@indigoai-us/hq-cloud 6.11.12 → 6.11.13
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/bin/sync-runner-company.d.ts +35 -0
- package/dist/bin/sync-runner-company.d.ts.map +1 -0
- package/dist/bin/sync-runner-company.js +290 -0
- package/dist/bin/sync-runner-company.js.map +1 -0
- package/dist/bin/sync-runner-events.d.ts +12 -0
- package/dist/bin/sync-runner-events.d.ts.map +1 -0
- package/dist/bin/sync-runner-events.js +12 -0
- package/dist/bin/sync-runner-events.js.map +1 -0
- package/dist/bin/sync-runner-planning.d.ts +53 -0
- package/dist/bin/sync-runner-planning.d.ts.map +1 -0
- package/dist/bin/sync-runner-planning.js +59 -0
- package/dist/bin/sync-runner-planning.js.map +1 -0
- package/dist/bin/sync-runner-rollup.d.ts +24 -0
- package/dist/bin/sync-runner-rollup.d.ts.map +1 -0
- package/dist/bin/sync-runner-rollup.js +46 -0
- package/dist/bin/sync-runner-rollup.js.map +1 -0
- package/dist/bin/sync-runner-telemetry.d.ts +5 -0
- package/dist/bin/sync-runner-telemetry.d.ts.map +1 -0
- package/dist/bin/sync-runner-telemetry.js +5 -0
- package/dist/bin/sync-runner-telemetry.js.map +1 -0
- package/dist/bin/sync-runner-watch-loop.d.ts +17 -0
- package/dist/bin/sync-runner-watch-loop.d.ts.map +1 -0
- package/dist/bin/sync-runner-watch-loop.js +372 -0
- package/dist/bin/sync-runner-watch-loop.js.map +1 -0
- package/dist/bin/sync-runner-watch-routes.d.ts +25 -0
- package/dist/bin/sync-runner-watch-routes.d.ts.map +1 -0
- package/dist/bin/sync-runner-watch-routes.js +74 -0
- package/dist/bin/sync-runner-watch-routes.js.map +1 -0
- package/dist/bin/sync-runner.d.ts +3 -54
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js +73 -1154
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/cli/reindex.d.ts.map +1 -1
- package/dist/cli/reindex.js +34 -17
- package/dist/cli/reindex.js.map +1 -1
- package/dist/cli/reindex.test.js +39 -5
- package/dist/cli/reindex.test.js.map +1 -1
- package/dist/cli/rescue-classify-ordering.test.js +17 -0
- package/dist/cli/rescue-classify-ordering.test.js.map +1 -1
- package/dist/cli/rescue-core.d.ts +45 -0
- package/dist/cli/rescue-core.d.ts.map +1 -1
- package/dist/cli/rescue-core.js +197 -170
- package/dist/cli/rescue-core.js.map +1 -1
- package/dist/cli/share.d.ts.map +1 -1
- package/dist/cli/share.js +224 -676
- package/dist/cli/share.js.map +1 -1
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +399 -726
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/sync.test.js +20 -0
- package/dist/cli/sync.test.js.map +1 -1
- package/dist/daemon-worker.d.ts +2 -2
- package/dist/daemon-worker.js +3 -3
- package/dist/daemon-worker.js.map +1 -1
- package/dist/object-io.js +1 -1
- package/dist/object-io.js.map +1 -1
- package/dist/remote-pull.d.ts +2 -2
- package/dist/remote-pull.d.ts.map +1 -1
- package/dist/remote-pull.js +23 -3
- package/dist/remote-pull.js.map +1 -1
- package/dist/remote-pull.test.js +24 -2
- package/dist/remote-pull.test.js.map +1 -1
- package/dist/sync/push-receiver.d.ts +6 -0
- package/dist/sync/push-receiver.d.ts.map +1 -1
- package/dist/sync/push-receiver.js +32 -2
- package/dist/sync/push-receiver.js.map +1 -1
- package/dist/sync/push-receiver.test.js +31 -0
- package/dist/sync/push-receiver.test.js.map +1 -1
- package/dist/sync-core.d.ts +27 -0
- package/dist/sync-core.d.ts.map +1 -0
- package/dist/sync-core.js +54 -0
- package/dist/sync-core.js.map +1 -0
- package/dist/vault-client.d.ts.map +1 -1
- package/dist/vault-client.js +284 -36
- package/dist/vault-client.js.map +1 -1
- package/dist/vault-client.test.js +59 -0
- package/dist/vault-client.test.js.map +1 -1
- package/dist/watcher.d.ts +2 -20
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +3 -113
- package/dist/watcher.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/sync-runner-company.ts +350 -0
- package/src/bin/sync-runner-events.ts +25 -0
- package/src/bin/sync-runner-planning.ts +121 -0
- package/src/bin/sync-runner-rollup.ts +72 -0
- package/src/bin/sync-runner-telemetry.ts +8 -0
- package/src/bin/sync-runner-watch-loop.ts +443 -0
- package/src/bin/sync-runner-watch-routes.ts +86 -0
- package/src/bin/sync-runner.ts +96 -1253
- package/src/cli/reindex.test.ts +41 -3
- package/src/cli/reindex.ts +35 -19
- package/src/cli/rescue-classify-ordering.test.ts +20 -0
- package/src/cli/rescue-core.ts +252 -176
- package/src/cli/share.ts +363 -705
- package/src/cli/sync.test.ts +25 -0
- package/src/cli/sync.ts +612 -802
- package/src/daemon-worker.ts +3 -3
- package/src/object-io.ts +1 -1
- package/src/remote-pull.test.ts +30 -1
- package/src/remote-pull.ts +29 -4
- package/src/sync/push-receiver.test.ts +35 -0
- package/src/sync/push-receiver.ts +41 -2
- package/src/sync-core.ts +58 -0
- package/src/vault-client.test.ts +74 -0
- package/src/vault-client.ts +395 -43
- package/src/watcher.ts +6 -141
package/src/watcher.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* File watcher — monitors HQ directory for changes
|
|
3
3
|
* Uses chokidar with debounced batching
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* to be passed in for entity-aware S3 operations.
|
|
5
|
+
* Active watcher path: TreeWatcher detects local changes, WatchPushDriver
|
|
6
|
+
* schedules pushes, and PushEventEmitter publishes typed push events.
|
|
8
7
|
*/
|
|
9
8
|
|
|
10
9
|
import * as fs from "fs";
|
|
@@ -12,12 +11,7 @@ import { createHash } from "node:crypto";
|
|
|
12
11
|
import { readFile, stat } from "node:fs/promises";
|
|
13
12
|
import * as path from "path";
|
|
14
13
|
import { watch } from "chokidar";
|
|
15
|
-
import
|
|
16
|
-
import type { EntityContext } from "./types.js";
|
|
17
|
-
import { createIgnoreFilter, isWithinSizeLimit } from "./ignore.js";
|
|
18
|
-
import { readJournal, writeJournal, hashFile, updateEntry } from "./journal.js";
|
|
19
|
-
import { uploadFile, deleteRemoteFile, toPosixKey } from "./s3.js";
|
|
20
|
-
import type { UploadAuthor } from "./s3.js";
|
|
14
|
+
import { createIgnoreFilter } from "./ignore.js";
|
|
21
15
|
import { isPersonalVaultExcluded } from "./personal-vault-exclusions.js";
|
|
22
16
|
import {
|
|
23
17
|
CONTINUITY_POINTER_REL,
|
|
@@ -205,141 +199,12 @@ export class WatchPushDriver {
|
|
|
205
199
|
}
|
|
206
200
|
}
|
|
207
201
|
|
|
208
|
-
interface PendingChange {
|
|
209
|
-
type: "add" | "change" | "unlink";
|
|
210
|
-
absolutePath: string;
|
|
211
|
-
relativePath: string;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export class SyncWatcher {
|
|
215
|
-
private watcher: FSWatcher | null = null;
|
|
216
|
-
private hqRoot: string;
|
|
217
|
-
private ctx: EntityContext;
|
|
218
|
-
private author?: UploadAuthor;
|
|
219
|
-
private shouldSync: (filePath: string, isDir?: boolean) => boolean;
|
|
220
|
-
private pendingChanges = new Map<string, PendingChange>();
|
|
221
|
-
private debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
222
|
-
private processing = false;
|
|
223
|
-
|
|
224
|
-
constructor(hqRoot: string, ctx: EntityContext, author?: UploadAuthor) {
|
|
225
|
-
this.hqRoot = hqRoot;
|
|
226
|
-
this.ctx = ctx;
|
|
227
|
-
this.author = author;
|
|
228
|
-
this.shouldSync = createIgnoreFilter(hqRoot);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
start(): void {
|
|
232
|
-
if (this.watcher) return;
|
|
233
|
-
|
|
234
|
-
this.watcher = watch(this.hqRoot, {
|
|
235
|
-
// See toChokidarIgnored: chokidar's pre-stat descent probe has no stats
|
|
236
|
-
// hint, so a naive file-verdict prunes intermediate allowlist dirs
|
|
237
|
-
// before descending to their in-scope leaves. Keep a statless probe
|
|
238
|
-
// when EITHER the file or directory reading would survive the filter.
|
|
239
|
-
ignored: toChokidarIgnored(this.shouldSync, this.hqRoot),
|
|
240
|
-
persistent: true,
|
|
241
|
-
ignoreInitial: true,
|
|
242
|
-
awaitWriteFinish: {
|
|
243
|
-
stabilityThreshold: 500,
|
|
244
|
-
pollInterval: 100,
|
|
245
|
-
},
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
this.watcher
|
|
249
|
-
.on("add", (p) => this.queueChange("add", p))
|
|
250
|
-
.on("change", (p) => this.queueChange("change", p))
|
|
251
|
-
.on("unlink", (p) => this.queueChange("unlink", p))
|
|
252
|
-
.on("error", (err) => console.error("Watcher error:", err));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
stop(): void {
|
|
256
|
-
if (this.watcher) {
|
|
257
|
-
this.watcher.close();
|
|
258
|
-
this.watcher = null;
|
|
259
|
-
}
|
|
260
|
-
if (this.debounceTimer) {
|
|
261
|
-
clearTimeout(this.debounceTimer);
|
|
262
|
-
this.debounceTimer = null;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
private queueChange(type: "add" | "change" | "unlink", absolutePath: string): void {
|
|
267
|
-
const relativePath = toPosixKey(path.relative(this.hqRoot, absolutePath));
|
|
268
|
-
|
|
269
|
-
// Skip files that exceed size limit
|
|
270
|
-
if (type !== "unlink" && !isWithinSizeLimit(absolutePath)) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
this.pendingChanges.set(relativePath, {
|
|
275
|
-
type,
|
|
276
|
-
absolutePath,
|
|
277
|
-
relativePath,
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// Debounce: wait for DEBOUNCE_MS of quiet before processing
|
|
281
|
-
if (this.debounceTimer) {
|
|
282
|
-
clearTimeout(this.debounceTimer);
|
|
283
|
-
}
|
|
284
|
-
this.debounceTimer = setTimeout(() => this.flush(), DEBOUNCE_MS);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
private async flush(): Promise<void> {
|
|
288
|
-
if (this.processing || this.pendingChanges.size === 0) return;
|
|
289
|
-
this.processing = true;
|
|
290
|
-
|
|
291
|
-
const batch = new Map(this.pendingChanges);
|
|
292
|
-
this.pendingChanges.clear();
|
|
293
|
-
|
|
294
|
-
const journal = readJournal(this.ctx.slug);
|
|
295
|
-
|
|
296
|
-
for (const [relativePath, change] of batch) {
|
|
297
|
-
try {
|
|
298
|
-
if (change.type === "unlink") {
|
|
299
|
-
await deleteRemoteFile(this.ctx, relativePath);
|
|
300
|
-
delete journal.files[relativePath];
|
|
301
|
-
} else {
|
|
302
|
-
const hash = hashFile(change.absolutePath);
|
|
303
|
-
const stat = fs.statSync(change.absolutePath);
|
|
304
|
-
|
|
305
|
-
// Skip if unchanged from last sync
|
|
306
|
-
const existing = journal.files[relativePath];
|
|
307
|
-
if (existing && existing.hash === hash) continue;
|
|
308
|
-
|
|
309
|
-
const { etag } = this.author
|
|
310
|
-
? await uploadFile(this.ctx, change.absolutePath, relativePath, this.author)
|
|
311
|
-
: await uploadFile(this.ctx, change.absolutePath, relativePath);
|
|
312
|
-
updateEntry(journal, relativePath, hash, stat.size, "up", etag);
|
|
313
|
-
}
|
|
314
|
-
} catch (err) {
|
|
315
|
-
console.error(
|
|
316
|
-
`Sync error [${relativePath}]:`,
|
|
317
|
-
err instanceof Error ? err.message : err
|
|
318
|
-
);
|
|
319
|
-
// Re-queue failed changes
|
|
320
|
-
this.pendingChanges.set(relativePath, change);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// See cli/sync.ts: stamp lastSync on every flush so the indicator
|
|
325
|
-
// ticks even when all changes were re-queued or no-op.
|
|
326
|
-
journal.lastSync = new Date().toISOString();
|
|
327
|
-
writeJournal(this.ctx.slug, journal);
|
|
328
|
-
this.processing = false;
|
|
329
|
-
|
|
330
|
-
// Process any changes that came in while we were flushing
|
|
331
|
-
if (this.pendingChanges.size > 0) {
|
|
332
|
-
this.debounceTimer = setTimeout(() => this.flush(), DEBOUNCE_MS);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
202
|
// ---------------------------------------------------------------------------
|
|
338
203
|
// US-002 — debounced, ignore-aware, exclusion-aware tree watcher.
|
|
339
204
|
//
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
//
|
|
205
|
+
// TreeWatcher is a pure change detector: it emits a single debounced `changed`
|
|
206
|
+
// callback after a quiet window and never touches S3 itself. US-003 wires that
|
|
207
|
+
// callback to a targeted push.
|
|
343
208
|
//
|
|
344
209
|
// The emit decision composes the SAME filter stack the push walk uses, so a
|
|
345
210
|
// path that the push would skip never wakes the watcher:
|