@flurryx/store 0.0.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/dist/index.cjs +275 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +252 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
BaseStore: () => BaseStore
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/base-store.ts
|
|
28
|
+
var import_core = require("@angular/core");
|
|
29
|
+
var import_core2 = require("@flurryx/core");
|
|
30
|
+
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
31
|
+
var BaseStore = class {
|
|
32
|
+
constructor(storeEnum) {
|
|
33
|
+
this.storeEnum = storeEnum;
|
|
34
|
+
this.initializeState();
|
|
35
|
+
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
36
|
+
}
|
|
37
|
+
signalsState = /* @__PURE__ */ new Map();
|
|
38
|
+
get(key) {
|
|
39
|
+
return this.signalsState.get(key.toString());
|
|
40
|
+
}
|
|
41
|
+
onUpdate(key, callback) {
|
|
42
|
+
const hooks = updateHooksMap.get(this);
|
|
43
|
+
if (!hooks.has(key)) {
|
|
44
|
+
hooks.set(key, []);
|
|
45
|
+
}
|
|
46
|
+
hooks.get(key).push(
|
|
47
|
+
callback
|
|
48
|
+
);
|
|
49
|
+
return () => {
|
|
50
|
+
const hooksMap = hooks.get(key);
|
|
51
|
+
if (!hooksMap) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const index = hooksMap.indexOf(
|
|
55
|
+
callback
|
|
56
|
+
);
|
|
57
|
+
if (index > -1) {
|
|
58
|
+
hooksMap.splice(index, 1);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
update(key, newState) {
|
|
63
|
+
const currentState = this.signalsState.get(key.toString());
|
|
64
|
+
if (!currentState) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const previousState = currentState();
|
|
68
|
+
currentState.update((state) => ({
|
|
69
|
+
...state,
|
|
70
|
+
...newState
|
|
71
|
+
}));
|
|
72
|
+
const updatedState = currentState();
|
|
73
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
74
|
+
}
|
|
75
|
+
clearAll() {
|
|
76
|
+
Object.keys(this.storeEnum).forEach((key) => {
|
|
77
|
+
this.clear(key);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
clear(key) {
|
|
81
|
+
const currentState = this.signalsState.get(key.toString());
|
|
82
|
+
if (!currentState) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const previousState = currentState();
|
|
86
|
+
const _typedKey = key;
|
|
87
|
+
currentState.set({
|
|
88
|
+
data: void 0,
|
|
89
|
+
isLoading: false,
|
|
90
|
+
status: void 0,
|
|
91
|
+
errors: void 0
|
|
92
|
+
});
|
|
93
|
+
const nextState = currentState();
|
|
94
|
+
this.notifyUpdateHooks(key, nextState, previousState);
|
|
95
|
+
}
|
|
96
|
+
startLoading(key) {
|
|
97
|
+
const currentState = this.signalsState.get(key.toString());
|
|
98
|
+
if (!currentState) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const _typedKey = key;
|
|
102
|
+
currentState.update(
|
|
103
|
+
(state) => ({
|
|
104
|
+
...state,
|
|
105
|
+
status: void 0,
|
|
106
|
+
isLoading: true,
|
|
107
|
+
errors: void 0
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
stopLoading(key) {
|
|
112
|
+
const currentState = this.signalsState.get(key.toString());
|
|
113
|
+
if (!currentState) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const _typedKey = key;
|
|
117
|
+
currentState.update(
|
|
118
|
+
(state) => ({
|
|
119
|
+
...state,
|
|
120
|
+
isLoading: false,
|
|
121
|
+
status: void 0,
|
|
122
|
+
errors: void 0
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
updateKeyedOne(key, resourceKey, entity) {
|
|
127
|
+
const currentState = this.signalsState.get(key.toString());
|
|
128
|
+
if (!currentState) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const state = currentState();
|
|
132
|
+
const data = (0, import_core2.isKeyedResourceData)(state.data) ? state.data : (0, import_core2.createKeyedResourceData)();
|
|
133
|
+
const nextErrors = { ...data.errors };
|
|
134
|
+
delete nextErrors[resourceKey];
|
|
135
|
+
const nextData = {
|
|
136
|
+
...data,
|
|
137
|
+
entities: {
|
|
138
|
+
...data.entities,
|
|
139
|
+
[resourceKey]: entity
|
|
140
|
+
},
|
|
141
|
+
isLoading: {
|
|
142
|
+
...data.isLoading,
|
|
143
|
+
[resourceKey]: false
|
|
144
|
+
},
|
|
145
|
+
status: {
|
|
146
|
+
...data.status,
|
|
147
|
+
[resourceKey]: "Success"
|
|
148
|
+
},
|
|
149
|
+
errors: nextErrors
|
|
150
|
+
};
|
|
151
|
+
this.update(key, {
|
|
152
|
+
data: nextData,
|
|
153
|
+
isLoading: (0, import_core2.isAnyKeyLoading)(nextData.isLoading),
|
|
154
|
+
status: void 0,
|
|
155
|
+
errors: void 0
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
clearKeyedOne(key, resourceKey) {
|
|
159
|
+
const currentState = this.signalsState.get(key.toString());
|
|
160
|
+
if (!currentState) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const previousState = currentState();
|
|
164
|
+
const state = previousState;
|
|
165
|
+
if (!(0, import_core2.isKeyedResourceData)(state.data)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const data = state.data;
|
|
169
|
+
const nextEntities = { ...data.entities };
|
|
170
|
+
delete nextEntities[resourceKey];
|
|
171
|
+
const nextIsLoading = { ...data.isLoading };
|
|
172
|
+
delete nextIsLoading[resourceKey];
|
|
173
|
+
const nextStatus = { ...data.status };
|
|
174
|
+
delete nextStatus[resourceKey];
|
|
175
|
+
const nextErrors = { ...data.errors };
|
|
176
|
+
delete nextErrors[resourceKey];
|
|
177
|
+
const nextData = {
|
|
178
|
+
...data,
|
|
179
|
+
entities: nextEntities,
|
|
180
|
+
isLoading: nextIsLoading,
|
|
181
|
+
status: nextStatus,
|
|
182
|
+
errors: nextErrors
|
|
183
|
+
};
|
|
184
|
+
const _typedKey = key;
|
|
185
|
+
currentState.update(
|
|
186
|
+
(prev) => ({
|
|
187
|
+
...prev,
|
|
188
|
+
data: nextData,
|
|
189
|
+
status: void 0,
|
|
190
|
+
isLoading: (0, import_core2.isAnyKeyLoading)(nextIsLoading),
|
|
191
|
+
errors: void 0
|
|
192
|
+
})
|
|
193
|
+
);
|
|
194
|
+
const updatedState = currentState();
|
|
195
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
196
|
+
}
|
|
197
|
+
startKeyedLoading(key, resourceKey) {
|
|
198
|
+
const currentState = this.signalsState.get(key.toString());
|
|
199
|
+
if (!currentState) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const _typedKey = key;
|
|
203
|
+
const state = currentState();
|
|
204
|
+
if (!(0, import_core2.isKeyedResourceData)(state.data)) {
|
|
205
|
+
this.startLoading(key);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const previousState = state;
|
|
209
|
+
const data = state.data;
|
|
210
|
+
const nextIsLoading = {
|
|
211
|
+
...data.isLoading,
|
|
212
|
+
[resourceKey]: true
|
|
213
|
+
};
|
|
214
|
+
const nextStatus = {
|
|
215
|
+
...data.status
|
|
216
|
+
};
|
|
217
|
+
delete nextStatus[resourceKey];
|
|
218
|
+
const nextErrors = {
|
|
219
|
+
...data.errors
|
|
220
|
+
};
|
|
221
|
+
delete nextErrors[resourceKey];
|
|
222
|
+
const nextData = {
|
|
223
|
+
...data,
|
|
224
|
+
isLoading: nextIsLoading,
|
|
225
|
+
status: nextStatus,
|
|
226
|
+
errors: nextErrors
|
|
227
|
+
};
|
|
228
|
+
currentState.update(
|
|
229
|
+
(previous) => ({
|
|
230
|
+
...previous,
|
|
231
|
+
data: nextData,
|
|
232
|
+
status: void 0,
|
|
233
|
+
isLoading: (0, import_core2.isAnyKeyLoading)(nextIsLoading),
|
|
234
|
+
errors: void 0
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
const updatedState = currentState();
|
|
238
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
239
|
+
}
|
|
240
|
+
notifyUpdateHooks(key, nextState, previousState) {
|
|
241
|
+
const hooks = updateHooksMap.get(this);
|
|
242
|
+
const keyHooks = hooks?.get(key);
|
|
243
|
+
if (!keyHooks) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
keyHooks.forEach(
|
|
247
|
+
(hook) => hook(
|
|
248
|
+
nextState,
|
|
249
|
+
previousState
|
|
250
|
+
)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
initializeState() {
|
|
254
|
+
Object.keys(this.storeEnum).forEach((key) => {
|
|
255
|
+
const _typedKey = key;
|
|
256
|
+
const initialState = {
|
|
257
|
+
data: void 0,
|
|
258
|
+
isLoading: false,
|
|
259
|
+
status: void 0,
|
|
260
|
+
errors: void 0
|
|
261
|
+
};
|
|
262
|
+
this.signalsState.set(
|
|
263
|
+
_typedKey,
|
|
264
|
+
(0, import_core.signal)(
|
|
265
|
+
initialState
|
|
266
|
+
)
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
272
|
+
0 && (module.exports = {
|
|
273
|
+
BaseStore
|
|
274
|
+
});
|
|
275
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/base-store.ts"],"sourcesContent":["export { BaseStore } from './base-store';\n","import { signal, WritableSignal } from '@angular/core';\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from '@flurryx/core';\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n> {\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: 'Success' as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(\n initialState as TData[typeof _typedKey]\n )\n );\n });\n }\n}\n"],"mappings":"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","names":["import_core"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { WritableSignal } from '@angular/core';
|
|
2
|
+
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
|
+
|
|
4
|
+
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
5
|
+
[K in keyof TEnum]: ResourceState<unknown>;
|
|
6
|
+
}> {
|
|
7
|
+
protected readonly storeEnum: TEnum;
|
|
8
|
+
private readonly signalsState;
|
|
9
|
+
protected constructor(storeEnum: TEnum);
|
|
10
|
+
get<K extends keyof TData>(key: K): WritableSignal<TData[K]>;
|
|
11
|
+
onUpdate<K extends keyof TData>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
12
|
+
update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void;
|
|
13
|
+
clearAll(): void;
|
|
14
|
+
clear<K extends keyof TData>(key: K): void;
|
|
15
|
+
startLoading<K extends keyof TData>(key: K): void;
|
|
16
|
+
stopLoading<K extends keyof TData>(key: K): void;
|
|
17
|
+
updateKeyedOne<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
18
|
+
clearKeyedOne<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey): void;
|
|
19
|
+
startKeyedLoading<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey): void;
|
|
20
|
+
private notifyUpdateHooks;
|
|
21
|
+
private initializeState;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { BaseStore };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { WritableSignal } from '@angular/core';
|
|
2
|
+
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
|
+
|
|
4
|
+
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
5
|
+
[K in keyof TEnum]: ResourceState<unknown>;
|
|
6
|
+
}> {
|
|
7
|
+
protected readonly storeEnum: TEnum;
|
|
8
|
+
private readonly signalsState;
|
|
9
|
+
protected constructor(storeEnum: TEnum);
|
|
10
|
+
get<K extends keyof TData>(key: K): WritableSignal<TData[K]>;
|
|
11
|
+
onUpdate<K extends keyof TData>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
12
|
+
update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void;
|
|
13
|
+
clearAll(): void;
|
|
14
|
+
clear<K extends keyof TData>(key: K): void;
|
|
15
|
+
startLoading<K extends keyof TData>(key: K): void;
|
|
16
|
+
stopLoading<K extends keyof TData>(key: K): void;
|
|
17
|
+
updateKeyedOne<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
18
|
+
clearKeyedOne<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey): void;
|
|
19
|
+
startKeyedLoading<K extends keyof TData>(key: K, resourceKey: KeyedResourceKey): void;
|
|
20
|
+
private notifyUpdateHooks;
|
|
21
|
+
private initializeState;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { BaseStore };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// src/base-store.ts
|
|
2
|
+
import { signal } from "@angular/core";
|
|
3
|
+
import {
|
|
4
|
+
isAnyKeyLoading,
|
|
5
|
+
isKeyedResourceData,
|
|
6
|
+
createKeyedResourceData
|
|
7
|
+
} from "@flurryx/core";
|
|
8
|
+
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
var BaseStore = class {
|
|
10
|
+
constructor(storeEnum) {
|
|
11
|
+
this.storeEnum = storeEnum;
|
|
12
|
+
this.initializeState();
|
|
13
|
+
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
14
|
+
}
|
|
15
|
+
signalsState = /* @__PURE__ */ new Map();
|
|
16
|
+
get(key) {
|
|
17
|
+
return this.signalsState.get(key.toString());
|
|
18
|
+
}
|
|
19
|
+
onUpdate(key, callback) {
|
|
20
|
+
const hooks = updateHooksMap.get(this);
|
|
21
|
+
if (!hooks.has(key)) {
|
|
22
|
+
hooks.set(key, []);
|
|
23
|
+
}
|
|
24
|
+
hooks.get(key).push(
|
|
25
|
+
callback
|
|
26
|
+
);
|
|
27
|
+
return () => {
|
|
28
|
+
const hooksMap = hooks.get(key);
|
|
29
|
+
if (!hooksMap) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const index = hooksMap.indexOf(
|
|
33
|
+
callback
|
|
34
|
+
);
|
|
35
|
+
if (index > -1) {
|
|
36
|
+
hooksMap.splice(index, 1);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
update(key, newState) {
|
|
41
|
+
const currentState = this.signalsState.get(key.toString());
|
|
42
|
+
if (!currentState) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const previousState = currentState();
|
|
46
|
+
currentState.update((state) => ({
|
|
47
|
+
...state,
|
|
48
|
+
...newState
|
|
49
|
+
}));
|
|
50
|
+
const updatedState = currentState();
|
|
51
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
52
|
+
}
|
|
53
|
+
clearAll() {
|
|
54
|
+
Object.keys(this.storeEnum).forEach((key) => {
|
|
55
|
+
this.clear(key);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
clear(key) {
|
|
59
|
+
const currentState = this.signalsState.get(key.toString());
|
|
60
|
+
if (!currentState) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const previousState = currentState();
|
|
64
|
+
const _typedKey = key;
|
|
65
|
+
currentState.set({
|
|
66
|
+
data: void 0,
|
|
67
|
+
isLoading: false,
|
|
68
|
+
status: void 0,
|
|
69
|
+
errors: void 0
|
|
70
|
+
});
|
|
71
|
+
const nextState = currentState();
|
|
72
|
+
this.notifyUpdateHooks(key, nextState, previousState);
|
|
73
|
+
}
|
|
74
|
+
startLoading(key) {
|
|
75
|
+
const currentState = this.signalsState.get(key.toString());
|
|
76
|
+
if (!currentState) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const _typedKey = key;
|
|
80
|
+
currentState.update(
|
|
81
|
+
(state) => ({
|
|
82
|
+
...state,
|
|
83
|
+
status: void 0,
|
|
84
|
+
isLoading: true,
|
|
85
|
+
errors: void 0
|
|
86
|
+
})
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
stopLoading(key) {
|
|
90
|
+
const currentState = this.signalsState.get(key.toString());
|
|
91
|
+
if (!currentState) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const _typedKey = key;
|
|
95
|
+
currentState.update(
|
|
96
|
+
(state) => ({
|
|
97
|
+
...state,
|
|
98
|
+
isLoading: false,
|
|
99
|
+
status: void 0,
|
|
100
|
+
errors: void 0
|
|
101
|
+
})
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
updateKeyedOne(key, resourceKey, entity) {
|
|
105
|
+
const currentState = this.signalsState.get(key.toString());
|
|
106
|
+
if (!currentState) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const state = currentState();
|
|
110
|
+
const data = isKeyedResourceData(state.data) ? state.data : createKeyedResourceData();
|
|
111
|
+
const nextErrors = { ...data.errors };
|
|
112
|
+
delete nextErrors[resourceKey];
|
|
113
|
+
const nextData = {
|
|
114
|
+
...data,
|
|
115
|
+
entities: {
|
|
116
|
+
...data.entities,
|
|
117
|
+
[resourceKey]: entity
|
|
118
|
+
},
|
|
119
|
+
isLoading: {
|
|
120
|
+
...data.isLoading,
|
|
121
|
+
[resourceKey]: false
|
|
122
|
+
},
|
|
123
|
+
status: {
|
|
124
|
+
...data.status,
|
|
125
|
+
[resourceKey]: "Success"
|
|
126
|
+
},
|
|
127
|
+
errors: nextErrors
|
|
128
|
+
};
|
|
129
|
+
this.update(key, {
|
|
130
|
+
data: nextData,
|
|
131
|
+
isLoading: isAnyKeyLoading(nextData.isLoading),
|
|
132
|
+
status: void 0,
|
|
133
|
+
errors: void 0
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
clearKeyedOne(key, resourceKey) {
|
|
137
|
+
const currentState = this.signalsState.get(key.toString());
|
|
138
|
+
if (!currentState) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const previousState = currentState();
|
|
142
|
+
const state = previousState;
|
|
143
|
+
if (!isKeyedResourceData(state.data)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const data = state.data;
|
|
147
|
+
const nextEntities = { ...data.entities };
|
|
148
|
+
delete nextEntities[resourceKey];
|
|
149
|
+
const nextIsLoading = { ...data.isLoading };
|
|
150
|
+
delete nextIsLoading[resourceKey];
|
|
151
|
+
const nextStatus = { ...data.status };
|
|
152
|
+
delete nextStatus[resourceKey];
|
|
153
|
+
const nextErrors = { ...data.errors };
|
|
154
|
+
delete nextErrors[resourceKey];
|
|
155
|
+
const nextData = {
|
|
156
|
+
...data,
|
|
157
|
+
entities: nextEntities,
|
|
158
|
+
isLoading: nextIsLoading,
|
|
159
|
+
status: nextStatus,
|
|
160
|
+
errors: nextErrors
|
|
161
|
+
};
|
|
162
|
+
const _typedKey = key;
|
|
163
|
+
currentState.update(
|
|
164
|
+
(prev) => ({
|
|
165
|
+
...prev,
|
|
166
|
+
data: nextData,
|
|
167
|
+
status: void 0,
|
|
168
|
+
isLoading: isAnyKeyLoading(nextIsLoading),
|
|
169
|
+
errors: void 0
|
|
170
|
+
})
|
|
171
|
+
);
|
|
172
|
+
const updatedState = currentState();
|
|
173
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
174
|
+
}
|
|
175
|
+
startKeyedLoading(key, resourceKey) {
|
|
176
|
+
const currentState = this.signalsState.get(key.toString());
|
|
177
|
+
if (!currentState) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const _typedKey = key;
|
|
181
|
+
const state = currentState();
|
|
182
|
+
if (!isKeyedResourceData(state.data)) {
|
|
183
|
+
this.startLoading(key);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const previousState = state;
|
|
187
|
+
const data = state.data;
|
|
188
|
+
const nextIsLoading = {
|
|
189
|
+
...data.isLoading,
|
|
190
|
+
[resourceKey]: true
|
|
191
|
+
};
|
|
192
|
+
const nextStatus = {
|
|
193
|
+
...data.status
|
|
194
|
+
};
|
|
195
|
+
delete nextStatus[resourceKey];
|
|
196
|
+
const nextErrors = {
|
|
197
|
+
...data.errors
|
|
198
|
+
};
|
|
199
|
+
delete nextErrors[resourceKey];
|
|
200
|
+
const nextData = {
|
|
201
|
+
...data,
|
|
202
|
+
isLoading: nextIsLoading,
|
|
203
|
+
status: nextStatus,
|
|
204
|
+
errors: nextErrors
|
|
205
|
+
};
|
|
206
|
+
currentState.update(
|
|
207
|
+
(previous) => ({
|
|
208
|
+
...previous,
|
|
209
|
+
data: nextData,
|
|
210
|
+
status: void 0,
|
|
211
|
+
isLoading: isAnyKeyLoading(nextIsLoading),
|
|
212
|
+
errors: void 0
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
const updatedState = currentState();
|
|
216
|
+
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
217
|
+
}
|
|
218
|
+
notifyUpdateHooks(key, nextState, previousState) {
|
|
219
|
+
const hooks = updateHooksMap.get(this);
|
|
220
|
+
const keyHooks = hooks?.get(key);
|
|
221
|
+
if (!keyHooks) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
keyHooks.forEach(
|
|
225
|
+
(hook) => hook(
|
|
226
|
+
nextState,
|
|
227
|
+
previousState
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
initializeState() {
|
|
232
|
+
Object.keys(this.storeEnum).forEach((key) => {
|
|
233
|
+
const _typedKey = key;
|
|
234
|
+
const initialState = {
|
|
235
|
+
data: void 0,
|
|
236
|
+
isLoading: false,
|
|
237
|
+
status: void 0,
|
|
238
|
+
errors: void 0
|
|
239
|
+
};
|
|
240
|
+
this.signalsState.set(
|
|
241
|
+
_typedKey,
|
|
242
|
+
signal(
|
|
243
|
+
initialState
|
|
244
|
+
)
|
|
245
|
+
);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
export {
|
|
250
|
+
BaseStore
|
|
251
|
+
};
|
|
252
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/base-store.ts"],"sourcesContent":["import { signal, WritableSignal } from '@angular/core';\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from '@flurryx/core';\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n> {\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: 'Success' as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n }) as TData[typeof _typedKey]\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(\n initialState as TData[typeof _typedKey]\n )\n );\n });\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flurryx/store",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Signal-first reactive store for Angular",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist"],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"typecheck": "tsc --noEmit"
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@flurryx/core": "0.0.1"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@angular/core": ">=17.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|