@astrale-os/kernel-dsl 1.0.0-beta.13 → 1.0.0-beta.15
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/v1/addressing/domain-dependency.d.ts +0 -6
- package/dist/v1/addressing/domain-dependency.js +1 -6
- package/dist/v1/addressing/key.js +2 -1
- package/dist/v1/addressing/patterns.d.ts +1 -0
- package/dist/v1/addressing/patterns.js +2 -1
- package/dist/v1/builder/class/authoring.d.ts +43 -0
- package/dist/v1/builder/class/property.d.ts +3 -9
- package/dist/v1/builder/class/property.js +1 -0
- package/dist/v1/builder/index.d.ts +1 -1
- package/dist/v1/builder/lowering/class.js +5 -1
- package/dist/v1/builder/lowering/policy.js +2 -0
- package/dist/v1/builder/lowering/schema/context.d.ts +5 -0
- package/dist/v1/builder/lowering/schema/context.js +22 -0
- package/dist/v1/builder/policy/authoring.d.ts +84 -4
- package/dist/v1/builder/policy/authoring.js +44 -14
- package/dist/v1/builder/schema/projection/class.d.ts +116 -14
- package/dist/v1/bundle/codec.js +9 -9
- package/dist/v1/bundle/diagnostic.d.ts +2 -0
- package/dist/v1/bundle/diagnostic.js +6 -0
- package/dist/v1/bundle/structure.js +2 -2
- package/dist/v1/compiled/admission/accept.js +3 -3
- package/dist/v1/compiled/admission/closure.js +2 -2
- package/dist/v1/compiled/admission/semantics/core.js +3 -7
- package/dist/v1/compiled/admission/semantics/policy/parity.js +3 -10
- package/dist/v1/domain/validation/create.d.ts +4 -1
- package/dist/v1/domain/validation/create.js +21 -34
- package/dist/v1/language/.spec/schemas/value-schema.schema.json +22 -0
- package/dist/v1/language/class/model/class.d.ts +4 -4
- package/dist/v1/language/class/model/edge.d.ts +2 -2
- package/dist/v1/language/class/model/property.d.ts +16 -7
- package/dist/v1/language/core/facts.d.ts +17 -4
- package/dist/v1/language/core/facts.js +26 -5
- package/dist/v1/language/definition/metadata.d.ts +5 -0
- package/dist/v1/language/definition/metadata.js +7 -0
- package/dist/v1/language/limits.d.ts +64 -0
- package/dist/v1/language/limits.js +60 -0
- package/dist/v1/language/policy/analysis/budgets.d.ts +39 -18
- package/dist/v1/language/policy/analysis/budgets.js +30 -20
- package/dist/v1/language/policy/analysis/checks.js +3 -2
- package/dist/v1/language/policy/analysis/typing.js +4 -3
- package/dist/v1/language/policy/model/policy.d.ts +5 -5
- package/dist/v1/language/policy/normalization/normalize.js +17 -16
- package/dist/v1/language/validation/diagnostic.d.ts +1 -1
- package/dist/v1/language/validation/rule.d.ts +29 -0
- package/dist/v1/language/validation/rule.js +120 -0
- package/dist/v1/language/value/profile/meta-schema.compiled.js +4 -1
- package/dist/v1/language/value/profile/rules.js +13 -37
- package/dist/v1/language/value/profile/vocabulary.d.ts +35 -2
- package/dist/v1/language/value/profile/vocabulary.js +52 -5
- package/dist/v1/language/value/reference/registry.index.js +2 -1
- package/dist/v1/language/value/regexp/ast.js +6 -7
- package/dist/v1/language/value/regexp/compile.d.ts +5 -11
- package/dist/v1/language/value/regexp/compile.js +14 -12
- package/dist/v1/language/value/regexp/syntax.js +3 -2
- package/dist/v1/language/value/syntax/keywords.d.ts +3 -3
- package/dist/v1/language/value/syntax/keywords.js +4 -20
- package/dist/v1/language/value/syntax/node-path/validate.js +2 -3
- package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +2336 -0
- package/dist/v1/schema/admission/accept.js +3 -14
- package/dist/v1/schema/admission/callable.d.ts +21 -0
- package/dist/v1/schema/admission/callable.js +96 -0
- package/dist/v1/schema/analysis/class.js +33 -15
- package/dist/v1/schema/compatibility/api.d.ts +1 -1
- package/dist/v1/schema/compatibility/coordinate.js +3 -3
- package/dist/v1/schema/compatibility/model.d.ts +5 -0
- package/dist/v1/schema/diagnostic.d.ts +17 -3
- package/dist/v1/schema/diagnostic.js +11 -0
- package/dist/v1/schema/index.d.ts +10 -1
- package/dist/v1/schema/index.js +4 -0
- package/dist/v1/schema/model/schema.d.ts +19 -1
- package/dist/v1/schema/normalization/domain.d.ts +2 -0
- package/dist/v1/schema/normalization/domain.js +2 -1
- package/dist/v1/schema/resolution/closure.js +2 -1
- package/dist/v1/schema/resolution/context.js +10 -8
- package/dist/v1/schema/resolution/domain.d.ts +5 -0
- package/dist/v1/schema/resolution/domain.js +1 -1
- package/dist/v1/schema/rule.d.ts +32 -0
- package/dist/v1/schema/rule.js +428 -0
- package/dist/v1/schema/validation/callable.d.ts +35 -2
- package/dist/v1/schema/validation/callable.js +51 -8
- package/dist/v1/schema/validation/class.js +36 -44
- package/dist/v1/schema/validation/core.js +19 -13
- package/dist/v1/schema/validation/domain.js +2 -2
- package/dist/v1/schema/validation/domain.json-schema.d.ts +15 -0
- package/dist/v1/schema/validation/domain.json-schema.js +183 -0
- package/dist/v1/schema/validation/domain.route.d.ts +6 -1
- package/dist/v1/schema/validation/domain.route.js +18 -0
- package/dist/v1/schema/validation/domain.structure.d.ts +4020 -0
- package/dist/v1/schema/validation/domain.structure.js +359 -153
- package/dist/v1/schema/validation/json.json-schema.d.ts +24 -0
- package/dist/v1/schema/validation/json.json-schema.js +36 -0
- package/dist/v1/schema/validation/policy/budgets.d.ts +33 -2
- package/dist/v1/schema/validation/policy/budgets.js +89 -16
- package/dist/v1/schema/validation/policy/references.js +6 -21
- package/dist/v1/schema/validation/policy/uses.d.ts +29 -0
- package/dist/v1/schema/validation/policy/uses.js +28 -51
- package/dist/v1/schema/validation/value-api.d.ts +12 -1
- package/dist/v1/schema/validation/value-api.js +10 -1
- package/dist/v1/schema/validation/value.d.ts +3 -0
- package/dist/v1/schema/validation/value.js +6 -12
- package/dist/v1/schema/validation/value.json-schema.d.ts +51 -0
- package/dist/v1/schema/validation/value.json-schema.js +126 -0
- package/package.json +3 -1
|
@@ -1,13 +1,119 @@
|
|
|
1
1
|
import type * as language from '../../../language/index.js';
|
|
2
|
+
import type { DomainSchema, DomainOfSchema } from '../../../schema/model/schema.js';
|
|
2
3
|
import type { NodeClass, DirectedEdgeClass, UndirectedEdgeClass, Class, ProjectionOfClass } from '../../class/handle.js';
|
|
3
4
|
import type { ClassReferenceProjection } from '../../class/projection.js';
|
|
4
5
|
import type { DomainSchemaInput } from '../input.js';
|
|
5
6
|
import type { OwnInstanceMethodProjectionsOf, OwnStaticMethodProjectionsOf } from './callable.js';
|
|
6
|
-
import type { AbstractOf, ConstraintsOf, ResolveLazy, LocalNameOfReference, ClassesInputOf, LocalNameOf } from './identity.js';
|
|
7
|
+
import type { AbstractOf, ConstraintsOf, ResolveLazy, LocalNameOfReference, ClassesInputOf, LocalNameOf, RecordField } from './identity.js';
|
|
7
8
|
import type { ClassProjection } from './model.js';
|
|
8
9
|
import type { EffectivePropertyProjectionsOf, OwnPropertyProjectionsOf } from './property.js';
|
|
9
10
|
import type { ClassProjectionOfResolved, ExactClass } from './resolved-class.js';
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A Class an endpoint accepts as the Schema names it: an authored Class by the ref of every Class
|
|
13
|
+
* that bears its mark, else the ref it carries.
|
|
14
|
+
*/
|
|
15
|
+
type AcceptedRefOf<Origin extends string, Reference, Root extends DomainSchemaInput> = Reference extends unknown ? ResolveLazy<Reference> extends infer Resolved ? Resolved extends {
|
|
16
|
+
readonly kind: 'node';
|
|
17
|
+
} ? MarkedClassRefOf<Origin, Resolved, Root> : Resolved extends {
|
|
18
|
+
readonly origin: infer RefOrigin extends string;
|
|
19
|
+
readonly kind: 'class';
|
|
20
|
+
readonly name: infer RefName extends string;
|
|
21
|
+
} ? language.ClassRef<RefName> & {
|
|
22
|
+
readonly origin: RefOrigin;
|
|
23
|
+
} : language.ClassRef : never : never;
|
|
24
|
+
/** The mark the class authoring module gives an accepted Node Class (`AcceptedClassMark`). */
|
|
25
|
+
type ClassMarkOf<Value> = Value extends NodeClass<infer Config> ? {
|
|
26
|
+
readonly kind: 'node';
|
|
27
|
+
readonly abstract: Config extends {
|
|
28
|
+
readonly abstract: infer Abstract;
|
|
29
|
+
} ? Abstract : never;
|
|
30
|
+
readonly depth: Config extends {
|
|
31
|
+
readonly depth: infer Depth;
|
|
32
|
+
} ? Depth : never;
|
|
33
|
+
readonly properties: Config extends {
|
|
34
|
+
readonly effectiveProperties: infer Properties;
|
|
35
|
+
} ? Properties extends {
|
|
36
|
+
readonly name: infer Name;
|
|
37
|
+
} ? Name : never : never;
|
|
38
|
+
readonly methods: Config extends {
|
|
39
|
+
readonly effectiveInstanceMethods: infer Instance;
|
|
40
|
+
readonly effectiveStaticMethods: infer Static;
|
|
41
|
+
} ? Instance | Static extends infer Method ? Method extends {
|
|
42
|
+
readonly name: infer Name;
|
|
43
|
+
} ? Name : never : never : never;
|
|
44
|
+
} : never;
|
|
45
|
+
type Same<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false;
|
|
46
|
+
/** Every local Class name whose mark is the accepted mark. */
|
|
47
|
+
type LocalNameOfMark<Root extends DomainSchemaInput, Mark> = {
|
|
48
|
+
[Name in keyof ClassesInputOf<Root>]: Same<ClassMarkOf<ClassesInputOf<Root>[Name]>, Mark> extends true ? Name : never;
|
|
49
|
+
}[keyof ClassesInputOf<Root>];
|
|
50
|
+
/**
|
|
51
|
+
* Every Class an authored handle bearing the mark may be: the builder resolves the handle of a
|
|
52
|
+
* Class of the Schema or of a direct dependency, so either may bear it. The ref stays broad when no
|
|
53
|
+
* Class bears it or a dependency's Classes are not named in the types.
|
|
54
|
+
*/
|
|
55
|
+
type MarkedClassRefOf<Origin extends string, Mark, Root extends DomainSchemaInput> = LocalClassRefOf<Origin, LocalNameOfMark<Root, Mark>> | DependencyClassRefOfMark<Root, Mark> extends infer Refs ? [Refs] extends [never] ? language.ClassRef : Refs : never;
|
|
56
|
+
type LocalClassRefOf<Origin extends string, Name> = Name extends string ? language.ClassRef<Name> & {
|
|
57
|
+
readonly origin: Origin;
|
|
58
|
+
} : never;
|
|
59
|
+
/** The names of the members of a resolved collection. */
|
|
60
|
+
type MemberNamesOf<Collection> = Collection extends {
|
|
61
|
+
readonly byKey: infer ByKey;
|
|
62
|
+
} ? ByKey[keyof ByKey] extends infer Member ? Member extends {
|
|
63
|
+
readonly name: infer Name;
|
|
64
|
+
} ? Name : never : never : never;
|
|
65
|
+
/**
|
|
66
|
+
* A dependency Class may bear a mark when it agrees with it in abstractness and the names of its
|
|
67
|
+
* effective Properties, and its own Methods are among the mark's. Its resolved type keeps neither
|
|
68
|
+
* its depth nor the abstract Methods it inherits, so neither is compared.
|
|
69
|
+
*/
|
|
70
|
+
type ResolvedBearsMark<Value, Mark> = Value extends {
|
|
71
|
+
readonly kind: 'node';
|
|
72
|
+
readonly definition: {
|
|
73
|
+
readonly abstract: infer Abstract;
|
|
74
|
+
};
|
|
75
|
+
readonly properties: infer Properties;
|
|
76
|
+
readonly methods: infer Methods;
|
|
77
|
+
readonly static: {
|
|
78
|
+
readonly methods: infer StaticMethods;
|
|
79
|
+
};
|
|
80
|
+
} ? Mark extends {
|
|
81
|
+
readonly abstract: infer MarkAbstract;
|
|
82
|
+
readonly properties: infer MarkProperties;
|
|
83
|
+
readonly methods: infer MarkMethods;
|
|
84
|
+
} ? Same<{
|
|
85
|
+
readonly abstract: Abstract;
|
|
86
|
+
readonly properties: MemberNamesOf<Properties>;
|
|
87
|
+
}, {
|
|
88
|
+
readonly abstract: MarkAbstract;
|
|
89
|
+
readonly properties: MarkProperties;
|
|
90
|
+
}> extends true ? [MemberNamesOf<Methods> | MemberNamesOf<StaticMethods>] extends [MarkMethods] ? true : false : false : false : false;
|
|
91
|
+
/** Every Node Class of a direct dependency that may bear the mark. */
|
|
92
|
+
type DependencyClassRefOfMark<Root extends DomainSchemaInput, Mark> = {
|
|
93
|
+
[Alias in keyof RecordField<Root, 'dependencies'>]: RecordField<Root, 'dependencies'>[Alias] extends infer Schema extends DomainSchema ? DomainOfSchema<Schema>['classes'] extends infer Classes ? string extends keyof Classes ? language.ClassRef : {
|
|
94
|
+
[Name in keyof Classes]: ResolvedBearsMark<Classes[Name], Mark> extends true ? Classes[Name] extends {
|
|
95
|
+
readonly ref: {
|
|
96
|
+
readonly origin: infer RefOrigin extends string;
|
|
97
|
+
readonly name: infer RefName extends string;
|
|
98
|
+
};
|
|
99
|
+
} ? language.ClassRef<RefName> & {
|
|
100
|
+
readonly origin: RefOrigin;
|
|
101
|
+
} : never : never;
|
|
102
|
+
}[keyof Classes] : never : never;
|
|
103
|
+
}[keyof RecordField<Root, 'dependencies'>];
|
|
104
|
+
/** Every Class an endpoint accepts, in any order: the runtime list is canonically sorted. */
|
|
105
|
+
type AcceptedRefsOf<Origin extends string, Accepts, Root extends DomainSchemaInput> = Accepts extends readonly (infer Reference)[] ? readonly [AcceptedRefOf<Origin, Reference, Root>, ...AcceptedRefOf<Origin, Reference, Root>[]] : readonly [language.ClassRef, ...language.ClassRef[]];
|
|
106
|
+
/** One endpoint as the Schema stores it: its role and its exact accepted Classes. */
|
|
107
|
+
type ProjectedEndpoint<Origin extends string, Endpoint, Root extends DomainSchemaInput> = Endpoint extends {
|
|
108
|
+
readonly as: infer Role;
|
|
109
|
+
readonly accepts: infer Accepts;
|
|
110
|
+
} ? {
|
|
111
|
+
readonly role: Role;
|
|
112
|
+
readonly accepts: AcceptedRefsOf<Origin, Accepts, Root>;
|
|
113
|
+
readonly onDelete?: language.EdgeLifetime;
|
|
114
|
+
} : never;
|
|
115
|
+
type EdgeDefinitionFields = 'ref' | 'kind' | 'abstract' | 'orientation' | 'endpoints' | 'constraints';
|
|
116
|
+
type ProjectedClassDefinition<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput> = Value extends NodeClass<infer Config> ? language.NodeClassDefinition & {
|
|
11
117
|
readonly ref: language.ClassRef<Name> & {
|
|
12
118
|
readonly origin: Origin;
|
|
13
119
|
};
|
|
@@ -22,7 +128,7 @@ type ProjectedClassDefinition<Origin extends string, Name extends string, Value>
|
|
|
22
128
|
readonly as: string;
|
|
23
129
|
readonly incoming: language.EdgeCount;
|
|
24
130
|
};
|
|
25
|
-
} ? language.
|
|
131
|
+
} ? Omit<language.DirectedEdgeDefinition, EdgeDefinitionFields> & {
|
|
26
132
|
readonly ref: language.ClassRef<Name> & {
|
|
27
133
|
readonly origin: Origin;
|
|
28
134
|
};
|
|
@@ -30,12 +136,10 @@ type ProjectedClassDefinition<Origin extends string, Name extends string, Value>
|
|
|
30
136
|
readonly abstract: AbstractOf<Input>;
|
|
31
137
|
readonly orientation: 'directed';
|
|
32
138
|
readonly endpoints: {
|
|
33
|
-
readonly source:
|
|
34
|
-
readonly role: Source['as'];
|
|
139
|
+
readonly source: ProjectedEndpoint<Origin, Source, Root> & {
|
|
35
140
|
readonly outgoing: Source['outgoing'];
|
|
36
141
|
};
|
|
37
|
-
readonly target:
|
|
38
|
-
readonly role: Target['as'];
|
|
142
|
+
readonly target: ProjectedEndpoint<Origin, Target, Root> & {
|
|
39
143
|
readonly incoming: Target['incoming'];
|
|
40
144
|
};
|
|
41
145
|
};
|
|
@@ -51,7 +155,7 @@ type ProjectedClassDefinition<Origin extends string, Name extends string, Value>
|
|
|
51
155
|
readonly incident: language.EdgeCount;
|
|
52
156
|
}
|
|
53
157
|
];
|
|
54
|
-
} ? language.
|
|
158
|
+
} ? Omit<language.UndirectedEdgeDefinition, EdgeDefinitionFields> & {
|
|
55
159
|
readonly ref: language.ClassRef<Name> & {
|
|
56
160
|
readonly origin: Origin;
|
|
57
161
|
};
|
|
@@ -59,12 +163,10 @@ type ProjectedClassDefinition<Origin extends string, Name extends string, Value>
|
|
|
59
163
|
readonly abstract: AbstractOf<Input>;
|
|
60
164
|
readonly orientation: 'undirected';
|
|
61
165
|
readonly endpoints: readonly [
|
|
62
|
-
|
|
63
|
-
readonly role: First['as'];
|
|
166
|
+
ProjectedEndpoint<Origin, First, Root> & {
|
|
64
167
|
readonly incident: First['incident'];
|
|
65
168
|
},
|
|
66
|
-
|
|
67
|
-
readonly role: Second['as'];
|
|
169
|
+
ProjectedEndpoint<Origin, Second, Root> & {
|
|
68
170
|
readonly incident: Second['incident'];
|
|
69
171
|
}
|
|
70
172
|
];
|
|
@@ -82,9 +184,9 @@ type ParentClassProjectionTuple<Origin extends string, Parents extends readonly
|
|
|
82
184
|
type ShallowClassProjectionOfAuthoring<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput> = ClassProjectionWithParents<Origin, Name, Value, Root, readonly language.AnyResolvedClass[]>;
|
|
83
185
|
/** Project each authored Class independently before computing its parent tuple. */
|
|
84
186
|
export type ClassProjectionOfAuthoring<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput, Seen = Value> = Value extends Class ? ClassProjectionWithParents<Origin, Name, Value, Root, ParentClassProjectionTuple<Origin, ParentInputsOfConfig<ProjectionOfClass<Extract<Value, Class>>>, Root, Seen>> : never;
|
|
85
|
-
type ClassProjectionWithParents<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput, Parents extends readonly unknown[]> = Value extends NodeClass<infer _Config> ? ClassProjection<'node', Extract<ProjectedClassDefinition<Origin, Name, Value>, language.NodeClassDefinition>, language.ClassRef<Name> & {
|
|
187
|
+
type ClassProjectionWithParents<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput, Parents extends readonly unknown[]> = Value extends NodeClass<infer _Config> ? ClassProjection<'node', Extract<ProjectedClassDefinition<Origin, Name, Value, Root>, language.NodeClassDefinition>, language.ClassRef<Name> & {
|
|
86
188
|
readonly origin: Origin;
|
|
87
|
-
}, language.DefinitionKey<Origin, 'class', Name>, Parents, EffectivePropertyProjectionsOf<Origin, Name, Value, Root>, OwnInstanceMethodProjectionsOf<Origin, Name, Value>, OwnStaticMethodProjectionsOf<Origin, Name, Value>, OwnPropertyProjectionsOf<Origin, Name, Value>, OwnInstanceMethodProjectionsOf<Origin, Name, Value>, OwnStaticMethodProjectionsOf<Origin, Name, Value>> : Value extends DirectedEdgeClass | UndirectedEdgeClass ? ClassProjection<'edge', Extract<ProjectedClassDefinition<Origin, Name, Value>, language.EdgeClassDefinition>, language.ClassRef<Name> & {
|
|
189
|
+
}, language.DefinitionKey<Origin, 'class', Name>, Parents, EffectivePropertyProjectionsOf<Origin, Name, Value, Root>, OwnInstanceMethodProjectionsOf<Origin, Name, Value>, OwnStaticMethodProjectionsOf<Origin, Name, Value>, OwnPropertyProjectionsOf<Origin, Name, Value>, OwnInstanceMethodProjectionsOf<Origin, Name, Value>, OwnStaticMethodProjectionsOf<Origin, Name, Value>> : Value extends DirectedEdgeClass | UndirectedEdgeClass ? ClassProjection<'edge', Extract<ProjectedClassDefinition<Origin, Name, Value, Root>, language.EdgeClassDefinition>, language.ClassRef<Name> & {
|
|
88
190
|
readonly origin: Origin;
|
|
89
191
|
}, language.DefinitionKey<Origin, 'class', Name>, Parents, EffectivePropertyProjectionsOf<Origin, Name, Value, Root>, never, never, OwnPropertyProjectionsOf<Origin, Name, Value>, never, never> : never;
|
|
90
192
|
export {};
|
package/dist/v1/bundle/codec.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, json, } from '@astrale-os/kernel-dsl/value';
|
|
2
|
-
import { dependencyLimits } from '../addressing/domain-dependency.js';
|
|
3
2
|
import { compareUnicode } from '../addressing/ordering.js';
|
|
3
|
+
import { limits } from '../language/limits.js';
|
|
4
4
|
import { escapePointerToken } from '../language/value/syntax/pointer.js';
|
|
5
5
|
import { acceptDomainSchema } from '../schema/admission/accept.js';
|
|
6
6
|
import { canonicalDomainSchemaAfterValidation } from '../schema/canonical/revision.js';
|
|
7
7
|
import { revisionOfDomainSchema } from '../schema/canonical/revision.js';
|
|
8
8
|
import { MemoryDomainSchemaLookup } from '../schema/dependency/lookup.js';
|
|
9
9
|
import { SchemaError } from '../schema/diagnostic.js';
|
|
10
|
-
import { BundleError, diagnostic } from './diagnostic.js';
|
|
10
|
+
import { BundleError, diagnostic, schemaDiagnosticAt } from './diagnostic.js';
|
|
11
11
|
import { asDomainSchemaBundle, } from './model.js';
|
|
12
12
|
import { parseDomainSchemaBundleStructure } from './structure.js';
|
|
13
13
|
export function acceptDomainSchemaBundle(input) {
|
|
@@ -46,12 +46,12 @@ function acceptBundleValue(input) {
|
|
|
46
46
|
const closure = structure.closure.map((schema, index) => candidate(schema, `/closure/${index}`));
|
|
47
47
|
const diagnostics = [];
|
|
48
48
|
const candidates = new Map();
|
|
49
|
-
if (closure.length + 1 >
|
|
50
|
-
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', '/closure', `A dependency closure may contain at most ${
|
|
49
|
+
if (closure.length + 1 > limits.dependency.closure) {
|
|
50
|
+
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', '/closure', `A dependency closure may contain at most ${limits.dependency.closure} Domains.`));
|
|
51
51
|
}
|
|
52
52
|
for (const entry of [root, ...closure]) {
|
|
53
|
-
if (Object.keys(entry.schema.dependencies).length >
|
|
54
|
-
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', `${entry.pointer}/dependencies`, `A Domain may declare at most ${
|
|
53
|
+
if (Object.keys(entry.schema.dependencies).length > limits.dependency.direct) {
|
|
54
|
+
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', `${entry.pointer}/dependencies`, `A Domain may declare at most ${limits.dependency.direct} direct dependency aliases.`));
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
for (const entry of closure) {
|
|
@@ -99,7 +99,7 @@ function acceptBundleValue(input) {
|
|
|
99
99
|
catch (error) {
|
|
100
100
|
if (!(error instanceof SchemaError))
|
|
101
101
|
throw error;
|
|
102
|
-
throw new BundleError(error.diagnostics.map((item) =>
|
|
102
|
+
throw new BundleError(error.diagnostics.map((item) => schemaDiagnosticAt(entry.pointer, item)));
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
105
|
for (const entry of candidates.values()) {
|
|
@@ -128,8 +128,8 @@ function collectReachable(current, root, candidates, reachable, active, revision
|
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
active.add(current.key);
|
|
131
|
-
if (depth >
|
|
132
|
-
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', current.pointer, `Dependency depth ${depth} exceeds the maximum ${
|
|
131
|
+
if (depth > limits.dependency.depth) {
|
|
132
|
+
diagnostics.push(diagnostic('DV_DEPENDENCY_LIMITS', current.pointer, `Dependency depth ${depth} exceeds the maximum ${limits.dependency.depth}.`));
|
|
133
133
|
active.delete(current.key);
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
@@ -4,6 +4,8 @@ export type BundleDiagnostic<Code extends BundleDiagnosticCode = BundleDiagnosti
|
|
|
4
4
|
readonly code: Code;
|
|
5
5
|
};
|
|
6
6
|
export declare function diagnostic<const Code extends BundleDiagnosticCode>(code: Code, pointer: string, message: string, ref?: string): BundleDiagnostic<Code>;
|
|
7
|
+
/** A refusal of one bundled schema, its pointer rebased under the schema's place in the bundle. */
|
|
8
|
+
export declare function schemaDiagnosticAt(pointer: string, refusal: SchemaDiagnostic): BundleDiagnostic;
|
|
7
9
|
export declare class BundleError extends Error {
|
|
8
10
|
readonly diagnostics: readonly BundleDiagnostic[];
|
|
9
11
|
constructor(diagnostics: readonly BundleDiagnostic[]);
|
|
@@ -2,6 +2,12 @@ import { formatDiagnostics, orderDiagnostics } from '../language/validation/diag
|
|
|
2
2
|
export function diagnostic(code, pointer, message, ref) {
|
|
3
3
|
return Object.freeze({ code, pointer, message, ...(ref === undefined ? {} : { ref }) });
|
|
4
4
|
}
|
|
5
|
+
/** A refusal of one bundled schema, its pointer rebased under the schema's place in the bundle. */
|
|
6
|
+
export function schemaDiagnosticAt(pointer, refusal) {
|
|
7
|
+
// Acceptance refuses a document with Schema codes only, never with comparison request codes.
|
|
8
|
+
const code = refusal.code;
|
|
9
|
+
return Object.freeze({ ...refusal, code, pointer: `${pointer}${refusal.pointer}` });
|
|
10
|
+
}
|
|
5
11
|
export class BundleError extends Error {
|
|
6
12
|
diagnostics;
|
|
7
13
|
constructor(diagnostics) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { escapePointerToken } from '../language/value/syntax/pointer.js';
|
|
2
2
|
import { SchemaError } from '../schema/diagnostic.js';
|
|
3
3
|
import { routeDomainSchema } from '../schema/validation/domain.route.js';
|
|
4
|
-
import { BundleError, diagnostic } from './diagnostic.js';
|
|
4
|
+
import { BundleError, diagnostic, schemaDiagnosticAt } from './diagnostic.js';
|
|
5
5
|
import { DOMAIN_BUNDLE_FORMAT, DOMAIN_BUNDLE_VERSION } from './model.js';
|
|
6
6
|
export function parseDomainSchemaBundleStructure(input) {
|
|
7
7
|
if (!isObject(input)) {
|
|
@@ -57,7 +57,7 @@ function routeAt(value, pointer, diagnostics) {
|
|
|
57
57
|
catch (error) {
|
|
58
58
|
if (!(error instanceof SchemaError))
|
|
59
59
|
throw error;
|
|
60
|
-
diagnostics.push(...error.diagnostics.map((entry) =>
|
|
60
|
+
diagnostics.push(...error.diagnostics.map((entry) => schemaDiagnosticAt(pointer, entry)));
|
|
61
61
|
return undefined;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { accept as acceptPortable } from '@astrale-os/kernel-dsl/value';
|
|
2
|
-
import {
|
|
2
|
+
import { limits } from '../../language/limits.js';
|
|
3
3
|
import {} from '../model/schema.js';
|
|
4
4
|
import { validateClosure } from './closure.js';
|
|
5
5
|
import { invalid, pointer } from './diagnostic.js';
|
|
@@ -20,7 +20,7 @@ export function acceptCompiledSchema(input) {
|
|
|
20
20
|
const rootPin = dependency(root.root, 'root', '/root');
|
|
21
21
|
const machines = new Map();
|
|
22
22
|
const closure = array(root.closure, 'closure', '/closure').map((value, index) => entry(value, index, `/closure/${index}`, machines));
|
|
23
|
-
if (closure.length >
|
|
23
|
+
if (closure.length > limits.dependency.closure) {
|
|
24
24
|
invalid('dependency closure limit', 'COMPILED_DEPENDENCY_LIMITS', '/closure');
|
|
25
25
|
}
|
|
26
26
|
const closureOrigins = new Set();
|
|
@@ -34,7 +34,7 @@ export function acceptCompiledSchema(input) {
|
|
|
34
34
|
if (rootEntry?.revision !== rootPin.revision)
|
|
35
35
|
invalid('root pin', undefined, '/root');
|
|
36
36
|
for (const [entryIndex, owner] of closure.entries()) {
|
|
37
|
-
if (Object.keys(owner.dependencies).length >
|
|
37
|
+
if (Object.keys(owner.dependencies).length > limits.dependency.direct) {
|
|
38
38
|
invalid('direct dependency limit', 'COMPILED_DEPENDENCY_LIMITS', `/closure/${entryIndex}/dependencies`);
|
|
39
39
|
}
|
|
40
40
|
for (const [alias, pin] of Object.entries(owner.dependencies)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {} from '@astrale-os/kernel-dsl/value';
|
|
2
|
-
import { dependencyLimits } from '../../addressing/domain-dependency.js';
|
|
3
2
|
import { Key, isDefinitionRef } from '../../addressing/index.js';
|
|
4
3
|
import {} from '../../language/class/model/edge.js';
|
|
4
|
+
import { limits } from '../../language/limits.js';
|
|
5
5
|
import {} from '../model/schema.js';
|
|
6
6
|
import { invalid, pointer } from './diagnostic.js';
|
|
7
7
|
/** Require closed direct references, acyclic inheritance and concrete Core Classes. */
|
|
@@ -128,7 +128,7 @@ function validateDependencyCycles(candidate) {
|
|
|
128
128
|
const visited = new Set();
|
|
129
129
|
const frames = [];
|
|
130
130
|
const push = (origin, depth) => {
|
|
131
|
-
if (depth >
|
|
131
|
+
if (depth > limits.dependency.depth) {
|
|
132
132
|
invalid('dependency depth limit', 'COMPILED_DEPENDENCY_LIMITS', `/closure/${byOrigin.get(origin)?.index ?? 0}/dependencies`);
|
|
133
133
|
}
|
|
134
134
|
active.add(origin);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Key } from '../../../addressing/index.js';
|
|
2
2
|
import { isMethodExecutable } from '../../../language/callable/executable.js';
|
|
3
3
|
import { coveringEdgeUniqueTuples, coveringNodeUniqueTuples, edgeUniqueKeys, nodeUniqueKeys, } from '../../../language/class/unique.js';
|
|
4
|
-
import { checkCoreEdgeSet, checkHeldKeys, coreEndpointsSatisfy, } from '../../../language/core/facts.js';
|
|
4
|
+
import { checkCoreEdgeSet, checkHeldKeys, coreEndpointsSatisfy, DOMAIN_ENDPOINT_CLASS, } from '../../../language/core/facts.js';
|
|
5
5
|
import {} from '../../../language/core/model/core.js';
|
|
6
6
|
import { policyObjectOrigin, policyObjectKey, projectedMemberClass, } from '../../../language/index.js';
|
|
7
7
|
import { bindValueProgram } from '../../../language/value/compile/load.js';
|
|
@@ -123,7 +123,7 @@ function validateCoreProperties(values, analysis, path) {
|
|
|
123
123
|
}
|
|
124
124
|
function resolveCoreEndpoint(context, entry, ref, nodes, path) {
|
|
125
125
|
if (ref.kind === 'domain')
|
|
126
|
-
return { key: 'domain' };
|
|
126
|
+
return { key: 'domain', member: { class: DOMAIN_ENDPOINT_CLASS, pointer: path } };
|
|
127
127
|
const undeclared = () => fail(path, 'Core endpoint does not name a declared local Definition.');
|
|
128
128
|
if (policyObjectOrigin(ref) !== entry.origin)
|
|
129
129
|
return undeclared();
|
|
@@ -151,9 +151,5 @@ function declaresProjectedMember(context, entry, ref) {
|
|
|
151
151
|
return declarations.some((declaration) => declaration.ref.name === ref.name);
|
|
152
152
|
}
|
|
153
153
|
function endpointSatisfies(context, endpoint, accepts) {
|
|
154
|
-
|
|
155
|
-
return classSatisfiesAny(context, endpoint.value.class, accepts);
|
|
156
|
-
if ('member' in endpoint)
|
|
157
|
-
return classSatisfiesAny(context, endpoint.member.class, accepts);
|
|
158
|
-
return true;
|
|
154
|
+
return classSatisfiesAny(context, 'value' in endpoint ? endpoint.value.class : endpoint.member.class, accepts);
|
|
159
155
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {} from '../../../../addressing/index.js';
|
|
2
2
|
import { branchesOf, targetMode, isConnected, } from '../../../../language/policy/analysis/branches.js';
|
|
3
|
-
import {
|
|
3
|
+
import { exceededLimits, measureChecks, policyMeasurer, } from '../../../../language/policy/analysis/budgets.js';
|
|
4
4
|
import { neverAdmittedClasses, } from '../../../../language/policy/analysis/checks.js';
|
|
5
5
|
import {} from '../../../../language/policy/analysis/typing.js';
|
|
6
6
|
import { checksNameTheCaller, isClassRuleChecks, } from '../../../../language/policy/model/policy.js';
|
|
@@ -28,11 +28,7 @@ export function validatePolicyParity(context, entry, entryIndex, policies, origi
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
const measure = measurePolicy(name);
|
|
31
|
-
if (measure !== undefined &&
|
|
32
|
-
(measure.depth > MAX_PATTERN_DEPTH ||
|
|
33
|
-
measure.edgeCounts.length > MAX_BRANCHES ||
|
|
34
|
-
Math.max(0, ...measure.edgeCounts) > MAX_EDGES ||
|
|
35
|
-
measure.domains.size > MAX_DOMAINS)) {
|
|
31
|
+
if (measure !== undefined && exceededLimits(measure).length > 0) {
|
|
36
32
|
fail(path, 'Policy expansion exceeds the V1 depth, branch, Edge, or Domain budget.');
|
|
37
33
|
}
|
|
38
34
|
const branches = typing.expandedBranches(name, `$${name}`);
|
|
@@ -98,10 +94,7 @@ function validatePolicyChecks(context, typing, entry, expression, input, receive
|
|
|
98
94
|
if (!checksNameTheCaller(expression)) {
|
|
99
95
|
fail(path, `${SITE[site].checks} must check a Policy on every branch: sameNode alone names no caller.`);
|
|
100
96
|
}
|
|
101
|
-
|
|
102
|
-
if (measure.depth > MAX_CHECK_DEPTH ||
|
|
103
|
-
measure.branches > MAX_BRANCHES ||
|
|
104
|
-
measure.leaves > MAX_CHECK_LEAVES) {
|
|
97
|
+
if (exceededLimits(measureChecks(expression)).length > 0) {
|
|
105
98
|
fail(path, `${SITE[site].checks} exceed the V1 depth, branch, or leaf budget.`);
|
|
106
99
|
}
|
|
107
100
|
const leaves = new Map();
|
|
@@ -14,6 +14,9 @@ export interface CallableValidation {
|
|
|
14
14
|
validateInputField(field: string, input: unknown): readonly Diagnostic[];
|
|
15
15
|
validateOutput(output: unknown): readonly Diagnostic[];
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Build the one Domain-level router shared by source resolution and compiled loading. The Domain
|
|
19
|
+
* built from the same entries asks only for the Properties and Callables they declare.
|
|
20
|
+
*/
|
|
18
21
|
export declare function createDomainValidation(properties: ReadonlyMap<PropertyKey, PropertyValidation>, callables: ReadonlyMap<Key.Callable, CallableValidation>): DomainValidation;
|
|
19
22
|
export declare function unknownInputField(field: string): readonly Diagnostic[];
|
|
@@ -1,34 +1,30 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Build the one Domain-level router shared by source resolution and compiled loading. The Domain
|
|
3
|
+
* built from the same entries asks only for the Properties and Callables they declare.
|
|
4
|
+
*/
|
|
2
5
|
export function createDomainValidation(properties, callables) {
|
|
6
|
+
const propertyOf = (key) => {
|
|
7
|
+
const target = properties.get(key);
|
|
8
|
+
if (target === undefined)
|
|
9
|
+
throw new TypeError(`Property ${key} is absent.`);
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
const callableOf = (key) => {
|
|
13
|
+
const target = callables.get(key);
|
|
14
|
+
if (target === undefined)
|
|
15
|
+
throw new TypeError(`Callable ${key} is absent.`);
|
|
16
|
+
return target;
|
|
17
|
+
};
|
|
3
18
|
const validation = {
|
|
4
19
|
propertyExists: (key) => properties.has(key),
|
|
5
|
-
property(key, input)
|
|
6
|
-
|
|
7
|
-
return target === undefined ? unknownTarget('Property', key) : target.validate(input);
|
|
8
|
-
},
|
|
9
|
-
propertyProgram(key) {
|
|
10
|
-
const target = properties.get(key);
|
|
11
|
-
if (target === undefined)
|
|
12
|
-
throw new TypeError(`Property ${key} is absent.`);
|
|
13
|
-
return target.program();
|
|
14
|
-
},
|
|
20
|
+
property: (key, input) => propertyOf(key).validate(input),
|
|
21
|
+
propertyProgram: (key) => propertyOf(key).program(),
|
|
15
22
|
propertyOrdering: (key) => properties.get(key)?.ordering,
|
|
16
23
|
callableExists: (key) => callables.has(key),
|
|
17
|
-
callableInput(key, input)
|
|
18
|
-
const target = callables.get(key);
|
|
19
|
-
return target === undefined ? unknownTarget('Callable', key) : target.validateInput(input);
|
|
20
|
-
},
|
|
24
|
+
callableInput: (key, input) => callableOf(key).validateInput(input),
|
|
21
25
|
callableFields: (key) => callables.get(key)?.fields,
|
|
22
|
-
callableInputField(key, field, input)
|
|
23
|
-
|
|
24
|
-
return target === undefined
|
|
25
|
-
? unknownTarget('Callable', key)
|
|
26
|
-
: target.validateInputField(field, input);
|
|
27
|
-
},
|
|
28
|
-
callableOutput(key, output) {
|
|
29
|
-
const target = callables.get(key);
|
|
30
|
-
return target === undefined ? unknownTarget('Callable', key) : target.validateOutput(output);
|
|
31
|
-
},
|
|
26
|
+
callableInputField: (key, field, input) => callableOf(key).validateInputField(field, input),
|
|
27
|
+
callableOutput: (key, output) => callableOf(key).validateOutput(output),
|
|
32
28
|
};
|
|
33
29
|
return Object.freeze(validation);
|
|
34
30
|
}
|
|
@@ -41,12 +37,3 @@ export function unknownInputField(field) {
|
|
|
41
37
|
}),
|
|
42
38
|
];
|
|
43
39
|
}
|
|
44
|
-
function unknownTarget(kind, key) {
|
|
45
|
-
return [
|
|
46
|
-
Object.freeze({
|
|
47
|
-
code: 'DOMAIN_VALIDATION_TARGET_UNKNOWN',
|
|
48
|
-
pointer: '',
|
|
49
|
-
message: `${kind} ${key} is absent.`,
|
|
50
|
-
}),
|
|
51
|
-
];
|
|
52
|
-
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.astrale.ai/dsl/v1/value-schema",
|
|
4
|
+
"$dynamicAnchor": "meta",
|
|
5
|
+
"$vocabulary": {
|
|
6
|
+
"https://json-schema.org/draft/2020-12/vocab/core": true,
|
|
7
|
+
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
|
|
8
|
+
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
|
|
9
|
+
"https://json-schema.org/draft/2020-12/vocab/validation": true,
|
|
10
|
+
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
|
|
11
|
+
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
|
|
12
|
+
"https://json-schema.org/draft/2020-12/vocab/content": true,
|
|
13
|
+
"https://schemas.astrale.ai/dsl/v1/value-schema/vocabulary": true
|
|
14
|
+
},
|
|
15
|
+
"title": "Astrale V1 value schema",
|
|
16
|
+
"$comment": "The meta-schema of the V1 value-schema dialect: Draft 2020-12 and the required Astrale vocabulary (fullMatch, x-astrale-path, x-astrale-value-kind). Its $dynamicAnchor extends Draft 2020-12 at every subschema, not only the root. The rules of the profile beyond it are published as schema.values.RULES.",
|
|
17
|
+
"allOf": [{ "$ref": "https://json-schema.org/draft/2020-12/schema" }],
|
|
18
|
+
"properties": {
|
|
19
|
+
"fullMatch": { "type": "string" },
|
|
20
|
+
"x-astrale-path": { "type": "object" }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { MethodRecord } from '../../callable/model/callable.js';
|
|
|
3
3
|
import type { ClassPolicy, NodeClassPolicy } from '../../policy/model/policy.js';
|
|
4
4
|
import type { DataFacet } from './data.js';
|
|
5
5
|
import type { EdgeContract } from './edge.js';
|
|
6
|
-
import type { PropertyFacet } from './property.js';
|
|
6
|
+
import type { EdgePropertyDefinition, NodePropertyDefinition, PropertyFacet } from './property.js';
|
|
7
7
|
export type ClassKind = 'node' | 'edge';
|
|
8
8
|
/**
|
|
9
9
|
* Which Classes may extend a Class: `'open'`, those of its Domain and of every Domain that depends
|
|
@@ -30,7 +30,7 @@ export type NodeUniqueTuple = readonly [PropertyKey, ...PropertyKey[]];
|
|
|
30
30
|
* backend announces it to enforce Node keys, so a tuple is never ignored where it is not.
|
|
31
31
|
*/
|
|
32
32
|
export type NodeUniqueForm = readonly ['property'];
|
|
33
|
-
export interface NodeClassDefinition extends DefinitionBase<ClassRef>, PropertyFacet
|
|
33
|
+
export interface NodeClassDefinition extends DefinitionBase<ClassRef>, PropertyFacet<NodePropertyDefinition>, DataFacet {
|
|
34
34
|
readonly kind: 'node';
|
|
35
35
|
readonly abstract: boolean;
|
|
36
36
|
/** Absent when `'internal'`, the default, so a Class that keeps the default keeps its revision. */
|
|
@@ -44,9 +44,9 @@ export interface NodeClassDefinition extends DefinitionBase<ClassRef>, PropertyF
|
|
|
44
44
|
* The tuples no two Nodes of this Class and of its active concrete descendants share while every
|
|
45
45
|
* Property is present; absent, none. A descendant is covered without declaring them again.
|
|
46
46
|
*/
|
|
47
|
-
readonly unique?: readonly NodeUniqueTuple[];
|
|
47
|
+
readonly unique?: readonly [NodeUniqueTuple, ...NodeUniqueTuple[]];
|
|
48
48
|
}
|
|
49
|
-
export type EdgeClassDefinition = DefinitionBase<ClassRef> & PropertyFacet & EdgeContract & {
|
|
49
|
+
export type EdgeClassDefinition = DefinitionBase<ClassRef> & PropertyFacet<EdgePropertyDefinition> & EdgeContract & {
|
|
50
50
|
readonly kind: 'edge';
|
|
51
51
|
readonly abstract: boolean;
|
|
52
52
|
/** Absent when `'internal'`, the default, so a Class that keeps the default keeps its revision. */
|
|
@@ -8,7 +8,7 @@ export type EdgeOrientation = 'directed' | 'undirected';
|
|
|
8
8
|
export type EdgeLifetime = 'restrict' | 'detach';
|
|
9
9
|
export interface EdgeEndpointBase {
|
|
10
10
|
readonly role: string;
|
|
11
|
-
readonly accepts: readonly ClassRef[];
|
|
11
|
+
readonly accepts: readonly [ClassRef, ...ClassRef[]];
|
|
12
12
|
/** Declared only when authored; otherwise derived (`edgeLifetimes`). */
|
|
13
13
|
readonly onDelete?: EdgeLifetime;
|
|
14
14
|
}
|
|
@@ -56,7 +56,7 @@ export interface DirectedEdgeContract {
|
|
|
56
56
|
* The tuples no two Edges of this Class and of its active concrete descendants share. Absent
|
|
57
57
|
* when the Class declares none, so a Class without one keeps its revision; never empty.
|
|
58
58
|
*/
|
|
59
|
-
readonly unique?: readonly EdgeUniqueTuple[];
|
|
59
|
+
readonly unique?: readonly [EdgeUniqueTuple, ...EdgeUniqueTuple[]];
|
|
60
60
|
}
|
|
61
61
|
export interface UndirectedEdgeContract {
|
|
62
62
|
readonly orientation: 'undirected';
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
+
import type { StateTopology } from '../../state/index.js';
|
|
2
|
+
import type { JsonSchema } from '../../value/model/schema.js';
|
|
1
3
|
export type AutoEvent = 'create' | 'update';
|
|
2
4
|
export type AutoSet = 'instant';
|
|
3
5
|
/** `create`: written only by node or edge creation. `once`: written while absent, never unset. */
|
|
4
6
|
export type PropertyImmutability = 'create' | 'once';
|
|
5
7
|
export interface PropertyAuto {
|
|
6
|
-
readonly on: readonly AutoEvent[];
|
|
8
|
+
readonly on: readonly [AutoEvent, ...AutoEvent[]];
|
|
7
9
|
readonly set: AutoSet;
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
/** A Property of a Node Class, which may be a State Property. */
|
|
12
|
+
export interface NodePropertyDefinition {
|
|
13
|
+
readonly schema: JsonSchema;
|
|
11
14
|
readonly required: boolean;
|
|
12
15
|
readonly auto?: PropertyAuto;
|
|
13
16
|
readonly immutable?: PropertyImmutability;
|
|
14
17
|
readonly description?: string;
|
|
15
|
-
readonly state?:
|
|
18
|
+
readonly state?: StateTopology;
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
export interface
|
|
19
|
-
readonly
|
|
20
|
+
/** A Property of an Edge Class: an Edge has no State Property. */
|
|
21
|
+
export interface EdgePropertyDefinition extends Omit<NodePropertyDefinition, 'state'> {
|
|
22
|
+
readonly state?: never;
|
|
23
|
+
}
|
|
24
|
+
/** A Property of a Class of either kind. */
|
|
25
|
+
export type PropertyDefinition = NodePropertyDefinition | EdgePropertyDefinition;
|
|
26
|
+
export type PropertyRecord<Definition extends PropertyDefinition = PropertyDefinition> = Readonly<Record<string, Definition>>;
|
|
27
|
+
export interface PropertyFacet<Definition extends PropertyDefinition = PropertyDefinition> {
|
|
28
|
+
readonly properties: PropertyRecord<Definition>;
|
|
20
29
|
}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { ClassRef } from '../../addressing/index.js';
|
|
2
2
|
import type { EdgeContract, EdgeCount, EdgeEndpointBase, IncidentEndpoint } from '../class/model/edge.js';
|
|
3
|
+
/**
|
|
4
|
+
* The Class of the owning Domain's Node: every Domain principal is a Node of the final Kernel
|
|
5
|
+
* `Domain` Class, so a Core Edge that names the Domain must accept that Class at that endpoint.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DOMAIN_ENDPOINT_CLASS: ClassRef;
|
|
3
8
|
/** One endpoint of a Core Edge: a Core Node, a projected member or the owning Domain. */
|
|
4
9
|
export interface CoreFactEndpoint {
|
|
5
10
|
readonly key: string;
|
|
6
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Set on a projected member and on the owning Domain: the Kernel Class it is a Node of, and where
|
|
13
|
+
* a breach of its degree is reported.
|
|
14
|
+
*/
|
|
7
15
|
readonly member?: {
|
|
8
16
|
readonly class: ClassRef;
|
|
9
17
|
readonly pointer: string;
|
|
@@ -26,10 +34,12 @@ export interface CoreDegreeSubject {
|
|
|
26
34
|
}
|
|
27
35
|
export interface CoreEdgeSet<Edge> {
|
|
28
36
|
readonly edges: readonly CoreFactEdge<Edge>[];
|
|
29
|
-
/** The local
|
|
37
|
+
/** The local Edge Classes, in the order their slices are checked. */
|
|
30
38
|
readonly classes: readonly {
|
|
31
39
|
readonly key: string;
|
|
32
|
-
readonly contract: EdgeContract
|
|
40
|
+
readonly contract: EdgeContract & {
|
|
41
|
+
readonly abstract: boolean;
|
|
42
|
+
};
|
|
33
43
|
}[];
|
|
34
44
|
readonly nodes: readonly CoreDegreeSubject[];
|
|
35
45
|
readonly satisfies: (ref: ClassRef, accepts: readonly ClassRef[]) => boolean;
|
|
@@ -68,5 +78,8 @@ export declare function coreEndpointsSatisfy<Endpoint>(contract: EdgeContract, s
|
|
|
68
78
|
* DV-EDGE-UNIQUE); Activation checks them against stored data.
|
|
69
79
|
*/
|
|
70
80
|
export declare function checkHeldKeys<Fact>(facts: Iterable<Fact>, keys: (fact: Fact) => readonly string[], report: (fact: Fact, previous: Fact) => void): void;
|
|
71
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Check normalized Edge identity, noSelf, keys, and the acyclicity and Core degrees of each exact
|
|
83
|
+
* concrete Edge Class over its own Edges.
|
|
84
|
+
*/
|
|
72
85
|
export declare function checkCoreEdgeSet<Edge>(set: CoreEdgeSet<Edge>): void;
|