@fozy-labs/rx-toolkit 0.4.2 → 0.4.4
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 +4 -5
- package/dist/{devtools → common/devtools}/combineDevtools.d.ts +1 -1
- package/dist/{devtools → common/devtools}/index.d.ts +1 -0
- package/dist/{devtools → common/devtools}/index.js +1 -0
- package/dist/common/devtools/reduxDevtools.d.ts +16 -0
- package/dist/{devtools → common/devtools}/reduxDevtools.js +7 -4
- package/dist/{query/api → common/options}/DefaultOptions.d.ts +1 -1
- package/dist/{query/api → common/options}/DefaultOptions.js +1 -1
- package/dist/{query/core → common/options}/SharedOptions.d.ts +1 -1
- package/dist/common/options/index.d.ts +1 -0
- package/dist/common/options/index.js +1 -0
- package/dist/{react-hooks → common/react}/index.d.ts +2 -3
- package/dist/{react-hooks → common/react}/index.js +2 -3
- package/dist/{react-hooks → common/react}/useObservable.js +2 -2
- package/dist/{react-hooks → common/react}/useSyncObservable.js +2 -1
- package/dist/common/utils/PromiseResolver.d.ts +7 -0
- package/dist/common/utils/PromiseResolver.js +14 -0
- package/dist/common/utils/index.d.ts +1 -0
- package/dist/common/utils/index.js +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/query/api/createOperation.d.ts +1 -5
- package/dist/query/api/createOperation.js +0 -4
- package/dist/query/api/createResource.d.ts +1 -1
- package/dist/query/core/Opertation/Operation.d.ts +2 -3
- package/dist/query/core/Opertation/Operation.js +6 -18
- package/dist/query/core/Opertation/OperationAgent.d.ts +2 -2
- package/dist/query/core/Opertation/OperationAgent.js +1 -1
- package/dist/query/core/QueriesCache.d.ts +2 -1
- package/dist/query/core/QueriesCache.js +19 -16
- package/dist/query/core/Resource/Resource.d.ts +3 -9
- package/dist/query/core/Resource/Resource.js +79 -26
- package/dist/query/core/Resource/ResourceAgent.d.ts +2 -2
- package/dist/query/core/Resource/ResourceAgent.js +5 -4
- package/dist/query/core/Resource/ResourceRef.d.ts +1 -4
- package/dist/query/core/Resource/ResourceRef.js +10 -20
- package/dist/query/index.d.ts +0 -1
- package/dist/query/index.js +0 -1
- package/dist/query/lib/IndirectMap.js +1 -1
- package/dist/query/lib/ReactiveCache.d.ts +6 -22
- package/dist/query/lib/ReactiveCache.js +19 -39
- package/dist/query/react/useOperationAgent.d.ts +1 -2
- package/dist/query/react/useOperationAgent.js +2 -1
- package/dist/query/react/useResourceAgent.d.ts +3 -7
- package/dist/query/react/useResourceAgent.js +7 -3
- package/dist/query/react/useResourceRef.d.ts +1 -2
- package/dist/query/react/useResourceRef.js +1 -1
- package/dist/query/types/Operation.types.d.ts +1 -1
- package/dist/query/types/Resource.types.d.ts +29 -10
- package/dist/query/types/index.d.ts +3 -0
- package/dist/query/types/index.js +3 -0
- package/dist/signals/base/Computed.js +1 -2
- package/dist/signals/base/Effect.js +3 -2
- package/dist/signals/base/ReadonlySignal.d.ts +2 -3
- package/dist/signals/base/ReadonlySignal.js +2 -11
- package/dist/signals/base/Signal.d.ts +2 -2
- package/dist/signals/base/Signal.js +1 -1
- package/dist/signals/base/Tracker.d.ts +0 -4
- package/dist/signals/base/Tracker.js +0 -6
- package/dist/signals/base/types.d.ts +9 -0
- package/dist/signals/index.d.ts +1 -0
- package/dist/signals/index.js +1 -0
- package/dist/signals/react/index.d.ts +1 -0
- package/dist/signals/react/index.js +1 -0
- package/dist/{react-hooks → signals/react}/useSignal.d.ts +1 -1
- package/dist/{react-hooks → signals/react}/useSignal.js +1 -1
- package/docs/signals/README.md +1 -1
- package/package.json +1 -1
- package/dist/devtools/reduxDevtools.d.ts +0 -2
- package/dist/query/api/createSubResource.d.ts +0 -0
- package/dist/query/api/createSubResource.js +0 -1
- /package/dist/{devtools → common/devtools}/combineDevtools.js +0 -0
- /package/dist/{query/types/devtools.d.ts → common/devtools/types.d.ts} +0 -0
- /package/dist/{query/types/devtools.js → common/devtools/types.js} +0 -0
- /package/dist/{query/core → common/options}/SharedOptions.js +0 -0
- /package/dist/{react-hooks → common/react}/useConstant.d.ts +0 -0
- /package/dist/{react-hooks → common/react}/useConstant.js +0 -0
- /package/dist/{react-hooks → common/react}/useEventHandler.d.ts +0 -0
- /package/dist/{react-hooks → common/react}/useEventHandler.js +0 -0
- /package/dist/{react-hooks → common/react}/useObservable.d.ts +0 -0
- /package/dist/{react-hooks → common/react}/useSyncObservable.d.ts +0 -0
package/README.md
CHANGED
|
@@ -41,11 +41,11 @@ RxToolkit решает эти проблемы, предоставляя сво
|
|
|
41
41
|
|
|
42
42
|
###### Создаем сигнал
|
|
43
43
|
```typescript
|
|
44
|
-
//
|
|
44
|
+
// Описываем логику в обычном JavaScript
|
|
45
45
|
const store = {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
count$: new Signal(0),
|
|
47
|
+
doubled$: new Computed(() => store.count$.value * 2),
|
|
48
|
+
increment: () => store.count$.value++,
|
|
49
49
|
};
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -71,7 +71,6 @@ $: count = store.count$;
|
|
|
71
71
|
|
|
72
72
|
```typescript
|
|
73
73
|
// Создаем Observable
|
|
74
|
-
|
|
75
74
|
const clicker$ = fromEvent(document, 'click').pipe(
|
|
76
75
|
debounceTime(300),
|
|
77
76
|
scan(count => count + 1, 0),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DevtoolsLike } from "
|
|
1
|
+
import { DevtoolsLike } from "./types";
|
|
2
2
|
export declare function combineDevtools(...devtools: DevtoolsLike[]): DevtoolsLike;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DevtoolsLike } from "./types";
|
|
2
|
+
interface ReduxDevtoolsExtension {
|
|
3
|
+
connect(options: {
|
|
4
|
+
name: string;
|
|
5
|
+
}): ReduxDevtoolsConnection;
|
|
6
|
+
}
|
|
7
|
+
interface ReduxDevtoolsConnection {
|
|
8
|
+
init(state: any): void;
|
|
9
|
+
send(action: any, state: any): void;
|
|
10
|
+
}
|
|
11
|
+
type Options = {
|
|
12
|
+
name?: string;
|
|
13
|
+
driver?: ReduxDevtoolsExtension;
|
|
14
|
+
};
|
|
15
|
+
export declare function reduxDevtools(options?: Options): DevtoolsLike;
|
|
16
|
+
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { Batcher } from "
|
|
2
|
-
export function reduxDevtools() {
|
|
1
|
+
import { Batcher } from "../../signals";
|
|
2
|
+
export function reduxDevtools(options = {}) {
|
|
3
|
+
const devtools = options.driver ?? window.__REDUX_DEVTOOLS_EXTENSION__;
|
|
4
|
+
if (!devtools) {
|
|
5
|
+
throw new Error('Redux Devtools extension is not installed');
|
|
6
|
+
}
|
|
3
7
|
let state = {};
|
|
4
|
-
|
|
5
|
-
const reduxDevtools = window.__REDUX_DEVTOOLS_EXTENSION__.connect({ name: 'RxToolkit' });
|
|
8
|
+
const reduxDevtools = devtools.connect({ name: options.name ?? 'RxToolkit' });
|
|
6
9
|
reduxDevtools.init(state);
|
|
7
10
|
const scheduler = Batcher.scheduler(Infinity);
|
|
8
11
|
const updateFn = () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DefaultOptions';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DefaultOptions';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useEventHandler } from "../react-hooks/useEventHandler";
|
|
3
2
|
import { BehaviorSubject } from 'rxjs';
|
|
4
|
-
import { useConstant } from "
|
|
3
|
+
import { useConstant } from "./useConstant";
|
|
4
|
+
import { useEventHandler } from "./useEventHandler";
|
|
5
5
|
const NONE = Symbol('NONE');
|
|
6
6
|
/**
|
|
7
7
|
* Hook for automatically subscribing and unsubscribing from an Observable.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BehaviorSubject } from 'rxjs';
|
|
3
|
-
import { useConstant
|
|
3
|
+
import { useConstant } from "./useConstant";
|
|
4
|
+
import { useEventHandler } from "./useEventHandler";
|
|
4
5
|
const NONE = Symbol('NONE');
|
|
5
6
|
/**
|
|
6
7
|
* Hook for automatically subscribing and unsubscribing from an Observable.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export class PromiseResolver {
|
|
2
|
+
_resolve;
|
|
3
|
+
_reject;
|
|
4
|
+
promise = new Promise((resolve, reject) => {
|
|
5
|
+
this._resolve = resolve;
|
|
6
|
+
this._reject = reject;
|
|
7
|
+
});
|
|
8
|
+
resolve(value) {
|
|
9
|
+
this._resolve(value);
|
|
10
|
+
}
|
|
11
|
+
reject(reason) {
|
|
12
|
+
this._reject(reason);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PromiseResolver';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PromiseResolver';
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import type { OperationCreateOptions, OperationDefinition } from "../../query/types
|
|
1
|
+
import type { OperationCreateOptions, OperationDefinition } from "../../query/types";
|
|
2
2
|
import { Operation } from "../../query/core/Opertation/Operation";
|
|
3
3
|
export declare const createOperation: <ARGS, RESULT, SELECTED = never>(options: OperationCreateOptions<OperationDefinition<ARGS, RESULT, SELECTED>>) => Operation<OperationDefinition<ARGS, RESULT, SELECTED>>;
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated Use `createOperation` instead.
|
|
6
|
-
*/
|
|
7
|
-
export declare const createMutationApi: <ARGS, RESULT, SELECTED = never>(options: OperationCreateOptions<OperationDefinition<ARGS, RESULT, SELECTED>>) => Operation<OperationDefinition<ARGS, RESULT, SELECTED>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ResourceCreateOptions, ResourceDefinition } from "../../query/types
|
|
1
|
+
import type { ResourceCreateOptions, ResourceDefinition } from "../../query/types";
|
|
2
2
|
import { Resource } from "../../query/core/Resource/Resource";
|
|
3
3
|
export declare const createResource: <ARGS, RESULT, SELECTED = never>(options: ResourceCreateOptions<ResourceDefinition<ARGS, RESULT, SELECTED>>) => Resource<ResourceDefinition<ARGS, RESULT, SELECTED>>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { ReactiveCache } from "../../../query/lib/ReactiveCache";
|
|
2
|
-
import { FallbackOnNever } from "../../../query/types
|
|
3
|
-
import { OperationCreateOptions, OperationDefinition, OperationInstance } from "../../../query/types/Operation.types";
|
|
1
|
+
import type { ReactiveCache } from "../../../query/lib/ReactiveCache";
|
|
2
|
+
import type { FallbackOnNever, OperationCreateOptions, OperationDefinition, OperationInstance } from "../../../query/types";
|
|
4
3
|
import { QueriesCache } from "../QueriesCache";
|
|
5
4
|
import { OperationAgent } from "./OperationAgent";
|
|
6
5
|
export type CoreOperationQueryState<D extends OperationDefinition> = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { PromiseResolver } from "../../../common/utils";
|
|
2
|
+
import { SharedOptions } from "../../../common/options/SharedOptions";
|
|
1
3
|
import { QueriesCache } from "../QueriesCache";
|
|
2
|
-
import { SharedOptions } from "../SharedOptions";
|
|
3
4
|
import { OperationAgent } from "./OperationAgent";
|
|
4
5
|
class OperationQueryState {
|
|
5
6
|
static create() {
|
|
@@ -50,7 +51,7 @@ class OperationQueryState {
|
|
|
50
51
|
}
|
|
51
52
|
export class Operation {
|
|
52
53
|
_options;
|
|
53
|
-
_queriesCache = new QueriesCache('Operation');
|
|
54
|
+
_queriesCache = new QueriesCache(60_000, 'Operation');
|
|
54
55
|
_links = [];
|
|
55
56
|
constructor(_options) {
|
|
56
57
|
this._options = _options;
|
|
@@ -104,9 +105,10 @@ export class Operation {
|
|
|
104
105
|
*/
|
|
105
106
|
linksMeta.forEach(({ link, ref, state }) => {
|
|
106
107
|
if (link.update && ref.has) {
|
|
107
|
-
|
|
108
|
+
// TODO подумать, нужно ли добавлять обработку, если patch() -> null (и в принце про работу patch)
|
|
109
|
+
ref.patch((draft) => {
|
|
108
110
|
return link.update({ draft, args, data });
|
|
109
|
-
});
|
|
111
|
+
})?.commit();
|
|
110
112
|
}
|
|
111
113
|
if (link.create && !ref.has) {
|
|
112
114
|
ref.create(link.create({ args, data }));
|
|
@@ -161,17 +163,3 @@ export class Operation {
|
|
|
161
163
|
return resolver.promise;
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
|
-
class PromiseResolver {
|
|
165
|
-
_resolve;
|
|
166
|
-
_reject;
|
|
167
|
-
promise = new Promise((resolve, reject) => {
|
|
168
|
-
this._resolve = resolve;
|
|
169
|
-
this._reject = reject;
|
|
170
|
-
});
|
|
171
|
-
resolve(value) {
|
|
172
|
-
this._resolve(value);
|
|
173
|
-
}
|
|
174
|
-
reject(reason) {
|
|
175
|
-
this._reject(reason);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OperationAgentInstanse, OperationDefinition } from "../../../query/types
|
|
1
|
+
import { OperationAgentInstanse, OperationDefinition } from "../../../query/types";
|
|
2
2
|
import { Computed } from "../../../signals";
|
|
3
3
|
import type { Operation } from "./Operation";
|
|
4
4
|
export declare class OperationAgent<D extends OperationDefinition> implements OperationAgentInstanse<D> {
|
|
@@ -10,7 +10,7 @@ export declare class OperationAgent<D extends OperationDefinition> implements Op
|
|
|
10
10
|
isSuccess: boolean;
|
|
11
11
|
isError: boolean;
|
|
12
12
|
error: {} | undefined;
|
|
13
|
-
data: NonNullable<import("
|
|
13
|
+
data: NonNullable<import("../../../query/types").FallbackOnNever<D["Selected"], D["Result"]>> | undefined;
|
|
14
14
|
args: D["Args"];
|
|
15
15
|
}>;
|
|
16
16
|
constructor(_operation: Operation<D>);
|
|
@@ -6,7 +6,7 @@ export class OperationAgent {
|
|
|
6
6
|
}, { disableDevtools: true });
|
|
7
7
|
state$ = new Computed(() => {
|
|
8
8
|
const operations = this._operations$.value;
|
|
9
|
-
const currState = operations.current$?.value;
|
|
9
|
+
const currState = operations.current$?.value$.value;
|
|
10
10
|
// Нет текущего состояния — дефолт
|
|
11
11
|
if (!currState) {
|
|
12
12
|
return {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ReactiveCache } from "../../query/lib/ReactiveCache";
|
|
2
2
|
export declare class QueriesCache<KEY, VALUE> {
|
|
3
|
+
private _cacheLifeTime;
|
|
3
4
|
private _logname;
|
|
4
5
|
private readonly _cache;
|
|
5
|
-
constructor(_logname?: string);
|
|
6
|
+
constructor(_cacheLifeTime?: number | false, _logname?: string);
|
|
6
7
|
getQueryCache(args: KEY): ReactiveCache<VALUE> | undefined;
|
|
7
8
|
createQueryCache(args: KEY, initialState: VALUE): ReactiveCache<VALUE>;
|
|
8
9
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { IndirectMap } from "../../query/lib/IndirectMap";
|
|
2
2
|
import { ReactiveCache } from "../../query/lib/ReactiveCache";
|
|
3
|
-
import { Indexer } from "../../signals/base/Indexer";
|
|
4
|
-
import { SharedOptions } from "./SharedOptions";
|
|
5
3
|
export class QueriesCache {
|
|
4
|
+
_cacheLifeTime;
|
|
6
5
|
_logname;
|
|
7
6
|
_cache = new IndirectMap();
|
|
8
|
-
constructor(_logname = 'query') {
|
|
7
|
+
constructor(_cacheLifeTime = 60_000, _logname = 'query') {
|
|
8
|
+
this._cacheLifeTime = _cacheLifeTime;
|
|
9
9
|
this._logname = _logname;
|
|
10
10
|
}
|
|
11
11
|
getQueryCache(args) {
|
|
@@ -14,20 +14,23 @@ export class QueriesCache {
|
|
|
14
14
|
createQueryCache(args, initialState) {
|
|
15
15
|
const cache = new ReactiveCache({
|
|
16
16
|
initialState,
|
|
17
|
+
cacheLifeTime: this._cacheLifeTime,
|
|
17
18
|
});
|
|
18
|
-
const stateDevtools = SharedOptions.DEVTOOLS?.state;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
// const stateDevtools = SharedOptions.DEVTOOLS?.state;
|
|
20
|
+
//
|
|
21
|
+
// if (stateDevtools) {
|
|
22
|
+
// const key = `${this._logname}:${JSON.stringify(args)}:i=${Indexer.getIndex()}`;
|
|
23
|
+
// let devtools = stateDevtools(key, initialState);
|
|
24
|
+
//
|
|
25
|
+
// cache.spy$.subscribe((state) => {
|
|
26
|
+
// if (state === initialState) return;
|
|
27
|
+
// devtools(state);
|
|
28
|
+
// });
|
|
29
|
+
//
|
|
30
|
+
// cache.onClean$.subscribe(() => {
|
|
31
|
+
// devtools('$CLEANED' as any);
|
|
32
|
+
// });
|
|
33
|
+
// }
|
|
31
34
|
cache.onClean$.subscribe(() => {
|
|
32
35
|
this._cache.delete(args);
|
|
33
36
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ReactiveCache } from "../../../query/lib/ReactiveCache";
|
|
2
|
-
import type { ResourceCreateOptions, ResourceDefinition, ResourceInstance, ResourceRefInstanse, ResourceTransaction } from "../../../query/types
|
|
3
|
-
import { QueriesCache } from "../QueriesCache";
|
|
2
|
+
import type { ResourceCreateOptions, ResourceDefinition, ResourceInstance, ResourceRefInstanse, ResourceTransaction } from "../../../query/types";
|
|
4
3
|
import { ResourceAgent } from "./ResourceAgent";
|
|
5
4
|
export type CoreResourceQueryState<D extends ResourceDefinition> = {
|
|
6
5
|
transactions: ResourceTransaction[] | null;
|
|
@@ -21,7 +20,8 @@ export type CoreResourceQueryState<D extends ResourceDefinition> = {
|
|
|
21
20
|
export type CoreResourceQueryCache<D extends ResourceDefinition> = ReactiveCache<CoreResourceQueryState<D>>;
|
|
22
21
|
export declare class Resource<D extends ResourceDefinition> implements ResourceInstance<D> {
|
|
23
22
|
private readonly _options;
|
|
24
|
-
readonly _queriesCache
|
|
23
|
+
private readonly _queriesCache;
|
|
24
|
+
private readonly _hooks;
|
|
25
25
|
constructor(_options: ResourceCreateOptions<D>);
|
|
26
26
|
createAgent: () => ResourceAgent<D>;
|
|
27
27
|
createRef: (args: D["Args"]) => ResourceRefInstanse<D>;
|
|
@@ -33,12 +33,6 @@ export declare class Resource<D extends ResourceDefinition> implements ResourceI
|
|
|
33
33
|
decrementLock(args: D['Args'], options?: {
|
|
34
34
|
cache?: CoreResourceQueryCache<D>;
|
|
35
35
|
}): CoreResourceQueryCache<D> | null;
|
|
36
|
-
/**
|
|
37
|
-
* @deprecated
|
|
38
|
-
*/
|
|
39
|
-
updateData_legacy(args: D['Args'], updateFn: (data: D['Data']) => D['Data'], options?: {
|
|
40
|
-
cache?: CoreResourceQueryCache<D>;
|
|
41
|
-
}): CoreResourceQueryCache<D> | null;
|
|
42
36
|
update(args: D['Args'], updateFn: (data: D['Data'], savedData: D['Data'] | null, transactions: ResourceTransaction[] | null) => {
|
|
43
37
|
data: D['Data'];
|
|
44
38
|
transactions: ResourceTransaction[] | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SharedOptions } from "
|
|
1
|
+
import { PromiseResolver } from "../../../common/utils";
|
|
2
|
+
import { SharedOptions } from "../../../common/options/SharedOptions";
|
|
3
|
+
import { QueriesCache } from "../../../query/core/QueriesCache";
|
|
3
4
|
import { ResourceAgent } from "./ResourceAgent";
|
|
4
5
|
import { ResourceRef } from "./ResourceRef";
|
|
5
6
|
class ResourceQueryState {
|
|
@@ -90,11 +91,67 @@ class ResourceQueryState {
|
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
93
|
}
|
|
94
|
+
// TODO вынести и унифицировать; как-то организовать глобальные хуки и devtools через хуки
|
|
95
|
+
class QueryHooks {
|
|
96
|
+
_options;
|
|
97
|
+
onCacheEntryAddedListeners = [];
|
|
98
|
+
onQueryStartedListeners = [];
|
|
99
|
+
constructor(_options) {
|
|
100
|
+
this._options = _options;
|
|
101
|
+
if (_options?.onCacheEntryAdded) {
|
|
102
|
+
this.onCacheEntryAddedListeners.push(_options.onCacheEntryAdded);
|
|
103
|
+
}
|
|
104
|
+
if (_options?.onQueryStarted) {
|
|
105
|
+
this.onQueryStartedListeners.push(_options.onQueryStarted);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
onCacheEntryAdded = (args) => {
|
|
109
|
+
const cacheDataLoadedResolver = new PromiseResolver();
|
|
110
|
+
const cacheEntryRemovedResolver = new PromiseResolver();
|
|
111
|
+
this.onCacheEntryAddedListeners.forEach((listener) => {
|
|
112
|
+
listener(args, {
|
|
113
|
+
$cacheDataLoaded: cacheDataLoadedResolver.promise,
|
|
114
|
+
$cacheEntryRemoved: cacheEntryRemovedResolver.promise,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
cacheDataLoaded: () => cacheDataLoadedResolver.resolve(),
|
|
119
|
+
cacheEntryRemoved: () => cacheEntryRemovedResolver.resolve(),
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
onQueryStarted = (args) => {
|
|
123
|
+
const queryFulfilledResolver = new PromiseResolver();
|
|
124
|
+
this.onQueryStartedListeners.forEach((listener) => {
|
|
125
|
+
listener(args, {
|
|
126
|
+
$queryFulfilled: queryFulfilledResolver.promise
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
fulfilledSuccess: (data) => {
|
|
131
|
+
queryFulfilledResolver.resolve({
|
|
132
|
+
data,
|
|
133
|
+
error: undefined,
|
|
134
|
+
isError: false
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
fulfilledError: (error) => {
|
|
138
|
+
queryFulfilledResolver.resolve({
|
|
139
|
+
data: undefined,
|
|
140
|
+
error,
|
|
141
|
+
isError: true
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
}
|
|
93
147
|
export class Resource {
|
|
94
148
|
_options;
|
|
95
|
-
_queriesCache
|
|
149
|
+
_queriesCache;
|
|
150
|
+
_hooks;
|
|
96
151
|
constructor(_options) {
|
|
97
152
|
this._options = _options;
|
|
153
|
+
this._hooks = new QueryHooks(_options);
|
|
154
|
+
this._queriesCache = new QueriesCache(_options.cacheLifetime, 'Resource');
|
|
98
155
|
}
|
|
99
156
|
createAgent = () => {
|
|
100
157
|
return new ResourceAgent(this);
|
|
@@ -106,7 +163,18 @@ export class Resource {
|
|
|
106
163
|
return this._queriesCache.getQueryCache(args);
|
|
107
164
|
}
|
|
108
165
|
createQueryCache(args) {
|
|
109
|
-
|
|
166
|
+
const cache = this._queriesCache.createQueryCache(args, ResourceQueryState.create());
|
|
167
|
+
const hookResolvers = this._hooks.onCacheEntryAdded(args);
|
|
168
|
+
const spySub = cache.spy$.subscribe((state) => {
|
|
169
|
+
if (!state.isDone)
|
|
170
|
+
return;
|
|
171
|
+
hookResolvers.cacheDataLoaded();
|
|
172
|
+
spySub.unsubscribe();
|
|
173
|
+
});
|
|
174
|
+
cache.onClean$.subscribe(() => {
|
|
175
|
+
hookResolvers.cacheEntryRemoved();
|
|
176
|
+
});
|
|
177
|
+
return cache;
|
|
110
178
|
}
|
|
111
179
|
incrementLock(args, options) {
|
|
112
180
|
let cache = options?.cache ?? this.getQueryCache(args);
|
|
@@ -124,22 +192,6 @@ export class Resource {
|
|
|
124
192
|
cache.next(ResourceQueryState.decrementLock(cache.value));
|
|
125
193
|
return cache;
|
|
126
194
|
}
|
|
127
|
-
/**
|
|
128
|
-
* @deprecated
|
|
129
|
-
*/
|
|
130
|
-
updateData_legacy(args, updateFn, options) {
|
|
131
|
-
let cache = options?.cache ?? this.getQueryCache(args);
|
|
132
|
-
if (!cache) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
const cacheValue = cache.value;
|
|
136
|
-
if (!cacheValue.isDone) {
|
|
137
|
-
return cache;
|
|
138
|
-
}
|
|
139
|
-
const newData = updateFn(cacheValue.data);
|
|
140
|
-
cache.next(ResourceQueryState.setData(cache.value, newData));
|
|
141
|
-
return cache;
|
|
142
|
-
}
|
|
143
195
|
update(args, updateFn, options) {
|
|
144
196
|
let cache = options?.cache ?? this.getQueryCache(args);
|
|
145
197
|
if (!cache) {
|
|
@@ -154,23 +206,23 @@ export class Resource {
|
|
|
154
206
|
return cache;
|
|
155
207
|
}
|
|
156
208
|
initiate(args, options) {
|
|
157
|
-
let cache = options?.cache ?? this.
|
|
209
|
+
let cache = options?.cache ?? this.getQueryCache(args);
|
|
158
210
|
const state = ResourceQueryState.load(cache?.value, args);
|
|
159
211
|
if (!cache) {
|
|
160
|
-
cache = this.
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
cache.next(state);
|
|
212
|
+
cache = this.createQueryCache(args);
|
|
164
213
|
}
|
|
214
|
+
cache.next(state);
|
|
165
215
|
let abortController = state.abortController;
|
|
166
216
|
abortController?.abort();
|
|
167
217
|
abortController = new AbortController();
|
|
168
218
|
const query = this._options.queryFn(args, { abortSignal: abortController.signal });
|
|
219
|
+
const hookResolvers = this._hooks.onQueryStarted(args);
|
|
169
220
|
query
|
|
170
221
|
.then((data) => {
|
|
171
222
|
if (abortController.signal.aborted) {
|
|
172
223
|
return;
|
|
173
224
|
}
|
|
225
|
+
hookResolvers.fulfilledSuccess(data);
|
|
174
226
|
const selectedData = this._options.select ? this._options.select(data) : data;
|
|
175
227
|
cache.next(ResourceQueryState.success(state, selectedData));
|
|
176
228
|
})
|
|
@@ -178,7 +230,8 @@ export class Resource {
|
|
|
178
230
|
if (abortController.signal.aborted) {
|
|
179
231
|
return;
|
|
180
232
|
}
|
|
181
|
-
|
|
233
|
+
hookResolvers.fulfilledError(error);
|
|
234
|
+
SharedOptions.onError?.(error); // TODO перенести в хуки
|
|
182
235
|
cache.next(ResourceQueryState.error(state, error));
|
|
183
236
|
});
|
|
184
237
|
return cache;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Computed } from "../../../signals";
|
|
2
|
-
import { ResourceAgentInstance, ResourceDefinition } from "../../../query/types
|
|
2
|
+
import { ResourceAgentInstance, ResourceDefinition } from "../../../query/types";
|
|
3
3
|
import type { Resource } from "./Resource";
|
|
4
4
|
export declare class ResourceAgent<D extends ResourceDefinition> implements ResourceAgentInstance<D> {
|
|
5
5
|
private _resource;
|
|
@@ -30,5 +30,5 @@ export declare class ResourceAgent<D extends ResourceDefinition> implements Reso
|
|
|
30
30
|
constructor(_resource: Resource<D>);
|
|
31
31
|
private _next;
|
|
32
32
|
initiate(args: D["Args"], force?: boolean): void;
|
|
33
|
-
|
|
33
|
+
complete(): void;
|
|
34
34
|
}
|
|
@@ -8,7 +8,7 @@ export class ResourceAgent {
|
|
|
8
8
|
state$ = new Computed(() => {
|
|
9
9
|
const resources = this._resources$.value;
|
|
10
10
|
let prevState;
|
|
11
|
-
const currState = resources.current$?.value;
|
|
11
|
+
const currState = resources.current$?.value$.value;
|
|
12
12
|
if (!currState?.isDone) {
|
|
13
13
|
prevState = resources.previous$?.value;
|
|
14
14
|
}
|
|
@@ -81,7 +81,8 @@ export class ResourceAgent {
|
|
|
81
81
|
this._next(cache);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
complete() {
|
|
85
|
+
this.state$.complete();
|
|
86
|
+
this._resources$.complete();
|
|
87
|
+
}
|
|
87
88
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ResourceDefinition, ResourceRefInstanse, ResourceTransaction } from "../../../query/types";
|
|
1
2
|
import { Resource } from "./Resource";
|
|
2
|
-
import { ResourceDefinition, ResourceRefInstanse, ResourceTransaction } from "../../types/Resource.types";
|
|
3
3
|
export declare class ResourceRef<D extends ResourceDefinition> implements ResourceRefInstanse<D> {
|
|
4
4
|
private readonly _resource;
|
|
5
5
|
private readonly _args;
|
|
@@ -10,9 +10,6 @@ export declare class ResourceRef<D extends ResourceDefinition> implements Resour
|
|
|
10
10
|
unlock: () => void;
|
|
11
11
|
};
|
|
12
12
|
unlockOne(): void;
|
|
13
|
-
update(updateFn: (data: D["Data"]) => D["Data"]): {
|
|
14
|
-
rollback: () => void;
|
|
15
|
-
};
|
|
16
13
|
patch(patchFn: (data: D["Data"]) => void): ResourceTransaction | null;
|
|
17
14
|
create(data: D["Data"]): void;
|
|
18
15
|
invalidate(): void;
|