@data-client/core 0.2.0 → 0.3.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 (46) hide show
  1. package/dist/index.js +38 -0
  2. package/dist/index.umd.min.js +1 -1
  3. package/dist/next.js +15 -0
  4. package/legacy/actionTypes.js +2 -1
  5. package/legacy/controller/Controller.js +9 -1
  6. package/legacy/controller/createExpireAll.js +8 -0
  7. package/legacy/manager/PollingSubscription.js +1 -1
  8. package/legacy/manager/applyManager.js +2 -1
  9. package/legacy/newActions.js +1 -1
  10. package/legacy/state/reducer/createReducer.js +5 -2
  11. package/legacy/state/reducer/expireReducer.js +15 -0
  12. package/lib/actionTypes.d.ts +1 -0
  13. package/lib/actionTypes.d.ts.map +1 -1
  14. package/lib/actionTypes.js +2 -1
  15. package/lib/controller/Controller.d.ts +9 -0
  16. package/lib/controller/Controller.d.ts.map +1 -1
  17. package/lib/controller/Controller.js +9 -1
  18. package/lib/controller/createExpireAll.d.ts +3 -0
  19. package/lib/controller/createExpireAll.d.ts.map +1 -0
  20. package/lib/controller/createExpireAll.js +8 -0
  21. package/lib/manager/PollingSubscription.d.ts.map +1 -1
  22. package/lib/manager/PollingSubscription.js +1 -1
  23. package/lib/manager/applyManager.d.ts.map +1 -1
  24. package/lib/manager/applyManager.js +2 -1
  25. package/lib/newActions.d.ts +6 -2
  26. package/lib/newActions.d.ts.map +1 -1
  27. package/lib/newActions.js +1 -1
  28. package/lib/state/reducer/createReducer.d.ts.map +1 -1
  29. package/lib/state/reducer/createReducer.js +5 -2
  30. package/lib/state/reducer/expireReducer.d.ts +36 -0
  31. package/lib/state/reducer/expireReducer.d.ts.map +1 -0
  32. package/lib/state/reducer/expireReducer.js +19 -0
  33. package/package.json +9 -6
  34. package/src/actionTypes.ts +1 -0
  35. package/src/controller/Controller.ts +10 -0
  36. package/src/controller/createExpireAll.ts +11 -0
  37. package/src/manager/PollingSubscription.ts +14 -11
  38. package/src/manager/applyManager.ts +1 -0
  39. package/src/newActions.ts +8 -0
  40. package/src/state/reducer/createReducer.ts +5 -0
  41. package/src/state/reducer/expireReducer.ts +20 -0
  42. package/ts3.4/actionTypes.d.ts +1 -0
  43. package/ts3.4/controller/Controller.d.ts +9 -0
  44. package/ts3.4/controller/createExpireAll.d.ts +3 -0
  45. package/ts3.4/newActions.d.ts +6 -2
  46. package/ts3.4/state/reducer/expireReducer.d.ts +36 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-client/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "High performance reactive framework for async data.",
5
5
  "sideEffects": false,
6
6
  "main": "dist/index.js",
@@ -89,20 +89,23 @@
89
89
  "async",
90
90
  "data fetching",
91
91
  "data cache",
92
+ "reactive",
93
+ "state management",
92
94
  "api client",
93
95
  "api",
94
96
  "normalized cache",
95
97
  "swr",
96
- "GraphQL",
97
98
  "query",
98
99
  "ios",
99
100
  "android",
100
101
  "web",
101
102
  "middleware",
102
103
  "websocket",
103
- "sse",
104
- "declarative",
105
- "scalable"
104
+ "SSE",
105
+ "GraphQL",
106
+ "REST",
107
+ "RPC",
108
+ "declarative"
106
109
  ],
107
110
  "author": "Nathaniel Tucker <me@ntucker.me> (https://github.com/ntucker)",
108
111
  "license": "Apache-2.0",
@@ -117,7 +120,7 @@
117
120
  },
118
121
  "dependencies": {
119
122
  "@babel/runtime": "^7.17.0",
120
- "@data-client/normalizr": "^0.2.0",
123
+ "@data-client/normalizr": "^0.2.2",
121
124
  "flux-standard-action": "^2.1.1"
122
125
  },
123
126
  "devDependencies": {
@@ -8,4 +8,5 @@ export const SUBSCRIBE_TYPE = 'rest-hooks/subscribe' as const;
8
8
  export const UNSUBSCRIBE_TYPE = 'rest-hook/unsubscribe' as const;
9
9
  export const INVALIDATE_TYPE = 'rest-hooks/invalidate' as const;
10
10
  export const INVALIDATEALL_TYPE = 'rest-hooks/invalidateall' as const;
11
+ export const EXPIREALL_TYPE = 'rest-hooks/expireall' as const;
11
12
  export const GC_TYPE = 'rest-hooks/gc' as const;
@@ -19,6 +19,7 @@ import {
19
19
  } from '@data-client/normalizr';
20
20
  import { inferResults, validateInference } from '@data-client/normalizr';
21
21
 
22
+ import createExpireAll from './createExpireAll.js';
22
23
  import createFetch from './createFetch.js';
23
24
  import createInvalidate from './createInvalidate.js';
24
25
  import createInvalidateAll from './createInvalidateAll.js';
@@ -136,10 +137,19 @@ export default class Controller<
136
137
  /**
137
138
  * Forces refetching and suspense on useSuspense on all matching endpoint result keys.
138
139
  * @see https://resthooks.io/docs/api/Controller#invalidateAll
140
+ * @returns Promise that resolves when invalidation is commited.
139
141
  */
140
142
  invalidateAll = (options: { testKey: (key: string) => boolean }) =>
141
143
  this.dispatch(createInvalidateAll((key: string) => options.testKey(key)));
142
144
 
145
+ /**
146
+ * Sets all matching endpoint result keys to be STALE.
147
+ * @see https://dataclient.io/docs/api/Controller#expireAll
148
+ * @returns Promise that resolves when expiry is commited. *NOT* fetch promise
149
+ */
150
+ expireAll = (options: { testKey: (key: string) => boolean }) =>
151
+ this.dispatch(createExpireAll((key: string) => options.testKey(key)));
152
+
143
153
  /**
144
154
  * Resets the entire Rest Hooks cache. All inflight requests will not resolve.
145
155
  * @see https://resthooks.io/docs/api/Controller#resetEntireStore
@@ -0,0 +1,11 @@
1
+ import { EXPIREALL_TYPE } from '../actionTypes.js';
2
+ import type { ExpireAllAction } from '../types.js';
3
+
4
+ export default function createExpireAll(
5
+ testKey: (key: string) => boolean,
6
+ ): ExpireAllAction {
7
+ return {
8
+ type: EXPIREALL_TYPE,
9
+ testKey,
10
+ };
11
+ }
@@ -145,17 +145,20 @@ export default class PollingSubscription implements Subscription {
145
145
  protected onlineListener = () => {
146
146
  this.connectionListener.removeOnlineListener(this.onlineListener);
147
147
  const now = Date.now();
148
- this.startId = setTimeout(() => {
149
- if (this.startId) {
150
- delete this.startId;
151
- this.update();
152
- this.run();
153
- } else if (process.env.NODE_ENV !== 'production') {
154
- console.warn(
155
- `Poll setTimeout for ${this.key} still running, but timeoutId deleted`,
156
- );
157
- }
158
- }, Math.max(0, this.lastFetchTime() - now + this.frequency));
148
+ this.startId = setTimeout(
149
+ () => {
150
+ if (this.startId) {
151
+ delete this.startId;
152
+ this.update();
153
+ this.run();
154
+ } else if (process.env.NODE_ENV !== 'production') {
155
+ console.warn(
156
+ `Poll setTimeout for ${this.key} still running, but timeoutId deleted`,
157
+ );
158
+ }
159
+ },
160
+ Math.max(0, this.lastFetchTime() - now + this.frequency),
161
+ );
159
162
  this.connectionListener.addOfflineListener(this.offlineListener);
160
163
  };
161
164
 
@@ -8,6 +8,7 @@ export default function applyManager(
8
8
  ): Middleware[] {
9
9
  return managers.map(manager => {
10
10
  const middleware = manager.getMiddleware();
11
+ // TODO(breaking): remove this once controller prop is no longer supported
11
12
  return ({ dispatch, getState }) => {
12
13
  (controller as any).dispatch = dispatch;
13
14
  (controller as any).getState = getState;
package/src/newActions.ts CHANGED
@@ -14,6 +14,7 @@ import type {
14
14
  GC_TYPE,
15
15
  OPTIMISTIC_TYPE,
16
16
  INVALIDATEALL_TYPE,
17
+ EXPIREALL_TYPE,
17
18
  } from './actionTypes.js';
18
19
  import type { EndpointUpdateFunction } from './controller/types.js';
19
20
 
@@ -112,6 +113,12 @@ export interface UnsubscribeAction<
112
113
  };
113
114
  }
114
115
 
116
+ /* EXPIRY */
117
+ export interface ExpireAllAction {
118
+ type: typeof EXPIREALL_TYPE;
119
+ testKey: (key: string) => boolean;
120
+ }
121
+
115
122
  /* INVALIDATE */
116
123
  export interface InvalidateAllAction {
117
124
  type: typeof INVALIDATEALL_TYPE;
@@ -146,5 +153,6 @@ export type ActionTypes =
146
153
  | UnsubscribeAction
147
154
  | InvalidateAction
148
155
  | InvalidateAllAction
156
+ | ExpireAllAction
149
157
  | ResetAction
150
158
  | GCAction;
@@ -1,3 +1,4 @@
1
+ import { expireReducer } from './expireReducer.js';
1
2
  import { fetchReducer } from './fetchReducer.js';
2
3
  import { invalidateReducer } from './invalidateReducer.js';
3
4
  import { setReducer } from './setReducer.js';
@@ -9,6 +10,7 @@ import {
9
10
  GC_TYPE,
10
11
  OPTIMISTIC_TYPE,
11
12
  INVALIDATEALL_TYPE,
13
+ EXPIREALL_TYPE,
12
14
  } from '../../actionTypes.js';
13
15
  import type Controller from '../../controller/Controller.js';
14
16
  import type { ActionTypes, State } from '../../types.js';
@@ -43,6 +45,9 @@ export default function createReducer(controller: Controller): ReducerType {
43
45
  case INVALIDATE_TYPE:
44
46
  return invalidateReducer(state, action);
45
47
 
48
+ case EXPIREALL_TYPE:
49
+ return expireReducer(state, action);
50
+
46
51
  case RESET_TYPE:
47
52
  return { ...initialState, lastReset: action.date };
48
53
 
@@ -0,0 +1,20 @@
1
+ import type { State, ExpireAllAction } from '../../types.js';
2
+
3
+ export function expireReducer(state: State<unknown>, action: ExpireAllAction) {
4
+ const meta = { ...state.meta };
5
+
6
+ Object.keys(meta).forEach(key => {
7
+ if (action.testKey(key)) {
8
+ meta[key] = {
9
+ ...meta[key],
10
+ // 1 instead of 0 so we can do 'falsy' checks to see if it is set
11
+ expiresAt: 1,
12
+ };
13
+ }
14
+ });
15
+
16
+ return {
17
+ ...state,
18
+ meta,
19
+ };
20
+ }
@@ -8,5 +8,6 @@ export declare const SUBSCRIBE_TYPE: "rest-hooks/subscribe";
8
8
  export declare const UNSUBSCRIBE_TYPE: "rest-hook/unsubscribe";
9
9
  export declare const INVALIDATE_TYPE: "rest-hooks/invalidate";
10
10
  export declare const INVALIDATEALL_TYPE: "rest-hooks/invalidateall";
11
+ export declare const EXPIREALL_TYPE: "rest-hooks/expireall";
11
12
  export declare const GC_TYPE: "rest-hooks/gc";
12
13
  //# sourceMappingURL=actionTypes.d.ts.map
@@ -50,10 +50,19 @@ export default class Controller<D extends GenericDispatch = DataClientDispatch>
50
50
  /**
51
51
  * Forces refetching and suspense on useSuspense on all matching endpoint result keys.
52
52
  * @see https://resthooks.io/docs/api/Controller#invalidateAll
53
+ * @returns Promise that resolves when invalidation is commited.
53
54
  */
54
55
  invalidateAll: (options: {
55
56
  testKey: (key: string) => boolean;
56
57
  }) => Promise<void>;
58
+ /**
59
+ * Sets all matching endpoint result keys to be STALE.
60
+ * @see https://dataclient.io/docs/api/Controller#expireAll
61
+ * @returns Promise that resolves when expiry is commited. *NOT* fetch promise
62
+ */
63
+ expireAll: (options: {
64
+ testKey: (key: string) => boolean;
65
+ }) => Promise<void>;
57
66
  /**
58
67
  * Resets the entire Rest Hooks cache. All inflight requests will not resolve.
59
68
  * @see https://resthooks.io/docs/api/Controller#resetEntireStore
@@ -0,0 +1,3 @@
1
+ import { ExpireAllAction } from '../types.js';
2
+ export default function createExpireAll(testKey: (key: string) => boolean): ExpireAllAction;
3
+ //# sourceMappingURL=createExpireAll.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { EndpointInterface, ResolveType, UnknownError } from '@data-client/normalizr';
2
- import { SET_TYPE, RESET_TYPE, FETCH_TYPE, SUBSCRIBE_TYPE, UNSUBSCRIBE_TYPE, INVALIDATE_TYPE, GC_TYPE, OPTIMISTIC_TYPE, INVALIDATEALL_TYPE } from './actionTypes.js';
2
+ import { SET_TYPE, RESET_TYPE, FETCH_TYPE, SUBSCRIBE_TYPE, UNSUBSCRIBE_TYPE, INVALIDATE_TYPE, GC_TYPE, OPTIMISTIC_TYPE, INVALIDATEALL_TYPE, EXPIREALL_TYPE } from './actionTypes.js';
3
3
  import { EndpointUpdateFunction } from './controller/types.js';
4
4
  type EndpointAndUpdate<E extends EndpointInterface> = EndpointInterface & {
5
5
  update?: EndpointUpdateFunction<E>;
@@ -69,6 +69,10 @@ export interface UnsubscribeAction<E extends EndpointAndUpdate<E> = EndpointDefa
69
69
  key: string;
70
70
  };
71
71
  }
72
+ export interface ExpireAllAction {
73
+ type: typeof EXPIREALL_TYPE;
74
+ testKey: (key: string) => boolean;
75
+ }
72
76
  export interface InvalidateAllAction {
73
77
  type: typeof INVALIDATEALL_TYPE;
74
78
  testKey: (key: string) => boolean;
@@ -91,6 +95,6 @@ export interface GCAction {
91
95
  ][];
92
96
  results: string[];
93
97
  }
94
- export type ActionTypes = FetchAction | OptimisticAction | SetAction | SubscribeAction | UnsubscribeAction | InvalidateAction | InvalidateAllAction | ResetAction | GCAction;
98
+ export type ActionTypes = FetchAction | OptimisticAction | SetAction | SubscribeAction | UnsubscribeAction | InvalidateAction | InvalidateAllAction | ExpireAllAction | ResetAction | GCAction;
95
99
  export {};
96
100
  //# sourceMappingURL=newActions.d.ts.map
@@ -0,0 +1,36 @@
1
+ import { State, ExpireAllAction } from '../../types.js';
2
+ export declare function expireReducer(state: State<unknown>, action: ExpireAllAction): {
3
+ meta: {
4
+ [x: string]: {
5
+ readonly date: number;
6
+ readonly error?: import("packages/normalizr/lib/index.js").ErrorTypes | undefined;
7
+ readonly expiresAt: number;
8
+ readonly prevExpiresAt?: number | undefined;
9
+ readonly invalidated?: boolean | undefined;
10
+ readonly errorPolicy?: "hard" | "soft" | undefined;
11
+ };
12
+ };
13
+ entities: {
14
+ readonly [entityKey: string]: {
15
+ readonly [pk: string]: unknown;
16
+ } | undefined;
17
+ };
18
+ indexes: import("packages/normalizr/lib/interface.js").NormalizedIndex;
19
+ results: {
20
+ readonly [key: string]: unknown;
21
+ };
22
+ entityMeta: {
23
+ readonly [entityKey: string]: {
24
+ readonly [pk: string]: {
25
+ readonly date: number;
26
+ readonly expiresAt: number;
27
+ readonly fetchedAt: number;
28
+ };
29
+ };
30
+ };
31
+ optimistic: (import("../../newActions.js").SetAction | import("../../newActions.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
+ }>)[];
34
+ lastReset: number;
35
+ };
36
+ //# sourceMappingURL=expireReducer.d.ts.map