@basictech/react 0.7.0 → 0.8.0-beta.2

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.
@@ -1,23 +1,24 @@
1
1
 
2
2
  
3
- > @basictech/react@0.7.0-beta.6 build
3
+ > @basictech/react@0.8.0-beta.1 build
4
4
  > tsup
5
5
 
6
6
  CLI Building entry: src/index.ts
7
7
  CLI Using tsconfig: tsconfig.json
8
- CLI tsup v7.2.0
8
+ CLI tsup v8.5.1
9
9
  CLI Using tsup config: /Users/raz/codebook/basic/libs/client-ts/packages/react/tsup.config.ts
10
10
  CLI Target: es2022
11
11
  CLI Cleaning output folder
12
12
  CJS Build start
13
13
  ESM Build start
14
- ESM dist/index.mjs 55.69 KB
15
- ESM dist/index.mjs.map 116.91 KB
16
- ESM ⚡️ Build success in 21ms
17
- CJS dist/index.js 57.98 KB
18
- CJS dist/index.js.map 116.96 KB
19
- CJS ⚡️ Build success in 21ms
20
- DTS Build start
21
- DTS ⚡️ Build success in 1353ms
22
- DTS dist/index.d.ts 9.48 KB
23
- DTS dist/index.d.mts 9.48 KB
14
+ CJS dist/index.js 97.02 KB
15
+ CJS dist/index.js.map 187.81 KB
16
+ CJS ⚡️ Build success in 36ms
17
+ ESM dist/index.mjs 93.09 KB
18
+ ESM dist/index.mjs.map 187.75 KB
19
+ ESM ⚡️ Build success in 37ms
20
+ DTS Build start
21
+ DTS ⚡️ Build success in 1091ms
22
+ DTS dist/index.d.ts 12.66 KB
23
+ DTS dist/index.d.mts 12.66 KB
24
+ ⠙
@@ -13,7 +13,7 @@ This guide provides comprehensive REST API specifications and requirements for i
13
13
  - [Session Management](#session-management)
14
14
  - [Password Management](#password-management)
15
15
  - [Email Verification](#email-verification)
16
- - [Username Availability](#username-availability)
16
+ - [Handle Availability](#handle-availability)
17
17
  - [DID Resolution](#did-resolution)
18
18
  2. [OAuth2 Implementation](#oauth2-implementation)
19
19
  - [Discovery & Configuration](#discovery--configuration)
@@ -36,7 +36,7 @@ This guide provides comprehensive REST API specifications and requirements for i
36
36
 
37
37
  ## PDS Authentication
38
38
 
39
- PDS authentication provides username/password-based authentication with email verification, password reset, and decentralized identifiers (DIDs). This is meant for clients of the PDS server, usually a front-end.
39
+ PDS authentication provides handle/password-based authentication with email verification, password reset, and decentralized identifiers (DIDs). This is meant for clients of the PDS server, usually a front-end.
40
40
 
41
41
  ---
42
42
 
@@ -44,7 +44,7 @@ PDS authentication provides username/password-based authentication with email ve
44
44
 
45
45
  **Endpoint:** `POST /auth/signup`
46
46
 
47
- Create a new user account with username and password.
47
+ Create a new user account with handle and password.
48
48
 
49
49
  #### Request
50
50
 
@@ -54,7 +54,7 @@ Content-Type: application/json
54
54
 
55
55
  {
56
56
  "type": "password",
57
- "username": "john_doe",
57
+ "handle": "john_doe",
58
58
  "password": "securepassword123",
59
59
  "email": "john@example.com",
60
60
  "name": "John Doe"
@@ -66,7 +66,7 @@ Content-Type: application/json
66
66
  | Parameter | Type | Required | Description |
67
67
  |-----------|------|----------|-------------|
68
68
  | `type` | string | Yes | Authentication type. Must be `"password"` |
69
- | `username` | string | Yes | Unique username (alphanumeric, underscores) |
69
+ | `handle` | string | Yes | Unique handle (alphanumeric, 2-30 chars) |
70
70
  | `password` | string | Yes | User password (minimum 3 characters) |
71
71
  | `email` | string | No | User email address (for verification) |
72
72
  | `name` | string | No | User's display name |
@@ -78,7 +78,7 @@ Content-Type: application/json
78
78
  {
79
79
  "data": {
80
80
  "id": "acc_12345",
81
- "username": "john_doe",
81
+ "handle": "john_doe.basic.id",
82
82
  "email": "john@example.com",
83
83
  "name": "John Doe",
84
84
  "created_at": "2025-09-29T10:00:00Z"
@@ -109,7 +109,7 @@ The verification token is valid for **24 hours**.
109
109
 
110
110
  **Endpoint:** `POST /auth/login`
111
111
 
112
- Authenticate with username and password to receive access and refresh tokens.
112
+ Authenticate with handle and password to receive access and refresh tokens.
113
113
 
114
114
  #### Request
115
115
 
@@ -118,7 +118,7 @@ POST /auth/login HTTP/1.1
118
118
  Content-Type: application/json
119
119
 
120
120
  {
121
- "username": "john_doe",
121
+ "handle": "john_doe",
122
122
  "password": "securepassword123"
123
123
  }
124
124
  ```
@@ -127,7 +127,7 @@ Content-Type: application/json
127
127
 
128
128
  | Parameter | Type | Required | Description |
129
129
  |-----------|------|----------|-------------|
130
- | `username` | string | Yes | User's username or email |
130
+ | `handle` | string | Yes | User's handle or email |
131
131
  | `password` | string | Yes | User's password |
132
132
 
133
133
  #### Response
@@ -336,7 +336,7 @@ Content-Type: application/json
336
336
 
337
337
  | Parameter | Type | Required | Description |
338
338
  |-----------|------|----------|-------------|
339
- | `identifier` | string | Yes | User's email or username |
339
+ | `identifier` | string | Yes | User's email or handle |
340
340
 
341
341
  #### Response
342
342
 
@@ -344,7 +344,7 @@ Content-Type: application/json
344
344
  ```json
345
345
  {
346
346
  "success": true,
347
- "message": "If an account with that email/username exists, a password reset link has been sent"
347
+ "message": "If an account with that email/handle exists, a password reset link has been sent"
348
348
  }
349
349
  ```
350
350
 
@@ -507,23 +507,25 @@ Content-Type: application/json
507
507
 
508
508
  ---
509
509
 
510
- ### Username Availability
510
+ ### Handle Availability
511
511
 
512
- **Endpoint:** `GET /auth/check-username`
512
+ **Endpoint:** `GET /auth/check-handle`
513
513
 
514
- Check if a username is available for registration.
514
+ Check if a handle is available for registration.
515
515
 
516
516
  #### Request
517
517
 
518
518
  ```http
519
- GET /auth/check-username?username=john_doe HTTP/1.1
519
+ GET /auth/check-handle?handle=john_doe HTTP/1.1
520
520
  ```
521
521
 
522
+ > **Backward compatibility:** The legacy `GET /auth/check-username` endpoint redirects to `/auth/check-handle`.
523
+
522
524
  #### Query Parameters
523
525
 
524
526
  | Parameter | Type | Required | Description |
525
527
  |-----------|------|----------|-------------|
526
- | `username` | string | Yes | Username to check |
528
+ | `handle` | string | Yes | Handle to check |
527
529
 
528
530
  #### Response
529
531
 
@@ -938,7 +940,7 @@ Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
938
940
  "id": "acc_12345",
939
941
  "name": "John Doe",
940
942
  "email": "john@example.com",
941
- "username": "john_doe"
943
+ "handle_bare": "john_doe"
942
944
  }
943
945
  ```
944
946
 
@@ -1001,7 +1003,7 @@ The server uses a hierarchical scope-based authorization system for fine-grained
1001
1003
 
1002
1004
  | Scope | Description |
1003
1005
  |-------|-------------|
1004
- | `profile:read` | User profile information (name, username) |
1006
+ | `profile:read` | User profile information (name, handle) |
1005
1007
  | `email:read` | User's email address |
1006
1008
  | `openid:read` | OpenID Connect authentication |
1007
1009
 
package/changelog.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # 1.3.4
2
2
 
3
+ ## 0.8.0-beta.2
4
+
5
+ ### Minor Changes
6
+
7
+ - added debug bar
8
+
9
+ ## 0.8.0-beta.1
10
+
11
+ ### Minor Changes
12
+
13
+ - uth updates
14
+
15
+ ## 0.8.0-beta.0
16
+
17
+ ### Minor Changes
18
+
19
+ - Overhaul auth system: extract AuthManager, add PKCE, cross-tab sync, proactive token refresh, enriched error handling, and fix DELETE Content-Type issue
20
+
21
+ ## Unreleased
22
+
23
+ ### Patch Changes
24
+
25
+ - **DBStatus:** Add `ERROR_WILL_RETRY` to align with dexie-syncable status code 4 (error but will retry). Export `DBStatus` enum from the package. Document all `DBStatus` values in readme, including when `ERROR_WILL_RETRY` occurs (e.g. expired token). Enables UI to show "Reconnecting…" or future token refresh on this state.
26
+
3
27
  ## 0.7.0
4
28
 
5
29
  ### Minor Changes
@@ -203,7 +227,6 @@
203
227
  - 96e0156: update schema validation
204
228
  - cda3d16: add schema validation
205
229
  - 2c898ae: update useQuery hook
206
-
207
230
  - no need to pass param as a function, can now enter query directly
208
231
  - defaults to empty array when loading
209
232
 
@@ -259,7 +282,6 @@
259
282
  ### Minor Changes
260
283
 
261
284
  - update useQuery hook
262
-
263
285
  - no need to pass param as a function, can now enter query directly
264
286
  - defaults to empty array when loading
265
287
 
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React from 'react';
2
+ import react from 'react';
3
3
  export { useLiveQuery as useQuery } from 'dexie-react-hooks';
4
4
 
5
5
  /**
@@ -92,6 +92,10 @@ interface AuthError {
92
92
  status: number;
93
93
  message: string;
94
94
  response?: any;
95
+ /** Classifies the error for UI display (e.g. "session expired" vs "forbidden") */
96
+ errorType: 'expired' | 'forbidden' | 'revoked' | 'network' | 'unknown';
97
+ /** True if this error occurred after a retry with a refreshed token */
98
+ afterRetry: boolean;
95
99
  }
96
100
  /**
97
101
  * Custom error class for Remote DB API errors
@@ -102,13 +106,20 @@ declare class RemoteDBError extends Error {
102
106
  response?: any;
103
107
  constructor(message: string, status: number, response?: any);
104
108
  }
109
+ /**
110
+ * Options for getToken (e.g. force refresh after 401)
111
+ */
112
+ interface GetTokenOptions$1 {
113
+ /** When true, refresh the access token before returning (e.g. after server returned 401) */
114
+ forceRefresh?: boolean;
115
+ }
105
116
  /**
106
117
  * Configuration for RemoteDB
107
118
  */
108
119
  interface RemoteDBConfig {
109
120
  serverUrl: string;
110
121
  projectId: string;
111
- getToken: () => Promise<string>;
122
+ getToken: (options?: GetTokenOptions$1) => Promise<string>;
112
123
  schema?: any;
113
124
  /** Enable debug logging (default: false) */
114
125
  debug?: boolean;
@@ -233,57 +244,45 @@ declare const STORAGE_KEYS: {
233
244
  readonly AUTH_STATE: "basic_auth_state";
234
245
  readonly REDIRECT_URI: "basic_redirect_uri";
235
246
  readonly SERVER_URL: "basic_server_url";
247
+ readonly PDS_ENDPOINTS: "basic_pds_endpoints";
248
+ readonly LAST_CONNECT_REPORT: "basic_last_connect_report";
236
249
  readonly DEBUG: "basic_debug";
250
+ readonly CODE_VERIFIER: "basic_code_verifier";
237
251
  };
238
252
 
239
- type AuthConfig = {
240
- scopes?: string | string[];
241
- server_url?: string;
242
- ws_url?: string;
253
+ type User = {
254
+ sub?: string;
255
+ name?: string;
256
+ email?: string;
257
+ picture?: string;
243
258
  };
244
- type BasicProviderProps = {
245
- children: React.ReactNode;
246
- /**
247
- * @deprecated Project ID is now extracted from schema.project_id.
248
- * This prop is kept for backward compatibility but can be omitted.
249
- */
250
- project_id?: string;
251
- /** The Basic schema object containing project_id and table definitions */
252
- schema?: any;
253
- debug?: boolean;
254
- storage?: BasicStorage;
255
- auth?: AuthConfig;
256
- /**
257
- * Database mode - determines which implementation is used
258
- * - 'sync': Uses Dexie + WebSocket for local-first sync (default)
259
- * - 'remote': Uses REST API calls directly to server
260
- */
261
- dbMode?: DBMode;
259
+ type AuthResult = {
260
+ success: boolean;
261
+ error?: string;
262
+ code?: string;
263
+ };
264
+ type GetTokenOptions = {
265
+ forceRefresh?: boolean;
262
266
  };
267
+
263
268
  declare enum DBStatus {
264
269
  LOADING = "LOADING",
265
270
  OFFLINE = "OFFLINE",
266
271
  CONNECTING = "CONNECTING",
267
272
  ONLINE = "ONLINE",
268
273
  SYNCING = "SYNCING",
269
- ERROR = "ERROR"
274
+ ERROR = "ERROR",
275
+ ERROR_WILL_RETRY = "ERROR_WILL_RETRY",
276
+ ERROR_TOKEN_EXPIRED = "ERROR_TOKEN_EXPIRED"
270
277
  }
271
- type User = {
272
- name?: string;
273
- email?: string;
274
- id?: string;
275
- primaryEmailAddress?: {
276
- emailAddress: string;
277
- };
278
- fullName?: string;
279
- };
280
- /**
281
- * Auth result type for signInWithCode
282
- */
283
- type AuthResult = {
284
- success: boolean;
278
+ /** Snapshot of local schema vs server (for dev toolbar and debugging). */
279
+ type BasicSchemaDevInfo = {
280
+ projectId: string | null;
281
+ localVersion: number | undefined;
282
+ status: string;
283
+ valid: boolean;
284
+ lastCheckedAt: number;
285
285
  error?: string;
286
- code?: string;
287
286
  };
288
287
  /**
289
288
  * Context type for useBasic hook
@@ -292,26 +291,100 @@ type BasicContextType = {
292
291
  isReady: boolean;
293
292
  isSignedIn: boolean;
294
293
  user: User | null;
294
+ did: string | null;
295
+ scope: string | null;
296
+ hasScope: (scope: string) => boolean;
297
+ missingScopes: () => string[];
295
298
  signIn: () => Promise<void>;
299
+ signInWithHandle: (handle: string) => Promise<void>;
296
300
  signOut: () => Promise<void>;
297
301
  signInWithCode: (code: string, state?: string) => Promise<AuthResult>;
298
- getToken: () => Promise<string>;
302
+ getToken: (options?: GetTokenOptions) => Promise<string>;
299
303
  getSignInUrl: (redirectUri?: string) => Promise<string>;
300
304
  db: BasicDB;
301
305
  dbStatus: DBStatus;
302
306
  dbMode: DBMode;
303
- /** @deprecated Use isReady instead */
307
+ /** Local schema vs server status; null if no schema on the provider. */
308
+ devInfo: BasicSchemaDevInfo | null;
309
+ /** Re-run remote schema check (dev toolbar). */
310
+ refreshSchemaStatus: () => Promise<void>;
304
311
  isAuthReady: boolean;
305
- /** @deprecated Use signIn instead */
306
312
  signin: () => Promise<void>;
307
- /** @deprecated Use signOut instead */
308
313
  signout: () => Promise<void>;
309
- /** @deprecated Use signInWithCode instead */
310
314
  signinWithCode: (code: string, state?: string) => Promise<AuthResult>;
311
- /** @deprecated Use getSignInUrl instead */
312
315
  getSignInLink: (redirectUri?: string) => Promise<string>;
313
316
  };
314
- declare function BasicProvider({ children, project_id: project_id_prop, schema, debug, storage, auth, dbMode }: BasicProviderProps): react_jsx_runtime.JSX.Element;
315
317
  declare function useBasic(): BasicContextType;
316
318
 
317
- export { AuthConfig, AuthError, AuthResult, BasicContextType, BasicDB, BasicProvider, BasicProviderProps, BasicStorage, Collection, DBMode, LocalStorageAdapter, NotAuthenticatedError, RemoteCollection, RemoteDB, RemoteDBConfig, RemoteDBError, STORAGE_KEYS, useBasic };
319
+ type AuthConfig = {
320
+ scopes?: string | string[];
321
+ /** @deprecated Use pds_url instead */
322
+ server_url?: string;
323
+ /** PDS URL for auth and data (default: https://pds.basic.id) */
324
+ pds_url?: string;
325
+ /** Admin server URL for connect reporting (default: https://api.basic.tech) */
326
+ admin_url?: string;
327
+ ws_url?: string;
328
+ };
329
+ type BasicProviderProps = {
330
+ children: react.ReactNode;
331
+ /**
332
+ * @deprecated Project ID is now extracted from schema.project_id.
333
+ * This prop is kept for backward compatibility but can be omitted.
334
+ */
335
+ project_id?: string;
336
+ /** The Basic schema object containing project_id and table definitions */
337
+ schema?: any;
338
+ debug?: boolean;
339
+ storage?: BasicStorage;
340
+ auth?: AuthConfig;
341
+ /**
342
+ * Database mode - determines which implementation is used
343
+ * - 'sync': Uses Dexie + WebSocket for local-first sync (default)
344
+ * - 'remote': Uses REST API calls directly to server
345
+ */
346
+ dbMode?: DBMode;
347
+ /** Show floating dev toolbar (localhost, NODE_ENV=development, or debug=true). */
348
+ devToolbar?: boolean;
349
+ };
350
+ declare function BasicProvider({ children, project_id: project_id_prop, schema, debug, storage, auth, dbMode, devToolbar, }: BasicProviderProps): react_jsx_runtime.JSX.Element;
351
+
352
+ type BasicDevToolbarProps = {
353
+ /** When false, toolbar does not render. Defaults to true when used standalone. */
354
+ enabled?: boolean;
355
+ /** Same as BasicProvider `debug` — when true, toolbar shows even off localhost. */
356
+ debug?: boolean;
357
+ };
358
+ /**
359
+ * Floating dev-only toolbar: auth, DB/sync, and schema status. Requires `BasicProvider` with `debug` or localhost / NODE_ENV=development for visibility unless `enabled` is forced.
360
+ */
361
+ declare function BasicDevToolbar({ enabled, debug }: BasicDevToolbarProps): react_jsx_runtime.JSX.Element | null;
362
+
363
+ type ResolvedDid = {
364
+ did: string;
365
+ handle?: string;
366
+ didDocument: Record<string, unknown>;
367
+ pdsUrl: string;
368
+ authorization_endpoint: string;
369
+ token_endpoint: string;
370
+ userinfo_endpoint: string;
371
+ };
372
+ /**
373
+ * Convert a did:web DID to the HTTPS URL where its DID document lives.
374
+ *
375
+ * did:web:pds.basic.id:did:abc123 -> https://pds.basic.id/did/abc123/did.json
376
+ * did:web:example.com -> https://example.com/.well-known/did.json
377
+ */
378
+ declare function resolveDidWebUrl(did: string): string | null;
379
+ /**
380
+ * Fetch a DID document by DID, extract the PDS URL, and discover OAuth endpoints.
381
+ */
382
+ declare function resolveDid(did: string): Promise<ResolvedDid>;
383
+ /**
384
+ * Resolve a handle (e.g. "alice.basic.id") to a DID and discover PDS + OAuth endpoints.
385
+ *
386
+ * Fetches https://{handle}/.well-known/did.json per the did:web spec.
387
+ */
388
+ declare function resolveHandle(handle: string): Promise<ResolvedDid>;
389
+
390
+ export { type AuthConfig, type AuthError, type AuthResult, type BasicContextType, type BasicDB, BasicDevToolbar, type BasicDevToolbarProps, BasicProvider, type BasicProviderProps, type BasicSchemaDevInfo, type BasicStorage, type Collection, type DBMode, DBStatus, type GetTokenOptions$1 as GetTokenOptions, LocalStorageAdapter, NotAuthenticatedError, RemoteCollection, RemoteDB, type RemoteDBConfig, RemoteDBError, type ResolvedDid, STORAGE_KEYS, resolveDid, resolveDidWebUrl, resolveHandle, useBasic };