@zerotal/flow 1.0.4 → 1.3.0

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/src/utils.ts CHANGED
@@ -176,15 +176,46 @@ export interface FlowChain<T> {
176
176
  // Shared capture variable: set by instrumented @expose getters in jsx-runtime,
177
177
  // consumed immediately by flow() to embed __key in the chain.
178
178
  let _exposedKeyCapture: string | undefined;
179
+
180
+ /**
181
+ * Every exposed key read since the last consume, in read order.
182
+ *
183
+ * `_exposedKeyCapture` is a single slot, but JSX evaluates *all* of an element's
184
+ * props before `jsx()` runs — so `value={this.destination} disabled={this.notSure}`
185
+ * leaves the slot pointing at `notSure` and the `value` binding resolves to nothing.
186
+ * Keeping the full read list lets a binding find the key that actually matches its
187
+ * own value, while still refusing to bind a literal that was never read through a
188
+ * `this.` getter at all. Bounded so a pathological render cannot grow it without limit.
189
+ */
190
+ const _exposedKeyReads: string[] = [];
191
+ const _MAX_KEY_READS = 64;
192
+
179
193
  export function _setExposedKeyCapture(k: string | undefined): void {
180
194
  _exposedKeyCapture = k;
195
+ if (k === undefined) return;
196
+ // Keep the most recent read last; drop an earlier duplicate so order stays meaningful.
197
+ const at = _exposedKeyReads.indexOf(k);
198
+ if (at !== -1) _exposedKeyReads.splice(at, 1);
199
+ _exposedKeyReads.push(k);
200
+ if (_exposedKeyReads.length > _MAX_KEY_READS) _exposedKeyReads.shift();
181
201
  }
202
+
182
203
  export function _consumeExposedKeyCapture(): string | undefined {
183
204
  const k = _exposedKeyCapture;
184
205
  _exposedKeyCapture = undefined;
185
206
  return k;
186
207
  }
187
208
 
209
+ /**
210
+ * The keys read since the last call, most recent first, clearing the list.
211
+ * Used by the value/checked binding resolver to survive a clobbered single slot.
212
+ */
213
+ export function _consumeExposedKeyReads(): string[] {
214
+ const reads = _exposedKeyReads.slice().reverse();
215
+ _exposedKeyReads.length = 0;
216
+ return reads;
217
+ }
218
+
188
219
  export function flow<T>(target: T): FlowChain<T> {
189
220
  const modifiers: string[] = [];
190
221
  // Capture immediately so subsequent prop evaluations cannot clobber it.