@almadar/shell-node 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.
@@ -0,0 +1,63 @@
1
+ import { createRequire } from 'module';
2
+ import { readFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { pathToFileURL } from 'url';
5
+ import { installKernelEvaluator } from '@almadar/core';
6
+ import { readLanguageBundle } from '@almadar/core/language-data';
7
+ import * as installedModule from '@almadar/kernel';
8
+ import { NativeMemoryPersistenceAdapter } from '@almadar/shell-runtime';
9
+
10
+ // src/kernel-loader.ts
11
+ function hasMemoryStore(kernel) {
12
+ return "MemoryStore" in kernel;
13
+ }
14
+ function nativeMemoryOf(kernel) {
15
+ if (!hasMemoryStore(kernel)) throw new Error("this kernel module exports no MemoryStore; install a kernel build that carries it");
16
+ return new NativeMemoryPersistenceAdapter(new kernel.MemoryStore());
17
+ }
18
+ async function loadKernelModule(kernelDir, options) {
19
+ return loadKernel(kernelDir, options);
20
+ }
21
+ var initialised = /* @__PURE__ */ new WeakSet();
22
+ function initOnce(loaded, wasm, languageFrom) {
23
+ if (initialised.has(loaded)) return loaded;
24
+ if (wasm !== void 0) loaded.initSync({ module: wasm });
25
+ loaded.installLanguage(JSON.stringify(readLanguageBundle(languageFrom)));
26
+ installKernelEvaluator(loaded);
27
+ initialised.add(loaded);
28
+ return loaded;
29
+ }
30
+ function initKernelSync(languageFrom) {
31
+ initOnce(installedModule, readFileSync(createRequire(import.meta.url).resolve("@almadar/kernel/kernel.wasm")), languageFrom);
32
+ return installedModule;
33
+ }
34
+ async function loadInstalledKernel(languageFrom) {
35
+ return initKernelSync(languageFrom);
36
+ }
37
+ async function loadHttpKernel(kernelDir, options) {
38
+ return loadKernel(kernelDir, options);
39
+ }
40
+ async function loadKernel(kernelDir, options) {
41
+ const loaded = await import(pathToFileURL(join(kernelDir, "pkg/orbital_wasm.js")).href);
42
+ return initOnce(loaded, initialised.has(loaded) ? void 0 : readFileSync(join(kernelDir, "pkg/orbital_wasm_bg.wasm")), options.languageFrom);
43
+ }
44
+ var NATIVE_PLATFORMS = {
45
+ "darwin-x64": "darwin-x64",
46
+ "darwin-arm64": "darwin-arm64",
47
+ "linux-x64": "linux-x64",
48
+ "linux-arm64": "linux-arm64",
49
+ "win32-x64": "windows-x64"
50
+ };
51
+ function resolveNativeAddon(from) {
52
+ const named = process.env.ALMADAR_KERNEL_NODE;
53
+ if (named !== void 0 && named !== "") return named;
54
+ const platform = NATIVE_PLATFORMS[`${process.platform}-${process.arch}`];
55
+ if (platform === void 0) throw new Error(`no native kernel add-on is shipped for ${process.platform}-${process.arch}`);
56
+ return createRequire(join(from, "resolve.js")).resolve(`@almadar/orb-${platform}/kernel.node`);
57
+ }
58
+ async function loadNativeKernelModule(addonPath, options) {
59
+ const loaded = createRequire(import.meta.url)(addonPath);
60
+ return initOnce(loaded, void 0, options.languageFrom);
61
+ }
62
+
63
+ export { initKernelSync, loadHttpKernel, loadInstalledKernel, loadKernelModule, loadNativeKernelModule, nativeMemoryOf, resolveNativeAddon };
@@ -0,0 +1,18 @@
1
+ import { workspacesRoot, kernelWorkspaceHost, workspaceBucketFromEnv } from './chunk-BJA6GYC5.js';
2
+ import { runProgramEffect } from './chunk-QYAPNUBH.js';
3
+ import { installedWorkspaceHost, installWorkspaceHost } from './chunk-BWMLDDCL.js';
4
+
5
+ // src/program/createProgramHandlers.ts
6
+ var bucketOf = () => {
7
+ const bucket = workspaceBucketFromEnv(process.env);
8
+ return bucket === void 0 ? {} : { bucket };
9
+ };
10
+ function createProgramHandlers(host) {
11
+ const opts = host.orbBin === void 0 ? { cwd: host.cwd } : { cwd: host.cwd, orbBin: host.orbBin };
12
+ if (installedWorkspaceHost()?.root !== workspacesRoot(host.cwd)) {
13
+ installWorkspaceHost(kernelWorkspaceHost({ projectRoot: host.cwd, ...bucketOf(), ...host.orbBin !== void 0 ? { orb: host.orbBin } : {} }));
14
+ }
15
+ return { programEffect: (op, args, context) => runProgramEffect(op, args, opts, context) };
16
+ }
17
+
18
+ export { createProgramHandlers };
@@ -0,0 +1,28 @@
1
+ import { EffectHandlers } from '@almadar/shell-runtime';
2
+
3
+ /**
4
+ * Program host handlers — server-side only.
5
+ *
6
+ * Backs the language trio's effects (behavior/catalog|describe|source,
7
+ * program/read|print|eval) with the one host implementation in
8
+ * `host/program`, which runs the installed `orb` from the
9
+ * project directory. Its workspaces are `std-workspace` run by the kernel
10
+ * (`kernelWorkspaceHost`). Wired by OrbitalServerRuntime
11
+ * (lazy import, merged under user handlers).
12
+ *
13
+ * NOT exported from the main index.ts because it spawns processes.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+
18
+ interface ProgramHostConfig {
19
+ /** Project root `orb` resolves behavior packages from. */
20
+ cwd: string;
21
+ /** Explicit `orb` binary; defaults to the host's resolution order. */
22
+ orbBin?: string;
23
+ }
24
+ type ProgramHandlers = Pick<EffectHandlers, 'programEffect'>;
25
+ declare function createProgramHandlers(host: ProgramHostConfig): ProgramHandlers;
26
+
27
+ export { createProgramHandlers };
28
+ export type { ProgramHandlers, ProgramHostConfig };
@@ -0,0 +1,6 @@
1
+ export { createProgramHandlers } from './chunk-WZFQ7T7V.js';
2
+ import './chunk-BJA6GYC5.js';
3
+ import './chunk-23YAOI6P.js';
4
+ import './chunk-UBZT5LDW.js';
5
+ import './chunk-QYAPNUBH.js';
6
+ import './chunk-BWMLDDCL.js';
@@ -0,0 +1,265 @@
1
+ import { PinnedFetch, CredentialScopeStorage, NetPort, ResolvedHost, OsAnchors, OsGrantPort, OsHostPort, KernelModule, HttpKernel, CredentialSeedKernel, NativeMemoryPersistenceAdapter, ServiceCallContext, StepRequest, PlayedStep, ProgramValidationReport, ProgramEffectName, ProgramEffectOutcome } from '@almadar/shell-runtime';
2
+ import { JsonValue, KernelMemoryStoreExports, OrbitalSchema, EvaluatedProgram, ProgramValidationIssue, CatalogScope, CatalogEntry, DependencyGraph, TraitValue, TraitDescription, DescribeTarget, BehaviorDescription, BehaviorRef, BehaviorValueMountResult, TraitValueMountResult } from '@almadar/core';
3
+ export { ClientEffectTuple, ClientNavigateBackTuple, ClientNavigateTuple, ClientRenderUITuple, OrbitalEventRequest, OrbitalEventResponse, TransitionRejection } from '@almadar/core';
4
+ import * as installedModule from '@almadar/kernel';
5
+ import { LayoutStrategy } from '@almadar/core/builders';
6
+ export { G as GCS_ENDPOINT, K as KernelProgram, a as KernelProgramOptions, b as KernelWorkspaceBucket, c as KernelWorkspaceHostOptions, P as ProgramRun, W as WORKSPACE_HMAC_KEY_ID, d as WORKSPACE_HMAC_SECRET, e as WorkspaceHost, f as WorkspacePort, g as emitPayload, i as installWorkspaceHost, h as installedWorkspaceHost, k as kernelWorkspaceHost, r as resolveKernelDir, j as resolveProgramFile, u as uninstallWorkspaceHost, w as workspaceBucketFromEnv, l as workspaceOwnerSegment, m as workspacesRoot } from './kernel-workspace-host-CU56iOlt.js';
7
+ export { HostDispatchItem, LiveBroadcastItem, LoaderConfig, OrbitalInfo, OrbitalServerRuntime, OrbitalServerRuntimeConfig, OrbitalSummary, PushItem, RegisterOptions, RegisteredOrbital, RuntimeOrbital, RuntimeOrbitalSchema, RuntimeTrait, RuntimeTraitTick, UnresolvedProgramError, createOrbitalServerRuntime } from './OrbitalServerRuntime.js';
8
+ export { ProgramHandlers, ProgramHostConfig, createProgramHandlers } from './createProgramHandlers.js';
9
+
10
+ declare const pinnedFetchNode: PinnedFetch;
11
+
12
+ declare function resolveHostNode(host: string): Promise<ResolvedHost>;
13
+ declare const nodeNetPort: NetPort;
14
+ declare function nodeCredentialScope(): CredentialScopeStorage;
15
+ /** Install the Node ports `@almadar/shell-runtime` leaves open: the pinned `http` fetch + resolver and per-tenant credential scopes. Idempotent. */
16
+ declare function installNodeHostPorts(): void;
17
+
18
+ /**
19
+ * A development host's credential-store master key: read from `<dir>/dev-credential-master-key`,
20
+ * generated there (owner-only) on first use. Production must hold its key in the platform secret
21
+ * store, so this refuses under NODE_ENV=production.
22
+ */
23
+ declare function loadOrCreateDevMasterKey(dir: string): string;
24
+
25
+ /** One program instance's `os` host: its own handle tables, closed by `close`. */
26
+ interface NodeOsHostOptions {
27
+ /** Where `~/` and `./` and the declared grant anchors are placed; absent, the process's own (`OsAnchors::of_process`). */
28
+ anchors?: OsAnchors;
29
+ }
30
+ /** The process's home, working directory, executable directory and environment, read once (`OsAnchors::of_process`). */
31
+ declare function processAnchors(): OsAnchors;
32
+ declare function createNodeOsHost(grants: OsGrantPort, options?: NodeOsHostOptions): OsHostPort;
33
+
34
+ type KvErrorKind = 'denied' | 'invalid' | 'io' | 'timeout' | 'unsupported' | 'closed';
35
+ type KvResult<T> = {
36
+ ok: true;
37
+ value: T;
38
+ } | {
39
+ ok: false;
40
+ error: string;
41
+ kind: KvErrorKind;
42
+ };
43
+ interface KvNamespace {
44
+ app: string;
45
+ locale: string;
46
+ store: string;
47
+ }
48
+ interface KvScanEntry {
49
+ key: string;
50
+ value: JsonValue;
51
+ }
52
+ type KvBatchOp = {
53
+ kind: 'put';
54
+ key: string;
55
+ value: JsonValue;
56
+ } | {
57
+ kind: 'delete';
58
+ key: string;
59
+ };
60
+ declare class KvFailure extends Error {
61
+ readonly kind: KvErrorKind;
62
+ constructor(kind: KvErrorKind, message: string);
63
+ }
64
+ /** A namespace's whole content, key order = UTF-8 byte order. Backends load and commit it whole. */
65
+ type KvTable = Map<string, JsonValue>;
66
+ interface KvBackend {
67
+ load(ns: KvNamespace): Promise<KvTable>;
68
+ /** Replace the namespace content atomically: a failure leaves the previous content. */
69
+ commit(ns: KvNamespace, table: KvTable): Promise<void>;
70
+ }
71
+ declare function namespaceId(ns: KvNamespace): string;
72
+ declare function memoryKvBackend(): KvBackend;
73
+ declare function directoryKvBackend(stateDir: string): KvBackend;
74
+ interface KvHost {
75
+ get(ns: KvNamespace, key: string): Promise<KvResult<{
76
+ found: boolean;
77
+ value?: JsonValue;
78
+ }>>;
79
+ put(ns: KvNamespace, key: string, value: JsonValue): Promise<KvResult<{
80
+ storedKey: string;
81
+ }>>;
82
+ delete(ns: KvNamespace, key: string): Promise<KvResult<{
83
+ existed: boolean;
84
+ }>>;
85
+ scan(ns: KvNamespace, prefix: string, limit?: number): Promise<KvResult<{
86
+ entries: KvScanEntry[];
87
+ }>>;
88
+ batch(ns: KvNamespace, ops: readonly KvBatchOp[]): Promise<KvResult<{
89
+ applied: number;
90
+ }>>;
91
+ }
92
+ declare function createKvHost(backend: KvBackend): KvHost;
93
+
94
+ /** The whole server kernel as Node loads it: the shared module plus the server-only exports the client build omits. */
95
+ interface LoadedKernel extends KernelModule, HttpKernel, CredentialSeedKernel, KernelMemoryStoreExports {
96
+ initSync(input: {
97
+ module: Uint8Array;
98
+ }): object;
99
+ }
100
+ /** A row store the kernel itself holds (its `MemoryStore`), as a host keeps rows with no database. */
101
+ declare function nativeMemoryOf(kernel: KernelModule): NativeMemoryPersistenceAdapter;
102
+ interface LoadKernelOptions {
103
+ /** Where the installed `@almadar/core` and `@almadar/std` are found, node-style. Required: the caller names its own root. */
104
+ languageFrom: string;
105
+ }
106
+ /**
107
+ * Loads the kernel and installs the language data the installed packages declare (the operator table that
108
+ * routes `program/*` and the other host effects), as `orb` reads it. The first install in a process wins.
109
+ */
110
+ declare function loadKernelModule(kernelDir: string, options: LoadKernelOptions): Promise<LoadedKernel>;
111
+ /**
112
+ * The kernel of the `@almadar/kernel` package this host installs, initialised synchronously with the language data
113
+ * the packages under `languageFrom` declare. `languageFrom` is required; the first call in a process wins.
114
+ */
115
+ declare function initKernelSync(languageFrom: string): typeof installedModule;
116
+ /**
117
+ * The kernel of the `@almadar/kernel` package this host installs, loaded once per process with the language data
118
+ * the packages under `languageFrom` declare. A host with no package installed rejects, never falls back.
119
+ */
120
+ declare function loadInstalledKernel(languageFrom: string): Promise<LoadedKernel>;
121
+ /**
122
+ * The `http` effect's builder exports of the same package (`buildHttpRequest`, `isPublicAddress`, …): the
123
+ * interpreter's only way to build a request. A directory that does not hold a built kernel rejects, never falls back.
124
+ */
125
+ declare function loadHttpKernel(kernelDir: string, options: LoadKernelOptions): Promise<HttpKernel>;
126
+ /**
127
+ * Where the native kernel add-on is: `ALMADAR_KERNEL_NODE`, else `kernel.node` in the `@almadar/orb-<platform>-<arch>`
128
+ * package this platform installs. Rejects when neither exists, so a host can fall back to the wasm kernel by choice.
129
+ */
130
+ declare function resolveNativeAddon(from: string): string;
131
+ /**
132
+ * Loads the native kernel add-on (the same API as the wasm module, run as machine code) and installs the language data
133
+ * the installed packages declare. The first install in a process wins.
134
+ */
135
+ declare function loadNativeKernelModule(addonPath: string, options: LoadKernelOptions): Promise<LoadedKernel>;
136
+
137
+ /**
138
+ * The host side of the language trio's server effects (`behavior/catalog`,
139
+ * `behavior/describe`, `behavior/source`, `behavior/resolve`, `behavior/dependencies`, `program/read|print|eval`): a thin
140
+ * caller that runs the installed `orb` from the project directory and parses its
141
+ * JSON. All behavior resolution, reflection, printing and validation is `orb`'s;
142
+ * nothing here re-implements it. Both execution paths (the interpreter's effect
143
+ * executor and the compiled server host) call this module.
144
+ *
145
+ * @packageDocumentation
146
+ */
147
+
148
+ /** Where the host runs `orb`: the project (workspace) root, so installed behavior packages resolve. */
149
+ interface ProgramHostOptions {
150
+ readonly cwd: string;
151
+ /** Explicit `orb` binary; defaults to {@link resolveOrbBinary}. */
152
+ readonly orbBin?: string;
153
+ }
154
+ /** `behavior/catalog`: installed behaviors under registry folders; `vectors: false` omits the vectors (`--no-vectors`). */
155
+ declare function behaviorCatalog(scope: CatalogScope, opts: ProgramHostOptions, options?: {
156
+ readonly vectors?: boolean;
157
+ }): Promise<CatalogEntry[]>;
158
+ /** {@link behaviorCatalog} for a caller that cannot await. */
159
+ declare function behaviorCatalogSync(scope: CatalogScope, opts: ProgramHostOptions): CatalogEntry[];
160
+ /** `behavior/describe`: a trait value's knobs and events; an orbital value's or a whole behavior's orbitals.
161
+ * `knobVectors: true` attaches a trait's knob vectors (`--knob-vectors`). */
162
+ declare function behaviorDescribe(value: TraitValue, opts: ProgramHostOptions, options?: {
163
+ readonly knobVectors?: boolean;
164
+ }): Promise<TraitDescription>;
165
+ declare function behaviorDescribe(value: DescribeTarget, opts: ProgramHostOptions, options?: {
166
+ readonly knobVectors?: boolean;
167
+ }): Promise<TraitDescription | BehaviorDescription>;
168
+ /** `behavior/source`: the behavior a value belongs to, as a program (`.orb` IR). */
169
+ declare function behaviorSource(value: Pick<TraitValue, 'behavior'>, opts: ProgramHostOptions): Promise<OrbitalSchema>;
170
+ /** `program/read`: `.lolo` text → a program (`.orb` IR). */
171
+ declare function programRead(text: string, opts: ProgramHostOptions): Promise<OrbitalSchema>;
172
+ /** `program/print`: a program (`.orb` IR) → `.lolo` text. */
173
+ declare function programPrint(program: OrbitalSchema, opts: ProgramHostOptions): Promise<string>;
174
+ /** Who runs a program effect: the signed-in caller, as `call-service` receives it. */
175
+ type ProgramCallContext = Pick<ServiceCallContext, 'principal' | 'role'>;
176
+ /**
177
+ * A workspace-backed specifier (`./<workspaces root>/<owner>/…`) is readable
178
+ * only by its owner; every other specifier is unaffected. Returns the refusal,
179
+ * or undefined when the caller may read it.
180
+ */
181
+ declare function workspaceAccessError(behavior: string, opts: ProgramHostOptions, context: ProgramCallContext | undefined): string | undefined;
182
+ /** Options for {@link programEval}. */
183
+ interface ProgramEvalOptions extends ProgramHostOptions {
184
+ /** Write into this workspace (opened as `context`'s caller) and snapshot it; without one, into `<cwd>/orbitals`. */
185
+ readonly workspace?: {
186
+ readonly id: string;
187
+ readonly context: ProgramCallContext;
188
+ };
189
+ /** A prior version of the program whose ids the re-evaluation keeps. */
190
+ readonly prior?: OrbitalSchema;
191
+ /** The program is a finished app (a generation concludes here): `orb validate --final`. */
192
+ readonly final?: boolean;
193
+ }
194
+ type ProgramEvalResult = {
195
+ readonly ok: true;
196
+ readonly result: EvaluatedProgram;
197
+ } | {
198
+ readonly ok: false;
199
+ readonly errors: readonly ProgramValidationIssue[];
200
+ };
201
+ /**
202
+ * `program/validate`: the same stamp-and-validate call as `program/eval`, at the same
203
+ * 0-error / 0-warning bar, in a temp directory that is removed after. Nothing is written
204
+ * to the workspace or the project.
205
+ */
206
+ declare function programValidate(program: OrbitalSchema, opts: Pick<ProgramEvalOptions, 'cwd' | 'prior' | 'final'> & ProgramHostOptions): Promise<ProgramValidationReport>;
207
+ /**
208
+ * `program/eval`: validate through {@link stampAndValidate}, and on success write the program to `orbitals/<name>.orb` in its workspace (or `cwd`)
209
+ * and return its traits as values. Failures come back as data.
210
+ */
211
+ declare function programEval(program: OrbitalSchema, opts: ProgramEvalOptions): Promise<ProgramEvalResult>;
212
+ /** Options for {@link programCompose}. */
213
+ interface ProgramComposeOptions {
214
+ readonly appName: string;
215
+ readonly layout?: LayoutStrategy;
216
+ /** The app's theme (a built-in theme name), set on the composed program. */
217
+ readonly theme?: string;
218
+ }
219
+ /**
220
+ * `program/compose`: assemble programs, in the order given, into one app
221
+ * program — core `composeAppFromFiles` (pages, layout, wiring, the app nav).
222
+ * The composer's registry lookups (an import's source orbital, an atom's trait,
223
+ * an organism's orbital order) are served from `orb behaviors source` for every
224
+ * behavior the programs import, loaded once up front.
225
+ */
226
+ declare function programCompose(programs: readonly OrbitalSchema[], options: ProgramComposeOptions, opts: ProgramHostOptions): Promise<OrbitalSchema>;
227
+ /**
228
+ * Turn a trait value into a program a host can run: a one-orbital wrapper that
229
+ * imports the value's owning orbital with `only { T }` and the value's overrides
230
+ * as `traits { T { … } }` (LOLO §8b), validated at the 0/0 bar (the binding's
231
+ * admission check) and resolved by `orb`. A project-relative behavior
232
+ * (`./orbitals/X`) is imported relatively from a wrapper written at `cwd`, since
233
+ * `orb`'s loader refuses an absolute import.
234
+ */
235
+ declare function mountTraitValue(value: TraitValue, opts: ProgramHostOptions, context?: ProgramCallContext): Promise<TraitValueMountResult>;
236
+ /**
237
+ * Make a behavior value runnable: the program as written is validated at the
238
+ * 0/0 bar (the embed's admission check) and resolved by `orb`; the frame opens
239
+ * it on its default page (the one marked `initial`, else the first).
240
+ */
241
+ declare function mountBehaviorValue(value: BehaviorRef, opts: ProgramHostOptions, context?: ProgramCallContext): Promise<BehaviorValueMountResult>;
242
+ /** A program file resolved by `orb` (every import flattened, every composed trait inlined): what a host registers. */
243
+ declare function programResolve(path: string, opts: ProgramHostOptions): Promise<OrbitalSchema>;
244
+ /** An unresolved program resolved by `orb` from the project root `opts.cwd`, so its relative imports resolve there. */
245
+ declare function programResolveSchema(program: OrbitalSchema, opts: ProgramHostOptions): Promise<OrbitalSchema>;
246
+ /** `behavior/resolve`: the behavior a value belongs to, resolved by `orb` — every import and composed trait inlined, as the runtime runs it. */
247
+ declare function behaviorResolve(value: Pick<TraitValue, 'behavior'>, opts: ProgramHostOptions): Promise<OrbitalSchema | {
248
+ error: string;
249
+ }>;
250
+ /** `behavior/dependencies`: a program's dependency graph — each orbital's imports, then every installed behavior they reach, with its layer and its own imports. */
251
+ declare function behaviorDependencies(program: OrbitalSchema, opts: ProgramHostOptions): Promise<DependencyGraph>;
252
+ declare function programStep(program: OrbitalSchema, requests: readonly StepRequest[], opts: ProgramHostOptions, live?: boolean): Promise<PlayedStep[] | {
253
+ error: string;
254
+ }>;
255
+ type EffectArg = JsonValue;
256
+ /**
257
+ * Parse one program effect's positional arguments (the trailing emit config
258
+ * already removed) and run it. Both execution paths call this — the
259
+ * interpreter's effect executor and the compiled server handlers — so argument
260
+ * validation has one owner. Failures come back as data, never thrown.
261
+ */
262
+ declare function runProgramEffect(op: ProgramEffectName, args: readonly EffectArg[], opts: ProgramHostOptions, context?: ProgramCallContext): Promise<ProgramEffectOutcome>;
263
+
264
+ export { KvFailure, behaviorCatalog, behaviorCatalogSync, behaviorDependencies, behaviorDescribe, behaviorResolve, behaviorSource, createKvHost, createNodeOsHost, directoryKvBackend, initKernelSync, installNodeHostPorts, loadHttpKernel, loadInstalledKernel, loadKernelModule, loadNativeKernelModule, loadOrCreateDevMasterKey, memoryKvBackend, mountBehaviorValue, mountTraitValue, namespaceId, nativeMemoryOf, nodeCredentialScope, nodeNetPort, pinnedFetchNode, processAnchors, programCompose, programEval, programPrint, programRead, programResolve, programResolveSchema, programStep, programValidate, resolveHostNode, resolveNativeAddon, runProgramEffect, workspaceAccessError };
265
+ export type { KvBackend, KvBatchOp, KvErrorKind, KvHost, KvNamespace, KvResult, KvScanEntry, KvTable, LoadKernelOptions, LoadedKernel, NodeOsHostOptions, ProgramCallContext, ProgramComposeOptions, ProgramEvalOptions, ProgramEvalResult, ProgramHostOptions };
package/dist/index.js ADDED
@@ -0,0 +1,217 @@
1
+ export { OrbitalServerRuntime, UnresolvedProgramError, createOrbitalServerRuntime } from './chunk-A2TIXOLJ.js';
2
+ export { createProgramHandlers } from './chunk-WZFQ7T7V.js';
3
+ export { GCS_ENDPOINT, KernelProgram, WORKSPACE_HMAC_KEY_ID, WORKSPACE_HMAC_SECRET, createNodeOsHost, emitPayload, kernelWorkspaceHost, processAnchors, resolveKernelDir, resolveProgramFile, workspaceBucketFromEnv, workspacesRoot } from './chunk-BJA6GYC5.js';
4
+ export { installNodeHostPorts, nodeCredentialScope, nodeNetPort, pinnedFetchNode, resolveHostNode } from './chunk-23YAOI6P.js';
5
+ export { initKernelSync, loadHttpKernel, loadInstalledKernel, loadKernelModule, loadNativeKernelModule, nativeMemoryOf, resolveNativeAddon } from './chunk-UBZT5LDW.js';
6
+ export { behaviorCatalog, behaviorCatalogSync, behaviorDependencies, behaviorDescribe, behaviorResolve, behaviorSource, mountBehaviorValue, mountTraitValue, programCompose, programEval, programPrint, programRead, programResolve, programResolveSchema, programStep, programValidate, runProgramEffect, workspaceAccessError } from './chunk-QYAPNUBH.js';
7
+ export { installWorkspaceHost, installedWorkspaceHost, uninstallWorkspaceHost, workspaceOwnerSegment } from './chunk-BWMLDDCL.js';
8
+ import { randomBytes } from 'crypto';
9
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
10
+ import { join } from 'path';
11
+ import { mkdir, open, rename, rm, readFile } from 'fs/promises';
12
+
13
+ var KEY_FILE = "dev-credential-master-key";
14
+ var HEX_KEY = /^[0-9a-f]{64}$/;
15
+ function loadOrCreateDevMasterKey(dir) {
16
+ if (process.env.NODE_ENV === "production") {
17
+ throw new Error("A generated dev master key is not permitted when NODE_ENV=production \u2014 set ALMADAR_CREDENTIAL_MASTER_KEY");
18
+ }
19
+ const path = join(dir, KEY_FILE);
20
+ if (existsSync(path)) {
21
+ const key2 = readFileSync(path, "utf8").trim();
22
+ if (!HEX_KEY.test(key2)) throw new Error(`${path} is malformed (expected 64 hex characters)`);
23
+ return key2;
24
+ }
25
+ mkdirSync(dir, { recursive: true });
26
+ const key = randomBytes(32).toString("hex");
27
+ writeFileSync(path, `${key}
28
+ `, { mode: 384, flag: "wx" });
29
+ return key;
30
+ }
31
+ var KvFailure = class extends Error {
32
+ constructor(kind, message) {
33
+ super(message);
34
+ this.kind = kind;
35
+ }
36
+ kind;
37
+ };
38
+ var LONE_SURROGATE = /[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
39
+ var SEGMENT = /^[A-Za-z0-9._-]+$/;
40
+ function namespaceId(ns) {
41
+ return `kv:${ns.app}:${ns.locale}:${ns.store}`;
42
+ }
43
+ function checkNamespace(ns) {
44
+ for (const [what, seg] of [["app", ns.app], ["locale", ns.locale], ["store", ns.store]]) {
45
+ if (!SEGMENT.test(seg) || seg === "." || seg === "..") throw new KvFailure("invalid", `kv ${what} name ${JSON.stringify(seg)} is not [A-Za-z0-9._-]+`);
46
+ }
47
+ }
48
+ function checkString(what, s) {
49
+ if (typeof s !== "string") throw new KvFailure("invalid", `kv ${what} must be a string`);
50
+ if (LONE_SURROGATE.test(s)) throw new KvFailure("invalid", `kv ${what} is not valid UTF-8`);
51
+ return s;
52
+ }
53
+ function checkJson(value, path) {
54
+ if (value === null || typeof value === "string" || typeof value === "boolean") return value;
55
+ if (typeof value === "number") {
56
+ if (!Number.isFinite(value)) throw new KvFailure("invalid", `kv value at ${path} is not a finite number`);
57
+ return value;
58
+ }
59
+ if (Array.isArray(value)) return value.map((item, i) => checkJson(item, `${path}[${i}]`));
60
+ if (typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
61
+ const out = {};
62
+ for (const [k, v] of Object.entries(value)) Object.defineProperty(out, k, { value: checkJson(v, `${path}.${k}`), enumerable: true, writable: true, configurable: true });
63
+ return out;
64
+ }
65
+ throw new KvFailure("invalid", `kv value at ${path} is not JSON`);
66
+ }
67
+ function byteCompare(a, b) {
68
+ return Buffer.compare(Buffer.from(a, "utf8"), Buffer.from(b, "utf8"));
69
+ }
70
+ function serialize(table) {
71
+ const keys = [...table.keys()].sort(byteCompare);
72
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(table.get(k))}`).join(",")}}`;
73
+ }
74
+ function parseTable(text) {
75
+ const parsed = JSON.parse(text);
76
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new KvFailure("io", "kv store file is not a JSON object");
77
+ const table = /* @__PURE__ */ new Map();
78
+ for (const [k, v] of Object.entries(parsed)) table.set(k, checkJson(v, k));
79
+ return table;
80
+ }
81
+ function memoryKvBackend() {
82
+ const tables = /* @__PURE__ */ new Map();
83
+ return {
84
+ async load(ns) {
85
+ return new Map(tables.get(namespaceId(ns)) ?? []);
86
+ },
87
+ async commit(ns, table) {
88
+ tables.set(namespaceId(ns), new Map(table));
89
+ }
90
+ };
91
+ }
92
+ function isErrno(e, code) {
93
+ return typeof e === "object" && e !== null && "code" in e && e.code === code;
94
+ }
95
+ function directoryKvBackend(stateDir) {
96
+ const fileOf = (ns) => {
97
+ const dir = join(stateDir, "kv", ns.app, ns.locale);
98
+ return { dir, file: join(dir, `${ns.store}.json`) };
99
+ };
100
+ return {
101
+ async load(ns) {
102
+ const { file } = fileOf(ns);
103
+ let text;
104
+ try {
105
+ text = await readFile(file, "utf8");
106
+ } catch (e) {
107
+ if (isErrno(e, "ENOENT")) return /* @__PURE__ */ new Map();
108
+ throw new KvFailure("io", `kv read failed: ${e instanceof Error ? e.message : String(e)}`);
109
+ }
110
+ try {
111
+ return parseTable(text);
112
+ } catch (e) {
113
+ if (e instanceof KvFailure) throw e;
114
+ throw new KvFailure("io", `kv store file is corrupt: ${e instanceof Error ? e.message : String(e)}`);
115
+ }
116
+ },
117
+ async commit(ns, table) {
118
+ const { dir, file } = fileOf(ns);
119
+ const tmp = `${file}.tmp-${randomBytes(6).toString("hex")}`;
120
+ try {
121
+ await mkdir(dir, { recursive: true });
122
+ const handle = await open(tmp, "w");
123
+ try {
124
+ await handle.writeFile(serialize(table), "utf8");
125
+ await handle.sync();
126
+ } finally {
127
+ await handle.close();
128
+ }
129
+ await rename(tmp, file);
130
+ } catch (e) {
131
+ await rm(tmp, { force: true }).catch(() => void 0);
132
+ throw new KvFailure("io", `kv write failed: ${e instanceof Error ? e.message : String(e)}`);
133
+ }
134
+ }
135
+ };
136
+ }
137
+ function createKvHost(backend) {
138
+ const tails = /* @__PURE__ */ new Map();
139
+ const serialized = (ns, run) => {
140
+ const id = namespaceId(ns);
141
+ const next = (tails.get(id) ?? Promise.resolve()).then(run, run);
142
+ tails.set(id, next.catch(() => void 0));
143
+ return next;
144
+ };
145
+ const guard = async (run) => {
146
+ try {
147
+ return { ok: true, value: await run() };
148
+ } catch (e) {
149
+ if (e instanceof KvFailure) return { ok: false, error: e.message, kind: e.kind };
150
+ return { ok: false, error: e instanceof Error ? e.message : String(e), kind: "io" };
151
+ }
152
+ };
153
+ return {
154
+ get: (ns, key) => guard(async () => {
155
+ checkNamespace(ns);
156
+ checkString("key", key);
157
+ const table = await backend.load(ns);
158
+ const value = table.get(key);
159
+ return value === void 0 ? { found: false } : { found: true, value };
160
+ }),
161
+ put: (ns, key, value) => guard(() => {
162
+ checkNamespace(ns);
163
+ checkString("key", key);
164
+ const checked = checkJson(value, "value");
165
+ return serialized(ns, async () => {
166
+ const table = await backend.load(ns);
167
+ table.set(key, checked);
168
+ await backend.commit(ns, table);
169
+ return { storedKey: key };
170
+ });
171
+ }),
172
+ delete: (ns, key) => guard(() => {
173
+ checkNamespace(ns);
174
+ checkString("key", key);
175
+ return serialized(ns, async () => {
176
+ const table = await backend.load(ns);
177
+ const existed = table.delete(key);
178
+ if (existed) await backend.commit(ns, table);
179
+ return { existed };
180
+ });
181
+ }),
182
+ scan: (ns, prefix, limit) => guard(async () => {
183
+ checkNamespace(ns);
184
+ checkString("prefix", prefix);
185
+ if (limit !== void 0 && (!Number.isInteger(limit) || limit < 0)) throw new KvFailure("invalid", "kv scan limit must be a non-negative integer");
186
+ const table = await backend.load(ns);
187
+ const wanted = Buffer.from(prefix, "utf8");
188
+ const hits = [...table.keys()].filter((k) => Buffer.from(k, "utf8").subarray(0, wanted.length).equals(wanted)).sort(byteCompare);
189
+ const entries = [];
190
+ for (const key of limit === void 0 ? hits : hits.slice(0, limit)) {
191
+ const value = table.get(key);
192
+ if (value !== void 0) entries.push({ key, value });
193
+ }
194
+ return { entries };
195
+ }),
196
+ batch: (ns, ops) => guard(() => {
197
+ checkNamespace(ns);
198
+ const checked = ops.map((op, i) => {
199
+ const key = checkString(`batch op ${i} key`, op.key);
200
+ if (op.kind === "put") return { kind: "put", key, value: checkJson(op.value, `ops[${i}].value`) };
201
+ if (op.kind === "delete") return { kind: "delete", key };
202
+ throw new KvFailure("invalid", `kv batch op ${i} has unknown kind`);
203
+ });
204
+ return serialized(ns, async () => {
205
+ const table = await backend.load(ns);
206
+ for (const op of checked) {
207
+ if (op.kind === "put") table.set(op.key, op.value);
208
+ else table.delete(op.key);
209
+ }
210
+ await backend.commit(ns, table);
211
+ return { applied: checked.length };
212
+ });
213
+ })
214
+ };
215
+ }
216
+
217
+ export { KvFailure, createKvHost, directoryKvBackend, loadOrCreateDevMasterKey, memoryKvBackend, namespaceId };
@@ -0,0 +1 @@
1
+ export { initKernelSync, loadHttpKernel, loadInstalledKernel, loadKernelModule, loadNativeKernelModule, nativeMemoryOf, resolveNativeAddon } from './chunk-UBZT5LDW.js';