@3fv/electron-utility-process-manager 1.0.6 → 1.0.8

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 (51) hide show
  1. package/README.md +53 -2
  2. package/lib/cjs/index.js +17 -7
  3. package/lib/cjs/index.js.map +1 -1
  4. package/lib/cjs/main/UPMMainService.js +24 -12
  5. package/lib/cjs/main/UPMMainService.js.map +1 -1
  6. package/lib/cjs/main/UPMMainServiceManager.js +17 -7
  7. package/lib/cjs/main/UPMMainServiceManager.js.map +1 -1
  8. package/lib/cjs/node/UPMNodeProcess.js +17 -7
  9. package/lib/cjs/node/UPMNodeProcess.js.map +1 -1
  10. package/lib/cjs/package.json +1 -0
  11. package/lib/cjs/renderer/UPMRendererClientFactory.js +17 -7
  12. package/lib/cjs/renderer/UPMRendererClientFactory.js.map +1 -1
  13. package/lib/mjs/main/UPMMainService.js +5 -3
  14. package/lib/mjs/main/UPMMainService.js.map +1 -1
  15. package/lib/mjs/package.json +1 -0
  16. package/package.json +81 -43
  17. package/src/common/clients.ts +276 -0
  18. package/src/common/guards.ts +11 -0
  19. package/src/common/index.ts +3 -0
  20. package/src/common/types.ts +106 -0
  21. package/src/index.ts +8 -0
  22. package/src/main/UPMMainService.ts +454 -0
  23. package/src/main/UPMMainServiceManager.ts +178 -0
  24. package/src/main/index.ts +2 -0
  25. package/src/node/UPMNodeProcess.ts +164 -0
  26. package/src/node/index.ts +3 -0
  27. package/src/renderer/UPMRendererClientFactory.ts +57 -0
  28. package/src/renderer/index.ts +4 -0
  29. package/.prettierrc.js +0 -14
  30. package/examples/lib-examples/complex/complex-main.d.ts +0 -1
  31. package/examples/lib-examples/complex/complex-main.js +0 -108
  32. package/examples/lib-examples/complex/complex-main.js.map +0 -1
  33. package/examples/lib-examples/complex/complex-node.d.ts +0 -1
  34. package/examples/lib-examples/complex/complex-node.js +0 -17
  35. package/examples/lib-examples/complex/complex-node.js.map +0 -1
  36. package/examples/lib-examples/complex/complex-renderer.d.ts +0 -1
  37. package/examples/lib-examples/complex/complex-renderer.js +0 -18
  38. package/examples/lib-examples/complex/complex-renderer.js.map +0 -1
  39. package/examples/lib-examples/complex/complex-types.d.ts +0 -3
  40. package/examples/lib-examples/complex/complex-types.js +0 -3
  41. package/examples/lib-examples/complex/complex-types.js.map +0 -1
  42. package/examples/lib-examples/simple/simple-main.d.ts +0 -1
  43. package/examples/lib-examples/simple/simple-main.js +0 -113
  44. package/examples/lib-examples/simple/simple-main.js.map +0 -1
  45. package/examples/lib-examples/simple/simple-node.d.ts +0 -1
  46. package/examples/lib-examples/simple/simple-node.js +0 -17
  47. package/examples/lib-examples/simple/simple-node.js.map +0 -1
  48. package/examples/lib-examples/simple/simple-renderer.d.ts +0 -1
  49. package/examples/lib-examples/simple/simple-renderer.js +0 -17
  50. package/examples/lib-examples/simple/simple-renderer.js.map +0 -1
  51. package/jest.config.js +0 -20
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@3fv/electron-utility-process-manager",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
+ "packageManager": "pnpm@12.15.0",
4
5
  "description": "electron-utility-process-manager",
5
6
  "author": "Jonathan Glanz",
6
7
  "license": "MIT",
@@ -11,54 +12,91 @@
11
12
  "type": "commonjs",
12
13
  "main": "./lib/cjs/index.js",
13
14
  "module": "./lib/mjs/index.js",
14
- "types": "./lib/mjs/index.d.ts",
15
+ "types": "./lib/cjs/index.d.ts",
15
16
  "exports": {
16
17
  ".": {
17
- "types": "./lib/mjs/index.d.ts",
18
- "node": "./lib/cjs/index.js",
19
- "browser": "./lib/cjs/index.js",
20
- "import": "./lib/mjs/index.js",
21
- "require": "./lib/cjs/index.js"
18
+ "node": {
19
+ "types": "./lib/cjs/index.d.ts",
20
+ "default": "./lib/cjs/index.js"
21
+ },
22
+ "browser": {
23
+ "types": "./lib/cjs/index.d.ts",
24
+ "default": "./lib/cjs/index.js"
25
+ },
26
+ "import": {
27
+ "types": "./lib/mjs/index.d.ts",
28
+ "default": "./lib/mjs/index.js"
29
+ },
30
+ "require": {
31
+ "types": "./lib/cjs/index.d.ts",
32
+ "default": "./lib/cjs/index.js"
33
+ }
22
34
  },
23
35
  "./main": {
24
- "types": "./lib/mjs/main/index.d.ts",
25
- "node": "./lib/cjs/main/index.js",
26
- "import": "./lib/mjs/main/index.js",
27
- "require": "./lib/cjs/main/index.js"
36
+ "node": {
37
+ "types": "./lib/cjs/main/index.d.ts",
38
+ "default": "./lib/cjs/main/index.js"
39
+ },
40
+ "import": {
41
+ "types": "./lib/mjs/main/index.d.ts",
42
+ "default": "./lib/mjs/main/index.js"
43
+ },
44
+ "require": {
45
+ "types": "./lib/cjs/main/index.d.ts",
46
+ "default": "./lib/cjs/main/index.js"
47
+ }
28
48
  },
29
49
  "./renderer": {
30
- "types": "./lib/mjs/renderer/index.d.ts",
31
- "node": "./lib/cjs/renderer/index.js",
32
- "browser": "./lib/cjs/renderer/index.js",
33
- "import": "./lib/mjs/renderer/index.js",
34
- "require": "./lib/cjs/renderer/index.js"
50
+ "node": {
51
+ "types": "./lib/cjs/renderer/index.d.ts",
52
+ "default": "./lib/cjs/renderer/index.js"
53
+ },
54
+ "browser": {
55
+ "types": "./lib/cjs/renderer/index.d.ts",
56
+ "default": "./lib/cjs/renderer/index.js"
57
+ },
58
+ "import": {
59
+ "types": "./lib/mjs/renderer/index.d.ts",
60
+ "default": "./lib/mjs/renderer/index.js"
61
+ },
62
+ "require": {
63
+ "types": "./lib/cjs/renderer/index.d.ts",
64
+ "default": "./lib/cjs/renderer/index.js"
65
+ }
35
66
  },
36
67
  "./node": {
37
- "types": "./lib/mjs/node/index.d.ts",
38
- "node": "./lib/cjs/node/index.js",
39
- "import": "./lib/mjs/node/index.js",
40
- "require": "./lib/cjs/node/index.js"
68
+ "node": {
69
+ "types": "./lib/cjs/node/index.d.ts",
70
+ "default": "./lib/cjs/node/index.js"
71
+ },
72
+ "import": {
73
+ "types": "./lib/mjs/node/index.d.ts",
74
+ "default": "./lib/mjs/node/index.js"
75
+ },
76
+ "require": {
77
+ "types": "./lib/cjs/node/index.d.ts",
78
+ "default": "./lib/cjs/node/index.js"
79
+ }
41
80
  }
42
81
  },
43
82
  "scripts": {
44
83
  "build": "node ./scripts/build.mjs",
45
- "build:link": "yarn run build && yarn unlink;yarn link",
46
- "build:watch": "run-s build:link && yarn run build --watch",
47
- "test": "yarn run build && jest",
48
- "test:watch": "yarn run build && jest --watchAll --no-cache",
84
+ "build:watch": "pnpm run build --watch",
85
+ "build:examples": "pnpm --filter @3fv/electron-utility-process-manager-examples run build",
86
+ "example": "node ./scripts/run-example.mjs",
87
+ "test": "jest --passWithNoTests",
88
+ "test:watch": "jest --watchAll --no-cache",
49
89
  "test:dev": "run-s build && run-p test:watch build:watch",
50
- "preversion": "yarn build",
51
- "preversion::with-tests": "yarn build && yarn test",
52
- "clean": "./scripts/clean.sh",
53
- "postversion": "node ./scripts/release.mjs latest",
54
- "release": "yarn build && yarn version --patch --non-interactive"
90
+ "preversion": "pnpm build",
91
+ "preversion::with-tests": "pnpm build && pnpm test",
92
+ "release": "gh workflow run release.yml --ref master -f bump=patch"
55
93
  },
56
94
  "publishConfig": {
57
95
  "access": "public"
58
96
  },
59
97
  "repository": {
60
98
  "type": "git",
61
- "url": "https://github.com/3fv/electron-utility-process-manager.git"
99
+ "url": "git+https://github.com/3fv/electron-utility-process-manager.git"
62
100
  },
63
101
  "keywords": [
64
102
  "typescript",
@@ -66,15 +104,15 @@
66
104
  "proxy"
67
105
  ],
68
106
  "files": [
69
- "**/*.d.ts",
70
- "**/*.js",
71
- "**/*.map",
72
- "package.json"
107
+ "lib",
108
+ "!lib/**/*.tsbuildinfo",
109
+ "src",
110
+ "README.md"
73
111
  ],
74
112
  "dependencies": {
75
- "@3fv/deferred": "^1.2.12",
76
- "@3fv/guard": "^1.4.38",
77
- "@3fv/prelude-ts": "^0.8.32",
113
+ "@3fv/deferred": "^1.2.17",
114
+ "@3fv/guard": "^1.4.41",
115
+ "@3fv/prelude-ts": "^0.8.45",
78
116
  "chalk": "^5.3.0",
79
117
  "debug": "^4.3.6",
80
118
  "lodash": "^4.17.21",
@@ -82,20 +120,20 @@
82
120
  "ts-pattern": "^5.5.0"
83
121
  },
84
122
  "peerDependencies": {
85
- "electron": "^31"
123
+ "electron": ">=31"
86
124
  },
87
125
  "devDependencies": {
88
126
  "@faker-js/faker": "^8.4.1",
89
127
  "@types/chalk": "^2.2.0",
90
128
  "@types/debug": "^4.1.12",
91
- "@types/jest": "^29.5.12",
129
+ "@types/jest": "^30.0.0",
92
130
  "@types/lodash": "^4.17.7",
93
131
  "@types/node": "^22.9.0",
94
132
  "@types/shelljs": "^0.8.15",
95
133
  "cross-env": "^7.0.3",
96
- "electron": "31.3.0",
134
+ "electron": "45.3.2",
97
135
  "electronmon": "^2.0.3",
98
- "jest": "^29.7.0",
136
+ "jest": "^30.5.2",
99
137
  "lodash": "^4.17.21",
100
138
  "npm-run-all": "^4.1.5",
101
139
  "prettier": "^3.3.3",
@@ -103,9 +141,9 @@
103
141
  "shelljs": "^0.8.5",
104
142
  "source-map-support": "^0.5.21",
105
143
  "supports-color": "^9.4.0",
106
- "ts-jest": "^29.2.4",
144
+ "ts-jest": "^29.4.15",
107
145
  "ts-node": "^10.9.2",
108
- "typescript": "^5.5.4",
146
+ "typescript": "^6.0.3",
109
147
  "zx": "^8.1.4"
110
148
  }
111
149
  }
@@ -0,0 +1,276 @@
1
+ import { isDefined, isFunction } from "@3fv/guard"
2
+ import { isMessagePort, isUtilityProcess } from "./guards.js"
3
+ import Tracer from "tracer"
4
+ import {
5
+ Defaults,
6
+ IPCChannel,
7
+ Message, MessageKind, MessageRequestFn,
8
+ MessageRequestMap,
9
+ MessageRequestNames,
10
+ MessageRequestParams,
11
+ MessageRequestReturnType, NodeEnvelope, NodeMessage,
12
+ PendingRequestMessage, Port
13
+ } from "./types.js"
14
+ import { Deferred } from "@3fv/deferred"
15
+
16
+ const log = Tracer.colorConsole()
17
+
18
+ /**
19
+ * Service client interface maps a `MessageRequestMap`
20
+ * to its functional methods
21
+ */
22
+ export type IServiceClient<
23
+ ReqMap extends MessageRequestMap,
24
+ MType extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>
25
+ > = { [Type in MType]: MessageRequestFn<ReqMap, Type> }
26
+
27
+ /**
28
+ * Messaging client interface
29
+ */
30
+ export interface IMessageClient<
31
+ ReqMap extends MessageRequestMap,
32
+ MType extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>
33
+ >
34
+ {
35
+
36
+ /**
37
+ * Get the clientId for the underlying port
38
+ */
39
+ get clientId(): string
40
+
41
+ /**
42
+ * A very low level function for sending `any` data
43
+ * to the `utilityProcess`
44
+ *
45
+ * @param data
46
+ */
47
+ sendEvent(data: any): void
48
+
49
+ /**
50
+ * Execute a request, with a response expected
51
+ *
52
+ * @param type
53
+ * @param args determined by the typed `MessageRequestMap` & `Type` parameters
54
+ */
55
+ executeRequest<
56
+ Type extends MType,
57
+ R extends MessageRequestReturnType<ReqMap, Type> = MessageRequestReturnType<ReqMap, Type>
58
+ >(
59
+ type: Type,
60
+ ...args: MessageRequestParams<ReqMap, Type>
61
+ ): Promise<R>
62
+
63
+ /**
64
+ * Close the message client
65
+ */
66
+ close(): void
67
+
68
+ /**
69
+ * Resolve when client is ready to use
70
+ */
71
+ whenReady(): Promise<IMessageClient<ReqMap, MType>>
72
+
73
+ /**
74
+ * Get service client from message client
75
+ */
76
+ getServiceClient(): IServiceClient<ReqMap, MType>
77
+ }
78
+
79
+ /**
80
+ * Generic `MessagePort` client implementation, which
81
+ * is functional in any process.
82
+ *
83
+ * > NOTE: Aside from the main & renderer processes,
84
+ * > an `utilityProcess` could potentially also
85
+ * > use this client to communicate with a separate
86
+ * > `utilityProcess`
87
+ */
88
+ export class MessagePortClient<
89
+ ReqMap extends MessageRequestMap,
90
+ MType extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>
91
+ > implements IMessageClient<ReqMap, MType> {
92
+
93
+ /**
94
+ * Used to generate IDS
95
+ *
96
+ * @private
97
+ */
98
+ private idSequence_: number = 0
99
+
100
+ /**
101
+ * A `Map` responsible for mapping `messageId`
102
+ * values to a `PendingRequestMessage`
103
+ *
104
+ * @private
105
+ */
106
+ private readonly pendingMessages_ = new Map<number, PendingRequestMessage>()
107
+
108
+ /**
109
+ * Get the next `messageId`
110
+ *
111
+ * @returns {number}
112
+ * @private
113
+ */
114
+ private generateMessageId(): number {
115
+ return this.idSequence_++
116
+ }
117
+
118
+ /**
119
+ * Remove a pending message mapping based on supplied ID
120
+ *
121
+ * @param {number} messageId
122
+ * @private
123
+ */
124
+ private removePendingMessage(messageId: number): void {
125
+ const pending = this.pendingMessages_.get(messageId)
126
+ if (!pending) {
127
+ return
128
+ }
129
+ clearTimeout(pending.timeoutId)
130
+ if (!pending.deferred.isSettled()) {
131
+ pending.deferred.reject("The pending message is being removed before promise is settled")
132
+ }
133
+ this.pendingMessages_.delete(messageId)
134
+ }
135
+
136
+ /**
137
+ * Handle messages posted by the `utilityProcess` via
138
+ * either `process.parentPort` or a specific `MessagePort`
139
+ *
140
+ * @param payloadOrEnvelopeOrData
141
+ * @private
142
+ */
143
+ private onMessage<Type extends MType = any>(payloadOrEnvelopeOrData: any): void {
144
+ const
145
+ // FIND THE `Message | NodeMessage` DEPENDING
146
+ // ON THE PROCESS AND TRANSPORT
147
+ payloadOrEnvelope = (
148
+ isDefined(payloadOrEnvelopeOrData?.["data"]) ?
149
+ payloadOrEnvelopeOrData["data"] :
150
+ payloadOrEnvelopeOrData
151
+ ) as Message<ReqMap, Type> | NodeMessage<ReqMap, Type>,
152
+
153
+ // FIND THE CHANNEL & PAYLOAD DEPENDING ON THE PROCESS & TRANSPORT
154
+ [channel, payload] =
155
+ (
156
+ isDefined(payloadOrEnvelope?.["payload"]) ?
157
+ [payloadOrEnvelope["channel"] ?? IPCChannel.UPMServiceMessage, payloadOrEnvelope["payload"]] :
158
+ [IPCChannel.UPMServiceMessage, payloadOrEnvelope]
159
+ ) as [string, Message<ReqMap, Type>],
160
+ { messageId, result, error } = payload
161
+
162
+ try {
163
+ const pending = this.pendingMessages_.get(messageId)
164
+ if (!pending) {
165
+ log.info(`Unable to find pending record ${messageId}`)
166
+ return
167
+ }
168
+
169
+ if (pending.deferred.isSettled()) {
170
+ log.error(`Already settled record ${messageId}`)
171
+ return
172
+ }
173
+
174
+ if (!!error) {
175
+ log.error(error)
176
+ pending.deferred.reject(new Error(error))
177
+ return
178
+ }
179
+ pending.deferred.resolve(result)
180
+ this.removePendingMessage(messageId)
181
+ } catch (err) {
182
+ log.error(`Failed to handle message`, err)
183
+ }
184
+ }
185
+
186
+
187
+ sendEvent(data: any): void {
188
+ const messageId = this.generateMessageId()
189
+ const payload: NodeEnvelope = {
190
+ channel: IPCChannel.UPMServiceMessage,
191
+ payload: { messageId, eventData: data, kind: MessageKind.Event }
192
+ }
193
+
194
+ this.port.postMessage(payload)
195
+ }
196
+
197
+ async executeRequest<
198
+ Type extends MType,
199
+ R extends MessageRequestReturnType<ReqMap, Type> = MessageRequestReturnType<ReqMap, Type>
200
+ >(
201
+ type: Type,
202
+ ...args: MessageRequestParams<ReqMap, Type>
203
+ ): Promise<R> {
204
+ const messageId = this.generateMessageId(),
205
+ pending: PendingRequestMessage<ReqMap, Type, R> = {
206
+ deferred: new Deferred<R>(),
207
+ messageId,
208
+ timeoutId: setTimeout(() => this.removePendingMessage(messageId), Defaults.RequestTimeout)
209
+ }
210
+
211
+ this.pendingMessages_.set(messageId, pending)
212
+ const payload: NodeMessage<ReqMap, Type> = {
213
+ channel: IPCChannel.UPMServiceMessage,
214
+ payload: { type, messageId, args, kind: MessageKind.Request }
215
+ }
216
+
217
+ this.port.postMessage(payload)
218
+
219
+ try {
220
+ const result = await pending.deferred.promise
221
+ log.debug(`Completed utility request (messageId=${messageId})`)
222
+ return result
223
+ } catch (err) {
224
+ log.error(`Failed utility request (messageId=${messageId})`, err)
225
+ throw err
226
+ }
227
+ }
228
+
229
+ close(): void {
230
+ }
231
+
232
+ whenReady(): Promise<this> {
233
+ return Promise.resolve(this)
234
+ }
235
+
236
+ /**
237
+ * Return a simple proxy facade wrapping
238
+ * `executeRequest` into individual methods
239
+ */
240
+ getServiceClient(): IServiceClient<ReqMap, MType> {
241
+ return new Proxy<IServiceClient<ReqMap, MType>>({} as any, {
242
+ get: (_target, prop) => {
243
+ if (prop === "then") {
244
+ return undefined
245
+ }
246
+ return (...args: any[]) => this.whenReady()
247
+ .then(client => client.executeRequest(prop as MType, ...args as any))
248
+
249
+ }
250
+ })
251
+ }
252
+
253
+ /**
254
+ * Create a new `MessagePortClient`
255
+ *
256
+ * @param clientId
257
+ * @param port
258
+ */
259
+ constructor(readonly clientId: string, readonly port: Port) {
260
+ if (isMessagePort(port) || isUtilityProcess(port)) {
261
+ if (isFunction(port?.["addEventListener"])) {
262
+ ;(
263
+ port as any
264
+ ).addEventListener("message", this.onMessage.bind(this))
265
+ } else {
266
+ port.on("message", this.onMessage.bind(this))
267
+ }
268
+ if (isMessagePort(port))
269
+ port.start()
270
+ } else {
271
+ log.error("Invalid port", port)
272
+ throw new Error("Invalid port")
273
+ }
274
+
275
+ }
276
+ }
@@ -0,0 +1,11 @@
1
+ import type { UtilityProcess } from "electron"
2
+ import { isFunction } from "@3fv/guard"
3
+ import { Port } from "./types.js"
4
+
5
+ export function isMessagePort(port: Port): port is Electron.MessagePortMain {
6
+ return isFunction(port?.["close"])
7
+ }
8
+
9
+ export function isUtilityProcess(port: Port): port is UtilityProcess {
10
+ return !!port && !isMessagePort(port)
11
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./types.js"
2
+ export * from "./guards.js"
3
+ export * from "./clients.js"
@@ -0,0 +1,106 @@
1
+ import type { UtilityProcess } from "electron"
2
+ import { Deferred } from "@3fv/deferred"
3
+
4
+
5
+ export const Defaults = { RequestTimeout: 120000 }
6
+
7
+ export enum MessageKind {
8
+ Event = "Event",
9
+ Request = "Request",
10
+ Response = "Response"
11
+ }
12
+
13
+ export enum IPCChannel {
14
+ UPMServiceMessage = "UPMServiceMessage",
15
+ UPMServiceNewClient = "UPMServiceNewClient"
16
+ }
17
+
18
+ export enum NodeMessageType {
19
+ UPMNodeEventMessage = "UPMNodeEventMessage",
20
+ UPMNodeRequestResponse = "UPMNodeRequestResponseMessage",
21
+ }
22
+
23
+ export type MessageRequestFnBase = (...args:any[]) => Promise<any>
24
+ export type MessageRequestMap = {}
25
+ export type MessageRequestNames<ReqMap extends MessageRequestMap> = keyof ReqMap
26
+ export type MessageRequestFn<ReqMap extends MessageRequestMap, Name extends MessageRequestNames<ReqMap>> = ReqMap[Name] extends MessageRequestFnBase ? ReqMap[Name] : never
27
+ export type MessageRequestParams<ReqMap extends MessageRequestMap, Name extends MessageRequestNames<ReqMap>> = ReqMap[Name] extends MessageRequestFnBase ? Parameters<ReqMap[Name]> : never
28
+ export type MessageRequestReturnType<ReqMap extends MessageRequestMap, Name extends MessageRequestNames<ReqMap>> = ReqMap[Name] extends MessageRequestFnBase ? Awaited<ReturnType<ReqMap[Name]>> : never
29
+
30
+ export interface Message<
31
+ ReqMap extends MessageRequestMap = any,
32
+ Type extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>,
33
+ Args extends MessageRequestParams<ReqMap, Type> = MessageRequestParams<ReqMap, Type>,
34
+ R extends MessageRequestReturnType<ReqMap, Type> = MessageRequestReturnType<ReqMap, Type>
35
+ >
36
+ {
37
+ type: Type;
38
+ kind: MessageKind;
39
+ messageId: number;
40
+ eventData?: any
41
+ args?: Args
42
+ result?: R
43
+ error?: string
44
+ }
45
+
46
+ export interface NodeEnvelope<Payload extends {} = any> {
47
+ channel: IPCChannel
48
+ payload: Payload
49
+ }
50
+
51
+ export type RequestHandler<
52
+ ReqMap extends MessageRequestMap = any,
53
+ Type extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>,
54
+ Args extends MessageRequestParams<ReqMap, Type> = MessageRequestParams<ReqMap, Type>,
55
+ R extends MessageRequestReturnType<ReqMap, Type> = MessageRequestReturnType<ReqMap, Type>
56
+ > = (type: Type, messageId: number, ...args: Args) => Promise<R>
57
+
58
+
59
+ export type NodeMessage<
60
+ ReqMap extends MessageRequestMap = any,
61
+ Type extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>> = NodeEnvelope<Message<ReqMap, Type>>
62
+
63
+ export interface PendingRequestMessage<
64
+ ReqMap extends MessageRequestMap = any,
65
+ Type extends MessageRequestNames<ReqMap> = MessageRequestNames<ReqMap>,
66
+ R extends MessageRequestReturnType<ReqMap, Type> = MessageRequestReturnType<ReqMap, Type>
67
+ >
68
+ {
69
+ deferred: Deferred<R>
70
+
71
+ timeoutId: ReturnType<typeof setTimeout>
72
+
73
+ messageId: number
74
+ }
75
+
76
+ /**
77
+ * @returns true if payload was handled, false if not
78
+ */
79
+ export type EventHandler = (clientId: string, port: Port, payload: any) => boolean
80
+
81
+ /**
82
+ * Port of any kind
83
+ */
84
+ export type Port = MessagePort | Electron.MessagePortMain | Electron.ParentPort | UtilityProcess
85
+
86
+ /**
87
+ * Debugging & Inspection config
88
+ */
89
+ export type ServiceInspectConfig = number | {
90
+ port: number
91
+ break?: boolean
92
+ }
93
+
94
+ /**
95
+ * Configuration to use when creating/launching
96
+ * a service (`Electron.UtilityProcess`)
97
+ */
98
+ export interface CreateServiceConfig {
99
+ serviceName: string
100
+ inspect: false | ServiceInspectConfig
101
+ }
102
+
103
+ /**
104
+ * Optional/Partial `CreateServiceConfig`
105
+ */
106
+ export type CreateServiceOptions = Partial<CreateServiceConfig>
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./common/index.js"
2
+ import * as UPM from "./common/index.js"
3
+
4
+ export {
5
+ UPM
6
+ }
7
+
8
+ export default UPM