@wordpress/data 8.0.0 → 8.2.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 +4 -0
- package/LICENSE.md +1 -1
- package/build/components/use-select/index.js +139 -239
- package/build/components/use-select/index.js.map +1 -1
- package/build/registry.js +12 -5
- package/build/registry.js.map +1 -1
- package/build-module/components/use-select/index.js +140 -239
- package/build-module/components/use-select/index.js.map +1 -1
- package/build-module/registry.js +12 -5
- package/build-module/registry.js.map +1 -1
- package/build-types/components/use-select/index.d.ts +0 -13
- package/build-types/components/use-select/index.d.ts.map +1 -1
- package/build-types/registry.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/components/use-select/index.js +142 -275
- package/src/components/use-select/test/index.js +52 -20
- package/src/components/use-select/test/suspense.js +74 -1
- package/src/registry.js +6 -5
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
package/LICENSE.md
CHANGED
|
@@ -8,24 +8,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.default = useSelect;
|
|
9
9
|
exports.useSuspenseSelect = useSuspenseSelect;
|
|
10
10
|
|
|
11
|
-
var _useMemoOne = require("use-memo-one");
|
|
12
|
-
|
|
13
11
|
var _priorityQueue = require("@wordpress/priority-queue");
|
|
14
12
|
|
|
15
13
|
var _element = require("@wordpress/element");
|
|
16
14
|
|
|
17
15
|
var _isShallowEqual = _interopRequireDefault(require("@wordpress/is-shallow-equal"));
|
|
18
16
|
|
|
19
|
-
var _compose = require("@wordpress/compose");
|
|
20
|
-
|
|
21
17
|
var _useRegistry = _interopRequireDefault(require("../registry-provider/use-registry"));
|
|
22
18
|
|
|
23
19
|
var _useAsyncMode = _interopRequireDefault(require("../async-mode-provider/use-async-mode"));
|
|
24
20
|
|
|
25
|
-
/**
|
|
26
|
-
* External dependencies
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
21
|
/**
|
|
30
22
|
* WordPress dependencies
|
|
31
23
|
*/
|
|
@@ -33,8 +25,6 @@ var _useAsyncMode = _interopRequireDefault(require("../async-mode-provider/use-a
|
|
|
33
25
|
/**
|
|
34
26
|
* Internal dependencies
|
|
35
27
|
*/
|
|
36
|
-
const noop = () => {};
|
|
37
|
-
|
|
38
28
|
const renderQueue = (0, _priorityQueue.createQueue)();
|
|
39
29
|
/**
|
|
40
30
|
* @typedef {import('../../types').StoreDescriptor<C>} StoreDescriptor
|
|
@@ -53,6 +43,129 @@ const renderQueue = (0, _priorityQueue.createQueue)();
|
|
|
53
43
|
|
|
54
44
|
/** @typedef {import('../../types').MapSelect} MapSelect */
|
|
55
45
|
|
|
46
|
+
function Store(registry, suspense) {
|
|
47
|
+
const select = suspense ? registry.suspendSelect : registry.select;
|
|
48
|
+
const queueContext = {};
|
|
49
|
+
let lastMapSelect;
|
|
50
|
+
let lastMapResult;
|
|
51
|
+
let lastMapResultValid = false;
|
|
52
|
+
let lastIsAsync;
|
|
53
|
+
let subscribe;
|
|
54
|
+
|
|
55
|
+
const createSubscriber = stores => listener => {
|
|
56
|
+
// Invalidate the value right after subscription was created. React will
|
|
57
|
+
// call `getValue` after subscribing, to detect store updates that happened
|
|
58
|
+
// in the interval between the `getValue` call during render and creating
|
|
59
|
+
// the subscription, which is slightly delayed. We need to ensure that this
|
|
60
|
+
// second `getValue` call will compute a fresh value.
|
|
61
|
+
lastMapResultValid = false;
|
|
62
|
+
|
|
63
|
+
const onStoreChange = () => {
|
|
64
|
+
// Invalidate the value on store update, so that a fresh value is computed.
|
|
65
|
+
lastMapResultValid = false;
|
|
66
|
+
listener();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const onChange = () => {
|
|
70
|
+
if (lastIsAsync) {
|
|
71
|
+
renderQueue.add(queueContext, onStoreChange);
|
|
72
|
+
} else {
|
|
73
|
+
onStoreChange();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const unsubs = stores.map(storeName => {
|
|
78
|
+
return registry.subscribe(onChange, storeName);
|
|
79
|
+
});
|
|
80
|
+
return () => {
|
|
81
|
+
// The return value of the subscribe function could be undefined if the store is a custom generic store.
|
|
82
|
+
for (const unsub of unsubs) {
|
|
83
|
+
unsub === null || unsub === void 0 ? void 0 : unsub();
|
|
84
|
+
} // Cancel existing store updates that were already scheduled.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
renderQueue.cancel(queueContext);
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (mapSelect, resubscribe, isAsync) => {
|
|
92
|
+
const selectValue = () => mapSelect(select, registry);
|
|
93
|
+
|
|
94
|
+
function updateValue(selectFromStore) {
|
|
95
|
+
// If the last value is valid, and the `mapSelect` callback hasn't changed,
|
|
96
|
+
// then we can safely return the cached value. The value can change only on
|
|
97
|
+
// store update, and in that case value will be invalidated by the listener.
|
|
98
|
+
if (lastMapResultValid && mapSelect === lastMapSelect) {
|
|
99
|
+
return lastMapResult;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const mapResult = selectFromStore(); // If the new value is shallow-equal to the old one, keep the old one so
|
|
103
|
+
// that we don't trigger unwanted updates that do a `===` check.
|
|
104
|
+
|
|
105
|
+
if (!(0, _isShallowEqual.default)(lastMapResult, mapResult)) {
|
|
106
|
+
lastMapResult = mapResult;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
lastMapResultValid = true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getValue() {
|
|
113
|
+
// Update the value in case it's been invalidated or `mapSelect` has changed.
|
|
114
|
+
updateValue(selectValue);
|
|
115
|
+
return lastMapResult;
|
|
116
|
+
} // When transitioning from async to sync mode, cancel existing store updates
|
|
117
|
+
// that have been scheduled, and invalidate the value so that it's freshly
|
|
118
|
+
// computed. It might have been changed by the update we just cancelled.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if (lastIsAsync && !isAsync) {
|
|
122
|
+
lastMapResultValid = false;
|
|
123
|
+
renderQueue.cancel(queueContext);
|
|
124
|
+
} // Either initialize the `subscribe` function, or create a new one if `mapSelect`
|
|
125
|
+
// changed and has dependencies.
|
|
126
|
+
// Usage without dependencies, `useSelect( ( s ) => { ... } )`, will subscribe
|
|
127
|
+
// only once, at mount, and won't resubscibe even if `mapSelect` changes.
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if (!subscribe || resubscribe && mapSelect !== lastMapSelect) {
|
|
131
|
+
// Find out what stores the `mapSelect` callback is selecting from and
|
|
132
|
+
// use that list to create subscriptions to specific stores.
|
|
133
|
+
const listeningStores = {
|
|
134
|
+
current: null
|
|
135
|
+
};
|
|
136
|
+
updateValue(() => registry.__unstableMarkListeningStores(selectValue, listeningStores));
|
|
137
|
+
subscribe = createSubscriber(listeningStores.current);
|
|
138
|
+
} else {
|
|
139
|
+
updateValue(selectValue);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
lastIsAsync = isAsync;
|
|
143
|
+
lastMapSelect = mapSelect; // Return a pair of functions that can be passed to `useSyncExternalStore`.
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
subscribe,
|
|
147
|
+
getValue
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function useStaticSelect(storeName) {
|
|
153
|
+
return (0, _useRegistry.default)().select(storeName);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function useMappingSelect(suspense, mapSelect, deps) {
|
|
157
|
+
const registry = (0, _useRegistry.default)();
|
|
158
|
+
const isAsync = (0, _useAsyncMode.default)();
|
|
159
|
+
const store = (0, _element.useMemo)(() => Store(registry, suspense), [registry]);
|
|
160
|
+
const selector = (0, _element.useCallback)(mapSelect, deps);
|
|
161
|
+
const {
|
|
162
|
+
subscribe,
|
|
163
|
+
getValue
|
|
164
|
+
} = store(selector, !!deps, isAsync);
|
|
165
|
+
const result = (0, _element.useSyncExternalStore)(subscribe, getValue, getValue);
|
|
166
|
+
(0, _element.useDebugValue)(result);
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
56
169
|
/**
|
|
57
170
|
* Custom react hook for retrieving props from registered selectors.
|
|
58
171
|
*
|
|
@@ -118,140 +231,25 @@ const renderQueue = (0, _priorityQueue.createQueue)();
|
|
|
118
231
|
* @return {UseSelectReturn<T>} A custom react hook.
|
|
119
232
|
*/
|
|
120
233
|
|
|
121
|
-
function useSelect(mapSelect, deps) {
|
|
122
|
-
const hasMappingFunction = 'function' === typeof mapSelect; // If we're recalling a store by its name or by
|
|
123
|
-
// its descriptor then we won't be caching the
|
|
124
|
-
// calls to `mapSelect` because we won't be calling it.
|
|
125
|
-
|
|
126
|
-
if (!hasMappingFunction) {
|
|
127
|
-
deps = [];
|
|
128
|
-
} // Because of the "rule of hooks" we have to call `useCallback`
|
|
129
|
-
// on every invocation whether or not we have a real function
|
|
130
|
-
// for `mapSelect`. we'll create this intermediate variable to
|
|
131
|
-
// fulfill that need and then reference it with our "real"
|
|
132
|
-
// `_mapSelect` if we can.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const callbackMapper = (0, _element.useCallback)(hasMappingFunction ? mapSelect : noop, deps);
|
|
136
234
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const listeningStores = (0, _element.useRef)([]);
|
|
149
|
-
const wrapSelect = (0, _element.useCallback)(callback => registry.__unstableMarkListeningStores(() => callback(registry.select, registry), listeningStores), [registry]); // Generate a "flag" for used in the effect dependency array.
|
|
150
|
-
// It's different than just using `mapSelect` since deps could be undefined,
|
|
151
|
-
// in that case, we would still want to memoize it.
|
|
152
|
-
|
|
153
|
-
const depsChangedFlag = (0, _element.useMemo)(() => ({}), deps || []);
|
|
154
|
-
let mapOutput;
|
|
155
|
-
let selectorRan = false;
|
|
156
|
-
|
|
157
|
-
if (_mapSelect) {
|
|
158
|
-
mapOutput = latestMapOutput.current;
|
|
159
|
-
const hasReplacedRegistry = latestRegistry.current !== registry;
|
|
160
|
-
const hasReplacedMapSelect = latestMapSelect.current !== _mapSelect;
|
|
161
|
-
const hasLeftAsyncMode = latestIsAsync.current && !isAsync;
|
|
162
|
-
const lastMapSelectFailed = !!latestMapOutputError.current;
|
|
163
|
-
|
|
164
|
-
if (hasReplacedRegistry || hasReplacedMapSelect || hasLeftAsyncMode || lastMapSelectFailed) {
|
|
165
|
-
try {
|
|
166
|
-
mapOutput = wrapSelect(_mapSelect);
|
|
167
|
-
selectorRan = true;
|
|
168
|
-
} catch (error) {
|
|
169
|
-
let errorMessage = `An error occurred while running 'mapSelect': ${error.message}`;
|
|
170
|
-
|
|
171
|
-
if (latestMapOutputError.current) {
|
|
172
|
-
errorMessage += `\nThe error may be correlated with this previous error:\n`;
|
|
173
|
-
errorMessage += `${latestMapOutputError.current.stack}\n\n`;
|
|
174
|
-
errorMessage += 'Original stack trace:';
|
|
175
|
-
} // eslint-disable-next-line no-console
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
console.error(errorMessage);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
235
|
+
function useSelect(mapSelect, deps) {
|
|
236
|
+
// On initial call, on mount, determine the mode of this `useSelect` call
|
|
237
|
+
// and then never allow it to change on subsequent updates.
|
|
238
|
+
const staticSelectMode = typeof mapSelect !== 'function';
|
|
239
|
+
const staticSelectModeRef = (0, _element.useRef)(staticSelectMode);
|
|
240
|
+
|
|
241
|
+
if (staticSelectMode !== staticSelectModeRef.current) {
|
|
242
|
+
const prevMode = staticSelectModeRef.current ? 'static' : 'mapping';
|
|
243
|
+
const nextMode = staticSelectMode ? 'static' : 'mapping';
|
|
244
|
+
throw new Error(`Switching useSelect from ${prevMode} to ${nextMode} is not allowed`);
|
|
181
245
|
}
|
|
246
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
247
|
+
// `staticSelectMode` is not allowed to change during the hook instance's,
|
|
248
|
+
// lifetime, so the rules of hooks are not really violated.
|
|
182
249
|
|
|
183
|
-
(0, _compose.useIsomorphicLayoutEffect)(() => {
|
|
184
|
-
if (!hasMappingFunction) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
250
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
latestIsAsync.current = isAsync;
|
|
191
|
-
|
|
192
|
-
if (selectorRan) {
|
|
193
|
-
latestMapOutput.current = mapOutput;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
latestMapOutputError.current = undefined;
|
|
197
|
-
}); // React can sometimes clear the `useMemo` cache.
|
|
198
|
-
// We use the cache-stable `useMemoOne` to avoid
|
|
199
|
-
// losing queues.
|
|
200
|
-
|
|
201
|
-
const queueContext = (0, _useMemoOne.useMemoOne)(() => ({
|
|
202
|
-
queue: true
|
|
203
|
-
}), [registry]);
|
|
204
|
-
const [, forceRender] = (0, _element.useReducer)(s => s + 1, 0);
|
|
205
|
-
const isMounted = (0, _element.useRef)(false);
|
|
206
|
-
(0, _compose.useIsomorphicLayoutEffect)(() => {
|
|
207
|
-
if (!hasMappingFunction) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const onStoreChange = () => {
|
|
212
|
-
try {
|
|
213
|
-
const newMapOutput = wrapSelect(latestMapSelect.current);
|
|
214
|
-
|
|
215
|
-
if ((0, _isShallowEqual.default)(latestMapOutput.current, newMapOutput)) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
latestMapOutput.current = newMapOutput;
|
|
220
|
-
} catch (error) {
|
|
221
|
-
latestMapOutputError.current = error;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
forceRender();
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const onChange = () => {
|
|
228
|
-
if (!isMounted.current) {
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (latestIsAsync.current) {
|
|
233
|
-
renderQueue.add(queueContext, onStoreChange);
|
|
234
|
-
} else {
|
|
235
|
-
onStoreChange();
|
|
236
|
-
}
|
|
237
|
-
}; // Catch any possible state changes during mount before the subscription
|
|
238
|
-
// could be set.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
onStoreChange();
|
|
242
|
-
const unsubscribers = listeningStores.current.map(storeName => registry.subscribe(onChange, storeName));
|
|
243
|
-
isMounted.current = true;
|
|
244
|
-
return () => {
|
|
245
|
-
// The return value of the subscribe function could be undefined if the store is a custom generic store.
|
|
246
|
-
unsubscribers.forEach(unsubscribe => unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
|
|
247
|
-
renderQueue.cancel(queueContext);
|
|
248
|
-
isMounted.current = false;
|
|
249
|
-
}; // If you're tempted to eliminate the spread dependencies below don't do it!
|
|
250
|
-
// We're passing these in from the calling function and want to make sure we're
|
|
251
|
-
// examining every individual value inside the `deps` array.
|
|
252
|
-
}, [registry, wrapSelect, hasMappingFunction, depsChangedFlag]);
|
|
253
|
-
(0, _element.useDebugValue)(mapOutput);
|
|
254
|
-
return hasMappingFunction ? mapOutput : registry.select(mapSelect);
|
|
251
|
+
return staticSelectMode ? useStaticSelect(mapSelect) : useMappingSelect(false, mapSelect, deps);
|
|
252
|
+
/* eslint-enable react-hooks/rules-of-hooks */
|
|
255
253
|
}
|
|
256
254
|
/**
|
|
257
255
|
* A variant of the `useSelect` hook that has the same API, but will throw a
|
|
@@ -271,104 +269,6 @@ function useSelect(mapSelect, deps) {
|
|
|
271
269
|
|
|
272
270
|
|
|
273
271
|
function useSuspenseSelect(mapSelect, deps) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const registry = (0, _useRegistry.default)();
|
|
277
|
-
const isAsync = (0, _useAsyncMode.default)();
|
|
278
|
-
const latestRegistry = (0, _element.useRef)(registry);
|
|
279
|
-
const latestMapSelect = (0, _element.useRef)();
|
|
280
|
-
const latestIsAsync = (0, _element.useRef)(isAsync);
|
|
281
|
-
const latestMapOutput = (0, _element.useRef)();
|
|
282
|
-
const latestMapOutputError = (0, _element.useRef)(); // Keep track of the stores being selected in the `mapSelect` function,
|
|
283
|
-
// and only subscribe to those stores later.
|
|
284
|
-
|
|
285
|
-
const listeningStores = (0, _element.useRef)([]);
|
|
286
|
-
const wrapSelect = (0, _element.useCallback)(callback => registry.__unstableMarkListeningStores(() => callback(registry.suspendSelect, registry), listeningStores), [registry]); // Generate a "flag" for used in the effect dependency array.
|
|
287
|
-
// It's different than just using `mapSelect` since deps could be undefined,
|
|
288
|
-
// in that case, we would still want to memoize it.
|
|
289
|
-
|
|
290
|
-
const depsChangedFlag = (0, _element.useMemo)(() => ({}), deps || []);
|
|
291
|
-
let mapOutput = latestMapOutput.current;
|
|
292
|
-
let mapOutputError = latestMapOutputError.current;
|
|
293
|
-
const hasReplacedRegistry = latestRegistry.current !== registry;
|
|
294
|
-
const hasReplacedMapSelect = latestMapSelect.current !== _mapSelect;
|
|
295
|
-
const hasLeftAsyncMode = latestIsAsync.current && !isAsync;
|
|
296
|
-
let selectorRan = false;
|
|
297
|
-
|
|
298
|
-
if (hasReplacedRegistry || hasReplacedMapSelect || hasLeftAsyncMode) {
|
|
299
|
-
try {
|
|
300
|
-
mapOutput = wrapSelect(_mapSelect);
|
|
301
|
-
selectorRan = true;
|
|
302
|
-
} catch (error) {
|
|
303
|
-
mapOutputError = error;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
(0, _compose.useIsomorphicLayoutEffect)(() => {
|
|
308
|
-
latestRegistry.current = registry;
|
|
309
|
-
latestMapSelect.current = _mapSelect;
|
|
310
|
-
latestIsAsync.current = isAsync;
|
|
311
|
-
|
|
312
|
-
if (selectorRan) {
|
|
313
|
-
latestMapOutput.current = mapOutput;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
latestMapOutputError.current = mapOutputError;
|
|
317
|
-
}); // React can sometimes clear the `useMemo` cache.
|
|
318
|
-
// We use the cache-stable `useMemoOne` to avoid
|
|
319
|
-
// losing queues.
|
|
320
|
-
|
|
321
|
-
const queueContext = (0, _useMemoOne.useMemoOne)(() => ({
|
|
322
|
-
queue: true
|
|
323
|
-
}), [registry]);
|
|
324
|
-
const [, forceRender] = (0, _element.useReducer)(s => s + 1, 0);
|
|
325
|
-
const isMounted = (0, _element.useRef)(false);
|
|
326
|
-
(0, _compose.useIsomorphicLayoutEffect)(() => {
|
|
327
|
-
const onStoreChange = () => {
|
|
328
|
-
try {
|
|
329
|
-
const newMapOutput = wrapSelect(latestMapSelect.current);
|
|
330
|
-
|
|
331
|
-
if ((0, _isShallowEqual.default)(latestMapOutput.current, newMapOutput)) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
latestMapOutput.current = newMapOutput;
|
|
336
|
-
} catch (error) {
|
|
337
|
-
latestMapOutputError.current = error;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
forceRender();
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
const onChange = () => {
|
|
344
|
-
if (!isMounted.current) {
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
if (latestIsAsync.current) {
|
|
349
|
-
renderQueue.add(queueContext, onStoreChange);
|
|
350
|
-
} else {
|
|
351
|
-
onStoreChange();
|
|
352
|
-
}
|
|
353
|
-
}; // catch any possible state changes during mount before the subscription
|
|
354
|
-
// could be set.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
onStoreChange();
|
|
358
|
-
const unsubscribers = listeningStores.current.map(storeName => registry.subscribe(onChange, storeName));
|
|
359
|
-
isMounted.current = true;
|
|
360
|
-
return () => {
|
|
361
|
-
// The return value of the subscribe function could be undefined if the store is a custom generic store.
|
|
362
|
-
unsubscribers.forEach(unsubscribe => unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
|
|
363
|
-
renderQueue.cancel(queueContext);
|
|
364
|
-
isMounted.current = false;
|
|
365
|
-
};
|
|
366
|
-
}, [registry, wrapSelect, depsChangedFlag]);
|
|
367
|
-
|
|
368
|
-
if (mapOutputError) {
|
|
369
|
-
throw mapOutputError;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return mapOutput;
|
|
272
|
+
return useMappingSelect(true, mapSelect, deps);
|
|
373
273
|
}
|
|
374
274
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/data/src/components/use-select/index.js"],"names":["noop","renderQueue","useSelect","mapSelect","deps","hasMappingFunction","callbackMapper","_mapSelect","registry","isAsync","latestRegistry","latestMapSelect","latestIsAsync","latestMapOutput","latestMapOutputError","listeningStores","wrapSelect","callback","__unstableMarkListeningStores","select","depsChangedFlag","mapOutput","selectorRan","current","hasReplacedRegistry","hasReplacedMapSelect","hasLeftAsyncMode","lastMapSelectFailed","error","errorMessage","message","stack","console","undefined","queueContext","queue","forceRender","s","isMounted","onStoreChange","newMapOutput","onChange","add","unsubscribers","map","storeName","subscribe","forEach","unsubscribe","cancel","useSuspenseSelect","suspendSelect","mapOutputError"],"mappings":";;;;;;;;;;AAGA;;AAKA;;AACA;;AAOA;;AACA;;AAKA;;AACA;;AAvBA;AACA;AACA;;AAGA;AACA;AACA;;AAYA;AACA;AACA;AAIA,MAAMA,IAAI,GAAG,MAAM,CAAE,CAArB;;AACA,MAAMC,WAAW,GAAG,iCAApB;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACe,SAASC,SAAT,CAAoBC,SAApB,EAA+BC,IAA/B,EAAsC;AACpD,QAAMC,kBAAkB,GAAG,eAAe,OAAOF,SAAjD,CADoD,CAGpD;AACA;AACA;;AACA,MAAK,CAAEE,kBAAP,EAA4B;AAC3BD,IAAAA,IAAI,GAAG,EAAP;AACA,GARmD,CAUpD;AACA;AACA;AACA;AACA;;;AACA,QAAME,cAAc,GAAG,0BACtBD,kBAAkB,GAAGF,SAAH,GAAeH,IADX,EAEtBI,IAFsB,CAAvB;;AAIA,QAAMG,UAAU,GAAGF,kBAAkB,GAAGC,cAAH,GAAoB,IAAzD;;AAEA,QAAME,QAAQ,GAAG,2BAAjB;AACA,QAAMC,OAAO,GAAG,4BAAhB;AAEA,QAAMC,cAAc,GAAG,qBAAQF,QAAR,CAAvB;AACA,QAAMG,eAAe,GAAG,sBAAxB;AACA,QAAMC,aAAa,GAAG,qBAAQH,OAAR,CAAtB;AACA,QAAMI,eAAe,GAAG,sBAAxB;AACA,QAAMC,oBAAoB,GAAG,sBAA7B,CA5BoD,CA8BpD;AACA;;AACA,QAAMC,eAAe,GAAG,qBAAQ,EAAR,CAAxB;AACA,QAAMC,UAAU,GAAG,0BAChBC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","sourcesContent":["/**\n * External dependencies\n */\nimport { useMemoOne } from 'use-memo-one';\n\n/**\n * WordPress dependencies\n */\nimport { createQueue } from '@wordpress/priority-queue';\nimport {\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n\tuseReducer,\n\tuseDebugValue,\n} from '@wordpress/element';\nimport isShallowEqual from '@wordpress/is-shallow-equal';\nimport { useIsomorphicLayoutEffect } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport useRegistry from '../registry-provider/use-registry';\nimport useAsyncMode from '../async-mode-provider/use-async-mode';\n\nconst noop = () => {};\nconst renderQueue = createQueue();\n\n/**\n * @typedef {import('../../types').StoreDescriptor<C>} StoreDescriptor\n * @template C\n */\n/**\n * @typedef {import('../../types').ReduxStoreConfig<State,Actions,Selectors>} ReduxStoreConfig\n * @template State,Actions,Selectors\n */\n/**\n * @typedef {import('../../types').UseSelectReturn<T>} UseSelectReturn\n * @template T\n */\n/** @typedef {import('../../types').MapSelect} MapSelect */\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\tconst hasMappingFunction = 'function' === typeof mapSelect;\n\n\t// If we're recalling a store by its name or by\n\t// its descriptor then we won't be caching the\n\t// calls to `mapSelect` because we won't be calling it.\n\tif ( ! hasMappingFunction ) {\n\t\tdeps = [];\n\t}\n\n\t// Because of the \"rule of hooks\" we have to call `useCallback`\n\t// on every invocation whether or not we have a real function\n\t// for `mapSelect`. we'll create this intermediate variable to\n\t// fulfill that need and then reference it with our \"real\"\n\t// `_mapSelect` if we can.\n\tconst callbackMapper = useCallback(\n\t\thasMappingFunction ? mapSelect : noop,\n\t\tdeps\n\t);\n\tconst _mapSelect = hasMappingFunction ? callbackMapper : null;\n\n\tconst registry = useRegistry();\n\tconst isAsync = useAsyncMode();\n\n\tconst latestRegistry = useRef( registry );\n\tconst latestMapSelect = useRef();\n\tconst latestIsAsync = useRef( isAsync );\n\tconst latestMapOutput = useRef();\n\tconst latestMapOutputError = useRef();\n\n\t// Keep track of the stores being selected in the _mapSelect function,\n\t// and only subscribe to those stores later.\n\tconst listeningStores = useRef( [] );\n\tconst wrapSelect = useCallback(\n\t\t( callback ) =>\n\t\t\tregistry.__unstableMarkListeningStores(\n\t\t\t\t() => callback( registry.select, registry ),\n\t\t\t\tlisteningStores\n\t\t\t),\n\t\t[ registry ]\n\t);\n\n\t// Generate a \"flag\" for used in the effect dependency array.\n\t// It's different than just using `mapSelect` since deps could be undefined,\n\t// in that case, we would still want to memoize it.\n\tconst depsChangedFlag = useMemo( () => ( {} ), deps || [] );\n\n\tlet mapOutput;\n\n\tlet selectorRan = false;\n\tif ( _mapSelect ) {\n\t\tmapOutput = latestMapOutput.current;\n\t\tconst hasReplacedRegistry = latestRegistry.current !== registry;\n\t\tconst hasReplacedMapSelect = latestMapSelect.current !== _mapSelect;\n\t\tconst hasLeftAsyncMode = latestIsAsync.current && ! isAsync;\n\t\tconst lastMapSelectFailed = !! latestMapOutputError.current;\n\n\t\tif (\n\t\t\thasReplacedRegistry ||\n\t\t\thasReplacedMapSelect ||\n\t\t\thasLeftAsyncMode ||\n\t\t\tlastMapSelectFailed\n\t\t) {\n\t\t\ttry {\n\t\t\t\tmapOutput = wrapSelect( _mapSelect );\n\t\t\t\tselectorRan = true;\n\t\t\t} catch ( error ) {\n\t\t\t\tlet errorMessage = `An error occurred while running 'mapSelect': ${ error.message }`;\n\n\t\t\t\tif ( latestMapOutputError.current ) {\n\t\t\t\t\terrorMessage += `\\nThe error may be correlated with this previous error:\\n`;\n\t\t\t\t\terrorMessage += `${ latestMapOutputError.current.stack }\\n\\n`;\n\t\t\t\t\terrorMessage += 'Original stack trace:';\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error( errorMessage );\n\t\t\t}\n\t\t}\n\t}\n\n\tuseIsomorphicLayoutEffect( () => {\n\t\tif ( ! hasMappingFunction ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlatestRegistry.current = registry;\n\t\tlatestMapSelect.current = _mapSelect;\n\t\tlatestIsAsync.current = isAsync;\n\t\tif ( selectorRan ) {\n\t\t\tlatestMapOutput.current = mapOutput;\n\t\t}\n\t\tlatestMapOutputError.current = undefined;\n\t} );\n\n\t// React can sometimes clear the `useMemo` cache.\n\t// We use the cache-stable `useMemoOne` to avoid\n\t// losing queues.\n\tconst queueContext = useMemoOne( () => ( { queue: true } ), [ registry ] );\n\tconst [ , forceRender ] = useReducer( ( s ) => s + 1, 0 );\n\tconst isMounted = useRef( false );\n\n\tuseIsomorphicLayoutEffect( () => {\n\t\tif ( ! hasMappingFunction ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst onStoreChange = () => {\n\t\t\ttry {\n\t\t\t\tconst newMapOutput = wrapSelect( latestMapSelect.current );\n\n\t\t\t\tif ( isShallowEqual( latestMapOutput.current, newMapOutput ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlatestMapOutput.current = newMapOutput;\n\t\t\t} catch ( error ) {\n\t\t\t\tlatestMapOutputError.current = error;\n\t\t\t}\n\t\t\tforceRender();\n\t\t};\n\n\t\tconst onChange = () => {\n\t\t\tif ( ! isMounted.current ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( latestIsAsync.current ) {\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\t// Catch any possible state changes during mount before the subscription\n\t\t// could be set.\n\t\tonStoreChange();\n\n\t\tconst unsubscribers = listeningStores.current.map( ( storeName ) =>\n\t\t\tregistry.subscribe( onChange, storeName )\n\t\t);\n\n\t\tisMounted.current = true;\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\tunsubscribers.forEach( ( unsubscribe ) => unsubscribe?.() );\n\t\t\trenderQueue.cancel( queueContext );\n\t\t\tisMounted.current = false;\n\t\t};\n\t\t// If you're tempted to eliminate the spread dependencies below don't do it!\n\t\t// We're passing these in from the calling function and want to make sure we're\n\t\t// examining every individual value inside the `deps` array.\n\t}, [ registry, wrapSelect, hasMappingFunction, depsChangedFlag ] );\n\n\tuseDebugValue( mapOutput );\n\n\treturn hasMappingFunction ? mapOutput : registry.select( mapSelect );\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\tconst _mapSelect = useCallback( mapSelect, deps );\n\n\tconst registry = useRegistry();\n\tconst isAsync = useAsyncMode();\n\n\tconst latestRegistry = useRef( registry );\n\tconst latestMapSelect = useRef();\n\tconst latestIsAsync = useRef( isAsync );\n\tconst latestMapOutput = useRef();\n\tconst latestMapOutputError = useRef();\n\n\t// Keep track of the stores being selected in the `mapSelect` function,\n\t// and only subscribe to those stores later.\n\tconst listeningStores = useRef( [] );\n\tconst wrapSelect = useCallback(\n\t\t( callback ) =>\n\t\t\tregistry.__unstableMarkListeningStores(\n\t\t\t\t() => callback( registry.suspendSelect, registry ),\n\t\t\t\tlisteningStores\n\t\t\t),\n\t\t[ registry ]\n\t);\n\n\t// Generate a \"flag\" for used in the effect dependency array.\n\t// It's different than just using `mapSelect` since deps could be undefined,\n\t// in that case, we would still want to memoize it.\n\tconst depsChangedFlag = useMemo( () => ( {} ), deps || [] );\n\n\tlet mapOutput = latestMapOutput.current;\n\tlet mapOutputError = latestMapOutputError.current;\n\n\tconst hasReplacedRegistry = latestRegistry.current !== registry;\n\tconst hasReplacedMapSelect = latestMapSelect.current !== _mapSelect;\n\tconst hasLeftAsyncMode = latestIsAsync.current && ! isAsync;\n\n\tlet selectorRan = false;\n\tif ( hasReplacedRegistry || hasReplacedMapSelect || hasLeftAsyncMode ) {\n\t\ttry {\n\t\t\tmapOutput = wrapSelect( _mapSelect );\n\t\t\tselectorRan = true;\n\t\t} catch ( error ) {\n\t\t\tmapOutputError = error;\n\t\t}\n\t}\n\n\tuseIsomorphicLayoutEffect( () => {\n\t\tlatestRegistry.current = registry;\n\t\tlatestMapSelect.current = _mapSelect;\n\t\tlatestIsAsync.current = isAsync;\n\t\tif ( selectorRan ) {\n\t\t\tlatestMapOutput.current = mapOutput;\n\t\t}\n\t\tlatestMapOutputError.current = mapOutputError;\n\t} );\n\n\t// React can sometimes clear the `useMemo` cache.\n\t// We use the cache-stable `useMemoOne` to avoid\n\t// losing queues.\n\tconst queueContext = useMemoOne( () => ( { queue: true } ), [ registry ] );\n\tconst [ , forceRender ] = useReducer( ( s ) => s + 1, 0 );\n\tconst isMounted = useRef( false );\n\n\tuseIsomorphicLayoutEffect( () => {\n\t\tconst onStoreChange = () => {\n\t\t\ttry {\n\t\t\t\tconst newMapOutput = wrapSelect( latestMapSelect.current );\n\n\t\t\t\tif ( isShallowEqual( latestMapOutput.current, newMapOutput ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlatestMapOutput.current = newMapOutput;\n\t\t\t} catch ( error ) {\n\t\t\t\tlatestMapOutputError.current = error;\n\t\t\t}\n\n\t\t\tforceRender();\n\t\t};\n\n\t\tconst onChange = () => {\n\t\t\tif ( ! isMounted.current ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( latestIsAsync.current ) {\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\t// catch any possible state changes during mount before the subscription\n\t\t// could be set.\n\t\tonStoreChange();\n\n\t\tconst unsubscribers = listeningStores.current.map( ( storeName ) =>\n\t\t\tregistry.subscribe( onChange, storeName )\n\t\t);\n\n\t\tisMounted.current = true;\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\tunsubscribers.forEach( ( unsubscribe ) => unsubscribe?.() );\n\t\t\trenderQueue.cancel( queueContext );\n\t\t\tisMounted.current = false;\n\t\t};\n\t}, [ registry, wrapSelect, depsChangedFlag ] );\n\n\tif ( mapOutputError ) {\n\t\tthrow mapOutputError;\n\t}\n\n\treturn mapOutput;\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","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 C\n */\n/**\n * @typedef {import('../../types').ReduxStoreConfig<State,Actions,Selectors>} ReduxStoreConfig\n * @template State,Actions,Selectors\n */\n/**\n * @typedef {import('../../types').UseSelectReturn<T>} UseSelectReturn\n * @template T\n */\n/** @typedef {import('../../types').MapSelect} MapSelect */\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"]}
|
package/build/registry.js
CHANGED
|
@@ -75,7 +75,7 @@ function createRegistry() {
|
|
|
75
75
|
let parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
76
76
|
const stores = {};
|
|
77
77
|
const emitter = (0, _emitter.createEmitter)();
|
|
78
|
-
|
|
78
|
+
let listeningStores = null;
|
|
79
79
|
/**
|
|
80
80
|
* Global listener called for each store's update.
|
|
81
81
|
*/
|
|
@@ -129,8 +129,10 @@ function createRegistry() {
|
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
function select(storeNameOrDescriptor) {
|
|
132
|
+
var _listeningStores;
|
|
133
|
+
|
|
132
134
|
const storeName = getStoreName(storeNameOrDescriptor);
|
|
133
|
-
listeningStores.add(storeName);
|
|
135
|
+
(_listeningStores = listeningStores) === null || _listeningStores === void 0 ? void 0 : _listeningStores.add(storeName);
|
|
134
136
|
const store = stores[storeName];
|
|
135
137
|
|
|
136
138
|
if (store) {
|
|
@@ -141,12 +143,13 @@ function createRegistry() {
|
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
function __unstableMarkListeningStores(callback, ref) {
|
|
144
|
-
listeningStores
|
|
146
|
+
listeningStores = new Set();
|
|
145
147
|
|
|
146
148
|
try {
|
|
147
149
|
return callback.call(this);
|
|
148
150
|
} finally {
|
|
149
151
|
ref.current = Array.from(listeningStores);
|
|
152
|
+
listeningStores = null;
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
/**
|
|
@@ -163,8 +166,10 @@ function createRegistry() {
|
|
|
163
166
|
|
|
164
167
|
|
|
165
168
|
function resolveSelect(storeNameOrDescriptor) {
|
|
169
|
+
var _listeningStores2;
|
|
170
|
+
|
|
166
171
|
const storeName = getStoreName(storeNameOrDescriptor);
|
|
167
|
-
listeningStores.add(storeName);
|
|
172
|
+
(_listeningStores2 = listeningStores) === null || _listeningStores2 === void 0 ? void 0 : _listeningStores2.add(storeName);
|
|
168
173
|
const store = stores[storeName];
|
|
169
174
|
|
|
170
175
|
if (store) {
|
|
@@ -187,8 +192,10 @@ function createRegistry() {
|
|
|
187
192
|
|
|
188
193
|
|
|
189
194
|
function suspendSelect(storeNameOrDescriptor) {
|
|
195
|
+
var _listeningStores3;
|
|
196
|
+
|
|
190
197
|
const storeName = getStoreName(storeNameOrDescriptor);
|
|
191
|
-
listeningStores.add(storeName);
|
|
198
|
+
(_listeningStores3 = listeningStores) === null || _listeningStores3 === void 0 ? void 0 : _listeningStores3.add(storeName);
|
|
192
199
|
const store = stores[storeName];
|
|
193
200
|
|
|
194
201
|
if (store) {
|