@alxia/react-router 0.39.0 → 0.41.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.
- package/README.md +39 -1
- package/dist/fetcher/index.d.ts +5 -2
- package/dist/fetcher/index.d.ts.map +1 -1
- package/dist/fetcher/index.js +41 -2
- package/dist/fetcher/index.js.map +6 -4
- package/dist/fetcher/use-visible-interval.d.ts +24 -0
- package/dist/fetcher/use-visible-interval.d.ts.map +1 -0
- package/dist/fetcher/use-visible-revalidation.d.ts +10 -0
- package/dist/fetcher/use-visible-revalidation.d.ts.map +1 -0
- package/dist/session/index.js +20 -3
- package/dist/session/index.js.map +3 -3
- package/dist/session/throttle.d.ts +16 -2
- package/dist/session/throttle.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/guide/fetcher.md +45 -3
- package/docs/guide/session.md +40 -1
- package/docs/roadmap.md +13 -0
- package/docs/troubleshooting.md +10 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1055,6 +1055,23 @@ if (!checked.value) {
|
|
|
1055
1055
|
throttle.clear(email);
|
|
1056
1056
|
```
|
|
1057
1057
|
|
|
1058
|
+
Past the global limit the default is a refusal for every key. To only slow
|
|
1059
|
+
attempts down, use `globalMode: 'delay'`: `wait(key)` then answers per key
|
|
1060
|
+
alone, and `globalDelay()` gives a delay in milliseconds that grows with the
|
|
1061
|
+
failures past `globalMax` and stops at `maxDelayMs` (3 000 by default).
|
|
1062
|
+
|
|
1063
|
+
```ts
|
|
1064
|
+
const throttle = createSignInThrottle({
|
|
1065
|
+
globalMax: 20,
|
|
1066
|
+
globalWindowMs: 15 * 60_000,
|
|
1067
|
+
globalMode: 'delay',
|
|
1068
|
+
maxDelayMs: 3_000,
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
const delay = throttle.globalDelay(); // 0 below globalMax
|
|
1072
|
+
if (delay > 0) await Bun.sleep(delay);
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1058
1075
|
## A GraphQL subscription for the browser
|
|
1059
1076
|
|
|
1060
1077
|
`@alxia/react-router/subscription` exposes subscriptions of your API to the
|
|
@@ -1158,6 +1175,25 @@ const { data, stale, state, retry } = useDebouncedFetcher<Found>(
|
|
|
1158
1175
|
);
|
|
1159
1176
|
```
|
|
1160
1177
|
|
|
1178
|
+
A screen with no real-time channel reads its data again every N ms, **only while the page is visible**, and at once when a hidden page comes back after more than N ms:
|
|
1179
|
+
|
|
1180
|
+
```tsx
|
|
1181
|
+
import { useFetcher } from 'react-router';
|
|
1182
|
+
import {
|
|
1183
|
+
useVisibleInterval,
|
|
1184
|
+
useVisibleRevalidation,
|
|
1185
|
+
} from '@alxia/react-router/fetcher';
|
|
1186
|
+
|
|
1187
|
+
// inside a component: the route's loaders, every minute
|
|
1188
|
+
useVisibleRevalidation(60_000);
|
|
1189
|
+
|
|
1190
|
+
// any callback, such as a fetcher's load; `enabled: false` pauses it
|
|
1191
|
+
const fetcher = useFetcher<Counts>();
|
|
1192
|
+
useVisibleInterval(() => void fetcher.load('/counts'), 300_000, {
|
|
1193
|
+
enabled: !menuOpen,
|
|
1194
|
+
});
|
|
1195
|
+
```
|
|
1196
|
+
|
|
1161
1197
|
See the [fetcher guide](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/fetcher.md).
|
|
1162
1198
|
|
|
1163
1199
|
## A list whose state is the URL
|
|
@@ -1458,6 +1494,8 @@ From `@alxia/react-router/fetcher` (`react` and `react-router` are its imports;
|
|
|
1458
1494
|
| `useFetcherAnswer(fetcher, onAnswer?)`, `AnswerSource` | `onAnswer(answer)` once per answer that arrives while the fetcher is idle and differs from the last one seen (the data present at mount counts as seen); the handler is read from a ref; returns the latest answer handed over, `undefined` before the first |
|
|
1459
1495
|
| `useFetcherPromise(fetcher, { refusal? }?)`, `FetcherPromiseOptions`, `FetcherPromiseAborted` | returns a stable `run(submit)` that calls `submit` (`() => fetcher.submit(...)`) and returns a Promise settled by the fetcher's next new answer: resolved with it, or rejected with an `Error` when `refusal(answer)` returns a message (or your own `Error`); an answer held before the call never settles it; a second `run` while one is pending rejects the older with `FetcherPromiseAborted` (`reason: 'superseded'`); an unmount rejects the pending one (`'unmounted'`); a `submit` that throws rejects with its error |
|
|
1460
1496
|
| `useFormRefusal(result)`, `FormRefusalResult` | `useFormRefusal(fetcher.data)` returns the `FormErrors` of a fetcher answer that carries `fieldErrors` (`apiErrors.formRefusal`'s), `undefined` for no answer, a done step or a refusal without them; stable for one answer |
|
|
1497
|
+
| `useVisibleInterval(callback, ms, { enabled?, runOnVisible? }?)`, `VisibleIntervalOptions` | runs `callback` every `ms` only while `document.visibilityState` is `'visible'` (a tick while hidden is skipped); when a hidden page becomes visible after at least `ms` since the last run it runs at once (`runOnVisible`, default `true`); `enabled: false` stops it; the callback is read from a ref, so a new function never restarts the timer; the timer and listener are cleared on unmount; nothing starts on the server |
|
|
1498
|
+
| `useVisibleRevalidation(ms, { enabled? }?)` | `useVisibleInterval` over `useRevalidator`: revalidates the route's loaders every `ms` while the page is visible, skipping a tick while a revalidation is in flight |
|
|
1461
1499
|
| `useDebouncedFetcher(value, to, { delayMs?, minLength?, enabled?, key?, keep? }?)`, `DebouncedFetcher`, `DebouncedFetcherOptions`, `DebouncedFetcherState` | a resource route loaded for what is typed: one `fetcher.load` after `delayMs` (250) without a change and from `minLength` (1) trimmed characters; `to` is a URL or `(value) => url`; returns `{ data, stale, state, retry }`: `data` is the answer for the value as it stands, else the previous one with `stale` set; `state` is `'idle' \| 'waiting' \| 'loading' \| 'done'`; `keep(answer)` filters what may stay as the stale answer; `retry()` (stable) asks again at once |
|
|
1462
1500
|
|
|
1463
1501
|
From `@alxia/react-router/subscription` (no import, no peer):
|
|
@@ -1484,7 +1522,7 @@ The `alxia-react-router` bin, run with `bunx`:
|
|
|
1484
1522
|
- [Installable and offline](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/pwa.md): what the subpaths hold, the worker's contract, the worker, what it caches, the offline page, building the worker with `alxia()` or `buildWorker`, the hooks in React, registering the worker and offering an update, serving the worker's script, the web app manifest, and clearing at sign-out.
|
|
1485
1523
|
- [An API's refusals](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/errors.md): what `/errors` holds, recognising an API error, the request id, the page a request is for, the catalogue store, the form checks in the API's words, the provider, wording a refusal, loaders and the error page, actions, JSON actions and CSRF, and keeping the catalogue fresh.
|
|
1486
1524
|
- [A BFF session](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/session.md): redirects that stay on the site, the cookies, the sign-in route, the second factor, the viewer and sign-out, the step-up, and the pages a mail's link opens.
|
|
1487
|
-
- [A fetcher's fresh answer](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/fetcher.md): `useFetcherAnswer`: a handler called once per new answer of a keyed fetcher, not for the data it held at mount; `useFetcherPromise`: one submission's answer as a Promise; `useDebouncedFetcher`: a resource route loaded for what is typed.
|
|
1525
|
+
- [A fetcher's fresh answer](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/fetcher.md): `useFetcherAnswer`: a handler called once per new answer of a keyed fetcher, not for the data it held at mount; `useFetcherPromise`: one submission's answer as a Promise; `useDebouncedFetcher`: a resource route loaded for what is typed; `useVisibleInterval` and `useVisibleRevalidation`: a callback or a revalidation on an interval while the page is visible.
|
|
1488
1526
|
- [Lists whose state is the URL](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/lists.md): `useSearchChange`, `useSameRouteLoading`, `usePagedRows`: a search that drops the cursor, a skeleton for the same page reloading, a load-more button.
|
|
1489
1527
|
- [Subscriptions for a BFF](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/subscriptions.md): exposing a GraphQL subscription to the browser through a resource route: the allow-list, the session's bearer, the headers, the heartbeat, abort and rate limits.
|
|
1490
1528
|
- [Troubleshooting](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/troubleshooting.md): each message, and the traps that print none.
|
package/dist/fetcher/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@alxia/react-router/fetcher`: the hooks around a React Router fetcher's
|
|
3
|
-
* answers
|
|
4
|
-
*
|
|
3
|
+
* answers, and the ones that keep a screen fresh while its page is visible.
|
|
4
|
+
* `react` and `react-router` are its imports, and every hook renders on the
|
|
5
|
+
* server (a load starts in the browser only).
|
|
5
6
|
*/
|
|
6
7
|
export { type DebouncedFetcher, type DebouncedFetcherOptions, type DebouncedFetcherState, useDebouncedFetcher, } from './use-debounced-fetcher';
|
|
7
8
|
export { type AnswerSource, useFetcherAnswer } from './use-fetcher-answer';
|
|
8
9
|
export { FetcherPromiseAborted, type FetcherPromiseOptions, useFetcherPromise, } from './use-fetcher-promise';
|
|
9
10
|
export { type FormRefusalResult, useFormRefusal } from './use-form-refusal';
|
|
11
|
+
export { useVisibleInterval, type VisibleIntervalOptions, } from './use-visible-interval';
|
|
12
|
+
export { useVisibleRevalidation } from './use-visible-revalidation';
|
|
10
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetcher/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetcher/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,mBAAmB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EACN,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,iBAAiB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACN,kBAAkB,EAClB,KAAK,sBAAsB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/fetcher/index.js
CHANGED
|
@@ -154,13 +154,52 @@ function useFormRefusal(result) {
|
|
|
154
154
|
formError: result.error || undefined
|
|
155
155
|
} : undefined, [result]);
|
|
156
156
|
}
|
|
157
|
+
// src/fetcher/use-visible-interval.ts
|
|
158
|
+
import { useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
159
|
+
function useVisibleInterval(callback, ms, options = {}) {
|
|
160
|
+
const { enabled = true, runOnVisible = true } = options;
|
|
161
|
+
const latest = useRef4(callback);
|
|
162
|
+
latest.current = callback;
|
|
163
|
+
useEffect4(() => {
|
|
164
|
+
if (!enabled || ms <= 0)
|
|
165
|
+
return;
|
|
166
|
+
let last = Date.now();
|
|
167
|
+
const run = () => {
|
|
168
|
+
if (document.visibilityState !== "visible")
|
|
169
|
+
return;
|
|
170
|
+
last = Date.now();
|
|
171
|
+
latest.current();
|
|
172
|
+
};
|
|
173
|
+
const timer = setInterval(run, ms);
|
|
174
|
+
const back = () => {
|
|
175
|
+
if (runOnVisible && Date.now() - last >= ms)
|
|
176
|
+
run();
|
|
177
|
+
};
|
|
178
|
+
document.addEventListener("visibilitychange", back);
|
|
179
|
+
return () => {
|
|
180
|
+
clearInterval(timer);
|
|
181
|
+
document.removeEventListener("visibilitychange", back);
|
|
182
|
+
};
|
|
183
|
+
}, [ms, enabled, runOnVisible]);
|
|
184
|
+
}
|
|
185
|
+
// src/fetcher/use-visible-revalidation.ts
|
|
186
|
+
import { useRevalidator } from "react-router";
|
|
187
|
+
function useVisibleRevalidation(ms, options) {
|
|
188
|
+
const revalidator = useRevalidator();
|
|
189
|
+
useVisibleInterval(() => {
|
|
190
|
+
if (revalidator.state === "idle")
|
|
191
|
+
revalidator.revalidate();
|
|
192
|
+
}, ms, options);
|
|
193
|
+
}
|
|
157
194
|
export {
|
|
158
195
|
FetcherPromiseAborted,
|
|
159
196
|
useDebouncedFetcher,
|
|
160
197
|
useFetcherAnswer,
|
|
161
198
|
useFetcherPromise,
|
|
162
|
-
useFormRefusal
|
|
199
|
+
useFormRefusal,
|
|
200
|
+
useVisibleInterval,
|
|
201
|
+
useVisibleRevalidation
|
|
163
202
|
};
|
|
164
203
|
|
|
165
|
-
//# debugId=
|
|
204
|
+
//# debugId=70FA37428A43B8C264756E2164756E21
|
|
166
205
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/fetcher/use-debounced-fetcher.ts", "../src/fetcher/use-fetcher-answer.ts", "../src/fetcher/use-fetcher-promise.ts", "../src/fetcher/use-form-refusal.ts"],
|
|
3
|
+
"sources": ["../src/fetcher/use-debounced-fetcher.ts", "../src/fetcher/use-fetcher-answer.ts", "../src/fetcher/use-fetcher-promise.ts", "../src/fetcher/use-form-refusal.ts", "../src/fetcher/use-visible-interval.ts", "../src/fetcher/use-visible-revalidation.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import {\n\tstartTransition,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { useFetcher } from 'react-router';\n\n/** What `useFetcher<Data>` hands back as `data` (`Data` may be `typeof loader`). */\ntype FetcherData<Data> = ReturnType<typeof useFetcher<Data>>['data'];\n\n/** What `useDebouncedFetcher` is doing for the value typed. */\nexport type DebouncedFetcherState =\n\t/** Nothing to ask: disabled, or the value is shorter than `minLength`. */\n\t| 'idle'\n\t/** The value changed and the pause after the last change is running. */\n\t| 'waiting'\n\t/** The resource route is loading. */\n\t| 'loading'\n\t/** The route answered for the value as it stands. */\n\t| 'done';\n\nexport interface DebouncedFetcherOptions<Data = unknown> {\n\t/** Pause after the last change before the route is asked. Default 250. */\n\treadonly delayMs?: number;\n\t/** The trimmed value must have this many characters. Default 1. */\n\treadonly minLength?: number;\n\t/** `false` asks nothing and forgets the previous answer. Default `true`. */\n\treadonly enabled?: boolean;\n\t/** The fetcher's key, to share it with another component. */\n\treadonly key?: string;\n\t/**\n\t * Which answers may be kept as the stale `data` while the next value waits\n\t * or loads. Default: all. An answer it refuses (a failure) is still `data`\n\t * while it is the current one, but is never shown as the previous one: after a refused answer, the stale\n\t * data is the last *kept* answer, not the refused one.\n\t */\n\treadonly keep?: (data: NonNullable<FetcherData<Data>>) => boolean;\n}\n\nexport interface DebouncedFetcher<Data> {\n\t/**\n\t * The route's answer for the value as it stands, else (`stale`) the last\n\t * answer for an earlier value, kept until the new one lands. `undefined`\n\t * before any answer, and again once the hook goes `idle`.\n\t */\n\treadonly data: FetcherData<Data>;\n\t/** `data` answers an earlier value (or none is current yet). */\n\treadonly stale: boolean;\n\treadonly state: DebouncedFetcherState;\n\t/** Asks the route again for the value as it stands, without waiting. */\n\treadonly retry: () => void;\n}\n\n/**\n * A resource route loaded through a fetcher for a value that changes as the\n * user types. After `delayMs` without a change, and from `minLength`\n * characters, it calls `fetcher.load` once (a newer load cancels the\n * previous one). An answer only counts for the value it was asked for: while\n * a newer value waits or loads, `data` is the previous answer with `stale`\n * set, and an answer for an older value is never returned as current.\n * `to` is the route's URL, or a function of the trimmed value that builds it\n * (a string without a function is loaded as it is, the value being only the\n * trigger). A refusal the route answers as data is `data` like any answer.\n */\nexport function useDebouncedFetcher<Data>(\n\tvalue: string,\n\tto: string | ((value: string) => string),\n\toptions: DebouncedFetcherOptions<Data> = {},\n): DebouncedFetcher<Data> {\n\tconst { delayMs = 250, minLength = 1, enabled = true, key, keep } = options;\n\tconst keepRef = useRef(keep);\n\tkeepRef.current = keep;\n\tconst fetcher = useFetcher<Data>(key === undefined ? undefined : { key });\n\tconst load = useRef(fetcher.load);\n\tload.current = fetcher.load;\n\tconst text = value.trim();\n\tconst url =\n\t\tenabled && text.length >= minLength\n\t\t\t? typeof to === 'function'\n\t\t\t\t? to(text)\n\t\t\t\t: to\n\t\t\t: null;\n\t// The URL the fetcher was last told to load.\n\tconst [loaded, setLoaded] = useState<string | null>(null);\n\tconst previous = useRef<FetcherData<Data>>(undefined);\n\t// React Router applies the fetcher's `loading` state in a transition, so\n\t// right after `load()` a render can still show `idle` and the previous\n\t// answer. A load has landed only once the fetcher was seen busy for that very load (the load number is kept, so a busy render of a superseded load does not count), or\n\t// its `load()` promise settled and a transition queued after it committed\n\t// (a fast load whose busy state was never rendered, or a route answering\n\t// the very same object twice). `seq` numbers the loads, so a superseded\n\t// one never counts.\n\tconst seq = useRef(0);\n\tconst [settled, setSettled] = useState(0);\n\tconst busySeq = useRef(0);\n\tuseLayoutEffect(() => {\n\t\tif (fetcher.state !== 'idle') busySeq.current = seq.current;\n\t}, [fetcher.state]);\n\tconst ask = (target: string) => {\n\t\tconst mine = ++seq.current;\n\t\tsetLoaded(target);\n\t\tvoid Promise.resolve(load.current(target)).then(() => {\n\t\t\tif (mine === seq.current) startTransition(() => setSettled(mine));\n\t\t});\n\t};\n\tconst askRef = useRef(ask);\n\taskRef.current = ask;\n\n\tuseEffect(() => {\n\t\tif (url === null) {\n\t\t\tprevious.current = undefined;\n\t\t\tsetLoaded(null);\n\t\t\treturn;\n\t\t}\n\t\tconst timer = setTimeout(() => {\n\t\t\taskRef.current(url);\n\t\t}, delayMs);\n\t\treturn () => clearTimeout(timer);\n\t}, [url, text, delayMs]);\n\n\tconst landed =\n\t\tfetcher.state === 'idle' &&\n\t\t(busySeq.current === seq.current || settled === seq.current);\n\tconst current =\n\t\turl !== null && loaded === url && landed && fetcher.data !== undefined;\n\tconst answer = current ? fetcher.data : undefined;\n\tuseEffect(() => {\n\t\tif (answer === undefined || answer === null) return;\n\t\tif (keepRef.current?.(answer) ?? true) previous.current = answer;\n\t}, [answer]);\n\n\tconst data = current ? answer : url === null ? undefined : previous.current;\n\tlet state: DebouncedFetcherState;\n\tif (url === null) state = 'idle';\n\telse if (loaded !== url) state = 'waiting';\n\telse state = landed ? 'done' : 'loading';\n\n\tconst urlRef = useRef(url);\n\turlRef.current = url;\n\tconst retry = useCallback(() => {\n\t\tconst now = urlRef.current;\n\t\tif (now === null) return;\n\t\taskRef.current(now);\n\t}, []);\n\treturn { data, stale: state !== 'done' && data !== undefined, state, retry };\n}\n",
|
|
6
6
|
"import { useEffect, useRef, useState } from 'react';\n\n/** What the hook reads of a React Router fetcher. */\nexport interface AnswerSource<Data> {\n\treadonly state: string;\n\treadonly data: Data | undefined;\n}\n\n/**\n * The answers a fetcher gives, one at a time. A keyed fetcher outlives its\n * component, so the data it holds when the component mounts is an earlier\n * visit's, not this one's. `onAnswer` is called once for each answer that\n * arrives while the fetcher is idle and is another object than the last one\n * seen (the data present at mount counts as seen). The handler is read from\n * a ref, so a new function each render never re-fires it. Returns the latest\n * answer handed over, `undefined` until one arrives.\n */\nexport function useFetcherAnswer<Data>(\n\tfetcher: AnswerSource<Data>,\n\tonAnswer?: (answer: Data) => void,\n): Data | undefined {\n\tconst seen = useRef(fetcher.data);\n\tconst handler = useRef(onAnswer);\n\thandler.current = onAnswer;\n\tconst [latest, setLatest] = useState<Data | undefined>(undefined);\n\tconst answer = fetcher.state === 'idle' ? fetcher.data : undefined;\n\tuseEffect(() => {\n\t\tif (answer === undefined || answer === null || answer === seen.current) {\n\t\t\treturn;\n\t\t}\n\t\tseen.current = answer;\n\t\tsetLatest(answer);\n\t\thandler.current?.(answer);\n\t}, [answer]);\n\treturn latest;\n}\n",
|
|
7
7
|
"import { useCallback, useEffect, useRef } from 'react';\nimport { type AnswerSource, useFetcherAnswer } from './use-fetcher-answer';\n\n/** What `useFetcherPromise` accepts. */\nexport interface FetcherPromiseOptions<Data> {\n\t/**\n\t * Decides whether an answer is a refusal: the message (or the `Error`) the\n\t * promise rejects with, `undefined` to resolve with the answer. Read from a\n\t * ref, so a new function each render is fine. Without it every answer\n\t * resolves.\n\t */\n\trefusal?: (answer: Data) => string | Error | undefined;\n}\n\n/** The rejection of a call replaced by a newer one, or cut off by an unmount. */\nexport class FetcherPromiseAborted extends Error {\n\toverride readonly name = 'FetcherPromiseAborted';\n\treadonly reason: 'superseded' | 'unmounted';\n\tconstructor(reason: 'superseded' | 'unmounted') {\n\t\tsuper(\n\t\t\treason === 'superseded'\n\t\t\t\t? 'useFetcherPromise: a newer call replaced this one before the fetcher answered'\n\t\t\t\t: 'useFetcherPromise: the component unmounted before the fetcher answered',\n\t\t);\n\t\tthis.reason = reason;\n\t}\n}\n\ninterface Waiting<Data> {\n\tresolve(answer: Data): void;\n\treject(error: unknown): void;\n}\n\n/**\n * Ties one submission to its answer. `run(submit)` calls `submit` (usually\n * `() => fetcher.submit(...)`) and returns a Promise settled by the fetcher's\n * next new answer (see `useFetcherAnswer`): it resolves with the answer, or\n * rejects with an `Error` when `options.refusal` returns a message for it. An\n * answer the fetcher already held when `run` was called never settles it.\n *\n * A second `run` while one is pending rejects the older promise with a\n * `FetcherPromiseAborted` (`'superseded'`) and waits for the answer to the\n * newer one. An unmount rejects the pending promise with a\n * `FetcherPromiseAborted` (`'unmounted'`). A `submit` that throws (or whose\n * promise rejects) rejects the promise with that error, and so does a\n * `refusal` that throws. `run` is stable.\n *\n * Catch every promise `run` returns: an abort rejects it, and one nobody\n * handles is an unhandled rejection. Ignore the aborts with\n * `.catch((e) => { if (!(e instanceof FetcherPromiseAborted)) throw e; })`.\n */\nexport function useFetcherPromise<Data>(\n\tfetcher: AnswerSource<Data>,\n\toptions: FetcherPromiseOptions<Data> = {},\n): (submit: () => void | Promise<unknown>) => Promise<Data> {\n\tconst waiting = useRef<Waiting<Data> | null>(null);\n\tconst refusal = useRef(options.refusal);\n\trefusal.current = options.refusal;\n\n\tuseFetcherAnswer(fetcher, (answer) => {\n\t\tconst pending = waiting.current;\n\t\tif (!pending) return;\n\t\twaiting.current = null;\n\t\tlet refused: string | Error | undefined;\n\t\ttry {\n\t\t\trefused = refusal.current?.(answer);\n\t\t} catch (error) {\n\t\t\tpending.reject(error);\n\t\t\treturn;\n\t\t}\n\t\tif (refused === undefined) pending.resolve(answer);\n\t\telse\n\t\t\tpending.reject(\n\t\t\t\ttypeof refused === 'string' ? new Error(refused) : refused,\n\t\t\t);\n\t});\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tconst pending = waiting.current;\n\t\t\twaiting.current = null;\n\t\t\tpending?.reject(new FetcherPromiseAborted('unmounted'));\n\t\t},\n\t\t[],\n\t);\n\n\treturn useCallback((submit) => {\n\t\twaiting.current?.reject(new FetcherPromiseAborted('superseded'));\n\t\treturn new Promise<Data>((resolve, reject) => {\n\t\t\tconst mine: Waiting<Data> = { resolve, reject };\n\t\t\twaiting.current = mine;\n\t\t\tconst fail = (error: unknown) => {\n\t\t\t\tif (waiting.current === mine) waiting.current = null;\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tPromise.resolve(submit()).catch(fail);\n\t\t\t} catch (error) {\n\t\t\t\tfail(error);\n\t\t\t}\n\t\t});\n\t}, []);\n}\n",
|
|
8
|
-
"import { useMemo } from 'react';\nimport type { FormErrors } from '../errors/form-errors';\n\n/**\n * What a form's fetcher answers: a done step (`ok: true`), or a refusal\n * (`formRefusal`, or `fetcherResult` with its `error`) that may carry the\n * form's field errors.\n */\nexport type FormRefusalResult =\n\t| { ok: true }\n\t| { ok?: false; fieldErrors?: Record<string, string>; error?: string };\n\n/**\n * The refusal of a form's last answer as its `FormErrors`: `undefined` for\n * no answer, a done step, or a refusal with no `fieldErrors` (a toast's\n * message, not the form's). Stable for one answer.\n */\nexport function useFormRefusal(\n\tresult: FormRefusalResult | undefined,\n): FormErrors | undefined {\n\treturn useMemo(\n\t\t() =>\n\t\t\tresult && !result.ok && result.fieldErrors\n\t\t\t\t? {\n\t\t\t\t\t\tfieldErrors: result.fieldErrors,\n\t\t\t\t\t\tformError: result.error || undefined,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t[result],\n\t);\n}\n"
|
|
8
|
+
"import { useMemo } from 'react';\nimport type { FormErrors } from '../errors/form-errors';\n\n/**\n * What a form's fetcher answers: a done step (`ok: true`), or a refusal\n * (`formRefusal`, or `fetcherResult` with its `error`) that may carry the\n * form's field errors.\n */\nexport type FormRefusalResult =\n\t| { ok: true }\n\t| { ok?: false; fieldErrors?: Record<string, string>; error?: string };\n\n/**\n * The refusal of a form's last answer as its `FormErrors`: `undefined` for\n * no answer, a done step, or a refusal with no `fieldErrors` (a toast's\n * message, not the form's). Stable for one answer.\n */\nexport function useFormRefusal(\n\tresult: FormRefusalResult | undefined,\n): FormErrors | undefined {\n\treturn useMemo(\n\t\t() =>\n\t\t\tresult && !result.ok && result.fieldErrors\n\t\t\t\t? {\n\t\t\t\t\t\tfieldErrors: result.fieldErrors,\n\t\t\t\t\t\tformError: result.error || undefined,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t[result],\n\t);\n}\n",
|
|
9
|
+
"import { useEffect, useRef } from 'react';\n\nexport interface VisibleIntervalOptions {\n\t/** `false` stops the timer. Default `true`. */\n\treadonly enabled?: boolean;\n\t/**\n\t * Run the callback as soon as a hidden page becomes visible again, when at\n\t * least the interval has passed since its last run. Default `true`.\n\t */\n\treadonly runOnVisible?: boolean;\n}\n\n/**\n * Runs `callback` every `ms` **only while the page is visible**\n * (`document.visibilityState`), for a screen that has no real-time channel\n * (a revalidation, a fetcher's `load`). A tick that fires while the page is\n * hidden is skipped; when the page becomes visible again after at least `ms`\n * since the last run, the callback runs at once (`runOnVisible`); a page that\n * comes back sooner waits for the next tick. The timer and the listener are\n * cleared on unmount and while `enabled` is false. `ms` must be positive.\n *\n * The callback is read from a ref: a new function each render never restarts\n * the timer, and the latest one runs. Skipping a read already in flight is the\n * callback's to decide. On the server nothing starts (effects do not run).\n */\nexport function useVisibleInterval(\n\tcallback: () => void,\n\tms: number,\n\toptions: VisibleIntervalOptions = {},\n): void {\n\tconst { enabled = true, runOnVisible = true } = options;\n\tconst latest = useRef(callback);\n\tlatest.current = callback;\n\n\tuseEffect(() => {\n\t\tif (!enabled || ms <= 0) return;\n\t\tlet last = Date.now();\n\t\tconst run = () => {\n\t\t\tif (document.visibilityState !== 'visible') return;\n\t\t\tlast = Date.now();\n\t\t\tlatest.current();\n\t\t};\n\t\tconst timer = setInterval(run, ms);\n\t\tconst back = () => {\n\t\t\tif (runOnVisible && Date.now() - last >= ms) run();\n\t\t};\n\t\tdocument.addEventListener('visibilitychange', back);\n\t\treturn () => {\n\t\t\tclearInterval(timer);\n\t\t\tdocument.removeEventListener('visibilitychange', back);\n\t\t};\n\t}, [ms, enabled, runOnVisible]);\n}\n",
|
|
10
|
+
"import { useRevalidator } from 'react-router';\nimport {\n\tuseVisibleInterval,\n\ttype VisibleIntervalOptions,\n} from './use-visible-interval';\n\n/**\n * Runs the current route's loaders again every `ms`, **only while the page is\n * visible**, and at once when a hidden page comes back after more than `ms`\n * (`useVisibleInterval` over React Router's `useRevalidator`). A revalidation\n * already in flight is not doubled. `enabled: false` stops it (a menu is open,\n * a change is in flight).\n */\nexport function useVisibleRevalidation(\n\tms: number,\n\toptions?: Pick<VisibleIntervalOptions, 'enabled'>,\n): void {\n\tconst revalidator = useRevalidator();\n\tuseVisibleInterval(\n\t\t() => {\n\t\t\tif (revalidator.state === 'idle') void revalidator.revalidate();\n\t\t},\n\t\tms,\n\t\toptions,\n\t);\n}\n"
|
|
9
11
|
],
|
|
10
|
-
"mappings": ";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AA2DO,SAAS,mBAAyB,CACxC,OACA,IACA,UAAyC,CAAC,GACjB;AAAA,EACzB,QAAQ,UAAU,KAAK,YAAY,GAAG,UAAU,MAAM,KAAK,SAAS;AAAA,EACpE,MAAM,UAAU,OAAO,IAAI;AAAA,EAC3B,QAAQ,UAAU;AAAA,EAClB,MAAM,UAAU,WAAiB,QAAQ,YAAY,YAAY,EAAE,IAAI,CAAC;AAAA,EACxE,MAAM,OAAO,OAAO,QAAQ,IAAI;AAAA,EAChC,KAAK,UAAU,QAAQ;AAAA,EACvB,MAAM,OAAO,MAAM,KAAK;AAAA,EACxB,MAAM,MACL,WAAW,KAAK,UAAU,YACvB,OAAO,OAAO,aACb,GAAG,IAAI,IACP,KACD;AAAA,EAEJ,OAAO,QAAQ,aAAa,SAAwB,IAAI;AAAA,EACxD,MAAM,WAAW,OAA0B,SAAS;AAAA,EAQpD,MAAM,MAAM,OAAO,CAAC;AAAA,EACpB,OAAO,SAAS,cAAc,SAAS,CAAC;AAAA,EACxC,MAAM,UAAU,OAAO,CAAC;AAAA,EACxB,gBAAgB,MAAM;AAAA,IACrB,IAAI,QAAQ,UAAU;AAAA,MAAQ,QAAQ,UAAU,IAAI;AAAA,KAClD,CAAC,QAAQ,KAAK,CAAC;AAAA,EAClB,MAAM,MAAM,CAAC,WAAmB;AAAA,IAC/B,MAAM,OAAO,EAAE,IAAI;AAAA,IACnB,UAAU,MAAM;AAAA,IACX,QAAQ,QAAQ,KAAK,QAAQ,MAAM,CAAC,EAAE,KAAK,MAAM;AAAA,MACrD,IAAI,SAAS,IAAI;AAAA,QAAS,gBAAgB,MAAM,WAAW,IAAI,CAAC;AAAA,KAChE;AAAA;AAAA,EAEF,MAAM,SAAS,OAAO,GAAG;AAAA,EACzB,OAAO,UAAU;AAAA,EAEjB,UAAU,MAAM;AAAA,IACf,IAAI,QAAQ,MAAM;AAAA,MACjB,SAAS,UAAU;AAAA,MACnB,UAAU,IAAI;AAAA,MACd;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC9B,OAAO,QAAQ,GAAG;AAAA,OAChB,OAAO;AAAA,IACV,OAAO,MAAM,aAAa,KAAK;AAAA,KAC7B,CAAC,KAAK,MAAM,OAAO,CAAC;AAAA,EAEvB,MAAM,SACL,QAAQ,UAAU,WACjB,QAAQ,YAAY,IAAI,WAAW,YAAY,IAAI;AAAA,EACrD,MAAM,UACL,QAAQ,QAAQ,WAAW,OAAO,UAAU,QAAQ,SAAS;AAAA,EAC9D,MAAM,SAAS,UAAU,QAAQ,OAAO;AAAA,EACxC,UAAU,MAAM;AAAA,IACf,IAAI,WAAW,aAAa,WAAW;AAAA,MAAM;AAAA,IAC7C,IAAI,QAAQ,UAAU,MAAM,KAAK;AAAA,MAAM,SAAS,UAAU;AAAA,KACxD,CAAC,MAAM,CAAC;AAAA,EAEX,MAAM,OAAO,UAAU,SAAS,QAAQ,OAAO,YAAY,SAAS;AAAA,EACpE,IAAI;AAAA,EACJ,IAAI,QAAQ;AAAA,IAAM,QAAQ;AAAA,EAC1B,KAAK,IAAI,WAAW;AAAA,IAAK,QAAQ;AAAA,EACjC;AAAA,IAAK,QAAQ,SAAS,SAAS;AAAA,EAE/B,MAAM,SAAS,OAAO,GAAG;AAAA,EACzB,OAAO,UAAU;AAAA,EACjB,MAAM,QAAQ,YAAY,MAAM;AAAA,IAC/B,MAAM,MAAM,OAAO;AAAA,IACnB,IAAI,QAAQ;AAAA,MAAM;AAAA,IAClB,OAAO,QAAQ,GAAG;AAAA,KAChB,CAAC,CAAC;AAAA,EACL,OAAO,EAAE,MAAM,OAAO,UAAU,UAAU,SAAS,WAAW,OAAO,MAAM;AAAA;;ACnJ5E,sBAAS,sBAAW,qBAAQ;AAiBrB,SAAS,gBAAsB,CACrC,SACA,UACmB;AAAA,EACnB,MAAM,OAAO,QAAO,QAAQ,IAAI;AAAA,EAChC,MAAM,UAAU,QAAO,QAAQ;AAAA,EAC/B,QAAQ,UAAU;AAAA,EAClB,OAAO,QAAQ,aAAa,UAA2B,SAAS;AAAA,EAChE,MAAM,SAAS,QAAQ,UAAU,SAAS,QAAQ,OAAO;AAAA,EACzD,WAAU,MAAM;AAAA,IACf,IAAI,WAAW,aAAa,WAAW,QAAQ,WAAW,KAAK,SAAS;AAAA,MACvE;AAAA,IACD;AAAA,IACA,KAAK,UAAU;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,QAAQ,UAAU,MAAM;AAAA,KACtB,CAAC,MAAM,CAAC;AAAA,EACX,OAAO;AAAA;;AClCR,wBAAS,2BAAa,sBAAW;AAe1B,MAAM,8BAA8B,MAAM;AAAA,EAC9B,OAAO;AAAA,EAChB;AAAA,EACT,WAAW,CAAC,QAAoC;AAAA,IAC/C,MACC,WAAW,eACR,kFACA,wEACJ;AAAA,IACA,KAAK,SAAS;AAAA;AAEhB;AAyBO,SAAS,iBAAuB,CACtC,SACA,UAAuC,CAAC,GACmB;AAAA,EAC3D,MAAM,UAAU,QAA6B,IAAI;AAAA,EACjD,MAAM,UAAU,QAAO,QAAQ,OAAO;AAAA,EACtC,QAAQ,UAAU,QAAQ;AAAA,EAE1B,iBAAiB,SAAS,CAAC,WAAW;AAAA,IACrC,MAAM,UAAU,QAAQ;AAAA,IACxB,IAAI,CAAC;AAAA,MAAS;AAAA,IACd,QAAQ,UAAU;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,UAAU,QAAQ,UAAU,MAAM;AAAA,MACjC,OAAO,OAAO;AAAA,MACf,QAAQ,OAAO,KAAK;AAAA,MACpB;AAAA;AAAA,IAED,IAAI,YAAY;AAAA,MAAW,QAAQ,QAAQ,MAAM;AAAA,IACjD;AAAA,MACC,QAAQ,OACP,OAAO,YAAY,WAAW,IAAI,MAAM,OAAO,IAAI,OACpD;AAAA,GACD;AAAA,EAED,WACC,MAAM,MAAM;AAAA,IACX,MAAM,UAAU,QAAQ;AAAA,IACxB,QAAQ,UAAU;AAAA,IAClB,SAAS,OAAO,IAAI,sBAAsB,WAAW,CAAC;AAAA,KAEvD,CAAC,CACF;AAAA,EAEA,OAAO,aAAY,CAAC,WAAW;AAAA,IAC9B,QAAQ,SAAS,OAAO,IAAI,sBAAsB,YAAY,CAAC;AAAA,IAC/D,OAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAAA,MAC7C,MAAM,OAAsB,EAAE,SAAS,OAAO;AAAA,MAC9C,QAAQ,UAAU;AAAA,MAClB,MAAM,OAAO,CAAC,UAAmB;AAAA,QAChC,IAAI,QAAQ,YAAY;AAAA,UAAM,QAAQ,UAAU;AAAA,QAChD,OAAO,KAAK;AAAA;AAAA,MAEb,IAAI;AAAA,QACH,QAAQ,QAAQ,OAAO,CAAC,EAAE,MAAM,IAAI;AAAA,QACnC,OAAO,OAAO;AAAA,QACf,KAAK,KAAK;AAAA;AAAA,KAEX;AAAA,KACC,CAAC,CAAC;AAAA;;ACrGN;AAiBO,SAAS,cAAc,CAC7B,QACyB;AAAA,EACzB,OAAO,QACN,MACC,UAAU,CAAC,OAAO,MAAM,OAAO,cAC5B;AAAA,IACA,aAAa,OAAO;AAAA,IACpB,WAAW,OAAO,SAAS;AAAA,EAC5B,IACC,WACJ,CAAC,MAAM,CACR;AAAA;",
|
|
11
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "70FA37428A43B8C264756E2164756E21",
|
|
12
14
|
"names": []
|
|
13
15
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface VisibleIntervalOptions {
|
|
2
|
+
/** `false` stops the timer. Default `true`. */
|
|
3
|
+
readonly enabled?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Run the callback as soon as a hidden page becomes visible again, when at
|
|
6
|
+
* least the interval has passed since its last run. Default `true`.
|
|
7
|
+
*/
|
|
8
|
+
readonly runOnVisible?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Runs `callback` every `ms` **only while the page is visible**
|
|
12
|
+
* (`document.visibilityState`), for a screen that has no real-time channel
|
|
13
|
+
* (a revalidation, a fetcher's `load`). A tick that fires while the page is
|
|
14
|
+
* hidden is skipped; when the page becomes visible again after at least `ms`
|
|
15
|
+
* since the last run, the callback runs at once (`runOnVisible`); a page that
|
|
16
|
+
* comes back sooner waits for the next tick. The timer and the listener are
|
|
17
|
+
* cleared on unmount and while `enabled` is false. `ms` must be positive.
|
|
18
|
+
*
|
|
19
|
+
* The callback is read from a ref: a new function each render never restarts
|
|
20
|
+
* the timer, and the latest one runs. Skipping a read already in flight is the
|
|
21
|
+
* callback's to decide. On the server nothing starts (effects do not run).
|
|
22
|
+
*/
|
|
23
|
+
export declare function useVisibleInterval(callback: () => void, ms: number, options?: VisibleIntervalOptions): void;
|
|
24
|
+
//# sourceMappingURL=use-visible-interval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visible-interval.d.ts","sourceRoot":"","sources":["../../src/fetcher/use-visible-interval.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACtC,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,sBAA2B,GAClC,IAAI,CAuBN"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type VisibleIntervalOptions } from './use-visible-interval';
|
|
2
|
+
/**
|
|
3
|
+
* Runs the current route's loaders again every `ms`, **only while the page is
|
|
4
|
+
* visible**, and at once when a hidden page comes back after more than `ms`
|
|
5
|
+
* (`useVisibleInterval` over React Router's `useRevalidator`). A revalidation
|
|
6
|
+
* already in flight is not doubled. `enabled: false` stops it (a menu is open,
|
|
7
|
+
* a change is in flight).
|
|
8
|
+
*/
|
|
9
|
+
export declare function useVisibleRevalidation(ms: number, options?: Pick<VisibleIntervalOptions, 'enabled'>): void;
|
|
10
|
+
//# sourceMappingURL=use-visible-revalidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visible-revalidation.d.ts","sourceRoot":"","sources":["../../src/fetcher/use-visible-revalidation.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,wBAAwB,CAAC;AAEhC;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACrC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,GAC/C,IAAI,CASN"}
|
package/dist/session/index.js
CHANGED
|
@@ -857,6 +857,7 @@ var DEFAULTS = {
|
|
|
857
857
|
maxKeys: 1e4,
|
|
858
858
|
globalMax: 100,
|
|
859
859
|
globalWindowMs: 60000,
|
|
860
|
+
maxDelayMs: 3000,
|
|
860
861
|
maxConcurrentVerifies: 2,
|
|
861
862
|
maxQueuedVerifies: 4
|
|
862
863
|
};
|
|
@@ -873,6 +874,12 @@ function createSignInThrottle(options = {}) {
|
|
|
873
874
|
const maxKeys = positive("maxKeys", options.maxKeys ?? DEFAULTS.maxKeys);
|
|
874
875
|
const globalMax = positive("globalMax", options.globalMax ?? DEFAULTS.globalMax);
|
|
875
876
|
const globalWindowMs = positive("globalWindowMs", options.globalWindowMs ?? DEFAULTS.globalWindowMs);
|
|
877
|
+
const mode = options.globalMode ?? "refuse";
|
|
878
|
+
if (mode !== "refuse" && mode !== "delay") {
|
|
879
|
+
throw new TypeError(`createSignInThrottle(): globalMode must be 'refuse' or 'delay'; got ${String(mode)}.`);
|
|
880
|
+
}
|
|
881
|
+
const maxDelayMs = positive("maxDelayMs", options.maxDelayMs ?? DEFAULTS.maxDelayMs);
|
|
882
|
+
const globalKept = mode === "delay" ? globalMax * 2 : globalMax;
|
|
876
883
|
const slots = positive("maxConcurrentVerifies", options.maxConcurrentVerifies ?? DEFAULTS.maxConcurrentVerifies);
|
|
877
884
|
const queueLimit = positive("maxQueuedVerifies", options.maxQueuedVerifies ?? DEFAULTS.maxQueuedVerifies, true);
|
|
878
885
|
const now = options.now ?? Date.now;
|
|
@@ -903,11 +910,21 @@ function createSignInThrottle(options = {}) {
|
|
|
903
910
|
wait = seconds(windowMs - (at - kept[0]));
|
|
904
911
|
}
|
|
905
912
|
global = global.filter((time) => at - time < globalWindowMs);
|
|
906
|
-
if (global.length >= globalMax) {
|
|
913
|
+
if (mode === "refuse" && global.length >= globalMax) {
|
|
907
914
|
wait = Math.max(wait, seconds(globalWindowMs - (at - global[0])));
|
|
908
915
|
}
|
|
909
916
|
return wait;
|
|
910
917
|
},
|
|
918
|
+
globalDelay() {
|
|
919
|
+
if (mode !== "delay")
|
|
920
|
+
return 0;
|
|
921
|
+
const at = now();
|
|
922
|
+
global = global.filter((time) => at - time < globalWindowMs);
|
|
923
|
+
if (global.length < globalMax)
|
|
924
|
+
return 0;
|
|
925
|
+
const excess = global.length - globalMax + 1;
|
|
926
|
+
return Math.min(maxDelayMs, Math.ceil(maxDelayMs * excess / globalMax));
|
|
927
|
+
},
|
|
911
928
|
fail(key) {
|
|
912
929
|
const at = now();
|
|
913
930
|
const kept = [...recent(key, at), at].slice(-max);
|
|
@@ -921,7 +938,7 @@ function createSignInThrottle(options = {}) {
|
|
|
921
938
|
global = [
|
|
922
939
|
...global.filter((time) => at - time < globalWindowMs),
|
|
923
940
|
at
|
|
924
|
-
].slice(-
|
|
941
|
+
].slice(-globalKept);
|
|
925
942
|
},
|
|
926
943
|
clear(key) {
|
|
927
944
|
failures.delete(key);
|
|
@@ -964,5 +981,5 @@ export {
|
|
|
964
981
|
stepUpSteps
|
|
965
982
|
};
|
|
966
983
|
|
|
967
|
-
//# debugId=
|
|
984
|
+
//# debugId=E267BD0EB46649CD64756E2164756E21
|
|
968
985
|
//# sourceMappingURL=index.js.map
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"import { data } from 'react-router';\nimport {\n\ttype ApiErrorLike,\n\tattemptsLeftOf,\n\tisApiErrorLike,\n\tretryAfterOf,\n} from '../errors/api-error';\nimport { INVALID_CODE, MAIL_THROTTLED, UNAUTHENTICATED } from './codes';\nimport type { CodeWording } from './flow-types';\nimport { samesitePost } from './guard';\nimport type {\n\tStepUpConfirmAnswer,\n\tStepUpError,\n\tStepUpRequestAnswer,\n\tStepUpVia,\n} from './model';\nimport { codeRefusal } from './step';\nimport { STEP_UP_OVER, STEP_UP_REQUIRED } from './step-up-codes';\nimport { signingOut } from './step-up-signed-out';\nimport type {\n\tStepUpRun,\n\tStepUpStayed,\n\tStepUpSteps,\n\tStepUpStepsOptions,\n} from './step-up-types';\n\ntype Refused = Extract<StepUpConfirmAnswer, { ok: false }>;\n\ninterface StepUpContext<L extends string, C> extends CodeWording<L> {\n\treadonly steps: StepUpStepsOptions<L, C>;\n\t/** The sign-in's redirect, bound; `resolve` makes sure `onSignedOut` has one. */\n\treadonly signInRedirect: ((request: Request) => Response) | undefined;\n\treadonly stepUpRequired: string;\n\treadonly mailThrottled: string;\n\treadonly unauthenticated: string;\n}\n\nfunction resolve<L extends string, C>(\n\tsteps: StepUpStepsOptions<L, C>,\n): StepUpContext<L, C> {\n\tconst invalidCode = steps.codes?.invalidCode ?? INVALID_CODE;\n\tconst challengeOver = steps.codes?.challengeOver ?? STEP_UP_OVER;\n\tif (challengeOver.includes(invalidCode)) {\n\t\tthrow new TypeError(\n\t\t\t`stepUpSteps(): the code ${JSON.stringify(invalidCode)} is both the wrong-code code (codes.invalidCode) and in codes.challengeOver. A wrong code that leaves tries cannot end the challenge.`,\n\t\t);\n\t}\n\tif (steps.onSignedOut === 'sign-in' && !steps.signIn.signInRedirect) {\n\t\tthrow new TypeError(\n\t\t\t\"stepUpSteps(): onSignedOut: 'sign-in' needs signIn.signInRedirect, which the sign-in given has not.\",\n\t\t);\n\t}\n\tconst { signIn } = steps;\n\treturn {\n\t\toptions: signIn,\n\t\tsignInRedirect: signIn.signInRedirect?.bind(signIn),\n\t\tsteps,\n\t\tinvalidCode,\n\t\tchallengeOver,\n\t\tstepUpRequired: steps.codes?.stepUpRequired ?? STEP_UP_REQUIRED,\n\t\tmailThrottled: steps.codes?.mailThrottled ?? MAIL_THROTTLED,\n\t\tunauthenticated: steps.codes?.unauthenticated ?? UNAUTHENTICATED,\n\t};\n}\n\n/** The refusal's message: the app's own wording, else `errors`'. */\nfunction worded<L extends string, C>(\n\t{ steps }: StepUpContext<L, C>,\n\terror: ApiErrorLike,\n\tlanguage: L,\n): string {\n\treturn (\n\t\tsteps.wording?.(error, language) ??\n\t\tsteps.signIn.errors.apiErrorMessage(error, language)\n\t);\n}\n\n/** A code the API refused. With none left, a mailed one is over and an app's is locked. */\nfunction refusedCode<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\terror: ApiErrorLike,\n\tvia: StepUpVia | undefined,\n\tlanguage: L,\n): Omit<Refused, 'ok' | 'intent'> {\n\tconst { steps } = context;\n\tconst attemptsLeft = attemptsLeftOf(error);\n\tif (attemptsLeft === 0 && via !== 'secondFactor') {\n\t\treturn {\n\t\t\terror: 'expired',\n\t\t\tattemptsLeft,\n\t\t\tlocked: false,\n\t\t\tmessage: steps.spent(language),\n\t\t};\n\t}\n\tconst locked = attemptsLeft === 0;\n\tconst message =\n\t\tcodeRefusal(\n\t\t\tcontext,\n\t\t\terror,\n\t\t\tlanguage,\n\t\t\tlocked ? steps.locked?.(language) : undefined,\n\t\t) ?? steps.signIn.errors.apiErrorMessage(error, language);\n\treturn {\n\t\terror: 'invalid',\n\t\t...(attemptsLeft === undefined ? {} : { attemptsLeft }),\n\t\tlocked,\n\t\tmessage,\n\t};\n}\n\n/** The mail throttle's code, or any 429: a rate limit asks to wait, whatever its code. */\nfunction isThrottle<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\terror: ApiErrorLike,\n): boolean {\n\treturn error.status === 429 || error.code === context.mailThrottled;\n}\n\nasync function requestStep<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\trun: Parameters<StepUpSteps<L>['request']>[0],\n\t{ request, language }: Parameters<StepUpSteps<L>['request']>[1],\n): Promise<StepUpRequestAnswer | StepUpStayed<StepUpRequestAnswer>> {\n\tsamesitePost(context.steps.signIn.json, request);\n\tconst intent = 'request-step-up';\n\ttry {\n\t\tconst { challenge, via } = await run();\n\t\treturn { ok: true, intent, challenge, via };\n\t} catch (error) {\n\t\tconst refusal = context.steps.signIn.errors.apiRefusal(error, language);\n\t\tif (!refusal) throw error;\n\t\tconst api = isApiErrorLike(error);\n\t\tconst message = api ? worded(context, error, language) : refusal.message;\n\t\tconst throttled = api && isThrottle(context, error);\n\t\tconst retryAfter = throttled ? retryAfterOf(error) : undefined;\n\t\treturn data<StepUpRequestAnswer>(\n\t\t\t{\n\t\t\t\tok: false,\n\t\t\t\tintent,\n\t\t\t\terror: throttled ? 'throttled' : 'failed',\n\t\t\t\tmessage,\n\t\t\t\t...(retryAfter === undefined ? {} : { retryAfter }),\n\t\t\t},\n\t\t\t{ status: refusal.status },\n\t\t);\n\t}\n}\n\nasync function confirmStep<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\trun: () => Promise<unknown>,\n\t{ request, language, via }: Parameters<StepUpSteps<L>['confirm']>[1],\n): Promise<StepUpConfirmAnswer | StepUpStayed<StepUpConfirmAnswer>> {\n\tsamesitePost(context.steps.signIn.json, request);\n\tconst intent = 'confirm-step-up';\n\ttry {\n\t\tawait run();\n\t\treturn { ok: true, intent };\n\t} catch (error) {\n\t\tconst refusal = context.steps.signIn.errors.apiRefusal(error, language);\n\t\tif (!refusal) throw error;\n\t\tconst stay = (\n\t\t\tfailure: Omit<Refused, 'ok' | 'intent'>,\n\t\t): StepUpStayed<StepUpConfirmAnswer> =>\n\t\t\tdata<StepUpConfirmAnswer>(\n\t\t\t\t{ ok: false, intent, ...failure },\n\t\t\t\t{ status: refusal.status },\n\t\t\t);\n\t\tconst failed = (message: string) =>\n\t\t\tstay({ error: 'failed' satisfies StepUpError, locked: false, message });\n\t\tif (!isApiErrorLike(error)) return failed(refusal.message);\n\t\tif (error.status === 429) {\n\t\t\tconst retryAfter = retryAfterOf(error);\n\t\t\treturn stay({\n\t\t\t\terror: 'throttled',\n\t\t\t\tlocked: false,\n\t\t\t\tmessage: worded(context, error, language),\n\t\t\t\t...(retryAfter === undefined ? {} : { retryAfter }),\n\t\t\t});\n\t\t}\n\t\tif (error.code === context.invalidCode) {\n\t\t\treturn stay(refusedCode(context, error, via, language));\n\t\t}\n\t\tif (error.code && context.challengeOver.includes(error.code)) {\n\t\t\treturn stay({\n\t\t\t\terror: 'expired',\n\t\t\t\tlocked: false,\n\t\t\t\tmessage:\n\t\t\t\t\tcontext.steps.wording?.(error, language) ??\n\t\t\t\t\tcontext.steps.spent(language),\n\t\t\t});\n\t\t}\n\t\treturn failed(worded(context, error, language));\n\t}\n}\n\nasync function routeStep<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\trun: StepUpRun,\n\tcall: Parameters<StepUpSteps<L>['request']>[1],\n) {\n\tconst { json } = context.steps.signIn;\n\tsamesitePost(json, call.request);\n\tif (context.steps.onSignedOut !== 'sign-in')\n\t\treturn routeIntent(context, run, call);\n\tconst redirect = context.signInRedirect;\n\tif (!redirect) return routeIntent(context, run, call);\n\treturn signingOut(\n\t\t{\n\t\t\tsignIn: { signInRedirect: redirect },\n\t\t\tunauthenticated: context.unauthenticated,\n\t\t\trun,\n\t\t\trequest: call.request,\n\t\t},\n\t\t(watched) => routeIntent(context, watched, call),\n\t);\n}\n\nasync function routeIntent<L extends string, C>(\n\tcontext: StepUpContext<L, C>,\n\trun: StepUpRun,\n\tcall: Parameters<StepUpSteps<L>['request']>[1],\n) {\n\tconst { json } = context.steps.signIn;\n\tconst body = (await json.readJson(call.request)) as {\n\t\tintent?: unknown;\n\t\tchallenge?: unknown;\n\t\tcode?: unknown;\n\t\tvia?: unknown;\n\t} | null;\n\tif (body?.intent === 'request-step-up') {\n\t\treturn requestStep(context, () => run.request(), call);\n\t}\n\tif (\n\t\tbody?.intent === 'confirm-step-up' &&\n\t\ttypeof body.challenge === 'string' &&\n\t\ttypeof body.code === 'string'\n\t) {\n\t\tconst { challenge, code } = body;\n\t\tconst via =\n\t\t\tbody.via === 'email' || body.via === 'secondFactor'\n\t\t\t\t? body.via\n\t\t\t\t: undefined;\n\t\treturn confirmStep(context, () => run.confirm({ challenge, code }), {\n\t\t\t...call,\n\t\t\tvia,\n\t\t});\n\t}\n\tthrow data('Not a step-up intent', { status: 400 });\n}\n\n/**\n * The server side of a BFF's step-up: `request` and `confirm` answer the\n * page's fetcher with `StepUpRequestAnswer` and `StepUpConfirmAnswer`, which\n * `stepUpReducer` takes as they are. It speaks `@nxgt/janus`'s words\n * (`CODE_INVALID`, `TOKEN_*`, `STEP_UP_REQUIRED`); the app maps the rest.\n *\n * @example\n * const stepUp = stepUpSteps({\n * \terrors,\n * \tattemptsLeft: (count, language) => t('code.attempts-left', { count }, language),\n * \tspent: (language) => t('step-up.spent', {}, language),\n * \tlocked: (language) => t('step-up.locked', {}, language),\n * });\n */\nexport function stepUpSteps<L extends string, C = undefined>(\n\toptions: StepUpStepsOptions<L, C>,\n): StepUpSteps<L> {\n\tconst context = resolve(options);\n\treturn {\n\t\trequest: (run, o) => requestStep(context, run, o),\n\t\tconfirm: (run, o) => confirmStep(context, run, o),\n\t\troute: (run, o) => routeStep(context, run, o),\n\t\tisStepUpRequired: (error) =>\n\t\t\tisApiErrorLike(error) && error.code === context.stepUpRequired,\n\t};\n}\n",
|
|
19
19
|
"import { CHALLENGE_OVER } from './codes';\n\n/** `@nxgt/janus`'s code for a mutation that needs a recent step-up. */\nexport const STEP_UP_REQUIRED = 'STEP_UP_REQUIRED';\n\n/**\n * The codes that end a step-up's challenge: unknown, spent, expired or stale,\n * and a second factor that changed since the request (`SECOND_FACTOR_ACTIVE`,\n * `SECOND_FACTOR_NOT_ENROLLED`). The user asks again.\n */\nexport const STEP_UP_OVER = [\n\t...CHALLENGE_OVER,\n\t'TOKEN_STALE',\n\t'SECOND_FACTOR_ACTIVE',\n\t'SECOND_FACTOR_NOT_ENROLLED',\n] as const;\n",
|
|
20
20
|
"import { isApiErrorLike } from '../errors/api-error';\nimport type { SignInFlow } from './flow-types';\nimport type { StepUpRun } from './step-up-types';\n\n/**\n * A signed-out user's failure. From `request`, the API's no-session code or a\n * bare 401 response; from `confirm`, the code only: a 401 there is also what a\n * wrong code answers, so a bare one stays a refusal.\n */\nfunction isSignedOut(\n\terror: unknown,\n\tunauthenticated: string,\n\tfrom: 'request' | 'confirm',\n): boolean {\n\tif (error instanceof Response)\n\t\treturn from === 'request' && error.status === 401;\n\treturn isApiErrorLike(error) && error.code === unauthenticated;\n}\n\n/**\n * The request the sign-in redirect comes back to: the same-site `Referer`'s\n * page (the step-up route has none of its own), else the request's own URL.\n * A `Referer` of another origin (port and protocol count), or one that is not\n * a URL, is ignored. Behind a TLS-terminating proxy an `http` `request.url`\n * never matches an `https` `Referer`, so `next` is the route's own path.\n */\nexport function cameFrom(request: Request): Request {\n\tconst referer = request.headers.get('referer');\n\tif (referer) {\n\t\ttry {\n\t\t\tconst from = new URL(referer);\n\t\t\tif (from.origin === new URL(request.url).origin) {\n\t\t\t\treturn new Request(from, { headers: request.headers });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Not a URL: the request's own path.\n\t\t}\n\t}\n\treturn request;\n}\n\n/**\n * Runs `route` over a `run` that notes a signed-out failure, then throws the\n * flow's sign-in redirect in place of whatever the step answered or threw.\n */\nexport async function signingOut<A>(\n\t{\n\t\tsignIn,\n\t\tunauthenticated,\n\t\trun,\n\t\trequest,\n\t}: {\n\t\treadonly signIn: Pick<SignInFlow<string, never>, 'signInRedirect'>;\n\t\treadonly unauthenticated: string;\n\t\treadonly run: StepUpRun;\n\t\treadonly request: Request;\n\t},\n\troute: (watched: StepUpRun) => Promise<A>,\n): Promise<A> {\n\tlet signedOut = false;\n\tconst watched: StepUpRun = {\n\t\trequest: async () => {\n\t\t\ttry {\n\t\t\t\treturn await run.request();\n\t\t\t} catch (error) {\n\t\t\t\tsignedOut ||= isSignedOut(error, unauthenticated, 'request');\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\tconfirm: async (input) => {\n\t\t\ttry {\n\t\t\t\treturn await run.confirm(input);\n\t\t\t} catch (error) {\n\t\t\t\tsignedOut ||= isSignedOut(error, unauthenticated, 'confirm');\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t};\n\tconst redirect = () => signIn.signInRedirect(cameFrom(request));\n\tlet answer: A;\n\ttry {\n\t\tanswer = await route(watched);\n\t} catch (error) {\n\t\tthrow signedOut ? redirect() : error;\n\t}\n\tif (signedOut) throw redirect();\n\treturn answer;\n}\n",
|
|
21
|
-
"/** What `createSignInThrottle` takes; every field has a default. */\nexport interface SignInThrottleOptions {\n\t/** Failures one key may make within `windowMs` before it waits. 5 by default. */\n\treadonly max?: number | undefined;\n\t/** The per-key window, in milliseconds. 15 minutes by default. */\n\treadonly windowMs?: number | undefined;\n\t/** How many keys are held; past it the oldest is dropped. 10 000 by default. */\n\treadonly maxKeys?: number | undefined;\n\t/** Failures, all keys together, within `globalWindowMs` before every sign-in is delayed. 100 by default. */\n\treadonly globalMax?: number | undefined;\n\t/** The global window, in milliseconds: also the longest the global delay lasts. 1 minute by default. */\n\treadonly globalWindowMs?: number | undefined;\n\t/** Password verifications that run at once. 2 by default. */\n\treadonly maxConcurrentVerifies?: number | undefined;\n\t/** Verifications that wait for a slot; past it `verify` answers `{ busy: true }`. 4 by default; 0 for none. */\n\treadonly maxQueuedVerifies?: number | undefined;\n\t/** The clock, in milliseconds. `Date.now` by default; inject one in a test. */\n\treadonly now?: (() => number) | undefined;\n}\n\n/** What `verify` answers: the task's value, or a refusal because the queue was full. */\nexport type VerifyResult<T> =\n\t| { readonly busy: false; readonly value: T }\n\t| { readonly busy: true };\n\n/** A per-process sign-in throttle. */\nexport interface SignInThrottle {\n\t/** Seconds to wait before this key may try again, 0 when it may. Records nothing. */\n\twait(key: string): number;\n\t/** Record a failed attempt for the key (and in the global bucket). */\n\tfail(key: string): void;\n\t/** Forget the key's failures after a successful sign-in. The global bucket is left alone. */\n\tclear(key: string): void;\n\t/** Run a password verification under the concurrency limit, or refuse when the wait queue is full. A rejection of `task` passes through and frees its slot. */\n\tverify<T>(task: () => Promise<T>): Promise<VerifyResult<T>>;\n\t/** How many keys are held now. */\n\treadonly size: number;\n}\n\nconst DEFAULTS = {\n\tmax: 5,\n\twindowMs: 15 * 60_000,\n\tmaxKeys: 10_000,\n\tglobalMax: 100,\n\tglobalWindowMs: 60_000,\n\tmaxConcurrentVerifies: 2,\n\tmaxQueuedVerifies: 4,\n} as const;\n\nfunction positive(name: string, value: number, allowZero = false): number {\n\tconst ok = Number.isInteger(value) && (allowZero ? value >= 0 : value > 0);\n\tif (!ok) {\n\t\tthrow new TypeError(\n\t\t\t`createSignInThrottle(): ${name} must be a positive integer${allowZero ? ' or 0' : ''}; got ${String(value)}.`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * A failed-attempt throttle for a password sign-in, in this process's memory:\n * `max` failures per key within `windowMs`, a bounded number of keys, a global\n * bucket that delays every sign-in for a few seconds rather than locking an\n * account, and `
|
|
21
|
+
"/** What `createSignInThrottle` takes; every field has a default. */\nexport interface SignInThrottleOptions {\n\t/** Failures one key may make within `windowMs` before it waits. 5 by default. */\n\treadonly max?: number | undefined;\n\t/** The per-key window, in milliseconds. 15 minutes by default. */\n\treadonly windowMs?: number | undefined;\n\t/** How many keys are held; past it the oldest is dropped. 10 000 by default. */\n\treadonly maxKeys?: number | undefined;\n\t/** Failures, all keys together, within `globalWindowMs` before every sign-in is delayed. 100 by default. */\n\treadonly globalMax?: number | undefined;\n\t/** The global window, in milliseconds: also the longest the global delay lasts. 1 minute by default. */\n\treadonly globalWindowMs?: number | undefined;\n\t/**\n\t * What the global bucket does past `globalMax`: `'refuse'` (the default) makes `wait` answer\n\t * the seconds left for every key; `'delay'` leaves `wait` per key and gives `globalDelay` a bounded delay instead.\n\t */\n\treadonly globalMode?: 'refuse' | 'delay' | undefined;\n\t/** In `'delay'` mode, the longest `globalDelay` answers, in milliseconds. 3 000 by default. */\n\treadonly maxDelayMs?: number | undefined;\n\t/** Password verifications that run at once. 2 by default. */\n\treadonly maxConcurrentVerifies?: number | undefined;\n\t/** Verifications that wait for a slot; past it `verify` answers `{ busy: true }`. 4 by default; 0 for none. */\n\treadonly maxQueuedVerifies?: number | undefined;\n\t/** The clock, in milliseconds. `Date.now` by default; inject one in a test. */\n\treadonly now?: (() => number) | undefined;\n}\n\n/** What `verify` answers: the task's value, or a refusal because the queue was full. */\nexport type VerifyResult<T> =\n\t| { readonly busy: false; readonly value: T }\n\t| { readonly busy: true };\n\n/** A per-process sign-in throttle. */\nexport interface SignInThrottle {\n\t/** Seconds to wait before this key may try again, 0 when it may. Records nothing. */\n\twait(key: string): number;\n\t/**\n\t * Milliseconds to slow this attempt down because of the global bucket, 0 when it needs none.\n\t * Always 0 in the default `'refuse'` mode. In `'delay'` mode it is 0 below `globalMax` failures in the window,\n\t * then grows by `maxDelayMs / globalMax` with each failure past it, up to `maxDelayMs`. Records nothing.\n\t */\n\tglobalDelay(): number;\n\t/** Record a failed attempt for the key (and in the global bucket). */\n\tfail(key: string): void;\n\t/** Forget the key's failures after a successful sign-in. The global bucket is left alone. */\n\tclear(key: string): void;\n\t/** Run a password verification under the concurrency limit, or refuse when the wait queue is full. A rejection of `task` passes through and frees its slot. */\n\tverify<T>(task: () => Promise<T>): Promise<VerifyResult<T>>;\n\t/** How many keys are held now. */\n\treadonly size: number;\n}\n\nconst DEFAULTS = {\n\tmax: 5,\n\twindowMs: 15 * 60_000,\n\tmaxKeys: 10_000,\n\tglobalMax: 100,\n\tglobalWindowMs: 60_000,\n\tmaxDelayMs: 3_000,\n\tmaxConcurrentVerifies: 2,\n\tmaxQueuedVerifies: 4,\n} as const;\n\nfunction positive(name: string, value: number, allowZero = false): number {\n\tconst ok = Number.isInteger(value) && (allowZero ? value >= 0 : value > 0);\n\tif (!ok) {\n\t\tthrow new TypeError(\n\t\t\t`createSignInThrottle(): ${name} must be a positive integer${allowZero ? ' or 0' : ''}; got ${String(value)}.`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * A failed-attempt throttle for a password sign-in, in this process's memory:\n * `max` failures per key within `windowMs`, a bounded number of keys, a global\n * bucket that delays every sign-in for a few seconds rather than locking an\n * account (or, with `globalMode: 'delay'`, leaves `wait` per key and gives\n * `globalDelay`, a bounded delay that grows with the excess), and `verify`,\n * which holds password hashing (argon2 at 64 MiB each) to a small concurrency. Each process counts alone: behind several instances\n * the limits multiply. Pass the lower-cased address as the key.\n *\n * @example\n * const throttle = createSignInThrottle({ max: 5, windowMs: 15 * 60_000 });\n * // in the sign-in action\n * const seconds = throttle.wait(email);\n * if (seconds > 0) return tooMany(seconds);\n * const checked = await throttle.verify(() => Bun.password.verify(password, hash));\n * if (checked.busy) return tryLater();\n * if (!checked.value) { throttle.fail(email); return refused(); }\n * throttle.clear(email);\n */\nexport function createSignInThrottle(\n\toptions: SignInThrottleOptions = {},\n): SignInThrottle {\n\tconst max = positive('max', options.max ?? DEFAULTS.max);\n\tconst windowMs = positive('windowMs', options.windowMs ?? DEFAULTS.windowMs);\n\tconst maxKeys = positive('maxKeys', options.maxKeys ?? DEFAULTS.maxKeys);\n\tconst globalMax = positive(\n\t\t'globalMax',\n\t\toptions.globalMax ?? DEFAULTS.globalMax,\n\t);\n\tconst globalWindowMs = positive(\n\t\t'globalWindowMs',\n\t\toptions.globalWindowMs ?? DEFAULTS.globalWindowMs,\n\t);\n\tconst mode = options.globalMode ?? 'refuse';\n\tif (mode !== 'refuse' && mode !== 'delay') {\n\t\tthrow new TypeError(\n\t\t\t`createSignInThrottle(): globalMode must be 'refuse' or 'delay'; got ${String(mode)}.`,\n\t\t);\n\t}\n\tconst maxDelayMs = positive(\n\t\t'maxDelayMs',\n\t\toptions.maxDelayMs ?? DEFAULTS.maxDelayMs,\n\t);\n\t// The refusing bucket needs globalMax failures; the delaying one counts the excess too.\n\tconst globalKept = mode === 'delay' ? globalMax * 2 : globalMax;\n\tconst slots = positive(\n\t\t'maxConcurrentVerifies',\n\t\toptions.maxConcurrentVerifies ?? DEFAULTS.maxConcurrentVerifies,\n\t);\n\tconst queueLimit = positive(\n\t\t'maxQueuedVerifies',\n\t\toptions.maxQueuedVerifies ?? DEFAULTS.maxQueuedVerifies,\n\t\ttrue,\n\t);\n\tconst now = options.now ?? Date.now;\n\n\t// A Map keeps insertion order: the first key is the oldest.\n\tconst failures = new Map<string, number[]>();\n\tlet global: number[] = [];\n\n\tconst recent = (key: string, at: number): number[] => {\n\t\tconst kept = (failures.get(key) ?? []).filter(\n\t\t\t(time) => at - time < windowMs,\n\t\t);\n\t\tif (kept.length === 0) failures.delete(key);\n\t\treturn kept;\n\t};\n\tconst seconds = (ms: number): number => Math.ceil(ms / 1000);\n\n\tlet running = 0;\n\tconst queue: Array<() => void> = [];\n\tconst release = () => {\n\t\tconst next = queue.shift();\n\t\tif (next) next();\n\t\telse running--;\n\t};\n\n\treturn {\n\t\twait(key) {\n\t\t\tconst at = now();\n\t\t\tlet wait = 0;\n\t\t\tconst kept = recent(key, at);\n\t\t\tif (kept.length >= max) {\n\t\t\t\twait = seconds(windowMs - (at - (kept[0] as number)));\n\t\t\t}\n\t\t\tglobal = global.filter((time) => at - time < globalWindowMs);\n\t\t\tif (mode === 'refuse' && global.length >= globalMax) {\n\t\t\t\twait = Math.max(\n\t\t\t\t\twait,\n\t\t\t\t\tseconds(globalWindowMs - (at - (global[0] as number))),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn wait;\n\t\t},\n\t\tglobalDelay() {\n\t\t\tif (mode !== 'delay') return 0;\n\t\t\tconst at = now();\n\t\t\tglobal = global.filter((time) => at - time < globalWindowMs);\n\t\t\tif (global.length < globalMax) return 0;\n\t\t\tconst excess = global.length - globalMax + 1;\n\t\t\treturn Math.min(maxDelayMs, Math.ceil((maxDelayMs * excess) / globalMax));\n\t\t},\n\t\tfail(key) {\n\t\t\tconst at = now();\n\t\t\tconst kept = [...recent(key, at), at].slice(-max);\n\t\t\tfailures.delete(key);\n\t\t\tfailures.set(key, kept);\n\t\t\tif (failures.size > maxKeys) {\n\t\t\t\tconst oldest = failures.keys().next().value;\n\t\t\t\tif (oldest !== undefined) failures.delete(oldest);\n\t\t\t}\n\t\t\tglobal = [\n\t\t\t\t...global.filter((time) => at - time < globalWindowMs),\n\t\t\t\tat,\n\t\t\t].slice(-globalKept);\n\t\t},\n\t\tclear(key) {\n\t\t\tfailures.delete(key);\n\t\t},\n\t\tasync verify(task) {\n\t\t\tif (running >= slots) {\n\t\t\t\tif (queue.length >= queueLimit) return { busy: true };\n\t\t\t\tawait new Promise<void>((resolve) => queue.push(resolve));\n\t\t\t} else {\n\t\t\t\trunning++;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn { busy: false, value: await task() };\n\t\t\t} finally {\n\t\t\t\trelease();\n\t\t\t}\n\t\t},\n\t\tget size() {\n\t\t\treturn failures.size;\n\t\t},\n\t};\n}\n"
|
|
22
22
|
],
|
|
23
|
-
"mappings": "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",
|
|
24
|
-
"debugId": "
|
|
23
|
+
"mappings": "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",
|
|
24
|
+
"debugId": "E267BD0EB46649CD64756E2164756E21",
|
|
25
25
|
"names": []
|
|
26
26
|
}
|
|
@@ -10,6 +10,13 @@ export interface SignInThrottleOptions {
|
|
|
10
10
|
readonly globalMax?: number | undefined;
|
|
11
11
|
/** The global window, in milliseconds: also the longest the global delay lasts. 1 minute by default. */
|
|
12
12
|
readonly globalWindowMs?: number | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* What the global bucket does past `globalMax`: `'refuse'` (the default) makes `wait` answer
|
|
15
|
+
* the seconds left for every key; `'delay'` leaves `wait` per key and gives `globalDelay` a bounded delay instead.
|
|
16
|
+
*/
|
|
17
|
+
readonly globalMode?: 'refuse' | 'delay' | undefined;
|
|
18
|
+
/** In `'delay'` mode, the longest `globalDelay` answers, in milliseconds. 3 000 by default. */
|
|
19
|
+
readonly maxDelayMs?: number | undefined;
|
|
13
20
|
/** Password verifications that run at once. 2 by default. */
|
|
14
21
|
readonly maxConcurrentVerifies?: number | undefined;
|
|
15
22
|
/** Verifications that wait for a slot; past it `verify` answers `{ busy: true }`. 4 by default; 0 for none. */
|
|
@@ -28,6 +35,12 @@ export type VerifyResult<T> = {
|
|
|
28
35
|
export interface SignInThrottle {
|
|
29
36
|
/** Seconds to wait before this key may try again, 0 when it may. Records nothing. */
|
|
30
37
|
wait(key: string): number;
|
|
38
|
+
/**
|
|
39
|
+
* Milliseconds to slow this attempt down because of the global bucket, 0 when it needs none.
|
|
40
|
+
* Always 0 in the default `'refuse'` mode. In `'delay'` mode it is 0 below `globalMax` failures in the window,
|
|
41
|
+
* then grows by `maxDelayMs / globalMax` with each failure past it, up to `maxDelayMs`. Records nothing.
|
|
42
|
+
*/
|
|
43
|
+
globalDelay(): number;
|
|
31
44
|
/** Record a failed attempt for the key (and in the global bucket). */
|
|
32
45
|
fail(key: string): void;
|
|
33
46
|
/** Forget the key's failures after a successful sign-in. The global bucket is left alone. */
|
|
@@ -41,8 +54,9 @@ export interface SignInThrottle {
|
|
|
41
54
|
* A failed-attempt throttle for a password sign-in, in this process's memory:
|
|
42
55
|
* `max` failures per key within `windowMs`, a bounded number of keys, a global
|
|
43
56
|
* bucket that delays every sign-in for a few seconds rather than locking an
|
|
44
|
-
* account,
|
|
45
|
-
*
|
|
57
|
+
* account (or, with `globalMode: 'delay'`, leaves `wait` per key and gives
|
|
58
|
+
* `globalDelay`, a bounded delay that grows with the excess), and `verify`,
|
|
59
|
+
* which holds password hashing (argon2 at 64 MiB each) to a small concurrency. Each process counts alone: behind several instances
|
|
46
60
|
* the limits multiply. Pass the lower-cased address as the key.
|
|
47
61
|
*
|
|
48
62
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/session/throttle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACrC,iFAAiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,4GAA4G;IAC5G,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,wGAAwG;IACxG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,6DAA6D;IAC7D,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpD,+GAA+G;IAC/G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,CAAC,CAAC,IACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC3C;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAE3B,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,qFAAqF;IACrF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,sEAAsE;IACtE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6FAA6F;IAC7F,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+JAA+J;IAC/J,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/session/throttle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACrC,iFAAiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,4GAA4G;IAC5G,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,wGAAwG;IACxG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACrD,+FAA+F;IAC/F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,6DAA6D;IAC7D,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpD,+GAA+G;IAC/G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAC1C;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,CAAC,CAAC,IACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC3C;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAE3B,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,qFAAqF;IACrF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,WAAW,IAAI,MAAM,CAAC;IACtB,sEAAsE;IACtE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6FAA6F;IAC7F,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+JAA+J;IAC/J,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,GAAE,qBAA0B,GACjC,cAAc,CAmHhB"}
|
package/docs/README.md
CHANGED
|
@@ -21,7 +21,7 @@ installable and usable offline, wording an API's refusals, the BFF session, a Gr
|
|
|
21
21
|
| [An API's refusals](guide/errors.md) | wording a GraphQL API's refusals for the pages: recognising an `ApiError` or a REST API's `problemError`, the request id, the page a request is for, the catalogue store, the form checks in the API's words, the provider, and the loaders, the error page and the actions that answer with it, the JSON actions with their CSRF check and fetcher hook, calling the API from a loader (`apiCallFailure`), and keeping the catalogue fresh (`@alxia/react-router/errors`) |
|
|
22
22
|
| [A BFF session](guide/session.md) | redirecting after sign-in to a page of the site and nowhere else, the sign-in pages' paths, the session's cookies, a signed session and a sign-in throttle (`signedSession`, `createSignInThrottle`), the sign-in flow (where an answer lands, a refused code, the viewer, sign-out; `@alxia/react-router/session`), the pages a mail's link opens (a magic link, a password reset: `authLinks`), the page's hooks (sign-out, a mail link's parameter, a one-code field; `@alxia/react-router/session/react`), the step-up route's signed-out handling (`onSignedOut`), and the step-up's state and the props it gives the UI (`@alxia/react-router/session/model`) |
|
|
23
23
|
| [Links through React Router](guide/link.md) | `RouterLink`, React Router's `Link` as the link component of a UI library that hands `href` and spreads anchor props; `@alxia/react-router/link` |
|
|
24
|
-
| [A fetcher's fresh answer](guide/fetcher.md) | `useFetcherAnswer`, `useFetcherPromise` (one submission's answer as a Promise), a handler called once per new answer of a keyed fetcher, not for the data it held at mount; `useDebouncedFetcher`, a resource route loaded for what is typed (pause, minimum length, stale answer kept, retry); `@alxia/react-router/fetcher` |
|
|
24
|
+
| [A fetcher's fresh answer](guide/fetcher.md) | `useFetcherAnswer`, `useFetcherPromise` (one submission's answer as a Promise), a handler called once per new answer of a keyed fetcher, not for the data it held at mount; `useDebouncedFetcher`, a resource route loaded for what is typed (pause, minimum length, stale answer kept, retry); `useVisibleInterval` and `useVisibleRevalidation`, a callback or a revalidation on an interval while the page is visible; `@alxia/react-router/fetcher` |
|
|
25
25
|
| [Lists whose state is the URL](guide/lists.md) | a search and filters in the address bar that drop the cursor (`useSearchChange`), a skeleton while the same page reloads (`useSameRouteLoading`), and a load-more button that appends pages by cursor and keeps the rows when one fails (`usePagedRows`); `@alxia/react-router/lists` |
|
|
26
26
|
| [Subscriptions for a BFF](guide/subscriptions.md) | showing a GraphQL subscription in the browser without giving it the API's token or a way to write a document: a resource route with a map of operation names to the server's documents, the same-site check, the bearer from the session, extra upstream headers, a heartbeat, abort propagation, size limits and a 429 passed through with `retryAfter` (`@alxia/react-router/subscription`) |
|
|
27
27
|
| [Troubleshooting](troubleshooting.md) | something went wrong and you have the message, or a page streams, hydrates or reads its context unlike you expected |
|
package/docs/guide/fetcher.md
CHANGED
|
@@ -6,9 +6,11 @@ component, so its data from an earlier visit is still there when the component
|
|
|
6
6
|
mounts again, and a plain `useEffect` on `fetcher.data` reacts to it as if it
|
|
7
7
|
were new. `@alxia/react-router/fetcher` holds the hook that tells them apart
|
|
8
8
|
(`useFetcherAnswer`, which reads the fetcher structurally) and the one that
|
|
9
|
-
loads a resource route for what the user types (`useDebouncedFetcher`, below)
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
loads a resource route for what the user types (`useDebouncedFetcher`, below),
|
|
10
|
+
and the ones that read data again while the page is visible
|
|
11
|
+
(`useVisibleInterval`, `useVisibleRevalidation`, below). `react` is its only
|
|
12
|
+
import, plus `react-router` for the hooks that use a fetcher or the
|
|
13
|
+
revalidator, and all render on the server.
|
|
12
14
|
|
|
13
15
|
```tsx
|
|
14
16
|
import { useJsonFetcher } from '@alxia/react-router/errors';
|
|
@@ -140,3 +142,43 @@ export function Suggestions({ typed }: { typed: string }) {
|
|
|
140
142
|
fetcher.
|
|
141
143
|
- `enabled: false` asks nothing and forgets the previous answer (a closed
|
|
142
144
|
dialog); `key` shares the fetcher with another component.
|
|
145
|
+
|
|
146
|
+
## Fresh data while the page is visible: `useVisibleInterval(callback, ms, options?)`
|
|
147
|
+
|
|
148
|
+
A screen with no real-time channel reads its data again on a timer. The timer
|
|
149
|
+
should run only while the user can see the page, and a page that was hidden
|
|
150
|
+
for a while should not show old data when it comes back.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useFetcher } from 'react-router';
|
|
154
|
+
import {
|
|
155
|
+
useVisibleInterval,
|
|
156
|
+
useVisibleRevalidation,
|
|
157
|
+
} from '@alxia/react-router/fetcher';
|
|
158
|
+
|
|
159
|
+
export function Board({ menuOpen }: { menuOpen: boolean }) {
|
|
160
|
+
// the route's loaders, every minute, never while a menu is open
|
|
161
|
+
useVisibleRevalidation(60_000, { enabled: !menuOpen });
|
|
162
|
+
|
|
163
|
+
// any callback, here a fetcher's load, every five minutes
|
|
164
|
+
const counts = useFetcher<Counts>();
|
|
165
|
+
useVisibleInterval(() => void counts.load('/counts'), 300_000);
|
|
166
|
+
return <Tiles counts={counts.data} />;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- The callback runs every `ms` while `document.visibilityState` is
|
|
171
|
+
`'visible'`. A tick that fires while the page is hidden is skipped.
|
|
172
|
+
- When a hidden page becomes visible and at least `ms` has passed since the
|
|
173
|
+
last run, the callback runs at once (`runOnVisible`, default `true`; pass
|
|
174
|
+
`false` to wait for the next tick). A page that comes back sooner waits for
|
|
175
|
+
the tick.
|
|
176
|
+
- `enabled: false` stops the timer and removes the listener; `true` again
|
|
177
|
+
starts a fresh interval.
|
|
178
|
+
- The callback is read from a ref: a new function each render does not
|
|
179
|
+
restart the timer, and the latest one runs. It decides whether to skip a
|
|
180
|
+
read already in flight (`fetcher.state`); `useVisibleRevalidation` does so
|
|
181
|
+
for `useRevalidator`.
|
|
182
|
+
- The timer and the listener are cleared on unmount. On the server nothing
|
|
183
|
+
starts, since effects do not run there.
|
|
184
|
+
- Changing `ms` restarts the interval. `ms` must be positive.
|
package/docs/guide/session.md
CHANGED
|
@@ -462,7 +462,8 @@ headers.append('Set-Cookie', await operator.commit());
|
|
|
462
462
|
answers the seconds until the oldest of them leaves that window, for every
|
|
463
463
|
key. It delays everyone briefly and lifts itself; it never locks an
|
|
464
464
|
account, so one attacker spraying addresses cannot lock the real owner out
|
|
465
|
-
for the per-key window. `clear` leaves it alone.
|
|
465
|
+
for the per-key window. `clear` leaves it alone. For a softer policy, see
|
|
466
|
+
[the delay-only global bucket](#a-delay-only-global-bucket).
|
|
466
467
|
- `verify(task)` runs `task` (the password check) with at most
|
|
467
468
|
`maxConcurrentVerifies` (2) at once, and up to `maxQueuedVerifies` (4) more
|
|
468
469
|
waiting for a slot. Past that it answers `{ busy: true }` without running
|
|
@@ -470,6 +471,44 @@ headers.append('Set-Cookie', await operator.commit());
|
|
|
470
471
|
through and frees its slot.
|
|
471
472
|
- `now` replaces the clock (`() => number` in milliseconds), for a test.
|
|
472
473
|
|
|
474
|
+
#### A delay-only global bucket
|
|
475
|
+
|
|
476
|
+
By default a full global bucket makes `wait` answer a wait for every key, so
|
|
477
|
+
a flood from many addresses also turns the real user away for up to
|
|
478
|
+
`globalWindowMs`. With `globalMode: 'delay'` the bucket never refuses: `wait`
|
|
479
|
+
answers per key only, and `globalDelay()` gives the milliseconds to slow the
|
|
480
|
+
attempt down by.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
export const throttle = createSignInThrottle({
|
|
484
|
+
max: 5,
|
|
485
|
+
windowMs: 15 * 60_000,
|
|
486
|
+
globalMax: 20, // failures, all keys together...
|
|
487
|
+
globalWindowMs: 15 * 60_000, // ...within this window
|
|
488
|
+
globalMode: 'delay', // 'refuse' by default
|
|
489
|
+
maxDelayMs: 3_000, // the longest delay, 3 000 by default
|
|
490
|
+
});
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
// in the sign-in action, before the verification
|
|
495
|
+
const seconds = throttle.wait(email); // per key only in this mode
|
|
496
|
+
if (seconds > 0) return tooMany(seconds);
|
|
497
|
+
|
|
498
|
+
const delay = throttle.globalDelay();
|
|
499
|
+
if (delay > 0) await Bun.sleep(delay);
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
- `globalDelay()` is `0` below `globalMax` failures in the window. From the
|
|
503
|
+
`globalMax`th it is `maxDelayMs / globalMax` for the first, and grows by
|
|
504
|
+
that much with each failure after, until it reaches `maxDelayMs` just
|
|
505
|
+
before twice `globalMax` failures (for `globalMax: 20` and `maxDelayMs: 3000`: 150 ms, 300 ms,
|
|
506
|
+
and so on up to 3 000 ms). It falls back as failures leave the window.
|
|
507
|
+
It records nothing, and `clear` leaves it alone.
|
|
508
|
+
- It is always `0` in the default `'refuse'` mode.
|
|
509
|
+
- Sleeping holds the request open, so keep `maxDelayMs` to a few seconds,
|
|
510
|
+
and let `verify`'s queue bound how many requests wait at once.
|
|
511
|
+
|
|
473
512
|
It is per process, in memory: a restart forgets every failure, and behind
|
|
474
513
|
several instances (or workers) each counts alone, so the effective limits are
|
|
475
514
|
multiplied by the instance count. For a limit shared between instances, count
|
package/docs/roadmap.md
CHANGED
|
@@ -88,6 +88,19 @@ Nothing planned.
|
|
|
88
88
|
|
|
89
89
|
### Unreleased
|
|
90
90
|
|
|
91
|
+
- **`useVisibleInterval` and `useVisibleRevalidation` on `/fetcher`.** A
|
|
92
|
+
callback, or a revalidation of the route's loaders, runs every N ms only
|
|
93
|
+
while the page is visible, and at once when a hidden page comes back after
|
|
94
|
+
more than N ms. See [Fresh data while the page is
|
|
95
|
+
visible](guide/fetcher.md#fresh-data-while-the-page-is-visible-usevisibleintervalcallback-ms-options).
|
|
96
|
+
|
|
97
|
+
- **A delay-only global bucket for `createSignInThrottle`.** With
|
|
98
|
+
`globalMode: 'delay'`, `wait` answers per key only and `globalDelay()` gives
|
|
99
|
+
a bounded delay (capped at `maxDelayMs`) that grows with the failures past
|
|
100
|
+
`globalMax`, so a flood from many addresses is slowed without turning the
|
|
101
|
+
real user away. Refusing stays the default. See [A delay-only global
|
|
102
|
+
bucket](guide/session.md#a-delay-only-global-bucket).
|
|
103
|
+
|
|
91
104
|
- **`createSignInThrottle` on `/session`.** A failed-attempt throttle for a
|
|
92
105
|
password sign-in: `wait`, `fail` and `clear` per key within a window, a
|
|
93
106
|
bounded number of keys, a global bucket that delays rather than locks, and
|
package/docs/troubleshooting.md
CHANGED
|
@@ -86,6 +86,7 @@ a loader, a message React Router or the browser prints, or an error from
|
|
|
86
86
|
- [`TypeError: sessionCookies(): sameSite "none" needs secure: true, since a browser drops a SameSite=None cookie without Secure.`](#typeerror-sessioncookies-samesite-none-needs-secure-true-since-a-browser-drops-a-samesitenone-cookie-without-secure)
|
|
87
87
|
- [`TypeError: signedSession(): secret must be a string of at least 32 characters.`](#typeerror-signedsession-secret-must-be-a-string-of-at-least-32-characters)
|
|
88
88
|
- [`TypeError: signedSession(): the name "…" must be an RFC 6265 token without a __Host- or __Secure- prefix; …` or `maxAge must be a positive integer of seconds; got ….`](#typeerror-signedsession-the-name--must-be-an-rfc-6265-token-without-a-__host--or-__secure--prefix--or-maxage-must-be-a-positive-integer-of-seconds-got-)
|
|
89
|
+
- [`TypeError: createSignInThrottle(): globalMode must be 'refuse' or 'delay'; got ….`](#typeerror-createsigninthrottle-globalmode-must-be-refuse-or-delay-got-)
|
|
89
90
|
- [`TypeError: createSignInThrottle(): … must be a positive integer; got ….` or `… must be a positive integer or 0; got ….`](#typeerror-createsigninthrottle--must-be-a-positive-integer-got--or--must-be-a-positive-integer-or-0-got-)
|
|
90
91
|
- [`TypeError: signInFlow(): paths.… must be a path of this site with no query or fragment, starting with a single "/"; got ….`](#typeerror-signinflow-paths-must-be-a-path-of-this-site-with-no-query-or-fragment-starting-with-a-single--got-)
|
|
91
92
|
- [`TypeError: signInPath(): options.path must be a path of this site with no query or fragment, starting with a single "/"; got ….`](#typeerror-signinpath-optionspath-must-be-a-path-of-this-site-with-no-query-or-fragment-starting-with-a-single--got-)
|
|
@@ -1884,12 +1885,20 @@ TypeError: sessionCookies(): sameSite must be "lax", "strict" or "none"; got "so
|
|
|
1884
1885
|
|
|
1885
1886
|
### `TypeError: createSignInThrottle(): … must be a positive integer; got ….` or `… must be a positive integer or 0; got ….`
|
|
1886
1887
|
|
|
1887
|
-
**When:** the module that calls `createSignInThrottle` is imported (the message names the option: `max`, `windowMs`, `maxKeys`, `globalMax`, `globalWindowMs`, `maxConcurrentVerifies` or `maxQueuedVerifies`).
|
|
1888
|
+
**When:** the module that calls `createSignInThrottle` is imported (the message names the option: `max`, `windowMs`, `maxKeys`, `globalMax`, `globalWindowMs`, `maxDelayMs`, `maxConcurrentVerifies` or `maxQueuedVerifies`).
|
|
1888
1889
|
|
|
1889
1890
|
**Why:** the option is not a whole number above 0 (`maxQueuedVerifies` may be 0, and then the message ends `or 0`), often a value read from the environment as a string or `NaN`.
|
|
1890
1891
|
|
|
1891
1892
|
**Fix:** convert it first, `max: Number(process.env.SIGNIN_MAX ?? 5)`.
|
|
1892
1893
|
|
|
1894
|
+
### `TypeError: createSignInThrottle(): globalMode must be 'refuse' or 'delay'; got ….`
|
|
1895
|
+
|
|
1896
|
+
**When:** the module that calls `createSignInThrottle` is imported.
|
|
1897
|
+
|
|
1898
|
+
**Why:** `globalMode` is neither `'refuse'` (the default) nor `'delay'`, often a value read from the environment or a typo.
|
|
1899
|
+
|
|
1900
|
+
**Fix:** pass one of the two: `globalMode: 'delay'`. See [the delay-only global bucket](guide/session.md#a-delay-only-global-bucket).
|
|
1901
|
+
|
|
1893
1902
|
### `TypeError: signInFlow(): paths.… must be a path of this site with no query or fragment, starting with a single "/"; got ….`
|
|
1894
1903
|
|
|
1895
1904
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alxia/react-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "alxia as the server of a React Router framework app: server rendering behind the app's hooks, loaders reading its typed context, the client's assets served; the code with no UI an installable app shares (`/pwa`), its hooks (`/pwa/react`), `noCache` for the worker's script (`/pwa/server`), the service worker on Workbox (`/pwa/worker`) and its build (`/pwa/build`), an API's refusals worded for the page (`/errors`), the BFF session: cookies, sign-in, step-up and mail links (`/session`), its page hooks (`/session/react`) and what it shares with the page (`/session/model`), a GraphQL subscription relayed to the browser over SSE (`/subscription`), the page's CSP nonce and inline boot scripts (`/document`) and a streaming `entry.server` (`/entry`)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|