@llui/vite-plugin 0.0.16 → 0.0.18

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/transform.js CHANGED
@@ -1119,13 +1119,38 @@ function tryBuildHandlers(configArg, topLevelBits, structuralMask, f) {
1119
1119
  * - 'mutate': array created via `.slice()` then mutated in place (same keys)
1120
1120
  * - 'general': unknown pattern, use generic reconcile
1121
1121
  */
1122
- function detectArrayOp(clause, stateName, modifiedFields, structuralMask, caseDirty) {
1123
- // No fields modified or dirty bits don't intersect any structural block
1124
- // skip structural blocks entirely (e.g., only `selected` changes)
1122
+ function detectArrayOp(clause, stateName, modifiedFields, _structuralMask, _caseDirty) {
1123
+ // No fields modified no Phase 1 needed (no bindings can care if no
1124
+ // state field changed). Safe to return 'none' here because it's a
1125
+ // tautology: every binding mask ANDed with zero is zero.
1125
1126
  if (modifiedFields.length === 0)
1126
1127
  return 'none';
1127
- if (structuralMask !== undefined && caseDirty !== undefined && (structuralMask & caseDirty) === 0)
1128
- return 'none';
1128
+ // Previously: if `(structuralMask & caseDirty) === 0`, return 'none'
1129
+ // on the theory that no structural block's mask could intersect this
1130
+ // case's dirty bits. That optimization was UNSAFE: `computeStructuralMask`
1131
+ // only walks the view function's lexical AST and does not descend into
1132
+ // helper function calls. A view like
1133
+ //
1134
+ // view: () => [
1135
+ // ...show({ when: s => s.mode === 'signin', render: () => [signinFormBody()] }),
1136
+ // ]
1137
+ //
1138
+ // where `signinFormBody()` is a helper that internally does
1139
+ // ...show({ when: s => s.errors.email !== undefined, ... })
1140
+ //
1141
+ // produces a `structuralMask` that covers `mode` but MISSES
1142
+ // `errors.email`. At runtime the inner show block is still registered
1143
+ // in `inst.structuralBlocks`, and it legitimately needs to reconcile
1144
+ // when `errors` changes — but the compiler was emitting `method = -1`
1145
+ // (skip blocks entirely) for cases that only touch `errors`, and the
1146
+ // error paragraphs would never mount.
1147
+ //
1148
+ // The fix is to remove this short-circuit. Phase 1 runs unconditionally
1149
+ // when any field is modified; `_handleMsg`'s per-block check
1150
+ // `if (!(block.mask & dirty)) continue` filters out uninterested
1151
+ // blocks at near-zero cost. We lose a micro-optimization but gain
1152
+ // correctness for every component that factors view helpers into
1153
+ // functions — which is the idiomatic pattern.
1129
1154
  // Look at the return expression's array field values
1130
1155
  for (const stmt of clause.statements) {
1131
1156
  const returnExpr = findReturnArray(stmt);