tempest-react-sdk 0.48.0 → 0.50.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/dist/audio/sfx-pool.cjs +1 -1
- package/dist/audio/sfx-pool.cjs.map +1 -1
- package/dist/audio/sfx-pool.js +16 -7
- package/dist/audio/sfx-pool.js.map +1 -1
- package/dist/audio/use-sfx-pool.cjs +1 -1
- package/dist/audio/use-sfx-pool.cjs.map +1 -1
- package/dist/audio/use-sfx-pool.js +3 -8
- package/dist/audio/use-sfx-pool.js.map +1 -1
- package/dist/auth/passkey.cjs +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js +79 -81
- package/dist/auth/passkey.js.map +1 -1
- package/dist/charts.cjs +1 -1
- package/dist/charts.js +4 -4
- package/dist/components/BarList/BarList.cjs +1 -1
- package/dist/components/BarList/BarList.cjs.map +1 -1
- package/dist/components/BarList/BarList.js +31 -24
- package/dist/components/BarList/BarList.js.map +1 -1
- package/dist/components/BarList/bar-list-model.cjs +1 -1
- package/dist/components/BarList/bar-list-model.cjs.map +1 -1
- package/dist/components/BarList/bar-list-model.js +5 -5
- package/dist/components/BarList/bar-list-model.js.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.js +13 -14
- package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +99 -95
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.cjs +1 -1
- package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.js +5 -3
- package/dist/components/DataTable/use-dev-warnings.js.map +1 -1
- package/dist/components/FilterBar/filter-apply.cjs +1 -1
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
- package/dist/components/FilterBar/filter-apply.js +35 -38
- package/dist/components/FilterBar/filter-apply.js.map +1 -1
- package/dist/components/FilterBar/filter-query.cjs +1 -1
- package/dist/components/FilterBar/filter-query.cjs.map +1 -1
- package/dist/components/FilterBar/filter-query.js +16 -13
- package/dist/components/FilterBar/filter-query.js.map +1 -1
- package/dist/geo/use-position-tracker.cjs +1 -1
- package/dist/geo/use-position-tracker.cjs.map +1 -1
- package/dist/geo/use-position-tracker.js +25 -26
- package/dist/geo/use-position-tracker.js.map +1 -1
- package/dist/hooks/use-async.cjs +1 -1
- package/dist/hooks/use-async.cjs.map +1 -1
- package/dist/hooks/use-async.js +27 -30
- package/dist/hooks/use-async.js.map +1 -1
- package/dist/hooks/use-click-outside.cjs +1 -1
- package/dist/hooks/use-click-outside.cjs.map +1 -1
- package/dist/hooks/use-click-outside.js +8 -9
- package/dist/hooks/use-click-outside.js.map +1 -1
- package/dist/hooks/use-countdown.cjs +1 -1
- package/dist/hooks/use-countdown.cjs.map +1 -1
- package/dist/hooks/use-countdown.js +8 -13
- package/dist/hooks/use-countdown.js.map +1 -1
- package/dist/hooks/use-event-listener.cjs +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-event-listener.js +6 -6
- package/dist/hooks/use-event-listener.js.map +1 -1
- package/dist/hooks/use-interval.cjs +1 -1
- package/dist/hooks/use-interval.cjs.map +1 -1
- package/dist/hooks/use-interval.js +5 -6
- package/dist/hooks/use-interval.js.map +1 -1
- package/dist/hooks/use-latest-ref.cjs.map +1 -1
- package/dist/hooks/use-latest-ref.js.map +1 -1
- package/dist/hooks/use-long-press-handlers.cjs +1 -1
- package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
- package/dist/hooks/use-long-press-handlers.js +8 -10
- package/dist/hooks/use-long-press-handlers.js.map +1 -1
- package/dist/hooks/use-long-press.cjs +1 -1
- package/dist/hooks/use-long-press.cjs.map +1 -1
- package/dist/hooks/use-long-press.js +6 -6
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-online.cjs +1 -1
- package/dist/hooks/use-online.cjs.map +1 -1
- package/dist/hooks/use-online.js +10 -10
- package/dist/hooks/use-online.js.map +1 -1
- package/dist/hooks/use-service-worker-update.cjs +1 -1
- package/dist/hooks/use-service-worker-update.cjs.map +1 -1
- package/dist/hooks/use-service-worker-update.js +24 -25
- package/dist/hooks/use-service-worker-update.js.map +1 -1
- package/dist/hooks/use-stable-callback.cjs +1 -1
- package/dist/hooks/use-stable-callback.cjs.map +1 -1
- package/dist/hooks/use-stable-callback.js +4 -3
- package/dist/hooks/use-stable-callback.js.map +1 -1
- package/dist/hooks/use-timeout.cjs +1 -1
- package/dist/hooks/use-timeout.cjs.map +1 -1
- package/dist/hooks/use-timeout.js +5 -6
- package/dist/hooks/use-timeout.js.map +1 -1
- package/dist/hooks/use-typewriter.cjs +1 -1
- package/dist/hooks/use-typewriter.cjs.map +1 -1
- package/dist/hooks/use-typewriter.js +9 -18
- package/dist/hooks/use-typewriter.js.map +1 -1
- package/dist/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +11 -16
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/describe-api-error.cjs +1 -1
- package/dist/http/describe-api-error.cjs.map +1 -1
- package/dist/http/describe-api-error.js +12 -15
- package/dist/http/describe-api-error.js.map +1 -1
- package/dist/http/errors.cjs +1 -1
- package/dist/http/errors.cjs.map +1 -1
- package/dist/http/errors.js +18 -6
- package/dist/http/errors.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +125 -118
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +20 -16
- package/dist/http/retry.js.map +1 -1
- package/dist/http/use-describe-api-error.cjs +1 -1
- package/dist/http/use-describe-api-error.cjs.map +1 -1
- package/dist/http/use-describe-api-error.js +2 -2
- package/dist/http/use-describe-api-error.js.map +1 -1
- package/dist/i18n/create-i18n.cjs +1 -1
- package/dist/i18n/create-i18n.cjs.map +1 -1
- package/dist/i18n/create-i18n.js +6 -6
- package/dist/i18n/create-i18n.js.map +1 -1
- package/dist/icons/material-symbols.cjs +1 -1
- package/dist/icons/material-symbols.cjs.map +1 -1
- package/dist/icons/material-symbols.js +136 -5
- package/dist/icons/material-symbols.js.map +1 -1
- package/dist/icons.d.ts +17 -5
- package/dist/offline/create-offline-sync.cjs +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js +17 -9
- package/dist/offline/create-offline-sync.js.map +1 -1
- package/dist/offline/use-offline-sync.cjs +1 -1
- package/dist/offline/use-offline-sync.cjs.map +1 -1
- package/dist/offline/use-offline-sync.js +7 -8
- package/dist/offline/use-offline-sync.js.map +1 -1
- package/dist/push/use-push-subscription.cjs +1 -1
- package/dist/push/use-push-subscription.cjs.map +1 -1
- package/dist/push/use-push-subscription.js +13 -12
- package/dist/push/use-push-subscription.js.map +1 -1
- package/dist/query/retry-policy.cjs +1 -1
- package/dist/query/retry-policy.cjs.map +1 -1
- package/dist/query/retry-policy.js +3 -3
- package/dist/query/retry-policy.js.map +1 -1
- package/dist/sse/use-event-stream.cjs +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/sse/use-event-stream.js +19 -20
- package/dist/sse/use-event-stream.js.map +1 -1
- package/dist/tabular/use-tabular-predictor.cjs +1 -1
- package/dist/tabular/use-tabular-predictor.cjs.map +1 -1
- package/dist/tabular/use-tabular-predictor.js +20 -17
- package/dist/tabular/use-tabular-predictor.js.map +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +381 -143
- package/dist/tempest-react-sdk.js +143 -143
- package/dist/theme/ThemeProvider.cjs +1 -1
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/ThemeProvider.js +12 -17
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/utils/base64.cjs +2 -0
- package/dist/utils/base64.cjs.map +1 -0
- package/dist/utils/base64.js +16 -0
- package/dist/utils/base64.js.map +1 -0
- package/dist/utils/compare-values.cjs +1 -1
- package/dist/utils/compare-values.cjs.map +1 -1
- package/dist/utils/compare-values.js +4 -3
- package/dist/utils/compare-values.js.map +1 -1
- package/dist/utils/compressed-storage.cjs +1 -1
- package/dist/utils/compressed-storage.cjs.map +1 -1
- package/dist/utils/compressed-storage.js +16 -46
- package/dist/utils/compressed-storage.js.map +1 -1
- package/dist/utils/storage.cjs +1 -1
- package/dist/utils/storage.cjs.map +1 -1
- package/dist/utils/storage.js +37 -17
- package/dist/utils/storage.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +34 -33
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vite/base-url.cjs +2 -0
- package/dist/vite/base-url.cjs.map +1 -0
- package/dist/vite/base-url.js +8 -0
- package/dist/vite/base-url.js.map +1 -0
- package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.js +54 -29
- package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs +2 -2
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js +15 -14
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/vite.d.ts +2 -2
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +40 -42
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-push-subscription.cjs","names":[],"sources":["../../src/push/use-push-subscription.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- the ref is read inside deferred callbacks, not during render */\nimport { useCallback, useEffect, useMemo,
|
|
1
|
+
{"version":3,"file":"use-push-subscription.cjs","names":[],"sources":["../../src/push/use-push-subscription.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- the ref is read inside deferred callbacks, not during render */\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport { WebPushClient, type WebPushClientConfig } from \"./web-push-client\";\nimport { isPushSupported } from \"./utils\";\n\nexport interface UsePushSubscriptionResult {\n /** True when the browser exposes the Push + Notification APIs. */\n supported: boolean;\n /** Current `Notification.permission` value, or `\"unsupported\"`. */\n permission: NotificationPermission | \"unsupported\";\n /** True when a subscription is active on this device. */\n subscribed: boolean;\n /** True while a subscribe/unsubscribe call is in-flight. */\n loading: boolean;\n /** Last error thrown by subscribe/unsubscribe, if any. */\n error: Error | null;\n subscribe: () => Promise<void>;\n unsubscribe: () => Promise<void>;\n /** Re-read the current subscription/permission state from the browser. */\n refresh: () => Promise<void>;\n}\n\n/**\n * React hook around {@link WebPushClient}. Tracks subscription, permission and\n * loading state; exposes imperative `subscribe`/`unsubscribe` actions.\n *\n * The hook does NOT register the service worker — the host app must do that\n * (e.g. via `vite-plugin-pwa` or a manual `navigator.serviceWorker.register`).\n *\n * @example\n * const push = usePushSubscription({\n * vapidPublicKey: import.meta.env.VITE_VAPID_PUBLIC_KEY,\n * onSubscribe: (sub) => api.post(\"/webpush/subscribe\", { body: sub }),\n * onUnsubscribe: () => api.delete(\"/webpush/my\"),\n * });\n */\nexport function usePushSubscription(config: WebPushClientConfig): UsePushSubscriptionResult {\n const configRef = useLatestRef(config);\n\n const client = useMemo(\n () =>\n new WebPushClient({\n vapidPublicKey: config.vapidPublicKey,\n onSubscribe: (sub) => configRef.current.onSubscribe(sub),\n onUnsubscribe: (sub) => configRef.current.onUnsubscribe?.(sub),\n getRegistration: config.getRegistration,\n }),\n [config.vapidPublicKey, config.getRegistration, configRef],\n );\n\n const [supported] = useState<boolean>(() => isPushSupported());\n const [permission, setPermission] = useState<NotificationPermission | \"unsupported\">(() =>\n client.permission(),\n );\n const [subscribed, setSubscribed] = useState<boolean>(false);\n const [loading, setLoading] = useState<boolean>(false);\n const [error, setError] = useState<Error | null>(null);\n\n const refresh = useCallback(async () => {\n if (!supported) return;\n setPermission(client.permission());\n try {\n const active = await client.isSubscribed();\n setSubscribed(active);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, [client, supported]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const subscribe = useCallback(async () => {\n if (!supported) return;\n setLoading(true);\n setError(null);\n try {\n await client.subscribe();\n setSubscribed(true);\n setPermission(client.permission());\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n throw err;\n } finally {\n setLoading(false);\n }\n }, [client, supported]);\n\n const unsubscribe = useCallback(async () => {\n if (!supported) return;\n setLoading(true);\n setError(null);\n try {\n await client.unsubscribe();\n setSubscribed(false);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n throw err;\n } finally {\n setLoading(false);\n }\n }, [client, supported]);\n\n return {\n supported,\n permission,\n subscribed,\n loading,\n error,\n subscribe,\n unsubscribe,\n refresh,\n };\n}\n"],"mappings":"kIAqCA,SAAgB,EAAoB,EAAwD,CACxF,IAAM,EAAY,EAAA,aAAa,CAAM,EAE/B,GAAA,EAAS,EAAA,QAAA,KAEP,IAAI,EAAA,cAAc,CACd,eAAgB,EAAO,eACvB,YAAc,GAAQ,EAAU,QAAQ,YAAY,CAAG,EACvD,cAAgB,GAAQ,EAAU,QAAQ,gBAAgB,CAAG,EAC7D,gBAAiB,EAAO,eAC5B,CAAC,EACL,CAAC,EAAO,eAAgB,EAAO,gBAAiB,CAAS,CAC7D,EAEM,CAAC,IAAA,EAAa,EAAA,SAAA,KAAwB,EAAA,gBAAgB,CAAC,EACvD,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,KAChC,EAAO,WAAW,CACtB,EACM,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAkB,EAAK,EACrD,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAkB,EAAK,EAC/C,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAuB,IAAI,EAE/C,GAAA,EAAU,EAAA,YAAA,CAAY,SAAY,CAC/B,KACL,GAAc,EAAO,WAAW,CAAC,EACjC,GAAI,CACA,IAAM,EAAS,MAAM,EAAO,aAAa,EACzC,EAAc,CAAM,CACxB,OAAS,EAAK,CACV,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,CAChE,CANiC,CAOrC,EAAG,CAAC,EAAQ,CAAS,CAAC,EAqCtB,OAnCA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAa,CACjB,EAAG,CAAC,CAAO,CAAC,EAiCL,CACH,YACA,aACA,aACA,UACA,QACA,WAAA,EArCc,EAAA,YAAA,CAAY,SAAY,CACjC,KAEL,CADA,EAAW,EAAI,EACf,EAAS,IAAI,EACb,GAAI,CACA,MAAM,EAAO,UAAU,EACvB,EAAc,EAAI,EAClB,EAAc,EAAO,WAAW,CAAC,CACrC,OAAS,EAAK,CAEV,MADA,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,EACtD,CACV,QAAU,CACN,EAAW,EAAK,CACpB,CAVa,CAWjB,EAAG,CAAC,EAAQ,CAAS,CAuBjB,EACA,aAAA,EAtBgB,EAAA,YAAA,CAAY,SAAY,CACnC,KAEL,CADA,EAAW,EAAI,EACf,EAAS,IAAI,EACb,GAAI,CACA,MAAM,EAAO,YAAY,EACzB,EAAc,EAAK,CACvB,OAAS,EAAK,CAEV,MADA,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,EACtD,CACV,QAAU,CACN,EAAW,EAAK,CACpB,CATa,CAUjB,EAAG,CAAC,EAAQ,CAAS,CASjB,EACA,SACJ,CACJ"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "../hooks/use-latest-ref.js";
|
|
2
|
+
import { isPushSupported as t } from "./utils.js";
|
|
3
|
+
import { WebPushClient as n } from "./web-push-client.js";
|
|
4
|
+
import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
|
|
4
5
|
//#region src/push/use-push-subscription.ts
|
|
5
6
|
function s(s) {
|
|
6
|
-
let c =
|
|
7
|
-
r(() => {
|
|
8
|
-
c.current = s;
|
|
9
|
-
}, [s]);
|
|
10
|
-
let l = i(() => new t({
|
|
7
|
+
let c = e(s), l = a(() => new n({
|
|
11
8
|
vapidPublicKey: s.vapidPublicKey,
|
|
12
9
|
onSubscribe: (e) => c.current.onSubscribe(e),
|
|
13
10
|
onUnsubscribe: (e) => c.current.onUnsubscribe?.(e),
|
|
14
11
|
getRegistration: s.getRegistration
|
|
15
|
-
}), [
|
|
12
|
+
}), [
|
|
13
|
+
s.vapidPublicKey,
|
|
14
|
+
s.getRegistration,
|
|
15
|
+
c
|
|
16
|
+
]), [u] = o(() => t()), [d, f] = o(() => l.permission()), [p, m] = o(!1), [h, g] = o(!1), [_, v] = o(null), y = r(async () => {
|
|
16
17
|
if (u) {
|
|
17
18
|
f(l.permission());
|
|
18
19
|
try {
|
|
@@ -23,7 +24,7 @@ function s(s) {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
}, [l, u]);
|
|
26
|
-
return
|
|
27
|
+
return i(() => {
|
|
27
28
|
y();
|
|
28
29
|
}, [y]), {
|
|
29
30
|
supported: u,
|
|
@@ -31,7 +32,7 @@ function s(s) {
|
|
|
31
32
|
subscribed: p,
|
|
32
33
|
loading: h,
|
|
33
34
|
error: _,
|
|
34
|
-
subscribe:
|
|
35
|
+
subscribe: r(async () => {
|
|
35
36
|
if (u) {
|
|
36
37
|
g(!0), v(null);
|
|
37
38
|
try {
|
|
@@ -43,7 +44,7 @@ function s(s) {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}, [l, u]),
|
|
46
|
-
unsubscribe:
|
|
47
|
+
unsubscribe: r(async () => {
|
|
47
48
|
if (u) {
|
|
48
49
|
g(!0), v(null);
|
|
49
50
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-push-subscription.js","names":[],"sources":["../../src/push/use-push-subscription.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- the ref is read inside deferred callbacks, not during render */\nimport { useCallback, useEffect, useMemo,
|
|
1
|
+
{"version":3,"file":"use-push-subscription.js","names":[],"sources":["../../src/push/use-push-subscription.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- the ref is read inside deferred callbacks, not during render */\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport { WebPushClient, type WebPushClientConfig } from \"./web-push-client\";\nimport { isPushSupported } from \"./utils\";\n\nexport interface UsePushSubscriptionResult {\n /** True when the browser exposes the Push + Notification APIs. */\n supported: boolean;\n /** Current `Notification.permission` value, or `\"unsupported\"`. */\n permission: NotificationPermission | \"unsupported\";\n /** True when a subscription is active on this device. */\n subscribed: boolean;\n /** True while a subscribe/unsubscribe call is in-flight. */\n loading: boolean;\n /** Last error thrown by subscribe/unsubscribe, if any. */\n error: Error | null;\n subscribe: () => Promise<void>;\n unsubscribe: () => Promise<void>;\n /** Re-read the current subscription/permission state from the browser. */\n refresh: () => Promise<void>;\n}\n\n/**\n * React hook around {@link WebPushClient}. Tracks subscription, permission and\n * loading state; exposes imperative `subscribe`/`unsubscribe` actions.\n *\n * The hook does NOT register the service worker — the host app must do that\n * (e.g. via `vite-plugin-pwa` or a manual `navigator.serviceWorker.register`).\n *\n * @example\n * const push = usePushSubscription({\n * vapidPublicKey: import.meta.env.VITE_VAPID_PUBLIC_KEY,\n * onSubscribe: (sub) => api.post(\"/webpush/subscribe\", { body: sub }),\n * onUnsubscribe: () => api.delete(\"/webpush/my\"),\n * });\n */\nexport function usePushSubscription(config: WebPushClientConfig): UsePushSubscriptionResult {\n const configRef = useLatestRef(config);\n\n const client = useMemo(\n () =>\n new WebPushClient({\n vapidPublicKey: config.vapidPublicKey,\n onSubscribe: (sub) => configRef.current.onSubscribe(sub),\n onUnsubscribe: (sub) => configRef.current.onUnsubscribe?.(sub),\n getRegistration: config.getRegistration,\n }),\n [config.vapidPublicKey, config.getRegistration, configRef],\n );\n\n const [supported] = useState<boolean>(() => isPushSupported());\n const [permission, setPermission] = useState<NotificationPermission | \"unsupported\">(() =>\n client.permission(),\n );\n const [subscribed, setSubscribed] = useState<boolean>(false);\n const [loading, setLoading] = useState<boolean>(false);\n const [error, setError] = useState<Error | null>(null);\n\n const refresh = useCallback(async () => {\n if (!supported) return;\n setPermission(client.permission());\n try {\n const active = await client.isSubscribed();\n setSubscribed(active);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, [client, supported]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const subscribe = useCallback(async () => {\n if (!supported) return;\n setLoading(true);\n setError(null);\n try {\n await client.subscribe();\n setSubscribed(true);\n setPermission(client.permission());\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n throw err;\n } finally {\n setLoading(false);\n }\n }, [client, supported]);\n\n const unsubscribe = useCallback(async () => {\n if (!supported) return;\n setLoading(true);\n setError(null);\n try {\n await client.unsubscribe();\n setSubscribed(false);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n throw err;\n } finally {\n setLoading(false);\n }\n }, [client, supported]);\n\n return {\n supported,\n permission,\n subscribed,\n loading,\n error,\n subscribe,\n unsubscribe,\n refresh,\n };\n}\n"],"mappings":";;;;;AAqCA,SAAgB,EAAoB,GAAwD;CACxF,IAAM,IAAY,EAAa,CAAM,GAE/B,IAAS,QAEP,IAAI,EAAc;EACd,gBAAgB,EAAO;EACvB,cAAc,MAAQ,EAAU,QAAQ,YAAY,CAAG;EACvD,gBAAgB,MAAQ,EAAU,QAAQ,gBAAgB,CAAG;EAC7D,iBAAiB,EAAO;CAC5B,CAAC,GACL;EAAC,EAAO;EAAgB,EAAO;EAAiB;CAAS,CAC7D,GAEM,CAAC,KAAa,QAAwB,EAAgB,CAAC,GACvD,CAAC,GAAY,KAAiB,QAChC,EAAO,WAAW,CACtB,GACM,CAAC,GAAY,KAAiB,EAAkB,EAAK,GACrD,CAAC,GAAS,KAAc,EAAkB,EAAK,GAC/C,CAAC,GAAO,KAAY,EAAuB,IAAI,GAE/C,IAAU,EAAY,YAAY;EAC/B,OACL;KAAc,EAAO,WAAW,CAAC;GACjC,IAAI;IACA,IAAM,IAAS,MAAM,EAAO,aAAa;IACzC,EAAc,CAAM;GACxB,SAAS,GAAK;IACV,EAAS,aAAe,QAAQ,IAAU,MAAM,OAAO,CAAG,CAAC,CAAC;GAChE;EANiC;CAOrC,GAAG,CAAC,GAAQ,CAAS,CAAC;CAqCtB,OAnCA,QAAgB;EACZ,EAAa;CACjB,GAAG,CAAC,CAAO,CAAC,GAiCL;EACH;EACA;EACA;EACA;EACA;EACA,WArCc,EAAY,YAAY;GACjC,OAEL;IADA,EAAW,EAAI,GACf,EAAS,IAAI;IACb,IAAI;KAGA,AAFA,MAAM,EAAO,UAAU,GACvB,EAAc,EAAI,GAClB,EAAc,EAAO,WAAW,CAAC;IACrC,SAAS,GAAK;KAEV,MADA,EAAS,aAAe,QAAQ,IAAU,MAAM,OAAO,CAAG,CAAC,CAAC,GACtD;IACV,UAAU;KACN,EAAW,EAAK;IACpB;GAVa;EAWjB,GAAG,CAAC,GAAQ,CAAS,CAuBjB;EACA,aAtBgB,EAAY,YAAY;GACnC,OAEL;IADA,EAAW,EAAI,GACf,EAAS,IAAI;IACb,IAAI;KAEA,AADA,MAAM,EAAO,YAAY,GACzB,EAAc,EAAK;IACvB,SAAS,GAAK;KAEV,MADA,EAAS,aAAe,QAAQ,IAAU,MAAM,OAAO,CAAG,CAAC,CAAC,GACtD;IACV,UAAU;KACN,EAAW,EAAK;IACpB;GATa;EAUjB,GAAG,CAAC,GAAQ,CAAS,CASjB;EACA;CACJ;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../http/errors.cjs");var t=
|
|
1
|
+
const e=require("../http/errors.cjs");var t=1;function n(n,r){return n>=t?!1:!e.isApiError(r)||e.isRetriableStatus(r.status)}exports.shouldRetryQuery=n;
|
|
2
2
|
//# sourceMappingURL=retry-policy.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-policy.cjs","names":[],"sources":["../../src/query/retry-policy.ts"],"sourcesContent":["import { isApiError } from \"../http/errors\";\n\n
|
|
1
|
+
{"version":3,"file":"retry-policy.cjs","names":[],"sources":["../../src/query/retry-policy.ts"],"sourcesContent":["import { isApiError, isRetriableStatus } from \"../http/errors\";\n\n/** How many times a retriable failure is replayed. */\nconst MAX_RETRIES = 1;\n\n/**\n * Default `retry` for SDK queries: replay transport and server failures, never a\n * deliberate client-side refusal.\n *\n * A flat `retry: 1` replays a 403 on an admin-only listing and a 404 for a record\n * somebody deleted. The server meant both — the second attempt returns the same\n * answer, doubles the network log and holds the spinner on screen for the length\n * of another round trip. A network failure or a 5xx is a different thing: it may\n * well succeed on the next try, so those keep the previous behaviour.\n *\n * The status list is {@link isRetriableStatus}, shared with the client's own\n * policy. It used to be a second copy here, and the copy was missing `425` — so\n * a `425 Too Early` was replayed by `createApiClient({ retry: true })` and not\n * by a query, for the same error in the same app.\n *\n * @example\n * new QueryClient({ defaultOptions: { queries: { retry: shouldRetryQuery } } });\n *\n * @param failureCount - Attempts already made, as react-query counts them.\n * @param error - The rejection value from the query function.\n * @returns Whether react-query should try again.\n */\nexport function shouldRetryQuery(failureCount: number, error: unknown): boolean {\n if (failureCount >= MAX_RETRIES) return false;\n if (!isApiError(error)) return true;\n return isRetriableStatus(error.status);\n}\n"],"mappings":"sCAGA,IAAM,EAAc,EAwBpB,SAAgB,EAAiB,EAAsB,EAAyB,CAG5E,OAFI,GAAgB,EAAoB,GACxC,CAAK,EAAA,WAAW,CAAK,GACd,EAAA,kBAAkB,EAAM,MAAM,CACzC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { isApiError as e } from "../http/errors.js";
|
|
1
|
+
import { isApiError as e, isRetriableStatus as t } from "../http/errors.js";
|
|
2
2
|
//#region src/query/retry-policy.ts
|
|
3
|
-
var
|
|
3
|
+
var n = 1;
|
|
4
4
|
function r(r, i) {
|
|
5
|
-
return r >= n ? !1 : !e(i) ||
|
|
5
|
+
return r >= n ? !1 : !e(i) || t(i.status);
|
|
6
6
|
}
|
|
7
7
|
//#endregion
|
|
8
8
|
export { r as shouldRetryQuery };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-policy.js","names":[],"sources":["../../src/query/retry-policy.ts"],"sourcesContent":["import { isApiError } from \"../http/errors\";\n\n
|
|
1
|
+
{"version":3,"file":"retry-policy.js","names":[],"sources":["../../src/query/retry-policy.ts"],"sourcesContent":["import { isApiError, isRetriableStatus } from \"../http/errors\";\n\n/** How many times a retriable failure is replayed. */\nconst MAX_RETRIES = 1;\n\n/**\n * Default `retry` for SDK queries: replay transport and server failures, never a\n * deliberate client-side refusal.\n *\n * A flat `retry: 1` replays a 403 on an admin-only listing and a 404 for a record\n * somebody deleted. The server meant both — the second attempt returns the same\n * answer, doubles the network log and holds the spinner on screen for the length\n * of another round trip. A network failure or a 5xx is a different thing: it may\n * well succeed on the next try, so those keep the previous behaviour.\n *\n * The status list is {@link isRetriableStatus}, shared with the client's own\n * policy. It used to be a second copy here, and the copy was missing `425` — so\n * a `425 Too Early` was replayed by `createApiClient({ retry: true })` and not\n * by a query, for the same error in the same app.\n *\n * @example\n * new QueryClient({ defaultOptions: { queries: { retry: shouldRetryQuery } } });\n *\n * @param failureCount - Attempts already made, as react-query counts them.\n * @param error - The rejection value from the query function.\n * @returns Whether react-query should try again.\n */\nexport function shouldRetryQuery(failureCount: number, error: unknown): boolean {\n if (failureCount >= MAX_RETRIES) return false;\n if (!isApiError(error)) return true;\n return isRetriableStatus(error.status);\n}\n"],"mappings":";;AAGA,IAAM,IAAc;AAwBpB,SAAgB,EAAiB,GAAsB,GAAyB;CAG5E,OAFI,KAAgB,IAAoB,KACxC,CAAK,EAAW,CAAK,KACd,EAAkB,EAAM,MAAM;AACzC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./create-event-stream.cjs");let
|
|
1
|
+
const e=require("../hooks/use-latest-ref.cjs"),t=require("./create-event-stream.cjs");let n=require("react");function r(r,i={}){let{enabled:a=!0,onMessage:o,...s}=i,[c,l]=(0,n.useState)(`idle`),[u,d]=(0,n.useState)(null),f=(0,n.useRef)(null),p=e.useLatestRef(o);return(0,n.useEffect)(()=>{if(!a||!r){l(`idle`);return}let e=t.createEventStream(r,{...s,onStatusChange:l,onMessage:e=>{d(e),p.current?.(e)}});return f.current=e.reconnect,()=>{e.close(),f.current=null}},[r,a]),{status:c,lastMessage:u,reconnect:()=>f.current?.()}}exports.useEventStream=r;
|
|
2
2
|
//# sourceMappingURL=use-event-stream.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-event-stream.cjs","names":[],"sources":["../../src/sse/use-event-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n createEventStream,\n type CreateEventStreamOptions,\n type EventStreamMessage,\n type EventStreamStatus,\n} from \"./create-event-stream\";\n\nexport interface UseEventStreamOptions<T> extends Omit<\n CreateEventStreamOptions<T>,\n \"onStatusChange\"\n> {\n /** When false, the stream is not opened. Useful for \"wait for auth\". Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseEventStreamResult<T> {\n status: EventStreamStatus;\n /** Last message received (excluding heartbeats). */\n lastMessage: EventStreamMessage<T> | null;\n /** Force a reconnect. */\n reconnect: () => void;\n}\n\n/**\n * React hook wrapper around {@link createEventStream}. Connection lifecycle is\n * tied to the component (and the `url`/`enabled` dependencies); the stream\n * closes on unmount.\n *\n * @example\n * useEventStream<Notification>(`${API}/notifications/stream`, {\n * enabled: !!user,\n * withCredentials: true,\n * onMessage: ({ data }) => addNotification(data),\n * });\n */\nexport function useEventStream<T = unknown>(\n url: string,\n options: UseEventStreamOptions<T> = {},\n): UseEventStreamResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<EventStreamStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<EventStreamMessage<T> | null>(null);\n const reconnectRef = useRef<(() => void) | null>(null);\n\n const onMessageRef =
|
|
1
|
+
{"version":3,"file":"use-event-stream.cjs","names":[],"sources":["../../src/sse/use-event-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport {\n createEventStream,\n type CreateEventStreamOptions,\n type EventStreamMessage,\n type EventStreamStatus,\n} from \"./create-event-stream\";\n\nexport interface UseEventStreamOptions<T> extends Omit<\n CreateEventStreamOptions<T>,\n \"onStatusChange\"\n> {\n /** When false, the stream is not opened. Useful for \"wait for auth\". Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseEventStreamResult<T> {\n status: EventStreamStatus;\n /** Last message received (excluding heartbeats). */\n lastMessage: EventStreamMessage<T> | null;\n /** Force a reconnect. */\n reconnect: () => void;\n}\n\n/**\n * React hook wrapper around {@link createEventStream}. Connection lifecycle is\n * tied to the component (and the `url`/`enabled` dependencies); the stream\n * closes on unmount.\n *\n * @example\n * useEventStream<Notification>(`${API}/notifications/stream`, {\n * enabled: !!user,\n * withCredentials: true,\n * onMessage: ({ data }) => addNotification(data),\n * });\n */\nexport function useEventStream<T = unknown>(\n url: string,\n options: UseEventStreamOptions<T> = {},\n): UseEventStreamResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<EventStreamStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<EventStreamMessage<T> | null>(null);\n const reconnectRef = useRef<(() => void) | null>(null);\n\n const onMessageRef = useLatestRef(onMessage);\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createEventStream<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n reconnectRef.current = controller.reconnect;\n\n return () => {\n controller.close();\n reconnectRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n return {\n status,\n lastMessage,\n reconnect: () => reconnectRef.current?.(),\n };\n}\n"],"mappings":"6GAqCA,SAAgB,EACZ,EACA,EAAoC,CAAC,EACd,CACvB,GAAM,CAAE,UAAU,GAAM,YAAW,GAAG,GAAS,EACzC,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAA4B,MAAM,EACxD,CAAC,EAAa,IAAA,EAAkB,EAAA,SAAA,CAAuC,IAAI,EAC3E,GAAA,EAAe,EAAA,OAAA,CAA4B,IAAI,EAE/C,EAAe,EAAA,aAAa,CAAS,EAyB3C,OAvBA,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAW,CAAC,EAAK,CAClB,EAAU,MAAM,EAChB,MACJ,CAEA,IAAM,EAAa,EAAA,kBAAqB,EAAK,CACzC,GAAG,EACH,eAAgB,EAChB,UAAY,GAAY,CACpB,EAAe,CAAO,EACtB,EAAa,UAAU,CAAO,CAClC,CACJ,CAAC,EAGD,MAFA,GAAa,QAAU,EAAW,cAErB,CACT,EAAW,MAAM,EACjB,EAAa,QAAU,IAC3B,CAEJ,EAAG,CAAC,EAAK,CAAO,CAAC,EAEV,CACH,SACA,cACA,cAAiB,EAAa,UAAU,CAC5C,CACJ"}
|
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "../hooks/use-latest-ref.js";
|
|
2
|
+
import { createEventStream as t } from "./create-event-stream.js";
|
|
3
|
+
import { useEffect as n, useRef as r, useState as i } from "react";
|
|
3
4
|
//#region src/sse/use-event-stream.ts
|
|
4
|
-
function
|
|
5
|
-
let { enabled:
|
|
6
|
-
return
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!o || !i) {
|
|
10
|
-
u("idle");
|
|
5
|
+
function a(a, o = {}) {
|
|
6
|
+
let { enabled: s = !0, onMessage: c, ...l } = o, [u, d] = i("idle"), [f, p] = i(null), m = r(null), h = e(c);
|
|
7
|
+
return n(() => {
|
|
8
|
+
if (!s || !a) {
|
|
9
|
+
d("idle");
|
|
11
10
|
return;
|
|
12
11
|
}
|
|
13
|
-
let
|
|
14
|
-
...
|
|
15
|
-
onStatusChange:
|
|
12
|
+
let e = t(a, {
|
|
13
|
+
...l,
|
|
14
|
+
onStatusChange: d,
|
|
16
15
|
onMessage: (e) => {
|
|
17
|
-
|
|
16
|
+
p(e), h.current?.(e);
|
|
18
17
|
}
|
|
19
18
|
});
|
|
20
|
-
return
|
|
21
|
-
|
|
19
|
+
return m.current = e.reconnect, () => {
|
|
20
|
+
e.close(), m.current = null;
|
|
22
21
|
};
|
|
23
|
-
}, [
|
|
24
|
-
status:
|
|
25
|
-
lastMessage:
|
|
26
|
-
reconnect: () =>
|
|
22
|
+
}, [a, s]), {
|
|
23
|
+
status: u,
|
|
24
|
+
lastMessage: f,
|
|
25
|
+
reconnect: () => m.current?.()
|
|
27
26
|
};
|
|
28
27
|
}
|
|
29
28
|
//#endregion
|
|
30
|
-
export {
|
|
29
|
+
export { a as useEventStream };
|
|
31
30
|
|
|
32
31
|
//# sourceMappingURL=use-event-stream.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-event-stream.js","names":[],"sources":["../../src/sse/use-event-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n createEventStream,\n type CreateEventStreamOptions,\n type EventStreamMessage,\n type EventStreamStatus,\n} from \"./create-event-stream\";\n\nexport interface UseEventStreamOptions<T> extends Omit<\n CreateEventStreamOptions<T>,\n \"onStatusChange\"\n> {\n /** When false, the stream is not opened. Useful for \"wait for auth\". Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseEventStreamResult<T> {\n status: EventStreamStatus;\n /** Last message received (excluding heartbeats). */\n lastMessage: EventStreamMessage<T> | null;\n /** Force a reconnect. */\n reconnect: () => void;\n}\n\n/**\n * React hook wrapper around {@link createEventStream}. Connection lifecycle is\n * tied to the component (and the `url`/`enabled` dependencies); the stream\n * closes on unmount.\n *\n * @example\n * useEventStream<Notification>(`${API}/notifications/stream`, {\n * enabled: !!user,\n * withCredentials: true,\n * onMessage: ({ data }) => addNotification(data),\n * });\n */\nexport function useEventStream<T = unknown>(\n url: string,\n options: UseEventStreamOptions<T> = {},\n): UseEventStreamResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<EventStreamStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<EventStreamMessage<T> | null>(null);\n const reconnectRef = useRef<(() => void) | null>(null);\n\n const onMessageRef =
|
|
1
|
+
{"version":3,"file":"use-event-stream.js","names":[],"sources":["../../src/sse/use-event-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport {\n createEventStream,\n type CreateEventStreamOptions,\n type EventStreamMessage,\n type EventStreamStatus,\n} from \"./create-event-stream\";\n\nexport interface UseEventStreamOptions<T> extends Omit<\n CreateEventStreamOptions<T>,\n \"onStatusChange\"\n> {\n /** When false, the stream is not opened. Useful for \"wait for auth\". Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseEventStreamResult<T> {\n status: EventStreamStatus;\n /** Last message received (excluding heartbeats). */\n lastMessage: EventStreamMessage<T> | null;\n /** Force a reconnect. */\n reconnect: () => void;\n}\n\n/**\n * React hook wrapper around {@link createEventStream}. Connection lifecycle is\n * tied to the component (and the `url`/`enabled` dependencies); the stream\n * closes on unmount.\n *\n * @example\n * useEventStream<Notification>(`${API}/notifications/stream`, {\n * enabled: !!user,\n * withCredentials: true,\n * onMessage: ({ data }) => addNotification(data),\n * });\n */\nexport function useEventStream<T = unknown>(\n url: string,\n options: UseEventStreamOptions<T> = {},\n): UseEventStreamResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<EventStreamStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<EventStreamMessage<T> | null>(null);\n const reconnectRef = useRef<(() => void) | null>(null);\n\n const onMessageRef = useLatestRef(onMessage);\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createEventStream<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n reconnectRef.current = controller.reconnect;\n\n return () => {\n controller.close();\n reconnectRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n return {\n status,\n lastMessage,\n reconnect: () => reconnectRef.current?.(),\n };\n}\n"],"mappings":";;;;AAqCA,SAAgB,EACZ,GACA,IAAoC,CAAC,GACd;CACvB,IAAM,EAAE,aAAU,IAAM,cAAW,GAAG,MAAS,GACzC,CAAC,GAAQ,KAAa,EAA4B,MAAM,GACxD,CAAC,GAAa,KAAkB,EAAuC,IAAI,GAC3E,IAAe,EAA4B,IAAI,GAE/C,IAAe,EAAa,CAAS;CAyB3C,OAvBA,QAAgB;EACZ,IAAI,CAAC,KAAW,CAAC,GAAK;GAClB,EAAU,MAAM;GAChB;EACJ;EAEA,IAAM,IAAa,EAAqB,GAAK;GACzC,GAAG;GACH,gBAAgB;GAChB,YAAY,MAAY;IAEpB,AADA,EAAe,CAAO,GACtB,EAAa,UAAU,CAAO;GAClC;EACJ,CAAC;EAGD,OAFA,EAAa,UAAU,EAAW,iBAErB;GAET,AADA,EAAW,MAAM,GACjB,EAAa,UAAU;EAC3B;CAEJ,GAAG,CAAC,GAAK,CAAO,CAAC,GAEV;EACH;EACA;EACA,iBAAiB,EAAa,UAAU;CAC5C;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./cache.cjs"),
|
|
1
|
+
const e=require("../hooks/use-latest-ref.cjs"),t=require("./cache.cjs"),n=require("./predictor.cjs");let r=require("react");function i(i,a={}){let[o,s]=(0,r.useState)(null),[c,l]=(0,r.useState)(`idle`),[u,d]=(0,r.useState)(null),[f,p]=(0,r.useState)(0),m=e.useLatestRef(a);(0,r.useEffect)(()=>{if(i===null){l(`idle`);return}let e=!1,r=null;return l(`loading`),d(null),(async()=>{try{let a=m.current,o=a.cache??!0,c=typeof i==`string`&&o!==!1?await t.fetchModelBytes(i,typeof o==`object`?o:{}):i,u=await n.TabularPredictor.create(c,{providers:a.providers,warmup:a.warmup,sessionOptions:a.sessionOptions});if(r=u,e){await u.dispose();return}s(u),l(`ready`)}catch(t){if(e)return;s(null),d(t instanceof Error?t:Error(String(t))),l(`error`)}})(),()=>{e=!0,s(null),r?.dispose()}},[i,f,m]);let h=(0,r.useCallback)(async e=>{if(o===null)throw Error("predict() was called before the model finished loading. Gate on `isReady`.");return await o.predict(e)},[o]),g=(0,r.useCallback)(()=>p(e=>e+1),[]);return{predictor:o,status:c,error:u,isReady:c===`ready`&&o!==null,predict:h,reload:g}}exports.useTabularPredictor=i;
|
|
2
2
|
//# sourceMappingURL=use-tabular-predictor.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tabular-predictor.cjs","names":[],"sources":["../../src/tabular/use-tabular-predictor.ts"],"sourcesContent":["/**\n * React binding for {@link TabularPredictor}.\n *\n * Loading a model is async, cancellable, and has to be undone on unmount —\n * three things every component that touches inference gets wrong the same\n * way. The hook owns that lifecycle so a component only deals with\n * `status` and `predict`.\n */\n\nimport { useCallback, useEffect,
|
|
1
|
+
{"version":3,"file":"use-tabular-predictor.cjs","names":[],"sources":["../../src/tabular/use-tabular-predictor.ts"],"sourcesContent":["/**\n * React binding for {@link TabularPredictor}.\n *\n * Loading a model is async, cancellable, and has to be undone on unmount —\n * three things every component that touches inference gets wrong the same\n * way. The hook owns that lifecycle so a component only deals with\n * `status` and `predict`.\n */\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\n\nimport { fetchModelBytes, type ModelCacheOptions } from \"./cache\";\nimport { TabularPredictor } from \"./predictor\";\nimport type {\n FeatureRow,\n TabularModelSource,\n TabularPrediction,\n TabularPredictorOptions,\n} from \"./types\";\n\n/** Lifecycle of the model behind the hook. */\nexport type TabularPredictorStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Options for {@link useTabularPredictor}. */\nexport interface UseTabularPredictorOptions extends TabularPredictorOptions {\n /**\n * Cache the model bytes on the device, so later loads work offline.\n *\n * On by default when the source is a URL: an app that runs inference in\n * the browser almost always wants it to keep working without a network,\n * and the failure mode of not caching only shows up in a tunnel.\n */\n readonly cache?: boolean | ModelCacheOptions;\n}\n\n/** What {@link useTabularPredictor} returns. */\nexport interface UseTabularPredictorResult {\n /** The loaded predictor, or `null` while loading or on error. */\n readonly predictor: TabularPredictor | null;\n /** Where the load is. */\n readonly status: TabularPredictorStatus;\n /** Why the load failed. */\n readonly error: Error | null;\n /** Whether the model is loaded and can answer. */\n readonly isReady: boolean;\n /**\n * Predict for a batch of rows.\n *\n * @throws When called before the model is ready — awaiting `isReady`\n * is the caller's job, and a silent empty result would hide the bug.\n */\n readonly predict: (rows: readonly FeatureRow[]) => Promise<TabularPrediction>;\n /** Load the model again, e.g. after a failure or a new version. */\n readonly reload: () => void;\n}\n\n/**\n * Load a tabular model and keep it for the component's lifetime.\n *\n * @example\n * ```tsx\n * function RiskWidget() {\n * const { predict, isReady } = useTabularPredictor(\"/models/risk-v3.onnx\");\n * const [score, setScore] = useState<number | null>(null);\n *\n * async function onSubmit(features: number[]) {\n * const { probabilities } = await predict([features]);\n * setScore(probabilities[0]?.[1] ?? null);\n * }\n *\n * return <button disabled={!isReady} onClick={() => onSubmit([1, 2, 3, 4])}>Score</button>;\n * }\n * ```\n *\n * @param source Model URL, or the bytes when the app already has them.\n * Pass `null` to hold off loading (a gate, a lazy tab).\n * @param options Predictor options plus caching.\n * @returns The predictor, its status, and a `predict` bound to it.\n */\nexport function useTabularPredictor(\n source: TabularModelSource | null,\n options: UseTabularPredictorOptions = {},\n): UseTabularPredictorResult {\n const [predictor, setPredictor] = useState<TabularPredictor | null>(null);\n const [status, setStatus] = useState<TabularPredictorStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [attempt, setAttempt] = useState(0);\n\n const optionsRef = useLatestRef(options);\n\n useEffect(() => {\n if (source === null) {\n setStatus(\"idle\");\n return;\n }\n\n let cancelled = false;\n let loaded: TabularPredictor | null = null;\n\n setStatus(\"loading\");\n setError(null);\n\n void (async () => {\n try {\n const current = optionsRef.current;\n const cache = current.cache ?? true;\n const bytes =\n typeof source === \"string\" && cache !== false\n ? await fetchModelBytes(source, typeof cache === \"object\" ? cache : {})\n : source;\n const created = await TabularPredictor.create(bytes, {\n providers: current.providers,\n warmup: current.warmup,\n sessionOptions: current.sessionOptions,\n });\n loaded = created;\n if (cancelled) {\n await created.dispose();\n return;\n }\n setPredictor(created);\n setStatus(\"ready\");\n } catch (caught) {\n if (cancelled) return;\n setPredictor(null);\n setError(caught instanceof Error ? caught : new Error(String(caught)));\n setStatus(\"error\");\n }\n })();\n\n return () => {\n cancelled = true;\n setPredictor(null);\n void loaded?.dispose();\n };\n }, [source, attempt, optionsRef]);\n\n const predict = useCallback(\n async (rows: readonly FeatureRow[]): Promise<TabularPrediction> => {\n if (predictor === null) {\n throw new Error(\n \"predict() was called before the model finished loading. \" +\n \"Gate on `isReady`.\",\n );\n }\n return await predictor.predict(rows);\n },\n [predictor],\n );\n\n const reload = useCallback(() => setAttempt((value) => value + 1), []);\n\n return {\n predictor,\n status,\n error,\n isReady: status === \"ready\" && predictor !== null,\n predict,\n reload,\n };\n}\n"],"mappings":"4HAgFA,SAAgB,EACZ,EACA,EAAsC,CAAC,EACd,CACzB,GAAM,CAAC,EAAW,IAAA,EAAgB,EAAA,SAAA,CAAkC,IAAI,EAClE,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAAiC,MAAM,EAC7D,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAuB,IAAI,EAC/C,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAS,CAAC,EAElC,EAAa,EAAA,aAAa,CAAO,GAEvC,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,IAAW,KAAM,CACjB,EAAU,MAAM,EAChB,MACJ,CAEA,IAAI,EAAY,GACZ,EAAkC,KAiCtC,OA/BA,EAAU,SAAS,EACnB,EAAS,IAAI,GAEP,SAAY,CACd,GAAI,CACA,IAAM,EAAU,EAAW,QACrB,EAAQ,EAAQ,OAAS,GACzB,EACF,OAAO,GAAW,UAAY,IAAU,GAClC,MAAM,EAAA,gBAAgB,EAAQ,OAAO,GAAU,SAAW,EAAQ,CAAC,CAAC,EACpE,EACJ,EAAU,MAAM,EAAA,iBAAiB,OAAO,EAAO,CACjD,UAAW,EAAQ,UACnB,OAAQ,EAAQ,OAChB,eAAgB,EAAQ,cAC5B,CAAC,EAED,GADA,EAAS,EACL,EAAW,CACX,MAAM,EAAQ,QAAQ,EACtB,MACJ,CACA,EAAa,CAAO,EACpB,EAAU,OAAO,CACrB,OAAS,EAAQ,CACb,GAAI,EAAW,OACf,EAAa,IAAI,EACjB,EAAS,aAAkB,MAAQ,EAAa,MAAM,OAAO,CAAM,CAAC,CAAC,EACrE,EAAU,OAAO,CACrB,CACJ,EAAA,CAAG,MAEU,CACT,EAAY,GACZ,EAAa,IAAI,EACjB,GAAa,QAAQ,CACzB,CACJ,EAAG,CAAC,EAAQ,EAAS,CAAU,CAAC,EAEhC,IAAM,GAAA,EAAU,EAAA,YAAA,CACZ,KAAO,IAA4D,CAC/D,GAAI,IAAc,KACd,MAAU,MACN,4EAEJ,EAEJ,OAAO,MAAM,EAAU,QAAQ,CAAI,CACvC,EACA,CAAC,CAAS,CACd,EAEM,GAAA,EAAS,EAAA,YAAA,KAAkB,EAAY,GAAU,EAAQ,CAAC,EAAG,CAAC,CAAC,EAErE,MAAO,CACH,YACA,SACA,QACA,QAAS,IAAW,SAAW,IAAc,KAC7C,UACA,QACJ,CACJ"}
|
|
@@ -1,41 +1,44 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "../hooks/use-latest-ref.js";
|
|
2
|
+
import { fetchModelBytes as t } from "./cache.js";
|
|
3
|
+
import { TabularPredictor as n } from "./predictor.js";
|
|
4
|
+
import { useCallback as r, useEffect as i, useState as a } from "react";
|
|
4
5
|
//#region src/tabular/use-tabular-predictor.ts
|
|
5
6
|
function o(o, s = {}) {
|
|
6
|
-
let [c, l] = a(null), [u, d] = a("idle"), [f, p] = a(null), [m, h] = a(0), g =
|
|
7
|
-
|
|
8
|
-
g.current = s;
|
|
9
|
-
}), r(() => {
|
|
7
|
+
let [c, l] = a(null), [u, d] = a("idle"), [f, p] = a(null), [m, h] = a(0), g = e(s);
|
|
8
|
+
i(() => {
|
|
10
9
|
if (o === null) {
|
|
11
10
|
d("idle");
|
|
12
11
|
return;
|
|
13
12
|
}
|
|
14
|
-
let
|
|
13
|
+
let e = !1, r = null;
|
|
15
14
|
return d("loading"), p(null), (async () => {
|
|
16
15
|
try {
|
|
17
|
-
let i = g.current, a = i.cache ?? !0, s = typeof o == "string" && a !== !1 ? await
|
|
16
|
+
let i = g.current, a = i.cache ?? !0, s = typeof o == "string" && a !== !1 ? await t(o, typeof a == "object" ? a : {}) : o, c = await n.create(s, {
|
|
18
17
|
providers: i.providers,
|
|
19
18
|
warmup: i.warmup,
|
|
20
19
|
sessionOptions: i.sessionOptions
|
|
21
20
|
});
|
|
22
|
-
if (r = c,
|
|
21
|
+
if (r = c, e) {
|
|
23
22
|
await c.dispose();
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
26
25
|
l(c), d("ready");
|
|
27
|
-
} catch (
|
|
28
|
-
if (
|
|
29
|
-
l(null), p(
|
|
26
|
+
} catch (t) {
|
|
27
|
+
if (e) return;
|
|
28
|
+
l(null), p(t instanceof Error ? t : Error(String(t))), d("error");
|
|
30
29
|
}
|
|
31
30
|
})(), () => {
|
|
32
|
-
|
|
31
|
+
e = !0, l(null), r?.dispose();
|
|
33
32
|
};
|
|
34
|
-
}, [
|
|
35
|
-
|
|
33
|
+
}, [
|
|
34
|
+
o,
|
|
35
|
+
m,
|
|
36
|
+
g
|
|
37
|
+
]);
|
|
38
|
+
let _ = r(async (e) => {
|
|
36
39
|
if (c === null) throw Error("predict() was called before the model finished loading. Gate on `isReady`.");
|
|
37
40
|
return await c.predict(e);
|
|
38
|
-
}, [c]), v =
|
|
41
|
+
}, [c]), v = r(() => h((e) => e + 1), []);
|
|
39
42
|
return {
|
|
40
43
|
predictor: c,
|
|
41
44
|
status: u,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tabular-predictor.js","names":[],"sources":["../../src/tabular/use-tabular-predictor.ts"],"sourcesContent":["/**\n * React binding for {@link TabularPredictor}.\n *\n * Loading a model is async, cancellable, and has to be undone on unmount —\n * three things every component that touches inference gets wrong the same\n * way. The hook owns that lifecycle so a component only deals with\n * `status` and `predict`.\n */\n\nimport { useCallback, useEffect,
|
|
1
|
+
{"version":3,"file":"use-tabular-predictor.js","names":[],"sources":["../../src/tabular/use-tabular-predictor.ts"],"sourcesContent":["/**\n * React binding for {@link TabularPredictor}.\n *\n * Loading a model is async, cancellable, and has to be undone on unmount —\n * three things every component that touches inference gets wrong the same\n * way. The hook owns that lifecycle so a component only deals with\n * `status` and `predict`.\n */\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\n\nimport { fetchModelBytes, type ModelCacheOptions } from \"./cache\";\nimport { TabularPredictor } from \"./predictor\";\nimport type {\n FeatureRow,\n TabularModelSource,\n TabularPrediction,\n TabularPredictorOptions,\n} from \"./types\";\n\n/** Lifecycle of the model behind the hook. */\nexport type TabularPredictorStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Options for {@link useTabularPredictor}. */\nexport interface UseTabularPredictorOptions extends TabularPredictorOptions {\n /**\n * Cache the model bytes on the device, so later loads work offline.\n *\n * On by default when the source is a URL: an app that runs inference in\n * the browser almost always wants it to keep working without a network,\n * and the failure mode of not caching only shows up in a tunnel.\n */\n readonly cache?: boolean | ModelCacheOptions;\n}\n\n/** What {@link useTabularPredictor} returns. */\nexport interface UseTabularPredictorResult {\n /** The loaded predictor, or `null` while loading or on error. */\n readonly predictor: TabularPredictor | null;\n /** Where the load is. */\n readonly status: TabularPredictorStatus;\n /** Why the load failed. */\n readonly error: Error | null;\n /** Whether the model is loaded and can answer. */\n readonly isReady: boolean;\n /**\n * Predict for a batch of rows.\n *\n * @throws When called before the model is ready — awaiting `isReady`\n * is the caller's job, and a silent empty result would hide the bug.\n */\n readonly predict: (rows: readonly FeatureRow[]) => Promise<TabularPrediction>;\n /** Load the model again, e.g. after a failure or a new version. */\n readonly reload: () => void;\n}\n\n/**\n * Load a tabular model and keep it for the component's lifetime.\n *\n * @example\n * ```tsx\n * function RiskWidget() {\n * const { predict, isReady } = useTabularPredictor(\"/models/risk-v3.onnx\");\n * const [score, setScore] = useState<number | null>(null);\n *\n * async function onSubmit(features: number[]) {\n * const { probabilities } = await predict([features]);\n * setScore(probabilities[0]?.[1] ?? null);\n * }\n *\n * return <button disabled={!isReady} onClick={() => onSubmit([1, 2, 3, 4])}>Score</button>;\n * }\n * ```\n *\n * @param source Model URL, or the bytes when the app already has them.\n * Pass `null` to hold off loading (a gate, a lazy tab).\n * @param options Predictor options plus caching.\n * @returns The predictor, its status, and a `predict` bound to it.\n */\nexport function useTabularPredictor(\n source: TabularModelSource | null,\n options: UseTabularPredictorOptions = {},\n): UseTabularPredictorResult {\n const [predictor, setPredictor] = useState<TabularPredictor | null>(null);\n const [status, setStatus] = useState<TabularPredictorStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [attempt, setAttempt] = useState(0);\n\n const optionsRef = useLatestRef(options);\n\n useEffect(() => {\n if (source === null) {\n setStatus(\"idle\");\n return;\n }\n\n let cancelled = false;\n let loaded: TabularPredictor | null = null;\n\n setStatus(\"loading\");\n setError(null);\n\n void (async () => {\n try {\n const current = optionsRef.current;\n const cache = current.cache ?? true;\n const bytes =\n typeof source === \"string\" && cache !== false\n ? await fetchModelBytes(source, typeof cache === \"object\" ? cache : {})\n : source;\n const created = await TabularPredictor.create(bytes, {\n providers: current.providers,\n warmup: current.warmup,\n sessionOptions: current.sessionOptions,\n });\n loaded = created;\n if (cancelled) {\n await created.dispose();\n return;\n }\n setPredictor(created);\n setStatus(\"ready\");\n } catch (caught) {\n if (cancelled) return;\n setPredictor(null);\n setError(caught instanceof Error ? caught : new Error(String(caught)));\n setStatus(\"error\");\n }\n })();\n\n return () => {\n cancelled = true;\n setPredictor(null);\n void loaded?.dispose();\n };\n }, [source, attempt, optionsRef]);\n\n const predict = useCallback(\n async (rows: readonly FeatureRow[]): Promise<TabularPrediction> => {\n if (predictor === null) {\n throw new Error(\n \"predict() was called before the model finished loading. \" +\n \"Gate on `isReady`.\",\n );\n }\n return await predictor.predict(rows);\n },\n [predictor],\n );\n\n const reload = useCallback(() => setAttempt((value) => value + 1), []);\n\n return {\n predictor,\n status,\n error,\n isReady: status === \"ready\" && predictor !== null,\n predict,\n reload,\n };\n}\n"],"mappings":";;;;;AAgFA,SAAgB,EACZ,GACA,IAAsC,CAAC,GACd;CACzB,IAAM,CAAC,GAAW,KAAgB,EAAkC,IAAI,GAClE,CAAC,GAAQ,KAAa,EAAiC,MAAM,GAC7D,CAAC,GAAO,KAAY,EAAuB,IAAI,GAC/C,CAAC,GAAS,KAAc,EAAS,CAAC,GAElC,IAAa,EAAa,CAAO;CAEvC,QAAgB;EACZ,IAAI,MAAW,MAAM;GACjB,EAAU,MAAM;GAChB;EACJ;EAEA,IAAI,IAAY,IACZ,IAAkC;EAiCtC,OA/BA,EAAU,SAAS,GACnB,EAAS,IAAI,IAEP,YAAY;GACd,IAAI;IACA,IAAM,IAAU,EAAW,SACrB,IAAQ,EAAQ,SAAS,IACzB,IACF,OAAO,KAAW,YAAY,MAAU,KAClC,MAAM,EAAgB,GAAQ,OAAO,KAAU,WAAW,IAAQ,CAAC,CAAC,IACpE,GACJ,IAAU,MAAM,EAAiB,OAAO,GAAO;KACjD,WAAW,EAAQ;KACnB,QAAQ,EAAQ;KAChB,gBAAgB,EAAQ;IAC5B,CAAC;IAED,IADA,IAAS,GACL,GAAW;KACX,MAAM,EAAQ,QAAQ;KACtB;IACJ;IAEA,AADA,EAAa,CAAO,GACpB,EAAU,OAAO;GACrB,SAAS,GAAQ;IACb,IAAI,GAAW;IAGf,AAFA,EAAa,IAAI,GACjB,EAAS,aAAkB,QAAQ,IAAa,MAAM,OAAO,CAAM,CAAC,CAAC,GACrE,EAAU,OAAO;GACrB;EACJ,EAAA,CAAG,SAEU;GAGT,AAFA,IAAY,IACZ,EAAa,IAAI,GACjB,GAAa,QAAQ;EACzB;CACJ,GAAG;EAAC;EAAQ;EAAS;CAAU,CAAC;CAEhC,IAAM,IAAU,EACZ,OAAO,MAA4D;EAC/D,IAAI,MAAc,MACd,MAAU,MACN,4EAEJ;EAEJ,OAAO,MAAM,EAAU,QAAQ,CAAI;CACvC,GACA,CAAC,CAAS,CACd,GAEM,IAAS,QAAkB,GAAY,MAAU,IAAQ,CAAC,GAAG,CAAC,CAAC;CAErE,OAAO;EACH;EACA;EACA;EACA,SAAS,MAAW,WAAW,MAAc;EAC7C;EACA;CACJ;AACJ"}
|