@savestate/cli 0.2.0 → 0.3.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/README.md +9 -0
- package/dist/cli.js +42 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +40 -9
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/login.d.ts +13 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +111 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/migrate.d.ts +21 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +218 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/schedule.d.ts +14 -0
- package/dist/commands/schedule.d.ts.map +1 -0
- package/dist/commands/schedule.js +294 -0
- package/dist/commands/schedule.js.map +1 -0
- package/dist/commands/snapshot.d.ts +1 -0
- package/dist/commands/snapshot.d.ts.map +1 -1
- package/dist/commands/snapshot.js +14 -4
- package/dist/commands/snapshot.js.map +1 -1
- package/dist/incremental.d.ts +137 -0
- package/dist/incremental.d.ts.map +1 -0
- package/dist/incremental.js +289 -0
- package/dist/incremental.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/restore.d.ts.map +1 -1
- package/dist/restore.js +7 -2
- package/dist/restore.js.map +1 -1
- package/dist/snapshot.d.ts +17 -1
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +82 -17
- package/dist/snapshot.js.map +1 -1
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/resolve.d.ts.map +1 -1
- package/dist/storage/resolve.js +19 -4
- package/dist/storage/resolve.js.map +1 -1
- package/dist/storage/s3.d.ts +64 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +360 -0
- package/dist/storage/s3.js.map +1 -0
- package/package.json +4 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaveState Incremental Snapshots
|
|
3
|
+
*
|
|
4
|
+
* Instead of storing a full copy every time, incremental snapshots
|
|
5
|
+
* only capture what changed since the parent snapshot.
|
|
6
|
+
*
|
|
7
|
+
* How it works:
|
|
8
|
+
* 1. Hash every file in the current snapshot (SHA-256)
|
|
9
|
+
* 2. Load the parent snapshot's content hashes
|
|
10
|
+
* 3. Compare: identify added, modified, removed files
|
|
11
|
+
* 4. Store only the delta (changed + added files)
|
|
12
|
+
* 5. On restore: reconstruct by applying deltas from base → current
|
|
13
|
+
*
|
|
14
|
+
* The delta manifest tracks the relationship:
|
|
15
|
+
* ```
|
|
16
|
+
* base (full) → delta-1 → delta-2 → delta-3 (current)
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Every Nth snapshot (configurable, default 10) forces a full snapshot
|
|
20
|
+
* to keep the chain short and restore fast.
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from 'node:crypto';
|
|
23
|
+
import { unpackFromArchive } from './format.js';
|
|
24
|
+
import { decrypt } from './encryption.js';
|
|
25
|
+
import { findEntry } from './index-file.js';
|
|
26
|
+
// ─── Configuration ───────────────────────────────────────────
|
|
27
|
+
/** Max chain depth before forcing a full snapshot */
|
|
28
|
+
export const MAX_CHAIN_DEPTH = 10;
|
|
29
|
+
/** If more than this fraction of files changed, just do a full snapshot */
|
|
30
|
+
export const FULL_SNAPSHOT_THRESHOLD = 0.7;
|
|
31
|
+
// ─── Content Hashing ─────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Compute SHA-256 hashes for every file in a packed snapshot.
|
|
34
|
+
*/
|
|
35
|
+
export function computeContentHashes(files) {
|
|
36
|
+
const hashes = {};
|
|
37
|
+
for (const [path, data] of files) {
|
|
38
|
+
hashes[path] = createHash('sha256').update(data).digest('hex');
|
|
39
|
+
}
|
|
40
|
+
// Root hash = hash of all sorted path:hash pairs
|
|
41
|
+
const sortedPairs = Object.entries(hashes)
|
|
42
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
43
|
+
.map(([p, h]) => `${p}:${h}`)
|
|
44
|
+
.join('\n');
|
|
45
|
+
const rootHash = createHash('sha256').update(sortedPairs).digest('hex');
|
|
46
|
+
return {
|
|
47
|
+
files: hashes,
|
|
48
|
+
count: Object.keys(hashes).length,
|
|
49
|
+
rootHash,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// ─── Delta Computation ───────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Compute the delta between the current snapshot files and a parent's content hashes.
|
|
55
|
+
*
|
|
56
|
+
* @param currentFiles - The full file map of the current snapshot
|
|
57
|
+
* @param parentHashes - Content hashes from the parent snapshot
|
|
58
|
+
* @param parentId - ID of the parent snapshot
|
|
59
|
+
* @param baseId - ID of the base (full) snapshot
|
|
60
|
+
* @param chainDepth - Current position in the chain
|
|
61
|
+
* @returns The computed delta and changed files
|
|
62
|
+
*/
|
|
63
|
+
export function computeDelta(currentFiles, parentHashes, parentId, baseId, chainDepth) {
|
|
64
|
+
const currentHashes = computeContentHashes(currentFiles);
|
|
65
|
+
const changedFiles = new Map();
|
|
66
|
+
const entries = [];
|
|
67
|
+
let added = 0;
|
|
68
|
+
let modified = 0;
|
|
69
|
+
let removed = 0;
|
|
70
|
+
let unchanged = 0;
|
|
71
|
+
let changedBytes = 0;
|
|
72
|
+
let totalBytes = 0;
|
|
73
|
+
// Check each current file against parent
|
|
74
|
+
for (const [path, data] of currentFiles) {
|
|
75
|
+
totalBytes += data.length;
|
|
76
|
+
const currentHash = currentHashes.files[path];
|
|
77
|
+
const parentHash = parentHashes.files[path];
|
|
78
|
+
if (!parentHash) {
|
|
79
|
+
// New file
|
|
80
|
+
entries.push({ path, type: 'added', hash: currentHash, size: data.length });
|
|
81
|
+
changedFiles.set(path, data);
|
|
82
|
+
changedBytes += data.length;
|
|
83
|
+
added++;
|
|
84
|
+
}
|
|
85
|
+
else if (currentHash !== parentHash) {
|
|
86
|
+
// Modified file
|
|
87
|
+
entries.push({ path, type: 'modified', hash: currentHash, size: data.length });
|
|
88
|
+
changedFiles.set(path, data);
|
|
89
|
+
changedBytes += data.length;
|
|
90
|
+
modified++;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
unchanged++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Check for removed files (in parent but not in current)
|
|
97
|
+
for (const path of Object.keys(parentHashes.files)) {
|
|
98
|
+
if (!currentFiles.has(path)) {
|
|
99
|
+
entries.push({ path, type: 'removed' });
|
|
100
|
+
removed++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const totalFiles = currentFiles.size;
|
|
104
|
+
const changedCount = added + modified + removed;
|
|
105
|
+
const changeRatio = totalFiles > 0 ? changedCount / totalFiles : 0;
|
|
106
|
+
// Should we force a full snapshot?
|
|
107
|
+
const shouldForceFull = chainDepth >= MAX_CHAIN_DEPTH || changeRatio >= FULL_SNAPSHOT_THRESHOLD;
|
|
108
|
+
const delta = {
|
|
109
|
+
parentId,
|
|
110
|
+
baseId,
|
|
111
|
+
chainDepth,
|
|
112
|
+
resultHashes: currentHashes,
|
|
113
|
+
entries,
|
|
114
|
+
stats: {
|
|
115
|
+
added,
|
|
116
|
+
modified,
|
|
117
|
+
removed,
|
|
118
|
+
unchanged,
|
|
119
|
+
totalFiles,
|
|
120
|
+
bytesSaved: totalBytes - changedBytes,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
return { delta, changedFiles, shouldForceFull };
|
|
124
|
+
}
|
|
125
|
+
// ─── Packing Incremental Archives ────────────────────────────
|
|
126
|
+
/**
|
|
127
|
+
* Pack an incremental snapshot (delta only).
|
|
128
|
+
* The archive contains:
|
|
129
|
+
* - manifest.json (with parent reference)
|
|
130
|
+
* - meta/delta-manifest.json (the delta details)
|
|
131
|
+
* - meta/snapshot-chain.json (chain info)
|
|
132
|
+
* - Only the changed/added files (same paths as full snapshot)
|
|
133
|
+
*/
|
|
134
|
+
export function packDelta(snapshot, delta, changedFiles) {
|
|
135
|
+
const files = new Map();
|
|
136
|
+
// Always include manifest and meta
|
|
137
|
+
files.set('manifest.json', Buffer.from(JSON.stringify(snapshot.manifest, null, 2)));
|
|
138
|
+
files.set('meta/delta-manifest.json', Buffer.from(JSON.stringify(delta, null, 2)));
|
|
139
|
+
files.set('meta/platform.json', Buffer.from(JSON.stringify(snapshot.platform, null, 2)));
|
|
140
|
+
files.set('meta/snapshot-chain.json', Buffer.from(JSON.stringify(snapshot.chain, null, 2)));
|
|
141
|
+
files.set('meta/restore-hints.json', Buffer.from(JSON.stringify(snapshot.restoreHints, null, 2)));
|
|
142
|
+
// Include only changed/added files
|
|
143
|
+
for (const [path, data] of changedFiles) {
|
|
144
|
+
files.set(path, data);
|
|
145
|
+
}
|
|
146
|
+
return files;
|
|
147
|
+
}
|
|
148
|
+
// ─── Reconstruction ──────────────────────────────────────────
|
|
149
|
+
/**
|
|
150
|
+
* Reconstruct a full snapshot by walking the chain from base to current.
|
|
151
|
+
*
|
|
152
|
+
* Starting from the base (full) snapshot, applies each delta in order:
|
|
153
|
+
* 1. Load base snapshot → full file map
|
|
154
|
+
* 2. For each delta in the chain:
|
|
155
|
+
* a. Add/overwrite files from the delta
|
|
156
|
+
* b. Remove files marked as 'removed'
|
|
157
|
+
* 3. Return the reconstructed full file map
|
|
158
|
+
*
|
|
159
|
+
* @param snapshotId - The target snapshot to reconstruct
|
|
160
|
+
* @param storage - Storage backend
|
|
161
|
+
* @param passphrase - Decryption passphrase
|
|
162
|
+
* @returns Reconstructed full file map
|
|
163
|
+
*/
|
|
164
|
+
export async function reconstructFromChain(snapshotId, storage, passphrase) {
|
|
165
|
+
// Build the chain: walk backwards from snapshotId to find the base
|
|
166
|
+
const chain = await buildChain(snapshotId, storage, passphrase);
|
|
167
|
+
if (chain.length === 0) {
|
|
168
|
+
throw new Error(`Could not build snapshot chain for ${snapshotId}`);
|
|
169
|
+
}
|
|
170
|
+
// chain[0] is the base (full) snapshot, chain[n-1] is the target
|
|
171
|
+
// Start with the base's full file map
|
|
172
|
+
const baseArchive = chain[0];
|
|
173
|
+
const files = new Map(baseArchive.files);
|
|
174
|
+
// Apply each delta in order
|
|
175
|
+
for (let i = 1; i < chain.length; i++) {
|
|
176
|
+
const { files: deltaFiles, delta } = chain[i];
|
|
177
|
+
if (!delta) {
|
|
178
|
+
// This is a full snapshot in the middle of the chain (shouldn't happen normally)
|
|
179
|
+
files.clear();
|
|
180
|
+
for (const [path, data] of deltaFiles) {
|
|
181
|
+
files.set(path, data);
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
// Apply additions and modifications
|
|
186
|
+
for (const [path, data] of deltaFiles) {
|
|
187
|
+
// Skip meta files — they're delta-specific
|
|
188
|
+
if (path === 'meta/delta-manifest.json')
|
|
189
|
+
continue;
|
|
190
|
+
files.set(path, data);
|
|
191
|
+
}
|
|
192
|
+
// Apply removals
|
|
193
|
+
for (const entry of delta.entries) {
|
|
194
|
+
if (entry.type === 'removed') {
|
|
195
|
+
files.delete(entry.path);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return files;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Build the full chain from base to the given snapshot.
|
|
203
|
+
* Returns an ordered array: [base, delta1, delta2, ..., target]
|
|
204
|
+
*/
|
|
205
|
+
async function buildChain(snapshotId, storage, passphrase) {
|
|
206
|
+
const links = [];
|
|
207
|
+
let currentId = snapshotId;
|
|
208
|
+
const visited = new Set();
|
|
209
|
+
// Walk backwards collecting snapshots
|
|
210
|
+
while (currentId && !visited.has(currentId)) {
|
|
211
|
+
visited.add(currentId);
|
|
212
|
+
const entry = await findEntry(currentId);
|
|
213
|
+
if (!entry) {
|
|
214
|
+
throw new Error(`Snapshot not found in index: ${currentId}`);
|
|
215
|
+
}
|
|
216
|
+
const encrypted = await storage.get(entry.filename);
|
|
217
|
+
const archive = await decrypt(encrypted, passphrase);
|
|
218
|
+
const files = await unpackFromArchive(archive);
|
|
219
|
+
// Check if this is a delta or full snapshot
|
|
220
|
+
const deltaManifestBuf = files.get('meta/delta-manifest.json');
|
|
221
|
+
let delta;
|
|
222
|
+
if (deltaManifestBuf) {
|
|
223
|
+
delta = JSON.parse(deltaManifestBuf.toString('utf-8'));
|
|
224
|
+
links.unshift({ id: currentId, files, delta });
|
|
225
|
+
currentId = delta.parentId;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
// Full snapshot — this is the base
|
|
229
|
+
links.unshift({ id: currentId, files, delta: undefined });
|
|
230
|
+
currentId = undefined; // Stop walking
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return links;
|
|
234
|
+
}
|
|
235
|
+
// ─── Helpers ─────────────────────────────────────────────────
|
|
236
|
+
/**
|
|
237
|
+
* Get content hashes for the latest snapshot (used as parent for incremental).
|
|
238
|
+
* Returns null if no previous snapshots exist.
|
|
239
|
+
*/
|
|
240
|
+
export async function getParentHashes(storage, passphrase) {
|
|
241
|
+
const { getLatestEntry } = await import('./index-file.js');
|
|
242
|
+
const latest = await getLatestEntry();
|
|
243
|
+
if (!latest)
|
|
244
|
+
return null;
|
|
245
|
+
try {
|
|
246
|
+
const encrypted = await storage.get(latest.filename);
|
|
247
|
+
const archive = await decrypt(encrypted, passphrase);
|
|
248
|
+
const files = await unpackFromArchive(archive);
|
|
249
|
+
// Check if the latest is itself a delta
|
|
250
|
+
const deltaManifestBuf = files.get('meta/delta-manifest.json');
|
|
251
|
+
if (deltaManifestBuf) {
|
|
252
|
+
const delta = JSON.parse(deltaManifestBuf.toString('utf-8'));
|
|
253
|
+
return {
|
|
254
|
+
hashes: delta.resultHashes,
|
|
255
|
+
parentId: latest.id,
|
|
256
|
+
baseId: delta.baseId,
|
|
257
|
+
chainDepth: delta.chainDepth + 1,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
// Full snapshot — compute hashes from the file map
|
|
261
|
+
const hashes = computeContentHashes(files);
|
|
262
|
+
return {
|
|
263
|
+
hashes,
|
|
264
|
+
parentId: latest.id,
|
|
265
|
+
baseId: latest.id,
|
|
266
|
+
chainDepth: 1,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Can't load parent — force full snapshot
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Check if a snapshot is incremental (has a delta manifest).
|
|
276
|
+
*/
|
|
277
|
+
export function isIncremental(files) {
|
|
278
|
+
return files.has('meta/delta-manifest.json');
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the delta manifest from an unpacked archive, if present.
|
|
282
|
+
*/
|
|
283
|
+
export function getDeltaManifest(files) {
|
|
284
|
+
const buf = files.get('meta/delta-manifest.json');
|
|
285
|
+
if (!buf)
|
|
286
|
+
return null;
|
|
287
|
+
return JSON.parse(buf.toString('utf-8'));
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=incremental.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incremental.js","sourceRoot":"","sources":["../src/incremental.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { encrypt, decrypt, verify } from './encryption.js';
|
|
|
8
8
|
export { packSnapshot, unpackSnapshot, computeChecksum, generateSnapshotId, snapshotFilename, SAF_EXTENSION, SAF_VERSION, } from './format.js';
|
|
9
9
|
export { loadConfig, saveConfig, initializeProject, isInitialized, defaultConfig, SAVESTATE_DIR, GLOBAL_SAVESTATE_DIR, } from './config.js';
|
|
10
10
|
export { createSnapshot, getLatestSnapshotId } from './snapshot.js';
|
|
11
|
+
export { computeContentHashes, computeDelta, packDelta, reconstructFromChain, getParentHashes, isIncremental, getDeltaManifest, MAX_CHAIN_DEPTH, FULL_SNAPSHOT_THRESHOLD, } from './incremental.js';
|
|
12
|
+
export type { ContentHashes, DeltaEntry, DeltaManifest, DeltaResult, } from './incremental.js';
|
|
11
13
|
export { restoreSnapshot, validateSnapshot } from './restore.js';
|
|
12
14
|
export { searchSnapshots, scoreMatch } from './search.js';
|
|
13
15
|
export { LocalStorageBackend } from './storage/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,OAAO,EACP,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,aAAa,EACb,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,OAAO,EACP,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,aAAa,EACb,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export { packSnapshot, unpackSnapshot, computeChecksum, generateSnapshotId, snap
|
|
|
11
11
|
export { loadConfig, saveConfig, initializeProject, isInitialized, defaultConfig, SAVESTATE_DIR, GLOBAL_SAVESTATE_DIR, } from './config.js';
|
|
12
12
|
// Snapshot
|
|
13
13
|
export { createSnapshot, getLatestSnapshotId } from './snapshot.js';
|
|
14
|
+
// Incremental
|
|
15
|
+
export { computeContentHashes, computeDelta, packDelta, reconstructFromChain, getParentHashes, isIncremental, getDeltaManifest, MAX_CHAIN_DEPTH, FULL_SNAPSHOT_THRESHOLD, } from './incremental.js';
|
|
14
16
|
// Restore
|
|
15
17
|
export { restoreSnapshot, validateSnapshot } from './restore.js';
|
|
16
18
|
// Search
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmCH,aAAa;AACb,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE3D,SAAS;AACT,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,SAAS;AACT,OAAO,EACL,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,aAAa,EACb,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpE,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjE,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,WAAW;AACX,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmCH,aAAa;AACb,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE3D,SAAS;AACT,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,SAAS;AACT,OAAO,EACL,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,aAAa,EACb,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpE,cAAc;AACd,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAQ1B,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjE,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,WAAW;AACX,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,qBAAqB,CAAC"}
|
package/dist/restore.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../src/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../src/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMpE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,QAAQ,GAAG,eAAe,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GACA,OAAO,CAAC,aAAa,CAAC,CA8ExB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CAYD"}
|
package/dist/restore.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { unpackFromArchive, unpackSnapshot, computeChecksum, snapshotFilename } from './format.js';
|
|
15
15
|
import { decrypt } from './encryption.js';
|
|
16
16
|
import { findEntry, getLatestEntry } from './index-file.js';
|
|
17
|
+
import { isIncremental, reconstructFromChain } from './incremental.js';
|
|
17
18
|
/**
|
|
18
19
|
* Restore from a snapshot.
|
|
19
20
|
*
|
|
@@ -67,9 +68,13 @@ export async function restoreSnapshot(snapshotId, adapter, storage, passphrase,
|
|
|
67
68
|
throw err;
|
|
68
69
|
}
|
|
69
70
|
// Step 4: Unpack SAF
|
|
70
|
-
|
|
71
|
+
let fileMap = await unpackFromArchive(archive);
|
|
72
|
+
// Step 4b: If incremental, reconstruct full state from chain
|
|
73
|
+
if (isIncremental(fileMap)) {
|
|
74
|
+
fileMap = await reconstructFromChain(resolvedId, storage, passphrase);
|
|
75
|
+
}
|
|
71
76
|
const snapshot = unpackSnapshot(fileMap);
|
|
72
|
-
// Verify integrity
|
|
77
|
+
// Verify integrity (for full snapshots)
|
|
73
78
|
const expectedChecksum = snapshot.manifest.checksum;
|
|
74
79
|
if (expectedChecksum) {
|
|
75
80
|
const actualChecksum = computeChecksum(archive);
|
package/dist/restore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../src/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../src/restore.ts"],"names":[],"mappings":"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"}
|
package/dist/snapshot.d.ts
CHANGED
|
@@ -21,20 +21,36 @@ export interface CreateSnapshotResult {
|
|
|
21
21
|
archiveSize: number;
|
|
22
22
|
encryptedSize: number;
|
|
23
23
|
fileCount: number;
|
|
24
|
+
/** Whether this is an incremental (delta) snapshot */
|
|
25
|
+
incremental: boolean;
|
|
26
|
+
/** Delta stats (only present for incremental snapshots) */
|
|
27
|
+
delta?: {
|
|
28
|
+
added: number;
|
|
29
|
+
modified: number;
|
|
30
|
+
removed: number;
|
|
31
|
+
unchanged: number;
|
|
32
|
+
bytesSaved: number;
|
|
33
|
+
chainDepth: number;
|
|
34
|
+
};
|
|
24
35
|
}
|
|
25
36
|
/**
|
|
26
37
|
* Create a new snapshot by extracting state from an adapter.
|
|
27
38
|
*
|
|
39
|
+
* Automatically uses incremental snapshots when a parent exists,
|
|
40
|
+
* unless `full` is explicitly requested or the chain is too deep.
|
|
41
|
+
*
|
|
28
42
|
* @param adapter - Platform adapter to extract state from
|
|
29
43
|
* @param storage - Storage backend to write to
|
|
30
44
|
* @param passphrase - Encryption passphrase
|
|
31
|
-
* @param options - Snapshot options (label, tags, etc.)
|
|
45
|
+
* @param options - Snapshot options (label, tags, full, etc.)
|
|
32
46
|
* @returns Details about the created snapshot
|
|
33
47
|
*/
|
|
34
48
|
export declare function createSnapshot(adapter: Adapter, storage: StorageBackend, passphrase: string, options?: {
|
|
35
49
|
label?: string;
|
|
36
50
|
tags?: string[];
|
|
37
51
|
parentId?: string;
|
|
52
|
+
/** Force a full snapshot (skip incremental) */
|
|
53
|
+
full?: boolean;
|
|
38
54
|
}): Promise<CreateSnapshotResult>;
|
|
39
55
|
/**
|
|
40
56
|
* Get the latest snapshot ID from the index.
|
package/dist/snapshot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAmB,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAmB,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAmBrF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,OAAO,CAAC;IACrB,2DAA2D;IAC3D,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,oBAAoB,CAAC,CAkI/B;AAYD;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIlE"}
|
package/dist/snapshot.js
CHANGED
|
@@ -17,13 +17,17 @@
|
|
|
17
17
|
import { generateSnapshotId, SAF_VERSION, packSnapshot, packToArchive, computeChecksum, snapshotFilename, } from './format.js';
|
|
18
18
|
import { encrypt } from './encryption.js';
|
|
19
19
|
import { addToIndex } from './index-file.js';
|
|
20
|
+
import { getParentHashes, computeDelta, packDelta, } from './incremental.js';
|
|
20
21
|
/**
|
|
21
22
|
* Create a new snapshot by extracting state from an adapter.
|
|
22
23
|
*
|
|
24
|
+
* Automatically uses incremental snapshots when a parent exists,
|
|
25
|
+
* unless `full` is explicitly requested or the chain is too deep.
|
|
26
|
+
*
|
|
23
27
|
* @param adapter - Platform adapter to extract state from
|
|
24
28
|
* @param storage - Storage backend to write to
|
|
25
29
|
* @param passphrase - Encryption passphrase
|
|
26
|
-
* @param options - Snapshot options (label, tags, etc.)
|
|
30
|
+
* @param options - Snapshot options (label, tags, full, etc.)
|
|
27
31
|
* @returns Details about the created snapshot
|
|
28
32
|
*/
|
|
29
33
|
export async function createSnapshot(adapter, storage, passphrase, options) {
|
|
@@ -32,6 +36,31 @@ export async function createSnapshot(adapter, storage, passphrase, options) {
|
|
|
32
36
|
// Step 2: Enrich manifest
|
|
33
37
|
const snapshotId = generateSnapshotId();
|
|
34
38
|
const now = new Date().toISOString();
|
|
39
|
+
// Step 3: Check for incremental opportunity
|
|
40
|
+
let parentInfo = null;
|
|
41
|
+
if (!options?.full) {
|
|
42
|
+
try {
|
|
43
|
+
parentInfo = await getParentHashes(storage, passphrase);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Can't load parent — proceed with full snapshot
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Step 4: Pack the full snapshot to get file map
|
|
50
|
+
// (we need this regardless — for delta comparison or full storage)
|
|
51
|
+
const fullFileMap = packSnapshot(snapshot);
|
|
52
|
+
// Step 5: Determine if we should do incremental or full
|
|
53
|
+
let deltaManifest;
|
|
54
|
+
let deltaResult;
|
|
55
|
+
let isIncremental = false;
|
|
56
|
+
if (parentInfo) {
|
|
57
|
+
deltaResult = computeDelta(fullFileMap, parentInfo.hashes, parentInfo.parentId, parentInfo.baseId, parentInfo.chainDepth);
|
|
58
|
+
if (!deltaResult.shouldForceFull) {
|
|
59
|
+
isIncremental = true;
|
|
60
|
+
deltaManifest = deltaResult.delta;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Step 6: Set manifest with parent reference
|
|
35
64
|
snapshot.manifest = {
|
|
36
65
|
...snapshot.manifest,
|
|
37
66
|
id: snapshotId,
|
|
@@ -41,31 +70,47 @@ export async function createSnapshot(adapter, storage, passphrase, options) {
|
|
|
41
70
|
platform: adapter.platform,
|
|
42
71
|
label: options?.label ?? snapshot.manifest.label,
|
|
43
72
|
tags: options?.tags ?? snapshot.manifest.tags,
|
|
44
|
-
parent: options?.parentId,
|
|
73
|
+
parent: isIncremental ? parentInfo.parentId : options?.parentId,
|
|
45
74
|
};
|
|
46
|
-
// Step
|
|
75
|
+
// Step 7: Update snapshot chain
|
|
47
76
|
snapshot.chain = {
|
|
48
77
|
current: snapshotId,
|
|
49
|
-
parent: options?.parentId,
|
|
50
|
-
ancestors:
|
|
51
|
-
? [...(
|
|
52
|
-
|
|
78
|
+
parent: isIncremental ? parentInfo.parentId : options?.parentId,
|
|
79
|
+
ancestors: isIncremental
|
|
80
|
+
? [...(deltaManifest.chainDepth > 1
|
|
81
|
+
? (await getChainAncestors(parentInfo.parentId))
|
|
82
|
+
: []), parentInfo.parentId]
|
|
83
|
+
: options?.parentId
|
|
84
|
+
? [...(snapshot.chain?.ancestors ?? []), options.parentId]
|
|
85
|
+
: [],
|
|
53
86
|
};
|
|
54
|
-
// Step
|
|
55
|
-
|
|
56
|
-
|
|
87
|
+
// Step 8: Pack the archive (incremental or full)
|
|
88
|
+
let archiveFileMap;
|
|
89
|
+
if (isIncremental && deltaResult && deltaManifest) {
|
|
90
|
+
archiveFileMap = packDelta(snapshot, deltaManifest, deltaResult.changedFiles);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
archiveFileMap = packSnapshot(snapshot);
|
|
94
|
+
}
|
|
95
|
+
// Step 9: Compute checksum and finalize
|
|
96
|
+
const firstArchive = packToArchive(archiveFileMap);
|
|
57
97
|
const checksum = computeChecksum(firstArchive);
|
|
58
|
-
// Step 5: Update manifest with checksum and size, then re-pack
|
|
59
98
|
snapshot.manifest.checksum = checksum;
|
|
60
99
|
snapshot.manifest.size = firstArchive.length;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
// Re-pack with updated manifest
|
|
101
|
+
if (isIncremental && deltaResult && deltaManifest) {
|
|
102
|
+
archiveFileMap.set('manifest.json', Buffer.from(JSON.stringify(snapshot.manifest, null, 2)));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
archiveFileMap = packSnapshot(snapshot);
|
|
106
|
+
}
|
|
107
|
+
const finalArchive = packToArchive(archiveFileMap);
|
|
108
|
+
// Step 10: Encrypt
|
|
64
109
|
const encrypted = await encrypt(finalArchive, passphrase);
|
|
65
|
-
// Step
|
|
110
|
+
// Step 11: Store
|
|
66
111
|
const filename = snapshotFilename(snapshotId);
|
|
67
112
|
await storage.put(filename, encrypted);
|
|
68
|
-
// Step
|
|
113
|
+
// Step 12: Update local index
|
|
69
114
|
await addToIndex({
|
|
70
115
|
id: snapshotId,
|
|
71
116
|
timestamp: now,
|
|
@@ -81,9 +126,29 @@ export async function createSnapshot(adapter, storage, passphrase, options) {
|
|
|
81
126
|
filename,
|
|
82
127
|
archiveSize: finalArchive.length,
|
|
83
128
|
encryptedSize: encrypted.length,
|
|
84
|
-
fileCount:
|
|
129
|
+
fileCount: archiveFileMap.size,
|
|
130
|
+
incremental: isIncremental,
|
|
131
|
+
delta: isIncremental && deltaManifest
|
|
132
|
+
? {
|
|
133
|
+
added: deltaManifest.stats.added,
|
|
134
|
+
modified: deltaManifest.stats.modified,
|
|
135
|
+
removed: deltaManifest.stats.removed,
|
|
136
|
+
unchanged: deltaManifest.stats.unchanged,
|
|
137
|
+
bytesSaved: deltaManifest.stats.bytesSaved,
|
|
138
|
+
chainDepth: deltaManifest.chainDepth,
|
|
139
|
+
}
|
|
140
|
+
: undefined,
|
|
85
141
|
};
|
|
86
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Helper: get the chain ancestors for a given snapshot ID.
|
|
145
|
+
*/
|
|
146
|
+
async function getChainAncestors(snapshotId) {
|
|
147
|
+
const index = await import('./index-file.js');
|
|
148
|
+
// We don't need to decrypt the full chain — just track IDs from the index
|
|
149
|
+
// For now, return empty. The chain info is primarily in meta/snapshot-chain.json
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
87
152
|
/**
|
|
88
153
|
* Get the latest snapshot ID from the index.
|
|
89
154
|
*/
|
package/dist/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Storage module re-exports
|
|
3
3
|
*/
|
|
4
4
|
export { LocalStorageBackend } from './local.js';
|
|
5
|
+
export { S3Storage, S3Error } from './s3.js';
|
|
6
|
+
export type { S3StorageOptions } from './s3.js';
|
|
5
7
|
export { resolveStorage } from './resolve.js';
|
|
6
8
|
export type { StorageBackend } from './interface.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/storage/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKnE;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CA6BtE"}
|