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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +978 -0
  3. package/README.zh-CN.md +978 -0
  4. package/dist/debug.d.mts +92 -0
  5. package/dist/debug.d.mts.map +1 -0
  6. package/dist/debug.mjs +206 -0
  7. package/dist/debug.mjs.map +1 -0
  8. package/dist/error-xVRu7Lxq.mjs +131 -0
  9. package/dist/error-xVRu7Lxq.mjs.map +1 -0
  10. package/dist/event.d.mts +71 -0
  11. package/dist/event.d.mts.map +1 -0
  12. package/dist/event.mjs +60 -0
  13. package/dist/event.mjs.map +1 -0
  14. package/dist/index.d.mts +78 -0
  15. package/dist/index.d.mts.map +1 -0
  16. package/dist/index.mjs +4 -0
  17. package/dist/internal-BZK_0O3n.mjs +23 -0
  18. package/dist/internal-BZK_0O3n.mjs.map +1 -0
  19. package/dist/main.d.mts +151 -0
  20. package/dist/main.d.mts.map +1 -0
  21. package/dist/main.mjs +329 -0
  22. package/dist/main.mjs.map +1 -0
  23. package/dist/preload.d.mts +23 -0
  24. package/dist/preload.d.mts.map +1 -0
  25. package/dist/preload.mjs +417 -0
  26. package/dist/preload.mjs.map +1 -0
  27. package/dist/renderer/builder.d.mts +64 -0
  28. package/dist/renderer/builder.d.mts.map +1 -0
  29. package/dist/renderer/builder.mjs +101 -0
  30. package/dist/renderer/builder.mjs.map +1 -0
  31. package/dist/renderer/client.d.mts +42 -0
  32. package/dist/renderer/client.d.mts.map +1 -0
  33. package/dist/renderer/client.mjs +136 -0
  34. package/dist/renderer/client.mjs.map +1 -0
  35. package/dist/renderer/event.d.mts +17 -0
  36. package/dist/renderer/event.d.mts.map +1 -0
  37. package/dist/renderer/event.mjs +117 -0
  38. package/dist/renderer/event.mjs.map +1 -0
  39. package/dist/renderer/index.d.mts +6 -0
  40. package/dist/renderer/index.mjs +6 -0
  41. package/dist/stream.d.mts +38 -0
  42. package/dist/stream.d.mts.map +1 -0
  43. package/dist/stream.mjs +80 -0
  44. package/dist/stream.mjs.map +1 -0
  45. package/dist/types-BnGse9DF.d.mts +201 -0
  46. package/dist/types-BnGse9DF.d.mts.map +1 -0
  47. 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"}
@@ -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"}