@graview/core 0.1.0 → 0.1.2
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 +787 -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 +143 -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 +1420 -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 +459 -0
- package/dist/document/schema.d.ts.map +1 -0
- package/dist/document/schema.js +197 -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 +182 -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 +52 -3
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +169 -16
- package/dist/graph/graph.js.map +1 -1
- package/dist/index.d.ts +40 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -10
- 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 +2 -3
- 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 +145 -4
- package/dist/ops/log.d.ts.map +1 -1
- package/dist/ops/log.js +220 -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 +23 -2
- package/dist/ops/undo.d.ts.map +1 -1
- package/dist/ops/undo.js +107 -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 +50 -0
- package/dist/permissions/sight.d.ts.map +1 -0
- package/dist/permissions/sight.js +76 -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 +31 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +36 -0
- package/dist/presence.js.map +1 -1
- 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 +6 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/seen.d.ts +58 -0
- package/dist/seen.d.ts.map +1 -0
- package/dist/seen.js +194 -0
- package/dist/seen.js.map +1 -0
- package/dist/store.d.ts +317 -8
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +720 -37
- 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 +83 -0
- package/dist/validate-graph.d.ts.map +1 -0
- package/dist/validate-graph.js +288 -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
package/dist/ops/log.d.ts
CHANGED
|
@@ -1,18 +1,131 @@
|
|
|
1
1
|
import { Graph } from "../graph/graph.js";
|
|
2
|
+
import type { GraphSnapshot } from "../graph/types.js";
|
|
2
3
|
import type { AnySchema } from "../schema/schema.js";
|
|
3
4
|
import type { Batch, Operation } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* A POINT THE LOG CAN BE FOLDED FROM (FR-27): the graph as it stood, and
|
|
7
|
+
* the seq of the first op that folds onto it.
|
|
8
|
+
*
|
|
9
|
+
* A log that spans a declaration change cannot be folded from empty under
|
|
10
|
+
* the new declaration, because the ops before the change wrote the old
|
|
11
|
+
* shape. So each declaration version begins an epoch: ship records one when
|
|
12
|
+
* a migration runs, with the migrated graph as its base, and one for the
|
|
13
|
+
* seed a store first opened on, which was never an operation. Verifying
|
|
14
|
+
* folds from the last epoch, and undo does not reach back across an epoch
|
|
15
|
+
* that changed the declaration.
|
|
16
|
+
*/
|
|
17
|
+
export interface Epoch {
|
|
18
|
+
/** The seq of the first op folded onto `base`; every op before it is history behind the base. */
|
|
19
|
+
readonly seq: number;
|
|
20
|
+
/** The graph at that point. */
|
|
21
|
+
readonly base: GraphSnapshot;
|
|
22
|
+
/** The declaration version the epoch begins, when one is known. */
|
|
23
|
+
readonly version?: number;
|
|
24
|
+
/**
|
|
25
|
+
* What changed to begin it, in a sentence ("migration 1→2: size words
|
|
26
|
+
* become bed counts"). Present when the declaration changed; undo does
|
|
27
|
+
* not cross an epoch that has one. A seed, or a store from before epochs
|
|
28
|
+
* adopting what it holds, begins an epoch without one.
|
|
29
|
+
*/
|
|
30
|
+
readonly change?: string;
|
|
31
|
+
/** When it began. */
|
|
32
|
+
readonly at?: string;
|
|
33
|
+
/**
|
|
34
|
+
* THE UNDO HORIZON (FR-23): this epoch is a checkpoint, and the ops
|
|
35
|
+
* before its seq were archived. A log restored with it begins at its seq,
|
|
36
|
+
* a normal open loads it and the ops after it and nothing older, and undo
|
|
37
|
+
* does not reach behind it. Absent on every other epoch.
|
|
38
|
+
*/
|
|
39
|
+
readonly horizon?: true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* WHAT A COMPACTION MOVED OUT OF THE LOG (FR-23): the ops before the
|
|
43
|
+
* horizon, and the epochs before it, oldest first. An adapter keeps them
|
|
44
|
+
* where a normal open does not load them (`loadArchive`), and a full export
|
|
45
|
+
* puts them back in front of the tail.
|
|
46
|
+
*/
|
|
47
|
+
export interface LogArchive {
|
|
48
|
+
readonly ops: readonly Operation[];
|
|
49
|
+
readonly epochs: readonly Epoch[];
|
|
50
|
+
}
|
|
4
51
|
/**
|
|
5
52
|
* The append-only log. Nothing here mutates or removes an entry: an undo is
|
|
6
53
|
* a new op carrying the inverse, so history is never destroyed and the log
|
|
7
54
|
* doubles as an audit trail of what an agent did on your behalf.
|
|
55
|
+
*
|
|
56
|
+
* A LOG BEGINS AT ITS HORIZON (FR-23). Its seqs are contiguous from there:
|
|
57
|
+
* from 0 for a whole log, from the checkpoint's seq for one compacted
|
|
58
|
+
* behind an undo horizon, whose older ops an adapter archived.
|
|
8
59
|
*/
|
|
9
60
|
export declare class OperationLog {
|
|
10
|
-
private
|
|
61
|
+
private ops;
|
|
62
|
+
private marks;
|
|
63
|
+
private start;
|
|
64
|
+
/**
|
|
65
|
+
* The seq the next op takes, which is how long the log is counting what
|
|
66
|
+
* a compaction archived (FR-23). The log holds `length - horizon` ops.
|
|
67
|
+
*/
|
|
11
68
|
get length(): number;
|
|
69
|
+
/**
|
|
70
|
+
* THE SEQ THE LOG BEGINS AT (FR-23): 0 for a whole log, the checkpoint's
|
|
71
|
+
* seq for one compacted behind an undo horizon. The ops before it are
|
|
72
|
+
* archived, not here.
|
|
73
|
+
*/
|
|
74
|
+
get horizon(): number;
|
|
75
|
+
/** The ops this log holds, oldest first: from its horizon on. */
|
|
12
76
|
all(): readonly Operation[];
|
|
77
|
+
/** The ops from `seq` on; from the horizon when `seq` is behind it. */
|
|
78
|
+
opsFrom(seq: number): readonly Operation[];
|
|
13
79
|
append(op: Operation): void;
|
|
14
|
-
/**
|
|
15
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Restores a log and its epochs from storage, checking the sequence is
|
|
82
|
+
* intact. A COMPACTED LOG (FR-23) begins at its horizon: the seq of the
|
|
83
|
+
* checkpoint among `epochs` (the last one marked `horizon`), or
|
|
84
|
+
* `options.horizon` for a log handed over without its base, as a client
|
|
85
|
+
* hydrating on a snapshot is. Its first op must carry that seq, and no
|
|
86
|
+
* epoch may be older than it. Without either, a log begins at 0.
|
|
87
|
+
*/
|
|
88
|
+
static from(ops: readonly Operation[], epochs?: readonly Epoch[], options?: {
|
|
89
|
+
readonly horizon?: number;
|
|
90
|
+
}): OperationLog;
|
|
91
|
+
/** The epochs this log can be folded from, oldest first. */
|
|
92
|
+
epochs(): readonly Epoch[];
|
|
93
|
+
/** The epoch the current graph folds from, if any was marked. */
|
|
94
|
+
lastEpoch(): Epoch | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Begins an epoch at `epoch.seq`, usually the log's current length: the
|
|
97
|
+
* next op folds onto `epoch.base`. Epochs are in order and none starts
|
|
98
|
+
* past the end of the log.
|
|
99
|
+
*/
|
|
100
|
+
markEpoch(epoch: Epoch): void;
|
|
101
|
+
/**
|
|
102
|
+
* ROLLS THE LOG BACK TO `length`, for ops that were only ever
|
|
103
|
+
* provisional: an optimistic client's pending tail, cut back before the
|
|
104
|
+
* server's ops land under it (`Store.rebase`). This is the one way an
|
|
105
|
+
* entry leaves the log, and it is not for history: ops another store has
|
|
106
|
+
* seen are undone by appending, never cut. Refuses to cut behind an epoch.
|
|
107
|
+
* Returns what was cut, oldest first.
|
|
108
|
+
*/
|
|
109
|
+
truncate(length: number): Operation[];
|
|
110
|
+
/**
|
|
111
|
+
* THE GRAPH AS IT STOOD AT `seq`, AS AN EPOCH TO FOLD FROM (FR-23): the
|
|
112
|
+
* base of the last epoch at or before it, with the ops up to it folded
|
|
113
|
+
* on. An epoch already at `seq` is that graph and is kept as it is,
|
|
114
|
+
* declaration change and all. Marked `horizon`, so `compact` can make it
|
|
115
|
+
* the undo horizon. `at` is when the last op before it was made.
|
|
116
|
+
*/
|
|
117
|
+
checkpointAt<S extends AnySchema>(schema: S, seq: number, options?: {
|
|
118
|
+
validate?: boolean;
|
|
119
|
+
}): Epoch;
|
|
120
|
+
/**
|
|
121
|
+
* MOVES THE UNDO HORIZON TO `checkpoint` (FR-23). The ops before its seq
|
|
122
|
+
* leave the log, with the epochs before it; the checkpoint becomes the
|
|
123
|
+
* first epoch, and the log begins at its seq. What left is returned,
|
|
124
|
+
* oldest first, for an adapter to archive: nothing here forgets history,
|
|
125
|
+
* it only stops carrying it. The graph is untouched, and still folds
|
|
126
|
+
* from the checkpoint with the ops after it.
|
|
127
|
+
*/
|
|
128
|
+
compact(checkpoint: Epoch): LogArchive;
|
|
16
129
|
get(id: string): Operation | undefined;
|
|
17
130
|
/** Ops that have not been inverted by a later op. */
|
|
18
131
|
live(): Operation[];
|
|
@@ -25,11 +138,39 @@ export declare class OperationLog {
|
|
|
25
138
|
undoneIds(): Set<string>;
|
|
26
139
|
opsInBatch(batchId: string): Operation[];
|
|
27
140
|
batches(): Batch[];
|
|
28
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* Rebuilds the graph by folding every op forward: from empty, or, given
|
|
143
|
+
* `from`, from that epoch's base with the ops from its seq on (FR-27),
|
|
144
|
+
* up to the op before seq `to` when that is given. A compacted log folds
|
|
145
|
+
* only from its checkpoint or an epoch after it (FR-23).
|
|
146
|
+
*
|
|
147
|
+
* Each op lands as it landed when it was made: a write is judged as a
|
|
148
|
+
* write (a default filled in on the way in is filled in again), an undo
|
|
149
|
+
* puts back what was there. An op an older declaration accepted and this
|
|
150
|
+
* one does not is HELD AS WRITTEN rather than refusing the whole history
|
|
151
|
+
* (FR-28) — `validateGraph` says what no longer fits. Only an op that
|
|
152
|
+
* cannot apply at all (a patch to a record that is not there) fails.
|
|
153
|
+
*/
|
|
29
154
|
fold<S extends AnySchema>(schema: S, options?: {
|
|
30
155
|
validate?: boolean;
|
|
156
|
+
from?: Epoch;
|
|
157
|
+
to?: number;
|
|
31
158
|
}): Graph<S>;
|
|
32
159
|
/** Serializable form for a persistence adapter. */
|
|
33
160
|
toJSON(): Operation[];
|
|
34
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* What `checkUndo` reads of a log: its ops, which of them are undone, and
|
|
164
|
+
* its epochs. An `OperationLog` is one; so is a log as one seat may see it.
|
|
165
|
+
*/
|
|
166
|
+
export interface LogReading {
|
|
167
|
+
/** The ops it holds: from the undo horizon on, when the log was compacted (FR-23). */
|
|
168
|
+
all(): readonly Operation[];
|
|
169
|
+
undoneIds(): Set<string>;
|
|
170
|
+
epochs(): readonly Epoch[];
|
|
171
|
+
}
|
|
172
|
+
/** The ops of a list that a live op undoes (`OperationLog.undoneIds`). */
|
|
173
|
+
export declare function undoneIn(ops: readonly Operation[]): Set<string>;
|
|
174
|
+
/** Ops grouped into the gestures they were made in, in the order each began. */
|
|
175
|
+
export declare function batchesOf(ops: readonly Operation[], undone: ReadonlySet<string>): Batch[];
|
|
35
176
|
//# sourceMappingURL=log.d.ts.map
|
package/dist/ops/log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"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"}
|
package/dist/ops/log.js
CHANGED
|
@@ -1,30 +1,162 @@
|
|
|
1
1
|
import { Graph } from "../graph/graph.js";
|
|
2
|
+
const beginsPastZero = (op) => `Op "${op.id}" has seq ${op.seq}, so the log begins at seq ${op.seq}: a log that begins past 0 begins at its undo horizon, and none was given (a checkpoint epoch, or { horizon })`;
|
|
2
3
|
/**
|
|
3
4
|
* The append-only log. Nothing here mutates or removes an entry: an undo is
|
|
4
5
|
* a new op carrying the inverse, so history is never destroyed and the log
|
|
5
6
|
* doubles as an audit trail of what an agent did on your behalf.
|
|
7
|
+
*
|
|
8
|
+
* A LOG BEGINS AT ITS HORIZON (FR-23). Its seqs are contiguous from there:
|
|
9
|
+
* from 0 for a whole log, from the checkpoint's seq for one compacted
|
|
10
|
+
* behind an undo horizon, whose older ops an adapter archived.
|
|
6
11
|
*/
|
|
7
12
|
export class OperationLog {
|
|
8
13
|
ops = [];
|
|
14
|
+
marks = [];
|
|
15
|
+
start = 0;
|
|
16
|
+
/**
|
|
17
|
+
* The seq the next op takes, which is how long the log is counting what
|
|
18
|
+
* a compaction archived (FR-23). The log holds `length - horizon` ops.
|
|
19
|
+
*/
|
|
9
20
|
get length() {
|
|
10
|
-
return this.ops.length;
|
|
21
|
+
return this.start + this.ops.length;
|
|
11
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* THE SEQ THE LOG BEGINS AT (FR-23): 0 for a whole log, the checkpoint's
|
|
25
|
+
* seq for one compacted behind an undo horizon. The ops before it are
|
|
26
|
+
* archived, not here.
|
|
27
|
+
*/
|
|
28
|
+
get horizon() {
|
|
29
|
+
return this.start;
|
|
30
|
+
}
|
|
31
|
+
/** The ops this log holds, oldest first: from its horizon on. */
|
|
12
32
|
all() {
|
|
13
33
|
return this.ops;
|
|
14
34
|
}
|
|
35
|
+
/** The ops from `seq` on; from the horizon when `seq` is behind it. */
|
|
36
|
+
opsFrom(seq) {
|
|
37
|
+
return this.ops.slice(Math.max(0, seq - this.start));
|
|
38
|
+
}
|
|
15
39
|
append(op) {
|
|
16
|
-
if (op.seq !== this.
|
|
17
|
-
throw new Error(`Op "${op.id}" has seq ${op.seq} but the log is ${this.
|
|
40
|
+
if (op.seq !== this.length) {
|
|
41
|
+
throw new Error(this.length === 0 && op.seq > 0 ? beginsPastZero(op) : `Op "${op.id}" has seq ${op.seq} but the log is ${this.length} long`);
|
|
18
42
|
}
|
|
19
43
|
this.ops.push(op);
|
|
20
44
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Restores a log and its epochs from storage, checking the sequence is
|
|
47
|
+
* intact. A COMPACTED LOG (FR-23) begins at its horizon: the seq of the
|
|
48
|
+
* checkpoint among `epochs` (the last one marked `horizon`), or
|
|
49
|
+
* `options.horizon` for a log handed over without its base, as a client
|
|
50
|
+
* hydrating on a snapshot is. Its first op must carry that seq, and no
|
|
51
|
+
* epoch may be older than it. Without either, a log begins at 0.
|
|
52
|
+
*/
|
|
53
|
+
static from(ops, epochs = [], options = {}) {
|
|
23
54
|
const log = new OperationLog();
|
|
55
|
+
const checkpoint = [...epochs].reverse().find((epoch) => epoch.horizon);
|
|
56
|
+
const horizon = options.horizon ?? checkpoint?.seq ?? 0;
|
|
57
|
+
if (!Number.isInteger(horizon) || horizon < 0)
|
|
58
|
+
throw new Error(`A log cannot begin at seq ${horizon}`);
|
|
59
|
+
if (checkpoint && options.horizon !== undefined && checkpoint.seq !== options.horizon) {
|
|
60
|
+
throw new Error(`A log said to begin at seq ${options.horizon} has its checkpoint at seq ${checkpoint.seq}`);
|
|
61
|
+
}
|
|
62
|
+
const first = ops[0];
|
|
63
|
+
if (first && horizon > 0 && first.seq !== horizon) {
|
|
64
|
+
throw new Error(`A log compacted at seq ${horizon} begins with op "${first.id}" at seq ${first.seq}`);
|
|
65
|
+
}
|
|
66
|
+
log.start = horizon;
|
|
24
67
|
for (const op of ops)
|
|
25
68
|
log.append(op);
|
|
69
|
+
for (const epoch of epochs)
|
|
70
|
+
log.markEpoch(epoch);
|
|
26
71
|
return log;
|
|
27
72
|
}
|
|
73
|
+
/** The epochs this log can be folded from, oldest first. */
|
|
74
|
+
epochs() {
|
|
75
|
+
return this.marks;
|
|
76
|
+
}
|
|
77
|
+
/** The epoch the current graph folds from, if any was marked. */
|
|
78
|
+
lastEpoch() {
|
|
79
|
+
return this.marks.at(-1);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Begins an epoch at `epoch.seq`, usually the log's current length: the
|
|
83
|
+
* next op folds onto `epoch.base`. Epochs are in order and none starts
|
|
84
|
+
* past the end of the log.
|
|
85
|
+
*/
|
|
86
|
+
markEpoch(epoch) {
|
|
87
|
+
if (!Number.isInteger(epoch.seq) || epoch.seq < 0 || epoch.seq > this.length) {
|
|
88
|
+
throw new Error(`An epoch at seq ${epoch.seq} starts past the end of a log ${this.length} long`);
|
|
89
|
+
}
|
|
90
|
+
if (epoch.seq < this.start) {
|
|
91
|
+
throw new Error(`An epoch at seq ${epoch.seq} is behind the horizon at seq ${this.start}: it went to the archive with the ops before it`);
|
|
92
|
+
}
|
|
93
|
+
const last = this.lastEpoch();
|
|
94
|
+
if (last && epoch.seq < last.seq) {
|
|
95
|
+
throw new Error(`An epoch at seq ${epoch.seq} comes before the last one, at seq ${last.seq}`);
|
|
96
|
+
}
|
|
97
|
+
this.marks.push(epoch);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* ROLLS THE LOG BACK TO `length`, for ops that were only ever
|
|
101
|
+
* provisional: an optimistic client's pending tail, cut back before the
|
|
102
|
+
* server's ops land under it (`Store.rebase`). This is the one way an
|
|
103
|
+
* entry leaves the log, and it is not for history: ops another store has
|
|
104
|
+
* seen are undone by appending, never cut. Refuses to cut behind an epoch.
|
|
105
|
+
* Returns what was cut, oldest first.
|
|
106
|
+
*/
|
|
107
|
+
truncate(length) {
|
|
108
|
+
if (!Number.isInteger(length) || length < this.start || length > this.length) {
|
|
109
|
+
throw new Error(`Cannot cut a log ${this.length} long back to ${length}`);
|
|
110
|
+
}
|
|
111
|
+
const last = this.lastEpoch();
|
|
112
|
+
if (last && last.seq > length) {
|
|
113
|
+
throw new Error(`Cannot cut the log back to ${length}: an epoch begins at seq ${last.seq}`);
|
|
114
|
+
}
|
|
115
|
+
return this.ops.splice(length - this.start);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* THE GRAPH AS IT STOOD AT `seq`, AS AN EPOCH TO FOLD FROM (FR-23): the
|
|
119
|
+
* base of the last epoch at or before it, with the ops up to it folded
|
|
120
|
+
* on. An epoch already at `seq` is that graph and is kept as it is,
|
|
121
|
+
* declaration change and all. Marked `horizon`, so `compact` can make it
|
|
122
|
+
* the undo horizon. `at` is when the last op before it was made.
|
|
123
|
+
*/
|
|
124
|
+
checkpointAt(schema, seq, options = {}) {
|
|
125
|
+
if (!Number.isInteger(seq) || seq < this.start || seq > this.length) {
|
|
126
|
+
throw new Error(`No checkpoint at seq ${seq}: this log holds seqs ${this.start} to ${this.length}`);
|
|
127
|
+
}
|
|
128
|
+
const from = [...this.marks].reverse().find((epoch) => epoch.seq <= seq);
|
|
129
|
+
if (from?.seq === seq)
|
|
130
|
+
return { ...from, horizon: true };
|
|
131
|
+
const base = this.fold(schema, { ...options, ...(from ? { from } : {}), to: seq }).snapshot();
|
|
132
|
+
const at = this.ops[seq - 1 - this.start]?.at ?? from?.at;
|
|
133
|
+
return {
|
|
134
|
+
seq,
|
|
135
|
+
base,
|
|
136
|
+
...(from?.version !== undefined ? { version: from.version } : {}),
|
|
137
|
+
...(at !== undefined ? { at } : {}),
|
|
138
|
+
horizon: true,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* MOVES THE UNDO HORIZON TO `checkpoint` (FR-23). The ops before its seq
|
|
143
|
+
* leave the log, with the epochs before it; the checkpoint becomes the
|
|
144
|
+
* first epoch, and the log begins at its seq. What left is returned,
|
|
145
|
+
* oldest first, for an adapter to archive: nothing here forgets history,
|
|
146
|
+
* it only stops carrying it. The graph is untouched, and still folds
|
|
147
|
+
* from the checkpoint with the ops after it.
|
|
148
|
+
*/
|
|
149
|
+
compact(checkpoint) {
|
|
150
|
+
if (!Number.isInteger(checkpoint.seq) || checkpoint.seq < this.start || checkpoint.seq > this.length) {
|
|
151
|
+
throw new Error(`Cannot compact at seq ${checkpoint.seq}: this log holds seqs ${this.start} to ${this.length}`);
|
|
152
|
+
}
|
|
153
|
+
const ops = this.ops.slice(0, checkpoint.seq - this.start);
|
|
154
|
+
const epochs = this.marks.filter((epoch) => epoch.seq < checkpoint.seq);
|
|
155
|
+
this.ops = this.ops.slice(checkpoint.seq - this.start);
|
|
156
|
+
this.marks = [{ ...checkpoint, horizon: true }, ...this.marks.filter((epoch) => epoch.seq > checkpoint.seq)];
|
|
157
|
+
this.start = checkpoint.seq;
|
|
158
|
+
return { ops, epochs };
|
|
159
|
+
}
|
|
28
160
|
get(id) {
|
|
29
161
|
return this.ops.find((op) => op.id === id);
|
|
30
162
|
}
|
|
@@ -40,58 +172,48 @@ export class OperationLog {
|
|
|
40
172
|
* from the end of the log backwards terminates in one pass.
|
|
41
173
|
*/
|
|
42
174
|
undoneIds() {
|
|
43
|
-
|
|
44
|
-
for (const op of this.ops) {
|
|
45
|
-
if (!op.undoes)
|
|
46
|
-
continue;
|
|
47
|
-
const list = undoers.get(op.undoes);
|
|
48
|
-
if (list)
|
|
49
|
-
list.push(op.id);
|
|
50
|
-
else
|
|
51
|
-
undoers.set(op.undoes, [op.id]);
|
|
52
|
-
}
|
|
53
|
-
const live = new Map();
|
|
54
|
-
for (let i = this.ops.length - 1; i >= 0; i--) {
|
|
55
|
-
const op = this.ops[i];
|
|
56
|
-
const mine = undoers.get(op.id) ?? [];
|
|
57
|
-
live.set(op.id, !mine.some((id) => live.get(id) === true));
|
|
58
|
-
}
|
|
59
|
-
return new Set(this.ops.filter((op) => live.get(op.id) === false).map((op) => op.id));
|
|
175
|
+
return undoneIn(this.ops);
|
|
60
176
|
}
|
|
61
177
|
opsInBatch(batchId) {
|
|
62
178
|
return this.ops.filter((op) => op.batch === batchId);
|
|
63
179
|
}
|
|
64
180
|
batches() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
181
|
+
return batchesOf(this.ops, this.undoneIds());
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Rebuilds the graph by folding every op forward: from empty, or, given
|
|
185
|
+
* `from`, from that epoch's base with the ops from its seq on (FR-27),
|
|
186
|
+
* up to the op before seq `to` when that is given. A compacted log folds
|
|
187
|
+
* only from its checkpoint or an epoch after it (FR-23).
|
|
188
|
+
*
|
|
189
|
+
* Each op lands as it landed when it was made: a write is judged as a
|
|
190
|
+
* write (a default filled in on the way in is filled in again), an undo
|
|
191
|
+
* puts back what was there. An op an older declaration accepted and this
|
|
192
|
+
* one does not is HELD AS WRITTEN rather than refusing the whole history
|
|
193
|
+
* (FR-28) — `validateGraph` says what no longer fits. Only an op that
|
|
194
|
+
* cannot apply at all (a patch to a record that is not there) fails.
|
|
195
|
+
*/
|
|
196
|
+
fold(schema, options = {}) {
|
|
197
|
+
const from = options.from?.seq ?? 0;
|
|
198
|
+
if (from < this.start) {
|
|
199
|
+
throw new Error(options.from
|
|
200
|
+
? `An epoch at seq ${from} is behind the horizon at seq ${this.start}: fold from the checkpoint`
|
|
201
|
+
: `A log compacted at seq ${this.start} does not fold from empty: fold from its checkpoint`);
|
|
76
202
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
fold(schema, options) {
|
|
92
|
-
const graph = new Graph(schema, options);
|
|
93
|
-
for (const op of this.ops) {
|
|
94
|
-
graph.applyPrimitives(op.primitives);
|
|
203
|
+
const base = (options.from?.base ?? { nodes: [], edges: [] });
|
|
204
|
+
const graph = Graph.from(schema, base, options.validate !== undefined ? { validate: options.validate } : {});
|
|
205
|
+
const to = options.to ?? this.length;
|
|
206
|
+
for (const op of this.ops.slice(from - this.start, Math.max(0, to - this.start))) {
|
|
207
|
+
if (op.undoes !== undefined) {
|
|
208
|
+
graph.applyPrimitives(op.primitives, { restoring: true });
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
graph.applyPrimitives(op.primitives);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
graph.applyPrimitives(op.primitives, { restoring: true });
|
|
216
|
+
}
|
|
95
217
|
}
|
|
96
218
|
return graph;
|
|
97
219
|
}
|
|
@@ -100,4 +222,51 @@ export class OperationLog {
|
|
|
100
222
|
return [...this.ops];
|
|
101
223
|
}
|
|
102
224
|
}
|
|
225
|
+
/** The ops of a list that a live op undoes (`OperationLog.undoneIds`). */
|
|
226
|
+
export function undoneIn(ops) {
|
|
227
|
+
const undoers = new Map();
|
|
228
|
+
for (const op of ops) {
|
|
229
|
+
if (!op.undoes)
|
|
230
|
+
continue;
|
|
231
|
+
const list = undoers.get(op.undoes);
|
|
232
|
+
if (list)
|
|
233
|
+
list.push(op.id);
|
|
234
|
+
else
|
|
235
|
+
undoers.set(op.undoes, [op.id]);
|
|
236
|
+
}
|
|
237
|
+
const live = new Map();
|
|
238
|
+
for (let i = ops.length - 1; i >= 0; i--) {
|
|
239
|
+
const op = ops[i];
|
|
240
|
+
const mine = undoers.get(op.id) ?? [];
|
|
241
|
+
live.set(op.id, !mine.some((id) => live.get(id) === true));
|
|
242
|
+
}
|
|
243
|
+
return new Set(ops.filter((op) => live.get(op.id) === false).map((op) => op.id));
|
|
244
|
+
}
|
|
245
|
+
/** Ops grouped into the gestures they were made in, in the order each began. */
|
|
246
|
+
export function batchesOf(ops, undone) {
|
|
247
|
+
const order = [];
|
|
248
|
+
const grouped = new Map();
|
|
249
|
+
for (const op of ops) {
|
|
250
|
+
const list = grouped.get(op.batch);
|
|
251
|
+
if (list)
|
|
252
|
+
list.push(op);
|
|
253
|
+
else {
|
|
254
|
+
grouped.set(op.batch, [op]);
|
|
255
|
+
order.push(op.batch);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return order.map((id) => {
|
|
259
|
+
const ops = grouped.get(id) ?? [];
|
|
260
|
+
const first = ops[0];
|
|
261
|
+
return {
|
|
262
|
+
id,
|
|
263
|
+
author: first.author,
|
|
264
|
+
// What the gesture was for, when its caller said; else its first op's own sentence.
|
|
265
|
+
intent: first.batchIntent ?? first.intent,
|
|
266
|
+
at: first.at,
|
|
267
|
+
ops,
|
|
268
|
+
undone: ops.every((op) => undone.has(op.id)),
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
}
|
|
103
272
|
//# sourceMappingURL=log.js.map
|
package/dist/ops/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Primitive } from "../graph/primitives.js";
|
|
2
|
+
import type { Operation } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* WHICH OP LAST WROTE EACH FIELD (FR-05) — read off the log, never stored.
|
|
5
|
+
*
|
|
6
|
+
* A stale write is one made against a value somebody has changed since:
|
|
7
|
+
* two people open one record, both change its status, and whoever sends
|
|
8
|
+
* second used to win without knowing the first had spoken. To say so, a
|
|
9
|
+
* call carries the revision of each field it changes as its sender last
|
|
10
|
+
* saw it, and the store compares that with the field's revision now.
|
|
11
|
+
*
|
|
12
|
+
* A field's revision is the `seq` of the op that last wrote it: an op that
|
|
13
|
+
* added its record, or one that patched it. It is DERIVED from the log
|
|
14
|
+
* rather than kept beside it, so no stored format changes and every store,
|
|
15
|
+
* every client and every host that folds the same log agrees on it without
|
|
16
|
+
* being told. A field no op in the log has written (a seeded one, or one
|
|
17
|
+
* written before the log's first op) is at `NEVER_WRITTEN`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const NEVER_WRITTEN = -1;
|
|
20
|
+
/** What a call says it saw: one field of one record, at the revision its sender last read. */
|
|
21
|
+
export interface FieldRevision {
|
|
22
|
+
readonly node: string;
|
|
23
|
+
readonly field: string;
|
|
24
|
+
readonly rev: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A FIELD THAT MOVED WHILE SOMEBODY WAS EDITING IT: the stale write, as
|
|
28
|
+
* the store refuses it. `theirs` is the value now, `yours` the one the call
|
|
29
|
+
* would have written, `by` who wrote theirs and `rev` the op that did.
|
|
30
|
+
* Named as Graview Cloud's room names it, so a host's interim reads the same.
|
|
31
|
+
*/
|
|
32
|
+
export interface FieldConflict {
|
|
33
|
+
readonly node: string;
|
|
34
|
+
readonly field: string;
|
|
35
|
+
readonly theirs: unknown;
|
|
36
|
+
readonly yours: unknown;
|
|
37
|
+
/** Who wrote theirs, by name where the log says one: "Sam", "Someone". */
|
|
38
|
+
readonly by: string;
|
|
39
|
+
/** The revision the field is at now. */
|
|
40
|
+
readonly rev: number;
|
|
41
|
+
/** The revision the call said it saw. */
|
|
42
|
+
readonly saw: number;
|
|
43
|
+
}
|
|
44
|
+
/** The fields one primitive writes, by record. */
|
|
45
|
+
export declare function fieldsWritten(primitive: Primitive): readonly (readonly [string, string])[];
|
|
46
|
+
/**
|
|
47
|
+
* The revision of every field a log has written, kept current as ops land.
|
|
48
|
+
* A revision only moves forward: an op noted twice, or out of order, leaves
|
|
49
|
+
* a later one standing.
|
|
50
|
+
*/
|
|
51
|
+
export declare class FieldRevisions {
|
|
52
|
+
private readonly revs;
|
|
53
|
+
/** Revisions read from a whole log (or the part of one a seat may see). */
|
|
54
|
+
static of(ops: readonly Operation[]): FieldRevisions;
|
|
55
|
+
/** Takes in ops as they land, by the seq each carries. */
|
|
56
|
+
note(ops: readonly Operation[]): void;
|
|
57
|
+
/** The seq of the op that last wrote this field, or `NEVER_WRITTEN`. */
|
|
58
|
+
of(node: string, field: string): number;
|
|
59
|
+
/** The base a call made of these ops would carry: each field they patch on a record they did not add, at its revision here. */
|
|
60
|
+
baseFor(ops: readonly Operation[], skip?: ReadonlySet<string>): FieldRevision[];
|
|
61
|
+
/** The base entries that no longer hold: each field written since its sender read it. */
|
|
62
|
+
stale(base: readonly FieldRevision[]): FieldRevision[];
|
|
63
|
+
}
|
|
64
|
+
/** Every record and every `record\0field` these ops write: what a later call need not claim to have seen. */
|
|
65
|
+
export declare function writtenBy(ops: readonly Operation[]): Set<string>;
|
|
66
|
+
//# sourceMappingURL=revisions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revisions.d.ts","sourceRoot":"","sources":["../../src/ops/revisions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,8FAA8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAID,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAQ1F;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAElD,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,cAAc;IAMpD,0DAA0D;IAC1D,IAAI,CAAC,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI;IAWrC,wEAAwE;IACxE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAIvC,+HAA+H;IAC/H,OAAO,CAAC,GAAG,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,aAAa,EAAE;IAiB1F,yFAAyF;IACzF,KAAK,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE;CAGvD;AAED,6GAA6G;AAC7G,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAShE"}
|