js-rpc2 2.3.0 → 2.3.1
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/package.json +1 -1
- package/src/lib.js +52 -14
- package/src/lib.test.js +5 -2
- package/src/server.js +16 -12
- package/src/types.ts +0 -5
package/package.json
CHANGED
package/src/lib.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Packr } from 'msgpackr'
|
2
2
|
|
3
3
|
/**
|
4
|
-
* @import { CALLBACK_ITEM,
|
4
|
+
* @import { CALLBACK_ITEM, RPC_DATA, RPC_DATA_ARG_ITEM } from "./types.js"
|
5
5
|
*/
|
6
6
|
|
7
7
|
const JS_RPC_WITH_CRYPTO = true
|
@@ -407,8 +407,7 @@ export function buildRpcItemData(items) {
|
|
407
407
|
}
|
408
408
|
|
409
409
|
/**
|
410
|
-
* @
|
411
|
-
* @param {ExtensionApi<T>} extension
|
410
|
+
* @param {object} extension
|
412
411
|
* @param {WritableStreamDefaultWriter<Uint8Array<ArrayBuffer>>} writer
|
413
412
|
* @param {Uint8Array<ArrayBuffer>} buffer
|
414
413
|
* @param {(msg:string)=>void} logger
|
@@ -501,13 +500,11 @@ export function createRPCProxy(apiInvoke) {
|
|
501
500
|
*/
|
502
501
|
|
503
502
|
/**
|
504
|
-
* @template T
|
505
503
|
* @param {{
|
506
504
|
* rpcKey: string;
|
507
|
-
* extension:
|
505
|
+
* extension: object;
|
508
506
|
* logger?: (msg:string)=>void;
|
509
507
|
* async?: boolean;
|
510
|
-
* context?:any;
|
511
508
|
* }} param
|
512
509
|
*/
|
513
510
|
export function createRpcServerHelper(param) {
|
@@ -517,8 +514,6 @@ export function createRpcServerHelper(param) {
|
|
517
514
|
let writer = encode.writable.getWriter()
|
518
515
|
decode.readable.pipeTo(new WritableStream({
|
519
516
|
async write(buffer) {
|
520
|
-
let asyncLocalStorage = param.extension.asyncLocalStorage
|
521
|
-
asyncLocalStorage?.enterWith(param.context)
|
522
517
|
if (param.async) {
|
523
518
|
rpcRunServerDecodeBuffer(param.extension, writer, buffer, param.logger).catch(console.error)
|
524
519
|
} else {
|
@@ -763,11 +758,55 @@ export function createRpcClientHttp(param) {
|
|
763
758
|
}
|
764
759
|
|
765
760
|
/**
|
766
|
-
* @
|
761
|
+
* @param {{
|
762
|
+
* url:string;
|
763
|
+
* rpcKey?:string;
|
764
|
+
* signal?:AbortSignal;
|
765
|
+
* intercept?:(res:Response)=>void;
|
766
|
+
* }} param
|
767
|
+
*/
|
768
|
+
export function _testCreateRpcClientHttp(param) {
|
769
|
+
let helper = createRpcClientHelper({ rpcKey: param.rpcKey })
|
770
|
+
let writer = helper.writable.getWriter()
|
771
|
+
helper.readable.pipeTo(new WritableStream({
|
772
|
+
write(chunk) {
|
773
|
+
fetch(param.url, {
|
774
|
+
method: 'POST',
|
775
|
+
signal: param.signal,
|
776
|
+
// @ts-ignore
|
777
|
+
duplex:'half',
|
778
|
+
body: new ReadableStream({
|
779
|
+
async pull(controller){
|
780
|
+
controller.enqueue(chunk.slice(0,10))
|
781
|
+
await sleep(1000)
|
782
|
+
controller.enqueue(chunk.slice(10))
|
783
|
+
controller.close()
|
784
|
+
}
|
785
|
+
}),
|
786
|
+
}).then(res => {
|
787
|
+
if (param.intercept) {
|
788
|
+
param.intercept(res)
|
789
|
+
}
|
790
|
+
res.body.pipeThrough(processPackets()).pipeTo(new WritableStream({
|
791
|
+
async write(chunk) {
|
792
|
+
await writer.write(chunk)
|
793
|
+
}
|
794
|
+
})).catch((e) => {
|
795
|
+
helper.reject(e)
|
796
|
+
})
|
797
|
+
}).catch(e => {
|
798
|
+
helper.reject(e)
|
799
|
+
})
|
800
|
+
}
|
801
|
+
})).catch((err) => helper.reject(err))
|
802
|
+
return createRPCProxy(helper.apiInvoke)
|
803
|
+
}
|
804
|
+
|
805
|
+
/**
|
767
806
|
* @param {{
|
768
807
|
* port:MessagePort;
|
769
808
|
* rpcKey:string;
|
770
|
-
* extension:
|
809
|
+
* extension: object;
|
771
810
|
* logger?:(msg:string)=>void;
|
772
811
|
* }} param
|
773
812
|
*/
|
@@ -789,11 +828,10 @@ export function createRpcServerMessagePort(param) {
|
|
789
828
|
|
790
829
|
/**
|
791
830
|
* @import {Electron} from './types.js'
|
792
|
-
* @template T
|
793
831
|
* @param {{
|
794
832
|
* port:Electron.MessagePortMain;
|
795
833
|
* rpcKey:string;
|
796
|
-
* extension:
|
834
|
+
* extension: object;
|
797
835
|
* logger?:(msg:string)=>void;
|
798
836
|
* }} param
|
799
837
|
*/
|
@@ -858,11 +896,10 @@ export function base64encode(buffer, urlsafe = false) {
|
|
858
896
|
|
859
897
|
/**
|
860
898
|
* @import {chrome as Chrome} from './types.js'
|
861
|
-
* @template T
|
862
899
|
* @param {{
|
863
900
|
* chrome:Chrome;
|
864
901
|
* key: string;
|
865
|
-
* extension:
|
902
|
+
* extension: {messageSender:Chrome.runtime.MessageSender;};
|
866
903
|
* logger?:(msg:string)=>void;
|
867
904
|
* }} param
|
868
905
|
*/
|
@@ -872,6 +909,7 @@ export function createRpcServerChromeExtensions(param) {
|
|
872
909
|
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
|
873
910
|
if (request.action === param.key) {
|
874
911
|
let tabId = sender.tab?.id
|
912
|
+
param.extension.messageSender = sender
|
875
913
|
let { keyServer, keyClient } = request.data
|
876
914
|
let helper = createRpcServerHelper({
|
877
915
|
rpcKey: '', extension: param.extension, async: true, logger: param.logger,
|
package/src/lib.test.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { test } from 'node:test'
|
2
2
|
import { deepStrictEqual, fail, ok, strictEqual } from 'node:assert'
|
3
|
-
import { createRpcClientHttp, createRpcClientWebSocket, sleep, Uint8Array_from } from './lib.js'
|
3
|
+
import { _testCreateRpcClientHttp, createRpcClientHttp, createRpcClientWebSocket, sleep, Uint8Array_from } from './lib.js'
|
4
4
|
import { createServer } from 'node:http'
|
5
5
|
import { WebSocketServer } from 'ws'
|
6
6
|
import Koa from 'koa'
|
@@ -292,6 +292,9 @@ test('测试RPC调用-KoaRouter-AsyncLocalStorage', async () => {
|
|
292
292
|
hello: async function (/** @type {string} */ name) {
|
293
293
|
let ctx = this.asyncLocalStorage.getStore()
|
294
294
|
strictEqual(ctx.path, '/abc')
|
295
|
+
await sleep(100)
|
296
|
+
ctx = this.asyncLocalStorage.getStore()
|
297
|
+
strictEqual(ctx.path, '/abc')
|
295
298
|
return `hello ${name}`
|
296
299
|
},
|
297
300
|
}
|
@@ -320,7 +323,7 @@ test('测试RPC调用-KoaRouter-AsyncLocalStorage', async () => {
|
|
320
323
|
await sleep(100)
|
321
324
|
|
322
325
|
/** @type{typeof extension} */
|
323
|
-
let client =
|
326
|
+
let client = _testCreateRpcClientHttp({
|
324
327
|
url: `http://127.0.0.1:9000/abc`,
|
325
328
|
rpcKey: 'abc',
|
326
329
|
signal: ac.signal,
|
package/src/server.js
CHANGED
@@ -3,8 +3,8 @@ import { createRpcServerHelper } from "./lib.js"
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks"
|
4
4
|
|
5
5
|
/**
|
6
|
+
* @import { IncomingMessage } from "node:http"
|
6
7
|
* @import {WebSocketServer} from 'ws'
|
7
|
-
* @import {ExtensionApi} from './types.js'
|
8
8
|
*/
|
9
9
|
|
10
10
|
export { createRpcServerHelper }
|
@@ -19,14 +19,13 @@ export { createRpcServerHelper }
|
|
19
19
|
* path: string;
|
20
20
|
* wss: WebSocketServer;
|
21
21
|
* rpcKey:string;
|
22
|
-
* extension:
|
22
|
+
* extension: {asyncLocalStorage:AsyncLocalStorage<IncomingMessage>;};
|
23
23
|
* logger?:(msg:string)=>void;
|
24
24
|
* }} param
|
25
25
|
*/
|
26
26
|
export function createRpcServerWebSocket(param) {
|
27
|
-
|
28
|
-
|
29
|
-
}
|
27
|
+
let asyncLocalStorage = param.extension.asyncLocalStorage
|
28
|
+
if (!asyncLocalStorage) { asyncLocalStorage = new AsyncLocalStorage() }
|
30
29
|
param.wss.on('connection', (ws, request) => {
|
31
30
|
let url = request.url
|
32
31
|
if (url != param.path) {
|
@@ -47,6 +46,7 @@ export function createRpcServerWebSocket(param) {
|
|
47
46
|
if (writer.desiredSize <= 0) {
|
48
47
|
ws.pause()
|
49
48
|
}
|
49
|
+
asyncLocalStorage.enterWith(request)
|
50
50
|
await writer.write(buffer)
|
51
51
|
ws.resume()
|
52
52
|
})
|
@@ -60,23 +60,27 @@ export function createRpcServerWebSocket(param) {
|
|
60
60
|
}
|
61
61
|
|
62
62
|
/**
|
63
|
-
* @template T
|
64
63
|
* @param {{
|
65
64
|
* path: string;
|
66
65
|
* router: Router<any, {}>;
|
67
66
|
* rpcKey?:string;
|
68
67
|
* logger?:(msg:string)=>void;
|
69
|
-
* extension:
|
68
|
+
* extension: {asyncLocalStorage:AsyncLocalStorage;};
|
70
69
|
* }} param
|
71
70
|
*/
|
72
71
|
export function createRpcServerKoaRouter(param) {
|
73
|
-
|
74
|
-
|
75
|
-
}
|
72
|
+
let asyncLocalStorage = param.extension.asyncLocalStorage
|
73
|
+
if (!asyncLocalStorage) { asyncLocalStorage = new AsyncLocalStorage() }
|
76
74
|
param.router.post(param.path, async (ctx) => {
|
77
|
-
|
75
|
+
asyncLocalStorage.enterWith(ctx)
|
76
|
+
let helper = createRpcServerHelper({ rpcKey: param.rpcKey, extension: param.extension, logger: param.logger })
|
78
77
|
let a = Readable.toWeb(ctx.req)
|
79
|
-
await a.
|
78
|
+
await a.pipeThrough(new TransformStream({
|
79
|
+
async transform(chunk, controller) {
|
80
|
+
asyncLocalStorage.enterWith(ctx)
|
81
|
+
controller.enqueue(chunk)
|
82
|
+
}
|
83
|
+
})).pipeTo(helper.writable)
|
80
84
|
ctx.status = 200
|
81
85
|
ctx.response.set({
|
82
86
|
'Connection': 'keep-alive',
|
package/src/types.ts
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
2
|
-
|
3
|
-
export type ExtensionApi<T> = { asyncLocalStorage?: AsyncLocalStorage<T> } & object;
|
4
|
-
|
5
|
-
|
6
1
|
export type RPC_TYPE_CALL = 0xdf68f4cb
|
7
2
|
export type RPC_TYPE_RETURN = 0x68b17581
|
8
3
|
export type RPC_TYPE_CALLBACK = 0x8d65e5cc
|