ctx-core 5.15.0 → 5.16.0

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,5 +1,5 @@
1
1
  import type { Be, be_config_T, Ctx, ctx__be_T, ctx__get_T, ctx__set_T, Ctx_wide_T, } from '../be_/index.js'
2
- import { lock_memosig_T } from '../rmemo/index.js'
2
+ import { lock_memosig_T, sig_T } from '../rmemo/index.js'
3
3
  export declare function be_lock_memosig_triple_<
4
4
  val_T,
5
5
  ns_T extends string = '',
@@ -13,9 +13,7 @@ export declare function be_lock_memosig_triple_<
13
13
  ctx_T extends Ctx = Ctx_wide_T<ns_T>,
14
14
  >(
15
15
  rmemo__new:(ctx:ctx_T, memosig:_sig_T)=>val_T,
16
- ...subscriber_a_THEN_config:
17
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[]]
18
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[], config:be_config_T<ns_T>]
16
+ config?:be_config_T<ns_T>
19
17
  ):be_lock_memosig_triple_T<val_T, ns_T, _sig_T, ctx_T>
20
18
  export type be_lock_memosig_triple_T<
21
19
  val_T,
@@ -26,4 +24,8 @@ export type be_lock_memosig_triple_T<
26
24
  ctx__be_T<ctx_T, _sig_T, ns_T>,
27
25
  ctx__get_T<ctx_T, val_T>,
28
26
  ctx__set_T<ctx_T, val_T>,
29
- ]
27
+ ]&{
28
+ add<add_val_T>(
29
+ add_def:(ctx:ctx_T, sig:_sig_T, prev_val:add_val_T|undefined)=>add_val_T
30
+ ):be_lock_memosig_triple_T<val_T, ns_T, _sig_T, ctx_T>
31
+ }
@@ -6,33 +6,34 @@ import { be_ } from '../be_/index.js'
6
6
  import { lock_memosig_ } from '../rmemo/index.js'
7
7
  /**
8
8
  * @param {Be<sig_T>|be__val__new_T<unknown>}be_OR_val__new
9
- * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
9
+ * @param {be_config_T}[config]
10
10
  * @returns {be_lock_memosig_triple_T}
11
11
  * @private
12
12
  */
13
13
  export function be_lock_memosig_triple_(
14
14
  be_OR_val__new,
15
- ...subscriber_a_THEN_config
15
+ config
16
16
  ) {
17
- let config =
18
- typeof subscriber_a_THEN_config[subscriber_a_THEN_config.length - 1] === 'object'
19
- ? subscriber_a_THEN_config.pop()
20
- : 0
17
+ let add_def_a = []
21
18
  /** @type {Be<sig_T>} */
22
19
  let be =
23
20
  be_OR_val__new.is_be
24
21
  ? be_OR_val__new
25
22
  : be_(ctx=>
26
- lock_memosig_(
27
- memo=>be_OR_val__new(ctx, memo),
28
- ...subscriber_a_THEN_config.map(subscriber=>
29
- sig=>subscriber(ctx, sig))),
23
+ add_def_a.reduce(
24
+ (memosig, add_def)=>memosig.add((...arg_a)=>add_def(ctx, ...arg_a)),
25
+ lock_memosig_(memo=>be_OR_val__new(ctx, memo))),
30
26
  config)
31
- return [
27
+ let be_lock_memosig_triple = [
32
28
  be,
33
29
  ctx=>be(ctx)(),
34
30
  (ctx, val)=>{
35
31
  be(ctx)._ = val
36
32
  },
37
33
  ]
34
+ be_lock_memosig_triple.add = add_def=>{
35
+ add_def_a.push(add_def)
36
+ return be_lock_memosig_triple
37
+ }
38
+ return be_lock_memosig_triple
38
39
  }
@@ -67,11 +67,11 @@ test('be_lock_memosig_triple_|+id|+ns', ()=>{
67
67
  /* eslint-enable @typescript-eslint/no-unused-vars */
68
68
  return base_(ctx) + 1
69
69
  },
70
- (ctx, foobar$)=>{
71
- subscriber_count++
72
- subscriber_dep__set(ctx, subscriber_count + foobar$())
73
- },
74
- { id: 'foobar', ns: 'test_ns' })
70
+ { id: 'foobar', ns: 'test_ns' }
71
+ ).add((ctx, foobar$)=>{
72
+ subscriber_count++
73
+ subscriber_dep__set(ctx, subscriber_count + foobar$())
74
+ })
75
75
  equal(subscriber_count, 0)
76
76
  equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 2)
77
77
  equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 2)
@@ -89,13 +89,13 @@ test('be_lock_memosig_triple_|+id|+ns', ()=>{
89
89
  equal(subscriber_count, 2)
90
90
  equal(subscriber_dep_(ctx), 7)
91
91
  base__set(ctx, 2)
92
- equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 5)
93
- equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 5)
94
- equal(foobar$_(ctx)._, 5)
95
- equal(foobar_(ctx), 5)
96
- equal(subscriber_count, 2)
97
- equal((ctx.s['test_ns'].get('foobar')![0] as sig_T<number>)._, 5)
98
- equal(subscriber_dep_(ctx), 7)
92
+ equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 3)
93
+ equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 3)
94
+ equal(foobar$_(ctx)._, 3)
95
+ equal(foobar_(ctx), 3)
96
+ equal(subscriber_count, 3)
97
+ equal((ctx.s['test_ns'].get('foobar')![0] as sig_T<number>)._, 3)
98
+ equal(subscriber_dep_(ctx), 6)
99
99
  })
100
100
  test('be_lock_memosig_triple_|+be', ()=>{
101
101
  const ctx = ns_ctx__new('test_ns')
@@ -116,11 +116,12 @@ test('be_lock_memosig_triple_|+be', ()=>{
116
116
  type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
117
117
  /* eslint-enable @typescript-eslint/no-unused-vars */
118
118
  const foobar$ =
119
- memosig_(()=>base_(ctx) + 1,
120
- foobar$=>{
121
- foobar$()
122
- subscriber_count++
123
- }) as custom_sig_T
119
+ memosig_(
120
+ ()=>base_(ctx) + 1
121
+ ).add(foobar$=>{
122
+ foobar$()
123
+ subscriber_count++
124
+ }) as custom_sig_T
124
125
  foobar$.custom = 'custom-val'
125
126
  return foobar$
126
127
  }, { id: 'foobar', ns: 'test_ns' }))
@@ -13,9 +13,7 @@ export declare function be_memo_pair_<
13
13
  ctx_T extends Ctx = Ctx_wide_T<ns_T>
14
14
  >(
15
15
  rmemo__new:(ctx:ctx_T, memo:_memo_T&{ _:val_T })=>val_T,
16
- ...subscriber_a_THEN_config:
17
- |[...((ctx:ctx_T, memosig:sig_T<val_T>)=>unknown)[]]
18
- |[...((ctx:ctx_T, memosig:sig_T<val_T>)=>unknown)[], config:be_config_T]
16
+ config?:be_config_T
19
17
  ):be_memo_pair_T<val_T, ns_T, _memo_T, ctx_T>
20
18
  export type be_memo_pair_T<
21
19
  val_T,
@@ -25,4 +23,8 @@ export type be_memo_pair_T<
25
23
  > = [
26
24
  ctx__be_T<ctx_T, _memo_T, ns_T>,
27
25
  ctx__get_T<ctx_T, val_T>,
28
- ]
26
+ ]&{
27
+ add<add_val_T>(
28
+ add_def:(ctx:ctx_T, sig:sig_T<val_T>, prev_val:add_val_T|undefined)=>add_val_T
29
+ ):be_memo_pair_T<val_T, ns_T, _memo_T, ctx_T>
30
+ }
@@ -5,32 +5,34 @@ import { be_ } from '../be_/index.js'
5
5
  import { memo_ } from '../rmemo/index.js'
6
6
  /**
7
7
  * @param {Be|be__val__new_T<unknown>}be_OR_val__new
8
- * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
8
+ * @param {be_config_T}[config]
9
9
  * @returns {be_memo_pair_T}
10
10
  * @private
11
11
  */
12
12
  export function be_memo_pair_(
13
13
  be_OR_val__new,
14
- ...subscriber_a_THEN_config
14
+ config
15
15
  ) {
16
- let config =
17
- typeof subscriber_a_THEN_config[subscriber_a_THEN_config.length - 1] === 'object'
18
- && subscriber_a_THEN_config.pop()
16
+ let add_def_a = []
19
17
  /** @type {Be} */
20
18
  let be =
21
19
  be_OR_val__new.is_be
22
20
  ? be_OR_val__new
23
21
  : be_(ctx=>
24
- memo_(
25
- memo=>be_OR_val__new(ctx, memo),
26
- ...subscriber_a_THEN_config.map(subscriber=>
27
- memo=>subscriber(ctx, memo))),
22
+ add_def_a.reduce(
23
+ (memo, add_def)=>memo.add((...arg_a)=>add_def(ctx, ...arg_a)),
24
+ memo_(memo=>be_OR_val__new(ctx, memo))),
28
25
  config)
29
- return [
26
+ let be_memo_pair = [
30
27
  be,
31
28
  ctx=>be(ctx)._,
32
29
  (ctx, val)=>{
33
30
  be(ctx)._ = val
34
31
  },
35
32
  ]
33
+ be_memo_pair.add = add_def=>{
34
+ add_def_a.push(add_def)
35
+ return be_memo_pair
36
+ }
37
+ return be_memo_pair
36
38
  }
@@ -55,15 +55,16 @@ test('be_memo_pair_|+id|+ns|+oninit|+subscriber_a', ()=>{
55
55
  const [
56
56
  foobar$_,
57
57
  foobar_,
58
- ] = be_memo_pair_<number, 'test_ns'>(ctx=>base_(ctx) + 1,
59
- (ctx, foobar$)=>{
60
- /* eslint-disable @typescript-eslint/no-unused-vars */
61
- type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
62
- /* eslint-enable @typescript-eslint/no-unused-vars */
63
- subscriber_count++
64
- subscriber_dep__set(ctx, subscriber_count + foobar$())
65
- },
66
- { id: 'foobar', ns: 'test_ns' })
58
+ ] = be_memo_pair_<number, 'test_ns'>(
59
+ ctx=>base_(ctx) + 1,
60
+ { id: 'foobar', ns: 'test_ns' }
61
+ ).add((ctx, foobar$)=>{
62
+ /* eslint-disable @typescript-eslint/no-unused-vars */
63
+ type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
64
+ /* eslint-enable @typescript-eslint/no-unused-vars */
65
+ subscriber_count++
66
+ subscriber_dep__set(ctx, subscriber_count + foobar$())
67
+ })
67
68
  equal(subscriber_count, 0)
68
69
  equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 2)
69
70
  equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 2)
@@ -96,7 +97,7 @@ test('be_memo_pair_|subscriber|receives a memosig to set the value of the memo',
96
97
  type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<''>>>
97
98
  /* eslint-enable @typescript-eslint/no-unused-vars */
98
99
  return 1
99
- }, (ctx, foobar$)=>{
100
+ }).add((ctx, foobar$)=>{
100
101
  foobar$._ = base_(ctx) + 1
101
102
  })
102
103
  equal(foobar$_(ctx)._, 2)
@@ -123,9 +124,8 @@ test('be_memo_pair_|be', ()=>{
123
124
  type test__ctx = Expect<Equal<typeof _ctx, Ctx_wide_T<'test_ns'>>>
124
125
  /* eslint-enable @typescript-eslint/no-unused-vars */
125
126
  const foobar$ = memo_(
126
- ()=>base_(ctx) + 1,
127
- ()=>subscriber_count++
128
- ) as custom_memo_T
127
+ ()=>base_(ctx) + 1
128
+ ).add(()=>subscriber_count++) as custom_memo_T
129
129
  equal(_ctx.s.test_ns, ctx.s.test_ns)
130
130
  foobar$.custom = 'custom-val'
131
131
  return foobar$
@@ -13,9 +13,7 @@ export declare function be_memosig_triple_<
13
13
  ctx_T extends Ctx = Ctx_wide_T<ns_T>
14
14
  >(
15
15
  rmemo__new:(ctx:ctx_T, memosig:_sig_T)=>val_T,
16
- ...subscriber_a_THEN_config:
17
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[]]
18
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[], config:be_config_T<ns_T>]
16
+ config?:be_config_T<ns_T>
19
17
  ):be_memosig_triple_T<val_T, ns_T, _sig_T, ctx_T>
20
18
  export type be_memosig_triple_T<
21
19
  val_T,
@@ -26,4 +24,8 @@ export type be_memosig_triple_T<
26
24
  ctx__be_T<ctx_T, _sig_T, ns_T>,
27
25
  ctx__get_T<ctx_T, val_T>,
28
26
  ctx__set_T<ctx_T, val_T>,
29
- ]
27
+ ]&{
28
+ add<add_val_T>(
29
+ add_def:(ctx:ctx_T, sig:_sig_T, prev_val:add_val_T|undefined)=>add_val_T
30
+ ):be_memosig_triple_T<val_T, ns_T, _sig_T, ctx_T>
31
+ }
@@ -67,14 +67,14 @@ test('be_memosig_triple_|+id|+ns', ()=>{
67
67
  /* eslint-enable @typescript-eslint/no-unused-vars */
68
68
  return base_(ctx) + 1
69
69
  },
70
- (ctx, foobar$)=>{
71
- /* eslint-disable @typescript-eslint/no-unused-vars */
72
- type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
73
- /* eslint-enable @typescript-eslint/no-unused-vars */
74
- subscriber_count++
75
- subscriber_dep__set(ctx, subscriber_count + foobar$())
76
- },
77
- { id: 'foobar', ns: 'test_ns' })
70
+ { id: 'foobar', ns: 'test_ns' }
71
+ ).add((ctx, foobar$)=>{
72
+ /* eslint-disable @typescript-eslint/no-unused-vars */
73
+ type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
74
+ /* eslint-enable @typescript-eslint/no-unused-vars */
75
+ subscriber_count++
76
+ subscriber_dep__set(ctx, subscriber_count + foobar$())
77
+ })
78
78
  equal(subscriber_count, 0)
79
79
  equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 2)
80
80
  equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 2)
@@ -119,11 +119,12 @@ test('be_memosig_triple_|+be', ()=>{
119
119
  type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
120
120
  /* eslint-enable @typescript-eslint/no-unused-vars */
121
121
  const foobar$ =
122
- memosig_(()=>base_(ctx) + 1,
123
- foobar$=>{
124
- foobar$()
125
- subscriber_count++
126
- }) as custom_sig_T
122
+ memosig_(
123
+ ()=>base_(ctx) + 1
124
+ ).add(foobar$=>{
125
+ foobar$()
126
+ subscriber_count++
127
+ }) as custom_sig_T
127
128
  foobar$.custom = 'custom-val'
128
129
  return foobar$
129
130
  }, { id: 'foobar', ns: 'test_ns' }))
@@ -13,17 +13,19 @@ export declare function be_sig_triple_<
13
13
  ctx_T extends Ctx = Ctx_wide_T<ns_T>,
14
14
  >(
15
15
  val__new:(ctx:ctx_T)=>val_T,
16
- ...subscriber_a_THEN_config:
17
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[]]
18
- |[...((ctx:ctx_T, sig:_sig_T)=>unknown)[], config:be_config_T<ns_T>]
16
+ config?:be_config_T<ns_T>
19
17
  ):be_sig_triple_T<val_T, ns_T, _sig_T, ctx_T>
20
18
  export type be_sig_triple_T<
21
19
  val_T,
22
- source extends string = '',
20
+ ns_T extends string = '',
23
21
  _sig_T extends sig_T<val_T> = sig_T<val_T>,
24
- ctx_T extends Ctx = Ctx_wide_T<source>
22
+ ctx_T extends Ctx = Ctx_wide_T<ns_T>
25
23
  > = [
26
- ctx__be_T<ctx_T, _sig_T, source>,
24
+ ctx__be_T<ctx_T, _sig_T, ns_T>,
27
25
  ctx__get_T<ctx_T, val_T>,
28
26
  ctx__set_T<ctx_T, val_T>
29
- ]
27
+ ]&{
28
+ add<add_val_T>(
29
+ add_def:(ctx:ctx_T, sig:_sig_T, prev_val:add_val_T|undefined)=>add_val_T
30
+ ):be_sig_triple_T<val_T, ns_T, _sig_T, ctx_T>
31
+ }
@@ -5,32 +5,34 @@ import { be_ } from '../be_/index.js'
5
5
  import { sig_ } from '../rmemo/index.js'
6
6
  /**
7
7
  * @param {Be<sig_T>|be__val__new_T<unknown>}be_OR_val__new
8
- * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
8
+ * @param {be_config_T}[config]
9
9
  * @returns {be_sig_triple_T}
10
10
  * @private
11
11
  */
12
12
  export function be_sig_triple_(
13
13
  be_OR_val__new,
14
- ...subscriber_a_THEN_config
14
+ config
15
15
  ) {
16
- let config =
17
- typeof subscriber_a_THEN_config[subscriber_a_THEN_config.length - 1] === 'object'
18
- && subscriber_a_THEN_config.pop()
16
+ let add_def_a = []
19
17
  /** @ype {Be<sig_T>} */
20
18
  let be =
21
19
  be_OR_val__new.is_be
22
20
  ? be_OR_val__new
23
21
  : be_(ctx=>
24
- sig_(
25
- be_OR_val__new(ctx),
26
- ...subscriber_a_THEN_config.map(subscriber=>
27
- sig=>subscriber(ctx, sig))),
22
+ add_def_a.reduce(
23
+ (sig, add_def)=>sig.add((...arg_a)=>add_def(ctx, ...arg_a)),
24
+ sig_(be_OR_val__new(ctx))),
28
25
  config)
29
- return [
26
+ let be_sig_triple = [
30
27
  be,
31
28
  ctx=>be(ctx)(),
32
29
  (ctx, val)=>{
33
30
  be(ctx)._ = val
34
31
  },
35
32
  ]
33
+ be_sig_triple.add = add_def=>{
34
+ add_def_a.push(add_def)
35
+ return be_sig_triple
36
+ }
37
+ return be_sig_triple
36
38
  }
@@ -43,11 +43,11 @@ test('be_sig_triple_|+id|+ns', ()=>{
43
43
  type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
44
44
  /* eslint-enable @typescript-eslint/no-unused-vars */
45
45
  return 1
46
- },
47
- (ctx, foobar$)=>{
48
- subscriber_count++
49
- subscriber_dep__set(ctx, subscriber_count + foobar$())
50
- }, { id: 'foobar', ns: 'test_ns' })
46
+ }, { id: 'foobar', ns: 'test_ns' }
47
+ ).add((ctx, foobar$)=>{
48
+ subscriber_count++
49
+ subscriber_dep__set(ctx, subscriber_count + foobar$())
50
+ })
51
51
  equal(subscriber_count, 0)
52
52
  equal(foobar$_(ns_ctx__new(ctx__new(), ctx))._, 1)
53
53
  equal(foobar_(ns_ctx__new(ctx__new(), ctx)), 1)
@@ -78,7 +78,9 @@ test('be_sig_triple_|+be', ()=>{
78
78
  type test_ctx = Expect<Equal<typeof ctx, Ctx_wide_T<'test_ns'>>>
79
79
  /* eslint-enable @typescript-eslint/no-unused-vars */
80
80
  const foobar$ =
81
- sig_(1, ()=>subscriber_count++) as custom_sig_T
81
+ sig_(
82
+ 1
83
+ ).add(()=>subscriber_count++) as custom_sig_T
82
84
  foobar$.custom = 'custom-val'
83
85
  return foobar$ as custom_sig_T
84
86
  }, { id: 'foobar', ns: 'test_ns' }))
@@ -4,6 +4,7 @@ export const [
4
4
  is_development$_,
5
5
  is_development_,
6
6
  ] = be_memo_pair_(ctx=>
7
- NODE_ENV_(ctx) === 'dev' || NODE_ENV_(ctx) === 'development',
7
+ NODE_ENV_(ctx) === 'dev'
8
+ || NODE_ENV_(ctx) === 'development',
8
9
  { id: 'is_development' })
9
10
  export { is_development$_ as is_development__ }
@@ -4,7 +4,8 @@ export const [
4
4
  is_production$_,
5
5
  is_production_,
6
6
  ] = be_memo_pair_(ctx=>
7
- NODE_ENV_(ctx) === 'prod' || NODE_ENV_(ctx) === 'production',
7
+ NODE_ENV_(ctx) === 'prod'
8
+ || NODE_ENV_(ctx) === 'production',
8
9
  { id: 'is_production' })
9
10
  export {
10
11
  is_production$_ as is_production__,
@@ -1,23 +1,11 @@
1
1
  /// <reference lib="es2021" />
2
- export declare function memo_<val_T>(
3
- def:memo_def_T<val_T>,
4
- ...subscriber_a:memo_subscriber_T<val_T>[]
5
- ):memo_T<val_T>
6
- export declare function sig_<val_T>(
7
- init_val:val_T,
8
- ...subscriber_a:memo_subscriber_T<val_T>[]
9
- ):sig_T<val_T>
10
- export declare function memosig_<val_T>(
11
- def:memo_def_T<val_T>,
12
- ...subscriber_a:memo_subscriber_T<val_T>[]
13
- ):sig_T<val_T>
14
- export declare function lock_memosig_<val_T>(
15
- def:memo_def_T<val_T>,
16
- ...subscriber_a:memo_subscriber_T<val_T>[]
17
- ):sig_T<val_T>
2
+ export declare function memo_<val_T>(def:memo_def_T<val_T>):memo_T<val_T>
3
+ export declare function sig_<val_T>(init_val:val_T):sig_T<val_T>
4
+ export declare function memosig_<val_T>(def:memo_def_T<val_T>):sig_T<val_T>
5
+ export declare function lock_memosig_<val_T>(def:memo_def_T<val_T>):sig_T<val_T>
18
6
  export declare function rmemo__on(rmemo:rmemo_T<unknown>):void
19
7
  export declare function rmemo__off(rmemo:rmemo_T<unknown>):void
20
- export declare function rmemo__subscribe(rmemo:rmemo_T<unknown>, listener:()=>unknown):()=>void
8
+ export declare function rmemo__add(rmemo:rmemo_T<unknown>, listener:()=>unknown):()=>void
21
9
  export type rmemo_T<val_T> = memo_T<val_T>|sig_T<val_T>|lock_memosig_T<val_T>
22
10
  export type circular_rmemo_T = circular_memo_T|circular_sig_T|circular_lock_memosig_T
23
11
  export type memo_T<val_T> = (()=>val_T)&{
@@ -25,23 +13,29 @@ export type memo_T<val_T> = (()=>val_T)&{
25
13
  readonly val:val_T
26
14
  r?:WeakRef<()=>val_T>
27
15
  memor:WeakRef<()=>val_T>[]
28
- b?:[unknown, memo_T<unknown>][]
16
+ a?:rmemo_a_T[]
17
+ add<add_val_T>(add_def:(sig:sig_T<val_T>, prev_val:add_val_T|undefined)=>add_val_T):memo_T<val_T>
18
+ }
19
+ export interface circular_memo_T extends memo_T<circular_memo_T> {
29
20
  }
30
- export interface circular_memo_T extends memo_T<circular_memo_T> {}
31
21
  export type sig_T<val_T> = (()=>val_T)&{
32
22
  _:val_T
33
23
  readonly val:val_T
34
24
  r?:WeakRef<()=>val_T>
35
25
  memor:WeakRef<()=>val_T>[]
36
- b?:[unknown, memo_T<unknown>][]
26
+ a?:rmemo_a_T[]
27
+ add<add_val_T>(fn:(sig:sig_T<val_T>, prev_val:add_val_T|undefined)=>add_val_T):sig_T<val_T>
28
+ }
29
+ export interface circular_sig_T extends sig_T<circular_sig_T> {
37
30
  }
38
- export interface circular_sig_T extends sig_T<circular_sig_T> {}
39
31
  export type lock_memosig_T<val_T> = sig_T<val_T>&{
40
32
  lock?:0|1
41
33
  }
42
- export interface circular_lock_memosig_T extends lock_memosig_T<circular_lock_memosig_T> {}
34
+ export interface circular_lock_memosig_T extends lock_memosig_T<circular_lock_memosig_T> {
35
+ }
43
36
  export type rmemo_val_T<sig_T> = sig_T extends { ():infer val_T }
44
37
  ? val_T
45
38
  : unknown
46
39
  export type memo_def_T<val_T> = (sig:sig_T<val_T>)=>val_T
47
- export type memo_subscriber_T<val_T> = (sig:sig_T<val_T>)=>unknown
40
+ export type rmemo_a_T = [memo_T<unknown>, unknown]
41
+ export type rmemo_add_T<val_T, SV> = (sig:sig_T<val_T>, old_val:SV|undefined)=>SV
@@ -5,11 +5,11 @@ let cur_memo
5
5
  let queue = new Set
6
6
  /**
7
7
  * @param {memo_def_T}memo_def
8
- * @param {memo_subscriber_T<unknown>[]}subscriber_a
8
+ * @param {rmemo_add_T<unknown>[]}add_def_a
9
9
  * @returns {memo_T}
10
10
  * @private
11
11
  */
12
- export function memo_(memo_def, ...subscriber_a) {
12
+ export function memo_(memo_def, ...add_def_a) {
13
13
  let memo = ()=>{
14
14
  if (!('val' in memo)) {
15
15
  memo.f()
@@ -17,9 +17,9 @@ export function memo_(memo_def, ...subscriber_a) {
17
17
  if (cur_memo) {
18
18
  if (!memo.memor.includes(cur_memo.r ||= new WeakRef(cur_memo.f))) memo.memor.push(cur_memo.r)
19
19
  if (cur_memo.f.l < memo.f.l + 1) cur_memo.f.l = memo.f.l + 1
20
- // conditional in r calls this r_memo
20
+ // memo is called by cur_memo's conditional execution...next change to memo will notify cur_memo
21
21
  cur_memo.f.s.push(memo)
22
- // prevent this rmemo from GC while cur_memo is still active
22
+ // prevent memo from GC while cur_memo still has a strong reference
23
23
  if (!cur_memo.f.S.includes(memo)) cur_memo.f.S.push(memo)
24
24
  }
25
25
  return memo.val
@@ -27,46 +27,52 @@ export function memo_(memo_def, ...subscriber_a) {
27
27
  Object.defineProperty(memo, '_', {
28
28
  get: memo,
29
29
  set: val=>{
30
- let run_queue
31
30
  if (memo.val !== val) {
32
- run_queue = !queue.size
33
31
  memo.memor = memo.memor.filter(r=>{
34
32
  r = r.deref()
35
- if (r && r.s.includes(memo)) { // if conditional r refresh calls this r_memo, add to queue
33
+ if (r && r.s.includes(memo)) { // if added by cur_memo.f.s.push(memo), add to queue
36
34
  queue.add(r)
37
35
  }
38
36
  return r
39
37
  })
40
38
  }
41
39
  memo.val = val
42
- if (!memo.b) {
43
- memo.b = subscriber_a.map(subscriber=>memo_(()=>subscriber(memo)))
44
- memo.b = memo.b.map(subscriber_memo=>[subscriber_memo(), subscriber_memo])
40
+ if (!memo.a) {
41
+ memo.a = []
42
+ add_def_a.map(memo.add)
45
43
  }
46
- if (run_queue) {
47
- cur_refresh_loop:for (let cur_refresh of queue) {
48
- queue.delete(cur_refresh)
49
- for (let queue_refresh of queue) {
50
- if (cur_refresh.l > queue_refresh.l) {
51
- queue.add(cur_refresh)
52
- continue cur_refresh_loop
53
- }
44
+ cur_refresh_loop:for (let cur_refresh of queue) {
45
+ queue.delete(cur_refresh)
46
+ for (let queue_refresh of queue) {
47
+ if (cur_refresh.l > queue_refresh.l) {
48
+ queue.add(cur_refresh)
49
+ continue cur_refresh_loop
54
50
  }
55
- cur_refresh()
56
51
  }
52
+ cur_refresh()
57
53
  }
58
54
  },
59
55
  })
56
+ memo.add = add_def=>{
57
+ if (memo.a) {
58
+ let pair = [memo_(()=>pair[1] = add_def(memo, pair[1]))]
59
+ memo.a.push(pair)
60
+ pair[0]()
61
+ } else {
62
+ add_def_a.push(add_def)
63
+ }
64
+ return memo
65
+ }
60
66
  memo.f = ()=>{
61
67
  let prev_memo = cur_memo
62
68
  cur_memo = memo
63
- memo.f.s = []
69
+ memo.f.s = [] // reset references in memo_def conditional execution path...see cur_memo.f.s.push(memo)
64
70
  try {
65
71
  memo._ = memo_def(memo)
66
72
  } catch (err) {
67
73
  console.error(err)
68
74
  }
69
- cur_memo = prev_memo // finally is not necessary...catch does not throw
75
+ cur_memo = prev_memo // catch does not throw
70
76
  }
71
77
  memo.f.l = 0
72
78
  memo.f.s = []
@@ -77,7 +83,7 @@ export function memo_(memo_def, ...subscriber_a) {
77
83
  export { memo_ as memosig_ }
78
84
  /**
79
85
  * @param {memo_def_T}memo_def
80
- * @param {memo_subscriber_T<unknown>[]}subscriber_a
86
+ * @param {rmemo_add_T<unknown>[]}subscriber_a
81
87
  * @returns {sig_T}
82
88
  * @private
83
89
  */
@@ -98,17 +104,16 @@ export function lock_memosig_(memo_def, ...subscriber_a) {
98
104
  }
99
105
  /**
100
106
  * @param {unknown}init_val
101
- * @param {memo_subscriber_T[]}subscriber_a
107
+ * @param {rmemo_add_T[]}add_a
102
108
  * @returns {sig_T}
103
109
  * @private
104
110
  */
105
- export function sig_(init_val, ...subscriber_a) {
106
- return memo_(sig=>{
107
- return 'val' in sig
111
+ export function sig_(init_val, ...add_a) {
112
+ return memo_(sig=>
113
+ 'val' in sig
108
114
  ? sig.val
109
- : init_val
110
- },
111
- ...subscriber_a)
115
+ : init_val,
116
+ ...add_a)
112
117
  }
113
118
  /**
114
119
  * Call the rmemo & enable updates from it's parents.
@@ -132,20 +137,21 @@ export function rmemo__off(rmemo) {
132
137
  }
133
138
  }
134
139
  /**
135
- * Bind reactive listener onto the given memo to prevent GC.
136
- * The listener can autosubscribe to any rmemo.
137
- * Returns an "off" function which deactivates the reactive listener & removes the GC binding from the given memo.
140
+ * Bind reactive add_def onto the given memo to prevent GC.
141
+ * The add_def can autosubscribe to any rmemo.
142
+ * Returns an "off" function which deactivates the reactive add_def & removes the GC binding from the given memo.
138
143
  * @param {rmemo_T}memo
139
- * @param {()=>unknown}listener
144
+ * @param {()=>unknown}add_def
140
145
  * @returns {()=>void}
141
146
  */
142
- export function rmemo__subscribe(memo, listener) {
143
- let listener_memo = memo_(()=>listener())
144
- listener_memo()
145
- memo.b ??= []
146
- memo.b.push(listener_memo)
147
+ export function rmemo__add(memo, add_def) {
148
+ let pair
149
+ memo.add(()=>{
150
+ pair = memo.a[memo.a.length - 1]
151
+ return add_def(memo)
152
+ })
147
153
  return ()=>{
148
- rmemo__off(listener_memo)
149
- memo.b.splice(memo.b.indexOf(listener_memo), 1)
154
+ rmemo__off(pair[0])
155
+ memo.a.splice(memo.a.indexOf(pair), 1)
150
156
  }
151
157
  }