@graview/core 0.1.0 → 0.1.3
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/README.md +7 -0
- package/dist/app.d.ts +17 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/arrange.d.ts +3 -2
- package/dist/arrange.d.ts.map +1 -1
- package/dist/arrange.js +19 -2
- package/dist/arrange.js.map +1 -1
- package/dist/beginning.d.ts +5 -2
- package/dist/beginning.d.ts.map +1 -1
- package/dist/beginning.js +28 -0
- package/dist/beginning.js.map +1 -1
- package/dist/capabilities.d.ts +32 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +31 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli/check/index.d.ts +1 -0
- package/dist/cli/check/index.d.ts.map +1 -1
- package/dist/cli/check/index.js +1 -0
- package/dist/cli/check/index.js.map +1 -1
- package/dist/cli/check/lenses.d.ts.map +1 -1
- package/dist/cli/check/lenses.js +25 -0
- package/dist/cli/check/lenses.js.map +1 -1
- package/dist/cli/check/policy.d.ts.map +1 -1
- package/dist/cli/check/policy.js +35 -0
- package/dist/cli/check/policy.js.map +1 -1
- package/dist/cli/check/relations.d.ts.map +1 -1
- package/dist/cli/check/relations.js +31 -0
- package/dist/cli/check/relations.js.map +1 -1
- package/dist/cli/check/views.d.ts +14 -0
- package/dist/cli/check/views.d.ts.map +1 -0
- package/dist/cli/check/views.js +27 -0
- package/dist/cli/check/views.js.map +1 -0
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +2 -1
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +63 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.d.ts +18 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +66 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/conformance/fixtures.d.ts +41 -0
- package/dist/conformance/fixtures.d.ts.map +1 -0
- package/dist/conformance/fixtures.js +950 -0
- package/dist/conformance/fixtures.js.map +1 -0
- package/dist/conformance/index.d.ts +54 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +81 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/document/canonical.d.ts +4 -0
- package/dist/document/canonical.d.ts.map +1 -0
- package/dist/document/canonical.js +29 -0
- package/dist/document/canonical.js.map +1 -0
- package/dist/document/compile.d.ts +43 -0
- package/dist/document/compile.d.ts.map +1 -0
- package/dist/document/compile.js +807 -0
- package/dist/document/compile.js.map +1 -0
- package/dist/document/diff.d.ts +32 -0
- package/dist/document/diff.d.ts.map +1 -0
- package/dist/document/diff.js +148 -0
- package/dist/document/diff.js.map +1 -0
- package/dist/document/edit.d.ts +63 -0
- package/dist/document/edit.d.ts.map +1 -0
- package/dist/document/edit.js +1432 -0
- package/dist/document/edit.js.map +1 -0
- package/dist/document/expr/analyze.d.ts +14 -0
- package/dist/document/expr/analyze.d.ts.map +1 -0
- package/dist/document/expr/analyze.js +52 -0
- package/dist/document/expr/analyze.js.map +1 -0
- package/dist/document/expr/evaluate.d.ts +36 -0
- package/dist/document/expr/evaluate.d.ts.map +1 -0
- package/dist/document/expr/evaluate.js +344 -0
- package/dist/document/expr/evaluate.js.map +1 -0
- package/dist/document/expr/index.d.ts +8 -0
- package/dist/document/expr/index.d.ts.map +1 -0
- package/dist/document/expr/index.js +5 -0
- package/dist/document/expr/index.js.map +1 -0
- package/dist/document/expr/parse.d.ts +50 -0
- package/dist/document/expr/parse.d.ts.map +1 -0
- package/dist/document/expr/parse.js +240 -0
- package/dist/document/expr/parse.js.map +1 -0
- package/dist/document/expr/print.d.ts +4 -0
- package/dist/document/expr/print.d.ts.map +1 -0
- package/dist/document/expr/print.js +81 -0
- package/dist/document/expr/print.js.map +1 -0
- package/dist/document/findings.d.ts +15 -0
- package/dist/document/findings.d.ts.map +1 -0
- package/dist/document/findings.js +30 -0
- package/dist/document/findings.js.map +1 -0
- package/dist/document/graview-template.d.ts +148 -0
- package/dist/document/graview-template.d.ts.map +1 -0
- package/dist/document/graview-template.js +450 -0
- package/dist/document/graview-template.js.map +1 -0
- package/dist/document/index.d.ts +27 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +16 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/migrate.d.ts +41 -0
- package/dist/document/migrate.d.ts.map +1 -0
- package/dist/document/migrate.js +252 -0
- package/dist/document/migrate.js.map +1 -0
- package/dist/document/patch.d.ts +16 -0
- package/dist/document/patch.d.ts.map +1 -0
- package/dist/document/patch.js +79 -0
- package/dist/document/patch.js.map +1 -0
- package/dist/document/rules.d.ts +40 -0
- package/dist/document/rules.d.ts.map +1 -0
- package/dist/document/rules.js +88 -0
- package/dist/document/rules.js.map +1 -0
- package/dist/document/schema.d.ts +461 -0
- package/dist/document/schema.d.ts.map +1 -0
- package/dist/document/schema.js +199 -0
- package/dist/document/schema.js.map +1 -0
- package/dist/document/template.d.ts +28 -0
- package/dist/document/template.d.ts.map +1 -0
- package/dist/document/template.js +117 -0
- package/dist/document/template.js.map +1 -0
- package/dist/document/to-document.d.ts +34 -0
- package/dist/document/to-document.d.ts.map +1 -0
- package/dist/document/to-document.js +186 -0
- package/dist/document/to-document.js.map +1 -0
- package/dist/document/upgrade.d.ts +9 -0
- package/dist/document/upgrade.d.ts.map +1 -0
- package/dist/document/upgrade.js +19 -0
- package/dist/document/upgrade.js.map +1 -0
- package/dist/document/views.d.ts +65 -0
- package/dist/document/views.d.ts.map +1 -0
- package/dist/document/views.js +264 -0
- package/dist/document/views.js.map +1 -0
- package/dist/formats.d.ts +50 -0
- package/dist/formats.d.ts.map +1 -0
- package/dist/formats.js +75 -0
- package/dist/formats.js.map +1 -0
- package/dist/graph/graph.d.ts +61 -3
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +187 -20
- package/dist/graph/graph.js.map +1 -1
- package/dist/index.d.ts +43 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -11
- package/dist/index.js.map +1 -1
- package/dist/integrity.d.ts +46 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +179 -0
- package/dist/integrity.js.map +1 -0
- package/dist/invariants/engine.d.ts +8 -0
- package/dist/invariants/engine.d.ts.map +1 -1
- package/dist/invariants/engine.js +40 -2
- package/dist/invariants/engine.js.map +1 -1
- package/dist/invariants/types.d.ts +19 -0
- package/dist/invariants/types.d.ts.map +1 -1
- package/dist/labels.d.ts +65 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +123 -0
- package/dist/labels.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts.map +1 -1
- package/dist/mutations/define-mutation.js +5 -6
- package/dist/mutations/define-mutation.js.map +1 -1
- package/dist/mutations/derive-edits.d.ts.map +1 -1
- package/dist/mutations/derive-edits.js +20 -1
- package/dist/mutations/derive-edits.js.map +1 -1
- package/dist/mutations/form.d.ts +9 -0
- package/dist/mutations/form.d.ts.map +1 -1
- package/dist/mutations/form.js +20 -0
- package/dist/mutations/form.js.map +1 -1
- package/dist/mutations/node-ref.d.ts +6 -0
- package/dist/mutations/node-ref.d.ts.map +1 -1
- package/dist/mutations/node-ref.js +22 -8
- package/dist/mutations/node-ref.js.map +1 -1
- package/dist/mutations/types.d.ts +8 -0
- package/dist/mutations/types.d.ts.map +1 -1
- package/dist/mutations/words.d.ts +49 -0
- package/dist/mutations/words.d.ts.map +1 -0
- package/dist/mutations/words.js +61 -0
- package/dist/mutations/words.js.map +1 -0
- package/dist/ops/log.d.ts +156 -4
- package/dist/ops/log.d.ts.map +1 -1
- package/dist/ops/log.js +234 -51
- package/dist/ops/log.js.map +1 -1
- package/dist/ops/revisions.d.ts +66 -0
- package/dist/ops/revisions.d.ts.map +1 -0
- package/dist/ops/revisions.js +97 -0
- package/dist/ops/revisions.js.map +1 -0
- package/dist/ops/types.d.ts +49 -1
- package/dist/ops/types.d.ts.map +1 -1
- package/dist/ops/undo.d.ts +29 -2
- package/dist/ops/undo.d.ts.map +1 -1
- package/dist/ops/undo.js +110 -1
- package/dist/ops/undo.js.map +1 -1
- package/dist/ops/withheld.d.ts +37 -0
- package/dist/ops/withheld.d.ts.map +1 -0
- package/dist/ops/withheld.js +84 -0
- package/dist/ops/withheld.js.map +1 -0
- package/dist/permissions/policy.d.ts +15 -0
- package/dist/permissions/policy.d.ts.map +1 -1
- package/dist/permissions/policy.js +28 -1
- package/dist/permissions/policy.js.map +1 -1
- package/dist/permissions/sight.d.ts +66 -0
- package/dist/permissions/sight.d.ts.map +1 -0
- package/dist/permissions/sight.js +131 -0
- package/dist/permissions/sight.js.map +1 -0
- package/dist/permissions/types.d.ts +26 -0
- package/dist/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js.map +1 -1
- package/dist/persistence/memory.d.ts.map +1 -1
- package/dist/persistence/memory.js +25 -0
- package/dist/persistence/memory.js.map +1 -1
- package/dist/persistence/sql.d.ts +43 -0
- package/dist/persistence/sql.d.ts.map +1 -0
- package/dist/persistence/sql.js +154 -0
- package/dist/persistence/sql.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +17 -3
- package/dist/persistence/sqlite.d.ts.map +1 -1
- package/dist/persistence/sqlite.js +32 -96
- package/dist/persistence/sqlite.js.map +1 -1
- package/dist/persistence/types.d.ts +19 -0
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/presence.d.ts +56 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +62 -2
- package/dist/presence.js.map +1 -1
- package/dist/refusal.d.ts +34 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +40 -0
- package/dist/refusal.js.map +1 -0
- package/dist/scaffold/from-template.d.ts +16 -0
- package/dist/scaffold/from-template.d.ts.map +1 -0
- package/dist/scaffold/from-template.js +157 -0
- package/dist/scaffold/from-template.js.map +1 -0
- package/dist/scaffold/index.d.ts +10 -1
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +35 -7
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/names.d.ts +4 -0
- package/dist/scaffold/names.d.ts.map +1 -1
- package/dist/scaffold/names.js.map +1 -1
- package/dist/scaffold/project.d.ts +1 -1
- package/dist/scaffold/project.d.ts.map +1 -1
- package/dist/scaffold/project.js +44 -13
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/ui.d.ts.map +1 -1
- package/dist/scaffold/ui.js +19 -10
- package/dist/scaffold/ui.js.map +1 -1
- package/dist/schema/define-node.d.ts +20 -0
- package/dist/schema/define-node.d.ts.map +1 -1
- package/dist/schema/define-node.js +27 -2
- package/dist/schema/define-node.js.map +1 -1
- package/dist/schema/path.d.ts +19 -0
- package/dist/schema/path.d.ts.map +1 -0
- package/dist/schema/path.js +34 -0
- package/dist/schema/path.js.map +1 -0
- package/dist/schema/types.d.ts +17 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/seen.d.ts +64 -0
- package/dist/seen.d.ts.map +1 -0
- package/dist/seen.js +200 -0
- package/dist/seen.js.map +1 -0
- package/dist/store.d.ts +378 -8
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +801 -41
- package/dist/store.js.map +1 -1
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -1
- package/dist/testing.js.map +1 -1
- package/dist/theme/palettes.d.ts.map +1 -1
- package/dist/theme/palettes.js +4 -0
- package/dist/theme/palettes.js.map +1 -1
- package/dist/theme/types.d.ts +9 -0
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js +4 -0
- package/dist/theme/types.js.map +1 -1
- package/dist/validate-graph.d.ts +84 -0
- package/dist/validate-graph.d.ts.map +1 -0
- package/dist/validate-graph.js +295 -0
- package/dist/validate-graph.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/views/types.d.ts +8 -0
- package/dist/views/types.d.ts.map +1 -1
- package/dist/views/types.js +5 -0
- package/dist/views/types.js.map +1 -1
- package/dist/watched.d.ts +39 -0
- package/dist/watched.d.ts.map +1 -1
- package/dist/watched.js +94 -1
- package/dist/watched.js.map +1 -1
- package/dist/who.d.ts +24 -1
- package/dist/who.d.ts.map +1 -1
- package/dist/who.js +49 -2
- package/dist/who.js.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { UNSET } from "../index.js";
|
|
2
|
+
/** Whether a plan loses anything: a value cleared, a record or link removed, a required value left missing. */
|
|
3
|
+
export function losesData(plan) {
|
|
4
|
+
return plan.counts.cleared + plan.counts.removedNodes + plan.counts.removedEdges + plan.missingRequired > 0;
|
|
5
|
+
}
|
|
6
|
+
/** Where a field in `after` takes its value from in `before`: itself, or what it was renamed from. */
|
|
7
|
+
function sourceField(beforeFields, name, spec) {
|
|
8
|
+
if (!beforeFields)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (spec.renamedFrom && beforeFields[spec.renamedFrom] && !beforeFields[name])
|
|
11
|
+
return spec.renamedFrom;
|
|
12
|
+
return beforeFields[name] ? name : undefined;
|
|
13
|
+
}
|
|
14
|
+
/** The kind in `before` a kind in `after` continues. */
|
|
15
|
+
function sourceKind(before, name, spec) {
|
|
16
|
+
if (spec.renamedFrom && before[spec.renamedFrom] && !before[name])
|
|
17
|
+
return spec.renamedFrom;
|
|
18
|
+
return before[name] ? name : undefined;
|
|
19
|
+
}
|
|
20
|
+
const DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
21
|
+
/** A value of type `from` as type `to`, or `undefined` when its meaning does not survive. */
|
|
22
|
+
export function coerce(value, from, to) {
|
|
23
|
+
if (value === undefined || value === null)
|
|
24
|
+
return undefined;
|
|
25
|
+
const type = to.type;
|
|
26
|
+
if (from === type && type !== "enum" && type !== "list")
|
|
27
|
+
return value;
|
|
28
|
+
const asText = (v) => (typeof v === "string" ? v : typeof v === "number" || typeof v === "boolean" ? String(v) : undefined);
|
|
29
|
+
switch (type) {
|
|
30
|
+
case "string":
|
|
31
|
+
case "text": {
|
|
32
|
+
if (Array.isArray(value))
|
|
33
|
+
return value.length === 1 ? asText(value[0]) : value.map(asText).filter((x) => x !== undefined).join(", ");
|
|
34
|
+
const t = asText(value);
|
|
35
|
+
return t === undefined ? undefined : type === "string" ? t.slice(0, 500) : t;
|
|
36
|
+
}
|
|
37
|
+
case "number":
|
|
38
|
+
case "integer": {
|
|
39
|
+
const n = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value.replace(/[, _]/g, "")) : NaN;
|
|
40
|
+
if (!Number.isFinite(n))
|
|
41
|
+
return undefined;
|
|
42
|
+
return type === "integer" ? (Number.isInteger(n) ? n : undefined) : n;
|
|
43
|
+
}
|
|
44
|
+
case "boolean": {
|
|
45
|
+
if (typeof value === "boolean")
|
|
46
|
+
return value;
|
|
47
|
+
const t = asText(value)?.trim().toLowerCase();
|
|
48
|
+
return t === "true" || t === "yes" ? true : t === "false" || t === "no" ? false : undefined;
|
|
49
|
+
}
|
|
50
|
+
case "date": {
|
|
51
|
+
const t = asText(value);
|
|
52
|
+
if (!t)
|
|
53
|
+
return undefined;
|
|
54
|
+
if (DATE.test(t))
|
|
55
|
+
return t;
|
|
56
|
+
const ms = Date.parse(t);
|
|
57
|
+
return Number.isNaN(ms) ? undefined : new Date(ms).toISOString().slice(0, 10);
|
|
58
|
+
}
|
|
59
|
+
case "datetime": {
|
|
60
|
+
const t = asText(value);
|
|
61
|
+
if (!t)
|
|
62
|
+
return undefined;
|
|
63
|
+
const ms = Date.parse(DATE.test(t) ? `${t}T00:00:00Z` : t);
|
|
64
|
+
return Number.isNaN(ms) ? undefined : new Date(ms).toISOString();
|
|
65
|
+
}
|
|
66
|
+
case "enum": {
|
|
67
|
+
const t = asText(value);
|
|
68
|
+
if (t === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
const options = to.options ?? [];
|
|
71
|
+
return options.find((o) => o === t) ?? options.find((o) => o.toLowerCase() === t.toLowerCase());
|
|
72
|
+
}
|
|
73
|
+
case "list": {
|
|
74
|
+
const items = Array.isArray(value) ? value : [value];
|
|
75
|
+
const of = to.of ?? "string";
|
|
76
|
+
const coerced = items.map((v) => coerce(v, typeof v === "number" ? "number" : "string", { type: of }));
|
|
77
|
+
return coerced.every((v) => v !== undefined) ? coerced : undefined;
|
|
78
|
+
}
|
|
79
|
+
case "url":
|
|
80
|
+
case "email": {
|
|
81
|
+
const t = asText(value)?.trim();
|
|
82
|
+
if (!t)
|
|
83
|
+
return undefined;
|
|
84
|
+
if (type === "email")
|
|
85
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t) ? t : undefined;
|
|
86
|
+
try {
|
|
87
|
+
return new URL(t).toString() === t || new URL(t).toString() === `${t}/` ? t : undefined;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const plural = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
|
|
96
|
+
export function planMigration(before, after, graph, options = {}) {
|
|
97
|
+
const primitives = [];
|
|
98
|
+
const counts = { moved: 0, coerced: 0, defaulted: 0, filled: 0, cleared: 0, removedNodes: 0, removedEdges: 0 };
|
|
99
|
+
let missingRequired = 0;
|
|
100
|
+
const fills = options.fills ?? [];
|
|
101
|
+
const words = [];
|
|
102
|
+
const tally = new Map();
|
|
103
|
+
const note = (sentence) => tally.set(sentence, (tally.get(sentence) ?? 0) + 1);
|
|
104
|
+
// Which after-kind each before-kind continues as (identity or rename), and which edge names map.
|
|
105
|
+
const kindAfter = new Map();
|
|
106
|
+
for (const [name, spec] of Object.entries(after.kinds)) {
|
|
107
|
+
const src = sourceKind(before.kinds, name, spec);
|
|
108
|
+
if (src)
|
|
109
|
+
kindAfter.set(src, name);
|
|
110
|
+
}
|
|
111
|
+
const edgeAfter = new Map();
|
|
112
|
+
for (const spec of Object.values(after.kinds)) {
|
|
113
|
+
for (const [name, e] of Object.entries(spec.edges ?? {})) {
|
|
114
|
+
const from = e.renamedFrom;
|
|
115
|
+
if (from && !Object.values(before.kinds).some((k) => k.edges?.[name]))
|
|
116
|
+
edgeAfter.set(from, name);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const spec of Object.values(before.kinds))
|
|
120
|
+
for (const name of Object.keys(spec.edges ?? {}))
|
|
121
|
+
if (!edgeAfter.has(name) && Object.values(after.kinds).some((k) => k.edges?.[name]))
|
|
122
|
+
edgeAfter.set(name, name);
|
|
123
|
+
const removedIds = new Set();
|
|
124
|
+
const rekinded = new Map();
|
|
125
|
+
for (const node of graph.nodes) {
|
|
126
|
+
const id = String(node["id"]);
|
|
127
|
+
const oldKind = String(node["kind"]);
|
|
128
|
+
const newKind = kindAfter.get(oldKind);
|
|
129
|
+
if (!newKind) {
|
|
130
|
+
removedIds.add(id);
|
|
131
|
+
counts.removedNodes++;
|
|
132
|
+
note(`${oldKind} record(s) removed with their kind`);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const was = before.kinds[oldKind].fields;
|
|
136
|
+
const now = after.kinds[newKind].fields;
|
|
137
|
+
const next = {};
|
|
138
|
+
const patchBefore = {};
|
|
139
|
+
const patchAfter = {};
|
|
140
|
+
for (const [field, spec] of Object.entries(now)) {
|
|
141
|
+
const src = sourceField(was, field, spec);
|
|
142
|
+
const old = src ? node[src] : undefined;
|
|
143
|
+
let value = undefined;
|
|
144
|
+
if (old !== undefined && old !== null && src) {
|
|
145
|
+
value = coerce(old, was[src].type, spec);
|
|
146
|
+
if (value === undefined) {
|
|
147
|
+
counts.cleared++;
|
|
148
|
+
note(`${newKind}'s ${field}: value(s) that do not fit ${spec.type}${spec.type === "enum" ? " options" : ""} cleared`);
|
|
149
|
+
}
|
|
150
|
+
else if (src !== field) {
|
|
151
|
+
counts.moved++;
|
|
152
|
+
note(`${newKind}'s ${src} renamed to ${field}, values kept`);
|
|
153
|
+
}
|
|
154
|
+
else if (JSON.stringify(value) !== JSON.stringify(old)) {
|
|
155
|
+
counts.coerced++;
|
|
156
|
+
note(`${newKind}'s ${field} converted to ${spec.type}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (value === undefined && spec.required && spec.default !== undefined) {
|
|
160
|
+
value = spec.default;
|
|
161
|
+
counts.defaulted++;
|
|
162
|
+
note(`${newKind}'s ${field} filled with its default`);
|
|
163
|
+
}
|
|
164
|
+
if (value !== undefined)
|
|
165
|
+
next[field] = value;
|
|
166
|
+
}
|
|
167
|
+
for (const fill of fills) {
|
|
168
|
+
const spec = now[fill.field];
|
|
169
|
+
if (fill.kind !== newKind || !spec || next[fill.field] !== undefined)
|
|
170
|
+
continue;
|
|
171
|
+
const source = fill.from !== undefined ? next[fill.from] : fill.value;
|
|
172
|
+
const fromType = fill.from !== undefined ? (now[fill.from]?.type ?? "string") : typeof source === "number" ? "number" : typeof source === "boolean" ? "boolean" : Array.isArray(source) ? "list" : "string";
|
|
173
|
+
const value = coerce(source, fromType, spec);
|
|
174
|
+
if (value === undefined)
|
|
175
|
+
continue;
|
|
176
|
+
next[fill.field] = value;
|
|
177
|
+
counts.filled++;
|
|
178
|
+
note(`${newKind}'s ${fill.field} filled in${fill.from !== undefined ? ` from ${fill.from}` : ""}`);
|
|
179
|
+
}
|
|
180
|
+
// Only a requirement this change brings counts: a record that already lacked a required value is not made worse.
|
|
181
|
+
for (const [field, spec] of Object.entries(now)) {
|
|
182
|
+
if (!spec.required || next[field] !== undefined)
|
|
183
|
+
continue;
|
|
184
|
+
const src = sourceField(was, field, spec);
|
|
185
|
+
if (!src || !was[src].required)
|
|
186
|
+
missingRequired++;
|
|
187
|
+
}
|
|
188
|
+
for (const field of Object.keys(was)) {
|
|
189
|
+
const kept = Object.entries(now).some(([f, spec]) => sourceField(was, f, spec) === field);
|
|
190
|
+
if (!kept && node[field] !== undefined) {
|
|
191
|
+
counts.cleared++;
|
|
192
|
+
note(`${newKind}'s ${field} removed, with its value(s)`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (newKind !== oldKind) {
|
|
196
|
+
// A kind cannot change in place: the record is made again under the new kind, with the same id.
|
|
197
|
+
rekinded.set(id, { id, kind: newKind, ...next });
|
|
198
|
+
removedIds.add(id);
|
|
199
|
+
counts.moved++;
|
|
200
|
+
note(`${oldKind} renamed to ${newKind}, records kept`);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
for (const key of new Set([...Object.keys(node), ...Object.keys(next)])) {
|
|
204
|
+
if (key === "id" || key === "kind")
|
|
205
|
+
continue;
|
|
206
|
+
const a = node[key];
|
|
207
|
+
const b = next[key];
|
|
208
|
+
if (JSON.stringify(a) === JSON.stringify(b))
|
|
209
|
+
continue;
|
|
210
|
+
patchBefore[key] = a === undefined ? UNSET : a;
|
|
211
|
+
patchAfter[key] = b === undefined ? UNSET : b;
|
|
212
|
+
}
|
|
213
|
+
if (Object.keys(patchAfter).length > 0)
|
|
214
|
+
primitives.push({ op: "patch-node", id, before: patchBefore, after: patchAfter });
|
|
215
|
+
}
|
|
216
|
+
// Links: kept, renamed (removed and added under the new name), or removed.
|
|
217
|
+
const keptEdges = [];
|
|
218
|
+
for (const edge of graph.edges) {
|
|
219
|
+
const name = edgeAfter.get(edge.kind);
|
|
220
|
+
const endsGone = removedIds.has(edge.from) && !rekinded.has(edge.from) || removedIds.has(edge.to) && !rekinded.has(edge.to);
|
|
221
|
+
const touchesRekinded = rekinded.has(edge.from) || rekinded.has(edge.to);
|
|
222
|
+
if (!name || endsGone) {
|
|
223
|
+
primitives.push({ op: "remove-edge", edge });
|
|
224
|
+
counts.removedEdges++;
|
|
225
|
+
note(!name ? `"${edge.kind}" link(s) removed with their relation` : `link(s) to removed records removed`);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (name !== edge.kind || touchesRekinded) {
|
|
229
|
+
primitives.push({ op: "remove-edge", edge });
|
|
230
|
+
keptEdges.push({ kind: name, from: edge.from, to: edge.to });
|
|
231
|
+
if (name !== edge.kind) {
|
|
232
|
+
counts.moved++;
|
|
233
|
+
note(`"${edge.kind}" renamed to "${name}", links kept`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
for (const node of graph.nodes) {
|
|
238
|
+
const id = String(node["id"]);
|
|
239
|
+
if (removedIds.has(id))
|
|
240
|
+
primitives.push({ op: "remove-node", node });
|
|
241
|
+
}
|
|
242
|
+
for (const node of rekinded.values())
|
|
243
|
+
primitives.push({ op: "add-node", node });
|
|
244
|
+
for (const edge of keptEdges)
|
|
245
|
+
primitives.push({ op: "add-edge", edge });
|
|
246
|
+
for (const [sentence, n] of tally)
|
|
247
|
+
words.push(sentence.includes("record(s)") || sentence.includes("link(s)") || sentence.includes("value(s)") ? `${n} ${sentence.replace(/\(s\)/g, n === 1 ? "" : "s")}.` : `${sentence} (${plural(n, "record")}).`);
|
|
248
|
+
if (missingRequired > 0)
|
|
249
|
+
words.push(`${plural(missingRequired, "required value")} would be missing; those records need ${missingRequired === 1 ? "it" : "them"} filled in.`);
|
|
250
|
+
return { primitives, words, counts, missingRequired };
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/document/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type PatchOp = {
|
|
2
|
+
readonly op: "add" | "replace" | "test";
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly value: unknown;
|
|
5
|
+
} | {
|
|
6
|
+
readonly op: "remove";
|
|
7
|
+
readonly path: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly op: "move" | "copy";
|
|
10
|
+
readonly from: string;
|
|
11
|
+
readonly path: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class PatchError extends Error {
|
|
14
|
+
}
|
|
15
|
+
export declare function applyPatch<T>(document: T, ops: readonly PatchOp[]): T;
|
|
16
|
+
//# sourceMappingURL=patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/document/patch.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,OAAO,GACf;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC3F;IAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,qBAAa,UAAW,SAAQ,KAAK;CAAG;AA6BxC,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,OAAO,EAAE,GAAG,CAAC,CA8BrE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* JSON Patch (RFC 6902: add, remove, replace, move, copy, test) — how an agent
|
|
3
|
+
* in a chat proposes a small change without resending the whole document.
|
|
4
|
+
*/
|
|
5
|
+
export class PatchError extends Error {
|
|
6
|
+
}
|
|
7
|
+
const unescape = (s) => s.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
8
|
+
const pointer = (path) => {
|
|
9
|
+
if (path === "")
|
|
10
|
+
return [];
|
|
11
|
+
if (!path.startsWith("/"))
|
|
12
|
+
throw new PatchError(`"${path}" is not a JSON pointer; it should start with "/"`);
|
|
13
|
+
return path.slice(1).split("/").map(unescape);
|
|
14
|
+
};
|
|
15
|
+
function parentOf(root, parts, path) {
|
|
16
|
+
let node = root;
|
|
17
|
+
for (const part of parts.slice(0, -1)) {
|
|
18
|
+
const next = Array.isArray(node) ? node[Number(part)] : node[part];
|
|
19
|
+
if (next === null || typeof next !== "object")
|
|
20
|
+
throw new PatchError(`nothing at "${path}" to change`);
|
|
21
|
+
node = next;
|
|
22
|
+
}
|
|
23
|
+
return { parent: node, key: parts.at(-1) };
|
|
24
|
+
}
|
|
25
|
+
function get(root, path) {
|
|
26
|
+
let node = root;
|
|
27
|
+
for (const part of pointer(path)) {
|
|
28
|
+
if (node === null || typeof node !== "object")
|
|
29
|
+
throw new PatchError(`nothing at "${path}"`);
|
|
30
|
+
node = Array.isArray(node) ? node[Number(part)] : node[part];
|
|
31
|
+
}
|
|
32
|
+
if (node === undefined)
|
|
33
|
+
throw new PatchError(`nothing at "${path}"`);
|
|
34
|
+
return node;
|
|
35
|
+
}
|
|
36
|
+
export function applyPatch(document, ops) {
|
|
37
|
+
if (ops.length > 200)
|
|
38
|
+
throw new PatchError("a patch may have at most 200 operations");
|
|
39
|
+
let root = structuredClone(document);
|
|
40
|
+
for (const op of ops) {
|
|
41
|
+
const parts = pointer(op.path);
|
|
42
|
+
if (op.op === "test") {
|
|
43
|
+
if (JSON.stringify(get(root, op.path)) !== JSON.stringify(op.value))
|
|
44
|
+
throw new PatchError(`"${op.path}" is not what the patch expected`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const value = "from" in op ? structuredClone(get(root, op.from)) : "value" in op ? structuredClone(op.value) : undefined;
|
|
48
|
+
if (op.op === "move" && "from" in op)
|
|
49
|
+
root = applyPatch(root, [{ op: "remove", path: op.from }]);
|
|
50
|
+
if (parts.length === 0) {
|
|
51
|
+
if (op.op === "remove")
|
|
52
|
+
throw new PatchError("cannot remove the whole document");
|
|
53
|
+
root = value;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const { parent, key } = parentOf(root, parts, op.path);
|
|
57
|
+
if (Array.isArray(parent)) {
|
|
58
|
+
const i = key === "-" ? parent.length : Number(key);
|
|
59
|
+
if (!Number.isInteger(i) || i < 0 || i > parent.length)
|
|
60
|
+
throw new PatchError(`"${op.path}" is not a place in that list`);
|
|
61
|
+
if (op.op === "remove")
|
|
62
|
+
parent.splice(i, 1);
|
|
63
|
+
else if (op.op === "replace")
|
|
64
|
+
parent[i] = value;
|
|
65
|
+
else
|
|
66
|
+
parent.splice(i, 0, value);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if ((op.op === "remove" || op.op === "replace") && !(key in parent))
|
|
70
|
+
throw new PatchError(`nothing at "${op.path}" to ${op.op}`);
|
|
71
|
+
if (op.op === "remove")
|
|
72
|
+
delete parent[key];
|
|
73
|
+
else
|
|
74
|
+
parent[key] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return root;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/document/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type AnySchema, type InvariantDefinition } from "../index.js";
|
|
2
|
+
import { type KindShape } from "./expr/evaluate.js";
|
|
3
|
+
/**
|
|
4
|
+
* What every kind of a COMPILED schema holds, for the rule language to read
|
|
5
|
+
* names against: its fields, and its relations with their cardinality (a
|
|
6
|
+
* relation of one reads as that record, a relation of many as a set). The
|
|
7
|
+
* document compiler builds the same from a document; this reads it from any
|
|
8
|
+
* declaration, TypeScript or document alike.
|
|
9
|
+
*/
|
|
10
|
+
export declare function shapesOfSchema(schema: AnySchema): Map<string, KindShape>;
|
|
11
|
+
/** A rule whose judgement is written in the rule language rather than as a function. */
|
|
12
|
+
export interface ExpressionRuleSpec {
|
|
13
|
+
/** The kind it judges, one violation per record; or the whole graph, at most one. */
|
|
14
|
+
readonly over: string | "graph";
|
|
15
|
+
/** What must hold. */
|
|
16
|
+
readonly require: string;
|
|
17
|
+
/** Only the records for which this holds are judged. */
|
|
18
|
+
readonly when?: string;
|
|
19
|
+
/** The sentence a violation says, as a template over the record: "{name} is booked but has no quote". */
|
|
20
|
+
readonly says?: string;
|
|
21
|
+
readonly title?: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
/** Acts that put it right, by name; each is offered with the subject as its `id`. */
|
|
24
|
+
readonly repairs?: readonly string[];
|
|
25
|
+
readonly judgesPast?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A RULE THAT SAYS WHAT MUST HOLD, AND IS JUDGED (FR-07). The studio and a
|
|
29
|
+
* checkout write a rule's judgement in the rule language instead of a
|
|
30
|
+
* function the studio cannot see; this makes it the invariant the engine
|
|
31
|
+
* runs. A syntax error is thrown here, when the rule is made — never later,
|
|
32
|
+
* while judging. Out of budget is `over-budget`; any other mistake while
|
|
33
|
+
* judging is `could-not-judge`; both name the rule and its subject.
|
|
34
|
+
*/
|
|
35
|
+
export declare function expressionRule(name: string, spec: ExpressionRuleSpec,
|
|
36
|
+
/** What each kind holds. Absent: read from the schema of the graph being judged, once per schema. */
|
|
37
|
+
kinds?: ReadonlyMap<string, KindShape>, options?: {
|
|
38
|
+
readonly today?: () => string;
|
|
39
|
+
}): InvariantDefinition;
|
|
40
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/document/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,KAAK,SAAS,EAAoB,KAAK,mBAAmB,EAAkB,MAAM,aAAa,CAAC;AAE9J,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIlG;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAUxE;AAYD,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yGAAyG;IACzG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,kBAAkB;AACxB,qGAAqG;AACrG,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EACtC,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GAC9C,mBAAmB,CAwCrB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { defineInvariant, RuleBudgetError } from "../index.js";
|
|
2
|
+
import { evaluateExpr, ExprBudgetError, ExprEvalError } from "./expr/evaluate.js";
|
|
3
|
+
import { parseExpr } from "./expr/parse.js";
|
|
4
|
+
import { parseTemplate, renderTemplate } from "./template.js";
|
|
5
|
+
/**
|
|
6
|
+
* What every kind of a COMPILED schema holds, for the rule language to read
|
|
7
|
+
* names against: its fields, and its relations with their cardinality (a
|
|
8
|
+
* relation of one reads as that record, a relation of many as a set). The
|
|
9
|
+
* document compiler builds the same from a document; this reads it from any
|
|
10
|
+
* declaration, TypeScript or document alike.
|
|
11
|
+
*/
|
|
12
|
+
export function shapesOfSchema(schema) {
|
|
13
|
+
const shapes = new Map();
|
|
14
|
+
for (const kind of schema.kinds) {
|
|
15
|
+
const definition = schema.tryDefinition(kind);
|
|
16
|
+
shapes.set(kind, {
|
|
17
|
+
fields: new Set(Object.keys(definition?.fields?.shape ?? {})),
|
|
18
|
+
edges: new Map(Object.entries(definition?.edges ?? {}).map(([name, edge]) => [name, edge.cardinality ?? "many"])),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return shapes;
|
|
22
|
+
}
|
|
23
|
+
const SHAPES = new WeakMap();
|
|
24
|
+
/** The shapes of the schema a graph was made with, read once per schema. */
|
|
25
|
+
function shapesOf(graph) {
|
|
26
|
+
const schema = graph.schema;
|
|
27
|
+
if (!schema)
|
|
28
|
+
throw new Error("a rule judged in words needs its kinds: pass them, or judge a Graph, which carries its schema");
|
|
29
|
+
let shapes = SHAPES.get(schema);
|
|
30
|
+
if (!shapes)
|
|
31
|
+
SHAPES.set(schema, (shapes = shapesOfSchema(schema)));
|
|
32
|
+
return shapes;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A RULE THAT SAYS WHAT MUST HOLD, AND IS JUDGED (FR-07). The studio and a
|
|
36
|
+
* checkout write a rule's judgement in the rule language instead of a
|
|
37
|
+
* function the studio cannot see; this makes it the invariant the engine
|
|
38
|
+
* runs. A syntax error is thrown here, when the rule is made — never later,
|
|
39
|
+
* while judging. Out of budget is `over-budget`; any other mistake while
|
|
40
|
+
* judging is `could-not-judge`; both name the rule and its subject.
|
|
41
|
+
*/
|
|
42
|
+
export function expressionRule(name, spec,
|
|
43
|
+
/** What each kind holds. Absent: read from the schema of the graph being judged, once per schema. */
|
|
44
|
+
kinds, options = {}) {
|
|
45
|
+
const require = parseExpr(spec.require);
|
|
46
|
+
const when = spec.when ? parseExpr(spec.when) : undefined;
|
|
47
|
+
const says = spec.says ? parseTemplate(spec.says) : undefined;
|
|
48
|
+
const title = spec.title ?? name.replace(/-/g, " ");
|
|
49
|
+
const today = options.today ?? (() => new Date().toISOString().slice(0, 10));
|
|
50
|
+
const judge = (graph, subject) => {
|
|
51
|
+
const shapes = (kinds ?? shapesOf(graph));
|
|
52
|
+
const ctx = { graph, subject, kinds: shapes, today: today() };
|
|
53
|
+
try {
|
|
54
|
+
if (when && evaluateExpr(when, ctx) !== true)
|
|
55
|
+
return [];
|
|
56
|
+
if (evaluateExpr(require, ctx) === true)
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof ExprBudgetError)
|
|
61
|
+
throw new RuleBudgetError(error.sentence);
|
|
62
|
+
if (error instanceof ExprEvalError)
|
|
63
|
+
throw new Error(error.sentence);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
invariant: name,
|
|
69
|
+
...(subject ? { subjectId: subject.id } : {}),
|
|
70
|
+
label: title,
|
|
71
|
+
message: says ? renderTemplate(says, { node: subject, kinds: shapes, graph, today: today() }) : title,
|
|
72
|
+
nodeIds: subject ? [subject.id] : [],
|
|
73
|
+
repairs: (spec.repairs ?? []).map((mutation) => ({ mutation, label: mutation.replace(/-/g, " "), args: subject ? { id: subject.id } : {} })),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
};
|
|
77
|
+
const common = {
|
|
78
|
+
label: title,
|
|
79
|
+
judgement: { require: spec.require, ...(spec.when ? { when: spec.when } : {}), ...(spec.says ? { says: spec.says } : {}) },
|
|
80
|
+
...(spec.description ? { description: spec.description } : {}),
|
|
81
|
+
...(spec.repairs && spec.repairs.length > 0 ? { repairs: [...spec.repairs] } : {}),
|
|
82
|
+
...(spec.judgesPast ? { judgesPast: true } : {}),
|
|
83
|
+
};
|
|
84
|
+
return (spec.over === "graph"
|
|
85
|
+
? defineInvariant(name, { scope: "graph", ...common, evaluate: ({ graph }) => judge(graph, null) })
|
|
86
|
+
: defineInvariant(name, { scope: { kind: spec.over }, ...common, evaluate: ({ graph, subject }) => judge(graph, subject) }));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/document/rules.ts"],"names":[],"mappings":"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"}
|