@fozy-labs/rx-toolkit 0.5.4 → 0.6.0
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 +4 -0
- package/dist/query/core/api/index.js +4 -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 +48 -2
- 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
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# Потоки данных
|
|
2
|
+
|
|
3
|
+
Диаграммы описывают основные сценарии взаимодействия компонентов модуля Query.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Потоки ресурса (Resource)
|
|
9
|
+
|
|
10
|
+
> Разделы ниже описывают потоки, специфичные для ресурсов. Команды используют упрощённый поток — см. «Мутация».
|
|
11
|
+
|
|
12
|
+
### Cache miss
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
sequenceDiagram
|
|
17
|
+
participant UI as React-компонент
|
|
18
|
+
participant Hook as useResource
|
|
19
|
+
participant Agent as Agent
|
|
20
|
+
participant Res as Resource
|
|
21
|
+
participant Cache as CacheMap
|
|
22
|
+
participant Entry as QueryCacheEntry
|
|
23
|
+
participant Query as queryFn
|
|
24
|
+
participant BQ as beforeQuery
|
|
25
|
+
participant Sync as SyncDriver
|
|
26
|
+
|
|
27
|
+
UI->>Hook: useResource(args)
|
|
28
|
+
Hook->>Agent: set(args)
|
|
29
|
+
|
|
30
|
+
Note over Agent: Создание Signal.computed
|
|
31
|
+
|
|
32
|
+
Agent->>Res: getEntry$(keyedArgs, doInitiate=false)
|
|
33
|
+
|
|
34
|
+
Res->>Cache: get(key)
|
|
35
|
+
Cache-->>Res: null (нет записи)
|
|
36
|
+
Res-->>Agent: null
|
|
37
|
+
Agent-->>Hook: pending
|
|
38
|
+
Hook-->>UI: { status: pending }
|
|
39
|
+
|
|
40
|
+
Note over Hook: useIsomorphicLayoutEffect срабатывает
|
|
41
|
+
|
|
42
|
+
opt синхронно
|
|
43
|
+
Hook->>Agent: start()
|
|
44
|
+
Agent->>Res: trigger(keyedArgs, doForce=false)
|
|
45
|
+
Res-->>Res: _getOrCreate(keyedArgs, doForce=false)
|
|
46
|
+
Res->>Cache: get(key)
|
|
47
|
+
Cache-->>Res: null
|
|
48
|
+
Res->>Entry: new Entry(options)
|
|
49
|
+
|
|
50
|
+
opt beforeQuery настроен (sync: true)
|
|
51
|
+
Res->>BQ: beforeQuery(key, keyedArgs)
|
|
52
|
+
BQ->>Sync: REQ { keys, reqId }
|
|
53
|
+
Note over Sync: BroadcastChannel.postMessage
|
|
54
|
+
Sync-->>BQ: RES { data } или таймаут
|
|
55
|
+
|
|
56
|
+
alt данные получены
|
|
57
|
+
BQ-->>Entry: hydrate(data)
|
|
58
|
+
Entry->>Entry: → success (без сетевого запроса)
|
|
59
|
+
Entry-->>Agent: machine$ → success
|
|
60
|
+
Agent-->>Hook: success
|
|
61
|
+
Hook-->>UI: { status: success, data }
|
|
62
|
+
else таймаут
|
|
63
|
+
BQ-->>Res: null
|
|
64
|
+
Note over Res: queryFn вызывается далее
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Entry->>Query: queryFn(args, abortSignal)
|
|
69
|
+
Query-->>Entry: Promise (pending)
|
|
70
|
+
Entry-->>Res: Entry (pending)
|
|
71
|
+
|
|
72
|
+
Res->>Cache: set(key, entry)
|
|
73
|
+
|
|
74
|
+
Cache-->>Res: Entry (pending)
|
|
75
|
+
|
|
76
|
+
opt Отработка реактивной зависимости (null → Entry)
|
|
77
|
+
Res -->> Res: lastEntry.set(Entry)
|
|
78
|
+
Res-->>Agent: $: Entry (pending)
|
|
79
|
+
Agent-->>Agent: Подписка на machine$ (pending)
|
|
80
|
+
Note over Agent: return stable(prev, next)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
Res -->> Agent: void
|
|
84
|
+
Agent-->>Hook: void
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Note over Query: Ожидание
|
|
88
|
+
|
|
89
|
+
alt ответ OK
|
|
90
|
+
Query-->>Entry: data
|
|
91
|
+
Entry->>Entry: → success
|
|
92
|
+
Entry-->>Agent: machine$ → success
|
|
93
|
+
Agent-->>Hook: success
|
|
94
|
+
Hook-->>UI: { status: success, data }
|
|
95
|
+
else ошибка
|
|
96
|
+
Query-->>Entry: error
|
|
97
|
+
Entry->>Entry: → error
|
|
98
|
+
Entry-->>Agent: machine$ → error
|
|
99
|
+
Agent-->>Hook: error
|
|
100
|
+
Hook-->>UI: { status: error, error }
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Cache hit
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
```mermaid
|
|
108
|
+
sequenceDiagram
|
|
109
|
+
participant UI as React-компонент
|
|
110
|
+
participant Hook as useResource
|
|
111
|
+
participant Agent as Agent
|
|
112
|
+
participant Res as Resource
|
|
113
|
+
participant Cache as CacheMap
|
|
114
|
+
|
|
115
|
+
UI->>Hook: useResource(args)
|
|
116
|
+
Hook->>Agent: set(args)
|
|
117
|
+
Note over Agent: Создание Signal.computed
|
|
118
|
+
Agent->>Res: getEntry$(keyedArgs, doInitiate=false)
|
|
119
|
+
Res->>Cache: get(key)
|
|
120
|
+
Cache-->>Res: Entry
|
|
121
|
+
Res-->>Agent: Entry
|
|
122
|
+
Agent-->>Agent: Подписка на machine$
|
|
123
|
+
Agent-->>Hook: state
|
|
124
|
+
Hook-->>UI: state
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Условный запрос (SKIP → реальные args)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
```mermaid
|
|
131
|
+
sequenceDiagram
|
|
132
|
+
participant UI as React-компонент
|
|
133
|
+
participant Hook as useResource
|
|
134
|
+
participant Agent as Agent
|
|
135
|
+
participant Res as Resource
|
|
136
|
+
|
|
137
|
+
UI->>Hook: useResource(SKIP)
|
|
138
|
+
Hook->>Agent: set(SKIP)
|
|
139
|
+
Note over Agent: → idle (запись не создаётся)
|
|
140
|
+
Agent-->>Hook: idle
|
|
141
|
+
Hook-->>UI: { status: idle }
|
|
142
|
+
|
|
143
|
+
Note over UI: зависимые данные готовы
|
|
144
|
+
|
|
145
|
+
UI->>Hook: useResource(args)
|
|
146
|
+
Hook->>Agent: set(args)
|
|
147
|
+
Agent->>Res: getEntry$(keyedArgs, doInitiate=false)
|
|
148
|
+
|
|
149
|
+
Res-->>Agent: Entry или null
|
|
150
|
+
|
|
151
|
+
Note over Agent: → поток «Cache miss» или «Cache hit»
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Refresh / фоновое обновление
|
|
155
|
+
|
|
156
|
+
```mermaid
|
|
157
|
+
sequenceDiagram
|
|
158
|
+
participant UI as React-компонент
|
|
159
|
+
participant Hook as useResource
|
|
160
|
+
participant Agent as Agent
|
|
161
|
+
participant Entry as QueryCacheEntry
|
|
162
|
+
participant Query as queryFn
|
|
163
|
+
|
|
164
|
+
Note over Entry: machine: success (data v1)
|
|
165
|
+
|
|
166
|
+
UI->>Hook: refresh()
|
|
167
|
+
Hook->>Agent: refresh()
|
|
168
|
+
Agent->>Entry: refresh()
|
|
169
|
+
Entry->>Entry: success → refreshing
|
|
170
|
+
Entry-->>Agent: machine$ → refreshing
|
|
171
|
+
Agent-->>Hook: refreshing
|
|
172
|
+
Hook-->>UI: { status: refreshing, data: v1 }
|
|
173
|
+
|
|
174
|
+
Entry->>Query: queryFn(args, abortSignal)
|
|
175
|
+
|
|
176
|
+
alt ответ OK
|
|
177
|
+
Query-->>Entry: data v2
|
|
178
|
+
Entry->>Entry: refreshing → success (rebase)
|
|
179
|
+
Entry-->>Agent: machine$ → success
|
|
180
|
+
Agent-->>Hook: success
|
|
181
|
+
Hook-->>UI: { status: success, data: v2 }
|
|
182
|
+
else ошибка
|
|
183
|
+
Query-->>Entry: error
|
|
184
|
+
Entry->>Entry: refreshing → refresh-error (fail)
|
|
185
|
+
Entry-->>Agent: machine$ → refresh-error
|
|
186
|
+
Agent-->>Hook: refresh-error
|
|
187
|
+
Hook-->>UI: { status: refresh-error, data: v1, error }
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### SWR-fallback при смене аргументов
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
```mermaid
|
|
195
|
+
sequenceDiagram
|
|
196
|
+
participant UI as React-компонент
|
|
197
|
+
participant Hook as useResource
|
|
198
|
+
participant Agent as Agent
|
|
199
|
+
participant Res as Resource
|
|
200
|
+
participant Entry2 as QueryCacheEntry (user/2)
|
|
201
|
+
|
|
202
|
+
Note over Agent: current = Entry1 (success, data/1)
|
|
203
|
+
|
|
204
|
+
UI->>Hook: useResource({ id: 2 })
|
|
205
|
+
Hook->>Agent: set({ id: 2 })
|
|
206
|
+
Agent->>Agent: prev = Entry1, current = null
|
|
207
|
+
|
|
208
|
+
Agent->>Res: getEntry$(keyedArgs, doInitiate=false)
|
|
209
|
+
Res-->>Agent: null
|
|
210
|
+
|
|
211
|
+
Note over Agent,Entry2: → поток «Cache miss» для { id: 2 }
|
|
212
|
+
|
|
213
|
+
Note over Agent: Реактивная зависимость: Entry2 (pending)
|
|
214
|
+
Agent-->>Agent: Подписка на machine$ (pending)
|
|
215
|
+
|
|
216
|
+
Note over Agent: pending + prev → refreshing (SWR)
|
|
217
|
+
Agent-->>Hook: refreshing
|
|
218
|
+
Hook-->>UI: { status: refreshing, data: data/1 }
|
|
219
|
+
|
|
220
|
+
alt ответ OK
|
|
221
|
+
Entry2->>Entry2: → success
|
|
222
|
+
Entry2-->>Agent: machine$ → success
|
|
223
|
+
Agent->>Agent: prev = null
|
|
224
|
+
Agent-->>Hook: success
|
|
225
|
+
Hook-->>UI: { status: success, data: data/2 }
|
|
226
|
+
else ошибка
|
|
227
|
+
Entry2->>Entry2: → error
|
|
228
|
+
Entry2-->>Agent: machine$ → error
|
|
229
|
+
Note over Agent: error не маскируется, prev (Entry1) сохраняется
|
|
230
|
+
Agent-->>Hook: error
|
|
231
|
+
Hook-->>UI: { status: error, data: data/1, error }
|
|
232
|
+
end
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Дедупликация параллельных запросов
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
```mermaid
|
|
239
|
+
sequenceDiagram
|
|
240
|
+
participant Agent as Потребитель B (например Agent)
|
|
241
|
+
participant Res as Resource
|
|
242
|
+
participant Cache as CacheMap
|
|
243
|
+
|
|
244
|
+
Note over Res: Потребитель A уже прошёл «Cache miss»<br/>(см. одноимённый раздел выше)
|
|
245
|
+
|
|
246
|
+
Agent->>Res: trigger(keyedArgs, doForce=false)
|
|
247
|
+
Res->>Cache: get(key)
|
|
248
|
+
Cache-->>Res: existing Entry (pending)
|
|
249
|
+
Res-->>Agent: void
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Потоки команды (Command)
|
|
253
|
+
|
|
254
|
+
### Мутация — базовый поток
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
```mermaid
|
|
258
|
+
sequenceDiagram
|
|
259
|
+
participant UI as React-компонент
|
|
260
|
+
participant Hook as useCommand
|
|
261
|
+
participant Agent as Agent
|
|
262
|
+
participant Cmd as Command
|
|
263
|
+
participant Cache as CacheMap
|
|
264
|
+
participant Entry as QueryCacheEntry
|
|
265
|
+
participant Query as queryFn
|
|
266
|
+
|
|
267
|
+
UI->>Hook: cmd.useCommand()
|
|
268
|
+
|
|
269
|
+
Hook-->>UI: { status: idle }
|
|
270
|
+
|
|
271
|
+
UI->>Hook: trigger(args)
|
|
272
|
+
Hook->>Agent: trigger(args)
|
|
273
|
+
Agent->>Cmd: trigger(keyedArgs)
|
|
274
|
+
Cmd->>Cache: get(key)
|
|
275
|
+
Cache-->>Cmd: null
|
|
276
|
+
Cmd->>Entry: new Entry(options)
|
|
277
|
+
Entry->>Query: queryFn(args)
|
|
278
|
+
Query-->>Entry: Promise (pending)
|
|
279
|
+
Entry-->>Cmd: Entry (pending)
|
|
280
|
+
Cmd->>Cache: set(key, entry)
|
|
281
|
+
Cache-->>Cmd: void
|
|
282
|
+
Cmd-->>Cmd: lastEntry.set(Entry)
|
|
283
|
+
Cmd-->>Agent: Entry (pending)
|
|
284
|
+
Agent-->>Hook: pending
|
|
285
|
+
Hook-->>UI: { status: pending }
|
|
286
|
+
|
|
287
|
+
alt ответ OK
|
|
288
|
+
Query-->>Entry: data
|
|
289
|
+
Entry->>Entry: pending → success
|
|
290
|
+
Entry-->>Agent: machine$ → success
|
|
291
|
+
Agent-->>Hook: success
|
|
292
|
+
Hook-->>UI: { status: success, data }
|
|
293
|
+
else ошибка
|
|
294
|
+
Query-->>Entry: error
|
|
295
|
+
Entry->>Entry: pending → error
|
|
296
|
+
Entry-->>Agent: machine$ → error
|
|
297
|
+
Agent-->>Hook: error
|
|
298
|
+
Hook-->>UI: { status: error, error }
|
|
299
|
+
end
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Связи (Links)
|
|
303
|
+
|
|
304
|
+
### Инвалидация через link после мутации
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
```mermaid
|
|
308
|
+
sequenceDiagram
|
|
309
|
+
participant Cmd as Command
|
|
310
|
+
participant Lnk as Link
|
|
311
|
+
participant Res as Resource
|
|
312
|
+
participant Cache as CacheMap
|
|
313
|
+
participant Entry as QueryCacheEntry
|
|
314
|
+
participant Query as queryFn
|
|
315
|
+
|
|
316
|
+
Note over Lnk: invalidate: true
|
|
317
|
+
|
|
318
|
+
Note over Entry: machine: success (data v1)
|
|
319
|
+
|
|
320
|
+
Note over Cmd: Мутация (UI → Hook → Cmd) — см. «Мутация — базовый поток»
|
|
321
|
+
Note over Cmd: queryFn(args) завершился успешно
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
Cmd->>Lnk: Вызов onQueryStarted ($queryFulfilled) хука
|
|
325
|
+
Lnk->>Lnk: forwardArgs(args) → args
|
|
326
|
+
Lnk->>Res: refresh(args)
|
|
327
|
+
Res->>Cache: get(key)
|
|
328
|
+
Cache-->>Res: Entry
|
|
329
|
+
Res->>Entry: refresh()
|
|
330
|
+
Entry->>Entry: success → refreshing
|
|
331
|
+
|
|
332
|
+
Note over Entry: подписчики записи ресурса получат refreshing
|
|
333
|
+
|
|
334
|
+
Entry->>Query: queryFn(args, abortSignal)
|
|
335
|
+
|
|
336
|
+
alt ответ OK
|
|
337
|
+
Query-->>Entry: fresh data
|
|
338
|
+
Entry->>Entry: refreshing → success (rebase)
|
|
339
|
+
Note over Entry: подписчики записи ресурса получат success
|
|
340
|
+
else ошибка
|
|
341
|
+
Query-->>Entry: error
|
|
342
|
+
Entry->>Entry: refreshing → refresh-error (fail)
|
|
343
|
+
Note over Entry: подписчики записи ресурса получат refresh-error
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
Entry-->>Res: void
|
|
347
|
+
Res-->>Lnk: void
|
|
348
|
+
Lnk-->>Cmd: void
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Оптимистичное обновление через link
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
```mermaid
|
|
355
|
+
sequenceDiagram
|
|
356
|
+
participant Cmd as Command
|
|
357
|
+
participant Lnk as Link
|
|
358
|
+
participant Res as Resource
|
|
359
|
+
participant Entry as QueryCacheEntry
|
|
360
|
+
|
|
361
|
+
Note over Cmd: trigger(args) — полный поток<br/>см. «Мутация — базовый поток»
|
|
362
|
+
|
|
363
|
+
Note over Lnk: optimisticUpdate: fn
|
|
364
|
+
|
|
365
|
+
Cmd->>Lnk: Вызов onQueryStarted хука
|
|
366
|
+
Lnk->>Lnk: forwardArgs(args) → args
|
|
367
|
+
Lnk->>Res: getEntry(args)
|
|
368
|
+
Res-->>Lnk: Entry
|
|
369
|
+
Lnk->>Entry: createPatch(patchFn)
|
|
370
|
+
Entry->>Entry: Immer produce → patches + inversePatches
|
|
371
|
+
Entry-->>Entry: machine$ → success (patched data)
|
|
372
|
+
|
|
373
|
+
alt ответ OK
|
|
374
|
+
Cmd->>Lnk: $queryFulfilled.resolve(data)
|
|
375
|
+
Lnk->>Entry: handle.commit()
|
|
376
|
+
Entry-->>Lnk: void
|
|
377
|
+
|
|
378
|
+
else ошибка
|
|
379
|
+
Cmd->>Lnk: onError(args, error)
|
|
380
|
+
Lnk->>Entry: handle.abort()
|
|
381
|
+
Entry->>Entry: inversePatches → rollback
|
|
382
|
+
Entry-->>Entry: machine$ → success (original data)
|
|
383
|
+
Note over Entry: Возможен isConsistencyViolation →<br/>автоинвалидация (см. патчинг)
|
|
384
|
+
Entry-->>Lnk: void
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
Lnk-->>Cmd: void
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
## Кросс-табовая синхронизация
|
|
394
|
+
|
|
395
|
+
> Синхронизация построена на PULL-модели: вкладка, которой нужны данные, запрашивает их у других вкладок через `beforeQuery` хук и `BroadcastChannel`. Вкладки **не** рассылают данные проактивно после успешного запроса.
|
|
396
|
+
|
|
397
|
+
```mermaid
|
|
398
|
+
sequenceDiagram
|
|
399
|
+
participant UI as React-компонент
|
|
400
|
+
participant Hook as useResource
|
|
401
|
+
participant Agent as Agent
|
|
402
|
+
participant Res as Resource
|
|
403
|
+
participant Entry as QueryCacheEntry
|
|
404
|
+
participant BQ as beforeQuery
|
|
405
|
+
participant Sync as SyncDriver
|
|
406
|
+
participant Sync2 as SyncDriver (отвечающий)
|
|
407
|
+
participant Cache2 as CacheMap
|
|
408
|
+
participant Query as queryFn
|
|
409
|
+
|
|
410
|
+
Note over UI, Sync: Tab B — запрашивающая вкладка
|
|
411
|
+
Note over Sync2, Cache2: Tab A — вкладка с данными (success)
|
|
412
|
+
|
|
413
|
+
Note over Res: Cache miss — создание новой записи<br/>(подробнее см. «Cache miss»)
|
|
414
|
+
Res->>Entry: new Entry(options)
|
|
415
|
+
|
|
416
|
+
opt beforeQuery настроен (sync: true)
|
|
417
|
+
Res->>BQ: beforeQuery(key, keyedArgs)
|
|
418
|
+
BQ->>Sync: REQ { keys, reqId }
|
|
419
|
+
Note over Sync: BroadcastChannel.postMessage
|
|
420
|
+
Sync-->>Sync2: ISyncMessage { type: "REQ", reqId, keys }
|
|
421
|
+
|
|
422
|
+
alt данные получены
|
|
423
|
+
Sync2->>Cache2: get(key)
|
|
424
|
+
Cache2-->>Sync2: Entry (success, data)
|
|
425
|
+
Sync2-->>Sync: ISyncMessage { type: "RES", reqId, data }
|
|
426
|
+
Sync-->>BQ: RES { data }
|
|
427
|
+
BQ-->>Entry: hydrate(data)
|
|
428
|
+
Entry->>Entry: → success (queryFn не вызывается)
|
|
429
|
+
Note over Entry: Мгновенный кэш-хит —<br/>рендер без сетевого запроса
|
|
430
|
+
Entry-->>Agent: machine$ → success
|
|
431
|
+
Agent-->>Hook: success
|
|
432
|
+
Hook-->>UI: { status: success, data }
|
|
433
|
+
else таймаут
|
|
434
|
+
Note over Sync2: Нет данных / нет других вкладок → нет ответа
|
|
435
|
+
Note over BQ: Таймаут — RES не получен
|
|
436
|
+
BQ-->>Res: null
|
|
437
|
+
Note over Res: queryFn вызывается далее
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
Entry->>Query: queryFn(args, abortSignal)
|
|
442
|
+
Note over Query: Сетевой запрос
|
|
443
|
+
|
|
444
|
+
alt ответ OK
|
|
445
|
+
Query-->>Entry: data
|
|
446
|
+
Entry->>Entry: → success
|
|
447
|
+
Entry-->>Agent: machine$ → success
|
|
448
|
+
Agent-->>Hook: success
|
|
449
|
+
Hook-->>UI: { status: success, data }
|
|
450
|
+
else ошибка
|
|
451
|
+
Query-->>Entry: error
|
|
452
|
+
Entry->>Entry: → error
|
|
453
|
+
Entry-->>Agent: machine$ → error
|
|
454
|
+
Agent-->>Hook: error
|
|
455
|
+
Hook-->>UI: { status: error, error }
|
|
456
|
+
end
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
## См. также
|
|
461
|
+
|
|
462
|
+
- [Машина состояний запроса][machine] — статусы и переходы, на которых построены все потоки
|
|
463
|
+
- [Система кэширования][cache] — жизненный цикл записей и `retentionTime`
|
|
464
|
+
- [Оптимистичные обновления (links)][usage-links] — `optimisticUpdate` и `invalidate` в действии
|
|
465
|
+
- [Агент][agent] — SWR-наблюдатель, транслирующий состояние машины в UI
|
|
466
|
+
- [Кросс-табовая синхронизация][usage-broadcast] — настройка `syncDriver` и `broadcastSyncDriver`
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
[agent]: agent.md
|
|
470
|
+
[machine]: machine.md
|
|
471
|
+
[cache]: cache.md
|
|
472
|
+
[usage-links]: ../usage/links.md
|
|
473
|
+
[usage-broadcast]: ../usage/broadcast.md
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Типизация аргументов (Keyed)
|
|
2
|
+
|
|
3
|
+
Все методы ресурсов и команд, принимающие аргументы, работают с типом `Args<TArgs>` — объединением сырых аргументов и обёрнутых в `Keyed`.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Типы
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
type Args<TArgs> = TArgs | Keyed<TArgs>;
|
|
10
|
+
|
|
11
|
+
type Keyed<T> = { value: T; key: string };
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- **`Keyed<T>`** — аргументы, обёрнутые с предвычисленным ключом кэша. Пара `{ value, key }`, где `key` — результат сериализации.
|
|
15
|
+
- **`Args<TArgs>`** — объединённый тип: сырые аргументы или `Keyed`. Все публичные методы (`trigger`, `refresh`, `getEntry`, `getEntry$`) принимают `Args<TArgs>`.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Пайплайн аргументов
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
args (UI / хук) → keyedArgs (Keyed<TArgs>) → key (string)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
1. **args** — сырые аргументы, переданные пользователем.
|
|
25
|
+
2. **keyedArgs** — обёртка `{ value: args, key }`, где `key` вычислен через `serializeArgs`.
|
|
26
|
+
3. **key** — строковый ключ кэша, используемый в `CacheMap`.
|
|
27
|
+
|
|
28
|
+
Метод `toKeyed(args)` на ресурсе выполняет шаг 1 → 2.
|
|
29
|
+
Передача `Keyed<TArgs>` напрямую позволяет избежать повторной сериализации.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## См. также
|
|
33
|
+
|
|
34
|
+
- [Ресурс — API][api-res] — методы ресурса, принимающие `Args<TArgs>`
|
|
35
|
+
- [Команда — API][api-cmd] — методы команды
|
|
36
|
+
- [Архитектура][architecture] — общая диаграмма компонентов
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
[api-res]: ../api/resource.md
|
|
41
|
+
[api-cmd]: ../api/command.md
|
|
42
|
+
[architecture]: architecture.md
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Машина состояний запроса
|
|
2
|
+
|
|
3
|
+
Каждый запрос представлен **иммутабельной машиной состояний**. Машина хранит статус, данные, ошибку и метаданные. Любой переход создаёт **новый** экземпляр — старый не мутируется.
|
|
4
|
+
|
|
5
|
+
## Пять состояний
|
|
6
|
+
|
|
7
|
+
| Статус | Данные | Ошибка | `updatedAt` |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `pending` | `null` | `null` | `null` |
|
|
10
|
+
| `success` | `TData` | `null` | `number` |
|
|
11
|
+
| `error` | `null` | `unknown` | `null` |
|
|
12
|
+
| `refreshing` | `TData` (устаревшие) | `null` | `number` |
|
|
13
|
+
| `refresh-error` | `TData` (устаревшие) | `unknown` | `number` |
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Диаграмма переходов
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
stateDiagram-v2
|
|
20
|
+
pending --> success : success(data)
|
|
21
|
+
|
|
22
|
+
[*] --> pending : Machine.pending(args)
|
|
23
|
+
[*] --> success : Machine.fromSnapshot(state)
|
|
24
|
+
[*] --> refreshing : Machine.fromSnapshot(state) | Запись устарела
|
|
25
|
+
|
|
26
|
+
state "refresh-error" as refresh_error
|
|
27
|
+
|
|
28
|
+
pending --> error : fail(error)
|
|
29
|
+
|
|
30
|
+
success --> refreshing : refresh()
|
|
31
|
+
success --> success : createPatch() / finishPatch() / finishAllPatches()
|
|
32
|
+
|
|
33
|
+
error --> pending : retry()
|
|
34
|
+
|
|
35
|
+
refreshing --> success : rebase(data)
|
|
36
|
+
refreshing --> refresh_error : fail(error)
|
|
37
|
+
refreshing --> refreshing : createPatch() / finishPatch() / finishAllPatches()
|
|
38
|
+
|
|
39
|
+
refresh_error --> refreshing : refresh()
|
|
40
|
+
refresh_error --> refresh_error : createPatch() / finishPatch() / finishAllPatches()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Модель данных
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
interface TPendingState<TArgs> {
|
|
47
|
+
status: 'pending';
|
|
48
|
+
args: TArgs;
|
|
49
|
+
data: null;
|
|
50
|
+
error: null;
|
|
51
|
+
updatedAt: null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface TSuccessState<TArgs, TData> {
|
|
55
|
+
status: 'success';
|
|
56
|
+
args: TArgs;
|
|
57
|
+
data: TData;
|
|
58
|
+
error: null;
|
|
59
|
+
updatedAt: number;
|
|
60
|
+
patchState: TPatchState<TData> | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface TErrorState<TArgs> {
|
|
64
|
+
status: 'error';
|
|
65
|
+
args: TArgs;
|
|
66
|
+
data: null;
|
|
67
|
+
error: unknown;
|
|
68
|
+
updatedAt: null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface TRefreshingState<TArgs, TData> {
|
|
72
|
+
status: 'refreshing';
|
|
73
|
+
args: TArgs;
|
|
74
|
+
data: TData;
|
|
75
|
+
error: null;
|
|
76
|
+
updatedAt: number;
|
|
77
|
+
patchState: TPatchState<TData> | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface TRefreshErrorState<TArgs, TData> {
|
|
81
|
+
status: 'refresh-error';
|
|
82
|
+
args: TArgs;
|
|
83
|
+
data: TData;
|
|
84
|
+
error: unknown;
|
|
85
|
+
updatedAt: number;
|
|
86
|
+
patchState: TPatchState<TData> | null;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## См. также
|
|
91
|
+
|
|
92
|
+
- [Кэш][cache] — хранит записи, каждая из которых содержит экземпляр машины.
|
|
93
|
+
- [Агент][agent] — наблюдает за записью кэша и транслирует состояние машины в UI.
|
|
94
|
+
- [Ресурс][usage-res] — использует машину для отслеживания состояния чтения данных.
|
|
95
|
+
- [Команда][usage-cmd] — использует машину для отслеживания состояния мутации.
|
|
96
|
+
- [Потоки данных][dataflows] — как машина участвует в потоках данных.
|
|
97
|
+
- [Патчинг][patching] — оптимистичные обновления через `createPatch` / `finishPatch`.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
[cache]: cache.md
|
|
102
|
+
[agent]: agent.md
|
|
103
|
+
[usage-res]: ../usage/resource.md
|
|
104
|
+
[usage-cmd]: ../usage/command.md
|
|
105
|
+
[dataflows]: dataflows.md
|
|
106
|
+
[patching]: patching.md
|