kkrpc 0.0.15 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -1
- package/dist/browser-mod.cjs +218 -134
- package/dist/browser-mod.d.cts +2 -1
- package/dist/browser-mod.d.ts +2 -1
- package/dist/browser-mod.js +6 -0
- package/dist/chrome.cjs +363 -0
- package/dist/{serialization-BrfKixNU.d.cts → chrome.d.cts} +15 -5
- package/dist/{serialization-C0yxGsSr.d.ts → chrome.d.ts} +15 -5
- package/dist/chrome.js +22 -0
- package/dist/chunk-INKNKSKA.js +84 -0
- package/dist/mod.cjs +89 -5
- package/dist/mod.d.cts +2 -1
- package/dist/mod.d.ts +2 -1
- package/dist/mod.js +6 -0
- package/dist/worker-ByZFWF48.d.cts +27 -0
- package/dist/worker-sUTyf1YL.d.ts +27 -0
- package/package.json +70 -48
package/README.md
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
- [Documentation by JSR](https://jsr.io/@kunkun/kkrpc/doc)
|
|
13
13
|
- [Typedoc Documentation](https://kunkunsh.github.io/kkrpc/)
|
|
14
14
|
|
|
15
|
+

|
|
16
|
+

|
|
17
|
+

|
|
18
|
+
|
|
15
19
|
## Supported Environments
|
|
16
20
|
|
|
17
21
|
- stdio: RPC over stdio between any combinations of Node.js, Deno, Bun processes
|
|
@@ -47,7 +51,7 @@ class RPCChannel<
|
|
|
47
51
|
> {}
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
##
|
|
54
|
+
## Examples
|
|
51
55
|
|
|
52
56
|
Below are simple examples.
|
|
53
57
|
|
|
@@ -166,3 +170,51 @@ console.log("echoResponse", echoResponse)
|
|
|
166
170
|
const sum = await clientAPI.add(2, 3)
|
|
167
171
|
console.log("Sum: ", sum)
|
|
168
172
|
```
|
|
173
|
+
|
|
174
|
+
### Chrome Extension Example
|
|
175
|
+
|
|
176
|
+
#### `background.ts`
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { ChromeBackgroundIO, RPCChannel } from "kkrpc"
|
|
180
|
+
import type { API } from "./api"
|
|
181
|
+
|
|
182
|
+
// Store RPC channels for each tab
|
|
183
|
+
const rpcChannels = new Map<number, RPCChannel<API, {}>>()
|
|
184
|
+
|
|
185
|
+
// Listen for tab connections
|
|
186
|
+
chrome.runtime.onConnect.addListener((port) => {
|
|
187
|
+
if (port.sender?.tab?.id) {
|
|
188
|
+
const tabId = port.sender.tab.id
|
|
189
|
+
const io = new ChromeBackgroundIO(tabId)
|
|
190
|
+
const rpc = new RPCChannel(io, { expose: backgroundAPI })
|
|
191
|
+
rpcChannels.set(tabId, rpc)
|
|
192
|
+
|
|
193
|
+
port.onDisconnect.addListener(() => {
|
|
194
|
+
rpcChannels.delete(tabId)
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `content.ts`
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { ChromeContentIO, RPCChannel } from "kkrpc"
|
|
204
|
+
import type { API } from "./api"
|
|
205
|
+
|
|
206
|
+
const io = new ChromeContentIO()
|
|
207
|
+
const rpc = new RPCChannel<API, API>(io, {
|
|
208
|
+
expose: {
|
|
209
|
+
updateUI: async (data) => {
|
|
210
|
+
document.body.innerHTML = data.message
|
|
211
|
+
return true
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// Get API from background script
|
|
217
|
+
const api = rpc.getAPI()
|
|
218
|
+
const data = await api.getData()
|
|
219
|
+
console.log(data) // { message: "Hello from background!" }
|
|
220
|
+
```
|
package/dist/browser-mod.cjs
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// browser-mod.ts
|
|
21
21
|
var browser_mod_exports = {};
|
|
22
22
|
__export(browser_mod_exports, {
|
|
23
|
+
ChromeBackgroundIO: () => ChromeBackgroundIO,
|
|
24
|
+
ChromeContentIO: () => ChromeContentIO,
|
|
23
25
|
IframeChildIO: () => IframeChildIO,
|
|
24
26
|
IframeParentIO: () => IframeParentIO,
|
|
25
27
|
RPCChannel: () => RPCChannel,
|
|
@@ -117,6 +119,220 @@ var WorkerChildIO = class {
|
|
|
117
119
|
}
|
|
118
120
|
};
|
|
119
121
|
|
|
122
|
+
// src/adapters/chrome.ts
|
|
123
|
+
var DESTROY_SIGNAL2 = "__DESTROY__";
|
|
124
|
+
var ChromeBackgroundIO = class {
|
|
125
|
+
name = "chrome-background-io";
|
|
126
|
+
messageQueue = [];
|
|
127
|
+
resolveRead = null;
|
|
128
|
+
tabId;
|
|
129
|
+
handleMessage = (message, sender, _sendResponse) => {
|
|
130
|
+
if (sender.tab?.id !== this.tabId) return;
|
|
131
|
+
if (message === DESTROY_SIGNAL2) {
|
|
132
|
+
this.destroy();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (this.resolveRead) {
|
|
136
|
+
this.resolveRead(message);
|
|
137
|
+
this.resolveRead = null;
|
|
138
|
+
} else {
|
|
139
|
+
this.messageQueue.push(message);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
constructor(tabId) {
|
|
143
|
+
this.tabId = tabId;
|
|
144
|
+
chrome.runtime.onMessage.addListener(this.handleMessage);
|
|
145
|
+
}
|
|
146
|
+
async read() {
|
|
147
|
+
if (this.messageQueue.length > 0) {
|
|
148
|
+
return this.messageQueue.shift() ?? null;
|
|
149
|
+
}
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
this.resolveRead = resolve;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async write(data) {
|
|
155
|
+
await chrome.tabs.sendMessage(this.tabId, data);
|
|
156
|
+
}
|
|
157
|
+
destroy() {
|
|
158
|
+
chrome.runtime.onMessage.removeListener(this.handleMessage);
|
|
159
|
+
}
|
|
160
|
+
signalDestroy() {
|
|
161
|
+
this.write(DESTROY_SIGNAL2);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
var ChromeContentIO = class {
|
|
165
|
+
name = "chrome-content-io";
|
|
166
|
+
messageQueue = [];
|
|
167
|
+
resolveRead = null;
|
|
168
|
+
constructor() {
|
|
169
|
+
chrome.runtime.onMessage.addListener(this.handleMessage);
|
|
170
|
+
}
|
|
171
|
+
handleMessage = (message, _sender, _sendResponse) => {
|
|
172
|
+
if (message === DESTROY_SIGNAL2) {
|
|
173
|
+
this.destroy();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (this.resolveRead) {
|
|
177
|
+
this.resolveRead(message);
|
|
178
|
+
this.resolveRead = null;
|
|
179
|
+
} else {
|
|
180
|
+
this.messageQueue.push(message);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
async read() {
|
|
184
|
+
if (this.messageQueue.length > 0) {
|
|
185
|
+
return this.messageQueue.shift() ?? null;
|
|
186
|
+
}
|
|
187
|
+
return new Promise((resolve) => {
|
|
188
|
+
this.resolveRead = resolve;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
async write(data) {
|
|
192
|
+
await chrome.runtime.sendMessage(data);
|
|
193
|
+
}
|
|
194
|
+
destroy() {
|
|
195
|
+
chrome.runtime.onMessage.removeListener(this.handleMessage);
|
|
196
|
+
}
|
|
197
|
+
signalDestroy() {
|
|
198
|
+
this.write(DESTROY_SIGNAL2);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// src/adapters/iframe.ts
|
|
203
|
+
var DESTROY_SIGNAL3 = "__DESTROY__";
|
|
204
|
+
var PORT_INIT_SIGNAL = "__PORT_INIT__";
|
|
205
|
+
var IframeParentIO = class {
|
|
206
|
+
/**
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* const io = new IframeParentIO(iframeRef.contentWindow);
|
|
210
|
+
* const rpc = new RPCChannel(io, {
|
|
211
|
+
* expose: {
|
|
212
|
+
* add: (a: number, b: number) => Promise.resolve(a + b),
|
|
213
|
+
* },
|
|
214
|
+
* });
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
constructor(targetWindow) {
|
|
218
|
+
this.targetWindow = targetWindow;
|
|
219
|
+
this.port = null;
|
|
220
|
+
window.addEventListener("message", (event) => {
|
|
221
|
+
if (event.source !== this.targetWindow) return;
|
|
222
|
+
if (event.data === PORT_INIT_SIGNAL && event.ports.length > 0) {
|
|
223
|
+
this.port = event.ports[0];
|
|
224
|
+
this.port.onmessage = this.handleMessage;
|
|
225
|
+
while (this.messageQueue.length > 0) {
|
|
226
|
+
const message = this.messageQueue.shift();
|
|
227
|
+
if (message) this.port.postMessage(message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
name = "iframe-parent-io";
|
|
233
|
+
messageQueue = [];
|
|
234
|
+
resolveRead = null;
|
|
235
|
+
port = null;
|
|
236
|
+
handleMessage = (event) => {
|
|
237
|
+
const message = event.data;
|
|
238
|
+
if (message === DESTROY_SIGNAL3) {
|
|
239
|
+
this.destroy();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (this.resolveRead) {
|
|
243
|
+
this.resolveRead(message);
|
|
244
|
+
this.resolveRead = null;
|
|
245
|
+
} else {
|
|
246
|
+
this.messageQueue.push(message);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
async read() {
|
|
250
|
+
if (this.messageQueue.length > 0) {
|
|
251
|
+
return this.messageQueue.shift() ?? null;
|
|
252
|
+
}
|
|
253
|
+
return new Promise((resolve) => {
|
|
254
|
+
this.resolveRead = resolve;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
async write(data) {
|
|
258
|
+
if (!this.port) {
|
|
259
|
+
this.messageQueue.push(data);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
this.port.postMessage(data);
|
|
263
|
+
}
|
|
264
|
+
destroy() {
|
|
265
|
+
if (this.port) {
|
|
266
|
+
this.port.postMessage(DESTROY_SIGNAL3);
|
|
267
|
+
this.port.close();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
signalDestroy() {
|
|
271
|
+
if (this.port) {
|
|
272
|
+
this.port.postMessage(DESTROY_SIGNAL3);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
var IframeChildIO = class {
|
|
277
|
+
name = "iframe-child-io";
|
|
278
|
+
messageQueue = [];
|
|
279
|
+
resolveRead = null;
|
|
280
|
+
port = null;
|
|
281
|
+
pendingMessages = [];
|
|
282
|
+
initialized;
|
|
283
|
+
channel;
|
|
284
|
+
constructor() {
|
|
285
|
+
this.channel = new MessageChannel();
|
|
286
|
+
this.port = this.channel.port1;
|
|
287
|
+
this.port.onmessage = this.handleMessage;
|
|
288
|
+
window.parent.postMessage(PORT_INIT_SIGNAL, "*", [this.channel.port2]);
|
|
289
|
+
this.initialized = Promise.resolve();
|
|
290
|
+
}
|
|
291
|
+
handleMessage = (event) => {
|
|
292
|
+
const message = event.data;
|
|
293
|
+
if (message === DESTROY_SIGNAL3) {
|
|
294
|
+
this.destroy();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (this.resolveRead) {
|
|
298
|
+
this.resolveRead(message);
|
|
299
|
+
this.resolveRead = null;
|
|
300
|
+
} else {
|
|
301
|
+
this.messageQueue.push(message);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
async read() {
|
|
305
|
+
await this.initialized;
|
|
306
|
+
if (this.messageQueue.length > 0) {
|
|
307
|
+
return this.messageQueue.shift() ?? null;
|
|
308
|
+
}
|
|
309
|
+
return new Promise((resolve) => {
|
|
310
|
+
this.resolveRead = resolve;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async write(data) {
|
|
314
|
+
await this.initialized;
|
|
315
|
+
if (this.port) {
|
|
316
|
+
this.port.postMessage(data);
|
|
317
|
+
} else {
|
|
318
|
+
this.pendingMessages.push(data);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
destroy() {
|
|
322
|
+
if (this.port) {
|
|
323
|
+
this.port.postMessage(DESTROY_SIGNAL3);
|
|
324
|
+
this.port.close();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
signalDestroy() {
|
|
328
|
+
if (this.port) {
|
|
329
|
+
this.port.postMessage(DESTROY_SIGNAL3);
|
|
330
|
+
} else {
|
|
331
|
+
this.pendingMessages.push(DESTROY_SIGNAL3);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
120
336
|
// src/interface.ts
|
|
121
337
|
var import_node_buffer = require("buffer");
|
|
122
338
|
|
|
@@ -356,142 +572,10 @@ var RPCChannel = class {
|
|
|
356
572
|
this.callbackCache.clear();
|
|
357
573
|
}
|
|
358
574
|
};
|
|
359
|
-
|
|
360
|
-
// src/adapters/iframe.ts
|
|
361
|
-
var DESTROY_SIGNAL2 = "__DESTROY__";
|
|
362
|
-
var PORT_INIT_SIGNAL = "__PORT_INIT__";
|
|
363
|
-
var IframeParentIO = class {
|
|
364
|
-
/**
|
|
365
|
-
* @example
|
|
366
|
-
* ```ts
|
|
367
|
-
* const io = new IframeParentIO(iframeRef.contentWindow);
|
|
368
|
-
* const rpc = new RPCChannel(io, {
|
|
369
|
-
* expose: {
|
|
370
|
-
* add: (a: number, b: number) => Promise.resolve(a + b),
|
|
371
|
-
* },
|
|
372
|
-
* });
|
|
373
|
-
* ```
|
|
374
|
-
*/
|
|
375
|
-
constructor(targetWindow) {
|
|
376
|
-
this.targetWindow = targetWindow;
|
|
377
|
-
this.port = null;
|
|
378
|
-
window.addEventListener("message", (event) => {
|
|
379
|
-
if (event.source !== this.targetWindow) return;
|
|
380
|
-
if (event.data === PORT_INIT_SIGNAL && event.ports.length > 0) {
|
|
381
|
-
this.port = event.ports[0];
|
|
382
|
-
this.port.onmessage = this.handleMessage;
|
|
383
|
-
while (this.messageQueue.length > 0) {
|
|
384
|
-
const message = this.messageQueue.shift();
|
|
385
|
-
if (message) this.port.postMessage(message);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
name = "iframe-parent-io";
|
|
391
|
-
messageQueue = [];
|
|
392
|
-
resolveRead = null;
|
|
393
|
-
port = null;
|
|
394
|
-
handleMessage = (event) => {
|
|
395
|
-
const message = event.data;
|
|
396
|
-
if (message === DESTROY_SIGNAL2) {
|
|
397
|
-
this.destroy();
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
if (this.resolveRead) {
|
|
401
|
-
this.resolveRead(message);
|
|
402
|
-
this.resolveRead = null;
|
|
403
|
-
} else {
|
|
404
|
-
this.messageQueue.push(message);
|
|
405
|
-
}
|
|
406
|
-
};
|
|
407
|
-
async read() {
|
|
408
|
-
if (this.messageQueue.length > 0) {
|
|
409
|
-
return this.messageQueue.shift() ?? null;
|
|
410
|
-
}
|
|
411
|
-
return new Promise((resolve) => {
|
|
412
|
-
this.resolveRead = resolve;
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
async write(data) {
|
|
416
|
-
if (!this.port) {
|
|
417
|
-
this.messageQueue.push(data);
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
this.port.postMessage(data);
|
|
421
|
-
}
|
|
422
|
-
destroy() {
|
|
423
|
-
if (this.port) {
|
|
424
|
-
this.port.postMessage(DESTROY_SIGNAL2);
|
|
425
|
-
this.port.close();
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
signalDestroy() {
|
|
429
|
-
if (this.port) {
|
|
430
|
-
this.port.postMessage(DESTROY_SIGNAL2);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
var IframeChildIO = class {
|
|
435
|
-
name = "iframe-child-io";
|
|
436
|
-
messageQueue = [];
|
|
437
|
-
resolveRead = null;
|
|
438
|
-
port = null;
|
|
439
|
-
pendingMessages = [];
|
|
440
|
-
initialized;
|
|
441
|
-
channel;
|
|
442
|
-
constructor() {
|
|
443
|
-
this.channel = new MessageChannel();
|
|
444
|
-
this.port = this.channel.port1;
|
|
445
|
-
this.port.onmessage = this.handleMessage;
|
|
446
|
-
window.parent.postMessage(PORT_INIT_SIGNAL, "*", [this.channel.port2]);
|
|
447
|
-
this.initialized = Promise.resolve();
|
|
448
|
-
}
|
|
449
|
-
handleMessage = (event) => {
|
|
450
|
-
const message = event.data;
|
|
451
|
-
if (message === DESTROY_SIGNAL2) {
|
|
452
|
-
this.destroy();
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
if (this.resolveRead) {
|
|
456
|
-
this.resolveRead(message);
|
|
457
|
-
this.resolveRead = null;
|
|
458
|
-
} else {
|
|
459
|
-
this.messageQueue.push(message);
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
async read() {
|
|
463
|
-
await this.initialized;
|
|
464
|
-
if (this.messageQueue.length > 0) {
|
|
465
|
-
return this.messageQueue.shift() ?? null;
|
|
466
|
-
}
|
|
467
|
-
return new Promise((resolve) => {
|
|
468
|
-
this.resolveRead = resolve;
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
async write(data) {
|
|
472
|
-
await this.initialized;
|
|
473
|
-
if (this.port) {
|
|
474
|
-
this.port.postMessage(data);
|
|
475
|
-
} else {
|
|
476
|
-
this.pendingMessages.push(data);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
destroy() {
|
|
480
|
-
if (this.port) {
|
|
481
|
-
this.port.postMessage(DESTROY_SIGNAL2);
|
|
482
|
-
this.port.close();
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
signalDestroy() {
|
|
486
|
-
if (this.port) {
|
|
487
|
-
this.port.postMessage(DESTROY_SIGNAL2);
|
|
488
|
-
} else {
|
|
489
|
-
this.pendingMessages.push(DESTROY_SIGNAL2);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
};
|
|
493
575
|
// Annotate the CommonJS export names for ESM import in node:
|
|
494
576
|
0 && (module.exports = {
|
|
577
|
+
ChromeBackgroundIO,
|
|
578
|
+
ChromeContentIO,
|
|
495
579
|
IframeChildIO,
|
|
496
580
|
IframeParentIO,
|
|
497
581
|
RPCChannel,
|
package/dist/browser-mod.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as WorkerChildIO, W as WorkerParentIO } from './worker-ByZFWF48.cjs';
|
|
2
|
+
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.cjs';
|
|
2
3
|
import { D as DestroyableIoInterface } from './channel-CGr_xSbe.cjs';
|
|
3
4
|
export { I as IoInterface, R as RPCChannel } from './channel-CGr_xSbe.cjs';
|
|
4
5
|
import 'node:buffer';
|
package/dist/browser-mod.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as WorkerChildIO, W as WorkerParentIO } from './worker-sUTyf1YL.js';
|
|
2
|
+
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.js';
|
|
2
3
|
import { D as DestroyableIoInterface } from './channel-CGr_xSbe.js';
|
|
3
4
|
export { I as IoInterface, R as RPCChannel } from './channel-CGr_xSbe.js';
|
|
4
5
|
import 'node:buffer';
|
package/dist/browser-mod.js
CHANGED
|
@@ -2,6 +2,10 @@ import {
|
|
|
2
2
|
WorkerChildIO,
|
|
3
3
|
WorkerParentIO
|
|
4
4
|
} from "./chunk-XU7DWWSJ.js";
|
|
5
|
+
import {
|
|
6
|
+
ChromeBackgroundIO,
|
|
7
|
+
ChromeContentIO
|
|
8
|
+
} from "./chunk-INKNKSKA.js";
|
|
5
9
|
import {
|
|
6
10
|
RPCChannel,
|
|
7
11
|
deserializeMessage,
|
|
@@ -145,6 +149,8 @@ var IframeChildIO = class {
|
|
|
145
149
|
}
|
|
146
150
|
};
|
|
147
151
|
export {
|
|
152
|
+
ChromeBackgroundIO,
|
|
153
|
+
ChromeContentIO,
|
|
148
154
|
IframeChildIO,
|
|
149
155
|
IframeParentIO,
|
|
150
156
|
RPCChannel,
|