@astrale-os/kernel-core 0.9.0-beta.65 → 0.9.0-beta.67

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.
Files changed (115) hide show
  1. package/dist/auth/authority/admission/admission.d.ts +0 -1
  2. package/dist/auth/authority/admission/admission.js +8 -141
  3. package/dist/auth/authority/admission/references.d.ts +13 -0
  4. package/dist/auth/authority/admission/references.js +38 -0
  5. package/dist/auth/authority/admission/term.d.ts +6 -0
  6. package/dist/auth/authority/admission/term.js +60 -0
  7. package/dist/auth/authority/admission/wire.d.ts +8 -0
  8. package/dist/auth/authority/admission/wire.js +33 -0
  9. package/dist/auth/authority/semantics/interpret.d.ts +6 -0
  10. package/dist/auth/authority/semantics/interpret.js +187 -14
  11. package/dist/auth/authority/semantics/snapshot.d.ts +6 -0
  12. package/dist/graph/graph/index.d.ts +1 -1
  13. package/dist/graph/graph/index.js +1 -1
  14. package/dist/graph/graph/model/codec.js +3 -3
  15. package/dist/graph/graph/model/index.d.ts +1 -1
  16. package/dist/graph/graph/model/index.js +1 -1
  17. package/dist/graph/graph/model/model.d.ts +7 -7
  18. package/dist/graph/graph/model/model.js +6 -6
  19. package/dist/graph/graph/model/wire.d.ts +0 -20
  20. package/dist/graph/graph/model/wire.js +2 -2
  21. package/dist/graph/mutate/authoring/builder.d.ts +2 -2
  22. package/dist/graph/mutate/authoring/builder.js +2 -2
  23. package/dist/graph/mutate/index.d.ts +1 -1
  24. package/dist/graph/mutate/language/codec.js +3 -3
  25. package/dist/graph/mutate/language/model.d.ts +4 -4
  26. package/dist/graph/mutate/language/wire.d.ts +11 -0
  27. package/dist/graph/mutate/result/index.d.ts +4 -3
  28. package/dist/graph/mutate/result/index.js +8 -6
  29. package/dist/graph/mutate/result/wire.d.ts +1 -0
  30. package/dist/graph/mutate/result/wire.js +5 -2
  31. package/dist/graph/node/identity/id.d.ts +0 -3
  32. package/dist/graph/node/identity/id.js +0 -4
  33. package/dist/graph/node/identity/order.js +20 -0
  34. package/dist/graph/query/authoring/builder.js +29 -2
  35. package/dist/graph/query/authoring/model.d.ts +20 -1
  36. package/dist/graph/query/index.d.ts +3 -3
  37. package/dist/graph/query/index.js +1 -1
  38. package/dist/graph/query/language/codec.js +18 -3
  39. package/dist/graph/query/language/fingerprint.js +8 -0
  40. package/dist/graph/query/language/model.d.ts +22 -4
  41. package/dist/graph/query/language/wire.d.ts +11 -0
  42. package/dist/graph/query/language/wire.js +8 -1
  43. package/dist/graph/query/order/index.d.ts +8 -1
  44. package/dist/graph/query/order/index.js +20 -0
  45. package/dist/graph/query/reference/evaluate.js +5 -3
  46. package/dist/graph/reconcile/condition/model.d.ts +2 -2
  47. package/dist/graph/reconcile/condition/references.d.ts +0 -1
  48. package/dist/graph/reconcile/condition/references.js +4 -4
  49. package/dist/graph/reconcile/correspondence.d.ts +9 -8
  50. package/dist/graph/reconcile/evidence.d.ts +2 -2
  51. package/dist/graph/reconcile/mutation/assess.d.ts +2 -1
  52. package/dist/graph/reconcile/observation.d.ts +4 -3
  53. package/dist/graph/reconcile/planning/context.d.ts +3 -3
  54. package/dist/graph/reconcile/planning/model.d.ts +4 -4
  55. package/dist/schema/callables/{view-for.d.ts → entrypoint.d.ts} +7 -5
  56. package/dist/schema/callables/entrypoint.js +12 -0
  57. package/dist/schema/callables/function.d.ts +0 -120
  58. package/dist/schema/callables/index.d.ts +1 -1
  59. package/dist/schema/callables/index.js +1 -1
  60. package/dist/schema/callables/view.d.ts +2 -24
  61. package/dist/schema/domain/domain.d.ts +2 -121
  62. package/dist/schema/domain/domain.js +3 -0
  63. package/dist/schema/identity/identity.d.ts +0 -8
  64. package/dist/schema/kernel/projection/core.d.ts +7 -0
  65. package/dist/schema/kernel/projection/core.js +51 -0
  66. package/dist/schema/kernel/projection/definitions.d.ts +13 -0
  67. package/dist/schema/kernel/projection/definitions.js +71 -0
  68. package/dist/schema/kernel/projection/methods.d.ts +5 -0
  69. package/dist/schema/kernel/projection/methods.js +41 -0
  70. package/dist/schema/kernel/projection/part.d.ts +34 -0
  71. package/dist/schema/kernel/projection/part.js +42 -0
  72. package/dist/schema/kernel/projection/paths.d.ts +6 -0
  73. package/dist/schema/kernel/projection/{keys.js → paths.js} +11 -12
  74. package/dist/schema/kernel/projection/project.d.ts +1 -1
  75. package/dist/schema/kernel/projection/project.js +16 -290
  76. package/dist/schema/kernel/projection/properties.d.ts +11 -0
  77. package/dist/schema/kernel/projection/properties.js +36 -0
  78. package/dist/schema/kernel/projection/relations.d.ts +7 -0
  79. package/dist/schema/kernel/projection/relations.js +49 -0
  80. package/dist/schema/kernel/projection/types.d.ts +4 -4
  81. package/dist/schema/kernel/schema.d.ts +174 -409
  82. package/dist/schema/kernel/schema.js +3 -2
  83. package/dist/schema/kernel/syscalls/contracts/blob.d.ts +12 -2
  84. package/dist/schema/kernel/syscalls/contracts/blob.js +10 -2
  85. package/dist/schema/kernel/syscalls/contracts/delegate.d.ts +0 -4
  86. package/dist/schema/kernel/syscalls/contracts/delegate.js +0 -3
  87. package/dist/schema/kernel/syscalls/contracts/index.d.ts +1 -1
  88. package/dist/schema/kernel/syscalls/contracts/index.js +1 -1
  89. package/dist/schema/kernel/syscalls/contracts/install.d.ts +3 -20
  90. package/dist/schema/kernel/syscalls/contracts/install.js +0 -2
  91. package/dist/schema/kernel/syscalls/contracts/installation.d.ts +0 -36
  92. package/dist/schema/kernel/syscalls/contracts/installation.js +3 -3
  93. package/dist/schema/kernel/syscalls/contracts/mutate.d.ts +13 -0
  94. package/dist/schema/kernel/syscalls/contracts/mutate.js +2 -1
  95. package/dist/schema/kernel/syscalls/contracts/query.d.ts +11 -0
  96. package/dist/schema/kernel/syscalls/contracts/view-resolve.d.ts +3 -14
  97. package/dist/schema/kernel/syscalls/contracts/view-resolve.js +3 -18
  98. package/dist/schema/kernel/syscalls/declarations/delegate.d.ts +0 -4
  99. package/dist/schema/kernel/syscalls/declarations/download.d.ts +5 -0
  100. package/dist/schema/kernel/syscalls/declarations/index.d.ts +30 -24
  101. package/dist/schema/kernel/syscalls/declarations/install.d.ts +0 -8
  102. package/dist/schema/kernel/syscalls/declarations/mutate.d.ts +13 -0
  103. package/dist/schema/kernel/syscalls/declarations/query.d.ts +11 -0
  104. package/dist/schema/kernel/syscalls/declarations/view-resolve.d.ts +1 -12
  105. package/dist/schema/kernel/syscalls/descriptors/identity.d.ts +0 -4
  106. package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.d.ts +2 -13
  107. package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.js +4 -119
  108. package/dist/schema/kernel/syscalls/descriptors/view.d.ts +1 -12
  109. package/package.json +2 -2
  110. package/dist/schema/callables/view-for.js +0 -12
  111. package/dist/schema/kernel/projection/keys.d.ts +0 -3
  112. package/dist/schema/kernel/syscalls/contracts/legacy/delegate.d.ts +0 -5
  113. package/dist/schema/kernel/syscalls/contracts/legacy/delegate.js +0 -25
  114. package/dist/schema/kernel/syscalls/contracts/legacy/install.d.ts +0 -22
  115. package/dist/schema/kernel/syscalls/contracts/legacy/install.js +0 -31
@@ -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
- export function managedKeys(domain) {
5
- const keys = new Map();
6
- add(keys, Path.domain(domain.origin).raw);
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(keys, Path.project(definition.ref).raw);
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(keys, projectedMethodPath(domain, method));
17
+ paths.add(projectedMethodPath(domain, method));
18
18
  }
19
19
  }
20
- return Object.freeze([...keys.values()].sort(compareNodePaths));
20
+ return Object.freeze([...paths].sort(compare));
21
21
  }
22
- export function coreKeys(domain) {
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(compareNodePaths));
26
+ .sort(compare));
26
27
  }
27
- function add(keys, key) {
28
- keys.set(key, key);
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 { type SourceDomain, type schema } from '@astrale-os/kernel-dsl/v1';
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;
@@ -1,13 +1,9 @@
1
- import { Key, } from '@astrale-os/kernel-dsl/v1';
2
- import { ClassKey as ClassKeyValue } from '@astrale-os/kernel-dsl/v1/addressing';
3
- import { LocalBinding as LocalBindingValue } from '#graph/graph';
4
- import { NodePath as NodePathValue, Path as PathValue } from '#graph/path';
5
- import { normalizeProperties } from '#graph/properties';
6
- import { K } from '../index.js';
7
- import { projectedMethodPath } from './callables.js';
8
- import { ProjectionError } from './diagnostics.js';
9
- import { coreKeys, managedKeys } from './keys.js';
10
- const EMPTY_PROPERTIES = normalizeProperties({});
1
+ import { projectCore } from './core.js';
2
+ import { projectDefinitions, projectDomain } from './definitions.js';
3
+ import { projectMethods } from './methods.js';
4
+ import { Part } from './part.js';
5
+ import { corePaths, managedPaths } from './paths.js';
6
+ import { projectRelations } from './relations.js';
11
7
  const NO_PAYLOAD = Object.freeze({});
12
8
  /** Project a Domain into an installation-independent symbolic graph. */
13
9
  export function project(domain) {
@@ -30,289 +26,19 @@ export function project(domain) {
30
26
  export function projectTopology(domain) {
31
27
  return walk(domain, () => NO_PAYLOAD);
32
28
  }
29
+ /** Both projections take the same steps in the same order; only the payload differs. */
33
30
  function walk(domain, payload) {
34
- // Consume payloads in argument position, before addNode's duplicate/binding checks and
35
- // addEdge's Class conversion, preserving the full projection's original error order.
36
- const domainSchema = domain.source;
37
- const managedLocations = projectionLocations(managedKeys(domain));
38
- const coreLocations = projectionLocations(coreKeys(domain));
39
- const managedNodes = new Map();
40
- const managedEdges = [];
41
- const coreNodes = new Map();
42
- const coreEdges = [];
43
- const locators = [];
44
- const domainPath = PathValue.domain(domain.origin).raw;
45
- const domainEndpoint = endpoint(domainPath, managedLocations);
46
- const persistedDomainEndpoint = Object.freeze({ path: NodePathValue(domainPath) });
47
- addNode(managedNodes, domainPath, ClassKeyValue.of(K.classes.Domain.ref), payload(() => domainPropertiesFor(domain)), managedLocations);
48
- for (const definition of domain.definitions()) {
49
- if (definition.ref.origin !== domain.origin)
50
- continue;
51
- const projectedClass = projectionClassFor(definition);
52
- if (projectedClass === undefined)
53
- continue;
54
- const definitionPath = PathValue.project(definition.ref).raw;
55
- const definitionEndpoint = addNode(managedNodes, definitionPath, projectedClass, payload(() => definitionPropertiesFor(definition)), managedLocations);
56
- addEdge(managedEdges, definitionEndpoint, domainEndpoint, K.classes.of_domain.ref, payload(() => normalizeProperties({
57
- [K.classes.of_domain.self.properties.member.key]: memberKey(definition),
58
- })));
59
- }
60
- for (const definition of domain.definitions()) {
61
- if (definition.ref.origin !== domain.origin)
62
- continue;
63
- const projectedClass = projectionClassFor(definition);
64
- if (projectedClass === undefined)
65
- continue;
66
- projectDefinitionRelations(domain, definition, endpoint(PathValue.project(definition.ref).raw, managedLocations), managedLocations, managedEdges, payload);
67
- }
68
- const methods = new Map();
69
- for (const definition of Object.values(domain.classes)) {
70
- for (const method of [...definition.methods, ...definition.static.methods]) {
71
- if (method.owner.ref.origin === domain.origin && method.executable) {
72
- methods.set(method.key, method);
73
- }
74
- }
75
- }
76
- for (const method of methods.values()) {
77
- const methodPath = projectedMethodPath(domain, method);
78
- const methodEndpoint = addNode(managedNodes, methodPath, ClassKeyValue.of(K.classes.Function.ref), payload(() => callablePropertiesFor(method.definition)), managedLocations);
79
- const ownerPath = PathValue.project(method.owner.ref);
80
- addEdge(managedEdges, methodEndpoint, endpoint(ownerPath.raw, managedLocations), K.classes.method_of.ref, payload(() => normalizeProperties({
81
- [K.classes.method_of.self.properties.name.key]: method.name,
82
- [K.classes.method_of.self.properties.static.key]: method.definition.static,
83
- })));
84
- // This structural check must also execute when no Property payload is requested.
85
- const member = callableMemberKey(domain, method);
86
- addEdge(managedEdges, methodEndpoint, domainEndpoint, K.classes.of_domain.ref, payload(() => normalizeProperties({
87
- [K.classes.of_domain.self.properties.member.key]: member,
88
- })));
89
- }
90
- for (const [slug, declaration] of Object.entries(domainSchema.core.nodes)) {
91
- assertIdentityAuthenticationUnowned(domain, declaration.class, declaration.properties, slug);
92
- const path = PathValue.project({ origin: domain.origin, kind: 'core', name: slug }).raw;
93
- const created = addNode(coreNodes, path, ClassKeyValue.of(declaration.class), payload(() => declaration.properties), coreLocations);
94
- addEdge(locators, created, persistedDomainEndpoint, K.classes.of_domain.ref, payload(() => normalizeProperties({
95
- [K.classes.of_domain.self.properties.member.key]: `core.${slug}`,
96
- })));
97
- }
98
- // Resolved edges carry each endpoint's own identity; the source IR only names it.
99
- for (const edge of domain.core.edges) {
100
- addEdge(coreEdges, coreEndpoint(edge.source, domain, persistedDomainEndpoint, coreLocations), coreEndpoint(edge.target, domain, persistedDomainEndpoint, coreLocations), edge.class.ref, payload(() => edge.properties));
101
- }
31
+ const managed = new Part(managedPaths(domain));
32
+ const core = new Part(corePaths(domain));
33
+ const domainEndpoint = projectDomain(domain, managed, payload);
34
+ projectDefinitions(domain, managed, domainEndpoint, payload);
35
+ projectRelations(domain, managed, payload);
36
+ projectMethods(domain, managed, domainEndpoint, payload);
37
+ const locators = projectCore(domain, core, payload);
102
38
  return Object.freeze({
103
39
  origin: domain.origin,
104
40
  revision: domain.revision,
105
- managed: Object.freeze({
106
- nodes: Object.freeze([...managedNodes.values()]),
107
- edges: Object.freeze(managedEdges),
108
- paths: invert(managedLocations),
109
- }),
110
- core: Object.freeze({
111
- nodes: Object.freeze([...coreNodes.values()]),
112
- edges: Object.freeze(coreEdges),
113
- paths: invert(coreLocations),
114
- locators: Object.freeze(locators),
115
- }),
41
+ managed: managed.done(),
42
+ core: Object.freeze({ ...core.done(), locators: Object.freeze(locators) }),
116
43
  });
117
44
  }
118
- function assertIdentityAuthenticationUnowned(domain, classRef, properties, slug) {
119
- const definition = domain.definition(classRef);
120
- if (definition?.ref.kind !== 'class' ||
121
- definition.kind !== 'node' ||
122
- !definition.satisfies(K.classes.Identity)) {
123
- return;
124
- }
125
- const hasIssuer = Object.hasOwn(properties, K.classes.Identity.properties.iss.key);
126
- const hasSubject = Object.hasOwn(properties, K.classes.Identity.properties.sub.key);
127
- if (hasIssuer || hasSubject) {
128
- throw new ProjectionError('PROJECTION_INVALID', `Core Identity ${domain.origin}:core.${slug} cannot declare protected Authentication properties iss or sub.`);
129
- }
130
- }
131
- function projectionLocations(paths) {
132
- return new Map(paths.map((path, index) => [NodePathValue(path), LocalBindingValue(`n${index}`)]));
133
- }
134
- function invert(locations) {
135
- return new Map([...locations].map(([path, binding]) => [binding, path]));
136
- }
137
- /**
138
- * A Core Node binds inside the Core part; every other local Definition is already projected as a
139
- * managed declaration, so it is addressed by its canonical Path exactly like the owning Domain.
140
- */
141
- function coreEndpoint(value, domain, domainEndpoint, locations) {
142
- if ('ref' in value)
143
- return endpoint(PathValue.project(value.ref).raw, locations);
144
- if ('owner' in value)
145
- return endpoint(projectedMethodPath(domain, value), locations);
146
- return domainEndpoint;
147
- }
148
- function projectDefinitionRelations(domain, definition, definitionEndpoint, locations, edges, payload) {
149
- if (isResolvedClass(definition)) {
150
- for (const parent of definition.definition.extends) {
151
- const path = PathValue.project(parent);
152
- addEdge(edges, definitionEndpoint, endpoint(path.raw, locations), K.classes.extends.ref, payload(() => EMPTY_PROPERTIES));
153
- }
154
- }
155
- if (isResolvedClass(definition)) {
156
- const declaration = definition.definition;
157
- const assignments = [
158
- ['read', declaration.policies.read],
159
- ['traverse', declaration.policies.traverse],
160
- ];
161
- const policies = new Map();
162
- for (const [operation, policy] of assignments) {
163
- if (policy === undefined)
164
- continue;
165
- const key = Key.of(policy);
166
- const existing = policies.get(key);
167
- if (existing === undefined) {
168
- policies.set(key, { policy, operations: new Set([operation]) });
169
- }
170
- else {
171
- existing.operations.add(operation);
172
- }
173
- }
174
- for (const { policy, operations } of policies.values()) {
175
- addEdge(edges, definitionEndpoint, endpoint(PathValue.project(policy).raw, locations), K.classes.governed_by.ref, payload(() => normalizeProperties({
176
- [K.classes.governed_by.self.properties.operations.key]: Object.freeze(['read', 'traverse'].filter((operation) => operations.has(operation))),
177
- })));
178
- }
179
- }
180
- if (isResolvedView(definition)) {
181
- const target = definition.definition.target;
182
- const paths = target.kind === 'domain'
183
- ? [PathValue.domain(domain.origin)]
184
- : target.definitions.map((reference) => {
185
- if (reference.kind !== 'class') {
186
- throw new ProjectionError('PROJECTION_INVALID', `View target ${reference.origin}:${reference.kind}.${reference.name} is not a Class.`);
187
- }
188
- return PathValue.project({
189
- origin: reference.origin,
190
- kind: 'class',
191
- name: reference.name,
192
- });
193
- });
194
- for (const path of paths) {
195
- addEdge(edges, definitionEndpoint, endpoint(path.raw, locations), K.classes.view_for.ref, payload(() => EMPTY_PROPERTIES));
196
- }
197
- }
198
- }
199
- function projectionClassFor(definition) {
200
- if (definition.ref.kind === 'class')
201
- return ClassKeyValue.of(K.classes.Class.ref);
202
- switch (definition.ref.kind) {
203
- case 'function':
204
- return ClassKeyValue.of(K.classes.Function.ref);
205
- case 'policy':
206
- return ClassKeyValue.of(K.classes.Policy.ref);
207
- case 'view':
208
- return ClassKeyValue.of(K.classes.View.ref);
209
- case 'core':
210
- return undefined;
211
- default:
212
- return undefined;
213
- }
214
- }
215
- function definitionPropertiesFor(definition) {
216
- const description = declarationDescription(definition);
217
- const metadata = descriptionProperties(description);
218
- if (isResolvedClass(definition)) {
219
- const declaration = definition.definition;
220
- const icon = declaration.kind === 'node' ? declaration.icon : undefined;
221
- return normalizeProperties({
222
- ...metadata,
223
- [K.classes.Class.self.properties.kind.key]: declaration.kind,
224
- [K.classes.Class.self.properties.abstract.key]: declaration.abstract,
225
- ...(icon !== undefined ? { [K.classes.Iconable.self.properties.icon.key]: icon } : {}),
226
- });
227
- }
228
- if (isResolvedFunction(definition)) {
229
- return callablePropertiesFor(definition.definition);
230
- }
231
- if (definition.ref.kind === 'view') {
232
- return normalizeProperties(metadata);
233
- }
234
- if (definition.ref.kind === 'policy')
235
- return normalizeProperties(metadata);
236
- return EMPTY_PROPERTIES;
237
- }
238
- function isResolvedClass(definition) {
239
- return definition.ref.kind === 'class';
240
- }
241
- function isResolvedFunction(definition) {
242
- return definition.ref.kind === 'function';
243
- }
244
- function isResolvedView(definition) {
245
- return definition.ref.kind === 'view';
246
- }
247
- function callablePropertiesFor(declaration) {
248
- const method = 'static' in declaration;
249
- return normalizeProperties({
250
- ...descriptionProperties(declaration.description),
251
- [K.classes.Function.self.properties.kind.key]: method ? 'method' : 'function',
252
- [K.classes.Function.self.properties.input.key]: declaration.input,
253
- [K.classes.Function.self.properties.output.key]: declaration.output,
254
- [K.classes.Function.self.properties.auth.key]: declaration.auth,
255
- ...(declaration.policy === undefined
256
- ? {}
257
- : {
258
- [K.classes.Function.self.properties.policy.key]: declaration.policy,
259
- }),
260
- ...(method
261
- ? {
262
- [K.classes.Function.self.properties.static.key]: declaration.static,
263
- [K.classes.Function.self.properties.abstract.key]: declaration.abstract,
264
- }
265
- : {}),
266
- });
267
- }
268
- function descriptionProperties(description) {
269
- if (description === undefined)
270
- return {};
271
- return { [K.classes.Descriptable.self.properties.description.key]: description };
272
- }
273
- function declarationDescription(definition) {
274
- if (definition.ref.kind === 'core')
275
- return undefined;
276
- return definition.definition.description;
277
- }
278
- function memberKey(definition) {
279
- return `${definition.ref.kind}.${definition.ref.name}`;
280
- }
281
- function callableMemberKey(domain, method) {
282
- const prefix = `${domain.origin}:`;
283
- if (!method.key.startsWith(prefix)) {
284
- throw new ProjectionError('PROJECTION_INVALID', 'Method key belongs to another Domain.');
285
- }
286
- return method.key.slice(prefix.length);
287
- }
288
- /** Identity properties are supplied atomically by trusted lifecycle materialization. */
289
- function domainPropertiesFor(domain) {
290
- return normalizeProperties({
291
- [K.classes.Domain.self.properties.origin.key]: domain.origin,
292
- [K.classes.Domain.self.properties.schema.key]: domain.source,
293
- [K.classes.Domain.self.properties.schemaRevision.key]: domain.revision,
294
- });
295
- }
296
- function endpoint(path, locations) {
297
- const created = locations.get(path);
298
- return created === undefined ? Object.freeze({ path }) : Object.freeze({ created });
299
- }
300
- function addNode(nodes, path, classKey, payload, locations) {
301
- const existing = nodes.get(path);
302
- if (existing !== undefined)
303
- return Object.freeze({ created: existing.as });
304
- const as = locations.get(path);
305
- if (as === undefined) {
306
- throw new ProjectionError('PROJECTION_INVALID', `Projection has no binding for ${path}.`);
307
- }
308
- nodes.set(path, Object.freeze({ as, class: classKey, ...payload }));
309
- return Object.freeze({ created: as });
310
- }
311
- function addEdge(edges, source, target, classRef, payload) {
312
- edges.push(Object.freeze({
313
- source,
314
- target,
315
- class: ClassKeyValue.of(classRef),
316
- ...payload,
317
- }));
318
- }
@@ -0,0 +1,11 @@
1
+ import type { FunctionDefinition, MethodDefinition } from '@astrale-os/kernel-dsl/v1';
2
+ import type * as portable from '@astrale-os/kernel-dsl/value';
3
+ import { type Properties } from '#graph/properties';
4
+ /** The Properties of a declaration or relation that carries none. */
5
+ export declare const EMPTY_PROPERTIES: import("@astrale-os/kernel-dsl/v1").PropertyValues;
6
+ /** The of_domain Properties locating a declaration under its Domain member name. */
7
+ export declare function memberProperties(member: string): Properties;
8
+ /** The Descriptable Property of an authored description, if any. */
9
+ export declare function descriptionProperties(description: string | undefined): Record<string, portable.Value>;
10
+ /** The Function Node Properties carrying a Function's or Method's complete callable contract. */
11
+ export declare function callableProperties(declaration: FunctionDefinition | MethodDefinition): Properties;
@@ -0,0 +1,36 @@
1
+ import { normalizeProperties } from '#graph/properties';
2
+ import { K } from '../index.js';
3
+ /** The Properties of a declaration or relation that carries none. */
4
+ export const EMPTY_PROPERTIES = normalizeProperties({});
5
+ /** The of_domain Properties locating a declaration under its Domain member name. */
6
+ export function memberProperties(member) {
7
+ return normalizeProperties({ [K.classes.of_domain.self.properties.member.key]: member });
8
+ }
9
+ /** The Descriptable Property of an authored description, if any. */
10
+ export function descriptionProperties(description) {
11
+ if (description === undefined)
12
+ return {};
13
+ return { [K.classes.Descriptable.self.properties.description.key]: description };
14
+ }
15
+ /** The Function Node Properties carrying a Function's or Method's complete callable contract. */
16
+ export function callableProperties(declaration) {
17
+ const method = 'static' in declaration;
18
+ return normalizeProperties({
19
+ ...descriptionProperties(declaration.description),
20
+ [K.classes.Function.self.properties.kind.key]: method ? 'method' : 'function',
21
+ [K.classes.Function.self.properties.input.key]: declaration.input,
22
+ [K.classes.Function.self.properties.output.key]: declaration.output,
23
+ [K.classes.Function.self.properties.auth.key]: declaration.auth,
24
+ ...(declaration.policy === undefined
25
+ ? {}
26
+ : {
27
+ [K.classes.Function.self.properties.policy.key]: declaration.policy,
28
+ }),
29
+ ...(method
30
+ ? {
31
+ [K.classes.Function.self.properties.static.key]: declaration.static,
32
+ [K.classes.Function.self.properties.abstract.key]: declaration.abstract,
33
+ }
34
+ : {}),
35
+ });
36
+ }
@@ -0,0 +1,7 @@
1
+ import { type SourceDomain, type schema } from '@astrale-os/kernel-dsl/v1';
2
+ import { type Part, type Payload } from './part.js';
3
+ /**
4
+ * Relate each local Definition to its parent Classes and governing Policies, and the entrypoint
5
+ * View to its Domain.
6
+ */
7
+ export declare function projectRelations<Extra extends object>(domain: SourceDomain<schema.DomainSchema>, managed: Part<Extra>, payload: Payload<Extra>): void;
@@ -0,0 +1,49 @@
1
+ import { Key, } from '@astrale-os/kernel-dsl/v1';
2
+ import { Path } from '#graph/path';
3
+ import { normalizeProperties } from '#graph/properties';
4
+ import { K } from '../index.js';
5
+ import { is, projectedDefinitions } from './definitions.js';
6
+ import { edge } from './part.js';
7
+ import { EMPTY_PROPERTIES } from './properties.js';
8
+ const OPERATIONS = ['read', 'traverse'];
9
+ /**
10
+ * Relate each local Definition to its parent Classes and governing Policies, and the entrypoint
11
+ * View to its Domain.
12
+ */
13
+ export function projectRelations(domain, managed, payload) {
14
+ for (const [definition] of projectedDefinitions(domain)) {
15
+ const source = managed.endpoint(Path.project(definition.ref).raw);
16
+ const relate = (target, classRef, extra) => managed.edges.push(edge(source, managed.endpoint(target), classRef, extra));
17
+ if (is(definition, 'class')) {
18
+ for (const parent of definition.definition.extends) {
19
+ relate(Path.project(parent).raw, K.classes.extends.ref, payload(() => EMPTY_PROPERTIES));
20
+ }
21
+ for (const [policy, operations] of governingPolicies(definition)) {
22
+ relate(Path.project(policy).raw, K.classes.governed_by.ref, payload(() => normalizeProperties({
23
+ [K.classes.governed_by.self.properties.operations.key]: operations,
24
+ })));
25
+ }
26
+ }
27
+ // The one entrypoint View links to its own Domain; other Views relate to it only by of_domain.
28
+ if (is(definition, 'view') && domain.source.entrypoint?.name === definition.ref.name) {
29
+ relate(Path.domain(domain.origin).raw, K.classes.entrypoint.ref, payload(() => EMPTY_PROPERTIES));
30
+ }
31
+ }
32
+ }
33
+ /** Each distinct Policy of a Class, with the operations it governs in canonical order. */
34
+ function governingPolicies(definition) {
35
+ const policies = definition.definition.policies;
36
+ const grouped = new Map();
37
+ for (const operation of OPERATIONS) {
38
+ const policy = policies[operation];
39
+ if (policy === undefined)
40
+ continue;
41
+ const key = Key.of(policy);
42
+ const existing = grouped.get(key);
43
+ if (existing === undefined)
44
+ grouped.set(key, { policy, operations: [operation] });
45
+ else
46
+ existing.operations.push(operation);
47
+ }
48
+ return [...grouped.values()].map(({ policy, operations }) => [policy, Object.freeze(operations)]);
49
+ }
@@ -1,11 +1,11 @@
1
1
  import type { Key, Revision } from '@astrale-os/kernel-dsl/v1';
2
2
  import type { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
3
- import type { GraphSpec, GraphSpecEdge, GraphSpecEndpoint, LocalBinding } from '#graph/graph';
3
+ import type { GraphSpec, GraphSpecEdge, GraphSpecEndpoint, LocalAlias } from '#graph/graph';
4
4
  import type { NodePath } from '#graph/path';
5
5
  export interface ProjectionPart {
6
6
  readonly graph: GraphSpec;
7
7
  /** Canonical locator of every anonymous Node declared by the projection. */
8
- readonly paths: ReadonlyMap<LocalBinding, NodePath>;
8
+ readonly paths: ReadonlyMap<LocalAlias, NodePath>;
9
9
  }
10
10
  export interface CoreProjection extends ProjectionPart {
11
11
  /** Runtime-owned locator relations that associate authored Core Nodes with their Domain. */
@@ -19,7 +19,7 @@ export interface Projection {
19
19
  }
20
20
  /** Declaration identity only; this is not a Graph Node with absent or defaulted Properties. */
21
21
  export interface ProjectionTopologyNode {
22
- readonly as: LocalBinding;
22
+ readonly as: LocalAlias;
23
23
  readonly class: ClassKey;
24
24
  }
25
25
  export interface ProjectionTopologyEdge {
@@ -28,7 +28,7 @@ export interface ProjectionTopologyEdge {
28
28
  readonly class: ClassKey;
29
29
  }
30
30
  export interface ProjectionTopologyPart {
31
- readonly paths: ReadonlyMap<LocalBinding, NodePath>;
31
+ readonly paths: ReadonlyMap<LocalAlias, NodePath>;
32
32
  readonly nodes: readonly ProjectionTopologyNode[];
33
33
  readonly edges: readonly ProjectionTopologyEdge[];
34
34
  }