@stacksjs/stx 0.2.364 → 0.2.366

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 (57) hide show
  1. package/dist/{chunk-gerew7rz.js → chunk-09xgdh4x.js} +1 -1
  2. package/dist/{chunk-jq4h14y6.js → chunk-09ypvk2t.js} +1 -1
  3. package/dist/{chunk-tan44cyf.js → chunk-0jp8bx88.js} +1 -1
  4. package/dist/{chunk-08pf5tmf.js → chunk-0vary9ym.js} +1 -1
  5. package/dist/{chunk-asxfek33.js → chunk-264fwxyv.js} +2 -2
  6. package/dist/{chunk-89c03r0q.js → chunk-2d737x81.js} +2 -2
  7. package/dist/{chunk-ec8pyr0w.js → chunk-2hpey68b.js} +1 -1
  8. package/dist/{chunk-5qe5amz6.js → chunk-2wbs79rn.js} +1 -1
  9. package/dist/{chunk-t0e193kb.js → chunk-34thbja9.js} +1 -1
  10. package/dist/{chunk-szbgwctn.js → chunk-3vctbh57.js} +1 -1
  11. package/dist/{chunk-8zw9npx5.js → chunk-53breaeh.js} +1 -1
  12. package/dist/{chunk-7tp3zk2s.js → chunk-5gwf1fxm.js} +1 -1
  13. package/dist/{chunk-0d96p1my.js → chunk-5yhbx6em.js} +1 -1
  14. package/dist/{chunk-ddsfdbwt.js → chunk-65nbdz3c.js} +1 -1
  15. package/dist/{chunk-drk5v3wn.js → chunk-8czscsf3.js} +1 -1
  16. package/dist/{chunk-3dkv2bqc.js → chunk-9n4wz4p2.js} +1 -1
  17. package/dist/{chunk-yyxgghm5.js → chunk-b3yn2q9z.js} +1 -1
  18. package/dist/{chunk-23ftyfcz.js → chunk-bxgq1ec0.js} +1 -1
  19. package/dist/{chunk-dj0c80w1.js → chunk-chnhccbg.js} +1 -1
  20. package/dist/{chunk-nfwtms2p.js → chunk-cvpr7j0a.js} +1 -1
  21. package/dist/{chunk-85tvgy7c.js → chunk-dvzxdyth.js} +1 -1
  22. package/dist/{chunk-yectvv7c.js → chunk-e16evm88.js} +1 -1
  23. package/dist/{chunk-zk0enyyh.js → chunk-e2wkw0mv.js} +1 -1
  24. package/dist/{chunk-c6b161h9.js → chunk-exve9vx9.js} +1 -1
  25. package/dist/{chunk-7wvvzame.js → chunk-g1wgckhg.js} +1 -1
  26. package/dist/{chunk-6gns8q1a.js → chunk-hd3g347d.js} +1 -1
  27. package/dist/{chunk-8qp89yt9.js → chunk-hdpcrf2k.js} +1 -1
  28. package/dist/{chunk-whywmp6c.js → chunk-ht2neybr.js} +1 -1
  29. package/dist/{chunk-wbwfsp44.js → chunk-jf9mv5tq.js} +108 -46
  30. package/dist/{chunk-4v04zysj.js → chunk-jq1pddw6.js} +1 -1
  31. package/dist/{chunk-bfecmzpa.js → chunk-jxc8ezvk.js} +1 -1
  32. package/dist/{chunk-7nf8tw22.js → chunk-k2sdmmmq.js} +2 -2
  33. package/dist/{chunk-p6avvxkg.js → chunk-ksfnb7rd.js} +1 -1
  34. package/dist/{chunk-2gkbht81.js → chunk-m883x1fp.js} +1 -1
  35. package/dist/{chunk-md0h8d2h.js → chunk-nfmdrmgz.js} +1 -1
  36. package/dist/{chunk-wsqbnhcy.js → chunk-nhshe26k.js} +8 -8
  37. package/dist/{chunk-ck4n9zkv.js → chunk-r92073jh.js} +1 -1
  38. package/dist/{chunk-6xmkzx0a.js → chunk-rg473fqn.js} +1 -1
  39. package/dist/{chunk-wzebxbek.js → chunk-t0bnbghk.js} +1 -1
  40. package/dist/{chunk-rw0j25b8.js → chunk-t6928tnd.js} +1 -1
  41. package/dist/{chunk-d8n3wqgy.js → chunk-tc8yfmm5.js} +1 -1
  42. package/dist/{chunk-h6jnte7x.js → chunk-v8ncfppj.js} +1 -1
  43. package/dist/{chunk-s5qkcz77.js → chunk-vd3ja1q9.js} +1 -1
  44. package/dist/{chunk-bkeszcra.js → chunk-vr3a5wma.js} +1 -1
  45. package/dist/{chunk-xh55b3m0.js → chunk-wb2y68dk.js} +1 -1
  46. package/dist/{chunk-y1vw94q2.js → chunk-y1twpva6.js} +1 -1
  47. package/dist/{chunk-3xt912sq.js → chunk-y3gd1g9s.js} +16 -16
  48. package/dist/{chunk-8b5cwheg.js → chunk-y4j6br2e.js} +1 -1
  49. package/dist/{chunk-e8nxcfp3.js → chunk-z541dzm4.js} +1 -1
  50. package/dist/{chunk-6xy59d9x.js → chunk-z9zayxg4.js} +1 -1
  51. package/dist/cli.js +8 -8
  52. package/dist/craft-entry.js +1 -1
  53. package/dist/craft.js +1 -1
  54. package/dist/pwa.js +1 -1
  55. package/dist/signals.js +108 -46
  56. package/dist/ssg.js +2 -2
  57. package/package.json +5 -5
package/dist/signals.js CHANGED
@@ -154,6 +154,65 @@ console.log('[stx] entering IIFE');
154
154
  // Reactive Core
155
155
  // ==========================================================================
156
156
 
157
+ // Compiled expression functions, by parameter list and body. A binding was
158
+ // compiled with new Function on every evaluation: a page with a few hundred
159
+ // names in scope rebuilt a function of a few hundred parameters for every
160
+ // binding of every row, every time a row re-rendered. Opening a 386-message
161
+ // conversation took seven seconds in WebKit, the window frozen meanwhile.
162
+ // A Function built this way closes over nothing, so one can be reused.
163
+ const __stxCompiled = new Map();
164
+ function __stxCompile(params, body) {
165
+ const key = params.join(',') + '\\x01' + body;
166
+ let fn = __stxCompiled.get(key);
167
+ if (!fn) {
168
+ fn = new Function(...params, body);
169
+ // Bounded: expressions are finite per page, but SPA navigation adds more.
170
+ if (__stxCompiled.size >= 5000) __stxCompiled.clear();
171
+ __stxCompiled.set(key, fn);
172
+ }
173
+ return fn;
174
+ }
175
+
176
+ // The names an expression mentions, by its text.
177
+ const __stxIdentifiers = new Map();
178
+ function __stxNamesIn(body) {
179
+ let names = __stxIdentifiers.get(body);
180
+ if (!names) {
181
+ names = Array.from(new Set(body.match(/[A-Za-z_$][\\w$]*/g) || []));
182
+ if (__stxIdentifiers.size >= 5000) __stxIdentifiers.clear();
183
+ __stxIdentifiers.set(body, names);
184
+ }
185
+ return names;
186
+ }
187
+
188
+ // Compile an expression over just the names in scope it mentions.
189
+ //
190
+ // It was compiled over every name in scope and called with every value,
191
+ // read through the auto-unwrap proxy. Reading a signal subscribes the
192
+ // running effect, so every binding depended on every signal on the page:
193
+ // changing one unrelated value re-ran every binding of every row. The proxy
194
+ // also tested each signal against the expression with fresh regexes. Now an
195
+ // expression sees, reads and subscribes to what it names; a mention inside
196
+ // a string only widens that, never narrows it.
197
+ function __stxCompileScoped(scope, extraParams, body) {
198
+ const keys = [];
199
+ const names = __stxNamesIn(body);
200
+ for (let i = 0; i < names.length; i++) {
201
+ if (Object.prototype.propertyIsEnumerable.call(scope, names[i])) keys.push(names[i]);
202
+ }
203
+ const fn = __stxCompile(extraParams.length ? keys.concat(extraParams) : keys, body);
204
+ // The cache keys on the parameter list, so a function always has these keys.
205
+ fn.__stxKeys = keys;
206
+ return fn;
207
+ }
208
+
209
+ function __stxArgs(fn, scope) {
210
+ const keys = fn.__stxKeys;
211
+ const args = new Array(keys.length);
212
+ for (let i = 0; i < keys.length; i++) args[i] = scope[keys[i]];
213
+ return args;
214
+ }
215
+
157
216
  let activeEffect = null;
158
217
  const effectStack = [];
159
218
  const pendingEffects = new Set();
@@ -743,8 +802,8 @@ else {
743
802
  // First evaluate the base expression
744
803
  let value;
745
804
  try {
746
- const fn = new Function(...Object.keys(scope), 'return ' + valueExpr);
747
- value = fn(...Object.values(scope));
805
+ const fn = __stxCompileScoped(scope, [], 'return ' + valueExpr);
806
+ value = fn(...__stxArgs(fn, scope));
748
807
  }
749
808
  catch (e) {
750
809
  if (!(e instanceof ReferenceError) && !(e instanceof TypeError)) console.warn('[STX] Pipe base expression error:', valueExpr, e);
@@ -764,8 +823,8 @@ catch (e) {
764
823
  if (/^['"].*['"]$/.test(arg)) return arg.slice(1, -1);
765
824
  // Try to evaluate as expression in scope
766
825
  try {
767
- const fn = new Function(...Object.keys(scope), 'return ' + arg);
768
- return fn(...Object.values(scope));
826
+ const fn = __stxCompileScoped(scope, [], 'return ' + arg);
827
+ return fn(...__stxArgs(fn, scope));
769
828
  }
770
829
  catch (e) {
771
830
  return arg;
@@ -2056,8 +2115,8 @@ finally {
2056
2115
  || expressionUsesSignalApi(expr, prop);
2057
2116
  })
2058
2117
  : baseScope;
2059
- const fn = new Function(...Object.keys(baseScope), 'return ' + expr);
2060
- const result = fn(...Object.values(scope));
2118
+ const fn = __stxCompileScoped(baseScope, [], 'return ' + expr);
2119
+ const result = fn(...__stxArgs(fn, scope));
2061
2120
  // Post-eval unwrap \u2014 see evalAttrExpr note for the reason.
2062
2121
  return (result && typeof result === 'function' && (result._isSignal || result._isDerived)) ? result() : result;
2063
2122
  }
@@ -2224,8 +2283,8 @@ catch (e) {
2224
2283
  const v = scope[k];
2225
2284
  handlerScope[k] = (v && typeof v === 'function' && v._isStxLoopItem) ? v() : v;
2226
2285
  });
2227
- const fn = new Function(...Object.keys(handlerScope), '$event', expr);
2228
- fn(...Object.values(handlerScope), event);
2286
+ const fn = __stxCompileScoped(handlerScope, ['$event'], expr);
2287
+ fn(...__stxArgs(fn, handlerScope), event);
2229
2288
  }
2230
2289
  catch (e) {
2231
2290
  // Event handlers fire on user interaction, not reactive re-runs \u2014 there's no
@@ -2534,7 +2593,7 @@ catch (e) {
2534
2593
  return expressionCallsSignal(expression, prop)
2535
2594
  || expressionUsesSignalApi(expression, prop);
2536
2595
  });
2537
- var fn = new Function('__scope__', 'with(__scope__) { return (' + expression + ') }');
2596
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expression + ') }');
2538
2597
  value = fn(unwrapScope);
2539
2598
  if (value && typeof value === 'function' && (value._isSignal || value._isDerived)) value = value();
2540
2599
  }
@@ -2742,8 +2801,8 @@ catch (e) {
2742
2801
  var memoExpr = el.getAttribute('data-stx-memo');
2743
2802
  try {
2744
2803
  var memoScope = { ...globalHelpers, ...scope, ...(findElementScope(el) || {}) };
2745
- var memoFn = new Function(...Object.keys(memoScope), 'return ' + memoExpr);
2746
- var memoVals = JSON.stringify(memoFn(...Object.values(memoScope)));
2804
+ var memoFn = __stxCompileScoped(memoScope, [], 'return ' + memoExpr);
2805
+ var memoVals = JSON.stringify(memoFn(...__stxArgs(memoFn, memoScope)));
2747
2806
  if (el.__stx_memo_prev === memoVals) {
2748
2807
  return; // Dependencies unchanged \u2014 skip re-processing
2749
2808
  }
@@ -2795,8 +2854,8 @@ catch (e) {
2795
2854
  else {
2796
2855
  // Use auto-unwrap proxy (Feature #1)
2797
2856
  const unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
2798
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
2799
- bindingNode.textContent = fn(...Object.values(unwrapScope));
2857
+ const fn = __stxCompileScoped(capturedScope, [], 'return ' + expr);
2858
+ bindingNode.textContent = fn(...__stxArgs(fn, unwrapScope));
2800
2859
  }
2801
2860
  }
2802
2861
  catch (e) {
@@ -2804,8 +2863,8 @@ catch (e) {
2804
2863
  // because it converts the signal to its value before the expression runs.
2805
2864
  // Retry without auto-unwrap so signal functions remain callable.
2806
2865
  try {
2807
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
2808
- bindingNode.textContent = fn(...Object.values(capturedScope));
2866
+ const fn = __stxCompileScoped(capturedScope, [], 'return ' + expr);
2867
+ bindingNode.textContent = fn(...__stxArgs(fn, capturedScope));
2809
2868
  }
2810
2869
  catch (e2) {
2811
2870
  if (!(e2 instanceof ReferenceError) && !(e2 instanceof TypeError)) console.warn('[STX] Expression error:', expr, e2);
@@ -2921,7 +2980,7 @@ else if (part) {
2921
2980
 
2922
2981
  // Use auto-unwrap proxy (Feature #1)
2923
2982
  const unwrapScope = createExpressionAutoUnwrapProxy(activeScope, expr);
2924
- const fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
2983
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
2925
2984
  var value = maybeUnwrapSignal(fn(unwrapScope));
2926
2985
  noteExprSuccess(expr);
2927
2986
  return value;
@@ -2930,7 +2989,7 @@ catch (e) {
2930
2989
  // Auto-unwrap can break explicit signal calls like errorData().message
2931
2990
  // Retry without auto-unwrap so signal functions remain callable
2932
2991
  try {
2933
- const fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
2992
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
2934
2993
  var retried = maybeUnwrapSignal(fn(activeScope));
2935
2994
  noteExprSuccess(expr);
2936
2995
  return retried;
@@ -3244,7 +3303,7 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
3244
3303
  return 'if(' + k + ' !== __s["' + k + '"]()) __s["' + k + '"].set(' + k + ')';
3245
3304
  }).join(';');
3246
3305
  var body = getVars + ';' + value + ';' + setVars;
3247
- var fn2 = new Function('__s', '$event', body);
3306
+ var fn2 = __stxCompile(['__s', '$event'], body);
3248
3307
  fn2(eventCapturedScope, handlerEvent);
3249
3308
  } else if (hasSignals) {
3250
3309
  // Function calls with signals in scope keep any signal used through
@@ -3267,11 +3326,11 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
3267
3326
  }
3268
3327
  return 'var ' + k + ' = __s["' + k + '"] && typeof __s["' + k + '"] === "function" && __s["' + k + '"]._isSignal ? __s["' + k + '"]() : __s["' + k + '"]';
3269
3328
  }).join(';');
3270
- var fn3 = new Function('__s', '$event', unwrapVars + ';' + value);
3329
+ var fn3 = __stxCompile(['__s', '$event'], unwrapVars + ';' + value);
3271
3330
  fn3(eventCapturedScope, handlerEvent);
3272
3331
  } else {
3273
- var fn = new Function(...Object.keys(eventCapturedScope), '$event', value);
3274
- fn(...Object.values(eventCapturedScope), handlerEvent);
3332
+ var fn = __stxCompileScoped(eventCapturedScope, ['$event'], value);
3333
+ fn(...__stxArgs(fn, eventCapturedScope), handlerEvent);
3275
3334
  }
3276
3335
  }
3277
3336
  catch (e) {
@@ -3396,14 +3455,14 @@ catch (e) {
3396
3455
  var value;
3397
3456
  try {
3398
3457
  var unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3399
- var fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
3400
- value = fn(...Object.values(unwrapScope));
3458
+ var fn = __stxCompileScoped(capturedScope, [], 'return ' + expr);
3459
+ value = fn(...__stxArgs(fn, unwrapScope));
3401
3460
  } catch (e1) {
3402
3461
  // Retry without unwrapping \u2014 handles edge cases where the proxy
3403
3462
  // interferes with certain expression patterns
3404
3463
  try {
3405
- var fn2 = new Function(...Object.keys(capturedScope), 'return ' + expr);
3406
- value = fn2(...Object.values(capturedScope));
3464
+ var fn2 = __stxCompileScoped(capturedScope, [], 'return ' + expr);
3465
+ value = fn2(...__stxArgs(fn2, capturedScope));
3407
3466
  } catch (e2) {
3408
3467
  // Suppress ReferenceError/TypeError during async init \u2014 a signal
3409
3468
  // or object may not be ready yet on the first effect run, and
@@ -3448,7 +3507,7 @@ catch (e) {
3448
3507
  return direct();
3449
3508
  try {
3450
3509
  var unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3451
- var fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
3510
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
3452
3511
  return fn(unwrapScope);
3453
3512
  }
3454
3513
  catch (e) {
@@ -3476,7 +3535,7 @@ else {
3476
3535
  // Routing through it also drops the old requirement that every scope
3477
3536
  // key be a valid identifier, since nothing is destructured now.
3478
3537
  var writeScope = createModelWriteProxy(capturedScope);
3479
- var writeFn = new Function('__scope__', '__v__', 'with(__scope__) { ' + expr + ' = __v__ }');
3538
+ var writeFn = __stxCompile(['__scope__', '__v__'], 'with(__scope__) { ' + expr + ' = __v__ }');
3480
3539
  writeFn(writeScope, val);
3481
3540
  }
3482
3541
  }
@@ -3586,11 +3645,14 @@ else {
3586
3645
  const capturedScope = { ...globalHelpers, ...passedScope, ...(findElementScope(el) || {}) };
3587
3646
  const keys = Object.keys(capturedScope);
3588
3647
 
3589
- // Pre-compile \u2014 filter out keys that aren't valid JS identifiers
3590
- const safeKeys = keys.filter(k => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k));
3648
+ // Pre-compile \u2014 only the names the expression mentions (see
3649
+ // __stxCompileScoped: reading every signal subscribed the class binding to
3650
+ // every signal on the page), and only valid JS identifiers.
3651
+ const mentioned = new Set(__stxNamesIn(expr));
3652
+ const safeKeys = keys.filter(k => mentioned.has(k) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k));
3591
3653
  let fn;
3592
3654
  try {
3593
- fn = new Function(...safeKeys, 'return ' + expr);
3655
+ fn = __stxCompile(safeKeys, 'return ' + expr);
3594
3656
  } catch (e) {
3595
3657
  console.warn('[STX] bindClass compile error:', expr, e);
3596
3658
  return;
@@ -3659,13 +3721,13 @@ else {
3659
3721
  // throw TypeError.
3660
3722
  try {
3661
3723
  const unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3662
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
3663
- return fn(...Object.values(unwrapScope));
3724
+ const fn = __stxCompileScoped(capturedScope, [], 'return ' + expr);
3725
+ return fn(...__stxArgs(fn, unwrapScope));
3664
3726
  }
3665
3727
  catch (e1) {
3666
3728
  try {
3667
- const fn2 = new Function(...Object.keys(capturedScope), 'return ' + expr);
3668
- return fn2(...Object.values(capturedScope));
3729
+ const fn2 = __stxCompileScoped(capturedScope, [], 'return ' + expr);
3730
+ return fn2(...__stxArgs(fn2, capturedScope));
3669
3731
  }
3670
3732
  catch (e2) {
3671
3733
  if (!(e2 instanceof ReferenceError) && !(e2 instanceof TypeError)) console.warn('[STX] Style expression error:', expr, e2);
@@ -4150,8 +4212,8 @@ else {
4150
4212
  return expressionCallsSignal(expression, prop)
4151
4213
  || expressionUsesSignalApi(expression, prop);
4152
4214
  });
4153
- const fn = new Function(...Object.keys(scope), 'return ' + expression);
4154
- return fn(...Object.values(unwrapScope));
4215
+ const fn = __stxCompileScoped(scope, [], 'return ' + expression);
4216
+ return fn(...__stxArgs(fn, unwrapScope));
4155
4217
  }
4156
4218
  catch (e) {
4157
4219
  if (!(e instanceof ReferenceError) && !(e instanceof TypeError)) console.warn('[STX] Expression error:', expression, e);
@@ -4173,7 +4235,7 @@ catch (e) {
4173
4235
  });
4174
4236
  // new Function body is non-strict, so with() works \u2014 only accessed
4175
4237
  // properties trigger the proxy's get trap and register as dependencies
4176
- const fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4238
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4177
4239
  return fn(unwrapScope);
4178
4240
  } catch (e) {
4179
4241
  if (!(e instanceof ReferenceError) && !(e instanceof TypeError)) console.warn('[STX] Expression error:', expression, e);
@@ -4268,7 +4330,7 @@ catch (e) {
4268
4330
  try {
4269
4331
  const scope = { [itemName]: item };
4270
4332
  if (indexName) scope[indexName] = index;
4271
- const fn = new Function(itemName, indexName || '_idx', 'return ' + keyExpr);
4333
+ const fn = __stxCompile([itemName, indexName || '_idx'], 'return ' + keyExpr);
4272
4334
  return String(fn(item, index));
4273
4335
  } catch (e) {
4274
4336
  return String(index);
@@ -4691,12 +4753,12 @@ catch (e) {
4691
4753
  try {
4692
4754
  var unwrapScope = createExpressionAutoUnwrapProxy(scope, expression);
4693
4755
  // new Function body is non-strict, so with() works.
4694
- var fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4756
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4695
4757
  return fn(unwrapScope);
4696
4758
  }
4697
4759
  catch (e1) {
4698
4760
  try {
4699
- var fn2 = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4761
+ var fn2 = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4700
4762
  return fn2(scope);
4701
4763
  }
4702
4764
  catch (e2) {
@@ -4940,14 +5002,14 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
4940
5002
  try {
4941
5003
  const scope = { ...globalHelpers, ...capturedComponentScope, ...(capturedElementScope || {}) };
4942
5004
  const unwrapScope = createExpressionAutoUnwrapProxy(scope, expression);
4943
- const fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
5005
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4944
5006
  return fn(unwrapScope);
4945
5007
  }
4946
5008
  catch (e1) {
4947
5009
  try {
4948
5010
  // Retry without the unwrap proxy so call-syntax (signal()) works.
4949
5011
  const scope2 = { ...globalHelpers, ...capturedComponentScope, ...(capturedElementScope || {}) };
4950
- const fn2 = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
5012
+ const fn2 = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4951
5013
  return fn2(scope2);
4952
5014
  }
4953
5015
  catch (e2) {
@@ -8240,8 +8302,8 @@ else {
8240
8302
  if (matches) {
8241
8303
  matches.forEach(match => {
8242
8304
  const expr = match.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, '');
8243
- const fn = new Function(...Object.keys(componentScope), 'return ' + expr);
8244
- const value = fn(...Object.values(componentScope));
8305
+ const fn = __stxCompileScoped(componentScope, [], 'return ' + expr);
8306
+ const value = fn(...__stxArgs(fn, componentScope));
8245
8307
  result = result.replace(match, value != null ? value : '');
8246
8308
  });
8247
8309
  }
@@ -8267,8 +8329,8 @@ else if (el.tagName === 'META') {
8267
8329
  matches.forEach(match => {
8268
8330
  const expr = match.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, '');
8269
8331
  if (/^__[A-Z_]+__$/.test(expr.trim())) return;
8270
- const fn = new Function(...Object.keys(componentScope), 'return ' + expr);
8271
- const value = fn(...Object.values(componentScope));
8332
+ const fn = __stxCompileScoped(componentScope, [], 'return ' + expr);
8333
+ const value = fn(...__stxArgs(fn, componentScope));
8272
8334
  result = result.replace(match, value != null ? value : '');
8273
8335
  });
8274
8336
  }
package/dist/ssg.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Ck as Fq,xk as Uq,yk as Iq}from"./chunk-necx4e30.js";import{Dk as Eq,Ek as Tq,Fk as Dq}from"./chunk-frp9fc7j.js";import{_k as _q,bl as zq,cl as Aq}from"./chunk-e8nxcfp3.js";import"./chunk-rw0j25b8.js";import"./chunk-qjvny3wf.js";import{Lp as P,Tm as Oq,jo as l,mo as Hq,xr as n}from"./chunk-3xt912sq.js";import"./chunk-jc6wrxrh.js";import"./chunk-2xpdcr8c.js";import"./chunk-v90kxg77.js";import"./chunk-4arms0am.js";import"./chunk-135mme4g.js";import{nt as Xq}from"./chunk-8b5cwheg.js";import{st as d}from"./chunk-w1asc0zd.js";import"./chunk-kd95t585.js";import"./chunk-6xmkzx0a.js";import"./chunk-xk402w4a.js";import{Zt as Bq}from"./chunk-dnard9gp.js";import"./chunk-vgx5077x.js";import"./chunk-met6wtbk.js";import"./chunk-ta6z7k4p.js";import"./chunk-zxptxz2b.js";import"./chunk-7racewc5.js";import{Aw as Lq,Bw as Nq,ww as Yq,xw as Vq,yw as jq,zw as Gq}from"./chunk-e03m4har.js";import"./chunk-vsqx756d.js";import{Sw as y}from"./chunk-m8kem5ca.js";import O from"fs";import j from"path";import{createHash as xq}from"crypto";function yq(q){try{return new Bun.Transpiler({loader:"js",minifyWhitespace:!0}).transformSync(q).replace(/\}(var |let |const |function )/g,"};$1").trim()}catch{return q}}var Pq=/<script\s+type="stx\/island"\s+data-stx-island="([^"]+)"([^>]*)>([\s\S]*?)<\/script>/g;function Cq(q){return Bun.hash(q).toString(16)}function Qq(q,Z={}){if(!q.includes('type="stx/island"'))return{html:q,chunks:[]};let $=new Map,Q=q.replace(Pq,(J,W,z,A)=>{let G=A.trim();if(!G)return J;if(/\bdata-stx-src=/.test(z))return J;if(Z.minify)G=yq(G);let X=Cq(G);if(!$.has(X))$.set(X,G);let B=Z.integrity?` data-stx-integrity="sha384-${xq("sha384").update(G).digest("base64")}"`:"";return`<script type="stx/island" data-stx-island="${W}" data-stx-src="/_stx/islands/${X}.js"${B}${z}></script>`}),K=Array.from($,([J,W])=>({hash:J,code:W}));return{html:Q,chunks:K}}var gq=new Set(["visible","idle"]);function Zq(q){if(!q.includes("data-stx-src="))return q;let Z=new Map,$=/data-stx-scope="([^"]+)"[^>]*?stx-hydrate="([^"]+)"/g,Q;while((Q=$.exec(q))!==null)Z.set(Q[1],Q[2]);let K=new Set,J=/data-stx-island="([^"]+)"[^>]*?data-stx-src="([^"]+)"/g,W;while((W=J.exec(q))!==null)if(gq.has(Z.get(W[1])||""))K.add(W[2]);let z=q.lastIndexOf("</head>");if(K.size===0||z===-1)return q;let A=Array.from(K).filter((G)=>!q.includes(`rel="prefetch" href="${G}"`)).map((G)=>`<link rel="prefetch" href="${G}" as="script">`).join("");if(!A)return q;return q.slice(0,z)+A+q.slice(z)}var fq=["STX_SITE_URL","SITE_URL","URL","VERCEL_URL","CF_PAGES_URL"];function h(q){let Z=q.trim();if(!Z)return null;let $=/^https?:\/\//i.test(Z)?Z:`https://${Z}`;try{return new URL($).origin+new URL($).pathname.replace(/\/$/,"")}catch{return null}}function mq(q){for(let Z of fq){let $=q[Z];if(!$)continue;let Q=h($);if(Q)return{url:Q,source:"env",via:Z}}return null}function $q(q){if(!q||typeof q!=="object")return null;let Z=q,$=Z.site?.url??Z.url??Z.app?.url;return typeof $==="string"?h($):null}async function dq(q){let{existsSync:Z}=await import("fs"),$=await import("path");for(let Q of["site.config.ts","site.config.js",".config/site.config.ts"]){let K=$.resolve(q,Q);if(!Z(K))continue;try{let J=await import(K),W=$q(J.default??J);if(W)return W}catch{}}return null}async function Kq(q={}){let Z=q.cwd??process.cwd(),$=q.env??process.env;if(q.explicit){let W=h(q.explicit);if(W)return{url:W,source:"option"}}let Q=$q(q.stxConfig);if(Q)return{url:Q,source:"stx.config",via:"site.url"};let K=await dq(Z);if(K)return{url:K,source:"site.config",via:"url"};let J=mq($);if(J)return J;return{url:"http://localhost",source:"fallback"}}function Wq(){return["No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost."," Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,"," via --domain, or with SITE_URL in the build environment."].join(`
2
+ import{Ck as Fq,xk as Uq,yk as Iq}from"./chunk-necx4e30.js";import{Dk as Eq,Ek as Tq,Fk as Dq}from"./chunk-frp9fc7j.js";import{_k as _q,bl as zq,cl as Aq}from"./chunk-z541dzm4.js";import"./chunk-t6928tnd.js";import"./chunk-qjvny3wf.js";import{Lp as P,Tm as Oq,jo as l,mo as Hq,xr as n}from"./chunk-y3gd1g9s.js";import"./chunk-jc6wrxrh.js";import"./chunk-2xpdcr8c.js";import"./chunk-v90kxg77.js";import"./chunk-4arms0am.js";import"./chunk-135mme4g.js";import{nt as Xq}from"./chunk-y4j6br2e.js";import{st as d}from"./chunk-w1asc0zd.js";import"./chunk-kd95t585.js";import"./chunk-rg473fqn.js";import"./chunk-xk402w4a.js";import{Zt as Bq}from"./chunk-dnard9gp.js";import"./chunk-vgx5077x.js";import"./chunk-met6wtbk.js";import"./chunk-ta6z7k4p.js";import"./chunk-zxptxz2b.js";import"./chunk-7racewc5.js";import{Aw as Lq,Bw as Nq,ww as Yq,xw as Vq,yw as jq,zw as Gq}from"./chunk-e03m4har.js";import"./chunk-vsqx756d.js";import{Sw as y}from"./chunk-m8kem5ca.js";import O from"fs";import j from"path";import{createHash as xq}from"crypto";function yq(q){try{return new Bun.Transpiler({loader:"js",minifyWhitespace:!0}).transformSync(q).replace(/\}(var |let |const |function )/g,"};$1").trim()}catch{return q}}var Pq=/<script\s+type="stx\/island"\s+data-stx-island="([^"]+)"([^>]*)>([\s\S]*?)<\/script>/g;function Cq(q){return Bun.hash(q).toString(16)}function Qq(q,Z={}){if(!q.includes('type="stx/island"'))return{html:q,chunks:[]};let $=new Map,Q=q.replace(Pq,(J,W,z,A)=>{let G=A.trim();if(!G)return J;if(/\bdata-stx-src=/.test(z))return J;if(Z.minify)G=yq(G);let X=Cq(G);if(!$.has(X))$.set(X,G);let B=Z.integrity?` data-stx-integrity="sha384-${xq("sha384").update(G).digest("base64")}"`:"";return`<script type="stx/island" data-stx-island="${W}" data-stx-src="/_stx/islands/${X}.js"${B}${z}></script>`}),K=Array.from($,([J,W])=>({hash:J,code:W}));return{html:Q,chunks:K}}var gq=new Set(["visible","idle"]);function Zq(q){if(!q.includes("data-stx-src="))return q;let Z=new Map,$=/data-stx-scope="([^"]+)"[^>]*?stx-hydrate="([^"]+)"/g,Q;while((Q=$.exec(q))!==null)Z.set(Q[1],Q[2]);let K=new Set,J=/data-stx-island="([^"]+)"[^>]*?data-stx-src="([^"]+)"/g,W;while((W=J.exec(q))!==null)if(gq.has(Z.get(W[1])||""))K.add(W[2]);let z=q.lastIndexOf("</head>");if(K.size===0||z===-1)return q;let A=Array.from(K).filter((G)=>!q.includes(`rel="prefetch" href="${G}"`)).map((G)=>`<link rel="prefetch" href="${G}" as="script">`).join("");if(!A)return q;return q.slice(0,z)+A+q.slice(z)}var fq=["STX_SITE_URL","SITE_URL","URL","VERCEL_URL","CF_PAGES_URL"];function h(q){let Z=q.trim();if(!Z)return null;let $=/^https?:\/\//i.test(Z)?Z:`https://${Z}`;try{return new URL($).origin+new URL($).pathname.replace(/\/$/,"")}catch{return null}}function mq(q){for(let Z of fq){let $=q[Z];if(!$)continue;let Q=h($);if(Q)return{url:Q,source:"env",via:Z}}return null}function $q(q){if(!q||typeof q!=="object")return null;let Z=q,$=Z.site?.url??Z.url??Z.app?.url;return typeof $==="string"?h($):null}async function dq(q){let{existsSync:Z}=await import("fs"),$=await import("path");for(let Q of["site.config.ts","site.config.js",".config/site.config.ts"]){let K=$.resolve(q,Q);if(!Z(K))continue;try{let J=await import(K),W=$q(J.default??J);if(W)return W}catch{}}return null}async function Kq(q={}){let Z=q.cwd??process.cwd(),$=q.env??process.env;if(q.explicit){let W=h(q.explicit);if(W)return{url:W,source:"option"}}let Q=$q(q.stxConfig);if(Q)return{url:Q,source:"stx.config",via:"site.url"};let K=await dq(Z);if(K)return{url:K,source:"site.config",via:"url"};let J=mq($);if(J)return J;return{url:"http://localhost",source:"fallback"}}function Wq(){return["No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost."," Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,"," via --domain, or with SITE_URL in the build environment."].join(`
3
3
  `)}class wq{cacheDir;cache=new Map;loaded=!1;salt;constructor(q,Z=""){this.cacheDir=q,this.salt=Z}async load(){if(this.loaded)return;let q=j.join(this.cacheDir,"build-cache.json");if(await Bun.file(q).exists())try{let Z=JSON.parse(await Bun.file(q).text());for(let[$,Q]of Object.entries(Z))this.cache.set($,Q)}catch{}this.loaded=!0}async save(){await O.promises.mkdir(this.cacheDir,{recursive:!0});let q=j.join(this.cacheDir,"build-cache.json"),Z={};for(let[$,Q]of this.cache)Z[$]=Q;await Bun.write(q,JSON.stringify(Z))}getHash(q,Z){let $=O.statSync(q),Q=`${this.salt}|${q}:${$.mtimeMs}`;for(let J of Z)if(O.existsSync(J)){let W=O.statSync(J);Q+=`:${J}:${W.mtimeMs}`}let K=0;for(let J=0;J<Q.length;J++){let W=Q.charCodeAt(J);K=(K<<5)-K+W,K=K&K}return Math.abs(K).toString(36)}get(q,Z){let $=this.cache.get(q);if(!$)return null;let Q=this.getHash(Z,$.dependencies??[]);if($.hash!==Q)return this.cache.delete(q),null;return $.html}set(q,Z,$,Q){let K=this.getHash(Z,$);this.cache.set(q,{hash:K,html:Q,generatedAt:Date.now(),dependencies:$})}}class Rq{cacheDir;constructor(q){this.cacheDir=q}getFilePath(q){let Z=q.replace(/[^a-zA-Z0-9]/g,"_")+".json";return j.join(this.cacheDir,"isr",Z)}async get(q){let Z=this.getFilePath(q);if(!await Bun.file(Z).exists())return null;try{return JSON.parse(await Bun.file(Z).text())}catch{return null}}async set(q,Z){let $=this.getFilePath(q);await O.promises.mkdir(j.dirname($),{recursive:!0}),await Bun.write($,JSON.stringify(Z))}async invalidate(q){let Z=this.getFilePath(q);if(await Bun.file(Z).exists())await O.promises.unlink(Z)}async invalidatePattern(q){let Z=j.join(this.cacheDir,"isr");if(!O.existsSync(Z))return;let $=await O.promises.readdir(Z);for(let Q of $){let K=Q.replace(/_/g,"/").replace(".json","");if(q.test(K))await O.promises.unlink(j.join(Z,Q))}}async needsRevalidation(q){let Z=await this.get(q);if(!Z)return!0;return Date.now()>Z.revalidateAfter}}async function pq(q){try{let $=(await Bun.file(q).text()).match(/<script\s+server\b[^>]*>([\s\S]*?)<\/script>/i);if(!$)return null;let Q=$[1];if(!Q.includes("getStaticPaths"))return null;let K=Q.match(/(?:export\s+)?(?:async\s+)?function\s+getStaticPaths\s*\([^)]*\)\s*\{([\s\S]*?)\n[\t ]*\}/);if(!K)return null;return await Function(`
4
4
  return (async function getStaticPaths() {
5
5
  ${K[1]}
@@ -41,7 +41,7 @@ ${q.map((Q)=>{let K=new URL(Q.loc,Z).href,J=` <url>
41
41
  ${$.join(`
42
42
  `)}
43
43
  </channel>
44
- </rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-6gns8q1a.js");try{L=N(await Y(process.cwd()))}catch{}}let{prepareImageDelivery:_}=await import("./chunk-pf8575bx.js"),F=await _(J.publicDir,J.outputDir);if(F.count>0)console.log(`Optimized ${F.count} image(s) for responsive delivery`),L=[L,F.fingerprint].filter(Boolean).join(":");let C=new wq(J.cacheDir,L);if(J.cache)await C.load();try{let{generateCss:Y}=await import("./chunk-6gns8q1a.js");await Y('<div class="bg-black"></div>')}catch{}Yq();let kq=$?.routeMiddleware?.dir||"middleware";await jq(process.cwd(),kq);let p=Vq();if(p.length>0)console.log(`Loaded ${p.length} middleware: ${p.join(", ")}`);let bq=$?.routeMiddleware?.global||[];Fq($?.layoutsDir,d(process.cwd()));let i=l(".",{pagesDir:J.pagesDir,pagesDirs:$?._layerPageDirs});console.log(`Found ${i.length} routes`);let g=[];for(let Y of i){let N=await uq(Y);for(let H of N)g.push({route:Y,url:H.url,params:H.params,props:H.props,revalidate:H.revalidate??J.revalidate})}W.totalPages=g.length,console.log(`Generating ${W.totalPages} pages...`);let b=[],s=[];for(let Y=0;Y<g.length;Y+=J.concurrency)s.push(g.slice(Y,Y+J.concurrency));for(let Y of s)await Promise.all(Y.map(async(N)=>{let{route:H,url:V,params:S,props:Sq,revalidate:a}=N;try{await J.hooks.onPageStart?.(V);let w=await Bun.file(H.filePath).text(),R=JJ(w),vq=R?.middleware?Array.isArray(R.middleware)?R.middleware:[R.middleware]:[],t=[...bq,...vq];if(t.length>0){let D=Gq(V,S,R||{}),M=Lq(D,null,void 0,{isServer:!0}),E=await Nq(t,M);if(E.redirect){let U=typeof E.redirect==="string"?E.redirect:E.redirect.path||E.redirect,x=QJ(String(U),V),k=ZJ(V,J);await O.promises.mkdir(j.dirname(k),{recursive:!0}),await Bun.write(k,x),W.successCount++,W.pages.push({route:V,outputPath:k,size:Buffer.byteLength(x),cached:!1}),b.push({loc:V,lastmod:new Date().toISOString()}),console.log(` \u21B3 ${V} \u2192 redirect to ${U}`);return}if(E.abort){let U=typeof E.abort==="string"?E.abort:E.abort?.error?.message||"aborted";console.warn(` \u21B3 ${V} \u2014 middleware aborted: ${U}`);return}}let e=w.match(/definePageMeta\s*\(\s*\{[\s\S]*?validate\s*:\s*((?:\([^)]*\)|[^,}])*(?:\{[\s\S]*?\})?)/m);if(e)try{if(!await Function("route",`
44
+ </rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-hd3g347d.js");try{L=N(await Y(process.cwd()))}catch{}}let{prepareImageDelivery:_}=await import("./chunk-pf8575bx.js"),F=await _(J.publicDir,J.outputDir);if(F.count>0)console.log(`Optimized ${F.count} image(s) for responsive delivery`),L=[L,F.fingerprint].filter(Boolean).join(":");let C=new wq(J.cacheDir,L);if(J.cache)await C.load();try{let{generateCss:Y}=await import("./chunk-hd3g347d.js");await Y('<div class="bg-black"></div>')}catch{}Yq();let kq=$?.routeMiddleware?.dir||"middleware";await jq(process.cwd(),kq);let p=Vq();if(p.length>0)console.log(`Loaded ${p.length} middleware: ${p.join(", ")}`);let bq=$?.routeMiddleware?.global||[];Fq($?.layoutsDir,d(process.cwd()));let i=l(".",{pagesDir:J.pagesDir,pagesDirs:$?._layerPageDirs});console.log(`Found ${i.length} routes`);let g=[];for(let Y of i){let N=await uq(Y);for(let H of N)g.push({route:Y,url:H.url,params:H.params,props:H.props,revalidate:H.revalidate??J.revalidate})}W.totalPages=g.length,console.log(`Generating ${W.totalPages} pages...`);let b=[],s=[];for(let Y=0;Y<g.length;Y+=J.concurrency)s.push(g.slice(Y,Y+J.concurrency));for(let Y of s)await Promise.all(Y.map(async(N)=>{let{route:H,url:V,params:S,props:Sq,revalidate:a}=N;try{await J.hooks.onPageStart?.(V);let w=await Bun.file(H.filePath).text(),R=JJ(w),vq=R?.middleware?Array.isArray(R.middleware)?R.middleware:[R.middleware]:[],t=[...bq,...vq];if(t.length>0){let D=Gq(V,S,R||{}),M=Lq(D,null,void 0,{isServer:!0}),E=await Nq(t,M);if(E.redirect){let U=typeof E.redirect==="string"?E.redirect:E.redirect.path||E.redirect,x=QJ(String(U),V),k=ZJ(V,J);await O.promises.mkdir(j.dirname(k),{recursive:!0}),await Bun.write(k,x),W.successCount++,W.pages.push({route:V,outputPath:k,size:Buffer.byteLength(x),cached:!1}),b.push({loc:V,lastmod:new Date().toISOString()}),console.log(` \u21B3 ${V} \u2192 redirect to ${U}`);return}if(E.abort){let U=typeof E.abort==="string"?E.abort:E.abort?.error?.message||"aborted";console.warn(` \u21B3 ${V} \u2014 middleware aborted: ${U}`);return}}let e=w.match(/definePageMeta\s*\(\s*\{[\s\S]*?validate\s*:\s*((?:\([^)]*\)|[^,}])*(?:\{[\s\S]*?\})?)/m);if(e)try{if(!await Function("route",`
45
45
  const validate = ${e[1]};
46
46
  return validate(route);
47
47
  `)({params:S})){console.warn(`Validation failed for ${V}, skipping...`);return}}catch{}let I=null,qq=!1;if(J.cache){if(I=C.get(V,H.filePath),I)qq=!0,W.cachedCount++}if(!I){let D=await Mq(H,S,Sq,J,$);if(I=D.html,J.failOnIncludeError&&D.includeFailures.length>0)throw Error(`${D.includeFailures.length} include(s) failed to resolve, so this page would have shipped with an error banner where the markup should be:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/stx",
3
3
  "type": "module",
4
- "version": "0.2.364",
4
+ "version": "0.2.366",
5
5
  "description": "A performant UI Framework. Powered by Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -118,12 +118,12 @@
118
118
  "dependencies": {
119
119
  "@stacksjs/ts-css": "^0.3.2",
120
120
  "@stacksjs/clapp": "^0.2.16",
121
- "@stacksjs/desktop": "0.2.364",
122
- "@stacksjs/sanitizer": "0.2.364",
121
+ "@stacksjs/desktop": "0.2.366",
122
+ "@stacksjs/sanitizer": "0.2.366",
123
123
  "@stacksjs/ts-i18n": "^0.1.11",
124
- "bun-plugin-stx": "0.2.364",
124
+ "bun-plugin-stx": "0.2.366",
125
125
  "bunfig": "^0.15.19",
126
- "stx-router": "0.2.364",
126
+ "stx-router": "0.2.366",
127
127
  "ts-broadcasting": "^0.0.10",
128
128
  "ts-images": "^0.2.22",
129
129
  "ts-syntax-highlighter": "^0.2.1"