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/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- 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.ddb_sizes = exports.DdbType = exports.DdbForm = void 0;
3
+ 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.ddb_sizes = exports.DdbType = exports.DdbForm = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  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
- bool: 0x80,
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 value = buf[0];
288
- return [1, value === exports.nulls.bool ? null : Boolean(value)];
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 value = String.fromCharCode(buf[0]);
292
- return [1, value === exports.nulls.char ? null : value];
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
- this.dec.decode(buf.subarray(0, length))
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
- Uint8Array.of(value === null ?
632
- exports.nulls.bool
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
- Uint8Array.of((value === null ?
639
- exports.nulls.char
639
+ Int8Array.of((value === null ?
640
+ exports.nulls.int8
640
641
  :
641
- value).charCodeAt(0))
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 [this.enc.encode(value)];
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
- if (this.form === DdbForm.pair)
887
- return `${(0, utils_js_1.inspect)(this.value[0], options)}, ${(0, utils_js_1.inspect)(this.value[1], options)}`;
888
- if (this.form === DdbForm.scalar && this.type === DdbType.functiondef)
889
- return (0, utils_js_1.inspect)(this.value.name, options);
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);
@@ -968,7 +975,10 @@ class DdbChar extends DdbObj {
968
975
  form: DdbForm.scalar,
969
976
  type: DdbType.char,
970
977
  length: 1,
971
- value,
978
+ value: typeof value === 'string' ?
979
+ value.charCodeAt(0)
980
+ :
981
+ value
972
982
  });
973
983
  }
974
984
  }
@@ -1094,20 +1104,6 @@ class DdbVectorInt extends DdbObj {
1094
1104
  }
1095
1105
  }
1096
1106
  exports.DdbVectorInt = DdbVectorInt;
1097
- class DdbVectorString extends DdbObj {
1098
- constructor(strings, name) {
1099
- super({
1100
- form: DdbForm.vector,
1101
- type: DdbType.string,
1102
- length: 0,
1103
- rows: strings.length,
1104
- cols: 1,
1105
- value: strings,
1106
- name,
1107
- });
1108
- }
1109
- }
1110
- exports.DdbVectorString = DdbVectorString;
1111
1107
  class DdbVectorDouble extends DdbObj {
1112
1108
  constructor(doubles, name) {
1113
1109
  super({
@@ -1128,6 +1124,20 @@ class DdbVectorDouble extends DdbObj {
1128
1124
  }
1129
1125
  }
1130
1126
  exports.DdbVectorDouble = DdbVectorDouble;
1127
+ class DdbVectorString extends DdbObj {
1128
+ constructor(strings, name) {
1129
+ super({
1130
+ form: DdbForm.vector,
1131
+ type: DdbType.string,
1132
+ length: 0,
1133
+ rows: strings.length,
1134
+ cols: 1,
1135
+ value: strings,
1136
+ name,
1137
+ });
1138
+ }
1139
+ }
1140
+ exports.DdbVectorString = DdbVectorString;
1131
1141
  class DdbVectorAny extends DdbObj {
1132
1142
  constructor(objs, name) {
1133
1143
  super({
@@ -1173,6 +1183,65 @@ class DdbVectorSymbol extends DdbObj {
1173
1183
  }
1174
1184
  }
1175
1185
  exports.DdbVectorSymbol = DdbVectorSymbol;
1186
+ class DdbSetInt extends DdbObj {
1187
+ constructor(ints) {
1188
+ super({
1189
+ form: DdbForm.set,
1190
+ type: DdbType.int,
1191
+ length: 0,
1192
+ rows: ints instanceof Set ?
1193
+ ints.size
1194
+ :
1195
+ ints.length,
1196
+ cols: 1,
1197
+ value: ints instanceof Int32Array ?
1198
+ ints
1199
+ :
1200
+ Int32Array.from(ints, v => v === null ?
1201
+ exports.nulls.int32
1202
+ :
1203
+ v),
1204
+ });
1205
+ }
1206
+ }
1207
+ exports.DdbSetInt = DdbSetInt;
1208
+ class DdbSetDouble extends DdbObj {
1209
+ constructor(doubles) {
1210
+ super({
1211
+ form: DdbForm.set,
1212
+ type: DdbType.double,
1213
+ length: 0,
1214
+ rows: doubles instanceof Set ?
1215
+ doubles.size
1216
+ :
1217
+ doubles.length,
1218
+ cols: 1,
1219
+ value: doubles instanceof Int32Array ?
1220
+ doubles
1221
+ :
1222
+ Int32Array.from(doubles, v => v === null ?
1223
+ exports.nulls.int32
1224
+ :
1225
+ v),
1226
+ });
1227
+ }
1228
+ }
1229
+ exports.DdbSetDouble = DdbSetDouble;
1230
+ class DdbSetString extends DdbObj {
1231
+ constructor(strings) {
1232
+ if (strings instanceof Set)
1233
+ strings = [...strings];
1234
+ super({
1235
+ form: DdbForm.set,
1236
+ type: DdbType.string,
1237
+ length: 0,
1238
+ rows: strings.length,
1239
+ cols: 1,
1240
+ value: strings
1241
+ });
1242
+ }
1243
+ }
1244
+ exports.DdbSetString = DdbSetString;
1176
1245
  class DdbTable extends DdbObj {
1177
1246
  constructor(columns, name = '') {
1178
1247
  super({
@@ -1289,6 +1358,8 @@ class DDB {
1289
1358
 
1290
1359
  @example
1291
1360
  let ddb = new DDB('ws://127.0.0.1:8848')
1361
+
1362
+ // 使用 HTTPS 加密
1292
1363
  let ddbsecure = new DDB('wss://dolphindb.com', {
1293
1364
  autologin: true,
1294
1365
  username: 'admin',
@@ -1302,7 +1373,6 @@ class DDB {
1302
1373
  /** utf-8 text decoder */
1303
1374
  this.dec = new TextDecoder('utf-8');
1304
1375
  this.enc = new TextEncoder();
1305
- this.print_buffer = false;
1306
1376
  this.websocket = null;
1307
1377
  /** little endian (server) */
1308
1378
  this.le = true;
@@ -1314,7 +1384,12 @@ class DDB {
1314
1384
  this.password = '123456';
1315
1385
  /** python session flag (2048) */
1316
1386
  this.python = false;
1317
- this.message_hook = null;
1387
+ this.print_message_buffer = false;
1388
+ this.print_object_buffer = false;
1389
+ this.print_message = true;
1390
+ this.parse_object = true;
1391
+ /** message handlers */
1392
+ this.handlers = [];
1318
1393
  this.presult = Promise.resolve(null);
1319
1394
  this.url = url;
1320
1395
  if (options.autologin !== undefined)
@@ -1326,12 +1401,8 @@ class DDB {
1326
1401
  if (options.python !== undefined)
1327
1402
  this.python = options.python;
1328
1403
  }
1329
- /** print message handler */
1330
- printer(message) {
1331
- console.log(message);
1332
- }
1333
1404
  /** resolver, rejector, promise of last rpc */
1334
- presolver(buf) { }
1405
+ presolver(ddbobj) { }
1335
1406
  prejector(error) { }
1336
1407
  get connected() {
1337
1408
  return this.websocket?.readyState === ws_1.WebSocket.OPEN;
@@ -1356,60 +1427,74 @@ class DDB {
1356
1427
  if (options.python !== undefined)
1357
1428
  this.python = options.python;
1358
1429
  this.disconnect();
1359
- let websocket = new ws_1.WebSocket(this.url, this.python ? ['python'] : [], {
1360
- maxPayload: 2 ** 33 // 8 GB
1361
- });
1362
- // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
1363
- websocket.binaryType = 'arraybuffer';
1364
- this.websocket = websocket;
1365
- await new Promise((resolve, reject) => {
1366
- websocket.addEventListener('open', async (event) => {
1367
- console.log(`${websocket.url} opened`);
1430
+ await (0, net_js_1.connect_websocket)(this.url, {
1431
+ protocols: this.python ? ['python'] : [],
1432
+ on_open: async (event, websocket) => {
1433
+ this.websocket = websocket;
1368
1434
  await this.rpc('connect', {});
1369
- resolve();
1370
- });
1371
- websocket.addEventListener('close', event => {
1372
- console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
1373
- });
1374
- websocket.addEventListener('error', event => {
1375
- const message = `${websocket.url} errored`;
1376
- console.error(message, event);
1377
- reject(Object.assign(new Error(message), { event }));
1378
- });
1379
- websocket.addEventListener('message', event => {
1435
+ },
1436
+ on_message: event => {
1380
1437
  const buf = new Uint8Array(event.data);
1381
- if (this.message_hook)
1382
- this.message_hook(buf);
1383
- try {
1384
- const { type, data } = this.parse_message(buf);
1385
- if (type === 'message') {
1386
- this.printer(data);
1387
- return;
1388
- }
1389
- this.presolver(data);
1438
+ if (this.print_message_buffer)
1439
+ console.log((0, utils_js_1.typed_array_to_buffer)(buf));
1440
+ const message = this.parse_message(buf);
1441
+ if (this.handlers.length) {
1442
+ const _handlers = [...this.handlers].reverse();
1443
+ for (const handler of _handlers)
1444
+ handler(message, this);
1390
1445
  }
1391
- catch (error) {
1392
- this.prejector(error);
1446
+ const { type, data } = message;
1447
+ switch (type) {
1448
+ case 'print':
1449
+ if (this.print_message)
1450
+ console.log(data);
1451
+ return;
1452
+ case 'object':
1453
+ if (this.print_object_buffer)
1454
+ console.log((0, utils_js_1.typed_array_to_buffer)(data.buffer));
1455
+ this.presolver(data);
1456
+ return;
1457
+ case 'error':
1458
+ this.prejector(data);
1459
+ return;
1393
1460
  }
1394
- });
1461
+ }
1395
1462
  });
1396
- if (!this.python)
1397
- await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
1463
+ await this.eval(this.python ?
1464
+ 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
1398
1465
  ' nargs = size(args)\n' +
1399
1466
  ' func = funcByName(func_name)\n' +
1400
1467
  ' \n' +
1401
- ' if (!nargs)\n' +
1468
+ ' if not nargs:\n' +
1402
1469
  ' return pnodeRun(func, nodes, add_node_alias)\n' +
1403
1470
  ' \n' +
1404
- ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
1405
- ' args_partial[0] = func\n' +
1406
- ' args_partial[1:] = args\n' +
1471
+ ' args_partial = [ ]\n' +
1472
+ ' args_partial.append(func)\n' +
1473
+ ' for a in args:\n' +
1474
+ ' args_partial.append(a)\n' +
1475
+ ' \n' +
1407
1476
  ' return pnodeRun(\n' +
1408
1477
  ' unifiedCall(partial, args_partial),\n' +
1409
1478
  ' nodes,\n' +
1410
1479
  ' add_node_alias\n' +
1411
- ' )\n' +
1412
- '}\n', { urgent: true });
1480
+ ' )\n'
1481
+ :
1482
+ 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
1483
+ ' nargs = size(args)\n' +
1484
+ ' func = funcByName(func_name)\n' +
1485
+ ' \n' +
1486
+ ' if (!nargs)\n' +
1487
+ ' return pnodeRun(func, nodes, add_node_alias)\n' +
1488
+ ' \n' +
1489
+ ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
1490
+ ' args_partial[0] = func\n' +
1491
+ ' args_partial[1:] = args\n' +
1492
+ ' return pnodeRun(\n' +
1493
+ ' unifiedCall(partial, args_partial),\n' +
1494
+ ' nodes,\n' +
1495
+ ' add_node_alias\n' +
1496
+ ' )\n' +
1497
+ '}\n', { urgent: true });
1413
1498
  if (this.autologin)
1414
1499
  if (this.python)
1415
1500
  await this.eval(`login(${this.username.quote('double')}, ${this.password.quote('double')})`, { urgent: true });
@@ -1445,7 +1530,7 @@ class DDB {
1445
1530
  limit,
1446
1531
  ] : [],
1447
1532
  ];
1448
- return `/ ${options.join('_')}`;
1533
+ return options.join('_');
1449
1534
  }
1450
1535
  disconnect() {
1451
1536
  if (this.connected)
@@ -1459,8 +1544,11 @@ class DDB {
1459
1544
  - options:
1460
1545
  - urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
1461
1546
  - vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
1547
+ - handler?: 处理本次 rpc 期间的消息
1548
+ - parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
1549
+ 不做解析,以便后续转发、序列化
1462
1550
  */
1463
- async rpc(type, { script, func, args = [], vars = [], urgent, }) {
1551
+ async rpc(type, { script, func, args = [], vars = [], urgent, handler, parse_object, }) {
1464
1552
  if (!this.websocket)
1465
1553
  await this.connect();
1466
1554
  if (!this.connected)
@@ -1507,25 +1595,35 @@ class DDB {
1507
1595
  }
1508
1596
  })());
1509
1597
  const message = (0, utils_js_1.concat)([
1510
- this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
1598
+ this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
1511
1599
  command,
1512
1600
  ...args.map((arg) => arg.pack())
1513
1601
  ]);
1514
- this.websocket.send(message);
1515
- const buf_data = await presult;
1516
- if (this.print_buffer)
1517
- console.log((0, utils_js_1.typed_array_to_buffer)(buf_data));
1518
- // LOCAL: 便于 repl
1519
- // return global.DdbObj.parse(data_buf) as DdbObj
1520
- return DdbObj.parse(buf_data, this.le);
1602
+ const _parse_object = this.parse_object;
1603
+ if (handler)
1604
+ this.handlers.push(handler);
1605
+ if (parse_object !== undefined)
1606
+ this.parse_object = parse_object;
1607
+ try {
1608
+ this.websocket.send(message);
1609
+ return (await presult);
1610
+ }
1611
+ finally {
1612
+ if (handler)
1613
+ this.handlers = this.handlers.filter(h => h !== handler);
1614
+ this.parse_object = _parse_object;
1615
+ }
1521
1616
  }
1522
- /** eval script through websocket (script command) */
1523
- async eval(
1524
- /** 执行的脚本 */
1525
- script,
1526
- /** 执行选项 */
1527
- { urgent } = {}) {
1528
- return this.rpc('script', { script, urgent });
1617
+ /** eval script through websocket (script command)
1618
+ - script?: 执行的脚本
1619
+ - options?: 执行选项
1620
+ - urgent?: 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞
1621
+ - handler?: 处理本次 rpc 期间的消息
1622
+ - parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
1623
+ 不做解析,以便后续转发、序列化
1624
+ */
1625
+ async eval(script, { urgent, handler, parse_object, } = {}) {
1626
+ return this.rpc('script', { script, urgent, handler, parse_object });
1529
1627
  }
1530
1628
  /** call function through websocket (function command)
1531
1629
  - func: 函数名
@@ -1536,10 +1634,11 @@ class DDB {
1536
1634
  - nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
1537
1635
  - func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
1538
1636
  - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
1637
+ - handler?: 处理本次 rpc 期间的消息
1638
+ - parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
1639
+ 不做解析,以便后续转发、序列化
1539
1640
  */
1540
- async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
1541
- if (this.python)
1542
- throw new Error('call doesn\'t support python session yet');
1641
+ async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, handler, parse_object, } = {}) {
1543
1642
  if (node) {
1544
1643
  if (typeof func_type === 'undefined')
1545
1644
  throw new Error('指定 node 时必须设置 func_type');
@@ -1569,6 +1668,8 @@ class DDB {
1569
1668
  func,
1570
1669
  args,
1571
1670
  urgent,
1671
+ handler,
1672
+ parse_object
1572
1673
  });
1573
1674
  }
1574
1675
  /** upload variable through websocket (variable command) */
@@ -1576,19 +1677,19 @@ class DDB {
1576
1677
  /** Uploaded variables' name */
1577
1678
  vars,
1578
1679
  /** Uploaded variables' value */
1579
- args) {
1680
+ args, { handler, parse_object, } = {}) {
1580
1681
  if (!args.length || args.length !== vars.length)
1581
- throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
1582
- return this.rpc('variable', { vars, args });
1682
+ throw new Error('variable command parameter is empty or parameter name is empty, or the number does not match');
1683
+ return this.rpc('variable', { vars, args, handler, parse_object });
1583
1684
  }
1584
1685
  /** 解析服务端响应报文,返回去掉 header 的 data buf */
1585
- parse_message(buf) {
1686
+ parse_message(buf, parse_object = this.parse_object) {
1586
1687
  // MSG\n
1587
1688
  // <message>\0
1588
1689
  // 'M'.codePointAt(0).to_hex_str()
1589
1690
  if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
1590
1691
  return {
1591
- type: 'message',
1692
+ type: 'print',
1592
1693
  data: this.dec.decode(buf.subarray(4))
1593
1694
  };
1594
1695
  // '1166953221 1 1\n'
@@ -1612,10 +1713,23 @@ class DDB {
1612
1713
  /** 'OK' 表示成功,其它文本表示失败 */
1613
1714
  const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
1614
1715
  if (message !== 'OK')
1615
- throw new Error(message);
1716
+ return {
1717
+ type: 'error',
1718
+ data: new Error(message)
1719
+ };
1720
+ const buf_obj = buf.subarray(i_lf_1 + 1);
1616
1721
  return {
1617
1722
  type: 'object',
1618
- data: buf.subarray(i_lf_1 + 1)
1723
+ data: parse_object ?
1724
+ Object.assign(DdbObj.parse(buf_obj, this.le), { buffer: buf_obj })
1725
+ :
1726
+ new DdbObj({
1727
+ form: DdbForm.scalar,
1728
+ type: DdbType.void,
1729
+ length: 0,
1730
+ le: this.le,
1731
+ buffer: buf_obj,
1732
+ })
1619
1733
  };
1620
1734
  }
1621
1735
  /** 自动转换 js string, boolean 为 DdbObj */