@astrale-os/sdk 0.5.0-beta.22 → 0.5.0-beta.24
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/application/action/context.d.ts +1 -1
- package/dist/deployment/build/admission.d.ts +10 -2
- package/dist/deployment/build/admission.js +10 -4
- package/dist/deployment/build/compile.js +1 -1
- package/dist/deployment/build/material.js +45 -14
- package/dist/deployment/release/publication/seal.js +2 -2
- package/dist/deployment/verify/preflight/publication.js +2 -2
- package/dist/execution/runtime/load.d.ts +1 -1
- package/dist/execution/runtime/load.js +3 -10
- package/package.json +1 -1
|
@@ -54,7 +54,7 @@ type SelfOf<Callable> = Callable extends ResolvedMethod<unknown, unknown, false>
|
|
|
54
54
|
};
|
|
55
55
|
/** Exact single-step Action context derived from one resolved callable. */
|
|
56
56
|
export type ActionContext<Callable extends ResolvedCallable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>> = {
|
|
57
|
-
/** Exact
|
|
57
|
+
/** Exact admitted Domain retained by the Build being executed. */
|
|
58
58
|
readonly domain: DomainValue;
|
|
59
59
|
readonly input: CallableInputOf<Callable>;
|
|
60
60
|
readonly integrations: IntegrationClients<Definitions>;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import type { RuntimeRegistry } from '../../application/runtime/index.js';
|
|
2
|
+
import type { Domain } from '../../platform/schema/index.js';
|
|
1
3
|
import type { Build } from './build.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
interface BuildEvidence {
|
|
5
|
+
readonly domain: Domain;
|
|
6
|
+
readonly registry: RuntimeRegistry;
|
|
7
|
+
}
|
|
8
|
+
/** Retain package ownership and realization evidence for one admitted Build. */
|
|
9
|
+
export declare function admitBuild<Value extends Build>(build: Value, evidence: BuildEvidence): Value;
|
|
4
10
|
export declare function isBuild(input: unknown): input is Build;
|
|
11
|
+
export declare function evidenceOf(build: Build): BuildEvidence;
|
|
12
|
+
export {};
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
const admittedBuilds = new
|
|
2
|
-
/** Retain package ownership
|
|
3
|
-
export function admitBuild(build) {
|
|
4
|
-
admittedBuilds.
|
|
1
|
+
const admittedBuilds = new WeakMap();
|
|
2
|
+
/** Retain package ownership and realization evidence for one admitted Build. */
|
|
3
|
+
export function admitBuild(build, evidence) {
|
|
4
|
+
admittedBuilds.set(build, Object.freeze({ domain: evidence.domain, registry: evidence.registry }));
|
|
5
5
|
return build;
|
|
6
6
|
}
|
|
7
7
|
export function isBuild(input) {
|
|
8
8
|
return input !== null && typeof input === 'object' && admittedBuilds.has(input);
|
|
9
9
|
}
|
|
10
|
+
export function evidenceOf(build) {
|
|
11
|
+
const evidence = admittedBuilds.get(build);
|
|
12
|
+
if (evidence === undefined)
|
|
13
|
+
throw new TypeError('Build is not admitted.');
|
|
14
|
+
return evidence;
|
|
15
|
+
}
|
|
@@ -38,7 +38,7 @@ export function compile(application) {
|
|
|
38
38
|
routes: plan,
|
|
39
39
|
...(frontend === undefined ? {} : { frontend }),
|
|
40
40
|
});
|
|
41
|
-
return admitBuild(build);
|
|
41
|
+
return admitBuild(build, { domain, registry });
|
|
42
42
|
}
|
|
43
43
|
function compileRequirements(domain, input, sourceBundle) {
|
|
44
44
|
for (const key of input?.callables ?? []) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as bundle from '@astrale-os/kernel-dsl/v1/bundle/transport';
|
|
2
2
|
import { load as loadCompiledSchema } from '@astrale-os/kernel-dsl/v1/compiled/loader';
|
|
3
3
|
import { revision } from '@astrale-os/kernel-dsl/v1/schema/revision';
|
|
4
|
+
import { equal } from '@astrale-os/kernel-dsl/value';
|
|
4
5
|
import * as artifact from '@astrale-os/kernel-protocol/artifact';
|
|
5
6
|
import { BUNDLE_MEDIA_TYPE } from '@astrale-os/kernel-protocol/publication/bundle';
|
|
6
7
|
import { admitRequirements, validateRequirements, } from '@astrale-os/kernel-protocol/publication/requirements';
|
|
8
|
+
import * as routes from '@astrale-os/kernel-protocol/routes';
|
|
7
9
|
import { admitRuntimeRegistry, isRuntime } from '../../application/runtime/index.js';
|
|
8
10
|
import { admitBuild, isBuild } from './admission.js';
|
|
9
11
|
/** Detach the provider-neutral, runtime-free material embedded into generated execution code. */
|
|
@@ -50,6 +52,7 @@ export function restoreBuild(input, runtime) {
|
|
|
50
52
|
const identified = artifact.identify(bytes, BUNDLE_MEDIA_TYPE);
|
|
51
53
|
if (identified.digest !== input.schema.bundle.ref.digest ||
|
|
52
54
|
identified.mediaType !== input.schema.bundle.ref.mediaType ||
|
|
55
|
+
identified.size !== input.schema.bundle.ref.size ||
|
|
53
56
|
decoded.root.origin !== input.schema.compiled.root.origin ||
|
|
54
57
|
revision(decoded.root) !== input.schema.compiled.root.revision) {
|
|
55
58
|
invalid();
|
|
@@ -62,32 +65,60 @@ export function restoreBuild(input, runtime) {
|
|
|
62
65
|
}
|
|
63
66
|
const requirements = admitRequirements(input.requirements);
|
|
64
67
|
validateRequirements(decoded.root, decoded.closure, requirements);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
68
|
+
const plan = admitRoutePlan(input.routes, domain);
|
|
69
|
+
const compiled = deepFreeze(input.schema.compiled);
|
|
70
|
+
const bundleRef = deepFreeze(input.schema.bundle.ref);
|
|
71
|
+
const frontend = input.frontend === undefined ? undefined : deepFreeze(input.frontend);
|
|
70
72
|
const detached = new Uint8Array(bytes);
|
|
71
73
|
const build = Object.freeze({
|
|
72
74
|
kind: 'build',
|
|
73
75
|
schema: Object.freeze({
|
|
74
|
-
compiled
|
|
76
|
+
compiled,
|
|
75
77
|
bundle: Object.freeze({
|
|
76
|
-
ref:
|
|
78
|
+
ref: bundleRef,
|
|
77
79
|
bytes: () => new Uint8Array(detached),
|
|
78
80
|
}),
|
|
79
81
|
}),
|
|
80
82
|
runtime,
|
|
81
83
|
callables: Object.freeze([...input.callables]),
|
|
82
84
|
requirements,
|
|
83
|
-
routes:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
routes: plan,
|
|
86
|
+
...(frontend === undefined ? {} : { frontend }),
|
|
87
|
+
});
|
|
88
|
+
return admitBuild(build, { domain, registry });
|
|
89
|
+
}
|
|
90
|
+
function admitRoutePlan(input, domain) {
|
|
91
|
+
if (input.origin !== domain.origin ||
|
|
92
|
+
input.revision !== domain.revision ||
|
|
93
|
+
!Array.isArray(input.entries)) {
|
|
94
|
+
invalid();
|
|
95
|
+
}
|
|
96
|
+
const declarations = input.entries.map((entry) => {
|
|
97
|
+
if (entry === null || typeof entry !== 'object' || Array.isArray(entry))
|
|
98
|
+
invalid();
|
|
99
|
+
const { target, auth: _auth, output: _output, default: isDefault, ...declaration } = entry;
|
|
100
|
+
return {
|
|
101
|
+
...declaration,
|
|
102
|
+
...(isDefault ? { default: true } : {}),
|
|
103
|
+
...(target?.kind === 'method' && target.dispatch === 'instance'
|
|
104
|
+
? { receiver: target.receiver }
|
|
105
|
+
: {}),
|
|
106
|
+
};
|
|
89
107
|
});
|
|
90
|
-
|
|
108
|
+
const admitted = routes.compile({ domain, routes: declarations });
|
|
109
|
+
if (!equal(admitted, input))
|
|
110
|
+
invalid();
|
|
111
|
+
return admitted;
|
|
112
|
+
}
|
|
113
|
+
function deepFreeze(input, seen = new WeakSet()) {
|
|
114
|
+
if (input !== null && typeof input === 'object' && !seen.has(input)) {
|
|
115
|
+
seen.add(input);
|
|
116
|
+
for (const value of Object.values(input))
|
|
117
|
+
deepFreeze(value, seen);
|
|
118
|
+
if (!Object.isFrozen(input))
|
|
119
|
+
Object.freeze(input);
|
|
120
|
+
}
|
|
121
|
+
return input;
|
|
91
122
|
}
|
|
92
123
|
function invalid() {
|
|
93
124
|
throw new TypeError('Generated Build material is invalid.');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { load as loadCompiledSchema } from '@astrale-os/kernel-dsl/v1/compiled/loader';
|
|
2
1
|
import * as publication from '@astrale-os/kernel-protocol/publication';
|
|
3
2
|
import * as protocolRoutes from '@astrale-os/kernel-protocol/routes';
|
|
3
|
+
import { evidenceOf } from '../../build/admission.js';
|
|
4
4
|
import { callables } from './callables.js';
|
|
5
5
|
import { manifest } from './manifest.js';
|
|
6
6
|
import { requirements } from './requirements.js';
|
|
@@ -32,7 +32,7 @@ export function seal(build, addressing) {
|
|
|
32
32
|
delivery: publication.placeDelivery({ path: DELIVERY_PATH, authentication: { kind: 'public' } }, addressing.issuer, new URL(BUNDLE_PATH, addressing.issuer).href),
|
|
33
33
|
routes: routes(build, addressing),
|
|
34
34
|
});
|
|
35
|
-
const domain =
|
|
35
|
+
const { domain } = evidenceOf(build);
|
|
36
36
|
return Object.freeze({
|
|
37
37
|
publication: sealed,
|
|
38
38
|
routes: protocolRoutes.bind(build.routes, sealed, domain),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { load as loadCompiledSchema } from '@astrale-os/kernel-dsl/v1/compiled/loader';
|
|
2
1
|
import { publication as protocolPublication, routes } from '@astrale-os/kernel-protocol';
|
|
2
|
+
import { evidenceOf } from '../../build/admission.js';
|
|
3
3
|
import { assemble } from '../../release/index.js';
|
|
4
4
|
/** Verify locally assemblable Publication evidence before any provider mutation. */
|
|
5
5
|
export function publication(artifact) {
|
|
@@ -8,7 +8,7 @@ export function publication(artifact) {
|
|
|
8
8
|
const release = assemble(artifact.build, artifact.addressing.addressing);
|
|
9
9
|
const admitted = protocolPublication.accept(release.publication);
|
|
10
10
|
protocolPublication.verifyBundleBytes(admitted, artifact.build.schema.bundle.bytes());
|
|
11
|
-
const domain =
|
|
11
|
+
const { domain } = evidenceOf(artifact.build);
|
|
12
12
|
routes.verifyTable(release.routes, admitted, domain);
|
|
13
13
|
return release;
|
|
14
14
|
}
|
|
@@ -7,5 +7,5 @@ export interface LoadedRuntime<BuildValue extends Build = Build> {
|
|
|
7
7
|
readonly domain: Domain;
|
|
8
8
|
readonly registry: RuntimeRegistry;
|
|
9
9
|
}
|
|
10
|
-
/** Load
|
|
10
|
+
/** Load one execution Runtime from the exact evidence retained by its admitted Build. */
|
|
11
11
|
export declare function load<const BuildValue extends Build>(release: Release<BuildValue>): LoadedRuntime<BuildValue>;
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { admitRuntimeRegistry } from '../../application/runtime/index.js';
|
|
1
|
+
import { evidenceOf } from '../../deployment/build/admission.js';
|
|
3
2
|
import { isRelease } from '../../deployment/release/admission.js';
|
|
4
3
|
import { capture } from './admission.js';
|
|
5
|
-
/** Load
|
|
4
|
+
/** Load one execution Runtime from the exact evidence retained by its admitted Build. */
|
|
6
5
|
export function load(release) {
|
|
7
6
|
if (!isRelease(release))
|
|
8
7
|
throw new TypeError('Runtime loading requires an admitted Release.');
|
|
9
|
-
const domain =
|
|
10
|
-
const registry = admitRuntimeRegistry(domain, release.build.runtime);
|
|
11
|
-
const actual = registry.implementations.map(({ callable }) => callable.key).sort();
|
|
12
|
-
if (actual.length !== release.build.callables.length ||
|
|
13
|
-
actual.some((key, index) => key !== release.build.callables[index])) {
|
|
14
|
-
throw new TypeError('Runtime registry differs from its compiled Build callable set.');
|
|
15
|
-
}
|
|
8
|
+
const { domain, registry } = evidenceOf(release.build);
|
|
16
9
|
return capture(Object.freeze({ release, domain, registry }));
|
|
17
10
|
}
|