@webspatial/core-sdk 1.6.1 → 2.0.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 (320) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +10 -0
  3. package/dist/JSBCommand.d.ts +398 -0
  4. package/dist/JSBCommand.js +668 -0
  5. package/dist/JSBCommand.js.map +1 -0
  6. package/dist/Spatial.d.ts +63 -0
  7. package/dist/Spatial.js +60 -0
  8. package/dist/Spatial.js.map +1 -0
  9. package/dist/SpatialObject.d.ts +19 -0
  10. package/dist/SpatialObject.js +44 -0
  11. package/dist/SpatialObject.js.map +1 -0
  12. package/dist/SpatialScene.d.ts +51 -0
  13. package/dist/SpatialScene.js +74 -0
  14. package/dist/SpatialScene.js.map +1 -0
  15. package/dist/SpatialSession.d.ts +143 -0
  16. package/dist/SpatialSession.js +173 -0
  17. package/dist/SpatialSession.js.map +1 -0
  18. package/dist/SpatialWebEvent.d.ts +8 -0
  19. package/dist/SpatialWebEvent.js +18 -0
  20. package/dist/SpatialWebEvent.js.map +1 -0
  21. package/dist/SpatialWebEventCreator.d.ts +11 -0
  22. package/dist/SpatialWebEventCreator.js +11 -0
  23. package/dist/SpatialWebEventCreator.js.map +1 -0
  24. package/dist/Spatialized2DElement.d.ts +42 -0
  25. package/dist/Spatialized2DElement.js +47 -0
  26. package/dist/Spatialized2DElement.js.map +1 -0
  27. package/dist/SpatializedDynamic3DElement.d.ts +7 -0
  28. package/dist/SpatializedDynamic3DElement.js +43 -0
  29. package/dist/SpatializedDynamic3DElement.js.map +1 -0
  30. package/dist/SpatializedElement.d.ts +7 -0
  31. package/dist/SpatializedElement.js +206 -0
  32. package/dist/SpatializedElement.js.map +1 -0
  33. package/dist/SpatializedElementCreator.d.ts +15 -0
  34. package/dist/SpatializedElementCreator.js +47 -0
  35. package/dist/SpatializedElementCreator.js.map +1 -0
  36. package/dist/SpatializedStatic3DElement.d.ts +195 -0
  37. package/dist/SpatializedStatic3DElement.js +327 -0
  38. package/dist/SpatializedStatic3DElement.js.map +1 -0
  39. package/dist/WebMsgCommand.d.ts +7 -0
  40. package/dist/WebMsgCommand.js +23 -0
  41. package/dist/WebMsgCommand.js.map +1 -0
  42. package/dist/index.d.ts +35 -1101
  43. package/dist/index.js +21 -3393
  44. package/dist/index.js.map +1 -1
  45. package/dist/install-polyfills.d.ts +2 -0
  46. package/dist/install-polyfills.js +13 -0
  47. package/dist/install-polyfills.js.map +1 -0
  48. package/dist/isSSREnv.d.ts +3 -0
  49. package/dist/isSSREnv.js +6 -0
  50. package/dist/isSSREnv.js.map +1 -0
  51. package/dist/motion/AnimationObject.d.ts +7 -0
  52. package/dist/motion/AnimationObject.js +140 -0
  53. package/dist/motion/AnimationObject.js.map +1 -0
  54. package/dist/motion/compute/index.d.ts +10 -0
  55. package/dist/motion/compute/index.js +19 -0
  56. package/dist/motion/compute/index.js.map +1 -0
  57. package/dist/motion/compute/motionPropertyValues.d.ts +19 -0
  58. package/dist/motion/compute/motionPropertyValues.js +50 -0
  59. package/dist/motion/compute/motionPropertyValues.js.map +1 -0
  60. package/dist/motion/compute/normalize.d.ts +31 -0
  61. package/dist/motion/compute/normalize.js +201 -0
  62. package/dist/motion/compute/normalize.js.map +1 -0
  63. package/dist/motion/compute/validate.d.ts +22 -0
  64. package/dist/motion/compute/validate.js +103 -0
  65. package/dist/motion/compute/validate.js.map +1 -0
  66. package/dist/motion/index.d.ts +8 -0
  67. package/dist/motion/index.js +6 -0
  68. package/dist/motion/index.js.map +1 -0
  69. package/dist/motion/native/serializeMotionTimeline.d.ts +12 -0
  70. package/dist/motion/native/serializeMotionTimeline.js +21 -0
  71. package/dist/motion/native/serializeMotionTimeline.js.map +1 -0
  72. package/dist/physicalMetrics-W5uZ5xKb.d.ts +48 -0
  73. package/dist/physicalMetrics.d.ts +1 -0
  74. package/dist/physicalMetrics.js +58 -0
  75. package/dist/physicalMetrics.js.map +1 -0
  76. package/dist/platform-adapter/CommandResultUtils.d.ts +12 -0
  77. package/dist/platform-adapter/CommandResultUtils.js +21 -0
  78. package/dist/platform-adapter/CommandResultUtils.js.map +1 -0
  79. package/dist/platform-adapter/createPlatformSync.d.ts +16 -0
  80. package/dist/platform-adapter/createPlatformSync.js +30 -0
  81. package/dist/platform-adapter/createPlatformSync.js.map +1 -0
  82. package/dist/platform-adapter/index.d.ts +12 -0
  83. package/dist/platform-adapter/index.js +10 -0
  84. package/dist/platform-adapter/index.js.map +1 -0
  85. package/dist/platform-adapter/interface.d.ts +7 -0
  86. package/dist/platform-adapter/interface.js +1 -0
  87. package/dist/platform-adapter/interface.js.map +1 -0
  88. package/dist/platform-adapter/pico-os/PicoOSPlatform.d.ts +25 -0
  89. package/dist/platform-adapter/pico-os/PicoOSPlatform.js +168 -0
  90. package/dist/platform-adapter/pico-os/PicoOSPlatform.js.map +1 -0
  91. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.d.ts +66 -0
  92. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js +372 -0
  93. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js.map +1 -0
  94. package/dist/platform-adapter/spatialRequestMetadata.d.ts +6 -0
  95. package/dist/platform-adapter/spatialRequestMetadata.js +39 -0
  96. package/dist/platform-adapter/spatialRequestMetadata.js.map +1 -0
  97. package/dist/platform-adapter/spatialSceneQuery.d.ts +12 -0
  98. package/dist/platform-adapter/spatialSceneQuery.js +12 -0
  99. package/dist/platform-adapter/spatialSceneQuery.js.map +1 -0
  100. package/dist/platform-adapter/vision-os/VisionOSPlatform.d.ts +19 -0
  101. package/dist/platform-adapter/vision-os/VisionOSPlatform.js +77 -0
  102. package/dist/platform-adapter/vision-os/VisionOSPlatform.js.map +1 -0
  103. package/dist/platform-runtime.d.ts +12 -0
  104. package/dist/platform-runtime.js +14 -0
  105. package/dist/platform-runtime.js.map +1 -0
  106. package/dist/reality/Attachment.d.ts +19 -0
  107. package/dist/reality/Attachment.js +39 -0
  108. package/dist/reality/Attachment.js.map +1 -0
  109. package/dist/reality/component/ModelComponent.d.ts +14 -0
  110. package/dist/reality/component/ModelComponent.js +11 -0
  111. package/dist/reality/component/ModelComponent.js.map +1 -0
  112. package/dist/reality/component/SpatialComponent.d.ts +8 -0
  113. package/dist/reality/component/SpatialComponent.js +19 -0
  114. package/dist/reality/component/SpatialComponent.js.map +1 -0
  115. package/dist/reality/component/index.d.ts +8 -0
  116. package/dist/reality/component/index.js +3 -0
  117. package/dist/reality/component/index.js.map +1 -0
  118. package/dist/reality/entity/SpatialEntity.d.ts +7 -0
  119. package/dist/reality/entity/SpatialEntity.js +291 -0
  120. package/dist/reality/entity/SpatialEntity.js.map +1 -0
  121. package/dist/reality/entity/SpatialModelEntity.d.ts +17 -0
  122. package/dist/reality/entity/SpatialModelEntity.js +17 -0
  123. package/dist/reality/entity/SpatialModelEntity.js.map +1 -0
  124. package/dist/reality/entity/index.d.ts +8 -0
  125. package/dist/reality/entity/index.js +3 -0
  126. package/dist/reality/entity/index.js.map +1 -0
  127. package/dist/reality/geometry/SpatialBoxGeometry.d.ts +16 -0
  128. package/dist/reality/geometry/SpatialBoxGeometry.js +13 -0
  129. package/dist/reality/geometry/SpatialBoxGeometry.js.map +1 -0
  130. package/dist/reality/geometry/SpatialConeGeometry.d.ts +16 -0
  131. package/dist/reality/geometry/SpatialConeGeometry.js +13 -0
  132. package/dist/reality/geometry/SpatialConeGeometry.js.map +1 -0
  133. package/dist/reality/geometry/SpatialCylinderGeometry.d.ts +16 -0
  134. package/dist/reality/geometry/SpatialCylinderGeometry.js +13 -0
  135. package/dist/reality/geometry/SpatialCylinderGeometry.js.map +1 -0
  136. package/dist/reality/geometry/SpatialGeometry.d.ts +7 -0
  137. package/dist/reality/geometry/SpatialGeometry.js +13 -0
  138. package/dist/reality/geometry/SpatialGeometry.js.map +1 -0
  139. package/dist/reality/geometry/SpatialPlaneGeometry.d.ts +16 -0
  140. package/dist/reality/geometry/SpatialPlaneGeometry.js +13 -0
  141. package/dist/reality/geometry/SpatialPlaneGeometry.js.map +1 -0
  142. package/dist/reality/geometry/SpatialSphereGeometry.d.ts +16 -0
  143. package/dist/reality/geometry/SpatialSphereGeometry.js +13 -0
  144. package/dist/reality/geometry/SpatialSphereGeometry.js.map +1 -0
  145. package/dist/reality/geometry/index.d.ts +12 -0
  146. package/dist/reality/geometry/index.js +7 -0
  147. package/dist/reality/geometry/index.js.map +1 -0
  148. package/dist/reality/index.d.ts +18 -0
  149. package/dist/reality/index.js +7 -0
  150. package/dist/reality/index.js.map +1 -0
  151. package/dist/reality/material/SpatialMaterial.d.ts +7 -0
  152. package/dist/reality/material/SpatialMaterial.js +13 -0
  153. package/dist/reality/material/SpatialMaterial.js.map +1 -0
  154. package/dist/reality/material/SpatialUnlitMaterial.d.ts +16 -0
  155. package/dist/reality/material/SpatialUnlitMaterial.js +16 -0
  156. package/dist/reality/material/SpatialUnlitMaterial.js.map +1 -0
  157. package/dist/reality/material/index.d.ts +8 -0
  158. package/dist/reality/material/index.js +3 -0
  159. package/dist/reality/material/index.js.map +1 -0
  160. package/dist/reality/realityCreator.d.ts +22 -0
  161. package/dist/reality/realityCreator.js +89 -0
  162. package/dist/reality/realityCreator.js.map +1 -0
  163. package/dist/reality/resource/SpatialModelAsset.d.ts +15 -0
  164. package/dist/reality/resource/SpatialModelAsset.js +12 -0
  165. package/dist/reality/resource/SpatialModelAsset.js.map +1 -0
  166. package/dist/reality/resource/SpatialTextureResource.d.ts +16 -0
  167. package/dist/reality/resource/SpatialTextureResource.js +16 -0
  168. package/dist/reality/resource/SpatialTextureResource.js.map +1 -0
  169. package/dist/reality/resource/index.d.ts +9 -0
  170. package/dist/reality/resource/index.js +3 -0
  171. package/dist/reality/resource/index.js.map +1 -0
  172. package/dist/runtime/WebSpatialRuntimeError.d.ts +10 -0
  173. package/dist/runtime/WebSpatialRuntimeError.js +14 -0
  174. package/dist/runtime/WebSpatialRuntimeError.js.map +1 -0
  175. package/dist/runtime/capability-data.d.ts +12 -0
  176. package/dist/runtime/capability-data.js +134 -0
  177. package/dist/runtime/capability-data.js.map +1 -0
  178. package/dist/runtime/index.d.ts +8 -0
  179. package/dist/runtime/index.js +27 -0
  180. package/dist/runtime/index.js.map +1 -0
  181. package/dist/runtime/jsbAdapterPlatform.d.ts +9 -0
  182. package/dist/runtime/jsbAdapterPlatform.js +38 -0
  183. package/dist/runtime/jsbAdapterPlatform.js.map +1 -0
  184. package/dist/runtime/keys.d.ts +34 -0
  185. package/dist/runtime/keys.js +122 -0
  186. package/dist/runtime/keys.js.map +1 -0
  187. package/dist/runtime/semver.d.ts +8 -0
  188. package/dist/runtime/semver.js +32 -0
  189. package/dist/runtime/semver.js.map +1 -0
  190. package/dist/runtime/supports.d.ts +22 -0
  191. package/dist/runtime/supports.js +78 -0
  192. package/dist/runtime/supports.js.map +1 -0
  193. package/dist/runtime/types.d.ts +12 -0
  194. package/dist/runtime/types.js +1 -0
  195. package/dist/runtime/types.js.map +1 -0
  196. package/dist/runtime/userAgent.d.ts +20 -0
  197. package/dist/runtime/userAgent.js +41 -0
  198. package/dist/runtime/userAgent.js.map +1 -0
  199. package/dist/scene-polyfill.d.ts +18 -0
  200. package/dist/scene-polyfill.js +480 -0
  201. package/dist/scene-polyfill.js.map +1 -0
  202. package/dist/spatial-host.d.ts +13 -0
  203. package/dist/spatial-host.js +18 -0
  204. package/dist/spatial-host.js.map +1 -0
  205. package/dist/spatial-window-polyfill.d.ts +3 -0
  206. package/dist/spatial-window-polyfill.js +155 -0
  207. package/dist/spatial-window-polyfill.js.map +1 -0
  208. package/dist/spatializedElementMotion-_0XWPQCE.d.ts +1009 -0
  209. package/dist/types/animation.d.ts +7 -0
  210. package/dist/types/animation.js +1 -0
  211. package/dist/types/animation.js.map +1 -0
  212. package/dist/types/global.d.ts +38 -0
  213. package/dist/types/global.js +1 -0
  214. package/dist/types/global.js.map +1 -0
  215. package/dist/types/internal.d.ts +7 -0
  216. package/dist/types/internal.js +12 -0
  217. package/dist/types/internal.js.map +1 -0
  218. package/dist/types/motion/index.d.ts +7 -0
  219. package/dist/types/motion/index.js +3 -0
  220. package/dist/types/motion/index.js.map +1 -0
  221. package/dist/types/motion/spatializedElementMotion.d.ts +7 -0
  222. package/dist/types/motion/spatializedElementMotion.js +1 -0
  223. package/dist/types/motion/spatializedElementMotion.js.map +1 -0
  224. package/dist/types/motion/spatializedMotion.d.ts +7 -0
  225. package/dist/types/motion/spatializedMotion.js +16 -0
  226. package/dist/types/motion/spatializedMotion.js.map +1 -0
  227. package/dist/types/motion/spatializedPlayback.d.ts +11 -0
  228. package/dist/types/motion/spatializedPlayback.js +1 -0
  229. package/dist/types/motion/spatializedPlayback.js.map +1 -0
  230. package/dist/types/motion/spatializedVisual.d.ts +35 -0
  231. package/dist/types/motion/spatializedVisual.js +1 -0
  232. package/dist/types/motion/spatializedVisual.js.map +1 -0
  233. package/dist/types/types.d.ts +7 -0
  234. package/dist/types/types.js +117 -0
  235. package/dist/types/types.js.map +1 -0
  236. package/dist/utils.d.ts +44 -0
  237. package/dist/utils.js +86 -0
  238. package/dist/utils.js.map +1 -0
  239. package/package.json +20 -4
  240. package/src/JSBCommand.ts +148 -91
  241. package/src/Spatial.ts +0 -21
  242. package/src/SpatialObject.ts +10 -0
  243. package/src/SpatialScene.ts +1 -5
  244. package/src/SpatialSession.ts +17 -3
  245. package/src/Spatialized2DElement.ts +5 -0
  246. package/src/SpatializedDynamic3DElement.ts +5 -1
  247. package/src/SpatializedElement.ts +29 -0
  248. package/src/SpatializedElementCreator.ts +6 -4
  249. package/src/SpatializedStatic3DElement.test.ts +99 -0
  250. package/src/SpatializedStatic3DElement.ts +141 -4
  251. package/src/WebMsgCommand.ts +50 -0
  252. package/src/coverage-boost.test.ts +258 -316
  253. package/src/index.ts +28 -12
  254. package/src/install-polyfills.ts +38 -0
  255. package/src/jsbcommand.coverage.test.ts +42 -48
  256. package/src/motion/AnimationObject.test.ts +421 -0
  257. package/src/motion/AnimationObject.ts +208 -0
  258. package/src/motion/compute/index.ts +10 -0
  259. package/src/motion/compute/motionPropertyValues.test.ts +55 -0
  260. package/src/motion/compute/motionPropertyValues.ts +70 -0
  261. package/src/motion/compute/normalize.test.ts +99 -0
  262. package/src/motion/compute/normalize.ts +289 -0
  263. package/src/motion/compute/validate.test.ts +229 -0
  264. package/src/motion/compute/validate.ts +156 -0
  265. package/src/motion/index.ts +2 -0
  266. package/src/motion/native/serializeMotionTimeline.test.ts +61 -0
  267. package/src/motion/native/serializeMotionTimeline.ts +27 -0
  268. package/src/platform-adapter/CommandResultUtils.ts +2 -2
  269. package/src/platform-adapter/createPlatformSync.ts +36 -0
  270. package/src/platform-adapter/index.ts +5 -51
  271. package/src/platform-adapter/interface.ts +35 -23
  272. package/src/platform-adapter/pico-os/PicoOSPlatform.ts +156 -59
  273. package/src/platform-adapter/puppeteer/PuppeteerPlatform.ts +37 -11
  274. package/src/platform-adapter/spatialRequestMetadata.test.ts +175 -0
  275. package/src/platform-adapter/spatialRequestMetadata.ts +48 -0
  276. package/src/platform-adapter/spatialSceneQuery.ts +17 -0
  277. package/src/platform-adapter/vision-os/VisionOSPlatform.ts +60 -24
  278. package/src/platform-runtime.ts +13 -0
  279. package/src/reality/Attachment.ts +2 -2
  280. package/src/reality/entity/SpatialEntity.ts +127 -2
  281. package/src/reality/realityCreator.ts +15 -1
  282. package/src/reality/resource/SpatialTextureResource.ts +16 -0
  283. package/src/reality/resource/index.ts +1 -0
  284. package/src/runtime/WebSpatialRuntimeError.ts +16 -0
  285. package/src/runtime/capability-data.ts +213 -0
  286. package/src/runtime/contract-review.test.ts +44 -0
  287. package/src/runtime/index.ts +17 -0
  288. package/src/runtime/jsbAdapterPlatform.test.ts +36 -0
  289. package/src/runtime/jsbAdapterPlatform.ts +51 -0
  290. package/src/runtime/keys.ts +140 -0
  291. package/src/runtime/semver.ts +33 -0
  292. package/src/runtime/supports.test.ts +346 -0
  293. package/src/runtime/supports.ts +112 -0
  294. package/src/runtime/types.ts +11 -0
  295. package/src/runtime/useAnimation.capability.test.ts +275 -0
  296. package/src/runtime/userAgent.ts +64 -0
  297. package/src/scene-polyfill.manifest.test.ts +312 -9
  298. package/src/scene-polyfill.request-metadata.test.ts +39 -0
  299. package/src/scene-polyfill.test.ts +33 -94
  300. package/src/scene-polyfill.ts +125 -92
  301. package/src/spatial-host.ts +25 -0
  302. package/src/spatial-window-polyfill.ts +18 -2
  303. package/src/transform-roundtrip.test.ts +90 -0
  304. package/src/types/animation.ts +224 -0
  305. package/src/types/{global.d.ts → global.ts} +10 -12
  306. package/src/types/motion/index.ts +10 -0
  307. package/src/types/motion/spatializedElementMotion.ts +49 -0
  308. package/src/types/motion/spatializedMotion.ts +147 -0
  309. package/src/types/motion/spatializedPlayback.ts +17 -0
  310. package/src/types/motion/spatializedVisual.ts +24 -0
  311. package/src/types/types.ts +12 -0
  312. package/src/utils.ts +54 -0
  313. package/tsup.config.ts +61 -36
  314. package/vitest.config.ts +5 -1
  315. package/dist/iife/index.d.ts +0 -1101
  316. package/dist/iife/index.global.js +0 -75
  317. package/dist/iife/index.global.js.map +0 -1
  318. package/src/platform-adapter/android/AndroidPlatform.ts +0 -133
  319. package/src/platform-adapter/ssr/SSRPlatform.ts +0 -43
  320. /package/src/{ssr-polyfill.ts → isSSREnv.ts} +0 -0
package/src/JSBCommand.ts CHANGED
@@ -1,5 +1,10 @@
1
- import { createPlatform } from './platform-adapter'
2
- import { WebSpatialProtocolResult } from './platform-adapter/interface'
1
+ import { getPlatform } from './platform-runtime'
2
+ import { pointToPhysical } from './physicalMetrics'
3
+ import {
4
+ getRuntime,
5
+ supports,
6
+ VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER,
7
+ } from './runtime/supports'
3
8
  import { SpatialComponent } from './reality/component/SpatialComponent'
4
9
  import { SpatialEntity } from './reality/entity/SpatialEntity'
5
10
  import { SpatialMaterial } from './reality/material/SpatialMaterial'
@@ -24,12 +29,16 @@ import {
24
29
  Vec3,
25
30
  AttachmentEntityOptions,
26
31
  AttachmentEntityUpdateOptions,
32
+ ModelLoadingMode,
27
33
  ModelSource,
34
+ SpatialTextureResourceOptions,
28
35
  } from './types/types'
29
- import { SpatialSceneCreationOptionsInternal } from './types/internal'
36
+ import type { AnimateTransformCommand } from './types/animation'
30
37
  import { composeSRT } from './utils'
31
-
32
- const platform = createPlatform()
38
+ import type {
39
+ ControlSpatializedElementAnimationCommand,
40
+ CreateSpatializedElementAnimationCommand,
41
+ } from './types/motion/spatializedElementMotion'
33
42
 
34
43
  abstract class JSBCommand {
35
44
  commandType: string = ''
@@ -38,6 +47,7 @@ abstract class JSBCommand {
38
47
  async execute() {
39
48
  const param = this.getParams()
40
49
  const msg = param ? JSON.stringify(param) : ''
50
+ const platform = await getPlatform()
41
51
  return platform.callJSB(this.commandType, msg)
42
52
  }
43
53
  }
@@ -293,14 +303,20 @@ export class CreateSpatializedStatic3DElementCommand extends JSBCommand {
293
303
  constructor(
294
304
  readonly modelURL?: string,
295
305
  readonly sources?: ModelSource[],
306
+ readonly loading: ModelLoadingMode = 'eager',
296
307
  ) {
297
308
  super()
298
309
  this.modelURL = modelURL
299
310
  this.sources = sources
311
+ this.loading = loading
300
312
  }
301
313
 
302
314
  protected getParams() {
303
- return { modelURL: this.modelURL, sources: this.sources }
315
+ return {
316
+ modelURL: this.modelURL,
317
+ sources: this.sources,
318
+ loading: this.loading,
319
+ }
304
320
  }
305
321
  }
306
322
 
@@ -558,7 +574,7 @@ export class ConvertCoordinateCommand extends JSBCommand {
558
574
  commandType = 'ConvertCoordinate'
559
575
  }
560
576
 
561
- export class CreateTextureResourceCommand extends JSBCommand {
577
+ export class CreateTextureCommand extends JSBCommand {
562
578
  constructor(private url: string) {
563
579
  super()
564
580
  }
@@ -567,7 +583,24 @@ export class CreateTextureResourceCommand extends JSBCommand {
567
583
  url: this.url,
568
584
  }
569
585
  }
570
- commandType = 'CreateTextureResource'
586
+ commandType = 'CreateTexture'
587
+ }
588
+
589
+ export class UpdateTexturePropertiesCommand extends SpatializedElementCommand {
590
+ properties: Partial<SpatialTextureResourceOptions>
591
+ commandType = 'UpdateTextureProperties'
592
+
593
+ constructor(
594
+ spatialObject: SpatialObject,
595
+ properties: Partial<SpatialTextureResourceOptions>,
596
+ ) {
597
+ super(spatialObject)
598
+ this.properties = properties
599
+ }
600
+
601
+ protected getExtraParams() {
602
+ return this.properties
603
+ }
571
604
  }
572
605
 
573
606
  export class InspectCommand extends JSBCommand {
@@ -606,86 +639,62 @@ export class CheckWebViewCanCreateCommand extends JSBCommand {
606
639
  }
607
640
  }
608
641
 
609
- /* WebSpatial Protocol Begin */
610
- abstract class WebSpatialProtocolCommand extends JSBCommand {
611
- target?: string
612
- features?: string
613
-
614
- async execute(): Promise<WebSpatialProtocolResult> {
615
- const query = this.getQuery()
616
- return platform.callWebSpatialProtocol(
617
- this.commandType,
618
- query,
619
- this.target,
620
- this.features,
621
- )
622
- }
623
-
624
- executeSync(): WebSpatialProtocolResult {
625
- const query = this.getQuery()
626
- return platform.callWebSpatialProtocolSync(
627
- this.commandType,
628
- query,
629
- this.target,
630
- this.features,
631
- )
632
- }
633
-
634
- private getQuery() {
635
- let query = undefined
636
- const params = this.getParams()
637
- if (params) {
638
- query = Object.keys(params)
639
- .map(key => {
640
- const value = params[key]
641
- const finalValue =
642
- typeof value === 'object' ? JSON.stringify(value) : value
643
- return `${key}=${encodeURIComponent(finalValue)}`
644
- })
645
- .join('&')
646
- }
647
-
648
- return query
649
- }
650
- }
642
+ export class AnimateTransformJSBCommand extends JSBCommand {
643
+ commandType = 'AnimateTransform'
651
644
 
652
- export class createSpatialized2DElementCommand extends WebSpatialProtocolCommand {
653
- commandType = 'createSpatialized2DElement'
654
- constructor() {
645
+ constructor(private command: AnimateTransformCommand) {
655
646
  super()
656
647
  }
657
- protected getParams() {
658
- return {}
659
- }
660
- }
661
648
 
662
- export class createSpatialSceneCommand extends WebSpatialProtocolCommand {
663
- commandType = 'createSpatialScene'
649
+ protected getParams(): Record<string, any> | undefined {
650
+ const { type, animationId, entityId } = this.command
651
+ const params: Record<string, any> = { type, animationId }
652
+
653
+ if (entityId !== undefined) params.entityId = entityId
654
+
655
+ if (type === 'play') {
656
+ if (this.command.toTransform) {
657
+ params.toTransform = Array.from(this.command.toTransform)
658
+ }
659
+ if (this.command.fromTransform) {
660
+ params.fromTransform = Array.from(this.command.fromTransform)
661
+ }
662
+ if (this.command.duration !== undefined)
663
+ params.duration = this.command.duration
664
+ if (this.command.timingFunction !== undefined)
665
+ params.timingFunction = this.command.timingFunction
666
+ if (this.command.delay !== undefined) params.delay = this.command.delay
667
+ if (this.command.loop !== undefined) params.loop = this.command.loop
668
+ if (this.command.playbackRate !== undefined)
669
+ params.playbackRate = this.command.playbackRate
670
+ }
664
671
 
665
- constructor(
666
- private url: string,
667
- private config: SpatialSceneCreationOptionsInternal | undefined,
668
- public target?: string,
669
- public features?: string,
670
- ) {
671
- super()
672
+ return params
672
673
  }
673
- protected getParams() {
674
- return {
675
- url: this.url,
676
- config: this.config,
677
- }
674
+ }
675
+ // TODO(remove): temporary OTA0 compat shim — delete once #1330 lands and
676
+ // attachment JSB always uses the placement-shaped payload.
677
+ function usePlacementProtocol(): boolean {
678
+ // WS_SHELL_VERSION debug shells claim every capability via supports(), but
679
+ // the in-repo visionOS runtime still decodes only the legacy attachment
680
+ // payload — keep sending it there.
681
+ const rt = getRuntime()
682
+ if (
683
+ rt.type === 'visionos' &&
684
+ rt.shellVersion === VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER
685
+ ) {
686
+ return false
678
687
  }
688
+ return supports('AttachmentEntity', ['placement'])
679
689
  }
680
690
 
681
- export class CreateAttachmentEntityCommand extends WebSpatialProtocolCommand {
682
- commandType = 'createAttachment'
683
- constructor(private options: AttachmentEntityOptions) {
684
- super()
685
- }
686
- protected getParams() {
687
- return {} // No metadata — just trigger engine/webview creation
688
- }
691
+ function toPlacementVec3(position?: [number, number, number]): {
692
+ x: number
693
+ y: number
694
+ z: number
695
+ } {
696
+ const [x, y, z] = position ?? [0, 0, 0]
697
+ return { x, y, z }
689
698
  }
690
699
 
691
700
  export class InitializeAttachmentCommand extends JSBCommand {
@@ -697,12 +706,25 @@ export class InitializeAttachmentCommand extends JSBCommand {
697
706
  super()
698
707
  }
699
708
  protected getParams() {
709
+ const p = this.options
710
+ if (!usePlacementProtocol()) {
711
+ return {
712
+ id: this.attachmentId,
713
+ parentEntityId: p.parentEntityId,
714
+ position: p.position ?? [0, 0, 0],
715
+ size: p.size,
716
+ ownerViewId: p.ownerViewId,
717
+ }
718
+ }
719
+ // Runtimes advertising this capability decode a Vec3 position and meter
720
+ // dimensions instead of the legacy tuple and point size.
700
721
  return {
701
722
  id: this.attachmentId,
702
- parentEntityId: this.options.parentEntityId,
703
- position: this.options.position ?? [0, 0, 0],
704
- size: this.options.size,
705
- ownerViewId: this.options.ownerViewId,
723
+ placementId: p.parentEntityId,
724
+ position: toPlacementVec3(p.position),
725
+ width: pointToPhysical(p.size.width),
726
+ height: pointToPhysical(p.size.height),
727
+ ownerViewId: p.ownerViewId,
706
728
  }
707
729
  }
708
730
  }
@@ -716,19 +738,54 @@ export class UpdateAttachmentEntityCommand extends JSBCommand {
716
738
  super()
717
739
  }
718
740
  protected getParams() {
741
+ if (!usePlacementProtocol()) {
742
+ return {
743
+ id: this.attachmentId,
744
+ ...this.options,
745
+ }
746
+ }
747
+ const { position, size } = this.options
719
748
  return {
720
749
  id: this.attachmentId,
721
- ...this.options,
750
+ ...(position ? { position: toPlacementVec3(position) } : {}),
751
+ ...(size
752
+ ? {
753
+ width: pointToPhysical(size.width),
754
+ height: pointToPhysical(size.height),
755
+ }
756
+ : {}),
722
757
  }
723
758
  }
724
759
  }
725
760
 
726
- // TODO: Can crypto.randomUUID be used instead including in dev environments without https
727
- function uuid(): string {
728
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
729
- const r = (Math.random() * 16) | 0
730
- return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
731
- })
761
+ export class CreateSpatializedElementAnimationJSBCommand extends JSBCommand {
762
+ commandType = 'CreateSpatializedElementAnimation'
763
+
764
+ constructor(private command: CreateSpatializedElementAnimationCommand) {
765
+ super()
766
+ }
767
+
768
+ protected getParams() {
769
+ const { elementId, timeline } = this.command
770
+ return {
771
+ elementId,
772
+ timeline,
773
+ }
774
+ }
732
775
  }
733
776
 
734
- /* WebSpatial Protocol End */
777
+ export class ControlSpatializedElementAnimationJSBCommand extends JSBCommand {
778
+ commandType = 'ControlSpatializedElementAnimation'
779
+
780
+ constructor(private command: ControlSpatializedElementAnimationCommand) {
781
+ super()
782
+ }
783
+
784
+ protected getParams() {
785
+ const { animationId, type } = this.command
786
+ return {
787
+ animationId,
788
+ type,
789
+ }
790
+ }
791
+ }
package/src/Spatial.ts CHANGED
@@ -6,8 +6,6 @@ import { SpatialWebEvent } from './SpatialWebEvent'
6
6
  * This is the main entry point for the WebSpatial SDK, providing access to spatial capabilities.
7
7
  */
8
8
  export class Spatial {
9
- private wsAppShellVersionFromUA: string | null | undefined
10
-
11
9
  /**
12
10
  * Requests a spatial session object from the browser.
13
11
  * This is the primary method to initialize spatial functionality.
@@ -35,25 +33,6 @@ export class Spatial {
35
33
  return false
36
34
  }
37
35
 
38
- getShellVersionFromUA(): string | null {
39
- if (this.wsAppShellVersionFromUA !== undefined) {
40
- return this.wsAppShellVersionFromUA
41
- }
42
- if (
43
- typeof navigator === 'undefined' ||
44
- typeof navigator.userAgent !== 'string'
45
- ) {
46
- this.wsAppShellVersionFromUA = null
47
- return null
48
- }
49
-
50
- const match = navigator.userAgent.match(
51
- /WSAppShell\/(\d+(?:\.\d+){2}(?:[-+][0-9A-Za-z.-]+)*)/,
52
- )
53
- this.wsAppShellVersionFromUA = match ? match[1] : '1.3.0'
54
- return this.wsAppShellVersionFromUA
55
- }
56
-
57
36
  /** @deprecated
58
37
  * Checks if WebSpatial is supported in the current environment.
59
38
  * Verifies compatibility between native and client versions.
@@ -38,6 +38,16 @@ export class SpatialObject {
38
38
  return
39
39
  }
40
40
 
41
+ const errorMessage =
42
+ typeof ret.errorMessage === 'string' ? ret.errorMessage.toLowerCase() : ''
43
+ const isMissingNativeObject = errorMessage.includes('not exsit')
44
+ if (isMissingNativeObject) {
45
+ // Treat native pre-teardown as an idempotent destroy during page back navigation.
46
+ this.onDestroy()
47
+ this.isDestroyed = true
48
+ return
49
+ }
50
+
41
51
  throw new Error(ret.errorMessage)
42
52
  }
43
53
 
@@ -1,8 +1,4 @@
1
- import {
2
- SpatialSceneCreationOptions,
3
- SpatialSceneProperties,
4
- Vec3,
5
- } from './types/types'
1
+ import { SpatialSceneProperties, Vec3 } from './types/types'
6
2
  import { SpatialSceneCreationOptionsInternal } from './types/internal'
7
3
  import {
8
4
  AddSpatializedElementToSpatialScene,
@@ -14,14 +14,14 @@ import {
14
14
  SpatialBoxGeometryOptions,
15
15
  SpatialConeGeometryOptions,
16
16
  SpatialCylinderGeometryOptions,
17
- SpatialGeometryOptions,
18
17
  SpatialModelEntityCreationOptions,
19
18
  SpatialPlaneGeometryOptions,
20
- SpatialSceneCreationOptions,
21
19
  SpatialSphereGeometryOptions,
22
20
  SpatialUnlitMaterialOptions,
21
+ SpatialTextureResourceOptions,
23
22
  SpatialEntityUserData,
24
23
  AttachmentEntityOptions,
24
+ ModelLoadingMode,
25
25
  ModelSource,
26
26
  } from './types/types'
27
27
  import { SpatializedDynamic3DElement } from './SpatializedDynamic3DElement'
@@ -32,6 +32,7 @@ import {
32
32
  createSpatialEntity,
33
33
  createSpatialGeometry,
34
34
  createSpatialModelEntity,
35
+ createSpatialTexture,
35
36
  createSpatialUnlitMaterial,
36
37
  } from './reality/realityCreator'
37
38
  import {
@@ -70,13 +71,16 @@ export class SpatialSession {
70
71
  * Creates a new static 3D element with an optional model URL.
71
72
  * Static 3D elements represent pre-built 3D models that can be loaded from a URL.
72
73
  * @param modelURL Optional URL to the 3D model to load
74
+ * @param sources Optional list of fallback model sources
75
+ * @param loading Whether the asset should fetch eagerly or be deferred (`'lazy'`)
73
76
  * @returns Promise resolving to a new SpatializedStatic3DElement instance
74
77
  */
75
78
  createSpatializedStatic3DElement(
76
79
  modelURL?: string,
77
80
  sources?: ModelSource[],
81
+ loading: ModelLoadingMode = 'eager',
78
82
  ): Promise<SpatializedStatic3DElement> {
79
- return createSpatializedStatic3DElement(modelURL, sources)
83
+ return createSpatializedStatic3DElement(modelURL, sources, loading)
80
84
  }
81
85
 
82
86
  /**
@@ -169,6 +173,16 @@ export class SpatialSession {
169
173
  return createSpatialUnlitMaterial(options)
170
174
  }
171
175
 
176
+ /**
177
+ * Creates a texture resource from the specified image URL.
178
+ * Texture resources can be referenced by materials and other spatial content.
179
+ * @param options Configuration options for the texture resource
180
+ * @returns Promise resolving to a new SpatialTextureResource instance
181
+ */
182
+ createTexture(options: SpatialTextureResourceOptions) {
183
+ return createSpatialTexture(options)
184
+ }
185
+
172
186
  /**
173
187
  * Creates a model asset with the specified configuration.
174
188
  * Model assets represent 3D model resources that can be used by entities.
@@ -12,6 +12,11 @@ import { Spatialized2DElementProperties } from './types/types'
12
12
  * allowing HTML elements to be positioned and interacted with in spatial applications.
13
13
  */
14
14
  export class Spatialized2DElement extends SpatializedElement {
15
+ /**
16
+ * Identifies the motion target kind supported by this element.
17
+ */
18
+ override readonly kind = 'spatialized2d' as const
19
+
15
20
  /**
16
21
  * Creates a new spatialized 2D element.
17
22
  * @param id Unique identifier for this element
@@ -1,5 +1,4 @@
1
1
  import {
2
- AddEntityToDynamic3DCommand,
3
2
  SetParentForEntityCommand,
4
3
  UpdateSpatializedDynamic3DElementProperties,
5
4
  } from './JSBCommand'
@@ -12,6 +11,11 @@ import {
12
11
  } from './types/types'
13
12
 
14
13
  export class SpatializedDynamic3DElement extends SpatializedElement {
14
+ /**
15
+ * Identifies the motion target kind supported by this element.
16
+ */
17
+ override readonly kind = 'dynamic3d' as const
18
+
15
19
  children: SpatialEntityOrReality[] = []
16
20
  events: Record<string, (data: any) => void> = {}
17
21
 
@@ -1,8 +1,14 @@
1
1
  import { UpdateSpatializedElementTransform } from './JSBCommand'
2
+ import { AnimationObject } from './motion/AnimationObject'
2
3
  import { WebSpatialProtocolResult } from './platform-adapter/interface'
3
4
  import { SpatialObject } from './SpatialObject'
4
5
  import { SpatialWebEvent } from './SpatialWebEvent'
5
6
  import { createSpatialEvent } from './SpatialWebEventCreator'
7
+ import {
8
+ normalizeMotionConfig,
9
+ validateNormalizedMotionConfig,
10
+ } from './motion/compute'
11
+ import { motionConfigToNativeTimeline } from './motion/native/serializeMotionTimeline'
6
12
  import {
7
13
  CubeInfo,
8
14
  SpatialDragEndEvent,
@@ -27,6 +33,10 @@ import {
27
33
  SpatialTapMsg,
28
34
  SpatialWebMsgType,
29
35
  } from './WebMsgCommand'
36
+ import type {
37
+ SpatializedMotionConfig,
38
+ SpatializedMotionKind,
39
+ } from './types/motion/spatializedMotion'
30
40
 
31
41
  /**
32
42
  * Abstract base class for all spatialized elements in the WebSpatial environment.
@@ -34,6 +44,11 @@ import {
34
44
  * including transformation handling and gesture event processing.
35
45
  */
36
46
  export abstract class SpatializedElement extends SpatialObject {
47
+ /**
48
+ * Identifies the motion target kind supported by this spatialized element.
49
+ */
50
+ abstract readonly kind: SpatializedMotionKind
51
+
37
52
  /**
38
53
  * Creates a new spatialized element with the specified ID.
39
54
  * Registers the element to receive spatial events.
@@ -55,6 +70,20 @@ export abstract class SpatializedElement extends SpatialObject {
55
70
  properties: Partial<SpatializedElementProperties>,
56
71
  ): Promise<WebSpatialProtocolResult>
57
72
 
73
+ /**
74
+ * Creates a native-first AnimationObject bound to this spatialized element.
75
+ */
76
+ async createAnimation(
77
+ config: SpatializedMotionConfig,
78
+ ): Promise<AnimationObject> {
79
+ const normalized = normalizeMotionConfig(config)
80
+ validateNormalizedMotionConfig(normalized)
81
+ return AnimationObject.create({
82
+ elementId: this.id,
83
+ timeline: motionConfigToNativeTimeline(normalized),
84
+ })
85
+ }
86
+
58
87
  /**
59
88
  * Updates the transformation matrix of this element in 3D space.
60
89
  * This affects the position, rotation, and scale of the element.
@@ -1,15 +1,15 @@
1
1
  import {
2
- createSpatialized2DElementCommand,
3
2
  CreateSpatializedDynamic3DElementCommand,
4
3
  CreateSpatializedStatic3DElementCommand,
5
4
  } from './JSBCommand'
6
5
  import { Spatialized2DElement } from './Spatialized2DElement'
7
6
  import { SpatializedStatic3DElement } from './SpatializedStatic3DElement'
8
7
  import { SpatializedDynamic3DElement } from './SpatializedDynamic3DElement'
9
- import { ModelSource } from './types/types'
8
+ import { createNativeSpatialDiv } from './spatial-host'
9
+ import { ModelLoadingMode, ModelSource } from './types/types'
10
10
 
11
11
  export async function createSpatialized2DElement(): Promise<Spatialized2DElement> {
12
- const result = await new createSpatialized2DElementCommand().execute()
12
+ const result = await createNativeSpatialDiv()
13
13
  if (!result.success) {
14
14
  throw new Error('createSpatialized2DElement failed')
15
15
  } else {
@@ -24,16 +24,18 @@ export async function createSpatialized2DElement(): Promise<Spatialized2DElement
24
24
  export async function createSpatializedStatic3DElement(
25
25
  modelURL?: string,
26
26
  sources?: ModelSource[],
27
+ loading: ModelLoadingMode = 'eager',
27
28
  ): Promise<SpatializedStatic3DElement> {
28
29
  const result = await new CreateSpatializedStatic3DElementCommand(
29
30
  modelURL,
30
31
  sources,
32
+ loading,
31
33
  ).execute()
32
34
  if (!result.success) {
33
35
  throw new Error('createSpatializedStatic3DElement failed')
34
36
  } else {
35
37
  const { id } = result.data
36
- return new SpatializedStatic3DElement(id, modelURL, sources)
38
+ return new SpatializedStatic3DElement(id, modelURL, sources, loading)
37
39
  }
38
40
  }
39
41
 
@@ -136,4 +136,103 @@ describe('SpatializedStatic3DElement', () => {
136
136
  el.onReceiveEvent({ type: SpatialWebMsgType.modelloaded })
137
137
  await expect(p3).resolves.toBe(true)
138
138
  })
139
+
140
+ it('currentTime defaults to 0 before any sample', () => {
141
+ const el = new SpatializedStatic3DElement('ct1', 'a.glb')
142
+ expect(el.currentTime).toBe(0)
143
+ })
144
+
145
+ it('currentTime returns the anchor while paused', () => {
146
+ const el = new SpatializedStatic3DElement('ct2', 'a.glb')
147
+ el.onReceiveEvent({
148
+ type: SpatialWebMsgType.animationstatechange,
149
+ detail: {
150
+ paused: true,
151
+ duration: 10,
152
+ currentTime: 4,
153
+ timestamp: Date.now(),
154
+ },
155
+ })
156
+ expect(el.currentTime).toBe(4)
157
+ })
158
+
159
+ it('currentTime extrapolates while playing using playbackRate', () => {
160
+ const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1_000)
161
+ const el = new SpatializedStatic3DElement('ct3', 'a.glb')
162
+ el.onReceiveEvent({
163
+ type: SpatialWebMsgType.animationstatechange,
164
+ detail: {
165
+ paused: false,
166
+ duration: 10,
167
+ currentTime: 2,
168
+ timestamp: 1_000,
169
+ },
170
+ })
171
+ nowSpy.mockReturnValue(2_000) // +1s real time
172
+ // default rate 1 → +1s animation time
173
+ expect(el.currentTime).toBe(3)
174
+ nowSpy.mockRestore()
175
+ })
176
+
177
+ it('currentTime clamps extrapolation to duration', () => {
178
+ const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1_000)
179
+ const el = new SpatializedStatic3DElement('ct4', 'a.glb')
180
+ el.onReceiveEvent({
181
+ type: SpatialWebMsgType.animationstatechange,
182
+ detail: {
183
+ paused: false,
184
+ duration: 5,
185
+ currentTime: 4,
186
+ timestamp: 1_000,
187
+ },
188
+ })
189
+ nowSpy.mockReturnValue(11_000) // +10s real time → would extrapolate to 14
190
+ expect(el.currentTime).toBe(5)
191
+ nowSpy.mockRestore()
192
+ })
193
+
194
+ it('setting currentTime optimistically updates the anchor', async () => {
195
+ const el = new SpatializedStatic3DElement('ct5', 'a.glb')
196
+ el.onReceiveEvent({
197
+ type: SpatialWebMsgType.animationstatechange,
198
+ detail: {
199
+ paused: true,
200
+ duration: 10,
201
+ currentTime: 0,
202
+ timestamp: Date.now(),
203
+ },
204
+ })
205
+ el.currentTime = 7
206
+ expect(el.currentTime).toBe(7)
207
+ })
208
+
209
+ it('setting currentTime clamps negative values to 0', async () => {
210
+ const el = new SpatializedStatic3DElement('ct6', 'a.glb')
211
+ el.onReceiveEvent({
212
+ type: SpatialWebMsgType.animationstatechange,
213
+ detail: {
214
+ paused: true,
215
+ duration: 10,
216
+ currentTime: 5,
217
+ timestamp: Date.now(),
218
+ },
219
+ })
220
+ el.currentTime = -3
221
+ expect(el.currentTime).toBe(0)
222
+ })
223
+
224
+ it('setting currentTime clamps values above duration', async () => {
225
+ const el = new SpatializedStatic3DElement('ct7', 'a.glb')
226
+ el.onReceiveEvent({
227
+ type: SpatialWebMsgType.animationstatechange,
228
+ detail: {
229
+ paused: true,
230
+ duration: 8,
231
+ currentTime: 0,
232
+ timestamp: Date.now(),
233
+ },
234
+ })
235
+ el.currentTime = 100
236
+ expect(el.currentTime).toBe(8)
237
+ })
139
238
  })