dolphindb 2.0.504 → 2.0.507
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 +69 -39
- package/browser.js +174 -122
- package/browser.js.map +1 -1
- package/index.d.ts +68 -39
- package/index.js +172 -129
- package/index.js.map +1 -1
- package/package.json +4 -4
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:
|
|
@@ -883,10 +884,16 @@ class DdbObj {
|
|
|
883
884
|
}
|
|
884
885
|
})();
|
|
885
886
|
const data = (() => {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
887
|
+
switch (this.form) {
|
|
888
|
+
case DdbForm.pair:
|
|
889
|
+
return `${(0, utils_js_1.inspect)(this.value[0], options)}, ${(0, utils_js_1.inspect)(this.value[1], options)}`;
|
|
890
|
+
case DdbForm.scalar:
|
|
891
|
+
switch (this.type) {
|
|
892
|
+
case DdbType.functiondef:
|
|
893
|
+
return (0, utils_js_1.inspect)(this.value.name, options);
|
|
894
|
+
}
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
890
897
|
if (this.value instanceof Uint8Array)
|
|
891
898
|
return (0, utils_js_1.inspect)((0, utils_js_1.typed_array_to_buffer)(this.value), options);
|
|
892
899
|
return (0, utils_js_1.inspect)(this.value, options);
|
|
@@ -900,21 +907,26 @@ class DdbObj {
|
|
|
900
907
|
for (let i = 0; i < this.rows; i++) {
|
|
901
908
|
let row = {};
|
|
902
909
|
for (let j = 0; j < this.cols; j++) {
|
|
903
|
-
const { type, name, value } = this.value[j]; // column
|
|
910
|
+
const { type, name, value: values } = this.value[j]; // column
|
|
904
911
|
switch (type) {
|
|
905
|
-
case DdbType.bool:
|
|
906
|
-
|
|
912
|
+
case DdbType.bool: {
|
|
913
|
+
const value = values[i];
|
|
914
|
+
row[name] = value === exports.nulls.int8 ?
|
|
915
|
+
null
|
|
916
|
+
:
|
|
917
|
+
Boolean(value);
|
|
907
918
|
break;
|
|
919
|
+
}
|
|
908
920
|
case DdbType.ipaddr:
|
|
909
|
-
row[name] =
|
|
921
|
+
row[name] = values.subarray(16 * i, 16 * (i + 1));
|
|
910
922
|
break;
|
|
911
923
|
case DdbType.symbol_extended: {
|
|
912
|
-
const { base, data } =
|
|
924
|
+
const { base, data } = values;
|
|
913
925
|
row[name] = base[data[i]];
|
|
914
926
|
break;
|
|
915
927
|
}
|
|
916
928
|
default:
|
|
917
|
-
row[name] =
|
|
929
|
+
row[name] = values[i];
|
|
918
930
|
}
|
|
919
931
|
}
|
|
920
932
|
rows[i] = row;
|
|
@@ -968,7 +980,10 @@ class DdbChar extends DdbObj {
|
|
|
968
980
|
form: DdbForm.scalar,
|
|
969
981
|
type: DdbType.char,
|
|
970
982
|
length: 1,
|
|
971
|
-
value
|
|
983
|
+
value: typeof value === 'string' ?
|
|
984
|
+
value.charCodeAt(0)
|
|
985
|
+
:
|
|
986
|
+
value
|
|
972
987
|
});
|
|
973
988
|
}
|
|
974
989
|
}
|
|
@@ -1363,7 +1378,6 @@ class DDB {
|
|
|
1363
1378
|
/** utf-8 text decoder */
|
|
1364
1379
|
this.dec = new TextDecoder('utf-8');
|
|
1365
1380
|
this.enc = new TextEncoder();
|
|
1366
|
-
this.print_buffer = false;
|
|
1367
1381
|
this.websocket = null;
|
|
1368
1382
|
/** little endian (server) */
|
|
1369
1383
|
this.le = true;
|
|
@@ -1375,8 +1389,13 @@ class DDB {
|
|
|
1375
1389
|
this.password = '123456';
|
|
1376
1390
|
/** python session flag (2048) */
|
|
1377
1391
|
this.python = false;
|
|
1378
|
-
this.
|
|
1379
|
-
this.
|
|
1392
|
+
this.print_message_buffer = false;
|
|
1393
|
+
this.print_object_buffer = false;
|
|
1394
|
+
this.print_message = true;
|
|
1395
|
+
this.parse_object = true;
|
|
1396
|
+
/** DdbMessage listeners */
|
|
1397
|
+
this.listeners = [];
|
|
1398
|
+
this.promise = Promise.resolve(null);
|
|
1380
1399
|
this.url = url;
|
|
1381
1400
|
if (options.autologin !== undefined)
|
|
1382
1401
|
this.autologin = options.autologin;
|
|
@@ -1387,16 +1406,10 @@ class DDB {
|
|
|
1387
1406
|
if (options.python !== undefined)
|
|
1388
1407
|
this.python = options.python;
|
|
1389
1408
|
}
|
|
1390
|
-
/** print message handler */
|
|
1391
|
-
printer(message) {
|
|
1392
|
-
console.log(message);
|
|
1393
|
-
}
|
|
1394
|
-
/** resolver, rejector, promise of last rpc */
|
|
1395
|
-
presolver(buf) { }
|
|
1396
|
-
prejector(error) { }
|
|
1397
1409
|
get connected() {
|
|
1398
1410
|
return this.websocket?.readyState === ws_1.WebSocket.OPEN;
|
|
1399
1411
|
}
|
|
1412
|
+
on_message(event) { }
|
|
1400
1413
|
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL
|
|
1401
1414
|
- options?:
|
|
1402
1415
|
- url?: DolphinDB WebSocket URL. By default, the WebSocket URL passed in when the instance is initialized is used
|
|
@@ -1417,60 +1430,51 @@ class DDB {
|
|
|
1417
1430
|
if (options.python !== undefined)
|
|
1418
1431
|
this.python = options.python;
|
|
1419
1432
|
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`);
|
|
1433
|
+
await (0, net_js_1.connect_websocket)(this.url, {
|
|
1434
|
+
protocols: this.python ? ['python'] : [],
|
|
1435
|
+
on_open: async (event, websocket) => {
|
|
1436
|
+
this.websocket = websocket;
|
|
1429
1437
|
await this.rpc('connect', {});
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
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 => {
|
|
1441
|
-
const buf = new Uint8Array(event.data);
|
|
1442
|
-
if (this.message_hook)
|
|
1443
|
-
this.message_hook(buf);
|
|
1444
|
-
try {
|
|
1445
|
-
const { type, data } = this.parse_message(buf);
|
|
1446
|
-
if (type === 'message') {
|
|
1447
|
-
this.printer(data);
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
this.presolver(data);
|
|
1451
|
-
}
|
|
1452
|
-
catch (error) {
|
|
1453
|
-
this.prejector(error);
|
|
1454
|
-
}
|
|
1455
|
-
});
|
|
1438
|
+
},
|
|
1439
|
+
on_message: event => {
|
|
1440
|
+
this.on_message(event);
|
|
1441
|
+
}
|
|
1456
1442
|
});
|
|
1457
|
-
|
|
1458
|
-
|
|
1443
|
+
await this.eval(this.python ?
|
|
1444
|
+
'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
|
|
1459
1445
|
' nargs = size(args)\n' +
|
|
1460
1446
|
' func = funcByName(func_name)\n' +
|
|
1461
1447
|
' \n' +
|
|
1462
|
-
' if
|
|
1448
|
+
' if not nargs:\n' +
|
|
1463
1449
|
' return pnodeRun(func, nodes, add_node_alias)\n' +
|
|
1464
1450
|
' \n' +
|
|
1465
|
-
' args_partial =
|
|
1466
|
-
' args_partial
|
|
1467
|
-
'
|
|
1451
|
+
' args_partial = [ ]\n' +
|
|
1452
|
+
' args_partial.append(func)\n' +
|
|
1453
|
+
' for a in args:\n' +
|
|
1454
|
+
' args_partial.append(a)\n' +
|
|
1455
|
+
' \n' +
|
|
1468
1456
|
' return pnodeRun(\n' +
|
|
1469
1457
|
' unifiedCall(partial, args_partial),\n' +
|
|
1470
1458
|
' nodes,\n' +
|
|
1471
1459
|
' add_node_alias\n' +
|
|
1472
|
-
' )\n'
|
|
1473
|
-
|
|
1460
|
+
' )\n'
|
|
1461
|
+
:
|
|
1462
|
+
'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
|
|
1463
|
+
' nargs = size(args)\n' +
|
|
1464
|
+
' func = funcByName(func_name)\n' +
|
|
1465
|
+
' \n' +
|
|
1466
|
+
' if (!nargs)\n' +
|
|
1467
|
+
' return pnodeRun(func, nodes, add_node_alias)\n' +
|
|
1468
|
+
' \n' +
|
|
1469
|
+
' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
|
|
1470
|
+
' args_partial[0] = func\n' +
|
|
1471
|
+
' args_partial[1:] = args\n' +
|
|
1472
|
+
' return pnodeRun(\n' +
|
|
1473
|
+
' unifiedCall(partial, args_partial),\n' +
|
|
1474
|
+
' nodes,\n' +
|
|
1475
|
+
' add_node_alias\n' +
|
|
1476
|
+
' )\n' +
|
|
1477
|
+
'}\n', { urgent: true });
|
|
1474
1478
|
if (this.autologin)
|
|
1475
1479
|
if (this.python)
|
|
1476
1480
|
await this.eval(`login(${this.username.quote('double')}, ${this.password.quote('double')})`, { urgent: true });
|
|
@@ -1506,47 +1510,69 @@ class DDB {
|
|
|
1506
1510
|
limit,
|
|
1507
1511
|
] : [],
|
|
1508
1512
|
];
|
|
1509
|
-
return
|
|
1513
|
+
return options.join('_');
|
|
1510
1514
|
}
|
|
1511
1515
|
disconnect() {
|
|
1512
1516
|
if (this.connected)
|
|
1513
1517
|
this.websocket.close(1000);
|
|
1514
|
-
this.
|
|
1515
|
-
this.
|
|
1516
|
-
this.presult = Promise.resolve(null);
|
|
1518
|
+
this.on_message = () => { };
|
|
1519
|
+
this.promise = Promise.resolve(null);
|
|
1517
1520
|
}
|
|
1518
1521
|
/** rpc through websocket (function/script/variable command)
|
|
1519
1522
|
- type: API 类型: 'script' | 'function' | 'variable'
|
|
1520
1523
|
- options:
|
|
1521
1524
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
1522
1525
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
1526
|
+
- handler?: Process messages during this rpc (DdbMessage)
|
|
1527
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
1528
|
+
不做解析,以便后续转发、序列化
|
|
1523
1529
|
*/
|
|
1524
|
-
async rpc(type, { script, func, args = [], vars = [], urgent, }) {
|
|
1530
|
+
async rpc(type, { script, func, args = [], vars = [], urgent, listener, parse_object, }) {
|
|
1525
1531
|
if (!this.websocket)
|
|
1526
1532
|
await this.connect();
|
|
1527
1533
|
if (!this.connected)
|
|
1528
1534
|
throw new Error(`${this.url} is already disconnected`);
|
|
1535
|
+
// this 上的当前配置需要在 message 到达后使用,先保存起来
|
|
1536
|
+
const _handlers = [...this.listeners].reverse();
|
|
1529
1537
|
// 临界区:保证多个 rpc 并发时形成 promise 链
|
|
1530
1538
|
// ddb 世界观:需要等待上一个 rpc 结果从 server 返回之后才能发起下一个调用
|
|
1531
1539
|
// 违反世界观可能造成:
|
|
1532
1540
|
// 1. 并发多个请求只返回第一个结果(阻塞,需后续请求疏通)
|
|
1533
1541
|
// 2. windows 下 ddb server 返回多个相同的结果
|
|
1534
|
-
const ptail = this.
|
|
1535
|
-
let
|
|
1536
|
-
let
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1542
|
+
const ptail = this.promise;
|
|
1543
|
+
let resolve;
|
|
1544
|
+
let reject;
|
|
1545
|
+
const promise = this.promise = new Promise((_resolve, _reject) => {
|
|
1546
|
+
resolve = _resolve;
|
|
1547
|
+
reject = _reject;
|
|
1540
1548
|
});
|
|
1541
1549
|
try {
|
|
1542
1550
|
await ptail;
|
|
1543
1551
|
}
|
|
1544
1552
|
catch { }
|
|
1545
|
-
this.
|
|
1546
|
-
this.
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1553
|
+
// 临界区结束,只有一个 rpc 函数调用运行到这里,可以独占 this.on_message 然后写 WebSocket
|
|
1554
|
+
this.on_message = ({ data: buffer }) => {
|
|
1555
|
+
const buf = new Uint8Array(buffer);
|
|
1556
|
+
if (this.print_message_buffer)
|
|
1557
|
+
console.log((0, utils_js_1.typed_array_to_buffer)(buf));
|
|
1558
|
+
const message = this.parse_message(buf, parse_object);
|
|
1559
|
+
listener?.(message, this);
|
|
1560
|
+
for (const listener of _handlers)
|
|
1561
|
+
listener(message, this);
|
|
1562
|
+
const { type, data } = message;
|
|
1563
|
+
switch (type) {
|
|
1564
|
+
case 'print':
|
|
1565
|
+
if (this.print_message)
|
|
1566
|
+
console.log(data);
|
|
1567
|
+
return;
|
|
1568
|
+
case 'object':
|
|
1569
|
+
resolve(data);
|
|
1570
|
+
return;
|
|
1571
|
+
case 'error':
|
|
1572
|
+
reject(data);
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1550
1576
|
args = this.to_ddbobjs(args);
|
|
1551
1577
|
const command = this.enc.encode((() => {
|
|
1552
1578
|
switch (type) {
|
|
@@ -1567,40 +1593,40 @@ class DDB {
|
|
|
1567
1593
|
return 'connect\n';
|
|
1568
1594
|
}
|
|
1569
1595
|
})());
|
|
1570
|
-
|
|
1571
|
-
this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
|
|
1596
|
+
this.websocket.send((0, utils_js_1.concat)([
|
|
1597
|
+
this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
|
|
1572
1598
|
command,
|
|
1573
1599
|
...args.map((arg) => arg.pack())
|
|
1574
|
-
]);
|
|
1575
|
-
|
|
1576
|
-
const buf_data = await presult;
|
|
1577
|
-
if (this.print_buffer)
|
|
1578
|
-
console.log((0, utils_js_1.typed_array_to_buffer)(buf_data));
|
|
1579
|
-
// LOCAL: 便于 repl
|
|
1580
|
-
// return global.DdbObj.parse(data_buf) as DdbObj
|
|
1581
|
-
return DdbObj.parse(buf_data, this.le);
|
|
1600
|
+
]));
|
|
1601
|
+
return promise;
|
|
1582
1602
|
}
|
|
1583
|
-
/** eval script through websocket (script command)
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1603
|
+
/** eval script through websocket (script command)
|
|
1604
|
+
- script?: Script to execute
|
|
1605
|
+
- options?: execution options
|
|
1606
|
+
- urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
|
|
1607
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
1608
|
+
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1609
|
+
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1610
|
+
so as to facilitate subsequent forwarding and serialization
|
|
1611
|
+
*/
|
|
1612
|
+
async eval(script, { urgent, listener, parse_object, } = {}) {
|
|
1613
|
+
return this.rpc('script', { script, urgent, listener, parse_object });
|
|
1590
1614
|
}
|
|
1591
1615
|
/** call function through websocket (function command)
|
|
1592
|
-
- func:
|
|
1593
|
-
- args?: `[ ]`
|
|
1594
|
-
- options?:
|
|
1595
|
-
- urgent?:
|
|
1596
|
-
- node?:
|
|
1597
|
-
- nodes?:
|
|
1598
|
-
- func_type?:
|
|
1599
|
-
- add_node_alias?:
|
|
1616
|
+
- func: function name
|
|
1617
|
+
- args?: `[ ]` Call parameters (the incoming native string and boolean will be automatically converted to DdbObj<string> and DdbObj<boolean>)
|
|
1618
|
+
- options?: call options
|
|
1619
|
+
- urgent?: Emergency flag. Use urgent worker execution to prevent being blocked by other jobs
|
|
1620
|
+
- node?: When the node alias is set, it is sent to the corresponding node in the cluster for execution (using the rpc method in DolphinDB)
|
|
1621
|
+
- nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
|
|
1622
|
+
- func_type?: It must be passed when setting the node parameter, the function type needs to be specified, and it is not passed in other cases
|
|
1623
|
+
- add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
|
|
1624
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
1625
|
+
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1626
|
+
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1627
|
+
so as to facilitate subsequent forwarding and serialization
|
|
1600
1628
|
*/
|
|
1601
|
-
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
|
|
1602
|
-
if (this.python)
|
|
1603
|
-
throw new Error('call doesn\'t support python session yet');
|
|
1629
|
+
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, } = {}) {
|
|
1604
1630
|
if (node) {
|
|
1605
1631
|
if (typeof func_type === 'undefined')
|
|
1606
1632
|
throw new Error('指定 node 时必须设置 func_type');
|
|
@@ -1630,6 +1656,8 @@ class DDB {
|
|
|
1630
1656
|
func,
|
|
1631
1657
|
args,
|
|
1632
1658
|
urgent,
|
|
1659
|
+
listener,
|
|
1660
|
+
parse_object
|
|
1633
1661
|
});
|
|
1634
1662
|
}
|
|
1635
1663
|
/** upload variable through websocket (variable command) */
|
|
@@ -1637,19 +1665,19 @@ class DDB {
|
|
|
1637
1665
|
/** Uploaded variables' name */
|
|
1638
1666
|
vars,
|
|
1639
1667
|
/** Uploaded variables' value */
|
|
1640
|
-
args) {
|
|
1668
|
+
args, { listener, parse_object, } = {}) {
|
|
1641
1669
|
if (!args.length || args.length !== vars.length)
|
|
1642
|
-
throw new Error('variable
|
|
1643
|
-
return this.rpc('variable', { vars, args });
|
|
1670
|
+
throw new Error('variable command parameter is empty or parameter name is empty, or the number does not match');
|
|
1671
|
+
return this.rpc('variable', { vars, args, listener, parse_object });
|
|
1644
1672
|
}
|
|
1645
1673
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
1646
|
-
parse_message(buf) {
|
|
1674
|
+
parse_message(buf, parse_object = this.parse_object) {
|
|
1647
1675
|
// MSG\n
|
|
1648
1676
|
// <message>\0
|
|
1649
1677
|
// 'M'.codePointAt(0).to_hex_str()
|
|
1650
1678
|
if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
|
|
1651
1679
|
return {
|
|
1652
|
-
type: '
|
|
1680
|
+
type: 'print',
|
|
1653
1681
|
data: this.dec.decode(buf.subarray(4))
|
|
1654
1682
|
};
|
|
1655
1683
|
// '1166953221 1 1\n'
|
|
@@ -1673,10 +1701,25 @@ class DDB {
|
|
|
1673
1701
|
/** 'OK' 表示成功,其它文本表示失败 */
|
|
1674
1702
|
const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
|
|
1675
1703
|
if (message !== 'OK')
|
|
1676
|
-
|
|
1704
|
+
return {
|
|
1705
|
+
type: 'error',
|
|
1706
|
+
data: new Error(message)
|
|
1707
|
+
};
|
|
1708
|
+
const buf_obj = buf.subarray(i_lf_1 + 1);
|
|
1709
|
+
if (this.print_object_buffer)
|
|
1710
|
+
console.log((0, utils_js_1.typed_array_to_buffer)(buf_obj));
|
|
1677
1711
|
return {
|
|
1678
1712
|
type: 'object',
|
|
1679
|
-
data:
|
|
1713
|
+
data: parse_object ?
|
|
1714
|
+
DdbObj.parse(buf_obj, this.le)
|
|
1715
|
+
:
|
|
1716
|
+
new DdbObj({
|
|
1717
|
+
form: DdbForm.scalar,
|
|
1718
|
+
type: DdbType.void,
|
|
1719
|
+
length: 0,
|
|
1720
|
+
le: this.le,
|
|
1721
|
+
buffer: buf_obj,
|
|
1722
|
+
})
|
|
1680
1723
|
};
|
|
1681
1724
|
}
|
|
1682
1725
|
/** 自动转换 js string, boolean 为 DdbObj */
|