@almadar/shell-runtime 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 (167) hide show
  1. package/dist/chunk-2WCVOMZ2.js +112 -0
  2. package/dist/chunk-57SBCUSM.js +62 -0
  3. package/dist/{chunk-Q2H75UYT.js → chunk-A2JJT4GA.js} +1 -37
  4. package/dist/chunk-BAS26HBN.js +10 -0
  5. package/dist/{chunk-REPX5QPI.js → chunk-BOVU4TCQ.js} +11 -3
  6. package/dist/chunk-BY5G4225.js +6 -0
  7. package/dist/chunk-DFDNHVDW.js +284 -0
  8. package/dist/{chunk-NATGCIVM.js → chunk-JVSREWQO.js} +378 -130
  9. package/dist/{chunk-DYOJGLIX.js → chunk-LKWYCYX5.js} +2 -5
  10. package/dist/chunk-LYFIQPXX.js +1 -0
  11. package/dist/{chunk-ODJCZ27I.js → chunk-N7HYNKK6.js} +35 -2
  12. package/dist/{chunk-4J2QEIUV.js → chunk-NTFQ36UN.js} +4 -30
  13. package/dist/chunk-NU6LVKGS.js +15 -0
  14. package/dist/{chunk-VNMG7NKY.js → chunk-OQVSN7DP.js} +21 -26
  15. package/dist/chunk-P2N6K2IV.js +20 -0
  16. package/dist/{chunk-QQRDUMB2.js → chunk-QCJWPXLH.js} +11 -11
  17. package/dist/{chunk-QELZ6TEJ.js → chunk-UD2CXYSJ.js} +39 -3
  18. package/dist/{chunk-UJHOUZAL.js → chunk-V4EMDPCO.js} +2 -5
  19. package/dist/chunk-VKQA2DJX.js +409 -0
  20. package/dist/chunk-VNGXRYFF.js +9 -0
  21. package/dist/{chunk-HNOAZWFH.js → chunk-WGCWJOT2.js} +2 -0
  22. package/dist/chunk-XZGVOBY6.js +33 -0
  23. package/dist/chunk-ZUSM4VW4.js +197 -0
  24. package/dist/client/EventTransport.d.ts +23 -7
  25. package/dist/client/EventTransport.js +1 -2
  26. package/dist/client/awaiting.js +0 -1
  27. package/dist/client/channel-transport.d.ts +6 -6
  28. package/dist/client/channel-transport.js +0 -1
  29. package/dist/client/circuit-store.d.ts +16 -5
  30. package/dist/client/circuit-store.js +2 -3
  31. package/dist/client/client-kernel.d.ts +36 -15
  32. package/dist/client/declared-input-dispatch.d.ts +19 -2
  33. package/dist/client/declared-input-dispatch.js +1 -2
  34. package/dist/client/inbound-dispatch.d.ts +21 -2
  35. package/dist/client/inbound-dispatch.js +1 -2
  36. package/dist/client/local-fold.d.ts +15 -8
  37. package/dist/client/local-fold.js +1 -2
  38. package/dist/client/render-sigils.js +0 -1
  39. package/dist/client/state-book.d.ts +9 -16
  40. package/dist/client/state-book.js +1 -2
  41. package/dist/client/trait-mount-error.js +0 -1
  42. package/dist/credentials/env-vars.d.ts +5 -1
  43. package/dist/credentials/env-vars.js +1 -3
  44. package/dist/credentials/scope.d.ts +8 -7
  45. package/dist/credentials/scope.js +0 -1
  46. package/dist/credentials/vault.d.ts +142 -0
  47. package/dist/credentials/vault.js +1 -0
  48. package/dist/effects/in-flight-calls.js +0 -1
  49. package/dist/effects/on-device-model.js +0 -1
  50. package/dist/events/EventBus.d.ts +1 -4
  51. package/dist/events/EventBus.js +0 -1
  52. package/dist/events/emit-stamp.js +0 -1
  53. package/dist/index.d.ts +25 -42
  54. package/dist/index.js +27 -45
  55. package/dist/kernel/decode.d.ts +10 -10
  56. package/dist/kernel/decode.js +1 -2
  57. package/dist/kernel/engine.d.ts +133 -31
  58. package/dist/kernel/engine.js +7 -9
  59. package/dist/kernel/frame-applier.d.ts +8 -7
  60. package/dist/kernel/frame-applier.js +1 -2
  61. package/dist/kernel/host.d.ts +148 -16
  62. package/dist/kernel/host.js +4 -7
  63. package/dist/kernel/lane.d.ts +1 -22
  64. package/dist/kernel/lane.js +1 -2
  65. package/dist/kernel/os-fetch-port.d.ts +7 -0
  66. package/dist/kernel/os-fetch-port.js +3 -0
  67. package/dist/kernel/os-port.d.ts +30 -8
  68. package/dist/kernel/os-port.js +1 -2
  69. package/dist/kernel/program-effects.d.ts +11 -28
  70. package/dist/kernel/program-effects.js +1 -2
  71. package/dist/kernel/secret-ports.d.ts +139 -0
  72. package/dist/kernel/secret-ports.js +2 -0
  73. package/dist/kernel/wire.d.ts +113 -12
  74. package/dist/loader/fetch-loader.d.ts +26 -0
  75. package/dist/loader/fetch-loader.js +1 -0
  76. package/dist/loader/lazy-page.js +0 -1
  77. package/dist/loader/schema-loader.d.ts +1 -17
  78. package/dist/persistence/native-memory.js +0 -1
  79. package/dist/runtime/entities/declaredCollections.d.ts +6 -0
  80. package/dist/runtime/entities/declaredCollections.js +1 -0
  81. package/dist/runtime/evaluation/local-store-transport.d.ts +16 -23
  82. package/dist/runtime/evaluation/local-store-transport.js +9 -13
  83. package/dist/runtime/evaluation/residence-transport.d.ts +3 -3
  84. package/dist/runtime/evaluation/residence-transport.js +1 -2
  85. package/dist/runtime/evaluation/routed-persistence.js +0 -1
  86. package/dist/runtime/events/identity/routing.d.ts +2 -53
  87. package/dist/runtime/events/identity/routing.js +1 -2
  88. package/dist/runtime/types.d.ts +5 -205
  89. package/dist/runtime/types.js +1 -2
  90. package/dist/service/default-call-service.js +0 -1
  91. package/dist/service/service-provider.js +0 -1
  92. package/package.json +8 -5
  93. package/dist/chunk-2JU7Y4KU.js +0 -21
  94. package/dist/chunk-46RWK2B5.js +0 -28
  95. package/dist/chunk-4ZICQ5PM.js +0 -192
  96. package/dist/chunk-53IPZXDP.js +0 -76
  97. package/dist/chunk-5D63EMO5.js +0 -16
  98. package/dist/chunk-CPSQXEJ6.js +0 -55
  99. package/dist/chunk-CQP5XAX6.js +0 -173
  100. package/dist/chunk-CROS2GEX.js +0 -49
  101. package/dist/chunk-D4XJTBLB.js +0 -217
  102. package/dist/chunk-D5USD2EX.js +0 -232
  103. package/dist/chunk-EV56K4GB.js +0 -63
  104. package/dist/chunk-FQ6IZMIU.js +0 -10
  105. package/dist/chunk-HMK6YMQS.js +0 -135
  106. package/dist/chunk-IHQLE5M7.js +0 -62
  107. package/dist/chunk-JFWFDUTR.js +0 -35
  108. package/dist/chunk-MHYSHSRG.js +0 -54
  109. package/dist/chunk-MLKGABMK.js +0 -7
  110. package/dist/chunk-NAECVIAR.js +0 -322
  111. package/dist/chunk-Q7JK4KY7.js +0 -9
  112. package/dist/chunk-RBUMDYFS.js +0 -681
  113. package/dist/chunk-SAS5KKCR.js +0 -43
  114. package/dist/chunk-SWPDU752.js +0 -28
  115. package/dist/chunk-T775TUCD.js +0 -18
  116. package/dist/chunk-VMOBW7RK.js +0 -21
  117. package/dist/chunk-WNPNNYXY.js +0 -22
  118. package/dist/chunk-XB5GYODW.js +0 -28
  119. package/dist/chunk-YL2SO5TP.js +0 -334
  120. package/dist/chunk-YO4LWS3I.js +0 -606
  121. package/dist/chunk-ZAQSS47X.js +0 -157
  122. package/dist/chunk-ZCQUUJIF.js +0 -129
  123. package/dist/client/ServerBridge.d.ts +0 -126
  124. package/dist/client/ServerBridge.js +0 -3
  125. package/dist/credentials/seed.d.ts +0 -21
  126. package/dist/credentials/seed.js +0 -2
  127. package/dist/credentials/store.d.ts +0 -110
  128. package/dist/credentials/store.js +0 -2
  129. package/dist/index-hT1xCdTq.d.ts +0 -46
  130. package/dist/kernel/beacon.d.ts +0 -32
  131. package/dist/kernel/beacon.js +0 -2
  132. package/dist/kernel/http.d.ts +0 -302
  133. package/dist/kernel/http.js +0 -6
  134. package/dist/kernel/oauth-effects.d.ts +0 -25
  135. package/dist/kernel/oauth-effects.js +0 -7
  136. package/dist/kernel/oauth-port.d.ts +0 -31
  137. package/dist/kernel/oauth-port.js +0 -2
  138. package/dist/loader/http-loader.d.ts +0 -111
  139. package/dist/loader/http-loader.js +0 -2
  140. package/dist/runtime/effects/composition/compose-behaviors.d.ts +0 -58
  141. package/dist/runtime/effects/composition/compose-behaviors.js +0 -4
  142. package/dist/runtime/effects/composition/event-wiring.d.ts +0 -38
  143. package/dist/runtime/effects/composition/event-wiring.js +0 -2
  144. package/dist/runtime/effects/composition/index.d.ts +0 -5
  145. package/dist/runtime/effects/composition/index.js +0 -6
  146. package/dist/runtime/effects/composition/layout-strategy.d.ts +0 -35
  147. package/dist/runtime/effects/composition/layout-strategy.js +0 -2
  148. package/dist/runtime/effects/composition/pipe.d.ts +0 -25
  149. package/dist/runtime/effects/composition/pipe.js +0 -2
  150. package/dist/runtime/entities/mockStoreSeed.d.ts +0 -56
  151. package/dist/runtime/entities/mockStoreSeed.js +0 -3
  152. package/dist/runtime/entities/seedBrowserStore.d.ts +0 -28
  153. package/dist/runtime/entities/seedBrowserStore.js +0 -2
  154. package/dist/runtime/entities/std-mock-seed.d.ts +0 -87
  155. package/dist/runtime/entities/std-mock-seed.js +0 -2
  156. package/dist/runtime/time/TickScheduler.d.ts +0 -77
  157. package/dist/runtime/time/TickScheduler.js +0 -3
  158. package/dist/runtime/time/cron.d.ts +0 -25
  159. package/dist/runtime/time/cron.js +0 -2
  160. package/dist/runtime/time/duration.d.ts +0 -20
  161. package/dist/runtime/time/duration.js +0 -2
  162. package/dist/runtime/traits/OrbitalTraitParsing.d.ts +0 -34
  163. package/dist/runtime/traits/OrbitalTraitParsing.js +0 -2
  164. package/dist/runtime/traits/listen-targets.d.ts +0 -16
  165. package/dist/runtime/traits/listen-targets.js +0 -3
  166. package/dist/runtime/traits/trait-index.d.ts +0 -35
  167. package/dist/runtime/traits/trait-index.js +0 -3
@@ -1,8 +1,6 @@
1
- import { findExternalInput } from '@almadar/core';
2
-
3
1
  // src/client/declared-input-dispatch.ts
4
- async function dispatchDeclaredInput(schema, orbitalName, request, send) {
5
- const declared = schema ? findExternalInput(schema, orbitalName, request.targetTrait, request.event) : void 0;
2
+ async function dispatchDeclaredInput(contract, orbitalName, request, send) {
3
+ const declared = contract.findExternalInput(orbitalName, request.targetTrait, request.event);
6
4
  if (!declared) {
7
5
  return {
8
6
  success: false,
@@ -17,7 +15,6 @@ async function dispatchDeclaredInput(schema, orbitalName, request, send) {
17
15
  event: request.event,
18
16
  payload: request.payload ?? {},
19
17
  targetTrait: request.targetTrait,
20
- ...request.user !== void 0 ? { user: request.user } : {},
21
18
  ...request.entityId !== void 0 ? { entityId: request.entityId } : {}
22
19
  });
23
20
  }
@@ -0,0 +1 @@
1
+
@@ -1,4 +1,4 @@
1
- import { StateBook } from './chunk-Q2H75UYT.js';
1
+ import { StateBook } from './chunk-A2JJT4GA.js';
2
2
  import { AwaitingRegistry } from './chunk-HC6ERSAH.js';
3
3
 
4
4
  // src/client/circuit-store.ts
@@ -7,10 +7,43 @@ function createMemoryCircuitStore(traits = [], observer) {
7
7
  const frames = /* @__PURE__ */ new Map();
8
8
  const listeners = /* @__PURE__ */ new Set();
9
9
  let version = 0;
10
+ let frameVersion = 0;
11
+ let frameSession;
10
12
  return {
11
13
  states,
12
14
  frames,
13
- callsitePayloads: /* @__PURE__ */ new Map(),
15
+ get frameVersion() {
16
+ return frameVersion;
17
+ },
18
+ applyFrames(delta) {
19
+ if (delta.session !== void 0) {
20
+ const snapshot = delta.from === 0 && delta.ops[0]?.[0] === "clear";
21
+ if (!snapshot) {
22
+ const current = (frameSession === void 0 || delta.session === frameSession) && delta.from === frameVersion;
23
+ if (delta.session === frameSession && delta.to <= frameVersion && !current) return "stale";
24
+ if (!current) return "gap";
25
+ }
26
+ frameSession = delta.session;
27
+ frameVersion = delta.to;
28
+ }
29
+ for (const op of delta.ops) {
30
+ switch (op[0]) {
31
+ case "clear":
32
+ frames.clear();
33
+ break;
34
+ case "del":
35
+ frames.delete(op[1]);
36
+ break;
37
+ case "put":
38
+ frames.set(op[1], { ...op[2] });
39
+ break;
40
+ case "set":
41
+ for (const [frame, fields] of Object.entries(op[1])) frames.set(frame, { ...frames.get(frame) ?? {}, ...fields });
42
+ break;
43
+ }
44
+ }
45
+ return "applied";
46
+ },
14
47
  awaiting: new AwaitingRegistry(),
15
48
  snapshot(trait, entityId, frameKey) {
16
49
  const key = frameKey ?? trait;
@@ -1,42 +1,15 @@
1
- import { isEventResponse } from '@almadar/core/kernel-wire';
1
+ import { isFrameWire } from '@almadar/core/kernel-wire';
2
2
  import { createLogger } from '@almadar/logger';
3
3
 
4
4
  // src/kernel/frame-applier.ts
5
5
  var log = createLogger("almadar:shell-web:frame");
6
- function isRecord(value) {
7
- return typeof value === "object" && value !== null && !Array.isArray(value);
8
- }
9
- function isList(value, item) {
10
- return Array.isArray(value) && value.every(item);
11
- }
12
- function isSeed(value) {
13
- return isRecord(value) && typeof value["trait"] === "string" && typeof value["event"] === "string";
14
- }
15
- function isRoutedLeg(value) {
16
- if (!isRecord(value) || typeof value["orbital"] !== "string") return false;
17
- const leg = value["leg"];
18
- return isRecord(leg) && typeof leg["event"] === "string";
19
- }
20
- function isFiredTick(value) {
21
- return isRecord(value) && typeof value["trait"] === "string" && typeof value["tick"] === "string";
22
- }
23
- function isFrameDispatch(value) {
24
- if (!isRecord(value)) return false;
25
- const response = value["response"];
26
- return typeof value["trait"] === "string" && typeof value["orbital"] === "string" && isSeed(value["seed"]) && response !== void 0 && isEventResponse(response) && isList(value["serverLegs"], isRoutedLeg) && typeof value["mode"] === "string" && Array.isArray(value["awaiting"]) && Array.isArray(value["foldSeeded"]);
27
- }
28
- function isFrameWire(value) {
29
- if (!isRecord(value)) return false;
30
- const response = value["response"];
31
- return isList(value["fired"], isFiredTick) && response !== void 0 && isEventResponse(response) && isList(value["dispatches"], isFrameDispatch) && isList(value["browserLegs"], isRoutedLeg) && typeof value["droppedServerEffects"] === "number" && isList(value["errors"], (entry) => typeof entry === "string");
32
- }
33
6
  function decodeFrame(json) {
34
7
  if (json === void 0) return void 0;
35
8
  const value = JSON.parse(json);
36
9
  if (!isFrameWire(value)) throw new Error("kernel wire: frame is not a FrameWire");
37
10
  return value;
38
11
  }
39
- var NOTHING = { fired: [], folded: 0, browserLegs: 0, droppedServerEffects: 0, outcomes: [], errors: [] };
12
+ var NOTHING = { fired: {}, firedCount: 0, folded: 0, browserLegs: 0, droppedServerEffects: 0, outcomes: [], errors: [] };
40
13
  var settle = (posted, failure, trait) => posted.then(
41
14
  (effects) => effects,
42
15
  (err) => {
@@ -67,6 +40,7 @@ async function applyFrame(json, kernel, post) {
67
40
  }
68
41
  return {
69
42
  fired: frame.fired,
43
+ firedCount: Object.values(frame.fired).reduce((n, ticks) => n + ticks.length, 0),
70
44
  folded: frame.dispatches.length + 1,
71
45
  browserLegs: frame.browserLegs.length,
72
46
  droppedServerEffects: frame.droppedServerEffects,
@@ -75,4 +49,4 @@ async function applyFrame(json, kernel, post) {
75
49
  };
76
50
  }
77
51
 
78
- export { applyFrame, decodeFrame, isFrameWire };
52
+ export { applyFrame, decodeFrame };
@@ -0,0 +1,15 @@
1
+ // src/kernel/lane.ts
2
+ var LaneHeldByParkedDispatch = class extends Error {
3
+ ticket;
4
+ event;
5
+ constructor(ticket, event) {
6
+ super(
7
+ `dispatch #${ticket} (${event}) is parked holding the dispatch lane on this thread; resume or drop it before starting another dispatch`
8
+ );
9
+ this.name = "LaneHeldByParkedDispatch";
10
+ this.ticket = ticket;
11
+ this.event = event;
12
+ }
13
+ };
14
+
15
+ export { LaneHeldByParkedDispatch };
@@ -1,19 +1,17 @@
1
1
  import { defaultCallService } from './chunk-4SEK5ER2.js';
2
2
  import { routeByEntity } from './chunk-O57GKTYU.js';
3
- import { buildTraitIndex } from './chunk-CPSQXEJ6.js';
4
- import { KernelEngine, evaluateOnKernel } from './chunk-D4XJTBLB.js';
3
+ import { KernelEngine, evaluateOnKernel } from './chunk-VKQA2DJX.js';
5
4
  import { InFlightCalls } from './chunk-MZKIL5IN.js';
6
- import { createInProcessTransport } from './chunk-QELZ6TEJ.js';
7
- import { orbitalInlineEntities, storesRowsInBrowser, inlineTraitRefs, applyRowAccess, readableEntitiesOf, externalInputsOf, entityOwnerOrbital } from '@almadar/core';
8
- import { entityAccessPolicies } from '@almadar/core/mock';
5
+ import { createInProcessTransport } from './chunk-UD2CXYSJ.js';
6
+ import { orbitalInlineEntities, storesRowsInBrowser, inlineTraitRefs } from '@almadar/core';
9
7
 
8
+ var LOCAL_CLIENT = "local";
10
9
  function localStorePersistence(schema, store, memory) {
11
10
  const browserStored = new Set(schema.orbitals.flatMap(orbitalInlineEntities).filter(storesRowsInBrowser).map((entity) => entity.name));
12
11
  return routeByEntity(browserStored, store, memory);
13
12
  }
14
13
  function openLocalKernel(options) {
15
14
  const { schema, persistence } = options;
16
- options.kernel.installLanguage(options.language);
17
15
  const callService = options.callService ?? defaultCallService;
18
16
  const engine = KernelEngine.open(options.kernel, { ...schema, orbitals: inlineTraitRefs(schema.orbitals) }, {
19
17
  persistence,
@@ -23,47 +21,44 @@ function openLocalKernel(options) {
23
21
  servicePorts: options.servicePorts ?? ((caller, user, message) => ({
24
22
  caller,
25
23
  message,
26
- inputs: () => externalInputsOf(schema),
27
- readableEntities: () => readableEntitiesOf(schema),
24
+ inputs: () => engine.externalInputs(),
25
+ readableEntities: () => engine.readableEntities(),
28
26
  dispatchInput: () => Promise.reject(new Error("a local store host takes no input dispatch")),
29
- read: async (entity) => applyRowAccess(await persistence.list(entity), entityAccessPolicies(schema, entity)?.read, void 0, { user }, entity)
27
+ read: async (entity) => engine.readRows(entity, await persistence.list(entity), user)
30
28
  })),
31
29
  deliverLive: () => void 0,
32
30
  deferCallOutcome: options.deferCallOutcome ?? (() => void 0),
33
31
  ...options.pageFacts !== void 0 ? { pageFacts: options.pageFacts } : {},
34
- ...options.http !== void 0 ? { http: options.http } : {},
32
+ ...options.hostActions !== void 0 ? { hostActions: options.hostActions } : {},
33
+ ...options.secretPorts !== void 0 ? { secretPorts: options.secretPorts } : {},
35
34
  ...options.onDevice !== void 0 ? { onDevice: options.onDevice } : {},
36
- ...options.tabs !== void 0 ? { tabs: options.tabs } : {}
35
+ ...options.tabs !== void 0 ? { tabs: options.tabs } : {},
36
+ ...options.os !== void 0 ? { os: options.os } : {},
37
+ ...options.gpu !== void 0 ? { gpu: options.gpu } : {}
37
38
  });
38
- if (options.messages !== void 0) engine.setMessages(Object.keys(options.messages), options.messages);
39
- engine.setTickMount([...buildTraitIndex(schema.orbitals).byName.keys()]);
39
+ for (const trait of engine.programSurface().traits) engine.mountClient(LOCAL_CLIENT, trait.orbital, [trait.name]);
40
40
  return engine;
41
41
  }
42
42
  function createLocalStoreTransport(options) {
43
43
  return createInProcessTransport(
44
44
  async (orbital, request) => evaluateOnKernel(
45
- {
46
- engine: await options.kernelEngine,
47
- orbital,
48
- ...options.outsideEventQueue !== void 0 ? { outsideEventQueue: options.outsideEventQueue } : {}
49
- },
45
+ { engine: await options.kernelEngine, orbital },
50
46
  request,
51
- await options.user,
52
- request.locale
47
+ request.locale ?? options.locale?.()
53
48
  ),
54
49
  {
55
50
  carriesCircuitState: false,
56
- ...options.schema !== void 0 ? { resolveRows: resolveOn(options, options.schema) } : {}
51
+ ...options.schema !== void 0 ? { resolveRows: resolveOn(options) } : {}
57
52
  }
58
53
  );
59
54
  }
60
- function resolveOn(options, schema) {
61
- return async (reference) => resolveLocalRows(await options.kernelEngine, schema, await options.user, reference);
55
+ function resolveOn(options) {
56
+ return async (reference) => resolveLocalRows(await options.kernelEngine, reference);
62
57
  }
63
- function resolveLocalRows(engine, schema, user, reference) {
64
- const owner = entityOwnerOrbital(schema, reference.entityType);
58
+ function resolveLocalRows(engine, reference) {
59
+ const owner = engine.entityOwnerOrbital(reference.entityType);
65
60
  if (owner === void 0) return Promise.reject(new Error(`${reference.entityType}: no orbital of the local program declares this entity`));
66
- return engine.resolveRows(reference, { orbital: owner.name, ...user !== void 0 ? { user } : {} });
61
+ return engine.resolveRows(reference, { orbital: owner });
67
62
  }
68
63
 
69
64
  export { createLocalStoreTransport, localStorePersistence, openLocalKernel, resolveLocalRows };
@@ -0,0 +1,20 @@
1
+ // src/client/inbound-dispatch.ts
2
+ async function dispatchInbound(contract, name, delivery, send, credential) {
3
+ const found = contract.findInbound(name);
4
+ if (!("route" in found)) return found.answer;
5
+ const { route } = found;
6
+ try {
7
+ const held = route.verifies !== void 0 ? await credential(route.verifies.credential) : void 0;
8
+ if (route.verifies !== void 0 && (held === void 0 || held === null || held === "")) return contract.credentialUnset(route.verifies.credential);
9
+ const response = await send(route.orbital, {
10
+ event: route.event,
11
+ payload: contract.inboundPayload(route, delivery, held),
12
+ targetTrait: route.trait
13
+ });
14
+ return contract.inboundAnswer(route, response.emittedEvents, response.error);
15
+ } catch (error) {
16
+ return contract.dispatchFailed(error instanceof Error ? error.message : String(error));
17
+ }
18
+ }
19
+
20
+ export { dispatchInbound };
@@ -1,16 +1,16 @@
1
1
  // src/client/local-fold.ts
2
- function mirrorResponse(store, frameKeyOf, response) {
2
+ function paintStates(store, response) {
3
3
  for (const [trait, state] of Object.entries(response.states)) {
4
4
  if (store.states.getState(trait)?.currentState !== state) store.states.seedState(trait, state);
5
5
  }
6
- for (const [trait, row] of Object.entries(response.entityByTrait ?? {})) {
7
- const frameKey = frameKeyOf(trait);
8
- if (frameKey === void 0) continue;
9
- store.frames.set(frameKey, { ...store.frames.get(frameKey) ?? {}, ...row });
10
- }
11
- for (const effect of response.clientEffectsByTrait ?? []) {
12
- if (effect.callsitePayload !== void 0) store.callsitePayloads.set(effect.traitName, effect.callsitePayload);
13
- }
6
+ }
7
+ function paintFrames(store, delta, framesSince) {
8
+ if (delta === void 0) return;
9
+ if (store.applyFrames(delta) === "gap") store.applyFrames(framesSince(store.frameVersion));
10
+ }
11
+ function paintResponse(store, framesSince, response) {
12
+ paintStates(store, response);
13
+ paintFrames(store, response.frames, framesSince);
14
14
  }
15
15
  function traceResponse(observer, response) {
16
16
  if (observer === void 0) return;
@@ -31,10 +31,10 @@ function createLocalFold(opts) {
31
31
  return {
32
32
  foldLocalResponse: async (response, traceHops, notify) => {
33
33
  if (traceHops) traceResponse(opts.observer, response);
34
- mirrorResponse(opts.store, opts.frameKeyOf, response);
34
+ paintResponse(opts.store, opts.framesSince, response);
35
35
  if (notify) opts.store.notify();
36
36
  }
37
37
  };
38
38
  }
39
39
 
40
- export { createLocalFold, mirrorResponse, traceResponse };
40
+ export { createLocalFold, paintFrames, paintResponse, paintStates, traceResponse };
@@ -88,6 +88,34 @@ function acquirePushChannel(key, resolveUrl, resumeKey, subscriber) {
88
88
  }
89
89
  };
90
90
  }
91
+ var SessionEndedError = class extends Error {
92
+ constructor(message) {
93
+ super(message);
94
+ this.name = "SessionEndedError";
95
+ }
96
+ };
97
+ var TransportStatusError = class extends Error {
98
+ constructor(status, bodyText) {
99
+ super(`the server answered ${status}${bodyText.length > 0 ? `: ${bodyText}` : " with no body"}`);
100
+ this.status = status;
101
+ this.bodyText = bodyText;
102
+ this.refusal = parseRefusal(bodyText);
103
+ this.name = "TransportStatusError";
104
+ }
105
+ status;
106
+ bodyText;
107
+ /** The `{ error, code }` body when the answer carried one. */
108
+ refusal;
109
+ };
110
+ function parseRefusal(text) {
111
+ if (text.length === 0) return void 0;
112
+ try {
113
+ const parsed = JSON.parse(text);
114
+ return typeof parsed === "object" && parsed !== null ? parsed : void 0;
115
+ } catch {
116
+ return void 0;
117
+ }
118
+ }
91
119
  var COMPRESSED_BODY_MIN_BYTES = 32 * 1024;
92
120
  async function encodeJsonBody(value, compress) {
93
121
  const text = JSON.stringify(value);
@@ -122,8 +150,9 @@ function createHttpTransport(options) {
122
150
  return `${eventsUrl}?${search.toString()}`;
123
151
  };
124
152
  const key = `${eventsUrl}?${new URLSearchParams(params).toString()}`;
153
+ const mintUrl = params["clientId"] !== void 0 ? `${eventsUrl}/ticket?${new URLSearchParams({ clientId: params["clientId"] }).toString()}` : `${eventsUrl}/ticket`;
125
154
  const resolveUrl = async () => {
126
- const reply = await fetchFn(`${eventsUrl}/ticket`, { method: "POST", headers: await authHeaders(getAccessToken) });
155
+ const reply = await fetchFn(mintUrl, { method: "POST", headers: await authHeaders(getAccessToken) });
127
156
  if (!reply.ok) throw new Error(`the server refused a stream ticket: ${reply.status}`);
128
157
  const body = await reply.json();
129
158
  if (typeof body.ticket !== "string" || body.ticket.length === 0) throw new Error("the server sent no stream ticket");
@@ -169,7 +198,14 @@ function createHttpTransport(options) {
169
198
  getAccessToken,
170
199
  compress
171
200
  );
172
- return await res.json();
201
+ const text = await res.text();
202
+ if (res.status === 409) {
203
+ const refusal = parseRefusal(text);
204
+ if (refusal?.code === "SESSION_ENDED") throw new SessionEndedError(refusal.error ?? "the session ended");
205
+ }
206
+ if (!res.ok && res.status !== 403) throw new TransportStatusError(res.status, text);
207
+ const body = JSON.parse(text);
208
+ return body;
173
209
  },
174
210
  async resolveRows(reference) {
175
211
  const res = await jsonPost(fetchFn, `${serverUrl}/resolve-rows`, { ref: reference }, getAccessToken, compress);
@@ -205,4 +241,4 @@ function createInProcessTransport(evaluate, options = {}) {
205
241
  };
206
242
  }
207
243
 
208
- export { COMPRESSED_BODY_MIN_BYTES, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody };
244
+ export { COMPRESSED_BODY_MIN_BYTES, SessionEndedError, TransportStatusError, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody };
@@ -1,9 +1,6 @@
1
- import { storesRowsInBrowser } from '@almadar/core';
2
-
3
1
  // src/runtime/evaluation/residence-transport.ts
4
2
  function createResidenceTransport(options) {
5
- const { local, remote, traitIndex } = options;
6
- const browserStored = new Set(traitIndex.allEntities.filter(storesRowsInBrowser).map((e) => e.name));
3
+ const { local, remote, browserEntities } = options;
7
4
  const route = (orbitalName, request) => {
8
5
  if (request.residence === "browser") return local;
9
6
  if (request.residence === "server") {
@@ -25,7 +22,7 @@ function createResidenceTransport(options) {
25
22
  return route(orbitalName, request).send(orbitalName, request);
26
23
  },
27
24
  async resolveRows(reference) {
28
- const owner = browserStored.has(reference.entityType) ? local : remote;
25
+ const owner = browserEntities.has(reference.entityType) ? local : remote;
29
26
  if (owner?.resolveRows === void 0) throw new Error(`residence: no transport resolves ${reference.entityType} row sets`);
30
27
  return owner.resolveRows(reference);
31
28
  },