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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-rpc2",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "js web websocket http rpc",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/lib.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Packr } from 'msgpackr'
2
2
 
3
3
  /**
4
- * @import { CALLBACK_ITEM, ExtensionApi, RPC_DATA, RPC_DATA_ARG_ITEM } from "./types.js"
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
- * @template T
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: ExtensionApi<T>;
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
- * @template T
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: ExtensionApi<T>;
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: ExtensionApi<T>;
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: ExtensionApi<T>
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 = createRpcClientHttp({
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: ExtensionApi<T>;
22
+ * extension: {asyncLocalStorage:AsyncLocalStorage<IncomingMessage>;};
23
23
  * logger?:(msg:string)=>void;
24
24
  * }} param
25
25
  */
26
26
  export function createRpcServerWebSocket(param) {
27
- if (!param.extension.asyncLocalStorage) {
28
- param.extension.asyncLocalStorage = new AsyncLocalStorage()
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: ExtensionApi<T>;
68
+ * extension: {asyncLocalStorage:AsyncLocalStorage;};
70
69
  * }} param
71
70
  */
72
71
  export function createRpcServerKoaRouter(param) {
73
- if (!param.extension.asyncLocalStorage) {
74
- param.extension.asyncLocalStorage = new AsyncLocalStorage()
75
- }
72
+ let asyncLocalStorage = param.extension.asyncLocalStorage
73
+ if (!asyncLocalStorage) { asyncLocalStorage = new AsyncLocalStorage() }
76
74
  param.router.post(param.path, async (ctx) => {
77
- let helper = createRpcServerHelper({ rpcKey: param.rpcKey, extension: param.extension, logger: param.logger, context: ctx })
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.pipeTo(helper.writable)
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