@lapxo/bound 0.2.4 → 0.2.6
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/CITATION.cff +1 -1
- package/README.md +20 -3
- package/TARGET.bound +85 -47
- package/dist/cli/accept.js +61 -590
- package/dist/cli/act-result.js +3 -103
- package/dist/cli/args.js +3 -44
- package/dist/cli/custodian.js +2 -29
- package/dist/cli/host.js +4 -32
- package/dist/cli/names.js +1 -12
- package/dist/cli/native-descendant.js +1 -19
- package/dist/cli/native.js +3 -60
- package/dist/cli/observe.js +1 -13
- package/dist/cli/owner.js +3 -139
- package/dist/cli/pass.js +22 -321
- package/dist/cli/place.js +6 -282
- package/dist/cli/release-result.js +3 -80
- package/dist/cli/retained-judgment.js +1 -25
- package/dist/cli/standing-result.js +4 -19
- package/dist/cli/takes.js +10 -112
- package/dist/cli/verb.d.ts +1 -2
- package/dist/cli/verb.js +85 -684
- package/dist/engine/computation.js +2 -0
- package/dist/engine/conformance.js +4 -0
- package/dist/engine/encoding.js +1 -2
- package/dist/engine/index.d.ts +1 -13
- package/dist/engine/index.js +2 -11
- package/dist/engine/object.js +1 -38
- package/dist/engine/ports.js +2 -117
- package/dist/fold/admission-history.js +1 -17
- package/dist/fold/bootstrap-anchor.js +1 -28
- package/dist/fold/ceilings.js +1 -142
- package/dist/fold/claims.js +2 -132
- package/dist/fold/closed.js +24 -235
- package/dist/fold/configures.js +1 -25
- package/dist/fold/digests.js +10 -226
- package/dist/fold/evidence.js +1 -22
- package/dist/fold/fold-worker.js +1 -13
- package/dist/fold/kept.js +12 -173
- package/dist/fold/keys.js +3 -91
- package/dist/fold/laid.js +3 -90
- package/dist/fold/nos.js +1 -48
- package/dist/fold/object.js +1 -2
- package/dist/fold/observed.js +28 -534
- package/dist/fold/opened.js +1 -33
- package/dist/fold/own.js +3 -217
- package/dist/fold/paid.js +1 -92
- package/dist/fold/place-inputs.js +1 -70
- package/dist/fold/places.js +3 -100
- package/dist/fold/rank.js +1 -9
- package/dist/fold/reach.js +1 -83
- package/dist/fold/readers.js +6 -142
- package/dist/fold/receipts.js +1 -47
- package/dist/fold/region-declarations.js +1 -13
- package/dist/fold/region.js +8 -286
- package/dist/fold/release-policy.js +1 -101
- package/dist/fold/resolved.js +6 -145
- package/dist/fold/roles.js +2 -59
- package/dist/fold/second.js +4 -71
- package/dist/fold/shards.js +12 -100
- package/dist/fold/signed.js +3 -81
- package/dist/fold/signers.js +1 -54
- package/dist/fold/stranger.js +6 -24
- package/dist/fold/views.js +1 -66
- package/dist/fold/wire.js +1 -46
- package/dist/fold/zoom.js +3 -81
- package/dist/host/act-cost.js +1 -25
- package/dist/host/adapters/keys/ed25519.js +1 -30
- package/dist/host/adapters/modules/javascript.js +1 -50
- package/dist/host/adapters/transport/http.js +1 -28
- package/dist/host/admitted-place.js +1 -35
- package/dist/host/archive.js +1 -152
- package/dist/host/call-context.js +1 -14
- package/dist/host/capsule-process.js +2 -62
- package/dist/host/capsule.js +9 -171
- package/dist/host/cell-receipts.js +12 -128
- package/dist/host/command-server.js +4 -0
- package/dist/host/commit-result.js +1 -5
- package/dist/host/content-needed.js +1 -8
- package/dist/host/content-store.js +1 -31
- package/dist/host/contextual-place.js +2 -72
- package/dist/host/digest.js +2 -15
- package/dist/host/hash.js +1 -9
- package/dist/host/host-controls.js +1 -19
- package/dist/host/in-process-act.js +3 -84
- package/dist/host/in-process-context.js +3 -91
- package/dist/host/in-process-root.js +6 -84
- package/dist/host/in-process.js +4 -55
- package/dist/host/index.d.ts +1 -15
- package/dist/host/index.js +1 -7
- package/dist/host/io.js +1 -11
- package/dist/host/lifetime.js +1 -79
- package/dist/host/located.js +6 -105
- package/dist/host/native/authority-card-view.js +5 -0
- package/dist/host/native/authority-card.js +1 -0
- package/dist/host/native/bounded-file.js +1 -32
- package/dist/host/native/command.js +1 -91
- package/dist/host/native/control-bridge-worker.js +2 -88
- package/dist/host/native/control-bridge.js +1 -110
- package/dist/host/native/control-selection.js +1 -32
- package/dist/host/native/custody.js +1 -91
- package/dist/host/native/deadline.js +1 -28
- package/dist/host/native/descendants.js +1 -528
- package/dist/host/native/generated-custodian.js +5 -267
- package/dist/host/native/generated.js +1 -379
- package/dist/host/native/image.js +1 -45
- package/dist/host/native/installed-package.d.ts +1 -0
- package/dist/host/native/installed-package.js +5 -0
- package/dist/host/native/jobs.js +2 -148
- package/dist/host/native/loader.js +1 -269
- package/dist/host/native/materialize.js +1 -175
- package/dist/host/native/module-closure.js +1 -130
- package/dist/host/native/module-delivery.d.ts +1 -62
- package/dist/host/native/module-delivery.js +1 -151
- package/dist/host/native/module-inventory.js +2 -0
- package/dist/host/native/module-syntax.js +1 -69
- package/dist/host/native/native-binary.js +1 -115
- package/dist/host/native/native-program.js +1 -72
- package/dist/host/native/node-jobs.js +3 -187
- package/dist/host/native/node-launch.js +1 -159
- package/dist/host/native/preload.js +1 -45
- package/dist/host/native/probes.js +1 -0
- package/dist/host/native/reading-witness-admission.js +5 -0
- package/dist/host/native/reading.js +1 -249
- package/dist/host/native/receipt-environment.js +1 -41
- package/dist/host/native/references.js +1 -30
- package/dist/host/native/root.js +1 -37
- package/dist/host/native/route.js +1 -216
- package/dist/host/native/runtime.js +1 -9
- package/dist/host/native-place-state.js +1 -0
- package/dist/host/native-reader-context.js +1 -8
- package/dist/host/native-receiver.js +1 -25
- package/dist/host/objects.js +1 -38
- package/dist/host/order.js +1 -2
- package/dist/host/persistent-host.js +1 -0
- package/dist/host/physical-lines.d.ts +1 -0
- package/dist/host/physical-lines.js +1 -0
- package/dist/host/place-act-transaction.js +4 -78
- package/dist/host/place-clock-selection.js +5 -124
- package/dist/host/ports/ingress.js +2 -57
- package/dist/host/ports/local-act.js +5 -183
- package/dist/host/ports/place-act.js +1 -134
- package/dist/host/ports/publication.js +1 -56
- package/dist/host/ports/signing.js +1 -74
- package/dist/host/ports/store.js +1 -18
- package/dist/host/ports/transport.js +1 -48
- package/dist/host/process-lifetime.js +1 -17
- package/dist/host/profile-composition.d.ts +1 -0
- package/dist/host/profile-composition.js +2 -0
- package/dist/host/provide.js +1 -183
- package/dist/host/read-only.js +1 -9
- package/dist/host/reading-closures.js +7 -227
- package/dist/host/reading-context.js +1 -53
- package/dist/host/reading-identity-types.js +0 -0
- package/dist/host/reading-identity.js +3 -0
- package/dist/host/reading-preparation.js +6 -0
- package/dist/host/reference-authenticated.d.ts +1 -40
- package/dist/host/reference-authenticated.js +3 -100
- package/dist/host/reference-contracts.js +1 -6
- package/dist/host/reference-export.js +6 -81
- package/dist/host/reference-native-api.d.ts +1 -3
- package/dist/host/reference-native-api.js +1 -3
- package/dist/host/reference-native.js +1 -74
- package/dist/host/reference-profile.js +1 -63
- package/dist/host/reference-standing.js +2 -18
- package/dist/host/reference.js +1 -24
- package/dist/host/refusals.js +2 -43
- package/dist/host/release.js +4 -256
- package/dist/host/root-clock-source.js +1 -307
- package/dist/host/selected-capsules.js +1 -50
- package/dist/host/selected-topos.js +1 -80
- package/dist/host/signature-era.js +1 -12
- package/dist/host/signing.js +2 -48
- package/dist/host/source-content.js +2 -111
- package/dist/host/standing-carrier.js +1 -18
- package/dist/host/standing-projection.js +1 -50
- package/dist/host/timing.js +1 -7
- package/dist/host/walk.js +20 -193
- package/dist/host/work-trace.js +1 -0
- package/dist/judge/late.js +1 -33
- package/dist/judge/take.js +2 -75
- package/dist/judge/widening.js +1 -25
- package/dist/land/act.js +8 -336
- package/dist/land/alias.js +1 -41
- package/dist/land/held.js +1 -23
- package/dist/land/inert.js +1 -33
- package/dist/land/leaving.js +1 -55
- package/dist/land/ledger.js +6 -188
- package/dist/land/owned.js +4 -66
- package/dist/land/sign.js +1 -53
- package/dist/land/standing-pin.js +1 -49
- package/dist/land/vouched.js +1 -112
- package/dist/land/withdraw.js +1 -24
- package/dist/observe/files.js +1 -88
- package/dist/observe/identity.js +1 -61
- package/dist/observe/match.js +1 -8
- package/dist/observe/regions.js +7 -306
- package/dist/observe/run.js +1 -41
- package/dist/observe/runner.js +4 -101
- package/dist/public-types.d.ts +2019 -0
- package/dist/render/capsule.js +1 -30
- package/dist/render/field.js +1 -40
- package/dist/render/names.js +1 -4
- package/dist/render/open.js +1 -61
- package/dist/render/page.js +1 -7
- package/dist/render/receipt-projection.js +1 -0
- package/dist/render/receipts.js +1 -47
- package/dist/render/shape.js +1 -74
- package/dist/render/target.js +4 -52
- package/dist/render/view.js +7 -197
- package/dist/vendor/bundle.json +1 -0
- package/dist/vendor/library14.js +1 -0
- package/dist/vendor/object-provider.js +42 -0
- package/dist/vendor/runtime.js +61 -0
- package/dist/wasm/adapter.d.ts +1 -51
- package/dist/wasm/adapter.js +1 -180
- package/dist/wasm/node-worker.js +1 -13
- package/dist/wasm/object.js +1 -76
- package/dist/wasm/worker.js +1 -7
- package/docs/contracts/authenticated-reference.publication.json +1 -1
- package/docs/contracts/authority-preflight.md +17 -0
- package/docs/contracts/authority-preflight.publication.json +25 -0
- package/docs/contracts/closure-delivery.md +1 -1
- package/docs/contracts/closure-delivery.publication.json +1 -1
- package/docs/contracts/conformance.json +142 -0
- package/docs/contracts/determinism.bound +9 -0
- package/docs/contracts/engine-object-projection.publication.json +1 -1
- package/docs/contracts/engine.md +21 -1
- package/docs/contracts/installed-package.md +21 -0
- package/docs/contracts/installed-package.publication.json +25 -0
- package/docs/contracts/materialized-leaf-sequence.md +15 -0
- package/docs/contracts/materialized-leaf-sequence.publication.json +25 -0
- package/docs/contracts/module-inventory.md +15 -0
- package/docs/contracts/module-inventory.publication.json +25 -0
- package/docs/contracts/native-host.md +29 -1
- package/docs/contracts/native-host.publication.json +4 -4
- package/docs/contracts/native-probes.md +13 -0
- package/docs/contracts/native-probes.publication.json +25 -0
- package/docs/contracts/native-publication.inventory.json +10 -1
- package/docs/contracts/native-view-batch.md +17 -0
- package/docs/contracts/native-view-batch.publication.json +25 -0
- package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
- package/docs/contracts/physical-lines.md +19 -0
- package/docs/contracts/physical-lines.publication.json +25 -0
- package/docs/contracts/profile-composition.md +17 -0
- package/docs/contracts/profile-composition.publication.json +25 -0
- package/docs/contracts/profile-preparation-native-meaning.md +9 -0
- package/docs/contracts/publication.md +12 -0
- package/docs/contracts/reading-identity.md +61 -0
- package/docs/contracts/reading-identity.publication.json +25 -0
- package/docs/contracts/reading-witness-admission.md +49 -0
- package/docs/contracts/readme.publication.json +1 -1
- package/docs/contracts/reference-port.md +11 -0
- package/docs/contracts/reference-port.publication.json +1 -1
- package/docs/contracts/refusals.bound +346 -94
- package/docs/contracts/refusals.md +119 -39
- package/docs/contracts/refusals.publication.json +2 -2
- package/docs/contracts/views.md +8 -0
- package/docs/reference.md +9 -0
- package/licenses/wasm/{fast-text-encoding.txt → NOTICE.txt} +111 -0
- package/package.json +84 -34
- package/receipts.bound +12952 -10449
- package/samples/authority-preflight/no.json +6 -0
- package/samples/authority-preflight/yes.json +30 -0
- package/samples/engine-alphabet/reader.js +3 -1457
- package/samples/engine-alphabet/receipts.bound +7 -7
- package/samples/engine-interval/reader.js +3 -1457
- package/samples/engine-interval/receipts.bound +7 -7
- package/samples/installed-package/consumer.mjs +29 -0
- package/samples/installed-package/fixture.json +48 -0
- package/samples/installed-package/no.json +10 -0
- package/samples/installed-package/yes.json +52 -0
- package/samples/materialized-leaf-sequence/no.json +11 -0
- package/samples/materialized-leaf-sequence/yes.json +10 -0
- package/samples/module-inventory/yes.json +28 -0
- package/samples/native/physical-line-reader.mjs +1 -0
- package/samples/native/physical-line-reader.source.mjs +13 -0
- package/samples/native-host/no.json +6 -1
- package/samples/native-host/yes.json +18 -1
- package/samples/native-probes/inputs/inspection.json +28 -0
- package/samples/native-probes/no.json +7 -0
- package/samples/native-probes/yes.json +28 -0
- package/samples/native-view-batch/no.json +14 -0
- package/samples/native-view-batch/yes.json +10 -0
- package/samples/no/engine-order/reader.js +3 -1457
- package/samples/no/module-inventory/no.json +10 -0
- package/samples/physical-lines/no.json +5 -0
- package/samples/physical-lines/yes.json +9 -0
- package/samples/profile-composition/no.json +6 -0
- package/samples/profile-composition/yes.json +14 -0
- package/samples/reading-identity/no.json +26 -0
- package/samples/reading-identity/yes.json +69 -0
- package/vectors/native/authority-preflight.vector.json +55 -0
- package/vectors/native/installed-package.vector.json +31 -0
- package/vectors/native/materialized-leaf-sequence.vector.json +31 -0
- package/vectors/native/module-inventory.vector.json +56 -0
- package/vectors/native/native-host.vector.json +214 -0
- package/vectors/native/native-probes.vector.json +31 -0
- package/vectors/native/native-view-batch.vector.json +31 -0
- package/vectors/native/physical-lines.vector.json +105 -0
- package/vectors/native/profile-composition.vector.json +53 -0
- package/vectors/native/reading-identity.vector.json +139 -0
- package/vectors/native/refusals.vector.json +138 -0
- package/vendor/syntax/LICENSE.md +7 -0
- package/vendor/syntax/parser.js +1 -0
- package/.github/workflows/release.yml +0 -67
- package/.github/workflows/test.yml +0 -35
- package/dist/engine/object.d.ts +0 -17
- package/dist/engine/ports.d.ts +0 -37
- package/dist/fold/claims.d.ts +0 -29
- package/dist/host/call-context.d.ts +0 -20
- package/dist/host/commit-result.d.ts +0 -6
- package/dist/host/in-process-act.d.ts +0 -82
- package/dist/host/in-process-context.d.ts +0 -46
- package/dist/host/in-process-root.d.ts +0 -117
- package/dist/host/in-process.d.ts +0 -41
- package/dist/host/native/module-closure.d.ts +0 -35
- package/dist/host/native-receiver.d.ts +0 -19
- package/dist/host/place-act-transaction.d.ts +0 -24
- package/dist/host/place-clock-selection.d.ts +0 -55
- package/dist/host/ports/local-act.d.ts +0 -44
- package/dist/host/ports/place-act.d.ts +0 -49
- package/dist/host/ports/publication.d.ts +0 -10
- package/dist/host/reference-export.d.ts +0 -33
- package/dist/host/reference-native.d.ts +0 -30
- package/dist/host/reference-profile.d.ts +0 -23
- package/dist/host/refusals.d.ts +0 -14
- package/dist/host/root-clock-source.d.ts +0 -86
- package/licenses/wasm/jitl-quickjs-ffi-types.txt +0 -21
- package/licenses/wasm/jitl-quickjs-wasmfile-release-sync.txt +0 -47
- package/licenses/wasm/quickjs-emscripten-core.txt +0 -21
- package/licenses/wasm/topos.txt +0 -21
- /package/{licenses/wasm/bound.txt → dist/vendor/28cba430228db1c04f446c93f81b09a2705d6bf3e222d35adbe5a4cee4061884.LICENSE} +0 -0
- /package/{licenses/wasm/obligations.txt → dist/vendor/7aca161279d14bc0e054dcc281cd110aeb95be2e026b42fdf527a260e58b2aae.LICENSE} +0 -0
package/dist/wasm/adapter.d.ts
CHANGED
|
@@ -1,51 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
readonly memoryBytes: number;
|
|
3
|
-
readonly stackBytes: number;
|
|
4
|
-
readonly executionMs: number;
|
|
5
|
-
}
|
|
6
|
-
export interface WasmTrust {
|
|
7
|
-
readonly runtime: string;
|
|
8
|
-
readonly wasm: string;
|
|
9
|
-
readonly modules: Readonly<Record<string, string>>;
|
|
10
|
-
readonly entry: string;
|
|
11
|
-
readonly aliases: Readonly<Record<string, string>>;
|
|
12
|
-
readonly limits: WasmLimits;
|
|
13
|
-
readonly byteLengths: {
|
|
14
|
-
readonly runtime: number;
|
|
15
|
-
readonly wasm: number;
|
|
16
|
-
readonly modules: Readonly<Record<string, number>>;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
export interface WasmRequest {
|
|
20
|
-
readonly trusted: WasmTrust;
|
|
21
|
-
readonly assets: {
|
|
22
|
-
readonly runtime: Uint8Array | ArrayBuffer;
|
|
23
|
-
readonly wasm: Uint8Array | ArrayBuffer;
|
|
24
|
-
};
|
|
25
|
-
readonly modules: Readonly<Record<string, string>>;
|
|
26
|
-
readonly entry: string;
|
|
27
|
-
readonly aliases?: Readonly<Record<string, string>>;
|
|
28
|
-
readonly limits: WasmLimits;
|
|
29
|
-
}
|
|
30
|
-
export interface WasmResult {
|
|
31
|
-
readonly output: string;
|
|
32
|
-
readonly initializedMs: number;
|
|
33
|
-
readonly executionMs: number;
|
|
34
|
-
}
|
|
35
|
-
export interface WorkerPort {
|
|
36
|
-
postMessage(message: WasmRequest): void;
|
|
37
|
-
terminate(): unknown;
|
|
38
|
-
addEventListener?(type: string, listener: (event: {
|
|
39
|
-
data?: unknown;
|
|
40
|
-
message?: string;
|
|
41
|
-
}) => void): void;
|
|
42
|
-
on?(type: string, listener: (value: unknown) => void): void;
|
|
43
|
-
}
|
|
44
|
-
export declare function digest(bytes: Uint8Array): Promise<string>;
|
|
45
|
-
export declare function preflight(request: WasmRequest): void;
|
|
46
|
-
export declare function runWasmRequest(request: WasmRequest): Promise<WasmResult>;
|
|
47
|
-
export declare function evaluateWasm(request: WasmRequest, { workerFactory, signal, lifetimeMs }: {
|
|
48
|
-
readonly workerFactory?: () => WorkerPort;
|
|
49
|
-
readonly signal?: AbortSignal;
|
|
50
|
-
readonly lifetimeMs: number;
|
|
51
|
-
}): Promise<WasmResult>;
|
|
1
|
+
export {public9_WasmLimits as WasmLimits,public9_WasmRequest as WasmRequest,public9_WasmResult as WasmResult,public9_WasmTrust as WasmTrust,public9_WorkerPort as WorkerPort,public9_digest as digest,public9_evaluateWasm as evaluateWasm,public9_preflight as preflight,public9_runWasmRequest as runWasmRequest} from "../public-types.js";
|
package/dist/wasm/adapter.js
CHANGED
|
@@ -1,180 +1 @@
|
|
|
1
|
-
var
|
|
2
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
|
-
const owns = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
|
|
10
|
-
const assetNames = ['runtime', 'wasm'], limitNames = ['memoryBytes', 'stackBytes', 'executionMs'];
|
|
11
|
-
// Host adapter only. Source integrity grants neither admission nor authority.
|
|
12
|
-
function refuse(cause) { throw Error('REFUSE·wasm ' + cause); }
|
|
13
|
-
export async function digest(bytes) { return 'sha256:' + Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256', bytes.slice().buffer))).map(x => x.toString(16).padStart(2, '0')).join(''); }
|
|
14
|
-
async function verified(bytes, expected) { if (typeof SharedArrayBuffer !== 'undefined' && (bytes instanceof SharedArrayBuffer || (ArrayBuffer.isView(bytes) && bytes.buffer instanceof SharedArrayBuffer)))
|
|
15
|
-
refuse('shared assets unsupported'); const copy = (bytes instanceof Uint8Array ? new Uint8Array(bytes) : new Uint8Array(bytes)).slice(); if (!/^sha256:[a-f0-9]{64}$/.test(expected) || await digest(copy) !== expected)
|
|
16
|
-
refuse('integrity'); return copy; }
|
|
17
|
-
const text = new TextEncoder();
|
|
18
|
-
// Exact host-declared sizes bound copies, hashing and worker handoff before work.
|
|
19
|
-
export function preflight(request) {
|
|
20
|
-
if (!request || Object.keys(request).some(k => !['trusted', 'assets', 'modules', 'aliases', 'entry', 'limits'].includes(k)))
|
|
21
|
-
refuse('request fields');
|
|
22
|
-
const { trusted, assets, modules, entry, aliases = {}, limits } = request, sizes = trusted?.byteLengths;
|
|
23
|
-
if (!sizes || !modules || !assets)
|
|
24
|
-
refuse('declared byte sizes');
|
|
25
|
-
if (Object.keys(assets).length !== 2 || Object.keys(assets).some(k => !['runtime', 'wasm'].includes(k)))
|
|
26
|
-
refuse('asset fields');
|
|
27
|
-
if (!limits || Object.keys(limits).length !== 3 || Object.keys(limits).some(k => !['memoryBytes', 'stackBytes', 'executionMs'].includes(k)))
|
|
28
|
-
refuse('limit fields');
|
|
29
|
-
for (const name of limitNames)
|
|
30
|
-
if (!Number.isSafeInteger(limits[name]) || limits[name] <= 0 || limits[name] !== trusted.limits?.[name])
|
|
31
|
-
refuse('limit ' + name);
|
|
32
|
-
if (typeof entry !== 'string' || entry !== trusted.entry || !aliases || Object.values(aliases).some(v => typeof v !== 'string') || JSON.stringify(Object.entries(aliases).sort()) !== JSON.stringify(Object.entries(trusted.aliases ?? {}).sort()))
|
|
33
|
-
refuse('entry or aliases differ from trusted context');
|
|
34
|
-
const names = Object.keys(modules), expected = Object.keys(trusted.modules ?? {});
|
|
35
|
-
if (names.length !== expected.length || names.some(n => !owns(trusted.modules, n)))
|
|
36
|
-
refuse('module count');
|
|
37
|
-
const size = (n, want) => { if (!Number.isSafeInteger(want) || want < 0)
|
|
38
|
-
refuse('declared size ' + n); return want; };
|
|
39
|
-
for (const name of assetNames) {
|
|
40
|
-
const v = assets[name];
|
|
41
|
-
if (typeof SharedArrayBuffer !== 'undefined' && (v instanceof SharedArrayBuffer || (ArrayBuffer.isView(v) && v.buffer instanceof SharedArrayBuffer)))
|
|
42
|
-
refuse('shared assets unsupported');
|
|
43
|
-
if (!(v instanceof Uint8Array || v instanceof ArrayBuffer) || v.byteLength !== size(name, sizes[name]))
|
|
44
|
-
refuse('asset bytes ' + name);
|
|
45
|
-
}
|
|
46
|
-
for (const name of names) {
|
|
47
|
-
const source = modules[name], want = size(name, sizes.modules?.[name]);
|
|
48
|
-
if (typeof source !== 'string' || source.length > want)
|
|
49
|
-
refuse('module bytes ' + name);
|
|
50
|
-
let bytes = 0;
|
|
51
|
-
for (let i = 0; i < source.length; i++) {
|
|
52
|
-
const c = source.charCodeAt(i);
|
|
53
|
-
bytes += c < 128 ? 1 : c < 2048 ? 2 : c >= 55296 && c <= 56319 && i + 1 < source.length && source.charCodeAt(i + 1) >= 56320 && source.charCodeAt(i + 1) <= 57343 ? (i++, 4) : 3;
|
|
54
|
-
if (bytes > want)
|
|
55
|
-
refuse('module bytes ' + name);
|
|
56
|
-
}
|
|
57
|
-
if (bytes !== want)
|
|
58
|
-
refuse('module bytes ' + name);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
export async function runWasmRequest(request) {
|
|
62
|
-
preflight(request);
|
|
63
|
-
try {
|
|
64
|
-
request = structuredClone(request);
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
refuse('request is not cloneable');
|
|
68
|
-
}
|
|
69
|
-
const { trusted, assets, modules, aliases = {}, entry, limits } = request;
|
|
70
|
-
for (const name of limitNames)
|
|
71
|
-
if (!Number.isSafeInteger(limits?.[name]) || limits[name] <= 0 || limits[name] !== trusted?.limits?.[name])
|
|
72
|
-
refuse('limit ' + name);
|
|
73
|
-
if (entry !== trusted.entry || JSON.stringify(Object.entries(aliases).sort()) !== JSON.stringify(Object.entries(trusted.aliases ?? {}).sort()))
|
|
74
|
-
refuse('entry or aliases differ from trusted context');
|
|
75
|
-
const runtime = await verified(assets.runtime, trusted.runtime), wasm = await verified(assets.wasm, trusted.wasm), sources = {};
|
|
76
|
-
for (const [id, source] of Object.entries(modules)) {
|
|
77
|
-
if (!owns(trusted.modules, id))
|
|
78
|
-
refuse('undeclared module ' + id);
|
|
79
|
-
sources[id] = new TextDecoder('utf-8', { fatal: true }).decode(await verified(text.encode(source), trusted.modules[id]));
|
|
80
|
-
}
|
|
81
|
-
if (Object.keys(trusted.modules).some(id => !owns(sources, id)))
|
|
82
|
-
refuse('missing module');
|
|
83
|
-
if (!owns(sources, entry))
|
|
84
|
-
refuse('entry');
|
|
85
|
-
// The runtime is a closed esbuild ESM bundle: no imports and no second fetch.
|
|
86
|
-
const url = 'data:text/javascript;base64,' + bytesBase64(runtime), factory = await import(__rewriteRelativeImportExtension(url));
|
|
87
|
-
const started = performance.now(), quick = await factory.createQuickJS(wasm);
|
|
88
|
-
const rt = quick.newRuntime();
|
|
89
|
-
let context;
|
|
90
|
-
try {
|
|
91
|
-
context = rt.newContext();
|
|
92
|
-
const memory = rt.computeMemoryUsage();
|
|
93
|
-
let initializedMemory;
|
|
94
|
-
try {
|
|
95
|
-
initializedMemory = context.dump(memory);
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
memory.dispose();
|
|
99
|
-
}
|
|
100
|
-
const used = typeof initializedMemory === 'object' && initializedMemory !== null ? initializedMemory.memory_used_size : undefined;
|
|
101
|
-
if (typeof used !== 'number' || !Number.isSafeInteger(used) || used < 0)
|
|
102
|
-
refuse('initialized memory measurement unavailable');
|
|
103
|
-
if (used > limits.memoryBytes)
|
|
104
|
-
refuse('initialized memory ' + used + ' exceeds declared memory ' + limits.memoryBytes);
|
|
105
|
-
const initializedMs = performance.now() - started;
|
|
106
|
-
rt.setMemoryLimit(limits.memoryBytes);
|
|
107
|
-
rt.setMaxStackSize(limits.stackBytes);
|
|
108
|
-
const start = performance.now();
|
|
109
|
-
rt.setInterruptHandler(() => performance.now() - start > limits.executionMs);
|
|
110
|
-
rt.setModuleLoader(id => { if (!owns(sources, id))
|
|
111
|
-
refuse('undeclared import ' + id); return sources[id]; }, (parent, name) => { if (owns(aliases, name))
|
|
112
|
-
return aliases[name]; if (name.startsWith('.'))
|
|
113
|
-
return new URL(name, new URL(parent, 'file:///')).pathname; if (owns(sources, name))
|
|
114
|
-
return name; refuse('undeclared import ' + name); });
|
|
115
|
-
const result = context.evalCode(sources[entry], entry, { type: 'module' });
|
|
116
|
-
if (result.error) {
|
|
117
|
-
const e = context.dump(result.error);
|
|
118
|
-
result.error.dispose();
|
|
119
|
-
refuse('guest ' + JSON.stringify(e));
|
|
120
|
-
}
|
|
121
|
-
result.value.dispose();
|
|
122
|
-
const value = context.evalCode('globalThis.result');
|
|
123
|
-
if (value.error) {
|
|
124
|
-
const e = context.dump(value.error);
|
|
125
|
-
value.error.dispose();
|
|
126
|
-
refuse('result ' + JSON.stringify(e));
|
|
127
|
-
}
|
|
128
|
-
const output = context.dump(value.value);
|
|
129
|
-
value.value.dispose();
|
|
130
|
-
if (typeof output !== 'string')
|
|
131
|
-
refuse('result must be declared text');
|
|
132
|
-
return { output, initializedMs, executionMs: performance.now() - start };
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
context?.dispose();
|
|
136
|
-
rt.dispose();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
function bytesBase64(bytes) { let binary = ''; for (const b of bytes)
|
|
140
|
-
binary += String.fromCharCode(b); return btoa(binary); }
|
|
141
|
-
// A separate worker makes external abort possible while synchronous WASM executes.
|
|
142
|
-
export async function evaluateWasm(request, { workerFactory = () => new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }), signal, lifetimeMs }) {
|
|
143
|
-
if (!Number.isSafeInteger(lifetimeMs) || lifetimeMs <= 0)
|
|
144
|
-
refuse('worker lifetime');
|
|
145
|
-
if (signal?.aborted)
|
|
146
|
-
refuse('cancelled');
|
|
147
|
-
preflight(request);
|
|
148
|
-
return new Promise((resolve, reject) => { const worker = workerFactory(); let done = false; const finish = (error, value) => { if (done)
|
|
149
|
-
return; done = true; clearTimeout(timer); signal?.removeEventListener('abort', abort); worker.terminate(); error ? reject(error) : resolve(value); }; const abort = () => finish(Error('REFUSE·wasm cancelled')); const timer = setTimeout(() => finish(Error('REFUSE·wasm worker lifetime')), lifetimeMs); signal?.addEventListener('abort', abort, { once: true }); const message = (raw) => { const data = raw; if (!data || typeof data !== 'object' || typeof data.ok !== 'boolean') {
|
|
150
|
-
finish(Error('REFUSE·wasm malformed worker result'));
|
|
151
|
-
return;
|
|
152
|
-
} if (data.ok) {
|
|
153
|
-
if (!data.result || typeof data.result.output !== 'string') {
|
|
154
|
-
finish(Error('REFUSE·wasm malformed worker output'));
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
finish(null, data.result);
|
|
158
|
-
}
|
|
159
|
-
else
|
|
160
|
-
finish(Error(typeof data.error === 'string' ? data.error : 'REFUSE·wasm worker failure')); }; if (typeof worker.addEventListener === 'function') {
|
|
161
|
-
worker.addEventListener('message', e => message(e.data));
|
|
162
|
-
worker.addEventListener('error', e => finish(Error('REFUSE·wasm worker ' + e.message)));
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
if (!worker.on) {
|
|
166
|
-
finish(Error('REFUSE·wasm worker event port'));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
worker.on('message', message);
|
|
170
|
-
worker.on('error', e => finish(e instanceof Error ? e : Error(String(e))));
|
|
171
|
-
} if (signal?.aborted) {
|
|
172
|
-
abort();
|
|
173
|
-
return;
|
|
174
|
-
} try {
|
|
175
|
-
worker.postMessage(request);
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
finish(Error('REFUSE·wasm request is not cloneable'));
|
|
179
|
-
} });
|
|
180
|
-
}
|
|
1
|
+
var N=Object.defineProperty;var m=(t,s)=>N(t,"name",{value:s,configurable:!0});var z=function(t,s){return typeof t=="string"&&/^\.\.?\//.test(t)?t.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(a,y,p,l,n){return y?s?".jsx":".js":p&&(!l||!n)?a:p+l+"."+n.toLowerCase()+"js"}):t};const S=m((t,s)=>Object.prototype.hasOwnProperty.call(t,s),"owns"),C=["runtime","wasm"],U=["memoryBytes","stackBytes","executionMs"];function o(t){throw Error("REFUSE\xB7wasm "+t)}m(o,"refuse");async function F(t){return"sha256:"+Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",t.slice().buffer))).map(s=>s.toString(16).padStart(2,"0")).join("")}m(F,"digest");async function O(t,s){typeof SharedArrayBuffer<"u"&&(t instanceof SharedArrayBuffer||ArrayBuffer.isView(t)&&t.buffer instanceof SharedArrayBuffer)&&o("shared assets unsupported");const a=(t instanceof Uint8Array?new Uint8Array(t):new Uint8Array(t)).slice();return(!/^sha256:[a-f0-9]{64}$/.test(s)||await F(a)!==s)&&o("integrity"),a}m(O,"verified");const M=new TextEncoder;function R(t){(!t||Object.keys(t).some(e=>!["trusted","assets","modules","aliases","entry","limits"].includes(e)))&&o("request fields");const{trusted:s,assets:a,modules:y,entry:p,aliases:l={},limits:n}=t,g=s?.byteLengths;(!g||!y||!a)&&o("declared byte sizes"),(Object.keys(a).length!==2||Object.keys(a).some(e=>!["runtime","wasm"].includes(e)))&&o("asset fields"),(!n||Object.keys(n).length!==3||Object.keys(n).some(e=>!["memoryBytes","stackBytes","executionMs"].includes(e)))&&o("limit fields");for(const e of U)(!Number.isSafeInteger(n[e])||n[e]<=0||n[e]!==s.limits?.[e])&&o("limit "+e);(typeof p!="string"||p!==s.entry||!l||Object.values(l).some(e=>typeof e!="string")||JSON.stringify(Object.entries(l).sort())!==JSON.stringify(Object.entries(s.aliases??{}).sort()))&&o("entry or aliases differ from trusted context");const f=Object.keys(y),d=Object.keys(s.modules??{});(f.length!==d.length||f.some(e=>!S(s.modules,e)))&&o("module count");const h=m((e,r)=>((!Number.isSafeInteger(r)||r<0)&&o("declared size "+e),r),"size");for(const e of C){const r=a[e];typeof SharedArrayBuffer<"u"&&(r instanceof SharedArrayBuffer||ArrayBuffer.isView(r)&&r.buffer instanceof SharedArrayBuffer)&&o("shared assets unsupported"),(!(r instanceof Uint8Array||r instanceof ArrayBuffer)||r.byteLength!==h(e,g[e]))&&o("asset bytes "+e)}for(const e of f){const r=y[e],u=h(e,g.modules?.[e]);(typeof r!="string"||r.length>u)&&o("module bytes "+e);let w=0;for(let c=0;c<r.length;c++){const i=r.charCodeAt(c);w+=i<128?1:i<2048?2:i>=55296&&i<=56319&&c+1<r.length&&r.charCodeAt(c+1)>=56320&&r.charCodeAt(c+1)<=57343?(c++,4):3,w>u&&o("module bytes "+e)}w!==u&&o("module bytes "+e)}}m(R,"preflight");async function _(t){R(t);try{t=structuredClone(t)}catch{o("request is not cloneable")}const{trusted:s,assets:a,modules:y,aliases:p={},entry:l,limits:n}=t;for(const i of U)(!Number.isSafeInteger(n?.[i])||n[i]<=0||n[i]!==s?.limits?.[i])&&o("limit "+i);(l!==s.entry||JSON.stringify(Object.entries(p).sort())!==JSON.stringify(Object.entries(s.aliases??{}).sort()))&&o("entry or aliases differ from trusted context");const g=await O(a.runtime,s.runtime),f=await O(a.wasm,s.wasm),d={};for(const[i,k]of Object.entries(y))S(s.modules,i)||o("undeclared module "+i),d[i]=new TextDecoder("utf-8",{fatal:!0}).decode(await O(M.encode(k),s.modules[i]));Object.keys(s.modules).some(i=>!S(d,i))&&o("missing module"),S(d,l)||o("entry");const h="data:text/javascript;base64,"+I(g),e=await import(z(h)),r=performance.now(),w=(await e.createQuickJS(f)).newRuntime();let c;try{c=w.newContext();const i=w.computeMemoryUsage();let k;try{k=c.dump(i)}finally{i.dispose()}const j=typeof k=="object"&&k!==null?k.memory_used_size:void 0;(typeof j!="number"||!Number.isSafeInteger(j)||j<0)&&o("initialized memory measurement unavailable"),j>n.memoryBytes&&o("initialized memory "+j+" exceeds declared memory "+n.memoryBytes);const L=performance.now()-r;w.setMemoryLimit(n.memoryBytes),w.setMaxStackSize(n.stackBytes);const A=performance.now();w.setInterruptHandler(()=>performance.now()-A>n.executionMs),w.setModuleLoader(b=>(S(d,b)||o("undeclared import "+b),d[b]),(b,E)=>{if(S(p,E))return p[E];if(E.startsWith("."))return new URL(E,new URL(b,"file:///")).pathname;if(S(d,E))return E;o("undeclared import "+E)});const x=c.evalCode(d[l],l,{type:"module"});if(x.error){const b=c.dump(x.error);x.error.dispose(),o("guest "+JSON.stringify(b))}x.value.dispose();const v=c.evalCode("globalThis.result");if(v.error){const b=c.dump(v.error);v.error.dispose(),o("result "+JSON.stringify(b))}const B=c.dump(v.value);return v.value.dispose(),typeof B!="string"&&o("result must be declared text"),{output:B,initializedMs:L,executionMs:performance.now()-A}}finally{c?.dispose(),w.dispose()}}m(_,"runWasmRequest");function I(t){let s="";for(const a of t)s+=String.fromCharCode(a);return btoa(s)}m(I,"bytesBase64");async function T(t,{workerFactory:s=m(()=>new Worker(new URL("./worker.js",import.meta.url),{type:"module"}),"workerFactory"),signal:a,lifetimeMs:y}){return(!Number.isSafeInteger(y)||y<=0)&&o("worker lifetime"),a?.aborted&&o("cancelled"),R(t),new Promise((p,l)=>{const n=s();let g=!1;const f=m((r,u)=>{g||(g=!0,clearTimeout(h),a?.removeEventListener("abort",d),n.terminate(),r?l(r):p(u))},"finish"),d=m(()=>f(Error("REFUSE\xB7wasm cancelled")),"abort"),h=setTimeout(()=>f(Error("REFUSE\xB7wasm worker lifetime")),y);a?.addEventListener("abort",d,{once:!0});const e=m(r=>{const u=r;if(!u||typeof u!="object"||typeof u.ok!="boolean"){f(Error("REFUSE\xB7wasm malformed worker result"));return}if(u.ok){if(!u.result||typeof u.result.output!="string"){f(Error("REFUSE\xB7wasm malformed worker output"));return}f(null,u.result)}else f(Error(typeof u.error=="string"?u.error:"REFUSE\xB7wasm worker failure"))},"message");if(typeof n.addEventListener=="function")n.addEventListener("message",r=>e(r.data)),n.addEventListener("error",r=>f(Error("REFUSE\xB7wasm worker "+r.message)));else{if(!n.on){f(Error("REFUSE\xB7wasm worker event port"));return}n.on("message",e),n.on("error",r=>f(r instanceof Error?r:Error(String(r))))}if(a?.aborted){d();return}try{n.postMessage(t)}catch{f(Error("REFUSE\xB7wasm request is not cloneable"))}})}m(T,"evaluateWasm");export{F as digest,T as evaluateWasm,R as preflight,_ as runWasmRequest};
|
package/dist/wasm/node-worker.js
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { runWasmRequest } from "./adapter.js";
|
|
3
|
-
if (!parentPort)
|
|
4
|
-
throw Error('REFUSE·wasm worker port missing');
|
|
5
|
-
const port = parentPort;
|
|
6
|
-
port.once('message', async (request) => {
|
|
7
|
-
try {
|
|
8
|
-
port.postMessage({ ok: true, result: await runWasmRequest(request) });
|
|
9
|
-
}
|
|
10
|
-
catch (error) {
|
|
11
|
-
port.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
12
|
-
}
|
|
13
|
-
});
|
|
1
|
+
import{parentPort as s}from"node:worker_threads";import{runWasmRequest as t}from"./adapter.js";if(!s)throw Error("REFUSE\xB7wasm worker port missing");const o=s;o.once("message",async e=>{try{o.postMessage({ok:!0,result:await t(e)})}catch(r){o.postMessage({ok:!1,error:r instanceof Error?r.message:String(r)})}});
|
package/dist/wasm/object.js
CHANGED
|
@@ -1,76 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Worker } from 'node:worker_threads';
|
|
3
|
-
import { sha256 } from "../host/hash.js";
|
|
4
|
-
import { toposAt } from "../host/selected-topos.js";
|
|
5
|
-
import { storeOf } from "../land/ledger.js";
|
|
6
|
-
import { evaluateWasm } from "./adapter.js";
|
|
7
|
-
function refuse(cause) { throw Error('REFUSE·wasm object ' + cause); }
|
|
8
|
-
/** Configuration is the caller's already authenticated, live standing; selection grants no authority. */
|
|
9
|
-
export function usesWasmObject(configuration) {
|
|
10
|
-
const rows = configuration.filter(f => f.scope === 'engine/object' && f.value !== 'withdraw');
|
|
11
|
-
if (!rows.length)
|
|
12
|
-
return false;
|
|
13
|
-
if (rows.length !== 1 || rows[0].role !== 'writes' || rows[0].measure !== 'id' || rows[0].form !== 'alphabet' || !['esm@1', 'wasm@1'].includes(rows[0].value ?? ''))
|
|
14
|
-
refuse('unique declared backend required');
|
|
15
|
-
return rows[0].value === 'wasm@1';
|
|
16
|
-
}
|
|
17
|
-
function limit(configuration, name, measure) {
|
|
18
|
-
const rows = configuration.filter(f => f.scope === 'engine/wasm/' + name && f.value !== 'withdraw');
|
|
19
|
-
if (rows.length !== 1 || rows[0].form !== 'interval' || rows[0].measure !== measure || rows[0].role !== 'writes')
|
|
20
|
-
refuse('missing or ambiguous ' + name + ' limit');
|
|
21
|
-
const span = /^(0|[1-9][0-9]*)\.\.(0|[1-9][0-9]*)$/.exec(rows[0].value ?? '');
|
|
22
|
-
if (!span || !Number.isSafeInteger(Number(span[1])) || !Number.isSafeInteger(Number(span[2])) || Number(span[1]) > Number(span[2]) || Number(span[2]) < 1)
|
|
23
|
-
refuse('invalid ' + name + ' limit');
|
|
24
|
-
return Number(span[2]);
|
|
25
|
-
}
|
|
26
|
-
/** The installed instrument owns the asset/form closure; place input cannot choose executable bytes. */
|
|
27
|
-
export async function foldObjectsWithWasm(root, records, context, configuration, signal) {
|
|
28
|
-
if (!usesWasmObject(configuration))
|
|
29
|
-
refuse('backend not selected');
|
|
30
|
-
const limits = { memoryBytes: limit(configuration, 'memory', 'bytes'), stackBytes: limit(configuration, 'stack', 'bytes'), executionMs: limit(configuration, 'execution', 'milliseconds') }, lifetimeMs = limit(configuration, 'worker-lifetime', 'milliseconds'), responseBytes = limit(configuration, 'response', 'bytes');
|
|
31
|
-
const assets = new URL('../../assets/wasm/', import.meta.url), manifest = JSON.parse(readFileSync(new URL('manifest.json', assets), 'utf8'));
|
|
32
|
-
if (!manifest.forms)
|
|
33
|
-
refuse('installed form closure missing');
|
|
34
|
-
const codecs = {};
|
|
35
|
-
for (const record of records.filter(r => r.record === 'cell')) {
|
|
36
|
-
const pin = record.fields.topos, binding = manifest.forms[pin];
|
|
37
|
-
if (!binding || !['intervalForm', 'alphabetOfForm'].includes(binding.export) || binding.form !== record.fields.form)
|
|
38
|
-
refuse('unsupported form standing ' + pin);
|
|
39
|
-
const standing = toposAt(pin, storeOf(root)), selector = standing.parts.filter(f => f.scope === 'wire/topos/context-view');
|
|
40
|
-
if (selector.length !== 1)
|
|
41
|
-
refuse('context selection ' + pin);
|
|
42
|
-
const offers = standing.parts.filter(f => f.kind === 'check' && f.view === selector[0].value);
|
|
43
|
-
if (offers.length !== 1 || offers[0].value !== binding.contextArtifact || !(offers[0].restsOn ?? '').split('|').includes(binding.contextArtifact))
|
|
44
|
-
refuse('context implementation differs ' + pin);
|
|
45
|
-
const selected = context.resolve(record);
|
|
46
|
-
if (selected.digest !== pin || selected.form.id !== binding.form)
|
|
47
|
-
refuse('prepared form differs ' + record.fields.scope);
|
|
48
|
-
codecs[record.fields.scope] = { digest: pin, export: binding.export, params: selected.params };
|
|
49
|
-
}
|
|
50
|
-
const guestNames = Object.keys(manifest.modules);
|
|
51
|
-
if (guestNames.length !== 1)
|
|
52
|
-
refuse('installed guest module map');
|
|
53
|
-
const guestName = guestNames[0];
|
|
54
|
-
let program;
|
|
55
|
-
try {
|
|
56
|
-
program = `import{objectFold,intervalForm,alphabetOfForm}from${JSON.stringify(guestName)};const forms={intervalForm,alphabetOfForm},codecs=${JSON.stringify(codecs)},records=${JSON.stringify(records)};const context={resolve:cell=>{const c=codecs[cell.fields.scope];if(!c)throw Error('REFUSE unknown prepared cell');return{digest:c.digest,form:forms[c.export],params:c.params}}};globalThis.result=JSON.stringify(objectFold(records,context));`;
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return refuse('context is not serializable');
|
|
60
|
-
}
|
|
61
|
-
const entry = guestName + '.entry', programDigest = sha256(program);
|
|
62
|
-
const guest = readFileSync(new URL('guest.js', assets), 'utf8'), modules = { [guestName]: guest, [entry]: program }, request = { trusted: { ...manifest, modules: { ...manifest.modules, [entry]: programDigest }, entry, aliases: {}, limits, byteLengths: { ...manifest.byteLengths, modules: { ...manifest.byteLengths.modules, [entry]: Buffer.byteLength(program) } } }, assets: { runtime: new Uint8Array(readFileSync(new URL('runtime.js', assets))), wasm: new Uint8Array(readFileSync(new URL('runtime.wasm', assets))) }, modules, entry, aliases: {}, limits };
|
|
63
|
-
const result = await evaluateWasm(request, { workerFactory: () => new Worker(new URL('./node-worker.js', import.meta.url)), lifetimeMs, ...(signal ? { signal } : {}) });
|
|
64
|
-
if (Buffer.byteLength(result.output) > responseBytes)
|
|
65
|
-
refuse('response bytes limit');
|
|
66
|
-
let readings;
|
|
67
|
-
try {
|
|
68
|
-
readings = JSON.parse(result.output);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return refuse('invalid projection text');
|
|
72
|
-
}
|
|
73
|
-
if (!Array.isArray(readings) || readings.some(r => !r || typeof r.cell !== 'string' || typeof r.state !== 'string'))
|
|
74
|
-
refuse('invalid projection shape');
|
|
75
|
-
return readings;
|
|
76
|
-
}
|
|
1
|
+
var J=Object.defineProperty;var c=(o,e)=>J(o,"name",{value:e,configurable:!0});import{readFileSync as y}from"node:fs";import{Worker as B}from"node:worker_threads";import{sha256 as W}from"../host/hash.js";import{toposAt as $}from"../host/selected-topos.js";import{storeOf as q}from"../land/ledger.js";import{evaluateWasm as I}from"./adapter.js";function t(o){throw Error("REFUSE\xB7wasm object "+o)}c(t,"refuse");function M(o){const e=o.filter(a=>a.scope==="engine/object"&&a.value!=="withdraw");return e.length?((e.length!==1||e[0].role!=="writes"||e[0].measure!=="id"||e[0].form!=="alphabet"||!["esm@1","wasm@1"].includes(e[0].value??""))&&t("unique declared backend required"),e[0].value==="wasm@1"):!1}c(M,"usesWasmObject");function d(o,e,a){const s=o.filter(f=>f.scope==="engine/wasm/"+e&&f.value!=="withdraw");(s.length!==1||s[0].form!=="interval"||s[0].measure!==a||s[0].role!=="writes")&&t("missing or ambiguous "+e+" limit");const r=/^(0|[1-9][0-9]*)\.\.(0|[1-9][0-9]*)$/.exec(s[0].value??"");return(!r||!Number.isSafeInteger(Number(r[1]))||!Number.isSafeInteger(Number(r[2]))||Number(r[1])>Number(r[2])||Number(r[2])<1)&&t("invalid "+e+" limit"),Number(r[2])}c(d,"limit");async function P(o,e,a,s,r){M(s)||t("backend not selected");const f={memoryBytes:d(s,"memory","bytes"),stackBytes:d(s,"stack","bytes"),executionMs:d(s,"execution","milliseconds")},L=d(s,"worker-lifetime","milliseconds"),S=d(s,"response","bytes"),p=new URL("../../assets/wasm/",import.meta.url),l=JSON.parse(y(new URL("manifest.json",p),"utf8"));l.forms||t("installed form closure missing");const N={};for(const i of e.filter(n=>n.record==="cell")){const n=i.fields.topos,m=l.forms[n];(!m||!["intervalForm","alphabetOfForm"].includes(m.export)||m.form!==i.fields.form)&&t("unsupported form standing "+n);const k=$(n,q(o)),F=k.parts.filter(w=>w.scope==="wire/topos/context-view");F.length!==1&&t("context selection "+n);const v=k.parts.filter(w=>w.kind==="check"&&w.view===F[0].value);(v.length!==1||v[0].value!==m.contextArtifact||!(v[0].restsOn??"").split("|").includes(m.contextArtifact))&&t("context implementation differs "+n);const x=a.resolve(i);(x.digest!==n||x.form.id!==m.form)&&t("prepared form differs "+i.fields.scope),N[i.fields.scope]={digest:n,export:m.export,params:x.params}}const O=Object.keys(l.modules);O.length!==1&&t("installed guest module map");const h=O[0];let g;try{g=`import{objectFold,intervalForm,alphabetOfForm}from${JSON.stringify(h)};const forms={intervalForm,alphabetOfForm},codecs=${JSON.stringify(N)},records=${JSON.stringify(e)};const context={resolve:cell=>{const c=codecs[cell.fields.scope];if(!c)throw Error('REFUSE unknown prepared cell');return{digest:c.digest,form:forms[c.export],params:c.params}}};globalThis.result=JSON.stringify(objectFold(records,context));`}catch{return t("context is not serializable")}const u=h+".entry",U=W(g),R=y(new URL("guest.js",p),"utf8"),A={[h]:R,[u]:g},E={trusted:{...l,modules:{...l.modules,[u]:U},entry:u,aliases:{},limits:f,byteLengths:{...l.byteLengths,modules:{...l.byteLengths.modules,[u]:Buffer.byteLength(g)}}},assets:{runtime:new Uint8Array(y(new URL("runtime.js",p))),wasm:new Uint8Array(y(new URL("runtime.wasm",p)))},modules:A,entry:u,aliases:{},limits:f},j=await I(E,{workerFactory:c(()=>new B(new URL("./node-worker.js",import.meta.url)),"workerFactory"),lifetimeMs:L,...r?{signal:r}:{}});Buffer.byteLength(j.output)>S&&t("response bytes limit");let b;try{b=JSON.parse(j.output)}catch{return t("invalid projection text")}return(!Array.isArray(b)||b.some(i=>!i||typeof i.cell!="string"||typeof i.state!="string"))&&t("invalid projection shape"),b}c(P,"foldObjectsWithWasm");export{P as foldObjectsWithWasm,M as usesWasmObject};
|
package/dist/wasm/worker.js
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
self.onmessage = async ({ data }) => { try {
|
|
3
|
-
self.postMessage({ ok: true, result: await runWasmRequest(data) });
|
|
4
|
-
}
|
|
5
|
-
catch (error) {
|
|
6
|
-
self.postMessage({ ok: false, error: String(error) });
|
|
7
|
-
} };
|
|
1
|
+
import{runWasmRequest as r}from"./adapter.js";self.onmessage=async({data:e})=>{try{self.postMessage({ok:!0,result:await r(e)})}catch(s){self.postMessage({ok:!1,error:String(s)})}};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"role": "contract",
|
|
6
6
|
"path": "docs/contracts/reference-port.md",
|
|
7
|
-
"digest": "sha256:
|
|
7
|
+
"digest": "sha256:7fe99f71468a800f88d64104710b8b877d874f3415b9f4480eee5d30a9d871ae"
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"role": "yes",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Authority card view
|
|
2
|
+
|
|
3
|
+
`await prepareNativeAuthorityCard(context)` produces a read-only native preflight for exact requested configuration records. `record-coverage` checks current signer eligibility, coordinate coverage and the existing widening witness rule. `admission` additionally invokes the same structured wire, standing-pin, same-lot withdrawal, destination ownership, fork, alias, existing-reading, withdrawn-coordinate and demand checks used by the native admission path. Root and child destinations use their actual authenticated standing. An `allow` covers only this named configuration preflight; the eventual act still verifies its actual signatures, current authority and commit conditions. It never signs, commits, publishes or runs a requested action.
|
|
4
|
+
|
|
5
|
+
The receiver supplies the Root location and native instrument. Both public operations are asynchronous and retain the existing native Root authority protection while inspecting evidence. The protection is released before the promise settles, including refusals, and nested protected calls reuse their real held protection. Prospective child inspection preserves the caller's preview state and keeps nested Root previews separate. Every call supplies an explicit authority epoch and `{name, unit, now}` clock. Current Root history is freshly authenticated from the original bootstrap anchor; grant digests supplied in request JSON establish nothing. Root history and selected lock bytes must remain unchanged throughout preparation. Operational elapsed-time measurements in existing demand/fold code continue using the actual host clock. They are not substituted for card freshness and are not frozen to the supplied semantic time.
|
|
6
|
+
|
|
7
|
+
The `catalog` and `standingContract` fields are the exact digests of the shipped refusal catalog and standing contract, read by the existing installed-contract helper. Policy, coverage, budget and judgment digests commit semantic context; they do not name invented files. The card uses the Topos authority-card format and `authorityCardAnswer`. Its coverage commitment binds the real Root location, selected place, key, authenticated current grants and exact action identities. Its snapshot binds the selected lock bytes. Answering reruns the native checks and verifies the reconstructed statement and evidence; it accepts no consumer-provided judgment callback. Grant retirement invalidates a card even when child lock bytes remain unchanged. An expired or obsolete card returns `card-stale`; an action absent from the card returns `not-in-card`. Parsed card shape alone cannot establish authority.
|
|
8
|
+
|
|
9
|
+
`allow`, `ask` and `deny` preserve the existing check outcomes. `ask` names the missing signatures, widening witnesses, existing readings or unpaid demands. Named native authority, wire, pin, placement, fork, withdrawal and demand refusals produce `deny`. Missing bounded admission evidence remains `ask` with its exact request identity. New demands remain owed until their native judgment is paid. A declared reading-witness policy uses the same witness-admission hook for the view and the act; legacy witnessing remains unchanged when no such policy is selected. Typed-object admission, execution and unrelated aggregate actions are outside this configuration contract and refuse explicitly.
|
|
10
|
+
|
|
11
|
+
## Request selection
|
|
12
|
+
|
|
13
|
+
`fold --as authority-card@<scope>` selects exactly one currently admitted Root record at `<scope>` with `form=alphabet`, `role=writes`, `measure=authority-card-request` and a SHA-256 digest in `value`. Two admitted interval records `<scope>/bytes` and `<scope>/items`, each `role=writes` and `value=0..N`, bound the request. The receiver reads local CAS bytes with the declared byte bound before decoding or hashing, verifies the selected digest, and calls `parseNativeAuthorityCardRequest`. It never resolves or executes an offered provider for this view.
|
|
14
|
+
|
|
15
|
+
The request document contains exactly `profile`, `place`, `key`, `authorityEpoch`, `clock`, `horizon`, `limits` and `actions`. The profile is `native-authority-card-request/1`. `place` is `.` or a declared relative child. `limits` contains positive finite `bytes` and `items`, neither larger than the admitted request policy. Every action contains exactly `kind` (`record-coverage` or `admission`) and `records` (wire-line strings). Clock contains exactly `name`, `unit` and `now`; horizon contains exactly `clock`, `unit`, `from` and `through`. Requested key names, record signatures and clocks are data checked against the current receiver context. The request cannot supply a Root path, store, instrument, trust anchor or private key. Extra `root` or `instrument` fields, unsupported actions, invalid clocks, unbounded input and digest mismatches refuse.
|
|
16
|
+
|
|
17
|
+
`await answerNativeAuthorityCard(card, requestIdentity, context)` uses the same trusted receiver inputs and fresh explicit request snapshot. Consumers use `nativeAuthorityRequestIdentity(action)` to name an exact action; they do not reconstruct grants or infer permission from a card's shape. All byte/item limits are finite, and preparation persists no admission result or proof cache.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scope": "contract/published/authority-preflight",
|
|
3
|
+
"members": [
|
|
4
|
+
{
|
|
5
|
+
"role": "contract",
|
|
6
|
+
"path": "docs/contracts/authority-preflight.md",
|
|
7
|
+
"digest": "sha256:5befc60061e202b1db514a1d591fd193276e3d158b26860ebe534d5d7eef4d64"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"role": "yes",
|
|
11
|
+
"path": "samples/authority-preflight/yes.json",
|
|
12
|
+
"digest": "sha256:4cc9fb389fad93be81262c450a279f5c7545a0c14e35360fdf046ed7895b66aa"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"role": "no",
|
|
16
|
+
"path": "samples/authority-preflight/no.json",
|
|
17
|
+
"digest": "sha256:803eeb7b829c32e05dbee392e249e3c304eb77f5f7876982e64eed1bf4533c78"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"role": "vector",
|
|
21
|
+
"path": "vectors/native/authority-preflight.vector.json",
|
|
22
|
+
"digest": "sha256:87c018d8997e83ef7cf618c7b239552fdb8ef392f9ef9d0678914752fd6a28d4"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -18,6 +18,6 @@ Consumer verifies the expected container digest and repeats the same closure pre
|
|
|
18
18
|
|
|
19
19
|
The host must verify actual mounted bytes again before execution; the test host demonstrates this but is not a public browser host.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Native, program and worker custody remains in force. A pinned syntax analyzer detects unsupported loading expressions before execution; Node inventories and links the executable modules. Authenticated world loads require a declared closure and verified mounted bytes. This preflight is not a JavaScript execution sandbox.
|
|
22
22
|
|
|
23
23
|
No external fetch or general demand resolver is introduced. Missing bytes remain outside completed delivery and must be resolved by the existing host contract.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"role": "contract",
|
|
6
6
|
"path": "docs/contracts/closure-delivery.md",
|
|
7
|
-
"digest": "sha256:
|
|
7
|
+
"digest": "sha256:e670a83d76a7c9d0558ff1f4f830c313497c9e809da409cece1caa5d2a079c8e"
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"role": "yes",
|