@mintjamsinc/ichigojs 0.1.70 → 0.1.72
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/README.md +4 -0
- package/dist/ichigo.cjs +80 -35
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +80 -35
- 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 +80 -35
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1021,6 +1021,10 @@ MIT License - Copyright (c) 2025 MintJams Inc.
|
|
|
1021
1021
|
|
|
1022
1022
|
Inspired by [Vue.js](https://vuejs.org/) - A progressive JavaScript framework.
|
|
1023
1023
|
|
|
1024
|
+
## Trademarks
|
|
1025
|
+
|
|
1026
|
+
All trademarks are the property of their respective owners.
|
|
1027
|
+
|
|
1024
1028
|
---
|
|
1025
1029
|
|
|
1026
1030
|
Built with ❤️ by [MintJams Inc.](https://github.com/mintjamsinc)
|
package/dist/ichigo.cjs
CHANGED
|
@@ -6945,42 +6945,70 @@
|
|
|
6945
6945
|
functionDependencies[funcName] = [];
|
|
6946
6946
|
}
|
|
6947
6947
|
}
|
|
6948
|
-
// Second pass:
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6948
|
+
// Second pass: resolve each function's transitive reactive dependencies.
|
|
6949
|
+
//
|
|
6950
|
+
// A function's direct dependency list mixes two kinds of identifiers: references to other
|
|
6951
|
+
// functions (call edges) and references to reactive data properties (the values we actually
|
|
6952
|
+
// care about). We want, for every function, the full set of reactive properties reachable by
|
|
6953
|
+
// following call edges to any depth.
|
|
6954
|
+
//
|
|
6955
|
+
// Functions are free to reference each other cyclically — a poller that reschedules itself
|
|
6956
|
+
// (`scheduleOperationPoll` -> `pollOperation` -> `scheduleOperationPoll`), a pair of mutually
|
|
6957
|
+
// recursive helpers, or any state machine. This is valid JavaScript, so the resolver must not
|
|
6958
|
+
// treat it as an error. Every function in a cycle (more precisely, a strongly connected
|
|
6959
|
+
// component) is reachable from the others, so they all share the same transitive dependency
|
|
6960
|
+
// set: the union of every member's direct reactive dependencies.
|
|
6961
|
+
//
|
|
6962
|
+
// A depth-first walk that bails out on back-edges cannot compute that correctly — it drops the
|
|
6963
|
+
// dependencies contributed around the cycle and caches incomplete, traversal-order-dependent
|
|
6964
|
+
// results, which would silently break reactivity for any computed that reads reactive data
|
|
6965
|
+
// through a cyclic method. We instead split each function's direct dependencies into reactive
|
|
6966
|
+
// properties and call edges, then propagate reactive properties along call edges until the sets
|
|
6967
|
+
// stop growing (a fixpoint). This converges regardless of cycles and yields the exact transitive
|
|
6968
|
+
// closure for every function, including those participating in a cycle.
|
|
6969
|
+
const directReactive = {};
|
|
6970
|
+
const callEdges = {};
|
|
6971
|
+
for (const funcName of Object.keys(functions)) {
|
|
6972
|
+
const reactive = new Set();
|
|
6973
|
+
const edges = [];
|
|
6974
|
+
for (const dep of functionDependencies[funcName] || []) {
|
|
6965
6975
|
if (dep === funcName)
|
|
6966
|
-
continue; // Skip self-references
|
|
6976
|
+
continue; // Skip self-references.
|
|
6967
6977
|
if (functions[dep]) {
|
|
6968
|
-
//
|
|
6969
|
-
const subDependencies = resolveDependencies(dep);
|
|
6970
|
-
subDependencies.forEach(subDep => allDependencies.add(subDep));
|
|
6978
|
+
edges.push(dep); // Call edge to another function.
|
|
6971
6979
|
}
|
|
6972
6980
|
else {
|
|
6973
|
-
//
|
|
6974
|
-
allDependencies.add(dep);
|
|
6981
|
+
reactive.add(dep); // Reactive data property (terminal dependency).
|
|
6975
6982
|
}
|
|
6976
6983
|
}
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
//
|
|
6984
|
+
directReactive[funcName] = reactive;
|
|
6985
|
+
callEdges[funcName] = edges;
|
|
6986
|
+
}
|
|
6987
|
+
// Seed each function with its own direct reactive dependencies, then propagate along call edges
|
|
6988
|
+
// until no set changes. Each pass can only add properties, and the universe of properties is
|
|
6989
|
+
// finite, so the loop is guaranteed to terminate.
|
|
6990
|
+
const resolved = {};
|
|
6982
6991
|
for (const funcName of Object.keys(functions)) {
|
|
6983
|
-
|
|
6992
|
+
resolved[funcName] = new Set(directReactive[funcName]);
|
|
6993
|
+
}
|
|
6994
|
+
let changed = true;
|
|
6995
|
+
while (changed) {
|
|
6996
|
+
changed = false;
|
|
6997
|
+
for (const funcName of Object.keys(functions)) {
|
|
6998
|
+
const target = resolved[funcName];
|
|
6999
|
+
for (const edge of callEdges[funcName]) {
|
|
7000
|
+
for (const dep of resolved[edge]) {
|
|
7001
|
+
if (!target.has(dep)) {
|
|
7002
|
+
target.add(dep);
|
|
7003
|
+
changed = true;
|
|
7004
|
+
}
|
|
7005
|
+
}
|
|
7006
|
+
}
|
|
7007
|
+
}
|
|
7008
|
+
}
|
|
7009
|
+
const resolvedDependencies = {};
|
|
7010
|
+
for (const funcName of Object.keys(functions)) {
|
|
7011
|
+
resolvedDependencies[funcName] = Array.from(resolved[funcName]);
|
|
6984
7012
|
}
|
|
6985
7013
|
return resolvedDependencies;
|
|
6986
7014
|
}
|
|
@@ -13757,7 +13785,8 @@
|
|
|
13757
13785
|
this.#logManager = new VLogManager(options.logLevel);
|
|
13758
13786
|
this.#logger = this.#logManager.getLogger('VApplication');
|
|
13759
13787
|
// Analyze function dependencies
|
|
13760
|
-
|
|
13788
|
+
const methods = (options.methods || {});
|
|
13789
|
+
this.#functionDependencies = ExpressionUtils.analyzeFunctionDependencies(methods);
|
|
13761
13790
|
// Analyze computed dependencies based on getter functions only.
|
|
13762
13791
|
// Writable computeds (defined as { get, set }) contribute their getter for dependency analysis.
|
|
13763
13792
|
const computedGetters = {};
|
|
@@ -13766,7 +13795,23 @@
|
|
|
13766
13795
|
computedGetters[key] = VApplication.#getComputedGetter(def);
|
|
13767
13796
|
}
|
|
13768
13797
|
}
|
|
13769
|
-
|
|
13798
|
+
// Resolve computed dependencies against BOTH the computed getters AND the methods, so a
|
|
13799
|
+
// computed that delegates to a method inherits that method's reactive dependencies. A
|
|
13800
|
+
// computed whose only reactive reads happen inside a called method (e.g. a reactive i18n
|
|
13801
|
+
// `t()` helper that reads `this.localization`) would otherwise never be invalidated, leaving
|
|
13802
|
+
// its binding stale on a dependency change. Analyzing the combined set flattens every
|
|
13803
|
+
// computed→method (and computed→computed, method→method) edge down to the underlying
|
|
13804
|
+
// reactive paths — the same expansion that template-expression analysis already performs for
|
|
13805
|
+
// method calls (see ExpressionUtils.extractIdentifiers). We then keep only the computed
|
|
13806
|
+
// entries, since #computedDependencies must be keyed by computed name alone.
|
|
13807
|
+
const combinedDependencies = ExpressionUtils.analyzeFunctionDependencies({
|
|
13808
|
+
...methods,
|
|
13809
|
+
...computedGetters,
|
|
13810
|
+
});
|
|
13811
|
+
this.#computedDependencies = {};
|
|
13812
|
+
for (const key of Object.keys(computedGetters)) {
|
|
13813
|
+
this.#computedDependencies[key] = combinedDependencies[key] || [];
|
|
13814
|
+
}
|
|
13770
13815
|
// Initialize watcher manager
|
|
13771
13816
|
this.#watcher = new VWatcher(this.#logger);
|
|
13772
13817
|
// Initialize bindings from data, computed, and methods
|
|
@@ -14120,10 +14165,10 @@
|
|
|
14120
14165
|
}
|
|
14121
14166
|
/**
|
|
14122
14167
|
* Marks computed properties as dirty (pull-based invalidation) when a dependency changes.
|
|
14123
|
-
* Uses the statically analyzed dependency graph; because computed→computed
|
|
14124
|
-
* flattened to their underlying reactive paths during analysis, a single change
|
|
14125
|
-
* transitively dependent computed dirty in one pass. The actual recomputation is
|
|
14126
|
-
* the value is read (see #recomputeOne).
|
|
14168
|
+
* Uses the statically analyzed dependency graph; because computed→computed and computed→method
|
|
14169
|
+
* dependencies are flattened to their underlying reactive paths during analysis, a single change
|
|
14170
|
+
* marks every transitively dependent computed dirty in one pass. The actual recomputation is
|
|
14171
|
+
* deferred until the value is read (see #recomputeOne).
|
|
14127
14172
|
* @param identifier The changed identifier reported by the bindings change tracker.
|
|
14128
14173
|
*/
|
|
14129
14174
|
#markDirtyComputeds(identifier) {
|