@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
@@ -0,0 +1,398 @@
1
+ import { LaneHeldByParkedDispatch } from './chunk-NU6LVKGS.js';
2
+ import { decodeDueTicks, decodeResolveProgress, decodeProgress, decodeNext } from './chunk-X6W44WHO.js';
3
+ import { declareCapabilities, answerRequest } from './chunk-7WB6VWRK.js';
4
+ import { installKernelEvaluator, LiveBroadcastItemSchema, MountSeedSchema, ExternalInputSchema, NameListSchema, PayloadJsonSchemaSchema, PayloadIssueSchema, InboundOnlySchema, OptionalNameSchema, EntityRowSchema, isEntityReferenceAny, InboundAnswerSchema, EventPayloadSchema, InboundFoundSchema } from '@almadar/core';
5
+
6
+ var PROGRAM_SURFACE = {
7
+ parse(input) {
8
+ return input;
9
+ }
10
+ };
11
+ function declaredEntityTypes(schema) {
12
+ return schema.orbitals.flatMap((orbital) => [orbital.entity, ...orbital.auxiliaryEntities ?? []].flatMap((entity) => isEntityReferenceAny(entity) ? [] : [entity.name]));
13
+ }
14
+ function contractAnswers(ask) {
15
+ return {
16
+ findExternalInput(orbital, trait, event) {
17
+ return ask(ExternalInputSchema.nullable(), { kind: "findExternalInput", orbital, trait, event }) ?? void 0;
18
+ },
19
+ findInbound(name) {
20
+ return ask(InboundFoundSchema, { kind: "findInbound", name });
21
+ },
22
+ inboundPayload(route, delivery, credential) {
23
+ const headers = Object.fromEntries(Object.entries(delivery.headers).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
24
+ return ask(EventPayloadSchema, { kind: "inboundPayload", route, headers, rawBody: delivery.rawBody, ...typeof credential === "string" ? { credential } : {} });
25
+ },
26
+ inboundAnswer(route, emitted, error) {
27
+ return ask(InboundAnswerSchema, { kind: "inboundAnswer", route, emitted, ...error !== void 0 ? { error } : {} });
28
+ },
29
+ credentialUnset(credential) {
30
+ return ask(InboundAnswerSchema, { kind: "credentialUnset", credential });
31
+ },
32
+ dispatchFailed(message) {
33
+ return ask(InboundAnswerSchema, { kind: "dispatchFailed", message });
34
+ }
35
+ };
36
+ }
37
+ var KernelEngine = class _KernelEngine {
38
+ constructor(kernel, schemaJson, ports, entityTypes = [], forkedFrom, providedHandle, preserveProgramContext = false, lazyDir) {
39
+ this.kernel = kernel;
40
+ this.schemaJson = schemaJson;
41
+ this.ports = ports;
42
+ this.entityTypes = entityTypes;
43
+ this.preserveProgramContext = preserveProgramContext;
44
+ this.lazyDir = lazyDir;
45
+ installKernelEvaluator(kernel);
46
+ this.ports = {
47
+ ...ports,
48
+ substrateMessage: (site, key, value) => JSON.parse(kernel.osCompletionEvent(JSON.stringify({ ...site, emit: { success: site.emit.onMessage } }), key, JSON.stringify({ ok: value }))),
49
+ substrateCompletion: (site, key, op, args, outcome) => JSON.parse(kernel.substrateCompletionEvent(JSON.stringify(site), key, op, JSON.stringify(args), JSON.stringify(outcome)))
50
+ };
51
+ this.handle = providedHandle ?? forkedFrom?.fork() ?? this.openServer();
52
+ this.declare();
53
+ }
54
+ kernel;
55
+ schemaJson;
56
+ ports;
57
+ entityTypes;
58
+ preserveProgramContext;
59
+ lazyDir;
60
+ handle;
61
+ turns = /* @__PURE__ */ new Map();
62
+ tickRelayIntervalMs;
63
+ stateful = false;
64
+ /**
65
+ * A kernel on the same program, registered once, holding none of this one's session: every trait at its initial
66
+ * state, no rows the kernel held, its mounted ticks kept. A stateless host serves each request a
67
+ * fork (EXEC-DIST-5), `ports` answering it.
68
+ */
69
+ fork(ports = this.ports) {
70
+ return new _KernelEngine(this.kernel, this.schemaJson, ports, this.entityTypes, this.handle, void 0, this.preserveProgramContext, this.lazyDir);
71
+ }
72
+ forkProgram(program, ports = this.ports) {
73
+ const schemaJson = JSON.stringify(program);
74
+ const entityTypes = [.../* @__PURE__ */ new Set([
75
+ ...this.entityTypes,
76
+ ...declaredEntityTypes(program)
77
+ ])];
78
+ return new _KernelEngine(this.kernel, schemaJson, ports, entityTypes, void 0, this.handle.forkProgram(schemaJson), true);
79
+ }
80
+ /** A server over the host's ports. */
81
+ openServer() {
82
+ return new this.kernel.Server(this.schemaJson, this.lazyDir);
83
+ }
84
+ declare() {
85
+ const handle = this.handle;
86
+ declareCapabilities(this.ports.persistence, (entityType, queryJson, writeJson) => handle.setCapabilities(entityType, queryJson, writeJson), this.entityTypes);
87
+ }
88
+ /** The contract answers for a host with no program registered yet: the kernel's, asked with no program. */
89
+ static withoutProgram(kernel) {
90
+ return contractAnswers((schema, query) => schema.parse(JSON.parse(kernel.contractQueryWithoutProgram(JSON.stringify(query)))));
91
+ }
92
+ static open(kernel, schema, ports, lazyDir) {
93
+ return new _KernelEngine(kernel, JSON.stringify(schema), ports, declaredEntityTypes(schema), void 0, void 0, false, lazyDir);
94
+ }
95
+ /** A fresh kernel on the same program: every trait back at its initial state. */
96
+ reset() {
97
+ const contextualHandle = this.preserveProgramContext ? this.handle.fork() : void 0;
98
+ this.handle.free();
99
+ this.handle = contextualHandle ?? this.openServer();
100
+ this.declare();
101
+ if (this.tickRelayIntervalMs !== void 0) this.handle.setTickRelayInterval(this.tickRelayIntervalMs);
102
+ if (this.stateful) this.handle.setStateful(true);
103
+ if (this.managedProgram !== void 0) this.handle.setManagedProgram(this.managedProgram);
104
+ }
105
+ managedProgram;
106
+ /** The program whose declared credentials this kernel's credential effects manage beside its own (a console's app). */
107
+ setManagedProgram(program) {
108
+ this.managedProgram = JSON.stringify(program);
109
+ this.handle.setManagedProgram(this.managedProgram);
110
+ }
111
+ /** `client` mounted `traits` of `orbital`: their mount-scoped ticks fire while any client holds them. A request derives this itself; this is for a mount made outside a request. */
112
+ mountClient(client, orbital, traits) {
113
+ this.handle.mountClient(client, orbital, JSON.stringify(traits));
114
+ }
115
+ unmountClient(client, orbital, traits) {
116
+ this.handle.unmountClient(client, orbital, JSON.stringify(traits));
117
+ }
118
+ /** `client` is gone: everything it mounted is released. */
119
+ releaseClient(client) {
120
+ this.handle.releaseClient(client);
121
+ }
122
+ /** This host holds the circuit state: the kernel takes a client's copy of it only on a delegated leg and refuses any other request carrying one. */
123
+ setStateful() {
124
+ this.stateful = true;
125
+ this.handle.setStateful(true);
126
+ }
127
+ /** Whether the program declares any tick: the host runs its timer only then. */
128
+ declaresTicks() {
129
+ return this.handle.declaresTicks();
130
+ }
131
+ /** Queue a tick-stamped dispatch for the coalesced peer relay; the ms after which to flush when it opened a window. */
132
+ relayTick(orbital, request) {
133
+ const window = JSON.parse(this.handle.relayTick(orbital, JSON.stringify(request)));
134
+ return window ?? void 0;
135
+ }
136
+ /** The relay window's length in ms; the kernel's default is 50. */
137
+ setTickRelayInterval(intervalMs) {
138
+ this.tickRelayIntervalMs = intervalMs;
139
+ this.handle.setTickRelayInterval(intervalMs);
140
+ }
141
+ /** Every item queued since the window opened, in first-arrival order; the window closes. */
142
+ flushTickRelay() {
143
+ return LiveBroadcastItemSchema.array().parse(JSON.parse(this.handle.flushTickRelay()));
144
+ }
145
+ /** One pass of the kernel's tick clock: the ticks due at monotonic `nowMs` that this server runs (`[background]` ticks, and those of a mounted trait), keyed by the orbital each `runTick` request is addressed to. */
146
+ tickPass(nowMs) {
147
+ return decodeDueTicks(this.handle.tickPass(nowMs));
148
+ }
149
+ /** Stop the kernel's tick clock; its phase is kept. */
150
+ tickPause() {
151
+ this.handle.tickPause();
152
+ }
153
+ /** Restart the kernel's tick clock; the paused span is never counted. */
154
+ tickResume() {
155
+ this.handle.tickResume();
156
+ }
157
+ tickPaused() {
158
+ return this.handle.tickPaused();
159
+ }
160
+ /** What this host mounts when it starts: the kernel's boot mounts for the side it serves (EXEC-ENDPOINT-3). */
161
+ bootMounts(side) {
162
+ return MountSeedSchema.array().parse(JSON.parse(this.handle.bootMounts(side)));
163
+ }
164
+ /** What mounts when a client opens `routePath` (EXEC-ENDPOINT-3). */
165
+ routeMounts(routePath) {
166
+ return MountSeedSchema.array().parse(JSON.parse(this.handle.routeMounts(routePath)));
167
+ }
168
+ dispose() {
169
+ this.handle.free();
170
+ }
171
+ answers = contractAnswers((schema, query) => this.contract(schema, query));
172
+ contract(schema, query) {
173
+ return schema.parse(JSON.parse(this.handle.contractQuery(JSON.stringify(query))));
174
+ }
175
+ /** Every external input the program declares: what an outside client may send which trait. */
176
+ externalInputs() {
177
+ return this.contract(ExternalInputSchema.array(), { kind: "externalInputs" });
178
+ }
179
+ /** What the kernel holds of every trait of the program, in name order, and the browser-stored entities. */
180
+ programSurface() {
181
+ return this.contract(PROGRAM_SURFACE, { kind: "programSurface" });
182
+ }
183
+ /** The entities a provider acting as the caller may read. */
184
+ readableEntities() {
185
+ return this.contract(NameListSchema, { kind: "readableEntities" });
186
+ }
187
+ /** The declared input of `trait.event` in `orbital`, when there is one. */
188
+ findExternalInput(orbital, trait, event) {
189
+ return this.answers.findExternalInput(orbital, trait, event);
190
+ }
191
+ /** The declared input a `listens`-addressed event names from `caller`'s position (`EVENT`, `Trait.EVENT`, `Orbital.Trait.EVENT`), when there is one. */
192
+ findInputByAddress(address, caller) {
193
+ return this.contract(ExternalInputSchema.nullable(), { kind: "findInputByAddress", address, caller }) ?? void 0;
194
+ }
195
+ /** A declared payload as the JSON Schema of one object: what a tool-calling model fills. */
196
+ payloadJsonSchema(fields) {
197
+ return this.contract(PayloadJsonSchemaSchema, { kind: "payloadSchemaToJsonSchema", fields });
198
+ }
199
+ /** The ways `value` misses the declared payload `fields`. */
200
+ payloadIssues(fields, value) {
201
+ return this.contract(PayloadIssueSchema.array(), { kind: "payloadIssues", fields, value });
202
+ }
203
+ /** The route a hook name is delivered to, or the answer to write for a hook the program does not serve. */
204
+ findInbound(name) {
205
+ return this.answers.findInbound(name);
206
+ }
207
+ /** The trait that handles `event` as an inbound hook in `orbital`, with the refusal message, when a client-facing request names it. */
208
+ inboundOnly(orbital, trait, event) {
209
+ return this.contract(InboundOnlySchema, { kind: "inboundOnly", orbital, ...trait !== void 0 ? { trait } : {}, event }) ?? void 0;
210
+ }
211
+ /** The payload an inbound event is delivered with. */
212
+ inboundPayload(route, delivery, credential) {
213
+ return this.answers.inboundPayload(route, delivery, credential);
214
+ }
215
+ /** The HTTP answer a finished dispatch produced for `route`. */
216
+ inboundAnswer(route, emitted, error) {
217
+ return this.answers.inboundAnswer(route, emitted, error);
218
+ }
219
+ /** The answer for a route whose credential the host holds no value for. */
220
+ credentialUnset(credential) {
221
+ return this.answers.credentialUnset(credential);
222
+ }
223
+ /** The answer for a delivery whose dispatch failed. */
224
+ dispatchFailed(message) {
225
+ return this.answers.dispatchFailed(message);
226
+ }
227
+ /** The name of the program's `[identity]` entity, when it declares one. */
228
+ identityEntity() {
229
+ return this.contract(OptionalNameSchema, { kind: "identityEntity" }) ?? void 0;
230
+ }
231
+ /** The orbital that declares `entity` inline. */
232
+ entityOwnerOrbital(entity) {
233
+ return this.contract(OptionalNameSchema, { kind: "entityOwner", entity }) ?? void 0;
234
+ }
235
+ /** `rows` of `entity` as `user` reads them: narrowed by the entity's declared `@read`, which the kernel evaluates with `@user` bound to the viewer. */
236
+ readRows(entity, rows, user) {
237
+ return this.contract(EntityRowSchema.array(), { kind: "readRows", entity, rows, viewer: user ?? null });
238
+ }
239
+ liveItemDelivered(item, clientId) {
240
+ return this.handle.liveItemDelivered(JSON.stringify(item), clientId);
241
+ }
242
+ /** `OsGrants::allows` over the grants of `orbital` in the program this kernel runs (the app level alone with no orbital). */
243
+ osAllows(requirementJson, orbital) {
244
+ return this.handle.osAllows(requirementJson, orbital);
245
+ }
246
+ /** Whether `url`'s origin is declared in the program's `egress` (the kernel's rule). */
247
+ egressAllows(url) {
248
+ return this.handle.egressAllows(url);
249
+ }
250
+ /** Place the program's anchored grants and arguments under the host's anchors. */
251
+ setOsAnchors(anchorsJson) {
252
+ return this.handle.setOsAnchors(anchorsJson);
253
+ }
254
+ /** An `os/` call's arguments with its anchored parts resolved under the host's anchors. */
255
+ osResolveArgs(op, argsJson) {
256
+ return this.handle.osResolveArgs(op, argsJson);
257
+ }
258
+ tlsComplete(key, outcomeJson) {
259
+ return this.handle.tlsComplete(key, outcomeJson);
260
+ }
261
+ /** A live stream of `client`'s session opened (EXEC-DIST-9); the id closes it. */
262
+ openSessionStream(client) {
263
+ return this.handle.openSessionStream(client);
264
+ }
265
+ /** The live stream `id` dropped: the kernel frees the session once its streams have all dropped and it is quiet. */
266
+ closeSessionStream(id) {
267
+ return this.handle.closeSessionStream(id);
268
+ }
269
+ /** The current state of a trait instance, `''` when it has none. */
270
+ stateOf(traitName, entityId) {
271
+ return this.handle.getState(traitName, entityId);
272
+ }
273
+ /**
274
+ * `reference` resolved for the identity `scope.originClientId`'s session bound (the anonymous viewer with none) against the host-answered store (EXEC-RENDER-3): the rows that still
275
+ * match its query and that identity's `@read` in the reference's order, a missing or hidden row omitted, and `total`
276
+ * re-counted (a `total: none` reference is not re-counted: the total is the resolved window). Each read the
277
+ * kernel makes is answered here, as in `evaluate`.
278
+ */
279
+ async resolveRows(reference, scope) {
280
+ const handle = this.handle;
281
+ let progress = decodeResolveProgress(handle.resolveRows(JSON.stringify(reference), scope.originClientId));
282
+ while (progress.status === "await") {
283
+ const { flight, requests } = progress;
284
+ let replies;
285
+ try {
286
+ replies = await Promise.all(
287
+ requests.map(async (pending) => ({ id: pending.id, answer: await answerRequest(this.ports, pending.request, scope) }))
288
+ );
289
+ } catch (error) {
290
+ handle.abandon(flight);
291
+ throw error;
292
+ }
293
+ progress = decodeResolveProgress(handle.resumeResolve(flight, JSON.stringify(replies)));
294
+ }
295
+ return { rows: progress.rows, total: progress.total };
296
+ }
297
+ /**
298
+ * Run `request` against `orbital`. The kernel orders every start and every resumption (EXEC-CONC-2): while another
299
+ * dispatch holds the lane it answers `queued` and runs the work itself once the lane frees; this host only answers
300
+ * what each dispatch asks.
301
+ */
302
+ async evaluate(orbital, request, scope) {
303
+ const handle = this.handle;
304
+ const streams = scope.onStream !== void 0;
305
+ let running = await this.ran(handle.start(orbital, JSON.stringify(request)), streams);
306
+ try {
307
+ while (running.progress.status === "await") {
308
+ const { flight, requests } = running.progress;
309
+ const assertReentry = () => {
310
+ if (handle.holdsLane(flight)) throw new LaneHeldByParkedDispatch(flight, request.event);
311
+ };
312
+ let replies;
313
+ try {
314
+ replies = await Promise.all(
315
+ requests.map(async (pending) => ({ id: pending.id, answer: await answerRequest(this.ports, pending.request, { ...scope, assertReentry }) }))
316
+ );
317
+ } catch (error) {
318
+ handle.abandon(flight);
319
+ throw error;
320
+ }
321
+ running = await this.ran(handle.resume(flight, JSON.stringify(replies)), streams);
322
+ }
323
+ } finally {
324
+ this.runQueued();
325
+ }
326
+ if (scope.onStream !== void 0 && running.stream !== void 0) {
327
+ const items = JSON.parse(running.stream);
328
+ for (const item of items) scope.onStream(item);
329
+ scope.onStream({ type: "complete", data: running.progress.response, timestamp: Date.now() });
330
+ }
331
+ return running.progress.response;
332
+ }
333
+ /** The kernel's answer to a start or resume, once it has run: at once, or when the kernel takes it from its queue. */
334
+ ran(json, streams) {
335
+ const progress = decodeProgress(json);
336
+ if (progress.status !== "queued") return this.running(progress, streams);
337
+ const turn = new Promise((ran, failed) => {
338
+ this.turns.set(progress.ticket, { streams, ran, failed });
339
+ });
340
+ queueMicrotask(() => this.runQueued());
341
+ return turn;
342
+ }
343
+ running(progress, streams) {
344
+ return { progress, stream: streams && progress.status === "done" ? this.handle.dispatchStream() : void 0 };
345
+ }
346
+ /** Run each piece of queued work that can run now, in the kernel's order, handing each to the dispatch it continues. */
347
+ runQueued() {
348
+ for (; ; ) {
349
+ const next = decodeNext(this.handle.next());
350
+ if (next === null) return;
351
+ const turn = this.turns.get(next.ticket);
352
+ if (turn === void 0) throw new Error(`kernel wire: the kernel ran ticket ${next.ticket}, which nothing waits on`);
353
+ this.turns.delete(next.ticket);
354
+ if (next.outcome === "failed") {
355
+ turn.failed(new Error(next.error));
356
+ continue;
357
+ }
358
+ if (next.progress.status === "queued") throw new Error("kernel wire: the kernel queued work it was running");
359
+ turn.ran(this.running(next.progress, turn.streams));
360
+ }
361
+ }
362
+ };
363
+ function kernelRequest(request, locale) {
364
+ const { _activeTraits: _dropped, _targetTrait: sidecarTarget, ...rest } = request.payload ?? {};
365
+ const payload = rest;
366
+ const target = request.targetTrait ?? (typeof sidecarTarget === "string" ? sidecarTarget : void 0);
367
+ const { payload: _payload, user: _hostViewer, ...others } = request;
368
+ return {
369
+ ...others,
370
+ ...request.payload !== void 0 ? { payload } : {},
371
+ ...target !== void 0 ? { targetTrait: target } : {},
372
+ ...locale !== void 0 ? { locale } : {}
373
+ };
374
+ }
375
+ function withOriginClient(response, clientId) {
376
+ if (clientId === void 0) return response;
377
+ return {
378
+ ...response,
379
+ emittedEvents: response.emittedEvents.map((emitted) => emitted.source === void 0 ? emitted : { ...emitted, source: { ...emitted.source, originClientId: emitted.source.originClientId ?? clientId } })
380
+ };
381
+ }
382
+ async function evaluateOnKernel(kernel, request, locale) {
383
+ return withOriginClient(await kernel.engine.evaluate(kernel.orbital, kernelRequest(request, locale), {
384
+ orbital: kernel.orbital,
385
+ ...request.clientId !== void 0 ? { originClientId: request.clientId } : {},
386
+ ...locale !== void 0 ? { locale } : {},
387
+ ...request.entityId !== void 0 ? { entityId: request.entityId } : {},
388
+ ...kernel.onStream !== void 0 ? { onStream: (item) => {
389
+ if (item.type === "event" && item.data.source !== void 0 && request.clientId !== void 0) {
390
+ kernel.onStream?.({ ...item, data: { ...item.data, source: { ...item.data.source, originClientId: item.data.source.originClientId ?? request.clientId } } });
391
+ } else if (item.type === "complete") {
392
+ kernel.onStream?.({ ...item, data: withOriginClient(item.data, request.clientId) });
393
+ } else kernel.onStream?.(item);
394
+ } } : {}
395
+ }), request.clientId);
396
+ }
397
+
398
+ export { KernelEngine, evaluateOnKernel, kernelRequest };
@@ -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,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-I3TKINSO.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,43 @@ 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
37
  });
38
- if (options.messages !== void 0) engine.setMessages(Object.keys(options.messages), options.messages);
39
- engine.setTickMount([...buildTraitIndex(schema.orbitals).byName.keys()]);
38
+ for (const trait of engine.programSurface().traits) engine.mountClient(LOCAL_CLIENT, trait.orbital, [trait.name]);
40
39
  return engine;
41
40
  }
42
41
  function createLocalStoreTransport(options) {
43
42
  return createInProcessTransport(
44
43
  async (orbital, request) => evaluateOnKernel(
45
- {
46
- engine: await options.kernelEngine,
47
- orbital,
48
- ...options.outsideEventQueue !== void 0 ? { outsideEventQueue: options.outsideEventQueue } : {}
49
- },
44
+ { engine: await options.kernelEngine, orbital },
50
45
  request,
51
- await options.user,
52
- request.locale
46
+ request.locale ?? options.locale?.()
53
47
  ),
54
48
  {
55
49
  carriesCircuitState: false,
56
- ...options.schema !== void 0 ? { resolveRows: resolveOn(options, options.schema) } : {}
50
+ ...options.schema !== void 0 ? { resolveRows: resolveOn(options) } : {}
57
51
  }
58
52
  );
59
53
  }
60
- function resolveOn(options, schema) {
61
- return async (reference) => resolveLocalRows(await options.kernelEngine, schema, await options.user, reference);
54
+ function resolveOn(options) {
55
+ return async (reference) => resolveLocalRows(await options.kernelEngine, reference);
62
56
  }
63
- function resolveLocalRows(engine, schema, user, reference) {
64
- const owner = entityOwnerOrbital(schema, reference.entityType);
57
+ function resolveLocalRows(engine, reference) {
58
+ const owner = engine.entityOwnerOrbital(reference.entityType);
65
59
  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 } : {} });
60
+ return engine.resolveRows(reference, { orbital: owner });
67
61
  }
68
62
 
69
63
  export { createLocalStoreTransport, localStorePersistence, openLocalKernel, resolveLocalRows };
@@ -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 };
@@ -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 };