@fozy-labs/rx-toolkit 0.4.5 → 0.4.7
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/dist/query/core/Opertation/Operation.js +3 -0
- package/dist/query/core/Resource/Resource.d.ts +3 -0
- package/dist/query/core/Resource/Resource.js +34 -10
- package/dist/query/core/Resource/ResourceRef.js +2 -2
- package/dist/query/react/useResourceAgent.js +5 -9
- package/dist/query/react/useResourceRef.d.ts +1 -1
- package/dist/signals/react/useSignal.js +13 -2
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -41,6 +41,9 @@ export declare class Resource<D extends ResourceDefinition> implements ResourceI
|
|
|
41
41
|
}, options?: {
|
|
42
42
|
cache?: CoreResourceQueryCache<D>;
|
|
43
43
|
}): CoreResourceQueryCache<D> | null;
|
|
44
|
+
createWithData(args: D['Args'], data: D['Data'], options?: {
|
|
45
|
+
cache?: CoreResourceQueryCache<D>;
|
|
46
|
+
}): CoreResourceQueryCache<D>;
|
|
44
47
|
initiate(args: D['Args'], options?: {
|
|
45
48
|
cache?: CoreResourceQueryCache<D>;
|
|
46
49
|
}): CoreResourceQueryCache<D>;
|
|
@@ -24,6 +24,7 @@ class ResourceQueryState {
|
|
|
24
24
|
static load(state = ResourceQueryState.create(), args) {
|
|
25
25
|
return {
|
|
26
26
|
...state,
|
|
27
|
+
abortController: new AbortController(),
|
|
27
28
|
args: args,
|
|
28
29
|
isLoading: !state.isDone,
|
|
29
30
|
isReloading: state.isDone,
|
|
@@ -33,6 +34,7 @@ class ResourceQueryState {
|
|
|
33
34
|
static success(state, data) {
|
|
34
35
|
return {
|
|
35
36
|
...state,
|
|
37
|
+
abortController: null,
|
|
36
38
|
savedData: null,
|
|
37
39
|
transactions: null,
|
|
38
40
|
data,
|
|
@@ -47,6 +49,7 @@ class ResourceQueryState {
|
|
|
47
49
|
static error(state, error) {
|
|
48
50
|
return {
|
|
49
51
|
...state,
|
|
52
|
+
abortController: null,
|
|
50
53
|
isLoading: false,
|
|
51
54
|
isReloading: false,
|
|
52
55
|
isDone: true,
|
|
@@ -79,14 +82,22 @@ class ResourceQueryState {
|
|
|
79
82
|
data
|
|
80
83
|
};
|
|
81
84
|
}
|
|
82
|
-
|
|
83
|
-
* @deprecated
|
|
84
|
-
*/
|
|
85
|
-
static setData(state, data) {
|
|
85
|
+
static createWithData(data, args) {
|
|
86
86
|
return {
|
|
87
|
-
|
|
87
|
+
savedData: null,
|
|
88
88
|
transactions: null,
|
|
89
|
-
data
|
|
89
|
+
data,
|
|
90
|
+
isLoading: false,
|
|
91
|
+
isReloading: false,
|
|
92
|
+
isDone: true,
|
|
93
|
+
isSuccess: true,
|
|
94
|
+
isError: false,
|
|
95
|
+
error: null,
|
|
96
|
+
abortController: null,
|
|
97
|
+
args,
|
|
98
|
+
isInitiated: false,
|
|
99
|
+
isLocked: false,
|
|
100
|
+
lockCount: 0
|
|
90
101
|
};
|
|
91
102
|
}
|
|
92
103
|
}
|
|
@@ -155,8 +166,22 @@ export class Resource {
|
|
|
155
166
|
cache.next(ResourceQueryState.update(cache.value, data, savedData, transactions));
|
|
156
167
|
return cache;
|
|
157
168
|
}
|
|
169
|
+
createWithData(args, data, options) {
|
|
170
|
+
let cache = options?.cache ?? this.getQueryCache(args);
|
|
171
|
+
const state = ResourceQueryState.createWithData(data, args);
|
|
172
|
+
if (!cache) {
|
|
173
|
+
cache = this.createQueryCache(args, state);
|
|
174
|
+
// Только обновляем кэш новыми данными, если он еще не был инициализирован.
|
|
175
|
+
// Это предотвращает перезапись уже инициализированного кэша.
|
|
176
|
+
}
|
|
177
|
+
else if (!cache.value.isInitiated) {
|
|
178
|
+
cache.next(state);
|
|
179
|
+
}
|
|
180
|
+
return cache;
|
|
181
|
+
}
|
|
158
182
|
initiate(args, options) {
|
|
159
183
|
let cache = options?.cache ?? this.getQueryCache(args);
|
|
184
|
+
const prevAbortController = cache?.value.abortController ?? null;
|
|
160
185
|
const state = ResourceQueryState.load(cache?.value, args);
|
|
161
186
|
if (!cache) {
|
|
162
187
|
cache = this.createQueryCache(args, state);
|
|
@@ -164,9 +189,8 @@ export class Resource {
|
|
|
164
189
|
else {
|
|
165
190
|
cache.next(state);
|
|
166
191
|
}
|
|
167
|
-
|
|
168
|
-
abortController
|
|
169
|
-
abortController = new AbortController();
|
|
192
|
+
prevAbortController?.abort();
|
|
193
|
+
const abortController = state.abortController;
|
|
170
194
|
const query = this._options.queryFn(args, { abortSignal: abortController.signal });
|
|
171
195
|
const hookResolvers = this._hooks.onQueryStarted(args);
|
|
172
196
|
query
|
|
@@ -174,7 +198,7 @@ export class Resource {
|
|
|
174
198
|
if (abortController.signal.aborted) {
|
|
175
199
|
return;
|
|
176
200
|
}
|
|
177
|
-
const data = this._options.select ?
|
|
201
|
+
const data = this._options.select ? this._options.select(result) : result;
|
|
178
202
|
cache.next(ResourceQueryState.success(state, data));
|
|
179
203
|
hookResolvers.fulfilledSuccess(data);
|
|
180
204
|
})
|
|
@@ -128,9 +128,9 @@ export class ResourceRef {
|
|
|
128
128
|
return transaction;
|
|
129
129
|
}
|
|
130
130
|
create(data) {
|
|
131
|
-
|
|
131
|
+
this._cacheItem = this._resource.createWithData(this._args, data, { cache: this._cacheItem ?? undefined });
|
|
132
132
|
}
|
|
133
133
|
invalidate() {
|
|
134
|
-
|
|
134
|
+
this._cacheItem = this._resource.initiate(this._args, { cache: this._cacheItem ?? undefined });
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -5,6 +5,7 @@ import { shallowEqual } from "../../query/lib/shallowEqual";
|
|
|
5
5
|
import { SKIP } from "../../query/SKIP_TOKEN";
|
|
6
6
|
export function useResourceAgent(res, ...argss) {
|
|
7
7
|
const args = (argss[0] === SKIP ? SKIP : argss[0]);
|
|
8
|
+
const prevArgsRef = React.useRef(args);
|
|
8
9
|
const agent = useConstant(() => {
|
|
9
10
|
const agent = res.createAgent();
|
|
10
11
|
if (args !== SKIP) {
|
|
@@ -12,16 +13,11 @@ export function useResourceAgent(res, ...argss) {
|
|
|
12
13
|
}
|
|
13
14
|
return agent;
|
|
14
15
|
});
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
const state = agent.state$.peek();
|
|
20
|
-
if (state.isInitiated && shallowEqual(args, state.args)) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
16
|
+
const state = agent.state$.peek();
|
|
17
|
+
if (state.isInitiated && args !== SKIP && !shallowEqual(args, prevArgsRef.current)) {
|
|
18
|
+
prevArgsRef.current = args;
|
|
23
19
|
agent.initiate(args);
|
|
24
|
-
}
|
|
20
|
+
}
|
|
25
21
|
React.useEffect(() => () => {
|
|
26
22
|
agent.complete();
|
|
27
23
|
}, []);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SKIP } from "../../query/SKIP_TOKEN";
|
|
2
2
|
import type { Prettify, ResourceDefinition, ResourceInstance, ResourceRefInstanse } from "../../query/types";
|
|
3
|
-
type Result<D extends ResourceDefinition> = Prettify<ResourceRefInstanse<D
|
|
3
|
+
type Result<D extends ResourceDefinition> = Prettify<ResourceRefInstanse<D>>;
|
|
4
4
|
export declare function useResourceRef<D extends ResourceDefinition>(res: ResourceInstance<D>, ...argss: D['Args'] extends void ? [] | [typeof SKIP] : [D['Args'] | typeof SKIP]): Result<D>;
|
|
5
5
|
export {};
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { useEventHandler } from "../../common/react";
|
|
3
3
|
export function useSignal(signal$) {
|
|
4
|
+
const doUpdateRef = React.useRef(false);
|
|
4
5
|
const subscribe = React.useCallback((update) => {
|
|
5
|
-
const subscription = signal$.subscribe(
|
|
6
|
+
const subscription = signal$.subscribe(() => {
|
|
7
|
+
doUpdateRef.current = true;
|
|
8
|
+
queueMicrotask(() => {
|
|
9
|
+
if (!doUpdateRef.current)
|
|
10
|
+
return;
|
|
11
|
+
update();
|
|
12
|
+
});
|
|
13
|
+
});
|
|
6
14
|
return () => {
|
|
7
15
|
subscription.unsubscribe();
|
|
8
16
|
};
|
|
9
17
|
}, [signal$]);
|
|
10
|
-
const getSnapshot = useEventHandler(() =>
|
|
18
|
+
const getSnapshot = useEventHandler(() => {
|
|
19
|
+
doUpdateRef.current = false;
|
|
20
|
+
return signal$.peek();
|
|
21
|
+
});
|
|
11
22
|
return React.useSyncExternalStore(subscribe, getSnapshot);
|
|
12
23
|
}
|