@esmj/signals 0.0.2 → 0.0.3

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/index.d.mts CHANGED
@@ -25,11 +25,18 @@ class Watcher extends Observable {
25
25
 
26
26
  this.pipe((observable) => {
27
27
  const originalSubscribe = observable.subscribe.bind(observable);
28
+ const originalUnsubscribe = observable.unsubscribe.bind(observable);
29
+
28
30
  observable.subscribe = (observer) => {
29
31
  originalSubscribe(observer);
30
32
  this.#pendings.add(observer);
31
33
  };
32
34
 
35
+ observable.unsubscribe = (observer) => {
36
+ originalUnsubscribe(observer);
37
+ this.#pendings.delete(observer);
38
+ };
39
+
33
40
  return observable;
34
41
  });
35
42
  }
@@ -38,6 +45,8 @@ class Watcher extends Observable {
38
45
  if (typeof signal.next !== 'function') {
39
46
  signal.next = () => {
40
47
  return untrack(() => {
48
+ this.#pendings.add(signal);
49
+
41
50
  this.#notify();
42
51
  });
43
52
  };
@@ -52,6 +61,8 @@ class Watcher extends Observable {
52
61
  const originalNext = signal.next.bind(signal);
53
62
  signal.next = () => {
54
63
  return untrack(() => {
64
+ this.#pendings.add(signal);
65
+
55
66
  originalNext();
56
67
 
57
68
  this.#notify();
@@ -64,7 +75,20 @@ class Watcher extends Observable {
64
75
  }
65
76
 
66
77
  getPending() {
67
- return Array.from(this.#pendings);
78
+ const pendings = Array.from(this.#pendings).map((pending) => {
79
+ const originalGet = pending.get.bind(pending);
80
+
81
+ pending.get = () => {
82
+ return untrack(() => {
83
+ this.#pendings.delete(pending);
84
+ return originalGet();
85
+ });
86
+ };
87
+
88
+ return pending;
89
+ });
90
+
91
+ return pendings;
68
92
  }
69
93
 
70
94
  unwatch(signal) {
@@ -84,9 +108,7 @@ createWatcher(() => {
84
108
  // TODO performance improvement
85
109
  setTimeout(() => {
86
110
  getPending().forEach((pending) => {
87
- untrack(() => {
88
- pending.get();
89
- });
111
+ pending.get();
90
112
  });
91
113
  }, 0);
92
114
  });
@@ -117,6 +139,8 @@ class Computed extends Observer {
117
139
  this.#callback = callback;
118
140
  this.#options = options;
119
141
 
142
+ this.debug = options?.debug;
143
+
120
144
  this.get = this.get.bind(this);
121
145
  }
122
146
 
@@ -208,7 +232,7 @@ function computed(callback, options) {
208
232
  return instance;
209
233
  }
210
234
 
211
- function effect(callback) {
235
+ function effect(callback, options) {
212
236
  let destructor;
213
237
 
214
238
  let c = computed(
@@ -216,7 +240,7 @@ function effect(callback) {
216
240
  destructor?.();
217
241
  destructor = callback();
218
242
  },
219
- { equals: () => false },
243
+ { equals: () => false, debug: 'effect', ...options },
220
244
  );
221
245
  c.get();
222
246
 
package/dist/index.d.ts CHANGED
@@ -25,11 +25,18 @@ class Watcher extends Observable {
25
25
 
26
26
  this.pipe((observable) => {
27
27
  const originalSubscribe = observable.subscribe.bind(observable);
28
+ const originalUnsubscribe = observable.unsubscribe.bind(observable);
29
+
28
30
  observable.subscribe = (observer) => {
29
31
  originalSubscribe(observer);
30
32
  this.#pendings.add(observer);
31
33
  };
32
34
 
35
+ observable.unsubscribe = (observer) => {
36
+ originalUnsubscribe(observer);
37
+ this.#pendings.delete(observer);
38
+ };
39
+
33
40
  return observable;
34
41
  });
35
42
  }
@@ -38,6 +45,8 @@ class Watcher extends Observable {
38
45
  if (typeof signal.next !== 'function') {
39
46
  signal.next = () => {
40
47
  return untrack(() => {
48
+ this.#pendings.add(signal);
49
+
41
50
  this.#notify();
42
51
  });
43
52
  };
@@ -52,6 +61,8 @@ class Watcher extends Observable {
52
61
  const originalNext = signal.next.bind(signal);
53
62
  signal.next = () => {
54
63
  return untrack(() => {
64
+ this.#pendings.add(signal);
65
+
55
66
  originalNext();
56
67
 
57
68
  this.#notify();
@@ -64,7 +75,20 @@ class Watcher extends Observable {
64
75
  }
65
76
 
66
77
  getPending() {
67
- return Array.from(this.#pendings);
78
+ const pendings = Array.from(this.#pendings).map((pending) => {
79
+ const originalGet = pending.get.bind(pending);
80
+
81
+ pending.get = () => {
82
+ return untrack(() => {
83
+ this.#pendings.delete(pending);
84
+ return originalGet();
85
+ });
86
+ };
87
+
88
+ return pending;
89
+ });
90
+
91
+ return pendings;
68
92
  }
69
93
 
70
94
  unwatch(signal) {
@@ -84,9 +108,7 @@ createWatcher(() => {
84
108
  // TODO performance improvement
85
109
  setTimeout(() => {
86
110
  getPending().forEach((pending) => {
87
- untrack(() => {
88
- pending.get();
89
- });
111
+ pending.get();
90
112
  });
91
113
  }, 0);
92
114
  });
@@ -117,6 +139,8 @@ class Computed extends Observer {
117
139
  this.#callback = callback;
118
140
  this.#options = options;
119
141
 
142
+ this.debug = options?.debug;
143
+
120
144
  this.get = this.get.bind(this);
121
145
  }
122
146
 
@@ -208,7 +232,7 @@ function computed(callback, options) {
208
232
  return instance;
209
233
  }
210
234
 
211
- function effect(callback) {
235
+ function effect(callback, options) {
212
236
  let destructor;
213
237
 
214
238
  let c = computed(
@@ -216,7 +240,7 @@ function effect(callback) {
216
240
  destructor?.();
217
241
  destructor = callback();
218
242
  },
219
- { equals: () => false },
243
+ { equals: () => false, debug: 'effect', ...options },
220
244
  );
221
245
  c.get();
222
246
 
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var observable=require('@esmj/observable');var r=null;function h(n){let t=r;r=null;let e=n();return r=t,e}var x=Symbol("internal observable"),c=Symbol("original next"),f=class extends observable.Observable{#t=new Set;#e=null;constructor(t){super(),this.#e=t,this.pipe(e=>{let s=e.subscribe.bind(e);return e.subscribe=i=>{s(i),this.#t.add(i);},e});}watch(t){if(typeof t.next!="function"&&(t.next=()=>h(()=>{this.#e();}),t.next[c]=void 0),t instanceof o&&t.next[c]===void 0){let e=t.next.bind(t);t.next=()=>h(()=>{e(),this.#e();}),t.next[c]=e;}return this.subscribe(t)}getPending(){return Array.from(this.#t)}unwatch(t){return t.next=t.next[c],this.unsubscribe(t)}},u=null;function w(n){u=new f(n);}w(()=>{setTimeout(()=>{y().forEach(n=>{h(()=>{n.get();});});},0);});function y(){return u.getPending()}function g(n){return u.watch(n)}function m(n){return u.unwatch(n)}var o=class extends observable.Observer{#t=!0;#e=null;#n=null;#r=this.#u();#s=null;#i=null;constructor(t,e){super(),this.#s=t,this.#i=e,this.get=this.get.bind(this);}#o(){Array.from(this.#r.dependencies.values()).forEach(({unsubscribe:t})=>{t();}),this.#r.dependencies.clear();}#u(){return {dependencies:new Map,observer:this}}#h(){this.#e=r,r=this.#r;}#f(){r=this.#e;}next(){this.#t=!0,this.#n[x].next();}get(){return this.#n||(this.#n=d(this.#c(),this.#i)),this.#t&&this.#c(),this.#n.get()}#c(){this.#t=!1,this.#o(),this.#h();let t;try{t=this.#s();}catch(e){t=e;}if(this.#f(),t instanceof Promise&&(t=t.then(e=>e).catch(e=>{throw e})),this.#n&&this.#n.set(t),t instanceof Error)throw t;return t}};function E(n,t){return new o(n,t)}function P(n){let t,e=E(()=>{t?.(),t=n();},{equals:()=>!1});return e.get(),g(e),()=>{t?.(),m(e);}}function d(n,t={}){let e=t?.equals??Object.is,s=new observable.Observable;function i(){if(typeof r=="object"&&r!==null&&r.dependencies.set(s,s.subscribe(r.observer)),n instanceof Error)throw n;return n}function b(l){return e(n,l)||(n=l,s.next()),n}return {get:i,set:b,[x]:s}}var S=d;exports.computed=E;exports.createSignal=d;exports.createWatcher=w;exports.effect=P;exports.getPending=y;exports.state=S;exports.untrack=h;exports.unwatch=m;exports.watch=g;
1
+ 'use strict';var observable=require('@esmj/observable');var s=null;function f(n){let t=s;s=null;let e=n();return s=t,e}var x=Symbol("internal observable"),c=Symbol("original next"),d=class extends observable.Observable{#t=new Set;#e=null;constructor(t){super(),this.#e=t,this.pipe(e=>{let r=e.subscribe.bind(e),h=e.unsubscribe.bind(e);return e.subscribe=i=>{r(i),this.#t.add(i);},e.unsubscribe=i=>{h(i),this.#t.delete(i);},e});}watch(t){if(typeof t.next!="function"&&(t.next=()=>f(()=>{this.#t.add(t),this.#e();}),t.next[c]=void 0),t instanceof u&&t.next[c]===void 0){let e=t.next.bind(t);t.next=()=>f(()=>{this.#t.add(t),e(),this.#e();}),t.next[c]=e;}return this.subscribe(t)}getPending(){return Array.from(this.#t).map(e=>{let r=e.get.bind(e);return e.get=()=>f(()=>(this.#t.delete(e),r())),e})}unwatch(t){return t.next=t.next[c],this.unsubscribe(t)}},o=null;function w(n){o=new d(n);}w(()=>{setTimeout(()=>{g().forEach(n=>{n.get();});},0);});function g(){return o.getPending()}function m(n){return o.watch(n)}function y(n){return o.unwatch(n)}var u=class extends observable.Observer{#t=!0;#e=null;#n=null;#r=this.#o();#s=null;#i=null;constructor(t,e){super(),this.#s=t,this.#i=e,this.debug=e?.debug,this.get=this.get.bind(this);}#u(){Array.from(this.#r.dependencies.values()).forEach(({unsubscribe:t})=>{t();}),this.#r.dependencies.clear();}#o(){return {dependencies:new Map,observer:this}}#h(){this.#e=s,s=this.#r;}#f(){s=this.#e;}next(){this.#t=!0,this.#n[x].next();}get(){return this.#n||(this.#n=b(this.#c(),this.#i)),this.#t&&this.#c(),this.#n.get()}#c(){this.#t=!1,this.#u(),this.#h();let t;try{t=this.#s();}catch(e){t=e;}if(this.#f(),t instanceof Promise&&(t=t.then(e=>e).catch(e=>{throw e})),this.#n&&this.#n.set(t),t instanceof Error)throw t;return t}};function E(n,t){return new u(n,t)}function P(n,t){let e,r=E(()=>{e?.(),e=n();},{equals:()=>!1,debug:"effect",...t});return r.get(),m(r),()=>{e?.(),y(r);}}function b(n,t={}){let e=t?.equals??Object.is,r=new observable.Observable;function h(){if(typeof s=="object"&&s!==null&&s.dependencies.set(r,r.subscribe(s.observer)),n instanceof Error)throw n;return n}function i(a){return e(n,a)||(n=a,r.next()),n}return {get:h,set:i,[x]:r}}var S=b;exports.computed=E;exports.createSignal=b;exports.createWatcher=w;exports.effect=P;exports.getPending=g;exports.state=S;exports.untrack=f;exports.unwatch=y;exports.watch=m;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {Observable,Observer}from'@esmj/observable';var r=null;function h(n){let t=r;r=null;let e=n();return r=t,e}var x=Symbol("internal observable"),c=Symbol("original next"),f=class extends Observable{#t=new Set;#e=null;constructor(t){super(),this.#e=t,this.pipe(e=>{let s=e.subscribe.bind(e);return e.subscribe=i=>{s(i),this.#t.add(i);},e});}watch(t){if(typeof t.next!="function"&&(t.next=()=>h(()=>{this.#e();}),t.next[c]=void 0),t instanceof o&&t.next[c]===void 0){let e=t.next.bind(t);t.next=()=>h(()=>{e(),this.#e();}),t.next[c]=e;}return this.subscribe(t)}getPending(){return Array.from(this.#t)}unwatch(t){return t.next=t.next[c],this.unsubscribe(t)}},u=null;function w(n){u=new f(n);}w(()=>{setTimeout(()=>{y().forEach(n=>{h(()=>{n.get();});});},0);});function y(){return u.getPending()}function g(n){return u.watch(n)}function m(n){return u.unwatch(n)}var o=class extends Observer{#t=!0;#e=null;#n=null;#r=this.#u();#s=null;#i=null;constructor(t,e){super(),this.#s=t,this.#i=e,this.get=this.get.bind(this);}#o(){Array.from(this.#r.dependencies.values()).forEach(({unsubscribe:t})=>{t();}),this.#r.dependencies.clear();}#u(){return {dependencies:new Map,observer:this}}#h(){this.#e=r,r=this.#r;}#f(){r=this.#e;}next(){this.#t=!0,this.#n[x].next();}get(){return this.#n||(this.#n=d(this.#c(),this.#i)),this.#t&&this.#c(),this.#n.get()}#c(){this.#t=!1,this.#o(),this.#h();let t;try{t=this.#s();}catch(e){t=e;}if(this.#f(),t instanceof Promise&&(t=t.then(e=>e).catch(e=>{throw e})),this.#n&&this.#n.set(t),t instanceof Error)throw t;return t}};function E(n,t){return new o(n,t)}function P(n){let t,e=E(()=>{t?.(),t=n();},{equals:()=>!1});return e.get(),g(e),()=>{t?.(),m(e);}}function d(n,t={}){let e=t?.equals??Object.is,s=new Observable;function i(){if(typeof r=="object"&&r!==null&&r.dependencies.set(s,s.subscribe(r.observer)),n instanceof Error)throw n;return n}function b(l){return e(n,l)||(n=l,s.next()),n}return {get:i,set:b,[x]:s}}var S=d;export{E as computed,d as createSignal,w as createWatcher,P as effect,y as getPending,S as state,h as untrack,m as unwatch,g as watch};
1
+ import {Observable,Observer}from'@esmj/observable';var s=null;function f(n){let t=s;s=null;let e=n();return s=t,e}var x=Symbol("internal observable"),c=Symbol("original next"),d=class extends Observable{#t=new Set;#e=null;constructor(t){super(),this.#e=t,this.pipe(e=>{let r=e.subscribe.bind(e),h=e.unsubscribe.bind(e);return e.subscribe=i=>{r(i),this.#t.add(i);},e.unsubscribe=i=>{h(i),this.#t.delete(i);},e});}watch(t){if(typeof t.next!="function"&&(t.next=()=>f(()=>{this.#t.add(t),this.#e();}),t.next[c]=void 0),t instanceof u&&t.next[c]===void 0){let e=t.next.bind(t);t.next=()=>f(()=>{this.#t.add(t),e(),this.#e();}),t.next[c]=e;}return this.subscribe(t)}getPending(){return Array.from(this.#t).map(e=>{let r=e.get.bind(e);return e.get=()=>f(()=>(this.#t.delete(e),r())),e})}unwatch(t){return t.next=t.next[c],this.unsubscribe(t)}},o=null;function w(n){o=new d(n);}w(()=>{setTimeout(()=>{g().forEach(n=>{n.get();});},0);});function g(){return o.getPending()}function m(n){return o.watch(n)}function y(n){return o.unwatch(n)}var u=class extends Observer{#t=!0;#e=null;#n=null;#r=this.#o();#s=null;#i=null;constructor(t,e){super(),this.#s=t,this.#i=e,this.debug=e?.debug,this.get=this.get.bind(this);}#u(){Array.from(this.#r.dependencies.values()).forEach(({unsubscribe:t})=>{t();}),this.#r.dependencies.clear();}#o(){return {dependencies:new Map,observer:this}}#h(){this.#e=s,s=this.#r;}#f(){s=this.#e;}next(){this.#t=!0,this.#n[x].next();}get(){return this.#n||(this.#n=b(this.#c(),this.#i)),this.#t&&this.#c(),this.#n.get()}#c(){this.#t=!1,this.#u(),this.#h();let t;try{t=this.#s();}catch(e){t=e;}if(this.#f(),t instanceof Promise&&(t=t.then(e=>e).catch(e=>{throw e})),this.#n&&this.#n.set(t),t instanceof Error)throw t;return t}};function E(n,t){return new u(n,t)}function P(n,t){let e,r=E(()=>{e?.(),e=n();},{equals:()=>!1,debug:"effect",...t});return r.get(),m(r),()=>{e?.(),y(r);}}function b(n,t={}){let e=t?.equals??Object.is,r=new Observable;function h(){if(typeof s=="object"&&s!==null&&s.dependencies.set(r,r.subscribe(s.observer)),n instanceof Error)throw n;return n}function i(a){return e(n,a)||(n=a,r.next()),n}return {get:h,set:i,[x]:r}}var S=b;export{E as computed,b as createSignal,w as createWatcher,P as effect,g as getPending,S as state,f as untrack,y as unwatch,m as watch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esmj/signals",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Tiny reactive signals.",
5
5
  "keywords": [
6
6
  "signals",
@@ -20,7 +20,7 @@
20
20
  "typings": "dist/index.d.ts",
21
21
  "scripts": {
22
22
  "lint:cmd": "eslint -c ./.eslintrc.js --ignore-path ./.prettierignore --no-eslintrc",
23
- "lint": "npm run lint:cmd -- 'src/**/*.ts'",
23
+ "lint": "npm run lint:cmd -- 'src/**/*.mjs' 'src/*.mjs'",
24
24
  "lint:fix": "npm run lint -- --fix",
25
25
  "dev": "node_modules/.bin/tsup --dts --watch --onSuccess 'node ./dist/index.mjs'",
26
26
  "test": "node --test",