synstate 0.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 (268) hide show
  1. package/README.md +878 -0
  2. package/dist/core/class/child-observable-class.d.mts +37 -0
  3. package/dist/core/class/child-observable-class.d.mts.map +1 -0
  4. package/dist/core/class/child-observable-class.mjs +134 -0
  5. package/dist/core/class/child-observable-class.mjs.map +1 -0
  6. package/dist/core/class/index.d.mts +4 -0
  7. package/dist/core/class/index.d.mts.map +1 -0
  8. package/dist/core/class/index.mjs +4 -0
  9. package/dist/core/class/index.mjs.map +1 -0
  10. package/dist/core/class/observable-base-class.d.mts +28 -0
  11. package/dist/core/class/observable-base-class.d.mts.map +1 -0
  12. package/dist/core/class/observable-base-class.mjs +116 -0
  13. package/dist/core/class/observable-base-class.mjs.map +1 -0
  14. package/dist/core/class/root-observable-class.d.mts +12 -0
  15. package/dist/core/class/root-observable-class.d.mts.map +1 -0
  16. package/dist/core/class/root-observable-class.mjs +35 -0
  17. package/dist/core/class/root-observable-class.mjs.map +1 -0
  18. package/dist/core/combine/combine.d.mts +35 -0
  19. package/dist/core/combine/combine.d.mts.map +1 -0
  20. package/dist/core/combine/combine.mjs +94 -0
  21. package/dist/core/combine/combine.mjs.map +1 -0
  22. package/dist/core/combine/index.d.mts +4 -0
  23. package/dist/core/combine/index.d.mts.map +1 -0
  24. package/dist/core/combine/index.mjs +4 -0
  25. package/dist/core/combine/index.mjs.map +1 -0
  26. package/dist/core/combine/merge.d.mts +28 -0
  27. package/dist/core/combine/merge.d.mts.map +1 -0
  28. package/dist/core/combine/merge.mjs +52 -0
  29. package/dist/core/combine/merge.mjs.map +1 -0
  30. package/dist/core/combine/zip.d.mts +26 -0
  31. package/dist/core/combine/zip.d.mts.map +1 -0
  32. package/dist/core/combine/zip.mjs +63 -0
  33. package/dist/core/combine/zip.mjs.map +1 -0
  34. package/dist/core/create/from-array.d.mts +21 -0
  35. package/dist/core/create/from-array.d.mts.map +1 -0
  36. package/dist/core/create/from-array.mjs +47 -0
  37. package/dist/core/create/from-array.mjs.map +1 -0
  38. package/dist/core/create/from-promise.d.mts +25 -0
  39. package/dist/core/create/from-promise.d.mts.map +1 -0
  40. package/dist/core/create/from-promise.mjs +51 -0
  41. package/dist/core/create/from-promise.mjs.map +1 -0
  42. package/dist/core/create/from-subscribable.d.mts +3 -0
  43. package/dist/core/create/from-subscribable.d.mts.map +1 -0
  44. package/dist/core/create/from-subscribable.mjs +22 -0
  45. package/dist/core/create/from-subscribable.mjs.map +1 -0
  46. package/dist/core/create/index.d.mts +8 -0
  47. package/dist/core/create/index.d.mts.map +1 -0
  48. package/dist/core/create/index.mjs +8 -0
  49. package/dist/core/create/index.mjs.map +1 -0
  50. package/dist/core/create/interval.d.mts +21 -0
  51. package/dist/core/create/interval.d.mts.map +1 -0
  52. package/dist/core/create/interval.mjs +74 -0
  53. package/dist/core/create/interval.mjs.map +1 -0
  54. package/dist/core/create/of.d.mts +20 -0
  55. package/dist/core/create/of.d.mts.map +1 -0
  56. package/dist/core/create/of.mjs +44 -0
  57. package/dist/core/create/of.mjs.map +1 -0
  58. package/dist/core/create/source.d.mts +29 -0
  59. package/dist/core/create/source.d.mts.map +1 -0
  60. package/dist/core/create/source.mjs +29 -0
  61. package/dist/core/create/source.mjs.map +1 -0
  62. package/dist/core/create/timer.d.mts +20 -0
  63. package/dist/core/create/timer.d.mts.map +1 -0
  64. package/dist/core/create/timer.mjs +64 -0
  65. package/dist/core/create/timer.mjs.map +1 -0
  66. package/dist/core/index.d.mts +7 -0
  67. package/dist/core/index.d.mts.map +1 -0
  68. package/dist/core/index.mjs +37 -0
  69. package/dist/core/index.mjs.map +1 -0
  70. package/dist/core/operators/audit-time.d.mts +3 -0
  71. package/dist/core/operators/audit-time.d.mts.map +1 -0
  72. package/dist/core/operators/audit-time.mjs +50 -0
  73. package/dist/core/operators/audit-time.mjs.map +1 -0
  74. package/dist/core/operators/debounce-time.d.mts +31 -0
  75. package/dist/core/operators/debounce-time.d.mts.map +1 -0
  76. package/dist/core/operators/debounce-time.mjs +73 -0
  77. package/dist/core/operators/debounce-time.mjs.map +1 -0
  78. package/dist/core/operators/filter.d.mts +28 -0
  79. package/dist/core/operators/filter.d.mts.map +1 -0
  80. package/dist/core/operators/filter.mjs +38 -0
  81. package/dist/core/operators/filter.mjs.map +1 -0
  82. package/dist/core/operators/index.d.mts +18 -0
  83. package/dist/core/operators/index.d.mts.map +1 -0
  84. package/dist/core/operators/index.mjs +18 -0
  85. package/dist/core/operators/index.mjs.map +1 -0
  86. package/dist/core/operators/map-with-index.d.mts +39 -0
  87. package/dist/core/operators/map-with-index.d.mts.map +1 -0
  88. package/dist/core/operators/map-with-index.mjs +73 -0
  89. package/dist/core/operators/map-with-index.mjs.map +1 -0
  90. package/dist/core/operators/merge-map.d.mts +34 -0
  91. package/dist/core/operators/merge-map.d.mts.map +1 -0
  92. package/dist/core/operators/merge-map.mjs +75 -0
  93. package/dist/core/operators/merge-map.mjs.map +1 -0
  94. package/dist/core/operators/pairwise.d.mts +27 -0
  95. package/dist/core/operators/pairwise.d.mts.map +1 -0
  96. package/dist/core/operators/pairwise.mjs +59 -0
  97. package/dist/core/operators/pairwise.mjs.map +1 -0
  98. package/dist/core/operators/scan.d.mts +30 -0
  99. package/dist/core/operators/scan.d.mts.map +1 -0
  100. package/dist/core/operators/scan.mjs +56 -0
  101. package/dist/core/operators/scan.mjs.map +1 -0
  102. package/dist/core/operators/skip-if-no-change.d.mts +33 -0
  103. package/dist/core/operators/skip-if-no-change.d.mts.map +1 -0
  104. package/dist/core/operators/skip-if-no-change.mjs +68 -0
  105. package/dist/core/operators/skip-if-no-change.mjs.map +1 -0
  106. package/dist/core/operators/skip-until.d.mts +3 -0
  107. package/dist/core/operators/skip-until.d.mts.map +1 -0
  108. package/dist/core/operators/skip-until.mjs +33 -0
  109. package/dist/core/operators/skip-until.mjs.map +1 -0
  110. package/dist/core/operators/skip-while.d.mts +4 -0
  111. package/dist/core/operators/skip-while.d.mts.map +1 -0
  112. package/dist/core/operators/skip-while.mjs +40 -0
  113. package/dist/core/operators/skip-while.mjs.map +1 -0
  114. package/dist/core/operators/switch-map.d.mts +31 -0
  115. package/dist/core/operators/switch-map.d.mts.map +1 -0
  116. package/dist/core/operators/switch-map.mjs +70 -0
  117. package/dist/core/operators/switch-map.mjs.map +1 -0
  118. package/dist/core/operators/take-until.d.mts +32 -0
  119. package/dist/core/operators/take-until.d.mts.map +1 -0
  120. package/dist/core/operators/take-until.mjs +60 -0
  121. package/dist/core/operators/take-until.mjs.map +1 -0
  122. package/dist/core/operators/take-while.d.mts +4 -0
  123. package/dist/core/operators/take-while.d.mts.map +1 -0
  124. package/dist/core/operators/take-while.mjs +42 -0
  125. package/dist/core/operators/take-while.mjs.map +1 -0
  126. package/dist/core/operators/throttle-time.d.mts +23 -0
  127. package/dist/core/operators/throttle-time.d.mts.map +1 -0
  128. package/dist/core/operators/throttle-time.mjs +68 -0
  129. package/dist/core/operators/throttle-time.mjs.map +1 -0
  130. package/dist/core/operators/with-buffered-from.d.mts +4 -0
  131. package/dist/core/operators/with-buffered-from.d.mts.map +1 -0
  132. package/dist/core/operators/with-buffered-from.mjs +45 -0
  133. package/dist/core/operators/with-buffered-from.mjs.map +1 -0
  134. package/dist/core/operators/with-current-value-from.d.mts +4 -0
  135. package/dist/core/operators/with-current-value-from.d.mts.map +1 -0
  136. package/dist/core/operators/with-current-value-from.mjs +37 -0
  137. package/dist/core/operators/with-current-value-from.mjs.map +1 -0
  138. package/dist/core/operators/with-initial-value.d.mts +26 -0
  139. package/dist/core/operators/with-initial-value.d.mts.map +1 -0
  140. package/dist/core/operators/with-initial-value.mjs +47 -0
  141. package/dist/core/operators/with-initial-value.mjs.map +1 -0
  142. package/dist/core/types/id.d.mts +4 -0
  143. package/dist/core/types/id.d.mts.map +1 -0
  144. package/dist/core/types/id.mjs +2 -0
  145. package/dist/core/types/id.mjs.map +1 -0
  146. package/dist/core/types/index.d.mts +6 -0
  147. package/dist/core/types/index.d.mts.map +1 -0
  148. package/dist/core/types/index.mjs +3 -0
  149. package/dist/core/types/index.mjs.map +1 -0
  150. package/dist/core/types/observable-family.d.mts +68 -0
  151. package/dist/core/types/observable-family.d.mts.map +1 -0
  152. package/dist/core/types/observable-family.mjs +2 -0
  153. package/dist/core/types/observable-family.mjs.map +1 -0
  154. package/dist/core/types/observable-kind.d.mts +4 -0
  155. package/dist/core/types/observable-kind.d.mts.map +1 -0
  156. package/dist/core/types/observable-kind.mjs +2 -0
  157. package/dist/core/types/observable-kind.mjs.map +1 -0
  158. package/dist/core/types/observable.d.mts +83 -0
  159. package/dist/core/types/observable.d.mts.map +1 -0
  160. package/dist/core/types/observable.mjs +10 -0
  161. package/dist/core/types/observable.mjs.map +1 -0
  162. package/dist/core/types/types.d.mts +16 -0
  163. package/dist/core/types/types.d.mts.map +1 -0
  164. package/dist/core/types/types.mjs +2 -0
  165. package/dist/core/types/types.mjs.map +1 -0
  166. package/dist/core/utils/id-maker.d.mts +5 -0
  167. package/dist/core/utils/id-maker.d.mts.map +1 -0
  168. package/dist/core/utils/id-maker.mjs +17 -0
  169. package/dist/core/utils/id-maker.mjs.map +1 -0
  170. package/dist/core/utils/index.d.mts +5 -0
  171. package/dist/core/utils/index.d.mts.map +1 -0
  172. package/dist/core/utils/index.mjs +5 -0
  173. package/dist/core/utils/index.mjs.map +1 -0
  174. package/dist/core/utils/max-depth.d.mts +3 -0
  175. package/dist/core/utils/max-depth.d.mts.map +1 -0
  176. package/dist/core/utils/max-depth.mjs +8 -0
  177. package/dist/core/utils/max-depth.mjs.map +1 -0
  178. package/dist/core/utils/observable-utils.d.mts +3 -0
  179. package/dist/core/utils/observable-utils.d.mts.map +1 -0
  180. package/dist/core/utils/observable-utils.mjs +7 -0
  181. package/dist/core/utils/observable-utils.mjs.map +1 -0
  182. package/dist/core/utils/utils.d.mts +4 -0
  183. package/dist/core/utils/utils.d.mts.map +1 -0
  184. package/dist/core/utils/utils.mjs +38 -0
  185. package/dist/core/utils/utils.mjs.map +1 -0
  186. package/dist/entry-point.d.mts +2 -0
  187. package/dist/entry-point.d.mts.map +1 -0
  188. package/dist/entry-point.mjs +40 -0
  189. package/dist/entry-point.mjs.map +1 -0
  190. package/dist/globals.d.mts +4 -0
  191. package/dist/index.d.mts +3 -0
  192. package/dist/index.d.mts.map +1 -0
  193. package/dist/index.mjs +40 -0
  194. package/dist/index.mjs.map +1 -0
  195. package/dist/tsconfig.json +1 -0
  196. package/dist/types.d.mts +2 -0
  197. package/dist/utils/create-event-emitter.d.mts +39 -0
  198. package/dist/utils/create-event-emitter.d.mts.map +1 -0
  199. package/dist/utils/create-event-emitter.mjs +57 -0
  200. package/dist/utils/create-event-emitter.mjs.map +1 -0
  201. package/dist/utils/create-reducer.d.mts +34 -0
  202. package/dist/utils/create-reducer.d.mts.map +1 -0
  203. package/dist/utils/create-reducer.mjs +49 -0
  204. package/dist/utils/create-reducer.mjs.map +1 -0
  205. package/dist/utils/create-state.d.mts +61 -0
  206. package/dist/utils/create-state.d.mts.map +1 -0
  207. package/dist/utils/create-state.mjs +92 -0
  208. package/dist/utils/create-state.mjs.map +1 -0
  209. package/dist/utils/index.d.mts +4 -0
  210. package/dist/utils/index.d.mts.map +1 -0
  211. package/dist/utils/index.mjs +4 -0
  212. package/dist/utils/index.mjs.map +1 -0
  213. package/package.json +71 -0
  214. package/src/core/class/child-observable-class.mts +232 -0
  215. package/src/core/class/index.mts +3 -0
  216. package/src/core/class/observable-base-class.mts +186 -0
  217. package/src/core/class/observable.class.test.mts +89 -0
  218. package/src/core/class/root-observable-class.mts +68 -0
  219. package/src/core/combine/combine.mts +144 -0
  220. package/src/core/combine/index.mts +3 -0
  221. package/src/core/combine/merge.mts +84 -0
  222. package/src/core/combine/zip.mts +149 -0
  223. package/src/core/create/from-array.mts +58 -0
  224. package/src/core/create/from-promise.mts +58 -0
  225. package/src/core/create/from-subscribable.mts +37 -0
  226. package/src/core/create/index.mts +7 -0
  227. package/src/core/create/interval.mts +99 -0
  228. package/src/core/create/of.mts +54 -0
  229. package/src/core/create/source.mts +59 -0
  230. package/src/core/create/timer.mts +84 -0
  231. package/src/core/index.mts +6 -0
  232. package/src/core/operators/audit-time.mts +77 -0
  233. package/src/core/operators/debounce-time.mts +96 -0
  234. package/src/core/operators/filter.mts +125 -0
  235. package/src/core/operators/index.mts +17 -0
  236. package/src/core/operators/map-with-index.mts +168 -0
  237. package/src/core/operators/merge-map.mts +108 -0
  238. package/src/core/operators/pairwise.mts +77 -0
  239. package/src/core/operators/scan.mts +81 -0
  240. package/src/core/operators/skip-if-no-change.mts +91 -0
  241. package/src/core/operators/skip-until.mts +54 -0
  242. package/src/core/operators/skip-while.mts +77 -0
  243. package/src/core/operators/switch-map.mts +101 -0
  244. package/src/core/operators/take-until.mts +80 -0
  245. package/src/core/operators/take-while.mts +103 -0
  246. package/src/core/operators/throttle-time.mts +95 -0
  247. package/src/core/operators/with-buffered-from.mts +68 -0
  248. package/src/core/operators/with-current-value-from.mts +58 -0
  249. package/src/core/operators/with-initial-value.mts +76 -0
  250. package/src/core/types/id.mts +5 -0
  251. package/src/core/types/index.mts +5 -0
  252. package/src/core/types/observable-family.mts +259 -0
  253. package/src/core/types/observable-kind.mts +5 -0
  254. package/src/core/types/observable.mts +218 -0
  255. package/src/core/types/types.mts +40 -0
  256. package/src/core/utils/id-maker.mts +31 -0
  257. package/src/core/utils/index.mts +4 -0
  258. package/src/core/utils/max-depth.mts +7 -0
  259. package/src/core/utils/observable-utils.mts +10 -0
  260. package/src/core/utils/utils.mts +51 -0
  261. package/src/core/utils/utils.test.mts +88 -0
  262. package/src/entry-point.mts +1 -0
  263. package/src/globals.d.mts +4 -0
  264. package/src/index.mts +2 -0
  265. package/src/utils/create-event-emitter.mts +62 -0
  266. package/src/utils/create-reducer.mts +55 -0
  267. package/src/utils/create-state.mts +138 -0
  268. package/src/utils/index.mts +3 -0
@@ -0,0 +1,61 @@
1
+ import { type InitializedObservable } from '../core/index.mjs';
2
+ /**
3
+ * Creates a reactive state container with getter and setter methods.
4
+ * Provides a simple state management solution with observable state.
5
+ *
6
+ * @template S - The type of the state
7
+ * @param initialState - The initial value of the state
8
+ * @returns An object containing the state observable and methods to manipulate it
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const [state, setState, { updateState, resetState }] = createState(0);
13
+ *
14
+ * state.subscribe((value: number) => {
15
+ * console.log(value);
16
+ * }); // logs: 0
17
+ *
18
+ * setState(10); // logs: 10
19
+ *
20
+ * updateState((prev: number) => prev + 1); // logs: 11
21
+ *
22
+ * resetState(); // logs: 0
23
+ * ```
24
+ */
25
+ export declare const createState: <S>(initialState: S) => readonly [state: InitializedObservable<S>, setState: (v: S) => S, Readonly<{
26
+ updateState: (updateFn: (prev: S) => S) => S;
27
+ resetState: () => S;
28
+ getSnapshot: () => S;
29
+ }>];
30
+ /**
31
+ * Creates a reactive boolean state with convenient methods for boolean operations.
32
+ * Extends `createState` with boolean-specific helpers like `toggle`, `setTrue`, and `setFalse`.
33
+ *
34
+ * @param initialState - The initial boolean value
35
+ * @returns An object with the state observable and boolean-specific methods
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const [state, { setTrue, toggle }] = createBooleanState(false);
40
+ *
41
+ * state.subscribe((value: boolean) => {
42
+ * console.log(value);
43
+ * }); // logs: false
44
+ *
45
+ * setTrue(); // logs: true
46
+ *
47
+ * toggle(); // logs: false
48
+ *
49
+ * toggle(); // logs: true
50
+ * ```
51
+ */
52
+ export declare const createBooleanState: (initialState: boolean) => readonly [state: InitializedObservable<boolean>, Readonly<{
53
+ setTrue: () => void;
54
+ setFalse: () => void;
55
+ setState: (next: boolean) => boolean;
56
+ toggle: () => boolean;
57
+ updateState: (updateFn: (prev: boolean) => boolean) => boolean;
58
+ resetState: () => boolean;
59
+ getSnapshot: () => boolean;
60
+ }>];
61
+ //# sourceMappingURL=create-state.d.mts.map
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,cAAc,CAAC,KACd,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,QAAQ,CAAC;IACP,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;CACtB,CAAC,CAwBH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,cAAc,OAAO,KACpB,SAAS,CACV,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,EACrC,QAAQ,CAAC;IACP,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;IACrC,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,KAAK,OAAO,CAAC;IAC/D,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B,CAAC,CAqBH,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { createReducer } from './create-reducer.mjs';
2
+
3
+ const reducer = (state, action) => {
4
+ switch (action.type) {
5
+ case 'set':
6
+ return action.nextState;
7
+ case 'update':
8
+ return action.updateFn(state);
9
+ }
10
+ };
11
+ /**
12
+ * Creates a reactive state container with getter and setter methods.
13
+ * Provides a simple state management solution with observable state.
14
+ *
15
+ * @template S - The type of the state
16
+ * @param initialState - The initial value of the state
17
+ * @returns An object containing the state observable and methods to manipulate it
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const [state, setState, { updateState, resetState }] = createState(0);
22
+ *
23
+ * state.subscribe((value: number) => {
24
+ * console.log(value);
25
+ * }); // logs: 0
26
+ *
27
+ * setState(10); // logs: 10
28
+ *
29
+ * updateState((prev: number) => prev + 1); // logs: 11
30
+ *
31
+ * resetState(); // logs: 0
32
+ * ```
33
+ */
34
+ const createState = (initialState) => {
35
+ const [state, dispatch, getSnapshot] = createReducer(reducer, initialState);
36
+ const updateState = (updateFn) => dispatch({ type: 'update', updateFn });
37
+ const setState = (nextState) => dispatch({ type: 'set', nextState });
38
+ const resetState = () => dispatch({ type: 'set', nextState: initialState });
39
+ return [
40
+ state,
41
+ setState,
42
+ {
43
+ updateState,
44
+ resetState,
45
+ getSnapshot,
46
+ },
47
+ ];
48
+ };
49
+ /**
50
+ * Creates a reactive boolean state with convenient methods for boolean operations.
51
+ * Extends `createState` with boolean-specific helpers like `toggle`, `setTrue`, and `setFalse`.
52
+ *
53
+ * @param initialState - The initial boolean value
54
+ * @returns An object with the state observable and boolean-specific methods
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const [state, { setTrue, toggle }] = createBooleanState(false);
59
+ *
60
+ * state.subscribe((value: boolean) => {
61
+ * console.log(value);
62
+ * }); // logs: false
63
+ *
64
+ * setTrue(); // logs: true
65
+ *
66
+ * toggle(); // logs: false
67
+ *
68
+ * toggle(); // logs: true
69
+ * ```
70
+ */
71
+ const createBooleanState = (initialState) => {
72
+ const [state, setState, { updateState, resetState, getSnapshot }] = createState(initialState);
73
+ return [
74
+ state,
75
+ {
76
+ setTrue: () => {
77
+ setState(true);
78
+ },
79
+ setFalse: () => {
80
+ setState(false);
81
+ },
82
+ toggle: () => updateState((s) => !s),
83
+ setState,
84
+ updateState,
85
+ resetState,
86
+ getSnapshot,
87
+ },
88
+ ];
89
+ };
90
+
91
+ export { createBooleanState, createState };
92
+ //# sourceMappingURL=create-state.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-state.mjs","sources":["../../src/utils/create-state.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAcA,MAAM,OAAO,GAAG,CAAK,KAAQ,EAAE,MAAiB,KAAO;AACrD,IAAA,QAAQ,MAAM,CAAC,IAAI;AACjB,QAAA,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,SAAS;AAEzB,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;;AAEnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACI,MAAM,WAAW,GAAG,CACzB,YAAe,KASb;AACF,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,aAAa,CAClD,OAAO,EACP,YAAY,CACb;AAED,IAAA,MAAM,WAAW,GAAG,CAAC,QAAwB,KAC3C,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAExC,IAAA,MAAM,QAAQ,GAAG,CAAC,SAAY,KAAQ,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAE1E,IAAA,MAAM,UAAU,GAAG,MACjB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAEpD,OAAO;QACL,KAAK;QACL,QAAQ;AACR,QAAA;YACE,WAAW;YACX,UAAU;YACV,WAAW;AACZ,SAAA;KACO;AACZ;AAEA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACI,MAAM,kBAAkB,GAAG,CAChC,YAAqB,KAYnB;AACF,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,GAC/D,WAAW,CAAC,YAAY,CAAC;IAE3B,OAAO;QACL,KAAK;AACL,QAAA;YACE,OAAO,EAAE,MAAK;gBACZ,QAAQ,CAAC,IAAI,CAAC;YAChB,CAAC;YACD,QAAQ,EAAE,MAAK;gBACb,QAAQ,CAAC,KAAK,CAAC;YACjB,CAAC;AACD,YAAA,MAAM,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,QAAQ;YACR,WAAW;YACX,UAAU;YACV,WAAW;AACZ,SAAA;KACO;AACZ;;;;"}
@@ -0,0 +1,4 @@
1
+ export * from './create-event-emitter.mjs';
2
+ export * from './create-reducer.mjs';
3
+ export * from './create-state.mjs';
4
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/utils/index.mts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createEventEmitter, createValueEmitter } from './create-event-emitter.mjs';
2
+ export { createReducer } from './create-reducer.mjs';
3
+ export { createBooleanState, createState } from './create-state.mjs';
4
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "synstate",
3
+ "version": "0.1.0",
4
+ "description": "Reactive Programming Library for TypeScript/JavaScript",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/noshiro-pf/synstate.git"
8
+ },
9
+ "license": "Apache-2.0",
10
+ "author": "noshiro-pf <noshiro.pf@gmail.com>",
11
+ "sideEffects": false,
12
+ "type": "module",
13
+ "exports": {
14
+ ".": {
15
+ "import": {
16
+ "types": "./dist/index.d.mts",
17
+ "default": "./dist/index.mjs"
18
+ }
19
+ }
20
+ },
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "files": [
24
+ "src",
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsx ./scripts/cmd/build.mts",
31
+ "build:min": "tsx ./scripts/cmd/build.mts --skip-check",
32
+ "check:ext": "tsx ./scripts/cmd/check-ext.mts",
33
+ "check-all": "tsx ./scripts/cmd/check-all.mts",
34
+ "codemod": "convert-to-readonly '{src,samples,test}/**/*.{mts,tsx}'",
35
+ "doc": "tsx ./scripts/cmd/gen-docs.mts",
36
+ "doc:embed": "tsx ./scripts/cmd/embed-examples.mts",
37
+ "doc:embed:jsdoc": "tsx ./scripts/cmd/embed-examples-in-jsdoc.mts",
38
+ "doc:preview": "vite preview --config ./configs/vite.doc.config.ts",
39
+ "doc:watch": "typedoc --options ./configs/typedoc.config.mjs --watch",
40
+ "fmt": "pnpm run z:prettier .",
41
+ "gi": "run-s gi:src fmt",
42
+ "gi:src": "gen-index-ts ./src --index-ext .mts --export-ext .mjs --target-ext .mts --target-ext .tsx --exclude entry-point.mts",
43
+ "lint": "eslint .",
44
+ "lint:fix": "eslint . --fix",
45
+ "test": "pnpm run z:vitest:node run",
46
+ "test:all": "run-p test test:stream",
47
+ "test:browser": "pnpm run z:vitest --project='Browser' run",
48
+ "test:cov": "pnpm run z:vitest:node run --coverage",
49
+ "test:cov:ui": "vite preview --outDir ./coverage",
50
+ "test:stream": "pnpm run z:vitest:stream run",
51
+ "test:ui": "pnpm run z:vitest:node --ui",
52
+ "testw": "pnpm run z:vitest:node watch",
53
+ "tsc": "tsc --noEmit",
54
+ "tscw": "tsc --noEmit --watch",
55
+ "type-check": "tsc --noEmit",
56
+ "update-packages": "pnpm update --latest",
57
+ "z:prettier": "prettier --config ../../.prettierrc --ignore-path ../../.prettierignore --ignore-path ../../.gitignore --ignore-unknown --no-error-on-unmatched-pattern --write",
58
+ "z:vitest": "vitest --config ./configs/vitest.config.mts",
59
+ "z:vitest:node": "pnpm run z:vitest --project='Node.js'",
60
+ "z:vitest:stream": "vitest --config ./configs/vitest.config.stream.ts"
61
+ },
62
+ "dependencies": {
63
+ "ts-data-forge": "^6.5.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/argparse": "^2.0.17",
67
+ "@types/react": "^19.2.14",
68
+ "argparse": "^2.0.1",
69
+ "react": "^19.2.4"
70
+ }
71
+ }
@@ -0,0 +1,232 @@
1
+ import { Arr } from 'ts-data-forge';
2
+ import {
3
+ isManagerObservable,
4
+ type AsyncChildObservable,
5
+ type ChildObservable,
6
+ type InitializedObservable,
7
+ type InitializedSyncChildObservable,
8
+ type KeepInitialValueOperator,
9
+ type NonEmptyUnknownList,
10
+ type Observable,
11
+ type ObservableId,
12
+ type Operator,
13
+ type SyncChildObservable,
14
+ type WithInitialValueOperator,
15
+ type Wrap,
16
+ } from '../types/index.mjs';
17
+ import { binarySearch, issueUpdaterSymbol, maxDepth } from '../utils/index.mjs';
18
+ import { ObservableBaseClass } from './observable-base-class.mjs';
19
+
20
+ const registerChild = <A,>(
21
+ child: ChildObservable<A>,
22
+ parents: ChildObservable<A>['parents'],
23
+ ): void => {
24
+ for (const p of parents) {
25
+ p.addChild(child);
26
+ }
27
+
28
+ // register child to all reachable ManagerObservables
29
+ const mut_rest = Array.from(parents);
30
+
31
+ while (Arr.isNonEmpty(mut_rest)) {
32
+ const p = mut_rest.pop();
33
+
34
+ if (p === undefined) break;
35
+
36
+ if (isManagerObservable(p)) {
37
+ p.addDescendant(child);
38
+ } else {
39
+ // trace back dependency graph
40
+ mut_rest.push(...p.parents);
41
+ }
42
+ }
43
+ };
44
+
45
+ const tryComplete = <A,>({
46
+ hasSubscriber,
47
+ hasActiveChild,
48
+ parents,
49
+ complete,
50
+ }: Readonly<{
51
+ hasSubscriber: boolean;
52
+ hasActiveChild: boolean;
53
+ parents: ChildObservable<A>['parents'];
54
+ complete: () => void;
55
+ }>): void => {
56
+ // If there is no working parent node
57
+ if (parents.every((r) => r.isCompleted)) {
58
+ complete();
59
+
60
+ return;
61
+ }
62
+
63
+ // If there are no active child node
64
+ if (!hasSubscriber && !hasActiveChild) {
65
+ complete();
66
+ }
67
+
68
+ // propagate to parents
69
+ for (const par of parents) {
70
+ par.tryComplete();
71
+ }
72
+ };
73
+
74
+ export class AsyncChildObservableClass<A, const P extends NonEmptyUnknownList>
75
+ extends ObservableBaseClass<A, 'async child', number>
76
+ implements AsyncChildObservable<A, P>
77
+ {
78
+ readonly parents;
79
+ #mut_procedure: readonly ChildObservable<unknown>[];
80
+ protected readonly descendantsIdSet: MutableSet<ObservableId>;
81
+
82
+ constructor({
83
+ parents,
84
+ depth = 1 + maxDepth(parents),
85
+ initialValue,
86
+ }: Readonly<{
87
+ parents: Wrap<P>;
88
+ depth?: number;
89
+ initialValue: ReturnType<AsyncChildObservable<A>['getSnapshot']>;
90
+ }>) {
91
+ super({
92
+ kind: 'async child',
93
+ depth,
94
+ initialValue,
95
+ });
96
+
97
+ this.parents = parents;
98
+
99
+ this.#mut_procedure = [];
100
+
101
+ this.descendantsIdSet = new Set<ObservableId>();
102
+
103
+ registerChild(this, parents);
104
+ }
105
+
106
+ // overload
107
+ addDescendant<B>(child: ChildObservable<B>): void {
108
+ if (this.descendantsIdSet.has(child.id)) return;
109
+
110
+ this.descendantsIdSet.add(child.id);
111
+
112
+ const insertPos = binarySearch(
113
+ this.#mut_procedure.map((a) => a.depth),
114
+ child.depth,
115
+ );
116
+
117
+ this.#mut_procedure = Arr.toInserted(this.#mut_procedure, insertPos, child);
118
+ }
119
+
120
+ startUpdate(nextValue: A): void {
121
+ const updaterSymbol = issueUpdaterSymbol();
122
+
123
+ this.setNext(nextValue, updaterSymbol);
124
+
125
+ for (const p of this.#mut_procedure) {
126
+ p.tryUpdate(updaterSymbol);
127
+ }
128
+ }
129
+
130
+ override complete(): void {
131
+ super.complete();
132
+
133
+ // propagate to parents
134
+ for (const par of this.parents) {
135
+ par.tryComplete();
136
+ }
137
+ }
138
+
139
+ override tryComplete(): void {
140
+ tryComplete({
141
+ complete: () => {
142
+ this.complete();
143
+ },
144
+ hasActiveChild: this.hasActiveChild(),
145
+ hasSubscriber: this.hasSubscriber,
146
+ parents: this.parents,
147
+ });
148
+ }
149
+ }
150
+
151
+ export class SyncChildObservableClass<A, const P extends NonEmptyUnknownList>
152
+ extends ObservableBaseClass<A, 'sync child', number>
153
+ implements SyncChildObservable<A, P>
154
+ {
155
+ readonly parents;
156
+
157
+ constructor({
158
+ parents,
159
+ depth = 1 + maxDepth(parents),
160
+ initialValue,
161
+ }: Readonly<{
162
+ parents: Wrap<P>;
163
+ depth?: number;
164
+ initialValue: ReturnType<SyncChildObservable<A>['getSnapshot']>;
165
+ }>) {
166
+ super({
167
+ kind: 'sync child',
168
+ depth,
169
+ initialValue,
170
+ });
171
+
172
+ this.parents = parents;
173
+
174
+ registerChild(this, parents);
175
+ }
176
+
177
+ override complete(): void {
178
+ super.complete();
179
+
180
+ for (const par of this.parents) {
181
+ par.tryComplete();
182
+ }
183
+ }
184
+
185
+ override tryComplete(): void {
186
+ tryComplete({
187
+ complete: () => {
188
+ this.complete();
189
+ },
190
+ hasActiveChild: this.hasActiveChild(),
191
+ hasSubscriber: this.hasSubscriber,
192
+ parents: this.parents,
193
+ });
194
+ }
195
+ }
196
+
197
+ export class InitializedSyncChildObservableClass<
198
+ A,
199
+ const P extends NonEmptyUnknownList,
200
+ >
201
+ extends SyncChildObservableClass<A, P>
202
+ implements InitializedSyncChildObservable<A, P>
203
+ {
204
+ constructor({
205
+ parents,
206
+ depth = 1 + maxDepth(parents),
207
+ initialValue,
208
+ }: Readonly<{
209
+ parents: Wrap<P>;
210
+ depth?: number;
211
+ initialValue: ReturnType<InitializedSyncChildObservable<A>['getSnapshot']>;
212
+ }>) {
213
+ super({ parents, depth, initialValue });
214
+ }
215
+
216
+ override getSnapshot(): Some<A> {
217
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
218
+ return super.getCurrentValue() as Some<A>;
219
+ }
220
+
221
+ override pipe<B>(
222
+ operator: KeepInitialValueOperator<A, B> | WithInitialValueOperator<A, B>,
223
+ ): InitializedObservable<B>;
224
+
225
+ override pipe<B>(operator: Operator<A, B>): Observable<B>;
226
+ override pipe<B>(operator: Operator<A, B>): Observable<B> {
227
+ return operator(
228
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
229
+ this as unknown as InitializedObservable<A>,
230
+ );
231
+ }
232
+ }
@@ -0,0 +1,3 @@
1
+ export * from './child-observable-class.mjs';
2
+ export * from './observable-base-class.mjs';
3
+ export * from './root-observable-class.mjs';
@@ -0,0 +1,186 @@
1
+ import { Arr, Optional } from 'ts-data-forge';
2
+ import {
3
+ type ChildObservable,
4
+ type InitializedObservable,
5
+ type Observable,
6
+ type ObservableBase,
7
+ type Operator,
8
+ type Subscriber,
9
+ type SubscriberId,
10
+ type Subscription,
11
+ type UpdaterSymbol,
12
+ type WithInitialValueOperator,
13
+ } from '../types/index.mjs';
14
+ import {
15
+ issueObservableId,
16
+ issueSubscriberId,
17
+ issueUpdaterSymbol,
18
+ toSubscriber,
19
+ } from '../utils/index.mjs';
20
+
21
+ export class ObservableBaseClass<
22
+ A,
23
+ Kind extends ObservableBase<A>['kind'],
24
+ Depth extends ObservableBase<A>['depth'],
25
+ > implements ObservableBase<A> {
26
+ readonly id;
27
+ readonly kind: Kind;
28
+ readonly depth: Depth;
29
+ #mut_children: readonly ChildObservable<unknown>[];
30
+ readonly #subscribers: MutableMap<SubscriberId, Subscriber<A>>;
31
+ #mut_currentValue: ReturnType<ObservableBase<A>['getSnapshot']>;
32
+ #mut_isCompleted: ObservableBase<A>['isCompleted'];
33
+ #mut_updaterSymbol: ObservableBase<A>['updaterSymbol'];
34
+
35
+ constructor({
36
+ kind,
37
+ depth,
38
+ initialValue,
39
+ }: Readonly<{
40
+ kind: Kind;
41
+ depth: Depth;
42
+ initialValue: ReturnType<ObservableBase<A>['getSnapshot']>;
43
+ }>) {
44
+ this.kind = kind;
45
+
46
+ this.depth = depth;
47
+
48
+ this.id = issueObservableId();
49
+
50
+ this.#mut_currentValue = initialValue;
51
+
52
+ this.#mut_children = [];
53
+
54
+ this.#subscribers = new Map<SubscriberId, Subscriber<A>>();
55
+
56
+ this.#mut_isCompleted = false;
57
+
58
+ this.#mut_updaterSymbol = issueUpdaterSymbol();
59
+ }
60
+
61
+ addChild<B>(child: ChildObservable<B>): void {
62
+ this.#mut_children = Arr.toPushed(
63
+ this.#mut_children,
64
+
65
+ child as ChildObservable<unknown>,
66
+ );
67
+ }
68
+
69
+ getSnapshot(): ReturnType<ObservableBase<A>['getSnapshot']> {
70
+ return this.#mut_currentValue;
71
+ }
72
+
73
+ protected getCurrentValue(): ReturnType<ObservableBase<A>['getSnapshot']> {
74
+ return this.#mut_currentValue;
75
+ }
76
+
77
+ get isCompleted(): boolean {
78
+ return this.#mut_isCompleted;
79
+ }
80
+
81
+ get updaterSymbol(): UpdaterSymbol {
82
+ return this.#mut_updaterSymbol;
83
+ }
84
+
85
+ get hasSubscriber(): boolean {
86
+ return this.#subscribers.size > 0;
87
+ }
88
+
89
+ get hasChild(): boolean {
90
+ return Arr.isNonEmpty(this.#mut_children);
91
+ }
92
+
93
+ hasActiveChild(): boolean {
94
+ return this.#mut_children.some((c) => !c.isCompleted);
95
+ }
96
+
97
+ protected setNext(nextValue: A, updaterSymbol: UpdaterSymbol): void {
98
+ this.#mut_updaterSymbol = updaterSymbol;
99
+
100
+ this.#mut_currentValue = Optional.some(nextValue);
101
+
102
+ for (const s of this.#subscribers.values()) {
103
+ s.onNext(nextValue);
104
+ }
105
+ }
106
+
107
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
108
+ tryUpdate(_updaterSymbol: UpdaterSymbol): void {
109
+ throw new Error('not implemented');
110
+ }
111
+
112
+ tryComplete(): void {
113
+ if (!this.hasSubscriber && !this.hasActiveChild()) {
114
+ this.complete();
115
+ }
116
+ }
117
+
118
+ complete(): void {
119
+ if (this.isCompleted) return; // terminate only once
120
+
121
+ // change state
122
+ this.#mut_isCompleted = true;
123
+
124
+ // run subscribers for the current value
125
+ for (const s of this.#subscribers.values()) {
126
+ s.onComplete();
127
+ }
128
+
129
+ // remove all subscribers
130
+ this.#subscribers.clear();
131
+
132
+ // propagate to children
133
+ for (const o of this.#mut_children) {
134
+ o.tryComplete();
135
+ }
136
+ }
137
+
138
+ pipe<B>(operator: WithInitialValueOperator<A, B>): InitializedObservable<B>;
139
+ pipe<B>(operator: Operator<A, B>): Observable<B>;
140
+ pipe<B>(operator: Operator<A, B>): Observable<B> {
141
+ return operator(
142
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
143
+ this as unknown as InitializedObservable<A>,
144
+ );
145
+ }
146
+
147
+ subscribe(onNext: (v: A) => void, onComplete?: () => void): Subscription {
148
+ // first emit
149
+ const curr = this.getSnapshot();
150
+
151
+ if (Optional.isSome(curr)) {
152
+ onNext(curr.value);
153
+ }
154
+
155
+ if (this.isCompleted) {
156
+ if (onComplete !== undefined) {
157
+ onComplete();
158
+ }
159
+
160
+ return { unsubscribe: () => {} };
161
+ }
162
+
163
+ const id: SubscriberId = this.#addSubscriber(
164
+ toSubscriber(onNext, onComplete),
165
+ );
166
+
167
+ return {
168
+ unsubscribe: () => {
169
+ this.#removeSubscriber(id);
170
+ },
171
+ };
172
+ }
173
+
174
+ #addSubscriber(s: Subscriber<A>): SubscriberId {
175
+ // return the id of added subscriber
176
+ const id = issueSubscriberId();
177
+
178
+ this.#subscribers.set(id, s);
179
+
180
+ return id;
181
+ }
182
+
183
+ #removeSubscriber(id: SubscriberId): void {
184
+ this.#subscribers.delete(id);
185
+ }
186
+ }