@fluxpointstudios/orynq-sdk-flight-recorder 0.1.0
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 +21 -0
- package/dist/crypto/compression.d.ts +37 -0
- package/dist/crypto/compression.d.ts.map +1 -0
- package/dist/crypto/compression.js +84 -0
- package/dist/crypto/compression.js.map +1 -0
- package/dist/crypto/encryption.d.ts +44 -0
- package/dist/crypto/encryption.d.ts.map +1 -0
- package/dist/crypto/encryption.js +129 -0
- package/dist/crypto/encryption.js.map +1 -0
- package/dist/crypto/hashing.d.ts +63 -0
- package/dist/crypto/hashing.d.ts.map +1 -0
- package/dist/crypto/hashing.js +182 -0
- package/dist/crypto/hashing.js.map +1 -0
- package/dist/crypto/index.d.ts +4 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +4 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/integration/index.d.ts +2 -0
- package/dist/integration/index.d.ts.map +1 -0
- package/dist/integration/index.js +2 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/openclaw-adapter.d.ts +64 -0
- package/dist/integration/openclaw-adapter.d.ts.map +1 -0
- package/dist/integration/openclaw-adapter.js +137 -0
- package/dist/integration/openclaw-adapter.js.map +1 -0
- package/dist/manifest/index.d.ts +2 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +2 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/manifest-builder.d.ts +72 -0
- package/dist/manifest/manifest-builder.d.ts.map +1 -0
- package/dist/manifest/manifest-builder.js +84 -0
- package/dist/manifest/manifest-builder.js.map +1 -0
- package/dist/recorder/chunk-manager.d.ts +56 -0
- package/dist/recorder/chunk-manager.d.ts.map +1 -0
- package/dist/recorder/chunk-manager.js +172 -0
- package/dist/recorder/chunk-manager.js.map +1 -0
- package/dist/recorder/event-buffer.d.ts +61 -0
- package/dist/recorder/event-buffer.d.ts.map +1 -0
- package/dist/recorder/event-buffer.js +101 -0
- package/dist/recorder/event-buffer.js.map +1 -0
- package/dist/recorder/index.d.ts +4 -0
- package/dist/recorder/index.d.ts.map +1 -0
- package/dist/recorder/index.js +4 -0
- package/dist/recorder/index.js.map +1 -0
- package/dist/recorder/stream-recorder.d.ts +66 -0
- package/dist/recorder/stream-recorder.d.ts.map +1 -0
- package/dist/recorder/stream-recorder.js +329 -0
- package/dist/recorder/stream-recorder.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local-adapter.d.ts +65 -0
- package/dist/storage/local-adapter.d.ts.map +1 -0
- package/dist/storage/local-adapter.js +152 -0
- package/dist/storage/local-adapter.js.map +1 -0
- package/dist/types.d.ts +284 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
- package/src/__tests__/flight-recorder.test.ts +211 -0
- package/src/crypto/compression.ts +105 -0
- package/src/crypto/encryption.ts +210 -0
- package/src/crypto/hashing.ts +225 -0
- package/src/crypto/index.ts +3 -0
- package/src/index.ts +96 -0
- package/src/integration/index.ts +1 -0
- package/src/integration/openclaw-adapter.ts +206 -0
- package/src/manifest/index.ts +1 -0
- package/src/manifest/manifest-builder.ts +152 -0
- package/src/recorder/chunk-manager.ts +224 -0
- package/src/recorder/event-buffer.ts +124 -0
- package/src/recorder/index.ts +3 -0
- package/src/recorder/stream-recorder.ts +427 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/local-adapter.ts +181 -0
- package/src/types.ts +347 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main streaming flight recorder.
|
|
3
|
+
* Captures inference events, manages chunking, and builds manifests.
|
|
4
|
+
*/
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { FlightRecorderException, FlightRecorderError } from "../types.js";
|
|
7
|
+
import { EventBuffer } from "./event-buffer.js";
|
|
8
|
+
import { ChunkManager } from "./chunk-manager.js";
|
|
9
|
+
import { rollingHash, buildMerkleRoot, sha256Json, sha256String } from "../crypto/hashing.js";
|
|
10
|
+
const RECORDER_VERSION = "0.1.0";
|
|
11
|
+
export class FlightRecorder {
|
|
12
|
+
config;
|
|
13
|
+
session = null;
|
|
14
|
+
buffer;
|
|
15
|
+
chunkManager;
|
|
16
|
+
rollingHashState = "";
|
|
17
|
+
startTime = null;
|
|
18
|
+
// Tracking for outputs
|
|
19
|
+
toolCallCount = 0;
|
|
20
|
+
totalTokens = 0;
|
|
21
|
+
completionTokens = 0;
|
|
22
|
+
transcriptHashes = [];
|
|
23
|
+
// Tracking for inputs
|
|
24
|
+
promptHash = null;
|
|
25
|
+
systemPromptHash = null;
|
|
26
|
+
modelName = null;
|
|
27
|
+
inferenceParams = null;
|
|
28
|
+
// Spans
|
|
29
|
+
activeSpans = new Map();
|
|
30
|
+
completedSpanCount = 0;
|
|
31
|
+
// Timeout for auto-chunking
|
|
32
|
+
chunkTimeout = null;
|
|
33
|
+
constructor(config) {
|
|
34
|
+
this.config = config;
|
|
35
|
+
this.buffer = new EventBuffer(config.chunkSizeBytes);
|
|
36
|
+
this.chunkManager = new ChunkManager(config.storage, config.encryption, "gzip");
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Start a recording session.
|
|
40
|
+
*/
|
|
41
|
+
async start() {
|
|
42
|
+
if (this.session) {
|
|
43
|
+
throw new FlightRecorderException(FlightRecorderError.RECORDING_ALREADY_FINALIZED, "Recording session already started");
|
|
44
|
+
}
|
|
45
|
+
// Initialize encryption
|
|
46
|
+
await this.chunkManager.initializeKey();
|
|
47
|
+
// Initialize rolling hash with genesis
|
|
48
|
+
this.rollingHashState = await sha256String("poi-flight-recorder:genesis:v2");
|
|
49
|
+
this.startTime = new Date();
|
|
50
|
+
this.session = {
|
|
51
|
+
sessionId: this.config.sessionId || randomUUID(),
|
|
52
|
+
agentId: this.config.agentId,
|
|
53
|
+
startedAt: this.startTime.toISOString(),
|
|
54
|
+
status: "recording",
|
|
55
|
+
};
|
|
56
|
+
// Start chunk timeout if configured
|
|
57
|
+
if (this.config.chunkTimeoutMs) {
|
|
58
|
+
this.startChunkTimeout();
|
|
59
|
+
}
|
|
60
|
+
return this.session;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Record an event.
|
|
64
|
+
*/
|
|
65
|
+
async record(event) {
|
|
66
|
+
if (!this.session || this.session.status !== "recording") {
|
|
67
|
+
throw new FlightRecorderException(FlightRecorderError.RECORDING_NOT_STARTED, "Recording not started or already finalized");
|
|
68
|
+
}
|
|
69
|
+
// Add timestamp
|
|
70
|
+
const eventWithTs = {
|
|
71
|
+
...event,
|
|
72
|
+
ts: new Date().toISOString(),
|
|
73
|
+
};
|
|
74
|
+
// Track event-specific data
|
|
75
|
+
await this.trackEventData(eventWithTs);
|
|
76
|
+
// Add to buffer
|
|
77
|
+
const shouldFlush = await this.buffer.add(eventWithTs);
|
|
78
|
+
// Update rolling hash
|
|
79
|
+
const eventJson = JSON.stringify(eventWithTs);
|
|
80
|
+
this.rollingHashState = await rollingHash(this.rollingHashState, new TextEncoder().encode(eventJson));
|
|
81
|
+
// Flush if threshold reached
|
|
82
|
+
if (shouldFlush) {
|
|
83
|
+
await this.flushBuffer();
|
|
84
|
+
}
|
|
85
|
+
// Reset chunk timeout
|
|
86
|
+
if (this.config.chunkTimeoutMs) {
|
|
87
|
+
this.resetChunkTimeout();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Start a span for grouping related events.
|
|
92
|
+
*/
|
|
93
|
+
startSpan(name) {
|
|
94
|
+
const spanId = randomUUID();
|
|
95
|
+
this.activeSpans.set(spanId, { name, startTime: new Date() });
|
|
96
|
+
return spanId;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* End a span.
|
|
100
|
+
*/
|
|
101
|
+
endSpan(spanId) {
|
|
102
|
+
if (this.activeSpans.has(spanId)) {
|
|
103
|
+
this.activeSpans.delete(spanId);
|
|
104
|
+
this.completedSpanCount++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Record an event within a span.
|
|
109
|
+
*/
|
|
110
|
+
async recordInSpan(_spanId, fn) {
|
|
111
|
+
// Note: spanId is used for grouping but not directly in this method
|
|
112
|
+
const result = await fn();
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Finalize the recording and produce a manifest.
|
|
117
|
+
*/
|
|
118
|
+
async finalize() {
|
|
119
|
+
if (!this.session || this.session.status !== "recording") {
|
|
120
|
+
throw new FlightRecorderException(FlightRecorderError.RECORDING_NOT_STARTED, "Recording not started or already finalized");
|
|
121
|
+
}
|
|
122
|
+
this.session.status = "finalizing";
|
|
123
|
+
// Clear timeout
|
|
124
|
+
if (this.chunkTimeout) {
|
|
125
|
+
clearTimeout(this.chunkTimeout);
|
|
126
|
+
this.chunkTimeout = null;
|
|
127
|
+
}
|
|
128
|
+
// Flush any remaining events
|
|
129
|
+
if (!this.buffer.isEmpty()) {
|
|
130
|
+
await this.flushBuffer();
|
|
131
|
+
}
|
|
132
|
+
// Build Merkle root from chunk hashes
|
|
133
|
+
const leafHashes = this.chunkManager.getLeafHashes();
|
|
134
|
+
const merkleRoot = await buildMerkleRoot(leafHashes);
|
|
135
|
+
// Compute transcript rolling hash
|
|
136
|
+
const transcriptRollingHash = this.transcriptHashes.length > 0
|
|
137
|
+
? await buildMerkleRoot(this.transcriptHashes)
|
|
138
|
+
: await sha256String("empty-transcript");
|
|
139
|
+
// Build manifest
|
|
140
|
+
const manifest = await this.buildManifest(merkleRoot, transcriptRollingHash);
|
|
141
|
+
// Compute manifest hash (excluding the manifestHash field itself)
|
|
142
|
+
const manifestWithoutHash = { ...manifest, manifestHash: "" };
|
|
143
|
+
const manifestHash = await sha256Json(manifestWithoutHash, "manifest");
|
|
144
|
+
manifest.manifestHash = manifestHash;
|
|
145
|
+
// Store manifest
|
|
146
|
+
const manifestRef = await this.config.storage.storeManifest(manifest);
|
|
147
|
+
// Get attestation if available
|
|
148
|
+
let attestation;
|
|
149
|
+
if (this.config.attestor?.isAttested()) {
|
|
150
|
+
attestation = await this.config.attestor.attest(manifest.rootHash);
|
|
151
|
+
}
|
|
152
|
+
// Build anchor entry
|
|
153
|
+
const anchorEntry = {
|
|
154
|
+
schema: "poi-anchor-v2",
|
|
155
|
+
rootHash: manifest.rootHash,
|
|
156
|
+
merkleRoot: manifest.merkleRoot,
|
|
157
|
+
manifestHash: manifest.manifestHash,
|
|
158
|
+
storageUri: manifestRef.uri,
|
|
159
|
+
agentId: this.config.agentId,
|
|
160
|
+
sessionId: this.session.sessionId,
|
|
161
|
+
timestamp: new Date().toISOString(),
|
|
162
|
+
};
|
|
163
|
+
this.session.status = "finalized";
|
|
164
|
+
const result = {
|
|
165
|
+
rootHash: manifest.rootHash,
|
|
166
|
+
merkleRoot: manifest.merkleRoot,
|
|
167
|
+
manifestHash: manifest.manifestHash,
|
|
168
|
+
manifest,
|
|
169
|
+
chunkRefs: this.chunkManager.getChunks(),
|
|
170
|
+
anchorEntry,
|
|
171
|
+
};
|
|
172
|
+
if (attestation) {
|
|
173
|
+
result.attestation = attestation;
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Abort the recording.
|
|
179
|
+
*/
|
|
180
|
+
async abort(reason) {
|
|
181
|
+
if (this.chunkTimeout) {
|
|
182
|
+
clearTimeout(this.chunkTimeout);
|
|
183
|
+
this.chunkTimeout = null;
|
|
184
|
+
}
|
|
185
|
+
if (this.session) {
|
|
186
|
+
this.session.status = "aborted";
|
|
187
|
+
}
|
|
188
|
+
// Optionally log abort reason
|
|
189
|
+
if (reason) {
|
|
190
|
+
console.warn(`Recording aborted: ${reason}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get current session info.
|
|
195
|
+
*/
|
|
196
|
+
getSession() {
|
|
197
|
+
return this.session;
|
|
198
|
+
}
|
|
199
|
+
// === Private methods ===
|
|
200
|
+
async flushBuffer() {
|
|
201
|
+
const events = this.buffer.flush();
|
|
202
|
+
if (events.length === 0)
|
|
203
|
+
return;
|
|
204
|
+
const first = events[0];
|
|
205
|
+
const last = events[events.length - 1];
|
|
206
|
+
if (!first || !last)
|
|
207
|
+
return;
|
|
208
|
+
const eventRange = [first.event.seq, last.event.seq];
|
|
209
|
+
const spanIds = this.buffer.getSpanIds();
|
|
210
|
+
try {
|
|
211
|
+
await this.chunkManager.createChunk(events, eventRange, spanIds);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
throw new FlightRecorderException(FlightRecorderError.CHUNK_CREATION_FAILED, "Failed to create chunk", error instanceof Error ? error : undefined);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async trackEventData(event) {
|
|
218
|
+
switch (event.kind) {
|
|
219
|
+
case "inference:start":
|
|
220
|
+
this.promptHash = event.promptHash;
|
|
221
|
+
this.systemPromptHash = event.systemPromptHash ?? null;
|
|
222
|
+
this.modelName = event.model;
|
|
223
|
+
this.inferenceParams = event.params;
|
|
224
|
+
break;
|
|
225
|
+
case "inference:end":
|
|
226
|
+
this.totalTokens += event.tokenCounts.prompt + event.tokenCounts.completion;
|
|
227
|
+
this.completionTokens += event.tokenCounts.completion;
|
|
228
|
+
this.transcriptHashes.push(event.outputHash);
|
|
229
|
+
break;
|
|
230
|
+
case "tool:call":
|
|
231
|
+
this.toolCallCount++;
|
|
232
|
+
break;
|
|
233
|
+
case "stream:chunk":
|
|
234
|
+
this.transcriptHashes.push(event.chunkHash);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async buildManifest(merkleRoot, transcriptRollingHash) {
|
|
239
|
+
const now = new Date();
|
|
240
|
+
const durationMs = this.startTime
|
|
241
|
+
? now.getTime() - this.startTime.getTime()
|
|
242
|
+
: 0;
|
|
243
|
+
return {
|
|
244
|
+
formatVersion: "2.0",
|
|
245
|
+
agentId: this.config.agentId,
|
|
246
|
+
sessionId: this.session.sessionId,
|
|
247
|
+
rootHash: this.rollingHashState,
|
|
248
|
+
merkleRoot,
|
|
249
|
+
manifestHash: "", // Filled in after computing
|
|
250
|
+
inputs: this.buildInputs(),
|
|
251
|
+
params: this.buildParams(),
|
|
252
|
+
runtime: {
|
|
253
|
+
recorderVersion: RECORDER_VERSION,
|
|
254
|
+
nodeVersion: process.version,
|
|
255
|
+
...(this.config.captureRuntime ? this.captureRuntimeInfo() : {}),
|
|
256
|
+
},
|
|
257
|
+
chunks: this.chunkManager.getChunks(),
|
|
258
|
+
outputs: {
|
|
259
|
+
transcriptRollingHash,
|
|
260
|
+
toolCallCount: this.toolCallCount,
|
|
261
|
+
totalTokens: this.totalTokens,
|
|
262
|
+
completionTokens: this.completionTokens,
|
|
263
|
+
},
|
|
264
|
+
createdAt: now.toISOString(),
|
|
265
|
+
startedAt: this.startTime?.toISOString() || now.toISOString(),
|
|
266
|
+
endedAt: now.toISOString(),
|
|
267
|
+
durationMs,
|
|
268
|
+
totalEvents: this.buffer.getSeq(),
|
|
269
|
+
totalSpans: this.completedSpanCount,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
captureRuntimeInfo() {
|
|
273
|
+
// Basic runtime capture - can be extended
|
|
274
|
+
return {
|
|
275
|
+
nodeVersion: process.version,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
buildInputs() {
|
|
279
|
+
const inputs = {
|
|
280
|
+
promptHash: this.promptHash || "",
|
|
281
|
+
};
|
|
282
|
+
if (this.systemPromptHash) {
|
|
283
|
+
inputs.systemPromptHash = this.systemPromptHash;
|
|
284
|
+
}
|
|
285
|
+
return inputs;
|
|
286
|
+
}
|
|
287
|
+
buildParams() {
|
|
288
|
+
const params = {
|
|
289
|
+
model: this.modelName || "unknown",
|
|
290
|
+
};
|
|
291
|
+
if (this.inferenceParams?.temperature !== undefined) {
|
|
292
|
+
params.temperature = this.inferenceParams.temperature;
|
|
293
|
+
}
|
|
294
|
+
if (this.inferenceParams?.topP !== undefined) {
|
|
295
|
+
params.topP = this.inferenceParams.topP;
|
|
296
|
+
}
|
|
297
|
+
if (this.inferenceParams?.topK !== undefined) {
|
|
298
|
+
params.topK = this.inferenceParams.topK;
|
|
299
|
+
}
|
|
300
|
+
if (this.inferenceParams?.maxTokens !== undefined) {
|
|
301
|
+
params.maxTokens = this.inferenceParams.maxTokens;
|
|
302
|
+
}
|
|
303
|
+
if (this.inferenceParams?.stopStrings !== undefined) {
|
|
304
|
+
params.stopStrings = this.inferenceParams.stopStrings;
|
|
305
|
+
}
|
|
306
|
+
if (this.inferenceParams?.frequencyPenalty !== undefined) {
|
|
307
|
+
params.frequencyPenalty = this.inferenceParams.frequencyPenalty;
|
|
308
|
+
}
|
|
309
|
+
if (this.inferenceParams?.presencePenalty !== undefined) {
|
|
310
|
+
params.presencePenalty = this.inferenceParams.presencePenalty;
|
|
311
|
+
}
|
|
312
|
+
return params;
|
|
313
|
+
}
|
|
314
|
+
startChunkTimeout() {
|
|
315
|
+
this.chunkTimeout = setTimeout(async () => {
|
|
316
|
+
if (!this.buffer.isEmpty()) {
|
|
317
|
+
await this.flushBuffer();
|
|
318
|
+
}
|
|
319
|
+
this.startChunkTimeout();
|
|
320
|
+
}, this.config.chunkTimeoutMs);
|
|
321
|
+
}
|
|
322
|
+
resetChunkTimeout() {
|
|
323
|
+
if (this.chunkTimeout) {
|
|
324
|
+
clearTimeout(this.chunkTimeout);
|
|
325
|
+
this.startChunkTimeout();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=stream-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-recorder.js","sourceRoot":"","sources":["../../src/recorder/stream-recorder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUzC,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE9F,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAEjC,MAAM,OAAO,cAAc;IA2BI;IA1BrB,OAAO,GAA4B,IAAI,CAAC;IACxC,MAAM,CAAc;IACpB,YAAY,CAAe;IAE3B,gBAAgB,GAAG,EAAE,CAAC;IACtB,SAAS,GAAgB,IAAI,CAAC;IAEtC,uBAAuB;IACf,aAAa,GAAG,CAAC,CAAC;IAClB,WAAW,GAAG,CAAC,CAAC;IAChB,gBAAgB,GAAG,CAAC,CAAC;IACrB,gBAAgB,GAAa,EAAE,CAAC;IAExC,sBAAsB;IACd,UAAU,GAAkB,IAAI,CAAC;IACjC,gBAAgB,GAAkB,IAAI,CAAC;IACvC,SAAS,GAAkB,IAAI,CAAC;IAChC,eAAe,GAA2B,IAAI,CAAC;IAEvD,QAAQ;IACA,WAAW,GAAG,IAAI,GAAG,EAA6C,CAAC;IACnE,kBAAkB,GAAG,CAAC,CAAC;IAE/B,4BAA4B;IACpB,YAAY,GAAyC,IAAI,CAAC;IAElE,YAA6B,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;QACjD,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAClC,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,UAAU,EACjB,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,CAAC,2BAA2B,EAC/C,mCAAmC,CACpC,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QAExC,uCAAuC;QACvC,IAAI,CAAC,gBAAgB,GAAG,MAAM,YAAY,CAAC,gCAAgC,CAAC,CAAC;QAE7E,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAE5B,IAAI,CAAC,OAAO,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,UAAU,EAAE;YAChD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;YACvC,MAAM,EAAE,WAAW;SACpB,CAAC;QAEF,oCAAoC;QACpC,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,KAAwC;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACzD,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,CAAC,qBAAqB,EACzC,4CAA4C,CAC7C,CAAC;QACJ,CAAC;QAED,gBAAgB;QAChB,MAAM,WAAW,GAAG;YAClB,GAAG,KAAK;YACR,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACC,CAAC;QAEhC,4BAA4B;QAC5B,MAAM,IAAI,CAAC,cAAc,CAAC,WAA4B,CAAC,CAAC;QAExD,gBAAgB;QAChB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEvD,sBAAsB;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,GAAG,MAAM,WAAW,CACvC,IAAI,CAAC,gBAAgB,EACrB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CACpC,CAAC;QAEF,6BAA6B;QAC7B,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,MAAc;QACpB,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAChB,OAAe,EACf,EAAoB;QAEpB,oEAAoE;QACpE,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACzD,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,CAAC,qBAAqB,EACzC,4CAA4C,CAC7C,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC;QAEnC,gBAAgB;QAChB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC;QAED,sCAAsC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;QAErD,kCAAkC;QAClC,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;YAC5D,CAAC,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC;YAC9C,CAAC,CAAC,MAAM,YAAY,CAAC,kBAAkB,CAAC,CAAC;QAE3C,iBAAiB;QACjB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;QAE7E,kEAAkE;QAClE,MAAM,mBAAmB,GAAG,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAC9D,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;QACvE,QAAQ,CAAC,YAAY,GAAG,YAAY,CAAC;QAErC,iBAAiB;QACjB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAEtE,+BAA+B;QAC/B,IAAI,WAAW,CAAC;QAChB,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC;YACvC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrE,CAAC;QAED,qBAAqB;QACrB,MAAM,WAAW,GAAgB;YAC/B,MAAM,EAAE,eAAe;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,UAAU,EAAE,WAAW,CAAC,GAAG;YAC3B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC;QAElC,MAAM,MAAM,GAAoB;YAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;YACxC,WAAW;SACZ,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QACnC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,MAAe;QACzB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;QAClC,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,0BAA0B;IAElB,KAAK,CAAC,WAAW;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEhC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO;QAE5B,MAAM,UAAU,GAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAEzC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,CAAC,qBAAqB,EACzC,wBAAwB,EACxB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,KAAoB;QAC/C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,iBAAiB;gBACpB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;gBACnC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC;gBACvD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;gBAC7B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC;gBACpC,MAAM;YAER,KAAK,eAAe;gBAClB,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC;gBAC5E,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC;gBACtD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC7C,MAAM;YAER,KAAK,WAAW;gBACd,IAAI,CAAC,aAAa,EAAE,CAAC;gBACrB,MAAM;YAER,KAAK,cAAc;gBACjB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAC5C,MAAM;QACV,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,UAAkB,EAClB,qBAA6B;QAE7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS;YAC/B,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YAC1C,CAAC,CAAC,CAAC,CAAC;QAEN,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,SAAS,EAAE,IAAI,CAAC,OAAQ,CAAC,SAAS;YAElC,QAAQ,EAAE,IAAI,CAAC,gBAAgB;YAC/B,UAAU;YACV,YAAY,EAAE,EAAE,EAAE,4BAA4B;YAE9C,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE;YAE1B,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE;YAE1B,OAAO,EAAE;gBACP,eAAe,EAAE,gBAAgB;gBACjC,WAAW,EAAE,OAAO,CAAC,OAAO;gBAC5B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE;YAED,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;YAErC,OAAO,EAAE;gBACP,qBAAqB;gBACrB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;aACxC;YAED,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC,WAAW,EAAE;YAC7D,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE;YAC1B,UAAU;YAEV,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YACjC,UAAU,EAAE,IAAI,CAAC,kBAAkB;SACpC,CAAC;IACJ,CAAC;IAEO,kBAAkB;QACxB,0CAA0C;QAC1C,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;IAEO,WAAW;QACjB,MAAM,MAAM,GAAyB;YACnC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;SAClC,CAAC;QACF,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAClD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,WAAW;QACjB,MAAM,MAAM,GAAyB;YACnC,KAAK,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS;SACnC,CAAC;QACF,IAAI,IAAI,CAAC,eAAe,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;YACpD,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAC1C,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAC1C,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;YACpD,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACzD,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC;QAClE,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,EAAE,eAAe,KAAK,SAAS,EAAE,CAAC;YACxD,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC;QAChE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;YACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local filesystem storage adapter for flight recorder.
|
|
3
|
+
* Stores chunks and manifests on the local filesystem.
|
|
4
|
+
*/
|
|
5
|
+
import type { StorageAdapter, StorageRef, ManifestV2 } from "../types.js";
|
|
6
|
+
export interface LocalStorageConfig {
|
|
7
|
+
baseDir: string;
|
|
8
|
+
createDirs?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class LocalStorageAdapter implements StorageAdapter {
|
|
11
|
+
private readonly config;
|
|
12
|
+
readonly type: "local";
|
|
13
|
+
private initialized;
|
|
14
|
+
constructor(config: LocalStorageConfig);
|
|
15
|
+
/**
|
|
16
|
+
* Initialize storage directories.
|
|
17
|
+
*/
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Store a chunk.
|
|
21
|
+
*/
|
|
22
|
+
store(data: Uint8Array): Promise<StorageRef>;
|
|
23
|
+
/**
|
|
24
|
+
* Store a manifest.
|
|
25
|
+
*/
|
|
26
|
+
storeManifest(manifest: ManifestV2): Promise<StorageRef>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch data by reference.
|
|
29
|
+
*/
|
|
30
|
+
fetch(ref: StorageRef): Promise<Uint8Array>;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch a manifest by reference.
|
|
33
|
+
*/
|
|
34
|
+
fetchManifest(ref: StorageRef): Promise<ManifestV2>;
|
|
35
|
+
/**
|
|
36
|
+
* Verify data integrity.
|
|
37
|
+
*/
|
|
38
|
+
verify(ref: StorageRef): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Delete data.
|
|
41
|
+
*/
|
|
42
|
+
delete(ref: StorageRef): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Pin data (no-op for local storage).
|
|
45
|
+
*/
|
|
46
|
+
pin(_ref: StorageRef): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* List all stored chunks.
|
|
49
|
+
*/
|
|
50
|
+
listChunks(): Promise<string[]>;
|
|
51
|
+
/**
|
|
52
|
+
* List all stored manifests.
|
|
53
|
+
*/
|
|
54
|
+
listManifests(): Promise<string[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Get storage statistics.
|
|
57
|
+
*/
|
|
58
|
+
getStats(): Promise<{
|
|
59
|
+
chunkCount: number;
|
|
60
|
+
manifestCount: number;
|
|
61
|
+
totalBytes: number;
|
|
62
|
+
}>;
|
|
63
|
+
private uriToPath;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=local-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-adapter.d.ts","sourceRoot":"","sources":["../../src/storage/local-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,mBAAoB,YAAW,cAAc;IAI5C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,WAAW,CAAS;gBAEC,MAAM,EAAE,kBAAkB;IAEvD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBlD;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAoB9D;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAMjD;;OAEG;IACG,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAMzD;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAU/C;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C;;OAEG;IACG,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOrC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOxC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IA2B5F,OAAO,CAAC,SAAS;CAMlB"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local filesystem storage adapter for flight recorder.
|
|
3
|
+
* Stores chunks and manifests on the local filesystem.
|
|
4
|
+
*/
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { sha256 } from "../crypto/hashing.js";
|
|
8
|
+
export class LocalStorageAdapter {
|
|
9
|
+
config;
|
|
10
|
+
type = "local";
|
|
11
|
+
initialized = false;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Initialize storage directories.
|
|
17
|
+
*/
|
|
18
|
+
async initialize() {
|
|
19
|
+
if (this.initialized)
|
|
20
|
+
return;
|
|
21
|
+
if (this.config.createDirs !== false) {
|
|
22
|
+
await fs.mkdir(path.join(this.config.baseDir, "chunks"), { recursive: true });
|
|
23
|
+
await fs.mkdir(path.join(this.config.baseDir, "manifests"), { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
this.initialized = true;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Store a chunk.
|
|
29
|
+
*/
|
|
30
|
+
async store(data) {
|
|
31
|
+
await this.initialize();
|
|
32
|
+
const hash = await sha256(data, "chunk");
|
|
33
|
+
const filename = `${hash}.bin`;
|
|
34
|
+
const filepath = path.join(this.config.baseDir, "chunks", filename);
|
|
35
|
+
await fs.writeFile(filepath, data);
|
|
36
|
+
return {
|
|
37
|
+
type: "local",
|
|
38
|
+
uri: `file://${filepath}`,
|
|
39
|
+
hash,
|
|
40
|
+
size: data.length,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Store a manifest.
|
|
45
|
+
*/
|
|
46
|
+
async storeManifest(manifest) {
|
|
47
|
+
await this.initialize();
|
|
48
|
+
const json = JSON.stringify(manifest, null, 2);
|
|
49
|
+
const data = new TextEncoder().encode(json);
|
|
50
|
+
const hash = manifest.manifestHash || await sha256(data, "manifest");
|
|
51
|
+
const filename = `${manifest.sessionId}-${hash.slice(0, 16)}.json`;
|
|
52
|
+
const filepath = path.join(this.config.baseDir, "manifests", filename);
|
|
53
|
+
await fs.writeFile(filepath, json, "utf-8");
|
|
54
|
+
return {
|
|
55
|
+
type: "local",
|
|
56
|
+
uri: `file://${filepath}`,
|
|
57
|
+
hash,
|
|
58
|
+
size: data.length,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Fetch data by reference.
|
|
63
|
+
*/
|
|
64
|
+
async fetch(ref) {
|
|
65
|
+
const filepath = this.uriToPath(ref.uri);
|
|
66
|
+
const data = await fs.readFile(filepath);
|
|
67
|
+
return new Uint8Array(data);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Fetch a manifest by reference.
|
|
71
|
+
*/
|
|
72
|
+
async fetchManifest(ref) {
|
|
73
|
+
const filepath = this.uriToPath(ref.uri);
|
|
74
|
+
const json = await fs.readFile(filepath, "utf-8");
|
|
75
|
+
return JSON.parse(json);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Verify data integrity.
|
|
79
|
+
*/
|
|
80
|
+
async verify(ref) {
|
|
81
|
+
try {
|
|
82
|
+
const data = await this.fetch(ref);
|
|
83
|
+
const hash = await sha256(data, "chunk");
|
|
84
|
+
return hash === ref.hash;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Delete data.
|
|
92
|
+
*/
|
|
93
|
+
async delete(ref) {
|
|
94
|
+
const filepath = this.uriToPath(ref.uri);
|
|
95
|
+
await fs.unlink(filepath);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Pin data (no-op for local storage).
|
|
99
|
+
*/
|
|
100
|
+
async pin(_ref) {
|
|
101
|
+
// No-op for local storage
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* List all stored chunks.
|
|
105
|
+
*/
|
|
106
|
+
async listChunks() {
|
|
107
|
+
await this.initialize();
|
|
108
|
+
const chunksDir = path.join(this.config.baseDir, "chunks");
|
|
109
|
+
const files = await fs.readdir(chunksDir);
|
|
110
|
+
return files.filter((f) => f.endsWith(".bin"));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* List all stored manifests.
|
|
114
|
+
*/
|
|
115
|
+
async listManifests() {
|
|
116
|
+
await this.initialize();
|
|
117
|
+
const manifestsDir = path.join(this.config.baseDir, "manifests");
|
|
118
|
+
const files = await fs.readdir(manifestsDir);
|
|
119
|
+
return files.filter((f) => f.endsWith(".json"));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get storage statistics.
|
|
123
|
+
*/
|
|
124
|
+
async getStats() {
|
|
125
|
+
await this.initialize();
|
|
126
|
+
const chunks = await this.listChunks();
|
|
127
|
+
const manifests = await this.listManifests();
|
|
128
|
+
let totalBytes = 0;
|
|
129
|
+
for (const chunk of chunks) {
|
|
130
|
+
const filepath = path.join(this.config.baseDir, "chunks", chunk);
|
|
131
|
+
const stat = await fs.stat(filepath);
|
|
132
|
+
totalBytes += stat.size;
|
|
133
|
+
}
|
|
134
|
+
for (const manifest of manifests) {
|
|
135
|
+
const filepath = path.join(this.config.baseDir, "manifests", manifest);
|
|
136
|
+
const stat = await fs.stat(filepath);
|
|
137
|
+
totalBytes += stat.size;
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
chunkCount: chunks.length,
|
|
141
|
+
manifestCount: manifests.length,
|
|
142
|
+
totalBytes,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
uriToPath(uri) {
|
|
146
|
+
if (uri.startsWith("file://")) {
|
|
147
|
+
return uri.slice(7);
|
|
148
|
+
}
|
|
149
|
+
return uri;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=local-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-adapter.js","sourceRoot":"","sources":["../../src/storage/local-adapter.ts"],"names":[],"mappings":"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"}
|