@graview/core 0.1.0
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/LICENSE +96 -0
- package/README.md +35 -0
- package/dist/app.d.ts +294 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +49 -0
- package/dist/app.js.map +1 -0
- package/dist/arrange.d.ts +185 -0
- package/dist/arrange.d.ts.map +1 -0
- package/dist/arrange.js +456 -0
- package/dist/arrange.js.map +1 -0
- package/dist/beginning.d.ts +65 -0
- package/dist/beginning.d.ts.map +1 -0
- package/dist/beginning.js +94 -0
- package/dist/beginning.js.map +1 -0
- package/dist/bind.d.ts +42 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +26 -0
- package/dist/bind.js.map +1 -0
- package/dist/city.d.ts +93 -0
- package/dist/city.d.ts.map +1 -0
- package/dist/city.js +160 -0
- package/dist/city.js.map +1 -0
- package/dist/cli/check/arrangement.d.ts +13 -0
- package/dist/cli/check/arrangement.d.ts.map +1 -0
- package/dist/cli/check/arrangement.js +63 -0
- package/dist/cli/check/arrangement.js.map +1 -0
- package/dist/cli/check/beginnings.d.ts +16 -0
- package/dist/cli/check/beginnings.d.ts.map +1 -0
- package/dist/cli/check/beginnings.js +53 -0
- package/dist/cli/check/beginnings.js.map +1 -0
- package/dist/cli/check/brand.d.ts +17 -0
- package/dist/cli/check/brand.d.ts.map +1 -0
- package/dist/cli/check/brand.js +153 -0
- package/dist/cli/check/brand.js.map +1 -0
- package/dist/cli/check/city.d.ts +17 -0
- package/dist/cli/check/city.d.ts.map +1 -0
- package/dist/cli/check/city.js +58 -0
- package/dist/cli/check/city.js.map +1 -0
- package/dist/cli/check/context.d.ts +50 -0
- package/dist/cli/check/context.d.ts.map +1 -0
- package/dist/cli/check/context.js +37 -0
- package/dist/cli/check/context.js.map +1 -0
- package/dist/cli/check/fields.d.ts +16 -0
- package/dist/cli/check/fields.d.ts.map +1 -0
- package/dist/cli/check/fields.js +237 -0
- package/dist/cli/check/fields.js.map +1 -0
- package/dist/cli/check/index.d.ts +14 -0
- package/dist/cli/check/index.d.ts.map +1 -0
- package/dist/cli/check/index.js +14 -0
- package/dist/cli/check/index.js.map +1 -0
- package/dist/cli/check/intelligence.d.ts +17 -0
- package/dist/cli/check/intelligence.d.ts.map +1 -0
- package/dist/cli/check/intelligence.js +136 -0
- package/dist/cli/check/intelligence.js.map +1 -0
- package/dist/cli/check/lenses.d.ts +17 -0
- package/dist/cli/check/lenses.d.ts.map +1 -0
- package/dist/cli/check/lenses.js +239 -0
- package/dist/cli/check/lenses.js.map +1 -0
- package/dist/cli/check/migrations.d.ts +16 -0
- package/dist/cli/check/migrations.d.ts.map +1 -0
- package/dist/cli/check/migrations.js +43 -0
- package/dist/cli/check/migrations.js.map +1 -0
- package/dist/cli/check/modules.d.ts +16 -0
- package/dist/cli/check/modules.d.ts.map +1 -0
- package/dist/cli/check/modules.js +123 -0
- package/dist/cli/check/modules.js.map +1 -0
- package/dist/cli/check/policy.d.ts +16 -0
- package/dist/cli/check/policy.d.ts.map +1 -0
- package/dist/cli/check/policy.js +90 -0
- package/dist/cli/check/policy.js.map +1 -0
- package/dist/cli/check/relations.d.ts +29 -0
- package/dist/cli/check/relations.d.ts.map +1 -0
- package/dist/cli/check/relations.js +279 -0
- package/dist/cli/check/relations.js.map +1 -0
- package/dist/cli/check/routes.d.ts +16 -0
- package/dist/cli/check/routes.d.ts.map +1 -0
- package/dist/cli/check/routes.js +31 -0
- package/dist/cli/check/routes.js.map +1 -0
- package/dist/cli/check/settings.d.ts +16 -0
- package/dist/cli/check/settings.d.ts.map +1 -0
- package/dist/cli/check/settings.js +81 -0
- package/dist/cli/check/settings.js.map +1 -0
- package/dist/cli/check.d.ts +36 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +76 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/create.d.ts +20 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +251 -0
- package/dist/cli/create.js.map +1 -0
- package/dist/cli/describe.d.ts +35 -0
- package/dist/cli/describe.d.ts.map +1 -0
- package/dist/cli/describe.js +230 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/docs.d.ts +11 -0
- package/dist/cli/docs.d.ts.map +1 -0
- package/dist/cli/docs.js +152 -0
- package/dist/cli/docs.js.map +1 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +281 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/extend.d.ts +23 -0
- package/dist/extend.d.ts.map +1 -0
- package/dist/extend.js +53 -0
- package/dist/extend.js.map +1 -0
- package/dist/graph/diff.d.ts +31 -0
- package/dist/graph/diff.d.ts.map +1 -0
- package/dist/graph/diff.js +71 -0
- package/dist/graph/diff.js.map +1 -0
- package/dist/graph/graph.d.ts +69 -0
- package/dist/graph/graph.d.ts.map +1 -0
- package/dist/graph/graph.js +284 -0
- package/dist/graph/graph.js.map +1 -0
- package/dist/graph/primitives.d.ts +52 -0
- package/dist/graph/primitives.d.ts.map +1 -0
- package/dist/graph/primitives.js +62 -0
- package/dist/graph/primitives.js.map +1 -0
- package/dist/graph/tracked.d.ts +31 -0
- package/dist/graph/tracked.d.ts.map +1 -0
- package/dist/graph/tracked.js +69 -0
- package/dist/graph/tracked.js.map +1 -0
- package/dist/graph/types.d.ts +34 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +0 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/installation.d.ts +112 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +193 -0
- package/dist/installation.js.map +1 -0
- package/dist/intelligence-bridge.d.ts +73 -0
- package/dist/intelligence-bridge.d.ts.map +1 -0
- package/dist/intelligence-bridge.js +31 -0
- package/dist/intelligence-bridge.js.map +1 -0
- package/dist/invariants/engine.d.ts +36 -0
- package/dist/invariants/engine.d.ts.map +1 -0
- package/dist/invariants/engine.js +88 -0
- package/dist/invariants/engine.js.map +1 -0
- package/dist/invariants/types.d.ts +75 -0
- package/dist/invariants/types.d.ts.map +1 -0
- package/dist/invariants/types.js +2 -0
- package/dist/invariants/types.js.map +1 -0
- package/dist/modules.d.ts +75 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +87 -0
- package/dist/modules.js.map +1 -0
- package/dist/mutations/decidable.d.ts +26 -0
- package/dist/mutations/decidable.d.ts.map +1 -0
- package/dist/mutations/decidable.js +39 -0
- package/dist/mutations/decidable.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts +32 -0
- package/dist/mutations/define-mutation.d.ts.map +1 -0
- package/dist/mutations/define-mutation.js +181 -0
- package/dist/mutations/define-mutation.js.map +1 -0
- package/dist/mutations/derive-edits.d.ts +75 -0
- package/dist/mutations/derive-edits.d.ts.map +1 -0
- package/dist/mutations/derive-edits.js +240 -0
- package/dist/mutations/derive-edits.js.map +1 -0
- package/dist/mutations/form.d.ts +63 -0
- package/dist/mutations/form.d.ts.map +1 -0
- package/dist/mutations/form.js +113 -0
- package/dist/mutations/form.js.map +1 -0
- package/dist/mutations/node-ref.d.ts +83 -0
- package/dist/mutations/node-ref.d.ts.map +1 -0
- package/dist/mutations/node-ref.js +113 -0
- package/dist/mutations/node-ref.js.map +1 -0
- package/dist/mutations/types.d.ts +136 -0
- package/dist/mutations/types.d.ts.map +1 -0
- package/dist/mutations/types.js +2 -0
- package/dist/mutations/types.js.map +1 -0
- package/dist/ops/log.d.ts +35 -0
- package/dist/ops/log.d.ts.map +1 -0
- package/dist/ops/log.js +103 -0
- package/dist/ops/log.js.map +1 -0
- package/dist/ops/types.d.ts +52 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +2 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/ops/undo.d.ts +33 -0
- package/dist/ops/undo.d.ts.map +1 -0
- package/dist/ops/undo.js +65 -0
- package/dist/ops/undo.js.map +1 -0
- package/dist/permissions/policy.d.ts +68 -0
- package/dist/permissions/policy.d.ts.map +1 -0
- package/dist/permissions/policy.js +191 -0
- package/dist/permissions/policy.js.map +1 -0
- package/dist/permissions/types.d.ts +78 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +17 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/persistence/memory.d.ts +6 -0
- package/dist/persistence/memory.d.ts.map +1 -0
- package/dist/persistence/memory.js +31 -0
- package/dist/persistence/memory.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +59 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +131 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/persistence/types.d.ts +22 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +2 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/presence.d.ts +38 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +50 -0
- package/dist/presence.js.map +1 -0
- package/dist/scaffold/domain.d.ts +8 -0
- package/dist/scaffold/domain.d.ts.map +1 -0
- package/dist/scaffold/domain.js +331 -0
- package/dist/scaffold/domain.js.map +1 -0
- package/dist/scaffold/index.d.ts +66 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +142 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/lens.d.ts +31 -0
- package/dist/scaffold/lens.d.ts.map +1 -0
- package/dist/scaffold/lens.js +176 -0
- package/dist/scaffold/lens.js.map +1 -0
- package/dist/scaffold/names.d.ts +44 -0
- package/dist/scaffold/names.d.ts.map +1 -0
- package/dist/scaffold/names.js +69 -0
- package/dist/scaffold/names.js.map +1 -0
- package/dist/scaffold/project.d.ts +41 -0
- package/dist/scaffold/project.d.ts.map +1 -0
- package/dist/scaffold/project.js +604 -0
- package/dist/scaffold/project.js.map +1 -0
- package/dist/scaffold/ui.d.ts +15 -0
- package/dist/scaffold/ui.d.ts.map +1 -0
- package/dist/scaffold/ui.js +536 -0
- package/dist/scaffold/ui.js.map +1 -0
- package/dist/schema/define-node.d.ts +132 -0
- package/dist/schema/define-node.d.ts.map +1 -0
- package/dist/schema/define-node.js +254 -0
- package/dist/schema/define-node.js.map +1 -0
- package/dist/schema/figures.d.ts +42 -0
- package/dist/schema/figures.d.ts.map +1 -0
- package/dist/schema/figures.js +220 -0
- package/dist/schema/figures.js.map +1 -0
- package/dist/schema/json-schema.d.ts +39 -0
- package/dist/schema/json-schema.d.ts.map +1 -0
- package/dist/schema/json-schema.js +74 -0
- package/dist/schema/json-schema.js.map +1 -0
- package/dist/schema/schema.d.ts +43 -0
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/schema.js +102 -0
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/types.d.ts +201 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +2 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/search.d.ts +215 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +449 -0
- package/dist/search.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +74 -0
- package/dist/settings.js.map +1 -0
- package/dist/store.d.ts +284 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +660 -0
- package/dist/store.js.map +1 -0
- package/dist/studio-door.d.ts +187 -0
- package/dist/studio-door.d.ts.map +1 -0
- package/dist/studio-door.js +20 -0
- package/dist/studio-door.js.map +1 -0
- package/dist/sync/conflict.d.ts +37 -0
- package/dist/sync/conflict.d.ts.map +1 -0
- package/dist/sync/conflict.js +56 -0
- package/dist/sync/conflict.js.map +1 -0
- package/dist/sync/engine.d.ts +118 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +341 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/google-calendar.d.ts +54 -0
- package/dist/sync/google-calendar.d.ts.map +1 -0
- package/dist/sync/google-calendar.js +167 -0
- package/dist/sync/google-calendar.js.map +1 -0
- package/dist/sync/types.d.ts +125 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +6 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/temporal/effectivity.d.ts +75 -0
- package/dist/temporal/effectivity.d.ts.map +1 -0
- package/dist/temporal/effectivity.js +89 -0
- package/dist/temporal/effectivity.js.map +1 -0
- package/dist/testing.d.ts +63 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +194 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme/contrast.d.ts +47 -0
- package/dist/theme/contrast.d.ts.map +1 -0
- package/dist/theme/contrast.js +172 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/derive.d.ts +81 -0
- package/dist/theme/derive.d.ts.map +1 -0
- package/dist/theme/derive.js +171 -0
- package/dist/theme/derive.js.map +1 -0
- package/dist/theme/kit.d.ts +106 -0
- package/dist/theme/kit.d.ts.map +1 -0
- package/dist/theme/kit.js +84 -0
- package/dist/theme/kit.js.map +1 -0
- package/dist/theme/palettes.d.ts +32 -0
- package/dist/theme/palettes.d.ts.map +1 -0
- package/dist/theme/palettes.js +96 -0
- package/dist/theme/palettes.js.map +1 -0
- package/dist/theme/types.d.ts +131 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +23 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/views/types.d.ts +89 -0
- package/dist/views/types.d.ts.map +1 -0
- package/dist/views/types.js +88 -0
- package/dist/views/types.js.map +1 -0
- package/dist/watched.d.ts +33 -0
- package/dist/watched.d.ts.map +1 -0
- package/dist/watched.js +50 -0
- package/dist/watched.js.map +1 -0
- package/dist/who.d.ts +26 -0
- package/dist/who.d.ts.map +1 -0
- package/dist/who.js +20 -0
- package/dist/who.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { humaniseField, labelOf } from "../schema/define-node.js";
|
|
2
|
+
import { SchemaError } from "../schema/schema.js";
|
|
3
|
+
import { diffSnapshots } from "./diff.js";
|
|
4
|
+
import { isUnset } from "./primitives.js";
|
|
5
|
+
import { edgeId } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* A validator's complaint, said in words.
|
|
8
|
+
*
|
|
9
|
+
* Zod's own `message` is the whole issue list as JSON. Each issue already
|
|
10
|
+
* carries a readable sentence and the path it is about, so the field is
|
|
11
|
+
* named the way the rest of the interface names it and the sentences are
|
|
12
|
+
* joined — nothing else in the object is for a person.
|
|
13
|
+
*/
|
|
14
|
+
function readably(error) {
|
|
15
|
+
const issues = error
|
|
16
|
+
?.issues;
|
|
17
|
+
if (!Array.isArray(issues) || issues.length === 0) {
|
|
18
|
+
return error instanceof Error ? error.message : String(error);
|
|
19
|
+
}
|
|
20
|
+
return issues
|
|
21
|
+
.map((issue) => {
|
|
22
|
+
const field = issue.path?.length ? humaniseField(String(issue.path.at(-1))) : null;
|
|
23
|
+
const said = issue.message ?? "is not what the declaration allows";
|
|
24
|
+
return field ? `${field}: ${said}` : said;
|
|
25
|
+
})
|
|
26
|
+
.join("; ");
|
|
27
|
+
}
|
|
28
|
+
export class GraphError extends Error {
|
|
29
|
+
hint;
|
|
30
|
+
constructor(message, hint) {
|
|
31
|
+
super(hint ? `${message}\n ${hint}` : message);
|
|
32
|
+
this.hint = hint;
|
|
33
|
+
this.name = "GraphError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The framework owns the reactive in-memory graph. Owning it — rather than
|
|
38
|
+
* reading someone else's store — is what makes invariants enforceable and
|
|
39
|
+
* agent attribution free; persistence is a pluggable adapter underneath.
|
|
40
|
+
*/
|
|
41
|
+
export class Graph {
|
|
42
|
+
schema;
|
|
43
|
+
nodes = new Map();
|
|
44
|
+
edges = new Map();
|
|
45
|
+
outIndex = new Map();
|
|
46
|
+
inIndex = new Map();
|
|
47
|
+
listeners = new Set();
|
|
48
|
+
validate;
|
|
49
|
+
constructor(schema, options = {}) {
|
|
50
|
+
this.schema = schema;
|
|
51
|
+
this.validate = options.validate ?? true;
|
|
52
|
+
}
|
|
53
|
+
static from(schema, snapshot, options = {}) {
|
|
54
|
+
const graph = new Graph(schema, options);
|
|
55
|
+
graph.load(snapshot);
|
|
56
|
+
return graph;
|
|
57
|
+
}
|
|
58
|
+
/** Replaces the whole graph without emitting a per-node diff storm. */
|
|
59
|
+
load(snapshot) {
|
|
60
|
+
const before = this.snapshot();
|
|
61
|
+
this.nodes.clear();
|
|
62
|
+
this.edges.clear();
|
|
63
|
+
this.outIndex.clear();
|
|
64
|
+
this.inIndex.clear();
|
|
65
|
+
for (const node of snapshot.nodes)
|
|
66
|
+
this.insertNode(node);
|
|
67
|
+
for (const edge of snapshot.edges)
|
|
68
|
+
this.insertEdge(edge);
|
|
69
|
+
const diff = diffSnapshots(before, this.snapshot());
|
|
70
|
+
this.emit(diff);
|
|
71
|
+
return diff;
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------- reads
|
|
74
|
+
getNode(id) {
|
|
75
|
+
return this.nodes.get(id);
|
|
76
|
+
}
|
|
77
|
+
has(id) {
|
|
78
|
+
return this.nodes.has(id);
|
|
79
|
+
}
|
|
80
|
+
allNodes() {
|
|
81
|
+
return [...this.nodes.values()];
|
|
82
|
+
}
|
|
83
|
+
allEdges() {
|
|
84
|
+
return [...this.edges.values()];
|
|
85
|
+
}
|
|
86
|
+
nodesOfKind(kind) {
|
|
87
|
+
return this.allNodes().filter((node) => node.kind === kind);
|
|
88
|
+
}
|
|
89
|
+
edgesOfKind(kind) {
|
|
90
|
+
return this.allEdges().filter((edge) => edge.kind === kind);
|
|
91
|
+
}
|
|
92
|
+
out(id, kind) {
|
|
93
|
+
return this.resolve(this.outIndex.get(id), kind, "to");
|
|
94
|
+
}
|
|
95
|
+
in(id, kind) {
|
|
96
|
+
return this.resolve(this.inIndex.get(id), kind, "from");
|
|
97
|
+
}
|
|
98
|
+
neighbors(id) {
|
|
99
|
+
const seen = new Map();
|
|
100
|
+
for (const node of [...this.out(id), ...this.in(id)])
|
|
101
|
+
seen.set(node.id, node);
|
|
102
|
+
return [...seen.values()];
|
|
103
|
+
}
|
|
104
|
+
/** Edges leaving `id`, optionally of one kind. */
|
|
105
|
+
outEdges(id, kind) {
|
|
106
|
+
return this.edgesFrom(this.outIndex.get(id), kind);
|
|
107
|
+
}
|
|
108
|
+
/** Edges arriving at `id`, optionally of one kind. */
|
|
109
|
+
inEdges(id, kind) {
|
|
110
|
+
return this.edgesFrom(this.inIndex.get(id), kind);
|
|
111
|
+
}
|
|
112
|
+
snapshot() {
|
|
113
|
+
return { nodes: this.allNodes(), edges: this.allEdges() };
|
|
114
|
+
}
|
|
115
|
+
get size() {
|
|
116
|
+
return { nodes: this.nodes.size, edges: this.edges.size };
|
|
117
|
+
}
|
|
118
|
+
// ------------------------------------------------------------- writes
|
|
119
|
+
/**
|
|
120
|
+
* Applies primitives as one batch and emits a single diff. Nothing outside
|
|
121
|
+
* the op log should call this directly — attribution lives in the log.
|
|
122
|
+
*/
|
|
123
|
+
applyPrimitives(primitives) {
|
|
124
|
+
const before = this.snapshot();
|
|
125
|
+
for (const primitive of primitives)
|
|
126
|
+
this.applyOne(primitive);
|
|
127
|
+
const diff = diffSnapshots(before, this.snapshot());
|
|
128
|
+
this.emit(diff);
|
|
129
|
+
return diff;
|
|
130
|
+
}
|
|
131
|
+
/** Applies primitives to a throwaway copy — used for previewing a diff. */
|
|
132
|
+
preview(primitives) {
|
|
133
|
+
const copy = Graph.from(this.schema, this.snapshot(), { validate: this.validate });
|
|
134
|
+
return copy.applyPrimitives(primitives);
|
|
135
|
+
}
|
|
136
|
+
subscribe(listener) {
|
|
137
|
+
this.listeners.add(listener);
|
|
138
|
+
return () => this.listeners.delete(listener);
|
|
139
|
+
}
|
|
140
|
+
// ------------------------------------------------------------ internals
|
|
141
|
+
emit(diff) {
|
|
142
|
+
if (diff.addedNodes.length === 0 &&
|
|
143
|
+
diff.removedNodes.length === 0 &&
|
|
144
|
+
diff.changedNodes.length === 0 &&
|
|
145
|
+
diff.addedEdges.length === 0 &&
|
|
146
|
+
diff.removedEdges.length === 0) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
for (const listener of this.listeners)
|
|
150
|
+
listener(diff);
|
|
151
|
+
}
|
|
152
|
+
applyOne(primitive) {
|
|
153
|
+
switch (primitive.op) {
|
|
154
|
+
case "add-node":
|
|
155
|
+
this.insertNode(primitive.node);
|
|
156
|
+
return;
|
|
157
|
+
case "remove-node": {
|
|
158
|
+
const id = primitive.node.id;
|
|
159
|
+
if (!this.nodes.has(id)) {
|
|
160
|
+
throw new GraphError(`Cannot remove missing node "${id}"`);
|
|
161
|
+
}
|
|
162
|
+
for (const edge of [...this.outEdges(id), ...this.inEdges(id)]) {
|
|
163
|
+
this.deleteEdge(edge);
|
|
164
|
+
}
|
|
165
|
+
this.nodes.delete(id);
|
|
166
|
+
this.outIndex.delete(id);
|
|
167
|
+
this.inIndex.delete(id);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
case "patch-node": {
|
|
171
|
+
const current = this.nodes.get(primitive.id);
|
|
172
|
+
if (!current) {
|
|
173
|
+
throw new GraphError(`Cannot patch missing node "${primitive.id}"`);
|
|
174
|
+
}
|
|
175
|
+
const next = { ...current };
|
|
176
|
+
for (const [key, value] of Object.entries(primitive.after)) {
|
|
177
|
+
// `undefined` in memory, `UNSET` once written down: both mean the
|
|
178
|
+
// key goes away. See `normalise` in primitives.ts.
|
|
179
|
+
if (isUnset(value))
|
|
180
|
+
delete next[key];
|
|
181
|
+
else
|
|
182
|
+
next[key] = value;
|
|
183
|
+
}
|
|
184
|
+
this.nodes.set(primitive.id, this.check(next));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
case "add-edge":
|
|
188
|
+
this.insertEdge(primitive.edge);
|
|
189
|
+
return;
|
|
190
|
+
case "remove-edge": {
|
|
191
|
+
if (!this.edges.has(edgeId(primitive.edge))) {
|
|
192
|
+
throw new GraphError(`Cannot remove missing edge ${edgeId(primitive.edge)}`);
|
|
193
|
+
}
|
|
194
|
+
this.deleteEdge(primitive.edge);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
check(node) {
|
|
200
|
+
if (!this.validate)
|
|
201
|
+
return node;
|
|
202
|
+
try {
|
|
203
|
+
return this.schema.parseNode(node);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (error instanceof SchemaError)
|
|
207
|
+
throw error;
|
|
208
|
+
const id = node?.id ?? "?";
|
|
209
|
+
const kind = node?.kind ?? "?";
|
|
210
|
+
/*
|
|
211
|
+
* A PERSON READS THIS. It is not only a developer's console message:
|
|
212
|
+
* a refused undo shows its reason in the activity rail, so the raw
|
|
213
|
+
* validator dump — `[ { "code": "invalid_value", "values": [ … ],
|
|
214
|
+
* "path": [ "urgency" ] … } ]` — went straight into the interface,
|
|
215
|
+
* beside a sentence about a thing called "Pay the deposit". The field
|
|
216
|
+
* is named in the app's own words and the node by its label.
|
|
217
|
+
*/
|
|
218
|
+
const definition = this.schema.tryDefinition(kind);
|
|
219
|
+
const named = definition && node && typeof node === "object"
|
|
220
|
+
? labelOf(definition, node)
|
|
221
|
+
: id;
|
|
222
|
+
throw new GraphError(`${named} does not match what ${kind} declares`, readably(error));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
insertNode(node) {
|
|
226
|
+
if (this.nodes.has(node.id)) {
|
|
227
|
+
throw new GraphError(`Duplicate node id "${node.id}"`);
|
|
228
|
+
}
|
|
229
|
+
this.nodes.set(node.id, this.check(node));
|
|
230
|
+
}
|
|
231
|
+
insertEdge(edge) {
|
|
232
|
+
const from = this.nodes.get(edge.from);
|
|
233
|
+
const to = this.nodes.get(edge.to);
|
|
234
|
+
if (!from || !to) {
|
|
235
|
+
throw new GraphError(`Edge "${edge.kind}" references missing node "${from ? edge.to : edge.from}"`);
|
|
236
|
+
}
|
|
237
|
+
if (this.validate && !this.schema.edgeAllowed(edge.kind, from.kind, to.kind)) {
|
|
238
|
+
const declared = this.schema.edge(edge.kind);
|
|
239
|
+
throw new GraphError(`Edge "${edge.kind}" is not declared from ${from.kind} to ${to.kind}`, declared
|
|
240
|
+
? `Declared: ${declared.from.join("|")} -> ${declared.to === "*" ? "*" : declared.to.join("|")}`
|
|
241
|
+
: `No edge kind "${edge.kind}" is declared in this schema`);
|
|
242
|
+
}
|
|
243
|
+
const id = edgeId(edge);
|
|
244
|
+
if (this.edges.has(id))
|
|
245
|
+
return;
|
|
246
|
+
this.edges.set(id, edge);
|
|
247
|
+
this.index(this.outIndex, edge.from, id);
|
|
248
|
+
this.index(this.inIndex, edge.to, id);
|
|
249
|
+
}
|
|
250
|
+
deleteEdge(edge) {
|
|
251
|
+
const id = edgeId(edge);
|
|
252
|
+
this.edges.delete(id);
|
|
253
|
+
this.outIndex.get(edge.from)?.delete(id);
|
|
254
|
+
this.inIndex.get(edge.to)?.delete(id);
|
|
255
|
+
}
|
|
256
|
+
index(map, key, id) {
|
|
257
|
+
const set = map.get(key);
|
|
258
|
+
if (set)
|
|
259
|
+
set.add(id);
|
|
260
|
+
else
|
|
261
|
+
map.set(key, new Set([id]));
|
|
262
|
+
}
|
|
263
|
+
edgesFrom(ids, kind) {
|
|
264
|
+
if (!ids)
|
|
265
|
+
return [];
|
|
266
|
+
const result = [];
|
|
267
|
+
for (const id of ids) {
|
|
268
|
+
const edge = this.edges.get(id);
|
|
269
|
+
if (edge && (kind === undefined || edge.kind === kind))
|
|
270
|
+
result.push(edge);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
resolve(ids, kind, end) {
|
|
275
|
+
const result = [];
|
|
276
|
+
for (const edge of this.edgesFrom(ids, kind)) {
|
|
277
|
+
const node = this.nodes.get(edge[end]);
|
|
278
|
+
if (node)
|
|
279
|
+
result.push(node);
|
|
280
|
+
}
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/graph/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AnyGraphNode, GraphEdge } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The five primitive operations every mutation compiles down to. Keeping the
|
|
4
|
+
* primitive set this small is what makes inverses mechanical and the fold
|
|
5
|
+
* over the log total.
|
|
6
|
+
*/
|
|
7
|
+
export type Primitive = {
|
|
8
|
+
readonly op: "add-node";
|
|
9
|
+
readonly node: AnyGraphNode;
|
|
10
|
+
} | {
|
|
11
|
+
readonly op: "remove-node";
|
|
12
|
+
readonly node: AnyGraphNode;
|
|
13
|
+
} | {
|
|
14
|
+
readonly op: "patch-node";
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly before: Readonly<Record<string, unknown>>;
|
|
17
|
+
readonly after: Readonly<Record<string, unknown>>;
|
|
18
|
+
} | {
|
|
19
|
+
readonly op: "add-edge";
|
|
20
|
+
readonly edge: GraphEdge;
|
|
21
|
+
} | {
|
|
22
|
+
readonly op: "remove-edge";
|
|
23
|
+
readonly edge: GraphEdge;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* "THIS KEY GOES AWAY", written down.
|
|
27
|
+
*
|
|
28
|
+
* A patch says "remove this field" by carrying the key with the value
|
|
29
|
+
* `undefined` — which is fine in memory and vanishes the moment the op is
|
|
30
|
+
* written to JSON. So every persisted patch that cleared a field came back
|
|
31
|
+
* with an empty `before`, and its inverse — the whole promise of an op log —
|
|
32
|
+
* silently did nothing. A migration that added a field could be "undone"
|
|
33
|
+
* after a reload and leave the field exactly where it was.
|
|
34
|
+
*
|
|
35
|
+
* `UNSET` is that instruction as a value. It survives JSON, it survives an
|
|
36
|
+
* export bundle, and `normalise` puts it in front of every primitive on its
|
|
37
|
+
* way into an operation so nobody writing a mutation has to know.
|
|
38
|
+
*/
|
|
39
|
+
export declare const UNSET = "\0graview:unset";
|
|
40
|
+
/** Whether a patch value means "take this key off the node". */
|
|
41
|
+
export declare const isUnset: (value: unknown) => boolean;
|
|
42
|
+
/**
|
|
43
|
+
* A primitive with every "remove this key" said as a value rather than as an
|
|
44
|
+
* absence. Applied where primitives become operations, so the log, the
|
|
45
|
+
* adapters and the export all carry the same instruction.
|
|
46
|
+
*/
|
|
47
|
+
export declare function normalise(primitive: Primitive): Primitive;
|
|
48
|
+
/** Every primitive's inverse is another primitive — no special cases. */
|
|
49
|
+
export declare function invert(primitive: Primitive): Primitive;
|
|
50
|
+
/** Node ids a primitive writes to. */
|
|
51
|
+
export declare function writesOf(primitive: Primitive): string[];
|
|
52
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/graph/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC3D;IACE,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,oBAAwB,CAAC;AAE3C,gEAAgE;AAChE,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,OAAiD,CAAC;AAE3F;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAOzD;AAED,yEAAyE;AACzE,wBAAgB,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAkBtD;AAED,sCAAsC;AACtC,wBAAgB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,CAWvD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "THIS KEY GOES AWAY", written down.
|
|
3
|
+
*
|
|
4
|
+
* A patch says "remove this field" by carrying the key with the value
|
|
5
|
+
* `undefined` — which is fine in memory and vanishes the moment the op is
|
|
6
|
+
* written to JSON. So every persisted patch that cleared a field came back
|
|
7
|
+
* with an empty `before`, and its inverse — the whole promise of an op log —
|
|
8
|
+
* silently did nothing. A migration that added a field could be "undone"
|
|
9
|
+
* after a reload and leave the field exactly where it was.
|
|
10
|
+
*
|
|
11
|
+
* `UNSET` is that instruction as a value. It survives JSON, it survives an
|
|
12
|
+
* export bundle, and `normalise` puts it in front of every primitive on its
|
|
13
|
+
* way into an operation so nobody writing a mutation has to know.
|
|
14
|
+
*/
|
|
15
|
+
export const UNSET = "\u0000graview:unset";
|
|
16
|
+
/** Whether a patch value means "take this key off the node". */
|
|
17
|
+
export const isUnset = (value) => value === undefined || value === UNSET;
|
|
18
|
+
/**
|
|
19
|
+
* A primitive with every "remove this key" said as a value rather than as an
|
|
20
|
+
* absence. Applied where primitives become operations, so the log, the
|
|
21
|
+
* adapters and the export all carry the same instruction.
|
|
22
|
+
*/
|
|
23
|
+
export function normalise(primitive) {
|
|
24
|
+
if (primitive.op !== "patch-node")
|
|
25
|
+
return primitive;
|
|
26
|
+
const said = (fields) => Object.fromEntries(Object.entries(fields).map(([key, value]) => [key, value === undefined ? UNSET : value]));
|
|
27
|
+
return { ...primitive, before: said(primitive.before), after: said(primitive.after) };
|
|
28
|
+
}
|
|
29
|
+
/** Every primitive's inverse is another primitive — no special cases. */
|
|
30
|
+
export function invert(primitive) {
|
|
31
|
+
switch (primitive.op) {
|
|
32
|
+
case "add-node":
|
|
33
|
+
return { op: "remove-node", node: primitive.node };
|
|
34
|
+
case "remove-node":
|
|
35
|
+
return { op: "add-node", node: primitive.node };
|
|
36
|
+
case "patch-node":
|
|
37
|
+
return {
|
|
38
|
+
op: "patch-node",
|
|
39
|
+
id: primitive.id,
|
|
40
|
+
before: primitive.after,
|
|
41
|
+
after: primitive.before,
|
|
42
|
+
};
|
|
43
|
+
case "add-edge":
|
|
44
|
+
return { op: "remove-edge", edge: primitive.edge };
|
|
45
|
+
case "remove-edge":
|
|
46
|
+
return { op: "add-edge", edge: primitive.edge };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Node ids a primitive writes to. */
|
|
50
|
+
export function writesOf(primitive) {
|
|
51
|
+
switch (primitive.op) {
|
|
52
|
+
case "add-node":
|
|
53
|
+
case "remove-node":
|
|
54
|
+
return [primitive.node.id];
|
|
55
|
+
case "patch-node":
|
|
56
|
+
return [primitive.id];
|
|
57
|
+
case "add-edge":
|
|
58
|
+
case "remove-edge":
|
|
59
|
+
return [primitive.edge.from, primitive.edge.to];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/graph/primitives.ts"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,qBAAqB,CAAC;AAE3C,gEAAgE;AAChE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC;AAE3F;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,SAAoB;IAC5C,IAAI,SAAS,CAAC,EAAE,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,IAAI,GAAG,CAAC,MAAyC,EAA2B,EAAE,CAClF,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACzF,CAAC;IACJ,OAAO,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,MAAM,CAAC,SAAoB;IACzC,QAAQ,SAAS,CAAC,EAAE,EAAE,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,aAAa;YAChB,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;QAClD,KAAK,YAAY;YACf,OAAO;gBACL,EAAE,EAAE,YAAY;gBAChB,EAAE,EAAE,SAAS,CAAC,EAAE;gBAChB,MAAM,EAAE,SAAS,CAAC,KAAK;gBACvB,KAAK,EAAE,SAAS,CAAC,MAAM;aACxB,CAAC;QACJ,KAAK,UAAU;YACb,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,aAAa;YAChB,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;AACH,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,QAAQ,CAAC,SAAoB;IAC3C,QAAQ,SAAS,CAAC,EAAE,EAAE,CAAC;QACrB,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7B,KAAK,YAAY;YACf,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACxB,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GraphEdge, GraphNodeBase, GraphReader } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Records every node a mutation looked at.
|
|
4
|
+
*
|
|
5
|
+
* Reads-tracking has to exist from the very first operation — historical
|
|
6
|
+
* reads are not recoverable, so this cannot be retrofitted onto an existing
|
|
7
|
+
* log. That constraint is why the mutation API hands out a reader rather
|
|
8
|
+
* than the graph itself.
|
|
9
|
+
*/
|
|
10
|
+
export declare class TrackedReader<N extends GraphNodeBase> implements GraphReader<N> {
|
|
11
|
+
private readonly inner;
|
|
12
|
+
private readonly seen;
|
|
13
|
+
constructor(inner: GraphReader<N>);
|
|
14
|
+
/** The ids this mutation read, in insertion order. */
|
|
15
|
+
reads(): string[];
|
|
16
|
+
private mark;
|
|
17
|
+
private markAll;
|
|
18
|
+
private markEdges;
|
|
19
|
+
getNode(id: string): N | undefined;
|
|
20
|
+
has(id: string): boolean;
|
|
21
|
+
allNodes(): N[];
|
|
22
|
+
allEdges(): GraphEdge[];
|
|
23
|
+
nodesOfKind<K extends N["kind"]>(kind: K): Extract<N, {
|
|
24
|
+
kind: K;
|
|
25
|
+
}>[];
|
|
26
|
+
edgesOfKind(kind: string): GraphEdge[];
|
|
27
|
+
out(id: string, kind?: string): N[];
|
|
28
|
+
in(id: string, kind?: string): N[];
|
|
29
|
+
neighbors(id: string): N[];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tracked.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked.d.ts","sourceRoot":"","sources":["../../src/graph/tracked.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,qBAAa,aAAa,CAAC,CAAC,SAAS,aAAa,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;IAG/D,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAEb,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;IAElD,sDAAsD;IACtD,KAAK,IAAI,MAAM,EAAE;IAIjB,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAKlC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKxB,QAAQ,IAAI,CAAC,EAAE;IAIf,QAAQ,IAAI,SAAS,EAAE;IAIvB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,EAAE;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE;IAItC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE;IAKnC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE;IAKlC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE;CAI3B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records every node a mutation looked at.
|
|
3
|
+
*
|
|
4
|
+
* Reads-tracking has to exist from the very first operation — historical
|
|
5
|
+
* reads are not recoverable, so this cannot be retrofitted onto an existing
|
|
6
|
+
* log. That constraint is why the mutation API hands out a reader rather
|
|
7
|
+
* than the graph itself.
|
|
8
|
+
*/
|
|
9
|
+
export class TrackedReader {
|
|
10
|
+
inner;
|
|
11
|
+
seen = new Set();
|
|
12
|
+
constructor(inner) {
|
|
13
|
+
this.inner = inner;
|
|
14
|
+
}
|
|
15
|
+
/** The ids this mutation read, in insertion order. */
|
|
16
|
+
reads() {
|
|
17
|
+
return [...this.seen];
|
|
18
|
+
}
|
|
19
|
+
mark(node) {
|
|
20
|
+
if (node)
|
|
21
|
+
this.seen.add(node.id);
|
|
22
|
+
return node;
|
|
23
|
+
}
|
|
24
|
+
markAll(nodes) {
|
|
25
|
+
for (const node of nodes)
|
|
26
|
+
this.seen.add(node.id);
|
|
27
|
+
return nodes;
|
|
28
|
+
}
|
|
29
|
+
markEdges(edges) {
|
|
30
|
+
for (const edge of edges) {
|
|
31
|
+
this.seen.add(edge.from);
|
|
32
|
+
this.seen.add(edge.to);
|
|
33
|
+
}
|
|
34
|
+
return edges;
|
|
35
|
+
}
|
|
36
|
+
getNode(id) {
|
|
37
|
+
this.seen.add(id);
|
|
38
|
+
return this.mark(this.inner.getNode(id));
|
|
39
|
+
}
|
|
40
|
+
has(id) {
|
|
41
|
+
this.seen.add(id);
|
|
42
|
+
return this.inner.has(id);
|
|
43
|
+
}
|
|
44
|
+
allNodes() {
|
|
45
|
+
return this.markAll(this.inner.allNodes());
|
|
46
|
+
}
|
|
47
|
+
allEdges() {
|
|
48
|
+
return this.markEdges(this.inner.allEdges());
|
|
49
|
+
}
|
|
50
|
+
nodesOfKind(kind) {
|
|
51
|
+
return this.markAll(this.inner.nodesOfKind(kind));
|
|
52
|
+
}
|
|
53
|
+
edgesOfKind(kind) {
|
|
54
|
+
return this.markEdges(this.inner.edgesOfKind(kind));
|
|
55
|
+
}
|
|
56
|
+
out(id, kind) {
|
|
57
|
+
this.seen.add(id);
|
|
58
|
+
return this.markAll(this.inner.out(id, kind));
|
|
59
|
+
}
|
|
60
|
+
in(id, kind) {
|
|
61
|
+
this.seen.add(id);
|
|
62
|
+
return this.markAll(this.inner.in(id, kind));
|
|
63
|
+
}
|
|
64
|
+
neighbors(id) {
|
|
65
|
+
this.seen.add(id);
|
|
66
|
+
return this.markAll(this.inner.neighbors(id));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=tracked.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked.js","sourceRoot":"","sources":["../../src/graph/tracked.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAGK;IAFZ,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C,YAA6B,KAAqB;QAArB,UAAK,GAAL,KAAK,CAAgB;IAAG,CAAC;IAEtD,sDAAsD;IACtD,KAAK;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAEO,IAAI,CAA0B,IAAO;QAC3C,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,OAAO,CAAc,KAAU;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,SAAS,CAAC,KAAkB;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,WAAW,CAAsB,IAAO;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,GAAG,CAAC,EAAU,EAAE,IAAa;QAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,EAAE,CAAC,EAAU,EAAE,IAAa;QAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS,CAAC,EAAU;QAClB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface GraphEdge {
|
|
2
|
+
readonly kind: string;
|
|
3
|
+
readonly from: string;
|
|
4
|
+
readonly to: string;
|
|
5
|
+
}
|
|
6
|
+
/** Stable identity for an edge — edges have no id of their own. */
|
|
7
|
+
export declare function edgeId(edge: GraphEdge): string;
|
|
8
|
+
export interface GraphNodeBase {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly kind: string;
|
|
11
|
+
}
|
|
12
|
+
export type AnyGraphNode = GraphNodeBase & Record<string, unknown>;
|
|
13
|
+
/** The read surface a mutation sees. Every method here is instrumented. */
|
|
14
|
+
export interface GraphReader<N extends GraphNodeBase = AnyGraphNode> {
|
|
15
|
+
getNode(id: string): N | undefined;
|
|
16
|
+
allNodes(): N[];
|
|
17
|
+
allEdges(): GraphEdge[];
|
|
18
|
+
nodesOfKind<K extends N["kind"]>(kind: K): Extract<N, {
|
|
19
|
+
kind: K;
|
|
20
|
+
}>[];
|
|
21
|
+
edgesOfKind(kind: string): GraphEdge[];
|
|
22
|
+
/** Nodes reached by following `kind` edges out of `id`. */
|
|
23
|
+
out(id: string, kind?: string): N[];
|
|
24
|
+
/** Nodes with a `kind` edge pointing at `id`. */
|
|
25
|
+
in(id: string, kind?: string): N[];
|
|
26
|
+
/** Every node one edge away, in either direction. */
|
|
27
|
+
neighbors(id: string): N[];
|
|
28
|
+
has(id: string): boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface GraphSnapshot<N extends GraphNodeBase = AnyGraphNode> {
|
|
31
|
+
readonly nodes: readonly N[];
|
|
32
|
+
readonly edges: readonly GraphEdge[];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,mEAAmE;AACnE,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAE9C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnE,2EAA2E;AAC3E,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,aAAa,GAAG,YAAY;IACjE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACnC,QAAQ,IAAI,CAAC,EAAE,CAAC;IAChB,QAAQ,IAAI,SAAS,EAAE,CAAC;IACxB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,EAAE,CAAC;IACrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IACvC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;IACpC,iDAAiD;IACjD,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;IACnC,qDAAqD;IACrD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,aAAa,GAAG,YAAY;IACnE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;CACtC"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/graph/types.ts"],"names":[],"mappings":"AAMA,mEAAmE;AACnE,MAAM,UAAU,MAAM,CAAC,IAAe;IACpC,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;AAChD,CAAC"}
|