veryfront 0.1.1240 → 0.1.1241

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 (57) hide show
  1. package/esm/deno.d.ts +1 -0
  2. package/esm/deno.js +4 -3
  3. package/esm/extensions/ext-llm-openai/src/openai-chat-stream.d.ts.map +1 -1
  4. package/esm/extensions/ext-llm-openai/src/openai-chat-stream.js +16 -6
  5. package/esm/src/cache/request-cache-batcher.d.ts +1 -0
  6. package/esm/src/cache/request-cache-batcher.d.ts.map +1 -1
  7. package/esm/src/cache/request-cache-batcher.js +21 -7
  8. package/esm/src/html/html-injection.d.ts +2 -0
  9. package/esm/src/html/html-injection.d.ts.map +1 -1
  10. package/esm/src/html/html-injection.js +4 -1
  11. package/esm/src/html/html-shell-generator.d.ts.map +1 -1
  12. package/esm/src/html/html-shell-generator.js +11 -3
  13. package/esm/src/html/hydration-script-builder/hydration-runtime.generated.js +1 -1
  14. package/esm/src/html/hydration-script-builder/prod-runtime-selection.d.ts +23 -0
  15. package/esm/src/html/hydration-script-builder/prod-runtime-selection.d.ts.map +1 -0
  16. package/esm/src/html/hydration-script-builder/prod-runtime-selection.js +55 -0
  17. package/esm/src/html/hydration-script-builder/prod-scripts.d.ts +2 -0
  18. package/esm/src/html/hydration-script-builder/prod-scripts.d.ts.map +1 -1
  19. package/esm/src/html/hydration-script-builder/prod-scripts.js +12 -3
  20. package/esm/src/html/schemas/html.schema.d.ts +2 -0
  21. package/esm/src/html/schemas/html.schema.d.ts.map +1 -1
  22. package/esm/src/html/schemas/html.schema.js +2 -0
  23. package/esm/src/platform/adapters/fs/cache/file-cache.d.ts.map +1 -1
  24. package/esm/src/platform/adapters/fs/cache/file-cache.js +5 -0
  25. package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts +39 -0
  26. package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
  27. package/esm/src/platform/adapters/fs/veryfront/adapter.js +209 -40
  28. package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
  29. package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +9 -1
  30. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts +2 -1
  31. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
  32. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +78 -32
  33. package/esm/src/platform/compat/http/pinned-fetch.d.ts +1 -1
  34. package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
  35. package/esm/src/rendering/orchestrator/html.js +23 -8
  36. package/esm/src/rendering/page-renderer.d.ts +2 -0
  37. package/esm/src/rendering/page-renderer.d.ts.map +1 -1
  38. package/esm/src/rendering/page-renderer.js +1 -0
  39. package/esm/src/rendering/renderer.d.ts.map +1 -1
  40. package/esm/src/rendering/renderer.js +1 -0
  41. package/esm/src/rendering/script-page-handling.d.ts +2 -0
  42. package/esm/src/rendering/script-page-handling.d.ts.map +1 -1
  43. package/esm/src/rendering/script-page-handling.js +17 -1
  44. package/esm/src/rendering/snippet-renderer.d.ts +10 -0
  45. package/esm/src/rendering/snippet-renderer.d.ts.map +1 -1
  46. package/esm/src/rendering/snippet-renderer.js +40 -18
  47. package/esm/src/server/handlers/request/snippet.handler.d.ts +6 -0
  48. package/esm/src/server/handlers/request/snippet.handler.d.ts.map +1 -1
  49. package/esm/src/server/handlers/request/snippet.handler.js +8 -1
  50. package/esm/src/server/handlers/request/static.handler.d.ts.map +1 -1
  51. package/esm/src/server/handlers/request/static.handler.js +1 -0
  52. package/esm/src/server/services/static/static-file.service.d.ts +4 -1
  53. package/esm/src/server/services/static/static-file.service.d.ts.map +1 -1
  54. package/esm/src/server/services/static/static-file.service.js +48 -22
  55. package/esm/src/utils/version-constant.d.ts +1 -1
  56. package/esm/src/utils/version-constant.js +1 -1
  57. package/package.json +8 -8
package/esm/deno.d.ts CHANGED
@@ -472,6 +472,7 @@ declare namespace _default {
472
472
  "lint:barrel-jsdoc": string;
473
473
  "lint:ban-test-only": string;
474
474
  "lint:sanitizer-baseline": string;
475
+ "lint:secret-scanning-config": string;
475
476
  "lint:skipped-tests": string;
476
477
  "lint:cwd-relative-test-reads": string;
477
478
  "lint:anti-slop": string;
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1240",
3
+ "version": "0.1.1241",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -499,7 +499,7 @@ export default {
499
499
  "build:storybook": "npm --prefix storybook run build-storybook",
500
500
  "storybook:check": "deno test --no-lock --config=scripts/test.deno.json --no-check --allow-read scripts/storybook/storybook-workbench.test.ts",
501
501
  "lint": "DENO_NO_PACKAGE_JSON=1 deno lint && deno lint --config=scripts/test.deno.json scripts/test/ scripts/build/dnt-meta-property-safety.ts scripts/build/dnt-meta-property-safety.test.ts scripts/build/dnt-polyfill.ts scripts/build/dnt-polyfill.test.ts scripts/build/npm-package-metadata.test.ts scripts/build/prepare-framework-sources.test.ts && deno lint --config=scripts/codemods/deno.json scripts/codemods/",
502
- "lint:ci": "deno task lint && deno task lint:core-deps && deno task lint:cross-runtime-jsr && deno task lint:dependency-boundaries && deno task lint:module-boundaries && deno task lint:client-bundle && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:skipped-tests && deno task lint:chat-ratchets && deno task lint:chat-composability && deno task lint:rfc-status && deno task lint:esm-sh-codemod && deno task lint:test-typecheck && deno task lint:cwd-relative-test-reads && deno task lint:anti-slop && deno task lint:dnt-meta-properties && deno task storybook:check && deno task docs:api-reference:check && deno task docs:errors:check && deno task docs:public:check && deno test --frozen --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run=bash scripts/ci/setup-deno-workflow.test.ts scripts/ci/prepare-rc-build.test.ts scripts/build/generated-artifact-checks.test.ts scripts/release.test.ts",
502
+ "lint:ci": "deno task lint && deno task lint:core-deps && deno task lint:cross-runtime-jsr && deno task lint:dependency-boundaries && deno task lint:module-boundaries && deno task lint:client-bundle && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task lint:ban-test-only && deno task lint:sanitizer-baseline && deno task lint:secret-scanning-config && deno task lint:skipped-tests && deno task lint:chat-ratchets && deno task lint:chat-composability && deno task lint:rfc-status && deno task lint:esm-sh-codemod && deno task lint:test-typecheck && deno task lint:cwd-relative-test-reads && deno task lint:anti-slop && deno task lint:dnt-meta-properties && deno task storybook:check && deno task docs:api-reference:check && deno task docs:errors:check && deno task docs:public:check && deno test --frozen --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run=bash scripts/ci/setup-deno-workflow.test.ts scripts/ci/prepare-rc-build.test.ts scripts/build/generated-artifact-checks.test.ts scripts/release.test.ts",
503
503
  "fmt": "deno fmt src/ cli/ react/ templates/ && deno fmt --config=scripts/test.deno.json scripts/test/ scripts/build/dnt-meta-property-safety.ts scripts/build/dnt-meta-property-safety.test.ts scripts/build/dnt-polyfill.ts scripts/build/dnt-polyfill.test.ts scripts/build/prepare-framework-sources.test.ts && deno fmt --config=scripts/codemods/deno.json scripts/codemods/",
504
504
  "fmt:check": "deno fmt --check src/ cli/ react/ templates/ && deno fmt --check --config=scripts/test.deno.json scripts/test/ scripts/build/dnt-meta-property-safety.ts scripts/build/dnt-meta-property-safety.test.ts scripts/build/dnt-polyfill.ts scripts/build/dnt-polyfill.test.ts scripts/build/prepare-framework-sources.test.ts && deno fmt --check --config=scripts/codemods/deno.json scripts/codemods/",
505
505
  "typecheck": "deno task generate:manifests:check && deno check src/index.ts cli/main.ts src/server/index.ts src/routing/api/index.ts src/rendering/index.ts src/platform/index.ts src/platform/adapters/index.ts src/build/index.ts src/build/production-build/index.ts src/transforms/index.ts src/config/index.ts src/utils/index.ts src/data/index.ts src/security/index.ts src/middleware/index.ts src/server/handlers/dev/index.ts src/server/handlers/request/api/index.ts src/rendering/cache/index.ts src/rendering/cache/stores/index.ts src/rendering/rsc/actions/index.ts src/html/index.ts src/html/hydration-script-builder/runtime/main.ts src/modules/index.ts src/proxy/main.ts src/react/components/ui/index.ts src/chat/index.ts src/markdown/index.ts src/mdx/index.ts src/fs/index.ts src/oauth/index.ts src/agent/index.ts src/agent/service/route-export.check.ts src/eval/index.ts src/tool/index.ts src/workflow/index.ts src/prompt/index.ts src/resource/index.ts src/runs/index.ts src/mcp/index.ts src/provider/index.ts",
@@ -548,11 +548,12 @@ export default {
548
548
  "lint:barrel-jsdoc": "deno run --allow-read scripts/lint/check-barrel-jsdoc.ts",
549
549
  "lint:ban-test-only": "deno run --allow-read scripts/lint/ban-test-only.ts",
550
550
  "lint:sanitizer-baseline": "deno run --allow-read scripts/lint/check-sanitizer-baseline.ts",
551
+ "lint:secret-scanning-config": "deno test --frozen --config=scripts/test.deno.json --no-check --allow-read scripts/security/secret-scanning-config.test.ts",
551
552
  "lint:skipped-tests": "deno run --allow-read scripts/lint/check-skipped-tests-baseline.ts",
552
553
  "lint:cwd-relative-test-reads": "deno run --allow-read scripts/lint/audit-cwd-relative-test-reads.ts",
553
554
  "lint:anti-slop": "deno run --allow-read scripts/lint/audit-anti-slop.ts",
554
555
  "lint:dnt-meta-properties": "deno run --config=scripts/test.deno.json --frozen --allow-read scripts/build/dnt-meta-property-safety.ts",
555
- "test:scripts": "deno test --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run scripts/ci/prepare-rc-build.test.ts scripts/ci/publish-npm-packages.test.ts scripts/ci/setup-deno-workflow.test.ts scripts/build/compile-binary.test.ts scripts/build/dnt-meta-property-safety.test.ts scripts/build/dnt-polyfill.test.ts scripts/build/generate-sbom.test.ts scripts/build/generated-artifact-checks.test.ts scripts/build/npm-dependency-sources.test.ts scripts/build/npm-extension-package-metadata.test.ts scripts/build/npm-package-metadata.test.ts scripts/build/npm-react-shims.test.ts scripts/build/npm-runtime-helper-contract.test.ts scripts/build/prepare-framework-sources.test.ts scripts/build/report-artifact-sizes.test.ts scripts/build/run-generate.test.ts scripts/docs/docs-coverage.test.ts scripts/docs/generate-api-reference.test.ts scripts/docs/guide-validation.test.ts scripts/lint/audit-chat-composability.test.ts scripts/lint/audit-rfc-status.test.ts scripts/lint/audit-core-deps.test.ts scripts/lint/audit-cwd-relative-test-reads.test.ts scripts/lint/audit-cross-runtime-jsr.test.ts scripts/lint/audit-dependency-boundaries.test.ts scripts/lint/audit-extension-capabilities.test.ts scripts/lint/audit-extension-contracts.test.ts scripts/lint/audit-deps.test.ts scripts/lint/check-module-boundaries.test.ts scripts/lint/lint-config.test.ts scripts/lint/ban-test-only.test.ts scripts/lint/check-sanitizer-baseline.test.ts scripts/lint/check-skipped-tests-baseline.test.ts scripts/lint/audit-anti-slop.test.ts scripts/lint/check-test-typecheck-baseline.test.ts scripts/lint/check-coverage.test.ts scripts/security/audit-npm.test.ts scripts/security/submit-dependency-snapshot.test.ts scripts/test/template-runtime-e2e.test.ts && deno task test:tool-search-live",
556
+ "test:scripts": "deno test --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run scripts/ci/prepare-rc-build.test.ts scripts/ci/publish-npm-packages.test.ts scripts/ci/setup-deno-workflow.test.ts scripts/build/compile-binary.test.ts scripts/build/dnt-meta-property-safety.test.ts scripts/build/dnt-polyfill.test.ts scripts/build/generate-sbom.test.ts scripts/build/generated-artifact-checks.test.ts scripts/build/npm-dependency-sources.test.ts scripts/build/npm-extension-package-metadata.test.ts scripts/build/npm-package-metadata.test.ts scripts/build/npm-react-shims.test.ts scripts/build/npm-runtime-helper-contract.test.ts scripts/build/prepare-framework-sources.test.ts scripts/build/report-artifact-sizes.test.ts scripts/build/run-generate.test.ts scripts/docs/docs-coverage.test.ts scripts/docs/generate-api-reference.test.ts scripts/docs/guide-validation.test.ts scripts/lint/audit-chat-composability.test.ts scripts/lint/audit-rfc-status.test.ts scripts/lint/audit-core-deps.test.ts scripts/lint/audit-cwd-relative-test-reads.test.ts scripts/lint/audit-cross-runtime-jsr.test.ts scripts/lint/audit-dependency-boundaries.test.ts scripts/lint/audit-extension-capabilities.test.ts scripts/lint/audit-extension-contracts.test.ts scripts/lint/audit-deps.test.ts scripts/lint/check-module-boundaries.test.ts scripts/lint/lint-config.test.ts scripts/lint/ban-test-only.test.ts scripts/lint/check-sanitizer-baseline.test.ts scripts/lint/check-skipped-tests-baseline.test.ts scripts/lint/audit-anti-slop.test.ts scripts/lint/check-test-typecheck-baseline.test.ts scripts/lint/check-coverage.test.ts scripts/security/audit-npm.test.ts scripts/security/secret-scanning-config.test.ts scripts/security/submit-dependency-snapshot.test.ts scripts/test/template-runtime-e2e.test.ts && deno task test:tool-search-live",
556
557
  "test:sentry-runtime-packages": "deno test --config=scripts/test.deno.json --no-check --no-lock --allow-read --allow-write --allow-run --allow-env=DENO_DIR,HOME,XDG_CACHE_HOME,LOCALAPPDATA,USERPROFILE scripts/build/sentry-runtime-packages.test.ts",
557
558
  "test:tool-search-live": "VF_DISABLE_LRU_INTERVAL=1 deno test --no-check -A tests/agent/verify-tool-search-live.test.ts",
558
559
  "test:cross-runtime": "deno run --allow-all src/platform/compat/cross-runtime.test.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-stream.ts"],"names":[],"mappings":"AA2BA,KAAK,4BAA4B,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AAExE,KAAK,uBAAuB,GAAG;IAC7B,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AASF,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AA4KlD,wBAAuB,2BAA2B,CAChD,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,OAAO,GAAE,uBAA4B,GACpC,aAAa,CAAC,OAAO,CAAC,CA0UxB"}
1
+ {"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-stream.ts"],"names":[],"mappings":"AA2BA,KAAK,4BAA4B,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AAExE,KAAK,uBAAuB,GAAG;IAC7B,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AASF,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AA4KlD,wBAAuB,2BAA2B,CAChD,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,OAAO,GAAE,uBAA4B,GACpC,aAAa,CAAC,OAAO,CAAC,CAsVxB"}
@@ -219,11 +219,16 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
219
219
  }
220
220
  delta = deltaRecord;
221
221
  }
222
- if (delta.role !== undefined &&
222
+ // Optional delta fields are `null` rather than absent on many
223
+ // OpenAI-compatible gateways (Moonshot/Kimi sends `reasoning_content: null`
224
+ // on both the opening and the finish chunk). Treat `null` as "not present
225
+ // on this chunk", matching how `content`, `refusal`, `tool_calls`, and
226
+ // `finish_reason` are already handled below.
227
+ if (delta.role !== undefined && delta.role !== null &&
223
228
  delta.role !== "assistant") {
224
229
  throw invalidOpenAIStream(context, "choice delta role was not assistant");
225
230
  }
226
- if (delta.reasoning_content !== undefined &&
231
+ if (delta.reasoning_content !== undefined && delta.reasoning_content !== null &&
227
232
  typeof delta.reasoning_content !== "string") {
228
233
  throw invalidOpenAIStream(context, "reasoning delta was malformed");
229
234
  }
@@ -272,11 +277,15 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
272
277
  throw invalidOpenAIStream(context, "tool call index was malformed");
273
278
  }
274
279
  const toolCallIndex = index;
275
- if (toolCallRecord.id !== undefined &&
280
+ // As with the reasoning delta above, gateways repeat `id`, `type`, and
281
+ // `function.name` as `null` on continuation fragments instead of omitting
282
+ // them; only the opening fragment carries real values. Treat `null` as
283
+ // absent so the fragment merges into the call already being assembled.
284
+ if (toolCallRecord.id !== undefined && toolCallRecord.id !== null &&
276
285
  !isBoundedOpenAIStreamString(toolCallRecord.id, MAX_OPENAI_STREAM_IDENTIFIER_BYTES)) {
277
286
  throw invalidOpenAIStream(context, "tool call id was malformed");
278
287
  }
279
- if (toolCallRecord.type !== undefined &&
288
+ if (toolCallRecord.type !== undefined && toolCallRecord.type !== null &&
280
289
  toolCallRecord.type !== "function") {
281
290
  throw invalidOpenAIStream(context, "tool call type was not function");
282
291
  }
@@ -306,7 +315,7 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
306
315
  if (!fn) {
307
316
  throw invalidOpenAIStream(context, "tool call function was not an object");
308
317
  }
309
- if (fn.name !== undefined &&
318
+ if (fn.name !== undefined && fn.name !== null &&
310
319
  !isBoundedOpenAIStreamString(fn.name, MAX_OPENAI_STREAM_TOOL_NAME_BYTES)) {
311
320
  throw invalidOpenAIStream(context, "tool call function name was malformed");
312
321
  }
@@ -324,7 +333,8 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
324
333
  toolName: current.name,
325
334
  };
326
335
  }
327
- if (fn.arguments !== undefined && typeof fn.arguments !== "string") {
336
+ if (fn.arguments !== undefined && fn.arguments !== null &&
337
+ typeof fn.arguments !== "string") {
328
338
  throw invalidOpenAIStream(context, "tool call arguments delta was malformed");
329
339
  }
330
340
  if (typeof fn.arguments === "string") {
@@ -7,6 +7,7 @@ interface PendingRequest {
7
7
  interface RequestCacheContext {
8
8
  cache: Map<string, string | null>;
9
9
  pending: Map<string, Promise<string | null>>;
10
+ mutationVersions: Map<string, number>;
10
11
  batchQueue: PendingRequest[];
11
12
  batchTimer: ReturnType<typeof setTimeout> | null;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request-cache-batcher.d.ts","sourceRoot":"","sources":["../../../src/src/cache/request-cache-batcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKjD,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7C,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;CAClD;AAMD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAexE;AAED,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,SAAS,CAExE;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkCxB;AAgDD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEzE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAK9E"}
1
+ {"version":3,"file":"request-cache-batcher.d.ts","sourceRoot":"","sources":["../../../src/src/cache/request-cache-batcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKjD,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7C,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC;CAClD;AAMD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAgBxE;AAED,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,SAAS,CAExE;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4CxB;AA+CD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAKzE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAK9E"}
@@ -10,6 +10,7 @@ export function runWithCacheBatching(fn) {
10
10
  const context = {
11
11
  cache: new Map(),
12
12
  pending: new Map(),
13
+ mutationVersions: new Map(),
13
14
  batchQueue: [],
14
15
  batchTimer: null,
15
16
  };
@@ -35,7 +36,8 @@ export async function getCachedWithBatching(backend, key) {
35
36
  const existingPending = ctx.pending.get(key);
36
37
  if (existingPending)
37
38
  return existingPending;
38
- const promise = new Promise((resolve, reject) => {
39
+ const mutationVersion = ctx.mutationVersions.get(key) ?? 0;
40
+ const backendPromise = new Promise((resolve, reject) => {
39
41
  ctx.batchQueue.push({ key, resolve, reject });
40
42
  if (ctx.batchQueue.length >= MAX_BATCH_SIZE) {
41
43
  void flushBatch(ctx, backend);
@@ -48,14 +50,23 @@ export async function getCachedWithBatching(backend, key) {
48
50
  void flushBatch(ctx, backend);
49
51
  }, BATCH_DELAY_MS);
50
52
  });
51
- ctx.pending.set(key, promise);
52
- try {
53
- const result = await promise;
53
+ // An explicit request-local set or delete supersedes a backend read that was
54
+ // already in flight. Return that newer local view instead of letting the
55
+ // pending result overwrite it when the backend eventually responds.
56
+ const promise = backendPromise.then((result) => {
57
+ if ((ctx.mutationVersions.get(key) ?? 0) !== mutationVersion) {
58
+ return ctx.cache.get(key) ?? null;
59
+ }
54
60
  ctx.cache.set(key, result);
55
61
  return result;
62
+ });
63
+ ctx.pending.set(key, promise);
64
+ try {
65
+ return await promise;
56
66
  }
57
67
  finally {
58
- ctx.pending.delete(key);
68
+ if (ctx.pending.get(key) === promise)
69
+ ctx.pending.delete(key);
59
70
  }
60
71
  }
61
72
  async function flushBatch(ctx, backend) {
@@ -79,7 +90,6 @@ async function flushBatch(ctx, backend) {
79
90
  : await getIndividually(backend, uniqueKeys);
80
91
  for (const request of requests) {
81
92
  const value = results.get(request.key) ?? null;
82
- ctx.cache.set(request.key, value);
83
93
  request.resolve(value);
84
94
  }
85
95
  }
@@ -95,7 +105,11 @@ async function getIndividually(backend, keys) {
95
105
  return buildBatchResults(keys, (key) => entries.get(key) ?? null);
96
106
  }
97
107
  export function setInRequestCache(key, value) {
98
- asyncLocalStorage.getStore()?.cache.set(key, value);
108
+ const ctx = asyncLocalStorage.getStore();
109
+ if (!ctx)
110
+ return;
111
+ ctx.mutationVersions.set(key, (ctx.mutationVersions.get(key) ?? 0) + 1);
112
+ ctx.cache.set(key, value);
99
113
  }
100
114
  export function getRequestCacheStats() {
101
115
  const ctx = asyncLocalStorage.getStore();
@@ -42,6 +42,8 @@ export interface InjectHTMLContentOptions {
42
42
  dependencyPinningCacheKey?: string;
43
43
  /** Ready release asset manifest used to hydrate full HTML client pages */
44
44
  releaseAssetManifest?: ReleaseAssetManifest | null;
45
+ /** Production hydration runtime selected from the rendered artifact set */
46
+ prodHydrationModulePath?: string;
45
47
  /** Configured route directories used to map physical page paths to route keys */
46
48
  directories?: ConfiguredRouteDirectories;
47
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"html-injection.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-injection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAuB/D,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAuBjF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACvC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnD,iFAAiF;IACjF,WAAW,CAAC,EAAE,0BAA0B,CAAC;CAC1C;AAsCD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,wBAAwB,GAChC,MAAM,CAuIR"}
1
+ {"version":3,"file":"html-injection.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-injection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAwB/D,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAuBjF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACvC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnD,2EAA2E;IAC3E,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,iFAAiF;IACjF,WAAW,CAAC,EAAE,0BAA0B,CAAC;CAC1C;AAsCD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,wBAAwB,GAChC,MAAM,CAyIR"}
@@ -4,6 +4,7 @@ import { generateLinkTags, generateMetaTags, generateScriptTags, generateStyleTa
4
4
  import { buildNonceAttribute, escapeHTML } from "./html-escape.js";
5
5
  import { escapeInlineJsonText, jsonForInlineScript, } from "../security/client/html-sanitizer.js";
6
6
  import { getDevScripts, getDevStyles, getPreviewStylesheetLink, getProdScripts, getStudioScripts, } from "./dev-scripts.js";
7
+ import { getProdScriptsForPath } from "./hydration-script-builder/prod-scripts.js";
7
8
  import { PROJECT_STYLESHEET_IDS } from "./project-stylesheet-ids.js";
8
9
  import { buildReleaseAssetModules } from "../release-assets/client-module-map.js";
9
10
  import { routeForConfiguredPage, } from "../release-assets/route-path.js";
@@ -135,7 +136,9 @@ export function injectHTMLContent(template, content, metadata, options) {
135
136
  else {
136
137
  html = html.replace(/{{\s*devScripts\s*}}/gi, "");
137
138
  html = html.replace(/{{\s*devStyles\s*}}/gi, "");
138
- const prodScripts = getProdScripts(options.slug, options.nonce);
139
+ const prodScripts = options.prodHydrationModulePath
140
+ ? getProdScriptsForPath(options.prodHydrationModulePath, options.nonce)
141
+ : getProdScripts(options.slug, options.nonce);
139
142
  const hasProdScriptsPlaceholder = /{{\s*prodScripts\s*}}/i.test(html);
140
143
  if (hasProdScriptsPlaceholder) {
141
144
  html = html.replace(/{{\s*prodScripts\s*}}/gi, prodScripts);
@@ -1 +1 @@
1
- {"version":3,"file":"html-shell-generator.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-shell-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA+BxE,OAAO,EAGL,aAAa,EACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA4DxD,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC;AAgFzE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAC7C,sBAAsB,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBzC;AAgSD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
1
+ {"version":3,"file":"html-shell-generator.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-shell-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgCxE,OAAO,EAGL,aAAa,EACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA4DxD,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC;AAgFzE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAC7C,sBAAsB,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBzC;AAwSD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
@@ -1,3 +1,4 @@
1
+ import { RENDER_ERROR } from "../errors/index.js";
1
2
  import { isAbsolute, resolve } from "../platform/compat/path/index.js";
2
3
  import { profilePhase, SpanNames } from "../observability/index.js";
3
4
  import { withSpan } from "../observability/tracing/otlp-setup.js";
@@ -10,7 +11,8 @@ import { routeForPage } from "../release-assets/route-path.js";
10
11
  import { VERSION } from "../utils/version.js";
11
12
  import { buildNonceAttribute, escapeHTML } from "./html-escape.js";
12
13
  import { HEAD_SHELL_PROVENANCE_ATTRIBUTE } from "./managed-head-protocol.js";
13
- import { generateHydrationData, getDevScripts, getProdHydrationModulePath, getProdScripts, } from "./hydration-script-builder/index.js";
14
+ import { generateHydrationData, getDevScripts, getProdHydrationModulePath, } from "./hydration-script-builder/index.js";
15
+ import { getProdScriptsForPath } from "./hydration-script-builder/prod-scripts.js";
14
16
  import { getPreviewStylesheetLink, getStudioScripts } from "./dev-scripts.js";
15
17
  import { processMetadata } from "./metadata-builder.js";
16
18
  import { extractCandidates, getDevStyles as getErrorOverlayStyles, getProjectCSS, } from "./styles-builder/index.js";
@@ -166,6 +168,12 @@ async function generateHTMLShellPartsImpl(meta, options, params, props, contentF
166
168
  managedHeadPayload: hydrationDataOverrides?.managedHeadPayload ?? managedHeadPayload,
167
169
  });
168
170
  const nonce = options.nonce ?? "";
171
+ const prodHydrationModulePath = options.prodHydrationModulePath;
172
+ if (!useDevScripts && options.releaseId && !prodHydrationModulePath) {
173
+ throw RENDER_ERROR.create({
174
+ detail: "Release hydration runtime must be selected before HTML generation",
175
+ });
176
+ }
169
177
  const modeScripts = useDevScripts
170
178
  ? getDevScripts(meta.slug || "", options.config, params, props, nonce, {
171
179
  skipDevHMR,
@@ -174,7 +182,7 @@ async function generateHTMLShellPartsImpl(meta, options, params, props, contentF
174
182
  // development render even though it serves the dev scripts for HMR.
175
183
  skipDevFlag: isPreviewMode,
176
184
  })
177
- : getProdScripts(meta.slug || "", params, props, nonce);
185
+ : getProdScriptsForPath(prodHydrationModulePath ?? getProdHydrationModulePath(), nonce);
178
186
  const modeStyles = useDevScripts ? getErrorOverlayStyles(nonce) : "";
179
187
  const modulePreloadHints = generateModulePreloadHints(options, releaseManifest);
180
188
  const importMap = await profilePhase("html.import_map", () => importMapPromise);
@@ -187,7 +195,7 @@ async function generateHTMLShellPartsImpl(meta, options, params, props, contentF
187
195
  : "";
188
196
  const prodHydrationModulePreload = useDevScripts
189
197
  ? ""
190
- : `<link rel="modulepreload" href="${getProdHydrationModulePath()}">`;
198
+ : `<link rel="modulepreload" href="${prodHydrationModulePath ?? getProdHydrationModulePath()}">`;
191
199
  const nonceAttr = buildNonceAttribute(nonce);
192
200
  // Expose project slug for runtime error overlay "Fix in Veryfront" button
193
201
  const overlaySlug = options.projectId || meta.slug;