@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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/dist/crypto/compression.d.ts +37 -0
  3. package/dist/crypto/compression.d.ts.map +1 -0
  4. package/dist/crypto/compression.js +84 -0
  5. package/dist/crypto/compression.js.map +1 -0
  6. package/dist/crypto/encryption.d.ts +44 -0
  7. package/dist/crypto/encryption.d.ts.map +1 -0
  8. package/dist/crypto/encryption.js +129 -0
  9. package/dist/crypto/encryption.js.map +1 -0
  10. package/dist/crypto/hashing.d.ts +63 -0
  11. package/dist/crypto/hashing.d.ts.map +1 -0
  12. package/dist/crypto/hashing.js +182 -0
  13. package/dist/crypto/hashing.js.map +1 -0
  14. package/dist/crypto/index.d.ts +4 -0
  15. package/dist/crypto/index.d.ts.map +1 -0
  16. package/dist/crypto/index.js +4 -0
  17. package/dist/crypto/index.js.map +1 -0
  18. package/dist/index.d.ts +48 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +54 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/integration/index.d.ts +2 -0
  23. package/dist/integration/index.d.ts.map +1 -0
  24. package/dist/integration/index.js +2 -0
  25. package/dist/integration/index.js.map +1 -0
  26. package/dist/integration/openclaw-adapter.d.ts +64 -0
  27. package/dist/integration/openclaw-adapter.d.ts.map +1 -0
  28. package/dist/integration/openclaw-adapter.js +137 -0
  29. package/dist/integration/openclaw-adapter.js.map +1 -0
  30. package/dist/manifest/index.d.ts +2 -0
  31. package/dist/manifest/index.d.ts.map +1 -0
  32. package/dist/manifest/index.js +2 -0
  33. package/dist/manifest/index.js.map +1 -0
  34. package/dist/manifest/manifest-builder.d.ts +72 -0
  35. package/dist/manifest/manifest-builder.d.ts.map +1 -0
  36. package/dist/manifest/manifest-builder.js +84 -0
  37. package/dist/manifest/manifest-builder.js.map +1 -0
  38. package/dist/recorder/chunk-manager.d.ts +56 -0
  39. package/dist/recorder/chunk-manager.d.ts.map +1 -0
  40. package/dist/recorder/chunk-manager.js +172 -0
  41. package/dist/recorder/chunk-manager.js.map +1 -0
  42. package/dist/recorder/event-buffer.d.ts +61 -0
  43. package/dist/recorder/event-buffer.d.ts.map +1 -0
  44. package/dist/recorder/event-buffer.js +101 -0
  45. package/dist/recorder/event-buffer.js.map +1 -0
  46. package/dist/recorder/index.d.ts +4 -0
  47. package/dist/recorder/index.d.ts.map +1 -0
  48. package/dist/recorder/index.js +4 -0
  49. package/dist/recorder/index.js.map +1 -0
  50. package/dist/recorder/stream-recorder.d.ts +66 -0
  51. package/dist/recorder/stream-recorder.d.ts.map +1 -0
  52. package/dist/recorder/stream-recorder.js +329 -0
  53. package/dist/recorder/stream-recorder.js.map +1 -0
  54. package/dist/storage/index.d.ts +2 -0
  55. package/dist/storage/index.d.ts.map +1 -0
  56. package/dist/storage/index.js +2 -0
  57. package/dist/storage/index.js.map +1 -0
  58. package/dist/storage/local-adapter.d.ts +65 -0
  59. package/dist/storage/local-adapter.d.ts.map +1 -0
  60. package/dist/storage/local-adapter.js +152 -0
  61. package/dist/storage/local-adapter.js.map +1 -0
  62. package/dist/types.d.ts +284 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +28 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +43 -0
  67. package/src/__tests__/flight-recorder.test.ts +211 -0
  68. package/src/crypto/compression.ts +105 -0
  69. package/src/crypto/encryption.ts +210 -0
  70. package/src/crypto/hashing.ts +225 -0
  71. package/src/crypto/index.ts +3 -0
  72. package/src/index.ts +96 -0
  73. package/src/integration/index.ts +1 -0
  74. package/src/integration/openclaw-adapter.ts +206 -0
  75. package/src/manifest/index.ts +1 -0
  76. package/src/manifest/manifest-builder.ts +152 -0
  77. package/src/recorder/chunk-manager.ts +224 -0
  78. package/src/recorder/event-buffer.ts +124 -0
  79. package/src/recorder/index.ts +3 -0
  80. package/src/recorder/stream-recorder.ts +427 -0
  81. package/src/storage/index.ts +1 -0
  82. package/src/storage/local-adapter.ts +181 -0
  83. 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":"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"}
@@ -0,0 +1,2 @@
1
+ export { LocalStorageAdapter } from "./local-adapter.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { LocalStorageAdapter } from "./local-adapter.js";
2
+ //# sourceMappingURL=index.js.map
@@ -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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"}