@zimi/remote 0.2.1 → 0.2.3
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/LICENSE.md +21 -21
- package/README.md +289 -285
- package/dist/adaptor.d.mts +33 -0
- package/dist/adaptor.d.ts +5 -4
- package/dist/adaptor.js +1 -1
- package/dist/adaptor.js.map +1 -1
- package/dist/adaptor.mjs +1 -0
- package/dist/adaptor.mjs.map +1 -0
- package/dist/adaptors/dao3/client.d.mts +39 -0
- package/dist/adaptors/dao3/client.d.ts +5 -3
- package/dist/adaptors/dao3/client.js +1 -44
- package/dist/adaptors/dao3/client.js.map +1 -1
- package/dist/adaptors/dao3/client.mjs +2 -0
- package/dist/adaptors/dao3/client.mjs.map +1 -0
- package/dist/adaptors/dao3/server.d.mts +82 -0
- package/dist/adaptors/dao3/server.d.ts +5 -3
- package/dist/adaptors/dao3/server.js +1 -104
- package/dist/adaptors/dao3/server.js.map +1 -1
- package/dist/adaptors/dao3/server.mjs +2 -0
- package/dist/adaptors/dao3/server.mjs.map +1 -0
- package/dist/adaptors/electron/constants.d.mts +5 -0
- package/dist/adaptors/electron/constants.d.ts +5 -0
- package/dist/adaptors/electron/constants.js +2 -0
- package/dist/adaptors/electron/constants.js.map +1 -0
- package/dist/adaptors/electron/constants.mjs +2 -0
- package/dist/adaptors/electron/constants.mjs.map +1 -0
- package/dist/adaptors/electron/main.d.mts +10 -0
- package/dist/adaptors/electron/main.d.ts +10 -0
- package/dist/adaptors/electron/main.js +2 -0
- package/dist/adaptors/electron/main.js.map +1 -0
- package/dist/adaptors/electron/main.mjs +2 -0
- package/dist/adaptors/electron/main.mjs.map +1 -0
- package/dist/adaptors/electron/messenger.d.mts +8 -0
- package/dist/adaptors/electron/messenger.d.ts +8 -0
- package/dist/adaptors/electron/messenger.js +2 -0
- package/dist/adaptors/electron/messenger.js.map +1 -0
- package/dist/adaptors/electron/messenger.mjs +2 -0
- package/dist/adaptors/electron/messenger.mjs.map +1 -0
- package/dist/adaptors/electron/preload.d.mts +6 -0
- package/dist/adaptors/electron/preload.d.ts +6 -0
- package/dist/adaptors/electron/preload.js +2 -0
- package/dist/adaptors/electron/preload.js.map +1 -0
- package/dist/adaptors/electron/preload.mjs +2 -0
- package/dist/adaptors/electron/preload.mjs.map +1 -0
- package/dist/adaptors/electron/renderer.d.mts +9 -0
- package/dist/adaptors/electron/renderer.d.ts +9 -0
- package/dist/adaptors/electron/renderer.js +2 -0
- package/dist/adaptors/electron/renderer.js.map +1 -0
- package/dist/adaptors/electron/renderer.mjs +2 -0
- package/dist/adaptors/electron/renderer.mjs.map +1 -0
- package/dist/adaptors/http.d.mts +15 -0
- package/dist/adaptors/http.d.ts +6 -4
- package/dist/adaptors/http.js +1 -26
- package/dist/adaptors/http.js.map +1 -1
- package/dist/adaptors/http.mjs +2 -0
- package/dist/adaptors/http.mjs.map +1 -0
- package/dist/adaptors/iframe.d.mts +7 -0
- package/dist/adaptors/iframe.d.ts +5 -2
- package/dist/adaptors/iframe.js +1 -38
- package/dist/adaptors/iframe.js.map +1 -1
- package/dist/adaptors/iframe.mjs +2 -0
- package/dist/adaptors/iframe.mjs.map +1 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -10
- package/dist/index.js +1 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/remote.d.mts +81 -0
- package/dist/remote.d.ts +6 -4
- package/dist/remote.js +1 -196
- package/dist/remote.js.map +1 -1
- package/dist/remote.mjs +2 -0
- package/dist/remote.mjs.map +1 -0
- package/dist/remoteValue/exposeToRemote.d.mts +43 -0
- package/dist/remoteValue/exposeToRemote.d.ts +7 -5
- package/dist/remoteValue/exposeToRemote.js +1 -52
- package/dist/remoteValue/exposeToRemote.js.map +1 -1
- package/dist/remoteValue/exposeToRemote.mjs +2 -0
- package/dist/remoteValue/exposeToRemote.mjs.map +1 -0
- package/dist/remoteValue/remoteValue.d.mts +29 -0
- package/dist/remoteValue/remoteValue.d.ts +6 -4
- package/dist/remoteValue/remoteValue.js +1 -67
- package/dist/remoteValue/remoteValue.js.map +1 -1
- package/dist/remoteValue/remoteValue.mjs +2 -0
- package/dist/remoteValue/remoteValue.mjs.map +1 -0
- package/dist/remoteValue/type.d.mts +67 -0
- package/dist/remoteValue/type.d.ts +20 -19
- package/dist/remoteValue/type.js +1 -1
- package/dist/remoteValue/type.js.map +1 -1
- package/dist/remoteValue/type.mjs +1 -0
- package/dist/remoteValue/type.mjs.map +1 -0
- package/dist/response.d.mts +105 -0
- package/dist/response.d.ts +6 -5
- package/dist/response.js +1 -154
- package/dist/response.js.map +1 -1
- package/dist/response.mjs +2 -0
- package/dist/response.mjs.map +1 -0
- package/package.json +13 -6
- package/src/adaptor.ts +34 -34
- package/src/adaptors/dao3/client.ts +53 -53
- package/src/adaptors/dao3/server.ts +136 -136
- package/src/adaptors/electron/constants.ts +3 -0
- package/src/adaptors/electron/main.ts +59 -0
- package/src/adaptors/electron/messenger.ts +13 -0
- package/src/adaptors/electron/preload.ts +21 -0
- package/src/adaptors/electron/renderer.ts +52 -0
- package/src/adaptors/http.ts +31 -31
- package/src/adaptors/iframe.ts +47 -47
- package/src/index.ts +5 -0
- package/src/remote.ts +263 -260
- package/src/remoteValue/exposeToRemote.ts +102 -102
- package/src/remoteValue/remoteValue.ts +94 -94
- package/src/remoteValue/type.ts +124 -124
- package/src/response.ts +170 -170
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
import EventEmitter from 'eventemitter3'
|
|
2
|
-
import { isRemoteAdaptorData } from '../../remote'
|
|
3
|
-
import { isRemoteValueEvent } from '../../remoteValue/exposeToRemote'
|
|
4
|
-
import { type AdaptorPackageData } from '../../adaptor'
|
|
5
|
-
|
|
6
|
-
interface GamePlayerEntityLike {
|
|
7
|
-
player: {
|
|
8
|
-
userKey: string
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface RemoteChannel<T extends GamePlayerEntityLike> {
|
|
13
|
-
onServerEvent(fn: (e: { args: unknown; entity: T }) => void): void
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
|
|
18
|
-
* ```ts
|
|
19
|
-
* const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
|
|
20
|
-
*
|
|
21
|
-
* world.onPlayerLeave(
|
|
22
|
-
* remoteManager.onPlayerLeave.bind(remoteManager)
|
|
23
|
-
* )
|
|
24
|
-
*
|
|
25
|
-
* export const remoteAdaptor = {
|
|
26
|
-
* every: remoteManager.onEvery.bind(remoteManager),
|
|
27
|
-
* off: remoteManager.off.bind(remoteManager),
|
|
28
|
-
* on: remoteManager.on.bind(remoteManager),
|
|
29
|
-
* once: remoteManager.once.bind(remoteManager),
|
|
30
|
-
* emit: (e) => {
|
|
31
|
-
* const entity = remoteManager.getEntity(e.targetDeviceId)
|
|
32
|
-
* if (!entity) {
|
|
33
|
-
* console.error('entity not found')
|
|
34
|
-
* return
|
|
35
|
-
* }
|
|
36
|
-
* remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
|
|
37
|
-
* },
|
|
38
|
-
* } satisfies Adaptor
|
|
39
|
-
*
|
|
40
|
-
* export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(
|
|
41
|
-
* remoteAdaptor,
|
|
42
|
-
* {
|
|
43
|
-
* deviceId: 'server',
|
|
44
|
-
* }
|
|
45
|
-
* )
|
|
46
|
-
*
|
|
47
|
-
* remote.register('initConnection', async () => {
|
|
48
|
-
* // 什么也不干,单纯的让客户端在服务端“备案”
|
|
49
|
-
* })
|
|
50
|
-
*
|
|
51
|
-
* export const getEntity = remoteManager.getEntity.bind(remoteManager)
|
|
52
|
-
* export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)
|
|
53
|
-
* export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)
|
|
54
|
-
* export const remoteTo = remoteManager.remoteTo.bind(remoteManager)
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
export class ServerSideRemoteChannelEventManager<
|
|
58
|
-
T extends GamePlayerEntityLike,
|
|
59
|
-
> extends EventEmitter<{
|
|
60
|
-
[key: string]: [AdaptorPackageData]
|
|
61
|
-
}> {
|
|
62
|
-
entityMap: [string, T][] = []
|
|
63
|
-
|
|
64
|
-
constructor(remoteChannel: RemoteChannel<T>) {
|
|
65
|
-
super()
|
|
66
|
-
remoteChannel.onServerEvent((e) => {
|
|
67
|
-
const { args } = e
|
|
68
|
-
if (!isRemoteAdaptorData(args)) {
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
const prevItem = this.entityMap.find(
|
|
72
|
-
(item) => item[1].player.userKey === e.entity.player.userKey
|
|
73
|
-
)
|
|
74
|
-
if (prevItem) {
|
|
75
|
-
prevItem[0] = args.deviceId
|
|
76
|
-
prevItem[1] = e.entity
|
|
77
|
-
} else {
|
|
78
|
-
this.entityMap.push([args.deviceId, e.entity])
|
|
79
|
-
}
|
|
80
|
-
if (!isRemoteValueEvent(args.name)) {
|
|
81
|
-
this.emit('__remote_every__', args)
|
|
82
|
-
}
|
|
83
|
-
this.emit(args.name, args)
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
onPlayerLeave(e: { entity: T }) {
|
|
88
|
-
this.entityMap = this.entityMap.filter(
|
|
89
|
-
(item) => item[1].player.userKey !== e.entity.player.userKey
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
onEvery(fn: (args: AdaptorPackageData) => void): void {
|
|
94
|
-
this.on('__remote_every__', fn)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
waitForRegister(entity: T) {
|
|
98
|
-
return new Promise<void>((resolve) => {
|
|
99
|
-
if (
|
|
100
|
-
this.entityMap.some(
|
|
101
|
-
([_, en]) => en.player.userKey === entity.player.userKey
|
|
102
|
-
)
|
|
103
|
-
) {
|
|
104
|
-
resolve()
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
this.once('__remote_every__', () => {
|
|
108
|
-
resolve()
|
|
109
|
-
})
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getEntity(deviceId: string): T | undefined {
|
|
114
|
-
return this.entityMap.find((item) => item[0] === deviceId)?.[1]
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
getIdByEntity(entity: T): string | undefined {
|
|
118
|
-
return this.entityMap.find(
|
|
119
|
-
(item) => item[1].player.userKey === entity.player.userKey
|
|
120
|
-
)?.[0]
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
remoteTo(config: { target: T }): {
|
|
124
|
-
targetDeviceId: string
|
|
125
|
-
}
|
|
126
|
-
remoteTo(config: { target: T; timeoutMs: number }): {
|
|
127
|
-
targetDeviceId: string
|
|
128
|
-
timeoutMs: number
|
|
129
|
-
}
|
|
130
|
-
remoteTo({ target, ...rest }: { target: T; timeoutMs?: number }) {
|
|
131
|
-
return {
|
|
132
|
-
targetDeviceId: this.getIdByEntity(target),
|
|
133
|
-
...rest,
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
import { isRemoteAdaptorData } from '../../remote'
|
|
3
|
+
import { isRemoteValueEvent } from '../../remoteValue/exposeToRemote'
|
|
4
|
+
import { type AdaptorPackageData } from '../../adaptor'
|
|
5
|
+
|
|
6
|
+
interface GamePlayerEntityLike {
|
|
7
|
+
player: {
|
|
8
|
+
userKey: string
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface RemoteChannel<T extends GamePlayerEntityLike> {
|
|
13
|
+
onServerEvent(fn: (e: { args: unknown; entity: T }) => void): void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
|
|
18
|
+
* ```ts
|
|
19
|
+
* const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
|
|
20
|
+
*
|
|
21
|
+
* world.onPlayerLeave(
|
|
22
|
+
* remoteManager.onPlayerLeave.bind(remoteManager)
|
|
23
|
+
* )
|
|
24
|
+
*
|
|
25
|
+
* export const remoteAdaptor = {
|
|
26
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
27
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
28
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
29
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
30
|
+
* emit: (e) => {
|
|
31
|
+
* const entity = remoteManager.getEntity(e.targetDeviceId)
|
|
32
|
+
* if (!entity) {
|
|
33
|
+
* console.error('entity not found')
|
|
34
|
+
* return
|
|
35
|
+
* }
|
|
36
|
+
* remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
|
|
37
|
+
* },
|
|
38
|
+
* } satisfies Adaptor
|
|
39
|
+
*
|
|
40
|
+
* export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(
|
|
41
|
+
* remoteAdaptor,
|
|
42
|
+
* {
|
|
43
|
+
* deviceId: 'server',
|
|
44
|
+
* }
|
|
45
|
+
* )
|
|
46
|
+
*
|
|
47
|
+
* remote.register('initConnection', async () => {
|
|
48
|
+
* // 什么也不干,单纯的让客户端在服务端“备案”
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* export const getEntity = remoteManager.getEntity.bind(remoteManager)
|
|
52
|
+
* export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)
|
|
53
|
+
* export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)
|
|
54
|
+
* export const remoteTo = remoteManager.remoteTo.bind(remoteManager)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export class ServerSideRemoteChannelEventManager<
|
|
58
|
+
T extends GamePlayerEntityLike,
|
|
59
|
+
> extends EventEmitter<{
|
|
60
|
+
[key: string]: [AdaptorPackageData]
|
|
61
|
+
}> {
|
|
62
|
+
entityMap: [string, T][] = []
|
|
63
|
+
|
|
64
|
+
constructor(remoteChannel: RemoteChannel<T>) {
|
|
65
|
+
super()
|
|
66
|
+
remoteChannel.onServerEvent((e) => {
|
|
67
|
+
const { args } = e
|
|
68
|
+
if (!isRemoteAdaptorData(args)) {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
const prevItem = this.entityMap.find(
|
|
72
|
+
(item) => item[1].player.userKey === e.entity.player.userKey
|
|
73
|
+
)
|
|
74
|
+
if (prevItem) {
|
|
75
|
+
prevItem[0] = args.deviceId
|
|
76
|
+
prevItem[1] = e.entity
|
|
77
|
+
} else {
|
|
78
|
+
this.entityMap.push([args.deviceId, e.entity])
|
|
79
|
+
}
|
|
80
|
+
if (!isRemoteValueEvent(args.name)) {
|
|
81
|
+
this.emit('__remote_every__', args)
|
|
82
|
+
}
|
|
83
|
+
this.emit(args.name, args)
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onPlayerLeave(e: { entity: T }) {
|
|
88
|
+
this.entityMap = this.entityMap.filter(
|
|
89
|
+
(item) => item[1].player.userKey !== e.entity.player.userKey
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
onEvery(fn: (args: AdaptorPackageData) => void): void {
|
|
94
|
+
this.on('__remote_every__', fn)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
waitForRegister(entity: T) {
|
|
98
|
+
return new Promise<void>((resolve) => {
|
|
99
|
+
if (
|
|
100
|
+
this.entityMap.some(
|
|
101
|
+
([_, en]) => en.player.userKey === entity.player.userKey
|
|
102
|
+
)
|
|
103
|
+
) {
|
|
104
|
+
resolve()
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
this.once('__remote_every__', () => {
|
|
108
|
+
resolve()
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getEntity(deviceId: string): T | undefined {
|
|
114
|
+
return this.entityMap.find((item) => item[0] === deviceId)?.[1]
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getIdByEntity(entity: T): string | undefined {
|
|
118
|
+
return this.entityMap.find(
|
|
119
|
+
(item) => item[1].player.userKey === entity.player.userKey
|
|
120
|
+
)?.[0]
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
remoteTo(config: { target: T }): {
|
|
124
|
+
targetDeviceId: string
|
|
125
|
+
}
|
|
126
|
+
remoteTo(config: { target: T; timeoutMs: number }): {
|
|
127
|
+
targetDeviceId: string
|
|
128
|
+
timeoutMs: number
|
|
129
|
+
}
|
|
130
|
+
remoteTo({ target, ...rest }: { target: T; timeoutMs?: number }) {
|
|
131
|
+
return {
|
|
132
|
+
targetDeviceId: this.getIdByEntity(target),
|
|
133
|
+
...rest,
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
|
|
3
|
+
import { BrowserWindow, ipcMain } from 'electron'
|
|
4
|
+
import { Adaptor, AdaptorPackageData } from '../../adaptor'
|
|
5
|
+
import { isRemoteAdaptorData } from '../../remote'
|
|
6
|
+
import { KEYOF_GET_ID, MESSENGER_EVENT_NAME } from './constants'
|
|
7
|
+
|
|
8
|
+
class RemoteEventManager extends EventEmitter<{
|
|
9
|
+
[key: string]: [AdaptorPackageData]
|
|
10
|
+
}> {
|
|
11
|
+
EVERY_EVENT_NAME = '__remote_every__'
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
super()
|
|
15
|
+
ipcMain.on(MESSENGER_EVENT_NAME, (_, data) => {
|
|
16
|
+
if (isRemoteAdaptorData(data)) {
|
|
17
|
+
this.emit(data.name, data)
|
|
18
|
+
// 一定要抛出 every 事件,remote 包基于此处理远端的响应
|
|
19
|
+
this.emit(this.EVERY_EVENT_NAME, data)
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
25
|
+
this.on(this.EVERY_EVENT_NAME, fn)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function onElectronMainEmit(data: AdaptorPackageData) {
|
|
30
|
+
// 主进程通过 webContents 发送消息到渲染进程
|
|
31
|
+
const allWindows = BrowserWindow.getAllWindows()
|
|
32
|
+
const win = allWindows.find(
|
|
33
|
+
(w) => w.webContents.id.toString() === data.targetDeviceId
|
|
34
|
+
)
|
|
35
|
+
win?.webContents.send(MESSENGER_EVENT_NAME, data)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface Options {
|
|
39
|
+
onEmit?: (data: AdaptorPackageData) => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function createElectronMainAdaptor(options?: Options) {
|
|
43
|
+
const onEmit = options?.onEmit ?? onElectronMainEmit
|
|
44
|
+
const remoteEventManager = new RemoteEventManager()
|
|
45
|
+
|
|
46
|
+
const adaptor: Adaptor = {
|
|
47
|
+
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
48
|
+
on: remoteEventManager.on.bind(remoteEventManager),
|
|
49
|
+
once: remoteEventManager.once.bind(remoteEventManager),
|
|
50
|
+
off: remoteEventManager.off.bind(remoteEventManager),
|
|
51
|
+
emit: onEmit,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return adaptor
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function initMessengerInMain() {
|
|
58
|
+
ipcMain.handle(KEYOF_GET_ID, (event) => event.sender.id.toString())
|
|
59
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import { MESSENGER_KEY } from './constants'
|
|
4
|
+
|
|
5
|
+
interface Messenger {
|
|
6
|
+
postMessage: (data: any) => void
|
|
7
|
+
getId: () => Promise<string>
|
|
8
|
+
on: (channel: string, listener: (...args: any[]) => void) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getMessenger() {
|
|
12
|
+
return window[MESSENGER_KEY as keyof Window] as Messenger
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import { KEYOF_GET_ID, MESSENGER_EVENT_NAME, MESSENGER_KEY } from './constants'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 在 preload 进程中初始化 messenger 对象
|
|
7
|
+
*/
|
|
8
|
+
export function initMessengerInPreload(
|
|
9
|
+
contextBridge: Electron.ContextBridge,
|
|
10
|
+
ipcRenderer: Electron.IpcRenderer
|
|
11
|
+
) {
|
|
12
|
+
contextBridge.exposeInMainWorld(MESSENGER_KEY, {
|
|
13
|
+
postMessage: (data: any) => {
|
|
14
|
+
ipcRenderer.postMessage(MESSENGER_EVENT_NAME, data)
|
|
15
|
+
},
|
|
16
|
+
getId: () => ipcRenderer.invoke(KEYOF_GET_ID),
|
|
17
|
+
on: (channel: string, listener: (...args: any[]) => void) => {
|
|
18
|
+
ipcRenderer.on(channel, (_, ...args) => listener(...args))
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
import { Adaptor, AdaptorPackageData } from '../../adaptor'
|
|
3
|
+
import { isRemoteAdaptorData } from '../../remote'
|
|
4
|
+
import { getMessenger } from './messenger'
|
|
5
|
+
import { MESSENGER_EVENT_NAME } from './constants'
|
|
6
|
+
|
|
7
|
+
class RemoteEventManager extends EventEmitter<{
|
|
8
|
+
[key: string]: [AdaptorPackageData]
|
|
9
|
+
}> {
|
|
10
|
+
EVERY_EVENT_NAME = '__remote_every__'
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
super()
|
|
14
|
+
if (typeof window === 'undefined') {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
getMessenger().on(MESSENGER_EVENT_NAME, (data) => {
|
|
18
|
+
if (isRemoteAdaptorData(data)) {
|
|
19
|
+
this.emit(data.name, data)
|
|
20
|
+
// 一定要抛出 every 事件,remote 包基于此处理远端的响应
|
|
21
|
+
this.emit(this.EVERY_EVENT_NAME, data)
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
27
|
+
this.on(this.EVERY_EVENT_NAME, fn)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function onElectronRendererEmit(data: AdaptorPackageData) {
|
|
32
|
+
getMessenger().postMessage(data)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Options {
|
|
36
|
+
onEmit?: (data: AdaptorPackageData) => void
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createElectronRendererAdaptor(options?: Options) {
|
|
40
|
+
const onEmit = options?.onEmit ?? onElectronRendererEmit
|
|
41
|
+
const remoteEventManager = new RemoteEventManager()
|
|
42
|
+
|
|
43
|
+
const adaptor: Adaptor = {
|
|
44
|
+
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
45
|
+
on: remoteEventManager.on.bind(remoteEventManager),
|
|
46
|
+
once: remoteEventManager.once.bind(remoteEventManager),
|
|
47
|
+
off: remoteEventManager.off.bind(remoteEventManager),
|
|
48
|
+
emit: onEmit,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return adaptor
|
|
52
|
+
}
|
package/src/adaptors/http.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import EventEmitter from 'eventemitter3'
|
|
2
|
-
|
|
3
|
-
import type { Adaptor, AdaptorPackageData } from '../adaptor'
|
|
4
|
-
|
|
5
|
-
class RemoteEventManager extends EventEmitter<{
|
|
6
|
-
[key: string]: [AdaptorPackageData]
|
|
7
|
-
}> {
|
|
8
|
-
EVERY_EVENT_NAME = '__remote_every__'
|
|
9
|
-
|
|
10
|
-
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
11
|
-
this.on(this.EVERY_EVENT_NAME, fn)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const remoteEventManager = new RemoteEventManager()
|
|
16
|
-
|
|
17
|
-
export function createHttpAdaptor({
|
|
18
|
-
onEmit,
|
|
19
|
-
}: {
|
|
20
|
-
onEmit: (data: AdaptorPackageData) => void
|
|
21
|
-
}) {
|
|
22
|
-
const adaptor: Adaptor = {
|
|
23
|
-
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
24
|
-
on: remoteEventManager.on.bind(remoteEventManager),
|
|
25
|
-
once: remoteEventManager.once.bind(remoteEventManager),
|
|
26
|
-
off: remoteEventManager.off.bind(remoteEventManager),
|
|
27
|
-
emit: onEmit,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return adaptor
|
|
31
|
-
}
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
|
|
3
|
+
import type { Adaptor, AdaptorPackageData } from '../adaptor'
|
|
4
|
+
|
|
5
|
+
class RemoteEventManager extends EventEmitter<{
|
|
6
|
+
[key: string]: [AdaptorPackageData]
|
|
7
|
+
}> {
|
|
8
|
+
EVERY_EVENT_NAME = '__remote_every__'
|
|
9
|
+
|
|
10
|
+
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
11
|
+
this.on(this.EVERY_EVENT_NAME, fn)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const remoteEventManager = new RemoteEventManager()
|
|
16
|
+
|
|
17
|
+
export function createHttpAdaptor({
|
|
18
|
+
onEmit,
|
|
19
|
+
}: {
|
|
20
|
+
onEmit: (data: AdaptorPackageData) => void
|
|
21
|
+
}) {
|
|
22
|
+
const adaptor: Adaptor = {
|
|
23
|
+
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
24
|
+
on: remoteEventManager.on.bind(remoteEventManager),
|
|
25
|
+
once: remoteEventManager.once.bind(remoteEventManager),
|
|
26
|
+
off: remoteEventManager.off.bind(remoteEventManager),
|
|
27
|
+
emit: onEmit,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return adaptor
|
|
31
|
+
}
|
package/src/adaptors/iframe.ts
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import EventEmitter from 'eventemitter3'
|
|
2
|
-
import { isRemoteAdaptorData } from '../remote'
|
|
3
|
-
|
|
4
|
-
import type { Adaptor, AdaptorPackageData } from '../adaptor'
|
|
5
|
-
|
|
6
|
-
class RemoteEventManager extends EventEmitter<{
|
|
7
|
-
[key: string]: [AdaptorPackageData]
|
|
8
|
-
}> {
|
|
9
|
-
EVERY_EVENT_NAME = '__remote_every__'
|
|
10
|
-
|
|
11
|
-
constructor() {
|
|
12
|
-
super()
|
|
13
|
-
if (typeof window === 'undefined') {
|
|
14
|
-
return
|
|
15
|
-
}
|
|
16
|
-
window.addEventListener('message', (event) => {
|
|
17
|
-
const { data } = event
|
|
18
|
-
if (isRemoteAdaptorData(data)) {
|
|
19
|
-
this.emit(data.name, data)
|
|
20
|
-
// 一定要抛出 every 事件,remote 包基于此处理远端的响应
|
|
21
|
-
this.emit(this.EVERY_EVENT_NAME, data)
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
27
|
-
this.on(this.EVERY_EVENT_NAME, fn)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function createIframeAdaptor({
|
|
32
|
-
onEmit,
|
|
33
|
-
}: {
|
|
34
|
-
onEmit: (data: AdaptorPackageData) => void
|
|
35
|
-
}) {
|
|
36
|
-
const remoteEventManager = new RemoteEventManager()
|
|
37
|
-
|
|
38
|
-
const adaptor: Adaptor = {
|
|
39
|
-
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
40
|
-
on: remoteEventManager.on.bind(remoteEventManager),
|
|
41
|
-
once: remoteEventManager.once.bind(remoteEventManager),
|
|
42
|
-
off: remoteEventManager.off.bind(remoteEventManager),
|
|
43
|
-
emit: onEmit,
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return adaptor
|
|
47
|
-
}
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
import { isRemoteAdaptorData } from '../remote'
|
|
3
|
+
|
|
4
|
+
import type { Adaptor, AdaptorPackageData } from '../adaptor'
|
|
5
|
+
|
|
6
|
+
class RemoteEventManager extends EventEmitter<{
|
|
7
|
+
[key: string]: [AdaptorPackageData]
|
|
8
|
+
}> {
|
|
9
|
+
EVERY_EVENT_NAME = '__remote_every__'
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super()
|
|
13
|
+
if (typeof window === 'undefined') {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
window.addEventListener('message', (event) => {
|
|
17
|
+
const { data } = event
|
|
18
|
+
if (isRemoteAdaptorData(data)) {
|
|
19
|
+
this.emit(data.name, data)
|
|
20
|
+
// 一定要抛出 every 事件,remote 包基于此处理远端的响应
|
|
21
|
+
this.emit(this.EVERY_EVENT_NAME, data)
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onEvery(fn: (data: AdaptorPackageData) => void) {
|
|
27
|
+
this.on(this.EVERY_EVENT_NAME, fn)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createIframeAdaptor({
|
|
32
|
+
onEmit,
|
|
33
|
+
}: {
|
|
34
|
+
onEmit: (data: AdaptorPackageData) => void
|
|
35
|
+
}) {
|
|
36
|
+
const remoteEventManager = new RemoteEventManager()
|
|
37
|
+
|
|
38
|
+
const adaptor: Adaptor = {
|
|
39
|
+
every: remoteEventManager.onEvery.bind(remoteEventManager),
|
|
40
|
+
on: remoteEventManager.on.bind(remoteEventManager),
|
|
41
|
+
once: remoteEventManager.once.bind(remoteEventManager),
|
|
42
|
+
off: remoteEventManager.off.bind(remoteEventManager),
|
|
43
|
+
emit: onEmit,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return adaptor
|
|
47
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -10,3 +10,8 @@ export * from './adaptors/iframe'
|
|
|
10
10
|
export * from './adaptors/http'
|
|
11
11
|
export * from './adaptors/dao3/client'
|
|
12
12
|
export * from './adaptors/dao3/server'
|
|
13
|
+
export * from './adaptors/electron/constants'
|
|
14
|
+
export * from './adaptors/electron/messenger'
|
|
15
|
+
export * from './adaptors/electron/main'
|
|
16
|
+
export * from './adaptors/electron/preload'
|
|
17
|
+
export * from './adaptors/electron/renderer'
|