synstate 3.0.5 → 3.1.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 (174) hide show
  1. package/README.md +1 -1
  2. package/dist/core/base/create-observable-base.d.mts +53 -8
  3. package/dist/core/base/create-observable-base.d.mts.map +1 -1
  4. package/dist/core/base/create-observable-base.mjs +48 -17
  5. package/dist/core/base/create-observable-base.mjs.map +1 -1
  6. package/dist/core/base/create-root-observable.d.mts +1 -1
  7. package/dist/core/base/create-root-observable.d.mts.map +1 -1
  8. package/dist/core/combine/combine.d.mts +2 -2
  9. package/dist/core/combine/combine.d.mts.map +1 -1
  10. package/dist/core/combine/merge.d.mts +2 -2
  11. package/dist/core/combine/merge.d.mts.map +1 -1
  12. package/dist/core/combine/zip.d.mts +2 -2
  13. package/dist/core/combine/zip.d.mts.map +1 -1
  14. package/dist/core/create/counter.d.mts +1 -1
  15. package/dist/core/create/counter.d.mts.map +1 -1
  16. package/dist/core/create/from-abortable-promise.d.mts +1 -1
  17. package/dist/core/create/from-abortable-promise.d.mts.map +1 -1
  18. package/dist/core/create/from-promise.d.mts +1 -1
  19. package/dist/core/create/from-promise.d.mts.map +1 -1
  20. package/dist/core/create/from-subscribable.d.mts +1 -1
  21. package/dist/core/create/from-subscribable.d.mts.map +1 -1
  22. package/dist/core/create/just.d.mts +1 -1
  23. package/dist/core/create/just.d.mts.map +1 -1
  24. package/dist/core/create/source.d.mts +1 -1
  25. package/dist/core/create/source.d.mts.map +1 -1
  26. package/dist/core/create/timer.d.mts +1 -1
  27. package/dist/core/create/timer.d.mts.map +1 -1
  28. package/dist/core/operators/audit.d.mts +1 -1
  29. package/dist/core/operators/audit.d.mts.map +1 -1
  30. package/dist/core/operators/debounce.d.mts +1 -1
  31. package/dist/core/operators/debounce.d.mts.map +1 -1
  32. package/dist/core/operators/filter.d.mts +1 -1
  33. package/dist/core/operators/filter.d.mts.map +1 -1
  34. package/dist/core/operators/map.d.mts +1 -1
  35. package/dist/core/operators/map.d.mts.map +1 -1
  36. package/dist/core/operators/merge-map.d.mts +1 -1
  37. package/dist/core/operators/merge-map.d.mts.map +1 -1
  38. package/dist/core/operators/pairwise.d.mts +2 -2
  39. package/dist/core/operators/pairwise.d.mts.map +1 -1
  40. package/dist/core/operators/scan.d.mts +1 -1
  41. package/dist/core/operators/scan.d.mts.map +1 -1
  42. package/dist/core/operators/skip-if-no-change.d.mts +1 -1
  43. package/dist/core/operators/skip-if-no-change.d.mts.map +1 -1
  44. package/dist/core/operators/skip-until.d.mts +1 -1
  45. package/dist/core/operators/skip-until.d.mts.map +1 -1
  46. package/dist/core/operators/skip-while.d.mts +1 -1
  47. package/dist/core/operators/skip-while.d.mts.map +1 -1
  48. package/dist/core/operators/switch-map.d.mts +1 -1
  49. package/dist/core/operators/switch-map.d.mts.map +1 -1
  50. package/dist/core/operators/take-until.d.mts +1 -1
  51. package/dist/core/operators/take-until.d.mts.map +1 -1
  52. package/dist/core/operators/take-while.d.mts +1 -1
  53. package/dist/core/operators/take-while.d.mts.map +1 -1
  54. package/dist/core/operators/throttle.d.mts +1 -1
  55. package/dist/core/operators/throttle.d.mts.map +1 -1
  56. package/dist/core/operators/with-buffered-from.d.mts +1 -1
  57. package/dist/core/operators/with-buffered-from.d.mts.map +1 -1
  58. package/dist/core/operators/with-current-value-from.d.mts +1 -1
  59. package/dist/core/operators/with-current-value-from.d.mts.map +1 -1
  60. package/dist/core/operators/with-initial-value.d.mts +1 -1
  61. package/dist/core/operators/with-initial-value.d.mts.map +1 -1
  62. package/dist/core/predefined/operators/attach-index.d.mts +2 -2
  63. package/dist/core/predefined/operators/attach-index.d.mts.map +1 -1
  64. package/dist/core/predefined/operators/map-optional.d.mts +1 -1
  65. package/dist/core/predefined/operators/map-optional.d.mts.map +1 -1
  66. package/dist/core/predefined/operators/map-result-err.d.mts +1 -1
  67. package/dist/core/predefined/operators/map-result-err.d.mts.map +1 -1
  68. package/dist/core/predefined/operators/map-result-ok.d.mts +1 -1
  69. package/dist/core/predefined/operators/map-result-ok.d.mts.map +1 -1
  70. package/dist/core/predefined/operators/map-to.d.mts +1 -1
  71. package/dist/core/predefined/operators/map-to.d.mts.map +1 -1
  72. package/dist/core/predefined/operators/pluck.d.mts +1 -1
  73. package/dist/core/predefined/operators/pluck.d.mts.map +1 -1
  74. package/dist/core/predefined/operators/skip.d.mts +2 -2
  75. package/dist/core/predefined/operators/skip.d.mts.map +1 -1
  76. package/dist/core/predefined/operators/take.d.mts +2 -2
  77. package/dist/core/predefined/operators/take.d.mts.map +1 -1
  78. package/dist/core/predefined/operators/unwrap-optional.d.mts +1 -1
  79. package/dist/core/predefined/operators/unwrap-optional.d.mts.map +1 -1
  80. package/dist/core/predefined/operators/unwrap-result-err.d.mts +1 -1
  81. package/dist/core/predefined/operators/unwrap-result-err.d.mts.map +1 -1
  82. package/dist/core/predefined/operators/unwrap-result-ok.d.mts +1 -1
  83. package/dist/core/predefined/operators/unwrap-result-ok.d.mts.map +1 -1
  84. package/dist/core/types/id.d.mts +1 -1
  85. package/dist/core/types/id.d.mts.map +1 -1
  86. package/dist/core/types/observable-family.d.mts +3 -3
  87. package/dist/core/types/observable-family.d.mts.map +1 -1
  88. package/dist/core/types/observable-kind.d.mts +1 -1
  89. package/dist/core/types/observable-kind.d.mts.map +1 -1
  90. package/dist/core/types/observable.d.mts +4 -4
  91. package/dist/core/types/observable.d.mts.map +1 -1
  92. package/dist/core/types/types.d.mts +1 -1
  93. package/dist/core/types/types.d.mts.map +1 -1
  94. package/dist/core/utils/id-maker.d.mts +1 -1
  95. package/dist/core/utils/id-maker.d.mts.map +1 -1
  96. package/dist/core/utils/max-depth.d.mts +1 -1
  97. package/dist/core/utils/max-depth.d.mts.map +1 -1
  98. package/dist/core/utils/observable-utils.d.mts +1 -1
  99. package/dist/core/utils/observable-utils.d.mts.map +1 -1
  100. package/dist/core/utils/utils.d.mts +1 -1
  101. package/dist/core/utils/utils.d.mts.map +1 -1
  102. package/dist/utils/collect-to-array.d.mts +1 -1
  103. package/dist/utils/collect-to-array.d.mts.map +1 -1
  104. package/dist/utils/create-boolean-state.d.mts +17 -14
  105. package/dist/utils/create-boolean-state.d.mts.map +1 -1
  106. package/dist/utils/create-boolean-state.mjs +4 -2
  107. package/dist/utils/create-boolean-state.mjs.map +1 -1
  108. package/dist/utils/create-reducer.d.mts +49 -2
  109. package/dist/utils/create-reducer.d.mts.map +1 -1
  110. package/dist/utils/create-reducer.mjs +31 -2
  111. package/dist/utils/create-reducer.mjs.map +1 -1
  112. package/dist/utils/create-state.d.mts +37 -2
  113. package/dist/utils/create-state.d.mts.map +1 -1
  114. package/dist/utils/create-state.mjs +36 -2
  115. package/dist/utils/create-state.mjs.map +1 -1
  116. package/package.json +11 -11
  117. package/src/core/base/create-child-observable.mts +1 -1
  118. package/src/core/base/create-observable-base.mts +131 -44
  119. package/src/core/base/create-root-observable.mts +1 -1
  120. package/src/core/base/observable-base.test.mts +7 -7
  121. package/src/core/combine/combine.mts +10 -10
  122. package/src/core/combine/merge.mts +8 -8
  123. package/src/core/combine/zip.mts +11 -11
  124. package/src/core/create/counter.mts +1 -1
  125. package/src/core/create/from-abortable-promise.mts +1 -1
  126. package/src/core/create/from-promise.mts +1 -1
  127. package/src/core/create/from-subscribable.mts +3 -3
  128. package/src/core/create/just.mts +1 -1
  129. package/src/core/create/source.mts +3 -3
  130. package/src/core/create/timer.mts +1 -1
  131. package/src/core/operators/audit.mts +5 -5
  132. package/src/core/operators/debounce.mts +5 -5
  133. package/src/core/operators/filter.mts +5 -5
  134. package/src/core/operators/map.mts +5 -5
  135. package/src/core/operators/merge-map.mts +5 -5
  136. package/src/core/operators/pairwise.mts +5 -5
  137. package/src/core/operators/scan.mts +4 -4
  138. package/src/core/operators/skip-if-no-change.mts +4 -4
  139. package/src/core/operators/skip-until.mts +4 -4
  140. package/src/core/operators/skip-while.mts +4 -4
  141. package/src/core/operators/switch-map.mts +5 -5
  142. package/src/core/operators/take-until.mts +4 -4
  143. package/src/core/operators/take-while.mts +5 -5
  144. package/src/core/operators/throttle.mts +5 -5
  145. package/src/core/operators/with-buffered-from.mts +4 -4
  146. package/src/core/operators/with-current-value-from.mts +4 -4
  147. package/src/core/operators/with-initial-value.mts +5 -5
  148. package/src/core/predefined/operators/attach-index.mts +2 -2
  149. package/src/core/predefined/operators/map-optional.mts +1 -1
  150. package/src/core/predefined/operators/map-result-err.mts +1 -1
  151. package/src/core/predefined/operators/map-result-ok.mts +1 -1
  152. package/src/core/predefined/operators/map-to.mts +1 -1
  153. package/src/core/predefined/operators/pluck.mts +1 -1
  154. package/src/core/predefined/operators/skip.mts +2 -2
  155. package/src/core/predefined/operators/take.mts +2 -2
  156. package/src/core/predefined/operators/unwrap-optional.mts +2 -2
  157. package/src/core/predefined/operators/unwrap-result-err.mts +2 -2
  158. package/src/core/predefined/operators/unwrap-result-ok.mts +2 -2
  159. package/src/core/types/id.mts +1 -1
  160. package/src/core/types/observable-family.mts +15 -15
  161. package/src/core/types/observable-kind.mts +1 -1
  162. package/src/core/types/observable.mts +4 -4
  163. package/src/core/types/types.mts +1 -1
  164. package/src/core/utils/id-maker.mts +4 -4
  165. package/src/core/utils/max-depth.mts +1 -1
  166. package/src/core/utils/observable-utils.mts +1 -1
  167. package/src/core/utils/utils.mts +1 -1
  168. package/src/utils/collect-to-array.mts +1 -1
  169. package/src/utils/create-boolean-state.mts +18 -14
  170. package/src/utils/create-boolean-state.test.mts +23 -0
  171. package/src/utils/create-reducer.mts +59 -2
  172. package/src/utils/create-reducer.test.mts +87 -0
  173. package/src/utils/create-state.mts +38 -2
  174. package/src/utils/create-state.test.mts +72 -0
@@ -1 +1 @@
1
- {"version":3,"file":"create-reducer.d.mts","sourceRoot":"","sources":["../../src/utils/create-reducer.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAU,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,WACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,gBACR,CAAC,KACd,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAC1B,KAAK,EAAE,QAAQ,CAAC;IACd,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;CACjB,CAAC,CAeH,CAAC"}
1
+ {"version":3,"file":"create-reducer.d.mts","sourceRoot":"","sources":["../../src/utils/create-reducer.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAU,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,WACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,gBACR,CAAC,YACL,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KACjC,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAC1B,KAAK,EAAE,QAAQ,CAAC;IACd,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;CACjB,CAAC,CAuBH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,QAAQ,CAAC;IACrC;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;CAC3C,CAAC,CAAC"}
@@ -42,10 +42,39 @@ import { source } from '../core/index.mjs';
42
42
 
43
43
 
44
44
 
45
- export const createReducer = (reducer, initialState) => {
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+ export const createReducer = (reducer, initialState, options) => {
46
70
  const state = source(initialState);
71
+ const equals = options?.equals;
47
72
  const dispatch = (action) => {
48
- const nextState = reducer(state.getSnapshot().value, action);
73
+ const currentState = state.getSnapshot().value;
74
+ const nextState = reducer(currentState, action);
75
+ if (equals?.(currentState, nextState) === true) {
76
+ return currentState;
77
+ }
49
78
  state.next(nextState);
50
79
  return nextState;
51
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"create-reducer.mjs","sourceRoot":"","sources":["../../src/utils/create-reducer.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAA8B,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAsB,EACtB,YAAe,EAQf,EAAE;IACF,MAAM,KAAK,GAAG,MAAM,CAAI,YAAY,CAAC,CAAC;IAEtC,MAAM,QAAQ,GAAG,CAAC,MAAS,EAAK,EAAE;QAChC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE7D,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC;IAEvD,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,CAAU,CAAC;AACnE,CAAC,CAAC"}
1
+ {"version":3,"file":"create-reducer.mjs","sourceRoot":"","sources":["../../src/utils/create-reducer.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAA8B,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAsB,EACtB,YAAe,EACf,OAAkC,EAQlC,EAAE;IACF,MAAM,KAAK,GAAG,MAAM,CAAI,YAAY,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAE/B,MAAM,QAAQ,GAAG,CAAC,MAAS,EAAK,EAAE;QAChC,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC;QAE/C,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAEhD,IAAI,MAAM,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/C,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC;IAEvD,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,CAAU,CAAC;AACnE,CAAC,CAAC"}
@@ -1,10 +1,13 @@
1
- import { type InitializedObservable } from '../core/index.mjs';
1
+ import type { InitializedObservable } from '../core/index.mjs';
2
+ import { type StateOptions } from './create-reducer.mjs';
2
3
  /**
3
4
  * Creates a reactive state container with getter and setter methods.
4
5
  * Provides a simple state management solution with observable state.
5
6
  *
6
7
  * @template S - The type of the state
7
8
  * @param initialState - The initial value of the state
9
+ * @param options - {@link StateOptions}: `equals`, to pass on only the
10
+ * updates that change the state
8
11
  * @returns A 3-element tuple: `[state, setState, { updateState, resetState, getSnapshot, initialState }]`
9
12
  *
10
13
  * @example
@@ -31,8 +34,40 @@ import { type InitializedObservable } from '../core/index.mjs';
31
34
  *
32
35
  * assert.deepStrictEqual(stateHistory, [0, 10, 11, 0]);
33
36
  * ```
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const [filters, setFilters] = createState(
41
+ * { label: 'bug', page: 1 },
42
+ * { equals: fastDeepEqual },
43
+ * );
44
+ *
45
+ * const before = filters.getSnapshot().value;
46
+ *
47
+ * // Derived state is recomputed only when the state really changes.
48
+ * const query = filters.pipe(
49
+ * map(({ label, page }) => `label:${label} page:${page}`),
50
+ * );
51
+ *
52
+ * const queryHistory: string[] = [];
53
+ *
54
+ * query.subscribe((value: string) => {
55
+ * queryHistory.push(value);
56
+ * });
57
+ *
58
+ * setFilters({ label: 'bug', page: 1 }); // equal: nothing is passed on
59
+ *
60
+ * assert.strictEqual(filters.getSnapshot().value, before);
61
+ *
62
+ * setFilters({ label: 'bug', page: 2 });
63
+ *
64
+ * assert.deepStrictEqual(queryHistory, [
65
+ * 'label:bug page:1',
66
+ * 'label:bug page:2',
67
+ * ]);
68
+ * ```
34
69
  */
35
- export declare const createState: <S>(initialState: S) => readonly [state: InitializedObservable<S>, setState: (v: S) => S, utils: Readonly<{
70
+ export declare const createState: <S>(initialState: S, options?: StateOptions<NoInfer<S>>) => readonly [state: InitializedObservable<S>, setState: (v: S) => S, utils: Readonly<{
36
71
  updateState: (updateFn: (prev: S) => S) => S;
37
72
  resetState: () => S;
38
73
  getSnapshot: () => S;
@@ -1 +1 @@
1
- {"version":3,"file":"create-state.d.mts","sourceRoot":"","sources":["../../src/utils/create-state.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAwB/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,gBACb,CAAC,KACd,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,KAAK,EAAE,QAAQ,CAAC;IACd,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;CACjB,CAAC,CAyBH,CAAC"}
1
+ {"version":3,"file":"create-state.d.mts","sourceRoot":"","sources":["../../src/utils/create-state.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAuBxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,gBACb,CAAC,YACL,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KACjC,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,KAAK,EAAE,QAAQ,CAAC;IACd,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;CACjB,CAAC,CA0BH,CAAC"}
@@ -40,8 +40,42 @@ const reducer = (state, action) => {
40
40
 
41
41
 
42
42
 
43
- export const createState = (initialState) => {
44
- const [state, dispatch, { getSnapshot }] = createReducer(reducer, initialState);
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+ export const createState = (initialState, options) => {
78
+ const [state, dispatch, { getSnapshot }] = createReducer(reducer, initialState, options);
45
79
  const updateState = (updateFn) => dispatch({ type: 'update', updateFn });
46
80
  const setState = (nextState) => dispatch({ type: 'set', nextState });
47
81
  const resetState = () => dispatch({ type: 'set', nextState: initialState });
@@ -1 +1 @@
1
- {"version":3,"file":"create-state.mjs","sourceRoot":"","sources":["../../src/utils/create-state.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAarD,MAAM,OAAO,GAAG,CAAK,KAAQ,EAAE,MAAiB,EAAK,EAAE;IACrD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,SAAS,CAAC;QAE1B,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,YAAe,EAUf,EAAE;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,GAAG,aAAa,CACtD,OAAO,EACP,YAAY,CACb,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,QAAwB,EAAK,EAAE,CAClD,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,CAAC,SAAY,EAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE3E,MAAM,UAAU,GAAG,GAAM,EAAE,CACzB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,KAAK;QACL,QAAQ;QACR;YACE,WAAW;YACX,UAAU;YACV,WAAW;YACX,YAAY;SACb;KACO,CAAC;AACb,CAAC,CAAC"}
1
+ {"version":3,"file":"create-state.mjs","sourceRoot":"","sources":["../../src/utils/create-state.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;AAaxE,MAAM,OAAO,GAAG,CAAK,KAAQ,EAAE,MAAiB,EAAK,EAAE;IACrD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,SAAS,CAAC;QAE1B,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,YAAe,EACf,OAAkC,EAUlC,EAAE;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,GAAG,aAAa,CACtD,OAAO,EACP,YAAY,EACZ,OAAO,CACR,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,QAAwB,EAAK,EAAE,CAClD,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,CAAC,SAAY,EAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE3E,MAAM,UAAU,GAAG,GAAM,EAAE,CACzB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,KAAK;QACL,QAAQ;QACR;YACE,WAAW;YACX,UAAU;YACV,WAAW;YACX,YAAY;SACb;KACO,CAAC;AACb,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synstate",
3
- "version": "3.0.5",
3
+ "version": "3.1.0",
4
4
  "description": "Type-safe State Management Library for TypeScript/JavaScript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,24 +35,24 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@reduxjs/toolkit": "2.12.0",
38
- "@sumi-lang/cli": "0.0.4",
38
+ "@sumi-lang/cli": "0.0.5",
39
39
  "@types/react": "19.3.0",
40
- "@vitest/browser-playwright": "5.0.1",
40
+ "@vitest/browser-playwright": "5.0.2",
41
41
  "argparse": "3.0.2",
42
- "eslint-config-typed": "5.15.0",
43
- "eslint-plugin-ts-data-forge": "0.8.1",
44
- "eslint-plugin-ts-fortress": "1.2.3",
45
- "eslint-plugin-ts-type-forge": "0.8.4",
42
+ "eslint-config-typed": "5.17.0",
43
+ "eslint-plugin-ts-data-forge": "0.8.3",
44
+ "eslint-plugin-ts-fortress": "1.3.0",
45
+ "eslint-plugin-ts-type-forge": "0.8.5",
46
46
  "jotai": "3.0.0",
47
- "mobx": "7.0.3",
47
+ "mobx": "7.0.5",
48
48
  "playwright": "1.63.0",
49
- "prettier": "3.9.8",
49
+ "prettier": "3.9.9",
50
50
  "prettier-plugin-organize-imports": "4.3.0",
51
51
  "prettier-plugin-packagejson": "3.0.2",
52
52
  "react": "19.3.0",
53
53
  "rxjs": "7.8.2",
54
- "synstate-react-hooks": "3.0.5",
55
- "synstate-react-hooks-compat": "3.0.5",
54
+ "synstate-react-hooks": "3.1.0",
55
+ "synstate-react-hooks-compat": "3.1.0",
56
56
  "ts-repo-utils": "10.7.1",
57
57
  "valtio": "2.3.2",
58
58
  "zustand": "5.0.15"
@@ -1,6 +1,6 @@
1
1
  import { Arr, type Optional, type Some } from 'ts-data-forge';
2
2
  import { panic } from 'ts-std-forge';
3
- import { type MutableSet } from 'ts-type-forge';
3
+ import type { MutableSet } from 'ts-type-forge';
4
4
  import {
5
5
  isChildObservable,
6
6
  isManagerObservable,
@@ -1,23 +1,19 @@
1
1
  import { Arr, Optional } from 'ts-data-forge';
2
2
  import { unreachable } from 'ts-std-forge';
3
- import {
4
- type MutableMap,
5
- type MutableSet,
6
- type ReadonlyRecord,
7
- } from 'ts-type-forge';
8
- import {
9
- type ChildObservable,
10
- type InitializedObservable,
11
- type Observable,
12
- type ObservableBase,
13
- type ObservableId,
14
- type ObservableKind,
15
- type Operator,
16
- type Subscriber,
17
- type SubscriberId,
18
- type Subscription,
19
- type UpdateToken,
20
- type WithInitialValueOperator,
3
+ import type { MutableMap, MutableSet, ReadonlyRecord } from 'ts-type-forge';
4
+ import type {
5
+ ChildObservable,
6
+ InitializedObservable,
7
+ Observable,
8
+ ObservableBase,
9
+ ObservableId,
10
+ ObservableKind,
11
+ Operator,
12
+ Subscriber,
13
+ SubscriberId,
14
+ Subscription,
15
+ UpdateToken,
16
+ WithInitialValueOperator,
21
17
  } from '../types/index.mjs';
22
18
  import {
23
19
  binarySearch,
@@ -42,6 +38,38 @@ import {
42
38
  export type ObservableBaseHandle<A> = Readonly<{
43
39
  id: ObservableId;
44
40
 
41
+ /**
42
+ * Registers the public object {@link assembleObservable} built from this
43
+ * handle, so that its four state flags (`isCompleted`, `updateToken`,
44
+ * `hasSubscriber`, `hasChild`) can be mirrored onto it as plain data
45
+ * properties.
46
+ *
47
+ * They used to be getters delegating to this handle's closures, and that
48
+ * costs more than it looks. Reading one was an accessor call plus a closure
49
+ * call where a field read would do — `updateToken` is read once per child
50
+ * per update, so the propagation path paid it on every step — and an object
51
+ * literal carrying accessors is far more expensive to create than one
52
+ * carrying data, which is most of what building a graph costs. Measured on
53
+ * one machine with `pnpm run benchmark`: the derived chain's 100,000 updates
54
+ * 16.7 ms -> 13.6 ms, and the cascaded diamond at N=20, whose measurement is
55
+ * dominated by graph construction, 587 ms -> 362 ms.
56
+ *
57
+ * Every write below therefore has to keep the mirror in step; that is the
58
+ * price of not reading through a closure on the hot path. It is paid in
59
+ * clarity too, and on purpose: `hasSubscriber` and `hasChild` are derived
60
+ * from `mut_subscribers` and `mut_children`, which a getter stated once and
61
+ * declaratively, whereas the mirror restates it at every write.
62
+ *
63
+ * Nor can the rarely read flags alone go back to getters while `updateToken`
64
+ * stays data. A single accessor in the literal is enough to lose nearly all
65
+ * of the gain: measured on Node 26 with the `...extra` spread followed by
66
+ * these properties, one getter among data properties made the literal about
67
+ * 10x slower to create than all data (four getters: about 15x) and gave
68
+ * every instance its own hidden class (`%HaveSameMap` false). Keep all four
69
+ * as data, or measure again before changing that.
70
+ */
71
+ attach: (writers: ObservableStateWriters) => void;
72
+
45
73
  addChild: <B>(child: ChildObservable<B>) => void;
46
74
 
47
75
  getSnapshot: () => Optional<A>;
@@ -52,8 +80,6 @@ export type ObservableBaseHandle<A> = Readonly<{
52
80
 
53
81
  hasSubscriber: () => boolean;
54
82
 
55
- hasChild: () => boolean;
56
-
57
83
  hasActiveChild: () => boolean;
58
84
 
59
85
  subscribe: (onNext: (v: A) => void, onComplete?: () => void) => Subscription;
@@ -70,6 +96,20 @@ export type ObservableBaseHandle<A> = Readonly<{
70
96
  completeBase: () => void;
71
97
  }>;
72
98
 
99
+ /**
100
+ * How the handle writes the four state flags onto the public object. The
101
+ * writers are closures over that object rather than the object itself, because
102
+ * a parameter this side could mutate has to be a mutable type, which
103
+ * `@typescript-eslint/prefer-readonly-parameter-types` rejects — and the object
104
+ * is `Readonly` to everyone else.
105
+ */
106
+ type ObservableStateWriters = Readonly<{
107
+ setIsCompleted: (value: boolean) => void;
108
+ setUpdateToken: (value: UpdateToken) => void;
109
+ setHasSubscriber: (value: boolean) => void;
110
+ setHasChild: (value: boolean) => void;
111
+ }>;
112
+
73
113
  export const createObservableBaseHandle = <A,>(
74
114
  initialValue: Optional<A>,
75
115
  ): ObservableBaseHandle<A> => {
@@ -85,17 +125,41 @@ export const createObservableBaseHandle = <A,>(
85
125
 
86
126
  let mut_updateToken: UpdateToken = issueUpdateToken();
87
127
 
128
+ /**
129
+ * Set once {@link assembleObservable} has built the public object. It does
130
+ * not exist while a leaf factory's `init` callback runs — that callback may
131
+ * already subscribe or complete — so every write below is optional, and
132
+ * `attach` copies the state as it stands rather than assuming defaults.
133
+ */
134
+ let mut_writers: ObservableStateWriters | undefined;
135
+
136
+ const attach = (writers: ObservableStateWriters): void => {
137
+ mut_writers = writers;
138
+
139
+ writers.setIsCompleted(mut_isCompleted);
140
+
141
+ writers.setUpdateToken(mut_updateToken);
142
+
143
+ writers.setHasSubscriber(mut_subscribers.size > 0);
144
+
145
+ writers.setHasChild(Arr.isNonEmpty(mut_children));
146
+ };
147
+
88
148
  const addSubscriber = (s: Subscriber<A>): SubscriberId => {
89
149
  // return the id of added subscriber
90
150
  const subscriberId = issueSubscriberId();
91
151
 
92
152
  mut_subscribers.set(subscriberId, s);
93
153
 
154
+ mut_writers?.setHasSubscriber(true);
155
+
94
156
  return subscriberId;
95
157
  };
96
158
 
97
159
  const removeSubscriber = (subscriberId: SubscriberId): void => {
98
160
  mut_subscribers.delete(subscriberId);
161
+
162
+ mut_writers?.setHasSubscriber(mut_subscribers.size > 0);
99
163
  };
100
164
 
101
165
  const addChild = <B,>(child: ChildObservable<B>): void => {
@@ -104,6 +168,8 @@ export const createObservableBaseHandle = <A,>(
104
168
 
105
169
  child as ChildObservable<unknown>,
106
170
  );
171
+
172
+ mut_writers?.setHasChild(true);
107
173
  };
108
174
 
109
175
  const getSnapshot = (): Optional<A> => mut_currentValue;
@@ -114,14 +180,14 @@ export const createObservableBaseHandle = <A,>(
114
180
 
115
181
  const hasSubscriber = (): boolean => mut_subscribers.size > 0;
116
182
 
117
- const hasChild = (): boolean => Arr.isNonEmpty(mut_children);
118
-
119
183
  const hasActiveChild = (): boolean =>
120
184
  mut_children.some((c) => !c.isCompleted);
121
185
 
122
186
  const setNext = (nextValue: A, nextUpdateToken: UpdateToken): void => {
123
187
  mut_updateToken = nextUpdateToken;
124
188
 
189
+ mut_writers?.setUpdateToken(nextUpdateToken);
190
+
125
191
  mut_currentValue = Optional.some(nextValue);
126
192
 
127
193
  for (const s of mut_subscribers.values()) {
@@ -137,6 +203,8 @@ export const createObservableBaseHandle = <A,>(
137
203
  // change state
138
204
  mut_isCompleted = true;
139
205
 
206
+ mut_writers?.setIsCompleted(true);
207
+
140
208
  // run subscribers for the current value
141
209
  for (const s of mut_subscribers.values()) {
142
210
  s.onComplete();
@@ -145,6 +213,8 @@ export const createObservableBaseHandle = <A,>(
145
213
  // remove all subscribers
146
214
  mut_subscribers.clear();
147
215
 
216
+ mut_writers?.setHasSubscriber(false);
217
+
148
218
  // propagate to children
149
219
  for (const o of mut_children) {
150
220
  o.tryComplete();
@@ -183,12 +253,12 @@ export const createObservableBaseHandle = <A,>(
183
253
 
184
254
  return {
185
255
  id,
256
+ attach,
186
257
  addChild,
187
258
  getSnapshot,
188
259
  isCompleted,
189
260
  updateToken,
190
261
  hasSubscriber,
191
- hasChild,
192
262
  hasActiveChild,
193
263
  subscribe,
194
264
  setNext,
@@ -282,8 +352,9 @@ type AssembleObservableArgs<
282
352
  /**
283
353
  * Kind-specific public members (`parents`, `addDescendant`) and leaf
284
354
  * extensions (`next`, `start`). They are merged here, in the one place the
285
- * final object literal is created, because the public getters below must not
286
- * be copied by a spread (spreading would freeze their current values).
355
+ * final object literal is created, because the handle keeps the state flags
356
+ * up to date on that object alone: a copy made by spreading it afterwards
357
+ * would freeze their current values.
287
358
  */
288
359
  extra: Extra;
289
360
  }>;
@@ -291,9 +362,10 @@ type AssembleObservableArgs<
291
362
  /**
292
363
  * Builds the public observable object from a base handle. This replaces the
293
364
  * implicit assembly a `class` performs: state stays in the handle's closures,
294
- * `isCompleted` / `updateToken` / `hasSubscriber` / `hasChild` become getters
295
- * delegating to the handle, and the kind-specific behavior (`tryUpdate`,
296
- * `tryComplete`, `complete`) is passed in already composed.
365
+ * `isCompleted` / `updateToken` / `hasSubscriber` / `hasChild` become data
366
+ * properties the handle keeps in step through `attach`, and the kind-specific
367
+ * behavior (`tryUpdate`, `tryComplete`, `complete`) is passed in already
368
+ * composed.
297
369
  */
298
370
  export const assembleObservable = <
299
371
  A,
@@ -323,11 +395,16 @@ export const assembleObservable = <
323
395
  return operator(
324
396
  // @sumi-expect-error banned-syntax/no-unsafe-type-assertion
325
397
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
326
- observable as unknown as InitializedObservable<A>,
398
+ mut_observable as unknown as InitializedObservable<A>,
327
399
  );
328
400
  }
329
401
 
330
- const observable = {
402
+ // The four state flags are plain data properties kept in step by the handle,
403
+ // not getters delegating to it — see `ObservableBaseHandle.attach` for the
404
+ // measurements that decided this. `updateToken` in particular is read once
405
+ // per child per update, and `tryUpdate` reading a field rather than calling
406
+ // through an accessor is most of what the change buys.
407
+ const mut_observable = {
331
408
  ...extra,
332
409
 
333
410
  id: handle.id,
@@ -340,21 +417,13 @@ export const assembleObservable = <
340
417
 
341
418
  getSnapshot: handle.getSnapshot,
342
419
 
343
- get isCompleted(): boolean {
344
- return handle.isCompleted();
345
- },
420
+ isCompleted: false,
346
421
 
347
- get updateToken(): UpdateToken {
348
- return handle.updateToken();
349
- },
422
+ updateToken: handle.updateToken(),
350
423
 
351
- get hasSubscriber(): boolean {
352
- return handle.hasSubscriber();
353
- },
424
+ hasSubscriber: false,
354
425
 
355
- get hasChild(): boolean {
356
- return handle.hasChild();
357
- },
426
+ hasChild: false,
358
427
 
359
428
  hasActiveChild: handle.hasActiveChild,
360
429
 
@@ -367,7 +436,25 @@ export const assembleObservable = <
367
436
  subscribe: handle.subscribe,
368
437
 
369
438
  pipe,
370
- } as const;
439
+ };
440
+
441
+ handle.attach({
442
+ setIsCompleted: (value) => {
443
+ mut_observable.isCompleted = value;
444
+ },
445
+
446
+ setUpdateToken: (value) => {
447
+ mut_observable.updateToken = value;
448
+ },
449
+
450
+ setHasSubscriber: (value) => {
451
+ mut_observable.hasSubscriber = value;
452
+ },
453
+
454
+ setHasChild: (value) => {
455
+ mut_observable.hasChild = value;
456
+ },
457
+ });
371
458
 
372
- return observable;
459
+ return mut_observable;
373
460
  };
@@ -1,5 +1,5 @@
1
1
  import { Optional } from 'ts-data-forge';
2
- import { type ReadonlyRecord } from 'ts-type-forge';
2
+ import type { ReadonlyRecord } from 'ts-type-forge';
3
3
  import { isRootObservable, type RootObservable } from '../types/index.mjs';
4
4
  import {
5
5
  assembleObservable,
@@ -1,11 +1,11 @@
1
1
  import { expectType, Optional } from 'ts-data-forge';
2
- import {
3
- type AsyncChildObservable,
4
- type ChildObservable,
5
- type Observable,
6
- type ObservableBase,
7
- type RootObservable,
8
- type SyncChildObservable,
2
+ import type {
3
+ AsyncChildObservable,
4
+ ChildObservable,
5
+ Observable,
6
+ ObservableBase,
7
+ RootObservable,
8
+ SyncChildObservable,
9
9
  } from '../types/index.mjs';
10
10
  import {
11
11
  createAsyncChildObservable,
@@ -1,17 +1,17 @@
1
1
  import { Arr, expectType, Optional } from 'ts-data-forge';
2
- import { type NonEmptyTuple, type Tuple } from 'ts-type-forge';
2
+ import type { NonEmptyTuple, Tuple } from 'ts-type-forge';
3
3
  import { createSyncChildObservable } from '../base/index.mjs';
4
4
  import { source } from '../create/index.mjs';
5
5
  import { withInitialValue } from '../operators/index.mjs';
6
- import {
7
- type CombineObservable,
8
- type CombineObservableRefined,
9
- type InitializedObservable,
10
- type InitializedSyncChildObservable,
11
- type NonEmptyUnknownList,
12
- type Observable,
13
- type SyncChildObservable,
14
- type Wrap,
6
+ import type {
7
+ CombineObservable,
8
+ CombineObservableRefined,
9
+ InitializedObservable,
10
+ InitializedSyncChildObservable,
11
+ NonEmptyUnknownList,
12
+ Observable,
13
+ SyncChildObservable,
14
+ Wrap,
15
15
  } from '../types/index.mjs';
16
16
 
17
17
  /**
@@ -1,14 +1,14 @@
1
1
  import { Optional, expectType } from 'ts-data-forge';
2
- import { type ArrayElement, type NonEmptyTuple } from 'ts-type-forge';
2
+ import type { ArrayElement, NonEmptyTuple } from 'ts-type-forge';
3
3
  import { createSyncChildObservable } from '../base/index.mjs';
4
4
  import { source } from '../create/index.mjs';
5
- import {
6
- type MergeObservable,
7
- type MergeObservableRefined,
8
- type NonEmptyUnknownList,
9
- type Observable,
10
- type SyncChildObservable,
11
- type Wrap,
5
+ import type {
6
+ MergeObservable,
7
+ MergeObservableRefined,
8
+ NonEmptyUnknownList,
9
+ Observable,
10
+ SyncChildObservable,
11
+ Wrap,
12
12
  } from '../types/index.mjs';
13
13
 
14
14
  /**
@@ -1,18 +1,18 @@
1
1
  import { Arr, Optional, createQueue, expectType } from 'ts-data-forge';
2
- import { type NonEmptyTuple, type Tuple } from 'ts-type-forge';
2
+ import type { NonEmptyTuple, Tuple } from 'ts-type-forge';
3
3
  import { createSyncChildObservable } from '../base/index.mjs';
4
4
  import { source } from '../create/index.mjs';
5
5
  import { withInitialValue } from '../operators/index.mjs';
6
- import {
7
- type InitializedObservable,
8
- type InitializedSyncChildObservable,
9
- type NonEmptyUnknownList,
10
- type Observable,
11
- type SyncChildObservable,
12
- type TupleToQueueTuple,
13
- type Wrap,
14
- type ZipObservable,
15
- type ZipObservableRefined,
6
+ import type {
7
+ InitializedObservable,
8
+ InitializedSyncChildObservable,
9
+ NonEmptyUnknownList,
10
+ Observable,
11
+ SyncChildObservable,
12
+ TupleToQueueTuple,
13
+ Wrap,
14
+ ZipObservable,
15
+ ZipObservableRefined,
16
16
  } from '../types/index.mjs';
17
17
 
18
18
  /**
@@ -1,6 +1,6 @@
1
1
  import { asSafeUint, Optional, SafeUint } from 'ts-data-forge';
2
2
  import { createRootObservable } from '../base/index.mjs';
3
- import { type CounterObservable, type TimerId } from '../types/index.mjs';
3
+ import type { CounterObservable, TimerId } from '../types/index.mjs';
4
4
 
5
5
  /**
6
6
  * Creates an observable that emits incremental numbers at a specified interval.
@@ -1,6 +1,6 @@
1
1
  import { Optional, Result } from 'ts-data-forge';
2
2
  import { createRootObservable } from '../base/index.mjs';
3
- import { type FromPromiseObservable } from '../types/index.mjs';
3
+ import type { FromPromiseObservable } from '../types/index.mjs';
4
4
 
5
5
  /**
6
6
  * Creates an observable from a Promise factory that receives an `AbortSignal`.
@@ -1,6 +1,6 @@
1
1
  import { Optional, Result } from 'ts-data-forge';
2
2
  import { createRootObservable } from '../base/index.mjs';
3
- import { type FromPromiseObservable } from '../types/index.mjs';
3
+ import type { FromPromiseObservable } from '../types/index.mjs';
4
4
 
5
5
  /**
6
6
  * Creates an observable from a Promise.