@factiii/runner 0.13.0 → 0.13.1
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/cli.js +44 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -17685,6 +17685,8 @@ var NOISE_GLOBS = ["**/.DS_Store", "**/4913", "**/*~", "**/.#*", "**/#*#"];
|
|
|
17685
17685
|
var MAX_BATCH = 200;
|
|
17686
17686
|
var FLUSH_MS = 120;
|
|
17687
17687
|
var SELF_WRITE_MS = 2e3;
|
|
17688
|
+
var RETRY_MIN_MS = 500;
|
|
17689
|
+
var RETRY_MAX_MS = 15e3;
|
|
17688
17690
|
var dynamicImport = new Function("s", "return import(s)");
|
|
17689
17691
|
var importFs = new Function("s", "return import(s)");
|
|
17690
17692
|
async function resolveReal(path23) {
|
|
@@ -17715,13 +17717,16 @@ var WorkspaceWatcher = class {
|
|
|
17715
17717
|
* A no-git card's root is the space dir itself, which also
|
|
17716
17718
|
* holds the runner's own bookkeeping.
|
|
17717
17719
|
*/
|
|
17718
|
-
constructor(root, emit, exclude = []) {
|
|
17720
|
+
constructor(root, emit, exclude = [], subscribeImpl) {
|
|
17719
17721
|
this.root = root;
|
|
17720
17722
|
this.emit = emit;
|
|
17721
17723
|
this.exclude = exclude;
|
|
17724
|
+
this.subscribeImpl = subscribeImpl;
|
|
17722
17725
|
this.sub = null;
|
|
17723
17726
|
this.pending = emptyPending();
|
|
17724
17727
|
this.flushTimer = null;
|
|
17728
|
+
this.retryTimer = null;
|
|
17729
|
+
this.retryDelay = RETRY_MIN_MS;
|
|
17725
17730
|
/** path -> expiry. Events for these are ours (the editor just saved) and must
|
|
17726
17731
|
* not come back as "changed on disk". */
|
|
17727
17732
|
this.selfWrites = /* @__PURE__ */ new Map();
|
|
@@ -17731,11 +17736,11 @@ var WorkspaceWatcher = class {
|
|
|
17731
17736
|
/** Fire-and-forget: callers treat starting a watch as synchronous, and
|
|
17732
17737
|
* nothing can be emitted before `subscribe` resolves anyway. */
|
|
17733
17738
|
start() {
|
|
17734
|
-
if (this.sub || this.closed) return;
|
|
17739
|
+
if (this.sub || this.closed || this.retryTimer) return;
|
|
17735
17740
|
void this.open();
|
|
17736
17741
|
}
|
|
17737
17742
|
async open() {
|
|
17738
|
-
const subscribe = await getSubscribe();
|
|
17743
|
+
const subscribe = this.subscribeImpl ?? await getSubscribe();
|
|
17739
17744
|
if (!subscribe) return this.stop();
|
|
17740
17745
|
this.watchRoot = await resolveReal(this.root);
|
|
17741
17746
|
const exclude = await Promise.all(this.exclude.map(resolveReal));
|
|
@@ -17743,7 +17748,7 @@ var WorkspaceWatcher = class {
|
|
|
17743
17748
|
const sub = await subscribe(
|
|
17744
17749
|
this.watchRoot,
|
|
17745
17750
|
(err, events) => {
|
|
17746
|
-
if (err) return this.
|
|
17751
|
+
if (err) return this.retry();
|
|
17747
17752
|
for (const event of events) this.onEvent(event);
|
|
17748
17753
|
},
|
|
17749
17754
|
// Prunes the walk itself, so a pruned tree is never enumerated.
|
|
@@ -17760,10 +17765,39 @@ var WorkspaceWatcher = class {
|
|
|
17760
17765
|
return;
|
|
17761
17766
|
}
|
|
17762
17767
|
this.sub = sub;
|
|
17768
|
+
this.retryDelay = RETRY_MIN_MS;
|
|
17763
17769
|
} catch {
|
|
17764
|
-
this.
|
|
17770
|
+
this.retry();
|
|
17765
17771
|
}
|
|
17766
17772
|
}
|
|
17773
|
+
/**
|
|
17774
|
+
* Re-subscribe after the OS dropped the watch — a remount, a wake from
|
|
17775
|
+
* sleep, an inotify limit easing. Treating those as terminal left a runner
|
|
17776
|
+
* watching nothing for the rest of its life. `resync` on the way back up,
|
|
17777
|
+
* since whatever changed while it was down produced no events.
|
|
17778
|
+
*/
|
|
17779
|
+
retry() {
|
|
17780
|
+
if (this.closed || this.retryTimer) return;
|
|
17781
|
+
const sub = this.sub;
|
|
17782
|
+
this.sub = null;
|
|
17783
|
+
if (sub) void sub.unsubscribe().catch(() => void 0);
|
|
17784
|
+
const delay = this.retryDelay;
|
|
17785
|
+
this.retryDelay = Math.min(this.retryDelay * 2, RETRY_MAX_MS);
|
|
17786
|
+
this.retryTimer = setTimeout(() => {
|
|
17787
|
+
this.retryTimer = null;
|
|
17788
|
+
if (this.closed) return;
|
|
17789
|
+
void this.open().then(() => {
|
|
17790
|
+
if (this.sub) {
|
|
17791
|
+
this.emit({
|
|
17792
|
+
added: [],
|
|
17793
|
+
changed: [],
|
|
17794
|
+
removed: [],
|
|
17795
|
+
resync: true
|
|
17796
|
+
});
|
|
17797
|
+
}
|
|
17798
|
+
});
|
|
17799
|
+
}, delay);
|
|
17800
|
+
}
|
|
17767
17801
|
/** Give up and say so once, so the UI falls back to manual refresh rather
|
|
17768
17802
|
* than showing a silently frozen tree. */
|
|
17769
17803
|
stop() {
|
|
@@ -17799,6 +17833,10 @@ var WorkspaceWatcher = class {
|
|
|
17799
17833
|
this.flushTimer = null;
|
|
17800
17834
|
}
|
|
17801
17835
|
this.pending = emptyPending();
|
|
17836
|
+
if (this.retryTimer) {
|
|
17837
|
+
clearTimeout(this.retryTimer);
|
|
17838
|
+
this.retryTimer = null;
|
|
17839
|
+
}
|
|
17802
17840
|
this.selfWrites.clear();
|
|
17803
17841
|
const sub = this.sub;
|
|
17804
17842
|
this.sub = null;
|
|
@@ -19936,7 +19974,6 @@ var ScratchpadStore = class {
|
|
|
19936
19974
|
*/
|
|
19937
19975
|
async list() {
|
|
19938
19976
|
const dir = this.dir();
|
|
19939
|
-
this.startWatching();
|
|
19940
19977
|
const out = await this.target().run([
|
|
19941
19978
|
"sh",
|
|
19942
19979
|
"-c",
|
|
@@ -19946,6 +19983,7 @@ var ScratchpadStore = class {
|
|
|
19946
19983
|
echo "$meta $f"
|
|
19947
19984
|
done | LC_ALL=C sort -rn | head -n ${SCRATCHPAD_MAX_ITEMS}`
|
|
19948
19985
|
]);
|
|
19986
|
+
this.startWatching();
|
|
19949
19987
|
const items = [];
|
|
19950
19988
|
for (const line of out.split("\n")) {
|
|
19951
19989
|
const match = /^(\d+) (\d+) (.+)$/.exec(line);
|
package/package.json
CHANGED