@typed/fx 0.0.6 → 0.0.8

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 (220) hide show
  1. package/.eslintcache +1 -1
  2. package/cjs/Env/Env.d.ts +9 -1
  3. package/cjs/Env/Env.d.ts.map +1 -1
  4. package/cjs/Env/Env.js +32 -5
  5. package/cjs/Env/Env.js.map +1 -1
  6. package/cjs/FiberContext/FiberContext.js +1 -1
  7. package/cjs/FiberContext/FiberContext.js.map +1 -1
  8. package/cjs/FiberRef/builtins.d.ts +4 -1
  9. package/cjs/FiberRef/builtins.d.ts.map +1 -1
  10. package/cjs/FiberRef/builtins.js +40 -13
  11. package/cjs/FiberRef/builtins.js.map +1 -1
  12. package/cjs/FiberRuntime/FiberRuntime.js +1 -1
  13. package/cjs/FiberRuntime/FiberRuntime.js.map +1 -1
  14. package/cjs/Fx/Fx.d.ts +1 -1
  15. package/cjs/Fx/Fx.d.ts.map +1 -1
  16. package/cjs/Fx/Fx.js +1 -2
  17. package/cjs/Fx/Fx.js.map +1 -1
  18. package/cjs/Stream/Stream.d.ts +0 -4
  19. package/cjs/Stream/Stream.d.ts.map +1 -1
  20. package/cjs/Stream/Stream.js.map +1 -1
  21. package/cjs/Stream/bimap.d.ts +29 -1
  22. package/cjs/Stream/bimap.d.ts.map +1 -1
  23. package/cjs/Stream/bimap.js +98 -3
  24. package/cjs/Stream/bimap.js.map +1 -1
  25. package/cjs/Stream/delay.d.ts +4 -0
  26. package/cjs/Stream/delay.d.ts.map +1 -0
  27. package/cjs/Stream/delay.js +30 -0
  28. package/cjs/Stream/delay.js.map +1 -0
  29. package/cjs/Stream/flatMap.d.ts.map +1 -1
  30. package/cjs/Stream/flatMap.js +10 -22
  31. package/cjs/Stream/flatMap.js.map +1 -1
  32. package/cjs/Stream/flatMapConcurrently.d.ts +1 -0
  33. package/cjs/Stream/flatMapConcurrently.d.ts.map +1 -1
  34. package/cjs/Stream/flatMapConcurrently.js +6 -1
  35. package/cjs/Stream/flatMapConcurrently.js.map +1 -1
  36. package/cjs/Stream/foldMap.d.ts +11 -0
  37. package/cjs/Stream/foldMap.d.ts.map +1 -0
  38. package/cjs/Stream/foldMap.js +67 -0
  39. package/cjs/Stream/foldMap.js.map +1 -0
  40. package/cjs/Stream/fromArray.d.ts +2 -0
  41. package/cjs/Stream/fromArray.d.ts.map +1 -0
  42. package/cjs/Stream/fromArray.js +12 -0
  43. package/cjs/Stream/fromArray.js.map +1 -0
  44. package/cjs/Stream/fromFx.d.ts +9 -0
  45. package/cjs/Stream/fromFx.d.ts.map +1 -1
  46. package/cjs/Stream/fromFx.js +14 -3
  47. package/cjs/Stream/fromFx.js.map +1 -1
  48. package/cjs/Stream/hkt.d.ts +24 -1
  49. package/cjs/Stream/hkt.d.ts.map +1 -1
  50. package/cjs/Stream/hkt.js +43 -5
  51. package/cjs/Stream/hkt.js.map +1 -1
  52. package/cjs/Stream/hold.d.ts.map +1 -1
  53. package/cjs/Stream/hold.js +2 -2
  54. package/cjs/Stream/hold.js.map +1 -1
  55. package/cjs/Stream/index.d.ts +6 -1
  56. package/cjs/Stream/index.d.ts.map +1 -1
  57. package/cjs/Stream/index.js +6 -1
  58. package/cjs/Stream/index.js.map +1 -1
  59. package/cjs/Stream/orElse.d.ts +1 -1
  60. package/cjs/Stream/orElse.d.ts.map +1 -1
  61. package/cjs/Stream/orElse.js +7 -20
  62. package/cjs/Stream/orElse.js.map +1 -1
  63. package/cjs/Stream/provide.d.ts +8 -0
  64. package/cjs/Stream/provide.d.ts.map +1 -0
  65. package/cjs/Stream/provide.js +42 -0
  66. package/cjs/Stream/provide.js.map +1 -0
  67. package/cjs/Stream/run.d.ts +2 -2
  68. package/cjs/Stream/run.d.ts.map +1 -1
  69. package/cjs/Stream/run.js +1 -1
  70. package/cjs/Stream/run.js.map +1 -1
  71. package/cjs/Stream/setFiberRefLocally.d.ts.map +1 -1
  72. package/cjs/Stream/setFiberRefLocally.js +6 -4
  73. package/cjs/Stream/setFiberRefLocally.js.map +1 -1
  74. package/cjs/Stream/skipRepeats.d.ts +5 -0
  75. package/cjs/Stream/skipRepeats.d.ts.map +1 -0
  76. package/cjs/Stream/skipRepeats.js +36 -0
  77. package/cjs/Stream/skipRepeats.js.map +1 -0
  78. package/cjs/Stream/switchMap.d.ts.map +1 -1
  79. package/cjs/Stream/switchMap.js +9 -21
  80. package/cjs/Stream/switchMap.js.map +1 -1
  81. package/cjs/Supervisor/index.d.ts +2 -0
  82. package/cjs/Supervisor/index.d.ts.map +1 -1
  83. package/cjs/Supervisor/index.js +2 -0
  84. package/cjs/Supervisor/index.js.map +1 -1
  85. package/cjs/Supervisor/inheritFiberRefs.d.ts +2 -0
  86. package/cjs/Supervisor/inheritFiberRefs.d.ts.map +1 -0
  87. package/cjs/Supervisor/inheritFiberRefs.js +17 -0
  88. package/cjs/Supervisor/inheritFiberRefs.js.map +1 -0
  89. package/esm/Env/Env.d.ts +9 -1
  90. package/esm/Env/Env.d.ts.map +1 -1
  91. package/esm/Env/Env.js +8 -5
  92. package/esm/Env/Env.js.map +1 -1
  93. package/esm/FiberContext/FiberContext.js +1 -1
  94. package/esm/FiberContext/FiberContext.js.map +1 -1
  95. package/esm/FiberRef/builtins.d.ts +4 -1
  96. package/esm/FiberRef/builtins.d.ts.map +1 -1
  97. package/esm/FiberRef/builtins.js +36 -12
  98. package/esm/FiberRef/builtins.js.map +1 -1
  99. package/esm/FiberRuntime/FiberRuntime.js +1 -1
  100. package/esm/FiberRuntime/FiberRuntime.js.map +1 -1
  101. package/esm/Fx/Fx.d.ts +1 -1
  102. package/esm/Fx/Fx.d.ts.map +1 -1
  103. package/esm/Fx/Fx.js +1 -2
  104. package/esm/Fx/Fx.js.map +1 -1
  105. package/esm/Stream/Stream.d.ts +0 -4
  106. package/esm/Stream/Stream.d.ts.map +1 -1
  107. package/esm/Stream/Stream.js.map +1 -1
  108. package/esm/Stream/bimap.d.ts +29 -1
  109. package/esm/Stream/bimap.d.ts.map +1 -1
  110. package/esm/Stream/bimap.js +91 -2
  111. package/esm/Stream/bimap.js.map +1 -1
  112. package/esm/Stream/delay.d.ts +4 -0
  113. package/esm/Stream/delay.d.ts.map +1 -0
  114. package/esm/Stream/delay.js +26 -0
  115. package/esm/Stream/delay.js.map +1 -0
  116. package/esm/Stream/flatMap.d.ts.map +1 -1
  117. package/esm/Stream/flatMap.js +9 -21
  118. package/esm/Stream/flatMap.js.map +1 -1
  119. package/esm/Stream/flatMapConcurrently.d.ts +1 -0
  120. package/esm/Stream/flatMapConcurrently.d.ts.map +1 -1
  121. package/esm/Stream/flatMapConcurrently.js +4 -0
  122. package/esm/Stream/flatMapConcurrently.js.map +1 -1
  123. package/esm/Stream/foldMap.d.ts +11 -0
  124. package/esm/Stream/foldMap.d.ts.map +1 -0
  125. package/esm/Stream/foldMap.js +38 -0
  126. package/esm/Stream/foldMap.js.map +1 -0
  127. package/esm/Stream/fromArray.d.ts +2 -0
  128. package/esm/Stream/fromArray.d.ts.map +1 -0
  129. package/esm/Stream/fromArray.js +8 -0
  130. package/esm/Stream/fromArray.js.map +1 -0
  131. package/esm/Stream/fromFx.d.ts +9 -0
  132. package/esm/Stream/fromFx.d.ts.map +1 -1
  133. package/esm/Stream/fromFx.js +12 -2
  134. package/esm/Stream/fromFx.js.map +1 -1
  135. package/esm/Stream/hkt.d.ts +24 -1
  136. package/esm/Stream/hkt.d.ts.map +1 -1
  137. package/esm/Stream/hkt.js +41 -4
  138. package/esm/Stream/hkt.js.map +1 -1
  139. package/esm/Stream/hold.d.ts.map +1 -1
  140. package/esm/Stream/hold.js +2 -2
  141. package/esm/Stream/hold.js.map +1 -1
  142. package/esm/Stream/index.d.ts +6 -1
  143. package/esm/Stream/index.d.ts.map +1 -1
  144. package/esm/Stream/index.js +6 -1
  145. package/esm/Stream/index.js.map +1 -1
  146. package/esm/Stream/orElse.d.ts +1 -1
  147. package/esm/Stream/orElse.d.ts.map +1 -1
  148. package/esm/Stream/orElse.js +8 -21
  149. package/esm/Stream/orElse.js.map +1 -1
  150. package/esm/Stream/provide.d.ts +8 -0
  151. package/esm/Stream/provide.d.ts.map +1 -0
  152. package/esm/Stream/provide.js +13 -0
  153. package/esm/Stream/provide.js.map +1 -0
  154. package/esm/Stream/run.d.ts +2 -2
  155. package/esm/Stream/run.d.ts.map +1 -1
  156. package/esm/Stream/run.js +2 -2
  157. package/esm/Stream/run.js.map +1 -1
  158. package/esm/Stream/setFiberRefLocally.d.ts.map +1 -1
  159. package/esm/Stream/setFiberRefLocally.js +6 -4
  160. package/esm/Stream/setFiberRefLocally.js.map +1 -1
  161. package/esm/Stream/skipRepeats.d.ts +5 -0
  162. package/esm/Stream/skipRepeats.d.ts.map +1 -0
  163. package/esm/Stream/skipRepeats.js +31 -0
  164. package/esm/Stream/skipRepeats.js.map +1 -0
  165. package/esm/Stream/switchMap.d.ts.map +1 -1
  166. package/esm/Stream/switchMap.js +8 -20
  167. package/esm/Stream/switchMap.js.map +1 -1
  168. package/esm/Supervisor/index.d.ts +2 -0
  169. package/esm/Supervisor/index.d.ts.map +1 -1
  170. package/esm/Supervisor/index.js +2 -0
  171. package/esm/Supervisor/index.js.map +1 -1
  172. package/esm/Supervisor/inheritFiberRefs.d.ts +2 -0
  173. package/esm/Supervisor/inheritFiberRefs.d.ts.map +1 -0
  174. package/esm/Supervisor/inheritFiberRefs.js +14 -0
  175. package/esm/Supervisor/inheritFiberRefs.js.map +1 -0
  176. package/package.json +68 -22
  177. package/perf/Stream-filter-map-reduce.test.ts +103 -0
  178. package/src/Env/Env.ts +15 -5
  179. package/src/FiberContext/FiberContext.ts +1 -1
  180. package/src/FiberRef/builtins.ts +45 -2
  181. package/src/FiberRuntime/FiberRuntime.ts +3 -3
  182. package/src/Fx/Fx.ts +1 -1
  183. package/src/Stream/Stream.ts +0 -4
  184. package/src/Stream/bimap.ts +148 -3
  185. package/src/Stream/delay.ts +43 -0
  186. package/src/Stream/flatMap.ts +3 -16
  187. package/src/Stream/flatMapConcurrently.ts +4 -0
  188. package/src/Stream/foldMap.ts +88 -0
  189. package/src/Stream/fromArray.ts +8 -0
  190. package/src/Stream/fromFx.ts +16 -7
  191. package/src/Stream/hkt.ts +59 -10
  192. package/src/Stream/hold.ts +2 -2
  193. package/src/Stream/index.ts +6 -1
  194. package/src/Stream/orElse.ts +7 -23
  195. package/src/Stream/provide.test.ts +78 -0
  196. package/src/Stream/provide.ts +34 -0
  197. package/src/Stream/run.ts +6 -3
  198. package/src/Stream/setFiberRefLocally.ts +10 -16
  199. package/src/Stream/skipRepeats.ts +41 -0
  200. package/src/Stream/switchMap.ts +3 -17
  201. package/src/Supervisor/index.ts +2 -0
  202. package/src/Supervisor/inheritFiberRefs.ts +17 -0
  203. package/cjs/Stream/map.d.ts +0 -15
  204. package/cjs/Stream/map.d.ts.map +0 -1
  205. package/cjs/Stream/map.js +0 -33
  206. package/cjs/Stream/map.js.map +0 -1
  207. package/cjs/test.d.ts +0 -1
  208. package/cjs/test.d.ts.map +0 -1
  209. package/cjs/test.js +0 -2
  210. package/cjs/test.js.map +0 -1
  211. package/esm/Stream/map.d.ts +0 -15
  212. package/esm/Stream/map.d.ts.map +0 -1
  213. package/esm/Stream/map.js +0 -28
  214. package/esm/Stream/map.js.map +0 -1
  215. package/esm/test.d.ts +0 -1
  216. package/esm/test.d.ts.map +0 -1
  217. package/esm/test.js +0 -2
  218. package/esm/test.js.map +0 -1
  219. package/src/Stream/map.ts +0 -49
  220. package/src/test.ts +0 -0
@@ -1,21 +1,18 @@
1
1
  import { flow, pipe } from 'hkt-ts'
2
- import { isRight } from 'hkt-ts/Either'
3
- import { isJust } from 'hkt-ts/Maybe'
4
2
 
5
3
  import { Stream } from './Stream.js'
6
- import { MapStream } from './map.js'
4
+ import { MapStream } from './bimap.js'
7
5
 
8
6
  import { AtomicCounter, decrement, increment } from '@/Atomic/AtomicCounter.js'
9
7
  import { Cause } from '@/Cause/index.js'
10
8
  import { Env } from '@/Env/Env.js'
11
9
  import { FiberContext } from '@/FiberContext/FiberContext.js'
12
10
  import { Live } from '@/FiberId/FiberId.js'
13
- import * as FiberRefs from '@/FiberRefs/index.js'
14
11
  import * as Fx from '@/Fx/index.js'
15
12
  import { access, lazy, unit } from '@/Fx/index.js'
16
13
  import { Scheduler } from '@/Scheduler/Scheduler.js'
17
14
  import * as Sink from '@/Sink/Sink.js'
18
- import { None, and } from '@/Supervisor/Supervisor.js'
15
+ import * as Supervisor from '@/Supervisor/index.js'
19
16
 
20
17
  export function flatMap<A, R2, E2, B>(
21
18
  f: (a: A) => Stream<R2, E2, B>,
@@ -66,16 +63,6 @@ export class FlatMapStream<R, E, A, R2, E2, B> implements Stream<R | R2, E | E2,
66
63
  class FlatMapSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E | E2, A, E3> {
67
64
  protected _running = AtomicCounter()
68
65
  protected _ended = false
69
- protected supervisor = None.extend({
70
- onEnd: () => (fiber, exit) => {
71
- const parentContext = fiber.context.parent
72
-
73
- // Merge FiberRefs upon successful completion
74
- if (isRight(exit) && isJust(parentContext)) {
75
- FiberRefs.join(parentContext.value.fiberRefs, fiber.context.fiberRefs)
76
- }
77
- },
78
- })
79
66
 
80
67
  constructor(
81
68
  readonly sink: Sink.Sink<E | E2, B, E3>,
@@ -89,7 +76,7 @@ class FlatMapSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E | E2, A, E3> {
89
76
  event = (a: A) =>
90
77
  Fx.lazy(() => {
91
78
  const forked = this.context.fork({
92
- supervisor: and(this.supervisor)(this.context.supervisor),
79
+ supervisor: Supervisor.and(Supervisor.inheritFiberRefs)(this.context.supervisor),
93
80
  })
94
81
 
95
82
  increment(this._running)
@@ -28,3 +28,7 @@ export function mergeConcurrently(concurrencyLevel: NonNegativeInteger, __trace?
28
28
  flatMapConcurrently((a) => a, concurrencyLevel, __trace),
29
29
  )
30
30
  }
31
+
32
+ export function concatMap<A, R2, E2, B>(f: (a: A) => Stream<R2, E2, B>, __trace?: string) {
33
+ return flow(flatMapConcurrently(f, NonNegativeInteger(1), __trace))
34
+ }
@@ -0,0 +1,88 @@
1
+ import { Maybe, flow, pipe } from 'hkt-ts'
2
+ import * as Endo from 'hkt-ts/Endomorphism'
3
+ import { Identity } from 'hkt-ts/Typeclass/Identity'
4
+ import * as B from 'hkt-ts/boolean'
5
+
6
+ import { Stream } from './Stream.js'
7
+ import { FilterMapStream, MapStream } from './bimap.js'
8
+ import { observe } from './drain.js'
9
+ import { FromFxStream } from './fromFx.js'
10
+
11
+ import * as Fx from '@/Fx/index.js'
12
+ import { Scheduler } from '@/Scheduler/Scheduler.js'
13
+
14
+ export const filterFoldMap = <A>(I: Identity<A>) => {
15
+ const foldMap_ =
16
+ <B>(f: (b: B) => Maybe.Maybe<A>, __trace?: string) =>
17
+ <R, E>(stream: Stream<R, E, B>): Fx.Fx<R | Scheduler, E, A> => {
18
+ if (stream instanceof FromFxStream) {
19
+ return pipe(
20
+ stream.fx,
21
+ Fx.map(
22
+ flow(
23
+ f,
24
+ Maybe.match(
25
+ () => I.id,
26
+ (a) => I.concat(I.id, a),
27
+ ),
28
+ ),
29
+ ),
30
+ )
31
+ }
32
+
33
+ if (stream instanceof MapStream) {
34
+ return foldMap_(flow(stream.f, f), __trace)(stream.stream)
35
+ }
36
+
37
+ if (stream instanceof FilterMapStream) {
38
+ return foldMap_(flow(stream.f, Maybe.flatMap(f)), __trace)(stream.stream)
39
+ }
40
+
41
+ return filterFoldMapStream(I, f, stream, __trace)
42
+ }
43
+
44
+ return foldMap_
45
+ }
46
+
47
+ export const foldMap =
48
+ <A>(I: Identity<A>) =>
49
+ <B>(f: (b: B) => A) =>
50
+ filterFoldMap(I)(flow(f, Maybe.Just))
51
+
52
+ const filterFoldMapStream = <A, B, R, E>(
53
+ I: Identity<A>,
54
+ f: (b: B) => Maybe.Maybe<A>,
55
+ stream: Stream<R, E, B>,
56
+ __trace?: string,
57
+ ) =>
58
+ Fx.lazy(() => {
59
+ let acc = I.id
60
+
61
+ return pipe(
62
+ stream,
63
+ observe((b) =>
64
+ Fx.fromLazy(() => {
65
+ const maybe = f(b)
66
+
67
+ if (Maybe.isJust(maybe)) {
68
+ acc = I.concat(acc, maybe.value)
69
+ }
70
+ }),
71
+ ),
72
+ Fx.flatMap(Fx.join),
73
+ Fx.map(() => acc, __trace),
74
+ )
75
+ })
76
+
77
+ export const reduce = <A, B>(
78
+ f: (a: A, b: B) => A,
79
+ seed: A,
80
+ ): (<R, E>(stream: Stream<R, E, B>) => Fx.Fx<Scheduler | R, E, A>) => {
81
+ return flow(
82
+ foldMap(Endo.makeIdentity<A>())((a: B) => (b: A) => f(b, a)),
83
+ Fx.flap(seed),
84
+ )
85
+ }
86
+
87
+ export const every = foldMap(B.All)
88
+ export const some = foldMap(B.Any)
@@ -0,0 +1,8 @@
1
+ import { fromCallback } from './fromCallback.js'
2
+
3
+ export function fromArray<A>(array: ReadonlyArray<A>) {
4
+ return fromCallback<never, A>(async ({ event, end }) => {
5
+ await Promise.all(array.map(event))
6
+ await end()
7
+ })
8
+ }
@@ -6,34 +6,43 @@ import { Stream } from './Stream.js'
6
6
  import { Cause } from '@/Cause/Cause.js'
7
7
  import { Env } from '@/Env/Env.js'
8
8
  import * as Exit from '@/Exit/Exit.js'
9
+ import { FiberContext } from '@/FiberContext/FiberContext.js'
9
10
  import { FiberId } from '@/FiberId/index.js'
10
11
  import * as Fx from '@/Fx/Fx.js'
12
+ import { Scheduler } from '@/Scheduler/Scheduler.js'
13
+ import { Sink } from '@/Sink/Sink.js'
11
14
 
12
15
  /**
13
16
  * Constructs a Stream from an Fx that runs within a LogSpan enabling
14
17
  */
15
18
  export function fromFx<R, E, A>(fx: Fx.Fx<R, E, A>, __trace?: string): Stream<R, E, A> {
16
- return Stream((sink, scheduler, context) =>
17
- Fx.asksEnv(
19
+ return new FromFxStream(fx, __trace)
20
+ }
21
+
22
+ export class FromFxStream<R, E, A> implements Stream<R, E, A> {
23
+ constructor(readonly fx: Fx.Fx<R, E, A>, readonly __trace?: string) {}
24
+
25
+ fork<E2>(sink: Sink<E, A, E2>, scheduler: Scheduler, context: FiberContext<FiberId.Live>) {
26
+ return Fx.asksEnv(
18
27
  (env: Env<R>) =>
19
28
  scheduler.asap(
20
29
  pipe(
21
- fx,
30
+ this.fx,
22
31
  Fx.matchCause(
23
32
  sink.error,
24
33
  flow(
25
34
  sink.event,
26
35
  Fx.flatMap(() => sink.end),
27
36
  ),
28
- __trace,
37
+ this.__trace,
29
38
  ),
30
39
  ),
31
40
  env,
32
41
  context,
33
42
  ),
34
- __trace,
35
- ),
36
- )
43
+ this.__trace,
44
+ )
45
+ }
37
46
  }
38
47
 
39
48
  export const now = <A>(value: A, __trace?: string) => fromFx(Fx.now(value), __trace)
package/src/Stream/hkt.ts CHANGED
@@ -1,18 +1,24 @@
1
1
  import { HKT3, Params } from 'hkt-ts'
2
+ import * as AB from 'hkt-ts/Typeclass/AssociativeBoth'
3
+ import * as AF from 'hkt-ts/Typeclass/AssociativeFlatten'
2
4
  import * as B from 'hkt-ts/Typeclass/Bicovariant'
5
+ import { Bottom3 } from 'hkt-ts/Typeclass/Bottom'
3
6
  import * as C from 'hkt-ts/Typeclass/Covariant'
7
+ import * as FM from 'hkt-ts/Typeclass/FilterMap'
8
+ import * as IB from 'hkt-ts/Typeclass/IdentityBoth'
9
+ import { IdentityFlatten3 } from 'hkt-ts/Typeclass/IdentityFlatten'
10
+ import * as T from 'hkt-ts/Typeclass/Top'
11
+ import { NonNegativeInteger } from 'hkt-ts/number'
4
12
 
5
13
  import { Stream } from './Stream.js'
6
- import { bimap } from './bimap.js'
7
- import { map } from './map.js'
14
+ import { bimap, filterMap, map } from './bimap.js'
15
+ import { join } from './flatMap.js'
16
+ import { mergeConcurrently } from './flatMapConcurrently.js'
17
+ import { fromFx } from './fromFx.js'
18
+
19
+ import * as Fx from '@/Fx/index.js'
8
20
 
9
- // TODO: AssociativeBoth
10
21
  // TOOD: AssociativeEither
11
- // TODO: Top
12
- // TODO: Bottom
13
- // TODO: FilterMap
14
- // TODO: AssociativeFlatten
15
- // TODO: IdentityBoth
16
22
  // TODO: IdentityEither
17
23
  // TODO: IdentityFlatten
18
24
 
@@ -24,8 +30,6 @@ export const Bicovariant: B.Bicovariant3<StreamHKT> = {
24
30
  bimap,
25
31
  }
26
32
 
27
- export const mapLeft = B.mapLeft(Bicovariant)
28
-
29
33
  export const Covariant: C.Covariant3<StreamHKT> = {
30
34
  map,
31
35
  }
@@ -34,3 +38,48 @@ export const bindTo = C.bindTo(Covariant)
34
38
  export const flap = C.flap(Covariant)
35
39
  export const mapTo = C.mapTo(Covariant)
36
40
  export const tupled = C.tupled(Covariant)
41
+
42
+ export const Top: T.Top3<StreamHKT> = {
43
+ top: fromFx(Fx.top),
44
+ }
45
+
46
+ export const Bottom: Bottom3<StreamHKT> = {
47
+ bottom: fromFx(Fx.bottom),
48
+ }
49
+
50
+ export const Flatten: AF.AssociativeFlatten3<StreamHKT> = {
51
+ flatten: join,
52
+ }
53
+
54
+ export const IdentityFlatten: IdentityFlatten3<StreamHKT> = {
55
+ ...Flatten,
56
+ ...Top,
57
+ }
58
+
59
+ export const makeFlattenConcurrently = (
60
+ concurrencyLevel: NonNegativeInteger,
61
+ ): AF.AssociativeFlatten3<StreamHKT> => ({
62
+ flatten: mergeConcurrently(concurrencyLevel),
63
+ })
64
+
65
+ export const AssociativeBoth = AF.makeAssociativeBoth<StreamHKT>({
66
+ ...Flatten,
67
+ ...Covariant,
68
+ })
69
+
70
+ export const zipLeftSeq = AB.zipLeft<StreamHKT>({ ...AssociativeBoth, ...Covariant })
71
+ export const zipRightSeq = AB.zipRight<StreamHKT>({ ...AssociativeBoth, ...Covariant })
72
+
73
+ export const IdentityBoth: IB.IdentityBoth3<StreamHKT> = {
74
+ ...AssociativeBoth,
75
+ ...Top,
76
+ }
77
+
78
+ export const structSeq = IB.struct<StreamHKT>({ ...IdentityBoth, ...Covariant })
79
+
80
+ export const FilterMap: FM.FilterMap3<StreamHKT> = {
81
+ filterMap,
82
+ }
83
+
84
+ export const compact = FM.compact(FilterMap)
85
+ export const filter = FM.filter(FilterMap)
@@ -5,10 +5,10 @@ import { Stream } from './Stream.js'
5
5
  import { MulticastStream } from './multicast.js'
6
6
 
7
7
  import { Cause } from '@/Cause/index.js'
8
+ import { fromFiberRefs } from '@/Env/Env.js'
8
9
  import { Fiber } from '@/Fiber/Fiber.js'
9
10
  import { FiberContext } from '@/FiberContext/FiberContext.js'
10
11
  import { FiberId } from '@/FiberId/FiberId.js'
11
- import { getServiceFromFiberRefs } from '@/FiberRef/builtins.js'
12
12
  import * as Fx from '@/Fx/index.js'
13
13
  import { Scheduler } from '@/Scheduler/Scheduler.js'
14
14
  import { Sink } from '@/Sink/Sink.js'
@@ -100,7 +100,7 @@ export class HoldStream<R, E, A> extends MulticastStream<R, E, A> implements Str
100
100
 
101
101
  this.scheduledFiber = scheduler.asap(
102
102
  this.flushPending(),
103
- { get: getServiceFromFiberRefs(context.fiberRefs.fork()) },
103
+ fromFiberRefs(context.fiberRefs),
104
104
  context.fork(),
105
105
  )
106
106
 
@@ -1,21 +1,26 @@
1
1
  export * from './acquirePermit.js'
2
2
  export * from './bimap.js'
3
3
  export * from './continueWith.js'
4
+ export * from './delay.js'
4
5
  export * from './drain.js'
5
6
  export * from './empty.js'
6
7
  export * from './flatMap.js'
7
8
  export * from './flatMapConcurrently.js'
8
9
  export * from './flatMapFx.js'
10
+ export * from './foldMap.js'
11
+ export * from './fromArray.js'
9
12
  export * from './fromCallback.js'
10
13
  export * from './fromFx.js'
11
14
  export * from './hkt.js'
12
15
  export * from './hold.js'
13
16
  export * from './lazy.js'
14
- export * from './map.js'
15
17
  export * from './merge.js'
16
18
  export * from './multicast.js'
17
19
  export * from './periodic.js'
20
+ export * from './provide.js'
21
+ export * from './run.js'
18
22
  export * from './setFiberRefLocally.js'
23
+ export * from './skipRepeats.js'
19
24
  export * from './scan.js'
20
25
  export * from './scheduled.js'
21
26
  export * from './Stream.js'
@@ -1,6 +1,4 @@
1
1
  import { pipe } from 'hkt-ts'
2
- import { isRight } from 'hkt-ts/Either'
3
- import { isJust } from 'hkt-ts/Maybe'
4
2
 
5
3
  import { Stream } from './Stream.js'
6
4
 
@@ -9,12 +7,11 @@ import { Cause } from '@/Cause/index.js'
9
7
  import { Env } from '@/Env/Env.js'
10
8
  import { FiberContext } from '@/FiberContext/FiberContext.js'
11
9
  import { Live } from '@/FiberId/FiberId.js'
12
- import * as FiberRefs from '@/FiberRefs/index.js'
13
10
  import * as Fx from '@/Fx/index.js'
14
- import { access, lazy, provideService, unit } from '@/Fx/index.js'
11
+ import { access, lazy, unit } from '@/Fx/index.js'
15
12
  import { Scheduler } from '@/Scheduler/Scheduler.js'
16
13
  import * as Sink from '@/Sink/Sink.js'
17
- import { None, and } from '@/Supervisor/Supervisor.js'
14
+ import * as Supervisor from '@/Supervisor/index.js'
18
15
 
19
16
  export function orElse<E, R2, E2, B>(
20
17
  f: (cause: Cause<E>) => Stream<R2, E2, B>,
@@ -34,13 +31,10 @@ export class OrElseStream<R, E, A, R2, E2, B> implements Stream<R | R2, E2, A |
34
31
  const { stream, f } = this
35
32
 
36
33
  return access((env: Env<R | R2>) =>
37
- pipe(
38
- stream.fork(
39
- new OrElseSink(sink, scheduler, context, f, env, this.__trace),
40
- scheduler,
41
- context,
42
- ),
43
- provideService(Scheduler, scheduler),
34
+ stream.fork(
35
+ new OrElseSink(sink, scheduler, context, f, env, this.__trace),
36
+ scheduler,
37
+ context,
44
38
  ),
45
39
  )
46
40
  }
@@ -57,16 +51,6 @@ export class OrElseStream<R, E, A, R2, E2, B> implements Stream<R | R2, E2, A |
57
51
  class OrElseSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E, A, E3> {
58
52
  protected _running = AtomicCounter()
59
53
  protected _ended = false
60
- protected supervisor = None.extend({
61
- onEnd: () => (fiber, exit) => {
62
- const parentContext = fiber.context.parent
63
-
64
- // Merge FiberRefs upon successful completion
65
- if (isRight(exit) && isJust(parentContext)) {
66
- FiberRefs.join(parentContext.value.fiberRefs, fiber.context.fiberRefs)
67
- }
68
- },
69
- })
70
54
 
71
55
  constructor(
72
56
  readonly sink: Sink.Sink<E2, A | B, E3>,
@@ -82,7 +66,7 @@ class OrElseSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E, A, E3> {
82
66
  error = (cause: Cause<E>) => {
83
67
  return lazy(() => {
84
68
  const forked = this.context.fork({
85
- supervisor: and(this.supervisor)(this.context.supervisor),
69
+ supervisor: Supervisor.and(Supervisor.inheritFiberRefs)(this.context.supervisor),
86
70
  })
87
71
 
88
72
  increment(this._running)
@@ -0,0 +1,78 @@
1
+ import { deepStrictEqual } from 'assert'
2
+
3
+ import { pipe } from 'hkt-ts'
4
+
5
+ import { collectAll } from './_internal.test.js'
6
+
7
+ import * as Stream from './index.js'
8
+
9
+ import { Env } from '@/Env/Env.js'
10
+ import * as Fx from '@/Fx/index.js'
11
+ import { Id } from '@/Service/Id.js'
12
+ import { testSuite } from '@/_internal/suite.js'
13
+
14
+ testSuite(import.meta.url, () => {
15
+ const value = Math.random()
16
+ class Foo extends Id {
17
+ constructor(readonly foo: typeof value) {
18
+ super()
19
+ }
20
+ }
21
+
22
+ describe('provide', () => {
23
+ it('should provide the environment', async () => {
24
+ const stream = pipe(
25
+ Stream.now(value),
26
+ Stream.flatMapFx((a) =>
27
+ pipe(
28
+ Foo.ask(),
29
+ Fx.flatMap((foo) => Fx.now(a + foo.foo)),
30
+ ),
31
+ ),
32
+ Stream.provide(Env(Foo.id(), new Foo(value))),
33
+ )
34
+
35
+ const events = await collectAll(stream)
36
+
37
+ deepStrictEqual(events, [value * 2])
38
+ })
39
+ })
40
+
41
+ describe('provideService', () => {
42
+ it('should provide the service', async () => {
43
+ const stream = pipe(
44
+ Stream.now(value),
45
+ Stream.flatMapFx((a) =>
46
+ pipe(
47
+ Foo.ask(),
48
+ Fx.flatMap((foo) => Fx.now(a + foo.foo)),
49
+ ),
50
+ ),
51
+ Stream.provideService(Foo.id(), new Foo(value)),
52
+ )
53
+
54
+ const events = await collectAll(stream)
55
+
56
+ deepStrictEqual(events, [value * 2])
57
+ })
58
+ })
59
+
60
+ describe('provideLayer', () => {
61
+ it('should provide the layer', async () => {
62
+ const stream = pipe(
63
+ Stream.now(value),
64
+ Stream.flatMapFx((a) =>
65
+ pipe(
66
+ Foo.ask(),
67
+ Fx.flatMap((foo) => Fx.now(a + foo.foo)),
68
+ ),
69
+ ),
70
+ Stream.provideLayer(Foo.layerOf(value)),
71
+ )
72
+
73
+ const events = await collectAll(stream)
74
+
75
+ deepStrictEqual(events, [value * 2])
76
+ })
77
+ })
78
+ })
@@ -0,0 +1,34 @@
1
+ import { pipe } from 'hkt-ts'
2
+
3
+ import { Stream } from './Stream.js'
4
+
5
+ import { Env } from '@/Env/Env.js'
6
+ import * as Fx from '@/Fx/index.js'
7
+ import { Layer } from '@/Layer/Layer.js'
8
+ import { Service } from '@/Service/Service.js'
9
+
10
+ export function provide<R>(env: Env<R>) {
11
+ return <E, A>(stream: Stream<R, E, A>): Stream<never, E, A> =>
12
+ Stream((sink, scheduler, context) => Fx.provide(env)(stream.fork(sink, scheduler, context)))
13
+ }
14
+
15
+ export function provideService<S, I extends S>(service: Service<S>, impl: I) {
16
+ return <R, E, A>(stream: Stream<R, E, A>): Stream<Exclude<R, S>, E, A> =>
17
+ Stream((sink, scheduler, context) =>
18
+ pipe(stream.fork(sink, scheduler, context), Fx.provideService(service, impl)),
19
+ )
20
+ }
21
+
22
+ export function provideLayer<R2, E2, S>(layer: Layer<R2, E2, S>) {
23
+ return <R, E, A>(stream: Stream<R | S, E, A>): Stream<Exclude<R | R2, S>, E | E2, A> =>
24
+ Stream((sink, scheduler, context) =>
25
+ pipe(
26
+ Fx.getFiberContext,
27
+ Fx.flatMap((c) => stream.fork(sink, scheduler, c.fork())),
28
+ Fx.provideLayer(layer),
29
+ Fx.orElseCause((cause) => Fx.fork(sink.error(cause))),
30
+ Fx.flatMap((f) => Fx.join(f)),
31
+ Fx.forkInContext(context),
32
+ ),
33
+ )
34
+ }
package/src/Stream/run.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { flow, pipe } from 'hkt-ts/function'
1
+ import { pipe } from 'hkt-ts/function'
2
2
 
3
3
  import { Stream } from './Stream.js'
4
4
  import { drain } from './drain.js'
@@ -7,8 +7,11 @@ import * as Fx from '@/Fx/index.js'
7
7
  import { Scheduler } from '@/Scheduler/Scheduler.js'
8
8
 
9
9
  export function run(scheduler: Scheduler) {
10
- return <E, A>(stream: Stream<never, E, A>): Fx.Fx<never, E, unknown> =>
10
+ return <E, A>(stream: Stream<Scheduler, E, A>): Fx.Fx<never, E, unknown> =>
11
11
  pipe(drain(stream), Fx.flatMap(Fx.join), Fx.provideService(Scheduler, scheduler))
12
12
  }
13
13
 
14
- export const runMain = (scheduler: Scheduler) => flow(run(scheduler), Fx.runMain)
14
+ export const runMain =
15
+ (scheduler: Scheduler) =>
16
+ <E, A>(stream: Stream<Scheduler, E, A>): Promise<unknown> =>
17
+ pipe(stream, run(scheduler), Fx.runMain)
@@ -23,22 +23,16 @@ export class SetFiberRefLocallyStream<R, E, A, R2, E2, A2> implements Stream<R2,
23
23
 
24
24
  fork<E3>(sink: Sink<E2, A2, E3>, scheduler: Scheduler, context: FiberContext<FiberId.Live>) {
25
25
  return pipe(
26
- fromLazy(() => FiberRefs.setFiberRefLocally(this.fiberRef, this.value())(context.fiberRefs)),
27
- flatMap(() =>
28
- this.stream.fork(
29
- {
30
- ...sink,
31
- end: pipe(
32
- sink.end,
33
- flatMap(() =>
34
- fromLazy(() => FiberRefs.popLocalFiberRef(this.fiberRef)(context.fiberRefs)),
35
- ),
36
- ),
37
- },
38
- scheduler,
39
- context,
40
- ),
41
- ),
26
+ fromLazy(() => {
27
+ // SetFiberRef
28
+ FiberRefs.setFiberRefLocally(this.fiberRef, this.value())(context.fiberRefs)
29
+
30
+ // Ensure it is popped off when the stream ends
31
+ context.scope.ensuring(() =>
32
+ fromLazy(() => FiberRefs.popLocalFiberRef(this.fiberRef)(context.fiberRefs)),
33
+ )
34
+ }),
35
+ flatMap(() => this.stream.fork(sink, scheduler, context)),
42
36
  )
43
37
  }
44
38
  }
@@ -0,0 +1,41 @@
1
+ import { Maybe } from 'hkt-ts'
2
+ import { DeepEquals, Eq } from 'hkt-ts/Typeclass/Eq'
3
+
4
+ import { Stream } from './Stream.js'
5
+
6
+ import { unit } from '@/Fx/index.js'
7
+ import { Sink, addTrace } from '@/Sink/Sink.js'
8
+
9
+ export function skipRepeatsWith<A>(
10
+ E: Eq<A>,
11
+ __trace?: string,
12
+ ): <R, E>(stream: Stream<R, E, A>) => Stream<R, E, A> {
13
+ return (stream) =>
14
+ Stream((sink, scheduler, context) =>
15
+ stream.fork(addTrace(new SkipRepeatsSink(sink, E), __trace), scheduler, context),
16
+ )
17
+ }
18
+
19
+ export function skipRepeats<R, E, A>(stream: Stream<R, E, A>, __trace?: string): Stream<R, E, A> {
20
+ return skipRepeatsWith<A>(DeepEquals, __trace)(stream)
21
+ }
22
+
23
+ class SkipRepeatsSink<E, A, E2> implements Sink<E, A, E2> {
24
+ constructor(readonly sink: Sink<E, A, E2>, readonly E: Eq<A>) {}
25
+
26
+ protected last: Maybe.Maybe<A> = Maybe.Nothing
27
+ protected elem = Maybe.contains(this.E)
28
+
29
+ event(value: A) {
30
+ if (this.elem(value)(this.last)) {
31
+ return unit
32
+ }
33
+
34
+ this.last = Maybe.Just(value)
35
+
36
+ return this.sink.event(value)
37
+ }
38
+
39
+ error = this.sink.error
40
+ end = this.sink.end
41
+ }
@@ -1,9 +1,7 @@
1
1
  import { flow, pipe } from 'hkt-ts'
2
- import { isRight } from 'hkt-ts/Either'
3
- import { isJust } from 'hkt-ts/Maybe'
4
2
 
5
3
  import { Stream } from './Stream.js'
6
- import { MapStream } from './map.js'
4
+ import { MapStream } from './bimap.js'
7
5
 
8
6
  import { Cause } from '@/Cause/index.js'
9
7
  import { Disposable, Settable, settable } from '@/Disposable/Disposable.js'
@@ -11,13 +9,12 @@ import { Env } from '@/Env/Env.js'
11
9
  import { Fiber } from '@/Fiber/Fiber.js'
12
10
  import { FiberContext } from '@/FiberContext/FiberContext.js'
13
11
  import { Live } from '@/FiberId/FiberId.js'
14
- import * as FiberRefs from '@/FiberRefs/index.js'
15
12
  import * as Fx from '@/Fx/index.js'
16
13
  import { access, lazy, unit } from '@/Fx/index.js'
17
14
  import { Scheduler } from '@/Scheduler/Scheduler.js'
18
15
  import { Lock } from '@/Semaphore/Semaphore.js'
19
16
  import * as Sink from '@/Sink/Sink.js'
20
- import { None, and } from '@/Supervisor/Supervisor.js'
17
+ import * as Supervisor from '@/Supervisor/index.js'
21
18
 
22
19
  export function switchMap<A, R2, E2, B>(
23
20
  f: (a: A) => Stream<R2, E2, B>,
@@ -70,17 +67,6 @@ class SwitchMapSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E | E2, A, E3>
70
67
  protected _fibers: Array<Fiber<E3, any>> = []
71
68
  protected _lock = new Lock()
72
69
 
73
- protected _supervisor = None.extend({
74
- onEnd: () => (fiber, exit) => {
75
- const parentContext = fiber.context.parent
76
-
77
- // Merge FiberRefs upon successful completion
78
- if (isRight(exit) && isJust(parentContext)) {
79
- FiberRefs.join(parentContext.value.fiberRefs, fiber.context.fiberRefs)
80
- }
81
- },
82
- })
83
-
84
70
  constructor(
85
71
  readonly sink: Sink.Sink<E | E2, B, E3>,
86
72
  readonly scheduler: Scheduler,
@@ -93,7 +79,7 @@ class SwitchMapSink<R, E, A, R2, E2, B, E3> implements Sink.Sink<E | E2, A, E3>
93
79
  event = (a: A): Fx.IO<E3, unknown> =>
94
80
  Fx.lazy(() => {
95
81
  const forked = this.context.fork({
96
- supervisor: and(this._supervisor)(this.context.supervisor),
82
+ supervisor: Supervisor.and(Supervisor.inheritFiberRefs)(this.context.supervisor),
97
83
  })
98
84
 
99
85
  const cleanup: Fx.Of<unknown> = Fx.zipAll(this._fibers.map((f) => f.interruptAs(forked.id)))