lume-js 0.2.0 → 0.2.1
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/package.json +2 -2
- package/src/addons/computed.js +38 -0
- package/src/addons/index.js +2 -0
- package/src/addons/watch.js +12 -0
- package/src/core/bindDom.js +1 -1
- package/src/core/state.js +4 -4
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* computed - creates a derived value based on state
|
|
3
|
+
* @param {Function} fn - function that computes value from state
|
|
4
|
+
* @returns {Object} - { get: () => value, recompute: () => void, subscribe: (cb) => unsubscribe }
|
|
5
|
+
*/
|
|
6
|
+
export function computed(fn) {
|
|
7
|
+
let value;
|
|
8
|
+
let dirty = true;
|
|
9
|
+
const subscribers = new Set();
|
|
10
|
+
|
|
11
|
+
const recalc = () => {
|
|
12
|
+
try {
|
|
13
|
+
value = fn();
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error("[computed] Error computing value:", err);
|
|
16
|
+
value = undefined;
|
|
17
|
+
}
|
|
18
|
+
dirty = false;
|
|
19
|
+
subscribers.forEach(cb => cb(value));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
get: () => {
|
|
24
|
+
if (dirty) recalc();
|
|
25
|
+
return value;
|
|
26
|
+
},
|
|
27
|
+
recompute: () => {
|
|
28
|
+
dirty = true;
|
|
29
|
+
recalc();
|
|
30
|
+
},
|
|
31
|
+
subscribe: cb => {
|
|
32
|
+
subscribers.add(cb);
|
|
33
|
+
// Immediately notify subscriber with current value
|
|
34
|
+
if (!dirty) cb(value);
|
|
35
|
+
return () => subscribers.delete(cb); // unsubscribe function
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* watch - observes changes to a state key and triggers callback
|
|
3
|
+
* @param {Object} store - reactive store created with state()
|
|
4
|
+
* @param {string} key - key in store to watch
|
|
5
|
+
* @param {Function} callback - called with new value
|
|
6
|
+
*/
|
|
7
|
+
export function watch(store, key, callback) {
|
|
8
|
+
if (!store.subscribe) {
|
|
9
|
+
throw new Error("store must be created with state()");
|
|
10
|
+
}
|
|
11
|
+
store.subscribe(key, callback);
|
|
12
|
+
}
|
package/src/core/bindDom.js
CHANGED
package/src/core/state.js
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
* Features:
|
|
7
7
|
* - Lightweight and Go-style
|
|
8
8
|
* - Explicit nested states
|
|
9
|
-
* -
|
|
9
|
+
* - subscribe for listening to key changes
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
12
|
* import { state } from "lume-js";
|
|
13
13
|
* const store = state({ count: 0 });
|
|
14
|
-
* store
|
|
14
|
+
* store.subscribe("count", val => console.log(val));
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Creates a reactive state object.
|
|
20
20
|
*
|
|
21
21
|
* @param {Object} obj - Initial state object
|
|
22
|
-
* @returns {Proxy} Reactive proxy with
|
|
22
|
+
* @returns {Proxy} Reactive proxy with subscribe method
|
|
23
23
|
*/
|
|
24
24
|
export function state(obj) {
|
|
25
25
|
const listeners = {};
|
|
@@ -47,7 +47,7 @@ export function state(obj) {
|
|
|
47
47
|
* @param {string} key
|
|
48
48
|
* @param {function} fn
|
|
49
49
|
*/
|
|
50
|
-
proxy
|
|
50
|
+
proxy.subscribe = (key, fn) => {
|
|
51
51
|
if (!listeners[key]) listeners[key] = [];
|
|
52
52
|
listeners[key].push(fn);
|
|
53
53
|
fn(proxy[key]); // initialize
|