@angular-architects/ngrx-toolkit 0.4.0 → 18.0.0
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 +47 -2
- package/esm2022/index.mjs +2 -2
- package/esm2022/lib/assertions/assertions.mjs +1 -1
- package/esm2022/lib/redux-connector/create-redux.mjs +1 -1
- package/esm2022/lib/redux-connector/model.mjs +1 -1
- package/esm2022/lib/redux-connector/rxjs-interop/redux-method.mjs +1 -1
- package/esm2022/lib/redux-connector/signal-redux-store.mjs +4 -4
- package/esm2022/lib/shared/prettify.mjs +2 -0
- package/esm2022/lib/shared/signal-store-models.mjs +2 -0
- package/esm2022/lib/with-call-state.mjs +6 -4
- package/esm2022/lib/with-data-service.mjs +73 -32
- package/esm2022/lib/with-devtools.mjs +5 -5
- package/esm2022/lib/with-pagination.mjs +70 -13
- package/esm2022/lib/with-redux.mjs +1 -1
- package/esm2022/lib/with-storage-sync.mjs +1 -1
- package/esm2022/lib/with-undo-redo.mjs +25 -11
- package/fesm2022/angular-architects-ngrx-toolkit.mjs +274 -160
- package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/lib/redux-connector/model.d.ts +6 -7
- package/lib/redux-connector/signal-redux-store.d.ts +2 -2
- package/lib/shared/prettify.d.ts +3 -0
- package/lib/shared/signal-store-models.d.ts +26 -0
- package/lib/with-call-state.d.ts +5 -16
- package/lib/with-data-service.d.ts +14 -20
- package/lib/with-devtools.d.ts +5 -10
- package/lib/with-pagination.d.ts +50 -27
- package/lib/with-redux.d.ts +2 -4
- package/lib/with-storage-sync.d.ts +4 -10
- package/lib/with-undo-redo.d.ts +13 -27
- package/package.json +2 -2
- package/esm2022/lib/shared/empty.mjs +0 -2
- package/lib/shared/empty.d.ts +0 -1
|
@@ -86,14 +86,14 @@ const patchState = (state, action, ...rest) => {
|
|
|
86
86
|
/**
|
|
87
87
|
* Wrapper of `patchState` for DevTools integration. Next to updating the state,
|
|
88
88
|
* it also sends the action to the DevTools.
|
|
89
|
-
* @param
|
|
89
|
+
* @param stateSource state of Signal Store
|
|
90
90
|
* @param action name of action how it will show in DevTools
|
|
91
91
|
* @param updaters updater functions or objects
|
|
92
92
|
*/
|
|
93
|
-
|
|
93
|
+
function updateState(stateSource, action, ...updaters) {
|
|
94
94
|
currentActionNames.add(action);
|
|
95
|
-
return patchState$1(
|
|
96
|
-
}
|
|
95
|
+
return patchState$1(stateSource, ...updaters);
|
|
96
|
+
}
|
|
97
97
|
|
|
98
98
|
function assertActionFnSpecs(obj) {
|
|
99
99
|
if (!obj || typeof obj !== 'object') {
|
|
@@ -218,7 +218,7 @@ function withCallState(config) {
|
|
|
218
218
|
[errorKey]: computed(() => {
|
|
219
219
|
const v = callState();
|
|
220
220
|
return typeof v === 'object' ? v.error : null;
|
|
221
|
-
})
|
|
221
|
+
}),
|
|
222
222
|
};
|
|
223
223
|
}));
|
|
224
224
|
}
|
|
@@ -237,7 +237,7 @@ function setLoaded(prop) {
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
function setError(error, prop) {
|
|
240
|
-
let errorMessage
|
|
240
|
+
let errorMessage;
|
|
241
241
|
if (!error) {
|
|
242
242
|
errorMessage = '';
|
|
243
243
|
}
|
|
@@ -248,7 +248,9 @@ function setError(error, prop) {
|
|
|
248
248
|
errorMessage = String(error);
|
|
249
249
|
}
|
|
250
250
|
if (prop) {
|
|
251
|
-
return {
|
|
251
|
+
return {
|
|
252
|
+
[`${prop}CallState`]: { error: errorMessage },
|
|
253
|
+
};
|
|
252
254
|
}
|
|
253
255
|
else {
|
|
254
256
|
return { callState: { error: errorMessage } };
|
|
@@ -259,22 +261,52 @@ function capitalize$1(str) {
|
|
|
259
261
|
return str ? str[0].toUpperCase() + str.substring(1) : str;
|
|
260
262
|
}
|
|
261
263
|
function getDataServiceKeys(options) {
|
|
262
|
-
const filterKey = options.collection
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const
|
|
264
|
+
const filterKey = options.collection
|
|
265
|
+
? `${options.collection}Filter`
|
|
266
|
+
: 'filter';
|
|
267
|
+
const selectedIdsKey = options.collection
|
|
268
|
+
? `selected${capitalize$1(options.collection)}Ids`
|
|
269
|
+
: 'selectedIds';
|
|
270
|
+
const selectedEntitiesKey = options.collection
|
|
271
|
+
? `selected${capitalize$1(options.collection)}Entities`
|
|
272
|
+
: 'selectedEntities';
|
|
273
|
+
const updateFilterKey = options.collection
|
|
274
|
+
? `update${capitalize$1(options.collection)}Filter`
|
|
275
|
+
: 'updateFilter';
|
|
276
|
+
const updateSelectedKey = options.collection
|
|
277
|
+
? `updateSelected${capitalize$1(options.collection)}Entities`
|
|
278
|
+
: 'updateSelected';
|
|
279
|
+
const loadKey = options.collection
|
|
280
|
+
? `load${capitalize$1(options.collection)}Entities`
|
|
281
|
+
: 'load';
|
|
282
|
+
const currentKey = options.collection
|
|
283
|
+
? `current${capitalize$1(options.collection)}`
|
|
284
|
+
: 'current';
|
|
285
|
+
const loadByIdKey = options.collection
|
|
286
|
+
? `load${capitalize$1(options.collection)}ById`
|
|
287
|
+
: 'loadById';
|
|
288
|
+
const setCurrentKey = options.collection
|
|
289
|
+
? `setCurrent${capitalize$1(options.collection)}`
|
|
290
|
+
: 'setCurrent';
|
|
291
|
+
const createKey = options.collection
|
|
292
|
+
? `create${capitalize$1(options.collection)}`
|
|
293
|
+
: 'create';
|
|
294
|
+
const updateKey = options.collection
|
|
295
|
+
? `update${capitalize$1(options.collection)}`
|
|
296
|
+
: 'update';
|
|
297
|
+
const updateAllKey = options.collection
|
|
298
|
+
? `updateAll${capitalize$1(options.collection)}`
|
|
299
|
+
: 'updateAll';
|
|
300
|
+
const deleteKey = options.collection
|
|
301
|
+
? `delete${capitalize$1(options.collection)}`
|
|
302
|
+
: 'delete';
|
|
275
303
|
// TODO: Take these from @ngrx/signals/entities, when they are exported
|
|
276
|
-
const entitiesKey = options.collection
|
|
277
|
-
|
|
304
|
+
const entitiesKey = options.collection
|
|
305
|
+
? `${options.collection}Entities`
|
|
306
|
+
: 'entities';
|
|
307
|
+
const entityMapKey = options.collection
|
|
308
|
+
? `${options.collection}EntityMap`
|
|
309
|
+
: 'entityMap';
|
|
278
310
|
const idsKey = options.collection ? `${options.collection}Ids` : 'ids';
|
|
279
311
|
return {
|
|
280
312
|
filterKey,
|
|
@@ -292,23 +324,23 @@ function getDataServiceKeys(options) {
|
|
|
292
324
|
createKey,
|
|
293
325
|
updateKey,
|
|
294
326
|
updateAllKey,
|
|
295
|
-
deleteKey
|
|
327
|
+
deleteKey,
|
|
296
328
|
};
|
|
297
329
|
}
|
|
298
330
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
331
|
function withDataService(options) {
|
|
300
332
|
const { dataServiceType, filter, collection: prefix } = options;
|
|
301
|
-
const { entitiesKey, filterKey, loadKey, selectedEntitiesKey, selectedIdsKey, updateFilterKey, updateSelectedKey, currentKey, createKey, updateKey, updateAllKey, deleteKey, loadByIdKey, setCurrentKey } = getDataServiceKeys(options);
|
|
333
|
+
const { entitiesKey, filterKey, loadKey, selectedEntitiesKey, selectedIdsKey, updateFilterKey, updateSelectedKey, currentKey, createKey, updateKey, updateAllKey, deleteKey, loadByIdKey, setCurrentKey, } = getDataServiceKeys(options);
|
|
302
334
|
const { callStateKey } = getCallStateKeys({ collection: prefix });
|
|
303
335
|
return signalStoreFeature(withState(() => ({
|
|
304
336
|
[filterKey]: filter,
|
|
305
337
|
[selectedIdsKey]: {},
|
|
306
|
-
[currentKey]: undefined
|
|
338
|
+
[currentKey]: undefined,
|
|
307
339
|
})), withComputed((store) => {
|
|
308
340
|
const entities = store[entitiesKey];
|
|
309
341
|
const selectedIds = store[selectedIdsKey];
|
|
310
342
|
return {
|
|
311
|
-
[selectedEntitiesKey]: computed(() => entities().filter(e => selectedIds()[e.id]))
|
|
343
|
+
[selectedEntitiesKey]: computed(() => entities().filter((e) => selectedIds()[e.id])),
|
|
312
344
|
};
|
|
313
345
|
}), withMethods((store) => {
|
|
314
346
|
const dataService = inject(dataServiceType);
|
|
@@ -321,7 +353,7 @@ function withDataService(options) {
|
|
|
321
353
|
[selectedIdsKey]: {
|
|
322
354
|
...state[selectedIdsKey],
|
|
323
355
|
[id]: selected,
|
|
324
|
-
}
|
|
356
|
+
},
|
|
325
357
|
}));
|
|
326
358
|
},
|
|
327
359
|
[loadKey]: async () => {
|
|
@@ -329,7 +361,9 @@ function withDataService(options) {
|
|
|
329
361
|
store[callStateKey] && patchState$1(store, setLoading(prefix));
|
|
330
362
|
try {
|
|
331
363
|
const result = await dataService.load(filter());
|
|
332
|
-
patchState$1(store, prefix
|
|
364
|
+
patchState$1(store, prefix
|
|
365
|
+
? setAllEntities(result, { collection: prefix })
|
|
366
|
+
: setAllEntities(result));
|
|
333
367
|
store[callStateKey] && patchState$1(store, setLoaded(prefix));
|
|
334
368
|
}
|
|
335
369
|
catch (e) {
|
|
@@ -358,7 +392,9 @@ function withDataService(options) {
|
|
|
358
392
|
try {
|
|
359
393
|
const created = await dataService.create(entity);
|
|
360
394
|
patchState$1(store, { [currentKey]: created });
|
|
361
|
-
patchState$1(store, prefix
|
|
395
|
+
patchState$1(store, prefix
|
|
396
|
+
? addEntity(created, { collection: prefix })
|
|
397
|
+
: addEntity(created));
|
|
362
398
|
store[callStateKey] && patchState$1(store, setLoaded(prefix));
|
|
363
399
|
}
|
|
364
400
|
catch (e) {
|
|
@@ -372,9 +408,12 @@ function withDataService(options) {
|
|
|
372
408
|
try {
|
|
373
409
|
const updated = await dataService.update(entity);
|
|
374
410
|
patchState$1(store, { [currentKey]: updated });
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
411
|
+
const updateArg = {
|
|
412
|
+
id: updated.id,
|
|
413
|
+
changes: updated,
|
|
414
|
+
};
|
|
415
|
+
const updater = (collection) => updateEntity(updateArg, { collection });
|
|
416
|
+
patchState$1(store, prefix ? updater(prefix) : updateEntity(updateArg));
|
|
378
417
|
store[callStateKey] && patchState$1(store, setLoaded(prefix));
|
|
379
418
|
}
|
|
380
419
|
catch (e) {
|
|
@@ -386,7 +425,9 @@ function withDataService(options) {
|
|
|
386
425
|
store[callStateKey] && patchState$1(store, setLoading(prefix));
|
|
387
426
|
try {
|
|
388
427
|
const result = await dataService.updateAll(entities);
|
|
389
|
-
patchState$1(store, prefix
|
|
428
|
+
patchState$1(store, prefix
|
|
429
|
+
? setAllEntities(result, { collection: prefix })
|
|
430
|
+
: setAllEntities(result));
|
|
390
431
|
store[callStateKey] && patchState$1(store, setLoaded(prefix));
|
|
391
432
|
}
|
|
392
433
|
catch (e) {
|
|
@@ -400,7 +441,9 @@ function withDataService(options) {
|
|
|
400
441
|
try {
|
|
401
442
|
await dataService.delete(entity);
|
|
402
443
|
patchState$1(store, { [currentKey]: undefined });
|
|
403
|
-
patchState$1(store, prefix
|
|
444
|
+
patchState$1(store, prefix
|
|
445
|
+
? removeEntity(entity.id, { collection: prefix })
|
|
446
|
+
: removeEntity(entity.id));
|
|
404
447
|
store[callStateKey] && patchState$1(store, setLoaded(prefix));
|
|
405
448
|
}
|
|
406
449
|
catch (e) {
|
|
@@ -413,11 +456,16 @@ function withDataService(options) {
|
|
|
413
456
|
}
|
|
414
457
|
|
|
415
458
|
const defaultOptions = {
|
|
416
|
-
maxStackSize: 100
|
|
459
|
+
maxStackSize: 100,
|
|
417
460
|
};
|
|
418
461
|
function getUndoRedoKeys(collections) {
|
|
419
462
|
if (collections) {
|
|
420
|
-
return collections.flatMap(c => [
|
|
463
|
+
return collections.flatMap((c) => [
|
|
464
|
+
`${c}EntityMap`,
|
|
465
|
+
`${c}Ids`,
|
|
466
|
+
`selected${capitalize$1(c)}Ids`,
|
|
467
|
+
`${c}Filter`,
|
|
468
|
+
]);
|
|
421
469
|
}
|
|
422
470
|
return ['entityMap', 'ids', 'selectedIds', 'filter'];
|
|
423
471
|
}
|
|
@@ -426,7 +474,7 @@ function withUndoRedo(options = {}) {
|
|
|
426
474
|
let skipOnce = false;
|
|
427
475
|
const normalized = {
|
|
428
476
|
...defaultOptions,
|
|
429
|
-
...options
|
|
477
|
+
...options,
|
|
430
478
|
};
|
|
431
479
|
//
|
|
432
480
|
// Design Decision: This feature has its own
|
|
@@ -443,7 +491,7 @@ function withUndoRedo(options = {}) {
|
|
|
443
491
|
const keys = getUndoRedoKeys(normalized?.collections);
|
|
444
492
|
return signalStoreFeature(withComputed(() => ({
|
|
445
493
|
canUndo: canUndo.asReadonly(),
|
|
446
|
-
canRedo: canRedo.asReadonly()
|
|
494
|
+
canRedo: canRedo.asReadonly(),
|
|
447
495
|
})), withMethods((store) => ({
|
|
448
496
|
undo() {
|
|
449
497
|
const item = undoStack.pop();
|
|
@@ -468,7 +516,7 @@ function withUndoRedo(options = {}) {
|
|
|
468
516
|
previous = item;
|
|
469
517
|
}
|
|
470
518
|
updateInternal();
|
|
471
|
-
}
|
|
519
|
+
},
|
|
472
520
|
})), withHooks({
|
|
473
521
|
onInit(store) {
|
|
474
522
|
effect(() => {
|
|
@@ -477,7 +525,7 @@ function withUndoRedo(options = {}) {
|
|
|
477
525
|
if (s && isSignal(s)) {
|
|
478
526
|
return {
|
|
479
527
|
...acc,
|
|
480
|
-
[key]: s()
|
|
528
|
+
[key]: s(),
|
|
481
529
|
};
|
|
482
530
|
}
|
|
483
531
|
return acc;
|
|
@@ -486,6 +534,15 @@ function withUndoRedo(options = {}) {
|
|
|
486
534
|
skipOnce = false;
|
|
487
535
|
return;
|
|
488
536
|
}
|
|
537
|
+
//
|
|
538
|
+
// Deep Comparison to prevent duplicated entries
|
|
539
|
+
// on the stack. This can e.g. happen after an undo
|
|
540
|
+
// if the component sends back the undone filter
|
|
541
|
+
// to the store.
|
|
542
|
+
//
|
|
543
|
+
if (JSON.stringify(cand) === JSON.stringify(previous)) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
489
546
|
// Clear redoStack after recorded action
|
|
490
547
|
redoStack.splice(0);
|
|
491
548
|
if (previous) {
|
|
@@ -498,7 +555,7 @@ function withUndoRedo(options = {}) {
|
|
|
498
555
|
// Don't propogate current reactive context
|
|
499
556
|
untracked(() => updateInternal());
|
|
500
557
|
});
|
|
501
|
-
}
|
|
558
|
+
},
|
|
502
559
|
}));
|
|
503
560
|
}
|
|
504
561
|
|
|
@@ -555,114 +612,6 @@ function withStorageSync(configOrKey) {
|
|
|
555
612
|
}));
|
|
556
613
|
}
|
|
557
614
|
|
|
558
|
-
function isUnsubscribable(fn) {
|
|
559
|
-
return !!fn?.unsubscribe;
|
|
560
|
-
}
|
|
561
|
-
function capitalize(str) {
|
|
562
|
-
return str ? str[0].toUpperCase() + str.substring(1) : str;
|
|
563
|
-
}
|
|
564
|
-
function isActionCreator(action) {
|
|
565
|
-
return (typeof action === 'function' &&
|
|
566
|
-
action &&
|
|
567
|
-
action.type &&
|
|
568
|
-
typeof action.type === 'string');
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
class SignalReduxStore {
|
|
572
|
-
constructor() {
|
|
573
|
-
this.mapperDict = {};
|
|
574
|
-
this.dispatch = rxMethod(pipe(tap((action) => {
|
|
575
|
-
const callbacks = this.mapperDict[action.type];
|
|
576
|
-
if (callbacks?.storeMethod) {
|
|
577
|
-
if (isUnsubscribable(callbacks.storeMethod) &&
|
|
578
|
-
callbacks.resultMethod) {
|
|
579
|
-
return callbacks.storeMethod(action, (a) => {
|
|
580
|
-
const resultAction = callbacks.resultMethod?.(a);
|
|
581
|
-
this.dispatch(resultAction);
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
return callbacks?.storeMethod(action);
|
|
585
|
-
}
|
|
586
|
-
return;
|
|
587
|
-
})));
|
|
588
|
-
}
|
|
589
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
590
|
-
connectFeatureStore(mappers) {
|
|
591
|
-
mappers.forEach(mapper => mapper.types.forEach(action => this.mapperDict[action] = {
|
|
592
|
-
storeMethod: mapper.storeMethod,
|
|
593
|
-
resultMethod: mapper.resultMethod
|
|
594
|
-
}));
|
|
595
|
-
}
|
|
596
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SignalReduxStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
597
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SignalReduxStore, providedIn: 'root' }); }
|
|
598
|
-
}
|
|
599
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SignalReduxStore, decorators: [{
|
|
600
|
-
type: Injectable,
|
|
601
|
-
args: [{
|
|
602
|
-
providedIn: 'root'
|
|
603
|
-
}]
|
|
604
|
-
}] });
|
|
605
|
-
function injectReduxDispatch() {
|
|
606
|
-
return inject(SignalReduxStore).dispatch;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function mapAction(...args) {
|
|
610
|
-
let resultMethod = args.pop();
|
|
611
|
-
let storeMethod = args.pop();
|
|
612
|
-
if (isActionCreator(storeMethod)) {
|
|
613
|
-
args.push(storeMethod);
|
|
614
|
-
storeMethod = resultMethod || storeMethod;
|
|
615
|
-
resultMethod = undefined;
|
|
616
|
-
}
|
|
617
|
-
const types = args.map((creator) => creator.type);
|
|
618
|
-
return {
|
|
619
|
-
types,
|
|
620
|
-
storeMethod,
|
|
621
|
-
resultMethod
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
function withActionMappers(...mappers) {
|
|
625
|
-
return mappers;
|
|
626
|
-
}
|
|
627
|
-
function createReduxState(storeName, signalStore, withActionMappers) {
|
|
628
|
-
const isRootProvider = signalStore?.ɵprov?.providedIn === 'root';
|
|
629
|
-
return {
|
|
630
|
-
[`provide${capitalize(storeName)}Store`]: (connectReduxDevtools = false) => makeEnvironmentProviders([
|
|
631
|
-
isRootProvider ? [] : signalStore,
|
|
632
|
-
{
|
|
633
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
634
|
-
multi: true,
|
|
635
|
-
useFactory: (signalReduxStore = inject(SignalReduxStore), store = inject(signalStore)) => () => {
|
|
636
|
-
if (connectReduxDevtools) {
|
|
637
|
-
// addStoreToReduxDevtools(store, storeName, false);
|
|
638
|
-
}
|
|
639
|
-
signalReduxStore.connectFeatureStore(withActionMappers(store));
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
]),
|
|
643
|
-
[`inject${capitalize(storeName)}Store`]: () => Object.assign(inject(signalStore), { dispatch: injectReduxDispatch() })
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
function reduxMethod(generator, resultMethodOrConfig, config) {
|
|
648
|
-
const injector = inject(Injector);
|
|
649
|
-
if (typeof resultMethodOrConfig === 'function') {
|
|
650
|
-
let unsubscribable;
|
|
651
|
-
const inputResultFn = ((input, resultMethod = resultMethodOrConfig) => {
|
|
652
|
-
const rxMethodWithResult = rxMethod(pipe(generator, map(resultMethod)), {
|
|
653
|
-
...(config || {}),
|
|
654
|
-
injector: config?.injector || injector
|
|
655
|
-
});
|
|
656
|
-
const rxWithInput = rxMethodWithResult(input);
|
|
657
|
-
unsubscribable = { unsubscribe: rxWithInput.unsubscribe.bind(rxWithInput) };
|
|
658
|
-
return rxWithInput;
|
|
659
|
-
});
|
|
660
|
-
inputResultFn.unsubscribe = () => unsubscribable?.unsubscribe();
|
|
661
|
-
return inputResultFn;
|
|
662
|
-
}
|
|
663
|
-
return rxMethod(generator, resultMethodOrConfig);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
615
|
/** With pagination comes in two flavors the first one is local pagination or in memory pagination. For example we have 2000 items which we want
|
|
667
616
|
* to display in a table and the response payload is small enough to be stored in the memory. But we can not display all 2000 items at once
|
|
668
617
|
* so we need to paginate the data. The second flavor is server side pagination where the response payload is too large to be stored in the memory
|
|
@@ -671,9 +620,9 @@ function reduxMethod(generator, resultMethodOrConfig, config) {
|
|
|
671
620
|
* This feature implements the local pagination.
|
|
672
621
|
*/
|
|
673
622
|
function withPagination(options) {
|
|
674
|
-
const { pageKey, pageSizeKey, entitiesKey, selectedPageEntitiesKey, totalCountKey, pageCountKey, pageNavigationArrayMaxKey, pageNavigationArrayKey, } = createPaginationKeys(options);
|
|
623
|
+
const { pageKey, pageSizeKey, entitiesKey, selectedPageEntitiesKey, totalCountKey, pageCountKey, pageNavigationArrayMaxKey, pageNavigationArrayKey, setPageSizeKey, nextPageKey, previousPageKey, lastPageKey, firstPageKey, gotoPageKey, hasNextPageKey, hasPreviousPageKey, } = createPaginationKeys(options);
|
|
675
624
|
return signalStoreFeature(withState({
|
|
676
|
-
[pageKey]:
|
|
625
|
+
[pageKey]: 0,
|
|
677
626
|
[pageSizeKey]: 10,
|
|
678
627
|
[pageNavigationArrayMaxKey]: 7,
|
|
679
628
|
}), withComputed((store) => {
|
|
@@ -686,14 +635,7 @@ function withPagination(options) {
|
|
|
686
635
|
[selectedPageEntitiesKey]: computed(() => {
|
|
687
636
|
const pageSizeValue = pageSize();
|
|
688
637
|
const pageValue = page();
|
|
689
|
-
|
|
690
|
-
// we should return an empty array
|
|
691
|
-
if (pageValue < 0 ||
|
|
692
|
-
pageSizeValue === 0 ||
|
|
693
|
-
pageValue > Math.ceil(entities().length / pageSizeValue)) {
|
|
694
|
-
return [];
|
|
695
|
-
}
|
|
696
|
-
return entities().slice((pageValue - 1) * pageSizeValue, pageValue * pageSizeValue);
|
|
638
|
+
return entities().slice(pageValue * pageSizeValue, (pageValue + 1) * pageSizeValue);
|
|
697
639
|
}),
|
|
698
640
|
[totalCountKey]: computed(() => entities().length),
|
|
699
641
|
[pageCountKey]: computed(() => {
|
|
@@ -705,6 +647,36 @@ function withPagination(options) {
|
|
|
705
647
|
return Math.ceil(totalCountValue / pageSizeValue);
|
|
706
648
|
}),
|
|
707
649
|
[pageNavigationArrayKey]: computed(() => createPageArray(page(), pageSize(), entities().length, pageNavigationArrayMax())),
|
|
650
|
+
[hasNextPageKey]: computed(() => {
|
|
651
|
+
return page() < pageSize();
|
|
652
|
+
}),
|
|
653
|
+
[hasPreviousPageKey]: computed(() => {
|
|
654
|
+
return page() > 1;
|
|
655
|
+
}),
|
|
656
|
+
};
|
|
657
|
+
}), withMethods((store) => {
|
|
658
|
+
return {
|
|
659
|
+
[setPageSizeKey]: (size) => {
|
|
660
|
+
patchState$1(store, setPageSize(size, options));
|
|
661
|
+
},
|
|
662
|
+
[nextPageKey]: () => {
|
|
663
|
+
patchState$1(store, nextPage(options));
|
|
664
|
+
},
|
|
665
|
+
[previousPageKey]: () => {
|
|
666
|
+
patchState$1(store, previousPage(options));
|
|
667
|
+
},
|
|
668
|
+
[lastPageKey]: () => {
|
|
669
|
+
const lastPage = store[pageCountKey]();
|
|
670
|
+
if (lastPage === 0)
|
|
671
|
+
return;
|
|
672
|
+
patchState$1(store, gotoPage(lastPage - 1, options));
|
|
673
|
+
},
|
|
674
|
+
[firstPageKey]: () => {
|
|
675
|
+
patchState$1(store, firstPage());
|
|
676
|
+
},
|
|
677
|
+
[gotoPageKey]: (page) => {
|
|
678
|
+
patchState$1(store, gotoPage(page, options));
|
|
679
|
+
},
|
|
708
680
|
};
|
|
709
681
|
}));
|
|
710
682
|
}
|
|
@@ -751,7 +723,9 @@ function createPaginationKeys(options) {
|
|
|
751
723
|
const selectedPageEntitiesKey = options?.collection
|
|
752
724
|
? `selectedPage${capitalize$1(options?.collection)}Entities`
|
|
753
725
|
: 'selectedPageEntities';
|
|
754
|
-
const pageKey = options?.collection
|
|
726
|
+
const pageKey = options?.collection
|
|
727
|
+
? `${options.collection}CurrentPage`
|
|
728
|
+
: 'currentPage';
|
|
755
729
|
const pageSizeKey = options?.collection
|
|
756
730
|
? `${options.collection}PageSize`
|
|
757
731
|
: 'pageSize';
|
|
@@ -767,6 +741,30 @@ function createPaginationKeys(options) {
|
|
|
767
741
|
const pageNavigationArrayKey = options?.collection
|
|
768
742
|
? `${options.collection}PageNavigationArray`
|
|
769
743
|
: 'pageNavigationArray';
|
|
744
|
+
const setPageSizeKey = options?.collection
|
|
745
|
+
? `set${capitalize$1(options.collection)}PageSize`
|
|
746
|
+
: 'setPageSize';
|
|
747
|
+
const nextPageKey = options?.collection
|
|
748
|
+
? `next${capitalize$1(options.collection)}Page`
|
|
749
|
+
: 'nextPage';
|
|
750
|
+
const previousPageKey = options?.collection
|
|
751
|
+
? `previous${capitalize$1(options.collection)}Page`
|
|
752
|
+
: 'previousPage';
|
|
753
|
+
const lastPageKey = options?.collection
|
|
754
|
+
? `last${capitalize$1(options.collection)}Page`
|
|
755
|
+
: 'lastPage';
|
|
756
|
+
const firstPageKey = options?.collection
|
|
757
|
+
? `first${capitalize$1(options.collection)}Page`
|
|
758
|
+
: 'firstPage';
|
|
759
|
+
const gotoPageKey = options?.collection
|
|
760
|
+
? `goto${capitalize$1(options.collection)}Page`
|
|
761
|
+
: 'gotoPage';
|
|
762
|
+
const hasNextPageKey = options?.collection
|
|
763
|
+
? `hasNext${capitalize$1(options.collection)}Page`
|
|
764
|
+
: 'hasNextPage';
|
|
765
|
+
const hasPreviousPageKey = options?.collection
|
|
766
|
+
? `hasPrevious${capitalize$1(options.collection)}Page`
|
|
767
|
+
: 'hasPreviousPage';
|
|
770
768
|
return {
|
|
771
769
|
pageKey,
|
|
772
770
|
pageSizeKey,
|
|
@@ -776,6 +774,14 @@ function createPaginationKeys(options) {
|
|
|
776
774
|
pageCountKey,
|
|
777
775
|
pageNavigationArrayKey,
|
|
778
776
|
pageNavigationArrayMaxKey,
|
|
777
|
+
setPageSizeKey,
|
|
778
|
+
nextPageKey,
|
|
779
|
+
previousPageKey,
|
|
780
|
+
lastPageKey,
|
|
781
|
+
firstPageKey,
|
|
782
|
+
gotoPageKey,
|
|
783
|
+
hasNextPageKey,
|
|
784
|
+
hasPreviousPageKey,
|
|
779
785
|
};
|
|
780
786
|
}
|
|
781
787
|
function createPageArray(currentPage, itemsPerPage, totalItems, paginationRange) {
|
|
@@ -812,6 +818,114 @@ function createPageArray(currentPage, itemsPerPage, totalItems, paginationRange)
|
|
|
812
818
|
return pages;
|
|
813
819
|
}
|
|
814
820
|
|
|
821
|
+
function isUnsubscribable(fn) {
|
|
822
|
+
return !!fn?.unsubscribe;
|
|
823
|
+
}
|
|
824
|
+
function capitalize(str) {
|
|
825
|
+
return str ? str[0].toUpperCase() + str.substring(1) : str;
|
|
826
|
+
}
|
|
827
|
+
function isActionCreator(action) {
|
|
828
|
+
return (typeof action === 'function' &&
|
|
829
|
+
action &&
|
|
830
|
+
action.type &&
|
|
831
|
+
typeof action.type === 'string');
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
class SignalReduxStore {
|
|
835
|
+
constructor() {
|
|
836
|
+
this.mapperDict = {};
|
|
837
|
+
this.dispatch = rxMethod(pipe(tap((action) => {
|
|
838
|
+
const callbacks = this.mapperDict[action.type];
|
|
839
|
+
if (callbacks?.storeMethod) {
|
|
840
|
+
if (isUnsubscribable(callbacks.storeMethod) &&
|
|
841
|
+
callbacks.resultMethod) {
|
|
842
|
+
return callbacks.storeMethod(action, (a) => {
|
|
843
|
+
const resultAction = callbacks.resultMethod?.(a);
|
|
844
|
+
this.dispatch(resultAction);
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
return callbacks?.storeMethod(action);
|
|
848
|
+
}
|
|
849
|
+
return;
|
|
850
|
+
})));
|
|
851
|
+
}
|
|
852
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
853
|
+
connectFeatureStore(mappers) {
|
|
854
|
+
mappers.forEach(mapper => mapper.types.forEach(action => this.mapperDict[action] = {
|
|
855
|
+
storeMethod: mapper.storeMethod,
|
|
856
|
+
resultMethod: mapper.resultMethod
|
|
857
|
+
}));
|
|
858
|
+
}
|
|
859
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: SignalReduxStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
860
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: SignalReduxStore, providedIn: 'root' }); }
|
|
861
|
+
}
|
|
862
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: SignalReduxStore, decorators: [{
|
|
863
|
+
type: Injectable,
|
|
864
|
+
args: [{
|
|
865
|
+
providedIn: 'root'
|
|
866
|
+
}]
|
|
867
|
+
}] });
|
|
868
|
+
function injectReduxDispatch() {
|
|
869
|
+
return inject(SignalReduxStore).dispatch;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function mapAction(...args) {
|
|
873
|
+
let resultMethod = args.pop();
|
|
874
|
+
let storeMethod = args.pop();
|
|
875
|
+
if (isActionCreator(storeMethod)) {
|
|
876
|
+
args.push(storeMethod);
|
|
877
|
+
storeMethod = resultMethod || storeMethod;
|
|
878
|
+
resultMethod = undefined;
|
|
879
|
+
}
|
|
880
|
+
const types = args.map((creator) => creator.type);
|
|
881
|
+
return {
|
|
882
|
+
types,
|
|
883
|
+
storeMethod,
|
|
884
|
+
resultMethod
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
function withActionMappers(...mappers) {
|
|
888
|
+
return mappers;
|
|
889
|
+
}
|
|
890
|
+
function createReduxState(storeName, signalStore, withActionMappers) {
|
|
891
|
+
const isRootProvider = signalStore?.ɵprov?.providedIn === 'root';
|
|
892
|
+
return {
|
|
893
|
+
[`provide${capitalize(storeName)}Store`]: (connectReduxDevtools = false) => makeEnvironmentProviders([
|
|
894
|
+
isRootProvider ? [] : signalStore,
|
|
895
|
+
{
|
|
896
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
897
|
+
multi: true,
|
|
898
|
+
useFactory: (signalReduxStore = inject(SignalReduxStore), store = inject(signalStore)) => () => {
|
|
899
|
+
if (connectReduxDevtools) {
|
|
900
|
+
// addStoreToReduxDevtools(store, storeName, false);
|
|
901
|
+
}
|
|
902
|
+
signalReduxStore.connectFeatureStore(withActionMappers(store));
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
]),
|
|
906
|
+
[`inject${capitalize(storeName)}Store`]: () => Object.assign(inject(signalStore), { dispatch: injectReduxDispatch() })
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
function reduxMethod(generator, resultMethodOrConfig, config) {
|
|
911
|
+
const injector = inject(Injector);
|
|
912
|
+
if (typeof resultMethodOrConfig === 'function') {
|
|
913
|
+
let unsubscribable;
|
|
914
|
+
const inputResultFn = ((input, resultMethod = resultMethodOrConfig) => {
|
|
915
|
+
const rxMethodWithResult = rxMethod(pipe(generator, map(resultMethod)), {
|
|
916
|
+
...(config || {}),
|
|
917
|
+
injector: config?.injector || injector
|
|
918
|
+
});
|
|
919
|
+
const rxWithInput = rxMethodWithResult(input);
|
|
920
|
+
unsubscribable = { unsubscribe: rxWithInput.unsubscribe.bind(rxWithInput) };
|
|
921
|
+
return rxWithInput;
|
|
922
|
+
});
|
|
923
|
+
inputResultFn.unsubscribe = () => unsubscribable?.unsubscribe();
|
|
924
|
+
return inputResultFn;
|
|
925
|
+
}
|
|
926
|
+
return rxMethod(generator, resultMethodOrConfig);
|
|
927
|
+
}
|
|
928
|
+
|
|
815
929
|
/**
|
|
816
930
|
* Generated bundle index. Do not edit.
|
|
817
931
|
*/
|