@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,230 @@
|
|
|
1
|
+
import HttpServerPort from '../../ports/HttpServerPort.js';
|
|
2
|
+
|
|
3
|
+
const ERROR_BODY = 'Internal Server Error';
|
|
4
|
+
const ERROR_BODY_BYTES = new TextEncoder().encode(ERROR_BODY);
|
|
5
|
+
|
|
6
|
+
/** Absolute streaming body limit (10 MB) — matches NodeHttpAdapter. */
|
|
7
|
+
const MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reads a ReadableStream body with a byte-count limit.
|
|
11
|
+
* Aborts immediately when the limit is exceeded, preventing full buffering.
|
|
12
|
+
*
|
|
13
|
+
* @param {ReadableStream} bodyStream
|
|
14
|
+
* @returns {Promise<Uint8Array|undefined>}
|
|
15
|
+
*/
|
|
16
|
+
async function readStreamBody(bodyStream) {
|
|
17
|
+
const reader = bodyStream.getReader();
|
|
18
|
+
const chunks = [];
|
|
19
|
+
let total = 0;
|
|
20
|
+
for (;;) {
|
|
21
|
+
const { done, value } = await reader.read();
|
|
22
|
+
if (done) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
total += value.byteLength;
|
|
26
|
+
if (total > MAX_BODY_BYTES) {
|
|
27
|
+
await reader.cancel();
|
|
28
|
+
throw Object.assign(new Error('Payload Too Large'), { status: 413 });
|
|
29
|
+
}
|
|
30
|
+
chunks.push(value);
|
|
31
|
+
}
|
|
32
|
+
if (total === 0) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const body = new Uint8Array(total);
|
|
36
|
+
let offset = 0;
|
|
37
|
+
for (const chunk of chunks) {
|
|
38
|
+
body.set(chunk, offset);
|
|
39
|
+
offset += chunk.byteLength;
|
|
40
|
+
}
|
|
41
|
+
return body;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Converts a Deno Request into the plain-object format expected by
|
|
46
|
+
* HttpServerPort request handlers.
|
|
47
|
+
*
|
|
48
|
+
* @param {Request} request - Deno Request object
|
|
49
|
+
* @returns {Promise<{ method: string, url: string, headers: Object, body: Uint8Array|undefined }>}
|
|
50
|
+
*/
|
|
51
|
+
async function toPlainRequest(request) {
|
|
52
|
+
const headers = {};
|
|
53
|
+
request.headers.forEach((value, key) => {
|
|
54
|
+
headers[key] = value;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
let body;
|
|
58
|
+
if (request.method !== 'GET' && request.method !== 'HEAD' && request.body) {
|
|
59
|
+
const cl = headers['content-length'];
|
|
60
|
+
if (cl !== undefined && Number(cl) > MAX_BODY_BYTES) {
|
|
61
|
+
throw Object.assign(new Error('Payload Too Large'), { status: 413 });
|
|
62
|
+
}
|
|
63
|
+
body = await readStreamBody(request.body);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const url = new URL(request.url);
|
|
67
|
+
return {
|
|
68
|
+
method: request.method,
|
|
69
|
+
url: url.pathname + url.search,
|
|
70
|
+
headers,
|
|
71
|
+
body,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Converts a plain-object response from the handler into a Deno Response.
|
|
77
|
+
*
|
|
78
|
+
* @param {{ status?: number, headers?: Object, body?: string|Uint8Array }} plain
|
|
79
|
+
* @returns {Response}
|
|
80
|
+
*/
|
|
81
|
+
function toDenoResponse(plain) {
|
|
82
|
+
return new Response(plain.body ?? null, {
|
|
83
|
+
status: plain.status || 200,
|
|
84
|
+
headers: plain.headers || {},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Creates a Deno.serve-compatible handler that bridges to the
|
|
90
|
+
* HttpServerPort request handler contract.
|
|
91
|
+
*
|
|
92
|
+
* @param {Function} requestHandler
|
|
93
|
+
* @param {{ error: Function }} logger
|
|
94
|
+
* @returns {(request: Request) => Promise<Response>}
|
|
95
|
+
*/
|
|
96
|
+
function createHandler(requestHandler, logger) {
|
|
97
|
+
return async (request) => {
|
|
98
|
+
try {
|
|
99
|
+
const plain = await toPlainRequest(request);
|
|
100
|
+
const response = await requestHandler(plain);
|
|
101
|
+
return toDenoResponse(response);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
if (err.status === 413) {
|
|
104
|
+
const msg = new TextEncoder().encode('Payload Too Large');
|
|
105
|
+
return new Response(msg, {
|
|
106
|
+
status: 413,
|
|
107
|
+
headers: { 'Content-Type': 'text/plain', 'Content-Length': String(msg.byteLength) },
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
logger.error('DenoHttpAdapter dispatch error', err);
|
|
111
|
+
return new Response(ERROR_BODY_BYTES, {
|
|
112
|
+
status: 500,
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'text/plain',
|
|
115
|
+
'Content-Length': String(ERROR_BODY_BYTES.byteLength),
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Gracefully shuts down the Deno HTTP server.
|
|
124
|
+
*
|
|
125
|
+
* @param {object} state - Shared mutable state `{ server }`
|
|
126
|
+
* @param {Function} [callback]
|
|
127
|
+
*/
|
|
128
|
+
function closeImpl(state, callback) {
|
|
129
|
+
if (!state.server) {
|
|
130
|
+
if (callback) {
|
|
131
|
+
callback();
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
state.server.shutdown().then(
|
|
136
|
+
() => {
|
|
137
|
+
state.server = null;
|
|
138
|
+
if (callback) {
|
|
139
|
+
callback();
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
(err) => {
|
|
143
|
+
state.server = null;
|
|
144
|
+
if (callback) {
|
|
145
|
+
callback(err);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Returns the server's bound address info.
|
|
153
|
+
*
|
|
154
|
+
* @param {object} state - Shared mutable state `{ server }`
|
|
155
|
+
* @returns {{ address: string, port: number, family: string }|null}
|
|
156
|
+
*/
|
|
157
|
+
function addressImpl(state) {
|
|
158
|
+
if (!state.server) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const { addr } = state.server;
|
|
162
|
+
if (addr.transport !== 'tcp' && addr.transport !== 'udp') {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
address: addr.hostname,
|
|
167
|
+
port: addr.port,
|
|
168
|
+
family: addr.hostname.includes(':') ? 'IPv6' : 'IPv4',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const noopLogger = { error() {} };
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Deno runtime HTTP adapter implementing HttpServerPort.
|
|
176
|
+
*
|
|
177
|
+
* Uses globalThis.Deno.serve() (Deno 1.35+) to create an HTTP server.
|
|
178
|
+
* This file can be imported on any runtime but will fail at runtime
|
|
179
|
+
* if Deno APIs are not available.
|
|
180
|
+
*
|
|
181
|
+
* @extends HttpServerPort
|
|
182
|
+
*/
|
|
183
|
+
export default class DenoHttpAdapter extends HttpServerPort {
|
|
184
|
+
/**
|
|
185
|
+
* @param {{ logger?: { error: Function } }} [options]
|
|
186
|
+
*/
|
|
187
|
+
constructor({ logger } = {}) {
|
|
188
|
+
super();
|
|
189
|
+
this._logger = logger || noopLogger;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** @inheritdoc */
|
|
193
|
+
createServer(requestHandler) {
|
|
194
|
+
const handler = createHandler(requestHandler, this._logger);
|
|
195
|
+
const state = { server: null };
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
listen: (port, host, callback) => {
|
|
199
|
+
const cb = typeof host === 'function' ? host : callback;
|
|
200
|
+
const hostname = typeof host === 'string' ? host : undefined;
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const serveOptions = {
|
|
204
|
+
port,
|
|
205
|
+
onListen() {
|
|
206
|
+
if (cb) {
|
|
207
|
+
cb(null);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
if (hostname !== undefined) {
|
|
212
|
+
serveOptions.hostname = hostname;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
state.server = globalThis.Deno.serve(serveOptions, handler);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
if (cb) {
|
|
218
|
+
cb(err);
|
|
219
|
+
} else {
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
close: (callback) => {
|
|
225
|
+
closeImpl(state, callback);
|
|
226
|
+
},
|
|
227
|
+
address: () => addressImpl(state),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|