veryfront 0.1.1022 → 0.1.1024

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1022",
3
+ "version": "0.1.1024",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -1,4 +1,4 @@
1
- const CHILD_RUN_RESULT_TEXT_LIMIT = 4_000;
1
+ const CHILD_RUN_RESULT_TEXT_LIMIT = 64_000;
2
2
  const CHILD_RUN_VALUE_STRING_LIMIT = 500;
3
3
  const CHILD_RUN_VALUE_SUMMARY_MAX_DEPTH = 5;
4
4
  const MALFORMED_TOOL_RESPONSE_PATTERN = /<tool_response(?:\s[^>]*)?>([\s\S]*?)<\/tool_response>/gi;
@@ -15,6 +15,10 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
15
15
  /** Single-flight background rewarm when the file list cache disappears */
16
16
  private fileListWarmupPromise;
17
17
  private fileListWarmupKey;
18
+ /** Single-flight foreground refresh when a branch preview read misses a newly pushed file. */
19
+ private branchMissRecoveryPromise;
20
+ private branchMissRecoveryGeneration;
21
+ private readonly branchMissRecoveryFailures;
18
22
  private projectData?;
19
23
  private apiBaseUrl;
20
24
  private apiToken;
@@ -38,6 +42,12 @@ export declare class VeryfrontFSAdapter implements FSAdapter {
38
42
  initialize(): Promise<void>;
39
43
  private isPersistentCacheInvalidated;
40
44
  private shouldBackgroundPregenerateStyles;
45
+ private getBranchMissRecoveryKey;
46
+ private hasRecentBranchMissRecoveryFailure;
47
+ private shouldRecoverBranchMiss;
48
+ private shouldRecoverBranchMissResult;
49
+ private refreshBranchSnapshotAfterMiss;
50
+ private withBranchSnapshotRecovery;
41
51
  private scheduleFileListWarmup;
42
52
  refreshSourceSnapshot(reason?: string): Promise<void>;
43
53
  getPokeMetrics(): {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
@@ -6,14 +6,16 @@ import { PathNormalizer } from "./path-normalizer.js";
6
6
  import { ReadOperations } from "./read-operations.js";
7
7
  import { DirectoryOperations } from "./directory-operations.js";
8
8
  import { StatOperations } from "./stat-operations.js";
9
- import { buildFileCacheKeyPrefix, buildFileListCacheKey } from "./cache-keys.js";
9
+ import { buildDirCacheKeyPrefix, buildFileCacheKeyPrefix, buildFileListCacheKey, buildStatCacheKeyPrefix, } from "./cache-keys.js";
10
10
  import { isPrefixBeingInvalidated } from "./invalidation-state.js";
11
11
  import { WebSocketManager } from "./websocket-manager.js";
12
12
  import { fetchFileListForContext, hasContentContextChanged, resolveContentContext, summarizeFileList, toClientContext, } from "./adapter-content-context.js";
13
13
  import { buildFileCacheOptions, buildRetryConfig, shouldBackgroundPregenerateStyles, } from "./adapter-helpers.js";
14
+ import { isNotFoundLikeError } from "./read-operations-helpers.js";
14
15
  import { clearCachedReleaseAssetManifests, registerManifestFetcherForRelease, unregisterManifestFetcherForRelease, } from "../../../../release-assets/manifest-cache.js";
15
16
  import { parseReleaseAssetManifest } from "../../../../release-assets/manifest-schema.js";
16
17
  const logger = baseLogger.component("veryfront-fs-adapter");
18
+ const BRANCH_MISS_RECOVERY_FAILURE_TTL_MS = 5_000;
17
19
  /**
18
20
  * Build a project-scoped manifest fetcher backed by the given API client.
19
21
  *
@@ -43,6 +45,10 @@ export class VeryfrontFSAdapter {
43
45
  /** Single-flight background rewarm when the file list cache disappears */
44
46
  fileListWarmupPromise = null;
45
47
  fileListWarmupKey = null;
48
+ /** Single-flight foreground refresh when a branch preview read misses a newly pushed file. */
49
+ branchMissRecoveryPromise = null;
50
+ branchMissRecoveryGeneration = 0;
51
+ branchMissRecoveryFailures = new Map();
46
52
  projectData;
47
53
  apiBaseUrl;
48
54
  apiToken;
@@ -312,6 +318,113 @@ export class VeryfrontFSAdapter {
312
318
  // pregenerate through the WebSocket path after branch content changes.
313
319
  return shouldBackgroundPregenerateStyles(this.contentContext);
314
320
  }
321
+ getBranchMissRecoveryKey(path) {
322
+ const normalizedPath = this.normalizer.normalize(path);
323
+ const branch = this.requestBranch ?? this.contentContext?.branch ?? "main";
324
+ return `${this.projectSlug}:${branch}:${normalizedPath}`;
325
+ }
326
+ hasRecentBranchMissRecoveryFailure(key) {
327
+ const failedAt = this.branchMissRecoveryFailures.get(key);
328
+ if (!failedAt)
329
+ return false;
330
+ if (Date.now() - failedAt < BRANCH_MISS_RECOVERY_FAILURE_TTL_MS)
331
+ return true;
332
+ this.branchMissRecoveryFailures.delete(key);
333
+ return false;
334
+ }
335
+ shouldRecoverBranchMiss(path, error) {
336
+ if (this.contentContext?.sourceType !== "branch")
337
+ return false;
338
+ if (!isNotFoundLikeError(error))
339
+ return false;
340
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
341
+ return !this.hasRecentBranchMissRecoveryFailure(recoveryKey);
342
+ }
343
+ shouldRecoverBranchMissResult(path, result, options) {
344
+ if (this.contentContext?.sourceType !== "branch")
345
+ return false;
346
+ if (!options?.isRecoverableMissResult?.(result))
347
+ return false;
348
+ if (options.requirePendingSourceInvalidation &&
349
+ !this.isPersistentCacheInvalidated(buildFileCacheKeyPrefix(this.contentContext))) {
350
+ return false;
351
+ }
352
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
353
+ return !this.hasRecentBranchMissRecoveryFailure(recoveryKey);
354
+ }
355
+ async refreshBranchSnapshotAfterMiss(path) {
356
+ let recoveryPromise = this.branchMissRecoveryPromise;
357
+ let ownsRecovery = false;
358
+ let recoveryGeneration = this.branchMissRecoveryGeneration;
359
+ if (!recoveryPromise) {
360
+ const normalizedPath = this.normalizer.normalize(path);
361
+ recoveryPromise = this.refreshSourceSnapshot(`branch-miss:${normalizedPath}`);
362
+ this.branchMissRecoveryPromise = recoveryPromise;
363
+ recoveryGeneration = ++this.branchMissRecoveryGeneration;
364
+ ownsRecovery = true;
365
+ }
366
+ try {
367
+ await recoveryPromise;
368
+ }
369
+ finally {
370
+ if (ownsRecovery && this.branchMissRecoveryGeneration === recoveryGeneration) {
371
+ this.branchMissRecoveryPromise = null;
372
+ }
373
+ }
374
+ }
375
+ async withBranchSnapshotRecovery(path, operation, options) {
376
+ try {
377
+ const result = await operation();
378
+ if (!this.shouldRecoverBranchMissResult(path, result, options))
379
+ return result;
380
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
381
+ try {
382
+ await this.refreshBranchSnapshotAfterMiss(path);
383
+ }
384
+ catch (refreshError) {
385
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
386
+ logger.warn("Branch snapshot recovery failed after result miss", {
387
+ path: this.normalizer.normalize(path),
388
+ projectSlug: this.projectSlug,
389
+ branch: this.requestBranch ?? this.contentContext?.branch,
390
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
391
+ });
392
+ return result;
393
+ }
394
+ const retryResult = await operation();
395
+ if (options?.isRecoverableMissResult?.(retryResult)) {
396
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
397
+ }
398
+ return retryResult;
399
+ }
400
+ catch (error) {
401
+ if (!this.shouldRecoverBranchMiss(path, error))
402
+ throw error;
403
+ const recoveryKey = this.getBranchMissRecoveryKey(path);
404
+ try {
405
+ await this.refreshBranchSnapshotAfterMiss(path);
406
+ }
407
+ catch (refreshError) {
408
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
409
+ logger.warn("Branch snapshot recovery failed after not-found miss", {
410
+ path: this.normalizer.normalize(path),
411
+ projectSlug: this.projectSlug,
412
+ branch: this.requestBranch ?? this.contentContext?.branch,
413
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
414
+ });
415
+ throw error;
416
+ }
417
+ try {
418
+ return await operation();
419
+ }
420
+ catch (retryError) {
421
+ if (isNotFoundLikeError(retryError)) {
422
+ this.branchMissRecoveryFailures.set(recoveryKey, Date.now());
423
+ }
424
+ throw retryError;
425
+ }
426
+ }
427
+ }
315
428
  scheduleFileListWarmup(reason, cacheKey) {
316
429
  if (!this.initialized || !this.contentContext)
317
430
  return;
@@ -393,10 +506,16 @@ export class VeryfrontFSAdapter {
393
506
  this.readOps.clearFileListIndex();
394
507
  this.statOps.clearIndex();
395
508
  this.dirOps.clearTree();
396
- await this.cache.deleteAsync(cacheKey);
509
+ await Promise.all([
510
+ this.cache.deleteByPrefixAsync(buildFileCacheKeyPrefix(refreshContext)),
511
+ this.cache.deleteByPrefixAsync(buildStatCacheKeyPrefix(refreshContext)),
512
+ this.cache.deleteByPrefixAsync(buildDirCacheKeyPrefix(refreshContext)),
513
+ this.cache.deleteAsync(cacheKey),
514
+ ]);
397
515
  const files = await fetchFileListForContext(this.client, refreshContext);
398
516
  await this.cache.setAsync(cacheKey, files);
399
517
  const fileSummary = summarizeFileList(files);
518
+ this.branchMissRecoveryFailures.clear();
400
519
  if (fileSummary.sourceFilesWithContent > 0 && this.shouldBackgroundPregenerateStyles()) {
401
520
  this.triggerCSSPregeneration(files).catch(() => {
402
521
  // Error already logged in triggerCSSPregeneration
@@ -419,31 +538,43 @@ export class VeryfrontFSAdapter {
419
538
  }
420
539
  async readFile(path) {
421
540
  await this.ensureInitialized();
422
- return this.readOps.readTextFile(path);
541
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readTextFile(path));
423
542
  }
424
543
  async readFileBytes(path) {
425
544
  await this.ensureInitialized();
426
- return this.readOps.readFile(path);
545
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readFile(path));
427
546
  }
428
547
  async readTextFile(path) {
429
548
  await this.ensureInitialized();
430
- return this.readOps.readTextFile(path);
549
+ return this.withBranchSnapshotRecovery(path, () => this.readOps.readTextFile(path));
431
550
  }
432
551
  async readdir(path) {
433
552
  await this.ensureInitialized();
434
- return this.dirOps.readdir(path);
553
+ return this.withBranchSnapshotRecovery(path, () => this.dirOps.readdir(path), {
554
+ isRecoverableMissResult: (entries) => entries.length === 0,
555
+ requirePendingSourceInvalidation: true,
556
+ });
435
557
  }
436
558
  async stat(path) {
437
559
  await this.ensureInitialized();
438
- return this.statOps.stat(path);
560
+ return this.withBranchSnapshotRecovery(path, () => this.statOps.stat(path));
439
561
  }
440
562
  async exists(path) {
441
563
  await this.ensureInitialized();
442
- return this.statOps.exists(path);
564
+ try {
565
+ await this.withBranchSnapshotRecovery(path, () => this.statOps.stat(path));
566
+ return true;
567
+ }
568
+ catch (_) {
569
+ return false;
570
+ }
443
571
  }
444
572
  async resolveFile(basePath, options) {
445
573
  await this.ensureInitialized();
446
- return this.statOps.resolveFile(basePath, options);
574
+ return this.withBranchSnapshotRecovery(basePath, () => this.statOps.resolveFile(basePath, options), {
575
+ isRecoverableMissResult: (resolvedPath) => resolvedPath === null,
576
+ requirePendingSourceInvalidation: true,
577
+ });
447
578
  }
448
579
  dispose() {
449
580
  this.wsManager.dispose();
@@ -453,6 +584,9 @@ export class VeryfrontFSAdapter {
453
584
  this.initialized = false;
454
585
  this.fileListWarmupPromise = null;
455
586
  this.fileListWarmupKey = null;
587
+ this.branchMissRecoveryPromise = null;
588
+ this.branchMissRecoveryGeneration++;
589
+ this.branchMissRecoveryFailures.clear();
456
590
  logger.debug("Disposed");
457
591
  }
458
592
  getCacheStats() {
@@ -576,6 +710,9 @@ export class VeryfrontFSAdapter {
576
710
  this.dirOps.clearTree();
577
711
  this.fileListWarmupPromise = null;
578
712
  this.fileListWarmupKey = null;
713
+ this.branchMissRecoveryPromise = null;
714
+ this.branchMissRecoveryGeneration++;
715
+ this.branchMissRecoveryFailures.clear();
579
716
  logger.debug("Cleared index and dirTree due to context change", {
580
717
  oldContext,
581
718
  newContext: context,
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1022";
2
+ export declare const VERSION = "0.1.1024";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1022";
4
+ export const VERSION = "0.1.1024";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1022",
3
+ "version": "0.1.1024",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -326,9 +326,9 @@
326
326
  "@types/react": "19.2.14",
327
327
  "@types/react-dom": "19.2.3",
328
328
  "ws": "8.21.0",
329
- "@veryfront/ext-bundler-esbuild": "0.1.1022",
330
- "@veryfront/ext-content-mdx": "0.1.1022",
331
- "@veryfront/ext-css-tailwind": "0.1.1022"
329
+ "@veryfront/ext-bundler-esbuild": "0.1.1024",
330
+ "@veryfront/ext-content-mdx": "0.1.1024",
331
+ "@veryfront/ext-css-tailwind": "0.1.1024"
332
332
  },
333
333
  "devDependencies": {
334
334
  "@types/node": "20.9.0"