@delight-rpc/child-process 0.6.1 → 0.6.2
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 +4 -3
- package/src/client.ts +108 -0
- package/src/index.ts +2 -0
- package/src/server.ts +36 -0
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delight-rpc/child-process",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
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",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"@commitlint/cli": "^17.4.4",
|
|
38
39
|
"@commitlint/config-conventional": "^17.4.4",
|
|
39
40
|
"@types/jest": "^29.5.0",
|
|
40
|
-
"@types/node": "
|
|
41
|
+
"@types/node": "16",
|
|
41
42
|
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
|
42
43
|
"@typescript-eslint/parser": "^5.55.0",
|
|
43
44
|
"cross-env": "^7.0.3",
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as DelightRPC from 'delight-rpc'
|
|
2
|
+
import { ChildProcess } from 'child_process'
|
|
3
|
+
import { Deferred } from 'extra-promise'
|
|
4
|
+
import { CustomError } from '@blackglory/errors'
|
|
5
|
+
import { IRequest, IResponse, IError, IBatchRequest, IBatchResponse } from '@delight-rpc/protocol'
|
|
6
|
+
|
|
7
|
+
export function createClient<IAPI extends object>(
|
|
8
|
+
process: ChildProcess | NodeJS.Process
|
|
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
|
+
process.on('message', handler)
|
|
18
|
+
|
|
19
|
+
const client = DelightRPC.createClient<IAPI>(
|
|
20
|
+
async function send(request: IRequest<unknown>) {
|
|
21
|
+
const res = new Deferred<IResponse<unknown>>()
|
|
22
|
+
pendings[request.id] = res
|
|
23
|
+
try {
|
|
24
|
+
process.send!(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() {
|
|
40
|
+
process.off('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(res: any): void {
|
|
49
|
+
if (DelightRPC.isResult(res) || DelightRPC.isError(res)) {
|
|
50
|
+
pendings[res.id]?.resolve(res)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function createBatchClient<DataType>(
|
|
56
|
+
process: ChildProcess | NodeJS.Process
|
|
57
|
+
, { expectedVersion, channel }: {
|
|
58
|
+
expectedVersion?: string
|
|
59
|
+
channel?: string
|
|
60
|
+
} = {}
|
|
61
|
+
): [client: DelightRPC.BatchClient<DataType>, close: () => void] {
|
|
62
|
+
const pendings: Record<
|
|
63
|
+
string
|
|
64
|
+
, | Deferred<IError | IBatchResponse<unknown>>
|
|
65
|
+
| undefined
|
|
66
|
+
> = {}
|
|
67
|
+
|
|
68
|
+
process.on('message', handler)
|
|
69
|
+
|
|
70
|
+
const client = new DelightRPC.BatchClient(
|
|
71
|
+
async function send(request: IBatchRequest<unknown>) {
|
|
72
|
+
const res = new Deferred<
|
|
73
|
+
| IError
|
|
74
|
+
| IBatchResponse<unknown>
|
|
75
|
+
>()
|
|
76
|
+
pendings[request.id] = res
|
|
77
|
+
try {
|
|
78
|
+
process.send!(request)
|
|
79
|
+
return await res
|
|
80
|
+
} finally {
|
|
81
|
+
delete pendings[request.id]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
, {
|
|
85
|
+
expectedVersion
|
|
86
|
+
, channel
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return [client, close]
|
|
91
|
+
|
|
92
|
+
function close() {
|
|
93
|
+
process.off('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(res: any): void {
|
|
102
|
+
if (DelightRPC.isError(res) || DelightRPC.isBatchResponse(res)) {
|
|
103
|
+
pendings[res.id]?.resolve(res)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export class ClientClosed extends CustomError {}
|
package/src/index.ts
ADDED
package/src/server.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as DelightRPC from 'delight-rpc'
|
|
2
|
+
import { ChildProcess } from 'child_process'
|
|
3
|
+
import { isntNull } from '@blackglory/prelude'
|
|
4
|
+
|
|
5
|
+
export function createServer<IAPI extends object>(
|
|
6
|
+
api: DelightRPC.ImplementationOf<IAPI>
|
|
7
|
+
, process: ChildProcess | NodeJS.Process
|
|
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
|
+
process.on('message', handler)
|
|
16
|
+
return () => process.off('message', handler)
|
|
17
|
+
|
|
18
|
+
async function handler(req: any): Promise<void> {
|
|
19
|
+
if (DelightRPC.isRequest(req) || DelightRPC.isBatchRequest(req)) {
|
|
20
|
+
const result = await DelightRPC.createResponse(
|
|
21
|
+
api
|
|
22
|
+
, req
|
|
23
|
+
, {
|
|
24
|
+
parameterValidators
|
|
25
|
+
, version
|
|
26
|
+
, channel
|
|
27
|
+
, ownPropsOnly
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if (isntNull(result)) {
|
|
32
|
+
process.send!(result)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|