veryfront 0.1.85 → 0.1.86
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/esm/deno.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts +4 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.js +76 -0
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/platform/adapters/fs/veryfront/adapter.ts +87 -0
package/esm/deno.js
CHANGED
|
@@ -12,6 +12,9 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
|
|
|
12
12
|
private initialized;
|
|
13
13
|
/** Resolves when file list initialization is complete (for coordinating reads) */
|
|
14
14
|
private fileListReadyResolve;
|
|
15
|
+
/** Single-flight background rewarm when the file list cache disappears */
|
|
16
|
+
private fileListWarmupPromise;
|
|
17
|
+
private fileListWarmupKey;
|
|
15
18
|
private projectData?;
|
|
16
19
|
private apiBaseUrl;
|
|
17
20
|
private apiToken;
|
|
@@ -29,6 +32,7 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
|
|
|
29
32
|
constructor(config: FSAdapterConfig);
|
|
30
33
|
initialize(): Promise<void>;
|
|
31
34
|
private isPersistentCacheInvalidated;
|
|
35
|
+
private scheduleFileListWarmup;
|
|
32
36
|
getPokeMetrics(): {
|
|
33
37
|
received: number;
|
|
34
38
|
invalidationsTriggered: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,SAAS,EACT,eAAe,EAEf,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AA2BnE,qBAAa,kBAAmB,YAAW,SAAS;IAClD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,WAAW,CAAS;IAE5B,kFAAkF;IAClF,OAAO,CAAC,oBAAoB,CAA6B;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,9 @@ export class VeryfrontFSAdapter {
|
|
|
27
27
|
initialized = false;
|
|
28
28
|
/** Resolves when file list initialization is complete (for coordinating reads) */
|
|
29
29
|
fileListReadyResolve = null;
|
|
30
|
+
/** Single-flight background rewarm when the file list cache disappears */
|
|
31
|
+
fileListWarmupPromise = null;
|
|
32
|
+
fileListWarmupKey = null;
|
|
30
33
|
projectData;
|
|
31
34
|
apiBaseUrl;
|
|
32
35
|
apiToken;
|
|
@@ -94,6 +97,9 @@ export class VeryfrontFSAdapter {
|
|
|
94
97
|
hasResult: !!result,
|
|
95
98
|
resultSize: result?.length ?? 0,
|
|
96
99
|
});
|
|
100
|
+
if (!result?.length) {
|
|
101
|
+
this.scheduleFileListWarmup("getFileList miss", cacheKey);
|
|
102
|
+
}
|
|
97
103
|
return result;
|
|
98
104
|
},
|
|
99
105
|
hasCachedFileList: async () => {
|
|
@@ -109,6 +115,9 @@ export class VeryfrontFSAdapter {
|
|
|
109
115
|
hasResult,
|
|
110
116
|
resultSize: result?.length ?? 0,
|
|
111
117
|
});
|
|
118
|
+
if (!hasResult) {
|
|
119
|
+
this.scheduleFileListWarmup("hasCachedFileList miss", cacheKey);
|
|
120
|
+
}
|
|
112
121
|
return hasResult;
|
|
113
122
|
},
|
|
114
123
|
isPersistentCacheInvalidated: (prefix) => this.isPersistentCacheInvalidated(prefix),
|
|
@@ -132,6 +141,9 @@ export class VeryfrontFSAdapter {
|
|
|
132
141
|
resultSize: result?.length ?? 0,
|
|
133
142
|
hasContent: result?.filter((f) => f.content)?.length ?? 0,
|
|
134
143
|
});
|
|
144
|
+
if (!result?.length) {
|
|
145
|
+
this.scheduleFileListWarmup("getFileListCache miss", cacheKey);
|
|
146
|
+
}
|
|
135
147
|
return result;
|
|
136
148
|
});
|
|
137
149
|
this.dirOps = new DirectoryOperations(this.client, this.cache, this.normalizer, contentContextGetter);
|
|
@@ -280,6 +292,65 @@ export class VeryfrontFSAdapter {
|
|
|
280
292
|
isPersistentCacheInvalidated(prefix) {
|
|
281
293
|
return isPrefixBeingInvalidated(prefix);
|
|
282
294
|
}
|
|
295
|
+
scheduleFileListWarmup(reason, cacheKey) {
|
|
296
|
+
if (!this.initialized || !this.contentContext)
|
|
297
|
+
return;
|
|
298
|
+
const effectiveCacheKey = cacheKey ?? buildFileListCacheKey(this.contentContext);
|
|
299
|
+
if (this.fileListWarmupPromise && this.fileListWarmupKey === effectiveCacheKey) {
|
|
300
|
+
logger.debug("File list warmup already in progress", {
|
|
301
|
+
reason,
|
|
302
|
+
cacheKey: effectiveCacheKey,
|
|
303
|
+
});
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const warmupContext = this.contentContext;
|
|
307
|
+
let warmupPromise = null;
|
|
308
|
+
warmupPromise = (async () => {
|
|
309
|
+
try {
|
|
310
|
+
const existing = await this.cache.getAsync(effectiveCacheKey);
|
|
311
|
+
if (existing?.length) {
|
|
312
|
+
logger.debug("Skipping file list warmup because cache is already populated", {
|
|
313
|
+
reason,
|
|
314
|
+
cacheKey: effectiveCacheKey,
|
|
315
|
+
fileCount: existing.length,
|
|
316
|
+
});
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
logger.debug("Starting file list warmup", {
|
|
320
|
+
reason,
|
|
321
|
+
cacheKey: effectiveCacheKey,
|
|
322
|
+
sourceType: warmupContext.sourceType,
|
|
323
|
+
branch: warmupContext.branch,
|
|
324
|
+
environmentName: warmupContext.environmentName,
|
|
325
|
+
releaseId: warmupContext.releaseId,
|
|
326
|
+
});
|
|
327
|
+
const files = await fetchFileListForContext(this.client, warmupContext);
|
|
328
|
+
await this.cache.setAsync(effectiveCacheKey, files);
|
|
329
|
+
logger.debug("File list warmup complete", {
|
|
330
|
+
reason,
|
|
331
|
+
cacheKey: effectiveCacheKey,
|
|
332
|
+
totalFiles: files.length,
|
|
333
|
+
filesWithContent: files.filter((file) => file.content).length,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
logger.warn("File list warmup failed", {
|
|
338
|
+
reason,
|
|
339
|
+
cacheKey: effectiveCacheKey,
|
|
340
|
+
error: error instanceof Error ? error.message : String(error),
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
finally {
|
|
344
|
+
if (warmupPromise && this.fileListWarmupPromise === warmupPromise) {
|
|
345
|
+
this.fileListWarmupPromise = null;
|
|
346
|
+
this.fileListWarmupKey = null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
})();
|
|
350
|
+
this.fileListWarmupPromise = warmupPromise;
|
|
351
|
+
this.fileListWarmupKey = effectiveCacheKey;
|
|
352
|
+
this.readOps.setFileListReadyPromise(warmupPromise);
|
|
353
|
+
}
|
|
283
354
|
getPokeMetrics() {
|
|
284
355
|
return this.wsManager.getPokeMetrics();
|
|
285
356
|
}
|
|
@@ -317,6 +388,8 @@ export class VeryfrontFSAdapter {
|
|
|
317
388
|
this.statOps.clearIndex();
|
|
318
389
|
this.dirOps.clearTree();
|
|
319
390
|
this.initialized = false;
|
|
391
|
+
this.fileListWarmupPromise = null;
|
|
392
|
+
this.fileListWarmupKey = null;
|
|
320
393
|
logger.debug("Disposed");
|
|
321
394
|
}
|
|
322
395
|
getCacheStats() {
|
|
@@ -342,6 +415,7 @@ export class VeryfrontFSAdapter {
|
|
|
342
415
|
hasFiles: !!files,
|
|
343
416
|
fileCount: files?.length ?? 0,
|
|
344
417
|
});
|
|
418
|
+
this.scheduleFileListWarmup("getAllSourceFiles miss", cacheKey);
|
|
345
419
|
return [];
|
|
346
420
|
}
|
|
347
421
|
const fileSummary = summarizeFileList(files);
|
|
@@ -429,6 +503,8 @@ export class VeryfrontFSAdapter {
|
|
|
429
503
|
if (contextChanged) {
|
|
430
504
|
this.statOps.clearIndex();
|
|
431
505
|
this.dirOps.clearTree();
|
|
506
|
+
this.fileListWarmupPromise = null;
|
|
507
|
+
this.fileListWarmupKey = null;
|
|
432
508
|
logger.debug("Cleared index and dirTree due to context change", {
|
|
433
509
|
oldContext,
|
|
434
510
|
newContext: context,
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -49,6 +49,9 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
49
49
|
|
|
50
50
|
/** Resolves when file list initialization is complete (for coordinating reads) */
|
|
51
51
|
private fileListReadyResolve: (() => void) | null = null;
|
|
52
|
+
/** Single-flight background rewarm when the file list cache disappears */
|
|
53
|
+
private fileListWarmupPromise: Promise<void> | null = null;
|
|
54
|
+
private fileListWarmupKey: string | null = null;
|
|
52
55
|
|
|
53
56
|
private projectData?: Project;
|
|
54
57
|
private apiBaseUrl: string;
|
|
@@ -140,6 +143,10 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
140
143
|
resultSize: result?.length ?? 0,
|
|
141
144
|
});
|
|
142
145
|
|
|
146
|
+
if (!result?.length) {
|
|
147
|
+
this.scheduleFileListWarmup("getFileList miss", cacheKey);
|
|
148
|
+
}
|
|
149
|
+
|
|
143
150
|
return result;
|
|
144
151
|
},
|
|
145
152
|
hasCachedFileList: async () => {
|
|
@@ -158,6 +165,10 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
158
165
|
resultSize: result?.length ?? 0,
|
|
159
166
|
});
|
|
160
167
|
|
|
168
|
+
if (!hasResult) {
|
|
169
|
+
this.scheduleFileListWarmup("hasCachedFileList miss", cacheKey);
|
|
170
|
+
}
|
|
171
|
+
|
|
161
172
|
return hasResult;
|
|
162
173
|
},
|
|
163
174
|
isPersistentCacheInvalidated: (prefix: string) => this.isPersistentCacheInvalidated(prefix),
|
|
@@ -202,6 +213,10 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
202
213
|
hasContent: result?.filter((f) => f.content)?.length ?? 0,
|
|
203
214
|
});
|
|
204
215
|
|
|
216
|
+
if (!result?.length) {
|
|
217
|
+
this.scheduleFileListWarmup("getFileListCache miss", cacheKey);
|
|
218
|
+
}
|
|
219
|
+
|
|
205
220
|
return result;
|
|
206
221
|
},
|
|
207
222
|
);
|
|
@@ -389,6 +404,73 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
389
404
|
return isPrefixBeingInvalidated(prefix);
|
|
390
405
|
}
|
|
391
406
|
|
|
407
|
+
private scheduleFileListWarmup(reason: string, cacheKey?: string): void {
|
|
408
|
+
if (!this.initialized || !this.contentContext) return;
|
|
409
|
+
|
|
410
|
+
const effectiveCacheKey = cacheKey ?? buildFileListCacheKey(this.contentContext);
|
|
411
|
+
|
|
412
|
+
if (this.fileListWarmupPromise && this.fileListWarmupKey === effectiveCacheKey) {
|
|
413
|
+
logger.debug("File list warmup already in progress", {
|
|
414
|
+
reason,
|
|
415
|
+
cacheKey: effectiveCacheKey,
|
|
416
|
+
});
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const warmupContext = this.contentContext;
|
|
421
|
+
let warmupPromise: Promise<void> | null = null;
|
|
422
|
+
warmupPromise = (async () => {
|
|
423
|
+
try {
|
|
424
|
+
const existing = await this.cache.getAsync<Array<{ path: string; content?: string }>>(
|
|
425
|
+
effectiveCacheKey,
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
if (existing?.length) {
|
|
429
|
+
logger.debug("Skipping file list warmup because cache is already populated", {
|
|
430
|
+
reason,
|
|
431
|
+
cacheKey: effectiveCacheKey,
|
|
432
|
+
fileCount: existing.length,
|
|
433
|
+
});
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
logger.debug("Starting file list warmup", {
|
|
438
|
+
reason,
|
|
439
|
+
cacheKey: effectiveCacheKey,
|
|
440
|
+
sourceType: warmupContext.sourceType,
|
|
441
|
+
branch: warmupContext.branch,
|
|
442
|
+
environmentName: warmupContext.environmentName,
|
|
443
|
+
releaseId: warmupContext.releaseId,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const files = await fetchFileListForContext(this.client, warmupContext);
|
|
447
|
+
await this.cache.setAsync(effectiveCacheKey, files);
|
|
448
|
+
|
|
449
|
+
logger.debug("File list warmup complete", {
|
|
450
|
+
reason,
|
|
451
|
+
cacheKey: effectiveCacheKey,
|
|
452
|
+
totalFiles: files.length,
|
|
453
|
+
filesWithContent: files.filter((file) => file.content).length,
|
|
454
|
+
});
|
|
455
|
+
} catch (error) {
|
|
456
|
+
logger.warn("File list warmup failed", {
|
|
457
|
+
reason,
|
|
458
|
+
cacheKey: effectiveCacheKey,
|
|
459
|
+
error: error instanceof Error ? error.message : String(error),
|
|
460
|
+
});
|
|
461
|
+
} finally {
|
|
462
|
+
if (warmupPromise && this.fileListWarmupPromise === warmupPromise) {
|
|
463
|
+
this.fileListWarmupPromise = null;
|
|
464
|
+
this.fileListWarmupKey = null;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
})();
|
|
468
|
+
|
|
469
|
+
this.fileListWarmupPromise = warmupPromise;
|
|
470
|
+
this.fileListWarmupKey = effectiveCacheKey;
|
|
471
|
+
this.readOps.setFileListReadyPromise(warmupPromise);
|
|
472
|
+
}
|
|
473
|
+
|
|
392
474
|
getPokeMetrics(): {
|
|
393
475
|
received: number;
|
|
394
476
|
invalidationsTriggered: number;
|
|
@@ -442,6 +524,8 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
442
524
|
this.statOps.clearIndex();
|
|
443
525
|
this.dirOps.clearTree();
|
|
444
526
|
this.initialized = false;
|
|
527
|
+
this.fileListWarmupPromise = null;
|
|
528
|
+
this.fileListWarmupKey = null;
|
|
445
529
|
|
|
446
530
|
logger.debug("Disposed");
|
|
447
531
|
}
|
|
@@ -473,6 +557,7 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
473
557
|
hasFiles: !!files,
|
|
474
558
|
fileCount: files?.length ?? 0,
|
|
475
559
|
});
|
|
560
|
+
this.scheduleFileListWarmup("getAllSourceFiles miss", cacheKey);
|
|
476
561
|
return [];
|
|
477
562
|
}
|
|
478
563
|
|
|
@@ -584,6 +669,8 @@ export class VeryfrontFSAdapter implements FSAdapter {
|
|
|
584
669
|
if (contextChanged) {
|
|
585
670
|
this.statOps.clearIndex();
|
|
586
671
|
this.dirOps.clearTree();
|
|
672
|
+
this.fileListWarmupPromise = null;
|
|
673
|
+
this.fileListWarmupKey = null;
|
|
587
674
|
logger.debug("Cleared index and dirTree due to context change", {
|
|
588
675
|
oldContext,
|
|
589
676
|
newContext: context,
|