@mintjamsinc/ichigojs 0.1.72 → 0.1.74

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.
@@ -8017,6 +8017,41 @@ class ReactiveProxy {
8017
8017
  * This allows mapping variable names to their actual source paths for dependency tracking.
8018
8018
  */
8019
8019
  static pathAliases = new Map();
8020
+ /**
8021
+ * The `Object.prototype.toString` tags of the *only* value types we deeply
8022
+ * proxy. Everything else is returned untouched (raw).
8023
+ *
8024
+ * Rationale: a Proxy can only safely intercept plain data containers. Built-in
8025
+ * and host objects — `Date`, `RegExp`, `File`, `Blob`, `FileList`, `Promise`,
8026
+ * `WeakMap`/`WeakSet`, typed arrays, DOM nodes, etc. — carry private internal
8027
+ * slots, and invoking their native methods with a Proxy as the `this`/receiver
8028
+ * throws "Illegal invocation". They must therefore never be wrapped. This is an
8029
+ * allow-list rather than a deny-list so that *every* such exotic type is
8030
+ * excluded by default, not just the handful we happened to enumerate.
8031
+ *
8032
+ * Plain user-defined class instances report `[object Object]` (unless they set
8033
+ * `Symbol.toStringTag`) and so remain reactive, preserving prior behaviour.
8034
+ * `Map`/`Set` stay reactive because the proxy specially wraps their mutation
8035
+ * methods (see the `get` trap); `WeakMap`/`WeakSet` are intentionally excluded
8036
+ * since they cannot be wrapped that way and would break the same as `File`.
8037
+ *
8038
+ * Callers that want a plain object kept non-reactive can still opt out
8039
+ * explicitly via {@link markRaw}.
8040
+ */
8041
+ static REACTIVE_TYPE_TAGS = new Set([
8042
+ '[object Object]',
8043
+ '[object Array]',
8044
+ '[object Arguments]',
8045
+ '[object Map]',
8046
+ '[object Set]',
8047
+ ]);
8048
+ /**
8049
+ * Whether the given non-null object value is one we deeply proxy.
8050
+ * See {@link REACTIVE_TYPE_TAGS} for the reasoning.
8051
+ */
8052
+ static isReactivable(value) {
8053
+ return this.REACTIVE_TYPE_TAGS.has(Object.prototype.toString.call(value));
8054
+ }
8020
8055
  /**
8021
8056
  * Creates a reactive proxy for the given object.
8022
8057
  * The proxy will call the onChange callback whenever a property is modified.
@@ -8036,11 +8071,10 @@ class ReactiveProxy {
8036
8071
  if (this.rawObjects.has(target)) {
8037
8072
  return target;
8038
8073
  }
8039
- // Don't wrap built-in objects that have internal slots
8040
- // These objects require their methods to be called with the correct 'this' context
8041
- // Use Object.prototype.toString for more reliable type checking
8042
- const typeTag = Object.prototype.toString.call(target);
8043
- if (typeTag === '[object Date]' || typeTag === '[object RegExp]' || typeTag === '[object Error]') {
8074
+ // Only deeply proxy plain data containers; return every built-in/host
8075
+ // object (Date, File, Blob, Promise, WeakMap, DOM nodes, …) as-is, since
8076
+ // their native methods break when invoked through a Proxy receiver.
8077
+ if (!this.isReactivable(target)) {
8044
8078
  return target;
8045
8079
  }
8046
8080
  // Check if the target is already a proxy - if so, return it as-is to prevent double-wrapping
@@ -8076,10 +8110,10 @@ class ReactiveProxy {
8076
8110
  if (ReactiveProxy.rawObjects.has(value)) {
8077
8111
  return value;
8078
8112
  }
8079
- // Don't wrap built-in objects that have internal slots
8080
- // Use Object.prototype.toString for more reliable type checking
8081
- const valueTypeTag = Object.prototype.toString.call(value);
8082
- if (valueTypeTag === '[object Date]' || valueTypeTag === '[object RegExp]' || valueTypeTag === '[object Error]') {
8113
+ // Only deeply proxy plain data containers; hand back built-in
8114
+ // and host objects (Date, File, Blob, Promise, WeakMap, DOM
8115
+ // nodes, …) untouched so their native methods keep working.
8116
+ if (!ReactiveProxy.isReactivable(value)) {
8083
8117
  return value;
8084
8118
  }
8085
8119
  // Build the nested path
@@ -8400,6 +8434,13 @@ class VBindings {
8400
8434
  * Flag to suppress onChange callbacks temporarily.
8401
8435
  */
8402
8436
  #suppressOnChange = false;
8437
+ /**
8438
+ * Flag forcing the next write through the `set` trap to stay in THIS scope's own
8439
+ * local store instead of walking up to an inherited binding of the same name.
8440
+ * Set only by {@link setLocal} for scope-local variables (e.g. v-for loop items),
8441
+ * which must shadow — never overwrite — a parent binding with the same key.
8442
+ */
8443
+ #localWrite = false;
8403
8444
  /**
8404
8445
  * Per-instance path aliases. Maps local variable names to their reactive source paths.
8405
8446
  * Scoped here instead of the global ReactiveProxy map so that v-for items each maintain
@@ -8478,8 +8519,13 @@ class VBindings {
8478
8519
  setter(value);
8479
8520
  return true;
8480
8521
  }
8522
+ // For a key that is not local to this scope, an assignment normally
8523
+ // retargets to the nearest parent that owns it, so reassignments
8524
+ // (e.g. `count = count + 1` in a handler) mutate the original binding.
8525
+ // A scope-local write (setLocal — used for v-for loop variables) skips
8526
+ // this walk so the variable shadows, never clobbers, an inherited key.
8481
8527
  let target = obj;
8482
- if (!Reflect.has(target, key)) {
8528
+ if (!this.#localWrite && !Reflect.has(target, key)) {
8483
8529
  for (let parent = this.#parent; parent; parent = parent.#parent) {
8484
8530
  if (Reflect.has(parent.#local, key)) {
8485
8531
  target = parent.#local;
@@ -8654,6 +8700,25 @@ class VBindings {
8654
8700
  set(key, value) {
8655
8701
  this.#local[key] = value;
8656
8702
  }
8703
+ /**
8704
+ * Sets a binding value in THIS scope's own local store, without walking up to a
8705
+ * parent scope. Used for scope-local variables (e.g. v-for loop items) that must
8706
+ * shadow — never overwrite — an inherited binding of the same name. Contrast with
8707
+ * {@link set}, which retargets a write of an inherited key to the owning parent so
8708
+ * that reassignments mutate the original; a loop variable named like a root data /
8709
+ * method / computed key (e.g. `t`) would otherwise clobber it.
8710
+ * @param key The binding name.
8711
+ * @param value The binding value.
8712
+ */
8713
+ setLocal(key, value) {
8714
+ this.#localWrite = true;
8715
+ try {
8716
+ this.#local[key] = value;
8717
+ }
8718
+ finally {
8719
+ this.#localWrite = false;
8720
+ }
8721
+ }
8657
8722
  /**
8658
8723
  * Gets a binding value.
8659
8724
  * @param key The binding name.
@@ -10749,26 +10814,30 @@ class VForDirective {
10749
10814
  * Sets item bindings for a VNode, handling nested destructuring if needed.
10750
10815
  */
10751
10816
  #setItemBindings(bindings, context) {
10817
+ // Loop variables are scope-local: they must shadow, never overwrite, an
10818
+ // inherited binding of the same name (a data / method / computed key on a
10819
+ // parent scope). setLocal writes to this iteration's own store so a loop
10820
+ // variable named like e.g. the i18n helper `t` cannot clobber it.
10752
10821
  if (this.#itemDestructure && Array.isArray(context.item)) {
10753
10822
  // Nested destructuring: spread array items to individual bindings
10754
10823
  // e.g., item = ['alice', 1] with itemDestructure = ['k', 'v']
10755
- // bindings.set('k', 'alice')
10756
- // bindings.set('v', 1)
10824
+ // bindings.setLocal('k', 'alice')
10825
+ // bindings.setLocal('v', 1)
10757
10826
  this.#itemDestructure.forEach((name, i) => {
10758
- bindings.set(name, context.item[i]);
10827
+ bindings.setLocal(name, context.item[i]);
10759
10828
  });
10760
10829
  }
10761
10830
  else if (this.#itemName) {
10762
10831
  // Simple item binding
10763
- bindings.set(this.#itemName, context.item);
10832
+ bindings.setLocal(this.#itemName, context.item);
10764
10833
  }
10765
10834
  if (this.#indexName) {
10766
10835
  // For objects, use objectKey if available; otherwise use numeric index
10767
- bindings.set(this.#indexName, context.objectKey ?? context.index);
10836
+ bindings.setLocal(this.#indexName, context.objectKey ?? context.index);
10768
10837
  }
10769
10838
  if (this.#thirdName) {
10770
10839
  // Third argument is always the numeric index
10771
- bindings.set(this.#thirdName, context.index);
10840
+ bindings.setLocal(this.#thirdName, context.index);
10772
10841
  }
10773
10842
  }
10774
10843
  /**