electrobun 1.18.4-beta.6 → 2.0.1-beta.13
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 +21 -0
- package/README.md +31 -170
- package/bin/electrobun.cjs +230 -153
- package/package.json +18 -49
- package/bun.lock +0 -119
- package/dist/api/browser/builtinrpcSchema.ts +0 -19
- package/dist/api/browser/global.d.ts +0 -36
- package/dist/api/browser/index.ts +0 -234
- package/dist/api/browser/webviewtag.ts +0 -88
- package/dist/api/browser/wgputag.ts +0 -48
- package/dist/api/bun/ElectrobunConfig.ts +0 -530
- package/dist/api/bun/__tests__/ffi-contract.test.ts +0 -105
- package/dist/api/bun/core/ApplicationMenu.ts +0 -70
- package/dist/api/bun/core/BrowserView.ts +0 -419
- package/dist/api/bun/core/BrowserWindow.ts +0 -400
- package/dist/api/bun/core/BuildConfig.ts +0 -71
- package/dist/api/bun/core/ContextMenu.ts +0 -75
- package/dist/api/bun/core/GpuWindow.ts +0 -289
- package/dist/api/bun/core/Paths.ts +0 -5
- package/dist/api/bun/core/Socket.ts +0 -22
- package/dist/api/bun/core/Tray.ts +0 -197
- package/dist/api/bun/core/Updater.ts +0 -1162
- package/dist/api/bun/core/Utils.ts +0 -487
- package/dist/api/bun/core/WGPUView.ts +0 -167
- package/dist/api/bun/core/menuRoles.ts +0 -181
- package/dist/api/bun/events/ApplicationEvents.ts +0 -22
- package/dist/api/bun/events/event.ts +0 -29
- package/dist/api/bun/events/eventEmitter.ts +0 -45
- package/dist/api/bun/events/trayEvents.ts +0 -11
- package/dist/api/bun/events/webviewEvents.ts +0 -39
- package/dist/api/bun/events/windowEvents.ts +0 -23
- package/dist/api/bun/index.ts +0 -298
- package/dist/api/bun/preload/.generated/compiled.ts +0 -8
- package/dist/api/bun/preload/build.ts +0 -65
- package/dist/api/bun/preload/dragRegions.ts +0 -41
- package/dist/api/bun/preload/encryption.ts +0 -86
- package/dist/api/bun/preload/events.ts +0 -171
- package/dist/api/bun/preload/globals.d.ts +0 -45
- package/dist/api/bun/preload/index-sandboxed.ts +0 -28
- package/dist/api/bun/preload/index.ts +0 -77
- package/dist/api/bun/preload/internalRpc.ts +0 -80
- package/dist/api/bun/preload/overlaySync.ts +0 -107
- package/dist/api/bun/preload/webviewTag.ts +0 -451
- package/dist/api/bun/preload/wgpuTag.ts +0 -246
- package/dist/api/bun/proc/linux.md +0 -43
- package/dist/api/bun/proc/native.ts +0 -3385
- package/dist/api/bun/webGPU.ts +0 -346
- package/dist/api/bun/webgpuAdapter.ts +0 -3011
- package/dist/api/shared/bun-version.ts +0 -3
- package/dist/api/shared/cef-version.ts +0 -5
- package/dist/api/shared/electrobun-version.ts +0 -2
- package/dist/api/shared/naming.test.ts +0 -327
- package/dist/api/shared/naming.ts +0 -188
- package/dist/api/shared/platform.ts +0 -48
- package/dist/api/shared/rpc.ts +0 -541
- package/dist/main.js +0 -168
- package/dist/preload-full.js +0 -913
- package/dist/preload-sandboxed.js +0 -111
- package/dist/zig-sdk/electrobun.zig +0 -1993
- package/src/cli/bun.lockb +0 -0
- package/src/cli/index.ts +0 -5689
- package/src/cli/package-lock.json +0 -81
- package/src/cli/package.json +0 -11
package/dist/api/shared/rpc.ts
DELETED
|
@@ -1,541 +0,0 @@
|
|
|
1
|
-
// ---- Wire protocol packets ----
|
|
2
|
-
|
|
3
|
-
type _RPCRequestPacket = {
|
|
4
|
-
type: "request";
|
|
5
|
-
id: number;
|
|
6
|
-
method: string;
|
|
7
|
-
params: any;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
type _RPCResponsePacket =
|
|
11
|
-
| { type: "response"; id: number; success: true; payload: any }
|
|
12
|
-
| { type: "response"; id: number; success: false; error?: string };
|
|
13
|
-
|
|
14
|
-
type _RPCMessagePacket = {
|
|
15
|
-
type: "message";
|
|
16
|
-
id: string;
|
|
17
|
-
payload: any;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type _RPCPacket = _RPCRequestPacket | _RPCResponsePacket | _RPCMessagePacket;
|
|
21
|
-
|
|
22
|
-
// ---- Schema primitives ----
|
|
23
|
-
|
|
24
|
-
type BaseRPCRequestsSchema = {
|
|
25
|
-
[key: string]: { params: unknown; response: unknown };
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type RPCRequestsSchema<
|
|
29
|
-
T extends BaseRPCRequestsSchema = BaseRPCRequestsSchema,
|
|
30
|
-
> = T;
|
|
31
|
-
|
|
32
|
-
type RPCRequestParams<
|
|
33
|
-
RS extends RPCRequestsSchema,
|
|
34
|
-
M extends keyof RS = keyof RS,
|
|
35
|
-
> = "params" extends keyof RS[M] ? RS[M]["params"] : never;
|
|
36
|
-
|
|
37
|
-
type RPCRequestResponse<
|
|
38
|
-
RS extends RPCRequestsSchema,
|
|
39
|
-
M extends keyof RS = keyof RS,
|
|
40
|
-
> = "response" extends keyof RS[M] ? RS[M]["response"] : void;
|
|
41
|
-
|
|
42
|
-
type BaseRPCMessagesSchema = Record<never, unknown>;
|
|
43
|
-
|
|
44
|
-
export type RPCMessagesSchema<
|
|
45
|
-
T extends BaseRPCMessagesSchema = BaseRPCMessagesSchema,
|
|
46
|
-
> = T;
|
|
47
|
-
|
|
48
|
-
type RPCMessagePayload<
|
|
49
|
-
MS extends RPCMessagesSchema,
|
|
50
|
-
N extends keyof MS = keyof MS,
|
|
51
|
-
> = MS[N];
|
|
52
|
-
|
|
53
|
-
// ---- Composite schema ----
|
|
54
|
-
|
|
55
|
-
type InputRPCSchema = {
|
|
56
|
-
requests?: RPCRequestsSchema;
|
|
57
|
-
messages?: RPCMessagesSchema;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
type ResolvedRPCSchema<I extends InputRPCSchema> = {
|
|
61
|
-
requests: undefined extends I["requests"]
|
|
62
|
-
? BaseRPCRequestsSchema
|
|
63
|
-
: NonNullable<I["requests"]>;
|
|
64
|
-
messages: undefined extends I["messages"]
|
|
65
|
-
? BaseRPCMessagesSchema
|
|
66
|
-
: NonNullable<I["messages"]>;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export type RPCSchema<
|
|
70
|
-
I extends InputRPCSchema | void = InputRPCSchema,
|
|
71
|
-
> = ResolvedRPCSchema<I extends InputRPCSchema ? I : InputRPCSchema>;
|
|
72
|
-
|
|
73
|
-
// ---- Handler types ----
|
|
74
|
-
|
|
75
|
-
type RPCRequestHandlerFn<RS extends RPCRequestsSchema = RPCRequestsSchema> = <
|
|
76
|
-
M extends keyof RS,
|
|
77
|
-
>(
|
|
78
|
-
method: M,
|
|
79
|
-
params: RPCRequestParams<RS, M>,
|
|
80
|
-
) => any | Promise<any>;
|
|
81
|
-
|
|
82
|
-
type RPCRequestHandlerObject<
|
|
83
|
-
RS extends RPCRequestsSchema = RPCRequestsSchema,
|
|
84
|
-
> = {
|
|
85
|
-
[M in keyof RS]?: (
|
|
86
|
-
...args: "params" extends keyof RS[M]
|
|
87
|
-
? undefined extends RS[M]["params"]
|
|
88
|
-
? [params?: RS[M]["params"]]
|
|
89
|
-
: [params: RS[M]["params"]]
|
|
90
|
-
: []
|
|
91
|
-
) =>
|
|
92
|
-
| Awaited<RPCRequestResponse<RS, M>>
|
|
93
|
-
| Promise<Awaited<RPCRequestResponse<RS, M>>>;
|
|
94
|
-
} & {
|
|
95
|
-
_?: (method: keyof RS, params: RPCRequestParams<RS>) => any;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export type RPCRequestHandler<
|
|
99
|
-
RS extends RPCRequestsSchema = RPCRequestsSchema,
|
|
100
|
-
> = RPCRequestHandlerFn<RS> | RPCRequestHandlerObject<RS>;
|
|
101
|
-
|
|
102
|
-
export type RPCMessageHandlerFn<
|
|
103
|
-
MS extends RPCMessagesSchema,
|
|
104
|
-
N extends keyof MS,
|
|
105
|
-
> = (payload: RPCMessagePayload<MS, N>) => void;
|
|
106
|
-
|
|
107
|
-
export type WildcardRPCMessageHandlerFn<MS extends RPCMessagesSchema> = (
|
|
108
|
-
messageName: keyof MS,
|
|
109
|
-
payload: RPCMessagePayload<MS>,
|
|
110
|
-
) => void;
|
|
111
|
-
|
|
112
|
-
// ---- Proxy types ----
|
|
113
|
-
|
|
114
|
-
type RPCRequestsProxy<RS extends RPCRequestsSchema> = {
|
|
115
|
-
[K in keyof RS]: (
|
|
116
|
-
...args: "params" extends keyof RS[K]
|
|
117
|
-
? undefined extends RS[K]["params"]
|
|
118
|
-
? [params?: RS[K]["params"]]
|
|
119
|
-
: [params: RS[K]["params"]]
|
|
120
|
-
: []
|
|
121
|
-
) => Promise<RPCRequestResponse<RS, K>>;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
type RPCMessagesProxy<MS extends RPCMessagesSchema> = {
|
|
125
|
-
[K in keyof MS]-?: (
|
|
126
|
-
...args: void extends MS[K]
|
|
127
|
-
? []
|
|
128
|
-
: undefined extends MS[K]
|
|
129
|
-
? [payload?: MS[K]]
|
|
130
|
-
: [payload: MS[K]]
|
|
131
|
-
) => void;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// ---- Transport ----
|
|
135
|
-
|
|
136
|
-
type RPCTransportHandler = (data: any) => void;
|
|
137
|
-
|
|
138
|
-
export type RPCTransport = {
|
|
139
|
-
send?: (data: any) => void;
|
|
140
|
-
registerHandler?: (handler: RPCTransportHandler) => void;
|
|
141
|
-
unregisterHandler?: () => void;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
// ---- Options ----
|
|
145
|
-
|
|
146
|
-
type DebugHooks = {
|
|
147
|
-
onSend?: (packet: _RPCPacket) => void;
|
|
148
|
-
onReceive?: (packet: _RPCPacket) => void;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
type _RPCAllOptions<S extends RPCSchema> = {
|
|
152
|
-
transport?: RPCTransport;
|
|
153
|
-
requestHandler?: RPCRequestHandler<S["requests"]>;
|
|
154
|
-
maxRequestTime?: number;
|
|
155
|
-
_debugHooks?: DebugHooks;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
type RPCBaseOption = "transport" | "_debugHooks";
|
|
159
|
-
type RPCRequestsInOption = "requestHandler";
|
|
160
|
-
type RPCRequestsOutOption = "maxRequestTime";
|
|
161
|
-
|
|
162
|
-
type OptionsByLocalSchema<S extends RPCSchema> =
|
|
163
|
-
NonNullable<unknown> extends S["requests"] ? never : RPCRequestsInOption;
|
|
164
|
-
type OptionsByRemoteSchema<RS extends RPCSchema> =
|
|
165
|
-
NonNullable<unknown> extends RS["requests"] ? never : RPCRequestsOutOption;
|
|
166
|
-
|
|
167
|
-
export type RPCOptions<
|
|
168
|
-
S extends RPCSchema,
|
|
169
|
-
RS extends RPCSchema,
|
|
170
|
-
> = Pick<
|
|
171
|
-
_RPCAllOptions<S>,
|
|
172
|
-
RPCBaseOption | OptionsByLocalSchema<S> | OptionsByRemoteSchema<RS>
|
|
173
|
-
>;
|
|
174
|
-
|
|
175
|
-
// ---- createRPC ----
|
|
176
|
-
|
|
177
|
-
const MAX_ID = 1e10;
|
|
178
|
-
const DEFAULT_MAX_REQUEST_TIME = 1000;
|
|
179
|
-
|
|
180
|
-
function missingTransportMethodError(
|
|
181
|
-
methods: string[],
|
|
182
|
-
action: string,
|
|
183
|
-
): Error {
|
|
184
|
-
const methodsString = methods.map((m) => `"${m}"`).join(", ");
|
|
185
|
-
return new Error(
|
|
186
|
-
`This RPC instance cannot ${action} because the transport did not provide one or more of these methods: ${methodsString}`,
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export function createRPC<
|
|
191
|
-
Schema extends RPCSchema = RPCSchema,
|
|
192
|
-
RemoteSchema extends RPCSchema = Schema,
|
|
193
|
-
>(options: _RPCAllOptions<Schema> = {}) {
|
|
194
|
-
// ---- transport ----
|
|
195
|
-
|
|
196
|
-
let debugHooks: DebugHooks = {};
|
|
197
|
-
let transport: RPCTransport = {};
|
|
198
|
-
let requestHandler:
|
|
199
|
-
| RPCRequestHandlerFn<Schema["requests"]>
|
|
200
|
-
| undefined = undefined;
|
|
201
|
-
|
|
202
|
-
function setTransport(newTransport: RPCTransport) {
|
|
203
|
-
if (transport.unregisterHandler) transport.unregisterHandler();
|
|
204
|
-
transport = newTransport;
|
|
205
|
-
transport.registerHandler?.(handler);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function setRequestHandler(
|
|
209
|
-
h: RPCRequestHandler<Schema["requests"]>,
|
|
210
|
-
) {
|
|
211
|
-
if (typeof h === "function") {
|
|
212
|
-
requestHandler = h as RPCRequestHandlerFn<Schema["requests"]>;
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
requestHandler = (method, params) => {
|
|
216
|
-
const handlerFn = (h as RPCRequestHandlerObject<Schema["requests"]>)[
|
|
217
|
-
method
|
|
218
|
-
];
|
|
219
|
-
if (handlerFn) return (handlerFn as any)(params);
|
|
220
|
-
const fallbackHandler = (
|
|
221
|
-
h as RPCRequestHandlerObject<Schema["requests"]>
|
|
222
|
-
)._;
|
|
223
|
-
if (!fallbackHandler)
|
|
224
|
-
throw new Error(`The requested method has no handler: ${String(method)}`);
|
|
225
|
-
return fallbackHandler(method, params as any);
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// ---- apply options ----
|
|
230
|
-
|
|
231
|
-
const { maxRequestTime = DEFAULT_MAX_REQUEST_TIME } = options;
|
|
232
|
-
if (options.transport) setTransport(options.transport);
|
|
233
|
-
if (options.requestHandler) setRequestHandler(options.requestHandler);
|
|
234
|
-
if (options._debugHooks) debugHooks = options._debugHooks;
|
|
235
|
-
|
|
236
|
-
// ---- outgoing requests ----
|
|
237
|
-
|
|
238
|
-
let lastRequestId = 0;
|
|
239
|
-
function getRequestId() {
|
|
240
|
-
if (lastRequestId <= MAX_ID) return ++lastRequestId;
|
|
241
|
-
return (lastRequestId = 0);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const requestListeners = new Map<
|
|
245
|
-
number,
|
|
246
|
-
{ resolve: (v: any) => void; reject: (e: Error) => void }
|
|
247
|
-
>();
|
|
248
|
-
const requestTimeouts = new Map<number, ReturnType<typeof setTimeout>>();
|
|
249
|
-
|
|
250
|
-
function requestFn<M extends keyof RemoteSchema["requests"]>(
|
|
251
|
-
method: M,
|
|
252
|
-
...args: "params" extends keyof RemoteSchema["requests"][M]
|
|
253
|
-
? undefined extends RemoteSchema["requests"][M]["params"]
|
|
254
|
-
? [params?: RemoteSchema["requests"][M]["params"]]
|
|
255
|
-
: [params: RemoteSchema["requests"][M]["params"]]
|
|
256
|
-
: []
|
|
257
|
-
): Promise<RPCRequestResponse<RemoteSchema["requests"], M>> {
|
|
258
|
-
const params = args[0];
|
|
259
|
-
return new Promise((resolve, reject) => {
|
|
260
|
-
if (!transport.send)
|
|
261
|
-
throw missingTransportMethodError(["send"], "make requests");
|
|
262
|
-
const requestId = getRequestId();
|
|
263
|
-
const request: _RPCRequestPacket = {
|
|
264
|
-
type: "request",
|
|
265
|
-
id: requestId,
|
|
266
|
-
method: method as string,
|
|
267
|
-
params,
|
|
268
|
-
};
|
|
269
|
-
requestListeners.set(requestId, { resolve, reject });
|
|
270
|
-
if (maxRequestTime !== Infinity)
|
|
271
|
-
requestTimeouts.set(
|
|
272
|
-
requestId,
|
|
273
|
-
setTimeout(() => {
|
|
274
|
-
requestTimeouts.delete(requestId);
|
|
275
|
-
requestListeners.delete(requestId);
|
|
276
|
-
reject(new Error("RPC request timed out."));
|
|
277
|
-
}, maxRequestTime),
|
|
278
|
-
);
|
|
279
|
-
debugHooks.onSend?.(request);
|
|
280
|
-
transport.send(request);
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const request = new Proxy(requestFn, {
|
|
285
|
-
get: (target, prop, receiver) => {
|
|
286
|
-
if (prop in target) return Reflect.get(target, prop, receiver);
|
|
287
|
-
return (params: any) => (requestFn as any)(prop, params);
|
|
288
|
-
},
|
|
289
|
-
}) as typeof requestFn & RPCRequestsProxy<RemoteSchema["requests"]>;
|
|
290
|
-
|
|
291
|
-
const requestProxy =
|
|
292
|
-
request as unknown as RPCRequestsProxy<RemoteSchema["requests"]>;
|
|
293
|
-
|
|
294
|
-
// ---- outgoing messages ----
|
|
295
|
-
|
|
296
|
-
function sendFn<M extends keyof Schema["messages"]>(
|
|
297
|
-
message: M,
|
|
298
|
-
...args: void extends RPCMessagePayload<Schema["messages"], M>
|
|
299
|
-
? []
|
|
300
|
-
: undefined extends RPCMessagePayload<Schema["messages"], M>
|
|
301
|
-
? [payload?: RPCMessagePayload<Schema["messages"], M>]
|
|
302
|
-
: [payload: RPCMessagePayload<Schema["messages"], M>]
|
|
303
|
-
) {
|
|
304
|
-
const payload = args[0];
|
|
305
|
-
if (!transport.send)
|
|
306
|
-
throw missingTransportMethodError(["send"], "send messages");
|
|
307
|
-
const rpcMessage: _RPCMessagePacket = {
|
|
308
|
-
type: "message",
|
|
309
|
-
id: message as string,
|
|
310
|
-
payload,
|
|
311
|
-
};
|
|
312
|
-
debugHooks.onSend?.(rpcMessage);
|
|
313
|
-
transport.send(rpcMessage);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const send = new Proxy(sendFn, {
|
|
317
|
-
get: (target, prop, receiver) => {
|
|
318
|
-
if (prop in target) return Reflect.get(target, prop, receiver);
|
|
319
|
-
return (payload: any) => (sendFn as any)(prop, payload);
|
|
320
|
-
},
|
|
321
|
-
}) as typeof sendFn & RPCMessagesProxy<Schema["messages"]>;
|
|
322
|
-
|
|
323
|
-
const sendProxy =
|
|
324
|
-
send as unknown as RPCMessagesProxy<Schema["messages"]>;
|
|
325
|
-
|
|
326
|
-
// ---- incoming message listeners ----
|
|
327
|
-
|
|
328
|
-
const messageListeners = new Map<string | symbol, Set<Function>>();
|
|
329
|
-
const wildcardMessageListeners = new Set<Function>();
|
|
330
|
-
|
|
331
|
-
function addMessageListener(
|
|
332
|
-
message: "*",
|
|
333
|
-
listener: WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>,
|
|
334
|
-
): void;
|
|
335
|
-
function addMessageListener<
|
|
336
|
-
M extends keyof RemoteSchema["messages"],
|
|
337
|
-
>(
|
|
338
|
-
message: M,
|
|
339
|
-
listener: RPCMessageHandlerFn<RemoteSchema["messages"], M>,
|
|
340
|
-
): void;
|
|
341
|
-
function addMessageListener(message: any, listener: any) {
|
|
342
|
-
if (!transport.registerHandler)
|
|
343
|
-
throw missingTransportMethodError(
|
|
344
|
-
["registerHandler"],
|
|
345
|
-
"register message listeners",
|
|
346
|
-
);
|
|
347
|
-
if (message === "*") {
|
|
348
|
-
wildcardMessageListeners.add(listener);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
if (!messageListeners.has(message))
|
|
352
|
-
messageListeners.set(message, new Set());
|
|
353
|
-
messageListeners.get(message)!.add(listener);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function removeMessageListener(
|
|
357
|
-
message: "*",
|
|
358
|
-
listener: WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>,
|
|
359
|
-
): void;
|
|
360
|
-
function removeMessageListener<
|
|
361
|
-
M extends keyof RemoteSchema["messages"],
|
|
362
|
-
>(
|
|
363
|
-
message: M,
|
|
364
|
-
listener: RPCMessageHandlerFn<RemoteSchema["messages"], M>,
|
|
365
|
-
): void;
|
|
366
|
-
function removeMessageListener(message: any, listener: any) {
|
|
367
|
-
if (message === "*") {
|
|
368
|
-
wildcardMessageListeners.delete(listener);
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
messageListeners.get(message)?.delete(listener);
|
|
372
|
-
if (messageListeners.get(message)?.size === 0)
|
|
373
|
-
messageListeners.delete(message);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// ---- incoming packet handler ----
|
|
377
|
-
|
|
378
|
-
async function handler(message: _RPCPacket) {
|
|
379
|
-
debugHooks.onReceive?.(message);
|
|
380
|
-
if (!("type" in message))
|
|
381
|
-
throw new Error("Message does not contain a type.");
|
|
382
|
-
|
|
383
|
-
if (message.type === "request") {
|
|
384
|
-
if (!transport.send || !requestHandler)
|
|
385
|
-
throw missingTransportMethodError(
|
|
386
|
-
["send", "requestHandler"],
|
|
387
|
-
"handle requests",
|
|
388
|
-
);
|
|
389
|
-
const { id, method, params } = message;
|
|
390
|
-
let response: _RPCResponsePacket;
|
|
391
|
-
try {
|
|
392
|
-
response = {
|
|
393
|
-
type: "response",
|
|
394
|
-
id,
|
|
395
|
-
success: true,
|
|
396
|
-
payload: await requestHandler(method as any, params),
|
|
397
|
-
};
|
|
398
|
-
} catch (error) {
|
|
399
|
-
if (!(error instanceof Error)) throw error;
|
|
400
|
-
response = {
|
|
401
|
-
type: "response",
|
|
402
|
-
id,
|
|
403
|
-
success: false,
|
|
404
|
-
error: error.message,
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
debugHooks.onSend?.(response);
|
|
408
|
-
transport.send(response);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (message.type === "response") {
|
|
413
|
-
const timeout = requestTimeouts.get(message.id);
|
|
414
|
-
if (timeout != null) clearTimeout(timeout);
|
|
415
|
-
requestTimeouts.delete(message.id);
|
|
416
|
-
const { resolve, reject } =
|
|
417
|
-
requestListeners.get(message.id) ?? {};
|
|
418
|
-
requestListeners.delete(message.id);
|
|
419
|
-
if (!message.success) reject?.(new Error(message.error));
|
|
420
|
-
else resolve?.(message.payload);
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (message.type === "message") {
|
|
425
|
-
for (const listener of wildcardMessageListeners)
|
|
426
|
-
(listener as any)(message.id, message.payload);
|
|
427
|
-
const listeners = messageListeners.get(message.id);
|
|
428
|
-
if (!listeners) return;
|
|
429
|
-
for (const listener of listeners) (listener as any)(message.payload);
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
throw new Error(
|
|
434
|
-
`Unexpected RPC message type: ${(message as any).type}`,
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const proxy = { send: sendProxy, request: requestProxy };
|
|
439
|
-
|
|
440
|
-
return {
|
|
441
|
-
setTransport,
|
|
442
|
-
setRequestHandler,
|
|
443
|
-
request,
|
|
444
|
-
requestProxy,
|
|
445
|
-
send,
|
|
446
|
-
sendProxy,
|
|
447
|
-
addMessageListener,
|
|
448
|
-
removeMessageListener,
|
|
449
|
-
proxy,
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// ---- Electrobun combined schema ----
|
|
454
|
-
|
|
455
|
-
export interface ElectrobunRPCSchema {
|
|
456
|
-
bun: RPCSchema;
|
|
457
|
-
webview: RPCSchema;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
export interface RPCWithTransport {
|
|
461
|
-
setTransport: (transport: RPCTransport) => void;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
export type ElectrobunRPCConfig<
|
|
465
|
-
Schema extends ElectrobunRPCSchema,
|
|
466
|
-
Side extends "bun" | "webview",
|
|
467
|
-
> = {
|
|
468
|
-
maxRequestTime?: number;
|
|
469
|
-
handlers: {
|
|
470
|
-
requests?: RPCRequestHandler<Schema[Side]["requests"]>;
|
|
471
|
-
messages?: {
|
|
472
|
-
[K in keyof Schema[Side]["messages"]]?: RPCMessageHandlerFn<
|
|
473
|
-
Schema[Side]["messages"],
|
|
474
|
-
K
|
|
475
|
-
>;
|
|
476
|
-
} & {
|
|
477
|
-
"*"?: WildcardRPCMessageHandlerFn<Schema[Side]["messages"]>;
|
|
478
|
-
};
|
|
479
|
-
};
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
// ---- defineElectrobunRPC ----
|
|
483
|
-
|
|
484
|
-
export function defineElectrobunRPC<
|
|
485
|
-
Schema extends ElectrobunRPCSchema,
|
|
486
|
-
Side extends "bun" | "webview" = "bun" | "webview",
|
|
487
|
-
>(
|
|
488
|
-
_side: Side,
|
|
489
|
-
config: ElectrobunRPCConfig<Schema, Side> & {
|
|
490
|
-
extraRequestHandlers?: Record<string, Function>;
|
|
491
|
-
},
|
|
492
|
-
) {
|
|
493
|
-
// Determine the other side for outgoing calls
|
|
494
|
-
type OtherSide = Side extends "bun" ? "webview" : "bun";
|
|
495
|
-
|
|
496
|
-
// Local schema = what this side handles (incoming requests) + what the other side handles (outgoing messages)
|
|
497
|
-
type LocalSchema = {
|
|
498
|
-
requests: Schema[Side]["requests"];
|
|
499
|
-
messages: Schema[OtherSide]["messages"];
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
// Remote schema = what the other side handles (outgoing requests) + what this side handles (incoming messages)
|
|
503
|
-
type RemoteSchema = {
|
|
504
|
-
requests: Schema[OtherSide]["requests"];
|
|
505
|
-
messages: Schema[Side]["messages"];
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
const rpcOptions = {
|
|
509
|
-
maxRequestTime: config.maxRequestTime,
|
|
510
|
-
requestHandler: {
|
|
511
|
-
...config.handlers.requests,
|
|
512
|
-
...config.extraRequestHandlers,
|
|
513
|
-
},
|
|
514
|
-
transport: {
|
|
515
|
-
// Provide a stub so addMessageListener doesn't throw before real transport is set
|
|
516
|
-
registerHandler: () => {},
|
|
517
|
-
},
|
|
518
|
-
} as _RPCAllOptions<LocalSchema>;
|
|
519
|
-
|
|
520
|
-
const rpc = createRPC<LocalSchema, RemoteSchema>(rpcOptions);
|
|
521
|
-
|
|
522
|
-
const messageHandlers = config.handlers.messages;
|
|
523
|
-
if (messageHandlers) {
|
|
524
|
-
rpc.addMessageListener(
|
|
525
|
-
"*" as any,
|
|
526
|
-
((messageName: keyof Schema[Side]["messages"], payload: any) => {
|
|
527
|
-
const globalHandler = (messageHandlers as any)["*"];
|
|
528
|
-
if (globalHandler) {
|
|
529
|
-
globalHandler(messageName, payload);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const messageHandler = (messageHandlers as any)[messageName];
|
|
533
|
-
if (messageHandler) {
|
|
534
|
-
messageHandler(payload);
|
|
535
|
-
}
|
|
536
|
-
}) as any,
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return rpc;
|
|
541
|
-
}
|
package/dist/main.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
var __require = import.meta.require;
|
|
3
|
-
|
|
4
|
-
// src/launcher/main.ts
|
|
5
|
-
import { join, dirname, resolve } from "path";
|
|
6
|
-
import { dlopen, suffix, ptr, toArrayBuffer } from "bun:ffi";
|
|
7
|
-
import { existsSync, writeFileSync } from "fs";
|
|
8
|
-
import { tmpdir } from "os";
|
|
9
|
-
var pathToMacOS = dirname(process.argv0);
|
|
10
|
-
var coreLibFileName = process.platform === "win32" ? "ElectrobunCore.dll" : `libElectrobunCore.${suffix}`;
|
|
11
|
-
var coreLibPath = join(pathToMacOS, coreLibFileName);
|
|
12
|
-
var absoluteCoreLibPath = resolve(coreLibPath);
|
|
13
|
-
function main() {
|
|
14
|
-
let channel = "";
|
|
15
|
-
let identifier = "";
|
|
16
|
-
let name = "";
|
|
17
|
-
try {
|
|
18
|
-
const pathToLauncherBin2 = process.argv0;
|
|
19
|
-
const pathToBinDir2 = dirname(pathToLauncherBin2);
|
|
20
|
-
const versionJsonPath = join(pathToBinDir2, "..", "Resources", "version.json");
|
|
21
|
-
if (existsSync(versionJsonPath)) {
|
|
22
|
-
const versionInfo = __require(versionJsonPath);
|
|
23
|
-
if (versionInfo.identifier) {
|
|
24
|
-
identifier = versionInfo.identifier;
|
|
25
|
-
}
|
|
26
|
-
if (versionInfo.name) {
|
|
27
|
-
name = versionInfo.name;
|
|
28
|
-
}
|
|
29
|
-
if (versionInfo.channel) {
|
|
30
|
-
channel = versionInfo.channel;
|
|
31
|
-
}
|
|
32
|
-
console.log(`[LAUNCHER] Loaded identifier: ${identifier}, name: ${name}, channel: ${channel}`);
|
|
33
|
-
}
|
|
34
|
-
} catch (error) {
|
|
35
|
-
console.error(`[LAUNCHER] Warning: Could not read version.json:`, error);
|
|
36
|
-
}
|
|
37
|
-
if (process.platform === "linux") {
|
|
38
|
-
const cefLibs = [
|
|
39
|
-
join(pathToMacOS, "libcef.so"),
|
|
40
|
-
join(pathToMacOS, "libvk_swiftshader.so")
|
|
41
|
-
];
|
|
42
|
-
const existingCefLibs = cefLibs.filter((lib2) => existsSync(lib2));
|
|
43
|
-
if (existingCefLibs.length > 0 && !process.env["LD_PRELOAD"]) {
|
|
44
|
-
console.error(`[LAUNCHER] ERROR: CEF libraries found but LD_PRELOAD not set!`);
|
|
45
|
-
console.error(`[LAUNCHER] Please run through the wrapper script: ./run.sh`);
|
|
46
|
-
console.error(`[LAUNCHER] Or set: LD_PRELOAD="${existingCefLibs.join(":")}" before starting.`);
|
|
47
|
-
const { spawn } = __require("child_process");
|
|
48
|
-
const env = { ...process.env, LD_PRELOAD: existingCefLibs.join(":") };
|
|
49
|
-
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
50
|
-
env,
|
|
51
|
-
stdio: "inherit"
|
|
52
|
-
});
|
|
53
|
-
child.on("exit", (code) => process.exit(code ?? 1));
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
let lib;
|
|
58
|
-
try {
|
|
59
|
-
if (!process.env["LD_LIBRARY_PATH"]?.includes(".")) {
|
|
60
|
-
process.env["LD_LIBRARY_PATH"] = `.${process.env["LD_LIBRARY_PATH"] ? ":" + process.env["LD_LIBRARY_PATH"] : ""}`;
|
|
61
|
-
}
|
|
62
|
-
lib = dlopen(coreLibPath, {
|
|
63
|
-
electrobun_core_run_main_thread: {
|
|
64
|
-
args: ["cstring", "cstring", "cstring", "i32"],
|
|
65
|
-
returns: "i32"
|
|
66
|
-
},
|
|
67
|
-
electrobun_core_last_error: {
|
|
68
|
-
args: [],
|
|
69
|
-
returns: "cstring"
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
} catch (error) {
|
|
73
|
-
console.error(`[LAUNCHER] Failed to load ElectrobunCore: ${error.message}`);
|
|
74
|
-
try {
|
|
75
|
-
lib = dlopen(absoluteCoreLibPath, {
|
|
76
|
-
electrobun_core_run_main_thread: {
|
|
77
|
-
args: ["cstring", "cstring", "cstring", "i32"],
|
|
78
|
-
returns: "i32"
|
|
79
|
-
},
|
|
80
|
-
electrobun_core_last_error: {
|
|
81
|
-
args: [],
|
|
82
|
-
returns: "cstring"
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
} catch (absError) {
|
|
86
|
-
console.error(`[LAUNCHER] Core library loading failed. Try running: ldd ${coreLibPath}`);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
const pathToLauncherBin = process.argv0;
|
|
91
|
-
const pathToBinDir = dirname(pathToLauncherBin);
|
|
92
|
-
const resourcesDir = join(pathToBinDir, "..", "Resources");
|
|
93
|
-
const asarPath = join(resourcesDir, "app.asar");
|
|
94
|
-
const appFolderPath = join(resourcesDir, "app");
|
|
95
|
-
let appEntrypointPath;
|
|
96
|
-
if (existsSync(asarPath)) {
|
|
97
|
-
console.log(`[LAUNCHER] Loading app code from ASAR: ${asarPath}`);
|
|
98
|
-
let asarLibPath;
|
|
99
|
-
let asarLib;
|
|
100
|
-
if (process.platform === "win32") {
|
|
101
|
-
asarLibPath = join(pathToMacOS, "libasar.dll");
|
|
102
|
-
} else {
|
|
103
|
-
asarLibPath = join(pathToMacOS, `libasar.${suffix}`);
|
|
104
|
-
}
|
|
105
|
-
try {
|
|
106
|
-
asarLib = dlopen(asarLibPath, {
|
|
107
|
-
asar_open: { args: ["cstring"], returns: "ptr" },
|
|
108
|
-
asar_read_file: { args: ["ptr", "cstring", "ptr"], returns: "ptr" },
|
|
109
|
-
asar_free_buffer: { args: ["ptr", "u64"], returns: "void" },
|
|
110
|
-
asar_close: { args: ["ptr"], returns: "void" }
|
|
111
|
-
});
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.error(`[LAUNCHER] Failed to load ASAR library: ${error.message}`);
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
const asarArchive = asarLib.symbols.asar_open(ptr(new Uint8Array(Buffer.from(asarPath + "\x00", "utf8"))));
|
|
117
|
-
if (!asarArchive || asarArchive === 0n) {
|
|
118
|
-
console.error(`[LAUNCHER] Failed to open ASAR archive at: ${asarPath}`);
|
|
119
|
-
throw new Error("Failed to open ASAR archive");
|
|
120
|
-
}
|
|
121
|
-
const filePath = "bun/index.js";
|
|
122
|
-
const sizeBuffer = new BigUint64Array(1);
|
|
123
|
-
const fileDataPtr = asarLib.symbols.asar_read_file(asarArchive, ptr(new Uint8Array(Buffer.from(filePath + "\x00", "utf8"))), ptr(sizeBuffer));
|
|
124
|
-
if (!fileDataPtr || fileDataPtr === 0n) {
|
|
125
|
-
console.error(`[LAUNCHER] Failed to read ${filePath} from ASAR`);
|
|
126
|
-
asarLib.symbols.asar_close(asarArchive);
|
|
127
|
-
throw new Error(`Failed to read ${filePath} from ASAR`);
|
|
128
|
-
}
|
|
129
|
-
const fileSize = Number(sizeBuffer[0]);
|
|
130
|
-
console.log(`[LAUNCHER] Read ${fileSize} bytes from ASAR for ${filePath}`);
|
|
131
|
-
const arrayBuffer = toArrayBuffer(fileDataPtr, 0, fileSize);
|
|
132
|
-
const fileData = Buffer.from(arrayBuffer);
|
|
133
|
-
const systemTmpDir = tmpdir();
|
|
134
|
-
const randomFileName = `electrobun-${Date.now()}-${Math.random().toString(36).substring(7)}.js`;
|
|
135
|
-
appEntrypointPath = join(systemTmpDir, randomFileName);
|
|
136
|
-
const wrappedFileData = `
|
|
137
|
-
// Auto-delete temp file after Worker loads it
|
|
138
|
-
const __tempFilePath = "${appEntrypointPath}";
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
try {
|
|
141
|
-
require("fs").unlinkSync(__tempFilePath);
|
|
142
|
-
console.log("[LAUNCHER] Deleted temp file:", __tempFilePath);
|
|
143
|
-
} catch (error) {
|
|
144
|
-
console.warn("[LAUNCHER] Failed to delete temp file:", error.message);
|
|
145
|
-
}
|
|
146
|
-
}, 100);
|
|
147
|
-
|
|
148
|
-
${fileData.toString("utf8")}
|
|
149
|
-
`;
|
|
150
|
-
writeFileSync(appEntrypointPath, wrappedFileData);
|
|
151
|
-
console.log(`[LAUNCHER] Wrote app entrypoint to: ${appEntrypointPath}`);
|
|
152
|
-
asarLib.symbols.asar_free_buffer(fileDataPtr, BigInt(fileSize));
|
|
153
|
-
asarLib.symbols.asar_close(asarArchive);
|
|
154
|
-
} else {
|
|
155
|
-
console.log(`[LAUNCHER] Loading app code from flat files`);
|
|
156
|
-
appEntrypointPath = join(appFolderPath, "bun", "index.js");
|
|
157
|
-
}
|
|
158
|
-
process.on("SIGINT", () => {});
|
|
159
|
-
process.on("SIGTERM", () => {});
|
|
160
|
-
new Worker(appEntrypointPath, {});
|
|
161
|
-
const runStatus = lib.symbols.electrobun_core_run_main_thread(ptr(new Uint8Array(Buffer.from(identifier + "\x00", "utf8"))), ptr(new Uint8Array(Buffer.from(name + "\x00", "utf8"))), ptr(new Uint8Array(Buffer.from(channel + "\x00", "utf8"))), 0);
|
|
162
|
-
if (runStatus !== 0) {
|
|
163
|
-
const coreError = lib.symbols.electrobun_core_last_error();
|
|
164
|
-
console.error(`[LAUNCHER] ElectrobunCore failed: ${coreError ? coreError.toString() : "Unknown error"}`);
|
|
165
|
-
process.exit(runStatus);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
main();
|