feat(gui): useProjection — the fifth framework hook seat through the standard kit

React half of the session-projection client base: the renderer contract gains
an open-key projections face on SessionMaybeProvideInfo (cellOf(key), distinct
from the static hooks roster), web-react mints projectionHook (per-bundle cache;
per-cell uSES binding via the shared observableHook cache; unresolved keys read
undefined through the absent source so hook order stays constant), standardKit
delivers kit.useProjection, and the runtime merges UseProjection into
SessionStandardProps/SessionMaybeStandardProps (overloads mirror useSession).
3 jsdom specs (kit delivery + live re-render, selector over undefined, faceless
bundle = all absent); existing direct-prop-feed specs gain the one-line stub the
new required seat mandates.
This commit is contained in:
imccyu
2026-07-27 15:37:42 +08:00
parent fbebe1757a
commit 90addbf53c
14 changed files with 196 additions and 1 deletions
@@ -10,7 +10,7 @@ import {
} from '@deepseek-ai/dsh-client-ui-slots'
import {
HostContext, SessionMaybeProvider, SessionProvider, SlotAssemblyError, maybeObservableHook,
observableHook, useHost, useSessionMaybeProvideInfo,
observableHook, projectionHook, useHost, useSessionMaybeProvideInfo,
} from './session-provider.tsx'
type InjectedProps = Record<string, unknown>
@@ -219,6 +219,9 @@ function standardKit(
}
Object.assign(kit, info.props)
kit['sessionId'] = info.sessionId
// The useProjection seat (fifth framework hook): key-addressed cell
// reader, bound per provide bundle (cached by info identity).
kit['useProjection'] = projectionHook(info)
}
const store = scope === 'session-maybe' && info?.sessionId === undefined
? undefined