synstate 1.0.1 → 2.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 (194) hide show
  1. package/README.md +9 -10
  2. package/dist/core/class/child-observable-class.d.mts.map +1 -1
  3. package/dist/core/class/child-observable-class.mjs +148 -140
  4. package/dist/core/class/child-observable-class.mjs.map +1 -1
  5. package/dist/core/class/observable-base-class.d.mts.map +1 -1
  6. package/dist/core/class/observable-base-class.mjs +111 -107
  7. package/dist/core/class/observable-base-class.mjs.map +1 -1
  8. package/dist/core/class/root-observable-class.d.mts.map +1 -1
  9. package/dist/core/class/root-observable-class.mjs +32 -24
  10. package/dist/core/class/root-observable-class.mjs.map +1 -1
  11. package/dist/core/combine/combine.d.mts +3 -3
  12. package/dist/core/combine/combine.d.mts.map +1 -1
  13. package/dist/core/combine/combine.mjs +31 -113
  14. package/dist/core/combine/combine.mjs.map +1 -1
  15. package/dist/core/combine/merge.d.mts +2 -2
  16. package/dist/core/combine/merge.d.mts.map +1 -1
  17. package/dist/core/combine/merge.mjs +21 -69
  18. package/dist/core/combine/merge.mjs.map +1 -1
  19. package/dist/core/combine/zip.d.mts +2 -2
  20. package/dist/core/combine/zip.d.mts.map +1 -1
  21. package/dist/core/combine/zip.mjs +34 -79
  22. package/dist/core/combine/zip.mjs.map +1 -1
  23. package/dist/core/create/counter.d.mts +1 -1
  24. package/dist/core/create/counter.d.mts.map +1 -1
  25. package/dist/core/create/counter.mjs +45 -84
  26. package/dist/core/create/counter.mjs.map +1 -1
  27. package/dist/core/create/from-abortable-promise.d.mts.map +1 -1
  28. package/dist/core/create/from-abortable-promise.mjs +29 -61
  29. package/dist/core/create/from-abortable-promise.mjs.map +1 -1
  30. package/dist/core/create/from-promise.d.mts.map +1 -1
  31. package/dist/core/create/from-promise.mjs +17 -66
  32. package/dist/core/create/from-promise.mjs.map +1 -1
  33. package/dist/core/create/from-subscribable.d.mts.map +1 -1
  34. package/dist/core/create/from-subscribable.mjs +18 -69
  35. package/dist/core/create/from-subscribable.mjs.map +1 -1
  36. package/dist/core/create/just.d.mts.map +1 -1
  37. package/dist/core/create/just.mjs +5 -35
  38. package/dist/core/create/just.mjs.map +1 -1
  39. package/dist/core/create/source.mjs +10 -13
  40. package/dist/core/create/source.mjs.map +1 -1
  41. package/dist/core/create/timer.d.mts.map +1 -1
  42. package/dist/core/create/timer.mjs +32 -68
  43. package/dist/core/create/timer.mjs.map +1 -1
  44. package/dist/core/operators/audit.d.mts.map +1 -1
  45. package/dist/core/operators/audit.mjs +39 -133
  46. package/dist/core/operators/audit.mjs.map +1 -1
  47. package/dist/core/operators/debounce.d.mts.map +1 -1
  48. package/dist/core/operators/debounce.mjs +36 -119
  49. package/dist/core/operators/debounce.mjs.map +1 -1
  50. package/dist/core/operators/filter.mjs +22 -25
  51. package/dist/core/operators/filter.mjs.map +1 -1
  52. package/dist/core/operators/map.d.mts.map +1 -1
  53. package/dist/core/operators/map.mjs +28 -61
  54. package/dist/core/operators/map.mjs.map +1 -1
  55. package/dist/core/operators/merge-map.d.mts +1 -1
  56. package/dist/core/operators/merge-map.d.mts.map +1 -1
  57. package/dist/core/operators/merge-map.mjs +34 -130
  58. package/dist/core/operators/merge-map.mjs.map +1 -1
  59. package/dist/core/operators/pairwise.d.mts +3 -2
  60. package/dist/core/operators/pairwise.d.mts.map +1 -1
  61. package/dist/core/operators/pairwise.mjs +19 -75
  62. package/dist/core/operators/pairwise.mjs.map +1 -1
  63. package/dist/core/operators/scan.d.mts.map +1 -1
  64. package/dist/core/operators/scan.mjs +16 -67
  65. package/dist/core/operators/scan.mjs.map +1 -1
  66. package/dist/core/operators/skip-if-no-change.d.mts +1 -1
  67. package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
  68. package/dist/core/operators/skip-if-no-change.mjs +28 -92
  69. package/dist/core/operators/skip-if-no-change.mjs.map +1 -1
  70. package/dist/core/operators/skip-until.d.mts.map +1 -1
  71. package/dist/core/operators/skip-until.mjs +23 -72
  72. package/dist/core/operators/skip-until.mjs.map +1 -1
  73. package/dist/core/operators/skip-while.d.mts.map +1 -1
  74. package/dist/core/operators/skip-while.mjs +26 -88
  75. package/dist/core/operators/skip-while.mjs.map +1 -1
  76. package/dist/core/operators/switch-map.d.mts.map +1 -1
  77. package/dist/core/operators/switch-map.mjs +31 -124
  78. package/dist/core/operators/switch-map.mjs.map +1 -1
  79. package/dist/core/operators/take-until.d.mts.map +1 -1
  80. package/dist/core/operators/take-until.mjs +28 -69
  81. package/dist/core/operators/take-until.mjs.map +1 -1
  82. package/dist/core/operators/take-while.d.mts.map +1 -1
  83. package/dist/core/operators/take-while.mjs +23 -83
  84. package/dist/core/operators/take-while.mjs.map +1 -1
  85. package/dist/core/operators/throttle.d.mts.map +1 -1
  86. package/dist/core/operators/throttle.mjs +38 -115
  87. package/dist/core/operators/throttle.mjs.map +1 -1
  88. package/dist/core/operators/with-buffered-from.d.mts +1 -1
  89. package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
  90. package/dist/core/operators/with-buffered-from.mjs +37 -90
  91. package/dist/core/operators/with-buffered-from.mjs.map +1 -1
  92. package/dist/core/operators/with-current-value-from.d.mts +1 -1
  93. package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
  94. package/dist/core/operators/with-current-value-from.mjs +23 -84
  95. package/dist/core/operators/with-current-value-from.mjs.map +1 -1
  96. package/dist/core/operators/with-initial-value.d.mts.map +1 -1
  97. package/dist/core/operators/with-initial-value.mjs +13 -58
  98. package/dist/core/operators/with-initial-value.mjs.map +1 -1
  99. package/dist/core/predefined/operators/attach-index.d.mts +1 -1
  100. package/dist/core/predefined/operators/attach-index.d.mts.map +1 -1
  101. package/dist/core/predefined/operators/attach-index.mjs +0 -53
  102. package/dist/core/predefined/operators/attach-index.mjs.map +1 -1
  103. package/dist/core/predefined/operators/map-optional.d.mts.map +1 -1
  104. package/dist/core/predefined/operators/map-optional.mjs +1 -48
  105. package/dist/core/predefined/operators/map-optional.mjs.map +1 -1
  106. package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -1
  107. package/dist/core/predefined/operators/map-result-err.mjs +1 -48
  108. package/dist/core/predefined/operators/map-result-err.mjs.map +1 -1
  109. package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -1
  110. package/dist/core/predefined/operators/map-result-ok.mjs +1 -48
  111. package/dist/core/predefined/operators/map-result-ok.mjs.map +1 -1
  112. package/dist/core/predefined/operators/map-to.d.mts.map +1 -1
  113. package/dist/core/predefined/operators/map-to.mjs +0 -40
  114. package/dist/core/predefined/operators/map-to.mjs.map +1 -1
  115. package/dist/core/predefined/operators/pluck.d.mts +1 -1
  116. package/dist/core/predefined/operators/pluck.d.mts.map +1 -1
  117. package/dist/core/predefined/operators/pluck.mjs +0 -43
  118. package/dist/core/predefined/operators/pluck.mjs.map +1 -1
  119. package/dist/core/predefined/operators/skip.d.mts.map +1 -1
  120. package/dist/core/predefined/operators/skip.mjs +0 -47
  121. package/dist/core/predefined/operators/skip.mjs.map +1 -1
  122. package/dist/core/predefined/operators/take.d.mts.map +1 -1
  123. package/dist/core/predefined/operators/take.mjs +0 -41
  124. package/dist/core/predefined/operators/take.mjs.map +1 -1
  125. package/dist/core/predefined/operators/unwrap-optional.mjs +4 -43
  126. package/dist/core/predefined/operators/unwrap-optional.mjs.map +1 -1
  127. package/dist/core/predefined/operators/unwrap-result-err.mjs +0 -40
  128. package/dist/core/predefined/operators/unwrap-result-err.mjs.map +1 -1
  129. package/dist/core/predefined/operators/unwrap-result-ok.mjs +4 -43
  130. package/dist/core/predefined/operators/unwrap-result-ok.mjs.map +1 -1
  131. package/dist/core/types/observable-family.d.mts +10 -10
  132. package/dist/core/types/observable-family.d.mts.map +1 -1
  133. package/dist/core/types/observable.d.mts.map +1 -1
  134. package/dist/core/types/observable.mjs +3 -5
  135. package/dist/core/types/observable.mjs.map +1 -1
  136. package/dist/core/types/types.d.mts +2 -1
  137. package/dist/core/types/types.d.mts.map +1 -1
  138. package/dist/core/utils/id-maker.mjs +5 -6
  139. package/dist/core/utils/id-maker.mjs.map +1 -1
  140. package/dist/core/utils/max-depth.d.mts.map +1 -1
  141. package/dist/core/utils/max-depth.mjs +1 -3
  142. package/dist/core/utils/max-depth.mjs.map +1 -1
  143. package/dist/core/utils/observable-utils.d.mts.map +1 -1
  144. package/dist/core/utils/observable-utils.mjs +3 -2
  145. package/dist/core/utils/observable-utils.mjs.map +1 -1
  146. package/dist/core/utils/utils.d.mts.map +1 -1
  147. package/dist/core/utils/utils.mjs +23 -30
  148. package/dist/core/utils/utils.mjs.map +1 -1
  149. package/dist/utils/collect-to-array.d.mts.map +1 -1
  150. package/dist/utils/collect-to-array.mjs +9 -6
  151. package/dist/utils/collect-to-array.mjs.map +1 -1
  152. package/dist/utils/create-boolean-state.d.mts +1 -1
  153. package/dist/utils/create-boolean-state.d.mts.map +1 -1
  154. package/dist/utils/create-boolean-state.mjs +18 -46
  155. package/dist/utils/create-boolean-state.mjs.map +1 -1
  156. package/dist/utils/create-event-emitter.mjs +10 -64
  157. package/dist/utils/create-event-emitter.mjs.map +1 -1
  158. package/dist/utils/create-reducer.d.mts +1 -1
  159. package/dist/utils/create-reducer.d.mts.map +1 -1
  160. package/dist/utils/create-reducer.mjs +8 -52
  161. package/dist/utils/create-reducer.mjs.map +1 -1
  162. package/dist/utils/create-state.d.mts +1 -1
  163. package/dist/utils/create-state.d.mts.map +1 -1
  164. package/dist/utils/create-state.mjs +23 -53
  165. package/dist/utils/create-state.mjs.map +1 -1
  166. package/package.json +16 -16
  167. package/src/core/class/child-observable-class.mts +1 -1
  168. package/src/core/class/observable-base-class.mts +16 -16
  169. package/src/core/combine/combine.mts +38 -16
  170. package/src/core/combine/merge.mts +3 -3
  171. package/src/core/combine/zip.mts +24 -13
  172. package/src/core/create/counter.mts +11 -9
  173. package/src/core/create/counter.test.mts +11 -0
  174. package/src/core/create/timer.mts +6 -6
  175. package/src/core/create/timer.test.mts +11 -0
  176. package/src/core/operators/audit-throttle-teardown.test.mts +21 -0
  177. package/src/core/operators/audit.mts +6 -6
  178. package/src/core/operators/debounce.mts +6 -6
  179. package/src/core/operators/pairwise.mts +10 -5
  180. package/src/core/operators/skip-while.mts +1 -5
  181. package/src/core/operators/skip-while.test.mts +20 -0
  182. package/src/core/operators/throttle.mts +6 -6
  183. package/src/core/operators/with-buffered-from.mts +4 -4
  184. package/src/core/predefined/operators/map-optional.mts +1 -2
  185. package/src/core/predefined/operators/map-result-err.mts +1 -1
  186. package/src/core/predefined/operators/map-result-ok.mts +1 -1
  187. package/src/core/types/observable-family.mts +12 -11
  188. package/src/core/types/observable.mts +5 -7
  189. package/src/core/types/types.mts +2 -1
  190. package/src/core/utils/max-depth.mts +5 -1
  191. package/src/core/utils/utils.mts +1 -1
  192. package/src/utils/create-boolean-state.mts +1 -1
  193. package/src/utils/create-reducer.mts +1 -1
  194. package/src/utils/create-state.mts +1 -1
@@ -3,21 +3,18 @@ import '../utils/id-maker.mjs';
3
3
  import { RootObservableClass } from '../class/root-observable-class.mjs';
4
4
 
5
5
  function source(...args) {
6
- return new SourceObservableClass(...args);
6
+ return new SourceObservableClass(...args);
7
7
  }
8
8
  class SourceObservableClass extends RootObservableClass {
9
- constructor(...args) {
10
- super({
11
- initialValue: Arr.isNonEmpty(args)
12
- ? Optional.some(args[0])
13
- : Optional.none,
14
- });
15
- }
16
- next(nextValue) {
17
- if (this.isCompleted)
18
- return;
19
- this.startUpdate(nextValue);
20
- }
9
+ constructor(...args) {
10
+ super({
11
+ initialValue: Arr.isNonEmpty(args) ? Optional.some(args[0]) : Optional.none
12
+ });
13
+ }
14
+ next(nextValue) {
15
+ if (this.isCompleted) return;
16
+ this.startUpdate(nextValue);
17
+ }
21
18
  }
22
19
 
23
20
  export { source };
@@ -1 +1 @@
1
- {"version":3,"file":"source.mjs","sources":["../../../src/core/create/source.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAoDM,SAAU,MAAM,CAAU,GAAG,IAAkB,EAAA;AACnD,IAAA,OAAO,IAAI,qBAAqB,CAAI,GAAG,IAAI,CAAC;AAC9C;AAEA,MAAM,qBACJ,SAAQ,mBAAsB,CAAA;AAG9B,IAAA,WAAA,CAAY,GAAG,IAAkB,EAAA;AAC/B,QAAA,KAAK,CAAC;AACJ,YAAA,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI;kBAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;kBACrB,QAAQ,CAAC,IAAI;AAClB,SAAA,CAAC;IACJ;AAEA,IAAA,IAAI,CAAC,SAAY,EAAA;QACf,IAAI,IAAI,CAAC,WAAW;YAAE;AAEtB,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;IAC7B;AACD;;;;"}
1
+ {"version":3,"file":"source.mjs","sources":["../../../src/core/create/source.mts"],"sourcesContent":["import { Arr, Optional } from 'ts-data-forge';\nimport { RootObservableClass } from '../class/index.mjs';\nimport {\n type InitializedSourceObservable,\n type SourceObservable,\n} from '../types/index.mjs';\n\n/**\n * Creates a new Observable source that can manually emit values.\n * This is the primary way to create root observables that start reactive chains.\n *\n * @template A - The type of values emitted by the source\n * @returns A SourceObservable that can emit values via `.next()` method\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // count$ 1 2 3 ...\n * //\n * // Explanation:\n * // - source creates a new observable that you can manually emit values to\n * // - Use .next() to emit values\n * // - Foundation for building custom observables\n *\n * const count$ = source<number>();\n *\n * const valueHistory: number[] = [];\n *\n * count$.subscribe((value) => {\n * valueHistory.push(value);\n * });\n *\n * count$.next(1); // logs: 1\n *\n * assert.deepStrictEqual(valueHistory, [1]);\n *\n * count$.next(2); // logs: 2\n *\n * assert.deepStrictEqual(valueHistory, [1, 2]);\n *\n * count$.next(3); // logs: 3\n *\n * assert.deepStrictEqual(valueHistory, [1, 2, 3]);\n * ```\n */\nexport function source<const A>(\n initialValue: A,\n): InitializedSourceObservable<A>;\n\nexport function source<const A>(): SourceObservable<A>;\n\nexport function source<const A>(...args: readonly A[]): SourceObservable<A> {\n return new SourceObservableClass<A>(...args);\n}\n\nclass SourceObservableClass<A>\n extends RootObservableClass<A>\n implements SourceObservable<A>\n{\n constructor(...args: readonly A[]) {\n super({\n initialValue: Arr.isNonEmpty(args)\n ? Optional.some(args[0])\n : Optional.none,\n });\n }\n\n next(nextValue: A): void {\n if (this.isCompleted) return;\n\n this.startUpdate(nextValue);\n }\n}\n"],"names":[],"mappings":";;;;AAoDO,SAAS,UAAmB,IAAA,EAAyC;AAC1E,EAAA,OAAO,IAAI,qBAAA,CAAyB,GAAG,IAAI,CAAA;AAC7C;AAEA,MAAM,8BACI,mBAAA,CAEV;AAAA,EACE,eAAe,IAAA,EAAoB;AACjC,IAAA,KAAA,CAAM;AAAA,MACJ,YAAA,EAAc,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA,GAC7B,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA,GACrB,QAAA,CAAS;AAAA,KACd,CAAA;AAAA,EACH;AAAA,EAEA,KAAK,SAAA,EAAoB;AACvB,IAAA,IAAI,KAAK,WAAA,EAAa;AAEtB,IAAA,IAAA,CAAK,YAAY,SAAS,CAAA;AAAA,EAC5B;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"timer.d.mts","sourceRoot":"","sources":["../../../src/core/create/timer.mts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,KAAK,GAChB,cAAc,MAAM,EACpB,UAAU,QAAQ,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC,KACD,eACsE,CAAC"}
1
+ {"version":3,"file":"timer.d.mts","sourceRoot":"","sources":["../../../src/core/create/timer.mts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,KAAK,iBACF,MAAM,YACV,QAAQ,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC,KACD,eACsE,CAAC"}
@@ -2,80 +2,44 @@ import { Optional } from 'ts-data-forge';
2
2
  import '../utils/id-maker.mjs';
3
3
  import { RootObservableClass } from '../class/root-observable-class.mjs';
4
4
 
5
- /**
6
- * Creates an observable that emits 0 after a specified delay and then completes.
7
- *
8
- * @param milliSeconds - The delay in milliseconds before emission
9
- * @param startManually - If true, waits for manual start (default: false)
10
- * @returns An observable that emits after delay
11
- *
12
- * @example
13
- * ```ts
14
- * // Timeline:
15
- * //
16
- * // Time(ms) 0 ... 1000
17
- * // delayed$ X (emits and completes)
18
- * //
19
- * // Explanation:
20
- * // - timer emits once after the specified delay, then completes
21
- * // - Useful for delayed actions or timeouts
22
- *
23
- * const delayed$ = timer(100);
24
- *
25
- * const valueHistory: number[] = [];
26
- *
27
- * await new Promise<void>((resolve) => {
28
- * delayed$.subscribe(
29
- * () => {
30
- * valueHistory.push(1);
31
- * },
32
- * () => {
33
- * resolve();
34
- * },
35
- * );
36
- * });
37
- *
38
- * assert.deepStrictEqual(valueHistory, [1]);
39
- * ```
40
- */
41
5
  const timer = (milliSeconds, options) => new TimerObservableClass(milliSeconds, options?.startManually ?? false);
42
6
  class TimerObservableClass extends RootObservableClass {
43
- #milliSeconds;
44
- #mut_timerId;
45
- #mut_isStarted;
46
- constructor(milliSeconds, startManually) {
47
- super({ initialValue: Optional.none });
48
- this.#milliSeconds = milliSeconds;
49
- this.#mut_timerId = undefined;
50
- this.#mut_isStarted = false;
51
- if (!startManually) {
52
- this.start();
53
- }
7
+ #milliSeconds;
8
+ #mut_timerId;
9
+ #mut_isStarted;
10
+ constructor(milliSeconds, startManually) {
11
+ super({ initialValue: Optional.none });
12
+ this.#milliSeconds = milliSeconds;
13
+ this.#mut_timerId = void 0;
14
+ this.#mut_isStarted = false;
15
+ if (!startManually) {
16
+ this.start();
54
17
  }
55
- start() {
56
- if (this.#mut_isStarted) {
57
- console.warn('cannot start twice');
58
- return;
59
- }
60
- this.#mut_isStarted = true;
61
- if (this.isCompleted) {
62
- console.warn('cannot restart stopped TimerObservable');
63
- return;
64
- }
65
- this.#mut_timerId = setTimeout(() => {
66
- this.startUpdate(0);
67
- this.complete();
68
- }, this.#milliSeconds);
18
+ }
19
+ #resetTimer() {
20
+ if (this.#mut_timerId !== void 0) {
21
+ clearTimeout(this.#mut_timerId);
69
22
  }
70
- #resetTimer() {
71
- if (this.#mut_timerId !== undefined) {
72
- clearTimeout(this.#mut_timerId);
73
- }
23
+ }
24
+ start() {
25
+ if (this.#mut_isStarted) {
26
+ console.warn("cannot start twice");
27
+ return;
74
28
  }
75
- complete() {
76
- this.#resetTimer();
77
- super.complete();
29
+ this.#mut_isStarted = true;
30
+ if (this.isCompleted) {
31
+ console.warn("cannot restart stopped TimerObservable");
32
+ return;
78
33
  }
34
+ this.#mut_timerId = setTimeout(() => {
35
+ this.startUpdate(0);
36
+ this.complete();
37
+ }, this.#milliSeconds);
38
+ }
39
+ complete() {
40
+ this.#resetTimer();
41
+ super.complete();
42
+ }
79
43
  }
80
44
 
81
45
  export { timer };
@@ -1 +1 @@
1
- {"version":3,"file":"timer.mjs","sources":["../../../src/core/create/timer.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCG;MACU,KAAK,GAAG,CACnB,YAAoB,EACpB,OAEE,KAEF,IAAI,oBAAoB,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,IAAI,KAAK;AAExE,MAAM,oBACJ,SAAQ,mBAAsB,CAAA;AAGrB,IAAA,aAAa;AACtB,IAAA,YAAY;AACZ,IAAA,cAAc;IAEd,WAAA,CAAY,YAAoB,EAAE,aAAsB,EAAA;QACtD,KAAK,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AAEtC,QAAA,IAAI,CAAC,aAAa,GAAG,YAAY;AAEjC,QAAA,IAAI,CAAC,YAAY,GAAG,SAAS;AAE7B,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK;QAE3B,IAAI,CAAC,aAAa,EAAE;YAClB,IAAI,CAAC,KAAK,EAAE;QACd;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC;YAElC;QACF;AAEA,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAE1B,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,YAAA,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC;YAEtD;QACF;AAEA,QAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAK;AAClC,YAAA,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnB,IAAI,CAAC,QAAQ,EAAE;AACjB,QAAA,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC;IACxB;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE;AACnC,YAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;QACjC;IACF;IAES,QAAQ,GAAA;QACf,IAAI,CAAC,WAAW,EAAE;QAElB,KAAK,CAAC,QAAQ,EAAE;IAClB;AACD;;;;"}
1
+ {"version":3,"file":"timer.mjs","sources":["../../../src/core/create/timer.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { RootObservableClass } from '../class/index.mjs';\nimport { type TimerId, type TimerObservable } from '../types/index.mjs';\n\n/**\n * Creates an observable that emits 0 after a specified delay and then completes.\n *\n * @param milliSeconds - The delay in milliseconds before emission\n * @param startManually - If true, waits for manual start (default: false)\n * @returns An observable that emits after delay\n *\n * @example\n * ```ts\n * // Timeline:\n * //\n * // Time(ms) 0 ... 1000\n * // delayed$ X (emits and completes)\n * //\n * // Explanation:\n * // - timer emits once after the specified delay, then completes\n * // - Useful for delayed actions or timeouts\n *\n * const delayed$ = timer(100);\n *\n * const valueHistory: number[] = [];\n *\n * await new Promise<void>((resolve) => {\n * delayed$.subscribe(\n * () => {\n * valueHistory.push(1);\n * },\n * () => {\n * resolve();\n * },\n * );\n * });\n *\n * assert.deepStrictEqual(valueHistory, [1]);\n * ```\n */\nexport const timer = (\n milliSeconds: number,\n options?: Readonly<{\n startManually?: boolean;\n }>,\n): TimerObservable =>\n new TimerObservableClass(milliSeconds, options?.startManually ?? false);\n\nclass TimerObservableClass\n extends RootObservableClass<0>\n implements TimerObservable\n{\n readonly #milliSeconds: number;\n #mut_timerId: TimerId | undefined;\n #mut_isStarted: boolean;\n\n constructor(milliSeconds: number, startManually: boolean) {\n super({ initialValue: Optional.none });\n\n this.#milliSeconds = milliSeconds;\n\n this.#mut_timerId = undefined;\n\n this.#mut_isStarted = false;\n\n if (!startManually) {\n this.start();\n }\n }\n\n #resetTimer(): void {\n if (this.#mut_timerId !== undefined) {\n clearTimeout(this.#mut_timerId);\n }\n }\n\n start(): void {\n if (this.#mut_isStarted) {\n console.warn('cannot start twice');\n\n return;\n }\n\n this.#mut_isStarted = true;\n\n if (this.isCompleted) {\n console.warn('cannot restart stopped TimerObservable');\n\n return;\n }\n\n this.#mut_timerId = setTimeout(() => {\n this.startUpdate(0);\n\n this.complete();\n }, this.#milliSeconds);\n }\n\n override complete(): void {\n this.#resetTimer();\n\n super.complete();\n }\n}\n"],"names":[],"mappings":";;;;AAwCO,MAAM,KAAA,GAAQ,CACnB,YAAA,EACA,OAAA,KAIA,IAAI,oBAAA,CAAqB,YAAA,EAAc,OAAA,EAAS,aAAA,IAAiB,KAAK;AAExE,MAAM,6BACI,mBAAA,CAEV;AAAA,EACW,aAAA;AAAA,EACT,YAAA;AAAA,EACA,cAAA;AAAA,EAEA,WAAA,CAAY,cAAsB,aAAA,EAAwB;AACxD,IAAA,KAAA,CAAM,EAAE,YAAA,EAAc,QAAA,CAAS,IAAA,EAAM,CAAA;AAErC,IAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAErB,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AAEpB,IAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AAEtB,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,WAAA,GAAoB;AAClB,IAAA,IAAI,IAAA,CAAK,iBAAiB,MAAA,EAAW;AACnC,MAAA,YAAA,CAAa,KAAK,YAAY,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,OAAA,CAAQ,KAAK,oBAAoB,CAAA;AAEjC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAEtB,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,OAAA,CAAQ,KAAK,wCAAwC,CAAA;AAErD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,MAAM;AACnC,MAAA,IAAA,CAAK,YAAY,CAAC,CAAA;AAElB,MAAA,IAAA,CAAK,QAAA,EAAS;AAAA,IAChB,CAAA,EAAG,KAAK,aAAa,CAAA;AAAA,EACvB;AAAA,EAES,QAAA,GAAiB;AACxB,IAAA,IAAA,CAAK,WAAA,EAAY;AAEjB,IAAA,KAAA,CAAM,QAAA,EAAS;AAAA,EACjB;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.mts","sourceRoot":"","sources":["../../../src/core/operators/audit.mts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,EACrB,cAAc,MAAM,KACnB,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAMQ,CAAC"}
1
+ {"version":3,"file":"audit.d.mts","sourceRoot":"","sources":["../../../src/core/operators/audit.mts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,gBACP,MAAM,KACnB,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAMQ,CAAC"}
@@ -2,142 +2,48 @@ import { Optional } from 'ts-data-forge';
2
2
  import { AsyncChildObservableClass } from '../class/child-observable-class.mjs';
3
3
  import '../utils/id-maker.mjs';
4
4
 
5
- /**
6
- * Ignores source values for duration milliseconds, then emits the most recent value from the source Observable, then repeats this process.
7
- *
8
- * Unlike `throttle` which emits the first value, `audit` emits the last value.
9
- *
10
- * @template A - The type of values from the source
11
- * @param milliSeconds - The audit time window in milliseconds
12
- * @returns An operator that audits emissions from the observable
13
- *
14
- * @example
15
- * ```ts
16
- * // Timeline (250ms audit):
17
- * //
18
- * // Time(x50ms) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
19
- * //
20
- * // input$ 0 2 3 9 10 11 12 13 14
21
- * // |- 250ms -> |- 250ms -> |- 250ms -> |- 250ms ->
22
- * // audited$ 2 3 11 14 (emitted at end of window)
23
- * //
24
- * // Explanation:
25
- * // - audit emits the LAST value received during each time window
26
- * // - Unlike throttle (which emits the FIRST value), audit emits the LAST
27
- * // - Useful when you want the most recent value after a burst of events
28
- *
29
- * const input$ = source<number>();
30
- *
31
- * const audited$ = input$.pipe(audit(250));
32
- *
33
- * const valueHistory: number[] = [];
34
- *
35
- * audited$.subscribe((value) => {
36
- * valueHistory.push(value);
37
- * });
38
- *
39
- * const sleep = (ms: number): Promise<void> =>
40
- * new Promise((resolve) => {
41
- * setTimeout(resolve, ms);
42
- * });
43
- *
44
- * input$.next(0);
45
- *
46
- * await sleep(200);
47
- *
48
- * input$.next(2);
49
- *
50
- * assert.deepStrictEqual(valueHistory, []);
51
- *
52
- * await sleep(100);
53
- *
54
- * assert.deepStrictEqual(valueHistory, [2]);
55
- *
56
- * input$.next(3);
57
- *
58
- * await sleep(300);
59
- *
60
- * assert.deepStrictEqual(valueHistory, [2, 3]);
61
- *
62
- * await sleep(300);
63
- *
64
- * input$.next(9);
65
- *
66
- * await sleep(100);
67
- *
68
- * input$.next(10);
69
- *
70
- * await sleep(100);
71
- *
72
- * input$.next(11);
73
- *
74
- * assert.deepStrictEqual(valueHistory, [2, 3]);
75
- *
76
- * await sleep(100);
77
- *
78
- * assert.deepStrictEqual(valueHistory, [2, 3, 11]);
79
- *
80
- * input$.next(12);
81
- *
82
- * await sleep(100);
83
- *
84
- * input$.next(13);
85
- *
86
- * assert.deepStrictEqual(valueHistory, [2, 3, 11]);
87
- *
88
- * await sleep(100);
89
- *
90
- * input$.next(14);
91
- *
92
- * assert.deepStrictEqual(valueHistory, [2, 3, 11]);
93
- *
94
- * await sleep(100);
95
- *
96
- * assert.deepStrictEqual(valueHistory, [2, 3, 11, 14]);
97
- * ```
98
- */
99
- const audit = (milliSeconds) =>
100
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
101
- ((parentObservable) => new AuditObservableClass(parentObservable, milliSeconds));
5
+ const audit = (milliSeconds) => (
6
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
7
+ ((parentObservable) => new AuditObservableClass(
8
+ parentObservable,
9
+ milliSeconds
10
+ ))
11
+ );
102
12
  class AuditObservableClass extends AsyncChildObservableClass {
103
- #milliSeconds;
104
- #mut_timerId;
105
- #mut_isSkipping;
106
- constructor(parentObservable, milliSeconds) {
107
- super({
108
- parents: [parentObservable],
109
- initialValue: parentObservable.getSnapshot(),
110
- });
111
- this.#mut_isSkipping = false;
112
- this.#mut_timerId = undefined;
113
- this.#milliSeconds = milliSeconds;
13
+ #milliSeconds;
14
+ #mut_timerId;
15
+ #mut_isSkipping;
16
+ constructor(parentObservable, milliSeconds) {
17
+ super({
18
+ parents: [parentObservable],
19
+ initialValue: parentObservable.getSnapshot()
20
+ });
21
+ this.#mut_isSkipping = false;
22
+ this.#mut_timerId = void 0;
23
+ this.#milliSeconds = milliSeconds;
24
+ }
25
+ #resetTimer() {
26
+ if (this.#mut_timerId !== void 0) {
27
+ clearTimeout(this.#mut_timerId);
114
28
  }
115
- tryUpdate(updateToken) {
116
- const par = this.parents[0];
117
- if (par.updateToken !== updateToken ||
118
- Optional.isNone(par.getSnapshot()) ||
119
- this.#mut_isSkipping) {
120
- return; // skip update
121
- }
122
- // set timer
123
- this.#mut_isSkipping = true;
124
- this.#mut_timerId = setTimeout(() => {
125
- const sn = par.getSnapshot();
126
- if (Optional.isNone(sn))
127
- return;
128
- this.startUpdate(sn.value);
129
- this.#mut_isSkipping = false;
130
- }, this.#milliSeconds);
131
- }
132
- #resetTimer() {
133
- if (this.#mut_timerId !== undefined) {
134
- clearTimeout(this.#mut_timerId);
135
- }
136
- }
137
- complete() {
138
- this.#resetTimer();
139
- super.complete();
29
+ }
30
+ tryUpdate(updateToken) {
31
+ const par = this.parents[0];
32
+ if (par.updateToken !== updateToken || Optional.isNone(par.getSnapshot()) || this.#mut_isSkipping) {
33
+ return;
140
34
  }
35
+ this.#mut_isSkipping = true;
36
+ this.#mut_timerId = setTimeout(() => {
37
+ const sn = par.getSnapshot();
38
+ if (Optional.isNone(sn)) return;
39
+ this.startUpdate(sn.value);
40
+ this.#mut_isSkipping = false;
41
+ }, this.#milliSeconds);
42
+ }
43
+ complete() {
44
+ this.#resetTimer();
45
+ super.complete();
46
+ }
141
47
  }
142
48
 
143
49
  export { audit };
@@ -1 +1 @@
1
- {"version":3,"file":"audit.mjs","sources":["../../../src/core/operators/audit.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FG;AACI,MAAM,KAAK,GAAG,CACnB,YAAoB;AAEpB;AACA,CAAC,CAAC,gBAAgB,KAChB,IAAI,oBAAoB,CACtB,gBAAgB,EAChB,YAAY,CACb;AAEL,MAAM,oBACJ,SAAQ,yBAA0C,CAAA;AAGzC,IAAA,aAAa;AACtB,IAAA,YAAY;AACZ,IAAA,eAAe;IAEf,WAAA,CAAY,gBAA+B,EAAE,YAAoB,EAAA;AAC/D,QAAA,KAAK,CAAC;YACJ,OAAO,EAAE,CAAC,gBAAgB,CAAC;AAC3B,YAAA,YAAY,EAAE,gBAAgB,CAAC,WAAW,EAAE;AAC7C,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,eAAe,GAAG,KAAK;AAE5B,QAAA,IAAI,CAAC,YAAY,GAAG,SAAS;AAE7B,QAAA,IAAI,CAAC,aAAa,GAAG,YAAY;IACnC;AAES,IAAA,SAAS,CAAC,WAAwB,EAAA;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAE3B,QAAA,IACE,GAAG,CAAC,WAAW,KAAK,WAAW;AAC/B,YAAA,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC,eAAe,EACpB;AACA,YAAA,OAAO;QACT;;AAGA,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI;AAE3B,QAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAK;AAClC,YAAA,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE;AAE5B,YAAA,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAE;AAEzB,YAAA,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC;AAE1B,YAAA,IAAI,CAAC,eAAe,GAAG,KAAK;AAC9B,QAAA,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC;IACxB;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE;AACnC,YAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;QACjC;IACF;IAES,QAAQ,GAAA;QACf,IAAI,CAAC,WAAW,EAAE;QAElB,KAAK,CAAC,QAAQ,EAAE;IAClB;AACD;;;;"}
1
+ {"version":3,"file":"audit.mjs","sources":["../../../src/core/operators/audit.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { AsyncChildObservableClass } from '../class/index.mjs';\nimport {\n type AuditOperatorObservable,\n type KeepInitialValueOperator,\n type Observable,\n type TimerId,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Ignores source values for duration milliseconds, then emits the most recent value from the source Observable, then repeats this process.\n *\n * Unlike `throttle` which emits the first value, `audit` emits the last value.\n *\n * @template A - The type of values from the source\n * @param milliSeconds - The audit time window in milliseconds\n * @returns An operator that audits emissions from the observable\n *\n * @example\n * ```ts\n * // Timeline (250ms audit):\n * //\n * // Time(x50ms) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0\n * //\n * // input$ 0 2 3 9 10 11 12 13 14\n * // |- 250ms -> |- 250ms -> |- 250ms -> |- 250ms ->\n * // audited$ 2 3 11 14 (emitted at end of window)\n * //\n * // Explanation:\n * // - audit emits the LAST value received during each time window\n * // - Unlike throttle (which emits the FIRST value), audit emits the LAST\n * // - Useful when you want the most recent value after a burst of events\n *\n * const input$ = source<number>();\n *\n * const audited$ = input$.pipe(audit(250));\n *\n * const valueHistory: number[] = [];\n *\n * audited$.subscribe((value) => {\n * valueHistory.push(value);\n * });\n *\n * const sleep = (ms: number): Promise<void> =>\n * new Promise((resolve) => {\n * setTimeout(resolve, ms);\n * });\n *\n * input$.next(0);\n *\n * await sleep(200);\n *\n * input$.next(2);\n *\n * assert.deepStrictEqual(valueHistory, []);\n *\n * await sleep(100);\n *\n * assert.deepStrictEqual(valueHistory, [2]);\n *\n * input$.next(3);\n *\n * await sleep(300);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3]);\n *\n * await sleep(300);\n *\n * input$.next(9);\n *\n * await sleep(100);\n *\n * input$.next(10);\n *\n * await sleep(100);\n *\n * input$.next(11);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3]);\n *\n * await sleep(100);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3, 11]);\n *\n * input$.next(12);\n *\n * await sleep(100);\n *\n * input$.next(13);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3, 11]);\n *\n * await sleep(100);\n *\n * input$.next(14);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3, 11]);\n *\n * await sleep(100);\n *\n * assert.deepStrictEqual(valueHistory, [2, 3, 11, 14]);\n * ```\n */\nexport const audit = <A,>(\n milliSeconds: number,\n): KeepInitialValueOperator<A, A> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n ((parentObservable) =>\n new AuditObservableClass(\n parentObservable,\n milliSeconds,\n )) as KeepInitialValueOperator<A, A>;\n\nclass AuditObservableClass<A>\n extends AsyncChildObservableClass<A, readonly [A]>\n implements AuditOperatorObservable<A>\n{\n readonly #milliSeconds: number;\n #mut_timerId: TimerId | undefined;\n #mut_isSkipping: boolean;\n\n constructor(parentObservable: Observable<A>, milliSeconds: number) {\n super({\n parents: [parentObservable],\n initialValue: parentObservable.getSnapshot(),\n });\n\n this.#mut_isSkipping = false;\n\n this.#mut_timerId = undefined;\n\n this.#milliSeconds = milliSeconds;\n }\n\n #resetTimer(): void {\n if (this.#mut_timerId !== undefined) {\n clearTimeout(this.#mut_timerId);\n }\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n if (\n par.updateToken !== updateToken ||\n Optional.isNone(par.getSnapshot()) ||\n this.#mut_isSkipping\n ) {\n return; // skip update\n }\n\n // set timer\n this.#mut_isSkipping = true;\n\n this.#mut_timerId = setTimeout(() => {\n const sn = par.getSnapshot();\n\n if (Optional.isNone(sn)) return;\n\n this.startUpdate(sn.value);\n\n this.#mut_isSkipping = false;\n }, this.#milliSeconds);\n }\n\n override complete(): void {\n this.#resetTimer();\n\n super.complete();\n }\n}\n"],"names":[],"mappings":";;;;AAwGO,MAAM,QAAQ,CACnB,YAAA;AAAA;AAAA,GAGC,CAAC,qBACA,IAAI,oBAAA;AAAA,IACF,gBAAA;AAAA,IACA;AAAA,GACF;AAAA;AAEJ,MAAM,6BACI,yBAAA,CAEV;AAAA,EACW,aAAA;AAAA,EACT,YAAA;AAAA,EACA,eAAA;AAAA,EAEA,WAAA,CAAY,kBAAiC,YAAA,EAAsB;AACjE,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,YAAA,EAAc,iBAAiB,WAAA;AAAY,KAC5C,CAAA;AAED,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAEvB,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AAEpB,IAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAAA,EACvB;AAAA,EAEA,WAAA,GAAoB;AAClB,IAAA,IAAI,IAAA,CAAK,iBAAiB,MAAA,EAAW;AACnC,MAAA,YAAA,CAAa,KAAK,YAAY,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,IACE,GAAA,CAAI,WAAA,KAAgB,WAAA,IACpB,QAAA,CAAS,MAAA,CAAO,IAAI,WAAA,EAAa,CAAA,IACjC,IAAA,CAAK,eAAA,EACL;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAEvB,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,MAAM;AACnC,MAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,MAAA,IAAI,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAEzB,MAAA,IAAA,CAAK,WAAA,CAAY,GAAG,KAAK,CAAA;AAEzB,MAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,IACzB,CAAA,EAAG,KAAK,aAAa,CAAA;AAAA,EACvB;AAAA,EAES,QAAA,GAAiB;AACxB,IAAA,IAAA,CAAK,WAAA,EAAY;AAEjB,IAAA,KAAA,CAAM,QAAA,EAAS;AAAA,EACjB;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.d.mts","sourceRoot":"","sources":["../../../src/core/operators/debounce.mts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EACxB,cAAc,MAAM,KACnB,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAMQ,CAAC"}
1
+ {"version":3,"file":"debounce.d.mts","sourceRoot":"","sources":["../../../src/core/operators/debounce.mts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAI9B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,gBACV,MAAM,KACnB,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAMQ,CAAC"}
@@ -2,128 +2,45 @@ import { Optional } from 'ts-data-forge';
2
2
  import { AsyncChildObservableClass } from '../class/child-observable-class.mjs';
3
3
  import '../utils/id-maker.mjs';
4
4
 
5
- /**
6
- * Delays emissions from the source observable until a specified time has passed without another emission.
7
- * Useful for handling user input events like typing or scrolling.
8
- *
9
- * @template A - The type of values from the source
10
- * @param milliSeconds - The debounce duration in milliseconds
11
- * @returns An operator that debounces the observable
12
- *
13
- * @example
14
- * ```ts
15
- * // Timeline (250ms debounce):
16
- * //
17
- * // Time(x50ms) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
18
- * //
19
- * // input$ 0 2 3 9 10 11 12 13 14
20
- * // |- 250ms -> |- 250ms ->
21
- * // debounced$ 3 14 (emitted after 250ms silence)
22
- * //
23
- * // Explanation:
24
- * // - debounce emits the latest value AFTER a quiet period with no new emissions
25
- * // - Unlike audit (which uses a fixed window), debounce resets the timer on every emission
26
- * // - Useful for search-as-you-type and form validation
27
- *
28
- * const input$ = source<number>();
29
- *
30
- * const debounced$ = input$.pipe(debounce(250));
31
- *
32
- * const valueHistory: number[] = [];
33
- *
34
- * debounced$.subscribe((value) => {
35
- * valueHistory.push(value);
36
- * });
37
- *
38
- * const sleep = (ms: number): Promise<void> =>
39
- * new Promise((resolve) => {
40
- * setTimeout(resolve, ms);
41
- * });
42
- *
43
- * input$.next(0);
44
- *
45
- * await sleep(200);
46
- *
47
- * input$.next(2);
48
- *
49
- * await sleep(100);
50
- *
51
- * input$.next(3);
52
- *
53
- * assert.deepStrictEqual(valueHistory, []);
54
- *
55
- * await sleep(300);
56
- *
57
- * assert.deepStrictEqual(valueHistory, [3]);
58
- *
59
- * await sleep(300);
60
- *
61
- * input$.next(9);
62
- *
63
- * await sleep(100);
64
- *
65
- * input$.next(10);
66
- *
67
- * await sleep(100);
68
- *
69
- * input$.next(11);
70
- *
71
- * await sleep(100);
72
- *
73
- * input$.next(12);
74
- *
75
- * await sleep(100);
76
- *
77
- * input$.next(13);
78
- *
79
- * await sleep(100);
80
- *
81
- * input$.next(14);
82
- *
83
- * assert.deepStrictEqual(valueHistory, [3]);
84
- *
85
- * await sleep(300);
86
- *
87
- * assert.deepStrictEqual(valueHistory, [3, 14]);
88
- * ```
89
- */
90
- const debounce = (milliSeconds) =>
91
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
92
- ((parentObservable) => new DebounceObservableClass(parentObservable, milliSeconds));
5
+ const debounce = (milliSeconds) => (
6
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
7
+ ((parentObservable) => new DebounceObservableClass(
8
+ parentObservable,
9
+ milliSeconds
10
+ ))
11
+ );
93
12
  class DebounceObservableClass extends AsyncChildObservableClass {
94
- #milliSeconds;
95
- #mut_timerId;
96
- constructor(parentObservable, milliSeconds) {
97
- super({
98
- parents: [parentObservable],
99
- initialValue: parentObservable.getSnapshot(),
100
- });
101
- this.#mut_timerId = undefined;
102
- this.#milliSeconds = milliSeconds;
13
+ #milliSeconds;
14
+ #mut_timerId;
15
+ constructor(parentObservable, milliSeconds) {
16
+ super({
17
+ parents: [parentObservable],
18
+ initialValue: parentObservable.getSnapshot()
19
+ });
20
+ this.#mut_timerId = void 0;
21
+ this.#milliSeconds = milliSeconds;
22
+ }
23
+ #resetTimer() {
24
+ if (this.#mut_timerId !== void 0) {
25
+ clearTimeout(this.#mut_timerId);
103
26
  }
104
- tryUpdate(updateToken) {
105
- const par = this.parents[0];
106
- const sn = par.getSnapshot();
107
- if (par.updateToken !== updateToken || Optional.isNone(sn)) {
108
- return; // skip update
109
- }
110
- this.#resetTimer();
111
- // set timer
112
- this.#mut_timerId = setTimeout(() => {
113
- if (Optional.isNone(sn))
114
- return;
115
- this.startUpdate(sn.value);
116
- }, this.#milliSeconds);
117
- }
118
- #resetTimer() {
119
- if (this.#mut_timerId !== undefined) {
120
- clearTimeout(this.#mut_timerId);
121
- }
122
- }
123
- complete() {
124
- this.#resetTimer();
125
- super.complete();
27
+ }
28
+ tryUpdate(updateToken) {
29
+ const par = this.parents[0];
30
+ const sn = par.getSnapshot();
31
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
32
+ return;
126
33
  }
34
+ this.#resetTimer();
35
+ this.#mut_timerId = setTimeout(() => {
36
+ if (Optional.isNone(sn)) return;
37
+ this.startUpdate(sn.value);
38
+ }, this.#milliSeconds);
39
+ }
40
+ complete() {
41
+ this.#resetTimer();
42
+ super.complete();
43
+ }
127
44
  }
128
45
 
129
46
  export { debounce };
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.mjs","sources":["../../../src/core/operators/debounce.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFG;AACI,MAAM,QAAQ,GAAG,CACtB,YAAoB;AAEpB;AACA,CAAC,CAAC,gBAAgB,KAChB,IAAI,uBAAuB,CACzB,gBAAgB,EAChB,YAAY,CACb;AAEL,MAAM,uBACJ,SAAQ,yBAA0C,CAAA;AAGzC,IAAA,aAAa;AACtB,IAAA,YAAY;IAEZ,WAAA,CAAY,gBAA+B,EAAE,YAAoB,EAAA;AAC/D,QAAA,KAAK,CAAC;YACJ,OAAO,EAAE,CAAC,gBAAgB,CAAC;AAC3B,YAAA,YAAY,EAAE,gBAAgB,CAAC,WAAW,EAAE;AAC7C,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,YAAY,GAAG,SAAS;AAE7B,QAAA,IAAI,CAAC,aAAa,GAAG,YAAY;IACnC;AAES,IAAA,SAAS,CAAC,WAAwB,EAAA;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAE3B,QAAA,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE;AAE5B,QAAA,IAAI,GAAG,CAAC,WAAW,KAAK,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AAC1D,YAAA,OAAO;QACT;QAEA,IAAI,CAAC,WAAW,EAAE;;AAGlB,QAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAK;AAClC,YAAA,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAE;AAEzB,YAAA,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC;AAC5B,QAAA,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC;IACxB;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE;AACnC,YAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;QACjC;IACF;IAES,QAAQ,GAAA;QACf,IAAI,CAAC,WAAW,EAAE;QAElB,KAAK,CAAC,QAAQ,EAAE;IAClB;AACD;;;;"}
1
+ {"version":3,"file":"debounce.mjs","sources":["../../../src/core/operators/debounce.mts"],"sourcesContent":["import { Optional } from 'ts-data-forge';\nimport { AsyncChildObservableClass } from '../class/index.mjs';\nimport {\n type DebounceOperatorObservable,\n type KeepInitialValueOperator,\n type Observable,\n type TimerId,\n type UpdateToken,\n} from '../types/index.mjs';\n\n/**\n * Delays emissions from the source observable until a specified time has passed without another emission.\n * Useful for handling user input events like typing or scrolling.\n *\n * @template A - The type of values from the source\n * @param milliSeconds - The debounce duration in milliseconds\n * @returns An operator that debounces the observable\n *\n * @example\n * ```ts\n * // Timeline (250ms debounce):\n * //\n * // Time(x50ms) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0\n * //\n * // input$ 0 2 3 9 10 11 12 13 14\n * // |- 250ms -> |- 250ms ->\n * // debounced$ 3 14 (emitted after 250ms silence)\n * //\n * // Explanation:\n * // - debounce emits the latest value AFTER a quiet period with no new emissions\n * // - Unlike audit (which uses a fixed window), debounce resets the timer on every emission\n * // - Useful for search-as-you-type and form validation\n *\n * const input$ = source<number>();\n *\n * const debounced$ = input$.pipe(debounce(250));\n *\n * const valueHistory: number[] = [];\n *\n * debounced$.subscribe((value) => {\n * valueHistory.push(value);\n * });\n *\n * const sleep = (ms: number): Promise<void> =>\n * new Promise((resolve) => {\n * setTimeout(resolve, ms);\n * });\n *\n * input$.next(0);\n *\n * await sleep(200);\n *\n * input$.next(2);\n *\n * await sleep(100);\n *\n * input$.next(3);\n *\n * assert.deepStrictEqual(valueHistory, []);\n *\n * await sleep(300);\n *\n * assert.deepStrictEqual(valueHistory, [3]);\n *\n * await sleep(300);\n *\n * input$.next(9);\n *\n * await sleep(100);\n *\n * input$.next(10);\n *\n * await sleep(100);\n *\n * input$.next(11);\n *\n * await sleep(100);\n *\n * input$.next(12);\n *\n * await sleep(100);\n *\n * input$.next(13);\n *\n * await sleep(100);\n *\n * input$.next(14);\n *\n * assert.deepStrictEqual(valueHistory, [3]);\n *\n * await sleep(300);\n *\n * assert.deepStrictEqual(valueHistory, [3, 14]);\n * ```\n */\nexport const debounce = <A,>(\n milliSeconds: number,\n): KeepInitialValueOperator<A, A> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n ((parentObservable) =>\n new DebounceObservableClass(\n parentObservable,\n milliSeconds,\n )) as KeepInitialValueOperator<A, A>;\n\nclass DebounceObservableClass<A>\n extends AsyncChildObservableClass<A, readonly [A]>\n implements DebounceOperatorObservable<A>\n{\n readonly #milliSeconds: number;\n #mut_timerId: TimerId | undefined;\n\n constructor(parentObservable: Observable<A>, milliSeconds: number) {\n super({\n parents: [parentObservable],\n initialValue: parentObservable.getSnapshot(),\n });\n\n this.#mut_timerId = undefined;\n\n this.#milliSeconds = milliSeconds;\n }\n\n #resetTimer(): void {\n if (this.#mut_timerId !== undefined) {\n clearTimeout(this.#mut_timerId);\n }\n }\n\n override tryUpdate(updateToken: UpdateToken): void {\n const par = this.parents[0];\n\n const sn = par.getSnapshot();\n\n if (par.updateToken !== updateToken || Optional.isNone(sn)) {\n return; // skip update\n }\n\n this.#resetTimer();\n\n // set timer\n this.#mut_timerId = setTimeout(() => {\n if (Optional.isNone(sn)) return;\n\n this.startUpdate(sn.value);\n }, this.#milliSeconds);\n }\n\n override complete(): void {\n this.#resetTimer();\n\n super.complete();\n }\n}\n"],"names":[],"mappings":";;;;AA+FO,MAAM,WAAW,CACtB,YAAA;AAAA;AAAA,GAGC,CAAC,qBACA,IAAI,uBAAA;AAAA,IACF,gBAAA;AAAA,IACA;AAAA,GACF;AAAA;AAEJ,MAAM,gCACI,yBAAA,CAEV;AAAA,EACW,aAAA;AAAA,EACT,YAAA;AAAA,EAEA,WAAA,CAAY,kBAAiC,YAAA,EAAsB;AACjE,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA,EAAS,CAAC,gBAAgB,CAAA;AAAA,MAC1B,YAAA,EAAc,iBAAiB,WAAA;AAAY,KAC5C,CAAA;AAED,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AAEpB,IAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAAA,EACvB;AAAA,EAEA,WAAA,GAAoB;AAClB,IAAA,IAAI,IAAA,CAAK,iBAAiB,MAAA,EAAW;AACnC,MAAA,YAAA,CAAa,KAAK,YAAY,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAES,UAAU,WAAA,EAAgC;AACjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA;AAE1B,IAAA,MAAM,EAAA,GAAK,IAAI,WAAA,EAAY;AAE3B,IAAA,IAAI,IAAI,WAAA,KAAgB,WAAA,IAAe,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,WAAA,EAAY;AAGjB,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,MAAM;AACnC,MAAA,IAAI,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG;AAEzB,MAAA,IAAA,CAAK,WAAA,CAAY,GAAG,KAAK,CAAA;AAAA,IAC3B,CAAA,EAAG,KAAK,aAAa,CAAA;AAAA,EACvB;AAAA,EAES,QAAA,GAAiB;AACxB,IAAA,IAAA,CAAK,WAAA,EAAY;AAEjB,IAAA,KAAA,CAAM,QAAA,EAAS;AAAA,EACjB;AACF;;;;"}
@@ -3,35 +3,32 @@ import { SyncChildObservableClass } from '../class/child-observable-class.mjs';
3
3
  import '../utils/id-maker.mjs';
4
4
 
5
5
  function filter(predicate) {
6
- return (parentObservable) => new FilterObservableClass(parentObservable, predicate);
6
+ return (parentObservable) => new FilterObservableClass(parentObservable, predicate);
7
7
  }
8
8
  class FilterObservableClass extends SyncChildObservableClass {
9
- #predicate;
10
- #mut_index;
11
- constructor(parentObservable, predicate) {
12
- super({
13
- parents: [parentObservable],
14
- initialValue: pipe(parentObservable.getSnapshot()).map((sn) => Optional.isNone(sn)
15
- ? Optional.none
16
- : predicate(sn.value, -1)
17
- ? sn
18
- : Optional.none).value,
19
- });
20
- this.#mut_index = -1;
21
- this.#predicate = predicate;
9
+ #predicate;
10
+ #mut_index;
11
+ constructor(parentObservable, predicate) {
12
+ super({
13
+ parents: [parentObservable],
14
+ initialValue: pipe(parentObservable.getSnapshot()).map(
15
+ (sn) => Optional.isNone(sn) ? Optional.none : predicate(sn.value, -1) ? sn : Optional.none
16
+ ).value
17
+ });
18
+ this.#mut_index = -1;
19
+ this.#predicate = predicate;
20
+ }
21
+ tryUpdate(updateToken) {
22
+ const par = this.parents[0];
23
+ const sn = par.getSnapshot();
24
+ if (par.updateToken !== updateToken || Optional.isNone(sn)) {
25
+ return;
22
26
  }
23
- tryUpdate(updateToken) {
24
- const par = this.parents[0];
25
- const sn = par.getSnapshot();
26
- if (par.updateToken !== updateToken || Optional.isNone(sn)) {
27
- return; // skip update
28
- }
29
- this.#mut_index =
30
- this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
31
- if (this.#predicate(sn.value, this.#mut_index)) {
32
- this.setNext(sn.value, updateToken);
33
- }
27
+ this.#mut_index = this.#mut_index === -1 ? asSafeUint(0) : SafeUint.add(1, this.#mut_index);
28
+ if (this.#predicate(sn.value, this.#mut_index)) {
29
+ this.setNext(sn.value, updateToken);
34
30
  }
31
+ }
35
32
  }
36
33
 
37
34
  export { filter };