@webspatial/core-sdk 1.0.5 → 1.2.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 +16 -0
- package/dist/iife/index.d.ts +29 -32
- package/dist/iife/index.global.js +3 -3
- package/dist/iife/index.global.js.map +1 -1
- package/dist/index.d.ts +29 -32
- package/dist/index.js +170 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/JSBCommand.ts +1 -1
- package/src/SpatialScene.ts +2 -2
- package/src/SpatialSession.ts +7 -4
- package/src/SpatializedElement.ts +13 -53
- package/src/SpatializedStatic3DElement.ts +1 -1
- package/src/WebMsgCommand.ts +8 -3
- package/src/coverage-boost.test.ts +1060 -0
- package/src/jsbcommand.coverage.test.ts +542 -0
- package/src/platform-adapter/android/AndroidPlatform.ts +2 -2
- package/src/platform-adapter/index.ts +31 -3
- package/src/platform-adapter/vision-os/VisionOSPlatform.ts +0 -1
- package/src/platform-adapter/xr/XRPlatform.ts +133 -0
- package/src/reality/component/index.ts +1 -1
- package/src/reality/entity/SpatialEntity.ts +6 -14
- package/src/reality/entity/index.ts +1 -1
- package/src/reality/geometry/SpatialBoxGeometry.ts +4 -1
- package/src/reality/geometry/index.ts +1 -1
- package/src/reality/material/index.ts +1 -1
- package/src/reality/resource/index.ts +1 -1
- package/src/scene-polyfill.ts +25 -9
- package/src/types/internal.ts +5 -5
- package/src/types/types.ts +23 -17
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { PlatformAbility, CommandResult } from '../interface'
|
|
2
|
+
import {
|
|
3
|
+
CommandResultFailure,
|
|
4
|
+
CommandResultSuccess,
|
|
5
|
+
} from '../CommandResultUtils'
|
|
6
|
+
import { SpatialWebEvent } from '../../SpatialWebEvent'
|
|
7
|
+
|
|
8
|
+
interface JSBResponse {
|
|
9
|
+
success: boolean
|
|
10
|
+
data: any
|
|
11
|
+
}
|
|
12
|
+
type JSBError = {
|
|
13
|
+
code: string
|
|
14
|
+
message: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let requestId = 0
|
|
18
|
+
|
|
19
|
+
const MAX_ID = 100000
|
|
20
|
+
|
|
21
|
+
function nextRequestId() {
|
|
22
|
+
requestId = (requestId + 1) % MAX_ID
|
|
23
|
+
return `rId_${requestId}`
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class XRPlatform implements PlatformAbility {
|
|
27
|
+
async callJSB(cmd: string, msg: string): Promise<CommandResult> {
|
|
28
|
+
// android JS Bridge interface only support sync invoking
|
|
29
|
+
// in order to implement promise API, register every request by requestId and remove when resolve/reject.
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
try {
|
|
32
|
+
const rId = nextRequestId()
|
|
33
|
+
|
|
34
|
+
SpatialWebEvent.addEventReceiver(rId, (result: JSBResponse) => {
|
|
35
|
+
SpatialWebEvent.removeEventReceiver(rId)
|
|
36
|
+
if (result.success) {
|
|
37
|
+
resolve(CommandResultSuccess(result.data))
|
|
38
|
+
} else {
|
|
39
|
+
const { code, message } = result.data as JSBError
|
|
40
|
+
resolve(CommandResultFailure(code, message))
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const ans = window.webspatialBridge.postMessage(rId, cmd, msg)
|
|
45
|
+
if (ans !== '') {
|
|
46
|
+
SpatialWebEvent.removeEventReceiver(rId)
|
|
47
|
+
// sync call
|
|
48
|
+
const result = JSON.parse(ans) as JSBResponse
|
|
49
|
+
if (result.success) {
|
|
50
|
+
resolve(CommandResultSuccess(result.data))
|
|
51
|
+
} else {
|
|
52
|
+
const { code, message } = result.data as JSBError
|
|
53
|
+
resolve(CommandResultFailure(code, message))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} catch (error: unknown) {
|
|
57
|
+
console.error(`XRPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`)
|
|
58
|
+
const { code, message } = error as JSBError
|
|
59
|
+
resolve(CommandResultFailure(code, message))
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async callWebSpatialProtocol(
|
|
65
|
+
command: string,
|
|
66
|
+
query?: string,
|
|
67
|
+
target?: string,
|
|
68
|
+
features?: string,
|
|
69
|
+
): Promise<CommandResult> {
|
|
70
|
+
// Waiting for request to create spatial div
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
const createdId = nextRequestId()
|
|
73
|
+
try {
|
|
74
|
+
let windowProxy: any = null
|
|
75
|
+
SpatialWebEvent.addEventReceiver(
|
|
76
|
+
createdId,
|
|
77
|
+
(result: { spatialId: string }) => {
|
|
78
|
+
console.log('createdId', createdId, result.spatialId)
|
|
79
|
+
resolve(
|
|
80
|
+
CommandResultSuccess({
|
|
81
|
+
windowProxy: windowProxy,
|
|
82
|
+
id: result.spatialId,
|
|
83
|
+
}),
|
|
84
|
+
)
|
|
85
|
+
SpatialWebEvent.removeEventReceiver(createdId)
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
windowProxy = this.openWindow(
|
|
89
|
+
command,
|
|
90
|
+
query,
|
|
91
|
+
target,
|
|
92
|
+
features,
|
|
93
|
+
).windowProxy
|
|
94
|
+
windowProxy?.open(`about:blank?rid=${createdId}`, '_self')
|
|
95
|
+
} catch (error: unknown) {
|
|
96
|
+
console.error(`open window error: ${error}`)
|
|
97
|
+
const { code, message } = error as JSBError
|
|
98
|
+
SpatialWebEvent.removeEventReceiver(createdId)
|
|
99
|
+
resolve(CommandResultFailure(code, message))
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
callWebSpatialProtocolSync(
|
|
105
|
+
command: string,
|
|
106
|
+
query?: string,
|
|
107
|
+
target?: string,
|
|
108
|
+
features?: string,
|
|
109
|
+
): CommandResult {
|
|
110
|
+
const { spatialId: id = '', windowProxy } = this.openWindow(
|
|
111
|
+
command,
|
|
112
|
+
query,
|
|
113
|
+
target,
|
|
114
|
+
features,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return CommandResultSuccess({ windowProxy, id })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private openWindow(
|
|
121
|
+
command: string,
|
|
122
|
+
query?: string,
|
|
123
|
+
target?: string,
|
|
124
|
+
features?: string,
|
|
125
|
+
) {
|
|
126
|
+
const windowProxy = window.open(
|
|
127
|
+
`webspatial://${command}?${query || ''}`,
|
|
128
|
+
target,
|
|
129
|
+
features,
|
|
130
|
+
)
|
|
131
|
+
return { spatialId: '', windowProxy }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './SpatialComponent'
|
|
2
|
-
export * from './ModelComponent'
|
|
2
|
+
export * from './ModelComponent'
|
|
@@ -164,13 +164,7 @@ export class SpatialEntity extends SpatialObject {
|
|
|
164
164
|
this.dispatchEvent(evt)
|
|
165
165
|
}
|
|
166
166
|
// rotate
|
|
167
|
-
else if (type === SpatialWebMsgType.
|
|
168
|
-
const evt = createSpatialEvent(
|
|
169
|
-
SpatialWebMsgType.spatialrotatestart,
|
|
170
|
-
(data as SpatialRotateMsg).detail,
|
|
171
|
-
)
|
|
172
|
-
this.dispatchEvent(evt)
|
|
173
|
-
} else if (type === SpatialWebMsgType.spatialrotate) {
|
|
167
|
+
else if (type === SpatialWebMsgType.spatialrotate) {
|
|
174
168
|
const evt = createSpatialEvent(
|
|
175
169
|
SpatialWebMsgType.spatialrotate,
|
|
176
170
|
(data as SpatialRotateMsg).detail,
|
|
@@ -184,13 +178,7 @@ export class SpatialEntity extends SpatialObject {
|
|
|
184
178
|
this.dispatchEvent(evt)
|
|
185
179
|
}
|
|
186
180
|
// magnify
|
|
187
|
-
else if (type === SpatialWebMsgType.
|
|
188
|
-
const evt = createSpatialEvent(
|
|
189
|
-
SpatialWebMsgType.spatialmagnifystart,
|
|
190
|
-
(data as SpatialMagnifyMsg).detail,
|
|
191
|
-
)
|
|
192
|
-
this.dispatchEvent(evt)
|
|
193
|
-
} else if (type === SpatialWebMsgType.spatialmagnify) {
|
|
181
|
+
else if (type === SpatialWebMsgType.spatialmagnify) {
|
|
194
182
|
const evt = createSpatialEvent(
|
|
195
183
|
SpatialWebMsgType.spatialmagnify,
|
|
196
184
|
(data as SpatialMagnifyMsg).detail,
|
|
@@ -206,6 +194,10 @@ export class SpatialEntity extends SpatialObject {
|
|
|
206
194
|
}
|
|
207
195
|
|
|
208
196
|
dispatchEvent(evt: CustomEvent) {
|
|
197
|
+
// Set origin once at the first dispatch in the bubbling chain
|
|
198
|
+
if (!(evt as any).__origin) {
|
|
199
|
+
Object.defineProperty(evt, '__origin', { value: this, enumerable: false })
|
|
200
|
+
}
|
|
209
201
|
this.events[evt.type]?.(evt)
|
|
210
202
|
if (evt.bubbles && !evt.cancelBubble) {
|
|
211
203
|
if (this.parent && this.parent instanceof SpatialEntity) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './SpatialEntity'
|
|
2
|
-
export * from './SpatialModelEntity'
|
|
2
|
+
export * from './SpatialModelEntity'
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
SpatialBoxGeometryOptions,
|
|
3
|
+
SpatialGeometryType,
|
|
4
|
+
} from '../../types/types'
|
|
2
5
|
import { SpatialGeometry } from './SpatialGeometry'
|
|
3
6
|
|
|
4
7
|
export class SpatialBoxGeometry extends SpatialGeometry {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './SpatialUnlitMaterial'
|
|
2
|
-
export * from './SpatialMaterial'
|
|
2
|
+
export * from './SpatialMaterial'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './SpatialModelAsset'
|
|
1
|
+
export * from './SpatialModelAsset'
|
package/src/scene-polyfill.ts
CHANGED
|
@@ -50,17 +50,37 @@ class SceneManager {
|
|
|
50
50
|
return this.configMap[name]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// Ensure URL is absolute; only convert when a relative path is provided
|
|
54
|
+
// - Keep external and special schemes untouched (http, https, data, blob, about, file, mailto, etc.)
|
|
55
|
+
// - Handle protocol-relative URLs (//example.com/path)
|
|
56
|
+
// - Resolve relative paths against document.baseURI (respects <base href>)
|
|
57
|
+
private ensureAbsoluteUrl(raw?: string): string | undefined {
|
|
58
|
+
if (!raw) return raw
|
|
59
|
+
// Already has a scheme (includes internal webspatial:// which is handled earlier)
|
|
60
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(raw)) {
|
|
61
|
+
return raw
|
|
62
|
+
}
|
|
63
|
+
// Protocol-relative URL
|
|
64
|
+
if (raw.startsWith('//')) {
|
|
65
|
+
return `${window.location.protocol}${raw}`
|
|
66
|
+
}
|
|
67
|
+
// Resolve against base URI
|
|
68
|
+
try {
|
|
69
|
+
return new URL(raw, document.baseURI).toString()
|
|
70
|
+
} catch {
|
|
71
|
+
// Fallback: leave unchanged
|
|
72
|
+
return raw
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
53
76
|
private open = (url?: string, target?: string, features?: string) => {
|
|
54
77
|
// bypass internal
|
|
55
78
|
if (url?.startsWith(INTERNAL_SCHEMA_PREFIX)) {
|
|
56
79
|
return this.originalOpen(url, target, features)
|
|
57
80
|
}
|
|
58
81
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
if (!url?.startsWith(prefix)) {
|
|
62
|
-
url = prefix + url
|
|
63
|
-
}
|
|
82
|
+
// Normalize only relative URLs to absolute for platform handling
|
|
83
|
+
url = this.ensureAbsoluteUrl(url)
|
|
64
84
|
|
|
65
85
|
// if target is special
|
|
66
86
|
if (target === '_self' || target === '_parent' || target === '_top') {
|
|
@@ -72,10 +92,6 @@ class SceneManager {
|
|
|
72
92
|
const cmd = new createSpatialSceneCommand(url!, cfg, target, features)
|
|
73
93
|
const result = cmd.executeSync()
|
|
74
94
|
|
|
75
|
-
if (typeof target === 'string' && this.configMap[target]) {
|
|
76
|
-
delete this.configMap[target]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
95
|
const id = result.data?.id
|
|
80
96
|
|
|
81
97
|
if (id) {
|
package/src/types/internal.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SpatialSceneCreationOptions, SpatialSceneType } from
|
|
1
|
+
import { SpatialSceneCreationOptions, SpatialSceneType } from './types'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
3
|
+
export type SpatialSceneCreationOptionsInternal =
|
|
4
|
+
SpatialSceneCreationOptions & {
|
|
5
|
+
type: SpatialSceneType
|
|
6
|
+
}
|
|
7
7
|
export enum SpatialSceneState {
|
|
8
8
|
idle = 'idle',
|
|
9
9
|
pending = 'pending',
|
package/src/types/types.ts
CHANGED
|
@@ -11,6 +11,13 @@ export interface Vec3 {
|
|
|
11
11
|
|
|
12
12
|
export type Point3D = Vec3
|
|
13
13
|
|
|
14
|
+
export interface Quaternion {
|
|
15
|
+
x: number
|
|
16
|
+
y: number
|
|
17
|
+
z: number
|
|
18
|
+
w: number
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Material type for SpatialDiv or HTML document.
|
|
16
23
|
*
|
|
@@ -69,10 +76,8 @@ export interface SpatializedElementProperties {
|
|
|
69
76
|
enableDragStartGesture: boolean
|
|
70
77
|
enableDragGesture: boolean
|
|
71
78
|
enableDragEndGesture: boolean
|
|
72
|
-
enableRotateStartGesture: boolean
|
|
73
79
|
enableRotateGesture: boolean
|
|
74
80
|
enableRotateEndGesture: boolean
|
|
75
|
-
enableMagnifyStartGesture: boolean
|
|
76
81
|
enableMagnifyGesture: boolean
|
|
77
82
|
enableMagnifyEndGesture: boolean
|
|
78
83
|
}
|
|
@@ -343,38 +348,39 @@ export interface SpatialTapEventDetail {
|
|
|
343
348
|
|
|
344
349
|
export type SpatialTapEvent = CustomEvent<SpatialTapEventDetail>
|
|
345
350
|
|
|
346
|
-
export interface
|
|
347
|
-
location3D: Point3D
|
|
351
|
+
export interface SpatialDragStartEventDetail {
|
|
348
352
|
startLocation3D: Point3D
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface SpatialDragEventDetail {
|
|
349
356
|
translation3D: Vec3
|
|
350
|
-
predictedEndTranslation3D: Vec3
|
|
351
|
-
predictedEndLocation3D: Point3D
|
|
352
|
-
velocity: Size
|
|
353
357
|
}
|
|
354
358
|
|
|
355
|
-
export
|
|
359
|
+
export interface SpatialDragEndEventDetail {}
|
|
356
360
|
|
|
357
|
-
export type
|
|
361
|
+
export type SpatialDragStartEvent = CustomEvent<SpatialDragStartEventDetail>
|
|
362
|
+
|
|
363
|
+
export type SpatialDragEvent = CustomEvent<SpatialDragEventDetail>
|
|
358
364
|
|
|
365
|
+
export type SpatialDragEndEvent = CustomEvent<SpatialDragEndEventDetail>
|
|
359
366
|
export interface SpatialRotateEventDetail {
|
|
360
|
-
|
|
361
|
-
startAnchor3D: Vec3
|
|
362
|
-
startLocation3D: Point3D
|
|
367
|
+
quaternion: Quaternion
|
|
363
368
|
}
|
|
364
369
|
|
|
370
|
+
export interface SpatialRotateEndEventDetail {}
|
|
371
|
+
|
|
365
372
|
export type SpatialRotateEvent = CustomEvent<SpatialRotateEventDetail>
|
|
366
373
|
|
|
367
|
-
export type SpatialRotateEndEvent =
|
|
374
|
+
export type SpatialRotateEndEvent = CustomEvent<SpatialRotateEndEventDetail>
|
|
368
375
|
|
|
369
376
|
export interface SpatialMagnifyEventDetail {
|
|
370
377
|
magnification: number
|
|
371
|
-
velocity: number
|
|
372
|
-
startAnchor3D: Vec3
|
|
373
|
-
startLocation3D: Point3D
|
|
374
378
|
}
|
|
375
379
|
|
|
380
|
+
export interface SpatialMagnifyEndEventDetail {}
|
|
381
|
+
|
|
376
382
|
export type SpatialMagnifyEvent = CustomEvent<SpatialMagnifyEventDetail>
|
|
377
383
|
|
|
378
|
-
export type SpatialMagnifyEndEvent =
|
|
384
|
+
export type SpatialMagnifyEndEvent = CustomEvent<SpatialMagnifyEndEventDetail>
|
|
379
385
|
|
|
380
386
|
export type SpatialEntityOrReality = SpatialEntity | SpatializedDynamic3DElement
|