@hydranium/protocol 1.0.0-next.187 → 1.0.0-next.189
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/lib/client/data-connection.js +2 -2
- package/lib/client/data-connection.js.map +1 -1
- package/lib/client/data-port.d.ts +1 -1
- package/lib/client/data-session.d.ts +39 -21
- package/lib/client/data-session.d.ts.map +1 -1
- package/lib/client/data-session.js +69 -43
- package/lib/client/data-session.js.map +1 -1
- package/lib/data/data-protocol-methods.d.ts.map +1 -1
- package/lib/data/data-protocol-methods.js.map +1 -1
- package/lib/data/data-server-protocol.d.ts +10 -9
- package/lib/data/data-server-protocol.d.ts.map +1 -1
- package/lib/data/events.d.ts +11 -5
- package/lib/data/events.d.ts.map +1 -1
- package/lib/data/requests.d.ts +4 -4
- package/lib/data/requests.d.ts.map +1 -1
- package/lib/errors.d.ts +31 -25
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +58 -23
- package/lib/errors.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/messages/index.d.ts +2 -2
- package/lib/messages/index.d.ts.map +1 -1
- package/lib/messages/index.js +3 -2
- package/lib/messages/index.js.map +1 -1
- package/lib/model-service/base-version.d.ts +64 -0
- package/lib/model-service/base-version.d.ts.map +1 -0
- package/lib/model-service/{based-on.js → base-version.js} +21 -15
- package/lib/model-service/base-version.js.map +1 -0
- package/lib/model-service/index.d.ts +1 -1
- package/lib/model-service/index.d.ts.map +1 -1
- package/lib/model-service/index.js +2 -2
- package/lib/model-service/index.js.map +1 -1
- package/lib/model-service/reference-candidate.d.ts +5 -3
- package/lib/model-service/reference-candidate.d.ts.map +1 -1
- package/lib/patch-merge.d.ts +11 -9
- package/lib/patch-merge.d.ts.map +1 -1
- package/lib/patch-merge.js +2 -2
- package/lib/patch-merge.js.map +1 -1
- package/lib/reconcile-write.d.ts +65 -0
- package/lib/reconcile-write.d.ts.map +1 -0
- package/lib/reconcile-write.js +67 -0
- package/lib/reconcile-write.js.map +1 -0
- package/lib/rpc/create-rpc-proxy.d.ts +3 -0
- package/lib/rpc/create-rpc-proxy.d.ts.map +1 -1
- package/lib/rpc/create-rpc-proxy.js +6 -1
- package/lib/rpc/create-rpc-proxy.js.map +1 -1
- package/lib/transfer-document.d.ts +59 -61
- package/lib/transfer-document.d.ts.map +1 -1
- package/lib/transfer-document.js +15 -20
- package/lib/transfer-document.js.map +1 -1
- package/lib/util.d.ts +1 -1
- package/lib/util.js +1 -1
- package/package.json +1 -1
- package/src/client/data-connection.ts +2 -2
- package/src/client/data-port.ts +1 -1
- package/src/client/data-session.ts +89 -51
- package/src/data/data-protocol-methods.ts +1 -1
- package/src/data/data-server-protocol.ts +12 -9
- package/src/data/events.ts +11 -5
- package/src/data/requests.ts +4 -4
- package/src/errors.ts +71 -31
- package/src/index.ts +1 -0
- package/src/messages/index.ts +2 -2
- package/src/model-service/base-version.ts +72 -0
- package/src/model-service/index.ts +2 -2
- package/src/model-service/reference-candidate.ts +5 -3
- package/src/patch-merge.ts +11 -9
- package/src/reconcile-write.ts +124 -0
- package/src/rpc/create-rpc-proxy.ts +6 -1
- package/src/transfer-document.ts +70 -65
- package/src/util.ts +1 -1
- package/lib/model-service/based-on.d.ts +0 -57
- package/lib/model-service/based-on.d.ts.map +0 -1
- package/lib/model-service/based-on.js.map +0 -1
- package/src/model-service/based-on.ts +0 -63
package/src/transfer-document.ts
CHANGED
|
@@ -9,71 +9,80 @@
|
|
|
9
9
|
|
|
10
10
|
import type { TransferDiagnostic } from './transfer-diagnostic';
|
|
11
11
|
import type { TransferElement } from './transfer-element';
|
|
12
|
-
import {
|
|
12
|
+
import { asModelVersion, type ModelVersion, type TextVersion } from './model-service/base-version';
|
|
13
|
+
|
|
14
|
+
/** The model a data server built for a document, encoded for the wire. */
|
|
15
|
+
export interface TransferModelSnapshot<TRoot extends TransferElement, TDiagnostic = TransferDiagnostic> {
|
|
16
|
+
root: TRoot;
|
|
17
|
+
/** Absent until the document is validated; `[]` once it is and nothing was found. */
|
|
18
|
+
diagnostics?: TDiagnostic[];
|
|
19
|
+
/**
|
|
20
|
+
* The version of the text `root` was parsed from. A caller that mutates the
|
|
21
|
+
* model sends this back as the `baseVersion` of its write, and the server
|
|
22
|
+
* rejects the write with `ConflictError` once its text has moved past it.
|
|
23
|
+
*/
|
|
24
|
+
version: ModelVersion;
|
|
25
|
+
/**
|
|
26
|
+
* The data server's fingerprint of `root` and `diagnostics`, or under its
|
|
27
|
+
* `'text-diagnostics'` strategy of the text `root` was parsed from and
|
|
28
|
+
* `diagnostics`.
|
|
29
|
+
* Independent of `version`; an equal hash also means equally validated.
|
|
30
|
+
*/
|
|
31
|
+
hash: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The text a data server held for a document when it sent it. */
|
|
35
|
+
export interface TextState {
|
|
36
|
+
/**
|
|
37
|
+
* The server's version of that text. A `TransferModelSnapshot.version` below it
|
|
38
|
+
* means the model was parsed from older text, and an update at this version
|
|
39
|
+
* or a later one follows.
|
|
40
|
+
*/
|
|
41
|
+
version: TextVersion;
|
|
42
|
+
/**
|
|
43
|
+
* What `textHash` makes of the text alone: equal texts hash equal whatever
|
|
44
|
+
* their version or dirty state, across a revert or a server restart that
|
|
45
|
+
* numbers versions afresh.
|
|
46
|
+
*/
|
|
47
|
+
hash: string;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the text differs from the file, as the server last knew the file.
|
|
50
|
+
* A later change arrives as `onDocumentDirtyChanged` to a client watching
|
|
51
|
+
* the document.
|
|
52
|
+
*/
|
|
53
|
+
dirty: boolean;
|
|
54
|
+
}
|
|
13
55
|
|
|
14
56
|
/**
|
|
15
57
|
* Wire envelope exchanged between the model-server's data-server head and
|
|
16
|
-
* its clients
|
|
17
|
-
*
|
|
58
|
+
* its clients: the server's model of a document and the text it holds for it,
|
|
59
|
+
* each absent where the server has none.
|
|
18
60
|
*
|
|
19
61
|
* The constraint `TTransfer extends TransferElement` pins the type system
|
|
20
62
|
* to the wire data shape (no `$container` cycles, references as strings;
|
|
21
|
-
* see {@link TransferElement}).
|
|
22
|
-
* `AstDocument<TAst extends AstNode, TDiagnostic>` in
|
|
23
|
-
* `@hydranium/core` — same structural shape, different generic
|
|
24
|
-
* constraint, used at the AST layer before the `TransferEncoder`
|
|
25
|
-
* translation produces a {@link TransferDocument}.
|
|
63
|
+
* see {@link TransferElement}).
|
|
26
64
|
*/
|
|
27
65
|
export interface TransferDocument<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic> {
|
|
28
66
|
uri: string;
|
|
29
67
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* the server rejects a stale-based update with `ConflictError`.
|
|
34
|
-
*
|
|
35
|
-
* See `@hydranium/protocol#errors` for the conflict-detection contract.
|
|
36
|
-
*/
|
|
37
|
-
version: SnapshotVersion;
|
|
38
|
-
/**
|
|
39
|
-
* Absent when the document does not exist — the server answers an unknown URI
|
|
40
|
-
* with a shaped envelope rather than an error, so absence is an ordinary
|
|
41
|
-
* branch and not a catch. Declared required it reads as a guarantee, and
|
|
42
|
-
* every `root.x` compiles into a throw.
|
|
43
|
-
*/
|
|
44
|
-
root?: TTransfer;
|
|
45
|
-
diagnostics: TDiagnostic[];
|
|
46
|
-
/**
|
|
47
|
-
* Whether the server holds text for this document that its file does not,
|
|
48
|
-
* as the server last knew the file: set on every document a data server
|
|
49
|
-
* answers or sends that the server holds, and absent otherwise. A change
|
|
50
|
-
* after this snapshot arrives as `onDocumentDirtyChanged` to a client
|
|
51
|
-
* watching the document.
|
|
68
|
+
* Absent when the document does not exist: the server answers an unknown
|
|
69
|
+
* URI with a shaped envelope rather than an error, so absence is an
|
|
70
|
+
* ordinary branch and not a catch.
|
|
52
71
|
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
* when it sends it: set on every document a data server answers or sends
|
|
57
|
-
* that the server holds, and absent otherwise. Equal texts hash equal,
|
|
58
|
-
* whatever the version, so a client compares the text two snapshots hold,
|
|
59
|
-
* across a revert or a server restart that numbers versions afresh.
|
|
60
|
-
*
|
|
61
|
-
* Of the text alone. The data server's de-duplication fingerprint hashes the
|
|
62
|
-
* text or the transfer root together with the diagnostics, and changes with
|
|
63
|
-
* a diagnostic where this does not.
|
|
64
|
-
*/
|
|
65
|
-
textHash?: string;
|
|
72
|
+
model?: TransferModelSnapshot<TTransfer, TDiagnostic>;
|
|
73
|
+
/** Absent when the server holds no text for the document. */
|
|
74
|
+
text?: TextState;
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
/**
|
|
69
|
-
* A {@link TransferDocument} the server actually had, so `
|
|
78
|
+
* A {@link TransferDocument} the server actually had, so `model` is present.
|
|
70
79
|
* Narrowed to by {@link TransferDocument.isLoaded} / {@link TransferDocument.assertLoaded}.
|
|
71
80
|
*/
|
|
72
81
|
export type LoadedTransferDocument<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic> = TransferDocument<
|
|
73
82
|
TTransfer,
|
|
74
83
|
TDiagnostic
|
|
75
84
|
> & {
|
|
76
|
-
|
|
85
|
+
model: TransferModelSnapshot<TTransfer, TDiagnostic>;
|
|
77
86
|
};
|
|
78
87
|
|
|
79
88
|
export namespace TransferDocument {
|
|
@@ -84,13 +93,13 @@ export namespace TransferDocument {
|
|
|
84
93
|
export function isLoaded<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(
|
|
85
94
|
document: TransferDocument<TTransfer, TDiagnostic>
|
|
86
95
|
): document is LoadedTransferDocument<TTransfer, TDiagnostic> {
|
|
87
|
-
return document.
|
|
96
|
+
return document.model !== undefined;
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
/**
|
|
91
|
-
* The same document with `
|
|
100
|
+
* The same document with `model` no longer optional, or a throw. For call
|
|
92
101
|
* sites where absence is a bug rather than a branch; the whole envelope is
|
|
93
|
-
* returned because a caller needing `
|
|
102
|
+
* returned because a caller needing `model` usually needs `uri` or `text`
|
|
94
103
|
* with it.
|
|
95
104
|
*/
|
|
96
105
|
export function assertLoaded<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(
|
|
@@ -102,33 +111,29 @@ export namespace TransferDocument {
|
|
|
102
111
|
return document;
|
|
103
112
|
}
|
|
104
113
|
|
|
105
|
-
/**
|
|
106
|
-
* The envelope for a document the server does not have — `root` absent, and
|
|
107
|
-
* the version a read of a URI the store never saw reports.
|
|
108
|
-
*
|
|
109
|
-
* Exists so the absent branch is built the same way the present one is: both
|
|
110
|
-
* doors mark the version as coming from a read, and neither asks a caller to
|
|
111
|
-
* do it.
|
|
112
|
-
*/
|
|
114
|
+
/** The envelope for a document the server does not have. */
|
|
113
115
|
export function absent<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(
|
|
114
|
-
uri: string
|
|
115
|
-
diagnostics: TDiagnostic[] = []
|
|
116
|
+
uri: string
|
|
116
117
|
): TransferDocument<TTransfer, TDiagnostic> {
|
|
117
|
-
return { uri
|
|
118
|
+
return { uri };
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
/**
|
|
121
|
-
* Construct a {@link TransferDocument} envelope
|
|
122
|
-
*
|
|
123
|
-
* "no diagnostics yet" code paths don't need to repeat the empty array
|
|
124
|
-
* at every call site.
|
|
122
|
+
* Construct a {@link TransferDocument} envelope with a model, its version
|
|
123
|
+
* marked as coming from a read. `diagnostics` absent means not validated.
|
|
125
124
|
*/
|
|
126
125
|
export function create<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(
|
|
127
126
|
uri: string,
|
|
128
127
|
version: number,
|
|
129
128
|
root: TTransfer,
|
|
130
|
-
|
|
129
|
+
hash: string,
|
|
130
|
+
diagnostics?: TDiagnostic[],
|
|
131
|
+
text?: TextState
|
|
131
132
|
): TransferDocument<TTransfer, TDiagnostic> {
|
|
132
|
-
return {
|
|
133
|
+
return {
|
|
134
|
+
uri,
|
|
135
|
+
model: { root, version: asModelVersion(version), hash, ...(diagnostics === undefined ? {} : { diagnostics }) },
|
|
136
|
+
...(text === undefined ? {} : { text })
|
|
137
|
+
};
|
|
133
138
|
}
|
|
134
139
|
}
|
package/src/util.ts
CHANGED
|
@@ -251,7 +251,7 @@ export function getAt<T = unknown>(obj: unknown, path: string[]): T | undefined
|
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
253
|
* A stable, non-cryptographic digest of `text`, equal on every host for equal
|
|
254
|
-
* text: the `
|
|
254
|
+
* text: the `TextState.hash` a data server stamps, so a client can
|
|
255
255
|
* hash text of its own to compare. An array is read as its elements joined, so
|
|
256
256
|
* a large text is hashed in parts without concatenating it. It tells whether a
|
|
257
257
|
* text changed, not who could forge one.
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made available under the
|
|
5
|
-
* terms of the MIT License which is available in the project root.
|
|
6
|
-
*
|
|
7
|
-
* SPDX-License-Identifier: MIT
|
|
8
|
-
********************************************************************************/
|
|
9
|
-
declare const snapshotMarker: unique symbol;
|
|
10
|
-
/**
|
|
11
|
-
* A text-document version that came out of a SNAPSHOT read: a document
|
|
12
|
-
* envelope's `version`, which cannot move once the envelope exists.
|
|
13
|
-
*
|
|
14
|
-
* A plain number at runtime, usable anywhere a number is, and it travels the
|
|
15
|
-
* wire as one. The marker exists only so the compiler can tell it apart from a
|
|
16
|
-
* version read off a LIVE document, which is the same number type and is the
|
|
17
|
-
* defect the conflict gate exists to prevent: read at write time it is whatever
|
|
18
|
-
* the server is at now, which is the number the gate is about to compare it
|
|
19
|
-
* against, so the gate passes unconditionally and a concurrent edit is
|
|
20
|
-
* overwritten with nothing logged.
|
|
21
|
-
*/
|
|
22
|
-
export type SnapshotVersion = number & {
|
|
23
|
-
readonly [snapshotMarker]: true;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* What a write declares it was based on: a version from a snapshot read, or
|
|
27
|
-
* `'anything'`.
|
|
28
|
-
*
|
|
29
|
-
* `'anything'` is a precondition that always holds — the write accepts whatever
|
|
30
|
-
* the server currently has, and therefore overwrites it. It is the honest
|
|
31
|
-
* answer wherever the write was authored against no particular server version,
|
|
32
|
-
* and a lie anywhere a reader handed the writer a document. The field carrying
|
|
33
|
-
* it is required, so an ungated write is a word someone chose rather than a
|
|
34
|
-
* field someone forgot.
|
|
35
|
-
*/
|
|
36
|
-
export type BasedOn = SnapshotVersion | 'anything';
|
|
37
|
-
/**
|
|
38
|
-
* Whether `basedOn` names a version, and so arms the gate.
|
|
39
|
-
*
|
|
40
|
-
* Branch on this rather than on `basedOn !== 'anything'`, which reads as "not
|
|
41
|
-
* based on anything" — the opposite of what the branch tests.
|
|
42
|
-
*/
|
|
43
|
-
export declare function isSnapshotVersion(basedOn: BasedOn): basedOn is SnapshotVersion;
|
|
44
|
-
/**
|
|
45
|
-
* Mark a version as having come from a snapshot read.
|
|
46
|
-
*
|
|
47
|
-
* **For the envelope constructors, not for callers.** Every door that builds a
|
|
48
|
-
* document envelope applies it on the way in, so anything a read returns
|
|
49
|
-
* already carries it and a writer never needs this. A caller reaching for it is
|
|
50
|
-
* asserting a provenance the compiler was about to deny — the read-late defect
|
|
51
|
-
* written out where a reviewer can see it.
|
|
52
|
-
*/
|
|
53
|
-
export declare function asSnapshotVersion(version: number): SnapshotVersion;
|
|
54
|
-
/** A snapshot version no write can match, so a write based on it conflicts. */
|
|
55
|
-
export declare const NO_MATCHING_VERSION: SnapshotVersion;
|
|
56
|
-
export {};
|
|
57
|
-
//# sourceMappingURL=based-on.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"based-on.d.ts","sourceRoot":"","sources":["../../src/model-service/based-on.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,MAAM,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,UAAU,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,eAAe,CAE9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAElE;AAED,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAE,eAAuC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"based-on.js","sourceRoot":"","sources":["../../src/model-service/based-on.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;AA+BlF;;;;;GAKG;AACH,2BAAkC,OAAgB;IAC/C,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,2BAAkC,OAAe;IAC9C,OAAO,OAA0B,CAAC;AACrC,CAAC;AAED,+EAA+E;AAClE,QAAA,mBAAmB,GAAoB,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made available under the
|
|
5
|
-
* terms of the MIT License which is available in the project root.
|
|
6
|
-
*
|
|
7
|
-
* SPDX-License-Identifier: MIT
|
|
8
|
-
********************************************************************************/
|
|
9
|
-
|
|
10
|
-
declare const snapshotMarker: unique symbol;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* A text-document version that came out of a SNAPSHOT read: a document
|
|
14
|
-
* envelope's `version`, which cannot move once the envelope exists.
|
|
15
|
-
*
|
|
16
|
-
* A plain number at runtime, usable anywhere a number is, and it travels the
|
|
17
|
-
* wire as one. The marker exists only so the compiler can tell it apart from a
|
|
18
|
-
* version read off a LIVE document, which is the same number type and is the
|
|
19
|
-
* defect the conflict gate exists to prevent: read at write time it is whatever
|
|
20
|
-
* the server is at now, which is the number the gate is about to compare it
|
|
21
|
-
* against, so the gate passes unconditionally and a concurrent edit is
|
|
22
|
-
* overwritten with nothing logged.
|
|
23
|
-
*/
|
|
24
|
-
export type SnapshotVersion = number & { readonly [snapshotMarker]: true };
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* What a write declares it was based on: a version from a snapshot read, or
|
|
28
|
-
* `'anything'`.
|
|
29
|
-
*
|
|
30
|
-
* `'anything'` is a precondition that always holds — the write accepts whatever
|
|
31
|
-
* the server currently has, and therefore overwrites it. It is the honest
|
|
32
|
-
* answer wherever the write was authored against no particular server version,
|
|
33
|
-
* and a lie anywhere a reader handed the writer a document. The field carrying
|
|
34
|
-
* it is required, so an ungated write is a word someone chose rather than a
|
|
35
|
-
* field someone forgot.
|
|
36
|
-
*/
|
|
37
|
-
export type BasedOn = SnapshotVersion | 'anything';
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Whether `basedOn` names a version, and so arms the gate.
|
|
41
|
-
*
|
|
42
|
-
* Branch on this rather than on `basedOn !== 'anything'`, which reads as "not
|
|
43
|
-
* based on anything" — the opposite of what the branch tests.
|
|
44
|
-
*/
|
|
45
|
-
export function isSnapshotVersion(basedOn: BasedOn): basedOn is SnapshotVersion {
|
|
46
|
-
return typeof basedOn === 'number';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Mark a version as having come from a snapshot read.
|
|
51
|
-
*
|
|
52
|
-
* **For the envelope constructors, not for callers.** Every door that builds a
|
|
53
|
-
* document envelope applies it on the way in, so anything a read returns
|
|
54
|
-
* already carries it and a writer never needs this. A caller reaching for it is
|
|
55
|
-
* asserting a provenance the compiler was about to deny — the read-late defect
|
|
56
|
-
* written out where a reviewer can see it.
|
|
57
|
-
*/
|
|
58
|
-
export function asSnapshotVersion(version: number): SnapshotVersion {
|
|
59
|
-
return version as SnapshotVersion;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** A snapshot version no write can match, so a write based on it conflicts. */
|
|
63
|
-
export const NO_MATCHING_VERSION: SnapshotVersion = asSnapshotVersion(-1);
|