@fozy-labs/rx-toolkit 0.5.3-rc.2 → 0.5.3
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 +21 -21
- package/README.md +143 -137
- package/dist/common/devtools/combineDevtools.js +3 -3
- package/dist/common/devtools/index.d.ts +3 -3
- package/dist/common/devtools/index.js +3 -3
- package/dist/common/devtools/reduxDevtools.d.ts +1 -1
- package/dist/common/devtools/reduxDevtools.js +17 -17
- package/dist/common/devtools/types.d.ts +0 -6
- package/dist/common/options/SharedOptions.d.ts +1 -0
- package/dist/common/options/SharedOptions.js +6 -0
- package/dist/common/options/index.d.ts +1 -1
- package/dist/common/options/index.js +1 -1
- package/dist/common/react/index.d.ts +2 -2
- package/dist/common/react/index.js +2 -2
- package/dist/common/react/useConstant.js +1 -1
- package/dist/common/utils/deepEqual.js +1 -1
- package/dist/common/utils/index.d.ts +3 -3
- package/dist/common/utils/index.js +3 -3
- package/dist/common/utils/shallowEqual.js +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +8 -7
- package/dist/query/SKIP_TOKEN.js +1 -1
- package/dist/query/api/createCommand.d.ts +1 -1
- package/dist/query/api/createOperation.d.ts +1 -1
- package/dist/query/api/createOperation.js +1 -1
- package/dist/query/api/createResource.d.ts +1 -1
- package/dist/query/api/createResourceDuplicator.d.ts +1 -1
- package/dist/query/core/Command/Command.d.ts +7 -7
- package/dist/query/core/Command/Command.js +2 -2
- package/dist/query/core/Command/CommandAgent.d.ts +1 -1
- package/dist/query/core/Command/index.d.ts +2 -2
- package/dist/query/core/Command/index.js +2 -2
- package/dist/query/core/{Opertation → Operation}/Operation.d.ts +2 -2
- package/dist/query/core/{Opertation → Operation}/Operation.js +1 -1
- package/dist/query/core/{Opertation → Operation}/OperationAgent.d.ts +1 -1
- package/dist/query/core/{Opertation → Operation}/OperationAgent.js +1 -1
- package/dist/query/core/QueriesCache.d.ts +1 -1
- package/dist/query/core/QueriesCache.js +1 -1
- package/dist/query/core/QueriesLifetimeHooks.js +7 -7
- package/dist/query/core/Resource/Resource.d.ts +15 -15
- package/dist/query/core/Resource/Resource.js +7 -7
- package/dist/query/core/Resource/ResourceAgent.d.ts +1 -1
- package/dist/query/core/Resource/ResourceAgent.js +2 -2
- package/dist/query/core/Resource/ResourceDuplicator.d.ts +16 -16
- package/dist/query/core/Resource/ResourceDuplicator.js +18 -20
- package/dist/query/core/Resource/ResourceDuplicatorAgent.d.ts +5 -5
- package/dist/query/core/Resource/ResourceDuplicatorAgent.js +2 -2
- package/dist/query/core/Resource/ResourceRef.d.ts +2 -2
- package/dist/query/core/Resource/ResourceRef.js +12 -12
- package/dist/query/index.d.ts +11 -10
- package/dist/query/index.js +11 -10
- package/dist/query/lib/IndirectMap.js +4 -4
- package/dist/query/react/useCommandAgent.d.ts +2 -2
- package/dist/query/react/useOperationAgent.d.ts +1 -1
- package/dist/query/react/useOperationAgent.js +1 -1
- package/dist/query/react/useResourceAgent.d.ts +3 -3
- package/dist/query/react/useResourceAgent.js +1 -1
- package/dist/query/react/useResourceRef.d.ts +3 -3
- package/dist/query/react/useResourceRef.js +7 -2
- package/dist/query/types/Command.types.d.ts +1 -1
- package/dist/query/types/Operation.types.d.ts +1 -1
- package/dist/query/types/Resource.types.d.ts +7 -5
- package/dist/query/types/index.d.ts +4 -4
- package/dist/query/types/index.js +4 -4
- package/dist/query-v2/api/createApi.d.ts +10 -0
- package/dist/query-v2/api/createApi.js +83 -0
- package/dist/query-v2/core/common/CacheEntry.d.ts +29 -0
- package/dist/query-v2/core/common/CacheEntry.js +71 -0
- package/dist/query-v2/core/common/CacheMap.d.ts +38 -0
- package/dist/query-v2/core/common/CacheMap.js +127 -0
- package/dist/query-v2/core/common/LifecycleHooks.d.ts +22 -0
- package/dist/query-v2/core/common/LifecycleHooks.js +104 -0
- package/dist/query-v2/core/common/index.d.ts +3 -0
- package/dist/query-v2/core/common/index.js +3 -0
- package/dist/query-v2/core/index.d.ts +3 -0
- package/dist/query-v2/core/index.js +3 -0
- package/dist/query-v2/core/machines/Machine.d.ts +14 -0
- package/dist/query-v2/core/machines/Machine.js +33 -0
- package/dist/query-v2/core/machines/MachineError.d.ts +11 -0
- package/dist/query-v2/core/machines/MachineError.js +26 -0
- package/dist/query-v2/core/machines/MachineIdle.d.ts +8 -0
- package/dist/query-v2/core/machines/MachineIdle.js +19 -0
- package/dist/query-v2/core/machines/MachinePending.d.ts +12 -0
- package/dist/query-v2/core/machines/MachinePending.js +29 -0
- package/dist/query-v2/core/machines/MachineRefreshing.d.ts +14 -0
- package/dist/query-v2/core/machines/MachineRefreshing.js +46 -0
- package/dist/query-v2/core/machines/MachineSuccess.d.ts +16 -0
- package/dist/query-v2/core/machines/MachineSuccess.js +42 -0
- package/dist/query-v2/core/machines/MachineWithData.d.ts +18 -0
- package/dist/query-v2/core/machines/MachineWithData.js +40 -0
- package/dist/query-v2/core/machines/Patcher.d.ts +20 -0
- package/dist/query-v2/core/machines/Patcher.js +104 -0
- package/dist/query-v2/core/machines/index.d.ts +8 -0
- package/dist/query-v2/core/machines/index.js +8 -0
- package/dist/query-v2/core/resource/ResourceV2.d.ts +120 -0
- package/dist/query-v2/core/resource/ResourceV2.js +464 -0
- package/dist/query-v2/core/resource/ResourceV2Agent.d.ts +26 -0
- package/dist/query-v2/core/resource/ResourceV2Agent.js +132 -0
- package/dist/query-v2/core/resource/index.d.ts +2 -0
- package/dist/query-v2/core/resource/index.js +2 -0
- package/dist/query-v2/index.d.ts +11 -0
- package/dist/query-v2/index.js +17 -0
- package/dist/query-v2/lib/NO_VALUE.d.ts +2 -0
- package/dist/query-v2/lib/NO_VALUE.js +1 -0
- package/dist/query-v2/lib/SKIP_TOKEN.d.ts +2 -0
- package/dist/query-v2/lib/SKIP_TOKEN.js +1 -0
- package/dist/query-v2/lib/index.d.ts +4 -0
- package/dist/query-v2/lib/index.js +3 -0
- package/dist/query-v2/lib/stableStringify.d.ts +8 -0
- package/dist/query-v2/lib/stableStringify.js +23 -0
- package/dist/query-v2/plugins/ReactHooksPlugin.d.ts +25 -0
- package/dist/query-v2/plugins/ReactHooksPlugin.js +19 -0
- package/dist/query-v2/plugins/types.d.ts +1 -0
- package/dist/query-v2/plugins/types.js +1 -0
- package/dist/query-v2/react/__tests__/helpers.d.ts +12 -0
- package/dist/query-v2/react/__tests__/helpers.js +33 -0
- package/dist/query-v2/react/index.d.ts +2 -0
- package/dist/query-v2/react/index.js +2 -0
- package/dist/query-v2/react/useResourceV2Agent.d.ts +12 -0
- package/dist/query-v2/react/useResourceV2Agent.js +36 -0
- package/dist/query-v2/react/useResourceV2Ref.d.ts +12 -0
- package/dist/query-v2/react/useResourceV2Ref.js +57 -0
- package/dist/query-v2/snapshot/Snapshot.d.ts +13 -0
- package/dist/query-v2/snapshot/Snapshot.js +76 -0
- package/dist/query-v2/types/agent.types.d.ts +54 -0
- package/dist/query-v2/types/agent.types.js +1 -0
- package/dist/query-v2/types/api.types.d.ts +22 -0
- package/dist/query-v2/types/api.types.js +1 -0
- package/dist/query-v2/types/cache.types.d.ts +37 -0
- package/dist/query-v2/types/cache.types.js +1 -0
- package/dist/query-v2/types/index.d.ts +9 -0
- package/dist/query-v2/types/index.js +9 -0
- package/dist/query-v2/types/lifecycle.types.d.ts +25 -0
- package/dist/query-v2/types/lifecycle.types.js +1 -0
- package/dist/query-v2/types/machine.types.d.ts +67 -0
- package/dist/query-v2/types/machine.types.js +1 -0
- package/dist/query-v2/types/plugin.types.d.ts +38 -0
- package/dist/query-v2/types/plugin.types.js +1 -0
- package/dist/query-v2/types/resource.types.d.ts +35 -0
- package/dist/query-v2/types/resource.types.js +1 -0
- package/dist/query-v2/types/shared.types.d.ts +20 -0
- package/dist/query-v2/types/shared.types.js +1 -0
- package/dist/query-v2/types/snapshot.types.d.ts +21 -0
- package/dist/query-v2/types/snapshot.types.js +1 -0
- package/dist/signals/base/Batcher.js +9 -5
- package/dist/signals/base/ComputeCache.js +3 -3
- package/dist/signals/base/DependencyTracker.js +1 -1
- package/dist/signals/base/Devtools.d.ts +3 -2
- package/dist/signals/base/Devtools.js +54 -27
- package/dist/signals/base/Indexer.js +1 -1
- package/dist/signals/base/ReadonlySignal.js +1 -1
- package/dist/signals/base/SyncObservable.d.ts +1 -2
- package/dist/signals/base/SyncObservable.js +2 -5
- package/dist/signals/base/index.d.ts +6 -6
- package/dist/signals/base/index.js +6 -6
- package/dist/signals/index.d.ts +5 -4
- package/dist/signals/index.js +5 -4
- package/dist/signals/operators/index.d.ts +1 -1
- package/dist/signals/operators/index.js +1 -1
- package/dist/signals/react/index.d.ts +1 -1
- package/dist/signals/react/index.js +1 -1
- package/dist/signals/signals/Computed.d.ts +3 -4
- package/dist/signals/signals/Computed.js +18 -10
- package/dist/signals/signals/Effect.js +2 -1
- package/dist/signals/signals/LocalState.d.ts +3 -4
- package/dist/signals/signals/LocalState.js +8 -8
- package/dist/signals/signals/Signal.d.ts +7 -6
- package/dist/signals/signals/Signal.js +4 -1
- package/dist/signals/signals/State.d.ts +4 -5
- package/dist/signals/signals/State.js +23 -9
- package/dist/signals/signals/index.d.ts +5 -5
- package/dist/signals/signals/index.js +5 -6
- package/dist/signals/types/SignalOptions.d.ts +16 -0
- package/dist/signals/types/SignalOptions.js +1 -0
- package/dist/signals/types/index.d.ts +3 -1
- package/dist/signals/types/index.js +3 -1
- package/dist/signals/types/normalizeSignalOptions.d.ts +2 -0
- package/dist/signals/types/normalizeSignalOptions.js +10 -0
- package/dist/signals/types/signals.types.d.ts +2 -3
- package/docs/CHANGELOG.md +111 -90
- package/docs/CONTRIBUTING.md +230 -0
- package/docs/contributing/ai-assisted-development.md +47 -0
- package/docs/contributing/query-v2/README.md +379 -0
- package/docs/{release → contributing/release}/README.md +59 -59
- package/docs/devtools/README.md +228 -228
- package/docs/migrations/0.5.0.md +58 -58
- package/docs/migrations/query-v2.md +171 -0
- package/docs/options/README.md +92 -92
- package/docs/query/README.md +575 -573
- package/docs/query-v2/README.md +280 -0
- package/docs/query-v2/api-reference.md +235 -0
- package/docs/query-v2/optimistic-updates.md +148 -0
- package/docs/query-v2/ssr.md +130 -0
- package/docs/signals/README.md +300 -300
- package/docs/usage/react/README.md +309 -309
- package/package.json +86 -63
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IMachineBox } from "./machine.types";
|
|
2
|
+
import type { TCompareArgsFn, TSerializeArgsFn } from "./shared.types";
|
|
3
|
+
/** Single reactive cache unit holding a Machine */
|
|
4
|
+
export interface ICacheEntry<TData, TError = Error> {
|
|
5
|
+
/** Reactive signal holding current machine state */
|
|
6
|
+
readonly machine$: () => IMachineBox<TData, TError>;
|
|
7
|
+
/** Synchronous peek at current machine */
|
|
8
|
+
peek(): IMachineBox<TData, TError>;
|
|
9
|
+
/** Update machine state */
|
|
10
|
+
set(machine: IMachineBox<TData, TError>): void;
|
|
11
|
+
/** Cleanup — complete and release */
|
|
12
|
+
complete(): void;
|
|
13
|
+
/** Observable for cache lifetime management */
|
|
14
|
+
readonly onClean$: {
|
|
15
|
+
subscribe(cb: () => void): {
|
|
16
|
+
unsubscribe(): void;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Dual-strategy cache abstraction */
|
|
21
|
+
export interface ICacheMap<TArgs, TData, TError = Error> {
|
|
22
|
+
get(args: TArgs): ICacheEntry<TData, TError> | undefined;
|
|
23
|
+
set(args: TArgs, entry: ICacheEntry<TData, TError>): void;
|
|
24
|
+
delete(args: TArgs): boolean;
|
|
25
|
+
has(args: TArgs): boolean;
|
|
26
|
+
values(): Iterable<ICacheEntry<TData, TError>>;
|
|
27
|
+
entries(): Iterable<[TArgs | string, ICacheEntry<TData, TError>]>;
|
|
28
|
+
clear(): void;
|
|
29
|
+
readonly size: number;
|
|
30
|
+
}
|
|
31
|
+
/** Factory options for creating appropriate cache map */
|
|
32
|
+
export interface ICacheMapOptions<_TArgs> {
|
|
33
|
+
keyStrategy: "serialize" | "compare";
|
|
34
|
+
serializeArgs: TSerializeArgsFn;
|
|
35
|
+
compareArg: TCompareArgsFn;
|
|
36
|
+
doCacheArgs: boolean;
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./shared.types";
|
|
2
|
+
export * from "./machine.types";
|
|
3
|
+
export * from "./cache.types";
|
|
4
|
+
export * from "./resource.types";
|
|
5
|
+
export * from "./agent.types";
|
|
6
|
+
export * from "./api.types";
|
|
7
|
+
export * from "./plugin.types";
|
|
8
|
+
export * from "./snapshot.types";
|
|
9
|
+
export * from "./lifecycle.types";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./shared.types";
|
|
2
|
+
export * from "./machine.types";
|
|
3
|
+
export * from "./cache.types";
|
|
4
|
+
export * from "./resource.types";
|
|
5
|
+
export * from "./agent.types";
|
|
6
|
+
export * from "./api.types";
|
|
7
|
+
export * from "./plugin.types";
|
|
8
|
+
export * from "./snapshot.types";
|
|
9
|
+
export * from "./lifecycle.types";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ICacheEntry } from "./cache.types";
|
|
2
|
+
import type { TMachine } from "./machine.types";
|
|
3
|
+
/** Tools provided to onCacheEntryAdded */
|
|
4
|
+
export interface TCacheEntryAddedTools<TData> {
|
|
5
|
+
/** Resolves when first MachineSuccess is set */
|
|
6
|
+
$cacheDataLoaded: Promise<TData>;
|
|
7
|
+
/** Resolves when cache entry is removed */
|
|
8
|
+
$cacheEntryRemoved: Promise<void>;
|
|
9
|
+
/** Get current machine state */
|
|
10
|
+
getCacheEntry(): TMachine<TData, any>;
|
|
11
|
+
}
|
|
12
|
+
/** onCacheEntryAdded callback type */
|
|
13
|
+
export type TOnCacheEntryAdded<TArgs, TData> = (args: TArgs, tools: TCacheEntryAddedTools<TData>) => void | Promise<void>;
|
|
14
|
+
/** Tools provided to onQueryStarted */
|
|
15
|
+
export interface TQueryStartedTools<TData> {
|
|
16
|
+
/** Resolves/rejects when query completes */
|
|
17
|
+
$queryFulfilled: Promise<{
|
|
18
|
+
data: TData;
|
|
19
|
+
isError: false;
|
|
20
|
+
}>;
|
|
21
|
+
/** Get current cache entry for patching */
|
|
22
|
+
getCacheEntry(): ICacheEntry<TData, any>;
|
|
23
|
+
}
|
|
24
|
+
/** onQueryStarted callback type */
|
|
25
|
+
export type TOnQueryStarted<TArgs, TData> = (args: TArgs, tools: TQueryStartedTools<TData>) => void | Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { NO_VALUE } from "./shared.types";
|
|
2
|
+
/** Discriminated union of all machine statuses */
|
|
3
|
+
export type TMachineStatus = "idle" | "pending" | "success" | "error" | "refreshing";
|
|
4
|
+
/** Idle state — initial, no data */
|
|
5
|
+
export interface TResourceV2IdleState {
|
|
6
|
+
status: "idle";
|
|
7
|
+
args: null;
|
|
8
|
+
data: null;
|
|
9
|
+
error: null;
|
|
10
|
+
updatedAt: null;
|
|
11
|
+
}
|
|
12
|
+
/** Pending state — query in progress, no data yet */
|
|
13
|
+
export interface TResourceV2PendingState<TData = unknown> {
|
|
14
|
+
status: "pending";
|
|
15
|
+
args: unknown;
|
|
16
|
+
data: null;
|
|
17
|
+
error: null;
|
|
18
|
+
updatedAt: null;
|
|
19
|
+
originalData: TData | NO_VALUE;
|
|
20
|
+
}
|
|
21
|
+
/** Success state — data loaded successfully */
|
|
22
|
+
export interface TResourceV2SuccessState<TData = unknown> {
|
|
23
|
+
status: "success";
|
|
24
|
+
args: unknown;
|
|
25
|
+
data: TData;
|
|
26
|
+
error: null;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
originalData: TData | NO_VALUE;
|
|
29
|
+
patches: TResourceV2Patch[] | null;
|
|
30
|
+
}
|
|
31
|
+
/** Error state — query failed */
|
|
32
|
+
export interface TResourceV2ErrorState<TError = Error> {
|
|
33
|
+
status: "error";
|
|
34
|
+
args: unknown;
|
|
35
|
+
data: null;
|
|
36
|
+
error: TError;
|
|
37
|
+
updatedAt: null;
|
|
38
|
+
}
|
|
39
|
+
/** Refreshing state — re-fetching while holding stale data */
|
|
40
|
+
export interface TResourceV2RefreshingState<TData = unknown> {
|
|
41
|
+
status: "refreshing";
|
|
42
|
+
args: unknown;
|
|
43
|
+
data: TData;
|
|
44
|
+
error: null;
|
|
45
|
+
updatedAt: number;
|
|
46
|
+
originalData: TData | NO_VALUE;
|
|
47
|
+
patches: TResourceV2Patch[] | null;
|
|
48
|
+
}
|
|
49
|
+
/** Patch record in the queue (Immer-based) */
|
|
50
|
+
export interface TResourceV2Patch {
|
|
51
|
+
patches: unknown[];
|
|
52
|
+
inversePatches: unknown[];
|
|
53
|
+
status: "pending" | "committed" | "aborted";
|
|
54
|
+
}
|
|
55
|
+
/** Patch function (Immer recipe) */
|
|
56
|
+
export type TPatchFn<TData> = (draft: TData) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Discriminated union of all machine states (flat state shapes).
|
|
59
|
+
*/
|
|
60
|
+
export type TMachine<TData, TError = Error> = TResourceV2IdleState | TResourceV2PendingState<TData> | TResourceV2SuccessState<TData> | TResourceV2ErrorState<TError> | TResourceV2RefreshingState<TData>;
|
|
61
|
+
/**
|
|
62
|
+
* Boxed machine — structural type matching runtime machine class instances.
|
|
63
|
+
* Each machine class wraps its flat state in a `readonly state` property.
|
|
64
|
+
*/
|
|
65
|
+
export interface IMachineBox<TData = unknown, TError = Error> {
|
|
66
|
+
readonly state: TMachine<TData, TError>;
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ResourceV2 } from "../../query-v2";
|
|
2
|
+
import type { IApi } from "./api.types";
|
|
3
|
+
import type { IResourceV2Options } from "./resource.types";
|
|
4
|
+
import type { Prettify } from "./shared.types";
|
|
5
|
+
/** Plugin interface — all plugins must implement this */
|
|
6
|
+
export interface IPlugin {
|
|
7
|
+
/** Unique plugin name */
|
|
8
|
+
readonly name: string;
|
|
9
|
+
/** Called once when createApi installs the plugin */
|
|
10
|
+
install(context: IPluginContext): void;
|
|
11
|
+
/** Called for each createResource — returns augmented resource */
|
|
12
|
+
augmentResource<TArgs, TData, TError>(resource: ResourceV2<TArgs, TData, TError>, options: IResourceV2Options<TArgs, TData, TError>): Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** Context provided to plugins during install */
|
|
15
|
+
export interface IPluginContext {
|
|
16
|
+
/** The API instance */
|
|
17
|
+
readonly api: IApi<any>;
|
|
18
|
+
/** Key strategy for this API */
|
|
19
|
+
readonly keyStrategy: "serialize" | "compare";
|
|
20
|
+
}
|
|
21
|
+
/** Helper: converts a union to an intersection */
|
|
22
|
+
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
23
|
+
/**
|
|
24
|
+
* Extract plugin contributions from a single plugin.
|
|
25
|
+
* Each plugin extends PluginContributionMap via declaration merging.
|
|
26
|
+
* The name property is used as the key lookup.
|
|
27
|
+
*/
|
|
28
|
+
export interface PluginContributionMap<TArgs, TData, TError> {
|
|
29
|
+
}
|
|
30
|
+
export type ExtractPluginContributions<P extends IPlugin, TArgs, TData, TError> = P extends {
|
|
31
|
+
name: infer N;
|
|
32
|
+
} ? N extends keyof PluginContributionMap<TArgs, TData, TError> ? PluginContributionMap<TArgs, TData, TError>[N] : object : object;
|
|
33
|
+
/**
|
|
34
|
+
* Type-level utility: extracts and merges augmentations from a plugin tuple.
|
|
35
|
+
* Uses UnionToIntersection + Prettify as per ADR-1.
|
|
36
|
+
*/
|
|
37
|
+
export type PluginAugmentations<TPlugins extends IPlugin[], TArgs, TData, TError> = TPlugins extends [] ? object : Prettify<UnionToIntersection<TPlugins[number] extends infer P ? P extends IPlugin ? ExtractPluginContributions<P, TArgs, TData, TError> : never : never>>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IResourceV2Agent } from "./agent.types";
|
|
2
|
+
import type { ICacheEntry } from "./cache.types";
|
|
3
|
+
import type { TOnCacheEntryAdded, TOnQueryStarted } from "./lifecycle.types";
|
|
4
|
+
import type { TMachine } from "./machine.types";
|
|
5
|
+
import type { TBeforeDevtoolsPushFn, TCompareArgsFn, TQueryFn, TSerializeArgsFn } from "./shared.types";
|
|
6
|
+
/** Options for api.createResource */
|
|
7
|
+
export interface IResourceV2Options<TArgs, TData, TError = Error> {
|
|
8
|
+
key?: string;
|
|
9
|
+
queryFn: TQueryFn<TArgs, TData>;
|
|
10
|
+
onCacheEntryAdded?: TOnCacheEntryAdded<TArgs, TData>;
|
|
11
|
+
onQueryStarted?: TOnQueryStarted<TArgs, TData>;
|
|
12
|
+
serializeArgs?: TSerializeArgsFn;
|
|
13
|
+
compareArg?: TCompareArgsFn;
|
|
14
|
+
cacheLifetime?: number;
|
|
15
|
+
beforeDevtoolsPush?: TBeforeDevtoolsPushFn<TMachine<TData, TError>>;
|
|
16
|
+
maxSnapshotDataAge?: number;
|
|
17
|
+
doCacheArgs?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** ResourceV2 instance (public API) */
|
|
20
|
+
export interface IResourceV2<TArgs, TData, TError = Error> {
|
|
21
|
+
/** Create an agent (observer with SWR) */
|
|
22
|
+
createAgent(): IResourceV2Agent<TArgs, TData, TError>;
|
|
23
|
+
/** Execute query, returns promise of cache entry */
|
|
24
|
+
query(args: TArgs, doForce?: boolean): Promise<ICacheEntry<TData, TError>>;
|
|
25
|
+
/** Reactive query — returns current machine state as signal read */
|
|
26
|
+
query$(args: TArgs, doForce?: boolean): TMachine<TData, TError>;
|
|
27
|
+
/** Get raw cache entry (non-reactive) */
|
|
28
|
+
entry(args: TArgs, doInitiate?: boolean): ICacheEntry<TData, TError> | null;
|
|
29
|
+
/** Get cache entry signal (reactive) */
|
|
30
|
+
entry$(args: TArgs, doInitiate?: boolean): TMachine<TData, TError>;
|
|
31
|
+
/** Force re-fetch for given args */
|
|
32
|
+
invalidate(args: TArgs): void;
|
|
33
|
+
/** Compare two args values */
|
|
34
|
+
compareArgs(a: TArgs, b: TArgs): boolean;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type Prettify<T> = {
|
|
2
|
+
[KeyType in keyof T]: T[KeyType];
|
|
3
|
+
} & {};
|
|
4
|
+
/** Serialize args to string cache key */
|
|
5
|
+
export type TSerializeArgsFn = (args: unknown) => string;
|
|
6
|
+
/** Compare two args for equality (used in 'compare' strategy) */
|
|
7
|
+
export type TCompareArgsFn = (a: unknown, b: unknown) => boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Intercepts machine state before pushing to Redux DevTools.
|
|
10
|
+
* Default behavior: push machine.state (plain object).
|
|
11
|
+
* User can transform or filter.
|
|
12
|
+
*/
|
|
13
|
+
export type TBeforeDevtoolsPushFn<TMachineState> = (newValue: TMachineState, push: (value: TMachineState) => void) => void;
|
|
14
|
+
/** Query function signature */
|
|
15
|
+
export type TQueryFn<TArgs, TData> = (args: TArgs, tools: TQueryFnTools) => Promise<TData>;
|
|
16
|
+
export interface TQueryFnTools {
|
|
17
|
+
abortSignal: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
/** NO_VALUE type alias — the runtime value lives in lib/NO_VALUE.ts */
|
|
20
|
+
export type NO_VALUE = typeof import("../lib/NO_VALUE").NO_VALUE;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Full API snapshot for SSR */
|
|
2
|
+
export interface TApiSnapshot {
|
|
3
|
+
/** Format version (integer counter) */
|
|
4
|
+
version: number;
|
|
5
|
+
/** keyPrefix of the API instance */
|
|
6
|
+
keyPrefix: string | null;
|
|
7
|
+
/** Resource snapshots keyed by resource key */
|
|
8
|
+
resources: Record<string, TResourceSnapshot>;
|
|
9
|
+
}
|
|
10
|
+
/** Single resource snapshot */
|
|
11
|
+
export interface TResourceSnapshot {
|
|
12
|
+
/** Cache entries keyed by serialized args */
|
|
13
|
+
entries: Record<string, TResourceV2SnapshotSlice>;
|
|
14
|
+
}
|
|
15
|
+
/** Single cache entry snapshot */
|
|
16
|
+
export interface TResourceV2SnapshotSlice<TData = unknown> {
|
|
17
|
+
status: "success";
|
|
18
|
+
args: unknown;
|
|
19
|
+
data: TData;
|
|
20
|
+
updatedAt: number;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -40,16 +40,20 @@ export const Batcher = {
|
|
|
40
40
|
if (!Scheduled.isLocked)
|
|
41
41
|
return fn();
|
|
42
42
|
Scheduled.set(rang, fn);
|
|
43
|
-
}
|
|
43
|
+
},
|
|
44
44
|
};
|
|
45
45
|
},
|
|
46
46
|
run(fn) {
|
|
47
47
|
if (Scheduled.isLocked)
|
|
48
48
|
return fn();
|
|
49
49
|
Scheduled.isLocked = true;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
try {
|
|
51
|
+
const v = fn();
|
|
52
|
+
Scheduled.run();
|
|
53
|
+
return v;
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
Scheduled.isLocked = false;
|
|
57
|
+
}
|
|
54
58
|
},
|
|
55
59
|
};
|
|
@@ -3,7 +3,7 @@ import { DependencyTracker } from "../../signals";
|
|
|
3
3
|
* Кеш для хранения вычисленного значения и его зависимостей
|
|
4
4
|
*/
|
|
5
5
|
export class ComputeCache {
|
|
6
|
-
static _NO_VALUE = Symbol(
|
|
6
|
+
static _NO_VALUE = Symbol("no-value");
|
|
7
7
|
_cachedValue = ComputeCache._NO_VALUE;
|
|
8
8
|
_dependencies = [];
|
|
9
9
|
/**
|
|
@@ -14,7 +14,7 @@ export class ComputeCache {
|
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
16
|
// Проверяем, что все зависимости имеют те же значения
|
|
17
|
-
return this._dependencies.every(dep => {
|
|
17
|
+
return this._dependencies.every((dep) => {
|
|
18
18
|
try {
|
|
19
19
|
const currentValue = dep.peek();
|
|
20
20
|
return Object.is(currentValue, dep.lastValue);
|
|
@@ -45,7 +45,7 @@ export class ComputeCache {
|
|
|
45
45
|
// Вычисляем значение
|
|
46
46
|
const result = computeFn();
|
|
47
47
|
// Получаем текущие значения зависимостей
|
|
48
|
-
dependencies.forEach(dep => {
|
|
48
|
+
dependencies.forEach((dep) => {
|
|
49
49
|
dep.lastValue = dep.peek();
|
|
50
50
|
});
|
|
51
51
|
// Сохраняем результат и зависимости
|
|
@@ -4,7 +4,7 @@ export class DependencyTracker {
|
|
|
4
4
|
this._currentHandler?.(dep);
|
|
5
5
|
}
|
|
6
6
|
static start(handler) {
|
|
7
|
-
|
|
7
|
+
const prevHandler = this._currentHandler;
|
|
8
8
|
this._currentHandler = handler;
|
|
9
9
|
return () => {
|
|
10
10
|
this._currentHandler = prevHandler;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SignalLifecycleHook, SignalOptions } from "../../signals/types";
|
|
2
2
|
export declare const Devtools: {
|
|
3
|
-
createState<T>(initialValue: T, optionsDry?:
|
|
3
|
+
createState<T>(initialValue: T, optionsDry?: SignalOptions<T> | string): ((newState: T) => void) | null;
|
|
4
|
+
createSignalHooks<T>(initialValue: T, options?: SignalOptions<T>): SignalLifecycleHook<T> | null;
|
|
4
5
|
readonly hasDevtools: boolean;
|
|
5
6
|
};
|
|
@@ -2,46 +2,73 @@ import { SharedOptions } from "../../common/options/SharedOptions";
|
|
|
2
2
|
import { Indexer } from "./Indexer";
|
|
3
3
|
export const Devtools = {
|
|
4
4
|
createState(initialValue, optionsDry = {}) {
|
|
5
|
-
const options = typeof optionsDry ===
|
|
6
|
-
? { name: optionsDry }
|
|
7
|
-
: optionsDry;
|
|
5
|
+
const options = typeof optionsDry === "string" ? { name: optionsDry } : optionsDry;
|
|
8
6
|
if (options.isDisabled)
|
|
9
7
|
return null;
|
|
10
|
-
|
|
8
|
+
const createStateDevtools = SharedOptions.DEVTOOLS?.state;
|
|
11
9
|
if (!createStateDevtools)
|
|
12
10
|
return null;
|
|
13
|
-
const key = createKey(options.name, options.base);
|
|
14
|
-
let stateDevtools =
|
|
15
|
-
|
|
16
|
-
: createStateDevtools(key, initialValue);
|
|
17
|
-
return (newState) => {
|
|
18
|
-
if (options._skipValues?.includes(newState)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
11
|
+
const key = createKey(options.key ?? options.name, options.base);
|
|
12
|
+
let stateDevtools = null;
|
|
13
|
+
const push = (value) => {
|
|
21
14
|
if (!stateDevtools) {
|
|
22
|
-
stateDevtools = createStateDevtools(key,
|
|
15
|
+
stateDevtools = createStateDevtools(key, value);
|
|
23
16
|
return;
|
|
24
17
|
}
|
|
25
|
-
stateDevtools(
|
|
18
|
+
stateDevtools(value);
|
|
19
|
+
};
|
|
20
|
+
// Init
|
|
21
|
+
if (options.beforeDevtoolsPush) {
|
|
22
|
+
options.beforeDevtoolsPush(initialValue, push);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
push(initialValue);
|
|
26
|
+
}
|
|
27
|
+
return (newState) => {
|
|
28
|
+
if (options.beforeDevtoolsPush) {
|
|
29
|
+
options.beforeDevtoolsPush(newState, push);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
push(newState);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
createSignalHooks(initialValue, options = {}) {
|
|
37
|
+
const stateDevtools = this.createState(initialValue, {
|
|
38
|
+
key: options.key,
|
|
39
|
+
name: options.name,
|
|
40
|
+
base: options.base,
|
|
41
|
+
isDisabled: options.isDisabled,
|
|
42
|
+
beforeDevtoolsPush: options.beforeDevtoolsPush,
|
|
43
|
+
});
|
|
44
|
+
if (!stateDevtools)
|
|
45
|
+
return null;
|
|
46
|
+
return {
|
|
47
|
+
onChange(newValue) {
|
|
48
|
+
stateDevtools(newValue);
|
|
49
|
+
},
|
|
50
|
+
onDispose() {
|
|
51
|
+
stateDevtools("$COMPLETED");
|
|
52
|
+
},
|
|
26
53
|
};
|
|
27
54
|
},
|
|
28
55
|
get hasDevtools() {
|
|
29
56
|
return !!SharedOptions.DEVTOOLS?.state;
|
|
30
57
|
},
|
|
31
58
|
};
|
|
32
|
-
function createKey(
|
|
59
|
+
function createKey(key, base) {
|
|
33
60
|
const i = Indexer.getIndex();
|
|
34
|
-
let
|
|
35
|
-
if (
|
|
36
|
-
const scopeName = SharedOptions.getScopeName?.() ||
|
|
37
|
-
|
|
61
|
+
let result = "";
|
|
62
|
+
if (key?.includes("{scope}")) {
|
|
63
|
+
const scopeName = SharedOptions.getScopeName?.() || "#global";
|
|
64
|
+
key = key.replace("{scope}", scopeName);
|
|
38
65
|
}
|
|
39
|
-
if (base &&
|
|
40
|
-
|
|
41
|
-
else if (!base &&
|
|
42
|
-
|
|
43
|
-
else if (base && !
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return
|
|
66
|
+
if (base && key)
|
|
67
|
+
result += key.replace("{base}", base);
|
|
68
|
+
else if (!base && key)
|
|
69
|
+
result += key;
|
|
70
|
+
else if (base && !key)
|
|
71
|
+
result += `${base}/`;
|
|
72
|
+
result += `#i=${i}`;
|
|
73
|
+
return result;
|
|
47
74
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
|
-
const empty = Symbol(
|
|
2
|
+
const empty = Symbol("EMPTY");
|
|
3
3
|
export class SyncObservable extends Observable {
|
|
4
|
-
constructor(subscribe) {
|
|
5
|
-
super(subscribe);
|
|
6
|
-
}
|
|
7
4
|
get value() {
|
|
8
5
|
let value = empty;
|
|
9
6
|
const sub = this.subscribe((v) => {
|
|
@@ -11,7 +8,7 @@ export class SyncObservable extends Observable {
|
|
|
11
8
|
});
|
|
12
9
|
sub.unsubscribe();
|
|
13
10
|
if (value === empty) {
|
|
14
|
-
throw new Error(
|
|
11
|
+
throw new Error("No value emitted");
|
|
15
12
|
}
|
|
16
13
|
return value;
|
|
17
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
1
|
+
export * from "./Batcher";
|
|
2
|
+
export * from "./DependencyTracker";
|
|
3
|
+
export * from "./ComputeCache";
|
|
4
|
+
export * from "./Devtools";
|
|
5
|
+
export * from "./ReadonlySignal";
|
|
6
|
+
export * from "./SyncObservable";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
1
|
+
export * from "./Batcher";
|
|
2
|
+
export * from "./DependencyTracker";
|
|
3
|
+
export * from "./ComputeCache";
|
|
4
|
+
export * from "./Devtools";
|
|
5
|
+
export * from "./ReadonlySignal";
|
|
6
|
+
export * from "./SyncObservable";
|
package/dist/signals/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./base";
|
|
2
|
+
export * from "./operators";
|
|
3
|
+
export * from "./react";
|
|
4
|
+
export * from "./signals";
|
|
5
|
+
export * from "./types";
|
package/dist/signals/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./base";
|
|
2
|
+
export * from "./operators";
|
|
3
|
+
export * from "./react";
|
|
4
|
+
export * from "./signals";
|
|
5
|
+
export * from "./types";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./signalize";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./signalize";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./useSignal";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./useSignal";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ComputeFn } from "../../signals/types";
|
|
1
|
+
import { ComputeFn, SignalOptionsOrKey } from "../../signals/types";
|
|
3
2
|
export declare class Computed<T> {
|
|
4
3
|
private _computeFn;
|
|
5
4
|
private _state$;
|
|
@@ -9,11 +8,11 @@ export declare class Computed<T> {
|
|
|
9
8
|
* Кеш для хранения вычисленного значения (без подписки) и его зависимостей
|
|
10
9
|
*/
|
|
11
10
|
private _computeCache;
|
|
12
|
-
constructor(_computeFn: () => T, options?:
|
|
11
|
+
constructor(_computeFn: () => T, options?: SignalOptionsOrKey<T>);
|
|
13
12
|
get(): T;
|
|
14
13
|
peek(): T;
|
|
15
14
|
private _start;
|
|
16
15
|
private _stop;
|
|
17
16
|
private static _EMPTY;
|
|
18
|
-
static create<T>(computeFn: () => T, options?:
|
|
17
|
+
static create<T>(computeFn: () => T, options?: SignalOptionsOrKey<T>): ComputeFn<T>;
|
|
19
18
|
}
|