@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
@@ -1,21 +0,0 @@
1
- /** Full API snapshot for SSR */
2
- export interface TApiSnapshot {
3
- /** Format version (integer counter) */
4
- version: number;
5
- /** keyPrefix of the API instance */
6
- keyPrefix: string | null;
7
- /** Resource snapshots keyed by resource key */
8
- resources: Record<string, TResourceSnapshot>;
9
- }
10
- /** Single resource snapshot */
11
- export interface TResourceSnapshot {
12
- /** Cache entries keyed by serialized args */
13
- entries: Record<string, TResourceV2SnapshotSlice>;
14
- }
15
- /** Single cache entry snapshot */
16
- export interface TResourceV2SnapshotSlice<TData = unknown> {
17
- status: "success";
18
- args: unknown;
19
- data: TData;
20
- updatedAt: number;
21
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,379 +0,0 @@
1
-
2
- # Query v2 RFC
3
-
4
- Цель Query v2 — создать более чистую, предсказуемую и расширяемую архитектуру для загрузки данных и кеширования.
5
-
6
- Для этого мы в экспериментальном виде реализуем "Api" и "ResourceV2".
7
-
8
- ## Motivation
9
-
10
- Есть проблемы, нужно их решить:
11
-
12
- 1. Сложности работы с внутренним API пакета, и его расширением.
13
- 2. Отсутствие надежной системы очистки кеша - текущая не сбрасывает состояние полностью.
14
- 3. Отсутствие возможности группировки разных API (ресурсов и комманд), для передачи им общих настроек, изоляции и одновременной очистки.
15
- 4. Нет поддержки SSR
16
-
17
- ## New package API
18
-
19
- ### createApi
20
-
21
- `createApi` - это новая, никак не зависящая от старых реализаций, функция для создания группы ресурсов (в дальнейшем и операций).
22
-
23
- | Опция | Тип | По умолчанию | Режим | Описание |
24
- |----------------------|------------------------------------------|-------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
25
- | `keyPrefix` | `string` \| `null` \| `undefined` | null | | Префикс для ключей ресурсов |
26
- | `keyStrategy` | `'serialize'` \| `'compare` | `'serialize'` | | Режим хранения и сравнения кеша. `serialize` хранит ключ кеша в виде строки. `compare` это старый способо, когда ключем являлось значние аргументов |
27
- | `serializeArgs` | `TSerializeArgsFn` | `stableStringify` | `'serialize'` | Функция для сериализации аргументов в строку. |
28
- | `compareArg` | `TCompareArgsFn` | `shallowEqual` | `compare` | Функция для сравнения аргументов. |
29
- | `initialSnapshot` | `TApiSnapshot` \| `null` \| `undefined` | null | `'serialize'` | Снимок для инициализации API с набором данных. |
30
- | `cacheLifetime` | `number` | 120_000 | | Время жизни кеша в миллисекундах. После истечения этого времени, кеш будет считаться устаревшим. |
31
- | `plugins` | `TApiPlugin[]` | [] | | Массив плагинов для расширения функциональности API. |
32
- | `maxSnapshotDataAge` | `number` | 5_000 | `'serialize'` | От какого возраста данных в спашноте необходима инвалидация. |
33
- | `doCacheArgs` | `boolean` | false | `serialize` | Кешировать ли результат сериализации аргументов. |
34
-
35
- | Свойство | Тип | Описание |
36
- |-----------------------|----------------------|------------------------------------------------------------------------------------------------|
37
- | `resetAll()` | `() => void` | Метод для сброса всего состояния API. |
38
- | `createResource(...)` | `TCreateResourceFn` | Метод для создания ресурса. Принимает определение ресурса и возвращает экземпляр `ResourceV2`. |
39
- | `getSnapshot()` | `() => TApiSnapshot` | Метод для получения снимка текущего состояния API. |
40
-
41
- ### api.createResource
42
-
43
- `api.createResource` - это метод для создания ресурса (`ResourceV2`).
44
-
45
- | Опция | Тип | По умолчанию | Описание |
46
- |----------------------|--------------------------------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
47
- | `key` | `string` | Обязятелен для `'serialize'` стратегии | Уникальный ключ ресурса. Использует для логирования в девтулс. Если указан, то будет проверятся на уникальнось в рамках api. |
48
- | `queryFn` | `TQueryFn` | Обязателен | Функция для выполнения запроса. Должна возвращать промис. |
49
- | `onCacheEntryAdded` | `TResourceOnCacheEntryAddedFn` | | Хук, который вызывается при добавлении новой записи в кеш. |
50
- | `onQueryStarted` | `TResourceOnQueryStartedFn` | | Хук, который вызывается при запуске запроса. |
51
- | `serializeArgs` | `TSerializeArgsFn` | createApi опция (stableStringify) | Функция для сериализации аргументов в строку. |
52
- | `compareArg` | `TCompareArgsFn` | createApi опция (shallowEqual) | Функция для сравнения аргументов. |
53
- | `cacheLifetime` | `number` | createApi опция (60_000) | Время жизни кеша для этого ресурса в миллисекундах. |
54
- | `beforeDevtoolsPush` | `TBeforeDevtoolsPushFn` | | Хук, который вызывается перед отправкой данных в Devtools. Позволяет модифицировать данные. |
55
- | `maxSnapshotDataAge` | `number` | createApi опция (5_000) | От какого возраста данных в спашноте необходима инвалидация. |
56
- | `doCacheArgs` | `boolean` | createApi опция (false) | Кешировать ли результат сериализации аргументов. |
57
-
58
- | Свойство | Тип | Описание |
59
- |----------------------------|-------------------------------|------------------------------------------------------------------------------------|
60
- | `createAgent()` | `CreateResourceV2AgentFn` | Метод для создания агента ресурса, который позволяет управлять состоянием ресурса. |
61
- | `query(args, doForse)` | `TResourveV2QueryFn` | Метод для выполнения запроса с заданными аргументами. Возвращает промис. |
62
- | `query$(args, doForse)` | `TResourveV2QuerySignalFn` | Метод для получения сигнала состояния запроса с заданными аргументами. |
63
- | `entry(args, doInitiate)` | `TGetResourceV2EntryFn` | Метод для получения объекта кеша. |
64
- | `entry$(args, doInitiate)` | `TGetResourceV2EntrySignalFn` | Метод для получения сигнала объекта кеша. |
65
-
66
-
67
- С react плагином:
68
-
69
- | Свойство | Тип | Описание |
70
- |---------------------|------------------|---------------------------------------------------------------------------------------------------------------------------|
71
- | `useResource(args)` | `TUseResourceV2` | Хук для выполнения запроса с заданными аргументами. Возвращает массив с состоянием запроса и функцией для его обновления. |
72
-
73
-
74
- ### TApiSnapshot
75
-
76
- `TApiSnapshot` - это тип, представляет сериализуемый снимок состояния API,
77
- который может быть использован для инициализации состояния с предопределенным набором данных (например для дегидрации/гидрации).
78
- Для гарантии совместимости содержит в себе текущую версию формата, `keyPrefix` и тип.
79
-
80
- ### TResourveV2QueryFn
81
-
82
- ```ts
83
- type TResourveV2QueryFn = <D extends TResourceV2Definition>(
84
- args: D['queryFnArgs'],
85
- force: boolean
86
- ) => TResourceV2Cache
87
- ```
88
-
89
- ### ICacheEntry
90
- `ICacheEntry` - представляет собой реактивную единицу кеша, хранит Machine.
91
-
92
-
93
- ## Махиники
94
-
95
- ### Machine
96
- `Machine` - это класс, который хранит state и инкапсулирует логику управление state. `Machine` содержит методы для перехода к другим `Machine`.
97
-
98
- ### Patch'es
99
-
100
- `Patch` - это абстрактное представление изменений, которые могут быть применены к данным ресурса.
101
- Патчи позволяют реализовать оптимистичные обновления.
102
- В отличие от некоторых других реализаций, патчи в ResourceV2 (как и в V1), защищены от ряда race conditions, благодаря `originalData`.
103
-
104
- ```
105
- // Все валидные committed - пропускаем и убираем из очереди
106
- // Все aborted - применяем и убираем из очереди
107
- // Все pending - применяем и оставляем в очереди
108
- // Все commited (которые после pending) - применяем, но оставляем в очереди
109
- // Все aborted (которые после pending) - откатываем, но оставляем в очереди
110
- // Если после aborted нет pending - пропускаем и убираем из очереди
111
- // Те после применения всех транзакций, очередь должна начинаться с первой pending транзакции (если есть), включая все, что после неё.
112
- // (Подробнее в коде V1) (у V1 проблема: если race conditions все же происходит, то patch "зависает")
113
- ```
114
-
115
- ## Naming Convention
116
-
117
- - Все interface и type начинаются с `I` или `T`
118
- - Все что непосредственно относится к ResourceV2, должно содежраь в названии `ResourceV2`, чтобы не путать с текущей реализацией.
119
-
120
- ## Примеры
121
-
122
- ### Пример создания API используя публичное API пакета:
123
-
124
- ```ts
125
- const mainApi = createApi({
126
- keyPrefix: 'main',
127
- onQueryError(ctx) {
128
- // ...
129
- }
130
- });
131
-
132
- // ===
133
-
134
- import { mainContracts } from '@/my-shared/contracts';
135
-
136
- const getUserById = mainApi.createResource({
137
- queryFn: mainContracts.fetchUserById,
138
- key: 'getUserById',
139
- });
140
-
141
- ```
142
-
143
-
144
- ### Strong typing
145
-
146
- Важно, сохрнить сильные стороны текущей реализации, в том числе сильную типизацию:
147
-
148
- ```ts
149
- const mainApi = createApi({
150
- plugins: [new ReactHooksPlugin()] // Новое: Модифицируем типы, добавлям хуки в русурс
151
- });
152
-
153
- const getUserById = mainApi.createResource({
154
- queryFn: mainContracts.fetchUserById, // Тип getUserById определится автоматически
155
- });
156
-
157
-
158
- // ===
159
-
160
- const userQuery = getUserById.useResource(userId ?? SKIP) // Типипизция допускает передачу только userId и SKIP
161
- ```
162
-
163
- ### Пример вне фреймворка:
164
-
165
-
166
- ```ts
167
-
168
- // Используем агента
169
- class UserStore {
170
- private getUserByIdAgent = getUserById.createAgent();
171
- selectedUserId$ = Signal.compute(() => this.getUserByIdAgent.state$().args);
172
-
173
- selectedUser$ = Signal.compute(() => this.getUserByIdAgent.state$().data);
174
-
175
- selectUserId(userId: number) {
176
- this.getUserByIdAgent.start(userId);
177
- }
178
- }
179
-
180
-
181
- // Или используем "query select"
182
-
183
- class UserStore {
184
- private getUserByIdAgent = getUserById.createAgent();
185
- selectedUserId$ = Signal.state<number | null>(null);
186
-
187
- selectedUser$ = Signal.compute<User | null>(() => {
188
- if (!this.selectedUserId$()) return null;
189
- return this.getUserByIdAgent.query$(this.selectedUserId$()).data;
190
- });
191
-
192
- selectUserId(userId: number) {
193
- this.selectedUserId$.set(userId);
194
- }
195
- }
196
- ```
197
-
198
- Разница между `start` и `query$`:
199
- 1) `start` устанавливает fresh аргументы, напрямую и возвращает промис
200
- 2) `query$` тоже устанавливает fresh аргументы, но `query$` - это сигнал, он возращает текущее состояние запроса.
201
-
202
- Прямой доступ к ResourceV2 vs agent:
203
- 1) Agent может хранить fresh и stale аргументы.
204
- 2) Agent реализует Stale-While-Revalidate стратегию, позволяя получать не актуальные данные, пока новые загружаются.
205
- 3) Agent предоставляет более удобное API.
206
-
207
-
208
- ### Пример опций createApi
209
-
210
- ```ts
211
- const mainApi = createApi({
212
- keyPrefix: 'main', // Префикс ключа
213
- mode: 'serialize', // Режим хранения хранения и сравнения кеша
214
- serializeFn: (args) => fastJson(args), // Функция сериализации аргументов
215
- onQueryError({ type, payload }) { /*...*/ }, // Хук ошибки
216
- snapshot: JSON.parse(hydrateData.mainApiSnapshot), // Снимок для инициализации API с набором данных
217
- });
218
-
219
- mainApi.resetAll(); // Сбросить все состояние
220
- mainApi.createResource(/*...*/) // Содать ресурс
221
- mainApi.getSnapshot(); // Получить снимок текущего состояния API
222
- ```
223
-
224
-
225
- ## Внутрянка
226
-
227
- ### Как кеш (state machine) типизируется:
228
-
229
- ```ts
230
- type TMachine<ARGS, DATA> =
231
- MachinePanding<ARGS, DATA>
232
- | MachineIdle<ARGS, DATA> //...
233
-
234
- class MachineIdle<ARGS, DATA> {
235
- state: TResourceV2IdleState;
236
-
237
- constructor(state: TResourceV2IdleState) {
238
- this.state = state;
239
- }
240
-
241
- start(args: D['queryFnArgs']) {
242
- return new MachinePending({
243
- status: 'pending',
244
- args,
245
- error: null,
246
- data: null,
247
- updatedAt: null,
248
- });
249
- }
250
-
251
- /* другие методы, которые могут понадобиться для idle состояния */
252
-
253
- static create() {
254
- return new MachineIdle({
255
- status: 'idle',
256
- args: null,
257
- error: null,
258
- data: null,
259
- updatedAt: null,
260
- });
261
- }
262
- }
263
-
264
- class MachinePending<ARGS, DATA> {
265
- state: TResourceV2PendingState;
266
-
267
- constructor(state: TResourceV2PendingState) {
268
- this.state = state;
269
- }
270
-
271
- errorHappened(error: Error) {
272
- return new MachineError({
273
- status: 'error',
274
- args: this.state.args,
275
- error,
276
- data: null,
277
- updatedAt: null,
278
- });
279
- }
280
-
281
- successHappened(data: DATA) {
282
- return new MachineSuccess({
283
- status: 'success',
284
- args: this.state.args,
285
- error: null,
286
- data,
287
- updatedAt: Date.now(),
288
- });
289
- }
290
-
291
- /* другие методы, которые могут понадобиться для pending состояния */
292
-
293
- static create(args: ARGS) {
294
- return new MachinePending({
295
- status: 'pending',
296
- args,
297
- originalData: NO_VALUE,
298
- });
299
- }
300
- }
301
-
302
- // Лучше, чтобы MachineSuccess и MachineRefreshing наследовались от общего класса (чтобы не дублировать код связанный с патчами)
303
- class MachineSuccess<ARGS, DATA> {
304
- state: TResourceV2SuccessState;
305
-
306
- constructor(state: TResourceV2SuccessState) {
307
- this.state = state;
308
- }
309
-
310
- invalidate() {
311
- return new MachineRefreshing({
312
- status: 'refreshing',
313
- args: this.state.args,
314
- data: this.state.data,
315
- updatedAt: this.state.updatedAt,
316
- });
317
- }
318
-
319
- addPatch(patch: TResourceV2Patch) {
320
- const originalData = this.state.originalData === NO_VALUE
321
- ? this.state.data
322
- : this.state.originalData;
323
-
324
- const patches = (this.state.patches ?? []).concat(tr);
325
-
326
- return new MachineSuccess({
327
- status: 'success',
328
- args: this.state.args,
329
- data: Patcher.resolvePatches(originalData, patches),
330
- updatedAt: Date.now(),
331
- originalData,
332
- patches,
333
- });
334
- }
335
-
336
- finishPatch(type: 'commit' | 'abort', patch: TResourceV2Patch) {
337
- const { originalData, patches } = Patcher.finishPatch(
338
- this.state.originalData,
339
- this.state.patches,
340
- type,
341
- patch
342
- );
343
-
344
- const machine = new MachineSuccess({
345
- status: 'success',
346
- args: this.state.args,
347
- data: !!originalData?.length
348
- ? Patcher.resolvePatches(originalData, patches)
349
- : originalData,
350
- updatedAt: Date.now(),
351
- originalData,
352
- patches,
353
- });
354
- }
355
-
356
- createPatch(patchFn: TPatchFn<D['queryFnReturn']>) {
357
- const patch = Patcher.createPatch(patchFn, this.state.data);
358
-
359
- const state = this.addPatch(patch);
360
-
361
- return { state, patch };
362
- }
363
-
364
- /* другие методы, которые могут понадобиться для pending состояния */
365
-
366
- static deploy(snapshotSlice: TResourceV2SnapshotSlice<D>) {
367
- return new MachineSuccess({
368
- status: 'success',
369
- args: snapshotSlice.args,
370
- data: snapshotSlice.data,
371
- updatedAt: snapshotSlice.updatedAt,
372
- });
373
- }
374
-
375
- }
376
-
377
-
378
- // ...
379
- ```
@@ -1,171 +0,0 @@
1
- # Миграция с Query v1 на Query v2
2
-
3
- > ⚠️ Query v2 — **экспериментальный модуль**. v1 продолжает поддерживаться.
4
-
5
- ## Сосуществование v1 и v2
6
-
7
- Оба модуля могут использоваться одновременно в одном приложении без конфликтов. Они полностью изолированы:
8
- - v1: импорты из `@fozy-labs/rx-toolkit` (`createResource`, `createCommand`)
9
- - v2: импорты из `@fozy-labs/rx-toolkit` через namespace `queryV2`
10
-
11
- ```typescript
12
- // v1
13
- import { createResource, useResourceAgent } from '@fozy-labs/rx-toolkit';
14
-
15
- // v2
16
- import { unstable_queryV2 } from '@fozy-labs/rx-toolkit';
17
- const api = unstable_queryV2.createApi({ /* ... */ });
18
- ```
19
-
20
- Кэши v1 и v2 не пересекаются. Можно мигрировать ресурсы по одному.
21
-
22
- ---
23
-
24
- ## Маппинг концепций
25
-
26
- ### createResource → createApi + api.createResource
27
-
28
- ```typescript
29
- // v1
30
- const userResource = createResource({
31
- queryFn: fetchUser,
32
- cacheLifetime: 30000,
33
- devtoolsName: 'user',
34
- });
35
-
36
- // v2
37
- const api = unstable_queryV2.createApi({
38
- plugins: [new unstable_queryV2.ReactHooksPlugin()],
39
- });
40
- const userResource = api.createResource({
41
- key: 'user',
42
- queryFn: fetchUser,
43
- cacheLifetime: 30000,
44
- });
45
- ```
46
-
47
- **Ключевые отличия:**
48
- - Ресурс создаётся через API-инстанс, а не как standalone
49
- - `devtoolsName` заменён на `key` + `beforeDevtoolsPush`
50
- - Общая конфигурация (cacheLifetime, serialization) задаётся на уровне API
51
-
52
- ### Resource → ResourceV2
53
-
54
- | v1 | v2 | Примечание |
55
- |----|----|-----------|
56
- | `createResource(opts)` | `api.createResource(opts)` | Через API-инстанс |
57
- | `queryFn(args, tools)` | `queryFn(args, { abortSignal })` | Та же сигнатура tools |
58
- | `select` | — | Убрано, трансформация вне ресурса |
59
- | `devtoolsName` | `key` + `beforeDevtoolsPush` | Ключ для snapshot и devtools |
60
- | `compareArgsFn` | `compareArg` | Переименовано |
61
-
62
- ### Command → Вне scope v2
63
-
64
- В v2 нет прямого аналога `createCommand`. Мутации реализуются через:
65
- - Прямые вызовы API + `ref.createPatch()` для оптимистичных обновлений
66
- - `ref.invalidate()` для инвалидации после мутации
67
-
68
- ```typescript
69
- // v1: Command с link
70
- const updateUser = createCommand({
71
- queryFn: updateUserApi,
72
- link(add) {
73
- add({
74
- resource: userResource,
75
- forwardArgs: (args) => ({ id: args.id }),
76
- update: ({ draft, args }) => { draft.name = args.name; },
77
- });
78
- },
79
- });
80
-
81
- // v2: Прямой вызов + патч
82
- async function updateUser(id: string, name: string) {
83
- const ref = userResource.useResourceV2Ref({ id });
84
- const patch = ref.createPatch(draft => { draft.name = name; });
85
- try {
86
- await fetch(`/api/users/${id}`, { method: 'PATCH', body: JSON.stringify({ name }) });
87
- patch?.commit();
88
- } catch {
89
- patch?.abort();
90
- }
91
- }
92
- ```
93
-
94
- ### Boolean flags → Machine states
95
-
96
- ```typescript
97
- // v1
98
- if (query.isLoading) { /* ... */ }
99
- if (query.isSuccess) { /* ... */ }
100
- if (query.isError) { /* ... */ }
101
-
102
- // v2 — агент предоставляет те же флаги
103
- if (state.isLoading) { /* ... */ }
104
- if (state.isSuccess) { /* ... */ }
105
- if (state.isError) { /* ... */ }
106
-
107
- // v2 — дополнительно: машина состояний
108
- if (state.status === 'pending') { /* ... */ }
109
- if (state.status === 'refreshing') { /* ... */ }
110
- if (state.isInitialLoading) { /* первая загрузка */ }
111
- if (state.isRefreshing) { /* обновление с данными */ }
112
- ```
113
-
114
- ### useResourceAgent → useResourceV2Agent
115
-
116
- ```typescript
117
- // v1
118
- import { useResourceAgent } from '@fozy-labs/rx-toolkit';
119
- const query = useResourceAgent(userResource, { id: '1' });
120
-
121
- // v2 (через ReactHooksPlugin)
122
- const state = userResource.useResourceV2Agent({ id: '1' });
123
- ```
124
-
125
- **Изменения:**
126
- - Хук вызывается на самом ресурсе (метод, добавленный плагином)
127
- - Не нужен отдельный импорт хука
128
- - Для пропуска запроса используется `SKIP` вместо условного вызова
129
-
130
- ### useResourceRef → useResourceV2Ref
131
-
132
- ```typescript
133
- // v1
134
- import { useResourceRef } from '@fozy-labs/rx-toolkit';
135
- const ref = useResourceRef(userResource, { id: '1' });
136
- ref.patch(draft => { draft.name = 'new'; });
137
-
138
- // v2 (через ReactHooksPlugin)
139
- const ref = userResource.useResourceV2Ref({ id: '1' });
140
- const patch = ref.createPatch(draft => { draft.name = 'new'; });
141
- patch?.commit(); // или patch?.abort();
142
- ```
143
-
144
- **Изменения:**
145
- - `patch()` → `createPatch()` с явным `commit/abort`
146
- - Добавлен `ref.create(data)` для предзаполнения кэша
147
- - `ref.lock()` возвращает `{ unlock }` для разблокировки
148
-
149
- ### resetAllQueriesCache → api.resetAll
150
-
151
- ```typescript
152
- // v1
153
- import { resetAllQueriesCache } from '@fozy-labs/rx-toolkit';
154
- resetAllQueriesCache();
155
-
156
- // v2
157
- api.resetAll();
158
- ```
159
-
160
- ---
161
-
162
- ## Новое в v2
163
-
164
- | Функция | Описание |
165
- |---------|----------|
166
- | **Плагины** | Расширяемая архитектура (`ReactHooksPlugin` и др.) |
167
- | **Machine states** | Типизированные состояния вместо boolean-флагов |
168
- | **SSR Snapshots** | `getSnapshot()` / `initialSnapshot` для серверного рендеринга |
169
- | **API factory** | Единая точка конфигурации |
170
- | **Очередь патчей** | Несколько независимых оптимистичных обновлений |
171
- | **SKIP_TOKEN** | Пропуск запроса с типобезопасностью |