@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.
- package/dist/{ArbitraryClassCompiler-Mzabq-UB.d.ts → ArbitraryClassCompiler-CO_iASBn.d.ts} +99 -4
- package/dist/AvlGlyph-PIXU6QH5.js +5 -0
- package/dist/AvlStateMachine-CKGMECMG.js +8 -0
- package/dist/AvlTransitionDetail-QZX6G5KJ.js +10 -0
- package/dist/AvlTransitionExplainer-26WLEIC6.js +11 -0
- package/dist/BehaviorView-JLZ4PKWY.js +10 -0
- package/dist/{EventBusProvider-CVwjkV_2.d.ts → EventBusProvider-BFFHfN4O.d.ts} +12 -0
- package/dist/{FileTree-BCFnBEuQ.d.ts → FileTree-B3GDAjaQ.d.ts} +131 -4
- package/dist/FlowCanvas-RPII4V24.js +23 -0
- package/dist/{BehaviorValueFrame-SSEMEBTG.css → FlowCanvas-VWUPMBKB.css} +189 -191
- package/dist/{GameAudioProvider-Cm9BnvmP.d.ts → GameAudioProvider-D7wo5ryN.d.ts} +5 -8
- package/dist/KernelEngineContext-CPeWQMAz.d.ts +46 -0
- package/dist/LayersPanel-M2LHWUFF.js +6 -0
- package/dist/ModuleCard-NJD6JQGD.js +6 -0
- package/dist/OrbInspector-OWWKPOBF.js +23 -0
- package/dist/{TraitValueFrame-4G3KOUBR.css → OrbInspector-VMTMZHNQ.css} +189 -191
- package/dist/{Select-mDZIwNqN.d.ts → Select-C2Uq6t86.d.ts} +17 -31
- package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
- package/dist/{FlowCanvas-3JRMNJLV.css → UISlotRenderer-BIS6KT7T.css} +189 -191
- package/dist/UISlotRenderer-PY7FIJXN.js +23 -0
- package/dist/auth/browser/index.js +1 -0
- package/dist/auth/react/index.d.ts +8 -1
- package/dist/auth/react/index.js +40 -2
- package/dist/avl/index.css +189 -191
- package/dist/avl/index.d.ts +107 -85
- package/dist/avl/index.js +170 -39
- package/dist/{chunk-P4LNHAFI.js → chunk-2WGR4TDJ.js} +465 -36
- package/dist/{chunk-GKIFONTE.js → chunk-3S54FWRC.js} +2 -2
- package/dist/{chunk-KVQS4GXU.js → chunk-4YJ53G7S.js} +18 -8
- package/dist/{chunk-MBQAMMSE.js → chunk-4YXBKHHM.js} +269 -658
- package/dist/{chunk-YDNJLLG6.js → chunk-57DC34LY.js} +19 -10
- package/dist/{chunk-FP3WIKTC.js → chunk-7N6ZPHQ5.js} +9 -1
- package/dist/{chunk-AILY3XPS.js → chunk-AE7VCQB6.js} +5 -6
- package/dist/{chunk-L677XGY3.js → chunk-AGVSO4WY.js} +4 -5
- package/dist/{chunk-FAJDTHWC.js → chunk-AGXD77SL.js} +2 -2
- package/dist/chunk-AU7O65OX.js +66 -0
- package/dist/{chunk-DFNZUYX4.js → chunk-FAKU5F62.js} +273 -29
- package/dist/{chunk-U6QRZASX.js → chunk-ILQXJ2AR.js} +1 -1
- package/dist/chunk-M74BCDBQ.js +490 -0
- package/dist/{chunk-GYTPOFVC.js → chunk-MS4K3K2R.js} +12095 -13329
- package/dist/{chunk-SGM3FASH.js → chunk-OWNG4JZI.js} +13 -12
- package/dist/{chunk-VFF5OO47.js → chunk-PCR37T3U.js} +15 -38
- package/dist/{chunk-SJGJJKBY.js → chunk-PRLHKBXG.js} +5 -3
- package/dist/{chunk-R5O5AUPI.js → chunk-PRXQGGCO.js} +93 -86
- package/dist/{chunk-42FY4RYA.js → chunk-REXYVBUO.js} +2 -2
- package/dist/{chunk-EQAMU2ZC.js → chunk-UTDC2NEA.js} +1 -1
- package/dist/{chunk-73SRAB4P.js → chunk-UU57VNS2.js} +2 -2
- package/dist/{chunk-TESBIVUA.js → chunk-VHC2M26B.js} +2 -2
- package/dist/{chunk-L2DEKY4J.js → chunk-VO2TTLS5.js} +3 -6
- package/dist/{chunk-2PY54Z44.js → chunk-VUIACGDU.js} +4 -5
- package/dist/{chunk-DLZF4PVE.js → chunk-YYIHRIDH.js} +3 -3
- package/dist/{chunk-DYEKAA4L.js → chunk-ZDRDJKYB.js} +243 -252
- package/dist/components/index.css +189 -191
- package/dist/components/index.d.ts +739 -289
- package/dist/components/index.js +25 -28
- package/dist/context/index.d.ts +2 -3
- package/dist/context/index.js +4 -3
- package/dist/core.d.ts +95 -19
- package/dist/core.js +2 -1
- package/dist/design-classes/index.cjs +3 -1
- package/dist/design-classes/index.js +3 -1
- package/dist/{fx-CmQjnHmT.d.ts → fx-Br8zjvu9.d.ts} +6 -6
- package/dist/hooks/index.d.ts +40 -5
- package/dist/hooks/index.js +5 -4
- package/dist/index.d.ts +40 -114
- package/dist/index.js +174 -34
- package/dist/kernel-client-JW6OH5FX.js +537 -0
- package/dist/kernel-wire-DGAySGhX.d.ts +95 -0
- package/dist/lib/index.d.ts +3 -4
- package/dist/lib/index.js +4 -4
- package/dist/{prism-AIWGN2X5.js → prism-X5YWKXO5.js} +5 -3
- package/dist/providers/index.css +189 -191
- package/dist/providers/index.d.ts +41 -28
- package/dist/providers/index.js +19 -24
- package/dist/renderer/index.d.ts +0 -2
- package/dist/renderer/index.js +1 -0
- package/dist/runtime/index.css +189 -191
- package/dist/runtime/index.d.ts +57 -253
- package/dist/runtime/index.js +18 -24
- package/dist/ssr/index.cjs +2643 -535
- package/dist/ssr/index.d.cts +0 -23
- package/dist/ssr/index.d.ts +0 -23
- package/dist/ssr/index.js +2639 -535
- package/dist/storage/browser/index.js +1 -0
- package/dist/test-support.d.ts +15 -8
- package/dist/test-support.js +91 -24
- package/dist/{paintDispatch-ChW5mVuK.d.ts → verificationRegistry-oopV1J1n.d.ts} +132 -30
- package/package.json +14 -38
- package/src/core/lib/band-shapes.json +7 -0
- package/src/core/locales/ar.json +18 -5
- package/src/core/locales/en.json +18 -5
- package/src/core/locales/sl.json +18 -5
- package/tailwind-preset.cjs +30 -1
- package/dist/AvlGlyph-JKJOAH23.js +0 -6
- package/dist/AvlStateMachine-PI4YGREK.js +0 -8
- package/dist/AvlTransitionDetail-ZH7V24UG.js +0 -12
- package/dist/AvlTransitionExplainer-ZSRT7L6Y.js +0 -13
- package/dist/BehaviorValueFrame-6RUJXT4A.js +0 -29
- package/dist/BehaviorView-RFEE5J6E.js +0 -10
- package/dist/Canvas3DHost-_Y-5uLM_.d.ts +0 -552
- package/dist/FlowCanvas-STDC4OWK.js +0 -27
- package/dist/KernelEngineContext-BOCQoFwk.d.ts +0 -43
- package/dist/LayersPanel-BBQ54IVG.js +0 -7
- package/dist/ModuleCard-3TT2X7IW.js +0 -7
- package/dist/OrbInspector-K6T6O7GI.js +0 -27
- package/dist/OrbInspector-MHLJ6OEE.css +0 -1756
- package/dist/ServerBridge-Cm1On51b.d.ts +0 -233
- package/dist/TraitValueFrame-2PJGLLVI.js +0 -28
- package/dist/UISlotRenderer-JKFSX24W.js +0 -27
- package/dist/UISlotRenderer-KVFO6J7R.css +0 -1756
- package/dist/UserContext-DqWeZkUZ.d.ts +0 -100
- package/dist/avl-3d-context-BIRKWpaL.d.ts +0 -204
- package/dist/avl-schema-parser-CtJxJ9KU.d.ts +0 -132
- package/dist/avl-zoom-state-CKMVuBFg.d.ts +0 -17
- package/dist/chunk-2QOH2HWM.js +0 -95
- package/dist/chunk-6P3MWXYE.js +0 -440
- package/dist/chunk-B4BU77LT.js +0 -432
- package/dist/chunk-DJ433ET5.js +0 -1327
- package/dist/chunk-DZ42OJQC.js +0 -176
- package/dist/chunk-EOWMARUB.js +0 -16
- package/dist/chunk-FIW6WN23.js +0 -508
- package/dist/chunk-GAR5TQ5B.js +0 -199
- package/dist/chunk-PC7K4SK7.js +0 -1384
- package/dist/chunk-ZO6MXAS3.js +0 -69
- package/dist/kernel-client-ZH4PSMCN.js +0 -367
- package/dist/kernel-wire-B4S8pnP3.d.ts +0 -65
- package/dist/three/index.css +0 -503
- package/dist/three/index.d.ts +0 -1185
- package/dist/three/index.js +0 -3896
- package/dist/useKeyboardRouter-Dsq553Ur.d.ts +0 -42
- package/dist/verificationRegistry-CabxhfTv.d.ts +0 -122
package/dist/chunk-FIW6WN23.js
DELETED
|
@@ -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 };
|