veryfront 0.1.100 → 0.1.101

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.
Files changed (30) hide show
  1. package/esm/deno.js +9 -9
  2. package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
  3. package/esm/src/observability/tracing/otlp-setup.js +11 -7
  4. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.d.ts +2 -0
  5. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.d.ts.map +1 -1
  6. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.js +102 -1
  7. package/esm/src/platform/adapters/redis/node.d.ts.map +1 -1
  8. package/esm/src/platform/adapters/redis/node.js +4 -2
  9. package/esm/src/platform/adapters/redis/types.d.ts +2 -2
  10. package/esm/src/platform/adapters/redis/types.d.ts.map +1 -1
  11. package/esm/src/proxy/cache/redis-cache.d.ts.map +1 -1
  12. package/esm/src/proxy/cache/redis-cache.js +9 -7
  13. package/esm/src/proxy/tracing.d.ts.map +1 -1
  14. package/esm/src/proxy/tracing.js +8 -5
  15. package/esm/src/server/services/rsc/endpoints/script-handlers.d.ts.map +1 -1
  16. package/esm/src/server/services/rsc/endpoints/script-handlers.js +21 -12
  17. package/esm/src/utils/version.d.ts +1 -1
  18. package/esm/src/utils/version.js +1 -1
  19. package/esm/src/workflow/claude-code/event-publisher.js +2 -2
  20. package/package.json +9 -9
  21. package/src/deno.js +9 -9
  22. package/src/src/observability/tracing/otlp-setup.ts +12 -8
  23. package/src/src/platform/adapters/fs/veryfront/proxy-manager.ts +148 -1
  24. package/src/src/platform/adapters/redis/node.ts +4 -2
  25. package/src/src/platform/adapters/redis/types.ts +2 -2
  26. package/src/src/proxy/cache/redis-cache.ts +9 -7
  27. package/src/src/proxy/tracing.ts +9 -5
  28. package/src/src/server/services/rsc/endpoints/script-handlers.ts +20 -14
  29. package/src/src/utils/version.ts +1 -1
  30. package/src/src/workflow/claude-code/event-publisher.ts +3 -3
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -240,7 +240,7 @@ export default {
240
240
  "es-module-lexer": "npm:es-module-lexer@2.0.0",
241
241
  "gray-matter": "npm:gray-matter@4.0.3",
242
242
  "zod": "npm:zod@3.25.76",
243
- "mime-types": "npm:mime-types@2.1.35",
243
+ "mime-types": "npm:mime-types@3.0.2",
244
244
  "mdast": "npm:@types/mdast@4.0.3",
245
245
  "hast": "npm:@types/hast@3.0.3",
246
246
  "unist": "npm:@types/unist@3.0.2",
@@ -259,15 +259,15 @@ export default {
259
259
  "tailwindcss/plugin": "https://esm.sh/tailwindcss@4.2.2/plugin",
260
260
  "tailwindcss/defaultTheme": "https://esm.sh/tailwindcss@4.2.2/defaultTheme",
261
261
  "tailwindcss/colors": "https://esm.sh/tailwindcss@4.2.2/colors",
262
- "redis": "npm:redis@4.6.13",
262
+ "redis": "npm:redis@5.11.0",
263
263
  "pg": "npm:pg@8.13.1",
264
264
  "jose": "npm:jose@5.9.6",
265
265
  "@opentelemetry/api": "npm:@opentelemetry/api@1.9.0",
266
- "@opentelemetry/core": "npm:@opentelemetry/core@1",
267
- "@opentelemetry/context-async-hooks": "npm:@opentelemetry/context-async-hooks@1",
268
- "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@1",
269
- "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.57",
270
- "@opentelemetry/resources": "npm:@opentelemetry/resources@1",
266
+ "@opentelemetry/core": "npm:@opentelemetry/core@2.6.0",
267
+ "@opentelemetry/context-async-hooks": "npm:@opentelemetry/context-async-hooks@2.6.0",
268
+ "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@2.6.0",
269
+ "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.213.0",
270
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@2.6.0",
271
271
  "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@1.40.0",
272
272
  "@babel/parser": "npm:@babel/parser@7.29.2",
273
273
  "@babel/traverse": "npm:@babel/traverse@7.29.0",
@@ -275,7 +275,7 @@ export default {
275
275
  "@babel/types": "npm:@babel/types@7.29.0",
276
276
  "class-variance-authority": "npm:class-variance-authority@0.7.1",
277
277
  "clsx": "npm:clsx@2.1.1",
278
- "tailwind-merge": "npm:tailwind-merge@2.6.0",
278
+ "tailwind-merge": "npm:tailwind-merge@3.5.0",
279
279
  "@kreuzberg/wasm": "npm:@kreuzberg/wasm@4.5.2",
280
280
  "#kreuzberg-wasm-glue": "npm:@kreuzberg/wasm@4.5.2/dist/pkg/kreuzberg_wasm.js"
281
281
  },
@@ -1 +1 @@
1
- {"version":3,"file":"otlp-setup.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/tracing/otlp-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;4BAS4B;AAC5B,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAalD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;CAClB;AA2DD,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAwEpD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CASlD;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,CAAC,EACX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,CAAC,CAsBH;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAahE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAW5D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,OAAO,GACtB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAW5C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAqBpF;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACpD,IAAI,CAKN;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACpD,IAAI,CAON;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG3F;AAED,wBAAgB,eAAe,IAAI;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQvE;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5D"}
1
+ {"version":3,"file":"otlp-setup.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/tracing/otlp-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;4BAS4B;AAC5B,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAalD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;CAClB;AA2DD,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA4EpD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CASlD;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,CAAC,EACX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,CAAC,CAsBH;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAahE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAW5D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,OAAO,GACtB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAW5C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAqBpF;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACpD,IAAI,CAKN;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACpD,IAAI,CAON;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG3F;AAED,wBAAgB,eAAe,IAAI;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQvE;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5D"}
@@ -71,10 +71,10 @@ export async function initializeOTLP() {
71
71
  try {
72
72
  const { BasicTracerProvider, BatchSpanProcessor } = await import("@opentelemetry/sdk-trace-base");
73
73
  const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
74
- const { Resource } = await import("@opentelemetry/resources");
74
+ const { resourceFromAttributes } = await import("@opentelemetry/resources");
75
75
  const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = await import("@opentelemetry/semantic-conventions");
76
76
  const { AsyncLocalStorageContextManager } = await import("@opentelemetry/context-async-hooks");
77
- const resource = new Resource({
77
+ const resource = resourceFromAttributes({
78
78
  [ATTR_SERVICE_NAME]: config.serviceName,
79
79
  [ATTR_SERVICE_VERSION]: RUNTIME_VERSION,
80
80
  });
@@ -83,14 +83,18 @@ export async function initializeOTLP() {
83
83
  url: `${endpointBase}/v1/traces`,
84
84
  headers: config.headers,
85
85
  });
86
- const provider = new BasicTracerProvider({ resource });
87
- provider.addSpanProcessor(new BatchSpanProcessor(exporter));
88
86
  const contextManager = new AsyncLocalStorageContextManager();
89
87
  contextManager.enable();
90
- provider.register({ contextManager });
91
- tracerProvider = provider;
92
- // MUST be set before marking as initialized, otherwise withSpan will skip creating spans.
88
+ const provider = new BasicTracerProvider({
89
+ resource,
90
+ spanProcessors: [new BatchSpanProcessor(exporter)],
91
+ });
92
+ // In OTel SDK v2, provider.register() is removed.
93
+ // Set global tracer provider and context manager via the API directly.
93
94
  traceApi = await import("@opentelemetry/api");
95
+ traceApi.trace.setGlobalTracerProvider(provider);
96
+ traceApi.context.setGlobalContextManager(contextManager);
97
+ tracerProvider = provider;
94
98
  initialized = true;
95
99
  logger.info("OpenTelemetry OTLP tracing initialized", {
96
100
  serviceName: config.serviceName,
@@ -6,9 +6,11 @@ interface ProxyFSAdapterManagerConfig {
6
6
  cleanupIntervalMs?: number;
7
7
  maxIdleMs?: number;
8
8
  }
9
+ export declare function getPushRefFallbackBranch(error: unknown, branch: string | null | undefined, productionMode?: boolean): string | null;
9
10
  export declare class ProxyFSAdapterManager {
10
11
  private adapters;
11
12
  private pendingAdapters;
13
+ private negativeCacheEntries;
12
14
  private baseConfig;
13
15
  private maxAdapters;
14
16
  private maxIdleMs;
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/proxy-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;AAetF,UAAU,2BAA2B;IACnC,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAyC;gBAElD,MAAM,EAAE,2BAA2B;IAkBzC,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,kBAAkB,CAAC;IA+H9B,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,wBAAwB;IAyChC,OAAO,CAAC,aAAa;IAqGrB,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,mBAAmB;IAY3B,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO;IAUV,QAAQ,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE;IAUnE,OAAO,IAAI,IAAI;CAchB"}
1
+ {"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/proxy-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;AAetF,UAAU,2BAA2B;IACnC,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgDD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,cAAc,UAAQ,GACrB,MAAM,GAAG,IAAI,CAkBf;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,oBAAoB,CAAyC;IACrE,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAyC;gBAElD,MAAM,EAAE,2BAA2B;IAkBzC,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,kBAAkB,CAAC;IA8J9B,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,wBAAwB;IAyChC,OAAO,CAAC,aAAa;IA4IrB,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,mBAAmB;IAY3B,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO;IAUV,QAAQ,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE;IAUnE,OAAO,IAAI,IAAI;CAoBhB"}
@@ -1,6 +1,6 @@
1
1
  import * as dntShim from "../../../../../_dnt.shims.js";
2
2
  import { logger as baseLogger } from "../../../../utils/index.js";
3
- import { CACHE_INVARIANT_VIOLATION, INVALID_ARGUMENT } from "../../../../errors/index.js";
3
+ import { CACHE_INVARIANT_VIOLATION, INVALID_ARGUMENT, VeryfrontError } from "../../../../errors/index.js";
4
4
  import { buildProxyManagerCacheKey } from "../../../../cache/index.js";
5
5
  import { VeryfrontFSAdapter } from "./index.js";
6
6
  import { GetAdapterParamsSchema } from "./schemas/index.js";
@@ -8,9 +8,57 @@ import { createDefaultInvalidationCallbacks } from "./default-invalidation-callb
8
8
  const logger = baseLogger.component("proxy-fs-adapter-manager");
9
9
  const DEFAULT_MAX_ADAPTERS = 100;
10
10
  const DEFAULT_MAX_IDLE_MS = 30 * 60 * 1_000;
11
+ function isPushPreviewBranch(branch, productionMode) {
12
+ return !productionMode && !!branch && branch !== "main" && branch.startsWith("push-");
13
+ }
14
+ function getApiErrorDetails(error) {
15
+ if (!(error instanceof VeryfrontError) || !error.context || typeof error.context !== "object") {
16
+ return null;
17
+ }
18
+ const details = error.context.details;
19
+ if (!details || typeof details !== "object")
20
+ return null;
21
+ const apiErrorDetails = {};
22
+ if (typeof details.responseText === "string") {
23
+ apiErrorDetails.responseText = details.responseText;
24
+ }
25
+ if (typeof details.url === "string") {
26
+ apiErrorDetails.url = details.url;
27
+ }
28
+ return apiErrorDetails.responseText || apiErrorDetails.url ? apiErrorDetails : null;
29
+ }
30
+ function getProblemDetail(error) {
31
+ const responseText = getApiErrorDetails(error)?.responseText;
32
+ if (!responseText)
33
+ return null;
34
+ try {
35
+ const parsed = JSON.parse(responseText);
36
+ return typeof parsed.detail === "string" ? parsed.detail : null;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ export function getPushRefFallbackBranch(error, branch, productionMode = false) {
43
+ if (!branch || !isPushPreviewBranch(branch, productionMode))
44
+ return null;
45
+ if (!(error instanceof VeryfrontError) || error.status !== 404)
46
+ return null;
47
+ const apiErrorDetails = getApiErrorDetails(error);
48
+ if (!apiErrorDetails?.url?.includes("/files?") ||
49
+ !apiErrorDetails.url.includes(`branch=${encodeURIComponent(branch)}`)) {
50
+ return null;
51
+ }
52
+ const detail = getProblemDetail(error);
53
+ if (detail && !detail.includes(`Branch '${branch}' not found`)) {
54
+ return null;
55
+ }
56
+ return "main";
57
+ }
11
58
  export class ProxyFSAdapterManager {
12
59
  adapters = new Map();
13
60
  pendingAdapters = new Map();
61
+ negativeCacheEntries = new Map();
14
62
  baseConfig;
15
63
  maxAdapters;
16
64
  maxIdleMs;
@@ -76,6 +124,26 @@ export class ProxyFSAdapterManager {
76
124
  hasExisting: this.adapters.has(cacheKey),
77
125
  totalCachedAdapters: this.adapters.size,
78
126
  });
127
+ const negativeEntry = this.negativeCacheEntries.get(cacheKey);
128
+ if (negativeEntry?.fallbackBranch && negativeEntry.fallbackBranch !== effectiveBranch) {
129
+ logger.warn("Using cached fallback branch for push ref", {
130
+ branch: effectiveBranch,
131
+ cacheKey,
132
+ fallbackBranch: negativeEntry.fallbackBranch,
133
+ projectSlug,
134
+ });
135
+ return this.getAdapter(projectSlug, token, projectId, effectiveProductionMode, effectiveReleaseId, effectiveEnvironmentName, negativeEntry.fallbackBranch);
136
+ }
137
+ // Reject known-bad cache keys only when there is no fallback target.
138
+ if (negativeEntry) {
139
+ logger.warn("Rejecting adapter request for negatively-cached key", {
140
+ cacheKey,
141
+ projectSlug,
142
+ });
143
+ throw INVALID_ARGUMENT.create({
144
+ detail: `Adapter for "${cacheKey}" is negatively cached (previous initialization returned 404). Retry after 60s.`,
145
+ });
146
+ }
79
147
  const existing = this.adapters.get(cacheKey);
80
148
  if (existing) {
81
149
  existing.lastAccessed = Date.now();
@@ -233,6 +301,34 @@ export class ProxyFSAdapterManager {
233
301
  return adapter;
234
302
  }
235
303
  catch (error) {
304
+ const fallbackBranch = getPushRefFallbackBranch(error, branch, productionMode);
305
+ if (fallbackBranch) {
306
+ const NEGATIVE_CACHE_TTL_MS = 60_000;
307
+ logger.warn("Push ref initialization returned 404, retrying with fallback branch", {
308
+ branch,
309
+ cacheKey,
310
+ duration: `${(performance.now() - initStartTime).toFixed(2)}ms`,
311
+ fallbackBranch,
312
+ projectSlug,
313
+ });
314
+ const existingEntry = this.negativeCacheEntries.get(cacheKey);
315
+ if (existingEntry) {
316
+ clearTimeout(existingEntry.timer);
317
+ }
318
+ const timer = dntShim.setTimeout(() => {
319
+ this.negativeCacheEntries.delete(cacheKey);
320
+ logger.debug("Negative cache sentinel expired", { cacheKey });
321
+ }, NEGATIVE_CACHE_TTL_MS);
322
+ // Unref so the timer doesn't keep processes/tests alive
323
+ try {
324
+ dntShim.Deno.unrefTimer(timer);
325
+ }
326
+ catch {
327
+ // Not available in all runtimes
328
+ }
329
+ this.negativeCacheEntries.set(cacheKey, { fallbackBranch, timer });
330
+ return await this.getAdapter(projectSlug, token, projectId, productionMode, releaseId, environmentName, fallbackBranch);
331
+ }
236
332
  logger.error("Adapter initialization failed", {
237
333
  cacheKey,
238
334
  projectSlug,
@@ -293,6 +389,11 @@ export class ProxyFSAdapterManager {
293
389
  clearInterval(this.cleanupTimer);
294
390
  this.cleanupTimer = undefined;
295
391
  }
392
+ // Clear negative cache timers
393
+ for (const entry of this.negativeCacheEntries.values()) {
394
+ clearTimeout(entry.timer);
395
+ }
396
+ this.negativeCacheEntries.clear();
296
397
  for (const [cacheKey, adapter] of this.adapters) {
297
398
  logger.debug("Disposing adapter", { cacheKey });
298
399
  adapter.adapter.dispose();
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/redis/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/redis/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,gBAAiB,YAAW,YAAY;IACvC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAE3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IAI3E,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAIrD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvD,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAInE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI1D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIvE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI9E,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAInF,UAAU,CACd,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,EAC5C,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3E,OAAO,CACR,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CACtF;IAgBD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAInE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxC,MAAM,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,GAAG,CACD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GACnD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B"}
@@ -78,9 +78,11 @@ export class NodeRedisAdapter {
78
78
  return this.client.get(key);
79
79
  }
80
80
  quit() {
81
- return this.client.quit();
81
+ // redis v5: quit() renamed to close()
82
+ return this.client.close();
82
83
  }
83
84
  disconnect() {
84
- return this.client.disconnect();
85
+ // redis v5: disconnect() renamed to destroy()
86
+ return this.client.destroy();
85
87
  }
86
88
  }
@@ -96,7 +96,7 @@ export interface NodeRedisClient {
96
96
  EX?: number;
97
97
  }): Promise<string | null>;
98
98
  get(key: string): Promise<string | null>;
99
- quit(): Promise<void>;
100
- disconnect(): Promise<void>;
99
+ close(): Promise<void>;
100
+ destroy(): Promise<void>;
101
101
  }
102
102
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/redis/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/redis/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"redis-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/proxy/cache/redis-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAY7F,qBAAa,UAAW,YAAW,UAAU;IAC3C,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,iBAAiB;IAStC,OAAO,CAAC,GAAG;IAIL,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAoCjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsCtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlC,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAmBd,kBAAkB;YAQlB,eAAe;CAoC9B"}
1
+ {"version":3,"file":"redis-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/proxy/cache/redis-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAY7F,qBAAa,UAAW,YAAW,UAAU;IAC3C,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,iBAAiB;IAStC,OAAO,CAAC,GAAG;IAIL,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAoCjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlC,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAmBd,kBAAkB;YAQlB,eAAe;CAoC9B"}
@@ -95,18 +95,20 @@ export class RedisCache {
95
95
  try {
96
96
  const client = await this.getConnectedClient();
97
97
  const pattern = `${this.prefix}*`;
98
- let cursor = 0;
98
+ // redis v5: scan cursor is string-based to prevent Number.MAX_SAFE_INTEGER overflow
99
+ let cursor = "0";
99
100
  let totalDeleted = 0;
100
101
  do {
101
- const { cursor: nextCursor, keys } = await client.scan(cursor, {
102
+ // deno-lint-ignore no-explicit-any
103
+ const result = await client.scan(cursor, {
102
104
  MATCH: pattern,
103
105
  COUNT: DEFAULT_SCAN_COUNT,
104
106
  });
105
- cursor = nextCursor;
106
- if (keys.length > 0) {
107
- totalDeleted += await client.del(keys);
107
+ cursor = String(result.cursor);
108
+ if (result.keys.length > 0) {
109
+ totalDeleted += await client.del(result.keys);
108
110
  }
109
- } while (cursor !== 0);
111
+ } while (cursor !== "0");
110
112
  if (totalDeleted > 0) {
111
113
  logger.info(`[RedisCache] Cleared ${totalDeleted} keys`);
112
114
  }
@@ -161,7 +163,7 @@ export class RedisCache {
161
163
  return;
162
164
  }
163
165
  try {
164
- await client.quit();
166
+ await client.close();
165
167
  }
166
168
  catch (_) {
167
169
  // expected: close errors are non-critical
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/tracing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAG/C,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAU,MAAM,oBAAoB,CAAC;AA6DhE,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyD5D;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CASlD;AAOD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,GAAG,SAAS,CAgB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAgB5D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,OAAO,GACtB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAMzC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAiBvF;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGrF;AAWD,wBAAgB,eAAe,IAAI;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAIvE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
1
+ {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/tracing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAG/C,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAU,MAAM,oBAAoB,CAAC;AA6DhE,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6D5D;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CASlD;AAOD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,GAAG,SAAS,CAgB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAgB5D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,OAAO,GACtB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAMzC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAiBvF;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGrF;AAWD,wBAAgB,eAAe,IAAI;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAIvE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACrD,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
@@ -64,10 +64,10 @@ export async function initializeOTLPWithApis() {
64
64
  const { trace } = await import("@opentelemetry/api");
65
65
  const { BasicTracerProvider, BatchSpanProcessor } = await import("@opentelemetry/sdk-trace-base");
66
66
  const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
67
- const { Resource } = await import("@opentelemetry/resources");
67
+ const { resourceFromAttributes } = await import("@opentelemetry/resources");
68
68
  const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = await import("@opentelemetry/semantic-conventions");
69
69
  const resourceAttrs = parseResourceAttributes(getEnv("OTEL_RESOURCE_ATTRIBUTES"));
70
- const resource = new Resource({
70
+ const resource = resourceFromAttributes({
71
71
  [ATTR_SERVICE_NAME]: config.serviceName,
72
72
  [ATTR_SERVICE_VERSION]: PROXY_RUNTIME_VERSION,
73
73
  ...resourceAttrs,
@@ -76,9 +76,12 @@ export async function initializeOTLPWithApis() {
76
76
  url: `${config.endpoint}/v1/traces`,
77
77
  headers: config.headers,
78
78
  });
79
- const provider = new BasicTracerProvider({ resource });
80
- provider.addSpanProcessor(new BatchSpanProcessor(exporter));
81
- provider.register();
79
+ const provider = new BasicTracerProvider({
80
+ resource,
81
+ spanProcessors: [new BatchSpanProcessor(exporter)],
82
+ });
83
+ // In OTel SDK v2, provider.register() is removed.
84
+ trace.setGlobalTracerProvider(provider);
82
85
  tracerProvider = provider;
83
86
  tracer = trace.getTracer(config.serviceName);
84
87
  initialized = true;
@@ -1 +1 @@
1
- {"version":3,"file":"script-handlers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/script-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AA6D5E,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAsB3B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAqBxF"}
1
+ {"version":3,"file":"script-handlers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/script-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuE5E,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAoB3B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAmBxF"}
@@ -10,22 +10,33 @@ function jsResponse(body) {
10
10
  });
11
11
  }
12
12
  async function buildOrServeScript(adapter, path, fallbackBundle, esbuildOptions) {
13
+ // If a pre-built bundle was injected at compile time, serve it directly
14
+ if (fallbackBundle)
15
+ return jsResponse(fallbackBundle);
13
16
  let esbuild = null;
14
17
  try {
15
- esbuild = await import("esbuild");
16
18
  const src = await adapter.fs.readFile(path);
17
- const result = await esbuild.build(esbuildOptions);
19
+ esbuild = await import("esbuild");
20
+ const result = await esbuild.build({
21
+ ...esbuildOptions,
22
+ stdin: { ...esbuildOptions.stdin, contents: src },
23
+ });
18
24
  const out = result.outputFiles?.[0]?.text ?? src;
19
25
  return jsResponse(out);
20
26
  }
21
27
  catch (error) {
22
- if (fallbackBundle)
23
- return jsResponse(fallbackBundle);
24
28
  serverLogger.debug("[ScriptHandlers] Build failed, serving raw TypeScript", error);
25
- const src = await adapter.fs.readFile(path);
26
- return new dntShim.Response(src, {
27
- headers: { "content-type": "application/typescript" },
28
- });
29
+ try {
30
+ const src = await adapter.fs.readFile(path);
31
+ return new dntShim.Response(src, {
32
+ headers: { "content-type": "application/typescript" },
33
+ });
34
+ }
35
+ catch {
36
+ return new dntShim.Response("// client-boot: source not available", {
37
+ headers: { "content-type": "application/javascript" },
38
+ });
39
+ }
29
40
  }
30
41
  finally {
31
42
  if (shouldStopEsbuild()) {
@@ -44,7 +55,6 @@ const CLIENT_BOOT_BUNDLE = "";
44
55
  const CLIENT_DOM_BUNDLE = "";
45
56
  export async function handleClientScript(adapter) {
46
57
  const path = new URL("../../../../rendering/rsc/client-boot.ts", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url).pathname;
47
- const contents = await adapter.fs.readFile(path);
48
58
  return buildOrServeScript(adapter, path, CLIENT_BOOT_BUNDLE, {
49
59
  bundle: true,
50
60
  write: false,
@@ -52,7 +62,7 @@ export async function handleClientScript(adapter) {
52
62
  platform: "browser",
53
63
  target: "es2020",
54
64
  stdin: {
55
- contents,
65
+ contents: "",
56
66
  loader: "ts",
57
67
  resolveDir: path.substring(0, path.lastIndexOf("/")),
58
68
  sourcefile: path,
@@ -62,7 +72,6 @@ export async function handleClientScript(adapter) {
62
72
  }
63
73
  export async function handleDomScript(adapter) {
64
74
  const path = new URL("../../../../rendering/rsc/client-dom.ts", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url).pathname;
65
- const contents = await adapter.fs.readFile(path);
66
75
  return buildOrServeScript(adapter, path, CLIENT_DOM_BUNDLE, {
67
76
  bundle: true,
68
77
  write: false,
@@ -70,7 +79,7 @@ export async function handleDomScript(adapter) {
70
79
  platform: "browser",
71
80
  target: "es2020",
72
81
  stdin: {
73
- contents,
82
+ contents: "",
74
83
  loader: "ts",
75
84
  resolveDir: path.substring(0, path.lastIndexOf("/")),
76
85
  sourcefile: path,
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.1.100";
1
+ export declare const VERSION = "0.1.101";
2
2
  export declare function normalizeVeryfrontVersion(version: string | undefined): string | undefined;
3
3
  export declare function resolveRuntimeVersion(options?: {
4
4
  veryfrontVersion?: string;
@@ -2,7 +2,7 @@ import denoConfig from "../../deno.js";
2
2
  import { getEnv } from "../platform/compat/process.js";
3
3
  // Keep in sync with deno.json version.
4
4
  // scripts/release.ts updates this constant during releases.
5
- export const VERSION = "0.1.100";
5
+ export const VERSION = "0.1.101";
6
6
  export function normalizeVeryfrontVersion(version) {
7
7
  if (!version)
8
8
  return undefined;
@@ -127,8 +127,8 @@ export class RedisEventPublisher {
127
127
  if (!this.initialized)
128
128
  return;
129
129
  await Promise.all([
130
- this.publishClient?.quit(),
131
- this.subscribeClient?.quit(),
130
+ this.publishClient?.close(),
131
+ this.subscribeClient?.close(),
132
132
  ]);
133
133
  this.publishClient = null;
134
134
  this.subscribeClient = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -136,11 +136,11 @@
136
136
  "@kreuzberg/wasm": "4.5.2",
137
137
  "@mdx-js/mdx": "3.1.1",
138
138
  "@opentelemetry/api": "1.9.0",
139
- "@opentelemetry/context-async-hooks": "1",
140
- "@opentelemetry/core": "1",
141
- "@opentelemetry/exporter-trace-otlp-http": "0.57",
142
- "@opentelemetry/resources": "1",
143
- "@opentelemetry/sdk-trace-base": "1",
139
+ "@opentelemetry/context-async-hooks": "2.6.0",
140
+ "@opentelemetry/core": "2.6.0",
141
+ "@opentelemetry/exporter-trace-otlp-http": "0.213.0",
142
+ "@opentelemetry/resources": "2.6.0",
143
+ "@opentelemetry/sdk-trace-base": "2.6.0",
144
144
  "@opentelemetry/semantic-conventions": "1.40.0",
145
145
  "@types/hast": "3.0.3",
146
146
  "@types/mdast": "4.0.3",
@@ -154,10 +154,10 @@
154
154
  "gray-matter": "4.0.3",
155
155
  "jose": "5.9.6",
156
156
  "mdast-util-to-string": "4.0.0",
157
- "mime-types": "2.1.35",
157
+ "mime-types": "3.0.2",
158
158
  "react": "19.2.4",
159
159
  "react-dom": "19.2.4",
160
- "redis": "4.6.13",
160
+ "redis": "5.11.0",
161
161
  "rehype-highlight": "7.0.2",
162
162
  "rehype-raw": "7.0.0",
163
163
  "rehype-sanitize": "6.0.0",
@@ -168,7 +168,7 @@
168
168
  "remark-gfm": "4.0.1",
169
169
  "remark-parse": "11.0.0",
170
170
  "remark-rehype": "11.1.2",
171
- "tailwind-merge": "2.6.0",
171
+ "tailwind-merge": "3.5.0",
172
172
  "tailwindcss": "4.2.2",
173
173
  "unified": "11.0.5",
174
174
  "unist-util-visit": "5.1.0",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -240,7 +240,7 @@ export default {
240
240
  "es-module-lexer": "npm:es-module-lexer@2.0.0",
241
241
  "gray-matter": "npm:gray-matter@4.0.3",
242
242
  "zod": "npm:zod@3.25.76",
243
- "mime-types": "npm:mime-types@2.1.35",
243
+ "mime-types": "npm:mime-types@3.0.2",
244
244
  "mdast": "npm:@types/mdast@4.0.3",
245
245
  "hast": "npm:@types/hast@3.0.3",
246
246
  "unist": "npm:@types/unist@3.0.2",
@@ -259,15 +259,15 @@ export default {
259
259
  "tailwindcss/plugin": "https://esm.sh/tailwindcss@4.2.2/plugin",
260
260
  "tailwindcss/defaultTheme": "https://esm.sh/tailwindcss@4.2.2/defaultTheme",
261
261
  "tailwindcss/colors": "https://esm.sh/tailwindcss@4.2.2/colors",
262
- "redis": "npm:redis@4.6.13",
262
+ "redis": "npm:redis@5.11.0",
263
263
  "pg": "npm:pg@8.13.1",
264
264
  "jose": "npm:jose@5.9.6",
265
265
  "@opentelemetry/api": "npm:@opentelemetry/api@1.9.0",
266
- "@opentelemetry/core": "npm:@opentelemetry/core@1",
267
- "@opentelemetry/context-async-hooks": "npm:@opentelemetry/context-async-hooks@1",
268
- "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@1",
269
- "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.57",
270
- "@opentelemetry/resources": "npm:@opentelemetry/resources@1",
266
+ "@opentelemetry/core": "npm:@opentelemetry/core@2.6.0",
267
+ "@opentelemetry/context-async-hooks": "npm:@opentelemetry/context-async-hooks@2.6.0",
268
+ "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@2.6.0",
269
+ "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.213.0",
270
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@2.6.0",
271
271
  "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@1.40.0",
272
272
  "@babel/parser": "npm:@babel/parser@7.29.2",
273
273
  "@babel/traverse": "npm:@babel/traverse@7.29.0",
@@ -275,7 +275,7 @@ export default {
275
275
  "@babel/types": "npm:@babel/types@7.29.0",
276
276
  "class-variance-authority": "npm:class-variance-authority@0.7.1",
277
277
  "clsx": "npm:clsx@2.1.1",
278
- "tailwind-merge": "npm:tailwind-merge@2.6.0",
278
+ "tailwind-merge": "npm:tailwind-merge@3.5.0",
279
279
  "@kreuzberg/wasm": "npm:@kreuzberg/wasm@4.5.2",
280
280
  "#kreuzberg-wasm-glue": "npm:@kreuzberg/wasm@4.5.2/dist/pkg/kreuzberg_wasm.js"
281
281
  },
@@ -110,13 +110,13 @@ export async function initializeOTLP(): Promise<void> {
110
110
  "@opentelemetry/sdk-trace-base"
111
111
  );
112
112
  const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
113
- const { Resource } = await import("@opentelemetry/resources");
113
+ const { resourceFromAttributes } = await import("@opentelemetry/resources");
114
114
  const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = await import(
115
115
  "@opentelemetry/semantic-conventions"
116
116
  );
117
117
  const { AsyncLocalStorageContextManager } = await import("@opentelemetry/context-async-hooks");
118
118
 
119
- const resource = new Resource({
119
+ const resource = resourceFromAttributes({
120
120
  [ATTR_SERVICE_NAME]: config.serviceName,
121
121
  [ATTR_SERVICE_VERSION]: RUNTIME_VERSION,
122
122
  });
@@ -127,17 +127,21 @@ export async function initializeOTLP(): Promise<void> {
127
127
  headers: config.headers,
128
128
  });
129
129
 
130
- const provider = new BasicTracerProvider({ resource });
131
- provider.addSpanProcessor(new BatchSpanProcessor(exporter));
132
-
133
130
  const contextManager = new AsyncLocalStorageContextManager();
134
131
  contextManager.enable();
135
- provider.register({ contextManager });
136
132
 
137
- tracerProvider = provider;
133
+ const provider = new BasicTracerProvider({
134
+ resource,
135
+ spanProcessors: [new BatchSpanProcessor(exporter)],
136
+ });
138
137
 
139
- // MUST be set before marking as initialized, otherwise withSpan will skip creating spans.
138
+ // In OTel SDK v2, provider.register() is removed.
139
+ // Set global tracer provider and context manager via the API directly.
140
140
  traceApi = await import("@opentelemetry/api");
141
+ traceApi.trace.setGlobalTracerProvider(provider);
142
+ traceApi.context.setGlobalContextManager(contextManager);
143
+
144
+ tracerProvider = provider;
141
145
 
142
146
  initialized = true;
143
147
  logger.info("OpenTelemetry OTLP tracing initialized", {
@@ -1,6 +1,6 @@
1
1
  import * as dntShim from "../../../../../_dnt.shims.js";
2
2
  import { logger as baseLogger } from "../../../../utils/index.js";
3
- import { CACHE_INVARIANT_VIOLATION, INVALID_ARGUMENT } from "../../../../errors/index.js";
3
+ import { CACHE_INVARIANT_VIOLATION, INVALID_ARGUMENT, VeryfrontError } from "../../../../errors/index.js";
4
4
  import { buildProxyManagerCacheKey } from "../../../../cache/index.js";
5
5
  import { VeryfrontFSAdapter } from "./index.js";
6
6
  import type { CacheStats, FSAdapterConfig, ResolvedContentContext } from "./types.js";
@@ -25,9 +25,80 @@ interface ProxyFSAdapterManagerConfig {
25
25
  maxIdleMs?: number;
26
26
  }
27
27
 
28
+ interface NegativeCacheEntry {
29
+ fallbackBranch: string | null;
30
+ timer: ReturnType<typeof dntShim.setTimeout>;
31
+ }
32
+
33
+ interface ApiErrorDetails {
34
+ responseText?: string;
35
+ url?: string;
36
+ }
37
+
38
+ function isPushPreviewBranch(branch: string | null | undefined, productionMode: boolean): boolean {
39
+ return !productionMode && !!branch && branch !== "main" && branch.startsWith("push-");
40
+ }
41
+
42
+ function getApiErrorDetails(error: unknown): ApiErrorDetails | null {
43
+ if (!(error instanceof VeryfrontError) || !error.context || typeof error.context !== "object") {
44
+ return null;
45
+ }
46
+
47
+ const details =
48
+ (error.context as { details?: { responseText?: unknown; url?: unknown } }).details;
49
+ if (!details || typeof details !== "object") return null;
50
+
51
+ const apiErrorDetails: ApiErrorDetails = {};
52
+ if (typeof details.responseText === "string") {
53
+ apiErrorDetails.responseText = details.responseText;
54
+ }
55
+ if (typeof details.url === "string") {
56
+ apiErrorDetails.url = details.url;
57
+ }
58
+
59
+ return apiErrorDetails.responseText || apiErrorDetails.url ? apiErrorDetails : null;
60
+ }
61
+
62
+ function getProblemDetail(error: unknown): string | null {
63
+ const responseText = getApiErrorDetails(error)?.responseText;
64
+ if (!responseText) return null;
65
+
66
+ try {
67
+ const parsed = JSON.parse(responseText) as { detail?: unknown };
68
+ return typeof parsed.detail === "string" ? parsed.detail : null;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+
74
+ export function getPushRefFallbackBranch(
75
+ error: unknown,
76
+ branch: string | null | undefined,
77
+ productionMode = false,
78
+ ): string | null {
79
+ if (!branch || !isPushPreviewBranch(branch, productionMode)) return null;
80
+ if (!(error instanceof VeryfrontError) || error.status !== 404) return null;
81
+
82
+ const apiErrorDetails = getApiErrorDetails(error);
83
+ if (
84
+ !apiErrorDetails?.url?.includes("/files?") ||
85
+ !apiErrorDetails.url.includes(`branch=${encodeURIComponent(branch)}`)
86
+ ) {
87
+ return null;
88
+ }
89
+
90
+ const detail = getProblemDetail(error);
91
+ if (detail && !detail.includes(`Branch '${branch}' not found`)) {
92
+ return null;
93
+ }
94
+
95
+ return "main";
96
+ }
97
+
28
98
  export class ProxyFSAdapterManager {
29
99
  private adapters = new Map<string, ProjectAdapter>();
30
100
  private pendingAdapters = new Map<string, Promise<VeryfrontFSAdapter>>();
101
+ private negativeCacheEntries = new Map<string, NegativeCacheEntry>();
31
102
  private baseConfig: FSAdapterConfig;
32
103
  private maxAdapters: number;
33
104
  private maxIdleMs: number;
@@ -121,6 +192,37 @@ export class ProxyFSAdapterManager {
121
192
  totalCachedAdapters: this.adapters.size,
122
193
  });
123
194
 
195
+ const negativeEntry = this.negativeCacheEntries.get(cacheKey);
196
+ if (negativeEntry?.fallbackBranch && negativeEntry.fallbackBranch !== effectiveBranch) {
197
+ logger.warn("Using cached fallback branch for push ref", {
198
+ branch: effectiveBranch,
199
+ cacheKey,
200
+ fallbackBranch: negativeEntry.fallbackBranch,
201
+ projectSlug,
202
+ });
203
+ return this.getAdapter(
204
+ projectSlug,
205
+ token,
206
+ projectId,
207
+ effectiveProductionMode,
208
+ effectiveReleaseId,
209
+ effectiveEnvironmentName,
210
+ negativeEntry.fallbackBranch,
211
+ );
212
+ }
213
+
214
+ // Reject known-bad cache keys only when there is no fallback target.
215
+ if (negativeEntry) {
216
+ logger.warn("Rejecting adapter request for negatively-cached key", {
217
+ cacheKey,
218
+ projectSlug,
219
+ });
220
+ throw INVALID_ARGUMENT.create({
221
+ detail:
222
+ `Adapter for "${cacheKey}" is negatively cached (previous initialization returned 404). Retry after 60s.`,
223
+ });
224
+ }
225
+
124
226
  const existing = this.adapters.get(cacheKey);
125
227
  if (existing) {
126
228
  existing.lastAccessed = Date.now();
@@ -350,12 +452,51 @@ export class ProxyFSAdapterManager {
350
452
  this.adapters.set(cacheKey, projectAdapter);
351
453
  return adapter;
352
454
  } catch (error) {
455
+ const fallbackBranch = getPushRefFallbackBranch(error, branch, productionMode);
456
+
457
+ if (fallbackBranch) {
458
+ const NEGATIVE_CACHE_TTL_MS = 60_000;
459
+ logger.warn("Push ref initialization returned 404, retrying with fallback branch", {
460
+ branch,
461
+ cacheKey,
462
+ duration: `${(performance.now() - initStartTime).toFixed(2)}ms`,
463
+ fallbackBranch,
464
+ projectSlug,
465
+ });
466
+ const existingEntry = this.negativeCacheEntries.get(cacheKey);
467
+ if (existingEntry) {
468
+ clearTimeout(existingEntry.timer);
469
+ }
470
+ const timer = dntShim.setTimeout(() => {
471
+ this.negativeCacheEntries.delete(cacheKey);
472
+ logger.debug("Negative cache sentinel expired", { cacheKey });
473
+ }, NEGATIVE_CACHE_TTL_MS);
474
+ // Unref so the timer doesn't keep processes/tests alive
475
+ try {
476
+ dntShim.Deno.unrefTimer(timer);
477
+ } catch {
478
+ // Not available in all runtimes
479
+ }
480
+ this.negativeCacheEntries.set(cacheKey, { fallbackBranch, timer });
481
+
482
+ return await this.getAdapter(
483
+ projectSlug,
484
+ token,
485
+ projectId,
486
+ productionMode,
487
+ releaseId,
488
+ environmentName,
489
+ fallbackBranch,
490
+ );
491
+ }
492
+
353
493
  logger.error("Adapter initialization failed", {
354
494
  cacheKey,
355
495
  projectSlug,
356
496
  duration: `${(performance.now() - initStartTime).toFixed(2)}ms`,
357
497
  error: error instanceof Error ? error.message : String(error),
358
498
  });
499
+
359
500
  throw error;
360
501
  } finally {
361
502
  projectAdapter.initializing = undefined;
@@ -432,6 +573,12 @@ export class ProxyFSAdapterManager {
432
573
  this.cleanupTimer = undefined;
433
574
  }
434
575
 
576
+ // Clear negative cache timers
577
+ for (const entry of this.negativeCacheEntries.values()) {
578
+ clearTimeout(entry.timer);
579
+ }
580
+ this.negativeCacheEntries.clear();
581
+
435
582
  for (const [cacheKey, adapter] of this.adapters) {
436
583
  logger.debug("Disposing adapter", { cacheKey });
437
584
  adapter.adapter.dispose();
@@ -116,10 +116,12 @@ export class NodeRedisAdapter implements RedisAdapter {
116
116
  }
117
117
 
118
118
  quit(): Promise<void> {
119
- return this.client.quit();
119
+ // redis v5: quit() renamed to close()
120
+ return this.client.close();
120
121
  }
121
122
 
122
123
  disconnect(): Promise<void> {
123
- return this.client.disconnect();
124
+ // redis v5: disconnect() renamed to destroy()
125
+ return this.client.destroy();
124
126
  }
125
127
  }
@@ -79,6 +79,6 @@ export interface NodeRedisClient {
79
79
  options?: { NX?: boolean; PX?: number; EX?: number },
80
80
  ): Promise<string | null>;
81
81
  get(key: string): Promise<string | null>;
82
- quit(): Promise<void>;
83
- disconnect(): Promise<void>;
82
+ close(): Promise<void>;
83
+ destroy(): Promise<void>;
84
84
  }
@@ -118,21 +118,23 @@ export class RedisCache implements TokenCache {
118
118
  const client = await this.getConnectedClient();
119
119
 
120
120
  const pattern = `${this.prefix}*`;
121
- let cursor = 0;
121
+ // redis v5: scan cursor is string-based to prevent Number.MAX_SAFE_INTEGER overflow
122
+ let cursor = "0";
122
123
  let totalDeleted = 0;
123
124
 
124
125
  do {
125
- const { cursor: nextCursor, keys } = await client.scan(cursor, {
126
+ // deno-lint-ignore no-explicit-any
127
+ const result = await (client as any).scan(cursor, {
126
128
  MATCH: pattern,
127
129
  COUNT: DEFAULT_SCAN_COUNT,
128
130
  });
129
131
 
130
- cursor = nextCursor;
132
+ cursor = String(result.cursor);
131
133
 
132
- if (keys.length > 0) {
133
- totalDeleted += await client.del(keys);
134
+ if (result.keys.length > 0) {
135
+ totalDeleted += await client.del(result.keys);
134
136
  }
135
- } while (cursor !== 0);
137
+ } while (cursor !== "0");
136
138
 
137
139
  if (totalDeleted > 0) {
138
140
  logger.info(`[RedisCache] Cleared ${totalDeleted} keys`);
@@ -196,7 +198,7 @@ export class RedisCache implements TokenCache {
196
198
  }
197
199
 
198
200
  try {
199
- await client.quit();
201
+ await client.close();
200
202
  } catch (_) {
201
203
  // expected: close errors are non-critical
202
204
  } finally {
@@ -88,13 +88,13 @@ export async function initializeOTLPWithApis(): Promise<void> {
88
88
  "@opentelemetry/sdk-trace-base"
89
89
  );
90
90
  const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
91
- const { Resource } = await import("@opentelemetry/resources");
91
+ const { resourceFromAttributes } = await import("@opentelemetry/resources");
92
92
  const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = await import(
93
93
  "@opentelemetry/semantic-conventions"
94
94
  );
95
95
 
96
96
  const resourceAttrs = parseResourceAttributes(getEnv("OTEL_RESOURCE_ATTRIBUTES"));
97
- const resource = new Resource({
97
+ const resource = resourceFromAttributes({
98
98
  [ATTR_SERVICE_NAME]: config.serviceName,
99
99
  [ATTR_SERVICE_VERSION]: PROXY_RUNTIME_VERSION,
100
100
  ...resourceAttrs,
@@ -105,9 +105,13 @@ export async function initializeOTLPWithApis(): Promise<void> {
105
105
  headers: config.headers,
106
106
  });
107
107
 
108
- const provider = new BasicTracerProvider({ resource });
109
- provider.addSpanProcessor(new BatchSpanProcessor(exporter));
110
- provider.register();
108
+ const provider = new BasicTracerProvider({
109
+ resource,
110
+ spanProcessors: [new BatchSpanProcessor(exporter)],
111
+ });
112
+
113
+ // In OTel SDK v2, provider.register() is removed.
114
+ trace.setGlobalTracerProvider(provider);
111
115
 
112
116
  tracerProvider = provider;
113
117
  tracer = trace.getTracer(config.serviceName);
@@ -22,27 +22,37 @@ async function buildOrServeScript(
22
22
  stdin: import("esbuild").StdinOptions;
23
23
  },
24
24
  ): Promise<dntShim.Response> {
25
+ // If a pre-built bundle was injected at compile time, serve it directly
26
+ if (fallbackBundle) return jsResponse(fallbackBundle);
27
+
25
28
  let esbuild: typeof import("esbuild") | null = null;
26
29
 
27
30
  try {
28
- esbuild = await import("esbuild");
29
31
  const src = await adapter.fs.readFile(path);
30
- const result = await esbuild.build(esbuildOptions);
32
+ esbuild = await import("esbuild");
33
+ const result = await esbuild.build({
34
+ ...esbuildOptions,
35
+ stdin: { ...esbuildOptions.stdin, contents: src },
36
+ });
31
37
  const out = result.outputFiles?.[0]?.text ?? src;
32
38
 
33
39
  return jsResponse(out);
34
40
  } catch (error) {
35
- if (fallbackBundle) return jsResponse(fallbackBundle);
36
-
37
41
  serverLogger.debug(
38
42
  "[ScriptHandlers] Build failed, serving raw TypeScript",
39
43
  error,
40
44
  );
41
45
 
42
- const src = await adapter.fs.readFile(path);
43
- return new dntShim.Response(src, {
44
- headers: { "content-type": "application/typescript" },
45
- });
46
+ try {
47
+ const src = await adapter.fs.readFile(path);
48
+ return new dntShim.Response(src, {
49
+ headers: { "content-type": "application/typescript" },
50
+ });
51
+ } catch {
52
+ return new dntShim.Response("// client-boot: source not available", {
53
+ headers: { "content-type": "application/javascript" },
54
+ });
55
+ }
46
56
  } finally {
47
57
  if (shouldStopEsbuild()) {
48
58
  try {
@@ -68,8 +78,6 @@ export async function handleClientScript(
68
78
  import.meta.url,
69
79
  ).pathname;
70
80
 
71
- const contents = await adapter.fs.readFile(path);
72
-
73
81
  return buildOrServeScript(adapter, path, CLIENT_BOOT_BUNDLE, {
74
82
  bundle: true,
75
83
  write: false,
@@ -77,7 +85,7 @@ export async function handleClientScript(
77
85
  platform: "browser",
78
86
  target: "es2020",
79
87
  stdin: {
80
- contents,
88
+ contents: "",
81
89
  loader: "ts",
82
90
  resolveDir: path.substring(0, path.lastIndexOf("/")),
83
91
  sourcefile: path,
@@ -92,8 +100,6 @@ export async function handleDomScript(adapter: RuntimeAdapter): Promise<dntShim.
92
100
  import.meta.url,
93
101
  ).pathname;
94
102
 
95
- const contents = await adapter.fs.readFile(path);
96
-
97
103
  return buildOrServeScript(adapter, path, CLIENT_DOM_BUNDLE, {
98
104
  bundle: true,
99
105
  write: false,
@@ -101,7 +107,7 @@ export async function handleDomScript(adapter: RuntimeAdapter): Promise<dntShim.
101
107
  platform: "browser",
102
108
  target: "es2020",
103
109
  stdin: {
104
- contents,
110
+ contents: "",
105
111
  loader: "ts",
106
112
  resolveDir: path.substring(0, path.lastIndexOf("/")),
107
113
  sourcefile: path,
@@ -3,7 +3,7 @@ import { getEnv } from "../platform/compat/process.js";
3
3
 
4
4
  // Keep in sync with deno.json version.
5
5
  // scripts/release.ts updates this constant during releases.
6
- export const VERSION = "0.1.100";
6
+ export const VERSION = "0.1.101";
7
7
 
8
8
  export function normalizeVeryfrontVersion(version: string | undefined): string | undefined {
9
9
  if (!version) return undefined;
@@ -96,7 +96,7 @@ interface RedisClient {
96
96
  publish(channel: string, message: string): Promise<number>;
97
97
  subscribe(channel: string, listener: (message: string) => void): Promise<void>;
98
98
  unsubscribe(channel: string): Promise<void>;
99
- quit(): Promise<void>;
99
+ close(): Promise<void>;
100
100
  }
101
101
 
102
102
  export class RedisEventPublisher implements ClaudeCodeEventPublisher, ClaudeCodeEventSubscriber {
@@ -193,8 +193,8 @@ export class RedisEventPublisher implements ClaudeCodeEventPublisher, ClaudeCode
193
193
  if (!this.initialized) return;
194
194
 
195
195
  await Promise.all([
196
- this.publishClient?.quit(),
197
- this.subscribeClient?.quit(),
196
+ this.publishClient?.close(),
197
+ this.subscribeClient?.close(),
198
198
  ]);
199
199
 
200
200
  this.publishClient = null;