@fozy-labs/rx-toolkit 0.5.4 → 0.6.2

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 (303) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +22 -13
  3. package/dist/common/devtools/reduxDevtools.js +17 -2
  4. package/dist/common/react/index.d.ts +1 -0
  5. package/dist/common/react/index.js +1 -0
  6. package/dist/common/react/useIsomorphicLayoutEffect.d.ts +17 -0
  7. package/dist/common/react/useIsomorphicLayoutEffect.js +17 -0
  8. package/dist/index.d.ts +1 -2
  9. package/dist/index.js +1 -2
  10. package/dist/query/api/createApi.d.ts +4 -0
  11. package/dist/query/api/createApi.js +9 -0
  12. package/dist/query/api/index.d.ts +1 -0
  13. package/dist/query/api/index.js +1 -0
  14. package/dist/query/constants.d.ts +12 -0
  15. package/dist/query/constants.js +15 -0
  16. package/dist/query/core/api/Api.d.ts +20 -0
  17. package/dist/query/core/api/Api.js +129 -0
  18. package/dist/query/core/api/constants.d.ts +2 -0
  19. package/dist/query/core/api/constants.js +3 -0
  20. package/dist/query/core/api/index.d.ts +3 -0
  21. package/dist/query/core/api/index.js +3 -0
  22. package/dist/query/core/api/mergeHooks.d.ts +2 -0
  23. package/dist/query/core/api/mergeHooks.js +26 -0
  24. package/dist/query/core/api/normalizeLinks.d.ts +2 -0
  25. package/dist/query/core/api/normalizeLinks.js +11 -0
  26. package/dist/query/core/cache/CacheEntry.d.ts +21 -0
  27. package/dist/query/core/cache/CacheEntry.js +54 -0
  28. package/dist/query/core/cache/CacheMap.d.ts +19 -0
  29. package/dist/query/core/cache/CacheMap.js +32 -0
  30. package/dist/query/core/cache/QueryCacheEntry.d.ts +21 -0
  31. package/dist/query/core/cache/QueryCacheEntry.js +136 -0
  32. package/dist/query/core/cache/index.d.ts +3 -0
  33. package/dist/query/core/cache/index.js +3 -0
  34. package/dist/query/core/command/Command.d.ts +67 -0
  35. package/dist/query/core/command/Command.js +253 -0
  36. package/dist/query/core/command/CommandAgent.d.ts +17 -0
  37. package/dist/query/core/command/CommandAgent.js +67 -0
  38. package/dist/query/core/command/LinkManager.d.ts +24 -0
  39. package/dist/query/core/command/LinkManager.js +71 -0
  40. package/dist/query/core/command/index.d.ts +2 -0
  41. package/dist/query/core/command/index.js +2 -0
  42. package/dist/query/core/errors/CacheEntryRemovedError.d.ts +7 -0
  43. package/dist/query/core/errors/CacheEntryRemovedError.js +9 -0
  44. package/dist/query/core/errors/MachineStateError.d.ts +8 -0
  45. package/dist/query/core/errors/MachineStateError.js +10 -0
  46. package/dist/query/core/errors/MachineTransitionError.d.ts +7 -0
  47. package/dist/query/core/errors/MachineTransitionError.js +9 -0
  48. package/dist/query/core/errors/index.d.ts +3 -0
  49. package/dist/query/core/errors/index.js +3 -0
  50. package/dist/query/core/index.d.ts +8 -0
  51. package/dist/query/core/index.js +8 -0
  52. package/dist/query/core/machine/Machine.d.ts +21 -0
  53. package/dist/query/core/machine/Machine.js +42 -0
  54. package/dist/query/core/machine/MachineBase.d.ts +31 -0
  55. package/dist/query/core/machine/MachineBase.js +176 -0
  56. package/dist/query/core/machine/MachineError.d.ts +10 -0
  57. package/dist/query/core/machine/MachineError.js +19 -0
  58. package/dist/query/core/machine/MachinePending.d.ts +13 -0
  59. package/dist/query/core/machine/MachinePending.js +32 -0
  60. package/dist/query/core/machine/MachineRefreshError.d.ts +12 -0
  61. package/dist/query/core/machine/MachineRefreshError.js +23 -0
  62. package/dist/query/core/machine/MachineRefreshing.d.ts +15 -0
  63. package/dist/query/core/machine/MachineRefreshing.js +43 -0
  64. package/dist/query/core/machine/MachineSuccess.d.ts +12 -0
  65. package/dist/query/core/machine/MachineSuccess.js +23 -0
  66. package/dist/query/core/machine/MachineWithData.d.ts +25 -0
  67. package/dist/query/core/machine/MachineWithData.js +73 -0
  68. package/dist/query/core/machine/index.d.ts +9 -0
  69. package/dist/query/core/machine/index.js +9 -0
  70. package/dist/query/core/machine/machine-helpers.d.ts +9 -0
  71. package/dist/query/core/machine/machine-helpers.js +80 -0
  72. package/dist/query/core/patcher/Patcher.d.ts +30 -0
  73. package/dist/query/core/patcher/Patcher.js +122 -0
  74. package/dist/query/core/patcher/index.d.ts +1 -0
  75. package/dist/query/core/patcher/index.js +1 -0
  76. package/dist/query/core/resource/Resource.d.ts +105 -0
  77. package/dist/query/core/resource/Resource.js +340 -0
  78. package/dist/query/core/resource/ResourceAgent.d.ts +37 -0
  79. package/dist/query/core/resource/ResourceAgent.js +179 -0
  80. package/dist/query/core/resource/index.d.ts +2 -0
  81. package/dist/query/core/resource/index.js +2 -0
  82. package/dist/query/core/snapshoter/Snapshoter.d.ts +22 -0
  83. package/dist/query/core/snapshoter/Snapshoter.js +78 -0
  84. package/dist/query/core/snapshoter/index.d.ts +2 -0
  85. package/dist/query/core/snapshoter/index.js +1 -0
  86. package/dist/query/core/syncer/Syncer.d.ts +32 -0
  87. package/dist/query/core/syncer/Syncer.js +85 -0
  88. package/dist/query/core/syncer/index.d.ts +2 -0
  89. package/dist/query/core/syncer/index.js +1 -0
  90. package/dist/query/index.d.ts +5 -10
  91. package/dist/query/index.js +5 -13
  92. package/dist/query/lib/broadcastSyncDriver.d.ts +5 -0
  93. package/dist/query/lib/broadcastSyncDriver.js +46 -0
  94. package/dist/query/lib/index.d.ts +3 -0
  95. package/dist/query/lib/index.js +3 -0
  96. package/dist/{query-v2 → query}/lib/stableStringify.js +5 -3
  97. package/dist/query/lib/toKeyed.d.ts +11 -0
  98. package/dist/query/lib/toKeyed.js +18 -0
  99. package/dist/query/react/ReactHooksPlugin.d.ts +31 -0
  100. package/dist/query/react/ReactHooksPlugin.js +21 -0
  101. package/dist/query/react/index.d.ts +3 -0
  102. package/dist/query/react/index.js +3 -0
  103. package/dist/query/react/useCommand.d.ts +2 -0
  104. package/dist/query/react/useCommand.js +14 -0
  105. package/dist/query/react/useResource.d.ts +2 -0
  106. package/dist/query/react/useResource.js +16 -0
  107. package/dist/query/types/api.d.ts +39 -0
  108. package/dist/query/types/cache.d.ts +51 -0
  109. package/dist/query/types/command.d.ts +52 -0
  110. package/dist/query/types/common.d.ts +65 -0
  111. package/dist/query/types/index.d.ts +8 -4
  112. package/dist/query/types/index.js +8 -5
  113. package/dist/query/types/plugin-hkt.d.ts +64 -0
  114. package/dist/query/types/resource.d.ts +49 -0
  115. package/dist/query/types/snapshot.d.ts +27 -0
  116. package/dist/query/types/snapshot.js +2 -0
  117. package/dist/query/types/state.d.ts +24 -0
  118. package/dist/signals/base/ComputeCache.js +1 -1
  119. package/dist/signals/base/Devtools.js +2 -6
  120. package/dist/signals/signals/Computed.d.ts +1 -0
  121. package/dist/signals/signals/Computed.js +5 -1
  122. package/dist/signals/signals/Effect.d.ts +0 -4
  123. package/dist/signals/signals/Effect.js +0 -6
  124. package/dist/signals/signals/LocalState.d.ts +1 -10
  125. package/dist/signals/signals/LocalState.js +0 -12
  126. package/dist/signals/signals/Signal.d.ts +2 -8
  127. package/dist/signals/signals/Signal.js +1 -10
  128. package/dist/signals/signals/State.d.ts +2 -1
  129. package/dist/signals/signals/State.js +9 -0
  130. package/dist/signals/types/SignalOptions.d.ts +0 -2
  131. package/dist/signals/types/normalizeSignalOptions.js +0 -3
  132. package/dist/signals/types/signals.types.d.ts +3 -1
  133. package/docs/CHANGELOG.md +54 -2
  134. package/docs/contributing/release/README.md +2 -8
  135. package/docs/migrations/0.6.0.md +224 -0
  136. package/docs/query/README.md +52 -562
  137. package/docs/query/api/README.md +59 -0
  138. package/docs/query/api/_CacheEntry.md +39 -0
  139. package/docs/query/api/_CacheMap.md +30 -0
  140. package/docs/query/api/_QueryCacheEntry.md +81 -0
  141. package/docs/query/api/command-agent.md +60 -0
  142. package/docs/query/api/command.md +76 -0
  143. package/docs/query/api/resource-agent.md +68 -0
  144. package/docs/query/api/resource.md +77 -0
  145. package/docs/query/concepts/agent.md +70 -0
  146. package/docs/query/concepts/architecture.md +139 -0
  147. package/docs/query/concepts/cache.md +81 -0
  148. package/docs/query/concepts/dataflows.md +473 -0
  149. package/docs/query/concepts/keyed.md +42 -0
  150. package/docs/query/concepts/machine.md +106 -0
  151. package/docs/query/concepts/patching.md +85 -0
  152. package/docs/query/usage/broadcast.md +188 -0
  153. package/docs/query/usage/command.md +203 -0
  154. package/docs/query/usage/lifecycle.md +114 -0
  155. package/docs/query/usage/links.md +125 -0
  156. package/docs/query/usage/plugins.md +96 -0
  157. package/docs/query/usage/resource.md +206 -0
  158. package/docs/query/usage/snapshot.md +80 -0
  159. package/docs/usage/react/README.md +45 -91
  160. package/package.json +5 -7
  161. package/dist/query/SKIP_TOKEN.d.ts +0 -1
  162. package/dist/query/SKIP_TOKEN.js +0 -1
  163. package/dist/query/api/createCommand.d.ts +0 -21
  164. package/dist/query/api/createCommand.js +0 -20
  165. package/dist/query/api/createOperation.d.ts +0 -5
  166. package/dist/query/api/createOperation.js +0 -6
  167. package/dist/query/api/createResource.d.ts +0 -3
  168. package/dist/query/api/createResource.js +0 -2
  169. package/dist/query/api/createResourceDuplicator.d.ts +0 -4
  170. package/dist/query/api/createResourceDuplicator.js +0 -2
  171. package/dist/query/api/resetAllQueriesCache.d.ts +0 -1
  172. package/dist/query/api/resetAllQueriesCache.js +0 -4
  173. package/dist/query/core/Command/Command.d.ts +0 -35
  174. package/dist/query/core/Command/Command.js +0 -210
  175. package/dist/query/core/Command/CommandAgent.d.ts +0 -19
  176. package/dist/query/core/Command/CommandAgent.js +0 -54
  177. package/dist/query/core/Command/index.d.ts +0 -2
  178. package/dist/query/core/Command/index.js +0 -2
  179. package/dist/query/core/Operation/Operation.d.ts +0 -8
  180. package/dist/query/core/Operation/Operation.js +0 -4
  181. package/dist/query/core/Operation/OperationAgent.d.ts +0 -4
  182. package/dist/query/core/Operation/OperationAgent.js +0 -4
  183. package/dist/query/core/QueriesCache.d.ts +0 -9
  184. package/dist/query/core/QueriesCache.js +0 -28
  185. package/dist/query/core/QueriesLifetimeHooks.d.ts +0 -22
  186. package/dist/query/core/QueriesLifetimeHooks.js +0 -86
  187. package/dist/query/core/ResetAllQueriesSignal.d.ts +0 -6
  188. package/dist/query/core/ResetAllQueriesSignal.js +0 -11
  189. package/dist/query/core/Resource/Resource.d.ts +0 -51
  190. package/dist/query/core/Resource/Resource.js +0 -232
  191. package/dist/query/core/Resource/ResourceAgent.d.ts +0 -35
  192. package/dist/query/core/Resource/ResourceAgent.js +0 -110
  193. package/dist/query/core/Resource/ResourceDuplicator.d.ts +0 -73
  194. package/dist/query/core/Resource/ResourceDuplicator.js +0 -227
  195. package/dist/query/core/Resource/ResourceDuplicatorAgent.d.ts +0 -35
  196. package/dist/query/core/Resource/ResourceDuplicatorAgent.js +0 -110
  197. package/dist/query/core/Resource/ResourceRef.d.ts +0 -16
  198. package/dist/query/core/Resource/ResourceRef.js +0 -136
  199. package/dist/query/lib/IndirectMap.d.ts +0 -19
  200. package/dist/query/lib/IndirectMap.js +0 -88
  201. package/dist/query/lib/ReactiveCache.d.ts +0 -62
  202. package/dist/query/lib/ReactiveCache.js +0 -80
  203. package/dist/query/react/useCommandAgent.d.ts +0 -24
  204. package/dist/query/react/useCommandAgent.js +0 -39
  205. package/dist/query/react/useOperationAgent.d.ts +0 -6
  206. package/dist/query/react/useOperationAgent.js +0 -6
  207. package/dist/query/react/useResourceAgent.d.ts +0 -6
  208. package/dist/query/react/useResourceAgent.js +0 -31
  209. package/dist/query/react/useResourceRef.d.ts +0 -5
  210. package/dist/query/react/useResourceRef.js +0 -13
  211. package/dist/query/types/Command.types.d.ts +0 -154
  212. package/dist/query/types/Command.types.js +0 -1
  213. package/dist/query/types/Operation.types.d.ts +0 -13
  214. package/dist/query/types/Operation.types.js +0 -1
  215. package/dist/query/types/Resource.types.d.ts +0 -129
  216. package/dist/query/types/Resource.types.js +0 -1
  217. package/dist/query/types/shared.types.d.ts +0 -26
  218. package/dist/query/types/shared.types.js +0 -1
  219. package/dist/query-v2/api/createApi.d.ts +0 -10
  220. package/dist/query-v2/api/createApi.js +0 -83
  221. package/dist/query-v2/core/common/CacheEntry.d.ts +0 -29
  222. package/dist/query-v2/core/common/CacheEntry.js +0 -71
  223. package/dist/query-v2/core/common/CacheMap.d.ts +0 -38
  224. package/dist/query-v2/core/common/CacheMap.js +0 -127
  225. package/dist/query-v2/core/common/LifecycleHooks.d.ts +0 -22
  226. package/dist/query-v2/core/common/LifecycleHooks.js +0 -104
  227. package/dist/query-v2/core/common/index.d.ts +0 -3
  228. package/dist/query-v2/core/common/index.js +0 -3
  229. package/dist/query-v2/core/index.d.ts +0 -3
  230. package/dist/query-v2/core/index.js +0 -3
  231. package/dist/query-v2/core/machines/Machine.d.ts +0 -14
  232. package/dist/query-v2/core/machines/Machine.js +0 -33
  233. package/dist/query-v2/core/machines/MachineError.d.ts +0 -11
  234. package/dist/query-v2/core/machines/MachineError.js +0 -26
  235. package/dist/query-v2/core/machines/MachineIdle.d.ts +0 -8
  236. package/dist/query-v2/core/machines/MachineIdle.js +0 -19
  237. package/dist/query-v2/core/machines/MachinePending.d.ts +0 -12
  238. package/dist/query-v2/core/machines/MachinePending.js +0 -29
  239. package/dist/query-v2/core/machines/MachineRefreshing.d.ts +0 -14
  240. package/dist/query-v2/core/machines/MachineRefreshing.js +0 -46
  241. package/dist/query-v2/core/machines/MachineSuccess.d.ts +0 -16
  242. package/dist/query-v2/core/machines/MachineSuccess.js +0 -42
  243. package/dist/query-v2/core/machines/MachineWithData.d.ts +0 -18
  244. package/dist/query-v2/core/machines/MachineWithData.js +0 -40
  245. package/dist/query-v2/core/machines/Patcher.d.ts +0 -20
  246. package/dist/query-v2/core/machines/Patcher.js +0 -104
  247. package/dist/query-v2/core/machines/index.d.ts +0 -8
  248. package/dist/query-v2/core/machines/index.js +0 -8
  249. package/dist/query-v2/core/resource/ResourceV2.d.ts +0 -120
  250. package/dist/query-v2/core/resource/ResourceV2.js +0 -464
  251. package/dist/query-v2/core/resource/ResourceV2Agent.d.ts +0 -26
  252. package/dist/query-v2/core/resource/ResourceV2Agent.js +0 -132
  253. package/dist/query-v2/core/resource/index.d.ts +0 -2
  254. package/dist/query-v2/core/resource/index.js +0 -2
  255. package/dist/query-v2/index.d.ts +0 -11
  256. package/dist/query-v2/index.js +0 -17
  257. package/dist/query-v2/lib/NO_VALUE.d.ts +0 -2
  258. package/dist/query-v2/lib/NO_VALUE.js +0 -1
  259. package/dist/query-v2/lib/SKIP_TOKEN.d.ts +0 -2
  260. package/dist/query-v2/lib/SKIP_TOKEN.js +0 -1
  261. package/dist/query-v2/lib/index.d.ts +0 -4
  262. package/dist/query-v2/lib/index.js +0 -3
  263. package/dist/query-v2/plugins/ReactHooksPlugin.d.ts +0 -25
  264. package/dist/query-v2/plugins/ReactHooksPlugin.js +0 -19
  265. package/dist/query-v2/plugins/types.d.ts +0 -1
  266. package/dist/query-v2/react/__tests__/helpers.d.ts +0 -12
  267. package/dist/query-v2/react/__tests__/helpers.js +0 -33
  268. package/dist/query-v2/react/index.d.ts +0 -2
  269. package/dist/query-v2/react/index.js +0 -2
  270. package/dist/query-v2/react/useResourceV2Agent.d.ts +0 -12
  271. package/dist/query-v2/react/useResourceV2Agent.js +0 -36
  272. package/dist/query-v2/react/useResourceV2Ref.d.ts +0 -12
  273. package/dist/query-v2/react/useResourceV2Ref.js +0 -57
  274. package/dist/query-v2/snapshot/Snapshot.d.ts +0 -13
  275. package/dist/query-v2/snapshot/Snapshot.js +0 -76
  276. package/dist/query-v2/types/agent.types.d.ts +0 -54
  277. package/dist/query-v2/types/api.types.d.ts +0 -22
  278. package/dist/query-v2/types/cache.types.d.ts +0 -37
  279. package/dist/query-v2/types/index.d.ts +0 -9
  280. package/dist/query-v2/types/index.js +0 -9
  281. package/dist/query-v2/types/lifecycle.types.d.ts +0 -25
  282. package/dist/query-v2/types/machine.types.d.ts +0 -67
  283. package/dist/query-v2/types/plugin.types.d.ts +0 -38
  284. package/dist/query-v2/types/resource.types.d.ts +0 -35
  285. package/dist/query-v2/types/resource.types.js +0 -1
  286. package/dist/query-v2/types/shared.types.d.ts +0 -20
  287. package/dist/query-v2/types/shared.types.js +0 -1
  288. package/dist/query-v2/types/snapshot.types.d.ts +0 -21
  289. package/dist/query-v2/types/snapshot.types.js +0 -1
  290. package/docs/contributing/query-v2/README.md +0 -379
  291. package/docs/migrations/query-v2.md +0 -171
  292. package/docs/query-v2/README.md +0 -280
  293. package/docs/query-v2/api-reference.md +0 -235
  294. package/docs/query-v2/optimistic-updates.md +0 -148
  295. package/docs/query-v2/ssr.md +0 -130
  296. /package/dist/{query-v2 → query}/lib/stableStringify.d.ts +0 -0
  297. /package/dist/{query-v2/plugins/types.js → query/types/api.js} +0 -0
  298. /package/dist/{query-v2/types/agent.types.js → query/types/cache.js} +0 -0
  299. /package/dist/{query-v2/types/api.types.js → query/types/command.js} +0 -0
  300. /package/dist/{query-v2/types/cache.types.js → query/types/common.js} +0 -0
  301. /package/dist/{query-v2/types/lifecycle.types.js → query/types/plugin-hkt.js} +0 -0
  302. /package/dist/{query-v2/types/machine.types.js → query/types/resource.js} +0 -0
  303. /package/dist/{query-v2/types/plugin.types.js → query/types/state.js} +0 -0
@@ -0,0 +1,64 @@
1
+ import type { IPlugin } from "./api";
2
+ /**
3
+ * Base Higher-Kinded Type for plugin resource augmentation.
4
+ *
5
+ * Plugin authors extend this and override `resourceType` / `commandType`
6
+ * using `this['_TArgs']` and `this['_TData']` to refer to the resource's
7
+ * type parameters.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * interface MyPluginHKT extends PluginHKT {
12
+ * readonly resourceType: { myHook: (args: this['_TArgs']) => this['_TData'] };
13
+ * }
14
+ * ```
15
+ */
16
+ export interface PluginHKT {
17
+ /** @phantom — substituted with the resource/command TArgs at application site */
18
+ readonly _TArgs: unknown;
19
+ /** @phantom — substituted with the resource/command TData at application site */
20
+ readonly _TData: unknown;
21
+ /** Override in subinterfaces to declare resource augmentation shape. */
22
+ readonly resourceType: {};
23
+ /** Override in subinterfaces to declare command augmentation shape. */
24
+ readonly commandType: {};
25
+ }
26
+ /**
27
+ * "Apply" a PluginHKT — substitute TArgs/TData and extract the resource augmentation type.
28
+ *
29
+ * Mechanism: intersect the HKT interface with concrete `{ _TArgs: TArgs; _TData: TData }`.
30
+ * Because `resourceType` references `this['_TArgs']`/`this['_TData']`, and `this` in the
31
+ * intersection resolves to the merged type, the phantom parameters become concrete.
32
+ */
33
+ type ApplyPluginResourceHKT<F extends PluginHKT, TArgs, TData> = (F & {
34
+ readonly _TArgs: TArgs;
35
+ readonly _TData: TData;
36
+ })["resourceType"];
37
+ type ApplyPluginCommandHKT<F extends PluginHKT, TArgs, TData> = (F & {
38
+ readonly _TArgs: TArgs;
39
+ readonly _TData: TData;
40
+ })["commandType"];
41
+ /**
42
+ * Extract and apply the resource augmentation from a single plugin type.
43
+ * Returns `{}` if the plugin does not declare an HKT (graceful degradation).
44
+ *
45
+ * Uses bounded `infer H extends PluginHKT` to reject `undefined` from optional `_hkt`.
46
+ */
47
+ type ExtractResourceAugment<P, TArgs, TData> = P extends {
48
+ readonly _hkt: infer H extends PluginHKT;
49
+ } ? ApplyPluginResourceHKT<H, TArgs, TData> : {};
50
+ type ExtractCommandAugment<P, TArgs, TData> = P extends {
51
+ readonly _hkt: infer H extends PluginHKT;
52
+ } ? ApplyPluginCommandHKT<H, TArgs, TData> : {};
53
+ /** Standard union-to-intersection utility. */
54
+ type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
55
+ /**
56
+ * Combine resource augmentations from all plugins in the tuple.
57
+ * Maps each `TPlugins[number]` through `ExtractResourceAugment`, then intersects the results.
58
+ *
59
+ * - `readonly [ReactHooksPlugin, OtherPlugin]` → `{ useResource: ... } & { otherHook: ... }`
60
+ * - `readonly IPlugin[]` (default) → `{}` (no augmentation)
61
+ */
62
+ export type CombinePluginResourceAugments<TPlugins extends readonly IPlugin[], TArgs, TData> = UnionToIntersection<ExtractResourceAugment<TPlugins[number], TArgs, TData>>;
63
+ export type CombinePluginCommandAugments<TPlugins extends readonly IPlugin[], TArgs, TData> = UnionToIntersection<ExtractCommandAugment<TPlugins[number], TArgs, TData>>;
64
+ export type { ApplyPluginResourceHKT, ApplyPluginCommandHKT, ExtractResourceAugment, ExtractCommandAugment, UnionToIntersection, };
@@ -0,0 +1,49 @@
1
+ import type { ArgsOrVoidOrSkip, TResourceSnapshot } from "../../query";
2
+ import type { ReadableSignalFnLike } from "../../signals/types";
3
+ import type { IQueryCacheEntry, TCacheEntryAddedContext, TQueryStartedContext } from "./cache";
4
+ import type { Args, ArgsOrVoid, Keyed } from "./common";
5
+ import type { TResourceAgentState } from "./state";
6
+ export interface IResource<TArgs, TData> {
7
+ trigger(args: Args<TArgs>, doForce?: boolean): void;
8
+ refresh(args: Args<TArgs>): void;
9
+ getEntry(args: ArgsOrVoid<TArgs>, doInitiate?: boolean): IQueryCacheEntry<TArgs, TData> | null;
10
+ getEntry$(args: ArgsOrVoid<TArgs>, doInitiate?: boolean): ReadableSignalFnLike<IQueryCacheEntry<TArgs, TData> | null>;
11
+ getEntries(): IterableIterator<IQueryCacheEntry<TArgs, TData>>;
12
+ createAgent(): IResourceAgent<TArgs, TData>;
13
+ serialize(args: Args<TArgs>): string;
14
+ toKeyed(args: Args<TArgs>): Keyed<TArgs>;
15
+ }
16
+ export interface IResourceAgent<TArgs, TData> {
17
+ state$: ReadableSignalFnLike<TResourceAgentState<TArgs, TData>>;
18
+ start(): void;
19
+ set(args: ArgsOrVoidOrSkip<TArgs>, mark?: boolean): void;
20
+ retry(): void;
21
+ refresh(): void;
22
+ get args(): TArgs | null;
23
+ }
24
+ export interface TResourceOptions<TArgs, TData> {
25
+ queryFn: (args: TArgs, abortSignal: AbortSignal) => Promise<TData>;
26
+ key?: string;
27
+ retentionTime?: number | false;
28
+ serializeArgs?: (args: TArgs) => string;
29
+ onCacheEntryAdded?: (args: TArgs, ctx: TCacheEntryAddedContext<TArgs, TData>) => void;
30
+ onQueryStarted?: (args: TArgs, ctx: TQueryStartedContext<TArgs, TData>) => void | Promise<void>;
31
+ snapshotValidTime?: number | false;
32
+ sync?: boolean;
33
+ getDevtoolsKey?: (args: Keyed<TArgs>) => string;
34
+ }
35
+ export interface IResourceConfig<TArgs, TData> {
36
+ queryFn: (args: TArgs, abortSignal: AbortSignal) => Promise<TData>;
37
+ key?: string;
38
+ retentionTime: number | false;
39
+ serializeArgs: (args: TArgs) => string;
40
+ onCacheEntryAdded?: (args: TArgs, ctx: TCacheEntryAddedContext<TArgs, TData>) => void;
41
+ onQueryStarted?: (args: TArgs, ctx: TQueryStartedContext<TArgs, TData>) => void | Promise<void>;
42
+ getDevtoolsKey?: (args: Keyed<TArgs>) => string;
43
+ /** Pre-populated entries from snapshot hydration (key → snapshot meta). */
44
+ snapshot?: TResourceSnapshot;
45
+ /** Cross-tab sync hook: called before queryFn to check if another tab has cached data. */
46
+ beforeQuery?: (resourceKey: string, entryKey: string) => Promise<{
47
+ data: TData;
48
+ } | null>;
49
+ }
@@ -0,0 +1,27 @@
1
+ export interface TResourceSnapshotEntry {
2
+ status: string;
3
+ args: unknown;
4
+ data: unknown;
5
+ updatedAt: number;
6
+ isStale?: boolean;
7
+ }
8
+ export interface TResourceSnapshot {
9
+ entries: Record<string, TResourceSnapshotEntry>;
10
+ }
11
+ export interface TApiSnapshot {
12
+ version: number;
13
+ keyPrefix: string | null;
14
+ timestamp: number;
15
+ resources: Record<string, TResourceSnapshot>;
16
+ }
17
+ export interface ISyncMessage {
18
+ type: "REQ" | "RES";
19
+ reqId: string;
20
+ keys: [string, string, string];
21
+ data?: unknown;
22
+ }
23
+ export interface ISyncDriver {
24
+ connect(onMessage: (msg: ISyncMessage) => void): void;
25
+ disconnect(): void;
26
+ send(message: ISyncMessage): void;
27
+ }
@@ -0,0 +1,2 @@
1
+ // ==================== Snapshot Types ====================
2
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { TAgentStatus } from "./common";
2
+ export interface TResourceAgentState<TArgs, TData> {
3
+ status: TAgentStatus;
4
+ data: TData | null;
5
+ error: unknown;
6
+ args: TArgs | null;
7
+ isLoading: boolean;
8
+ isInitialLoading: boolean;
9
+ isRefreshing: boolean;
10
+ isRefreshError: boolean;
11
+ isSuccess: boolean;
12
+ isError: boolean;
13
+ retry: () => void;
14
+ refresh: () => void;
15
+ }
16
+ export interface TCommandAgentState<TArgs, TData> {
17
+ status: "idle" | "pending" | "success" | "error";
18
+ data: TData | null;
19
+ error: unknown;
20
+ args: TArgs | null;
21
+ isLoading: boolean;
22
+ isSuccess: boolean;
23
+ isError: boolean;
24
+ }
@@ -1,4 +1,4 @@
1
- import { DependencyTracker } from "../../signals";
1
+ import { DependencyTracker } from "./DependencyTracker";
2
2
  /**
3
3
  * Кеш для хранения вычисленного значения и его зависимостей
4
4
  */
@@ -1,14 +1,13 @@
1
1
  import { SharedOptions } from "../../common/options/SharedOptions";
2
- import { Indexer } from "./Indexer";
3
2
  export const Devtools = {
4
3
  createState(initialValue, optionsDry = {}) {
5
- const options = typeof optionsDry === "string" ? { name: optionsDry } : optionsDry;
4
+ const options = typeof optionsDry === "string" ? { key: optionsDry } : optionsDry;
6
5
  if (options.isDisabled)
7
6
  return null;
8
7
  const createStateDevtools = SharedOptions.DEVTOOLS?.state;
9
8
  if (!createStateDevtools)
10
9
  return null;
11
- const key = createKey(options.key ?? options.name, options.base);
10
+ const key = createKey(options.key, options.base);
12
11
  let stateDevtools = null;
13
12
  const push = (value) => {
14
13
  if (!stateDevtools) {
@@ -36,7 +35,6 @@ export const Devtools = {
36
35
  createSignalHooks(initialValue, options = {}) {
37
36
  const stateDevtools = this.createState(initialValue, {
38
37
  key: options.key,
39
- name: options.name,
40
38
  base: options.base,
41
39
  isDisabled: options.isDisabled,
42
40
  beforeDevtoolsPush: options.beforeDevtoolsPush,
@@ -57,7 +55,6 @@ export const Devtools = {
57
55
  },
58
56
  };
59
57
  function createKey(key, base) {
60
- const i = Indexer.getIndex();
61
58
  let result = "";
62
59
  if (key?.includes("{scope}")) {
63
60
  const scopeName = SharedOptions.getScopeName?.() || "#global";
@@ -69,6 +66,5 @@ function createKey(key, base) {
69
66
  result += key;
70
67
  else if (base && !key)
71
68
  result += `${base}/`;
72
- result += `#i=${i}`;
73
69
  return result;
74
70
  }
@@ -13,6 +13,7 @@ export declare class Computed<T> {
13
13
  peek(): T;
14
14
  private _start;
15
15
  private _stop;
16
+ destroy(): void;
16
17
  private static _EMPTY;
17
18
  static create<T>(computeFn: () => T, options?: SignalOptionsOrKey<T>): ComputeFn<T>;
18
19
  }
@@ -17,7 +17,6 @@ export class Computed {
17
17
  const opts = normalizeSignalOptions(options);
18
18
  const stateOptions = {
19
19
  key: opts.key,
20
- name: opts.name,
21
20
  base: opts.base ?? Computed.name,
22
21
  isDisabled: opts.isDisabled,
23
22
  beforeDevtoolsPush: (value, push) => {
@@ -84,6 +83,10 @@ export class Computed {
84
83
  }
85
84
  this._state$.set(Computed._EMPTY);
86
85
  }
86
+ destroy() {
87
+ this._stop();
88
+ this._computeCache.clear();
89
+ }
87
90
  // === static ===
88
91
  static _EMPTY = Symbol("empty");
89
92
  static create(computeFn, options) {
@@ -94,6 +97,7 @@ export class Computed {
94
97
  computedFn.peek = () => lc.peek();
95
98
  computedFn.get = () => lc.get();
96
99
  computedFn.obs = lc.obs;
100
+ computedFn.destroy = () => lc.destroy();
97
101
  return computedFn;
98
102
  }
99
103
  }
@@ -13,10 +13,6 @@ export declare class Effect implements SubscriptionLike {
13
13
  private _runInTrackedContext;
14
14
  unsubscribe(): void;
15
15
  _getRang(): number;
16
- /**
17
- * @deprecated Use `unsubscribe()` method instead.
18
- */
19
- complete(): void;
20
16
  private _callTeardown;
21
17
  static create(effectFn: EffectFn): Effect;
22
18
  }
@@ -72,12 +72,6 @@ export class Effect {
72
72
  _getRang() {
73
73
  return this._rang;
74
74
  }
75
- /**
76
- * @deprecated Use `unsubscribe()` method instead.
77
- */
78
- complete() {
79
- this.unsubscribe();
80
- }
81
75
  _callTeardown() {
82
76
  if (this._teardown) {
83
77
  this._teardown();
@@ -1,4 +1,3 @@
1
- import { Observable } from "rxjs";
2
1
  import { ZodType } from "zod/v4";
3
2
  import { type SignalOptionsOrKey, type StatefulSignalFn } from "../../signals/types";
4
3
  type StorageLike = {
@@ -10,10 +9,6 @@ type Options<T> = {
10
9
  zodSchema?: ZodType<T>;
11
10
  key: string;
12
11
  userId?: string;
13
- /**
14
- * @deprecated use checkEffect instead
15
- */
16
- validator$?: Observable<(value: T) => boolean>;
17
12
  checkEffect?: (value: T) => boolean;
18
13
  driver?: StorageLike;
19
14
  defaultValue: T;
@@ -23,7 +18,7 @@ export declare class LocalState<T = string | null | number | undefined> {
23
18
  private _state$;
24
19
  private _computed;
25
20
  private readonly _options;
26
- readonly obs: Observable<T>;
21
+ readonly obs: import("rxjs").Observable<T>;
27
22
  private get _driver();
28
23
  constructor(options: Options<T>);
29
24
  set(value: T): void;
@@ -37,8 +32,4 @@ export declare class LocalState<T = string | null | number | undefined> {
37
32
  static DEFAULT_DRIVER: Storage;
38
33
  static create<T = string | null | number | undefined>(options: Options<T>): StatefulSignalFn<T>;
39
34
  }
40
- /**
41
- * @deprecated use LocalState instead
42
- */
43
- export declare const LocalSignal: typeof LocalState;
44
35
  export {};
@@ -1,5 +1,4 @@
1
1
  import { z } from "zod/v4";
2
- import { signalize } from "../operators";
3
2
  import { Computed } from "./Computed";
4
3
  import { State } from "./State";
5
4
  const NONE = Symbol("NONE");
@@ -18,15 +17,8 @@ export class LocalState {
18
17
  initialValue = options.defaultValue;
19
18
  }
20
19
  this._state$ = new State(initialValue, { isDisabled: true });
21
- const validatorSignal$ = options.validator$ && signalize(options.validator$);
22
20
  this._computed = new Computed(() => {
23
21
  const value = this._state$.get();
24
- if (validatorSignal$) {
25
- const validator = validatorSignal$.get();
26
- if (!validator(value)) {
27
- return options.defaultValue;
28
- }
29
- }
30
22
  if (options.checkEffect) {
31
23
  return options.checkEffect(value) ? value : options.defaultValue;
32
24
  }
@@ -116,7 +108,3 @@ export class LocalState {
116
108
  return signalFn;
117
109
  }
118
110
  }
119
- /**
120
- * @deprecated use LocalState instead
121
- */
122
- export const LocalSignal = LocalState;
@@ -1,12 +1,6 @@
1
- import type { SignalOptionsOrKey } from "../../signals/types";
2
- import { SignalFn } from "../../signals/types";
1
+ import type { SignalFn, SignalOptionsOrKey } from "../../signals/types";
3
2
  import { Effect } from "./Effect";
4
- import { State } from "./State";
5
- export declare class Signal<T> extends State<T> {
6
- /** @deprecated use `State` instead */
7
- constructor(initialValue: T, options?: SignalOptionsOrKey<T>);
8
- /** @deprecated use `state` instead */
9
- static create<T>(initialValue: T, options?: SignalOptionsOrKey<T>): SignalFn<T>;
3
+ export declare class Signal {
10
4
  static state<T>(initialValue: T, options?: SignalOptionsOrKey<T>): SignalFn<T>;
11
5
  static compute<T>(computeFn: () => T, options?: SignalOptionsOrKey<T>): import("../../signals/types").ComputeFn<T>;
12
6
  static effect(effectFn: () => void): Effect;
@@ -1,16 +1,7 @@
1
1
  import { Computed } from "./Computed";
2
2
  import { Effect } from "./Effect";
3
3
  import { State } from "./State";
4
- export class Signal extends State {
5
- /** @deprecated use `State` instead */
6
- // eslint-disable-next-line @typescript-eslint/no-useless-constructor
7
- constructor(initialValue, options) {
8
- super(initialValue, options);
9
- }
10
- /** @deprecated use `state` instead */
11
- static create(initialValue, options) {
12
- return this.state(initialValue, options);
13
- }
4
+ export class Signal {
14
5
  static state(initialValue, options) {
15
6
  return State.create(initialValue, options);
16
7
  }
@@ -1,7 +1,7 @@
1
1
  import { BehaviorSubject } from "rxjs";
2
2
  import { SignalFn, SignalOptionsOrKey } from "../../signals/types";
3
3
  export declare class State<T> {
4
- private readonly _hooks;
4
+ private _hooks;
5
5
  private _rang;
6
6
  protected readonly bs$: BehaviorSubject<T>;
7
7
  readonly obs: import("rxjs").Observable<T>;
@@ -9,6 +9,7 @@ export declare class State<T> {
9
9
  peek(): T;
10
10
  set(value: T): void;
11
11
  get(): T;
12
+ complete(): void;
12
13
  private static _finalizationRegistry;
13
14
  static create<T>(initialValue: T, options?: SignalOptionsOrKey<T>): SignalFn<T>;
14
15
  }
@@ -48,6 +48,15 @@ export class State {
48
48
  });
49
49
  return this.bs$.getValue();
50
50
  }
51
+ complete() {
52
+ this.bs$.complete();
53
+ if (this._hooks) {
54
+ for (const hook of this._hooks) {
55
+ hook.onDispose?.();
56
+ }
57
+ this._hooks = null;
58
+ }
59
+ }
51
60
  // === static ===
52
61
  static _finalizationRegistry = new FinalizationRegistry((hooks) => {
53
62
  for (const hook of hooks) {
@@ -6,8 +6,6 @@ export interface SignalLifecycleHook<T = any> {
6
6
  export type TBeforeDevtoolsPushFn<T = any> = (newValue: T, push: (v: T) => void) => void;
7
7
  export interface SignalOptions<T = any> {
8
8
  key?: string;
9
- /** @deprecated use key */
10
- name?: string;
11
9
  base?: string;
12
10
  isDisabled?: boolean;
13
11
  beforeDevtoolsPush?: TBeforeDevtoolsPushFn<T>;
@@ -3,8 +3,5 @@ export function normalizeSignalOptions(options) {
3
3
  return {};
4
4
  if (typeof options === "string")
5
5
  return { key: options };
6
- if (options.name && !options.key) {
7
- return { ...options, key: options.name };
8
- }
9
6
  return options;
10
7
  }
@@ -17,4 +17,6 @@ export interface StatefulSignalFn<T> extends ReadableSignalFnLike<T>, WriteableS
17
17
  }
18
18
  export interface SignalFn<T> extends ReadableSignalFnLike<T>, WriteableSignalLike<T> {
19
19
  }
20
- export type ComputeFn<T> = ReadableSignalFnLike<T>;
20
+ export type ComputeFn<T> = ReadableSignalFnLike<T> & {
21
+ destroy(): void;
22
+ };
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [0.6.2] - 2026-05-17
4
+
5
+ ### Fixed
6
+ - Исправлен вывод типов в `links`
7
+
8
+ ## [0.6.0] - 2026-04-17
9
+
10
+ [Гайд по миграции с 0.5.x](./migrations/0.6.0.md)
11
+
12
+ ### Added
13
+ - `createApi()` — центральная фабрика для создания ресурсов и команд, заменяет standalone-функции
14
+ - Фабричные методы `Machine.pending()`, `Machine.fromSnapshot()`
15
+ - Система плагинов с HKT-типами для типобезопасного расширения
16
+ - SSR-гидрация кеша через опции `initialSnapshot` и `getSnapshot()`
17
+ - Кросс-табовая синхронизация через опции `syncDriver` и `defaultSync`
18
+ - Новые опции `createApi`: `keyPrefix`, `syncDriver`, `defaultSync`, `snapshotValidTime`, `initialSnapshot`, `resourceRetentionTime`, `commandRetentionTime`
19
+ - Статус `isRefreshError` в агентах ресурсов
20
+ - Статус `idle` в агентах (ресурсов и команд)
21
+ - `reactHooksPlugin()` — фабричная функция (альтернатива `new ReactHooksPlugin()`)
22
+
23
+ ### Changed
24
+ - **Полностью переработанный модуль Query** — иммутабельные состояния машины, реактивные кеш-записи, SWR-поведение
25
+ - `Machine` теперь дискриминированное объединение иммутабельных подтипов: `MachinePending`, `MachineSuccess`, `MachineError`, `MachineRefreshing`, `MachineRefreshError`
26
+ - Ресурсы теперь поддерживают реактивные кеш-записи с методами `getEntry$()`, `createAgent()`, `trigger()`, `refresh()`
27
+ - Агенты ресурсов переработаны — SWR-поведение, методы `start`, `set`, `retry`, `refresh`, новый статус `idle`
28
+ - Агенты команд переработаны — методы `trigger`, `setKey`
29
+ - Команды теперь поддерживают оптимистичные обновления, патчи при успехе и инвалидацию связанных ресурсов
30
+ - `link` (callback) переименован в `links` (массив или callback): `optimisticUpdate(draft, args)`, `update(draft, args, result)`, `invalidate` — вместо обёрточного объекта
31
+ - React хуки переписаны: `useResource(resource, args)`, `useCommand(command, key)`
32
+ - Оптимистичные обновления с Immer-патчами и rebase-логикой
33
+
34
+ ### Removed
35
+ - Удалены deprecated-элементы:
36
+ - `api.createOperation()` → используйте `api.createCommand()`
37
+ - `useOperationAgent()` → используйте `useCommand()`
38
+ - Все Operation-типы (`OperationDefinition`, `OperationInstance`, `OperationCreateOptions`, `OperationCreateFn`, `OperationQueryState`, `OperationAgentInstanse`) → удалены (Query модуль полностью переписан, см. [гайд по миграции](./migrations/0.6.0.md))
39
+ - `ResourceRefInstanse` — удалён (используйте `resource.getEntry()` для доступа к кеш-записям)
40
+ - `LocalSignal` → используйте `LocalState`
41
+ - `Signal.create()` — удалён из публичного API (технически доступен через наследование от `State`, но не рекомендуется) → используйте `Signal.state()` / `State.create()`
42
+ - Удалены standalone-функции (заменены методами `createApi()`):
43
+ - `createResource()` → `api.createResource()`
44
+ - `createCommand()` → `api.createCommand()`
45
+ - `createResourceDuplicator()` → удалён без замены
46
+ - `resetAllQueriesCache()` → `api.resetAll()`
47
+ - Удалены и заменены React-хуки:
48
+ - `useCommandAgent()` → используйте `useCommand()`
49
+ - `useResourceAgent()` → используйте `useResource()`
50
+ - `useResourceRef()` → удалён (используйте `resource.getEntry()`)
51
+ - Удалён namespace `unstable_queryV2` — экспериментальный API стал основным
52
+
3
53
  ## [0.5.4] - 2026-03-21
4
54
 
5
55
  ### Fixed
@@ -88,8 +138,10 @@
88
138
  - **BatchStrategy**: настройка стратегии обновлений (`'sync'`, `'microtask'`, `'task'`)
89
139
  - **DefaultOptions**: расширенная конфигурация (`onQueryError`, `getScopeName`)
90
140
 
91
- [0.5.3-rc.2]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.3-rc.1...v0.5.3-rc.2
92
- [0.5.3-rc.1]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.2...v0.5.3-rc.1
141
+ [0.6.2]: https://github.com/fozy-labs/rx-toolkit/compare/v0.6.0...v0.6.2
142
+ [0.6.0]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.4...v0.6.0
143
+ [0.5.4]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.3...v0.5.4
144
+ [0.5.3]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.2...v0.5.3
93
145
  [0.5.2]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.1...v0.5.2
94
146
  [0.5.1]: https://github.com/fozy-labs/rx-toolkit/compare/v0.5.0...v0.5.1
95
147
  [0.5.0]: https://github.com/fozy-labs/rx-toolkit/compare/v0.4.18...v0.5.0
@@ -22,10 +22,7 @@ npm version patch # для патч-версии (0.4.18 -> 0.4.19)
22
22
  npm version minor # для минорной версии (0.4.18 -> 0.5.0)
23
23
  npm version major # для мажорной версии (0.4.18 -> 1.0.0)
24
24
 
25
- # 4. Публикация в npm
26
- npm publish
27
-
28
- # 5. Пуш тегов в репозиторий
25
+ # 4. Пуш тегов в репозиторий
29
26
  git push origin develop --tags
30
27
  ```
31
28
 
@@ -44,10 +41,7 @@ npm run build
44
41
  npm version prerelease --preid=rc
45
42
  # пример: 1.2.0 → 1.2.0-rc.0
46
43
 
47
- # 4. Публикация RC (НЕ latest!)
48
- npm publish --tag rc
49
-
50
- # 5. Пуш тегов
44
+ # 4. Пуш тегов
51
45
  git push origin develop --tags
52
46
  ```
53
47