@webspatial/core-sdk 1.6.1 → 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.
Files changed (53) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/iife/index.d.ts +386 -236
  3. package/dist/iife/index.global.js +7 -7
  4. package/dist/iife/index.global.js.map +1 -1
  5. package/dist/index.d.ts +386 -236
  6. package/dist/index.js +1467 -1210
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/JSBCommand.ts +30 -100
  10. package/src/Spatial.ts +0 -21
  11. package/src/SpatialScene.ts +1 -5
  12. package/src/SpatialSession.ts +17 -3
  13. package/src/SpatializedDynamic3DElement.ts +0 -1
  14. package/src/SpatializedElementCreator.ts +6 -4
  15. package/src/SpatializedStatic3DElement.test.ts +99 -0
  16. package/src/SpatializedStatic3DElement.ts +99 -1
  17. package/src/WebMsgCommand.ts +10 -0
  18. package/src/coverage-boost.test.ts +38 -119
  19. package/src/index.ts +3 -1
  20. package/src/jsbcommand.coverage.test.ts +19 -48
  21. package/src/platform-adapter/CommandResultUtils.ts +2 -2
  22. package/src/platform-adapter/createPlatformSync.ts +34 -0
  23. package/src/platform-adapter/index.ts +5 -51
  24. package/src/platform-adapter/interface.ts +35 -23
  25. package/src/platform-adapter/pico-os/PicoOSPlatform.ts +84 -52
  26. package/src/platform-adapter/puppeteer/PuppeteerPlatform.ts +37 -11
  27. package/src/platform-adapter/spatialSceneQuery.ts +17 -0
  28. package/src/platform-adapter/ssr/SSRPlatform.ts +24 -15
  29. package/src/platform-adapter/vision-os/VisionOSPlatform.ts +55 -24
  30. package/src/platform-runtime.ts +13 -0
  31. package/src/reality/Attachment.ts +2 -2
  32. package/src/reality/entity/SpatialEntity.ts +0 -2
  33. package/src/reality/realityCreator.ts +15 -1
  34. package/src/reality/resource/SpatialTextureResource.ts +16 -0
  35. package/src/reality/resource/index.ts +1 -0
  36. package/src/runtime/WebSpatialRuntimeError.ts +16 -0
  37. package/src/runtime/capability-data.ts +113 -0
  38. package/src/runtime/contract-review.test.ts +44 -0
  39. package/src/runtime/index.ts +28 -0
  40. package/src/runtime/jsbAdapterPlatform.test.ts +36 -0
  41. package/src/runtime/jsbAdapterPlatform.ts +51 -0
  42. package/src/runtime/keys.ts +129 -0
  43. package/src/runtime/semver.ts +33 -0
  44. package/src/runtime/supports.test.ts +207 -0
  45. package/src/runtime/supports.ts +110 -0
  46. package/src/runtime/types.ts +11 -0
  47. package/src/runtime/userAgent.ts +64 -0
  48. package/src/scene-polyfill.manifest.test.ts +7 -5
  49. package/src/scene-polyfill.ts +8 -5
  50. package/src/spatial-host.ts +25 -0
  51. package/src/types/{global.d.ts → global.ts} +10 -5
  52. package/src/types/types.ts +9 -0
  53. package/src/platform-adapter/android/AndroidPlatform.ts +0 -133
package/dist/index.js CHANGED
@@ -2,73 +2,91 @@
2
2
  (function(){
3
3
  if(typeof window === 'undefined') return;
4
4
  if(!window.__webspatialsdk__) window.__webspatialsdk__ = {}
5
- window.__webspatialsdk__['core-sdk-version'] = "1.6.1"
5
+ window.__webspatialsdk__['core-sdk-version'] = "1.7.0"
6
6
  })()
7
7
 
8
8
  var __defProp = Object.defineProperty;
9
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
- var __getOwnPropNames = Object.getOwnPropertyNames;
11
- var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __esm = (fn, res) => function __init() {
13
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
14
- };
15
9
  var __export = (target, all) => {
16
10
  for (var name in all)
17
11
  __defProp(target, name, { get: all[name], enumerable: true });
18
12
  };
19
- var __copyProps = (to, from, except, desc) => {
20
- if (from && typeof from === "object" || typeof from === "function") {
21
- for (let key of __getOwnPropNames(from))
22
- if (!__hasOwnProp.call(to, key) && key !== except)
23
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
- }
25
- return to;
26
- };
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
13
 
29
- // src/ssr-polyfill.ts
30
- var isSSR, isSSREnv;
31
- var init_ssr_polyfill = __esm({
32
- "src/ssr-polyfill.ts"() {
33
- "use strict";
34
- isSSR = typeof window === "undefined";
35
- isSSREnv = () => isSSR;
14
+ // src/runtime/userAgent.ts
15
+ function parseShellToken(ua) {
16
+ const ws = /\bWSAppShell\/([\w.-]+)/i.exec(ua);
17
+ if (ws?.[1]) return { version: ws[1], source: "wsapp" };
18
+ const pico = /\bPicoWebApp\/([\w.-]+)/i.exec(ua);
19
+ if (pico?.[1]) return { version: pico[1], source: "picoapp" };
20
+ return { version: null, source: null };
21
+ }
22
+ function inferPicoOs(ua) {
23
+ return /\bPicoWebApp\//i.test(ua) || /\bPicoBrowser\b/i.test(ua);
24
+ }
25
+ function inferVisionOsFromUa(ua) {
26
+ return /Mac OS X/i.test(ua);
27
+ }
28
+ function computeRuntimeFromUserAgent(userAgent) {
29
+ if (userAgent === void 0 || userAgent === "") {
30
+ return { type: null, shellVersion: null };
36
31
  }
37
- });
32
+ if (userAgent.includes("Puppeteer")) {
33
+ const { version: version2 } = parseShellToken(userAgent);
34
+ return { type: "puppeteer", shellVersion: version2 };
35
+ }
36
+ const { version, source } = parseShellToken(userAgent);
37
+ if (!version) {
38
+ return { type: null, shellVersion: null };
39
+ }
40
+ if (source === "picoapp" || inferPicoOs(userAgent)) {
41
+ return { type: "picoos", shellVersion: version };
42
+ }
43
+ if (source === "wsapp") {
44
+ if (inferVisionOsFromUa(userAgent)) {
45
+ return { type: "visionos", shellVersion: version };
46
+ }
47
+ return { type: null, shellVersion: version };
48
+ }
49
+ return { type: null, shellVersion: version };
50
+ }
38
51
 
39
- // src/platform-adapter/ssr/SSRPlatform.ts
40
- var SSRPlatform;
41
- var init_SSRPlatform = __esm({
42
- "src/platform-adapter/ssr/SSRPlatform.ts"() {
43
- "use strict";
44
- SSRPlatform = class {
45
- callJSB(cmd, msg) {
46
- return Promise.resolve({
47
- success: true,
48
- data: void 0,
49
- errorCode: void 0,
50
- errorMessage: void 0
51
- });
52
- }
53
- callWebSpatialProtocol(schema, query, target, features) {
54
- return Promise.resolve({
55
- success: true,
56
- data: void 0,
57
- errorCode: void 0,
58
- errorMessage: void 0
59
- });
60
- }
61
- callWebSpatialProtocolSync(schema, query, target, features, resultCallback) {
62
- return {
63
- success: true,
64
- data: void 0,
65
- errorCode: void 0,
66
- errorMessage: void 0
67
- };
68
- }
69
- };
52
+ // src/runtime/jsbAdapterPlatform.ts
53
+ function getWebSpatialVersion(ua) {
54
+ const match = ua.match(/WebSpatial\/(\d+)\.(\d+)\.(\d+)/);
55
+ if (!match) {
56
+ return null;
70
57
  }
71
- });
58
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
59
+ }
60
+ function isVersionGreater(a, b) {
61
+ if (!a) {
62
+ return false;
63
+ }
64
+ for (let index = 0; index < 3; index += 1) {
65
+ const diff = a[index] - b[index];
66
+ if (diff > 0) {
67
+ return true;
68
+ }
69
+ if (diff < 0) {
70
+ return false;
71
+ }
72
+ }
73
+ return false;
74
+ }
75
+ function resolveJsbAdapterPlatform(userAgent) {
76
+ const rt = computeRuntimeFromUserAgent(userAgent);
77
+ if (rt.type === "puppeteer") {
78
+ return "puppeteer";
79
+ }
80
+ const webSpatialVersion = getWebSpatialVersion(userAgent);
81
+ if (userAgent.includes("PicoWebApp") && isVersionGreater(webSpatialVersion, [0, 0, 1])) {
82
+ return "picoos";
83
+ }
84
+ return "visionos";
85
+ }
86
+
87
+ // src/ssr-polyfill.ts
88
+ var isSSR = typeof window === "undefined";
89
+ var isSSREnv = () => isSSR;
72
90
 
73
91
  // src/platform-adapter/CommandResultUtils.ts
74
92
  function CommandResultSuccess(data) {
@@ -87,235 +105,367 @@ function CommandResultFailure(errorCode, errorMessage = "") {
87
105
  errorMessage
88
106
  };
89
107
  }
90
- var init_CommandResultUtils = __esm({
91
- "src/platform-adapter/CommandResultUtils.ts"() {
92
- "use strict";
108
+
109
+ // src/platform-adapter/spatialSceneQuery.ts
110
+ function buildSpatialSceneQuery(url, config) {
111
+ const params = { url, config };
112
+ return Object.keys(params).map((key) => {
113
+ const value = params[key];
114
+ const finalValue = typeof value === "object" ? JSON.stringify(value) : value;
115
+ return `${key}=${encodeURIComponent(finalValue)}`;
116
+ }).join("&");
117
+ }
118
+
119
+ // src/SpatialWebEvent.ts
120
+ var SpatialWebEvent = class _SpatialWebEvent {
121
+ static eventReceiver = {};
122
+ static init() {
123
+ window.__SpatialWebEvent = ({ id, data }) => {
124
+ _SpatialWebEvent.eventReceiver[id]?.(data);
125
+ };
93
126
  }
94
- });
127
+ static addEventReceiver(id, callback) {
128
+ _SpatialWebEvent.eventReceiver[id] = callback;
129
+ }
130
+ static removeEventReceiver(id) {
131
+ delete _SpatialWebEvent.eventReceiver[id];
132
+ }
133
+ };
95
134
 
96
- // src/platform-adapter/puppeteer/PuppeteerPlatform.ts
97
- var PuppeteerPlatform_exports = {};
98
- __export(PuppeteerPlatform_exports, {
99
- PuppeteerPlatform: () => PuppeteerPlatform
100
- });
101
- var PuppeteerPlatform;
102
- var init_PuppeteerPlatform = __esm({
103
- "src/platform-adapter/puppeteer/PuppeteerPlatform.ts"() {
104
- "use strict";
105
- init_CommandResultUtils();
106
- console.log("PuppeteerPlatform");
107
- PuppeteerPlatform = class {
108
- // store iframe instance
109
- iframeRegistry = /* @__PURE__ */ new Map();
110
- constructor() {
111
- }
112
- callJSB(cmd, msg) {
113
- return new Promise((resolve) => {
114
- try {
115
- if (window.__handleJSBMessage) {
116
- try {
117
- console.log(` core-sdk Puppeteer Platform: callJSB: ${cmd}::${msg}`);
118
- const result = window.__handleJSBMessage(`${cmd}::${msg}`);
119
- console.log(
120
- ` core-sdk Puppeteer Platform callJSB result: ${result}`
121
- );
122
- resolve(CommandResultSuccess(result));
123
- } catch (err) {
124
- resolve(CommandResultFailure("500", "JSB execution error"));
125
- }
126
- } else {
127
- resolve(CommandResultSuccess("ok"));
128
- }
129
- } catch (error) {
130
- console.error(
131
- `PuppeteerPlatform cmd Error: ${cmd}, msg: ${msg} error: ${error}`
132
- );
133
- resolve(CommandResultFailure("500", "Internal error"));
134
- }
135
+ // src/platform-adapter/pico-os/PicoOSPlatform.ts
136
+ var requestId = 0;
137
+ var MAX_ID = 1e5;
138
+ var DEFAULT_JSB_ERROR_CODE = "E_PICO_JSB";
139
+ var DEFAULT_JSB_ERROR_MESSAGE = "Pico JSB execution failed";
140
+ function nextRequestId() {
141
+ requestId = (requestId + 1) % MAX_ID;
142
+ return `rId_${requestId}`;
143
+ }
144
+ var PicoOSPlatform = class {
145
+ async callJSB(cmd, msg) {
146
+ return new Promise((resolve) => {
147
+ try {
148
+ const rId = nextRequestId();
149
+ SpatialWebEvent.addEventReceiver(rId, (result) => {
150
+ SpatialWebEvent.removeEventReceiver(rId);
151
+ resolve(this.toCommandResult(result));
135
152
  });
153
+ const ans = window.webspatialBridge.postMessage(rId, cmd, msg);
154
+ if (ans !== "") {
155
+ SpatialWebEvent.removeEventReceiver(rId);
156
+ resolve(this.parseBridgeResponse(ans));
157
+ }
158
+ } catch (error) {
159
+ console.error(`SwanPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`);
160
+ const { code, message } = this.parseJSBError(error);
161
+ resolve(CommandResultFailure(code, message));
136
162
  }
137
- /**
138
- * Synchronously create Spatialized2DElement to Puppeteer Runner
139
- */
140
- createSpatializedElementSync(spatialId, webspatialUrl) {
141
- try {
142
- console.log(
143
- `[Puppeteer Platform] Creating spatialized element sync with id: ${spatialId}, url: ${webspatialUrl}`
144
- );
145
- const win = window;
146
- if (win.__handleJSBMessage) {
147
- const createCommand = {
148
- id: spatialId,
149
- url: webspatialUrl
150
- };
151
- win.__handleJSBMessage(
152
- `CreateSpatialized2DElement::${JSON.stringify(createCommand)}`
163
+ });
164
+ }
165
+ openSpatialSceneSync(url, config, target, features) {
166
+ const query = buildSpatialSceneQuery(url, config);
167
+ const { spatialId: id = "", windowProxy } = this.openWindow(
168
+ "createSpatialScene",
169
+ query,
170
+ target,
171
+ features
172
+ );
173
+ return CommandResultSuccess({ windowProxy, id });
174
+ }
175
+ createNativeSpatialDiv() {
176
+ return this.waitForRidProtocolAsync("createSpatialized2DElement");
177
+ }
178
+ createNativeAttachment(_options) {
179
+ return this.waitForRidProtocolAsync("createAttachment");
180
+ }
181
+ /**
182
+ * Async path for createNativeSpatialDiv / createNativeAttachment: open webspatial URL
183
+ * with rid= correlation (Pico OS 6).
184
+ */
185
+ waitForRidProtocolAsync(command) {
186
+ return new Promise((resolve) => {
187
+ const createdId = nextRequestId();
188
+ try {
189
+ let windowProxy = null;
190
+ SpatialWebEvent.addEventReceiver(
191
+ createdId,
192
+ (result) => {
193
+ resolve(
194
+ CommandResultSuccess({
195
+ windowProxy,
196
+ id: result.spatialId
197
+ })
153
198
  );
199
+ SpatialWebEvent.removeEventReceiver(createdId);
154
200
  }
155
- } catch (error) {
156
- console.error("Error creating spatialized element sync:", error);
157
- }
158
- }
159
- callWebSpatialProtocol(command, query, target, features) {
160
- console.log(
161
- `PuppeteerPlatform: Calling webspatial protocol: webspatial://${command}${query ? `?${query}` : ""}`
162
201
  );
163
- return new Promise((resolve) => {
202
+ windowProxy = this.openWindow(command, "rid=" + createdId).windowProxy;
203
+ } catch (error) {
204
+ const { code, message } = this.parseJSBError(error);
205
+ SpatialWebEvent.removeEventReceiver(createdId);
206
+ resolve(CommandResultFailure(code, message));
207
+ }
208
+ });
209
+ }
210
+ openWindow(command, query, target, features) {
211
+ const url = query ? `webspatial://${command}?${query}` : `webspatial://${command}`;
212
+ const windowProxy = window.open(url, target, features);
213
+ return { spatialId: "", windowProxy };
214
+ }
215
+ parseBridgeResponse(ans) {
216
+ try {
217
+ const result = JSON.parse(ans);
218
+ return this.toCommandResult(result);
219
+ } catch {
220
+ return CommandResultFailure(
221
+ DEFAULT_JSB_ERROR_CODE,
222
+ "Invalid Pico JSB response payload"
223
+ );
224
+ }
225
+ }
226
+ toCommandResult(result) {
227
+ if (result.success) {
228
+ return CommandResultSuccess(result.data);
229
+ }
230
+ const { code, message } = this.parseJSBError(result.data);
231
+ return CommandResultFailure(code, message);
232
+ }
233
+ parseJSBError(error) {
234
+ return {
235
+ code: error?.code ?? DEFAULT_JSB_ERROR_CODE,
236
+ message: error?.message ?? (typeof error === "string" ? error : DEFAULT_JSB_ERROR_MESSAGE)
237
+ };
238
+ }
239
+ };
240
+
241
+ // src/platform-adapter/puppeteer/PuppeteerPlatform.ts
242
+ var PuppeteerPlatform = class {
243
+ // store iframe instance
244
+ iframeRegistry = /* @__PURE__ */ new Map();
245
+ constructor() {
246
+ }
247
+ callJSB(cmd, msg) {
248
+ return new Promise((resolve) => {
249
+ try {
250
+ if (window.__handleJSBMessage) {
164
251
  try {
165
- const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ""}`;
166
- const { spatialId, iframe, windowProxy } = this.createIframeWindow(
167
- webspatialUrl,
168
- target,
169
- features
170
- );
171
- if (command === "createSpatialized2DElement") {
172
- this.createSpatializedElementSync(spatialId, webspatialUrl);
173
- }
252
+ console.log(` core-sdk Puppeteer Platform: callJSB: ${cmd}::${msg}`);
253
+ const result = window.__handleJSBMessage(`${cmd}::${msg}`);
174
254
  console.log(
175
- `[Puppeteer Platform] iframe created with spatialId: ${spatialId}`
176
- );
177
- this.iframeRegistry.set(spatialId, iframe);
178
- resolve(CommandResultSuccess({ windowProxy, id: spatialId }));
179
- } catch (error) {
180
- console.error("Error calling webspatial protocol:", error);
181
- resolve(
182
- CommandResultFailure("500", "Failed to call webspatial protocol")
255
+ ` core-sdk Puppeteer Platform callJSB result: ${result}`
183
256
  );
257
+ resolve(CommandResultSuccess(result));
258
+ } catch (err) {
259
+ resolve(CommandResultFailure("500", "JSB execution error"));
184
260
  }
185
- });
261
+ } else {
262
+ resolve(CommandResultSuccess("ok"));
263
+ }
264
+ } catch (error) {
265
+ console.error(
266
+ `PuppeteerPlatform cmd Error: ${cmd}, msg: ${msg} error: ${error}`
267
+ );
268
+ resolve(CommandResultFailure("500", "Internal error"));
186
269
  }
187
- callWebSpatialProtocolSync(command, query, target, features) {
188
- try {
189
- const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ""}`;
190
- console.log(`Calling webspatial protocol sync: ${webspatialUrl}`);
191
- const { spatialId, iframe, windowProxy } = this.createIframeWindow(
192
- webspatialUrl,
193
- target,
194
- features
195
- );
196
- if (command === "createSpatialized2DElement") {
197
- this.createSpatializedElementSync(spatialId, webspatialUrl);
198
- }
199
- this.iframeRegistry.set(spatialId, iframe);
200
- return CommandResultSuccess({ windowProxy, id: spatialId });
201
- } catch (error) {
202
- console.error("Error calling webspatial protocol sync:", error);
203
- return CommandResultFailure(
204
- "500",
205
- "Failed to call webspatial protocol sync"
206
- );
270
+ });
271
+ }
272
+ /**
273
+ * Synchronously create Spatialized2DElement to Puppeteer Runner
274
+ */
275
+ createSpatializedElementSync(spatialId, webspatialUrl) {
276
+ try {
277
+ console.log(
278
+ `[Puppeteer Platform] Creating spatialized element sync with id: ${spatialId}, url: ${webspatialUrl}`
279
+ );
280
+ const win = window;
281
+ if (win.__handleJSBMessage) {
282
+ const createCommand = {
283
+ id: spatialId,
284
+ url: webspatialUrl
285
+ };
286
+ win.__handleJSBMessage(
287
+ `CreateSpatialized2DElement::${JSON.stringify(createCommand)}`
288
+ );
289
+ }
290
+ } catch (error) {
291
+ console.error("Error creating spatialized element sync:", error);
292
+ }
293
+ }
294
+ openSpatialSceneSync(url, config, target, features) {
295
+ const query = buildSpatialSceneQuery(url, config);
296
+ return this.runProtocolSync("createSpatialScene", query, target, features);
297
+ }
298
+ createNativeSpatialDiv() {
299
+ return this.runProtocolAsync(
300
+ "createSpatialized2DElement",
301
+ "",
302
+ void 0,
303
+ void 0
304
+ );
305
+ }
306
+ createNativeAttachment(_options) {
307
+ return this.runProtocolAsync("createAttachment", "", void 0, void 0);
308
+ }
309
+ runProtocolAsync(command, query, target, features) {
310
+ console.log(
311
+ `PuppeteerPlatform: Calling webspatial protocol: webspatial://${command}${query ? `?${query}` : ""}`
312
+ );
313
+ return new Promise((resolve) => {
314
+ try {
315
+ const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ""}`;
316
+ const { spatialId, iframe, windowProxy } = this.createIframeWindow(
317
+ webspatialUrl,
318
+ target,
319
+ features
320
+ );
321
+ if (command === "createSpatialized2DElement") {
322
+ this.createSpatializedElementSync(spatialId, webspatialUrl);
207
323
  }
324
+ console.log(
325
+ `[Puppeteer Platform] iframe created with spatialId: ${spatialId}`
326
+ );
327
+ this.iframeRegistry.set(spatialId, iframe);
328
+ resolve(CommandResultSuccess({ windowProxy, id: spatialId }));
329
+ } catch (error) {
330
+ console.error("Error calling webspatial protocol:", error);
331
+ resolve(
332
+ CommandResultFailure("500", "Failed to call webspatial protocol")
333
+ );
208
334
  }
209
- /**
210
- * Synchronously create iframe-based window
211
- */
212
- createIframeWindow(url, target, features) {
213
- const iframe = document.createElement("iframe");
214
- iframe.style.border = "none";
215
- iframe.style.display = "none";
216
- iframe.style.width = "100%";
217
- iframe.style.height = "100%";
218
- const spatialId = this.generateUUID();
219
- iframe.spatialId = spatialId;
220
- iframe.id = `spatial-iframe-${spatialId}`;
221
- const featuresObj = this.parseFeatures(features || "");
222
- if (featuresObj.width) {
223
- iframe.style.width = featuresObj.width;
335
+ });
336
+ }
337
+ runProtocolSync(command, query, target, features) {
338
+ try {
339
+ const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ""}`;
340
+ console.log(`Calling webspatial protocol sync: ${webspatialUrl}`);
341
+ const { spatialId, iframe, windowProxy } = this.createIframeWindow(
342
+ webspatialUrl,
343
+ target,
344
+ features
345
+ );
346
+ if (command === "createSpatialized2DElement") {
347
+ this.createSpatializedElementSync(spatialId, webspatialUrl);
348
+ }
349
+ this.iframeRegistry.set(spatialId, iframe);
350
+ return CommandResultSuccess({ windowProxy, id: spatialId });
351
+ } catch (error) {
352
+ console.error("Error calling webspatial protocol sync:", error);
353
+ return CommandResultFailure(
354
+ "500",
355
+ "Failed to call webspatial protocol sync"
356
+ );
357
+ }
358
+ }
359
+ /**
360
+ * Synchronously create iframe-based window
361
+ */
362
+ createIframeWindow(url, target, features) {
363
+ const iframe = document.createElement("iframe");
364
+ iframe.style.border = "none";
365
+ iframe.style.display = "none";
366
+ iframe.style.width = "100%";
367
+ iframe.style.height = "100%";
368
+ const spatialId = this.generateUUID();
369
+ iframe.spatialId = spatialId;
370
+ iframe.id = `spatial-iframe-${spatialId}`;
371
+ const featuresObj = this.parseFeatures(features || "");
372
+ if (featuresObj.width) {
373
+ iframe.style.width = featuresObj.width;
374
+ }
375
+ if (featuresObj.height) {
376
+ iframe.style.height = featuresObj.height;
377
+ }
378
+ if (featuresObj.left) {
379
+ iframe.style.left = featuresObj.left;
380
+ iframe.style.position = "absolute";
381
+ }
382
+ if (featuresObj.top) {
383
+ iframe.style.top = featuresObj.top;
384
+ iframe.style.position = "absolute";
385
+ }
386
+ document.body.appendChild(iframe);
387
+ const windowProxy = this.createEnhancedWindowProxy(iframe, url, spatialId);
388
+ iframe.src = "about:blank";
389
+ console.log(
390
+ `PuppeteerPlatform created iframe window with spatialId: ${spatialId}, URL: ${url}`
391
+ );
392
+ this.initializeIframeContent(iframe, url, spatialId);
393
+ return { spatialId, iframe, windowProxy };
394
+ }
395
+ /**
396
+ * create enhanced windowProxy object
397
+ */
398
+ createEnhancedWindowProxy(iframe, url, spatialId) {
399
+ return {
400
+ // basic properties
401
+ location: {
402
+ href: url,
403
+ toString: () => url,
404
+ reload: () => {
405
+ if (iframe.contentWindow) {
406
+ iframe.contentWindow.location.reload();
407
+ }
224
408
  }
225
- if (featuresObj.height) {
226
- iframe.style.height = featuresObj.height;
409
+ },
410
+ navigator: {
411
+ userAgent: `Mozilla/5.0 (WebKit) SpatialId/${spatialId}`
412
+ },
413
+ // methods
414
+ close: () => {
415
+ console.log(`Closing iframe with spatialId: ${spatialId}`);
416
+ iframe.remove();
417
+ this.iframeRegistry.delete(spatialId);
418
+ },
419
+ // document access
420
+ document: iframe.contentDocument || {},
421
+ contentWindow: iframe.contentWindow || {},
422
+ // add message communication method
423
+ postMessage: (message, targetOrigin) => {
424
+ if (iframe.contentWindow) {
425
+ iframe.contentWindow.postMessage(message, targetOrigin || "*");
227
426
  }
228
- if (featuresObj.left) {
229
- iframe.style.left = featuresObj.left;
230
- iframe.style.position = "absolute";
427
+ },
428
+ // add event listener method
429
+ addEventListener: (type, listener) => {
430
+ if (iframe.contentWindow) {
431
+ iframe.contentWindow.addEventListener(type, listener);
231
432
  }
232
- if (featuresObj.top) {
233
- iframe.style.top = featuresObj.top;
234
- iframe.style.position = "absolute";
433
+ },
434
+ removeEventListener: (type, listener) => {
435
+ if (iframe.contentWindow) {
436
+ iframe.contentWindow.removeEventListener(type, listener);
235
437
  }
236
- document.body.appendChild(iframe);
237
- const windowProxy = this.createEnhancedWindowProxy(iframe, url, spatialId);
238
- iframe.src = "about:blank";
239
- console.log(
240
- `PuppeteerPlatform created iframe window with spatialId: ${spatialId}, URL: ${url}`
241
- );
242
- this.initializeIframeContent(iframe, url, spatialId);
243
- return { spatialId, iframe, windowProxy };
244
- }
245
- /**
246
- * create enhanced windowProxy object
247
- */
248
- createEnhancedWindowProxy(iframe, url, spatialId) {
249
- return {
250
- // basic properties
251
- location: {
252
- href: url,
253
- toString: () => url,
254
- reload: () => {
255
- if (iframe.contentWindow) {
256
- iframe.contentWindow.location.reload();
257
- }
258
- }
259
- },
260
- navigator: {
261
- userAgent: `Mozilla/5.0 (WebKit) SpatialId/${spatialId}`
262
- },
263
- // methods
264
- close: () => {
265
- console.log(`Closing iframe with spatialId: ${spatialId}`);
266
- iframe.remove();
267
- this.iframeRegistry.delete(spatialId);
268
- },
269
- // document access
270
- document: iframe.contentDocument || {},
271
- contentWindow: iframe.contentWindow || {},
272
- // add message communication method
273
- postMessage: (message, targetOrigin) => {
274
- if (iframe.contentWindow) {
275
- iframe.contentWindow.postMessage(message, targetOrigin || "*");
276
- }
277
- },
278
- // add event listener method
279
- addEventListener: (type, listener) => {
280
- if (iframe.contentWindow) {
281
- iframe.contentWindow.addEventListener(type, listener);
282
- }
283
- },
284
- removeEventListener: (type, listener) => {
285
- if (iframe.contentWindow) {
286
- iframe.contentWindow.removeEventListener(type, listener);
287
- }
288
- },
289
- // execute JavaScript
290
- executeScript: (code) => {
291
- if (iframe.contentWindow) {
292
- try {
293
- const win = iframe.contentWindow;
294
- return win.eval(code);
295
- } catch (error) {
296
- console.error(
297
- `Error executing script in iframe ${spatialId}:`,
298
- error
299
- );
300
- return null;
301
- }
302
- }
438
+ },
439
+ // execute JavaScript
440
+ executeScript: (code) => {
441
+ if (iframe.contentWindow) {
442
+ try {
443
+ const win = iframe.contentWindow;
444
+ return win.eval(code);
445
+ } catch (error) {
446
+ console.error(
447
+ `Error executing script in iframe ${spatialId}:`,
448
+ error
449
+ );
303
450
  return null;
304
- },
305
- // get iframe reference
306
- getIframe: () => iframe,
307
- // get spatialId
308
- getSpatialId: () => spatialId
309
- };
310
- }
311
- /**
312
- * initialize iframe content
313
- */
314
- initializeIframeContent(iframe, url, spatialId) {
451
+ }
452
+ }
453
+ return null;
454
+ },
455
+ // get iframe reference
456
+ getIframe: () => iframe,
457
+ // get spatialId
458
+ getSpatialId: () => spatialId
459
+ };
460
+ }
461
+ /**
462
+ * initialize iframe content
463
+ */
464
+ initializeIframeContent(iframe, url, spatialId) {
465
+ try {
466
+ iframe.onload = () => {
315
467
  try {
316
- iframe.onload = () => {
317
- try {
318
- const iframeContent = `
468
+ const iframeContent = `
319
469
  // inject communication script
320
470
  window.webSpatialId = '${spatialId}';
321
471
  window.SpatialId = '${spatialId}';
@@ -363,10 +513,10 @@ var init_PuppeteerPlatform = __esm({
363
513
  }
364
514
  });
365
515
  `;
366
- const doc = iframe.contentDocument;
367
- if (doc) {
368
- doc.open();
369
- doc.write(`
516
+ const doc = iframe.contentDocument;
517
+ if (doc) {
518
+ doc.open();
519
+ doc.write(`
370
520
  <!DOCTYPE html>
371
521
  <html>
372
522
  <head>
@@ -385,402 +535,206 @@ var init_PuppeteerPlatform = __esm({
385
535
  </body>
386
536
  </html>
387
537
  `);
388
- doc.close();
389
- }
390
- } catch (error) {
391
- console.error("Error initializing iframe content:", error);
392
- }
393
- };
394
- } catch (error) {
395
- console.error("Error setting up iframe:", error);
396
- }
397
- }
398
- /**
399
- * parse features string to object
400
- */
401
- parseFeatures(features) {
402
- const result = {};
403
- const pairs = features.split(",");
404
- pairs.forEach((pair) => {
405
- const [key, value] = pair.split("=").map((s) => s.trim());
406
- if (key && value) {
407
- result[key] = value;
538
+ doc.close();
408
539
  }
409
- });
410
- return result;
411
- }
412
- /**
413
- * send message to iframe with specified spatialId
414
- */
415
- sendMessageToIframe(spatialId, message) {
416
- const iframe = this.iframeRegistry.get(spatialId);
417
- if (iframe && iframe.contentWindow) {
418
- iframe.contentWindow.postMessage(message, window.location.origin);
419
- return true;
540
+ } catch (error) {
541
+ console.error("Error initializing iframe content:", error);
420
542
  }
421
- return false;
422
- }
423
- /**
424
- * get all active iframes
425
- */
426
- getAllActiveIframes() {
427
- const result = [];
428
- this.iframeRegistry.forEach((iframe, spatialId) => {
429
- result.push({ spatialId, iframe });
430
- });
431
- return result;
432
- }
433
- /**
434
- * dispose all active iframes
435
- */
436
- dispose() {
437
- this.iframeRegistry.forEach((iframe, spatialId) => {
438
- console.log(`Disposing iframe with spatialId: ${spatialId}`);
439
- iframe.remove();
440
- });
441
- this.iframeRegistry.clear();
442
- }
443
- // generate UUID function
444
- generateUUID() {
445
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
446
- /[xy]/g,
447
- function(c) {
448
- const r = Math.random() * 16 | 0;
449
- const v = c === "x" ? r : r & 3 | 8;
450
- return v.toString(16).toUpperCase();
451
- }
452
- );
453
- }
454
- };
543
+ };
544
+ } catch (error) {
545
+ console.error("Error setting up iframe:", error);
546
+ }
455
547
  }
456
- });
457
-
458
- // src/SpatialWebEvent.ts
459
- var SpatialWebEvent;
460
- var init_SpatialWebEvent = __esm({
461
- "src/SpatialWebEvent.ts"() {
462
- "use strict";
463
- SpatialWebEvent = class _SpatialWebEvent {
464
- static eventReceiver = {};
465
- static init() {
466
- window.__SpatialWebEvent = ({ id, data }) => {
467
- _SpatialWebEvent.eventReceiver[id]?.(data);
468
- };
469
- }
470
- static addEventReceiver(id, callback) {
471
- _SpatialWebEvent.eventReceiver[id] = callback;
472
- }
473
- static removeEventReceiver(id) {
474
- delete _SpatialWebEvent.eventReceiver[id];
548
+ /**
549
+ * parse features string to object
550
+ */
551
+ parseFeatures(features) {
552
+ const result = {};
553
+ const pairs = features.split(",");
554
+ pairs.forEach((pair) => {
555
+ const [key, value] = pair.split("=").map((s) => s.trim());
556
+ if (key && value) {
557
+ result[key] = value;
475
558
  }
476
- };
559
+ });
560
+ return result;
477
561
  }
478
- });
479
-
480
- // src/platform-adapter/pico-os/PicoOSPlatform.ts
481
- var PicoOSPlatform_exports = {};
482
- __export(PicoOSPlatform_exports, {
483
- PicoOSPlatform: () => PicoOSPlatform
484
- });
485
- function nextRequestId() {
486
- requestId = (requestId + 1) % MAX_ID;
487
- return `rId_${requestId}`;
488
- }
489
- var requestId, MAX_ID, PicoOSPlatform;
490
- var init_PicoOSPlatform = __esm({
491
- "src/platform-adapter/pico-os/PicoOSPlatform.ts"() {
492
- "use strict";
493
- init_CommandResultUtils();
494
- init_SpatialWebEvent();
495
- requestId = 0;
496
- MAX_ID = 1e5;
497
- PicoOSPlatform = class {
498
- async callJSB(cmd, msg) {
499
- return new Promise((resolve, reject) => {
500
- try {
501
- const rId = nextRequestId();
502
- SpatialWebEvent.addEventReceiver(rId, (result) => {
503
- SpatialWebEvent.removeEventReceiver(rId);
504
- if (result.success) {
505
- resolve(CommandResultSuccess(result.data));
506
- } else {
507
- const { code, message } = result.data;
508
- resolve(CommandResultFailure(code, message));
509
- }
510
- });
511
- const ans = window.webspatialBridge.postMessage(rId, cmd, msg);
512
- if (ans !== "") {
513
- SpatialWebEvent.removeEventReceiver(rId);
514
- const result = JSON.parse(ans);
515
- if (result.success) {
516
- resolve(CommandResultSuccess(result.data));
517
- } else {
518
- const { code, message } = result.data;
519
- resolve(CommandResultFailure(code, message));
520
- }
521
- }
522
- } catch (error) {
523
- console.error(`SwanPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`);
524
- const { code, message } = error;
525
- resolve(CommandResultFailure(code, message));
526
- }
527
- });
528
- }
529
- async callWebSpatialProtocol(command, query, target, features) {
530
- return new Promise((resolve, reject) => {
531
- const createdId = nextRequestId();
532
- try {
533
- let windowProxy = null;
534
- SpatialWebEvent.addEventReceiver(
535
- createdId,
536
- (result) => {
537
- resolve(
538
- CommandResultSuccess({
539
- windowProxy,
540
- id: result.spatialId
541
- })
542
- );
543
- SpatialWebEvent.removeEventReceiver(createdId);
544
- }
545
- );
546
- windowProxy = this.openWindow(
547
- command,
548
- "rid=" + createdId,
549
- target,
550
- features
551
- ).windowProxy;
552
- } catch (error) {
553
- const { code, message } = error;
554
- SpatialWebEvent.removeEventReceiver(createdId);
555
- resolve(CommandResultFailure(code, message));
556
- }
557
- });
558
- }
559
- callWebSpatialProtocolSync(command, query, target, features) {
560
- const { spatialId: id = "", windowProxy } = this.openWindow(
561
- command,
562
- query,
563
- target,
564
- features
565
- );
566
- return CommandResultSuccess({ windowProxy, id });
567
- }
568
- openWindow(command, query, target, features) {
569
- const windowProxy = window.open(
570
- `webspatial://${command}?${query || ""}`,
571
- target,
572
- features
573
- );
574
- return { spatialId: "", windowProxy };
562
+ /**
563
+ * send message to iframe with specified spatialId
564
+ */
565
+ sendMessageToIframe(spatialId, message) {
566
+ const iframe = this.iframeRegistry.get(spatialId);
567
+ if (iframe && iframe.contentWindow) {
568
+ iframe.contentWindow.postMessage(message, window.location.origin);
569
+ return true;
570
+ }
571
+ return false;
572
+ }
573
+ /**
574
+ * get all active iframes
575
+ */
576
+ getAllActiveIframes() {
577
+ const result = [];
578
+ this.iframeRegistry.forEach((iframe, spatialId) => {
579
+ result.push({ spatialId, iframe });
580
+ });
581
+ return result;
582
+ }
583
+ /**
584
+ * dispose all active iframes
585
+ */
586
+ dispose() {
587
+ this.iframeRegistry.forEach((iframe, spatialId) => {
588
+ console.log(`Disposing iframe with spatialId: ${spatialId}`);
589
+ iframe.remove();
590
+ });
591
+ this.iframeRegistry.clear();
592
+ }
593
+ // generate UUID function
594
+ generateUUID() {
595
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
596
+ /[xy]/g,
597
+ function(c) {
598
+ const r = Math.random() * 16 | 0;
599
+ const v = c === "x" ? r : r & 3 | 8;
600
+ return v.toString(16).toUpperCase();
575
601
  }
576
- };
602
+ );
577
603
  }
578
- });
604
+ };
579
605
 
580
- // src/platform-adapter/android/AndroidPlatform.ts
581
- var AndroidPlatform_exports = {};
582
- __export(AndroidPlatform_exports, {
583
- AndroidPlatform: () => AndroidPlatform
584
- });
585
- function nextRequestId2() {
586
- requestId2 = (requestId2 + 1) % MAX_ID2;
587
- return `rId_${requestId2}`;
588
- }
589
- var creatingElementCount, requestId2, MAX_ID2, AndroidPlatform;
590
- var init_AndroidPlatform = __esm({
591
- "src/platform-adapter/android/AndroidPlatform.ts"() {
592
- "use strict";
593
- init_CommandResultUtils();
594
- init_JSBCommand();
595
- init_SpatialWebEvent();
596
- creatingElementCount = 0;
597
- requestId2 = 0;
598
- MAX_ID2 = 1e5;
599
- AndroidPlatform = class {
600
- async callJSB(cmd, msg) {
601
- return new Promise((resolve, reject) => {
602
- try {
603
- const rId = nextRequestId2();
604
- SpatialWebEvent.addEventReceiver(rId, (result) => {
605
- SpatialWebEvent.removeEventReceiver(rId);
606
- if (result.success) {
607
- resolve(CommandResultSuccess(result.data));
608
- } else {
609
- const { code, message } = result.data;
610
- resolve(CommandResultFailure(code, message));
611
- }
612
- });
613
- const ans = window.webspatialBridge.postMessage(rId, cmd, msg);
614
- if (ans !== "") {
615
- SpatialWebEvent.removeEventReceiver(rId);
616
- const result = JSON.parse(ans);
617
- if (result.success) {
618
- resolve(CommandResultSuccess(result.data));
619
- } else {
620
- const { code, message } = result.data;
621
- resolve(CommandResultFailure(code, message));
622
- }
623
- }
624
- } catch (error) {
625
- console.error(
626
- `AndroidPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`
627
- );
628
- const { code, message } = error;
629
- resolve(CommandResultFailure(code, message));
630
- }
631
- });
632
- }
633
- async callWebSpatialProtocol(command, query, target, features) {
634
- await new Promise((resolve) => setTimeout(resolve, 16 * creatingElementCount));
635
- creatingElementCount++;
636
- let canCreate = await new CheckWebViewCanCreateCommand().execute();
637
- while (!canCreate.data.can) {
638
- await new Promise((resolve) => setTimeout(resolve, 16));
639
- canCreate = await new CheckWebViewCanCreateCommand().execute();
640
- }
641
- const { windowProxy } = this.openWindow(command, query, target, features);
642
- while (!windowProxy?.open) {
643
- await new Promise((resolve) => setTimeout(resolve, 16));
644
- }
645
- windowProxy?.open("about:blank", "_self");
646
- while (!windowProxy?.__SpatialId) {
647
- await new Promise((resolve) => setTimeout(resolve, 16));
648
- }
649
- let spatialId = windowProxy?.__SpatialId;
650
- creatingElementCount--;
651
- return Promise.resolve(
652
- CommandResultSuccess({ windowProxy, id: spatialId })
653
- );
654
- }
655
- callWebSpatialProtocolSync(command, query, target, features) {
656
- const { spatialId: id = "", windowProxy } = this.openWindow(
657
- command,
658
- query,
659
- target,
660
- features
661
- );
662
- return CommandResultSuccess({ windowProxy, id });
663
- }
664
- openWindow(command, query, target, features) {
665
- const windowProxy = window.open(
666
- `webspatial://${command}?${query || ""}`,
667
- target,
668
- features
669
- );
670
- return { spatialId: "", windowProxy };
671
- }
606
+ // src/platform-adapter/ssr/SSRPlatform.ts
607
+ var SSRPlatform = class {
608
+ callJSB(cmd, msg) {
609
+ return Promise.resolve({
610
+ success: true,
611
+ data: void 0,
612
+ errorCode: void 0,
613
+ errorMessage: void 0
614
+ });
615
+ }
616
+ openSpatialSceneSync(_url, _config, _target, _features) {
617
+ return {
618
+ success: true,
619
+ data: void 0,
620
+ errorCode: void 0,
621
+ errorMessage: void 0
672
622
  };
673
623
  }
674
- });
624
+ createNativeSpatialDiv() {
625
+ return Promise.resolve({
626
+ success: true,
627
+ data: void 0,
628
+ errorCode: void 0,
629
+ errorMessage: void 0
630
+ });
631
+ }
632
+ createNativeAttachment(_options) {
633
+ return Promise.resolve({
634
+ success: true,
635
+ data: void 0,
636
+ errorCode: void 0,
637
+ errorMessage: void 0
638
+ });
639
+ }
640
+ };
675
641
 
676
642
  // src/platform-adapter/vision-os/VisionOSPlatform.ts
677
- var VisionOSPlatform_exports = {};
678
- __export(VisionOSPlatform_exports, {
679
- VisionOSPlatform: () => VisionOSPlatform
680
- });
681
- var VisionOSPlatform;
682
- var init_VisionOSPlatform = __esm({
683
- "src/platform-adapter/vision-os/VisionOSPlatform.ts"() {
684
- "use strict";
685
- init_CommandResultUtils();
686
- VisionOSPlatform = class {
687
- async callJSB(cmd, msg) {
688
- try {
689
- const result = await window.webkit.messageHandlers.bridge.postMessage(
690
- `${cmd}::${msg}`
691
- );
692
- return CommandResultSuccess(result);
693
- } catch (error) {
694
- const { code, message } = JSON.parse(error.message);
695
- return CommandResultFailure(code, message);
696
- }
697
- }
698
- callWebSpatialProtocol(command, query, target, features) {
699
- const { spatialId: id, windowProxy } = this.openWindow(
700
- command,
701
- query,
702
- target,
703
- features
704
- );
705
- return Promise.resolve(
706
- CommandResultSuccess({ windowProxy, id })
707
- );
708
- }
709
- callWebSpatialProtocolSync(command, query, target, features) {
710
- const { spatialId: id = "", windowProxy } = this.openWindow(
711
- command,
712
- query,
713
- target,
714
- features
715
- );
716
- return CommandResultSuccess({ windowProxy, id });
717
- }
718
- openWindow(command, query, target, features) {
719
- const windowProxy = window.open(
720
- `webspatial://${command}?${query || ""}`,
721
- target,
722
- features
723
- );
724
- const ua = windowProxy?.navigator.userAgent;
725
- const spatialId = ua?.match(
726
- /\b([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})\b/gi
727
- )?.[0];
728
- return { spatialId, windowProxy };
729
- }
730
- };
643
+ var UUID_RE = /\b([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})\b/gi;
644
+ var VisionOSPlatform = class {
645
+ async callJSB(cmd, msg) {
646
+ try {
647
+ const result = await window.webkit.messageHandlers.bridge.postMessage(
648
+ `${cmd}::${msg}`
649
+ );
650
+ return CommandResultSuccess(result);
651
+ } catch (error) {
652
+ const { code, message } = this.parseJSBError(error);
653
+ return CommandResultFailure(code, message);
654
+ }
731
655
  }
732
- });
733
-
734
- // src/platform-adapter/index.ts
735
- function getWebSpatialVersion(ua) {
736
- const match = ua.match(/WebSpatial\/(\d+)\.(\d+)\.(\d+)/);
737
- if (!match) {
738
- return null;
656
+ openSpatialSceneSync(url, config, target, features) {
657
+ const query = buildSpatialSceneQuery(url, config);
658
+ const { spatialId: id = "", windowProxy } = this.openWindow(
659
+ "createSpatialScene",
660
+ query,
661
+ target,
662
+ features
663
+ );
664
+ return CommandResultSuccess({ windowProxy, id });
739
665
  }
740
- return [Number(match[1]), Number(match[2]), Number(match[3])];
741
- }
742
- function isVersionGreater(a, b) {
743
- if (!a) {
744
- return false;
666
+ createNativeSpatialDiv() {
667
+ return this.openProtocolAsync("createSpatialized2DElement");
745
668
  }
746
- for (let index = 0; index < 3; index += 1) {
747
- const diff = a[index] - b[index];
748
- if (diff > 0) {
749
- return true;
750
- }
751
- if (diff < 0) {
752
- return false;
669
+ createNativeAttachment(_options) {
670
+ return this.openProtocolAsync("createAttachment");
671
+ }
672
+ async openProtocolAsync(command) {
673
+ const { spatialId: id = "", windowProxy } = this.openWindow(
674
+ command,
675
+ "",
676
+ void 0,
677
+ void 0
678
+ );
679
+ return CommandResultSuccess({ windowProxy, id });
680
+ }
681
+ openWindow(command, query, target, features) {
682
+ const windowProxy = window.open(
683
+ `webspatial://${command}?${query || ""}`,
684
+ target,
685
+ features
686
+ );
687
+ const ua = windowProxy?.navigator.userAgent;
688
+ const spatialId = ua?.match(UUID_RE)?.[0];
689
+ return { spatialId, windowProxy };
690
+ }
691
+ parseJSBError(error) {
692
+ try {
693
+ const parsed = JSON.parse(error.message ?? "");
694
+ return {
695
+ code: parsed.code ?? "E_VISIONOS_JSB",
696
+ message: parsed.message ?? "VisionOS JSB execution failed"
697
+ };
698
+ } catch {
699
+ return {
700
+ code: "E_VISIONOS_JSB",
701
+ message: error?.message ?? "VisionOS JSB execution failed"
702
+ };
753
703
  }
754
704
  }
755
- return false;
705
+ };
706
+
707
+ // src/platform-adapter/createPlatformSync.ts
708
+ function assertNever(_) {
709
+ throw new Error("Unhandled jsb adapter platform kind");
756
710
  }
757
- function createPlatform() {
711
+ function createPlatformSync() {
758
712
  if (isSSREnv()) {
759
713
  return new SSRPlatform();
760
714
  }
761
715
  const userAgent = window.navigator.userAgent;
762
- const webSpatialVersion = getWebSpatialVersion(userAgent);
763
- if (window.navigator.userAgent.includes("Puppeteer")) {
764
- const PuppeteerPlatform2 = (init_PuppeteerPlatform(), __toCommonJS(PuppeteerPlatform_exports)).PuppeteerPlatform;
765
- return new PuppeteerPlatform2();
766
- } else if (userAgent.includes("PicoWebApp") && isVersionGreater(webSpatialVersion, [0, 0, 1])) {
767
- const PicoOSPlatform2 = (init_PicoOSPlatform(), __toCommonJS(PicoOSPlatform_exports)).PicoOSPlatform;
768
- return new PicoOSPlatform2();
769
- } else if (userAgent.includes("Android") || userAgent.includes("Linux")) {
770
- const AndroidPlatform2 = (init_AndroidPlatform(), __toCommonJS(AndroidPlatform_exports)).AndroidPlatform;
771
- return new AndroidPlatform2();
772
- } else {
773
- const VisionOSPlatform2 = (init_VisionOSPlatform(), __toCommonJS(VisionOSPlatform_exports)).VisionOSPlatform;
774
- return new VisionOSPlatform2();
716
+ const kind = resolveJsbAdapterPlatform(userAgent);
717
+ switch (kind) {
718
+ case "puppeteer":
719
+ return new PuppeteerPlatform();
720
+ case "picoos":
721
+ return new PicoOSPlatform();
722
+ case "visionos":
723
+ return new VisionOSPlatform();
724
+ default:
725
+ return assertNever(kind);
775
726
  }
776
727
  }
777
- var init_platform_adapter = __esm({
778
- "src/platform-adapter/index.ts"() {
779
- "use strict";
780
- init_ssr_polyfill();
781
- init_SSRPlatform();
782
- }
783
- });
728
+
729
+ // src/platform-runtime.ts
730
+ var platformResolved;
731
+ function getPlatformSync() {
732
+ platformResolved ??= createPlatformSync();
733
+ return platformResolved;
734
+ }
735
+ async function getPlatform() {
736
+ return getPlatformSync();
737
+ }
784
738
 
785
739
  // src/utils.ts
786
740
  function parseBorderRadius(borderProperty, width) {
@@ -834,532 +788,468 @@ function deepCloneJSON(value) {
834
788
  }
835
789
  return JSON.parse(JSON.stringify(value));
836
790
  }
837
- var init_utils = __esm({
838
- "src/utils.ts"() {
839
- "use strict";
840
- }
841
- });
842
791
 
843
792
  // src/JSBCommand.ts
844
- var platform, JSBCommand, UpdateEntityPropertiesCommand, UpdateEntityEventCommand, UpdateSpatialSceneProperties, UpdateSceneConfig, FocusScene, GetSpatialSceneState, SpatializedElementCommand, UpdateSpatialized2DElementProperties, UpdateSpatializedDynamic3DElementProperties, UpdateUnlitMaterialProperties, UpdateSpatializedElementTransform, UpdateSpatializedStatic3DElementProperties, AddSpatializedElementToSpatialized2DElement, AddSpatializedElementToSpatialScene, CreateSpatializedStatic3DElementCommand, CreateSpatializedDynamic3DElementCommand, CreateSpatialEntityCommand, CreateModelComponentCommand, CreateSpatialModelEntityCommand, CreateModelAssetCommand, CreateSpatialGeometryCommand, CreateSpatialUnlitMaterialCommand, AddComponentToEntityCommand, RemoveComponentFromEntityCommand, SetMaterialsOnEntityCommand, SetParentForEntityCommand, ConvertFromEntityToEntityCommand, ConvertFromEntityToSceneCommand, ConvertFromSceneToEntityCommand, ConvertCoordinateCommand, InspectCommand, DestroyCommand, CheckWebViewCanCreateCommand, WebSpatialProtocolCommand, createSpatialized2DElementCommand, createSpatialSceneCommand, CreateAttachmentEntityCommand, InitializeAttachmentCommand, UpdateAttachmentEntityCommand;
845
- var init_JSBCommand = __esm({
846
- "src/JSBCommand.ts"() {
847
- "use strict";
848
- init_platform_adapter();
849
- init_utils();
850
- platform = createPlatform();
851
- JSBCommand = class {
852
- commandType = "";
853
- async execute() {
854
- const param = this.getParams();
855
- const msg = param ? JSON.stringify(param) : "";
856
- return platform.callJSB(this.commandType, msg);
857
- }
858
- };
859
- UpdateEntityPropertiesCommand = class extends JSBCommand {
860
- constructor(entity, properties) {
861
- super();
862
- this.entity = entity;
863
- this.properties = properties;
864
- }
865
- commandType = "UpdateEntityProperties";
866
- getParams() {
867
- const transform = composeSRT(
868
- this.properties.position ?? this.entity.position,
869
- this.properties.rotation ?? this.entity.rotation,
870
- this.properties.scale ?? this.entity.scale
871
- ).toFloat64Array();
872
- return {
873
- entityId: this.entity.id,
874
- transform
875
- };
876
- }
877
- };
878
- UpdateEntityEventCommand = class extends JSBCommand {
879
- constructor(entity, type, isEnable) {
880
- super();
881
- this.entity = entity;
882
- this.type = type;
883
- this.isEnable = isEnable;
884
- }
885
- commandType = "UpdateEntityEvent";
886
- getParams() {
887
- return {
888
- type: this.type,
889
- entityId: this.entity.id,
890
- isEnable: this.isEnable
891
- };
892
- }
893
- };
894
- UpdateSpatialSceneProperties = class extends JSBCommand {
895
- properties;
896
- commandType = "UpdateSpatialSceneProperties";
897
- constructor(properties) {
898
- super();
899
- this.properties = properties;
900
- }
901
- getParams() {
902
- return this.properties;
903
- }
904
- };
905
- UpdateSceneConfig = class extends JSBCommand {
906
- config;
907
- commandType = "UpdateSceneConfig";
908
- constructor(config) {
909
- super();
910
- this.config = config;
911
- }
912
- getParams() {
913
- return { config: this.config };
914
- }
915
- };
916
- FocusScene = class extends JSBCommand {
917
- constructor(id) {
918
- super();
919
- this.id = id;
920
- }
921
- commandType = "FocusScene";
922
- getParams() {
923
- return { id: this.id };
924
- }
925
- };
926
- GetSpatialSceneState = class extends JSBCommand {
927
- commandType = "GetSpatialSceneState";
928
- constructor() {
929
- super();
930
- }
931
- getParams() {
932
- return {};
933
- }
934
- };
935
- SpatializedElementCommand = class extends JSBCommand {
936
- constructor(spatialObject) {
937
- super();
938
- this.spatialObject = spatialObject;
939
- }
940
- getParams() {
941
- const extraParams = this.getExtraParams();
942
- return { id: this.spatialObject.id, ...extraParams };
943
- }
944
- };
945
- UpdateSpatialized2DElementProperties = class extends SpatializedElementCommand {
946
- properties;
947
- commandType = "UpdateSpatialized2DElementProperties";
948
- constructor(spatialObject, properties) {
949
- super(spatialObject);
950
- this.properties = properties;
951
- }
952
- getExtraParams() {
953
- return this.properties;
954
- }
955
- };
956
- UpdateSpatializedDynamic3DElementProperties = class extends SpatializedElementCommand {
957
- properties;
958
- commandType = "UpdateSpatializedDynamic3DElementProperties";
959
- constructor(spatialObject, properties) {
960
- super(spatialObject);
961
- this.properties = properties;
962
- }
963
- getExtraParams() {
964
- return {
965
- id: this.spatialObject.id,
966
- ...this.properties
967
- };
968
- }
969
- };
970
- UpdateUnlitMaterialProperties = class extends SpatializedElementCommand {
971
- properties;
972
- commandType = "UpdateUnlitMaterialProperties";
973
- constructor(spatialObject, properties) {
974
- super(spatialObject);
975
- this.properties = properties;
976
- }
977
- getExtraParams() {
978
- return this.properties;
979
- }
980
- };
981
- UpdateSpatializedElementTransform = class extends SpatializedElementCommand {
982
- matrix;
983
- commandType = "UpdateSpatializedElementTransform";
984
- constructor(spatialObject, matrix) {
985
- super(spatialObject);
986
- this.matrix = matrix;
987
- }
988
- getExtraParams() {
989
- return { matrix: Array.from(this.matrix.toFloat64Array()) };
990
- }
991
- };
992
- UpdateSpatializedStatic3DElementProperties = class extends SpatializedElementCommand {
993
- properties;
994
- commandType = "UpdateSpatializedStatic3DElementProperties";
995
- constructor(spatialObject, properties) {
996
- super(spatialObject);
997
- this.properties = properties;
998
- }
999
- getExtraParams() {
1000
- return this.properties;
1001
- }
1002
- };
1003
- AddSpatializedElementToSpatialized2DElement = class extends SpatializedElementCommand {
1004
- commandType = "AddSpatializedElementToSpatialized2DElement";
1005
- spatializedElement;
1006
- constructor(spatialObject, spatializedElement) {
1007
- super(spatialObject);
1008
- this.spatializedElement = spatializedElement;
1009
- }
1010
- getExtraParams() {
1011
- return { spatializedElementId: this.spatializedElement.id };
1012
- }
1013
- };
1014
- AddSpatializedElementToSpatialScene = class extends JSBCommand {
1015
- commandType = "AddSpatializedElementToSpatialScene";
1016
- spatializedElement;
1017
- constructor(spatializedElement) {
1018
- super();
1019
- this.spatializedElement = spatializedElement;
1020
- }
1021
- getParams() {
1022
- return {
1023
- spatializedElementId: this.spatializedElement.id
1024
- };
1025
- }
1026
- };
1027
- CreateSpatializedStatic3DElementCommand = class extends JSBCommand {
1028
- constructor(modelURL, sources) {
1029
- super();
1030
- this.modelURL = modelURL;
1031
- this.sources = sources;
1032
- this.modelURL = modelURL;
1033
- this.sources = sources;
1034
- }
1035
- commandType = "CreateSpatializedStatic3DElement";
1036
- getParams() {
1037
- return { modelURL: this.modelURL, sources: this.sources };
1038
- }
1039
- };
1040
- CreateSpatializedDynamic3DElementCommand = class extends JSBCommand {
1041
- getParams() {
1042
- return { test: true };
1043
- }
1044
- commandType = "CreateSpatializedDynamic3DElement";
1045
- };
1046
- CreateSpatialEntityCommand = class extends JSBCommand {
1047
- constructor(name) {
1048
- super();
1049
- this.name = name;
1050
- }
1051
- getParams() {
1052
- return { name: this.name };
1053
- }
1054
- commandType = "CreateSpatialEntity";
1055
- };
1056
- CreateModelComponentCommand = class extends JSBCommand {
1057
- constructor(options) {
1058
- super();
1059
- this.options = options;
1060
- }
1061
- getParams() {
1062
- let geometryId = this.options.mesh.id;
1063
- let materialIds = this.options.materials.map((material) => material.id);
1064
- return { geometryId, materialIds };
1065
- }
1066
- commandType = "CreateModelComponent";
1067
- };
1068
- CreateSpatialModelEntityCommand = class extends JSBCommand {
1069
- constructor(options) {
1070
- super();
1071
- this.options = options;
1072
- }
1073
- getParams() {
1074
- return this.options;
1075
- }
1076
- commandType = "CreateSpatialModelEntity";
1077
- };
1078
- CreateModelAssetCommand = class extends JSBCommand {
1079
- constructor(options) {
1080
- super();
1081
- this.options = options;
1082
- }
1083
- getParams() {
1084
- return { url: this.options.url };
1085
- }
1086
- commandType = "CreateModelAsset";
1087
- };
1088
- CreateSpatialGeometryCommand = class extends JSBCommand {
1089
- constructor(type, options = {}) {
1090
- super();
1091
- this.type = type;
1092
- this.options = options;
1093
- }
1094
- getParams() {
1095
- return { type: this.type, ...this.options };
1096
- }
1097
- commandType = "CreateGeometry";
1098
- };
1099
- CreateSpatialUnlitMaterialCommand = class extends JSBCommand {
1100
- constructor(options) {
1101
- super();
1102
- this.options = options;
1103
- }
1104
- getParams() {
1105
- return this.options;
1106
- }
1107
- commandType = "CreateUnlitMaterial";
1108
- };
1109
- AddComponentToEntityCommand = class extends JSBCommand {
1110
- constructor(entity, comp) {
1111
- super();
1112
- this.entity = entity;
1113
- this.comp = comp;
1114
- }
1115
- getParams() {
1116
- return {
1117
- entityId: this.entity.id,
1118
- componentId: this.comp.id
1119
- };
1120
- }
1121
- commandType = "AddComponentToEntity";
1122
- };
1123
- RemoveComponentFromEntityCommand = class extends JSBCommand {
1124
- constructor(entity, comp) {
1125
- super();
1126
- this.entity = entity;
1127
- this.comp = comp;
1128
- }
1129
- getParams() {
1130
- return {
1131
- entityId: this.entity.id,
1132
- componentId: this.comp.id
1133
- };
1134
- }
1135
- commandType = "RemoveComponentFromEntity";
793
+ var JSBCommand = class {
794
+ commandType = "";
795
+ async execute() {
796
+ const param = this.getParams();
797
+ const msg = param ? JSON.stringify(param) : "";
798
+ const platform = await getPlatform();
799
+ return platform.callJSB(this.commandType, msg);
800
+ }
801
+ };
802
+ var UpdateEntityPropertiesCommand = class extends JSBCommand {
803
+ constructor(entity, properties) {
804
+ super();
805
+ this.entity = entity;
806
+ this.properties = properties;
807
+ }
808
+ commandType = "UpdateEntityProperties";
809
+ getParams() {
810
+ const transform = composeSRT(
811
+ this.properties.position ?? this.entity.position,
812
+ this.properties.rotation ?? this.entity.rotation,
813
+ this.properties.scale ?? this.entity.scale
814
+ ).toFloat64Array();
815
+ return {
816
+ entityId: this.entity.id,
817
+ transform
1136
818
  };
1137
- SetMaterialsOnEntityCommand = class extends JSBCommand {
1138
- constructor(entityId, materials) {
1139
- super();
1140
- this.entityId = entityId;
1141
- this.materials = materials;
1142
- }
1143
- getParams() {
1144
- return {
1145
- entityId: this.entityId,
1146
- materialIds: this.materials.map((m) => m.id)
1147
- };
1148
- }
1149
- commandType = "SetMaterialsOnEntity";
819
+ }
820
+ };
821
+ var UpdateEntityEventCommand = class extends JSBCommand {
822
+ constructor(entity, type, isEnable) {
823
+ super();
824
+ this.entity = entity;
825
+ this.type = type;
826
+ this.isEnable = isEnable;
827
+ }
828
+ commandType = "UpdateEntityEvent";
829
+ getParams() {
830
+ return {
831
+ type: this.type,
832
+ entityId: this.entity.id,
833
+ isEnable: this.isEnable
1150
834
  };
1151
- SetParentForEntityCommand = class extends JSBCommand {
1152
- // childId, parentId
1153
- constructor(childId, parentId) {
1154
- super();
1155
- this.childId = childId;
1156
- this.parentId = parentId;
1157
- }
1158
- getParams() {
1159
- return {
1160
- childId: this.childId,
1161
- parentId: this.parentId
1162
- };
1163
- }
1164
- commandType = "SetParentToEntity";
835
+ }
836
+ };
837
+ var UpdateSpatialSceneProperties = class extends JSBCommand {
838
+ properties;
839
+ commandType = "UpdateSpatialSceneProperties";
840
+ constructor(properties) {
841
+ super();
842
+ this.properties = properties;
843
+ }
844
+ getParams() {
845
+ return this.properties;
846
+ }
847
+ };
848
+ var UpdateSceneConfig = class extends JSBCommand {
849
+ config;
850
+ commandType = "UpdateSceneConfig";
851
+ constructor(config) {
852
+ super();
853
+ this.config = config;
854
+ }
855
+ getParams() {
856
+ return { config: this.config };
857
+ }
858
+ };
859
+ var FocusScene = class extends JSBCommand {
860
+ constructor(id) {
861
+ super();
862
+ this.id = id;
863
+ }
864
+ commandType = "FocusScene";
865
+ getParams() {
866
+ return { id: this.id };
867
+ }
868
+ };
869
+ var GetSpatialSceneState = class extends JSBCommand {
870
+ commandType = "GetSpatialSceneState";
871
+ constructor() {
872
+ super();
873
+ }
874
+ getParams() {
875
+ return {};
876
+ }
877
+ };
878
+ var SpatializedElementCommand = class extends JSBCommand {
879
+ constructor(spatialObject) {
880
+ super();
881
+ this.spatialObject = spatialObject;
882
+ }
883
+ getParams() {
884
+ const extraParams = this.getExtraParams();
885
+ return { id: this.spatialObject.id, ...extraParams };
886
+ }
887
+ };
888
+ var UpdateSpatialized2DElementProperties = class extends SpatializedElementCommand {
889
+ properties;
890
+ commandType = "UpdateSpatialized2DElementProperties";
891
+ constructor(spatialObject, properties) {
892
+ super(spatialObject);
893
+ this.properties = properties;
894
+ }
895
+ getExtraParams() {
896
+ return this.properties;
897
+ }
898
+ };
899
+ var UpdateSpatializedDynamic3DElementProperties = class extends SpatializedElementCommand {
900
+ properties;
901
+ commandType = "UpdateSpatializedDynamic3DElementProperties";
902
+ constructor(spatialObject, properties) {
903
+ super(spatialObject);
904
+ this.properties = properties;
905
+ }
906
+ getExtraParams() {
907
+ return {
908
+ id: this.spatialObject.id,
909
+ ...this.properties
1165
910
  };
1166
- ConvertFromEntityToEntityCommand = class extends JSBCommand {
1167
- constructor(fromEntityId, toEntityId, fromPosition) {
1168
- super();
1169
- this.fromEntityId = fromEntityId;
1170
- this.toEntityId = toEntityId;
1171
- this.fromPosition = fromPosition;
1172
- }
1173
- getParams() {
1174
- return {
1175
- fromEntityId: this.fromEntityId,
1176
- toEntityId: this.toEntityId,
1177
- position: this.fromPosition
1178
- };
1179
- }
1180
- commandType = "ConvertFromEntityToEntity";
911
+ }
912
+ };
913
+ var UpdateUnlitMaterialProperties = class extends SpatializedElementCommand {
914
+ properties;
915
+ commandType = "UpdateUnlitMaterialProperties";
916
+ constructor(spatialObject, properties) {
917
+ super(spatialObject);
918
+ this.properties = properties;
919
+ }
920
+ getExtraParams() {
921
+ return this.properties;
922
+ }
923
+ };
924
+ var UpdateSpatializedElementTransform = class extends SpatializedElementCommand {
925
+ matrix;
926
+ commandType = "UpdateSpatializedElementTransform";
927
+ constructor(spatialObject, matrix) {
928
+ super(spatialObject);
929
+ this.matrix = matrix;
930
+ }
931
+ getExtraParams() {
932
+ return { matrix: Array.from(this.matrix.toFloat64Array()) };
933
+ }
934
+ };
935
+ var UpdateSpatializedStatic3DElementProperties = class extends SpatializedElementCommand {
936
+ properties;
937
+ commandType = "UpdateSpatializedStatic3DElementProperties";
938
+ constructor(spatialObject, properties) {
939
+ super(spatialObject);
940
+ this.properties = properties;
941
+ }
942
+ getExtraParams() {
943
+ return this.properties;
944
+ }
945
+ };
946
+ var AddSpatializedElementToSpatialized2DElement = class extends SpatializedElementCommand {
947
+ commandType = "AddSpatializedElementToSpatialized2DElement";
948
+ spatializedElement;
949
+ constructor(spatialObject, spatializedElement) {
950
+ super(spatialObject);
951
+ this.spatializedElement = spatializedElement;
952
+ }
953
+ getExtraParams() {
954
+ return { spatializedElementId: this.spatializedElement.id };
955
+ }
956
+ };
957
+ var AddSpatializedElementToSpatialScene = class extends JSBCommand {
958
+ commandType = "AddSpatializedElementToSpatialScene";
959
+ spatializedElement;
960
+ constructor(spatializedElement) {
961
+ super();
962
+ this.spatializedElement = spatializedElement;
963
+ }
964
+ getParams() {
965
+ return {
966
+ spatializedElementId: this.spatializedElement.id
1181
967
  };
1182
- ConvertFromEntityToSceneCommand = class extends JSBCommand {
1183
- constructor(fromEntityId, position) {
1184
- super();
1185
- this.fromEntityId = fromEntityId;
1186
- this.position = position;
1187
- }
1188
- getParams() {
1189
- return {
1190
- fromEntityId: this.fromEntityId,
1191
- position: this.position
1192
- };
1193
- }
1194
- commandType = "ConvertFromEntityToScene";
968
+ }
969
+ };
970
+ var CreateSpatializedStatic3DElementCommand = class extends JSBCommand {
971
+ constructor(modelURL, sources, loading = "eager") {
972
+ super();
973
+ this.modelURL = modelURL;
974
+ this.sources = sources;
975
+ this.loading = loading;
976
+ this.modelURL = modelURL;
977
+ this.sources = sources;
978
+ this.loading = loading;
979
+ }
980
+ commandType = "CreateSpatializedStatic3DElement";
981
+ getParams() {
982
+ return {
983
+ modelURL: this.modelURL,
984
+ sources: this.sources,
985
+ loading: this.loading
1195
986
  };
1196
- ConvertFromSceneToEntityCommand = class extends JSBCommand {
1197
- // let entityId: String
1198
- // let position:Vec3
1199
- constructor(entityId, position) {
1200
- super();
1201
- this.entityId = entityId;
1202
- this.position = position;
1203
- }
1204
- getParams() {
1205
- return {
1206
- entityId: this.entityId,
1207
- position: this.position
1208
- };
1209
- }
1210
- commandType = "ConvertFromSceneToEntity";
987
+ }
988
+ };
989
+ var CreateSpatializedDynamic3DElementCommand = class extends JSBCommand {
990
+ getParams() {
991
+ return { test: true };
992
+ }
993
+ commandType = "CreateSpatializedDynamic3DElement";
994
+ };
995
+ var CreateSpatialEntityCommand = class extends JSBCommand {
996
+ constructor(name) {
997
+ super();
998
+ this.name = name;
999
+ }
1000
+ getParams() {
1001
+ return { name: this.name };
1002
+ }
1003
+ commandType = "CreateSpatialEntity";
1004
+ };
1005
+ var CreateModelComponentCommand = class extends JSBCommand {
1006
+ constructor(options) {
1007
+ super();
1008
+ this.options = options;
1009
+ }
1010
+ getParams() {
1011
+ let geometryId = this.options.mesh.id;
1012
+ let materialIds = this.options.materials.map((material) => material.id);
1013
+ return { geometryId, materialIds };
1014
+ }
1015
+ commandType = "CreateModelComponent";
1016
+ };
1017
+ var CreateSpatialModelEntityCommand = class extends JSBCommand {
1018
+ constructor(options) {
1019
+ super();
1020
+ this.options = options;
1021
+ }
1022
+ getParams() {
1023
+ return this.options;
1024
+ }
1025
+ commandType = "CreateSpatialModelEntity";
1026
+ };
1027
+ var CreateModelAssetCommand = class extends JSBCommand {
1028
+ constructor(options) {
1029
+ super();
1030
+ this.options = options;
1031
+ }
1032
+ getParams() {
1033
+ return { url: this.options.url };
1034
+ }
1035
+ commandType = "CreateModelAsset";
1036
+ };
1037
+ var CreateSpatialGeometryCommand = class extends JSBCommand {
1038
+ constructor(type, options = {}) {
1039
+ super();
1040
+ this.type = type;
1041
+ this.options = options;
1042
+ }
1043
+ getParams() {
1044
+ return { type: this.type, ...this.options };
1045
+ }
1046
+ commandType = "CreateGeometry";
1047
+ };
1048
+ var CreateSpatialUnlitMaterialCommand = class extends JSBCommand {
1049
+ constructor(options) {
1050
+ super();
1051
+ this.options = options;
1052
+ }
1053
+ getParams() {
1054
+ return this.options;
1055
+ }
1056
+ commandType = "CreateUnlitMaterial";
1057
+ };
1058
+ var AddComponentToEntityCommand = class extends JSBCommand {
1059
+ constructor(entity, comp) {
1060
+ super();
1061
+ this.entity = entity;
1062
+ this.comp = comp;
1063
+ }
1064
+ getParams() {
1065
+ return {
1066
+ entityId: this.entity.id,
1067
+ componentId: this.comp.id
1211
1068
  };
1212
- ConvertCoordinateCommand = class extends JSBCommand {
1213
- constructor(position, fromId, toId) {
1214
- super();
1215
- this.position = position;
1216
- this.fromId = fromId;
1217
- this.toId = toId;
1218
- }
1219
- getParams() {
1220
- return {
1221
- position: this.position,
1222
- fromId: this.fromId,
1223
- toId: this.toId
1224
- };
1225
- }
1226
- commandType = "ConvertCoordinate";
1069
+ }
1070
+ commandType = "AddComponentToEntity";
1071
+ };
1072
+ var RemoveComponentFromEntityCommand = class extends JSBCommand {
1073
+ constructor(entity, comp) {
1074
+ super();
1075
+ this.entity = entity;
1076
+ this.comp = comp;
1077
+ }
1078
+ getParams() {
1079
+ return {
1080
+ entityId: this.entity.id,
1081
+ componentId: this.comp.id
1227
1082
  };
1228
- InspectCommand = class extends JSBCommand {
1229
- constructor(id = "") {
1230
- super();
1231
- this.id = id;
1232
- }
1233
- commandType = "Inspect";
1234
- getParams() {
1235
- return this.id ? { id: this.id } : { id: "" };
1236
- }
1083
+ }
1084
+ commandType = "RemoveComponentFromEntity";
1085
+ };
1086
+ var SetMaterialsOnEntityCommand = class extends JSBCommand {
1087
+ constructor(entityId, materials) {
1088
+ super();
1089
+ this.entityId = entityId;
1090
+ this.materials = materials;
1091
+ }
1092
+ getParams() {
1093
+ return {
1094
+ entityId: this.entityId,
1095
+ materialIds: this.materials.map((m) => m.id)
1237
1096
  };
1238
- DestroyCommand = class extends JSBCommand {
1239
- constructor(id) {
1240
- super();
1241
- this.id = id;
1242
- }
1243
- commandType = "Destroy";
1244
- getParams() {
1245
- return { id: this.id };
1246
- }
1097
+ }
1098
+ commandType = "SetMaterialsOnEntity";
1099
+ };
1100
+ var SetParentForEntityCommand = class extends JSBCommand {
1101
+ // childId, parentId
1102
+ constructor(childId, parentId) {
1103
+ super();
1104
+ this.childId = childId;
1105
+ this.parentId = parentId;
1106
+ }
1107
+ getParams() {
1108
+ return {
1109
+ childId: this.childId,
1110
+ parentId: this.parentId
1247
1111
  };
1248
- CheckWebViewCanCreateCommand = class extends JSBCommand {
1249
- constructor(id = "") {
1250
- super();
1251
- this.id = id;
1252
- }
1253
- commandType = "CheckWebViewCanCreate";
1254
- getParams() {
1255
- return { id: this.id };
1256
- }
1112
+ }
1113
+ commandType = "SetParentToEntity";
1114
+ };
1115
+ var ConvertFromEntityToEntityCommand = class extends JSBCommand {
1116
+ constructor(fromEntityId, toEntityId, fromPosition) {
1117
+ super();
1118
+ this.fromEntityId = fromEntityId;
1119
+ this.toEntityId = toEntityId;
1120
+ this.fromPosition = fromPosition;
1121
+ }
1122
+ getParams() {
1123
+ return {
1124
+ fromEntityId: this.fromEntityId,
1125
+ toEntityId: this.toEntityId,
1126
+ position: this.fromPosition
1257
1127
  };
1258
- WebSpatialProtocolCommand = class extends JSBCommand {
1259
- target;
1260
- features;
1261
- async execute() {
1262
- const query = this.getQuery();
1263
- return platform.callWebSpatialProtocol(
1264
- this.commandType,
1265
- query,
1266
- this.target,
1267
- this.features
1268
- );
1269
- }
1270
- executeSync() {
1271
- const query = this.getQuery();
1272
- return platform.callWebSpatialProtocolSync(
1273
- this.commandType,
1274
- query,
1275
- this.target,
1276
- this.features
1277
- );
1278
- }
1279
- getQuery() {
1280
- let query = void 0;
1281
- const params = this.getParams();
1282
- if (params) {
1283
- query = Object.keys(params).map((key) => {
1284
- const value = params[key];
1285
- const finalValue = typeof value === "object" ? JSON.stringify(value) : value;
1286
- return `${key}=${encodeURIComponent(finalValue)}`;
1287
- }).join("&");
1288
- }
1289
- return query;
1290
- }
1128
+ }
1129
+ commandType = "ConvertFromEntityToEntity";
1130
+ };
1131
+ var ConvertFromEntityToSceneCommand = class extends JSBCommand {
1132
+ constructor(fromEntityId, position) {
1133
+ super();
1134
+ this.fromEntityId = fromEntityId;
1135
+ this.position = position;
1136
+ }
1137
+ getParams() {
1138
+ return {
1139
+ fromEntityId: this.fromEntityId,
1140
+ position: this.position
1291
1141
  };
1292
- createSpatialized2DElementCommand = class extends WebSpatialProtocolCommand {
1293
- commandType = "createSpatialized2DElement";
1294
- constructor() {
1295
- super();
1296
- }
1297
- getParams() {
1298
- return {};
1299
- }
1142
+ }
1143
+ commandType = "ConvertFromEntityToScene";
1144
+ };
1145
+ var ConvertFromSceneToEntityCommand = class extends JSBCommand {
1146
+ // let entityId: String
1147
+ // let position:Vec3
1148
+ constructor(entityId, position) {
1149
+ super();
1150
+ this.entityId = entityId;
1151
+ this.position = position;
1152
+ }
1153
+ getParams() {
1154
+ return {
1155
+ entityId: this.entityId,
1156
+ position: this.position
1300
1157
  };
1301
- createSpatialSceneCommand = class extends WebSpatialProtocolCommand {
1302
- constructor(url, config, target, features) {
1303
- super();
1304
- this.url = url;
1305
- this.config = config;
1306
- this.target = target;
1307
- this.features = features;
1308
- }
1309
- commandType = "createSpatialScene";
1310
- getParams() {
1311
- return {
1312
- url: this.url,
1313
- config: this.config
1314
- };
1315
- }
1158
+ }
1159
+ commandType = "ConvertFromSceneToEntity";
1160
+ };
1161
+ var ConvertCoordinateCommand = class extends JSBCommand {
1162
+ constructor(position, fromId, toId) {
1163
+ super();
1164
+ this.position = position;
1165
+ this.fromId = fromId;
1166
+ this.toId = toId;
1167
+ }
1168
+ getParams() {
1169
+ return {
1170
+ position: this.position,
1171
+ fromId: this.fromId,
1172
+ toId: this.toId
1316
1173
  };
1317
- CreateAttachmentEntityCommand = class extends WebSpatialProtocolCommand {
1318
- constructor(options) {
1319
- super();
1320
- this.options = options;
1321
- }
1322
- commandType = "createAttachment";
1323
- getParams() {
1324
- return {};
1325
- }
1174
+ }
1175
+ commandType = "ConvertCoordinate";
1176
+ };
1177
+ var CreateTextureCommand = class extends JSBCommand {
1178
+ constructor(url) {
1179
+ super();
1180
+ this.url = url;
1181
+ }
1182
+ getParams() {
1183
+ return {
1184
+ url: this.url
1326
1185
  };
1327
- InitializeAttachmentCommand = class extends JSBCommand {
1328
- constructor(attachmentId, options) {
1329
- super();
1330
- this.attachmentId = attachmentId;
1331
- this.options = options;
1332
- }
1333
- commandType = "InitializeAttachment";
1334
- getParams() {
1335
- return {
1336
- id: this.attachmentId,
1337
- parentEntityId: this.options.parentEntityId,
1338
- position: this.options.position ?? [0, 0, 0],
1339
- size: this.options.size,
1340
- ownerViewId: this.options.ownerViewId
1341
- };
1342
- }
1186
+ }
1187
+ commandType = "CreateTexture";
1188
+ };
1189
+ var UpdateTexturePropertiesCommand = class extends SpatializedElementCommand {
1190
+ properties;
1191
+ commandType = "UpdateTextureProperties";
1192
+ constructor(spatialObject, properties) {
1193
+ super(spatialObject);
1194
+ this.properties = properties;
1195
+ }
1196
+ getExtraParams() {
1197
+ return this.properties;
1198
+ }
1199
+ };
1200
+ var InspectCommand = class extends JSBCommand {
1201
+ constructor(id = "") {
1202
+ super();
1203
+ this.id = id;
1204
+ }
1205
+ commandType = "Inspect";
1206
+ getParams() {
1207
+ return this.id ? { id: this.id } : { id: "" };
1208
+ }
1209
+ };
1210
+ var DestroyCommand = class extends JSBCommand {
1211
+ constructor(id) {
1212
+ super();
1213
+ this.id = id;
1214
+ }
1215
+ commandType = "Destroy";
1216
+ getParams() {
1217
+ return { id: this.id };
1218
+ }
1219
+ };
1220
+ var InitializeAttachmentCommand = class extends JSBCommand {
1221
+ constructor(attachmentId, options) {
1222
+ super();
1223
+ this.attachmentId = attachmentId;
1224
+ this.options = options;
1225
+ }
1226
+ commandType = "InitializeAttachment";
1227
+ getParams() {
1228
+ return {
1229
+ id: this.attachmentId,
1230
+ parentEntityId: this.options.parentEntityId,
1231
+ position: this.options.position ?? [0, 0, 0],
1232
+ size: this.options.size,
1233
+ ownerViewId: this.options.ownerViewId
1343
1234
  };
1344
- UpdateAttachmentEntityCommand = class extends JSBCommand {
1345
- constructor(attachmentId, options) {
1346
- super();
1347
- this.attachmentId = attachmentId;
1348
- this.options = options;
1349
- }
1350
- commandType = "UpdateAttachmentEntity";
1351
- getParams() {
1352
- return {
1353
- id: this.attachmentId,
1354
- ...this.options
1355
- };
1356
- }
1235
+ }
1236
+ };
1237
+ var UpdateAttachmentEntityCommand = class extends JSBCommand {
1238
+ constructor(attachmentId, options) {
1239
+ super();
1240
+ this.attachmentId = attachmentId;
1241
+ this.options = options;
1242
+ }
1243
+ commandType = "UpdateAttachmentEntity";
1244
+ getParams() {
1245
+ return {
1246
+ id: this.attachmentId,
1247
+ ...this.options
1357
1248
  };
1358
1249
  }
1359
- });
1250
+ };
1360
1251
 
1361
1252
  // src/SpatialObject.ts
1362
- init_JSBCommand();
1363
1253
  var SpatialObject = class {
1364
1254
  /** @hidden */
1365
1255
  constructor(id) {
@@ -1393,12 +1283,20 @@ var SpatialObject = class {
1393
1283
  }
1394
1284
  };
1395
1285
 
1396
- // src/scene-polyfill.ts
1397
- init_JSBCommand();
1286
+ // src/spatial-host.ts
1287
+ async function createNativeSpatialDiv() {
1288
+ const platform = await getPlatform();
1289
+ return platform.createNativeSpatialDiv();
1290
+ }
1291
+ async function createNativeAttachment(options) {
1292
+ const platform = await getPlatform();
1293
+ return platform.createNativeAttachment(options);
1294
+ }
1295
+ function openSpatialSceneSync(url, config, target, features) {
1296
+ return getPlatformSync().openSpatialSceneSync(url, config, target, features);
1297
+ }
1398
1298
 
1399
1299
  // src/SpatialScene.ts
1400
- init_JSBCommand();
1401
- init_JSBCommand();
1402
1300
  var instance;
1403
1301
  var SpatialScene = class _SpatialScene extends SpatialObject {
1404
1302
  /**
@@ -1566,9 +1464,6 @@ var CubeInfo = class {
1566
1464
  }
1567
1465
  };
1568
1466
 
1569
- // src/scene-polyfill.ts
1570
- init_utils();
1571
-
1572
1467
  // src/physicalMetrics.ts
1573
1468
  var physicalMetrics_exports = {};
1574
1469
  __export(physicalMetrics_exports, {
@@ -1577,7 +1472,6 @@ __export(physicalMetrics_exports, {
1577
1472
  pointToPhysical: () => pointToPhysical,
1578
1473
  subscribe: () => subscribe
1579
1474
  });
1580
- init_SpatialWebEvent();
1581
1475
  var snapshot = {
1582
1476
  meterToPtUnscaled: 1360,
1583
1477
  meterToPtScaled: 1360
@@ -1775,8 +1669,12 @@ var SceneManager = class _SceneManager {
1775
1669
  const [ans] = formatSceneConfig(preFormatted, "window");
1776
1670
  cfg = { ...ans, type: "window" };
1777
1671
  }
1778
- const cmd = new createSpatialSceneCommand(url, cfg, target, features);
1779
- const result = cmd.executeSync();
1672
+ const result = openSpatialSceneSync(
1673
+ url,
1674
+ cfg,
1675
+ target,
1676
+ features
1677
+ );
1780
1678
  const id = result.data?.id;
1781
1679
  if (id) {
1782
1680
  let focusCmd = new FocusScene(id);
@@ -1930,7 +1828,6 @@ function formatToNumber(str, targetUnit, defaultUnit) {
1930
1828
  }
1931
1829
  }
1932
1830
  function formatSceneConfig(config, sceneType) {
1933
- const defaultSceneConfig2 = getSceneDefaultConfig(sceneType);
1934
1831
  const errors = [];
1935
1832
  const isWindow = sceneType === "window";
1936
1833
  if (!isValidSpatialSceneType(sceneType)) {
@@ -2076,16 +1973,6 @@ function injectSceneHook() {
2076
1973
  injectScenePolyfill();
2077
1974
  }
2078
1975
 
2079
- // src/SpatializedElementCreator.ts
2080
- init_JSBCommand();
2081
-
2082
- // src/Spatialized2DElement.ts
2083
- init_JSBCommand();
2084
-
2085
- // src/SpatializedElement.ts
2086
- init_JSBCommand();
2087
- init_SpatialWebEvent();
2088
-
2089
1976
  // src/SpatialWebEventCreator.ts
2090
1977
  function createSpatialEvent(type, detail) {
2091
1978
  return new CustomEvent(type, {
@@ -2311,7 +2198,6 @@ var Spatialized2DElement = class extends SpatializedElement {
2311
2198
  };
2312
2199
 
2313
2200
  // src/SpatializedStatic3DElement.ts
2314
- init_JSBCommand();
2315
2201
  var SpatializedStatic3DElement = class extends SpatializedElement {
2316
2202
  /**
2317
2203
  * Creates a new spatialized static 3D element with the specified ID and URL.
@@ -2319,11 +2205,13 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2319
2205
  * @param id Unique identifier for this element
2320
2206
  * @param modelURL URL of the 3D model
2321
2207
  * @param sources Optional fallback model sources
2208
+ * @param loading Initial loading mode (`'eager'` by default)
2322
2209
  */
2323
- constructor(id, modelURL, sources) {
2210
+ constructor(id, modelURL, sources, loading = "eager") {
2324
2211
  super(id);
2325
2212
  this.modelURL = modelURL;
2326
2213
  this.sources = sources;
2214
+ this._loading = loading;
2327
2215
  }
2328
2216
  /**
2329
2217
  * Promise resolver for the ready state.
@@ -2335,6 +2223,10 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2335
2223
  * Used to reset the ready promise when the model URL changes.
2336
2224
  */
2337
2225
  modelURL;
2226
+ // @TODO: Deprecate modelURL property from Web and Swift code
2227
+ get modelUrl() {
2228
+ return this.modelURL;
2229
+ }
2338
2230
  /**
2339
2231
  * Caches the last sources array to detect changes.
2340
2232
  */
@@ -2393,8 +2285,19 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2393
2285
  this._loop = properties.loop;
2394
2286
  }
2395
2287
  if (properties.playbackRate !== void 0) {
2288
+ if (!this._paused) {
2289
+ this._currentTime = this.currentTime;
2290
+ this._anchorTimestamp = Date.now();
2291
+ }
2396
2292
  this._playbackRate = properties.playbackRate;
2397
2293
  }
2294
+ if (properties.currentTime !== void 0) {
2295
+ this._currentTime = properties.currentTime;
2296
+ this._anchorTimestamp = Date.now();
2297
+ }
2298
+ if (properties.loading !== void 0) {
2299
+ this._loading = properties.loading;
2300
+ }
2398
2301
  return new UpdateSpatializedStatic3DElementProperties(
2399
2302
  this,
2400
2303
  properties
@@ -2426,6 +2329,41 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2426
2329
  set playbackRate(value) {
2427
2330
  this.updateProperties({ playbackRate: value });
2428
2331
  }
2332
+ /**
2333
+ * Last playback position sampled from native (seconds).
2334
+ */
2335
+ _currentTime = 0;
2336
+ /**
2337
+ * Unix epoch time (ms) corresponding to `_currentTime`. Sourced from the
2338
+ * native `timestamp` on samples, or `Date.now()` on local seeks/transitions.
2339
+ */
2340
+ _anchorTimestamp = 0;
2341
+ clampTime(time) {
2342
+ if (!Number.isFinite(time) || time < 0) return 0;
2343
+ if (time > this._duration) {
2344
+ return this.loop && this.duration > 0 ? time % this._duration : this.duration;
2345
+ }
2346
+ return time;
2347
+ }
2348
+ /**
2349
+ * Returns the current (un-scaled) playback position in seconds. While
2350
+ * playing, the value is extrapolated from the last anchor using
2351
+ * `playbackRate` and clamped to `[0, duration]`; while paused it returns
2352
+ * the anchor directly.
2353
+ */
2354
+ get currentTime() {
2355
+ if (this._paused) return this._currentTime;
2356
+ const elapsed = (Date.now() - this._anchorTimestamp) / 1e3;
2357
+ return this.clampTime(this._currentTime + elapsed * this._playbackRate);
2358
+ }
2359
+ /**
2360
+ * Seeks the animation to `value` seconds (clamped to `[0, duration]`) and
2361
+ * forwards the request to native.
2362
+ */
2363
+ set currentTime(value) {
2364
+ const time = Number.isNaN(value) ? 0 : clamp(value, 0, this.duration);
2365
+ this.updateProperties({ currentTime: time });
2366
+ }
2429
2367
  /**
2430
2368
  * Whether the animation is currently paused.
2431
2369
  */
@@ -2451,6 +2389,9 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2451
2389
  * @returns Promise resolving when the command is sent
2452
2390
  */
2453
2391
  async play() {
2392
+ if (this._paused) {
2393
+ this._anchorTimestamp = Date.now();
2394
+ }
2454
2395
  this._paused = false;
2455
2396
  await this.updateProperties({ animationPaused: false });
2456
2397
  }
@@ -2459,6 +2400,10 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2459
2400
  * @returns Promise resolving when the command is sent
2460
2401
  */
2461
2402
  async pause() {
2403
+ if (!this._paused) {
2404
+ this._currentTime = this.currentTime;
2405
+ this._anchorTimestamp = Date.now();
2406
+ }
2462
2407
  this._paused = true;
2463
2408
  await this.updateProperties({ animationPaused: true });
2464
2409
  }
@@ -2478,6 +2423,8 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2478
2423
  } else if (data.type === "animationstatechange" /* animationstatechange */) {
2479
2424
  this._paused = data.detail.paused;
2480
2425
  this._duration = data.detail.duration;
2426
+ this._currentTime = data.detail.currentTime ?? 0;
2427
+ this._anchorTimestamp = data.detail.timestamp ?? Date.now();
2481
2428
  this._onAnimationStateChangeCallback?.(data.detail);
2482
2429
  } else {
2483
2430
  super.onReceiveEvent(data);
@@ -2493,6 +2440,14 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2493
2440
  get autoplay() {
2494
2441
  return this._autoplay;
2495
2442
  }
2443
+ /**
2444
+ * Asset fetch policy. `'lazy'` defers fetching until the host signals the
2445
+ * element is in view; `'eager'` fetches immediately.
2446
+ */
2447
+ _loading = "eager";
2448
+ get loading() {
2449
+ return this._loading;
2450
+ }
2496
2451
  /**
2497
2452
  * Whether the model animation should loop continuously.
2498
2453
  */
@@ -2530,9 +2485,11 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
2530
2485
  this.updateProperties({ modelTransform });
2531
2486
  }
2532
2487
  };
2488
+ function clamp(num, min, max) {
2489
+ return num <= min ? min : num >= max ? max : num;
2490
+ }
2533
2491
 
2534
2492
  // src/SpatializedDynamic3DElement.ts
2535
- init_JSBCommand();
2536
2493
  var SpatializedDynamic3DElement = class extends SpatializedElement {
2537
2494
  children = [];
2538
2495
  events = {};
@@ -2566,7 +2523,7 @@ var SpatializedDynamic3DElement = class extends SpatializedElement {
2566
2523
 
2567
2524
  // src/SpatializedElementCreator.ts
2568
2525
  async function createSpatialized2DElement() {
2569
- const result = await new createSpatialized2DElementCommand().execute();
2526
+ const result = await createNativeSpatialDiv();
2570
2527
  if (!result.success) {
2571
2528
  throw new Error("createSpatialized2DElement failed");
2572
2529
  } else {
@@ -2576,16 +2533,17 @@ async function createSpatialized2DElement() {
2576
2533
  return new Spatialized2DElement(id, windowProxy);
2577
2534
  }
2578
2535
  }
2579
- async function createSpatializedStatic3DElement(modelURL, sources) {
2536
+ async function createSpatializedStatic3DElement(modelURL, sources, loading = "eager") {
2580
2537
  const result = await new CreateSpatializedStatic3DElementCommand(
2581
2538
  modelURL,
2582
- sources
2539
+ sources,
2540
+ loading
2583
2541
  ).execute();
2584
2542
  if (!result.success) {
2585
2543
  throw new Error("createSpatializedStatic3DElement failed");
2586
2544
  } else {
2587
2545
  const { id } = result.data;
2588
- return new SpatializedStatic3DElement(id, modelURL, sources);
2546
+ return new SpatializedStatic3DElement(id, modelURL, sources, loading);
2589
2547
  }
2590
2548
  }
2591
2549
  async function createSpatializedDynamic3DElement() {
@@ -2599,7 +2557,6 @@ async function createSpatializedDynamic3DElement() {
2599
2557
  }
2600
2558
 
2601
2559
  // src/reality/Attachment.ts
2602
- init_JSBCommand();
2603
2560
  var Attachment = class extends SpatialObject {
2604
2561
  constructor(id, windowProxy, options) {
2605
2562
  super(id);
@@ -2620,7 +2577,7 @@ var Attachment = class extends SpatialObject {
2620
2577
  }
2621
2578
  };
2622
2579
  async function createAttachmentEntity(options) {
2623
- const result = await new CreateAttachmentEntityCommand(options).execute();
2580
+ const result = await createNativeAttachment(options);
2624
2581
  if (!result.success) {
2625
2582
  throw new Error("createAttachmentEntity failed: " + result?.errorMessage);
2626
2583
  }
@@ -2629,13 +2586,7 @@ async function createAttachmentEntity(options) {
2629
2586
  return new Attachment(id, windowProxy, options);
2630
2587
  }
2631
2588
 
2632
- // src/reality/realityCreator.ts
2633
- init_JSBCommand();
2634
-
2635
2589
  // src/reality/entity/SpatialEntity.ts
2636
- init_JSBCommand();
2637
- init_JSBCommand();
2638
- init_SpatialWebEvent();
2639
2590
  var SpatialEntity = class extends SpatialObject {
2640
2591
  constructor(id, userData) {
2641
2592
  super(id);
@@ -2820,7 +2771,6 @@ var SpatialEntity = class extends SpatialObject {
2820
2771
  };
2821
2772
 
2822
2773
  // src/reality/entity/SpatialModelEntity.ts
2823
- init_JSBCommand();
2824
2774
  var SpatialModelEntity = class extends SpatialEntity {
2825
2775
  constructor(id, options, userData) {
2826
2776
  super(id, userData);
@@ -2834,7 +2784,6 @@ var SpatialModelEntity = class extends SpatialEntity {
2834
2784
  };
2835
2785
 
2836
2786
  // src/reality/component/SpatialComponent.ts
2837
- init_SpatialWebEvent();
2838
2787
  var SpatialComponent = class extends SpatialObject {
2839
2788
  constructor(id) {
2840
2789
  super(id);
@@ -2856,9 +2805,6 @@ var ModelComponent = class extends SpatialComponent {
2856
2805
  }
2857
2806
  };
2858
2807
 
2859
- // src/reality/material/SpatialUnlitMaterial.ts
2860
- init_JSBCommand();
2861
-
2862
2808
  // src/reality/material/SpatialMaterial.ts
2863
2809
  var SpatialMaterial = class extends SpatialObject {
2864
2810
  constructor(id, type) {
@@ -2890,6 +2836,18 @@ var SpatialModelAsset = class extends SpatialObject {
2890
2836
  }
2891
2837
  };
2892
2838
 
2839
+ // src/reality/resource/SpatialTextureResource.ts
2840
+ var SpatialTextureResource = class extends SpatialObject {
2841
+ constructor(id, options) {
2842
+ super(id);
2843
+ this.id = id;
2844
+ this.options = options;
2845
+ }
2846
+ updateProperties(properties) {
2847
+ return new UpdateTexturePropertiesCommand(this, properties).execute();
2848
+ }
2849
+ };
2850
+
2893
2851
  // src/reality/realityCreator.ts
2894
2852
  async function createSpatialEntity(userData) {
2895
2853
  const result = await new CreateSpatialEntityCommand(userData?.name).execute();
@@ -2948,6 +2906,15 @@ async function createModelAsset(options) {
2948
2906
  return new SpatialModelAsset(id, options);
2949
2907
  }
2950
2908
  }
2909
+ async function createSpatialTexture(options) {
2910
+ const result = await new CreateTextureCommand(options.url).execute();
2911
+ if (!result.success) {
2912
+ throw new Error("createSpatialTexture failed:" + result?.errorMessage);
2913
+ } else {
2914
+ const { id } = result.data;
2915
+ return new SpatialTextureResource(id, options);
2916
+ }
2917
+ }
2951
2918
 
2952
2919
  // src/reality/geometry/SpatialGeometry.ts
2953
2920
  var SpatialGeometry = class extends SpatialObject {
@@ -3031,10 +2998,12 @@ var SpatialSession = class {
3031
2998
  * Creates a new static 3D element with an optional model URL.
3032
2999
  * Static 3D elements represent pre-built 3D models that can be loaded from a URL.
3033
3000
  * @param modelURL Optional URL to the 3D model to load
3001
+ * @param sources Optional list of fallback model sources
3002
+ * @param loading Whether the asset should fetch eagerly or be deferred (`'lazy'`)
3034
3003
  * @returns Promise resolving to a new SpatializedStatic3DElement instance
3035
3004
  */
3036
- createSpatializedStatic3DElement(modelURL, sources) {
3037
- return createSpatializedStatic3DElement(modelURL, sources);
3005
+ createSpatializedStatic3DElement(modelURL, sources, loading = "eager") {
3006
+ return createSpatializedStatic3DElement(modelURL, sources, loading);
3038
3007
  }
3039
3008
  /**
3040
3009
  * Initializes the spatial scene with custom configuration.
@@ -3116,6 +3085,15 @@ var SpatialSession = class {
3116
3085
  createUnlitMaterial(options) {
3117
3086
  return createSpatialUnlitMaterial(options);
3118
3087
  }
3088
+ /**
3089
+ * Creates a texture resource from the specified image URL.
3090
+ * Texture resources can be referenced by materials and other spatial content.
3091
+ * @param options Configuration options for the texture resource
3092
+ * @returns Promise resolving to a new SpatialTextureResource instance
3093
+ */
3094
+ createTexture(options) {
3095
+ return createSpatialTexture(options);
3096
+ }
3119
3097
  /**
3120
3098
  * Creates a model asset with the specified configuration.
3121
3099
  * Model assets represent 3D model resources that can be used by entities.
@@ -3146,9 +3124,7 @@ var SpatialSession = class {
3146
3124
  };
3147
3125
 
3148
3126
  // src/Spatial.ts
3149
- init_SpatialWebEvent();
3150
3127
  var Spatial = class {
3151
- wsAppShellVersionFromUA;
3152
3128
  /**
3153
3129
  * Requests a spatial session object from the browser.
3154
3130
  * This is the primary method to initialize spatial functionality.
@@ -3174,20 +3150,6 @@ var Spatial = class {
3174
3150
  }
3175
3151
  return false;
3176
3152
  }
3177
- getShellVersionFromUA() {
3178
- if (this.wsAppShellVersionFromUA !== void 0) {
3179
- return this.wsAppShellVersionFromUA;
3180
- }
3181
- if (typeof navigator === "undefined" || typeof navigator.userAgent !== "string") {
3182
- this.wsAppShellVersionFromUA = null;
3183
- return null;
3184
- }
3185
- const match = navigator.userAgent.match(
3186
- /WSAppShell\/(\d+(?:\.\d+){2}(?:[-+][0-9A-Za-z.-]+)*)/
3187
- );
3188
- this.wsAppShellVersionFromUA = match ? match[1] : "1.3.0";
3189
- return this.wsAppShellVersionFromUA;
3190
- }
3191
3153
  /** @deprecated
3192
3154
  * Checks if WebSpatial is supported in the current environment.
3193
3155
  * Verifies compatibility between native and client versions.
@@ -3213,15 +3175,289 @@ var Spatial = class {
3213
3175
  * @returns Client SDK version string in format "x.x.x"
3214
3176
  */
3215
3177
  getClientVersion() {
3216
- return "1.6.1";
3178
+ return "1.7.0";
3217
3179
  }
3218
3180
  };
3219
3181
 
3220
- // src/index.ts
3221
- init_ssr_polyfill();
3182
+ // src/runtime/WebSpatialRuntimeError.ts
3183
+ var WebSpatialRuntimeError = class extends Error {
3184
+ capability;
3185
+ constructor(capability, message) {
3186
+ super(
3187
+ message ?? `Capability "${capability}" is not supported in this WebSpatial runtime`
3188
+ );
3189
+ this.name = "WebSpatialRuntimeError";
3190
+ this.capability = capability;
3191
+ }
3192
+ };
3193
+
3194
+ // src/runtime/keys.ts
3195
+ var COMPONENT_KEYS = [
3196
+ "Model",
3197
+ "Reality",
3198
+ "Entity",
3199
+ "BoxEntity",
3200
+ "SphereEntity",
3201
+ "ConeEntity",
3202
+ "CylinderEntity",
3203
+ "PlaneEntity",
3204
+ "SceneGraph",
3205
+ "ModelAsset",
3206
+ "ModelEntity",
3207
+ "UnlitMaterial",
3208
+ "Material",
3209
+ "AttachmentAsset",
3210
+ "AttachmentEntity"
3211
+ ];
3212
+ var CSS_KEYS = [
3213
+ "-xr-background-material",
3214
+ "-xr-back",
3215
+ "-xr-depth",
3216
+ "-xr-transform"
3217
+ ];
3218
+ var GESTURE_KEYS = [
3219
+ "SpatialTapEvent",
3220
+ "SpatialDragStartEvent",
3221
+ "SpatialDragEvent",
3222
+ "SpatialDragEndEvent",
3223
+ "SpatialRotateEvent",
3224
+ "SpatialRotateEndEvent",
3225
+ "SpatialMagnifyEvent",
3226
+ "SpatialMagnifyEndEvent"
3227
+ ];
3228
+ var JS_SCENE_KEYS = [
3229
+ "useMetrics",
3230
+ "convertCoordinate",
3231
+ "initScene",
3232
+ "WindowScene",
3233
+ "VolumeScene"
3234
+ ];
3235
+ var ELEMENT_DOM_DEPTH_KEYS = ["xrClientDepth", "xrOffsetBack"];
3236
+ var WINDOW_DOM_DEPTH_KEYS = ["xrInnerDepth", "xrOuterDepth"];
3237
+ var DOM_DEPTH_KEYS = [
3238
+ ...ELEMENT_DOM_DEPTH_KEYS,
3239
+ ...WINDOW_DOM_DEPTH_KEYS
3240
+ ];
3241
+ var TOP_LEVEL_KEYS = [
3242
+ ...COMPONENT_KEYS,
3243
+ ...CSS_KEYS,
3244
+ ...GESTURE_KEYS,
3245
+ ...JS_SCENE_KEYS,
3246
+ ...DOM_DEPTH_KEYS
3247
+ ];
3248
+ var ALIAS_TO_CANONICAL = {
3249
+ Box: "BoxEntity",
3250
+ Sphere: "SphereEntity",
3251
+ Cone: "ConeEntity",
3252
+ Cylinder: "CylinderEntity",
3253
+ Plane: "PlaneEntity",
3254
+ World: "SceneGraph"
3255
+ };
3256
+ function normalizeCapabilityName(name) {
3257
+ return ALIAS_TO_CANONICAL[name] ?? name;
3258
+ }
3259
+ var SUB_TOKENS_BY_NAME = {
3260
+ Material: ["unlit"],
3261
+ WindowScene: ["defaultSize", "resizability"],
3262
+ VolumeScene: [
3263
+ "defaultSize",
3264
+ "resizability",
3265
+ "worldScaling",
3266
+ "worldAlignment",
3267
+ "baseplateVisibility"
3268
+ ],
3269
+ SpatialRotateEvent: ["constrainedToAxis"],
3270
+ Model: [
3271
+ "autoplay",
3272
+ "loop",
3273
+ "stagemode",
3274
+ "poster",
3275
+ "loading",
3276
+ "source",
3277
+ "ready",
3278
+ "currentSrc",
3279
+ "entityTransform",
3280
+ "paused",
3281
+ "duration",
3282
+ "playbackRate",
3283
+ "play",
3284
+ "pause",
3285
+ "currentTime"
3286
+ ]
3287
+ };
3288
+ function isKnownTopLevel(name) {
3289
+ return TOP_LEVEL_KEYS.includes(name);
3290
+ }
3291
+ function isKnownSubToken(name, token) {
3292
+ const allowed = SUB_TOKENS_BY_NAME[name];
3293
+ return allowed !== void 0 && allowed.includes(token);
3294
+ }
3295
+
3296
+ // src/runtime/capability-data.ts
3297
+ function baseTrueFlags() {
3298
+ const flags = {};
3299
+ for (const k of TOP_LEVEL_KEYS) {
3300
+ flags[k] = true;
3301
+ }
3302
+ for (const [name, toks] of Object.entries(SUB_TOKENS_BY_NAME)) {
3303
+ for (const t of toks) {
3304
+ flags[`${name}:${t}`] = true;
3305
+ }
3306
+ }
3307
+ return flags;
3308
+ }
3309
+ function matrixVision_1_5_0_Flags() {
3310
+ const flags = baseTrueFlags();
3311
+ const modelNo = [
3312
+ "autoplay",
3313
+ "loop",
3314
+ "stagemode",
3315
+ "poster",
3316
+ "loading",
3317
+ "source",
3318
+ "paused",
3319
+ "duration",
3320
+ "playbackRate",
3321
+ "play",
3322
+ "pause",
3323
+ "currentTime"
3324
+ ];
3325
+ for (const t of modelNo) {
3326
+ flags[`Model:${t}`] = false;
3327
+ }
3328
+ flags["SpatialRotateEvent:constrainedToAxis"] = true;
3329
+ return flags;
3330
+ }
3331
+ function matrixVision_1_6_0_Flags() {
3332
+ const flags = baseTrueFlags();
3333
+ for (const t of ["stagemode", "poster", "loading", "currentTime"]) {
3334
+ flags[`Model:${t}`] = false;
3335
+ }
3336
+ flags["SpatialRotateEvent:constrainedToAxis"] = true;
3337
+ return flags;
3338
+ }
3339
+ function matrixPico_0_1_1_Flags() {
3340
+ const flags = matrixVision_1_5_0_Flags();
3341
+ flags.xrInnerDepth = false;
3342
+ flags.xrOuterDepth = false;
3343
+ return flags;
3344
+ }
3345
+ function matrixPico_0_1_2_Flags() {
3346
+ const flags = matrixVision_1_6_0_Flags();
3347
+ flags.xrInnerDepth = false;
3348
+ flags.xrOuterDepth = false;
3349
+ return flags;
3350
+ }
3351
+ function visionOsRow_1_5_0() {
3352
+ return { version: "1.5.0", flags: matrixVision_1_5_0_Flags() };
3353
+ }
3354
+ function visionOsRow_1_6_0() {
3355
+ return { version: "1.6.0", flags: matrixVision_1_6_0_Flags() };
3356
+ }
3357
+ function picoOsRow_0_1_1() {
3358
+ return { version: "0.1.1", flags: matrixPico_0_1_1_Flags() };
3359
+ }
3360
+ function picoOsRow_0_1_2() {
3361
+ return { version: "0.1.2", flags: matrixPico_0_1_2_Flags() };
3362
+ }
3363
+ var CAPABILITY_TABLE = {
3364
+ visionos: [visionOsRow_1_5_0(), visionOsRow_1_6_0()],
3365
+ picoos: [picoOsRow_0_1_1(), picoOsRow_0_1_2()]
3366
+ };
3367
+
3368
+ // src/runtime/semver.ts
3369
+ function compareSemver(a, b) {
3370
+ const pa = parseSemverParts(a);
3371
+ const pb = parseSemverParts(b);
3372
+ if (!pa || !pb) {
3373
+ return String(a).localeCompare(String(b));
3374
+ }
3375
+ const len = Math.max(pa.length, pb.length);
3376
+ for (let i = 0; i < len; i++) {
3377
+ const da = pa[i] ?? 0;
3378
+ const db = pb[i] ?? 0;
3379
+ if (da !== db) return da - db;
3380
+ }
3381
+ return 0;
3382
+ }
3383
+ function parseSemverParts(v) {
3384
+ const m = /^(\d+)(?:\.(\d+)(?:\.(\d+))?)?/.exec(v.trim());
3385
+ if (!m) return null;
3386
+ const major = Number(m[1]);
3387
+ const minor = m[2] !== void 0 ? Number(m[2]) : 0;
3388
+ const patch = m[3] !== void 0 ? Number(m[3]) : 0;
3389
+ if ([major, minor, patch].some((n) => Number.isNaN(n))) return null;
3390
+ return [major, minor, patch];
3391
+ }
3392
+ function parseSemverOrNull(v) {
3393
+ const m = /^(\d+(?:\.\d+){0,2})/.exec(v.trim());
3394
+ return m ? m[1] : null;
3395
+ }
3396
+
3397
+ // src/runtime/supports.ts
3398
+ var VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER = "WS_SHELL_VERSION";
3399
+ var runtimeCache;
3400
+ function resetRuntimeCacheForTests() {
3401
+ runtimeCache = void 0;
3402
+ }
3403
+ function getRuntime() {
3404
+ if (runtimeCache !== void 0) return runtimeCache;
3405
+ if (typeof navigator === "undefined") {
3406
+ runtimeCache = { type: null, shellVersion: null };
3407
+ return runtimeCache;
3408
+ }
3409
+ runtimeCache = computeRuntimeFromUserAgent(navigator.userAgent);
3410
+ return runtimeCache;
3411
+ }
3412
+ function selectRow(type, shellVersion) {
3413
+ const norm = parseSemverOrNull(shellVersion);
3414
+ if (!norm) return null;
3415
+ const rows = CAPABILITY_TABLE[type];
3416
+ if (!rows.length) return null;
3417
+ const sorted = [...rows].sort((a, b) => compareSemver(a.version, b.version));
3418
+ const minV = sorted[0].version;
3419
+ if (compareSemver(norm, minV) < 0) return null;
3420
+ let chosen = null;
3421
+ for (const row of sorted) {
3422
+ if (compareSemver(row.version, norm) <= 0) {
3423
+ chosen = row;
3424
+ } else {
3425
+ break;
3426
+ }
3427
+ }
3428
+ return chosen;
3429
+ }
3430
+ function supports(name, tokens) {
3431
+ if (typeof name !== "string") return false;
3432
+ const canonical = normalizeCapabilityName(name);
3433
+ if (!isKnownTopLevel(canonical)) return false;
3434
+ const tokList = tokens === void 0 ? [] : Array.isArray(tokens) ? [...tokens] : [];
3435
+ if (tokList.some((t) => typeof t !== "string")) return false;
3436
+ for (const t of tokList) {
3437
+ if (!isKnownSubToken(canonical, t)) return false;
3438
+ }
3439
+ const rt = getRuntime();
3440
+ if (rt.type === "puppeteer") {
3441
+ return true;
3442
+ }
3443
+ if (rt.type === null) return false;
3444
+ if (rt.shellVersion === null) return false;
3445
+ if (rt.type === "visionos" && rt.shellVersion === VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER) {
3446
+ return true;
3447
+ }
3448
+ const parsedShell = parseSemverOrNull(rt.shellVersion);
3449
+ if (!parsedShell) return false;
3450
+ if (rt.type !== "visionos" && rt.type !== "picoos") return false;
3451
+ const row = selectRow(rt.type, parsedShell);
3452
+ if (!row) return false;
3453
+ if (tokList.length === 0) {
3454
+ return row.flags[canonical] === true;
3455
+ }
3456
+ if (row.flags[canonical] !== true) return false;
3457
+ return tokList.every((t) => row.flags[`${canonical}:${t}`] === true);
3458
+ }
3222
3459
 
3223
3460
  // src/spatial-window-polyfill.ts
3224
- init_utils();
3225
3461
  var spatial = new Spatial();
3226
3462
  var session = void 0;
3227
3463
  var SpatialGlobalCustomVars = {
@@ -3366,9 +3602,17 @@ if (!isSSREnv() && navigator.userAgent.indexOf("WebSpatial/") > 0) {
3366
3602
  export {
3367
3603
  Attachment,
3368
3604
  BaseplateVisibilityValues,
3605
+ CAPABILITY_TABLE,
3606
+ COMPONENT_KEYS,
3607
+ CSS_KEYS,
3369
3608
  CubeInfo,
3609
+ DOM_DEPTH_KEYS,
3610
+ ELEMENT_DOM_DEPTH_KEYS,
3611
+ GESTURE_KEYS,
3612
+ JS_SCENE_KEYS,
3370
3613
  ModelComponent,
3371
3614
  physicalMetrics_exports as PhysicalMetrics,
3615
+ SUB_TOKENS_BY_NAME,
3372
3616
  Spatial,
3373
3617
  SpatialBoxGeometry,
3374
3618
  SpatialComponent,
@@ -3386,20 +3630,33 @@ export {
3386
3630
  SpatialSceneValues,
3387
3631
  SpatialSession,
3388
3632
  SpatialSphereGeometry,
3633
+ SpatialTextureResource,
3389
3634
  SpatialUnlitMaterial,
3390
3635
  Spatialized2DElement,
3391
3636
  SpatializedDynamic3DElement,
3392
3637
  SpatializedElement,
3393
3638
  SpatializedElementType,
3394
3639
  SpatializedStatic3DElement,
3640
+ TOP_LEVEL_KEYS,
3641
+ VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER,
3642
+ WINDOW_DOM_DEPTH_KEYS,
3643
+ WebSpatialRuntimeError,
3395
3644
  WorldAlignmentValues,
3396
3645
  WorldScalingValues,
3646
+ compareSemver,
3647
+ computeRuntimeFromUserAgent,
3397
3648
  createAttachmentEntity,
3649
+ getRuntime,
3398
3650
  isSSREnv,
3399
3651
  isValidBaseplateVisibilityType,
3400
3652
  isValidSceneUnit,
3401
3653
  isValidSpatialSceneType,
3402
3654
  isValidWorldAlignmentType,
3403
- isValidWorldScalingType
3655
+ isValidWorldScalingType,
3656
+ parseSemverOrNull,
3657
+ parseShellToken,
3658
+ resetRuntimeCacheForTests,
3659
+ resolveJsbAdapterPlatform,
3660
+ supports
3404
3661
  };
3405
3662
  //# sourceMappingURL=index.js.map