@webspatial/core-sdk 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -402,10 +402,12 @@ declare class CubeInfo$1 {
402
402
  }
403
403
  interface SpatialTapEventDetail {
404
404
  location3D: Point3D;
405
+ globalLocation3D?: Point3D;
405
406
  }
406
407
  type SpatialTapEvent = CustomEvent<SpatialTapEventDetail>;
407
408
  interface SpatialDragStartEventDetail {
408
409
  startLocation3D: Point3D;
410
+ globalLocation3D?: Point3D;
409
411
  }
410
412
  interface SpatialDragEventDetail {
411
413
  translation3D: Vec3;
@@ -430,6 +432,21 @@ interface SpatialMagnifyEndEventDetail {
430
432
  type SpatialMagnifyEvent = CustomEvent<SpatialMagnifyEventDetail>;
431
433
  type SpatialMagnifyEndEvent = CustomEvent<SpatialMagnifyEndEventDetail>;
432
434
  type SpatialEntityOrReality = SpatialEntity | SpatializedDynamic3DElement;
435
+ interface AttachmentEntityOptions {
436
+ parentEntityId: string;
437
+ position?: [number, number, number];
438
+ size: {
439
+ width: number;
440
+ height: number;
441
+ };
442
+ }
443
+ interface AttachmentEntityUpdateOptions {
444
+ position?: [number, number, number];
445
+ size?: {
446
+ width: number;
447
+ height: number;
448
+ };
449
+ }
433
450
 
434
451
  declare class SpatialComponent extends SpatialObject {
435
452
  constructor(id: string);
@@ -523,6 +540,16 @@ declare class SpatialModelAsset extends SpatialObject {
523
540
  constructor(id: string, options: ModelAssetOptions);
524
541
  }
525
542
 
543
+ declare class Attachment extends SpatialObject {
544
+ private readonly windowProxy;
545
+ private options;
546
+ constructor(id: string, windowProxy: WindowProxy, options: AttachmentEntityOptions);
547
+ getContainer(): HTMLElement;
548
+ getWindowProxy(): WindowProxy;
549
+ update(options: AttachmentEntityUpdateOptions): Promise<CommandResult | undefined>;
550
+ }
551
+ declare function createAttachmentEntity(options: AttachmentEntityOptions): Promise<Attachment>;
552
+
526
553
  declare function initScene(name: string, callback: (pre: SpatialSceneCreationOptions$1) => SpatialSceneCreationOptions$1, options?: {
527
554
  type: SpatialSceneType$1;
528
555
  }): void;
@@ -614,6 +641,13 @@ declare class Spatialized2DElement extends SpatializedElement {
614
641
  * and provides events for load success and failure.
615
642
  */
616
643
  declare class SpatializedStatic3DElement extends SpatializedElement {
644
+ /**
645
+ * Creates a new spatialized static 3D element with the specified ID and URL.
646
+ * Registers the element to receive spatial events.
647
+ * @param id Unique identifier for this element
648
+ * @param modelURL URL of the 3D model
649
+ */
650
+ constructor(id: string, modelURL: string);
617
651
  /**
618
652
  * Promise resolver for the ready state.
619
653
  * Used to resolve the ready promise when the model is loaded.
@@ -694,7 +728,7 @@ declare class SpatialSession {
694
728
  * @param modelURL Optional URL to the 3D model to load
695
729
  * @returns Promise resolving to a new SpatializedStatic3DElement instance
696
730
  */
697
- createSpatializedStatic3DElement(modelURL?: string): Promise<SpatializedStatic3DElement>;
731
+ createSpatializedStatic3DElement(modelURL: string): Promise<SpatializedStatic3DElement>;
698
732
  /**
699
733
  * Initializes the spatial scene with custom configuration.
700
734
  * This is a reference to the initScene function from scene-polyfill.
@@ -771,6 +805,13 @@ declare class SpatialSession {
771
805
  * @returns Promise resolving to a new SpatialModelEntity instance
772
806
  */
773
807
  createSpatialModelEntity(options: SpatialModelEntityCreationOptions, userData?: SpatialEntityUserData): Promise<SpatialModelEntity>;
808
+ /**
809
+ * Creates an attachment entity that renders 2D HTML content as a child
810
+ * of a 3D entity in the scene graph.
811
+ * @param options Configuration options including parent entity ID, position, and size
812
+ * @returns Promise resolving to a new Attachment instance
813
+ */
814
+ createAttachmentEntity(options: AttachmentEntityOptions): Promise<Attachment>;
774
815
  }
775
816
 
776
817
  /**
@@ -856,4 +897,4 @@ declare global {
856
897
 
857
898
  declare const isSSREnv: () => boolean;
858
899
 
859
- export { type BackgroundMaterialType, type BaseplateVisibilityType, BaseplateVisibilityValues, type CornerRadius, CubeInfo$1 as CubeInfo, type ModelAssetOptions, ModelComponent, type ModelComponentOptions, type Point3D, type Quaternion, type Size, type Size3D, Spatial, SpatialBoxGeometry, type SpatialBoxGeometryOptions, SpatialComponent, SpatialConeGeometry, type SpatialConeGeometryOptions, SpatialCylinderGeometry, type SpatialCylinderGeometryOptions, type SpatialDragEndEvent, type SpatialDragEndEventDetail, type SpatialDragEvent, type SpatialDragEventDetail, type SpatialDragStartEvent, type SpatialDragStartEventDetail, SpatialEntity, type SpatialEntityEventType, type SpatialEntityOrReality, type SpatialEntityProperties, type SpatialEntityUserData, SpatialGeometry, type SpatialGeometryOptions, type SpatialGeometryType, type SpatialMagnifyEndEvent, type SpatialMagnifyEndEventDetail, type SpatialMagnifyEvent, type SpatialMagnifyEventDetail, SpatialMaterial, type SpatialMaterialType, SpatialModelAsset, type SpatialModelDragEvent, SpatialModelEntity, type SpatialModelEntityCreationOptions, SpatialObject, SpatialPlaneGeometry, type SpatialPlaneGeometryOptions, type SpatialRotateEndEvent, type SpatialRotateEndEventDetail, type SpatialRotateEvent, type SpatialRotateEventDetail, SpatialScene, type SpatialSceneCreationOptions$1 as SpatialSceneCreationOptions, type SpatialSceneProperties, SpatialSceneState$1 as SpatialSceneState, type SpatialSceneType$1 as SpatialSceneType, SpatialSceneValues, SpatialSession, SpatialSphereGeometry, type SpatialSphereGeometryOptions, type SpatialTapEvent, type SpatialTapEventDetail, SpatialUnlitMaterial, type SpatialUnlitMaterialOptions, Spatialized2DElement, type Spatialized2DElementProperties, SpatializedDynamic3DElement, SpatializedElement, type SpatializedElementProperties, SpatializedElementType, SpatializedStatic3DElement, type SpatializedStatic3DElementProperties, type Vec3, type WorldAlignmentType, WorldAlignmentValues, type WorldScalingType, WorldScalingValues, isSSREnv, isValidBaseplateVisibilityType, isValidSceneUnit, isValidSpatialSceneType, isValidWorldAlignmentType, isValidWorldScalingType };
900
+ export { Attachment, type AttachmentEntityOptions, type AttachmentEntityUpdateOptions, type BackgroundMaterialType, type BaseplateVisibilityType, BaseplateVisibilityValues, type CornerRadius, CubeInfo$1 as CubeInfo, type ModelAssetOptions, ModelComponent, type ModelComponentOptions, type Point3D, type Quaternion, type Size, type Size3D, Spatial, SpatialBoxGeometry, type SpatialBoxGeometryOptions, SpatialComponent, SpatialConeGeometry, type SpatialConeGeometryOptions, SpatialCylinderGeometry, type SpatialCylinderGeometryOptions, type SpatialDragEndEvent, type SpatialDragEndEventDetail, type SpatialDragEvent, type SpatialDragEventDetail, type SpatialDragStartEvent, type SpatialDragStartEventDetail, SpatialEntity, type SpatialEntityEventType, type SpatialEntityOrReality, type SpatialEntityProperties, type SpatialEntityUserData, SpatialGeometry, type SpatialGeometryOptions, type SpatialGeometryType, type SpatialMagnifyEndEvent, type SpatialMagnifyEndEventDetail, type SpatialMagnifyEvent, type SpatialMagnifyEventDetail, SpatialMaterial, type SpatialMaterialType, SpatialModelAsset, type SpatialModelDragEvent, SpatialModelEntity, type SpatialModelEntityCreationOptions, SpatialObject, SpatialPlaneGeometry, type SpatialPlaneGeometryOptions, type SpatialRotateEndEvent, type SpatialRotateEndEventDetail, type SpatialRotateEvent, type SpatialRotateEventDetail, SpatialScene, type SpatialSceneCreationOptions$1 as SpatialSceneCreationOptions, type SpatialSceneProperties, SpatialSceneState$1 as SpatialSceneState, type SpatialSceneType$1 as SpatialSceneType, SpatialSceneValues, SpatialSession, SpatialSphereGeometry, type SpatialSphereGeometryOptions, type SpatialTapEvent, type SpatialTapEventDetail, SpatialUnlitMaterial, type SpatialUnlitMaterialOptions, Spatialized2DElement, type Spatialized2DElementProperties, SpatializedDynamic3DElement, SpatializedElement, type SpatializedElementProperties, SpatializedElementType, SpatializedStatic3DElement, type SpatializedStatic3DElementProperties, type Vec3, type WorldAlignmentType, WorldAlignmentValues, type WorldScalingType, WorldScalingValues, createAttachmentEntity, isSSREnv, isValidBaseplateVisibilityType, isValidSceneUnit, isValidSpatialSceneType, isValidWorldAlignmentType, isValidWorldScalingType };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  (function(){
3
3
  if(typeof window === 'undefined') return;
4
4
  if(!window.__webspatialsdk__) window.__webspatialsdk__ = {}
5
- window.__webspatialsdk__['core-sdk-version'] = "1.2.0"
5
+ window.__webspatialsdk__['core-sdk-version'] = "1.3.0"
6
6
  })()
7
7
 
8
8
  var __defProp = Object.defineProperty;
@@ -93,6 +93,368 @@ var init_CommandResultUtils = __esm({
93
93
  }
94
94
  });
95
95
 
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
+ // 存储iframe实例
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
+ });
136
+ }
137
+ /**
138
+ * 同步创建Spatialized2DElement到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)}`
153
+ );
154
+ }
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
+ );
163
+ return new Promise((resolve) => {
164
+ 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
+ }
174
+ 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")
183
+ );
184
+ }
185
+ });
186
+ }
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
+ );
207
+ }
208
+ }
209
+ /**
210
+ * 创建基于iframe的窗口
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;
224
+ }
225
+ if (featuresObj.height) {
226
+ iframe.style.height = featuresObj.height;
227
+ }
228
+ if (featuresObj.left) {
229
+ iframe.style.left = featuresObj.left;
230
+ iframe.style.position = "absolute";
231
+ }
232
+ if (featuresObj.top) {
233
+ iframe.style.top = featuresObj.top;
234
+ iframe.style.position = "absolute";
235
+ }
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
+ * 创建增强的windowProxy对象
247
+ */
248
+ createEnhancedWindowProxy(iframe, url, spatialId) {
249
+ return {
250
+ // 基本属性
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
+ // 方法
264
+ close: () => {
265
+ console.log(`Closing iframe with spatialId: ${spatialId}`);
266
+ iframe.remove();
267
+ this.iframeRegistry.delete(spatialId);
268
+ },
269
+ // 文档访问
270
+ document: iframe.contentDocument || {},
271
+ contentWindow: iframe.contentWindow || {},
272
+ // 添加消息通信方法
273
+ postMessage: (message, targetOrigin) => {
274
+ if (iframe.contentWindow) {
275
+ iframe.contentWindow.postMessage(message, targetOrigin || "*");
276
+ }
277
+ },
278
+ // 添加事件监听方法
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
+ // 执行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
+ }
303
+ return null;
304
+ },
305
+ // 获取iframe引用
306
+ getIframe: () => iframe,
307
+ // 获取spatialId
308
+ getSpatialId: () => spatialId
309
+ };
310
+ }
311
+ /**
312
+ * 初始化iframe内容
313
+ */
314
+ initializeIframeContent(iframe, url, spatialId) {
315
+ try {
316
+ iframe.onload = () => {
317
+ try {
318
+ const iframeContent = `
319
+ // \u6CE8\u5165\u901A\u4FE1\u811A\u672C
320
+ window.webSpatialId = '${spatialId}';
321
+ window.SpatialId = '${spatialId}';
322
+
323
+ // \u91CD\u5199window.open\u4EE5\u652F\u6301webspatial\u534F\u8BAE
324
+ const originalOpen = window.open;
325
+ window.open = function(url, target, features) {
326
+ if (url && url.startsWith('webspatial://')) {
327
+ // \u901A\u8FC7windowProxy\u5904\u7406webspatial\u534F\u8BAE
328
+ const windowProxy = new Proxy({}, {
329
+ get: function(target, prop) {
330
+ if (prop === 'toString') {
331
+ return function() { return url; };
332
+ }
333
+ return undefined;
334
+ }
335
+ });
336
+ return windowProxy;
337
+ }
338
+ return originalOpen.call(window, url, target, features);
339
+ };
340
+
341
+ // \u8BBE\u7F6Enavigator.userAgent\u4EE5\u8BC6\u522Bwebspatial\u73AF\u5883
342
+ Object.defineProperty(navigator, 'userAgent', {
343
+ value: 'WebSpatial/1.0 ' + navigator.userAgent,
344
+ configurable: true
345
+ });
346
+
347
+ // \u53D1\u9001\u52A0\u8F7D\u5B8C\u6210\u6D88\u606F
348
+ window.parent.postMessage({
349
+ type: 'iframe_loaded',
350
+ spatialId: '${spatialId}',
351
+ url: '${url}'
352
+ }, '${window.location.origin}');
353
+
354
+ // \u8BBE\u7F6E\u6D88\u606F\u5904\u7406\u5668
355
+ window.addEventListener('message', (event) => {
356
+ if (event.origin !== window.parent.location.origin) return;
357
+
358
+ const data = event.data;
359
+ if (data && data.type === 'webspatial_command') {
360
+ // \u5904\u7406\u6765\u81EA\u7236\u7A97\u53E3\u7684\u547D\u4EE4
361
+ console.log('Received command in iframe from parent:', data.command);
362
+ // \u8FD9\u91CC\u53EF\u4EE5\u6DFB\u52A0\u547D\u4EE4\u5904\u7406\u903B\u8F91
363
+ }
364
+ });
365
+ `;
366
+ const doc = iframe.contentDocument;
367
+ if (doc) {
368
+ doc.open();
369
+ doc.write(`
370
+ <!DOCTYPE html>
371
+ <html>
372
+ <head>
373
+ <title>Spatial Iframe - ${spatialId}</title>
374
+ <meta charset="UTF-8">
375
+ <style>
376
+ body {
377
+ margin: 0;
378
+ padding: 0;
379
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
380
+ }
381
+ </style>
382
+ </head>
383
+ <body>
384
+ <script>${iframeContent}</script>
385
+ </body>
386
+ </html>
387
+ `);
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
+ * 解析features字符串为对象
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;
408
+ }
409
+ });
410
+ return result;
411
+ }
412
+ /**
413
+ * 发送消息到指定spatialId的iframe
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;
420
+ }
421
+ return false;
422
+ }
423
+ /**
424
+ * 获取所有活跃的iframe
425
+ */
426
+ getAllActiveIframes() {
427
+ const result = [];
428
+ this.iframeRegistry.forEach((iframe, spatialId) => {
429
+ result.push({ spatialId, iframe });
430
+ });
431
+ return result;
432
+ }
433
+ /**
434
+ * 清理资源
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
+ // 生成UUID函数
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
+ };
455
+ }
456
+ });
457
+
96
458
  // src/SpatialWebEvent.ts
97
459
  var SpatialWebEvent;
98
460
  var init_SpatialWebEvent = __esm({
@@ -401,7 +763,10 @@ function createPlatform() {
401
763
  }
402
764
  const userAgent = window.navigator.userAgent;
403
765
  const webSpatialVersion = getWebSpatialVersion(userAgent);
404
- if (userAgent.includes("PicoWebApp") && isVersionGreater(webSpatialVersion, [0, 0, 1])) {
766
+ if (window.navigator.userAgent.includes("Puppeteer")) {
767
+ const PuppeteerPlatform2 = (init_PuppeteerPlatform(), __toCommonJS(PuppeteerPlatform_exports)).PuppeteerPlatform;
768
+ return new PuppeteerPlatform2();
769
+ } else if (userAgent.includes("PicoWebApp") && isVersionGreater(webSpatialVersion, [0, 0, 1])) {
405
770
  const XRPlatform2 = (init_XRPlatform(), __toCommonJS(XRPlatform_exports)).XRPlatform;
406
771
  return new XRPlatform2();
407
772
  } else if (userAgent.includes("Android") || userAgent.includes("Linux")) {
@@ -469,7 +834,7 @@ var init_utils = __esm({
469
834
  });
470
835
 
471
836
  // src/JSBCommand.ts
472
- 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, SetParentForEntityCommand, ConvertFromEntityToEntityCommand, ConvertFromEntityToSceneCommand, ConvertFromSceneToEntityCommand, InspectCommand, DestroyCommand, CheckWebViewCanCreateCommand, WebSpatialProtocolCommand, createSpatialized2DElementCommand, createSpatialSceneCommand;
837
+ 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, SetParentForEntityCommand, ConvertFromEntityToEntityCommand, ConvertFromEntityToSceneCommand, ConvertFromSceneToEntityCommand, InspectCommand, DestroyCommand, CheckWebViewCanCreateCommand, WebSpatialProtocolCommand, createSpatialized2DElementCommand, createSpatialSceneCommand, CreateAttachmentEntityCommand, UpdateAttachmentEntityCommand;
473
838
  var init_JSBCommand = __esm({
474
839
  "src/JSBCommand.ts"() {
475
840
  "use strict";
@@ -896,6 +1261,34 @@ var init_JSBCommand = __esm({
896
1261
  };
897
1262
  }
898
1263
  };
1264
+ CreateAttachmentEntityCommand = class extends WebSpatialProtocolCommand {
1265
+ constructor(options) {
1266
+ super();
1267
+ this.options = options;
1268
+ }
1269
+ commandType = "createAttachment";
1270
+ getParams() {
1271
+ return {
1272
+ parentEntityId: this.options.parentEntityId,
1273
+ position: this.options.position ?? [0, 0, 0],
1274
+ size: this.options.size
1275
+ };
1276
+ }
1277
+ };
1278
+ UpdateAttachmentEntityCommand = class extends JSBCommand {
1279
+ constructor(attachmentId, options) {
1280
+ super();
1281
+ this.attachmentId = attachmentId;
1282
+ this.options = options;
1283
+ }
1284
+ commandType = "UpdateAttachmentEntity";
1285
+ getParams() {
1286
+ return {
1287
+ id: this.attachmentId,
1288
+ ...this.options
1289
+ };
1290
+ }
1291
+ };
899
1292
  }
900
1293
  });
901
1294
 
@@ -1627,6 +2020,16 @@ var Spatialized2DElement = class extends SpatializedElement {
1627
2020
  // src/SpatializedStatic3DElement.ts
1628
2021
  init_JSBCommand();
1629
2022
  var SpatializedStatic3DElement = class extends SpatializedElement {
2023
+ /**
2024
+ * Creates a new spatialized static 3D element with the specified ID and URL.
2025
+ * Registers the element to receive spatial events.
2026
+ * @param id Unique identifier for this element
2027
+ * @param modelURL URL of the 3D model
2028
+ */
2029
+ constructor(id, modelURL) {
2030
+ super(id);
2031
+ this.modelURL = modelURL;
2032
+ }
1630
2033
  /**
1631
2034
  * Promise resolver for the ready state.
1632
2035
  * Used to resolve the ready promise when the model is loaded.
@@ -1636,7 +2039,7 @@ var SpatializedStatic3DElement = class extends SpatializedElement {
1636
2039
  * Caches the last model URL to detect changes.
1637
2040
  * Used to reset the ready promise when the model URL changes.
1638
2041
  */
1639
- modelURL = "";
2042
+ modelURL;
1640
2043
  /**
1641
2044
  * Creates a new promise for tracking the ready state of the model.
1642
2045
  * @returns Promise that resolves when the model is loaded (true) or fails to load (false)
@@ -1754,7 +2157,7 @@ async function createSpatializedStatic3DElement(modelURL) {
1754
2157
  throw new Error("createSpatializedStatic3DElement failed");
1755
2158
  } else {
1756
2159
  const { id } = result.data;
1757
- return new SpatializedStatic3DElement(id);
2160
+ return new SpatializedStatic3DElement(id, modelURL);
1758
2161
  }
1759
2162
  }
1760
2163
  async function createSpatializedDynamic3DElement() {
@@ -1767,6 +2170,36 @@ async function createSpatializedDynamic3DElement() {
1767
2170
  }
1768
2171
  }
1769
2172
 
2173
+ // src/reality/Attachment.ts
2174
+ init_JSBCommand();
2175
+ var Attachment = class extends SpatialObject {
2176
+ constructor(id, windowProxy, options) {
2177
+ super(id);
2178
+ this.windowProxy = windowProxy;
2179
+ this.options = options;
2180
+ }
2181
+ getContainer() {
2182
+ return this.windowProxy.document.body;
2183
+ }
2184
+ getWindowProxy() {
2185
+ return this.windowProxy;
2186
+ }
2187
+ async update(options) {
2188
+ if (this.isDestroyed) return;
2189
+ if (options.position) this.options.position = options.position;
2190
+ if (options.size) this.options.size = options.size;
2191
+ return new UpdateAttachmentEntityCommand(this.id, options).execute();
2192
+ }
2193
+ };
2194
+ async function createAttachmentEntity(options) {
2195
+ const result = await new CreateAttachmentEntityCommand(options).execute();
2196
+ if (!result.success) {
2197
+ throw new Error("createAttachmentEntity failed: " + result?.errorMessage);
2198
+ }
2199
+ const { id, windowProxy } = result.data;
2200
+ return new Attachment(id, windowProxy, options);
2201
+ }
2202
+
1770
2203
  // src/reality/realityCreator.ts
1771
2204
  init_JSBCommand();
1772
2205
 
@@ -2156,7 +2589,7 @@ var SpatialSession = class {
2156
2589
  * @param modelURL Optional URL to the 3D model to load
2157
2590
  * @returns Promise resolving to a new SpatializedStatic3DElement instance
2158
2591
  */
2159
- createSpatializedStatic3DElement(modelURL = "") {
2592
+ createSpatializedStatic3DElement(modelURL) {
2160
2593
  return createSpatializedStatic3DElement(modelURL);
2161
2594
  }
2162
2595
  /**
@@ -2257,6 +2690,15 @@ var SpatialSession = class {
2257
2690
  createSpatialModelEntity(options, userData) {
2258
2691
  return createSpatialModelEntity(options, userData);
2259
2692
  }
2693
+ /**
2694
+ * Creates an attachment entity that renders 2D HTML content as a child
2695
+ * of a 3D entity in the scene graph.
2696
+ * @param options Configuration options including parent entity ID, position, and size
2697
+ * @returns Promise resolving to a new Attachment instance
2698
+ */
2699
+ createAttachmentEntity(options) {
2700
+ return createAttachmentEntity(options);
2701
+ }
2260
2702
  };
2261
2703
 
2262
2704
  // src/Spatial.ts
@@ -2312,7 +2754,7 @@ var Spatial = class {
2312
2754
  * @returns Client SDK version string in format "x.x.x"
2313
2755
  */
2314
2756
  getClientVersion() {
2315
- return "1.2.0";
2757
+ return "1.3.0";
2316
2758
  }
2317
2759
  };
2318
2760
 
@@ -2463,6 +2905,7 @@ if (!isSSREnv() && navigator.userAgent.indexOf("WebSpatial/") > 0) {
2463
2905
  spatialWindowPolyfill();
2464
2906
  }
2465
2907
  export {
2908
+ Attachment,
2466
2909
  BaseplateVisibilityValues,
2467
2910
  CubeInfo,
2468
2911
  ModelComponent,
@@ -2491,6 +2934,7 @@ export {
2491
2934
  SpatializedStatic3DElement,
2492
2935
  WorldAlignmentValues,
2493
2936
  WorldScalingValues,
2937
+ createAttachmentEntity,
2494
2938
  isSSREnv,
2495
2939
  isValidBaseplateVisibilityType,
2496
2940
  isValidSceneUnit,