@fozy-labs/rx-toolkit 0.5.3-rc.2 → 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 (196) 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/SharedOptions.d.ts +1 -0
  10. package/dist/common/options/SharedOptions.js +6 -0
  11. package/dist/common/options/index.d.ts +1 -1
  12. package/dist/common/options/index.js +1 -1
  13. package/dist/common/react/index.d.ts +2 -2
  14. package/dist/common/react/index.js +2 -2
  15. package/dist/common/react/useConstant.js +1 -1
  16. package/dist/common/utils/deepEqual.js +1 -1
  17. package/dist/common/utils/index.d.ts +3 -3
  18. package/dist/common/utils/index.js +3 -3
  19. package/dist/common/utils/shallowEqual.js +1 -1
  20. package/dist/index.d.ts +8 -7
  21. package/dist/index.js +8 -7
  22. package/dist/query/SKIP_TOKEN.js +1 -1
  23. package/dist/query/api/createCommand.d.ts +1 -1
  24. package/dist/query/api/createOperation.d.ts +1 -1
  25. package/dist/query/api/createOperation.js +1 -1
  26. package/dist/query/api/createResource.d.ts +1 -1
  27. package/dist/query/api/createResourceDuplicator.d.ts +1 -1
  28. package/dist/query/core/Command/Command.d.ts +7 -7
  29. package/dist/query/core/Command/Command.js +2 -2
  30. package/dist/query/core/Command/CommandAgent.d.ts +1 -1
  31. package/dist/query/core/Command/index.d.ts +2 -2
  32. package/dist/query/core/Command/index.js +2 -2
  33. package/dist/query/core/{Opertation → Operation}/Operation.d.ts +2 -2
  34. package/dist/query/core/{Opertation → Operation}/Operation.js +1 -1
  35. package/dist/query/core/{Opertation → Operation}/OperationAgent.d.ts +1 -1
  36. package/dist/query/core/{Opertation → Operation}/OperationAgent.js +1 -1
  37. package/dist/query/core/QueriesCache.d.ts +1 -1
  38. package/dist/query/core/QueriesCache.js +1 -1
  39. package/dist/query/core/QueriesLifetimeHooks.js +7 -7
  40. package/dist/query/core/Resource/Resource.d.ts +15 -15
  41. package/dist/query/core/Resource/Resource.js +7 -7
  42. package/dist/query/core/Resource/ResourceAgent.d.ts +1 -1
  43. package/dist/query/core/Resource/ResourceAgent.js +2 -2
  44. package/dist/query/core/Resource/ResourceDuplicator.d.ts +16 -16
  45. package/dist/query/core/Resource/ResourceDuplicator.js +18 -20
  46. package/dist/query/core/Resource/ResourceDuplicatorAgent.d.ts +5 -5
  47. package/dist/query/core/Resource/ResourceDuplicatorAgent.js +2 -2
  48. package/dist/query/core/Resource/ResourceRef.d.ts +2 -2
  49. package/dist/query/core/Resource/ResourceRef.js +12 -12
  50. package/dist/query/index.d.ts +11 -10
  51. package/dist/query/index.js +11 -10
  52. package/dist/query/lib/IndirectMap.js +4 -4
  53. package/dist/query/react/useCommandAgent.d.ts +2 -2
  54. package/dist/query/react/useOperationAgent.d.ts +1 -1
  55. package/dist/query/react/useOperationAgent.js +1 -1
  56. package/dist/query/react/useResourceAgent.d.ts +3 -3
  57. package/dist/query/react/useResourceAgent.js +1 -1
  58. package/dist/query/react/useResourceRef.d.ts +3 -3
  59. package/dist/query/react/useResourceRef.js +7 -2
  60. package/dist/query/types/Command.types.d.ts +1 -1
  61. package/dist/query/types/Operation.types.d.ts +1 -1
  62. package/dist/query/types/Resource.types.d.ts +7 -5
  63. package/dist/query/types/index.d.ts +4 -4
  64. package/dist/query/types/index.js +4 -4
  65. package/dist/query-v2/api/createApi.d.ts +10 -0
  66. package/dist/query-v2/api/createApi.js +83 -0
  67. package/dist/query-v2/core/common/CacheEntry.d.ts +29 -0
  68. package/dist/query-v2/core/common/CacheEntry.js +71 -0
  69. package/dist/query-v2/core/common/CacheMap.d.ts +38 -0
  70. package/dist/query-v2/core/common/CacheMap.js +127 -0
  71. package/dist/query-v2/core/common/LifecycleHooks.d.ts +22 -0
  72. package/dist/query-v2/core/common/LifecycleHooks.js +104 -0
  73. package/dist/query-v2/core/common/index.d.ts +3 -0
  74. package/dist/query-v2/core/common/index.js +3 -0
  75. package/dist/query-v2/core/index.d.ts +3 -0
  76. package/dist/query-v2/core/index.js +3 -0
  77. package/dist/query-v2/core/machines/Machine.d.ts +14 -0
  78. package/dist/query-v2/core/machines/Machine.js +33 -0
  79. package/dist/query-v2/core/machines/MachineError.d.ts +11 -0
  80. package/dist/query-v2/core/machines/MachineError.js +26 -0
  81. package/dist/query-v2/core/machines/MachineIdle.d.ts +8 -0
  82. package/dist/query-v2/core/machines/MachineIdle.js +19 -0
  83. package/dist/query-v2/core/machines/MachinePending.d.ts +12 -0
  84. package/dist/query-v2/core/machines/MachinePending.js +29 -0
  85. package/dist/query-v2/core/machines/MachineRefreshing.d.ts +14 -0
  86. package/dist/query-v2/core/machines/MachineRefreshing.js +46 -0
  87. package/dist/query-v2/core/machines/MachineSuccess.d.ts +16 -0
  88. package/dist/query-v2/core/machines/MachineSuccess.js +42 -0
  89. package/dist/query-v2/core/machines/MachineWithData.d.ts +18 -0
  90. package/dist/query-v2/core/machines/MachineWithData.js +40 -0
  91. package/dist/query-v2/core/machines/Patcher.d.ts +20 -0
  92. package/dist/query-v2/core/machines/Patcher.js +104 -0
  93. package/dist/query-v2/core/machines/index.d.ts +8 -0
  94. package/dist/query-v2/core/machines/index.js +8 -0
  95. package/dist/query-v2/core/resource/ResourceV2.d.ts +120 -0
  96. package/dist/query-v2/core/resource/ResourceV2.js +464 -0
  97. package/dist/query-v2/core/resource/ResourceV2Agent.d.ts +26 -0
  98. package/dist/query-v2/core/resource/ResourceV2Agent.js +132 -0
  99. package/dist/query-v2/core/resource/index.d.ts +2 -0
  100. package/dist/query-v2/core/resource/index.js +2 -0
  101. package/dist/query-v2/index.d.ts +11 -0
  102. package/dist/query-v2/index.js +17 -0
  103. package/dist/query-v2/lib/NO_VALUE.d.ts +2 -0
  104. package/dist/query-v2/lib/NO_VALUE.js +1 -0
  105. package/dist/query-v2/lib/SKIP_TOKEN.d.ts +2 -0
  106. package/dist/query-v2/lib/SKIP_TOKEN.js +1 -0
  107. package/dist/query-v2/lib/index.d.ts +4 -0
  108. package/dist/query-v2/lib/index.js +3 -0
  109. package/dist/query-v2/lib/stableStringify.d.ts +8 -0
  110. package/dist/query-v2/lib/stableStringify.js +23 -0
  111. package/dist/query-v2/plugins/ReactHooksPlugin.d.ts +25 -0
  112. package/dist/query-v2/plugins/ReactHooksPlugin.js +19 -0
  113. package/dist/query-v2/plugins/types.d.ts +1 -0
  114. package/dist/query-v2/plugins/types.js +1 -0
  115. package/dist/query-v2/react/__tests__/helpers.d.ts +12 -0
  116. package/dist/query-v2/react/__tests__/helpers.js +33 -0
  117. package/dist/query-v2/react/index.d.ts +2 -0
  118. package/dist/query-v2/react/index.js +2 -0
  119. package/dist/query-v2/react/useResourceV2Agent.d.ts +12 -0
  120. package/dist/query-v2/react/useResourceV2Agent.js +36 -0
  121. package/dist/query-v2/react/useResourceV2Ref.d.ts +12 -0
  122. package/dist/query-v2/react/useResourceV2Ref.js +57 -0
  123. package/dist/query-v2/snapshot/Snapshot.d.ts +13 -0
  124. package/dist/query-v2/snapshot/Snapshot.js +76 -0
  125. package/dist/query-v2/types/agent.types.d.ts +54 -0
  126. package/dist/query-v2/types/agent.types.js +1 -0
  127. package/dist/query-v2/types/api.types.d.ts +22 -0
  128. package/dist/query-v2/types/api.types.js +1 -0
  129. package/dist/query-v2/types/cache.types.d.ts +37 -0
  130. package/dist/query-v2/types/cache.types.js +1 -0
  131. package/dist/query-v2/types/index.d.ts +9 -0
  132. package/dist/query-v2/types/index.js +9 -0
  133. package/dist/query-v2/types/lifecycle.types.d.ts +25 -0
  134. package/dist/query-v2/types/lifecycle.types.js +1 -0
  135. package/dist/query-v2/types/machine.types.d.ts +67 -0
  136. package/dist/query-v2/types/machine.types.js +1 -0
  137. package/dist/query-v2/types/plugin.types.d.ts +38 -0
  138. package/dist/query-v2/types/plugin.types.js +1 -0
  139. package/dist/query-v2/types/resource.types.d.ts +35 -0
  140. package/dist/query-v2/types/resource.types.js +1 -0
  141. package/dist/query-v2/types/shared.types.d.ts +20 -0
  142. package/dist/query-v2/types/shared.types.js +1 -0
  143. package/dist/query-v2/types/snapshot.types.d.ts +21 -0
  144. package/dist/query-v2/types/snapshot.types.js +1 -0
  145. package/dist/signals/base/Batcher.js +9 -5
  146. package/dist/signals/base/ComputeCache.js +3 -3
  147. package/dist/signals/base/DependencyTracker.js +1 -1
  148. package/dist/signals/base/Devtools.d.ts +3 -2
  149. package/dist/signals/base/Devtools.js +54 -27
  150. package/dist/signals/base/Indexer.js +1 -1
  151. package/dist/signals/base/ReadonlySignal.js +1 -1
  152. package/dist/signals/base/SyncObservable.d.ts +1 -2
  153. package/dist/signals/base/SyncObservable.js +2 -5
  154. package/dist/signals/base/index.d.ts +6 -6
  155. package/dist/signals/base/index.js +6 -6
  156. package/dist/signals/index.d.ts +5 -4
  157. package/dist/signals/index.js +5 -4
  158. package/dist/signals/operators/index.d.ts +1 -1
  159. package/dist/signals/operators/index.js +1 -1
  160. package/dist/signals/react/index.d.ts +1 -1
  161. package/dist/signals/react/index.js +1 -1
  162. package/dist/signals/signals/Computed.d.ts +3 -4
  163. package/dist/signals/signals/Computed.js +18 -10
  164. package/dist/signals/signals/Effect.js +2 -1
  165. package/dist/signals/signals/LocalState.d.ts +3 -4
  166. package/dist/signals/signals/LocalState.js +8 -8
  167. package/dist/signals/signals/Signal.d.ts +7 -6
  168. package/dist/signals/signals/Signal.js +4 -1
  169. package/dist/signals/signals/State.d.ts +4 -5
  170. package/dist/signals/signals/State.js +23 -9
  171. package/dist/signals/signals/index.d.ts +5 -5
  172. package/dist/signals/signals/index.js +5 -6
  173. package/dist/signals/types/SignalOptions.d.ts +16 -0
  174. package/dist/signals/types/SignalOptions.js +1 -0
  175. package/dist/signals/types/index.d.ts +3 -1
  176. package/dist/signals/types/index.js +3 -1
  177. package/dist/signals/types/normalizeSignalOptions.d.ts +2 -0
  178. package/dist/signals/types/normalizeSignalOptions.js +10 -0
  179. package/dist/signals/types/signals.types.d.ts +2 -3
  180. package/docs/CHANGELOG.md +111 -90
  181. package/docs/CONTRIBUTING.md +230 -0
  182. package/docs/contributing/ai-assisted-development.md +47 -0
  183. package/docs/contributing/query-v2/README.md +379 -0
  184. package/docs/{release → contributing/release}/README.md +59 -59
  185. package/docs/devtools/README.md +228 -228
  186. package/docs/migrations/0.5.0.md +58 -58
  187. package/docs/migrations/query-v2.md +171 -0
  188. package/docs/options/README.md +92 -92
  189. package/docs/query/README.md +575 -573
  190. package/docs/query-v2/README.md +280 -0
  191. package/docs/query-v2/api-reference.md +235 -0
  192. package/docs/query-v2/optimistic-updates.md +148 -0
  193. package/docs/query-v2/ssr.md +130 -0
  194. package/docs/signals/README.md +300 -300
  195. package/docs/usage/react/README.md +309 -309
  196. package/package.json +86 -63
@@ -1,13 +1,14 @@
1
1
  // Command API
2
- export * from './api/createCommand';
3
- export * from './react/useCommandAgent';
2
+ export * from "./api/createCommand";
3
+ export * from "./react/useCommandAgent";
4
4
  // Resource API
5
- export * from './api/createResource';
6
- export * from './api/createResourceDuplicator';
7
- export * from './api/resetAllQueriesCache';
8
- export * from './SKIP_TOKEN';
9
- export * from './react/useResourceAgent';
10
- export * from './react/useResourceRef';
5
+ export * from "./api/createResource";
6
+ export * from "./api/createResourceDuplicator";
7
+ export * from "./api/resetAllQueriesCache";
8
+ export * from "./SKIP_TOKEN";
9
+ export * from "./types";
10
+ export * from "./react/useResourceAgent";
11
+ export * from "./react/useResourceRef";
11
12
  // Deprecated Operation API (backward compatibility)
12
- export * from './api/createOperation';
13
- export * from './react/useOperationAgent';
13
+ export * from "./api/createOperation";
14
+ export * from "./react/useOperationAgent";
@@ -22,7 +22,7 @@ export class IndirectMap {
22
22
  get(key) {
23
23
  const item = this._map.get(key);
24
24
  if (!item) {
25
- const isObject = typeof key === 'object' && key !== null;
25
+ const isObject = typeof key === "object" && key !== null;
26
26
  if (!isObject) {
27
27
  return undefined;
28
28
  }
@@ -40,7 +40,7 @@ export class IndirectMap {
40
40
  this._map.set(key, value);
41
41
  }
42
42
  else {
43
- const isObject = typeof key === 'object' && key !== null;
43
+ const isObject = typeof key === "object" && key !== null;
44
44
  if (!isObject) {
45
45
  this._map.set(key, value);
46
46
  return;
@@ -61,7 +61,7 @@ export class IndirectMap {
61
61
  * @param key
62
62
  */
63
63
  delete(key) {
64
- const isObject = typeof key === 'object' && key !== null;
64
+ const isObject = typeof key === "object" && key !== null;
65
65
  if (isObject) {
66
66
  const cachedKey = this._getCachedKey(key);
67
67
  if (cachedKey) {
@@ -73,7 +73,7 @@ export class IndirectMap {
73
73
  }
74
74
  has(key) {
75
75
  const has = this._map.has(key);
76
- if (!has && typeof key === 'object' && key !== null) {
76
+ if (!has && typeof key === "object" && key !== null) {
77
77
  const cachedKey = this._getCachedKey(key);
78
78
  if (!cachedKey) {
79
79
  return false;
@@ -1,8 +1,8 @@
1
- import type { Prettify, CommandAgentInstance, CommandDefinition, CommandQueryState } from "../../query/types";
1
+ import type { CommandAgentInstance, CommandDefinition, CommandQueryState, Prettify } from "../../query/types";
2
2
  type WithAgent<D extends CommandDefinition> = {
3
3
  createAgent: () => CommandAgentInstance<D>;
4
4
  };
5
- type TriggerFn<D extends CommandDefinition> = (args: D['Args']) => Promise<D['Data']>;
5
+ type TriggerFn<D extends CommandDefinition> = (args: D["Args"]) => Promise<D["Data"]>;
6
6
  type Result<D extends CommandDefinition> = [TriggerFn<D>, Prettify<CommandQueryState<D>>];
7
7
  /**
8
8
  * React hook для работы с командой (Command).
@@ -1,4 +1,4 @@
1
- import { useCommandAgent } from './useCommandAgent';
1
+ import { useCommandAgent } from "./useCommandAgent";
2
2
  /**
3
3
  * @deprecated Use `useCommandAgent` instead. Will be removed in v0.6.0.
4
4
  * @see useCommandAgent
@@ -1,4 +1,4 @@
1
- import { useCommandAgent } from './useCommandAgent';
1
+ import { useCommandAgent } from "./useCommandAgent";
2
2
  /**
3
3
  * @deprecated Use `useCommandAgent` instead. Will be removed in v0.6.0.
4
4
  * @see useCommandAgent
@@ -1,6 +1,6 @@
1
- import { Prettify, ResourceDefinition, ResourceInstance, ResourceQueryState } from "../../query/types";
2
- import { SKIP } from "../../query/SKIP_TOKEN";
3
1
  import { DuplicatorDefinition, ResourceDuplicator } from "../../query/core/Resource/ResourceDuplicator";
2
+ import { SKIP } from "../../query/SKIP_TOKEN";
3
+ import { Prettify, ResourceDefinition, ResourceInstance, ResourceQueryState } from "../../query/types";
4
4
  type Result<D extends ResourceDefinition> = Prettify<ResourceQueryState<D>>;
5
- export declare function useResourceAgent<D extends ResourceDefinition>(res: ResourceInstance<D> | ResourceDuplicator<DuplicatorDefinition<D>>, ...argss: D['Args'] extends void ? [] | [typeof SKIP] : [D['Args'] | typeof SKIP]): Result<D>;
5
+ export declare function useResourceAgent<D extends ResourceDefinition>(res: ResourceInstance<D> | ResourceDuplicator<DuplicatorDefinition<D>>, ...argss: D["Args"] extends void ? [] | [typeof SKIP] : [D["Args"] | typeof SKIP]): Result<D>;
6
6
  export {};
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { useConstant } from "../../common/react";
3
- import { useSignal } from "../../signals/react";
4
3
  import { SKIP } from "../../query/SKIP_TOKEN";
4
+ import { useSignal } from "../../signals/react";
5
5
  export function useResourceAgent(res, ...argss) {
6
6
  const args = (argss[0] === SKIP ? SKIP : argss[0]);
7
7
  const prevArgsRef = React.useRef(SKIP);
@@ -1,5 +1,5 @@
1
1
  import { SKIP } from "../../query/SKIP_TOKEN";
2
- import type { Prettify, ResourceDefinition, ResourceInstance, ResourceRefInstanse } from "../../query/types";
3
- type Result<D extends ResourceDefinition> = Prettify<ResourceRefInstanse<D>>;
4
- export declare function useResourceRef<D extends ResourceDefinition>(res: ResourceInstance<D>, ...argss: D['Args'] extends void ? [] | [typeof SKIP] : [D['Args'] | typeof SKIP]): Result<D>;
2
+ import type { Prettify, ResourceDefinition, ResourceInstance, ResourceRefInstance } from "../../query/types";
3
+ type Result<D extends ResourceDefinition> = Prettify<ResourceRefInstance<D>>;
4
+ export declare function useResourceRef<D extends ResourceDefinition>(res: ResourceInstance<D>, ...argss: D["Args"] extends void ? [] | [typeof SKIP] : [D["Args"] | typeof SKIP]): Result<D>;
5
5
  export {};
@@ -1,8 +1,13 @@
1
1
  import React from "react";
2
+ import { shallowEqual } from "../../common/utils/shallowEqual";
2
3
  import { SKIP } from "../../query/SKIP_TOKEN";
3
4
  export function useResourceRef(res, ...argss) {
4
5
  const args = (argss[0] === SKIP ? SKIP : argss[0]);
6
+ const stableArgsRef = React.useRef(args);
7
+ if (!shallowEqual(stableArgsRef.current, args)) {
8
+ stableArgsRef.current = args;
9
+ }
5
10
  return React.useMemo(() => {
6
- return res.createRef(args);
7
- }, [args]);
11
+ return res.createRef(stableArgsRef.current);
12
+ }, [stableArgsRef.current]);
8
13
  }
@@ -1,6 +1,6 @@
1
1
  import { ReadableSignalLike } from "../../signals/types";
2
- import { FallbackOnNever, OnCacheEntryAdded, OnQueryStarted } from "./shared.types";
3
2
  import { ResourceDefinition, ResourceInstance } from "./Resource.types";
3
+ import { FallbackOnNever, OnCacheEntryAdded, OnQueryStarted } from "./shared.types";
4
4
  /**
5
5
  * Функция создания команды
6
6
  */
@@ -1,4 +1,4 @@
1
- import { CommandCreateFn, CommandCreateOptions, CommandDefinition, CommandInstance, CommandAgentInstance, CommandQueryState } from './Command.types';
1
+ import { CommandAgentInstance, CommandCreateFn, CommandCreateOptions, CommandDefinition, CommandInstance, CommandQueryState } from "./Command.types";
2
2
  /** @deprecated Use `CommandCreateFn` instead. Will be removed in v0.6.0. */
3
3
  export type OperationCreateFn<ARGS, RESULT, SELECTED = never> = CommandCreateFn<ARGS, RESULT, SELECTED>;
4
4
  /** @deprecated Use `CommandCreateOptions` instead. Will be removed in v0.6.0. */
@@ -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,4 +1,4 @@
1
- export * from './Command.types';
2
- export * from './Resource.types';
3
- export * from './shared.types';
4
- export * from './Operation.types';
1
+ export * from "./Command.types";
2
+ export * from "./Resource.types";
3
+ export * from "./shared.types";
4
+ export * from "./Operation.types";
@@ -1,5 +1,5 @@
1
- export * from './Command.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
4
  // Deprecated Operation types (backward compatibility)
5
- export * from './Operation.types';
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
+ }