@git-stunts/git-warp 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +16 -0
- package/README.md +480 -0
- package/SECURITY.md +30 -0
- package/bin/git-warp +24 -0
- package/bin/warp-graph.js +1574 -0
- package/index.d.ts +2366 -0
- package/index.js +180 -0
- package/package.json +129 -0
- package/scripts/install-git-warp.sh +258 -0
- package/scripts/uninstall-git-warp.sh +139 -0
- package/src/domain/WarpGraph.js +3157 -0
- package/src/domain/crdt/Dot.js +160 -0
- package/src/domain/crdt/LWW.js +154 -0
- package/src/domain/crdt/ORSet.js +371 -0
- package/src/domain/crdt/VersionVector.js +222 -0
- package/src/domain/entities/GraphNode.js +60 -0
- package/src/domain/errors/EmptyMessageError.js +47 -0
- package/src/domain/errors/ForkError.js +30 -0
- package/src/domain/errors/IndexError.js +23 -0
- package/src/domain/errors/OperationAbortedError.js +22 -0
- package/src/domain/errors/QueryError.js +39 -0
- package/src/domain/errors/SchemaUnsupportedError.js +17 -0
- package/src/domain/errors/ShardCorruptionError.js +56 -0
- package/src/domain/errors/ShardLoadError.js +57 -0
- package/src/domain/errors/ShardValidationError.js +61 -0
- package/src/domain/errors/StorageError.js +57 -0
- package/src/domain/errors/SyncError.js +30 -0
- package/src/domain/errors/TraversalError.js +23 -0
- package/src/domain/errors/WarpError.js +31 -0
- package/src/domain/errors/WormholeError.js +28 -0
- package/src/domain/errors/WriterError.js +39 -0
- package/src/domain/errors/index.js +21 -0
- package/src/domain/services/AnchorMessageCodec.js +99 -0
- package/src/domain/services/BitmapIndexBuilder.js +225 -0
- package/src/domain/services/BitmapIndexReader.js +435 -0
- package/src/domain/services/BoundaryTransitionRecord.js +463 -0
- package/src/domain/services/CheckpointMessageCodec.js +147 -0
- package/src/domain/services/CheckpointSerializerV5.js +281 -0
- package/src/domain/services/CheckpointService.js +384 -0
- package/src/domain/services/CommitDagTraversalService.js +156 -0
- package/src/domain/services/DagPathFinding.js +712 -0
- package/src/domain/services/DagTopology.js +239 -0
- package/src/domain/services/DagTraversal.js +245 -0
- package/src/domain/services/Frontier.js +108 -0
- package/src/domain/services/GCMetrics.js +101 -0
- package/src/domain/services/GCPolicy.js +122 -0
- package/src/domain/services/GitLogParser.js +205 -0
- package/src/domain/services/HealthCheckService.js +246 -0
- package/src/domain/services/HookInstaller.js +326 -0
- package/src/domain/services/HttpSyncServer.js +262 -0
- package/src/domain/services/IndexRebuildService.js +426 -0
- package/src/domain/services/IndexStalenessChecker.js +103 -0
- package/src/domain/services/JoinReducer.js +582 -0
- package/src/domain/services/KeyCodec.js +113 -0
- package/src/domain/services/LegacyAnchorDetector.js +67 -0
- package/src/domain/services/LogicalTraversal.js +351 -0
- package/src/domain/services/MessageCodecInternal.js +132 -0
- package/src/domain/services/MessageSchemaDetector.js +145 -0
- package/src/domain/services/MigrationService.js +55 -0
- package/src/domain/services/ObserverView.js +265 -0
- package/src/domain/services/PatchBuilderV2.js +669 -0
- package/src/domain/services/PatchMessageCodec.js +140 -0
- package/src/domain/services/ProvenanceIndex.js +337 -0
- package/src/domain/services/ProvenancePayload.js +242 -0
- package/src/domain/services/QueryBuilder.js +835 -0
- package/src/domain/services/StateDiff.js +300 -0
- package/src/domain/services/StateSerializerV5.js +156 -0
- package/src/domain/services/StreamingBitmapIndexBuilder.js +709 -0
- package/src/domain/services/SyncProtocol.js +593 -0
- package/src/domain/services/TemporalQuery.js +201 -0
- package/src/domain/services/TranslationCost.js +221 -0
- package/src/domain/services/TraversalService.js +8 -0
- package/src/domain/services/WarpMessageCodec.js +29 -0
- package/src/domain/services/WarpStateIndexBuilder.js +127 -0
- package/src/domain/services/WormholeService.js +353 -0
- package/src/domain/types/TickReceipt.js +285 -0
- package/src/domain/types/WarpTypes.js +209 -0
- package/src/domain/types/WarpTypesV2.js +200 -0
- package/src/domain/utils/CachedValue.js +140 -0
- package/src/domain/utils/EventId.js +89 -0
- package/src/domain/utils/LRUCache.js +112 -0
- package/src/domain/utils/MinHeap.js +114 -0
- package/src/domain/utils/RefLayout.js +280 -0
- package/src/domain/utils/WriterId.js +205 -0
- package/src/domain/utils/cancellation.js +33 -0
- package/src/domain/utils/canonicalStringify.js +42 -0
- package/src/domain/utils/defaultClock.js +20 -0
- package/src/domain/utils/defaultCodec.js +51 -0
- package/src/domain/utils/nullLogger.js +21 -0
- package/src/domain/utils/roaring.js +181 -0
- package/src/domain/utils/shardVersion.js +9 -0
- package/src/domain/warp/PatchSession.js +217 -0
- package/src/domain/warp/Writer.js +181 -0
- package/src/hooks/post-merge.sh +60 -0
- package/src/infrastructure/adapters/BunHttpAdapter.js +225 -0
- package/src/infrastructure/adapters/ClockAdapter.js +57 -0
- package/src/infrastructure/adapters/ConsoleLogger.js +150 -0
- package/src/infrastructure/adapters/DenoHttpAdapter.js +230 -0
- package/src/infrastructure/adapters/GitGraphAdapter.js +787 -0
- package/src/infrastructure/adapters/GlobalClockAdapter.js +5 -0
- package/src/infrastructure/adapters/NoOpLogger.js +62 -0
- package/src/infrastructure/adapters/NodeCryptoAdapter.js +32 -0
- package/src/infrastructure/adapters/NodeHttpAdapter.js +98 -0
- package/src/infrastructure/adapters/PerformanceClockAdapter.js +5 -0
- package/src/infrastructure/adapters/WebCryptoAdapter.js +121 -0
- package/src/infrastructure/codecs/CborCodec.js +384 -0
- package/src/ports/BlobPort.js +30 -0
- package/src/ports/ClockPort.js +25 -0
- package/src/ports/CodecPort.js +25 -0
- package/src/ports/CommitPort.js +114 -0
- package/src/ports/ConfigPort.js +31 -0
- package/src/ports/CryptoPort.js +38 -0
- package/src/ports/GraphPersistencePort.js +57 -0
- package/src/ports/HttpServerPort.js +25 -0
- package/src/ports/IndexStoragePort.js +39 -0
- package/src/ports/LoggerPort.js +68 -0
- package/src/ports/RefPort.js +51 -0
- package/src/ports/TreePort.js +51 -0
- package/src/visualization/index.js +26 -0
- package/src/visualization/layouts/converters.js +75 -0
- package/src/visualization/layouts/elkAdapter.js +86 -0
- package/src/visualization/layouts/elkLayout.js +95 -0
- package/src/visualization/layouts/index.js +29 -0
- package/src/visualization/renderers/ascii/box.js +16 -0
- package/src/visualization/renderers/ascii/check.js +271 -0
- package/src/visualization/renderers/ascii/colors.js +13 -0
- package/src/visualization/renderers/ascii/formatters.js +73 -0
- package/src/visualization/renderers/ascii/graph.js +344 -0
- package/src/visualization/renderers/ascii/history.js +335 -0
- package/src/visualization/renderers/ascii/index.js +14 -0
- package/src/visualization/renderers/ascii/info.js +245 -0
- package/src/visualization/renderers/ascii/materialize.js +255 -0
- package/src/visualization/renderers/ascii/path.js +240 -0
- package/src/visualization/renderers/ascii/progress.js +32 -0
- package/src/visualization/renderers/ascii/symbols.js +33 -0
- package/src/visualization/renderers/ascii/table.js +19 -0
- package/src/visualization/renderers/browser/index.js +1 -0
- package/src/visualization/renderers/svg/index.js +159 -0
- package/src/visualization/utils/ansi.js +14 -0
- package/src/visualization/utils/time.js +40 -0
- package/src/visualization/utils/truncate.js +40 -0
- package/src/visualization/utils/unicode.js +52 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { createDot } from './Dot.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview VersionVector - Causality Tracking via Join-Semilattice
|
|
5
|
+
*
|
|
6
|
+
* A version vector is a fundamental data structure for tracking causality in
|
|
7
|
+
* distributed systems. It maps each writer ID to the highest operation counter
|
|
8
|
+
* observed from that writer, forming a compact summary of "what has been seen."
|
|
9
|
+
*
|
|
10
|
+
* ## Semilattice Structure
|
|
11
|
+
*
|
|
12
|
+
* Version vectors form a **join-semilattice** under the pointwise maximum
|
|
13
|
+
* operation (vvMerge). A join-semilattice is a partially ordered set where
|
|
14
|
+
* every pair of elements has a least upper bound (join).
|
|
15
|
+
*
|
|
16
|
+
* The semilattice properties of vvMerge:
|
|
17
|
+
*
|
|
18
|
+
* - **Commutative**: vvMerge(a, b) = vvMerge(b, a)
|
|
19
|
+
* Order of merge doesn't matter
|
|
20
|
+
*
|
|
21
|
+
* - **Associative**: vvMerge(vvMerge(a, b), c) = vvMerge(a, vvMerge(b, c))
|
|
22
|
+
* Grouping of merges doesn't matter
|
|
23
|
+
*
|
|
24
|
+
* - **Idempotent**: vvMerge(a, a) = a
|
|
25
|
+
* Merging with self is a no-op
|
|
26
|
+
*
|
|
27
|
+
* These properties guarantee that any replica can merge updates from any other
|
|
28
|
+
* replica in any order, and all will converge to the same state. This is the
|
|
29
|
+
* foundation of conflict-free replicated data types (CRDTs).
|
|
30
|
+
*
|
|
31
|
+
* ## Concurrent Conflict-Free Merges
|
|
32
|
+
*
|
|
33
|
+
* Version vectors enable concurrent merges without coordination:
|
|
34
|
+
*
|
|
35
|
+
* 1. **No locks needed**: Any replica can accept updates at any time
|
|
36
|
+
* 2. **Eventual consistency**: All replicas converge given sufficient communication
|
|
37
|
+
* 3. **Order independence**: Updates can arrive in any order
|
|
38
|
+
*
|
|
39
|
+
* When two writers concurrently create patches, each has a version vector that
|
|
40
|
+
* doesn't include the other's patch. When merged, the result includes both,
|
|
41
|
+
* and the semilattice properties ensure consistency.
|
|
42
|
+
*
|
|
43
|
+
* ## Relationship to Patch Causality
|
|
44
|
+
*
|
|
45
|
+
* In git-warp, each patch carries a version vector representing its causal
|
|
46
|
+
* context - all patches it has observed. This enables:
|
|
47
|
+
*
|
|
48
|
+
* - **Happens-before detection**: If vv_a <= vv_b, then a happens-before b
|
|
49
|
+
* - **Concurrency detection**: If neither vv_a <= vv_b nor vv_b <= vv_a, they're concurrent
|
|
50
|
+
* - **Dot containment**: A dot (writerId, counter) is "observed" if vv[writerId] >= counter
|
|
51
|
+
*
|
|
52
|
+
* The version vector grows monotonically: each patch advances at least its own
|
|
53
|
+
* writer's counter, and may advance others via merge.
|
|
54
|
+
*
|
|
55
|
+
* ## Partial Order
|
|
56
|
+
*
|
|
57
|
+
* Version vectors are partially ordered by vvDescends (componentwise <=):
|
|
58
|
+
* - vv_a <= vv_b iff for all writerIds w: vv_a[w] <= vv_b[w]
|
|
59
|
+
*
|
|
60
|
+
* This forms a **causal order** where vv_a <= vv_b means "a causally precedes b"
|
|
61
|
+
* or "b has observed all of a's history." Incomparable vectors represent
|
|
62
|
+
* concurrent states.
|
|
63
|
+
*
|
|
64
|
+
* @module crdt/VersionVector
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* VersionVector - A map from writerId to counter representing observed operations.
|
|
69
|
+
* Used to track causality and determine what operations a writer has observed.
|
|
70
|
+
*
|
|
71
|
+
* @typedef {Map<string, number>} VersionVector
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Creates an empty VersionVector.
|
|
76
|
+
*
|
|
77
|
+
* @returns {VersionVector}
|
|
78
|
+
*/
|
|
79
|
+
export function createVersionVector() {
|
|
80
|
+
return new Map();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Increments the counter for a writer and returns the new Dot.
|
|
85
|
+
* This mutates the VersionVector.
|
|
86
|
+
*
|
|
87
|
+
* @param {VersionVector} vv - The version vector to mutate
|
|
88
|
+
* @param {string} writerId - The writer to increment
|
|
89
|
+
* @returns {import('./Dot.js').Dot} The new dot representing this operation
|
|
90
|
+
*/
|
|
91
|
+
export function vvIncrement(vv, writerId) {
|
|
92
|
+
const current = vv.get(writerId) || 0;
|
|
93
|
+
const newCounter = current + 1;
|
|
94
|
+
vv.set(writerId, newCounter);
|
|
95
|
+
return createDot(writerId, newCounter);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Merges two VersionVectors by taking the pointwise maximum.
|
|
100
|
+
* Returns a new VersionVector; does not mutate inputs.
|
|
101
|
+
*
|
|
102
|
+
* Properties:
|
|
103
|
+
* - Commutative: vvMerge(a, b) === vvMerge(b, a)
|
|
104
|
+
* - Associative: vvMerge(vvMerge(a, b), c) === vvMerge(a, vvMerge(b, c))
|
|
105
|
+
* - Idempotent: vvMerge(a, a) === a
|
|
106
|
+
*
|
|
107
|
+
* @param {VersionVector} a
|
|
108
|
+
* @param {VersionVector} b
|
|
109
|
+
* @returns {VersionVector}
|
|
110
|
+
*/
|
|
111
|
+
export function vvMerge(a, b) {
|
|
112
|
+
const result = new Map(a);
|
|
113
|
+
|
|
114
|
+
for (const [writerId, counter] of b) {
|
|
115
|
+
const existing = result.get(writerId) || 0;
|
|
116
|
+
result.set(writerId, Math.max(existing, counter));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Checks if VersionVector a descends from (is >= than) VersionVector b.
|
|
124
|
+
* a >= b means for every entry in b, a has an equal or greater counter.
|
|
125
|
+
*
|
|
126
|
+
* @param {VersionVector} a - The potentially descending vector
|
|
127
|
+
* @param {VersionVector} b - The potential ancestor vector
|
|
128
|
+
* @returns {boolean} True if a >= b componentwise
|
|
129
|
+
*/
|
|
130
|
+
export function vvDescends(a, b) {
|
|
131
|
+
for (const [writerId, counter] of b) {
|
|
132
|
+
const aCounter = a.get(writerId) || 0;
|
|
133
|
+
if (aCounter < counter) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Checks if a dot is contained within (observed by) the VersionVector.
|
|
142
|
+
* A dot is contained if dot.counter <= vv[dot.writerId].
|
|
143
|
+
*
|
|
144
|
+
* @param {VersionVector} vv
|
|
145
|
+
* @param {import('./Dot.js').Dot} dot
|
|
146
|
+
* @returns {boolean}
|
|
147
|
+
*/
|
|
148
|
+
export function vvContains(vv, dot) {
|
|
149
|
+
const counter = vv.get(dot.writerId) || 0;
|
|
150
|
+
return dot.counter <= counter;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Serializes a VersionVector to a plain object for CBOR encoding.
|
|
155
|
+
* Keys are sorted for deterministic serialization.
|
|
156
|
+
*
|
|
157
|
+
* @param {VersionVector} vv
|
|
158
|
+
* @returns {Object<string, number>}
|
|
159
|
+
*/
|
|
160
|
+
export function vvSerialize(vv) {
|
|
161
|
+
const obj = {};
|
|
162
|
+
const sortedKeys = [...vv.keys()].sort();
|
|
163
|
+
|
|
164
|
+
for (const key of sortedKeys) {
|
|
165
|
+
obj[key] = vv.get(key);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return obj;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Deserializes a plain object back to a VersionVector.
|
|
173
|
+
*
|
|
174
|
+
* @param {Object<string, number>} obj
|
|
175
|
+
* @returns {VersionVector}
|
|
176
|
+
* @throws {Error} If any counter value is not a non-negative integer
|
|
177
|
+
*/
|
|
178
|
+
export function vvDeserialize(obj) {
|
|
179
|
+
const vv = new Map();
|
|
180
|
+
|
|
181
|
+
for (const [writerId, counter] of Object.entries(obj)) {
|
|
182
|
+
if (typeof counter !== 'number' || !Number.isInteger(counter) || counter < 0) {
|
|
183
|
+
throw new Error(`Invalid counter for writerId "${writerId}": ${counter}`);
|
|
184
|
+
}
|
|
185
|
+
if (counter > 0) {
|
|
186
|
+
vv.set(writerId, counter);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return vv;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Clones a VersionVector.
|
|
195
|
+
*
|
|
196
|
+
* @param {VersionVector} vv
|
|
197
|
+
* @returns {VersionVector}
|
|
198
|
+
*/
|
|
199
|
+
export function vvClone(vv) {
|
|
200
|
+
return new Map(vv);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Checks if two VersionVectors are equal.
|
|
205
|
+
*
|
|
206
|
+
* @param {VersionVector} a
|
|
207
|
+
* @param {VersionVector} b
|
|
208
|
+
* @returns {boolean}
|
|
209
|
+
*/
|
|
210
|
+
export function vvEqual(a, b) {
|
|
211
|
+
if (a.size !== b.size) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (const [writerId, counter] of a) {
|
|
216
|
+
if (b.get(writerId) !== counter) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable domain entity representing a node in the graph.
|
|
3
|
+
*
|
|
4
|
+
* Each GraphNode corresponds to a Git commit pointing to the Empty Tree.
|
|
5
|
+
* Instances are frozen after construction to ensure immutability.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Create a node from parsed git log data
|
|
9
|
+
* const node = new GraphNode({
|
|
10
|
+
* sha: 'abc123def456...',
|
|
11
|
+
* message: '{"type":"UserCreated","payload":{...}}',
|
|
12
|
+
* author: 'Alice',
|
|
13
|
+
* date: '2026-01-29',
|
|
14
|
+
* parents: ['def456...']
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Access properties (all readonly)
|
|
19
|
+
* console.log(node.sha); // 'abc123def456...'
|
|
20
|
+
* console.log(node.message); // '{"type":"UserCreated",...}'
|
|
21
|
+
* console.log(node.parents); // ['def456...'] (frozen array)
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Attempting to modify throws in strict mode
|
|
25
|
+
* node.sha = 'new-sha'; // TypeError: Cannot assign to read only property
|
|
26
|
+
* node.parents.push('xyz'); // TypeError: Cannot add property
|
|
27
|
+
*/
|
|
28
|
+
export default class GraphNode {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new immutable GraphNode.
|
|
31
|
+
*
|
|
32
|
+
* @param {Object} data - Node data
|
|
33
|
+
* @param {string} data.sha - The commit SHA (40 hex characters). Required.
|
|
34
|
+
* @param {string} data.message - The commit message/payload. Required.
|
|
35
|
+
* @param {string} [data.author] - The commit author name. Optional.
|
|
36
|
+
* @param {string} [data.date] - The commit date string. Optional.
|
|
37
|
+
* @param {string[]} [data.parents=[]] - Array of parent commit SHAs. Defaults to empty array.
|
|
38
|
+
* @throws {Error} If sha is missing or not a string
|
|
39
|
+
* @throws {Error} If message is missing or not a string
|
|
40
|
+
* @throws {Error} If parents is not an array
|
|
41
|
+
*/
|
|
42
|
+
constructor({ sha, message, author, date, parents = [] }) {
|
|
43
|
+
if (!sha || typeof sha !== 'string') {
|
|
44
|
+
throw new Error('GraphNode requires a valid sha string');
|
|
45
|
+
}
|
|
46
|
+
if (!message || typeof message !== 'string') {
|
|
47
|
+
throw new Error('GraphNode requires a valid message string');
|
|
48
|
+
}
|
|
49
|
+
if (!Array.isArray(parents)) {
|
|
50
|
+
throw new Error('GraphNode parents must be an array');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.sha = sha;
|
|
54
|
+
this.message = message;
|
|
55
|
+
this.author = author;
|
|
56
|
+
this.date = date;
|
|
57
|
+
this.parents = Object.freeze([...parents]);
|
|
58
|
+
Object.freeze(this);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import IndexError from './IndexError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when a message is empty or contains only whitespace.
|
|
5
|
+
*
|
|
6
|
+
* This error indicates that an operation received an empty message
|
|
7
|
+
* where content was required.
|
|
8
|
+
*
|
|
9
|
+
* @class EmptyMessageError
|
|
10
|
+
* @extends IndexError
|
|
11
|
+
*
|
|
12
|
+
* @property {string} name - The error name ('EmptyMessageError')
|
|
13
|
+
* @property {string} code - Error code ('EMPTY_MESSAGE')
|
|
14
|
+
* @property {string} operation - The operation that failed due to empty message
|
|
15
|
+
* @property {Object} context - Serializable context object for debugging
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* if (!message || message.trim() === '') {
|
|
19
|
+
* throw new EmptyMessageError('Message cannot be empty', {
|
|
20
|
+
* operation: 'createNode',
|
|
21
|
+
* context: { nodeType: 'commit' }
|
|
22
|
+
* });
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
export default class EmptyMessageError extends IndexError {
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new EmptyMessageError.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} message - Human-readable error message
|
|
30
|
+
* @param {Object} [options={}] - Error options
|
|
31
|
+
* @param {string} [options.operation] - The operation that failed
|
|
32
|
+
* @param {Object} [options.context={}] - Additional context for debugging
|
|
33
|
+
*/
|
|
34
|
+
constructor(message, options = {}) {
|
|
35
|
+
const context = {
|
|
36
|
+
...options.context,
|
|
37
|
+
operation: options.operation,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
super(message, {
|
|
41
|
+
code: 'EMPTY_MESSAGE',
|
|
42
|
+
context,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.operation = options.operation;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import WarpError from './WarpError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error class for graph fork operations.
|
|
5
|
+
*
|
|
6
|
+
* ## Error Codes
|
|
7
|
+
*
|
|
8
|
+
* | Code | Description |
|
|
9
|
+
* |------|-------------|
|
|
10
|
+
* | `E_FORK_INVALID_ARGS` | Required fork parameters are missing or invalid |
|
|
11
|
+
* | `E_FORK_WRITER_NOT_FOUND` | The specified writer does not exist |
|
|
12
|
+
* | `E_FORK_PATCH_NOT_FOUND` | The specified patch SHA does not exist |
|
|
13
|
+
* | `E_FORK_PATCH_NOT_IN_CHAIN` | The patch SHA is not in the writer's chain |
|
|
14
|
+
* | `E_FORK_NAME_INVALID` | The fork graph name is invalid |
|
|
15
|
+
* | `E_FORK_WRITER_ID_INVALID` | The fork writer ID is invalid |
|
|
16
|
+
* | `E_FORK_ALREADY_EXISTS` | A graph with the fork name already exists |
|
|
17
|
+
* | `FORK_ERROR` | Generic/default fork error |
|
|
18
|
+
*
|
|
19
|
+
* @class ForkError
|
|
20
|
+
* @extends WarpError
|
|
21
|
+
*
|
|
22
|
+
* @property {string} name - Always 'ForkError' for instanceof checks
|
|
23
|
+
* @property {string} code - Machine-readable error code for programmatic handling
|
|
24
|
+
* @property {Object} context - Serializable context object with error details
|
|
25
|
+
*/
|
|
26
|
+
export default class ForkError extends WarpError {
|
|
27
|
+
constructor(message, options = {}) {
|
|
28
|
+
super(message, 'FORK_ERROR', options);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import WarpError from './WarpError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base error class for bitmap index operations.
|
|
5
|
+
*
|
|
6
|
+
* @class IndexError
|
|
7
|
+
* @extends WarpError
|
|
8
|
+
*
|
|
9
|
+
* @property {string} name - The error name ('IndexError')
|
|
10
|
+
* @property {string} code - Error code for programmatic handling (default: 'INDEX_ERROR')
|
|
11
|
+
* @property {Object} context - Serializable context object for debugging
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* throw new IndexError('Failed to process index', {
|
|
15
|
+
* code: 'CUSTOM_ERROR',
|
|
16
|
+
* context: { operation: 'merge', shardCount: 5 }
|
|
17
|
+
* });
|
|
18
|
+
*/
|
|
19
|
+
export default class IndexError extends WarpError {
|
|
20
|
+
constructor(message, options = {}) {
|
|
21
|
+
super(message, 'INDEX_ERROR', options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import WarpError from './WarpError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error class for aborted operations.
|
|
5
|
+
*
|
|
6
|
+
* @class OperationAbortedError
|
|
7
|
+
* @extends WarpError
|
|
8
|
+
*
|
|
9
|
+
* @property {string} name - The error name ('OperationAbortedError')
|
|
10
|
+
* @property {string} code - Error code for programmatic handling (default: 'OPERATION_ABORTED')
|
|
11
|
+
* @property {string} operation - The name of the operation that was aborted
|
|
12
|
+
* @property {string} reason - The reason the operation was aborted
|
|
13
|
+
* @property {Object} context - Serializable context object for debugging
|
|
14
|
+
*/
|
|
15
|
+
export default class OperationAbortedError extends WarpError {
|
|
16
|
+
constructor(operation, options = {}) {
|
|
17
|
+
const reason = options.reason || 'Operation was aborted';
|
|
18
|
+
super(`Operation '${operation}' aborted: ${reason}`, 'OPERATION_ABORTED', options);
|
|
19
|
+
this.operation = operation;
|
|
20
|
+
this.reason = reason;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import WarpError from './WarpError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error class for query builder and graph query operations.
|
|
5
|
+
*
|
|
6
|
+
* QueryError is thrown when a query operation fails due to invalid input,
|
|
7
|
+
* missing state, or constraint violations. It provides structured error
|
|
8
|
+
* information via error codes and context objects for programmatic handling.
|
|
9
|
+
*
|
|
10
|
+
* ## Error Codes
|
|
11
|
+
*
|
|
12
|
+
* | Code | Description |
|
|
13
|
+
* |------|-------------|
|
|
14
|
+
* | `E_NO_STATE` | No cached state available; call `materialize()` first |
|
|
15
|
+
* | `E_STALE_STATE` | Cached state is outdated; call `materialize()` to refresh |
|
|
16
|
+
* | `E_QUERY_MATCH_TYPE` | Invalid type passed to `match()` (expected string) |
|
|
17
|
+
* | `E_QUERY_WHERE_TYPE` | Invalid type passed to `where()` (expected function or object) |
|
|
18
|
+
* | `E_QUERY_WHERE_VALUE` | Non-primitive value in where() object shorthand |
|
|
19
|
+
* | `E_QUERY_LABEL_TYPE` | Invalid type for edge label (expected string) |
|
|
20
|
+
* | `E_QUERY_DEPTH_TYPE` | Invalid depth value (expected non-negative integer or [min, max] array) |
|
|
21
|
+
* | `E_QUERY_DEPTH_RANGE` | Invalid depth range (min > max) |
|
|
22
|
+
* | `E_QUERY_SELECT_TYPE` | Invalid type passed to `select()` (expected array) |
|
|
23
|
+
* | `E_QUERY_SELECT_FIELD` | Unknown field name in select() |
|
|
24
|
+
* | `E_QUERY_AGGREGATE_TYPE` | Invalid type passed to `aggregate()` |
|
|
25
|
+
* | `E_QUERY_AGGREGATE_TERMINAL` | Method called after aggregate() which is terminal |
|
|
26
|
+
* | `QUERY_ERROR` | Generic/default query error |
|
|
27
|
+
*
|
|
28
|
+
* @class QueryError
|
|
29
|
+
* @extends WarpError
|
|
30
|
+
*
|
|
31
|
+
* @property {string} name - Always 'QueryError' for instanceof checks
|
|
32
|
+
* @property {string} code - Machine-readable error code for programmatic handling
|
|
33
|
+
* @property {Object} context - Serializable context object with error details
|
|
34
|
+
*/
|
|
35
|
+
export default class QueryError extends WarpError {
|
|
36
|
+
constructor(message, options = {}) {
|
|
37
|
+
super(message, 'QUERY_ERROR', options);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import WarpError from './WarpError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when a patch contains operations unsupported by the current schema version.
|
|
5
|
+
*
|
|
6
|
+
* @class SchemaUnsupportedError
|
|
7
|
+
* @extends WarpError
|
|
8
|
+
*
|
|
9
|
+
* @property {string} name - The error name ('SchemaUnsupportedError')
|
|
10
|
+
* @property {string} code - Error code ('E_SCHEMA_UNSUPPORTED')
|
|
11
|
+
* @property {Object} context - Serializable context object for debugging
|
|
12
|
+
*/
|
|
13
|
+
export default class SchemaUnsupportedError extends WarpError {
|
|
14
|
+
constructor(message, options = {}) {
|
|
15
|
+
super(message, 'E_SCHEMA_UNSUPPORTED', options);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import IndexError from './IndexError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when shard data is corrupted or invalid.
|
|
5
|
+
*
|
|
6
|
+
* This error indicates that a shard file contains invalid or corrupted data,
|
|
7
|
+
* such as invalid checksums, unsupported versions, or malformed content.
|
|
8
|
+
*
|
|
9
|
+
* @class ShardCorruptionError
|
|
10
|
+
* @extends IndexError
|
|
11
|
+
*
|
|
12
|
+
* @property {string} name - The error name ('ShardCorruptionError')
|
|
13
|
+
* @property {string} code - Error code ('SHARD_CORRUPTION_ERROR')
|
|
14
|
+
* @property {string} shardPath - Path to the corrupted shard file
|
|
15
|
+
* @property {string} oid - Object ID associated with the shard
|
|
16
|
+
* @property {string} reason - Reason for corruption (e.g., 'invalid_checksum', 'invalid_version', 'parse_error')
|
|
17
|
+
* @property {Object} context - Serializable context object for debugging
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* if (!validateChecksum(data)) {
|
|
21
|
+
* throw new ShardCorruptionError('Shard checksum mismatch', {
|
|
22
|
+
* shardPath: '/path/to/shard',
|
|
23
|
+
* oid: 'abc123',
|
|
24
|
+
* reason: 'invalid_checksum'
|
|
25
|
+
* });
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
export default class ShardCorruptionError extends IndexError {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new ShardCorruptionError.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} message - Human-readable error message
|
|
33
|
+
* @param {Object} [options={}] - Error options
|
|
34
|
+
* @param {string} [options.shardPath] - Path to the corrupted shard file
|
|
35
|
+
* @param {string} [options.oid] - Object ID associated with the shard
|
|
36
|
+
* @param {string} [options.reason] - Reason for corruption (e.g., 'invalid_checksum', 'invalid_version', 'parse_error')
|
|
37
|
+
* @param {Object} [options.context={}] - Additional context for debugging
|
|
38
|
+
*/
|
|
39
|
+
constructor(message, options = {}) {
|
|
40
|
+
const context = {
|
|
41
|
+
...options.context,
|
|
42
|
+
shardPath: options.shardPath,
|
|
43
|
+
oid: options.oid,
|
|
44
|
+
reason: options.reason,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
super(message, {
|
|
48
|
+
code: 'SHARD_CORRUPTION_ERROR',
|
|
49
|
+
context,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.shardPath = options.shardPath;
|
|
53
|
+
this.oid = options.oid;
|
|
54
|
+
this.reason = options.reason;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import IndexError from './IndexError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when a shard fails to load.
|
|
5
|
+
*
|
|
6
|
+
* This error indicates that a shard file could not be read or parsed,
|
|
7
|
+
* typically due to I/O errors, missing files, or permission issues.
|
|
8
|
+
*
|
|
9
|
+
* @class ShardLoadError
|
|
10
|
+
* @extends IndexError
|
|
11
|
+
*
|
|
12
|
+
* @property {string} name - The error name ('ShardLoadError')
|
|
13
|
+
* @property {string} code - Error code ('SHARD_LOAD_ERROR')
|
|
14
|
+
* @property {string} shardPath - Path to the shard file that failed to load
|
|
15
|
+
* @property {string} oid - Object ID associated with the shard
|
|
16
|
+
* @property {Error} cause - The original error that caused the load failure
|
|
17
|
+
* @property {Object} context - Serializable context object for debugging
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* try {
|
|
21
|
+
* await loadShard(path);
|
|
22
|
+
* } catch (err) {
|
|
23
|
+
* throw new ShardLoadError('Failed to load shard', {
|
|
24
|
+
* shardPath: '/path/to/shard',
|
|
25
|
+
* oid: 'abc123',
|
|
26
|
+
* cause: err
|
|
27
|
+
* });
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
export default class ShardLoadError extends IndexError {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new ShardLoadError.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} message - Human-readable error message
|
|
35
|
+
* @param {Object} [options={}] - Error options
|
|
36
|
+
* @param {string} [options.shardPath] - Path to the shard file
|
|
37
|
+
* @param {string} [options.oid] - Object ID associated with the shard
|
|
38
|
+
* @param {Error} [options.cause] - The original error that caused the failure
|
|
39
|
+
* @param {Object} [options.context={}] - Additional context for debugging
|
|
40
|
+
*/
|
|
41
|
+
constructor(message, options = {}) {
|
|
42
|
+
const context = {
|
|
43
|
+
...options.context,
|
|
44
|
+
shardPath: options.shardPath,
|
|
45
|
+
oid: options.oid,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
super(message, {
|
|
49
|
+
code: 'SHARD_LOAD_ERROR',
|
|
50
|
+
context,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.shardPath = options.shardPath;
|
|
54
|
+
this.oid = options.oid;
|
|
55
|
+
this.cause = options.cause;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import IndexError from './IndexError.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when shard validation fails.
|
|
5
|
+
*
|
|
6
|
+
* This error indicates that a shard file failed validation checks,
|
|
7
|
+
* where expected values do not match actual values for specific fields.
|
|
8
|
+
*
|
|
9
|
+
* @class ShardValidationError
|
|
10
|
+
* @extends IndexError
|
|
11
|
+
*
|
|
12
|
+
* @property {string} name - The error name ('ShardValidationError')
|
|
13
|
+
* @property {string} code - Error code ('SHARD_VALIDATION_ERROR')
|
|
14
|
+
* @property {string} shardPath - Path to the shard file that failed validation
|
|
15
|
+
* @property {*} expected - The expected value for the field
|
|
16
|
+
* @property {*} actual - The actual value found in the shard
|
|
17
|
+
* @property {string} field - The field that failed validation (e.g., 'checksum', 'version')
|
|
18
|
+
* @property {Object} context - Serializable context object for debugging
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* if (shard.version !== EXPECTED_VERSION) {
|
|
22
|
+
* throw new ShardValidationError('Shard version mismatch', {
|
|
23
|
+
* shardPath: '/path/to/shard',
|
|
24
|
+
* expected: EXPECTED_VERSION,
|
|
25
|
+
* actual: shard.version,
|
|
26
|
+
* field: 'version'
|
|
27
|
+
* });
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
export default class ShardValidationError extends IndexError {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new ShardValidationError.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} message - Human-readable error message
|
|
35
|
+
* @param {Object} [options={}] - Error options
|
|
36
|
+
* @param {string} [options.shardPath] - Path to the shard file
|
|
37
|
+
* @param {*} [options.expected] - The expected value
|
|
38
|
+
* @param {*} [options.actual] - The actual value found
|
|
39
|
+
* @param {string} [options.field] - The field that failed validation (e.g., 'checksum', 'version')
|
|
40
|
+
* @param {Object} [options.context={}] - Additional context for debugging
|
|
41
|
+
*/
|
|
42
|
+
constructor(message, options = {}) {
|
|
43
|
+
const context = {
|
|
44
|
+
...options.context,
|
|
45
|
+
shardPath: options.shardPath,
|
|
46
|
+
expected: options.expected,
|
|
47
|
+
actual: options.actual,
|
|
48
|
+
field: options.field,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
super(message, {
|
|
52
|
+
code: 'SHARD_VALIDATION_ERROR',
|
|
53
|
+
context,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this.shardPath = options.shardPath;
|
|
57
|
+
this.expected = options.expected;
|
|
58
|
+
this.actual = options.actual;
|
|
59
|
+
this.field = options.field;
|
|
60
|
+
}
|
|
61
|
+
}
|