@seaverse/dataservice 1.8.1 → 1.8.3

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/index.d.mts CHANGED
@@ -302,33 +302,6 @@ declare function debugSetToken(token: string): void;
302
302
  * ```
303
303
  */
304
304
  declare function setAppId(appId: string): void;
305
- /**
306
- * Create a new Data Service client
307
- *
308
- * The SDK automatically obtains the service host from the parent page via PostMessage (500ms timeout).
309
- * If the fetch fails, it falls back to the default host: https://dataservice-api.seaverse.ai
310
- *
311
- * AI-friendly: Single entry point with clear configuration
312
- *
313
- * @param config - Client configuration (optional)
314
- * @returns DataServiceClient instance
315
- *
316
- * @example
317
- * ```typescript
318
- * // Auto-fetch token and serviceHost from parent page (iframe)
319
- * // ServiceHost fetch: 500ms timeout, falls back to https://dataservice-api.seaverse.ai
320
- * const client = await createClient({});
321
- *
322
- * // For development/testing, use debugSetToken
323
- * import { debugSetToken, createClient } from '@seaverse/dataservice';
324
- * debugSetToken('your-test-token');
325
- * const client = await createClient({});
326
- *
327
- * // appId is automatically extracted from current URL
328
- * const order = await client.userData.collection('orders').insert({ ... });
329
- * const orders = await client.userData.collection('orders').select().execute();
330
- * ```
331
- */
332
305
  declare function createClient(config?: ClientConfig): Promise<DataServiceClient>;
333
306
 
334
307
  /**
package/dist/index.d.ts CHANGED
@@ -302,33 +302,6 @@ declare function debugSetToken(token: string): void;
302
302
  * ```
303
303
  */
304
304
  declare function setAppId(appId: string): void;
305
- /**
306
- * Create a new Data Service client
307
- *
308
- * The SDK automatically obtains the service host from the parent page via PostMessage (500ms timeout).
309
- * If the fetch fails, it falls back to the default host: https://dataservice-api.seaverse.ai
310
- *
311
- * AI-friendly: Single entry point with clear configuration
312
- *
313
- * @param config - Client configuration (optional)
314
- * @returns DataServiceClient instance
315
- *
316
- * @example
317
- * ```typescript
318
- * // Auto-fetch token and serviceHost from parent page (iframe)
319
- * // ServiceHost fetch: 500ms timeout, falls back to https://dataservice-api.seaverse.ai
320
- * const client = await createClient({});
321
- *
322
- * // For development/testing, use debugSetToken
323
- * import { debugSetToken, createClient } from '@seaverse/dataservice';
324
- * debugSetToken('your-test-token');
325
- * const client = await createClient({});
326
- *
327
- * // appId is automatically extracted from current URL
328
- * const order = await client.userData.collection('orders').insert({ ... });
329
- * const orders = await client.userData.collection('orders').select().execute();
330
- * ```
331
- */
332
305
  declare function createClient(config?: ClientConfig): Promise<DataServiceClient>;
333
306
 
334
307
  /**
package/dist/index.js CHANGED
@@ -56,16 +56,27 @@ function isInIframe() {
56
56
  return false;
57
57
  }
58
58
  }
59
+ function isInSeaVerseApp() {
60
+ try {
61
+ return typeof globalThis !== "undefined" && "window" in globalThis && typeof globalThis.window.ReactNativeWebView !== "undefined";
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
59
66
  async function getTokenFromParent(timeout = 5e3) {
60
- if (!isInIframe()) {
67
+ if (!isInIframe() && !isInSeaVerseApp()) {
61
68
  return null;
62
69
  }
63
70
  return new Promise((resolve) => {
71
+ const callId = `token_${Date.now()}_${Math.random()}`;
64
72
  const messageHandler = (event) => {
65
73
  if (event.data && event.data.type === "seaverse:token") {
66
74
  cleanup();
67
75
  const token = event.data.payload?.accessToken;
68
76
  resolve(token || null);
77
+ } else if (event.data && event.data.type === "seaverse:token_response" && event.data.callId === callId) {
78
+ cleanup();
79
+ resolve(event.data.token || null);
69
80
  } else if (event.data && event.data.type === "seaverse:error") {
70
81
  cleanup();
71
82
  console.warn("[SeaVerse DataService SDK] Error getting token from parent:", event.data.error);
@@ -82,11 +93,16 @@ async function getTokenFromParent(timeout = 5e3) {
82
93
  };
83
94
  globalThis.window.addEventListener("message", messageHandler);
84
95
  try {
85
- globalThis.window.parent.postMessage(
86
- { type: "seaverse:get_token" },
87
- "*"
88
- // Allow any origin, supports cross-domain scenarios
89
- );
96
+ if (isInSeaVerseApp()) {
97
+ globalThis.window.ReactNativeWebView.postMessage(
98
+ JSON.stringify({ type: "seaverse:get_token", callId })
99
+ );
100
+ } else {
101
+ globalThis.window.parent.postMessage(
102
+ { type: "seaverse:get_token" },
103
+ "*"
104
+ );
105
+ }
90
106
  } catch (e) {
91
107
  cleanup();
92
108
  resolve(null);
@@ -94,15 +110,19 @@ async function getTokenFromParent(timeout = 5e3) {
94
110
  });
95
111
  }
96
112
  async function getServiceHostFromParent(timeout = 500, serviceName = "dataservice") {
97
- if (!isInIframe()) {
113
+ if (!isInIframe() && !isInSeaVerseApp()) {
98
114
  return null;
99
115
  }
100
116
  return new Promise((resolve) => {
117
+ const callId = `host_${Date.now()}_${Math.random()}`;
101
118
  const messageHandler = (event) => {
102
119
  if (event.data && event.data.type === "seaverse:service_host") {
103
120
  cleanup();
104
121
  const serviceHost = event.data.payload?.serviceHost;
105
122
  resolve(serviceHost || null);
123
+ } else if (event.data && event.data.type === "seaverse:service_host_response" && event.data.callId === callId) {
124
+ cleanup();
125
+ resolve(event.data.serviceHost || null);
106
126
  } else if (event.data && event.data.type === "seaverse:error") {
107
127
  cleanup();
108
128
  console.warn("[SeaVerse DataService SDK] Error getting serviceHost from parent:", event.data.error);
@@ -119,11 +139,16 @@ async function getServiceHostFromParent(timeout = 500, serviceName = "dataservic
119
139
  };
120
140
  globalThis.window.addEventListener("message", messageHandler);
121
141
  try {
122
- globalThis.window.parent.postMessage(
123
- { type: "seaverse:get_service_host", payload: { serviceName } },
124
- "*"
125
- // Allow any origin, supports cross-domain scenarios
126
- );
142
+ if (isInSeaVerseApp()) {
143
+ globalThis.window.ReactNativeWebView.postMessage(
144
+ JSON.stringify({ type: "seaverse:get_service_host", callId, serviceName })
145
+ );
146
+ } else {
147
+ globalThis.window.parent.postMessage(
148
+ { type: "seaverse:get_service_host", payload: { serviceName } },
149
+ "*"
150
+ );
151
+ }
127
152
  } catch (e) {
128
153
  cleanup();
129
154
  resolve(null);
@@ -131,15 +156,19 @@ async function getServiceHostFromParent(timeout = 500, serviceName = "dataservic
131
156
  });
132
157
  }
133
158
  async function getAppIdFromParent(timeout = 500) {
134
- if (!isInIframe()) {
159
+ if (!isInIframe() && !isInSeaVerseApp()) {
135
160
  return null;
136
161
  }
137
162
  return new Promise((resolve) => {
163
+ const callId = `appid_${Date.now()}_${Math.random()}`;
138
164
  const messageHandler = (event) => {
139
165
  if (event.data && event.data.type === "seaverse:appId") {
140
166
  cleanup();
141
167
  const appId = event.data.payload?.appId;
142
168
  resolve(appId || null);
169
+ } else if (event.data && event.data.type === "seaverse:appId_response" && event.data.callId === callId) {
170
+ cleanup();
171
+ resolve(event.data.appId || null);
143
172
  } else if (event.data && event.data.type === "seaverse:error") {
144
173
  cleanup();
145
174
  console.warn("[SeaVerse DataService SDK] Error getting appId from parent:", event.data.error);
@@ -156,10 +185,16 @@ async function getAppIdFromParent(timeout = 500) {
156
185
  };
157
186
  globalThis.window.addEventListener("message", messageHandler);
158
187
  try {
159
- globalThis.window.parent.postMessage(
160
- { type: "seaverse:get_appId" },
161
- "*"
162
- );
188
+ if (isInSeaVerseApp()) {
189
+ globalThis.window.ReactNativeWebView.postMessage(
190
+ JSON.stringify({ type: "seaverse:get_appId", callId })
191
+ );
192
+ } else {
193
+ globalThis.window.parent.postMessage(
194
+ { type: "seaverse:get_appId" },
195
+ "*"
196
+ );
197
+ }
163
198
  } catch (e) {
164
199
  cleanup();
165
200
  resolve(null);
package/dist/index.mjs CHANGED
@@ -26,16 +26,27 @@ function isInIframe() {
26
26
  return false;
27
27
  }
28
28
  }
29
+ function isInSeaVerseApp() {
30
+ try {
31
+ return typeof globalThis !== "undefined" && "window" in globalThis && typeof globalThis.window.ReactNativeWebView !== "undefined";
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
29
36
  async function getTokenFromParent(timeout = 5e3) {
30
- if (!isInIframe()) {
37
+ if (!isInIframe() && !isInSeaVerseApp()) {
31
38
  return null;
32
39
  }
33
40
  return new Promise((resolve) => {
41
+ const callId = `token_${Date.now()}_${Math.random()}`;
34
42
  const messageHandler = (event) => {
35
43
  if (event.data && event.data.type === "seaverse:token") {
36
44
  cleanup();
37
45
  const token = event.data.payload?.accessToken;
38
46
  resolve(token || null);
47
+ } else if (event.data && event.data.type === "seaverse:token_response" && event.data.callId === callId) {
48
+ cleanup();
49
+ resolve(event.data.token || null);
39
50
  } else if (event.data && event.data.type === "seaverse:error") {
40
51
  cleanup();
41
52
  console.warn("[SeaVerse DataService SDK] Error getting token from parent:", event.data.error);
@@ -52,11 +63,16 @@ async function getTokenFromParent(timeout = 5e3) {
52
63
  };
53
64
  globalThis.window.addEventListener("message", messageHandler);
54
65
  try {
55
- globalThis.window.parent.postMessage(
56
- { type: "seaverse:get_token" },
57
- "*"
58
- // Allow any origin, supports cross-domain scenarios
59
- );
66
+ if (isInSeaVerseApp()) {
67
+ globalThis.window.ReactNativeWebView.postMessage(
68
+ JSON.stringify({ type: "seaverse:get_token", callId })
69
+ );
70
+ } else {
71
+ globalThis.window.parent.postMessage(
72
+ { type: "seaverse:get_token" },
73
+ "*"
74
+ );
75
+ }
60
76
  } catch (e) {
61
77
  cleanup();
62
78
  resolve(null);
@@ -64,15 +80,19 @@ async function getTokenFromParent(timeout = 5e3) {
64
80
  });
65
81
  }
66
82
  async function getServiceHostFromParent(timeout = 500, serviceName = "dataservice") {
67
- if (!isInIframe()) {
83
+ if (!isInIframe() && !isInSeaVerseApp()) {
68
84
  return null;
69
85
  }
70
86
  return new Promise((resolve) => {
87
+ const callId = `host_${Date.now()}_${Math.random()}`;
71
88
  const messageHandler = (event) => {
72
89
  if (event.data && event.data.type === "seaverse:service_host") {
73
90
  cleanup();
74
91
  const serviceHost = event.data.payload?.serviceHost;
75
92
  resolve(serviceHost || null);
93
+ } else if (event.data && event.data.type === "seaverse:service_host_response" && event.data.callId === callId) {
94
+ cleanup();
95
+ resolve(event.data.serviceHost || null);
76
96
  } else if (event.data && event.data.type === "seaverse:error") {
77
97
  cleanup();
78
98
  console.warn("[SeaVerse DataService SDK] Error getting serviceHost from parent:", event.data.error);
@@ -89,11 +109,16 @@ async function getServiceHostFromParent(timeout = 500, serviceName = "dataservic
89
109
  };
90
110
  globalThis.window.addEventListener("message", messageHandler);
91
111
  try {
92
- globalThis.window.parent.postMessage(
93
- { type: "seaverse:get_service_host", payload: { serviceName } },
94
- "*"
95
- // Allow any origin, supports cross-domain scenarios
96
- );
112
+ if (isInSeaVerseApp()) {
113
+ globalThis.window.ReactNativeWebView.postMessage(
114
+ JSON.stringify({ type: "seaverse:get_service_host", callId, serviceName })
115
+ );
116
+ } else {
117
+ globalThis.window.parent.postMessage(
118
+ { type: "seaverse:get_service_host", payload: { serviceName } },
119
+ "*"
120
+ );
121
+ }
97
122
  } catch (e) {
98
123
  cleanup();
99
124
  resolve(null);
@@ -101,15 +126,19 @@ async function getServiceHostFromParent(timeout = 500, serviceName = "dataservic
101
126
  });
102
127
  }
103
128
  async function getAppIdFromParent(timeout = 500) {
104
- if (!isInIframe()) {
129
+ if (!isInIframe() && !isInSeaVerseApp()) {
105
130
  return null;
106
131
  }
107
132
  return new Promise((resolve) => {
133
+ const callId = `appid_${Date.now()}_${Math.random()}`;
108
134
  const messageHandler = (event) => {
109
135
  if (event.data && event.data.type === "seaverse:appId") {
110
136
  cleanup();
111
137
  const appId = event.data.payload?.appId;
112
138
  resolve(appId || null);
139
+ } else if (event.data && event.data.type === "seaverse:appId_response" && event.data.callId === callId) {
140
+ cleanup();
141
+ resolve(event.data.appId || null);
113
142
  } else if (event.data && event.data.type === "seaverse:error") {
114
143
  cleanup();
115
144
  console.warn("[SeaVerse DataService SDK] Error getting appId from parent:", event.data.error);
@@ -126,10 +155,16 @@ async function getAppIdFromParent(timeout = 500) {
126
155
  };
127
156
  globalThis.window.addEventListener("message", messageHandler);
128
157
  try {
129
- globalThis.window.parent.postMessage(
130
- { type: "seaverse:get_appId" },
131
- "*"
132
- );
158
+ if (isInSeaVerseApp()) {
159
+ globalThis.window.ReactNativeWebView.postMessage(
160
+ JSON.stringify({ type: "seaverse:get_appId", callId })
161
+ );
162
+ } else {
163
+ globalThis.window.parent.postMessage(
164
+ { type: "seaverse:get_appId" },
165
+ "*"
166
+ );
167
+ }
133
168
  } catch (e) {
134
169
  cleanup();
135
170
  resolve(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seaverse/dataservice",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "AI-Friendly Universal Data Storage SDK for TypeScript/JavaScript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",