@almadar/shell-runtime 0.1.0 → 1.0.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-57SBCUSM.js +62 -0
  2. package/dist/chunk-625EP7W2.js +108 -0
  3. package/dist/{chunk-NATGCIVM.js → chunk-7WB6VWRK.js} +344 -129
  4. package/dist/{chunk-Q2H75UYT.js → chunk-A2JJT4GA.js} +1 -37
  5. package/dist/chunk-BAS26HBN.js +10 -0
  6. package/dist/{chunk-REPX5QPI.js → chunk-BOVU4TCQ.js} +11 -3
  7. package/dist/chunk-BY5G4225.js +6 -0
  8. package/dist/chunk-DFDNHVDW.js +284 -0
  9. package/dist/chunk-I3TKINSO.js +398 -0
  10. package/dist/{chunk-DYOJGLIX.js → chunk-LKWYCYX5.js} +2 -5
  11. package/dist/chunk-LYFIQPXX.js +1 -0
  12. package/dist/{chunk-VNMG7NKY.js → chunk-MU335ZA4.js} +20 -26
  13. package/dist/{chunk-ODJCZ27I.js → chunk-N7HYNKK6.js} +35 -2
  14. package/dist/{chunk-4J2QEIUV.js → chunk-NTFQ36UN.js} +4 -30
  15. package/dist/chunk-NU6LVKGS.js +15 -0
  16. package/dist/chunk-P2N6K2IV.js +20 -0
  17. package/dist/{chunk-QQRDUMB2.js → chunk-QCJWPXLH.js} +11 -11
  18. package/dist/{chunk-QELZ6TEJ.js → chunk-UD2CXYSJ.js} +39 -3
  19. package/dist/{chunk-UJHOUZAL.js → chunk-V4EMDPCO.js} +2 -5
  20. package/dist/chunk-VNGXRYFF.js +9 -0
  21. package/dist/{chunk-HNOAZWFH.js → chunk-WGCWJOT2.js} +2 -0
  22. package/dist/chunk-X6W44WHO.js +26 -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 +8 -10
  56. package/dist/kernel/decode.js +1 -2
  57. package/dist/kernel/engine.d.ts +132 -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 +127 -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 +50 -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 +14 -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,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
  },
@@ -0,0 +1,9 @@
1
+ // src/credentials/env-vars.ts
2
+ var CREDENTIAL_MASTER_KEY_ENV = "ALMADAR_CREDENTIAL_MASTER_KEY";
3
+ var CREDENTIAL_PREVIOUS_MASTER_KEY_ENV = "ALMADAR_CREDENTIAL_MASTER_KEY_PREVIOUS";
4
+ var STORE_BOOTSTRAP_ENV_VARS = /* @__PURE__ */ new Set([CREDENTIAL_MASTER_KEY_ENV, CREDENTIAL_PREVIOUS_MASTER_KEY_ENV]);
5
+ function allCredentialEnvVars() {
6
+ return new Set(STORE_BOOTSTRAP_ENV_VARS);
7
+ }
8
+
9
+ export { CREDENTIAL_MASTER_KEY_ENV, CREDENTIAL_PREVIOUS_MASTER_KEY_ENV, STORE_BOOTSTRAP_ENV_VARS, allCredentialEnvVars };
@@ -9,6 +9,8 @@ var PROGRAM_EFFECTS = [
9
9
  "program/print",
10
10
  "program/eval",
11
11
  "program/validate",
12
+ "program/prove",
13
+ "program/os-grants",
12
14
  "program/compose",
13
15
  "program/step"
14
16
  ];
@@ -0,0 +1,26 @@
1
+ import { decodeServerProgressWire, decodeNextWire, decodeResolveProgressWire, decodeFiredTick } from '@almadar/core/kernel-wire';
2
+ export { decodeIoRequestWire } from '@almadar/core/kernel-wire';
3
+
4
+ // src/kernel/decode.ts
5
+ function decodeProgress(json) {
6
+ return decodeServerProgressWire(JSON.parse(json));
7
+ }
8
+ function decodeNext(json) {
9
+ const value = JSON.parse(json);
10
+ return value === null ? null : decodeNextWire(value);
11
+ }
12
+ function decodeResolveProgress(json) {
13
+ return decodeResolveProgressWire(JSON.parse(json));
14
+ }
15
+ function decodeDueTicks(json) {
16
+ const value = JSON.parse(json);
17
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("tickPass: the kernel answered a non-object");
18
+ const byOrbital = {};
19
+ for (const [orbital, ticks] of Object.entries(value)) {
20
+ if (!Array.isArray(ticks)) throw new Error(`tickPass: the kernel answered a non-list for orbital ${orbital}`);
21
+ byOrbital[orbital] = ticks.map(decodeFiredTick);
22
+ }
23
+ return byOrbital;
24
+ }
25
+
26
+ export { decodeDueTicks, decodeNext, decodeProgress, decodeResolveProgress };
@@ -0,0 +1,197 @@
1
+ import { resolveCredentialRef, getEffectiveCredentialStore, getModeControl } from './chunk-HLOUDLPI.js';
2
+ import { credentialStorageKey, resolveCredentialStatusIdentity, credentialStatusConnected } from '@almadar/core';
3
+
4
+ function userCredentialKey(principal, name) {
5
+ return credentialStorageKey({ name, principal });
6
+ }
7
+ function envTailsOf(env) {
8
+ return (names) => {
9
+ const tails = [];
10
+ for (const name of names) {
11
+ const value = env[name];
12
+ if (value === void 0 || value === "") continue;
13
+ const chars = Array.from(value);
14
+ tails.push(chars.length >= 8 ? { name, last4: chars.slice(-4).join("") } : { name });
15
+ }
16
+ return tails;
17
+ };
18
+ }
19
+ var installedSecretsHost = {
20
+ async store() {
21
+ return getEffectiveCredentialStore();
22
+ },
23
+ async resolve(name, principal) {
24
+ return resolveCredentialRef(name, void 0, principal);
25
+ }
26
+ };
27
+ function createSecretStore(now = Date.now, host = installedSecretsHost, tokenPost) {
28
+ const environmentMinted = /* @__PURE__ */ new Map();
29
+ const storeMinted = /* @__PURE__ */ new WeakMap();
30
+ const cacheFor = (store) => {
31
+ if (store === null) return environmentMinted;
32
+ const held = storeMinted.get(store);
33
+ if (held !== void 0) return held;
34
+ const cache = /* @__PURE__ */ new Map();
35
+ storeMinted.set(store, cache);
36
+ return cache;
37
+ };
38
+ const slot = (name, principal) => credentialStorageKey({ name, ...principal !== void 0 ? { principal } : {} });
39
+ return {
40
+ async get(name, principal) {
41
+ const store = await host.store();
42
+ const minted = cacheFor(store);
43
+ const key = slot(name, principal);
44
+ const held = minted.get(key);
45
+ if (held !== void 0) {
46
+ if (held.expiresAt > now()) return held.value;
47
+ minted.delete(key);
48
+ }
49
+ if (store !== null && store.enabled && tokenPost !== void 0) {
50
+ const fresh = await store.resolveFresh(name, principal, tokenPost);
51
+ if (fresh !== void 0) return fresh;
52
+ }
53
+ return host.resolve(name, principal);
54
+ },
55
+ async set(name, value, ttlMs, principal) {
56
+ const minted = cacheFor(await host.store());
57
+ const key = slot(name, principal);
58
+ if (ttlMs <= 0) minted.delete(key);
59
+ else minted.set(key, { value, expiresAt: now() + ttlMs });
60
+ },
61
+ async rotate(name, value, principal) {
62
+ const store = await host.store();
63
+ if (store === null) throw new Error("this host keeps no credential store to rotate into");
64
+ cacheFor(store).delete(slot(name, principal));
65
+ await store.replace(name, value, principal);
66
+ },
67
+ async persist(name, value, principal, label) {
68
+ const store = await host.store();
69
+ if (store === null || !store.enabled) throw new Error("this host keeps no credential store to persist into");
70
+ cacheFor(store).delete(slot(name, principal));
71
+ await store.persist(name, value, principal, label);
72
+ },
73
+ async label(name, principal) {
74
+ return (await host.store())?.label(name, principal);
75
+ },
76
+ async durable() {
77
+ const store = await host.store();
78
+ return store !== null && store.enabled;
79
+ },
80
+ async forget(name, principal) {
81
+ const store = await host.store();
82
+ const minted = cacheFor(store);
83
+ const key = slot(name, principal);
84
+ minted.delete(key);
85
+ await store?.remove(name, principal);
86
+ }
87
+ };
88
+ }
89
+ function createCredentialConnectPort(post) {
90
+ return async (grant) => {
91
+ const store = getEffectiveCredentialStore();
92
+ if (store === null || !store.enabled) return { error: { kind: "unavailable", message: "this host holds no credential store that can connect" } };
93
+ return store.connect(grant, post);
94
+ };
95
+ }
96
+ function createCredentialAdminPort() {
97
+ const installed = () => {
98
+ const store = getEffectiveCredentialStore();
99
+ if (store === null) throw new Error("this host keeps no credential store");
100
+ return store;
101
+ };
102
+ return {
103
+ async list() {
104
+ return getEffectiveCredentialStore()?.listing() ?? null;
105
+ },
106
+ async read(name) {
107
+ return getEffectiveCredentialStore()?.resolve(name) ?? null;
108
+ },
109
+ async write(service, name, value) {
110
+ await installed().set(service, name, value);
111
+ },
112
+ async remove(name) {
113
+ return installed().remove(name);
114
+ },
115
+ async rotate() {
116
+ return installed().rotate();
117
+ },
118
+ async mode() {
119
+ return getModeControl()?.mode ?? null;
120
+ },
121
+ async setMode(mode) {
122
+ const control = getModeControl();
123
+ if (control === null) throw new Error("No integration manager is installed on this host");
124
+ if (mode !== "mock" && mode !== "real") throw new Error(`mode must be "mock" or "real", got "${mode}"`);
125
+ control.setMode(mode);
126
+ return control.mode;
127
+ }
128
+ };
129
+ }
130
+ var systemRandom = (bytes) => crypto.getRandomValues(new Uint8Array(bytes));
131
+ var RANDOM_BYTES_MAX = 1024;
132
+ function binary(bytes) {
133
+ let text = "";
134
+ for (const byte of bytes) text += String.fromCharCode(byte);
135
+ return text;
136
+ }
137
+ function base64Standard(bytes) {
138
+ return btoa(binary(bytes));
139
+ }
140
+ function base64Url(bytes) {
141
+ return base64Standard(bytes).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
142
+ }
143
+ function randomBytesPayload(ports, bytes, key) {
144
+ if (key !== void 0 && (typeof key !== "string" || key === "")) {
145
+ throw new Error(`call key must evaluate to a non-empty string, got ${String(key)}`);
146
+ }
147
+ if (typeof bytes !== "number" || !Number.isInteger(bytes) || bytes < 1 || bytes > RANDOM_BYTES_MAX) {
148
+ throw new Error(`random-bytes: the byte count must be an integer from 1 to ${RANDOM_BYTES_MAX}, got ${String(bytes)}`);
149
+ }
150
+ const value = base64Url(ports.random(bytes));
151
+ return key === void 0 ? { value } : { value, key };
152
+ }
153
+ function signedIn(head, principal) {
154
+ if (principal === void 0) throw new Error(`${head}: nobody is signed in`);
155
+ return principal;
156
+ }
157
+ function credentialName(head, credential) {
158
+ if (typeof credential !== "string") throw new Error(`${head}: the credential must be a secret knob's name`);
159
+ return credential;
160
+ }
161
+ async function credentialStatusPayload(ports, credential, principal) {
162
+ const identity = resolveCredentialStatusIdentity(credential, principal);
163
+ const connected = credentialStatusConnected(await ports.secrets.get(identity.name, identity.principal), identity.principal);
164
+ const label = connected ? await ports.secrets.label?.(identity.name, identity.principal) ?? "" : "";
165
+ return { connected, label };
166
+ }
167
+ async function credentialForgetPayload(ports, credential, principal) {
168
+ const who = signedIn("credential-forget", principal);
169
+ const name = credentialName("credential-forget", credential);
170
+ await ports.secrets.forget(name, who);
171
+ return { connected: false, label: "" };
172
+ }
173
+ function createSecretPorts(options = {}) {
174
+ return {
175
+ random: options.random ?? systemRandom,
176
+ secrets: options.secrets ?? createSecretStore(Date.now, installedSecretsHost, options.tokenPost),
177
+ credentials: options.credentials ?? createCredentialAdminPort(),
178
+ env: options.env ?? ((names) => envTailsOf(process.env)(names)),
179
+ ...options.tokenPost !== void 0 ? { connect: createCredentialConnectPort(options.tokenPost) } : {}
180
+ };
181
+ }
182
+ var browserSecrets = {
183
+ async get(name) {
184
+ throw new Error(`credential ${name} is not available in a browser`);
185
+ },
186
+ async set(name) {
187
+ throw new Error(`credential ${name} cannot be stored in a browser`);
188
+ },
189
+ async forget(name) {
190
+ throw new Error(`credential ${name} cannot be forgotten in a browser`);
191
+ }
192
+ };
193
+ function createBrowserSecretPorts() {
194
+ return { random: systemRandom, secrets: browserSecrets };
195
+ }
196
+
197
+ export { RANDOM_BYTES_MAX, base64Standard, base64Url, createBrowserSecretPorts, createCredentialAdminPort, createCredentialConnectPort, createSecretPorts, createSecretStore, credentialForgetPayload, credentialStatusPayload, envTailsOf, randomBytesPayload, systemRandom, userCredentialKey };
@@ -1,4 +1,4 @@
1
- import { OrbitalSchema, OrbitalEventRequest, OrbitalEventResponse, RowSetRef, RowQueryPage, EmittedEvent, ServerTopology } from '@almadar/core';
1
+ import { OrbitalSchema, EventRequest, EventResponse, RowSetRef, RowQueryPage, EmittedEvent, ServerTopology } from '@almadar/core';
2
2
 
3
3
  /**
4
4
  * EventTransport — the client → orbital event transport port (plan P5,
@@ -11,8 +11,8 @@ import { OrbitalSchema, OrbitalEventRequest, OrbitalEventResponse, RowSetRef, Ro
11
11
  * be switched onto this port at the W5b build checkpoint (see the plan);
12
12
  * until then this file has no consumers outside this package.
13
13
  *
14
- * The wire shapes are `@almadar/core`'s existing `OrbitalEventRequest` /
15
- * `OrbitalEventResponse` — no shadow types.
14
+ * The wire shapes are `@almadar/core`'s existing `EventRequest` /
15
+ * `EventResponse` — no shadow types.
16
16
  *
17
17
  * @packageDocumentation
18
18
  */
@@ -48,7 +48,7 @@ interface EventTransport {
48
48
  register(schema: OrbitalSchema): Promise<EventTransportRegisterResult>;
49
49
  unregister(): Promise<void>;
50
50
  /** Play one event through the orbital named `orbitalName`. */
51
- send(orbitalName: string, request: OrbitalEventRequest): Promise<OrbitalEventResponse>;
51
+ send(orbitalName: string, request: EventRequest): Promise<EventResponse>;
52
52
  /**
53
53
  * A row-set reference resolved by the host that holds the rows, for the viewer the transport is signed in as (the
54
54
  * host applies `@read`): the rows that still match, in the reference's order. Absent when the transport has no
@@ -78,7 +78,7 @@ interface EventTransport {
78
78
  subscribeHostDispatches?(onDispatch: HostDispatchListener, params?: Record<string, string>): () => void;
79
79
  }
80
80
  /** A dispatch the host ran on its own, with its result. */
81
- type HostDispatchListener = (orbitalName: string, request: OrbitalEventRequest, response: OrbitalEventResponse) => void;
81
+ type HostDispatchListener = (orbitalName: string, request: EventRequest, response: EventResponse) => void;
82
82
  /**
83
83
  * Supplies the bearer token the hosting server authenticates with. Resolved
84
84
  * per request (tokens expire); `undefined` sends the request unauthenticated
@@ -86,6 +86,22 @@ type HostDispatchListener = (orbitalName: string, request: OrbitalEventRequest,
86
86
  * from `@almadar/ui`'s `providers/ServerBridge.tsx`.
87
87
  */
88
88
  type AccessTokenProvider = () => Promise<string | undefined>;
89
+ /** The host freed this client's session after its live stream dropped: mount again with the frames the client holds (EXEC-DIST-9). */
90
+ declare class SessionEndedError extends Error {
91
+ constructor(message: string);
92
+ }
93
+ /** The host answered a dispatch with a non-2xx status: a transport or auth failure, never an event response. */
94
+ declare class TransportStatusError extends Error {
95
+ readonly status: number;
96
+ readonly bodyText: string;
97
+ /** The `{ error, code }` body when the answer carried one. */
98
+ readonly refusal: RefusalBody | undefined;
99
+ constructor(status: number, bodyText: string);
100
+ }
101
+ interface RefusalBody {
102
+ code?: string;
103
+ error?: string;
104
+ }
89
105
  interface HttpTransportOptions {
90
106
  serverUrl: string;
91
107
  getAccessToken?: AccessTokenProvider;
@@ -108,7 +124,7 @@ declare function encodeJsonBody(value: object, compress: boolean): Promise<{
108
124
  /** HTTP transport — POSTs to a server speaking the canonical playground-runtime contract. */
109
125
  declare function createHttpTransport(options: HttpTransportOptions): EventTransport;
110
126
  /** Evaluates one event against an orbital with no wire in between — the unified `evaluateOrbitalEvent` (a separate, in-progress unit) is a valid `OrbitalEvaluator`. */
111
- type OrbitalEvaluator = (orbitalName: string, request: OrbitalEventRequest) => Promise<OrbitalEventResponse>;
127
+ type OrbitalEvaluator = (orbitalName: string, request: EventRequest) => Promise<EventResponse>;
112
128
  interface InProcessTransportOptions {
113
129
  onRegister?: (schema: OrbitalSchema) => Promise<void> | void;
114
130
  onUnregister?: () => Promise<void> | void;
@@ -127,5 +143,5 @@ interface InProcessTransportOptions {
127
143
  /** In-process transport — the evaluator is INJECTED (e.g. the unified `evaluateOrbitalEvent`, owned elsewhere). */
128
144
  declare function createInProcessTransport(evaluate: OrbitalEvaluator, options?: InProcessTransportOptions): EventTransport;
129
145
 
130
- export { COMPRESSED_BODY_MIN_BYTES, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody };
146
+ export { COMPRESSED_BODY_MIN_BYTES, SessionEndedError, TransportStatusError, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody };
131
147
  export type { AccessTokenProvider, EventTransport, EventTransportRegisterResult, HostDispatchListener, HttpTransportOptions, InProcessTransportOptions, OrbitalEvaluator, PushTarget };
@@ -1,2 +1 @@
1
- export { COMPRESSED_BODY_MIN_BYTES, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody } from '../chunk-QELZ6TEJ.js';
2
- import '../chunk-MLKGABMK.js';
1
+ export { COMPRESSED_BODY_MIN_BYTES, SessionEndedError, TransportStatusError, createHttpTransport, createInProcessTransport, deriveCarriesCircuitState, encodeJsonBody } from '../chunk-UD2CXYSJ.js';
@@ -1,2 +1 @@
1
1
  export { AwaitingRegistry } from '../chunk-HC6ERSAH.js';
2
- import '../chunk-MLKGABMK.js';
@@ -1,4 +1,4 @@
1
- import { OrbitalEventRequest, OrbitalEventResponse, EmittedEvent } from '@almadar/core';
1
+ import { EventRequest, EventResponse, EmittedEvent } from '@almadar/core';
2
2
  import { PushTarget, EventTransport } from './EventTransport.js';
3
3
 
4
4
  /**
@@ -20,11 +20,11 @@ type ChannelMessage = {
20
20
  almadarChannel: 'send';
21
21
  id: number;
22
22
  orbitalName: string;
23
- request: OrbitalEventRequest;
23
+ request: EventRequest;
24
24
  } | {
25
25
  almadarChannel: 'reply';
26
26
  id: number;
27
- response: OrbitalEventResponse;
27
+ response: EventResponse;
28
28
  } | {
29
29
  almadarChannel: 'push';
30
30
  emitted: EmittedEvent;
@@ -32,8 +32,8 @@ type ChannelMessage = {
32
32
  } | {
33
33
  almadarChannel: 'dispatched';
34
34
  orbitalName: string;
35
- request: OrbitalEventRequest;
36
- response: OrbitalEventResponse;
35
+ request: EventRequest;
36
+ response: EventResponse;
37
37
  };
38
38
  interface TransportChannel {
39
39
  post(message: ChannelMessage): void;
@@ -51,7 +51,7 @@ interface ServedChannel {
51
51
  /** Push a host-side event to the view (e.g. one a declared input caused while no view was asking). */
52
52
  push(emitted: EmittedEvent, target: PushTarget): void;
53
53
  /** Send the view the result of a dispatch the host ran on its own. */
54
- pushDispatch(orbitalName: string, request: OrbitalEventRequest, response: OrbitalEventResponse): void;
54
+ pushDispatch(orbitalName: string, request: EventRequest, response: EventResponse): void;
55
55
  stop(): void;
56
56
  }
57
57
  /** The host half: serve `transport` on `channel` for the program named `schemaName`. */
@@ -1,2 +1 @@
1
1
  export { createChannelTransport, holdUntilServed, serveChannel } from '../chunk-SKLMWHQD.js';
2
- import '../chunk-MLKGABMK.js';
@@ -1,8 +1,8 @@
1
1
  import { AwaitingRegistry } from './awaiting.js';
2
2
  import { StateBook } from './state-book.js';
3
- import { EntityRow, EventPayload, TraitDefinition } from '@almadar/core';
3
+ import { EntityRow, TraitDefinition } from '@almadar/core';
4
+ import { FrameDelta } from '@almadar/core/kernel-wire';
4
5
  import { RollbackCause, TransitionObserver } from './trait-types.js';
5
- import '@almadar/core/kernel-wire';
6
6
 
7
7
  /**
8
8
  * CircuitStore — P2, `docs/Almadar_Runtime_Stateless_Stateful_PLAN.md` §4.2.
@@ -28,14 +28,25 @@ interface TraitSnapshot {
28
28
  state: string;
29
29
  frame: EntityRow | undefined;
30
30
  }
31
+ /**
32
+ * What a frame delta did to the store: `applied`; `stale` (its version is behind the one painted: dropped, so an
33
+ * old repaint never overwrites a newer value); `gap` (it starts past the painted version: nothing applied, the
34
+ * caller asks the kernel for `framesSince(frameVersion)` and applies the snapshot).
35
+ */
36
+ type FrameOutcome = 'applied' | 'stale' | 'gap';
31
37
  interface CircuitStore {
32
38
  /** Each trait's state as the kernel last reported it. */
33
39
  readonly states: StateBook;
34
40
  /** The entity-frame map (`(set @entity.X)` writes), keyed by
35
41
  * `IndexedTrait.frameKey`. */
36
42
  readonly frames: Map<string, EntityRow>;
37
- /** Embedded child → the payload its composer last composed it with (sticky `@callsitePayload`). */
38
- readonly callsitePayloads: Map<string, EventPayload>;
43
+ /** The version of the kernel's frame record this store has painted. */
44
+ readonly frameVersion: number;
45
+ /**
46
+ * Paint the kernel's frame delta (EXEC-DIST-7): ops land only at the version they start from, and a snapshot
47
+ * (`from` 0 with a leading `clear`) always lands. The store merges nothing by its own rules.
48
+ */
49
+ applyFrames(delta: FrameDelta): FrameOutcome;
39
50
  /** Traits awaiting a server round trip (per-trait subscriptions; see `AwaitingRegistry`). */
40
51
  readonly awaiting: AwaitingRegistry;
41
52
  /**
@@ -73,4 +84,4 @@ interface CircuitStore {
73
84
  declare function createMemoryCircuitStore(traits?: readonly TraitDefinition[], observer?: TransitionObserver): CircuitStore;
74
85
 
75
86
  export { createMemoryCircuitStore };
76
- export type { CircuitStore, TraitSnapshot };
87
+ export type { CircuitStore, FrameOutcome, TraitSnapshot };
@@ -1,4 +1,3 @@
1
- export { createMemoryCircuitStore } from '../chunk-ODJCZ27I.js';
2
- import '../chunk-Q2H75UYT.js';
1
+ export { createMemoryCircuitStore } from '../chunk-N7HYNKK6.js';
2
+ import '../chunk-A2JJT4GA.js';
3
3
  import '../chunk-HC6ERSAH.js';
4
- import '../chunk-MLKGABMK.js';