@dr.pogodin/react-global-state 0.14.0 → 0.14.2

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { cloneDeep } from 'lodash';
6
- import { useEffect } from 'react';
6
+ import { useEffect, useRef } from 'react';
7
7
  import { v4 as uuid } from 'uuid';
8
8
 
9
9
  import { MIN_MS } from '@dr.pogodin/js-utils';
@@ -27,6 +27,9 @@ const DEFAULT_MAXAGE = 5 * MIN_MS; // 5 minutes.
27
27
  export type AsyncDataLoaderT<DataT>
28
28
  = (oldData: null | DataT) => DataT | Promise<DataT>;
29
29
 
30
+ export type AsyncDataReloaderT<DataT>
31
+ = (loader?: AsyncDataLoaderT<DataT>) => Promise<void>;
32
+
30
33
  export type AsyncDataEnvelopeT<DataT> = {
31
34
  data: null | DataT;
32
35
  numRefs: number;
@@ -57,7 +60,7 @@ export type UseAsyncDataOptionsT = {
57
60
  export type UseAsyncDataResT<DataT> = {
58
61
  data: DataT | null;
59
62
  loading: boolean;
60
- reload: (loader?: AsyncDataLoaderT<DataT>) => Promise<void>;
63
+ reload: AsyncDataReloaderT<DataT>;
61
64
  timestamp: number;
62
65
  };
63
66
 
@@ -92,9 +95,14 @@ async function load<DataT>(
92
95
  const operationId = opIdPrefix + uuid();
93
96
  const operationIdPath = path ? `${path}.operationId` : 'operationId';
94
97
  globalState.set<ForceT, string>(operationIdPath, operationId);
95
- const data = await loader(
98
+
99
+ const dataOrLoader = loader(
96
100
  oldData || (globalState.get<ForceT, AsyncDataEnvelopeT<DataT>>(path)).data,
97
101
  );
102
+
103
+ const data: DataT = dataOrLoader instanceof Promise
104
+ ? await dataOrLoader : dataOrLoader;
105
+
98
106
  const state: AsyncDataEnvelopeT<DataT> = globalState.get<ForceT, AsyncDataEnvelopeT<DataT>>(path);
99
107
  if (operationId === state.operationId) {
100
108
  if (process.env.NODE_ENV !== 'production' && isDebugMode()) {
@@ -174,6 +182,14 @@ export type DataInEnvelopeAtPathT<StateT, PathT extends null | string | undefine
174
182
  ? Exclude<ValueAtPathT<StateT, PathT, never>['data'], null>
175
183
  : void;
176
184
 
185
+ type HeapT<DataT> = {
186
+ // Note: these heap fields are necessary to make reload() a stable function.
187
+ globalState?: GlobalState<unknown>;
188
+ path?: null | string;
189
+ loader?: AsyncDataLoaderT<DataT>;
190
+ reload?: AsyncDataReloaderT<DataT>;
191
+ };
192
+
177
193
  function useAsyncData<
178
194
  StateT,
179
195
  PathT extends null | string | undefined,
@@ -216,6 +232,19 @@ function useAsyncData<DataT>(
216
232
  initialValue: newAsyncDataEnvelope<DataT>(),
217
233
  });
218
234
 
235
+ const { current: heap } = useRef<HeapT<DataT>>({});
236
+ heap.globalState = globalState;
237
+ heap.path = path;
238
+ heap.loader = loader;
239
+
240
+ if (!heap.reload) {
241
+ heap.reload = (customLoader?: AsyncDataLoaderT<DataT>) => {
242
+ const localLoader = customLoader || heap.loader;
243
+ if (!localLoader || !heap.globalState) throw Error('Internal error');
244
+ return load(heap.path, localLoader, heap.globalState, null);
245
+ };
246
+ }
247
+
219
248
  if (globalState.ssrContext && !options.noSSR) {
220
249
  if (!state.timestamp && !state.operationId) {
221
250
  globalState.ssrContext.pending.push(
@@ -301,19 +330,12 @@ function useAsyncData<DataT>(
301
330
  return {
302
331
  data: maxage < Date.now() - localState.timestamp ? null : localState.data,
303
332
  loading: Boolean(localState.operationId),
304
-
305
- reload: (customLoader?: AsyncDataLoaderT<DataT>) => load(
306
- path,
307
- customLoader || loader,
308
- globalState,
309
- null,
310
- ),
311
-
333
+ reload: heap.reload,
312
334
  timestamp: localState.timestamp,
313
335
  };
314
336
  }
315
337
 
316
- export default useAsyncData;
338
+ export { useAsyncData };
317
339
 
318
340
  export interface UseAsyncDataI<StateT> {
319
341
  <PathT extends null | string | undefined>(
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "./node_modules/@tsconfig/recommended/tsconfig.json",
2
+ "extends": "@tsconfig/recommended",
3
3
  "compilerOptions": {
4
4
  "declaration": true,
5
5
  "jsx": "react-jsx",
@@ -0,0 +1,6 @@
1
+ {
2
+ "testFileMatch": [
3
+ "__tests__/ts",
4
+ "__tests__/ts-types"
5
+ ]
6
+ }