@almadar/shell-runtime 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-2WCVOMZ2.js +112 -0
- package/dist/chunk-57SBCUSM.js +62 -0
- package/dist/{chunk-Q2H75UYT.js → chunk-A2JJT4GA.js} +1 -37
- package/dist/chunk-BAS26HBN.js +10 -0
- package/dist/{chunk-REPX5QPI.js → chunk-BOVU4TCQ.js} +11 -3
- package/dist/chunk-BY5G4225.js +6 -0
- package/dist/chunk-DFDNHVDW.js +284 -0
- package/dist/{chunk-NATGCIVM.js → chunk-JVSREWQO.js} +378 -130
- package/dist/{chunk-DYOJGLIX.js → chunk-LKWYCYX5.js} +2 -5
- package/dist/chunk-LYFIQPXX.js +1 -0
- package/dist/{chunk-ODJCZ27I.js → chunk-N7HYNKK6.js} +35 -2
- package/dist/{chunk-4J2QEIUV.js → chunk-NTFQ36UN.js} +4 -30
- package/dist/chunk-NU6LVKGS.js +15 -0
- package/dist/{chunk-VNMG7NKY.js → chunk-OQVSN7DP.js} +21 -26
- package/dist/chunk-P2N6K2IV.js +20 -0
- package/dist/{chunk-QQRDUMB2.js → chunk-QCJWPXLH.js} +11 -11
- package/dist/{chunk-QELZ6TEJ.js → chunk-UD2CXYSJ.js} +39 -3
- package/dist/{chunk-UJHOUZAL.js → chunk-V4EMDPCO.js} +2 -5
- package/dist/chunk-VKQA2DJX.js +409 -0
- package/dist/chunk-VNGXRYFF.js +9 -0
- package/dist/{chunk-HNOAZWFH.js → chunk-WGCWJOT2.js} +2 -0
- package/dist/chunk-XZGVOBY6.js +33 -0
- package/dist/chunk-ZUSM4VW4.js +197 -0
- package/dist/client/EventTransport.d.ts +23 -7
- package/dist/client/EventTransport.js +1 -2
- package/dist/client/awaiting.js +0 -1
- package/dist/client/channel-transport.d.ts +6 -6
- package/dist/client/channel-transport.js +0 -1
- package/dist/client/circuit-store.d.ts +16 -5
- package/dist/client/circuit-store.js +2 -3
- package/dist/client/client-kernel.d.ts +36 -15
- package/dist/client/declared-input-dispatch.d.ts +19 -2
- package/dist/client/declared-input-dispatch.js +1 -2
- package/dist/client/inbound-dispatch.d.ts +21 -2
- package/dist/client/inbound-dispatch.js +1 -2
- package/dist/client/local-fold.d.ts +15 -8
- package/dist/client/local-fold.js +1 -2
- package/dist/client/render-sigils.js +0 -1
- package/dist/client/state-book.d.ts +9 -16
- package/dist/client/state-book.js +1 -2
- package/dist/client/trait-mount-error.js +0 -1
- package/dist/credentials/env-vars.d.ts +5 -1
- package/dist/credentials/env-vars.js +1 -3
- package/dist/credentials/scope.d.ts +8 -7
- package/dist/credentials/scope.js +0 -1
- package/dist/credentials/vault.d.ts +142 -0
- package/dist/credentials/vault.js +1 -0
- package/dist/effects/in-flight-calls.js +0 -1
- package/dist/effects/on-device-model.js +0 -1
- package/dist/events/EventBus.d.ts +1 -4
- package/dist/events/EventBus.js +0 -1
- package/dist/events/emit-stamp.js +0 -1
- package/dist/index.d.ts +25 -42
- package/dist/index.js +27 -45
- package/dist/kernel/decode.d.ts +10 -10
- package/dist/kernel/decode.js +1 -2
- package/dist/kernel/engine.d.ts +133 -31
- package/dist/kernel/engine.js +7 -9
- package/dist/kernel/frame-applier.d.ts +8 -7
- package/dist/kernel/frame-applier.js +1 -2
- package/dist/kernel/host.d.ts +148 -16
- package/dist/kernel/host.js +4 -7
- package/dist/kernel/lane.d.ts +1 -22
- package/dist/kernel/lane.js +1 -2
- package/dist/kernel/os-fetch-port.d.ts +7 -0
- package/dist/kernel/os-fetch-port.js +3 -0
- package/dist/kernel/os-port.d.ts +30 -8
- package/dist/kernel/os-port.js +1 -2
- package/dist/kernel/program-effects.d.ts +11 -28
- package/dist/kernel/program-effects.js +1 -2
- package/dist/kernel/secret-ports.d.ts +139 -0
- package/dist/kernel/secret-ports.js +2 -0
- package/dist/kernel/wire.d.ts +113 -12
- package/dist/loader/fetch-loader.d.ts +26 -0
- package/dist/loader/fetch-loader.js +1 -0
- package/dist/loader/lazy-page.js +0 -1
- package/dist/loader/schema-loader.d.ts +1 -17
- package/dist/persistence/native-memory.js +0 -1
- package/dist/runtime/entities/declaredCollections.d.ts +6 -0
- package/dist/runtime/entities/declaredCollections.js +1 -0
- package/dist/runtime/evaluation/local-store-transport.d.ts +16 -23
- package/dist/runtime/evaluation/local-store-transport.js +9 -13
- package/dist/runtime/evaluation/residence-transport.d.ts +3 -3
- package/dist/runtime/evaluation/residence-transport.js +1 -2
- package/dist/runtime/evaluation/routed-persistence.js +0 -1
- package/dist/runtime/events/identity/routing.d.ts +2 -53
- package/dist/runtime/events/identity/routing.js +1 -2
- package/dist/runtime/types.d.ts +5 -205
- package/dist/runtime/types.js +1 -2
- package/dist/service/default-call-service.js +0 -1
- package/dist/service/service-provider.js +0 -1
- package/package.json +8 -5
- package/dist/chunk-2JU7Y4KU.js +0 -21
- package/dist/chunk-46RWK2B5.js +0 -28
- package/dist/chunk-4ZICQ5PM.js +0 -192
- package/dist/chunk-53IPZXDP.js +0 -76
- package/dist/chunk-5D63EMO5.js +0 -16
- package/dist/chunk-CPSQXEJ6.js +0 -55
- package/dist/chunk-CQP5XAX6.js +0 -173
- package/dist/chunk-CROS2GEX.js +0 -49
- package/dist/chunk-D4XJTBLB.js +0 -217
- package/dist/chunk-D5USD2EX.js +0 -232
- package/dist/chunk-EV56K4GB.js +0 -63
- package/dist/chunk-FQ6IZMIU.js +0 -10
- package/dist/chunk-HMK6YMQS.js +0 -135
- package/dist/chunk-IHQLE5M7.js +0 -62
- package/dist/chunk-JFWFDUTR.js +0 -35
- package/dist/chunk-MHYSHSRG.js +0 -54
- package/dist/chunk-MLKGABMK.js +0 -7
- package/dist/chunk-NAECVIAR.js +0 -322
- package/dist/chunk-Q7JK4KY7.js +0 -9
- package/dist/chunk-RBUMDYFS.js +0 -681
- package/dist/chunk-SAS5KKCR.js +0 -43
- package/dist/chunk-SWPDU752.js +0 -28
- package/dist/chunk-T775TUCD.js +0 -18
- package/dist/chunk-VMOBW7RK.js +0 -21
- package/dist/chunk-WNPNNYXY.js +0 -22
- package/dist/chunk-XB5GYODW.js +0 -28
- package/dist/chunk-YL2SO5TP.js +0 -334
- package/dist/chunk-YO4LWS3I.js +0 -606
- package/dist/chunk-ZAQSS47X.js +0 -157
- package/dist/chunk-ZCQUUJIF.js +0 -129
- package/dist/client/ServerBridge.d.ts +0 -126
- package/dist/client/ServerBridge.js +0 -3
- package/dist/credentials/seed.d.ts +0 -21
- package/dist/credentials/seed.js +0 -2
- package/dist/credentials/store.d.ts +0 -110
- package/dist/credentials/store.js +0 -2
- package/dist/index-hT1xCdTq.d.ts +0 -46
- package/dist/kernel/beacon.d.ts +0 -32
- package/dist/kernel/beacon.js +0 -2
- package/dist/kernel/http.d.ts +0 -302
- package/dist/kernel/http.js +0 -6
- package/dist/kernel/oauth-effects.d.ts +0 -25
- package/dist/kernel/oauth-effects.js +0 -7
- package/dist/kernel/oauth-port.d.ts +0 -31
- package/dist/kernel/oauth-port.js +0 -2
- package/dist/loader/http-loader.d.ts +0 -111
- package/dist/loader/http-loader.js +0 -2
- package/dist/runtime/effects/composition/compose-behaviors.d.ts +0 -58
- package/dist/runtime/effects/composition/compose-behaviors.js +0 -4
- package/dist/runtime/effects/composition/event-wiring.d.ts +0 -38
- package/dist/runtime/effects/composition/event-wiring.js +0 -2
- package/dist/runtime/effects/composition/index.d.ts +0 -5
- package/dist/runtime/effects/composition/index.js +0 -6
- package/dist/runtime/effects/composition/layout-strategy.d.ts +0 -35
- package/dist/runtime/effects/composition/layout-strategy.js +0 -2
- package/dist/runtime/effects/composition/pipe.d.ts +0 -25
- package/dist/runtime/effects/composition/pipe.js +0 -2
- package/dist/runtime/entities/mockStoreSeed.d.ts +0 -56
- package/dist/runtime/entities/mockStoreSeed.js +0 -3
- package/dist/runtime/entities/seedBrowserStore.d.ts +0 -28
- package/dist/runtime/entities/seedBrowserStore.js +0 -2
- package/dist/runtime/entities/std-mock-seed.d.ts +0 -87
- package/dist/runtime/entities/std-mock-seed.js +0 -2
- package/dist/runtime/time/TickScheduler.d.ts +0 -77
- package/dist/runtime/time/TickScheduler.js +0 -3
- package/dist/runtime/time/cron.d.ts +0 -25
- package/dist/runtime/time/cron.js +0 -2
- package/dist/runtime/time/duration.d.ts +0 -20
- package/dist/runtime/time/duration.js +0 -2
- package/dist/runtime/traits/OrbitalTraitParsing.d.ts +0 -34
- package/dist/runtime/traits/OrbitalTraitParsing.js +0 -2
- package/dist/runtime/traits/listen-targets.d.ts +0 -16
- package/dist/runtime/traits/listen-targets.js +0 -3
- package/dist/runtime/traits/trait-index.d.ts +0 -35
- package/dist/runtime/traits/trait-index.js +0 -3
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { LaneHeldByParkedDispatch } from './chunk-NU6LVKGS.js';
|
|
2
|
+
import { decodeAnswer, decodeHeldCompletion, decodeDueTicks, decodeResolveProgress, decodeProgress, decodeNext } from './chunk-XZGVOBY6.js';
|
|
3
|
+
import { declareCapabilities, answerRequest } from './chunk-JVSREWQO.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
|
+
...ports.gpu !== void 0 ? {
|
|
51
|
+
heldGpu: {
|
|
52
|
+
answer: async (ticket, completed) => decodeAnswer(await this.handle.answerGpu(ticket, (json) => completed(decodeHeldCompletion(json)))),
|
|
53
|
+
drop: (heldPayload) => {
|
|
54
|
+
this.handle.dropHeldPayload(heldPayload);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} : {}
|
|
58
|
+
};
|
|
59
|
+
this.handle = providedHandle ?? forkedFrom?.fork() ?? this.openServer();
|
|
60
|
+
this.declare();
|
|
61
|
+
}
|
|
62
|
+
kernel;
|
|
63
|
+
schemaJson;
|
|
64
|
+
ports;
|
|
65
|
+
entityTypes;
|
|
66
|
+
preserveProgramContext;
|
|
67
|
+
lazyDir;
|
|
68
|
+
handle;
|
|
69
|
+
turns = /* @__PURE__ */ new Map();
|
|
70
|
+
tickRelayIntervalMs;
|
|
71
|
+
stateful = false;
|
|
72
|
+
/**
|
|
73
|
+
* A kernel on the same program, registered once, holding none of this one's session: every trait at its initial
|
|
74
|
+
* state, no rows the kernel held, its mounted ticks kept. A stateless host serves each request a
|
|
75
|
+
* fork (EXEC-DIST-5), `ports` answering it.
|
|
76
|
+
*/
|
|
77
|
+
fork(ports = this.ports) {
|
|
78
|
+
return new _KernelEngine(this.kernel, this.schemaJson, ports, this.entityTypes, this.handle, void 0, this.preserveProgramContext, this.lazyDir);
|
|
79
|
+
}
|
|
80
|
+
forkProgram(program, ports = this.ports) {
|
|
81
|
+
const schemaJson = JSON.stringify(program);
|
|
82
|
+
const entityTypes = [.../* @__PURE__ */ new Set([
|
|
83
|
+
...this.entityTypes,
|
|
84
|
+
...declaredEntityTypes(program)
|
|
85
|
+
])];
|
|
86
|
+
return new _KernelEngine(this.kernel, schemaJson, ports, entityTypes, void 0, this.handle.forkProgram(schemaJson), true);
|
|
87
|
+
}
|
|
88
|
+
/** A server over the host's ports. */
|
|
89
|
+
/** A server over the host's ports; the host's GPU answerer is installed in it, so it holds every `gpu/` ask. */
|
|
90
|
+
openServer() {
|
|
91
|
+
const server = new this.kernel.Server(this.schemaJson, this.lazyDir);
|
|
92
|
+
if (this.ports.gpu !== void 0) server.installGpu(this.ports.gpu);
|
|
93
|
+
return server;
|
|
94
|
+
}
|
|
95
|
+
declare() {
|
|
96
|
+
const handle = this.handle;
|
|
97
|
+
declareCapabilities(this.ports.persistence, (entityType, queryJson, writeJson) => handle.setCapabilities(entityType, queryJson, writeJson), this.entityTypes);
|
|
98
|
+
}
|
|
99
|
+
/** The contract answers for a host with no program registered yet: the kernel's, asked with no program. */
|
|
100
|
+
static withoutProgram(kernel) {
|
|
101
|
+
return contractAnswers((schema, query) => schema.parse(JSON.parse(kernel.contractQueryWithoutProgram(JSON.stringify(query)))));
|
|
102
|
+
}
|
|
103
|
+
static open(kernel, schema, ports, lazyDir) {
|
|
104
|
+
return new _KernelEngine(kernel, JSON.stringify(schema), ports, declaredEntityTypes(schema), void 0, void 0, false, lazyDir);
|
|
105
|
+
}
|
|
106
|
+
/** A fresh kernel on the same program: every trait back at its initial state. */
|
|
107
|
+
reset() {
|
|
108
|
+
const contextualHandle = this.preserveProgramContext ? this.handle.fork() : void 0;
|
|
109
|
+
this.handle.free();
|
|
110
|
+
this.handle = contextualHandle ?? this.openServer();
|
|
111
|
+
this.declare();
|
|
112
|
+
if (this.tickRelayIntervalMs !== void 0) this.handle.setTickRelayInterval(this.tickRelayIntervalMs);
|
|
113
|
+
if (this.stateful) this.handle.setStateful(true);
|
|
114
|
+
if (this.managedProgram !== void 0) this.handle.setManagedProgram(this.managedProgram);
|
|
115
|
+
}
|
|
116
|
+
managedProgram;
|
|
117
|
+
/** The program whose declared credentials this kernel's credential effects manage beside its own (a console's app). */
|
|
118
|
+
setManagedProgram(program) {
|
|
119
|
+
this.managedProgram = JSON.stringify(program);
|
|
120
|
+
this.handle.setManagedProgram(this.managedProgram);
|
|
121
|
+
}
|
|
122
|
+
/** `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. */
|
|
123
|
+
mountClient(client, orbital, traits) {
|
|
124
|
+
this.handle.mountClient(client, orbital, JSON.stringify(traits));
|
|
125
|
+
}
|
|
126
|
+
unmountClient(client, orbital, traits) {
|
|
127
|
+
this.handle.unmountClient(client, orbital, JSON.stringify(traits));
|
|
128
|
+
}
|
|
129
|
+
/** `client` is gone: everything it mounted is released. */
|
|
130
|
+
releaseClient(client) {
|
|
131
|
+
this.handle.releaseClient(client);
|
|
132
|
+
}
|
|
133
|
+
/** 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. */
|
|
134
|
+
setStateful() {
|
|
135
|
+
this.stateful = true;
|
|
136
|
+
this.handle.setStateful(true);
|
|
137
|
+
}
|
|
138
|
+
/** Whether the program declares any tick: the host runs its timer only then. */
|
|
139
|
+
declaresTicks() {
|
|
140
|
+
return this.handle.declaresTicks();
|
|
141
|
+
}
|
|
142
|
+
/** Queue a tick-stamped dispatch for the coalesced peer relay; the ms after which to flush when it opened a window. */
|
|
143
|
+
relayTick(orbital, request) {
|
|
144
|
+
const window = JSON.parse(this.handle.relayTick(orbital, JSON.stringify(request)));
|
|
145
|
+
return window ?? void 0;
|
|
146
|
+
}
|
|
147
|
+
/** The relay window's length in ms; the kernel's default is 50. */
|
|
148
|
+
setTickRelayInterval(intervalMs) {
|
|
149
|
+
this.tickRelayIntervalMs = intervalMs;
|
|
150
|
+
this.handle.setTickRelayInterval(intervalMs);
|
|
151
|
+
}
|
|
152
|
+
/** Every item queued since the window opened, in first-arrival order; the window closes. */
|
|
153
|
+
flushTickRelay() {
|
|
154
|
+
return LiveBroadcastItemSchema.array().parse(JSON.parse(this.handle.flushTickRelay()));
|
|
155
|
+
}
|
|
156
|
+
/** 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. */
|
|
157
|
+
tickPass(nowMs) {
|
|
158
|
+
return decodeDueTicks(this.handle.tickPass(nowMs));
|
|
159
|
+
}
|
|
160
|
+
/** Stop the kernel's tick clock; its phase is kept. */
|
|
161
|
+
tickPause() {
|
|
162
|
+
this.handle.tickPause();
|
|
163
|
+
}
|
|
164
|
+
/** Restart the kernel's tick clock; the paused span is never counted. */
|
|
165
|
+
tickResume() {
|
|
166
|
+
this.handle.tickResume();
|
|
167
|
+
}
|
|
168
|
+
tickPaused() {
|
|
169
|
+
return this.handle.tickPaused();
|
|
170
|
+
}
|
|
171
|
+
/** What this host mounts when it starts: the kernel's boot mounts for the side it serves (EXEC-ENDPOINT-3). */
|
|
172
|
+
bootMounts(side) {
|
|
173
|
+
return MountSeedSchema.array().parse(JSON.parse(this.handle.bootMounts(side)));
|
|
174
|
+
}
|
|
175
|
+
/** What mounts when a client opens `routePath` (EXEC-ENDPOINT-3). */
|
|
176
|
+
routeMounts(routePath) {
|
|
177
|
+
return MountSeedSchema.array().parse(JSON.parse(this.handle.routeMounts(routePath)));
|
|
178
|
+
}
|
|
179
|
+
dispose() {
|
|
180
|
+
this.handle.free();
|
|
181
|
+
}
|
|
182
|
+
answers = contractAnswers((schema, query) => this.contract(schema, query));
|
|
183
|
+
contract(schema, query) {
|
|
184
|
+
return schema.parse(JSON.parse(this.handle.contractQuery(JSON.stringify(query))));
|
|
185
|
+
}
|
|
186
|
+
/** Every external input the program declares: what an outside client may send which trait. */
|
|
187
|
+
externalInputs() {
|
|
188
|
+
return this.contract(ExternalInputSchema.array(), { kind: "externalInputs" });
|
|
189
|
+
}
|
|
190
|
+
/** What the kernel holds of every trait of the program, in name order, and the browser-stored entities. */
|
|
191
|
+
programSurface() {
|
|
192
|
+
return this.contract(PROGRAM_SURFACE, { kind: "programSurface" });
|
|
193
|
+
}
|
|
194
|
+
/** The entities a provider acting as the caller may read. */
|
|
195
|
+
readableEntities() {
|
|
196
|
+
return this.contract(NameListSchema, { kind: "readableEntities" });
|
|
197
|
+
}
|
|
198
|
+
/** The declared input of `trait.event` in `orbital`, when there is one. */
|
|
199
|
+
findExternalInput(orbital, trait, event) {
|
|
200
|
+
return this.answers.findExternalInput(orbital, trait, event);
|
|
201
|
+
}
|
|
202
|
+
/** The declared input a `listens`-addressed event names from `caller`'s position (`EVENT`, `Trait.EVENT`, `Orbital.Trait.EVENT`), when there is one. */
|
|
203
|
+
findInputByAddress(address, caller) {
|
|
204
|
+
return this.contract(ExternalInputSchema.nullable(), { kind: "findInputByAddress", address, caller }) ?? void 0;
|
|
205
|
+
}
|
|
206
|
+
/** A declared payload as the JSON Schema of one object: what a tool-calling model fills. */
|
|
207
|
+
payloadJsonSchema(fields) {
|
|
208
|
+
return this.contract(PayloadJsonSchemaSchema, { kind: "payloadSchemaToJsonSchema", fields });
|
|
209
|
+
}
|
|
210
|
+
/** The ways `value` misses the declared payload `fields`. */
|
|
211
|
+
payloadIssues(fields, value) {
|
|
212
|
+
return this.contract(PayloadIssueSchema.array(), { kind: "payloadIssues", fields, value });
|
|
213
|
+
}
|
|
214
|
+
/** The route a hook name is delivered to, or the answer to write for a hook the program does not serve. */
|
|
215
|
+
findInbound(name) {
|
|
216
|
+
return this.answers.findInbound(name);
|
|
217
|
+
}
|
|
218
|
+
/** The trait that handles `event` as an inbound hook in `orbital`, with the refusal message, when a client-facing request names it. */
|
|
219
|
+
inboundOnly(orbital, trait, event) {
|
|
220
|
+
return this.contract(InboundOnlySchema, { kind: "inboundOnly", orbital, ...trait !== void 0 ? { trait } : {}, event }) ?? void 0;
|
|
221
|
+
}
|
|
222
|
+
/** The payload an inbound event is delivered with. */
|
|
223
|
+
inboundPayload(route, delivery, credential) {
|
|
224
|
+
return this.answers.inboundPayload(route, delivery, credential);
|
|
225
|
+
}
|
|
226
|
+
/** The HTTP answer a finished dispatch produced for `route`. */
|
|
227
|
+
inboundAnswer(route, emitted, error) {
|
|
228
|
+
return this.answers.inboundAnswer(route, emitted, error);
|
|
229
|
+
}
|
|
230
|
+
/** The answer for a route whose credential the host holds no value for. */
|
|
231
|
+
credentialUnset(credential) {
|
|
232
|
+
return this.answers.credentialUnset(credential);
|
|
233
|
+
}
|
|
234
|
+
/** The answer for a delivery whose dispatch failed. */
|
|
235
|
+
dispatchFailed(message) {
|
|
236
|
+
return this.answers.dispatchFailed(message);
|
|
237
|
+
}
|
|
238
|
+
/** The name of the program's `[identity]` entity, when it declares one. */
|
|
239
|
+
identityEntity() {
|
|
240
|
+
return this.contract(OptionalNameSchema, { kind: "identityEntity" }) ?? void 0;
|
|
241
|
+
}
|
|
242
|
+
/** The orbital that declares `entity` inline. */
|
|
243
|
+
entityOwnerOrbital(entity) {
|
|
244
|
+
return this.contract(OptionalNameSchema, { kind: "entityOwner", entity }) ?? void 0;
|
|
245
|
+
}
|
|
246
|
+
/** `rows` of `entity` as `user` reads them: narrowed by the entity's declared `@read`, which the kernel evaluates with `@user` bound to the viewer. */
|
|
247
|
+
readRows(entity, rows, user) {
|
|
248
|
+
return this.contract(EntityRowSchema.array(), { kind: "readRows", entity, rows, viewer: user ?? null });
|
|
249
|
+
}
|
|
250
|
+
liveItemDelivered(item, clientId) {
|
|
251
|
+
return this.handle.liveItemDelivered(JSON.stringify(item), clientId);
|
|
252
|
+
}
|
|
253
|
+
/** `OsGrants::allows` over the grants of `orbital` in the program this kernel runs (the app level alone with no orbital). */
|
|
254
|
+
osAllows(requirementJson, orbital) {
|
|
255
|
+
return this.handle.osAllows(requirementJson, orbital);
|
|
256
|
+
}
|
|
257
|
+
/** Whether `url`'s origin is declared in the program's `egress` (the kernel's rule). */
|
|
258
|
+
egressAllows(url) {
|
|
259
|
+
return this.handle.egressAllows(url);
|
|
260
|
+
}
|
|
261
|
+
/** Place the program's anchored grants and arguments under the host's anchors. */
|
|
262
|
+
setOsAnchors(anchorsJson) {
|
|
263
|
+
return this.handle.setOsAnchors(anchorsJson);
|
|
264
|
+
}
|
|
265
|
+
/** An `os/` call's arguments with its anchored parts resolved under the host's anchors. */
|
|
266
|
+
osResolveArgs(op, argsJson) {
|
|
267
|
+
return this.handle.osResolveArgs(op, argsJson);
|
|
268
|
+
}
|
|
269
|
+
tlsComplete(key, outcomeJson) {
|
|
270
|
+
return this.handle.tlsComplete(key, outcomeJson);
|
|
271
|
+
}
|
|
272
|
+
/** A live stream of `client`'s session opened (EXEC-DIST-9); the id closes it. */
|
|
273
|
+
openSessionStream(client) {
|
|
274
|
+
return this.handle.openSessionStream(client);
|
|
275
|
+
}
|
|
276
|
+
/** The live stream `id` dropped: the kernel frees the session once its streams have all dropped and it is quiet. */
|
|
277
|
+
closeSessionStream(id) {
|
|
278
|
+
return this.handle.closeSessionStream(id);
|
|
279
|
+
}
|
|
280
|
+
/** The current state of a trait instance, `''` when it has none. */
|
|
281
|
+
stateOf(traitName, entityId) {
|
|
282
|
+
return this.handle.getState(traitName, entityId);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* `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
|
|
286
|
+
* match its query and that identity's `@read` in the reference's order, a missing or hidden row omitted, and `total`
|
|
287
|
+
* re-counted (a `total: none` reference is not re-counted: the total is the resolved window). Each read the
|
|
288
|
+
* kernel makes is answered here, as in `evaluate`.
|
|
289
|
+
*/
|
|
290
|
+
async resolveRows(reference, scope) {
|
|
291
|
+
const handle = this.handle;
|
|
292
|
+
let progress = decodeResolveProgress(handle.resolveRows(JSON.stringify(reference), scope.originClientId));
|
|
293
|
+
while (progress.status === "await") {
|
|
294
|
+
const { flight, requests } = progress;
|
|
295
|
+
let replies;
|
|
296
|
+
try {
|
|
297
|
+
replies = await Promise.all(
|
|
298
|
+
requests.map(async (pending) => ({ id: pending.id, answer: await answerRequest(this.ports, pending.request, scope) }))
|
|
299
|
+
);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
handle.abandon(flight);
|
|
302
|
+
throw error;
|
|
303
|
+
}
|
|
304
|
+
progress = decodeResolveProgress(handle.resumeResolve(flight, JSON.stringify(replies)));
|
|
305
|
+
}
|
|
306
|
+
return { rows: progress.rows, total: progress.total };
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Run `request` against `orbital`. The kernel orders every start and every resumption (EXEC-CONC-2): while another
|
|
310
|
+
* dispatch holds the lane it answers `queued` and runs the work itself once the lane frees; this host only answers
|
|
311
|
+
* what each dispatch asks.
|
|
312
|
+
*/
|
|
313
|
+
async evaluate(orbital, request, scope) {
|
|
314
|
+
const handle = this.handle;
|
|
315
|
+
const streams = scope.onStream !== void 0;
|
|
316
|
+
let running = await this.ran(handle.start(orbital, JSON.stringify(request)), streams);
|
|
317
|
+
try {
|
|
318
|
+
while (running.progress.status === "await") {
|
|
319
|
+
const { flight, requests } = running.progress;
|
|
320
|
+
const assertReentry = () => {
|
|
321
|
+
if (handle.holdsLane(flight)) throw new LaneHeldByParkedDispatch(flight, request.event);
|
|
322
|
+
};
|
|
323
|
+
let replies;
|
|
324
|
+
try {
|
|
325
|
+
replies = await Promise.all(
|
|
326
|
+
requests.map(async (pending) => ({ id: pending.id, answer: await answerRequest(this.ports, pending.request, { ...scope, assertReentry }) }))
|
|
327
|
+
);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
handle.abandon(flight);
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
running = await this.ran(handle.resume(flight, JSON.stringify(replies)), streams);
|
|
333
|
+
}
|
|
334
|
+
} finally {
|
|
335
|
+
this.runQueued();
|
|
336
|
+
}
|
|
337
|
+
if (scope.onStream !== void 0 && running.stream !== void 0) {
|
|
338
|
+
const items = JSON.parse(running.stream);
|
|
339
|
+
for (const item of items) scope.onStream(item);
|
|
340
|
+
scope.onStream({ type: "complete", data: running.progress.response, timestamp: Date.now() });
|
|
341
|
+
}
|
|
342
|
+
return running.progress.response;
|
|
343
|
+
}
|
|
344
|
+
/** The kernel's answer to a start or resume, once it has run: at once, or when the kernel takes it from its queue. */
|
|
345
|
+
ran(json, streams) {
|
|
346
|
+
const progress = decodeProgress(json);
|
|
347
|
+
if (progress.status !== "queued") return this.running(progress, streams);
|
|
348
|
+
const turn = new Promise((ran, failed) => {
|
|
349
|
+
this.turns.set(progress.ticket, { streams, ran, failed });
|
|
350
|
+
});
|
|
351
|
+
queueMicrotask(() => this.runQueued());
|
|
352
|
+
return turn;
|
|
353
|
+
}
|
|
354
|
+
running(progress, streams) {
|
|
355
|
+
return { progress, stream: streams && progress.status === "done" ? this.handle.dispatchStream() : void 0 };
|
|
356
|
+
}
|
|
357
|
+
/** Run each piece of queued work that can run now, in the kernel's order, handing each to the dispatch it continues. */
|
|
358
|
+
runQueued() {
|
|
359
|
+
for (; ; ) {
|
|
360
|
+
const next = decodeNext(this.handle.next());
|
|
361
|
+
if (next === null) return;
|
|
362
|
+
const turn = this.turns.get(next.ticket);
|
|
363
|
+
if (turn === void 0) throw new Error(`kernel wire: the kernel ran ticket ${next.ticket}, which nothing waits on`);
|
|
364
|
+
this.turns.delete(next.ticket);
|
|
365
|
+
if (next.outcome === "failed") {
|
|
366
|
+
turn.failed(new Error(next.error));
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (next.progress.status === "queued") throw new Error("kernel wire: the kernel queued work it was running");
|
|
370
|
+
turn.ran(this.running(next.progress, turn.streams));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
function kernelRequest(request, locale) {
|
|
375
|
+
const { _activeTraits: _dropped, _targetTrait: sidecarTarget, ...rest } = request.payload ?? {};
|
|
376
|
+
const payload = rest;
|
|
377
|
+
const target = request.targetTrait ?? (typeof sidecarTarget === "string" ? sidecarTarget : void 0);
|
|
378
|
+
const { payload: _payload, user: _hostViewer, ...others } = request;
|
|
379
|
+
return {
|
|
380
|
+
...others,
|
|
381
|
+
...request.payload !== void 0 ? { payload } : {},
|
|
382
|
+
...target !== void 0 ? { targetTrait: target } : {},
|
|
383
|
+
...locale !== void 0 ? { locale } : {}
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function withOriginClient(response, clientId) {
|
|
387
|
+
if (clientId === void 0) return response;
|
|
388
|
+
return {
|
|
389
|
+
...response,
|
|
390
|
+
emittedEvents: response.emittedEvents.map((emitted) => emitted.source === void 0 ? emitted : { ...emitted, source: { ...emitted.source, originClientId: emitted.source.originClientId ?? clientId } })
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
async function evaluateOnKernel(kernel, request, locale) {
|
|
394
|
+
return withOriginClient(await kernel.engine.evaluate(kernel.orbital, kernelRequest(request, locale), {
|
|
395
|
+
orbital: kernel.orbital,
|
|
396
|
+
...request.clientId !== void 0 ? { originClientId: request.clientId } : {},
|
|
397
|
+
...locale !== void 0 ? { locale } : {},
|
|
398
|
+
...request.entityId !== void 0 ? { entityId: request.entityId } : {},
|
|
399
|
+
...kernel.onStream !== void 0 ? { onStream: (item) => {
|
|
400
|
+
if (item.type === "event" && item.data.source !== void 0 && request.clientId !== void 0) {
|
|
401
|
+
kernel.onStream?.({ ...item, data: { ...item.data, source: { ...item.data.source, originClientId: item.data.source.originClientId ?? request.clientId } } });
|
|
402
|
+
} else if (item.type === "complete") {
|
|
403
|
+
kernel.onStream?.({ ...item, data: withOriginClient(item.data, request.clientId) });
|
|
404
|
+
} else kernel.onStream?.(item);
|
|
405
|
+
} } : {}
|
|
406
|
+
}), request.clientId);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export { KernelEngine, evaluateOnKernel, kernelRequest };
|
|
@@ -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 };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { decodeServerProgressWire, decodeIoAnswerWire, decodeHeldGpuCompletion, 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 decodeAnswer(json) {
|
|
9
|
+
return decodeIoAnswerWire(JSON.parse(json));
|
|
10
|
+
}
|
|
11
|
+
function decodeHeldCompletion(json) {
|
|
12
|
+
const value = JSON.parse(json);
|
|
13
|
+
return value === null ? null : decodeHeldGpuCompletion(value);
|
|
14
|
+
}
|
|
15
|
+
function decodeNext(json) {
|
|
16
|
+
const value = JSON.parse(json);
|
|
17
|
+
return value === null ? null : decodeNextWire(value);
|
|
18
|
+
}
|
|
19
|
+
function decodeResolveProgress(json) {
|
|
20
|
+
return decodeResolveProgressWire(JSON.parse(json));
|
|
21
|
+
}
|
|
22
|
+
function decodeDueTicks(json) {
|
|
23
|
+
const value = JSON.parse(json);
|
|
24
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("tickPass: the kernel answered a non-object");
|
|
25
|
+
const byOrbital = {};
|
|
26
|
+
for (const [orbital, ticks] of Object.entries(value)) {
|
|
27
|
+
if (!Array.isArray(ticks)) throw new Error(`tickPass: the kernel answered a non-list for orbital ${orbital}`);
|
|
28
|
+
byOrbital[orbital] = ticks.map(decodeFiredTick);
|
|
29
|
+
}
|
|
30
|
+
return byOrbital;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { decodeAnswer, decodeDueTicks, decodeHeldCompletion, 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 };
|