@vesk/compiler 0.2.45 → 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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/compiler",
3
- "version": "0.2.45",
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.45",
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",