@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.
- package/LICENSE +1 -1
- package/README.md +22 -13
- package/dist/common/devtools/reduxDevtools.js +17 -2
- package/dist/common/react/index.d.ts +1 -0
- package/dist/common/react/index.js +1 -0
- package/dist/common/react/useIsomorphicLayoutEffect.d.ts +17 -0
- package/dist/common/react/useIsomorphicLayoutEffect.js +17 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/query/api/createApi.d.ts +4 -0
- package/dist/query/api/createApi.js +9 -0
- package/dist/query/api/index.d.ts +1 -0
- package/dist/query/api/index.js +1 -0
- package/dist/query/constants.d.ts +12 -0
- package/dist/query/constants.js +15 -0
- package/dist/query/core/api/Api.d.ts +20 -0
- package/dist/query/core/api/Api.js +129 -0
- package/dist/query/core/api/constants.d.ts +2 -0
- package/dist/query/core/api/constants.js +3 -0
- package/dist/query/core/api/index.d.ts +3 -0
- package/dist/query/core/api/index.js +3 -0
- package/dist/query/core/api/mergeHooks.d.ts +2 -0
- package/dist/query/core/api/mergeHooks.js +26 -0
- package/dist/query/core/api/normalizeLinks.d.ts +2 -0
- package/dist/query/core/api/normalizeLinks.js +11 -0
- package/dist/query/core/cache/CacheEntry.d.ts +21 -0
- package/dist/query/core/cache/CacheEntry.js +54 -0
- package/dist/query/core/cache/CacheMap.d.ts +19 -0
- package/dist/query/core/cache/CacheMap.js +32 -0
- package/dist/query/core/cache/QueryCacheEntry.d.ts +21 -0
- package/dist/query/core/cache/QueryCacheEntry.js +136 -0
- package/dist/query/core/cache/index.d.ts +3 -0
- package/dist/query/core/cache/index.js +3 -0
- package/dist/query/core/command/Command.d.ts +67 -0
- package/dist/query/core/command/Command.js +253 -0
- package/dist/query/core/command/CommandAgent.d.ts +17 -0
- package/dist/query/core/command/CommandAgent.js +67 -0
- package/dist/query/core/command/LinkManager.d.ts +24 -0
- package/dist/query/core/command/LinkManager.js +71 -0
- package/dist/query/core/command/index.d.ts +2 -0
- package/dist/query/core/command/index.js +2 -0
- package/dist/query/core/errors/CacheEntryRemovedError.d.ts +7 -0
- package/dist/query/core/errors/CacheEntryRemovedError.js +9 -0
- package/dist/query/core/errors/MachineStateError.d.ts +8 -0
- package/dist/query/core/errors/MachineStateError.js +10 -0
- package/dist/query/core/errors/MachineTransitionError.d.ts +7 -0
- package/dist/query/core/errors/MachineTransitionError.js +9 -0
- package/dist/query/core/errors/index.d.ts +3 -0
- package/dist/query/core/errors/index.js +3 -0
- package/dist/query/core/index.d.ts +8 -0
- package/dist/query/core/index.js +8 -0
- package/dist/query/core/machine/Machine.d.ts +21 -0
- package/dist/query/core/machine/Machine.js +42 -0
- package/dist/query/core/machine/MachineBase.d.ts +31 -0
- package/dist/query/core/machine/MachineBase.js +176 -0
- package/dist/query/core/machine/MachineError.d.ts +10 -0
- package/dist/query/core/machine/MachineError.js +19 -0
- package/dist/query/core/machine/MachinePending.d.ts +13 -0
- package/dist/query/core/machine/MachinePending.js +32 -0
- package/dist/query/core/machine/MachineRefreshError.d.ts +12 -0
- package/dist/query/core/machine/MachineRefreshError.js +23 -0
- package/dist/query/core/machine/MachineRefreshing.d.ts +15 -0
- package/dist/query/core/machine/MachineRefreshing.js +43 -0
- package/dist/query/core/machine/MachineSuccess.d.ts +12 -0
- package/dist/query/core/machine/MachineSuccess.js +23 -0
- package/dist/query/core/machine/MachineWithData.d.ts +25 -0
- package/dist/query/core/machine/MachineWithData.js +73 -0
- package/dist/query/core/machine/index.d.ts +9 -0
- package/dist/query/core/machine/index.js +9 -0
- package/dist/query/core/machine/machine-helpers.d.ts +9 -0
- package/dist/query/core/machine/machine-helpers.js +80 -0
- package/dist/query/core/patcher/Patcher.d.ts +30 -0
- package/dist/query/core/patcher/Patcher.js +122 -0
- package/dist/query/core/patcher/index.d.ts +1 -0
- package/dist/query/core/patcher/index.js +1 -0
- package/dist/query/core/resource/Resource.d.ts +105 -0
- package/dist/query/core/resource/Resource.js +340 -0
- package/dist/query/core/resource/ResourceAgent.d.ts +37 -0
- package/dist/query/core/resource/ResourceAgent.js +179 -0
- package/dist/query/core/resource/index.d.ts +2 -0
- package/dist/query/core/resource/index.js +2 -0
- package/dist/query/core/snapshoter/Snapshoter.d.ts +22 -0
- package/dist/query/core/snapshoter/Snapshoter.js +78 -0
- package/dist/query/core/snapshoter/index.d.ts +2 -0
- package/dist/query/core/snapshoter/index.js +1 -0
- package/dist/query/core/syncer/Syncer.d.ts +32 -0
- package/dist/query/core/syncer/Syncer.js +85 -0
- package/dist/query/core/syncer/index.d.ts +2 -0
- package/dist/query/core/syncer/index.js +1 -0
- package/dist/query/index.d.ts +5 -10
- package/dist/query/index.js +5 -13
- package/dist/query/lib/broadcastSyncDriver.d.ts +5 -0
- package/dist/query/lib/broadcastSyncDriver.js +46 -0
- package/dist/query/lib/index.d.ts +3 -0
- package/dist/query/lib/index.js +3 -0
- package/dist/{query-v2 → query}/lib/stableStringify.js +5 -3
- package/dist/query/lib/toKeyed.d.ts +11 -0
- package/dist/query/lib/toKeyed.js +18 -0
- package/dist/query/react/ReactHooksPlugin.d.ts +31 -0
- package/dist/query/react/ReactHooksPlugin.js +21 -0
- package/dist/query/react/index.d.ts +3 -0
- package/dist/query/react/index.js +3 -0
- package/dist/query/react/useCommand.d.ts +2 -0
- package/dist/query/react/useCommand.js +14 -0
- package/dist/query/react/useResource.d.ts +2 -0
- package/dist/query/react/useResource.js +16 -0
- package/dist/query/types/api.d.ts +39 -0
- package/dist/query/types/cache.d.ts +51 -0
- package/dist/query/types/command.d.ts +52 -0
- package/dist/query/types/common.d.ts +65 -0
- package/dist/query/types/index.d.ts +8 -4
- package/dist/query/types/index.js +8 -5
- package/dist/query/types/plugin-hkt.d.ts +64 -0
- package/dist/query/types/resource.d.ts +49 -0
- package/dist/query/types/snapshot.d.ts +27 -0
- package/dist/query/types/snapshot.js +2 -0
- package/dist/query/types/state.d.ts +24 -0
- package/dist/signals/base/ComputeCache.js +1 -1
- package/dist/signals/base/Devtools.js +2 -6
- package/dist/signals/signals/Computed.d.ts +1 -0
- package/dist/signals/signals/Computed.js +5 -1
- package/dist/signals/signals/Effect.d.ts +0 -4
- package/dist/signals/signals/Effect.js +0 -6
- package/dist/signals/signals/LocalState.d.ts +1 -10
- package/dist/signals/signals/LocalState.js +0 -12
- package/dist/signals/signals/Signal.d.ts +2 -8
- package/dist/signals/signals/Signal.js +1 -10
- package/dist/signals/signals/State.d.ts +2 -1
- package/dist/signals/signals/State.js +9 -0
- package/dist/signals/types/SignalOptions.d.ts +0 -2
- package/dist/signals/types/normalizeSignalOptions.js +0 -3
- package/dist/signals/types/signals.types.d.ts +3 -1
- package/docs/CHANGELOG.md +54 -2
- package/docs/contributing/release/README.md +2 -8
- package/docs/migrations/0.6.0.md +224 -0
- package/docs/query/README.md +52 -562
- package/docs/query/api/README.md +59 -0
- package/docs/query/api/_CacheEntry.md +39 -0
- package/docs/query/api/_CacheMap.md +30 -0
- package/docs/query/api/_QueryCacheEntry.md +81 -0
- package/docs/query/api/command-agent.md +60 -0
- package/docs/query/api/command.md +76 -0
- package/docs/query/api/resource-agent.md +68 -0
- package/docs/query/api/resource.md +77 -0
- package/docs/query/concepts/agent.md +70 -0
- package/docs/query/concepts/architecture.md +139 -0
- package/docs/query/concepts/cache.md +81 -0
- package/docs/query/concepts/dataflows.md +473 -0
- package/docs/query/concepts/keyed.md +42 -0
- package/docs/query/concepts/machine.md +106 -0
- package/docs/query/concepts/patching.md +85 -0
- package/docs/query/usage/broadcast.md +188 -0
- package/docs/query/usage/command.md +203 -0
- package/docs/query/usage/lifecycle.md +114 -0
- package/docs/query/usage/links.md +125 -0
- package/docs/query/usage/plugins.md +96 -0
- package/docs/query/usage/resource.md +206 -0
- package/docs/query/usage/snapshot.md +80 -0
- package/docs/usage/react/README.md +45 -91
- package/package.json +5 -7
- package/dist/query/SKIP_TOKEN.d.ts +0 -1
- package/dist/query/SKIP_TOKEN.js +0 -1
- package/dist/query/api/createCommand.d.ts +0 -21
- package/dist/query/api/createCommand.js +0 -20
- package/dist/query/api/createOperation.d.ts +0 -5
- package/dist/query/api/createOperation.js +0 -6
- package/dist/query/api/createResource.d.ts +0 -3
- package/dist/query/api/createResource.js +0 -2
- package/dist/query/api/createResourceDuplicator.d.ts +0 -4
- package/dist/query/api/createResourceDuplicator.js +0 -2
- package/dist/query/api/resetAllQueriesCache.d.ts +0 -1
- package/dist/query/api/resetAllQueriesCache.js +0 -4
- package/dist/query/core/Command/Command.d.ts +0 -35
- package/dist/query/core/Command/Command.js +0 -210
- package/dist/query/core/Command/CommandAgent.d.ts +0 -19
- package/dist/query/core/Command/CommandAgent.js +0 -54
- package/dist/query/core/Command/index.d.ts +0 -2
- package/dist/query/core/Command/index.js +0 -2
- package/dist/query/core/Operation/Operation.d.ts +0 -8
- package/dist/query/core/Operation/Operation.js +0 -4
- package/dist/query/core/Operation/OperationAgent.d.ts +0 -4
- package/dist/query/core/Operation/OperationAgent.js +0 -4
- package/dist/query/core/QueriesCache.d.ts +0 -9
- package/dist/query/core/QueriesCache.js +0 -28
- package/dist/query/core/QueriesLifetimeHooks.d.ts +0 -22
- package/dist/query/core/QueriesLifetimeHooks.js +0 -86
- package/dist/query/core/ResetAllQueriesSignal.d.ts +0 -6
- package/dist/query/core/ResetAllQueriesSignal.js +0 -11
- package/dist/query/core/Resource/Resource.d.ts +0 -51
- package/dist/query/core/Resource/Resource.js +0 -232
- package/dist/query/core/Resource/ResourceAgent.d.ts +0 -35
- package/dist/query/core/Resource/ResourceAgent.js +0 -110
- package/dist/query/core/Resource/ResourceDuplicator.d.ts +0 -73
- package/dist/query/core/Resource/ResourceDuplicator.js +0 -227
- package/dist/query/core/Resource/ResourceDuplicatorAgent.d.ts +0 -35
- package/dist/query/core/Resource/ResourceDuplicatorAgent.js +0 -110
- package/dist/query/core/Resource/ResourceRef.d.ts +0 -16
- package/dist/query/core/Resource/ResourceRef.js +0 -136
- package/dist/query/lib/IndirectMap.d.ts +0 -19
- package/dist/query/lib/IndirectMap.js +0 -88
- package/dist/query/lib/ReactiveCache.d.ts +0 -62
- package/dist/query/lib/ReactiveCache.js +0 -80
- package/dist/query/react/useCommandAgent.d.ts +0 -24
- package/dist/query/react/useCommandAgent.js +0 -39
- package/dist/query/react/useOperationAgent.d.ts +0 -6
- package/dist/query/react/useOperationAgent.js +0 -6
- package/dist/query/react/useResourceAgent.d.ts +0 -6
- package/dist/query/react/useResourceAgent.js +0 -31
- package/dist/query/react/useResourceRef.d.ts +0 -5
- package/dist/query/react/useResourceRef.js +0 -13
- package/dist/query/types/Command.types.d.ts +0 -154
- package/dist/query/types/Command.types.js +0 -1
- package/dist/query/types/Operation.types.d.ts +0 -13
- package/dist/query/types/Operation.types.js +0 -1
- package/dist/query/types/Resource.types.d.ts +0 -129
- package/dist/query/types/Resource.types.js +0 -1
- package/dist/query/types/shared.types.d.ts +0 -26
- package/dist/query/types/shared.types.js +0 -1
- package/dist/query-v2/api/createApi.d.ts +0 -10
- package/dist/query-v2/api/createApi.js +0 -83
- package/dist/query-v2/core/common/CacheEntry.d.ts +0 -29
- package/dist/query-v2/core/common/CacheEntry.js +0 -71
- package/dist/query-v2/core/common/CacheMap.d.ts +0 -38
- package/dist/query-v2/core/common/CacheMap.js +0 -127
- package/dist/query-v2/core/common/LifecycleHooks.d.ts +0 -22
- package/dist/query-v2/core/common/LifecycleHooks.js +0 -104
- package/dist/query-v2/core/common/index.d.ts +0 -3
- package/dist/query-v2/core/common/index.js +0 -3
- package/dist/query-v2/core/index.d.ts +0 -3
- package/dist/query-v2/core/index.js +0 -3
- package/dist/query-v2/core/machines/Machine.d.ts +0 -14
- package/dist/query-v2/core/machines/Machine.js +0 -33
- package/dist/query-v2/core/machines/MachineError.d.ts +0 -11
- package/dist/query-v2/core/machines/MachineError.js +0 -26
- package/dist/query-v2/core/machines/MachineIdle.d.ts +0 -8
- package/dist/query-v2/core/machines/MachineIdle.js +0 -19
- package/dist/query-v2/core/machines/MachinePending.d.ts +0 -12
- package/dist/query-v2/core/machines/MachinePending.js +0 -29
- package/dist/query-v2/core/machines/MachineRefreshing.d.ts +0 -14
- package/dist/query-v2/core/machines/MachineRefreshing.js +0 -46
- package/dist/query-v2/core/machines/MachineSuccess.d.ts +0 -16
- package/dist/query-v2/core/machines/MachineSuccess.js +0 -42
- package/dist/query-v2/core/machines/MachineWithData.d.ts +0 -18
- package/dist/query-v2/core/machines/MachineWithData.js +0 -40
- package/dist/query-v2/core/machines/Patcher.d.ts +0 -20
- package/dist/query-v2/core/machines/Patcher.js +0 -104
- package/dist/query-v2/core/machines/index.d.ts +0 -8
- package/dist/query-v2/core/machines/index.js +0 -8
- package/dist/query-v2/core/resource/ResourceV2.d.ts +0 -120
- package/dist/query-v2/core/resource/ResourceV2.js +0 -464
- package/dist/query-v2/core/resource/ResourceV2Agent.d.ts +0 -26
- package/dist/query-v2/core/resource/ResourceV2Agent.js +0 -132
- package/dist/query-v2/core/resource/index.d.ts +0 -2
- package/dist/query-v2/core/resource/index.js +0 -2
- package/dist/query-v2/index.d.ts +0 -11
- package/dist/query-v2/index.js +0 -17
- package/dist/query-v2/lib/NO_VALUE.d.ts +0 -2
- package/dist/query-v2/lib/NO_VALUE.js +0 -1
- package/dist/query-v2/lib/SKIP_TOKEN.d.ts +0 -2
- package/dist/query-v2/lib/SKIP_TOKEN.js +0 -1
- package/dist/query-v2/lib/index.d.ts +0 -4
- package/dist/query-v2/lib/index.js +0 -3
- package/dist/query-v2/plugins/ReactHooksPlugin.d.ts +0 -25
- package/dist/query-v2/plugins/ReactHooksPlugin.js +0 -19
- package/dist/query-v2/plugins/types.d.ts +0 -1
- package/dist/query-v2/react/__tests__/helpers.d.ts +0 -12
- package/dist/query-v2/react/__tests__/helpers.js +0 -33
- package/dist/query-v2/react/index.d.ts +0 -2
- package/dist/query-v2/react/index.js +0 -2
- package/dist/query-v2/react/useResourceV2Agent.d.ts +0 -12
- package/dist/query-v2/react/useResourceV2Agent.js +0 -36
- package/dist/query-v2/react/useResourceV2Ref.d.ts +0 -12
- package/dist/query-v2/react/useResourceV2Ref.js +0 -57
- package/dist/query-v2/snapshot/Snapshot.d.ts +0 -13
- package/dist/query-v2/snapshot/Snapshot.js +0 -76
- package/dist/query-v2/types/agent.types.d.ts +0 -54
- package/dist/query-v2/types/api.types.d.ts +0 -22
- package/dist/query-v2/types/cache.types.d.ts +0 -37
- package/dist/query-v2/types/index.d.ts +0 -9
- package/dist/query-v2/types/index.js +0 -9
- package/dist/query-v2/types/lifecycle.types.d.ts +0 -25
- package/dist/query-v2/types/machine.types.d.ts +0 -67
- package/dist/query-v2/types/plugin.types.d.ts +0 -38
- package/dist/query-v2/types/resource.types.d.ts +0 -35
- package/dist/query-v2/types/resource.types.js +0 -1
- package/dist/query-v2/types/shared.types.d.ts +0 -20
- package/dist/query-v2/types/shared.types.js +0 -1
- package/dist/query-v2/types/snapshot.types.d.ts +0 -21
- package/dist/query-v2/types/snapshot.types.js +0 -1
- package/docs/contributing/query-v2/README.md +0 -379
- package/docs/migrations/query-v2.md +0 -171
- package/docs/query-v2/README.md +0 -280
- package/docs/query-v2/api-reference.md +0 -235
- package/docs/query-v2/optimistic-updates.md +0 -148
- package/docs/query-v2/ssr.md +0 -130
- /package/dist/{query-v2 → query}/lib/stableStringify.d.ts +0 -0
- /package/dist/{query-v2/plugins/types.js → query/types/api.js} +0 -0
- /package/dist/{query-v2/types/agent.types.js → query/types/cache.js} +0 -0
- /package/dist/{query-v2/types/api.types.js → query/types/command.js} +0 -0
- /package/dist/{query-v2/types/cache.types.js → query/types/common.js} +0 -0
- /package/dist/{query-v2/types/lifecycle.types.js → query/types/plugin-hkt.js} +0 -0
- /package/dist/{query-v2/types/machine.types.js → query/types/resource.js} +0 -0
- /package/dist/{query-v2/types/plugin.types.js → query/types/state.js} +0 -0
package/docs/query/README.md
CHANGED
|
@@ -1,575 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Модуль Query
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Модуль Query — декларативное управление серверными данными: кеширование, инвалидация, оптимистичные обновления и SSR. Построен на RxJS и [сигналах][signals], не зависит от UI-фреймворка — React-интеграция подключается плагином. Два базовых примитива: [ресурс][resource] (чтение данных с кешем по аргументам) и [команда][command] (мутация / побочное действие).
|
|
4
4
|
|
|
5
|
-
RxQuery — система для управления асинхронными запросами и кэшированием данных в RxToolkit. Она состоит из двух основных компонентов: **Resources** и **Commands**.
|
|
6
5
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
### Resources (Ресурсы)
|
|
10
|
-
|
|
11
|
-
Resources предназначены для реактивного кэширования повторяемых запросов. Они автоматически управляют состоянием загрузки, кэшируют результаты и обеспечивают эффективную инвалидацию данных.
|
|
12
|
-
|
|
13
|
-
**Ключевые особенности:**
|
|
14
|
-
- Автоматическое кэширование по аргументам запроса
|
|
15
|
-
- Поддержка AbortController для отмены запросов
|
|
16
|
-
- Реактивные обновления состояния
|
|
17
|
-
- Оптимистичные обновления
|
|
18
|
-
- Гибкое управление временем жизни кэша
|
|
19
|
-
|
|
20
|
-
### Commands (Команды)
|
|
21
|
-
|
|
22
|
-
Commands представляют одноразовые команды или мутации. Они не кэшируются, но предоставляют состояние выполнения и могут связываться с ресурсами для их обновления.
|
|
23
|
-
|
|
24
|
-
**Ключевые особенности:**
|
|
25
|
-
- Отслеживание состояния выполнения
|
|
26
|
-
- Связывание с ресурсами для их обновления
|
|
27
|
-
- Поддержка оптимистичных обновлений
|
|
28
|
-
- Возможность блокировки связанных ресурсов
|
|
29
|
-
- Автоматический откат при ошибках
|
|
30
|
-
|
|
31
|
-
### Agents (Агенты)
|
|
32
|
-
|
|
33
|
-
Agents представляют собой интеллектуальные обертки над ресурсами (или командами), которые обеспечивают более удобную работу с состояниями запросов для потребителей.
|
|
34
|
-
|
|
35
|
-
**Основная проблема, которую решают агенты:**
|
|
36
|
-
|
|
37
|
-
Кэш ресурсов содержит "сырые" состояния отдельных запросов, но потребителям нужна более высокоуровневая логика:
|
|
38
|
-
- `isInitialLoading` должно быть true только при первой загрузке ресурса
|
|
39
|
-
- При смене аргументов запроса нужно показывать данные предыдущего запроса, пока загружается новый
|
|
40
|
-
- Состояние загрузки должно отражать контекст использования, а не просто состояние кэша
|
|
41
|
-
|
|
42
|
-
### ResourceRef (Ссылка на ресурс)
|
|
43
|
-
|
|
44
|
-
Ref — это абстракция для взаимодействия с элементом кэша ресурса напрямую.
|
|
45
|
-
|
|
46
|
-
**Особенности:**
|
|
47
|
-
- Команды используют ref под капотом для управления связанным ресурсом
|
|
48
|
-
- Ref может ссылаться на отсутствующий элемент кэша
|
|
49
|
-
- Позволяет выполнять patch-транзакции для оптимистичных обновлений
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## API
|
|
54
|
-
|
|
55
|
-
### createResource
|
|
56
|
-
|
|
57
|
-
Создает новый ресурс для кэширования данных.
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { createResource } from '@fozy-labs/rx-toolkit';
|
|
61
|
-
|
|
62
|
-
interface User {
|
|
63
|
-
id: string;
|
|
64
|
-
name: string;
|
|
65
|
-
email: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const userResource = createResource<{ id: string }, User>({
|
|
69
|
-
async queryFn(args, tools) {
|
|
70
|
-
const response = await fetch(`/api/users/${args.id}`, {
|
|
71
|
-
signal: tools.abortSignal // Поддержка отмены запроса
|
|
72
|
-
});
|
|
73
|
-
return response.json();
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
// Опционально: трансформация данных
|
|
77
|
-
select: (data) => ({
|
|
78
|
-
id: data.id,
|
|
79
|
-
name: data.name,
|
|
80
|
-
email: data.email
|
|
81
|
-
}),
|
|
82
|
-
|
|
83
|
-
// Опционально: время жизни кэша (по умолчанию 60 секунд)
|
|
84
|
-
cacheLifetime: 30000, // 30 секунд
|
|
85
|
-
|
|
86
|
-
// Опционально: имя для devtools
|
|
87
|
-
devtoolsName: 'user-resource',
|
|
88
|
-
|
|
89
|
-
// Опционально: кастомное сравнение аргументов
|
|
90
|
-
compareArgsFn: (args1, args2) => args1.id === args2.id,
|
|
91
|
-
});
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Параметры createResource:**
|
|
95
|
-
|
|
96
|
-
| Параметр | Тип | Описание |
|
|
97
|
-
|----------|-----|----------|
|
|
98
|
-
| `queryFn` | `(args, tools) => Promise<Result>` | Функция выполнения запроса |
|
|
99
|
-
| `select` | `(data) => Selected` | Опциональная функция трансформации данных |
|
|
100
|
-
| `cacheLifetime` | `number \| false` | Время жизни кэша в мс (default: 60000). `false` — кэш не удаляется |
|
|
101
|
-
| `compareArgsFn` | `(args1, args2) => boolean` | Кастомная функция сравнения аргументов |
|
|
102
|
-
| `onCacheEntryAdded` | `(args, tools) => void` | Хук при добавлении элемента в кэш |
|
|
103
|
-
| `onQueryStarted` | `(args, tools) => void` | Хук при старте запроса |
|
|
104
|
-
| `devtoolsName` | `string \| false` | Имя для devtools (`false` — отключить) |
|
|
105
|
-
|
|
106
|
-
**Tools в queryFn:**
|
|
107
|
-
- `abortSignal` — AbortSignal для отмены запроса
|
|
108
|
-
|
|
109
|
-
### createCommand
|
|
110
|
-
|
|
111
|
-
Создает новую команду для выполнения мутаций.
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
import { createCommand } from '@fozy-labs/rx-toolkit';
|
|
115
|
-
|
|
116
|
-
const updateUser = createCommand<
|
|
117
|
-
{ id: string; data: Partial<User> },
|
|
118
|
-
User
|
|
119
|
-
>({
|
|
120
|
-
async queryFn(args) {
|
|
121
|
-
const response = await fetch(`/api/users/${args.id}`, {
|
|
122
|
-
method: 'PATCH',
|
|
123
|
-
headers: { 'Content-Type': 'application/json' },
|
|
124
|
-
body: JSON.stringify(args.data)
|
|
125
|
-
});
|
|
126
|
-
return response.json();
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
// Связывание с ресурсами
|
|
130
|
-
link(add) {
|
|
131
|
-
add({
|
|
132
|
-
resource: userResource,
|
|
133
|
-
forwardArgs: (args) => ({ id: args.id }),
|
|
134
|
-
// Обновление кэша после успешного запроса
|
|
135
|
-
update({ draft, args, data }) {
|
|
136
|
-
Object.assign(draft, args.data);
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
devtoolsName: 'update-user',
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Параметры createCommand:**
|
|
146
|
-
|
|
147
|
-
| Параметр | Тип | Описание |
|
|
148
|
-
|---------------------|-----------------------------|-----------------------------------------------|
|
|
149
|
-
| `queryFn` | `(args) => Promise<Result>` | Функция выполнения команды |
|
|
150
|
-
| `select` | `(data) => Selected` | Опциональная функция трансформации результата |
|
|
151
|
-
| `link` | `(add) => void` | Функция связывания с ресурсами |
|
|
152
|
-
| `cacheLifetime` | `number \| false` | Время жизни кэша команды (default: 1000) |
|
|
153
|
-
| `onCacheEntryAdded` | `(args, tools) => void` | Хук при добавлении в кэш |
|
|
154
|
-
| `onQueryStarted` | `(args, tools) => void` | Хук при старте команды |
|
|
155
|
-
| `devtoolsName` | `string \| false` | Имя для devtools |
|
|
156
|
-
|
|
157
|
-
> **Note:** `createOperation` and `useOperationAgent` are deprecated aliases for `createCommand` and `useCommandAgent` respectively. They will be removed in v0.6.0.
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## Свойства Link
|
|
162
|
-
|
|
163
|
-
Link позволяет связывать команды с ресурсами для автоматического обновления кэша:
|
|
6
|
+
## Быстрый старт
|
|
164
7
|
|
|
165
8
|
```typescript
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Целевой ресурс, с которым связывается команда
|
|
169
|
-
* @required
|
|
170
|
-
*/
|
|
171
|
-
resource: ResourceInstance<RD>;
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Функция для получения аргументов ресурса из аргументов команды.
|
|
175
|
-
* Используется для определения какой элемент в кэше нужно обновить
|
|
176
|
-
* @required
|
|
177
|
-
*/
|
|
178
|
-
forwardArgs: (args: D["Args"]) => RD["Args"];
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Инвалидация кэша после выполнения команды.
|
|
182
|
-
* При true — кэш будет очищен и ресурс перезагрузится
|
|
183
|
-
* @default false
|
|
184
|
-
*/
|
|
185
|
-
invalidate?: boolean;
|
|
9
|
+
import { createApi, reactHooksPlugin } from '@fozy-labs/rx-toolkit';
|
|
186
10
|
|
|
187
|
-
|
|
188
|
-
* Блокировка ресурса во время выполнения команды.
|
|
189
|
-
* При true — ресурс не сможет выполнять новые запросы
|
|
190
|
-
* @default false
|
|
191
|
-
*/
|
|
192
|
-
lock?: boolean;
|
|
11
|
+
const api = createApi({ plugins: [reactHooksPlugin()] });
|
|
193
12
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
draft: RD["Data"]; // Immer draft для мутации
|
|
200
|
-
args: D["Args"]; // Аргументы команды
|
|
201
|
-
data: D["Data"]; // Результат команды
|
|
202
|
-
}) => void | RD["Data"];
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Оптимистичное обновление ДО выполнения команды.
|
|
206
|
-
* Позволяет обновить UI немедленно
|
|
207
|
-
*/
|
|
208
|
-
optimisticUpdate?: (tools: {
|
|
209
|
-
draft: RD["Data"]; // Immer draft для мутации
|
|
210
|
-
args: D["Args"]; // Аргументы команды
|
|
211
|
-
}) => void | RD["Data"];
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Создание нового элемента в кэше.
|
|
215
|
-
* Используется когда команда создает новую сущность
|
|
216
|
-
*/
|
|
217
|
-
create?: (tools: {
|
|
218
|
-
args: D["Args"];
|
|
219
|
-
data: D["Data"];
|
|
220
|
-
}) => RD["Data"] | Promise<RD["Data"]>;
|
|
221
|
-
};
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Пример: Оптимистичные обновления
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
const toggleCartItem = createCommand({
|
|
228
|
-
queryFn: async (args: { id: string; enabled: boolean }) => {
|
|
229
|
-
return fetch(`/api/cart/toggle`, {
|
|
230
|
-
method: 'POST',
|
|
231
|
-
body: JSON.stringify(args)
|
|
232
|
-
}).then(r => r.json());
|
|
233
|
-
},
|
|
234
|
-
link(add) {
|
|
235
|
-
add({
|
|
236
|
-
resource: cartResource,
|
|
237
|
-
forwardArgs: () => undefined, // Корзина без параметров
|
|
238
|
-
|
|
239
|
-
// Оптимистичное обновление — UI обновится мгновенно
|
|
240
|
-
optimisticUpdate: ({ draft, args }) => {
|
|
241
|
-
const item = draft.items.find(i => i.id === args.id);
|
|
242
|
-
if (item) {
|
|
243
|
-
item.enabled = args.enabled;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
// При ошибке изменения автоматически откатятся
|
|
247
|
-
});
|
|
248
|
-
}
|
|
13
|
+
const usersResource = api.createResource({
|
|
14
|
+
queryFn: async (args: { page: number }, signal) => {
|
|
15
|
+
const res = await fetch(`/api/users?page=${args.page}`, { signal });
|
|
16
|
+
return res.json();
|
|
17
|
+
},
|
|
249
18
|
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
---
|
|
253
19
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
type ResourceQueryState<D> = {
|
|
262
|
-
/** Инициализирован ли хотя бы один запрос */
|
|
263
|
-
isInitiated: boolean;
|
|
264
|
-
|
|
265
|
-
/** Любая загрузка (первая или повторная) */
|
|
266
|
-
isLoading: boolean;
|
|
267
|
-
|
|
268
|
-
/** Первая загрузка (данных еще не было) */
|
|
269
|
-
isInitialLoading: boolean;
|
|
270
|
-
|
|
271
|
-
/** Перезагрузка (данные уже есть) */
|
|
272
|
-
isReloading: boolean;
|
|
273
|
-
|
|
274
|
-
/** Завершен ли запрос */
|
|
275
|
-
isDone: boolean;
|
|
276
|
-
|
|
277
|
-
/** Успешно ли завершен последний запрос */
|
|
278
|
-
isSuccess: boolean;
|
|
279
|
-
|
|
280
|
-
/** Произошла ли ошибка последнего запроса */
|
|
281
|
-
isError: boolean;
|
|
282
|
-
|
|
283
|
-
/** Заблокирован ли ресурс командой */
|
|
284
|
-
isLocked: boolean;
|
|
285
|
-
|
|
286
|
-
/** Оригинал ошибки, если есть */
|
|
287
|
-
error: unknown | undefined;
|
|
288
|
-
|
|
289
|
-
/** Данные (или select данных) */
|
|
290
|
-
data: D["Data"] | undefined;
|
|
291
|
-
|
|
292
|
-
/** Аргументы последнего запроса */
|
|
293
|
-
args: D["Args"] | undefined;
|
|
294
|
-
}
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### CommandQueryState
|
|
298
|
-
|
|
299
|
-
Состояние выполнения команды:
|
|
300
|
-
|
|
301
|
-
```typescript
|
|
302
|
-
type CommandQueryState<D> = {
|
|
303
|
-
isInitiated: boolean;
|
|
304
|
-
isLoading: boolean;
|
|
305
|
-
isDone: boolean;
|
|
306
|
-
isSuccess: boolean;
|
|
307
|
-
isError: boolean;
|
|
308
|
-
error: unknown | undefined;
|
|
309
|
-
data: D["Data"] | undefined;
|
|
20
|
+
// React-компонент
|
|
21
|
+
function UsersList({ page }: { page: number }) {
|
|
22
|
+
const { data, error, isLoading } = usersResource.useResource({ page });
|
|
23
|
+
if (isLoading) return <Spinner />;
|
|
24
|
+
return <ul>{data.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
|
|
310
25
|
}
|
|
311
26
|
```
|
|
312
27
|
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## ResourceRef API
|
|
316
|
-
|
|
317
|
-
ResourceRef предоставляет низкоуровневый доступ к элементу кэша:
|
|
318
|
-
|
|
319
|
-
```typescript
|
|
320
|
-
type ResourceRefInstance<D> = {
|
|
321
|
-
/** Проверка наличия элемента в кэше */
|
|
322
|
-
get has(): boolean;
|
|
323
|
-
|
|
324
|
-
/** Блокировка ресурса (возвращает функцию разблокировки) */
|
|
325
|
-
lock(): { unlock: () => void };
|
|
326
|
-
|
|
327
|
-
/** Снятие одной блокировки */
|
|
328
|
-
unlockOne(): void;
|
|
329
|
-
|
|
330
|
-
/** Patch-транзакция для изменения данных */
|
|
331
|
-
patch(patchFn: (data: D['Data']) => void): ResourceTransaction | null;
|
|
332
|
-
|
|
333
|
-
/** Инвалидация (очистка) кэша */
|
|
334
|
-
invalidate(): void;
|
|
335
|
-
|
|
336
|
-
/** Создание элемента в кэше с данными */
|
|
337
|
-
create(data: D['Data']): void;
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### Patch-транзакции
|
|
342
|
-
|
|
343
|
-
Транзакции позволяют делать изменения с возможностью отката:
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
type ResourceTransaction = {
|
|
347
|
-
patches: ImmerPatch[] // Патчи изменений
|
|
348
|
-
inversePatches: ImmerPatch[] // Патчи для отката
|
|
349
|
-
status: 'pending' | 'committed' | 'aborted'
|
|
350
|
-
abort(): void // Откатить изменения
|
|
351
|
-
commit(): void // Подтвердить изменения
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
**Пример использования транзакций:**
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
import { useResourceRef } from '@fozy-labs/rx-toolkit';
|
|
359
|
-
|
|
360
|
-
function TodoList() {
|
|
361
|
-
const todoRef = useResourceRef(todoResource, undefined);
|
|
362
|
-
const [pendingChanges, setPendingChanges] = useState([]);
|
|
363
|
-
|
|
364
|
-
const handleToggle = (itemId: number) => {
|
|
365
|
-
const transaction = todoRef.patch((draft) => {
|
|
366
|
-
const item = draft.items.find(i => i.id === itemId);
|
|
367
|
-
if (item) item.completed = !item.completed;
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
if (transaction) {
|
|
371
|
-
setPendingChanges(prev => [...prev, {
|
|
372
|
-
id: itemId,
|
|
373
|
-
transaction
|
|
374
|
-
}]);
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
const commitChange = (id: number) => {
|
|
379
|
-
const change = pendingChanges.find(c => c.id === id);
|
|
380
|
-
change?.transaction.commit();
|
|
381
|
-
setPendingChanges(prev => prev.filter(c => c.id !== id));
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const abortChange = (id: number) => {
|
|
385
|
-
const change = pendingChanges.find(c => c.id === id);
|
|
386
|
-
change?.transaction.abort(); // Данные вернутся к исходным
|
|
387
|
-
setPendingChanges(prev => prev.filter(c => c.id !== id));
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
---
|
|
393
|
-
|
|
394
|
-
## Lifecycle хуки
|
|
395
|
-
|
|
396
|
-
### onCacheEntryAdded
|
|
397
|
-
|
|
398
|
-
Вызывается при добавлении нового элемента в кэш:
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
const userResource = createResource({
|
|
402
|
-
queryFn: fetchUser,
|
|
403
|
-
|
|
404
|
-
onCacheEntryAdded(args, { $cacheDataLoaded, $cacheEntryRemoved, dataChanged$ }) {
|
|
405
|
-
// args — аргументы запроса
|
|
406
|
-
|
|
407
|
-
// Ожидание первой загрузки данных
|
|
408
|
-
$cacheDataLoaded.then(() => {
|
|
409
|
-
console.log('Данные загружены в кэш');
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
// Ожидание удаления из кэша
|
|
413
|
-
$cacheEntryRemoved.then(() => {
|
|
414
|
-
console.log('Элемент удален из кэша');
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// Подписка на изменения данных
|
|
418
|
-
const sub = dataChanged$.subscribe(data => {
|
|
419
|
-
console.log('Данные изменились:', data);
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### onQueryStarted
|
|
426
|
-
|
|
427
|
-
Вызывается при старте каждого запроса:
|
|
428
|
-
|
|
429
|
-
```typescript
|
|
430
|
-
const userResource = createResource({
|
|
431
|
-
queryFn: fetchUser,
|
|
432
|
-
|
|
433
|
-
async onQueryStarted(args, { $queryFulfilled }) {
|
|
434
|
-
console.log('Запрос начат с аргументами:', args);
|
|
435
|
-
|
|
436
|
-
const result = await $queryFulfilled;
|
|
437
|
-
|
|
438
|
-
if (result.isError) {
|
|
439
|
-
console.error('Ошибка запроса:', result.error);
|
|
440
|
-
} else {
|
|
441
|
-
console.log('Запрос успешен:', result.data);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
---
|
|
448
|
-
|
|
449
|
-
## Утилиты
|
|
450
|
-
|
|
451
|
-
### resetAllQueriesCache
|
|
452
|
-
|
|
453
|
-
Сбрасывает кэш всех ресурсов в приложении:
|
|
454
|
-
|
|
455
|
-
```typescript
|
|
456
|
-
import { resetAllQueriesCache } from '@fozy-labs/rx-toolkit';
|
|
457
|
-
|
|
458
|
-
function LogoutButton() {
|
|
459
|
-
const handleLogout = () => {
|
|
460
|
-
// Очистить все кэшированные данные при выходе
|
|
461
|
-
resetAllQueriesCache();
|
|
462
|
-
navigate('/login');
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
return <button onClick={handleLogout}>Выйти</button>;
|
|
466
|
-
}
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
### SKIP токен
|
|
470
|
-
|
|
471
|
-
Используется для условного пропуска запроса:
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
import { useResourceAgent, SKIP } from '@fozy-labs/rx-toolkit';
|
|
475
|
-
|
|
476
|
-
function UserProfile({ userId }: { userId: string | null }) {
|
|
477
|
-
// Запрос будет выполнен только если userId не null
|
|
478
|
-
const userQuery = useResourceAgent(
|
|
479
|
-
userResource,
|
|
480
|
-
userId ? { id: userId } : SKIP
|
|
481
|
-
);
|
|
482
|
-
|
|
483
|
-
if (!userId) return <div>Выберите пользователя</div>;
|
|
484
|
-
if (userQuery.isLoading) return <div>Загрузка...</div>;
|
|
485
|
-
|
|
486
|
-
return <div>{userQuery.data?.name}</div>;
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
## Примеры
|
|
493
|
-
|
|
494
|
-
### Корзина покупок с оптимистичными обновлениями
|
|
495
|
-
|
|
496
|
-
```typescript
|
|
497
|
-
import { createResource, createCommand, useResourceAgent, useCommandAgent } from '@fozy-labs/rx-toolkit';
|
|
498
|
-
|
|
499
|
-
const cartResource = createResource({
|
|
500
|
-
queryFn: () => fetch('/api/cart').then(r => r.json()),
|
|
501
|
-
devtoolsName: 'cart'
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
const toggleCartItem = createCommand({
|
|
505
|
-
queryFn: (args: { id: string; enabled: boolean }) =>
|
|
506
|
-
fetch('/api/cart/toggle', {
|
|
507
|
-
method: 'POST',
|
|
508
|
-
body: JSON.stringify(args)
|
|
509
|
-
}).then(r => r.json()),
|
|
510
|
-
|
|
511
|
-
link(add) {
|
|
512
|
-
add({
|
|
513
|
-
resource: cartResource,
|
|
514
|
-
forwardArgs: () => undefined,
|
|
515
|
-
optimisticUpdate: ({ draft, args }) => {
|
|
516
|
-
const item = draft.items.find(i => i.id === args.id);
|
|
517
|
-
if (item) item.enabled = args.enabled;
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
function ShoppingCart() {
|
|
524
|
-
const cartQuery = useResourceAgent(cartResource, undefined);
|
|
525
|
-
const [toggleItem, toggleState] = useCommandAgent(toggleCartItem);
|
|
526
|
-
|
|
527
|
-
return (
|
|
528
|
-
<div>
|
|
529
|
-
{cartQuery.data?.items.map(item => (
|
|
530
|
-
<div key={item.id}>
|
|
531
|
-
<span>{item.name}</span>
|
|
532
|
-
<button onClick={() => toggleItem({
|
|
533
|
-
id: item.id,
|
|
534
|
-
enabled: !item.enabled
|
|
535
|
-
})}>
|
|
536
|
-
{item.enabled ? 'Убрать' : 'Добавить'}
|
|
537
|
-
</button>
|
|
538
|
-
</div>
|
|
539
|
-
))}
|
|
540
|
-
</div>
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### Зависимые запросы
|
|
546
|
-
|
|
547
|
-
```typescript
|
|
548
|
-
const userResource = createResource({
|
|
549
|
-
queryFn: (args: { id: number }) => fetch(`/api/users/${args.id}`).then(r => r.json()),
|
|
550
|
-
});
|
|
551
|
-
|
|
552
|
-
const userStatsResource = createResource({
|
|
553
|
-
queryFn: (args: { userId: number; period: string }) =>
|
|
554
|
-
fetch(`/api/users/${args.userId}/stats?period=${args.period}`).then(r => r.json()),
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
function UserDashboard({ userId }: { userId: number }) {
|
|
558
|
-
const [period, setPeriod] = useState('daily');
|
|
559
|
-
|
|
560
|
-
const userQuery = useResourceAgent(userResource, { id: userId });
|
|
561
|
-
|
|
562
|
-
// Запрос статистики выполняется только после загрузки пользователя
|
|
563
|
-
const statsQuery = useResourceAgent(
|
|
564
|
-
userStatsResource,
|
|
565
|
-
userQuery.isSuccess ? { userId, period } : SKIP
|
|
566
|
-
);
|
|
567
|
-
|
|
568
|
-
// ...
|
|
569
|
-
}
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
## React интеграция
|
|
573
|
-
|
|
574
|
-
См. [React интеграция](../usage/react/README.md) для подробной информации о React хуках.
|
|
575
28
|
|
|
29
|
+
## Возможности
|
|
30
|
+
|
|
31
|
+
- **Кеширование** — автоматическое по аргументам, с настраиваемым временем жизни
|
|
32
|
+
- **Stale-While-Revalidate** — показ устаревших данных во время фонового обновления
|
|
33
|
+
- **Оптимистичные обновления** — Immer-патчи с автоматическим ребейсом при ответе сервера
|
|
34
|
+
- **SSR / гидрация** — снимки кеша для серверного рендеринга
|
|
35
|
+
- **Кросс-табовая синхронизация** — BroadcastChannel для актуальности данных между вкладками
|
|
36
|
+
- **Система плагинов** — расширение ресурсов и команд через `createApi({ plugins: [...] })`
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Что читать дальше
|
|
40
|
+
|
|
41
|
+
| Цель | Рекомендуемый порядок |
|
|
42
|
+
|------|-----------------------|
|
|
43
|
+
| **Быстрый старт** | [usage/resource.md][resource] → [usage/command.md][command] |
|
|
44
|
+
| **Понять внутреннее устройство** | [concepts/machine.md][machine] → [concepts/cache.md][cache] → [concepts/agent.md][agent] |
|
|
45
|
+
| **Оптимистичные обновления** | [concepts/patching.md][patching] → [usage/links.md][links] |
|
|
46
|
+
| **SSR / гидрация** | [usage/snapshot.md][snapshot] |
|
|
47
|
+
| **Кросс-табовая синхронизация** | [usage/broadcast.md][broadcast] |
|
|
48
|
+
| **API-справочник** | [api/README.md][api] → [api/resource.md][api-resource] → [api/command.md][api-command] |
|
|
49
|
+
| **Написание плагинов** | [usage/plugins.md][plugins] |
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
[signals]: ../signals/README.md
|
|
53
|
+
[resource]: usage/resource.md
|
|
54
|
+
[command]: usage/command.md
|
|
55
|
+
[machine]: concepts/machine.md
|
|
56
|
+
[cache]: concepts/cache.md
|
|
57
|
+
[agent]: concepts/agent.md
|
|
58
|
+
[patching]: concepts/patching.md
|
|
59
|
+
[links]: usage/links.md
|
|
60
|
+
[snapshot]: usage/snapshot.md
|
|
61
|
+
[broadcast]: usage/broadcast.md
|
|
62
|
+
[api]: api/README.md
|
|
63
|
+
[api-resource]: api/resource.md
|
|
64
|
+
[api-command]: api/command.md
|
|
65
|
+
[plugins]: usage/plugins.md
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# RxQuery API
|
|
2
|
+
|
|
3
|
+
API — центральный объект, управляющий ресурсами и командами.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Создание API
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { createApi, reactHooksPlugin } from '@fozy-labs/rx-toolkit';
|
|
10
|
+
|
|
11
|
+
const api = createApi({
|
|
12
|
+
keyPrefix: 'my-app', // (опционально) префикс для всех ключей ресурсов
|
|
13
|
+
plugins: [
|
|
14
|
+
reactHooksPlugin(), // (опционально) подключаем React Hooks плагин для удобного использования в React-приложениях
|
|
15
|
+
],
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Опции API
|
|
21
|
+
|
|
22
|
+
| Опция | Тип | По умолчанию | Описание |
|
|
23
|
+
|----------------------|---------------------------|-------------------|---------------------------------------------------------------------------------------------------------------------------------|
|
|
24
|
+
| `keyPrefix` | `string` \| `null` | `undefined` | Префикс, который добавляется ко всем ключам ресурсов и команд, создаваемых через этот API. |
|
|
25
|
+
| `plugins` | `IPlugin[]` | `[]` | Массив плагинов, которые будут использоваться этим API. |
|
|
26
|
+
| `serializeArgs` | `(args: TArgs) => string` | `stableStringify` | Функция сериализации аргументов в строку. |
|
|
27
|
+
| `resourceRetentionTime` | `number` \| `false` | `60_000 ms` | Время удержания кэша ресурсов. `false` — не удалять. |
|
|
28
|
+
| `commandRetentionTime` | `number` \| `false` | `0` | Время удержания кэша команд. `false` — не удалять. |
|
|
29
|
+
| `initialSnapshot` | `TApiSnapshot` \| `null` | `null` | Начальный [снимок] состояния всех ресурсов (для SSR или гидрации). |
|
|
30
|
+
| `snapshotValidTime` | `number` \| `false` | `false` | Время валидности данных в снимке. `false` - данные в [снимке][снимок] считаются всегда валидными. |
|
|
31
|
+
| `defaultSync` | `'none'` \| `'resources'` \| `'all'` | `'none'` | Режим синхронизации по умолчанию для ресурсов. `'none'` — выключена, `'resources'` / `'all'` — включена. Команды не поддерживают синхронизацию. |
|
|
32
|
+
| `syncDriver` | `ISyncDriver` | `undefined` | Драйвер для [синхронизации][синхронизация] состояния между несколькими экземплярами API (например, в разных вкладках браузера). |
|
|
33
|
+
| `onCacheEntryAdded` | `(args, ctx) => void` | — | Хук жизненного цикла уровня API — вызывается при создании любой кэш-записи. См. [lifecycle hooks][lifecycle]. |
|
|
34
|
+
| `onQueryStarted` | `(args, ctx) => void \| Promise<void>` | — | Хук жизненного цикла уровня API — вызывается при каждом запуске `queryFn`. См. [lifecycle hooks][lifecycle]. |
|
|
35
|
+
|
|
36
|
+
## Методы API
|
|
37
|
+
|
|
38
|
+
| Метод | Опции | Возвращаемое значение | Описание |
|
|
39
|
+
|------------------|--------------------------------------------|-----------------------------------------|-----------------------------------------------------------------|
|
|
40
|
+
| `createResource` | `options: TResourceOptions<TArgs, TData>` | `IApiResource<TPlugins, TArgs, TData>` | Создаёт новый [ресурс]. |
|
|
41
|
+
| `createCommand` | `options: TCommandOptions<TArgs, TData>` | `IApiCommand<TPlugins, TArgs, TData>` | Создаёт новую [команду][команда]. |
|
|
42
|
+
| `getSnapshot()` | - | `TApiSnapshot` | Получает текущий [снимок] состояния всех [ресурсов][ресурс]. |
|
|
43
|
+
| `resetAll()` | - | `void` | Сбрасывает все ресурсы и очищает сохранённый снимок. |
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## См. также
|
|
47
|
+
|
|
48
|
+
- [Ресурс](../usage/resource.md)
|
|
49
|
+
- [Команда](../usage/command.md)
|
|
50
|
+
- [Снимок (SSR / гидрация)](../usage/snapshot.md)
|
|
51
|
+
- [Синхронизация между вкладками](../usage/broadcast.md)
|
|
52
|
+
- [Lifecycle hooks](../usage/lifecycle.md)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
[снимок]: ../usage/snapshot.md
|
|
56
|
+
[синхронизация]: ../usage/broadcast.md
|
|
57
|
+
[lifecycle]: ../usage/lifecycle.md
|
|
58
|
+
[ресурс]: ../usage/resource.md
|
|
59
|
+
[команда]: ../usage/command.md
|