@almadar/shell-web 0.1.0 → 1.1.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.
Files changed (131) hide show
  1. package/dist/{ArbitraryClassCompiler-Mzabq-UB.d.ts → ArbitraryClassCompiler-CO_iASBn.d.ts} +99 -4
  2. package/dist/AvlGlyph-PIXU6QH5.js +5 -0
  3. package/dist/AvlStateMachine-CKGMECMG.js +8 -0
  4. package/dist/AvlTransitionDetail-QZX6G5KJ.js +10 -0
  5. package/dist/AvlTransitionExplainer-26WLEIC6.js +11 -0
  6. package/dist/BehaviorView-JLZ4PKWY.js +10 -0
  7. package/dist/{EventBusProvider-CVwjkV_2.d.ts → EventBusProvider-BFFHfN4O.d.ts} +12 -0
  8. package/dist/{FileTree-BCFnBEuQ.d.ts → FileTree-B3GDAjaQ.d.ts} +131 -4
  9. package/dist/FlowCanvas-RPII4V24.js +23 -0
  10. package/dist/{BehaviorValueFrame-SSEMEBTG.css → FlowCanvas-VWUPMBKB.css} +189 -191
  11. package/dist/{GameAudioProvider-Cm9BnvmP.d.ts → GameAudioProvider-D7wo5ryN.d.ts} +5 -8
  12. package/dist/KernelEngineContext-CPeWQMAz.d.ts +46 -0
  13. package/dist/LayersPanel-M2LHWUFF.js +6 -0
  14. package/dist/ModuleCard-NJD6JQGD.js +6 -0
  15. package/dist/OrbInspector-OWWKPOBF.js +23 -0
  16. package/dist/{TraitValueFrame-4G3KOUBR.css → OrbInspector-VMTMZHNQ.css} +189 -191
  17. package/dist/{Select-mDZIwNqN.d.ts → Select-C2Uq6t86.d.ts} +17 -31
  18. package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
  19. package/dist/{FlowCanvas-3JRMNJLV.css → UISlotRenderer-BIS6KT7T.css} +189 -191
  20. package/dist/UISlotRenderer-PY7FIJXN.js +23 -0
  21. package/dist/auth/browser/index.js +1 -0
  22. package/dist/auth/react/index.d.ts +8 -1
  23. package/dist/auth/react/index.js +40 -2
  24. package/dist/avl/index.css +189 -191
  25. package/dist/avl/index.d.ts +107 -85
  26. package/dist/avl/index.js +170 -39
  27. package/dist/{chunk-P4LNHAFI.js → chunk-2WGR4TDJ.js} +465 -36
  28. package/dist/{chunk-GKIFONTE.js → chunk-3S54FWRC.js} +2 -2
  29. package/dist/{chunk-KVQS4GXU.js → chunk-4YJ53G7S.js} +18 -8
  30. package/dist/{chunk-MBQAMMSE.js → chunk-4YXBKHHM.js} +269 -658
  31. package/dist/{chunk-YDNJLLG6.js → chunk-57DC34LY.js} +19 -10
  32. package/dist/{chunk-FP3WIKTC.js → chunk-7N6ZPHQ5.js} +9 -1
  33. package/dist/{chunk-AILY3XPS.js → chunk-AE7VCQB6.js} +5 -6
  34. package/dist/{chunk-L677XGY3.js → chunk-AGVSO4WY.js} +4 -5
  35. package/dist/{chunk-FAJDTHWC.js → chunk-AGXD77SL.js} +2 -2
  36. package/dist/chunk-AU7O65OX.js +66 -0
  37. package/dist/{chunk-DFNZUYX4.js → chunk-FAKU5F62.js} +273 -29
  38. package/dist/{chunk-U6QRZASX.js → chunk-ILQXJ2AR.js} +1 -1
  39. package/dist/chunk-M74BCDBQ.js +490 -0
  40. package/dist/{chunk-GYTPOFVC.js → chunk-MS4K3K2R.js} +12095 -13329
  41. package/dist/{chunk-SGM3FASH.js → chunk-OWNG4JZI.js} +13 -12
  42. package/dist/{chunk-VFF5OO47.js → chunk-PCR37T3U.js} +15 -38
  43. package/dist/{chunk-SJGJJKBY.js → chunk-PRLHKBXG.js} +5 -3
  44. package/dist/{chunk-R5O5AUPI.js → chunk-PRXQGGCO.js} +93 -86
  45. package/dist/{chunk-42FY4RYA.js → chunk-REXYVBUO.js} +2 -2
  46. package/dist/{chunk-EQAMU2ZC.js → chunk-UTDC2NEA.js} +1 -1
  47. package/dist/{chunk-73SRAB4P.js → chunk-UU57VNS2.js} +2 -2
  48. package/dist/{chunk-TESBIVUA.js → chunk-VHC2M26B.js} +2 -2
  49. package/dist/{chunk-L2DEKY4J.js → chunk-VO2TTLS5.js} +3 -6
  50. package/dist/{chunk-2PY54Z44.js → chunk-VUIACGDU.js} +4 -5
  51. package/dist/{chunk-DLZF4PVE.js → chunk-YYIHRIDH.js} +3 -3
  52. package/dist/{chunk-DYEKAA4L.js → chunk-ZDRDJKYB.js} +243 -252
  53. package/dist/components/index.css +189 -191
  54. package/dist/components/index.d.ts +739 -289
  55. package/dist/components/index.js +25 -28
  56. package/dist/context/index.d.ts +2 -3
  57. package/dist/context/index.js +4 -3
  58. package/dist/core.d.ts +95 -19
  59. package/dist/core.js +2 -1
  60. package/dist/design-classes/index.cjs +3 -1
  61. package/dist/design-classes/index.js +3 -1
  62. package/dist/{fx-CmQjnHmT.d.ts → fx-Br8zjvu9.d.ts} +6 -6
  63. package/dist/hooks/index.d.ts +40 -5
  64. package/dist/hooks/index.js +5 -4
  65. package/dist/index.d.ts +40 -114
  66. package/dist/index.js +174 -34
  67. package/dist/kernel-client-JW6OH5FX.js +537 -0
  68. package/dist/kernel-wire-DGAySGhX.d.ts +95 -0
  69. package/dist/lib/index.d.ts +3 -4
  70. package/dist/lib/index.js +4 -4
  71. package/dist/{prism-AIWGN2X5.js → prism-X5YWKXO5.js} +5 -3
  72. package/dist/providers/index.css +189 -191
  73. package/dist/providers/index.d.ts +41 -28
  74. package/dist/providers/index.js +19 -24
  75. package/dist/renderer/index.d.ts +0 -2
  76. package/dist/renderer/index.js +1 -0
  77. package/dist/runtime/index.css +189 -191
  78. package/dist/runtime/index.d.ts +57 -253
  79. package/dist/runtime/index.js +18 -24
  80. package/dist/ssr/index.cjs +2643 -535
  81. package/dist/ssr/index.d.cts +0 -23
  82. package/dist/ssr/index.d.ts +0 -23
  83. package/dist/ssr/index.js +2639 -535
  84. package/dist/storage/browser/index.js +1 -0
  85. package/dist/test-support.d.ts +15 -8
  86. package/dist/test-support.js +91 -24
  87. package/dist/{paintDispatch-ChW5mVuK.d.ts → verificationRegistry-oopV1J1n.d.ts} +132 -30
  88. package/package.json +14 -38
  89. package/src/core/lib/band-shapes.json +7 -0
  90. package/src/core/locales/ar.json +18 -5
  91. package/src/core/locales/en.json +18 -5
  92. package/src/core/locales/sl.json +18 -5
  93. package/tailwind-preset.cjs +30 -1
  94. package/dist/AvlGlyph-JKJOAH23.js +0 -6
  95. package/dist/AvlStateMachine-PI4YGREK.js +0 -8
  96. package/dist/AvlTransitionDetail-ZH7V24UG.js +0 -12
  97. package/dist/AvlTransitionExplainer-ZSRT7L6Y.js +0 -13
  98. package/dist/BehaviorValueFrame-6RUJXT4A.js +0 -29
  99. package/dist/BehaviorView-RFEE5J6E.js +0 -10
  100. package/dist/Canvas3DHost-_Y-5uLM_.d.ts +0 -552
  101. package/dist/FlowCanvas-STDC4OWK.js +0 -27
  102. package/dist/KernelEngineContext-BOCQoFwk.d.ts +0 -43
  103. package/dist/LayersPanel-BBQ54IVG.js +0 -7
  104. package/dist/ModuleCard-3TT2X7IW.js +0 -7
  105. package/dist/OrbInspector-K6T6O7GI.js +0 -27
  106. package/dist/OrbInspector-MHLJ6OEE.css +0 -1756
  107. package/dist/ServerBridge-Cm1On51b.d.ts +0 -233
  108. package/dist/TraitValueFrame-2PJGLLVI.js +0 -28
  109. package/dist/UISlotRenderer-JKFSX24W.js +0 -27
  110. package/dist/UISlotRenderer-KVFO6J7R.css +0 -1756
  111. package/dist/UserContext-DqWeZkUZ.d.ts +0 -100
  112. package/dist/avl-3d-context-BIRKWpaL.d.ts +0 -204
  113. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +0 -132
  114. package/dist/avl-zoom-state-CKMVuBFg.d.ts +0 -17
  115. package/dist/chunk-2QOH2HWM.js +0 -95
  116. package/dist/chunk-6P3MWXYE.js +0 -440
  117. package/dist/chunk-B4BU77LT.js +0 -432
  118. package/dist/chunk-DJ433ET5.js +0 -1327
  119. package/dist/chunk-DZ42OJQC.js +0 -176
  120. package/dist/chunk-EOWMARUB.js +0 -16
  121. package/dist/chunk-FIW6WN23.js +0 -508
  122. package/dist/chunk-GAR5TQ5B.js +0 -199
  123. package/dist/chunk-PC7K4SK7.js +0 -1384
  124. package/dist/chunk-ZO6MXAS3.js +0 -69
  125. package/dist/kernel-client-ZH4PSMCN.js +0 -367
  126. package/dist/kernel-wire-B4S8pnP3.d.ts +0 -65
  127. package/dist/three/index.css +0 -503
  128. package/dist/three/index.d.ts +0 -1185
  129. package/dist/three/index.js +0 -3896
  130. package/dist/useKeyboardRouter-Dsq553Ur.d.ts +0 -42
  131. package/dist/verificationRegistry-CabxhfTv.d.ts +0 -122
@@ -1,508 +0,0 @@
1
- import { LoadingState, ErrorState, UISlotComponent, useKernelEngine, useClientTicks, KernelLoaderMissingError, LanguageLoaderMissingError, SeedProgramLoaderMissingError, kernelOrbitals, getTabClientId, createLazyKernelClient } from './chunk-GYTPOFVC.js';
2
- import { nativeMemoryPersistence, openLocalKernel, withForkedSeeder, mockStoreSeed_exports, local_store_transport_exports, trait_index_exports } from './chunk-DYEKAA4L.js';
3
- import { UISlotProvider, useUISlots } from './chunk-AILY3XPS.js';
4
- import { useEventBus, useRootEventBus, useTraitScopeChain, useTranslate } from './chunk-MBQAMMSE.js';
5
- import { createContext, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
6
- import { createMemoryCircuitStore } from '@almadar/shell-runtime/client/circuit-store';
7
- import { UI_SLOTS } from '@almadar/core';
8
- import { createLogger } from '@almadar/logger';
9
- import { jsxs, jsx } from 'react/jsx-runtime';
10
-
11
- var log = createLogger("almadar:ui:plugin-host");
12
- var UI_SLOT_SET = new Set(UI_SLOTS);
13
- function isUISlot(value) {
14
- return UI_SLOT_SET.has(value);
15
- }
16
- var OrbitalPluginHostContext = createContext(null);
17
- function useOrbitalPluginHostContext(caller) {
18
- const ctx = useContext(OrbitalPluginHostContext);
19
- if (!ctx) {
20
- throw new Error(`${caller} must be used within an <OrbitalPluginHost>.`);
21
- }
22
- return ctx;
23
- }
24
- function toTraitState(trait, stateName, lastEvent) {
25
- return { traitName: trait, currentState: stateName, previousState: null, lastEvent, context: {} };
26
- }
27
- function isKeymapValue(value) {
28
- if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
29
- return Object.values(value).every((entry) => Array.isArray(entry) && entry.every((k) => typeof k === "string"));
30
- }
31
- function findInlineTrait(schema, orbitalName, traitName) {
32
- const orbital = schema.orbitals.find((o) => o.name === orbitalName);
33
- if (!orbital) return void 0;
34
- for (const ref of orbital.traits) {
35
- if (typeof ref === "string") continue;
36
- if ("ref" in ref) continue;
37
- if (ref.name === traitName) return ref;
38
- }
39
- return void 0;
40
- }
41
- function readKeymapConfig(trait, knob) {
42
- const declared = trait?.config?.[knob]?.default;
43
- return isKeymapValue(declared) ? declared : {};
44
- }
45
- function traitNamesOf(orbital) {
46
- const names = [];
47
- for (const ref of orbital.traits) {
48
- if (typeof ref === "string") {
49
- names.push(ref);
50
- } else if ("ref" in ref) {
51
- if (ref.name) names.push(ref.name);
52
- } else {
53
- names.push(ref.name);
54
- }
55
- }
56
- return names;
57
- }
58
- function useDeclaredCaptureTable(opts) {
59
- const { pluginId, orbital, trait, keymapKnob = "keymap", target = "shell" } = opts;
60
- const ctx = useOrbitalPluginHostContext("useDeclaredCaptureTable");
61
- return useMemo(() => {
62
- const schema = ctx.getPluginSchema(pluginId);
63
- const inlineTrait = schema ? findInlineTrait(schema, orbital, trait) : void 0;
64
- const keymap = readKeymapConfig(inlineTrait, keymapKnob);
65
- const currentState = ctx.getState(pluginId, orbital, trait)?.currentState;
66
- const keys = currentState !== void 0 ? keymap[currentState] ?? [] : [];
67
- const entry = { mode: currentState ?? "unknown", keys: new Set(keys) };
68
- const targets = Array.isArray(target) ? target : [target];
69
- const table = {};
70
- for (const t of targets) table[t] = entry;
71
- return table;
72
- }, [ctx, pluginId, orbital, trait, keymapKnob, target]);
73
- }
74
- function useOrbitalPluginHost() {
75
- const ctx = useOrbitalPluginHostContext("useOrbitalPluginHost");
76
- return { getState: ctx.getState, lastEvent: ctx.lastEvent, errors: ctx.errors };
77
- }
78
- function paintClientEffects(id, effects, handlers) {
79
- for (const effect of effects) {
80
- switch (effect[0]) {
81
- case "render-ui":
82
- void handlers.renderUI?.(effect[1], effect[2]);
83
- break;
84
- case "navigate":
85
- handlers.navigate?.(effect[1], effect[2] ?? void 0, effect[3]?.crumb);
86
- break;
87
- case "navigate-back":
88
- if (handlers.navigateBack !== void 0) handlers.navigateBack();
89
- else log.warn("navigate-back:unhandled", { pluginId: id });
90
- break;
91
- }
92
- }
93
- }
94
- function buildMockEffectHandlers(opts) {
95
- const { pluginId, denySet, slotsRef, renderedSlotsRef, navigateRef } = opts;
96
- const handlers = {
97
- renderUI: (slot, pattern) => {
98
- if (!isUISlot(slot)) {
99
- log.warn("renderUI:unknown-slot", { pluginId, slot });
100
- return;
101
- }
102
- if (pattern === null) {
103
- slotsRef.current.clearBySource(slot, pluginId);
104
- return;
105
- }
106
- renderedSlotsRef.current.add(slot);
107
- const { type, ...inline } = pattern;
108
- slotsRef.current.render({
109
- target: slot,
110
- pattern: type,
111
- props: inline,
112
- sourceTrait: pluginId
113
- });
114
- }
115
- };
116
- if (denySet.has("navigate")) {
117
- handlers.navigate = (path) => log.warn("navigate:denied", { pluginId, path });
118
- } else if (navigateRef.current) {
119
- handlers.navigate = (path) => navigateRef.current?.(path);
120
- }
121
- return handlers;
122
- }
123
- function writeDeniedStore(pluginId, store) {
124
- return {
125
- create: async (entityType, _data) => {
126
- log.warn("persist:denied", { pluginId, action: "create", entityType });
127
- return { id: "" };
128
- },
129
- update: async (entityType, id) => {
130
- log.warn("persist:denied", { pluginId, action: "update", entityType, id });
131
- },
132
- delete: async (entityType, id) => {
133
- log.warn("persist:denied", { pluginId, action: "delete", entityType, id });
134
- },
135
- getById: (entityType, id) => store.getById(entityType, id),
136
- list: (entityType) => store.list(entityType)
137
- };
138
- }
139
- function openPluginKernel(plugin, engine, denySet) {
140
- if (engine === null) throw new KernelLoaderMissingError();
141
- const language = engine.loadLanguage !== void 0 ? engine.loadLanguage() : Promise.reject(new LanguageLoaderMissingError());
142
- const loadSeedProgram = engine.loadSeedProgram;
143
- const schema = plugin.schema;
144
- const opened = Promise.all([engine.loadModule(), language]).then(async ([kernel, bundle]) => {
145
- const rows = nativeMemoryPersistence(kernel);
146
- const persistence = denySet.has("persist") ? writeDeniedStore(plugin.id, rows) : rows;
147
- const server = openLocalKernel({
148
- kernel,
149
- language: bundle,
150
- schema,
151
- persistence,
152
- ...denySet.has("call-service") ? {
153
- callService: async (service, action) => {
154
- log.warn("call-service:denied", { pluginId: plugin.id, service, action });
155
- return null;
156
- }
157
- } : {}
158
- });
159
- if (loadSeedProgram === void 0) throw new SeedProgramLoaderMissingError();
160
- const { viewer } = await withForkedSeeder(
161
- server,
162
- schema,
163
- loadSeedProgram,
164
- rows,
165
- void 0,
166
- (host) => (0, mockStoreSeed_exports.seedMockStore)(host, schema, { namedByHost: false, current: () => void 0, seedIdentity: true })
167
- );
168
- server.seedRuntimeMock(viewer?.id);
169
- return { kernel, server, viewer };
170
- });
171
- opened.catch(() => void 0);
172
- const kernelEngine = opened.then((o) => o.server);
173
- kernelEngine.catch(() => void 0);
174
- const transport = (0, local_store_transport_exports.createLocalStoreTransport)({ kernelEngine, user: opened.then((o) => o.viewer) });
175
- const instance = opened.then(({ kernel, viewer }) => {
176
- const k = new kernel.Kernel(JSON.stringify({ name: schema.name, orbitals: kernelOrbitals(schema.orbitals), ...schema._metadata !== void 0 ? { _metadata: schema._metadata } : {} }), getTabClientId());
177
- k.setHostFansOut(true);
178
- if (viewer !== void 0) k.setCurrentUser(JSON.stringify(viewer));
179
- return k;
180
- });
181
- instance.catch(() => void 0);
182
- const traitIndex = (0, trait_index_exports.buildTraitIndex)(schema.orbitals);
183
- const client = createLazyKernelClient({
184
- instance,
185
- store: createMemoryCircuitStore(Array.from(traitIndex.byName.values(), (entry) => entry.traitDef)),
186
- traitIndex,
187
- transport,
188
- topology: Promise.resolve({ carriesCircuitState: false })
189
- });
190
- return { kernelEngine, client, instance, transport };
191
- }
192
- var HOST_TICKS = { startFrames: () => () => void 0 };
193
- function PluginRuntimeMount({
194
- plugin,
195
- mode,
196
- transport,
197
- deny,
198
- navigate,
199
- onTransition,
200
- onDispatched,
201
- onError
202
- }) {
203
- const bus = useEventBus();
204
- const rootBus = useRootEventBus();
205
- const chain = useTraitScopeChain();
206
- const relay = useCallback(
207
- (type, payload, source) => {
208
- const physical = { ...source };
209
- for (const key of /* @__PURE__ */ new Set([`UI:${type}`, ...chain.map((sc) => `UI:${sc.orbital}.${sc.trait}.${type}`)])) {
210
- rootBus.emit(key, payload, physical);
211
- }
212
- },
213
- [rootBus, chain]
214
- );
215
- const { locale } = useTranslate();
216
- const slots = useUISlots();
217
- const slotsRef = useRef(slots);
218
- slotsRef.current = slots;
219
- const renderedSlotsRef = useRef(/* @__PURE__ */ new Set());
220
- const navigateRef = useRef(navigate);
221
- navigateRef.current = navigate;
222
- const kernelEngineValue = useKernelEngine();
223
- const [mockHandlers] = useState(() => mode !== "mock" ? void 0 : buildMockEffectHandlers({
224
- pluginId: plugin.id,
225
- denySet: new Set(deny ?? []),
226
- slotsRef,
227
- renderedSlotsRef,
228
- navigateRef
229
- }));
230
- const denyRef = useRef(deny);
231
- const local = useMemo(
232
- () => mode !== "mock" ? void 0 : openPluginKernel(plugin, kernelEngineValue, new Set(denyRef.current ?? [])),
233
- // The kernel is the plugin's program: a new schema opens a new one.
234
- [mode, plugin.id, plugin.schema, kernelEngineValue]
235
- );
236
- const activeTransport = local?.transport ?? (mode === "server" ? transport : void 0);
237
- const engineRef = useRef(void 0);
238
- const registrationReady = useMemo(async () => {
239
- if (activeTransport === void 0) return;
240
- await activeTransport.register(plugin.schema);
241
- if (local !== void 0) engineRef.current = await local.instance;
242
- }, [activeTransport, local, plugin.schema]);
243
- useEffect(() => {
244
- if (mode === "server" && !transport) {
245
- onError(plugin.id, 'OrbitalPluginHost: mode "server" requires a transport');
246
- }
247
- }, [mode, transport, plugin.id, onError]);
248
- const teardownRef = useRef(null);
249
- useEffect(() => {
250
- if (teardownRef.current !== null && teardownRef.current.transport === activeTransport) {
251
- clearTimeout(teardownRef.current.timer);
252
- teardownRef.current = null;
253
- }
254
- return () => {
255
- const timer = setTimeout(() => {
256
- if (teardownRef.current?.timer === timer) teardownRef.current = null;
257
- if (activeTransport !== void 0) void activeTransport.unregister();
258
- void local?.kernelEngine.then((engine) => engine.dispose(), () => void 0);
259
- void local?.instance.then((instance) => {
260
- if (engineRef.current === instance) engineRef.current = void 0;
261
- instance.free();
262
- }, () => void 0);
263
- for (const slot of renderedSlotsRef.current) {
264
- slotsRef.current.clearBySource(slot, plugin.id);
265
- }
266
- }, 0);
267
- teardownRef.current = { transport: activeTransport, timer };
268
- };
269
- }, [activeTransport, local, plugin.id]);
270
- const ownOrbitals = useMemo(
271
- () => new Set(plugin.schema.orbitals.map((o) => o.name)),
272
- [plugin.schema]
273
- );
274
- const inboundVocabulary = useMemo(
275
- () => new Set(plugin.inbound.flatMap((row) => [row.busEvent, row.trigger])),
276
- [plugin.inbound]
277
- );
278
- const snapshotAllStates = useCallback((lastEvent) => {
279
- const engine = engineRef.current;
280
- const states = [];
281
- if (engine === void 0) return states;
282
- for (const orbital of plugin.schema.orbitals) {
283
- for (const traitName of traitNamesOf(orbital)) {
284
- const current = engine.getState(traitName);
285
- if (current !== "") states.push([orbital.name, traitName, toTraitState(traitName, current, lastEvent)]);
286
- }
287
- }
288
- return states;
289
- }, [plugin.schema]);
290
- useEffect(() => {
291
- let cancelled = false;
292
- void registrationReady.then(() => {
293
- if (cancelled) return;
294
- const states = snapshotAllStates(null);
295
- if (states.length > 0) onDispatched(plugin.id, null, states);
296
- }).catch((err) => {
297
- if (!cancelled) onError(plugin.id, err instanceof Error ? err.message : String(err));
298
- });
299
- return () => {
300
- cancelled = true;
301
- };
302
- }, [registrationReady, plugin.id, onDispatched, onError, snapshotAllStates]);
303
- const orbitalOfTrait = useMemo(
304
- () => new Map(plugin.schema.orbitals.flatMap((orbital) => traitNamesOf(orbital).map((trait) => [trait, orbital.name]))),
305
- [plugin.schema]
306
- );
307
- const settle = useCallback(
308
- (trigger, response, orbital) => {
309
- if (!response.success) {
310
- onError(plugin.id, response.error ?? `${plugin.id}: ${trigger ?? "tick"} failed`);
311
- }
312
- if (mockHandlers !== void 0) paintClientEffects(plugin.id, response.clientEffects ?? [], mockHandlers);
313
- for (const entry of response.emittedEvents ?? []) {
314
- if (inboundVocabulary.has(entry.event)) continue;
315
- if (plugin.outbound !== void 0 && !plugin.outbound.includes(entry.event)) continue;
316
- const sourceOrbital = entry.source?.orbital;
317
- if (sourceOrbital === void 0 || !ownOrbitals.has(sourceOrbital)) continue;
318
- relay(entry.event, entry.payload, entry.source);
319
- }
320
- const transitions = Object.entries(response.states).flatMap(([traitName, stateName]) => {
321
- const owner = orbital ?? orbitalOfTrait.get(traitName);
322
- return owner === void 0 ? [] : [[owner, traitName, stateName]];
323
- });
324
- const states = local !== void 0 ? snapshotAllStates(trigger) : transitions.map(([owner, traitName, stateName]) => [owner, traitName, toTraitState(traitName, stateName, trigger)]);
325
- for (const [owner, traitName, stateName] of transitions) onTransition?.(plugin.id, owner, traitName, stateName);
326
- onDispatched(plugin.id, trigger, states);
327
- },
328
- [local, mockHandlers, plugin, ownOrbitals, orbitalOfTrait, inboundVocabulary, relay, snapshotAllStates, onError, onTransition, onDispatched]
329
- );
330
- const dispatch = useCallback(
331
- async (row, payload) => {
332
- await registrationReady;
333
- const request = { event: row.trigger, payload, targetTrait: row.trait, locale };
334
- if (local !== void 0) {
335
- settle(row.trigger, (await local.client.dispatch(request)).response, row.orbital);
336
- return;
337
- }
338
- if (activeTransport === void 0) return;
339
- settle(row.trigger, await activeTransport.send(row.orbital, request), row.orbital);
340
- },
341
- [registrationReady, activeTransport, local, locale, settle]
342
- );
343
- const onKernelFrame = useCallback(
344
- (outcomes) => {
345
- for (const outcome of outcomes) {
346
- settle(null, outcome.response, void 0);
347
- void outcome.tickSettled?.then((added) => {
348
- if (added !== void 0 && mockHandlers !== void 0) paintClientEffects(plugin.id, added.clientEffects ?? [], mockHandlers);
349
- });
350
- }
351
- },
352
- [settle, mockHandlers, plugin.id]
353
- );
354
- useClientTicks({
355
- kernelClient: local?.client ?? HOST_TICKS,
356
- onKernelFrame,
357
- ...kernelEngineValue?.scheduleFrame !== void 0 ? { scheduleFrame: kernelEngineValue.scheduleFrame } : {},
358
- hostRunsProgram: local === void 0
359
- });
360
- useEffect(() => {
361
- const unsubs = plugin.inbound.flatMap((row) => {
362
- const keys = /* @__PURE__ */ new Set([`UI:${row.busEvent}`, ...chain.map((sc) => `UI:${sc.orbital}.${sc.trait}.${row.busEvent}`)]);
363
- const delivered = /* @__PURE__ */ new WeakSet();
364
- return Array.from(
365
- keys,
366
- (key) => bus.on(key, (event) => {
367
- if (event.source) {
368
- if (delivered.has(event.source)) return;
369
- delivered.add(event.source);
370
- }
371
- void dispatch(row, event.payload).catch((err) => {
372
- onError(plugin.id, err instanceof Error ? err.message : String(err));
373
- });
374
- })
375
- );
376
- });
377
- return () => {
378
- for (const unsub of unsubs) unsub();
379
- };
380
- }, [bus, plugin, dispatch, onError, chain]);
381
- return null;
382
- }
383
- function OrbitalPluginHost({
384
- plugins,
385
- mode = "mock",
386
- transport,
387
- deny,
388
- navigate,
389
- onTransition,
390
- children
391
- }) {
392
- const [tick, setTick] = useState(0);
393
- const [errors, setErrors] = useState({});
394
- const statesRef = useRef(/* @__PURE__ */ new Map());
395
- const lastEventRef = useRef(/* @__PURE__ */ new Map());
396
- const pluginSchemas = useMemo(
397
- () => new Map(plugins.map((plugin) => [plugin.id, plugin.schema])),
398
- [plugins]
399
- );
400
- const handleDispatched = useCallback(
401
- (pluginId, trigger, states) => {
402
- if (trigger !== null) {
403
- lastEventRef.current.set(pluginId, trigger);
404
- }
405
- let byKey = statesRef.current.get(pluginId);
406
- if (!byKey) {
407
- byKey = /* @__PURE__ */ new Map();
408
- statesRef.current.set(pluginId, byKey);
409
- }
410
- for (const [orbital, trait, state] of states) {
411
- byKey.set(`${orbital}.${trait}`, state);
412
- }
413
- setTick((t) => t + 1);
414
- },
415
- []
416
- );
417
- const handleError = useCallback((pluginId, message) => {
418
- setErrors((prev) => prev[pluginId] === message ? prev : { ...prev, [pluginId]: message });
419
- }, []);
420
- const contextValue = useMemo(
421
- () => ({
422
- getState: (pluginId, orbital, trait) => statesRef.current.get(pluginId)?.get(`${orbital}.${trait}`),
423
- lastEvent: (pluginId) => lastEventRef.current.get(pluginId),
424
- errors,
425
- tick,
426
- getPluginSchema: (pluginId) => pluginSchemas.get(pluginId)
427
- }),
428
- [errors, tick, pluginSchemas]
429
- );
430
- return /* @__PURE__ */ jsxs(OrbitalPluginHostContext.Provider, { value: contextValue, children: [
431
- plugins.map((plugin) => /* @__PURE__ */ jsx(
432
- PluginRuntimeMount,
433
- {
434
- plugin,
435
- mode,
436
- transport,
437
- deny,
438
- navigate,
439
- onTransition,
440
- onDispatched: handleDispatched,
441
- onError: handleError
442
- },
443
- plugin.id
444
- )),
445
- children ?? null
446
- ] });
447
- }
448
- var TraitValueMountContext = createContext(null);
449
- function TraitValueMountProvider({ host, children }) {
450
- return /* @__PURE__ */ jsx(TraitValueMountContext.Provider, { value: host, children });
451
- }
452
- function initEventOf(key) {
453
- return `TRAIT_VALUE_MOUNTED:${key}`;
454
- }
455
- function MountedInit({ event }) {
456
- const bus = useEventBus();
457
- useEffect(() => {
458
- bus.emit(`UI:${event}`, {});
459
- }, [bus, event]);
460
- return null;
461
- }
462
- function TraitValueFrame({ value }) {
463
- const host = useContext(TraitValueMountContext);
464
- const key = useMemo(() => JSON.stringify(value), [value]);
465
- const latest = useRef(value);
466
- latest.current = value;
467
- const [state, setState] = useState({ status: "loading" });
468
- useEffect(() => {
469
- const current = latest.current;
470
- if (host === null) {
471
- setState({ status: "error", message: `No trait-value host is configured to mount ${current.behavior}.traits.${current.trait}` });
472
- return;
473
- }
474
- let live = true;
475
- setState({ status: "loading" });
476
- void host.mount(current).then((result) => {
477
- if (!live) return;
478
- if (!result.ok) {
479
- const detail = (result.errors ?? []).map((e) => `${e.code}: ${e.message}`).join("\n");
480
- setState({ status: "error", message: detail.length > 0 ? `${result.error}
481
- ${detail}` : result.error });
482
- return;
483
- }
484
- const initEvent = initEventOf(key);
485
- setState({
486
- status: "ready",
487
- initEvent,
488
- plugin: {
489
- id: key,
490
- schema: result.mounted.schema,
491
- inbound: [{ busEvent: initEvent, orbital: result.mounted.orbital, trait: result.mounted.trait, trigger: "INIT" }]
492
- }
493
- });
494
- });
495
- return () => {
496
- live = false;
497
- };
498
- }, [host, key]);
499
- if (state.status === "loading") return /* @__PURE__ */ jsx(LoadingState, {});
500
- if (state.status === "error") return /* @__PURE__ */ jsx(ErrorState, { message: state.message });
501
- return /* @__PURE__ */ jsx(UISlotProvider, { children: /* @__PURE__ */ jsxs(OrbitalPluginHost, { plugins: [state.plugin], mode: host?.mode ?? "mock", transport: host?.transport, children: [
502
- /* @__PURE__ */ jsx(MountedInit, { event: state.initEvent }),
503
- /* @__PURE__ */ jsx(UISlotComponent, { slot: "main" })
504
- ] }) });
505
- }
506
- var TraitValueFrame_default = TraitValueFrame;
507
-
508
- export { MountedInit, OrbitalPluginHost, TraitValueFrame, TraitValueFrame_default, TraitValueMountContext, TraitValueMountProvider, useDeclaredCaptureTable, useOrbitalPluginHost };