@delight-rpc/electron 6.0.1 → 6.0.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/package.json +5 -4
- package/src/client.ts +217 -0
- package/src/index.ts +2 -0
- package/src/server.ts +71 -0
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delight-rpc/electron",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"files": [
|
|
7
|
-
"lib"
|
|
7
|
+
"lib",
|
|
8
|
+
"src"
|
|
8
9
|
],
|
|
9
10
|
"type": "module",
|
|
10
11
|
"main": "lib/index.js",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"@typescript-eslint/parser": "^5.55.0",
|
|
43
44
|
"cross-env": "^7.0.3",
|
|
44
45
|
"delight-rpc": "^6.0.0",
|
|
45
|
-
"electron": "^
|
|
46
|
+
"electron": "^28.0.0",
|
|
46
47
|
"eslint": "8.36.0",
|
|
47
48
|
"husky": "4",
|
|
48
49
|
"jest": "^29.5.0",
|
|
@@ -64,6 +65,6 @@
|
|
|
64
65
|
},
|
|
65
66
|
"peerDependencies": {
|
|
66
67
|
"delight-rpc": "^5.0.0 || ^6.0.0",
|
|
67
|
-
"electron": "
|
|
68
|
+
"electron": ">=16.0.1 <29"
|
|
68
69
|
}
|
|
69
70
|
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import * as DelightRPC from 'delight-rpc'
|
|
2
|
+
import { Deferred } from 'extra-promise'
|
|
3
|
+
import Electron from 'electron'
|
|
4
|
+
import { CustomError } from '@blackglory/errors'
|
|
5
|
+
import { IResponse, IError, IBatchResponse } from '@delight-rpc/protocol'
|
|
6
|
+
|
|
7
|
+
export function createClientInMain<IAPI extends object>(
|
|
8
|
+
port: Electron.MessagePortMain
|
|
9
|
+
, { parameterValidators, expectedVersion, channel }: {
|
|
10
|
+
parameterValidators?: DelightRPC.ParameterValidators<IAPI>
|
|
11
|
+
, expectedVersion?: string
|
|
12
|
+
, channel?: string
|
|
13
|
+
} = {}
|
|
14
|
+
): [client: DelightRPC.ClientProxy<IAPI>, close: () => void] {
|
|
15
|
+
const pendings: Record<string, Deferred<IResponse<unknown>> | undefined> = {}
|
|
16
|
+
|
|
17
|
+
port.addListener('message', handler)
|
|
18
|
+
|
|
19
|
+
const client = DelightRPC.createClient<IAPI>(
|
|
20
|
+
async function send(request) {
|
|
21
|
+
const res = new Deferred<IResponse<unknown>>()
|
|
22
|
+
pendings[request.id] = res
|
|
23
|
+
try {
|
|
24
|
+
port.postMessage(request)
|
|
25
|
+
return await res
|
|
26
|
+
} finally {
|
|
27
|
+
delete pendings[request.id]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
, {
|
|
31
|
+
parameterValidators
|
|
32
|
+
, expectedVersion
|
|
33
|
+
, channel
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
return [client, close]
|
|
38
|
+
|
|
39
|
+
function close(): void {
|
|
40
|
+
port.removeListener('message', handler)
|
|
41
|
+
|
|
42
|
+
for (const [key, deferred] of Object.entries(pendings)) {
|
|
43
|
+
deferred!.reject(new ClientClosed())
|
|
44
|
+
delete pendings[key]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function handler(event: Electron.MessageEvent): void {
|
|
49
|
+
const res = event.data
|
|
50
|
+
if (DelightRPC.isResult(res) || DelightRPC.isError(res)) {
|
|
51
|
+
pendings[res.id]?.resolve(res)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function createClientInRenderer<IAPI extends object>(
|
|
57
|
+
port: MessagePort
|
|
58
|
+
, { parameterValidators, expectedVersion, channel }: {
|
|
59
|
+
parameterValidators?: DelightRPC.ParameterValidators<IAPI>
|
|
60
|
+
expectedVersion?: string
|
|
61
|
+
channel?: string
|
|
62
|
+
} = {}
|
|
63
|
+
): [client: DelightRPC.ClientProxy<IAPI>, close: () => void] {
|
|
64
|
+
const pendings: Record<
|
|
65
|
+
string
|
|
66
|
+
, | Deferred<IResponse<unknown>>
|
|
67
|
+
| undefined
|
|
68
|
+
> = {}
|
|
69
|
+
|
|
70
|
+
port.addEventListener('message', handler)
|
|
71
|
+
|
|
72
|
+
const client = DelightRPC.createClient<IAPI>(
|
|
73
|
+
async function send(request) {
|
|
74
|
+
const res = new Deferred<IResponse<unknown>>()
|
|
75
|
+
pendings[request.id] = res
|
|
76
|
+
try {
|
|
77
|
+
port.postMessage(request)
|
|
78
|
+
return await res
|
|
79
|
+
} finally {
|
|
80
|
+
delete pendings[request.id]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
, {
|
|
84
|
+
parameterValidators
|
|
85
|
+
, expectedVersion
|
|
86
|
+
, channel
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return [client, close]
|
|
91
|
+
|
|
92
|
+
function close(): void {
|
|
93
|
+
port.removeEventListener('message', handler)
|
|
94
|
+
|
|
95
|
+
for (const [key, deferred] of Object.entries(pendings)) {
|
|
96
|
+
deferred!.reject(new ClientClosed())
|
|
97
|
+
delete pendings[key]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function handler(event: MessageEvent): void {
|
|
102
|
+
const res = event.data
|
|
103
|
+
if (DelightRPC.isResult(res) || DelightRPC.isError(res)) {
|
|
104
|
+
pendings[res.id]?.resolve(res)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function createBatchClientInMain<DataType>(
|
|
110
|
+
port: Electron.MessagePortMain
|
|
111
|
+
, { expectedVersion, channel }: {
|
|
112
|
+
expectedVersion?: string
|
|
113
|
+
channel?: string
|
|
114
|
+
} = {}
|
|
115
|
+
): [client: DelightRPC.BatchClient<DataType>, close: () => void] {
|
|
116
|
+
const pendings: Record<
|
|
117
|
+
string
|
|
118
|
+
, | Deferred<IError | IBatchResponse<unknown>>
|
|
119
|
+
| undefined
|
|
120
|
+
> = {}
|
|
121
|
+
|
|
122
|
+
port.addListener('message', handler)
|
|
123
|
+
|
|
124
|
+
const client = new DelightRPC.BatchClient(
|
|
125
|
+
async function send(request) {
|
|
126
|
+
const res = new Deferred<
|
|
127
|
+
| IError
|
|
128
|
+
| IBatchResponse<unknown>
|
|
129
|
+
>()
|
|
130
|
+
pendings[request.id] = res
|
|
131
|
+
try {
|
|
132
|
+
port.postMessage(request)
|
|
133
|
+
return await res
|
|
134
|
+
} finally {
|
|
135
|
+
delete pendings[request.id]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
, {
|
|
139
|
+
expectedVersion
|
|
140
|
+
, channel
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return [client, close]
|
|
145
|
+
|
|
146
|
+
function close(): void {
|
|
147
|
+
port.removeListener('message', handler)
|
|
148
|
+
|
|
149
|
+
for (const [key, deferred] of Object.entries(pendings)) {
|
|
150
|
+
deferred!.reject(new ClientClosed())
|
|
151
|
+
delete pendings[key]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function handler(event: Electron.MessageEvent): void {
|
|
156
|
+
const res = event.data
|
|
157
|
+
if (DelightRPC.isError(res) || DelightRPC.isBatchResponse(res)) {
|
|
158
|
+
pendings[res.id]?.resolve(res)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function createBatchClientInRenderer<DataType>(
|
|
164
|
+
port: MessagePort
|
|
165
|
+
, { expectedVersion, channel }: {
|
|
166
|
+
expectedVersion?: string
|
|
167
|
+
channel?: string
|
|
168
|
+
} = {}
|
|
169
|
+
): [client: DelightRPC.BatchClient<DataType>, close: () => void] {
|
|
170
|
+
const pendings: Record<
|
|
171
|
+
string
|
|
172
|
+
, | Deferred<IError | IBatchResponse<unknown>>
|
|
173
|
+
| undefined
|
|
174
|
+
> = {}
|
|
175
|
+
|
|
176
|
+
port.addEventListener('message', handler)
|
|
177
|
+
|
|
178
|
+
const client = new DelightRPC.BatchClient(
|
|
179
|
+
async function send(request) {
|
|
180
|
+
const res = new Deferred<
|
|
181
|
+
| IError
|
|
182
|
+
| IBatchResponse<unknown>
|
|
183
|
+
>()
|
|
184
|
+
pendings[request.id] = res
|
|
185
|
+
try {
|
|
186
|
+
port.postMessage(request)
|
|
187
|
+
return await res
|
|
188
|
+
} finally {
|
|
189
|
+
delete pendings[request.id]
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
, {
|
|
193
|
+
expectedVersion
|
|
194
|
+
, channel
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return [client, close]
|
|
199
|
+
|
|
200
|
+
function close(): void {
|
|
201
|
+
port.removeEventListener('message', handler)
|
|
202
|
+
|
|
203
|
+
for (const [key, deferred] of Object.entries(pendings)) {
|
|
204
|
+
deferred!.reject(new ClientClosed())
|
|
205
|
+
delete pendings[key]
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function handler(event: MessageEvent): void {
|
|
210
|
+
const res = event.data
|
|
211
|
+
if (DelightRPC.isError(res) || DelightRPC.isBatchResponse(res)) {
|
|
212
|
+
pendings[res.id]?.resolve(res)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export class ClientClosed extends CustomError {}
|
package/src/index.ts
ADDED
package/src/server.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as DelightRPC from 'delight-rpc'
|
|
2
|
+
import Electron from 'electron'
|
|
3
|
+
import { isntNull } from '@blackglory/prelude'
|
|
4
|
+
|
|
5
|
+
export function createServerInMain<IAPI extends object>(
|
|
6
|
+
api: DelightRPC.ImplementationOf<IAPI>
|
|
7
|
+
, port: Electron.MessagePortMain
|
|
8
|
+
, { parameterValidators, version, channel, ownPropsOnly }: {
|
|
9
|
+
parameterValidators?: DelightRPC.ParameterValidators<IAPI>
|
|
10
|
+
version?: `${number}.${number}.${number}`
|
|
11
|
+
channel?: string | RegExp | typeof DelightRPC.AnyChannel
|
|
12
|
+
ownPropsOnly?: boolean
|
|
13
|
+
} = {}
|
|
14
|
+
): () => void {
|
|
15
|
+
port.addListener('message', handler)
|
|
16
|
+
return () => port.removeListener('message', handler)
|
|
17
|
+
|
|
18
|
+
async function handler(event: Electron.MessageEvent): Promise<void> {
|
|
19
|
+
const req = event.data
|
|
20
|
+
if (DelightRPC.isRequest(req) || DelightRPC.isBatchRequest(req)) {
|
|
21
|
+
const result = await DelightRPC.createResponse(
|
|
22
|
+
api
|
|
23
|
+
, req
|
|
24
|
+
, {
|
|
25
|
+
parameterValidators
|
|
26
|
+
, version
|
|
27
|
+
, channel
|
|
28
|
+
, ownPropsOnly
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if (isntNull(result)) {
|
|
33
|
+
port.postMessage(result)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createServerInRenderer<IAPI extends object>(
|
|
40
|
+
api: DelightRPC.ImplementationOf<IAPI>
|
|
41
|
+
, port: MessagePort
|
|
42
|
+
, { parameterValidators, version, channel, ownPropsOnly }: {
|
|
43
|
+
parameterValidators?: DelightRPC.ParameterValidators<IAPI>
|
|
44
|
+
version?: `${number}.${number}.${number}`
|
|
45
|
+
channel?: string | RegExp | typeof DelightRPC.AnyChannel
|
|
46
|
+
ownPropsOnly?: boolean
|
|
47
|
+
} = {}
|
|
48
|
+
): () => void {
|
|
49
|
+
port.addEventListener('message', handler)
|
|
50
|
+
return () => port.removeEventListener('message', handler)
|
|
51
|
+
|
|
52
|
+
async function handler(event: MessageEvent): Promise<void> {
|
|
53
|
+
const req = event.data
|
|
54
|
+
if (DelightRPC.isRequest(req) || DelightRPC.isBatchRequest(req)) {
|
|
55
|
+
const result = await DelightRPC.createResponse(
|
|
56
|
+
api
|
|
57
|
+
, req
|
|
58
|
+
, {
|
|
59
|
+
parameterValidators
|
|
60
|
+
, version
|
|
61
|
+
, channel
|
|
62
|
+
, ownPropsOnly
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if (isntNull(result)) {
|
|
67
|
+
port.postMessage(result)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|