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 CHANGED
@@ -75,11 +75,10 @@ export interface DdbArrayVectorBlock {
75
75
  lengths: Uint8Array | Uint16Array | Uint32Array;
76
76
  data: DdbVectorValue;
77
77
  }
78
- export declare type DdbValue = null | boolean | number | [number, number] | bigint | string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
79
- export declare type DdbVectorValue = string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
78
+ export declare type DdbValue = null | boolean | number | [number, number] | bigint | string | string[] | Uint8Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
79
+ export declare type DdbVectorValue = string | string[] | Uint8Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
80
80
  export declare const nulls: {
81
- readonly bool: 128;
82
- readonly char: "€";
81
+ readonly int8: -128;
83
82
  readonly int16: -32768;
84
83
  readonly int32: -2147483648;
85
84
  readonly int64: -9223372036854775808n;
@@ -125,6 +124,8 @@ export declare class DdbObj<T extends DdbValue = DdbValue> {
125
124
  datatype?: DdbType;
126
125
  /** 实际数据。不同的 DdbForm, DdbType 使用 DdbValue 中不同的类型来表示实际数据 */
127
126
  value: T;
127
+ /** 原始二进制数据 */
128
+ buffer?: Uint8Array;
128
129
  constructor(data: Partial<DdbObj> & {
129
130
  form: DdbForm;
130
131
  type: DdbType;
@@ -159,7 +160,7 @@ export declare class DdbBool extends DdbObj<boolean> {
159
160
  constructor(value: boolean | null);
160
161
  }
161
162
  export declare class DdbChar extends DdbObj<string> {
162
- constructor(value: string | null);
163
+ constructor(value: string | number | null);
163
164
  }
164
165
  export declare class DdbInt extends DdbObj<number> {
165
166
  constructor(value: number | null);
@@ -270,13 +271,13 @@ export declare class DDB {
270
271
  password: string;
271
272
  /** python session flag (2048) */
272
273
  python: boolean;
273
- message_hook: (message: Uint8Array) => any;
274
- /** print message handler */
275
- printer(message: string): void;
274
+ parse_object: boolean;
275
+ /** message handler */
276
+ on_message({ type, data }: DdbMessage, _this: DDB): void;
276
277
  /** resolver, rejector, promise of last rpc */
277
- presolver(buf: Uint8Array): void;
278
+ presolver(message: DdbMessage): void;
278
279
  prejector(error: Error): void;
279
- presult: Promise<Uint8Array>;
280
+ presult: Promise<DdbMessage>;
280
281
  get connected(): boolean;
281
282
  /**
282
283
  Initialize an instance of DolphinDB Client using the WebSocket URL
@@ -349,58 +350,80 @@ export declare class DDB {
349
350
  - options:
350
351
  - urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
351
352
  - vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
353
+ - on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
354
+ - parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
355
+ 不做解析,以便后续转发、序列化
352
356
  */
353
- rpc<T extends DdbObj = DdbObj>(type: 'script' | 'function' | 'variable' | 'connect', { script, func, args, vars, urgent, }: {
357
+ rpc<T extends DdbObj = DdbObj>(type: 'script' | 'function' | 'variable' | 'connect', { script, func, args, vars, urgent, on_message, parse_object, }: {
354
358
  script?: string;
355
359
  func?: string;
356
360
  args?: (DdbObj | string | boolean)[];
357
361
  vars?: string[];
358
362
  urgent?: boolean;
363
+ on_message?: DDB['on_message'];
364
+ parse_object?: boolean;
359
365
  }): Promise<T>;
360
- /** eval script through websocket (script command) */
361
- eval<T extends DdbObj>(
362
- /** 执行的脚本 */
363
- script: string,
364
- /** 执行选项 */
365
- { urgent }?: {
366
- /** 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞 */
366
+ /** eval script through websocket (script command)
367
+ - script?: Script to execute
368
+ - options?: execution options
369
+ - urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
370
+ - on_message?: Set the message handler during this rpc, and restore the original after the end
371
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
372
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
373
+ so as to facilitate subsequent forwarding and serialization
374
+ */
375
+ eval<T extends DdbObj>(script: string, { urgent, on_message, parse_object, }?: {
367
376
  urgent?: boolean;
377
+ on_message?: DDB['on_message'];
378
+ parse_object?: boolean;
368
379
  }): Promise<T>;
369
380
  /** call function through websocket (function command)
370
- - func: 函数名
371
- - args?: `[ ]` 调用参数 (传入的原生 string 和 boolean 会被自动转换为 DdbObj<string> 和 DdbObj<boolean>)
372
- - options?: 调用选项
373
- - urgent?: 紧急 flag。使用 urgent worker 执行,防止被其它作业阻塞
374
- - node?: 设置结点 alias 时发送到集群中对应的结点执行 (使用 DolphinDB 中的 rpc 方法)
375
- - nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
376
- - func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
377
- - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
381
+ - func: function name
382
+ - args?: `[ ]` Call parameters (the incoming native string and boolean will be automatically converted to DdbObj<string> and DdbObj<boolean>)
383
+ - options?: call options
384
+ - urgent?: Emergency flag. Use urgent worker execution to prevent being blocked by other jobs
385
+ - 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)
386
+ - nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
387
+ - 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
388
+ - add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
389
+ - on_message?: Set the message handler during this rpc, and restore the original after the end
390
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
391
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
392
+ so as to facilitate subsequent forwarding and serialization
378
393
  */
379
- call<T extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias }?: {
394
+ call<T extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias, on_message, parse_object, }?: {
380
395
  urgent?: boolean;
381
396
  node?: string;
382
397
  nodes?: string[];
383
398
  func_type?: DdbFunctionType;
384
399
  add_node_alias?: boolean;
400
+ on_message?: DDB['on_message'];
401
+ parse_object?: boolean;
385
402
  }): Promise<T>;
386
403
  /** upload variable through websocket (variable command) */
387
404
  upload(
388
405
  /** Uploaded variables' name */
389
406
  vars: string[],
390
407
  /** Uploaded variables' value */
391
- args: (DdbObj | string | boolean)[]): Promise<DdbObj<DdbValue>>;
408
+ args: (DdbObj | string | boolean)[], { on_message, parse_object, }?: {
409
+ on_message?: DDB['on_message'];
410
+ parse_object?: boolean;
411
+ }): Promise<DdbObj<DdbValue>>;
392
412
  /** 解析服务端响应报文,返回去掉 header 的 data buf */
393
- parse_message(buf: Uint8Array): {
394
- type: "message";
395
- data: string;
396
- } | {
397
- type: "object";
398
- data: Uint8Array;
399
- };
413
+ parse_message(buf: Uint8Array, parse_object?: boolean): DdbMessage;
400
414
  /** 自动转换 js string, boolean 为 DdbObj */
401
415
  to_ddbobj(value: DdbObj | string | boolean): DdbObj;
402
416
  /** 转换 js 数组为 DdbObj[] */
403
417
  to_ddbobjs(values: any[]): DdbObj<DdbValue>[];
404
418
  }
419
+ export interface DdbPrintMessage {
420
+ type: 'print';
421
+ data: string;
422
+ }
423
+ export interface DdbObjectMessage {
424
+ type: 'object';
425
+ data: DdbObj;
426
+ }
427
+ export declare type DdbMessage = DdbPrintMessage | DdbObjectMessage;
405
428
  export declare let ddb: DDB;
406
429
  export default ddb;
package/browser.js CHANGED
@@ -7,6 +7,7 @@ const customParseFormat_js_1 = tslib_1.__importDefault(require("dayjs/plugin/cus
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
  }
@@ -1355,7 +1367,7 @@ class DDB {
1355
1367
  this.password = '123456';
1356
1368
  /** python session flag (2048) */
1357
1369
  this.python = false;
1358
- this.message_hook = null;
1370
+ this.parse_object = true;
1359
1371
  this.presult = Promise.resolve(null);
1360
1372
  if (!url) {
1361
1373
  const _url = new URL(location.href);
@@ -1373,12 +1385,16 @@ class DDB {
1373
1385
  if (options.python !== undefined)
1374
1386
  this.python = options.python;
1375
1387
  }
1376
- /** print message handler */
1377
- printer(message) {
1378
- console.log(message);
1388
+ /** message handler */
1389
+ on_message({ type, data }, _this) {
1390
+ switch (type) {
1391
+ case 'print':
1392
+ console.log(data);
1393
+ return;
1394
+ }
1379
1395
  }
1380
1396
  /** resolver, rejector, promise of last rpc */
1381
- presolver(buf) { }
1397
+ presolver(message) { }
1382
1398
  prejector(error) { }
1383
1399
  get connected() {
1384
1400
  return this.websocket?.readyState === WebSocket.OPEN;
@@ -1403,40 +1419,25 @@ class DDB {
1403
1419
  if (options.python !== undefined)
1404
1420
  this.python = options.python;
1405
1421
  this.disconnect();
1406
- let websocket = new WebSocket(this.url, this.python ? ['python'] : []);
1407
- // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
1408
- websocket.binaryType = 'arraybuffer';
1409
- this.websocket = websocket;
1410
- await new Promise((resolve, reject) => {
1411
- websocket.addEventListener('open', async (event) => {
1412
- console.log(`${websocket.url} opened`);
1422
+ await (0, net_browser_js_1.connect_websocket)(this.url, {
1423
+ protocols: this.python ? ['python'] : [],
1424
+ on_open: async (event, websocket) => {
1425
+ this.websocket = websocket;
1413
1426
  await this.rpc('connect', {});
1414
- resolve();
1415
- });
1416
- websocket.addEventListener('close', event => {
1417
- console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
1418
- });
1419
- websocket.addEventListener('error', event => {
1420
- const message = `${websocket.url} errored`;
1421
- console.error(message, event);
1422
- reject(Object.assign(new Error(message), { event }));
1423
- });
1424
- websocket.addEventListener('message', event => {
1427
+ },
1428
+ on_message: event => {
1425
1429
  const buf = new Uint8Array(event.data);
1426
- if (this.message_hook)
1427
- this.message_hook(buf);
1428
1430
  try {
1429
- const { type, data } = this.parse_message(buf);
1430
- if (type === 'message') {
1431
- this.printer(data);
1431
+ const message = this.parse_message(buf);
1432
+ this.on_message(message, this);
1433
+ if (message.type === 'print')
1432
1434
  return;
1433
- }
1434
- this.presolver(data);
1435
+ this.presolver(message);
1435
1436
  }
1436
1437
  catch (error) {
1437
1438
  this.prejector(error);
1438
1439
  }
1439
- });
1440
+ }
1440
1441
  });
1441
1442
  if (!this.python)
1442
1443
  await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
@@ -1490,7 +1491,7 @@ class DDB {
1490
1491
  limit,
1491
1492
  ] : [],
1492
1493
  ];
1493
- return `/ ${options.join('_')}`;
1494
+ return options.join('_');
1494
1495
  }
1495
1496
  disconnect() {
1496
1497
  if (this.connected)
@@ -1504,8 +1505,11 @@ class DDB {
1504
1505
  - options:
1505
1506
  - urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
1506
1507
  - vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
1508
+ - on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
1509
+ - parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
1510
+ 不做解析,以便后续转发、序列化
1507
1511
  */
1508
- async rpc(type, { script, func, args = [], vars = [], urgent, }) {
1512
+ async rpc(type, { script, func, args = [], vars = [], urgent, on_message, parse_object, }) {
1509
1513
  if (!this.websocket)
1510
1514
  await this.connect();
1511
1515
  if (!this.connected)
@@ -1552,33 +1556,53 @@ class DDB {
1552
1556
  }
1553
1557
  })());
1554
1558
  const message = (0, utils_browser_1.concat)([
1555
- this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
1559
+ this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
1556
1560
  command,
1557
1561
  ...args.map((arg) => arg.pack())
1558
1562
  ]);
1559
- this.websocket.send(message);
1560
- return DdbObj.parse(await presult, // data_buf
1561
- this.le);
1563
+ const _on_message = this.on_message;
1564
+ const _parse_object = this.parse_object;
1565
+ if (on_message)
1566
+ this.on_message = on_message;
1567
+ if (parse_object !== undefined)
1568
+ this.parse_object = parse_object;
1569
+ try {
1570
+ this.websocket.send(message);
1571
+ const { data } = (await presult);
1572
+ return data;
1573
+ }
1574
+ finally {
1575
+ this.on_message = _on_message;
1576
+ this.parse_object = _parse_object;
1577
+ }
1562
1578
  }
1563
- /** eval script through websocket (script command) */
1564
- async eval(
1565
- /** 执行的脚本 */
1566
- script,
1567
- /** 执行选项 */
1568
- { urgent } = {}) {
1569
- return this.rpc('script', { script, urgent });
1579
+ /** eval script through websocket (script command)
1580
+ - script?: Script to execute
1581
+ - options?: execution options
1582
+ - urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
1583
+ - on_message?: Set the message handler during this rpc, and restore the original after the end
1584
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
1585
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
1586
+ so as to facilitate subsequent forwarding and serialization
1587
+ */
1588
+ async eval(script, { urgent, on_message, parse_object, } = {}) {
1589
+ return this.rpc('script', { script, urgent, on_message, parse_object });
1570
1590
  }
1571
1591
  /** call function through websocket (function command)
1572
- - func: 函数名
1573
- - args?: `[ ]` 调用参数 (传入的原生 string 和 boolean 会被自动转换为 DdbObj<string> 和 DdbObj<boolean>)
1574
- - options?: 调用选项
1575
- - urgent?: 紧急 flag。使用 urgent worker 执行,防止被其它作业阻塞
1576
- - node?: 设置结点 alias 时发送到集群中对应的结点执行 (使用 DolphinDB 中的 rpc 方法)
1577
- - nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
1578
- - func_type?: 设置 node 参数时必传,需指定函数类型,其它情况下不传
1579
- - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
1592
+ - func: function name
1593
+ - args?: `[ ]` Call parameters (the incoming native string and boolean will be automatically converted to DdbObj<string> and DdbObj<boolean>)
1594
+ - options?: call options
1595
+ - urgent?: Emergency flag. Use urgent worker execution to prevent being blocked by other jobs
1596
+ - 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)
1597
+ - nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
1598
+ - 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
1599
+ - add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
1600
+ - on_message?: Set the message handler during this rpc, and restore the original after the end
1601
+ - parse_object?: Set parse_object during this rpc, and restore the original after the end.
1602
+ When it is false, the returned DdbObj only contains buffer and le without parsing,
1603
+ so as to facilitate subsequent forwarding and serialization
1580
1604
  */
1581
- async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
1605
+ async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, on_message, parse_object, } = {}) {
1582
1606
  if (this.python)
1583
1607
  throw new Error('call doesn\'t support python session yet');
1584
1608
  if (node) {
@@ -1610,6 +1634,8 @@ class DDB {
1610
1634
  func,
1611
1635
  args,
1612
1636
  urgent,
1637
+ on_message,
1638
+ parse_object
1613
1639
  });
1614
1640
  }
1615
1641
  /** upload variable through websocket (variable command) */
@@ -1617,19 +1643,19 @@ class DDB {
1617
1643
  /** Uploaded variables' name */
1618
1644
  vars,
1619
1645
  /** Uploaded variables' value */
1620
- args) {
1646
+ args, { on_message, parse_object, } = {}) {
1621
1647
  if (!args.length || args.length !== vars.length)
1622
1648
  throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
1623
- return this.rpc('variable', { vars, args });
1649
+ return this.rpc('variable', { vars, args, on_message, parse_object });
1624
1650
  }
1625
1651
  /** 解析服务端响应报文,返回去掉 header 的 data buf */
1626
- parse_message(buf) {
1652
+ parse_message(buf, parse_object = this.parse_object) {
1627
1653
  // MSG\n
1628
1654
  // <message>\0
1629
1655
  // 'M'.codePointAt(0).to_hex_str()
1630
1656
  if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
1631
1657
  return {
1632
- type: 'message',
1658
+ type: 'print',
1633
1659
  data: this.dec.decode(buf.subarray(4))
1634
1660
  };
1635
1661
  // '1166953221 1 1\n'
@@ -1654,9 +1680,19 @@ class DDB {
1654
1680
  const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
1655
1681
  if (message !== 'OK')
1656
1682
  throw new Error(message);
1683
+ const buf_obj = buf.subarray(i_lf_1 + 1);
1657
1684
  return {
1658
1685
  type: 'object',
1659
- data: buf.subarray(i_lf_1 + 1)
1686
+ data: parse_object ?
1687
+ Object.assign(DdbObj.parse(buf_obj, this.le), { buffer: buf_obj })
1688
+ :
1689
+ new DdbObj({
1690
+ form: DdbForm.scalar,
1691
+ type: DdbType.void,
1692
+ length: 0,
1693
+ le: this.le,
1694
+ buffer: buf_obj,
1695
+ })
1660
1696
  };
1661
1697
  }
1662
1698
  /** 自动转换 js string, boolean 为 DdbObj */