dolphindb 2.0.503 → 2.0.506

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.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.str2timestamp = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbTable = exports.DdbVectorSymbol = exports.DdbVectorAny = exports.DdbVectorDouble = exports.DdbVectorString = exports.DdbVectorInt = exports.DdbFunction = exports.DdbPair = exports.DdbNanoTimeStamp = exports.DdbTimeStamp = exports.DdbDateTime = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbChar = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.DdbType = exports.DdbForm = void 0;
3
+ exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.str2timestamp = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbTable = exports.DdbSetString = exports.DdbSetDouble = exports.DdbSetInt = exports.DdbVectorSymbol = exports.DdbVectorAny = exports.DdbVectorString = exports.DdbVectorDouble = exports.DdbVectorInt = exports.DdbFunction = exports.DdbPair = exports.DdbNanoTimeStamp = exports.DdbTimeStamp = exports.DdbDateTime = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbChar = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.DdbType = exports.DdbForm = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
6
6
  const customParseFormat_js_1 = tslib_1.__importDefault(require("dayjs/plugin/customParseFormat.js"));
7
7
  dayjs_1.default.extend(customParseFormat_js_1.default);
8
8
  require("xshell/prototype.browser");
9
9
  const utils_browser_1 = require("xshell/utils.browser");
10
+ const net_browser_js_1 = require("xshell/net.browser.js");
10
11
  var DdbForm;
11
12
  (function (DdbForm) {
12
13
  DdbForm[DdbForm["scalar"] = 0] = "scalar";
@@ -72,8 +73,7 @@ var DdbFunctionType;
72
73
  DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
73
74
  })(DdbFunctionType = exports.DdbFunctionType || (exports.DdbFunctionType = {}));
74
75
  exports.nulls = {
75
- bool: 0x80,
76
- char: '\x80',
76
+ int8: -0x80,
77
77
  int16: -32768,
78
78
  int32: -2147483648,
79
79
  int64: -0x8000000000000000n,
@@ -247,12 +247,14 @@ class DdbObj {
247
247
  case DdbType.void:
248
248
  return [1, null];
249
249
  case DdbType.bool: {
250
- const value = buf[0];
251
- return [1, value === exports.nulls.bool ? null : Boolean(value)];
250
+ const dv = new DataView(buf.buffer, buf.byteOffset);
251
+ const value = dv.getInt8(0);
252
+ return [1, value === exports.nulls.int8 ? null : Boolean(value)];
252
253
  }
253
254
  case DdbType.char: {
254
- const value = String.fromCharCode(buf[0]);
255
- return [1, value === exports.nulls.char ? null : value];
255
+ const dv = new DataView(buf.buffer, buf.byteOffset);
256
+ const value = dv.getInt8(0);
257
+ return [1, value === exports.nulls.int8 ? null : value];
256
258
  }
257
259
  case DdbType.short: {
258
260
  const dv = new DataView(buf.buffer, buf.byteOffset);
@@ -437,11 +439,10 @@ class DdbObj {
437
439
  static parse_vector_items(buf, le, type, length) {
438
440
  switch (type) {
439
441
  case DdbType.bool:
440
- return [length, buf.slice(0, length)];
441
442
  case DdbType.char:
442
443
  return [
443
444
  length,
444
- this.dec.decode(buf.subarray(0, length))
445
+ new Int8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + length))
445
446
  ];
446
447
  case DdbType.short:
447
448
  return [
@@ -591,17 +592,17 @@ class DdbObj {
591
592
  return [Uint8Array.of(1)];
592
593
  case DdbType.bool:
593
594
  return [
594
- Uint8Array.of(value === null ?
595
- exports.nulls.bool
595
+ Int8Array.of(value === null ?
596
+ exports.nulls.int8
596
597
  :
597
598
  Number(value))
598
599
  ];
599
600
  case DdbType.char:
600
601
  return [
601
- Uint8Array.of((value === null ?
602
- exports.nulls.char
602
+ Int8Array.of((value === null ?
603
+ exports.nulls.int8
603
604
  :
604
- value).charCodeAt(0))
605
+ value))
605
606
  ];
606
607
  case DdbType.short:
607
608
  return [
@@ -743,7 +744,7 @@ class DdbObj {
743
744
  case DdbType.bool:
744
745
  return [value];
745
746
  case DdbType.char:
746
- return [this.enc.encode(value)];
747
+ return [value];
747
748
  case DdbType.short:
748
749
  return [value];
749
750
  case DdbType.int:
@@ -846,10 +847,18 @@ class DdbObj {
846
847
  }
847
848
  })();
848
849
  const data = (() => {
849
- if (this.form === DdbForm.pair)
850
- return `${this.value[0]}, ${this.value[1]}`;
851
- if (this.form === DdbForm.scalar && this.type === DdbType.functiondef)
852
- return `'${this.value.name}'`;
850
+ switch (this.form) {
851
+ case DdbForm.pair:
852
+ return `${this.value[0]}, ${this.value[1]}`;
853
+ case DdbForm.scalar:
854
+ switch (this.type) {
855
+ case DdbType.functiondef:
856
+ return `'${this.value.name}'`;
857
+ case DdbType.string:
858
+ return `'${this.value}'`;
859
+ }
860
+ break;
861
+ }
853
862
  return this.value;
854
863
  })();
855
864
  return `${type}(${this.name ? `'${this.name}', ` : ''}${data})\n`;
@@ -949,7 +958,10 @@ class DdbChar extends DdbObj {
949
958
  form: DdbForm.scalar,
950
959
  type: DdbType.char,
951
960
  length: 1,
952
- value,
961
+ value: typeof value === 'string' ?
962
+ value.charCodeAt(0)
963
+ :
964
+ value
953
965
  });
954
966
  }
955
967
  }
@@ -1075,20 +1087,6 @@ class DdbVectorInt extends DdbObj {
1075
1087
  }
1076
1088
  }
1077
1089
  exports.DdbVectorInt = DdbVectorInt;
1078
- class DdbVectorString extends DdbObj {
1079
- constructor(strings, name) {
1080
- super({
1081
- form: DdbForm.vector,
1082
- type: DdbType.string,
1083
- length: 0,
1084
- rows: strings.length,
1085
- cols: 1,
1086
- value: strings,
1087
- name,
1088
- });
1089
- }
1090
- }
1091
- exports.DdbVectorString = DdbVectorString;
1092
1090
  class DdbVectorDouble extends DdbObj {
1093
1091
  constructor(doubles, name) {
1094
1092
  super({
@@ -1109,6 +1107,20 @@ class DdbVectorDouble extends DdbObj {
1109
1107
  }
1110
1108
  }
1111
1109
  exports.DdbVectorDouble = DdbVectorDouble;
1110
+ class DdbVectorString extends DdbObj {
1111
+ constructor(strings, name) {
1112
+ super({
1113
+ form: DdbForm.vector,
1114
+ type: DdbType.string,
1115
+ length: 0,
1116
+ rows: strings.length,
1117
+ cols: 1,
1118
+ value: strings,
1119
+ name,
1120
+ });
1121
+ }
1122
+ }
1123
+ exports.DdbVectorString = DdbVectorString;
1112
1124
  class DdbVectorAny extends DdbObj {
1113
1125
  constructor(objs, name) {
1114
1126
  super({
@@ -1154,6 +1166,65 @@ class DdbVectorSymbol extends DdbObj {
1154
1166
  }
1155
1167
  }
1156
1168
  exports.DdbVectorSymbol = DdbVectorSymbol;
1169
+ class DdbSetInt extends DdbObj {
1170
+ constructor(ints) {
1171
+ super({
1172
+ form: DdbForm.set,
1173
+ type: DdbType.int,
1174
+ length: 0,
1175
+ rows: ints instanceof Set ?
1176
+ ints.size
1177
+ :
1178
+ ints.length,
1179
+ cols: 1,
1180
+ value: ints instanceof Int32Array ?
1181
+ ints
1182
+ :
1183
+ Int32Array.from(ints, v => v === null ?
1184
+ exports.nulls.int32
1185
+ :
1186
+ v),
1187
+ });
1188
+ }
1189
+ }
1190
+ exports.DdbSetInt = DdbSetInt;
1191
+ class DdbSetDouble extends DdbObj {
1192
+ constructor(doubles) {
1193
+ super({
1194
+ form: DdbForm.set,
1195
+ type: DdbType.double,
1196
+ length: 0,
1197
+ rows: doubles instanceof Set ?
1198
+ doubles.size
1199
+ :
1200
+ doubles.length,
1201
+ cols: 1,
1202
+ value: doubles instanceof Int32Array ?
1203
+ doubles
1204
+ :
1205
+ Int32Array.from(doubles, v => v === null ?
1206
+ exports.nulls.int32
1207
+ :
1208
+ v),
1209
+ });
1210
+ }
1211
+ }
1212
+ exports.DdbSetDouble = DdbSetDouble;
1213
+ class DdbSetString extends DdbObj {
1214
+ constructor(strings) {
1215
+ if (strings instanceof Set)
1216
+ strings = [...strings];
1217
+ super({
1218
+ form: DdbForm.set,
1219
+ type: DdbType.string,
1220
+ length: 0,
1221
+ rows: strings.length,
1222
+ cols: 1,
1223
+ value: strings
1224
+ });
1225
+ }
1226
+ }
1227
+ exports.DdbSetString = DdbSetString;
1157
1228
  class DdbTable extends DdbObj {
1158
1229
  constructor(columns, name = '') {
1159
1230
  super({
@@ -1270,6 +1341,8 @@ class DDB {
1270
1341
 
1271
1342
  @example
1272
1343
  let ddb = new DDB('ws://127.0.0.1:8848')
1344
+
1345
+ // Encrypt with HTTPS
1273
1346
  let ddbsecure = new DDB('wss://dolphindb.com', {
1274
1347
  autologin: true,
1275
1348
  username: 'admin',
@@ -1294,7 +1367,12 @@ class DDB {
1294
1367
  this.password = '123456';
1295
1368
  /** python session flag (2048) */
1296
1369
  this.python = false;
1297
- this.message_hook = null;
1370
+ this.print_message_buffer = false;
1371
+ this.print_object_buffer = false;
1372
+ this.print_message = true;
1373
+ this.parse_object = true;
1374
+ /** message handlers */
1375
+ this.handlers = [];
1298
1376
  this.presult = Promise.resolve(null);
1299
1377
  if (!url) {
1300
1378
  const _url = new URL(location.href);
@@ -1312,12 +1390,8 @@ class DDB {
1312
1390
  if (options.python !== undefined)
1313
1391
  this.python = options.python;
1314
1392
  }
1315
- /** print message handler */
1316
- printer(message) {
1317
- console.log(message);
1318
- }
1319
1393
  /** resolver, rejector, promise of last rpc */
1320
- presolver(buf) { }
1394
+ presolver(ddbobj) { }
1321
1395
  prejector(error) { }
1322
1396
  get connected() {
1323
1397
  return this.websocket?.readyState === WebSocket.OPEN;
@@ -1342,58 +1416,74 @@ class DDB {
1342
1416
  if (options.python !== undefined)
1343
1417
  this.python = options.python;
1344
1418
  this.disconnect();
1345
- let websocket = new WebSocket(this.url, this.python ? ['python'] : []);
1346
- // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
1347
- websocket.binaryType = 'arraybuffer';
1348
- this.websocket = websocket;
1349
- await new Promise((resolve, reject) => {
1350
- websocket.addEventListener('open', async (event) => {
1351
- console.log(`${websocket.url} opened`);
1419
+ await (0, net_browser_js_1.connect_websocket)(this.url, {
1420
+ protocols: this.python ? ['python'] : [],
1421
+ on_open: async (event, websocket) => {
1422
+ this.websocket = websocket;
1352
1423
  await this.rpc('connect', {});
1353
- resolve();
1354
- });
1355
- websocket.addEventListener('close', event => {
1356
- console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
1357
- });
1358
- websocket.addEventListener('error', event => {
1359
- const message = `${websocket.url} errored`;
1360
- console.error(message, event);
1361
- reject(Object.assign(new Error(message), { event }));
1362
- });
1363
- websocket.addEventListener('message', event => {
1424
+ },
1425
+ on_message: event => {
1364
1426
  const buf = new Uint8Array(event.data);
1365
- if (this.message_hook)
1366
- this.message_hook(buf);
1367
- try {
1368
- const { type, data } = this.parse_message(buf);
1369
- if (type === 'message') {
1370
- this.printer(data);
1371
- return;
1372
- }
1373
- this.presolver(data);
1427
+ if (this.print_message_buffer)
1428
+ console.log(buf);
1429
+ const message = this.parse_message(buf);
1430
+ if (this.handlers.length) {
1431
+ const _handlers = [...this.handlers].reverse();
1432
+ for (const handler of _handlers)
1433
+ handler(message, this);
1374
1434
  }
1375
- catch (error) {
1376
- this.prejector(error);
1435
+ const { type, data } = message;
1436
+ switch (type) {
1437
+ case 'print':
1438
+ if (this.print_message)
1439
+ console.log(data);
1440
+ return;
1441
+ case 'object':
1442
+ if (this.print_object_buffer)
1443
+ console.log(data.buffer);
1444
+ this.presolver(data);
1445
+ return;
1446
+ case 'error':
1447
+ this.prejector(data);
1448
+ return;
1377
1449
  }
1378
- });
1450
+ }
1379
1451
  });
1380
- if (!this.python)
1381
- await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
1452
+ await this.eval(this.python ?
1453
+ 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
1382
1454
  ' nargs = size(args)\n' +
1383
1455
  ' func = funcByName(func_name)\n' +
1384
1456
  ' \n' +
1385
- ' if (!nargs)\n' +
1457
+ ' if not nargs:\n' +
1386
1458
  ' return pnodeRun(func, nodes, add_node_alias)\n' +
1387
1459
  ' \n' +
1388
- ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
1389
- ' args_partial[0] = func\n' +
1390
- ' args_partial[1:] = args\n' +
1460
+ ' args_partial = [ ]\n' +
1461
+ ' args_partial.append(func)\n' +
1462
+ ' for a in args:\n' +
1463
+ ' args_partial.append(a)\n' +
1464
+ ' \n' +
1391
1465
  ' return pnodeRun(\n' +
1392
1466
  ' unifiedCall(partial, args_partial),\n' +
1393
1467
  ' nodes,\n' +
1394
1468
  ' add_node_alias\n' +
1395
- ' )\n' +
1396
- '}\n', { urgent: true });
1469
+ ' )\n'
1470
+ :
1471
+ 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
1472
+ ' nargs = size(args)\n' +
1473
+ ' func = funcByName(func_name)\n' +
1474
+ ' \n' +
1475
+ ' if (!nargs)\n' +
1476
+ ' return pnodeRun(func, nodes, add_node_alias)\n' +
1477
+ ' \n' +
1478
+ ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
1479
+ ' args_partial[0] = func\n' +
1480
+ ' args_partial[1:] = args\n' +
1481
+ ' return pnodeRun(\n' +
1482
+ ' unifiedCall(partial, args_partial),\n' +
1483
+ ' nodes,\n' +
1484
+ ' add_node_alias\n' +
1485
+ ' )\n' +
1486
+ '}\n', { urgent: true });
1397
1487
  if (this.autologin)
1398
1488
  if (this.python)
1399
1489
  await this.eval(`login(${this.username.quote('double')}, ${this.password.quote('double')})`, { urgent: true });
@@ -1429,7 +1519,7 @@ class DDB {
1429
1519
  limit,
1430
1520
  ] : [],
1431
1521
  ];
1432
- return `/ ${options.join('_')}`;
1522
+ return options.join('_');
1433
1523
  }
1434
1524
  disconnect() {
1435
1525
  if (this.connected)
@@ -1443,8 +1533,11 @@ class DDB {
1443
1533
  - options:
1444
1534
  - urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
1445
1535
  - vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
1536
+ - handler?: 处理本次 rpc 期间的消息
1537
+ - parse_object?: 在本次 rpc 期间设置 parse_object, 结束后恢复原有
1538
+ 为 false 时返回的 DdbObj 仅含有 buffer 和 le,不做解析,以便后续转发、序列化
1446
1539
  */
1447
- async rpc(type, { script, func, args = [], vars = [], urgent, }) {
1540
+ async rpc(type, { script, func, args = [], vars = [], urgent, handler, parse_object, }) {
1448
1541
  if (!this.websocket)
1449
1542
  await this.connect();
1450
1543
  if (!this.connected)
@@ -1491,35 +1584,52 @@ class DDB {
1491
1584
  }
1492
1585
  })());
1493
1586
  const message = (0, utils_browser_1.concat)([
1494
- this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
1587
+ this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
1495
1588
  command,
1496
1589
  ...args.map((arg) => arg.pack())
1497
1590
  ]);
1498
- this.websocket.send(message);
1499
- return DdbObj.parse(await presult, // data_buf
1500
- this.le);
1591
+ const _parse_object = this.parse_object;
1592
+ if (handler)
1593
+ this.handlers.push(handler);
1594
+ if (parse_object !== undefined)
1595
+ this.parse_object = parse_object;
1596
+ try {
1597
+ this.websocket.send(message);
1598
+ return (await presult);
1599
+ }
1600
+ finally {
1601
+ if (handler)
1602
+ this.handlers = this.handlers.filter(h => h !== handler);
1603
+ this.parse_object = _parse_object;
1604
+ }
1501
1605
  }
1502
- /** eval script through websocket (script command) */
1503
- async eval(
1504
- /** 执行的脚本 */
1505
- script,
1506
- /** 执行选项 */
1507
- { urgent } = {}) {
1508
- return this.rpc('script', { script, urgent });
1606
+ /** eval script through websocket (script command)
1607
+ - script?: Script to execute
1608
+ - options?: execution options
1609
+ - urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
1610
+ - handler?: Process messages during this rpc
1611
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
1612
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
1613
+ so as to facilitate subsequent forwarding and serialization
1614
+ */
1615
+ async eval(script, { urgent, handler, parse_object, } = {}) {
1616
+ return this.rpc('script', { script, urgent, handler, parse_object });
1509
1617
  }
1510
1618
  /** call function through websocket (function command)
1511
- - func: 函数名
1512
- - args?: `[ ]` 调用参数 (传入的原生 string 和 boolean 会被自动转换为 DdbObj<string> 和 DdbObj<boolean>)
1513
- - options?: 调用选项
1514
- - urgent?: 紧急 flag。使用 urgent worker 执行,防止被其它作业阻塞
1515
- - node?: 设置结点 alias 时发送到集群中对应的结点执行 (使用 DolphinDB 中的 rpc 方法)
1516
- - nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
1517
- - func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
1518
- - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
1619
+ - func: function name
1620
+ - args?: `[ ]` Call parameters (the incoming native string and boolean will be automatically converted to DdbObj<string> and DdbObj<boolean>)
1621
+ - options?: call options
1622
+ - urgent?: Emergency flag. Use urgent worker execution to prevent being blocked by other jobs
1623
+ - 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)
1624
+ - nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
1625
+ - 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
1626
+ - add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
1627
+ - handler?: Process messages during this rpc
1628
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
1629
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
1630
+ so as to facilitate subsequent forwarding and serialization
1519
1631
  */
1520
- async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
1521
- if (this.python)
1522
- throw new Error('call doesn\'t support python session yet');
1632
+ async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, handler, parse_object, } = {}) {
1523
1633
  if (node) {
1524
1634
  if (typeof func_type === 'undefined')
1525
1635
  throw new Error('指定 node 时必须设置 func_type');
@@ -1549,6 +1659,8 @@ class DDB {
1549
1659
  func,
1550
1660
  args,
1551
1661
  urgent,
1662
+ handler,
1663
+ parse_object
1552
1664
  });
1553
1665
  }
1554
1666
  /** upload variable through websocket (variable command) */
@@ -1556,19 +1668,19 @@ class DDB {
1556
1668
  /** Uploaded variables' name */
1557
1669
  vars,
1558
1670
  /** Uploaded variables' value */
1559
- args) {
1671
+ args, { handler, parse_object, } = {}) {
1560
1672
  if (!args.length || args.length !== vars.length)
1561
1673
  throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
1562
- return this.rpc('variable', { vars, args });
1674
+ return this.rpc('variable', { vars, args, handler, parse_object });
1563
1675
  }
1564
1676
  /** 解析服务端响应报文,返回去掉 header 的 data buf */
1565
- parse_message(buf) {
1677
+ parse_message(buf, parse_object = this.parse_object) {
1566
1678
  // MSG\n
1567
1679
  // <message>\0
1568
1680
  // 'M'.codePointAt(0).to_hex_str()
1569
1681
  if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
1570
1682
  return {
1571
- type: 'message',
1683
+ type: 'print',
1572
1684
  data: this.dec.decode(buf.subarray(4))
1573
1685
  };
1574
1686
  // '1166953221 1 1\n'
@@ -1592,10 +1704,23 @@ class DDB {
1592
1704
  /** 'OK' 表示成功,其它文本表示失败 */
1593
1705
  const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
1594
1706
  if (message !== 'OK')
1595
- throw new Error(message);
1707
+ return {
1708
+ type: 'error',
1709
+ data: new Error(message)
1710
+ };
1711
+ const buf_obj = buf.subarray(i_lf_1 + 1);
1596
1712
  return {
1597
1713
  type: 'object',
1598
- data: buf.subarray(i_lf_1 + 1)
1714
+ data: parse_object ?
1715
+ Object.assign(DdbObj.parse(buf_obj, this.le), { buffer: buf_obj })
1716
+ :
1717
+ new DdbObj({
1718
+ form: DdbForm.scalar,
1719
+ type: DdbType.void,
1720
+ length: 0,
1721
+ le: this.le,
1722
+ buffer: buf_obj,
1723
+ })
1599
1724
  };
1600
1725
  }
1601
1726
  /** 自动转换 js string, boolean 为 DdbObj */