@lunora/react-native 1.0.0-alpha.3 → 1.0.0-alpha.30

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/auth.d.mts CHANGED
@@ -1,37 +1,78 @@
1
- export { expoClient, setupExpoFocusManager, setupExpoOnlineManager } from '@better-auth/expo/client';
1
+ import { expoClient as expoClient$1 } from '@better-auth/expo/client';
2
+ export { setupExpoFocusManager, setupExpoOnlineManager } from '@better-auth/expo/client';
3
+ import { BetterAuthClientPlugin } from 'better-auth/client';
2
4
  /**
3
- * Read the current better-auth session token from an Expo auth client, for use
4
- * as a **bearer** credential on the Lunora client — `client.setAuthToken(token)`
5
- * for HTTP RPC and `client.setWsToken(token ?? undefined)` for the live socket.
6
- *
7
- * The Expo plugin persists the session as a cookie in `SecureStore`;
8
- * `getCookie()` exposes it, and this pulls the `session_token` value out.
9
- * better-auth's `bearer` plugin accepts that value verbatim in the
10
- * `Authorization` header — so the native client authenticates WITHOUT sending a
11
- * `Cookie`, which the runtime's CSRF guard rejects on an `Origin`-less native
12
- * request (React Native sends no `Origin`). Returns `null` when signed out.
13
- *
14
- * Re-run it whenever the session changes and feed the result to the client (see
15
- * the package README):
16
- *
17
- * ```ts
18
- * const token = expoBearerToken(authClient);
19
- * client.setAuthToken(token);
20
- * client.setWsToken(token ?? undefined);
21
- * ```
22
- * @experimental
23
- */
5
+ * Read the current better-auth session token from an Expo auth client, for use
6
+ * as a **bearer** credential on the Lunora client — `client.setAuthToken(token)`
7
+ * for HTTP RPC and `client.setWsToken(token ?? undefined)` for the live socket.
8
+ *
9
+ * The Expo plugin persists the session as a cookie in `SecureStore`;
10
+ * `getCookie()` exposes it, and this pulls the `session_token` value out.
11
+ * better-auth's `bearer` plugin accepts that value verbatim in the
12
+ * `Authorization` header — so the native client authenticates WITHOUT sending a
13
+ * `Cookie`, which the runtime's CSRF guard rejects on an `Origin`-less native
14
+ * request (React Native sends no `Origin`). Returns `null` when signed out.
15
+ *
16
+ * Re-run it whenever the session changes and feed the result to the client (see
17
+ * the package README):
18
+ *
19
+ * ```ts
20
+ * const token = expoBearerToken(authClient);
21
+ * client.setAuthToken(token);
22
+ * client.setWsToken(token ?? undefined);
23
+ * ```
24
+ * @experimental
25
+ */
24
26
  declare const expoBearerToken: (authClient: {
25
27
  getCookie: () => string;
26
28
  }) => null | string;
27
29
  /**
28
- * The slice of a key/value store the better-auth Expo plugin needs — the shape
29
- * of `expo-secure-store` (a synchronous `getItem`, plus `setItem`). Pass Expo
30
- * `SecureStore` straight in.
31
- * @experimental
32
- */
30
+ * The slice of a key/value store the better-auth Expo plugin needs — the shape
31
+ * of `expo-secure-store` (a synchronous `getItem`, plus `setItem`). Pass Expo
32
+ * `SecureStore` straight in.
33
+ * @experimental
34
+ */
33
35
  interface SecureStorageLike {
34
36
  getItem: (key: string) => null | string;
35
37
  setItem: (key: string, value: string) => unknown;
36
38
  }
37
- export { SecureStorageLike, expoBearerToken };
39
+ /** The actions `expoClient` contributes to the auth client. */
40
+ interface ExpoClientActions {
41
+ /** The session cookie persisted in `SecureStore`, as a `name=value; …` string. */
42
+ getCookie: () => string;
43
+ }
44
+ /**
45
+ * `expoClient`'s plugin type, restated so it satisfies `BetterAuthClientPlugin`.
46
+ *
47
+ * From better-auth 1.6.24 through 1.7.0-rc.2, `@better-auth/expo`'s own declaration
48
+ * does not: its `getActions` types the `$fetch` parameter as a *different*
49
+ * `BetterFetch` instantiation than the interface requires, and under
50
+ * `strictFunctionTypes` parameter contravariance rejects the assignment — so
51
+ * `createAuthClient({ plugins: [expoClient(…)] })` fails to typecheck with a TS2322
52
+ * whose error text is several hundred characters of generic-inference expansion.
53
+ * The knock-on is a TS2345 wherever the inferred `getCookie` action is then read.
54
+ *
55
+ * The base has to stay upstream's own return type, with only `getActions` replaced:
56
+ * better-auth infers the whole client API (`signIn`, `signUp`, the session shape)
57
+ * from the literal plugin members, so rebuilding the type on top of
58
+ * `BetterAuthClientPlugin` instead — or merely intersecting with it — collapses that
59
+ * inference to `never` and the errors reappear as "Property 'signIn' does not exist".
60
+ * The replacement takes its parameters from better-auth's interface (making the
61
+ * assignment trivially valid) and returns {@link ExpoClientActions}, which is what
62
+ * keeps `authClient.getCookie()` typed for `expoBearerToken`. Runtime behaviour
63
+ * is untouched — this is a declaration-level correction of an upstream bug.
64
+ *
65
+ * Delete this shim (and re-export `expoClient` directly) once upstream's
66
+ * `getActions` signature matches the interface again.
67
+ * @experimental
68
+ */
69
+ type ExpoClientPlugin = Omit<ReturnType<typeof expoClient$1>, "getActions"> & {
70
+ getActions: (...arguments_: Parameters<NonNullable<BetterAuthClientPlugin["getActions"]>>) => ExpoClientActions;
71
+ };
72
+ /**
73
+ * The better-auth Expo client plugin — session persisted in `SecureStore`, OAuth via
74
+ * the app scheme. Pass it to `createAuthClient({ plugins: [expoClient({ scheme, storage })] })`.
75
+ * @experimental
76
+ */
77
+ declare const expoClient: (options: Parameters<typeof expoClient$1>[0]) => ExpoClientPlugin;
78
+ export { ExpoClientActions, ExpoClientPlugin, SecureStorageLike, expoBearerToken, expoClient };
package/dist/auth.d.ts CHANGED
@@ -1,37 +1,78 @@
1
- export { expoClient, setupExpoFocusManager, setupExpoOnlineManager } from '@better-auth/expo/client';
1
+ import { expoClient as expoClient$1 } from '@better-auth/expo/client';
2
+ export { setupExpoFocusManager, setupExpoOnlineManager } from '@better-auth/expo/client';
3
+ import { BetterAuthClientPlugin } from 'better-auth/client';
2
4
  /**
3
- * Read the current better-auth session token from an Expo auth client, for use
4
- * as a **bearer** credential on the Lunora client — `client.setAuthToken(token)`
5
- * for HTTP RPC and `client.setWsToken(token ?? undefined)` for the live socket.
6
- *
7
- * The Expo plugin persists the session as a cookie in `SecureStore`;
8
- * `getCookie()` exposes it, and this pulls the `session_token` value out.
9
- * better-auth's `bearer` plugin accepts that value verbatim in the
10
- * `Authorization` header — so the native client authenticates WITHOUT sending a
11
- * `Cookie`, which the runtime's CSRF guard rejects on an `Origin`-less native
12
- * request (React Native sends no `Origin`). Returns `null` when signed out.
13
- *
14
- * Re-run it whenever the session changes and feed the result to the client (see
15
- * the package README):
16
- *
17
- * ```ts
18
- * const token = expoBearerToken(authClient);
19
- * client.setAuthToken(token);
20
- * client.setWsToken(token ?? undefined);
21
- * ```
22
- * @experimental
23
- */
5
+ * Read the current better-auth session token from an Expo auth client, for use
6
+ * as a **bearer** credential on the Lunora client — `client.setAuthToken(token)`
7
+ * for HTTP RPC and `client.setWsToken(token ?? undefined)` for the live socket.
8
+ *
9
+ * The Expo plugin persists the session as a cookie in `SecureStore`;
10
+ * `getCookie()` exposes it, and this pulls the `session_token` value out.
11
+ * better-auth's `bearer` plugin accepts that value verbatim in the
12
+ * `Authorization` header — so the native client authenticates WITHOUT sending a
13
+ * `Cookie`, which the runtime's CSRF guard rejects on an `Origin`-less native
14
+ * request (React Native sends no `Origin`). Returns `null` when signed out.
15
+ *
16
+ * Re-run it whenever the session changes and feed the result to the client (see
17
+ * the package README):
18
+ *
19
+ * ```ts
20
+ * const token = expoBearerToken(authClient);
21
+ * client.setAuthToken(token);
22
+ * client.setWsToken(token ?? undefined);
23
+ * ```
24
+ * @experimental
25
+ */
24
26
  declare const expoBearerToken: (authClient: {
25
27
  getCookie: () => string;
26
28
  }) => null | string;
27
29
  /**
28
- * The slice of a key/value store the better-auth Expo plugin needs — the shape
29
- * of `expo-secure-store` (a synchronous `getItem`, plus `setItem`). Pass Expo
30
- * `SecureStore` straight in.
31
- * @experimental
32
- */
30
+ * The slice of a key/value store the better-auth Expo plugin needs — the shape
31
+ * of `expo-secure-store` (a synchronous `getItem`, plus `setItem`). Pass Expo
32
+ * `SecureStore` straight in.
33
+ * @experimental
34
+ */
33
35
  interface SecureStorageLike {
34
36
  getItem: (key: string) => null | string;
35
37
  setItem: (key: string, value: string) => unknown;
36
38
  }
37
- export { SecureStorageLike, expoBearerToken };
39
+ /** The actions `expoClient` contributes to the auth client. */
40
+ interface ExpoClientActions {
41
+ /** The session cookie persisted in `SecureStore`, as a `name=value; …` string. */
42
+ getCookie: () => string;
43
+ }
44
+ /**
45
+ * `expoClient`'s plugin type, restated so it satisfies `BetterAuthClientPlugin`.
46
+ *
47
+ * From better-auth 1.6.24 through 1.7.0-rc.2, `@better-auth/expo`'s own declaration
48
+ * does not: its `getActions` types the `$fetch` parameter as a *different*
49
+ * `BetterFetch` instantiation than the interface requires, and under
50
+ * `strictFunctionTypes` parameter contravariance rejects the assignment — so
51
+ * `createAuthClient({ plugins: [expoClient(…)] })` fails to typecheck with a TS2322
52
+ * whose error text is several hundred characters of generic-inference expansion.
53
+ * The knock-on is a TS2345 wherever the inferred `getCookie` action is then read.
54
+ *
55
+ * The base has to stay upstream's own return type, with only `getActions` replaced:
56
+ * better-auth infers the whole client API (`signIn`, `signUp`, the session shape)
57
+ * from the literal plugin members, so rebuilding the type on top of
58
+ * `BetterAuthClientPlugin` instead — or merely intersecting with it — collapses that
59
+ * inference to `never` and the errors reappear as "Property 'signIn' does not exist".
60
+ * The replacement takes its parameters from better-auth's interface (making the
61
+ * assignment trivially valid) and returns {@link ExpoClientActions}, which is what
62
+ * keeps `authClient.getCookie()` typed for `expoBearerToken`. Runtime behaviour
63
+ * is untouched — this is a declaration-level correction of an upstream bug.
64
+ *
65
+ * Delete this shim (and re-export `expoClient` directly) once upstream's
66
+ * `getActions` signature matches the interface again.
67
+ * @experimental
68
+ */
69
+ type ExpoClientPlugin = Omit<ReturnType<typeof expoClient$1>, "getActions"> & {
70
+ getActions: (...arguments_: Parameters<NonNullable<BetterAuthClientPlugin["getActions"]>>) => ExpoClientActions;
71
+ };
72
+ /**
73
+ * The better-auth Expo client plugin — session persisted in `SecureStore`, OAuth via
74
+ * the app scheme. Pass it to `createAuthClient({ plugins: [expoClient({ scheme, storage })] })`.
75
+ * @experimental
76
+ */
77
+ declare const expoClient: (options: Parameters<typeof expoClient$1>[0]) => ExpoClientPlugin;
78
+ export { ExpoClientActions, ExpoClientPlugin, SecureStorageLike, expoBearerToken, expoClient };
package/dist/auth.mjs CHANGED
@@ -1,2 +1 @@
1
- export { default as expoBearerToken } from './packem_shared/expoBearerToken-B0Zorz--.mjs';
2
- export { expoClient, setupExpoFocusManager, setupExpoOnlineManager } from '@better-auth/expo/client';
1
+ import{expoClient as e}from"@better-auth/expo/client";import{setupExpoFocusManager as n,setupExpoOnlineManager as x}from"@better-auth/expo/client";import{default as s}from"./packem_shared/expoBearerToken-D4y9YP0s.mjs";const p=e;export{s as expoBearerToken,p as expoClient,n as setupExpoFocusManager,x as setupExpoOnlineManager};
package/dist/index.d.mts CHANGED
@@ -1,78 +1,78 @@
1
1
  import { AsyncStorageLike, LunoraClientOptions, LunoraClient } from '@lunora/client';
2
2
  export * from '@lunora/react';
3
3
  /**
4
- * A `() => headers` factory the React Native client threads onto every HTTP RPC
5
- * request *and* the WebSocket upgrade — a generic escape hatch for attaching a
6
- * **custom** credential header (an API-gateway key, a proxy token, …) that
7
- * React Native's missing cookie jar can't carry implicitly. Return `undefined`
8
- * (or an empty object) when there's nothing to attach.
9
- *
10
- * For better-auth Expo sessions, prefer a **bearer** token instead: read it with
11
- * `@lunora/react-native/auth`'s `expoBearerToken` and feed it to
12
- * `client.setAuthToken` / `setWsToken` (see the package README). A bearer avoids
13
- * the `Cookie` header the runtime's CSRF guard rejects on `Origin`-less native
14
- * requests.
15
- * @experimental
16
- */
4
+ * A `() => headers` factory the React Native client threads onto every HTTP RPC
5
+ * request *and* the WebSocket upgrade — a generic escape hatch for attaching a
6
+ * **custom** credential header (an API-gateway key, a proxy token, …) that
7
+ * React Native's missing cookie jar can't carry implicitly. Return `undefined`
8
+ * (or an empty object) when there's nothing to attach.
9
+ *
10
+ * For better-auth Expo sessions, prefer a **bearer** token instead: read it with
11
+ * `@lunora/react-native/auth`'s `expoBearerToken` and feed it to
12
+ * `client.setAuthToken` / `setWsToken` (see the package README). A bearer avoids
13
+ * the `Cookie` header the runtime's CSRF guard rejects on `Origin`-less native
14
+ * requests.
15
+ * @experimental
16
+ */
17
17
  type AuthHeadersFactory = () => Record<string, string> | undefined;
18
18
  /**
19
- * Options for `createLunoraClient` — the React Native / Expo counterpart to
20
- * constructing a `LunoraClient` directly. It is `LunoraClientOptions` with two
21
- * React-Native-shaped conveniences layered on. `storage` wires the
22
- * AsyncStorage-backed offline-queue persistence for you (the browser default
23
- * auto-probes IndexedDB, which React Native lacks, so without this the queue
24
- * stays in memory and is lost on reload). `getAuthHeaders` is a generic escape
25
- * hatch for a custom credential header on both the HTTP RPC path and the
26
- * WebSocket upgrade; for better-auth sessions prefer a bearer token
27
- * (`expoBearerToken` + the client's `setAuthToken` / `setWsToken`).
28
- *
29
- * The `persistence`, `fetch`, and `WebSocket` fields of `LunoraClientOptions`
30
- * are still accepted and take precedence when you need full control; the two
31
- * conveniences are sugar over exactly those seams.
32
- * @experimental
33
- */
19
+ * Options for `createLunoraClient` — the React Native / Expo counterpart to
20
+ * constructing a `LunoraClient` directly. It is `LunoraClientOptions` with two
21
+ * React-Native-shaped conveniences layered on. `storage` wires the
22
+ * AsyncStorage-backed offline-queue persistence for you (the browser default
23
+ * auto-probes IndexedDB, which React Native lacks, so without this the queue
24
+ * stays in memory and is lost on reload). `getAuthHeaders` is a generic escape
25
+ * hatch for a custom credential header on both the HTTP RPC path and the
26
+ * WebSocket upgrade; for better-auth sessions prefer a bearer token
27
+ * (`expoBearerToken` + the client's `setAuthToken` / `setWsToken`).
28
+ *
29
+ * The `persistence`, `fetch`, and `WebSocket` fields of `LunoraClientOptions`
30
+ * are still accepted and take precedence when you need full control; the two
31
+ * conveniences are sugar over exactly those seams.
32
+ * @experimental
33
+ */
34
34
  interface CreateLunoraClientOptions extends LunoraClientOptions {
35
35
  /**
36
- * Attaches a credential to every HTTP RPC request and to the WebSocket
37
- * upgrade request. See `AuthHeadersFactory`. When omitted, requests go out
38
- * with only whatever `LunoraClient` already sets (its bearer token from
39
- * `setAuthToken`, if any).
40
- *
41
- * Merged UNDER the client's own headers on the HTTP path (an explicit
42
- * `setAuthToken` bearer wins over a same-named header here); applied to the
43
- * WebSocket upgrade via a wrapping `WebSocket`, since the socket has no other
44
- * way to carry credentials in React Native.
45
- */
36
+ * Attaches a credential to every HTTP RPC request and to the WebSocket
37
+ * upgrade request. See `AuthHeadersFactory`. When omitted, requests go out
38
+ * with only whatever `LunoraClient` already sets (its bearer token from
39
+ * `setAuthToken`, if any).
40
+ *
41
+ * Merged UNDER the client's own headers on the HTTP path (an explicit
42
+ * `setAuthToken` bearer wins over a same-named header here); applied to the
43
+ * WebSocket upgrade via a wrapping `WebSocket`, since the socket has no other
44
+ * way to carry credentials in React Native.
45
+ */
46
46
  getAuthHeaders?: AuthHeadersFactory;
47
47
  /**
48
- * React Native `AsyncStorage` (or any async key/value store with the same
49
- * `getItem`/`setItem`/`removeItem` surface — Expo `SecureStore`, an in-memory
50
- * map in tests). When supplied, the offline mutation queue is persisted here
51
- * via `createAsyncStoragePersistence`, so writes made offline survive an app
52
- * restart. Ignored when an explicit `persistence` is passed.
53
- */
48
+ * React Native `AsyncStorage` (or any async key/value store with the same
49
+ * `getItem`/`setItem`/`removeItem` surface — Expo `SecureStore`, an in-memory
50
+ * map in tests). When supplied, the offline mutation queue is persisted here
51
+ * via `createAsyncStoragePersistence`, so writes made offline survive an app
52
+ * restart. Ignored when an explicit `persistence` is passed.
53
+ */
54
54
  storage?: AsyncStorageLike;
55
55
  }
56
56
  /**
57
- * Construct a `LunoraClient` tuned for React Native / Expo — a thin wrapper over
58
- * `new LunoraClient(options)` that fills in the two things a browser gets for
59
- * free but React Native does not.
60
- *
61
- * First, a durable offline queue: pass `storage` (React Native `AsyncStorage`,
62
- * or any async key/value store) and the offline mutation queue is persisted
63
- * through `createAsyncStoragePersistence` — the browser default auto-probes
64
- * IndexedDB, which React Native lacks, so without this the queue lives only in
65
- * memory and is lost on reload.
66
- *
67
- * Second, credentialed requests: pass `getAuthHeaders` and the returned headers
68
- * ride both the HTTP RPC path and the WebSocket upgrade, since React Native has
69
- * no cookie jar to attach a session implicitly.
70
- *
71
- * Everything on `LunoraClientOptions` is still accepted and passed through; an
72
- * explicit `persistence`, `fetch`, or `WebSocket` takes precedence over the
73
- * convenience derived from `storage` / `getAuthHeaders`. See the package README
74
- * for a full setup example.
75
- * @experimental
76
- */
57
+ * Construct a `LunoraClient` tuned for React Native / Expo — a thin wrapper over
58
+ * `new LunoraClient(options)` that fills in the two things a browser gets for
59
+ * free but React Native does not.
60
+ *
61
+ * First, a durable offline queue: pass `storage` (React Native `AsyncStorage`,
62
+ * or any async key/value store) and the offline mutation queue is persisted
63
+ * through `createAsyncStoragePersistence` — the browser default auto-probes
64
+ * IndexedDB, which React Native lacks, so without this the queue lives only in
65
+ * memory and is lost on reload.
66
+ *
67
+ * Second, credentialed requests: pass `getAuthHeaders` and the returned headers
68
+ * ride both the HTTP RPC path and the WebSocket upgrade, since React Native has
69
+ * no cookie jar to attach a session implicitly.
70
+ *
71
+ * Everything on `LunoraClientOptions` is still accepted and passed through; an
72
+ * explicit `persistence`, `fetch`, or `WebSocket` takes precedence over the
73
+ * convenience derived from `storage` / `getAuthHeaders`. See the package README
74
+ * for a full setup example.
75
+ * @experimental
76
+ */
77
77
  declare const createLunoraClient: (options: CreateLunoraClientOptions) => LunoraClient;
78
78
  export { type AuthHeadersFactory, type CreateLunoraClientOptions, createLunoraClient };
package/dist/index.d.ts CHANGED
@@ -1,78 +1,78 @@
1
1
  import { AsyncStorageLike, LunoraClientOptions, LunoraClient } from '@lunora/client';
2
2
  export * from '@lunora/react';
3
3
  /**
4
- * A `() => headers` factory the React Native client threads onto every HTTP RPC
5
- * request *and* the WebSocket upgrade — a generic escape hatch for attaching a
6
- * **custom** credential header (an API-gateway key, a proxy token, …) that
7
- * React Native's missing cookie jar can't carry implicitly. Return `undefined`
8
- * (or an empty object) when there's nothing to attach.
9
- *
10
- * For better-auth Expo sessions, prefer a **bearer** token instead: read it with
11
- * `@lunora/react-native/auth`'s `expoBearerToken` and feed it to
12
- * `client.setAuthToken` / `setWsToken` (see the package README). A bearer avoids
13
- * the `Cookie` header the runtime's CSRF guard rejects on `Origin`-less native
14
- * requests.
15
- * @experimental
16
- */
4
+ * A `() => headers` factory the React Native client threads onto every HTTP RPC
5
+ * request *and* the WebSocket upgrade — a generic escape hatch for attaching a
6
+ * **custom** credential header (an API-gateway key, a proxy token, …) that
7
+ * React Native's missing cookie jar can't carry implicitly. Return `undefined`
8
+ * (or an empty object) when there's nothing to attach.
9
+ *
10
+ * For better-auth Expo sessions, prefer a **bearer** token instead: read it with
11
+ * `@lunora/react-native/auth`'s `expoBearerToken` and feed it to
12
+ * `client.setAuthToken` / `setWsToken` (see the package README). A bearer avoids
13
+ * the `Cookie` header the runtime's CSRF guard rejects on `Origin`-less native
14
+ * requests.
15
+ * @experimental
16
+ */
17
17
  type AuthHeadersFactory = () => Record<string, string> | undefined;
18
18
  /**
19
- * Options for `createLunoraClient` — the React Native / Expo counterpart to
20
- * constructing a `LunoraClient` directly. It is `LunoraClientOptions` with two
21
- * React-Native-shaped conveniences layered on. `storage` wires the
22
- * AsyncStorage-backed offline-queue persistence for you (the browser default
23
- * auto-probes IndexedDB, which React Native lacks, so without this the queue
24
- * stays in memory and is lost on reload). `getAuthHeaders` is a generic escape
25
- * hatch for a custom credential header on both the HTTP RPC path and the
26
- * WebSocket upgrade; for better-auth sessions prefer a bearer token
27
- * (`expoBearerToken` + the client's `setAuthToken` / `setWsToken`).
28
- *
29
- * The `persistence`, `fetch`, and `WebSocket` fields of `LunoraClientOptions`
30
- * are still accepted and take precedence when you need full control; the two
31
- * conveniences are sugar over exactly those seams.
32
- * @experimental
33
- */
19
+ * Options for `createLunoraClient` — the React Native / Expo counterpart to
20
+ * constructing a `LunoraClient` directly. It is `LunoraClientOptions` with two
21
+ * React-Native-shaped conveniences layered on. `storage` wires the
22
+ * AsyncStorage-backed offline-queue persistence for you (the browser default
23
+ * auto-probes IndexedDB, which React Native lacks, so without this the queue
24
+ * stays in memory and is lost on reload). `getAuthHeaders` is a generic escape
25
+ * hatch for a custom credential header on both the HTTP RPC path and the
26
+ * WebSocket upgrade; for better-auth sessions prefer a bearer token
27
+ * (`expoBearerToken` + the client's `setAuthToken` / `setWsToken`).
28
+ *
29
+ * The `persistence`, `fetch`, and `WebSocket` fields of `LunoraClientOptions`
30
+ * are still accepted and take precedence when you need full control; the two
31
+ * conveniences are sugar over exactly those seams.
32
+ * @experimental
33
+ */
34
34
  interface CreateLunoraClientOptions extends LunoraClientOptions {
35
35
  /**
36
- * Attaches a credential to every HTTP RPC request and to the WebSocket
37
- * upgrade request. See `AuthHeadersFactory`. When omitted, requests go out
38
- * with only whatever `LunoraClient` already sets (its bearer token from
39
- * `setAuthToken`, if any).
40
- *
41
- * Merged UNDER the client's own headers on the HTTP path (an explicit
42
- * `setAuthToken` bearer wins over a same-named header here); applied to the
43
- * WebSocket upgrade via a wrapping `WebSocket`, since the socket has no other
44
- * way to carry credentials in React Native.
45
- */
36
+ * Attaches a credential to every HTTP RPC request and to the WebSocket
37
+ * upgrade request. See `AuthHeadersFactory`. When omitted, requests go out
38
+ * with only whatever `LunoraClient` already sets (its bearer token from
39
+ * `setAuthToken`, if any).
40
+ *
41
+ * Merged UNDER the client's own headers on the HTTP path (an explicit
42
+ * `setAuthToken` bearer wins over a same-named header here); applied to the
43
+ * WebSocket upgrade via a wrapping `WebSocket`, since the socket has no other
44
+ * way to carry credentials in React Native.
45
+ */
46
46
  getAuthHeaders?: AuthHeadersFactory;
47
47
  /**
48
- * React Native `AsyncStorage` (or any async key/value store with the same
49
- * `getItem`/`setItem`/`removeItem` surface — Expo `SecureStore`, an in-memory
50
- * map in tests). When supplied, the offline mutation queue is persisted here
51
- * via `createAsyncStoragePersistence`, so writes made offline survive an app
52
- * restart. Ignored when an explicit `persistence` is passed.
53
- */
48
+ * React Native `AsyncStorage` (or any async key/value store with the same
49
+ * `getItem`/`setItem`/`removeItem` surface — Expo `SecureStore`, an in-memory
50
+ * map in tests). When supplied, the offline mutation queue is persisted here
51
+ * via `createAsyncStoragePersistence`, so writes made offline survive an app
52
+ * restart. Ignored when an explicit `persistence` is passed.
53
+ */
54
54
  storage?: AsyncStorageLike;
55
55
  }
56
56
  /**
57
- * Construct a `LunoraClient` tuned for React Native / Expo — a thin wrapper over
58
- * `new LunoraClient(options)` that fills in the two things a browser gets for
59
- * free but React Native does not.
60
- *
61
- * First, a durable offline queue: pass `storage` (React Native `AsyncStorage`,
62
- * or any async key/value store) and the offline mutation queue is persisted
63
- * through `createAsyncStoragePersistence` — the browser default auto-probes
64
- * IndexedDB, which React Native lacks, so without this the queue lives only in
65
- * memory and is lost on reload.
66
- *
67
- * Second, credentialed requests: pass `getAuthHeaders` and the returned headers
68
- * ride both the HTTP RPC path and the WebSocket upgrade, since React Native has
69
- * no cookie jar to attach a session implicitly.
70
- *
71
- * Everything on `LunoraClientOptions` is still accepted and passed through; an
72
- * explicit `persistence`, `fetch`, or `WebSocket` takes precedence over the
73
- * convenience derived from `storage` / `getAuthHeaders`. See the package README
74
- * for a full setup example.
75
- * @experimental
76
- */
57
+ * Construct a `LunoraClient` tuned for React Native / Expo — a thin wrapper over
58
+ * `new LunoraClient(options)` that fills in the two things a browser gets for
59
+ * free but React Native does not.
60
+ *
61
+ * First, a durable offline queue: pass `storage` (React Native `AsyncStorage`,
62
+ * or any async key/value store) and the offline mutation queue is persisted
63
+ * through `createAsyncStoragePersistence` — the browser default auto-probes
64
+ * IndexedDB, which React Native lacks, so without this the queue lives only in
65
+ * memory and is lost on reload.
66
+ *
67
+ * Second, credentialed requests: pass `getAuthHeaders` and the returned headers
68
+ * ride both the HTTP RPC path and the WebSocket upgrade, since React Native has
69
+ * no cookie jar to attach a session implicitly.
70
+ *
71
+ * Everything on `LunoraClientOptions` is still accepted and passed through; an
72
+ * explicit `persistence`, `fetch`, or `WebSocket` takes precedence over the
73
+ * convenience derived from `storage` / `getAuthHeaders`. See the package README
74
+ * for a full setup example.
75
+ * @experimental
76
+ */
77
77
  declare const createLunoraClient: (options: CreateLunoraClientOptions) => LunoraClient;
78
78
  export { type AuthHeadersFactory, type CreateLunoraClientOptions, createLunoraClient };
package/dist/index.mjs CHANGED
@@ -1,2 +1 @@
1
- export { createLunoraClient } from './packem_shared/createLunoraClient-D9i-IKbc.mjs';
2
- export * from '@lunora/react';
1
+ import{createLunoraClient as o}from"./packem_shared/createLunoraClient-C_r92Czw.mjs";export*from"@lunora/react";export{o as createLunoraClient};
@@ -0,0 +1 @@
1
+ import{LunoraClient as h,createAsyncStoragePersistence as d}from"@lunora/client";const u=(c,t)=>(r,e)=>{const s=t();if(!s)return c(r,e);const o=new Headers(s);return e?.headers&&new Headers(e.headers).forEach((n,a)=>{o.set(a,n)}),c(r,{...e,headers:o})},f=(c,t)=>class extends c{constructor(e,s){const o=t();super(e,s,o?{headers:o}:void 0)}},S=c=>{const{getAuthHeaders:t,storage:r,...e}=c,s=t&&e.fetch===void 0&&typeof fetch=="function"?u(fetch.bind(globalThis),t):e.fetch,o=t&&e.WebSocket===void 0&&typeof WebSocket=="function"?f(WebSocket,t):e.WebSocket;return new h({...e,persistence:e.persistence??(r?d({storage:r}):void 0),fetch:s,WebSocket:o})};export{S as createLunoraClient,u as withAuthHeaders,f as withAuthWebSocket};
@@ -0,0 +1 @@
1
+ const o=/(?:^|;)[^;=]*session_token=([^;]+)/,n=e=>o.exec(e.getCookie())?.[1]??null;export{n as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/react-native",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "React Native / Expo integration for Lunora: an AsyncStorage-backed client factory, the useQuery/useMutation/useSubscription hooks, and a one-call better-auth Expo client",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,8 +50,8 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/client": "1.0.0-alpha.23",
54
- "@lunora/react": "1.0.0-alpha.27"
53
+ "@lunora/client": "1.0.0-alpha.51",
54
+ "@lunora/react": "1.0.0-alpha.55"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "@better-auth/expo": "^1.6.23",
@@ -1,36 +0,0 @@
1
- import { LunoraClient, createAsyncStoragePersistence } from '@lunora/client';
2
-
3
- const withAuthHeaders = (fetchImpl, getAuthHeaders) => (input, init) => {
4
- const extra = getAuthHeaders();
5
- if (!extra) {
6
- return fetchImpl(input, init);
7
- }
8
- const merged = new Headers(extra);
9
- if (init?.headers) {
10
- new Headers(init.headers).forEach((value, key) => {
11
- merged.set(key, value);
12
- });
13
- }
14
- return fetchImpl(input, { ...init, headers: merged });
15
- };
16
- const withAuthWebSocket = (WebSocketImpl, getAuthHeaders) => class AuthWebSocket extends WebSocketImpl {
17
- constructor(url, protocols) {
18
- const headers = getAuthHeaders();
19
- super(url, protocols, headers ? { headers } : void 0);
20
- }
21
- };
22
- const createLunoraClient = (options) => {
23
- const { getAuthHeaders, storage, ...rest } = options;
24
- const authedFetch = getAuthHeaders && rest.fetch === void 0 && typeof fetch === "function" ? withAuthHeaders(fetch.bind(globalThis), getAuthHeaders) : rest.fetch;
25
- const authedWebSocket = getAuthHeaders && rest.WebSocket === void 0 && typeof WebSocket === "function" ? withAuthWebSocket(WebSocket, getAuthHeaders) : rest.WebSocket;
26
- return new LunoraClient({
27
- ...rest,
28
- // Auto-wire AsyncStorage persistence unless the caller passed an explicit
29
- // `persistence` (including `false` to opt out).
30
- persistence: rest.persistence ?? (storage ? createAsyncStoragePersistence({ storage }) : void 0),
31
- fetch: authedFetch,
32
- WebSocket: authedWebSocket
33
- });
34
- };
35
-
36
- export { createLunoraClient, withAuthHeaders, withAuthWebSocket };
@@ -1,7 +0,0 @@
1
- const SESSION_TOKEN_COOKIE = /(?:^|;)[^;=]*session_token=([^;]+)/;
2
- const expoBearerToken = (authClient) => {
3
- const match = SESSION_TOKEN_COOKIE.exec(authClient.getCookie());
4
- return match?.[1] ?? null;
5
- };
6
-
7
- export { expoBearerToken as default };