@data-client/core 0.14.24 → 0.15.0-beta-20251022142546-a457d1596871fb28f1a91f2531cc259db4d55a9c

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 (60) hide show
  1. package/CHANGELOG.md +1174 -0
  2. package/README.md +2 -2
  3. package/dist/index.js +100 -97
  4. package/dist/index.umd.min.js +1 -1
  5. package/legacy/controller/Controller.js +31 -46
  6. package/legacy/index.js +1 -1
  7. package/legacy/manager/NetworkManager.js +44 -33
  8. package/legacy/state/GCPolicy.js +20 -12
  9. package/legacy/state/reducer/createReducer.js +4 -4
  10. package/legacy/state/reducer/setReducer.js +3 -3
  11. package/legacy/state/reducer/setResponseReducer.js +4 -4
  12. package/legacy/types.js +1 -1
  13. package/lib/controller/Controller.d.ts +3 -3
  14. package/lib/controller/Controller.d.ts.map +1 -1
  15. package/lib/controller/Controller.js +31 -46
  16. package/lib/index.d.ts +2 -1
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +1 -1
  19. package/lib/manager/NetworkManager.d.ts +7 -12
  20. package/lib/manager/NetworkManager.d.ts.map +1 -1
  21. package/lib/manager/NetworkManager.js +44 -34
  22. package/lib/state/GCPolicy.d.ts.map +1 -1
  23. package/lib/state/GCPolicy.js +20 -12
  24. package/lib/state/reducer/createReducer.js +4 -4
  25. package/lib/state/reducer/expireReducer.d.ts +1 -1
  26. package/lib/state/reducer/invalidateReducer.d.ts +1 -1
  27. package/lib/state/reducer/setReducer.d.ts +1 -1
  28. package/lib/state/reducer/setReducer.js +3 -3
  29. package/lib/state/reducer/setResponseReducer.d.ts +1 -1
  30. package/lib/state/reducer/setResponseReducer.js +4 -4
  31. package/lib/types.d.ts +1 -1
  32. package/lib/types.d.ts.map +1 -1
  33. package/lib/types.js +1 -1
  34. package/package.json +6 -6
  35. package/src/controller/Controller.ts +38 -80
  36. package/src/controller/__tests__/Controller.ts +2 -2
  37. package/src/controller/__tests__/__snapshots__/get.ts.snap +34 -8
  38. package/src/controller/__tests__/__snapshots__/getResponse.ts.snap +1 -1
  39. package/src/controller/__tests__/get.ts +163 -22
  40. package/src/controller/__tests__/getResponse.ts +1 -1
  41. package/src/index.ts +4 -0
  42. package/src/manager/NetworkManager.ts +46 -32
  43. package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +1 -1
  44. package/src/manager/__tests__/pollingSubscription.ts +9 -5
  45. package/src/state/GCPolicy.ts +12 -10
  46. package/src/state/__tests__/GCPolicy.test.ts +6 -6
  47. package/src/state/__tests__/__snapshots__/reducer.ts.snap +3 -3
  48. package/src/state/__tests__/reducer.ts +17 -9
  49. package/src/state/reducer/createReducer.ts +2 -2
  50. package/src/state/reducer/setReducer.ts +2 -2
  51. package/src/state/reducer/setResponseReducer.ts +3 -3
  52. package/src/types.ts +1 -1
  53. package/ts3.4/controller/Controller.d.ts +3 -3
  54. package/ts3.4/index.d.ts +2 -1
  55. package/ts3.4/manager/NetworkManager.d.ts +7 -12
  56. package/ts3.4/state/reducer/expireReducer.d.ts +1 -1
  57. package/ts3.4/state/reducer/invalidateReducer.d.ts +1 -1
  58. package/ts3.4/state/reducer/setReducer.d.ts +1 -1
  59. package/ts3.4/state/reducer/setResponseReducer.d.ts +1 -1
  60. package/ts3.4/types.d.ts +1 -1
package/lib/types.d.ts CHANGED
@@ -31,7 +31,7 @@ export interface State<T> {
31
31
  readonly errorPolicy?: 'hard' | 'soft' | undefined;
32
32
  };
33
33
  };
34
- readonly entityMeta: {
34
+ readonly entitiesMeta: {
35
35
  readonly [entityKey: string]: {
36
36
  readonly [pk: string]: {
37
37
  readonly fetchedAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhF,cAAc,cAAc,CAAC;AAE7B,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,CAAC;AAErD,MAAM,MAAM,EAAE,GAAG,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG;YAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,CAAA;SAAE,GAAG,SAAS,CAAC;KACxE,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;KACzD,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG;YACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;YAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;YAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;YAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;SACpD,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG;YAC5B,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG;gBACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;aAC5B,CAAC;SACH,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,EAAE,CAAC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,GAAG,WAAW;IAC5C,gEAAgE;IAChE,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAC;IAChB,uDAAuD;IACvD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CACpC;AAED,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhF,cAAc,cAAc,CAAC;AAE7B,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,CAAC;AAErD,MAAM,MAAM,EAAE,GAAG,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG;YAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,CAAA;SAAE,GAAG,SAAS,CAAC;KACxE,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;KACzD,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG;YACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;YAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;YAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;YAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;SACpD,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG;YAC5B,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG;gBACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;aAC5B,CAAC;SACH,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,EAAE,CAAC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,GAAG,WAAW;IAC5C,gEAAgE;IAChE,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAC;IAChB,uDAAuD;IACvD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CACpC;AAED,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC"}
package/lib/types.js CHANGED
@@ -12,4 +12,4 @@ export * from './actions.js';
12
12
  * @see https://dataclient.io/docs/api/Manager
13
13
  */
14
14
  export {};
15
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vcm1hbGl6ZWRJbmRleCB9IGZyb20gJ0BkYXRhLWNsaWVudC9ub3JtYWxpenInO1xuaW1wb3J0IHR5cGUge1xuICBVcGRhdGVGdW5jdGlvbixcbiAgQWJzdHJhY3RJbnN0YW5jZVR5cGUsXG59IGZyb20gJ0BkYXRhLWNsaWVudC9ub3JtYWxpenInO1xuaW1wb3J0IHR5cGUgeyBFcnJvclR5cGVzIH0gZnJvbSAnQGRhdGEtY2xpZW50L25vcm1hbGl6cic7XG5cbmltcG9ydCB0eXBlIHtcbiAgQWN0aW9uVHlwZXMsXG4gIFNldFJlc3BvbnNlQWN0aW9uLFxuICBPcHRpbWlzdGljQWN0aW9uLFxufSBmcm9tICcuL2FjdGlvbnMuanMnO1xuaW1wb3J0IHR5cGUgeyBEaXNwYXRjaCwgTWlkZGxld2FyZSwgTWlkZGxld2FyZUFQSSB9IGZyb20gJy4vbWlkZGxld2FyZVR5cGVzLmpzJztcblxuZXhwb3J0ICogZnJvbSAnLi9hY3Rpb25zLmpzJztcblxuZXhwb3J0IHR5cGUgeyBBYnN0cmFjdEluc3RhbmNlVHlwZSwgVXBkYXRlRnVuY3Rpb24gfTtcblxuZXhwb3J0IHR5cGUgUEsgPSBzdHJpbmc7XG5cbi8qKiBOb3JtYWxpemVkIHN0YXRlIGZvciBSZWFjdGl2ZSBEYXRhIENsaWVudFxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvY29uY2VwdHMvbm9ybWFsaXphdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlPFQ+IHtcbiAgcmVhZG9ubHkgZW50aXRpZXM6IHtcbiAgICByZWFkb25seSBbZW50aXR5S2V5OiBzdHJpbmddOiB7IHJlYWRvbmx5IFtwazogc3RyaW5nXTogVCB9IHwgdW5kZWZpbmVkO1xuICB9O1xuICByZWFkb25seSBlbmRwb2ludHM6IHtcbiAgICByZWFkb25seSBba2V5OiBzdHJpbmddOiB1bmtub3duIHwgUEtbXSB8IFBLIHwgdW5kZWZpbmVkO1xuICB9O1xuICByZWFkb25seSBpbmRleGVzOiBOb3JtYWxpemVkSW5kZXg7XG4gIHJlYWRvbmx5IG1ldGE6IHtcbiAgICByZWFkb25seSBba2V5OiBzdHJpbmddOiB7XG4gICAgICByZWFkb25seSBkYXRlOiBudW1iZXI7XG4gICAgICByZWFkb25seSBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgICAgIHJlYWRvbmx5IGV4cGlyZXNBdDogbnVtYmVyO1xuICAgICAgcmVhZG9ubHkgcHJldkV4cGlyZXNBdD86IG51bWJlcjtcbiAgICAgIHJlYWRvbmx5IGVycm9yPzogRXJyb3JUeXBlcztcbiAgICAgIHJlYWRvbmx5IGludmFsaWRhdGVkPzogYm9vbGVhbjtcbiAgICAgIHJlYWRvbmx5IGVycm9yUG9saWN5PzogJ2hhcmQnIHwgJ3NvZnQnIHwgdW5kZWZpbmVkO1xuICAgIH07XG4gIH07XG4gIHJlYWRvbmx5IGVudGl0eU1ldGE6IHtcbiAgICByZWFkb25seSBbZW50aXR5S2V5OiBzdHJpbmddOiB7XG4gICAgICByZWFkb25seSBbcGs6IHN0cmluZ106IHtcbiAgICAgICAgcmVhZG9ubHkgZmV0Y2hlZEF0OiBudW1iZXI7XG4gICAgICAgIHJlYWRvbmx5IGRhdGU6IG51bWJlcjtcbiAgICAgICAgcmVhZG9ubHkgZXhwaXJlc0F0OiBudW1iZXI7XG4gICAgICB9O1xuICAgIH07XG4gIH07XG4gIHJlYWRvbmx5IG9wdGltaXN0aWM6IChTZXRSZXNwb25zZUFjdGlvbiB8IE9wdGltaXN0aWNBY3Rpb24pW107XG4gIHJlYWRvbmx5IGxhc3RSZXNldDogbnVtYmVyO1xufVxuXG4vKiogU2luZ2xldG9ucyB0aGF0IGhhbmRsZSBnbG9iYWwgc2lkZS1lZmZlY3RzXG4gKlxuICogS2luZCBvZiBsaWtlIHVzZUVmZmVjdCgpIGZvciB0aGUgY2VudHJhbCBkYXRhIHN0b3JlXG4gKlxuICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vZG9jcy9hcGkvTWFuYWdlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1hbmFnZXI8QWN0aW9ucyA9IEFjdGlvblR5cGVzPiB7XG4gIC8qKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9kb2NzL2FwaS9NYW5hZ2VyI2dldG1pZGRsZXdhcmUgKi9cbiAgZ2V0TWlkZGxld2FyZT8oKTogTWlkZGxld2FyZTxBY3Rpb25zPjtcbiAgLyoqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvYXBpL01hbmFnZXIjbWlkZGxld2FyZSAqL1xuICBtaWRkbGV3YXJlPzogTWlkZGxld2FyZTxBY3Rpb25zPjtcbiAgLyoqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvYXBpL01hbmFnZXIjY2xlYW51cCAqL1xuICBjbGVhbnVwKCk6IHZvaWQ7XG4gIC8qKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9kb2NzL2FwaS9NYW5hZ2VyI2luaXQgKi9cbiAgaW5pdD86IChzdGF0ZTogU3RhdGU8YW55PikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUgeyBEaXNwYXRjaCwgTWlkZGxld2FyZSwgTWlkZGxld2FyZUFQSSB9O1xuIl0sIm1hcHBpbmdzIjoiQUFjQSxjQUFjLGNBQWM7O0FBTTVCO0FBQ0E7QUFDQTtBQUNBOztBQWlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQSIsImlnbm9yZUxpc3QiOltdfQ==
15
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vcm1hbGl6ZWRJbmRleCB9IGZyb20gJ0BkYXRhLWNsaWVudC9ub3JtYWxpenInO1xuaW1wb3J0IHR5cGUge1xuICBVcGRhdGVGdW5jdGlvbixcbiAgQWJzdHJhY3RJbnN0YW5jZVR5cGUsXG59IGZyb20gJ0BkYXRhLWNsaWVudC9ub3JtYWxpenInO1xuaW1wb3J0IHR5cGUgeyBFcnJvclR5cGVzIH0gZnJvbSAnQGRhdGEtY2xpZW50L25vcm1hbGl6cic7XG5cbmltcG9ydCB0eXBlIHtcbiAgQWN0aW9uVHlwZXMsXG4gIFNldFJlc3BvbnNlQWN0aW9uLFxuICBPcHRpbWlzdGljQWN0aW9uLFxufSBmcm9tICcuL2FjdGlvbnMuanMnO1xuaW1wb3J0IHR5cGUgeyBEaXNwYXRjaCwgTWlkZGxld2FyZSwgTWlkZGxld2FyZUFQSSB9IGZyb20gJy4vbWlkZGxld2FyZVR5cGVzLmpzJztcblxuZXhwb3J0ICogZnJvbSAnLi9hY3Rpb25zLmpzJztcblxuZXhwb3J0IHR5cGUgeyBBYnN0cmFjdEluc3RhbmNlVHlwZSwgVXBkYXRlRnVuY3Rpb24gfTtcblxuZXhwb3J0IHR5cGUgUEsgPSBzdHJpbmc7XG5cbi8qKiBOb3JtYWxpemVkIHN0YXRlIGZvciBSZWFjdGl2ZSBEYXRhIENsaWVudFxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvY29uY2VwdHMvbm9ybWFsaXphdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlPFQ+IHtcbiAgcmVhZG9ubHkgZW50aXRpZXM6IHtcbiAgICByZWFkb25seSBbZW50aXR5S2V5OiBzdHJpbmddOiB7IHJlYWRvbmx5IFtwazogc3RyaW5nXTogVCB9IHwgdW5kZWZpbmVkO1xuICB9O1xuICByZWFkb25seSBlbmRwb2ludHM6IHtcbiAgICByZWFkb25seSBba2V5OiBzdHJpbmddOiB1bmtub3duIHwgUEtbXSB8IFBLIHwgdW5kZWZpbmVkO1xuICB9O1xuICByZWFkb25seSBpbmRleGVzOiBOb3JtYWxpemVkSW5kZXg7XG4gIHJlYWRvbmx5IG1ldGE6IHtcbiAgICByZWFkb25seSBba2V5OiBzdHJpbmddOiB7XG4gICAgICByZWFkb25seSBkYXRlOiBudW1iZXI7XG4gICAgICByZWFkb25seSBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgICAgIHJlYWRvbmx5IGV4cGlyZXNBdDogbnVtYmVyO1xuICAgICAgcmVhZG9ubHkgcHJldkV4cGlyZXNBdD86IG51bWJlcjtcbiAgICAgIHJlYWRvbmx5IGVycm9yPzogRXJyb3JUeXBlcztcbiAgICAgIHJlYWRvbmx5IGludmFsaWRhdGVkPzogYm9vbGVhbjtcbiAgICAgIHJlYWRvbmx5IGVycm9yUG9saWN5PzogJ2hhcmQnIHwgJ3NvZnQnIHwgdW5kZWZpbmVkO1xuICAgIH07XG4gIH07XG4gIHJlYWRvbmx5IGVudGl0aWVzTWV0YToge1xuICAgIHJlYWRvbmx5IFtlbnRpdHlLZXk6IHN0cmluZ106IHtcbiAgICAgIHJlYWRvbmx5IFtwazogc3RyaW5nXToge1xuICAgICAgICByZWFkb25seSBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgICAgICAgcmVhZG9ubHkgZGF0ZTogbnVtYmVyO1xuICAgICAgICByZWFkb25seSBleHBpcmVzQXQ6IG51bWJlcjtcbiAgICAgIH07XG4gICAgfTtcbiAgfTtcbiAgcmVhZG9ubHkgb3B0aW1pc3RpYzogKFNldFJlc3BvbnNlQWN0aW9uIHwgT3B0aW1pc3RpY0FjdGlvbilbXTtcbiAgcmVhZG9ubHkgbGFzdFJlc2V0OiBudW1iZXI7XG59XG5cbi8qKiBTaW5nbGV0b25zIHRoYXQgaGFuZGxlIGdsb2JhbCBzaWRlLWVmZmVjdHNcbiAqXG4gKiBLaW5kIG9mIGxpa2UgdXNlRWZmZWN0KCkgZm9yIHRoZSBjZW50cmFsIGRhdGEgc3RvcmVcbiAqXG4gKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9kb2NzL2FwaS9NYW5hZ2VyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuYWdlcjxBY3Rpb25zID0gQWN0aW9uVHlwZXM+IHtcbiAgLyoqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvYXBpL01hbmFnZXIjZ2V0bWlkZGxld2FyZSAqL1xuICBnZXRNaWRkbGV3YXJlPygpOiBNaWRkbGV3YXJlPEFjdGlvbnM+O1xuICAvKiogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vZG9jcy9hcGkvTWFuYWdlciNtaWRkbGV3YXJlICovXG4gIG1pZGRsZXdhcmU/OiBNaWRkbGV3YXJlPEFjdGlvbnM+O1xuICAvKiogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vZG9jcy9hcGkvTWFuYWdlciNjbGVhbnVwICovXG4gIGNsZWFudXAoKTogdm9pZDtcbiAgLyoqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL2RvY3MvYXBpL01hbmFnZXIjaW5pdCAqL1xuICBpbml0PzogKHN0YXRlOiBTdGF0ZTxhbnk+KSA9PiB2b2lkO1xufVxuXG5leHBvcnQgdHlwZSB7IERpc3BhdGNoLCBNaWRkbGV3YXJlLCBNaWRkbGV3YXJlQVBJIH07XG4iXSwibWFwcGluZ3MiOiJBQWNBLGNBQWMsY0FBYzs7QUFNNUI7QUFDQTtBQUNBO0FBQ0E7O0FBaUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBIiwiaWdub3JlTGlzdCI6W119
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-client/core",
3
- "version": "0.14.24",
3
+ "version": "0.15.0-beta-20251022142546-a457d1596871fb28f1a91f2531cc259db4d55a9c",
4
4
  "description": "Async State Management without the Management. REST, GraphQL, SSE, Websockets, Fetch",
5
5
  "sideEffects": false,
6
6
  "main": "dist/index.js",
@@ -125,14 +125,14 @@
125
125
  },
126
126
  "dependencies": {
127
127
  "@babel/runtime": "^7.20.0",
128
- "@data-client/normalizr": "^0.14.22",
128
+ "@data-client/normalizr": "^0.15.0-beta-20251006024044-92bd01c4976f2921993b8c9f1e4dbb87af87ba7b",
129
129
  "flux-standard-action": "^2.1.1"
130
130
  },
131
131
  "devDependencies": {
132
132
  "@anansi/browserslist-config": "^1.4.2",
133
- "@data-client/endpoint": "workspace:*",
134
- "@types/jest": "^29.5.14",
133
+ "@data-client/endpoint": "0.15.0-beta-20251022010821-0e5f6bd2963b6deecb68b5febe71cdd3b10c801a",
134
+ "@types/jest": "30.0.0",
135
135
  "@types/node": "^22.0.0",
136
- "rollup-plugins": "workspace:*"
136
+ "rollup-plugins": "1.0.0"
137
137
  }
138
- }
138
+ }
@@ -172,7 +172,7 @@ export default class Controller<
172
172
  ...args: readonly [...Parameters<E>]
173
173
  ): E['schema'] extends undefined | null ? ReturnType<E> | ResolveType<E>
174
174
  : Promise<Denormalize<E['schema']>> | Denormalize<E['schema']> => {
175
- const { data, expiresAt, expiryStatus } = this.getResponse(
175
+ const { data, expiresAt, expiryStatus } = this.getResponseMeta(
176
176
  endpoint,
177
177
  ...args,
178
178
  this.getState(),
@@ -514,13 +514,7 @@ export default class Controller<
514
514
  const input =
515
515
  shouldQuery ?
516
516
  // nothing in endpoints cache, so try querying if we have a schema to do so
517
- this.memo.buildQueryKey(
518
- schema,
519
- args,
520
- state.entities as any,
521
- state.indexes,
522
- key,
523
- )
517
+ this.memo.buildQueryKey(schema, args, state, key)
524
518
  : cacheEndpoints;
525
519
 
526
520
  if (!isActive) {
@@ -540,17 +534,16 @@ export default class Controller<
540
534
  } else if (!schema || !schemaHasEntity(schema)) {
541
535
  return {
542
536
  data: cacheEndpoints,
543
- expiryStatus:
544
- meta?.invalidated ? ExpiryStatus.Invalid
545
- : cacheEndpoints && !endpoint.invalidIfStale ? ExpiryStatus.Valid
546
- : ExpiryStatus.InvalidIfStale,
537
+ expiryStatus: this.getExpiryStatus(
538
+ !cacheEndpoints,
539
+ !!endpoint.invalidIfStale,
540
+ meta,
541
+ ),
547
542
  expiresAt: expiresAt || 0,
548
543
  countRef: this.gcPolicy.createCountRef({ key }),
549
544
  };
550
545
  }
551
546
 
552
- // second argument is false if any entities are missing
553
-
554
547
  const { data, paths } = this.memo.denormalize(
555
548
  schema,
556
549
  input,
@@ -558,18 +551,23 @@ export default class Controller<
558
551
  args,
559
552
  ) as { data: any; paths: EntityPath[] };
560
553
 
561
- // note: isInvalid can only be true if shouldQuery is true
562
- if (!expiresAt && isInvalid) expiresAt = 1;
554
+ if (!expiresAt) {
555
+ // note: isInvalid can only be true if shouldQuery is true
556
+ if (isInvalid) expiresAt = 1;
557
+ // fallback to entity expiry time
558
+ else expiresAt = entityExpiresAt(paths, state.entitiesMeta);
559
+ }
563
560
 
564
- return this.getSchemaResponse(
561
+ return {
565
562
  data,
566
- key,
567
- paths,
568
- state.entityMeta,
563
+ expiryStatus: this.getExpiryStatus(
564
+ typeof data === 'symbol',
565
+ !!endpoint.invalidIfStale || isInvalid,
566
+ meta,
567
+ ),
569
568
  expiresAt,
570
- endpoint.invalidIfStale || isInvalid,
571
- meta,
572
- );
569
+ countRef: this.gcPolicy.createCountRef({ key, paths }),
570
+ };
573
571
  }
574
572
 
575
573
  /**
@@ -580,7 +578,7 @@ export default class Controller<
580
578
  schema: S,
581
579
  ...rest: readonly [
582
580
  ...SchemaArgs<S>,
583
- Pick<State<unknown>, 'entities' | 'entityMeta'>,
581
+ Pick<State<unknown>, 'entities' | 'indexes'>,
584
582
  ]
585
583
  ): DenormalizeNullable<S> | undefined {
586
584
  const state = rest[rest.length - 1] as State<any>;
@@ -589,7 +587,8 @@ export default class Controller<
589
587
  .slice(0, rest.length - 1)
590
588
  .map(ensurePojo) as SchemaArgs<S>;
591
589
 
592
- return this.memo.query(schema, args, state.entities as any, state.indexes);
590
+ const { data } = this.memo.query(schema, args, state);
591
+ return typeof data === 'symbol' ? undefined : data;
593
592
  }
594
593
 
595
594
  /**
@@ -600,7 +599,7 @@ export default class Controller<
600
599
  schema: S,
601
600
  ...rest: readonly [
602
601
  ...SchemaArgs<S>,
603
- Pick<State<unknown>, 'entities' | 'entityMeta'>,
602
+ Pick<State<unknown>, 'entities' | 'indexes'>,
604
603
  ]
605
604
  ): {
606
605
  data: DenormalizeNullable<S> | undefined;
@@ -612,68 +611,27 @@ export default class Controller<
612
611
  .slice(0, rest.length - 1)
613
612
  .map(ensurePojo) as SchemaArgs<S>;
614
613
 
615
- // TODO: breaking: Switch back to this.memo.query(schema, args, state.entities as any, state.indexes) to do
616
- // this logic
617
- const input = this.memo.buildQueryKey(
618
- schema,
619
- args,
620
- state.entities as any,
621
- state.indexes,
622
- JSON.stringify(args),
623
- );
624
-
625
- if (!input) {
626
- return { data: undefined, countRef: () => () => undefined };
627
- }
614
+ const { data, paths } = this.memo.query(schema, args, state);
628
615
 
629
- const { data, paths } = this.memo.denormalize(
630
- schema,
631
- input,
632
- state.entities,
633
- args,
634
- );
635
616
  return {
636
- data: typeof data === 'symbol' ? undefined : (data as any),
617
+ data: typeof data === 'symbol' ? undefined : data,
637
618
  countRef: this.gcPolicy.createCountRef({ paths }),
638
619
  };
639
620
  }
640
621
 
641
- private getSchemaResponse<T>(
642
- data: T,
643
- key: string,
644
- paths: EntityPath[],
645
- entityMeta: State<unknown>['entityMeta'],
646
- expiresAt: number,
622
+ private getExpiryStatus(
623
+ invalidData: boolean,
647
624
  invalidIfStale: boolean,
648
625
  meta: { error?: unknown; invalidated?: unknown } = {},
649
- ): {
650
- data: T;
651
- expiryStatus: ExpiryStatus;
652
- expiresAt: number;
653
- countRef: () => () => void;
654
- } {
655
- const invalidDenormalize = typeof data === 'symbol';
656
-
657
- // fallback to entity expiry time
658
- if (!expiresAt) {
659
- expiresAt = entityExpiresAt(paths, entityMeta);
660
- }
661
-
626
+ ) {
662
627
  // https://dataclient.io/docs/concepts/expiry-policy#expiry-status
663
628
  // we don't track the difference between stale or fresh because that is tied to triggering
664
629
  // conditions
665
- const expiryStatus =
666
- meta?.invalidated || (invalidDenormalize && !meta?.error) ?
667
- ExpiryStatus.Invalid
668
- : invalidDenormalize || invalidIfStale ? ExpiryStatus.InvalidIfStale
669
- : ExpiryStatus.Valid;
670
-
671
- return {
672
- data,
673
- expiryStatus,
674
- expiresAt,
675
- countRef: this.gcPolicy.createCountRef({ key, paths }),
676
- };
630
+ return (
631
+ meta.invalidated || (invalidData && !meta.error) ? ExpiryStatus.Invalid
632
+ : invalidData || invalidIfStale ? ExpiryStatus.InvalidIfStale
633
+ : ExpiryStatus.Valid
634
+ );
677
635
  }
678
636
  }
679
637
 
@@ -681,7 +639,7 @@ export default class Controller<
681
639
  // earliest expiry dictates age
682
640
  function entityExpiresAt(
683
641
  paths: EntityPath[],
684
- entityMeta: {
642
+ entitiesMeta: {
685
643
  readonly [entityKey: string]: {
686
644
  readonly [pk: string]: {
687
645
  readonly date: number;
@@ -692,8 +650,8 @@ function entityExpiresAt(
692
650
  },
693
651
  ) {
694
652
  let expiresAt = Infinity;
695
- for (const { pk, key } of paths) {
696
- const entityExpiry = entityMeta[key]?.[pk]?.expiresAt;
653
+ for (const { key, pk } of paths) {
654
+ const entityExpiry = entitiesMeta[key]?.[pk]?.expiresAt;
697
655
  // expiresAt will always resolve to false with any comparison
698
656
  if (entityExpiry < expiresAt) expiresAt = entityExpiry;
699
657
  }
@@ -46,7 +46,7 @@ describe('Controller', () => {
46
46
  endpoints: {
47
47
  [fetchKey]: result,
48
48
  },
49
- entityMeta: createEntityMeta(entities),
49
+ entitiesMeta: createEntityMeta(entities),
50
50
  meta: {
51
51
  [fetchKey]: {
52
52
  date: Date.now(),
@@ -85,7 +85,7 @@ describe('Controller', () => {
85
85
  endpoints: {
86
86
  [fetchKey]: result,
87
87
  },
88
- entityMeta: createEntityMeta(entities),
88
+ entitiesMeta: createEntityMeta(entities),
89
89
  meta: {
90
90
  [fetchKey]: {
91
91
  date: 0,
@@ -1,4 +1,4 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
3
  exports[`Controller.get() Query+All based on args 1`] = `
4
4
  [
@@ -53,6 +53,39 @@ Group {
53
53
  }
54
54
  `;
55
55
 
56
+ exports[`Controller.get() Union based on args with function schemaAttribute 1`] = `
57
+ User {
58
+ "id": "1",
59
+ "type": "users",
60
+ "username": "bob",
61
+ }
62
+ `;
63
+
64
+ exports[`Controller.get() Union based on args with function schemaAttribute 2`] = `
65
+ Group {
66
+ "groupname": "fast",
67
+ "id": "2",
68
+ "memberCount": 5,
69
+ "type": "groups",
70
+ }
71
+ `;
72
+
73
+ exports[`Controller.get() indexes query Entity based on index 1`] = `
74
+ User {
75
+ "id": "1",
76
+ "staff": false,
77
+ "username": "bob",
78
+ }
79
+ `;
80
+
81
+ exports[`Controller.get() indexes query indexes after empty state 1`] = `
82
+ User {
83
+ "id": "1",
84
+ "staff": false,
85
+ "username": "bob",
86
+ }
87
+ `;
88
+
56
89
  exports[`Controller.get() query All should get all entities 1`] = `
57
90
  [
58
91
  Tacos {
@@ -105,13 +138,6 @@ exports[`Controller.get() query Collection based on args 2`] = `
105
138
  ]
106
139
  `;
107
140
 
108
- exports[`Controller.get() query Entity based on index 1`] = `
109
- User {
110
- "id": "1",
111
- "username": "bob",
112
- }
113
- `;
114
-
115
141
  exports[`Controller.get() query Entity based on pk 1`] = `
116
142
  Tacos {
117
143
  "id": "1",
@@ -1,4 +1,4 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
3
  exports[`Controller.getResponse() denormalizes schema with extra members but not set 1`] = `
4
4
  {
@@ -1,6 +1,7 @@
1
1
  import { Entity, schema } from '@data-client/endpoint';
2
2
 
3
3
  import { initialState } from '../../state/reducer/createReducer';
4
+ import { State } from '../../types';
4
5
  import Controller from '../Controller';
5
6
 
6
7
  class Tacos extends Entity {
@@ -46,37 +47,113 @@ describe('Controller.get()', () => {
46
47
  () => controller.get(Tacos, { doesnotexist: 5 }, state);
47
48
  });
48
49
 
49
- it('query Entity based on index', () => {
50
+ describe('indexes', () => {
50
51
  class User extends Entity {
51
52
  id = '';
52
53
  username = '';
54
+ staff = false;
53
55
 
54
56
  static indexes = ['username'] as const;
55
57
  }
58
+ it('query Entity based on index', () => {
59
+ const controller = new Controller();
60
+ const state: State<unknown> = {
61
+ ...initialState,
62
+ entities: {
63
+ User: {
64
+ '1': { id: '1', username: 'bob' },
65
+ '2': { id: '2', username: 'george' },
66
+ },
67
+ },
68
+ indexes: {
69
+ User: {
70
+ username: {
71
+ bob: '1',
72
+ george: '2',
73
+ },
74
+ },
75
+ },
76
+ };
56
77
 
57
- const controller = new Controller();
58
- const state = {
59
- ...initialState,
60
- entities: {
61
- User: {
62
- '1': { id: '1', username: 'bob' },
78
+ const bob = controller.get(User, { username: 'bob' }, state);
79
+ expect(bob).toBeDefined();
80
+ expect(bob).toBeInstanceOf(User);
81
+ expect(bob).toMatchSnapshot();
82
+ // stability
83
+ expect(controller.get(User, { username: 'bob' }, state)).toBe(bob);
84
+ // should be same as id lookup
85
+ expect(controller.get(User, { id: '1' }, state)).toBe(bob);
86
+ // update index
87
+ let nextState: State<unknown> = {
88
+ ...state,
89
+ entities: {
90
+ ...state.entities,
91
+ User: {
92
+ ...state.entities.User,
93
+ '1': { id: '1', username: 'george' },
94
+ '2': { id: '2', username: 'bob' },
95
+ },
63
96
  },
64
- },
65
- indexes: {
66
- User: {
67
- username: {
68
- bob: '1',
97
+ indexes: {
98
+ ...state.indexes,
99
+ User: {
100
+ ...state.indexes.User,
101
+ username: {
102
+ ...state.indexes.User.username,
103
+ bob: '2',
104
+ george: '1',
105
+ },
69
106
  },
70
107
  },
71
- },
72
- };
108
+ };
109
+ expect(controller.get(User, { username: 'bob' }, nextState)).not.toBe(
110
+ bob,
111
+ );
112
+ nextState = {
113
+ ...state,
114
+ entities: {
115
+ ...state.entities,
116
+ User: {
117
+ ...state.entities.User,
118
+ '1': { id: '1', username: 'bob', staff: true },
119
+ },
120
+ },
121
+ };
122
+ // update entity keep index
123
+ const nextBob = controller.get(User, { username: 'bob' }, nextState);
124
+ expect(nextBob).not.toBe(bob);
125
+ expect(nextBob).toBeDefined();
126
+ expect(nextBob).toBeInstanceOf(User);
127
+ expect(nextBob?.staff).toBe(true);
128
+ });
73
129
 
74
- const bob = controller.get(User, { username: 'bob' }, state);
75
- expect(bob).toBeDefined();
76
- expect(bob).toBeInstanceOf(User);
77
- expect(bob).toMatchSnapshot();
78
- // should be same as id lookup
79
- expect(bob).toBe(controller.get(User, { id: '1' }, state));
130
+ it('query indexes after empty state', () => {
131
+ const controller = new Controller();
132
+ expect(
133
+ controller.get(User, { username: 'bob' }, initialState),
134
+ ).toBeUndefined();
135
+ const state: State<unknown> = {
136
+ ...initialState,
137
+ entities: {
138
+ User: {
139
+ '1': { id: '1', username: 'bob' },
140
+ '2': { id: '2', username: 'george' },
141
+ },
142
+ },
143
+ indexes: {
144
+ User: {
145
+ username: {
146
+ bob: '1',
147
+ george: '2',
148
+ },
149
+ },
150
+ },
151
+ };
152
+ const bob = controller.get(User, { username: 'bob' }, state);
153
+ expect(bob).toBeDefined();
154
+ expect(bob).toBeInstanceOf(User);
155
+ expect(bob).toMatchSnapshot();
156
+ });
80
157
  });
81
158
 
82
159
  it('query Collection based on args', () => {
@@ -218,11 +295,11 @@ describe('Controller.get()', () => {
218
295
  id: string = '';
219
296
  }
220
297
  class User extends IDEntity {
221
- type = 'user';
298
+ type = 'users';
222
299
  username: string = '';
223
300
  }
224
301
  class Group extends IDEntity {
225
- type = 'group';
302
+ type = 'groups';
226
303
  groupname: string = '';
227
304
  memberCount = 0;
228
305
  }
@@ -272,6 +349,70 @@ describe('Controller.get()', () => {
272
349
  // @ts-expect-error
273
350
  () => controller.get(queryPerson, { id: '1', doesnotexist: 5 }, state);
274
351
  });
352
+
353
+ it('Union based on args with function schemaAttribute', () => {
354
+ class IDEntity extends Entity {
355
+ id: string = '';
356
+ }
357
+ class User extends IDEntity {
358
+ type = 'user';
359
+ username: string = '';
360
+ }
361
+ class Group extends IDEntity {
362
+ type = 'group';
363
+ groupname: string = '';
364
+ memberCount = 0;
365
+ }
366
+ const queryPerson = new schema.Union(
367
+ {
368
+ users: User,
369
+ groups: Group,
370
+ },
371
+ (value: { type: 'users' | 'groups' }) => value.type,
372
+ );
373
+ const controller = new Controller();
374
+ const state = {
375
+ ...initialState,
376
+ entities: {
377
+ User: {
378
+ '1': { id: '1', type: 'users', username: 'bob' },
379
+ },
380
+ Group: {
381
+ '2': { id: '2', type: 'groups', groupname: 'fast', memberCount: 5 },
382
+ },
383
+ },
384
+ };
385
+ const user = controller.get(queryPerson, { id: '1', type: 'users' }, state);
386
+ expect(user).toBeDefined();
387
+ expect(user).toBeInstanceOf(User);
388
+ expect(user).toMatchSnapshot();
389
+ const group = controller.get(
390
+ queryPerson,
391
+ { id: '2', type: 'groups' },
392
+ state,
393
+ );
394
+ expect(group).toBeDefined();
395
+ expect(group).toBeInstanceOf(Group);
396
+ expect(group).toMatchSnapshot();
397
+
398
+ // should maintain referential equality
399
+ expect(user).toBe(
400
+ controller.get(queryPerson, { id: '1', type: 'users' }, state),
401
+ );
402
+
403
+ // these are the 'fallback case' where it cannot determine type discriminator, so just enumerates
404
+ () => controller.get(queryPerson, { id: '1' }, state);
405
+ // @ts-expect-error
406
+ () => controller.get(queryPerson, { id: '1', type: 'notrealtype' }, state);
407
+ // @ts-expect-error
408
+ () => controller.get(queryPerson, { id: { bob: 5 }, type: 'users' }, state);
409
+ // @ts-expect-error
410
+ expect(controller.get(queryPerson, 5, state)).toBeUndefined();
411
+ // @ts-expect-error
412
+ () => controller.get(queryPerson, { doesnotexist: 5 }, state);
413
+ // @ts-expect-error
414
+ () => controller.get(queryPerson, { id: '1', doesnotexist: 5 }, state);
415
+ });
275
416
  });
276
417
 
277
418
  describe('Snapshot.getQueryMeta()', () => {
@@ -152,7 +152,7 @@ describe('Controller.getResponse()', () => {
152
152
  const state = {
153
153
  ...initialState,
154
154
  entities,
155
- entityMeta: {
155
+ entitiesMeta: {
156
156
  Tacos: {
157
157
  1: { date: 1000000, expiresAt: 1100000, fetchedAt: 1000000 },
158
158
  2: { date: 2000000, expiresAt: 2100000, fetchedAt: 2000000 },
package/src/index.ts CHANGED
@@ -16,6 +16,9 @@ export type {
16
16
  EndpointExtraOptions,
17
17
  Queryable,
18
18
  SchemaArgs,
19
+ Mergeable,
20
+ IQueryDelegate,
21
+ INormalizeDelegate,
19
22
  NI,
20
23
  } from '@data-client/normalizr';
21
24
  export { ExpiryStatus } from '@data-client/normalizr';
@@ -23,6 +26,7 @@ export {
23
26
  default as NetworkManager,
24
27
  ResetError,
25
28
  } from './manager/NetworkManager.js';
29
+ export type { FetchingMeta } from './manager/NetworkManager.js';
26
30
  export * from './state/GCPolicy.js';
27
31
  export {
28
32
  default as createReducer,