@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.
Files changed (81) hide show
  1. package/README.md +4 -5
  2. package/dist/{devtools → common/devtools}/combineDevtools.d.ts +1 -1
  3. package/dist/{devtools → common/devtools}/index.d.ts +1 -0
  4. package/dist/{devtools → common/devtools}/index.js +1 -0
  5. package/dist/common/devtools/reduxDevtools.d.ts +16 -0
  6. package/dist/{devtools → common/devtools}/reduxDevtools.js +7 -4
  7. package/dist/{query/api → common/options}/DefaultOptions.d.ts +1 -1
  8. package/dist/{query/api → common/options}/DefaultOptions.js +1 -1
  9. package/dist/{query/core → common/options}/SharedOptions.d.ts +1 -1
  10. package/dist/common/options/index.d.ts +1 -0
  11. package/dist/common/options/index.js +1 -0
  12. package/dist/{react-hooks → common/react}/index.d.ts +2 -3
  13. package/dist/{react-hooks → common/react}/index.js +2 -3
  14. package/dist/{react-hooks → common/react}/useObservable.js +2 -2
  15. package/dist/{react-hooks → common/react}/useSyncObservable.js +2 -1
  16. package/dist/common/utils/PromiseResolver.d.ts +7 -0
  17. package/dist/common/utils/PromiseResolver.js +14 -0
  18. package/dist/common/utils/index.d.ts +1 -0
  19. package/dist/common/utils/index.js +1 -0
  20. package/dist/index.d.ts +3 -2
  21. package/dist/index.js +3 -2
  22. package/dist/query/api/createOperation.d.ts +1 -5
  23. package/dist/query/api/createOperation.js +0 -4
  24. package/dist/query/api/createResource.d.ts +1 -1
  25. package/dist/query/core/Opertation/Operation.d.ts +2 -3
  26. package/dist/query/core/Opertation/Operation.js +6 -18
  27. package/dist/query/core/Opertation/OperationAgent.d.ts +2 -2
  28. package/dist/query/core/Opertation/OperationAgent.js +1 -1
  29. package/dist/query/core/QueriesCache.d.ts +2 -1
  30. package/dist/query/core/QueriesCache.js +19 -16
  31. package/dist/query/core/Resource/Resource.d.ts +3 -9
  32. package/dist/query/core/Resource/Resource.js +79 -26
  33. package/dist/query/core/Resource/ResourceAgent.d.ts +2 -2
  34. package/dist/query/core/Resource/ResourceAgent.js +5 -4
  35. package/dist/query/core/Resource/ResourceRef.d.ts +1 -4
  36. package/dist/query/core/Resource/ResourceRef.js +10 -20
  37. package/dist/query/index.d.ts +0 -1
  38. package/dist/query/index.js +0 -1
  39. package/dist/query/lib/IndirectMap.js +1 -1
  40. package/dist/query/lib/ReactiveCache.d.ts +6 -22
  41. package/dist/query/lib/ReactiveCache.js +19 -39
  42. package/dist/query/react/useOperationAgent.d.ts +1 -2
  43. package/dist/query/react/useOperationAgent.js +2 -1
  44. package/dist/query/react/useResourceAgent.d.ts +3 -7
  45. package/dist/query/react/useResourceAgent.js +7 -3
  46. package/dist/query/react/useResourceRef.d.ts +1 -2
  47. package/dist/query/react/useResourceRef.js +1 -1
  48. package/dist/query/types/Operation.types.d.ts +1 -1
  49. package/dist/query/types/Resource.types.d.ts +29 -10
  50. package/dist/query/types/index.d.ts +3 -0
  51. package/dist/query/types/index.js +3 -0
  52. package/dist/signals/base/Computed.js +1 -2
  53. package/dist/signals/base/Effect.js +3 -2
  54. package/dist/signals/base/ReadonlySignal.d.ts +2 -3
  55. package/dist/signals/base/ReadonlySignal.js +2 -11
  56. package/dist/signals/base/Signal.d.ts +2 -2
  57. package/dist/signals/base/Signal.js +1 -1
  58. package/dist/signals/base/Tracker.d.ts +0 -4
  59. package/dist/signals/base/Tracker.js +0 -6
  60. package/dist/signals/base/types.d.ts +9 -0
  61. package/dist/signals/index.d.ts +1 -0
  62. package/dist/signals/index.js +1 -0
  63. package/dist/signals/react/index.d.ts +1 -0
  64. package/dist/signals/react/index.js +1 -0
  65. package/dist/{react-hooks → signals/react}/useSignal.d.ts +1 -1
  66. package/dist/{react-hooks → signals/react}/useSignal.js +1 -1
  67. package/docs/signals/README.md +1 -1
  68. package/package.json +1 -1
  69. package/dist/devtools/reduxDevtools.d.ts +0 -2
  70. package/dist/query/api/createSubResource.d.ts +0 -0
  71. package/dist/query/api/createSubResource.js +0 -1
  72. /package/dist/{devtools → common/devtools}/combineDevtools.js +0 -0
  73. /package/dist/{query/types/devtools.d.ts → common/devtools/types.d.ts} +0 -0
  74. /package/dist/{query/types/devtools.js → common/devtools/types.js} +0 -0
  75. /package/dist/{query/core → common/options}/SharedOptions.js +0 -0
  76. /package/dist/{react-hooks → common/react}/useConstant.d.ts +0 -0
  77. /package/dist/{react-hooks → common/react}/useConstant.js +0 -0
  78. /package/dist/{react-hooks → common/react}/useEventHandler.d.ts +0 -0
  79. /package/dist/{react-hooks → common/react}/useEventHandler.js +0 -0
  80. /package/dist/{react-hooks → common/react}/useObservable.d.ts +0 -0
  81. /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
- // Описываете логику в обычном JavaScript
44
+ // Описываем логику в обычном JavaScript
45
45
  const store = {
46
- count$: new Signal(0),
47
- doubled$: new Computed(() => store.count$.value * 2),
48
- increment: () => store.count$.next(store.count$.value + 1)
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 "../query/types/devtools";
1
+ import { DevtoolsLike } from "./types";
2
2
  export declare function combineDevtools(...devtools: DevtoolsLike[]): DevtoolsLike;
@@ -1,2 +1,3 @@
1
1
  export * from './reduxDevtools';
2
2
  export * from './combineDevtools';
3
+ export * from './types';
@@ -1,2 +1,3 @@
1
1
  export * from './reduxDevtools';
2
2
  export * from './combineDevtools';
3
+ export * from './types';
@@ -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 "../signals";
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
- // @ts-ignore
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 = () => {
@@ -1,4 +1,4 @@
1
- import { DevtoolsLike } from "../../query/types/devtools";
1
+ import type { DevtoolsLike } from "../../common/devtools";
2
2
  type Update = Partial<{
3
3
  DEVTOOLS: DevtoolsLike | null;
4
4
  onError: (error: unknown) => void;
@@ -1,4 +1,4 @@
1
- import { SharedOptions } from "../../query/core/SharedOptions";
1
+ import { SharedOptions } from "./SharedOptions";
2
2
  export class DefaultOptions {
3
3
  static update(part) {
4
4
  if (part.DEVTOOLS !== undefined)
@@ -1,4 +1,4 @@
1
- import { DevtoolsLike } from "../../query/types/devtools";
1
+ import { DevtoolsLike } from "../../common/devtools";
2
2
  export declare class SharedOptions {
3
3
  static DEVTOOLS: DevtoolsLike | null;
4
4
  static onError: ((error: unknown) => void) | null;
@@ -0,0 +1 @@
1
+ export * from './DefaultOptions';
@@ -0,0 +1 @@
1
+ export * from './DefaultOptions';
@@ -1,5 +1,4 @@
1
- export * from './useSignal';
1
+ export * from './useConstant';
2
+ export * from './useEventHandler';
2
3
  export * from './useObservable';
3
4
  export * from './useSyncObservable';
4
- export * from './useEventHandler';
5
- export * from './useConstant';
@@ -1,5 +1,4 @@
1
- export * from './useSignal';
1
+ export * from './useConstant';
2
+ export * from './useEventHandler';
2
3
  export * from './useObservable';
3
4
  export * from './useSyncObservable';
4
- export * from './useEventHandler';
5
- export * from './useConstant';
@@ -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 "../react-hooks/useConstant";
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, useEventHandler } from "../react-hooks";
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,7 @@
1
+ export declare class PromiseResolver<T> {
2
+ private _resolve;
3
+ private _reject;
4
+ promise: Promise<T>;
5
+ resolve(value: T): void;
6
+ reject(reason?: any): void;
7
+ }
@@ -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
@@ -1,4 +1,5 @@
1
+ export * from './common/devtools';
2
+ export * from './common/options';
3
+ export * from './common/react';
1
4
  export * from './query';
2
5
  export * from './signals';
3
- export * from './react-hooks';
4
- export * from './devtools';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
+ export * from './common/devtools';
2
+ export * from './common/options';
3
+ export * from './common/react';
1
4
  export * from './query';
2
5
  export * from './signals';
3
- export * from './react-hooks';
4
- export * from './devtools';
@@ -1,7 +1,3 @@
1
- import type { OperationCreateOptions, OperationDefinition } from "../../query/types/Operation.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,6 +1,2 @@
1
1
  import { Operation } from "../../query/core/Opertation/Operation";
2
2
  export const createOperation = ((options) => new Operation(options));
3
- /**
4
- * @deprecated Use `createOperation` instead.
5
- */
6
- export const createMutationApi = createOperation;
@@ -1,3 +1,3 @@
1
- import type { ResourceCreateOptions, ResourceDefinition } from "../../query/types/Resource.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/shared.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
- ref.update((draft) => {
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/Operation.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("../../types/shared.types").FallbackOnNever<D["Selected"], D["Result"]>> | undefined;
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
- if (stateDevtools) {
20
- const key = `${this._logname}:${JSON.stringify(args)}:i=${Indexer.getIndex()}`;
21
- let devtools = stateDevtools(key, initialState);
22
- cache.spy$.subscribe((state) => {
23
- if (state === initialState)
24
- return;
25
- devtools(state);
26
- });
27
- cache.onClean$.subscribe(() => {
28
- devtools('$CLEANED');
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/Resource.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: QueriesCache<D["Args"], CoreResourceQueryState<D>>;
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 { QueriesCache } from "../QueriesCache";
2
- import { SharedOptions } from "../SharedOptions";
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 = new QueriesCache('Resource');
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
- return this._queriesCache.createQueryCache(args, ResourceQueryState.create());
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._queriesCache.getQueryCache(args);
209
+ let cache = options?.cache ?? this.getQueryCache(args);
158
210
  const state = ResourceQueryState.load(cache?.value, args);
159
211
  if (!cache) {
160
- cache = this._queriesCache.createQueryCache(args, state);
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
- SharedOptions.onError?.(error);
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/Resource.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
- createAgent: () => ResourceAgentInstance<D>;
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
- createAgent = () => {
85
- return this;
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;