@astrale-os/kernel-dsl 0.2.0-beta.8 → 1.0.0-beta.1
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/addressing/patterns.d.ts +0 -5
- package/dist/v1/addressing/patterns.js +5 -5
- package/dist/v1/builder/callable/authoring.d.ts +87 -41
- package/dist/v1/builder/callable/authoring.js +29 -14
- package/dist/v1/builder/class/authoring.d.ts +311 -36
- package/dist/v1/builder/class/authoring.js +3 -4
- package/dist/v1/builder/class/property.d.ts +16 -8
- package/dist/v1/builder/class/property.js +21 -5
- package/dist/v1/builder/core/authoring.d.ts +28 -13
- package/dist/v1/builder/core/authoring.js +22 -2
- package/dist/v1/builder/index.d.ts +9 -8
- package/dist/v1/builder/index.js +2 -2
- package/dist/v1/builder/lowering/callable.d.ts +3 -1
- package/dist/v1/builder/lowering/callable.js +43 -51
- package/dist/v1/builder/lowering/class.d.ts +7 -0
- package/dist/v1/builder/lowering/class.js +79 -29
- package/dist/v1/builder/lowering/core.d.ts +3 -2
- package/dist/v1/builder/lowering/core.js +9 -6
- package/dist/v1/builder/lowering/policy.d.ts +8 -1
- package/dist/v1/builder/lowering/policy.js +35 -0
- package/dist/v1/builder/lowering/schema/capture.js +9 -4
- package/dist/v1/builder/lowering/schema/compile.d.ts +2 -2
- package/dist/v1/builder/lowering/schema/compile.js +15 -2
- package/dist/v1/builder/lowering/schema/context.d.ts +11 -8
- package/dist/v1/builder/lowering/schema/context.js +59 -29
- package/dist/v1/builder/lowering/schema/ownership.d.ts +3 -3
- package/dist/v1/builder/lowering/schema/ownership.js +2 -1
- package/dist/v1/builder/lowering/value/compile.js +14 -4
- package/dist/v1/builder/lowering/value/zod.d.ts +7 -6
- package/dist/v1/builder/lowering/value/zod.js +16 -7
- package/dist/v1/builder/lowering/view.d.ts +4 -3
- package/dist/v1/builder/lowering/view.js +2 -14
- package/dist/v1/builder/policy/authoring.d.ts +23 -6
- package/dist/v1/builder/policy/authoring.js +35 -8
- package/dist/v1/builder/schema/define.d.ts +8 -5
- package/dist/v1/builder/schema/diagnostic.d.ts +1 -1
- package/dist/v1/builder/schema/handle.d.ts +2 -1
- package/dist/v1/builder/schema/input.d.ts +9 -1
- package/dist/v1/builder/schema/projection/callable.d.ts +51 -0
- package/dist/v1/builder/schema/projection/callable.js +1 -0
- package/dist/v1/builder/schema/projection/class.d.ts +89 -0
- package/dist/v1/builder/schema/projection/class.js +1 -0
- package/dist/v1/builder/schema/projection/core-input.d.ts +32 -0
- package/dist/v1/builder/schema/projection/core-input.js +1 -0
- package/dist/v1/builder/schema/projection/domain.d.ts +59 -0
- package/dist/v1/builder/schema/projection/domain.js +1 -0
- package/dist/v1/builder/schema/projection/identity.d.ts +39 -0
- package/dist/v1/builder/schema/projection/identity.js +1 -0
- package/dist/v1/builder/schema/projection/model.d.ts +59 -0
- package/dist/v1/builder/schema/projection/model.js +1 -0
- package/dist/v1/builder/schema/projection/property.d.ts +32 -0
- package/dist/v1/builder/schema/projection/property.js +1 -0
- package/dist/v1/builder/schema/projection/resolved-class.d.ts +76 -0
- package/dist/v1/builder/schema/projection/resolved-class.js +1 -0
- package/dist/v1/builder/schema/projection.d.ts +4 -258
- package/dist/v1/builder/value/full-match.js +6 -3
- package/dist/v1/builder/value/path.d.ts +2 -2
- package/dist/v1/builder/value/path.js +2 -2
- package/dist/v1/builder/view/authoring.d.ts +6 -14
- package/dist/v1/builder/view/authoring.js +13 -5
- package/dist/v1/bundle/structure.d.ts +2 -1
- package/dist/v1/compiled/admission/accept.d.ts +1 -1
- package/dist/v1/compiled/admission/accept.js +11 -814
- package/dist/v1/compiled/admission/closure.d.ts +3 -0
- package/dist/v1/compiled/admission/closure.js +173 -0
- package/dist/v1/compiled/admission/diagnostic.d.ts +7 -0
- package/dist/v1/compiled/admission/diagnostic.js +13 -0
- package/dist/v1/compiled/admission/revision.js +9 -1
- package/dist/v1/compiled/admission/semantics/cardinality.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/cardinality.js +113 -0
- package/dist/v1/compiled/admission/semantics/class.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/class.js +125 -0
- package/dist/v1/compiled/admission/semantics/context.d.ts +60 -0
- package/dist/v1/compiled/admission/semantics/context.js +81 -0
- package/dist/v1/compiled/admission/semantics/core.d.ts +35 -0
- package/dist/v1/compiled/admission/semantics/core.js +123 -0
- package/dist/v1/compiled/admission/semantics/edge.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/edge.js +89 -0
- package/dist/v1/compiled/admission/semantics/policy/admit.d.ts +4 -0
- package/dist/v1/compiled/admission/semantics/policy/admit.js +63 -0
- package/dist/v1/compiled/admission/semantics/policy/callable.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/policy/callable.js +72 -0
- package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +24 -0
- package/dist/v1/compiled/admission/semantics/policy/contracts.js +45 -0
- package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/policy/equality.js +27 -0
- package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +9 -0
- package/dist/v1/compiled/admission/semantics/policy/measure.js +81 -0
- package/dist/v1/compiled/admission/semantics/policy/parity.d.ts +4 -0
- package/dist/v1/compiled/admission/semantics/policy/parity.js +138 -0
- package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/policy/pattern.js +78 -0
- package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +28 -0
- package/dist/v1/compiled/admission/semantics/policy/typing.js +206 -0
- package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +10 -0
- package/dist/v1/compiled/admission/semantics/policy/variants.js +65 -0
- package/dist/v1/compiled/admission/semantics.d.ts +1 -1
- package/dist/v1/compiled/admission/semantics.js +8 -1078
- package/dist/v1/compiled/admission/wire/callable.d.ts +6 -0
- package/dist/v1/compiled/admission/wire/callable.js +90 -0
- package/dist/v1/compiled/admission/wire/class.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/class.js +133 -0
- package/dist/v1/compiled/admission/wire/core.d.ts +5 -0
- package/dist/v1/compiled/admission/wire/core.js +32 -0
- package/dist/v1/compiled/admission/wire/dependency.d.ts +14 -0
- package/dist/v1/compiled/admission/wire/dependency.js +43 -0
- package/dist/v1/compiled/admission/wire/entry.d.ts +5 -0
- package/dist/v1/compiled/admission/wire/entry.js +100 -0
- package/dist/v1/compiled/admission/wire/pattern.d.ts +12 -0
- package/dist/v1/compiled/admission/wire/pattern.js +111 -0
- package/dist/v1/compiled/admission/wire/policy.d.ts +10 -0
- package/dist/v1/compiled/admission/wire/policy.js +189 -0
- package/dist/v1/compiled/admission/wire/program.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/program.js +52 -0
- package/dist/v1/compiled/admission/wire/property.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/property.js +74 -0
- package/dist/v1/compiled/admission/wire/reference.d.ts +8 -0
- package/dist/v1/compiled/admission/wire/reference.js +33 -0
- package/dist/v1/compiled/admission/wire/value.d.ts +29 -0
- package/dist/v1/compiled/admission/wire/value.js +98 -0
- package/dist/v1/compiled/admission/wire/view.d.ts +3 -0
- package/dist/v1/compiled/admission/wire/view.js +17 -0
- package/dist/v1/compiled/compiler/compile.js +43 -11
- package/dist/v1/compiled/generated.d.ts +10 -0
- package/dist/v1/compiled/generated.js +15 -0
- package/dist/v1/compiled/loader/load.d.ts +5 -0
- package/dist/v1/compiled/loader/load.js +18 -4
- package/dist/v1/compiled/model/schema.d.ts +16 -7
- package/dist/v1/domain/create.js +18 -28
- 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 +13 -41
- package/dist/v1/domain/validation/create.d.ts +2 -0
- package/dist/v1/domain/validation/create.js +12 -0
- package/dist/v1/index.d.ts +5 -2
- package/dist/v1/index.js +3 -1
- package/dist/v1/language/callable/composition.d.ts +27 -0
- package/dist/v1/language/callable/composition.js +52 -0
- package/dist/v1/language/callable/executable.d.ts +6 -0
- package/dist/v1/language/callable/executable.js +4 -0
- package/dist/v1/language/callable/model/callable.d.ts +34 -9
- package/dist/v1/language/callable/model/callable.js +3 -1
- package/dist/v1/language/callable/resolved.d.ts +23 -8
- package/dist/v1/language/class/facets.d.ts +5 -2
- package/dist/v1/language/class/inheritance.d.ts +12 -0
- package/dist/v1/language/class/inheritance.js +25 -0
- package/dist/v1/language/class/lifetime.d.ts +17 -0
- package/dist/v1/language/class/lifetime.js +26 -0
- package/dist/v1/language/class/model/class.d.ts +8 -4
- package/dist/v1/language/class/model/property.d.ts +4 -2
- package/dist/v1/language/class/property-values.js +5 -2
- package/dist/v1/language/class/resolved.d.ts +25 -15
- package/dist/v1/language/core/model/core.d.ts +7 -1
- package/dist/v1/language/core/resolved.d.ts +6 -2
- package/dist/v1/language/definition/metadata.d.ts +8 -0
- package/dist/v1/language/definition/metadata.js +12 -0
- package/dist/v1/language/index.d.ts +9 -0
- package/dist/v1/language/index.js +6 -0
- package/dist/v1/language/policy/analysis/branches.d.ts +4 -3
- package/dist/v1/language/policy/analysis/branches.js +54 -12
- package/dist/v1/language/policy/analysis/budgets.js +1 -1
- package/dist/v1/language/policy/analysis/checks.d.ts +28 -0
- package/dist/v1/language/policy/analysis/checks.js +80 -0
- package/dist/v1/language/policy/index.d.ts +1 -0
- package/dist/v1/language/policy/index.js +1 -0
- package/dist/v1/language/policy/model/policy.d.ts +71 -5
- package/dist/v1/language/policy/model/policy.js +52 -1
- package/dist/v1/language/policy/normalization/normalize.d.ts +12 -1
- package/dist/v1/language/policy/normalization/normalize.js +178 -44
- package/dist/v1/language/state/index.d.ts +3 -0
- package/dist/v1/language/state/index.js +1 -0
- package/dist/v1/language/state/machine.d.ts +28 -0
- package/dist/v1/language/state/machine.js +40 -0
- package/dist/v1/language/state/topology.d.ts +14 -0
- package/dist/v1/language/state/topology.js +69 -0
- package/dist/v1/language/value/compile/fields.d.ts +1 -1
- package/dist/v1/language/value/compile/load.d.ts +4 -2
- package/dist/v1/language/value/compile/load.js +22 -1
- package/dist/v1/language/value/compile/model.d.ts +16 -1
- package/dist/v1/language/value/evaluate/assertions.d.ts +2 -0
- package/dist/v1/language/value/evaluate/assertions.js +13 -0
- package/dist/v1/language/value/evaluate/evaluator.js +111 -28
- package/dist/v1/language/value/evaluate/preparation.d.ts +10 -1
- package/dist/v1/language/value/evaluate/preparation.js +17 -26
- package/dist/v1/language/value/evaluate/program.js +1 -1
- package/dist/v1/language/value/evaluate/validate.d.ts +6 -2
- package/dist/v1/language/value/evaluate/validate.js +18 -11
- 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/model/blob.d.ts +31 -0
- package/dist/v1/language/value/model/blob.js +90 -0
- package/dist/v1/language/value/model/instant.d.ts +0 -2
- package/dist/v1/language/value/model/instant.js +1 -1
- package/dist/v1/language/value/model/schema.d.ts +2 -1
- package/dist/v1/language/value/model/schema.js +1 -5
- package/dist/v1/language/value/ordering.d.ts +2 -0
- package/dist/v1/language/value/ordering.js +4 -8
- package/dist/v1/language/value/profile/json.validate.js +1 -1
- package/dist/v1/language/value/profile/rules.js +48 -12
- package/dist/v1/language/value/reference/registry.d.ts +2 -1
- package/dist/v1/language/value/regexp/ast.js +3 -64
- package/dist/v1/language/value/regexp/compile.d.ts +32 -3
- package/dist/v1/language/value/regexp/compile.js +117 -21
- package/dist/v1/language/value/regexp/matcher.d.ts +6 -3
- package/dist/v1/language/value/regexp/matcher.js +185 -28
- package/dist/v1/language/value/regexp/syntax.d.ts +12 -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 +8 -5
- package/dist/v1/language/value/syntax/node-path/validate.js +4 -6
- package/dist/v1/language/view/model/view.d.ts +2 -4
- package/dist/v1/language/view/resolved.d.ts +2 -2
- package/dist/v1/schema/analysis/class.d.ts +36 -6
- package/dist/v1/schema/analysis/class.js +31 -66
- package/dist/v1/schema/canonical/revision.d.ts +2 -1
- package/dist/v1/schema/canonical/revision.js +4 -1
- package/dist/v1/schema/compatibility/api.d.ts +3 -0
- package/dist/v1/schema/compatibility/api.js +2 -0
- package/dist/v1/schema/compatibility/comparators/callables.d.ts +39 -0
- package/dist/v1/schema/compatibility/comparators/callables.js +101 -0
- package/dist/v1/schema/compatibility/comparators/classes.d.ts +47 -0
- package/dist/v1/schema/compatibility/comparators/classes.js +160 -0
- package/dist/v1/schema/compatibility/comparators/index.d.ts +12 -0
- package/dist/v1/schema/compatibility/comparators/index.js +53 -0
- package/dist/v1/schema/compatibility/comparators/members.d.ts +4 -0
- package/dist/v1/schema/compatibility/comparators/members.js +49 -0
- package/dist/v1/schema/compatibility/comparators/values.d.ts +5 -0
- package/dist/v1/schema/compatibility/comparators/values.js +37 -0
- package/dist/v1/schema/compatibility/compare.d.ts +5 -0
- package/dist/v1/schema/compatibility/compare.js +23 -0
- package/dist/v1/schema/compatibility/context.d.ts +19 -0
- package/dist/v1/schema/compatibility/context.js +49 -0
- package/dist/v1/schema/compatibility/coordinate.d.ts +40 -0
- package/dist/v1/schema/compatibility/coordinate.js +38 -0
- package/dist/v1/schema/compatibility/diff.d.ts +12 -0
- package/dist/v1/schema/compatibility/diff.js +39 -0
- package/dist/v1/schema/compatibility/evidence.d.ts +16 -0
- package/dist/v1/schema/compatibility/evidence.js +62 -0
- package/dist/v1/schema/compatibility/fields.d.ts +194 -0
- package/dist/v1/schema/compatibility/fields.js +94 -0
- package/dist/v1/schema/compatibility/index.d.ts +6 -0
- package/dist/v1/schema/compatibility/index.js +3 -0
- package/dist/v1/schema/compatibility/meaning/footprint.d.ts +7 -0
- package/dist/v1/schema/compatibility/meaning/footprint.js +59 -0
- package/dist/v1/schema/compatibility/meaning/index.d.ts +3 -0
- package/dist/v1/schema/compatibility/meaning/index.js +16 -0
- package/dist/v1/schema/compatibility/model.d.ts +131 -0
- package/dist/v1/schema/compatibility/model.js +1 -0
- package/dist/v1/schema/compatibility/references.d.ts +38 -0
- package/dist/v1/schema/compatibility/references.js +149 -0
- package/dist/v1/schema/compatibility/report.d.ts +27 -0
- package/dist/v1/schema/compatibility/report.js +100 -0
- package/dist/v1/schema/compatibility/scope.d.ts +36 -0
- package/dist/v1/schema/compatibility/scope.js +110 -0
- package/dist/v1/schema/compatibility/structure/index.d.ts +3 -0
- package/dist/v1/schema/compatibility/structure/index.js +40 -0
- package/dist/v1/schema/compatibility/structure/inheritance.d.ts +7 -0
- package/dist/v1/schema/compatibility/structure/inheritance.js +68 -0
- package/dist/v1/schema/compatibility/structure/requirements.d.ts +7 -0
- package/dist/v1/schema/compatibility/structure/requirements.js +97 -0
- package/dist/v1/schema/compatibility/subjects.d.ts +39 -0
- package/dist/v1/schema/compatibility/subjects.js +143 -0
- package/dist/v1/schema/compatibility/versioning/index.d.ts +8 -0
- package/dist/v1/schema/compatibility/versioning/index.js +50 -0
- package/dist/v1/schema/compatibility/versioning/members.d.ts +12 -0
- package/dist/v1/schema/compatibility/versioning/members.js +47 -0
- package/dist/v1/schema/compatibility/versioning/surface.d.ts +11 -0
- package/dist/v1/schema/compatibility/versioning/surface.js +61 -0
- package/dist/v1/schema/diagnostic.d.ts +1 -1
- package/dist/v1/schema/fingerprint.d.ts +2 -0
- package/dist/v1/schema/fingerprint.js +1 -0
- package/dist/v1/schema/index.d.ts +4 -3
- package/dist/v1/schema/index.js +2 -1
- package/dist/v1/schema/model/schema.d.ts +8 -11
- package/dist/v1/schema/normalization/domain.js +57 -13
- package/dist/v1/schema/resolution/definition.index.d.ts +1 -2
- package/dist/v1/schema/resolution/definition.index.js +0 -3
- package/dist/v1/schema/resolution/domain.d.ts +4 -1
- package/dist/v1/schema/resolution/domain.js +26 -18
- package/dist/v1/schema/resolution/origins.d.ts +28 -5
- package/dist/v1/schema/resolution/origins.js +68 -31
- package/dist/v1/schema/validation/callable.d.ts +4 -0
- package/dist/v1/schema/validation/callable.js +39 -0
- package/dist/v1/schema/validation/class.d.ts +10 -0
- package/dist/v1/schema/validation/class.js +79 -60
- package/dist/v1/schema/validation/core.js +83 -55
- package/dist/v1/schema/validation/domain.d.ts +2 -1
- package/dist/v1/schema/validation/domain.js +2 -0
- package/dist/v1/schema/validation/domain.structure.d.ts +0 -2
- package/dist/v1/schema/validation/domain.structure.js +214 -171
- package/dist/v1/schema/validation/policy/budgets.js +36 -6
- package/dist/v1/schema/validation/policy/context.js +5 -16
- package/dist/v1/schema/validation/policy/objects.d.ts +4 -0
- package/dist/v1/schema/validation/policy/objects.js +71 -0
- package/dist/v1/schema/validation/policy/references.js +16 -4
- package/dist/v1/schema/validation/policy/typing.d.ts +2 -0
- package/dist/v1/schema/validation/policy/typing.js +55 -7
- package/dist/v1/schema/validation/policy/uses.js +73 -99
- package/dist/v1/schema/validation/value-api.d.ts +2 -0
- package/dist/v1/schema/validation/value-api.js +1 -0
- package/dist/v1/schema/validation/value.js +7 -1
- package/dist/v1/schema/validation/view.js +14 -9
- package/dist/value/accept.d.ts +9 -0
- package/dist/value/accept.js +106 -7
- package/dist/value/canonical.d.ts +3 -0
- package/dist/value/canonical.js +22 -6
- package/dist/value/immutable.optimization.d.ts +15 -0
- package/dist/value/immutable.optimization.js +34 -0
- package/dist/value/index.d.ts +1 -1
- package/dist/value/index.js +1 -1
- package/dist/value/json.d.ts +1 -1
- package/dist/value/json.js +1 -1
- package/dist/value/limits.d.ts +1 -1
- package/dist/value/unicode.d.ts +4 -1
- package/dist/value/unicode.js +28 -0
- package/package.json +20 -5
- package/dist/v1/schema/compatibility/meaning.d.ts +0 -29
- package/dist/v1/schema/compatibility/meaning.js +0 -605
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Key } from '../../../addressing/index.js';
|
|
2
|
+
import { compareAddedProperties, compareLostProperties } from '../comparators/classes.js';
|
|
3
|
+
import { compareFacet } from '../comparators/index.js';
|
|
4
|
+
import { contextInvalid } from '../context.js';
|
|
5
|
+
import { callableReferences, classReferences, inherits, memberReferences, valueReferences, } from '../references.js';
|
|
6
|
+
/** Meaning follows complete callable contracts through the exact authored reference closure. */
|
|
7
|
+
export function compareFootprint({ context, report, }) {
|
|
8
|
+
const queue = [...context.roots];
|
|
9
|
+
const visited = new Set();
|
|
10
|
+
for (const reference of queue) {
|
|
11
|
+
report.note(reference);
|
|
12
|
+
const { coordinate, usage } = reference;
|
|
13
|
+
const visit = `${coordinate.key}:${usage.relation}`;
|
|
14
|
+
if (visited.has(visit))
|
|
15
|
+
continue;
|
|
16
|
+
visited.add(visit);
|
|
17
|
+
const pair = context.pair(coordinate);
|
|
18
|
+
const subject = pair.source;
|
|
19
|
+
if (subject === undefined)
|
|
20
|
+
throw contextInvalid(`Retained acceptance context has no meaning for ${coordinate.key}.`, coordinate.key);
|
|
21
|
+
let facet;
|
|
22
|
+
switch (subject.kind) {
|
|
23
|
+
case 'class': {
|
|
24
|
+
facet = inherits(usage) ? 'class.inherit' : 'class.reference';
|
|
25
|
+
queue.push(...classReferences(subject, false));
|
|
26
|
+
if (inherits(usage))
|
|
27
|
+
queue.push(...classReferences(subject, true));
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case 'property':
|
|
31
|
+
facet = 'property';
|
|
32
|
+
queue.push(...valueReferences(subject));
|
|
33
|
+
break;
|
|
34
|
+
case 'method':
|
|
35
|
+
facet = 'method.signature';
|
|
36
|
+
queue.push(...callableReferences(subject));
|
|
37
|
+
break;
|
|
38
|
+
case 'member': {
|
|
39
|
+
facet =
|
|
40
|
+
subject.coordinate.ref.kind === 'function'
|
|
41
|
+
? 'function.signature'
|
|
42
|
+
: subject.coordinate.ref.kind;
|
|
43
|
+
queue.push(...memberReferences(subject));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (Key.origin(coordinate.key) !== context.source.origin)
|
|
47
|
+
continue;
|
|
48
|
+
report.record({
|
|
49
|
+
pair,
|
|
50
|
+
facet,
|
|
51
|
+
...compareFacet({ context, pair, facet }),
|
|
52
|
+
requirement: { kind: facet },
|
|
53
|
+
});
|
|
54
|
+
if (facet === 'class.inherit')
|
|
55
|
+
compareAddedProperties({ context, pair, report });
|
|
56
|
+
if (subject.kind === 'class')
|
|
57
|
+
compareLostProperties({ pair, report });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { evidenceOf, losesProperties } from '../evidence.js';
|
|
2
|
+
import { createReport } from '../report.js';
|
|
3
|
+
import { compareFootprint } from './footprint.js';
|
|
4
|
+
export function analyzeMeaning(context) {
|
|
5
|
+
const report = createReport();
|
|
6
|
+
compareFootprint({ context, report });
|
|
7
|
+
const result = { scope: context.scope, ...report.finish() };
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
kind: 'meaning',
|
|
10
|
+
...result,
|
|
11
|
+
equivalent: result.assessments.every(({ satisfied }) => satisfied),
|
|
12
|
+
// Version 2 adds a referenced or inherited Class that lost an effective Property; without it,
|
|
13
|
+
// version 1.
|
|
14
|
+
evidence: evidenceOf({ kind: 'meaning', version: losesProperties(result) ? 2 : 1, ...result }),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Value } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import type { Definition, Key, Revision } from '../../addressing/index.js';
|
|
3
|
+
import type { DomainSchema } from '../model/schema.js';
|
|
4
|
+
import type { ReferenceSite } from '../resolution/origins.js';
|
|
5
|
+
import type { MeaningDifference } from './diff.js';
|
|
6
|
+
export type Fingerprint = `sha256:${string}`;
|
|
7
|
+
/** Inputs carry accepted schemas; a dependency's source is always its retained exact context. */
|
|
8
|
+
export interface ComparisonRequest {
|
|
9
|
+
readonly scope: {
|
|
10
|
+
readonly kind: 'dependency';
|
|
11
|
+
readonly dependent: DomainSchema;
|
|
12
|
+
/**
|
|
13
|
+
* Function, Method and Class Keys the dependent declares as capability requirements outside
|
|
14
|
+
* its schema. Keys of the target origin become roots with relation `capability`: a Function
|
|
15
|
+
* or Method requires its existence and dispatch, a Class its reference meaning and effective
|
|
16
|
+
* Property surface. Keys of other origins are ignored; a value that is not a Key list, or an
|
|
17
|
+
* unresolvable or unsupported Key of the target origin, is rejected with DM_CAPABILITY_INVALID.
|
|
18
|
+
*/
|
|
19
|
+
readonly capabilities?: readonly Key[];
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'members';
|
|
22
|
+
readonly source: DomainSchema;
|
|
23
|
+
readonly roots: readonly [Key, ...Key[]];
|
|
24
|
+
};
|
|
25
|
+
readonly target: DomainSchema;
|
|
26
|
+
}
|
|
27
|
+
export interface SchemaIdentity {
|
|
28
|
+
readonly origin: Key.Origin;
|
|
29
|
+
readonly revision: Revision;
|
|
30
|
+
}
|
|
31
|
+
export interface ComparisonScope {
|
|
32
|
+
readonly kind: ComparisonRequest['scope']['kind'];
|
|
33
|
+
readonly source: SchemaIdentity;
|
|
34
|
+
readonly target: SchemaIdentity;
|
|
35
|
+
readonly dependent?: SchemaIdentity;
|
|
36
|
+
readonly roots: readonly Key[];
|
|
37
|
+
}
|
|
38
|
+
/** Identity contains no requirement or usage level. */
|
|
39
|
+
export interface Subject {
|
|
40
|
+
readonly key: Key;
|
|
41
|
+
readonly kind: Definition.Kind | 'property' | 'method';
|
|
42
|
+
}
|
|
43
|
+
/** Immediate provenance, retained even when several paths impose the same requirement. */
|
|
44
|
+
export interface Usage {
|
|
45
|
+
readonly source: SchemaIdentity;
|
|
46
|
+
readonly key?: Key;
|
|
47
|
+
readonly relation: ReferenceSite | 'member' | 'abstract' | 'selection' | 'capability';
|
|
48
|
+
}
|
|
49
|
+
export type Facet = 'class.reference' | 'class.inherit' | 'class.composition' | 'class.properties' | 'class.endpoints' | 'property' | 'property.required' | 'method.existence' | 'method.object' | 'method.inheritance' | 'method.signature' | 'function.existence' | 'function.signature' | 'policy' | 'view' | 'core';
|
|
50
|
+
/** A fact about a compared facet, including unchanged facets. No admission decision is implied. */
|
|
51
|
+
export interface Observation {
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly facet: Facet;
|
|
54
|
+
readonly state: 'equal' | 'changed' | 'missing' | 'added';
|
|
55
|
+
readonly before?: Value;
|
|
56
|
+
readonly after?: Value;
|
|
57
|
+
readonly differences: readonly MeaningDifference[];
|
|
58
|
+
}
|
|
59
|
+
export interface ComparisonEntry {
|
|
60
|
+
readonly subject: Subject;
|
|
61
|
+
readonly source?: SchemaIdentity;
|
|
62
|
+
readonly target?: SchemaIdentity;
|
|
63
|
+
readonly usages: readonly Usage[];
|
|
64
|
+
readonly observations: readonly Observation[];
|
|
65
|
+
}
|
|
66
|
+
/** An established requirement; observations without one remain visible but do not affect the conclusion. */
|
|
67
|
+
export interface Assessment {
|
|
68
|
+
readonly subject: Subject;
|
|
69
|
+
readonly observation: Observation;
|
|
70
|
+
readonly requirement: {
|
|
71
|
+
readonly kind: Facet;
|
|
72
|
+
};
|
|
73
|
+
readonly satisfied: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Evidence is a semantic projection; presentation/provenance never enters its digest. Versions are
|
|
77
|
+
* per kind, and a comparison names the oldest policy that yields its facts. Meaning is version 1.
|
|
78
|
+
* Structure is version 2, or version 3 when declared capabilities are among its roots, so a
|
|
79
|
+
* comparison without them keeps the version-2 bytes. Capability Keys join the root Key set of both
|
|
80
|
+
* digests: one that is not already a root changes the meaning fingerprint, never its version, and
|
|
81
|
+
* meaning evidence never records whether capabilities were declared. A referenced or inherited Class
|
|
82
|
+
* that loses an effective Property (`class.properties`) raises structure to version 4 and meaning to
|
|
83
|
+
* version 2, and structure is version 4 too when it records that a dependent Policy lost what it
|
|
84
|
+
* relies on (`method.object`, `class.endpoints`). Those facts are recorded only on such a loss, so
|
|
85
|
+
* every other comparison, every compatible one included, keeps its bytes.
|
|
86
|
+
*/
|
|
87
|
+
export interface ComparisonEvidence {
|
|
88
|
+
readonly kind: 'structure' | 'meaning';
|
|
89
|
+
readonly version: 1 | 2 | 3 | 4;
|
|
90
|
+
readonly fingerprint: Fingerprint;
|
|
91
|
+
}
|
|
92
|
+
export interface Analysis {
|
|
93
|
+
readonly scope: ComparisonScope;
|
|
94
|
+
readonly entries: readonly ComparisonEntry[];
|
|
95
|
+
readonly assessments: readonly Assessment[];
|
|
96
|
+
readonly evidence: ComparisonEvidence;
|
|
97
|
+
}
|
|
98
|
+
export interface StructureComparison extends Analysis {
|
|
99
|
+
readonly kind: 'structure';
|
|
100
|
+
readonly compatible: boolean;
|
|
101
|
+
}
|
|
102
|
+
export interface MeaningComparison extends Analysis {
|
|
103
|
+
readonly kind: 'meaning';
|
|
104
|
+
readonly equivalent: boolean;
|
|
105
|
+
}
|
|
106
|
+
export interface Comparison {
|
|
107
|
+
readonly scope: ComparisonScope;
|
|
108
|
+
readonly entries: readonly ComparisonEntry[];
|
|
109
|
+
readonly structure: StructureComparison;
|
|
110
|
+
readonly meaning: MeaningComparison;
|
|
111
|
+
readonly evidence: {
|
|
112
|
+
readonly structure: ComparisonEvidence;
|
|
113
|
+
readonly meaning: ComparisonEvidence;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/** The semantic level a schema change requires at minimum; version numbers stay with the caller. */
|
|
117
|
+
export type Bump = 'patch' | 'minor' | 'major';
|
|
118
|
+
/** One non-equal observation between two versions of one Domain, with the level it alone requires. */
|
|
119
|
+
export interface VersionChange {
|
|
120
|
+
readonly subject: Subject;
|
|
121
|
+
readonly observation: Observation;
|
|
122
|
+
readonly bump: Bump;
|
|
123
|
+
}
|
|
124
|
+
/** The floor `next` sets over `previous`: the highest level among its changes, patch without any. */
|
|
125
|
+
export interface RequiredBump {
|
|
126
|
+
readonly level: Bump;
|
|
127
|
+
readonly previous: SchemaIdentity;
|
|
128
|
+
readonly next: SchemaIdentity;
|
|
129
|
+
/** Every non-equal observation, ordered by subject Key then observation id; empty for equal revisions. */
|
|
130
|
+
readonly changes: readonly VersionChange[];
|
|
131
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DomainSchema } from '../model/schema.js';
|
|
2
|
+
import type { Coordinate } from './coordinate.js';
|
|
3
|
+
import type { Usage } from './model.js';
|
|
4
|
+
import type { ResolvedSubject } from './subjects.js';
|
|
5
|
+
import { Key } from '../../addressing/index.js';
|
|
6
|
+
export interface Reference {
|
|
7
|
+
readonly coordinate: Coordinate;
|
|
8
|
+
readonly usage: Usage;
|
|
9
|
+
}
|
|
10
|
+
export declare function schemaIdentity(schema: DomainSchema): Readonly<{
|
|
11
|
+
origin: string;
|
|
12
|
+
revision: import("../../addressing/revision.js").Revision;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function usageOf(schema: DomainSchema, relation: Usage['relation'], key?: Key): Usage;
|
|
15
|
+
/** References keep their declaring member and relation; no strongest-usage collapse happens here. */
|
|
16
|
+
export declare function rootReferences(schema: DomainSchema): readonly Reference[];
|
|
17
|
+
/**
|
|
18
|
+
* What the dependent's own Policies rely on in one origin beyond naming a Definition: each Method a
|
|
19
|
+
* Policy object term names, in a callable's checks or a Node Class rule, which the Policy resolves
|
|
20
|
+
* as its owner's own executable declaration, and each Edge Class a Policy pattern matches, whose
|
|
21
|
+
* orientation and accepted endpoint Classes Policy typing reads. Policies the dependent reaches in
|
|
22
|
+
* a dependency are that dependency's own.
|
|
23
|
+
*/
|
|
24
|
+
export declare function policyReliance(schema: DomainSchema, origin: Key.Origin): readonly Reference[];
|
|
25
|
+
/** Existing DSL collectors own reference syntax. These functions attach comparison provenance. */
|
|
26
|
+
export declare function valueReferences(subject: Extract<ResolvedSubject, {
|
|
27
|
+
kind: 'property';
|
|
28
|
+
}>): readonly Reference[];
|
|
29
|
+
export declare function callableReferences(subject: Extract<ResolvedSubject, {
|
|
30
|
+
kind: 'method';
|
|
31
|
+
}>): readonly Reference[];
|
|
32
|
+
export declare function classReferences(subject: Extract<ResolvedSubject, {
|
|
33
|
+
kind: 'class';
|
|
34
|
+
}>, inherit: boolean): readonly Reference[];
|
|
35
|
+
export declare function memberReferences(subject: Extract<ResolvedSubject, {
|
|
36
|
+
kind: 'member';
|
|
37
|
+
}>): readonly Reference[];
|
|
38
|
+
export declare function inherits(usage: Usage): boolean;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Key } from '../../addressing/index.js';
|
|
2
|
+
import { revisionOfDomainSchema } from '../canonical/revision.js';
|
|
3
|
+
import { collectCallableContractRefs, collectCallableRefs, collectClassPolicyRefs, collectCoreRefs, collectEndpointRefs, collectPolicyDefinitionRefs, collectValueDefinitionRefs, coreEndpointDefinitionRef, } from '../resolution/origins.js';
|
|
4
|
+
import { classCoordinate, keyForDefinitionRef, memberCoordinate, methodCoordinate, propertyCoordinate, } from './coordinate.js';
|
|
5
|
+
export function schemaIdentity(schema) {
|
|
6
|
+
return Object.freeze({ origin: schema.origin, revision: revisionOfDomainSchema(schema) });
|
|
7
|
+
}
|
|
8
|
+
export function usageOf(schema, relation, key) {
|
|
9
|
+
return Object.freeze({
|
|
10
|
+
source: schemaIdentity(schema),
|
|
11
|
+
relation,
|
|
12
|
+
...(key === undefined ? {} : { key }),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/** A Method a Policy names stays a reference to its owner Class; `policyReliance` keeps the Method. */
|
|
16
|
+
function collector(schema, result, key) {
|
|
17
|
+
return (ref, relation) => {
|
|
18
|
+
const definition = ref.kind === 'method' ? ref.owner : ref;
|
|
19
|
+
result.push({
|
|
20
|
+
coordinate: definition.kind === 'class'
|
|
21
|
+
? classCoordinate(definition)
|
|
22
|
+
: memberCoordinate(definition),
|
|
23
|
+
usage: usageOf(schema, relation, key),
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** References keep their declaring member and relation; no strongest-usage collapse happens here. */
|
|
28
|
+
export function rootReferences(schema) {
|
|
29
|
+
const result = [];
|
|
30
|
+
for (const declaration of Object.values(schema.classes)) {
|
|
31
|
+
const key = keyForDefinitionRef(declaration.ref);
|
|
32
|
+
const add = collector(schema, result, key);
|
|
33
|
+
declaration.extends.forEach((ref) => add(ref, 'extends'));
|
|
34
|
+
for (const [name, field] of Object.entries(declaration.properties)) {
|
|
35
|
+
collectValueDefinitionRefs(field.schema, collector(schema, result, propertyCoordinate(declaration.ref, name).key));
|
|
36
|
+
}
|
|
37
|
+
collectClassPolicyRefs(declaration, add);
|
|
38
|
+
if (declaration.kind === 'edge')
|
|
39
|
+
collectEndpointRefs(declaration, add);
|
|
40
|
+
else
|
|
41
|
+
for (const [name, method] of Object.entries(declaration.methods)) {
|
|
42
|
+
collectCallableRefs(method, collector(schema, result, methodCoordinate(declaration.ref, name).key));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const declaration of Object.values(schema.functions))
|
|
46
|
+
collectCallableRefs(declaration, collector(schema, result, keyForDefinitionRef(declaration.ref)));
|
|
47
|
+
for (const declaration of Object.values(schema.policies))
|
|
48
|
+
collectPolicyDefinitionRefs(declaration, collector(schema, result, keyForDefinitionRef(declaration.ref)));
|
|
49
|
+
collectCoreRefs(schema, collector(schema, result));
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* What the dependent's own Policies rely on in one origin beyond naming a Definition: each Method a
|
|
54
|
+
* Policy object term names, in a callable's checks or a Node Class rule, which the Policy resolves
|
|
55
|
+
* as its owner's own executable declaration, and each Edge Class a Policy pattern matches, whose
|
|
56
|
+
* orientation and accepted endpoint Classes Policy typing reads. Policies the dependent reaches in
|
|
57
|
+
* a dependency are that dependency's own.
|
|
58
|
+
*/
|
|
59
|
+
export function policyReliance(schema, origin) {
|
|
60
|
+
const result = new Map();
|
|
61
|
+
const collect = (key) => (ref, site) => {
|
|
62
|
+
const coordinate = ref.kind === 'method'
|
|
63
|
+
? methodCoordinate(ref.owner, ref.name)
|
|
64
|
+
: site === 'pattern'
|
|
65
|
+
? classCoordinate(ref)
|
|
66
|
+
: undefined;
|
|
67
|
+
if (coordinate === undefined || Key.origin(coordinate.key) !== origin)
|
|
68
|
+
return;
|
|
69
|
+
result.set(`${coordinate.key}:${site}`, { coordinate, usage: usageOf(schema, site, key) });
|
|
70
|
+
};
|
|
71
|
+
for (const declaration of Object.values(schema.classes)) {
|
|
72
|
+
collectClassPolicyRefs(declaration, collect(keyForDefinitionRef(declaration.ref)));
|
|
73
|
+
if (declaration.kind === 'node')
|
|
74
|
+
for (const [name, method] of Object.entries(declaration.methods))
|
|
75
|
+
collectCallableRefs(method, collect(methodCoordinate(declaration.ref, name).key));
|
|
76
|
+
}
|
|
77
|
+
for (const declaration of Object.values(schema.functions))
|
|
78
|
+
collectCallableRefs(declaration, collect(keyForDefinitionRef(declaration.ref)));
|
|
79
|
+
for (const declaration of Object.values(schema.policies))
|
|
80
|
+
collectPolicyDefinitionRefs(declaration, collect(keyForDefinitionRef(declaration.ref)));
|
|
81
|
+
return [...result.values()];
|
|
82
|
+
}
|
|
83
|
+
/** Existing DSL collectors own reference syntax. These functions attach comparison provenance. */
|
|
84
|
+
export function valueReferences(subject) {
|
|
85
|
+
const result = [];
|
|
86
|
+
collectValueDefinitionRefs(subject.field.schema, collector(subject.schema, result, subject.coordinate.key));
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
export function callableReferences(subject) {
|
|
90
|
+
const result = [];
|
|
91
|
+
collectCallableContractRefs(subject.method.declaration, collector(subject.schema, result, subject.coordinate.key));
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
export function classReferences(subject, inherit) {
|
|
95
|
+
const result = [];
|
|
96
|
+
const add = collector(subject.schema, result, subject.coordinate.key);
|
|
97
|
+
if (inherit) {
|
|
98
|
+
subject.analysis.declaration.extends.forEach((ref) => add(ref, 'extends'));
|
|
99
|
+
if (subject.analysis.declaration.kind === 'edge')
|
|
100
|
+
collectEndpointRefs(subject.analysis.declaration, add);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
for (const field of subject.analysis.properties.values())
|
|
104
|
+
result.push({
|
|
105
|
+
coordinate: propertyCoordinate(field.owner, field.name),
|
|
106
|
+
usage: usageOf(subject.schema, 'member', subject.coordinate.key),
|
|
107
|
+
});
|
|
108
|
+
for (const method of subject.analysis.methods.values())
|
|
109
|
+
result.push({
|
|
110
|
+
coordinate: methodCoordinate(method.owner, method.name),
|
|
111
|
+
usage: usageOf(subject.schema, 'member', subject.coordinate.key),
|
|
112
|
+
});
|
|
113
|
+
collectClassPolicyRefs(subject.analysis.declaration, add);
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
export function memberReferences(subject) {
|
|
118
|
+
const result = [];
|
|
119
|
+
const { schema, coordinate: { ref, key }, } = subject;
|
|
120
|
+
const add = collector(schema, result, key);
|
|
121
|
+
switch (ref.kind) {
|
|
122
|
+
case 'function':
|
|
123
|
+
collectCallableRefs(schema.functions[ref.name], add);
|
|
124
|
+
break;
|
|
125
|
+
case 'policy':
|
|
126
|
+
collectPolicyDefinitionRefs(schema.policies[ref.name], add);
|
|
127
|
+
break;
|
|
128
|
+
case 'view':
|
|
129
|
+
break;
|
|
130
|
+
case 'core': {
|
|
131
|
+
add(schema.core.nodes[ref.name].class, 'endpoint');
|
|
132
|
+
for (const edge of schema.core.edges) {
|
|
133
|
+
if (!((edge.source.kind === 'core' && edge.source.name === ref.name) ||
|
|
134
|
+
(edge.target.kind === 'core' && edge.target.name === ref.name)))
|
|
135
|
+
continue;
|
|
136
|
+
add(edge.class, 'endpoint');
|
|
137
|
+
for (const endpoint of [edge.source, edge.target]) {
|
|
138
|
+
const ref = coreEndpointDefinitionRef(endpoint);
|
|
139
|
+
if (ref !== undefined)
|
|
140
|
+
add(ref, 'endpoint');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
export function inherits(usage) {
|
|
148
|
+
return usage.relation === 'extends' || usage.relation === 'core';
|
|
149
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Value } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import type { Assessment, ComparisonEntry, Facet } from './model.js';
|
|
3
|
+
import type { Reference } from './references.js';
|
|
4
|
+
import type { SubjectPair } from './scope.js';
|
|
5
|
+
interface ComparisonFact {
|
|
6
|
+
readonly pair: SubjectPair;
|
|
7
|
+
readonly facet: Facet;
|
|
8
|
+
readonly before?: Value;
|
|
9
|
+
readonly after?: Value;
|
|
10
|
+
readonly requirement?: {
|
|
11
|
+
readonly kind: Assessment['requirement']['kind'];
|
|
12
|
+
readonly satisfied?: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Mutable collection is local to one analysis; callers only receive frozen completed reports. */
|
|
16
|
+
export declare function createReport(): {
|
|
17
|
+
note({ coordinate, usage }: Reference): void;
|
|
18
|
+
record(fact: ComparisonFact): void;
|
|
19
|
+
finish(): Readonly<{
|
|
20
|
+
entries: readonly ComparisonEntry[];
|
|
21
|
+
assessments: readonly Assessment[];
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
export type Report = ReturnType<typeof createReport>;
|
|
25
|
+
/** Full comparison merges facts; it never reclassifies the two analyses' conclusions. */
|
|
26
|
+
export declare function mergeEntries(...groups: readonly (readonly ComparisonEntry[])[]): readonly ComparisonEntry[];
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { compareUnicode } from '../../addressing/ordering.js';
|
|
3
|
+
import { deepFreeze } from '../canonical/freeze.js';
|
|
4
|
+
import { fingerprintMeaning } from './comparators/values.js';
|
|
5
|
+
import { differences } from './diff.js';
|
|
6
|
+
import { schemaIdentity } from './references.js';
|
|
7
|
+
import { identityOf } from './subjects.js';
|
|
8
|
+
/** Mutable collection is local to one analysis; callers only receive frozen completed reports. */
|
|
9
|
+
export function createReport() {
|
|
10
|
+
const usages = new Map();
|
|
11
|
+
const entries = new Map();
|
|
12
|
+
const assessments = new Map();
|
|
13
|
+
return {
|
|
14
|
+
note({ coordinate, usage }) {
|
|
15
|
+
const values = usages.get(coordinate.key) ?? [];
|
|
16
|
+
values.push(usage);
|
|
17
|
+
usages.set(coordinate.key, values);
|
|
18
|
+
},
|
|
19
|
+
record(fact) {
|
|
20
|
+
const { pair, facet, before, after } = fact;
|
|
21
|
+
const id = `${pair.coordinate.key}#${facet}`;
|
|
22
|
+
const entry = entries.get(pair.coordinate.key) ?? {
|
|
23
|
+
pair,
|
|
24
|
+
observations: new Map(),
|
|
25
|
+
};
|
|
26
|
+
const observation = entry.observations.get(id) ??
|
|
27
|
+
deepFreeze({
|
|
28
|
+
id,
|
|
29
|
+
facet,
|
|
30
|
+
state: before === undefined
|
|
31
|
+
? 'added'
|
|
32
|
+
: after === undefined
|
|
33
|
+
? 'missing'
|
|
34
|
+
: fingerprintMeaning(before) === fingerprintMeaning(after)
|
|
35
|
+
? 'equal'
|
|
36
|
+
: 'changed',
|
|
37
|
+
...(before === undefined ? {} : { before }),
|
|
38
|
+
...(after === undefined ? {} : { after }),
|
|
39
|
+
differences: before === undefined || after === undefined ? [] : differences(before, after),
|
|
40
|
+
});
|
|
41
|
+
entry.observations.set(id, observation);
|
|
42
|
+
entries.set(pair.coordinate.key, entry);
|
|
43
|
+
if (fact.requirement !== undefined) {
|
|
44
|
+
assessments.set(`${id}:${fact.requirement.kind}`, {
|
|
45
|
+
pair,
|
|
46
|
+
requirement: fact.requirement,
|
|
47
|
+
observation,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
finish() {
|
|
52
|
+
const completed = [...entries.values()]
|
|
53
|
+
.map(({ pair, observations }) => Object.freeze({
|
|
54
|
+
subject: identityOf(pair.coordinate),
|
|
55
|
+
...(pair.source === undefined ? {} : { source: schemaIdentity(pair.source.schema) }),
|
|
56
|
+
...(pair.target === undefined ? {} : { target: schemaIdentity(pair.target.schema) }),
|
|
57
|
+
usages: uniqueUsages(usages.get(pair.coordinate.key) ?? []),
|
|
58
|
+
observations: Object.freeze([...observations.values()].sort((a, b) => compareUnicode(a.id, b.id))),
|
|
59
|
+
}))
|
|
60
|
+
.sort((a, b) => compareUnicode(a.subject.key, b.subject.key));
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
entries: Object.freeze(completed),
|
|
63
|
+
assessments: Object.freeze([...assessments.values()]
|
|
64
|
+
.map(({ pair, requirement, observation }) => deepFreeze({
|
|
65
|
+
subject: identityOf(pair.coordinate),
|
|
66
|
+
observation,
|
|
67
|
+
requirement: { kind: requirement.kind },
|
|
68
|
+
satisfied: requirement.satisfied ?? observation.state === 'equal',
|
|
69
|
+
}))
|
|
70
|
+
.sort((a, b) => compareUnicode(a.observation.id, b.observation.id) ||
|
|
71
|
+
compareUnicode(a.requirement.kind, b.requirement.kind))),
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Full comparison merges facts; it never reclassifies the two analyses' conclusions. */
|
|
77
|
+
export function mergeEntries(...groups) {
|
|
78
|
+
const merged = new Map();
|
|
79
|
+
for (const entry of groups.flat()) {
|
|
80
|
+
const previous = merged.get(entry.subject.key);
|
|
81
|
+
merged.set(entry.subject.key, previous === undefined
|
|
82
|
+
? entry
|
|
83
|
+
: Object.freeze({
|
|
84
|
+
...entry,
|
|
85
|
+
usages: uniqueUsages([...previous.usages, ...entry.usages]),
|
|
86
|
+
observations: Object.freeze([
|
|
87
|
+
...new Map([...previous.observations, ...entry.observations].map((value) => [
|
|
88
|
+
value.id,
|
|
89
|
+
value,
|
|
90
|
+
])).values(),
|
|
91
|
+
].sort((a, b) => compareUnicode(a.id, b.id))),
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
return Object.freeze([...merged.values()].sort((a, b) => compareUnicode(a.subject.key, b.subject.key)));
|
|
95
|
+
}
|
|
96
|
+
function uniqueUsages(values) {
|
|
97
|
+
return Object.freeze([...new Map(values.map((value) => [json.serialize(value), value])).entries()]
|
|
98
|
+
.sort(([a], [b]) => compareUnicode(a, b))
|
|
99
|
+
.map(([, value]) => value));
|
|
100
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Key } from '../../addressing/index.js';
|
|
2
|
+
import type { DomainSchema } from '../model/schema.js';
|
|
3
|
+
import type { Context } from './context.js';
|
|
4
|
+
import type { Coordinate } from './coordinate.js';
|
|
5
|
+
import type { ComparisonRequest, ComparisonScope } from './model.js';
|
|
6
|
+
import type { Reference } from './references.js';
|
|
7
|
+
import type { ResolvedSubject } from './subjects.js';
|
|
8
|
+
export interface SubjectPair {
|
|
9
|
+
readonly coordinate: Coordinate;
|
|
10
|
+
readonly source: ResolvedSubject | undefined;
|
|
11
|
+
readonly target: ResolvedSubject | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface ComparisonContext {
|
|
14
|
+
readonly scope: ComparisonScope;
|
|
15
|
+
readonly source: DomainSchema;
|
|
16
|
+
readonly target: DomainSchema;
|
|
17
|
+
readonly dependent?: DomainSchema;
|
|
18
|
+
readonly before: Context;
|
|
19
|
+
readonly after: Context;
|
|
20
|
+
readonly roots: readonly Reference[];
|
|
21
|
+
/** Roots the dependent declares as capabilities on the compared origin; also in `roots`. */
|
|
22
|
+
readonly capabilities: readonly Reference[];
|
|
23
|
+
/**
|
|
24
|
+
* What the dependent's own Policies rely on in the compared origin (`policyReliance`). Not roots:
|
|
25
|
+
* structure records them only when they fail, so a compatible comparison keeps its bytes.
|
|
26
|
+
*/
|
|
27
|
+
readonly reliance: readonly Reference[];
|
|
28
|
+
pair(coordinate: Coordinate): SubjectPair;
|
|
29
|
+
}
|
|
30
|
+
export declare function prepare(request: ComparisonRequest): ComparisonContext;
|
|
31
|
+
/**
|
|
32
|
+
* Select distinct Keys of the source against a target the caller checked to be of the same origin.
|
|
33
|
+
* The selection may be empty, which a public request cannot be: `requiredBump` selects every member
|
|
34
|
+
* of a version that may declare none.
|
|
35
|
+
*/
|
|
36
|
+
export declare function selectMembers(source: DomainSchema, target: DomainSchema, keys: readonly Key[]): ComparisonContext;
|