dolphindb 2.0.504 → 2.0.505
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/browser.d.ts +58 -35
- package/browser.js +113 -77
- package/browser.js.map +1 -1
- package/index.d.ts +48 -27
- package/index.js +95 -71
- package/index.js.map +1 -1
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -78,11 +78,10 @@ export interface DdbArrayVectorBlock {
|
|
|
78
78
|
lengths: Uint8Array | Uint16Array | Uint32Array;
|
|
79
79
|
data: DdbVectorValue;
|
|
80
80
|
}
|
|
81
|
-
export declare type DdbValue = null | boolean | number | [number, number] | bigint | string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
|
|
82
|
-
export declare type DdbVectorValue = string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
|
|
81
|
+
export declare type DdbValue = null | boolean | number | [number, number] | bigint | string | string[] | Uint8Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
|
|
82
|
+
export declare type DdbVectorValue = string | string[] | Uint8Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
|
|
83
83
|
export declare const nulls: {
|
|
84
|
-
readonly
|
|
85
|
-
readonly char: "";
|
|
84
|
+
readonly int8: -128;
|
|
86
85
|
readonly int16: -32768;
|
|
87
86
|
readonly int32: -2147483648;
|
|
88
87
|
readonly int64: -9223372036854775808n;
|
|
@@ -128,6 +127,8 @@ export declare class DdbObj<T extends DdbValue = DdbValue> {
|
|
|
128
127
|
datatype?: DdbType;
|
|
129
128
|
/** 实际数据。不同的 DdbForm, DdbType 使用 DdbValue 中不同的类型来表示实际数据 */
|
|
130
129
|
value: T;
|
|
130
|
+
/** 原始二进制数据 */
|
|
131
|
+
buffer?: Uint8Array;
|
|
131
132
|
constructor(data: Partial<DdbObj> & {
|
|
132
133
|
form: DdbForm;
|
|
133
134
|
type: DdbType;
|
|
@@ -157,7 +158,7 @@ export declare class DdbBool extends DdbObj<boolean> {
|
|
|
157
158
|
constructor(value: boolean | null);
|
|
158
159
|
}
|
|
159
160
|
export declare class DdbChar extends DdbObj<string> {
|
|
160
|
-
constructor(value: string | null);
|
|
161
|
+
constructor(value: string | number | null);
|
|
161
162
|
}
|
|
162
163
|
export declare class DdbInt extends DdbObj<number> {
|
|
163
164
|
constructor(value: number | null);
|
|
@@ -269,13 +270,13 @@ export declare class DDB {
|
|
|
269
270
|
password: string;
|
|
270
271
|
/** python session flag (2048) */
|
|
271
272
|
python: boolean;
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
|
|
273
|
+
parse_object: boolean;
|
|
274
|
+
/** message handler */
|
|
275
|
+
on_message({ type, data }: DdbMessage, _this: DDB): void;
|
|
275
276
|
/** resolver, rejector, promise of last rpc */
|
|
276
|
-
presolver(
|
|
277
|
+
presolver(message: DdbMessage): void;
|
|
277
278
|
prejector(error: Error): void;
|
|
278
|
-
presult: Promise<
|
|
279
|
+
presult: Promise<DdbMessage>;
|
|
279
280
|
get connected(): boolean;
|
|
280
281
|
/**
|
|
281
282
|
Initialize an instance of DolphinDB Client using the WebSocket URL
|
|
@@ -348,22 +349,31 @@ export declare class DDB {
|
|
|
348
349
|
- options:
|
|
349
350
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
350
351
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
352
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
353
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
354
|
+
不做解析,以便后续转发、序列化
|
|
351
355
|
*/
|
|
352
|
-
rpc<T extends DdbObj = DdbObj>(type: 'script' | 'function' | 'variable' | 'connect', { script, func, args, vars, urgent, }: {
|
|
356
|
+
rpc<T extends DdbObj = DdbObj>(type: 'script' | 'function' | 'variable' | 'connect', { script, func, args, vars, urgent, on_message, parse_object, }: {
|
|
353
357
|
script?: string;
|
|
354
358
|
func?: string;
|
|
355
359
|
args?: (DdbObj | string | boolean)[];
|
|
356
360
|
vars?: string[];
|
|
357
361
|
urgent?: boolean;
|
|
362
|
+
on_message?: DDB['on_message'];
|
|
363
|
+
parse_object?: boolean;
|
|
358
364
|
}): Promise<T>;
|
|
359
|
-
/** eval script through websocket (script command)
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
365
|
+
/** eval script through websocket (script command)
|
|
366
|
+
- script?: 执行的脚本
|
|
367
|
+
- options?: 执行选项
|
|
368
|
+
- urgent?: 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞
|
|
369
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
370
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
371
|
+
不做解析,以便后续转发、序列化
|
|
372
|
+
*/
|
|
373
|
+
eval<T extends DdbObj>(script: string, { urgent, on_message, parse_object, }?: {
|
|
366
374
|
urgent?: boolean;
|
|
375
|
+
on_message?: DDB['on_message'];
|
|
376
|
+
parse_object?: boolean;
|
|
367
377
|
}): Promise<T>;
|
|
368
378
|
/** call function through websocket (function command)
|
|
369
379
|
- func: 函数名
|
|
@@ -374,31 +384,42 @@ export declare class DDB {
|
|
|
374
384
|
- nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
|
|
375
385
|
- func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
|
|
376
386
|
- add_node_alias?: 设置 nodes 参数时选传,其它情况不传
|
|
387
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
388
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
389
|
+
不做解析,以便后续转发、序列化
|
|
377
390
|
*/
|
|
378
|
-
call<T extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias }?: {
|
|
391
|
+
call<T extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias, on_message, parse_object, }?: {
|
|
379
392
|
urgent?: boolean;
|
|
380
393
|
node?: string;
|
|
381
394
|
nodes?: string[];
|
|
382
395
|
func_type?: DdbFunctionType;
|
|
383
396
|
add_node_alias?: boolean;
|
|
397
|
+
on_message?: DDB['on_message'];
|
|
398
|
+
parse_object?: boolean;
|
|
384
399
|
}): Promise<T>;
|
|
385
400
|
/** upload variable through websocket (variable command) */
|
|
386
401
|
upload(
|
|
387
402
|
/** Uploaded variables' name */
|
|
388
403
|
vars: string[],
|
|
389
404
|
/** Uploaded variables' value */
|
|
390
|
-
args: (DdbObj | string | boolean)[]
|
|
405
|
+
args: (DdbObj | string | boolean)[], { on_message, parse_object, }?: {
|
|
406
|
+
on_message?: DDB['on_message'];
|
|
407
|
+
parse_object?: boolean;
|
|
408
|
+
}): Promise<DdbObj<DdbValue>>;
|
|
391
409
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
392
|
-
parse_message(buf: Uint8Array):
|
|
393
|
-
type: "message";
|
|
394
|
-
data: string;
|
|
395
|
-
} | {
|
|
396
|
-
type: "object";
|
|
397
|
-
data: Uint8Array;
|
|
398
|
-
};
|
|
410
|
+
parse_message(buf: Uint8Array, parse_object?: boolean): DdbMessage;
|
|
399
411
|
/** 自动转换 js string, boolean 为 DdbObj */
|
|
400
412
|
to_ddbobj(value: DdbObj | string | boolean): DdbObj;
|
|
401
413
|
/** 转换 js 数组为 DdbObj[] */
|
|
402
414
|
to_ddbobjs(values: any[]): DdbObj<DdbValue>[];
|
|
403
415
|
}
|
|
416
|
+
export interface DdbPrintMessage {
|
|
417
|
+
type: 'print';
|
|
418
|
+
data: string;
|
|
419
|
+
}
|
|
420
|
+
export interface DdbObjectMessage {
|
|
421
|
+
type: 'object';
|
|
422
|
+
data: DdbObj;
|
|
423
|
+
}
|
|
424
|
+
export declare type DdbMessage = DdbPrintMessage | DdbObjectMessage;
|
|
404
425
|
export default DDB;
|
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const ws_1 = require("ws");
|
|
|
6
6
|
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
|
7
7
|
const customParseFormat_js_1 = tslib_1.__importDefault(require("dayjs/plugin/customParseFormat.js"));
|
|
8
8
|
dayjs_1.default.extend(customParseFormat_js_1.default);
|
|
9
|
+
const net_js_1 = require("xshell/net.js");
|
|
9
10
|
const utils_js_1 = require("xshell/utils.js");
|
|
10
11
|
var DdbForm;
|
|
11
12
|
(function (DdbForm) {
|
|
@@ -109,8 +110,7 @@ var DdbFunctionType;
|
|
|
109
110
|
DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
|
|
110
111
|
})(DdbFunctionType = exports.DdbFunctionType || (exports.DdbFunctionType = {}));
|
|
111
112
|
exports.nulls = {
|
|
112
|
-
|
|
113
|
-
char: '\x80',
|
|
113
|
+
int8: -0x80,
|
|
114
114
|
int16: -32768,
|
|
115
115
|
int32: -2147483648,
|
|
116
116
|
int64: -0x8000000000000000n,
|
|
@@ -284,12 +284,14 @@ class DdbObj {
|
|
|
284
284
|
case DdbType.void:
|
|
285
285
|
return [1, null];
|
|
286
286
|
case DdbType.bool: {
|
|
287
|
-
const
|
|
288
|
-
|
|
287
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
288
|
+
const value = dv.getInt8(0);
|
|
289
|
+
return [1, value === exports.nulls.int8 ? null : Boolean(value)];
|
|
289
290
|
}
|
|
290
291
|
case DdbType.char: {
|
|
291
|
-
const
|
|
292
|
-
|
|
292
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
293
|
+
const value = dv.getInt8(0);
|
|
294
|
+
return [1, value === exports.nulls.int8 ? null : value];
|
|
293
295
|
}
|
|
294
296
|
case DdbType.short: {
|
|
295
297
|
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
@@ -474,11 +476,10 @@ class DdbObj {
|
|
|
474
476
|
static parse_vector_items(buf, le, type, length) {
|
|
475
477
|
switch (type) {
|
|
476
478
|
case DdbType.bool:
|
|
477
|
-
return [length, buf.slice(0, length)];
|
|
478
479
|
case DdbType.char:
|
|
479
480
|
return [
|
|
480
481
|
length,
|
|
481
|
-
|
|
482
|
+
new Int8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + length))
|
|
482
483
|
];
|
|
483
484
|
case DdbType.short:
|
|
484
485
|
return [
|
|
@@ -628,17 +629,17 @@ class DdbObj {
|
|
|
628
629
|
return [Uint8Array.of(1)];
|
|
629
630
|
case DdbType.bool:
|
|
630
631
|
return [
|
|
631
|
-
|
|
632
|
-
exports.nulls.
|
|
632
|
+
Int8Array.of(value === null ?
|
|
633
|
+
exports.nulls.int8
|
|
633
634
|
:
|
|
634
635
|
Number(value))
|
|
635
636
|
];
|
|
636
637
|
case DdbType.char:
|
|
637
638
|
return [
|
|
638
|
-
|
|
639
|
-
exports.nulls.
|
|
639
|
+
Int8Array.of((value === null ?
|
|
640
|
+
exports.nulls.int8
|
|
640
641
|
:
|
|
641
|
-
value)
|
|
642
|
+
value))
|
|
642
643
|
];
|
|
643
644
|
case DdbType.short:
|
|
644
645
|
return [
|
|
@@ -780,7 +781,7 @@ class DdbObj {
|
|
|
780
781
|
case DdbType.bool:
|
|
781
782
|
return [value];
|
|
782
783
|
case DdbType.char:
|
|
783
|
-
return [
|
|
784
|
+
return [value];
|
|
784
785
|
case DdbType.short:
|
|
785
786
|
return [value];
|
|
786
787
|
case DdbType.int:
|
|
@@ -968,7 +969,10 @@ class DdbChar extends DdbObj {
|
|
|
968
969
|
form: DdbForm.scalar,
|
|
969
970
|
type: DdbType.char,
|
|
970
971
|
length: 1,
|
|
971
|
-
value
|
|
972
|
+
value: typeof value === 'string' ?
|
|
973
|
+
value.charCodeAt(0)
|
|
974
|
+
:
|
|
975
|
+
value
|
|
972
976
|
});
|
|
973
977
|
}
|
|
974
978
|
}
|
|
@@ -1375,7 +1379,7 @@ class DDB {
|
|
|
1375
1379
|
this.password = '123456';
|
|
1376
1380
|
/** python session flag (2048) */
|
|
1377
1381
|
this.python = false;
|
|
1378
|
-
this.
|
|
1382
|
+
this.parse_object = true;
|
|
1379
1383
|
this.presult = Promise.resolve(null);
|
|
1380
1384
|
this.url = url;
|
|
1381
1385
|
if (options.autologin !== undefined)
|
|
@@ -1387,12 +1391,20 @@ class DDB {
|
|
|
1387
1391
|
if (options.python !== undefined)
|
|
1388
1392
|
this.python = options.python;
|
|
1389
1393
|
}
|
|
1390
|
-
/**
|
|
1391
|
-
|
|
1392
|
-
|
|
1394
|
+
/** message handler */
|
|
1395
|
+
on_message({ type, data }, _this) {
|
|
1396
|
+
switch (type) {
|
|
1397
|
+
case 'print':
|
|
1398
|
+
console.log(data);
|
|
1399
|
+
return;
|
|
1400
|
+
case 'object':
|
|
1401
|
+
if (this.print_buffer)
|
|
1402
|
+
console.log((0, utils_js_1.typed_array_to_buffer)(data.buffer));
|
|
1403
|
+
return;
|
|
1404
|
+
}
|
|
1393
1405
|
}
|
|
1394
1406
|
/** resolver, rejector, promise of last rpc */
|
|
1395
|
-
presolver(
|
|
1407
|
+
presolver(message) { }
|
|
1396
1408
|
prejector(error) { }
|
|
1397
1409
|
get connected() {
|
|
1398
1410
|
return this.websocket?.readyState === ws_1.WebSocket.OPEN;
|
|
@@ -1417,42 +1429,25 @@ class DDB {
|
|
|
1417
1429
|
if (options.python !== undefined)
|
|
1418
1430
|
this.python = options.python;
|
|
1419
1431
|
this.disconnect();
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
websocket.binaryType = 'arraybuffer';
|
|
1425
|
-
this.websocket = websocket;
|
|
1426
|
-
await new Promise((resolve, reject) => {
|
|
1427
|
-
websocket.addEventListener('open', async (event) => {
|
|
1428
|
-
console.log(`${websocket.url} opened`);
|
|
1432
|
+
await (0, net_js_1.connect_websocket)(this.url, {
|
|
1433
|
+
protocols: this.python ? ['python'] : [],
|
|
1434
|
+
on_open: async (event, websocket) => {
|
|
1435
|
+
this.websocket = websocket;
|
|
1429
1436
|
await this.rpc('connect', {});
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
websocket.addEventListener('close', event => {
|
|
1433
|
-
console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
|
|
1434
|
-
});
|
|
1435
|
-
websocket.addEventListener('error', event => {
|
|
1436
|
-
const message = `${websocket.url} errored`;
|
|
1437
|
-
console.error(message, event);
|
|
1438
|
-
reject(Object.assign(new Error(message), { event }));
|
|
1439
|
-
});
|
|
1440
|
-
websocket.addEventListener('message', event => {
|
|
1437
|
+
},
|
|
1438
|
+
on_message: event => {
|
|
1441
1439
|
const buf = new Uint8Array(event.data);
|
|
1442
|
-
if (this.message_hook)
|
|
1443
|
-
this.message_hook(buf);
|
|
1444
1440
|
try {
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1441
|
+
const message = this.parse_message(buf);
|
|
1442
|
+
this.on_message(message, this);
|
|
1443
|
+
if (message.type === 'print')
|
|
1448
1444
|
return;
|
|
1449
|
-
|
|
1450
|
-
this.presolver(data);
|
|
1445
|
+
this.presolver(message);
|
|
1451
1446
|
}
|
|
1452
1447
|
catch (error) {
|
|
1453
1448
|
this.prejector(error);
|
|
1454
1449
|
}
|
|
1455
|
-
}
|
|
1450
|
+
}
|
|
1456
1451
|
});
|
|
1457
1452
|
if (!this.python)
|
|
1458
1453
|
await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
|
|
@@ -1506,7 +1501,7 @@ class DDB {
|
|
|
1506
1501
|
limit,
|
|
1507
1502
|
] : [],
|
|
1508
1503
|
];
|
|
1509
|
-
return
|
|
1504
|
+
return options.join('_');
|
|
1510
1505
|
}
|
|
1511
1506
|
disconnect() {
|
|
1512
1507
|
if (this.connected)
|
|
@@ -1520,8 +1515,11 @@ class DDB {
|
|
|
1520
1515
|
- options:
|
|
1521
1516
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
1522
1517
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
1518
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
1519
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
1520
|
+
不做解析,以便后续转发、序列化
|
|
1523
1521
|
*/
|
|
1524
|
-
async rpc(type, { script, func, args = [], vars = [], urgent, }) {
|
|
1522
|
+
async rpc(type, { script, func, args = [], vars = [], urgent, on_message, parse_object, }) {
|
|
1525
1523
|
if (!this.websocket)
|
|
1526
1524
|
await this.connect();
|
|
1527
1525
|
if (!this.connected)
|
|
@@ -1568,25 +1566,36 @@ class DDB {
|
|
|
1568
1566
|
}
|
|
1569
1567
|
})());
|
|
1570
1568
|
const message = (0, utils_js_1.concat)([
|
|
1571
|
-
this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
|
|
1569
|
+
this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
|
|
1572
1570
|
command,
|
|
1573
1571
|
...args.map((arg) => arg.pack())
|
|
1574
1572
|
]);
|
|
1575
|
-
this.
|
|
1576
|
-
const
|
|
1577
|
-
if (
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1573
|
+
const _on_message = this.on_message;
|
|
1574
|
+
const _parse_object = this.parse_object;
|
|
1575
|
+
if (on_message)
|
|
1576
|
+
this.on_message = on_message;
|
|
1577
|
+
if (parse_object !== undefined)
|
|
1578
|
+
this.parse_object = parse_object;
|
|
1579
|
+
try {
|
|
1580
|
+
this.websocket.send(message);
|
|
1581
|
+
const { data } = (await presult);
|
|
1582
|
+
return data;
|
|
1583
|
+
}
|
|
1584
|
+
finally {
|
|
1585
|
+
this.on_message = _on_message;
|
|
1586
|
+
this.parse_object = _parse_object;
|
|
1587
|
+
}
|
|
1582
1588
|
}
|
|
1583
|
-
/** eval script through websocket (script command)
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1589
|
+
/** eval script through websocket (script command)
|
|
1590
|
+
- script?: 执行的脚本
|
|
1591
|
+
- options?: 执行选项
|
|
1592
|
+
- urgent?: 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞
|
|
1593
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
1594
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
1595
|
+
不做解析,以便后续转发、序列化
|
|
1596
|
+
*/
|
|
1597
|
+
async eval(script, { urgent, on_message, parse_object, } = {}) {
|
|
1598
|
+
return this.rpc('script', { script, urgent, on_message, parse_object });
|
|
1590
1599
|
}
|
|
1591
1600
|
/** call function through websocket (function command)
|
|
1592
1601
|
- func: 函数名
|
|
@@ -1597,8 +1606,11 @@ class DDB {
|
|
|
1597
1606
|
- nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
|
|
1598
1607
|
- func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
|
|
1599
1608
|
- add_node_alias?: 设置 nodes 参数时选传,其它情况不传
|
|
1609
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
1610
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
1611
|
+
不做解析,以便后续转发、序列化
|
|
1600
1612
|
*/
|
|
1601
|
-
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
|
|
1613
|
+
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, on_message, parse_object, } = {}) {
|
|
1602
1614
|
if (this.python)
|
|
1603
1615
|
throw new Error('call doesn\'t support python session yet');
|
|
1604
1616
|
if (node) {
|
|
@@ -1630,6 +1642,8 @@ class DDB {
|
|
|
1630
1642
|
func,
|
|
1631
1643
|
args,
|
|
1632
1644
|
urgent,
|
|
1645
|
+
on_message,
|
|
1646
|
+
parse_object
|
|
1633
1647
|
});
|
|
1634
1648
|
}
|
|
1635
1649
|
/** upload variable through websocket (variable command) */
|
|
@@ -1637,19 +1651,19 @@ class DDB {
|
|
|
1637
1651
|
/** Uploaded variables' name */
|
|
1638
1652
|
vars,
|
|
1639
1653
|
/** Uploaded variables' value */
|
|
1640
|
-
args) {
|
|
1654
|
+
args, { on_message, parse_object, } = {}) {
|
|
1641
1655
|
if (!args.length || args.length !== vars.length)
|
|
1642
1656
|
throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
|
|
1643
|
-
return this.rpc('variable', { vars, args });
|
|
1657
|
+
return this.rpc('variable', { vars, args, on_message, parse_object });
|
|
1644
1658
|
}
|
|
1645
1659
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
1646
|
-
parse_message(buf) {
|
|
1660
|
+
parse_message(buf, parse_object = this.parse_object) {
|
|
1647
1661
|
// MSG\n
|
|
1648
1662
|
// <message>\0
|
|
1649
1663
|
// 'M'.codePointAt(0).to_hex_str()
|
|
1650
1664
|
if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
|
|
1651
1665
|
return {
|
|
1652
|
-
type: '
|
|
1666
|
+
type: 'print',
|
|
1653
1667
|
data: this.dec.decode(buf.subarray(4))
|
|
1654
1668
|
};
|
|
1655
1669
|
// '1166953221 1 1\n'
|
|
@@ -1674,9 +1688,19 @@ class DDB {
|
|
|
1674
1688
|
const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
|
|
1675
1689
|
if (message !== 'OK')
|
|
1676
1690
|
throw new Error(message);
|
|
1691
|
+
const buf_obj = buf.subarray(i_lf_1 + 1);
|
|
1677
1692
|
return {
|
|
1678
1693
|
type: 'object',
|
|
1679
|
-
data:
|
|
1694
|
+
data: parse_object ?
|
|
1695
|
+
Object.assign(DdbObj.parse(buf_obj, this.le), { buffer: buf_obj })
|
|
1696
|
+
:
|
|
1697
|
+
new DdbObj({
|
|
1698
|
+
form: DdbForm.scalar,
|
|
1699
|
+
type: DdbType.void,
|
|
1700
|
+
length: 0,
|
|
1701
|
+
le: this.le,
|
|
1702
|
+
buffer: buf_obj,
|
|
1703
|
+
})
|
|
1680
1704
|
};
|
|
1681
1705
|
}
|
|
1682
1706
|
/** 自动转换 js string, boolean 为 DdbObj */
|