@vesk/compiler 0.2.45 → 0.2.47
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 +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/module-imports.d.ts.map +1 -1
- package/dist/module-imports.js +96 -14
- package/dist/parser.d.ts +18 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +25 -0
- package/dist/precompile.d.ts +2 -0
- package/dist/precompile.d.ts.map +1 -1
- package/dist/precompile.js +30 -1
- package/package.json +2 -2
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-imports.d.ts","sourceRoot":"","sources":["../src/module-imports.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AA2ElD,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgC1F;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQpE;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,IAAI,CAuBN;AAiBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiE7E;
|
|
1
|
+
{"version":3,"file":"module-imports.d.ts","sourceRoot":"","sources":["../src/module-imports.ts"],"names":[],"mappings":"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"}
|
package/dist/module-imports.js
CHANGED
|
@@ -301,15 +301,70 @@ function depsFresh(cachedVal) {
|
|
|
301
301
|
}
|
|
302
302
|
return true;
|
|
303
303
|
}
|
|
304
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Raw file contents, keyed by path and validated by mtime.
|
|
306
|
+
*
|
|
307
|
+
* `readSsrSource` is on the hot path of every `.vsk` compile: a page's module
|
|
308
|
+
* bundle pulls in its `.ts`/`.js` imports, and a docs-style app where 26 pages
|
|
309
|
+
* all import one content module read and re-parsed that module 26 times. The
|
|
310
|
+
* parsed AST is deliberately NOT shared (callers mutate it — `stripTsTypes`,
|
|
311
|
+
* `stripped.body = ...`) and is still produced per call; only the immutable
|
|
312
|
+
* text is reused, and only while the file's mtime is unchanged, so an edit in
|
|
313
|
+
* a watch session is picked up immediately.
|
|
314
|
+
*/
|
|
315
|
+
const rawSourceCache = new Map();
|
|
316
|
+
/**
|
|
317
|
+
* Bounded, insertion-ordered eviction.
|
|
318
|
+
*
|
|
319
|
+
* The cap has to clear the OLDEST entries, not the whole map: an app that
|
|
320
|
+
* imports an icon barrel walks 1,600+ modules, and a 512-entry cap with
|
|
321
|
+
* `clear()` on overflow thrashed itself into a 0% hit rate (11,235 reads of
|
|
322
|
+
* 1,620 distinct files on vesk-doc). Draining the front keeps the hot modules
|
|
323
|
+
* resident and bounds memory.
|
|
324
|
+
*/
|
|
325
|
+
const BUILD_CACHE_MAX = 8192;
|
|
326
|
+
const BUILD_CACHE_EVICT = 2048;
|
|
327
|
+
function evict(cache) {
|
|
328
|
+
if (cache.size <= BUILD_CACHE_MAX)
|
|
329
|
+
return;
|
|
330
|
+
let dropped = 0;
|
|
331
|
+
for (const key of cache.keys()) {
|
|
332
|
+
cache.delete(key);
|
|
333
|
+
if (++dropped >= BUILD_CACHE_EVICT)
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function readSourceCached(absPath) {
|
|
338
|
+
let mtimeMs;
|
|
339
|
+
try {
|
|
340
|
+
mtimeMs = statSync(absPath).mtimeMs;
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
const hit = rawSourceCache.get(absPath);
|
|
346
|
+
if (hit && hit.mtimeMs === mtimeMs)
|
|
347
|
+
return hit.raw;
|
|
305
348
|
let raw;
|
|
306
349
|
try {
|
|
307
350
|
raw = readFileSync(absPath, 'utf-8');
|
|
308
351
|
}
|
|
309
|
-
catch
|
|
310
|
-
|
|
352
|
+
catch {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
rawSourceCache.set(absPath, { mtimeMs, raw });
|
|
356
|
+
evict(rawSourceCache);
|
|
357
|
+
return raw;
|
|
358
|
+
}
|
|
359
|
+
export function readSsrSource(absPath) {
|
|
360
|
+
const cachedRaw = readSourceCached(absPath);
|
|
361
|
+
if (cachedRaw === null) {
|
|
362
|
+
// Keep the original warning: a missing module is a build-time signal, not
|
|
363
|
+
// a cache miss to swallow.
|
|
364
|
+
console.warn(`[vesk] SSR: failed to read ${absPath}`);
|
|
311
365
|
return null;
|
|
312
366
|
}
|
|
367
|
+
const raw = cachedRaw;
|
|
313
368
|
let ast = null;
|
|
314
369
|
try {
|
|
315
370
|
ast = parse(raw, { filename: absPath });
|
|
@@ -1208,18 +1263,44 @@ export function collectModuleBundled(absPath, collector) {
|
|
|
1208
1263
|
collector.modules.push({ key, code: `module.exports = ${raw};`, dir, deps: {} });
|
|
1209
1264
|
return key;
|
|
1210
1265
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1266
|
+
// The transpiled code and the relative specifiers of a module do not depend
|
|
1267
|
+
// on which collector is asking, only on the file — and every `.vsk` compile
|
|
1268
|
+
// builds its own collector, so a docs-style app whose 26 pages all import one
|
|
1269
|
+
// content module read, parsed, stripped and re-transpiled that module 26
|
|
1270
|
+
// times (51s of a 95s build). Cache the result against the file's mtime and
|
|
1271
|
+
// skip the read AND the parse on a hit: callers mutate the AST they get
|
|
1272
|
+
// (`stripTsTypes`, `stripped.body = ...`), so the AST itself stays private to
|
|
1273
|
+
// the call that created it.
|
|
1274
|
+
let mtimeMs = -1;
|
|
1275
|
+
try {
|
|
1276
|
+
mtimeMs = statSync(absPath).mtimeMs;
|
|
1277
|
+
}
|
|
1278
|
+
catch { /* unreadable: fall through to the uncached path */ }
|
|
1279
|
+
const cached = mtimeMs >= 0 ? bundledCodeCache.get(absPath) : undefined;
|
|
1280
|
+
let code;
|
|
1281
|
+
let specifiers;
|
|
1282
|
+
if (cached && cached.mtimeMs === mtimeMs) {
|
|
1283
|
+
code = cached.code;
|
|
1284
|
+
specifiers = cached.specifiers;
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
const src = readSsrSource(absPath);
|
|
1288
|
+
if (!src || !src.ast) {
|
|
1289
|
+
const raw = src ? src.raw : '// unreadable during build\nmodule.exports = {};';
|
|
1290
|
+
collector.modules.push({ key, code: raw, dir, deps: {} });
|
|
1291
|
+
return key;
|
|
1292
|
+
}
|
|
1293
|
+
let stripped = src.ast;
|
|
1294
|
+
if (hasTsSyntax(src.ast))
|
|
1295
|
+
stripped = stripTsTypes(src.ast);
|
|
1296
|
+
stripped.body = (stripped.body || []).filter((n) => (n ? !isTypeOnlyStatement(n) : false));
|
|
1297
|
+
specifiers = [...collectModuleSpecifiers(src.ast)];
|
|
1298
|
+
code = esmToCjs(stripped.body);
|
|
1299
|
+
bundledCodeCache.set(absPath, { mtimeMs, code, specifiers });
|
|
1300
|
+
evict(bundledCodeCache);
|
|
1216
1301
|
}
|
|
1217
|
-
let stripped = src.ast;
|
|
1218
|
-
if (hasTsSyntax(src.ast))
|
|
1219
|
-
stripped = stripTsTypes(src.ast);
|
|
1220
|
-
stripped.body = (stripped.body || []).filter((n) => (n ? !isTypeOnlyStatement(n) : false));
|
|
1221
1302
|
const deps = {};
|
|
1222
|
-
for (const spec of
|
|
1303
|
+
for (const spec of specifiers) {
|
|
1223
1304
|
if (!isRelativeSpec(spec))
|
|
1224
1305
|
continue;
|
|
1225
1306
|
const depPath = resolveSsrModule(spec, dir);
|
|
@@ -1227,9 +1308,10 @@ export function collectModuleBundled(absPath, collector) {
|
|
|
1227
1308
|
continue;
|
|
1228
1309
|
deps[spec] = collectModuleBundled(depPath, collector);
|
|
1229
1310
|
}
|
|
1230
|
-
collector.modules.push({ key, code
|
|
1311
|
+
collector.modules.push({ key, code, dir, deps });
|
|
1231
1312
|
return key;
|
|
1232
1313
|
}
|
|
1314
|
+
const bundledCodeCache = new Map();
|
|
1233
1315
|
/**
|
|
1234
1316
|
* Builds the module bundle + local-binding list for a set of import lines
|
|
1235
1317
|
* (a `.vsk` file's `imports`). Framework-owned, `.vsk`, `.css` and markdown
|
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
|
package/dist/parser.d.ts.map
CHANGED
|
@@ -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));
|
package/dist/precompile.d.ts
CHANGED
|
@@ -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
|
package/dist/precompile.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/precompile.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
3
|
+
"version": "0.2.47",
|
|
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.
|
|
23
|
+
"@vesk/types": "^0.2.47",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|