@mintjamsinc/ichigojs 0.1.40 → 0.1.41

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/ichigo.cjs CHANGED
@@ -7816,6 +7816,13 @@
7816
7816
  * This allows retrieving the source path of an object for computed property mapping.
7817
7817
  */
7818
7818
  static proxyPaths = new WeakMap();
7819
+ /**
7820
+ * A Map to store path aliases.
7821
+ * Key: alias path (e.g., "editingNestedStep.steps")
7822
+ * Value: source path (e.g., "routes[0].steps[0].steps")
7823
+ * This allows mapping variable names to their actual source paths for dependency tracking.
7824
+ */
7825
+ static pathAliases = new Map();
7819
7826
  /**
7820
7827
  * Creates a reactive proxy for the given object.
7821
7828
  * The proxy will call the onChange callback whenever a property is modified.
@@ -7982,6 +7989,84 @@
7982
7989
  }
7983
7990
  return this.proxyPaths.get(obj);
7984
7991
  }
7992
+ /**
7993
+ * Registers a path alias.
7994
+ * This is used when a variable is assigned to reference an existing reactive object.
7995
+ * For example, when `editingNestedStep = routes[0].steps[0]`, this creates an alias
7996
+ * so that changes to "routes[0].steps[0].steps" also match "editingNestedStep.steps".
7997
+ *
7998
+ * @param aliasPath The alias path (e.g., "editingNestedStep")
7999
+ * @param sourcePath The source path (e.g., "routes[0].steps[0]")
8000
+ */
8001
+ static registerPathAlias(aliasPath, sourcePath) {
8002
+ if (aliasPath && sourcePath && aliasPath !== sourcePath) {
8003
+ this.pathAliases.set(aliasPath, sourcePath);
8004
+ }
8005
+ }
8006
+ /**
8007
+ * Unregisters a path alias.
8008
+ *
8009
+ * @param aliasPath The alias path to remove
8010
+ */
8011
+ static unregisterPathAlias(aliasPath) {
8012
+ // Remove all aliases that start with the given path
8013
+ for (const key of this.pathAliases.keys()) {
8014
+ if (key === aliasPath || key.startsWith(aliasPath + '.') || key.startsWith(aliasPath + '[')) {
8015
+ this.pathAliases.delete(key);
8016
+ }
8017
+ }
8018
+ }
8019
+ /**
8020
+ * Resolves an alias path to its source path.
8021
+ * Also handles nested paths (e.g., "editingNestedStep.steps" -> "routes[0].steps[0].steps").
8022
+ *
8023
+ * @param aliasPath The alias path to resolve
8024
+ * @returns The source path, or undefined if no alias exists
8025
+ */
8026
+ static resolvePathAlias(aliasPath) {
8027
+ // Direct match
8028
+ if (this.pathAliases.has(aliasPath)) {
8029
+ return this.pathAliases.get(aliasPath);
8030
+ }
8031
+ // Check if this is a nested path of an aliased variable
8032
+ // e.g., "editingNestedStep.steps" when "editingNestedStep" is aliased
8033
+ for (const [alias, source] of this.pathAliases.entries()) {
8034
+ if (aliasPath.startsWith(alias + '.') || aliasPath.startsWith(alias + '[')) {
8035
+ const suffix = aliasPath.substring(alias.length);
8036
+ return source + suffix;
8037
+ }
8038
+ }
8039
+ return undefined;
8040
+ }
8041
+ /**
8042
+ * Checks if a change path matches an identifier, considering path aliases.
8043
+ * For example, if "editingNestedStep" is aliased to "routes[0].steps[0]",
8044
+ * then a change to "routes[0].steps[0].steps" should match "editingNestedStep.steps".
8045
+ *
8046
+ * @param changePath The path that was changed (e.g., "routes[0].steps[0].steps")
8047
+ * @param identifier The identifier to check (e.g., "editingNestedStep.steps")
8048
+ * @returns True if the change path matches the identifier
8049
+ */
8050
+ static doesChangeMatchIdentifier(changePath, identifier) {
8051
+ // Direct match
8052
+ if (changePath === identifier) {
8053
+ return true;
8054
+ }
8055
+ // Check if the identifier has an alias that matches
8056
+ const resolvedIdentifier = this.resolvePathAlias(identifier);
8057
+ if (resolvedIdentifier && changePath === resolvedIdentifier) {
8058
+ return true;
8059
+ }
8060
+ // Check if change path starts with the resolved identifier
8061
+ // (handles cases like array item changes)
8062
+ if (resolvedIdentifier) {
8063
+ if (changePath.startsWith(resolvedIdentifier + '.') ||
8064
+ changePath.startsWith(resolvedIdentifier + '[')) {
8065
+ return true;
8066
+ }
8067
+ }
8068
+ return false;
8069
+ }
7985
8070
  }
7986
8071
 
7987
8072
  // Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
@@ -8049,18 +8134,33 @@
8049
8134
  }
8050
8135
  let newValue = value;
8051
8136
  if (typeof value === 'object' && value !== null) {
8052
- // Wrap objects/arrays with reactive proxy, tracking the root key
8053
- newValue = ReactiveProxy.create(value, (changedPath) => {
8054
- let path = '';
8055
- for (const part of changedPath?.split('.') || []) {
8056
- path = path ? `${path}.${part}` : part;
8057
- this.#logger?.debug(`Binding changed: ${path}`);
8058
- this.#changes.add(path);
8059
- }
8060
- if (!this.#suppressOnChange) {
8061
- this.#onChange?.(changedPath);
8062
- }
8063
- }, key);
8137
+ // Check if the value already has a path (it's an existing reactive proxy reference)
8138
+ const existingPath = ReactiveProxy.getPath(value);
8139
+ if (existingPath) {
8140
+ // Register a path alias so changes to the source path will match this identifier
8141
+ ReactiveProxy.registerPathAlias(key, existingPath);
8142
+ this.#logger?.debug(`Path alias registered: ${key} -> ${existingPath}`);
8143
+ // Keep the existing proxy as-is to preserve reactivity chain
8144
+ newValue = value;
8145
+ }
8146
+ else {
8147
+ // Wrap objects/arrays with reactive proxy, tracking the root key
8148
+ newValue = ReactiveProxy.create(value, (changedPath) => {
8149
+ let path = '';
8150
+ for (const part of changedPath?.split('.') || []) {
8151
+ path = path ? `${path}.${part}` : part;
8152
+ this.#logger?.debug(`Binding changed: ${path}`);
8153
+ this.#changes.add(path);
8154
+ }
8155
+ if (!this.#suppressOnChange) {
8156
+ this.#onChange?.(changedPath);
8157
+ }
8158
+ }, key);
8159
+ }
8160
+ }
8161
+ else if (value === null || value === undefined) {
8162
+ // When setting to null/undefined, unregister any path alias
8163
+ ReactiveProxy.unregisterPathAlias(key);
8064
8164
  }
8065
8165
  const oldValue = Reflect.get(target, key);
8066
8166
  const result = Reflect.set(target, key, newValue);
@@ -8934,7 +9034,7 @@
8934
9034
  }
8935
9035
  // Prepare bindings for each preparer if relevant identifiers have changed
8936
9036
  for (const preparer of this.#directiveManager.bindingsPreparers) {
8937
- const changed = preparer.dependentIdentifiers.some(id => changes.includes(id));
9037
+ const changed = preparer.dependentIdentifiers.some(id => changes.some(change => ReactiveProxy.doesChangeMatchIdentifier(change, id)));
8938
9038
  if (changed) {
8939
9039
  preparer.prepareBindings();
8940
9040
  }
@@ -8943,7 +9043,7 @@
8943
9043
  // Apply DOM updaters from directives, if any
8944
9044
  if (this.#directiveManager?.domUpdaters) {
8945
9045
  for (const updater of this.#directiveManager.domUpdaters) {
8946
- const changed = updater.dependentIdentifiers.some(id => changes.includes(id));
9046
+ const changed = updater.dependentIdentifiers.some(id => changes.some(change => ReactiveProxy.doesChangeMatchIdentifier(change, id)));
8947
9047
  if (changed) {
8948
9048
  updater.applyToDOM();
8949
9049
  }
@@ -8951,7 +9051,7 @@
8951
9051
  }
8952
9052
  // Recursively update dependent virtual nodes
8953
9053
  this.#dependents?.forEach(dependentNode => {
8954
- const changed = dependentNode.dependentIdentifiers.some(id => changes.includes(id));
9054
+ const changed = dependentNode.dependentIdentifiers.some(id => changes.some(change => ReactiveProxy.doesChangeMatchIdentifier(change, id)));
8955
9055
  if (changed) {
8956
9056
  dependentNode.update();
8957
9057
  }
@@ -12210,6 +12310,13 @@
12210
12310
  });
12211
12311
  // Initial rendering
12212
12312
  this.#vNode.update();
12313
+ // Remove v-cloak attributes after mounting
12314
+ // v-cloak is used to hide un-compiled template until the app is ready
12315
+ // Usage: Add CSS rule "[v-cloak] { display: none; }" to hide elements with v-cloak
12316
+ element.querySelectorAll('[v-cloak]').forEach(el => {
12317
+ el.removeAttribute('v-cloak');
12318
+ });
12319
+ element.removeAttribute('v-cloak');
12213
12320
  this.#logger.info('Application mounted.');
12214
12321
  }
12215
12322
  /**