@vyr/remote 0.0.1

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 (42) hide show
  1. package/package.json +18 -0
  2. package/src/Bridge.ts +133 -0
  3. package/src/ChangeScriptable.ts +22 -0
  4. package/src/Collection.ts +36 -0
  5. package/src/RemoteExecutor.ts +514 -0
  6. package/src/RemoteInvoker.ts +72 -0
  7. package/src/RemoteProcess.ts +87 -0
  8. package/src/index.ts +7 -0
  9. package/src/job/IJob.ts +6 -0
  10. package/src/job/Job.ts +16 -0
  11. package/src/job/asset/add.ts +23 -0
  12. package/src/job/asset/dragdrap.ts +24 -0
  13. package/src/job/asset/index.ts +6 -0
  14. package/src/job/asset/load.ts +20 -0
  15. package/src/job/asset/remove.ts +20 -0
  16. package/src/job/asset/unload.ts +18 -0
  17. package/src/job/asset/update.ts +22 -0
  18. package/src/job/bridge/connection.ts +18 -0
  19. package/src/job/bridge/disconnect.ts +29 -0
  20. package/src/job/bridge/index.ts +2 -0
  21. package/src/job/index.ts +1 -0
  22. package/src/job/invoke/alert.ts +20 -0
  23. package/src/job/invoke/animation.ts +45 -0
  24. package/src/job/invoke/event.ts +40 -0
  25. package/src/job/invoke/index.ts +8 -0
  26. package/src/job/invoke/orbit.ts +20 -0
  27. package/src/job/invoke/pick.ts +15 -0
  28. package/src/job/invoke/properties.ts +43 -0
  29. package/src/job/invoke/screenshot.ts +35 -0
  30. package/src/job/invoke/transform.ts +36 -0
  31. package/src/job/scene/add.ts +22 -0
  32. package/src/job/scene/dragdrap.ts +23 -0
  33. package/src/job/scene/index.ts +6 -0
  34. package/src/job/scene/load.ts +19 -0
  35. package/src/job/scene/remove.ts +19 -0
  36. package/src/job/scene/unload.ts +17 -0
  37. package/src/job/scene/update.ts +20 -0
  38. package/src/locale/Language.ts +10 -0
  39. package/src/locale/LanguageProvider.ts +15 -0
  40. package/src/locale/index.ts +2 -0
  41. package/src/utils/index.ts +85 -0
  42. package/src/utils/screenshot.ts +20 -0
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@vyr/remote",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "./src/index.ts",
6
+ "author": "",
7
+ "license": "MIT",
8
+ "dependencies": {
9
+ "dom-to-image": "^2.6.0",
10
+ "@vyr/locale": "0.0.1",
11
+ "@vyr/declare": "0.0.1",
12
+ "@vyr/engine": "0.0.1"
13
+ },
14
+ "files": [
15
+ "package.json",
16
+ "src/"
17
+ ]
18
+ }
package/src/Bridge.ts ADDED
@@ -0,0 +1,133 @@
1
+ import { AsyncTask, Descriptor, Listener } from "@vyr/engine"
2
+ import { Job } from "./job"
3
+
4
+ interface RemoteConfig {
5
+ /**代理的唯一标识 */
6
+ id: string
7
+ /**远程服务的运行环境 */
8
+ env: 'window' | 'iframe'
9
+ /**远程服务是否执行任务 */
10
+ execute: boolean
11
+ /**是否启用远程服务的调用功能 */
12
+ invoke: boolean
13
+ /**远程服务运行后立即渲染的场景 */
14
+ scene?: string
15
+ }
16
+
17
+ interface BridgeConfig {
18
+ id: string
19
+ args?: any[]
20
+ useRemote?: () => Promise<Window>
21
+ autoConnect?: boolean
22
+ }
23
+
24
+ interface BridgeListener {
25
+ keydown: (event: KeyboardEvent) => void
26
+ keyup: (event: KeyboardEvent) => void
27
+ mouseup: (event: MouseEvent) => void
28
+ close: (args: {}) => void
29
+ }
30
+
31
+ /**
32
+ * 用于在远程环境之间传递信息的桥梁
33
+ */
34
+ class Bridge {
35
+ static readonly key = '__VYR_RUNTIME_REMOTE'
36
+ static createBaseUrl() {
37
+ const { protocol, hostname, port } = window.location
38
+ return `${protocol}//${hostname}:${port}`
39
+ }
40
+ private _id
41
+ private _args
42
+ private _remote!: Window
43
+ private _closeId = -1
44
+ private _readyId = -1
45
+ private _listener = new Listener<BridgeListener>()
46
+ connected = new AsyncTask()
47
+ comm
48
+
49
+ constructor(config: BridgeConfig) {
50
+ this._id = config.id
51
+ this._args = config.args ?? []
52
+ this.comm = Bridge.createBaseUrl()
53
+ window.addEventListener('message', this.onReceive)
54
+ window.addEventListener('beforeunload', () => this.send(new Job.bridge.disconnect.Response({})))
55
+ if (config.useRemote) config.useRemote().then(this.checkReady)
56
+ }
57
+
58
+ private pipe = (remote: Window, message: Job) => {
59
+ remote.postMessage({ key: Bridge.key, id: this._id, message: Descriptor.serialization(message) }, this.comm)
60
+ }
61
+
62
+ private checkReady = (remote: Window) => {
63
+ if (this._remote) return
64
+ clearTimeout(this._readyId)
65
+ //@ts-ignore
66
+ this._readyId = setTimeout(() => this.checkReady(remote), 1000)
67
+ this.pipe(remote, new Job.bridge.connection.Response({}))
68
+ }
69
+
70
+ private isBridgeMessage = (event: MessageEvent) => {
71
+ return event.data.key === Bridge.key && event.data.id === this._id
72
+ }
73
+ private checkWindowClosed = () => {
74
+ if (this._remote.closed === false) return
75
+ this._listener.trigger('close', {})
76
+ }
77
+ private onDisconnect = () => {
78
+ clearTimeout(this._closeId)
79
+ this._closeId = setTimeout(this.checkWindowClosed, 5000) as unknown as number
80
+ this.connected = new AsyncTask()
81
+ const remote = this._remote
82
+ //@ts-ignore
83
+ this._remote = null
84
+ this.checkReady(remote)
85
+ }
86
+ private onReceive = (event: MessageEvent) => {
87
+ if (this.isBridgeMessage(event) === false) return
88
+ const task = Descriptor.deserialization<Job>(event.data.message)
89
+ switch (task.method) {
90
+ case Job.bridge.connection.Method:
91
+ clearTimeout(this._readyId)
92
+ this._remote = event.source as Window
93
+ this.connected.run()
94
+ const params = task.params as { stop?: boolean }
95
+ if (params.stop === undefined) {
96
+ this.send(new Job.bridge.connection.Response({ stop: true }))
97
+ }
98
+ break;
99
+ case Job.bridge.disconnect.Method:
100
+ this.onDisconnect()
101
+ break;
102
+ default:
103
+ this._listener.trigger(task.method, task, ...this._args)
104
+ break;
105
+ }
106
+ }
107
+
108
+ listen<T extends keyof BridgeListener>(method: T, cb: BridgeListener[T]): void
109
+ listen(method: string, cb: (...args: any[]) => void): void
110
+ listen(method: string, cb: (...args: any[]) => void) {
111
+ this._listener.listen(method, cb)
112
+ }
113
+
114
+ unlisten<T extends keyof BridgeListener>(method: T, cb: BridgeListener[T]): void
115
+ unlisten(method: string, cb: (...args: any[]) => void): void
116
+ unlisten(method: string, cb: (...args: any[]) => void) {
117
+ this._listener.unlisten(method, cb)
118
+ }
119
+
120
+ async send(message: Job) {
121
+ const serialization = Descriptor.serialization(message)
122
+ await this.connected.done()
123
+ this._remote.postMessage({ key: Bridge.key, id: this._id, message: serialization }, this.comm)
124
+ }
125
+
126
+ async close() {
127
+ await this.connected.done()
128
+ this._remote.close()
129
+ this._listener.trigger('close', {})
130
+ }
131
+ }
132
+
133
+ export { RemoteConfig, Bridge }
@@ -0,0 +1,22 @@
1
+ import { Descriptor, Graphics, HTMLTransformControllerChangeArgs, HTMLTransformControllerDescriptor, Scriptable } from "@vyr/engine";
2
+ import { RemoteProcess } from "./RemoteProcess";
3
+ import { Job } from "./job";
4
+
5
+ class ChangeScriptable extends Scriptable {
6
+
7
+ execute(descriptor: HTMLTransformControllerDescriptor, graphics: Graphics, args: HTMLTransformControllerChangeArgs) {
8
+ const process = RemoteProcess.get(graphics.engine)
9
+ if (process === null) return
10
+
11
+ if (args.event.type === 'contextmenu') {
12
+ process.bridge.send(new Job.invoke.pick.Response({ descriptor: '' }))
13
+ } else {
14
+ const target = Descriptor.get(args.event.target) as Descriptor
15
+ if (target === null) return
16
+ const params = { eventType: args.event.type, target: args.event.target, descriptor: target.clone(false) }
17
+ process.bridge.send(new Job.invoke.transform.Response(params))
18
+ }
19
+ }
20
+ }
21
+
22
+ export default ChangeScriptable
@@ -0,0 +1,36 @@
1
+ interface Item {
2
+ [k: string]: any
3
+ }
4
+
5
+ class Collection {
6
+ private instance = new Map<Item, Item>()
7
+ private map = new Map<Item, Item>()
8
+
9
+ set(key: Item, value: Item) {
10
+ this.instance.set(key, value)
11
+ this.map.set(value, key)
12
+ }
13
+
14
+ get<T extends Item = Item>(key: Item) {
15
+ return (this.instance.get(key) ?? null) as T | null
16
+ }
17
+
18
+ getByMap<T extends Item = Item>(key: Item) {
19
+ return (this.map.get(key) ?? null) as T | null
20
+ }
21
+
22
+ delete(key: Item) {
23
+ const value = this.instance.get(key)
24
+ if (value === undefined) return
25
+ this.instance.delete(key)
26
+ this.map.delete(value)
27
+ }
28
+
29
+ values<T extends Item = Item>() {
30
+ return [...this.instance.values()] as T[]
31
+ }
32
+ }
33
+
34
+ export {
35
+ Collection
36
+ }