@basictech/react 0.7.0-beta.6 → 0.7.0-beta.7
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/.turbo/turbo-build.log +10 -10
- package/changelog.md +6 -0
- package/dist/index.d.mts +266 -13
- package/dist/index.d.ts +266 -13
- package/dist/index.js +645 -184
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +625 -172
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/readme.md +203 -209
- package/src/AuthContext.tsx +183 -53
- package/src/core/db/RemoteCollection.ts +294 -0
- package/src/core/db/RemoteDB.ts +40 -0
- package/src/core/db/index.ts +7 -0
- package/src/core/db/types.ts +128 -0
- package/src/index.ts +25 -9
- package/src/sync/index.ts +133 -54
- package/src/db.ts +0 -55
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @basictech/react@0.7.0-beta.
|
|
3
|
+
> @basictech/react@0.7.0-beta.6 build
|
|
4
4
|
> tsup
|
|
5
5
|
|
|
6
6
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
[34mCLI[39m Cleaning output folder
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
13
|
[34mESM[39m Build start
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
19
|
-
[
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m55.69 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m116.91 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 21ms
|
|
17
|
+
[32mCJS[39m [1mdist/index.js [22m[32m57.98 KB[39m
|
|
18
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m116.96 KB[39m
|
|
19
|
+
[32mCJS[39m ⚡️ Build success in 21ms
|
|
20
20
|
[34mDTS[39m Build start
|
|
21
|
-
[32mDTS[39m ⚡️ Build success in
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
23
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[
|
|
21
|
+
[32mDTS[39m ⚡️ Build success in 1353ms
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m9.48 KB[39m
|
|
23
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m9.48 KB[39m
|
package/changelog.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,221 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
export { useLiveQuery as useQuery } from 'dexie-react-hooks';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Core DB types for Basic SDK
|
|
7
|
+
* These interfaces are implemented by both SyncDB (Dexie-based) and RemoteDB (REST-based)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Collection interface for CRUD operations on a table
|
|
11
|
+
* All write operations return the full object (not just the id)
|
|
12
|
+
*/
|
|
13
|
+
interface Collection<T extends {
|
|
14
|
+
id: string;
|
|
15
|
+
} = Record<string, any> & {
|
|
16
|
+
id: string;
|
|
17
|
+
}> {
|
|
18
|
+
/**
|
|
19
|
+
* Add a new record to the collection
|
|
20
|
+
* @param data - The data to add (without id, which will be generated)
|
|
21
|
+
* @returns The created object with its generated id
|
|
22
|
+
*/
|
|
23
|
+
add(data: Omit<T, 'id'>): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Put (upsert) a record - requires id
|
|
26
|
+
* @param data - The full object including id
|
|
27
|
+
* @returns The upserted object
|
|
28
|
+
*/
|
|
29
|
+
put(data: T): Promise<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Update an existing record by id
|
|
32
|
+
* @param id - The record id to update
|
|
33
|
+
* @param data - Partial data to merge
|
|
34
|
+
* @returns The updated object, or null if not found
|
|
35
|
+
*/
|
|
36
|
+
update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete a record by id
|
|
39
|
+
* @param id - The record id to delete
|
|
40
|
+
* @returns true if deleted, false if not found
|
|
41
|
+
*/
|
|
42
|
+
delete(id: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Get a single record by id
|
|
45
|
+
* @param id - The record id to fetch
|
|
46
|
+
* @returns The object or null if not found
|
|
47
|
+
*/
|
|
48
|
+
get(id: string): Promise<T | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Get all records in the collection
|
|
51
|
+
* @returns Array of all objects
|
|
52
|
+
*/
|
|
53
|
+
getAll(): Promise<T[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Filter records using a predicate function
|
|
56
|
+
* @param fn - Filter function that returns true for matches
|
|
57
|
+
* @returns Array of matching objects
|
|
58
|
+
*/
|
|
59
|
+
filter(fn: (item: T) => boolean): Promise<T[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Direct access to underlying storage (optional)
|
|
62
|
+
* For sync mode: Dexie table reference
|
|
63
|
+
* For remote mode: undefined
|
|
64
|
+
*/
|
|
65
|
+
ref?: any;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* BasicDB interface - factory for creating collections
|
|
69
|
+
*/
|
|
70
|
+
interface BasicDB {
|
|
71
|
+
/**
|
|
72
|
+
* Get a collection by name
|
|
73
|
+
* @param name - The table/collection name (must match schema)
|
|
74
|
+
* @returns A Collection instance for CRUD operations
|
|
75
|
+
*/
|
|
76
|
+
collection<T extends {
|
|
77
|
+
id: string;
|
|
78
|
+
} = Record<string, any> & {
|
|
79
|
+
id: string;
|
|
80
|
+
}>(name: string): Collection<T>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Database mode - determines which implementation is used
|
|
84
|
+
* - 'sync': Uses Dexie + WebSocket for local-first sync (default)
|
|
85
|
+
* - 'remote': Uses REST API calls directly to server
|
|
86
|
+
*/
|
|
87
|
+
type DBMode = 'sync' | 'remote';
|
|
88
|
+
/**
|
|
89
|
+
* Auth error information passed to onAuthError callback
|
|
90
|
+
*/
|
|
91
|
+
interface AuthError {
|
|
92
|
+
status: number;
|
|
93
|
+
message: string;
|
|
94
|
+
response?: any;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Custom error class for Remote DB API errors
|
|
98
|
+
* Includes HTTP status code for reliable error handling
|
|
99
|
+
*/
|
|
100
|
+
declare class RemoteDBError extends Error {
|
|
101
|
+
status: number;
|
|
102
|
+
response?: any;
|
|
103
|
+
constructor(message: string, status: number, response?: any);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Configuration for RemoteDB
|
|
107
|
+
*/
|
|
108
|
+
interface RemoteDBConfig {
|
|
109
|
+
serverUrl: string;
|
|
110
|
+
projectId: string;
|
|
111
|
+
getToken: () => Promise<string>;
|
|
112
|
+
schema?: any;
|
|
113
|
+
/** Enable debug logging (default: false) */
|
|
114
|
+
debug?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Optional callback when authentication fails (401 error after retry)
|
|
117
|
+
* Use this to show login UI or redirect to sign-in
|
|
118
|
+
*/
|
|
119
|
+
onAuthError?: (error: AuthError) => void;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* RemoteDB - REST API based implementation of BasicDB
|
|
124
|
+
* Creates RemoteCollection instances for each table
|
|
125
|
+
*/
|
|
126
|
+
declare class RemoteDB implements BasicDB {
|
|
127
|
+
private config;
|
|
128
|
+
private collections;
|
|
129
|
+
constructor(config: RemoteDBConfig);
|
|
130
|
+
/**
|
|
131
|
+
* Get a collection by name
|
|
132
|
+
* Collections are cached for reuse
|
|
133
|
+
*/
|
|
134
|
+
collection<T extends {
|
|
135
|
+
id: string;
|
|
136
|
+
} = Record<string, any> & {
|
|
137
|
+
id: string;
|
|
138
|
+
}>(name: string): Collection<T>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Error thrown when user is not authenticated
|
|
143
|
+
*/
|
|
144
|
+
declare class NotAuthenticatedError extends Error {
|
|
145
|
+
constructor(message?: string);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* RemoteCollection - REST API based implementation of the Collection interface
|
|
149
|
+
* All operations make HTTP calls to the Basic API server
|
|
150
|
+
*/
|
|
151
|
+
declare class RemoteCollection<T extends {
|
|
152
|
+
id: string;
|
|
153
|
+
} = Record<string, any> & {
|
|
154
|
+
id: string;
|
|
155
|
+
}> implements Collection<T> {
|
|
156
|
+
private tableName;
|
|
157
|
+
private config;
|
|
158
|
+
constructor(tableName: string, config: RemoteDBConfig);
|
|
159
|
+
private log;
|
|
160
|
+
/**
|
|
161
|
+
* Check if an error is a "not authenticated" error
|
|
162
|
+
*/
|
|
163
|
+
private isNotAuthenticatedError;
|
|
164
|
+
/**
|
|
165
|
+
* Helper to make authenticated API requests
|
|
166
|
+
* Automatically retries once on 401 (token expired) by refreshing the token
|
|
167
|
+
*/
|
|
168
|
+
private request;
|
|
169
|
+
/**
|
|
170
|
+
* Validate data against schema if available
|
|
171
|
+
*/
|
|
172
|
+
private validateData;
|
|
173
|
+
/**
|
|
174
|
+
* Get the base path for this collection
|
|
175
|
+
*/
|
|
176
|
+
private get basePath();
|
|
177
|
+
/**
|
|
178
|
+
* Add a new record to the collection
|
|
179
|
+
* The server generates the ID
|
|
180
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
181
|
+
*/
|
|
182
|
+
add(data: Omit<T, 'id'>): Promise<T>;
|
|
183
|
+
/**
|
|
184
|
+
* Put (upsert) a record - requires id
|
|
185
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
186
|
+
*/
|
|
187
|
+
put(data: T): Promise<T>;
|
|
188
|
+
/**
|
|
189
|
+
* Update an existing record by id
|
|
190
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
191
|
+
*/
|
|
192
|
+
update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>;
|
|
193
|
+
/**
|
|
194
|
+
* Delete a record by id
|
|
195
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
196
|
+
*/
|
|
197
|
+
delete(id: string): Promise<boolean>;
|
|
198
|
+
/**
|
|
199
|
+
* Get a single record by id
|
|
200
|
+
* Returns null if not authenticated (graceful degradation for read operations)
|
|
201
|
+
*/
|
|
202
|
+
get(id: string): Promise<T | null>;
|
|
203
|
+
/**
|
|
204
|
+
* Get all records in the collection
|
|
205
|
+
* Returns empty array if not authenticated (graceful degradation for read operations)
|
|
206
|
+
*/
|
|
207
|
+
getAll(): Promise<T[]>;
|
|
208
|
+
/**
|
|
209
|
+
* Filter records using a predicate function
|
|
210
|
+
* Note: This fetches all records and filters client-side
|
|
211
|
+
* Returns empty array if not authenticated (graceful degradation for read operations)
|
|
212
|
+
*/
|
|
213
|
+
filter(fn: (item: T) => boolean): Promise<T[]>;
|
|
214
|
+
/**
|
|
215
|
+
* ref is not available for remote collections
|
|
216
|
+
*/
|
|
217
|
+
ref: undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
5
220
|
interface BasicStorage {
|
|
6
221
|
get(key: string): Promise<string | null>;
|
|
7
222
|
set(key: string, value: string): Promise<void>;
|
|
@@ -12,6 +227,14 @@ declare class LocalStorageAdapter implements BasicStorage {
|
|
|
12
227
|
set(key: string, value: string): Promise<void>;
|
|
13
228
|
remove(key: string): Promise<void>;
|
|
14
229
|
}
|
|
230
|
+
declare const STORAGE_KEYS: {
|
|
231
|
+
readonly REFRESH_TOKEN: "basic_refresh_token";
|
|
232
|
+
readonly USER_INFO: "basic_user_info";
|
|
233
|
+
readonly AUTH_STATE: "basic_auth_state";
|
|
234
|
+
readonly REDIRECT_URI: "basic_redirect_uri";
|
|
235
|
+
readonly SERVER_URL: "basic_server_url";
|
|
236
|
+
readonly DEBUG: "basic_debug";
|
|
237
|
+
};
|
|
15
238
|
|
|
16
239
|
type AuthConfig = {
|
|
17
240
|
scopes?: string | string[];
|
|
@@ -20,11 +243,22 @@ type AuthConfig = {
|
|
|
20
243
|
};
|
|
21
244
|
type BasicProviderProps = {
|
|
22
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
|
+
*/
|
|
23
250
|
project_id?: string;
|
|
251
|
+
/** The Basic schema object containing project_id and table definitions */
|
|
24
252
|
schema?: any;
|
|
25
253
|
debug?: boolean;
|
|
26
254
|
storage?: BasicStorage;
|
|
27
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;
|
|
28
262
|
};
|
|
29
263
|
declare enum DBStatus {
|
|
30
264
|
LOADING = "LOADING",
|
|
@@ -43,22 +277,41 @@ type User = {
|
|
|
43
277
|
};
|
|
44
278
|
fullName?: string;
|
|
45
279
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
280
|
+
/**
|
|
281
|
+
* Auth result type for signInWithCode
|
|
282
|
+
*/
|
|
283
|
+
type AuthResult = {
|
|
284
|
+
success: boolean;
|
|
285
|
+
error?: string;
|
|
286
|
+
code?: string;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Context type for useBasic hook
|
|
290
|
+
*/
|
|
291
|
+
type BasicContextType = {
|
|
292
|
+
isReady: boolean;
|
|
50
293
|
isSignedIn: boolean;
|
|
51
294
|
user: User | null;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
success: boolean;
|
|
56
|
-
error?: string;
|
|
57
|
-
}>;
|
|
295
|
+
signIn: () => Promise<void>;
|
|
296
|
+
signOut: () => Promise<void>;
|
|
297
|
+
signInWithCode: (code: string, state?: string) => Promise<AuthResult>;
|
|
58
298
|
getToken: () => Promise<string>;
|
|
59
|
-
|
|
60
|
-
db:
|
|
299
|
+
getSignInUrl: (redirectUri?: string) => Promise<string>;
|
|
300
|
+
db: BasicDB;
|
|
61
301
|
dbStatus: DBStatus;
|
|
302
|
+
dbMode: DBMode;
|
|
303
|
+
/** @deprecated Use isReady instead */
|
|
304
|
+
isAuthReady: boolean;
|
|
305
|
+
/** @deprecated Use signIn instead */
|
|
306
|
+
signin: () => Promise<void>;
|
|
307
|
+
/** @deprecated Use signOut instead */
|
|
308
|
+
signout: () => Promise<void>;
|
|
309
|
+
/** @deprecated Use signInWithCode instead */
|
|
310
|
+
signinWithCode: (code: string, state?: string) => Promise<AuthResult>;
|
|
311
|
+
/** @deprecated Use getSignInUrl instead */
|
|
312
|
+
getSignInLink: (redirectUri?: string) => Promise<string>;
|
|
62
313
|
};
|
|
314
|
+
declare function BasicProvider({ children, project_id: project_id_prop, schema, debug, storage, auth, dbMode }: BasicProviderProps): react_jsx_runtime.JSX.Element;
|
|
315
|
+
declare function useBasic(): BasicContextType;
|
|
63
316
|
|
|
64
|
-
export { AuthConfig, BasicProvider, BasicProviderProps, BasicStorage, LocalStorageAdapter, useBasic };
|
|
317
|
+
export { AuthConfig, AuthError, AuthResult, BasicContextType, BasicDB, BasicProvider, BasicProviderProps, BasicStorage, Collection, DBMode, LocalStorageAdapter, NotAuthenticatedError, RemoteCollection, RemoteDB, RemoteDBConfig, RemoteDBError, STORAGE_KEYS, useBasic };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,221 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
export { useLiveQuery as useQuery } from 'dexie-react-hooks';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Core DB types for Basic SDK
|
|
7
|
+
* These interfaces are implemented by both SyncDB (Dexie-based) and RemoteDB (REST-based)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Collection interface for CRUD operations on a table
|
|
11
|
+
* All write operations return the full object (not just the id)
|
|
12
|
+
*/
|
|
13
|
+
interface Collection<T extends {
|
|
14
|
+
id: string;
|
|
15
|
+
} = Record<string, any> & {
|
|
16
|
+
id: string;
|
|
17
|
+
}> {
|
|
18
|
+
/**
|
|
19
|
+
* Add a new record to the collection
|
|
20
|
+
* @param data - The data to add (without id, which will be generated)
|
|
21
|
+
* @returns The created object with its generated id
|
|
22
|
+
*/
|
|
23
|
+
add(data: Omit<T, 'id'>): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Put (upsert) a record - requires id
|
|
26
|
+
* @param data - The full object including id
|
|
27
|
+
* @returns The upserted object
|
|
28
|
+
*/
|
|
29
|
+
put(data: T): Promise<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Update an existing record by id
|
|
32
|
+
* @param id - The record id to update
|
|
33
|
+
* @param data - Partial data to merge
|
|
34
|
+
* @returns The updated object, or null if not found
|
|
35
|
+
*/
|
|
36
|
+
update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete a record by id
|
|
39
|
+
* @param id - The record id to delete
|
|
40
|
+
* @returns true if deleted, false if not found
|
|
41
|
+
*/
|
|
42
|
+
delete(id: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Get a single record by id
|
|
45
|
+
* @param id - The record id to fetch
|
|
46
|
+
* @returns The object or null if not found
|
|
47
|
+
*/
|
|
48
|
+
get(id: string): Promise<T | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Get all records in the collection
|
|
51
|
+
* @returns Array of all objects
|
|
52
|
+
*/
|
|
53
|
+
getAll(): Promise<T[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Filter records using a predicate function
|
|
56
|
+
* @param fn - Filter function that returns true for matches
|
|
57
|
+
* @returns Array of matching objects
|
|
58
|
+
*/
|
|
59
|
+
filter(fn: (item: T) => boolean): Promise<T[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Direct access to underlying storage (optional)
|
|
62
|
+
* For sync mode: Dexie table reference
|
|
63
|
+
* For remote mode: undefined
|
|
64
|
+
*/
|
|
65
|
+
ref?: any;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* BasicDB interface - factory for creating collections
|
|
69
|
+
*/
|
|
70
|
+
interface BasicDB {
|
|
71
|
+
/**
|
|
72
|
+
* Get a collection by name
|
|
73
|
+
* @param name - The table/collection name (must match schema)
|
|
74
|
+
* @returns A Collection instance for CRUD operations
|
|
75
|
+
*/
|
|
76
|
+
collection<T extends {
|
|
77
|
+
id: string;
|
|
78
|
+
} = Record<string, any> & {
|
|
79
|
+
id: string;
|
|
80
|
+
}>(name: string): Collection<T>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Database mode - determines which implementation is used
|
|
84
|
+
* - 'sync': Uses Dexie + WebSocket for local-first sync (default)
|
|
85
|
+
* - 'remote': Uses REST API calls directly to server
|
|
86
|
+
*/
|
|
87
|
+
type DBMode = 'sync' | 'remote';
|
|
88
|
+
/**
|
|
89
|
+
* Auth error information passed to onAuthError callback
|
|
90
|
+
*/
|
|
91
|
+
interface AuthError {
|
|
92
|
+
status: number;
|
|
93
|
+
message: string;
|
|
94
|
+
response?: any;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Custom error class for Remote DB API errors
|
|
98
|
+
* Includes HTTP status code for reliable error handling
|
|
99
|
+
*/
|
|
100
|
+
declare class RemoteDBError extends Error {
|
|
101
|
+
status: number;
|
|
102
|
+
response?: any;
|
|
103
|
+
constructor(message: string, status: number, response?: any);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Configuration for RemoteDB
|
|
107
|
+
*/
|
|
108
|
+
interface RemoteDBConfig {
|
|
109
|
+
serverUrl: string;
|
|
110
|
+
projectId: string;
|
|
111
|
+
getToken: () => Promise<string>;
|
|
112
|
+
schema?: any;
|
|
113
|
+
/** Enable debug logging (default: false) */
|
|
114
|
+
debug?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Optional callback when authentication fails (401 error after retry)
|
|
117
|
+
* Use this to show login UI or redirect to sign-in
|
|
118
|
+
*/
|
|
119
|
+
onAuthError?: (error: AuthError) => void;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* RemoteDB - REST API based implementation of BasicDB
|
|
124
|
+
* Creates RemoteCollection instances for each table
|
|
125
|
+
*/
|
|
126
|
+
declare class RemoteDB implements BasicDB {
|
|
127
|
+
private config;
|
|
128
|
+
private collections;
|
|
129
|
+
constructor(config: RemoteDBConfig);
|
|
130
|
+
/**
|
|
131
|
+
* Get a collection by name
|
|
132
|
+
* Collections are cached for reuse
|
|
133
|
+
*/
|
|
134
|
+
collection<T extends {
|
|
135
|
+
id: string;
|
|
136
|
+
} = Record<string, any> & {
|
|
137
|
+
id: string;
|
|
138
|
+
}>(name: string): Collection<T>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Error thrown when user is not authenticated
|
|
143
|
+
*/
|
|
144
|
+
declare class NotAuthenticatedError extends Error {
|
|
145
|
+
constructor(message?: string);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* RemoteCollection - REST API based implementation of the Collection interface
|
|
149
|
+
* All operations make HTTP calls to the Basic API server
|
|
150
|
+
*/
|
|
151
|
+
declare class RemoteCollection<T extends {
|
|
152
|
+
id: string;
|
|
153
|
+
} = Record<string, any> & {
|
|
154
|
+
id: string;
|
|
155
|
+
}> implements Collection<T> {
|
|
156
|
+
private tableName;
|
|
157
|
+
private config;
|
|
158
|
+
constructor(tableName: string, config: RemoteDBConfig);
|
|
159
|
+
private log;
|
|
160
|
+
/**
|
|
161
|
+
* Check if an error is a "not authenticated" error
|
|
162
|
+
*/
|
|
163
|
+
private isNotAuthenticatedError;
|
|
164
|
+
/**
|
|
165
|
+
* Helper to make authenticated API requests
|
|
166
|
+
* Automatically retries once on 401 (token expired) by refreshing the token
|
|
167
|
+
*/
|
|
168
|
+
private request;
|
|
169
|
+
/**
|
|
170
|
+
* Validate data against schema if available
|
|
171
|
+
*/
|
|
172
|
+
private validateData;
|
|
173
|
+
/**
|
|
174
|
+
* Get the base path for this collection
|
|
175
|
+
*/
|
|
176
|
+
private get basePath();
|
|
177
|
+
/**
|
|
178
|
+
* Add a new record to the collection
|
|
179
|
+
* The server generates the ID
|
|
180
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
181
|
+
*/
|
|
182
|
+
add(data: Omit<T, 'id'>): Promise<T>;
|
|
183
|
+
/**
|
|
184
|
+
* Put (upsert) a record - requires id
|
|
185
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
186
|
+
*/
|
|
187
|
+
put(data: T): Promise<T>;
|
|
188
|
+
/**
|
|
189
|
+
* Update an existing record by id
|
|
190
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
191
|
+
*/
|
|
192
|
+
update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>;
|
|
193
|
+
/**
|
|
194
|
+
* Delete a record by id
|
|
195
|
+
* Requires authentication - throws NotAuthenticatedError if not signed in
|
|
196
|
+
*/
|
|
197
|
+
delete(id: string): Promise<boolean>;
|
|
198
|
+
/**
|
|
199
|
+
* Get a single record by id
|
|
200
|
+
* Returns null if not authenticated (graceful degradation for read operations)
|
|
201
|
+
*/
|
|
202
|
+
get(id: string): Promise<T | null>;
|
|
203
|
+
/**
|
|
204
|
+
* Get all records in the collection
|
|
205
|
+
* Returns empty array if not authenticated (graceful degradation for read operations)
|
|
206
|
+
*/
|
|
207
|
+
getAll(): Promise<T[]>;
|
|
208
|
+
/**
|
|
209
|
+
* Filter records using a predicate function
|
|
210
|
+
* Note: This fetches all records and filters client-side
|
|
211
|
+
* Returns empty array if not authenticated (graceful degradation for read operations)
|
|
212
|
+
*/
|
|
213
|
+
filter(fn: (item: T) => boolean): Promise<T[]>;
|
|
214
|
+
/**
|
|
215
|
+
* ref is not available for remote collections
|
|
216
|
+
*/
|
|
217
|
+
ref: undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
5
220
|
interface BasicStorage {
|
|
6
221
|
get(key: string): Promise<string | null>;
|
|
7
222
|
set(key: string, value: string): Promise<void>;
|
|
@@ -12,6 +227,14 @@ declare class LocalStorageAdapter implements BasicStorage {
|
|
|
12
227
|
set(key: string, value: string): Promise<void>;
|
|
13
228
|
remove(key: string): Promise<void>;
|
|
14
229
|
}
|
|
230
|
+
declare const STORAGE_KEYS: {
|
|
231
|
+
readonly REFRESH_TOKEN: "basic_refresh_token";
|
|
232
|
+
readonly USER_INFO: "basic_user_info";
|
|
233
|
+
readonly AUTH_STATE: "basic_auth_state";
|
|
234
|
+
readonly REDIRECT_URI: "basic_redirect_uri";
|
|
235
|
+
readonly SERVER_URL: "basic_server_url";
|
|
236
|
+
readonly DEBUG: "basic_debug";
|
|
237
|
+
};
|
|
15
238
|
|
|
16
239
|
type AuthConfig = {
|
|
17
240
|
scopes?: string | string[];
|
|
@@ -20,11 +243,22 @@ type AuthConfig = {
|
|
|
20
243
|
};
|
|
21
244
|
type BasicProviderProps = {
|
|
22
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
|
+
*/
|
|
23
250
|
project_id?: string;
|
|
251
|
+
/** The Basic schema object containing project_id and table definitions */
|
|
24
252
|
schema?: any;
|
|
25
253
|
debug?: boolean;
|
|
26
254
|
storage?: BasicStorage;
|
|
27
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;
|
|
28
262
|
};
|
|
29
263
|
declare enum DBStatus {
|
|
30
264
|
LOADING = "LOADING",
|
|
@@ -43,22 +277,41 @@ type User = {
|
|
|
43
277
|
};
|
|
44
278
|
fullName?: string;
|
|
45
279
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
280
|
+
/**
|
|
281
|
+
* Auth result type for signInWithCode
|
|
282
|
+
*/
|
|
283
|
+
type AuthResult = {
|
|
284
|
+
success: boolean;
|
|
285
|
+
error?: string;
|
|
286
|
+
code?: string;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Context type for useBasic hook
|
|
290
|
+
*/
|
|
291
|
+
type BasicContextType = {
|
|
292
|
+
isReady: boolean;
|
|
50
293
|
isSignedIn: boolean;
|
|
51
294
|
user: User | null;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
success: boolean;
|
|
56
|
-
error?: string;
|
|
57
|
-
}>;
|
|
295
|
+
signIn: () => Promise<void>;
|
|
296
|
+
signOut: () => Promise<void>;
|
|
297
|
+
signInWithCode: (code: string, state?: string) => Promise<AuthResult>;
|
|
58
298
|
getToken: () => Promise<string>;
|
|
59
|
-
|
|
60
|
-
db:
|
|
299
|
+
getSignInUrl: (redirectUri?: string) => Promise<string>;
|
|
300
|
+
db: BasicDB;
|
|
61
301
|
dbStatus: DBStatus;
|
|
302
|
+
dbMode: DBMode;
|
|
303
|
+
/** @deprecated Use isReady instead */
|
|
304
|
+
isAuthReady: boolean;
|
|
305
|
+
/** @deprecated Use signIn instead */
|
|
306
|
+
signin: () => Promise<void>;
|
|
307
|
+
/** @deprecated Use signOut instead */
|
|
308
|
+
signout: () => Promise<void>;
|
|
309
|
+
/** @deprecated Use signInWithCode instead */
|
|
310
|
+
signinWithCode: (code: string, state?: string) => Promise<AuthResult>;
|
|
311
|
+
/** @deprecated Use getSignInUrl instead */
|
|
312
|
+
getSignInLink: (redirectUri?: string) => Promise<string>;
|
|
62
313
|
};
|
|
314
|
+
declare function BasicProvider({ children, project_id: project_id_prop, schema, debug, storage, auth, dbMode }: BasicProviderProps): react_jsx_runtime.JSX.Element;
|
|
315
|
+
declare function useBasic(): BasicContextType;
|
|
63
316
|
|
|
64
|
-
export { AuthConfig, BasicProvider, BasicProviderProps, BasicStorage, LocalStorageAdapter, useBasic };
|
|
317
|
+
export { AuthConfig, AuthError, AuthResult, BasicContextType, BasicDB, BasicProvider, BasicProviderProps, BasicStorage, Collection, DBMode, LocalStorageAdapter, NotAuthenticatedError, RemoteCollection, RemoteDB, RemoteDBConfig, RemoteDBError, STORAGE_KEYS, useBasic };
|