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 CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "lume-js",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "main": "src/index.js",
5
5
  "type": "module",
6
6
  "scripts": {
7
- "dev": "vite examples",
7
+ "dev": "vite",
8
8
  "build": "echo 'No build step yet, zero-runtime already!'"
9
9
  },
10
10
  "files": [
@@ -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,2 @@
1
+ export { computed } from "./computed.js";
2
+ export { watch } from "./watch.js";
@@ -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
+ }
@@ -37,7 +37,7 @@ export function bindDom(root, store) {
37
37
  }
38
38
 
39
39
  // Subscribe once
40
- target.$subscribe(lastKey, val => {
40
+ target.subscribe(lastKey, val => {
41
41
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") el.value = val;
42
42
  else el.textContent = val;
43
43
  });
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
- * - $subscribe for listening to key changes
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.$subscribe("count", val => console.log(val));
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 $subscribe method
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.$subscribe = (key, fn) => {
50
+ proxy.subscribe = (key, fn) => {
51
51
  if (!listeners[key]) listeners[key] = [];
52
52
  listeners[key].push(fn);
53
53
  fn(proxy[key]); // initialize