dsh-edge 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +1318 -1075
- package/dist/assets/index-Df-65__b.js +110 -0
- package/dist/assets/index-b24khbeK.css +1 -0
- package/dist/assets/langs/{php-DDkx9sim.js → php-DJl5gRdb.js} +2 -2
- package/dist/assets/langs/{ruby-DCxyoPen.js → ruby-5eNB0pDK.js} +2 -2
- package/dist/assets/vendor-BNsW4eBh.css +1 -0
- package/dist/assets/vendor-CCJJTK99.js +411 -0
- package/dist/index.html +8 -8
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +1513 -77
- package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +3608 -757
- package/dist/plugins/@deepseek-ai/dsh-api-session-controller/client.js +2777 -0
- package/dist/plugins/@deepseek-ai/dsh-api-workspace-controller/client.js +415 -0
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +1975 -7466
- package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +225 -76
- package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +67 -15
- package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +270 -460
- package/dist/plugins/@deepseek-ai/dsh-client-ui-approval/client.js +292 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +42 -17
- package/dist/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js +7 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-chat/client.js +8177 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +22 -10
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +14950 -8910
- package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +161 -137
- package/dist/plugins/@deepseek-ai/dsh-client-ui-goal/client.js +6 -7
- package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +268 -40
- package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +1 -1
- package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +45 -11
- package/dist/plugins/@deepseek-ai/dsh-client-ui-message-feedback/client.js +30 -58
- package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +188 -89
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +105 -75
- package/dist/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js +650 -188
- package/dist/plugins/@deepseek-ai/dsh-client-ui-schedule/client.js +307 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-session/client.js +340 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +57 -50
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +134 -69
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js +575 -442
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +24 -11
- package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +13 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +44 -20
- package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +265 -94
- package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +899 -433
- package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +1472 -613
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +249 -95
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +5 -5
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +425 -146
- package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +29 -14
- package/dist/plugins/dsh-edge-client-ui/client.js +28 -26
- package/package.json +62 -58
- package/scripts/verify-packed.mjs +1 -1
- package/worker/direct/index.js +2866 -1466
- package/worker/isolated/index.js +2438 -1038
- package/dist/assets/index-C6eRlFa6.css +0 -1
- package/dist/assets/index-ClqxG24t.js +0 -96
- package/dist/assets/vendor-CjyC-hUb.css +0 -1
- package/dist/assets/vendor-D22_Mp1f.js +0 -411
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +0 -10574
|
@@ -12,6 +12,7 @@ window.__ModuleLoader__.load({
|
|
|
12
12
|
let react_dom_client = require("react-dom/client");
|
|
13
13
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
14
14
|
let _deepseek_ai_dsh_client_ui_slots = require("@deepseek-ai/dsh-client-ui-slots");
|
|
15
|
+
let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
|
|
15
16
|
//#region ../../../node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.3.1/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js
|
|
16
17
|
/**
|
|
17
18
|
* @license React
|
|
@@ -159,40 +160,45 @@ window.__ModuleLoader__.load({
|
|
|
159
160
|
};
|
|
160
161
|
}
|
|
161
162
|
//#endregion
|
|
162
|
-
//#region lib/types/client/
|
|
163
|
-
/** Internal React bindings for
|
|
164
|
-
/**
|
|
165
|
-
* A missing-provider assembly error: the shell wired the tree wrong. The slot
|
|
166
|
-
* error boundary rethrows this class so misassembly stays fail-loud while
|
|
167
|
-
* registrant errors (inject factories, entry components) are contained
|
|
168
|
-
* per entry.
|
|
169
|
-
*/
|
|
163
|
+
//#region lib/types/client/bindings.js
|
|
164
|
+
/** Internal React bindings for renderer hosts and standard-source scopes. */
|
|
165
|
+
/** Missing renderer assembly dependency. */
|
|
170
166
|
var SlotAssemblyError = class extends Error {};
|
|
171
167
|
/** In-package renderer host context. */
|
|
172
168
|
const HostContext = (0, react.createContext)(null);
|
|
173
169
|
/**
|
|
174
|
-
* Read the installed renderer host
|
|
175
|
-
* (framework components must not render detached from the renderer).
|
|
170
|
+
* Read the installed renderer host.
|
|
176
171
|
* @returns the host API.
|
|
177
172
|
*/
|
|
178
173
|
function useHost() {
|
|
179
174
|
const host = (0, react.useContext)(HostContext);
|
|
180
|
-
if (
|
|
175
|
+
if (host === null) throw new SlotAssemblyError("slot machinery rendered outside the installed renderer tree");
|
|
181
176
|
return host;
|
|
182
177
|
}
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
178
|
+
const RootBindingContext = (0, react.createContext)(null);
|
|
179
|
+
const ScopeBindingContext = (0, react.createContext)(null);
|
|
180
|
+
/**
|
|
181
|
+
* Read the root standard-source binding.
|
|
182
|
+
* @returns the current root binding.
|
|
183
|
+
*/
|
|
184
|
+
function useRootBinding() {
|
|
185
|
+
const binding = (0, react.useContext)(RootBindingContext);
|
|
186
|
+
if (binding === null) throw new SlotAssemblyError("slot rendered outside the root standard-source provider");
|
|
187
|
+
return binding;
|
|
189
188
|
}
|
|
190
189
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
* Read the current-session-optional binding.
|
|
191
|
+
* @returns a binding whose key is absent when no Session is selected.
|
|
192
|
+
*/
|
|
193
|
+
function useScopeBinding() {
|
|
194
|
+
const binding = (0, react.useContext)(ScopeBindingContext);
|
|
195
|
+
if (binding === null) throw new SlotAssemblyError("scoped slot rendered outside its scope provider");
|
|
196
|
+
return binding;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Bind one observable source to an identity-stable selector Hook.
|
|
200
|
+
* @param source - observable source.
|
|
201
|
+
* @returns cached selector Hook.
|
|
196
202
|
*/
|
|
197
203
|
function observableHook(source) {
|
|
198
204
|
let hook = hookCache.get(source);
|
|
@@ -207,7 +213,11 @@ window.__ModuleLoader__.load({
|
|
|
207
213
|
getSnapshot: () => void 0,
|
|
208
214
|
subscribe: () => () => {}
|
|
209
215
|
};
|
|
210
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Bind an optional source without changing Hook call order.
|
|
218
|
+
* @param source - current source, or absence.
|
|
219
|
+
* @returns selector Hook returning `undefined` while absent.
|
|
220
|
+
*/
|
|
211
221
|
function maybeObservableHook(source) {
|
|
212
222
|
if (source !== void 0) return observableHook(source);
|
|
213
223
|
return useAbsentSnapshot;
|
|
@@ -216,54 +226,43 @@ window.__ModuleLoader__.load({
|
|
|
216
226
|
observableHook(absentSource)(() => void 0);
|
|
217
227
|
}
|
|
218
228
|
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* face off the projection store; the bound selector hook comes from the same
|
|
223
|
-
* per-source cache as every other kit hook, so exactly one uSES subscription
|
|
224
|
-
* runs per call and the subscribe reference stays stable per key. A key no
|
|
225
|
-
* baseline or frame has carried (or a no-session bundle) reads `undefined` —
|
|
226
|
-
* capability absence — keeping the hook order constant.
|
|
229
|
+
* Bind an open-key source family.
|
|
230
|
+
* @param source - keyed resolver, or absence for an optional scope.
|
|
231
|
+
* @returns cached keyed selector Hook.
|
|
227
232
|
*/
|
|
228
|
-
function
|
|
229
|
-
|
|
233
|
+
function keyedObservableHook(source) {
|
|
234
|
+
if (source === void 0) return absentKeyedHook;
|
|
235
|
+
let hook = keyedHookCache.get(source);
|
|
230
236
|
if (hook === void 0) {
|
|
231
|
-
hook = (key, selector,
|
|
232
|
-
return observableHook(
|
|
237
|
+
hook = (key, selector, equal) => {
|
|
238
|
+
return observableHook(source(key) ?? absentSource)(selector ?? identity, equal);
|
|
233
239
|
};
|
|
234
|
-
|
|
240
|
+
keyedHookCache.set(source, hook);
|
|
235
241
|
}
|
|
236
242
|
return hook;
|
|
237
243
|
}
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const info = observableHook(useHost().sessions.provideInfo)((s) => s);
|
|
247
|
-
return (0, react_jsx_runtime.jsx)(BindingContext.Provider, {
|
|
248
|
-
value: info,
|
|
244
|
+
const keyedHookCache = /* @__PURE__ */ new WeakMap();
|
|
245
|
+
const identity = (value) => value;
|
|
246
|
+
const absentKeyedHook = (_key, selector, equal) => observableHook(absentSource)(selector ?? identity, equal);
|
|
247
|
+
/** Subscribe the tree to the atomically assembled root standard-source roster. */
|
|
248
|
+
function RootStandardProvider({ children }) {
|
|
249
|
+
const binding = observableHook(useHost().root)((value) => value);
|
|
250
|
+
return (0, react_jsx_runtime.jsx)(RootBindingContext.Provider, {
|
|
251
|
+
value: binding,
|
|
249
252
|
children
|
|
250
253
|
});
|
|
251
254
|
}
|
|
252
|
-
/**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return (0, react_jsx_runtime.jsx)(BindingContext.Provider, {
|
|
264
|
-
value: info,
|
|
265
|
-
children: children(id)
|
|
266
|
-
}, id);
|
|
255
|
+
/** Subscribe to the scope roster before resolving and binding its current adapter. */
|
|
256
|
+
function ScopeProvider({ scope, children }) {
|
|
257
|
+
const host = useHost();
|
|
258
|
+
observableHook(host.scopeRevision)((value) => value);
|
|
259
|
+
const adapter = host.scope(scope);
|
|
260
|
+
if (adapter === void 0) throw new SlotAssemblyError(`scope '${scope}' rendered without an installed adapter`);
|
|
261
|
+
const binding = observableHook(adapter.current)((value) => value);
|
|
262
|
+
return (0, react_jsx_runtime.jsx)(ScopeBindingContext.Provider, {
|
|
263
|
+
value: binding,
|
|
264
|
+
children
|
|
265
|
+
});
|
|
267
266
|
}
|
|
268
267
|
//#endregion
|
|
269
268
|
//#region lib/types/client/scoped-slots.js
|
|
@@ -323,7 +322,7 @@ window.__ModuleLoader__.load({
|
|
|
323
322
|
}
|
|
324
323
|
/**
|
|
325
324
|
* Inject results cache: root entries per entry, session entries per
|
|
326
|
-
* (entry x
|
|
325
|
+
* (entry x scope binding). WeakMap keys are entry/binding objects (both
|
|
327
326
|
* identity-stable per registration/session scope), so cache lifetime rides
|
|
328
327
|
* the same axes as the values it memoizes.
|
|
329
328
|
*/
|
|
@@ -331,27 +330,29 @@ window.__ModuleLoader__.load({
|
|
|
331
330
|
const sessionInjectCache = /* @__PURE__ */ new WeakMap();
|
|
332
331
|
const sessionMaybeInjectCache = /* @__PURE__ */ new WeakMap();
|
|
333
332
|
const EMPTY_INJECTED_PROPS = {};
|
|
334
|
-
function runInject(entry,
|
|
333
|
+
function runInject(entry, binding, actions) {
|
|
335
334
|
const inject = entry.inject;
|
|
336
335
|
if (!inject) return EMPTY_INJECTED_PROPS;
|
|
337
336
|
const args = [];
|
|
338
|
-
if (
|
|
337
|
+
if (binding !== void 0) args.push(binding.key);
|
|
339
338
|
if (actions !== void 0) args.push(actions);
|
|
340
|
-
return
|
|
339
|
+
return bindInjectSources(inject(...args));
|
|
341
340
|
}
|
|
342
|
-
/**
|
|
343
|
-
|
|
344
|
-
* compartment remains the original Observable-only contract.
|
|
345
|
-
*/
|
|
346
|
-
function bindInjectHooks(face) {
|
|
341
|
+
/** Bind one entry-owned inject face on its existing cache axis. */
|
|
342
|
+
function bindInjectSources(face) {
|
|
347
343
|
const sources = face["hooks"];
|
|
348
|
-
|
|
349
|
-
|
|
344
|
+
const keyedSources = face["keyedHooks"];
|
|
345
|
+
if (sources === void 0 && keyedSources === void 0) return face;
|
|
346
|
+
const { hooks: _hooks, keyedHooks: _keyedHooks, ...rest } = face;
|
|
350
347
|
const bound = rest;
|
|
351
|
-
for (const [name, source] of Object.entries(sources)) {
|
|
352
|
-
const hookName =
|
|
348
|
+
for (const [name, source] of Object.entries(sources ?? {})) {
|
|
349
|
+
const hookName = (0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name);
|
|
353
350
|
bound[hookName] = observableHook(source);
|
|
354
351
|
}
|
|
352
|
+
for (const [name, source] of Object.entries(keyedSources ?? {})) {
|
|
353
|
+
const hookName = (0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name);
|
|
354
|
+
bound[hookName] = keyedObservableHook(source);
|
|
355
|
+
}
|
|
355
356
|
return bound;
|
|
356
357
|
}
|
|
357
358
|
const slotInjectCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -371,7 +372,7 @@ window.__ModuleLoader__.load({
|
|
|
371
372
|
const props = rest;
|
|
372
373
|
let factories;
|
|
373
374
|
for (const [name, definition] of Object.entries(definitions)) {
|
|
374
|
-
const hookName =
|
|
375
|
+
const hookName = (0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name);
|
|
375
376
|
if (typeof definition === "function") {
|
|
376
377
|
factories ??= {};
|
|
377
378
|
factories[name] = definition;
|
|
@@ -388,7 +389,7 @@ window.__ModuleLoader__.load({
|
|
|
388
389
|
function bindSlotHookFactories(factories, standard, hookContext) {
|
|
389
390
|
const hooks = {};
|
|
390
391
|
for (const [name, factory] of Object.entries(factories)) {
|
|
391
|
-
const hookName =
|
|
392
|
+
const hookName = (0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name);
|
|
392
393
|
hooks[hookName] = factory(standard, hookContext);
|
|
393
394
|
}
|
|
394
395
|
return hooks;
|
|
@@ -401,29 +402,29 @@ window.__ModuleLoader__.load({
|
|
|
401
402
|
}
|
|
402
403
|
return props;
|
|
403
404
|
}
|
|
404
|
-
function cachedSessionInject(entry,
|
|
405
|
-
let
|
|
406
|
-
if (!
|
|
407
|
-
|
|
408
|
-
sessionInjectCache.set(entry,
|
|
405
|
+
function cachedSessionInject(entry, binding, actions) {
|
|
406
|
+
let perBinding = sessionInjectCache.get(entry);
|
|
407
|
+
if (!perBinding) {
|
|
408
|
+
perBinding = /* @__PURE__ */ new WeakMap();
|
|
409
|
+
sessionInjectCache.set(entry, perBinding);
|
|
409
410
|
}
|
|
410
|
-
let props =
|
|
411
|
+
let props = perBinding.get(binding);
|
|
411
412
|
if (!props) {
|
|
412
|
-
props = runInject(entry,
|
|
413
|
-
|
|
413
|
+
props = runInject(entry, binding, actions);
|
|
414
|
+
perBinding.set(binding, props);
|
|
414
415
|
}
|
|
415
416
|
return props;
|
|
416
417
|
}
|
|
417
|
-
function cachedSessionMaybeInject(entry,
|
|
418
|
-
let
|
|
419
|
-
if (!
|
|
420
|
-
|
|
421
|
-
sessionMaybeInjectCache.set(entry,
|
|
418
|
+
function cachedSessionMaybeInject(entry, binding, actions) {
|
|
419
|
+
let perBinding = sessionMaybeInjectCache.get(entry);
|
|
420
|
+
if (!perBinding) {
|
|
421
|
+
perBinding = /* @__PURE__ */ new WeakMap();
|
|
422
|
+
sessionMaybeInjectCache.set(entry, perBinding);
|
|
422
423
|
}
|
|
423
|
-
let props =
|
|
424
|
+
let props = perBinding.get(binding);
|
|
424
425
|
if (!props) {
|
|
425
|
-
props = runInject(entry,
|
|
426
|
-
|
|
426
|
+
props = runInject(entry, binding, actions);
|
|
427
|
+
perBinding.set(binding, props);
|
|
427
428
|
}
|
|
428
429
|
return props;
|
|
429
430
|
}
|
|
@@ -530,41 +531,59 @@ window.__ModuleLoader__.load({
|
|
|
530
531
|
return this.props.children;
|
|
531
532
|
}
|
|
532
533
|
};
|
|
533
|
-
const
|
|
534
|
+
const rootStandardCache = /* @__PURE__ */ new WeakMap();
|
|
535
|
+
const sessionStandardCache = /* @__PURE__ */ new WeakMap();
|
|
536
|
+
const sessionMaybeStandardCache = /* @__PURE__ */ new WeakMap();
|
|
537
|
+
/** Materialize one binding into stable framework Hook and plain-prop seats. */
|
|
538
|
+
function materializeStandardBinding(binding, optional) {
|
|
539
|
+
const standard = { ...binding.props };
|
|
540
|
+
for (const [name, source] of Object.entries(binding.hooks)) {
|
|
541
|
+
if (source === void 0 && !optional) throw new SlotAssemblyError(`strict standard hook '${name}' has no source`);
|
|
542
|
+
standard[(0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name)] = optional ? maybeObservableHook(source) : observableHook(source);
|
|
543
|
+
}
|
|
544
|
+
for (const [name, source] of Object.entries(binding.keyedHooks)) {
|
|
545
|
+
if (source === void 0 && !optional) throw new SlotAssemblyError(`strict keyed standard hook '${name}' has no source resolver`);
|
|
546
|
+
standard[(0, _deepseek_ai_dsh_client_ui_slots.standardHookPropName)(name)] = keyedObservableHook(source);
|
|
547
|
+
}
|
|
548
|
+
return standard;
|
|
549
|
+
}
|
|
534
550
|
/** Stable official-props object used by contextual Hook factories. */
|
|
535
|
-
function standardProps(
|
|
536
|
-
let
|
|
537
|
-
if (
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
useSessions: observableHook(host.sessions.list),
|
|
541
|
-
useWorkspaces: observableHook(host.workspaces.list)
|
|
542
|
-
},
|
|
543
|
-
session: /* @__PURE__ */ new WeakMap(),
|
|
544
|
-
sessionMaybe: /* @__PURE__ */ new WeakMap()
|
|
545
|
-
};
|
|
546
|
-
standardPropsCache.set(host, cache);
|
|
551
|
+
function standardProps(scope, rootBinding, scopeBinding) {
|
|
552
|
+
let root = rootStandardCache.get(rootBinding);
|
|
553
|
+
if (root === void 0) {
|
|
554
|
+
root = materializeStandardBinding(rootBinding, false);
|
|
555
|
+
rootStandardCache.set(rootBinding, root);
|
|
547
556
|
}
|
|
548
|
-
if (scope === "root") return
|
|
549
|
-
if (
|
|
550
|
-
const
|
|
551
|
-
let
|
|
552
|
-
if (
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
const hookName = `use${name[0]?.toUpperCase() ?? ""}${name.slice(1)}`;
|
|
556
|
-
if (scope === "session-maybe") standard[hookName] = maybeObservableHook(source);
|
|
557
|
-
else {
|
|
558
|
-
if (source === void 0) throw new SlotAssemblyError(`strict session hook '${name}' has no source`);
|
|
559
|
-
standard[hookName] = observableHook(source);
|
|
560
|
-
}
|
|
557
|
+
if (scope === "root") return root;
|
|
558
|
+
if (scopeBinding === void 0) throw new SlotAssemblyError(`scope '${scope}' rendered without a standard-source binding`);
|
|
559
|
+
const cache = scope === "session" ? sessionStandardCache : sessionMaybeStandardCache;
|
|
560
|
+
let perScope = cache.get(rootBinding);
|
|
561
|
+
if (perScope === void 0) {
|
|
562
|
+
perScope = /* @__PURE__ */ new WeakMap();
|
|
563
|
+
cache.set(rootBinding, perScope);
|
|
561
564
|
}
|
|
562
|
-
|
|
563
|
-
standard
|
|
564
|
-
standard
|
|
565
|
-
|
|
565
|
+
let standard = perScope.get(scopeBinding);
|
|
566
|
+
if (standard !== void 0) return standard;
|
|
567
|
+
standard = {
|
|
568
|
+
...root,
|
|
569
|
+
...materializeStandardBinding(scopeBinding, scope === "session-maybe")
|
|
570
|
+
};
|
|
571
|
+
perScope.set(scopeBinding, standard);
|
|
566
572
|
return standard;
|
|
567
573
|
}
|
|
574
|
+
const scopeAreaCache = /* @__PURE__ */ new WeakMap();
|
|
575
|
+
/** Bind one domain-owned scope area renderer to the current scope binding. */
|
|
576
|
+
function scopeAreaProvider(adapter) {
|
|
577
|
+
let Provider = scopeAreaCache.get(adapter);
|
|
578
|
+
if (Provider !== void 0) return Provider;
|
|
579
|
+
if (adapter.renderArea === void 0) throw new SlotAssemblyError("scope 'session' adapter does not provide its area renderer");
|
|
580
|
+
const renderArea = adapter.renderArea.bind(adapter);
|
|
581
|
+
Provider = function ScopeAreaProvider(props) {
|
|
582
|
+
return renderArea(useScopeBinding(), props);
|
|
583
|
+
};
|
|
584
|
+
scopeAreaCache.set(adapter, Provider);
|
|
585
|
+
return Provider;
|
|
586
|
+
}
|
|
568
587
|
/**
|
|
569
588
|
* Standard-kit synthesis shared by both scope branches: the global
|
|
570
589
|
* useSessions/useWorkspaces hooks, the per-session provide bundle (every
|
|
@@ -577,15 +596,16 @@ window.__ModuleLoader__.load({
|
|
|
577
596
|
* per source (observableHook), so spreading a fresh kit object per render
|
|
578
597
|
* never churns child subscriptions.
|
|
579
598
|
*/
|
|
580
|
-
function standardKit(host, entry, scope,
|
|
581
|
-
const standard = standardProps(
|
|
599
|
+
function standardKit(host, entry, scope, rootBinding, scopeBinding) {
|
|
600
|
+
const standard = standardProps(scope, rootBinding, scopeBinding);
|
|
582
601
|
const kit = { ...standard };
|
|
583
602
|
if (entry.locale !== void 0) {
|
|
584
603
|
const face = host.locale;
|
|
585
604
|
if (face === void 0) throw new SlotAssemblyError(`entry declares locale namespace '${entry.locale}' but no locale face is installed (locale plugin missing from the composition?)`);
|
|
586
605
|
kit["t"] = localeSeat(face, entry.locale);
|
|
587
606
|
}
|
|
588
|
-
const
|
|
607
|
+
const scopedStoreBinding = scopeBinding?.key === void 0 ? void 0 : scopeBinding;
|
|
608
|
+
const store = host.storeOf(entry, scopedStoreBinding);
|
|
589
609
|
if (store !== void 0) {
|
|
590
610
|
kit["useStore"] = observableHook(store);
|
|
591
611
|
kit["actions"] = store.actions;
|
|
@@ -593,7 +613,11 @@ window.__ModuleLoader__.load({
|
|
|
593
613
|
if (entry.children !== void 0) {
|
|
594
614
|
kit["renderSlot"] = boundRenderSlot(host, entry);
|
|
595
615
|
if (Object.values(entry.children).some((spec) => spec.kind === "chain")) kit["renderSlotChain"] = boundRenderSlotChain(host, entry);
|
|
596
|
-
if (Object.values(entry.children).some((spec) => spec.scope === "session"))
|
|
616
|
+
if (Object.values(entry.children).some((spec) => spec.scope === "session")) {
|
|
617
|
+
const adapter = host.scope("session");
|
|
618
|
+
if (adapter === void 0) throw new SlotAssemblyError("entry declares a session child without an installed 'session' scope adapter");
|
|
619
|
+
kit["SessionProvider"] = scopeAreaProvider(adapter);
|
|
620
|
+
}
|
|
597
621
|
}
|
|
598
622
|
return {
|
|
599
623
|
kit,
|
|
@@ -644,17 +668,19 @@ window.__ModuleLoader__.load({
|
|
|
644
668
|
hasHookContext
|
|
645
669
|
});
|
|
646
670
|
}
|
|
647
|
-
function SessionEntry({ entry, ownerProps,
|
|
671
|
+
function SessionEntry({ entry, ownerProps, binding, slotKey, slotInjected, hookContext, hasHookContext }) {
|
|
648
672
|
const host = useHost();
|
|
673
|
+
const rootBinding = useRootBinding();
|
|
649
674
|
const Comp = entry.component;
|
|
650
|
-
const { kit, standard, actions } = standardKit(host, entry, "session",
|
|
651
|
-
return renderEntry(slotKey, Comp, kit, standard, cachedSessionInject(entry,
|
|
675
|
+
const { kit, standard, actions } = standardKit(host, entry, "session", rootBinding, binding);
|
|
676
|
+
return renderEntry(slotKey, Comp, kit, standard, cachedSessionInject(entry, binding, actions), slotInjected, ownerProps, hookContext, hasHookContext);
|
|
652
677
|
}
|
|
653
|
-
function SessionMaybeEntryBody({ entry, ownerProps,
|
|
678
|
+
function SessionMaybeEntryBody({ entry, ownerProps, binding, slotKey, slotInjected, hookContext, hasHookContext }) {
|
|
654
679
|
const host = useHost();
|
|
680
|
+
const rootBinding = useRootBinding();
|
|
655
681
|
const Comp = entry.component;
|
|
656
|
-
const { kit, standard, actions } = standardKit(host, entry, "session-maybe",
|
|
657
|
-
return renderEntry(slotKey, Comp, kit, standard, cachedSessionMaybeInject(entry,
|
|
682
|
+
const { kit, standard, actions } = standardKit(host, entry, "session-maybe", rootBinding, binding);
|
|
683
|
+
return renderEntry(slotKey, Comp, kit, standard, cachedSessionMaybeInject(entry, binding, actions), slotInjected, ownerProps, hookContext, hasHookContext);
|
|
658
684
|
}
|
|
659
685
|
/**
|
|
660
686
|
* Session-maybe identity: adoption — the ONLY behavior (there is no
|
|
@@ -670,23 +696,23 @@ window.__ModuleLoader__.load({
|
|
|
670
696
|
* store, hooks) — the existing layering rule, now load-bearing.
|
|
671
697
|
*/
|
|
672
698
|
function SessionMaybeEntry({ entry, ownerProps, slotKey, slotInjected, hookContext, hasHookContext }) {
|
|
673
|
-
const
|
|
699
|
+
const binding = useScopeBinding();
|
|
674
700
|
const [state, setState] = (0, react.useState)(FIRST_INCARNATION);
|
|
675
701
|
let { adopted, epoch } = state;
|
|
676
|
-
if (
|
|
677
|
-
adopted =
|
|
702
|
+
if (binding.key !== void 0 && adopted === void 0) {
|
|
703
|
+
adopted = binding.key;
|
|
678
704
|
setState({
|
|
679
705
|
adopted,
|
|
680
706
|
epoch
|
|
681
707
|
});
|
|
682
|
-
} else if (adopted !== void 0 &&
|
|
683
|
-
adopted =
|
|
708
|
+
} else if (adopted !== void 0 && binding.key !== void 0 && binding.key !== adopted) {
|
|
709
|
+
adopted = binding.key;
|
|
684
710
|
epoch += 1;
|
|
685
711
|
setState({
|
|
686
712
|
adopted,
|
|
687
713
|
epoch
|
|
688
714
|
});
|
|
689
|
-
} else if (adopted !== void 0 &&
|
|
715
|
+
} else if (adopted !== void 0 && binding.key === void 0) {
|
|
690
716
|
adopted = void 0;
|
|
691
717
|
epoch += 1;
|
|
692
718
|
setState({
|
|
@@ -697,7 +723,7 @@ window.__ModuleLoader__.load({
|
|
|
697
723
|
return (0, react_jsx_runtime.jsx)(SessionMaybeEntryBody, {
|
|
698
724
|
entry,
|
|
699
725
|
ownerProps,
|
|
700
|
-
|
|
726
|
+
binding,
|
|
701
727
|
slotKey,
|
|
702
728
|
slotInjected,
|
|
703
729
|
hookContext,
|
|
@@ -710,26 +736,27 @@ window.__ModuleLoader__.load({
|
|
|
710
736
|
};
|
|
711
737
|
function RootEntry({ entry, ownerProps, slotKey, slotInjected, hookContext, hasHookContext }) {
|
|
712
738
|
const host = useHost();
|
|
739
|
+
const rootBinding = useRootBinding();
|
|
713
740
|
const Comp = entry.component;
|
|
714
|
-
const { kit, standard, actions } = standardKit(host, entry, "root", void 0);
|
|
741
|
+
const { kit, standard, actions } = standardKit(host, entry, "root", rootBinding, void 0);
|
|
715
742
|
return renderEntry(slotKey, Comp, kit, standard, cachedRootInject(entry, actions), slotInjected, ownerProps, hookContext, hasHookContext);
|
|
716
743
|
}
|
|
717
744
|
function StrictSessionEntry({ slotKey, entry, ownerProps, slotInjected, hookContext, hasHookContext, onEntryError }) {
|
|
718
|
-
const
|
|
719
|
-
if (
|
|
745
|
+
const binding = useScopeBinding();
|
|
746
|
+
if (binding.key === void 0) throw new SlotAssemblyError(`strict session slot '${slotKey}' rendered without a scope binding`);
|
|
720
747
|
return (0, react_jsx_runtime.jsx)(SlotErrorBoundary, {
|
|
721
748
|
slotKey,
|
|
722
749
|
onEntryError,
|
|
723
750
|
children: (0, react_jsx_runtime.jsx)(SessionEntry, {
|
|
724
751
|
entry,
|
|
725
752
|
ownerProps,
|
|
726
|
-
|
|
753
|
+
binding,
|
|
727
754
|
slotKey,
|
|
728
755
|
slotInjected,
|
|
729
756
|
hookContext,
|
|
730
757
|
hasHookContext
|
|
731
758
|
})
|
|
732
|
-
},
|
|
759
|
+
}, binding.key);
|
|
733
760
|
}
|
|
734
761
|
/**
|
|
735
762
|
* Anchor style shared by every outlet wrapper: `display:contents` keeps the
|
|
@@ -745,16 +772,16 @@ window.__ModuleLoader__.load({
|
|
|
745
772
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
746
773
|
"data-slot": slotKey,
|
|
747
774
|
style: ANCHOR_STYLE,
|
|
748
|
-
children: renderOutletContent(host, slotKey, ownerProps, opts,
|
|
775
|
+
children: renderOutletContent(host, slotKey, ownerProps, opts, useScopeBinding())
|
|
749
776
|
});
|
|
750
777
|
}
|
|
751
778
|
/** Kind dispatch behind the outlet anchor (single/keyed/list/chain, fallbacks, crash faces). */
|
|
752
|
-
function renderOutletContent(host, slotKey, ownerProps, opts,
|
|
779
|
+
function renderOutletContent(host, slotKey, ownerProps, opts, scopeBinding) {
|
|
753
780
|
const spec = host.specOf(slotKey);
|
|
754
781
|
if (!spec) return null;
|
|
755
|
-
|
|
756
|
-
if (
|
|
757
|
-
const entries =
|
|
782
|
+
if (spec.kind === "chain" && opts?.fallbackOnly === true) return renderChainResult(slotKey, null, opts);
|
|
783
|
+
if (spec.scope === "session" && scopeBinding.key === void 0) throw new SlotAssemblyError(`strict session slot '${slotKey}' rendered without a scope binding`);
|
|
784
|
+
const entries = host.entriesOf(slotKey);
|
|
758
785
|
const slotInjected = cachedSlotInject(spec.inject);
|
|
759
786
|
const guarded = (entry, key, owner = ownerProps) => {
|
|
760
787
|
const hasHookContext = opts !== void 0 && Object.hasOwn(opts, "hookContext");
|
|
@@ -819,12 +846,7 @@ window.__ModuleLoader__.load({
|
|
|
819
846
|
break;
|
|
820
847
|
}
|
|
821
848
|
}
|
|
822
|
-
|
|
823
|
-
"data-chain-overlay-fallback": slotKey,
|
|
824
|
-
style: { display: elected === null ? "contents" : "none" },
|
|
825
|
-
children: opts.fallback ?? null
|
|
826
|
-
}), elected] });
|
|
827
|
-
return elected ?? (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: opts?.fallback ?? null });
|
|
849
|
+
return renderChainResult(slotKey, elected, opts);
|
|
828
850
|
}
|
|
829
851
|
const rows = host.entriesOfSlot(slotKey).map((entry) => ({
|
|
830
852
|
entry,
|
|
@@ -846,6 +868,15 @@ window.__ModuleLoader__.load({
|
|
|
846
868
|
if (list.length === 0) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: opts?.fallback ?? null });
|
|
847
869
|
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: list.map((item, i) => item.entry !== void 0 ? guarded(item.entry, `e${entryKeyOf(item.entry)}`) : (0, react_jsx_runtime.jsx)("div", { "data-slot-error": slotKey }, `x${item.id ?? i}`)) });
|
|
848
870
|
}
|
|
871
|
+
/** Render a chain election while preserving the overlay fallback's tree position. */
|
|
872
|
+
function renderChainResult(slotKey, elected, opts) {
|
|
873
|
+
if (!opts?.overlay) return elected ?? (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: opts?.fallback ?? null });
|
|
874
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
|
|
875
|
+
"data-chain-overlay-fallback": slotKey,
|
|
876
|
+
style: { display: elected === null ? "contents" : "none" },
|
|
877
|
+
children: opts.fallback ?? null
|
|
878
|
+
}), elected] });
|
|
879
|
+
}
|
|
849
880
|
/** Root outlet: the shell's single ctx-level render entry — an unregistered 'root' is a boot-order failure, never a silent blank. */
|
|
850
881
|
function RootOutlet({ ownerProps }) {
|
|
851
882
|
const host = useHost();
|
|
@@ -876,7 +907,7 @@ window.__ModuleLoader__.load({
|
|
|
876
907
|
});
|
|
877
908
|
}
|
|
878
909
|
/**
|
|
879
|
-
* Build the renderer
|
|
910
|
+
* Build the renderer installed into the `ui-renderer` SlotRegistry
|
|
880
911
|
* (ctx.slots.install(createSlotRenderer()) at boot; the service owns the
|
|
881
912
|
* install/renderSlot contract and the double-install/not-installed throws).
|
|
882
913
|
* @returns the renderer.
|
|
@@ -885,29 +916,14 @@ window.__ModuleLoader__.load({
|
|
|
885
916
|
return { renderRoot(host, ownerProps) {
|
|
886
917
|
return (0, react_jsx_runtime.jsx)(HostContext.Provider, {
|
|
887
918
|
value: host,
|
|
888
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
919
|
+
children: (0, react_jsx_runtime.jsx)(RootStandardProvider, { children: (0, react_jsx_runtime.jsx)(ScopeProvider, {
|
|
920
|
+
scope: "session-maybe",
|
|
921
|
+
children: (0, react_jsx_runtime.jsx)(RootOutlet, { ownerProps })
|
|
922
|
+
}) })
|
|
889
923
|
});
|
|
890
924
|
} };
|
|
891
925
|
}
|
|
892
926
|
//#endregion
|
|
893
|
-
//#region lib/types/client/DocumentTitle.js
|
|
894
|
-
/**
|
|
895
|
-
* Project the selected durable session title into the browser title and
|
|
896
|
-
* restore the build-selected product title when unmounted.
|
|
897
|
-
* @param props - Selected session title projection.
|
|
898
|
-
* @returns No rendered content.
|
|
899
|
-
*/
|
|
900
|
-
function DocumentTitle({ title }) {
|
|
901
|
-
const productTitle = "DeepSeek Harness";
|
|
902
|
-
(0, react.useEffect)(() => {
|
|
903
|
-
document.title = title === void 0 ? productTitle : `${title} — ${productTitle}`;
|
|
904
|
-
return () => {
|
|
905
|
-
document.title = productTitle;
|
|
906
|
-
};
|
|
907
|
-
}, [productTitle, title]);
|
|
908
|
-
return null;
|
|
909
|
-
}
|
|
910
|
-
//#endregion
|
|
911
927
|
//#region lib/types/client/app.js
|
|
912
928
|
/**
|
|
913
929
|
* Build the assembled application factory.
|
|
@@ -916,18 +932,463 @@ window.__ModuleLoader__.load({
|
|
|
916
932
|
*/
|
|
917
933
|
function buildRenderApp(deps) {
|
|
918
934
|
const { ctx } = deps;
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
935
|
+
return () => ctx.slots.renderSlot("root", {});
|
|
936
|
+
}
|
|
937
|
+
//#endregion
|
|
938
|
+
//#region lib/types/client/registry.js
|
|
939
|
+
/**
|
|
940
|
+
* SlotRegistry: the renderer-owned Cordis service over the pure
|
|
941
|
+
* SlotCore (ui-slots owns registration semantics, the declaration ledger,
|
|
942
|
+
* the load-time validations, and the unload cascade). This layer owns what
|
|
943
|
+
* needs a live application: the 'slots/changed' event bridge, register and
|
|
944
|
+
* declaration injection through the caller's ctx.effect (fiber unload
|
|
945
|
+
* collects both), the renderer installation contract (install()/renderSlot('root') +
|
|
946
|
+
* the SlotRendererHost face), and the store INSTANCE axis — handle x scope
|
|
947
|
+
* key -> create/cache, dropped with the last holding entry, session instances
|
|
948
|
+
* cleared (with persisted state) on scope death.
|
|
949
|
+
*/
|
|
950
|
+
/** Instance key for root-scoped store records (session records key by session id, so the literal cannot collide). */
|
|
951
|
+
const ROOT_INSTANCE_KEY = "root";
|
|
952
|
+
/** cordis Service layer of the slot system; see the module doc for the split with SlotCore. */
|
|
953
|
+
var SlotRegistry = class extends _deepseek_ai_cordis.Service {
|
|
954
|
+
_core = new _deepseek_ai_dsh_client_ui_slots.SlotCore();
|
|
955
|
+
/** Store-instance axis: handle -> mounted scope, refcount, resolved instances. */
|
|
956
|
+
_stores = /* @__PURE__ */ new Map();
|
|
957
|
+
/** Latest live Context generation for each scoped store key. */
|
|
958
|
+
_storeScopeOwners = /* @__PURE__ */ new Map();
|
|
959
|
+
_renderer;
|
|
960
|
+
_locale;
|
|
961
|
+
_host;
|
|
962
|
+
_rootContributions = [];
|
|
963
|
+
_rootListeners = /* @__PURE__ */ new Set();
|
|
964
|
+
_rootBinding = {
|
|
965
|
+
key: void 0,
|
|
966
|
+
hooks: {},
|
|
967
|
+
keyedHooks: {},
|
|
968
|
+
props: {}
|
|
969
|
+
};
|
|
970
|
+
_rootSource = {
|
|
971
|
+
getSnapshot: () => this._rootBinding,
|
|
972
|
+
subscribe: (listener) => {
|
|
973
|
+
this._rootListeners.add(listener);
|
|
974
|
+
return () => {
|
|
975
|
+
this._rootListeners.delete(listener);
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
_scopes = /* @__PURE__ */ new Map();
|
|
980
|
+
_scopeRevision = 0;
|
|
981
|
+
_scopeListeners = /* @__PURE__ */ new Set();
|
|
982
|
+
_scopeRevisionSource = {
|
|
983
|
+
getSnapshot: () => this._scopeRevision,
|
|
984
|
+
subscribe: (listener) => {
|
|
985
|
+
this._scopeListeners.add(listener);
|
|
986
|
+
return () => {
|
|
987
|
+
this._scopeListeners.delete(listener);
|
|
988
|
+
};
|
|
989
|
+
}
|
|
928
990
|
};
|
|
929
|
-
|
|
991
|
+
/**
|
|
992
|
+
* @param ctx - owning root context.
|
|
993
|
+
*/
|
|
994
|
+
constructor(ctx) {
|
|
995
|
+
super(ctx, "slots");
|
|
996
|
+
this._core.onMutate((key) => {
|
|
997
|
+
ctx.emit("slots/changed", key);
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Install an effect for each declaration lifetime of a slot. The callback
|
|
1002
|
+
* runs synchronously when the declaration already exists; otherwise it runs
|
|
1003
|
+
* inside the declaring `register()` call after the declaration is committed.
|
|
1004
|
+
* Collapse disposes the effect and a later declaration runs it again.
|
|
1005
|
+
* Callback effects are synchronous disposers; iterable effects install
|
|
1006
|
+
* transactionally and dispose in reverse order. The controller belongs to
|
|
1007
|
+
* the caller's fiber, so plugin unload cancels a pending wait and removes any
|
|
1008
|
+
* active contribution.
|
|
1009
|
+
*
|
|
1010
|
+
* @param key - declared SlotMap key to depend on.
|
|
1011
|
+
* @param callback - creates one disposer or an iterable of disposers.
|
|
1012
|
+
* @returns idempotent disposer for the wait and active effect.
|
|
1013
|
+
* @throws callback setup failures synchronously when the slot is already declared.
|
|
1014
|
+
*/
|
|
1015
|
+
inject(key, callback) {
|
|
1016
|
+
const ctx = this.ctx;
|
|
1017
|
+
const disposeController = ctx.effect(() => {
|
|
1018
|
+
let active;
|
|
1019
|
+
let activeEpoch;
|
|
1020
|
+
let stopped = false;
|
|
1021
|
+
let unsubscribe = () => {};
|
|
1022
|
+
const stop = () => {
|
|
1023
|
+
if (stopped) return;
|
|
1024
|
+
stopped = true;
|
|
1025
|
+
unsubscribe();
|
|
1026
|
+
const dispose = active;
|
|
1027
|
+
active = void 0;
|
|
1028
|
+
activeEpoch = void 0;
|
|
1029
|
+
dispose?.();
|
|
1030
|
+
};
|
|
1031
|
+
const reconcile = () => {
|
|
1032
|
+
if (stopped) return;
|
|
1033
|
+
const spec = this._core.specDynamic(key);
|
|
1034
|
+
const epoch = this._core.declarationEpoch(key);
|
|
1035
|
+
if (active !== void 0 && activeEpoch === epoch) return;
|
|
1036
|
+
const dispose = active;
|
|
1037
|
+
active = void 0;
|
|
1038
|
+
activeEpoch = void 0;
|
|
1039
|
+
dispose?.();
|
|
1040
|
+
if (spec === void 0) return;
|
|
1041
|
+
const disposeEffect = ctx.effect(callback, `slots.inject(${JSON.stringify(key)}): declaration`);
|
|
1042
|
+
active = () => {
|
|
1043
|
+
disposeEffect();
|
|
1044
|
+
};
|
|
1045
|
+
activeEpoch = epoch;
|
|
1046
|
+
};
|
|
1047
|
+
const changed = () => {
|
|
1048
|
+
try {
|
|
1049
|
+
reconcile();
|
|
1050
|
+
} catch (error) {
|
|
1051
|
+
if (error?.code === "INACTIVE_EFFECT") {
|
|
1052
|
+
stop();
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
stop();
|
|
1056
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
1057
|
+
queueMicrotask(() => {
|
|
1058
|
+
throw failure;
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
unsubscribe = this._core.subscribeDeclaration(key, changed);
|
|
1063
|
+
try {
|
|
1064
|
+
reconcile();
|
|
1065
|
+
} catch (error) {
|
|
1066
|
+
stop();
|
|
1067
|
+
throw error;
|
|
1068
|
+
}
|
|
1069
|
+
return stop;
|
|
1070
|
+
}, `slots.inject(${JSON.stringify(key)})`);
|
|
1071
|
+
return () => {
|
|
1072
|
+
disposeController();
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Install the shell's renderer (ui-renderer's createSlotRenderer product).
|
|
1077
|
+
* Boot-once: a second install throws. Runs through the caller's ctx.effect,
|
|
1078
|
+
* so shell fiber unload uninstalls the renderer.
|
|
1079
|
+
* @param renderer - the outlet machinery implementing SlotRenderer.
|
|
1080
|
+
*/
|
|
1081
|
+
install(renderer) {
|
|
1082
|
+
if (this._renderer !== void 0) throw new Error("slot renderer already installed (install() is boot-once)");
|
|
1083
|
+
this.ctx.effect(() => {
|
|
1084
|
+
this._renderer = renderer;
|
|
1085
|
+
return () => {
|
|
1086
|
+
if (this._renderer === renderer) this._renderer = void 0;
|
|
1087
|
+
};
|
|
1088
|
+
}, "slots.install()");
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Install the locale face backing the `t` standard seat (the locale
|
|
1092
|
+
* plugin's product; same boot-once discipline as the renderer install).
|
|
1093
|
+
* Runs through the caller's ctx.effect, so the installing fiber's unload
|
|
1094
|
+
* uninstalls the face.
|
|
1095
|
+
* @param face - namespace binder + revision observable.
|
|
1096
|
+
*/
|
|
1097
|
+
installLocale(face) {
|
|
1098
|
+
if (this._locale !== void 0) throw new Error("locale face already installed (installLocale() is boot-once)");
|
|
1099
|
+
this.ctx.effect(() => {
|
|
1100
|
+
this._locale = face;
|
|
1101
|
+
return () => {
|
|
1102
|
+
if (this._locale === face) this._locale = void 0;
|
|
1103
|
+
};
|
|
1104
|
+
}, "slots.installLocale()");
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Contribute domain-owned root data. Hook names must be globally unique;
|
|
1108
|
+
* registration and disposal republish one atomic root binding.
|
|
1109
|
+
* @param contribution - bare sources and stable props.
|
|
1110
|
+
* @returns disposer owned by the caller's Cordis fiber.
|
|
1111
|
+
*/
|
|
1112
|
+
provideRoot(contribution) {
|
|
1113
|
+
const dispose = this.ctx.effect(() => {
|
|
1114
|
+
this._rootContributions.push(contribution);
|
|
1115
|
+
try {
|
|
1116
|
+
this.rebuildRootBinding();
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
this._rootContributions.pop();
|
|
1119
|
+
throw error;
|
|
1120
|
+
}
|
|
1121
|
+
return () => {
|
|
1122
|
+
const index = this._rootContributions.indexOf(contribution);
|
|
1123
|
+
if (index === -1) return;
|
|
1124
|
+
this._rootContributions.splice(index, 1);
|
|
1125
|
+
this.rebuildRootBinding();
|
|
1126
|
+
};
|
|
1127
|
+
}, "slots.provideRoot()");
|
|
1128
|
+
return () => {
|
|
1129
|
+
dispose();
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Install the owner adapter for one strict scope. Its optional counterpart
|
|
1134
|
+
* resolves through the same adapter.
|
|
1135
|
+
* @param scope - strict scope name.
|
|
1136
|
+
* @param adapter - current/resolved binding source and release notifications.
|
|
1137
|
+
*/
|
|
1138
|
+
installScope(scope, adapter) {
|
|
1139
|
+
if (this._scopes.has(scope)) throw new Error(`slot scope '${scope}' already has an adapter`);
|
|
1140
|
+
this.ctx.effect(() => {
|
|
1141
|
+
this._scopes.set(scope, adapter);
|
|
1142
|
+
this.publishScopeRevision();
|
|
1143
|
+
return () => {
|
|
1144
|
+
if (this._scopes.get(scope) === adapter) {
|
|
1145
|
+
this._scopes.delete(scope);
|
|
1146
|
+
this.publishScopeRevision();
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
}, `slots.installScope(${JSON.stringify(scope)})`);
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Bind all scoped Store handles to one owner Context lifetime. The cleanup
|
|
1153
|
+
* materializes an otherwise-unused handle before clearing it, because a
|
|
1154
|
+
* previous application run may have persisted state for a Slot that this
|
|
1155
|
+
* scope never rendered. Rebinding the same key transfers cleanup ownership
|
|
1156
|
+
* to the newest Context generation.
|
|
1157
|
+
*
|
|
1158
|
+
* @param binding - materialized scope identity and its owning Context.
|
|
1159
|
+
*/
|
|
1160
|
+
bindStoreScope(binding) {
|
|
1161
|
+
if (this._storeScopeOwners.get(binding.key) === binding.ctx) return;
|
|
1162
|
+
this._storeScopeOwners.set(binding.key, binding.ctx);
|
|
1163
|
+
binding.ctx.effect(() => () => {
|
|
1164
|
+
if (this._storeScopeOwners.get(binding.key) !== binding.ctx) return;
|
|
1165
|
+
this._storeScopeOwners.delete(binding.key);
|
|
1166
|
+
this.clearStoreScope(binding.key);
|
|
1167
|
+
}, `slots: store scope ${binding.key}`);
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* The single ctx-level render entry: the shell renders 'root'; every other
|
|
1171
|
+
* key renders inside components through the props renderSlot face. All
|
|
1172
|
+
* three guards are fail-loud boot-order checks, no fallback.
|
|
1173
|
+
* @param key - must be 'root' (runtime-enforced for dynamically composed callers).
|
|
1174
|
+
* @param owner - owner share for the root entry (the shell supplies {}).
|
|
1175
|
+
* @returns the rendered root tree.
|
|
1176
|
+
*/
|
|
1177
|
+
renderSlot(key, owner) {
|
|
1178
|
+
if (key !== "root") throw new Error(`ctx-level renderSlot only renders 'root' (got "${key}"); child slots render through the component props face`);
|
|
1179
|
+
if (this._renderer === void 0) throw new Error("slot renderer not installed — boot must call ctx.slots.install(createSlotRenderer()) before rendering 'root'");
|
|
1180
|
+
if (this._core.entries("root").length === 0) throw new Error("'root' has no registration — a layout entry must register into 'root' before the shell renders it");
|
|
1181
|
+
return this._renderer.renderRoot(this.hostFace(), owner);
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Snapshot entries for a key (render-erased view; stable reference between mutations).
|
|
1185
|
+
* @param key - SlotMap key.
|
|
1186
|
+
* @returns registered entries.
|
|
1187
|
+
*/
|
|
1188
|
+
entries(key) {
|
|
1189
|
+
return this._core.entries(key);
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Shadowing winners per cell for a key: the first live (non-abdicated)
|
|
1193
|
+
* entry of each cell in priority order — what outlets render; chain keys
|
|
1194
|
+
* pass through unchanged (election consumes every entry). The raw
|
|
1195
|
+
* {@link SlotsService.entries} view stays the inspection surface. Fresh
|
|
1196
|
+
* array per call, not a uSES getSnapshot source.
|
|
1197
|
+
* @param key - SlotMap key.
|
|
1198
|
+
* @returns the winning entry per occupied cell.
|
|
1199
|
+
*/
|
|
1200
|
+
entriesOfSlot(key) {
|
|
1201
|
+
return this._core.entriesOfSlot(key);
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Export the current JSON-safe Slot declaration tree for read-only inspection.
|
|
1205
|
+
* @param root - exact live Slot root; omitted returns all roots.
|
|
1206
|
+
* @returns selected Slot trees.
|
|
1207
|
+
*/
|
|
1208
|
+
snapshot(root) {
|
|
1209
|
+
return this._core.snapshot(root);
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Observe entry boundary crashes (every render-time entry failure the
|
|
1213
|
+
* boundaries contain, abdicating or not) — the supervision seam for
|
|
1214
|
+
* plugins mirroring contribution health. Fires synchronously per report,
|
|
1215
|
+
* after the registry mutated for abdicating crashes. Callers own the
|
|
1216
|
+
* disposer (wire it through ctx.effect for fiber-lifetime cleanup, as with
|
|
1217
|
+
* {@link SlotsService.subscribe}).
|
|
1218
|
+
* @param fn - called with the slot key, the crashed entry, the crash
|
|
1219
|
+
* cause, and `abdicated`: whether the crash retired the entry from its cell.
|
|
1220
|
+
* @returns unsubscribe.
|
|
1221
|
+
*/
|
|
1222
|
+
onEntryError(fn) {
|
|
1223
|
+
return this._core.onEntryError(fn);
|
|
1224
|
+
}
|
|
1225
|
+
/**
|
|
1226
|
+
* Look up a declared spec (register-declared or the built-in 'root').
|
|
1227
|
+
* @param key - SlotMap key.
|
|
1228
|
+
* @returns spec or undefined.
|
|
1229
|
+
*/
|
|
1230
|
+
spec(key) {
|
|
1231
|
+
return this._core.spec(key);
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Subscribe to a key's registration changes (microtask-batched).
|
|
1235
|
+
* @param key - SlotMap key.
|
|
1236
|
+
* @param fn - change callback.
|
|
1237
|
+
* @returns unsubscribe.
|
|
1238
|
+
*/
|
|
1239
|
+
subscribe(key, fn) {
|
|
1240
|
+
return this._core.subscribe(key, fn);
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Version counter for uSES pairing.
|
|
1244
|
+
* @param key - SlotMap key.
|
|
1245
|
+
* @returns current version.
|
|
1246
|
+
*/
|
|
1247
|
+
getVersion(key) {
|
|
1248
|
+
return this._core.getVersion(key);
|
|
1249
|
+
}
|
|
1250
|
+
/** Delegating registration path: factory minting + registrant stamp + core write + instance-axis bookkeeping. */
|
|
1251
|
+
_register(options, component) {
|
|
1252
|
+
const store = typeof options.store === "function" ? options.store() : options.store;
|
|
1253
|
+
const registrant = options.registrant ?? this.ctx.fiber?.name;
|
|
1254
|
+
const erased = {
|
|
1255
|
+
...options,
|
|
1256
|
+
...store !== void 0 ? { store } : {},
|
|
1257
|
+
...registrant !== void 0 ? { registrant } : {}
|
|
1258
|
+
};
|
|
1259
|
+
const dispose = this._core.register(erased, component);
|
|
1260
|
+
if (store !== void 0) {
|
|
1261
|
+
const scope = this._core.specDynamic(options.name).scope;
|
|
1262
|
+
this._acquire(store, scope);
|
|
1263
|
+
}
|
|
1264
|
+
let disposed = false;
|
|
1265
|
+
return () => {
|
|
1266
|
+
if (disposed) return;
|
|
1267
|
+
disposed = true;
|
|
1268
|
+
dispose();
|
|
1269
|
+
if (store !== void 0) this._release(store);
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
/** Build the domain-neutral host face once; installed adapters remain live through getters. */
|
|
1273
|
+
hostFace() {
|
|
1274
|
+
if (this._host !== void 0) return this._host;
|
|
1275
|
+
const service = this;
|
|
1276
|
+
this._host = {
|
|
1277
|
+
subscribe: (key, fn) => this._core.subscribe(key, fn),
|
|
1278
|
+
getVersion: (key) => this._core.getVersion(key),
|
|
1279
|
+
entriesOf: (key) => this._core.entries(key),
|
|
1280
|
+
entriesOfSlot: (key) => this._core.entriesOfSlot(key),
|
|
1281
|
+
reportEntryError: (key, entry, error, info) => {
|
|
1282
|
+
this._core.reportEntryError(key, entry, error, info);
|
|
1283
|
+
},
|
|
1284
|
+
specOf: (key) => this._core.specDynamic(key),
|
|
1285
|
+
isLive: (entry) => this._core.isLive(entry),
|
|
1286
|
+
storeOf: (entry, scopeBinding) => entry.store === void 0 ? void 0 : this.resolveStore(entry.store, scopeBinding),
|
|
1287
|
+
root: this._rootSource,
|
|
1288
|
+
scopeRevision: this._scopeRevisionSource,
|
|
1289
|
+
scope: (scope) => service._scopes.get(scope === "session-maybe" ? "session" : scope),
|
|
1290
|
+
get locale() {
|
|
1291
|
+
return service._locale;
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
return this._host;
|
|
1295
|
+
}
|
|
1296
|
+
/** Validate and atomically publish the current root contribution roster. */
|
|
1297
|
+
rebuildRootBinding() {
|
|
1298
|
+
const hooks = {};
|
|
1299
|
+
const keyedHooks = {};
|
|
1300
|
+
const props = {};
|
|
1301
|
+
const finalProps = /* @__PURE__ */ new Set();
|
|
1302
|
+
for (const contribution of this._rootContributions) {
|
|
1303
|
+
copyUnique("hook", hooks, contribution.hooks, finalProps, _deepseek_ai_dsh_client_ui_slots.standardHookPropName);
|
|
1304
|
+
copyUnique("keyed hook", keyedHooks, contribution.keyedHooks, finalProps, _deepseek_ai_dsh_client_ui_slots.standardHookPropName);
|
|
1305
|
+
copyUnique("prop", props, contribution.props, finalProps, (name) => name);
|
|
1306
|
+
}
|
|
1307
|
+
this._rootBinding = {
|
|
1308
|
+
key: void 0,
|
|
1309
|
+
hooks,
|
|
1310
|
+
keyedHooks,
|
|
1311
|
+
props
|
|
1312
|
+
};
|
|
1313
|
+
for (const listener of [...this._rootListeners]) try {
|
|
1314
|
+
listener();
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
console.error("root standard-source subscriber failed:", error);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
/** Publish one installed-scope roster transition after the map is authoritative. */
|
|
1320
|
+
publishScopeRevision() {
|
|
1321
|
+
this._scopeRevision += 1;
|
|
1322
|
+
for (const listener of [...this._scopeListeners]) try {
|
|
1323
|
+
listener();
|
|
1324
|
+
} catch (error) {
|
|
1325
|
+
console.error("scope-adapter subscriber failed:", error);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
/** Resolve (create or reuse) the store instance for a registered handle under a scope key. */
|
|
1329
|
+
resolveStore(handle, scopeBinding) {
|
|
1330
|
+
const record = this._stores.get(handle);
|
|
1331
|
+
if (record === void 0) throw new Error("store handle is not registered (entry unloaded, or the handle never went through register)");
|
|
1332
|
+
let key;
|
|
1333
|
+
if (record.scope === "root") key = ROOT_INSTANCE_KEY;
|
|
1334
|
+
else {
|
|
1335
|
+
if (scopeBinding === void 0) throw new Error(`${record.scope} store resolution requires a session id`);
|
|
1336
|
+
key = scopeBinding.key;
|
|
1337
|
+
this.bindStoreScope(scopeBinding);
|
|
1338
|
+
}
|
|
1339
|
+
let instance = record.instances.get(key);
|
|
1340
|
+
if (instance === void 0) {
|
|
1341
|
+
instance = record.scope === "root" ? handle.create() : handle.create(key);
|
|
1342
|
+
record.instances.set(key, instance);
|
|
1343
|
+
}
|
|
1344
|
+
return instance;
|
|
1345
|
+
}
|
|
1346
|
+
/** Clear every live non-root Store handle for one dead scope key. */
|
|
1347
|
+
clearStoreScope(key) {
|
|
1348
|
+
for (const [handle, record] of this._stores) {
|
|
1349
|
+
if (record.scope === "root") continue;
|
|
1350
|
+
(record.instances.get(key) ?? handle.create(key)).clearPersisted();
|
|
1351
|
+
record.instances.delete(key);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
/** Bind (or re-reference) a handle on the axis; cross-scope conflicts already threw in the core. */
|
|
1355
|
+
_acquire(handle, scope) {
|
|
1356
|
+
const record = this._stores.get(handle);
|
|
1357
|
+
if (record === void 0) {
|
|
1358
|
+
this._stores.set(handle, {
|
|
1359
|
+
scope,
|
|
1360
|
+
refs: 1,
|
|
1361
|
+
instances: /* @__PURE__ */ new Map()
|
|
1362
|
+
});
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
record.refs += 1;
|
|
1366
|
+
}
|
|
1367
|
+
/** Drop one reference; the last holder's unload drops the record (instances go with it — engine stores need no explicit dispose). */
|
|
1368
|
+
_release(handle) {
|
|
1369
|
+
const record = this._stores.get(handle);
|
|
1370
|
+
/* v8 ignore next -- defensive: release only runs from a disposer whose
|
|
1371
|
+
* register acquired the same handle, so the record must exist; kept so a
|
|
1372
|
+
* future call site cannot underflow the axis. */
|
|
1373
|
+
if (record === void 0) return;
|
|
1374
|
+
record.refs -= 1;
|
|
1375
|
+
if (record.refs !== 0) return;
|
|
1376
|
+
this._stores.delete(handle);
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
function copyUnique(kind, target, values, finalProps, propNameOf) {
|
|
1380
|
+
if (values === void 0) return;
|
|
1381
|
+
for (const [name, value] of Object.entries(values)) {
|
|
1382
|
+
const propName = propNameOf(name);
|
|
1383
|
+
if (finalProps.has(propName)) throw new Error(`duplicate root standard ${kind} '${name}' at prop '${propName}'`);
|
|
1384
|
+
finalProps.add(propName);
|
|
1385
|
+
target[name] = value;
|
|
1386
|
+
}
|
|
930
1387
|
}
|
|
1388
|
+
SlotRegistry.prototype.register = function register(rawOptions, component) {
|
|
1389
|
+
const options = rawOptions;
|
|
1390
|
+
return this.ctx.effect(() => this["_register"](options, component), "slots.register()");
|
|
1391
|
+
};
|
|
931
1392
|
//#endregion
|
|
932
1393
|
//#region lib/types/client/index.js
|
|
933
1394
|
/**
|
|
@@ -936,7 +1397,7 @@ window.__ModuleLoader__.load({
|
|
|
936
1397
|
* kernel after the complete client roster settles.
|
|
937
1398
|
*/
|
|
938
1399
|
/** Services required before application assembly. */
|
|
939
|
-
const inject = [
|
|
1400
|
+
const inject = [];
|
|
940
1401
|
/** Hydrate the kernel-owned loading DOM before replacing it with the application. */
|
|
941
1402
|
function BootHandoff(props) {
|
|
942
1403
|
const [ready, setReady] = (0, react.useState)(false);
|
|
@@ -971,7 +1432,7 @@ window.__ModuleLoader__.load({
|
|
|
971
1432
|
* @param ctx - Plugin context.
|
|
972
1433
|
*/
|
|
973
1434
|
function apply(ctx) {
|
|
974
|
-
ctx.
|
|
1435
|
+
new SlotRegistry(ctx).install(createSlotRenderer());
|
|
975
1436
|
ctx.reflect.provide("uiRenderer", { mount: (container) => {
|
|
976
1437
|
const root = mountApp(container, buildRenderApp({ ctx }));
|
|
977
1438
|
return () => {
|
|
@@ -980,6 +1441,7 @@ window.__ModuleLoader__.load({
|
|
|
980
1441
|
} });
|
|
981
1442
|
}
|
|
982
1443
|
//#endregion
|
|
1444
|
+
exports.SlotRegistry = SlotRegistry;
|
|
983
1445
|
exports.apply = apply;
|
|
984
1446
|
exports.inject = inject;
|
|
985
1447
|
return module.exports;
|