electron-effect-rpc 0.2.0 → 0.3.0
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/README.md +78 -192
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/kit.d.ts +71 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +138 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +53 -4
- package/dist/preload.d.ts +4 -0
- package/dist/preload.d.ts.map +1 -1
- package/dist/preload.js +26 -1
- package/dist/renderer.d.ts +2 -2
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +27 -4
- package/dist/types.d.ts +5 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
# electron-effect-rpc
|
|
2
2
|
|
|
3
|
-
Typed IPC RPC for Electron, built on Effect and @effect/schema.
|
|
4
|
-
lets you define a shared contract, generate a typed RPC client in the renderer,
|
|
5
|
-
register handlers in the main process, and stream typed events across processes.
|
|
3
|
+
Typed IPC RPC for Electron, built on Effect and @effect/schema.
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
The ergonomic default is now a single shared `createIpcKit` configuration that
|
|
6
|
+
you reuse in main, preload, and renderer code. Low-level subpath APIs still
|
|
7
|
+
exist and remain fully supported.
|
|
8
|
+
|
|
9
|
+
This package is ESM-only. It targets modern Electron runtimes and assumes an
|
|
10
|
+
ESM-capable build pipeline.
|
|
9
11
|
|
|
10
12
|
## Features
|
|
11
13
|
- Single shared contract for methods and events.
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
14
|
+
- Single shared kit config to eliminate cross-process prefix drift.
|
|
15
|
+
- End-to-end schema validation at IPC boundaries.
|
|
16
|
+
- Promise-based renderer RPC with typed domain errors.
|
|
17
|
+
- Effect-native main handlers with explicit runtime injection.
|
|
18
|
+
- Explicit lifecycle handles and bounded event queue backpressure.
|
|
17
19
|
- Structured diagnostics hooks for decode/protocol/dispatch failures.
|
|
18
20
|
|
|
19
21
|
## Requirements
|
|
20
22
|
- Electron with context isolation enabled.
|
|
21
|
-
- ESM-capable
|
|
23
|
+
- ESM-capable bundling.
|
|
22
24
|
- Peer dependencies: `effect`, `@effect/schema`, `electron`.
|
|
23
25
|
|
|
24
26
|
## Installation
|
|
@@ -26,31 +28,12 @@ uses Electron 38) and assumes ESM-capable bundling.
|
|
|
26
28
|
bun add electron-effect-rpc effect @effect/schema
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
and let the workspace resolver handle the rest.
|
|
31
|
-
|
|
32
|
-
## Core Concepts
|
|
33
|
-
|
|
34
|
-
### Communication directions
|
|
35
|
-
|
|
36
|
-
This library provides two communication patterns for Electron IPC:
|
|
37
|
-
|
|
38
|
-
| Direction | Mechanism | Pattern | Use case |
|
|
39
|
-
|-----------|-----------|---------|----------|
|
|
40
|
-
| **Renderer → Main** | RPC methods | Request/response | Fetching data, triggering actions, calling main process APIs |
|
|
41
|
-
| **Main → Renderer** | Event bus | Push/broadcast | Progress updates, state changes, background task notifications |
|
|
42
|
-
|
|
43
|
-
**RPC methods** are for when the renderer needs something from the main process. The renderer calls a method and awaits a typed response.
|
|
44
|
-
|
|
45
|
-
**Events** are for when the main process needs to notify the renderer. The main process emits events whenever it wants, and the renderer subscribes to receive them.
|
|
46
|
-
|
|
47
|
-
### Defining methods and events
|
|
48
|
-
|
|
49
|
-
Define methods and events using schema-based helpers:
|
|
31
|
+
## Quickstart (Kit-First)
|
|
50
32
|
|
|
33
|
+
### 1) Define contract and kit once
|
|
51
34
|
```ts
|
|
52
35
|
import * as S from "@effect/schema/Schema";
|
|
53
|
-
import { defineContract, event, rpc } from "electron-effect-rpc
|
|
36
|
+
import { createIpcKit, defineContract, event, rpc } from "electron-effect-rpc";
|
|
54
37
|
|
|
55
38
|
export const GetAppVersion = rpc(
|
|
56
39
|
"GetAppVersion",
|
|
@@ -67,218 +50,121 @@ export const WorkUnitProgress = event(
|
|
|
67
50
|
})
|
|
68
51
|
);
|
|
69
52
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Errors
|
|
77
|
-
Error schemas should be `Schema.TaggedError` classes. If a method does not
|
|
78
|
-
declare an error schema, it uses `NoError` and the error channel is `never`.
|
|
53
|
+
const contract = defineContract({
|
|
54
|
+
methods: [GetAppVersion] as const,
|
|
55
|
+
events: [WorkUnitProgress] as const,
|
|
56
|
+
});
|
|
79
57
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
path: S.String,
|
|
87
|
-
}) {}
|
|
88
|
-
|
|
89
|
-
export const ReadTextFile = rpc(
|
|
90
|
-
"ReadTextFile",
|
|
91
|
-
S.Struct({ path: S.String }),
|
|
92
|
-
S.Struct({ content: S.String }),
|
|
93
|
-
FileReadError
|
|
94
|
-
);
|
|
58
|
+
export const ipc = createIpcKit({
|
|
59
|
+
contract,
|
|
60
|
+
channelPrefix: { rpc: "rpc/", event: "event/" },
|
|
61
|
+
bridge: { global: "api" },
|
|
62
|
+
decode: { rpc: "envelope", events: "safe" },
|
|
63
|
+
});
|
|
95
64
|
```
|
|
96
65
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
### Main process: register handlers
|
|
66
|
+
### 2) Main process
|
|
100
67
|
```ts
|
|
101
68
|
import { app, ipcMain } from "electron";
|
|
102
69
|
import { Effect } from "effect";
|
|
103
70
|
import * as Runtime from "effect/Runtime";
|
|
104
|
-
import {
|
|
105
|
-
import { contract, WorkUnitProgress } from "./contract.ts";
|
|
106
|
-
|
|
107
|
-
const implementations = {
|
|
108
|
-
GetAppVersion: () => Effect.succeed({ version: app.getVersion() }),
|
|
109
|
-
};
|
|
71
|
+
import { ipc, WorkUnitProgress } from "./shared-ipc.ts";
|
|
110
72
|
|
|
111
|
-
const
|
|
73
|
+
const mainRpc = ipc.main({
|
|
74
|
+
ipcMain,
|
|
75
|
+
handlers: {
|
|
76
|
+
GetAppVersion: () => Effect.succeed({ version: app.getVersion() }),
|
|
77
|
+
},
|
|
112
78
|
runtime: Runtime.defaultRuntime,
|
|
113
|
-
});
|
|
114
|
-
endpoint.start();
|
|
115
|
-
|
|
116
|
-
const publisher = createEventPublisher(contract, {
|
|
117
79
|
getWindow: () => mainWindow,
|
|
118
80
|
});
|
|
119
|
-
publisher.start();
|
|
120
81
|
|
|
121
|
-
|
|
82
|
+
mainRpc.start();
|
|
83
|
+
|
|
84
|
+
void mainRpc.emit(WorkUnitProgress, {
|
|
122
85
|
requestId: "req-1",
|
|
123
|
-
chunk: "
|
|
86
|
+
chunk: "starting",
|
|
124
87
|
done: false,
|
|
125
88
|
});
|
|
126
|
-
```
|
|
127
89
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```ts
|
|
131
|
-
import * as Runtime from "effect/Runtime";
|
|
132
|
-
import { createRpcEndpoint } from "electron-effect-rpc/main";
|
|
133
|
-
import { contract } from "./contract.ts";
|
|
134
|
-
|
|
135
|
-
const endpoint = createRpcEndpoint(contract, ipcMain, implementations, {
|
|
136
|
-
runtime: Runtime.defaultRuntime,
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
endpoint.start();
|
|
90
|
+
// Effect-native alternative:
|
|
91
|
+
// void Effect.runPromise(mainRpc.publish(WorkUnitProgress, {...}));
|
|
140
92
|
```
|
|
141
93
|
|
|
142
|
-
### Preload
|
|
94
|
+
### 3) Preload
|
|
143
95
|
```ts
|
|
144
|
-
import {
|
|
145
|
-
|
|
146
|
-
exposeRpcBridge();
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Defaults:
|
|
150
|
-
- RPC global: `window.rpc.invoke(method, payload)`
|
|
151
|
-
- Events global: `window.events.subscribe(name, handler)`
|
|
152
|
-
- Channel prefix: `rpc/` and `event/`
|
|
96
|
+
import { ipc } from "./shared-ipc.ts";
|
|
153
97
|
|
|
154
|
-
|
|
155
|
-
```ts
|
|
156
|
-
exposeRpcBridge({
|
|
157
|
-
rpcGlobal: "rpcApi",
|
|
158
|
-
eventsGlobal: "rpcEvents",
|
|
159
|
-
channelPrefix: { rpc: "rpc/", event: "events/" },
|
|
160
|
-
});
|
|
98
|
+
ipc.preload().expose();
|
|
161
99
|
```
|
|
162
100
|
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
import { createBridgeAdapters } from "electron-effect-rpc/preload";
|
|
166
|
-
|
|
167
|
-
const bridge = createBridgeAdapters();
|
|
168
|
-
// bridge.invoke(method, payload)
|
|
169
|
-
// bridge.subscribe(name, handler)
|
|
170
|
-
```
|
|
101
|
+
This exposes one global by default: `window.api`.
|
|
171
102
|
|
|
172
|
-
### Renderer
|
|
103
|
+
### 4) Renderer
|
|
173
104
|
```ts
|
|
174
|
-
import {
|
|
175
|
-
import { contract, WorkUnitProgress } from "./contract.ts";
|
|
176
|
-
|
|
177
|
-
const client = createRpcClient(contract, { invoke: window.rpc.invoke });
|
|
178
|
-
const events = createEventSubscriber(contract, {
|
|
179
|
-
subscribe: window.events.subscribe,
|
|
180
|
-
decodeMode: "safe", // default
|
|
181
|
-
});
|
|
105
|
+
import { ipc, WorkUnitProgress } from "./shared-ipc.ts";
|
|
182
106
|
|
|
107
|
+
const { client, events } = ipc.renderer(window.api);
|
|
183
108
|
const { version } = await client.GetAppVersion();
|
|
184
109
|
|
|
185
|
-
events.subscribe(WorkUnitProgress, (payload) => {
|
|
110
|
+
const unsubscribe = events.subscribe(WorkUnitProgress, (payload) => {
|
|
186
111
|
console.log(payload.chunk);
|
|
187
112
|
});
|
|
188
|
-
```
|
|
189
113
|
|
|
190
|
-
|
|
191
|
-
|
|
114
|
+
// later
|
|
115
|
+
unsubscribe();
|
|
116
|
+
events.dispose();
|
|
117
|
+
```
|
|
192
118
|
|
|
119
|
+
### 5) Window typing
|
|
193
120
|
```ts
|
|
194
121
|
declare global {
|
|
195
122
|
interface Window {
|
|
196
|
-
|
|
123
|
+
api: {
|
|
197
124
|
invoke: (method: string, payload: unknown) => Promise<unknown>;
|
|
198
|
-
};
|
|
199
|
-
events: {
|
|
200
125
|
subscribe: (name: string, handler: (payload: unknown) => void) => () => void;
|
|
201
126
|
};
|
|
202
127
|
}
|
|
203
128
|
}
|
|
204
129
|
```
|
|
205
130
|
|
|
206
|
-
##
|
|
207
|
-
|
|
208
|
-
### Renderer client tests
|
|
209
|
-
Use the testing helpers to stub invoke behavior:
|
|
210
|
-
|
|
211
|
-
```ts
|
|
212
|
-
import { createRpcClient } from "electron-effect-rpc/renderer";
|
|
213
|
-
import { createInvokeStub } from "electron-effect-rpc/testing";
|
|
214
|
-
import { contract } from "./contract.ts";
|
|
215
|
-
|
|
216
|
-
const invoke = createInvokeStub(async (method, payload) => {
|
|
217
|
-
return {
|
|
218
|
-
type: "success",
|
|
219
|
-
data: { version: "1.0.0" },
|
|
220
|
-
};
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
const client = createRpcClient(contract, { invoke });
|
|
224
|
-
await client.GetAppVersion();
|
|
225
|
-
|
|
226
|
-
expect(invoke.invocations).toEqual([
|
|
227
|
-
{ method: "GetAppVersion", payload: {} },
|
|
228
|
-
]);
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### Main process tests
|
|
232
|
-
You can stub `IpcMainLike` and collect registered handlers:
|
|
131
|
+
## Error Model
|
|
233
132
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
import type { IpcMainLike } from "electron-effect-rpc/types";
|
|
238
|
-
import { contract } from "./contract.ts";
|
|
239
|
-
|
|
240
|
-
const handlers = new Map<string, (event: unknown, payload: unknown) => unknown>();
|
|
241
|
-
const ipcMainStub: IpcMainLike = {
|
|
242
|
-
handle: (channel, handler) => {
|
|
243
|
-
handlers.set(channel, handler);
|
|
244
|
-
},
|
|
245
|
-
removeHandler: (channel) => {
|
|
246
|
-
handlers.delete(channel);
|
|
247
|
-
},
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const endpoint = createRpcEndpoint(contract, ipcMainStub, implementations, {
|
|
251
|
-
runtime: Runtime.defaultRuntime,
|
|
252
|
-
});
|
|
253
|
-
endpoint.start();
|
|
254
|
-
```
|
|
133
|
+
Domain failures are modeled with tagged error schemas and are re-thrown in the
|
|
134
|
+
renderer as those same error classes. Unexpected failures, transport defects,
|
|
135
|
+
and protocol mismatches are surfaced as `RpcDefectError`.
|
|
255
136
|
|
|
256
|
-
##
|
|
257
|
-
- If a handler fails with a typed domain error, the renderer client rejects
|
|
258
|
-
with that error instance.
|
|
259
|
-
- If a handler dies or throws a defect, the renderer client rejects with
|
|
260
|
-
`RpcDefectError`.
|
|
137
|
+
## Low-Level APIs (Still Supported)
|
|
261
138
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
Entry points:
|
|
139
|
+
If you need direct control, keep using subpath entry points:
|
|
265
140
|
- `electron-effect-rpc/contract`
|
|
266
|
-
- `rpc`, `event`, `defineContract`, `exitSchemaFor`, `SchemaNoContext`, `NoError`
|
|
267
|
-
- `electron-effect-rpc/types`
|
|
268
|
-
- Type aliases such as `Implementations`, `RpcClient`, `RpcEventPublisher`, `IpcMainLike`
|
|
269
141
|
- `electron-effect-rpc/main`
|
|
270
|
-
- `createRpcEndpoint`, `createEventPublisher`
|
|
271
142
|
- `electron-effect-rpc/renderer`
|
|
272
|
-
- `createRpcClient`, `createEventSubscriber`, `RpcDefectError`
|
|
273
143
|
- `electron-effect-rpc/preload`
|
|
274
|
-
|
|
144
|
+
- `electron-effect-rpc/types`
|
|
275
145
|
- `electron-effect-rpc/testing`
|
|
276
|
-
|
|
146
|
+
|
|
147
|
+
## Root API Surface
|
|
148
|
+
|
|
149
|
+
The root entry point exports:
|
|
150
|
+
- `createIpcKit`
|
|
151
|
+
- `rpc`, `event`, `defineContract`, `NoError`
|
|
152
|
+
- Types: `IpcKit`, `IpcKitOptions`, `IpcMainHandle`, `IpcBridge`, `IpcBridgeGlobal`
|
|
153
|
+
|
|
154
|
+
Low-level factories like `createRpcClient` remain subpath-only by design.
|
|
155
|
+
|
|
156
|
+
## Tutorials
|
|
157
|
+
|
|
158
|
+
For deeper walkthroughs and production guidance:
|
|
159
|
+
- [Tutorial Index](./docs/tutorials/README.md)
|
|
160
|
+
- [First RPC: Main + Preload + Renderer](./docs/tutorials/01-first-rpc.md)
|
|
161
|
+
- [Typed Errors, Defects, and Diagnostics](./docs/tutorials/02-typed-errors-defects-diagnostics.md)
|
|
162
|
+
- [Events, Lifecycle, and Backpressure](./docs/tutorials/03-events-lifecycle-backpressure.md)
|
|
277
163
|
|
|
278
164
|
## Conventions
|
|
279
165
|
- Relative imports use `.ts` extensions.
|
|
280
166
|
- Package imports are extensionless.
|
|
281
|
-
- No `index.ts` barrel files.
|
|
167
|
+
- No `index.ts` barrel files in subpath modules.
|
|
282
168
|
|
|
283
169
|
## License
|
|
284
170
|
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EACV,SAAS,EACT,eAAe,EACf,MAAM,EACN,aAAa,EACb,aAAa,GACd,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
package/dist/kit.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type * as Runtime from "effect/Runtime";
|
|
3
|
+
import type { AnyEvent, AnyMethod, RpcContract, RpcEventPayload } from "./contract.ts";
|
|
4
|
+
import { type ChannelPrefix, type EventDecodeMode, type EventPublisherDiagnostics, type EventSubscribe, type EventSubscriber, type IpcMainLike, type Implementations, type RendererWindowLike, type RpcClient, type RpcEndpoint, type RpcEndpointDiagnostics, type RpcEventPublisher, type RpcInvoke, type RpcResponseDecodeMode } from "./types.ts";
|
|
5
|
+
export type IpcBridge = {
|
|
6
|
+
readonly invoke: RpcInvoke;
|
|
7
|
+
readonly subscribe: EventSubscribe;
|
|
8
|
+
};
|
|
9
|
+
export type IpcBridgeGlobal<Name extends string = "api"> = {
|
|
10
|
+
readonly [K in Name]: IpcBridge;
|
|
11
|
+
};
|
|
12
|
+
export type IpcKitOptions<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>> = {
|
|
13
|
+
readonly contract: C;
|
|
14
|
+
readonly channelPrefix?: ChannelPrefix;
|
|
15
|
+
readonly bridge?: {
|
|
16
|
+
readonly global?: string;
|
|
17
|
+
};
|
|
18
|
+
readonly decode?: {
|
|
19
|
+
readonly rpc?: RpcResponseDecodeMode;
|
|
20
|
+
readonly events?: EventDecodeMode;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
type IpcMainOptions<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>, R> = {
|
|
24
|
+
readonly ipcMain: IpcMainLike;
|
|
25
|
+
readonly handlers: Implementations<C, R>;
|
|
26
|
+
readonly runtime: Runtime.Runtime<R>;
|
|
27
|
+
readonly getWindow: () => RendererWindowLike | null;
|
|
28
|
+
readonly maxQueueSize?: number;
|
|
29
|
+
readonly diagnostics?: {
|
|
30
|
+
readonly rpc?: RpcEndpointDiagnostics;
|
|
31
|
+
readonly events?: EventPublisherDiagnostics;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export type IpcMainHandle<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>> = {
|
|
35
|
+
readonly endpoint: RpcEndpoint;
|
|
36
|
+
readonly publisher: RpcEventPublisher<C>;
|
|
37
|
+
readonly start: () => void;
|
|
38
|
+
readonly stop: () => void;
|
|
39
|
+
readonly dispose: () => void;
|
|
40
|
+
readonly isRunning: () => boolean;
|
|
41
|
+
readonly publish: <E extends C["events"][number]>(event: E, payload: RpcEventPayload<E>) => Effect.Effect<void, never>;
|
|
42
|
+
readonly emit: <E extends C["events"][number]>(event: E, payload: RpcEventPayload<E>) => Promise<void>;
|
|
43
|
+
readonly stats: () => {
|
|
44
|
+
readonly queued: number;
|
|
45
|
+
readonly dropped: number;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export type IpcKit<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>> = {
|
|
49
|
+
readonly contract: C;
|
|
50
|
+
readonly config: {
|
|
51
|
+
readonly channelPrefix: ChannelPrefix;
|
|
52
|
+
readonly bridgeGlobal: string;
|
|
53
|
+
readonly rpcDecodeMode: RpcResponseDecodeMode;
|
|
54
|
+
readonly eventDecodeMode: EventDecodeMode;
|
|
55
|
+
};
|
|
56
|
+
readonly main: <R>(options: IpcMainOptions<C, R>) => IpcMainHandle<C>;
|
|
57
|
+
readonly preload: (options?: {
|
|
58
|
+
readonly global?: string;
|
|
59
|
+
}) => {
|
|
60
|
+
readonly global: string;
|
|
61
|
+
readonly bridge: IpcBridge;
|
|
62
|
+
readonly expose: () => void;
|
|
63
|
+
};
|
|
64
|
+
readonly renderer: (bridge: IpcBridge) => {
|
|
65
|
+
readonly client: RpcClient<C>;
|
|
66
|
+
readonly events: EventSubscriber<C>;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export declare function createIpcKit<const Methods extends ReadonlyArray<AnyMethod>, const Events extends ReadonlyArray<AnyEvent>>(options: IpcKitOptions<RpcContract<Methods, Events>>): IpcKit<RpcContract<Methods, Events>>;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIvF,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,KAAK,IAAI;IACzD,QAAQ,EAAE,CAAC,IAAI,IAAI,GAAG,SAAS;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,CACvB,CAAC,SAAS,WAAW,CAAC,SAAS,SAAS,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,IAC9D;IACF,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,GAAG,CAAC,EAAE,qBAAqB,CAAC;QACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;KACnC,CAAC;CACH,CAAC;AAEF,KAAK,cAAc,CACjB,CAAC,SAAS,WAAW,CAAC,SAAS,SAAS,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,EAChE,CAAC,IACC;IACF,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAAC;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,sBAAsB,CAAC;QACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,yBAAyB,CAAC;KAC7C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,CACvB,CAAC,SAAS,WAAW,CAAC,SAAS,SAAS,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,IAC9D;IACF,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAC9C,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAC3C,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,KACxB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM;QACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,CAChB,CAAC,SAAS,WAAW,CAAC,SAAS,SAAS,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,IAC9D;IACF,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;QACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;QAC9C,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;KAC3C,CAAC;IACF,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK;QAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;KAC7B,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK;QACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;KACrC,CAAC;CACH,CAAC;AAEF,wBAAgB,YAAY,CAC1B,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAE5C,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,GACnD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CA8JtC"}
|
package/dist/kit.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { createEventPublisher, createRpcEndpoint } from "./main.js";
|
|
3
|
+
import { exposeIpcBridge, createBridgeAdapters } from "./preload.js";
|
|
4
|
+
import { createEventSubscriber, createRpcClient } from "./renderer.js";
|
|
5
|
+
import { defaultChannelPrefix, } from "./types.js";
|
|
6
|
+
export function createIpcKit(options) {
|
|
7
|
+
const contract = options.contract;
|
|
8
|
+
const channelPrefix = options.channelPrefix
|
|
9
|
+
? { ...options.channelPrefix }
|
|
10
|
+
: { ...defaultChannelPrefix };
|
|
11
|
+
const bridgeGlobal = options.bridge?.global ?? "api";
|
|
12
|
+
const rpcDecodeMode = options.decode?.rpc ?? "envelope";
|
|
13
|
+
const eventDecodeMode = options.decode?.events ?? "safe";
|
|
14
|
+
const main = (mainOptions) => {
|
|
15
|
+
const endpoint = createRpcEndpoint(contract, mainOptions.ipcMain, mainOptions.handlers, {
|
|
16
|
+
runtime: mainOptions.runtime,
|
|
17
|
+
channelPrefix,
|
|
18
|
+
diagnostics: mainOptions.diagnostics?.rpc,
|
|
19
|
+
});
|
|
20
|
+
const publisher = createEventPublisher(contract, {
|
|
21
|
+
getWindow: mainOptions.getWindow,
|
|
22
|
+
maxQueueSize: mainOptions.maxQueueSize,
|
|
23
|
+
channelPrefix,
|
|
24
|
+
diagnostics: mainOptions.diagnostics?.events,
|
|
25
|
+
});
|
|
26
|
+
function start() {
|
|
27
|
+
endpoint.start();
|
|
28
|
+
try {
|
|
29
|
+
publisher.start();
|
|
30
|
+
}
|
|
31
|
+
catch (cause) {
|
|
32
|
+
try {
|
|
33
|
+
endpoint.stop();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Best effort rollback.
|
|
37
|
+
}
|
|
38
|
+
throw cause;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function stop() {
|
|
42
|
+
let firstError;
|
|
43
|
+
try {
|
|
44
|
+
publisher.stop();
|
|
45
|
+
}
|
|
46
|
+
catch (cause) {
|
|
47
|
+
firstError ??= cause;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
endpoint.stop();
|
|
51
|
+
}
|
|
52
|
+
catch (cause) {
|
|
53
|
+
firstError ??= cause;
|
|
54
|
+
}
|
|
55
|
+
if (firstError !== undefined) {
|
|
56
|
+
throw firstError;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function dispose() {
|
|
60
|
+
let firstError;
|
|
61
|
+
try {
|
|
62
|
+
publisher.dispose();
|
|
63
|
+
}
|
|
64
|
+
catch (cause) {
|
|
65
|
+
firstError ??= cause;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
endpoint.dispose();
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
firstError ??= cause;
|
|
72
|
+
}
|
|
73
|
+
if (firstError !== undefined) {
|
|
74
|
+
throw firstError;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function isRunning() {
|
|
78
|
+
return endpoint.isRunning() && publisher.isRunning();
|
|
79
|
+
}
|
|
80
|
+
function publish(event, payload) {
|
|
81
|
+
return publisher.publish(event, payload);
|
|
82
|
+
}
|
|
83
|
+
function emit(event, payload) {
|
|
84
|
+
return Effect.runPromise(publisher.publish(event, payload));
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
endpoint,
|
|
88
|
+
publisher,
|
|
89
|
+
start,
|
|
90
|
+
stop,
|
|
91
|
+
dispose,
|
|
92
|
+
isRunning,
|
|
93
|
+
publish,
|
|
94
|
+
emit,
|
|
95
|
+
stats: publisher.stats,
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
const preload = (preloadOptions) => {
|
|
99
|
+
const global = preloadOptions?.global ?? bridgeGlobal;
|
|
100
|
+
const bridge = createBridgeAdapters({
|
|
101
|
+
channelPrefix,
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
global,
|
|
105
|
+
bridge,
|
|
106
|
+
expose: () => {
|
|
107
|
+
exposeIpcBridge({
|
|
108
|
+
global,
|
|
109
|
+
channelPrefix,
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
const renderer = (bridge) => {
|
|
115
|
+
return {
|
|
116
|
+
client: createRpcClient(contract, {
|
|
117
|
+
invoke: bridge.invoke,
|
|
118
|
+
rpcDecodeMode,
|
|
119
|
+
}),
|
|
120
|
+
events: createEventSubscriber(contract, {
|
|
121
|
+
subscribe: bridge.subscribe,
|
|
122
|
+
decodeMode: eventDecodeMode,
|
|
123
|
+
}),
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
contract,
|
|
128
|
+
config: {
|
|
129
|
+
channelPrefix,
|
|
130
|
+
bridgeGlobal,
|
|
131
|
+
rpcDecodeMode,
|
|
132
|
+
eventDecodeMode,
|
|
133
|
+
},
|
|
134
|
+
main,
|
|
135
|
+
preload,
|
|
136
|
+
renderer,
|
|
137
|
+
};
|
|
138
|
+
}
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,eAAe,CAAC;AAQvB,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAmBpB,wBAAgB,iBAAiB,CAC/B,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAC5C,CAAC,GAAG,KAAK,EAET,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EACjE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,WAAW,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,eAAe,CAAC;AAQvB,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAmBpB,wBAAgB,iBAAiB,CAC/B,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAC5C,CAAC,GAAG,KAAK,EAET,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EACjE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,WAAW,CAgNb;AAmBD,wBAAgB,oBAAoB,CAClC,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAE5C,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACvC,OAAO,EAAE,qBAAqB,GAC7B,iBAAiB,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAkMjD"}
|
package/dist/main.js
CHANGED
|
@@ -109,8 +109,23 @@ export function createRpcEndpoint(contract, ipc, implementations, options) {
|
|
|
109
109
|
if (running) {
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
const registeredChannels = [];
|
|
113
|
+
try {
|
|
114
|
+
for (const [channel, listener] of listeners) {
|
|
115
|
+
ipc.handle(channel, listener);
|
|
116
|
+
registeredChannels.push(channel);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (cause) {
|
|
120
|
+
for (const channel of registeredChannels) {
|
|
121
|
+
try {
|
|
122
|
+
ipc.removeHandler(channel);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Best-effort rollback: avoid leaving partial registration behind.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
throw cause;
|
|
114
129
|
}
|
|
115
130
|
running = true;
|
|
116
131
|
}
|
|
@@ -118,17 +133,35 @@ export function createRpcEndpoint(contract, ipc, implementations, options) {
|
|
|
118
133
|
if (!running) {
|
|
119
134
|
return;
|
|
120
135
|
}
|
|
136
|
+
let firstError;
|
|
121
137
|
for (const channel of listeners.keys()) {
|
|
122
|
-
|
|
138
|
+
try {
|
|
139
|
+
ipc.removeHandler(channel);
|
|
140
|
+
}
|
|
141
|
+
catch (cause) {
|
|
142
|
+
firstError ??= cause;
|
|
143
|
+
}
|
|
123
144
|
}
|
|
124
145
|
running = false;
|
|
146
|
+
if (firstError !== undefined) {
|
|
147
|
+
throw firstError;
|
|
148
|
+
}
|
|
125
149
|
}
|
|
126
150
|
function dispose() {
|
|
127
151
|
if (disposed) {
|
|
128
152
|
return;
|
|
129
153
|
}
|
|
130
|
-
|
|
154
|
+
let stopError;
|
|
155
|
+
try {
|
|
156
|
+
stop();
|
|
157
|
+
}
|
|
158
|
+
catch (cause) {
|
|
159
|
+
stopError = cause;
|
|
160
|
+
}
|
|
131
161
|
disposed = true;
|
|
162
|
+
if (stopError !== undefined) {
|
|
163
|
+
throw stopError;
|
|
164
|
+
}
|
|
132
165
|
}
|
|
133
166
|
function isRunning() {
|
|
134
167
|
return running;
|
|
@@ -193,17 +226,33 @@ export function createEventPublisher(_contract, options) {
|
|
|
193
226
|
}
|
|
194
227
|
const window = options.getWindow();
|
|
195
228
|
if (!window || window.isDestroyed()) {
|
|
229
|
+
dropped += 1;
|
|
230
|
+
safelyCall(diagnostics?.onDroppedEvent, {
|
|
231
|
+
event: item.event.name,
|
|
232
|
+
payload: item.payload,
|
|
233
|
+
reason: "window_unavailable",
|
|
234
|
+
queued: queue.length,
|
|
235
|
+
dropped,
|
|
236
|
+
});
|
|
196
237
|
return;
|
|
197
238
|
}
|
|
198
239
|
try {
|
|
199
240
|
window.webContents.send(`${channelPrefix.event}${item.event.name}`, encoded);
|
|
200
241
|
}
|
|
201
242
|
catch (cause) {
|
|
243
|
+
dropped += 1;
|
|
202
244
|
safelyCall(diagnostics?.onDispatchFailure, {
|
|
203
245
|
event: item.event.name,
|
|
204
246
|
payload: item.payload,
|
|
205
247
|
cause,
|
|
206
248
|
});
|
|
249
|
+
safelyCall(diagnostics?.onDroppedEvent, {
|
|
250
|
+
event: item.event.name,
|
|
251
|
+
payload: item.payload,
|
|
252
|
+
reason: "dispatch_failed",
|
|
253
|
+
queued: queue.length,
|
|
254
|
+
dropped,
|
|
255
|
+
});
|
|
207
256
|
}
|
|
208
257
|
}
|
|
209
258
|
function drain() {
|
package/dist/preload.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export type BridgeExposureOptions = BridgeAdaptersOptions & {
|
|
|
10
10
|
readonly rpcGlobal?: string;
|
|
11
11
|
readonly eventsGlobal?: string;
|
|
12
12
|
};
|
|
13
|
+
export type IpcBridgeExposureOptions = BridgeAdaptersOptions & {
|
|
14
|
+
readonly global?: string;
|
|
15
|
+
};
|
|
13
16
|
export declare function createBridgeAdapters(options?: BridgeAdaptersOptions): BridgeAdapters;
|
|
14
17
|
export declare function exposeRpcBridge(options?: BridgeExposureOptions): void;
|
|
18
|
+
export declare function exposeIpcBridge(options?: IpcBridgeExposureOptions): void;
|
|
15
19
|
//# sourceMappingURL=preload.d.ts.map
|
package/dist/preload.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../src/preload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../src/preload.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,qBAAqB,GAAG;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,GAAG;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAwCF,wBAAgB,oBAAoB,CAClC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAuBhB;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAgBrE;AAED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAYxE"}
|
package/dist/preload.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as electronModule from "electron";
|
|
2
2
|
import { defaultChannelPrefix, } from "./types.js";
|
|
3
|
+
function resolveElectronRendererBindings() {
|
|
4
|
+
const moduleDefault = electronModule.default;
|
|
5
|
+
const source = moduleDefault && typeof moduleDefault === "object"
|
|
6
|
+
? moduleDefault
|
|
7
|
+
: electronModule;
|
|
8
|
+
const contextBridge = source.contextBridge;
|
|
9
|
+
const ipcRenderer = source.ipcRenderer;
|
|
10
|
+
if (!contextBridge || !ipcRenderer) {
|
|
11
|
+
throw new Error("electron-effect-rpc/preload requires Electron preload runtime bindings.");
|
|
12
|
+
}
|
|
13
|
+
return { contextBridge, ipcRenderer };
|
|
14
|
+
}
|
|
3
15
|
export function createBridgeAdapters(options) {
|
|
4
16
|
const channelPrefix = options?.channelPrefix ?? defaultChannelPrefix;
|
|
17
|
+
const { ipcRenderer } = resolveElectronRendererBindings();
|
|
5
18
|
const invoke = (method, payload) => ipcRenderer.invoke(`${channelPrefix.rpc}${method}`, payload);
|
|
6
19
|
const subscribe = (event, listener) => {
|
|
7
20
|
const wrapped = (_event, payload) => listener(payload);
|
|
@@ -19,6 +32,7 @@ export function createBridgeAdapters(options) {
|
|
|
19
32
|
export function exposeRpcBridge(options) {
|
|
20
33
|
const rpcGlobal = options?.rpcGlobal ?? "rpc";
|
|
21
34
|
const eventsGlobal = options?.eventsGlobal ?? "events";
|
|
35
|
+
const { contextBridge } = resolveElectronRendererBindings();
|
|
22
36
|
const adapters = createBridgeAdapters({
|
|
23
37
|
channelPrefix: options?.channelPrefix,
|
|
24
38
|
});
|
|
@@ -29,3 +43,14 @@ export function exposeRpcBridge(options) {
|
|
|
29
43
|
subscribe: adapters.subscribe,
|
|
30
44
|
});
|
|
31
45
|
}
|
|
46
|
+
export function exposeIpcBridge(options) {
|
|
47
|
+
const global = options?.global ?? "api";
|
|
48
|
+
const { contextBridge } = resolveElectronRendererBindings();
|
|
49
|
+
const adapters = createBridgeAdapters({
|
|
50
|
+
channelPrefix: options?.channelPrefix,
|
|
51
|
+
});
|
|
52
|
+
contextBridge.exposeInMainWorld(global, {
|
|
53
|
+
invoke: adapters.invoke,
|
|
54
|
+
subscribe: adapters.subscribe,
|
|
55
|
+
});
|
|
56
|
+
}
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RpcContract } from "./contract.ts";
|
|
2
2
|
import { type AnyEvent, type AnyMethod, type EventSubscriber, type EventSubscriberOptions, type RpcClient, type RpcClientOptions } from "./types.ts";
|
|
3
|
-
export declare function createRpcClient<const Methods extends ReadonlyArray<AnyMethod>, const Events extends ReadonlyArray<AnyEvent>>(contract: RpcContract<Methods, Events>, options
|
|
4
|
-
export declare function createEventSubscriber<const Methods extends ReadonlyArray<AnyMethod>, const Events extends ReadonlyArray<AnyEvent>>(contract: RpcContract<Methods, Events>, options
|
|
3
|
+
export declare function createRpcClient<const Methods extends ReadonlyArray<AnyMethod>, const Events extends ReadonlyArray<AnyEvent>>(contract: RpcContract<Methods, Events>, options: RpcClientOptions): RpcClient<RpcContract<Methods, Events>>;
|
|
4
|
+
export declare function createEventSubscriber<const Methods extends ReadonlyArray<AnyMethod>, const Events extends ReadonlyArray<AnyEvent>>(contract: RpcContract<Methods, Events>, options: EventSubscriberOptions): EventSubscriber<RpcContract<Methods, Events>>;
|
|
5
5
|
export { RpcDefectError } from "./types.ts";
|
|
6
6
|
//# sourceMappingURL=renderer.d.ts.map
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,WAAW,EAIjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAGd,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,KAAK,gBAAgB,EAEtB,MAAM,YAAY,CAAC;AAuDpB,wBAAgB,eAAe,CAC7B,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAE5C,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,WAAW,EAIjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAGd,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,KAAK,gBAAgB,EAEtB,MAAM,YAAY,CAAC;AAuDpB,wBAAgB,eAAe,CAC7B,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAE5C,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,OAAO,EAAE,gBAAgB,GACxB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAwIzC;AAqBD,wBAAgB,qBAAqB,CACnC,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,EAC9C,KAAK,CAAC,MAAM,SAAS,aAAa,CAAC,QAAQ,CAAC,EAE5C,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAyF/C;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/renderer.js
CHANGED
|
@@ -54,7 +54,18 @@ export function createRpcClient(contract, options) {
|
|
|
54
54
|
});
|
|
55
55
|
throw new Error(`RPC ${method.name} request encoding failed: ${formatUnknown(cause)}`);
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
let raw;
|
|
58
|
+
try {
|
|
59
|
+
raw = await invoke(method.name, encoded);
|
|
60
|
+
}
|
|
61
|
+
catch (cause) {
|
|
62
|
+
safelyCall(diagnostics?.onProtocolError, {
|
|
63
|
+
method: method.name,
|
|
64
|
+
response: undefined,
|
|
65
|
+
cause,
|
|
66
|
+
});
|
|
67
|
+
throw new RpcDefectError(`RPC ${method.name} invoke failed: ${formatUnknown(cause)}`, cause);
|
|
68
|
+
}
|
|
58
69
|
const envelope = parseRpcResponseEnvelope(raw);
|
|
59
70
|
if (envelope) {
|
|
60
71
|
switch (envelope.type) {
|
|
@@ -117,8 +128,11 @@ export function createRpcClient(contract, options) {
|
|
|
117
128
|
const client = Object.create(null);
|
|
118
129
|
const clientRecord = client;
|
|
119
130
|
for (const method of contract.methods) {
|
|
120
|
-
const
|
|
121
|
-
|
|
131
|
+
const decodeDefaultInput = S.decodeUnknownSync(method.req);
|
|
132
|
+
const caller = (...args) => {
|
|
133
|
+
const payload = args.length === 0
|
|
134
|
+
? decodeDefaultInput({})
|
|
135
|
+
: args[0];
|
|
122
136
|
return call(method, payload);
|
|
123
137
|
};
|
|
124
138
|
clientRecord[method.name] = caller;
|
|
@@ -187,10 +201,19 @@ export function createEventSubscriber(contract, options) {
|
|
|
187
201
|
return registerUnsubscribe(unsubscribe);
|
|
188
202
|
};
|
|
189
203
|
function dispose() {
|
|
204
|
+
let firstError;
|
|
190
205
|
for (const unsubscribe of subscriptions) {
|
|
191
|
-
|
|
206
|
+
try {
|
|
207
|
+
unsubscribe();
|
|
208
|
+
}
|
|
209
|
+
catch (cause) {
|
|
210
|
+
firstError ??= cause;
|
|
211
|
+
}
|
|
192
212
|
}
|
|
193
213
|
subscriptions.clear();
|
|
214
|
+
if (firstError !== undefined) {
|
|
215
|
+
throw firstError;
|
|
216
|
+
}
|
|
194
217
|
}
|
|
195
218
|
return {
|
|
196
219
|
subscribe: subscribeEvent,
|
package/dist/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type { AnyEvent, AnyMethod, ErrorSchema, ExtractMethod, RpcContract, RpcE
|
|
|
5
5
|
export type Implementations<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>, R = never> = {
|
|
6
6
|
readonly [Name in C["methods"][number]["name"]]: (input: RpcInput<ExtractMethod<C["methods"], Name>>) => Effect.Effect<RpcOutput<ExtractMethod<C["methods"], Name>>, RpcError<ExtractMethod<C["methods"], Name>>, R>;
|
|
7
7
|
};
|
|
8
|
-
type IsEmptyObject<T> = keyof T extends never ? true : false;
|
|
8
|
+
type IsEmptyObject<T> = T extends object ? keyof T extends never ? true : false : false;
|
|
9
9
|
export type RpcCaller<M extends AnyMethod> = IsEmptyObject<RpcInput<M>> extends true ? () => Promise<RpcOutput<M>> : (input: RpcInput<M>) => Promise<RpcOutput<M>>;
|
|
10
10
|
export type RpcClient<C extends RpcContract<readonly AnyMethod[], readonly AnyEvent[]>> = {
|
|
11
11
|
readonly [Name in C["methods"][number]["name"]]: RpcCaller<ExtractMethod<C["methods"], Name>>;
|
|
@@ -37,7 +37,7 @@ export type DispatchFailureContext = {
|
|
|
37
37
|
readonly payload: unknown;
|
|
38
38
|
readonly cause: unknown;
|
|
39
39
|
};
|
|
40
|
-
export type DroppedEventReason = "queue_full" | "encoding_failed";
|
|
40
|
+
export type DroppedEventReason = "queue_full" | "encoding_failed" | "window_unavailable" | "dispatch_failed";
|
|
41
41
|
export type DroppedEventContext = {
|
|
42
42
|
readonly event: string;
|
|
43
43
|
readonly payload: unknown;
|
|
@@ -52,7 +52,7 @@ export type RpcClientDiagnostics = {
|
|
|
52
52
|
readonly onProtocolError?: (context: ProtocolErrorContext) => void;
|
|
53
53
|
};
|
|
54
54
|
export type RpcClientOptions = {
|
|
55
|
-
readonly invoke
|
|
55
|
+
readonly invoke: RpcInvoke;
|
|
56
56
|
readonly diagnostics?: RpcClientDiagnostics;
|
|
57
57
|
readonly rpcDecodeMode?: RpcResponseDecodeMode;
|
|
58
58
|
};
|
|
@@ -112,7 +112,7 @@ export type EventSubscriberDiagnostics = {
|
|
|
112
112
|
readonly onDecodeFailure?: (context: DecodeFailureContext) => void;
|
|
113
113
|
};
|
|
114
114
|
export type EventSubscriberOptions = {
|
|
115
|
-
readonly subscribe
|
|
115
|
+
readonly subscribe: EventSubscribe;
|
|
116
116
|
readonly decodeMode?: EventDecodeMode;
|
|
117
117
|
readonly diagnostics?: EventSubscriberDiagnostics;
|
|
118
118
|
};
|
|
@@ -121,4 +121,5 @@ export interface EventSubscriber<C extends RpcContract<readonly AnyMethod[], rea
|
|
|
121
121
|
readonly subscribeByName: (name: string, handler: (payload: unknown) => void) => () => void;
|
|
122
122
|
readonly dispose: () => void;
|
|
123
123
|
}
|
|
124
|
+
export type { IpcBridge, IpcBridgeGlobal, IpcKit, IpcKitOptions, IpcMainHandle, } from "./kit.ts";
|
|
124
125
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EAET,aAAa,EACb,WAAW,EACX,QAAQ,EAER,eAAe,EACf,QAAQ,EAER,SAAS,EAEV,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,aAAa,EACb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,SAAS,EACT,SAAS,EACT,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,eAAe,CACzB,CAAC,SAAS,WAAW,CAAC,SAAS,SAAS,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,EAChE,CAAC,GAAG,KAAK,IACP;IACF,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAC/C,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,KAC/C,MAAM,CAAC,MAAM,CAChB,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,EAC5C,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,EAC3C,CAAC,CACF;CACF,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electron-effect-rpc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Typed IPC RPC for Electron, built on Effect and @effect/schema",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
},
|
|
7
11
|
"./main": {
|
|
8
12
|
"types": "./dist/main.d.ts",
|
|
9
13
|
"default": "./dist/main.js"
|
|
@@ -35,6 +39,12 @@
|
|
|
35
39
|
"scripts": {
|
|
36
40
|
"build": "tsc",
|
|
37
41
|
"prepublishOnly": "bun run build",
|
|
42
|
+
"test:unit": "bun test",
|
|
43
|
+
"test:types": "bun run typecheck && bunx tsc -p tsconfig.type-tests.json --noEmit",
|
|
44
|
+
"test:packaging": "bash ./scripts/run-packaging-checks.sh",
|
|
45
|
+
"test:integration": "bun test __tests__/integration.test.ts",
|
|
46
|
+
"test:stress": "bun test __tests__/stress.test.ts",
|
|
47
|
+
"test:full": "bun run test:unit && bun run test:types && bun run test:packaging && bun run test:integration && bun run test:stress",
|
|
38
48
|
"test": "bun test",
|
|
39
49
|
"typecheck": "tsc --noEmit"
|
|
40
50
|
},
|