@mintjamsinc/ichigojs 0.1.49 → 0.1.51
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 +87 -10
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +87 -10
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.min.cjs +1 -1
- package/dist/ichigo.umd.js +87 -10
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/dist/types/ichigo/VBindings.d.ts +11 -0
- package/package.json +1 -1
package/dist/ichigo.cjs
CHANGED
|
@@ -7581,9 +7581,17 @@
|
|
|
7581
7581
|
#updateProperty(element, name, value) {
|
|
7582
7582
|
if (value == null && (name === 'value' || name === 'textContent' || name === 'innerHTML')) {
|
|
7583
7583
|
element[name] = '';
|
|
7584
|
+
if (name === 'value') {
|
|
7585
|
+
element._value = null;
|
|
7586
|
+
}
|
|
7584
7587
|
}
|
|
7585
7588
|
else {
|
|
7586
7589
|
element[name] = value;
|
|
7590
|
+
if (name === 'value') {
|
|
7591
|
+
// Store the original typed value so that v-model on radio buttons
|
|
7592
|
+
// can preserve the type (e.g., boolean false instead of string "false").
|
|
7593
|
+
element._value = value;
|
|
7594
|
+
}
|
|
7587
7595
|
}
|
|
7588
7596
|
}
|
|
7589
7597
|
/**
|
|
@@ -8119,6 +8127,12 @@
|
|
|
8119
8127
|
* Flag to suppress onChange callbacks temporarily.
|
|
8120
8128
|
*/
|
|
8121
8129
|
#suppressOnChange = false;
|
|
8130
|
+
/**
|
|
8131
|
+
* Per-instance path aliases. Maps local variable names to their reactive source paths.
|
|
8132
|
+
* Scoped here instead of the global ReactiveProxy map so that v-for items each maintain
|
|
8133
|
+
* their own alias (e.g. "file" -> "files[0]") without overwriting each other.
|
|
8134
|
+
*/
|
|
8135
|
+
#localAliases = new Map();
|
|
8122
8136
|
/**
|
|
8123
8137
|
* Creates a new instance of VBindings.
|
|
8124
8138
|
* @param parent The parent bindings, if any.
|
|
@@ -8153,7 +8167,7 @@
|
|
|
8153
8167
|
const existingPath = ReactiveProxy.getPath(value);
|
|
8154
8168
|
if (existingPath) {
|
|
8155
8169
|
// Register a path alias so changes to the source path will match this identifier
|
|
8156
|
-
|
|
8170
|
+
this.#localAliases.set(key, existingPath);
|
|
8157
8171
|
this.#logger?.debug(`Path alias registered: ${key} -> ${existingPath}`);
|
|
8158
8172
|
// Keep the existing proxy as-is to preserve reactivity chain
|
|
8159
8173
|
newValue = value;
|
|
@@ -8168,7 +8182,7 @@
|
|
|
8168
8182
|
const propPath = ReactiveProxy.getPath(propValue);
|
|
8169
8183
|
if (propPath) {
|
|
8170
8184
|
// Register alias: key.propKey -> propPath
|
|
8171
|
-
|
|
8185
|
+
this.#localAliases.set(`${key}.${propKey}`, propPath);
|
|
8172
8186
|
this.#logger?.debug(`Property path alias registered: ${key}.${propKey} -> ${propPath}`);
|
|
8173
8187
|
}
|
|
8174
8188
|
}
|
|
@@ -8189,8 +8203,14 @@
|
|
|
8189
8203
|
}
|
|
8190
8204
|
}
|
|
8191
8205
|
else if (value === null || value === undefined) {
|
|
8192
|
-
// When setting to null/undefined,
|
|
8193
|
-
|
|
8206
|
+
// When setting to null/undefined, remove local aliases for this key and nested paths
|
|
8207
|
+
for (const aliasKey of [...this.#localAliases.keys()]) {
|
|
8208
|
+
if (aliasKey === key ||
|
|
8209
|
+
aliasKey.startsWith(key + ".") ||
|
|
8210
|
+
aliasKey.startsWith(key + "[")) {
|
|
8211
|
+
this.#localAliases.delete(aliasKey);
|
|
8212
|
+
}
|
|
8213
|
+
}
|
|
8194
8214
|
}
|
|
8195
8215
|
const oldValue = Reflect.get(target, key);
|
|
8196
8216
|
const result = Reflect.set(target, key, newValue);
|
|
@@ -8327,6 +8347,54 @@
|
|
|
8327
8347
|
markChanged(key) {
|
|
8328
8348
|
this.#changes.add(key);
|
|
8329
8349
|
}
|
|
8350
|
+
/**
|
|
8351
|
+
* Resolves a local path alias for the given identifier by walking up the bindings chain.
|
|
8352
|
+
* Returns the resolved source path, or undefined if no alias is found.
|
|
8353
|
+
*/
|
|
8354
|
+
resolveAlias(identifier) {
|
|
8355
|
+
// Direct match in local aliases
|
|
8356
|
+
if (this.#localAliases.has(identifier)) {
|
|
8357
|
+
return this.#localAliases.get(identifier);
|
|
8358
|
+
}
|
|
8359
|
+
// Check if this is a nested path of a locally aliased variable (e.g. "file.isModified")
|
|
8360
|
+
for (const [alias, source] of this.#localAliases.entries()) {
|
|
8361
|
+
if (identifier.startsWith(alias + '.') || identifier.startsWith(alias + '[')) {
|
|
8362
|
+
return source + identifier.substring(alias.length);
|
|
8363
|
+
}
|
|
8364
|
+
}
|
|
8365
|
+
// Walk up the parent chain
|
|
8366
|
+
return this.#parent?.resolveAlias(identifier);
|
|
8367
|
+
}
|
|
8368
|
+
/**
|
|
8369
|
+
* Checks whether a reactive change path matches a given identifier, taking local path
|
|
8370
|
+
* aliases into account. Falls back to ReactiveProxy.doesChangeMatchIdentifier for
|
|
8371
|
+
* global aliases (computed properties etc.).
|
|
8372
|
+
*/
|
|
8373
|
+
doesChangeMatchIdentifier(changePath, identifier) {
|
|
8374
|
+
// Direct match
|
|
8375
|
+
if (changePath === identifier) {
|
|
8376
|
+
return true;
|
|
8377
|
+
}
|
|
8378
|
+
// Resolve via local (scoped) alias chain
|
|
8379
|
+
const resolved = this.resolveAlias(identifier);
|
|
8380
|
+
if (resolved) {
|
|
8381
|
+
if (changePath === resolved) {
|
|
8382
|
+
return true;
|
|
8383
|
+
}
|
|
8384
|
+
// changePath is a descendant of resolved (e.g. "files[0].isModified" for resolved "files[0]")
|
|
8385
|
+
if (changePath.startsWith(resolved + '.') || changePath.startsWith(resolved + '[')) {
|
|
8386
|
+
return true;
|
|
8387
|
+
}
|
|
8388
|
+
// changePath is an ancestor of resolved (e.g. "files" for resolved "files[0].isModified")
|
|
8389
|
+
// This handles raw objects: when the parent collection is replaced/spliced, all item
|
|
8390
|
+
// properties are considered changed.
|
|
8391
|
+
if (resolved.startsWith(changePath + '.') || resolved.startsWith(changePath + '[')) {
|
|
8392
|
+
return true;
|
|
8393
|
+
}
|
|
8394
|
+
}
|
|
8395
|
+
// Fall back to global alias resolution (computed properties, etc.)
|
|
8396
|
+
return ReactiveProxy.doesChangeMatchIdentifier(changePath, identifier);
|
|
8397
|
+
}
|
|
8330
8398
|
}
|
|
8331
8399
|
|
|
8332
8400
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
|
@@ -9043,7 +9111,7 @@
|
|
|
9043
9111
|
if (this.#nodeType === Node.TEXT_NODE && this.#textEvaluator) {
|
|
9044
9112
|
// If this is a text node with a text evaluator, update its content if needed
|
|
9045
9113
|
// Check if any of the identifiers are in the changed identifiers (considering path aliases)
|
|
9046
|
-
const changed = this.#textEvaluator.identifiers.some(id => changes.some(change =>
|
|
9114
|
+
const changed = this.#textEvaluator.identifiers.some(id => changes.some(change => this.bindings.doesChangeMatchIdentifier(change, id)));
|
|
9047
9115
|
// If the text node has changed, update its content
|
|
9048
9116
|
if (changed) {
|
|
9049
9117
|
const text = this.#node;
|
|
@@ -9066,7 +9134,7 @@
|
|
|
9066
9134
|
}
|
|
9067
9135
|
// Prepare bindings for each preparer if relevant identifiers have changed
|
|
9068
9136
|
for (const preparer of this.#directiveManager.bindingsPreparers) {
|
|
9069
|
-
const changed = preparer.dependentIdentifiers.some(id => changes.some(change =>
|
|
9137
|
+
const changed = preparer.dependentIdentifiers.some(id => changes.some(change => this.bindings.doesChangeMatchIdentifier(change, id)));
|
|
9070
9138
|
if (changed) {
|
|
9071
9139
|
preparer.prepareBindings();
|
|
9072
9140
|
}
|
|
@@ -9075,7 +9143,7 @@
|
|
|
9075
9143
|
// Apply DOM updaters from directives, if any
|
|
9076
9144
|
if (this.#directiveManager?.domUpdaters) {
|
|
9077
9145
|
for (const updater of this.#directiveManager.domUpdaters) {
|
|
9078
|
-
const changed = updater.dependentIdentifiers.some(id => changes.some(change =>
|
|
9146
|
+
const changed = updater.dependentIdentifiers.some(id => changes.some(change => this.bindings.doesChangeMatchIdentifier(change, id)));
|
|
9079
9147
|
if (changed) {
|
|
9080
9148
|
updater.applyToDOM();
|
|
9081
9149
|
}
|
|
@@ -9083,7 +9151,7 @@
|
|
|
9083
9151
|
}
|
|
9084
9152
|
// Recursively update dependent virtual nodes
|
|
9085
9153
|
this.#dependents?.forEach(dependentNode => {
|
|
9086
|
-
const changed = dependentNode.dependentIdentifiers.some(id => changes.some(change =>
|
|
9154
|
+
const changed = dependentNode.dependentIdentifiers.some(id => changes.some(change => dependentNode.bindings.doesChangeMatchIdentifier(change, id)));
|
|
9087
9155
|
if (changed) {
|
|
9088
9156
|
dependentNode.update();
|
|
9089
9157
|
}
|
|
@@ -10771,7 +10839,12 @@
|
|
|
10771
10839
|
element.checked = !!value;
|
|
10772
10840
|
}
|
|
10773
10841
|
else if (element.type === 'radio') {
|
|
10774
|
-
|
|
10842
|
+
// Prefer the original typed value stored by VBindDirective (:value binding)
|
|
10843
|
+
// to avoid type coercion issues (e.g., boolean false vs string "false").
|
|
10844
|
+
const radioValue = element._value !== undefined
|
|
10845
|
+
? element._value
|
|
10846
|
+
: element.value;
|
|
10847
|
+
element.checked = radioValue === value;
|
|
10775
10848
|
}
|
|
10776
10849
|
else {
|
|
10777
10850
|
element.value = value ?? '';
|
|
@@ -10799,7 +10872,11 @@
|
|
|
10799
10872
|
newValue = target.checked;
|
|
10800
10873
|
}
|
|
10801
10874
|
else if (target.type === 'radio') {
|
|
10802
|
-
|
|
10875
|
+
// Prefer the original typed value stored by VBindDirective (:value binding)
|
|
10876
|
+
// to preserve the type on write-back (e.g., boolean false, number 0).
|
|
10877
|
+
newValue = target._value !== undefined
|
|
10878
|
+
? target._value
|
|
10879
|
+
: target.value;
|
|
10803
10880
|
}
|
|
10804
10881
|
else {
|
|
10805
10882
|
newValue = target.value;
|