update services to not use a Provider

This commit is contained in:
Andrew Pareles 2024-11-14 03:38:41 -08:00
parent dbea46ba32
commit a273780472
7 changed files with 34 additions and 49 deletions

View file

@ -1,7 +1,7 @@
import React, { JSX, useCallback, useEffect, useState } from 'react'
import { marked, MarkedToken, Token } from 'marked'
import { BlockCode } from './BlockCode.js'
import { useService } from '../util/contextForServices.js'
import { useService } from '../util/services.js'
enum CopyButtonState {

View file

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { mountFnGenerator } from '../util/mountFnGenerator.js'
import { SidebarSettings } from './SidebarSettings.js';
import { useSidebarState } from '../util/contextForServices.js';
import { useSidebarState } from '../util/services.js';
// import { SidebarThreadSelector } from './SidebarThreadSelector.js';
// import { SidebarChat } from './SidebarChat.js';

View file

@ -1,7 +1,7 @@
import React, { FormEvent, useCallback, useRef, useState } from 'react';
import { useConfigState, useService, useSidebarState, useThreadsState } from '../util/contextForServices.js';
import { useConfigState, useService, useSidebarState, useThreadsState } from '../util/services.js';
import { URI } from '../../../../../../../base/common/uri.js';
import { VSReadFile } from '../../../registerInlineDiffs.js';
import { sendLLMMessage } from '../util/sendLLMMessage.js';

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { useConfigState, useService } from '../util/contextForServices.js';
import { useConfigState, useService } from '../util/services.js';
import { IVoidConfigStateService, nonDefaultConfigFields, PartialVoidConfig, VoidConfig, VoidConfigField, VoidConfigInfo, SetFieldFnType, ConfigState } from '../../../registerConfig.js';

View file

@ -1,5 +1,5 @@
import React from "react";
import { useService, useThreadsState } from '../util/contextForServices.js';
import { useService, useThreadsState } from '../util/services.js';
const truncate = (s: string) => {

View file

@ -1,7 +1,9 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import * as ReactDOM from 'react-dom/client'
import { AccessorProvider } from './contextForServices.js';
import { ReactServicesType } from '../../../registerSidebar.js';
import { ReactServicesType, VoidSidebarState } from '../../../registerSidebar.js';
import { ConfigState } from '../../../registerConfig.js';
import { ThreadsState } from '../../../registerThreads.js';
import { _registerServices } from './services.js';
export const mountFnGenerator = (Component: React.FC) => (rootElement: HTMLElement, services: ReactServicesType) => {
@ -9,10 +11,9 @@ export const mountFnGenerator = (Component: React.FC) => (rootElement: HTMLEleme
console.error('index.tsx error: document was undefined')
return
}
_registerServices(services)
const root = ReactDOM.createRoot(rootElement)
root.render(
<AccessorProvider services={services}>
<Component />
</AccessorProvider>
);
root.render(<Component />);
}

View file

@ -1,35 +1,12 @@
import React, { createContext, useContext, useEffect, useState } from 'react'
import { ReactServicesType, VoidSidebarState } from '../../../registerSidebar.js';
import { ConfigState } from '../../../registerConfig.js';
import { ThreadsState } from '../../../registerThreads.js';
const AccessorContext = createContext<ReactServicesType | undefined>(undefined)
export const AccessorProvider = ({ children, services }: { children: React.ReactNode; services: ReactServicesType }) => {
registerStateListeners(services)
return <AccessorContext.Provider value={services}>
{children}
</AccessorContext.Provider>
}
import { useState, useEffect } from 'react'
import { ConfigState } from '../../../registerConfig.js'
import { VoidSidebarState, ReactServicesType } from '../../../registerSidebar.js'
import { ThreadsState } from '../../../registerThreads.js'
// -- services --
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes
let services: ReactServicesType | null = null
const useServices = (): ReactServicesType => {
const context = useContext(AccessorContext)
if (context === undefined) {
throw new Error('useAccessor must be used within an AccessorProvider')
}
return context;
}
export const useService = <T extends keyof ReactServicesType,>(serviceName: T) => {
const services = useServices()
return services[serviceName] as ReactServicesType[T]
}
// -- state of services --
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but here, useEffect mounts too late and misses initial state changes
let sidebarState: VoidSidebarState | null = null
let configState: ConfigState | null = null
let threadsState: ThreadsState | null = null
@ -38,12 +15,10 @@ const sidebarStateListeners: Set<(s: VoidSidebarState) => void> = new Set()
const configStateListeners: Set<(s: ConfigState) => void> = new Set()
const threadsStateListeners: Set<(s: ThreadsState) => void> = new Set()
let isRegistered = false
const registerStateListeners = (context: ReactServicesType) => {
if (isRegistered) return
isRegistered = true
const { sidebarStateService, configStateService, threadsStateService, } = context
// must call this before you can use any of the hooks below
export const _registerServices = (services_: ReactServicesType) => {
services = services_
const { sidebarStateService, configStateService, threadsStateService, } = services
sidebarState = sidebarStateService.state
sidebarStateService.onDidChangeState(() => {
@ -66,7 +41,16 @@ const registerStateListeners = (context: ReactServicesType) => {
}
// track the config state using React state so visual updates happen
// -- services --
export const useService = <T extends keyof ReactServicesType,>(serviceName: T) => {
if (services === null) {
throw new Error('useAccessor must be used within an AccessorProvider')
}
return services[serviceName] as ReactServicesType[T]
}
// -- state of services --
export const useSidebarState = () => {
const [s, ss] = useState(sidebarState)
useEffect(() => {