@vesk/compiler 0.2.44 → 0.2.46

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { parse, createBaseParser } from '@vesk/compiler/src/parser';
1
+ export { parse, createBaseParser, parseGeneratedJs } from '@vesk/compiler/src/parser';
2
2
  export { VeskParserPlugin } from '@vesk/compiler/src/vesk-plugin';
3
3
  export { generateIR } from '@vesk/compiler/src/ir-generator';
4
4
  export { render } from '@vesk/compiler/src/server-codegen';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,MAAM,EACN,WAAW,EACX,UAAU,EACV,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACtH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,MAAM,EACN,WAAW,EACX,UAAU,EACV,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACtH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { parse, createBaseParser } from '@vesk/compiler/src/parser';
1
+ export { parse, createBaseParser, parseGeneratedJs } from '@vesk/compiler/src/parser';
2
2
  export { VeskParserPlugin } from '@vesk/compiler/src/vesk-plugin';
3
3
  export { generateIR } from '@vesk/compiler/src/ir-generator';
4
4
  export { render } from '@vesk/compiler/src/server-codegen';
package/dist/parser.d.ts CHANGED
@@ -34,5 +34,23 @@ export declare function preprocessForClauses(source: string): {
34
34
  annotations: VeskAnnotation[];
35
35
  };
36
36
  export declare function createBaseParser(): typeof acorn.Parser;
37
+ /**
38
+ * Parse GENERATED JavaScript with plain acorn — no TypeScript plugin, no
39
+ * `{#clause}` preprocessing, no comment blanking.
40
+ *
41
+ * The build parses every emitted module several times over (strip imports,
42
+ * strip exports, collect runtime names, fold chunk imports), and on a CPU
43
+ * profile of a 28-route build that parsing was two thirds of the whole build.
44
+ * None of those passes need the `.vsk` pipeline: they only read top-level
45
+ * import/export nodes out of code the code generator just produced, and acorn
46
+ * reports the same offsets either way (blankComments and friends preserve
47
+ * length). Measured on a 43 KB emitted chunk: 180 ms with the `.vsk` parser,
48
+ * 36 ms here.
49
+ *
50
+ * Returns `null` when the source is not plain ES — anything with JSX, type
51
+ * syntax or `{#clause}` markers — so callers fall back to `parse()` and keep
52
+ * exactly the behaviour they had.
53
+ */
54
+ export declare function parseGeneratedJs(source: string): Program | null;
37
55
  export declare function parse(source: string, options?: ParseOptions): Program;
38
56
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CA4LpG;AAED,wBAAgB,gBAAgB,IAAI,OAAO,KAAK,CAAC,MAAM,CAEtD;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAuEzE"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CA4LpG;AAED,wBAAgB,gBAAgB,IAAI,OAAO,KAAK,CAAC,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAM/D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAuEzE"}
package/dist/parser.js CHANGED
@@ -256,6 +256,31 @@ export function preprocessForClauses(source) {
256
256
  export function createBaseParser() {
257
257
  return acorn.Parser.extend(tsPlugin({}), VeskParserPlugin());
258
258
  }
259
+ /**
260
+ * Parse GENERATED JavaScript with plain acorn — no TypeScript plugin, no
261
+ * `{#clause}` preprocessing, no comment blanking.
262
+ *
263
+ * The build parses every emitted module several times over (strip imports,
264
+ * strip exports, collect runtime names, fold chunk imports), and on a CPU
265
+ * profile of a 28-route build that parsing was two thirds of the whole build.
266
+ * None of those passes need the `.vsk` pipeline: they only read top-level
267
+ * import/export nodes out of code the code generator just produced, and acorn
268
+ * reports the same offsets either way (blankComments and friends preserve
269
+ * length). Measured on a 43 KB emitted chunk: 180 ms with the `.vsk` parser,
270
+ * 36 ms here.
271
+ *
272
+ * Returns `null` when the source is not plain ES — anything with JSX, type
273
+ * syntax or `{#clause}` markers — so callers fall back to `parse()` and keep
274
+ * exactly the behaviour they had.
275
+ */
276
+ export function parseGeneratedJs(source) {
277
+ try {
278
+ return acorn.parse(source, { ecmaVersion: 'latest', sourceType: 'module' });
279
+ }
280
+ catch {
281
+ return null;
282
+ }
283
+ }
259
284
  export function parse(source, options = {}) {
260
285
  const ParserClass = createBaseParser();
261
286
  const { code, annotations } = preprocessForClauses(blankComments(source));
@@ -10,4 +10,6 @@ import type { PrecompileFilePlan } from '@vesk/compiler/src/precompile-runtime';
10
10
  * access and no `.vsk` source embedded in the deployment.
11
11
  */
12
12
  export declare function precompileFile(source: string, sourcePath?: string): PrecompileFilePlan;
13
+ /** Drop the plan cache (tests, and any caller that compiles outside a build). */
14
+ export declare function clearPrecompileCache(): void;
13
15
  //# sourceMappingURL=precompile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"precompile.d.ts","sourceRoot":"","sources":["../src/precompile.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,uCAAuC,CAAC;AAG/C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAEtF"}
1
+ {"version":3,"file":"precompile.d.ts","sourceRoot":"","sources":["../src/precompile.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,uCAAuC,CAAC;AAG/C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAYtF;AAeD,iFAAiF;AACjF,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -20,7 +20,36 @@ import { irToJSON } from '@vesk/compiler/src/precompile-runtime';
20
20
  * access and no `.vsk` source embedded in the deployment.
21
21
  */
22
22
  export function precompileFile(source, sourcePath) {
23
- return precompileFileInternal(source, sourcePath, new Set());
23
+ if (sourcePath === undefined)
24
+ return precompileFileInternal(source, sourcePath, new Set());
25
+ const hit = precompileCache.get(sourcePath);
26
+ // Compare the source, not just the path: the dev server rebuilds in-process
27
+ // and a stale plan would silently ship yesterday's component.
28
+ if (hit !== undefined && hit.source === source)
29
+ return hit.plan;
30
+ const plan = precompileFileInternal(source, sourcePath, new Set());
31
+ // Bound it: plans are sizeable on a large app, and a watch session can
32
+ // outlive many builds.
33
+ if (precompileCache.size >= 512)
34
+ precompileCache.clear();
35
+ precompileCache.set(sourcePath, { source, plan });
36
+ return plan;
37
+ }
38
+ /**
39
+ * Compiled plans, keyed by absolute path.
40
+ *
41
+ * Every generated SSR function precompiles its own page, its layout chain, its
42
+ * error boundary and every shared component it pulls in, so a build compiled
43
+ * the same `layout.vsk` once per route and each shared `components/*.vsk` once
44
+ * per route that used it — 25x the root layout and 28x a shared counter on the
45
+ * 28-route test-app, i.e. work growing as routes x shared files. The plan is a
46
+ * pure function of (source, path) and callers only JSON.stringify it into the
47
+ * generated function, so one compile per file per build is enough.
48
+ */
49
+ const precompileCache = new Map();
50
+ /** Drop the plan cache (tests, and any caller that compiles outside a build). */
51
+ export function clearPrecompileCache() {
52
+ precompileCache.clear();
24
53
  }
25
54
  function precompileFileInternal(source, sourcePath, seenImportFiles) {
26
55
  if (sourcePath) {
@@ -4,4 +4,5 @@ export { irNodeToJS, generateFunctionBody, buildComponentMap, buildComponentEntr
4
4
  export { irToJSON, irFromJSON, hydratePrecompile, } from '@vesk/compiler/src/precompile-runtime';
5
5
  export { precompileFile, } from '@vesk/compiler/src/precompile';
6
6
  export { compileFile, render, renderPage, ssg, renderFullPage, renderPageStream, buildDataScripts, applyHeadPlugins, applyHeadInjects, applyHtmlPlugins, } from '@vesk/compiler/src/server-render';
7
+ export { withSsrStore, withSsrStoreOf, createSsrStore, adoptSsrStore, currentSsrToken, resetSsrToken, keepSsrSlot, dropSsrSlot, isSsrSlotLive, ssrSink, } from '@vesk/compiler/src/ssr-store';
7
8
  //# sourceMappingURL=server-codegen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-codegen.d.ts","sourceRoot":"","sources":["../src/server-codegen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,GAAG,EACH,MAAM,EACN,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,cAAc,EACd,aAAa,GACd,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,QAAQ,EACR,UAAU,EACV,iBAAiB,GAClB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,cAAc,GACf,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,GAAG,EACH,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"server-codegen.d.ts","sourceRoot":"","sources":["../src/server-codegen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,GAAG,EACH,MAAM,EACN,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,cAAc,EACd,aAAa,GACd,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,QAAQ,EACR,UAAU,EACV,iBAAiB,GAClB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,cAAc,GACf,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,GAAG,EACH,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAO1C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,GACR,MAAM,8BAA8B,CAAC"}
@@ -4,3 +4,9 @@ export { irNodeToJS, generateFunctionBody, buildComponentMap, buildComponentEntr
4
4
  export { irToJSON, irFromJSON, hydratePrecompile, } from '@vesk/compiler/src/precompile-runtime';
5
5
  export { precompileFile, } from '@vesk/compiler/src/precompile';
6
6
  export { compileFile, render, renderPage, ssg, renderFullPage, renderPageStream, buildDataScripts, applyHeadPlugins, applyHeadInjects, applyHtmlPlugins, } from '@vesk/compiler/src/server-render';
7
+ // Re-exported so bundlers reach the request-scope store through THIS module
8
+ // rather than a second specifier for the same file. A bundle that resolved
9
+ // `@vesk/compiler/src/ssr-store` on its own (as the server-runtime entry used
10
+ // to) could end up with two copies of the module — two AsyncLocalStorages and
11
+ // two liveness maps — and the scope one copy opens is invisible to the other.
12
+ export { withSsrStore, withSsrStoreOf, createSsrStore, adoptSsrStore, currentSsrToken, resetSsrToken, keepSsrSlot, dropSsrSlot, isSsrSlotLive, ssrSink, } from '@vesk/compiler/src/ssr-store';
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-store.d.ts","sourceRoot":"","sources":["../src/ssr-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,MAAM,WAAW,QAAQ;IACvB;;gCAE4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAkBD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAEzC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,QAAQ,CAExC;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAuB9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEjE;AAED,wEAAwE;AACxE,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAYtC;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAG3D;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAM3D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,eAAO,MAAM,OAAO,EAAE,WAgBrB,CAAC"}
1
+ {"version":3,"file":"ssr-store.d.ts","sourceRoot":"","sources":["../src/ssr-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAK9D,MAAM,WAAW,QAAQ;IACvB;;gCAE4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AA8CD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAEzC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,QAAQ,CAExC;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAuB9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEjE;AAED,wEAAwE;AACxE,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAYtC;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAG3D;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAM3D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,eAAO,MAAM,OAAO,EAAE,WAgBrB,CAAC"}
package/dist/ssr-store.js CHANGED
@@ -4,7 +4,16 @@ import { AsyncLocalStorage } from 'node:async_hooks';
4
4
  // resolving types through the barrel then fails.
5
5
  import { setSsrSink } from '@vesk/runtime/src/index-server';
6
6
  const TOKEN_KEY = '__vsk_ssr_token';
7
- const storage = new AsyncLocalStorage();
7
+ const IMPL_KEY = '__vsk_ssr_store_impl';
8
+ const g = globalThis;
9
+ const impl = g[IMPL_KEY] ?? (g[IMPL_KEY] = {
10
+ storage: new AsyncLocalStorage(),
11
+ liveSlots: new Map(),
12
+ // Only the copy that created the implementation installs the token
13
+ // accessor; a later copy must not redefine it over the shared storage.
14
+ ownsAccessor: true,
15
+ });
16
+ const storage = impl.storage;
8
17
  /**
9
18
  * Tokens whose `__vsk_ssr_data_<token>` slot a live render still owns, with a
10
19
  * refcount. A request runs `renderPage` (page) -> `renderPage` (each nested
@@ -13,7 +22,7 @@ const storage = new AsyncLocalStorage();
13
22
  * first inner release revoke the claim the document render still depends on,
14
23
  * so the reaper could reap a live request's handoff. Counts balance instead.
15
24
  */
16
- const liveSlots = new Map();
25
+ const liveSlots = impl.liveSlots;
17
26
  function newSsrToken() {
18
27
  return Math.random().toString(36).slice(2);
19
28
  }
@@ -151,6 +160,9 @@ export const ssrSink = {
151
160
  }
152
161
  },
153
162
  };
163
+ // `setSsrSink` is safe to call from every copy: each copy's sink reads and
164
+ // writes the same shared store, so whichever one the runtime ends up holding
165
+ // behaves identically.
154
166
  setSsrSink(ssrSink);
155
167
  // The generated server code reads `globalThis.__vsk_ssr_token` synchronously
156
168
  // at the top of every component render, and the runtime's promise tracker and
@@ -170,14 +182,16 @@ setSsrSink(ssrSink);
170
182
  // process-global token, reintroducing the race for every later request. Clear
171
183
  // a token by assigning through `globalThis` inside a scope, or with
172
184
  // `resetSsrToken`.
173
- Object.defineProperty(globalThis, TOKEN_KEY, {
174
- configurable: true,
175
- get() {
176
- return storage.getStore()?.token;
177
- },
178
- set(value) {
179
- const store = storage.getStore();
180
- if (store)
181
- store.token = value;
182
- },
183
- });
185
+ if (impl.ownsAccessor) {
186
+ Object.defineProperty(globalThis, TOKEN_KEY, {
187
+ configurable: true,
188
+ get() {
189
+ return storage.getStore()?.token;
190
+ },
191
+ set(value) {
192
+ const store = storage.getStore();
193
+ if (store)
194
+ store.token = value;
195
+ },
196
+ });
197
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/compiler",
3
- "version": "0.2.44",
3
+ "version": "0.2.46",
4
4
  "type": "module",
5
5
  "description": "Vesk compiler — lexer, parser, semantic analysis, IR, codegen",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@sveltejs/acorn-typescript": "^1.0.0",
23
- "@vesk/types": "^0.2.44",
23
+ "@vesk/types": "^0.2.46",
24
24
  "acorn": "^8.15.0",
25
25
  "esrap": "^2.3.0",
26
26
  "is-reference": "^3.0.0",