@seaverse/dataservice 1.6.2 → 1.7.0
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 +25 -15
- package/dist/index.d.mts +9 -10
- package/dist/index.d.ts +9 -10
- package/dist/index.js +48 -3
- package/dist/index.mjs +48 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,10 +55,13 @@ const client = new DataServiceClient(); // This will fail!
|
|
|
55
55
|
|
|
56
56
|
The SDK uses a **factory function pattern**. Always use `createClient()`:
|
|
57
57
|
|
|
58
|
+
**Important:** The SDK automatically obtains the service host from the parent page via PostMessage (500ms timeout). If the fetch fails, it defaults to `https://dataservice-api.seaverse.ai`. No configuration is needed.
|
|
59
|
+
|
|
58
60
|
```typescript
|
|
59
61
|
import { createClient, debugSetToken } from '@seaverse/dataservice';
|
|
60
62
|
|
|
61
|
-
// Production: Auto-fetch token from parent page (when running in iframe)
|
|
63
|
+
// Production: Auto-fetch token and serviceHost from parent page (when running in iframe)
|
|
64
|
+
// Falls back to https://dataservice-api.seaverse.ai if fetch fails
|
|
62
65
|
const client = await createClient({});
|
|
63
66
|
|
|
64
67
|
// Development/Testing: Use debug token
|
|
@@ -308,7 +311,6 @@ interface DataRecord<T> {
|
|
|
308
311
|
import { createClient } from '@seaverse/dataservice';
|
|
309
312
|
|
|
310
313
|
const client = await createClient({
|
|
311
|
-
url?: string; // PostgREST API URL (default: https://dataservice-api.seaverse.ai)
|
|
312
314
|
options?: {
|
|
313
315
|
timeout?: number; // Request timeout in ms (default: 30000)
|
|
314
316
|
tokenFetchTimeout?: number; // Token fetch timeout in ms (default: 5000)
|
|
@@ -317,6 +319,14 @@ const client = await createClient({
|
|
|
317
319
|
});
|
|
318
320
|
```
|
|
319
321
|
|
|
322
|
+
**ServiceHost Auto-Detection:**
|
|
323
|
+
|
|
324
|
+
The SDK automatically fetches the service host from the parent page via PostMessage:
|
|
325
|
+
- **Timeout**: 500ms (hardcoded, not configurable)
|
|
326
|
+
- **Protocol**: Sends `{ type: 'seaverse:get_service_host', payload: { serviceName: 'dataservice' } }`
|
|
327
|
+
- **Fallback**: If fetch fails, defaults to `https://dataservice-api.seaverse.ai`
|
|
328
|
+
- **No user configuration**: ServiceHost is managed internally to prevent request failures
|
|
329
|
+
|
|
320
330
|
**Token Authentication Priority:**
|
|
321
331
|
|
|
322
332
|
The SDK uses the following priority order for obtaining authentication tokens:
|
|
@@ -327,16 +337,22 @@ The SDK uses the following priority order for obtaining authentication tokens:
|
|
|
327
337
|
|
|
328
338
|
**Production Usage (Auto-fetch from parent):**
|
|
329
339
|
|
|
330
|
-
The SDK automatically fetches the authentication token from the parent page via PostMessage when running in an iframe:
|
|
340
|
+
The SDK automatically fetches the authentication token and service host from the parent page via PostMessage when running in an iframe:
|
|
331
341
|
|
|
332
342
|
```typescript
|
|
333
|
-
// No
|
|
343
|
+
// No configuration needed - auto-fetches token and serviceHost from parent
|
|
334
344
|
const client = await createClient({});
|
|
335
345
|
|
|
336
346
|
// Parent page should respond to PostMessage:
|
|
347
|
+
// Token request:
|
|
337
348
|
// Send: { type: 'seaverse:get_token' }
|
|
338
349
|
// Receive: { type: 'seaverse:token', payload: { accessToken: string, expiresIn: number } }
|
|
339
350
|
// Error: { type: 'seaverse:error', error: string }
|
|
351
|
+
|
|
352
|
+
// ServiceHost request:
|
|
353
|
+
// Send: { type: 'seaverse:get_service_host', payload: { serviceName: 'dataservice' } }
|
|
354
|
+
// Receive: { type: 'seaverse:service_host', payload: { serviceHost: string } }
|
|
355
|
+
// Error: { type: 'seaverse:error', error: string }
|
|
340
356
|
```
|
|
341
357
|
|
|
342
358
|
**Development/Testing (Debug Token):**
|
|
@@ -355,10 +371,13 @@ const client = await createClient({});
|
|
|
355
371
|
|
|
356
372
|
**Graceful Degradation:**
|
|
357
373
|
|
|
358
|
-
If token fetching fails
|
|
374
|
+
If token or serviceHost fetching fails, the SDK gracefully handles the failure:
|
|
375
|
+
|
|
376
|
+
- **Token fetch failure**: Creates client without authentication (API calls will return 401)
|
|
377
|
+
- **ServiceHost fetch failure**: Falls back to default `https://dataservice-api.seaverse.ai`
|
|
359
378
|
|
|
360
379
|
```typescript
|
|
361
|
-
// Client creation never throws, even if
|
|
380
|
+
// Client creation never throws, even if fetch fails
|
|
362
381
|
const client = await createClient({});
|
|
363
382
|
|
|
364
383
|
try {
|
|
@@ -372,15 +391,6 @@ try {
|
|
|
372
391
|
}
|
|
373
392
|
```
|
|
374
393
|
|
|
375
|
-
**Custom Endpoint:**
|
|
376
|
-
|
|
377
|
-
```typescript
|
|
378
|
-
// Use custom API endpoint
|
|
379
|
-
const client = await createClient({
|
|
380
|
-
url: 'https://your-custom-api.example.com',
|
|
381
|
-
});
|
|
382
|
-
```
|
|
383
|
-
|
|
384
394
|
### DataTable Methods
|
|
385
395
|
|
|
386
396
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
14
|
* const config: ClientConfig = {
|
|
15
|
-
*
|
|
15
|
+
* options: {
|
|
16
|
+
* timeout: 10000,
|
|
17
|
+
* }
|
|
16
18
|
* };
|
|
17
19
|
* ```
|
|
18
20
|
*/
|
|
19
21
|
interface ClientConfig {
|
|
20
|
-
/** PostgREST API base URL (default: https://dataservice-api.seaverse.ai) */
|
|
21
|
-
url?: string;
|
|
22
22
|
/** Optional configuration */
|
|
23
23
|
options?: {
|
|
24
24
|
/** Custom fetch implementation (useful for Node.js < 18) */
|
|
@@ -281,21 +281,20 @@ declare function debugSetToken(token: string): void;
|
|
|
281
281
|
/**
|
|
282
282
|
* Create a new Data Service client
|
|
283
283
|
*
|
|
284
|
+
* The SDK automatically obtains the service host from the parent page via PostMessage (500ms timeout).
|
|
285
|
+
* If the fetch fails, it falls back to the default host: https://dataservice-api.seaverse.ai
|
|
286
|
+
*
|
|
284
287
|
* AI-friendly: Single entry point with clear configuration
|
|
285
288
|
*
|
|
286
|
-
* @param config - Client configuration
|
|
289
|
+
* @param config - Client configuration (optional)
|
|
287
290
|
* @returns DataServiceClient instance
|
|
288
291
|
*
|
|
289
292
|
* @example
|
|
290
293
|
* ```typescript
|
|
291
|
-
* // Auto-fetch token from parent page (iframe)
|
|
294
|
+
* // Auto-fetch token and serviceHost from parent page (iframe)
|
|
295
|
+
* // ServiceHost fetch: 500ms timeout, falls back to https://dataservice-api.seaverse.ai
|
|
292
296
|
* const client = await createClient({});
|
|
293
297
|
*
|
|
294
|
-
* // Custom endpoint
|
|
295
|
-
* const client = await createClient({
|
|
296
|
-
* url: 'https://your-postgrest-api.example.com',
|
|
297
|
-
* });
|
|
298
|
-
*
|
|
299
298
|
* // For development/testing, use debugSetToken
|
|
300
299
|
* import { debugSetToken, createClient } from '@seaverse/dataservice';
|
|
301
300
|
* debugSetToken('your-test-token');
|
package/dist/index.d.ts
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
14
|
* const config: ClientConfig = {
|
|
15
|
-
*
|
|
15
|
+
* options: {
|
|
16
|
+
* timeout: 10000,
|
|
17
|
+
* }
|
|
16
18
|
* };
|
|
17
19
|
* ```
|
|
18
20
|
*/
|
|
19
21
|
interface ClientConfig {
|
|
20
|
-
/** PostgREST API base URL (default: https://dataservice-api.seaverse.ai) */
|
|
21
|
-
url?: string;
|
|
22
22
|
/** Optional configuration */
|
|
23
23
|
options?: {
|
|
24
24
|
/** Custom fetch implementation (useful for Node.js < 18) */
|
|
@@ -281,21 +281,20 @@ declare function debugSetToken(token: string): void;
|
|
|
281
281
|
/**
|
|
282
282
|
* Create a new Data Service client
|
|
283
283
|
*
|
|
284
|
+
* The SDK automatically obtains the service host from the parent page via PostMessage (500ms timeout).
|
|
285
|
+
* If the fetch fails, it falls back to the default host: https://dataservice-api.seaverse.ai
|
|
286
|
+
*
|
|
284
287
|
* AI-friendly: Single entry point with clear configuration
|
|
285
288
|
*
|
|
286
|
-
* @param config - Client configuration
|
|
289
|
+
* @param config - Client configuration (optional)
|
|
287
290
|
* @returns DataServiceClient instance
|
|
288
291
|
*
|
|
289
292
|
* @example
|
|
290
293
|
* ```typescript
|
|
291
|
-
* // Auto-fetch token from parent page (iframe)
|
|
294
|
+
* // Auto-fetch token and serviceHost from parent page (iframe)
|
|
295
|
+
* // ServiceHost fetch: 500ms timeout, falls back to https://dataservice-api.seaverse.ai
|
|
292
296
|
* const client = await createClient({});
|
|
293
297
|
*
|
|
294
|
-
* // Custom endpoint
|
|
295
|
-
* const client = await createClient({
|
|
296
|
-
* url: 'https://your-postgrest-api.example.com',
|
|
297
|
-
* });
|
|
298
|
-
*
|
|
299
298
|
* // For development/testing, use debugSetToken
|
|
300
299
|
* import { debugSetToken, createClient } from '@seaverse/dataservice';
|
|
301
300
|
* debugSetToken('your-test-token');
|
package/dist/index.js
CHANGED
|
@@ -88,6 +88,43 @@ async function getTokenFromParent(timeout = 5e3) {
|
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
+
async function getServiceHostFromParent(timeout = 500, serviceName = "dataservice") {
|
|
92
|
+
if (!isInIframe()) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
const messageHandler = (event) => {
|
|
97
|
+
if (event.data && event.data.type === "seaverse:service_host") {
|
|
98
|
+
cleanup();
|
|
99
|
+
const serviceHost = event.data.payload?.serviceHost;
|
|
100
|
+
resolve(serviceHost || null);
|
|
101
|
+
} else if (event.data && event.data.type === "seaverse:error") {
|
|
102
|
+
cleanup();
|
|
103
|
+
console.warn("[SeaVerse DataService SDK] Error getting serviceHost from parent:", event.data.error);
|
|
104
|
+
resolve(null);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const timeoutId = setTimeout(() => {
|
|
108
|
+
cleanup();
|
|
109
|
+
resolve(null);
|
|
110
|
+
}, timeout);
|
|
111
|
+
const cleanup = () => {
|
|
112
|
+
clearTimeout(timeoutId);
|
|
113
|
+
globalThis.window.removeEventListener("message", messageHandler);
|
|
114
|
+
};
|
|
115
|
+
globalThis.window.addEventListener("message", messageHandler);
|
|
116
|
+
try {
|
|
117
|
+
globalThis.window.parent.postMessage(
|
|
118
|
+
{ type: "seaverse:get_service_host", payload: { serviceName } },
|
|
119
|
+
"*"
|
|
120
|
+
// Allow any origin, supports cross-domain scenarios
|
|
121
|
+
);
|
|
122
|
+
} catch (e) {
|
|
123
|
+
cleanup();
|
|
124
|
+
resolve(null);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
91
128
|
function extractAppId() {
|
|
92
129
|
if (typeof globalThis !== "undefined" && "location" in globalThis) {
|
|
93
130
|
const location = globalThis.location;
|
|
@@ -106,8 +143,9 @@ var HTTPClient = class {
|
|
|
106
143
|
fetchFn;
|
|
107
144
|
timeout;
|
|
108
145
|
tokenPromise = null;
|
|
109
|
-
constructor(config, token) {
|
|
110
|
-
|
|
146
|
+
constructor(config, token, serviceHost) {
|
|
147
|
+
const defaultHost = "https://dataservice-api.seaverse.ai";
|
|
148
|
+
this.baseUrl = (serviceHost || defaultHost).replace(/\/$/, "");
|
|
111
149
|
const customFetch = config.options?.fetch;
|
|
112
150
|
this.fetchFn = customFetch ? customFetch.bind(customFetch) : globalThis.fetch.bind(globalThis);
|
|
113
151
|
this.timeout = config.options?.timeout || 3e4;
|
|
@@ -408,6 +446,7 @@ var DataServiceClientImpl = class {
|
|
|
408
446
|
};
|
|
409
447
|
async function createClient(config = {}) {
|
|
410
448
|
let token = null;
|
|
449
|
+
let serviceHost = null;
|
|
411
450
|
if (debugToken) {
|
|
412
451
|
token = debugToken;
|
|
413
452
|
} else {
|
|
@@ -419,7 +458,13 @@ async function createClient(config = {}) {
|
|
|
419
458
|
token = null;
|
|
420
459
|
}
|
|
421
460
|
}
|
|
422
|
-
|
|
461
|
+
try {
|
|
462
|
+
serviceHost = await getServiceHostFromParent(500, "dataservice");
|
|
463
|
+
} catch (error) {
|
|
464
|
+
console.warn("[SeaVerse DataService SDK] Failed to fetch serviceHost:", error);
|
|
465
|
+
serviceHost = null;
|
|
466
|
+
}
|
|
467
|
+
const httpClient = new HTTPClient(config, token || void 0, serviceHost || void 0);
|
|
423
468
|
const appId = extractAppId();
|
|
424
469
|
return new DataServiceClientImpl(httpClient, appId);
|
|
425
470
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -59,6 +59,43 @@ async function getTokenFromParent(timeout = 5e3) {
|
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
+
async function getServiceHostFromParent(timeout = 500, serviceName = "dataservice") {
|
|
63
|
+
if (!isInIframe()) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
const messageHandler = (event) => {
|
|
68
|
+
if (event.data && event.data.type === "seaverse:service_host") {
|
|
69
|
+
cleanup();
|
|
70
|
+
const serviceHost = event.data.payload?.serviceHost;
|
|
71
|
+
resolve(serviceHost || null);
|
|
72
|
+
} else if (event.data && event.data.type === "seaverse:error") {
|
|
73
|
+
cleanup();
|
|
74
|
+
console.warn("[SeaVerse DataService SDK] Error getting serviceHost from parent:", event.data.error);
|
|
75
|
+
resolve(null);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const timeoutId = setTimeout(() => {
|
|
79
|
+
cleanup();
|
|
80
|
+
resolve(null);
|
|
81
|
+
}, timeout);
|
|
82
|
+
const cleanup = () => {
|
|
83
|
+
clearTimeout(timeoutId);
|
|
84
|
+
globalThis.window.removeEventListener("message", messageHandler);
|
|
85
|
+
};
|
|
86
|
+
globalThis.window.addEventListener("message", messageHandler);
|
|
87
|
+
try {
|
|
88
|
+
globalThis.window.parent.postMessage(
|
|
89
|
+
{ type: "seaverse:get_service_host", payload: { serviceName } },
|
|
90
|
+
"*"
|
|
91
|
+
// Allow any origin, supports cross-domain scenarios
|
|
92
|
+
);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
cleanup();
|
|
95
|
+
resolve(null);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
62
99
|
function extractAppId() {
|
|
63
100
|
if (typeof globalThis !== "undefined" && "location" in globalThis) {
|
|
64
101
|
const location = globalThis.location;
|
|
@@ -77,8 +114,9 @@ var HTTPClient = class {
|
|
|
77
114
|
fetchFn;
|
|
78
115
|
timeout;
|
|
79
116
|
tokenPromise = null;
|
|
80
|
-
constructor(config, token) {
|
|
81
|
-
|
|
117
|
+
constructor(config, token, serviceHost) {
|
|
118
|
+
const defaultHost = "https://dataservice-api.seaverse.ai";
|
|
119
|
+
this.baseUrl = (serviceHost || defaultHost).replace(/\/$/, "");
|
|
82
120
|
const customFetch = config.options?.fetch;
|
|
83
121
|
this.fetchFn = customFetch ? customFetch.bind(customFetch) : globalThis.fetch.bind(globalThis);
|
|
84
122
|
this.timeout = config.options?.timeout || 3e4;
|
|
@@ -379,6 +417,7 @@ var DataServiceClientImpl = class {
|
|
|
379
417
|
};
|
|
380
418
|
async function createClient(config = {}) {
|
|
381
419
|
let token = null;
|
|
420
|
+
let serviceHost = null;
|
|
382
421
|
if (debugToken) {
|
|
383
422
|
token = debugToken;
|
|
384
423
|
} else {
|
|
@@ -390,7 +429,13 @@ async function createClient(config = {}) {
|
|
|
390
429
|
token = null;
|
|
391
430
|
}
|
|
392
431
|
}
|
|
393
|
-
|
|
432
|
+
try {
|
|
433
|
+
serviceHost = await getServiceHostFromParent(500, "dataservice");
|
|
434
|
+
} catch (error) {
|
|
435
|
+
console.warn("[SeaVerse DataService SDK] Failed to fetch serviceHost:", error);
|
|
436
|
+
serviceHost = null;
|
|
437
|
+
}
|
|
438
|
+
const httpClient = new HTTPClient(config, token || void 0, serviceHost || void 0);
|
|
394
439
|
const appId = extractAppId();
|
|
395
440
|
return new DataServiceClientImpl(httpClient, appId);
|
|
396
441
|
}
|