@seaverse/dataservice 1.5.0 → 1.6.1

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
@@ -22,13 +22,13 @@ npm install @seaverse/dataservice
22
22
  ```typescript
23
23
  import { createClient } from '@seaverse/dataservice';
24
24
 
25
- // Option 1: Auto-fetch token from parent page (iframe only)
25
+ // Auto-fetch token from parent page (iframe)
26
26
  const client = await createClient({});
27
27
 
28
- // Option 2: Provide token explicitly
29
- const client = await createClient({
30
- token: 'your-jwt-token',
31
- });
28
+ // For development/testing, use debugSetToken
29
+ import { debugSetToken } from '@seaverse/dataservice';
30
+ debugSetToken('your-test-token');
31
+ const client = await createClient({});
32
32
 
33
33
  // Store user preferences (single record)
34
34
  const userPrefs = client.userData.collection('user_preferences');
@@ -269,7 +269,6 @@ interface DataRecord<T> {
269
269
  import { createClient } from '@seaverse/dataservice';
270
270
 
271
271
  const client = await createClient({
272
- token?: string; // JWT token (optional, auto-fetched from parent if in iframe)
273
272
  url?: string; // PostgREST API URL (default: https://dataservice-api.seaverse.ai)
274
273
  options?: {
275
274
  timeout?: number; // Request timeout in ms (default: 30000)
@@ -279,11 +278,17 @@ const client = await createClient({
279
278
  });
280
279
  ```
281
280
 
282
- **Token Options:**
281
+ **Token Authentication Priority:**
282
+
283
+ The SDK uses the following priority order for obtaining authentication tokens:
283
284
 
284
- The SDK supports two ways to provide authentication:
285
+ 1. **Debug Token (Highest Priority)** - Set via `debugSetToken()`
286
+ 2. **Parent Page Token** - Auto-fetched via PostMessage when in iframe
287
+ 3. **No Token** - Client created without authentication (API calls will fail with 401)
285
288
 
286
- 1. **Auto-fetch from parent page (iframe only)**: When running in an iframe, the SDK can automatically request the token from the parent page via PostMessage:
289
+ **Production Usage (Auto-fetch from parent):**
290
+
291
+ The SDK automatically fetches the authentication token from the parent page via PostMessage when running in an iframe:
287
292
 
288
293
  ```typescript
289
294
  // No token needed - auto-fetches from parent
@@ -295,18 +300,37 @@ const client = await createClient({});
295
300
  // Error: { type: 'seaverse:error', error: string }
296
301
  ```
297
302
 
298
- 2. **Explicit token**: Provide the token directly (Bearer prefix is auto-added):
303
+ **Development/Testing (Debug Token):**
304
+
305
+ For development and testing, use `debugSetToken` to bypass the parent page token fetch:
299
306
 
300
307
  ```typescript
301
- // Token without Bearer prefix
302
- const client = await createClient({
303
- token: 'your-jwt-token',
304
- });
308
+ import { debugSetToken, createClient } from '@seaverse/dataservice';
305
309
 
306
- // Or with explicit Bearer prefix (both work)
307
- const client = await createClient({
308
- token: 'Bearer your-jwt-token',
309
- });
310
+ // Set debug token BEFORE creating client (highest priority)
311
+ debugSetToken('your-test-token');
312
+
313
+ // Client will use debug token directly, skipping parent page fetch
314
+ const client = await createClient({});
315
+ ```
316
+
317
+ **Graceful Degradation:**
318
+
319
+ If token fetching fails (e.g., not in an iframe, parent doesn't respond), the SDK will create a client without a token. API calls that require authentication will return 401 errors:
320
+
321
+ ```typescript
322
+ // Client creation never throws, even if token fetch fails
323
+ const client = await createClient({});
324
+
325
+ try {
326
+ // API calls may fail with authentication errors if no token
327
+ const data = await client.userData.collection('test').insert({ foo: 'bar' });
328
+ } catch (error) {
329
+ if (error instanceof DataServiceError && error.statusCode === 401) {
330
+ console.log('Authentication required - no token available');
331
+ // Handle authentication error (e.g., show login prompt)
332
+ }
333
+ }
310
334
  ```
311
335
 
312
336
  **Custom Endpoint:**
@@ -315,7 +339,6 @@ const client = await createClient({
315
339
  // Use custom API endpoint
316
340
  const client = await createClient({
317
341
  url: 'https://your-custom-api.example.com',
318
- token: 'your-jwt-token',
319
342
  });
320
343
  ```
321
344
 
@@ -453,9 +476,10 @@ type Order = {
453
476
  notes?: string;
454
477
  };
455
478
 
456
- const client = createClient({
457
- token: process.env.JWT_TOKEN!,
458
- });
479
+ // For development/testing with Node.js
480
+ import { debugSetToken, createClient } from '@seaverse/dataservice';
481
+ debugSetToken(process.env.JWT_TOKEN!);
482
+ const client = await createClient({});
459
483
 
460
484
  // Create multiple orders - each with unique collection name
461
485
  const orderNumber1 = `ORD-${Date.now()}`;
package/dist/index.d.mts CHANGED
@@ -12,18 +12,13 @@
12
12
  * @example
13
13
  * ```typescript
14
14
  * const config: ClientConfig = {
15
- * token: 'Bearer your-jwt-token-here',
15
+ * url: 'https://dataservice-api.seaverse.ai',
16
16
  * };
17
17
  * ```
18
18
  */
19
19
  interface ClientConfig {
20
20
  /** PostgREST API base URL (default: https://dataservice-api.seaverse.ai) */
21
21
  url?: string;
22
- /**
23
- * JWT token containing user_id in payload.user_id
24
- * If not provided, will attempt to fetch from parent page via PostMessage (iframe only)
25
- */
26
- token?: string;
27
22
  /** Optional configuration */
28
23
  options?: {
29
24
  /** Custom fetch implementation (useful for Node.js < 18) */
@@ -268,30 +263,24 @@ declare function debugSetToken(token: string): void;
268
263
  *
269
264
  * AI-friendly: Single entry point with clear configuration
270
265
  *
271
- * @param config - Client configuration (token optional, will auto-fetch from parent if in iframe)
266
+ * @param config - Client configuration
272
267
  * @returns DataServiceClient instance
273
268
  *
274
269
  * @example
275
270
  * ```typescript
276
- * // Auto-fetch token from parent page (iframe only)
271
+ * // Auto-fetch token from parent page (iframe)
277
272
  * const client = await createClient({});
278
273
  *
279
- * // Or provide token explicitly
280
- * const client = await createClient({
281
- * token: 'your-jwt-token-here',
282
- * });
283
- *
284
- * // Bearer prefix is auto-added
285
- * const client = await createClient({
286
- * token: 'Bearer your-jwt-token-here',
287
- * });
288
- *
289
274
  * // Custom endpoint
290
275
  * const client = await createClient({
291
276
  * url: 'https://your-postgrest-api.example.com',
292
- * token: 'your-jwt-token-here',
293
277
  * });
294
278
  *
279
+ * // For development/testing, use debugSetToken
280
+ * import { debugSetToken, createClient } from '@seaverse/dataservice';
281
+ * debugSetToken('your-test-token');
282
+ * const client = await createClient({});
283
+ *
295
284
  * // appId is automatically extracted from current URL
296
285
  * const order = await client.userData.collection('orders').insert({ ... });
297
286
  * const orders = await client.userData.collection('orders').select().execute();
@@ -308,15 +297,14 @@ declare function createClient(config?: ClientConfig): Promise<DataServiceClient>
308
297
  *
309
298
  * @example Basic Usage with Auto Token Fetch
310
299
  * ```typescript
311
- * import { createClient } from '@seaverse/dataservice';
300
+ * import { createClient, debugSetToken } from '@seaverse/dataservice';
312
301
  *
313
- * // Auto-fetch token from parent page (iframe only)
302
+ * // Auto-fetch token from parent page (iframe)
314
303
  * const client = await createClient({});
315
304
  *
316
- * // Or provide token explicitly
317
- * const client = await createClient({
318
- * token: 'your-jwt-token',
319
- * });
305
+ * // For development/testing, use debugSetToken
306
+ * debugSetToken('your-test-token');
307
+ * const client = await createClient({});
320
308
  *
321
309
  * // appId is automatically extracted from current URL
322
310
  * // Insert data
package/dist/index.d.ts CHANGED
@@ -12,18 +12,13 @@
12
12
  * @example
13
13
  * ```typescript
14
14
  * const config: ClientConfig = {
15
- * token: 'Bearer your-jwt-token-here',
15
+ * url: 'https://dataservice-api.seaverse.ai',
16
16
  * };
17
17
  * ```
18
18
  */
19
19
  interface ClientConfig {
20
20
  /** PostgREST API base URL (default: https://dataservice-api.seaverse.ai) */
21
21
  url?: string;
22
- /**
23
- * JWT token containing user_id in payload.user_id
24
- * If not provided, will attempt to fetch from parent page via PostMessage (iframe only)
25
- */
26
- token?: string;
27
22
  /** Optional configuration */
28
23
  options?: {
29
24
  /** Custom fetch implementation (useful for Node.js < 18) */
@@ -268,30 +263,24 @@ declare function debugSetToken(token: string): void;
268
263
  *
269
264
  * AI-friendly: Single entry point with clear configuration
270
265
  *
271
- * @param config - Client configuration (token optional, will auto-fetch from parent if in iframe)
266
+ * @param config - Client configuration
272
267
  * @returns DataServiceClient instance
273
268
  *
274
269
  * @example
275
270
  * ```typescript
276
- * // Auto-fetch token from parent page (iframe only)
271
+ * // Auto-fetch token from parent page (iframe)
277
272
  * const client = await createClient({});
278
273
  *
279
- * // Or provide token explicitly
280
- * const client = await createClient({
281
- * token: 'your-jwt-token-here',
282
- * });
283
- *
284
- * // Bearer prefix is auto-added
285
- * const client = await createClient({
286
- * token: 'Bearer your-jwt-token-here',
287
- * });
288
- *
289
274
  * // Custom endpoint
290
275
  * const client = await createClient({
291
276
  * url: 'https://your-postgrest-api.example.com',
292
- * token: 'your-jwt-token-here',
293
277
  * });
294
278
  *
279
+ * // For development/testing, use debugSetToken
280
+ * import { debugSetToken, createClient } from '@seaverse/dataservice';
281
+ * debugSetToken('your-test-token');
282
+ * const client = await createClient({});
283
+ *
295
284
  * // appId is automatically extracted from current URL
296
285
  * const order = await client.userData.collection('orders').insert({ ... });
297
286
  * const orders = await client.userData.collection('orders').select().execute();
@@ -308,15 +297,14 @@ declare function createClient(config?: ClientConfig): Promise<DataServiceClient>
308
297
  *
309
298
  * @example Basic Usage with Auto Token Fetch
310
299
  * ```typescript
311
- * import { createClient } from '@seaverse/dataservice';
300
+ * import { createClient, debugSetToken } from '@seaverse/dataservice';
312
301
  *
313
- * // Auto-fetch token from parent page (iframe only)
302
+ * // Auto-fetch token from parent page (iframe)
314
303
  * const client = await createClient({});
315
304
  *
316
- * // Or provide token explicitly
317
- * const client = await createClient({
318
- * token: 'your-jwt-token',
319
- * });
305
+ * // For development/testing, use debugSetToken
306
+ * debugSetToken('your-test-token');
307
+ * const client = await createClient({});
320
308
  *
321
309
  * // appId is automatically extracted from current URL
322
310
  * // Insert data
package/dist/index.js CHANGED
@@ -108,7 +108,8 @@ var HTTPClient = class {
108
108
  tokenPromise = null;
109
109
  constructor(config, token) {
110
110
  this.baseUrl = (config.url || "https://dataservice-api.seaverse.ai").replace(/\/$/, "");
111
- this.fetchFn = config.options?.fetch || globalThis.fetch;
111
+ const customFetch = config.options?.fetch;
112
+ this.fetchFn = customFetch ? customFetch.bind(customFetch) : globalThis.fetch.bind(globalThis);
112
113
  this.timeout = config.options?.timeout || 3e4;
113
114
  this.headers = {
114
115
  "Content-Type": "application/json",
@@ -406,23 +407,19 @@ var DataServiceClientImpl = class {
406
407
  }
407
408
  };
408
409
  async function createClient(config = {}) {
409
- let token = config.token;
410
- if (!token) {
411
- if (debugToken) {
412
- token = debugToken;
413
- } else {
410
+ let token = null;
411
+ if (debugToken) {
412
+ token = debugToken;
413
+ } else {
414
+ try {
414
415
  const timeout = config.options?.tokenFetchTimeout || 5e3;
415
- const fetchedToken = await getTokenFromParent(timeout);
416
- if (!fetchedToken) {
417
- throw new DataServiceError(
418
- "No token provided and failed to fetch from parent page. Please provide a token or ensure the app is running in an iframe with a parent that responds to seaverse:get_token messages.",
419
- "NO_TOKEN"
420
- );
421
- }
422
- token = fetchedToken;
416
+ token = await getTokenFromParent(timeout);
417
+ } catch (error) {
418
+ console.warn("[SeaVerse DataService SDK] Failed to fetch token:", error);
419
+ token = null;
423
420
  }
424
421
  }
425
- const httpClient = new HTTPClient(config, token);
422
+ const httpClient = new HTTPClient(config, token || void 0);
426
423
  const appId = extractAppId();
427
424
  return new DataServiceClientImpl(httpClient, appId);
428
425
  }
package/dist/index.mjs CHANGED
@@ -79,7 +79,8 @@ var HTTPClient = class {
79
79
  tokenPromise = null;
80
80
  constructor(config, token) {
81
81
  this.baseUrl = (config.url || "https://dataservice-api.seaverse.ai").replace(/\/$/, "");
82
- this.fetchFn = config.options?.fetch || globalThis.fetch;
82
+ const customFetch = config.options?.fetch;
83
+ this.fetchFn = customFetch ? customFetch.bind(customFetch) : globalThis.fetch.bind(globalThis);
83
84
  this.timeout = config.options?.timeout || 3e4;
84
85
  this.headers = {
85
86
  "Content-Type": "application/json",
@@ -377,23 +378,19 @@ var DataServiceClientImpl = class {
377
378
  }
378
379
  };
379
380
  async function createClient(config = {}) {
380
- let token = config.token;
381
- if (!token) {
382
- if (debugToken) {
383
- token = debugToken;
384
- } else {
381
+ let token = null;
382
+ if (debugToken) {
383
+ token = debugToken;
384
+ } else {
385
+ try {
385
386
  const timeout = config.options?.tokenFetchTimeout || 5e3;
386
- const fetchedToken = await getTokenFromParent(timeout);
387
- if (!fetchedToken) {
388
- throw new DataServiceError(
389
- "No token provided and failed to fetch from parent page. Please provide a token or ensure the app is running in an iframe with a parent that responds to seaverse:get_token messages.",
390
- "NO_TOKEN"
391
- );
392
- }
393
- token = fetchedToken;
387
+ token = await getTokenFromParent(timeout);
388
+ } catch (error) {
389
+ console.warn("[SeaVerse DataService SDK] Failed to fetch token:", error);
390
+ token = null;
394
391
  }
395
392
  }
396
- const httpClient = new HTTPClient(config, token);
393
+ const httpClient = new HTTPClient(config, token || void 0);
397
394
  const appId = extractAppId();
398
395
  return new DataServiceClientImpl(httpClient, appId);
399
396
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seaverse/dataservice",
3
- "version": "1.5.0",
3
+ "version": "1.6.1",
4
4
  "description": "AI-Friendly Universal Data Storage SDK for TypeScript/JavaScript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",