@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 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.12 · Guides: [docs.w6w.io/clients/react](https://docs.w6w.io/clients/react/)
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 `exchangeToken` from `@w6w/sdk/server` on your backend.
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 five more props for exactly this:
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
- ready={true}
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-token` route this example fetches from, with `exchangeToken` and a
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
- export interface W6WProviderProps {
45
- /** The w6w server's origin, e.g. `"https://api.example.com"`. */
46
- baseUrl: string;
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,EAAE,KAAK,SAAS,EAA8C,MAAM,OAAO,CAAC;AAEnF,oGAAoG;AACpG,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,qGAAqG;IACrG,KAAK,EAAE,WAAW,CAAC;IACnB;;;;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;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,0FAA0F;IAC1F,KAAK,EAAE,OAAO,CAAC;CAChB;AAeD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAqE9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,SAAS,CASxC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CASvD"}
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"}
@@ -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
- return new W6WClient({
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
- }, [baseUrl, project, identityKey, refreshOnUnauthorized, headersSnapshot]);
109
- const value = useMemo(() => ({ client, ready }), [client, ready]);
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":"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"}
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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"}
@@ -15,5 +15,5 @@
15
15
  * every wrapper's version in lockstep, and that pattern depends on the literal
16
16
  * `: string` shape being present.
17
17
  */
18
- export const VERSION = "0.9.12";
18
+ export const VERSION = "0.9.13";
19
19
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w6w/react",
3
- "version": "0.9.12",
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.12"
47
+ "@w6w/sdk": "^0.9.13"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@biomejs/biome": "^1.9.4",