@vctrl/embed 0.22.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 +23 -0
- package/LICENSE.md +650 -0
- package/README.md +103 -0
- package/package.json +41 -0
- package/project.json +63 -0
- package/src/embed.ts +362 -0
- package/src/index.ts +28 -0
- package/src/protocol.ts +149 -0
- package/tsconfig.json +19 -0
- package/tsconfig.lib.json +15 -0
- package/vite.config.ts +49 -0
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { ViewerCommand, ViewerInteractionEvent } from '@vctrl/viewer'
|
|
2
|
+
|
|
3
|
+
export const HOSTED_PREVIEW_HOST_SOURCE = 'vectreal-host'
|
|
4
|
+
export const HOSTED_PREVIEW_VIEWER_SOURCE = 'vectreal-preview'
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Incoming messages (parent page → iframe)
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
export interface HostedPreviewPingMessage {
|
|
11
|
+
source: typeof HOSTED_PREVIEW_HOST_SOURCE
|
|
12
|
+
type: 'ping'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface HostedPreviewViewerCommandMessage {
|
|
16
|
+
source: typeof HOSTED_PREVIEW_HOST_SOURCE
|
|
17
|
+
type: 'viewer_command'
|
|
18
|
+
command: ViewerCommand
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HostedPreviewScrollProgressMessage {
|
|
22
|
+
source: typeof HOSTED_PREVIEW_HOST_SOURCE
|
|
23
|
+
type: 'host_scroll_progress'
|
|
24
|
+
progress: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface HostedPreviewHostMessage {
|
|
28
|
+
source: typeof HOSTED_PREVIEW_HOST_SOURCE
|
|
29
|
+
type: 'host_message'
|
|
30
|
+
message: string
|
|
31
|
+
payload?: Record<string, unknown>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type HostedPreviewIncomingMessage =
|
|
35
|
+
| HostedPreviewHostMessage
|
|
36
|
+
| HostedPreviewPingMessage
|
|
37
|
+
| HostedPreviewScrollProgressMessage
|
|
38
|
+
| HostedPreviewViewerCommandMessage
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Outgoing messages (iframe → parent page)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
export interface EmbedCameraDescriptor {
|
|
45
|
+
id: string
|
|
46
|
+
name: string
|
|
47
|
+
fov?: number
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface HostedPreviewPongMessage {
|
|
51
|
+
source: typeof HOSTED_PREVIEW_VIEWER_SOURCE
|
|
52
|
+
type: 'pong'
|
|
53
|
+
sceneId?: string
|
|
54
|
+
cameras: EmbedCameraDescriptor[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface HostedPreviewViewerEventMessage {
|
|
58
|
+
source: typeof HOSTED_PREVIEW_VIEWER_SOURCE
|
|
59
|
+
type: 'viewer_event'
|
|
60
|
+
sceneId?: string
|
|
61
|
+
event: ViewerInteractionEvent
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface HostedPreviewCustomEventMessage {
|
|
65
|
+
source: typeof HOSTED_PREVIEW_VIEWER_SOURCE
|
|
66
|
+
type: 'interaction_event'
|
|
67
|
+
sceneId?: string
|
|
68
|
+
interactionId?: string
|
|
69
|
+
eventName: string
|
|
70
|
+
payload?: Record<string, unknown>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type HostedPreviewOutgoingMessage =
|
|
74
|
+
| HostedPreviewCustomEventMessage
|
|
75
|
+
| HostedPreviewPongMessage
|
|
76
|
+
| HostedPreviewViewerEventMessage
|
|
77
|
+
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Type guards
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
83
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function isViewerCommand(value: unknown): value is ViewerCommand {
|
|
87
|
+
if (!isRecord(value) || typeof value.type !== 'string') {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
switch (value.type) {
|
|
92
|
+
case 'activate_camera':
|
|
93
|
+
return (
|
|
94
|
+
typeof value.cameraId === 'string' && value.cameraId.trim().length > 0
|
|
95
|
+
)
|
|
96
|
+
case 'set_controls_enabled':
|
|
97
|
+
return typeof value.enabled === 'boolean'
|
|
98
|
+
case 'set_auto_rotate':
|
|
99
|
+
return (
|
|
100
|
+
typeof value.enabled === 'boolean' &&
|
|
101
|
+
(value.speed === undefined || typeof value.speed === 'number')
|
|
102
|
+
)
|
|
103
|
+
case 'set_controls_options':
|
|
104
|
+
return (
|
|
105
|
+
(value.zoom === undefined || typeof value.zoom === 'boolean') &&
|
|
106
|
+
(value.pan === undefined || typeof value.pan === 'boolean')
|
|
107
|
+
)
|
|
108
|
+
case 'set_transition':
|
|
109
|
+
return (
|
|
110
|
+
typeof value.transitionType === 'string' &&
|
|
111
|
+
['none', 'linear', 'object_avoidance'].includes(
|
|
112
|
+
value.transitionType as string
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
default:
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function isHostedPreviewIncomingMessage(
|
|
121
|
+
value: unknown
|
|
122
|
+
): value is HostedPreviewIncomingMessage {
|
|
123
|
+
if (
|
|
124
|
+
!isRecord(value) ||
|
|
125
|
+
value.source !== HOSTED_PREVIEW_HOST_SOURCE ||
|
|
126
|
+
typeof value.type !== 'string'
|
|
127
|
+
) {
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
switch (value.type) {
|
|
132
|
+
case 'ping':
|
|
133
|
+
return true
|
|
134
|
+
case 'viewer_command':
|
|
135
|
+
return isViewerCommand(value.command)
|
|
136
|
+
case 'host_scroll_progress':
|
|
137
|
+
return (
|
|
138
|
+
typeof value.progress === 'number' && Number.isFinite(value.progress)
|
|
139
|
+
)
|
|
140
|
+
case 'host_message':
|
|
141
|
+
return (
|
|
142
|
+
typeof value.message === 'string' &&
|
|
143
|
+
value.message.trim().length > 0 &&
|
|
144
|
+
(value.payload === undefined || isRecord(value.payload))
|
|
145
|
+
)
|
|
146
|
+
default:
|
|
147
|
+
return false
|
|
148
|
+
}
|
|
149
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"allowJs": false,
|
|
5
|
+
"esModuleInterop": false,
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
9
|
+
"types": ["vite/client"]
|
|
10
|
+
},
|
|
11
|
+
"files": [],
|
|
12
|
+
"include": [],
|
|
13
|
+
"references": [
|
|
14
|
+
{
|
|
15
|
+
"path": "./tsconfig.lib.json"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"extends": "../../tsconfig.base.json"
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"types": ["node", "vite/client"]
|
|
7
|
+
},
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/*.spec.ts",
|
|
10
|
+
"**/*.test.ts",
|
|
11
|
+
"**/*.spec.js",
|
|
12
|
+
"**/*.test.js"
|
|
13
|
+
],
|
|
14
|
+
"include": ["src/**/*.ts"]
|
|
15
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as path from 'path'
|
|
2
|
+
|
|
3
|
+
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'
|
|
4
|
+
import { defineConfig } from 'vite'
|
|
5
|
+
import dts from 'vite-plugin-dts'
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
root: __dirname,
|
|
9
|
+
cacheDir: '../../node_modules/.vite/packages/@vctrl/embed',
|
|
10
|
+
plugins: [
|
|
11
|
+
nxViteTsPaths(),
|
|
12
|
+
dts({
|
|
13
|
+
entryRoot: 'src',
|
|
14
|
+
tsconfigPath: path.join(__dirname, 'tsconfig.lib.json')
|
|
15
|
+
})
|
|
16
|
+
],
|
|
17
|
+
|
|
18
|
+
build: {
|
|
19
|
+
emptyOutDir: true,
|
|
20
|
+
reportCompressedSize: true,
|
|
21
|
+
commonjsOptions: {
|
|
22
|
+
transformMixedEsModules: true
|
|
23
|
+
},
|
|
24
|
+
lib: {
|
|
25
|
+
entry: 'src/index.ts',
|
|
26
|
+
name: '@vctrl/embed',
|
|
27
|
+
fileName: 'index',
|
|
28
|
+
formats: ['es', 'cjs']
|
|
29
|
+
},
|
|
30
|
+
rollupOptions: {
|
|
31
|
+
output: [
|
|
32
|
+
{
|
|
33
|
+
format: 'es',
|
|
34
|
+
entryFileNames: 'index.js'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
format: 'cjs',
|
|
38
|
+
entryFileNames: 'index.cjs'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
format: 'umd',
|
|
42
|
+
name: 'VectrealEmbed',
|
|
43
|
+
entryFileNames: 'vectreal-embed.umd.js',
|
|
44
|
+
exports: 'named'
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
})
|