@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.
Files changed (143) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +16 -0
  3. package/README.md +480 -0
  4. package/SECURITY.md +30 -0
  5. package/bin/git-warp +24 -0
  6. package/bin/warp-graph.js +1574 -0
  7. package/index.d.ts +2366 -0
  8. package/index.js +180 -0
  9. package/package.json +129 -0
  10. package/scripts/install-git-warp.sh +258 -0
  11. package/scripts/uninstall-git-warp.sh +139 -0
  12. package/src/domain/WarpGraph.js +3157 -0
  13. package/src/domain/crdt/Dot.js +160 -0
  14. package/src/domain/crdt/LWW.js +154 -0
  15. package/src/domain/crdt/ORSet.js +371 -0
  16. package/src/domain/crdt/VersionVector.js +222 -0
  17. package/src/domain/entities/GraphNode.js +60 -0
  18. package/src/domain/errors/EmptyMessageError.js +47 -0
  19. package/src/domain/errors/ForkError.js +30 -0
  20. package/src/domain/errors/IndexError.js +23 -0
  21. package/src/domain/errors/OperationAbortedError.js +22 -0
  22. package/src/domain/errors/QueryError.js +39 -0
  23. package/src/domain/errors/SchemaUnsupportedError.js +17 -0
  24. package/src/domain/errors/ShardCorruptionError.js +56 -0
  25. package/src/domain/errors/ShardLoadError.js +57 -0
  26. package/src/domain/errors/ShardValidationError.js +61 -0
  27. package/src/domain/errors/StorageError.js +57 -0
  28. package/src/domain/errors/SyncError.js +30 -0
  29. package/src/domain/errors/TraversalError.js +23 -0
  30. package/src/domain/errors/WarpError.js +31 -0
  31. package/src/domain/errors/WormholeError.js +28 -0
  32. package/src/domain/errors/WriterError.js +39 -0
  33. package/src/domain/errors/index.js +21 -0
  34. package/src/domain/services/AnchorMessageCodec.js +99 -0
  35. package/src/domain/services/BitmapIndexBuilder.js +225 -0
  36. package/src/domain/services/BitmapIndexReader.js +435 -0
  37. package/src/domain/services/BoundaryTransitionRecord.js +463 -0
  38. package/src/domain/services/CheckpointMessageCodec.js +147 -0
  39. package/src/domain/services/CheckpointSerializerV5.js +281 -0
  40. package/src/domain/services/CheckpointService.js +384 -0
  41. package/src/domain/services/CommitDagTraversalService.js +156 -0
  42. package/src/domain/services/DagPathFinding.js +712 -0
  43. package/src/domain/services/DagTopology.js +239 -0
  44. package/src/domain/services/DagTraversal.js +245 -0
  45. package/src/domain/services/Frontier.js +108 -0
  46. package/src/domain/services/GCMetrics.js +101 -0
  47. package/src/domain/services/GCPolicy.js +122 -0
  48. package/src/domain/services/GitLogParser.js +205 -0
  49. package/src/domain/services/HealthCheckService.js +246 -0
  50. package/src/domain/services/HookInstaller.js +326 -0
  51. package/src/domain/services/HttpSyncServer.js +262 -0
  52. package/src/domain/services/IndexRebuildService.js +426 -0
  53. package/src/domain/services/IndexStalenessChecker.js +103 -0
  54. package/src/domain/services/JoinReducer.js +582 -0
  55. package/src/domain/services/KeyCodec.js +113 -0
  56. package/src/domain/services/LegacyAnchorDetector.js +67 -0
  57. package/src/domain/services/LogicalTraversal.js +351 -0
  58. package/src/domain/services/MessageCodecInternal.js +132 -0
  59. package/src/domain/services/MessageSchemaDetector.js +145 -0
  60. package/src/domain/services/MigrationService.js +55 -0
  61. package/src/domain/services/ObserverView.js +265 -0
  62. package/src/domain/services/PatchBuilderV2.js +669 -0
  63. package/src/domain/services/PatchMessageCodec.js +140 -0
  64. package/src/domain/services/ProvenanceIndex.js +337 -0
  65. package/src/domain/services/ProvenancePayload.js +242 -0
  66. package/src/domain/services/QueryBuilder.js +835 -0
  67. package/src/domain/services/StateDiff.js +300 -0
  68. package/src/domain/services/StateSerializerV5.js +156 -0
  69. package/src/domain/services/StreamingBitmapIndexBuilder.js +709 -0
  70. package/src/domain/services/SyncProtocol.js +593 -0
  71. package/src/domain/services/TemporalQuery.js +201 -0
  72. package/src/domain/services/TranslationCost.js +221 -0
  73. package/src/domain/services/TraversalService.js +8 -0
  74. package/src/domain/services/WarpMessageCodec.js +29 -0
  75. package/src/domain/services/WarpStateIndexBuilder.js +127 -0
  76. package/src/domain/services/WormholeService.js +353 -0
  77. package/src/domain/types/TickReceipt.js +285 -0
  78. package/src/domain/types/WarpTypes.js +209 -0
  79. package/src/domain/types/WarpTypesV2.js +200 -0
  80. package/src/domain/utils/CachedValue.js +140 -0
  81. package/src/domain/utils/EventId.js +89 -0
  82. package/src/domain/utils/LRUCache.js +112 -0
  83. package/src/domain/utils/MinHeap.js +114 -0
  84. package/src/domain/utils/RefLayout.js +280 -0
  85. package/src/domain/utils/WriterId.js +205 -0
  86. package/src/domain/utils/cancellation.js +33 -0
  87. package/src/domain/utils/canonicalStringify.js +42 -0
  88. package/src/domain/utils/defaultClock.js +20 -0
  89. package/src/domain/utils/defaultCodec.js +51 -0
  90. package/src/domain/utils/nullLogger.js +21 -0
  91. package/src/domain/utils/roaring.js +181 -0
  92. package/src/domain/utils/shardVersion.js +9 -0
  93. package/src/domain/warp/PatchSession.js +217 -0
  94. package/src/domain/warp/Writer.js +181 -0
  95. package/src/hooks/post-merge.sh +60 -0
  96. package/src/infrastructure/adapters/BunHttpAdapter.js +225 -0
  97. package/src/infrastructure/adapters/ClockAdapter.js +57 -0
  98. package/src/infrastructure/adapters/ConsoleLogger.js +150 -0
  99. package/src/infrastructure/adapters/DenoHttpAdapter.js +230 -0
  100. package/src/infrastructure/adapters/GitGraphAdapter.js +787 -0
  101. package/src/infrastructure/adapters/GlobalClockAdapter.js +5 -0
  102. package/src/infrastructure/adapters/NoOpLogger.js +62 -0
  103. package/src/infrastructure/adapters/NodeCryptoAdapter.js +32 -0
  104. package/src/infrastructure/adapters/NodeHttpAdapter.js +98 -0
  105. package/src/infrastructure/adapters/PerformanceClockAdapter.js +5 -0
  106. package/src/infrastructure/adapters/WebCryptoAdapter.js +121 -0
  107. package/src/infrastructure/codecs/CborCodec.js +384 -0
  108. package/src/ports/BlobPort.js +30 -0
  109. package/src/ports/ClockPort.js +25 -0
  110. package/src/ports/CodecPort.js +25 -0
  111. package/src/ports/CommitPort.js +114 -0
  112. package/src/ports/ConfigPort.js +31 -0
  113. package/src/ports/CryptoPort.js +38 -0
  114. package/src/ports/GraphPersistencePort.js +57 -0
  115. package/src/ports/HttpServerPort.js +25 -0
  116. package/src/ports/IndexStoragePort.js +39 -0
  117. package/src/ports/LoggerPort.js +68 -0
  118. package/src/ports/RefPort.js +51 -0
  119. package/src/ports/TreePort.js +51 -0
  120. package/src/visualization/index.js +26 -0
  121. package/src/visualization/layouts/converters.js +75 -0
  122. package/src/visualization/layouts/elkAdapter.js +86 -0
  123. package/src/visualization/layouts/elkLayout.js +95 -0
  124. package/src/visualization/layouts/index.js +29 -0
  125. package/src/visualization/renderers/ascii/box.js +16 -0
  126. package/src/visualization/renderers/ascii/check.js +271 -0
  127. package/src/visualization/renderers/ascii/colors.js +13 -0
  128. package/src/visualization/renderers/ascii/formatters.js +73 -0
  129. package/src/visualization/renderers/ascii/graph.js +344 -0
  130. package/src/visualization/renderers/ascii/history.js +335 -0
  131. package/src/visualization/renderers/ascii/index.js +14 -0
  132. package/src/visualization/renderers/ascii/info.js +245 -0
  133. package/src/visualization/renderers/ascii/materialize.js +255 -0
  134. package/src/visualization/renderers/ascii/path.js +240 -0
  135. package/src/visualization/renderers/ascii/progress.js +32 -0
  136. package/src/visualization/renderers/ascii/symbols.js +33 -0
  137. package/src/visualization/renderers/ascii/table.js +19 -0
  138. package/src/visualization/renderers/browser/index.js +1 -0
  139. package/src/visualization/renderers/svg/index.js +159 -0
  140. package/src/visualization/utils/ansi.js +14 -0
  141. package/src/visualization/utils/time.js +40 -0
  142. package/src/visualization/utils/truncate.js +40 -0
  143. 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
+ }