@eidos.space/client 0.2.0 → 0.4.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/dist/index.d.mts CHANGED
@@ -1,10 +1,38 @@
1
- import { DataSpace, DataSpace as DataSpace$1 } from "@eidos.space/core";
1
+ import { DataSpace, DataSpace as DataSpace$1, Eidos } from "@eidos.space/core";
2
2
 
3
3
  //#region src/types.d.ts
4
+ /**
5
+ * Main thread bridge for AI, script, and utils operations
6
+ * These features require a main thread environment with UI capabilities
7
+ */
8
+ interface MainThreadBridge {
9
+ /** Generate text using AI */
10
+ generateText: (options: {
11
+ model?: string;
12
+ prompt: string;
13
+ [key: string]: any;
14
+ }) => Promise<string>;
15
+ /** Generate structured object using AI */
16
+ generateObject: (options: {
17
+ model?: string;
18
+ prompt: string;
19
+ schema: Record<string, any>;
20
+ [key: string]: any;
21
+ }) => Promise<Record<string, any>>;
22
+ /** Call another script */
23
+ callScript: (scriptId: string, ...args: any[]) => Promise<any>;
24
+ /** Fetch blob from URL */
25
+ fetchBlob: (url: string, options?: RequestInit) => Promise<Blob>;
26
+ /** Highlight a row in the table view */
27
+ tableHighlightRow: (tableId: string, rowId: string, fieldId?: string) => void;
28
+ }
4
29
  /**
5
30
  * Eidos client interface
31
+ *
32
+ * AI, script, and utils methods require a mainThreadBridge to be provided
33
+ * in the configuration. Without it, these methods will throw errors.
6
34
  */
7
- interface EidosClient {
35
+ interface EidosClient extends Eidos {
8
36
  /**
9
37
  * The current data space
10
38
  */
@@ -26,6 +54,11 @@ interface EidosClientConfig {
26
54
  fetch?: typeof fetch;
27
55
  /** API Key for authentication */
28
56
  apiKey?: string;
57
+ /**
58
+ * Main thread bridge for AI, script, and utils operations
59
+ * Required for features that need main thread capabilities
60
+ */
61
+ mainThreadBridge?: MainThreadBridge;
29
62
  }
30
63
  //#endregion
31
64
  //#region src/transport.d.ts
@@ -63,11 +96,37 @@ declare function onCallBack(port: TransportPort): Promise<any>;
63
96
  */
64
97
  declare function createSpaceProxy(config: TransportConfig): {};
65
98
  //#endregion
99
+ //#region src/binary-data.d.ts
100
+ declare function containsBinaryData(data: any): boolean;
101
+ declare function processBinaryDataForResponse(data: any, onBinaryData: (binaryData: Blob) => string): any;
102
+ declare function restoreBinaryData(data: any, binaryDataMap: Record<string, any>): any;
103
+ declare function parseMultipartFormData(req: Request): Promise<Record<string, any>>;
104
+ //#endregion
66
105
  //#region src/index.d.ts
67
106
  /**
68
107
  * Create an Eidos client for connecting to headless server
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * // Basic usage (headless mode)
112
+ * const eidos = createEidosClient({
113
+ * endpoint: 'http://localhost:3000/rpc'
114
+ * })
115
+ *
116
+ * // With main thread bridge (for iframe/webview environments)
117
+ * const eidos = createEidosClient({
118
+ * endpoint: 'http://localhost:3000/rpc',
119
+ * mainThreadBridge: {
120
+ * generateText: async (options) => { ... },
121
+ * generateObject: async (options) => { ... },
122
+ * callScript: async (scriptId, ...args) => { ... },
123
+ * fetchBlob: async (url, options) => { ... },
124
+ * tableHighlightRow: (tableId, rowId, fieldId) => { ... }
125
+ * }
126
+ * })
127
+ * ```
69
128
  */
70
129
  declare function createEidosClient(config: EidosClientConfig): EidosClient;
71
130
  //#endregion
72
- export { type DataSpace, type EidosClient, type EidosClientConfig, type TransportConfig, type TransportPort, createEidosClient, createHttpTransport, createSpaceProxy, onCallBack };
131
+ export { type DataSpace, type EidosClient, type EidosClientConfig, type MainThreadBridge, type TransportConfig, type TransportPort, containsBinaryData, createEidosClient, createHttpTransport, createSpaceProxy, onCallBack, parseMultipartFormData, processBinaryDataForResponse, restoreBinaryData };
73
132
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/transport.ts","../src/space-proxy.ts","../src/index.ts"],"mappings":";;;;AAKA;;UAAiB,WAAA;EAAA;;;EAIf,YAAA,EAAc,WAAA;EAAA;;;EAId,KAAA,EAAO,WAAA;AAAA;AAAA;;;AAAA,UAMQ,iBAAA;EAAA;EAEf,QAAA;EAAA;EAEA,OAAA;EAAA;EAEA,KAAA,UAAe,KAAA;EAAA;EAEf,MAAA;AAAA;;;;ACtBF;;;UAAiB,eAAA;EACf,QAAA;EACA,OAAA;EACA,KAAA,UAAe,KAAA;EACf,MAAA;AAAA;AAAA,UAGe,aAAA;EACf,SAAA,IAAa,KAAA;IAAS,IAAA;EAAA;EACtB,KAAA;AAAA;AAAA;;;AAAA,iBAMc,mBAAA,CAAoB,MAAA,EAAQ,eAAA;8BAKR,OAAA,CAAQ,aAAA;;;;;;iBAyD5B,UAAA,CAAW,IAAA,EAAM,aAAA,GAAgB,OAAA;;;;ACvEjD;;iBAAgB,gBAAA,CAAiB,MAAA,EAAQ,eAAA;;;;ACqBzC;;iBAAgB,iBAAA,CAAkB,MAAA,EAAQ,iBAAA,GAAoB,WAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/transport.ts","../src/space-proxy.ts","../src/binary-data.ts","../src/index.ts"],"mappings":";;;;AAMA;;;UAAiB,gBAAA;EAAA;EAEf,YAAA,GAAe,OAAA;IACb,KAAA;IACA,MAAA;IAAA,CACC,GAAA;EAAA,MACG,OAAA;EAAA;EAGN,cAAA,GAAiB,OAAA;IACf,KAAA;IACA,MAAA;IACA,MAAA,EAAQ,MAAA;IAAA,CACP,GAAA;EAAA,MACG,OAAA,CAAQ,MAAA;EAAA;EAGd,UAAA,GAAa,QAAA,aAAqB,IAAA,YAAgB,OAAA;EAAA;EAGlD,SAAA,GAAY,GAAA,UAAa,OAAA,GAAU,WAAA,KAAgB,OAAA,CAAQ,IAAA;EAAA;EAG3D,iBAAA,GAAoB,OAAA,UAAiB,KAAA,UAAe,OAAA;AAAA;AAAA;;;AAStD;;;AATsD,UASrC,WAAA,SAAoB,KAAA;EAAA;;;EAInC,YAAA,EAAc,WAAA;EAAA;;;EAId,KAAA,EAAO,WAAA;AAAA;AAAA;;;AAAA,UAMQ,iBAAA;EAAA;EAEf,QAAA;EAAA;EAEA,OAAA;EAAA;EAEA,KAAA,UAAe,KAAA;EAAA;EAEf,MAAA;EAAA;;;;EAKA,gBAAA,GAAmB,gBAAA;AAAA;;;;AC5DrB;;;UAAiB,eAAA;EACf,QAAA;EACA,OAAA;EACA,KAAA,UAAe,KAAA;EACf,MAAA;AAAA;AAAA,UAGe,aAAA;EACf,SAAA,IAAa,KAAA;IAAS,IAAA;EAAA;EACtB,KAAA;AAAA;AAAA;;;AAAA,iBAQc,mBAAA,CAAoB,MAAA,EAAQ,eAAA;8BAKR,OAAA,CAAQ,aAAA;;;;;;iBAqG5B,UAAA,CAAW,IAAA,EAAM,aAAA,GAAgB,OAAA;;;;ACrHjD;;iBAAgB,gBAAA,CAAiB,MAAA,EAAQ,eAAA;;;iBCVzB,kBAAA,CAAmB,IAAA;AAAA,iBAoFnB,4BAAA,CACd,IAAA,OACA,YAAA,GAAe,UAAA,EAAY,IAAA;AAAA,iBAiDb,iBAAA,CACd,IAAA,OACA,aAAA,EAAe,MAAA;AAAA,iBAiFK,sBAAA,CACpB,GAAA,EAAK,OAAA,GACJ,OAAA,CAAQ,MAAA;;;;AClKX;;;;;;;;;;;;;;;;;;;;;;iBAAgB,iBAAA,CAAkB,MAAA,EAAQ,iBAAA,GAAoB,WAAA"}
package/dist/index.mjs CHANGED
@@ -1,3 +1,199 @@
1
+ //#region src/binary-data.ts
2
+ function containsBinaryData(data) {
3
+ if (data === null || data === void 0) return false;
4
+ if (data instanceof ArrayBuffer || data instanceof Blob || data instanceof File) return true;
5
+ if (data && data.buffer instanceof ArrayBuffer && data.byteLength !== void 0) return true;
6
+ if (Array.isArray(data)) return data.some((item) => containsBinaryData(item));
7
+ if (typeof data === "object") return Object.values(data).some((value) => containsBinaryData(value));
8
+ return false;
9
+ }
10
+ function processBinaryData(data, onBinaryData) {
11
+ if (data === null || data === void 0) return data;
12
+ if (data instanceof ArrayBuffer) return {
13
+ __binary_ref: onBinaryData(new Blob([data])),
14
+ type: "ArrayBuffer"
15
+ };
16
+ if (data && data.buffer instanceof ArrayBuffer && data.byteLength !== void 0) return {
17
+ __binary_ref: onBinaryData(new Blob([data.buffer])),
18
+ type: data.constructor.name,
19
+ byteLength: data.byteLength
20
+ };
21
+ if (data instanceof Blob) return {
22
+ __binary_ref: onBinaryData(data),
23
+ type: "Blob"
24
+ };
25
+ if (data instanceof File) return {
26
+ __binary_ref: onBinaryData(data),
27
+ type: "File",
28
+ name: data.name
29
+ };
30
+ if (Array.isArray(data)) return data.map((item) => processBinaryData(item, onBinaryData));
31
+ if (typeof data === "object") {
32
+ const processed = {};
33
+ for (const [key, value] of Object.entries(data)) processed[key] = processBinaryData(value, onBinaryData);
34
+ return processed;
35
+ }
36
+ return data;
37
+ }
38
+ function processBinaryDataForResponse(data, onBinaryData) {
39
+ if (data === null || data === void 0) return data;
40
+ if (data instanceof ArrayBuffer) return {
41
+ __binary_ref: onBinaryData(new Blob([data])),
42
+ type: "ArrayBuffer"
43
+ };
44
+ if (data && data.buffer instanceof ArrayBuffer && data.byteLength !== void 0) return {
45
+ __binary_ref: onBinaryData(new Blob([data.buffer])),
46
+ type: data.constructor.name,
47
+ byteLength: data.byteLength
48
+ };
49
+ if (data instanceof Blob) return {
50
+ __binary_ref: onBinaryData(data),
51
+ type: "Blob"
52
+ };
53
+ if (data instanceof File) return {
54
+ __binary_ref: onBinaryData(data),
55
+ type: "File",
56
+ name: data.name
57
+ };
58
+ if (Array.isArray(data)) return data.map((item) => processBinaryDataForResponse(item, onBinaryData));
59
+ if (typeof data === "object") {
60
+ const processed = {};
61
+ for (const [key, value] of Object.entries(data)) processed[key] = processBinaryDataForResponse(value, onBinaryData);
62
+ return processed;
63
+ }
64
+ return data;
65
+ }
66
+ function restoreBinaryData(data, binaryDataMap) {
67
+ if (data === null || data === void 0) return data;
68
+ if (typeof data === "object" && data.__binary_ref) {
69
+ const binaryData = binaryDataMap[data.__binary_ref];
70
+ if (!binaryData) throw new Error(`Binary data reference not found: ${data.__binary_ref}`);
71
+ if (data.type === "ArrayBuffer") return binaryData.data;
72
+ if (data.type && data.type.includes("Array") && data.type !== "ArrayBuffer") {
73
+ const arrayBuffer = binaryData.data;
74
+ const byteLength = data.byteLength || arrayBuffer.byteLength;
75
+ switch (data.type) {
76
+ case "Uint8Array": return new Uint8Array(arrayBuffer, 0, byteLength);
77
+ case "Uint8ClampedArray": return new Uint8ClampedArray(arrayBuffer, 0, byteLength);
78
+ case "Uint16Array": return new Uint16Array(arrayBuffer, 0, byteLength / 2);
79
+ case "Uint32Array": return new Uint32Array(arrayBuffer, 0, byteLength / 4);
80
+ case "Int8Array": return new Int8Array(arrayBuffer, 0, byteLength);
81
+ case "Int16Array": return new Int16Array(arrayBuffer, 0, byteLength / 2);
82
+ case "Int32Array": return new Int32Array(arrayBuffer, 0, byteLength / 4);
83
+ case "Float32Array": return new Float32Array(arrayBuffer, 0, byteLength / 4);
84
+ case "Float64Array": return new Float64Array(arrayBuffer, 0, byteLength / 8);
85
+ default: return new Uint8Array(arrayBuffer, 0, byteLength);
86
+ }
87
+ }
88
+ if (data.type === "Blob") return new Blob([binaryData.data], { type: binaryData.type });
89
+ if (data.type === "File") return new File([binaryData.data], data.name || binaryData.name, { type: binaryData.type });
90
+ return binaryData;
91
+ }
92
+ if (Array.isArray(data)) return data.map((item) => restoreBinaryData(item, binaryDataMap));
93
+ if (typeof data === "object") {
94
+ const restored = {};
95
+ for (const [key, value] of Object.entries(data)) restored[key] = restoreBinaryData(value, binaryDataMap);
96
+ return restored;
97
+ }
98
+ return data;
99
+ }
100
+ async function parseMultipartFormData(req) {
101
+ const contentType = req.headers.get("content-type") || "";
102
+ if (!contentType.includes("multipart/form-data")) throw new Error("Not a multipart/form-data request");
103
+ const boundaryMatch = contentType.match(/boundary=([^;]+)/);
104
+ if (!boundaryMatch) throw new Error("No boundary found in multipart/form-data header");
105
+ const boundary = boundaryMatch[1].trim();
106
+ const bodyBuffer = await req.arrayBuffer();
107
+ const bodyBytes = new Uint8Array(bodyBuffer);
108
+ const boundaryBytes = new TextEncoder().encode(`--${boundary}`);
109
+ const formData = {};
110
+ let start = 0;
111
+ let partIndex = 0;
112
+ while (start < bodyBytes.length) {
113
+ let boundaryStart = -1;
114
+ for (let i = start; i <= bodyBytes.length - boundaryBytes.length; i++) {
115
+ let match = true;
116
+ for (let j = 0; j < boundaryBytes.length; j++) if (bodyBytes[i + j] !== boundaryBytes[j]) {
117
+ match = false;
118
+ break;
119
+ }
120
+ if (match) {
121
+ boundaryStart = i;
122
+ break;
123
+ }
124
+ }
125
+ if (boundaryStart === -1) break;
126
+ start = boundaryStart + boundaryBytes.length;
127
+ if (start < bodyBytes.length && bodyBytes[start] === 13 && bodyBytes[start + 1] === 10) start += 2;
128
+ let nextBoundaryStart = -1;
129
+ for (let i = start; i <= bodyBytes.length - boundaryBytes.length; i++) {
130
+ let match = true;
131
+ for (let j = 0; j < boundaryBytes.length; j++) if (bodyBytes[i + j] !== boundaryBytes[j]) {
132
+ match = false;
133
+ break;
134
+ }
135
+ if (match) {
136
+ nextBoundaryStart = i;
137
+ break;
138
+ }
139
+ }
140
+ if (nextBoundaryStart === -1) {
141
+ const termBoundary = new TextEncoder().encode(`--${boundary}--`);
142
+ for (let i = start; i <= bodyBytes.length - termBoundary.length; i++) {
143
+ let match = true;
144
+ for (let j = 0; j < termBoundary.length; j++) if (bodyBytes[i + j] !== termBoundary[j]) {
145
+ match = false;
146
+ break;
147
+ }
148
+ if (match) {
149
+ nextBoundaryStart = i;
150
+ break;
151
+ }
152
+ }
153
+ if (nextBoundaryStart === -1) nextBoundaryStart = bodyBytes.length;
154
+ }
155
+ const partEnd = nextBoundaryStart;
156
+ if (partEnd <= start) break;
157
+ const partBytes = bodyBytes.slice(start, partEnd);
158
+ let headerEnd = -1;
159
+ for (let i = 0; i <= partBytes.length - 4; i++) if (partBytes[i] === 13 && partBytes[i + 1] === 10 && partBytes[i + 2] === 13 && partBytes[i + 3] === 10) {
160
+ headerEnd = i;
161
+ break;
162
+ }
163
+ if (headerEnd === -1) {
164
+ start = partEnd;
165
+ continue;
166
+ }
167
+ const headerBytes = partBytes.slice(0, headerEnd);
168
+ const headerText = new TextDecoder().decode(headerBytes);
169
+ const contentDisposition = headerText.match(/Content-Disposition: form-data; name="([^"]+)"/);
170
+ if (!contentDisposition) {
171
+ start = partEnd;
172
+ continue;
173
+ }
174
+ const fieldName = contentDisposition[1];
175
+ const contentStart = headerEnd + 4;
176
+ let contentEnd = partBytes.length;
177
+ if (contentEnd >= contentStart + 2 && partBytes[contentEnd - 2] === 13 && partBytes[contentEnd - 1] === 10) contentEnd -= 2;
178
+ const contentBytes = partBytes.slice(contentStart, contentEnd);
179
+ const filenameMatch = headerText.match(/filename="([^"]+)"/);
180
+ if (filenameMatch) {
181
+ const filename = filenameMatch[1];
182
+ const contentTypeMatch = headerText.match(/Content-Type: ([^\r\n]+)/);
183
+ formData[fieldName] = {
184
+ name: filename,
185
+ type: contentTypeMatch ? contentTypeMatch[1].trim() : "application/octet-stream",
186
+ data: contentBytes.slice().buffer,
187
+ size: contentBytes.length
188
+ };
189
+ } else formData[fieldName] = new TextDecoder().decode(contentBytes);
190
+ start = partEnd;
191
+ partIndex++;
192
+ }
193
+ return formData;
194
+ }
195
+
196
+ //#endregion
1
197
  //#region src/transport.ts
2
198
  /**
3
199
  * Create HTTP transport for RPC calls
@@ -10,20 +206,51 @@ function createHttpTransport(config) {
10
206
  const controller = new AbortController();
11
207
  const timeoutId = setTimeout(() => controller.abort(), timeout);
12
208
  try {
209
+ let body;
210
+ let headers = { ...config.apiKey ? { "Authorization": `Bearer ${config.apiKey}` } : {} };
211
+ if (containsBinaryData(requestData)) {
212
+ const formData = new FormData();
213
+ let binaryIndex = 0;
214
+ const processedData = processBinaryData(requestData, (binaryData) => {
215
+ const fieldName = `binary_${binaryIndex++}`;
216
+ formData.append(fieldName, binaryData);
217
+ return fieldName;
218
+ });
219
+ formData.append("json", JSON.stringify(processedData));
220
+ body = formData;
221
+ } else {
222
+ body = JSON.stringify(requestData);
223
+ headers["Content-Type"] = "application/json";
224
+ }
13
225
  const response = await fetchFn(endpoint, {
14
226
  method: "POST",
15
- headers: {
16
- "Content-Type": "application/json",
17
- ...config.apiKey ? { "Authorization": `Bearer ${config.apiKey}` } : {}
18
- },
19
- body: JSON.stringify(requestData),
227
+ headers,
228
+ body,
20
229
  signal: controller.signal
21
230
  });
22
231
  clearTimeout(timeoutId);
23
232
  if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
24
- const jsonData = await response.json();
25
- if (!jsonData.success) throw new Error(jsonData.error || "RPC call failed");
26
- const responseData = jsonData.data;
233
+ const contentType = response.headers.get("content-type");
234
+ let responseData;
235
+ if (contentType && contentType.includes("multipart/form-data")) {
236
+ const formData = await response.formData();
237
+ const jsonData = JSON.parse(formData.get("json") || "{}");
238
+ if (!jsonData.success) throw new Error(jsonData.error || "RPC call failed");
239
+ const binaryDataMap = {};
240
+ for (const [key, entryValue] of formData.entries()) {
241
+ const value = entryValue;
242
+ if (key.startsWith("binary_") && value instanceof Blob) binaryDataMap[key] = {
243
+ data: await value.arrayBuffer(),
244
+ type: value.type,
245
+ size: value.size
246
+ };
247
+ }
248
+ responseData = restoreBinaryData(jsonData.data, binaryDataMap);
249
+ } else {
250
+ const jsonData = await response.json();
251
+ if (!jsonData.success) throw new Error(jsonData.error || "RPC call failed");
252
+ responseData = jsonData.data;
253
+ }
27
254
  const simulatedPort = {
28
255
  onmessage: null,
29
256
  close: () => {}
@@ -95,6 +322,7 @@ function createSpaceProxy(config) {
95
322
  if ([
96
323
  "doc",
97
324
  "action",
325
+ "schema",
98
326
  "graft",
99
327
  "script",
100
328
  "extension",
@@ -107,7 +335,10 @@ function createSpaceProxy(config) {
107
335
  "theme",
108
336
  "dataView",
109
337
  "kv",
110
- "fs"
338
+ "fs",
339
+ "AI",
340
+ "ai",
341
+ "utils"
111
342
  ].includes(method)) return new Proxy({}, { get(target$1, subMethod) {
112
343
  return async function(...params) {
113
344
  return onCallBack(await transport.send({
@@ -152,10 +383,34 @@ function createSpaceProxy(config) {
152
383
  * ```
153
384
  */
154
385
  /**
386
+ * Error message for features not available without main thread bridge
387
+ */
388
+ const NO_BRIDGE_ERROR = (feature) => `${feature} is not available without a mainThreadBridge. Please provide a mainThreadBridge in the configuration to enable this feature.`;
389
+ /**
155
390
  * Create an Eidos client for connecting to headless server
391
+ *
392
+ * @example
393
+ * ```typescript
394
+ * // Basic usage (headless mode)
395
+ * const eidos = createEidosClient({
396
+ * endpoint: 'http://localhost:3000/rpc'
397
+ * })
398
+ *
399
+ * // With main thread bridge (for iframe/webview environments)
400
+ * const eidos = createEidosClient({
401
+ * endpoint: 'http://localhost:3000/rpc',
402
+ * mainThreadBridge: {
403
+ * generateText: async (options) => { ... },
404
+ * generateObject: async (options) => { ... },
405
+ * callScript: async (scriptId, ...args) => { ... },
406
+ * fetchBlob: async (url, options) => { ... },
407
+ * tableHighlightRow: (tableId, rowId, fieldId) => { ... }
408
+ * }
409
+ * })
410
+ * ```
156
411
  */
157
412
  function createEidosClient(config) {
158
- const { endpoint, timeout, fetch: fetchFn } = config;
413
+ const { endpoint, timeout, fetch: fetchFn, mainThreadBridge } = config;
159
414
  const spaceProxy = createSpaceProxy({
160
415
  endpoint,
161
416
  timeout,
@@ -164,10 +419,34 @@ function createEidosClient(config) {
164
419
  });
165
420
  return {
166
421
  currentSpace: spaceProxy,
167
- space: spaceProxy
422
+ space: spaceProxy,
423
+ AI: {
424
+ generateText: (options) => {
425
+ if (!mainThreadBridge) throw new Error(NO_BRIDGE_ERROR("AI.generateText"));
426
+ return mainThreadBridge.generateText(options);
427
+ },
428
+ generateObject: (options) => {
429
+ if (!mainThreadBridge) throw new Error(NO_BRIDGE_ERROR("AI.generateObject"));
430
+ return mainThreadBridge.generateObject(options);
431
+ }
432
+ },
433
+ script: { call: (scriptId, ...args) => {
434
+ if (!mainThreadBridge) throw new Error(NO_BRIDGE_ERROR("script.call"));
435
+ return mainThreadBridge.callScript(scriptId, ...args);
436
+ } },
437
+ utils: {
438
+ fetchBlob: (url, options) => {
439
+ if (!mainThreadBridge) throw new Error(NO_BRIDGE_ERROR("utils.fetchBlob"));
440
+ return mainThreadBridge.fetchBlob(url, options);
441
+ },
442
+ tableHighlightRow: (tableId, rowId, fieldId) => {
443
+ if (!mainThreadBridge) throw new Error(NO_BRIDGE_ERROR("utils.tableHighlightRow"));
444
+ return mainThreadBridge.tableHighlightRow(tableId, rowId, fieldId);
445
+ }
446
+ }
168
447
  };
169
448
  }
170
449
 
171
450
  //#endregion
172
- export { createEidosClient, createHttpTransport, createSpaceProxy, onCallBack };
451
+ export { containsBinaryData, createEidosClient, createHttpTransport, createSpaceProxy, onCallBack, parseMultipartFormData, processBinaryDataForResponse, restoreBinaryData };
173
452
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/transport.ts","../src/space-proxy.ts","../src/index.ts"],"sourcesContent":["/**\n * HTTP Transport for Eidos RPC client\n * Extracted and adapted from packages/sandbox/src/sdk-inject-script.html\n */\n\nexport interface TransportConfig {\n endpoint: string\n timeout?: number\n fetch?: typeof fetch\n apiKey?: string\n}\n\nexport interface TransportPort {\n onmessage: ((event: { data: any }) => void) | null\n close: () => void\n}\n\n/**\n * Create HTTP transport for RPC calls\n */\nexport function createHttpTransport(config: TransportConfig) {\n const { endpoint, timeout = 30000 } = config\n const fetchFn = config.fetch || globalThis.fetch\n \n return {\n send: async (requestData: any): Promise<TransportPort> => {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n \n try {\n const response = await fetchFn(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { 'Authorization': `Bearer ${config.apiKey}` } : {}),\n },\n body: JSON.stringify(requestData),\n signal: controller.signal,\n })\n \n clearTimeout(timeoutId)\n \n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status}`)\n }\n \n const jsonData = await response.json()\n \n if (!jsonData.success) {\n throw new Error(jsonData.error || 'RPC call failed')\n }\n \n const responseData = jsonData.data\n \n // Create simulated port for callback compatibility\n const simulatedPort: TransportPort = {\n onmessage: null,\n close: () => {},\n }\n \n // Async callback\n setTimeout(() => {\n if (simulatedPort.onmessage) {\n simulatedPort.onmessage({\n data: { type: 'rpcCallResp', data: responseData },\n })\n }\n }, 0)\n \n return simulatedPort\n } catch (error) {\n clearTimeout(timeoutId)\n throw error\n }\n },\n close: () => {},\n }\n}\n\n/**\n * Wait for callback from transport port\n */\nexport function onCallBack(port: TransportPort): Promise<any> {\n return new Promise((resolve, reject) => {\n port.onmessage = (event) => {\n port.close()\n const { type, data } = event.data\n if (type === 'rpcCallResp') {\n resolve(data)\n } else {\n reject(new Error('RPC call failed'))\n }\n }\n })\n}\n","/**\n * Space Proxy for Eidos RPC client\n * Creates a Proxy-based interface for calling RPC methods\n * Extracted and adapted from packages/sandbox/src/sdk-inject-script.html\n */\n\nimport { createHttpTransport, onCallBack, TransportConfig } from './transport'\n\n/**\n * Create space proxy with Prisma-style API\n */\nexport function createSpaceProxy(config: TransportConfig) {\n const transport = createHttpTransport(config)\n \n return new Proxy({}, {\n get: (target, method: string) => {\n // Prisma-style table() API\n if (method === 'table') {\n return function(tableId: string) {\n const tableMethods = [\n 'create',\n 'createMany', \n 'findUnique',\n 'findFirst',\n 'findMany',\n 'count',\n 'update',\n 'updateMany',\n 'delete',\n 'deleteMany',\n ]\n \n return new Proxy({}, {\n get(target, tableMethod: string) {\n if (tableMethods.includes(tableMethod)) {\n return async function(args?: any) {\n const port = await transport.send({\n method: `table(${tableId}).${tableMethod}`,\n params: [args],\n })\n return onCallBack(port)\n }\n }\n return undefined\n },\n })\n }\n }\n \n // Namespace APIs: doc, tree, file, kv, fs, etc.\n const namespaces = [\n 'doc',\n 'action', \n 'graft',\n 'script',\n 'extension',\n 'tree',\n 'view',\n 'column',\n 'embedding',\n 'file',\n 'extNode',\n 'theme',\n 'dataView',\n 'kv',\n 'fs',\n ]\n \n if (namespaces.includes(method)) {\n return new Proxy({}, {\n get(target, subMethod: string) {\n return async function(...params: any[]) {\n const port = await transport.send({\n method: `${method}.${subMethod}`,\n params,\n })\n return onCallBack(port)\n }\n },\n })\n }\n \n // Direct method call\n return async (...params: any[]) => {\n const port = await transport.send({\n method,\n params,\n })\n return onCallBack(port)\n }\n },\n })\n}\n","/**\n * @eidos.space/client\n * \n * Eidos RPC client for Node.js and browser environments.\n * Connect to a headless Eidos server via HTTP.\n * \n * @example\n * ```typescript\n * import { createEidosClient } from '@eidos.space/client'\n * \n * const eidos = createEidosClient({\n * endpoint: 'http://localhost:3000/rpc'\n * })\n * \n * // Query table data\n * const posts = await eidos.currentSpace.table('posts').findMany({\n * where: { published: true },\n * orderBy: { created_at: 'desc' }\n * })\n * \n * // Get document\n * const doc = await eidos.currentSpace.doc.get('doc-id')\n * ```\n */\n\nimport { createSpaceProxy } from './space-proxy'\nimport type { EidosClient, EidosClientConfig } from './types'\nimport type { DataSpace } from '@eidos.space/core'\n\n/**\n * Create an Eidos client for connecting to headless server\n */\nexport function createEidosClient(config: EidosClientConfig): EidosClient {\n const { endpoint, timeout, fetch: fetchFn } = config\n \n const spaceProxy = createSpaceProxy({\n endpoint,\n timeout,\n fetch: fetchFn,\n apiKey: config.apiKey,\n }) as unknown as DataSpace\n \n return {\n currentSpace: spaceProxy,\n space: spaceProxy,\n }\n}\n\n// Re-export types\nexport type {\n EidosClient,\n EidosClientConfig,\n} from './types'\n\n// Re-export DataSpace for convenience\nexport type { DataSpace } from '@eidos.space/core'\n\n// Re-export low-level APIs for advanced usage\nexport { createSpaceProxy } from './space-proxy'\nexport { createHttpTransport, onCallBack } from './transport'\nexport type { TransportConfig, TransportPort } from './transport'\n"],"mappings":";;;;AAoBA,SAAgB,oBAAoB,QAAyB;CAC3D,MAAM,EAAE,UAAU,UAAU,QAAU;CACtC,MAAM,UAAU,OAAO,SAAS,WAAW;AAE3C,QAAO;EACL,MAAM,OAAO,gBAA6C;GACxD,MAAM,aAAa,IAAI,iBAAiB;GACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,QAAQ;AAE/D,OAAI;IACF,MAAM,WAAW,MAAM,QAAQ,UAAU;KACvC,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,GAAI,OAAO,SAAS,EAAE,iBAAiB,UAAU,OAAO,UAAU,GAAG,EAAE;MACxE;KACD,MAAM,KAAK,UAAU,YAAY;KACjC,QAAQ,WAAW;KACpB,CAAC;AAEF,iBAAa,UAAU;AAEvB,QAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,eAAe,SAAS,SAAS;IAGnD,MAAM,WAAW,MAAM,SAAS,MAAM;AAEtC,QAAI,CAAC,SAAS,QACZ,OAAM,IAAI,MAAM,SAAS,SAAS,kBAAkB;IAGtD,MAAM,eAAe,SAAS;IAG9B,MAAM,gBAA+B;KACnC,WAAW;KACX,aAAa;KACd;AAGD,qBAAiB;AACf,SAAI,cAAc,UAChB,eAAc,UAAU,EACtB,MAAM;MAAE,MAAM;MAAe,MAAM;MAAc,EAClD,CAAC;OAEH,EAAE;AAEL,WAAO;YACA,OAAO;AACd,iBAAa,UAAU;AACvB,UAAM;;;EAGV,aAAa;EACd;;;;;AAMH,SAAgB,WAAW,MAAmC;AAC5D,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,OAAK,aAAa,UAAU;AAC1B,QAAK,OAAO;GACZ,MAAM,EAAE,MAAM,SAAS,MAAM;AAC7B,OAAI,SAAS,cACX,SAAQ,KAAK;OAEb,wBAAO,IAAI,MAAM,kBAAkB,CAAC;;GAGxC;;;;;;;;;;;;;AClFJ,SAAgB,iBAAiB,QAAyB;CACxD,MAAM,YAAY,oBAAoB,OAAO;AAE7C,QAAO,IAAI,MAAM,EAAE,EAAE,EACnB,MAAM,QAAQ,WAAmB;AAE/B,MAAI,WAAW,QACb,QAAO,SAAS,SAAiB;GAC/B,MAAM,eAAe;IACnB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD;AAED,UAAO,IAAI,MAAM,EAAE,EAAE,EACnB,IAAI,UAAQ,aAAqB;AAC/B,QAAI,aAAa,SAAS,YAAY,CACpC,QAAO,eAAe,MAAY;AAKhC,YAAO,WAJM,MAAM,UAAU,KAAK;MAChC,QAAQ,SAAS,QAAQ,IAAI;MAC7B,QAAQ,CAAC,KAAK;MACf,CAAC,CACqB;;MAK9B,CAAC;;AAuBN,MAlBmB;GACjB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAEc,SAAS,OAAO,CAC7B,QAAO,IAAI,MAAM,EAAE,EAAE,EACnB,IAAI,UAAQ,WAAmB;AAC7B,UAAO,eAAe,GAAG,QAAe;AAKtC,WAAO,WAJM,MAAM,UAAU,KAAK;KAChC,QAAQ,GAAG,OAAO,GAAG;KACrB;KACD,CAAC,CACqB;;KAG5B,CAAC;AAIJ,SAAO,OAAO,GAAG,WAAkB;AAKjC,UAAO,WAJM,MAAM,UAAU,KAAK;IAChC;IACA;IACD,CAAC,CACqB;;IAG5B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3DJ,SAAgB,kBAAkB,QAAwC;CACxE,MAAM,EAAE,UAAU,SAAS,OAAO,YAAY;CAE9C,MAAM,aAAa,iBAAiB;EAClC;EACA;EACA,OAAO;EACP,QAAQ,OAAO;EAChB,CAAC;AAEF,QAAO;EACL,cAAc;EACd,OAAO;EACR"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/binary-data.ts","../src/transport.ts","../src/space-proxy.ts","../src/index.ts"],"sourcesContent":["// Helper function to check if data contains binary content\nexport function containsBinaryData(data: any): boolean {\n if (data === null || data === undefined) return false\n\n if (\n data instanceof ArrayBuffer ||\n data instanceof Blob ||\n data instanceof File\n ) {\n return true\n }\n\n // Check for TypedArray types (Uint8Array, Int8Array, etc.)\n // TypedArray instances have a buffer property that is an ArrayBuffer\n if (\n data &&\n data.buffer instanceof ArrayBuffer &&\n data.byteLength !== undefined\n ) {\n return true\n }\n\n if (Array.isArray(data)) {\n return data.some((item) => containsBinaryData(item))\n }\n\n if (typeof data === \"object\") {\n return Object.values(data).some((value) => containsBinaryData(value))\n }\n\n return false\n}\n\n// Helper function to process binary data and replace with references (for requests)\nexport function processBinaryData(\n data: any,\n onBinaryData: (binaryData: Blob) => string\n): any {\n if (data === null || data === undefined) return data\n\n if (data instanceof ArrayBuffer) {\n const fieldName = onBinaryData(new Blob([data]))\n return { __binary_ref: fieldName, type: \"ArrayBuffer\" }\n }\n\n // Handle TypedArray types (Uint8Array, Int8Array, etc.)\n if (\n data &&\n data.buffer instanceof ArrayBuffer &&\n data.byteLength !== undefined\n ) {\n const fieldName = onBinaryData(new Blob([data.buffer]))\n return {\n __binary_ref: fieldName,\n type: data.constructor.name,\n byteLength: data.byteLength,\n }\n }\n\n if (data instanceof Blob) {\n const fieldName = onBinaryData(data)\n return { __binary_ref: fieldName, type: \"Blob\" }\n }\n\n if (data instanceof File) {\n const fieldName = onBinaryData(data)\n return { __binary_ref: fieldName, type: \"File\", name: data.name }\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => processBinaryData(item, onBinaryData))\n }\n\n if (typeof data === \"object\") {\n const processed: Record<string, any> = {}\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processBinaryData(value, onBinaryData)\n }\n return processed\n }\n\n return data\n}\n\n// Helper function to process binary data for responses (server -> client)\nexport function processBinaryDataForResponse(\n data: any,\n onBinaryData: (binaryData: Blob) => string\n): any {\n if (data === null || data === undefined) return data\n\n if (data instanceof ArrayBuffer) {\n const fieldName = onBinaryData(new Blob([data]))\n return { __binary_ref: fieldName, type: \"ArrayBuffer\" }\n }\n\n // Handle TypedArray types (Uint8Array, Int8Array, etc.)\n if (\n data &&\n data.buffer instanceof ArrayBuffer &&\n data.byteLength !== undefined\n ) {\n const fieldName = onBinaryData(new Blob([data.buffer]))\n return {\n __binary_ref: fieldName,\n type: data.constructor.name,\n byteLength: data.byteLength,\n }\n }\n\n if (data instanceof Blob) {\n const fieldName = onBinaryData(data)\n return { __binary_ref: fieldName, type: \"Blob\" }\n }\n\n if (data instanceof File) {\n const fieldName = onBinaryData(data)\n return { __binary_ref: fieldName, type: \"File\", name: data.name }\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => processBinaryDataForResponse(item, onBinaryData))\n }\n\n if (typeof data === \"object\") {\n const processed: Record<string, any> = {}\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processBinaryDataForResponse(value, onBinaryData)\n }\n return processed\n }\n\n return data\n}\n\n// Helper function to restore binary data from form fields (for responses)\nexport function restoreBinaryData(\n data: any,\n binaryDataMap: Record<string, any>\n): any {\n if (data === null || data === undefined) return data\n\n if (typeof data === \"object\" && data.__binary_ref) {\n const binaryData = binaryDataMap[data.__binary_ref]\n if (!binaryData) {\n throw new Error(`Binary data reference not found: ${data.__binary_ref}`)\n }\n\n if (data.type === \"ArrayBuffer\") {\n // Return the ArrayBuffer directly\n return binaryData.data\n }\n\n // Handle TypedArray types\n if (\n data.type &&\n data.type.includes(\"Array\") &&\n data.type !== \"ArrayBuffer\"\n ) {\n // Create a view of the ArrayBuffer for the specific TypedArray type\n const arrayBuffer = binaryData.data\n const byteLength = data.byteLength || arrayBuffer.byteLength\n\n switch (data.type) {\n case \"Uint8Array\":\n return new Uint8Array(arrayBuffer, 0, byteLength)\n case \"Uint8ClampedArray\":\n return new Uint8ClampedArray(arrayBuffer, 0, byteLength)\n case \"Uint16Array\":\n return new Uint16Array(arrayBuffer, 0, byteLength / 2)\n case \"Uint32Array\":\n return new Uint32Array(arrayBuffer, 0, byteLength / 4)\n case \"Int8Array\":\n return new Int8Array(arrayBuffer, 0, byteLength)\n case \"Int16Array\":\n return new Int16Array(arrayBuffer, 0, byteLength / 2)\n case \"Int32Array\":\n return new Int32Array(arrayBuffer, 0, byteLength / 4)\n case \"Float32Array\":\n return new Float32Array(arrayBuffer, 0, byteLength / 4)\n case \"Float64Array\":\n return new Float64Array(arrayBuffer, 0, byteLength / 8)\n default:\n // Fallback: create Uint8Array for unknown TypedArray types\n return new Uint8Array(arrayBuffer, 0, byteLength)\n }\n }\n\n if (data.type === \"Blob\") {\n // Create a Blob from the ArrayBuffer\n return new Blob([binaryData.data], { type: binaryData.type })\n }\n\n if (data.type === \"File\") {\n // Create a File from the ArrayBuffer\n return new File([binaryData.data], data.name || binaryData.name, {\n type: binaryData.type,\n })\n }\n\n return binaryData\n }\n\n if (Array.isArray(data)) {\n return data.map((item) => restoreBinaryData(item, binaryDataMap))\n }\n\n if (typeof data === \"object\") {\n const restored: Record<string, any> = {}\n for (const [key, value] of Object.entries(data)) {\n restored[key] = restoreBinaryData(value, binaryDataMap)\n }\n return restored\n }\n\n return data\n}\n\n// Helper function to parse multipart form data manually (server-side only)\nexport async function parseMultipartFormData(\n req: Request\n): Promise<Record<string, any>> {\n const contentType = req.headers.get(\"content-type\") || \"\"\n if (!contentType.includes(\"multipart/form-data\")) {\n throw new Error(\"Not a multipart/form-data request\")\n }\n\n // Extract boundary from content-type header\n const boundaryMatch = contentType.match(/boundary=([^;]+)/)\n if (!boundaryMatch) {\n throw new Error(\"No boundary found in multipart/form-data header\")\n }\n const boundary = boundaryMatch[1].trim()\n\n // Read the request body as ArrayBuffer to preserve binary data\n const bodyBuffer = await req.arrayBuffer()\n const bodyBytes = new Uint8Array(bodyBuffer)\n\n // Convert boundary to bytes\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`)\n\n const formData: Record<string, any> = {}\n\n // Find all parts by splitting on boundary\n let start = 0\n let partIndex = 0\n\n while (start < bodyBytes.length) {\n // Find next boundary\n let boundaryStart = -1\n for (let i = start; i <= bodyBytes.length - boundaryBytes.length; i++) {\n let match = true\n for (let j = 0; j < boundaryBytes.length; j++) {\n if (bodyBytes[i + j] !== boundaryBytes[j]) {\n match = false\n break\n }\n }\n if (match) {\n boundaryStart = i\n break\n }\n }\n\n if (boundaryStart === -1) break\n\n // Skip boundary and CRLF\n start = boundaryStart + boundaryBytes.length\n if (\n start < bodyBytes.length &&\n bodyBytes[start] === 13 &&\n bodyBytes[start + 1] === 10\n ) {\n start += 2\n }\n\n // Find end of this part (next boundary or end of data)\n let nextBoundaryStart = -1\n for (let i = start; i <= bodyBytes.length - boundaryBytes.length; i++) {\n let match = true\n for (let j = 0; j < boundaryBytes.length; j++) {\n if (bodyBytes[i + j] !== boundaryBytes[j]) {\n match = false\n break\n }\n }\n if (match) {\n nextBoundaryStart = i\n break\n }\n }\n\n if (nextBoundaryStart === -1) {\n // Last part - check for terminating boundary\n const termBoundary = new TextEncoder().encode(`--${boundary}--`)\n for (let i = start; i <= bodyBytes.length - termBoundary.length; i++) {\n let match = true\n for (let j = 0; j < termBoundary.length; j++) {\n if (bodyBytes[i + j] !== termBoundary[j]) {\n match = false\n break\n }\n }\n if (match) {\n nextBoundaryStart = i\n break\n }\n }\n if (nextBoundaryStart === -1) {\n nextBoundaryStart = bodyBytes.length\n }\n }\n\n const partEnd = nextBoundaryStart\n if (partEnd <= start) break\n\n // Extract this part\n const partBytes = bodyBytes.slice(start, partEnd)\n\n // Find header/body split (look for \\r\\n\\r\\n)\n let headerEnd = -1\n for (let i = 0; i <= partBytes.length - 4; i++) {\n if (\n partBytes[i] === 13 &&\n partBytes[i + 1] === 10 &&\n partBytes[i + 2] === 13 &&\n partBytes[i + 3] === 10\n ) {\n headerEnd = i\n break\n }\n }\n\n if (headerEnd === -1) {\n start = partEnd\n continue\n }\n\n // Parse headers\n const headerBytes = partBytes.slice(0, headerEnd)\n const headerText = new TextDecoder().decode(headerBytes)\n\n // Extract field name from Content-Disposition header\n const contentDisposition = headerText.match(\n /Content-Disposition: form-data; name=\"([^\"]+)\"/\n )\n if (!contentDisposition) {\n start = partEnd\n continue\n }\n\n const fieldName = contentDisposition[1]\n\n // Extract content (skip the \\r\\n\\r\\n separator)\n const contentStart = headerEnd + 4\n let contentEnd = partBytes.length\n\n // Remove trailing \\r\\n if present\n if (\n contentEnd >= contentStart + 2 &&\n partBytes[contentEnd - 2] === 13 &&\n partBytes[contentEnd - 1] === 10\n ) {\n contentEnd -= 2\n }\n\n const contentBytes = partBytes.slice(contentStart, contentEnd)\n\n // Check if this is a file upload\n const filenameMatch = headerText.match(/filename=\"([^\"]+)\"/)\n\n if (filenameMatch) {\n // This is a file upload - create a Blob-like object\n const filename = filenameMatch[1]\n const contentTypeMatch = headerText.match(/Content-Type: ([^\\r\\n]+)/)\n const mimeType = contentTypeMatch\n ? contentTypeMatch[1].trim()\n : \"application/octet-stream\"\n\n // Create ArrayBuffer from raw bytes\n const arrayBuffer = contentBytes.slice().buffer\n\n formData[fieldName] = {\n name: filename,\n type: mimeType,\n data: arrayBuffer,\n size: contentBytes.length,\n }\n } else {\n // This is a regular field - decode as text\n formData[fieldName] = new TextDecoder().decode(contentBytes)\n }\n\n start = partEnd\n partIndex++\n }\n\n return formData\n}\n","/**\n * HTTP Transport for Eidos RPC client\n * Extracted and adapted from packages/sandbox/src/sdk-inject-script.html\n */\n\nexport interface TransportConfig {\n endpoint: string\n timeout?: number\n fetch?: typeof fetch\n apiKey?: string\n}\n\nexport interface TransportPort {\n onmessage: ((event: { data: any }) => void) | null\n close: () => void\n}\n\nimport { containsBinaryData, processBinaryData, restoreBinaryData } from './binary-data'\n\n/**\n * Create HTTP transport for RPC calls\n */\nexport function createHttpTransport(config: TransportConfig) {\n const { endpoint, timeout = 30000 } = config\n const fetchFn = config.fetch || globalThis.fetch\n \n return {\n send: async (requestData: any): Promise<TransportPort> => {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n \n try {\n let body: any\n let headers: Record<string, string> = {\n ...(config.apiKey ? { 'Authorization': `Bearer ${config.apiKey}` } : {}),\n }\n\n const hasBinaryData = containsBinaryData(requestData)\n\n if (hasBinaryData) {\n const formData = new FormData()\n let binaryIndex = 0\n const processedData = processBinaryData(requestData, (binaryData) => {\n const fieldName = `binary_${binaryIndex++}`\n formData.append(fieldName, binaryData)\n return fieldName\n })\n formData.append('json', JSON.stringify(processedData))\n body = formData\n // Browser will set Content-Type with boundary for FormData\n } else {\n body = JSON.stringify(requestData)\n headers['Content-Type'] = 'application/json'\n }\n\n const response = await fetchFn(endpoint, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n })\n \n clearTimeout(timeoutId)\n \n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status}`)\n }\n \n const contentType = response.headers.get('content-type')\n let responseData: any\n\n if (contentType && contentType.includes('multipart/form-data')) {\n const formData = await response.formData()\n const jsonData = JSON.parse(formData.get('json') as string || '{}')\n \n if (!jsonData.success) {\n throw new Error(jsonData.error || 'RPC call failed')\n }\n\n const binaryDataMap: Record<string, any> = {}\n for (const [key, entryValue] of formData.entries()) {\n const value = entryValue as any\n if (key.startsWith('binary_') && value instanceof Blob) {\n const arrayBuffer = await value.arrayBuffer()\n binaryDataMap[key] = {\n data: arrayBuffer,\n type: value.type,\n size: value.size,\n }\n }\n }\n responseData = restoreBinaryData(jsonData.data, binaryDataMap)\n } else {\n const jsonData = await response.json()\n if (!jsonData.success) {\n throw new Error(jsonData.error || 'RPC call failed')\n }\n responseData = jsonData.data\n }\n \n // Create simulated port for callback compatibility\n const simulatedPort: TransportPort = {\n onmessage: null,\n close: () => {},\n }\n \n // Async callback\n setTimeout(() => {\n if (simulatedPort.onmessage) {\n simulatedPort.onmessage({\n data: { type: 'rpcCallResp', data: responseData },\n })\n }\n }, 0)\n \n return simulatedPort\n } catch (error) {\n clearTimeout(timeoutId)\n throw error\n }\n },\n close: () => {},\n }\n}\n\n/**\n * Wait for callback from transport port\n */\nexport function onCallBack(port: TransportPort): Promise<any> {\n return new Promise((resolve, reject) => {\n port.onmessage = (event) => {\n port.close()\n const { type, data } = event.data\n if (type === 'rpcCallResp') {\n resolve(data)\n } else {\n reject(new Error('RPC call failed'))\n }\n }\n })\n}\n","/**\n * Space Proxy for Eidos RPC client\n * Creates a Proxy-based interface for calling RPC methods\n * Extracted and adapted from packages/sandbox/src/sdk-inject-script.html\n */\n\nimport { createHttpTransport, onCallBack, TransportConfig } from './transport'\n\n/**\n * Create space proxy with Prisma-style API\n */\nexport function createSpaceProxy(config: TransportConfig) {\n const transport = createHttpTransport(config)\n \n return new Proxy({}, {\n get: (target, method: string) => {\n // Prisma-style table() API\n if (method === 'table') {\n return function(tableId: string) {\n const tableMethods = [\n 'create',\n 'createMany', \n 'findUnique',\n 'findFirst',\n 'findMany',\n 'count',\n 'update',\n 'updateMany',\n 'delete',\n 'deleteMany',\n ]\n \n return new Proxy({}, {\n get(target, tableMethod: string) {\n if (tableMethods.includes(tableMethod)) {\n return async function(args?: any) {\n const port = await transport.send({\n method: `table(${tableId}).${tableMethod}`,\n params: [args],\n })\n return onCallBack(port)\n }\n }\n return undefined\n },\n })\n }\n }\n \n // Namespace APIs: doc, tree, file, kv, fs, etc.\n const namespaces = [\n 'doc',\n 'action', \n 'schema',\n 'graft',\n 'script',\n 'extension',\n 'tree',\n 'view',\n 'column',\n 'embedding',\n 'file',\n 'extNode',\n 'theme',\n 'dataView',\n 'kv',\n 'fs',\n 'AI',\n 'ai',\n 'utils',\n ]\n \n if (namespaces.includes(method)) {\n return new Proxy({}, {\n get(target, subMethod: string) {\n return async function(...params: any[]) {\n const port = await transport.send({\n method: `${method}.${subMethod}`,\n params,\n })\n return onCallBack(port)\n }\n },\n })\n }\n \n // Direct method call\n return async (...params: any[]) => {\n const port = await transport.send({\n method,\n params,\n })\n return onCallBack(port)\n }\n },\n })\n}\n","/**\n * @eidos.space/client\n * \n * Eidos RPC client for Node.js and browser environments.\n * Connect to a headless Eidos server via HTTP.\n * \n * @example\n * ```typescript\n * import { createEidosClient } from '@eidos.space/client'\n * \n * const eidos = createEidosClient({\n * endpoint: 'http://localhost:3000/rpc'\n * })\n * \n * // Query table data\n * const posts = await eidos.currentSpace.table('posts').findMany({\n * where: { published: true },\n * orderBy: { created_at: 'desc' }\n * })\n * \n * // Get document\n * const doc = await eidos.currentSpace.doc.get('doc-id')\n * ```\n */\n\nimport { createSpaceProxy } from './space-proxy'\nimport type { EidosClient, EidosClientConfig } from './types'\nimport type { DataSpace } from '@eidos.space/core'\n\n/**\n * Error message for features not available without main thread bridge\n */\nconst NO_BRIDGE_ERROR = (feature: string) => \n `${feature} is not available without a mainThreadBridge. ` +\n `Please provide a mainThreadBridge in the configuration to enable this feature.`\n\n/**\n * Create an Eidos client for connecting to headless server\n * \n * @example\n * ```typescript\n * // Basic usage (headless mode)\n * const eidos = createEidosClient({\n * endpoint: 'http://localhost:3000/rpc'\n * })\n * \n * // With main thread bridge (for iframe/webview environments)\n * const eidos = createEidosClient({\n * endpoint: 'http://localhost:3000/rpc',\n * mainThreadBridge: {\n * generateText: async (options) => { ... },\n * generateObject: async (options) => { ... },\n * callScript: async (scriptId, ...args) => { ... },\n * fetchBlob: async (url, options) => { ... },\n * tableHighlightRow: (tableId, rowId, fieldId) => { ... }\n * }\n * })\n * ```\n */\nexport function createEidosClient(config: EidosClientConfig): EidosClient {\n const { endpoint, timeout, fetch: fetchFn, mainThreadBridge } = config\n \n const spaceProxy = createSpaceProxy({\n endpoint,\n timeout,\n fetch: fetchFn,\n apiKey: config.apiKey,\n }) as unknown as DataSpace\n \n return {\n currentSpace: spaceProxy,\n space: spaceProxy,\n \n // AI methods - use bridge if available\n AI: {\n generateText: (options) => {\n if (!mainThreadBridge) {\n throw new Error(NO_BRIDGE_ERROR('AI.generateText'))\n }\n return mainThreadBridge.generateText(options)\n },\n generateObject: (options) => {\n if (!mainThreadBridge) {\n throw new Error(NO_BRIDGE_ERROR('AI.generateObject'))\n }\n return mainThreadBridge.generateObject(options)\n },\n },\n \n // Script methods - use bridge if available\n script: {\n call: (scriptId, ...args) => {\n if (!mainThreadBridge) {\n throw new Error(NO_BRIDGE_ERROR('script.call'))\n }\n return mainThreadBridge.callScript(scriptId, ...args)\n },\n },\n \n // Utils methods - use bridge if available\n utils: {\n fetchBlob: (url, options) => {\n if (!mainThreadBridge) {\n throw new Error(NO_BRIDGE_ERROR('utils.fetchBlob'))\n }\n return mainThreadBridge.fetchBlob(url, options)\n },\n tableHighlightRow: (tableId, rowId, fieldId) => {\n if (!mainThreadBridge) {\n throw new Error(NO_BRIDGE_ERROR('utils.tableHighlightRow'))\n }\n return mainThreadBridge.tableHighlightRow(tableId, rowId, fieldId)\n },\n },\n }\n}\n\n// Re-export types\nexport type {\n EidosClient,\n EidosClientConfig,\n MainThreadBridge,\n} from './types'\n\n// Re-export DataSpace for convenience\nexport type { DataSpace } from '@eidos.space/core'\n\n// Re-export low-level APIs for advanced usage\nexport { createSpaceProxy } from './space-proxy'\nexport { createHttpTransport, onCallBack } from './transport'\nexport type { TransportConfig, TransportPort } from './transport'\n\n// Re-export binary data utilities for server-side usage\nexport {\n containsBinaryData,\n processBinaryDataForResponse,\n restoreBinaryData,\n parseMultipartFormData,\n} from './binary-data'\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eidos.space/client",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Eidos RPC client for Node.js and browser",
5
5
  "keywords": [
6
6
  "eidos",
@@ -23,18 +23,14 @@
23
23
  "homepage": "https://github.com/mayneyao/eidos/tree/main/packages/client#readme",
24
24
  "type": "module",
25
25
  "sideEffects": false,
26
- "publishConfig": {
27
- "access": "public",
28
- "registry": "https://registry.npmjs.org/"
29
- },
30
- "main": "dist/index.js",
31
- "module": "dist/index.js",
32
- "types": "dist/index.d.ts",
26
+ "main": "dist/index.mjs",
27
+ "module": "dist/index.mjs",
28
+ "types": "dist/index.d.mts",
33
29
  "exports": {
34
30
  ".": {
35
- "types": "./dist/index.d.ts",
36
- "import": "./dist/index.js",
37
- "default": "./dist/index.js"
31
+ "types": "./dist/index.d.mts",
32
+ "import": "./dist/index.mjs",
33
+ "default": "./dist/index.mjs"
38
34
  }
39
35
  },
40
36
  "files": [
@@ -43,7 +39,7 @@
43
39
  "LICENSE"
44
40
  ],
45
41
  "dependencies": {
46
- "@eidos.space/core": "^0.28.0"
42
+ "@eidos.space/core": "^0.28.2"
47
43
  },
48
44
  "devDependencies": {
49
45
  "tsdown": "0.20.0-beta.3",
@@ -57,6 +53,10 @@
57
53
  "optional": true
58
54
  }
59
55
  },
56
+ "publishConfig": {
57
+ "access": "public",
58
+ "registry": "https://registry.npmjs.org/"
59
+ },
60
60
  "scripts": {
61
61
  "build": "tsdown",
62
62
  "dev": "tsdown --watch"