ropegeo-common 1.12.12 → 1.12.14

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.
@@ -44,6 +44,12 @@ export type RopeGeoCursorPaginationHttpRequestProps<T = unknown> = {
44
44
  loadMore: () => void;
45
45
  hasMore: boolean;
46
46
  timeoutCountdown: number | null;
47
+ /**
48
+ * Re-runs from the first page while online: aborts any `loadMore`, resets the cursor to the
49
+ * initial `queryParams`, sets `loading` to `true`, clears `errors`, and clears `data` until the
50
+ * new first page resolves. No-op when `isOnline` is `false`.
51
+ */
52
+ reload: () => void;
47
53
  }) => ReactNode;
48
54
  };
49
55
  export declare function RopeGeoCursorPaginationHttpRequest<T = unknown>({ service, method, path, pathParams, queryParams, timeoutAfterSeconds, isOnline, refreshOnReconnect, children, }: RopeGeoCursorPaginationHttpRequestProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"RopeGeoCursorPaginationHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoCursorPaginationHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAC;AAsCzE,MAAM,MAAM,uCAAuC,CAAC,CAAC,GAAG,OAAO,IAAI;IACjE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,EAAE,sBAAsB,CAAC;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,OAAO,CAAC;QACrB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF,wBAAgB,kCAAkC,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9D,OAAO,EACP,MAAmB,EACnB,IAAI,EACJ,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,uCAAuC,CAAC,CAAC,CAAC,2CAqV5C"}
1
+ {"version":3,"file":"RopeGeoCursorPaginationHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoCursorPaginationHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAC;AAsCzE,MAAM,MAAM,uCAAuC,CAAC,CAAC,GAAG,OAAO,IAAI;IACjE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,EAAE,sBAAsB,CAAC;IACpC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,OAAO,CAAC;QACrB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC;;;;WAIG;QACH,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF,wBAAgB,kCAAkC,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9D,OAAO,EACP,MAAmB,EACnB,IAAI,EACJ,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,uCAAuC,CAAC,CAAC,CAAC,2CAyY5C"}
@@ -38,6 +38,8 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
38
38
  const [errors, setErrors] = (0, react_1.useState)(null);
39
39
  const [timeoutCountdown, setTimeoutCountdown] = (0, react_1.useState)(null);
40
40
  const [hasCommittedOnce, setHasCommittedOnce] = (0, react_1.useState)(false);
41
+ const [reloadTick, setReloadTick] = (0, react_1.useState)(0);
42
+ const pendingReloadRef = (0, react_1.useRef)(false);
41
43
  const errorsRef = (0, react_1.useRef)(errors);
42
44
  const hasCommittedRef = (0, react_1.useRef)(hasCommittedOnce);
43
45
  errorsRef.current = errors;
@@ -57,12 +59,27 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
57
59
  const fullPath = queryString ? `${resolvedPath}?${queryString}` : resolvedPath;
58
60
  return new URL(fullPath, baseUrl).toString();
59
61
  }, [service, path, pathParams]);
62
+ const reload = (0, react_1.useCallback)(() => {
63
+ if (isOnline === false)
64
+ return;
65
+ pendingReloadRef.current = true;
66
+ setReloadTick((n) => n + 1);
67
+ }, [isOnline]);
60
68
  (0, react_1.useEffect)(() => {
61
69
  const online = isOnline !== false;
62
70
  const prevOnline = prevIsOnlineRef.current;
63
71
  const reconnecting = prevOnline === false && online;
64
72
  const keyChanged = lastRequestKeyRef.current !== requestKey;
73
+ const isManualReload = pendingReloadRef.current;
74
+ if (isManualReload) {
75
+ pendingReloadRef.current = false;
76
+ loadMoreAbortRef.current?.abort();
77
+ loadMoreAbortRef.current = null;
78
+ loadingMoreRef.current = false;
79
+ setLoadingMore(false);
80
+ }
65
81
  if (!online) {
82
+ pendingReloadRef.current = false;
66
83
  if (keyChanged) {
67
84
  lastRequestKeyRef.current = requestKey;
68
85
  setData(null);
@@ -87,9 +104,18 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
87
104
  setParams(queryParams);
88
105
  setErrors(null);
89
106
  }
107
+ else if (isManualReload) {
108
+ setHasCommittedOnce(false);
109
+ setData(null);
110
+ setParams(queryParams);
111
+ setErrors(null);
112
+ }
90
113
  if (!keyChanged && reconnecting) {
91
114
  const onlyNoNetwork = errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE;
92
- if (hasCommittedRef.current && onlyNoNetwork && !refreshOnReconnect) {
115
+ if (!isManualReload &&
116
+ hasCommittedRef.current &&
117
+ onlyNoNetwork &&
118
+ !refreshOnReconnect) {
93
119
  setErrors(null);
94
120
  setLoading(false);
95
121
  prevIsOnlineRef.current = true;
@@ -109,7 +135,7 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
109
135
  hasCommittedRef.current &&
110
136
  errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE &&
111
137
  refreshOnReconnect;
112
- if (!keyChanged && !keepStaleDuringFetch) {
138
+ if (!keyChanged && !keepStaleDuringFetch && !isManualReload) {
113
139
  setData(null);
114
140
  setParams(queryParams);
115
141
  }
@@ -222,6 +248,7 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
222
248
  isOnline,
223
249
  refreshOnReconnect,
224
250
  requestKey,
251
+ reloadTick,
225
252
  ]);
226
253
  (0, react_1.useEffect)(() => {
227
254
  return () => {
@@ -270,10 +297,16 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
270
297
  fetch(url, init)
271
298
  .then(async (res) => {
272
299
  const text = await res.text();
273
- if (!res.ok)
300
+ if (!res.ok) {
301
+ setErrors(new Error((0, network_1.formatHttpStatusMessage)(res.status, text || res.statusText)));
302
+ setParams((p) => p.withCursor(null));
274
303
  return;
275
- if (text.length === 0)
304
+ }
305
+ if (text.length === 0) {
306
+ setErrors(null);
307
+ setParams((p) => p.withCursor(null));
276
308
  return;
309
+ }
277
310
  try {
278
311
  const raw = JSON.parse(text);
279
312
  const body = getResponseBody(raw);
@@ -281,6 +314,7 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
281
314
  const { results, nextCursor } = result;
282
315
  setData((prev) => [...(prev ?? []), ...results]);
283
316
  setParams((p) => p.withCursor(nextCursor));
317
+ setErrors(null);
284
318
  }
285
319
  catch (parseError) {
286
320
  console.error("[RopeGeoCursorPaginationHttpRequest] loadMore: Invalid JSON response", {
@@ -289,6 +323,8 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
289
323
  responseText: text.slice(0, 500),
290
324
  parseError: parseError instanceof Error ? parseError.message : String(parseError),
291
325
  });
326
+ setErrors(new Error("Invalid JSON response"));
327
+ setParams((p) => p.withCursor(null));
292
328
  }
293
329
  })
294
330
  .catch((err) => {
@@ -296,6 +332,8 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
296
332
  return;
297
333
  if (timedOutRef.current) {
298
334
  console.error("[RopeGeoCursorPaginationHttpRequest] loadMore: timed out", { url });
335
+ setErrors(new Error((0, network_1.formatNetworkRequestErrorMessage)(new Error(network_1.NETWORK_REQUEST_TIMED_OUT_MESSAGE))));
336
+ setParams((p) => p.withCursor(null));
299
337
  return;
300
338
  }
301
339
  if ((0, network_1.isAbortError)(err))
@@ -304,6 +342,8 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
304
342
  url,
305
343
  error: err instanceof Error ? err.message : String(err),
306
344
  });
345
+ setErrors(new Error((0, network_1.formatNetworkRequestErrorMessage)(err)));
346
+ setParams((p) => p.withCursor(null));
307
347
  })
308
348
  .finally(() => {
309
349
  policyDispose();
@@ -325,5 +365,6 @@ function RopeGeoCursorPaginationHttpRequest({ service, method = RopeGeoHttpReque
325
365
  loadMore,
326
366
  hasMore,
327
367
  timeoutCountdown,
368
+ reload,
328
369
  }) }));
329
370
  }
@@ -56,6 +56,12 @@ export type RopeGeoHttpRequestProps<T = unknown> = {
56
56
  * after `NETWORK_REQUEST_SLOW_THRESHOLD_MS` from `ropegeo-common/helpers`).
57
57
  */
58
58
  timeoutCountdown: number | null;
59
+ /**
60
+ * Re-runs the current request while online. Sets `loading` to `true`, clears `errors`, and
61
+ * keeps existing `data` visible until the new response resolves (when data was already
62
+ * committed). No-op when `isOnline` is `false`.
63
+ */
64
+ reload: () => void;
59
65
  }) => ReactNode;
60
66
  };
61
67
  export declare function RopeGeoHttpRequest<T = unknown>({ service, method, path, pathParams, queryParams, body, timeoutAfterSeconds, isOnline, refreshOnReconnect, children, }: RopeGeoHttpRequestProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"RopeGeoHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,eAAO,MAAM,OAAO;;CAEV,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE7D,eAAO,MAAM,MAAM;;;;;CAKT,CAAC;AACX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAEpD,CAAC;AAmCF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,OAAO,IAAI;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB;;;;WAIG;QACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9C,OAAO,EACP,MAAM,EACN,IAAI,EACJ,UAAU,EACV,WAAW,EACX,IAAI,EACJ,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,uBAAuB,CAAC,CAAC,CAAC,2CAkO5B"}
1
+ {"version":3,"file":"RopeGeoHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,eAAO,MAAM,OAAO;;CAEV,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE7D,eAAO,MAAM,MAAM;;;;;CAKT,CAAC;AACX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAEpD,CAAC;AAmCF,MAAM,MAAM,uBAAuB,CAAC,CAAC,GAAG,OAAO,IAAI;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB;;;;WAIG;QACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC;;;;WAIG;QACH,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9C,OAAO,EACP,MAAM,EACN,IAAI,EACJ,UAAU,EACV,WAAW,EACX,IAAI,EACJ,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,uBAAuB,CAAC,CAAC,CAAC,2CAuP5B"}
@@ -46,10 +46,18 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
46
46
  const [errors, setErrors] = (0, react_1.useState)(null);
47
47
  const [timeoutCountdown, setTimeoutCountdown] = (0, react_1.useState)(null);
48
48
  const [hasCommittedOnce, setHasCommittedOnce] = (0, react_1.useState)(false);
49
+ const [reloadTick, setReloadTick] = (0, react_1.useState)(0);
50
+ const pendingReloadRef = (0, react_1.useRef)(false);
49
51
  const errorsRef = (0, react_1.useRef)(errors);
50
52
  const hasCommittedRef = (0, react_1.useRef)(hasCommittedOnce);
51
53
  errorsRef.current = errors;
52
54
  hasCommittedRef.current = hasCommittedOnce;
55
+ const reload = (0, react_1.useCallback)(() => {
56
+ if (isOnline === false)
57
+ return;
58
+ pendingReloadRef.current = true;
59
+ setReloadTick((n) => n + 1);
60
+ }, [isOnline]);
53
61
  const pathParamsKey = JSON.stringify(pathParams ?? null);
54
62
  const queryParamsKey = JSON.stringify(queryParams ?? null);
55
63
  const bodyKey = body === undefined || body === null
@@ -65,7 +73,12 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
65
73
  const prevOnline = prevIsOnlineRef.current;
66
74
  const reconnecting = prevOnline === false && online;
67
75
  const keyChanged = lastRequestKeyRef.current !== requestKey;
76
+ const isManualReload = pendingReloadRef.current;
77
+ if (isManualReload) {
78
+ pendingReloadRef.current = false;
79
+ }
68
80
  if (!online) {
81
+ pendingReloadRef.current = false;
69
82
  if (keyChanged) {
70
83
  lastRequestKeyRef.current = requestKey;
71
84
  setData(null);
@@ -86,7 +99,10 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
86
99
  }
87
100
  if (!keyChanged && reconnecting) {
88
101
  const onlyNoNetwork = errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE;
89
- if (hasCommittedRef.current && onlyNoNetwork && !refreshOnReconnect) {
102
+ if (!isManualReload &&
103
+ hasCommittedRef.current &&
104
+ onlyNoNetwork &&
105
+ !refreshOnReconnect) {
90
106
  setErrors(null);
91
107
  setLoading(false);
92
108
  prevIsOnlineRef.current = true;
@@ -106,7 +122,8 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
106
122
  hasCommittedRef.current &&
107
123
  errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE &&
108
124
  refreshOnReconnect;
109
- if (!keyChanged && !keepStaleDuringFetch) {
125
+ const keepStaleForManualReload = isManualReload && hasCommittedRef.current;
126
+ if (!keyChanged && !keepStaleDuringFetch && !keepStaleForManualReload) {
110
127
  setData(null);
111
128
  }
112
129
  const policyDispose = timeoutMs == null
@@ -220,6 +237,7 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
220
237
  isOnline,
221
238
  refreshOnReconnect,
222
239
  requestKey,
240
+ reloadTick,
223
241
  ]);
224
242
  const refreshing = loading && hasCommittedOnce;
225
243
  return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children({
@@ -228,5 +246,6 @@ function RopeGeoHttpRequest({ service, method, path, pathParams, queryParams, bo
228
246
  data,
229
247
  errors,
230
248
  timeoutCountdown,
249
+ reload,
231
250
  }) }));
232
251
  }
@@ -51,6 +51,12 @@ export type RopeGeoPaginationHttpRequestProps<T = unknown> = {
51
51
  errors: Error | null;
52
52
  /** Timeout countdown for the active phase (initial page or current batch); `null` between phases. */
53
53
  timeoutCountdown: number | null;
54
+ /**
55
+ * Re-runs the full pagination pass while online. Sets `loading` to `true`, clears `errors`,
56
+ * and resets progress (`received` / `total` / `data`) until the new pass completes. No-op when
57
+ * `isOnline` is `false`.
58
+ */
59
+ reload: () => void;
54
60
  }) => ReactNode;
55
61
  };
56
62
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"RopeGeoPaginationHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoPaginationHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAC;AA8DzE,MAAM,MAAM,iCAAiC,CAAC,CAAC,GAAG,OAAO,IAAI;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB;;;WAGG;QACH,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,+FAA+F;QAC/F,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB,qGAAqG;QACrG,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,GAAG,OAAO,EAAE,EACxD,OAAO,EACP,MAAmB,EACnB,IAAI,EACJ,UAAU,EACV,WAAW,EACX,SAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,iCAAiC,CAAC,CAAC,CAAC,2CAyTtC"}
1
+ {"version":3,"file":"RopeGeoPaginationHttpRequest.d.ts","sourceRoot":"","sources":["../../src/components/RopeGeoPaginationHttpRequest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAC;AA8DzE,MAAM,MAAM,iCAAiC,CAAC,CAAC,GAAG,OAAO,IAAI;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB;;;WAGG;QACH,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,+FAA+F;QAC/F,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;QACrB,qGAAqG;QACrG,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC;;;;WAIG;QACH,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,GAAG,OAAO,EAAE,EACxD,OAAO,EACP,MAAmB,EACnB,IAAI,EACJ,UAAU,EACV,WAAW,EACX,SAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,kBAA0B,EAC1B,QAAQ,GACT,EAAE,iCAAiC,CAAC,CAAC,CAAC,2CAmVtC"}
@@ -65,6 +65,8 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
65
65
  const [errors, setErrors] = (0, react_1.useState)(null);
66
66
  const [timeoutCountdown, setTimeoutCountdown] = (0, react_1.useState)(null);
67
67
  const [hasCommittedOnce, setHasCommittedOnce] = (0, react_1.useState)(false);
68
+ const [reloadTick, setReloadTick] = (0, react_1.useState)(0);
69
+ const pendingReloadRef = (0, react_1.useRef)(false);
68
70
  const errorsRef = (0, react_1.useRef)(errors);
69
71
  const hasCommittedRef = (0, react_1.useRef)(hasCommittedOnce);
70
72
  errorsRef.current = errors;
@@ -75,12 +77,23 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
75
77
  const requestKey = (0, react_1.useMemo)(() => `${service}|${method}|${path}|${pathParamsKey}|${queryParamsKey}|${effectiveBatch}|${timeoutAfterSeconds ?? ""}`, [service, method, path, pathParamsKey, queryParamsKey, effectiveBatch, timeoutAfterSeconds]);
76
78
  const prevIsOnlineRef = (0, react_1.useRef)(undefined);
77
79
  const lastRequestKeyRef = (0, react_1.useRef)("");
80
+ const reload = (0, react_1.useCallback)(() => {
81
+ if (isOnline === false)
82
+ return;
83
+ pendingReloadRef.current = true;
84
+ setReloadTick((n) => n + 1);
85
+ }, [isOnline]);
78
86
  (0, react_1.useEffect)(() => {
79
87
  const online = isOnline !== false;
80
88
  const prevOnline = prevIsOnlineRef.current;
81
89
  const reconnecting = prevOnline === false && online;
82
90
  const keyChanged = lastRequestKeyRef.current !== requestKey;
91
+ const isManualReload = pendingReloadRef.current;
92
+ if (isManualReload) {
93
+ pendingReloadRef.current = false;
94
+ }
83
95
  if (!online) {
96
+ pendingReloadRef.current = false;
84
97
  if (keyChanged) {
85
98
  lastRequestKeyRef.current = requestKey;
86
99
  setHasCommittedOnce(false);
@@ -103,9 +116,19 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
103
116
  setData(null);
104
117
  setErrors(null);
105
118
  }
119
+ else if (isManualReload) {
120
+ setHasCommittedOnce(false);
121
+ setReceived(0);
122
+ setTotal(null);
123
+ setData(null);
124
+ setErrors(null);
125
+ }
106
126
  if (!keyChanged && reconnecting) {
107
127
  const onlyNoNetwork = errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE;
108
- if (hasCommittedRef.current && onlyNoNetwork && !refreshOnReconnect) {
128
+ if (!isManualReload &&
129
+ hasCommittedRef.current &&
130
+ onlyNoNetwork &&
131
+ !refreshOnReconnect) {
109
132
  setErrors(null);
110
133
  setLoading(false);
111
134
  prevIsOnlineRef.current = true;
@@ -124,7 +147,7 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
124
147
  hasCommittedRef.current &&
125
148
  errorsRef.current?.message === network_1.NO_NETWORK_MESSAGE &&
126
149
  refreshOnReconnect;
127
- if (!keyChanged && !keepStaleDuringFetch) {
150
+ if (!keyChanged && !keepStaleDuringFetch && !isManualReload) {
128
151
  setReceived(0);
129
152
  setTotal(null);
130
153
  setData(null);
@@ -326,6 +349,7 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
326
349
  isOnline,
327
350
  refreshOnReconnect,
328
351
  requestKey,
352
+ reloadTick,
329
353
  ]);
330
354
  const refreshing = loading && hasCommittedOnce;
331
355
  return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children({
@@ -336,5 +360,6 @@ function RopeGeoPaginationHttpRequest({ service, method = RopeGeoHttpRequest_1.M
336
360
  data,
337
361
  errors,
338
362
  timeoutCountdown,
363
+ reload,
339
364
  }) }));
340
365
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ropegeo-common",
3
- "version": "1.12.12",
3
+ "version": "1.12.14",
4
4
  "description": "Shared domain models and helpers for RopeGeo and WebScraper",
5
5
  "license": "ISC",
6
6
  "repository": {