@wordpress/data 9.3.0 → 9.5.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/use-dispatch/use-dispatch-with-map.js +2 -6
  3. package/build/components/use-dispatch/use-dispatch-with-map.js.map +1 -1
  4. package/build/components/use-select/index.js +1 -1
  5. package/build/components/use-select/index.js.map +1 -1
  6. package/build/controls.js +18 -37
  7. package/build/controls.js.map +1 -1
  8. package/build/factory.js +1 -3
  9. package/build/factory.js.map +1 -1
  10. package/build/redux-store/index.js +100 -191
  11. package/build/redux-store/index.js.map +1 -1
  12. package/build/redux-store/metadata/reducer.js +2 -8
  13. package/build/redux-store/metadata/reducer.js.map +1 -1
  14. package/build/redux-store/metadata/selectors.js +13 -15
  15. package/build/redux-store/metadata/selectors.js.map +1 -1
  16. package/build/redux-store/metadata/utils.js +1 -3
  17. package/build/redux-store/metadata/utils.js.map +1 -1
  18. package/build/registry.js +8 -18
  19. package/build/registry.js.map +1 -1
  20. package/build/resolvers-cache-middleware.js +3 -6
  21. package/build/resolvers-cache-middleware.js.map +1 -1
  22. package/build/store/index.js +2 -10
  23. package/build/store/index.js.map +1 -1
  24. package/build-module/components/use-dispatch/use-dispatch-with-map.js +2 -6
  25. package/build-module/components/use-dispatch/use-dispatch-with-map.js.map +1 -1
  26. package/build-module/components/use-select/index.js +1 -1
  27. package/build-module/components/use-select/index.js.map +1 -1
  28. package/build-module/controls.js +18 -37
  29. package/build-module/controls.js.map +1 -1
  30. package/build-module/factory.js +1 -3
  31. package/build-module/factory.js.map +1 -1
  32. package/build-module/redux-store/index.js +100 -191
  33. package/build-module/redux-store/index.js.map +1 -1
  34. package/build-module/redux-store/metadata/reducer.js +2 -8
  35. package/build-module/redux-store/metadata/reducer.js.map +1 -1
  36. package/build-module/redux-store/metadata/selectors.js +13 -15
  37. package/build-module/redux-store/metadata/selectors.js.map +1 -1
  38. package/build-module/redux-store/metadata/utils.js +1 -3
  39. package/build-module/redux-store/metadata/utils.js.map +1 -1
  40. package/build-module/registry.js +8 -18
  41. package/build-module/registry.js.map +1 -1
  42. package/build-module/resolvers-cache-middleware.js +3 -6
  43. package/build-module/resolvers-cache-middleware.js.map +1 -1
  44. package/build-module/store/index.js +2 -10
  45. package/build-module/store/index.js.map +1 -1
  46. package/build-types/redux-store/index.d.ts.map +1 -1
  47. package/build-types/redux-store/metadata/selectors.d.ts.map +1 -1
  48. package/package.json +9 -9
  49. package/src/redux-store/index.js +129 -206
  50. package/src/redux-store/metadata/selectors.js +9 -2
  51. package/src/test/privateAPIs.js +31 -0
  52. package/tsconfig.tsbuildinfo +1 -1
@@ -2,19 +2,11 @@ const coreDataStore = {
2
2
  name: 'core/data',
3
3
 
4
4
  instantiate(registry) {
5
- const getCoreDataSelector = selectorName => function (key) {
6
- for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
7
- args[_key - 1] = arguments[_key];
8
- }
9
-
5
+ const getCoreDataSelector = selectorName => (key, ...args) => {
10
6
  return registry.select(key)[selectorName](...args);
11
7
  };
12
8
 
13
- const getCoreDataAction = actionName => function (key) {
14
- for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
15
- args[_key2 - 1] = arguments[_key2];
16
- }
17
-
9
+ const getCoreDataAction = actionName => (key, ...args) => {
18
10
  return registry.dispatch(key)[actionName](...args);
19
11
  };
20
12
 
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/data/src/store/index.js"],"names":["coreDataStore","name","instantiate","registry","getCoreDataSelector","selectorName","key","args","select","getCoreDataAction","actionName","dispatch","getSelectors","Object","fromEntries","map","getActions","subscribe"],"mappings":"AAAA,MAAMA,aAAa,GAAG;AACrBC,EAAAA,IAAI,EAAE,WADe;;AAErBC,EAAAA,WAAW,CAAEC,QAAF,EAAa;AACvB,UAAMC,mBAAmB,GACtBC,YAAF,IACA,UAAEC,GAAF,EAAoB;AAAA,wCAAVC,IAAU;AAAVA,QAAAA,IAAU;AAAA;;AACnB,aAAOJ,QAAQ,CAACK,MAAT,CAAiBF,GAAjB,EAAwBD,YAAxB,EAAwC,GAAGE,IAA3C,CAAP;AACA,KAJF;;AAMA,UAAME,iBAAiB,GACpBC,UAAF,IACA,UAAEJ,GAAF,EAAoB;AAAA,yCAAVC,IAAU;AAAVA,QAAAA,IAAU;AAAA;;AACnB,aAAOJ,QAAQ,CAACQ,QAAT,CAAmBL,GAAnB,EAA0BI,UAA1B,EAAwC,GAAGH,IAA3C,CAAP;AACA,KAJF;;AAMA,WAAO;AACNK,MAAAA,YAAY,GAAG;AACd,eAAOC,MAAM,CAACC,WAAP,CACN,CACC,gBADD,EAEC,sBAFD,EAGC,uBAHD,EAIC,aAJD,EAKC,oBALD,EAMEC,GANF,CAMSV,YAAF,IAAoB,CAC1BA,YAD0B,EAE1BD,mBAAmB,CAAEC,YAAF,CAFO,CAN3B,CADM,CAAP;AAYA,OAdK;;AAgBNW,MAAAA,UAAU,GAAG;AACZ,eAAOH,MAAM,CAACC,WAAP,CACN,CACC,iBADD,EAEC,kBAFD,EAGC,sBAHD,EAIC,8BAJD,EAKC,sCALD,EAMEC,GANF,CAMSL,UAAF,IAAkB,CACxBA,UADwB,EAExBD,iBAAiB,CAAEC,UAAF,CAFO,CANzB,CADM,CAAP;AAYA,OA7BK;;AA+BNO,MAAAA,SAAS,GAAG;AACX;AACA;AACA;AACA;AACA,eAAO,MAAM,MAAM,CAAE,CAArB;AACA;;AArCK,KAAP;AAuCA;;AAtDoB,CAAtB;AAyDA,eAAejB,aAAf","sourcesContent":["const coreDataStore = {\n\tname: 'core/data',\n\tinstantiate( registry ) {\n\t\tconst getCoreDataSelector =\n\t\t\t( selectorName ) =>\n\t\t\t( key, ...args ) => {\n\t\t\t\treturn registry.select( key )[ selectorName ]( ...args );\n\t\t\t};\n\n\t\tconst getCoreDataAction =\n\t\t\t( actionName ) =>\n\t\t\t( key, ...args ) => {\n\t\t\t\treturn registry.dispatch( key )[ actionName ]( ...args );\n\t\t\t};\n\n\t\treturn {\n\t\t\tgetSelectors() {\n\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t[\n\t\t\t\t\t\t'getIsResolving',\n\t\t\t\t\t\t'hasStartedResolution',\n\t\t\t\t\t\t'hasFinishedResolution',\n\t\t\t\t\t\t'isResolving',\n\t\t\t\t\t\t'getCachedResolvers',\n\t\t\t\t\t].map( ( selectorName ) => [\n\t\t\t\t\t\tselectorName,\n\t\t\t\t\t\tgetCoreDataSelector( selectorName ),\n\t\t\t\t\t] )\n\t\t\t\t);\n\t\t\t},\n\n\t\t\tgetActions() {\n\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t[\n\t\t\t\t\t\t'startResolution',\n\t\t\t\t\t\t'finishResolution',\n\t\t\t\t\t\t'invalidateResolution',\n\t\t\t\t\t\t'invalidateResolutionForStore',\n\t\t\t\t\t\t'invalidateResolutionForStoreSelector',\n\t\t\t\t\t].map( ( actionName ) => [\n\t\t\t\t\t\tactionName,\n\t\t\t\t\t\tgetCoreDataAction( actionName ),\n\t\t\t\t\t] )\n\t\t\t\t);\n\t\t\t},\n\n\t\t\tsubscribe() {\n\t\t\t\t// There's no reasons to trigger any listener when we subscribe to this store\n\t\t\t\t// because there's no state stored in this store that need to retrigger selectors\n\t\t\t\t// if a change happens, the corresponding store where the tracking stated live\n\t\t\t\t// would have already triggered a \"subscribe\" call.\n\t\t\t\treturn () => () => {};\n\t\t\t},\n\t\t};\n\t},\n};\n\nexport default coreDataStore;\n"]}
1
+ {"version":3,"sources":["@wordpress/data/src/store/index.js"],"names":["coreDataStore","name","instantiate","registry","getCoreDataSelector","selectorName","key","args","select","getCoreDataAction","actionName","dispatch","getSelectors","Object","fromEntries","map","getActions","subscribe"],"mappings":"AAAA,MAAMA,aAAa,GAAG;AACrBC,EAAAA,IAAI,EAAE,WADe;;AAErBC,EAAAA,WAAW,CAAEC,QAAF,EAAa;AACvB,UAAMC,mBAAmB,GACtBC,YAAF,IACA,CAAEC,GAAF,EAAO,GAAGC,IAAV,KAAoB;AACnB,aAAOJ,QAAQ,CAACK,MAAT,CAAiBF,GAAjB,EAAwBD,YAAxB,EAAwC,GAAGE,IAA3C,CAAP;AACA,KAJF;;AAMA,UAAME,iBAAiB,GACpBC,UAAF,IACA,CAAEJ,GAAF,EAAO,GAAGC,IAAV,KAAoB;AACnB,aAAOJ,QAAQ,CAACQ,QAAT,CAAmBL,GAAnB,EAA0BI,UAA1B,EAAwC,GAAGH,IAA3C,CAAP;AACA,KAJF;;AAMA,WAAO;AACNK,MAAAA,YAAY,GAAG;AACd,eAAOC,MAAM,CAACC,WAAP,CACN,CACC,gBADD,EAEC,sBAFD,EAGC,uBAHD,EAIC,aAJD,EAKC,oBALD,EAMEC,GANF,CAMSV,YAAF,IAAoB,CAC1BA,YAD0B,EAE1BD,mBAAmB,CAAEC,YAAF,CAFO,CAN3B,CADM,CAAP;AAYA,OAdK;;AAgBNW,MAAAA,UAAU,GAAG;AACZ,eAAOH,MAAM,CAACC,WAAP,CACN,CACC,iBADD,EAEC,kBAFD,EAGC,sBAHD,EAIC,8BAJD,EAKC,sCALD,EAMEC,GANF,CAMSL,UAAF,IAAkB,CACxBA,UADwB,EAExBD,iBAAiB,CAAEC,UAAF,CAFO,CANzB,CADM,CAAP;AAYA,OA7BK;;AA+BNO,MAAAA,SAAS,GAAG;AACX;AACA;AACA;AACA;AACA,eAAO,MAAM,MAAM,CAAE,CAArB;AACA;;AArCK,KAAP;AAuCA;;AAtDoB,CAAtB;AAyDA,eAAejB,aAAf","sourcesContent":["const coreDataStore = {\n\tname: 'core/data',\n\tinstantiate( registry ) {\n\t\tconst getCoreDataSelector =\n\t\t\t( selectorName ) =>\n\t\t\t( key, ...args ) => {\n\t\t\t\treturn registry.select( key )[ selectorName ]( ...args );\n\t\t\t};\n\n\t\tconst getCoreDataAction =\n\t\t\t( actionName ) =>\n\t\t\t( key, ...args ) => {\n\t\t\t\treturn registry.dispatch( key )[ actionName ]( ...args );\n\t\t\t};\n\n\t\treturn {\n\t\t\tgetSelectors() {\n\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t[\n\t\t\t\t\t\t'getIsResolving',\n\t\t\t\t\t\t'hasStartedResolution',\n\t\t\t\t\t\t'hasFinishedResolution',\n\t\t\t\t\t\t'isResolving',\n\t\t\t\t\t\t'getCachedResolvers',\n\t\t\t\t\t].map( ( selectorName ) => [\n\t\t\t\t\t\tselectorName,\n\t\t\t\t\t\tgetCoreDataSelector( selectorName ),\n\t\t\t\t\t] )\n\t\t\t\t);\n\t\t\t},\n\n\t\t\tgetActions() {\n\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t[\n\t\t\t\t\t\t'startResolution',\n\t\t\t\t\t\t'finishResolution',\n\t\t\t\t\t\t'invalidateResolution',\n\t\t\t\t\t\t'invalidateResolutionForStore',\n\t\t\t\t\t\t'invalidateResolutionForStoreSelector',\n\t\t\t\t\t].map( ( actionName ) => [\n\t\t\t\t\t\tactionName,\n\t\t\t\t\t\tgetCoreDataAction( actionName ),\n\t\t\t\t\t] )\n\t\t\t\t);\n\t\t\t},\n\n\t\t\tsubscribe() {\n\t\t\t\t// There's no reasons to trigger any listener when we subscribe to this store\n\t\t\t\t// because there's no state stored in this store that need to retrigger selectors\n\t\t\t\t// if a change happens, the corresponding store where the tracking stated live\n\t\t\t\t// would have already triggered a \"subscribe\" call.\n\t\t\t\treturn () => () => {};\n\t\t\t},\n\t\t};\n\t},\n};\n\nexport default coreDataStore;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redux-store/index.js"],"names":[],"mappings":"AAwGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qGAPW,MAAM,+KAkLhB;2BApRa,OAAO,UAAU,EAAE,YAAY;sEAEhC,OAAO,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;sFAIrC,OAAO,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAC,OAAO,EAAC,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redux-store/index.js"],"names":[],"mappings":"AAuGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qGAPW,MAAM,+KAoLhB;2BArRa,OAAO,UAAU,EAAE,YAAY;sEAEhC,OAAO,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;sFAIrC,OAAO,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAC,OAAO,EAAC,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/redux-store/metadata/selectors.js"],"names":[],"mappings":"AAKA,iEAAiE;AACjE,2DAA2D;AAC3D,mDAAmD;AAEnD;;;;;;;;;;;GAWG;AACH,0CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,UAAU,GAAC,SAAS,CAS/B;AAED;;;;;;;;;;;GAWG;AACH,sCANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,GAAG,SAAS,CAM9B;AAED;;;;;;;;;GASG;AACH,4CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAIlB;AAED;;;;;;;;;GASG;AACH,6CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAKlB;AAED;;;;;;;;;GASG;AACH,2CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAIlB;AAED;;;;;;;;;;GAUG;AACH,0CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,KAAK,GAAC,OAAO,CAKxB;AAED;;;;;;;;;GASG;AACH,mCANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAMlB;AAED;;;;;;GAMG;AACH,0CAJW,KAAK,GAEJ,KAAK,CAIhB;AAED;;;;;;GAMG;AACH,6CAJW,KAAK,GAEJ,OAAO,CAQlB;oBA9Ia,OAAO,MAAM,EAAE,OAAO,WAAW,EAAE,KAAK,CAAC;yBACzC,OAAO,WAAW,EAAE,UAAU;qBAC9B,OAAO,WAAW,EAAE,MAAM"}
1
+ {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/redux-store/metadata/selectors.js"],"names":[],"mappings":"AAKA,iEAAiE;AACjE,2DAA2D;AAC3D,mDAAmD;AAEnD;;;;;;;;;;;GAWG;AACH,0CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,UAAU,GAAC,SAAS,CAS/B;AAED;;;;;;;;;;;GAWG;AACH,sCANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,GAAG,SAAS,CAM9B;AAED;;;;;;;;;GASG;AACH,4CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAIlB;AAED;;;;;;;;;GASG;AACH,6CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAKlB;AAED;;;;;;;;;GASG;AACH,2CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAIlB;AAED;;;;;;;;;;GAUG;AACH,0CANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,KAAK,GAAC,OAAO,CAKxB;AAED;;;;;;;;;GASG;AACH,mCANW,KAAK,gBACL,MAAM,QACN,OAAO,EAAE,UAER,OAAO,CAMlB;AAED;;;;;;GAMG;AACH,0CAJW,KAAK,GAEJ,KAAK,CAIhB;AAED;;;;;;GAMG;AACH,6CAJW,KAAK,GAEJ,OAAO,CAelB;oBArJa,OAAO,MAAM,EAAE,OAAO,WAAW,EAAE,KAAK,CAAC;yBACzC,OAAO,WAAW,EAAE,UAAU;qBAC9B,OAAO,WAAW,EAAE,MAAM"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/data",
3
- "version": "9.3.0",
3
+ "version": "9.5.0",
4
4
  "description": "Data module for WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -29,13 +29,13 @@
29
29
  "sideEffects": false,
30
30
  "dependencies": {
31
31
  "@babel/runtime": "^7.16.0",
32
- "@wordpress/compose": "^6.10.0",
33
- "@wordpress/deprecated": "^3.33.0",
34
- "@wordpress/element": "^5.10.0",
35
- "@wordpress/is-shallow-equal": "^4.33.0",
36
- "@wordpress/priority-queue": "^2.33.0",
37
- "@wordpress/private-apis": "^0.15.0",
38
- "@wordpress/redux-routine": "^4.33.0",
32
+ "@wordpress/compose": "^6.12.0",
33
+ "@wordpress/deprecated": "^3.35.0",
34
+ "@wordpress/element": "^5.12.0",
35
+ "@wordpress/is-shallow-equal": "^4.35.0",
36
+ "@wordpress/priority-queue": "^2.35.0",
37
+ "@wordpress/private-apis": "^0.17.0",
38
+ "@wordpress/redux-routine": "^4.35.0",
39
39
  "deepmerge": "^4.3.0",
40
40
  "equivalent-key-map": "^0.2.2",
41
41
  "is-plain-object": "^5.0.0",
@@ -50,5 +50,5 @@
50
50
  "publishConfig": {
51
51
  "access": "public"
52
52
  },
53
- "gitHead": "e936127e1e13881f1a940b7bd1593a9e500147f3"
53
+ "gitHead": "a92f606309b1541b834ff9b0a76ed2a466fc45ed"
54
54
  }
@@ -54,12 +54,11 @@ const trimUndefinedValues = ( array ) => {
54
54
  * @return {Array} Transformed object.
55
55
  */
56
56
  const mapValues = ( obj, callback ) =>
57
- Object.entries( obj ?? {} ).reduce(
58
- ( acc, [ key, value ] ) => ( {
59
- ...acc,
60
- [ key ]: callback( value, key ),
61
- } ),
62
- {}
57
+ Object.fromEntries(
58
+ Object.entries( obj ?? {} ).map( ( [ key, value ] ) => [
59
+ key,
60
+ callback( value, key ),
61
+ ] )
63
62
  );
64
63
 
65
64
  // Convert Map objects to plain objects
@@ -176,75 +175,77 @@ export default function createReduxStore( key, options ) {
176
175
  lock( store, privateRegistrationFunctions );
177
176
  const resolversCache = createResolversCache();
178
177
 
179
- let resolvers;
180
- const actions = mapActions(
181
- {
182
- ...metadataActions,
183
- ...options.actions,
184
- },
185
- store
186
- );
178
+ function bindAction( action ) {
179
+ return ( ...args ) =>
180
+ Promise.resolve( store.dispatch( action( ...args ) ) );
181
+ }
182
+
183
+ const actions = {
184
+ ...mapValues( metadataActions, bindAction ),
185
+ ...mapValues( options.actions, bindAction ),
186
+ };
187
+
187
188
  lock(
188
189
  actions,
189
190
  new Proxy( privateActions, {
190
191
  get: ( target, prop ) => {
191
- return (
192
- mapActions( privateActions, store )[ prop ] ||
193
- actions[ prop ]
194
- );
192
+ const privateAction = privateActions[ prop ];
193
+ return privateAction
194
+ ? bindAction( privateAction )
195
+ : actions[ prop ];
195
196
  },
196
197
  } )
197
198
  );
198
199
 
199
- let selectors = mapSelectors(
200
- {
201
- ...mapValues(
202
- metadataSelectors,
203
- ( selector ) =>
204
- ( state, ...args ) =>
205
- selector( state.metadata, ...args )
206
- ),
207
- ...mapValues( options.selectors, ( selector ) => {
208
- if ( selector.isRegistrySelector ) {
209
- selector.registry = registry;
210
- }
200
+ function bindSelector( selector ) {
201
+ if ( selector.isRegistrySelector ) {
202
+ selector.registry = registry;
203
+ }
204
+ const boundSelector = ( ...args ) => {
205
+ const state = store.__unstableOriginalGetState();
206
+ return selector( state.root, ...args );
207
+ };
208
+ boundSelector.hasResolver = false;
209
+ return boundSelector;
210
+ }
211
211
 
212
- return ( state, ...args ) =>
213
- selector( state.root, ...args );
214
- } ),
215
- },
216
- store
217
- );
218
- lock(
219
- selectors,
220
- new Proxy( privateSelectors, {
221
- get: ( target, prop ) => {
222
- return (
223
- mapSelectors(
224
- mapValues(
225
- privateSelectors,
226
- ( selector ) =>
227
- ( state, ...args ) =>
228
- selector( state.root, ...args )
229
- ),
230
- store
231
- )[ prop ] || selectors[ prop ]
232
- );
233
- },
234
- } )
235
- );
212
+ function bindMetadataSelector( selector ) {
213
+ const boundSelector = ( ...args ) => {
214
+ const state = store.__unstableOriginalGetState();
215
+ return selector( state.metadata, ...args );
216
+ };
217
+ boundSelector.hasResolver = false;
218
+ return boundSelector;
219
+ }
236
220
 
221
+ let selectors = {
222
+ ...mapValues( metadataSelectors, bindMetadataSelector ),
223
+ ...mapValues( options.selectors, bindSelector ),
224
+ };
225
+
226
+ let resolvers;
237
227
  if ( options.resolvers ) {
238
- const result = mapResolvers(
239
- options.resolvers,
228
+ resolvers = mapResolvers( options.resolvers );
229
+ selectors = mapSelectorsWithResolvers(
240
230
  selectors,
231
+ resolvers,
241
232
  store,
242
233
  resolversCache
243
234
  );
244
- resolvers = result.resolvers;
245
- selectors = result.selectors;
246
235
  }
247
236
 
237
+ lock(
238
+ selectors,
239
+ new Proxy( privateSelectors, {
240
+ get: ( target, prop ) => {
241
+ const privateSelector = privateSelectors[ prop ];
242
+ return privateSelector
243
+ ? bindSelector( privateSelector )
244
+ : selectors[ prop ];
245
+ },
246
+ } )
247
+ );
248
+
248
249
  const resolveSelectors = mapResolveSelectors( selectors, store );
249
250
  const suspendSelectors = mapSuspendSelectors( selectors, store );
250
251
 
@@ -358,59 +359,6 @@ function instantiateReduxStore( key, options, registry, thunkArgs ) {
358
359
  );
359
360
  }
360
361
 
361
- /**
362
- * Maps selectors to a store.
363
- *
364
- * @param {Object} selectors Selectors to register. Keys will be used as the
365
- * public facing API. Selectors will get passed the
366
- * state as first argument.
367
- * @param {Object} store The store to which the selectors should be mapped.
368
- * @return {Object} Selectors mapped to the provided store.
369
- */
370
- function mapSelectors( selectors, store ) {
371
- const createStateSelector = ( registrySelector ) => {
372
- const selector = function runSelector() {
373
- // This function is an optimized implementation of:
374
- //
375
- // selector( store.getState(), ...arguments )
376
- //
377
- // Where the above would incur an `Array#concat` in its application,
378
- // the logic here instead efficiently constructs an arguments array via
379
- // direct assignment.
380
- const argsLength = arguments.length;
381
- const args = new Array( argsLength + 1 );
382
- args[ 0 ] = store.__unstableOriginalGetState();
383
- for ( let i = 0; i < argsLength; i++ ) {
384
- args[ i + 1 ] = arguments[ i ];
385
- }
386
-
387
- return registrySelector( ...args );
388
- };
389
- selector.hasResolver = false;
390
- return selector;
391
- };
392
-
393
- return mapValues( selectors, createStateSelector );
394
- }
395
-
396
- /**
397
- * Maps actions to dispatch from a given store.
398
- *
399
- * @param {Object} actions Actions to register.
400
- * @param {Object} store The redux store to which the actions should be mapped.
401
- *
402
- * @return {Object} Actions mapped to the redux store provided.
403
- */
404
- function mapActions( actions, store ) {
405
- const createBoundAction =
406
- ( action ) =>
407
- ( ...args ) => {
408
- return Promise.resolve( store.dispatch( action( ...args ) ) );
409
- };
410
-
411
- return mapValues( actions, createBoundAction );
412
- }
413
-
414
362
  /**
415
363
  * Maps selectors to functions that return a resolution promise for them
416
364
  *
@@ -517,20 +465,13 @@ function mapSuspendSelectors( selectors, store ) {
517
465
  }
518
466
 
519
467
  /**
520
- * Returns resolvers with matched selectors for a given namespace.
521
- * Resolvers are side effects invoked once per argument set of a given selector call,
522
- * used in ensuring that the data needs for the selector are satisfied.
468
+ * Convert resolvers to a normalized form, an object with `fulfill` method and
469
+ * optional methods like `isFulfilled`.
523
470
  *
524
- * @param {Object} resolvers Resolvers to register.
525
- * @param {Object} selectors The current selectors to be modified.
526
- * @param {Object} store The redux store to which the resolvers should be mapped.
527
- * @param {Object} resolversCache Resolvers Cache.
471
+ * @param {Object} resolvers Resolver to convert
528
472
  */
529
- function mapResolvers( resolvers, selectors, store, resolversCache ) {
530
- // The `resolver` can be either a function that does the resolution, or, in more advanced
531
- // cases, an object with a `fullfill` method and other optional methods like `isFulfilled`.
532
- // Here we normalize the `resolver` function to an object with `fulfill` method.
533
- const mappedResolvers = mapValues( resolvers, ( resolver ) => {
473
+ function mapResolvers( resolvers ) {
474
+ return mapValues( resolvers, ( resolver ) => {
534
475
  if ( resolver.fulfill ) {
535
476
  return resolver;
536
477
  }
@@ -540,99 +481,81 @@ function mapResolvers( resolvers, selectors, store, resolversCache ) {
540
481
  fulfill: resolver, // Add the fulfill method.
541
482
  };
542
483
  } );
484
+ }
543
485
 
544
- const mapSelector = ( selector, selectorName ) => {
545
- const resolver = resolvers[ selectorName ];
546
- if ( ! resolver ) {
547
- selector.hasResolver = false;
548
- return selector;
486
+ /**
487
+ * Returns resolvers with matched selectors for a given namespace.
488
+ * Resolvers are side effects invoked once per argument set of a given selector call,
489
+ * used in ensuring that the data needs for the selector are satisfied.
490
+ *
491
+ * @param {Object} selectors The current selectors to be modified.
492
+ * @param {Object} resolvers Resolvers to register.
493
+ * @param {Object} store The redux store to which the resolvers should be mapped.
494
+ * @param {Object} resolversCache Resolvers Cache.
495
+ */
496
+ function mapSelectorsWithResolvers(
497
+ selectors,
498
+ resolvers,
499
+ store,
500
+ resolversCache
501
+ ) {
502
+ function fulfillSelector( resolver, selectorName, args ) {
503
+ const state = store.getState();
504
+
505
+ if (
506
+ resolversCache.isRunning( selectorName, args ) ||
507
+ ( typeof resolver.isFulfilled === 'function' &&
508
+ resolver.isFulfilled( state, ...args ) )
509
+ ) {
510
+ return;
549
511
  }
550
512
 
551
- const selectorResolver = ( ...args ) => {
552
- async function fulfillSelector() {
553
- const state = store.getState();
554
-
555
- if (
556
- resolversCache.isRunning( selectorName, args ) ||
557
- ( typeof resolver.isFulfilled === 'function' &&
558
- resolver.isFulfilled( state, ...args ) )
559
- ) {
560
- return;
561
- }
562
-
563
- const { metadata } = store.__unstableOriginalGetState();
513
+ const { metadata } = store.__unstableOriginalGetState();
564
514
 
565
- if (
566
- metadataSelectors.hasStartedResolution(
567
- metadata,
568
- selectorName,
569
- args
570
- )
571
- ) {
572
- return;
573
- }
515
+ if (
516
+ metadataSelectors.hasStartedResolution(
517
+ metadata,
518
+ selectorName,
519
+ args
520
+ )
521
+ ) {
522
+ return;
523
+ }
574
524
 
575
- resolversCache.markAsRunning( selectorName, args );
525
+ resolversCache.markAsRunning( selectorName, args );
576
526
 
577
- setTimeout( async () => {
578
- resolversCache.clear( selectorName, args );
579
- store.dispatch(
580
- metadataActions.startResolution( selectorName, args )
581
- );
582
- try {
583
- await fulfillResolver(
584
- store,
585
- mappedResolvers,
586
- selectorName,
587
- ...args
588
- );
589
- store.dispatch(
590
- metadataActions.finishResolution(
591
- selectorName,
592
- args
593
- )
594
- );
595
- } catch ( error ) {
596
- store.dispatch(
597
- metadataActions.failResolution(
598
- selectorName,
599
- args,
600
- error
601
- )
602
- );
603
- }
604
- } );
527
+ setTimeout( async () => {
528
+ resolversCache.clear( selectorName, args );
529
+ store.dispatch(
530
+ metadataActions.startResolution( selectorName, args )
531
+ );
532
+ try {
533
+ const action = resolver.fulfill( ...args );
534
+ if ( action ) {
535
+ await store.dispatch( action );
536
+ }
537
+ store.dispatch(
538
+ metadataActions.finishResolution( selectorName, args )
539
+ );
540
+ } catch ( error ) {
541
+ store.dispatch(
542
+ metadataActions.failResolution( selectorName, args, error )
543
+ );
605
544
  }
545
+ }, 0 );
546
+ }
547
+
548
+ return mapValues( selectors, ( selector, selectorName ) => {
549
+ const resolver = resolvers[ selectorName ];
550
+ if ( ! resolver ) {
551
+ return selector;
552
+ }
606
553
 
607
- fulfillSelector( ...args );
554
+ const selectorResolver = ( ...args ) => {
555
+ fulfillSelector( resolver, selectorName, args );
608
556
  return selector( ...args );
609
557
  };
610
558
  selectorResolver.hasResolver = true;
611
559
  return selectorResolver;
612
- };
613
-
614
- return {
615
- resolvers: mappedResolvers,
616
- selectors: mapValues( selectors, mapSelector ),
617
- };
618
- }
619
-
620
- /**
621
- * Calls a resolver given arguments
622
- *
623
- * @param {Object} store Store reference, for fulfilling via resolvers
624
- * @param {Object} resolvers Store Resolvers
625
- * @param {string} selectorName Selector name to fulfill.
626
- * @param {Array} args Selector Arguments.
627
- */
628
- async function fulfillResolver( store, resolvers, selectorName, ...args ) {
629
- const resolver = resolvers[ selectorName ];
630
- if ( ! resolver ) {
631
- return;
632
- }
633
-
634
- const action = resolver.fulfill( ...args );
635
- if ( action ) {
636
- await store.dispatch( action );
637
- }
560
+ } );
638
561
  }
@@ -140,8 +140,15 @@ export function getCachedResolvers( state ) {
140
140
  * @return {boolean} True if one or more selectors are resolving, false otherwise.
141
141
  */
142
142
  export function hasResolvingSelectors( state ) {
143
- return [ ...Object.values( state ) ].some( ( selectorState ) =>
144
- [ ...selectorState._map.values() ].some(
143
+ return Object.values( state ).some( ( selectorState ) =>
144
+ /**
145
+ * This uses the internal `_map` property of `EquivalentKeyMap` for
146
+ * optimization purposes, since the `EquivalentKeyMap` implementation
147
+ * does not support a `.values()` implementation.
148
+ *
149
+ * @see https://github.com/aduth/equivalent-key-map
150
+ */
151
+ Array.from( selectorState._map.values() ).some(
145
152
  ( resolution ) => resolution[ 1 ]?.status === 'resolving'
146
153
  )
147
154
  );
@@ -96,6 +96,37 @@ describe( 'Private data APIs', () => {
96
96
  );
97
97
  } );
98
98
 
99
+ it( 'should support combination of private selectors and resolvers', async () => {
100
+ const testStore = createReduxStore( 'test', {
101
+ reducer: ( state = {}, action ) => {
102
+ if ( action.type === 'RECEIVE' ) {
103
+ return { ...state, [ action.key ]: action.value };
104
+ }
105
+ return state;
106
+ },
107
+ selectors: {
108
+ get: ( state, key ) => state[ key ],
109
+ },
110
+ resolvers: {
111
+ get:
112
+ ( key ) =>
113
+ async ( { dispatch } ) => {
114
+ const value = await ( 'resolved-' + key );
115
+ dispatch( { type: 'RECEIVE', key, value } );
116
+ },
117
+ },
118
+ } );
119
+ unlock( testStore ).registerPrivateSelectors( {
120
+ peek: ( state, key ) => state[ key ],
121
+ } );
122
+ registry.register( testStore );
123
+
124
+ await registry.resolveSelect( testStore ).get( 'x' );
125
+ expect( unlock( registry.select( testStore ) ).peek( 'x' ) ).toBe(
126
+ 'resolved-x'
127
+ );
128
+ } );
129
+
99
130
  it( 'should give private selectors access to the state', () => {
100
131
  const groceryStore = createStore();
101
132
  unlock( groceryStore ).registerPrivateSelectors( {