@fozy-labs/rx-toolkit 0.5.3-rc.0 → 0.5.3-rc.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/README.md +3 -3
- package/dist/query/api/createCommand.d.ts +21 -0
- package/dist/query/api/createCommand.js +20 -0
- package/dist/query/api/createOperation.d.ts +5 -3
- package/dist/query/api/createOperation.js +6 -2
- package/dist/query/core/Command/Command.d.ts +35 -0
- package/dist/query/core/Command/Command.js +210 -0
- package/dist/query/core/Command/CommandAgent.d.ts +19 -0
- package/dist/query/core/Command/CommandAgent.js +54 -0
- package/dist/query/core/Command/index.d.ts +2 -0
- package/dist/query/core/Command/index.js +2 -0
- package/dist/query/core/Opertation/Operation.d.ts +8 -35
- package/dist/query/core/Opertation/Operation.js +4 -211
- package/dist/query/core/Opertation/OperationAgent.d.ts +4 -19
- package/dist/query/core/Opertation/OperationAgent.js +4 -54
- package/dist/query/core/Resource/ResourceAgent.js +1 -1
- package/dist/query/core/Resource/ResourceDuplicatorAgent.js +1 -1
- package/dist/query/index.d.ts +4 -2
- package/dist/query/index.js +7 -2
- package/dist/query/react/useCommandAgent.d.ts +24 -0
- package/dist/query/react/useCommandAgent.js +39 -0
- package/dist/query/react/useOperationAgent.d.ts +6 -8
- package/dist/query/react/useOperationAgent.js +6 -23
- package/dist/query/types/Command.types.d.ts +154 -0
- package/dist/query/types/Command.types.js +1 -0
- package/dist/query/types/Operation.types.d.ts +13 -154
- package/dist/query/types/index.d.ts +2 -1
- package/dist/query/types/index.js +3 -1
- package/dist/signals/signals/Computed.d.ts +1 -1
- package/dist/signals/signals/Computed.js +7 -7
- package/dist/signals/signals/LocalState.d.ts +45 -0
- package/dist/signals/signals/LocalState.js +122 -0
- package/dist/signals/signals/Signal.d.ts +6 -12
- package/dist/signals/signals/Signal.js +9 -50
- package/dist/signals/signals/State.d.ts +15 -0
- package/dist/signals/signals/State.js +54 -0
- package/dist/signals/signals/index.d.ts +2 -1
- package/dist/signals/signals/index.js +3 -1
- package/dist/signals/types/signals.types.d.ts +5 -0
- package/docs/CHANGELOG.md +76 -18
- package/docs/devtools/README.md +4 -4
- package/docs/options/README.md +4 -2
- package/docs/query/README.md +34 -32
- package/docs/signals/README.md +29 -24
- package/docs/usage/react/README.md +17 -15
- package/package.json +1 -1
- package/dist/signals/signals/LocalSignal.d.ts +0 -32
- package/dist/signals/signals/LocalSignal.js +0 -88
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
private _operations$;
|
|
6
|
-
state$: import("../../../signals/types").ComputeFn<{
|
|
7
|
-
isLoading: boolean;
|
|
8
|
-
isDone: boolean;
|
|
9
|
-
isSuccess: boolean;
|
|
10
|
-
isError: boolean;
|
|
11
|
-
error: {} | undefined;
|
|
12
|
-
data: NonNullable<import("../../../query/types").FallbackOnNever<D["Selected"], D["Result"]>> | undefined;
|
|
13
|
-
args: D["Args"];
|
|
14
|
-
}>;
|
|
15
|
-
constructor(_operation: Operation<D>);
|
|
16
|
-
private _next;
|
|
17
|
-
initiate(args: D["Args"]): void;
|
|
18
|
-
createAgent(): OperationAgentInstanse<D>;
|
|
19
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Use `CommandAgent` from '../Command/CommandAgent' instead. Will be removed in v0.6.0.
|
|
3
|
+
*/
|
|
4
|
+
export { CommandAgent as OperationAgent } from '../Command/CommandAgent';
|
|
@@ -1,54 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
current$: null,
|
|
6
|
-
}, { isDisabled: true });
|
|
7
|
-
state$ = Computed.create(() => {
|
|
8
|
-
const operations = this._operations$.get();
|
|
9
|
-
const currState = operations.current$?.value$.get();
|
|
10
|
-
// Нет текущего состояния — дефолт
|
|
11
|
-
if (!currState) {
|
|
12
|
-
return {
|
|
13
|
-
isLoading: false,
|
|
14
|
-
isDone: false,
|
|
15
|
-
isSuccess: false,
|
|
16
|
-
isError: false,
|
|
17
|
-
error: undefined,
|
|
18
|
-
data: undefined,
|
|
19
|
-
args: undefined,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
isLoading: currState.isLoading,
|
|
24
|
-
isDone: currState.isDone,
|
|
25
|
-
isSuccess: currState.isSuccess,
|
|
26
|
-
isError: currState.isError,
|
|
27
|
-
error: currState.error ?? undefined,
|
|
28
|
-
data: currState.data ?? undefined,
|
|
29
|
-
args: currState.arg,
|
|
30
|
-
};
|
|
31
|
-
}, { isDisabled: true });
|
|
32
|
-
constructor(_operation) {
|
|
33
|
-
this._operation = _operation;
|
|
34
|
-
}
|
|
35
|
-
_next(newCache) {
|
|
36
|
-
this._operations$.set({
|
|
37
|
-
current$: newCache,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
initiate(args) {
|
|
41
|
-
const cache = this._operation.getQueryCache(args);
|
|
42
|
-
if (!cache) {
|
|
43
|
-
const newCache = this._operation.initiate(args);
|
|
44
|
-
this._next(newCache);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// Всегда запускаем операцию заново, так как операции обычно не кэшируются как ресурсы
|
|
48
|
-
const newCache = this._operation.initiate(args, { cache });
|
|
49
|
-
this._next(newCache);
|
|
50
|
-
}
|
|
51
|
-
createAgent() {
|
|
52
|
-
return new OperationAgent(this._operation);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Use `CommandAgent` from '../Command/CommandAgent' instead. Will be removed in v0.6.0.
|
|
3
|
+
*/
|
|
4
|
+
export { CommandAgent as OperationAgent } from '../Command/CommandAgent';
|
package/dist/query/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export * from './api/createCommand';
|
|
2
|
+
export * from './react/useCommandAgent';
|
|
1
3
|
export * from './api/createResource';
|
|
2
|
-
export * from './api/createOperation';
|
|
3
|
-
export * from './api/resetAllQueriesCache';
|
|
4
4
|
export * from './api/createResourceDuplicator';
|
|
5
|
+
export * from './api/resetAllQueriesCache';
|
|
5
6
|
export * from './SKIP_TOKEN';
|
|
6
7
|
export * from './react/useResourceAgent';
|
|
7
8
|
export * from './react/useResourceRef';
|
|
9
|
+
export * from './api/createOperation';
|
|
8
10
|
export * from './react/useOperationAgent';
|
package/dist/query/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
// Command API
|
|
2
|
+
export * from './api/createCommand';
|
|
3
|
+
export * from './react/useCommandAgent';
|
|
4
|
+
// Resource API
|
|
1
5
|
export * from './api/createResource';
|
|
2
|
-
export * from './api/createOperation';
|
|
3
|
-
export * from './api/resetAllQueriesCache';
|
|
4
6
|
export * from './api/createResourceDuplicator';
|
|
7
|
+
export * from './api/resetAllQueriesCache';
|
|
5
8
|
export * from './SKIP_TOKEN';
|
|
6
9
|
export * from './react/useResourceAgent';
|
|
7
10
|
export * from './react/useResourceRef';
|
|
11
|
+
// Deprecated Operation API (backward compatibility)
|
|
12
|
+
export * from './api/createOperation';
|
|
8
13
|
export * from './react/useOperationAgent';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Prettify, CommandAgentInstance, CommandDefinition, CommandQueryState } from "../../query/types";
|
|
2
|
+
type WithAgent<D extends CommandDefinition> = {
|
|
3
|
+
createAgent: () => CommandAgentInstance<D>;
|
|
4
|
+
};
|
|
5
|
+
type TriggerFn<D extends CommandDefinition> = (args: D['Args']) => Promise<D['Data']>;
|
|
6
|
+
type Result<D extends CommandDefinition> = [TriggerFn<D>, Prettify<CommandQueryState<D>>];
|
|
7
|
+
/**
|
|
8
|
+
* React hook для работы с командой (Command).
|
|
9
|
+
*
|
|
10
|
+
* Возвращает кортеж `[trigger, state]`:
|
|
11
|
+
* - `trigger(args)` — инициирует выполнение команды и возвращает Promise с результатом.
|
|
12
|
+
* - `state` — реактивное состояние выполнения команды.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const [updateUser, state] = useCommandAgent(api.updateUser);
|
|
17
|
+
*
|
|
18
|
+
* const handleSubmit = async () => {
|
|
19
|
+
* const result = await updateUser({ id: 1, name: 'New Name' });
|
|
20
|
+
* };
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function useCommandAgent<D extends CommandDefinition>(op: WithAgent<D>): Result<D>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useConstant, useEventHandler } from "../../common/react";
|
|
2
|
+
import { useSignal } from "../../signals/react";
|
|
3
|
+
/**
|
|
4
|
+
* React hook для работы с командой (Command).
|
|
5
|
+
*
|
|
6
|
+
* Возвращает кортеж `[trigger, state]`:
|
|
7
|
+
* - `trigger(args)` — инициирует выполнение команды и возвращает Promise с результатом.
|
|
8
|
+
* - `state` — реактивное состояние выполнения команды.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const [updateUser, state] = useCommandAgent(api.updateUser);
|
|
13
|
+
*
|
|
14
|
+
* const handleSubmit = async () => {
|
|
15
|
+
* const result = await updateUser({ id: 1, name: 'New Name' });
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function useCommandAgent(op) {
|
|
20
|
+
const agent = useConstant(() => op.createAgent());
|
|
21
|
+
const state = useSignal(agent.state$);
|
|
22
|
+
const trigger = useEventHandler((args) => {
|
|
23
|
+
agent.initiate(args);
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const sub = agent.state$.obs.subscribe((s) => {
|
|
26
|
+
if (s.isDone && !s.isLoading) {
|
|
27
|
+
sub.unsubscribe();
|
|
28
|
+
if (s.isSuccess) {
|
|
29
|
+
resolve(s.data);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
reject(s.error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
return [trigger, state];
|
|
39
|
+
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export declare function useOperationAgent<D extends OperationDefinition>(op: WithAgent<D>): Result<D>;
|
|
8
|
-
export {};
|
|
1
|
+
import { useCommandAgent } from './useCommandAgent';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated Use `useCommandAgent` instead. Will be removed in v0.6.0.
|
|
4
|
+
* @see useCommandAgent
|
|
5
|
+
*/
|
|
6
|
+
export declare const useOperationAgent: typeof useCommandAgent;
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
agent.initiate(args);
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
const sub = agent.state$.obs.subscribe((s) => {
|
|
10
|
-
if (s.isDone && !s.isLoading) {
|
|
11
|
-
sub.unsubscribe();
|
|
12
|
-
if (s.isSuccess) {
|
|
13
|
-
resolve(s.data);
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
reject(s.error);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
return [trigger, state];
|
|
23
|
-
}
|
|
1
|
+
import { useCommandAgent } from './useCommandAgent';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated Use `useCommandAgent` instead. Will be removed in v0.6.0.
|
|
4
|
+
* @see useCommandAgent
|
|
5
|
+
*/
|
|
6
|
+
export const useOperationAgent = useCommandAgent;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { ReadableSignalLike } from "../../signals/types";
|
|
2
|
+
import { FallbackOnNever, OnCacheEntryAdded, OnQueryStarted } from "./shared.types";
|
|
3
|
+
import { ResourceDefinition, ResourceInstance } from "./Resource.types";
|
|
4
|
+
/**
|
|
5
|
+
* Функция создания команды
|
|
6
|
+
*/
|
|
7
|
+
export type CommandCreateFn<ARGS, RESULT, SELECTED = never> = (options: CommandCreateOptions<CommandDefinition<ARGS, RESULT, SELECTED>>) => CommandInstance<CommandDefinition<ARGS, RESULT, SELECTED>>;
|
|
8
|
+
/**
|
|
9
|
+
* Опции создания команды
|
|
10
|
+
*/
|
|
11
|
+
export type CommandCreateOptions<D extends CommandDefinition> = {
|
|
12
|
+
/** Функция селектора для преобразования результата команды */
|
|
13
|
+
select?: (data: D["Result"]) => D["Selected"];
|
|
14
|
+
/** Функция выполнения команды */
|
|
15
|
+
queryFn: (args: D["Args"]) => Promise<D["Result"]>;
|
|
16
|
+
/** Связанные ресурсы */
|
|
17
|
+
link?: (link: <RD extends ResourceDefinition>(options: LinkOptions<D, RD>) => void) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Время жизни кеша в миллисекундах. По умолчанию 1_000 (1 секунда).
|
|
20
|
+
* Если указано false - кеш не удаляется автоматически.
|
|
21
|
+
*/
|
|
22
|
+
cacheLifetime?: number | false;
|
|
23
|
+
/**
|
|
24
|
+
* Хук, вызываемый при добавлении нового элемента в кеш.
|
|
25
|
+
* Также позволяет отследить:
|
|
26
|
+
* - когда данные были загружены (впервые)
|
|
27
|
+
* - когда элемент был удален из кеша
|
|
28
|
+
*/
|
|
29
|
+
onCacheEntryAdded?: OnCacheEntryAdded<D["Args"], D["Data"]>;
|
|
30
|
+
/**
|
|
31
|
+
* Хук, вызываемый при старте запроса.
|
|
32
|
+
* Также позволяет отследить:
|
|
33
|
+
* - завершение запроса с результатом или ошибкой
|
|
34
|
+
*/
|
|
35
|
+
onQueryStarted?: OnQueryStarted<D["Args"], D["Result"]>;
|
|
36
|
+
/**
|
|
37
|
+
* Настройка отображения в devtools
|
|
38
|
+
*/
|
|
39
|
+
devtoolsName?: string | false;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Настройки связи команды с ресурсом
|
|
43
|
+
*/
|
|
44
|
+
export type LinkOptions<D extends CommandDefinition, RD extends ResourceDefinition> = {
|
|
45
|
+
/**
|
|
46
|
+
* Целевой ресурс, с которым связывается команда
|
|
47
|
+
* @required
|
|
48
|
+
*/
|
|
49
|
+
resource: ResourceInstance<RD>;
|
|
50
|
+
/**
|
|
51
|
+
* Функция для получения аргументов ресурса из аргументов команды.
|
|
52
|
+
* Используется для определения какой именно элемент в кэше ресурса нужно обновить
|
|
53
|
+
* @required
|
|
54
|
+
*/
|
|
55
|
+
forwardArgs: (args: D["Args"]) => RD["Args"];
|
|
56
|
+
/**
|
|
57
|
+
* Флаг для инвалидации (очистки) кэша ресурса после выполнения команды.
|
|
58
|
+
* При true - кэш будет очищен и ресурс будет перезагружен при следующем обращении
|
|
59
|
+
* @optional @default false
|
|
60
|
+
*/
|
|
61
|
+
invalidate?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Флаг для блокировки ресурса во время выполнения команды.
|
|
64
|
+
* При true - ресурс будет заблокирован и не сможет выполнять новые запросы
|
|
65
|
+
* @optional @default false
|
|
66
|
+
*/
|
|
67
|
+
lock?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Функция для обновления кэша ресурса после успешного выполнения команды.
|
|
70
|
+
* Получает draft объект для мутации, аргументы команды и результат команды
|
|
71
|
+
* @optional
|
|
72
|
+
*/
|
|
73
|
+
update?: (tools: {
|
|
74
|
+
/** Immer draft объект для мутации кэша ресурса */
|
|
75
|
+
draft: RD["Data"];
|
|
76
|
+
/** Аргументы, с которыми была вызвана команда */
|
|
77
|
+
args: D["Args"];
|
|
78
|
+
/** Результат выполнения команды */
|
|
79
|
+
data: D["Data"];
|
|
80
|
+
}) => void | RD["Data"] | Promise<RD["Data"]>;
|
|
81
|
+
/**
|
|
82
|
+
* Функция для оптимистичного обновления кэша ресурса ДО выполнения команды.
|
|
83
|
+
* Позволяет обновить UI немедленно, до получения ответа от сервера
|
|
84
|
+
* @optional
|
|
85
|
+
*/
|
|
86
|
+
optimisticUpdate?: (tools: {
|
|
87
|
+
/** Immer draft объект для мутации кэша ресурса */
|
|
88
|
+
draft: RD["Data"];
|
|
89
|
+
/** Аргументы, с которыми была вызвана команда */
|
|
90
|
+
args: D["Args"];
|
|
91
|
+
}) => void | RD["Data"] | Promise<RD["Data"]>;
|
|
92
|
+
/**
|
|
93
|
+
* Функция для создания нового элемента в кэше ресурса.
|
|
94
|
+
* Используется когда команда создает новую сущность, которую нужно добавить в кэш
|
|
95
|
+
* @optional
|
|
96
|
+
*/
|
|
97
|
+
create?: (tools: {
|
|
98
|
+
/** Аргументы, с которыми была вызвана команда */
|
|
99
|
+
args: D["Args"];
|
|
100
|
+
/** Результат выполнения команды */
|
|
101
|
+
data: D["Data"];
|
|
102
|
+
}) => RD["Data"] | Promise<RD["Data"]>;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Определение типов команды
|
|
106
|
+
*/
|
|
107
|
+
export type CommandDefinition<A = any, R = any, S = any> = {
|
|
108
|
+
Args: A;
|
|
109
|
+
Result: R;
|
|
110
|
+
Selected: S;
|
|
111
|
+
Data: FallbackOnNever<S, R>;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Экземпляр команды
|
|
115
|
+
*/
|
|
116
|
+
export type CommandInstance<D extends CommandDefinition> = {
|
|
117
|
+
/** Создает агента для выполнения команды */
|
|
118
|
+
createAgent(): CommandAgentInstance<D>;
|
|
119
|
+
/**
|
|
120
|
+
* Выполняет команду с указанными аргументами
|
|
121
|
+
* @deprecated
|
|
122
|
+
*/
|
|
123
|
+
mutate: (args: D["Args"]) => Promise<D["Data"]>;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Агент для выполнения команды
|
|
127
|
+
*/
|
|
128
|
+
export type CommandAgentInstance<D extends CommandDefinition> = {
|
|
129
|
+
/** Observable состояния выполнения команды */
|
|
130
|
+
state$: ReadableSignalLike<CommandQueryState<D>>;
|
|
131
|
+
/** Инициирует выполнение команды с указанными аргументами */
|
|
132
|
+
initiate(args: D["Args"]): void;
|
|
133
|
+
/** Создает новый агент команды */
|
|
134
|
+
createAgent(): CommandAgentInstance<D>;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Состояние выполнения команды
|
|
138
|
+
*/
|
|
139
|
+
export type CommandQueryState<D extends CommandDefinition> = {
|
|
140
|
+
/** Выполняется ли команда в данный момент */
|
|
141
|
+
isLoading: boolean;
|
|
142
|
+
/** Завершена ли команда */
|
|
143
|
+
isDone: boolean;
|
|
144
|
+
/** Успешно ли завершена команда (false по умолчанию) */
|
|
145
|
+
isSuccess: boolean;
|
|
146
|
+
/** Произошла ли ошибка при выполнении команды (false по умолчанию) */
|
|
147
|
+
isError: boolean;
|
|
148
|
+
/** Оригинал ошибки, если есть */
|
|
149
|
+
error: unknown | undefined;
|
|
150
|
+
/** Результат выполнения команды */
|
|
151
|
+
data: D["Data"] | undefined;
|
|
152
|
+
/** Аргументы команды */
|
|
153
|
+
args: D["Args"];
|
|
154
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,154 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
*/
|
|
7
|
-
export type
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export type
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/** Функция выполнения операции */
|
|
15
|
-
queryFn: (args: D["Args"]) => Promise<D["Result"]>;
|
|
16
|
-
/** Связанные ресурсы */
|
|
17
|
-
link?: (link: <RD extends ResourceDefinition>(options: LinkOptions<D, RD>) => void) => void;
|
|
18
|
-
/**
|
|
19
|
-
* Время жизни кеша в миллисекундах. По умолчанию 1_000 (1 секунда).
|
|
20
|
-
* Если указано false - кеш не удаляется автоматически.
|
|
21
|
-
*/
|
|
22
|
-
cacheLifetime?: number | false;
|
|
23
|
-
/**
|
|
24
|
-
* Хук, вызываемый при добавлении нового элемента в кеш.
|
|
25
|
-
* Также позволяет отследить:
|
|
26
|
-
* - когда данные были загружены (впервые)
|
|
27
|
-
* - когда элемент был удален из кеша
|
|
28
|
-
*/
|
|
29
|
-
onCacheEntryAdded?: OnCacheEntryAdded<D["Args"], D["Data"]>;
|
|
30
|
-
/**
|
|
31
|
-
* Хук, вызываемый при старте запроса.
|
|
32
|
-
* Также позволяет отследить:
|
|
33
|
-
* - завершение запроса с результатом или ошибкой
|
|
34
|
-
*/
|
|
35
|
-
onQueryStarted?: OnQueryStarted<D["Args"], D["Result"]>;
|
|
36
|
-
/**
|
|
37
|
-
* Настройка отображения в devtools
|
|
38
|
-
*/
|
|
39
|
-
devtoolsName?: string | false;
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Настройки связи операции с ресурсом
|
|
43
|
-
*/
|
|
44
|
-
export type LinkOptions<D extends OperationDefinition, RD extends ResourceDefinition> = {
|
|
45
|
-
/**
|
|
46
|
-
* Целевой ресурс, с которым связывается операция
|
|
47
|
-
* @required
|
|
48
|
-
*/
|
|
49
|
-
resource: ResourceInstance<RD>;
|
|
50
|
-
/**
|
|
51
|
-
* Функция для получения аргументов ресурса из аргументов операции.
|
|
52
|
-
* Используется для определения какой именно элемент в кэше ресурса нужно обновить
|
|
53
|
-
* @required
|
|
54
|
-
*/
|
|
55
|
-
forwardArgs: (args: D["Args"]) => RD["Args"];
|
|
56
|
-
/**
|
|
57
|
-
* Флаг для инвалидации (очистки) кэша ресурса после выполнения операции.
|
|
58
|
-
* При true - кэш будет очищен и ресурс будет перезагружен при следующем обращении
|
|
59
|
-
* @optional @default false
|
|
60
|
-
*/
|
|
61
|
-
invalidate?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Флаг для блокировки ресурса во время выполнения операции.
|
|
64
|
-
* При true - ресурс будет заблокирован и не сможет выполнять новые запросы
|
|
65
|
-
* @optional @default false
|
|
66
|
-
*/
|
|
67
|
-
lock?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Функция для обновления кэша ресурса после успешного выполнения операции.
|
|
70
|
-
* Получает draft объект для мутации, аргументы операции и результат операции
|
|
71
|
-
* @optional
|
|
72
|
-
*/
|
|
73
|
-
update?: (tools: {
|
|
74
|
-
/** Immer draft объект для мутации кэша ресурса */
|
|
75
|
-
draft: RD["Data"];
|
|
76
|
-
/** Аргументы, с которыми была вызвана операция */
|
|
77
|
-
args: D["Args"];
|
|
78
|
-
/** Результат выполнения операции */
|
|
79
|
-
data: D["Data"];
|
|
80
|
-
}) => void | RD["Data"] | Promise<RD["Data"]>;
|
|
81
|
-
/**
|
|
82
|
-
* Функция для оптимистичного обновления кэша ресурса ДО выполнения операции.
|
|
83
|
-
* Позволяет обновить UI немедленно, до получения ответа от сервера
|
|
84
|
-
* @optional
|
|
85
|
-
*/
|
|
86
|
-
optimisticUpdate?: (tools: {
|
|
87
|
-
/** Immer draft объект для мутации кэша ресурса */
|
|
88
|
-
draft: RD["Data"];
|
|
89
|
-
/** Аргументы, с которыми была вызвана операция */
|
|
90
|
-
args: D["Args"];
|
|
91
|
-
}) => void | RD["Data"] | Promise<RD["Data"]>;
|
|
92
|
-
/**
|
|
93
|
-
* Функция для создания нового элемента в кэше ресурса.
|
|
94
|
-
* Используется когда операция создает новую сущность, которую нужно добавить в кэш
|
|
95
|
-
* @optional
|
|
96
|
-
*/
|
|
97
|
-
create?: (tools: {
|
|
98
|
-
/** Аргументы, с которыми была вызвана операция */
|
|
99
|
-
args: D["Args"];
|
|
100
|
-
/** Результат выполнения операции */
|
|
101
|
-
data: D["Data"];
|
|
102
|
-
}) => RD["Data"] | Promise<RD["Data"]>;
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Определение типов операции
|
|
106
|
-
*/
|
|
107
|
-
export type OperationDefinition<A = any, R = any, S = any> = {
|
|
108
|
-
Args: A;
|
|
109
|
-
Result: R;
|
|
110
|
-
Selected: S;
|
|
111
|
-
Data: FallbackOnNever<S, R>;
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* Экземпляр операции
|
|
115
|
-
*/
|
|
116
|
-
export type OperationInstance<D extends OperationDefinition> = {
|
|
117
|
-
/** Создает агента для выполнения операции */
|
|
118
|
-
createAgent(): OperationAgentInstanse<D>;
|
|
119
|
-
/**
|
|
120
|
-
* Выполняет операцию с указанными аргументами
|
|
121
|
-
* @deprecated
|
|
122
|
-
*/
|
|
123
|
-
mutate: (args: D["Args"]) => Promise<D["Data"]>;
|
|
124
|
-
};
|
|
125
|
-
/**
|
|
126
|
-
* Агент для выполнения операции
|
|
127
|
-
*/
|
|
128
|
-
export type OperationAgentInstanse<D extends OperationDefinition> = {
|
|
129
|
-
/** Observable состояния выполнения операции */
|
|
130
|
-
state$: ReadableSignalLike<OperationQueryState<D>>;
|
|
131
|
-
/** Инициирует выполнение операции с указанными аргументами */
|
|
132
|
-
initiate(args: D["Args"]): void;
|
|
133
|
-
/** Создает новый агент операции */
|
|
134
|
-
createAgent(): OperationAgentInstanse<D>;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Состояние выполнения операции
|
|
138
|
-
*/
|
|
139
|
-
export type OperationQueryState<D extends OperationDefinition> = {
|
|
140
|
-
/** Выполняется ли операция в данный момент */
|
|
141
|
-
isLoading: boolean;
|
|
142
|
-
/** Завершена ли операция */
|
|
143
|
-
isDone: boolean;
|
|
144
|
-
/** Успешно ли завершена операция (false по умолчанию) */
|
|
145
|
-
isSuccess: boolean;
|
|
146
|
-
/** Произошла ли ошибка при выполнении операции (false по умолчанию) */
|
|
147
|
-
isError: boolean;
|
|
148
|
-
/** Оригинал ошибки, если есть */
|
|
149
|
-
error: unknown | undefined;
|
|
150
|
-
/** Результат выполнения операции */
|
|
151
|
-
data: D["Data"] | undefined;
|
|
152
|
-
/** Аргументы операции */
|
|
153
|
-
args: D["Args"];
|
|
154
|
-
};
|
|
1
|
+
import { CommandCreateFn, CommandCreateOptions, CommandDefinition, CommandInstance, CommandAgentInstance, CommandQueryState } from './Command.types';
|
|
2
|
+
/** @deprecated Use `CommandCreateFn` instead. Will be removed in v0.6.0. */
|
|
3
|
+
export type OperationCreateFn<ARGS, RESULT, SELECTED = never> = CommandCreateFn<ARGS, RESULT, SELECTED>;
|
|
4
|
+
/** @deprecated Use `CommandCreateOptions` instead. Will be removed in v0.6.0. */
|
|
5
|
+
export type OperationCreateOptions<D extends CommandDefinition> = CommandCreateOptions<D>;
|
|
6
|
+
/** @deprecated Use `CommandDefinition` instead. Will be removed in v0.6.0. */
|
|
7
|
+
export type OperationDefinition<A = any, R = any, S = any> = CommandDefinition<A, R, S>;
|
|
8
|
+
/** @deprecated Use `CommandInstance` instead. Will be removed in v0.6.0. */
|
|
9
|
+
export type OperationInstance<D extends CommandDefinition> = CommandInstance<D>;
|
|
10
|
+
/** @deprecated Use `CommandAgentInstance` instead. Will be removed in v0.6.0. */
|
|
11
|
+
export type OperationAgentInstanse<D extends CommandDefinition> = CommandAgentInstance<D>;
|
|
12
|
+
/** @deprecated Use `CommandQueryState` instead. Will be removed in v0.6.0. */
|
|
13
|
+
export type OperationQueryState<D extends CommandDefinition> = CommandQueryState<D>;
|
|
@@ -2,7 +2,7 @@ import { StateDevtoolsOptions } from "../../common/devtools";
|
|
|
2
2
|
import { ComputeFn } from "../../signals/types";
|
|
3
3
|
export declare class Computed<T> {
|
|
4
4
|
private _computeFn;
|
|
5
|
-
private
|
|
5
|
+
private _state$;
|
|
6
6
|
readonly obs: import("rxjs").Observable<T>;
|
|
7
7
|
private _effect;
|
|
8
8
|
/**
|
|
@@ -4,7 +4,7 @@ import { Effect } from "./Effect";
|
|
|
4
4
|
import { Signal } from "./Signal";
|
|
5
5
|
export class Computed {
|
|
6
6
|
_computeFn;
|
|
7
|
-
|
|
7
|
+
_state$;
|
|
8
8
|
obs;
|
|
9
9
|
_effect = null;
|
|
10
10
|
/**
|
|
@@ -18,8 +18,8 @@ export class Computed {
|
|
|
18
18
|
...(typeof options === 'string' ? { name: options } : options),
|
|
19
19
|
_skipValues: [Computed._EMPTY],
|
|
20
20
|
};
|
|
21
|
-
this.
|
|
22
|
-
this.obs = this.
|
|
21
|
+
this._state$ = Signal.state(Computed._EMPTY, lsOptions);
|
|
22
|
+
this.obs = this._state$.obs.pipe(map((value) => {
|
|
23
23
|
if (value === Computed._EMPTY) {
|
|
24
24
|
return this._start();
|
|
25
25
|
}
|
|
@@ -46,7 +46,7 @@ export class Computed {
|
|
|
46
46
|
return this.peek();
|
|
47
47
|
}
|
|
48
48
|
peek() {
|
|
49
|
-
const v = this.
|
|
49
|
+
const v = this._state$.peek();
|
|
50
50
|
if (v === Computed._EMPTY) {
|
|
51
51
|
// Используем кеш для вычисления без создания подписки
|
|
52
52
|
return this._computeCache.getOrCompute(this._computeFn);
|
|
@@ -58,10 +58,10 @@ export class Computed {
|
|
|
58
58
|
this._effect = new Effect(() => {
|
|
59
59
|
if (initialValue === Computed._EMPTY) {
|
|
60
60
|
initialValue = this._computeFn();
|
|
61
|
-
this.
|
|
61
|
+
this._state$.set(initialValue);
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
this.
|
|
64
|
+
this._state$.set(this._computeFn());
|
|
65
65
|
});
|
|
66
66
|
this._computeCache.clear();
|
|
67
67
|
if (initialValue === Computed._EMPTY) {
|
|
@@ -74,7 +74,7 @@ export class Computed {
|
|
|
74
74
|
this._effect.unsubscribe();
|
|
75
75
|
this._effect = null;
|
|
76
76
|
}
|
|
77
|
-
this.
|
|
77
|
+
this._state$.set(Computed._EMPTY);
|
|
78
78
|
}
|
|
79
79
|
// === static ===
|
|
80
80
|
static _EMPTY = Symbol('empty');
|