@astrale-os/kernel-core 0.9.0-beta.64 → 0.9.0-beta.66
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/auth/authority/admission/admission.d.ts +0 -1
- package/dist/auth/authority/admission/admission.js +8 -141
- package/dist/auth/authority/admission/references.d.ts +13 -0
- package/dist/auth/authority/admission/references.js +38 -0
- package/dist/auth/authority/admission/term.d.ts +6 -0
- package/dist/auth/authority/admission/term.js +60 -0
- package/dist/auth/authority/admission/wire.d.ts +8 -0
- package/dist/auth/authority/admission/wire.js +33 -0
- package/dist/graph/graph/index.d.ts +1 -1
- package/dist/graph/graph/index.js +1 -1
- package/dist/graph/graph/model/codec.js +3 -3
- package/dist/graph/graph/model/index.d.ts +1 -1
- package/dist/graph/graph/model/index.js +1 -1
- package/dist/graph/graph/model/model.d.ts +7 -7
- package/dist/graph/graph/model/model.js +6 -6
- package/dist/graph/graph/model/wire.d.ts +0 -20
- package/dist/graph/graph/model/wire.js +2 -2
- package/dist/graph/mutate/authoring/builder.d.ts +2 -2
- package/dist/graph/mutate/authoring/builder.js +2 -2
- package/dist/graph/mutate/index.d.ts +1 -1
- package/dist/graph/mutate/language/codec.js +3 -3
- package/dist/graph/mutate/language/model.d.ts +4 -4
- package/dist/graph/mutate/result/index.d.ts +3 -3
- package/dist/graph/mutate/result/index.js +5 -5
- package/dist/graph/node/identity/id.d.ts +0 -3
- package/dist/graph/node/identity/id.js +0 -4
- package/dist/graph/query/language/codec.js +3 -3
- package/dist/graph/query/language/model.d.ts +3 -3
- package/dist/graph/reconcile/condition/model.d.ts +2 -2
- package/dist/graph/reconcile/condition/references.d.ts +0 -1
- package/dist/graph/reconcile/condition/references.js +4 -4
- package/dist/graph/reconcile/correspondence.d.ts +9 -8
- package/dist/graph/reconcile/evidence.d.ts +2 -2
- package/dist/graph/reconcile/mutation/assess.d.ts +2 -1
- package/dist/graph/reconcile/observation.d.ts +4 -3
- package/dist/graph/reconcile/planning/context.d.ts +3 -3
- package/dist/graph/reconcile/planning/model.d.ts +4 -4
- package/dist/schema/callables/{view-for.d.ts → entrypoint.d.ts} +7 -5
- package/dist/schema/callables/entrypoint.js +12 -0
- package/dist/schema/callables/function.d.ts +0 -90
- package/dist/schema/callables/index.d.ts +1 -1
- package/dist/schema/callables/index.js +1 -1
- package/dist/schema/callables/view.d.ts +2 -24
- package/dist/schema/domain/domain.d.ts +2 -91
- package/dist/schema/domain/domain.js +3 -0
- package/dist/schema/identity/identity.d.ts +0 -6
- package/dist/schema/kernel/projection/core.d.ts +7 -0
- package/dist/schema/kernel/projection/core.js +51 -0
- package/dist/schema/kernel/projection/definitions.d.ts +13 -0
- package/dist/schema/kernel/projection/definitions.js +71 -0
- package/dist/schema/kernel/projection/methods.d.ts +5 -0
- package/dist/schema/kernel/projection/methods.js +41 -0
- package/dist/schema/kernel/projection/part.d.ts +34 -0
- package/dist/schema/kernel/projection/part.js +42 -0
- package/dist/schema/kernel/projection/paths.d.ts +6 -0
- package/dist/schema/kernel/projection/{keys.js → paths.js} +11 -12
- package/dist/schema/kernel/projection/project.d.ts +1 -1
- package/dist/schema/kernel/projection/project.js +16 -290
- package/dist/schema/kernel/projection/properties.d.ts +11 -0
- package/dist/schema/kernel/projection/properties.js +36 -0
- package/dist/schema/kernel/projection/relations.d.ts +7 -0
- package/dist/schema/kernel/projection/relations.js +49 -0
- package/dist/schema/kernel/projection/types.d.ts +4 -4
- package/dist/schema/kernel/schema.d.ts +125 -347
- package/dist/schema/kernel/schema.js +3 -2
- package/dist/schema/kernel/syscalls/contracts/blob.d.ts +12 -2
- package/dist/schema/kernel/syscalls/contracts/blob.js +10 -2
- package/dist/schema/kernel/syscalls/contracts/delegate.d.ts +0 -1
- package/dist/schema/kernel/syscalls/contracts/delegate.js +1 -3
- package/dist/schema/kernel/syscalls/contracts/impersonate.d.ts +0 -1
- package/dist/schema/kernel/syscalls/contracts/index.d.ts +1 -1
- package/dist/schema/kernel/syscalls/contracts/index.js +1 -1
- package/dist/schema/kernel/syscalls/contracts/install.d.ts +3 -20
- package/dist/schema/kernel/syscalls/contracts/install.js +0 -2
- package/dist/schema/kernel/syscalls/contracts/installation.d.ts +0 -36
- package/dist/schema/kernel/syscalls/contracts/installation.js +3 -3
- package/dist/schema/kernel/syscalls/contracts/mint.d.ts +0 -1
- package/dist/schema/kernel/syscalls/contracts/mint.js +1 -2
- package/dist/schema/kernel/syscalls/contracts/view-resolve.d.ts +3 -14
- package/dist/schema/kernel/syscalls/contracts/view-resolve.js +3 -18
- package/dist/schema/kernel/syscalls/declarations/delegate.d.ts +0 -1
- package/dist/schema/kernel/syscalls/declarations/download.d.ts +5 -0
- package/dist/schema/kernel/syscalls/declarations/impersonate.d.ts +0 -1
- package/dist/schema/kernel/syscalls/declarations/index.d.ts +6 -23
- package/dist/schema/kernel/syscalls/declarations/install.d.ts +0 -8
- package/dist/schema/kernel/syscalls/declarations/mint.d.ts +0 -1
- package/dist/schema/kernel/syscalls/declarations/view-resolve.d.ts +1 -12
- package/dist/schema/kernel/syscalls/descriptors/identity.d.ts +0 -3
- package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.d.ts +2 -13
- package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.js +4 -119
- package/dist/schema/kernel/syscalls/descriptors/view.d.ts +1 -12
- package/package.json +2 -2
- package/dist/schema/callables/view-for.js +0 -12
- package/dist/schema/kernel/projection/keys.d.ts +0 -3
- package/dist/schema/kernel/syscalls/contracts/legacy/install.d.ts +0 -22
- package/dist/schema/kernel/syscalls/contracts/legacy/install.js +0 -31
|
@@ -9,6 +9,9 @@ export const Domain = nodeClass({
|
|
|
9
9
|
type: 'string',
|
|
10
10
|
pattern: '[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+',
|
|
11
11
|
},
|
|
12
|
+
// The authored display name; a revision that predates it projects its origin instead, which
|
|
13
|
+
// is why the bound admits a complete origin rather than only an authored name.
|
|
14
|
+
name: { type: 'string', minLength: 1, maxLength: 253 },
|
|
12
15
|
dependencyContext: property({ type: 'array', items: { type: 'object' } }, { required: false }),
|
|
13
16
|
schema: property({ type: 'object' }, {}),
|
|
14
17
|
schemaRevision: property({ type: 'string', pattern: 'sha256:[0-9a-f]{64}' }, {}),
|
|
@@ -41,7 +41,6 @@ export declare const Identity: builder.NodeClass<{
|
|
|
41
41
|
principal: string;
|
|
42
42
|
audience: string;
|
|
43
43
|
ttlSeconds: number;
|
|
44
|
-
attenuation?: unknown;
|
|
45
44
|
}, {
|
|
46
45
|
readonly mode: 'value';
|
|
47
46
|
readonly value: string;
|
|
@@ -112,7 +111,6 @@ export declare const Identity: builder.NodeClass<{
|
|
|
112
111
|
mint: builder.Method<builder.CallableProjection<{
|
|
113
112
|
audience?: string | undefined;
|
|
114
113
|
ttlSeconds: number;
|
|
115
|
-
grant?: unknown;
|
|
116
114
|
}, {
|
|
117
115
|
readonly mode: 'value';
|
|
118
116
|
readonly value: string;
|
|
@@ -120,7 +118,6 @@ export declare const Identity: builder.NodeClass<{
|
|
|
120
118
|
impersonate: builder.Method<builder.CallableProjection<{
|
|
121
119
|
audience?: string | undefined;
|
|
122
120
|
ttlSeconds: number;
|
|
123
|
-
grant?: unknown;
|
|
124
121
|
identity: string;
|
|
125
122
|
}, {
|
|
126
123
|
readonly mode: 'value';
|
|
@@ -177,7 +174,6 @@ export declare const Identity: builder.NodeClass<{
|
|
|
177
174
|
principal: string;
|
|
178
175
|
audience: string;
|
|
179
176
|
ttlSeconds: number;
|
|
180
|
-
attenuation?: unknown;
|
|
181
177
|
}, {
|
|
182
178
|
readonly mode: 'value';
|
|
183
179
|
readonly value: string;
|
|
@@ -207,14 +203,12 @@ export declare const Identity: builder.NodeClass<{
|
|
|
207
203
|
}, "authorized", true, false, undefined>>, "whois", "self"> | builder.AuthoredMethodProjection<builder.Method<builder.CallableProjection<{
|
|
208
204
|
audience?: string | undefined;
|
|
209
205
|
ttlSeconds: number;
|
|
210
|
-
grant?: unknown;
|
|
211
206
|
}, {
|
|
212
207
|
readonly mode: 'value';
|
|
213
208
|
readonly value: string;
|
|
214
209
|
}, "authenticated", true, false, undefined>>, "mint", "self"> | builder.AuthoredMethodProjection<builder.Method<builder.CallableProjection<{
|
|
215
210
|
audience?: string | undefined;
|
|
216
211
|
ttlSeconds: number;
|
|
217
|
-
grant?: unknown;
|
|
218
212
|
identity: string;
|
|
219
213
|
}, {
|
|
220
214
|
readonly mode: 'value';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SourceDomain, schema } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import { type Edge, type Part, type Payload } from './part.js';
|
|
3
|
+
/**
|
|
4
|
+
* Declare each authored Core Node, then each authored Core Edge, and return the locators that
|
|
5
|
+
* associate every Core Node with its Domain.
|
|
6
|
+
*/
|
|
7
|
+
export declare function projectCore<Extra extends object>(domain: SourceDomain<schema.DomainSchema>, core: Part<Extra>, payload: Payload<Extra>): Edge<Extra>[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { Path } from '#graph/path';
|
|
3
|
+
import { K } from '../index.js';
|
|
4
|
+
import { projectedMethodPath } from './callables.js';
|
|
5
|
+
import { ProjectionError } from './diagnostics.js';
|
|
6
|
+
import { edge } from './part.js';
|
|
7
|
+
import { memberProperties } from './properties.js';
|
|
8
|
+
/**
|
|
9
|
+
* Declare each authored Core Node, then each authored Core Edge, and return the locators that
|
|
10
|
+
* associate every Core Node with its Domain.
|
|
11
|
+
*/
|
|
12
|
+
export function projectCore(domain, core, payload) {
|
|
13
|
+
// The Domain Node is persisted before its Core part, so locators address it by its Path.
|
|
14
|
+
const domainEndpoint = Object.freeze({ path: Path.domain(domain.origin).raw });
|
|
15
|
+
const locators = [];
|
|
16
|
+
for (const [slug, declaration] of Object.entries(domain.source.core.nodes)) {
|
|
17
|
+
assertAuthenticationUnowned(domain, declaration.class, declaration.properties, slug);
|
|
18
|
+
const created = core.node(Path.project({ origin: domain.origin, kind: 'core', name: slug }).raw, ClassKey.of(declaration.class), payload(() => declaration.properties));
|
|
19
|
+
locators.push(edge(created, domainEndpoint, K.classes.of_domain.ref, payload(() => memberProperties(`core.${slug}`))));
|
|
20
|
+
}
|
|
21
|
+
// Resolved edges carry each endpoint's own identity; the source IR only names it.
|
|
22
|
+
for (const authored of domain.core.edges) {
|
|
23
|
+
core.edges.push(edge(endpoint(authored.source, domain, core, domainEndpoint), endpoint(authored.target, domain, core, domainEndpoint), authored.class.ref, payload(() => authored.properties)));
|
|
24
|
+
}
|
|
25
|
+
return locators;
|
|
26
|
+
}
|
|
27
|
+
/** Authentication of a Core Identity is established only by the credential-evidenced lifecycle. */
|
|
28
|
+
function assertAuthenticationUnowned(domain, classRef, properties, slug) {
|
|
29
|
+
const definition = domain.definition(classRef);
|
|
30
|
+
if (definition?.ref.kind !== 'class' ||
|
|
31
|
+
definition.kind !== 'node' ||
|
|
32
|
+
!definition.satisfies(K.classes.Identity)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const hasIssuer = Object.hasOwn(properties, K.classes.Identity.properties.iss.key);
|
|
36
|
+
const hasSubject = Object.hasOwn(properties, K.classes.Identity.properties.sub.key);
|
|
37
|
+
if (hasIssuer || hasSubject) {
|
|
38
|
+
throw new ProjectionError('PROJECTION_INVALID', `Core Identity ${domain.origin}:core.${slug} cannot declare protected Authentication properties iss or sub.`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A Core Node binds inside the Core part; every other local Definition is already projected as a
|
|
43
|
+
* managed declaration, so it is addressed by its canonical Path exactly like the owning Domain.
|
|
44
|
+
*/
|
|
45
|
+
function endpoint(value, domain, core, domainEndpoint) {
|
|
46
|
+
if ('ref' in value)
|
|
47
|
+
return core.endpoint(Path.project(value.ref).raw);
|
|
48
|
+
if ('owner' in value)
|
|
49
|
+
return core.endpoint(projectedMethodPath(domain, value));
|
|
50
|
+
return domainEndpoint;
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SourceDomain, schema } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type { ResolvedDefinition, ResolvedDefinitionOf } from '@astrale-os/kernel-dsl/v1/language';
|
|
3
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
4
|
+
import type { GraphSpecEndpoint } from '#graph/graph';
|
|
5
|
+
import { type Part, type Payload } from './part.js';
|
|
6
|
+
/** Declare the Domain Node, the target of every of_domain locator. */
|
|
7
|
+
export declare function projectDomain<Extra extends object>(domain: SourceDomain<schema.DomainSchema>, managed: Part<Extra>, payload: Payload<Extra>): GraphSpecEndpoint;
|
|
8
|
+
/** Declare each local Definition's Node and its of_domain locator. */
|
|
9
|
+
export declare function projectDefinitions<Extra extends object>(domain: SourceDomain<schema.DomainSchema>, managed: Part<Extra>, domainEndpoint: GraphSpecEndpoint, payload: Payload<Extra>): void;
|
|
10
|
+
/** Each local Definition projected as a managed declaration, with the Kernel Class it projects to. */
|
|
11
|
+
export declare function projectedDefinitions(domain: SourceDomain<schema.DomainSchema>): Generator<readonly [ResolvedDefinition, ClassKey]>;
|
|
12
|
+
/** Whether a resolved Definition is of the given kind. */
|
|
13
|
+
export declare function is<Kind extends ResolvedDefinition['ref']['kind']>(definition: ResolvedDefinition, kind: Kind): definition is ResolvedDefinitionOf<Kind>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { Path } from '#graph/path';
|
|
3
|
+
import { normalizeProperties } from '#graph/properties';
|
|
4
|
+
import { K } from '../index.js';
|
|
5
|
+
import { edge } from './part.js';
|
|
6
|
+
import { EMPTY_PROPERTIES, callableProperties, descriptionProperties, memberProperties, } from './properties.js';
|
|
7
|
+
/** Declare the Domain Node, the target of every of_domain locator. */
|
|
8
|
+
export function projectDomain(domain, managed, payload) {
|
|
9
|
+
return managed.node(Path.domain(domain.origin).raw, ClassKey.of(K.classes.Domain.ref), payload(() => domainProperties(domain)));
|
|
10
|
+
}
|
|
11
|
+
/** Declare each local Definition's Node and its of_domain locator. */
|
|
12
|
+
export function projectDefinitions(domain, managed, domainEndpoint, payload) {
|
|
13
|
+
for (const [definition, projectedClass] of projectedDefinitions(domain)) {
|
|
14
|
+
const definitionEndpoint = managed.node(Path.project(definition.ref).raw, projectedClass, payload(() => definitionProperties(definition)));
|
|
15
|
+
managed.edges.push(edge(definitionEndpoint, domainEndpoint, K.classes.of_domain.ref, payload(() => memberProperties(`${definition.ref.kind}.${definition.ref.name}`))));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Each local Definition projected as a managed declaration, with the Kernel Class it projects to. */
|
|
19
|
+
export function* projectedDefinitions(domain) {
|
|
20
|
+
for (const definition of domain.definitions()) {
|
|
21
|
+
if (definition.ref.origin !== domain.origin)
|
|
22
|
+
continue;
|
|
23
|
+
const projectedClass = classOf(definition);
|
|
24
|
+
if (projectedClass !== undefined)
|
|
25
|
+
yield [definition, projectedClass];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Whether a resolved Definition is of the given kind. */
|
|
29
|
+
export function is(definition, kind) {
|
|
30
|
+
return definition.ref.kind === kind;
|
|
31
|
+
}
|
|
32
|
+
function classOf(definition) {
|
|
33
|
+
switch (definition.ref.kind) {
|
|
34
|
+
case 'class':
|
|
35
|
+
return ClassKey.of(K.classes.Class.ref);
|
|
36
|
+
case 'function':
|
|
37
|
+
return ClassKey.of(K.classes.Function.ref);
|
|
38
|
+
case 'policy':
|
|
39
|
+
return ClassKey.of(K.classes.Policy.ref);
|
|
40
|
+
case 'view':
|
|
41
|
+
return ClassKey.of(K.classes.View.ref);
|
|
42
|
+
default:
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Identity properties are supplied atomically by trusted lifecycle materialization. */
|
|
47
|
+
function domainProperties(domain) {
|
|
48
|
+
return normalizeProperties({
|
|
49
|
+
[K.classes.Domain.self.properties.origin.key]: domain.origin,
|
|
50
|
+
[K.classes.Domain.self.properties.name.key]: domain.source.name,
|
|
51
|
+
[K.classes.Domain.self.properties.schema.key]: domain.source,
|
|
52
|
+
[K.classes.Domain.self.properties.schemaRevision.key]: domain.revision,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function definitionProperties(definition) {
|
|
56
|
+
if (is(definition, 'function'))
|
|
57
|
+
return callableProperties(definition.definition);
|
|
58
|
+
if (is(definition, 'core'))
|
|
59
|
+
return EMPTY_PROPERTIES;
|
|
60
|
+
const metadata = descriptionProperties(definition.definition.description);
|
|
61
|
+
if (!is(definition, 'class'))
|
|
62
|
+
return normalizeProperties(metadata);
|
|
63
|
+
const declaration = definition.definition;
|
|
64
|
+
const icon = declaration.kind === 'node' ? declaration.icon : undefined;
|
|
65
|
+
return normalizeProperties({
|
|
66
|
+
...metadata,
|
|
67
|
+
[K.classes.Class.self.properties.kind.key]: declaration.kind,
|
|
68
|
+
[K.classes.Class.self.properties.abstract.key]: declaration.abstract,
|
|
69
|
+
...(icon !== undefined ? { [K.classes.Iconable.self.properties.icon.key]: icon } : {}),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SourceDomain, schema } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type { GraphSpecEndpoint } from '#graph/graph';
|
|
3
|
+
import { type Part, type Payload } from './part.js';
|
|
4
|
+
/** Declare each executable local Method as a Function Node, with its method_of and of_domain Edges. */
|
|
5
|
+
export declare function projectMethods<Extra extends object>(domain: SourceDomain<schema.DomainSchema>, managed: Part<Extra>, domainEndpoint: GraphSpecEndpoint, payload: Payload<Extra>): void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { Path } from '#graph/path';
|
|
3
|
+
import { normalizeProperties } from '#graph/properties';
|
|
4
|
+
import { K } from '../index.js';
|
|
5
|
+
import { projectedMethodPath } from './callables.js';
|
|
6
|
+
import { ProjectionError } from './diagnostics.js';
|
|
7
|
+
import { edge } from './part.js';
|
|
8
|
+
import { callableProperties, memberProperties } from './properties.js';
|
|
9
|
+
/** Declare each executable local Method as a Function Node, with its method_of and of_domain Edges. */
|
|
10
|
+
export function projectMethods(domain, managed, domainEndpoint, payload) {
|
|
11
|
+
for (const method of executableMethods(domain)) {
|
|
12
|
+
const methodEndpoint = managed.node(projectedMethodPath(domain, method), ClassKey.of(K.classes.Function.ref), payload(() => callableProperties(method.definition)));
|
|
13
|
+
managed.edges.push(edge(methodEndpoint, managed.endpoint(Path.project(method.owner.ref).raw), K.classes.method_of.ref, payload(() => normalizeProperties({
|
|
14
|
+
[K.classes.method_of.self.properties.name.key]: method.name,
|
|
15
|
+
[K.classes.method_of.self.properties.static.key]: method.definition.static,
|
|
16
|
+
}))));
|
|
17
|
+
// This structural check must also execute when no Property payload is requested.
|
|
18
|
+
const member = memberOf(domain, method);
|
|
19
|
+
managed.edges.push(edge(methodEndpoint, domainEndpoint, K.classes.of_domain.ref, payload(() => memberProperties(member))));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Each local executable Method once, instance and static, across every Class of the Domain. */
|
|
23
|
+
function executableMethods(domain) {
|
|
24
|
+
const methods = new Map();
|
|
25
|
+
for (const definition of Object.values(domain.classes)) {
|
|
26
|
+
for (const method of [...definition.methods, ...definition.static.methods]) {
|
|
27
|
+
if (method.owner.ref.origin === domain.origin && method.executable) {
|
|
28
|
+
methods.set(method.key, method);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return methods.values();
|
|
33
|
+
}
|
|
34
|
+
/** The Method's member name within its Domain. */
|
|
35
|
+
function memberOf(domain, method) {
|
|
36
|
+
const prefix = `${domain.origin}:`;
|
|
37
|
+
if (!method.key.startsWith(prefix)) {
|
|
38
|
+
throw new ProjectionError('PROJECTION_INVALID', 'Method key belongs to another Domain.');
|
|
39
|
+
}
|
|
40
|
+
return method.key.slice(prefix.length);
|
|
41
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ClassRef } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
3
|
+
import type { GraphSpecEndpoint } from '#graph/graph';
|
|
4
|
+
import type { NodePath } from '#graph/path';
|
|
5
|
+
import type { Properties } from '#graph/properties';
|
|
6
|
+
import { LocalAlias } from '#graph/graph';
|
|
7
|
+
import type { ProjectionTopologyEdge, ProjectionTopologyNode } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* What each declaration carries besides its identity: full projection evaluates the Property
|
|
10
|
+
* factory, topology projection never does. Call it in argument position, before `node` or `edge`
|
|
11
|
+
* runs its own checks, so both projections throw the same error first.
|
|
12
|
+
*/
|
|
13
|
+
export type Payload<Extra extends object> = (properties: () => Properties) => Extra;
|
|
14
|
+
export type Node<Extra extends object> = ProjectionTopologyNode & Extra;
|
|
15
|
+
export type Edge<Extra extends object> = ProjectionTopologyEdge & Extra;
|
|
16
|
+
/** One graph part under construction: its local bindings, its declared Nodes and its Edges. */
|
|
17
|
+
export declare class Part<Extra extends object> {
|
|
18
|
+
#private;
|
|
19
|
+
readonly edges: Edge<Extra>[];
|
|
20
|
+
/** Bind each Path, in the given order, to the next local binding `n0`, `n1`, ... */
|
|
21
|
+
constructor(paths: readonly NodePath[]);
|
|
22
|
+
/** A Path declared in this part is addressed by its binding, any other by the Path itself. */
|
|
23
|
+
endpoint(path: NodePath): GraphSpecEndpoint;
|
|
24
|
+
/** Declare the Node at a bound Path once; declaring it again returns the first binding. */
|
|
25
|
+
node(path: NodePath, classKey: ClassKey, payload: Extra): GraphSpecEndpoint;
|
|
26
|
+
/** The declared Nodes and Edges in declaration order, with each binding's Path. */
|
|
27
|
+
done(): Readonly<{
|
|
28
|
+
nodes: readonly Node<Extra>[];
|
|
29
|
+
edges: readonly Edge<Extra>[];
|
|
30
|
+
paths: Map<LocalAlias, import("../../../graph/path/language/model.js").NodePath>;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
/** One projected Edge. */
|
|
34
|
+
export declare function edge<Extra extends object>(source: GraphSpecEndpoint, target: GraphSpecEndpoint, classRef: ClassRef, payload: Extra): Edge<Extra>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
|
+
import { LocalAlias } from '#graph/graph';
|
|
3
|
+
import { ProjectionError } from './diagnostics.js';
|
|
4
|
+
/** One graph part under construction: its local bindings, its declared Nodes and its Edges. */
|
|
5
|
+
export class Part {
|
|
6
|
+
edges = [];
|
|
7
|
+
#bindings;
|
|
8
|
+
#nodes = new Map();
|
|
9
|
+
/** Bind each Path, in the given order, to the next local binding `n0`, `n1`, ... */
|
|
10
|
+
constructor(paths) {
|
|
11
|
+
this.#bindings = new Map(paths.map((path, index) => [path, LocalAlias(`n${index}`)]));
|
|
12
|
+
}
|
|
13
|
+
/** A Path declared in this part is addressed by its binding, any other by the Path itself. */
|
|
14
|
+
endpoint(path) {
|
|
15
|
+
const created = this.#bindings.get(path);
|
|
16
|
+
return created === undefined ? Object.freeze({ path }) : Object.freeze({ created });
|
|
17
|
+
}
|
|
18
|
+
/** Declare the Node at a bound Path once; declaring it again returns the first binding. */
|
|
19
|
+
node(path, classKey, payload) {
|
|
20
|
+
const existing = this.#nodes.get(path);
|
|
21
|
+
if (existing !== undefined)
|
|
22
|
+
return Object.freeze({ created: existing.as });
|
|
23
|
+
const as = this.#bindings.get(path);
|
|
24
|
+
if (as === undefined) {
|
|
25
|
+
throw new ProjectionError('PROJECTION_INVALID', `Projection has no binding for ${path}.`);
|
|
26
|
+
}
|
|
27
|
+
this.#nodes.set(path, Object.freeze({ as, class: classKey, ...payload }));
|
|
28
|
+
return Object.freeze({ created: as });
|
|
29
|
+
}
|
|
30
|
+
/** The declared Nodes and Edges in declaration order, with each binding's Path. */
|
|
31
|
+
done() {
|
|
32
|
+
return Object.freeze({
|
|
33
|
+
nodes: Object.freeze([...this.#nodes.values()]),
|
|
34
|
+
edges: Object.freeze(this.edges),
|
|
35
|
+
paths: new Map([...this.#bindings].map(([path, binding]) => [binding, path])),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** One projected Edge. */
|
|
40
|
+
export function edge(source, target, classRef, payload) {
|
|
41
|
+
return Object.freeze({ source, target, class: ClassKey.of(classRef), ...payload });
|
|
42
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Domain } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type { NodePath } from '#graph/path';
|
|
3
|
+
/** Sorted Paths of the Domain Node, its local Definitions and their executable Methods. */
|
|
4
|
+
export declare function managedPaths(domain: Domain): readonly NodePath[];
|
|
5
|
+
/** Sorted Paths of the Domain's authored Core Nodes. */
|
|
6
|
+
export declare function corePaths(domain: Domain): readonly NodePath[];
|
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
import { Path } from '#graph/path';
|
|
2
2
|
import { projectedMethodPath } from './callables.js';
|
|
3
3
|
const encoder = new TextEncoder();
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/** Sorted Paths of the Domain Node, its local Definitions and their executable Methods. */
|
|
5
|
+
export function managedPaths(domain) {
|
|
6
|
+
const paths = new Set([Path.domain(domain.origin).raw]);
|
|
7
7
|
for (const definition of domain.definitions()) {
|
|
8
8
|
if (definition.ref.origin !== domain.origin || definition.ref.kind === 'core')
|
|
9
9
|
continue;
|
|
10
|
-
add(
|
|
10
|
+
paths.add(Path.project(definition.ref).raw);
|
|
11
11
|
if (!('methods' in definition) || definition.kind !== 'node')
|
|
12
12
|
continue;
|
|
13
13
|
for (const method of [...definition.methods, ...definition.static.methods]) {
|
|
14
14
|
if (method.owner.ref.origin !== domain.origin || !method.executable) {
|
|
15
15
|
continue;
|
|
16
16
|
}
|
|
17
|
-
add(
|
|
17
|
+
paths.add(projectedMethodPath(domain, method));
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
return Object.freeze([...
|
|
20
|
+
return Object.freeze([...paths].sort(compare));
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
/** Sorted Paths of the Domain's authored Core Nodes. */
|
|
23
|
+
export function corePaths(domain) {
|
|
23
24
|
return Object.freeze(Object.values(domain.core.nodes)
|
|
24
25
|
.map((definition) => Path.project(definition.ref).raw)
|
|
25
|
-
.sort(
|
|
26
|
+
.sort(compare));
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
function compareNodePaths(left, right) {
|
|
28
|
+
/** Byte order of the UTF-8 encodings, independent of the host's string collation. */
|
|
29
|
+
function compare(left, right) {
|
|
31
30
|
const a = encoder.encode(left);
|
|
32
31
|
const b = encoder.encode(right);
|
|
33
32
|
const length = Math.min(a.length, b.length);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SourceDomain, schema } from '@astrale-os/kernel-dsl/v1';
|
|
2
2
|
import type { Projection, ProjectionTopology } from './types.js';
|
|
3
3
|
/** Project a Domain into an installation-independent symbolic graph. */
|
|
4
4
|
export declare function project(domain: SourceDomain<schema.DomainSchema>): Projection;
|