@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,69 +0,0 @@
1
- import { createContext, useMemo, useContext } from 'react';
2
- import { createLogger } from '@almadar/logger';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- var log = createLogger("almadar:ui:trait-provider");
6
- var TraitContext = createContext(null);
7
- function TraitProvider({
8
- traits: traitBindings,
9
- children
10
- }) {
11
- const traitInstances = useMemo(() => {
12
- const map = /* @__PURE__ */ new Map();
13
- for (const binding of traitBindings) {
14
- const trait = binding.trait;
15
- const initialState = trait.states.find((s) => s.isInitial);
16
- const stateName = initialState?.name || trait.states[0]?.name || "idle";
17
- const instance = {
18
- name: trait.name,
19
- currentState: stateName,
20
- availableEvents: trait.transitions.filter((t) => t.from === stateName).map((t) => t.event),
21
- dispatch: (eventKey, payload) => {
22
- log.debug("Dispatch", () => ({
23
- trait: trait.name,
24
- event: eventKey,
25
- payloadKeys: payload ? Object.keys(payload) : []
26
- }));
27
- },
28
- canDispatch: (eventKey) => {
29
- return trait.transitions.some(
30
- (t) => t.from === stateName && t.event === eventKey
31
- );
32
- },
33
- trait
34
- };
35
- map.set(trait.name, instance);
36
- }
37
- return map;
38
- }, [traitBindings]);
39
- const contextValue = useMemo(() => {
40
- return {
41
- traits: traitInstances,
42
- getTrait: (name) => traitInstances.get(name),
43
- dispatchToTrait: (traitName, eventKey, payload) => {
44
- const instance = traitInstances.get(traitName);
45
- if (instance) {
46
- instance.dispatch(eventKey, payload);
47
- }
48
- },
49
- canDispatch: (traitName, eventKey) => {
50
- const instance = traitInstances.get(traitName);
51
- return instance?.canDispatch(eventKey) || false;
52
- }
53
- };
54
- }, [traitInstances]);
55
- return /* @__PURE__ */ jsx(TraitContext.Provider, { value: contextValue, children });
56
- }
57
- function useTraitContext() {
58
- const context = useContext(TraitContext);
59
- if (!context) {
60
- throw new Error("useTraitContext must be used within a TraitProvider");
61
- }
62
- return context;
63
- }
64
- function useTrait(traitName) {
65
- const context = useTraitContext();
66
- return context.getTrait(traitName);
67
- }
68
-
69
- export { TraitContext, TraitProvider, useTrait, useTraitContext };
@@ -1,367 +0,0 @@
1
- import { createLocalFold, src_exports, createTickDriver, runTickFrame, mirrorResponse, traceResponse } from './chunk-6P3MWXYE.js';
2
- import './chunk-DYEKAA4L.js';
3
- import { presenceGroup, getTraitPresence } from './chunk-MBQAMMSE.js';
4
- import './chunk-G7DCAZ22.js';
5
- import { TraitMountError } from '@almadar/shell-runtime/client/trait-mount-error';
6
- import { createLogger } from '@almadar/logger';
7
-
8
- var log = createLogger("almadar:ui:kernel-client");
9
- var defaultFrameScheduler = (callback) => {
10
- if (typeof requestAnimationFrame === "function") {
11
- const handle = requestAnimationFrame(callback);
12
- return () => cancelAnimationFrame(handle);
13
- }
14
- const timer = setTimeout(() => callback(performance.now()), 16);
15
- return () => clearTimeout(timer);
16
- };
17
- function parse(text) {
18
- return JSON.parse(text);
19
- }
20
- function payloadJson(payload) {
21
- return payload === void 0 ? void 0 : JSON.stringify(payload);
22
- }
23
- function createKernelClient(opts) {
24
- const { store, traitIndex, transport } = opts;
25
- let loaded;
26
- const configs = /* @__PURE__ */ new Map();
27
- const ready = opts.instance.then((k) => {
28
- loaded = k;
29
- return k;
30
- });
31
- ready.catch(() => void 0);
32
- const visibleGroups = [...traitIndex.byName].filter(([, entry]) => (entry.irTrait.ticks ?? []).some((tick) => tick.whileVisible === true)).map(([name]) => [name, presenceGroup(traitIndex, name)]);
33
- let queueTail = Promise.resolve();
34
- const enqueue = (run) => {
35
- const result = queueTail.then(run);
36
- queueTail = result.then(() => void 0, () => void 0);
37
- return result;
38
- };
39
- let progressTail = Promise.resolve();
40
- let scopeTail = Promise.resolve();
41
- const declareScope = (apply) => {
42
- const applied = scopeTail.then(() => ready).then(apply);
43
- scopeTail = applied.then(() => void 0, () => void 0);
44
- return applied;
45
- };
46
- const frameKeyOf = (trait) => traitIndex.byName.get(trait)?.frameKey;
47
- const mirror = (response) => mirrorResponse(store, frameKeyOf, response);
48
- const trace = (response) => traceResponse(opts.observer, response);
49
- const localFold = createLocalFold({ store, frameKeyOf, ...opts.observer !== void 0 ? { observer: opts.observer } : {} });
50
- const lane = new src_exports.DispatchLane();
51
- const syncStates = (k, traits) => {
52
- for (const trait of traits) {
53
- const state = k.getState(trait);
54
- if (state !== "" && store.states.getState(trait)?.currentState !== state) store.states.seedState(trait, state);
55
- }
56
- };
57
- const restore = (k, wire, entityId) => {
58
- const snapshot = wire.snapshot;
59
- if (snapshot === null) return { clientEffects: [], clientEffectsByTrait: [] };
60
- const trait = wire.seed.trait;
61
- const repaint = parse(k.restore(trait, entityId, JSON.stringify(snapshot)));
62
- const frameKey = traitIndex.byName.get(trait)?.frameKey ?? trait;
63
- if (snapshot.state !== "") store.states.rollbackState(trait, snapshot.state, entityId, "server-rejected");
64
- const entity = snapshot.entity;
65
- if (entity !== null && typeof entity === "object" && !Array.isArray(entity)) store.frames.set(frameKey, { ...entity });
66
- else store.frames.delete(frameKey);
67
- mirror(repaint);
68
- store.notify();
69
- return { clientEffects: repaint.clientEffects ?? [], clientEffectsByTrait: repaint.clientEffectsByTrait ?? [] };
70
- };
71
- const planDispatch = (wire, carriesCircuitState) => {
72
- if (wire.serverLegs.length > 0) {
73
- return {
74
- awaiting: wire.awaiting,
75
- legs: wire.serverLegs.map(({ orbital, leg }) => ({
76
- orbital,
77
- leg,
78
- keepsState: carriesCircuitState || wire.mode === "hybridClientOnly",
79
- alreadyDelivered: wire.alreadyDelivered,
80
- foldSeeded: wire.foldSeeded,
81
- wires: [wire]
82
- }))
83
- };
84
- }
85
- if (!carriesCircuitState && wire.statefulLeg !== null) {
86
- return {
87
- awaiting: wire.statefulLeg.awaiting,
88
- legs: [{ orbital: wire.statefulLeg.orbital, leg: wire.statefulLeg.leg, keepsState: true, alreadyDelivered: wire.alreadyDelivered, foldSeeded: [], wires: [wire] }]
89
- };
90
- }
91
- return { legs: [], awaiting: [] };
92
- };
93
- const sendLegs = async (k, legs, request, flags, initial) => {
94
- const out = {
95
- response: initial,
96
- serverEffects: { clientEffects: [], clientEffectsByTrait: [] },
97
- success: true,
98
- rejections: [],
99
- foldedEmits: []
100
- };
101
- if (transport === void 0) return out;
102
- const queue = [...legs];
103
- for (let planned = queue.shift(); planned !== void 0; planned = queue.shift()) {
104
- const shaped = planned.keepsState ? planned.leg : JSON.parse(k.statefulLeg(JSON.stringify(planned.leg)));
105
- const sent = request.locale !== void 0 ? { ...shaped, locale: request.locale } : shaped;
106
- const base = k.foldBase(sent.entityByTrait !== void 0 ? JSON.stringify(sent.entityByTrait) : void 0, JSON.stringify(planned.foldSeeded), sent.entityId);
107
- let posted;
108
- try {
109
- posted = await transport.send(planned.orbital, sent);
110
- } catch (err) {
111
- if (flags.rollback || flags.mount) for (const wire of planned.wires) restore(k, wire, request.entityId);
112
- throw err instanceof Error ? err : new Error(String(err));
113
- }
114
- if (!posted.success) {
115
- const optimistic = planned.wires.filter((wire) => wire.mode === "runtimeOptimistic");
116
- if (flags.rollback && optimistic.length > 0) {
117
- return { ...out, response: posted, success: false, rolledBack: restore(k, optimistic[0], request.entityId) };
118
- }
119
- if (flags.mount) for (const wire of optimistic) restore(k, wire, request.entityId);
120
- }
121
- const applied = parse(k.applyServerResponse(JSON.stringify(posted), JSON.stringify(planned.alreadyDelivered), base));
122
- log.debug("fold", { orbital: planned.orbital, event: sent.event, posted: { success: posted.success, states: posted.states, emitted: posted.emittedEvents.map((e) => e.event) }, applied: applied.applied, cascadeEmitted: applied.response.emittedEvents.map((e) => e.event) });
123
- trace(applied.response);
124
- for (const routed of applied.serverLegs) {
125
- queue.push({ orbital: routed.orbital, leg: routed.leg, keepsState: true, alreadyDelivered: [], foldSeeded: [], wires: [] });
126
- }
127
- mirror(posted);
128
- mirror(applied.response);
129
- syncStates(k, [...Object.keys(posted.states), ...applied.applied.map(([trait]) => trait)]);
130
- store.notify();
131
- const fold = applied.response;
132
- const delivered = new Set(planned.alreadyDelivered.map(([trait, event]) => `${trait}\0${event}`));
133
- const serverEmits = posted.emittedEvents.filter((e) => !delivered.has(`${e.source?.trait ?? ""}\0${e.event}`));
134
- const effects = [...posted.clientEffects ?? [], ...fold.clientEffects ?? []];
135
- const byTrait = [...posted.clientEffectsByTrait ?? [], ...fold.clientEffectsByTrait ?? []];
136
- out.serverEffects.clientEffects?.push(...effects);
137
- out.serverEffects.clientEffectsByTrait?.push(...byTrait);
138
- out.foldedEmits.push(...serverEmits, ...fold.emittedEvents);
139
- out.response = {
140
- ...out.response,
141
- emittedEvents: [...out.response.emittedEvents, ...serverEmits, ...fold.emittedEvents],
142
- clientEffects: [...out.response.clientEffects ?? [], ...effects],
143
- clientEffectsByTrait: [...out.response.clientEffectsByTrait ?? [], ...byTrait],
144
- effectResults: [...out.response.effectResults ?? [], ...fold.effectResults ?? []]
145
- };
146
- out.success = out.success && posted.success;
147
- if (posted.error !== void 0) out.error = posted.error;
148
- out.rejections.push(...(fold.rejections ?? []).filter((r) => r.code === "effect-failed"));
149
- }
150
- return out;
151
- };
152
- const post = async (k, wire, request, flags) => {
153
- const topology = await opts.topology;
154
- const plan = planDispatch(wire, topology.carriesCircuitState);
155
- const awaiting = flags.awaiting ? plan.awaiting : [];
156
- store.awaiting.begin(awaiting);
157
- try {
158
- return await sendLegs(k, plan.legs, request, { rollback: flags.rollback, mount: false }, wire.response);
159
- } finally {
160
- store.awaiting.end(awaiting.map((a) => a.trait));
161
- }
162
- };
163
- const framePost = (k) => {
164
- if (transport === void 0) return void 0;
165
- return {
166
- postDispatch: async (wire) => (await post(k, wire, {}, { rollback: false, awaiting: false })).serverEffects,
167
- sendBrowserLeg: async (routed, frameResponse) => {
168
- const planned = { orbital: routed.orbital, leg: routed.leg, keepsState: true, alreadyDelivered: [], foldSeeded: [], wires: [] };
169
- return (await sendLegs(k, [planned], {}, { rollback: false, mount: false }, frameResponse)).serverEffects;
170
- }
171
- };
172
- };
173
- const tickPorts = (k) => ({
174
- kernel: {
175
- frame: (nowMs) => {
176
- const presence = getTraitPresence();
177
- for (const [traitName, group] of visibleGroups) k.setTraitOnScreen(traitName, presence.state(group) !== "off-screen");
178
- return k.frame(nowMs);
179
- },
180
- framePause: () => k.framePause(),
181
- frameResume: () => k.frameResume(),
182
- tickCount: () => k.tickCount()
183
- },
184
- lane,
185
- client: localFold,
186
- post: framePost(k)
187
- });
188
- const dispatchOne = async (request, hooks, progress) => {
189
- const traitName = request.targetTrait;
190
- if (traitName === void 0) throw new Error("dispatch requires request.targetTrait (the seed trait)");
191
- const k = await ready;
192
- if (request.runTick !== void 0) {
193
- const response = parse(k.tick(request.runTick.trait, request.runTick.tick, request.entityId));
194
- mirror(response);
195
- store.notify();
196
- return { response, mode: parse(k.dispatchMode(request.runTick.trait)) };
197
- }
198
- const wire = parse(k.dispatch(traitName, request.entityId, request.event, payloadJson(request.payload)));
199
- log.debug("dispatch", { trait: traitName, event: request.event, mode: wire.mode, legs: wire.serverLegs.length, success: wire.response.success, states: wire.response.states, effects: (wire.response.clientEffectsByTrait ?? []).map((e) => `${e.traitName}:${e.effect[0]}:${e.effect[1] ?? ""}`), emitted: wire.response.emittedEvents.map((e) => e.event) });
200
- trace(wire.response);
201
- mirror(wire.response);
202
- store.notify();
203
- if (transport === void 0 || wire.serverLegs.length === 0 && wire.statefulLeg === null) return { response: wire.response, mode: wire.mode };
204
- const painters = hooks.filter((h) => h.onLocal !== void 0);
205
- for (const h of painters) h.onLocal?.(wire.response);
206
- const posted = await post(k, wire, request, { rollback: true, awaiting: !progress });
207
- const localPainted = painters.length > 0;
208
- if (posted.rolledBack !== void 0) {
209
- return { response: posted.response, mode: wire.mode, ...localPainted ? { localPainted, serverEffects: posted.rolledBack } : {} };
210
- }
211
- return localPainted ? { response: posted.response, mode: wire.mode, localPainted, serverEffects: posted.serverEffects } : { response: posted.response, mode: wire.mode };
212
- };
213
- const client = {
214
- store,
215
- dispatch: (request, hooks) => enqueue(() => dispatchOne(request, hooks !== void 0 ? [hooks] : [], false)),
216
- dispatchProgress: (request) => {
217
- const outcome = progressTail.then(() => dispatchOne(request, [], true));
218
- progressTail = outcome.then(() => void 0, () => void 0);
219
- return outcome;
220
- },
221
- foldHostDispatch: (request, response) => enqueue(async () => {
222
- const k = await ready;
223
- if (request.targetTrait === void 0) throw new Error("foldHostDispatch requires request.targetTrait (the seed trait)");
224
- const mode = parse(k.dispatchMode(request.targetTrait));
225
- if (!response.success) return { response: { ...response, clientEffects: [], clientEffectsByTrait: [] }, mode };
226
- const applied = parse(k.applyServerResponse(JSON.stringify(response), "[]"));
227
- trace(applied.response);
228
- mirror(response);
229
- mirror(applied.response);
230
- syncStates(k, [...Object.keys(response.states), ...applied.applied.map(([trait]) => trait)]);
231
- store.notify();
232
- return {
233
- response: {
234
- ...response,
235
- clientEffects: [...response.clientEffects ?? [], ...applied.response.clientEffects ?? []],
236
- clientEffectsByTrait: [...response.clientEffectsByTrait ?? [], ...applied.response.clientEffectsByTrait ?? []]
237
- },
238
- mode
239
- };
240
- }),
241
- dispatchMount: (seeds, hooks, base) => enqueue(async () => {
242
- const k = await ready;
243
- await scopeTail;
244
- const baseRequest = base ?? {};
245
- k.mount(JSON.stringify(seeds.map((s) => s.trait)));
246
- const mount = parse(k.dispatchMount(JSON.stringify(seeds), baseRequest.entityId, payloadJson(baseRequest.payload)));
247
- if (mount.failed !== null) {
248
- const failed = mount.failed;
249
- throw new TraitMountError(failed.trait, failed.event, new Error(failed.message));
250
- }
251
- const wires = mount.seeds;
252
- for (const wire of wires) {
253
- log.debug("mount", { trait: wire.seed.trait, event: wire.seed.event, mode: wire.mode, legs: wire.serverLegs.length, success: wire.response.success });
254
- trace(wire.response);
255
- mirror(wire.response);
256
- }
257
- store.notify();
258
- for (const wire of wires) hooks?.onLocal?.(wire.seed.trait, wire.response);
259
- const outcome = {
260
- seeds: wires.map((w) => ({ trait: w.seed.trait, event: w.seed.event, mode: w.mode, local: w.response })),
261
- posted: false,
262
- success: true,
263
- rejections: [],
264
- serverEffects: { clientEffects: [], clientEffectsByTrait: [] },
265
- emittedEvents: []
266
- };
267
- if (transport === void 0) return outcome;
268
- const topology = await opts.topology;
269
- for (const group of topology.carriesCircuitState ? mount.legs : mount.statefulLegs) {
270
- const answered = wires.filter((w) => group.seeds.some((s) => s.trait === w.seed.trait && s.event === w.seed.event));
271
- const planned = { orbital: group.orbital, leg: group.leg, keepsState: true, alreadyDelivered: group.alreadyDelivered, foldSeeded: group.foldSeeded, wires: answered };
272
- store.awaiting.begin(group.awaiting);
273
- let posted;
274
- try {
275
- posted = await sendLegs(k, [planned], baseRequest, { rollback: false, mount: true }, answered[0]?.response ?? outcome.seeds[0].local);
276
- } finally {
277
- store.awaiting.end(group.awaiting.map((a) => a.trait));
278
- }
279
- outcome.posted = true;
280
- outcome.success = outcome.success && posted.success;
281
- if (posted.error !== void 0) outcome.error = posted.error;
282
- outcome.rejections.push(...posted.rejections);
283
- outcome.serverEffects.clientEffects?.push(...posted.serverEffects.clientEffects ?? []);
284
- outcome.serverEffects.clientEffectsByTrait?.push(...posted.serverEffects.clientEffectsByTrait ?? []);
285
- outcome.emittedEvents.push(...posted.foldedEmits);
286
- }
287
- return outcome;
288
- }),
289
- routeMounts: async (routePath) => parse((await ready).routeMounts(routePath)),
290
- remount: (traits) => declareScope((k) => k.remount(JSON.stringify(traits))),
291
- mount: (traits) => declareScope((k) => k.mount(JSON.stringify(traits))),
292
- unmount: (traits) => declareScope((k) => k.unmount(JSON.stringify(traits))),
293
- frame: async (nowMs) => {
294
- const k = await ready;
295
- await scopeTail;
296
- return (await runTickFrame(tickPorts(k), () => nowMs)).outcomes;
297
- },
298
- framePause: () => loaded?.framePause(),
299
- frameResume: () => loaded?.frameResume(),
300
- startFrames: (onFrame, schedule = defaultFrameScheduler) => {
301
- const presence = getTraitPresence();
302
- const releases = visibleGroups.map(([, group]) => presence.watch(group));
303
- let stopped = false;
304
- let latestMs = 0;
305
- let nextHandle = 0;
306
- const cancels = /* @__PURE__ */ new Map();
307
- const visibility = {
308
- hidden: () => document.visibilityState === "hidden",
309
- onChange: (listener) => {
310
- document.addEventListener("visibilitychange", listener);
311
- return () => document.removeEventListener("visibilitychange", listener);
312
- }
313
- };
314
- let driver;
315
- ready.then(async (k) => {
316
- await scopeTail;
317
- if (stopped) return;
318
- driver = createTickDriver({
319
- ...tickPorts(k),
320
- now: () => latestMs,
321
- requestFrame: (callback) => {
322
- nextHandle += 1;
323
- const handle = nextHandle;
324
- cancels.set(handle, schedule((nowMs) => {
325
- cancels.delete(handle);
326
- latestMs = nowMs;
327
- callback(nowMs);
328
- }));
329
- return handle;
330
- },
331
- cancelFrame: (handle) => {
332
- cancels.get(handle)?.();
333
- cancels.delete(handle);
334
- },
335
- visibility,
336
- onApplied: (applied) => {
337
- if (!stopped && applied.outcomes.length > 0) onFrame(applied.outcomes);
338
- },
339
- onError: (error) => log.error("kernel-frame-failed", { error: error.message })
340
- });
341
- driver.start();
342
- }).catch((error) => log.error("kernel-frame-failed", { error: error.message }));
343
- return () => {
344
- stopped = true;
345
- driver?.stop();
346
- releases.forEach((release) => release());
347
- };
348
- },
349
- traitState: (traitName) => loaded?.getState(traitName),
350
- traitConfig: (traitName) => {
351
- if (loaded === void 0) return void 0;
352
- const held = configs.get(traitName);
353
- if (held !== void 0) return held;
354
- const config = parse(loaded.traitConfig(traitName));
355
- configs.set(traitName, config);
356
- return config;
357
- },
358
- setViewer: async (user) => {
359
- const k = await ready;
360
- k.setCurrentUser(JSON.stringify(user));
361
- configs.clear();
362
- }
363
- };
364
- return client;
365
- }
366
-
367
- export { createKernelClient };
@@ -1,65 +0,0 @@
1
- import { OrbitalSchema } from '@almadar/core';
2
- import { KernelModule as KernelModule$1 } from '@almadar/shell-runtime/kernel/wire';
3
- import './verification-C5pTeMJv.js';
4
-
5
- /**
6
- * The `Kernel` class surface of `@almadar/kernel` (JSON strings in, JSON strings out). The wire data it
7
- * speaks (`DispatchWire`, `AppliedWire`, `FrameWire`, ...) is imported from `@almadar/core/kernel-wire`.
8
- *
9
- * @packageDocumentation
10
- */
11
-
12
- /** The `Kernel` class `@almadar/kernel` exports: JSON strings in, JSON strings out. */
13
- interface KernelInstance {
14
- dispatch(traitName: string, entityId: string | undefined, event: string, payloadJson?: string): string;
15
- applyServerResponse(responseJson: string, alreadyDeliveredJson?: string, baseJson?: string): string;
16
- /** The rows a posted leg's answer is folded against; `undefined` when the leg carried none. */
17
- /** The leg as a host that holds the circuit state takes it: only the `[shared]` frame rows its traits read. */
18
- statefulLeg(legJson: string): string;
19
- foldBase(carriedJson: string | undefined, seededJson: string, entityId?: string): string | undefined;
20
- dispatchMount(seedsJson: string, entityId?: string, payloadJson?: string): string;
21
- restore(traitName: string, entityId: string | undefined, snapshotJson: string): string;
22
- tick(traitName: string, tickName: string, entityId?: string): string;
23
- frame(nowMs: number): string | undefined;
24
- framePause(): void;
25
- frameResume(): void;
26
- tickCount(): number;
27
- /** The kernel's dispatch mode for a registered trait (`DispatchMode` as JSON text); throws for an unregistered one. */
28
- dispatchMode(traitName: string): string;
29
- /** The config the kernel binds as `@config` for a registered trait (JSON text); throws for an unregistered one. */
30
- traitConfig(traitName: string): string;
31
- getState(traitName: string, entityId?: string): string;
32
- setCurrentUser(userJson: string): void;
33
- /** The viewer's locales (`string[]`, the first is painted) and their catalogs (`{ [locale]: { [key]: text } }`) for `i18n/t`. */
34
- setMessages(localesJson: string, catalogsJson: string): void;
35
- /** The host runs the listeners of every emit it marks `dispatched` (the JS runtime, `orbital-server`). */
36
- setHostFansOut(fansOut: boolean): void;
37
- /** Carry each hop's `@entity` before and after it on the dispatch's transitions, for a verifier (EXEC-STEP-10). */
38
- setRecordEntityAfter(record: boolean): void;
39
- /** The kernel's mounts for a host start on `side` (`client|server|process|start`): `MountSeed[]` as JSON. */
40
- bootMounts(side: string): string;
41
- /** The kernel's mounts for a client opening `routePath`: `MountSeed[]` as JSON. */
42
- routeMounts(routePath: string): string;
43
- mount(traitsJson: string): void;
44
- remount(traitsJson: string): void;
45
- unmount(traitsJson: string): void;
46
- /** The host's report of whether a trait's rendered output is on screen; gates its `[visible]` ticks. */
47
- setTraitOnScreen(traitName: string, onScreen: boolean): void;
48
- seed(entityType: string, rowsJson: string): void;
49
- free(): void;
50
- }
51
- /**
52
- * What a host's loader resolves: the `@almadar/kernel` module with its WebAssembly already
53
- * initialised (`await init()` in a browser, `initSync` in Node). `@almadar/ui` never imports the
54
- * package itself, so the default bundle carries none of it.
55
- */
56
- interface KernelModule extends KernelModule$1 {
57
- Kernel: new (resolvedSchemaJson: string, clientId: string) => KernelInstance;
58
- }
59
- type KernelLoader = () => Promise<KernelModule>;
60
- /** Resolves the language bundle (`@almadar/core/language-data` `LanguageBundle`) as JSON text, for a kernel a browser opens over a local store. */
61
- type LanguageLoader = () => Promise<string>;
62
- /** Resolves the std `std-mock-seed` program (an already-resolved schema) that seeds a mock or browser store. */
63
- type SeedProgramLoader = () => Promise<OrbitalSchema>;
64
-
65
- export type { KernelModule as K, LanguageLoader as L, SeedProgramLoader as S, KernelLoader as a, KernelInstance as b };