@fnndsc/cumin 3.16.1 → 3.17.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.
@@ -3,12 +3,13 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- export { ListCache, listCache_get } from './listCache.js';
6
+ export { ListCache, listCache_get, LIST_CACHE_SIGNAL_BACKED_TTL_MS, LIST_CACHE_SIGNAL_FREE_TTL_MS, LIST_CACHE_PLUGIN_INDEX_TTL_MS, LIST_CACHE_MAX_ENTRIES, } from './listCache.js';
7
7
  export type { CacheStats, CacheResult, CacheOptions, ListCacheSnapshot, ListCacheEntrySnapshot } from './listCache.js';
8
8
  export { listCheckpointPath_get, listCheckpoint_restore, listCheckpoint_save, listCheckpoint_watch, } from './listCheckpoint.js';
9
9
  export type { ListCheckpointRestoreResult } from './listCheckpoint.js';
10
- export { ProcCache, procCache_get, status_isTerminal, feed_isActive, feedTopology_changed, PROC_TERMINAL_STATUSES } from './procCache.js';
11
- export type { ProcInstance, ProcFeed, ProcFeedScopeCounts, ProcWarmupProgress, ProcCacheState, ProcCacheLifecycle, ProcCacheSnapshot, ProcFeedSnapshot, ProcCacheChange, ProcCacheListener, } from './procCache.js';
10
+ export { listingsForFeeds_note, listingsForFeeds_drop, listingsForRoster_note, listingInvalidation_flush, listingInvalidation_reset, LISTING_INVALIDATION_WINDOW_MS, } from './listingInvalidation.js';
11
+ export { ProcCache, procCache_get, status_isTerminal, feed_isActive, feedTopology_changed, PROC_TERMINAL_STATUSES, PROC_ARRIVAL_TTL_MS } from './procCache.js';
12
+ export type { RosterFolders, ProcInstance, ProcFeed, ProcFeedScopeCounts, ProcWarmupProgress, ProcFeedLoadProgress, ProcCacheState, ProcCacheLifecycle, ProcCacheSnapshot, ProcFeedSnapshot, ProcCacheChange, ProcCacheListener, } from './procCache.js';
12
13
  export type { ProcPromptState, ProcPromptProgress } from '@fnndsc/menu';
13
14
  export { procCheckpointPath_get, procCheckpointDir_get, procCheckpoint_restore, procCheckpoint_save, procCheckpointFeed_save, procCheckpointRoster_save, procCheckpoint_watch, } from './procCheckpoint.js';
14
15
  export type { ProcCheckpointRestoreResult } from './procCheckpoint.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.procCheckpoint_watch = exports.procCheckpointRoster_save = exports.procCheckpointFeed_save = exports.procCheckpoint_save = exports.procCheckpoint_restore = exports.procCheckpointDir_get = exports.procCheckpointPath_get = exports.PROC_TERMINAL_STATUSES = exports.feedTopology_changed = exports.feed_isActive = exports.status_isTerminal = exports.procCache_get = exports.ProcCache = exports.listCheckpoint_watch = exports.listCheckpoint_save = exports.listCheckpoint_restore = exports.listCheckpointPath_get = exports.listCache_get = exports.ListCache = void 0;
3
+ exports.procCheckpoint_watch = exports.procCheckpointRoster_save = exports.procCheckpointFeed_save = exports.procCheckpoint_save = exports.procCheckpoint_restore = exports.procCheckpointDir_get = exports.procCheckpointPath_get = exports.PROC_ARRIVAL_TTL_MS = exports.PROC_TERMINAL_STATUSES = exports.feedTopology_changed = exports.feed_isActive = exports.status_isTerminal = exports.procCache_get = exports.ProcCache = exports.LISTING_INVALIDATION_WINDOW_MS = exports.listingInvalidation_reset = exports.listingInvalidation_flush = exports.listingsForRoster_note = exports.listingsForFeeds_drop = exports.listingsForFeeds_note = exports.listCheckpoint_watch = exports.listCheckpoint_save = exports.listCheckpoint_restore = exports.listCheckpointPath_get = exports.LIST_CACHE_MAX_ENTRIES = exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS = exports.LIST_CACHE_SIGNAL_FREE_TTL_MS = exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS = exports.listCache_get = exports.ListCache = void 0;
4
4
  /**
5
5
  * @file Cache module exports.
6
6
  *
@@ -9,11 +9,22 @@ exports.procCheckpoint_watch = exports.procCheckpointRoster_save = exports.procC
9
9
  var listCache_js_1 = require("./listCache.js");
10
10
  Object.defineProperty(exports, "ListCache", { enumerable: true, get: function () { return listCache_js_1.ListCache; } });
11
11
  Object.defineProperty(exports, "listCache_get", { enumerable: true, get: function () { return listCache_js_1.listCache_get; } });
12
+ Object.defineProperty(exports, "LIST_CACHE_SIGNAL_BACKED_TTL_MS", { enumerable: true, get: function () { return listCache_js_1.LIST_CACHE_SIGNAL_BACKED_TTL_MS; } });
13
+ Object.defineProperty(exports, "LIST_CACHE_SIGNAL_FREE_TTL_MS", { enumerable: true, get: function () { return listCache_js_1.LIST_CACHE_SIGNAL_FREE_TTL_MS; } });
14
+ Object.defineProperty(exports, "LIST_CACHE_PLUGIN_INDEX_TTL_MS", { enumerable: true, get: function () { return listCache_js_1.LIST_CACHE_PLUGIN_INDEX_TTL_MS; } });
15
+ Object.defineProperty(exports, "LIST_CACHE_MAX_ENTRIES", { enumerable: true, get: function () { return listCache_js_1.LIST_CACHE_MAX_ENTRIES; } });
12
16
  var listCheckpoint_js_1 = require("./listCheckpoint.js");
13
17
  Object.defineProperty(exports, "listCheckpointPath_get", { enumerable: true, get: function () { return listCheckpoint_js_1.listCheckpointPath_get; } });
14
18
  Object.defineProperty(exports, "listCheckpoint_restore", { enumerable: true, get: function () { return listCheckpoint_js_1.listCheckpoint_restore; } });
15
19
  Object.defineProperty(exports, "listCheckpoint_save", { enumerable: true, get: function () { return listCheckpoint_js_1.listCheckpoint_save; } });
16
20
  Object.defineProperty(exports, "listCheckpoint_watch", { enumerable: true, get: function () { return listCheckpoint_js_1.listCheckpoint_watch; } });
21
+ var listingInvalidation_js_1 = require("./listingInvalidation.js");
22
+ Object.defineProperty(exports, "listingsForFeeds_note", { enumerable: true, get: function () { return listingInvalidation_js_1.listingsForFeeds_note; } });
23
+ Object.defineProperty(exports, "listingsForFeeds_drop", { enumerable: true, get: function () { return listingInvalidation_js_1.listingsForFeeds_drop; } });
24
+ Object.defineProperty(exports, "listingsForRoster_note", { enumerable: true, get: function () { return listingInvalidation_js_1.listingsForRoster_note; } });
25
+ Object.defineProperty(exports, "listingInvalidation_flush", { enumerable: true, get: function () { return listingInvalidation_js_1.listingInvalidation_flush; } });
26
+ Object.defineProperty(exports, "listingInvalidation_reset", { enumerable: true, get: function () { return listingInvalidation_js_1.listingInvalidation_reset; } });
27
+ Object.defineProperty(exports, "LISTING_INVALIDATION_WINDOW_MS", { enumerable: true, get: function () { return listingInvalidation_js_1.LISTING_INVALIDATION_WINDOW_MS; } });
17
28
  var procCache_js_1 = require("./procCache.js");
18
29
  Object.defineProperty(exports, "ProcCache", { enumerable: true, get: function () { return procCache_js_1.ProcCache; } });
19
30
  Object.defineProperty(exports, "procCache_get", { enumerable: true, get: function () { return procCache_js_1.procCache_get; } });
@@ -21,6 +32,7 @@ Object.defineProperty(exports, "status_isTerminal", { enumerable: true, get: fun
21
32
  Object.defineProperty(exports, "feed_isActive", { enumerable: true, get: function () { return procCache_js_1.feed_isActive; } });
22
33
  Object.defineProperty(exports, "feedTopology_changed", { enumerable: true, get: function () { return procCache_js_1.feedTopology_changed; } });
23
34
  Object.defineProperty(exports, "PROC_TERMINAL_STATUSES", { enumerable: true, get: function () { return procCache_js_1.PROC_TERMINAL_STATUSES; } });
35
+ Object.defineProperty(exports, "PROC_ARRIVAL_TTL_MS", { enumerable: true, get: function () { return procCache_js_1.PROC_ARRIVAL_TTL_MS; } });
24
36
  var procCheckpoint_js_1 = require("./procCheckpoint.js");
25
37
  Object.defineProperty(exports, "procCheckpointPath_get", { enumerable: true, get: function () { return procCheckpoint_js_1.procCheckpointPath_get; } });
26
38
  Object.defineProperty(exports, "procCheckpointDir_get", { enumerable: true, get: function () { return procCheckpoint_js_1.procCheckpointDir_get; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,+CAA0D;AAAjD,yGAAA,SAAS,OAAA;AAAE,6GAAA,aAAa,OAAA;AAEjC,yDAK6B;AAJ3B,2HAAA,sBAAsB,OAAA;AACtB,2HAAA,sBAAsB,OAAA;AACtB,wHAAA,mBAAmB,OAAA;AACnB,yHAAA,oBAAoB,OAAA;AAGtB,+CAA0I;AAAjI,yGAAA,SAAS,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,oHAAA,oBAAoB,OAAA;AAAE,sHAAA,sBAAsB,OAAA;AAwBjH,yDAQ6B;AAP3B,2HAAA,sBAAsB,OAAA;AACtB,0HAAA,qBAAqB,OAAA;AACrB,2HAAA,sBAAsB,OAAA;AACtB,wHAAA,mBAAmB,OAAA;AACnB,4HAAA,uBAAuB,OAAA;AACvB,8HAAA,yBAAyB,OAAA;AACzB,yHAAA,oBAAoB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,+CAOwB;AANtB,yGAAA,SAAS,OAAA;AACT,6GAAA,aAAa,OAAA;AACb,+HAAA,+BAA+B,OAAA;AAC/B,6HAAA,6BAA6B,OAAA;AAC7B,8HAAA,8BAA8B,OAAA;AAC9B,sHAAA,sBAAsB,OAAA;AAGxB,yDAK6B;AAJ3B,2HAAA,sBAAsB,OAAA;AACtB,2HAAA,sBAAsB,OAAA;AACtB,wHAAA,mBAAmB,OAAA;AACnB,yHAAA,oBAAoB,OAAA;AAGtB,mEAOkC;AANhC,+HAAA,qBAAqB,OAAA;AACrB,+HAAA,qBAAqB,OAAA;AACrB,gIAAA,sBAAsB,OAAA;AACtB,mIAAA,yBAAyB,OAAA;AACzB,mIAAA,yBAAyB,OAAA;AACzB,wIAAA,8BAA8B,OAAA;AAEhC,+CAA+J;AAAtJ,yGAAA,SAAS,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,oHAAA,oBAAoB,OAAA;AAAE,sHAAA,sBAAsB,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AA0BtI,yDAQ6B;AAP3B,2HAAA,sBAAsB,OAAA;AACtB,0HAAA,qBAAqB,OAAA;AACrB,2HAAA,sBAAsB,OAAA;AACtB,wHAAA,mBAAmB,OAAA;AACnB,4HAAA,uBAAuB,OAAA;AACvB,8HAAA,yBAAyB,OAAA;AACzB,yHAAA,oBAAoB,OAAA"}
@@ -1,17 +1,22 @@
1
1
  /**
2
- * @file Enhanced Directory Listing Cache with TTL and dirty tracking.
2
+ * Lifetime for a path `/proc` reports movement on.
3
3
  *
4
- * Provides a singleton cache for directory listings to avoid redundant API calls
5
- * during tab completion and file operations. Features:
6
- * - TTL-based expiration (different TTLs per path pattern)
7
- * - Dirty flag tracking (local mutations mark cache as needing refresh)
8
- * - LRU eviction (bounded memory usage)
9
- * - Optimistic serving (serve stale cache while refreshing)
10
- *
11
- * Generic implementation - stores any data type keyed by path.
4
+ * Long by design: arrivals, departures and job completions mark these
5
+ * dirty as they happen, so the clock is a backstop against a missed
6
+ * notification rather than the mechanism.
7
+ */
8
+ export declare const LIST_CACHE_SIGNAL_BACKED_TTL_MS: number;
9
+ /** Lifetime for a path nothing reports movement on. */
10
+ export declare const LIST_CACHE_SIGNAL_FREE_TTL_MS: number;
11
+ /**
12
+ * Lifetime for the plugin and pipeline indexes.
12
13
  *
13
- * @module
14
+ * Registration is an administrative act on a CUBE, not something a
15
+ * session causes, and it happens on a scale of months.
14
16
  */
17
+ export declare const LIST_CACHE_PLUGIN_INDEX_TTL_MS: number;
18
+ /** How many path listings the cache retains before evicting the oldest. */
19
+ export declare const LIST_CACHE_MAX_ENTRIES: number;
15
20
  /**
16
21
  * Result returned by cache_get with freshness information.
17
22
  */
@@ -69,6 +74,8 @@ export interface CacheStats {
69
74
  entries: number;
70
75
  /** Estimated total memory usage in bytes. */
71
76
  totalSize: number;
77
+ /** Age of the oldest retained entry in milliseconds, or null when empty. */
78
+ oldestAge: number | null;
72
79
  }
73
80
  /**
74
81
  * Singleton cache for directory listings with TTL and dirty tracking.
@@ -112,10 +119,19 @@ export declare class ListCache {
112
119
  private cache;
113
120
  /** Maximum cache entries (LRU eviction). */
114
121
  private maxEntries;
115
- /** Default TTL for unconfigured paths (3 minutes). */
122
+ /** Lifetime for a path no configured prefix covers. */
116
123
  private defaultTTL;
117
- /** Path-specific TTL configuration. */
124
+ /**
125
+ * Prefix-keyed lifetimes, longest prefix winning.
126
+ *
127
+ * A path is governed by a signal or by a clock, never argued over by
128
+ * both. Where `/proc` reports movement, the clock is only a backstop
129
+ * against a missed notification and can be long. Where nothing reports,
130
+ * a guess is all that is available and it stays short.
131
+ */
118
132
  private ttlConfig;
133
+ /** Whether this session has already reported that the cache filled. */
134
+ private evictionReported;
119
135
  /** Cache statistics. */
120
136
  private stats;
121
137
  /** Listeners told after any mutation a persister would want to see. */
@@ -170,6 +186,15 @@ export declare class ListCache {
170
186
  * @param options - Optional TTL and dirty flag.
171
187
  */
172
188
  cache_set<T = unknown>(path: string, data: T, options?: CacheOptions): void;
189
+ /**
190
+ * Every path the cache currently holds.
191
+ *
192
+ * Returned as a snapshot so a caller may mark or invalidate while
193
+ * iterating without mutating the map underneath itself.
194
+ *
195
+ * @returns The cached paths, least recently used first.
196
+ */
197
+ paths_get(): string[];
173
198
  /**
174
199
  * Marks a cached path as dirty (needs refresh).
175
200
  * Used when local mutations might have changed the data.
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListCache = exports.LIST_CACHE_MAX_ENTRIES = exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS = exports.LIST_CACHE_SIGNAL_FREE_TTL_MS = exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS = void 0;
4
+ exports.listCache_get = listCache_get;
2
5
  /**
3
6
  * @file Enhanced Directory Listing Cache with TTL and dirty tracking.
4
7
  *
@@ -13,9 +16,26 @@
13
16
  *
14
17
  * @module
15
18
  */
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ListCache = void 0;
18
- exports.listCache_get = listCache_get;
19
+ const errorStack_1 = require("../error/errorStack");
20
+ /**
21
+ * Lifetime for a path `/proc` reports movement on.
22
+ *
23
+ * Long by design: arrivals, departures and job completions mark these
24
+ * dirty as they happen, so the clock is a backstop against a missed
25
+ * notification rather than the mechanism.
26
+ */
27
+ exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS = 60 * 60 * 1000;
28
+ /** Lifetime for a path nothing reports movement on. */
29
+ exports.LIST_CACHE_SIGNAL_FREE_TTL_MS = 3 * 60 * 1000;
30
+ /**
31
+ * Lifetime for the plugin and pipeline indexes.
32
+ *
33
+ * Registration is an administrative act on a CUBE, not something a
34
+ * session causes, and it happens on a scale of months.
35
+ */
36
+ exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS = 24 * 60 * 60 * 1000;
37
+ /** How many path listings the cache retains before evicting the oldest. */
38
+ exports.LIST_CACHE_MAX_ENTRIES = 500;
19
39
  /**
20
40
  * Singleton cache for directory listings with TTL and dirty tracking.
21
41
  *
@@ -109,16 +129,33 @@ class ListCache {
109
129
  /** Cache storage: path → entry. */
110
130
  this.cache = new Map();
111
131
  /** Maximum cache entries (LRU eviction). */
112
- this.maxEntries = 100;
113
- /** Default TTL for unconfigured paths (3 minutes). */
114
- this.defaultTTL = 3 * 60 * 1000;
115
- /** Path-specific TTL configuration. */
132
+ this.maxEntries = exports.LIST_CACHE_MAX_ENTRIES;
133
+ /** Lifetime for a path no configured prefix covers. */
134
+ this.defaultTTL = exports.LIST_CACHE_SIGNAL_FREE_TTL_MS;
135
+ /**
136
+ * Prefix-keyed lifetimes, longest prefix winning.
137
+ *
138
+ * A path is governed by a signal or by a clock, never argued over by
139
+ * both. Where `/proc` reports movement, the clock is only a backstop
140
+ * against a missed notification and can be long. Where nothing reports,
141
+ * a guess is all that is available and it stays short.
142
+ */
116
143
  this.ttlConfig = new Map([
117
- ['/PUBLIC', 10 * 60 * 1000], // 10 min (stable, public directory)
118
- ['/home', 5 * 60 * 1000], // 5 min (user home directories)
119
- ['/bin', 60 * 60 * 1000], // 1 hour (plugins rarely change)
120
- ['/feeds/*', 5 * 60 * 1000], // 5 min (feed outputs)
144
+ // Signal-covered: the roster and job-completion notifications decide
145
+ // when these go stale (see listing_dirtyByFeed).
146
+ ['/home', exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS],
147
+ ['/SHARED', exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS],
148
+ ['/PUBLIC', exports.LIST_CACHE_SIGNAL_BACKED_TTL_MS],
149
+ // Signal-free: nothing reports movement, so a clock is the only option.
150
+ // Plugin registration is an administrative act on a scale of months,
151
+ // so a day is closer to true than an hour; `refresh` is the escape
152
+ // hatch when an operator knows a plugin was just registered.
153
+ ['/bin', exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS],
154
+ ['/usr/share', exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS],
155
+ ['/PIPELINES', exports.LIST_CACHE_PLUGIN_INDEX_TTL_MS],
121
156
  ]);
157
+ /** Whether this session has already reported that the cache filled. */
158
+ this.evictionReported = false;
122
159
  /** Cache statistics. */
123
160
  this.stats = {
124
161
  hits: 0,
@@ -189,6 +226,17 @@ class ListCache {
189
226
  this.evict_lru();
190
227
  this.change_emit();
191
228
  }
229
+ /**
230
+ * Every path the cache currently holds.
231
+ *
232
+ * Returned as a snapshot so a caller may mark or invalidate while
233
+ * iterating without mutating the map underneath itself.
234
+ *
235
+ * @returns The cached paths, least recently used first.
236
+ */
237
+ paths_get() {
238
+ return Array.from(this.cache.keys());
239
+ }
192
240
  /**
193
241
  * Marks a cached path as dirty (needs refresh).
194
242
  * Used when local mutations might have changed the data.
@@ -270,18 +318,23 @@ class ListCache {
270
318
  * @returns TTL in milliseconds.
271
319
  */
272
320
  ttl_get(path) {
273
- if (this.ttlConfig.has(path)) {
274
- return this.ttlConfig.get(path);
275
- }
276
- for (const [pattern, ttl] of this.ttlConfig) {
277
- if (pattern.includes('*')) {
278
- const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
279
- if (regex.test(path)) {
280
- return ttl;
281
- }
321
+ const exact = this.ttlConfig.get(path);
322
+ if (exact !== undefined)
323
+ return exact;
324
+ // Longest matching prefix wins, so a deeper entry can override a
325
+ // shallower one. Matching is on whole segments: `/bindings` must not
326
+ // inherit `/bin`'s lifetime.
327
+ let bestLength = -1;
328
+ let bestTTL = this.defaultTTL;
329
+ for (const [prefix, ttl] of this.ttlConfig) {
330
+ if (!path.startsWith(prefix + '/'))
331
+ continue;
332
+ if (prefix.length > bestLength) {
333
+ bestLength = prefix.length;
334
+ bestTTL = ttl;
282
335
  }
283
336
  }
284
- return this.defaultTTL;
337
+ return bestTTL;
285
338
  }
286
339
  /**
287
340
  * Evicts oldest entries if cache exceeds max size.
@@ -292,6 +345,14 @@ class ListCache {
292
345
  if (oldestKey !== undefined) {
293
346
  this.cache.delete(oldestKey);
294
347
  this.stats.evictions++;
348
+ // An eviction is not an error, but it is worth knowing about: the
349
+ // dropped listing also leaves the checkpoint, so a restart comes
350
+ // back thinner than the session that wrote it. Said once, because
351
+ // a session that crosses the cap will cross it repeatedly.
352
+ if (!this.evictionReported) {
353
+ this.evictionReported = true;
354
+ errorStack_1.errorStack.stack_push('warning', `listing cache is full at ${this.maxEntries} paths; the least recently used listings are being dropped and will not survive to the next session`);
355
+ }
295
356
  }
296
357
  else {
297
358
  break; // Should never happen, but safety check
@@ -305,9 +366,13 @@ class ListCache {
305
366
  */
306
367
  stats_get() {
307
368
  let totalSize = 0;
369
+ let oldestTimestamp = null;
308
370
  for (const entry of this.cache.values()) {
309
371
  // Rough estimate: JSON string length
310
372
  totalSize += JSON.stringify(entry.data).length;
373
+ if (oldestTimestamp === null || entry.timestamp < oldestTimestamp) {
374
+ oldestTimestamp = entry.timestamp;
375
+ }
311
376
  }
312
377
  return {
313
378
  hits: this.stats.hits,
@@ -316,6 +381,7 @@ class ListCache {
316
381
  evictions: this.stats.evictions,
317
382
  entries: this.cache.size,
318
383
  totalSize,
384
+ oldestAge: oldestTimestamp === null ? null : Date.now() - oldestTimestamp,
319
385
  };
320
386
  }
321
387
  /**
@@ -327,6 +393,7 @@ class ListCache {
327
393
  this.stats.misses = 0;
328
394
  this.stats.staleHits = 0;
329
395
  this.stats.evictions = 0;
396
+ this.evictionReported = false;
330
397
  }
331
398
  }
332
399
  exports.ListCache = ListCache;
@@ -1 +1 @@
1
- {"version":3,"file":"listCache.js","sourceRoot":"","sources":["../../src/cache/listCache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAobH,sCAEC;AA5VD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAa,SAAS;IA8BpB;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAoB;QACrC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAS,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAEO,WAAW;QACjB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,EAAE,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,MAAM,OAAO,GAA6B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;;;OAQG;IACH,gBAAgB,CAAC,QAA2B;QAC1C,MAAM,IAAI,GAAqC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACnH,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACH;QAhFA,mCAAmC;QAC3B,UAAK,GAAqC,IAAI,GAAG,EAAE,CAAC;QAE5D,4CAA4C;QACpC,eAAU,GAAW,GAAG,CAAC;QAEjC,sDAAsD;QAC9C,eAAU,GAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAE3C,uCAAuC;QAC/B,cAAS,GAAwB,IAAI,GAAG,CAAC;YAC/C,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAM,oCAAoC;YACrE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAU,gCAAgC;YAClE,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAU,iCAAiC;YACnE,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAO,uBAAuB;SAC1D,CAAC,CAAC;QAEH,wBAAwB;QAChB,UAAK,GAAG;YACd,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb,CAAC;QACF,uEAAuE;QAC/D,cAAS,GAAoB,IAAI,GAAG,EAAE,CAAC;IAuDxB,CAAC;IAExB;;;;OAIG;IACH,MAAM,CAAC,YAAY;QACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAc,IAAY;QACjC,MAAM,KAAK,GAAoC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE5B,sBAAsB;QACtB,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;QACjD,MAAM,KAAK,GAAY,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAEvD,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC/C,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAc,IAAY,EAAE,IAAO,EAAE,OAAsB;QAClE,mDAAmD;QACnD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,GAAG,GAAW,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEvD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;YACnB,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK;YAC9B,GAAG;SACJ,CAAC,CAAC;QAEH,6BAA6B;QAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,IAAY;QAC1B,MAAM,KAAK,GAAoC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAc,IAAY,EAAE,OAAuB;QAC7D,MAAM,KAAK,GAAoC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAS,CAAC,CAAC;YACtC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAE,kBAAkB;YACjD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAY,qBAAqB;YACrD,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,IAAa;QAC5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;;;;OASG;IACH,oBAAoB,CAAC,IAAY;QAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,MAAM,GAAW,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;QAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,OAAe;QACxB,qDAAqD;QACrD,oDAAoD;IACtD,CAAC;IAED;;;;;OAKG;IACK,OAAO,CAAC,IAAY;QAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QACnC,CAAC;QAED,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAW,IAAI,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;gBAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,SAAS;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,MAAM,SAAS,GAAuB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACrE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC7B,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAE,wCAAwC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,IAAI,SAAS,GAAW,CAAC,CAAC;QAC1B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,qCAAqC;YACrC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACjD,CAAC;QAED,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;YAC/B,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;YAC/B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACxB,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,WAAW;QACT,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AA/SD,8BA+SC;AAED;;;;GAIG;AACH,SAAgB,aAAa;IAC3B,OAAO,SAAS,CAAC,YAAY,EAAE,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"listCache.js","sourceRoot":"","sources":["../../src/cache/listCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * How long feed movement collects before the cache is walked.
3
+ *
4
+ * Short on purpose: the whole point is that the mark beats the operator's
5
+ * next listing of that folder.
6
+ */
7
+ export declare const LISTING_INVALIDATION_WINDOW_MS: number;
8
+ /**
9
+ * Notes that a feed's contents moved, so its cached folder listings are
10
+ * behind. Call when a job crosses into a terminal state — that is when
11
+ * output becomes visible.
12
+ *
13
+ * @param feedIDs - Feeds whose contents changed.
14
+ */
15
+ export declare function listingsForFeeds_note(feedIDs: readonly number[]): void;
16
+ /**
17
+ * Notes that feeds arrived in, or vanished from, a parent folder.
18
+ *
19
+ * An arrival changes the *parent* listing rather than anything inside the
20
+ * feed, which is why this takes the folders as well: a feed shared to this
21
+ * identity adds a row to a folder that may itself be perfectly fresh.
22
+ *
23
+ * @param feedIDs - Feeds that arrived or departed.
24
+ * @param parentPaths - Folder listings whose membership therefore changed.
25
+ */
26
+ export declare function listingsForRoster_note(feedIDs: readonly number[], parentPaths: readonly string[]): void;
27
+ /**
28
+ * Removes every cached listing belonging to feeds that are gone.
29
+ *
30
+ * A departure is not staleness. A feed this identity can no longer see has
31
+ * no contents to serve, and dirty entries are still served while they
32
+ * refresh, so marking one would keep showing a tree that has been taken
33
+ * away. This deletes instead, and does so at once rather than on the
34
+ * window, because there is nothing to race.
35
+ *
36
+ * @param feedIDs - Feeds that vanished from the roster.
37
+ * @returns The cache paths removed.
38
+ */
39
+ export declare function listingsForFeeds_drop(feedIDs: readonly number[]): string[];
40
+ /**
41
+ * Applies any pending movement at once, without waiting for the window.
42
+ *
43
+ * @returns The cache paths marked dirty.
44
+ */
45
+ export declare function listingInvalidation_flush(): string[];
46
+ /** Discards pending movement without applying it (tests, cache reset). */
47
+ export declare function listingInvalidation_reset(): void;
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LISTING_INVALIDATION_WINDOW_MS = void 0;
4
+ exports.listingsForFeeds_note = listingsForFeeds_note;
5
+ exports.listingsForRoster_note = listingsForRoster_note;
6
+ exports.listingsForFeeds_drop = listingsForFeeds_drop;
7
+ exports.listingInvalidation_flush = listingInvalidation_flush;
8
+ exports.listingInvalidation_reset = listingInvalidation_reset;
9
+ /**
10
+ * @file Feed movement invalidates the folder listings it touched.
11
+ *
12
+ * The listing cache used to decide staleness with a clock that had no
13
+ * relationship to when anything changed, while `/proc` — in the same
14
+ * process — knew and said nothing. This is the wire between them.
15
+ *
16
+ * Two rules govern what happens on the far end:
17
+ *
18
+ * - **Your own act deletes; someone else's act dirties.** A mutation
19
+ * (rm, mv, cp, upload) removes the entry, because showing a file you
20
+ * just deleted is incoherent. A job's output or a colleague's share is
21
+ * not wrong, merely behind, so the entry is marked dirty and served at
22
+ * once while it refreshes behind.
23
+ * - **Movement coalesces.** A feed completing a fan-out stage lands many
24
+ * terminal transitions in the same second; they collapse into one pass
25
+ * over the cache keys.
26
+ *
27
+ * Nothing here subscribes to the process cache's change stream. That
28
+ * stream fires on every instance add and status observation, so indexing
29
+ * one large feed emits tens of thousands of events, none of which mean a
30
+ * file appeared. Movement is pushed from the two places that know.
31
+ *
32
+ * @module
33
+ */
34
+ const listCache_1 = require("./listCache");
35
+ const chrisPath_1 = require("../path/chrisPath");
36
+ /**
37
+ * How long feed movement collects before the cache is walked.
38
+ *
39
+ * Short on purpose: the whole point is that the mark beats the operator's
40
+ * next listing of that folder.
41
+ */
42
+ exports.LISTING_INVALIDATION_WINDOW_MS = 1500;
43
+ /** Feed ids whose listings are waiting to be marked. */
44
+ const pendingFeeds = new Set();
45
+ /** Parent folders waiting to be marked, from arrivals and departures. */
46
+ const pendingParents = new Set();
47
+ /** The open coalescing window, or null when nothing is pending. */
48
+ let windowTimer = null;
49
+ /**
50
+ * Marks every cached listing belonging to the given feeds, and any parent
51
+ * folders queued alongside them.
52
+ *
53
+ * @returns The cache paths marked dirty.
54
+ */
55
+ function pending_flush() {
56
+ const feeds = new Set(pendingFeeds);
57
+ const parents = new Set(pendingParents);
58
+ pendingFeeds.clear();
59
+ pendingParents.clear();
60
+ windowTimer = null;
61
+ if (feeds.size === 0 && parents.size === 0)
62
+ return [];
63
+ // Only paths the cache still holds are considered, so a listing dropped
64
+ // between the note and the flush leaves nothing behind to mark.
65
+ const cache = (0, listCache_1.listCache_get)();
66
+ const marked = [];
67
+ for (const path of cache.paths_get()) {
68
+ const feedID = (0, chrisPath_1.path_extractFeedID)(path);
69
+ const isFeedPath = feedID !== null && feeds.has(feedID);
70
+ if (!isFeedPath && !parents.has(path))
71
+ continue;
72
+ cache.cache_markDirty(path);
73
+ marked.push(path);
74
+ }
75
+ return marked;
76
+ }
77
+ /** Opens the coalescing window if one is not already running. */
78
+ function window_open() {
79
+ if (windowTimer !== null)
80
+ return;
81
+ windowTimer = setTimeout(() => { pending_flush(); }, exports.LISTING_INVALIDATION_WINDOW_MS);
82
+ // A pending mark must never hold a process open on its own.
83
+ windowTimer.unref?.();
84
+ }
85
+ /**
86
+ * Notes that a feed's contents moved, so its cached folder listings are
87
+ * behind. Call when a job crosses into a terminal state — that is when
88
+ * output becomes visible.
89
+ *
90
+ * @param feedIDs - Feeds whose contents changed.
91
+ */
92
+ function listingsForFeeds_note(feedIDs) {
93
+ if (feedIDs.length === 0)
94
+ return;
95
+ for (const feedID of feedIDs)
96
+ pendingFeeds.add(feedID);
97
+ window_open();
98
+ }
99
+ /**
100
+ * Notes that feeds arrived in, or vanished from, a parent folder.
101
+ *
102
+ * An arrival changes the *parent* listing rather than anything inside the
103
+ * feed, which is why this takes the folders as well: a feed shared to this
104
+ * identity adds a row to a folder that may itself be perfectly fresh.
105
+ *
106
+ * @param feedIDs - Feeds that arrived or departed.
107
+ * @param parentPaths - Folder listings whose membership therefore changed.
108
+ */
109
+ function listingsForRoster_note(feedIDs, parentPaths) {
110
+ if (feedIDs.length === 0 && parentPaths.length === 0)
111
+ return;
112
+ for (const feedID of feedIDs)
113
+ pendingFeeds.add(feedID);
114
+ for (const path of parentPaths)
115
+ pendingParents.add(path);
116
+ window_open();
117
+ }
118
+ /**
119
+ * Removes every cached listing belonging to feeds that are gone.
120
+ *
121
+ * A departure is not staleness. A feed this identity can no longer see has
122
+ * no contents to serve, and dirty entries are still served while they
123
+ * refresh, so marking one would keep showing a tree that has been taken
124
+ * away. This deletes instead, and does so at once rather than on the
125
+ * window, because there is nothing to race.
126
+ *
127
+ * @param feedIDs - Feeds that vanished from the roster.
128
+ * @returns The cache paths removed.
129
+ */
130
+ function listingsForFeeds_drop(feedIDs) {
131
+ if (feedIDs.length === 0)
132
+ return [];
133
+ const gone = new Set(feedIDs);
134
+ const cache = (0, listCache_1.listCache_get)();
135
+ const removed = [];
136
+ for (const path of cache.paths_get()) {
137
+ const feedID = (0, chrisPath_1.path_extractFeedID)(path);
138
+ if (feedID === null || !gone.has(feedID))
139
+ continue;
140
+ cache.cache_invalidate(path);
141
+ removed.push(path);
142
+ }
143
+ // A feed that left must not be resurrected by movement noted before it
144
+ // went; drop it from anything still pending.
145
+ for (const feedID of feedIDs)
146
+ pendingFeeds.delete(feedID);
147
+ return removed;
148
+ }
149
+ /**
150
+ * Applies any pending movement at once, without waiting for the window.
151
+ *
152
+ * @returns The cache paths marked dirty.
153
+ */
154
+ function listingInvalidation_flush() {
155
+ if (windowTimer !== null) {
156
+ clearTimeout(windowTimer);
157
+ windowTimer = null;
158
+ }
159
+ return pending_flush();
160
+ }
161
+ /** Discards pending movement without applying it (tests, cache reset). */
162
+ function listingInvalidation_reset() {
163
+ if (windowTimer !== null) {
164
+ clearTimeout(windowTimer);
165
+ windowTimer = null;
166
+ }
167
+ pendingFeeds.clear();
168
+ pendingParents.clear();
169
+ }
170
+ //# sourceMappingURL=listingInvalidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listingInvalidation.js","sourceRoot":"","sources":["../../src/cache/listingInvalidation.ts"],"names":[],"mappings":"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"}