state-decorator 6.12.2 → 7.0.0-beta.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 +320 -61
- package/es/helpers.d.ts +48 -0
- package/es/helpers.js +2 -0
- package/es/helpers.js.map +1 -0
- package/es/impl.d.ts +1 -1
- package/es/impl.js +1 -1
- package/es/index.d.ts +42 -39
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/middlewares.js +1 -1
- package/es/test.d.ts +2 -2
- package/es/test.js +1 -1
- package/es/test.js.map +1 -1
- package/es/types.d.ts +16 -9
- package/es/v5_test.js +1 -1
- package/helpers.d.ts +48 -0
- package/helpers.js +2 -0
- package/helpers.js.map +1 -0
- package/impl.d.ts +1 -1
- package/impl.js +1 -1
- package/index.d.ts +42 -39
- package/index.js +1 -1
- package/middlewares.js +1 -1
- package/package.json +1 -1
- package/test.d.ts +2 -2
- package/test.js +1 -1
- package/test.js.map +1 -1
- package/types.d.ts +16 -9
- package/v5_test.js +1 -1
package/README.md
CHANGED
|
@@ -11,12 +11,22 @@ The StateDecorator is a set of Reacts hook that manages a complex component stat
|
|
|
11
11
|
- Deterministic state changes (clear separation of effects and side effects)
|
|
12
12
|
- Ease asynchronous actions state changes (loading / error states, success & error handlers, parallel actions management, optimistic updates...)
|
|
13
13
|
- Easily and efficiently share slices of state.
|
|
14
|
-
- Easily testable (
|
|
14
|
+
- Easily testable (test framework provided)
|
|
15
15
|
- Easily update state from or react to props changes
|
|
16
|
-
- Ease debugging (trace state changes)
|
|
16
|
+
- Ease debugging (trace state changes, dev tools)
|
|
17
17
|
- Improve code conciseness (no boiler plate code)
|
|
18
|
-
-
|
|
19
|
-
|
|
18
|
+
- Strongly typed (Typescript)
|
|
19
|
+
|
|
20
|
+
# V7: Partial state and new hooks
|
|
21
|
+
|
|
22
|
+
- React 17 (upcoming V8 for React 18)
|
|
23
|
+
- All effects can now return a partial state that will be merged with current state.
|
|
24
|
+
- More documentation on global and local store use cases.
|
|
25
|
+
- **useLocalStore** and **useStore** now have a parameter to specify if the React component must re-rerender after a state change.
|
|
26
|
+
- New **useStoreContextSlice** hook was added to get a slice of a store in a context.
|
|
27
|
+
- New **onMountDeferred** to execute initialization code after initial render
|
|
28
|
+
- New effect helpers
|
|
29
|
+
- Removed useBindStore hook.
|
|
20
30
|
|
|
21
31
|
# 🏎️ V6: The Store
|
|
22
32
|
|
|
@@ -82,13 +92,12 @@ export const getInitialState = (): State => ({
|
|
|
82
92
|
|
|
83
93
|
export const userAppActions: StoreActions<State, Actions, Props> = {
|
|
84
94
|
// synchronous action (simple form)
|
|
85
|
-
selectUser: ({
|
|
95
|
+
selectUser: ({ args: [id] }) => ({ selectedUserId: id }),
|
|
86
96
|
|
|
87
97
|
// a synchronous action with side effects
|
|
88
98
|
selectAndLoadUser: {
|
|
89
|
-
// same as simple form, using aliases (use short context alias 's' instead of 'state')
|
|
90
99
|
// effects contain only immutable state changes
|
|
91
|
-
effects: ({
|
|
100
|
+
effects: ({ args: [id] }) => ({ selectedUserId: id }),
|
|
92
101
|
// side effects (ie. other effects than state changes), using "actions" alias
|
|
93
102
|
sideEffects: ({ a }) => {
|
|
94
103
|
a.loadUser();
|
|
@@ -100,9 +109,9 @@ export const userAppActions: StoreActions<State, Actions, Props> = {
|
|
|
100
109
|
// promise provider, can use action context (ctx) to get current state, args, props etc.
|
|
101
110
|
getPromise: (ctx) => Promise.resolve({ firstName: 'John', lastName: 'Doe' }),
|
|
102
111
|
// state changes
|
|
103
|
-
effects: ({
|
|
112
|
+
effects: ({ res }) => ({ user: res }),
|
|
104
113
|
// state changes if error
|
|
105
|
-
errorEffects: ({
|
|
114
|
+
errorEffects: ({ error }) => ({ user: null }),
|
|
106
115
|
// side effects here
|
|
107
116
|
sideEffects: ({ res, actions }) => {},
|
|
108
117
|
// side effects if error
|
|
@@ -139,12 +148,12 @@ export function App(props: Props) => {
|
|
|
139
148
|
|
|
140
149
|
# React hooks
|
|
141
150
|
|
|
142
|
-
| Hook
|
|
143
|
-
|
|
|
144
|
-
| useLocalStore
|
|
145
|
-
| useStore
|
|
146
|
-
|
|
|
147
|
-
|
|
|
151
|
+
| Hook | Purpose | Returns | Is component refreshed on store change? | Is store destroyed on unmount? |
|
|
152
|
+
| -------------------- | --------------------------------------------------- | ------- | --------------------------------------- | ------------------------------ |
|
|
153
|
+
| useLocalStore | Create a store and binds it to the react component. | Store | if **refreshOnUpdate** is set | Y |
|
|
154
|
+
| useStore | Binds a store instance to the react component. | Store | if **refreshOnUpdate** is set | N |
|
|
155
|
+
| useStoreSlice | Get a slice of a store. | Slice | If slice has changed only | N |
|
|
156
|
+
| useStoreContextSlice | Get a slice of a store stored in a context | Slice | If slice has changed only | N |
|
|
148
157
|
|
|
149
158
|
# Initial state
|
|
150
159
|
|
|
@@ -190,14 +199,14 @@ The StateDecorator is taking a list of actions and decorate them to inject state
|
|
|
190
199
|
## Short form
|
|
191
200
|
|
|
192
201
|
```typescript
|
|
193
|
-
action: (ctx) => ctx.state, // state
|
|
202
|
+
action: (ctx) => ctx.state, // changes to be merged to current state
|
|
194
203
|
```
|
|
195
204
|
|
|
196
205
|
Example:
|
|
197
206
|
|
|
198
207
|
```typescript
|
|
199
208
|
const actions: StoreActions<State, Actions> = {
|
|
200
|
-
setText: ({
|
|
209
|
+
setText: ({ args: [newText] }) => ({ text: newText }),
|
|
201
210
|
};
|
|
202
211
|
```
|
|
203
212
|
|
|
@@ -222,7 +231,7 @@ Example:
|
|
|
222
231
|
```typescript
|
|
223
232
|
const actions: StoreActions<State, Actions> = {
|
|
224
233
|
setText: {
|
|
225
|
-
effects: ({
|
|
234
|
+
effects: ({ args: [newText] }) => ({ text: newText }),
|
|
226
235
|
// use either debounceTimeout or debounceSideEffectsTimeout
|
|
227
236
|
// debounceTimeout: 5000,
|
|
228
237
|
debounceSideEffectsTimeout: 5000,
|
|
@@ -272,7 +281,7 @@ Example:
|
|
|
272
281
|
const actions: StoreActions<State, Actions> = {
|
|
273
282
|
loadList: {
|
|
274
283
|
getPromise: () => fetch('https://myapi/myservices').then((res) => (res.ok ? res.json() : Promise.reject())),
|
|
275
|
-
effects: ({
|
|
284
|
+
effects: ({ res }) => ({ list: res }),
|
|
276
285
|
sideEffects: ({ a }) => {
|
|
277
286
|
a.otherAction();
|
|
278
287
|
},
|
|
@@ -395,7 +404,7 @@ If some actions need to be triggered, set **errorSideEffects**.
|
|
|
395
404
|
const actions: StoreActions<State, Actions> = {
|
|
396
405
|
loadList: {
|
|
397
406
|
getPromise: () => new Promise((_, reject) => setTimeout(reject, 500, new Error('Too bad'))),
|
|
398
|
-
errorEffects: ({
|
|
407
|
+
errorEffects: ({ error }) => ({ error: error.message, list: [] }),
|
|
399
408
|
getErrorMessage: ({ err }) => err.message,
|
|
400
409
|
errorSideEffects: ({ error }) => {
|
|
401
410
|
Logger.log(error);
|
|
@@ -517,8 +526,8 @@ Example:
|
|
|
517
526
|
const actions: StoreActions<State, Actions> = {
|
|
518
527
|
deleteItem: {
|
|
519
528
|
getPromise: ([id]) => new Promise((resolve) => setTimeout(resolve, 500)),
|
|
520
|
-
optimisticEffects: (
|
|
521
|
-
errorEffects: (
|
|
529
|
+
optimisticEffects: ({ args: [id] }) => ({ list: list.filter((item) => item.id === id) }),
|
|
530
|
+
errorEffects: ({err} => ({ err: error.message }),
|
|
522
531
|
},
|
|
523
532
|
};
|
|
524
533
|
```
|
|
@@ -554,9 +563,9 @@ export const actionsAbort: StoreActions<State, Actions, Props> = {
|
|
|
554
563
|
reject(new DOMException('Aborted', 'AbortError'));
|
|
555
564
|
});
|
|
556
565
|
}),
|
|
557
|
-
errorEffects: ({
|
|
558
|
-
effects: (
|
|
559
|
-
errorSideEffects: ({
|
|
566
|
+
errorEffects: ({ err}) => (err.name === 'AbortError' ? { isAborted: true } : { isError: true }),
|
|
567
|
+
effects: () => ({ isSuccess: true }),
|
|
568
|
+
errorSideEffects: ({ err }) => {
|
|
560
569
|
if (e.name === 'AbortError') {
|
|
561
570
|
console.log('AbortError side effect');
|
|
562
571
|
} else {
|
|
@@ -571,6 +580,40 @@ Note: ongoing abortable actions will be automatically aborted on store destructi
|
|
|
571
580
|
|
|
572
581
|
[](https://codesandbox.io/s/abort-v6-uvnl7)
|
|
573
582
|
|
|
583
|
+
## Helper effect functions
|
|
584
|
+
|
|
585
|
+
For common / simple use cases, some helpers functions are provided to write basic action effects and improve actions readability.
|
|
586
|
+
|
|
587
|
+
Example
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
import { setArgIn } from 'state-decorator/helpers';
|
|
591
|
+
|
|
592
|
+
type State = {
|
|
593
|
+
myProp: string;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
type Actions = {
|
|
597
|
+
setMyProp: (v: string) => void;
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
const actions: StoreActions<State, Actions> = {
|
|
601
|
+
setMyProp: setArgIn('myProp'),
|
|
602
|
+
// same as
|
|
603
|
+
// setMyProp: ({ args: [v] }) => ({ myProp: v }),
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
| Name | Purpose | Action signature |
|
|
608
|
+
| ------------ | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
|
|
609
|
+
| setArgIn | Effect function to update a state property from action first argument | (v:T) => void |
|
|
610
|
+
| setTrueIn | Effect function to update a boolean state property to true | () => void |
|
|
611
|
+
| setFalseIn | Effect function to update a boolean state property to false | () => void |
|
|
612
|
+
| toggleProp | Effect function to toggle a boolean state property | () => void |
|
|
613
|
+
| setMapProp | Effect function to update a state property of type Record<string, T> using first action argument as key and second as value | (id: string, v:T) => void |
|
|
614
|
+
| setArrayItem | Effect function to update a state property of type T[] using first action argument as index and second as value | (index: number, v:T) => void |
|
|
615
|
+
| setResIn | Effect function of asynchronous action to update a state property with the result of the promise | () => Promise<T> |
|
|
616
|
+
|
|
574
617
|
## Call actions on mount
|
|
575
618
|
|
|
576
619
|
When store is created (for example whe React component in mounted), the **onMount** option is called.
|
|
@@ -580,7 +623,21 @@ import { createStore } from 'state-decorator';
|
|
|
580
623
|
|
|
581
624
|
const store = createStore(getInitialState, actionsImpl, {
|
|
582
625
|
onMount: ({ a }) => {
|
|
583
|
-
a.loadList;
|
|
626
|
+
a.loadList();
|
|
627
|
+
},
|
|
628
|
+
});
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
After React component is mounted using _useLocalStore_, the **onMountDeferred** option is called (in a _useEffect_).
|
|
632
|
+
The **onMount** is called _during_ the render of the hooks. If the onMount code is containing a function that is changing parent state,
|
|
633
|
+
React will not update the parent state and will issue a warning.
|
|
634
|
+
|
|
635
|
+
```typescript
|
|
636
|
+
import { createStore } from 'state-decorator';
|
|
637
|
+
|
|
638
|
+
const store = createStore(getInitialState, actionsImpl, {
|
|
639
|
+
onMountDeferred: ({ p }) => {
|
|
640
|
+
p.loadParentList();
|
|
584
641
|
},
|
|
585
642
|
});
|
|
586
643
|
```
|
|
@@ -646,34 +703,6 @@ export function SubComponent() {
|
|
|
646
703
|
|
|
647
704
|
[](https://codesandbox.io/s/slices-v6-eg471?file=/src/SliceView.tsx)
|
|
648
705
|
|
|
649
|
-
# Global configuration
|
|
650
|
-
|
|
651
|
-
Overrides configuration to set properties that will be used by all stores.
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
// all parameters are optional
|
|
655
|
-
setGlobalConfig({
|
|
656
|
-
// Used to clone state and props when managing optimistic conflicting actions.
|
|
657
|
-
clone: defaultCloneFunc,
|
|
658
|
-
// Compare to objets and returns if they are equal (slices).
|
|
659
|
-
comparator: shallow,
|
|
660
|
-
// Callback function to handle asychronous actions rejected promise (error reporting).
|
|
661
|
-
asyncErrorHandler: () => {},
|
|
662
|
-
// Tests if the error will trigger a retry of the action or will fail directly (retry promises)
|
|
663
|
-
retryOnErrorFunction: (error: Error) => error instanceof TypeError,
|
|
664
|
-
// Notification function on successful asynchronous action (if success message is set on action)
|
|
665
|
-
notifySuccess: undefined,
|
|
666
|
-
// Notification function on failed asynchronous action (if error message is set on action)
|
|
667
|
-
notifyError: undefined,
|
|
668
|
-
// Notification function injected in side effects action context (success and error) to notify warning
|
|
669
|
-
notifyWarning: undefined,
|
|
670
|
-
// Function called to return common error message if error message is not provided or error not managed in action.
|
|
671
|
-
// To override locally in action, provide a function that returns _null_.
|
|
672
|
-
// If _isErrorManaged_ is set to _true_, this function will not be called.
|
|
673
|
-
getErrorMessage: undefined,
|
|
674
|
-
});
|
|
675
|
-
```
|
|
676
|
-
|
|
677
706
|
# Update store when props change
|
|
678
707
|
|
|
679
708
|
## Getting started
|
|
@@ -686,7 +715,7 @@ const store = createStore(getInitialState, actionsImpl, {
|
|
|
686
715
|
// list of depedencies that should trigger effects & side effects if changed
|
|
687
716
|
getDeps: (p) => [p.id],
|
|
688
717
|
// state changes, indices contains the indices of dependencies that have changed
|
|
689
|
-
effects: ({
|
|
718
|
+
effects: ({ props, indices, isInit }) => ({ selectedId: props.id }),
|
|
690
719
|
// other changes (use short aliases)
|
|
691
720
|
sideEffects: ({ p, a, indices, isInit }) => {
|
|
692
721
|
a.loadItem(p.id);
|
|
@@ -722,7 +751,7 @@ const store = createStore(getInitialState, actionsImpl, {
|
|
|
722
751
|
},
|
|
723
752
|
{
|
|
724
753
|
getDeps: (p) => [p.otherProp],
|
|
725
|
-
effects: ({
|
|
754
|
+
effects: ({ props, indices }) => ({ otherProp: props.otherProp }),
|
|
726
755
|
sideEffects: ({ p, a }) => {
|
|
727
756
|
a.otherSideEffect(p.otherProp);
|
|
728
757
|
},
|
|
@@ -745,7 +774,7 @@ const store = createStore(getInitialState, actionsImpl, {
|
|
|
745
774
|
onPropsChange: [
|
|
746
775
|
{
|
|
747
776
|
getDeps: (p) => [p.userId],
|
|
748
|
-
effects: ({
|
|
777
|
+
effects: ({ p }) => ({ userId: p.userId }),
|
|
749
778
|
sideEffects: ({ p, a }) => {
|
|
750
779
|
a.loadUser(p.userId);
|
|
751
780
|
},
|
|
@@ -759,7 +788,7 @@ const store = createStore(getInitialState, actionsImpl, {
|
|
|
759
788
|
onPropsChange: [
|
|
760
789
|
{
|
|
761
790
|
getDeps: (p) => [p.userId],
|
|
762
|
-
effects: ({
|
|
791
|
+
effects: ({ p, isInit }) => (isInit ? null : { userId: p.userId }),
|
|
763
792
|
sideEffects: ({ p, a }) => {
|
|
764
793
|
a.loadUser(p.userId);
|
|
765
794
|
},
|
|
@@ -776,6 +805,210 @@ const store = createStore(getInitialState, actionsImpl, {
|
|
|
776
805
|
- Use several prop change configurations to separate dependencies between props and have simple definition.
|
|
777
806
|
- Use onMount flag to have a more systematic and simpler code.
|
|
778
807
|
|
|
808
|
+
# Global / local Stores and State sharing
|
|
809
|
+
|
|
810
|
+
There are two ways to share state and actions:
|
|
811
|
+
|
|
812
|
+
- Using regular props.
|
|
813
|
+
- Using state slices.
|
|
814
|
+
|
|
815
|
+
There are two types of stores:
|
|
816
|
+
|
|
817
|
+
- Global store:
|
|
818
|
+
|
|
819
|
+
- store is created as an instance (**createStore**) and it is exported from the JS module.
|
|
820
|
+
- it can be imported in any other JS module.
|
|
821
|
+
- store lifespan is equal to the application one.
|
|
822
|
+
|
|
823
|
+
- Local store:
|
|
824
|
+
- store is created by a hook (**useLocalStore**) and is bound to a React component (each instance of this component owns its own store).
|
|
825
|
+
- action and props can be shared using props or sharing the store itself (see example below)
|
|
826
|
+
- store is destroyed when its owner React component is unmounted.
|
|
827
|
+
|
|
828
|
+
## Using props
|
|
829
|
+
|
|
830
|
+
- Bind a React component to make store state / actions available on React component.
|
|
831
|
+
- Any change in the store (state, loading actions, ...) will trigger a refresh of the bound React component.
|
|
832
|
+
- Pass state / actions using regular React props.
|
|
833
|
+
- Use React.memo to prevent unecessary React re-renders if needed.
|
|
834
|
+
|
|
835
|
+
### Global store
|
|
836
|
+
|
|
837
|
+
```typescript
|
|
838
|
+
// Declare typings & actions as above
|
|
839
|
+
|
|
840
|
+
// Create a store in a dedicated file, named GlobalStore.ts for example
|
|
841
|
+
export const store = createStore(getInitialState, userAppActions);
|
|
842
|
+
|
|
843
|
+
//----------------------
|
|
844
|
+
|
|
845
|
+
// In another file
|
|
846
|
+
import React, { memo } from 'react';
|
|
847
|
+
import { useStore } from 'state-decorator';
|
|
848
|
+
import store from './GlobalStore';
|
|
849
|
+
|
|
850
|
+
// Bind to react component
|
|
851
|
+
// Each time the store state changes, a re-render is done.
|
|
852
|
+
export function Container(props: Props) {
|
|
853
|
+
const { state, actions } = useStore(store, props);
|
|
854
|
+
return (
|
|
855
|
+
<div>
|
|
856
|
+
<Title text={state.title} />
|
|
857
|
+
<Subtitle text={state.subtitle} />
|
|
858
|
+
</div>
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// Simple presentation components
|
|
863
|
+
// Use memo to prevent re-render if another part of the state has changed than "title"
|
|
864
|
+
const Title = memo(function Title(props: { title: string }) {
|
|
865
|
+
return <div>{props.text}</div>;
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
const Subtitle = memo(function Subtitle(props: { subtitle: string }) {
|
|
869
|
+
return <div>{props.subtitle}</div>;
|
|
870
|
+
});
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### Local Store
|
|
874
|
+
|
|
875
|
+
```typescript
|
|
876
|
+
import React, { memo } from 'react';
|
|
877
|
+
import { useLocalStore } from 'state-decorator';
|
|
878
|
+
|
|
879
|
+
// Declare typings & actions as above
|
|
880
|
+
|
|
881
|
+
// Create and bind to react component
|
|
882
|
+
// Each time the store state changes, a re-render is done.
|
|
883
|
+
export function Container(props: Props) {
|
|
884
|
+
const { state, actions } = useLocalStore(getInitialState, userAppActions, props);
|
|
885
|
+
return (
|
|
886
|
+
<div>
|
|
887
|
+
<Title text={state.title} />
|
|
888
|
+
<Subtitle text={state.subtitle} />
|
|
889
|
+
</div>
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Simple presentation components
|
|
894
|
+
// Use memo to prevent re-render if another part of the state has changed than "title"
|
|
895
|
+
const Title = memo(function Title(props: { title: string }) {
|
|
896
|
+
return <div>{props.title}</div>;
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
const Subtitle = memo(function Subtitle(props: { subtitle: string }) {
|
|
900
|
+
return <div>{props.subtitle}</div>;
|
|
901
|
+
});
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
## State slices
|
|
905
|
+
|
|
906
|
+
Using React props implies useless re-renders and optionally memoization.
|
|
907
|
+
|
|
908
|
+
To prevent this, React provides [context](https://en.reactjs.org/docs/context.html) hooks.
|
|
909
|
+
|
|
910
|
+
The problem is that if the context contains a complex state with lots of props, if **any** of these props is changing, **all** components that uses this context will be re-rendered.
|
|
911
|
+
|
|
912
|
+
To overcome this problem, the StateDecorator provides a **useStoreSlice** and **useStoreContextSlice** hook that allow to define and extracts a slice of the state and trigger a re-render of the React component only if the slice has changed.
|
|
913
|
+
|
|
914
|
+
[](https://codesandbox.io/s/slices-v6-eg471?file=/src/SliceView.tsx)
|
|
915
|
+
|
|
916
|
+
## Global Store
|
|
917
|
+
|
|
918
|
+
```typescript
|
|
919
|
+
// Declare typings & actions as above
|
|
920
|
+
|
|
921
|
+
// Create a store in a dedicated file, named GlobalStore.ts for example
|
|
922
|
+
export const store = createStore(getInitialState, userAppActions);
|
|
923
|
+
|
|
924
|
+
//----------------------
|
|
925
|
+
|
|
926
|
+
import React, { memo } from 'react';
|
|
927
|
+
import { useStoreSlice } from 'state-decorator';
|
|
928
|
+
import store from './GlobalStore';
|
|
929
|
+
|
|
930
|
+
export function Container(props: Props) {
|
|
931
|
+
return (
|
|
932
|
+
<div>
|
|
933
|
+
<Title />
|
|
934
|
+
<Subtitle />
|
|
935
|
+
</div>
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
function Title() {
|
|
940
|
+
// extracts the "title" slice
|
|
941
|
+
// component is refresh only if title is changed in the store
|
|
942
|
+
const { title } = useStoreSlice(store, ['title']);
|
|
943
|
+
return <div>{title}</div>;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
function Subtitle(props: { subtitle: string }) {
|
|
947
|
+
const { subtitle } = useStoreSlice(store, ['subtitle']);
|
|
948
|
+
return <div>{subtitle}</div>;
|
|
949
|
+
}
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
## Local Store
|
|
953
|
+
|
|
954
|
+
```typescript
|
|
955
|
+
// ------- stores/MyStore.ts --------
|
|
956
|
+
|
|
957
|
+
import React from 'react';
|
|
958
|
+
import { useLocalStore, useStoreContextSlice } from 'state-decorator';
|
|
959
|
+
|
|
960
|
+
// Declare typings & actions as above
|
|
961
|
+
|
|
962
|
+
// Create a store context
|
|
963
|
+
|
|
964
|
+
type StoreContextProps = StoreApi<State, Actions, Props>;
|
|
965
|
+
|
|
966
|
+
export const StoreContext = createContext<StoreContextProps>(null);
|
|
967
|
+
|
|
968
|
+
// The StoreContext will allow to access to the store
|
|
969
|
+
// But this context is NOT refreshed if the store state is changed
|
|
970
|
+
export function StoreContextProvider(p: { children: any; propIn: string }) {
|
|
971
|
+
const { children, ...props } = p;
|
|
972
|
+
const store = useLocalStore(getInitialState, actionsImpl, props);
|
|
973
|
+
return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// In a container file ------------------------
|
|
977
|
+
|
|
978
|
+
import { StoreContextProvider } from 'stores/MyStore';
|
|
979
|
+
|
|
980
|
+
// If Container is destroyed store is destroyed
|
|
981
|
+
export function Container(props: Props) {
|
|
982
|
+
return (
|
|
983
|
+
<StoreContextProvider {...props}>
|
|
984
|
+
<SubComponent />
|
|
985
|
+
<SubComponent2 />
|
|
986
|
+
</StoreContextProvider>
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// Component deeper in the component tree...
|
|
991
|
+
|
|
992
|
+
import { StoreContext } from 'stores/MyStore';
|
|
993
|
+
|
|
994
|
+
function Title() {
|
|
995
|
+
// extracts the "title" slice
|
|
996
|
+
// component is refresh only if title is changed in the store
|
|
997
|
+
const { title } = useStoreContextSlice(StoreContext, ['title']);
|
|
998
|
+
|
|
999
|
+
// same as
|
|
1000
|
+
// const store = useContext(StoreContext)
|
|
1001
|
+
// const { title } = useStoreSlice(store, ['title']);
|
|
1002
|
+
|
|
1003
|
+
return <div>{title}</div>;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function Subtitle(props: { subtitle: string }) {
|
|
1007
|
+
const { subtitle } = useStoreContextSlice(StoreContext, ['subtitle']);
|
|
1008
|
+
return <div>{subtitle}</div>;
|
|
1009
|
+
}
|
|
1010
|
+
```
|
|
1011
|
+
|
|
779
1012
|
# Derived state
|
|
780
1013
|
|
|
781
1014
|
A derived state is a state that can be deduced from state and props.
|
|
@@ -831,6 +1064,32 @@ export function App(props: Props) {
|
|
|
831
1064
|
- In general, do **not** compute derived values directly in state, it's error prone as you can forget some places or implement different logic.
|
|
832
1065
|
- Use derived state especially if this state is shared accross several sub components
|
|
833
1066
|
|
|
1067
|
+
# Global configuration
|
|
1068
|
+
|
|
1069
|
+
Overrides configuration to set properties that will be used by all stores.
|
|
1070
|
+
|
|
1071
|
+
```typescript
|
|
1072
|
+
// all parameters are optional
|
|
1073
|
+
setGlobalConfig({
|
|
1074
|
+
// Used to clone state and props when managing optimistic conflicting actions.
|
|
1075
|
+
clone: defaultCloneFunc,
|
|
1076
|
+
// Compare to objets and returns if they are equal (slices).
|
|
1077
|
+
comparator: shallow,
|
|
1078
|
+
// Callback function to handle asychronous actions rejected promise (error reporting).
|
|
1079
|
+
asyncErrorHandler: () => {},
|
|
1080
|
+
// Tests if the error will trigger a retry of the action or will fail directly (retry promises)
|
|
1081
|
+
retryOnErrorFunction: (error: Error) => error instanceof TypeError,
|
|
1082
|
+
// Notification function on successful asynchronous action (if success message is set on action)
|
|
1083
|
+
notifySuccess: undefined,
|
|
1084
|
+
// Notification function on failed asynchronous action (if error message is set on action)
|
|
1085
|
+
notifyError: undefined,
|
|
1086
|
+
// Notification function injected in side effects action context (success and error) to notify warning
|
|
1087
|
+
notifyWarning: undefined,
|
|
1088
|
+
// Function called to return common error message if error message is not provided or error not managed in action. To override locally in action, provide a function that returns _null_.
|
|
1089
|
+
getErrorMessage: undefined,
|
|
1090
|
+
});
|
|
1091
|
+
```
|
|
1092
|
+
|
|
834
1093
|
# Debug actions
|
|
835
1094
|
|
|
836
1095
|
To debug actions, add a middleware to the store.
|
|
@@ -862,7 +1121,7 @@ Example:
|
|
|
862
1121
|
|
|
863
1122
|
```
|
|
864
1123
|
[StateDecorator sample] loadList effects {list: Array(10), prop1: "", prop2: "", prop3: ""} loading: false
|
|
865
|
-
|
|
1124
|
+
[StateDecorator sample] setProp1 effects {list: Array(10), prop1: "92", prop2: "", prop3: ""}
|
|
866
1125
|
```
|
|
867
1126
|
|
|
868
1127
|
## Detailed Logger
|
|
@@ -914,11 +1173,11 @@ function Container(props: Props) {
|
|
|
914
1173
|
- a new store is created each time state or props are set.
|
|
915
1174
|
- it allows to share mock store across tests.
|
|
916
1175
|
- The API is chainable: functions are returning a mock store, excepting test functions.
|
|
917
|
-
- On a mock store, we can test the store internals after initialiation, after inbound props have changed, after actions are called.
|
|
1176
|
+
- On a mock store, we can test the store internals after initialiation, after inbound props have changed, after actions are called. These test function do not change the internal state of the mock store.
|
|
918
1177
|
|
|
919
1178
|
## Getting started
|
|
920
1179
|
|
|
921
|
-
1. Create and setup a mock store (_createMockFromStore_)
|
|
1180
|
+
1. Create and setup a mock store (_createMockFromStore_, _createMockStore_)
|
|
922
1181
|
2. Test store after initialization (_onInit_)
|
|
923
1182
|
3. Test store after props changes (_onPropsChange_)
|
|
924
1183
|
4. Test each action:
|
package/es/helpers.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effect function that sets the first action argument to the specified prop.
|
|
3
|
+
*/
|
|
4
|
+
export declare function setArgIn<S, K extends keyof S>(propName: K): (ctx: {
|
|
5
|
+
s: S;
|
|
6
|
+
args: [S[K]];
|
|
7
|
+
}) => Partial<S>;
|
|
8
|
+
/**
|
|
9
|
+
* Effect function that sets <code>true</code> in the specified prop.
|
|
10
|
+
*/
|
|
11
|
+
export declare function setTrueIn<S, K extends keyof S>(propName: K): (ctx: {
|
|
12
|
+
s: S;
|
|
13
|
+
}) => Partial<S>;
|
|
14
|
+
/**
|
|
15
|
+
* Effect function that sets <code>false</code> in the specified prop.
|
|
16
|
+
*/
|
|
17
|
+
export declare function setFalseIn<S, K extends keyof S>(propName: K): (ctx: {
|
|
18
|
+
s: S;
|
|
19
|
+
}) => Partial<S>;
|
|
20
|
+
/**
|
|
21
|
+
* Effect function that sets toggles the boolean value of the specified prop.
|
|
22
|
+
*/
|
|
23
|
+
export declare function toggleProp<S, K extends keyof S>(propName: K): (ctx: {
|
|
24
|
+
s: S;
|
|
25
|
+
}) => Partial<S>;
|
|
26
|
+
/**
|
|
27
|
+
* Effect function that sets the update the specifed prop as an array using first action argument as index
|
|
28
|
+
* and second as value to set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function setMapItem<S, K extends keyof S, T>(propName: K): (ctx: {
|
|
31
|
+
s: S;
|
|
32
|
+
args: [string, T];
|
|
33
|
+
}) => Partial<S>;
|
|
34
|
+
/**
|
|
35
|
+
* Effect function that sets the update the specifed prop as an array using first action argument as index
|
|
36
|
+
* and second as value to set.
|
|
37
|
+
*/
|
|
38
|
+
export declare function setArrayItem<S, K extends keyof S, T>(propName: K): (ctx: {
|
|
39
|
+
s: S;
|
|
40
|
+
args: [number, T];
|
|
41
|
+
}) => Partial<S>;
|
|
42
|
+
/**
|
|
43
|
+
* Effect function that sets the asynchronous action result to the specified prop.
|
|
44
|
+
*/
|
|
45
|
+
export declare function setResIn<S, K extends keyof S>(propName: K): (ctx: {
|
|
46
|
+
s: S;
|
|
47
|
+
res: S[K];
|
|
48
|
+
}) => Partial<S>;
|
package/es/helpers.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var n=function(){return(n=Object.assign||function(n){for(var r,t=1,u=arguments.length;t<u;t++)for(var e in r=arguments[t])Object.prototype.hasOwnProperty.call(r,e)&&(n[e]=r[e]);return n}).apply(this,arguments)};function r(n){return function(r){var t,u=r.s,e=r.args[0];return u[n]===e?null:((t={})[n]=e,t)}}function t(n){return function(r){var t;return r.s[n]?null:((t={})[n]=!0,t)}}function u(n){return function(r){var t;return r.s[n]?((t={})[n]=!1,t):null}}function e(n){return function(r){var t,u=r.s;return(t={})[n]=!u[n],t}}function o(r){return function(t){var u,e,o=t.s,c=t.args,i=c[0],a=c[1];return(u={})[r]=n(n({},o[r]),((e={})[i]=a,e)),u}}function c(n){return function(r){var t,u=r.s,e=r.args,o=e[0],c=e[1],i=function(n,r,t){if(t||2===arguments.length)for(var u,e=0,o=r.length;e<o;e++)!u&&e in r||(u||(u=Array.prototype.slice.call(r,0,e)),u[e]=r[e]);return n.concat(u||Array.prototype.slice.call(r))}([],u[n],!0);return i[o]=c,(t={})[n]=i,t}}function i(n){return function(r){var t,u=r.res;return(t={})[n]=u,t}}export{r as setArgIn,c as setArrayItem,u as setFalseIn,o as setMapItem,i as setResIn,t as setTrueIn,e as toggleProp};
|
|
2
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../../node_modules/tslib/tslib.es6.js"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","this","to","from","pack","ar","l","Array","slice","concat"],"mappings":"AA+BO,IAAIA,EAAW,WAQlB,OAPAA,EAAWC,OAAOC,QAAU,SAAkBC,GAC1C,IAAK,IAAIC,EAAGC,EAAI,EAAGC,EAAIC,UAAUC,OAAQH,EAAIC,EAAGD,IAE5C,IAAK,IAAII,KADTL,EAAIG,UAAUF,GACOJ,OAAOS,UAAUC,eAAeC,KAAKR,EAAGK,KAAIN,EAAEM,GAAKL,EAAEK,IAE9E,OAAON,IAEKU,MAAMC,KAAMP,sgBA6HzB,SAAuBQ,EAAIC,EAAMC,GACpC,GAAIA,GAA6B,IAArBV,UAAUC,OAAc,IAAK,IAA4BU,EAAxBb,EAAI,EAAGc,EAAIH,EAAKR,OAAYH,EAAIc,EAAGd,KACxEa,GAAQb,KAAKW,IACRE,IAAIA,EAAKE,MAAMV,UAAUW,MAAMT,KAAKI,EAAM,EAAGX,IAClDa,EAAGb,GAAKW,EAAKX,IAGrB,OAAOU,EAAGO,OAAOJ,GAAME,MAAMV,UAAUW,MAAMT,KAAKI"}
|
package/es/impl.d.ts
CHANGED
|
@@ -188,7 +188,7 @@ export declare function areSameArgs(args1: any[], args2: any[]): boolean;
|
|
|
188
188
|
/** @internal */
|
|
189
189
|
export declare function computeDerivedValues<S, A, P, DS>(s: Ref<S>, p: Ref<P>, derivedStateRef: Ref<DerivedState<DS>>, options: StoreOptions<S, A, P, DS>): boolean;
|
|
190
190
|
/** @internal */
|
|
191
|
-
export declare function onPropChange<S, P, A, DS>(stateRef: Ref<S>, derivedStateRef: Ref<DerivedState<DS>>, propsRef: Ref<P>, oldProps: P, actionsRef: Ref<A>, options: StoreOptions<S, A, P, DS>, setState: SetStateFunc<S, A>, isInit: boolean): void;
|
|
191
|
+
export declare function onPropChange<S, P, A, DS>(stateRef: Ref<S>, derivedStateRef: Ref<DerivedState<DS>>, propsRef: Ref<P>, oldProps: P, actionsRef: Ref<A>, options: StoreOptions<S, A, P, DS>, setState: SetStateFunc<S, A>, isInit: boolean, isDeferred: boolean): void;
|
|
192
192
|
/** @internal */
|
|
193
193
|
export declare function runMiddlewares<S, A extends DecoratedActions, P>(middlewares: Middleware<S, A, P>[], oldState: S, newState: S, loading: boolean, actionName: keyof A, actionType: 'preEffects' | 'effects' | 'errorEffects' | null, isAsync: boolean, actionCtx: any): {
|
|
194
194
|
newState: S;
|