@wordpress/data 8.6.0 → 9.1.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/CHANGELOG.md +8 -0
- package/README.md +28 -65
- package/build/components/use-select/index.js +90 -55
- package/build/components/use-select/index.js.map +1 -1
- package/build/registry.js +16 -7
- package/build/registry.js.map +1 -1
- package/build-module/components/use-select/index.js +90 -55
- package/build-module/components/use-select/index.js.map +1 -1
- package/build-module/registry.js +16 -7
- package/build-module/registry.js.map +1 -1
- package/build-types/components/use-select/index.d.ts.map +1 -1
- package/build-types/registry.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/components/use-select/index.js +87 -57
- package/src/components/use-select/test/index.js +247 -163
- package/src/registry.js +20 -8
- package/src/test/registry.js +31 -22
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 9.1.0 (2023-04-12)
|
|
6
|
+
|
|
7
|
+
## 9.0.0 (2023-03-29)
|
|
8
|
+
|
|
9
|
+
### Breaking Changes
|
|
10
|
+
|
|
11
|
+
- The `registry.register` function will no longer register a store if another instance is registered with the same name.
|
|
12
|
+
|
|
5
13
|
## 8.6.0 (2023-03-15)
|
|
6
14
|
|
|
7
15
|
## 8.5.0 (2023-03-01)
|
package/README.md
CHANGED
|
@@ -279,8 +279,7 @@ Specific implementation differences from Redux and React Redux:
|
|
|
279
279
|
|
|
280
280
|
### AsyncModeProvider
|
|
281
281
|
|
|
282
|
-
Context Provider Component used to switch the data module component rerendering
|
|
283
|
-
between Sync and Async modes.
|
|
282
|
+
Context Provider Component used to switch the data module component rerendering between Sync and Async modes.
|
|
284
283
|
|
|
285
284
|
_Usage_
|
|
286
285
|
|
|
@@ -320,8 +319,7 @@ _Returns_
|
|
|
320
319
|
|
|
321
320
|
### combineReducers
|
|
322
321
|
|
|
323
|
-
The combineReducers helper function turns an object whose values are different
|
|
324
|
-
reducing functions into a single reducing function you can pass to registerReducer.
|
|
322
|
+
The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to registerReducer.
|
|
325
323
|
|
|
326
324
|
_Usage_
|
|
327
325
|
|
|
@@ -368,8 +366,7 @@ Undocumented declaration.
|
|
|
368
366
|
|
|
369
367
|
### createReduxStore
|
|
370
368
|
|
|
371
|
-
Creates a data store descriptor for the provided Redux store configuration containing
|
|
372
|
-
properties describing reducer, actions, selectors, controls and resolvers.
|
|
369
|
+
Creates a data store descriptor for the provided Redux store configuration containing properties describing reducer, actions, selectors, controls and resolvers.
|
|
373
370
|
|
|
374
371
|
_Usage_
|
|
375
372
|
|
|
@@ -395,8 +392,7 @@ _Returns_
|
|
|
395
392
|
|
|
396
393
|
### createRegistry
|
|
397
394
|
|
|
398
|
-
Creates a new store registry, given an optional object of initial store
|
|
399
|
-
configurations.
|
|
395
|
+
Creates a new store registry, given an optional object of initial store configurations.
|
|
400
396
|
|
|
401
397
|
_Parameters_
|
|
402
398
|
|
|
@@ -409,8 +405,7 @@ _Returns_
|
|
|
409
405
|
|
|
410
406
|
### createRegistryControl
|
|
411
407
|
|
|
412
|
-
Creates a control function that takes additional curried argument with the `registry` object.
|
|
413
|
-
While a regular control has signature
|
|
408
|
+
Creates a control function that takes additional curried argument with the `registry` object. While a regular control has signature
|
|
414
409
|
|
|
415
410
|
```js
|
|
416
411
|
( action ) => iteratorOrPromise;
|
|
@@ -422,11 +417,9 @@ where the control works with the `action` that it's bound to, a registry control
|
|
|
422
417
|
( registry ) => ( action ) => iteratorOrPromise;
|
|
423
418
|
```
|
|
424
419
|
|
|
425
|
-
A registry control is typically used to select data or dispatch an action to a registered
|
|
426
|
-
store.
|
|
420
|
+
A registry control is typically used to select data or dispatch an action to a registered store.
|
|
427
421
|
|
|
428
|
-
When registering a control created with `createRegistryControl` with a store, the store
|
|
429
|
-
knows which calling convention to use when executing the control.
|
|
422
|
+
When registering a control created with `createRegistryControl` with a store, the store knows which calling convention to use when executing the control.
|
|
430
423
|
|
|
431
424
|
_Parameters_
|
|
432
425
|
|
|
@@ -438,15 +431,13 @@ _Returns_
|
|
|
438
431
|
|
|
439
432
|
### createRegistrySelector
|
|
440
433
|
|
|
441
|
-
Creates a selector function that takes additional curried argument with the
|
|
442
|
-
registry `select` function. While a regular selector has signature
|
|
434
|
+
Creates a selector function that takes additional curried argument with the registry `select` function. While a regular selector has signature
|
|
443
435
|
|
|
444
436
|
```js
|
|
445
437
|
( state, ...selectorArgs ) => result;
|
|
446
438
|
```
|
|
447
439
|
|
|
448
|
-
that allows to select data from the store's `state`, a registry selector
|
|
449
|
-
has signature:
|
|
440
|
+
that allows to select data from the store's `state`, a registry selector has signature:
|
|
450
441
|
|
|
451
442
|
```js
|
|
452
443
|
( select ) =>
|
|
@@ -493,11 +484,9 @@ _Returns_
|
|
|
493
484
|
|
|
494
485
|
### dispatch
|
|
495
486
|
|
|
496
|
-
Given a store descriptor, returns an object of the store's action creators.
|
|
497
|
-
Calling an action creator will cause it to be dispatched, updating the state value accordingly.
|
|
487
|
+
Given a store descriptor, returns an object of the store's action creators. Calling an action creator will cause it to be dispatched, updating the state value accordingly.
|
|
498
488
|
|
|
499
|
-
Note: Action creators returned by the dispatch will return a promise when
|
|
500
|
-
they are called.
|
|
489
|
+
Note: Action creators returned by the dispatch will return a promise when they are called.
|
|
501
490
|
|
|
502
491
|
_Usage_
|
|
503
492
|
|
|
@@ -578,11 +567,9 @@ _Returns_
|
|
|
578
567
|
|
|
579
568
|
### RegistryConsumer
|
|
580
569
|
|
|
581
|
-
A custom react Context consumer exposing the provided `registry` to
|
|
582
|
-
children components. Used along with the RegistryProvider.
|
|
570
|
+
A custom react Context consumer exposing the provided `registry` to children components. Used along with the RegistryProvider.
|
|
583
571
|
|
|
584
|
-
You can read more about the react context api here:
|
|
585
|
-
<https://reactjs.org/docs/context.html#contextprovider>
|
|
572
|
+
You can read more about the react context api here: <https://reactjs.org/docs/context.html#contextprovider>
|
|
586
573
|
|
|
587
574
|
_Usage_
|
|
588
575
|
|
|
@@ -611,17 +598,13 @@ const App = ( { props } ) => {
|
|
|
611
598
|
|
|
612
599
|
### RegistryProvider
|
|
613
600
|
|
|
614
|
-
A custom Context provider for exposing the provided `registry` to children
|
|
615
|
-
components via a consumer.
|
|
601
|
+
A custom Context provider for exposing the provided `registry` to children components via a consumer.
|
|
616
602
|
|
|
617
|
-
See <a name="#RegistryConsumer">RegistryConsumer</a> documentation for
|
|
618
|
-
example.
|
|
603
|
+
See <a name="#RegistryConsumer">RegistryConsumer</a> documentation for example.
|
|
619
604
|
|
|
620
605
|
### resolveSelect
|
|
621
606
|
|
|
622
|
-
Given a store descriptor, returns an object containing the store's selectors pre-bound to state
|
|
623
|
-
so that you only need to supply additional arguments, and modified so that they return promises
|
|
624
|
-
that resolve to their eventual values, after any resolvers have ran.
|
|
607
|
+
Given a store descriptor, returns an object containing the store's selectors pre-bound to state so that you only need to supply additional arguments, and modified so that they return promises that resolve to their eventual values, after any resolvers have ran.
|
|
625
608
|
|
|
626
609
|
_Usage_
|
|
627
610
|
|
|
@@ -642,9 +625,7 @@ _Returns_
|
|
|
642
625
|
|
|
643
626
|
### select
|
|
644
627
|
|
|
645
|
-
Given a store descriptor, returns an object of the store's selectors.
|
|
646
|
-
The selector functions are been pre-bound to pass the current state automatically.
|
|
647
|
-
As a consumer, you need only pass arguments of the selector, if applicable.
|
|
628
|
+
Given a store descriptor, returns an object of the store's selectors. The selector functions are been pre-bound to pass the current state automatically. As a consumer, you need only pass arguments of the selector, if applicable.
|
|
648
629
|
|
|
649
630
|
_Usage_
|
|
650
631
|
|
|
@@ -665,10 +646,7 @@ _Returns_
|
|
|
665
646
|
|
|
666
647
|
### subscribe
|
|
667
648
|
|
|
668
|
-
Given a listener function, the function will be called any time the state value
|
|
669
|
-
of one of the registered stores has changed. If you specify the optional
|
|
670
|
-
`storeNameOrDescriptor` parameter, the listener function will be called only
|
|
671
|
-
on updates on that one specific registered store.
|
|
649
|
+
Given a listener function, the function will be called any time the state value of one of the registered stores has changed. If you specify the optional `storeNameOrDescriptor` parameter, the listener function will be called only on updates on that one specific registered store.
|
|
672
650
|
|
|
673
651
|
This function returns an `unsubscribe` function used to stop the subscription.
|
|
674
652
|
|
|
@@ -693,9 +671,7 @@ _Parameters_
|
|
|
693
671
|
|
|
694
672
|
### suspendSelect
|
|
695
673
|
|
|
696
|
-
Given a store descriptor, returns an object containing the store's selectors pre-bound to state
|
|
697
|
-
so that you only need to supply additional arguments, and modified so that they throw promises
|
|
698
|
-
in case the selector is not resolved yet.
|
|
674
|
+
Given a store descriptor, returns an object containing the store's selectors pre-bound to state so that you only need to supply additional arguments, and modified so that they throw promises in case the selector is not resolved yet.
|
|
699
675
|
|
|
700
676
|
_Parameters_
|
|
701
677
|
|
|
@@ -707,9 +683,7 @@ _Returns_
|
|
|
707
683
|
|
|
708
684
|
### use
|
|
709
685
|
|
|
710
|
-
Extends a registry to inherit functionality provided by a given plugin. A
|
|
711
|
-
plugin is an object with properties aligning to that of a registry, merged
|
|
712
|
-
to extend the default registry behavior.
|
|
686
|
+
Extends a registry to inherit functionality provided by a given plugin. A plugin is an object with properties aligning to that of a registry, merged to extend the default registry behavior.
|
|
713
687
|
|
|
714
688
|
_Parameters_
|
|
715
689
|
|
|
@@ -719,8 +693,7 @@ _Parameters_
|
|
|
719
693
|
|
|
720
694
|
A custom react hook returning the current registry dispatch actions creators.
|
|
721
695
|
|
|
722
|
-
Note: The component using this hook must be within the context of a
|
|
723
|
-
RegistryProvider.
|
|
696
|
+
Note: The component using this hook must be within the context of a RegistryProvider.
|
|
724
697
|
|
|
725
698
|
_Usage_
|
|
726
699
|
|
|
@@ -771,16 +744,11 @@ _Returns_
|
|
|
771
744
|
|
|
772
745
|
A custom react hook exposing the registry context for use.
|
|
773
746
|
|
|
774
|
-
This exposes the `registry` value provided via the
|
|
775
|
-
<a href="#RegistryProvider">Registry Provider</a> to a component implementing
|
|
776
|
-
this hook.
|
|
747
|
+
This exposes the `registry` value provided via the <a href="#RegistryProvider">Registry Provider</a> to a component implementing this hook.
|
|
777
748
|
|
|
778
749
|
It acts similarly to the `useContext` react hook.
|
|
779
750
|
|
|
780
|
-
Note: Generally speaking, `useRegistry` is a low level hook that in most cases
|
|
781
|
-
won't be needed for implementation. Most interactions with the `@wordpress/data`
|
|
782
|
-
API can be performed via the `useSelect` hook, or the `withSelect` and
|
|
783
|
-
`withDispatch` higher order components.
|
|
751
|
+
Note: Generally speaking, `useRegistry` is a low level hook that in most cases won't be needed for implementation. Most interactions with the `@wordpress/data` API can be performed via the `useSelect` hook, or the `withSelect` and `withDispatch` higher order components.
|
|
784
752
|
|
|
785
753
|
_Usage_
|
|
786
754
|
|
|
@@ -811,8 +779,7 @@ _Returns_
|
|
|
811
779
|
|
|
812
780
|
Custom react hook for retrieving props from registered selectors.
|
|
813
781
|
|
|
814
|
-
In general, this custom React hook follows the
|
|
815
|
-
[rules of hooks](https://reactjs.org/docs/hooks-rules.html).
|
|
782
|
+
In general, this custom React hook follows the [rules of hooks](https://reactjs.org/docs/hooks-rules.html).
|
|
816
783
|
|
|
817
784
|
_Usage_
|
|
818
785
|
|
|
@@ -875,8 +842,7 @@ _Returns_
|
|
|
875
842
|
|
|
876
843
|
### useSuspenseSelect
|
|
877
844
|
|
|
878
|
-
A variant of the `useSelect` hook that has the same API, but will throw a
|
|
879
|
-
suspense Promise if any of the called selectors is in an unresolved state.
|
|
845
|
+
A variant of the `useSelect` hook that has the same API, but will throw a suspense Promise if any of the called selectors is in an unresolved state.
|
|
880
846
|
|
|
881
847
|
_Parameters_
|
|
882
848
|
|
|
@@ -889,8 +855,7 @@ _Returns_
|
|
|
889
855
|
|
|
890
856
|
### withDispatch
|
|
891
857
|
|
|
892
|
-
Higher-order component used to add dispatch props using registered action
|
|
893
|
-
creators.
|
|
858
|
+
Higher-order component used to add dispatch props using registered action creators.
|
|
894
859
|
|
|
895
860
|
_Usage_
|
|
896
861
|
|
|
@@ -978,8 +943,7 @@ _Returns_
|
|
|
978
943
|
|
|
979
944
|
### withRegistry
|
|
980
945
|
|
|
981
|
-
Higher-order component which renders the original component with the current
|
|
982
|
-
registry context passed as its `registry` prop.
|
|
946
|
+
Higher-order component which renders the original component with the current registry context passed as its `registry` prop.
|
|
983
947
|
|
|
984
948
|
_Parameters_
|
|
985
949
|
|
|
@@ -991,8 +955,7 @@ _Returns_
|
|
|
991
955
|
|
|
992
956
|
### withSelect
|
|
993
957
|
|
|
994
|
-
Higher-order component used to inject state-derived props using registered
|
|
995
|
-
selectors.
|
|
958
|
+
Higher-order component used to inject state-derived props using registered selectors.
|
|
996
959
|
|
|
997
960
|
_Usage_
|
|
998
961
|
|
|
@@ -52,48 +52,87 @@ function Store(registry, suspense) {
|
|
|
52
52
|
let lastMapResult;
|
|
53
53
|
let lastMapResultValid = false;
|
|
54
54
|
let lastIsAsync;
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
const createSubscriber = stores =>
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
let subscriber;
|
|
56
|
+
|
|
57
|
+
const createSubscriber = stores => {
|
|
58
|
+
// The set of stores the `subscribe` function is supposed to subscribe to. Here it is
|
|
59
|
+
// initialized, and then the `updateStores` function can add new stores to it.
|
|
60
|
+
const activeStores = [...stores]; // The `subscribe` function, which is passed to the `useSyncExternalStore` hook, could
|
|
61
|
+
// be called multiple times to establish multiple subscriptions. That's why we need to
|
|
62
|
+
// keep a set of active subscriptions;
|
|
63
|
+
|
|
64
|
+
const activeSubscriptions = new Set();
|
|
65
|
+
|
|
66
|
+
function subscribe(listener) {
|
|
67
|
+
// Invalidate the value right after subscription was created. React will
|
|
68
|
+
// call `getValue` after subscribing, to detect store updates that happened
|
|
69
|
+
// in the interval between the `getValue` call during render and creating
|
|
70
|
+
// the subscription, which is slightly delayed. We need to ensure that this
|
|
71
|
+
// second `getValue` call will compute a fresh value.
|
|
67
72
|
lastMapResultValid = false;
|
|
68
|
-
listener();
|
|
69
|
-
};
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const onStoreChange = () => {
|
|
75
|
+
// Invalidate the value on store update, so that a fresh value is computed.
|
|
76
|
+
lastMapResultValid = false;
|
|
77
|
+
listener();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const onChange = () => {
|
|
81
|
+
if (lastIsAsync) {
|
|
82
|
+
renderQueue.add(queueContext, onStoreChange);
|
|
83
|
+
} else {
|
|
84
|
+
onStoreChange();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const unsubs = [];
|
|
89
|
+
|
|
90
|
+
function subscribeStore(storeName) {
|
|
91
|
+
unsubs.push(registry.subscribe(onChange, storeName));
|
|
76
92
|
}
|
|
77
|
-
};
|
|
78
93
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return () => {
|
|
83
|
-
// The return value of the subscribe function could be undefined if the store is a custom generic store.
|
|
84
|
-
for (const unsub of unsubs) {
|
|
85
|
-
unsub === null || unsub === void 0 ? void 0 : unsub();
|
|
86
|
-
} // Cancel existing store updates that were already scheduled.
|
|
94
|
+
for (const storeName of activeStores) {
|
|
95
|
+
subscribeStore(storeName);
|
|
96
|
+
}
|
|
87
97
|
|
|
98
|
+
activeSubscriptions.add(subscribeStore);
|
|
99
|
+
return () => {
|
|
100
|
+
activeSubscriptions.delete(subscribeStore);
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
for (const unsub of unsubs.values()) {
|
|
103
|
+
// The return value of the subscribe function could be undefined if the store is a custom generic store.
|
|
104
|
+
unsub === null || unsub === void 0 ? void 0 : unsub();
|
|
105
|
+
} // Cancel existing store updates that were already scheduled.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
renderQueue.cancel(queueContext);
|
|
109
|
+
};
|
|
110
|
+
} // Check if `newStores` contains some stores we're not subscribed to yet, and add them.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
function updateStores(newStores) {
|
|
114
|
+
for (const newStore of newStores) {
|
|
115
|
+
if (activeStores.includes(newStore)) {
|
|
116
|
+
continue;
|
|
117
|
+
} // New `subscribe` calls will subscribe to `newStore`, too.
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
activeStores.push(newStore); // Add `newStore` to existing subscriptions.
|
|
121
|
+
|
|
122
|
+
for (const subscription of activeSubscriptions) {
|
|
123
|
+
subscription(newStore);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
subscribe,
|
|
130
|
+
updateStores
|
|
90
131
|
};
|
|
91
132
|
};
|
|
92
133
|
|
|
93
|
-
return (mapSelect,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
function updateValue(selectFromStore) {
|
|
134
|
+
return (mapSelect, isAsync) => {
|
|
135
|
+
function updateValue() {
|
|
97
136
|
// If the last value is valid, and the `mapSelect` callback hasn't changed,
|
|
98
137
|
// then we can safely return the cached value. The value can change only on
|
|
99
138
|
// store update, and in that case value will be invalidated by the listener.
|
|
@@ -101,19 +140,31 @@ function Store(registry, suspense) {
|
|
|
101
140
|
return lastMapResult;
|
|
102
141
|
}
|
|
103
142
|
|
|
104
|
-
const
|
|
143
|
+
const listeningStores = {
|
|
144
|
+
current: null
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const mapResult = registry.__unstableMarkListeningStores(() => mapSelect(select, registry), listeningStores);
|
|
148
|
+
|
|
149
|
+
if (!subscriber) {
|
|
150
|
+
subscriber = createSubscriber(listeningStores.current);
|
|
151
|
+
} else {
|
|
152
|
+
subscriber.updateStores(listeningStores.current);
|
|
153
|
+
} // If the new value is shallow-equal to the old one, keep the old one so
|
|
105
154
|
// that we don't trigger unwanted updates that do a `===` check.
|
|
106
155
|
|
|
156
|
+
|
|
107
157
|
if (!(0, _isShallowEqual.default)(lastMapResult, mapResult)) {
|
|
108
158
|
lastMapResult = mapResult;
|
|
109
159
|
}
|
|
110
160
|
|
|
161
|
+
lastMapSelect = mapSelect;
|
|
111
162
|
lastMapResultValid = true;
|
|
112
163
|
}
|
|
113
164
|
|
|
114
165
|
function getValue() {
|
|
115
166
|
// Update the value in case it's been invalidated or `mapSelect` has changed.
|
|
116
|
-
updateValue(
|
|
167
|
+
updateValue();
|
|
117
168
|
return lastMapResult;
|
|
118
169
|
} // When transitioning from async to sync mode, cancel existing store updates
|
|
119
170
|
// that have been scheduled, and invalidate the value so that it's freshly
|
|
@@ -123,29 +174,13 @@ function Store(registry, suspense) {
|
|
|
123
174
|
if (lastIsAsync && !isAsync) {
|
|
124
175
|
lastMapResultValid = false;
|
|
125
176
|
renderQueue.cancel(queueContext);
|
|
126
|
-
} // Either initialize the `subscribe` function, or create a new one if `mapSelect`
|
|
127
|
-
// changed and has dependencies.
|
|
128
|
-
// Usage without dependencies, `useSelect( ( s ) => { ... } )`, will subscribe
|
|
129
|
-
// only once, at mount, and won't resubscibe even if `mapSelect` changes.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (!subscribe || resubscribe && mapSelect !== lastMapSelect) {
|
|
133
|
-
// Find out what stores the `mapSelect` callback is selecting from and
|
|
134
|
-
// use that list to create subscriptions to specific stores.
|
|
135
|
-
const listeningStores = {
|
|
136
|
-
current: null
|
|
137
|
-
};
|
|
138
|
-
updateValue(() => registry.__unstableMarkListeningStores(selectValue, listeningStores));
|
|
139
|
-
subscribe = createSubscriber(listeningStores.current);
|
|
140
|
-
} else {
|
|
141
|
-
updateValue(selectValue);
|
|
142
177
|
}
|
|
143
178
|
|
|
144
|
-
|
|
145
|
-
|
|
179
|
+
updateValue();
|
|
180
|
+
lastIsAsync = isAsync; // Return a pair of functions that can be passed to `useSyncExternalStore`.
|
|
146
181
|
|
|
147
182
|
return {
|
|
148
|
-
subscribe,
|
|
183
|
+
subscribe: subscriber.subscribe,
|
|
149
184
|
getValue
|
|
150
185
|
};
|
|
151
186
|
};
|
|
@@ -163,7 +198,7 @@ function useMappingSelect(suspense, mapSelect, deps) {
|
|
|
163
198
|
const {
|
|
164
199
|
subscribe,
|
|
165
200
|
getValue
|
|
166
|
-
} = store(selector,
|
|
201
|
+
} = store(selector, isAsync);
|
|
167
202
|
const result = (0, _element.useSyncExternalStore)(subscribe, getValue, getValue);
|
|
168
203
|
(0, _element.useDebugValue)(result);
|
|
169
204
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/data/src/components/use-select/index.js"],"names":["renderQueue","Store","registry","suspense","select","suspendSelect","queueContext","lastMapSelect","lastMapResult","lastMapResultValid","lastIsAsync","subscribe","createSubscriber","stores","listener","onStoreChange","onChange","add","unsubs","map","storeName","unsub","cancel","mapSelect","resubscribe","isAsync","selectValue","updateValue","selectFromStore","mapResult","getValue","listeningStores","current","__unstableMarkListeningStores","useStaticSelect","useMappingSelect","deps","store","selector","result","useSelect","staticSelectMode","staticSelectModeRef","prevMode","nextMode","Error","useSuspenseSelect"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createQueue } from '@wordpress/priority-queue';\nimport {\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n\tuseSyncExternalStore,\n\tuseDebugValue,\n} from '@wordpress/element';\nimport isShallowEqual from '@wordpress/is-shallow-equal';\n\n/**\n * Internal dependencies\n */\nimport useRegistry from '../registry-provider/use-registry';\nimport useAsyncMode from '../async-mode-provider/use-async-mode';\n\nconst renderQueue = createQueue();\n\n/**\n * @typedef {import('../../types').StoreDescriptor<C>} StoreDescriptor\n * @template {import('../../types').AnyConfig} C\n */\n/**\n * @typedef {import('../../types').ReduxStoreConfig<State,Actions,Selectors>} ReduxStoreConfig\n * @template State\n * @template {Record<string,import('../../types').ActionCreator>} Actions\n * @template Selectors\n */\n/** @typedef {import('../../types').MapSelect} MapSelect */\n/**\n * @typedef {import('../../types').UseSelectReturn<T>} UseSelectReturn\n * @template {MapSelect|StoreDescriptor<any>} T\n */\n\nfunction Store( registry, suspense ) {\n\tconst select = suspense ? registry.suspendSelect : registry.select;\n\tconst queueContext = {};\n\tlet lastMapSelect;\n\tlet lastMapResult;\n\tlet lastMapResultValid = false;\n\tlet lastIsAsync;\n\tlet subscribe;\n\n\tconst createSubscriber = ( stores ) => ( listener ) => {\n\t\t// Invalidate the value right after subscription was created. React will\n\t\t// call `getValue` after subscribing, to detect store updates that happened\n\t\t// in the interval between the `getValue` call during render and creating\n\t\t// the subscription, which is slightly delayed. We need to ensure that this\n\t\t// second `getValue` call will compute a fresh value.\n\t\tlastMapResultValid = false;\n\n\t\tconst onStoreChange = () => {\n\t\t\t// Invalidate the value on store update, so that a fresh value is computed.\n\t\t\tlastMapResultValid = false;\n\t\t\tlistener();\n\t\t};\n\n\t\tconst onChange = () => {\n\t\t\tif ( lastIsAsync ) {\n\t\t\t\trenderQueue.add( queueContext, onStoreChange );\n\t\t\t} else {\n\t\t\t\tonStoreChange();\n\t\t\t}\n\t\t};\n\n\t\tconst unsubs = stores.map( ( storeName ) => {\n\t\t\treturn registry.subscribe( onChange, storeName );\n\t\t} );\n\n\t\treturn () => {\n\t\t\t// The return value of the subscribe function could be undefined if the store is a custom generic store.\n\t\t\tfor ( const unsub of unsubs ) {\n\t\t\t\tunsub?.();\n\t\t\t}\n\t\t\t// Cancel existing store updates that were already scheduled.\n\t\t\trenderQueue.cancel( queueContext );\n\t\t};\n\t};\n\n\treturn ( mapSelect, resubscribe, isAsync ) => {\n\t\tconst selectValue = () => mapSelect( select, registry );\n\n\t\tfunction updateValue( selectFromStore ) {\n\t\t\t// If the last value is valid, and the `mapSelect` callback hasn't changed,\n\t\t\t// then we can safely return the cached value. The value can change only on\n\t\t\t// store update, and in that case value will be invalidated by the listener.\n\t\t\tif ( lastMapResultValid && mapSelect === lastMapSelect ) {\n\t\t\t\treturn lastMapResult;\n\t\t\t}\n\n\t\t\tconst mapResult = selectFromStore();\n\n\t\t\t// If the new value is shallow-equal to the old one, keep the old one so\n\t\t\t// that we don't trigger unwanted updates that do a `===` check.\n\t\t\tif ( ! isShallowEqual( lastMapResult, mapResult ) ) {\n\t\t\t\tlastMapResult = mapResult;\n\t\t\t}\n\t\t\tlastMapResultValid = true;\n\t\t}\n\n\t\tfunction getValue() {\n\t\t\t// Update the value in case it's been invalidated or `mapSelect` has changed.\n\t\t\tupdateValue( selectValue );\n\t\t\treturn lastMapResult;\n\t\t}\n\n\t\t// When transitioning from async to sync mode, cancel existing store updates\n\t\t// that have been scheduled, and invalidate the value so that it's freshly\n\t\t// computed. It might have been changed by the update we just cancelled.\n\t\tif ( lastIsAsync && ! isAsync ) {\n\t\t\tlastMapResultValid = false;\n\t\t\trenderQueue.cancel( queueContext );\n\t\t}\n\n\t\t// Either initialize the `subscribe` function, or create a new one if `mapSelect`\n\t\t// changed and has dependencies.\n\t\t// Usage without dependencies, `useSelect( ( s ) => { ... } )`, will subscribe\n\t\t// only once, at mount, and won't resubscibe even if `mapSelect` changes.\n\t\tif ( ! subscribe || ( resubscribe && mapSelect !== lastMapSelect ) ) {\n\t\t\t// Find out what stores the `mapSelect` callback is selecting from and\n\t\t\t// use that list to create subscriptions to specific stores.\n\t\t\tconst listeningStores = { current: null };\n\t\t\tupdateValue( () =>\n\t\t\t\tregistry.__unstableMarkListeningStores(\n\t\t\t\t\tselectValue,\n\t\t\t\t\tlisteningStores\n\t\t\t\t)\n\t\t\t);\n\t\t\tsubscribe = createSubscriber( listeningStores.current );\n\t\t} else {\n\t\t\tupdateValue( selectValue );\n\t\t}\n\n\t\tlastIsAsync = isAsync;\n\t\tlastMapSelect = mapSelect;\n\n\t\t// Return a pair of functions that can be passed to `useSyncExternalStore`.\n\t\treturn { subscribe, getValue };\n\t};\n}\n\nfunction useStaticSelect( storeName ) {\n\treturn useRegistry().select( storeName );\n}\n\nfunction useMappingSelect( suspense, mapSelect, deps ) {\n\tconst registry = useRegistry();\n\tconst isAsync = useAsyncMode();\n\tconst store = useMemo( () => Store( registry, suspense ), [ registry ] );\n\tconst selector = useCallback( mapSelect, deps );\n\tconst { subscribe, getValue } = store( selector, !! deps, isAsync );\n\tconst result = useSyncExternalStore( subscribe, getValue, getValue );\n\tuseDebugValue( result );\n\treturn result;\n}\n\n/**\n * Custom react hook for retrieving props from registered selectors.\n *\n * In general, this custom React hook follows the\n * [rules of hooks](https://reactjs.org/docs/hooks-rules.html).\n *\n * @template {MapSelect | StoreDescriptor<any>} T\n * @param {T} mapSelect Function called on every state change. The returned value is\n * exposed to the component implementing this hook. The function\n * receives the `registry.select` method on the first argument\n * and the `registry` on the second argument.\n * When a store key is passed, all selectors for the store will be\n * returned. This is only meant for usage of these selectors in event\n * callbacks, not for data needed to create the element tree.\n * @param {unknown[]} deps If provided, this memoizes the mapSelect so the same `mapSelect` is\n * invoked on every state change unless the dependencies change.\n *\n * @example\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function HammerPriceDisplay( { currency } ) {\n * const price = useSelect( ( select ) => {\n * return select( myCustomStore ).getPrice( 'hammer', currency );\n * }, [ currency ] );\n * return new Intl.NumberFormat( 'en-US', {\n * style: 'currency',\n * currency,\n * } ).format( price );\n * }\n *\n * // Rendered in the application:\n * // <HammerPriceDisplay currency=\"USD\" />\n * ```\n *\n * In the above example, when `HammerPriceDisplay` is rendered into an\n * application, the price will be retrieved from the store state using the\n * `mapSelect` callback on `useSelect`. If the currency prop changes then\n * any price in the state for that currency is retrieved. If the currency prop\n * doesn't change and other props are passed in that do change, the price will\n * not change because the dependency is just the currency.\n *\n * When data is only used in an event callback, the data should not be retrieved\n * on render, so it may be useful to get the selectors function instead.\n *\n * **Don't use `useSelect` this way when calling the selectors in the render\n * function because your component won't re-render on a data change.**\n *\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function Paste( { children } ) {\n * const { getSettings } = useSelect( myCustomStore );\n * function onPaste() {\n * // Do something with the settings.\n * const settings = getSettings();\n * }\n * return <div onPaste={ onPaste }>{ children }</div>;\n * }\n * ```\n * @return {UseSelectReturn<T>} A custom react hook.\n */\nexport default function useSelect( mapSelect, deps ) {\n\t// On initial call, on mount, determine the mode of this `useSelect` call\n\t// and then never allow it to change on subsequent updates.\n\tconst staticSelectMode = typeof mapSelect !== 'function';\n\tconst staticSelectModeRef = useRef( staticSelectMode );\n\n\tif ( staticSelectMode !== staticSelectModeRef.current ) {\n\t\tconst prevMode = staticSelectModeRef.current ? 'static' : 'mapping';\n\t\tconst nextMode = staticSelectMode ? 'static' : 'mapping';\n\t\tthrow new Error(\n\t\t\t`Switching useSelect from ${ prevMode } to ${ nextMode } is not allowed`\n\t\t);\n\t}\n\n\t/* eslint-disable react-hooks/rules-of-hooks */\n\t// `staticSelectMode` is not allowed to change during the hook instance's,\n\t// lifetime, so the rules of hooks are not really violated.\n\treturn staticSelectMode\n\t\t? useStaticSelect( mapSelect )\n\t\t: useMappingSelect( false, mapSelect, deps );\n\t/* eslint-enable react-hooks/rules-of-hooks */\n}\n\n/**\n * A variant of the `useSelect` hook that has the same API, but will throw a\n * suspense Promise if any of the called selectors is in an unresolved state.\n *\n * @param {Function} mapSelect Function called on every state change. The\n * returned value is exposed to the component\n * using this hook. The function receives the\n * `registry.suspendSelect` method as the first\n * argument and the `registry` as the second one.\n * @param {Array} deps A dependency array used to memoize the `mapSelect`\n * so that the same `mapSelect` is invoked on every\n * state change unless the dependencies change.\n *\n * @return {Object} Data object returned by the `mapSelect` function.\n */\nexport function useSuspenseSelect( mapSelect, deps ) {\n\treturn useMappingSelect( true, mapSelect, deps );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["@wordpress/data/src/components/use-select/index.js"],"names":["renderQueue","Store","registry","suspense","select","suspendSelect","queueContext","lastMapSelect","lastMapResult","lastMapResultValid","lastIsAsync","subscriber","createSubscriber","stores","activeStores","activeSubscriptions","Set","subscribe","listener","onStoreChange","onChange","add","unsubs","subscribeStore","storeName","push","delete","unsub","values","cancel","updateStores","newStores","newStore","includes","subscription","mapSelect","isAsync","updateValue","listeningStores","current","mapResult","__unstableMarkListeningStores","getValue","useStaticSelect","useMappingSelect","deps","store","selector","result","useSelect","staticSelectMode","staticSelectModeRef","prevMode","nextMode","Error","useSuspenseSelect"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createQueue } from '@wordpress/priority-queue';\nimport {\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n\tuseSyncExternalStore,\n\tuseDebugValue,\n} from '@wordpress/element';\nimport isShallowEqual from '@wordpress/is-shallow-equal';\n\n/**\n * Internal dependencies\n */\nimport useRegistry from '../registry-provider/use-registry';\nimport useAsyncMode from '../async-mode-provider/use-async-mode';\n\nconst renderQueue = createQueue();\n\n/**\n * @typedef {import('../../types').StoreDescriptor<C>} StoreDescriptor\n * @template {import('../../types').AnyConfig} C\n */\n/**\n * @typedef {import('../../types').ReduxStoreConfig<State,Actions,Selectors>} ReduxStoreConfig\n * @template State\n * @template {Record<string,import('../../types').ActionCreator>} Actions\n * @template Selectors\n */\n/** @typedef {import('../../types').MapSelect} MapSelect */\n/**\n * @typedef {import('../../types').UseSelectReturn<T>} UseSelectReturn\n * @template {MapSelect|StoreDescriptor<any>} T\n */\n\nfunction Store( registry, suspense ) {\n\tconst select = suspense ? registry.suspendSelect : registry.select;\n\tconst queueContext = {};\n\tlet lastMapSelect;\n\tlet lastMapResult;\n\tlet lastMapResultValid = false;\n\tlet lastIsAsync;\n\tlet subscriber;\n\n\tconst createSubscriber = ( stores ) => {\n\t\t// The set of stores the `subscribe` function is supposed to subscribe to. Here it is\n\t\t// initialized, and then the `updateStores` function can add new stores to it.\n\t\tconst activeStores = [ ...stores ];\n\n\t\t// The `subscribe` function, which is passed to the `useSyncExternalStore` hook, could\n\t\t// be called multiple times to establish multiple subscriptions. That's why we need to\n\t\t// keep a set of active subscriptions;\n\t\tconst activeSubscriptions = new Set();\n\n\t\tfunction subscribe( listener ) {\n\t\t\t// Invalidate the value right after subscription was created. React will\n\t\t\t// call `getValue` after subscribing, to detect store updates that happened\n\t\t\t// in the interval between the `getValue` call during render and creating\n\t\t\t// the subscription, which is slightly delayed. We need to ensure that this\n\t\t\t// second `getValue` call will compute a fresh value.\n\t\t\tlastMapResultValid = false;\n\n\t\t\tconst onStoreChange = () => {\n\t\t\t\t// Invalidate the value on store update, so that a fresh value is computed.\n\t\t\t\tlastMapResultValid = false;\n\t\t\t\tlistener();\n\t\t\t};\n\n\t\t\tconst onChange = () => {\n\t\t\t\tif ( lastIsAsync ) {\n\t\t\t\t\trenderQueue.add( queueContext, onStoreChange );\n\t\t\t\t} else {\n\t\t\t\t\tonStoreChange();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst unsubs = [];\n\t\t\tfunction subscribeStore( storeName ) {\n\t\t\t\tunsubs.push( registry.subscribe( onChange, storeName ) );\n\t\t\t}\n\n\t\t\tfor ( const storeName of activeStores ) {\n\t\t\t\tsubscribeStore( storeName );\n\t\t\t}\n\n\t\t\tactiveSubscriptions.add( subscribeStore );\n\n\t\t\treturn () => {\n\t\t\t\tactiveSubscriptions.delete( subscribeStore );\n\n\t\t\t\tfor ( const unsub of unsubs.values() ) {\n\t\t\t\t\t// The return value of the subscribe function could be undefined if the store is a custom generic store.\n\t\t\t\t\tunsub?.();\n\t\t\t\t}\n\t\t\t\t// Cancel existing store updates that were already scheduled.\n\t\t\t\trenderQueue.cancel( queueContext );\n\t\t\t};\n\t\t}\n\n\t\t// Check if `newStores` contains some stores we're not subscribed to yet, and add them.\n\t\tfunction updateStores( newStores ) {\n\t\t\tfor ( const newStore of newStores ) {\n\t\t\t\tif ( activeStores.includes( newStore ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// New `subscribe` calls will subscribe to `newStore`, too.\n\t\t\t\tactiveStores.push( newStore );\n\n\t\t\t\t// Add `newStore` to existing subscriptions.\n\t\t\t\tfor ( const subscription of activeSubscriptions ) {\n\t\t\t\t\tsubscription( newStore );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { subscribe, updateStores };\n\t};\n\n\treturn ( mapSelect, isAsync ) => {\n\t\tfunction updateValue() {\n\t\t\t// If the last value is valid, and the `mapSelect` callback hasn't changed,\n\t\t\t// then we can safely return the cached value. The value can change only on\n\t\t\t// store update, and in that case value will be invalidated by the listener.\n\t\t\tif ( lastMapResultValid && mapSelect === lastMapSelect ) {\n\t\t\t\treturn lastMapResult;\n\t\t\t}\n\n\t\t\tconst listeningStores = { current: null };\n\t\t\tconst mapResult = registry.__unstableMarkListeningStores(\n\t\t\t\t() => mapSelect( select, registry ),\n\t\t\t\tlisteningStores\n\t\t\t);\n\n\t\t\tif ( ! subscriber ) {\n\t\t\t\tsubscriber = createSubscriber( listeningStores.current );\n\t\t\t} else {\n\t\t\t\tsubscriber.updateStores( listeningStores.current );\n\t\t\t}\n\n\t\t\t// If the new value is shallow-equal to the old one, keep the old one so\n\t\t\t// that we don't trigger unwanted updates that do a `===` check.\n\t\t\tif ( ! isShallowEqual( lastMapResult, mapResult ) ) {\n\t\t\t\tlastMapResult = mapResult;\n\t\t\t}\n\t\t\tlastMapSelect = mapSelect;\n\t\t\tlastMapResultValid = true;\n\t\t}\n\n\t\tfunction getValue() {\n\t\t\t// Update the value in case it's been invalidated or `mapSelect` has changed.\n\t\t\tupdateValue();\n\t\t\treturn lastMapResult;\n\t\t}\n\n\t\t// When transitioning from async to sync mode, cancel existing store updates\n\t\t// that have been scheduled, and invalidate the value so that it's freshly\n\t\t// computed. It might have been changed by the update we just cancelled.\n\t\tif ( lastIsAsync && ! isAsync ) {\n\t\t\tlastMapResultValid = false;\n\t\t\trenderQueue.cancel( queueContext );\n\t\t}\n\n\t\tupdateValue();\n\n\t\tlastIsAsync = isAsync;\n\n\t\t// Return a pair of functions that can be passed to `useSyncExternalStore`.\n\t\treturn { subscribe: subscriber.subscribe, getValue };\n\t};\n}\n\nfunction useStaticSelect( storeName ) {\n\treturn useRegistry().select( storeName );\n}\n\nfunction useMappingSelect( suspense, mapSelect, deps ) {\n\tconst registry = useRegistry();\n\tconst isAsync = useAsyncMode();\n\tconst store = useMemo( () => Store( registry, suspense ), [ registry ] );\n\tconst selector = useCallback( mapSelect, deps );\n\tconst { subscribe, getValue } = store( selector, isAsync );\n\tconst result = useSyncExternalStore( subscribe, getValue, getValue );\n\tuseDebugValue( result );\n\treturn result;\n}\n\n/**\n * Custom react hook for retrieving props from registered selectors.\n *\n * In general, this custom React hook follows the\n * [rules of hooks](https://reactjs.org/docs/hooks-rules.html).\n *\n * @template {MapSelect | StoreDescriptor<any>} T\n * @param {T} mapSelect Function called on every state change. The returned value is\n * exposed to the component implementing this hook. The function\n * receives the `registry.select` method on the first argument\n * and the `registry` on the second argument.\n * When a store key is passed, all selectors for the store will be\n * returned. This is only meant for usage of these selectors in event\n * callbacks, not for data needed to create the element tree.\n * @param {unknown[]} deps If provided, this memoizes the mapSelect so the same `mapSelect` is\n * invoked on every state change unless the dependencies change.\n *\n * @example\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function HammerPriceDisplay( { currency } ) {\n * const price = useSelect( ( select ) => {\n * return select( myCustomStore ).getPrice( 'hammer', currency );\n * }, [ currency ] );\n * return new Intl.NumberFormat( 'en-US', {\n * style: 'currency',\n * currency,\n * } ).format( price );\n * }\n *\n * // Rendered in the application:\n * // <HammerPriceDisplay currency=\"USD\" />\n * ```\n *\n * In the above example, when `HammerPriceDisplay` is rendered into an\n * application, the price will be retrieved from the store state using the\n * `mapSelect` callback on `useSelect`. If the currency prop changes then\n * any price in the state for that currency is retrieved. If the currency prop\n * doesn't change and other props are passed in that do change, the price will\n * not change because the dependency is just the currency.\n *\n * When data is only used in an event callback, the data should not be retrieved\n * on render, so it may be useful to get the selectors function instead.\n *\n * **Don't use `useSelect` this way when calling the selectors in the render\n * function because your component won't re-render on a data change.**\n *\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function Paste( { children } ) {\n * const { getSettings } = useSelect( myCustomStore );\n * function onPaste() {\n * // Do something with the settings.\n * const settings = getSettings();\n * }\n * return <div onPaste={ onPaste }>{ children }</div>;\n * }\n * ```\n * @return {UseSelectReturn<T>} A custom react hook.\n */\nexport default function useSelect( mapSelect, deps ) {\n\t// On initial call, on mount, determine the mode of this `useSelect` call\n\t// and then never allow it to change on subsequent updates.\n\tconst staticSelectMode = typeof mapSelect !== 'function';\n\tconst staticSelectModeRef = useRef( staticSelectMode );\n\n\tif ( staticSelectMode !== staticSelectModeRef.current ) {\n\t\tconst prevMode = staticSelectModeRef.current ? 'static' : 'mapping';\n\t\tconst nextMode = staticSelectMode ? 'static' : 'mapping';\n\t\tthrow new Error(\n\t\t\t`Switching useSelect from ${ prevMode } to ${ nextMode } is not allowed`\n\t\t);\n\t}\n\n\t/* eslint-disable react-hooks/rules-of-hooks */\n\t// `staticSelectMode` is not allowed to change during the hook instance's,\n\t// lifetime, so the rules of hooks are not really violated.\n\treturn staticSelectMode\n\t\t? useStaticSelect( mapSelect )\n\t\t: useMappingSelect( false, mapSelect, deps );\n\t/* eslint-enable react-hooks/rules-of-hooks */\n}\n\n/**\n * A variant of the `useSelect` hook that has the same API, but will throw a\n * suspense Promise if any of the called selectors is in an unresolved state.\n *\n * @param {Function} mapSelect Function called on every state change. The\n * returned value is exposed to the component\n * using this hook. The function receives the\n * `registry.suspendSelect` method as the first\n * argument and the `registry` as the second one.\n * @param {Array} deps A dependency array used to memoize the `mapSelect`\n * so that the same `mapSelect` is invoked on every\n * state change unless the dependencies change.\n *\n * @return {Object} Data object returned by the `mapSelect` function.\n */\nexport function useSuspenseSelect( mapSelect, deps ) {\n\treturn useMappingSelect( true, mapSelect, deps );\n}\n"]}
|
package/build/registry.js
CHANGED
|
@@ -240,12 +240,20 @@ function createRegistry() {
|
|
|
240
240
|
/**
|
|
241
241
|
* Registers a store instance.
|
|
242
242
|
*
|
|
243
|
-
* @param {string}
|
|
244
|
-
* @param {
|
|
243
|
+
* @param {string} name Store registry name.
|
|
244
|
+
* @param {Function} createStore Function that creates a store object (getSelectors, getActions, subscribe).
|
|
245
245
|
*/
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
function registerStoreInstance(name,
|
|
248
|
+
function registerStoreInstance(name, createStore) {
|
|
249
|
+
if (stores[name]) {
|
|
250
|
+
// eslint-disable-next-line no-console
|
|
251
|
+
console.error('Store "' + name + '" is already registered.');
|
|
252
|
+
return stores[name];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const store = createStore();
|
|
256
|
+
|
|
249
257
|
if (typeof store.getSelectors !== 'function') {
|
|
250
258
|
throw new TypeError('store.getSelectors must be a function');
|
|
251
259
|
}
|
|
@@ -292,6 +300,8 @@ function createRegistry() {
|
|
|
292
300
|
// ignore it.
|
|
293
301
|
}
|
|
294
302
|
}
|
|
303
|
+
|
|
304
|
+
return store;
|
|
295
305
|
}
|
|
296
306
|
/**
|
|
297
307
|
* Registers a new store given a store descriptor.
|
|
@@ -301,7 +311,7 @@ function createRegistry() {
|
|
|
301
311
|
|
|
302
312
|
|
|
303
313
|
function register(store) {
|
|
304
|
-
registerStoreInstance(store.name, store.instantiate(registry));
|
|
314
|
+
registerStoreInstance(store.name, () => store.instantiate(registry));
|
|
305
315
|
}
|
|
306
316
|
|
|
307
317
|
function registerGenericStore(name, store) {
|
|
@@ -309,7 +319,7 @@ function createRegistry() {
|
|
|
309
319
|
since: '5.9',
|
|
310
320
|
alternative: 'wp.data.register( storeDescriptor )'
|
|
311
321
|
});
|
|
312
|
-
registerStoreInstance(name, store);
|
|
322
|
+
registerStoreInstance(name, () => store);
|
|
313
323
|
}
|
|
314
324
|
/**
|
|
315
325
|
* Registers a standard `@wordpress/data` store.
|
|
@@ -326,8 +336,7 @@ function createRegistry() {
|
|
|
326
336
|
throw new TypeError('Must specify store reducer');
|
|
327
337
|
}
|
|
328
338
|
|
|
329
|
-
const store = (0, _reduxStore.default)(storeName, options).instantiate(registry);
|
|
330
|
-
registerStoreInstance(storeName, store);
|
|
339
|
+
const store = registerStoreInstance(storeName, () => (0, _reduxStore.default)(storeName, options).instantiate(registry));
|
|
331
340
|
return store.store;
|
|
332
341
|
}
|
|
333
342
|
|