whenmap 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/README.md CHANGED
@@ -25,8 +25,10 @@ async function example_init() {
25
25
  }
26
26
  ```
27
27
 
28
- - `when_db.when(key)` returns a promise for the key. The promise
29
- may or may not be resolved.
28
+ - `when_db.when(key)` returns a promise for the newly tracked key.
29
+ The promise may or may not be resolved.
30
+
31
+ - `when_db.ref(key, p)` is a observation hook for newly tracked keys.
30
32
 
31
33
  - `when_db.get(key)` is an alias for `when_db.when(key)`
32
34
 
@@ -43,21 +45,36 @@ async function example_init() {
43
45
  clearing all tracked keys.
44
46
 
45
47
 
46
- ## WhenAiter API
48
+ ## aiter_pipe API
47
49
 
48
- ```javascript
49
- import { WhenAiter } from 'whenmap'
50
+ `aiter_pipe(opt)` returns a connected `[send, recv]` pair where `send` is a
51
+ function and `recv` is an async iterable.
50
52
 
53
+ - `send(value)` adds value to the internal queue, after awaiting it if a promisable.
54
+ - `opt.on_error(err)` is an optional promise `.catch()` handler.
55
+ - `send.stop()` terminates the async iterable stream from within the `init_arg` closure.
56
+ - `send.ready` is a promise to provide overflow backpressure.
57
+ - `opt.max_size` manages the `send.ready` promise, default of 5
51
58
 
52
- // For streaming promises as they are settled
53
- let misc_promises = [ 100, 20, 50 ].map(ms =>
54
- new Promise(done =>
55
- setTimeout(done, ms, `delay: ${ms}`) ))
59
+ - `recv` extends the optional prototype
60
+ - `recv.size` returns the interal queue size
61
+ - `recv` supports async iterable protocol: `for await (let each of when_stream) {}`
62
+ - `recv.next()` returns the next resolved value
63
+ - if `opt.batch`, returns list of all resolved values
64
+ - `recv.return()`
65
+ - `recv.throw()`
66
+ - `recv[Symbol.asyncIterator]()`
56
67
 
57
- for await (let each of WhenAiter.from(misc_promises)) {
58
- console.log('stream resolved:', detail)
59
- }
68
+ - an AbortSignal instance is aborted when the stream is stopped.
69
+ - assigned into `recv.signal` and `send.signal`
70
+
71
+ ## WhenAiter API
72
+
73
+ `WhenAiter` is a Promise-like wrapper around `aiter_pipe` to transform callback
74
+ events into async iteratable.
60
75
 
76
+ ```javascript
77
+ import { WhenAiter } from 'whenmap'
61
78
 
62
79
  // For streaming events
63
80
  let when_stream = new WhenAiter(send => {
@@ -72,29 +89,25 @@ for await (let detail of when_stream) {
72
89
  }
73
90
  ```
74
91
 
75
- - `new WhenMap(init_arg, opt)` returns an async iterable.
92
+ `WhenAiter` can also transform a collection promises into an async iteratable.
93
+
94
+ ```javascript
95
+ import { WhenAiter } from 'whenmap'
96
+ const sleep = new Promise(done => setTimeout(done, ms, `delay: ${ms}`) )
97
+ // For streaming promises as they are settled
98
+ let misc_promises = [ sleep(100), sleep(20), sleep(50) ]
99
+
100
+ for await (let each of WhenAiter.from(misc_promises)) {
101
+ console.log('stream resolved:', detail)
102
+ }
103
+ ```
104
+
105
+ - `new WhenAiter(init_arg, opt)` returns an async iterable.
76
106
  - If `init_arg` is iterable, `send()` is called on each item.
77
107
  - other `init_arg(send)` is invoked.
78
108
 
79
- - `WhenMap.from(init_arg, opt)` is an alias for `new WhenMap`
80
-
81
- - `aiter_pipe(opt, recv_self)` returns a connected `[send, recv]` pair
82
- - `send(value)` adds value to the internal queue, after awaiting it if a promisable.
83
- - `opt.on_error(err)` is an optional promise `.catch()` handler.
84
- - `send.stop()` terminates the async iterable stream from within the `init_arg` closure.
85
- - `send.ready` is a promise to provide overflow backpressure.
86
- - `opt.max_size` manages the `send.ready` promise
87
-
88
- - `recv` extends the `recv_self` prototype
89
- - `recv.size` returns the interal queue size
90
- - `recv` supports async iterable protocol: `for await (let each of when_stream) {}`
91
- - `recv.next()`
92
- - `recv.return()`
93
- - `recv.throw()`
94
- - `recv[Symbol.asyncIterator]()`
95
-
96
- - an AbortSignal instance is aborted when the stream is stopped.
97
- - assigned into `recv.signal` and `send.signal`
109
+ - `WhenAiter.from(init_arg, opt)` is an alias for `new WhenAiter`
110
+
98
111
 
99
112
 
100
113
  ## Install
package/esm/whenaiter.js CHANGED
@@ -3,16 +3,20 @@ class WhenAiter {
3
3
  return new this(init_arg, opt)}
4
4
 
5
5
  constructor(init_arg, opt) {
6
- let [send, recv_self] = aiter_pipe(opt, this);
7
- if (init_arg?.[Symbol.iterator]) {
8
- _send_all(init_arg, send, recv_self);}
9
- else init_arg?.(send);
10
- return recv_self} }
6
+ let [send, recv_aiter] = aiter_pipe.call(this, opt);
11
7
 
8
+ if(init_arg)
9
+ init_arg?.call ? init_arg(send)
10
+ : Array.from(init_arg, send)
11
+ .reduce((a,b) => a.then(b), send.ready)
12
+ .then(_ => send.stop());
12
13
 
14
+ return recv_aiter} }
13
15
 
14
- function aiter_pipe(opt, recv_self) {
16
+
17
+ function aiter_pipe(opt) {
15
18
  const q=[], max_size = opt?.max_size ?? 5;
19
+ const pop_result = opt?.batch ? q => q.splice(0) : q => q.shift();
16
20
  let abrt = new AbortController();
17
21
  let p_underflow, p_overflow;
18
22
 
@@ -22,53 +26,47 @@ function aiter_pipe(opt, recv_self) {
22
26
  return v.then(send, opt?.on_error)}
23
27
 
24
28
  q.push(v);
25
- p_underflow = void p_underflow?.resolve();}
29
+ p_underflow = void p_underflow?.resolve();
30
+
31
+ // update overflow promise state
32
+ if (q.length >= max_size) {
33
+ send.ready = (p_overflow ??= Promise.withResolvers()).promise;} }
26
34
 
27
35
  send.signal = abrt.signal;
28
- send.ready = Promise.resolve(true);
36
+ send.ready = Promise.resolve();
29
37
  send.stop = async () => {
30
38
  abrt = void abrt?.abort();
31
39
  p_underflow = void p_underflow?.resolve();
32
40
  return { done: true }};
33
41
 
34
-
35
42
  // Async Iterable Receiver
36
- recv_self ={
37
- __proto__: recv_self
43
+ let recv_aiter ={
44
+ __proto__: this
38
45
  , get size() {return q.length}
39
46
  , signal: abrt.signal
40
47
 
41
48
  , [Symbol.asyncIterator]() {return this}
42
- , return: send.stop, throw: send.stop,
43
- async next() {
49
+ , return: send.stop
50
+ , throw: send.stop
51
+ , async next() {
44
52
  while (1) {
45
- if (q.length) {
46
- return { value: q.shift(), done: false }}
47
-
48
- if (undefined === abrt) {
49
- return { done: true }}
50
- else if (q.length < max_size) {
51
- p_overflow = void p_overflow?.resolve(true);}
52
- else if (! p_overflow) {
53
- send.ready = (p_overflow = Promise.withResolvers()).promise;}
54
-
55
- await (p_underflow ??= Promise.withResolvers()).promise;} } };
56
-
53
+ let r, len=q.length;
54
+ if (len) {// results are available
55
+ r = pop_result(q);
57
56
 
58
- return [send, recv_self]}
57
+ if (len <= max_size) {
58
+ // update overflow promise state
59
+ p_overflow = void p_overflow?.resolve();}
60
+ return { value: r, done: false }}
59
61
 
62
+ if (undefined === abrt) {// async iterable is done
63
+ return { done: true }}
60
64
 
61
- async function _send_all(iterable, send, aiter) {
62
- let l=[];
63
- for (let v of iterable) {
64
- v = send(v);
65
- if (v) {l.push(v);} }
66
-
67
- // join on all promises
68
- while (l.length) {await l.pop();}
65
+ // set underflow promise state
66
+ await (p_underflow ??= Promise.withResolvers()).promise;
67
+ } } };// after underflow resolved, loop to try again
69
68
 
70
- // mark complete
71
- await aiter.return();}
69
+ return [send, recv_aiter]}
72
70
 
73
71
  export { WhenAiter, aiter_pipe };
74
72
  //# sourceMappingURL=whenaiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"whenaiter.js","sources":["../code/whenaiter.jsy"],"sourcesContent":["\nexport class WhenAiter ::\n static from(init_arg, opt) ::\n return new this(init_arg, opt)\n\n constructor(init_arg, opt) ::\n let [send, recv_self] = aiter_pipe(opt, this)\n if init_arg?.[Symbol.iterator] ::\n _send_all(init_arg, send, recv_self)\n else init_arg?.(send)\n return recv_self\n\n\n\nexport function aiter_pipe(opt, recv_self) ::\n const q=[], max_size = opt?.max_size ?? 5\n let abrt = new AbortController()\n let p_underflow, p_overflow\n\n // Sender function closure\n function send(v) ::\n if v?.then ::\n return v.then(send, opt?.on_error)\n\n q.push(v)\n p_underflow = void p_underflow?.resolve()\n\n send.signal = abrt.signal\n send.ready = Promise.resolve(true)\n send.stop = async () => ::\n abrt = void abrt?.abort()\n p_underflow = void p_underflow?.resolve()\n return { done: true }\n\n\n // Async Iterable Receiver\n recv_self = @{}\n __proto__: recv_self\n get size() :: return q.length\n signal: abrt.signal\n\n [Symbol.asyncIterator]() :: return this\n return: send.stop, throw: send.stop,\n async next() ::\n while 1 ::\n if q.length ::\n return { value: q.shift(), done: false }\n\n if undefined === abrt ::\n return { done: true }\n else if q.length < max_size ::\n p_overflow = void p_overflow?.resolve(true)\n else if ! p_overflow ::\n send.ready = (p_overflow = Promise.withResolvers()).promise\n\n await (p_underflow ??= Promise.withResolvers()).promise\n\n\n return [send, recv_self]\n\n\nasync function _send_all(iterable, send, aiter) ::\n let l=[]\n for let v of iterable ::\n v = send(v)\n if v :: l.push(v)\n\n // join on all promises\n while l.length :: await l.pop()\n\n // mark complete\n await aiter.return()\n\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"whenaiter.js","sources":["../code/whenaiter.jsy"],"sourcesContent":["\nexport class WhenAiter ::\n static from(init_arg, opt) ::\n return new this(init_arg, opt)\n\n constructor(init_arg, opt) ::\n let [send, recv_aiter] = aiter_pipe.call(this, opt)\n\n if(init_arg)\n init_arg?.call ? init_arg(send)\n : Array.from(init_arg, send)\n .reduce((a,b) => a.then(b), send.ready)\n .then(_ => send.stop())\n\n return recv_aiter\n\n\nexport function aiter_pipe(opt) ::\n const q=[], max_size = opt?.max_size ?? 5\n const pop_result = opt?.batch ? q => q.splice(0) : q => q.shift()\n let abrt = new AbortController()\n let p_underflow, p_overflow\n\n // Sender function closure\n function send(v) ::\n if v?.then ::\n return v.then(send, opt?.on_error)\n\n q.push(v)\n p_underflow = void p_underflow?.resolve()\n\n // update overflow promise state\n if q.length >= max_size ::\n send.ready = (p_overflow ??= Promise.withResolvers()).promise\n\n send.signal = abrt.signal\n send.ready = Promise.resolve()\n send.stop = async () => ::\n abrt = void abrt?.abort()\n p_underflow = void p_underflow?.resolve()\n return { done: true }\n\n // Async Iterable Receiver\n let recv_aiter = @{}\n __proto__: this\n get size() :: return q.length\n signal: abrt.signal\n\n [Symbol.asyncIterator]() :: return this\n return: send.stop\n throw: send.stop\n async next() ::\n while 1 ::\n let r, len=q.length\n if len :: // results are available\n r = pop_result(q)\n\n if len <= max_size ::\n // update overflow promise state\n p_overflow = void p_overflow?.resolve()\n return { value: r, done: false }\n\n if undefined === abrt :: // async iterable is done\n return { done: true }\n\n // set underflow promise state\n await (p_underflow ??= Promise.withResolvers()).promise\n // after underflow resolved, loop to try again\n\n return [send, recv_aiter]\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- class e{static from(e,r){return new this(e,r)}constructor(e,t){let[o,n]=r(t,this);return e?.[Symbol.iterator]?async function(e,r,t){let o=[];for(let t of e)t=r(t),t&&o.push(t);for(;o.length;)await o.pop();await t.return()}(e,o,n):e?.(o),n}}function r(e,r){const t=[],o=e?.max_size??5;let n,s,i=new AbortController;function l(r){if(r?.then)return r.then(l,e?.on_error);t.push(r),n=void n?.resolve()}return l.signal=i.signal,l.ready=Promise.resolve(!0),l.stop=async()=>(i=void i?.abort(),n=void n?.resolve(),{done:!0}),r={__proto__:r,get size(){return t.length},signal:i.signal,[Symbol.asyncIterator](){return this},return:l.stop,throw:l.stop,async next(){for(;;){if(t.length)return{value:t.shift(),done:!1};if(void 0===i)return{done:!0};t.length<o?s=void s?.resolve(!0):s||(l.ready=(s=Promise.withResolvers()).promise),await(n??=Promise.withResolvers()).promise}}},[l,r]}export{e as WhenAiter,r as aiter_pipe};
1
+ class e{static from(e,r){return new this(e,r)}constructor(e,t){let[o,s]=r.call(this,t);return e&&(e?.call?e(o):Array.from(e,o).reduce(((e,r)=>e.then(r)),o.ready).then((e=>o.stop()))),s}}function r(e){const r=[],t=e?.max_size??5,o=e?.batch?e=>e.splice(0):e=>e.shift();let s,n,i=new AbortController;function l(o){if(o?.then)return o.then(l,e?.on_error);r.push(o),s=void s?.resolve(),r.length>=t&&(l.ready=(n??=Promise.withResolvers()).promise)}return l.signal=i.signal,l.ready=Promise.resolve(),l.stop=async()=>(i=void i?.abort(),s=void s?.resolve(),{done:!0}),[l,{__proto__:this,get size(){return r.length},signal:i.signal,[Symbol.asyncIterator](){return this},return:l.stop,throw:l.stop,async next(){for(;;){let e,l=r.length;if(l)return e=o(r),l<=t&&(n=void n?.resolve()),{value:e,done:!1};if(void 0===i)return{done:!0};await(s??=Promise.withResolvers()).promise}}}]}export{e as WhenAiter,r as aiter_pipe};
package/esm/whenmap.js CHANGED
@@ -1,9 +1,14 @@
1
- const _when_fns = new WeakMap();
2
- const _as_when_tuples = ([k,v]) => [k, Promise.resolve(v)];
1
+ const _when_fns = /* #__PURE__ */ new WeakMap();
2
+ function _when_resolve(p, val) {
3
+ let fn = _when_fns.get(p);
4
+ _when_fns.delete(p);
5
+ fn?.(val);}
3
6
 
4
7
  class WhenMap extends Map {
5
8
  constructor(entries) {
6
- super(entries &&= Array.from(entries, _as_when_tuples)); }
9
+ super();
10
+ for (let [k,v] of entries||[])
11
+ this.set(k,v);}
7
12
 
8
13
  has(key) {
9
14
  let p = super.get(key);
@@ -16,30 +21,25 @@ class WhenMap extends Map {
16
21
  p = new Promise(fn => f=fn);
17
22
  _when_fns.set(p, f);
18
23
  super.set(key, p);
19
- this.on_ref?.(key, p);}
24
+ this.ref?.(key, p);}
20
25
  return p}
21
26
 
27
+ // ref(key, p) ::
28
+
22
29
  set(key, val) {
23
- // resolve promise
24
- _pop_when(this.when(key))?.(val);
30
+ _when_resolve(this.when(key),val);
25
31
  return this}
26
32
 
27
33
  delete(key) {
28
34
  // resolve outstanding promise, if exists
29
- _pop_when(super.get(key))?.();
35
+ _when_resolve(super.get(key));
30
36
  return super.delete(key)}
31
37
 
32
38
  clear() {
33
39
  // resolve all outstanding promises
34
40
  for (let p of this.values()) {
35
- _pop_when(p)?.();}
41
+ _when_resolve(p);}
36
42
  super.clear();} }
37
43
 
38
-
39
- function _pop_when(p) {
40
- let f = _when_fns.get(p);
41
- _when_fns.delete(p);
42
- return f}
43
-
44
44
  export { WhenMap, WhenMap as default };
45
45
  //# sourceMappingURL=whenmap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"whenmap.js","sources":["../code/whenmap.jsy"],"sourcesContent":["const _when_fns = new WeakMap()\nconst _as_when_tuples = ([k,v]) => [k, Promise.resolve(v)]\n\nexport class WhenMap extends Map ::\n constructor(entries) ::\n super @ entries &&= Array.from(entries, _as_when_tuples)\n\n has(key) ::\n let p = super.get(key)\n return p ? _when_fns.has(p) ? 1 : true : false\n\n get get() :: return this.when\n when(key) ::\n let p = super.get(key), f\n if ! p ::\n p = new Promise(fn => f=fn)\n _when_fns.set(p, f)\n super.set(key, p)\n this.on_ref?.(key, p)\n return p\n\n set(key, val) ::\n // resolve promise\n _pop_when(this.when(key))?.(val)\n return this\n\n delete(key) ::\n // resolve outstanding promise, if exists\n _pop_when(super.get(key))?.()\n return super.delete(key)\n\n clear() ::\n // resolve all outstanding promises\n for let p of this.values() ::\n _pop_when(p)?.()\n super.clear()\n\nexport default WhenMap\n\n\nfunction _pop_when(p) ::\n let f = _when_fns.get(p)\n _when_fns.delete(p)\n return f\n\n"],"names":[],"mappings":"AAAA,MAAA,SAAA,GAAA,IAAA,OAAA;AACA,MAAA,eAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,OAAA,CAAA,OAAA,CAAA,CAAA,CAAA;;AAEA,MAAA,OAAA,SAAA,GAAA,CAAA;AACE,EAAA,WAAA,CAAA,OAAA,EAAA;IACE,KAAA,CAAO,OAAA,KAAA,KAAA,CAAA,IAAA,CAAA,OAAA,EAAA,eAAA,CAAA,EAAA;;AAET,EAAA,GAAA,CAAA,GAAA,EAAA;AACE,IAAA,IAAA,CAAA,GAAA,KAAA,CAAA,GAAA,CAAA,GAAA;AACA,IAAA,OAAA,CAAA,GAAA,SAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,GAAA,KAAA;;EAEF,IAAA,GAAA,GAAA,CAAY,OAAA,IAAA,CAAA,IAAA;AACZ,EAAA,IAAA,CAAA,GAAA,EAAA;AACE,IAAA,IAAA,CAAA,GAAA,KAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACG,IAAA,IAAA,EAAA,CAAA,EAAA;AACD,MAAA,CAAA,GAAA,IAAA,OAAA,CAAA,EAAA,IAAA,CAAA,CAAA,EAAA;AACA,MAAA,SAAA,CAAA,GAAA,CAAA,CAAA,EAAA,CAAA;AACA,MAAA,KAAA,CAAA,GAAA,CAAA,GAAA,EAAA,CAAA;AACA,MAAA,IAAA,CAAA,MAAA,GAAA,GAAA,EAAA,CAAA,EAAA;AACF,IAAA,OAAA,CAAA;;AAEF,EAAA,GAAA,CAAA,GAAA,EAAA,GAAA,EAAA;;AAEE,IAAA,SAAA,CAAA,IAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,GAAA,GAAA;AACA,IAAA,OAAA,IAAA;;AAEF,EAAA,MAAA,CAAA,GAAA,EAAA;;AAEE,IAAA,SAAA,CAAA,KAAA,CAAA,GAAA,CAAA,GAAA,CAAA,CAAA;AACA,IAAA,OAAA,KAAA,CAAA,MAAA,CAAA,GAAA,CAAA;;AAEF,EAAA,KAAA,GAAA;;AAEK,IAAA,KAAA,IAAA,CAAA,IAAA,IAAA,CAAA,MAAA,EAAA,EAAA;AACD,MAAA,SAAA,CAAA,CAAA,CAAA,KAAA;AACF,IAAA,KAAA,CAAA,KAAA,GAAA,CAAA;;;AAKJ,SAAA,SAAA,CAAA,CAAA,EAAA;AACE,EAAA,IAAA,CAAA,GAAA,SAAA,CAAA,GAAA,CAAA,CAAA;AACA,EAAA,SAAA,CAAA,MAAA,CAAA,CAAA;AACA,EAAA,OAAA,CAAA;;;;"}
1
+ {"version":3,"file":"whenmap.js","sources":["../code/whenmap.jsy"],"sourcesContent":["const _when_fns = /* #__PURE__ */ new WeakMap()\nfunction _when_resolve(p, val) ::\n let fn = _when_fns.get(p)\n _when_fns.delete(p)\n fn?.(val)\n\nexport class WhenMap extends Map ::\n constructor(entries) ::\n super()\n for (let [k,v] of entries||[])\n this.set(k,v)\n\n has(key) ::\n let p = super.get(key)\n return p ? _when_fns.has(p) ? 1 : true : false\n\n get get() :: return this.when\n when(key) ::\n let p = super.get(key), f\n if ! p ::\n p = new Promise(fn => f=fn)\n _when_fns.set(p, f)\n super.set(key, p)\n this.ref?.(key, p)\n return p\n\n // ref(key, p) ::\n\n set(key, val) ::\n _when_resolve(this.when(key),val)\n return this\n\n delete(key) ::\n // resolve outstanding promise, if exists\n _when_resolve(super.get(key))\n return super.delete(key)\n\n clear() ::\n // resolve all outstanding promises\n for let p of this.values() ::\n _when_resolve(p)\n super.clear()\n\nexport default WhenMap\n\n"],"names":[],"mappings":"AAAA,MAAA,SAAA,mBAAiC,IAAA,OAAA;AACjC,SAAA,aAAA,CAAA,CAAA,EAAA,GAAA,EAAA;AACE,EAAA,IAAA,EAAA,GAAA,SAAA,CAAA,GAAA,CAAA,CAAA;AACA,EAAA,SAAA,CAAA,MAAA,CAAA,CAAA;AACA,EAAA,EAAA,GAAA,GAAA,EAAA;;AAEF,MAAA,OAAA,SAAA,GAAA,CAAA;AACE,EAAA,WAAA,CAAA,OAAA,EAAA;AACE,IAAA,KAAA;AACA,IAAA,KAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,OAAA,EAAA,EAAA;AACE,MAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,EAAA;;AAEJ,EAAA,GAAA,CAAA,GAAA,EAAA;AACE,IAAA,IAAA,CAAA,GAAA,KAAA,CAAA,GAAA,CAAA,GAAA;AACA,IAAA,OAAA,CAAA,GAAA,SAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,GAAA,KAAA;;EAEF,IAAA,GAAA,GAAA,CAAY,OAAA,IAAA,CAAA,IAAA;AACZ,EAAA,IAAA,CAAA,GAAA,EAAA;AACE,IAAA,IAAA,CAAA,GAAA,KAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACG,IAAA,IAAA,EAAA,CAAA,EAAA;AACD,MAAA,CAAA,GAAA,IAAA,OAAA,CAAA,EAAA,IAAA,CAAA,CAAA,EAAA;AACA,MAAA,SAAA,CAAA,GAAA,CAAA,CAAA,EAAA,CAAA;AACA,MAAA,KAAA,CAAA,GAAA,CAAA,GAAA,EAAA,CAAA;AACA,MAAA,IAAA,CAAA,GAAA,GAAA,GAAA,EAAA,CAAA,EAAA;AACF,IAAA,OAAA,CAAA;;;;AAIF,EAAA,GAAA,CAAA,GAAA,EAAA,GAAA,EAAA;AACE,IAAA,aAAA,CAAA,IAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,GAAA;AACA,IAAA,OAAA,IAAA;;AAEF,EAAA,MAAA,CAAA,GAAA,EAAA;;AAEE,IAAA,aAAA,CAAA,KAAA,CAAA,GAAA,CAAA,GAAA,CAAA;AACA,IAAA,OAAA,KAAA,CAAA,MAAA,CAAA,GAAA,CAAA;;AAEF,EAAA,KAAA,GAAA;;AAEK,IAAA,KAAA,IAAA,CAAA,IAAA,IAAA,CAAA,MAAA,EAAA,EAAA;AACD,MAAA,aAAA,CAAA,CAAA,EAAA;AACF,IAAA,KAAA,CAAA,KAAA,GAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- const e=new WeakMap,t=([e,t])=>[e,Promise.resolve(t)];class r extends Map{constructor(e){super(e&&=Array.from(e,t))}has(t){let r=super.get(t);return!!r&&(!e.has(r)||1)}get get(){return this.when}when(t){let r,s=super.get(t);return s||(s=new Promise((e=>r=e)),e.set(s,r),super.set(t,s),this.on_ref?.(t,s)),s}set(e,t){return s(this.when(e))?.(t),this}delete(e){return s(super.get(e))?.(),super.delete(e)}clear(){for(let e of this.values())s(e)?.();super.clear()}}function s(t){let r=e.get(t);return e.delete(t),r}export{r as WhenMap,r as default};
1
+ const e=new WeakMap;function t(t,s){let r=e.get(t);e.delete(t),r?.(s)}class s extends Map{constructor(e){super();for(let[t,s]of e||[])this.set(t,s)}has(t){let s=super.get(t);return!!s&&(!e.has(s)||1)}get get(){return this.when}when(t){let s,r=super.get(t);return r||(r=new Promise((e=>s=e)),e.set(r,s),super.set(t,r),this.ref?.(t,r)),r}set(e,s){return t(this.when(e),s),this}delete(e){return t(super.get(e)),super.delete(e)}clear(){for(let e of this.values())t(e);super.clear()}}export{s as WhenMap,s as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whenmap",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "",
5
5
  "license": "BSD-2-Clause",
6
6
  "author": "Shane Holloway <shane.holloway@ieee.org>",
@@ -28,12 +28,12 @@
28
28
  },
29
29
  "devDependencies": {
30
30
  "@rollup/plugin-terser": "^0.4.4",
31
- "chai": "^5.2.0",
32
- "rollup": "^4.44.0",
31
+ "chai": "^6.2.2",
32
+ "rollup": "^4.54.0",
33
33
  "rollup-plugin-jsy": "^1.9.4"
34
34
  },
35
35
  "optionalDependencies": {
36
- "vite": "^6.3.5"
36
+ "vite": "^7.3.0"
37
37
  },
38
38
  "scripts": {
39
39
  "clean": "rm ./esm/* || true",