electron-json-rpc 1.0.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/LICENSE +21 -0
- package/README.md +978 -0
- package/README.zh-CN.md +978 -0
- package/dist/debug.d.mts +92 -0
- package/dist/debug.d.mts.map +1 -0
- package/dist/debug.mjs +206 -0
- package/dist/debug.mjs.map +1 -0
- package/dist/error-xVRu7Lxq.mjs +131 -0
- package/dist/error-xVRu7Lxq.mjs.map +1 -0
- package/dist/event.d.mts +71 -0
- package/dist/event.d.mts.map +1 -0
- package/dist/event.mjs +60 -0
- package/dist/event.mjs.map +1 -0
- package/dist/index.d.mts +78 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/internal-BZK_0O3n.mjs +23 -0
- package/dist/internal-BZK_0O3n.mjs.map +1 -0
- package/dist/main.d.mts +151 -0
- package/dist/main.d.mts.map +1 -0
- package/dist/main.mjs +329 -0
- package/dist/main.mjs.map +1 -0
- package/dist/preload.d.mts +23 -0
- package/dist/preload.d.mts.map +1 -0
- package/dist/preload.mjs +417 -0
- package/dist/preload.mjs.map +1 -0
- package/dist/renderer/builder.d.mts +64 -0
- package/dist/renderer/builder.d.mts.map +1 -0
- package/dist/renderer/builder.mjs +101 -0
- package/dist/renderer/builder.mjs.map +1 -0
- package/dist/renderer/client.d.mts +42 -0
- package/dist/renderer/client.d.mts.map +1 -0
- package/dist/renderer/client.mjs +136 -0
- package/dist/renderer/client.mjs.map +1 -0
- package/dist/renderer/event.d.mts +17 -0
- package/dist/renderer/event.d.mts.map +1 -0
- package/dist/renderer/event.mjs +117 -0
- package/dist/renderer/event.mjs.map +1 -0
- package/dist/renderer/index.d.mts +6 -0
- package/dist/renderer/index.mjs +6 -0
- package/dist/stream.d.mts +38 -0
- package/dist/stream.d.mts.map +1 -0
- package/dist/stream.mjs +80 -0
- package/dist/stream.mjs.map +1 -0
- package/dist/types-BnGse9DF.d.mts +201 -0
- package/dist/types-BnGse9DF.d.mts.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { d as RpcClientOptions, f as RpcDebugOptions, u as RpcApi } from "../types-BnGse9DF.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/client.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create an untyped RPC client
|
|
6
|
+
*
|
|
7
|
+
* @param options - Client options
|
|
8
|
+
* @returns RPC client with call/notify/stream methods
|
|
9
|
+
*/
|
|
10
|
+
declare function createRpcClient(options?: RpcClientOptions & RpcDebugOptions): {
|
|
11
|
+
call: <T = unknown>(method: string, ...params: unknown[]) => Promise<T>;
|
|
12
|
+
notify: (method: string, ...params: unknown[]) => void;
|
|
13
|
+
stream: (method: string, ...params: unknown[]) => ReadableStream;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Create a typed RPC client with full type safety
|
|
17
|
+
*
|
|
18
|
+
* @param options - Client options
|
|
19
|
+
* @returns Typed proxy client
|
|
20
|
+
*/
|
|
21
|
+
declare function createTypedRpcClient<T extends Record<string, (...args: any[]) => any>>(options?: RpcClientOptions & RpcDebugOptions): RpcApi<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Create a RPC client using the preload proxy method
|
|
24
|
+
* This allows the preload script to expose a typed proxy
|
|
25
|
+
*
|
|
26
|
+
* @param options - Client options
|
|
27
|
+
* @returns RPC client or proxy
|
|
28
|
+
*/
|
|
29
|
+
declare function useRpcProxy(options?: RpcClientOptions & RpcDebugOptions): Record<string, (...args: unknown[]) => Promise<unknown>>;
|
|
30
|
+
/**
|
|
31
|
+
* Define a typed RPC API from an interface
|
|
32
|
+
*
|
|
33
|
+
* This is an alias for createTypedRpcClient with a more semantic name
|
|
34
|
+
* for defining API interfaces.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Client options
|
|
37
|
+
* @returns Typed proxy client
|
|
38
|
+
*/
|
|
39
|
+
declare function defineRpcApi<T extends Record<string, (...args: any[]) => any>>(options?: RpcClientOptions & RpcDebugOptions): RpcApi<T>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { type RpcApi, type RpcClientOptions, createRpcClient, createTypedRpcClient, defineRpcApi, useRpcProxy };
|
|
42
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../../src/renderer/client.ts"],"mappings":";;;;AAiBA;;;;;iBAAgB,eAAA,CAAA,OAAA,GAAyB,gBAAA,GAAmB,eAAA;EAAA,IAAA,gBAAA,MAAA,aAAA,MAAA,gBACG,OAAA,CAAQ,CAAA;EAAA,MAAA,GAAA,MAAA,aAAA,MAAA;EAAA,MAAA,GAAA,MAAA,aAAA,MAAA,gBAEnB,cAAA;AAAA;AAAA;;AA+DpD;;;;AA/DoD,iBA+DpC,oBAAA,WAA+B,MAAA,aAAA,IAAA,iBAAA,CAAA,OAAA,GACpC,gBAAA,GAAmB,eAAA,GAC3B,MAAA,CAAO,CAAA;AAAA;;;AAuDV;;;;AAvDU,iBAuDM,WAAA,CAAA,OAAA,GACL,gBAAA,GAAmB,eAAA,GAC3B,MAAA,aAAA,IAAA,gBAAuC,OAAA;AAAA;;;AAqD1C;;;;;;AArD0C,iBAqD1B,YAAA,WAAuB,MAAA,aAAA,IAAA,iBAAA,CAAA,OAAA,GAC5B,gBAAA,GAAmB,eAAA,GAC3B,MAAA,CAAO,CAAA"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { i as RpcTimeoutError } from "../error-xVRu7Lxq.mjs";
|
|
2
|
+
import { getLogger } from "../debug.mjs";
|
|
3
|
+
import { n as createTracker, r as getExposedApi, t as DEFAULT_API_NAME } from "../internal-BZK_0O3n.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/renderer/client.ts
|
|
6
|
+
/**
|
|
7
|
+
* Create an untyped RPC client
|
|
8
|
+
*
|
|
9
|
+
* @param options - Client options
|
|
10
|
+
* @returns RPC client with call/notify/stream methods
|
|
11
|
+
*/
|
|
12
|
+
function createRpcClient(options = {}) {
|
|
13
|
+
const { timeout = 3e4, apiName = DEFAULT_API_NAME, debug, logger } = options;
|
|
14
|
+
const api = getExposedApi(apiName);
|
|
15
|
+
if (!api) throw new Error(`RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`);
|
|
16
|
+
const debugTracker = createTracker(debug, logger ?? getLogger());
|
|
17
|
+
const requestIdCounter = { value: 0 };
|
|
18
|
+
return {
|
|
19
|
+
call: (method, ...params) => {
|
|
20
|
+
const requestId = ++requestIdCounter.value;
|
|
21
|
+
const startTime = performance.now();
|
|
22
|
+
debugTracker.onRequest(method, params, requestId);
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const timeoutId = setTimeout(() => {
|
|
25
|
+
const duration = Math.round(performance.now() - startTime);
|
|
26
|
+
debugTracker.onError(method, params, `Timeout after ${timeout}ms`, duration, requestId);
|
|
27
|
+
reject(new RpcTimeoutError(timeout));
|
|
28
|
+
}, timeout);
|
|
29
|
+
api.call(method, ...params).then((result) => {
|
|
30
|
+
clearTimeout(timeoutId);
|
|
31
|
+
const duration = Math.round(performance.now() - startTime);
|
|
32
|
+
debugTracker.onResponse(method, params, result, duration, requestId);
|
|
33
|
+
resolve(result);
|
|
34
|
+
}).catch((error) => {
|
|
35
|
+
clearTimeout(timeoutId);
|
|
36
|
+
const duration = Math.round(performance.now() - startTime);
|
|
37
|
+
debugTracker.onError(method, params, error.message, duration, requestId);
|
|
38
|
+
reject(error);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
notify: (method, ...params) => {
|
|
43
|
+
debugTracker.onNotify(method, params);
|
|
44
|
+
api.notify(method, ...params);
|
|
45
|
+
},
|
|
46
|
+
stream: (method, ...params) => {
|
|
47
|
+
debugTracker.onStream(method, params);
|
|
48
|
+
return api.stream(method, ...params);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a typed RPC client with full type safety
|
|
54
|
+
*
|
|
55
|
+
* @param options - Client options
|
|
56
|
+
* @returns Typed proxy client
|
|
57
|
+
*/
|
|
58
|
+
function createTypedRpcClient(options = {}) {
|
|
59
|
+
const { timeout = 3e4, apiName = DEFAULT_API_NAME, debug, logger } = options;
|
|
60
|
+
const api = getExposedApi(apiName);
|
|
61
|
+
if (!api) throw new Error(`RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`);
|
|
62
|
+
const debugTracker = createTracker(debug, logger ?? getLogger());
|
|
63
|
+
const requestIdCounter = { value: 0 };
|
|
64
|
+
return new Proxy({}, { get(_target, prop) {
|
|
65
|
+
return (...args) => {
|
|
66
|
+
const requestId = ++requestIdCounter.value;
|
|
67
|
+
const startTime = performance.now();
|
|
68
|
+
debugTracker.onRequest(prop, args, requestId);
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const timeoutId = setTimeout(() => {
|
|
71
|
+
const duration = Math.round(performance.now() - startTime);
|
|
72
|
+
debugTracker.onError(prop, args, `Timeout after ${timeout}ms`, duration, requestId);
|
|
73
|
+
reject(new RpcTimeoutError(timeout));
|
|
74
|
+
}, timeout);
|
|
75
|
+
api.call(prop, ...args).then((result) => {
|
|
76
|
+
clearTimeout(timeoutId);
|
|
77
|
+
const duration = Math.round(performance.now() - startTime);
|
|
78
|
+
debugTracker.onResponse(prop, args, result, duration, requestId);
|
|
79
|
+
resolve(result);
|
|
80
|
+
}).catch((error) => {
|
|
81
|
+
clearTimeout(timeoutId);
|
|
82
|
+
const duration = Math.round(performance.now() - startTime);
|
|
83
|
+
debugTracker.onError(prop, args, error.message, duration, requestId);
|
|
84
|
+
reject(error);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
} });
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a RPC client using the preload proxy method
|
|
92
|
+
* This allows the preload script to expose a typed proxy
|
|
93
|
+
*
|
|
94
|
+
* @param options - Client options
|
|
95
|
+
* @returns RPC client or proxy
|
|
96
|
+
*/
|
|
97
|
+
function useRpcProxy(options = {}) {
|
|
98
|
+
const { apiName = DEFAULT_API_NAME, debug, logger } = options;
|
|
99
|
+
const api = getExposedApi(apiName);
|
|
100
|
+
if (!api) throw new Error(`RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`);
|
|
101
|
+
if (typeof api.proxy === "function") return api.proxy();
|
|
102
|
+
const debugTracker = createTracker(debug, logger ?? getLogger());
|
|
103
|
+
const requestIdCounter = { value: 0 };
|
|
104
|
+
return new Proxy({}, { get(_target, prop) {
|
|
105
|
+
return (...args) => {
|
|
106
|
+
const requestId = ++requestIdCounter.value;
|
|
107
|
+
const startTime = performance.now();
|
|
108
|
+
debugTracker.onRequest(prop, args, requestId);
|
|
109
|
+
return api.call(prop, ...args).then((result) => {
|
|
110
|
+
const duration = Math.round(performance.now() - startTime);
|
|
111
|
+
debugTracker.onResponse(prop, args, result, duration, requestId);
|
|
112
|
+
return result;
|
|
113
|
+
}).catch((error) => {
|
|
114
|
+
const duration = Math.round(performance.now() - startTime);
|
|
115
|
+
debugTracker.onError(prop, args, error.message, duration, requestId);
|
|
116
|
+
throw error;
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
} });
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Define a typed RPC API from an interface
|
|
123
|
+
*
|
|
124
|
+
* This is an alias for createTypedRpcClient with a more semantic name
|
|
125
|
+
* for defining API interfaces.
|
|
126
|
+
*
|
|
127
|
+
* @param options - Client options
|
|
128
|
+
* @returns Typed proxy client
|
|
129
|
+
*/
|
|
130
|
+
function defineRpcApi(options = {}) {
|
|
131
|
+
return createTypedRpcClient(options);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
//#endregion
|
|
135
|
+
export { createRpcClient, createTypedRpcClient, defineRpcApi, useRpcProxy };
|
|
136
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/renderer/client.ts"],"sourcesContent":["/**\n * JSON-RPC Client for Electron Renderer Process\n *\n * Basic client functionality: createRpcClient, createTypedRpcClient, useRpcProxy, defineRpcApi\n */\n\nimport type { RpcApi, RpcClientOptions, RpcDebugOptions } from \"../types.js\";\nimport { RpcTimeoutError } from \"../error.js\";\nimport { getLogger } from \"../debug.js\";\nimport { DEFAULT_API_NAME, getExposedApi, createTracker } from \"./internal.js\";\n\n/**\n * Create an untyped RPC client\n *\n * @param options - Client options\n * @returns RPC client with call/notify/stream methods\n */\nexport function createRpcClient(options: RpcClientOptions & RpcDebugOptions = {}): {\n call: <T = unknown>(method: string, ...params: unknown[]) => Promise<T>;\n notify: (method: string, ...params: unknown[]) => void;\n stream: (method: string, ...params: unknown[]) => ReadableStream;\n} {\n const { timeout = 30000, apiName = DEFAULT_API_NAME, debug, logger } = options;\n const api = getExposedApi(apiName);\n\n if (!api) {\n throw new Error(\n `RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`,\n );\n }\n\n const debugTracker = createTracker(debug, logger ?? getLogger());\n const requestIdCounter = { value: 0 };\n\n return {\n call: <T = unknown>(method: string, ...params: unknown[]): Promise<T> => {\n const requestId = ++requestIdCounter.value;\n const startTime = performance.now();\n\n debugTracker.onRequest(method, params, requestId);\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onError(method, params, `Timeout after ${timeout}ms`, duration, requestId);\n reject(new RpcTimeoutError(timeout));\n }, timeout);\n\n api\n .call(method, ...params)\n .then((result: unknown) => {\n clearTimeout(timeoutId);\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onResponse(method, params, result, duration, requestId);\n resolve(result as T);\n })\n .catch((error: Error) => {\n clearTimeout(timeoutId);\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onError(method, params, error.message, duration, requestId);\n reject(error);\n });\n });\n },\n\n notify: (method: string, ...params: unknown[]): void => {\n debugTracker.onNotify(method, params);\n api.notify(method, ...params);\n },\n\n stream: (method: string, ...params: unknown[]): ReadableStream => {\n debugTracker.onStream(method, params);\n return api.stream(method, ...params);\n },\n };\n}\n\n/**\n * Create a typed RPC client with full type safety\n *\n * @param options - Client options\n * @returns Typed proxy client\n */\nexport function createTypedRpcClient<T extends Record<string, (...args: any[]) => any>>(\n options: RpcClientOptions & RpcDebugOptions = {},\n): RpcApi<T> {\n const { timeout = 30000, apiName = DEFAULT_API_NAME, debug, logger } = options;\n const api = getExposedApi(apiName);\n\n if (!api) {\n throw new Error(\n `RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`,\n );\n }\n\n const debugTracker = createTracker(debug, logger ?? getLogger());\n const requestIdCounter = { value: 0 };\n\n return new Proxy({} as RpcApi<T>, {\n get(_target, prop: string) {\n return (...args: unknown[]) => {\n const requestId = ++requestIdCounter.value;\n const startTime = performance.now();\n\n debugTracker.onRequest(prop, args, requestId);\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onError(prop, args, `Timeout after ${timeout}ms`, duration, requestId);\n reject(new RpcTimeoutError(timeout));\n }, timeout);\n\n api\n .call(prop, ...args)\n .then((result: unknown) => {\n clearTimeout(timeoutId);\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onResponse(prop, args, result, duration, requestId);\n resolve(result as any);\n })\n .catch((error: Error) => {\n clearTimeout(timeoutId);\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onError(prop, args, error.message, duration, requestId);\n reject(error);\n });\n });\n };\n },\n });\n}\n\n/**\n * Create a RPC client using the preload proxy method\n * This allows the preload script to expose a typed proxy\n *\n * @param options - Client options\n * @returns RPC client or proxy\n */\nexport function useRpcProxy(\n options: RpcClientOptions & RpcDebugOptions = {},\n): Record<string, (...args: unknown[]) => Promise<unknown>> {\n const { apiName = DEFAULT_API_NAME, debug, logger } = options;\n const api = getExposedApi(apiName);\n\n if (!api) {\n throw new Error(\n `RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`,\n );\n }\n\n // If preload exposed a proxy method, use it\n if (typeof api.proxy === \"function\") {\n return api.proxy();\n }\n\n const debugTracker = createTracker(debug, logger ?? getLogger());\n const requestIdCounter = { value: 0 };\n\n // Otherwise, return a generic proxy\n return new Proxy({} as Record<string, (...args: unknown[]) => Promise<unknown>>, {\n get(_target, prop: string) {\n return (...args: unknown[]) => {\n const requestId = ++requestIdCounter.value;\n const startTime = performance.now();\n\n debugTracker.onRequest(prop, args, requestId);\n\n return api\n .call(prop, ...args)\n .then((result: unknown) => {\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onResponse(prop, args, result, duration, requestId);\n return result;\n })\n .catch((error: Error) => {\n const duration = Math.round(performance.now() - startTime);\n debugTracker.onError(prop, args, error.message, duration, requestId);\n throw error;\n });\n };\n },\n });\n}\n\n/**\n * Define a typed RPC API from an interface\n *\n * This is an alias for createTypedRpcClient with a more semantic name\n * for defining API interfaces.\n *\n * @param options - Client options\n * @returns Typed proxy client\n */\nexport function defineRpcApi<T extends Record<string, (...args: any[]) => any>>(\n options: RpcClientOptions & RpcDebugOptions = {},\n): RpcApi<T> {\n return createTypedRpcClient<T>(options);\n}\n\n/**\n * Re-export types for convenience\n */\nexport type { RpcApi, RpcClientOptions } from \"../types.js\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { f as RpcDebugOptions, r as EventHandler, t as EventBus } from "../types-BnGse9DF.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/event.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create a typed event bus for renderer process
|
|
6
|
+
*
|
|
7
|
+
* Provides type-safe event subscription with full type inference.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Client options
|
|
10
|
+
* @returns Typed event bus
|
|
11
|
+
*/
|
|
12
|
+
declare function createEventBus<T extends Record<string, unknown> = Record<string, unknown>>(options?: {
|
|
13
|
+
apiName?: string;
|
|
14
|
+
} & RpcDebugOptions): EventBus<T>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { type EventBus, type EventHandler, createEventBus };
|
|
17
|
+
//# sourceMappingURL=event.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.mts","names":[],"sources":["../../src/renderer/event.ts"],"mappings":";;;;AAkBA;;;;;;;iBAAgB,cAAA,WAAyB,MAAA,oBAA0B,MAAA,kBAAA,CAAA,OAAA;EAAA,OAAA;AAAA,IACjC,eAAA,GAC/B,QAAA,CAAS,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createDebugTracker, getLogger, isDebugEnabled } from "../debug.mjs";
|
|
2
|
+
import { r as getExposedApi, t as DEFAULT_API_NAME } from "../internal-BZK_0O3n.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/event.ts
|
|
5
|
+
/**
|
|
6
|
+
* Create a typed event bus for renderer process
|
|
7
|
+
*
|
|
8
|
+
* Provides type-safe event subscription with full type inference.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Client options
|
|
11
|
+
* @returns Typed event bus
|
|
12
|
+
*/
|
|
13
|
+
function createEventBus(options = {}) {
|
|
14
|
+
const { apiName = DEFAULT_API_NAME, debug, logger } = options;
|
|
15
|
+
const api = getExposedApi(apiName);
|
|
16
|
+
if (!api) throw new Error(`RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`);
|
|
17
|
+
if (typeof api.on !== "function") throw new Error("Event bus methods not available. Make sure you're using a version of electron-json-rpc/preload that supports events.");
|
|
18
|
+
const enabled = isDebugEnabled(debug);
|
|
19
|
+
const debugTracker = createDebugTracker(enabled, logger ?? getLogger());
|
|
20
|
+
const subscribedEvents = /* @__PURE__ */ new Set();
|
|
21
|
+
const handlerRegistry = /* @__PURE__ */ new Map();
|
|
22
|
+
const wrappedHandlers = /* @__PURE__ */ new Map();
|
|
23
|
+
const registerHandler = (eventName, handler) => {
|
|
24
|
+
let handlers = handlerRegistry.get(eventName);
|
|
25
|
+
if (!handlers) {
|
|
26
|
+
handlers = /* @__PURE__ */ new Set();
|
|
27
|
+
handlerRegistry.set(eventName, handlers);
|
|
28
|
+
}
|
|
29
|
+
handlers.add(handler);
|
|
30
|
+
subscribedEvents.add(eventName);
|
|
31
|
+
};
|
|
32
|
+
const unregisterHandler = (eventName, handler) => {
|
|
33
|
+
const handlers = handlerRegistry.get(eventName);
|
|
34
|
+
if (!handlers) return;
|
|
35
|
+
if (handler) {
|
|
36
|
+
handlers.delete(handler);
|
|
37
|
+
wrappedHandlers.get(eventName)?.delete(handler);
|
|
38
|
+
} else {
|
|
39
|
+
handlers.clear();
|
|
40
|
+
handlerRegistry.delete(eventName);
|
|
41
|
+
wrappedHandlers.delete(eventName);
|
|
42
|
+
}
|
|
43
|
+
if (handlers.size === 0) {
|
|
44
|
+
handlerRegistry.delete(eventName);
|
|
45
|
+
wrappedHandlers.delete(eventName);
|
|
46
|
+
subscribedEvents.delete(eventName);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const getWrappedHandler = (eventName, handler) => {
|
|
50
|
+
if (!enabled) return handler;
|
|
51
|
+
let eventHandlers = wrappedHandlers.get(eventName);
|
|
52
|
+
if (!eventHandlers) {
|
|
53
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
54
|
+
wrappedHandlers.set(eventName, eventHandlers);
|
|
55
|
+
}
|
|
56
|
+
const existing = eventHandlers.get(handler);
|
|
57
|
+
if (existing) return existing;
|
|
58
|
+
const wrapped = (data) => {
|
|
59
|
+
debugTracker.onEvent(String(eventName), data);
|
|
60
|
+
return handler(data);
|
|
61
|
+
};
|
|
62
|
+
eventHandlers.set(handler, wrapped);
|
|
63
|
+
return wrapped;
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
on: (eventName, callback) => {
|
|
67
|
+
const name = String(eventName);
|
|
68
|
+
const handler = callback;
|
|
69
|
+
const wrappedHandler = getWrappedHandler(name, handler);
|
|
70
|
+
registerHandler(name, handler);
|
|
71
|
+
const unsubscribe = api.on(name, wrappedHandler);
|
|
72
|
+
return () => {
|
|
73
|
+
unsubscribe();
|
|
74
|
+
unregisterHandler(name, handler);
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
off: (eventName, callback) => {
|
|
78
|
+
const name = String(eventName);
|
|
79
|
+
if (callback) {
|
|
80
|
+
const handler = callback;
|
|
81
|
+
const wrappedHandler = wrappedHandlers.get(name)?.get(handler) ?? handler;
|
|
82
|
+
api.off(name, wrappedHandler);
|
|
83
|
+
unregisterHandler(name, handler);
|
|
84
|
+
} else {
|
|
85
|
+
api.off(name);
|
|
86
|
+
unregisterHandler(name);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
once: (eventName, callback) => {
|
|
90
|
+
const name = String(eventName);
|
|
91
|
+
const handler = callback;
|
|
92
|
+
registerHandler(name, handler);
|
|
93
|
+
const wrappedHandler = (data) => {
|
|
94
|
+
if (enabled) debugTracker.onEvent(name, data);
|
|
95
|
+
try {
|
|
96
|
+
handler(data);
|
|
97
|
+
} finally {
|
|
98
|
+
unregisterHandler(name, handler);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
if (enabled) {
|
|
102
|
+
let eventHandlers = wrappedHandlers.get(name);
|
|
103
|
+
if (!eventHandlers) {
|
|
104
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
105
|
+
wrappedHandlers.set(name, eventHandlers);
|
|
106
|
+
}
|
|
107
|
+
eventHandlers.set(handler, wrappedHandler);
|
|
108
|
+
}
|
|
109
|
+
api.once(name, wrappedHandler);
|
|
110
|
+
},
|
|
111
|
+
getSubscribedEvents: () => Array.from(subscribedEvents)
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { createEventBus };
|
|
117
|
+
//# sourceMappingURL=event.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.mjs","names":[],"sources":["../../src/renderer/event.ts"],"sourcesContent":["/**\n * Typed Event Bus for Electron Renderer Process\n *\n * Provides type-safe event subscription with full type inference.\n */\n\nimport type { EventBus, EventHandler, RpcDebugOptions } from \"../types.js\";\nimport { isDebugEnabled, getLogger, createDebugTracker } from \"../debug.js\";\nimport { DEFAULT_API_NAME, getExposedApi } from \"./internal.js\";\n\n/**\n * Create a typed event bus for renderer process\n *\n * Provides type-safe event subscription with full type inference.\n *\n * @param options - Client options\n * @returns Typed event bus\n */\nexport function createEventBus<T extends Record<string, unknown> = Record<string, unknown>>(\n options: { apiName?: string } & RpcDebugOptions = {},\n): EventBus<T> {\n const { apiName = DEFAULT_API_NAME, debug, logger } = options;\n const api = getExposedApi(apiName);\n\n if (!api) {\n throw new Error(\n `RPC API not found. Make sure exposeRpcApi() is called in your preload script with apiName='${apiName}'.`,\n );\n }\n\n // Check if the API has event methods\n if (typeof api.on !== \"function\") {\n throw new Error(\n \"Event bus methods not available. Make sure you're using a version of electron-json-rpc/preload that supports events.\",\n );\n }\n\n const enabled = isDebugEnabled(debug);\n const debugTracker = createDebugTracker(enabled, logger ?? getLogger());\n const subscribedEvents = new Set<string>();\n const handlerRegistry = new Map<string, Set<EventHandler<unknown>>>();\n const wrappedHandlers = new Map<string, Map<EventHandler<unknown>, (data: unknown) => void>>();\n\n const registerHandler = (eventName: string, handler: EventHandler<unknown>): void => {\n let handlers = handlerRegistry.get(eventName);\n if (!handlers) {\n handlers = new Set();\n handlerRegistry.set(eventName, handlers);\n }\n handlers.add(handler);\n subscribedEvents.add(eventName);\n };\n\n const unregisterHandler = (eventName: string, handler?: EventHandler<unknown>): void => {\n const handlers = handlerRegistry.get(eventName);\n if (!handlers) {\n return;\n }\n\n if (handler) {\n handlers.delete(handler);\n wrappedHandlers.get(eventName)?.delete(handler);\n } else {\n handlers.clear();\n handlerRegistry.delete(eventName);\n wrappedHandlers.delete(eventName);\n }\n\n if (handlers.size === 0) {\n handlerRegistry.delete(eventName);\n wrappedHandlers.delete(eventName);\n subscribedEvents.delete(eventName);\n }\n };\n\n const getWrappedHandler = (\n eventName: string,\n handler: EventHandler<unknown>,\n ): ((data: unknown) => void) => {\n if (!enabled) {\n return handler as (data: unknown) => void;\n }\n\n let eventHandlers = wrappedHandlers.get(eventName);\n if (!eventHandlers) {\n eventHandlers = new Map();\n wrappedHandlers.set(eventName, eventHandlers);\n }\n\n const existing = eventHandlers.get(handler);\n if (existing) {\n return existing;\n }\n\n const wrapped = (data: unknown) => {\n debugTracker.onEvent(String(eventName), data);\n return handler(data);\n };\n\n eventHandlers.set(handler, wrapped);\n return wrapped;\n };\n\n return {\n on: (eventName, callback) => {\n const name = String(eventName);\n const handler = callback as EventHandler<unknown>;\n const wrappedHandler = getWrappedHandler(name, handler);\n\n registerHandler(name, handler);\n\n const unsubscribe = api.on!(name, wrappedHandler);\n return () => {\n unsubscribe();\n unregisterHandler(name, handler);\n };\n },\n\n off: (eventName, callback) => {\n const name = String(eventName);\n\n if (callback) {\n const handler = callback as EventHandler<unknown>;\n const wrappedHandler = wrappedHandlers.get(name)?.get(handler) ?? handler;\n api.off!(name, wrappedHandler as (data?: unknown) => void);\n unregisterHandler(name, handler);\n } else {\n api.off!(name);\n unregisterHandler(name);\n }\n },\n\n once: (eventName, callback) => {\n const name = String(eventName);\n const handler = callback as EventHandler<unknown>;\n\n registerHandler(name, handler);\n\n const wrappedHandler = (data: unknown) => {\n if (enabled) {\n debugTracker.onEvent(name, data);\n }\n try {\n handler(data);\n } finally {\n unregisterHandler(name, handler);\n }\n };\n\n if (enabled) {\n let eventHandlers = wrappedHandlers.get(name);\n if (!eventHandlers) {\n eventHandlers = new Map();\n wrappedHandlers.set(name, eventHandlers);\n }\n eventHandlers.set(handler, wrappedHandler);\n }\n\n api.once!(name, wrappedHandler);\n },\n\n getSubscribedEvents: () => Array.from(subscribedEvents),\n };\n}\n\n/**\n * Re-export types for convenience\n */\nexport type { EventBus, EventHandler } from \"../types.js\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { d as RpcClientOptions, h as RpcLogger, m as RpcLogEntry, r as EventHandler, t as EventBus, u as RpcApi } from "../types-BnGse9DF.mjs";
|
|
2
|
+
import { isRpcDebug, setRpcDebug, setRpcLogger } from "../debug.mjs";
|
|
3
|
+
import { RpcBuilder, RpcBuilderMethods, RpcBuilderWithMethod, createRpc } from "./builder.mjs";
|
|
4
|
+
import { createRpcClient, createTypedRpcClient, defineRpcApi, useRpcProxy } from "./client.mjs";
|
|
5
|
+
import { createEventBus } from "./event.mjs";
|
|
6
|
+
export { type EventBus, type EventHandler, type RpcApi, type RpcBuilder, type RpcBuilderMethods, type RpcBuilderWithMethod, type RpcClientOptions, type RpcLogEntry, type RpcLogger, createEventBus, createRpc, createRpcClient, createTypedRpcClient, defineRpcApi, isRpcDebug, setRpcDebug, setRpcLogger, useRpcProxy };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { isRpcDebug, setRpcDebug, setRpcLogger } from "../debug.mjs";
|
|
2
|
+
import { createRpcClient, createTypedRpcClient, defineRpcApi, useRpcProxy } from "./client.mjs";
|
|
3
|
+
import { createRpc } from "./builder.mjs";
|
|
4
|
+
import { createEventBus } from "./event.mjs";
|
|
5
|
+
|
|
6
|
+
export { createEventBus, createRpc, createRpcClient, createTypedRpcClient, defineRpcApi, isRpcDebug, setRpcDebug, setRpcLogger, useRpcProxy };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/stream.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stream utilities for electron-json-rpc
|
|
4
|
+
*
|
|
5
|
+
* Shared constants and utilities for streaming support
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* IPC channel name for stream chunks
|
|
9
|
+
*/
|
|
10
|
+
declare const STREAM_CHANNEL = "json-rpc-stream";
|
|
11
|
+
declare function generateStreamId(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Create a stream chunk message
|
|
14
|
+
*/
|
|
15
|
+
declare function createStreamChunk(streamId: string | number, type: "chunk" | "end" | "error", data?: unknown): {
|
|
16
|
+
streamId: string | number;
|
|
17
|
+
type: "chunk" | "end" | "error";
|
|
18
|
+
data?: unknown;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Check if a value is a ReadableStream
|
|
22
|
+
*/
|
|
23
|
+
declare function isReadableStream(value: unknown): value is ReadableStream;
|
|
24
|
+
/**
|
|
25
|
+
* Read entire stream into an array
|
|
26
|
+
*/
|
|
27
|
+
declare function readStream<T>(stream: ReadableStream<T>): Promise<T[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Convert async generator to ReadableStream
|
|
30
|
+
*/
|
|
31
|
+
declare function asyncGeneratorToStream<T>(generator: () => AsyncGenerator<T>): ReadableStream<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Convert array to ReadableStream
|
|
34
|
+
*/
|
|
35
|
+
declare function iterableToStream<T>(iterable: Iterable<T> | AsyncIterable<T>): ReadableStream<T>;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { STREAM_CHANNEL, asyncGeneratorToStream, createStreamChunk, generateStreamId, isReadableStream, iterableToStream, readStream };
|
|
38
|
+
//# sourceMappingURL=stream.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.mts","names":[],"sources":["../src/stream.ts"],"mappings":";;AASA;AAMA;AAOA;AAeA;;AA5BA;AAMA;cANa,cAAA;AAAA,iBAMG,gBAAA,CAAA;AAAA;AAOhB;AAeA;AAtBgB,iBAOA,iBAAA,CAAA,QAAA,mBAAA,IAAA,6BAAA,IAAA;EAAA,QAAA;EAAA,IAAA;EAAA,IAAA;AAAA;AAAA;AAehB;AAYA;AA3BgB,iBAeA,gBAAA,CAAA,KAAA,YAAA,KAAA,IAA2C,cAAA;AAAA;AAY3D;;AAZ2D,iBAYrC,UAAA,GAAA,CAAA,MAAA,EAAsB,cAAA,CAAe,CAAA,IAAK,OAAA,CAAQ,CAAA;AAAA;;;AAAA,iBAsBxD,sBAAA,GAAA,CAAA,SAAA,QAA2C,cAAA,CAAe,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA;;;AAAA,iBAkB9E,gBAAA,GAAA,CAAA,QAAA,EAA8B,QAAA,CAAS,CAAA,IAAK,aAAA,CAAc,CAAA,IAAK,cAAA,CAAe,CAAA"}
|
package/dist/stream.mjs
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/stream.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stream utilities for electron-json-rpc
|
|
4
|
+
*
|
|
5
|
+
* Shared constants and utilities for streaming support
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* IPC channel name for stream chunks
|
|
9
|
+
*/
|
|
10
|
+
const STREAM_CHANNEL = "json-rpc-stream";
|
|
11
|
+
/**
|
|
12
|
+
* Generate unique stream ID
|
|
13
|
+
*/
|
|
14
|
+
let streamIdCounter = 0;
|
|
15
|
+
function generateStreamId() {
|
|
16
|
+
return `stream_${++streamIdCounter}_${Date.now()}`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create a stream chunk message
|
|
20
|
+
*/
|
|
21
|
+
function createStreamChunk(streamId, type, data) {
|
|
22
|
+
return {
|
|
23
|
+
streamId,
|
|
24
|
+
type,
|
|
25
|
+
data
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a value is a ReadableStream
|
|
30
|
+
*/
|
|
31
|
+
function isReadableStream(value) {
|
|
32
|
+
return typeof value === "object" && value !== null && "getReader" in value && typeof value.getReader === "function";
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Read entire stream into an array
|
|
36
|
+
*/
|
|
37
|
+
async function readStream(stream) {
|
|
38
|
+
const reader = stream.getReader();
|
|
39
|
+
const chunks = [];
|
|
40
|
+
try {
|
|
41
|
+
while (true) {
|
|
42
|
+
const { done, value } = await reader.read();
|
|
43
|
+
if (done) break;
|
|
44
|
+
if (value !== void 0) chunks.push(value);
|
|
45
|
+
}
|
|
46
|
+
} finally {
|
|
47
|
+
reader.releaseLock();
|
|
48
|
+
}
|
|
49
|
+
return chunks;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert async generator to ReadableStream
|
|
53
|
+
*/
|
|
54
|
+
function asyncGeneratorToStream(generator) {
|
|
55
|
+
return new ReadableStream({ async start(controller) {
|
|
56
|
+
try {
|
|
57
|
+
for await (const value of generator()) controller.enqueue(value);
|
|
58
|
+
controller.close();
|
|
59
|
+
} catch (error) {
|
|
60
|
+
controller.error(error);
|
|
61
|
+
}
|
|
62
|
+
} });
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert array to ReadableStream
|
|
66
|
+
*/
|
|
67
|
+
function iterableToStream(iterable) {
|
|
68
|
+
return new ReadableStream({ async start(controller) {
|
|
69
|
+
try {
|
|
70
|
+
for await (const value of iterable) controller.enqueue(value);
|
|
71
|
+
controller.close();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
controller.error(error);
|
|
74
|
+
}
|
|
75
|
+
} });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { STREAM_CHANNEL, asyncGeneratorToStream, createStreamChunk, generateStreamId, isReadableStream, iterableToStream, readStream };
|
|
80
|
+
//# sourceMappingURL=stream.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.mjs","names":[],"sources":["../src/stream.ts"],"sourcesContent":["/**\n * Stream utilities for electron-json-rpc\n *\n * Shared constants and utilities for streaming support\n */\n\n/**\n * IPC channel name for stream chunks\n */\nexport const STREAM_CHANNEL = \"json-rpc-stream\";\n\n/**\n * Generate unique stream ID\n */\nlet streamIdCounter = 0;\nexport function generateStreamId(): string {\n return `stream_${++streamIdCounter}_${Date.now()}`;\n}\n\n/**\n * Create a stream chunk message\n */\nexport function createStreamChunk(\n streamId: string | number,\n type: \"chunk\" | \"end\" | \"error\",\n data?: unknown,\n): {\n streamId: string | number;\n type: \"chunk\" | \"end\" | \"error\";\n data?: unknown;\n} {\n return { streamId, type, data };\n}\n\n/**\n * Check if a value is a ReadableStream\n */\nexport function isReadableStream(value: unknown): value is ReadableStream {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"getReader\" in value &&\n typeof (value as ReadableStream).getReader === \"function\"\n );\n}\n\n/**\n * Read entire stream into an array\n */\nexport async function readStream<T>(stream: ReadableStream<T>): Promise<T[]> {\n const reader = stream.getReader();\n const chunks: T[] = [];\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value !== undefined) {\n chunks.push(value);\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return chunks;\n}\n\n/**\n * Convert async generator to ReadableStream\n */\nexport function asyncGeneratorToStream<T>(generator: () => AsyncGenerator<T>): ReadableStream<T> {\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const value of generator()) {\n controller.enqueue(value);\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\n/**\n * Convert array to ReadableStream\n */\nexport function iterableToStream<T>(iterable: Iterable<T> | AsyncIterable<T>): ReadableStream<T> {\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const value of iterable) {\n controller.enqueue(value);\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,iBAAiB;;;;AAK9B,IAAI,kBAAkB;AACtB,SAAgB,mBAA2B;AACzC,QAAO,UAAU,EAAE,gBAAgB,GAAG,KAAK,KAAK;;;;;AAMlD,SAAgB,kBACd,UACA,MACA,MAKA;AACA,QAAO;EAAE;EAAU;EAAM;EAAM;;;;;AAMjC,SAAgB,iBAAiB,OAAyC;AACxE,QACE,OAAO,UAAU,YACjB,UAAU,QACV,eAAe,SACf,OAAQ,MAAyB,cAAc;;;;;AAOnD,eAAsB,WAAc,QAAyC;CAC3E,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,SAAc,EAAE;AAEtB,KAAI;AACF,SAAO,MAAM;GACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,OAAI,KAAM;AACV,OAAI,UAAU,OACZ,QAAO,KAAK,MAAM;;WAGd;AACR,SAAO,aAAa;;AAGtB,QAAO;;;;;AAMT,SAAgB,uBAA0B,WAAuD;AAC/F,QAAO,IAAI,eAAe,EACxB,MAAM,MAAM,YAAY;AACtB,MAAI;AACF,cAAW,MAAM,SAAS,WAAW,CACnC,YAAW,QAAQ,MAAM;AAE3B,cAAW,OAAO;WACX,OAAO;AACd,cAAW,MAAM,MAAM;;IAG5B,CAAC;;;;;AAMJ,SAAgB,iBAAoB,UAA6D;AAC/F,QAAO,IAAI,eAAe,EACxB,MAAM,MAAM,YAAY;AACtB,MAAI;AACF,cAAW,MAAM,SAAS,SACxB,YAAW,QAAQ,MAAM;AAE3B,cAAW,OAAO;WACX,OAAO;AACd,cAAW,MAAM,MAAM;;IAG5B,CAAC"}
|