@flurryx/store 1.0.1 → 1.1.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.js CHANGED
@@ -89,6 +89,257 @@ import { signal, computed } from "@angular/core";
89
89
  var INVALID_HISTORY_INDEX_ERROR = "History index is out of range";
90
90
  var INVALID_HISTORY_MESSAGE_ID_ERROR = "History message id is out of range";
91
91
  var MESSAGE_NOT_ACKNOWLEDGED_ERROR = "Message was not acknowledged";
92
+ var INVALID_STORE_KEY_ERROR = "Invalid store key";
93
+
94
+ // src/store-message-consumer.ts
95
+ import {
96
+ isKeyedResourceData,
97
+ createKeyedResourceData,
98
+ isAnyKeyLoading
99
+ } from "@flurryx/core";
100
+ function createDefaultState() {
101
+ return {
102
+ data: void 0,
103
+ isLoading: false,
104
+ status: void 0,
105
+ errors: void 0
106
+ };
107
+ }
108
+ function createStoreMessageConsumer(signals, notifier) {
109
+ function applyUpdate(key, newState, notify = true) {
110
+ const sig = signals.getOrCreate(key);
111
+ const previousState = sig();
112
+ sig.update((state) => ({ ...state, ...newState }));
113
+ if (notify) {
114
+ const updatedState = sig();
115
+ notifier.notify(key, updatedState, previousState);
116
+ }
117
+ return true;
118
+ }
119
+ function applyClear(key) {
120
+ const sig = signals.getOrCreate(key);
121
+ const previousState = sig();
122
+ sig.set(createDefaultState());
123
+ const nextState = sig();
124
+ notifier.notify(key, nextState, previousState);
125
+ return true;
126
+ }
127
+ function applyClearAll() {
128
+ const keys = Array.from(signals.getAllKeys());
129
+ if (keys.length === 0) {
130
+ return false;
131
+ }
132
+ keys.forEach((key) => {
133
+ applyClear(key);
134
+ });
135
+ return true;
136
+ }
137
+ function applyStartLoading(key) {
138
+ const sig = signals.getOrCreate(key);
139
+ sig.update(
140
+ (state) => ({
141
+ ...state,
142
+ status: void 0,
143
+ isLoading: true,
144
+ errors: void 0
145
+ })
146
+ );
147
+ return true;
148
+ }
149
+ function applyStopLoading(key) {
150
+ const sig = signals.getOrCreate(key);
151
+ sig.update(
152
+ (state) => ({
153
+ ...state,
154
+ isLoading: false
155
+ })
156
+ );
157
+ return true;
158
+ }
159
+ function applyUpdateKeyedOne(key, resourceKey, entity) {
160
+ const sig = signals.getOrCreate(key);
161
+ const state = sig();
162
+ const data = isKeyedResourceData(state.data) ? state.data : createKeyedResourceData();
163
+ const nextErrors = { ...data.errors };
164
+ delete nextErrors[resourceKey];
165
+ const nextData = {
166
+ ...data,
167
+ entities: { ...data.entities, [resourceKey]: entity },
168
+ isLoading: { ...data.isLoading, [resourceKey]: false },
169
+ status: { ...data.status, [resourceKey]: "Success" },
170
+ errors: nextErrors
171
+ };
172
+ return applyUpdate(key, {
173
+ data: nextData,
174
+ isLoading: isAnyKeyLoading(nextData.isLoading),
175
+ status: void 0,
176
+ errors: void 0
177
+ });
178
+ }
179
+ function applyClearKeyedOne(key, resourceKey) {
180
+ const sig = signals.getOrCreate(key);
181
+ const previousState = sig();
182
+ const state = previousState;
183
+ if (!isKeyedResourceData(state.data)) {
184
+ return true;
185
+ }
186
+ const data = state.data;
187
+ const nextEntities = { ...data.entities };
188
+ delete nextEntities[resourceKey];
189
+ const nextIsLoading = { ...data.isLoading };
190
+ delete nextIsLoading[resourceKey];
191
+ const nextStatus = { ...data.status };
192
+ delete nextStatus[resourceKey];
193
+ const nextErrors = { ...data.errors };
194
+ delete nextErrors[resourceKey];
195
+ const nextData = {
196
+ ...data,
197
+ entities: nextEntities,
198
+ isLoading: nextIsLoading,
199
+ status: nextStatus,
200
+ errors: nextErrors
201
+ };
202
+ sig.update(
203
+ (prev) => ({
204
+ ...prev,
205
+ data: nextData,
206
+ status: void 0,
207
+ isLoading: isAnyKeyLoading(nextIsLoading),
208
+ errors: void 0
209
+ })
210
+ );
211
+ const updatedState = sig();
212
+ notifier.notify(key, updatedState, previousState);
213
+ return true;
214
+ }
215
+ function applyStartKeyedLoading(key, resourceKey) {
216
+ const sig = signals.getOrCreate(key);
217
+ const state = sig();
218
+ if (!isKeyedResourceData(state.data)) {
219
+ return applyStartLoading(key);
220
+ }
221
+ const previousState = state;
222
+ const data = state.data;
223
+ const nextIsLoading = {
224
+ ...data.isLoading,
225
+ [resourceKey]: true
226
+ };
227
+ const nextStatus = { ...data.status };
228
+ delete nextStatus[resourceKey];
229
+ const nextErrors = { ...data.errors };
230
+ delete nextErrors[resourceKey];
231
+ const nextData = {
232
+ ...data,
233
+ isLoading: nextIsLoading,
234
+ status: nextStatus,
235
+ errors: nextErrors
236
+ };
237
+ sig.update(
238
+ (previous) => ({
239
+ ...previous,
240
+ data: nextData,
241
+ status: void 0,
242
+ isLoading: isAnyKeyLoading(nextIsLoading),
243
+ errors: void 0
244
+ })
245
+ );
246
+ const updatedState = sig();
247
+ notifier.notify(key, updatedState, previousState);
248
+ return true;
249
+ }
250
+ function applyMessage(message) {
251
+ switch (message.type) {
252
+ case "update":
253
+ return applyUpdate(message.key, cloneValue(message.state));
254
+ case "clear":
255
+ return applyClear(message.key);
256
+ case "clearAll":
257
+ return applyClearAll();
258
+ case "startLoading":
259
+ return applyStartLoading(message.key);
260
+ case "stopLoading":
261
+ return applyStopLoading(message.key);
262
+ case "updateKeyedOne":
263
+ return applyUpdateKeyedOne(
264
+ message.key,
265
+ message.resourceKey,
266
+ cloneValue(message.entity)
267
+ );
268
+ case "clearKeyedOne":
269
+ return applyClearKeyedOne(message.key, message.resourceKey);
270
+ case "startKeyedLoading":
271
+ return applyStartKeyedLoading(message.key, message.resourceKey);
272
+ }
273
+ }
274
+ function applySnapshot(snapshot) {
275
+ const keys = /* @__PURE__ */ new Set([
276
+ ...Array.from(signals.getAllKeys()),
277
+ ...Object.keys(snapshot)
278
+ ]);
279
+ keys.forEach((rawKey) => {
280
+ const key = rawKey;
281
+ const sig = signals.getOrCreate(key);
282
+ const snapshotState = snapshot[key] ?? createDefaultState();
283
+ applyUpdate(key, createSnapshotRestorePatch(sig(), snapshotState), true);
284
+ });
285
+ }
286
+ function captureSnapshot() {
287
+ const entries = Array.from(signals.getAllKeys()).map((key) => [
288
+ key,
289
+ cloneValue(signals.getOrCreate(key)())
290
+ ]);
291
+ return Object.fromEntries(entries);
292
+ }
293
+ function applyKeyUpdate(key, snapshotState) {
294
+ const sig = signals.getOrCreate(key);
295
+ const currentState = sig();
296
+ const patch = createSnapshotRestorePatch(currentState, snapshotState);
297
+ applyUpdate(key, patch, true);
298
+ }
299
+ return {
300
+ applyMessage,
301
+ applySnapshot,
302
+ applyKeyUpdate,
303
+ createSnapshot: captureSnapshot
304
+ };
305
+ }
306
+ function createUpdateMessage(key, state) {
307
+ return { type: "update", key, state };
308
+ }
309
+ function createClearMessage(key) {
310
+ return { type: "clear", key };
311
+ }
312
+ function createClearAllMessage() {
313
+ return { type: "clearAll" };
314
+ }
315
+ function createStartLoadingMessage(key) {
316
+ return { type: "startLoading", key };
317
+ }
318
+ function createStopLoadingMessage(key) {
319
+ return { type: "stopLoading", key };
320
+ }
321
+ function createUpdateKeyedOneMessage(key, resourceKey, entity) {
322
+ return {
323
+ type: "updateKeyedOne",
324
+ key,
325
+ resourceKey,
326
+ entity
327
+ };
328
+ }
329
+ function createClearKeyedOneMessage(key, resourceKey) {
330
+ return {
331
+ type: "clearKeyedOne",
332
+ key,
333
+ resourceKey
334
+ };
335
+ }
336
+ function createStartKeyedLoadingMessage(key, resourceKey) {
337
+ return {
338
+ type: "startKeyedLoading",
339
+ key,
340
+ resourceKey
341
+ };
342
+ }
92
343
 
93
344
  // src/store-channels.ts
94
345
  function serializeStoreMessageChannelValue(value) {
@@ -563,24 +814,36 @@ function createStoreHistory(config) {
563
814
  throw new Error(INVALID_HISTORY_INDEX_ERROR);
564
815
  }
565
816
  }
566
- function travelTo(index) {
817
+ function restoreStoreAt(index) {
567
818
  ensureIndexInRange(index);
568
819
  config.applySnapshot(history[index].snapshot);
569
820
  currentIndex = index;
570
821
  notifyVersion();
571
822
  }
823
+ function restoreResource(key, index) {
824
+ const targetIndex = index !== void 0 ? index : currentIndex;
825
+ ensureIndexInRange(targetIndex);
826
+ const allKeys = new Set(Array.from(config.getAllKeys()));
827
+ if (!allKeys.has(key)) {
828
+ throw new Error(INVALID_STORE_KEY_ERROR);
829
+ }
830
+ const snapshot = history[targetIndex].snapshot;
831
+ const snapshotState = snapshot[key];
832
+ config.applyKeyUpdate(key, snapshotState ?? createDefaultState());
833
+ notifyVersion();
834
+ }
572
835
  function undo() {
573
836
  if (currentIndex === 0) {
574
837
  return false;
575
838
  }
576
- travelTo(currentIndex - 1);
839
+ restoreStoreAt(currentIndex - 1);
577
840
  return true;
578
841
  }
579
842
  function redo() {
580
843
  if (currentIndex >= history.length - 1) {
581
844
  return false;
582
845
  }
583
- travelTo(currentIndex + 1);
846
+ restoreStoreAt(currentIndex + 1);
584
847
  return true;
585
848
  }
586
849
  function getErrorMessage(error) {
@@ -717,7 +980,8 @@ function createStoreHistory(config) {
717
980
  replay(input) {
718
981
  return replayByIds(input);
719
982
  },
720
- travelTo,
983
+ restoreStoreAt,
984
+ restoreResource,
721
985
  undo,
722
986
  redo,
723
987
  getHistory(key) {
@@ -760,249 +1024,6 @@ function clearAllStores() {
760
1024
  }
761
1025
  }
762
1026
 
763
- // src/store-message-consumer.ts
764
- import {
765
- isKeyedResourceData,
766
- createKeyedResourceData,
767
- isAnyKeyLoading
768
- } from "@flurryx/core";
769
- function createDefaultState() {
770
- return {
771
- data: void 0,
772
- isLoading: false,
773
- status: void 0,
774
- errors: void 0
775
- };
776
- }
777
- function createStoreMessageConsumer(signals, notifier) {
778
- function applyUpdate(key, newState, notify = true) {
779
- const sig = signals.getOrCreate(key);
780
- const previousState = sig();
781
- sig.update((state) => ({ ...state, ...newState }));
782
- if (notify) {
783
- const updatedState = sig();
784
- notifier.notify(key, updatedState, previousState);
785
- }
786
- return true;
787
- }
788
- function applyClear(key) {
789
- const sig = signals.getOrCreate(key);
790
- const previousState = sig();
791
- sig.set(createDefaultState());
792
- const nextState = sig();
793
- notifier.notify(key, nextState, previousState);
794
- return true;
795
- }
796
- function applyClearAll() {
797
- const keys = Array.from(signals.getAllKeys());
798
- if (keys.length === 0) {
799
- return false;
800
- }
801
- keys.forEach((key) => {
802
- applyClear(key);
803
- });
804
- return true;
805
- }
806
- function applyStartLoading(key) {
807
- const sig = signals.getOrCreate(key);
808
- sig.update(
809
- (state) => ({
810
- ...state,
811
- status: void 0,
812
- isLoading: true,
813
- errors: void 0
814
- })
815
- );
816
- return true;
817
- }
818
- function applyStopLoading(key) {
819
- const sig = signals.getOrCreate(key);
820
- sig.update(
821
- (state) => ({
822
- ...state,
823
- isLoading: false
824
- })
825
- );
826
- return true;
827
- }
828
- function applyUpdateKeyedOne(key, resourceKey, entity) {
829
- const sig = signals.getOrCreate(key);
830
- const state = sig();
831
- const data = isKeyedResourceData(state.data) ? state.data : createKeyedResourceData();
832
- const nextErrors = { ...data.errors };
833
- delete nextErrors[resourceKey];
834
- const nextData = {
835
- ...data,
836
- entities: { ...data.entities, [resourceKey]: entity },
837
- isLoading: { ...data.isLoading, [resourceKey]: false },
838
- status: { ...data.status, [resourceKey]: "Success" },
839
- errors: nextErrors
840
- };
841
- return applyUpdate(key, {
842
- data: nextData,
843
- isLoading: isAnyKeyLoading(nextData.isLoading),
844
- status: void 0,
845
- errors: void 0
846
- });
847
- }
848
- function applyClearKeyedOne(key, resourceKey) {
849
- const sig = signals.getOrCreate(key);
850
- const previousState = sig();
851
- const state = previousState;
852
- if (!isKeyedResourceData(state.data)) {
853
- return true;
854
- }
855
- const data = state.data;
856
- const nextEntities = { ...data.entities };
857
- delete nextEntities[resourceKey];
858
- const nextIsLoading = { ...data.isLoading };
859
- delete nextIsLoading[resourceKey];
860
- const nextStatus = { ...data.status };
861
- delete nextStatus[resourceKey];
862
- const nextErrors = { ...data.errors };
863
- delete nextErrors[resourceKey];
864
- const nextData = {
865
- ...data,
866
- entities: nextEntities,
867
- isLoading: nextIsLoading,
868
- status: nextStatus,
869
- errors: nextErrors
870
- };
871
- sig.update(
872
- (prev) => ({
873
- ...prev,
874
- data: nextData,
875
- status: void 0,
876
- isLoading: isAnyKeyLoading(nextIsLoading),
877
- errors: void 0
878
- })
879
- );
880
- const updatedState = sig();
881
- notifier.notify(key, updatedState, previousState);
882
- return true;
883
- }
884
- function applyStartKeyedLoading(key, resourceKey) {
885
- const sig = signals.getOrCreate(key);
886
- const state = sig();
887
- if (!isKeyedResourceData(state.data)) {
888
- return applyStartLoading(key);
889
- }
890
- const previousState = state;
891
- const data = state.data;
892
- const nextIsLoading = {
893
- ...data.isLoading,
894
- [resourceKey]: true
895
- };
896
- const nextStatus = { ...data.status };
897
- delete nextStatus[resourceKey];
898
- const nextErrors = { ...data.errors };
899
- delete nextErrors[resourceKey];
900
- const nextData = {
901
- ...data,
902
- isLoading: nextIsLoading,
903
- status: nextStatus,
904
- errors: nextErrors
905
- };
906
- sig.update(
907
- (previous) => ({
908
- ...previous,
909
- data: nextData,
910
- status: void 0,
911
- isLoading: isAnyKeyLoading(nextIsLoading),
912
- errors: void 0
913
- })
914
- );
915
- const updatedState = sig();
916
- notifier.notify(key, updatedState, previousState);
917
- return true;
918
- }
919
- function applyMessage(message) {
920
- switch (message.type) {
921
- case "update":
922
- return applyUpdate(message.key, cloneValue(message.state));
923
- case "clear":
924
- return applyClear(message.key);
925
- case "clearAll":
926
- return applyClearAll();
927
- case "startLoading":
928
- return applyStartLoading(message.key);
929
- case "stopLoading":
930
- return applyStopLoading(message.key);
931
- case "updateKeyedOne":
932
- return applyUpdateKeyedOne(
933
- message.key,
934
- message.resourceKey,
935
- cloneValue(message.entity)
936
- );
937
- case "clearKeyedOne":
938
- return applyClearKeyedOne(message.key, message.resourceKey);
939
- case "startKeyedLoading":
940
- return applyStartKeyedLoading(message.key, message.resourceKey);
941
- }
942
- }
943
- function applySnapshot(snapshot) {
944
- const keys = /* @__PURE__ */ new Set([
945
- ...Array.from(signals.getAllKeys()),
946
- ...Object.keys(snapshot)
947
- ]);
948
- keys.forEach((rawKey) => {
949
- const key = rawKey;
950
- const sig = signals.getOrCreate(key);
951
- const snapshotState = snapshot[key] ?? createDefaultState();
952
- applyUpdate(key, createSnapshotRestorePatch(sig(), snapshotState), true);
953
- });
954
- }
955
- function captureSnapshot() {
956
- const entries = Array.from(signals.getAllKeys()).map((key) => [
957
- key,
958
- cloneValue(signals.getOrCreate(key)())
959
- ]);
960
- return Object.fromEntries(entries);
961
- }
962
- return {
963
- applyMessage,
964
- applySnapshot,
965
- createSnapshot: captureSnapshot
966
- };
967
- }
968
- function createUpdateMessage(key, state) {
969
- return { type: "update", key, state };
970
- }
971
- function createClearMessage(key) {
972
- return { type: "clear", key };
973
- }
974
- function createClearAllMessage() {
975
- return { type: "clearAll" };
976
- }
977
- function createStartLoadingMessage(key) {
978
- return { type: "startLoading", key };
979
- }
980
- function createStopLoadingMessage(key) {
981
- return { type: "stopLoading", key };
982
- }
983
- function createUpdateKeyedOneMessage(key, resourceKey, entity) {
984
- return {
985
- type: "updateKeyedOne",
986
- key,
987
- resourceKey,
988
- entity
989
- };
990
- }
991
- function createClearKeyedOneMessage(key, resourceKey) {
992
- return {
993
- type: "clearKeyedOne",
994
- key,
995
- resourceKey
996
- };
997
- }
998
- function createStartKeyedLoadingMessage(key, resourceKey) {
999
- return {
1000
- type: "startKeyedLoading",
1001
- key,
1002
- resourceKey
1003
- };
1004
- }
1005
-
1006
1027
  // src/base-store.ts
1007
1028
  var updateHooksMap = /* @__PURE__ */ new WeakMap();
1008
1029
  var BaseStore = class {
@@ -1023,6 +1044,8 @@ var BaseStore = class {
1023
1044
  this.historyDriver = createStoreHistory({
1024
1045
  captureSnapshot: () => consumer.createSnapshot(),
1025
1046
  applySnapshot: (snapshot) => consumer.applySnapshot(snapshot),
1047
+ applyKeyUpdate: (key, snapshotState) => consumer.applyKeyUpdate(key, snapshotState),
1048
+ getAllKeys: () => this.storeKeys,
1026
1049
  applyMessage: (message) => consumer.applyMessage(message),
1027
1050
  channel: options?.channel
1028
1051
  });
@@ -1036,7 +1059,9 @@ var BaseStore = class {
1036
1059
  storeKeys;
1037
1060
  historyDriver;
1038
1061
  /** @inheritDoc */
1039
- travelTo = (index) => this.historyDriver.travelTo(index);
1062
+ restoreStoreAt = (index) => this.historyDriver.restoreStoreAt(index);
1063
+ /** @inheritDoc */
1064
+ restoreResource = (key, index) => this.historyDriver.restoreResource(key, index);
1040
1065
  /** @inheritDoc */
1041
1066
  undo = () => this.historyDriver.undo();
1042
1067
  /** @inheritDoc */
@@ -1242,7 +1267,9 @@ var LazyStore = class {
1242
1267
  hooks = /* @__PURE__ */ new Map();
1243
1268
  historyDriver;
1244
1269
  /** @inheritDoc */
1245
- travelTo = (index) => this.historyDriver.travelTo(index);
1270
+ restoreStoreAt = (index) => this.historyDriver.restoreStoreAt(index);
1271
+ /** @inheritDoc */
1272
+ restoreResource = (key, index) => this.historyDriver.restoreResource(key, index);
1246
1273
  /** @inheritDoc */
1247
1274
  undo = () => this.historyDriver.undo();
1248
1275
  /** @inheritDoc */
@@ -1294,6 +1321,8 @@ var LazyStore = class {
1294
1321
  this.historyDriver = createStoreHistory({
1295
1322
  captureSnapshot: () => consumer.createSnapshot(),
1296
1323
  applySnapshot: (snapshot) => consumer.applySnapshot(snapshot),
1324
+ applyKeyUpdate: (key, snapshotState) => consumer.applyKeyUpdate(key, snapshotState),
1325
+ getAllKeys: () => this.signals.keys(),
1297
1326
  applyMessage: (message) => consumer.applyMessage(message),
1298
1327
  channel: options?.channel
1299
1328
  });
@@ -1789,6 +1818,7 @@ function createStoreFor(enumObj) {
1789
1818
  }
1790
1819
  export {
1791
1820
  BaseStore,
1821
+ INVALID_STORE_KEY_ERROR,
1792
1822
  LazyStore,
1793
1823
  Store,
1794
1824
  clearAllStores,