js-rpc2 1.0.1 → 1.0.3
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 +77 -48
- package/src/lib.test.js +19 -1
package/package.json
CHANGED
package/src/lib.js
CHANGED
@@ -86,10 +86,10 @@ export async function buildBufferData(queue, key, iv) {
|
|
86
86
|
}
|
87
87
|
|
88
88
|
/**
|
89
|
-
* @param {Uint8Array} buffer
|
89
|
+
* @param {Uint8Array<ArrayBuffer>} buffer
|
90
90
|
* @param {CryptoKey} key
|
91
91
|
* @param {Uint8Array} iv
|
92
|
-
* @returns {Promise<[Uint8Array[],Uint8Array]>}
|
92
|
+
* @returns {Promise<[Uint8Array[],Uint8Array<ArrayBuffer>]>}
|
93
93
|
*/
|
94
94
|
export async function parseBufferData(buffer, key, iv) {
|
95
95
|
/** @type{Uint8Array[]} */
|
@@ -120,6 +120,19 @@ export async function parseBufferData(buffer, key, iv) {
|
|
120
120
|
return [queue, remain]
|
121
121
|
}
|
122
122
|
|
123
|
+
export function processPackets() {
|
124
|
+
let last = new Uint8Array(0)
|
125
|
+
return new TransformStream({
|
126
|
+
async transform(chunk, controller) {
|
127
|
+
let [queueReceive, remain] = await parseBufferData(Uint8Array_concat([last, chunk]), null, null)
|
128
|
+
last = remain
|
129
|
+
if (queueReceive.length > 0) {
|
130
|
+
let buffer = await buildBufferData(queueReceive, null, null)
|
131
|
+
controller.enqueue(buffer)
|
132
|
+
}
|
133
|
+
}
|
134
|
+
})
|
135
|
+
}
|
123
136
|
|
124
137
|
/**
|
125
138
|
* @param {Uint8Array} buffer
|
@@ -360,26 +373,26 @@ export const RPC_TYPE_ERROR = 0xa07c0f84
|
|
360
373
|
*/
|
361
374
|
|
362
375
|
/**
|
363
|
-
* @typedef {{type:
|
376
|
+
* @typedef {{type:RPC_DATA_ARG_TYPE;data:object}} RPC_DATA_ARG_ITEM
|
364
377
|
* @typedef {{
|
365
378
|
* id:number;
|
366
379
|
* type:RPC_TYPES;
|
367
|
-
* data:{type:
|
380
|
+
* data:{type:RPC_DATA_ARG_TYPE;data:object}[];
|
368
381
|
* }} RPC_DATA
|
369
382
|
*/
|
370
383
|
|
371
|
-
export const
|
372
|
-
export const
|
373
|
-
export const
|
374
|
-
export const
|
375
|
-
export const
|
384
|
+
export const RPC_DATA_ARG_TYPE_OBJECT = 0xa7f68c
|
385
|
+
export const RPC_DATA_ARG_TYPE_FUNCTION = 0x7ff45f
|
386
|
+
export const RPC_DATA_ARG_TYPE_UINT8ARRAY = 0xedb218
|
387
|
+
export const RPC_DATA_ARG_TYPE_UNDEFINED = 0x7f77fe
|
388
|
+
export const RPC_DATA_ARG_TYPE_NULL = 0x5794f9
|
376
389
|
|
377
390
|
/**
|
378
|
-
* @typedef {
|
379
|
-
* |
|
380
|
-
* |
|
381
|
-
* |
|
382
|
-
* |
|
391
|
+
* @typedef {RPC_DATA_ARG_TYPE_OBJECT
|
392
|
+
* |RPC_DATA_ARG_TYPE_FUNCTION
|
393
|
+
* |RPC_DATA_ARG_TYPE_UINT8ARRAY
|
394
|
+
* |RPC_DATA_ARG_TYPE_UNDEFINED
|
395
|
+
* |RPC_DATA_ARG_TYPE_NULL} RPC_DATA_ARG_TYPE
|
383
396
|
*/
|
384
397
|
|
385
398
|
/**
|
@@ -392,23 +405,23 @@ export function buildRpcData(box) {
|
|
392
405
|
buildBufferNumberUInt32LE(box.data.length),
|
393
406
|
]
|
394
407
|
for (const o of box.data) {
|
395
|
-
if (o.type ==
|
408
|
+
if (o.type == RPC_DATA_ARG_TYPE_UINT8ARRAY) {
|
396
409
|
buffers.push(buildBufferNumberUInt32LE(o.type))
|
397
410
|
buffers.push(buildBufferNumberUInt32LE(o.data.length))
|
398
411
|
buffers.push(o.data)
|
399
412
|
}
|
400
|
-
if (o.type ==
|
413
|
+
if (o.type == RPC_DATA_ARG_TYPE_FUNCTION) {
|
401
414
|
buffers.push(buildBufferNumberUInt32LE(o.type))
|
402
415
|
buffers.push(buildBufferSizeString(o.data))
|
403
416
|
}
|
404
|
-
if (o.type ==
|
417
|
+
if (o.type == RPC_DATA_ARG_TYPE_OBJECT) {
|
405
418
|
buffers.push(buildBufferNumberUInt32LE(o.type))
|
406
419
|
buffers.push(buildBufferSizeString(JSON.stringify(o.data)))
|
407
420
|
}
|
408
|
-
if (o.type ==
|
421
|
+
if (o.type == RPC_DATA_ARG_TYPE_UNDEFINED) {
|
409
422
|
buffers.push(buildBufferNumberUInt32LE(o.type))
|
410
423
|
}
|
411
|
-
if (o.type ==
|
424
|
+
if (o.type == RPC_DATA_ARG_TYPE_NULL) {
|
412
425
|
buffers.push(buildBufferNumberUInt32LE(o.type))
|
413
426
|
}
|
414
427
|
}
|
@@ -432,28 +445,28 @@ export function parseRpcData(buffer) {
|
|
432
445
|
for (let i = 0; i < dataLength; i++) {
|
433
446
|
let type = readUInt32LE(buffer, offset)
|
434
447
|
offset += 4
|
435
|
-
if (type ==
|
448
|
+
if (type == RPC_DATA_ARG_TYPE_UINT8ARRAY) {
|
436
449
|
let size = readUInt32LE(buffer, offset)
|
437
450
|
offset += 4
|
438
451
|
let data = buffer.slice(offset, offset + size)
|
439
452
|
offset += size
|
440
453
|
args.push({ type: type, data })
|
441
454
|
}
|
442
|
-
if (type ==
|
455
|
+
if (type == RPC_DATA_ARG_TYPE_FUNCTION) {
|
443
456
|
let o = readBufferSizeString(buffer, offset)
|
444
457
|
offset += o.size
|
445
458
|
args.push({ type: type, data: o.string })
|
446
459
|
}
|
447
|
-
if (type ==
|
460
|
+
if (type == RPC_DATA_ARG_TYPE_OBJECT) {
|
448
461
|
let o = readBufferSizeString(buffer, offset)
|
449
462
|
offset += o.size
|
450
463
|
let data = o.string
|
451
464
|
args.push({ type: type, data: JSON.parse(data) })
|
452
465
|
}
|
453
|
-
if (type ==
|
466
|
+
if (type == RPC_DATA_ARG_TYPE_UNDEFINED) {
|
454
467
|
args.push({ type: type, data: undefined })
|
455
468
|
}
|
456
|
-
if (type ==
|
469
|
+
if (type == RPC_DATA_ARG_TYPE_NULL) {
|
457
470
|
args.push({ type: type, data: null })
|
458
471
|
}
|
459
472
|
}
|
@@ -469,23 +482,23 @@ export function buildRpcItemData(items) {
|
|
469
482
|
/** @type{RPC_DATA_ARG_ITEM[]} */
|
470
483
|
let arr = []
|
471
484
|
for (const item of items) {
|
472
|
-
/** @type{
|
485
|
+
/** @type{RPC_DATA_ARG_TYPE} */
|
473
486
|
let type = null
|
474
487
|
let data = null
|
475
488
|
if (item === undefined) {
|
476
|
-
type =
|
489
|
+
type = RPC_DATA_ARG_TYPE_UNDEFINED
|
477
490
|
data = item
|
478
491
|
} else if (item === null) {
|
479
|
-
type =
|
492
|
+
type = RPC_DATA_ARG_TYPE_NULL
|
480
493
|
data = item
|
481
494
|
} else if (item instanceof Uint8Array) {
|
482
|
-
type =
|
495
|
+
type = RPC_DATA_ARG_TYPE_UINT8ARRAY
|
483
496
|
data = item
|
484
497
|
} else if (typeof item == 'function') {
|
485
|
-
type =
|
498
|
+
type = RPC_DATA_ARG_TYPE_FUNCTION
|
486
499
|
data = item()
|
487
500
|
} else {
|
488
|
-
type =
|
501
|
+
type = RPC_DATA_ARG_TYPE_OBJECT
|
489
502
|
data = JSON.stringify(item)
|
490
503
|
}
|
491
504
|
arr.push({ type, data })
|
@@ -501,19 +514,19 @@ export function parseRpcItemData(array) {
|
|
501
514
|
let items = []
|
502
515
|
for (let i = 0; i < array.length; i++) {
|
503
516
|
const o = array[i]
|
504
|
-
if (o.type ==
|
517
|
+
if (o.type == RPC_DATA_ARG_TYPE_FUNCTION) {
|
505
518
|
o.data = o.data
|
506
519
|
}
|
507
|
-
if (o.type ==
|
520
|
+
if (o.type == RPC_DATA_ARG_TYPE_NULL) {
|
508
521
|
o.data = null
|
509
522
|
}
|
510
|
-
if (o.type ==
|
523
|
+
if (o.type == RPC_DATA_ARG_TYPE_UNDEFINED) {
|
511
524
|
o.data = undefined
|
512
525
|
}
|
513
|
-
if (o.type ==
|
526
|
+
if (o.type == RPC_DATA_ARG_TYPE_UINT8ARRAY) {
|
514
527
|
o.data = o.data
|
515
528
|
}
|
516
|
-
if (o.type ==
|
529
|
+
if (o.type == RPC_DATA_ARG_TYPE_OBJECT) {
|
517
530
|
o.data = JSON.parse(o.data)
|
518
531
|
}
|
519
532
|
items.push(o)
|
@@ -539,7 +552,7 @@ export async function rpcRunServerDecodeBuffer(extension, writer, buffer) {
|
|
539
552
|
let params = []
|
540
553
|
for (let i = 0; i < args.length; i++) {
|
541
554
|
const p = args[i]
|
542
|
-
if (p.type ==
|
555
|
+
if (p.type == RPC_DATA_ARG_TYPE_FUNCTION) {
|
543
556
|
const callback = async (/** @type {any[]} */ ...args) => {
|
544
557
|
/** @type{RPC_DATA} */
|
545
558
|
let box = { id: p.data, type: RPC_TYPE_CALLBACK, data: buildRpcItemData(args), }
|
@@ -627,6 +640,7 @@ export function createRpcServerHelper(param) {
|
|
627
640
|
* writable: WritableStream<Uint8Array>;
|
628
641
|
* readable: ReadableStream<Uint8Array>;
|
629
642
|
* apiInvoke: (fnName: string, args: object[]) => Promise<object>;
|
643
|
+
* reject: (error:object)=>void;
|
630
644
|
* }} RPC_HELPER_CLIENT
|
631
645
|
*/
|
632
646
|
|
@@ -710,8 +724,18 @@ export function createRpcClientHelper(param) {
|
|
710
724
|
}
|
711
725
|
}
|
712
726
|
|
727
|
+
/**
|
728
|
+
* @param {object} error
|
729
|
+
*/
|
730
|
+
function reject(error) {
|
731
|
+
callbackFunctionMap.forEach((o) => {
|
732
|
+
o.promise?.reject(error)
|
733
|
+
})
|
734
|
+
callbackFunctionMap.clear()
|
735
|
+
}
|
736
|
+
|
713
737
|
/** @type{RPC_HELPER_CLIENT} */
|
714
|
-
let ret = { writable: decode.writable, readable: encode.readable, apiInvoke }
|
738
|
+
let ret = { writable: decode.writable, readable: encode.readable, apiInvoke, reject }
|
715
739
|
return ret
|
716
740
|
}
|
717
741
|
|
@@ -790,21 +814,26 @@ export function createRpcClientHttp(param) {
|
|
790
814
|
let helper = createRpcClientHelper({ rpcKey: param.rpcKey })
|
791
815
|
let writer = helper.writable.getWriter()
|
792
816
|
helper.readable.pipeTo(new WritableStream({
|
793
|
-
|
794
|
-
|
817
|
+
write(chunk) {
|
818
|
+
fetch(param.url, {
|
795
819
|
method: 'POST',
|
796
820
|
signal: param.signal,
|
797
821
|
body: chunk,
|
798
|
-
})
|
799
|
-
|
800
|
-
|
801
|
-
}
|
802
|
-
res.body.pipeTo(new WritableStream({
|
803
|
-
async write(chunk) {
|
804
|
-
await writer.write(chunk)
|
822
|
+
}).then(res => {
|
823
|
+
if (param.intercept) {
|
824
|
+
param.intercept(res)
|
805
825
|
}
|
806
|
-
|
826
|
+
res.body.pipeThrough(processPackets()).pipeTo(new WritableStream({
|
827
|
+
async write(chunk) {
|
828
|
+
await writer.write(chunk)
|
829
|
+
}
|
830
|
+
})).catch((e) => {
|
831
|
+
helper.reject(e)
|
832
|
+
})
|
833
|
+
}).catch(e => {
|
834
|
+
helper.reject(e)
|
835
|
+
})
|
807
836
|
}
|
808
|
-
})).catch((err) =>
|
837
|
+
})).catch((err) => helper.reject(err))
|
809
838
|
return createRPCProxy(helper.apiInvoke)
|
810
839
|
}
|
package/src/lib.test.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { test } from 'node:test'
|
2
|
-
import { deepStrictEqual, strictEqual } from 'node:assert'
|
2
|
+
import { deepStrictEqual, ok, strictEqual } from 'node:assert'
|
3
3
|
import { createRpcClientHttp, createRpcClientWebSocket, sleep, Uint8Array_from } from './lib.js'
|
4
4
|
import { createServer } from 'node:http'
|
5
5
|
import { WebSocketServer } from 'ws'
|
@@ -193,6 +193,10 @@ test('测试RPC调用-KoaRouter', async () => {
|
|
193
193
|
},
|
194
194
|
void: async function (/** @type {string} */ name,/** @type {Uint8Array} */ buffer) {
|
195
195
|
console.info('call void')
|
196
|
+
},
|
197
|
+
longTimeBlock: async function () {
|
198
|
+
await sleep(1000)
|
199
|
+
return 'finished'
|
196
200
|
}
|
197
201
|
}
|
198
202
|
|
@@ -251,6 +255,20 @@ test('测试RPC调用-KoaRouter', async () => {
|
|
251
255
|
|
252
256
|
let retvoid = await client.void('asdfghjkl', buffer)
|
253
257
|
strictEqual(retvoid, undefined)
|
258
|
+
|
259
|
+
let startTime = performance.now()
|
260
|
+
let [time1, time2] = await Promise.all([
|
261
|
+
client.longTimeBlock().then(v => {
|
262
|
+
console.info('longTimeBlock', v)
|
263
|
+
return performance.now() - startTime
|
264
|
+
}),
|
265
|
+
client.hello('欣瑶').then(v => {
|
266
|
+
console.info('hello', v)
|
267
|
+
return performance.now() - startTime
|
268
|
+
})
|
269
|
+
])
|
270
|
+
ok(time1 > 1000, `time1:${time1}`)
|
271
|
+
ok(time2 < 10, `time2:${time2}`)
|
254
272
|
})
|
255
273
|
console.info('over!')
|
256
274
|
})
|