@vesk/compiler 0.2.83 → 0.2.85
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/module-imports.d.ts +46 -4
- package/dist/module-imports.d.ts.map +1 -1
- package/dist/module-imports.js +63 -13
- package/dist/precompile-runtime.d.ts +5 -5
- package/dist/precompile-runtime.d.ts.map +1 -1
- package/dist/precompile-runtime.js +15 -18
- package/dist/precompile.d.ts +2 -1
- package/dist/precompile.d.ts.map +1 -1
- package/dist/precompile.js +9 -8
- package/package.json +2 -2
package/dist/module-imports.d.ts
CHANGED
|
@@ -125,20 +125,62 @@ export interface ModuleBindingData {
|
|
|
125
125
|
/** `default` | `*` | named export. */
|
|
126
126
|
kind: string;
|
|
127
127
|
}
|
|
128
|
+
/** Lightweight plan-level reference to a bundled module (no source code). */
|
|
129
|
+
export interface ModuleRef {
|
|
130
|
+
/** Synthetic loader key (e.g. `__veskMod0`), referenced by deps/bindings. */
|
|
131
|
+
key: string;
|
|
132
|
+
/** Directory the module lived in at build time (require fallback anchor). */
|
|
133
|
+
dir: string;
|
|
134
|
+
/** Relative specifier (as written) -> sibling module key. */
|
|
135
|
+
deps: Record<string, string>;
|
|
136
|
+
}
|
|
137
|
+
/** What the registry stores per key: the transpiled body plus anchor dir/deps. */
|
|
138
|
+
export interface ModuleEntry {
|
|
139
|
+
/** ESM->CJS rewritten body (or raw CJS / JSON `module.exports` body). */
|
|
140
|
+
code: string;
|
|
141
|
+
/** Directory the module lived in at build time (require fallback anchor). */
|
|
142
|
+
dir: string;
|
|
143
|
+
/** Relative specifier (as written) -> sibling module key. */
|
|
144
|
+
deps: Record<string, string>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Global registry of bundled module source code, shared across every SSR
|
|
148
|
+
* function in a single build. Without it, every page plan re-embedded the
|
|
149
|
+
* full source of every module it transitively imports — a docs-style app
|
|
150
|
+
* whose 40 pages all import `lucide-vevk` stored its ~1.8 MB `buildSvgString`
|
|
151
|
+
* 40 times, inflating the single serverless handler to hundreds of megabytes
|
|
152
|
+
* and OOM-killing cold starts. Modules are registered once and every plan
|
|
153
|
+
* references them by key; the registry source is emitted into one shared file
|
|
154
|
+
* imported by every SSR function.
|
|
155
|
+
*/
|
|
156
|
+
export declare class ModuleRegistry {
|
|
157
|
+
private keysByAbs;
|
|
158
|
+
private data;
|
|
159
|
+
has(absPath: string): boolean;
|
|
160
|
+
getKey(absPath: string): string | undefined;
|
|
161
|
+
get size(): number;
|
|
162
|
+
/** Register a module's transpiled body, returning its globally-unique key. */
|
|
163
|
+
register(absPath: string, entry: ModuleEntry): string;
|
|
164
|
+
getModule(key: string): ModuleEntry | undefined;
|
|
165
|
+
/** All registered modules as a plain object keyed by synthetic key, for
|
|
166
|
+
* passing to `hydratePrecompile` at SSR load time. */
|
|
167
|
+
modules(): Record<string, ModuleEntry>;
|
|
168
|
+
/** Emit a self-contained module registry source file. */
|
|
169
|
+
toModuleSource(): string;
|
|
170
|
+
}
|
|
128
171
|
export type ModuleCollector = {
|
|
129
|
-
|
|
130
|
-
modules: BundledModuleData[];
|
|
172
|
+
modules: ModuleRef[];
|
|
131
173
|
};
|
|
132
174
|
/**
|
|
133
175
|
* Bundles one module file (plus its relative closure) into `collector`.
|
|
134
176
|
* Returns the synthetic key loaded modules use to reference it.
|
|
135
177
|
*/
|
|
136
|
-
export declare function collectModuleBundled(absPath: string,
|
|
178
|
+
export declare function collectModuleBundled(absPath: string, registry: ModuleRegistry): string;
|
|
137
179
|
/**
|
|
138
180
|
* Builds the module bundle + local-binding list for a set of import lines
|
|
139
181
|
* (a `.vsk` file's `imports`). Framework-owned, `.vsk`, `.css` and markdown
|
|
140
182
|
* targets are skipped exactly as `applyLocalModuleImports` skips them, so the
|
|
141
183
|
* hydrate-time scope matches today's runtime module loader.
|
|
142
184
|
*/
|
|
143
|
-
export declare function collectModuleBundle(importStrs: string[], fromDir: string | undefined, collector: ModuleCollector): ModuleBindingData[];
|
|
185
|
+
export declare function collectModuleBundle(importStrs: string[], fromDir: string | undefined, registry: ModuleRegistry, collector: ModuleCollector): ModuleBindingData[];
|
|
144
186
|
//# sourceMappingURL=module-imports.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-imports.d.ts","sourceRoot":"","sources":["../src/module-imports.ts"],"names":[],"mappings":"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
|
|
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
|
@@ -1437,6 +1437,55 @@ export function esmToCjs(body) {
|
|
|
1437
1437
|
}
|
|
1438
1438
|
return lines.join('\n');
|
|
1439
1439
|
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Global registry of bundled module source code, shared across every SSR
|
|
1442
|
+
* function in a single build. Without it, every page plan re-embedded the
|
|
1443
|
+
* full source of every module it transitively imports — a docs-style app
|
|
1444
|
+
* whose 40 pages all import `lucide-vevk` stored its ~1.8 MB `buildSvgString`
|
|
1445
|
+
* 40 times, inflating the single serverless handler to hundreds of megabytes
|
|
1446
|
+
* and OOM-killing cold starts. Modules are registered once and every plan
|
|
1447
|
+
* references them by key; the registry source is emitted into one shared file
|
|
1448
|
+
* imported by every SSR function.
|
|
1449
|
+
*/
|
|
1450
|
+
export class ModuleRegistry {
|
|
1451
|
+
keysByAbs = new Map();
|
|
1452
|
+
data = new Map();
|
|
1453
|
+
has(absPath) {
|
|
1454
|
+
return this.keysByAbs.has(absPath);
|
|
1455
|
+
}
|
|
1456
|
+
getKey(absPath) {
|
|
1457
|
+
return this.keysByAbs.get(absPath);
|
|
1458
|
+
}
|
|
1459
|
+
get size() {
|
|
1460
|
+
return this.data.size;
|
|
1461
|
+
}
|
|
1462
|
+
/** Register a module's transpiled body, returning its globally-unique key. */
|
|
1463
|
+
register(absPath, entry) {
|
|
1464
|
+
const existing = this.keysByAbs.get(absPath);
|
|
1465
|
+
if (existing)
|
|
1466
|
+
return existing;
|
|
1467
|
+
const key = `__veskMod${this.data.size}`;
|
|
1468
|
+
this.keysByAbs.set(absPath, key);
|
|
1469
|
+
this.data.set(key, entry);
|
|
1470
|
+
return key;
|
|
1471
|
+
}
|
|
1472
|
+
getModule(key) {
|
|
1473
|
+
return this.data.get(key);
|
|
1474
|
+
}
|
|
1475
|
+
/** All registered modules as a plain object keyed by synthetic key, for
|
|
1476
|
+
* passing to `hydratePrecompile` at SSR load time. */
|
|
1477
|
+
modules() {
|
|
1478
|
+
return Object.fromEntries(this.data.entries());
|
|
1479
|
+
}
|
|
1480
|
+
/** Emit a self-contained module registry source file. */
|
|
1481
|
+
toModuleSource() {
|
|
1482
|
+
const parts = [];
|
|
1483
|
+
for (const [key, entry] of this.data) {
|
|
1484
|
+
parts.push(`${JSON.stringify(key)}: ${JSON.stringify({ code: entry.code, dir: entry.dir, deps: entry.deps })}`);
|
|
1485
|
+
}
|
|
1486
|
+
return `export const __veskModules = {${parts.join(',')}};\n`;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1440
1489
|
function isRelativeSpec(spec) {
|
|
1441
1490
|
return spec.startsWith('./') || spec.startsWith('../');
|
|
1442
1491
|
}
|
|
@@ -1497,12 +1546,10 @@ function collectModuleSpecifiers(ast) {
|
|
|
1497
1546
|
* Bundles one module file (plus its relative closure) into `collector`.
|
|
1498
1547
|
* Returns the synthetic key loaded modules use to reference it.
|
|
1499
1548
|
*/
|
|
1500
|
-
export function collectModuleBundled(absPath,
|
|
1501
|
-
const existing =
|
|
1549
|
+
export function collectModuleBundled(absPath, registry) {
|
|
1550
|
+
const existing = registry.getKey(absPath);
|
|
1502
1551
|
if (existing)
|
|
1503
1552
|
return existing;
|
|
1504
|
-
const key = `__veskMod${collector.keysByAbs.size}`;
|
|
1505
|
-
collector.keysByAbs.set(absPath, key);
|
|
1506
1553
|
const dir = dirname(absPath);
|
|
1507
1554
|
if (absPath.endsWith('.json')) {
|
|
1508
1555
|
let raw = '';
|
|
@@ -1512,8 +1559,7 @@ export function collectModuleBundled(absPath, collector) {
|
|
|
1512
1559
|
catch (err) {
|
|
1513
1560
|
raw = '{}';
|
|
1514
1561
|
}
|
|
1515
|
-
|
|
1516
|
-
return key;
|
|
1562
|
+
return registry.register(absPath, { code: `module.exports = ${raw};`, dir, deps: {} });
|
|
1517
1563
|
}
|
|
1518
1564
|
// The transpiled code and the relative specifiers of a module do not depend
|
|
1519
1565
|
// on which collector is asking, only on the file — and every `.vsk` compile
|
|
@@ -1544,8 +1590,7 @@ export function collectModuleBundled(absPath, collector) {
|
|
|
1544
1590
|
if (src?.parseError)
|
|
1545
1591
|
throw src.parseError;
|
|
1546
1592
|
const raw = src ? src.raw : '// unreadable during build\nmodule.exports = {};';
|
|
1547
|
-
|
|
1548
|
-
return key;
|
|
1593
|
+
return registry.register(absPath, { code: raw, dir, deps: {} });
|
|
1549
1594
|
}
|
|
1550
1595
|
let stripped = src.ast;
|
|
1551
1596
|
if (hasTsSyntax(src.ast))
|
|
@@ -1563,10 +1608,9 @@ export function collectModuleBundled(absPath, collector) {
|
|
|
1563
1608
|
const depPath = resolveSsrModule(spec, dir);
|
|
1564
1609
|
if (!depPath)
|
|
1565
1610
|
continue;
|
|
1566
|
-
deps[spec] = collectModuleBundled(depPath,
|
|
1611
|
+
deps[spec] = collectModuleBundled(depPath, registry);
|
|
1567
1612
|
}
|
|
1568
|
-
|
|
1569
|
-
return key;
|
|
1613
|
+
return registry.register(absPath, { code, dir, deps });
|
|
1570
1614
|
}
|
|
1571
1615
|
const bundledCodeCache = new Map();
|
|
1572
1616
|
/**
|
|
@@ -1575,10 +1619,11 @@ const bundledCodeCache = new Map();
|
|
|
1575
1619
|
* targets are skipped exactly as `applyLocalModuleImports` skips them, so the
|
|
1576
1620
|
* hydrate-time scope matches today's runtime module loader.
|
|
1577
1621
|
*/
|
|
1578
|
-
export function collectModuleBundle(importStrs, fromDir, collector) {
|
|
1622
|
+
export function collectModuleBundle(importStrs, fromDir, registry, collector) {
|
|
1579
1623
|
const bindings = [];
|
|
1580
1624
|
if (!fromDir)
|
|
1581
1625
|
return bindings;
|
|
1626
|
+
const seenKeys = new Set();
|
|
1582
1627
|
for (const imp of importStrs) {
|
|
1583
1628
|
const target = importModuleTarget(imp);
|
|
1584
1629
|
if (!target || isCompilerOwnedTarget(target) || isValueLessTarget(target))
|
|
@@ -1588,7 +1633,12 @@ export function collectModuleBundle(importStrs, fromDir, collector) {
|
|
|
1588
1633
|
// Keep render behavior identical to the runtime loader (warn + skip).
|
|
1589
1634
|
continue;
|
|
1590
1635
|
}
|
|
1591
|
-
const key = collectModuleBundled(resolved,
|
|
1636
|
+
const key = collectModuleBundled(resolved, registry);
|
|
1637
|
+
const mod = registry.getModule(key);
|
|
1638
|
+
if (mod && !seenKeys.has(key)) {
|
|
1639
|
+
seenKeys.add(key);
|
|
1640
|
+
collector.modules.push({ key, dir: mod.dir, deps: mod.deps });
|
|
1641
|
+
}
|
|
1592
1642
|
for (const pair of importBindingPairs(imp)) {
|
|
1593
1643
|
bindings.push({ local: pair.local, key, kind: pair.imported });
|
|
1594
1644
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { CompileFileResult } from '@vesk/compiler/src/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ModuleBindingData, ModuleEntry, ModuleRef } from '@vesk/compiler/src/module-imports';
|
|
3
3
|
export interface PrecompiledComponentEntry {
|
|
4
4
|
name: string;
|
|
5
5
|
/** Compiled component body source (`buildComponentMap`-style function code). */
|
|
6
6
|
source: string;
|
|
7
7
|
isAsync: boolean;
|
|
8
8
|
}
|
|
9
|
-
export type PrecompileBundledModule =
|
|
9
|
+
export type PrecompileBundledModule = ModuleRef;
|
|
10
10
|
export type PrecompileBinding = ModuleBindingData;
|
|
11
11
|
export interface PrecompileSubFilePlan {
|
|
12
12
|
importPath: string;
|
|
@@ -19,8 +19,8 @@ export interface PrecompileFilePlan {
|
|
|
19
19
|
runtimeImports: string[];
|
|
20
20
|
/** This file's own compiled components. */
|
|
21
21
|
components: PrecompiledComponentEntry[];
|
|
22
|
-
/** The module bundle backing this file's local value imports. */
|
|
23
|
-
modules:
|
|
22
|
+
/** The module bundle backing this file's local value imports (keys into the shared __veskModules registry). */
|
|
23
|
+
modules: ModuleRef[];
|
|
24
24
|
/** local name -> bundled module export. */
|
|
25
25
|
bindings: PrecompileBinding[];
|
|
26
26
|
/** Top-level statements, already `defineAction`-transformed for `server`. */
|
|
@@ -50,5 +50,5 @@ export declare function irFromJSON(value: unknown): unknown;
|
|
|
50
50
|
* `precompile.ts` plan at SSR function load time. No source, no disk, no
|
|
51
51
|
* syntax analysis — the plan is fully compiled at build time.
|
|
52
52
|
*/
|
|
53
|
-
export declare function hydratePrecompile(plan: PrecompileFilePlan): CompileFileResult;
|
|
53
|
+
export declare function hydratePrecompile(plan: PrecompileFilePlan, modules: Record<string, ModuleEntry>): CompileFileResult;
|
|
54
54
|
//# sourceMappingURL=precompile-runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"precompile-runtime.d.ts","sourceRoot":"","sources":["../src/precompile-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA0BlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"precompile-runtime.d.ts","sourceRoot":"","sources":["../src/precompile-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA0BlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAenG,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,uBAAuB,GAAG,SAAS,CAAC;AAEhD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IACnB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,+GAA+G;IAC/G,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAqCD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0BlD;AA0ID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACnC,iBAAiB,CAEnB"}
|
|
@@ -97,30 +97,27 @@ export function irFromJSON(value) {
|
|
|
97
97
|
// ---------------------------------------------------------------------------
|
|
98
98
|
// Hydration.
|
|
99
99
|
// ---------------------------------------------------------------------------
|
|
100
|
-
function hydrateModuleScope(scope, plan) {
|
|
100
|
+
function hydrateModuleScope(scope, plan, modules) {
|
|
101
101
|
if (!plan.modules || plan.modules.length === 0)
|
|
102
102
|
return;
|
|
103
|
-
const byKey = new Map();
|
|
104
|
-
for (const m of plan.modules)
|
|
105
|
-
byKey.set(m.key, m);
|
|
106
103
|
const exportsByKey = new Map();
|
|
107
104
|
const evaluateModule = (key) => {
|
|
108
105
|
const existing = exportsByKey.get(key);
|
|
109
106
|
if (existing)
|
|
110
107
|
return existing;
|
|
111
|
-
const
|
|
112
|
-
if (!
|
|
108
|
+
const entry = modules[key];
|
|
109
|
+
if (!entry)
|
|
113
110
|
return null;
|
|
114
111
|
const exportsObj = {};
|
|
115
112
|
exportsByKey.set(key, exportsObj);
|
|
116
113
|
const moduleObj = { exports: exportsObj };
|
|
117
114
|
const requireShim = (spec) => {
|
|
118
|
-
const depKey =
|
|
115
|
+
const depKey = entry.deps[spec];
|
|
119
116
|
if (depKey)
|
|
120
117
|
return evaluateModule(depKey) || {};
|
|
121
118
|
// Framework runtime imports resolve to the instance the SSR bundle
|
|
122
119
|
// already loaded. Leaving them to the real loader broke every
|
|
123
|
-
// serverless deployment: `
|
|
120
|
+
// serverless deployment: `entry.dir` is the BUILD-time absolute path
|
|
124
121
|
// (/vercel/path0/src/_lib), which does not exist at runtime, so
|
|
125
122
|
// `require('@vesk/runtime')` walked a market that was not there.
|
|
126
123
|
if (spec === '@vesk/runtime' ||
|
|
@@ -135,7 +132,7 @@ function hydrateModuleScope(scope, plan) {
|
|
|
135
132
|
// real loader. Anchor at the module's own dir first (dev/local), then at
|
|
136
133
|
// the process cwd, which is the deployment root on serverless hosts.
|
|
137
134
|
let lastErr;
|
|
138
|
-
for (const anchor of [
|
|
135
|
+
for (const anchor of [entry.dir, process.cwd()]) {
|
|
139
136
|
try {
|
|
140
137
|
return createRequire(join(anchor, '__vesk__.js'))(spec);
|
|
141
138
|
}
|
|
@@ -143,16 +140,16 @@ function hydrateModuleScope(scope, plan) {
|
|
|
143
140
|
lastErr = err;
|
|
144
141
|
}
|
|
145
142
|
}
|
|
146
|
-
throw new Error(`Cannot resolve '${spec}' required by ${
|
|
143
|
+
throw new Error(`Cannot resolve '${spec}' required by ${key} during SSR hydrate: ${lastErr?.message}`);
|
|
147
144
|
};
|
|
148
145
|
try {
|
|
149
|
-
const body =
|
|
146
|
+
const body = entry.code ? `'use strict';\n${entry.code}` : "'use strict';";
|
|
150
147
|
const fn = new Function('require', 'module', 'exports', '__dirname', '__filename', body);
|
|
151
|
-
fn(requireShim, moduleObj, moduleObj.exports,
|
|
148
|
+
fn(requireShim, moduleObj, moduleObj.exports, entry.dir, join(entry.dir, '__vesk__.js'));
|
|
152
149
|
}
|
|
153
150
|
catch (err) {
|
|
154
151
|
exportsByKey.delete(key);
|
|
155
|
-
console.warn(`[vesk] SSR: failed to evaluate bundled module ${
|
|
152
|
+
console.warn(`[vesk] SSR: failed to evaluate bundled module ${key} (${entry.dir}): ` +
|
|
156
153
|
`${err?.message ?? String(err)}`);
|
|
157
154
|
return null;
|
|
158
155
|
}
|
|
@@ -185,10 +182,10 @@ function hydrateModuleScope(scope, plan) {
|
|
|
185
182
|
}
|
|
186
183
|
}
|
|
187
184
|
}
|
|
188
|
-
function hydrateFile(plan, seen) {
|
|
185
|
+
function hydrateFile(plan, seen, modules) {
|
|
189
186
|
const ir = plan.ir ? irFromJSON(plan.ir) : new IRRoot([], [], new Set(), null, null, []);
|
|
190
187
|
const __vesk = loadRuntimeImports(plan.runtimeImports || []);
|
|
191
|
-
hydrateModuleScope(__vesk, plan);
|
|
188
|
+
hydrateModuleScope(__vesk, plan, modules);
|
|
192
189
|
evalTopLevelCode(plan.topLevelCode || [], __vesk);
|
|
193
190
|
const componentMap = new Map();
|
|
194
191
|
for (const entry of plan.components || []) {
|
|
@@ -206,7 +203,7 @@ function hydrateFile(plan, seen) {
|
|
|
206
203
|
if (seen.has(sub.importPath))
|
|
207
204
|
continue;
|
|
208
205
|
seen.add(sub.importPath);
|
|
209
|
-
const subResult = hydrateFile(sub.plan, seen);
|
|
206
|
+
const subResult = hydrateFile(sub.plan, seen, modules);
|
|
210
207
|
for (const [name, fn] of subResult.componentMap) {
|
|
211
208
|
if (!componentMap.has(name))
|
|
212
209
|
componentMap.set(name, fn);
|
|
@@ -227,6 +224,6 @@ function hydrateFile(plan, seen) {
|
|
|
227
224
|
* `precompile.ts` plan at SSR function load time. No source, no disk, no
|
|
228
225
|
* syntax analysis — the plan is fully compiled at build time.
|
|
229
226
|
*/
|
|
230
|
-
export function hydratePrecompile(plan) {
|
|
231
|
-
return hydrateFile(plan, new Set());
|
|
227
|
+
export function hydratePrecompile(plan, modules) {
|
|
228
|
+
return hydrateFile(plan, new Set(), modules);
|
|
232
229
|
}
|
package/dist/precompile.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ModuleRegistry } from '@vesk/compiler/src/module-imports';
|
|
1
2
|
import type { PrecompileFilePlan } from '@vesk/compiler/src/precompile-runtime';
|
|
2
3
|
/**
|
|
3
4
|
* Precompiles one `.vsk` file into a `PrecompileFilePlan` at BUILD time.
|
|
@@ -9,7 +10,7 @@ import type { PrecompileFilePlan } from '@vesk/compiler/src/precompile-runtime';
|
|
|
9
10
|
* `CompileFileResult` at load time with `hydratePrecompile`, with no disk
|
|
10
11
|
* access and no `.vsk` source embedded in the deployment.
|
|
11
12
|
*/
|
|
12
|
-
export declare function precompileFile(source: string, sourcePath?: string): PrecompileFilePlan;
|
|
13
|
+
export declare function precompileFile(source: string, sourcePath?: string, registry?: ModuleRegistry): PrecompileFilePlan;
|
|
13
14
|
/** Drop the plan cache (tests, and any caller that compiles outside a build). */
|
|
14
15
|
export declare function clearPrecompileCache(): void;
|
|
15
16
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"precompile.d.ts","sourceRoot":"","sources":["../src/precompile.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,cAAc,EACf,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,uCAAuC,CAAC;AAG/C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,cAAc,GACxB,kBAAkB,CAapB;AAeD,iFAAiF;AACjF,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
package/dist/precompile.js
CHANGED
|
@@ -7,7 +7,7 @@ import { buildComponentEntries } from '@vesk/compiler/src/server-jsgen';
|
|
|
7
7
|
import { transformTopLevelForActions } from '@vesk/compiler/src/actions';
|
|
8
8
|
import { collectVskImportPaths, collectVskReexportPaths } from '@vesk/compiler/src/vsk-imports';
|
|
9
9
|
import { inlineMdImportsFrom, guessProjectRoots } from '@vesk/compiler/src/md-inline';
|
|
10
|
-
import { collectModuleBundle, } from '@vesk/compiler/src/module-imports';
|
|
10
|
+
import { collectModuleBundle, ModuleRegistry, } from '@vesk/compiler/src/module-imports';
|
|
11
11
|
import { irToJSON } from '@vesk/compiler/src/precompile-runtime';
|
|
12
12
|
/**
|
|
13
13
|
* Precompiles one `.vsk` file into a `PrecompileFilePlan` at BUILD time.
|
|
@@ -19,15 +19,16 @@ import { irToJSON } from '@vesk/compiler/src/precompile-runtime';
|
|
|
19
19
|
* `CompileFileResult` at load time with `hydratePrecompile`, with no disk
|
|
20
20
|
* access and no `.vsk` source embedded in the deployment.
|
|
21
21
|
*/
|
|
22
|
-
export function precompileFile(source, sourcePath) {
|
|
22
|
+
export function precompileFile(source, sourcePath, registry) {
|
|
23
|
+
const reg = registry ?? new ModuleRegistry();
|
|
23
24
|
if (sourcePath === undefined)
|
|
24
|
-
return precompileFileInternal(source, sourcePath, new Set());
|
|
25
|
+
return precompileFileInternal(source, sourcePath, new Set(), reg);
|
|
25
26
|
const hit = precompileCache.get(sourcePath);
|
|
26
27
|
// Compare the source, not just the path: the dev server rebuilds in-process
|
|
27
28
|
// and a stale plan would silently ship yesterday's component.
|
|
28
29
|
if (hit !== undefined && hit.source === source)
|
|
29
30
|
return hit.plan;
|
|
30
|
-
const plan = precompileFileInternal(source, sourcePath, new Set());
|
|
31
|
+
const plan = precompileFileInternal(source, sourcePath, new Set(), reg);
|
|
31
32
|
// Bound it: plans are sizeable on a large app, and a watch session can
|
|
32
33
|
// outlive many builds.
|
|
33
34
|
if (precompileCache.size >= 512)
|
|
@@ -51,7 +52,7 @@ const precompileCache = new Map();
|
|
|
51
52
|
export function clearPrecompileCache() {
|
|
52
53
|
precompileCache.clear();
|
|
53
54
|
}
|
|
54
|
-
function precompileFileInternal(source, sourcePath, seenImportFiles) {
|
|
55
|
+
function precompileFileInternal(source, sourcePath, seenImportFiles, registry) {
|
|
55
56
|
if (sourcePath) {
|
|
56
57
|
const dir = dirname(sourcePath);
|
|
57
58
|
source = inlineMdImportsFrom(source, sourcePath, guessProjectRoots(dir));
|
|
@@ -76,8 +77,8 @@ function precompileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
76
77
|
const topLevelCode = transformTopLevelForActions(ir.topLevelCode, 'server');
|
|
77
78
|
const metadataSource = ir.metadataSource || null;
|
|
78
79
|
const runtimeImports = ir.imports.slice();
|
|
79
|
-
const collector = {
|
|
80
|
-
const bindings = sourcePath !== undefined ? collectModuleBundle(ir.imports, dirname(sourcePath), collector) : [];
|
|
80
|
+
const collector = { modules: [] };
|
|
81
|
+
const bindings = sourcePath !== undefined ? collectModuleBundle(ir.imports, dirname(sourcePath), registry, collector) : [];
|
|
81
82
|
const subFiles = [];
|
|
82
83
|
if (sourcePath !== undefined) {
|
|
83
84
|
const vskPaths = [
|
|
@@ -90,7 +91,7 @@ function precompileFileInternal(source, sourcePath, seenImportFiles) {
|
|
|
90
91
|
seenImportFiles.add(importPath);
|
|
91
92
|
try {
|
|
92
93
|
const importedSrc = readFileSync(importPath, 'utf-8');
|
|
93
|
-
const subPlan = precompileFileInternal(importedSrc, importPath, seenImportFiles);
|
|
94
|
+
const subPlan = precompileFileInternal(importedSrc, importPath, seenImportFiles, registry);
|
|
94
95
|
subFiles.push({ importPath, plan: subPlan });
|
|
95
96
|
}
|
|
96
97
|
catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.85",
|
|
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.85",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|