@vesk/adapter 0.2.58 → 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.
@@ -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;AA4MD;;;;;;;;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,CAie7B;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"}
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"}
@@ -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
- const mainKey = JSON.stringify(routeTree) + '|' + [...runtimeImportNames].sort().join(',') + `|${!!options?.hmr}|${!!options?.importRuntime}|${options?.routeDataCache ?? ''}`;
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.58",
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.58",
27
- "@vesk/runtime": "^0.2.58",
28
- "@vesk/types": "^0.2.58"
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",