@fozy-labs/rx-toolkit 0.5.3-rc.1 → 0.5.3

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 (207) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +143 -137
  3. package/dist/common/devtools/combineDevtools.js +3 -3
  4. package/dist/common/devtools/index.d.ts +3 -3
  5. package/dist/common/devtools/index.js +3 -3
  6. package/dist/common/devtools/reduxDevtools.d.ts +1 -1
  7. package/dist/common/devtools/reduxDevtools.js +17 -17
  8. package/dist/common/devtools/types.d.ts +0 -6
  9. package/dist/common/options/DefaultOptions.d.ts +1 -1
  10. package/dist/common/options/SharedOptions.d.ts +3 -2
  11. package/dist/common/options/SharedOptions.js +6 -0
  12. package/dist/common/options/index.d.ts +1 -1
  13. package/dist/common/options/index.js +1 -1
  14. package/dist/common/react/index.d.ts +2 -2
  15. package/dist/common/react/index.js +2 -2
  16. package/dist/common/react/useConstant.js +1 -1
  17. package/dist/common/utils/deepEqual.js +1 -1
  18. package/dist/common/utils/index.d.ts +3 -3
  19. package/dist/common/utils/index.js +3 -3
  20. package/dist/common/utils/shallowEqual.js +1 -1
  21. package/dist/index.d.ts +8 -7
  22. package/dist/index.js +8 -7
  23. package/dist/query/SKIP_TOKEN.js +1 -1
  24. package/dist/query/api/createCommand.d.ts +21 -0
  25. package/dist/query/api/createCommand.js +20 -0
  26. package/dist/query/api/createOperation.d.ts +5 -3
  27. package/dist/query/api/createOperation.js +6 -2
  28. package/dist/query/api/createResource.d.ts +2 -2
  29. package/dist/query/api/createResourceDuplicator.d.ts +2 -2
  30. package/dist/query/core/Command/Command.d.ts +35 -0
  31. package/dist/query/core/{Opertation/Operation.js → Command/Command.js} +13 -14
  32. package/dist/query/core/Command/CommandAgent.d.ts +19 -0
  33. package/dist/query/core/{Opertation/OperationAgent.js → Command/CommandAgent.js} +13 -13
  34. package/dist/query/core/Command/index.d.ts +2 -0
  35. package/dist/query/core/Command/index.js +2 -0
  36. package/dist/query/core/Operation/Operation.d.ts +8 -0
  37. package/dist/query/core/Operation/Operation.js +4 -0
  38. package/dist/query/core/Operation/OperationAgent.d.ts +4 -0
  39. package/dist/query/core/Operation/OperationAgent.js +4 -0
  40. package/dist/query/core/QueriesCache.d.ts +2 -2
  41. package/dist/query/core/QueriesCache.js +1 -1
  42. package/dist/query/core/QueriesLifetimeHooks.d.ts +1 -1
  43. package/dist/query/core/QueriesLifetimeHooks.js +7 -7
  44. package/dist/query/core/Resource/Resource.d.ts +16 -16
  45. package/dist/query/core/Resource/Resource.js +7 -7
  46. package/dist/query/core/Resource/ResourceAgent.d.ts +2 -2
  47. package/dist/query/core/Resource/ResourceAgent.js +3 -3
  48. package/dist/query/core/Resource/ResourceDuplicator.d.ts +17 -17
  49. package/dist/query/core/Resource/ResourceDuplicator.js +18 -20
  50. package/dist/query/core/Resource/ResourceDuplicatorAgent.d.ts +6 -6
  51. package/dist/query/core/Resource/ResourceDuplicatorAgent.js +3 -3
  52. package/dist/query/core/Resource/ResourceRef.d.ts +2 -2
  53. package/dist/query/core/Resource/ResourceRef.js +12 -12
  54. package/dist/query/index.d.ts +11 -8
  55. package/dist/query/index.js +14 -8
  56. package/dist/query/lib/IndirectMap.js +4 -4
  57. package/dist/query/lib/ReactiveCache.d.ts +1 -1
  58. package/dist/query/react/useCommandAgent.d.ts +24 -0
  59. package/dist/query/react/useCommandAgent.js +39 -0
  60. package/dist/query/react/useOperationAgent.d.ts +6 -8
  61. package/dist/query/react/useOperationAgent.js +6 -23
  62. package/dist/query/react/useResourceAgent.d.ts +4 -4
  63. package/dist/query/react/useResourceAgent.js +1 -1
  64. package/dist/query/react/useResourceRef.d.ts +3 -3
  65. package/dist/query/react/useResourceRef.js +7 -2
  66. package/dist/query/types/Command.types.d.ts +154 -0
  67. package/dist/query/types/Command.types.js +1 -0
  68. package/dist/query/types/Operation.types.d.ts +13 -154
  69. package/dist/query/types/Resource.types.d.ts +7 -5
  70. package/dist/query/types/index.d.ts +4 -3
  71. package/dist/query/types/index.js +5 -3
  72. package/dist/query-v2/api/createApi.d.ts +10 -0
  73. package/dist/query-v2/api/createApi.js +83 -0
  74. package/dist/query-v2/core/common/CacheEntry.d.ts +29 -0
  75. package/dist/query-v2/core/common/CacheEntry.js +71 -0
  76. package/dist/query-v2/core/common/CacheMap.d.ts +38 -0
  77. package/dist/query-v2/core/common/CacheMap.js +127 -0
  78. package/dist/query-v2/core/common/LifecycleHooks.d.ts +22 -0
  79. package/dist/query-v2/core/common/LifecycleHooks.js +104 -0
  80. package/dist/query-v2/core/common/index.d.ts +3 -0
  81. package/dist/query-v2/core/common/index.js +3 -0
  82. package/dist/query-v2/core/index.d.ts +3 -0
  83. package/dist/query-v2/core/index.js +3 -0
  84. package/dist/query-v2/core/machines/Machine.d.ts +14 -0
  85. package/dist/query-v2/core/machines/Machine.js +33 -0
  86. package/dist/query-v2/core/machines/MachineError.d.ts +11 -0
  87. package/dist/query-v2/core/machines/MachineError.js +26 -0
  88. package/dist/query-v2/core/machines/MachineIdle.d.ts +8 -0
  89. package/dist/query-v2/core/machines/MachineIdle.js +19 -0
  90. package/dist/query-v2/core/machines/MachinePending.d.ts +12 -0
  91. package/dist/query-v2/core/machines/MachinePending.js +29 -0
  92. package/dist/query-v2/core/machines/MachineRefreshing.d.ts +14 -0
  93. package/dist/query-v2/core/machines/MachineRefreshing.js +46 -0
  94. package/dist/query-v2/core/machines/MachineSuccess.d.ts +16 -0
  95. package/dist/query-v2/core/machines/MachineSuccess.js +42 -0
  96. package/dist/query-v2/core/machines/MachineWithData.d.ts +18 -0
  97. package/dist/query-v2/core/machines/MachineWithData.js +40 -0
  98. package/dist/query-v2/core/machines/Patcher.d.ts +20 -0
  99. package/dist/query-v2/core/machines/Patcher.js +104 -0
  100. package/dist/query-v2/core/machines/index.d.ts +8 -0
  101. package/dist/query-v2/core/machines/index.js +8 -0
  102. package/dist/query-v2/core/resource/ResourceV2.d.ts +120 -0
  103. package/dist/query-v2/core/resource/ResourceV2.js +464 -0
  104. package/dist/query-v2/core/resource/ResourceV2Agent.d.ts +26 -0
  105. package/dist/query-v2/core/resource/ResourceV2Agent.js +132 -0
  106. package/dist/query-v2/core/resource/index.d.ts +2 -0
  107. package/dist/query-v2/core/resource/index.js +2 -0
  108. package/dist/query-v2/index.d.ts +11 -0
  109. package/dist/query-v2/index.js +17 -0
  110. package/dist/query-v2/lib/NO_VALUE.d.ts +2 -0
  111. package/dist/query-v2/lib/NO_VALUE.js +1 -0
  112. package/dist/query-v2/lib/SKIP_TOKEN.d.ts +2 -0
  113. package/dist/query-v2/lib/SKIP_TOKEN.js +1 -0
  114. package/dist/query-v2/lib/index.d.ts +4 -0
  115. package/dist/query-v2/lib/index.js +3 -0
  116. package/dist/query-v2/lib/stableStringify.d.ts +8 -0
  117. package/dist/query-v2/lib/stableStringify.js +23 -0
  118. package/dist/query-v2/plugins/ReactHooksPlugin.d.ts +25 -0
  119. package/dist/query-v2/plugins/ReactHooksPlugin.js +19 -0
  120. package/dist/query-v2/plugins/types.d.ts +1 -0
  121. package/dist/query-v2/plugins/types.js +1 -0
  122. package/dist/query-v2/react/__tests__/helpers.d.ts +12 -0
  123. package/dist/query-v2/react/__tests__/helpers.js +33 -0
  124. package/dist/query-v2/react/index.d.ts +2 -0
  125. package/dist/query-v2/react/index.js +2 -0
  126. package/dist/query-v2/react/useResourceV2Agent.d.ts +12 -0
  127. package/dist/query-v2/react/useResourceV2Agent.js +36 -0
  128. package/dist/query-v2/react/useResourceV2Ref.d.ts +12 -0
  129. package/dist/query-v2/react/useResourceV2Ref.js +57 -0
  130. package/dist/query-v2/snapshot/Snapshot.d.ts +13 -0
  131. package/dist/query-v2/snapshot/Snapshot.js +76 -0
  132. package/dist/query-v2/types/agent.types.d.ts +54 -0
  133. package/dist/query-v2/types/agent.types.js +1 -0
  134. package/dist/query-v2/types/api.types.d.ts +22 -0
  135. package/dist/query-v2/types/api.types.js +1 -0
  136. package/dist/query-v2/types/cache.types.d.ts +37 -0
  137. package/dist/query-v2/types/cache.types.js +1 -0
  138. package/dist/query-v2/types/index.d.ts +9 -0
  139. package/dist/query-v2/types/index.js +9 -0
  140. package/dist/query-v2/types/lifecycle.types.d.ts +25 -0
  141. package/dist/query-v2/types/lifecycle.types.js +1 -0
  142. package/dist/query-v2/types/machine.types.d.ts +67 -0
  143. package/dist/query-v2/types/machine.types.js +1 -0
  144. package/dist/query-v2/types/plugin.types.d.ts +38 -0
  145. package/dist/query-v2/types/plugin.types.js +1 -0
  146. package/dist/query-v2/types/resource.types.d.ts +35 -0
  147. package/dist/query-v2/types/resource.types.js +1 -0
  148. package/dist/query-v2/types/shared.types.d.ts +20 -0
  149. package/dist/query-v2/types/shared.types.js +1 -0
  150. package/dist/query-v2/types/snapshot.types.d.ts +21 -0
  151. package/dist/query-v2/types/snapshot.types.js +1 -0
  152. package/dist/signals/base/Batcher.js +9 -5
  153. package/dist/signals/base/ComputeCache.js +3 -3
  154. package/dist/signals/base/DependencyTracker.js +1 -1
  155. package/dist/signals/base/Devtools.d.ts +3 -2
  156. package/dist/signals/base/Devtools.js +54 -27
  157. package/dist/signals/base/Indexer.js +1 -1
  158. package/dist/signals/base/ReadonlySignal.js +1 -1
  159. package/dist/signals/base/SyncObservable.d.ts +1 -2
  160. package/dist/signals/base/SyncObservable.js +2 -5
  161. package/dist/signals/base/index.d.ts +6 -6
  162. package/dist/signals/base/index.js +6 -6
  163. package/dist/signals/index.d.ts +5 -4
  164. package/dist/signals/index.js +5 -4
  165. package/dist/signals/operators/index.d.ts +1 -1
  166. package/dist/signals/operators/index.js +1 -1
  167. package/dist/signals/operators/signalize.d.ts +1 -1
  168. package/dist/signals/react/index.d.ts +1 -1
  169. package/dist/signals/react/index.js +1 -1
  170. package/dist/signals/signals/Computed.d.ts +3 -4
  171. package/dist/signals/signals/Computed.js +18 -10
  172. package/dist/signals/signals/Effect.js +2 -1
  173. package/dist/signals/signals/LocalState.d.ts +44 -0
  174. package/dist/signals/signals/{LocalSignal.js → LocalState.js} +62 -28
  175. package/dist/signals/signals/Signal.d.ts +8 -7
  176. package/dist/signals/signals/Signal.js +4 -1
  177. package/dist/signals/signals/State.d.ts +4 -5
  178. package/dist/signals/signals/State.js +23 -9
  179. package/dist/signals/signals/index.d.ts +5 -5
  180. package/dist/signals/signals/index.js +5 -6
  181. package/dist/signals/types/SignalOptions.d.ts +16 -0
  182. package/dist/signals/types/SignalOptions.js +1 -0
  183. package/dist/signals/types/index.d.ts +3 -1
  184. package/dist/signals/types/index.js +3 -1
  185. package/dist/signals/types/normalizeSignalOptions.d.ts +2 -0
  186. package/dist/signals/types/normalizeSignalOptions.js +10 -0
  187. package/dist/signals/types/signals.types.d.ts +6 -2
  188. package/docs/CHANGELOG.md +111 -32
  189. package/docs/CONTRIBUTING.md +230 -0
  190. package/docs/contributing/ai-assisted-development.md +47 -0
  191. package/docs/contributing/query-v2/README.md +379 -0
  192. package/docs/{release → contributing/release}/README.md +59 -59
  193. package/docs/devtools/README.md +228 -228
  194. package/docs/migrations/0.5.0.md +58 -58
  195. package/docs/migrations/query-v2.md +171 -0
  196. package/docs/options/README.md +92 -90
  197. package/docs/query/README.md +575 -571
  198. package/docs/query-v2/README.md +280 -0
  199. package/docs/query-v2/api-reference.md +235 -0
  200. package/docs/query-v2/optimistic-updates.md +148 -0
  201. package/docs/query-v2/ssr.md +130 -0
  202. package/docs/signals/README.md +300 -295
  203. package/docs/usage/react/README.md +309 -307
  204. package/package.json +86 -63
  205. package/dist/query/core/Opertation/Operation.d.ts +0 -35
  206. package/dist/query/core/Opertation/OperationAgent.d.ts +0 -19
  207. package/dist/signals/signals/LocalSignal.d.ts +0 -32
@@ -1,154 +1,13 @@
1
- import { ReadableSignalLike } from "../../signals/types";
2
- import { FallbackOnNever, OnCacheEntryAdded, OnQueryStarted } from "./shared.types";
3
- import { ResourceDefinition, ResourceInstance } from "./Resource.types";
4
- /**
5
- * Функция создания операции
6
- */
7
- export type OperationCreateFn<ARGS, RESULT, SELECTED = never> = (options: OperationCreateOptions<OperationDefinition<ARGS, RESULT, SELECTED>>) => OperationInstance<OperationDefinition<ARGS, RESULT, SELECTED>>;
8
- /**
9
- * Опции создания операции
10
- */
11
- export type OperationCreateOptions<D extends OperationDefinition> = {
12
- /** Функция селектора для преобразования результата операции */
13
- select?: (data: D["Result"]) => D["Selected"];
14
- /** Функция выполнения операции */
15
- queryFn: (args: D["Args"]) => Promise<D["Result"]>;
16
- /** Связанные ресурсы */
17
- link?: (link: <RD extends ResourceDefinition>(options: LinkOptions<D, RD>) => void) => void;
18
- /**
19
- * Время жизни кеша в миллисекундах. По умолчанию 1_000 (1 секунда).
20
- * Если указано false - кеш не удаляется автоматически.
21
- */
22
- cacheLifetime?: number | false;
23
- /**
24
- * Хук, вызываемый при добавлении нового элемента в кеш.
25
- * Также позволяет отследить:
26
- * - когда данные были загружены (впервые)
27
- * - когда элемент был удален из кеша
28
- */
29
- onCacheEntryAdded?: OnCacheEntryAdded<D["Args"], D["Data"]>;
30
- /**
31
- * Хук, вызываемый при старте запроса.
32
- * Также позволяет отследить:
33
- * - завершение запроса с результатом или ошибкой
34
- */
35
- onQueryStarted?: OnQueryStarted<D["Args"], D["Result"]>;
36
- /**
37
- * Настройка отображения в devtools
38
- */
39
- devtoolsName?: string | false;
40
- };
41
- /**
42
- * Настройки связи операции с ресурсом
43
- */
44
- export type LinkOptions<D extends OperationDefinition, RD extends ResourceDefinition> = {
45
- /**
46
- * Целевой ресурс, с которым связывается операция
47
- * @required
48
- */
49
- resource: ResourceInstance<RD>;
50
- /**
51
- * Функция для получения аргументов ресурса из аргументов операции.
52
- * Используется для определения какой именно элемент в кэше ресурса нужно обновить
53
- * @required
54
- */
55
- forwardArgs: (args: D["Args"]) => RD["Args"];
56
- /**
57
- * Флаг для инвалидации (очистки) кэша ресурса после выполнения операции.
58
- * При true - кэш будет очищен и ресурс будет перезагружен при следующем обращении
59
- * @optional @default false
60
- */
61
- invalidate?: boolean;
62
- /**
63
- * Флаг для блокировки ресурса во время выполнения операции.
64
- * При true - ресурс будет заблокирован и не сможет выполнять новые запросы
65
- * @optional @default false
66
- */
67
- lock?: boolean;
68
- /**
69
- * Функция для обновления кэша ресурса после успешного выполнения операции.
70
- * Получает draft объект для мутации, аргументы операции и результат операции
71
- * @optional
72
- */
73
- update?: (tools: {
74
- /** Immer draft объект для мутации кэша ресурса */
75
- draft: RD["Data"];
76
- /** Аргументы, с которыми была вызвана операция */
77
- args: D["Args"];
78
- /** Результат выполнения операции */
79
- data: D["Data"];
80
- }) => void | RD["Data"] | Promise<RD["Data"]>;
81
- /**
82
- * Функция для оптимистичного обновления кэша ресурса ДО выполнения операции.
83
- * Позволяет обновить UI немедленно, до получения ответа от сервера
84
- * @optional
85
- */
86
- optimisticUpdate?: (tools: {
87
- /** Immer draft объект для мутации кэша ресурса */
88
- draft: RD["Data"];
89
- /** Аргументы, с которыми была вызвана операция */
90
- args: D["Args"];
91
- }) => void | RD["Data"] | Promise<RD["Data"]>;
92
- /**
93
- * Функция для создания нового элемента в кэше ресурса.
94
- * Используется когда операция создает новую сущность, которую нужно добавить в кэш
95
- * @optional
96
- */
97
- create?: (tools: {
98
- /** Аргументы, с которыми была вызвана операция */
99
- args: D["Args"];
100
- /** Результат выполнения операции */
101
- data: D["Data"];
102
- }) => RD["Data"] | Promise<RD["Data"]>;
103
- };
104
- /**
105
- * Определение типов операции
106
- */
107
- export type OperationDefinition<A = any, R = any, S = any> = {
108
- Args: A;
109
- Result: R;
110
- Selected: S;
111
- Data: FallbackOnNever<S, R>;
112
- };
113
- /**
114
- * Экземпляр операции
115
- */
116
- export type OperationInstance<D extends OperationDefinition> = {
117
- /** Создает агента для выполнения операции */
118
- createAgent(): OperationAgentInstanse<D>;
119
- /**
120
- * Выполняет операцию с указанными аргументами
121
- * @deprecated
122
- */
123
- mutate: (args: D["Args"]) => Promise<D["Data"]>;
124
- };
125
- /**
126
- * Агент для выполнения операции
127
- */
128
- export type OperationAgentInstanse<D extends OperationDefinition> = {
129
- /** Observable состояния выполнения операции */
130
- state$: ReadableSignalLike<OperationQueryState<D>>;
131
- /** Инициирует выполнение операции с указанными аргументами */
132
- initiate(args: D["Args"]): void;
133
- /** Создает новый агент операции */
134
- createAgent(): OperationAgentInstanse<D>;
135
- };
136
- /**
137
- * Состояние выполнения операции
138
- */
139
- export type OperationQueryState<D extends OperationDefinition> = {
140
- /** Выполняется ли операция в данный момент */
141
- isLoading: boolean;
142
- /** Завершена ли операция */
143
- isDone: boolean;
144
- /** Успешно ли завершена операция (false по умолчанию) */
145
- isSuccess: boolean;
146
- /** Произошла ли ошибка при выполнении операции (false по умолчанию) */
147
- isError: boolean;
148
- /** Оригинал ошибки, если есть */
149
- error: unknown | undefined;
150
- /** Результат выполнения операции */
151
- data: D["Data"] | undefined;
152
- /** Аргументы операции */
153
- args: D["Args"];
154
- };
1
+ import { CommandAgentInstance, CommandCreateFn, CommandCreateOptions, CommandDefinition, CommandInstance, CommandQueryState } from "./Command.types";
2
+ /** @deprecated Use `CommandCreateFn` instead. Will be removed in v0.6.0. */
3
+ export type OperationCreateFn<ARGS, RESULT, SELECTED = never> = CommandCreateFn<ARGS, RESULT, SELECTED>;
4
+ /** @deprecated Use `CommandCreateOptions` instead. Will be removed in v0.6.0. */
5
+ export type OperationCreateOptions<D extends CommandDefinition> = CommandCreateOptions<D>;
6
+ /** @deprecated Use `CommandDefinition` instead. Will be removed in v0.6.0. */
7
+ export type OperationDefinition<A = any, R = any, S = any> = CommandDefinition<A, R, S>;
8
+ /** @deprecated Use `CommandInstance` instead. Will be removed in v0.6.0. */
9
+ export type OperationInstance<D extends CommandDefinition> = CommandInstance<D>;
10
+ /** @deprecated Use `CommandAgentInstance` instead. Will be removed in v0.6.0. */
11
+ export type OperationAgentInstanse<D extends CommandDefinition> = CommandAgentInstance<D>;
12
+ /** @deprecated Use `CommandQueryState` instead. Will be removed in v0.6.0. */
13
+ export type OperationQueryState<D extends CommandDefinition> = CommandQueryState<D>;
@@ -61,7 +61,7 @@ export type ResourceInstance<D extends ResourceDefinition> = {
61
61
  /** Создает агента для работы с ресурсом */
62
62
  createAgent(): ResourceAgentInstance<D>;
63
63
  /** Создает ссылку на ресурс с указанными аргументами */
64
- createRef(args: D["Args"]): ResourceRefInstanse<D>;
64
+ createRef(args: D["Args"]): ResourceRefInstance<D>;
65
65
  };
66
66
  /**
67
67
  * Агент для работы с ресурсом
@@ -107,7 +107,7 @@ export type ResourceQueryState<D extends ResourceDefinition> = {
107
107
  export type ResourceTransaction = {
108
108
  patches: ImmerPatch[];
109
109
  inversePatches: ImmerPatch[];
110
- status: 'pending' | 'committed' | 'aborted';
110
+ status: "pending" | "committed" | "aborted";
111
111
  abort(): void;
112
112
  commit(): void;
113
113
  };
@@ -115,13 +115,15 @@ export type ResourceTransaction = {
115
115
  * Эте не ссылка в "классическом" понимании, а абстракция
116
116
  * для работы с элементом кеша ресурса.
117
117
  */
118
- export type ResourceRefInstanse<D extends ResourceDefinition> = {
118
+ export type ResourceRefInstance<D extends ResourceDefinition> = {
119
119
  get has(): boolean;
120
120
  lock(): {
121
121
  unlock: () => void;
122
122
  };
123
123
  unlockOne(): void;
124
- patch(patchFn: (data: D['Data']) => void): ResourceTransaction | null;
124
+ patch(patchFn: (data: D["Data"]) => void): ResourceTransaction | null;
125
125
  invalidate(): void;
126
- create(data: D['Data']): void;
126
+ create(data: D["Data"]): void;
127
127
  };
128
+ /** @deprecated Use ResourceRefInstance. Will be removed in v0.6.0 */
129
+ export type ResourceRefInstanse<D extends ResourceDefinition> = ResourceRefInstance<D>;
@@ -1,3 +1,4 @@
1
- export * from './Operation.types';
2
- export * from './Resource.types';
3
- export * from './shared.types';
1
+ export * from "./Command.types";
2
+ export * from "./Resource.types";
3
+ export * from "./shared.types";
4
+ export * from "./Operation.types";
@@ -1,3 +1,5 @@
1
- export * from './Operation.types';
2
- export * from './Resource.types';
3
- export * from './shared.types';
1
+ export * from "./Command.types";
2
+ export * from "./Resource.types";
3
+ export * from "./shared.types";
4
+ // Deprecated Operation types (backward compatibility)
5
+ export * from "./Operation.types";
@@ -0,0 +1,10 @@
1
+ import type { IApi, ICreateApiOptions } from "../../query-v2/types/api.types";
2
+ import type { IPlugin } from "../../query-v2/types/plugin.types";
3
+ /**
4
+ * Create a query-v2 API instance — the root entry point for managing resources, snapshots, and plugins.
5
+ *
6
+ * @param options - Configuration for the API instance (keyPrefix, plugins, snapshot, cache settings).
7
+ * @returns API instance with `createResource`, `resetAll`, and `getSnapshot` methods.
8
+ * @see docs/query-v2/README.md
9
+ */
10
+ export declare function createApi<TPlugins extends IPlugin[] = []>(options?: ICreateApiOptions<TPlugins>): IApi<TPlugins>;
@@ -0,0 +1,83 @@
1
+ import { ResourceV2 } from "../../query-v2/core/resource/ResourceV2";
2
+ import { getSnapshot, hydrateSnapshot } from "../../query-v2/snapshot/Snapshot";
3
+ const DEFAULT_CACHE_LIFETIME = 60_000;
4
+ const DEFAULT_MAX_SNAPSHOT_DATA_AGE = 300_000; // 5 minutes
5
+ /**
6
+ * Create a query-v2 API instance — the root entry point for managing resources, snapshots, and plugins.
7
+ *
8
+ * @param options - Configuration for the API instance (keyPrefix, plugins, snapshot, cache settings).
9
+ * @returns API instance with `createResource`, `resetAll`, and `getSnapshot` methods.
10
+ * @see docs/query-v2/README.md
11
+ */
12
+ export function createApi(options = {}) {
13
+ const { keyPrefix = null, keyStrategy = "serialize", serializeArgs, compareArg, initialSnapshot = null, cacheLifetime = DEFAULT_CACHE_LIFETIME, plugins = [], maxSnapshotDataAge = DEFAULT_MAX_SNAPSHOT_DATA_AGE, doCacheArgs = false, } = options;
14
+ // ADR-6: Generic registry (Map, not typed to resources only)
15
+ const registry = new Map();
16
+ // Plugin initialization: call install() once per plugin
17
+ const pluginContext = {
18
+ get api() {
19
+ return api;
20
+ },
21
+ keyStrategy,
22
+ };
23
+ for (const plugin of plugins) {
24
+ plugin.install(pluginContext);
25
+ }
26
+ const api = {
27
+ createResource(resourceOptions) {
28
+ // Merge: resource options override API defaults
29
+ const mergedConfig = {
30
+ key: resourceOptions.key,
31
+ keyPrefix: keyPrefix ?? undefined,
32
+ keyStrategy,
33
+ queryFn: resourceOptions.queryFn,
34
+ onCacheEntryAdded: resourceOptions.onCacheEntryAdded,
35
+ onQueryStarted: resourceOptions.onQueryStarted,
36
+ serializeArgs: resourceOptions.serializeArgs ?? serializeArgs,
37
+ compareArg: resourceOptions.compareArg ?? compareArg,
38
+ cacheLifetime: resourceOptions.cacheLifetime ?? cacheLifetime,
39
+ beforeDevtoolsPush: resourceOptions.beforeDevtoolsPush,
40
+ maxSnapshotDataAge: resourceOptions.maxSnapshotDataAge ?? maxSnapshotDataAge,
41
+ doCacheArgs: resourceOptions.doCacheArgs ?? doCacheArgs,
42
+ };
43
+ // Validate unique key (for serialize strategy, key is expected for snapshot)
44
+ const resourceKey = mergedConfig.key;
45
+ if (resourceKey != null) {
46
+ if (registry.has(resourceKey)) {
47
+ throw new Error(`Duplicate resource key "${resourceKey}". Each resource must have a unique key.`);
48
+ }
49
+ }
50
+ // Create resource
51
+ const resource = new ResourceV2(mergedConfig);
52
+ // Apply plugin augmentations
53
+ const augmentations = {};
54
+ for (const plugin of plugins) {
55
+ const pluginContributions = plugin.augmentResource(resource, resourceOptions);
56
+ Object.assign(augmentations, pluginContributions);
57
+ }
58
+ // Create the augmented resource
59
+ const augmentedResource = Object.assign(resource, augmentations);
60
+ // Register resource
61
+ if (resourceKey != null) {
62
+ registry.set(resourceKey, resource);
63
+ }
64
+ // Hydrate from initial snapshot if available
65
+ if (initialSnapshot && resourceKey != null) {
66
+ const snapshotMaxAge = mergedConfig.maxSnapshotDataAge ?? maxSnapshotDataAge;
67
+ const singleResourceRegistry = new Map();
68
+ singleResourceRegistry.set(resourceKey, resource);
69
+ hydrateSnapshot(initialSnapshot, singleResourceRegistry, keyPrefix, snapshotMaxAge);
70
+ }
71
+ return augmentedResource;
72
+ },
73
+ resetAll() {
74
+ for (const [, resource] of registry) {
75
+ resource.resetCache();
76
+ }
77
+ },
78
+ getSnapshot() {
79
+ return getSnapshot(registry, keyPrefix, keyStrategy);
80
+ },
81
+ };
82
+ return api;
83
+ }
@@ -0,0 +1,29 @@
1
+ import type { TBeforeDevtoolsPushFn } from "../../../query-v2/types/shared.types";
2
+ import type { TMachineInstance } from "../machines/Machine";
3
+ export interface CacheEntryOptions {
4
+ keyParts?: string[];
5
+ beforeDevtoolsPush?: TBeforeDevtoolsPushFn<unknown>;
6
+ }
7
+ /**
8
+ * Cache entry wrapping a reactive signal over a state machine instance.
9
+ * Represents a single cached query result with its full lifecycle (idle → pending → success/error).
10
+ */
11
+ export declare class CacheEntry<TData = unknown, TError = Error> {
12
+ private readonly _signal;
13
+ private readonly _onClean$;
14
+ private _completed;
15
+ constructor(initialMachine: TMachineInstance<TData, TError>, options?: CacheEntryOptions);
16
+ /** Reactive accessor for the current machine state — reading this registers a signal dependency. */
17
+ get machine$(): () => TMachineInstance<TData, TError>;
18
+ /** Non-reactive read of the current machine state (does not register a signal dependency). */
19
+ peek(): TMachineInstance<TData, TError>;
20
+ /** Transition to a new machine state. No-op if the entry has been completed. */
21
+ set(machine: TMachineInstance<TData, TError>): void;
22
+ get onClean$(): {
23
+ subscribe: (cb: () => void) => {
24
+ unsubscribe: () => void;
25
+ };
26
+ };
27
+ /** Complete the entry — aborts pending patches, resets to idle, and notifies cleanup listeners. */
28
+ complete(): void;
29
+ }
@@ -0,0 +1,71 @@
1
+ import { Subject } from "rxjs";
2
+ import { Signal } from "../../../signals";
3
+ import { MachineIdle } from "../machines/MachineIdle";
4
+ import { MachineWithData } from "../machines/MachineWithData";
5
+ /**
6
+ * Cache entry wrapping a reactive signal over a state machine instance.
7
+ * Represents a single cached query result with its full lifecycle (idle → pending → success/error).
8
+ */
9
+ export class CacheEntry {
10
+ _signal;
11
+ _onClean$ = new Subject();
12
+ _completed = false;
13
+ constructor(initialMachine, options) {
14
+ const userCallback = options?.beforeDevtoolsPush;
15
+ // Default beforeDevtoolsPush projects machine → machine.state for devtools (ADR-8).
16
+ // The push function types are mismatched intentionally: we push plain state objects
17
+ // instead of machine instances to keep devtools output JSON-friendly.
18
+ const beforeDevtoolsPush = ((newValue, push) => {
19
+ const machine = newValue;
20
+ const state = machine.state;
21
+ if (userCallback) {
22
+ userCallback(state, push);
23
+ }
24
+ else {
25
+ push(state);
26
+ }
27
+ });
28
+ this._signal = Signal.state(initialMachine, {
29
+ key: options?.keyParts?.join("/"),
30
+ beforeDevtoolsPush,
31
+ });
32
+ }
33
+ /** Reactive accessor for the current machine state — reading this registers a signal dependency. */
34
+ get machine$() {
35
+ return this._signal;
36
+ }
37
+ /** Non-reactive read of the current machine state (does not register a signal dependency). */
38
+ peek() {
39
+ return this._signal.peek();
40
+ }
41
+ /** Transition to a new machine state. No-op if the entry has been completed. */
42
+ set(machine) {
43
+ if (this._completed)
44
+ return;
45
+ this._signal.set(machine);
46
+ }
47
+ get onClean$() {
48
+ return {
49
+ subscribe: (cb) => {
50
+ const sub = this._onClean$.subscribe(cb);
51
+ return { unsubscribe: () => sub.unsubscribe() };
52
+ },
53
+ };
54
+ }
55
+ /** Complete the entry — aborts pending patches, resets to idle, and notifies cleanup listeners. */
56
+ complete() {
57
+ if (this._completed)
58
+ return;
59
+ this._completed = true;
60
+ // Layer 3 (ADR-4): Abort all pending patches on MachineWithData instances
61
+ const current = this._signal.peek();
62
+ if (current instanceof MachineWithData) {
63
+ current.abortAllPendingPatches();
64
+ }
65
+ // Set to idle to release data references
66
+ this._signal.set(MachineIdle.create());
67
+ // Notify cleanup listeners
68
+ this._onClean$.next();
69
+ this._onClean$.complete();
70
+ }
71
+ }
@@ -0,0 +1,38 @@
1
+ import type { ICacheMapOptions } from "../../../query-v2/types/cache.types";
2
+ import type { CacheEntry } from "./CacheEntry";
3
+ declare class SerializedCacheMap<TArgs, TData, TError = Error> {
4
+ private readonly _map;
5
+ private readonly _serializeArgs;
6
+ private readonly _argsMemo;
7
+ constructor(serializeArgs: (args: unknown) => string, doCacheArgs: boolean);
8
+ private _serialize;
9
+ get(args: TArgs): CacheEntry<TData, TError> | undefined;
10
+ set(args: TArgs, entry: CacheEntry<TData, TError>): void;
11
+ getOrCreate(args: TArgs, factory: () => CacheEntry<TData, TError>): CacheEntry<TData, TError>;
12
+ delete(args: TArgs): boolean;
13
+ has(args: TArgs): boolean;
14
+ values(): Iterable<CacheEntry<TData, TError>>;
15
+ entries(): Iterable<[string, CacheEntry<TData, TError>]>;
16
+ clear(): void;
17
+ get size(): number;
18
+ }
19
+ declare class CompareCacheMap<TArgs, TData, TError = Error> {
20
+ private readonly _items;
21
+ private readonly _compareArg;
22
+ constructor(compareArg: (a: unknown, b: unknown) => boolean);
23
+ private _findIndex;
24
+ get(args: TArgs): CacheEntry<TData, TError> | undefined;
25
+ set(args: TArgs, entry: CacheEntry<TData, TError>): void;
26
+ getOrCreate(args: TArgs, factory: () => CacheEntry<TData, TError>): CacheEntry<TData, TError>;
27
+ delete(args: TArgs): boolean;
28
+ has(args: TArgs): boolean;
29
+ values(): Iterable<CacheEntry<TData, TError>>;
30
+ entries(): Iterable<[TArgs, CacheEntry<TData, TError>]>;
31
+ clear(): void;
32
+ get size(): number;
33
+ }
34
+ export type TCacheMapInstance<TArgs, TData, TError = Error> = SerializedCacheMap<TArgs, TData, TError> | CompareCacheMap<TArgs, TData, TError>;
35
+ export declare const CacheMap: {
36
+ create<TArgs, TData, TError = Error>(options: ICacheMapOptions<TArgs>): TCacheMapInstance<TArgs, TData, TError>;
37
+ };
38
+ export {};
@@ -0,0 +1,127 @@
1
+ import { shallowEqual } from "../../../common/utils/shallowEqual";
2
+ import { stableStringify } from "../../../query-v2/lib/stableStringify";
3
+ class SerializedCacheMap {
4
+ _map = new Map();
5
+ _serializeArgs;
6
+ _argsMemo;
7
+ constructor(serializeArgs, doCacheArgs) {
8
+ this._serializeArgs = serializeArgs;
9
+ this._argsMemo = doCacheArgs ? new WeakMap() : null;
10
+ }
11
+ _serialize(args) {
12
+ if (this._argsMemo && typeof args === "object" && args !== null) {
13
+ let cached = this._argsMemo.get(args);
14
+ if (cached === undefined) {
15
+ cached = this._serializeArgs(args);
16
+ this._argsMemo.set(args, cached);
17
+ }
18
+ return cached;
19
+ }
20
+ return this._serializeArgs(args);
21
+ }
22
+ get(args) {
23
+ return this._map.get(this._serialize(args));
24
+ }
25
+ set(args, entry) {
26
+ this._map.set(this._serialize(args), entry);
27
+ }
28
+ getOrCreate(args, factory) {
29
+ const key = this._serialize(args);
30
+ let entry = this._map.get(key);
31
+ if (!entry) {
32
+ entry = factory();
33
+ this._map.set(key, entry);
34
+ }
35
+ return entry;
36
+ }
37
+ delete(args) {
38
+ return this._map.delete(this._serialize(args));
39
+ }
40
+ has(args) {
41
+ return this._map.has(this._serialize(args));
42
+ }
43
+ values() {
44
+ return this._map.values();
45
+ }
46
+ entries() {
47
+ return this._map.entries();
48
+ }
49
+ clear() {
50
+ this._map.clear();
51
+ }
52
+ get size() {
53
+ return this._map.size;
54
+ }
55
+ }
56
+ class CompareCacheMap {
57
+ _items = [];
58
+ _compareArg;
59
+ constructor(compareArg) {
60
+ this._compareArg = compareArg;
61
+ }
62
+ _findIndex(args) {
63
+ for (let i = 0; i < this._items.length; i++) {
64
+ if (this._compareArg(this._items[i].args, args)) {
65
+ return i;
66
+ }
67
+ }
68
+ return -1;
69
+ }
70
+ get(args) {
71
+ const idx = this._findIndex(args);
72
+ return idx >= 0 ? this._items[idx].entry : undefined;
73
+ }
74
+ set(args, entry) {
75
+ const idx = this._findIndex(args);
76
+ if (idx >= 0) {
77
+ this._items[idx] = { args, entry };
78
+ }
79
+ else {
80
+ this._items.push({ args, entry });
81
+ }
82
+ }
83
+ getOrCreate(args, factory) {
84
+ const idx = this._findIndex(args);
85
+ if (idx >= 0) {
86
+ return this._items[idx].entry;
87
+ }
88
+ const entry = factory();
89
+ this._items.push({ args, entry });
90
+ return entry;
91
+ }
92
+ delete(args) {
93
+ const idx = this._findIndex(args);
94
+ if (idx >= 0) {
95
+ this._items.splice(idx, 1);
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+ has(args) {
101
+ return this._findIndex(args) >= 0;
102
+ }
103
+ *values() {
104
+ for (const item of this._items) {
105
+ yield item.entry;
106
+ }
107
+ }
108
+ *entries() {
109
+ for (const item of this._items) {
110
+ yield [item.args, item.entry];
111
+ }
112
+ }
113
+ clear() {
114
+ this._items.length = 0;
115
+ }
116
+ get size() {
117
+ return this._items.length;
118
+ }
119
+ }
120
+ export const CacheMap = {
121
+ create(options) {
122
+ if (options.keyStrategy === "compare") {
123
+ return new CompareCacheMap(options.compareArg ?? shallowEqual);
124
+ }
125
+ return new SerializedCacheMap(options.serializeArgs ?? stableStringify, options.doCacheArgs);
126
+ },
127
+ };
@@ -0,0 +1,22 @@
1
+ import type { TOnCacheEntryAdded, TOnQueryStarted } from "../../../query-v2/types/lifecycle.types";
2
+ import type { TMachineInstance } from "../machines/Machine";
3
+ import type { CacheEntry } from "./CacheEntry";
4
+ export declare class LifecycleHooks<TArgs, TData, TError = Error> {
5
+ private readonly _onCacheEntryAdded?;
6
+ private readonly _onQueryStarted?;
7
+ private _cacheEntryState;
8
+ private _queryState;
9
+ private _serializeArgs;
10
+ constructor(options: {
11
+ onCacheEntryAdded?: TOnCacheEntryAdded<TArgs, TData>;
12
+ onQueryStarted?: TOnQueryStarted<TArgs, TData>;
13
+ serializeArgs: (args: unknown) => string;
14
+ });
15
+ fireCacheEntryAdded(args: TArgs, getCacheEntry: () => TMachineInstance<TData, TError>): void;
16
+ fireCacheEntryRemoved(args: TArgs): void;
17
+ resolveCacheDataLoaded(args: TArgs, data: TData): void;
18
+ fireQueryStarted(args: TArgs, getCacheEntry: () => CacheEntry<TData, TError>): void;
19
+ resolveQueryFulfilled(data: TData): void;
20
+ rejectQueryFulfilled(error: unknown): void;
21
+ clearAll(): void;
22
+ }