@seedvault/cli 0.4.3 → 0.4.4
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/dist/sv.js +43 -14
- package/package.json +1 -1
package/dist/sv.js
CHANGED
|
@@ -158,6 +158,9 @@ function createClient(serverUrl, token) {
|
|
|
158
158
|
if (opts.contentType) {
|
|
159
159
|
headers["Content-Type"] = opts.contentType;
|
|
160
160
|
}
|
|
161
|
+
if (opts.extraHeaders) {
|
|
162
|
+
Object.assign(headers, opts.extraHeaders);
|
|
163
|
+
}
|
|
161
164
|
const res = await fetch(`${base}${path}`, {
|
|
162
165
|
method,
|
|
163
166
|
headers,
|
|
@@ -199,10 +202,16 @@ function createClient(serverUrl, token) {
|
|
|
199
202
|
const res = await request("GET", "/v1/contributors");
|
|
200
203
|
return res.json();
|
|
201
204
|
},
|
|
202
|
-
async putFile(username, path, content) {
|
|
205
|
+
async putFile(username, path, content, opts) {
|
|
206
|
+
const extraHeaders = {};
|
|
207
|
+
if (opts?.originCtime)
|
|
208
|
+
extraHeaders["X-Origin-Ctime"] = opts.originCtime;
|
|
209
|
+
if (opts?.originMtime)
|
|
210
|
+
extraHeaders["X-Origin-Mtime"] = opts.originMtime;
|
|
203
211
|
const res = await request("PUT", `/v1/files/${username}/${encodePath(path)}`, {
|
|
204
212
|
body: content,
|
|
205
|
-
contentType: "text/markdown"
|
|
213
|
+
contentType: "text/markdown",
|
|
214
|
+
extraHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined
|
|
206
215
|
});
|
|
207
216
|
return res.json();
|
|
208
217
|
},
|
|
@@ -2148,7 +2157,8 @@ class RetryQueue {
|
|
|
2148
2157
|
const op = this.items[0];
|
|
2149
2158
|
try {
|
|
2150
2159
|
if (op.type === "put" && op.content !== null) {
|
|
2151
|
-
|
|
2160
|
+
const opts = op.originCtime || op.originMtime ? { originCtime: op.originCtime ?? undefined, originMtime: op.originMtime ?? undefined } : undefined;
|
|
2161
|
+
await this.client.putFile(op.username, op.serverPath, op.content, opts);
|
|
2152
2162
|
} else if (op.type === "delete") {
|
|
2153
2163
|
await this.client.deleteFile(op.username, op.serverPath);
|
|
2154
2164
|
}
|
|
@@ -2228,7 +2238,9 @@ class Syncer {
|
|
|
2228
2238
|
username: this.username,
|
|
2229
2239
|
serverPath: f.path,
|
|
2230
2240
|
content: null,
|
|
2231
|
-
queuedAt: new Date().toISOString()
|
|
2241
|
+
queuedAt: new Date().toISOString(),
|
|
2242
|
+
originCtime: null,
|
|
2243
|
+
originMtime: null
|
|
2232
2244
|
});
|
|
2233
2245
|
}
|
|
2234
2246
|
});
|
|
@@ -2244,7 +2256,7 @@ class Syncer {
|
|
|
2244
2256
|
const { files: serverFiles } = await this.client.listFiles(this.username, collection.name + "/");
|
|
2245
2257
|
const serverMap = new Map;
|
|
2246
2258
|
for (const f of serverFiles) {
|
|
2247
|
-
serverMap.set(f.path, f
|
|
2259
|
+
serverMap.set(f.path, f);
|
|
2248
2260
|
}
|
|
2249
2261
|
const localFiles = await walkMd(collection.path);
|
|
2250
2262
|
const localServerPaths = new Set;
|
|
@@ -2253,8 +2265,9 @@ class Syncer {
|
|
|
2253
2265
|
const relPath = toPosixPath(relative5(collection.path, localFile.path));
|
|
2254
2266
|
const serverPath = `${collection.name}/${relPath}`;
|
|
2255
2267
|
localServerPaths.add(serverPath);
|
|
2256
|
-
const
|
|
2257
|
-
if (
|
|
2268
|
+
const serverEntry = serverMap.get(serverPath);
|
|
2269
|
+
if (serverEntry) {
|
|
2270
|
+
const serverMod = serverEntry.originMtime || serverEntry.modifiedAt;
|
|
2258
2271
|
const serverDate = new Date(serverMod).getTime();
|
|
2259
2272
|
const localDate = localFile.mtimeMs;
|
|
2260
2273
|
if (localDate <= serverDate) {
|
|
@@ -2263,11 +2276,16 @@ class Syncer {
|
|
|
2263
2276
|
}
|
|
2264
2277
|
}
|
|
2265
2278
|
const content = await readFile(localFile.path, "utf-8");
|
|
2266
|
-
|
|
2279
|
+
const originCtime = new Date(localFile.birthtimeMs).toISOString();
|
|
2280
|
+
const originMtime = new Date(localFile.mtimeMs).toISOString();
|
|
2281
|
+
toUpload.push({ serverPath, content, originCtime, originMtime });
|
|
2267
2282
|
}
|
|
2268
2283
|
await pooled(toUpload, SYNC_CONCURRENCY, async (item) => {
|
|
2269
2284
|
try {
|
|
2270
|
-
await this.client.putFile(this.username, item.serverPath, item.content
|
|
2285
|
+
await this.client.putFile(this.username, item.serverPath, item.content, {
|
|
2286
|
+
originCtime: item.originCtime,
|
|
2287
|
+
originMtime: item.originMtime
|
|
2288
|
+
});
|
|
2271
2289
|
uploaded++;
|
|
2272
2290
|
} catch {
|
|
2273
2291
|
this.queue.enqueue({
|
|
@@ -2275,7 +2293,9 @@ class Syncer {
|
|
|
2275
2293
|
username: this.username,
|
|
2276
2294
|
serverPath: item.serverPath,
|
|
2277
2295
|
content: item.content,
|
|
2278
|
-
queuedAt: new Date().toISOString()
|
|
2296
|
+
queuedAt: new Date().toISOString(),
|
|
2297
|
+
originCtime: item.originCtime,
|
|
2298
|
+
originMtime: item.originMtime
|
|
2279
2299
|
});
|
|
2280
2300
|
}
|
|
2281
2301
|
});
|
|
@@ -2329,14 +2349,21 @@ class Syncer {
|
|
|
2329
2349
|
}
|
|
2330
2350
|
async handleEvent(event) {
|
|
2331
2351
|
if (event.type === "add" || event.type === "change") {
|
|
2332
|
-
const content = await
|
|
2352
|
+
const [content, s] = await Promise.all([
|
|
2353
|
+
readFile(event.localPath, "utf-8"),
|
|
2354
|
+
stat4(event.localPath)
|
|
2355
|
+
]);
|
|
2356
|
+
const originCtime = new Date(s.birthtimeMs).toISOString();
|
|
2357
|
+
const originMtime = new Date(s.mtimeMs).toISOString();
|
|
2333
2358
|
this.log(`PUT ${event.serverPath} (${content.length} bytes)`);
|
|
2334
2359
|
this.queue.enqueue({
|
|
2335
2360
|
type: "put",
|
|
2336
2361
|
username: this.username,
|
|
2337
2362
|
serverPath: event.serverPath,
|
|
2338
2363
|
content,
|
|
2339
|
-
queuedAt: new Date().toISOString()
|
|
2364
|
+
queuedAt: new Date().toISOString(),
|
|
2365
|
+
originCtime,
|
|
2366
|
+
originMtime
|
|
2340
2367
|
});
|
|
2341
2368
|
} else if (event.type === "unlink") {
|
|
2342
2369
|
this.log(`DELETE ${event.serverPath}`);
|
|
@@ -2345,7 +2372,9 @@ class Syncer {
|
|
|
2345
2372
|
username: this.username,
|
|
2346
2373
|
serverPath: event.serverPath,
|
|
2347
2374
|
content: null,
|
|
2348
|
-
queuedAt: new Date().toISOString()
|
|
2375
|
+
queuedAt: new Date().toISOString(),
|
|
2376
|
+
originCtime: null,
|
|
2377
|
+
originMtime: null
|
|
2349
2378
|
});
|
|
2350
2379
|
}
|
|
2351
2380
|
}
|
|
@@ -2384,7 +2413,7 @@ async function walkDirRecursive(dir, results) {
|
|
|
2384
2413
|
await walkDirRecursive(full, results);
|
|
2385
2414
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
2386
2415
|
const s = await stat4(full);
|
|
2387
|
-
results.push({ path: full, mtimeMs: s.mtimeMs });
|
|
2416
|
+
results.push({ path: full, mtimeMs: s.mtimeMs, birthtimeMs: s.birthtimeMs });
|
|
2388
2417
|
}
|
|
2389
2418
|
}
|
|
2390
2419
|
}
|