@mintjamsinc/ichigojs 0.1.4 → 0.1.6

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.
@@ -7678,6 +7678,13 @@
7678
7678
  * This is optional and may be undefined if the node has not been templatized.
7679
7679
  */
7680
7680
  #templatized;
7681
+ /**
7682
+ * User data storage for lifecycle directives.
7683
+ * This provides a Proxy-free space where developers can store arbitrary data
7684
+ * associated with this VNode. The data is automatically cleaned up when the
7685
+ * VNode is destroyed.
7686
+ */
7687
+ #userData;
7681
7688
  /**
7682
7689
  * Creates an instance of the virtual node.
7683
7690
  * @param args The initialization arguments for the virtual node.
@@ -7889,6 +7896,18 @@
7889
7896
  this.#preparableIdentifiers = preparableIdentifiers.length === 0 ? [] : [...new Set(preparableIdentifiers)];
7890
7897
  return this.#preparableIdentifiers;
7891
7898
  }
7899
+ /**
7900
+ * Gets the user data storage for this virtual node.
7901
+ * This is lazily initialized and provides a Proxy-free space for storing
7902
+ * arbitrary data associated with lifecycle directives.
7903
+ * @returns A Map for storing user data.
7904
+ */
7905
+ get userData() {
7906
+ if (!this.#userData) {
7907
+ this.#userData = new Map();
7908
+ }
7909
+ return this.#userData;
7910
+ }
7892
7911
  /**
7893
7912
  * The DOM path of this virtual node.
7894
7913
  * This is a string representation of the path from the root to this node,
@@ -8095,6 +8114,14 @@
8095
8114
  /**
8096
8115
  * Cleans up any resources used by this virtual node.
8097
8116
  * This method is called when the virtual node is no longer needed.
8117
+ *
8118
+ * Cleanup order:
8119
+ * 1. Call onUnmount lifecycle hooks
8120
+ * 2. Auto-cleanup userData (close() on Closeable objects)
8121
+ * 3. Recursively destroy child nodes
8122
+ * 4. Unregister dependencies
8123
+ * 5. Clean up directive manager
8124
+ * 6. Call onUnmounted lifecycle hooks
8098
8125
  */
8099
8126
  destroy() {
8100
8127
  // If no directive requires template preservation, call onUnmount for directives that do not templatize
@@ -8103,6 +8130,23 @@
8103
8130
  d.onUnmount?.();
8104
8131
  });
8105
8132
  }
8133
+ // Clean up user data, calling close() on any Closeable objects
8134
+ // This happens after onUnmount but before other cleanup, allowing users to
8135
+ // perform custom cleanup in onUnmount while having automatic cleanup of userData
8136
+ if (this.#userData) {
8137
+ for (const [key, value] of this.#userData.entries()) {
8138
+ try {
8139
+ // If the value has a close() method (Closeable pattern), call it
8140
+ if (value && typeof value === 'object' && typeof value.close === 'function') {
8141
+ value.close();
8142
+ }
8143
+ }
8144
+ catch (error) {
8145
+ this.#vApplication.logManager.getLogger(this.constructor.name).error(`Error closing user data '${key}': ${error}`);
8146
+ }
8147
+ }
8148
+ this.#userData.clear();
8149
+ }
8106
8150
  // Recursively destroy child nodes
8107
8151
  if (this.#childVNodes) {
8108
8152
  for (const childVNode of this.#childVNodes) {
@@ -9507,7 +9551,7 @@
9507
9551
  return ['mount', 'mounted', 'update', 'updated', 'unmount', 'unmounted'].includes(eventName);
9508
9552
  }
9509
9553
  /**
9510
- * Creates a wrapper function for lifecycle hooks (with element parameter).
9554
+ * Creates a wrapper function for lifecycle hooks (with context parameter).
9511
9555
  * @param expression The expression string to evaluate.
9512
9556
  * @returns A function that handles the lifecycle hook.
9513
9557
  */
@@ -9517,22 +9561,27 @@
9517
9561
  // Return a function that handles the lifecycle hook with proper scope
9518
9562
  return () => {
9519
9563
  const bindings = vNode.bindings;
9520
- const el = vNode.node;
9564
+ const $ctx = {
9565
+ element: vNode.node,
9566
+ vnode: vNode,
9567
+ userData: vNode.userData
9568
+ };
9521
9569
  // If the expression is just a method name, call it with bindings as 'this'
9522
9570
  const trimmedExpr = expression.trim();
9523
9571
  if (identifiers.includes(trimmedExpr) && typeof bindings?.get(trimmedExpr) === 'function') {
9524
9572
  const methodName = trimmedExpr;
9525
9573
  const originalMethod = bindings?.get(methodName);
9526
- // Call the method with bindings as 'this' context and element as parameter
9527
- // This allows the method to access the DOM element and bindings
9528
- return originalMethod(el);
9574
+ // Call the method with bindings as 'this' context and context as parameter
9575
+ // This allows the method to access the DOM element, VNode, and userData
9576
+ return originalMethod($ctx);
9529
9577
  }
9530
- // For inline expressions, evaluate normally with element parameter
9578
+ // For inline expressions, evaluate normally with $ctx parameter
9579
+ // Note: $ctx is a reserved variable name for lifecycle context
9531
9580
  const values = identifiers.map(id => vNode.bindings?.get(id));
9532
- const args = [...identifiers, 'el'].join(", ");
9581
+ const args = [...identifiers, '$ctx'].join(", ");
9533
9582
  const funcBody = `return (${expression});`;
9534
9583
  const func = new Function(args, funcBody);
9535
- return func.call(bindings?.raw, ...values, el);
9584
+ return func.call(bindings?.raw, ...values, $ctx);
9536
9585
  };
9537
9586
  }
9538
9587
  /**