synstate 0.1.1 → 1.0.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.
Files changed (309) hide show
  1. package/README.md +317 -298
  2. package/dist/core/class/child-observable-class.d.mts.map +1 -1
  3. package/dist/core/class/child-observable-class.mjs +43 -10
  4. package/dist/core/class/child-observable-class.mjs.map +1 -1
  5. package/dist/core/class/observable-base-class.d.mts +4 -4
  6. package/dist/core/class/observable-base-class.d.mts.map +1 -1
  7. package/dist/core/class/observable-base-class.mjs +8 -8
  8. package/dist/core/class/observable-base-class.mjs.map +1 -1
  9. package/dist/core/class/root-observable-class.d.mts +1 -1
  10. package/dist/core/class/root-observable-class.d.mts.map +1 -1
  11. package/dist/core/class/root-observable-class.mjs +9 -9
  12. package/dist/core/class/root-observable-class.mjs.map +1 -1
  13. package/dist/core/combine/combine.d.mts +7 -7
  14. package/dist/core/combine/combine.mjs +13 -14
  15. package/dist/core/combine/combine.mjs.map +1 -1
  16. package/dist/core/combine/merge.d.mts +6 -6
  17. package/dist/core/combine/merge.mjs +9 -9
  18. package/dist/core/combine/merge.mjs.map +1 -1
  19. package/dist/core/combine/zip.d.mts +20 -19
  20. package/dist/core/combine/zip.d.mts.map +1 -1
  21. package/dist/core/combine/zip.mjs +22 -21
  22. package/dist/core/combine/zip.mjs.map +1 -1
  23. package/dist/core/create/{interval.d.mts → counter.d.mts} +14 -12
  24. package/dist/core/create/counter.d.mts.map +1 -0
  25. package/dist/core/create/{interval.mjs → counter.mjs} +21 -23
  26. package/dist/core/create/counter.mjs.map +1 -0
  27. package/dist/core/create/from-abortable-promise.d.mts +29 -0
  28. package/dist/core/create/from-abortable-promise.d.mts.map +1 -0
  29. package/dist/core/create/from-abortable-promise.mjs +70 -0
  30. package/dist/core/create/from-abortable-promise.mjs.map +1 -0
  31. package/dist/core/create/from-promise.d.mts +9 -6
  32. package/dist/core/create/from-promise.d.mts.map +1 -1
  33. package/dist/core/create/from-promise.mjs +8 -5
  34. package/dist/core/create/from-promise.mjs.map +1 -1
  35. package/dist/core/create/from-subscribable.d.mts +4 -4
  36. package/dist/core/create/from-subscribable.mjs +4 -4
  37. package/dist/core/create/index.d.mts +3 -3
  38. package/dist/core/create/index.d.mts.map +1 -1
  39. package/dist/core/create/index.mjs +4 -4
  40. package/dist/core/create/just.d.mts +32 -0
  41. package/dist/core/create/just.d.mts.map +1 -0
  42. package/dist/core/create/just.mjs +44 -0
  43. package/dist/core/create/just.mjs.map +1 -0
  44. package/dist/core/create/source.d.mts +7 -12
  45. package/dist/core/create/source.d.mts.map +1 -1
  46. package/dist/core/create/source.mjs +1 -6
  47. package/dist/core/create/source.mjs.map +1 -1
  48. package/dist/core/create/timer.d.mts +6 -4
  49. package/dist/core/create/timer.d.mts.map +1 -1
  50. package/dist/core/create/timer.mjs +6 -7
  51. package/dist/core/create/timer.mjs.map +1 -1
  52. package/dist/core/index.d.mts +1 -1
  53. package/dist/core/index.d.mts.map +1 -1
  54. package/dist/core/index.mjs +21 -14
  55. package/dist/core/index.mjs.map +1 -1
  56. package/dist/core/operators/audit.d.mts +97 -0
  57. package/dist/core/operators/audit.d.mts.map +1 -0
  58. package/dist/core/operators/audit.mjs +144 -0
  59. package/dist/core/operators/audit.mjs.map +1 -0
  60. package/dist/core/operators/debounce.d.mts +88 -0
  61. package/dist/core/operators/debounce.d.mts.map +1 -0
  62. package/dist/core/operators/debounce.mjs +130 -0
  63. package/dist/core/operators/debounce.mjs.map +1 -0
  64. package/dist/core/operators/filter.d.mts +5 -5
  65. package/dist/core/operators/filter.mjs +3 -3
  66. package/dist/core/operators/filter.mjs.map +1 -1
  67. package/dist/core/operators/index.d.mts +4 -4
  68. package/dist/core/operators/index.d.mts.map +1 -1
  69. package/dist/core/operators/index.mjs +6 -6
  70. package/dist/core/operators/map.d.mts +41 -0
  71. package/dist/core/operators/map.d.mts.map +1 -0
  72. package/dist/core/operators/map.mjs +71 -0
  73. package/dist/core/operators/map.mjs.map +1 -0
  74. package/dist/core/operators/merge-map.d.mts +57 -30
  75. package/dist/core/operators/merge-map.d.mts.map +1 -1
  76. package/dist/core/operators/merge-map.mjs +59 -32
  77. package/dist/core/operators/merge-map.mjs.map +1 -1
  78. package/dist/core/operators/pairwise.d.mts +6 -6
  79. package/dist/core/operators/pairwise.mjs +9 -9
  80. package/dist/core/operators/pairwise.mjs.map +1 -1
  81. package/dist/core/operators/scan.d.mts +6 -6
  82. package/dist/core/operators/scan.mjs +9 -9
  83. package/dist/core/operators/scan.mjs.map +1 -1
  84. package/dist/core/operators/skip-if-no-change.d.mts +21 -9
  85. package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
  86. package/dist/core/operators/skip-if-no-change.mjs +25 -13
  87. package/dist/core/operators/skip-if-no-change.mjs.map +1 -1
  88. package/dist/core/operators/skip-until.d.mts +5 -5
  89. package/dist/core/operators/skip-until.mjs +8 -8
  90. package/dist/core/operators/skip-until.mjs.map +1 -1
  91. package/dist/core/operators/skip-while.d.mts +18 -9
  92. package/dist/core/operators/skip-while.d.mts.map +1 -1
  93. package/dist/core/operators/skip-while.mjs +28 -16
  94. package/dist/core/operators/skip-while.mjs.map +1 -1
  95. package/dist/core/operators/switch-map.d.mts +57 -26
  96. package/dist/core/operators/switch-map.d.mts.map +1 -1
  97. package/dist/core/operators/switch-map.mjs +59 -28
  98. package/dist/core/operators/switch-map.mjs.map +1 -1
  99. package/dist/core/operators/take-until.d.mts +5 -5
  100. package/dist/core/operators/take-until.mjs +8 -8
  101. package/dist/core/operators/take-until.mjs.map +1 -1
  102. package/dist/core/operators/take-while.d.mts +15 -8
  103. package/dist/core/operators/take-while.d.mts.map +1 -1
  104. package/dist/core/operators/take-while.mjs +19 -13
  105. package/dist/core/operators/take-while.mjs.map +1 -1
  106. package/dist/core/operators/throttle.d.mts +81 -0
  107. package/dist/core/operators/throttle.d.mts.map +1 -0
  108. package/dist/core/operators/throttle.mjs +126 -0
  109. package/dist/core/operators/throttle.mjs.map +1 -0
  110. package/dist/core/operators/with-buffered-from.d.mts +13 -9
  111. package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
  112. package/dist/core/operators/with-buffered-from.mjs +17 -13
  113. package/dist/core/operators/with-buffered-from.mjs.map +1 -1
  114. package/dist/core/operators/with-current-value-from.d.mts +14 -9
  115. package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
  116. package/dist/core/operators/with-current-value-from.mjs +18 -13
  117. package/dist/core/operators/with-current-value-from.mjs.map +1 -1
  118. package/dist/core/operators/with-initial-value.d.mts +5 -5
  119. package/dist/core/operators/with-initial-value.mjs +8 -8
  120. package/dist/core/operators/with-initial-value.mjs.map +1 -1
  121. package/dist/core/predefined/index.d.mts +2 -0
  122. package/dist/core/predefined/index.d.mts.map +1 -0
  123. package/dist/core/predefined/index.mjs +12 -0
  124. package/dist/core/predefined/index.mjs.map +1 -0
  125. package/dist/core/predefined/operators/attach-index.d.mts +57 -0
  126. package/dist/core/predefined/operators/attach-index.d.mts.map +1 -0
  127. package/dist/core/predefined/operators/attach-index.mjs +62 -0
  128. package/dist/core/predefined/operators/attach-index.mjs.map +1 -0
  129. package/dist/core/predefined/operators/index.d.mts +12 -0
  130. package/dist/core/predefined/operators/index.d.mts.map +1 -0
  131. package/dist/core/predefined/operators/index.mjs +12 -0
  132. package/dist/core/predefined/operators/index.mjs.map +1 -0
  133. package/dist/core/predefined/operators/map-optional.d.mts +51 -0
  134. package/dist/core/predefined/operators/map-optional.d.mts.map +1 -0
  135. package/dist/core/predefined/operators/map-optional.mjs +55 -0
  136. package/dist/core/predefined/operators/map-optional.mjs.map +1 -0
  137. package/dist/core/predefined/operators/map-result-err.d.mts +51 -0
  138. package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -0
  139. package/dist/core/predefined/operators/map-result-err.mjs +55 -0
  140. package/dist/core/predefined/operators/map-result-err.mjs.map +1 -0
  141. package/dist/core/predefined/operators/map-result-ok.d.mts +51 -0
  142. package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -0
  143. package/dist/core/predefined/operators/map-result-ok.mjs +55 -0
  144. package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -0
  145. package/dist/core/predefined/operators/map-to.d.mts +43 -0
  146. package/dist/core/predefined/operators/map-to.d.mts.map +1 -0
  147. package/dist/core/predefined/operators/map-to.mjs +48 -0
  148. package/dist/core/predefined/operators/map-to.mjs.map +1 -0
  149. package/dist/core/predefined/operators/pluck.d.mts +47 -0
  150. package/dist/core/predefined/operators/pluck.d.mts.map +1 -0
  151. package/dist/core/predefined/operators/pluck.mjs +52 -0
  152. package/dist/core/predefined/operators/pluck.mjs.map +1 -0
  153. package/dist/core/predefined/operators/skip.d.mts +50 -0
  154. package/dist/core/predefined/operators/skip.d.mts.map +1 -0
  155. package/dist/core/predefined/operators/skip.mjs +56 -0
  156. package/dist/core/predefined/operators/skip.mjs.map +1 -0
  157. package/dist/core/predefined/operators/take.d.mts +44 -0
  158. package/dist/core/predefined/operators/take.d.mts.map +1 -0
  159. package/dist/core/predefined/operators/take.mjs +49 -0
  160. package/dist/core/predefined/operators/take.mjs.map +1 -0
  161. package/dist/core/predefined/operators/unwrap-optional.d.mts +44 -0
  162. package/dist/core/predefined/operators/unwrap-optional.d.mts.map +1 -0
  163. package/dist/core/predefined/operators/unwrap-optional.mjs +50 -0
  164. package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -0
  165. package/dist/core/predefined/operators/unwrap-result-err.d.mts +44 -0
  166. package/dist/core/predefined/operators/unwrap-result-err.d.mts.map +1 -0
  167. package/dist/core/predefined/operators/unwrap-result-err.mjs +48 -0
  168. package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -0
  169. package/dist/core/predefined/operators/unwrap-result-ok.d.mts +44 -0
  170. package/dist/core/predefined/operators/unwrap-result-ok.d.mts.map +1 -0
  171. package/dist/core/predefined/operators/unwrap-result-ok.mjs +50 -0
  172. package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -0
  173. package/dist/core/types/id.d.mts +1 -1
  174. package/dist/core/types/id.d.mts.map +1 -1
  175. package/dist/core/types/index.d.mts +1 -0
  176. package/dist/core/types/index.d.mts.map +1 -1
  177. package/dist/core/types/observable-family.d.mts +8 -14
  178. package/dist/core/types/observable-family.d.mts.map +1 -1
  179. package/dist/core/types/observable.d.mts +3 -3
  180. package/dist/core/types/observable.d.mts.map +1 -1
  181. package/dist/core/types/timer.d.mts +2 -0
  182. package/dist/core/types/timer.d.mts.map +1 -0
  183. package/dist/core/types/timer.mjs +2 -0
  184. package/dist/core/types/timer.mjs.map +1 -0
  185. package/dist/core/utils/id-maker.d.mts +2 -2
  186. package/dist/core/utils/id-maker.d.mts.map +1 -1
  187. package/dist/core/utils/id-maker.mjs +3 -3
  188. package/dist/core/utils/id-maker.mjs.map +1 -1
  189. package/dist/core/utils/index.mjs +1 -1
  190. package/dist/entry-point.mjs +24 -15
  191. package/dist/entry-point.mjs.map +1 -1
  192. package/dist/globals.d.mts +0 -3
  193. package/dist/index.mjs +24 -15
  194. package/dist/index.mjs.map +1 -1
  195. package/dist/utils/collect-to-array.d.mts +3 -0
  196. package/dist/utils/collect-to-array.d.mts.map +1 -0
  197. package/dist/utils/collect-to-array.mjs +11 -0
  198. package/dist/utils/collect-to-array.mjs.map +1 -0
  199. package/dist/utils/create-boolean-state.d.mts +40 -0
  200. package/dist/utils/create-boolean-state.d.mts.map +1 -0
  201. package/dist/utils/create-boolean-state.mjs +53 -0
  202. package/dist/utils/create-boolean-state.mjs.map +1 -0
  203. package/dist/utils/create-event-emitter.d.mts +4 -4
  204. package/dist/utils/create-event-emitter.mjs +4 -4
  205. package/dist/utils/create-reducer.d.mts +10 -7
  206. package/dist/utils/create-reducer.d.mts.map +1 -1
  207. package/dist/utils/create-reducer.mjs +7 -7
  208. package/dist/utils/create-reducer.mjs.map +1 -1
  209. package/dist/utils/create-state.d.mts +8 -48
  210. package/dist/utils/create-state.d.mts.map +1 -1
  211. package/dist/utils/create-state.mjs +10 -60
  212. package/dist/utils/create-state.mjs.map +1 -1
  213. package/dist/utils/index.d.mts +2 -0
  214. package/dist/utils/index.d.mts.map +1 -1
  215. package/dist/utils/index.mjs +3 -1
  216. package/dist/utils/index.mjs.map +1 -1
  217. package/package.json +17 -11
  218. package/src/core/class/child-observable-class.mts +65 -9
  219. package/src/core/class/circular-dependency-comparison.test.mts +142 -0
  220. package/src/core/class/circular-dependency.test.mts +251 -0
  221. package/src/core/class/observable-base-class.mts +9 -9
  222. package/src/core/class/root-observable-class.mts +14 -10
  223. package/src/core/combine/combine.mts +15 -15
  224. package/src/core/combine/merge.mts +13 -14
  225. package/src/core/combine/zip.mts +26 -25
  226. package/src/core/create/{interval.mts → counter.mts} +32 -30
  227. package/src/core/create/from-abortable-promise.mts +83 -0
  228. package/src/core/create/from-promise.mts +10 -7
  229. package/src/core/create/from-subscribable.mts +4 -4
  230. package/src/core/create/index.mts +3 -3
  231. package/src/core/create/just.mts +43 -0
  232. package/src/core/create/source.mts +10 -14
  233. package/src/core/create/timer.mts +12 -11
  234. package/src/core/index.mts +1 -1
  235. package/src/core/operators/audit.mts +172 -0
  236. package/src/core/operators/debounce.mts +154 -0
  237. package/src/core/operators/filter.mts +9 -9
  238. package/src/core/operators/index.mts +4 -4
  239. package/src/core/operators/map.mts +124 -0
  240. package/src/core/operators/merge-map.mts +60 -33
  241. package/src/core/operators/pairwise.mts +10 -10
  242. package/src/core/operators/scan.mts +10 -10
  243. package/src/core/operators/skip-if-no-change.mts +26 -14
  244. package/src/core/operators/skip-until.mts +9 -9
  245. package/src/core/operators/skip-while.mts +30 -28
  246. package/src/core/operators/switch-map.mts +60 -29
  247. package/src/core/operators/take-until.mts +9 -9
  248. package/src/core/operators/take-while.mts +21 -19
  249. package/src/core/operators/{throttle-time.mts → throttle.mts} +58 -38
  250. package/src/core/operators/with-buffered-from.mts +18 -14
  251. package/src/core/operators/with-current-value-from.mts +19 -14
  252. package/src/core/operators/with-initial-value.mts +9 -9
  253. package/src/core/predefined/index.mts +1 -0
  254. package/src/core/predefined/operators/attach-index.mts +62 -0
  255. package/src/core/predefined/operators/index.mts +11 -0
  256. package/src/core/predefined/operators/map-optional.mts +55 -0
  257. package/src/core/predefined/operators/map-result-err.mts +55 -0
  258. package/src/core/predefined/operators/map-result-ok.mts +55 -0
  259. package/src/core/predefined/operators/map-to.mts +45 -0
  260. package/src/core/predefined/operators/pluck.mts +51 -0
  261. package/src/core/predefined/operators/skip.mts +57 -0
  262. package/src/core/predefined/operators/take.mts +47 -0
  263. package/src/core/predefined/operators/unwrap-optional.mts +49 -0
  264. package/src/core/predefined/operators/unwrap-result-err.mts +48 -0
  265. package/src/core/predefined/operators/unwrap-result-ok.mts +49 -0
  266. package/src/core/types/id.mts +1 -1
  267. package/src/core/types/index.mts +1 -0
  268. package/src/core/types/observable-family.mts +8 -24
  269. package/src/core/types/observable.mts +3 -3
  270. package/src/core/types/timer.mts +2 -0
  271. package/src/core/utils/id-maker.mts +4 -4
  272. package/src/globals.d.mts +0 -3
  273. package/src/utils/collect-to-array.mts +17 -0
  274. package/src/utils/create-boolean-state.mts +68 -0
  275. package/src/utils/create-event-emitter.mts +4 -4
  276. package/src/utils/create-reducer.mts +11 -8
  277. package/src/utils/create-state.mts +10 -75
  278. package/src/utils/index.mts +2 -0
  279. package/dist/core/create/from-array.d.mts +0 -39
  280. package/dist/core/create/from-array.d.mts.map +0 -1
  281. package/dist/core/create/from-array.mjs +0 -65
  282. package/dist/core/create/from-array.mjs.map +0 -1
  283. package/dist/core/create/interval.d.mts.map +0 -1
  284. package/dist/core/create/interval.mjs.map +0 -1
  285. package/dist/core/create/of.d.mts +0 -39
  286. package/dist/core/create/of.d.mts.map +0 -1
  287. package/dist/core/create/of.mjs +0 -63
  288. package/dist/core/create/of.mjs.map +0 -1
  289. package/dist/core/operators/audit-time.d.mts +0 -62
  290. package/dist/core/operators/audit-time.d.mts.map +0 -1
  291. package/dist/core/operators/audit-time.mjs +0 -109
  292. package/dist/core/operators/audit-time.mjs.map +0 -1
  293. package/dist/core/operators/debounce-time.d.mts +0 -51
  294. package/dist/core/operators/debounce-time.d.mts.map +0 -1
  295. package/dist/core/operators/debounce-time.mjs +0 -93
  296. package/dist/core/operators/debounce-time.mjs.map +0 -1
  297. package/dist/core/operators/map-with-index.d.mts +0 -54
  298. package/dist/core/operators/map-with-index.d.mts.map +0 -1
  299. package/dist/core/operators/map-with-index.mjs +0 -88
  300. package/dist/core/operators/map-with-index.mjs.map +0 -1
  301. package/dist/core/operators/throttle-time.d.mts +0 -62
  302. package/dist/core/operators/throttle-time.d.mts.map +0 -1
  303. package/dist/core/operators/throttle-time.mjs +0 -107
  304. package/dist/core/operators/throttle-time.mjs.map +0 -1
  305. package/src/core/create/from-array.mts +0 -76
  306. package/src/core/create/of.mts +0 -73
  307. package/src/core/operators/audit-time.mts +0 -136
  308. package/src/core/operators/debounce-time.mts +0 -116
  309. package/src/core/operators/map-with-index.mts +0 -183
@@ -4,7 +4,7 @@ import {
4
4
  type KeepInitialValueOperator,
5
5
  type Observable,
6
6
  type SkipIfNoChangeOperatorObservable,
7
- type UpdaterSymbol,
7
+ type UpdateToken,
8
8
  } from '../types/index.mjs';
9
9
 
10
10
  /**
@@ -19,8 +19,8 @@ import {
19
19
  * ```ts
20
20
  * // Timeline:
21
21
  * //
22
- * // num$ 1 1 2 2 2 3
23
- * // distinct$ 1 2 3
22
+ * // num$ 1 1 2 2 1 2 3 2
23
+ * // distinct$ 1 2 1 2 3 2
24
24
  * //
25
25
  * // Explanation:
26
26
  * // - skipIfNoChange filters out consecutive duplicate values
@@ -31,29 +31,41 @@ import {
31
31
  *
32
32
  * const distinct$ = num$.pipe(skipIfNoChange());
33
33
  *
34
- * const mut_history: number[] = [];
34
+ * const valueHistory: number[] = [];
35
35
  *
36
36
  * distinct$.subscribe((x) => {
37
- * mut_history.push(x);
37
+ * valueHistory.push(x);
38
38
  * });
39
39
  *
40
40
  * num$.next(1); // logs: 1
41
41
  *
42
- * assert.deepStrictEqual(mut_history, [1]);
42
+ * assert.deepStrictEqual(valueHistory, [1]);
43
43
  *
44
44
  * num$.next(1); // nothing logged
45
45
  *
46
- * assert.deepStrictEqual(mut_history, [1]);
46
+ * assert.deepStrictEqual(valueHistory, [1]);
47
47
  *
48
48
  * num$.next(2); // logs: 2
49
49
  *
50
- * assert.deepStrictEqual(mut_history, [1, 2]);
50
+ * assert.deepStrictEqual(valueHistory, [1, 2]);
51
51
  *
52
52
  * num$.next(2); // nothing logged
53
53
  *
54
+ * num$.next(1); // logs: 1
55
+ *
56
+ * assert.deepStrictEqual(valueHistory, [1, 2, 1]);
57
+ *
58
+ * num$.next(2); // logs: 2
59
+ *
60
+ * assert.deepStrictEqual(valueHistory, [1, 2, 1, 2]);
61
+ *
54
62
  * num$.next(3); // logs: 3
55
63
  *
56
- * assert.deepStrictEqual(mut_history, [1, 2, 3]);
64
+ * assert.deepStrictEqual(valueHistory, [1, 2, 1, 2, 3]);
65
+ *
66
+ * num$.next(2); // logs: 2
67
+ *
68
+ * assert.deepStrictEqual(valueHistory, [1, 2, 1, 2, 3, 2]);
57
69
  * ```
58
70
  */
59
71
  export const skipIfNoChange = <A,>(
@@ -67,10 +79,10 @@ export const skipIfNoChange = <A,>(
67
79
  )) as KeepInitialValueOperator<A, A>;
68
80
 
69
81
  /**
70
- * Alias for `skipIfNoChange()`.
82
+ * Alias for `skipIfNoChange`.
71
83
  * @see skipIfNoChange
72
84
  */
73
- export const distinctUntilChanged = skipIfNoChange; // alias
85
+ export const distinctUntilChanged = skipIfNoChange;
74
86
 
75
87
  class SkipIfNoChangeObservableClass<A>
76
88
  extends SyncChildObservableClass<A, readonly [A]>
@@ -92,12 +104,12 @@ class SkipIfNoChangeObservableClass<A>
92
104
  this.#eq = eq;
93
105
  }
94
106
 
95
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
107
+ override tryUpdate(updateToken: UpdateToken): void {
96
108
  const par = this.parents[0];
97
109
 
98
110
  const sn = par.getSnapshot();
99
111
 
100
- if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
112
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
101
113
  return; // skip update
102
114
  }
103
115
 
@@ -109,7 +121,7 @@ class SkipIfNoChangeObservableClass<A>
109
121
  this.#mut_previousValue = sn;
110
122
 
111
123
  if (cond) {
112
- this.setNext(sn.value, updaterSymbol);
124
+ this.setNext(sn.value, updateToken);
113
125
  }
114
126
  }
115
127
  }
@@ -4,7 +4,7 @@ import {
4
4
  type DropInitialValueOperator,
5
5
  type Observable,
6
6
  type SkipUntilOperatorObservable,
7
- type UpdaterSymbol,
7
+ type UpdateToken,
8
8
  } from '../types/index.mjs';
9
9
 
10
10
  /**
@@ -34,27 +34,27 @@ import {
34
34
  *
35
35
  * const skipped$ = num$.pipe(skipUntil(startNotifier));
36
36
  *
37
- * const mut_history: number[] = [];
37
+ * const valueHistory: number[] = [];
38
38
  *
39
39
  * skipped$.subscribe((x) => {
40
- * mut_history.push(x);
40
+ * valueHistory.push(x);
41
41
  * });
42
42
  *
43
43
  * num$.next(1); // nothing logged
44
44
  *
45
45
  * num$.next(2); // nothing logged
46
46
  *
47
- * assert.deepStrictEqual(mut_history, []);
47
+ * assert.deepStrictEqual(valueHistory, []);
48
48
  *
49
49
  * start_();
50
50
  *
51
51
  * num$.next(4); // logs: 4
52
52
  *
53
- * assert.deepStrictEqual(mut_history, [4]);
53
+ * assert.deepStrictEqual(valueHistory, [4]);
54
54
  *
55
55
  * num$.next(5); // logs: 5
56
56
  *
57
- * assert.deepStrictEqual(mut_history, [4, 5]);
57
+ * assert.deepStrictEqual(valueHistory, [4, 5]);
58
58
  * ```
59
59
  */
60
60
  export const skipUntil =
@@ -86,19 +86,19 @@ class SkipUntilObservableClass<A>
86
86
  );
87
87
  }
88
88
 
89
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
89
+ override tryUpdate(updateToken: UpdateToken): void {
90
90
  const par = this.parents[0];
91
91
 
92
92
  const sn = par.getSnapshot();
93
93
 
94
94
  if (
95
- par.updaterSymbol !== updaterSymbol ||
95
+ par.updateToken !== updateToken ||
96
96
  Optional.isNone(sn) ||
97
97
  this.#mut_isSkipping
98
98
  ) {
99
99
  return; // skip update
100
100
  }
101
101
 
102
- this.setNext(sn.value, updaterSymbol);
102
+ this.setNext(sn.value, updateToken);
103
103
  }
104
104
  }
@@ -1,16 +1,10 @@
1
- import {
2
- Optional,
3
- PositiveSafeInt,
4
- SafeUint,
5
- asSafeUint,
6
- pipe,
7
- } from 'ts-data-forge';
1
+ import { Optional, SafeUint, asSafeUint, pipe } from 'ts-data-forge';
8
2
  import { SyncChildObservableClass } from '../class/index.mjs';
9
3
  import {
10
4
  type DropInitialValueOperator,
11
5
  type Observable,
12
6
  type SkipWhileOperatorObservable,
13
- type UpdaterSymbol,
7
+ type UpdateToken,
14
8
  } from '../types/index.mjs';
15
9
 
16
10
  /**
@@ -25,9 +19,9 @@ import {
25
19
  * ```ts
26
20
  * // Timeline:
27
21
  * //
28
- * // num$ 1 2 3 4 5 6 7
29
- * // skipped$ 5 6 7
30
- * // |---- skip -----|
22
+ * // num$ 1 2 3 4 5 6 7 1 2
23
+ * // skipped$ 5 6 7 1 2
24
+ * // |-------- skip --------|
31
25
  * //
32
26
  * // Explanation:
33
27
  * // - skipWhile skips values while the predicate returns true
@@ -38,27 +32,37 @@ import {
38
32
  *
39
33
  * const skipped$ = num$.pipe(skipWhile((x) => x < 5));
40
34
  *
41
- * const mut_history: number[] = [];
35
+ * const valueHistory: number[] = [];
42
36
  *
43
37
  * skipped$.subscribe((x) => {
44
- * mut_history.push(x);
38
+ * valueHistory.push(x);
45
39
  * });
46
40
  *
47
41
  * num$.next(1); // nothing logged
48
42
  *
49
43
  * num$.next(2); // nothing logged
50
44
  *
45
+ * num$.next(3); // nothing logged
46
+ *
47
+ * num$.next(4); // nothing logged
48
+ *
51
49
  * num$.next(5); // logs: 5
52
50
  *
53
- * assert.deepStrictEqual(mut_history, [5]);
51
+ * assert.deepStrictEqual(valueHistory, [5]);
54
52
  *
55
53
  * num$.next(6); // logs: 6
56
54
  *
57
- * assert.deepStrictEqual(mut_history, [5, 6]);
55
+ * assert.deepStrictEqual(valueHistory, [5, 6]);
58
56
  *
59
57
  * num$.next(7); // logs: 7
60
58
  *
61
- * assert.deepStrictEqual(mut_history, [5, 6, 7]);
59
+ * assert.deepStrictEqual(valueHistory, [5, 6, 7]);
60
+ *
61
+ * num$.next(1); // logs: 1
62
+ *
63
+ * num$.next(2); // logs: 2
64
+ *
65
+ * assert.deepStrictEqual(valueHistory, [5, 6, 7, 1, 2]);
62
66
  * ```
63
67
  */
64
68
  export const skipWhile =
@@ -68,15 +72,6 @@ export const skipWhile =
68
72
  (parentObservable) =>
69
73
  new SkipWhileObservableClass(parentObservable, predicate);
70
74
 
71
- /* Specialized operators */
72
-
73
- export const skip = <A,>(
74
- n: PositiveSafeIntWithSmallInt,
75
- ): DropInitialValueOperator<A, A> =>
76
- !PositiveSafeInt.is(n) ? idFn : skipWhile((_, index) => index + 1 <= n);
77
-
78
- const idFn = <T,>(value: T): T => value;
79
-
80
75
  /* implementation */
81
76
 
82
77
  class SkipWhileObservableClass<A>
@@ -85,6 +80,7 @@ class SkipWhileObservableClass<A>
85
80
  {
86
81
  readonly #predicate: (value: A, index: SafeUint | -1) => boolean;
87
82
  #mut_index: SafeUint | -1;
83
+ #mut_skipping: boolean;
88
84
 
89
85
  constructor(
90
86
  parentObservable: Observable<A>,
@@ -104,14 +100,16 @@ class SkipWhileObservableClass<A>
104
100
  this.#mut_index = -1;
105
101
 
106
102
  this.#predicate = predicate;
103
+
104
+ this.#mut_skipping = true;
107
105
  }
108
106
 
109
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
107
+ override tryUpdate(updateToken: UpdateToken): void {
110
108
  const par = this.parents[0];
111
109
 
112
110
  const sn = par.getSnapshot();
113
111
 
114
- if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
112
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
115
113
  return; // skip update
116
114
  }
117
115
 
@@ -119,7 +117,11 @@ class SkipWhileObservableClass<A>
119
117
  this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
120
118
 
121
119
  if (!this.#predicate(sn.value, this.#mut_index)) {
122
- this.setNext(sn.value, updaterSymbol);
120
+ this.#mut_skipping = false;
121
+ }
122
+
123
+ if (!this.#mut_skipping) {
124
+ this.setNext(sn.value, updateToken);
123
125
  }
124
126
  }
125
127
  }
@@ -5,7 +5,7 @@ import {
5
5
  type Observable,
6
6
  type Subscription,
7
7
  type SwitchMapOperatorObservable,
8
- type UpdaterSymbol,
8
+ type UpdateToken,
9
9
  } from '../types/index.mjs';
10
10
 
11
11
  /**
@@ -21,50 +21,81 @@ import {
21
21
  * ```ts
22
22
  * // Timeline:
23
23
  * //
24
- * // searchQuery$ "a" "ab" "abc"
25
- * // requests fetch1 fetch2 fetch3
26
- * // results$ cancel cancel result3
27
- * // fetch1 fetch2
24
+ * // input$ A B C
25
+ * // inner A A1 A2 A3
26
+ * // inner B B1 B2 (switched!)
27
+ * // inner C C1 C2 C3
28
+ * // result$ A1 A2 A3 B1 B2 C1 C2 C3
28
29
  * //
29
30
  * // Explanation:
30
- * // - switchMap cancels previous inner observables when a new value arrives
31
- * // - Only the result from the latest search query is emitted
32
- * // - Previous ongoing requests are cancelled
33
- * // - Ideal for search-as-you-type scenarios
31
+ * // - switchMap creates an inner observable for each source value
32
+ * // - When a new source value arrives, the previous inner is unsubscribed
33
+ * // - A's inner completes normally (all 3 values emitted)
34
+ * // - B's inner is interrupted by C (only 2 values emitted)
35
+ * // - C's inner completes normally (all 3 values emitted)
34
36
  *
35
- * const searchQuery$ = source<string>();
37
+ * const input$ = source<string>();
36
38
  *
37
- * const results$ = searchQuery$.pipe(
38
- * switchMap((query) => {
39
- * const result$ = source<string[]>();
39
+ * const result$ = input$.pipe(
40
+ * switchMap((letter) => {
41
+ * const inner$ = source<string>();
40
42
  *
41
43
  * setTimeout(() => {
42
- * result$.next([query]);
43
- *
44
- * result$.complete();
44
+ * inner$.next(`${letter}1`);
45
45
  * }, 10);
46
46
  *
47
- * return result$;
47
+ * setTimeout(() => {
48
+ * inner$.next(`${letter}2`);
49
+ * }, 110);
50
+ *
51
+ * setTimeout(() => {
52
+ * inner$.next(`${letter}3`);
53
+ * }, 210);
54
+ *
55
+ * return inner$;
48
56
  * }),
49
57
  * );
50
58
  *
51
- * const mut_history: string[][] = [];
59
+ * const valueHistory: string[] = [];
52
60
  *
53
- * results$.subscribe((value) => {
54
- * mut_history.push(value);
61
+ * result$.subscribe((value) => {
62
+ * valueHistory.push(value);
55
63
  * });
56
64
  *
57
- * searchQuery$.next('a');
65
+ * const sleep = (ms: number): Promise<void> =>
66
+ * new Promise((resolve) => {
67
+ * setTimeout(resolve, ms);
68
+ * });
58
69
  *
59
- * searchQuery$.next('ab');
70
+ * // Emit A - inner emits A1, A2, A3 at 10ms, 110ms, 210ms
71
+ * input$.next('A');
60
72
  *
61
- * searchQuery$.next('abc');
73
+ * await sleep(250);
62
74
  *
63
- * await new Promise((resolve) => {
64
- * setTimeout(resolve, 200);
65
- * });
75
+ * assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3']);
76
+ *
77
+ * // Emit B - inner starts emitting B1, B2 at 10ms, 110ms
78
+ * input$.next('B');
79
+ *
80
+ * await sleep(150);
81
+ *
82
+ * assert.deepStrictEqual(valueHistory, ['A1', 'A2', 'A3', 'B1', 'B2']);
83
+ *
84
+ * // Emit C - switches away from B (B3 cancelled), C's inner starts
85
+ * input$.next('C');
86
+ *
87
+ * await sleep(250);
66
88
  *
67
- * assert.deepStrictEqual(mut_history, [['abc']]);
89
+ * assert.deepStrictEqual(valueHistory, [
90
+ * 'A1',
91
+ * 'A2',
92
+ * 'A3',
93
+ * 'B1',
94
+ * 'B2',
95
+ * 'C1',
96
+ * 'C2',
97
+ * 'C3',
98
+ * ]);
68
99
  * ```
69
100
  *
70
101
  * @note To improve code readability, consider using `createState` instead of `switchMap`,
@@ -101,12 +132,12 @@ class SwitchMapObservableClass<A, B>
101
132
  this.#mut_subscription = undefined;
102
133
  }
103
134
 
104
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
135
+ override tryUpdate(updateToken: UpdateToken): void {
105
136
  const par = this.parents[0];
106
137
 
107
138
  const sn = par.getSnapshot();
108
139
 
109
- if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
140
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
110
141
  return; // skip update
111
142
  }
112
143
 
@@ -4,7 +4,7 @@ import {
4
4
  type KeepInitialValueOperator,
5
5
  type Observable,
6
6
  type TakeUntilOperatorObservable,
7
- type UpdaterSymbol,
7
+ type UpdateToken,
8
8
  } from '../types/index.mjs';
9
9
 
10
10
  /**
@@ -34,25 +34,25 @@ import {
34
34
  *
35
35
  * const limited$ = num$.pipe(takeUntil(stopNotifier));
36
36
  *
37
- * const mut_history: number[] = [];
37
+ * const valueHistory: number[] = [];
38
38
  *
39
39
  * limited$.subscribe((x) => {
40
- * mut_history.push(x);
40
+ * valueHistory.push(x);
41
41
  * });
42
42
  *
43
43
  * num$.next(1); // logs: 1
44
44
  *
45
- * assert.deepStrictEqual(mut_history, [1]);
45
+ * assert.deepStrictEqual(valueHistory, [1]);
46
46
  *
47
47
  * num$.next(2); // logs: 2
48
48
  *
49
- * assert.deepStrictEqual(mut_history, [1, 2]);
49
+ * assert.deepStrictEqual(valueHistory, [1, 2]);
50
50
  *
51
51
  * stop_();
52
52
  *
53
53
  * num$.next(3); // nothing logged (completed)
54
54
  *
55
- * assert.deepStrictEqual(mut_history, [1, 2]);
55
+ * assert.deepStrictEqual(valueHistory, [1, 2]);
56
56
  * ```
57
57
  */
58
58
  export const takeUntil = <A,>(
@@ -85,15 +85,15 @@ class TakeUntilObservableClass<A>
85
85
  );
86
86
  }
87
87
 
88
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
88
+ override tryUpdate(updateToken: UpdateToken): void {
89
89
  const par = this.parents[0];
90
90
 
91
91
  const sn = par.getSnapshot();
92
92
 
93
- if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
93
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
94
94
  return; // skip update
95
95
  }
96
96
 
97
- this.setNext(sn.value, updaterSymbol);
97
+ this.setNext(sn.value, updateToken);
98
98
  }
99
99
  }
@@ -12,7 +12,7 @@ import {
12
12
  type InitializedObservable,
13
13
  type Observable,
14
14
  type TakeWhileOperatorObservable,
15
- type UpdaterSymbol,
15
+ type UpdateToken,
16
16
  } from '../types/index.mjs';
17
17
  import { withInitialValue } from './with-initial-value.mjs';
18
18
 
@@ -28,7 +28,7 @@ import { withInitialValue } from './with-initial-value.mjs';
28
28
  * ```ts
29
29
  * // Timeline:
30
30
  * //
31
- * // num$ 1 2 3 4 5 6 (ignored)
31
+ * // num$ 1 2 3 4 5 6 1 2 (ignored)
32
32
  * // taken$ 1 2 3 4 | (completes)
33
33
  * //
34
34
  * // Explanation:
@@ -40,27 +40,35 @@ import { withInitialValue } from './with-initial-value.mjs';
40
40
  *
41
41
  * const taken$ = num$.pipe(takeWhile((x) => x < 5));
42
42
  *
43
- * const mut_history: number[] = [];
43
+ * const valueHistory: number[] = [];
44
44
  *
45
45
  * taken$.subscribe((x) => {
46
- * mut_history.push(x);
46
+ * valueHistory.push(x);
47
47
  * });
48
48
  *
49
49
  * num$.next(1); // logs: 1
50
50
  *
51
- * assert.deepStrictEqual(mut_history, [1]);
51
+ * assert.deepStrictEqual(valueHistory, [1]);
52
52
  *
53
53
  * num$.next(2); // logs: 2
54
54
  *
55
- * assert.deepStrictEqual(mut_history, [1, 2]);
55
+ * num$.next(3); // logs: 3
56
+ *
57
+ * num$.next(4); // logs: 4
58
+ *
59
+ * assert.deepStrictEqual(valueHistory, [1, 2, 3, 4]);
56
60
  *
57
61
  * num$.next(5); // nothing logged (completes)
58
62
  *
59
- * assert.deepStrictEqual(mut_history, [1, 2]);
63
+ * assert.deepStrictEqual(valueHistory, [1, 2, 3, 4]);
60
64
  *
61
65
  * num$.next(6); // nothing logged (already completed)
62
66
  *
63
- * assert.deepStrictEqual(mut_history, [1, 2]);
67
+ * assert.deepStrictEqual(valueHistory, [1, 2, 3, 4]);
68
+ *
69
+ * num$.next(1); // logs: 1
70
+ *
71
+ * assert.deepStrictEqual(valueHistory, [1, 2, 3, 4]);
64
72
  * ```
65
73
  */
66
74
  export const takeWhile =
@@ -70,12 +78,6 @@ export const takeWhile =
70
78
  (parentObservable) =>
71
79
  new TakeWhileObservableClass(parentObservable, predicate);
72
80
 
73
- /* Specialized operators */
74
-
75
- export const take = <A,>(
76
- n: PositiveSafeIntWithSmallInt,
77
- ): DropInitialValueOperator<A, A> => takeWhile((_, index) => index + 1 <= n);
78
-
79
81
  /* implementation */
80
82
 
81
83
  class TakeWhileObservableClass<A>
@@ -105,12 +107,12 @@ class TakeWhileObservableClass<A>
105
107
  this.#predicate = predicate;
106
108
  }
107
109
 
108
- override tryUpdate(updaterSymbol: UpdaterSymbol): void {
110
+ override tryUpdate(updateToken: UpdateToken): void {
109
111
  const par = this.parents[0];
110
112
 
111
113
  const sn = par.getSnapshot();
112
114
 
113
- if (par.updaterSymbol !== updaterSymbol || Optional.isNone(sn)) {
115
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
114
116
  return; // skip update
115
117
  }
116
118
 
@@ -118,7 +120,7 @@ class TakeWhileObservableClass<A>
118
120
  this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
119
121
 
120
122
  if (this.#predicate(sn.value, this.#mut_index)) {
121
- this.setNext(sn.value, updaterSymbol);
123
+ this.setNext(sn.value, updateToken);
122
124
  } else {
123
125
  this.complete();
124
126
  }
@@ -133,7 +135,7 @@ if (import.meta.vitest !== undefined) {
133
135
  {
134
136
  const s: Observable<number> = source<number>();
135
137
 
136
- const _d1 = s.pipe(take(3));
138
+ const _d1 = s.pipe(takeWhile((_, index) => index + 1 <= 3));
137
139
 
138
140
  expectType<typeof _d1, Observable<number>>('=');
139
141
  }
@@ -143,7 +145,7 @@ if (import.meta.vitest !== undefined) {
143
145
 
144
146
  const m: InitializedObservable<number> = s.pipe(withInitialValue(0));
145
147
 
146
- const _d = m.pipe(take(3));
148
+ const _d = m.pipe(takeWhile((_, index) => index + 1 <= 3));
147
149
 
148
150
  expectType<typeof _d, Observable<number>>('=');
149
151
  }