@vesk/adapter 0.2.57 → 0.2.59
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/client-bundle.d.ts.map +1 -1
- package/dist/client-bundle.js +220 -5
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAmF,MAAM,yBAAyB,CAAC;AAoCnL;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA4BhE;AAED;;;;;GAKG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7B,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IACtH,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,MAAM,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KAC/F,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAmDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAKzD;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B7D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBlD;
|
|
1
|
+
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAmF,MAAM,yBAAyB,CAAC;AAoCnL;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA4BhE;AAED;;;;;GAKG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7B,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IACtH,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,MAAM,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KAC/F,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAmDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAKzD;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B7D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBlD;AAuQD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B5D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD;AA4CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GAAG,MAAM,CAoBnG;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CA0nB7B;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+B3D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAUlE;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/F"}
|
package/dist/client-bundle.js
CHANGED
|
@@ -268,6 +268,48 @@ export function demoteExports(code) {
|
|
|
268
268
|
function chunkHasImports(headLen, mergeAborted) {
|
|
269
269
|
return headLen > 0 || mergeAborted;
|
|
270
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Scans a module's own source for the names it imports from `@vesk/runtime*`.
|
|
273
|
+
* The shared-module pass needs them so the entry bundle publishes exactly the
|
|
274
|
+
* bindings the shared code will read back off `globalThis`.
|
|
275
|
+
*/
|
|
276
|
+
function runtimeImportsOf(filePath) {
|
|
277
|
+
let text;
|
|
278
|
+
try {
|
|
279
|
+
text = readFileSync(filePath, 'utf8');
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
const names = [];
|
|
285
|
+
const pattern = /import\s+(type\s+)?\{([^}]*)\}\s*from\s*['"]@vesk\/runtime[^'"]*['"]/g;
|
|
286
|
+
for (const match of text.matchAll(pattern)) {
|
|
287
|
+
if (match[1])
|
|
288
|
+
continue; // type-only imports are erased
|
|
289
|
+
for (const part of match[2].split(',')) {
|
|
290
|
+
const cleaned = part.trim().replace(/^type\s+/, '');
|
|
291
|
+
if (!cleaned)
|
|
292
|
+
continue;
|
|
293
|
+
const name = cleaned.split(/\s+as\s+/)[0].trim();
|
|
294
|
+
if (name)
|
|
295
|
+
names.push(name);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return names;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* esbuild resolver that redirects `@vesk/runtime*` imports in the shared-module
|
|
302
|
+
* pass to a generated shim reading the ENTRY bundle's runtime off `globalThis`.
|
|
303
|
+
* `shimPath` is generated by the caller, which knows which names are needed.
|
|
304
|
+
*/
|
|
305
|
+
function sharedRuntimeResolver(shimPath) {
|
|
306
|
+
return {
|
|
307
|
+
name: 'vesk-shared-runtime',
|
|
308
|
+
setup(build) {
|
|
309
|
+
build.onResolve({ filter: /^@vesk\/runtime(\/.*)?$/ }, () => ({ path: shimPath }));
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
271
313
|
/**
|
|
272
314
|
* Accumulates every import a code-split chunk needs and rebuilds it as a
|
|
273
315
|
* single deduped import block.
|
|
@@ -401,6 +443,21 @@ class ChunkImports {
|
|
|
401
443
|
get reason() {
|
|
402
444
|
return this.abortReason;
|
|
403
445
|
}
|
|
446
|
+
/** Every import source this chunk's merged block pulls in (absolute paths). */
|
|
447
|
+
sources() {
|
|
448
|
+
return this.aborted ? [] : [...this.bySource.keys()];
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* The named bindings this chunk imports from `source`, so a shared-module
|
|
452
|
+
* shim can re-export exactly what consumers use (re-exporting `*` from the
|
|
453
|
+
* real module would drag it back into the chunk being built).
|
|
454
|
+
*/
|
|
455
|
+
bindingsFor(source) {
|
|
456
|
+
const group = this.bySource.get(source);
|
|
457
|
+
if (!group)
|
|
458
|
+
return { named: [], hasDefault: false };
|
|
459
|
+
return { named: [...group.named.keys()].sort(), hasDefault: !!group.default };
|
|
460
|
+
}
|
|
404
461
|
/** Renders the deduped import block (empty string when there are no imports). */
|
|
405
462
|
render() {
|
|
406
463
|
if (this.aborted || this.bySource.size === 0)
|
|
@@ -631,6 +688,9 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
631
688
|
let cachedFileHits = 0;
|
|
632
689
|
let compiledFiles = 0;
|
|
633
690
|
let mainFromCache = false;
|
|
691
|
+
// Shared-module bundle inlined at the top of the entry chunk (code-split
|
|
692
|
+
// path only). Non-empty when app modules are shared between route chunks.
|
|
693
|
+
let sharedModuleBundle = '';
|
|
634
694
|
function mustReuseWithoutStat(filePath) {
|
|
635
695
|
return !!only && !only.has(filePath);
|
|
636
696
|
}
|
|
@@ -899,7 +959,7 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
899
959
|
console.error('[vesk] chunk import merge aborted for', chunkName + ':', chunkImports.reason);
|
|
900
960
|
const head = chunkImports.render();
|
|
901
961
|
const code = (head ? head + '\n\n' : '') + chunkCode.join('\n\n');
|
|
902
|
-
chunkEntries.push({ name: chunkName, code, node, imports: chunkHasImports(head.length, !chunkImports.ok) });
|
|
962
|
+
chunkEntries.push({ name: chunkName, code, node, importsTable: chunkImports, imports: chunkHasImports(head.length, !chunkImports.ok) });
|
|
903
963
|
}
|
|
904
964
|
walkSplit(node.children || [], [..._chain, node]);
|
|
905
965
|
}
|
|
@@ -917,9 +977,144 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
917
977
|
console.error('[vesk] chunk import merge aborted for shared.js:', sharedImports.reason);
|
|
918
978
|
const head = sharedImports.render();
|
|
919
979
|
const code = (head ? head + '\n\n' : '') + sharedCode.join('\n\n');
|
|
920
|
-
chunkEntries.push({ name: 'shared.js', code, node: null, imports: chunkHasImports(head.length, !sharedImports.ok) });
|
|
980
|
+
chunkEntries.push({ name: 'shared.js', code, node: null, importsTable: sharedImports, imports: chunkHasImports(head.length, !sharedImports.ok) });
|
|
921
981
|
}
|
|
922
982
|
const chunkIIFE = (body) => `(()=>{\nconst __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\n${body}\n})();\n`;
|
|
983
|
+
/**
|
|
984
|
+
* Modules imported by MORE THAN ONE chunk are bundled ONCE and shipped
|
|
985
|
+
* inside the main bundle, instead of being inlined into every chunk.
|
|
986
|
+
*
|
|
987
|
+
* Per-chunk bundling duplicates them, and a duplicated module means a
|
|
988
|
+
* duplicated module SCOPE: a module-scope `track()` cell in `auth/store.ts`
|
|
989
|
+
* exists once per chunk, so signing in through the login chunk left the
|
|
990
|
+
* portal chunk's copy of the session empty and the router rendered the
|
|
991
|
+
* signed-out view — silently, with a green build and no thrown error.
|
|
992
|
+
*
|
|
993
|
+
* The one copy lives in the entry bundle (loaded by every page before any
|
|
994
|
+
* route chunk exists) and publishes itself on `globalThis.__veskShared`;
|
|
995
|
+
* each route chunk imports a generated shim that reads its bindings from
|
|
996
|
+
* there. Keeping it in the MAIN bundle rather than a separate chunk is what
|
|
997
|
+
* makes it race-free: dynamically inserted classic scripts are async by
|
|
998
|
+
* default and do not execute in insertion order, so a shared chunk fetched
|
|
999
|
+
* alongside route chunks can — and did — lose that race.
|
|
1000
|
+
*
|
|
1001
|
+
* Only app-local modules qualify. A node_modules package used by several
|
|
1002
|
+
* chunks is pure third-party code with no module state worth sharing, and
|
|
1003
|
+
* hoisting one (a `lucide-vesk` barrel) would pull it into the entry
|
|
1004
|
+
* bundle for every page.
|
|
1005
|
+
*/
|
|
1006
|
+
const sharedUsage = new Map();
|
|
1007
|
+
for (const entry of chunkEntries) {
|
|
1008
|
+
for (const source of new Set(entry.importsTable.sources())) {
|
|
1009
|
+
sharedUsage.set(source, (sharedUsage.get(source) ?? 0) + 1);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
const isAppLocal = (source) => !source.includes('node_modules') && source.startsWith(resolve(appDir, '..'));
|
|
1013
|
+
const sharedSources = [...sharedUsage.entries()]
|
|
1014
|
+
.filter(([source, uses]) => uses > 1 && isAppLocal(source))
|
|
1015
|
+
.map(([source]) => source);
|
|
1016
|
+
if (process.env.VESK_DEBUG_SHARED) {
|
|
1017
|
+
console.error('[shared] candidates:', [...sharedUsage.entries()].map(([s, n]) => `${n}x ${s}`).join('\n'));
|
|
1018
|
+
console.error('[shared] selected:', sharedSources.join(', '));
|
|
1019
|
+
}
|
|
1020
|
+
const chunkAlias = {};
|
|
1021
|
+
let sharedBundleCode = '';
|
|
1022
|
+
// Runtime bindings the shared modules need. The entry bundle publishes each
|
|
1023
|
+
// of these on `globalThis`, and the shared bundle reads them back, so the
|
|
1024
|
+
// app and its stores share ONE runtime instance.
|
|
1025
|
+
const sharedRuntimeNames = new Set();
|
|
1026
|
+
if (sharedSources.length > 0) {
|
|
1027
|
+
const tmpBase = mkdtempSync(join(resolve(appDir, '..'), 'tmp-vesk-shared-'));
|
|
1028
|
+
try {
|
|
1029
|
+
// One entry that imports every shared module and publishes the whole
|
|
1030
|
+
// map on a global, so esbuild emits a single deduped body.
|
|
1031
|
+
const sharedEntry = join(tmpBase, 'shared-entry.js');
|
|
1032
|
+
const lines = [];
|
|
1033
|
+
const members = [];
|
|
1034
|
+
sharedSources.forEach((source, i) => {
|
|
1035
|
+
lines.push(`import * as m${i} from ${JSON.stringify(source)};`);
|
|
1036
|
+
members.push(` ${JSON.stringify(source)}: m${i},`);
|
|
1037
|
+
});
|
|
1038
|
+
lines.push(`globalThis.__veskShared = { ${members.join('\n')} };`);
|
|
1039
|
+
writeFileSync(sharedEntry, lines.join('\n'));
|
|
1040
|
+
const appTsconfig = findTsconfigPath(appDir);
|
|
1041
|
+
// Which runtime bindings do the shared modules need? The entry bundle
|
|
1042
|
+
// publishes exactly these on `globalThis`; the shim reads them back.
|
|
1043
|
+
const runtimeShim = join(tmpBase, 'runtime-shim.js');
|
|
1044
|
+
const runtimeLines = [
|
|
1045
|
+
'// ONE runtime instance: the entry bundle publishes these on globalThis,',
|
|
1046
|
+
'// and route chunks import the same functions. A second bundled copy',
|
|
1047
|
+
'// would mean a second Cell class and a second currentEffect.',
|
|
1048
|
+
'const __r = (n) => (...args) => globalThis[n](...args);',
|
|
1049
|
+
];
|
|
1050
|
+
for (const source of sharedSources) {
|
|
1051
|
+
for (const name of runtimeImportsOf(source))
|
|
1052
|
+
sharedRuntimeNames.add(name);
|
|
1053
|
+
}
|
|
1054
|
+
for (const name of [...sharedRuntimeNames].sort()) {
|
|
1055
|
+
runtimeLines.push(`export const ${name} = __r(${JSON.stringify(name)});`);
|
|
1056
|
+
}
|
|
1057
|
+
writeFileSync(runtimeShim, runtimeLines.join('\n') + '\n');
|
|
1058
|
+
const result = await build({
|
|
1059
|
+
entryPoints: [sharedEntry],
|
|
1060
|
+
bundle: true,
|
|
1061
|
+
format: 'iife',
|
|
1062
|
+
platform: 'browser',
|
|
1063
|
+
write: false,
|
|
1064
|
+
logLevel: 'silent',
|
|
1065
|
+
loader: { '.js': 'tsx' },
|
|
1066
|
+
legalComments: 'none',
|
|
1067
|
+
// `@vesk/runtime` MUST stay the entry bundle's instance. Bundling a
|
|
1068
|
+
// second copy in here gives the app a second `Cell` class and a
|
|
1069
|
+
// second `currentEffect` variable: a store cell written from a click
|
|
1070
|
+
// notifies subscribers registered against the OTHER copy, so nothing
|
|
1071
|
+
// the store drives ever updates — writes land, no error, no repaint.
|
|
1072
|
+
plugins: [sharedRuntimeResolver(runtimeShim)],
|
|
1073
|
+
...(appTsconfig ? { tsconfig: appTsconfig } : {}),
|
|
1074
|
+
});
|
|
1075
|
+
sharedBundleCode = result.outputFiles[0].text;
|
|
1076
|
+
// Per-chunk shims: `export const login = __veskShared['…'].login`.
|
|
1077
|
+
// esbuild inlines these tiny stubs instead of the real module.
|
|
1078
|
+
sharedSources.forEach((source, i) => {
|
|
1079
|
+
const named = new Set();
|
|
1080
|
+
let hasDefault = false;
|
|
1081
|
+
for (const entry of chunkEntries) {
|
|
1082
|
+
const bindings = entry.importsTable.bindingsFor(source);
|
|
1083
|
+
bindings.named.forEach((n) => named.add(n));
|
|
1084
|
+
hasDefault = hasDefault || bindings.hasDefault;
|
|
1085
|
+
}
|
|
1086
|
+
const shim = join(tmpBase, `shim-${i}.js`);
|
|
1087
|
+
const shimLines = [`const m = globalThis.__veskShared[${JSON.stringify(source)}];`];
|
|
1088
|
+
if (hasDefault)
|
|
1089
|
+
shimLines.push(`export default m;`);
|
|
1090
|
+
for (const name of [...named].sort()) {
|
|
1091
|
+
shimLines.push(`export const ${name} = m[${JSON.stringify(name)}];`);
|
|
1092
|
+
}
|
|
1093
|
+
writeFileSync(shim, shimLines.join('\n') + '\n');
|
|
1094
|
+
chunkAlias[source] = shim;
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
catch (e) {
|
|
1098
|
+
// A failed shared pass must never ship a half-shared graph: fall back
|
|
1099
|
+
// to per-chunk inlining (the historical behaviour, duplicated modules
|
|
1100
|
+
// and all) rather than to dangling bindings.
|
|
1101
|
+
console.error('[vesk] shared-module pass failed; falling back to per-chunk inlining:', e.message);
|
|
1102
|
+
sharedBundleCode = '';
|
|
1103
|
+
for (const key of Object.keys(chunkAlias))
|
|
1104
|
+
delete chunkAlias[key];
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
const sharedRedirectPlugin = Object.keys(chunkAlias).length > 0
|
|
1108
|
+
? {
|
|
1109
|
+
name: 'vesk-shared-modules',
|
|
1110
|
+
setup(build) {
|
|
1111
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
1112
|
+
const mapped = chunkAlias[args.path];
|
|
1113
|
+
return mapped ? { path: mapped } : null;
|
|
1114
|
+
});
|
|
1115
|
+
},
|
|
1116
|
+
}
|
|
1117
|
+
: null;
|
|
923
1118
|
for (const entry of chunkEntries) {
|
|
924
1119
|
if (!entry.code.trim())
|
|
925
1120
|
continue;
|
|
@@ -955,6 +1150,13 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
955
1150
|
// for a dependency stays in its own package; shipping every
|
|
956
1151
|
// module's header inside our own chunk adds nothing.
|
|
957
1152
|
legalComments: 'none',
|
|
1153
|
+
// Shared app modules are NOT inlined here: the resolver below
|
|
1154
|
+
// redirects them to a generated shim reading
|
|
1155
|
+
// `globalThis.__veskShared`, so the single copy in
|
|
1156
|
+
// shared-modules.js serves every route chunk. (esbuild's `alias`
|
|
1157
|
+
// option only accepts bare package names, so this is a resolver
|
|
1158
|
+
// rather than a map.)
|
|
1159
|
+
...(sharedRedirectPlugin ? { plugins: [sharedRedirectPlugin] } : {}),
|
|
958
1160
|
...(appTsconfig ? { tsconfig: appTsconfig } : {}),
|
|
959
1161
|
});
|
|
960
1162
|
finalCode = result.outputFiles[0].text;
|
|
@@ -1018,14 +1220,22 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1018
1220
|
}
|
|
1019
1221
|
}
|
|
1020
1222
|
annotate(routeTree);
|
|
1021
|
-
|
|
1223
|
+
// Publish shared modules from the ENTRY bundle so they exist before any
|
|
1224
|
+
// route chunk is even requested (see the shared-module pass above).
|
|
1225
|
+
sharedModuleBundle = sharedBundleCode;
|
|
1226
|
+
// The shared modules read these runtime bindings back off `globalThis`, so
|
|
1227
|
+
// the entry bundle must publish them even when no `.vsk` file imports them
|
|
1228
|
+
// (a store-only app would otherwise get `undefined` for `track`).
|
|
1229
|
+
for (const name of sharedRuntimeNames)
|
|
1230
|
+
runtimeImportNames.add(name);
|
|
1231
|
+
const mainKey = JSON.stringify(routeTree) + '|' + [...runtimeImportNames].sort().join(',') + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ''}|${sharedModuleBundle.length}`;
|
|
1022
1232
|
let main;
|
|
1023
1233
|
if (cache?.mainBundle && cache.mainBundle.key === mainKey) {
|
|
1024
1234
|
mainFromCache = true;
|
|
1025
1235
|
main = cache.mainBundle.code;
|
|
1026
1236
|
}
|
|
1027
1237
|
else {
|
|
1028
|
-
main = await buildMainBundle(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
|
|
1238
|
+
main = await buildMainBundle(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache, sharedModuleBundle);
|
|
1029
1239
|
if (cache)
|
|
1030
1240
|
cache.mainBundle = { key: mainKey, code: main };
|
|
1031
1241
|
}
|
|
@@ -1275,7 +1485,7 @@ function appendHmrGlobals(code) {
|
|
|
1275
1485
|
" return eval(code);\n" +
|
|
1276
1486
|
"};\n";
|
|
1277
1487
|
}
|
|
1278
|
-
async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
|
|
1488
|
+
async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache, sharedModuleBundle = '') {
|
|
1279
1489
|
const baseRuntimeImports = ['createFileRouter', 'get', 'set', 'effect', 'track', 'destroy_block', 'getActiveComponent', 'setActiveComponent', 'NavLink', 'Link', 'reactiveProps', 'matchRoute', 'ensureChunk', 'toDomNode', 'rerenderNode'];
|
|
1280
1490
|
const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0
|
|
1281
1491
|
? [...new Set([...baseRuntimeImports, ...runtimeImportNames])]
|
|
@@ -1392,6 +1602,11 @@ async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, impo
|
|
|
1392
1602
|
'const __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\n' +
|
|
1393
1603
|
'const __runtime_comps = __components;\n\n' +
|
|
1394
1604
|
runtimeGlobals + extraGlobals +
|
|
1605
|
+
// Shared app modules run HERE: after the runtime bindings are published,
|
|
1606
|
+
// before anything can request a route chunk. Earlier (at the top of the
|
|
1607
|
+
// bundle) `globalThis.track` was still undefined, so every module-scope
|
|
1608
|
+
// cell in a store was created against a missing runtime.
|
|
1609
|
+
(sharedModuleBundle ? sharedModuleBundle + '\n' : '') +
|
|
1395
1610
|
cleanupFn +
|
|
1396
1611
|
placeFn +
|
|
1397
1612
|
'globalThis.__components = __components;\n' +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.59",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk adapter — builds deployable .vesk/ output for Deno and Node serverless",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"sharp": "^0.35.3"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@vesk/compiler": "^0.2.
|
|
27
|
-
"@vesk/runtime": "^0.2.
|
|
28
|
-
"@vesk/types": "^0.2.
|
|
26
|
+
"@vesk/compiler": "^0.2.59",
|
|
27
|
+
"@vesk/runtime": "^0.2.59",
|
|
28
|
+
"@vesk/types": "^0.2.59"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.18.1",
|