@flurryx/store 0.7.6 → 0.8.1
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 +33 -3
- package/dist/index.cjs +116 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -36
- package/dist/index.d.ts +46 -36
- package/dist/index.js +115 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Signal, InjectionToken } from '@angular/core';
|
|
2
2
|
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
3
|
|
|
4
|
+
type StoreDataShape<TData> = {
|
|
5
|
+
[K in keyof TData]: ResourceState<unknown>;
|
|
6
|
+
};
|
|
7
|
+
type StoreKey<TData> = keyof TData & string;
|
|
4
8
|
/**
|
|
5
9
|
* Phantom-typed marker for a store resource slot.
|
|
6
10
|
* Carries type information at compile time with zero runtime cost.
|
|
@@ -31,23 +35,23 @@ type InferData<TConfig extends StoreConfig> = {
|
|
|
31
35
|
* Maps a plain config interface to ResourceState-wrapped data.
|
|
32
36
|
* e.g. { SESSIONS: ChatSession[] } -> { SESSIONS: ResourceState<ChatSession[]> }
|
|
33
37
|
*/
|
|
34
|
-
type ConfigToData<TConfig extends
|
|
38
|
+
type ConfigToData<TConfig extends object> = {
|
|
35
39
|
[K in keyof TConfig & string]: ResourceState<TConfig[K]>;
|
|
36
40
|
};
|
|
37
41
|
/**
|
|
38
42
|
* Shared store interface implemented by both BaseStore and LazyStore.
|
|
39
43
|
*/
|
|
40
|
-
interface IStore<TData extends
|
|
41
|
-
get<K extends
|
|
42
|
-
update<K extends
|
|
43
|
-
clear<K extends
|
|
44
|
+
interface IStore<TData extends StoreDataShape<TData>> {
|
|
45
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
46
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
47
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
44
48
|
clearAll(): void;
|
|
45
|
-
startLoading<K extends
|
|
46
|
-
stopLoading<K extends
|
|
47
|
-
updateKeyedOne<K extends
|
|
48
|
-
clearKeyedOne<K extends
|
|
49
|
-
startKeyedLoading<K extends
|
|
50
|
-
onUpdate<K extends
|
|
49
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
50
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
51
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
52
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
53
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
54
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
@@ -75,20 +79,21 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
75
79
|
* Used by the `Store.for<Config>().build()` API where keys are
|
|
76
80
|
* known only at the type level (no runtime enum).
|
|
77
81
|
*/
|
|
78
|
-
declare class LazyStore<TData extends
|
|
82
|
+
declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<TData> {
|
|
79
83
|
private readonly signals;
|
|
80
84
|
private readonly hooks;
|
|
85
|
+
constructor();
|
|
81
86
|
private getOrCreate;
|
|
82
|
-
get<K extends
|
|
83
|
-
update<K extends
|
|
84
|
-
clear<K extends
|
|
87
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
88
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
89
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
85
90
|
clearAll(): void;
|
|
86
|
-
startLoading<K extends
|
|
87
|
-
stopLoading<K extends
|
|
88
|
-
updateKeyedOne<K extends
|
|
89
|
-
clearKeyedOne<K extends
|
|
90
|
-
startKeyedLoading<K extends
|
|
91
|
-
onUpdate<K extends
|
|
91
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
92
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
93
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
94
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
95
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
96
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
92
97
|
private notifyHooks;
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -104,10 +109,11 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
|
|
|
104
109
|
*/
|
|
105
110
|
interface StoreBuilder<TAccum extends StoreConfig> {
|
|
106
111
|
resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
|
|
107
|
-
mirror<TSourceData extends
|
|
108
|
-
|
|
112
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
113
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
114
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
109
115
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
110
|
-
}, targetKey?:
|
|
116
|
+
}, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
111
117
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
112
118
|
}
|
|
113
119
|
/** Keys from the enum that have NOT yet been defined. */
|
|
@@ -121,19 +127,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
|
|
|
121
127
|
* defined yet. `.build()` is only available when all keys are accounted for.
|
|
122
128
|
*/
|
|
123
129
|
type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
|
|
124
|
-
mirror<TSourceData extends
|
|
125
|
-
|
|
130
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
131
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
132
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
126
133
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
127
|
-
}, targetKey?:
|
|
134
|
+
}, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
128
135
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
129
136
|
} : {
|
|
130
137
|
resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
|
|
131
138
|
};
|
|
132
|
-
interface InterfaceBuilder<TConfig extends
|
|
133
|
-
mirror<TSourceData extends
|
|
134
|
-
|
|
139
|
+
interface InterfaceBuilder<TConfig extends object> {
|
|
140
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
141
|
+
mirrorSelf(sourceKey: StoreKey<ConfigToData<TConfig>>, targetKey: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
142
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
135
143
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
136
|
-
}, targetKey?:
|
|
144
|
+
}, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
137
145
|
build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
|
|
138
146
|
}
|
|
139
147
|
interface StoreEntry {
|
|
@@ -156,7 +164,7 @@ interface StoreEntry {
|
|
|
156
164
|
* }
|
|
157
165
|
* const ChatStore = Store.for<ChatStoreConfig>().build();
|
|
158
166
|
*/
|
|
159
|
-
for<TConfig extends
|
|
167
|
+
for<TConfig extends object>(): InterfaceBuilder<TConfig>;
|
|
160
168
|
/**
|
|
161
169
|
* Bind the builder to an enum object for compile-time key validation.
|
|
162
170
|
*
|
|
@@ -167,7 +175,7 @@ interface StoreEntry {
|
|
|
167
175
|
* .resource('B').as<number>()
|
|
168
176
|
* .build();
|
|
169
177
|
*/
|
|
170
|
-
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<
|
|
178
|
+
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<never, never>>;
|
|
171
179
|
}
|
|
172
180
|
/**
|
|
173
181
|
* Fluent store builder entry point.
|
|
@@ -189,6 +197,8 @@ interface StoreEntry {
|
|
|
189
197
|
*/
|
|
190
198
|
declare const Store: StoreEntry;
|
|
191
199
|
|
|
200
|
+
declare function clearAllStores(): void;
|
|
201
|
+
|
|
192
202
|
interface MirrorOptions {
|
|
193
203
|
destroyRef?: {
|
|
194
204
|
onDestroy: (fn: () => void) => void;
|
|
@@ -205,7 +215,7 @@ interface MirrorOptions {
|
|
|
205
215
|
* @param options - Mirror options when a target key is provided
|
|
206
216
|
* @returns Cleanup function to stop mirroring
|
|
207
217
|
*/
|
|
208
|
-
declare function mirrorKey<TSource extends
|
|
218
|
+
declare function mirrorKey<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions, options?: MirrorOptions): () => void;
|
|
209
219
|
|
|
210
220
|
interface CollectKeyedOptions<TEntity> {
|
|
211
221
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
@@ -229,6 +239,6 @@ interface CollectKeyedOptions<TEntity> {
|
|
|
229
239
|
* @param options - Collect options when a target key is provided
|
|
230
240
|
* @returns Cleanup function to stop collecting
|
|
231
241
|
*/
|
|
232
|
-
declare function collectKeyed<TSource extends
|
|
242
|
+
declare function collectKeyed<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>, TEntity = unknown>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>, options?: CollectKeyedOptions<TEntity>): () => void;
|
|
233
243
|
|
|
234
|
-
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, collectKeyed, mirrorKey };
|
|
244
|
+
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, clearAllStores, collectKeyed, mirrorKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Signal, InjectionToken } from '@angular/core';
|
|
2
2
|
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
3
|
|
|
4
|
+
type StoreDataShape<TData> = {
|
|
5
|
+
[K in keyof TData]: ResourceState<unknown>;
|
|
6
|
+
};
|
|
7
|
+
type StoreKey<TData> = keyof TData & string;
|
|
4
8
|
/**
|
|
5
9
|
* Phantom-typed marker for a store resource slot.
|
|
6
10
|
* Carries type information at compile time with zero runtime cost.
|
|
@@ -31,23 +35,23 @@ type InferData<TConfig extends StoreConfig> = {
|
|
|
31
35
|
* Maps a plain config interface to ResourceState-wrapped data.
|
|
32
36
|
* e.g. { SESSIONS: ChatSession[] } -> { SESSIONS: ResourceState<ChatSession[]> }
|
|
33
37
|
*/
|
|
34
|
-
type ConfigToData<TConfig extends
|
|
38
|
+
type ConfigToData<TConfig extends object> = {
|
|
35
39
|
[K in keyof TConfig & string]: ResourceState<TConfig[K]>;
|
|
36
40
|
};
|
|
37
41
|
/**
|
|
38
42
|
* Shared store interface implemented by both BaseStore and LazyStore.
|
|
39
43
|
*/
|
|
40
|
-
interface IStore<TData extends
|
|
41
|
-
get<K extends
|
|
42
|
-
update<K extends
|
|
43
|
-
clear<K extends
|
|
44
|
+
interface IStore<TData extends StoreDataShape<TData>> {
|
|
45
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
46
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
47
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
44
48
|
clearAll(): void;
|
|
45
|
-
startLoading<K extends
|
|
46
|
-
stopLoading<K extends
|
|
47
|
-
updateKeyedOne<K extends
|
|
48
|
-
clearKeyedOne<K extends
|
|
49
|
-
startKeyedLoading<K extends
|
|
50
|
-
onUpdate<K extends
|
|
49
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
50
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
51
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
52
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
53
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
54
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
@@ -75,20 +79,21 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
75
79
|
* Used by the `Store.for<Config>().build()` API where keys are
|
|
76
80
|
* known only at the type level (no runtime enum).
|
|
77
81
|
*/
|
|
78
|
-
declare class LazyStore<TData extends
|
|
82
|
+
declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<TData> {
|
|
79
83
|
private readonly signals;
|
|
80
84
|
private readonly hooks;
|
|
85
|
+
constructor();
|
|
81
86
|
private getOrCreate;
|
|
82
|
-
get<K extends
|
|
83
|
-
update<K extends
|
|
84
|
-
clear<K extends
|
|
87
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
88
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
89
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
85
90
|
clearAll(): void;
|
|
86
|
-
startLoading<K extends
|
|
87
|
-
stopLoading<K extends
|
|
88
|
-
updateKeyedOne<K extends
|
|
89
|
-
clearKeyedOne<K extends
|
|
90
|
-
startKeyedLoading<K extends
|
|
91
|
-
onUpdate<K extends
|
|
91
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
92
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
93
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
94
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
95
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
96
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
92
97
|
private notifyHooks;
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -104,10 +109,11 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
|
|
|
104
109
|
*/
|
|
105
110
|
interface StoreBuilder<TAccum extends StoreConfig> {
|
|
106
111
|
resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
|
|
107
|
-
mirror<TSourceData extends
|
|
108
|
-
|
|
112
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
113
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
114
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
109
115
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
110
|
-
}, targetKey?:
|
|
116
|
+
}, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
111
117
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
112
118
|
}
|
|
113
119
|
/** Keys from the enum that have NOT yet been defined. */
|
|
@@ -121,19 +127,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
|
|
|
121
127
|
* defined yet. `.build()` is only available when all keys are accounted for.
|
|
122
128
|
*/
|
|
123
129
|
type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
|
|
124
|
-
mirror<TSourceData extends
|
|
125
|
-
|
|
130
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
131
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
132
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
126
133
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
127
|
-
}, targetKey?:
|
|
134
|
+
}, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
128
135
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
129
136
|
} : {
|
|
130
137
|
resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
|
|
131
138
|
};
|
|
132
|
-
interface InterfaceBuilder<TConfig extends
|
|
133
|
-
mirror<TSourceData extends
|
|
134
|
-
|
|
139
|
+
interface InterfaceBuilder<TConfig extends object> {
|
|
140
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
141
|
+
mirrorSelf(sourceKey: StoreKey<ConfigToData<TConfig>>, targetKey: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
142
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
135
143
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
136
|
-
}, targetKey?:
|
|
144
|
+
}, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
137
145
|
build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
|
|
138
146
|
}
|
|
139
147
|
interface StoreEntry {
|
|
@@ -156,7 +164,7 @@ interface StoreEntry {
|
|
|
156
164
|
* }
|
|
157
165
|
* const ChatStore = Store.for<ChatStoreConfig>().build();
|
|
158
166
|
*/
|
|
159
|
-
for<TConfig extends
|
|
167
|
+
for<TConfig extends object>(): InterfaceBuilder<TConfig>;
|
|
160
168
|
/**
|
|
161
169
|
* Bind the builder to an enum object for compile-time key validation.
|
|
162
170
|
*
|
|
@@ -167,7 +175,7 @@ interface StoreEntry {
|
|
|
167
175
|
* .resource('B').as<number>()
|
|
168
176
|
* .build();
|
|
169
177
|
*/
|
|
170
|
-
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<
|
|
178
|
+
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<never, never>>;
|
|
171
179
|
}
|
|
172
180
|
/**
|
|
173
181
|
* Fluent store builder entry point.
|
|
@@ -189,6 +197,8 @@ interface StoreEntry {
|
|
|
189
197
|
*/
|
|
190
198
|
declare const Store: StoreEntry;
|
|
191
199
|
|
|
200
|
+
declare function clearAllStores(): void;
|
|
201
|
+
|
|
192
202
|
interface MirrorOptions {
|
|
193
203
|
destroyRef?: {
|
|
194
204
|
onDestroy: (fn: () => void) => void;
|
|
@@ -205,7 +215,7 @@ interface MirrorOptions {
|
|
|
205
215
|
* @param options - Mirror options when a target key is provided
|
|
206
216
|
* @returns Cleanup function to stop mirroring
|
|
207
217
|
*/
|
|
208
|
-
declare function mirrorKey<TSource extends
|
|
218
|
+
declare function mirrorKey<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions, options?: MirrorOptions): () => void;
|
|
209
219
|
|
|
210
220
|
interface CollectKeyedOptions<TEntity> {
|
|
211
221
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
@@ -229,6 +239,6 @@ interface CollectKeyedOptions<TEntity> {
|
|
|
229
239
|
* @param options - Collect options when a target key is provided
|
|
230
240
|
* @returns Cleanup function to stop collecting
|
|
231
241
|
*/
|
|
232
|
-
declare function collectKeyed<TSource extends
|
|
242
|
+
declare function collectKeyed<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>, TEntity = unknown>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>, options?: CollectKeyedOptions<TEntity>): () => void;
|
|
233
243
|
|
|
234
|
-
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, collectKeyed, mirrorKey };
|
|
244
|
+
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, clearAllStores, collectKeyed, mirrorKey };
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,26 @@ import {
|
|
|
5
5
|
isKeyedResourceData,
|
|
6
6
|
createKeyedResourceData
|
|
7
7
|
} from "@flurryx/core";
|
|
8
|
+
|
|
9
|
+
// src/store-registry.ts
|
|
10
|
+
var trackedStores = /* @__PURE__ */ new Set();
|
|
11
|
+
function trackStore(store) {
|
|
12
|
+
trackedStores.add(store);
|
|
13
|
+
}
|
|
14
|
+
function clearAllStores() {
|
|
15
|
+
for (const store of [...trackedStores]) {
|
|
16
|
+
store.clearAll();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/base-store.ts
|
|
8
21
|
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
9
22
|
var BaseStore = class {
|
|
10
23
|
constructor(storeEnum) {
|
|
11
24
|
this.storeEnum = storeEnum;
|
|
12
25
|
this.initializeState();
|
|
13
26
|
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
27
|
+
trackStore(this);
|
|
14
28
|
}
|
|
15
29
|
signalsState = /* @__PURE__ */ new Map();
|
|
16
30
|
get(key) {
|
|
@@ -263,6 +277,9 @@ function createDefaultState() {
|
|
|
263
277
|
var LazyStore = class {
|
|
264
278
|
signals = /* @__PURE__ */ new Map();
|
|
265
279
|
hooks = /* @__PURE__ */ new Map();
|
|
280
|
+
constructor() {
|
|
281
|
+
trackStore(this);
|
|
282
|
+
}
|
|
266
283
|
getOrCreate(key) {
|
|
267
284
|
let sig = this.signals.get(key);
|
|
268
285
|
if (!sig) {
|
|
@@ -575,7 +592,22 @@ function wireMirrorKeyed(store, defs) {
|
|
|
575
592
|
}
|
|
576
593
|
return store;
|
|
577
594
|
}
|
|
578
|
-
|
|
595
|
+
var MIRROR_SELF_SAME_KEY_ERROR = "mirrorSelf source and target keys must be different";
|
|
596
|
+
function wireSelfMirrors(store, defs) {
|
|
597
|
+
for (const def of defs) {
|
|
598
|
+
if (def.sourceKey === def.targetKey) {
|
|
599
|
+
throw new Error(MIRROR_SELF_SAME_KEY_ERROR);
|
|
600
|
+
}
|
|
601
|
+
mirrorKey(
|
|
602
|
+
store,
|
|
603
|
+
def.sourceKey,
|
|
604
|
+
store,
|
|
605
|
+
def.targetKey
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
return store;
|
|
609
|
+
}
|
|
610
|
+
function createBuilder(accum, mirrors = [], mirrorKeyedDefs = [], selfMirrors = []) {
|
|
579
611
|
return {
|
|
580
612
|
resource(key) {
|
|
581
613
|
return {
|
|
@@ -584,7 +616,12 @@ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
|
|
|
584
616
|
...accum,
|
|
585
617
|
[key]: resource()
|
|
586
618
|
};
|
|
587
|
-
return createBuilder(
|
|
619
|
+
return createBuilder(
|
|
620
|
+
nextAccum,
|
|
621
|
+
mirrors,
|
|
622
|
+
mirrorKeyedDefs,
|
|
623
|
+
selfMirrors
|
|
624
|
+
);
|
|
588
625
|
}
|
|
589
626
|
};
|
|
590
627
|
},
|
|
@@ -594,7 +631,22 @@ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
|
|
|
594
631
|
sourceKey,
|
|
595
632
|
targetKey: targetKey ?? sourceKey
|
|
596
633
|
};
|
|
597
|
-
return createBuilder(
|
|
634
|
+
return createBuilder(
|
|
635
|
+
accum,
|
|
636
|
+
[...mirrors, def],
|
|
637
|
+
mirrorKeyedDefs,
|
|
638
|
+
selfMirrors
|
|
639
|
+
);
|
|
640
|
+
},
|
|
641
|
+
mirrorSelf(sourceKey, targetKey) {
|
|
642
|
+
const def = {
|
|
643
|
+
sourceKey,
|
|
644
|
+
targetKey
|
|
645
|
+
};
|
|
646
|
+
return createBuilder(accum, mirrors, mirrorKeyedDefs, [
|
|
647
|
+
...selfMirrors,
|
|
648
|
+
def
|
|
649
|
+
]);
|
|
598
650
|
},
|
|
599
651
|
mirrorKeyed(source, sourceKey, options, targetKey) {
|
|
600
652
|
const def = {
|
|
@@ -603,7 +655,12 @@ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
|
|
|
603
655
|
targetKey: targetKey ?? sourceKey,
|
|
604
656
|
extractId: options.extractId
|
|
605
657
|
};
|
|
606
|
-
return createBuilder(
|
|
658
|
+
return createBuilder(
|
|
659
|
+
accum,
|
|
660
|
+
mirrors,
|
|
661
|
+
[...mirrorKeyedDefs, def],
|
|
662
|
+
selfMirrors
|
|
663
|
+
);
|
|
607
664
|
},
|
|
608
665
|
build() {
|
|
609
666
|
return new InjectionToken("FlurryxStore", {
|
|
@@ -612,13 +669,14 @@ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
|
|
|
612
669
|
const store = new DynamicStore(accum);
|
|
613
670
|
wireMirrors(store, mirrors);
|
|
614
671
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
672
|
+
wireSelfMirrors(store, selfMirrors);
|
|
615
673
|
return store;
|
|
616
674
|
}
|
|
617
675
|
});
|
|
618
676
|
}
|
|
619
677
|
};
|
|
620
678
|
}
|
|
621
|
-
function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs = []) {
|
|
679
|
+
function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs = [], selfMirrors = []) {
|
|
622
680
|
return {
|
|
623
681
|
resource(key) {
|
|
624
682
|
return {
|
|
@@ -631,7 +689,8 @@ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs
|
|
|
631
689
|
_enumObj,
|
|
632
690
|
nextAccum,
|
|
633
691
|
mirrors,
|
|
634
|
-
mirrorKeyedDefs
|
|
692
|
+
mirrorKeyedDefs,
|
|
693
|
+
selfMirrors
|
|
635
694
|
);
|
|
636
695
|
}
|
|
637
696
|
};
|
|
@@ -646,7 +705,21 @@ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs
|
|
|
646
705
|
_enumObj,
|
|
647
706
|
accum,
|
|
648
707
|
[...mirrors, def],
|
|
649
|
-
mirrorKeyedDefs
|
|
708
|
+
mirrorKeyedDefs,
|
|
709
|
+
selfMirrors
|
|
710
|
+
);
|
|
711
|
+
},
|
|
712
|
+
mirrorSelf(sourceKey, targetKey) {
|
|
713
|
+
const def = {
|
|
714
|
+
sourceKey,
|
|
715
|
+
targetKey
|
|
716
|
+
};
|
|
717
|
+
return createConstrainedBuilder(
|
|
718
|
+
_enumObj,
|
|
719
|
+
accum,
|
|
720
|
+
mirrors,
|
|
721
|
+
mirrorKeyedDefs,
|
|
722
|
+
[...selfMirrors, def]
|
|
650
723
|
);
|
|
651
724
|
},
|
|
652
725
|
mirrorKeyed(source, sourceKey, options, targetKey) {
|
|
@@ -656,10 +729,13 @@ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs
|
|
|
656
729
|
targetKey: targetKey ?? sourceKey,
|
|
657
730
|
extractId: options.extractId
|
|
658
731
|
};
|
|
659
|
-
return createConstrainedBuilder(
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
732
|
+
return createConstrainedBuilder(
|
|
733
|
+
_enumObj,
|
|
734
|
+
accum,
|
|
735
|
+
mirrors,
|
|
736
|
+
[...mirrorKeyedDefs, def],
|
|
737
|
+
selfMirrors
|
|
738
|
+
);
|
|
663
739
|
},
|
|
664
740
|
build() {
|
|
665
741
|
return new InjectionToken("FlurryxStore", {
|
|
@@ -668,13 +744,14 @@ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs
|
|
|
668
744
|
const store = new DynamicStore(accum);
|
|
669
745
|
wireMirrors(store, mirrors);
|
|
670
746
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
747
|
+
wireSelfMirrors(store, selfMirrors);
|
|
671
748
|
return store;
|
|
672
749
|
}
|
|
673
750
|
});
|
|
674
751
|
}
|
|
675
752
|
};
|
|
676
753
|
}
|
|
677
|
-
function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
|
|
754
|
+
function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = [], selfMirrors = []) {
|
|
678
755
|
return {
|
|
679
756
|
mirror(source, sourceKey, targetKey) {
|
|
680
757
|
const def = {
|
|
@@ -684,9 +761,20 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
|
|
|
684
761
|
};
|
|
685
762
|
return createInterfaceBuilder(
|
|
686
763
|
[...mirrors, def],
|
|
687
|
-
mirrorKeyedDefs
|
|
764
|
+
mirrorKeyedDefs,
|
|
765
|
+
selfMirrors
|
|
688
766
|
);
|
|
689
767
|
},
|
|
768
|
+
mirrorSelf(sourceKey, targetKey) {
|
|
769
|
+
const def = {
|
|
770
|
+
sourceKey,
|
|
771
|
+
targetKey
|
|
772
|
+
};
|
|
773
|
+
return createInterfaceBuilder(mirrors, mirrorKeyedDefs, [
|
|
774
|
+
...selfMirrors,
|
|
775
|
+
def
|
|
776
|
+
]);
|
|
777
|
+
},
|
|
690
778
|
mirrorKeyed(source, sourceKey, options, targetKey) {
|
|
691
779
|
const def = {
|
|
692
780
|
sourceToken: source,
|
|
@@ -694,10 +782,11 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
|
|
|
694
782
|
targetKey: targetKey ?? sourceKey,
|
|
695
783
|
extractId: options.extractId
|
|
696
784
|
};
|
|
697
|
-
return createInterfaceBuilder(
|
|
698
|
-
|
|
699
|
-
def
|
|
700
|
-
|
|
785
|
+
return createInterfaceBuilder(
|
|
786
|
+
mirrors,
|
|
787
|
+
[...mirrorKeyedDefs, def],
|
|
788
|
+
selfMirrors
|
|
789
|
+
);
|
|
701
790
|
},
|
|
702
791
|
build() {
|
|
703
792
|
return new InjectionToken("FlurryxStore", {
|
|
@@ -706,6 +795,7 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
|
|
|
706
795
|
const store = new LazyStore();
|
|
707
796
|
wireMirrors(store, mirrors);
|
|
708
797
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
798
|
+
wireSelfMirrors(store, selfMirrors);
|
|
709
799
|
return store;
|
|
710
800
|
}
|
|
711
801
|
});
|
|
@@ -714,17 +804,19 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
|
|
|
714
804
|
}
|
|
715
805
|
var Store = {
|
|
716
806
|
...createBuilder({}),
|
|
717
|
-
for
|
|
718
|
-
if (arguments.length === 0) {
|
|
719
|
-
return createInterfaceBuilder();
|
|
720
|
-
}
|
|
721
|
-
return createConstrainedBuilder(enumObj, {});
|
|
722
|
-
}
|
|
807
|
+
for: createStoreFor
|
|
723
808
|
};
|
|
809
|
+
function createStoreFor(enumObj) {
|
|
810
|
+
if (arguments.length === 0) {
|
|
811
|
+
return createInterfaceBuilder();
|
|
812
|
+
}
|
|
813
|
+
return createConstrainedBuilder(enumObj, {});
|
|
814
|
+
}
|
|
724
815
|
export {
|
|
725
816
|
BaseStore,
|
|
726
817
|
LazyStore,
|
|
727
818
|
Store,
|
|
819
|
+
clearAllStores,
|
|
728
820
|
collectKeyed,
|
|
729
821
|
mirrorKey
|
|
730
822
|
};
|