js-rpc2 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/package.json +5 -5
- package/src/lib.js +95 -24
- package/src/server.js +0 -1
- package/src/types.ts +43 -1
package/README.md
CHANGED
@@ -312,4 +312,47 @@ export async function runWithAbortController(func) {
|
|
312
312
|
await sleep(1000)
|
313
313
|
} finally { ac.abort() }
|
314
314
|
}
|
315
|
+
```
|
316
|
+
|
317
|
+
## Electron
|
318
|
+
```js
|
319
|
+
// main.js
|
320
|
+
class AppApi {
|
321
|
+
asyncLocalStorage = new AsyncLocalStorage()
|
322
|
+
|
323
|
+
async hello(param) {
|
324
|
+
return 'wertyuioiuytre ' + param
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
import { ipcMain } from 'electron'
|
329
|
+
import { createRpcServerElectronMessagePort } from 'js-rpc2/src/lib.js'
|
330
|
+
|
331
|
+
ipcMain.on('port', (event) => {
|
332
|
+
const port = event.ports[0]
|
333
|
+
createRpcServerElectronMessagePort({ port, rpcKey: '', extension: new AppApi() })
|
334
|
+
port.start()
|
335
|
+
})
|
336
|
+
|
337
|
+
// preload.js
|
338
|
+
import { ipcRenderer } from 'electron/renderer'
|
339
|
+
|
340
|
+
window.onmessage = (/** @type {MessageEvent} */ event) => {
|
341
|
+
if (event.origin == location.origin && event.data != 'port') {
|
342
|
+
ipcRenderer.postMessage('port', null, [event.ports[0]])
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
// renderer.js
|
347
|
+
import { createRpcClientMessagePort } from 'js-rpc2/src/lib.js'
|
348
|
+
|
349
|
+
const channel = new MessageChannel();
|
350
|
+
window.postMessage("port", location.origin, [channel.port1]);
|
351
|
+
let rpc = createRpcClientMessagePort({ port: channel.port2, rpcKey: "" });
|
352
|
+
|
353
|
+
// uasge.js
|
354
|
+
async function postPortMessage() {
|
355
|
+
let ret = await rpc.hello('6667');
|
356
|
+
console.info("ret from rpc:", ret);
|
357
|
+
}
|
315
358
|
```
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "js-rpc2",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.2.0",
|
4
4
|
"description": "js web websocket http rpc",
|
5
5
|
"main": "index.js",
|
6
6
|
"type": "module",
|
@@ -26,10 +26,10 @@
|
|
26
26
|
"author": "yuanliwei",
|
27
27
|
"license": "MIT",
|
28
28
|
"devDependencies": {
|
29
|
-
"@koa/router": "^
|
30
|
-
"@types/node": "^
|
31
|
-
"koa": "^
|
32
|
-
"ws": "^8.18.
|
29
|
+
"@koa/router": "^14.0.0",
|
30
|
+
"@types/node": "^24.2.1",
|
31
|
+
"koa": "^3.0.1",
|
32
|
+
"ws": "^8.18.3"
|
33
33
|
},
|
34
34
|
"dependencies": {
|
35
35
|
"msgpackr": "^1.11.5"
|
package/src/lib.js
CHANGED
@@ -23,8 +23,8 @@ export function Promise_withResolvers() {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
/**
|
26
|
-
* @param {Promise<[CryptoKey,Uint8Array]>} key_iv
|
27
|
-
* @returns {TransformStream<Uint8Array
|
26
|
+
* @param {Promise<[CryptoKey,Uint8Array<ArrayBuffer>]>} key_iv
|
27
|
+
* @returns {TransformStream<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>}
|
28
28
|
*/
|
29
29
|
export function createEncodeStream(key_iv) {
|
30
30
|
let key = null
|
@@ -41,8 +41,8 @@ export function createEncodeStream(key_iv) {
|
|
41
41
|
}
|
42
42
|
|
43
43
|
/**
|
44
|
-
* @param {Promise<[CryptoKey,Uint8Array]>} key_iv
|
45
|
-
* @returns {TransformStream<Uint8Array
|
44
|
+
* @param {Promise<[CryptoKey,Uint8Array<ArrayBuffer>]>} key_iv
|
45
|
+
* @returns {TransformStream<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>}
|
46
46
|
*/
|
47
47
|
export function createDecodeStream(key_iv) {
|
48
48
|
let key = null
|
@@ -65,10 +65,10 @@ export function createDecodeStream(key_iv) {
|
|
65
65
|
const HEADER_CHECK = 0xb1f7705f
|
66
66
|
|
67
67
|
/**
|
68
|
-
* @param {Uint8Array[]} queue
|
68
|
+
* @param {Uint8Array<ArrayBuffer>[]} queue
|
69
69
|
* @param {CryptoKey} key
|
70
|
-
* @param {Uint8Array} iv
|
71
|
-
* @returns {Promise<Uint8Array
|
70
|
+
* @param {Uint8Array<ArrayBuffer>} iv
|
71
|
+
* @returns {Promise<Uint8Array<ArrayBuffer>>}
|
72
72
|
*/
|
73
73
|
export async function buildBufferData(queue, key, iv) {
|
74
74
|
let buffers = []
|
@@ -134,7 +134,7 @@ export function processPackets() {
|
|
134
134
|
}
|
135
135
|
|
136
136
|
/**
|
137
|
-
* @param {Uint8Array} buffer
|
137
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
138
138
|
* @param {number} offset
|
139
139
|
*/
|
140
140
|
export function readUInt32LE(buffer, offset) {
|
@@ -146,7 +146,7 @@ export function readUInt32LE(buffer, offset) {
|
|
146
146
|
}
|
147
147
|
|
148
148
|
/**
|
149
|
-
* @param {Uint8Array} buffer
|
149
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
150
150
|
* @param {number} value
|
151
151
|
* @param {number} offset
|
152
152
|
*/
|
@@ -159,7 +159,7 @@ export function writeUInt32LE(buffer, value, offset) {
|
|
159
159
|
}
|
160
160
|
|
161
161
|
/**
|
162
|
-
* @param {Uint8Array[]} buffers
|
162
|
+
* @param {Uint8Array<ArrayBuffer>[]} buffers
|
163
163
|
*/
|
164
164
|
export function Uint8Array_concat(buffers) {
|
165
165
|
const totalLength = buffers.reduce((sum, buffer) => sum + buffer.length, 0)
|
@@ -196,7 +196,7 @@ export function Uint8Array_from(array, encoding) {
|
|
196
196
|
}
|
197
197
|
|
198
198
|
/**
|
199
|
-
* @param {Uint8Array} buffer
|
199
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
200
200
|
* @param {'utf-8' | 'hex' | 'base64'} [encoding]
|
201
201
|
*/
|
202
202
|
export function Uint8Array_toString(buffer, encoding = 'utf-8') {
|
@@ -231,7 +231,7 @@ function buildBufferSizeString(string) {
|
|
231
231
|
}
|
232
232
|
|
233
233
|
/**
|
234
|
-
* @param {Uint8Array} buffer
|
234
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
235
235
|
* @param {number} offset
|
236
236
|
*/
|
237
237
|
function readBufferSizeString(buffer, offset) {
|
@@ -258,7 +258,7 @@ export function guid() {
|
|
258
258
|
*
|
259
259
|
* @param {string} password
|
260
260
|
* @param {number} iterations
|
261
|
-
* @returns {Promise<[CryptoKey,Uint8Array]>}
|
261
|
+
* @returns {Promise<[CryptoKey,Uint8Array<ArrayBuffer>]>}
|
262
262
|
*/
|
263
263
|
export async function buildKeyIv(password, iterations) {
|
264
264
|
if (!JS_RPC_WITH_CRYPTO) return [null, null]
|
@@ -294,9 +294,9 @@ export async function buildKeyIv(password, iterations) {
|
|
294
294
|
|
295
295
|
/**
|
296
296
|
*
|
297
|
-
* @param {Uint8Array} data
|
297
|
+
* @param {Uint8Array<ArrayBuffer>} data
|
298
298
|
* @param {CryptoKey} key
|
299
|
-
* @param {Uint8Array} iv
|
299
|
+
* @param {Uint8Array<ArrayBuffer>} iv
|
300
300
|
* @returns
|
301
301
|
*/
|
302
302
|
export async function encrypt(data, key, iv) {
|
@@ -311,7 +311,7 @@ export async function encrypt(data, key, iv) {
|
|
311
311
|
/**
|
312
312
|
* @param {Uint8Array<ArrayBuffer>} data
|
313
313
|
* @param {CryptoKey} key
|
314
|
-
* @param {Uint8Array} iv
|
314
|
+
* @param {Uint8Array<ArrayBuffer>} iv
|
315
315
|
* @returns
|
316
316
|
*/
|
317
317
|
export async function decrypt(data, key, iv) {
|
@@ -373,7 +373,7 @@ export function buildRpcData(box) {
|
|
373
373
|
}
|
374
374
|
|
375
375
|
/**
|
376
|
-
* @param {Uint8Array} buffer
|
376
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
377
377
|
*/
|
378
378
|
export function parseRpcData(buffer) {
|
379
379
|
let [id, type, data] = packr.unpack(buffer)
|
@@ -409,8 +409,8 @@ export function buildRpcItemData(items) {
|
|
409
409
|
/**
|
410
410
|
* @template T
|
411
411
|
* @param {ExtensionApi<T>} extension
|
412
|
-
* @param {WritableStreamDefaultWriter<Uint8Array
|
413
|
-
* @param {Uint8Array} buffer
|
412
|
+
* @param {WritableStreamDefaultWriter<Uint8Array<ArrayBuffer>>} writer
|
413
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
414
414
|
* @param {(msg:string)=>void} logger
|
415
415
|
*/
|
416
416
|
export async function rpcRunServerDecodeBuffer(extension, writer, buffer, logger) {
|
@@ -495,8 +495,8 @@ export function createRPCProxy(apiInvoke) {
|
|
495
495
|
|
496
496
|
/**
|
497
497
|
* @typedef {{
|
498
|
-
* writable: WritableStream<Uint8Array
|
499
|
-
* readable: ReadableStream<Uint8Array
|
498
|
+
* writable: WritableStream<Uint8Array<ArrayBuffer>>;
|
499
|
+
* readable: ReadableStream<Uint8Array<ArrayBuffer>>;
|
500
500
|
* }} RPC_HELPER_SERVER
|
501
501
|
*/
|
502
502
|
|
@@ -537,8 +537,8 @@ export function createRpcServerHelper(param) {
|
|
537
537
|
|
538
538
|
/**
|
539
539
|
* @typedef {{
|
540
|
-
* writable: WritableStream<Uint8Array
|
541
|
-
* readable: ReadableStream<Uint8Array
|
540
|
+
* writable: WritableStream<Uint8Array<ArrayBuffer>>;
|
541
|
+
* readable: ReadableStream<Uint8Array<ArrayBuffer>>;
|
542
542
|
* apiInvoke: (fnName: string, args: object[]) => Promise<object>;
|
543
543
|
* reject: (error:object)=>void;
|
544
544
|
* }} RPC_HELPER_CLIENT
|
@@ -671,7 +671,7 @@ export function createRpcClientWebSocket(param) {
|
|
671
671
|
let helper = createRpcClientHelper({ rpcKey: param.rpcKey })
|
672
672
|
let writer = helper.writable.getWriter()
|
673
673
|
let signal = Promise_withResolvers()
|
674
|
-
/** @type{WritableStreamDefaultWriter<Uint8Array
|
674
|
+
/** @type{WritableStreamDefaultWriter<Uint8Array<ArrayBuffer>>} */
|
675
675
|
let socketWriter = null
|
676
676
|
helper.readable.pipeTo(new WritableStream({
|
677
677
|
async write(chunk) {
|
@@ -761,3 +761,74 @@ export function createRpcClientHttp(param) {
|
|
761
761
|
})).catch((err) => helper.reject(err))
|
762
762
|
return createRPCProxy(helper.apiInvoke)
|
763
763
|
}
|
764
|
+
|
765
|
+
/**
|
766
|
+
* @template T
|
767
|
+
* @param {{
|
768
|
+
* port:MessagePort;
|
769
|
+
* rpcKey:string;
|
770
|
+
* extension: ExtensionApi<T>;
|
771
|
+
* logger?:(msg:string)=>void;
|
772
|
+
* }} param
|
773
|
+
*/
|
774
|
+
export function createRpcServerMessagePort(param) {
|
775
|
+
const port = param.port
|
776
|
+
let helper = createRpcServerHelper({
|
777
|
+
rpcKey: '', extension: param.extension, async: true, logger: param.logger,
|
778
|
+
})
|
779
|
+
let writer = helper.writable.getWriter()
|
780
|
+
port.onmessage = async (event) => {
|
781
|
+
await writer.write(event.data)
|
782
|
+
}
|
783
|
+
helper.readable.pipeTo(new WritableStream({
|
784
|
+
async write(chunk) {
|
785
|
+
port.postMessage(chunk)
|
786
|
+
}
|
787
|
+
}))
|
788
|
+
}
|
789
|
+
|
790
|
+
/**
|
791
|
+
* @import {Electron} from './types.js'
|
792
|
+
* @template T
|
793
|
+
* @param {{
|
794
|
+
* port:Electron.MessagePortMain;
|
795
|
+
* rpcKey:string;
|
796
|
+
* extension: ExtensionApi<T>;
|
797
|
+
* logger?:(msg:string)=>void;
|
798
|
+
* }} param
|
799
|
+
*/
|
800
|
+
export function createRpcServerElectronMessagePort(param) {
|
801
|
+
const port = param.port
|
802
|
+
let helper = createRpcServerHelper({
|
803
|
+
rpcKey: '', extension: param.extension, async: true, logger: param.logger,
|
804
|
+
})
|
805
|
+
let writer = helper.writable.getWriter()
|
806
|
+
port.on('message', async (event) => {
|
807
|
+
await writer.write(event.data)
|
808
|
+
})
|
809
|
+
helper.readable.pipeTo(new WritableStream({
|
810
|
+
async write(chunk) {
|
811
|
+
port.postMessage(chunk)
|
812
|
+
}
|
813
|
+
}))
|
814
|
+
}
|
815
|
+
|
816
|
+
/**
|
817
|
+
* @param {{
|
818
|
+
* port:MessagePort;
|
819
|
+
* rpcKey:string;
|
820
|
+
* }} param
|
821
|
+
*/
|
822
|
+
export function createRpcClientMessagePort(param) {
|
823
|
+
let helper = createRpcClientHelper({ rpcKey: param.rpcKey })
|
824
|
+
let writer = helper.writable.getWriter()
|
825
|
+
helper.readable.pipeTo(new WritableStream({
|
826
|
+
async write(chunk) {
|
827
|
+
param.port.postMessage(chunk)
|
828
|
+
}
|
829
|
+
}))
|
830
|
+
param.port.onmessage = async (event) => {
|
831
|
+
await writer.write(event.data)
|
832
|
+
}
|
833
|
+
return createRPCProxy(helper.apiInvoke)
|
834
|
+
}
|
package/src/server.js
CHANGED
@@ -75,7 +75,6 @@ export function createRpcServerKoaRouter(param) {
|
|
75
75
|
}
|
76
76
|
param.router.post(param.path, async (ctx) => {
|
77
77
|
let helper = createRpcServerHelper({ rpcKey: param.rpcKey, extension: param.extension, logger: param.logger, context: ctx })
|
78
|
-
/** @type{ReadableStream} */
|
79
78
|
let a = Readable.toWeb(ctx.req)
|
80
79
|
await a.pipeTo(helper.writable)
|
81
80
|
ctx.status = 200
|
package/src/types.ts
CHANGED
@@ -46,4 +46,46 @@ export type RPC_DATA = {
|
|
46
46
|
data: { message: string, stack: string };
|
47
47
|
};
|
48
48
|
|
49
|
-
export type RPC_DATA_ARG_TYPE = RPC_DATA_ARG_TYPE_OTHERS | RPC_DATA_ARG_TYPE_FUNCTION;
|
49
|
+
export type RPC_DATA_ARG_TYPE = RPC_DATA_ARG_TYPE_OTHERS | RPC_DATA_ARG_TYPE_FUNCTION;
|
50
|
+
|
51
|
+
export declare namespace Electron {
|
52
|
+
|
53
|
+
const NodeEventEmitter: typeof import('events').EventEmitter;
|
54
|
+
|
55
|
+
class MessagePortMain extends NodeEventEmitter {
|
56
|
+
|
57
|
+
// Docs: https://electronjs.org/docs/api/message-port-main
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Emitted when the remote end of a MessagePortMain object becomes disconnected.
|
61
|
+
*/
|
62
|
+
on(event: 'close', listener: () => void): this;
|
63
|
+
off(event: 'close', listener: () => void): this;
|
64
|
+
once(event: 'close', listener: () => void): this;
|
65
|
+
addListener(event: 'close', listener: () => void): this;
|
66
|
+
removeListener(event: 'close', listener: () => void): this;
|
67
|
+
/**
|
68
|
+
* Emitted when a MessagePortMain object receives a message.
|
69
|
+
*/
|
70
|
+
on(event: 'message', listener: (messageEvent: MessageEvent) => void): this;
|
71
|
+
off(event: 'message', listener: (messageEvent: MessageEvent) => void): this;
|
72
|
+
once(event: 'message', listener: (messageEvent: MessageEvent) => void): this;
|
73
|
+
addListener(event: 'message', listener: (messageEvent: MessageEvent) => void): this;
|
74
|
+
removeListener(event: 'message', listener: (messageEvent: MessageEvent) => void): this;
|
75
|
+
/**
|
76
|
+
* Disconnects the port, so it is no longer active.
|
77
|
+
*/
|
78
|
+
close(): void;
|
79
|
+
/**
|
80
|
+
* Sends a message from the port, and optionally, transfers ownership of objects to
|
81
|
+
* other browsing contexts.
|
82
|
+
*/
|
83
|
+
postMessage(message: any, transfer?: MessagePortMain[]): void;
|
84
|
+
/**
|
85
|
+
* Starts the sending of messages queued on the port. Messages will be queued until
|
86
|
+
* this method is called.
|
87
|
+
*/
|
88
|
+
start(): void;
|
89
|
+
}
|
90
|
+
|
91
|
+
}
|