@webspatial/core-sdk 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/iife/index.d.ts +386 -236
- package/dist/iife/index.global.js +7 -7
- package/dist/iife/index.global.js.map +1 -1
- package/dist/index.d.ts +386 -236
- package/dist/index.js +1479 -1226
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/JSBCommand.ts +30 -100
- package/src/Spatial.ts +0 -21
- package/src/SpatialScene.ts +1 -5
- package/src/SpatialSession.ts +17 -3
- package/src/SpatializedDynamic3DElement.ts +0 -1
- package/src/SpatializedElementCreator.ts +6 -4
- package/src/SpatializedStatic3DElement.test.ts +99 -0
- package/src/SpatializedStatic3DElement.ts +99 -1
- package/src/WebMsgCommand.ts +10 -0
- package/src/coverage-boost.test.ts +38 -119
- package/src/index.ts +3 -1
- package/src/jsbcommand.coverage.test.ts +19 -48
- package/src/platform-adapter/CommandResultUtils.ts +2 -2
- package/src/platform-adapter/createPlatformSync.ts +34 -0
- package/src/platform-adapter/index.ts +5 -51
- package/src/platform-adapter/interface.ts +35 -23
- package/src/platform-adapter/pico-os/PicoOSPlatform.ts +84 -52
- package/src/platform-adapter/puppeteer/PuppeteerPlatform.ts +37 -11
- package/src/platform-adapter/spatialSceneQuery.ts +17 -0
- package/src/platform-adapter/ssr/SSRPlatform.ts +24 -15
- package/src/platform-adapter/vision-os/VisionOSPlatform.ts +55 -24
- package/src/platform-runtime.ts +13 -0
- package/src/reality/Attachment.ts +2 -2
- package/src/reality/entity/SpatialEntity.ts +0 -2
- package/src/reality/realityCreator.ts +15 -1
- package/src/reality/resource/SpatialTextureResource.ts +16 -0
- package/src/reality/resource/index.ts +1 -0
- package/src/runtime/WebSpatialRuntimeError.ts +16 -0
- package/src/runtime/capability-data.ts +113 -0
- package/src/runtime/contract-review.test.ts +44 -0
- package/src/runtime/index.ts +28 -0
- package/src/runtime/jsbAdapterPlatform.test.ts +36 -0
- package/src/runtime/jsbAdapterPlatform.ts +51 -0
- package/src/runtime/keys.ts +129 -0
- package/src/runtime/semver.ts +33 -0
- package/src/runtime/supports.test.ts +207 -0
- package/src/runtime/supports.ts +110 -0
- package/src/runtime/types.ts +11 -0
- package/src/runtime/userAgent.ts +64 -0
- package/src/scene-polyfill.manifest.test.ts +7 -5
- package/src/scene-polyfill.test.ts +60 -0
- package/src/scene-polyfill.ts +23 -22
- package/src/spatial-host.ts +25 -0
- package/src/types/{global.d.ts → global.ts} +10 -5
- package/src/types/types.ts +9 -0
- package/src/platform-adapter/android/AndroidPlatform.ts +0 -133
|
@@ -263,115 +263,6 @@ describe('platform adapters', () => {
|
|
|
263
263
|
vi.unmock('./JSBCommand')
|
|
264
264
|
})
|
|
265
265
|
|
|
266
|
-
// it('AndroidPlatform.callJSB resolves from async SpatialWebEvent callback', async () => {
|
|
267
|
-
// const postMessage = vi.fn((rId: string) => {
|
|
268
|
-
// expect(rId.startsWith('rId_')).toBe(true)
|
|
269
|
-
// return ''
|
|
270
|
-
// })
|
|
271
|
-
// ;(window as any).webspatialBridge = { postMessage }
|
|
272
|
-
|
|
273
|
-
// const { AndroidPlatform } = await import(
|
|
274
|
-
// './platform-adapter/android/AndroidPlatform'
|
|
275
|
-
// )
|
|
276
|
-
// const { SpatialWebEvent: SpatialWebEventInstance } = await import(
|
|
277
|
-
// './SpatialWebEvent'
|
|
278
|
-
// )
|
|
279
|
-
// const platform = new AndroidPlatform()
|
|
280
|
-
// const p = platform.callJSB('c', '{"a":1}')
|
|
281
|
-
|
|
282
|
-
// const rId = postMessage.mock.calls[0]?.[0] as string
|
|
283
|
-
// SpatialWebEventInstance.eventReceiver[rId]({
|
|
284
|
-
// success: true,
|
|
285
|
-
// data: { ok: true },
|
|
286
|
-
// })
|
|
287
|
-
|
|
288
|
-
// await expect(p).resolves.toEqual({
|
|
289
|
-
// success: true,
|
|
290
|
-
// data: { ok: true },
|
|
291
|
-
// errorCode: '',
|
|
292
|
-
// errorMessage: '',
|
|
293
|
-
// })
|
|
294
|
-
// })
|
|
295
|
-
|
|
296
|
-
// it('AndroidPlatform.callJSB handles sync bridge response and failures', async () => {
|
|
297
|
-
// ;(window as any).webspatialBridge = {
|
|
298
|
-
// postMessage: vi.fn(() =>
|
|
299
|
-
// JSON.stringify({
|
|
300
|
-
// success: false,
|
|
301
|
-
// data: { code: 'E_SYNC', message: 'bad' },
|
|
302
|
-
// }),
|
|
303
|
-
// ),
|
|
304
|
-
// }
|
|
305
|
-
|
|
306
|
-
// const { AndroidPlatform } = await import(
|
|
307
|
-
// './platform-adapter/android/AndroidPlatform'
|
|
308
|
-
// )
|
|
309
|
-
// const platform = new AndroidPlatform()
|
|
310
|
-
// await expect(platform.callJSB('c', '{}')).resolves.toEqual({
|
|
311
|
-
// success: false,
|
|
312
|
-
// data: undefined,
|
|
313
|
-
// errorCode: 'E_SYNC',
|
|
314
|
-
// errorMessage: 'bad',
|
|
315
|
-
// })
|
|
316
|
-
// })
|
|
317
|
-
|
|
318
|
-
// it('AndroidPlatform.callWebSpatialProtocol polls and returns injected SpatialId', async () => {
|
|
319
|
-
// vi.useFakeTimers()
|
|
320
|
-
|
|
321
|
-
// let canCount = 0
|
|
322
|
-
// vi.doMock('./JSBCommand', () => {
|
|
323
|
-
// return {
|
|
324
|
-
// CheckWebViewCanCreateCommand: vi.fn().mockImplementation(() => ({
|
|
325
|
-
// execute: vi.fn().mockImplementation(() => {
|
|
326
|
-
// canCount += 1
|
|
327
|
-
// return Promise.resolve({
|
|
328
|
-
// success: true,
|
|
329
|
-
// data: { can: canCount >= 2 },
|
|
330
|
-
// errorCode: '',
|
|
331
|
-
// errorMessage: '',
|
|
332
|
-
// })
|
|
333
|
-
// }),
|
|
334
|
-
// })),
|
|
335
|
-
// }
|
|
336
|
-
// })
|
|
337
|
-
|
|
338
|
-
// const windowProxy: any = {}
|
|
339
|
-
// const openFn = vi.fn()
|
|
340
|
-
// ;(window as any).open = vi.fn(() => windowProxy)
|
|
341
|
-
|
|
342
|
-
// setTimeout(() => {
|
|
343
|
-
// windowProxy.open = openFn
|
|
344
|
-
// }, 20)
|
|
345
|
-
|
|
346
|
-
// const { AndroidPlatform } = await import(
|
|
347
|
-
// './platform-adapter/android/AndroidPlatform'
|
|
348
|
-
// )
|
|
349
|
-
// const { SpatialWebEvent: SpatialWebEventInstance } = await import(
|
|
350
|
-
// './SpatialWebEvent'
|
|
351
|
-
// )
|
|
352
|
-
// const platform = new AndroidPlatform()
|
|
353
|
-
// const p = platform.callWebSpatialProtocol('open', 'x=1', '_blank', '')
|
|
354
|
-
|
|
355
|
-
// const receiverIds = Object.keys(SpatialWebEventInstance.eventReceiver)
|
|
356
|
-
// const createdId = receiverIds[0] as string
|
|
357
|
-
// const loadedId = receiverIds[1] as string
|
|
358
|
-
// SpatialWebEventInstance.eventReceiver[createdId]?.({ spatialId: 'temp' })
|
|
359
|
-
// await vi.advanceTimersByTimeAsync(100)
|
|
360
|
-
// SpatialWebEventInstance.eventReceiver[loadedId]?.({
|
|
361
|
-
// spatialId: 'spatial-1',
|
|
362
|
-
// })
|
|
363
|
-
|
|
364
|
-
// await vi.advanceTimersByTimeAsync(200)
|
|
365
|
-
|
|
366
|
-
// const result = await p
|
|
367
|
-
// expect(result.success).toBe(true)
|
|
368
|
-
// expect(result.data.id).toBe('spatial-1')
|
|
369
|
-
// expect(result.data.windowProxy).toBe(windowProxy)
|
|
370
|
-
// const call = openFn.mock.calls[0] as unknown as [string, string | undefined]
|
|
371
|
-
// expect(call?.[0]).toMatch(/^about:blank\?rid=/)
|
|
372
|
-
// expect(call?.[1]).toBe('_self')
|
|
373
|
-
// })
|
|
374
|
-
|
|
375
266
|
it('SSRPlatform returns successful no-op results', async () => {
|
|
376
267
|
const { SSRPlatform } = await import('./platform-adapter/ssr/SSRPlatform')
|
|
377
268
|
const platform = new SSRPlatform()
|
|
@@ -379,12 +270,7 @@ describe('platform adapters', () => {
|
|
|
379
270
|
await expect(platform.callJSB('c', '{}')).resolves.toMatchObject({
|
|
380
271
|
success: true,
|
|
381
272
|
})
|
|
382
|
-
|
|
383
|
-
platform.callWebSpatialProtocol('s', '', '', ''),
|
|
384
|
-
).resolves.toMatchObject({
|
|
385
|
-
success: true,
|
|
386
|
-
})
|
|
387
|
-
expect(platform.callWebSpatialProtocolSync('s', '', '', '')).toMatchObject({
|
|
273
|
+
expect(platform.openSpatialSceneSync('s', undefined)).toMatchObject({
|
|
388
274
|
success: true,
|
|
389
275
|
})
|
|
390
276
|
})
|
|
@@ -437,7 +323,7 @@ describe('platform adapters', () => {
|
|
|
437
323
|
'./platform-adapter/vision-os/VisionOSPlatform'
|
|
438
324
|
)
|
|
439
325
|
const platform = new VisionOSPlatform()
|
|
440
|
-
const r = await platform.
|
|
326
|
+
const r = await platform.createNativeSpatialDiv()
|
|
441
327
|
|
|
442
328
|
expect(r.success).toBe(true)
|
|
443
329
|
expect(r.data.id).toBe(uuid)
|
|
@@ -584,6 +470,14 @@ describe('SpatializedElementCreator', () => {
|
|
|
584
470
|
const windowProxy: any = {
|
|
585
471
|
document: { head: { innerHTML: '' } },
|
|
586
472
|
}
|
|
473
|
+
vi.doMock('./spatial-host', () => ({
|
|
474
|
+
createNativeSpatialDiv: vi.fn().mockResolvedValue({
|
|
475
|
+
success: true,
|
|
476
|
+
data: { id: 'w1', windowProxy },
|
|
477
|
+
errorCode: '',
|
|
478
|
+
errorMessage: '',
|
|
479
|
+
}),
|
|
480
|
+
}))
|
|
587
481
|
|
|
588
482
|
vi.doMock('./JSBCommand', () => {
|
|
589
483
|
class OkCommand {
|
|
@@ -649,6 +543,15 @@ describe('SpatializedElementCreator', () => {
|
|
|
649
543
|
})
|
|
650
544
|
|
|
651
545
|
it('createSpatialized2DElement throws when command fails', async () => {
|
|
546
|
+
vi.doMock('./spatial-host', () => ({
|
|
547
|
+
createNativeSpatialDiv: vi.fn().mockResolvedValue({
|
|
548
|
+
success: false,
|
|
549
|
+
data: undefined,
|
|
550
|
+
errorCode: 'E',
|
|
551
|
+
errorMessage: 'bad',
|
|
552
|
+
}),
|
|
553
|
+
}))
|
|
554
|
+
|
|
652
555
|
vi.doMock('./JSBCommand', () => {
|
|
653
556
|
class OkCommand {
|
|
654
557
|
execute() {
|
|
@@ -1052,9 +955,25 @@ describe('platform-adapter', () => {
|
|
|
1052
955
|
})
|
|
1053
956
|
|
|
1054
957
|
const { createPlatform } = await import('./platform-adapter')
|
|
1055
|
-
const p = createPlatform()
|
|
958
|
+
const p = await createPlatform()
|
|
1056
959
|
expect(typeof p.callJSB).toBe('function')
|
|
1057
|
-
expect(typeof p.
|
|
1058
|
-
expect(typeof p.
|
|
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 () => {
|
|
966
|
+
vi.resetModules()
|
|
967
|
+
vi.doMock('./ssr-polyfill', () => {
|
|
968
|
+
return { isSSREnv: () => true }
|
|
969
|
+
})
|
|
970
|
+
|
|
971
|
+
const { createPlatformSync } = await import(
|
|
972
|
+
'./platform-adapter/createPlatformSync'
|
|
973
|
+
)
|
|
974
|
+
const p = createPlatformSync()
|
|
975
|
+
const r = p.openSpatialSceneSync('https://x', undefined)
|
|
976
|
+
expect(r.success).toBe(true)
|
|
977
|
+
expect(r.data).toBeUndefined()
|
|
1059
978
|
})
|
|
1060
979
|
})
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export type {} from './types/global'
|
|
2
|
+
|
|
1
3
|
export { SpatialObject } from './SpatialObject'
|
|
2
4
|
export { Spatial } from './Spatial'
|
|
3
5
|
export { SpatialSession } from './SpatialSession'
|
|
@@ -10,7 +12,7 @@ export * as PhysicalMetrics from './physicalMetrics'
|
|
|
10
12
|
|
|
11
13
|
export * from './reality'
|
|
12
14
|
export * from './types/types'
|
|
13
|
-
export * from './
|
|
15
|
+
export * from './runtime'
|
|
14
16
|
|
|
15
17
|
// side effects
|
|
16
18
|
import { injectSceneHook } from './scene-polyfill'
|
|
@@ -55,12 +55,14 @@ class DOMMatrixPolyfill {
|
|
|
55
55
|
|
|
56
56
|
const platformSpy = {
|
|
57
57
|
callJSB: vi.fn(),
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
openSpatialSceneSync: vi.fn(),
|
|
59
|
+
createNativeSpatialDiv: vi.fn(),
|
|
60
|
+
createNativeAttachment: vi.fn(),
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
vi.mock('./platform-adapter', () => ({
|
|
63
|
-
createPlatform: () => platformSpy,
|
|
64
|
+
createPlatform: () => Promise.resolve(platformSpy),
|
|
65
|
+
createPlatformSync: () => platformSpy,
|
|
64
66
|
}))
|
|
65
67
|
|
|
66
68
|
function ok(data: any = {}) {
|
|
@@ -72,23 +74,20 @@ function ok(data: any = {}) {
|
|
|
72
74
|
})
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
function parseQuery(q?: string) {
|
|
76
|
-
const sp = new URLSearchParams(q ?? '')
|
|
77
|
-
const out: Record<string, string> = {}
|
|
78
|
-
for (const [k, v] of sp.entries()) out[k] = v
|
|
79
|
-
return out
|
|
80
|
-
}
|
|
81
|
-
|
|
82
77
|
describe('JSBCommand', () => {
|
|
83
78
|
beforeEach(() => {
|
|
84
79
|
platformSpy.callJSB.mockReset()
|
|
85
|
-
platformSpy.
|
|
86
|
-
platformSpy.
|
|
80
|
+
platformSpy.openSpatialSceneSync.mockReset()
|
|
81
|
+
platformSpy.createNativeSpatialDiv.mockReset()
|
|
82
|
+
platformSpy.createNativeAttachment.mockReset()
|
|
87
83
|
platformSpy.callJSB.mockImplementation(() => ok({ id: 'id-1' }))
|
|
88
|
-
platformSpy.
|
|
84
|
+
platformSpy.createNativeSpatialDiv.mockImplementation(() =>
|
|
85
|
+
ok({ windowProxy: {}, id: 'spatial-1' }),
|
|
86
|
+
)
|
|
87
|
+
platformSpy.createNativeAttachment.mockImplementation(() =>
|
|
89
88
|
ok({ windowProxy: {}, id: 'spatial-1' }),
|
|
90
89
|
)
|
|
91
|
-
platformSpy.
|
|
90
|
+
platformSpy.openSpatialSceneSync.mockImplementation(() => ({
|
|
92
91
|
success: true,
|
|
93
92
|
data: { windowProxy: {}, id: 'spatial-1' },
|
|
94
93
|
errorCode: '',
|
|
@@ -192,40 +191,6 @@ describe('JSBCommand', () => {
|
|
|
192
191
|
JSON.stringify({ id: 'so-1', color: '#fff' }),
|
|
193
192
|
)
|
|
194
193
|
})
|
|
195
|
-
|
|
196
|
-
it('creates query string and calls WebSpatialProtocol', async () => {
|
|
197
|
-
const mod = await import('./JSBCommand')
|
|
198
|
-
const { createSpatialSceneCommand, createSpatialized2DElementCommand } = mod
|
|
199
|
-
|
|
200
|
-
await new createSpatialized2DElementCommand().execute()
|
|
201
|
-
expect(platformSpy.callWebSpatialProtocol).toHaveBeenCalledWith(
|
|
202
|
-
'createSpatialized2DElement',
|
|
203
|
-
'',
|
|
204
|
-
undefined,
|
|
205
|
-
undefined,
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
const cmd = new createSpatialSceneCommand(
|
|
209
|
-
'https://example.com/a?b=c',
|
|
210
|
-
{ type: 'window', defaultSize: { width: 1, height: 2 } } as any,
|
|
211
|
-
'_self',
|
|
212
|
-
'popup=1',
|
|
213
|
-
)
|
|
214
|
-
await cmd.execute()
|
|
215
|
-
const call = platformSpy.callWebSpatialProtocol.mock.calls.at(-1)
|
|
216
|
-
expect(call?.[0]).toBe('createSpatialScene')
|
|
217
|
-
expect(call?.[2]).toBe('_self')
|
|
218
|
-
expect(call?.[3]).toBe('popup=1')
|
|
219
|
-
const q = parseQuery(call?.[1])
|
|
220
|
-
expect(q.url).toBe('https://example.com/a?b=c')
|
|
221
|
-
expect(JSON.parse(q.config)).toEqual({
|
|
222
|
-
type: 'window',
|
|
223
|
-
defaultSize: { width: 1, height: 2 },
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
cmd.executeSync()
|
|
227
|
-
expect(platformSpy.callWebSpatialProtocolSync).toHaveBeenCalled()
|
|
228
|
-
})
|
|
229
194
|
})
|
|
230
195
|
|
|
231
196
|
describe('SpatialObject', () => {
|
|
@@ -272,6 +237,7 @@ describe('realityCreator', () => {
|
|
|
272
237
|
if (cmd === 'CreateModelComponent') return ok({ id: 'cmp-1' })
|
|
273
238
|
if (cmd === 'CreateSpatialModelEntity') return ok({ id: 'ment-1' })
|
|
274
239
|
if (cmd === 'CreateModelAsset') return ok({ id: 'asset-1' })
|
|
240
|
+
if (cmd === 'CreateTexture') return ok({ id: 'tex-1' })
|
|
275
241
|
return ok({ id: 'id-1' })
|
|
276
242
|
})
|
|
277
243
|
})
|
|
@@ -282,6 +248,7 @@ describe('realityCreator', () => {
|
|
|
282
248
|
const mat = await import('./reality/material/SpatialUnlitMaterial')
|
|
283
249
|
const cmp = await import('./reality/component/ModelComponent')
|
|
284
250
|
const asset = await import('./reality/resource/SpatialModelAsset')
|
|
251
|
+
const tex = await import('./reality/resource/SpatialTextureResource')
|
|
285
252
|
const ent = await import('./reality/entity/SpatialEntity')
|
|
286
253
|
const modelEnt = await import('./reality/entity/SpatialModelEntity')
|
|
287
254
|
|
|
@@ -311,6 +278,10 @@ describe('realityCreator', () => {
|
|
|
311
278
|
creator.createModelAsset({ url: 'https://example.com/a.glb' }),
|
|
312
279
|
).resolves.toBeInstanceOf(asset.SpatialModelAsset)
|
|
313
280
|
|
|
281
|
+
await expect(
|
|
282
|
+
creator.createSpatialTexture({ url: 'https://example.com/tex.png' }),
|
|
283
|
+
).resolves.toBeInstanceOf(tex.SpatialTextureResource)
|
|
284
|
+
|
|
314
285
|
await expect(
|
|
315
286
|
creator.createSpatialModelEntity(
|
|
316
287
|
{ modelAssetId: 'asset-1' },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CommandResult } from './interface'
|
|
2
2
|
|
|
3
|
-
export function CommandResultSuccess(data:
|
|
3
|
+
export function CommandResultSuccess<TData>(data: TData): CommandResult<TData> {
|
|
4
4
|
return {
|
|
5
5
|
success: true,
|
|
6
6
|
data,
|
|
@@ -12,7 +12,7 @@ export function CommandResultSuccess(data: any): CommandResult {
|
|
|
12
12
|
export function CommandResultFailure(
|
|
13
13
|
errorCode: string,
|
|
14
14
|
errorMessage = '',
|
|
15
|
-
): CommandResult {
|
|
15
|
+
): CommandResult<undefined> {
|
|
16
16
|
return {
|
|
17
17
|
success: false,
|
|
18
18
|
data: undefined,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { resolveJsbAdapterPlatform } from '../runtime/jsbAdapterPlatform'
|
|
2
|
+
import { isSSREnv } from '../ssr-polyfill'
|
|
3
|
+
import { PlatformAbility } from './interface'
|
|
4
|
+
import { PicoOSPlatform } from './pico-os/PicoOSPlatform'
|
|
5
|
+
import { PuppeteerPlatform } from './puppeteer/PuppeteerPlatform'
|
|
6
|
+
import { SSRPlatform } from './ssr/SSRPlatform'
|
|
7
|
+
import { VisionOSPlatform } from './vision-os/VisionOSPlatform'
|
|
8
|
+
|
|
9
|
+
function assertNever(_: never): never {
|
|
10
|
+
throw new Error('Unhandled jsb adapter platform kind')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Construct the JSB platform synchronously (static imports).
|
|
15
|
+
* Used by getPlatformSync (e.g. scene-polyfill openSpatialSceneSync) and kept
|
|
16
|
+
* consistent with async createPlatform so paths share one implementation.
|
|
17
|
+
*/
|
|
18
|
+
export function createPlatformSync(): PlatformAbility {
|
|
19
|
+
if (isSSREnv()) {
|
|
20
|
+
return new SSRPlatform()
|
|
21
|
+
}
|
|
22
|
+
const userAgent = window.navigator.userAgent
|
|
23
|
+
const kind = resolveJsbAdapterPlatform(userAgent)
|
|
24
|
+
switch (kind) {
|
|
25
|
+
case 'puppeteer':
|
|
26
|
+
return new PuppeteerPlatform()
|
|
27
|
+
case 'picoos':
|
|
28
|
+
return new PicoOSPlatform()
|
|
29
|
+
case 'visionos':
|
|
30
|
+
return new VisionOSPlatform()
|
|
31
|
+
default:
|
|
32
|
+
return assertNever(kind)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,53 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
export { createPlatformSync } from './createPlatformSync'
|
|
2
|
+
import { createPlatformSync } from './createPlatformSync'
|
|
3
|
+
import type { PlatformAbility } from './interface'
|
|
4
4
|
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
if (!match) {
|
|
8
|
-
return null
|
|
9
|
-
}
|
|
10
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function isVersionGreater(a: number[] | null, b: number[]): boolean {
|
|
14
|
-
if (!a) {
|
|
15
|
-
return false
|
|
16
|
-
}
|
|
17
|
-
for (let index = 0; index < 3; index += 1) {
|
|
18
|
-
const diff = a[index] - b[index]
|
|
19
|
-
if (diff > 0) {
|
|
20
|
-
return true
|
|
21
|
-
}
|
|
22
|
-
if (diff < 0) {
|
|
23
|
-
return false
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return false
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function createPlatform(): PlatformAbility {
|
|
30
|
-
if (isSSREnv()) {
|
|
31
|
-
return new SSRPlatform()
|
|
32
|
-
}
|
|
33
|
-
const userAgent = window.navigator.userAgent
|
|
34
|
-
const webSpatialVersion = getWebSpatialVersion(userAgent)
|
|
35
|
-
if (window.navigator.userAgent.includes('Puppeteer')) {
|
|
36
|
-
const PuppeteerPlatform =
|
|
37
|
-
require('./puppeteer/PuppeteerPlatform').PuppeteerPlatform
|
|
38
|
-
return new PuppeteerPlatform()
|
|
39
|
-
} else if (
|
|
40
|
-
userAgent.includes('PicoWebApp') &&
|
|
41
|
-
isVersionGreater(webSpatialVersion, [0, 0, 1])
|
|
42
|
-
) {
|
|
43
|
-
const PicoOSPlatform = require('./pico-os/PicoOSPlatform').PicoOSPlatform
|
|
44
|
-
return new PicoOSPlatform()
|
|
45
|
-
} else if (userAgent.includes('Android') || userAgent.includes('Linux')) {
|
|
46
|
-
const AndroidPlatform = require('./android/AndroidPlatform').AndroidPlatform
|
|
47
|
-
return new AndroidPlatform()
|
|
48
|
-
} else {
|
|
49
|
-
const VisionOSPlatform =
|
|
50
|
-
require('./vision-os/VisionOSPlatform').VisionOSPlatform
|
|
51
|
-
return new VisionOSPlatform()
|
|
52
|
-
}
|
|
5
|
+
export async function createPlatform(): Promise<PlatformAbility> {
|
|
6
|
+
return createPlatformSync()
|
|
53
7
|
}
|
|
@@ -1,36 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
data: any
|
|
4
|
-
errorCode: string | undefined
|
|
5
|
-
errorMessage: string | undefined
|
|
6
|
-
}
|
|
1
|
+
import type { SpatialSceneCreationOptionsInternal } from '../types/internal'
|
|
2
|
+
import type { AttachmentEntityOptions } from '../types/types'
|
|
7
3
|
|
|
8
|
-
export interface
|
|
4
|
+
export interface CommandResult<TData = any> {
|
|
9
5
|
success: boolean
|
|
10
|
-
data:
|
|
11
|
-
| {
|
|
12
|
-
windowProxy: WindowProxy
|
|
13
|
-
id: string
|
|
14
|
-
}
|
|
15
|
-
| undefined
|
|
6
|
+
data: TData
|
|
16
7
|
errorCode: string | undefined
|
|
17
8
|
errorMessage: string | undefined
|
|
18
9
|
}
|
|
19
10
|
|
|
11
|
+
export type WebSpatialProtocolResult = CommandResult<
|
|
12
|
+
| {
|
|
13
|
+
// Platform-dependent window proxy shape:
|
|
14
|
+
// - browser WindowProxy (visionOS/PICO)
|
|
15
|
+
// - puppeteer simulated window object
|
|
16
|
+
// Keep broad to avoid over-constraining platform adapters/callers.
|
|
17
|
+
windowProxy: any
|
|
18
|
+
id: string
|
|
19
|
+
}
|
|
20
|
+
| undefined
|
|
21
|
+
>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Host/runtime bridge: JSB plus explicit spatial host capabilities.
|
|
25
|
+
* Implementations may use webspatial://, iframes, native events, etc.
|
|
26
|
+
*/
|
|
20
27
|
export interface PlatformAbility {
|
|
21
28
|
callJSB(cmd: string, msg: string): Promise<CommandResult>
|
|
22
|
-
callWebSpatialProtocol(
|
|
23
|
-
schema: string,
|
|
24
|
-
query?: string,
|
|
25
|
-
target?: string,
|
|
26
|
-
features?: string,
|
|
27
|
-
): Promise<WebSpatialProtocolResult>
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Open a spatial scene synchronously (e.g. window.open polyfill).
|
|
32
|
+
* Implementations may use webspatial://createSpatialScene under the hood.
|
|
33
|
+
*/
|
|
34
|
+
openSpatialSceneSync(
|
|
35
|
+
url: string,
|
|
36
|
+
config: SpatialSceneCreationOptionsInternal | undefined,
|
|
32
37
|
target?: string,
|
|
33
38
|
features?: string,
|
|
34
|
-
resultCallback?: (result: CommandResult) => void,
|
|
35
39
|
): WebSpatialProtocolResult
|
|
40
|
+
|
|
41
|
+
/** Create a native-backed spatial 2D surface (spatial div). */
|
|
42
|
+
createNativeSpatialDiv(): Promise<WebSpatialProtocolResult>
|
|
43
|
+
|
|
44
|
+
/** Create a native attachment surface; options reserved for future protocol fields. */
|
|
45
|
+
createNativeAttachment(
|
|
46
|
+
options?: AttachmentEntityOptions,
|
|
47
|
+
): Promise<WebSpatialProtocolResult>
|
|
36
48
|
}
|