@data-client/core 0.13.0 → 0.13.5

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 (57) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +36 -25
  3. package/dist/index.umd.min.js +1 -1
  4. package/legacy/actions.js +1 -1
  5. package/legacy/controller/Controller.js +14 -14
  6. package/legacy/controller/createSet.js +1 -1
  7. package/legacy/internal.js +1 -2
  8. package/legacy/manager/NetworkManager.js +13 -7
  9. package/legacy/state/reducer/createReducer.js +2 -2
  10. package/legacy/state/reducer/setReducer.js +11 -3
  11. package/lib/actions.d.ts +1 -1
  12. package/lib/actions.d.ts.map +1 -1
  13. package/lib/actions.js +1 -1
  14. package/lib/controller/Controller.d.ts +17 -16
  15. package/lib/controller/Controller.d.ts.map +1 -1
  16. package/lib/controller/Controller.js +14 -14
  17. package/lib/controller/createSet.d.ts +2 -2
  18. package/lib/controller/createSet.d.ts.map +1 -1
  19. package/lib/controller/createSet.js +1 -1
  20. package/lib/internal.d.ts +0 -1
  21. package/lib/internal.d.ts.map +1 -1
  22. package/lib/internal.js +1 -2
  23. package/lib/manager/NetworkManager.d.ts +5 -0
  24. package/lib/manager/NetworkManager.d.ts.map +1 -1
  25. package/lib/manager/NetworkManager.js +13 -7
  26. package/lib/state/reducer/createReducer.js +2 -2
  27. package/lib/state/reducer/expireReducer.d.ts +5 -7
  28. package/lib/state/reducer/expireReducer.d.ts.map +1 -1
  29. package/lib/state/reducer/invalidateReducer.d.ts +4 -6
  30. package/lib/state/reducer/invalidateReducer.d.ts.map +1 -1
  31. package/lib/state/reducer/setReducer.d.ts +2 -1
  32. package/lib/state/reducer/setReducer.d.ts.map +1 -1
  33. package/lib/state/reducer/setReducer.js +11 -3
  34. package/package.json +1 -1
  35. package/src/actions.ts +1 -1
  36. package/src/controller/Controller.ts +14 -4
  37. package/src/controller/createSet.ts +6 -2
  38. package/src/internal.ts +0 -1
  39. package/src/manager/NetworkManager.ts +15 -5
  40. package/src/state/__tests__/reducer.ts +70 -1
  41. package/src/state/reducer/createReducer.ts +1 -1
  42. package/src/state/reducer/setReducer.ts +19 -2
  43. package/ts3.4/actions.d.ts +1 -1
  44. package/ts3.4/controller/Controller.d.ts +22 -18
  45. package/ts3.4/controller/createSet.d.ts +2 -2
  46. package/ts3.4/internal.d.ts +0 -1
  47. package/ts3.4/manager/NetworkManager.d.ts +5 -0
  48. package/ts3.4/state/reducer/expireReducer.d.ts +5 -7
  49. package/ts3.4/state/reducer/invalidateReducer.d.ts +4 -6
  50. package/ts3.4/state/reducer/setReducer.d.ts +2 -1
  51. package/legacy/state/RIC.js +0 -3
  52. package/lib/state/RIC.d.ts +0 -3
  53. package/lib/state/RIC.d.ts.map +0 -1
  54. package/lib/state/RIC.js +0 -3
  55. package/src/state/RIC.ts +0 -5
  56. package/src/state/__tests__/RIC.web.ts +0 -16
  57. package/ts3.4/state/RIC.d.ts +0 -3
@@ -1,11 +1,19 @@
1
1
  import { normalize } from '@data-client/normalizr';
2
- export function setReducer(state, action) {
2
+ export function setReducer(state, action, controller) {
3
+ let value;
4
+ if (typeof action.value === 'function') {
5
+ const previousValue = controller.get(action.schema, ...action.meta.args, state);
6
+ if (previousValue === undefined) return state;
7
+ value = action.value(previousValue);
8
+ } else {
9
+ value = action.value;
10
+ }
3
11
  try {
4
12
  const {
5
13
  entities,
6
14
  indexes,
7
15
  entityMeta
8
- } = normalize(action.value, action.schema, action.meta.args, state.entities, state.indexes, state.entityMeta, action.meta);
16
+ } = normalize(value, action.schema, action.meta.args, state.entities, state.indexes, state.entityMeta, action.meta);
9
17
  return {
10
18
  entities,
11
19
  indexes,
@@ -25,4 +33,4 @@ export function setReducer(state, action) {
25
33
  return state;
26
34
  }
27
35
  }
28
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJub3JtYWxpemUiLCJzZXRSZWR1Y2VyIiwic3RhdGUiLCJhY3Rpb24iLCJlbnRpdGllcyIsImluZGV4ZXMiLCJlbnRpdHlNZXRhIiwidmFsdWUiLCJzY2hlbWEiLCJtZXRhIiwiYXJncyIsImVuZHBvaW50cyIsIm9wdGltaXN0aWMiLCJsYXN0UmVzZXQiLCJlcnJvciIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsImNvbnNvbGUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3RhdGUvcmVkdWNlci9zZXRSZWR1Y2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ0BkYXRhLWNsaWVudC9ub3JtYWxpenInO1xuXG5pbXBvcnQgdHlwZSB7IFN0YXRlLCBTZXRBY3Rpb24gfSBmcm9tICcuLi8uLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRSZWR1Y2VyKHN0YXRlOiBTdGF0ZTx1bmtub3duPiwgYWN0aW9uOiBTZXRBY3Rpb24pIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7IGVudGl0aWVzLCBpbmRleGVzLCBlbnRpdHlNZXRhIH0gPSBub3JtYWxpemUoXG4gICAgICBhY3Rpb24udmFsdWUsXG4gICAgICBhY3Rpb24uc2NoZW1hLFxuICAgICAgYWN0aW9uLm1ldGEuYXJncyBhcyBhbnksXG4gICAgICBzdGF0ZS5lbnRpdGllcyxcbiAgICAgIHN0YXRlLmluZGV4ZXMsXG4gICAgICBzdGF0ZS5lbnRpdHlNZXRhLFxuICAgICAgYWN0aW9uLm1ldGEsXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgZW50aXRpZXMsXG4gICAgICBpbmRleGVzLFxuICAgICAgZW5kcG9pbnRzOiBzdGF0ZS5lbmRwb2ludHMsXG4gICAgICBlbnRpdHlNZXRhLFxuICAgICAgbWV0YTogc3RhdGUubWV0YSxcbiAgICAgIG9wdGltaXN0aWM6IHN0YXRlLm9wdGltaXN0aWMsXG4gICAgICBsYXN0UmVzZXQ6IHN0YXRlLmxhc3RSZXNldCxcbiAgICB9O1xuICAgIC8vIHJlZHVjZXIgbXVzdCB1cGRhdGUgdGhlIHN0YXRlLCBzbyBpbiBjYXNlIG9mIHByb2Nlc3NpbmcgZXJyb3JzIHdlIHNpbXBseSBjb21wdXRlIHRoZSBlbmRwb2ludHMgaW5saW5lXG4gIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAvLyB0aGlzIGlzIG5vdCBhbHdheXMgYnViYmxlZCB1cCwgc28gbGV0J3MgZG91YmxlIHN1cmUgdGhpcyBkb2Vzbid0IGZhaWwgc2lsZW50bHlcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFNBQVMsUUFBUSx3QkFBd0I7QUFJbEQsT0FBTyxTQUFTQyxVQUFVQSxDQUFDQyxLQUFxQixFQUFFQyxNQUFpQixFQUFFO0VBQ25FLElBQUk7SUFDRixNQUFNO01BQUVDLFFBQVE7TUFBRUMsT0FBTztNQUFFQztJQUFXLENBQUMsR0FBR04sU0FBUyxDQUNqREcsTUFBTSxDQUFDSSxLQUFLLEVBQ1pKLE1BQU0sQ0FBQ0ssTUFBTSxFQUNiTCxNQUFNLENBQUNNLElBQUksQ0FBQ0MsSUFBSSxFQUNoQlIsS0FBSyxDQUFDRSxRQUFRLEVBQ2RGLEtBQUssQ0FBQ0csT0FBTyxFQUNiSCxLQUFLLENBQUNJLFVBQVUsRUFDaEJILE1BQU0sQ0FBQ00sSUFDVCxDQUFDO0lBQ0QsT0FBTztNQUNMTCxRQUFRO01BQ1JDLE9BQU87TUFDUE0sU0FBUyxFQUFFVCxLQUFLLENBQUNTLFNBQVM7TUFDMUJMLFVBQVU7TUFDVkcsSUFBSSxFQUFFUCxLQUFLLENBQUNPLElBQUk7TUFDaEJHLFVBQVUsRUFBRVYsS0FBSyxDQUFDVSxVQUFVO01BQzVCQyxTQUFTLEVBQUVYLEtBQUssQ0FBQ1c7SUFDbkIsQ0FBQztJQUNEO0VBQ0YsQ0FBQyxDQUFDLE9BQU9DLEtBQVUsRUFBRTtJQUNuQjtJQUNBO0lBQ0EsSUFBSUMsT0FBTyxDQUFDQyxHQUFHLENBQUNDLFFBQVEsS0FBSyxZQUFZLEVBQUU7TUFDekNDLE9BQU8sQ0FBQ0osS0FBSyxDQUFDQSxLQUFLLENBQUM7SUFDdEI7SUFDQSxPQUFPWixLQUFLO0VBQ2Q7QUFDRiIsImlnbm9yZUxpc3QiOltdfQ==
36
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJub3JtYWxpemUiLCJzZXRSZWR1Y2VyIiwic3RhdGUiLCJhY3Rpb24iLCJjb250cm9sbGVyIiwidmFsdWUiLCJwcmV2aW91c1ZhbHVlIiwiZ2V0Iiwic2NoZW1hIiwibWV0YSIsImFyZ3MiLCJ1bmRlZmluZWQiLCJlbnRpdGllcyIsImluZGV4ZXMiLCJlbnRpdHlNZXRhIiwiZW5kcG9pbnRzIiwib3B0aW1pc3RpYyIsImxhc3RSZXNldCIsImVycm9yIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiY29uc29sZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zdGF0ZS9yZWR1Y2VyL3NldFJlZHVjZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbm9ybWFsaXplIH0gZnJvbSAnQGRhdGEtY2xpZW50L25vcm1hbGl6cic7XG5cbmltcG9ydCBDb250cm9sbGVyIGZyb20gJy4uLy4uL2NvbnRyb2xsZXIvQ29udHJvbGxlci5qcyc7XG5pbXBvcnQgdHlwZSB7IFN0YXRlLCBTZXRBY3Rpb24gfSBmcm9tICcuLi8uLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRSZWR1Y2VyKFxuICBzdGF0ZTogU3RhdGU8dW5rbm93bj4sXG4gIGFjdGlvbjogU2V0QWN0aW9uLFxuICBjb250cm9sbGVyOiBDb250cm9sbGVyLFxuKSB7XG4gIGxldCB2YWx1ZTogYW55O1xuICBpZiAodHlwZW9mIGFjdGlvbi52YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSBjb250cm9sbGVyLmdldChcbiAgICAgIGFjdGlvbi5zY2hlbWEsXG4gICAgICAuLi5hY3Rpb24ubWV0YS5hcmdzLFxuICAgICAgc3RhdGUsXG4gICAgKTtcbiAgICBpZiAocHJldmlvdXNWYWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gc3RhdGU7XG4gICAgdmFsdWUgPSBhY3Rpb24udmFsdWUocHJldmlvdXNWYWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBhY3Rpb24udmFsdWU7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCB7IGVudGl0aWVzLCBpbmRleGVzLCBlbnRpdHlNZXRhIH0gPSBub3JtYWxpemUoXG4gICAgICB2YWx1ZSxcbiAgICAgIGFjdGlvbi5zY2hlbWEsXG4gICAgICBhY3Rpb24ubWV0YS5hcmdzIGFzIGFueSxcbiAgICAgIHN0YXRlLmVudGl0aWVzLFxuICAgICAgc3RhdGUuaW5kZXhlcyxcbiAgICAgIHN0YXRlLmVudGl0eU1ldGEsXG4gICAgICBhY3Rpb24ubWV0YSxcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBlbnRpdGllcyxcbiAgICAgIGluZGV4ZXMsXG4gICAgICBlbmRwb2ludHM6IHN0YXRlLmVuZHBvaW50cyxcbiAgICAgIGVudGl0eU1ldGEsXG4gICAgICBtZXRhOiBzdGF0ZS5tZXRhLFxuICAgICAgb3B0aW1pc3RpYzogc3RhdGUub3B0aW1pc3RpYyxcbiAgICAgIGxhc3RSZXNldDogc3RhdGUubGFzdFJlc2V0LFxuICAgIH07XG4gICAgLy8gcmVkdWNlciBtdXN0IHVwZGF0ZSB0aGUgc3RhdGUsIHNvIGluIGNhc2Ugb2YgcHJvY2Vzc2luZyBlcnJvcnMgd2Ugc2ltcGx5IGNvbXB1dGUgdGhlIGVuZHBvaW50cyBpbmxpbmVcbiAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgIC8vIHRoaXMgaXMgbm90IGFsd2F5cyBidWJibGVkIHVwLCBzbyBsZXQncyBkb3VibGUgc3VyZSB0aGlzIGRvZXNuJ3QgZmFpbCBzaWxlbnRseVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsU0FBUyxRQUFRLHdCQUF3QjtBQUtsRCxPQUFPLFNBQVNDLFVBQVVBLENBQ3hCQyxLQUFxQixFQUNyQkMsTUFBaUIsRUFDakJDLFVBQXNCLEVBQ3RCO0VBQ0EsSUFBSUMsS0FBVTtFQUNkLElBQUksT0FBT0YsTUFBTSxDQUFDRSxLQUFLLEtBQUssVUFBVSxFQUFFO0lBQ3RDLE1BQU1DLGFBQWEsR0FBR0YsVUFBVSxDQUFDRyxHQUFHLENBQ2xDSixNQUFNLENBQUNLLE1BQU0sRUFDYixHQUFHTCxNQUFNLENBQUNNLElBQUksQ0FBQ0MsSUFBSSxFQUNuQlIsS0FDRixDQUFDO0lBQ0QsSUFBSUksYUFBYSxLQUFLSyxTQUFTLEVBQUUsT0FBT1QsS0FBSztJQUM3Q0csS0FBSyxHQUFHRixNQUFNLENBQUNFLEtBQUssQ0FBQ0MsYUFBYSxDQUFDO0VBQ3JDLENBQUMsTUFBTTtJQUNMRCxLQUFLLEdBQUdGLE1BQU0sQ0FBQ0UsS0FBSztFQUN0QjtFQUNBLElBQUk7SUFDRixNQUFNO01BQUVPLFFBQVE7TUFBRUMsT0FBTztNQUFFQztJQUFXLENBQUMsR0FBR2QsU0FBUyxDQUNqREssS0FBSyxFQUNMRixNQUFNLENBQUNLLE1BQU0sRUFDYkwsTUFBTSxDQUFDTSxJQUFJLENBQUNDLElBQUksRUFDaEJSLEtBQUssQ0FBQ1UsUUFBUSxFQUNkVixLQUFLLENBQUNXLE9BQU8sRUFDYlgsS0FBSyxDQUFDWSxVQUFVLEVBQ2hCWCxNQUFNLENBQUNNLElBQ1QsQ0FBQztJQUNELE9BQU87TUFDTEcsUUFBUTtNQUNSQyxPQUFPO01BQ1BFLFNBQVMsRUFBRWIsS0FBSyxDQUFDYSxTQUFTO01BQzFCRCxVQUFVO01BQ1ZMLElBQUksRUFBRVAsS0FBSyxDQUFDTyxJQUFJO01BQ2hCTyxVQUFVLEVBQUVkLEtBQUssQ0FBQ2MsVUFBVTtNQUM1QkMsU0FBUyxFQUFFZixLQUFLLENBQUNlO0lBQ25CLENBQUM7SUFDRDtFQUNGLENBQUMsQ0FBQyxPQUFPQyxLQUFVLEVBQUU7SUFDbkI7SUFDQTtJQUNBLElBQUlDLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDQyxRQUFRLEtBQUssWUFBWSxFQUFFO01BQ3pDQyxPQUFPLENBQUNKLEtBQUssQ0FBQ0EsS0FBSyxDQUFDO0lBQ3RCO0lBQ0EsT0FBT2hCLEtBQUs7RUFDZDtBQUNGIiwiaWdub3JlTGlzdCI6W119
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-client/core",
3
- "version": "0.13.0",
3
+ "version": "0.13.5",
4
4
  "description": "High performance mutable data framework.",
5
5
  "sideEffects": false,
6
6
  "main": "dist/index.js",
package/src/actions.ts CHANGED
@@ -40,7 +40,7 @@ export interface SetAction<S extends Queryable = any> {
40
40
  type: typeof SET_TYPE;
41
41
  schema: S;
42
42
  meta: SetMeta;
43
- value: Denormalize<S>;
43
+ value: {} | ((previousValue: Denormalize<S>) => {});
44
44
  }
45
45
 
46
46
  /* setResponse */
@@ -186,18 +186,28 @@ export default class Controller<
186
186
  * Sets value for the Queryable and args.
187
187
  * @see https://dataclient.io/docs/api/Controller#set
188
188
  */
189
- set = <S extends Queryable>(
189
+ set<S extends Queryable>(
190
+ schema: S,
191
+ ...rest: readonly [...SchemaArgs<S>, (previousValue: Denormalize<S>) => {}]
192
+ ): Promise<void>;
193
+
194
+ set<S extends Queryable>(
195
+ schema: S,
196
+ ...rest: readonly [...SchemaArgs<S>, {}]
197
+ ): Promise<void>;
198
+
199
+ set<S extends Queryable>(
190
200
  schema: S,
191
201
  ...rest: readonly [...SchemaArgs<S>, any]
192
- ): Promise<void> => {
193
- const value: Denormalize<S> = rest[rest.length - 1];
202
+ ): Promise<void> {
203
+ const value = rest[rest.length - 1];
194
204
  const action = createSet(schema, {
195
205
  args: rest.slice(0, rest.length - 1) as SchemaArgs<S>,
196
206
  value,
197
207
  });
198
208
  // TODO: reject with error if this fails in reducer
199
209
  return this.dispatch(action);
200
- };
210
+ }
201
211
 
202
212
  /**
203
213
  * Sets response for the Endpoint and args.
@@ -1,4 +1,8 @@
1
- import type { Queryable, SchemaArgs } from '@data-client/normalizr';
1
+ import type {
2
+ Denormalize,
3
+ Queryable,
4
+ SchemaArgs,
5
+ } from '@data-client/normalizr';
2
6
 
3
7
  import ensurePojo from './ensurePojo.js';
4
8
  import { SET_TYPE } from '../actionTypes.js';
@@ -12,7 +16,7 @@ export default function createSet<S extends Queryable>(
12
16
  value,
13
17
  }: {
14
18
  args: readonly [...SchemaArgs<S>];
15
- value: any;
19
+ value: {} | ((previousValue: Denormalize<S>) => {});
16
20
  fetchedAt?: number;
17
21
  },
18
22
  ): SetAction<S> {
package/src/internal.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export { MemoCache, INVALID } from '@data-client/normalizr';
2
- export { default as RIC } from './state/RIC.js';
3
2
  export { initialState } from './state/reducer/createReducer.js';
@@ -1,7 +1,6 @@
1
1
  import { SET_RESPONSE_TYPE, FETCH_TYPE, RESET_TYPE } from '../actionTypes.js';
2
2
  import Controller from '../controller/Controller.js';
3
3
  import createSetResponse from '../controller/createSetResponse.js';
4
- import RIC from '../state/RIC.js';
5
4
  import type {
6
5
  FetchAction,
7
6
  Manager,
@@ -282,11 +281,11 @@ export default class NetworkManager implements Manager {
282
281
  });
283
282
  this.fetchedAt[key] = createdAt;
284
283
 
285
- // since our real promise is resolved via the wrapReducer(),
286
- // we should just stop all errors here.
287
- // TODO: decouple this from useFetcher() (that's what's dispatching the error the resolves in here)
288
- RIC(
284
+ this.idleCallback(
289
285
  () => {
286
+ // since our real promise is resolved via the wrapReducer(),
287
+ // we should just stop all errors here.
288
+ // TODO: decouple this from useFetcher() (that's what's dispatching the error the resolves in here)
290
289
  fetch().catch(() => null);
291
290
  },
292
291
  { timeout: 500 },
@@ -294,4 +293,15 @@ export default class NetworkManager implements Manager {
294
293
 
295
294
  return this.fetched[key];
296
295
  }
296
+
297
+ /** Calls the callback when client is not 'busy' with high priority interaction tasks
298
+ *
299
+ * Override for platform-specific implementations
300
+ */
301
+ protected idleCallback(
302
+ callback: (...args: any[]) => void,
303
+ options?: IdleRequestOptions,
304
+ ) {
305
+ callback();
306
+ }
297
307
  }
@@ -1,4 +1,4 @@
1
- import { INVALID } from '@data-client/endpoint';
1
+ import { INVALID, Entity } from '@data-client/endpoint';
2
2
  import { ArticleResource, Article, PaginatedArticle } from '__tests__/new';
3
3
 
4
4
  import { Controller } from '../..';
@@ -202,6 +202,75 @@ describe('reducer', () => {
202
202
  });
203
203
  });
204
204
 
205
+ it('set(function) should do nothing when entity does not exist', () => {
206
+ const id = 20;
207
+ const value = (previous: { counter: number }) => ({
208
+ counter: previous.counter + 1,
209
+ });
210
+ class Counter extends Entity {
211
+ id = 0;
212
+ counter = 0;
213
+ pk() {
214
+ return this.id;
215
+ }
216
+
217
+ static key = 'Counter';
218
+ }
219
+ const action: SetAction = {
220
+ type: SET_TYPE,
221
+ value,
222
+ schema: Counter,
223
+ meta: {
224
+ args: [{ id }],
225
+ date: 0,
226
+ fetchedAt: 0,
227
+ expiresAt: 1000000000000,
228
+ },
229
+ };
230
+ const newState = reducer(initialState, action);
231
+ expect(newState).toBe(initialState);
232
+ });
233
+
234
+ it('set(function) should increment when it is found', () => {
235
+ const id = 20;
236
+ const value = (previous: { id: number; counter: number }) => ({
237
+ id: previous.id,
238
+ counter: previous.counter + 1,
239
+ });
240
+ class Counter extends Entity {
241
+ id = 0;
242
+ counter = 0;
243
+ pk() {
244
+ return this.id;
245
+ }
246
+
247
+ static key = 'Counter';
248
+ }
249
+ const action: SetAction = {
250
+ type: SET_TYPE,
251
+ value,
252
+ schema: Counter,
253
+ meta: {
254
+ args: [{ id }],
255
+ date: 0,
256
+ fetchedAt: 0,
257
+ expiresAt: 1000000000000,
258
+ },
259
+ };
260
+ const state = {
261
+ ...initialState,
262
+ entities: {
263
+ [Counter.key]: {
264
+ [id]: { id, counter: 5 },
265
+ },
266
+ },
267
+ };
268
+ const newState = reducer(state, action);
269
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
270
+ // @ts-ignore
271
+ expect(newState.entities[Counter.key]?.[id]?.counter).toBe(6);
272
+ });
273
+
205
274
  it('set should add entity when it does not exist', () => {
206
275
  const id = 20;
207
276
  const value = { id, title: 'hi', content: 'this is the content' };
@@ -44,7 +44,7 @@ export default function createReducer(controller: Controller): ReducerType {
44
44
  return setResponseReducer(state, action, controller);
45
45
 
46
46
  case SET_TYPE:
47
- return setReducer(state, action);
47
+ return setReducer(state, action, controller);
48
48
 
49
49
  case INVALIDATEALL_TYPE:
50
50
  case INVALIDATE_TYPE:
@@ -1,11 +1,28 @@
1
1
  import { normalize } from '@data-client/normalizr';
2
2
 
3
+ import Controller from '../../controller/Controller.js';
3
4
  import type { State, SetAction } from '../../types.js';
4
5
 
5
- export function setReducer(state: State<unknown>, action: SetAction) {
6
+ export function setReducer(
7
+ state: State<unknown>,
8
+ action: SetAction,
9
+ controller: Controller,
10
+ ) {
11
+ let value: any;
12
+ if (typeof action.value === 'function') {
13
+ const previousValue = controller.get(
14
+ action.schema,
15
+ ...action.meta.args,
16
+ state,
17
+ );
18
+ if (previousValue === undefined) return state;
19
+ value = action.value(previousValue);
20
+ } else {
21
+ value = action.value;
22
+ }
6
23
  try {
7
24
  const { entities, indexes, entityMeta } = normalize(
8
- action.value,
25
+ value,
9
26
  action.schema,
10
27
  action.meta.args as any,
11
28
  state.entities,
@@ -17,7 +17,7 @@ export interface SetAction<S extends Queryable = any> {
17
17
  type: typeof SET_TYPE;
18
18
  schema: S;
19
19
  meta: SetMeta;
20
- value: Denormalize<S>;
20
+ value: {} | ((previousValue: Denormalize<S>) => {});
21
21
  }
22
22
  export interface SetResponseMeta {
23
23
  args: readonly any[];
@@ -38,21 +38,21 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
38
38
  * Fetches the endpoint with given args, updating the Reactive Data Client cache with the response or error upon completion.
39
39
  * @see https://dataclient.io/docs/api/Controller#fetch
40
40
  */
41
- fetch: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined> & {
42
- update?: EndpointUpdateFunction<E> | undefined;
43
- }>(endpoint: E, ...args_0: Parameters<E>) => E['schema'] extends undefined | null ? ReturnType<E> : Promise<Denormalize<E['schema']>>;
41
+ fetch: <E extends EndpointInterface & {
42
+ update?: EndpointUpdateFunction<E>;
43
+ }>(endpoint: E, ...args_0: Parameters<E>) => E["schema"] extends undefined | null ? ReturnType<E> : Promise<Denormalize<E["schema"]>>;
44
44
  /**
45
45
  * Fetches only if endpoint is considered 'stale'; otherwise returns undefined
46
46
  * @see https://dataclient.io/docs/api/Controller#fetchIfStale
47
47
  */
48
- fetchIfStale: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined> & {
49
- update?: EndpointUpdateFunction<E> | undefined;
50
- }>(endpoint: E, ...args_0: Parameters<E>) => E['schema'] extends undefined | null ? ReturnType<E> | ResolveType<E> : Promise<Denormalize<E['schema']>> | Denormalize<E['schema']>;
48
+ fetchIfStale: <E extends EndpointInterface & {
49
+ update?: EndpointUpdateFunction<E>;
50
+ }>(endpoint: E, ...args_0: Parameters<E>) => E["schema"] extends undefined | null ? ReturnType<E> | ResolveType<E> : Promise<Denormalize<E["schema"]>> | Denormalize<E["schema"]>;
51
51
  /**
52
52
  * Forces refetching and suspense on useSuspense with the same Endpoint and parameters.
53
53
  * @see https://dataclient.io/docs/api/Controller#invalidate
54
54
  */
55
- invalidate: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined>>(endpoint: E, ...args: readonly [
55
+ invalidate: <E extends EndpointInterface>(endpoint: E, ...args: readonly [
56
56
  ...Parameters<E>
57
57
  ] | readonly [
58
58
  null
@@ -82,16 +82,20 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
82
82
  * Sets value for the Queryable and args.
83
83
  * @see https://dataclient.io/docs/api/Controller#set
84
84
  */
85
- set: <S extends Queryable>(schema: S, ...rest: readonly [
85
+ set<S extends Queryable>(schema: S, ...rest: readonly [
86
86
  ...SchemaArgs<S>,
87
- any
88
- ]) => Promise<void>;
87
+ (previousValue: Denormalize<S>) => {}
88
+ ]): Promise<void>;
89
+ set<S extends Queryable>(schema: S, ...rest: readonly [
90
+ ...SchemaArgs<S>,
91
+ {}
92
+ ]): Promise<void>;
89
93
  /**
90
94
  * Sets response for the Endpoint and args.
91
95
  * @see https://dataclient.io/docs/api/Controller#setResponse
92
96
  */
93
- setResponse: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined> & {
94
- update?: EndpointUpdateFunction<E> | undefined;
97
+ setResponse: <E extends EndpointInterface & {
98
+ update?: EndpointUpdateFunction<E>;
95
99
  }>(endpoint: E, ...rest: readonly [
96
100
  ...Parameters<E>,
97
101
  any
@@ -100,8 +104,8 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
100
104
  * Sets an error response for the Endpoint and args.
101
105
  * @see https://dataclient.io/docs/api/Controller#setError
102
106
  */
103
- setError: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined> & {
104
- update?: EndpointUpdateFunction<E> | undefined;
107
+ setError: <E extends EndpointInterface & {
108
+ update?: EndpointUpdateFunction<E>;
105
109
  }>(endpoint: E, ...rest: readonly [
106
110
  ...Parameters<E>,
107
111
  Error
@@ -110,8 +114,8 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
110
114
  * Resolves an inflight fetch. `fetchedAt` should `fetch`'s `createdAt`
111
115
  * @see https://dataclient.io/docs/api/Controller#resolve
112
116
  */
113
- resolve: <E extends EndpointInterface<FetchFunction, Schema | undefined, boolean | undefined> & {
114
- update?: EndpointUpdateFunction<E> | undefined;
117
+ resolve: <E extends EndpointInterface & {
118
+ update?: EndpointUpdateFunction<E>;
115
119
  }>(endpoint: E, meta: {
116
120
  args: readonly [
117
121
  ...Parameters<E>
@@ -131,7 +135,7 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
131
135
  * Marks a new subscription to a given Endpoint.
132
136
  * @see https://dataclient.io/docs/api/Controller#subscribe
133
137
  */
134
- subscribe: <E extends EndpointInterface<FetchFunction, Schema | undefined, false | undefined>>(endpoint: E, ...args: readonly [
138
+ subscribe: <E extends EndpointInterface<FetchFunction, Schema | undefined, undefined | false>>(endpoint: E, ...args: readonly [
135
139
  ...Parameters<E>
136
140
  ] | readonly [
137
141
  null
@@ -140,7 +144,7 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
140
144
  * Marks completion of subscription to a given Endpoint.
141
145
  * @see https://dataclient.io/docs/api/Controller#unsubscribe
142
146
  */
143
- unsubscribe: <E extends EndpointInterface<FetchFunction, Schema | undefined, false | undefined>>(endpoint: E, ...args: readonly [
147
+ unsubscribe: <E extends EndpointInterface<FetchFunction, Schema | undefined, undefined | false>>(endpoint: E, ...args: readonly [
144
148
  ...Parameters<E>
145
149
  ] | readonly [
146
150
  null
@@ -1,10 +1,10 @@
1
- import { Queryable, SchemaArgs } from '@data-client/normalizr';
1
+ import { Denormalize, Queryable, SchemaArgs } from '@data-client/normalizr';
2
2
  import { SetAction } from '../types.js';
3
3
  export default function createSet<S extends Queryable>(schema: S, { args, fetchedAt, value, }: {
4
4
  args: readonly [
5
5
  ...SchemaArgs<S>
6
6
  ];
7
- value: any;
7
+ value: {} | ((previousValue: Denormalize<S>) => {});
8
8
  fetchedAt?: number;
9
9
  }): SetAction<S>;
10
10
  //# sourceMappingURL=createSet.d.ts.map
@@ -1,4 +1,3 @@
1
1
  export { MemoCache, INVALID } from '@data-client/normalizr';
2
- export { default as RIC } from './state/RIC.js';
3
2
  export { initialState } from './state/reducer/createReducer.js';
4
3
  //# sourceMappingURL=internal.d.ts.map
@@ -77,5 +77,10 @@ export default class NetworkManager implements Manager {
77
77
  * by the reducer.
78
78
  */
79
79
  protected throttle(key: string, fetch: () => Promise<any>, createdAt: number): Promise<any>;
80
+ /** Calls the callback when client is not 'busy' with high priority interaction tasks
81
+ *
82
+ * Override for platform-specific implementations
83
+ */
84
+ protected idleCallback(callback: (...args: any[]) => void, options?: IdleRequestOptions): void;
80
85
  }
81
86
  //# sourceMappingURL=NetworkManager.d.ts.map
@@ -3,10 +3,10 @@ export declare function expireReducer(state: State<unknown>, action: ExpireAllAc
3
3
  meta: {
4
4
  [x: string]: {
5
5
  readonly date: number;
6
- readonly error?: import("packages/normalizr/lib/index.js").ErrorTypes | undefined;
6
+ readonly error?: import("packages/normalizr/lib/index.js").ErrorTypes;
7
7
  readonly expiresAt: number;
8
- readonly prevExpiresAt?: number | undefined;
9
- readonly invalidated?: boolean | undefined;
8
+ readonly prevExpiresAt?: number;
9
+ readonly invalidated?: boolean;
10
10
  readonly errorPolicy?: "hard" | "soft" | undefined;
11
11
  };
12
12
  };
@@ -17,7 +17,7 @@ export declare function expireReducer(state: State<unknown>, action: ExpireAllAc
17
17
  };
18
18
  indexes: import("packages/normalizr/lib/interface.js").NormalizedIndex;
19
19
  endpoints: {
20
- readonly [key: string]: unknown;
20
+ readonly [key: string]: unknown | import("../../types.js").PK[] | import("../../types.js").PK | undefined;
21
21
  };
22
22
  entityMeta: {
23
23
  readonly [entityKey: string]: {
@@ -28,9 +28,7 @@ export declare function expireReducer(state: State<unknown>, action: ExpireAllAc
28
28
  };
29
29
  };
30
30
  };
31
- optimistic: (import("../../actions.js").SetResponseAction | import("../../actions.js").OptimisticAction<import("packages/normalizr/lib/index.js").EndpointInterface<import("packages/normalizr/lib/index.js").FetchFunction, import("packages/normalizr/lib/interface.js").Schema | undefined, boolean | undefined> & {
32
- update?: import("../../index.js").EndpointUpdateFunction<import("packages/normalizr/lib/index.js").EndpointInterface<import("packages/normalizr/lib/index.js").FetchFunction, import("packages/normalizr/lib/interface.js").Schema | undefined, boolean | undefined>> | undefined;
33
- }>)[];
31
+ optimistic: (import("../../actions.js").SetResponseAction | import("../../actions.js").OptimisticAction)[];
34
32
  lastReset: number;
35
33
  };
36
34
  //# sourceMappingURL=expireReducer.d.ts.map
@@ -6,10 +6,10 @@ export declare function invalidateReducer(state: State<unknown>, action: Invalid
6
6
  meta: {
7
7
  [x: string]: {
8
8
  readonly date: number;
9
- readonly error?: import("packages/normalizr/lib/index.js").ErrorTypes | undefined;
9
+ readonly error?: import("packages/normalizr/lib/index.js").ErrorTypes;
10
10
  readonly expiresAt: number;
11
- readonly prevExpiresAt?: number | undefined;
12
- readonly invalidated?: boolean | undefined;
11
+ readonly prevExpiresAt?: number;
12
+ readonly invalidated?: boolean;
13
13
  readonly errorPolicy?: "hard" | "soft" | undefined;
14
14
  };
15
15
  };
@@ -28,9 +28,7 @@ export declare function invalidateReducer(state: State<unknown>, action: Invalid
28
28
  };
29
29
  };
30
30
  };
31
- optimistic: (import("../../actions.js").SetResponseAction | import("../../actions.js").OptimisticAction<import("packages/normalizr/lib/index.js").EndpointInterface<import("packages/normalizr/lib/index.js").FetchFunction, import("packages/normalizr/lib/interface.js").Schema | undefined, boolean | undefined> & {
32
- update?: import("../../index.js").EndpointUpdateFunction<import("packages/normalizr/lib/index.js").EndpointInterface<import("packages/normalizr/lib/index.js").FetchFunction, import("packages/normalizr/lib/interface.js").Schema | undefined, boolean | undefined>> | undefined;
33
- }>)[];
31
+ optimistic: (import("../../actions.js").SetResponseAction | import("../../actions.js").OptimisticAction)[];
34
32
  lastReset: number;
35
33
  };
36
34
  //# sourceMappingURL=invalidateReducer.d.ts.map
@@ -1,3 +1,4 @@
1
+ import Controller from '../../controller/Controller.js';
1
2
  import { State, SetAction } from '../../types.js';
2
- export declare function setReducer(state: State<unknown>, action: SetAction): State<unknown>;
3
+ export declare function setReducer(state: State<unknown>, action: SetAction, controller: Controller): State<unknown>;
3
4
  //# sourceMappingURL=setReducer.d.ts.map
@@ -1,3 +0,0 @@
1
- const RIC = typeof requestIdleCallback === 'function' ? requestIdleCallback : cb => cb();
2
- export default RIC;
3
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSSUMiLCJyZXF1ZXN0SWRsZUNhbGxiYWNrIiwiY2IiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGUvUklDLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IFJJQzogKGNiOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQsIG9wdGlvbnM6IGFueSkgPT4gdm9pZCA9IChcbiAgdHlwZW9mIHJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyByZXF1ZXN0SWRsZUNhbGxiYWNrIDogKFxuICAgIChjYjogYW55KSA9PiBjYigpXG4gICkpIGFzIGFueTtcbmV4cG9ydCBkZWZhdWx0IFJJQztcbiJdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTUEsR0FBeUQsR0FDN0QsT0FBT0MsbUJBQW1CLEtBQUssVUFBVSxHQUFHQSxtQkFBbUIsR0FDNURDLEVBQU8sSUFBS0EsRUFBRSxDQUFDLENBQ1Q7QUFDWCxlQUFlRixHQUFHIiwiaWdub3JlTGlzdCI6W119
@@ -1,3 +0,0 @@
1
- declare const RIC: (cb: (...args: any[]) => void, options: any) => void;
2
- export default RIC;
3
- //# sourceMappingURL=RIC.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RIC.d.ts","sourceRoot":"","sources":["../../src/state/RIC.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,IAGhD,CAAC;AACZ,eAAe,GAAG,CAAC"}
package/lib/state/RIC.js DELETED
@@ -1,3 +0,0 @@
1
- const RIC = typeof requestIdleCallback === 'function' ? requestIdleCallback : cb => cb();
2
- export default RIC;
3
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSSUMiLCJyZXF1ZXN0SWRsZUNhbGxiYWNrIiwiY2IiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGUvUklDLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IFJJQzogKGNiOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQsIG9wdGlvbnM6IGFueSkgPT4gdm9pZCA9IChcbiAgdHlwZW9mIHJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyByZXF1ZXN0SWRsZUNhbGxiYWNrIDogKFxuICAgIChjYjogYW55KSA9PiBjYigpXG4gICkpIGFzIGFueTtcbmV4cG9ydCBkZWZhdWx0IFJJQztcbiJdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTUEsR0FBeUQsR0FDN0QsT0FBT0MsbUJBQW1CLEtBQUssVUFBVSxHQUFHQSxtQkFBbUIsR0FDNURDLEVBQU8sSUFBS0EsRUFBRSxDQUFDLENBQ1Q7QUFDWCxlQUFlRixHQUFHIiwiaWdub3JlTGlzdCI6W119
package/src/state/RIC.ts DELETED
@@ -1,5 +0,0 @@
1
- const RIC: (cb: (...args: any[]) => void, options: any) => void = (
2
- typeof requestIdleCallback === 'function' ? requestIdleCallback : (
3
- (cb: any) => cb()
4
- )) as any;
5
- export default RIC;
@@ -1,16 +0,0 @@
1
- describe('RequestIdleCallback', () => {
2
- it('should still run when requestIdleCallback is not available', () => {
3
- const requestIdle = (global as any).requestIdleCallback;
4
- (global as any).requestIdleCallback = undefined;
5
- jest.resetModules();
6
- // eslint-disable-next-line @typescript-eslint/no-var-requires
7
- const RIC = require('../RIC').default;
8
- const fn = jest.fn();
9
- jest.useFakeTimers();
10
- RIC(fn, {});
11
- jest.runAllTimers();
12
- expect(fn).toBeCalled();
13
- (global as any).requestIdleCallback = requestIdle;
14
- jest.useRealTimers();
15
- });
16
- });
@@ -1,3 +0,0 @@
1
- declare const RIC: (cb: (...args: any[]) => void, options: any) => void;
2
- export default RIC;
3
- //# sourceMappingURL=RIC.d.ts.map