stx-router 0.2.316 → 0.2.317

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.
Files changed (2) hide show
  1. package/dist/client.js +27 -4
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -326,6 +326,15 @@ export function getRouterScript() {
326
326
  // navigation, leaking a listener and an observer each time and resetting the
327
327
  // instance registry \u2014 trading a silent missing component for a silent leak.
328
328
  var REGISTERS_SCOPE=/window\\.stx\\.mount|_scopes\\s*\\[|\\.initScope\\s*\\(|__stxComponentFactories\\s*\\[/;
329
+ // The page's module registry (#1957): the bundle every component that
330
+ // imports a local module reads from, so on navigation it has to run before
331
+ // any of them. Marked data-stx-modules; the text test also finds it where
332
+ // only a script's text survives. Its wrapper names __stxModuleBundles, which
333
+ // no component script does -- they read __stxModules.
334
+ var REGISTRY_TEXT=/__stxModuleBundles/;
335
+ function isModuleRegistryScript(s){
336
+ return !!s&&((s.hasAttribute&&s.hasAttribute('data-stx-modules'))||REGISTRY_TEXT.test(s.textContent||''));
337
+ }
329
338
  function runsAlways(declared, code){
330
339
  if(declared==='always')return true;
331
340
  if(declared==='once')return false;
@@ -1330,7 +1339,7 @@ else {
1330
1339
  var slot='document-'+(++routedBodyScriptId);
1331
1340
  var setupName=generatedSetupName(text);
1332
1341
  if(setupName)incomingSetupName=setupName;
1333
- routedBodyScripts.push({text:text,runAlways:true,slot:slot,setupName:setupName,run:s.getAttribute('data-stx-run')||'',owner:s.getAttribute('data-stx-owner')||''});
1342
+ routedBodyScripts.push({text:text,runAlways:true,slot:slot,setupName:setupName,run:s.getAttribute('data-stx-run')||'',owner:s.getAttribute('data-stx-owner')||'',registry:isModuleRegistryScript(s)});
1334
1343
  s.textContent='';
1335
1344
  s.setAttribute('type','application/stx-pending');
1336
1345
  s.setAttribute('data-stx-route-script',slot);
@@ -1412,16 +1421,24 @@ else {
1412
1421
 
1413
1422
  var scripts=routedBodyScripts.slice();
1414
1423
  function addScript(text, runAlways, slot, owner){
1415
- scripts.push({text:text,runAlways:!!runAlways,slot:slot||'',owner:owner||''});
1424
+ scripts.push({text:text,runAlways:!!runAlways,slot:slot||'',owner:owner||'',registry:REGISTRY_TEXT.test(text)});
1416
1425
  }
1417
1426
  if(isLayoutChange){
1418
- // Also collect setup functions from <head>
1427
+ // Also collect setup functions from <head>, and the page's module
1428
+ // registry (#1957). The registry is anchored to the signals runtime,
1429
+ // and a layout with its own <head> script (analytics, say) pulls the
1430
+ // runtime -- and the registry with it -- into <head>. Collecting only
1431
+ // setups there dropped it, so every component that imports a local
1432
+ // module threw "is not registered on this page" and its template
1433
+ // hydrated against globals: an <input id="email"> bound to
1434
+ // :model="email" showed "[object HTMLInputElement]".
1419
1435
  doc.querySelectorAll('head script').forEach(function(s){
1420
1436
  var text=s.textContent||'';
1421
1437
  if(s.hasAttribute('src'))return;
1422
1438
  if(!text.trim())return;
1423
1439
  if(isSignalsRuntimeScript(s,text))return;
1424
- if(text.indexOf('__stx_setup_')!==-1)addScript(text,true);
1440
+ if(isModuleRegistryScript(s))addScript(text,true,'','');
1441
+ else if(text.indexOf('__stx_setup_')!==-1)addScript(text,true);
1425
1442
  });
1426
1443
  } else {
1427
1444
  // Collect page scripts from <head> AND <body> (outside container).
@@ -1469,6 +1486,12 @@ else {
1469
1486
  return aPage-bPage;
1470
1487
  });
1471
1488
  }
1489
+ // The module registry runs before anything that reads it (#1957). The
1490
+ // container's own scripts are collected first and head scripts after,
1491
+ // so without this a component in the page body could run ahead of the
1492
+ // registry it imports from. Stable: the order within each group holds.
1493
+ var registryFirst=scripts.filter(function(e){return e.registry});
1494
+ if(registryFirst.length)scripts=registryFirst.concat(scripts.filter(function(e){return !e.registry}));
1472
1495
 
1473
1496
  // Push history state (before active link updates so location.pathname is current)
1474
1497
  if(pushState!==false)writeHistory(pushState,url+(hash||''));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stx-router",
3
3
  "type": "module",
4
- "version": "0.2.316",
4
+ "version": "0.2.317",
5
5
  "description": "File-based router for STX — .stx template discovery, nested layouts, typed route params, middleware, and client-side SPA navigation.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",