@w6w/react 0.9.12 → 0.9.13
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 +34 -17
- package/dist/mod.d.ts +1 -0
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -0
- package/dist/mod.js.map +1 -1
- package/dist/src/W6WProvider.d.ts +27 -4
- package/dist/src/W6WProvider.d.ts.map +1 -1
- package/dist/src/W6WProvider.js +39 -6
- package/dist/src/W6WProvider.js.map +1 -1
- package/dist/src/session.d.ts +51 -0
- package/dist/src/session.d.ts.map +1 -0
- package/dist/src/session.js +249 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ surface (`me`, `documents`, `vars`, `connections`, `workflows`, `functions`, `ru
|
|
|
6
6
|
`createW6WUiAdapter`, a structural bridge from a `W6WClient` to
|
|
7
7
|
[`@w6w/ui`](https://github.com/w6w-io/w6w-ui)'s `W6WApi` contract.
|
|
8
8
|
|
|
9
|
-
License: MIT · Version: 0.9.
|
|
9
|
+
License: MIT · Version: 0.9.13 · Guides: [docs.w6w.io/clients/react](https://docs.w6w.io/clients/react/)
|
|
10
10
|
(with a [hooks reference](https://docs.w6w.io/clients/react/hooks/) and a
|
|
11
11
|
[Next.js walkthrough](https://docs.w6w.io/clients/react/nextjs/))
|
|
12
12
|
|
|
@@ -22,7 +22,7 @@ npm install @w6w/react react
|
|
|
22
22
|
|
|
23
23
|
`@w6w/sdk` comes in as a dependency. Add it to your own `package.json` too
|
|
24
24
|
(`npm install @w6w/sdk`) if you import from it directly — `ApiError` for an
|
|
25
|
-
`instanceof` check, or `
|
|
25
|
+
`instanceof` check, or `createEmbedSessionClient` from `@w6w/sdk/server` on your backend.
|
|
26
26
|
|
|
27
27
|
`react-dom` is not a dependency of this package — `<W6WProvider>`'s only JSX is a
|
|
28
28
|
context wrapper (`<Ctx.Provider>`), never a DOM element of its own. Your app already
|
|
@@ -76,7 +76,23 @@ function DocList() {
|
|
|
76
76
|
|
|
77
77
|
A host juggling more than one signed-in identity — or one that does not have a
|
|
78
78
|
token/identity yet at mount time — needs more than the Quick start's one-shot
|
|
79
|
-
`token` prop. `<W6WProvider>` takes
|
|
79
|
+
`token` prop. `<W6WProvider>` takes more props for exactly this:
|
|
80
|
+
|
|
81
|
+
- **`getSession`** (with **`renewBeforeMs`**, default `30000`) — instead of `token`,
|
|
82
|
+
one `() => Promise<{token, expiresAt, expiresIn?}>` callback that calls your
|
|
83
|
+
backend's session endpoint. The provider calls it lazily and one call at a time,
|
|
84
|
+
caches the session, renews it before expiry (never later than half the
|
|
85
|
+
session's lifetime) and re-checks when a hidden tab becomes visible; you write
|
|
86
|
+
no cache or timer. Pass exactly one of `token` or `getSession` (both, or
|
|
87
|
+
neither, throws). Needs 0.9.13 or later. `useW6WSession()` returns
|
|
88
|
+
`{status, expiresAt, error, refresh}`, where `status` is `"loading"`, `"ready"`,
|
|
89
|
+
`"renewing"`, `"expired"` or `"error"`. Keep the identity switch in
|
|
90
|
+
`identityKey` (it must change when the user or account behind `getSession`
|
|
91
|
+
does). Place the provider above any `<Suspense>` boundary that can re-suspend: one
|
|
92
|
+
above or around it detaches the store, and reads error with "disposed" until it
|
|
93
|
+
re-shows. A mutation in flight at an identity switch is not cancelled, keeps the
|
|
94
|
+
old client's request and token, still lands its result in the hook's state, and
|
|
95
|
+
that state is not reset (unchanged).
|
|
80
96
|
|
|
81
97
|
- **`ready`** (default `true`) — set it `false` until you actually have a
|
|
82
98
|
token/identity to embed with. While `false`, every read hook reports
|
|
@@ -105,26 +121,24 @@ token/identity yet at mount time — needs more than the Quick start's one-shot
|
|
|
105
121
|
|
|
106
122
|
import { W6WProvider } from "@w6w/react";
|
|
107
123
|
|
|
124
|
+
// Your own backend route: it holds the tenant credentials and answers with a
|
|
125
|
+
// session ({ token, expiresAt, ... }) for this signed-in user, built with
|
|
126
|
+
// `createEmbedSessionClient` from `@w6w/sdk/server`.
|
|
127
|
+
async function getSession() {
|
|
128
|
+
const res = await fetch("/api/w6w-session", { method: "POST" });
|
|
129
|
+
if (!res.ok) throw new Error(`session route answered ${res.status}`);
|
|
130
|
+
return res.json();
|
|
131
|
+
}
|
|
132
|
+
|
|
108
133
|
export default function W6WLayout({ children }: { children: React.ReactNode }) {
|
|
109
134
|
return (
|
|
110
135
|
<W6WProvider
|
|
111
136
|
baseUrl="https://api.example.com"
|
|
112
|
-
|
|
137
|
+
getSession={getSession}
|
|
113
138
|
identityKey={`${session.subject}:${session.account}`}
|
|
114
139
|
headers={{ "X-W6W-Tenant": session.tenantId }}
|
|
115
140
|
refreshOnUnauthorized
|
|
116
141
|
onUnauthorized={() => redirectToLogin()}
|
|
117
|
-
token={async () => {
|
|
118
|
-
// Your own backend route, not w6w's — it holds whatever credential
|
|
119
|
-
// mints a w6w token for this signed-in user (a tenant exchange, a
|
|
120
|
-
// cached short-lived token, …). This is a Next.js App Router layout,
|
|
121
|
-
// so it is a Client Component ("use client" above) even though the
|
|
122
|
-
// token-minting route itself runs on your server.
|
|
123
|
-
const res = await fetch("/api/w6w-token");
|
|
124
|
-
if (!res.ok) return null;
|
|
125
|
-
const { token } = await res.json();
|
|
126
|
-
return token;
|
|
127
|
-
}}
|
|
128
142
|
>
|
|
129
143
|
{children}
|
|
130
144
|
</W6WProvider>
|
|
@@ -133,8 +147,7 @@ export default function W6WLayout({ children }: { children: React.ReactNode }) {
|
|
|
133
147
|
```
|
|
134
148
|
|
|
135
149
|
The [Next.js walkthrough](https://docs.w6w.io/clients/react/nextjs/) builds the
|
|
136
|
-
`/api/w6w-
|
|
137
|
-
cached, refreshable token supplier.
|
|
150
|
+
`/api/w6w-session` route this example fetches from, with `createEmbedSessionClient`.
|
|
138
151
|
|
|
139
152
|
## Using this package with `@w6w/ui`
|
|
140
153
|
|
|
@@ -199,6 +212,10 @@ To update the pin, change the npm version in `package.json`, refresh
|
|
|
199
212
|
`package-lock.json`, and run `npm test` and `npm run build`. These checks report
|
|
200
213
|
any incompatible UI contract changes.
|
|
201
214
|
|
|
215
|
+
On Node older than 22.18, run the local gate as
|
|
216
|
+
`NODE_OPTIONS=--experimental-strip-types npm test` (the tests load `.ts` files directly;
|
|
217
|
+
CI uses Node 24).
|
|
218
|
+
|
|
202
219
|
**Runtime conformance.** Assignability is checked at compile time only, so it cannot
|
|
203
220
|
see a member that is typed but missing or mis-wired at run time.
|
|
204
221
|
`src/__tests__/adapter-conformance.test.ts` closes that gap. It reads the member names
|
package/dist/mod.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
export { VERSION } from "./src/version.ts";
|
|
16
16
|
export { type TokenSource, useW6WClient, W6WProvider, type W6WProviderProps, } from "./src/W6WProvider.tsx";
|
|
17
|
+
export { useW6WSession, type W6WSession, type W6WSessionState, type W6WSessionStatus, } from "./src/session.ts";
|
|
17
18
|
export { type MutationResult, type ReadResult, useArchiveWorkflow, useConnections, useCreateDocument, useCreateFunction, useCreateVar, useCreateWorkflow, useDeleteDocument, useDeleteFunction, useDeleteVar, useDeleteWorkflow, useDocument, useDocumentByKey, useDocuments, useFunction, useFunctions, useMe, useRun, useRunWorkflow, useUpdateDocument, useUpdateFunction, useUpdateVar, useUpdateWorkflow, useVar, useVars, useWorkflow, useWorkflows, } from "./src/hooks.ts";
|
|
18
19
|
export { createW6WUiAdapter, type W6WApi } from "./src/adapter.ts";
|
|
19
20
|
export { type FlowEdgeShape, type FlowStepShape, type FlowWorkflowShape, fromFlowWorkflow, toFlowWorkflow, WorkflowShapeError, type WorkflowShapeIssue, } from "./src/flow-workflow.ts";
|
package/dist/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EACL,KAAK,WAAW,EAChB,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,OAAO,EACP,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EACL,KAAK,WAAW,EAChB,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,aAAa,EACb,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,OAAO,EACP,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC"}
|
package/dist/mod.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export { VERSION } from "./src/version.js";
|
|
17
17
|
export { useW6WClient, W6WProvider, } from "./src/W6WProvider.js";
|
|
18
|
+
export { useW6WSession, } from "./src/session.js";
|
|
18
19
|
export { useArchiveWorkflow, useConnections, useCreateDocument, useCreateFunction, useCreateVar, useCreateWorkflow, useDeleteDocument, useDeleteFunction, useDeleteVar, useDeleteWorkflow, useDocument, useDocumentByKey, useDocuments, useFunction, useFunctions, useMe, useRun, useRunWorkflow, useUpdateDocument, useUpdateFunction, useUpdateVar, useUpdateWorkflow, useVar, useVars, useWorkflow, useWorkflows, } from "./src/hooks.js";
|
|
19
20
|
export { createW6WUiAdapter } from "./src/adapter.js";
|
|
20
21
|
export { fromFlowWorkflow, toFlowWorkflow, WorkflowShapeError, } from "./src/flow-workflow.js";
|
package/dist/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAEL,YAAY,EACZ,WAAW,GAEZ,MAAM,sBAAuB,CAAC;AAE/B,OAAO,EAGL,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,OAAO,EACP,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAe,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAIL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GAEnB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAEL,YAAY,EACZ,WAAW,GAEZ,MAAM,sBAAuB,CAAC;AAE/B,OAAO,EACL,aAAa,GAId,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAGL,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,OAAO,EACP,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAe,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAIL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GAEnB,MAAM,wBAAwB,CAAC"}
|
|
@@ -39,13 +39,34 @@
|
|
|
39
39
|
*/
|
|
40
40
|
import { type ApiError, type FetchLike, type TokenProvider, W6WClient } from "@w6w/sdk";
|
|
41
41
|
import { type ReactNode } from "react";
|
|
42
|
+
import { SessionStore, type W6WSession } from "./session.ts";
|
|
42
43
|
/** A static bearer token, or a supplier called per request (concurrent requests share one call). */
|
|
43
44
|
export type TokenSource = string | TokenProvider;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Exactly one credential source: a `token` (string, or a supplier called per
|
|
47
|
+
* request) OR a `getSession` callback whose session the provider caches,
|
|
48
|
+
* renews before expiry and re-checks on tab resume (see `useW6WSession`).
|
|
49
|
+
*/
|
|
50
|
+
export type W6WCredentialProps = {
|
|
47
51
|
/** A literal bearer token, or a supplier called per request (concurrent requests share one call). */
|
|
48
52
|
token: TokenSource;
|
|
53
|
+
getSession?: never;
|
|
54
|
+
renewBeforeMs?: never;
|
|
55
|
+
} | {
|
|
56
|
+
token?: never;
|
|
57
|
+
/**
|
|
58
|
+
* Mints a session (`{token, expiresAt, expiresIn?}`). Called lazily, at
|
|
59
|
+
* most once at a time; the result is cached until `renewBeforeMs` (capped
|
|
60
|
+
* at half the session's lifetime) before it expires. Always the LATEST
|
|
61
|
+
* callback, read through a ref.
|
|
62
|
+
*/
|
|
63
|
+
getSession: () => Promise<W6WSession>;
|
|
64
|
+
/** Renew this long before expiry. Default `30_000`. */
|
|
65
|
+
renewBeforeMs?: number;
|
|
66
|
+
};
|
|
67
|
+
export type W6WProviderProps = {
|
|
68
|
+
/** The w6w server's origin, e.g. `"https://api.example.com"`. */
|
|
69
|
+
baseUrl: string;
|
|
49
70
|
/**
|
|
50
71
|
* The real transport this provider's stable `fetch` wrapper delegates to.
|
|
51
72
|
* Defaults to `globalThis.fetch`. Mainly for tests — a caller wanting to
|
|
@@ -89,9 +110,11 @@ export interface W6WProviderProps {
|
|
|
89
110
|
*/
|
|
90
111
|
onUnauthorized?: (error: ApiError) => void;
|
|
91
112
|
children: ReactNode;
|
|
92
|
-
}
|
|
113
|
+
} & W6WCredentialProps;
|
|
93
114
|
interface W6WContextValue {
|
|
94
115
|
client: W6WClient;
|
|
116
|
+
/** The `getSession` store, or `null` for a `token` provider. Read by `useW6WSession`. */
|
|
117
|
+
session: SessionStore | null;
|
|
95
118
|
/** Mirrors the `ready` prop. Read by `hooks.ts`'s `useAsync`, never by `useW6WClient`. */
|
|
96
119
|
ready: boolean;
|
|
97
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"W6WProvider.d.ts","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"W6WProvider.d.ts","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACxF,OAAO,EACL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AACf,OAAO,EAA2B,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtF,oGAAoG;AACpG,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IACE,qGAAqG;IACrG,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC;CACvB,GACD;IACE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;;;OAKG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC3C,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,kBAAkB,CAAC;AAEvB,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,yFAAyF;IACzF,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,0FAA0F;IAC1F,KAAK,EAAE,OAAO,CAAC;CAChB;AAeD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAiH9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,SAAS,CASxC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CASvD"}
|
package/dist/src/W6WProvider.js
CHANGED
|
@@ -39,7 +39,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
39
39
|
* @module
|
|
40
40
|
*/
|
|
41
41
|
import { W6WClient } from "@w6w/sdk";
|
|
42
|
-
import { createContext, useContext, useMemo, useRef } from "react";
|
|
42
|
+
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, } from "react";
|
|
43
|
+
import { DEFAULT_RENEW_BEFORE_MS, SessionStore } from "./session.js";
|
|
43
44
|
const Ctx = createContext(null);
|
|
44
45
|
/**
|
|
45
46
|
* Canonical encoding of a headers object for the `useMemo` dependency array —
|
|
@@ -57,7 +58,19 @@ function headersKey(headers) {
|
|
|
57
58
|
* memoization policy.
|
|
58
59
|
*/
|
|
59
60
|
export function W6WProvider(props) {
|
|
60
|
-
const { baseUrl, token, fetch: fetchOverride, project, headers, ready = true, identityKey, refreshOnUnauthorized, onUnauthorized, children, } = props;
|
|
61
|
+
const { baseUrl, token, getSession, renewBeforeMs, fetch: fetchOverride, project, headers, ready = true, identityKey, refreshOnUnauthorized, onUnauthorized, children, } = props;
|
|
62
|
+
const hasToken = token !== undefined && token !== null;
|
|
63
|
+
const hasSession = getSession !== undefined && getSession !== null;
|
|
64
|
+
// An explicit-but-undefined `token` (`token={maybeToken}` while signed out)
|
|
65
|
+
// behaves exactly as before this prop pair existed: legacy token mode, the
|
|
66
|
+
// SDK rejects the blank value per request. Only a provider with NEITHER key
|
|
67
|
+
// present is real misuse.
|
|
68
|
+
const legacyUndefinedToken = !hasToken && !hasSession && "token" in props && !("getSession" in props);
|
|
69
|
+
if (hasToken === hasSession && !legacyUndefinedToken) {
|
|
70
|
+
throw new Error(hasToken
|
|
71
|
+
? "<W6WProvider> takes exactly one of `token` or `getSession`, not both."
|
|
72
|
+
: "<W6WProvider> needs exactly one of `token` or `getSession`.");
|
|
73
|
+
}
|
|
61
74
|
// "Latest ref" pattern: kept in sync on every render, but never a `useMemo`
|
|
62
75
|
// dependency below — the stable wrappers constructed inside always read the
|
|
63
76
|
// CURRENT prop value through these, so a token rotation, a new `fetch`
|
|
@@ -70,6 +83,10 @@ export function W6WProvider(props) {
|
|
|
70
83
|
// the moment the memo recomputes.
|
|
71
84
|
const tokenRef = useRef(token);
|
|
72
85
|
tokenRef.current = token;
|
|
86
|
+
const getSessionRef = useRef(getSession);
|
|
87
|
+
getSessionRef.current = getSession;
|
|
88
|
+
const renewBeforeMsRef = useRef(renewBeforeMs);
|
|
89
|
+
renewBeforeMsRef.current = renewBeforeMs;
|
|
73
90
|
const fetchRef = useRef(fetchOverride);
|
|
74
91
|
fetchRef.current = fetchOverride;
|
|
75
92
|
const onUnauthorizedRef = useRef(onUnauthorized);
|
|
@@ -77,7 +94,7 @@ export function W6WProvider(props) {
|
|
|
77
94
|
const headersRef = useRef(headers);
|
|
78
95
|
headersRef.current = headers;
|
|
79
96
|
const headersSnapshot = headersKey(headers);
|
|
80
|
-
const client = useMemo(() => {
|
|
97
|
+
const { client, store } = useMemo(() => {
|
|
81
98
|
// `identityKey` and `headersSnapshot` are not otherwise read in this body
|
|
82
99
|
// — they exist purely so this memo depends on them (identity switch;
|
|
83
100
|
// headers content change, per this module's header). Referencing them
|
|
@@ -85,7 +102,17 @@ export function W6WProvider(props) {
|
|
|
85
102
|
// `useExhaustiveDependencies` from treating them as superfluous.
|
|
86
103
|
void identityKey;
|
|
87
104
|
void headersSnapshot;
|
|
105
|
+
// Born and killed with this memo (i.e. with `identityKey`); disposed by the
|
|
106
|
+
// effect below, never here (StrictMode double-invokes memo bodies).
|
|
107
|
+
const store = hasSession
|
|
108
|
+
? new SessionStore(() => {
|
|
109
|
+
const fn = getSessionRef.current;
|
|
110
|
+
return fn ? fn() : Promise.reject(new Error("getSession was removed"));
|
|
111
|
+
}, () => renewBeforeMsRef.current ?? DEFAULT_RENEW_BEFORE_MS)
|
|
112
|
+
: null;
|
|
88
113
|
const stableToken = (ctx) => {
|
|
114
|
+
if (store)
|
|
115
|
+
return store.supplier(ctx);
|
|
89
116
|
const current = tokenRef.current;
|
|
90
117
|
return typeof current === "function" ? current(ctx) : current;
|
|
91
118
|
};
|
|
@@ -96,7 +123,7 @@ export function W6WProvider(props) {
|
|
|
96
123
|
const stableOnUnauthorized = (error) => {
|
|
97
124
|
onUnauthorizedRef.current?.(error);
|
|
98
125
|
};
|
|
99
|
-
|
|
126
|
+
const client = new W6WClient({
|
|
100
127
|
baseUrl,
|
|
101
128
|
project,
|
|
102
129
|
token: stableToken,
|
|
@@ -105,8 +132,14 @@ export function W6WProvider(props) {
|
|
|
105
132
|
refreshOnUnauthorized,
|
|
106
133
|
onUnauthorized: stableOnUnauthorized,
|
|
107
134
|
});
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
return { client, store };
|
|
136
|
+
}, [baseUrl, project, identityKey, refreshOnUnauthorized, headersSnapshot, hasSession]);
|
|
137
|
+
// Listener/timer lifecycle + late-discard of the OLD store on identity change.
|
|
138
|
+
(typeof document === "undefined" ? useEffect : useLayoutEffect)(() => {
|
|
139
|
+
store?.attach();
|
|
140
|
+
return () => store?.detach();
|
|
141
|
+
}, [store]);
|
|
142
|
+
const value = useMemo(() => ({ client, ready, session: store }), [client, ready, store]);
|
|
110
143
|
return _jsx(Ctx.Provider, { value: value, children: children });
|
|
111
144
|
}
|
|
112
145
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"W6WProvider.js","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAqD,SAAS,EAAE,MAAM,UAAU,CAAC;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"W6WProvider.js","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** What `getSession` resolves to. A structural supertype of `@w6w/sdk/server`'s `EmbedSession`. */
|
|
2
|
+
export interface W6WSession {
|
|
3
|
+
token: string;
|
|
4
|
+
/** ISO-8601 instant the token stops being valid. */
|
|
5
|
+
expiresAt: string;
|
|
6
|
+
/** Seconds the token lives from receipt; bounds a far-future `expiresAt` (clock skew). */
|
|
7
|
+
expiresIn?: number;
|
|
8
|
+
}
|
|
9
|
+
export type W6WSessionStatus = "loading" | "ready" | "renewing" | "expired" | "error";
|
|
10
|
+
export interface W6WSessionState {
|
|
11
|
+
status: W6WSessionStatus;
|
|
12
|
+
/** The cached session's `expiresAt`, or `null` (no session yet, or a `token`-mode provider). */
|
|
13
|
+
expiresAt: string | null;
|
|
14
|
+
/** The last acquisition failure, until the next acquisition starts. */
|
|
15
|
+
error: unknown;
|
|
16
|
+
/** Starts (or joins) an acquisition. Resolves when it settles; never rejects — read `error`. */
|
|
17
|
+
refresh(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Default `renewBeforeMs`. */
|
|
20
|
+
export declare const DEFAULT_RENEW_BEFORE_MS = 30000;
|
|
21
|
+
export declare class SessionStore {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(getSession: () => Promise<W6WSession>, renewBeforeMs: () => number);
|
|
24
|
+
subscribe: (listener: () => void) => (() => void);
|
|
25
|
+
getSnapshot: () => W6WSessionState;
|
|
26
|
+
refresh: () => Promise<void>;
|
|
27
|
+
/** `forceRefresh` JOINS an acquisition already in flight, else starts exactly one. */
|
|
28
|
+
supplier: (ctx?: {
|
|
29
|
+
forceRefresh?: boolean;
|
|
30
|
+
}) => Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Called from the provider's effect. Disposal is DEFERRED one microtask (the
|
|
33
|
+
* same refcount idiom `hooks.ts` uses for its abort controller): React
|
|
34
|
+
* StrictMode runs mount -> cleanup -> mount synchronously, and descendants'
|
|
35
|
+
* passive effects (a read hook's first request) have already entered the
|
|
36
|
+
* supplier by the time the cleanup runs, so tearing the flight down at
|
|
37
|
+
* cleanup would reject that request ("stale acquisition"). A re-attach in
|
|
38
|
+
* the same task simply cancels the pending disposal; a real unmount or
|
|
39
|
+
* identity change disposes one microtask later.
|
|
40
|
+
*/
|
|
41
|
+
attach(): void;
|
|
42
|
+
detach(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The provider's session state. With a `getSession` provider it mirrors the
|
|
46
|
+
* store; with a `token` provider `status` is `"ready"` when the provider's
|
|
47
|
+
* `ready` is true (else `"loading"`), `expiresAt` is `null` and `refresh()`
|
|
48
|
+
* resolves without calling anything.
|
|
49
|
+
*/
|
|
50
|
+
export declare function useW6WSession(): W6WSessionState;
|
|
51
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAqBA,mGAAmG;AACnG,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,gGAAgG;IAChG,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,uEAAuE;IACvE,KAAK,EAAE,OAAO,CAAC;IACf,gGAAgG;IAChG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,+BAA+B;AAC/B,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAiB9C,qBAAa,YAAY;;gBAeX,UAAU,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,aAAa,EAAE,MAAM,MAAM;IAQ9E,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAK9C;IAEF,WAAW,QAAO,eAAe,CAAmB;IAEpD,OAAO,QAAa,OAAO,CAAC,IAAI,CAAC,CAG/B;IAIF,sFAAsF;IACtF,QAAQ,GAAU,MAAM;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,MAAM,CAAC,CAelE;IAIF;;;;;;;;;OASG;IACH,MAAM,IAAI,IAAI;IASd,MAAM,IAAI,IAAI;CAiIf;AAKD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,eAAe,CAgB/C"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The session store behind `<W6WProvider getSession>` and `useW6WSession()`.
|
|
3
|
+
*
|
|
4
|
+
* A host hands the provider ONE callback that mints a short-lived session
|
|
5
|
+
* (`{token, expiresAt, expiresIn?}`). The store caches the session until
|
|
6
|
+
* shortly before it expires, shares one acquisition between every caller,
|
|
7
|
+
* re-checks when a hidden tab becomes visible again, and is born and killed
|
|
8
|
+
* with the provider's `identityKey` (it is created inside the client
|
|
9
|
+
* `useMemo`), so an identity switch can never send the previous identity's
|
|
10
|
+
* token: a disposed store commits nothing and its supplier throws.
|
|
11
|
+
*
|
|
12
|
+
* Layering: `@w6w/sdk` already calls the token supplier per request, dedups
|
|
13
|
+
* CONCURRENT ordinary supplier calls and owns the one-shot 401 retry
|
|
14
|
+
* (`refreshOnUnauthorized`, `forceRefresh: true`). This store adds only the
|
|
15
|
+
* cache + single-flight acquisition + resume/expiry handling on top.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { useMemo, useSyncExternalStore } from "react";
|
|
20
|
+
import { useW6WProviderContext } from "./W6WProvider.js";
|
|
21
|
+
/** Default `renewBeforeMs`. */
|
|
22
|
+
export const DEFAULT_RENEW_BEFORE_MS = 30_000;
|
|
23
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
24
|
+
export class SessionStore {
|
|
25
|
+
#getSession;
|
|
26
|
+
#renewBeforeMs;
|
|
27
|
+
#held = null;
|
|
28
|
+
#flight = null;
|
|
29
|
+
#error = null;
|
|
30
|
+
#hasError = false;
|
|
31
|
+
/** Bumped on disposal: an acquisition from an older epoch never commits. */
|
|
32
|
+
#epoch = 0;
|
|
33
|
+
#dead = false;
|
|
34
|
+
#attached = false;
|
|
35
|
+
#timer;
|
|
36
|
+
#listeners = new Set();
|
|
37
|
+
#snapshot;
|
|
38
|
+
constructor(getSession, renewBeforeMs) {
|
|
39
|
+
this.#getSession = getSession;
|
|
40
|
+
this.#renewBeforeMs = renewBeforeMs;
|
|
41
|
+
this.#snapshot = this.#compute();
|
|
42
|
+
}
|
|
43
|
+
// ── external-store surface ─────────────────────────────────────────────
|
|
44
|
+
subscribe = (listener) => {
|
|
45
|
+
this.#listeners.add(listener);
|
|
46
|
+
return () => {
|
|
47
|
+
this.#listeners.delete(listener);
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
getSnapshot = () => this.#snapshot;
|
|
51
|
+
refresh = async () => {
|
|
52
|
+
if (this.#dead)
|
|
53
|
+
return;
|
|
54
|
+
await (this.#flight ? this.#flight.promise : this.#start());
|
|
55
|
+
};
|
|
56
|
+
// ── the stable supplier handed to the SDK ──────────────────────────────
|
|
57
|
+
/** `forceRefresh` JOINS an acquisition already in flight, else starts exactly one. */
|
|
58
|
+
supplier = async (ctx) => {
|
|
59
|
+
if (this.#dead)
|
|
60
|
+
throw new Error("w6w session store was disposed (identity changed or unmounted)");
|
|
61
|
+
const held = this.#held;
|
|
62
|
+
if (ctx?.forceRefresh !== true && held && Date.now() < held.expiry - held.window) {
|
|
63
|
+
return held.token;
|
|
64
|
+
}
|
|
65
|
+
const outcome = await (this.#flight ? this.#flight.promise : this.#start());
|
|
66
|
+
if (this.#dead || !outcome) {
|
|
67
|
+
throw new Error("w6w session store was disposed (identity changed or unmounted)");
|
|
68
|
+
}
|
|
69
|
+
if (outcome.ok)
|
|
70
|
+
return outcome.token;
|
|
71
|
+
const still = this.#held;
|
|
72
|
+
if (still && Date.now() < still.expiry)
|
|
73
|
+
return still.token;
|
|
74
|
+
throw outcome.error;
|
|
75
|
+
};
|
|
76
|
+
// ── lifecycle (effect-driven; disposal deferred so StrictMode's remount works) ─
|
|
77
|
+
/**
|
|
78
|
+
* Called from the provider's effect. Disposal is DEFERRED one microtask (the
|
|
79
|
+
* same refcount idiom `hooks.ts` uses for its abort controller): React
|
|
80
|
+
* StrictMode runs mount -> cleanup -> mount synchronously, and descendants'
|
|
81
|
+
* passive effects (a read hook's first request) have already entered the
|
|
82
|
+
* supplier by the time the cleanup runs, so tearing the flight down at
|
|
83
|
+
* cleanup would reject that request ("stale acquisition"). A re-attach in
|
|
84
|
+
* the same task simply cancels the pending disposal; a real unmount or
|
|
85
|
+
* identity change disposes one microtask later.
|
|
86
|
+
*/
|
|
87
|
+
attach() {
|
|
88
|
+
this.#dead = false;
|
|
89
|
+
this.#attached = true;
|
|
90
|
+
if (typeof document !== "undefined") {
|
|
91
|
+
document.addEventListener("visibilitychange", this.#onVisibility);
|
|
92
|
+
}
|
|
93
|
+
this.#schedule();
|
|
94
|
+
}
|
|
95
|
+
detach() {
|
|
96
|
+
this.#attached = false;
|
|
97
|
+
if (this.#timer !== undefined)
|
|
98
|
+
clearTimeout(this.#timer);
|
|
99
|
+
this.#timer = undefined;
|
|
100
|
+
if (typeof document !== "undefined") {
|
|
101
|
+
document.removeEventListener("visibilitychange", this.#onVisibility);
|
|
102
|
+
}
|
|
103
|
+
queueMicrotask(() => {
|
|
104
|
+
if (this.#attached || this.#dead)
|
|
105
|
+
return;
|
|
106
|
+
this.#dead = true;
|
|
107
|
+
this.#epoch += 1;
|
|
108
|
+
this.#flight = null;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// ── internals ──────────────────────────────────────────────────────────
|
|
112
|
+
#visible() {
|
|
113
|
+
return typeof document !== "undefined" && document.visibilityState === "visible";
|
|
114
|
+
}
|
|
115
|
+
#onVisibility = () => {
|
|
116
|
+
if (this.#dead || !this.#visible() || this.#flight || this.#hasError)
|
|
117
|
+
return;
|
|
118
|
+
const held = this.#held;
|
|
119
|
+
if (!held || Date.now() >= held.expiry - held.window)
|
|
120
|
+
void this.#start();
|
|
121
|
+
else
|
|
122
|
+
this.#update();
|
|
123
|
+
};
|
|
124
|
+
#start() {
|
|
125
|
+
const epoch = this.#epoch;
|
|
126
|
+
const flight = {};
|
|
127
|
+
this.#flight = flight;
|
|
128
|
+
this.#hasError = false;
|
|
129
|
+
this.#error = null;
|
|
130
|
+
this.#update();
|
|
131
|
+
const run = async () => {
|
|
132
|
+
let outcome;
|
|
133
|
+
try {
|
|
134
|
+
const session = await this.#getSession();
|
|
135
|
+
const held = this.#toHeld(session);
|
|
136
|
+
if (epoch !== this.#epoch)
|
|
137
|
+
return { ok: false, error: new Error("stale acquisition") };
|
|
138
|
+
this.#held = held;
|
|
139
|
+
outcome = { ok: true, token: held.token };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (epoch !== this.#epoch)
|
|
143
|
+
return { ok: false, error };
|
|
144
|
+
this.#hasError = true;
|
|
145
|
+
this.#error = error;
|
|
146
|
+
outcome = { ok: false, error };
|
|
147
|
+
}
|
|
148
|
+
if (this.#flight === flight)
|
|
149
|
+
this.#flight = null;
|
|
150
|
+
this.#update();
|
|
151
|
+
this.#schedule();
|
|
152
|
+
return outcome;
|
|
153
|
+
};
|
|
154
|
+
flight.promise = run();
|
|
155
|
+
return flight.promise;
|
|
156
|
+
}
|
|
157
|
+
#toHeld(session) {
|
|
158
|
+
const receivedAt = Date.now();
|
|
159
|
+
if (!session || typeof session.token !== "string" || session.token.trim().length === 0) {
|
|
160
|
+
throw new Error("getSession returned a blank token");
|
|
161
|
+
}
|
|
162
|
+
let expiry = Date.parse(session.expiresAt);
|
|
163
|
+
if (Number.isNaN(expiry))
|
|
164
|
+
throw new Error("getSession returned an invalid expiresAt");
|
|
165
|
+
if (typeof session.expiresIn === "number" && Number.isFinite(session.expiresIn)) {
|
|
166
|
+
expiry = Math.min(expiry, receivedAt + session.expiresIn * 1000);
|
|
167
|
+
}
|
|
168
|
+
const window = Math.max(0, Math.min(this.#renewBeforeMs(), (expiry - receivedAt) / 2));
|
|
169
|
+
return { token: session.token, expiresAt: session.expiresAt, expiry, window };
|
|
170
|
+
}
|
|
171
|
+
#schedule() {
|
|
172
|
+
if (this.#timer !== undefined)
|
|
173
|
+
clearTimeout(this.#timer);
|
|
174
|
+
this.#timer = undefined;
|
|
175
|
+
const held = this.#held;
|
|
176
|
+
if (!this.#attached || !held)
|
|
177
|
+
return;
|
|
178
|
+
const now = Date.now();
|
|
179
|
+
const renewAt = held.expiry - held.window;
|
|
180
|
+
const target = now < renewAt ? renewAt : now < held.expiry ? held.expiry : null;
|
|
181
|
+
if (target === null)
|
|
182
|
+
return;
|
|
183
|
+
this.#timer = setTimeout(this.#tick, Math.min(Math.max(0, target - now), MAX_TIMER_MS));
|
|
184
|
+
}
|
|
185
|
+
#tick = () => {
|
|
186
|
+
this.#timer = undefined;
|
|
187
|
+
if (this.#dead)
|
|
188
|
+
return;
|
|
189
|
+
const held = this.#held;
|
|
190
|
+
if (held &&
|
|
191
|
+
!this.#flight &&
|
|
192
|
+
!this.#hasError &&
|
|
193
|
+
this.#visible() &&
|
|
194
|
+
Date.now() >= held.expiry - held.window) {
|
|
195
|
+
void this.#start(); // updates + reschedules itself on settle
|
|
196
|
+
}
|
|
197
|
+
this.#update();
|
|
198
|
+
this.#schedule();
|
|
199
|
+
};
|
|
200
|
+
#compute() {
|
|
201
|
+
const held = this.#held;
|
|
202
|
+
let status;
|
|
203
|
+
if (this.#flight)
|
|
204
|
+
status = held ? "renewing" : "loading";
|
|
205
|
+
else if (this.#hasError)
|
|
206
|
+
status = "error";
|
|
207
|
+
else if (!held)
|
|
208
|
+
status = "loading";
|
|
209
|
+
else
|
|
210
|
+
status = Date.now() >= held.expiry ? "expired" : "ready";
|
|
211
|
+
return {
|
|
212
|
+
status,
|
|
213
|
+
expiresAt: held ? held.expiresAt : null,
|
|
214
|
+
error: this.#error,
|
|
215
|
+
refresh: this.refresh,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
#update() {
|
|
219
|
+
const next = this.#compute();
|
|
220
|
+
const prev = this.#snapshot;
|
|
221
|
+
if (next.status === prev.status &&
|
|
222
|
+
next.expiresAt === prev.expiresAt &&
|
|
223
|
+
next.error === prev.error) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.#snapshot = next;
|
|
227
|
+
for (const listener of [...this.#listeners])
|
|
228
|
+
listener();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const noopSubscribe = () => () => { };
|
|
232
|
+
const noopRefresh = () => Promise.resolve();
|
|
233
|
+
/**
|
|
234
|
+
* The provider's session state. With a `getSession` provider it mirrors the
|
|
235
|
+
* store; with a `token` provider `status` is `"ready"` when the provider's
|
|
236
|
+
* `ready` is true (else `"loading"`), `expiresAt` is `null` and `refresh()`
|
|
237
|
+
* resolves without calling anything.
|
|
238
|
+
*/
|
|
239
|
+
export function useW6WSession() {
|
|
240
|
+
const { session, ready } = useW6WProviderContext();
|
|
241
|
+
const tokenState = useMemo(() => ({
|
|
242
|
+
status: ready ? "ready" : "loading",
|
|
243
|
+
expiresAt: null,
|
|
244
|
+
error: null,
|
|
245
|
+
refresh: noopRefresh,
|
|
246
|
+
}), [ready]);
|
|
247
|
+
return useSyncExternalStore(session ? session.subscribe : noopSubscribe, session ? session.getSnapshot : () => tokenState, session ? session.getSnapshot : () => tokenState);
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@w6w/react",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"description": "React bindings for @w6w/sdk — a <W6WProvider>, a small hook set, and a structural adapter for @w6w/ui's W6WApi contract.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"react": ">=18"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@w6w/sdk": "^0.9.
|
|
47
|
+
"@w6w/sdk": "^0.9.13"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@biomejs/biome": "^1.9.4",
|