bansa 0.0.13 → 0.0.15

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.
@@ -1 +1 @@
1
- var d=class{r;V;a;o;l;get(){if(this.s||(I(this),u(this)),this.state.error)throw this.state.error;if(this.state.promise)throw this.state.promise;return this.state.value}watch(t){return this.s||k(this),(this.o||=new Set).add(t),()=>{this.o.delete(t),this.o.size||u(this)}}subscribe(t){let a={h:t,p:{get signal(){return(a.t||=q()).signal}}};if(!this.s)k(this);else if(!this.state.error&&!this.state.promise)try{t(this.state.value,a.p)}catch(n){f(n)}return(this.l||=new Set).add(a),()=>{this.l.delete(a),a.t&&(a.t.abort(),a.t=void 0),this.l.size||u(this)}}[Symbol.toPrimitive](){return this.state.value}},i=class extends d{n=!1;A=!1;constructor(t,a){super(),this.d=t,this.m=a?.equals,this.r=t,this.state={promise:void 0,error:void 0,value:t}}set(t){let a=t instanceof Function?t(this.r):t;x(a,this.state.value,this.m)||(this.r=a,m(this))}};i.prototype.y=!0;i.prototype.s=!0;i.prototype.u=!1;var A=class extends d{s=!1;u=!1;n=!1;A=!1;f=0;t;i;c;constructor(t,a){super(),this.d=t,this.m=a?.equals,this.b=!!a?.persist;let n=this;this.p={get signal(){return(n.t||=q()).signal}},this.state={promise:g,error:void 0,value:void 0}}};A.prototype.y=!1;var c=()=>c,_=()=>{};Object.setPrototypeOf(c,new Proxy(c,{get:(e,t)=>t===Symbol.toPrimitive?_:c}));var g=Promise.reject();g.catch(_);var p=(e,t)=>e instanceof Function?new A(e,t):new i(e,t),z=e=>p((t,a)=>{let n,r,o=e(y=>{let l=t(y,!1);if(l.error)r=l.error;else if(l.promise)(n||=[]).push(l.promise);else return l.value;return c},a);if(r)throw r;if(n)throw Promise.all(n);return o},{equals:T}),C=(e,t)=>{let a=new WeakMap;if(t)for(let[r,o]of t)a.set(r,o instanceof d?o:p(o));let n=(r=>{let o=a.get(r);return o||a.set(r,o=r.d instanceof Function?p((y,l)=>r.d((D,E)=>y(n(D),E),l)):e?.(r)||p(r.d)),o});return n},T=(e,t)=>{if(typeof e!="object"||typeof t!="object"||!e||!t)return!1;let a=e.constructor;if(a!==t.constructor)return!1;if(a===Array){let r=e.length;if(r!==t.length)return!1;for(;(r=r-1|0)>=0;)if(!Object.is(e[r],t[r]))return!1;return!0}let n=0;for(let r in e){if(!(r in t&&Object.is(e[r],t[r])))return!1;n=n+1|0}for(let r in t)if((n=n-1|0)<0)return!1;return!0},b=!1,h=[],v=[],k=e=>{e.u||(e.u=!0,m(e))},m=e=>{e.n||(e.n=!0,h.push(e),b||(b=!0,queueMicrotask(K)))},K=()=>{b=!1;{let t=h;h=[];for(let a of t)a.state.promise=void 0,a.state.error=a.V,a.state.value=a.r,O(a)}let e=v;v=[];for(let t=e.length;t--;){let a=e[t];a.A=!1,a.u&&(a.n=!0,I(a)),a.n&&G(a)}},G=e=>{if(e.n=!1,e.o)for(let t of e.o)try{t()}catch(a){f(a)}if(!e.state.error&&!e.state.promise){if(e.l)for(let t of e.l){t.t&&(t.t.abort(),t.t=void 0);try{t.h(e.state.value,t.p)}catch(a){f(a)}}if(e.a)for(let t of e.a)t.u=!0}},O=e=>{if(!e.A){if(e.A=!0,e.a)for(let t of e.a)O(t);v.push(e)}},s=class{e;constructor(t){this.e=t}},P=Symbol(),I=e=>{let t=++e.f;e.s=!0,e.u=!1,e.state.promise=void 0,e.t&&(e.t.abort(),e.t=void 0);try{let a=e.d((n,r=!0)=>{if(t!==e.f)throw P;if(e!==n&&(n.s||(I(n),n.n&&G(n)),(e.c||=new Set).add(n),(n.a||=new Set).add(e)),!r)return n.state;if(n.state.error)throw new s(n.state.error);if(n.state.promise)throw new s(n.state.promise);return n.state.value},e.p);j(a)?(e.state.promise=a,a.then(n=>{t===e.f&&(V(e),x(n,e.state.value,e.m)?e.state.promise=void 0:(e.r=n,e.V=void 0),m(e))},n=>{t===e.f&&(V(e),n instanceof s?n=n.e:f(n),e.V=n,m(e))})):(V(e),e.state.error=void 0,x(a,e.state.value,e.m)?e.n=!1:e.state.value=e.r=a)}catch(a){V(e),a===P?e.n=!1:(a instanceof s?a=a.e:f(a),e.state.error=a)}},V=e=>{++e.f;let t=e.i;if(e.i=e.c,t){for(let a of t)e.i?.has(a)||(a.a.delete(e),u(a));t.clear()}e.c=t},S=!1,w=new Set,u=e=>{!e.y&&!e.b&&!e.a?.size&&!e.o?.size&&!e.l?.size&&(w.add(e),S||(S=!0,setTimeout(L,0)))},L=()=>{for(let e of w)if(!e.y&&!e.b&&!e.a?.size&&!e.o?.size&&!e.l?.size&&(e.state.promise=g,e.r=e.V=e.state.error=e.state.value=void 0,e.n=e.u=e.s=!1,e.t&&(e.t.abort(),e.t=void 0),e.i)){for(let t of e.i)t.a.delete(e),u(t);if(e.i.clear(),e.c){for(let t of e.c)t.a.delete(e),u(t);e.c.clear()}}w.clear(),S=!1},x=(e,t,a)=>Object.is(e,t)||a!==void 0&&t!==void 0&&a(e,t),j=e=>typeof e?.then=="function",q=()=>{let e=new AbortController,t=e.signal,a=new Promise(n=>{t.then=r=>a.then(r),t.addEventListener("abort",n,{once:!0,passive:!0})});return{abort:()=>e.abort(),signal:t}},f=e=>{queueMicrotask(()=>{throw e})};export{p as $,z as $$,C as createScope,g as inactive};
1
+ var f=class{r;p;a;o;l;get(){if(this.s||(k(this),i(this)),this.state.error)throw this.state.error;if(this.state.promise)throw this.state.promise;return this.state.value}watch(t){return this.s||_(this),(this.o||=new Set).add(t),()=>{this.o.delete(t),this.o.size||i(this)}}subscribe(t){let a={h:t,A:{get signal(){return(a.t||=T()).signal}}};if(!this.s)_(this);else if(!this.state.error&&!this.state.promise)try{t(this.state.value,a.A)}catch(n){p(n)}return(this.l||=new Set).add(a),()=>{this.l.delete(a),a.t&&(a.t.abort(),a.t=void 0),this.l.size||i(this)}}[Symbol.toPrimitive](){return this.state.value}},c=class extends f{n=!1;m=!1;constructor(t,a){super(),this.d=t,this.V=a?.equals,this.r=t,this.state={promise:void 0,error:void 0,value:t}}set(t){let a=t instanceof Function?t(this.r):t;g(a,this.state.value,this.V)||(this.r=a,b(this))}};c.prototype.y=!0;c.prototype.s=!0;c.prototype.u=!1;var y=class extends f{s=!1;u=!1;n=!1;m=!1;f=0;t;i;c;constructor(t,a){super(),this.d=t,this.V=a?.equals,this.b=!!a?.persist;let n=this;this.A={get signal(){return(n.t||=T()).signal}},this.state={promise:I,error:void 0,value:void 0}}};y.prototype.y=!1;var V=()=>V,O=()=>{};Object.setPrototypeOf(V,new Proxy(V,{get:(e,t)=>t===Symbol.toPrimitive?O:V}));var I=Promise.reject();I.catch(O);var m=(e,t)=>e instanceof Function?new y(e,t):new c(e,t),U=e=>m((t,a)=>{let n,r,l=e(s=>{let o=t(s,!1);if(o.error)r=o.error;else if(o.promise)(n||=[]).push(o.promise);else return o.value;return V},a);if(r)throw r;if(n)throw Promise.all(n);return l},{equals:z}),R=(e,t)=>{let a=new WeakMap,n=new WeakMap;if(t)for(let[l,s]of t)a.set(l,s instanceof f?s:m(s));let r=((l,s=!1)=>{let o=a.get(l);if(s)return o||e?.(l,!0);if(!o){let P=e?.(l,!0),d=P||l;n.set(l,o=d.d instanceof Function?m((E,K)=>d.d((L,j)=>E(r(L),j),K),{equals:d.V,persist:d.b}):P||m(d.d))}return o});return r},z=(e,t)=>{if(typeof e!="object"||typeof t!="object"||!e||!t)return!1;let a=e.constructor;if(a!==t.constructor)return!1;if(a===Array){let r=e.length;if(r!==t.length)return!1;for(;(r=r-1|0)>=0;)if(!Object.is(e[r],t[r]))return!1;return!0}let n=0;for(let r in e){if(!(r in t&&Object.is(e[r],t[r])))return!1;n=n+1|0}for(let r in t)if((n=n-1|0)<0)return!1;return!0},h=!1,v=[],S=[],_=e=>{e.u||(e.u=!0,b(e))},b=e=>{e.n||(e.n=!0,v.push(e),h||(h=!0,queueMicrotask(C)))},C=()=>{h=!1;{let t=v;v=[];for(let a of t)a.state.promise=void 0,a.state.error=a.p,a.state.value=a.r,D(a)}let e=S;S=[];for(let t=e.length;t--;){let a=e[t];a.m=!1,a.u&&(a.n=!0,k(a)),a.n&&q(a)}},q=e=>{if(e.n=!1,e.o)for(let t of e.o)try{t()}catch(a){p(a)}if(!e.state.error&&!e.state.promise){if(e.l)for(let t of e.l){t.t&&(t.t.abort(),t.t=void 0);try{t.h(e.state.value,t.A)}catch(a){p(a)}}if(e.a)for(let t of e.a)t.u=!0}},D=e=>{if(!e.m){if(e.m=!0,e.a)for(let t of e.a)D(t);S.push(e)}},u=class{e;constructor(t){this.e=t}},G=Symbol(),k=e=>{let t=++e.f;e.s=!0,e.u=!1,e.state.promise=void 0,e.t&&(e.t.abort(),e.t=void 0);try{let a=e.d((n,r=!0)=>{if(t!==e.f)throw G;if(e!==n&&(n.s||(k(n),n.n&&q(n)),(e.c||=new Set).add(n),(n.a||=new Set).add(e)),!r)return n.state;if(n.state.error)throw new u(n.state.error);if(n.state.promise)throw new u(n.state.promise);return n.state.value},e.A);W(a)?(e.state.promise=a,a.then(n=>{t===e.f&&(A(e),g(n,e.state.value,e.V)?e.state.promise=void 0:(e.r=n,e.p=void 0),b(e))},n=>{t===e.f&&(A(e),n instanceof u?n=n.e:p(n),e.p=n,b(e))})):(A(e),e.state.error=void 0,g(a,e.state.value,e.V)?e.n=!1:e.state.value=e.r=a)}catch(a){A(e),a===G?e.n=!1:(a instanceof u?a=a.e:p(a),e.state.error=a)}},A=e=>{++e.f;let t=e.i;if(e.i=e.c,t){for(let a of t)e.i?.has(a)||(a.a.delete(e),i(a));t.clear()}e.c=t},w=!1,x=new Set,i=e=>{!e.y&&!e.b&&!e.a?.size&&!e.o?.size&&!e.l?.size&&(x.add(e),w||(w=!0,setTimeout(M,0)))},M=()=>{for(let e of x)if(!e.y&&!e.b&&!e.a?.size&&!e.o?.size&&!e.l?.size&&(e.state.promise=I,e.r=e.p=e.state.error=e.state.value=void 0,e.n=e.u=e.s=!1,e.t&&(e.t.abort(),e.t=void 0),e.i)){for(let t of e.i)t.a.delete(e),i(t);if(e.i.clear(),e.c){for(let t of e.c)t.a.delete(e),i(t);e.c.clear()}}x.clear(),w=!1},g=(e,t,a)=>Object.is(e,t)||a!==void 0&&t!==void 0&&a(e,t),W=e=>typeof e?.then=="function",T=()=>{let e=new AbortController,t=e.signal,a=new Promise(n=>{t.then=r=>a.then(r),t.addEventListener("abort",n,{once:!0,passive:!0})});return{abort:()=>e.abort(),signal:t}},p=e=>{queueMicrotask(()=>{throw e})};export{m as $,U as $$,R as createScope,I as inactive};
package/dist/index.d.ts CHANGED
@@ -65,15 +65,15 @@ export type AtomScope = {
65
65
  <Value>(baseAtom: PrimitiveAtom<Value>): PrimitiveAtom<Value>;
66
66
  <Value>(baseAtom: DerivedAtom<Value>): DerivedAtom<Value>;
67
67
  <Value>(baseAtom: Atom<Value>): Atom<Value>;
68
- <Value>(baseAtom: PrimitiveAtom<Value>, create: false): PrimitiveAtom<Value> | undefined;
69
- <Value>(baseAtom: DerivedAtom<Value>, create: false): DerivedAtom<Value> | undefined;
70
- <Value>(baseAtom: Atom<Value>, create: false): Atom<Value> | undefined;
68
+ <Value>(baseAtom: PrimitiveAtom<Value>, strict: true): PrimitiveAtom<Value> | undefined;
69
+ <Value>(baseAtom: DerivedAtom<Value>, strict: true): DerivedAtom<Value> | undefined;
70
+ <Value>(baseAtom: Atom<Value>, strict: true): Atom<Value> | undefined;
71
71
  };
72
72
  export type SetLike<Key> = Key[] | Set<Key> | (Key extends object ? WeakSet<Key> : never);
73
73
  export type MapLike<Key, Value> = Map<Key, Value> | (Key extends object ? WeakMap<Key, Value> : never) | (Key extends string | number | symbol ? Record<Key, Value> : never);
74
74
  export declare const inactive: Promise<never>;
75
75
  export declare const $: CreateAtom;
76
76
  export declare const $$: <Value>(init: AtomGetter<Value>) => DerivedAtom<Value>;
77
- export type AtomValuePair<Value> = [Atom<Value>, Value | Atom<Value>];
78
- export declare const createScope: (parentScope?: AtomScope | null, atomValuePairs?: AtomValuePair<unknown>[]) => AtomScope;
77
+ export type AtomValuePair<Value> = [Atom<Value>, Value | PrimitiveAtom<Value>] | [DerivedAtom<Value>, Value | Atom<Value>];
78
+ export declare const createScope: <T extends AtomValuePair<unknown>[]>(parentScope?: AtomScope | null, atomValuePairs?: T) => AtomScope;
79
79
  export {};
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  class CommonAtomInternal {
2
2
  d;
3
- n;
3
+ o;
4
4
  b;
5
5
  f;
6
6
  g;
@@ -28,7 +28,7 @@ class CommonAtomInternal {
28
28
  subscribe(subscriber) {
29
29
  const atomSubscriber = {
30
30
  t: subscriber,
31
- o: {
31
+ p: {
32
32
  get signal() {
33
33
  return (atomSubscriber.a ||= createThenableSignal()).signal;
34
34
  }
@@ -38,7 +38,7 @@ class CommonAtomInternal {
38
38
  requestActivate(this);
39
39
  } else if (!this.state.error && !this.state.promise) {
40
40
  try {
41
- subscriber(this.state.value, atomSubscriber.o);
41
+ subscriber(this.state.value, atomSubscriber.p);
42
42
  } catch (e) {
43
43
  logError(e);
44
44
  }
@@ -61,11 +61,11 @@ class CommonAtomInternal {
61
61
  }
62
62
  class PrimitiveAtomInternal extends CommonAtomInternal {
63
63
  c = false;
64
- p = false;
64
+ q = false;
65
65
  constructor(init, options) {
66
66
  super();
67
67
  this.l = init;
68
- this.q = options?.equals;
68
+ this.m = options?.equals;
69
69
  this.d = init;
70
70
  this.state = {
71
71
  promise: void 0,
@@ -75,7 +75,7 @@ class PrimitiveAtomInternal extends CommonAtomInternal {
75
75
  }
76
76
  set(value) {
77
77
  const nextValue = value instanceof Function ? value(this.d) : value;
78
- if (!equals(nextValue, this.state.value, this.q)) {
78
+ if (!equals(nextValue, this.state.value, this.m)) {
79
79
  this.d = nextValue;
80
80
  requestPropagate(this);
81
81
  }
@@ -88,18 +88,18 @@ class DerivedAtomInternal extends CommonAtomInternal {
88
88
  h = false;
89
89
  i = false;
90
90
  c = false;
91
- p = false;
92
- m = 0;
91
+ q = false;
92
+ n = 0;
93
93
  a;
94
94
  j;
95
95
  k;
96
96
  constructor(init, options) {
97
97
  super();
98
98
  this.l = init;
99
- this.q = options?.equals;
99
+ this.m = options?.equals;
100
100
  this.s = !!options?.persist;
101
101
  const self = this;
102
- this.o = {
102
+ this.p = {
103
103
  get signal() {
104
104
  return (self.a ||= createThenableSignal()).signal;
105
105
  }
@@ -145,20 +145,29 @@ const $$ = (init) => $((get, options) => {
145
145
  });
146
146
  const createScope = (parentScope, atomValuePairs) => {
147
147
  const scopeMap = /* @__PURE__ */ new WeakMap();
148
+ const atomMap = /* @__PURE__ */ new WeakMap();
148
149
  if (atomValuePairs) {
149
150
  for (const [atom, value] of atomValuePairs) {
150
151
  scopeMap.set(atom, value instanceof CommonAtomInternal ? value : $(value));
151
152
  }
152
153
  }
153
- const scope = ((baseAtom) => {
154
+ const scope = ((baseAtom, strict = false) => {
154
155
  let scopedAtom = scopeMap.get(baseAtom);
155
- if (!scopedAtom) scopeMap.set(
156
- baseAtom,
157
- scopedAtom = baseAtom.l instanceof Function ? $((get, options) => baseAtom.l(
158
- (atom, unwrap) => get(scope(atom), unwrap),
159
- options
160
- )) : parentScope?.(baseAtom) || $(baseAtom.l)
161
- );
156
+ if (strict) return scopedAtom || parentScope?.(baseAtom, true);
157
+ if (!scopedAtom) {
158
+ const parentAtom = parentScope?.(baseAtom, true);
159
+ const realBaseAtom = parentAtom || baseAtom;
160
+ atomMap.set(
161
+ baseAtom,
162
+ scopedAtom = realBaseAtom.l instanceof Function ? $((get, options) => realBaseAtom.l(
163
+ (atom, unwrap) => get(scope(atom), unwrap),
164
+ options
165
+ ), {
166
+ equals: realBaseAtom.m,
167
+ persist: realBaseAtom.s
168
+ }) : parentAtom || $(realBaseAtom.l)
169
+ );
170
+ }
162
171
  return scopedAtom;
163
172
  });
164
173
  return scope;
@@ -207,7 +216,7 @@ const updateAtoms = () => {
207
216
  updateQueue = [];
208
217
  for (const atom of updatedAtoms) {
209
218
  atom.state.promise = void 0;
210
- atom.state.error = atom.n;
219
+ atom.state.error = atom.o;
211
220
  atom.state.value = atom.d;
212
221
  mark(atom);
213
222
  }
@@ -216,7 +225,7 @@ const updateAtoms = () => {
216
225
  stack = [];
217
226
  for (let i = markedAtoms.length; i--; ) {
218
227
  const atom = markedAtoms[i];
219
- atom.p = false;
228
+ atom.q = false;
220
229
  if (atom.i) {
221
230
  atom.c = true;
222
231
  execute(atom);
@@ -245,7 +254,7 @@ const propagate = (atom) => {
245
254
  subscriber.a = void 0;
246
255
  }
247
256
  try {
248
- subscriber.t(atom.state.value, subscriber.o);
257
+ subscriber.t(atom.state.value, subscriber.p);
249
258
  } catch (e) {
250
259
  logError(e);
251
260
  }
@@ -259,8 +268,8 @@ const propagate = (atom) => {
259
268
  }
260
269
  };
261
270
  const mark = (atom) => {
262
- if (!atom.p) {
263
- atom.p = true;
271
+ if (!atom.q) {
272
+ atom.q = true;
264
273
  if (atom.b) {
265
274
  for (const child of atom.b) {
266
275
  mark(child);
@@ -277,7 +286,7 @@ class Wrapped {
277
286
  }
278
287
  const expired = Symbol();
279
288
  const execute = (atom) => {
280
- const counter = ++atom.m;
289
+ const counter = ++atom.n;
281
290
  atom.h = true;
282
291
  atom.i = false;
283
292
  atom.state.promise = void 0;
@@ -288,7 +297,7 @@ const execute = (atom) => {
288
297
  try {
289
298
  const value = atom.l(
290
299
  (anotherAtom, unwrap = true) => {
291
- if (counter !== atom.m) throw expired;
300
+ if (counter !== atom.n) throw expired;
292
301
  if (atom !== anotherAtom) {
293
302
  if (!anotherAtom.h) {
294
303
  execute(anotherAtom);
@@ -306,32 +315,32 @@ const execute = (atom) => {
306
315
  throw new Wrapped(anotherAtom.state.promise);
307
316
  return anotherAtom.state.value;
308
317
  },
309
- atom.o
318
+ atom.p
310
319
  );
311
320
  if (isPromiseLike(value)) {
312
321
  atom.state.promise = value;
313
322
  value.then(
314
323
  (value2) => {
315
- if (counter === atom.m) {
324
+ if (counter === atom.n) {
316
325
  finalizeExecution(atom);
317
- if (equals(value2, atom.state.value, atom.q)) {
326
+ if (equals(value2, atom.state.value, atom.m)) {
318
327
  atom.state.promise = void 0;
319
328
  } else {
320
329
  atom.d = value2;
321
- atom.n = void 0;
330
+ atom.o = void 0;
322
331
  }
323
332
  requestPropagate(atom);
324
333
  }
325
334
  },
326
335
  (e) => {
327
- if (counter === atom.m) {
336
+ if (counter === atom.n) {
328
337
  finalizeExecution(atom);
329
338
  if (e instanceof Wrapped) {
330
339
  e = e.e;
331
340
  } else {
332
341
  logError(e);
333
342
  }
334
- atom.n = e;
343
+ atom.o = e;
335
344
  requestPropagate(atom);
336
345
  }
337
346
  }
@@ -339,7 +348,7 @@ const execute = (atom) => {
339
348
  } else {
340
349
  finalizeExecution(atom);
341
350
  atom.state.error = void 0;
342
- if (equals(value, atom.state.value, atom.q)) {
351
+ if (equals(value, atom.state.value, atom.m)) {
343
352
  atom.c = false;
344
353
  } else {
345
354
  atom.state.value = atom.d = value;
@@ -360,7 +369,7 @@ const execute = (atom) => {
360
369
  }
361
370
  };
362
371
  const finalizeExecution = (atom) => {
363
- ++atom.m;
372
+ ++atom.n;
364
373
  const oldDependencies = atom.j;
365
374
  atom.j = atom.k;
366
375
  if (oldDependencies) {
@@ -389,7 +398,7 @@ const gc = () => {
389
398
  for (const atom of gcCandidates) {
390
399
  if (!atom.r && !atom.s && !atom.b?.size && !atom.f?.size && !atom.g?.size) {
391
400
  atom.state.promise = inactive;
392
- atom.d = atom.n = atom.state.error = atom.state.value = void 0;
401
+ atom.d = atom.o = atom.state.error = atom.state.value = void 0;
393
402
  atom.c = atom.i = atom.h = false;
394
403
  if (atom.a) {
395
404
  atom.a.abort();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bansa",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,5 +1,5 @@
1
1
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { $, createScope, DerivedAtom, type ThenableSignal } from '../src/index';
2
+ import { $, createScope, type DerivedAtom, type PrimitiveAtom, type ThenableSignal } from '../src/index';
3
3
 
4
4
  const flushMicrotasks = () =>
5
5
  new Promise((resolve) => {
@@ -488,7 +488,7 @@ describe('Atom Library - Advanced Tests', () => {
488
488
  expect(derivedAtom1.state.value).toEqual(undefined);
489
489
  });
490
490
 
491
- it('deep scope', async () => {
491
+ it('scope with deep dependencies', async () => {
492
492
  const $x1 = $(1);
493
493
  const $x2 = $((get) => get($x1) + 1);
494
494
  const $x3 = $((get) => get($x2) + 1);
@@ -531,6 +531,62 @@ describe('Atom Library - Advanced Tests', () => {
531
531
  expect($y2.get()).toBe(25);
532
532
  });
533
533
 
534
+ it('deep scope', async () => {
535
+ const $x1 = $(1); // 1
536
+ const $x2 = $((get) => get($x1) + 1); // 2
537
+ const $x3 = $((get) => get($x2) + 1); // 3
538
+ const $x4 = $((get) => get($x3) + 1); // 4
539
+ const $x5 = $((get) => get($x1) + get($x2) + get($x3) + get($x4)); // 10
540
+ const identity = (x: any) => x;
541
+ const scope0 = createScope(identity);
542
+ const scope1 = createScope(scope0, [
543
+ [$x1, 11],
544
+ ]);
545
+ const scope2 = createScope(scope1, [
546
+ [$x2, 22],
547
+ ]);
548
+
549
+ $x5.subscribe(nop);
550
+ await flushMicrotasks();
551
+
552
+ const $y0 = scope0($x5);
553
+ const $y1 = scope1($x5);
554
+ const $y2 = scope2($x5);
555
+
556
+ expect($x5.get()).toBe(10);
557
+ expect($y0.get()).toBe(10);
558
+ expect($y1.get()).toBe(50);
559
+ expect($y2.get()).toBe(80);
560
+
561
+ $x1.set(101);
562
+ await flushMicrotasks();
563
+ expect($x5.get()).toBe(410);
564
+ expect($y0.get()).toBe(410);
565
+ expect($y1.get()).toBe(50);
566
+ expect($y2.get()).toBe(80);
567
+
568
+ scope1($x1).set(101);
569
+ await flushMicrotasks();
570
+ expect($x5.get()).toBe(410);
571
+ expect($y0.get()).toBe(410);
572
+ expect($y1.get()).toBe(410);
573
+ expect($y2.get()).toBe(170);
574
+
575
+ scope2($x1).set(201);
576
+ await flushMicrotasks();
577
+ expect($x5.get()).toBe(410);
578
+ expect($y0.get()).toBe(410);
579
+ expect($y1.get()).toBe(810);
580
+ expect($y2.get()).toBe(270);
581
+
582
+ (scope2($x2) as PrimitiveAtom<number>).set(202);
583
+ await flushMicrotasks();
584
+ expect($x5.get()).toBe(410);
585
+ expect($y0.get()).toBe(410);
586
+ expect($y1.get()).toBe(810);
587
+ expect($y2.get()).toBe(810);
588
+ });
589
+
534
590
  it('should not provide stale values to conditional dependents', async () => {
535
591
  const dataAtom = $([100]);
536
592
  const hasFilterAtom = $(false);