@almadar/shell-runtime 0.0.0-stage → 0.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 (180) hide show
  1. package/dist/chunk-2JU7Y4KU.js +21 -0
  2. package/dist/chunk-46RWK2B5.js +28 -0
  3. package/dist/chunk-4J2QEIUV.js +78 -0
  4. package/dist/chunk-4SEK5ER2.js +8 -0
  5. package/dist/chunk-4ZICQ5PM.js +192 -0
  6. package/dist/chunk-53IPZXDP.js +76 -0
  7. package/dist/chunk-5D63EMO5.js +16 -0
  8. package/dist/chunk-64IH2SMY.js +22 -0
  9. package/dist/chunk-7SDV3QWR.js +67 -0
  10. package/dist/chunk-CPSQXEJ6.js +55 -0
  11. package/dist/chunk-CQP5XAX6.js +173 -0
  12. package/dist/chunk-CROS2GEX.js +49 -0
  13. package/dist/chunk-D4XJTBLB.js +217 -0
  14. package/dist/chunk-D5USD2EX.js +232 -0
  15. package/dist/chunk-DYOJGLIX.js +25 -0
  16. package/dist/chunk-ELBLT2HZ.js +1 -0
  17. package/dist/chunk-EV56K4GB.js +63 -0
  18. package/dist/chunk-EZZYLTWY.js +1 -0
  19. package/dist/chunk-FQ6IZMIU.js +10 -0
  20. package/dist/chunk-FWA5K7Q2.js +48 -0
  21. package/dist/chunk-HC6ERSAH.js +55 -0
  22. package/dist/chunk-HLOUDLPI.js +48 -0
  23. package/dist/chunk-HMK6YMQS.js +135 -0
  24. package/dist/chunk-HNOAZWFH.js +19 -0
  25. package/dist/chunk-IHQLE5M7.js +62 -0
  26. package/dist/chunk-IOPUS6Q5.js +15 -0
  27. package/dist/chunk-JFWFDUTR.js +35 -0
  28. package/dist/chunk-LZIOTBFX.js +1 -0
  29. package/dist/chunk-MHYSHSRG.js +54 -0
  30. package/dist/chunk-MLKGABMK.js +7 -0
  31. package/dist/chunk-MZKIL5IN.js +74 -0
  32. package/dist/chunk-NAECVIAR.js +322 -0
  33. package/dist/chunk-NATGCIVM.js +583 -0
  34. package/dist/chunk-O57GKTYU.js +30 -0
  35. package/dist/chunk-ODJCZ27I.js +50 -0
  36. package/dist/chunk-P53CKOME.js +1 -0
  37. package/dist/chunk-Q2H75UYT.js +92 -0
  38. package/dist/chunk-Q7JK4KY7.js +9 -0
  39. package/dist/chunk-QELZ6TEJ.js +208 -0
  40. package/dist/chunk-QQRDUMB2.js +40 -0
  41. package/dist/chunk-RBUMDYFS.js +681 -0
  42. package/dist/chunk-REPX5QPI.js +57 -0
  43. package/dist/chunk-SAS5KKCR.js +43 -0
  44. package/dist/chunk-SKLMWHQD.js +109 -0
  45. package/dist/chunk-SOQDEPME.js +131 -0
  46. package/dist/chunk-SWPDU752.js +28 -0
  47. package/dist/chunk-T775TUCD.js +18 -0
  48. package/dist/chunk-UBN5JJKZ.js +26 -0
  49. package/dist/chunk-UJHOUZAL.js +36 -0
  50. package/dist/chunk-UP6GGGAN.js +34 -0
  51. package/dist/chunk-VMOBW7RK.js +21 -0
  52. package/dist/chunk-VNMG7NKY.js +69 -0
  53. package/dist/chunk-WNPNNYXY.js +22 -0
  54. package/dist/chunk-XB5GYODW.js +28 -0
  55. package/dist/chunk-XXWNMJI6.js +15 -0
  56. package/dist/chunk-YL2SO5TP.js +334 -0
  57. package/dist/chunk-YO4LWS3I.js +606 -0
  58. package/dist/chunk-ZAQSS47X.js +157 -0
  59. package/dist/chunk-ZCQUUJIF.js +129 -0
  60. package/dist/client/EventTransport.d.ts +131 -0
  61. package/dist/client/EventTransport.js +2 -0
  62. package/dist/client/ServerBridge.d.ts +126 -0
  63. package/dist/client/ServerBridge.js +3 -0
  64. package/dist/client/awaiting.d.ts +28 -0
  65. package/dist/client/awaiting.js +2 -0
  66. package/dist/client/channel-transport.d.ts +69 -0
  67. package/dist/client/channel-transport.js +2 -0
  68. package/dist/client/circuit-store.d.ts +76 -0
  69. package/dist/client/circuit-store.js +4 -0
  70. package/dist/client/client-kernel.d.ts +113 -0
  71. package/dist/client/client-kernel.js +1 -0
  72. package/dist/client/declared-input-dispatch.d.ts +5 -0
  73. package/dist/client/declared-input-dispatch.js +2 -0
  74. package/dist/client/inbound-dispatch.d.ts +5 -0
  75. package/dist/client/inbound-dispatch.js +2 -0
  76. package/dist/client/local-fold.d.ts +26 -0
  77. package/dist/client/local-fold.js +2 -0
  78. package/dist/client/render-sigils.d.ts +24 -0
  79. package/dist/client/render-sigils.js +2 -0
  80. package/dist/client/state-book.d.ts +37 -0
  81. package/dist/client/state-book.js +2 -0
  82. package/dist/client/trait-mount-error.d.ts +9 -0
  83. package/dist/client/trait-mount-error.js +2 -0
  84. package/dist/client/trait-types.d.ts +67 -0
  85. package/dist/client/trait-types.js +1 -0
  86. package/dist/credentials/env-vars.d.ts +14 -0
  87. package/dist/credentials/env-vars.js +3 -0
  88. package/dist/credentials/scope.d.ts +50 -0
  89. package/dist/credentials/scope.js +2 -0
  90. package/dist/credentials/seed.d.ts +21 -0
  91. package/dist/credentials/seed.js +2 -0
  92. package/dist/credentials/store.d.ts +110 -0
  93. package/dist/credentials/store.js +2 -0
  94. package/dist/effects/in-flight-calls.d.ts +36 -0
  95. package/dist/effects/in-flight-calls.js +2 -0
  96. package/dist/effects/on-device-model.d.ts +22 -0
  97. package/dist/effects/on-device-model.js +2 -0
  98. package/dist/events/EventBus.d.ts +90 -0
  99. package/dist/events/EventBus.js +2 -0
  100. package/dist/events/emit-stamp.d.ts +47 -0
  101. package/dist/events/emit-stamp.js +2 -0
  102. package/dist/index-hT1xCdTq.d.ts +46 -0
  103. package/dist/index.d.ts +60 -0
  104. package/dist/index.js +59 -0
  105. package/dist/kernel/beacon.d.ts +32 -0
  106. package/dist/kernel/beacon.js +2 -0
  107. package/dist/kernel/decode.d.ts +15 -0
  108. package/dist/kernel/decode.js +2 -0
  109. package/dist/kernel/engine.d.ts +94 -0
  110. package/dist/kernel/engine.js +11 -0
  111. package/dist/kernel/frame-applier.d.ts +43 -0
  112. package/dist/kernel/frame-applier.js +2 -0
  113. package/dist/kernel/host.d.ts +95 -0
  114. package/dist/kernel/host.js +9 -0
  115. package/dist/kernel/http.d.ts +302 -0
  116. package/dist/kernel/http.js +6 -0
  117. package/dist/kernel/lane.d.ts +28 -0
  118. package/dist/kernel/lane.js +2 -0
  119. package/dist/kernel/oauth-effects.d.ts +25 -0
  120. package/dist/kernel/oauth-effects.js +7 -0
  121. package/dist/kernel/oauth-port.d.ts +31 -0
  122. package/dist/kernel/oauth-port.js +2 -0
  123. package/dist/kernel/os-port.d.ts +133 -0
  124. package/dist/kernel/os-port.js +2 -0
  125. package/dist/kernel/program-effects.d.ts +65 -0
  126. package/dist/kernel/program-effects.js +2 -0
  127. package/dist/kernel/wire.d.ts +66 -0
  128. package/dist/kernel/wire.js +1 -0
  129. package/dist/loader/http-loader.d.ts +111 -0
  130. package/dist/loader/http-loader.js +2 -0
  131. package/dist/loader/lazy-page.d.ts +12 -0
  132. package/dist/loader/lazy-page.js +2 -0
  133. package/dist/loader/schema-loader.d.ts +160 -0
  134. package/dist/loader/schema-loader.js +1 -0
  135. package/dist/persistence/native-memory.d.ts +28 -0
  136. package/dist/persistence/native-memory.js +2 -0
  137. package/dist/runtime/effects/composition/compose-behaviors.d.ts +58 -0
  138. package/dist/runtime/effects/composition/compose-behaviors.js +4 -0
  139. package/dist/runtime/effects/composition/event-wiring.d.ts +38 -0
  140. package/dist/runtime/effects/composition/event-wiring.js +2 -0
  141. package/dist/runtime/effects/composition/index.d.ts +5 -0
  142. package/dist/runtime/effects/composition/index.js +6 -0
  143. package/dist/runtime/effects/composition/layout-strategy.d.ts +35 -0
  144. package/dist/runtime/effects/composition/layout-strategy.js +2 -0
  145. package/dist/runtime/effects/composition/pipe.d.ts +25 -0
  146. package/dist/runtime/effects/composition/pipe.js +2 -0
  147. package/dist/runtime/entities/mockStoreSeed.d.ts +56 -0
  148. package/dist/runtime/entities/mockStoreSeed.js +3 -0
  149. package/dist/runtime/entities/seedBrowserStore.d.ts +28 -0
  150. package/dist/runtime/entities/seedBrowserStore.js +2 -0
  151. package/dist/runtime/entities/std-mock-seed.d.ts +87 -0
  152. package/dist/runtime/entities/std-mock-seed.js +2 -0
  153. package/dist/runtime/evaluation/local-store-transport.d.ts +68 -0
  154. package/dist/runtime/evaluation/local-store-transport.js +18 -0
  155. package/dist/runtime/evaluation/residence-transport.d.ts +15 -0
  156. package/dist/runtime/evaluation/residence-transport.js +2 -0
  157. package/dist/runtime/evaluation/routed-persistence.d.ts +9 -0
  158. package/dist/runtime/evaluation/routed-persistence.js +2 -0
  159. package/dist/runtime/events/identity/routing.d.ts +84 -0
  160. package/dist/runtime/events/identity/routing.js +2 -0
  161. package/dist/runtime/time/TickScheduler.d.ts +77 -0
  162. package/dist/runtime/time/TickScheduler.js +3 -0
  163. package/dist/runtime/time/cron.d.ts +25 -0
  164. package/dist/runtime/time/cron.js +2 -0
  165. package/dist/runtime/time/duration.d.ts +20 -0
  166. package/dist/runtime/time/duration.js +2 -0
  167. package/dist/runtime/traits/OrbitalTraitParsing.d.ts +34 -0
  168. package/dist/runtime/traits/OrbitalTraitParsing.js +2 -0
  169. package/dist/runtime/traits/listen-targets.d.ts +16 -0
  170. package/dist/runtime/traits/listen-targets.js +3 -0
  171. package/dist/runtime/traits/trait-index.d.ts +35 -0
  172. package/dist/runtime/traits/trait-index.js +3 -0
  173. package/dist/runtime/types.d.ts +574 -0
  174. package/dist/runtime/types.js +2 -0
  175. package/dist/service/default-call-service.d.ts +23 -0
  176. package/dist/service/default-call-service.js +3 -0
  177. package/dist/service/service-provider.d.ts +37 -0
  178. package/dist/service/service-provider.js +2 -0
  179. package/package.json +46 -3
  180. package/README.md +0 -3
@@ -0,0 +1,21 @@
1
+ import { findInbound, unknownHook, credentialUnset, inboundPayload, inboundAnswerOf, dispatchFailed } from '@almadar/core';
2
+
3
+ // src/client/inbound-dispatch.ts
4
+ async function dispatchInbound(schema, name, delivery, send, credential) {
5
+ const route = schema ? findInbound(schema, name) : void 0;
6
+ if (route === void 0) return unknownHook(name);
7
+ try {
8
+ const held = route.verifies !== void 0 ? await credential(route.verifies.credential) : void 0;
9
+ if (route.verifies !== void 0 && (held === void 0 || held === null || held === "")) return credentialUnset(route.verifies.credential);
10
+ const response = await send(route.orbital, {
11
+ event: route.event,
12
+ payload: inboundPayload(route, delivery, held),
13
+ targetTrait: route.trait
14
+ });
15
+ return inboundAnswerOf(route, response.emittedEvents, response.error);
16
+ } catch (error) {
17
+ return dispatchFailed(error instanceof Error ? error.message : String(error));
18
+ }
19
+ }
20
+
21
+ export { dispatchInbound };
@@ -0,0 +1,28 @@
1
+ // src/runtime/time/duration.ts
2
+ function parseDurationString(interval) {
3
+ const match = interval.match(/^(\d+)(ms|s|m|h)?$/);
4
+ if (!match) {
5
+ throw new Error(
6
+ `Invalid duration '${interval}': expected a shape like '5ms'/'5s'/'1m'/'1h'`
7
+ );
8
+ }
9
+ const value = parseInt(match[1], 10);
10
+ const unit = match[2] || "ms";
11
+ switch (unit) {
12
+ case "ms":
13
+ return value;
14
+ case "s":
15
+ return value * 1e3;
16
+ case "m":
17
+ return value * 60 * 1e3;
18
+ case "h":
19
+ return value * 60 * 60 * 1e3;
20
+ default:
21
+ return value;
22
+ }
23
+ }
24
+ function isValidDurationString(interval) {
25
+ return /^(\d+)(ms|s|m|h)?$/.test(interval);
26
+ }
27
+
28
+ export { isValidDurationString, parseDurationString };
@@ -0,0 +1,78 @@
1
+ import { isEventResponse } from '@almadar/core/kernel-wire';
2
+ import { createLogger } from '@almadar/logger';
3
+
4
+ // src/kernel/frame-applier.ts
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
+ function decodeFrame(json) {
34
+ if (json === void 0) return void 0;
35
+ const value = JSON.parse(json);
36
+ if (!isFrameWire(value)) throw new Error("kernel wire: frame is not a FrameWire");
37
+ return value;
38
+ }
39
+ var NOTHING = { fired: [], folded: 0, browserLegs: 0, droppedServerEffects: 0, outcomes: [], errors: [] };
40
+ var settle = (posted, failure, trait) => posted.then(
41
+ (effects) => effects,
42
+ (err) => {
43
+ log.warn(failure, { trait, error: String(err) });
44
+ return void 0;
45
+ }
46
+ );
47
+ async function applyFrame(json, kernel, post) {
48
+ const frame = decodeFrame(json);
49
+ if (frame === void 0) return NOTHING;
50
+ for (const message of frame.errors) log.warn("frame-tick-failed", { error: message });
51
+ const last = frame.dispatches.length - 1;
52
+ await kernel.foldLocalResponse(frame.response, false, last < 0);
53
+ for (const [i, dispatch] of frame.dispatches.entries()) await kernel.foldLocalResponse(dispatch.response, true, i === last);
54
+ const outcomes = [{ response: frame.response, mode: "hybridClientOnly" }];
55
+ if (post !== void 0) {
56
+ for (const leg of frame.browserLegs) {
57
+ const tickSettled = settle(post.sendBrowserLeg(leg, frame.response), "tick-browser-leg-failed", leg.leg.targetTrait ?? "");
58
+ outcomes.push({ response: { success: true, transitioned: false, states: {}, emittedEvents: [] }, mode: "hybridClientOnly", tickSettled });
59
+ }
60
+ }
61
+ for (const dispatch of frame.dispatches) {
62
+ if (post === void 0 || dispatch.serverLegs.length === 0 && dispatch.statefulLeg === null) {
63
+ outcomes.push({ response: dispatch.response, mode: dispatch.mode });
64
+ continue;
65
+ }
66
+ outcomes.push({ response: dispatch.response, mode: dispatch.mode, tickSettled: settle(post.postDispatch(dispatch), "tick-post-failed", dispatch.trait) });
67
+ }
68
+ return {
69
+ fired: frame.fired,
70
+ folded: frame.dispatches.length + 1,
71
+ browserLegs: frame.browserLegs.length,
72
+ droppedServerEffects: frame.droppedServerEffects,
73
+ outcomes,
74
+ errors: frame.errors
75
+ };
76
+ }
77
+
78
+ export { applyFrame, decodeFrame, isFrameWire };
@@ -0,0 +1,8 @@
1
+ import { callRegisteredService } from './chunk-UBN5JJKZ.js';
2
+
3
+ // src/service/default-call-service.ts
4
+ function defaultCallService(service, action, params, context) {
5
+ return callRegisteredService(service, action, params, context);
6
+ }
7
+
8
+ export { defaultCallService };
@@ -0,0 +1,192 @@
1
+ import { isJsonObject } from '@almadar/core';
2
+
3
+ // src/kernel/oauth-port.ts
4
+ var PENDING_GRACE_MS = 60 * 60 * 1e3;
5
+ var NO_CALLER = "a provider connection needs a signed-in caller";
6
+ var NO_CONNECTIONS = "no OAuth connection store is installed on this host";
7
+ var NO_TAKE = "this host keeps no derived secrets to take";
8
+ var UNREADABLE = "a held OAuth credential is unreadable";
9
+ var pendingName = (state) => `oauth:grant:${state}`;
10
+ var connectionName = (provider) => `oauth:connection:${provider}`;
11
+ function parseObject(text) {
12
+ let value;
13
+ try {
14
+ value = JSON.parse(text);
15
+ } catch {
16
+ throw new Error(UNREADABLE);
17
+ }
18
+ if (!isJsonObject(value)) throw new Error(UNREADABLE);
19
+ return value;
20
+ }
21
+ function textOf(object, name) {
22
+ const value = object[name];
23
+ if (typeof value !== "string") throw new Error(UNREADABLE);
24
+ return value;
25
+ }
26
+ function textOrNull(object, name) {
27
+ const value = object[name];
28
+ if (value === void 0 || value === null) return null;
29
+ if (typeof value !== "string") throw new Error(UNREADABLE);
30
+ return value;
31
+ }
32
+ function textList(object, name) {
33
+ const value = object[name];
34
+ if (!Array.isArray(value)) throw new Error(UNREADABLE);
35
+ return value.map((item) => {
36
+ if (typeof item !== "string") throw new Error(UNREADABLE);
37
+ return item;
38
+ });
39
+ }
40
+ function objectOf(object, name) {
41
+ const value = object[name];
42
+ if (value === void 0 || !isJsonObject(value)) throw new Error(UNREADABLE);
43
+ return value;
44
+ }
45
+ function grantOf(object) {
46
+ return {
47
+ provider: textOf(object, "provider"),
48
+ redirectUri: textOf(object, "redirectUri"),
49
+ verifier: textOf(object, "verifier"),
50
+ subject: textOrNull(object, "subject"),
51
+ scopes: textList(object, "scopes")
52
+ };
53
+ }
54
+ function rowOf(object, provider) {
55
+ const connected = object.connected;
56
+ if (typeof connected !== "boolean") throw new Error(UNREADABLE);
57
+ return {
58
+ provider,
59
+ connected,
60
+ account: textOf(object, "account"),
61
+ avatarUrl: textOf(object, "avatarUrl"),
62
+ scope: textList(object, "scope"),
63
+ connectedAt: textOf(object, "connectedAt")
64
+ };
65
+ }
66
+ var disconnected = (provider) => ({ provider, connected: false, account: "", avatarUrl: "", scope: [], connectedAt: "" });
67
+ function createOAuthPort(options) {
68
+ const secrets = () => typeof options.secrets === "function" ? options.secrets() : options.secrets;
69
+ const now = options.now ?? Date.now;
70
+ const subjects = /* @__PURE__ */ new Map();
71
+ const mockTokens = /* @__PURE__ */ new Map();
72
+ const mockRefresh = /* @__PURE__ */ new Map();
73
+ const metadata = /* @__PURE__ */ new Map();
74
+ const caller = (principal) => {
75
+ if (principal === void 0 || principal === "") throw new Error(NO_CALLER);
76
+ return principal;
77
+ };
78
+ const durable = async (held) => held.persist !== void 0 && held.durable !== void 0 && held.durable();
79
+ const take = async (held, name, principal) => {
80
+ if (held.take === void 0) throw new Error(NO_TAKE);
81
+ return held.take(name, principal);
82
+ };
83
+ return {
84
+ async answer(ask, principal) {
85
+ switch (ask.ask) {
86
+ case "pendingPut": {
87
+ const held = secrets();
88
+ const record = JSON.stringify({ grant: ask.grant, expiresAt: now() + ask.ttlMs });
89
+ if (held.hold !== void 0) await held.hold(pendingName(ask.state), record, ask.ttlMs + PENDING_GRACE_MS, void 0);
90
+ else await held.set(pendingName(ask.state), record, ask.ttlMs + PENDING_GRACE_MS, void 0);
91
+ return { reply: "done" };
92
+ }
93
+ case "pendingTake": {
94
+ const held = secrets();
95
+ const name = pendingName(ask.state);
96
+ const text = await take(held, name, void 0);
97
+ if (text === void 0) return { reply: "taken", taken: { found: "missing" } };
98
+ const record = parseObject(text);
99
+ const expiresAt = record.expiresAt;
100
+ if (typeof expiresAt !== "number") throw new Error(UNREADABLE);
101
+ if (expiresAt < now()) return { reply: "taken", taken: { found: "expired" } };
102
+ return { reply: "taken", taken: { found: "grant", grant: grantOf(objectOf(record, "grant")) } };
103
+ }
104
+ case "connectionAvailable":
105
+ return { reply: "flag", value: await durable(secrets()) };
106
+ case "connectionSave": {
107
+ const held = secrets();
108
+ if (held.persist === void 0 || !await durable(held)) throw new Error(NO_CONNECTIONS);
109
+ const who = caller(principal);
110
+ const row = {
111
+ provider: ask.provider,
112
+ connected: true,
113
+ account: ask.grant.subject ?? "",
114
+ avatarUrl: "",
115
+ scope: ask.grant.scope ?? [],
116
+ connectedAt: new Date(now()).toISOString()
117
+ };
118
+ await held.persist(connectionName(ask.provider), JSON.stringify({ row, grant: ask.grant }), who);
119
+ return { reply: "row", row };
120
+ }
121
+ case "connectionStatus": {
122
+ const text = await secrets().get(connectionName(ask.provider), caller(principal));
123
+ return { reply: "row", row: text === void 0 ? disconnected(ask.provider) : rowOf(objectOf(parseObject(text), "row"), ask.provider) };
124
+ }
125
+ case "connectionRemove":
126
+ await secrets().forget(connectionName(ask.provider), caller(principal));
127
+ return { reply: "row", row: disconnected(ask.provider) };
128
+ case "subjectRemember":
129
+ subjects.set(ask.accessToken, ask.subject);
130
+ return { reply: "done" };
131
+ case "subjectLookup":
132
+ return { reply: "subject", subject: subjects.get(ask.accessToken) ?? null };
133
+ case "subjectForget":
134
+ subjects.delete(ask.accessToken);
135
+ return { reply: "done" };
136
+ case "metadataGet":
137
+ return { reply: "metadata", metadata: metadata.get(ask.issuer) ?? null };
138
+ case "metadataPut":
139
+ metadata.set(ask.issuer, ask.metadata);
140
+ return { reply: "done" };
141
+ case "clock":
142
+ return { reply: "millis", value: now() };
143
+ case "consent":
144
+ return { reply: "code", code: options.consent === void 0 ? null : await options.consent({ authUrl: ask.authUrl, state: ask.state, redirectUri: ask.redirectUri }) };
145
+ case "mockTokenPut":
146
+ mockTokens.set(ask.accessToken, { refresh: ask.refreshToken, expiresAt: ask.expiresAtMs, provider: ask.provider });
147
+ mockRefresh.set(ask.refreshToken, { access: ask.accessToken, provider: ask.provider });
148
+ return { reply: "done" };
149
+ case "mockTokenRefresh": {
150
+ const old = mockRefresh.get(ask.refreshToken);
151
+ if (old === void 0) return { reply: "flag", value: false };
152
+ mockTokens.delete(old.access);
153
+ const sub = subjects.get(old.access);
154
+ subjects.delete(old.access);
155
+ if (sub !== void 0) subjects.set(ask.newAccessToken, sub);
156
+ mockTokens.set(ask.newAccessToken, { refresh: ask.refreshToken, expiresAt: ask.expiresAtMs, provider: old.provider });
157
+ mockRefresh.set(ask.refreshToken, { access: ask.newAccessToken, provider: old.provider });
158
+ return { reply: "flag", value: true };
159
+ }
160
+ case "mockTokenRevoke": {
161
+ const held = mockTokens.get(ask.token);
162
+ if (held !== void 0) {
163
+ mockTokens.delete(ask.token);
164
+ mockRefresh.delete(held.refresh);
165
+ subjects.delete(ask.token);
166
+ return { reply: "flag", value: true };
167
+ }
168
+ const issued = mockRefresh.get(ask.token);
169
+ if (issued !== void 0) {
170
+ mockRefresh.delete(ask.token);
171
+ mockTokens.delete(issued.access);
172
+ subjects.delete(issued.access);
173
+ return { reply: "flag", value: true };
174
+ }
175
+ return { reply: "flag", value: false };
176
+ }
177
+ case "mockTokenCheck": {
178
+ const held = mockTokens.get(ask.accessToken);
179
+ if (held === void 0) return { reply: "mockToken", state: "missing", provider: null };
180
+ if (now() > held.expiresAt) {
181
+ mockTokens.delete(ask.accessToken);
182
+ subjects.delete(ask.accessToken);
183
+ return { reply: "mockToken", state: "expired", provider: null };
184
+ }
185
+ return { reply: "mockToken", state: "valid", provider: held.provider };
186
+ }
187
+ }
188
+ }
189
+ };
190
+ }
191
+
192
+ export { PENDING_GRACE_MS, createOAuthPort };
@@ -0,0 +1,76 @@
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
+ var DispatchLane = class {
15
+ nextTicket = 0;
16
+ holder;
17
+ depth = 0;
18
+ parkedEvent;
19
+ waiters = [];
20
+ assertCanReenter(turn) {
21
+ if (this.holder === turn && this.parkedEvent !== void 0) throw new LaneHeldByParkedDispatch(turn.ticket, this.parkedEvent);
22
+ }
23
+ async enter(turn) {
24
+ const holder = this.holder;
25
+ if (holder !== void 0 && turn === holder) {
26
+ if (this.parkedEvent !== void 0) {
27
+ throw new LaneHeldByParkedDispatch(holder.ticket, this.parkedEvent);
28
+ }
29
+ this.depth += 1;
30
+ return this.guard(holder, false);
31
+ }
32
+ const own = { ticket: this.nextTicket };
33
+ this.nextTicket += 1;
34
+ if (this.holder === void 0) {
35
+ this.take(own);
36
+ } else {
37
+ await new Promise((grant) => {
38
+ this.waiters.push({ turn: own, grant });
39
+ });
40
+ }
41
+ return this.guard(own, true);
42
+ }
43
+ take(turn) {
44
+ this.holder = turn;
45
+ this.depth = 1;
46
+ this.parkedEvent = void 0;
47
+ }
48
+ guard(turn, outer) {
49
+ let done = false;
50
+ return {
51
+ turn,
52
+ park: (event) => {
53
+ if (!done && outer && this.holder === turn && this.depth === 1) this.parkedEvent = event;
54
+ },
55
+ resume: () => {
56
+ if (!done && outer && this.holder === turn) this.parkedEvent = void 0;
57
+ },
58
+ release: () => {
59
+ if (done) return;
60
+ done = true;
61
+ if (this.holder !== turn) return;
62
+ this.depth -= 1;
63
+ if (this.depth > 0) return;
64
+ this.holder = void 0;
65
+ this.parkedEvent = void 0;
66
+ const next = this.waiters.shift();
67
+ if (next !== void 0) {
68
+ this.take(next.turn);
69
+ next.grant();
70
+ }
71
+ }
72
+ };
73
+ }
74
+ };
75
+
76
+ export { DispatchLane, LaneHeldByParkedDispatch };
@@ -0,0 +1,16 @@
1
+ import { pipeBehaviors } from './chunk-FQ6IZMIU.js';
2
+ import { composeBehaviors } from './chunk-ZCQUUJIF.js';
3
+ import { detectLayoutStrategy } from './chunk-EV56K4GB.js';
4
+ import { applyEventWiring } from './chunk-MHYSHSRG.js';
5
+ import { __export } from './chunk-MLKGABMK.js';
6
+
7
+ // src/runtime/effects/composition/index.ts
8
+ var composition_exports = {};
9
+ __export(composition_exports, {
10
+ applyEventWiring: () => applyEventWiring,
11
+ composeBehaviors: () => composeBehaviors,
12
+ detectLayoutStrategy: () => detectLayoutStrategy,
13
+ pipeBehaviors: () => pipeBehaviors
14
+ });
15
+
16
+ export { composition_exports };
@@ -0,0 +1,22 @@
1
+ // src/events/emit-stamp.ts
2
+ function stampEmitSource(source, identity) {
3
+ const stamp = source ?? {
4
+ orbital: identity.orbitalName,
5
+ trait: identity.traitName
6
+ };
7
+ if (stamp.orbitalId === void 0 && identity.orbitalId !== void 0) {
8
+ stamp.orbitalId = identity.orbitalId;
9
+ }
10
+ if (stamp.traitId === void 0 && identity.traitId !== void 0) {
11
+ stamp.traitId = identity.traitId;
12
+ }
13
+ if (stamp.eventId === void 0 && identity.emitContractEventId !== void 0) {
14
+ stamp.eventId = identity.emitContractEventId;
15
+ }
16
+ if (identity.originClientId !== void 0 && stamp.originClientId === void 0) {
17
+ stamp.originClientId = identity.originClientId;
18
+ }
19
+ return stamp;
20
+ }
21
+
22
+ export { stampEmitSource };
@@ -0,0 +1,67 @@
1
+ import { EntityRowSchema, RowWriteOutcomeSchema, RowQueryPageSchema, RowIdPageSchema, QueryCapabilitiesSchema, WriteCapabilitiesSchema, JsonValueSchema, isJsonObject } from '@almadar/core';
2
+
3
+ // src/persistence/native-memory.ts
4
+ var NativeMemoryWriteError = class extends Error {
5
+ constructor(outcome) {
6
+ super(`native memory update failed: ${outcome.kind}`);
7
+ this.outcome = outcome;
8
+ this.name = "NativeMemoryWriteError";
9
+ }
10
+ outcome;
11
+ };
12
+ var NativeMemoryPersistenceAdapter = class {
13
+ constructor(store) {
14
+ this.store = store;
15
+ }
16
+ store;
17
+ async getById(entityType, id) {
18
+ return EntityRowSchema.nullable().parse(JSON.parse(this.store.getById(entityType, id)));
19
+ }
20
+ async list(entityType) {
21
+ return EntityRowSchema.array().parse(JSON.parse(this.store.list(entityType)));
22
+ }
23
+ // The kernel's plain create merges a supplied existing id; writeWhere exposes strict create and replacement upsert.
24
+ async create(entityType, data) {
25
+ const row = EntityRowSchema.parse(JSON.parse(this.store.create(entityType, JSON.stringify(data))));
26
+ if (typeof row.id !== "string") throw new Error("native memory create returned a row without an id");
27
+ return { id: row.id };
28
+ }
29
+ async update(entityType, id, data) {
30
+ const outcome = RowWriteOutcomeSchema.parse(JSON.parse(this.store.update(entityType, id, JSON.stringify(data))));
31
+ if (outcome.kind !== "updated") throw new NativeMemoryWriteError(outcome);
32
+ }
33
+ async delete(entityType, id) {
34
+ this.store.delete(entityType, id);
35
+ }
36
+ async queryPage(entityType, query) {
37
+ return RowQueryPageSchema.parse(JSON.parse(this.store.queryPage(entityType, JSON.stringify(query))));
38
+ }
39
+ async queryIds(entityType, query) {
40
+ return RowIdPageSchema.parse(JSON.parse(this.store.queryIds(entityType, JSON.stringify(query))));
41
+ }
42
+ queryCapabilities(_entityType) {
43
+ return QueryCapabilitiesSchema.parse(JSON.parse(this.store.queryCapabilities()));
44
+ }
45
+ async writeWhere(op) {
46
+ return RowWriteOutcomeSchema.parse(JSON.parse(this.store.writeWhere(JSON.stringify(op))));
47
+ }
48
+ async writeBatch(batch) {
49
+ return RowWriteOutcomeSchema.array().parse(JSON.parse(this.store.writeBatch(JSON.stringify(batch))));
50
+ }
51
+ writeCapabilities(_entityType) {
52
+ return WriteCapabilitiesSchema.parse(JSON.parse(this.store.writeCapabilities()));
53
+ }
54
+ bindCollection(entityType, collection) {
55
+ this.store.bindCollection(entityType, collection);
56
+ }
57
+ clear() {
58
+ this.store.clear();
59
+ }
60
+ snapshot() {
61
+ const value = JsonValueSchema.parse(JSON.parse(this.store.snapshot()));
62
+ if (!isJsonObject(value)) throw new Error("native memory snapshot returned a non-object");
63
+ return Object.fromEntries(Object.entries(value).map(([key, rows]) => [key, EntityRowSchema.array().parse(rows)]));
64
+ }
65
+ };
66
+
67
+ export { NativeMemoryPersistenceAdapter, NativeMemoryWriteError };
@@ -0,0 +1,55 @@
1
+ import { parseOrbitalTraits } from './chunk-SAS5KKCR.js';
2
+ import { findEntityAmongOrbitals, orbitalInlineEntities } from '@almadar/core';
3
+ import { createLogger } from '@almadar/logger';
4
+
5
+ var traitIndexLog = createLogger("almadar:runtime:trait-index");
6
+ var parseCache = /* @__PURE__ */ new WeakMap();
7
+ function parseOrbitalCached(orbital) {
8
+ let cached = parseCache.get(orbital);
9
+ if (cached === void 0) {
10
+ cached = { traits: parseOrbitalTraits(orbital), entities: orbitalInlineEntities(orbital) };
11
+ parseCache.set(orbital, cached);
12
+ }
13
+ return cached;
14
+ }
15
+ function buildTraitIndex(orbitals) {
16
+ const parsed = orbitals.map((orbital) => ({ orbital, parsed: parseOrbitalCached(orbital).traits }));
17
+ const allEntities = orbitals.map((orbital) => parseOrbitalCached(orbital).entities).flat();
18
+ const orbitalsView = parsed.map(({ orbital, parsed: p }) => ({ schema: orbital, entity: p.entity }));
19
+ const byName = /* @__PURE__ */ new Map();
20
+ for (const { orbital, parsed: p } of parsed) {
21
+ const { traits, inlineTraits, entity } = p;
22
+ for (let i = 0; i < traits.length; i++) {
23
+ const traitDef = traits[i];
24
+ const irTrait = inlineTraits[i];
25
+ const linkedEntityName = irTrait?.linkedEntity;
26
+ let traitEntity = entity;
27
+ if (linkedEntityName && linkedEntityName !== traitEntity.name) {
28
+ const resolved = findEntityAmongOrbitals(allEntities, linkedEntityName);
29
+ if (resolved) {
30
+ traitEntity = resolved;
31
+ } else {
32
+ traitIndexLog.warn("linkedEntity:unresolved", {
33
+ orbital: orbital.name,
34
+ trait: traitDef.name,
35
+ linkedEntityName
36
+ });
37
+ traitEntity = { name: linkedEntityName, fields: [] };
38
+ }
39
+ }
40
+ const isShared = traitEntity.shared === true;
41
+ byName.set(traitDef.name, {
42
+ traitDef,
43
+ irTrait,
44
+ entity: traitEntity,
45
+ orbitalName: orbital.name,
46
+ ...orbital.id !== void 0 ? { orbitalId: orbital.id } : {},
47
+ frameKey: isShared ? `$shared::${traitEntity.name}` : traitDef.name,
48
+ isSharedEntity: isShared
49
+ });
50
+ }
51
+ }
52
+ return { byName, allEntities, orbitals: orbitalsView };
53
+ }
54
+
55
+ export { buildTraitIndex };