@astrale-os/kernel-dsl 0.2.0-beta.45 → 0.2.0-beta.47
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/class-key.js +5 -4
- package/dist/v1/addressing/method-key.js +3 -2
- package/dist/v1/builder/class/property.d.ts +3 -1
- package/dist/v1/builder/class/property.js +9 -1
- package/dist/v1/builder/lowering/schema/compile.js +1 -1
- package/dist/v1/builder/lowering/value/compile.js +3 -0
- package/dist/v1/builder/lowering/value/zod.js +11 -2
- package/dist/v1/builder/lowering/view.d.ts +2 -2
- package/dist/v1/builder/lowering/view.js +2 -14
- package/dist/v1/builder/schema/diagnostic.d.ts +1 -1
- package/dist/v1/builder/value/full-match.js +6 -3
- package/dist/v1/builder/view/authoring.d.ts +3 -7
- package/dist/v1/builder/view/authoring.js +5 -2
- package/dist/v1/compiled/admission/accept.js +31 -6
- package/dist/v1/compiled/admission/semantics.js +49 -16
- package/dist/v1/compiled/compiler/compile.js +1 -0
- package/dist/v1/compiled/loader/load.js +1 -0
- package/dist/v1/domain/create.js +0 -19
- package/dist/v1/domain/model/domain.d.ts +0 -1
- package/dist/v1/domain/model/input.d.ts +3 -0
- package/dist/v1/domain/projection/classes.js +1 -0
- package/dist/v1/domain/validation/create.d.ts +2 -0
- package/dist/v1/domain/validation/create.js +12 -0
- package/dist/v1/language/class/model/property.d.ts +3 -0
- package/dist/v1/language/class/resolved.d.ts +3 -0
- package/dist/v1/language/index.d.ts +2 -0
- package/dist/v1/language/index.js +1 -0
- package/dist/v1/language/policy/normalization/normalize.d.ts +4 -0
- package/dist/v1/language/policy/normalization/normalize.js +51 -13
- package/dist/v1/language/value/inclusion/includes.d.ts +9 -0
- package/dist/v1/language/value/inclusion/includes.js +777 -0
- package/dist/v1/language/value/profile/rules.js +11 -32
- package/dist/v1/language/value/regexp/ast.js +3 -64
- package/dist/v1/language/value/regexp/compile.d.ts +25 -2
- package/dist/v1/language/value/regexp/compile.js +48 -12
- package/dist/v1/language/value/regexp/syntax.d.ts +11 -1
- package/dist/v1/language/value/regexp/syntax.js +14 -2
- package/dist/v1/language/value/regexp/unicode.d.ts +32 -0
- package/dist/v1/language/value/regexp/unicode.js +139 -0
- package/dist/v1/language/value/syntax/full-match.js +6 -3
- package/dist/v1/language/view/model/view.d.ts +6 -0
- package/dist/v1/language/view/resolved.d.ts +2 -2
- package/dist/v1/schema/analysis/class.d.ts +2 -1
- package/dist/v1/schema/analysis/class.js +1 -0
- package/dist/v1/schema/compatibility/comparators/callables.d.ts +7 -0
- package/dist/v1/schema/compatibility/comparators/callables.js +13 -0
- package/dist/v1/schema/compatibility/comparators/classes.d.ts +18 -0
- package/dist/v1/schema/compatibility/comparators/classes.js +54 -0
- package/dist/v1/schema/compatibility/comparators/index.d.ts +1 -1
- package/dist/v1/schema/compatibility/comparators/index.js +14 -2
- package/dist/v1/schema/compatibility/context.d.ts +6 -2
- package/dist/v1/schema/compatibility/context.js +12 -6
- package/dist/v1/schema/compatibility/evidence.d.ts +8 -1
- package/dist/v1/schema/compatibility/evidence.js +10 -1
- package/dist/v1/schema/compatibility/fields.d.ts +2 -0
- package/dist/v1/schema/compatibility/fields.js +1 -0
- package/dist/v1/schema/compatibility/meaning/footprint.js +3 -1
- package/dist/v1/schema/compatibility/meaning/index.js +4 -2
- package/dist/v1/schema/compatibility/model.d.ts +11 -6
- package/dist/v1/schema/compatibility/references.d.ts +8 -1
- package/dist/v1/schema/compatibility/references.js +39 -6
- package/dist/v1/schema/compatibility/scope.d.ts +5 -0
- package/dist/v1/schema/compatibility/scope.js +5 -2
- package/dist/v1/schema/compatibility/structure/index.js +21 -2
- package/dist/v1/schema/compatibility/structure/requirements.js +26 -1
- package/dist/v1/schema/compatibility/subjects.js +20 -2
- package/dist/v1/schema/diagnostic.d.ts +1 -1
- package/dist/v1/schema/normalization/domain.js +1 -0
- package/dist/v1/schema/resolution/domain.d.ts +4 -1
- package/dist/v1/schema/resolution/domain.js +7 -7
- package/dist/v1/schema/resolution/origins.d.ts +11 -4
- package/dist/v1/schema/resolution/origins.js +7 -8
- package/dist/v1/schema/validation/class.d.ts +10 -0
- package/dist/v1/schema/validation/class.js +13 -2
- package/dist/v1/schema/validation/domain.structure.js +1 -0
- package/package.json +1 -1
|
@@ -20,10 +20,11 @@ export function ClassKey(input) {
|
|
|
20
20
|
function is(input) {
|
|
21
21
|
if (typeof input !== 'string' || !Key.is(input))
|
|
22
22
|
return false;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
!
|
|
23
|
+
// Only the coordinate is tested: an origin label may itself be `property` or `method`.
|
|
24
|
+
const coordinate = input.slice(input.indexOf(':') + 1);
|
|
25
|
+
return (coordinate.startsWith('class.') &&
|
|
26
|
+
!coordinate.includes('.property.') &&
|
|
27
|
+
!coordinate.includes('.method.'));
|
|
27
28
|
}
|
|
28
29
|
ClassKey.is = is;
|
|
29
30
|
function ref(input) {
|
|
@@ -21,8 +21,9 @@ export function MethodKey(input) {
|
|
|
21
21
|
function is(input) {
|
|
22
22
|
if (typeof input !== 'string' || !Key.is(input))
|
|
23
23
|
return false;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// The member kind is the third segment: the owner Class may itself be named `method`.
|
|
25
|
+
const [kind, , member] = input.slice(input.indexOf(':') + 1).split('.');
|
|
26
|
+
return kind === 'class' && member === 'method';
|
|
26
27
|
}
|
|
27
28
|
MethodKey.is = is;
|
|
28
29
|
function address(input) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
-
import type { AutoEvent, AutoSet } from '../../language/class/model/property.js';
|
|
2
|
+
import type { AutoEvent, AutoSet, PropertyImmutability } from '../../language/class/model/property.js';
|
|
3
3
|
import type { StateMachine } from '../../language/state/index.js';
|
|
4
4
|
import type { JsonSchema } from '../../language/value/model/schema.js';
|
|
5
5
|
import type { AUTHORING } from '../schema/handle.js';
|
|
@@ -9,6 +9,8 @@ export type ValueSchemaInput = z.ZodType | JsonSchema;
|
|
|
9
9
|
export interface PropertyOptions {
|
|
10
10
|
readonly required?: boolean;
|
|
11
11
|
readonly description?: string;
|
|
12
|
+
/** `create` freezes the value at creation; `once` admits one write while absent. */
|
|
13
|
+
readonly immutable?: PropertyImmutability;
|
|
12
14
|
}
|
|
13
15
|
export interface AutoOptions {
|
|
14
16
|
readonly on: AutoEvent | readonly AutoEvent[];
|
|
@@ -10,7 +10,12 @@ export function autoPropertyAuthoringInput(value) {
|
|
|
10
10
|
}
|
|
11
11
|
export function property(schema, options) {
|
|
12
12
|
const admitted = options ?? {};
|
|
13
|
-
assertKnownKeys(admitted, ['required', 'description']);
|
|
13
|
+
assertKnownKeys(admitted, ['required', 'description', 'immutable']);
|
|
14
|
+
if (admitted.immutable !== undefined &&
|
|
15
|
+
admitted.immutable !== 'create' &&
|
|
16
|
+
admitted.immutable !== 'once') {
|
|
17
|
+
fail('BUILDER_PROPERTY_IMMUTABLE_INVALID', '/immutable', 'immutable is create or once.');
|
|
18
|
+
}
|
|
14
19
|
return authoringValue('property', {
|
|
15
20
|
[PROPERTY_INPUT]: {
|
|
16
21
|
schema,
|
|
@@ -34,6 +39,9 @@ export function auto(property, options) {
|
|
|
34
39
|
fail('BUILDER_AUTO_NESTED', '', 'auto(...) cannot wrap another auto Property.');
|
|
35
40
|
}
|
|
36
41
|
assertKnownKeys(options, ['on', 'set']);
|
|
42
|
+
if (propertyAuthoringInput(property).options.immutable !== undefined) {
|
|
43
|
+
fail('BUILDER_AUTO_IMMUTABLE', '', 'An auto Property cannot be immutable.');
|
|
44
|
+
}
|
|
37
45
|
const authored = Array.isArray(options.on) ? options.on : [options.on];
|
|
38
46
|
if (authored.length === 0)
|
|
39
47
|
fail('BUILDER_AUTO_EVENT_INVALID', '/on', 'auto(...) requires an event.');
|
|
@@ -47,7 +47,7 @@ function assembleDomainSchema(origin, input, lookup) {
|
|
|
47
47
|
}));
|
|
48
48
|
const policies = mapRecord(input.policies ?? {}, (value, name) => policyCompiler.compile(value, name, `/policies/${escapeToken(name)}`));
|
|
49
49
|
assertPolicyCompositionAcyclic(policies, origin);
|
|
50
|
-
const views = mapRecord(input.views ?? {}, (value, name) => viewCompiler.compile(value, name
|
|
50
|
+
const views = mapRecord(input.views ?? {}, (value, name) => viewCompiler.compile(value, name));
|
|
51
51
|
const core = compileCore(input.core, context);
|
|
52
52
|
const semanticContent = {
|
|
53
53
|
format: 'astrale.dsl',
|
|
@@ -37,6 +37,9 @@ export class BuilderValueSchemas {
|
|
|
37
37
|
schema: canonicalizeValueSchema(schema, 'property-facet', this.registry),
|
|
38
38
|
required: authoredInput?.options.required ?? isRequired(schemaInput),
|
|
39
39
|
...(autoInput === undefined ? {} : { auto: autoInput.options }),
|
|
40
|
+
...(authoredInput?.options.immutable === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: { immutable: authoredInput.options.immutable }),
|
|
40
43
|
...(authoredInput?.options.description === undefined
|
|
41
44
|
? {}
|
|
42
45
|
: { description: authoredInput.options.description }),
|
|
@@ -161,7 +161,10 @@ function inspectCheck(def, pointer, diagnostics) {
|
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
if (def.check === 'string_format' && def.format === 'regex' && def.pattern instanceof RegExp) {
|
|
164
|
-
if (
|
|
164
|
+
if (def.pattern.flags === '') {
|
|
165
|
+
diagnostics.push(diagnostic('ZOD_SCHEMA_NOT_LOSSLESS', pointer, 'Zod RegExp without the u flag reads \\p{...} as literal text, and classes and quantifiers by UTF-16 code unit, unlike the V1 I-Regexp it would lower to; add the u flag.'));
|
|
166
|
+
}
|
|
167
|
+
else if (!isLosslessRegexp(def.pattern)) {
|
|
165
168
|
diagnostics.push(diagnostic('ZOD_SCHEMA_NOT_LOSSLESS', pointer, 'Zod RegExp flags, anchors, dot semantics, or syntax cannot be preserved as a V1 I-Regexp substring pattern.'));
|
|
166
169
|
}
|
|
167
170
|
}
|
|
@@ -292,8 +295,14 @@ function escapePointerToken(value) {
|
|
|
292
295
|
function isPlainRecord(value) {
|
|
293
296
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
294
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Whether a Zod RegExp search means its source read as an I-Regexp. Only the u flag qualifies:
|
|
300
|
+
* without it, `\p{L}` matches the text `p{L}`, and classes and quantifiers apply to UTF-16 code
|
|
301
|
+
* units rather than scalars; `v` reads class syntax differently, and every other flag changes the
|
|
302
|
+
* match itself.
|
|
303
|
+
*/
|
|
295
304
|
function isLosslessRegexp(pattern) {
|
|
296
|
-
if (pattern.flags !== '
|
|
305
|
+
if (pattern.flags !== 'u')
|
|
297
306
|
return false;
|
|
298
307
|
if (!isIRegexp(pattern.source))
|
|
299
308
|
return false;
|
|
@@ -2,10 +2,10 @@ import type { ViewDefinition } from '../../language/view/model/view.js';
|
|
|
2
2
|
import type { View } from '../view/authoring.js';
|
|
3
3
|
import type { BuilderContext } from './schema/context.js';
|
|
4
4
|
export interface ViewCompiler {
|
|
5
|
-
compile(value: View, name: string
|
|
5
|
+
compile(value: View, name: string): ViewDefinition;
|
|
6
6
|
}
|
|
7
7
|
export declare class V1ViewCompiler implements ViewCompiler {
|
|
8
8
|
readonly context: BuilderContext;
|
|
9
9
|
constructor(context: BuilderContext);
|
|
10
|
-
compile(value: View, name: string
|
|
10
|
+
compile(value: View, name: string): ViewDefinition;
|
|
11
11
|
}
|
|
@@ -1,27 +1,15 @@
|
|
|
1
|
-
import { compareDefinitionRefs } from '../../addressing/ordering.js';
|
|
2
1
|
import { viewAuthoringInput } from '../view/authoring.js';
|
|
3
2
|
export class V1ViewCompiler {
|
|
4
3
|
context;
|
|
5
4
|
constructor(context) {
|
|
6
5
|
this.context = context;
|
|
7
6
|
}
|
|
8
|
-
compile(value, name
|
|
7
|
+
compile(value, name) {
|
|
9
8
|
const config = viewAuthoringInput(value);
|
|
10
|
-
const target = config.target;
|
|
11
9
|
return {
|
|
12
10
|
ref: { origin: this.context.origin, kind: 'view', name },
|
|
13
11
|
...(config.description === undefined ? {} : { description: config.description }),
|
|
14
|
-
target:
|
|
15
|
-
? { kind: 'domain' }
|
|
16
|
-
: {
|
|
17
|
-
kind: 'definition',
|
|
18
|
-
definitions: (isTargetList(target) ? target : [target])
|
|
19
|
-
.map((entry, index) => this.context.resolveNodeClass(entry, `${pointer}/target/definitions/${index}`))
|
|
20
|
-
.sort(compareDefinitionRefs),
|
|
21
|
-
},
|
|
12
|
+
target: { kind: 'domain' },
|
|
22
13
|
};
|
|
23
14
|
}
|
|
24
15
|
}
|
|
25
|
-
function isTargetList(input) {
|
|
26
|
-
return Array.isArray(input);
|
|
27
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DiagnosticCode as LanguageDiagnosticCode } from '../../language/validation/diagnostic.js';
|
|
2
|
-
export type BuilderDiagnosticCode = LanguageDiagnosticCode | 'BUILDER_ABSTRACT_POLICY' | 'BUILDER_AMBIGUOUS_OWNERSHIP' | 'BUILDER_AUTO_EVENT_INVALID' | 'BUILDER_AUTO_NESTED' | 'BUILDER_AUTO_SET_INVALID' | 'BUILDER_CALLABLE_AUTH' | 'BUILDER_CALLABLE_PLACEMENT' | 'BUILDER_CALLABLE_POLICY_AUTH' | 'BUILDER_CORE_CLASS' | 'BUILDER_CORE_EDGE' | 'BUILDER_CORE_NODE' | 'BUILDER_CORE_PROPERTY' | 'BUILDER_CORE_REF' | 'BUILDER_DEFINITION' | 'BUILDER_DEPENDENCY_CONFLICT' | 'BUILDER_DEPENDENCY_ALIAS' | 'BUILDER_DEPENDENCY_DIRECT' | 'BUILDER_DUPLICATE_MEMBER' | 'BUILDER_FOREIGN_POLICY' | 'BUILDER_FULL_MATCH_INVALID' | 'BUILDER_FUNCTION' | 'BUILDER_METHOD' | 'BUILDER_PATH_DUPLICATE' | 'BUILDER_PATH_EMPTY' | 'BUILDER_POLICY' | 'BUILDER_POLICY_COMPOSITION' | 'BUILDER_POLICY_CYCLE' | 'BUILDER_POLICY_EMPTY_COMPOSITION' | 'BUILDER_POLICY_EMPTY_EXISTS' | 'BUILDER_POLICY_INPUT' | 'BUILDER_POLICY_REF' | 'BUILDER_POLICY_SELF' | 'BUILDER_REFERENCE_CYCLE' | 'BUILDER_REFERENCE_KIND' | 'BUILDER_REFERENCE_MISSING' | 'BUILDER_UNKNOWN_FIELD' | 'BUILDER_UNOWNED_REFERENCE' | 'BUILDER_VIEW' | 'ZOD_SCHEMA_NOT_LOSSLESS';
|
|
2
|
+
export type BuilderDiagnosticCode = LanguageDiagnosticCode | 'BUILDER_ABSTRACT_POLICY' | 'BUILDER_AMBIGUOUS_OWNERSHIP' | 'BUILDER_AUTO_EVENT_INVALID' | 'BUILDER_AUTO_IMMUTABLE' | 'BUILDER_AUTO_NESTED' | 'BUILDER_AUTO_SET_INVALID' | 'BUILDER_CALLABLE_AUTH' | 'BUILDER_CALLABLE_PLACEMENT' | 'BUILDER_CALLABLE_POLICY_AUTH' | 'BUILDER_CORE_CLASS' | 'BUILDER_CORE_EDGE' | 'BUILDER_CORE_NODE' | 'BUILDER_CORE_PROPERTY' | 'BUILDER_CORE_REF' | 'BUILDER_DEFINITION' | 'BUILDER_DEPENDENCY_CONFLICT' | 'BUILDER_DEPENDENCY_ALIAS' | 'BUILDER_DEPENDENCY_DIRECT' | 'BUILDER_DUPLICATE_MEMBER' | 'BUILDER_FOREIGN_POLICY' | 'BUILDER_FULL_MATCH_INVALID' | 'BUILDER_FUNCTION' | 'BUILDER_METHOD' | 'BUILDER_PATH_DUPLICATE' | 'BUILDER_PATH_EMPTY' | 'BUILDER_POLICY' | 'BUILDER_POLICY_COMPOSITION' | 'BUILDER_POLICY_CYCLE' | 'BUILDER_POLICY_EMPTY_COMPOSITION' | 'BUILDER_POLICY_EMPTY_EXISTS' | 'BUILDER_POLICY_INPUT' | 'BUILDER_POLICY_REF' | 'BUILDER_POLICY_SELF' | 'BUILDER_PROPERTY_IMMUTABLE_INVALID' | 'BUILDER_REFERENCE_CYCLE' | 'BUILDER_REFERENCE_KIND' | 'BUILDER_REFERENCE_MISSING' | 'BUILDER_UNKNOWN_FIELD' | 'BUILDER_UNOWNED_REFERENCE' | 'BUILDER_VIEW' | 'ZOD_SCHEMA_NOT_LOSSLESS';
|
|
3
3
|
export interface BuilderDiagnostic<out Code extends BuilderDiagnosticCode = BuilderDiagnosticCode> {
|
|
4
4
|
readonly code: Code;
|
|
5
5
|
readonly pointer: string;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { refuseIRegexp, stateBudgetMessage } from '../../language/value/regexp/syntax.js';
|
|
2
2
|
import { fullMatch as languageFullMatch, } from '../../language/value/syntax/full-match.js';
|
|
3
3
|
import { fail } from '../schema/diagnostic.js';
|
|
4
4
|
export { fullMatchSource } from '../../language/value/syntax/full-match.js';
|
|
5
5
|
/** Authoring facade preserving the Builder-owned diagnostic for invalid source syntax. */
|
|
6
6
|
export function fullMatch(source) {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const refusal = refuseIRegexp(source);
|
|
8
|
+
if (refusal !== undefined) {
|
|
9
|
+
fail('BUILDER_FULL_MATCH_INVALID', '/fullMatch', refusal === 'syntax'
|
|
10
|
+
? 'fullMatch(...) requires a complete RFC 9485 I-Regexp source.'
|
|
11
|
+
: stateBudgetMessage('fullMatch(...)'));
|
|
9
12
|
}
|
|
10
13
|
return languageFullMatch(source);
|
|
11
14
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type { NodeClassReferenceInput } from '../class/authoring.js';
|
|
2
1
|
import type { AUTHORING } from '../schema/handle.js';
|
|
3
|
-
|
|
4
|
-
NodeClassReferenceInput,
|
|
5
|
-
...NodeClassReferenceInput[]
|
|
6
|
-
];
|
|
7
|
-
export type ViewTargetInput = 'domain' | NodeClassReferenceInput | ViewDefinitionTargetsInput;
|
|
2
|
+
/** A View always targets its owning Domain; it declares no Class or Node target. */
|
|
8
3
|
export interface ViewInput {
|
|
9
4
|
readonly description?: string;
|
|
10
|
-
|
|
5
|
+
/** Removed: every View targets its owning Domain. Refused at compile time and at runtime. */
|
|
6
|
+
readonly target?: never;
|
|
11
7
|
}
|
|
12
8
|
export interface View {
|
|
13
9
|
readonly [AUTHORING]: 'view';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertKnownKeys } from '../schema/diagnostic.js';
|
|
1
|
+
import { assertKnownKeys, fail } from '../schema/diagnostic.js';
|
|
2
2
|
import { authoringValue } from '../schema/handle.js';
|
|
3
3
|
const viewInputs = new WeakMap();
|
|
4
4
|
/** Internal lowering access; View authoring handles expose no public configuration object. */
|
|
@@ -9,7 +9,10 @@ export function viewAuthoringInput(value) {
|
|
|
9
9
|
return input;
|
|
10
10
|
}
|
|
11
11
|
export function view(config) {
|
|
12
|
-
|
|
12
|
+
if (Object.hasOwn(config, 'target')) {
|
|
13
|
+
fail('BUILDER_VIEW', '/target', 'View target is removed: every View targets its owning Domain. Select a Node inside the View frontend instead.');
|
|
14
|
+
}
|
|
15
|
+
assertKnownKeys(config, ['description']);
|
|
13
16
|
const value = authoringValue('view', {});
|
|
14
17
|
viewInputs.set(value, { ...config });
|
|
15
18
|
return value;
|
|
@@ -8,6 +8,8 @@ import { admitStateTopology } from '../../language/state/topology.js';
|
|
|
8
8
|
import { bindValueProgram } from '../../language/value/compile/load.js';
|
|
9
9
|
import { isValueObject } from '../../language/value/model/object.js';
|
|
10
10
|
import { classifyValueProgramOrdering } from '../../language/value/ordering.js';
|
|
11
|
+
import { compilePattern } from '../../language/value/regexp/compile.js';
|
|
12
|
+
import { isIRegexp } from '../../language/value/regexp/syntax.js';
|
|
11
13
|
import { invalidCompiled } from '../diagnostic.js';
|
|
12
14
|
import { revisionOfCompiledEntry } from './revision.js';
|
|
13
15
|
import { validateCompiledSemantics } from './semantics.js';
|
|
@@ -24,7 +26,8 @@ export function acceptCompiledSchema(input) {
|
|
|
24
26
|
if (root.version !== 2)
|
|
25
27
|
invalid('version', undefined, '/version');
|
|
26
28
|
const rootPin = dependency(root.root, 'root', '/root');
|
|
27
|
-
const
|
|
29
|
+
const machines = new Map();
|
|
30
|
+
const closure = array(root.closure, 'closure', '/closure').map((value, index) => entry(value, index, `/closure/${index}`, machines));
|
|
28
31
|
if (closure.length > dependencyLimits.closure) {
|
|
29
32
|
invalid('dependency closure limit', 'COMPILED_DEPENDENCY_LIMITS', '/closure');
|
|
30
33
|
}
|
|
@@ -74,7 +77,7 @@ export function acceptCompiledSchema(input) {
|
|
|
74
77
|
validateCompiledSemantics(candidate);
|
|
75
78
|
return deepFreeze(candidate);
|
|
76
79
|
}
|
|
77
|
-
function entry(input, entryIndex, path) {
|
|
80
|
+
function entry(input, entryIndex, path, machines) {
|
|
78
81
|
const value = object(input, `closure[${entryIndex}]`, path);
|
|
79
82
|
exact(value, ['origin', 'revision', 'dependencies', 'definitions', 'facts', 'values', 'patterns'], 'entry', path);
|
|
80
83
|
const origin = originValue(value.origin, 'entry origin', `${path}/origin`);
|
|
@@ -89,7 +92,7 @@ function entry(input, entryIndex, path) {
|
|
|
89
92
|
}
|
|
90
93
|
const valuesPath = `${path}/values`;
|
|
91
94
|
const patternsPath = `${path}/patterns`;
|
|
92
|
-
const patterns = array(value.patterns, 'entry patterns', patternsPath).map((item, index) => pattern(item, index, `${patternsPath}/${index}
|
|
95
|
+
const patterns = array(value.patterns, 'entry patterns', patternsPath).map((item, index) => pattern(item, index, `${patternsPath}/${index}`, machines));
|
|
93
96
|
const values = array(value.values, 'values', valuesPath).map((item, index) => program(item, index, `${valuesPath}/${index}`, patterns));
|
|
94
97
|
const bound = values.map((value) => bindValueProgram(value, patterns));
|
|
95
98
|
const definitionsPath = `${path}/definitions`;
|
|
@@ -195,6 +198,7 @@ function compiledProperty(input, values, node, path) {
|
|
|
195
198
|
exact(value, ['name', 'required', 'value'], 'Compiled Property', path, [
|
|
196
199
|
'auto',
|
|
197
200
|
'description',
|
|
201
|
+
'immutable',
|
|
198
202
|
'ordering',
|
|
199
203
|
'state',
|
|
200
204
|
]);
|
|
@@ -203,6 +207,9 @@ function compiledProperty(input, values, node, path) {
|
|
|
203
207
|
description(value.description, 'Property description', `${path}/description`);
|
|
204
208
|
if (value.auto !== undefined)
|
|
205
209
|
propertyAuto(value.auto, `${path}/auto`);
|
|
210
|
+
if (value.immutable !== undefined && value.immutable !== 'create' && value.immutable !== 'once') {
|
|
211
|
+
invalid('Property immutability', undefined, `${path}/immutable`);
|
|
212
|
+
}
|
|
206
213
|
const valueIndex = index(value.value, values.length, 'Property value', `${path}/value`);
|
|
207
214
|
let state;
|
|
208
215
|
if (value.state !== undefined) {
|
|
@@ -838,10 +845,28 @@ function valueNode(input, nodeIndex, path) {
|
|
|
838
845
|
: { reference: integer(value.reference, 'reference', `${path}/reference`) }),
|
|
839
846
|
};
|
|
840
847
|
}
|
|
841
|
-
|
|
848
|
+
/**
|
|
849
|
+
* Admit one received pattern as data and return the machine compiled from its source. A received
|
|
850
|
+
* machine never decides membership: it may come from another compiler, from a host with other
|
|
851
|
+
* Unicode data, or from a forger, and the artifact carries no compiler version that could tell a
|
|
852
|
+
* current machine from those, so it is ignored rather than compared. Its source decides, through
|
|
853
|
+
* the same bounded `isIRegexp` and `compilePattern` that source resolution uses.
|
|
854
|
+
*/
|
|
855
|
+
function pattern(input, patternIndex, path, machines) {
|
|
842
856
|
const value = object(input, `patterns[${patternIndex}]`, path);
|
|
843
|
-
|
|
844
|
-
|
|
857
|
+
const { source } = Object.hasOwn(value, 'runs')
|
|
858
|
+
? runPattern(value, path)
|
|
859
|
+
: nfaPattern(value, path);
|
|
860
|
+
let machine = machines.get(source);
|
|
861
|
+
if (machine === undefined) {
|
|
862
|
+
if (!isIRegexp(source))
|
|
863
|
+
invalid('Pattern source', 'COMPILED_SOURCE_INVALID', `${path}/source`);
|
|
864
|
+
machine = compilePattern(source);
|
|
865
|
+
machines.set(source, machine);
|
|
866
|
+
}
|
|
867
|
+
return machine;
|
|
868
|
+
}
|
|
869
|
+
function nfaPattern(value, path) {
|
|
845
870
|
exact(value, ['source', 'start', 'states'], 'Pattern', path);
|
|
846
871
|
if (typeof value.source !== 'string')
|
|
847
872
|
invalid('Pattern source', undefined, `${path}/source`);
|
|
@@ -21,10 +21,11 @@ export function validateCompiledSemantics(candidate) {
|
|
|
21
21
|
const partial = index(candidate);
|
|
22
22
|
const analyses = analyzeClasses(partial.classes);
|
|
23
23
|
const context = { ...partial, analyses };
|
|
24
|
+
const admitted = admittedOrigins(candidate);
|
|
24
25
|
validateClassFacets(context);
|
|
25
|
-
validateEdges(context);
|
|
26
|
+
validateEdges(context, admitted);
|
|
26
27
|
validateViews(candidate, context);
|
|
27
|
-
validatePolicies(candidate, context);
|
|
28
|
+
validatePolicies(candidate, context, admitted);
|
|
28
29
|
validateCore(candidate, context);
|
|
29
30
|
}
|
|
30
31
|
function index(candidate) {
|
|
@@ -161,6 +162,14 @@ function validateClassFacets(context) {
|
|
|
161
162
|
fail(`${path}/auto/set`, 'The instant setter requires an Instant value program.');
|
|
162
163
|
}
|
|
163
164
|
}
|
|
165
|
+
if (property.immutable !== undefined) {
|
|
166
|
+
if (property.auto !== undefined || property.state !== undefined) {
|
|
167
|
+
fail(`${path}/immutable`, 'An immutable Property is neither automatic nor a State Property.');
|
|
168
|
+
}
|
|
169
|
+
if (property.immutable === 'once' && property.required) {
|
|
170
|
+
fail(`${path}/immutable`, 'A required immutable Property is declared create, not once.');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
164
173
|
}
|
|
165
174
|
if (located.value.kind === 'node') {
|
|
166
175
|
for (const [index, method] of located.value.methods.entries()) {
|
|
@@ -171,7 +180,30 @@ function validateClassFacets(context) {
|
|
|
171
180
|
}
|
|
172
181
|
}
|
|
173
182
|
}
|
|
174
|
-
|
|
183
|
+
/**
|
|
184
|
+
* The origins each closure entry was admitted against: itself and its transitive dependencies.
|
|
185
|
+
* Source admission decides undirected overlap and types Policies within that closure alone, so a
|
|
186
|
+
* dependent's Class extending a dependency's Classes never reaches the dependency's own decisions.
|
|
187
|
+
*/
|
|
188
|
+
function admittedOrigins(candidate) {
|
|
189
|
+
const entries = new Map(candidate.closure.map((entry) => [entry.origin, entry]));
|
|
190
|
+
const scopes = new Map();
|
|
191
|
+
const scope = (origin) => {
|
|
192
|
+
const known = scopes.get(origin);
|
|
193
|
+
if (known !== undefined)
|
|
194
|
+
return known;
|
|
195
|
+
const origins = new Set([origin]);
|
|
196
|
+
for (const dependency of Object.values(entries.get(origin)?.dependencies ?? {}))
|
|
197
|
+
for (const reached of scope(dependency.origin))
|
|
198
|
+
origins.add(reached);
|
|
199
|
+
scopes.set(origin, origins);
|
|
200
|
+
return origins;
|
|
201
|
+
};
|
|
202
|
+
for (const entry of candidate.closure)
|
|
203
|
+
scope(entry.origin);
|
|
204
|
+
return scopes;
|
|
205
|
+
}
|
|
206
|
+
function validateEdges(context, admitted) {
|
|
175
207
|
for (const located of context.classes.values()) {
|
|
176
208
|
if (!isCompiledEdge(located.value))
|
|
177
209
|
continue;
|
|
@@ -194,7 +226,7 @@ function validateEdges(context) {
|
|
|
194
226
|
}
|
|
195
227
|
if (edge.orientation === 'undirected' &&
|
|
196
228
|
!sameIncidentEndpoint(edge.endpoints[0], edge.endpoints[1]) &&
|
|
197
|
-
undirectedOverlap(context, edge.endpoints)) {
|
|
229
|
+
undirectedOverlap(context, edge.endpoints, admitted.get(located.entry.origin))) {
|
|
198
230
|
fail(`${located.pointer}/endpoints`, 'Unequal undirected endpoint contracts overlap.');
|
|
199
231
|
}
|
|
200
232
|
for (const [parentIndex, parentRef] of edge.extends.entries()) {
|
|
@@ -242,8 +274,9 @@ function sameIncidentEndpoint(left, right) {
|
|
|
242
274
|
a.length === b.length &&
|
|
243
275
|
a.every((value, index) => value === b[index]));
|
|
244
276
|
}
|
|
245
|
-
function undirectedOverlap(context, endpoints) {
|
|
246
|
-
return [...context.classes.values()].some(({ value }) => value.
|
|
277
|
+
function undirectedOverlap(context, endpoints, origins) {
|
|
278
|
+
return [...context.classes.values()].some(({ value }) => origins.has(value.ref.origin) &&
|
|
279
|
+
value.kind === 'node' &&
|
|
247
280
|
!value.abstract &&
|
|
248
281
|
classSatisfiesAny(context, value.ref, endpoints[0].accepts) &&
|
|
249
282
|
classSatisfiesAny(context, value.ref, endpoints[1].accepts));
|
|
@@ -274,14 +307,14 @@ function validateViews(candidate, context) {
|
|
|
274
307
|
}
|
|
275
308
|
}
|
|
276
309
|
}
|
|
277
|
-
function validatePolicies(candidate, context) {
|
|
310
|
+
function validatePolicies(candidate, context, admitted) {
|
|
278
311
|
for (const [entryIndex, entry] of candidate.closure.entries()) {
|
|
279
312
|
const localPolicies = new Map(entry.definitions.policies.map((value) => [value.ref.name, value]));
|
|
280
313
|
for (const [policyIndex, policy] of entry.definitions.policies.entries()) {
|
|
281
314
|
validatePolicyExpression(context, entry, policy.expression, `/closure/${entryIndex}/definitions/policies/${policyIndex}/expression`, localPolicies);
|
|
282
315
|
}
|
|
283
316
|
validatePolicyCycles(entry, localPolicies, entryIndex);
|
|
284
|
-
validatePolicyParity(context, entry, entryIndex, localPolicies);
|
|
317
|
+
validatePolicyParity(context, entry, entryIndex, localPolicies, admitted.get(entry.origin));
|
|
285
318
|
for (const [functionIndex, callable] of entry.definitions.functions.entries()) {
|
|
286
319
|
if (callable.policy !== undefined)
|
|
287
320
|
validateCallablePolicy(context, entry, callable.policy, typeof callable.input === 'number' ? callable.input : callable.input.metadata, callable.fields, false, `/closure/${entryIndex}/definitions/functions/${functionIndex}/policy`);
|
|
@@ -455,9 +488,9 @@ function isNodeClassRef(context, value) {
|
|
|
455
488
|
}
|
|
456
489
|
return context.classes.get(Key.of(ref))?.value.kind === 'node';
|
|
457
490
|
}
|
|
458
|
-
function validatePolicyParity(context, entry, entryIndex, policies) {
|
|
491
|
+
function validatePolicyParity(context, entry, entryIndex, policies, origins) {
|
|
459
492
|
const normalized = new Map([...policies].map(([name, policy]) => [name, normalizePolicyExpression(policy.expression)]));
|
|
460
|
-
const typing = new CompiledPolicyTyping(context, entry, normalized);
|
|
493
|
+
const typing = new CompiledPolicyTyping(context, entry, normalized, origins);
|
|
461
494
|
for (const [name, declaration] of policies) {
|
|
462
495
|
const path = `/closure/${entryIndex}/definitions/policies/${declarationIndex(entry, 'policies', name)}`;
|
|
463
496
|
if ('match' in declaration.expression) {
|
|
@@ -602,21 +635,21 @@ function nodePathAccepts(entry, input, field) {
|
|
|
602
635
|
? annotation.accepts
|
|
603
636
|
: [];
|
|
604
637
|
}
|
|
638
|
+
/** Types one entry's Policies against the Node Classes of its own closure, as source admission. */
|
|
605
639
|
class CompiledPolicyTyping {
|
|
606
640
|
context;
|
|
607
641
|
entry;
|
|
608
642
|
normalized;
|
|
609
643
|
allNodeClasses;
|
|
610
644
|
concreteNodeClasses;
|
|
611
|
-
constructor(context, entry, normalized) {
|
|
645
|
+
constructor(context, entry, normalized, origins) {
|
|
612
646
|
this.context = context;
|
|
613
647
|
this.entry = entry;
|
|
614
648
|
this.normalized = normalized;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
.filter(({ value }) => value.kind === 'node' && !value.abstract)
|
|
649
|
+
const nodeClasses = [...context.classes.values()].filter(({ value }) => value.kind === 'node' && origins.has(value.ref.origin));
|
|
650
|
+
this.allNodeClasses = nodeClasses.map(({ value }) => value.ref);
|
|
651
|
+
this.concreteNodeClasses = nodeClasses
|
|
652
|
+
.filter(({ value }) => !value.abstract)
|
|
620
653
|
.map(({ value }) => value.ref);
|
|
621
654
|
}
|
|
622
655
|
expandedBranches(name, visiting, namespace) {
|
|
@@ -54,6 +54,7 @@ function compileEntry(schema, lookup) {
|
|
|
54
54
|
name,
|
|
55
55
|
required: property.required,
|
|
56
56
|
...(property.auto === undefined ? {} : { auto: property.auto }),
|
|
57
|
+
...(property.immutable === undefined ? {} : { immutable: property.immutable }),
|
|
57
58
|
...(property.description === undefined ? {} : { description: property.description }),
|
|
58
59
|
...(property.state === undefined ? {} : { state: property.state }),
|
|
59
60
|
...(ordering === undefined ? {} : { ordering }),
|
|
@@ -125,6 +125,7 @@ function programValidation(programs, properties, propertyOrdering, callables) {
|
|
|
125
125
|
propertyValidation.set(key, Object.freeze({
|
|
126
126
|
ordering: propertyOrdering.get(key),
|
|
127
127
|
validate: (value) => validateValueProgram(program, value),
|
|
128
|
+
program: () => program,
|
|
128
129
|
}));
|
|
129
130
|
}
|
|
130
131
|
const callableValidation = new Map();
|
package/dist/v1/domain/create.js
CHANGED
|
@@ -104,24 +104,6 @@ export function createDomain(input) {
|
|
|
104
104
|
definitions(kind) {
|
|
105
105
|
return kind === undefined ? local : local.filter(({ ref }) => ref.kind === kind);
|
|
106
106
|
},
|
|
107
|
-
viewsFor(target) {
|
|
108
|
-
return Object.freeze(Object.values(views).filter((view) => {
|
|
109
|
-
if (view.target.kind === 'domain')
|
|
110
|
-
return target === 'domain';
|
|
111
|
-
if (target === 'domain')
|
|
112
|
-
return false;
|
|
113
|
-
return view.target.definitions.some((ref) => {
|
|
114
|
-
const selected = classesByKey.get(Key.of(ref));
|
|
115
|
-
if (target.kind === 'node' && selected?.kind === 'node') {
|
|
116
|
-
return target.satisfies(selected);
|
|
117
|
-
}
|
|
118
|
-
if (target.kind === 'edge' && selected?.kind === 'edge') {
|
|
119
|
-
return target.satisfies(selected);
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
});
|
|
123
|
-
}));
|
|
124
|
-
},
|
|
125
107
|
};
|
|
126
108
|
const admitted = Object.freeze(domain);
|
|
127
109
|
facades.set(entry.origin, admitted);
|
|
@@ -175,7 +157,6 @@ function createDefinitions(declarations, classesByKey, input) {
|
|
|
175
157
|
definitionsByKey.set(key, Object.freeze({
|
|
176
158
|
ref: definition.ref,
|
|
177
159
|
key,
|
|
178
|
-
target: definition.target,
|
|
179
160
|
description: definition.description,
|
|
180
161
|
definition,
|
|
181
162
|
}));
|
|
@@ -36,7 +36,6 @@ export interface Domain<Classes extends Readonly<Record<string, unknown>> = Read
|
|
|
36
36
|
callable(key: Key.Callable): ResolvedCallable | undefined;
|
|
37
37
|
definitions(): readonly ResolvedDefinition[];
|
|
38
38
|
definitions<const Kind extends DefinitionRef['kind']>(kind: Kind): readonly ResolvedDefinitionOf<Kind>[];
|
|
39
|
-
viewsFor(target: 'domain' | AnyResolvedClass): readonly Views[keyof Views][];
|
|
40
39
|
}
|
|
41
40
|
declare const DOMAIN_SOURCE_RESOLVED: unique symbol;
|
|
42
41
|
/** Type-only witness carried by a source that retains its exact resolved Domain. */
|
|
@@ -3,6 +3,7 @@ import type { DomainDependency, DomainDependencyMap } from '../../addressing/ind
|
|
|
3
3
|
import type { CoreEdge } from '../../language/core/model/core.js';
|
|
4
4
|
import type { Definition } from '../../language/definition.js';
|
|
5
5
|
import type { Diagnostic } from '../../language/validation/diagnostic.js';
|
|
6
|
+
import type { ValueProgram } from '../../language/value/compile/model.js';
|
|
6
7
|
import type { OrderingKind } from '../../language/value/ordering.js';
|
|
7
8
|
/** One admitted Schema entry in a dependency-closed Domain universe. */
|
|
8
9
|
export interface DomainEntryInput {
|
|
@@ -22,6 +23,8 @@ export interface DomainInput {
|
|
|
22
23
|
export interface DomainValidation {
|
|
23
24
|
propertyExists(key: PropertyKey): boolean;
|
|
24
25
|
property(key: PropertyKey, input: unknown): readonly Diagnostic[];
|
|
26
|
+
/** The admitted program `property` evaluates. */
|
|
27
|
+
propertyProgram(key: PropertyKey): ValueProgram;
|
|
25
28
|
propertyOrdering(key: PropertyKey): OrderingKind | undefined;
|
|
26
29
|
callableExists(key: AddressKey.Callable): boolean;
|
|
27
30
|
callableInput(key: AddressKey.Callable, input: unknown): readonly Diagnostic[];
|
|
@@ -45,6 +45,7 @@ export function createClasses(definitions, validation) {
|
|
|
45
45
|
definition: propertyDefinition,
|
|
46
46
|
...(ordering === undefined ? {} : { ordering }),
|
|
47
47
|
validate: (input) => validation.property(propertyKey, input),
|
|
48
|
+
program: () => validation.propertyProgram(propertyKey),
|
|
48
49
|
});
|
|
49
50
|
ownProperties.push(property);
|
|
50
51
|
effectiveProperties.set(property.key, property);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Key, PropertyKey } from '../../addressing/index.js';
|
|
2
2
|
import type { Diagnostic } from '../../language/validation/diagnostic.js';
|
|
3
|
+
import type { ValueProgram } from '../../language/value/compile/model.js';
|
|
3
4
|
import type { OrderingKind } from '../../language/value/ordering.js';
|
|
4
5
|
import type { DomainValidation } from '../model/input.js';
|
|
5
6
|
export interface PropertyValidation {
|
|
6
7
|
readonly ordering?: OrderingKind;
|
|
7
8
|
validate(input: unknown): readonly Diagnostic[];
|
|
9
|
+
program(): ValueProgram;
|
|
8
10
|
}
|
|
9
11
|
export interface CallableValidation {
|
|
10
12
|
readonly fields?: readonly string[];
|
|
@@ -6,6 +6,12 @@ export function createDomainValidation(properties, callables) {
|
|
|
6
6
|
const target = properties.get(key);
|
|
7
7
|
return target === undefined ? unknownTarget('Property', key) : target.validate(input);
|
|
8
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
|
+
},
|
|
9
15
|
propertyOrdering: (key) => properties.get(key)?.ordering,
|
|
10
16
|
callableExists: (key) => callables.has(key),
|
|
11
17
|
callableInput(key, input) {
|
|
@@ -33,6 +39,12 @@ export function combineDomainValidation(values) {
|
|
|
33
39
|
const owner = values.find((value) => value.propertyExists(key));
|
|
34
40
|
return owner === undefined ? unknownTarget('Property', key) : owner.property(key, input);
|
|
35
41
|
},
|
|
42
|
+
propertyProgram(key) {
|
|
43
|
+
const owner = values.find((value) => value.propertyExists(key));
|
|
44
|
+
if (owner === undefined)
|
|
45
|
+
throw new TypeError(`Property ${key} is absent.`);
|
|
46
|
+
return owner.propertyProgram(key);
|
|
47
|
+
},
|
|
36
48
|
propertyOrdering: (key) => values.find((value) => value.propertyExists(key))?.propertyOrdering(key),
|
|
37
49
|
callableExists: (key) => values.some((value) => value.callableExists(key)),
|
|
38
50
|
callableInput(key, input) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type AutoEvent = 'create' | 'update';
|
|
2
2
|
export type AutoSet = 'instant';
|
|
3
|
+
/** `create`: written only by node or edge creation. `once`: written while absent, never unset. */
|
|
4
|
+
export type PropertyImmutability = 'create' | 'once';
|
|
3
5
|
export interface PropertyAuto {
|
|
4
6
|
readonly on: readonly AutoEvent[];
|
|
5
7
|
readonly set: AutoSet;
|
|
@@ -8,6 +10,7 @@ export interface PropertyDefinition {
|
|
|
8
10
|
readonly schema: import('../../value/model/schema.js').JsonSchema;
|
|
9
11
|
readonly required: boolean;
|
|
10
12
|
readonly auto?: PropertyAuto;
|
|
13
|
+
readonly immutable?: PropertyImmutability;
|
|
11
14
|
readonly description?: string;
|
|
12
15
|
readonly state?: import('../../state/index.js').StateTopology;
|
|
13
16
|
}
|
|
@@ -3,6 +3,7 @@ import type { ClassRef, DefinitionKey, Key, PropertyKey } from '../../addressing
|
|
|
3
3
|
import type { ResolvedMethodCollection } from '../callable/resolved.js';
|
|
4
4
|
import type { StateTopology } from '../state/index.js';
|
|
5
5
|
import type { Diagnostic } from '../validation/diagnostic.js';
|
|
6
|
+
import type { ValueProgram } from '../value/compile/model.js';
|
|
6
7
|
import type { OrderingKind } from '../value/ordering.js';
|
|
7
8
|
import type { ClassDefinition, ClassKind } from './model/class.js';
|
|
8
9
|
import type { DataDefinition } from './model/data.js';
|
|
@@ -19,6 +20,8 @@ export interface ResolvedProperty<out Value = PortableValue, out Required extend
|
|
|
19
20
|
/** The one portable scalar ordering domain, when the Property is orderable. */
|
|
20
21
|
readonly ordering?: OrderingKind;
|
|
21
22
|
validate(input: unknown): readonly Diagnostic[];
|
|
23
|
+
/** The admitted program `validate` evaluates. */
|
|
24
|
+
program(): ValueProgram;
|
|
22
25
|
readonly __value?: Value;
|
|
23
26
|
readonly __input?: Input;
|
|
24
27
|
}
|
|
@@ -4,6 +4,8 @@ export type { ClassRef, CoreRef, DefinitionBase, DefinitionKey, DefinitionRef, F
|
|
|
4
4
|
export type { Value as PropertyValue } from '@astrale-os/kernel-dsl/value';
|
|
5
5
|
export type { JsonSchema as ValueSchema, JsonSchemaObject as ValueSchemaObject, } from './value/model/schema.js';
|
|
6
6
|
export type { OrderingKind } from './value/ordering.js';
|
|
7
|
+
export type { ValueProgram } from './value/compile/model.js';
|
|
8
|
+
export { valueProgramIncludes } from './value/inclusion/includes.js';
|
|
7
9
|
export { stateMachine } from './state/index.js';
|
|
8
10
|
export type { EventOf, StateMachine, StateOf, StateTopology } from './state/index.js';
|
|
9
11
|
export type * from './callable/model/callable.js';
|