@webspatial/core-sdk 1.7.0 → 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 (296) hide show
  1. package/CHANGELOG.md +61 -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 -1251
  43. package/dist/index.js +21 -3650
  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 +132 -5
  241. package/src/SpatialObject.ts +10 -0
  242. package/src/Spatialized2DElement.ts +5 -0
  243. package/src/SpatializedDynamic3DElement.ts +5 -0
  244. package/src/SpatializedElement.ts +29 -0
  245. package/src/SpatializedStatic3DElement.ts +42 -3
  246. package/src/WebMsgCommand.ts +40 -0
  247. package/src/coverage-boost.test.ts +239 -216
  248. package/src/index.ts +25 -11
  249. package/src/install-polyfills.ts +38 -0
  250. package/src/jsbcommand.coverage.test.ts +23 -0
  251. package/src/motion/AnimationObject.test.ts +421 -0
  252. package/src/motion/AnimationObject.ts +208 -0
  253. package/src/motion/compute/index.ts +10 -0
  254. package/src/motion/compute/motionPropertyValues.test.ts +55 -0
  255. package/src/motion/compute/motionPropertyValues.ts +70 -0
  256. package/src/motion/compute/normalize.test.ts +99 -0
  257. package/src/motion/compute/normalize.ts +289 -0
  258. package/src/motion/compute/validate.test.ts +229 -0
  259. package/src/motion/compute/validate.ts +156 -0
  260. package/src/motion/index.ts +2 -0
  261. package/src/motion/native/serializeMotionTimeline.test.ts +61 -0
  262. package/src/motion/native/serializeMotionTimeline.ts +27 -0
  263. package/src/platform-adapter/createPlatformSync.ts +5 -3
  264. package/src/platform-adapter/pico-os/PicoOSPlatform.ts +76 -11
  265. package/src/platform-adapter/spatialRequestMetadata.test.ts +175 -0
  266. package/src/platform-adapter/spatialRequestMetadata.ts +48 -0
  267. package/src/platform-adapter/vision-os/VisionOSPlatform.ts +6 -1
  268. package/src/reality/entity/SpatialEntity.ts +127 -0
  269. package/src/runtime/capability-data.ts +104 -4
  270. package/src/runtime/index.ts +0 -11
  271. package/src/runtime/keys.ts +12 -1
  272. package/src/runtime/supports.test.ts +143 -4
  273. package/src/runtime/supports.ts +3 -1
  274. package/src/runtime/useAnimation.capability.test.ts +275 -0
  275. package/src/scene-polyfill.manifest.test.ts +306 -5
  276. package/src/scene-polyfill.request-metadata.test.ts +39 -0
  277. package/src/scene-polyfill.test.ts +33 -94
  278. package/src/scene-polyfill.ts +117 -87
  279. package/src/spatial-window-polyfill.ts +18 -2
  280. package/src/transform-roundtrip.test.ts +90 -0
  281. package/src/types/animation.ts +224 -0
  282. package/src/types/global.ts +1 -8
  283. package/src/types/motion/index.ts +10 -0
  284. package/src/types/motion/spatializedElementMotion.ts +49 -0
  285. package/src/types/motion/spatializedMotion.ts +147 -0
  286. package/src/types/motion/spatializedPlayback.ts +17 -0
  287. package/src/types/motion/spatializedVisual.ts +24 -0
  288. package/src/types/types.ts +3 -0
  289. package/src/utils.ts +54 -0
  290. package/tsup.config.ts +61 -36
  291. package/vitest.config.ts +5 -1
  292. package/dist/iife/index.d.ts +0 -1251
  293. package/dist/iife/index.global.js +0 -75
  294. package/dist/iife/index.global.js.map +0 -1
  295. package/src/platform-adapter/ssr/SSRPlatform.ts +0 -52
  296. /package/src/{ssr-polyfill.ts → isSSREnv.ts} +0 -0
@@ -80,15 +80,17 @@ describe('utils', () => {
80
80
  { x: 2, y: 3, z: 4 },
81
81
  )
82
82
 
83
+ // Use toMatchObject because happy-dom returns a real DOMPoint (which
84
+ // includes a `w` property) rather than a plain {x,y,z} object.
83
85
  const origin = m.transformPoint({ x: 0, y: 0, z: 0 })
84
- expect(origin).toEqual({
86
+ expect(origin).toMatchObject({
85
87
  x: 10,
86
88
  y: 20,
87
89
  z: 30,
88
90
  })
89
91
 
90
92
  const p = m.transformPoint({ x: 1, y: 1, z: 1 })
91
- expect(p).toEqual({ x: 12, y: 23, z: 34 })
93
+ expect(p).toMatchObject({ x: 12, y: 23, z: 34 })
92
94
  })
93
95
  })
94
96
 
@@ -171,20 +173,24 @@ describe('SpatialObject', () => {
171
173
  it('inspect returns data when command succeeds', async () => {
172
174
  vi.doMock('./JSBCommand', () => {
173
175
  return {
174
- InspectCommand: vi.fn().mockImplementation(() => ({
175
- execute: vi.fn().mockResolvedValue({
176
- success: true,
177
- data: { a: 1 },
178
- errorMessage: '',
179
- }),
180
- })),
181
- DestroyCommand: vi.fn().mockImplementation(() => ({
182
- execute: vi.fn().mockResolvedValue({
183
- success: true,
184
- data: undefined,
185
- errorMessage: '',
186
- }),
187
- })),
176
+ InspectCommand: vi.fn().mockImplementation(function () {
177
+ return {
178
+ execute: vi.fn().mockResolvedValue({
179
+ success: true,
180
+ data: { a: 1 },
181
+ errorMessage: '',
182
+ }),
183
+ }
184
+ }),
185
+ DestroyCommand: vi.fn().mockImplementation(function () {
186
+ return {
187
+ execute: vi.fn().mockResolvedValue({
188
+ success: true,
189
+ data: undefined,
190
+ errorMessage: '',
191
+ }),
192
+ }
193
+ }),
188
194
  }
189
195
  })
190
196
 
@@ -196,20 +202,24 @@ describe('SpatialObject', () => {
196
202
  it('inspect throws when command fails', async () => {
197
203
  vi.doMock('./JSBCommand', () => {
198
204
  return {
199
- InspectCommand: vi.fn().mockImplementation(() => ({
200
- execute: vi.fn().mockResolvedValue({
201
- success: false,
202
- data: undefined,
203
- errorMessage: 'nope',
204
- }),
205
- })),
206
- DestroyCommand: vi.fn().mockImplementation(() => ({
207
- execute: vi.fn().mockResolvedValue({
208
- success: true,
209
- data: undefined,
210
- errorMessage: '',
211
- }),
212
- })),
205
+ InspectCommand: vi.fn().mockImplementation(function () {
206
+ return {
207
+ execute: vi.fn().mockResolvedValue({
208
+ success: false,
209
+ data: undefined,
210
+ errorMessage: 'nope',
211
+ }),
212
+ }
213
+ }),
214
+ DestroyCommand: vi.fn().mockImplementation(function () {
215
+ return {
216
+ execute: vi.fn().mockResolvedValue({
217
+ success: true,
218
+ data: undefined,
219
+ errorMessage: '',
220
+ }),
221
+ }
222
+ }),
213
223
  }
214
224
  })
215
225
 
@@ -222,20 +232,24 @@ describe('SpatialObject', () => {
222
232
  const onDestroy = vi.fn()
223
233
  vi.doMock('./JSBCommand', () => {
224
234
  return {
225
- InspectCommand: vi.fn().mockImplementation(() => ({
226
- execute: vi.fn().mockResolvedValue({
227
- success: true,
228
- data: undefined,
229
- errorMessage: '',
230
- }),
231
- })),
232
- DestroyCommand: vi.fn().mockImplementation(() => ({
233
- execute: vi.fn().mockResolvedValue({
234
- success: true,
235
- data: { ok: true },
236
- errorMessage: '',
237
- }),
238
- })),
235
+ InspectCommand: vi.fn().mockImplementation(function () {
236
+ return {
237
+ execute: vi.fn().mockResolvedValue({
238
+ success: true,
239
+ data: undefined,
240
+ errorMessage: '',
241
+ }),
242
+ }
243
+ }),
244
+ DestroyCommand: vi.fn().mockImplementation(function () {
245
+ return {
246
+ execute: vi.fn().mockResolvedValue({
247
+ success: true,
248
+ data: { ok: true },
249
+ errorMessage: '',
250
+ }),
251
+ }
252
+ }),
239
253
  }
240
254
  })
241
255
 
@@ -253,6 +267,45 @@ describe('SpatialObject', () => {
253
267
  await expect(obj.destroy()).resolves.toBeUndefined()
254
268
  expect(onDestroy).toHaveBeenCalledTimes(1)
255
269
  })
270
+
271
+ it('treats missing native spatial objects as already destroyed', async () => {
272
+ const onDestroy = vi.fn()
273
+ vi.doMock('./JSBCommand', () => {
274
+ return {
275
+ InspectCommand: vi.fn().mockImplementation(function () {
276
+ return {
277
+ execute: vi.fn().mockResolvedValue({
278
+ success: true,
279
+ data: undefined,
280
+ errorMessage: '',
281
+ }),
282
+ }
283
+ }),
284
+ DestroyCommand: vi.fn().mockImplementation(function () {
285
+ return {
286
+ execute: vi.fn().mockResolvedValue({
287
+ success: false,
288
+ data: undefined,
289
+ errorMessage:
290
+ 'Failed to destroy SpatialObject: invalid inspect spatial object id obj-2 not exsit!',
291
+ }),
292
+ }
293
+ }),
294
+ }
295
+ })
296
+
297
+ const { SpatialObject } = await import('./SpatialObject')
298
+ class TestObject extends SpatialObject {
299
+ protected onDestroy() {
300
+ onDestroy()
301
+ }
302
+ }
303
+
304
+ const obj = new TestObject('obj-2')
305
+ await expect(obj.destroy()).resolves.toBeUndefined()
306
+ expect(obj.isDestroyed).toBe(true)
307
+ expect(onDestroy).toHaveBeenCalledTimes(1)
308
+ })
256
309
  })
257
310
 
258
311
  describe('platform adapters', () => {
@@ -263,18 +316,6 @@ describe('platform adapters', () => {
263
316
  vi.unmock('./JSBCommand')
264
317
  })
265
318
 
266
- it('SSRPlatform returns successful no-op results', async () => {
267
- const { SSRPlatform } = await import('./platform-adapter/ssr/SSRPlatform')
268
- const platform = new SSRPlatform()
269
-
270
- await expect(platform.callJSB('c', '{}')).resolves.toMatchObject({
271
- success: true,
272
- })
273
- expect(platform.openSpatialSceneSync('s', undefined)).toMatchObject({
274
- success: true,
275
- })
276
- })
277
-
278
319
  it('VisionOSPlatform.callJSB returns success and parses failures', async () => {
279
320
  ;(window as any).webkit = {
280
321
  messageHandlers: {
@@ -326,8 +367,8 @@ describe('platform adapters', () => {
326
367
  const r = await platform.createNativeSpatialDiv()
327
368
 
328
369
  expect(r.success).toBe(true)
329
- expect(r.data.id).toBe(uuid)
330
- expect(r.data.windowProxy).toBe(windowProxy)
370
+ expect(r.data?.id).toBe(uuid)
371
+ expect(r.data?.windowProxy).toBe(windowProxy)
331
372
  })
332
373
  })
333
374
 
@@ -456,6 +497,44 @@ describe('spatialWindowPolyfill', () => {
456
497
  expect(updateSpatialProperties).toHaveBeenCalledWith({
457
498
  material: 'none',
458
499
  })
500
+
501
+ await Promise.resolve()
502
+ await Promise.resolve()
503
+ updateSpatialProperties.mockClear()
504
+ ;(document.documentElement.style as any)['--xr-background-material'] =
505
+ 'translucent'
506
+ expect(updateSpatialProperties).toHaveBeenCalledWith({
507
+ material: 'translucent',
508
+ })
509
+ expect(
510
+ getComputedStyle(document.documentElement)
511
+ .getPropertyValue('--xr-background-material')
512
+ .trim(),
513
+ ).toBe('translucent')
514
+ expect(
515
+ (
516
+ (document.documentElement.style as any)[
517
+ '--xr-background-material'
518
+ ] as string
519
+ ).trim(),
520
+ ).toBe('translucent')
521
+
522
+ updateSpatialProperties.mockClear()
523
+ document.documentElement.style.setProperty('border-radius', '80px')
524
+ await Promise.resolve()
525
+ await Promise.resolve()
526
+
527
+ expect(updateSpatialProperties).toHaveBeenCalledWith({
528
+ cornerRadius: {
529
+ topLeading: 80,
530
+ topTrailing: 80,
531
+ bottomLeading: 80,
532
+ bottomTrailing: 80,
533
+ },
534
+ })
535
+ expect(updateSpatialProperties).not.toHaveBeenCalledWith({
536
+ material: 'none',
537
+ })
459
538
  })
460
539
  })
461
540
 
@@ -501,34 +580,42 @@ describe('SpatializedElementCreator', () => {
501
580
  UpdateSpatializedDynamic3DElementProperties: OkCommand,
502
581
  SetParentForEntityCommand: OkCommand,
503
582
  AddEntityToDynamic3DCommand: OkCommand,
504
- createSpatialized2DElementCommand: vi.fn().mockImplementation(() => ({
505
- execute: vi.fn().mockResolvedValue({
506
- success: true,
507
- data: { id: 'w1', windowProxy },
508
- errorCode: '',
509
- errorMessage: '',
583
+ createSpatialized2DElementCommand: vi
584
+ .fn()
585
+ .mockImplementation(function () {
586
+ return {
587
+ execute: vi.fn().mockResolvedValue({
588
+ success: true,
589
+ data: { id: 'w1', windowProxy },
590
+ errorCode: '',
591
+ errorMessage: '',
592
+ }),
593
+ }
510
594
  }),
511
- })),
512
595
  CreateSpatializedStatic3DElementCommand: vi
513
596
  .fn()
514
- .mockImplementation(() => ({
515
- execute: vi.fn().mockResolvedValue({
516
- success: true,
517
- data: { id: 's-default' },
518
- errorCode: '',
519
- errorMessage: '',
520
- }),
521
- })),
597
+ .mockImplementation(function () {
598
+ return {
599
+ execute: vi.fn().mockResolvedValue({
600
+ success: true,
601
+ data: { id: 's-default' },
602
+ errorCode: '',
603
+ errorMessage: '',
604
+ }),
605
+ }
606
+ }),
522
607
  CreateSpatializedDynamic3DElementCommand: vi
523
608
  .fn()
524
- .mockImplementation(() => ({
525
- execute: vi.fn().mockResolvedValue({
526
- success: true,
527
- data: { id: 'd-default' },
528
- errorCode: '',
529
- errorMessage: '',
530
- }),
531
- })),
609
+ .mockImplementation(function () {
610
+ return {
611
+ execute: vi.fn().mockResolvedValue({
612
+ success: true,
613
+ data: { id: 'd-default' },
614
+ errorCode: '',
615
+ errorMessage: '',
616
+ }),
617
+ }
618
+ }),
532
619
  }
533
620
  })
534
621
 
@@ -574,14 +661,18 @@ describe('SpatializedElementCreator', () => {
574
661
  UpdateSpatializedDynamic3DElementProperties: OkCommand,
575
662
  SetParentForEntityCommand: OkCommand,
576
663
  AddEntityToDynamic3DCommand: OkCommand,
577
- createSpatialized2DElementCommand: vi.fn().mockImplementation(() => ({
578
- execute: vi.fn().mockResolvedValue({
579
- success: false,
580
- data: undefined,
581
- errorCode: 'E',
582
- errorMessage: 'bad',
664
+ createSpatialized2DElementCommand: vi
665
+ .fn()
666
+ .mockImplementation(function () {
667
+ return {
668
+ execute: vi.fn().mockResolvedValue({
669
+ success: false,
670
+ data: undefined,
671
+ errorCode: 'E',
672
+ errorMessage: 'bad',
673
+ }),
674
+ }
583
675
  }),
584
- })),
585
676
  CreateSpatializedStatic3DElementCommand: vi.fn(),
586
677
  CreateSpatializedDynamic3DElementCommand: vi.fn(),
587
678
  }
@@ -622,22 +713,26 @@ describe('SpatializedElementCreator', () => {
622
713
  CreateSpatializedDynamic3DElementCommand: vi.fn(),
623
714
  CreateSpatializedStatic3DElementCommand: vi
624
715
  .fn()
625
- .mockImplementationOnce(() => ({
626
- execute: vi.fn().mockResolvedValue({
627
- success: true,
628
- data: { id: 's3' },
629
- errorCode: '',
630
- errorMessage: '',
631
- }),
632
- }))
633
- .mockImplementationOnce(() => ({
634
- execute: vi.fn().mockResolvedValue({
635
- success: false,
636
- data: undefined,
637
- errorCode: 'E',
638
- errorMessage: 'bad',
639
- }),
640
- })),
716
+ .mockImplementationOnce(function () {
717
+ return {
718
+ execute: vi.fn().mockResolvedValue({
719
+ success: true,
720
+ data: { id: 's3' },
721
+ errorCode: '',
722
+ errorMessage: '',
723
+ }),
724
+ }
725
+ })
726
+ .mockImplementationOnce(function () {
727
+ return {
728
+ execute: vi.fn().mockResolvedValue({
729
+ success: false,
730
+ data: undefined,
731
+ errorCode: 'E',
732
+ errorMessage: 'bad',
733
+ }),
734
+ }
735
+ }),
641
736
  }
642
737
  })
643
738
 
@@ -679,22 +774,26 @@ describe('SpatializedElementCreator', () => {
679
774
  CreateSpatializedStatic3DElementCommand: vi.fn(),
680
775
  CreateSpatializedDynamic3DElementCommand: vi
681
776
  .fn()
682
- .mockImplementationOnce(() => ({
683
- execute: vi.fn().mockResolvedValue({
684
- success: true,
685
- data: { id: 'd3' },
686
- errorCode: '',
687
- errorMessage: '',
688
- }),
689
- }))
690
- .mockImplementationOnce(() => ({
691
- execute: vi.fn().mockResolvedValue({
692
- success: false,
693
- data: undefined,
694
- errorCode: 'E',
695
- errorMessage: 'bad',
696
- }),
697
- })),
777
+ .mockImplementationOnce(function () {
778
+ return {
779
+ execute: vi.fn().mockResolvedValue({
780
+ success: true,
781
+ data: { id: 'd3' },
782
+ errorCode: '',
783
+ errorMessage: '',
784
+ }),
785
+ }
786
+ })
787
+ .mockImplementationOnce(function () {
788
+ return {
789
+ execute: vi.fn().mockResolvedValue({
790
+ success: false,
791
+ data: undefined,
792
+ errorCode: 'E',
793
+ errorMessage: 'bad',
794
+ }),
795
+ }
796
+ }),
698
797
  }
699
798
  })
700
799
 
@@ -717,72 +816,7 @@ describe('SpatializedStatic3DElement', () => {
717
816
  vi.unmock('./JSBCommand')
718
817
  })
719
818
 
720
- it('resets ready when modelURL changes and resolves on load events', async () => {
721
- const execute = vi.fn().mockResolvedValue({
722
- success: true,
723
- data: undefined,
724
- errorCode: '',
725
- errorMessage: '',
726
- })
727
- vi.doMock('./JSBCommand', () => {
728
- class OkCommand {
729
- execute() {
730
- return Promise.resolve({
731
- success: true,
732
- data: undefined,
733
- errorCode: '',
734
- errorMessage: '',
735
- })
736
- }
737
- }
738
-
739
- return {
740
- InspectCommand: OkCommand,
741
- DestroyCommand: OkCommand,
742
- UpdateSpatializedElementTransform: OkCommand,
743
- UpdateSpatialized2DElementProperties: OkCommand,
744
- AddSpatializedElementToSpatialized2DElement: OkCommand,
745
- UpdateSpatializedDynamic3DElementProperties: OkCommand,
746
- SetParentForEntityCommand: OkCommand,
747
- AddEntityToDynamic3DCommand: OkCommand,
748
- createSpatialized2DElementCommand: vi.fn(),
749
- CreateSpatializedStatic3DElementCommand: vi.fn(),
750
- CreateSpatializedDynamic3DElementCommand: vi.fn(),
751
- UpdateSpatializedStatic3DElementProperties: vi
752
- .fn()
753
- .mockImplementation(() => ({ execute })),
754
- }
755
- })
756
-
757
- const { SpatializedStatic3DElement } = await import(
758
- './SpatializedStatic3DElement'
759
- )
760
- const { SpatialWebMsgType } = await import('./WebMsgCommand')
761
-
762
- const el = new SpatializedStatic3DElement('m1')
763
- const onLoad = vi.fn()
764
- const onFail = vi.fn()
765
- el.onLoadCallback = onLoad
766
- el.onLoadFailureCallback = onFail
767
-
768
- const p1 = el.ready
769
- await el.updateProperties({ modelURL: 'a.glb' } as any)
770
- expect(execute).toHaveBeenCalledTimes(1)
771
- const p2 = el.ready
772
- expect(p2).not.toBe(p1)
773
-
774
- el.onReceiveEvent({ type: SpatialWebMsgType.modelloaded } as any)
775
- await expect(p2).resolves.toBe(true)
776
- expect(onLoad).toHaveBeenCalledTimes(1)
777
-
778
- await el.updateProperties({ modelURL: 'b.glb' } as any)
779
- const p3 = el.ready
780
- el.onReceiveEvent({ type: SpatialWebMsgType.modelloadfailed } as any)
781
- await expect(p3).resolves.toBe(false)
782
- expect(onFail).toHaveBeenCalledTimes(1)
783
- })
784
-
785
- it('updateModelTransform passes float64 array to updateProperties', async () => {
819
+ it('entityTransform setter passes float64 array to updateProperties', async () => {
786
820
  const execute = vi.fn().mockResolvedValue({
787
821
  success: true,
788
822
  data: undefined,
@@ -815,7 +849,9 @@ describe('SpatializedStatic3DElement', () => {
815
849
  CreateSpatializedDynamic3DElementCommand: vi.fn(),
816
850
  UpdateSpatializedStatic3DElementProperties: vi
817
851
  .fn()
818
- .mockImplementation(() => ({ execute })),
852
+ .mockImplementation(function () {
853
+ return { execute }
854
+ }),
819
855
  }
820
856
  })
821
857
 
@@ -832,7 +868,7 @@ describe('SpatializedStatic3DElement', () => {
832
868
  }
833
869
 
834
870
  const el = new SpatializedStatic3DElement('m2')
835
- el.updateModelTransform(new DOMMatrixWithArray() as any)
871
+ el.entityTransform = new DOMMatrixWithArray() as any
836
872
  expect(execute).toHaveBeenCalledTimes(1)
837
873
  })
838
874
  })
@@ -875,9 +911,9 @@ describe('SpatializedDynamic3DElement', () => {
875
911
  CreateSpatializedStatic3DElementCommand: vi.fn(),
876
912
  CreateSpatializedDynamic3DElementCommand: vi.fn(),
877
913
  AddEntityToDynamic3DCommand: OkCommand,
878
- SetParentForEntityCommand: vi
879
- .fn()
880
- .mockImplementation(() => ({ execute })),
914
+ SetParentForEntityCommand: vi.fn().mockImplementation(function () {
915
+ return { execute }
916
+ }),
881
917
  }
882
918
  })
883
919
 
@@ -927,7 +963,9 @@ describe('SpatializedDynamic3DElement', () => {
927
963
  CreateSpatializedDynamic3DElementCommand: vi.fn(),
928
964
  UpdateSpatializedDynamic3DElementProperties: vi
929
965
  .fn()
930
- .mockImplementation(() => ({ execute })),
966
+ .mockImplementation(function () {
967
+ return { execute }
968
+ }),
931
969
  }
932
970
  })
933
971
 
@@ -940,40 +978,25 @@ describe('SpatializedDynamic3DElement', () => {
940
978
  })
941
979
  })
942
980
 
943
- describe('ssr-polyfill', () => {
981
+ describe('isSSREnv', () => {
944
982
  it('isSSREnv returns false in jsdom', async () => {
945
- const { isSSREnv } = await import('./ssr-polyfill')
983
+ const { isSSREnv } = await import('./isSSREnv')
946
984
  expect(isSSREnv()).toBe(false)
947
985
  })
948
986
  })
949
987
 
950
988
  describe('platform-adapter', () => {
951
- it('createPlatform returns SSRPlatform in SSR env', async () => {
952
- vi.resetModules()
953
- vi.doMock('./ssr-polyfill', () => {
954
- return { isSSREnv: () => true }
955
- })
956
-
957
- const { createPlatform } = await import('./platform-adapter')
958
- const p = await createPlatform()
959
- expect(typeof p.callJSB).toBe('function')
960
- expect(typeof p.openSpatialSceneSync).toBe('function')
961
- expect(typeof p.createNativeSpatialDiv).toBe('function')
962
- expect(typeof p.createNativeAttachment).toBe('function')
963
- })
964
-
965
- it('createPlatformSync uses SSR sync noop in SSR env', async () => {
989
+ it('createPlatform and createPlatformSync throw in SSR env', async () => {
966
990
  vi.resetModules()
967
- vi.doMock('./ssr-polyfill', () => {
991
+ vi.doMock('./isSSREnv', () => {
968
992
  return { isSSREnv: () => true }
969
993
  })
970
994
 
971
- const { createPlatformSync } = await import(
972
- './platform-adapter/createPlatformSync'
995
+ const { createPlatform, createPlatformSync } = await import(
996
+ './platform-adapter'
973
997
  )
974
- const p = createPlatformSync()
975
- const r = p.openSpatialSceneSync('https://x', undefined)
976
- expect(r.success).toBe(true)
977
- expect(r.data).toBeUndefined()
998
+ const expected = /cannot run during SSR/
999
+ await expect(createPlatform()).rejects.toThrow(expected)
1000
+ expect(() => createPlatformSync()).toThrow(expected)
978
1001
  })
979
1002
  })
package/src/index.ts CHANGED
@@ -1,3 +1,23 @@
1
+ // =============================================================================
2
+ // `@webspatial/core-sdk` ESM entry — side-effect-free.
3
+ //
4
+ // The previous top-level polyfill installation (`if (UA contains
5
+ // 'WebSpatial/') { injectSceneHook(); spatialWindowPolyfill(); }`) lived
6
+ // here historically and was extracted out per the lazy-load proposal
7
+ // `tasks.md §12.9` ("Pre-v1 budget calibration"). ESM bundlers cannot
8
+ // tree-shake observable top-level side effects, so the runtime UA guard
9
+ // was useless for bundle size — every consumer that imported anything
10
+ // from this package statically bundled `scene-polyfill.ts` + the
11
+ // `spatial-window-polyfill.ts` pair regardless of whether they ran in a
12
+ // WebSpatial browser. After this extraction, consumers opt in:
13
+ //
14
+ // import '@webspatial/core-sdk/install-polyfills'
15
+ //
16
+ // `@webspatial/react-sdk` does this from inside its spatial chunk so the
17
+ // polyfills install only when `bootSpatial()` resolves, never in the
18
+ // lean default-entry bundle.
19
+ // =============================================================================
20
+
1
21
  export type {} from './types/global'
2
22
 
3
23
  export { SpatialObject } from './SpatialObject'
@@ -12,16 +32,10 @@ export * as PhysicalMetrics from './physicalMetrics'
12
32
 
13
33
  export * from './reality'
14
34
  export * from './types/types'
35
+ export * from './types/animation'
36
+ export * from './types/motion'
37
+ export { validateSpatializedMotionConfig } from './motion'
15
38
  export * from './runtime'
16
39
 
17
- // side effects
18
- import { injectSceneHook } from './scene-polyfill'
19
- import { isSSREnv } from './ssr-polyfill'
20
- import { spatialWindowPolyfill } from './spatial-window-polyfill'
21
-
22
- export { isSSREnv }
23
-
24
- if (!isSSREnv() && navigator.userAgent.indexOf('WebSpatial/') > 0) {
25
- injectSceneHook()
26
- spatialWindowPolyfill()
27
- }
40
+ export { composeSRT, decomposeSRT } from './utils'
41
+ export { isSSREnv } from './isSSREnv'
@@ -0,0 +1,38 @@
1
+ // =============================================================================
2
+ // `@webspatial/core-sdk/install-polyfills` — opt-in polyfill installer.
3
+ //
4
+ // Side-effect-only module: installs the spatial scene hook + the
5
+ // `window.spatial` polyfill iff the page is running inside a
6
+ // WebSpatial-capable browser (UA contains `WebSpatial/`) AND we are not
7
+ // in an SSR / non-browser environment.
8
+ //
9
+ // Previously this side effect lived as a top-level `if (...)` block in
10
+ // `src/index.ts`, which forced every consumer of the package — even
11
+ // consumers that only imported pure runtime helpers like `supports()` —
12
+ // to bundle `scene-polyfill.ts` (~636 LoC) and `spatial-window-polyfill.ts`
13
+ // (~182 LoC) statically. ESM bundlers cannot tree-shake observable
14
+ // side effects, so the if-statement guard was useless for bundle size.
15
+ //
16
+ // After this extraction, `src/index.ts` is side-effect-free and consumers
17
+ // who need the polyfills opt in explicitly:
18
+ //
19
+ // import '@webspatial/core-sdk/install-polyfills'
20
+ //
21
+ // `@webspatial/react-sdk` does this from inside its spatial chunk
22
+ // (`packages/react/src/spatial/index.ts`) so the polyfill installs only
23
+ // when the spatial chunk dynamically loads — never in the SDK's lean
24
+ // default entry.
25
+ //
26
+ // Per the lazy-load proposal `tasks.md §12.9` ("Pre-v1 budget calibration"),
27
+ // extracting these polyfills is one of the named optimization candidates
28
+ // for closing the marginal-delta gap on the 8 KB strict budget.
29
+ // =============================================================================
30
+
31
+ import { injectSceneHook } from './scene-polyfill'
32
+ import { spatialWindowPolyfill } from './spatial-window-polyfill'
33
+ import { isSSREnv } from './isSSREnv'
34
+
35
+ if (!isSSREnv() && navigator.userAgent.indexOf('WebSpatial/') > 0) {
36
+ injectSceneHook()
37
+ spatialWindowPolyfill()
38
+ }