@typed/fx 1.20.0 → 1.20.2

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.
Files changed (103) hide show
  1. package/dist/cjs/Fx.js +5 -1
  2. package/dist/cjs/Fx.js.map +1 -1
  3. package/dist/cjs/Idle.js +8 -6
  4. package/dist/cjs/Idle.js.map +1 -1
  5. package/dist/cjs/Push.js.map +1 -1
  6. package/dist/cjs/RefHashMap.js.map +1 -1
  7. package/dist/cjs/RefSubject.js +13 -9
  8. package/dist/cjs/RefSubject.js.map +1 -1
  9. package/dist/cjs/Subject.js +7 -3
  10. package/dist/cjs/Subject.js.map +1 -1
  11. package/dist/cjs/Versioned.js.map +1 -1
  12. package/dist/cjs/internal/DeferredRef.js +1 -1
  13. package/dist/cjs/internal/DeferredRef.js.map +1 -1
  14. package/dist/cjs/internal/core.js +2 -1
  15. package/dist/cjs/internal/core.js.map +1 -1
  16. package/dist/cjs/internal/diff.js +28 -20
  17. package/dist/cjs/internal/diff.js.map +1 -1
  18. package/dist/cjs/internal/helpers.js +5 -1
  19. package/dist/cjs/internal/helpers.js.map +1 -1
  20. package/dist/cjs/internal/keyed.js +13 -14
  21. package/dist/cjs/internal/keyed.js.map +1 -1
  22. package/dist/cjs/internal/share.js +4 -1
  23. package/dist/cjs/internal/share.js.map +1 -1
  24. package/dist/dts/Emitter.d.ts +1 -1
  25. package/dist/dts/Emitter.d.ts.map +1 -1
  26. package/dist/dts/Form.d.ts +2 -2
  27. package/dist/dts/Form.d.ts.map +1 -1
  28. package/dist/dts/Fx.d.ts.map +1 -1
  29. package/dist/dts/Guard.d.ts +1 -1
  30. package/dist/dts/Guard.d.ts.map +1 -1
  31. package/dist/dts/Idle.d.ts.map +1 -1
  32. package/dist/dts/Match.d.ts +2 -2
  33. package/dist/dts/Match.d.ts.map +1 -1
  34. package/dist/dts/Pull.d.ts +1 -1
  35. package/dist/dts/Pull.d.ts.map +1 -1
  36. package/dist/dts/Push.d.ts +4 -1
  37. package/dist/dts/Push.d.ts.map +1 -1
  38. package/dist/dts/RefArray.d.ts +1 -1
  39. package/dist/dts/RefArray.d.ts.map +1 -1
  40. package/dist/dts/RefChunk.d.ts +1 -1
  41. package/dist/dts/RefChunk.d.ts.map +1 -1
  42. package/dist/dts/RefHashMap.d.ts +1 -1
  43. package/dist/dts/RefHashMap.d.ts.map +1 -1
  44. package/dist/dts/RefHashSet.d.ts +1 -1
  45. package/dist/dts/RefHashSet.d.ts.map +1 -1
  46. package/dist/dts/RefSubject.d.ts +24 -4
  47. package/dist/dts/RefSubject.d.ts.map +1 -1
  48. package/dist/dts/Subject.d.ts +1 -1
  49. package/dist/dts/Subject.d.ts.map +1 -1
  50. package/dist/dts/Versioned.d.ts +1 -1
  51. package/dist/dts/Versioned.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/diff.d.ts +20 -16
  54. package/dist/dts/internal/diff.d.ts.map +1 -1
  55. package/dist/dts/internal/helpers.d.ts +2 -1
  56. package/dist/dts/internal/helpers.d.ts.map +1 -1
  57. package/dist/dts/internal/keyed.d.ts.map +1 -1
  58. package/dist/dts/internal/share.d.ts.map +1 -1
  59. package/dist/esm/Fx.js +5 -1
  60. package/dist/esm/Fx.js.map +1 -1
  61. package/dist/esm/Idle.js +8 -6
  62. package/dist/esm/Idle.js.map +1 -1
  63. package/dist/esm/Push.js.map +1 -1
  64. package/dist/esm/RefHashMap.js.map +1 -1
  65. package/dist/esm/RefSubject.js +11 -9
  66. package/dist/esm/RefSubject.js.map +1 -1
  67. package/dist/esm/Subject.js +7 -3
  68. package/dist/esm/Subject.js.map +1 -1
  69. package/dist/esm/Versioned.js.map +1 -1
  70. package/dist/esm/internal/DeferredRef.js +1 -1
  71. package/dist/esm/internal/DeferredRef.js.map +1 -1
  72. package/dist/esm/internal/core.js +2 -1
  73. package/dist/esm/internal/core.js.map +1 -1
  74. package/dist/esm/internal/diff.js +26 -16
  75. package/dist/esm/internal/diff.js.map +1 -1
  76. package/dist/esm/internal/helpers.js +5 -1
  77. package/dist/esm/internal/helpers.js.map +1 -1
  78. package/dist/esm/internal/keyed.js +14 -15
  79. package/dist/esm/internal/keyed.js.map +1 -1
  80. package/dist/esm/internal/share.js +4 -1
  81. package/dist/esm/internal/share.js.map +1 -1
  82. package/package.json +8 -8
  83. package/src/Emitter.ts +1 -1
  84. package/src/Form.ts +2 -2
  85. package/src/Fx.ts +5 -4
  86. package/src/Guard.ts +1 -1
  87. package/src/Idle.ts +9 -13
  88. package/src/Match.ts +2 -2
  89. package/src/Pull.ts +1 -1
  90. package/src/Push.ts +6 -1
  91. package/src/RefArray.ts +1 -1
  92. package/src/RefChunk.ts +1 -1
  93. package/src/RefHashMap.ts +3 -1
  94. package/src/RefHashSet.ts +1 -1
  95. package/src/RefSubject.ts +54 -25
  96. package/src/Subject.ts +24 -6
  97. package/src/Versioned.ts +4 -2
  98. package/src/internal/DeferredRef.ts +1 -1
  99. package/src/internal/core.ts +5 -1
  100. package/src/internal/diff.ts +56 -42
  101. package/src/internal/helpers.ts +7 -2
  102. package/src/internal/keyed.ts +19 -21
  103. package/src/internal/share.ts +6 -1
@@ -2,45 +2,55 @@ import type { Equivalence } from "effect"
2
2
  import * as Equal from "effect/Equal"
3
3
  import { identity } from "effect/Function"
4
4
 
5
- export type DiffResult<A> = ReadonlyArray<Diff<A>>
5
+ export type DiffResult<A, B> = ReadonlyArray<Diff<A, B>>
6
6
 
7
- export type Diff<A> = Add<A> | Remove<A> | Update<A> | Moved<A>
7
+ export type Diff<A, B> = Add<A, B> | Remove<A, B> | Update<A, B> | Moved<A, B>
8
8
 
9
- export interface Add<A> {
9
+ export interface Add<A, B> {
10
10
  readonly _tag: "Add"
11
11
  readonly index: number
12
12
  readonly value: A
13
+ readonly key: B
13
14
  }
14
15
 
15
- export const add = <A>(value: A, index: number): Add<A> => ({ _tag: "Add", index, value })
16
+ export const add = <A, B>(value: A, index: number, key: B): Add<A, B> => ({ _tag: "Add", index, value, key })
16
17
 
17
- export interface Remove<A> {
18
+ export interface Remove<A, B> {
18
19
  readonly _tag: "Remove"
19
20
  readonly index: number
20
21
  readonly value: A
22
+ readonly key: B
21
23
  }
22
24
 
23
- export const remove = <A>(value: A, index: number): Remove<A> => ({ _tag: "Remove", index, value })
25
+ export const remove = <A, B>(value: A, index: number, key: B): Remove<A, B> => ({ _tag: "Remove", index, value, key })
24
26
 
25
- export interface Update<A> {
27
+ export interface Update<A, B> {
26
28
  readonly _tag: "Update"
27
29
  readonly index: number
28
30
  readonly value: A
31
+ readonly key: B
29
32
  }
30
33
 
31
- export const update = <A>(value: A, index: number): Update<A> => ({ _tag: "Update", index, value })
34
+ export const update = <A, B>(value: A, index: number, key: B): Update<A, B> => ({ _tag: "Update", index, value, key })
32
35
 
33
- export interface Moved<A> {
36
+ export interface Moved<A, B> {
34
37
  readonly _tag: "Moved"
35
38
  readonly index: number
36
39
  readonly to: number
37
40
  readonly value: A
41
+ readonly key: B
38
42
  }
39
43
 
40
- export const moved = <A>(value: A, from: number, to: number): Moved<A> => ({ _tag: "Moved", index: from, to, value })
44
+ export const moved = <A, B>(value: A, from: number, to: number, key: B): Moved<A, B> => ({
45
+ _tag: "Moved",
46
+ index: from,
47
+ to,
48
+ value,
49
+ key
50
+ })
41
51
 
42
- export type DiffOptions<A> = {
43
- readonly getKey: (a: A) => PropertyKey
52
+ export type DiffOptions<A, B extends PropertyKey> = {
53
+ readonly getKey: (a: A) => B
44
54
  readonly eq?: Equivalence.Equivalence<A>
45
55
  readonly keyMap?: Map<PropertyKey, number>
46
56
  }
@@ -48,43 +58,45 @@ export type DiffOptions<A> = {
48
58
  export function diff<A extends PropertyKey>(
49
59
  oldValue: ReadonlyArray<A>,
50
60
  newValue: ReadonlyArray<A>,
51
- options?: Omit<DiffOptions<A>, "getKey">
52
- ): DiffResult<A>
61
+ options?: Omit<DiffOptions<A, A>, "getKey">
62
+ ): DiffResult<A, A>
53
63
 
54
- export function diff<A>(
64
+ export function diff<A, B extends PropertyKey>(
55
65
  oldValue: ReadonlyArray<A>,
56
66
  newValue: ReadonlyArray<A>,
57
- options: DiffOptions<A>
58
- ): DiffResult<A>
67
+ options: DiffOptions<A, B>
68
+ ): DiffResult<A, B>
59
69
 
60
- export function diff<A>(
70
+ export function diff<A, B extends PropertyKey>(
61
71
  a: ReadonlyArray<A>,
62
72
  b: ReadonlyArray<A>,
63
- options: Partial<DiffOptions<A>> = {}
64
- ): DiffResult<A> {
73
+ options: Partial<DiffOptions<A, B>> = {}
74
+ ): DiffResult<A, B> {
65
75
  const { eq = Equal.equals, getKey = identity as any } = options
66
- const diff: Array<Diff<A>> = []
76
+ const diff: Array<Diff<A, B>> = []
67
77
  const oldKeyMap = options.keyMap ?? getKeyMap(a, getKey)
68
78
  const keyMap = getKeyMap(b, getKey)
69
79
 
70
80
  for (let i = 0; i < a.length; ++i) {
71
81
  const aValue = a[i]
72
- const bIndex = keyMap.get(getKey(aValue))
82
+ const key = getKey(aValue)
83
+ const bIndex = keyMap.get(key)
73
84
  if (bIndex === undefined) {
74
- diff.push(remove(aValue, i))
85
+ diff.push(remove(aValue, i, key))
75
86
  }
76
87
  }
77
88
 
78
89
  for (let i = 0; i < b.length; ++i) {
79
90
  const bValue = b[i]
80
- const aIndex = oldKeyMap.get(getKey(bValue))
91
+ const key = getKey(bValue)
92
+ const aIndex = oldKeyMap.get(key)
81
93
  if (aIndex === undefined) {
82
- diff.push(add(bValue, i))
94
+ diff.push(add(bValue, i, key))
83
95
  } else {
84
96
  if (aIndex !== i) {
85
- diff.push(moved(bValue, aIndex, i))
97
+ diff.push(moved(bValue, aIndex, i, key))
86
98
  } else if (!eq(a[aIndex], bValue)) {
87
- diff.push(update(bValue, i))
99
+ diff.push(update(bValue, i, key))
88
100
  }
89
101
  }
90
102
  }
@@ -95,48 +107,50 @@ export function diff<A>(
95
107
  export function diffIterator<A extends PropertyKey>(
96
108
  oldValue: ReadonlyArray<A>,
97
109
  newValue: ReadonlyArray<A>,
98
- options?: Omit<DiffOptions<A>, "getKey">
99
- ): Generator<Diff<A>>
110
+ options?: Omit<DiffOptions<A, A>, "getKey">
111
+ ): Generator<Diff<A, A>>
100
112
 
101
- export function diffIterator<A>(
113
+ export function diffIterator<A, B extends PropertyKey>(
102
114
  oldValue: ReadonlyArray<A>,
103
115
  newValue: ReadonlyArray<A>,
104
- options: DiffOptions<A>
105
- ): Generator<Diff<A>>
116
+ options: DiffOptions<A, B>
117
+ ): Generator<Diff<A, B>>
106
118
 
107
- export function* diffIterator<A>(
119
+ export function* diffIterator<A, B extends PropertyKey>(
108
120
  a: ReadonlyArray<A>,
109
121
  b: ReadonlyArray<A>,
110
- options: Partial<DiffOptions<A>> = {}
111
- ): Generator<Diff<A>> {
122
+ options: Partial<DiffOptions<A, B>> = {}
123
+ ): Generator<Diff<A, B>> {
112
124
  const { eq = Equal.equals, getKey = identity as any } = options
113
125
  const oldKeyMap = options.keyMap ?? getKeyMap(a, getKey)
114
126
  const keyMap = getKeyMap(b, getKey)
115
127
 
116
128
  for (let i = 0; i < a.length; ++i) {
117
129
  const aValue = a[i]
118
- const bIndex = keyMap.get(getKey(aValue))
130
+ const key = getKey(aValue)
131
+ const bIndex = keyMap.get(key)
119
132
  if (bIndex === undefined) {
120
- yield remove(aValue, i)
133
+ yield remove(aValue, i, key)
121
134
  }
122
135
  }
123
136
 
124
137
  for (let i = 0; i < b.length; ++i) {
125
138
  const bValue = b[i]
126
- const aIndex = oldKeyMap.get(getKey(bValue))
139
+ const key = getKey(bValue)
140
+ const aIndex = oldKeyMap.get(key)
127
141
  if (aIndex === undefined) {
128
- yield add(bValue, i)
142
+ yield add(bValue, i, key)
129
143
  } else {
130
144
  if (aIndex !== i) {
131
- yield moved(bValue, aIndex, i)
145
+ yield moved(bValue, aIndex, i, key)
132
146
  } else if (!eq(a[aIndex], bValue)) {
133
- yield update(bValue, i)
147
+ yield update(bValue, i, key)
134
148
  }
135
149
  }
136
150
  }
137
151
  }
138
152
 
139
- function sortDiff<A>(a: Diff<A>, b: Diff<A>): number {
153
+ function sortDiff<A, B>(a: Diff<A, B>, b: Diff<A, B>): number {
140
154
  if (a._tag === "Remove" && b._tag !== "Remove") return -1
141
155
  if (b._tag === "Remove") return 1
142
156
  return a.index - b.index
@@ -85,7 +85,7 @@ export function withScopedFork<R, E, A>(
85
85
 
86
86
  export function makeForkInScope(scope: Scope.Scope) {
87
87
  return <R, E, A>(effect: Effect.Effect<R, E, A>) =>
88
- matchEffectPrimitive<R, E, A, Effect.Effect<Exclude<R, Scope.Scope>, never, Fiber.Fiber<E, A>>>(effect, {
88
+ matchEffectPrimitive<R, E, A, Effect.Effect<R, never, Fiber.Fiber<E, A>>>(effect, {
89
89
  Success: (a) => Effect.succeed(Fiber.succeed(a)),
90
90
  Failure: (cause) => Effect.succeed(Fiber.failCause(cause)),
91
91
  Sync: (f) =>
@@ -100,7 +100,7 @@ export function makeForkInScope(scope: Scope.Scope) {
100
100
  Right: (a) => Effect.succeed(Fiber.succeed(a)),
101
101
  Some: (a) => Effect.succeed(Fiber.succeed(a)),
102
102
  None: (e) => Effect.succeed(Fiber.fail(e)),
103
- Otherwise: (eff) => Effect.forkIn(Effect.provideService(eff, Scope.Scope, scope), scope)
103
+ Otherwise: (eff) => Effect.forkIn(eff, scope)
104
104
  })
105
105
  }
106
106
 
@@ -454,6 +454,11 @@ export class RingBuffer<A> {
454
454
  )
455
455
  }
456
456
  }
457
+
458
+ clear() {
459
+ this._buffer = Array(this.capacity)
460
+ this._size = 0
461
+ }
457
462
  }
458
463
 
459
464
  export function awaitScopeClose(scope: Scope.Scope) {
@@ -1,5 +1,5 @@
1
1
  import type { FiberId } from "effect"
2
- import { Context, Effect, ExecutionStrategy, Option, Scope } from "effect"
2
+ import { Context, Effect, ExecutionStrategy, Exit, Option, Scope } from "effect"
3
3
  import type { Fx, KeyedOptions } from "../Fx.js"
4
4
  import * as RefSubject from "../RefSubject.js"
5
5
  import * as Sink from "../Sink.js"
@@ -40,14 +40,14 @@ class Keyed<R, E, A, B extends PropertyKey, R2, E2, C> extends FxBase<R | R2 | S
40
40
  interface KeyedState<A, B extends PropertyKey, C> {
41
41
  readonly entries: Map<B, KeyedEntry<A, C>>
42
42
  readonly indices: Map<number, B>
43
- previousKeys: ReadonlyArray<B>
43
+ previousValues: ReadonlyArray<A>
44
44
  }
45
45
 
46
46
  function emptyKeyedState<A, B extends PropertyKey, C>(): KeyedState<A, B, C> {
47
47
  return {
48
48
  entries: new Map(),
49
49
  indices: new Map(),
50
- previousKeys: []
50
+ previousValues: []
51
51
  }
52
52
  }
53
53
 
@@ -65,15 +65,14 @@ function runKeyed<R, E, A, B extends PropertyKey, R2, E2, C, R3>(
65
65
 
66
66
  function diffAndPatch(values: ReadonlyArray<A>) {
67
67
  return Effect.gen(function*(_) {
68
- const previous = state.previousKeys
69
- const keys = values.map(options.getKey)
70
- state.previousKeys = keys
68
+ const previous = state.previousValues
69
+ state.previousValues = values
71
70
 
72
71
  let added = false
73
72
  let done = false
74
73
  let scheduled = false
75
74
 
76
- for (const patch of diffIterator(previous, keys)) {
75
+ for (const patch of diffIterator(previous, values, options)) {
77
76
  if (patch._tag === "Remove") {
78
77
  yield* _(removeValue(state, patch))
79
78
  } else if (patch._tag === "Add") {
@@ -133,11 +132,11 @@ class KeyedEntry<A, C> {
133
132
  }
134
133
 
135
134
  function getReadyIndices<A, B extends PropertyKey, C>(
136
- { entries, indices, previousKeys }: KeyedState<A, B, C>
135
+ { entries, indices, previousValues }: KeyedState<A, B, C>
137
136
  ): ReadonlyArray<C> {
138
137
  const output: Array<C> = []
139
138
 
140
- for (let i = 0; i < previousKeys.length; ++i) {
139
+ for (let i = 0; i < previousValues.length; ++i) {
141
140
  const key = indices.get(i)
142
141
 
143
142
  if (key === undefined) break
@@ -156,7 +155,7 @@ function getReadyIndices<A, B extends PropertyKey, C>(
156
155
  function addValue<A, B extends PropertyKey, C, R2, E2, E, R3, D>(
157
156
  { entries, indices }: KeyedState<A, B, C>,
158
157
  values: ReadonlyArray<A>,
159
- patch: Add<B>,
158
+ patch: Add<A, B>,
160
159
  id: FiberId.FiberId,
161
160
  parentScope: Scope.Scope,
162
161
  options: KeyedOptions<A, B, R2, E2, C>,
@@ -172,23 +171,22 @@ function addValue<A, B extends PropertyKey, C, R2, E2, E, R3, D>(
172
171
  scope: childScope,
173
172
  id
174
173
  }))
174
+ yield* _(Scope.addFinalizer(childScope, ref.interrupt))
175
175
 
176
176
  const entry = new KeyedEntry<A, C>(
177
177
  value,
178
178
  patch.index,
179
179
  Option.none(),
180
180
  ref,
181
- ref.interrupt
181
+ Scope.close(childScope, Exit.interrupt(id))
182
182
  )
183
183
 
184
- entries.set(patch.value, entry)
185
- indices.set(patch.index, patch.value)
186
-
187
- yield* _(Scope.addFinalizer(childScope, ref.interrupt))
184
+ entries.set(patch.key, entry)
185
+ indices.set(patch.index, patch.key)
188
186
 
189
187
  yield* _(
190
188
  Effect.forkIn(
191
- options.onValue(ref, patch.value).run(Sink.make(
189
+ options.onValue(ref, patch.key).run(Sink.make(
192
190
  (cause) => sink.onFailure(cause),
193
191
  (output) => {
194
192
  entry.output = Option.some(output)
@@ -202,9 +200,9 @@ function addValue<A, B extends PropertyKey, C, R2, E2, E, R3, D>(
202
200
  })
203
201
  }
204
202
 
205
- function removeValue<A, B extends PropertyKey, C>({ entries, indices }: KeyedState<A, B, C>, patch: Remove<B>) {
206
- const interrupt = entries.get(patch.value)!.interrupt
207
- entries.delete(patch.value)
203
+ function removeValue<A, B extends PropertyKey, C>({ entries, indices }: KeyedState<A, B, C>, patch: Remove<A, B>) {
204
+ const interrupt = entries.get(patch.key)!.interrupt
205
+ entries.delete(patch.key)
208
206
  indices.delete(patch.index)
209
207
  return interrupt
210
208
  }
@@ -212,9 +210,9 @@ function removeValue<A, B extends PropertyKey, C>({ entries, indices }: KeyedSta
212
210
  function updateValue<A, B extends PropertyKey, C>(
213
211
  { entries, indices }: KeyedState<A, B, C>,
214
212
  values: ReadonlyArray<A>,
215
- patch: Update<B> | Moved<B>
213
+ patch: Update<A, B> | Moved<A, B>
216
214
  ) {
217
- const key = patch.value
215
+ const key = patch.key
218
216
  const entry = entries.get(key)!
219
217
 
220
218
  if (patch._tag === "Moved") {
@@ -57,7 +57,12 @@ export class Share<R, E, A, R2> extends FxBase<R | R2 | Scope.Scope, E, A> {
57
57
  return Effect.suspend(() => {
58
58
  if (this._RefCount.increment() === 1) {
59
59
  return this.i0.run(this.i1).pipe(
60
- Effect.onExit(() => Effect.sync(() => MutableRef.set(this._FxFiber, Option.none()))),
60
+ Effect.onExit(() =>
61
+ Effect.suspend(() => {
62
+ MutableRef.set(this._FxFiber, Option.none())
63
+ return this.i1.interrupt
64
+ })
65
+ ),
61
66
  Effect.interruptible,
62
67
  Effect.forkDaemon,
63
68
  Effect.tap((fiber) => Effect.sync(() => MutableRef.set(this._FxFiber, Option.some(fiber)))),