dolphindb 3.0.2 → 3.0.20

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
@@ -5,13 +5,130 @@ import ipaddrjs from 'ipaddr.js';
5
5
  const { fromByteArray: buf2ipaddr } = ipaddrjs;
6
6
  import 'xshell/prototype.browser.js';
7
7
  import { blue, cyan, green, grey, magenta } from 'xshell/chalk.browser.js';
8
- import { concat, assert, Lock, genid } from 'xshell/utils.browser.js';
8
+ import { concat, assert, Lock, genid, seq, zip_object } from 'xshell/utils.browser.js';
9
9
  import { connect_websocket } from 'xshell/net.browser.js';
10
10
  import { t } from './i18n/index.js';
11
- import { DdbDecimal128Serializor } from './data-types/decimal-128.js';
12
- import { is_decimal_type, is_decimal_null_value, get_duration_unit } from './shared/utils.js';
13
- import { nulls, DdbChartType, DdbDurationUnit, DdbForm, DdbFunctionType, DdbType, DdbVoidType, dictables } from './shared/constants.js';
14
- export * from './shared/constants.js';
11
+ export const nulls = {
12
+ int8: -0x80, // -128
13
+ int16: -0x80_00, // -32768
14
+ int32: -0x80_00_00_00, // -21_4748_3648
15
+ int64: -0x8000000000000000n, // -922_3372_0368_5477_5808
16
+ int128: -0x80000000000000000000000000000000n, // -170_1411_8346_0469_2317_3168_7303_7158_8410_5728
17
+ float32: -3.4028234663852886e+38,
18
+ /** -Number.MAX_VALUE */
19
+ double: -Number.MAX_VALUE,
20
+ bytes16: Uint8Array.from(new Array(16).fill(0))
21
+ };
22
+ export var DdbForm;
23
+ (function (DdbForm) {
24
+ DdbForm[DdbForm["scalar"] = 0] = "scalar";
25
+ DdbForm[DdbForm["vector"] = 1] = "vector";
26
+ DdbForm[DdbForm["pair"] = 2] = "pair";
27
+ DdbForm[DdbForm["matrix"] = 3] = "matrix";
28
+ DdbForm[DdbForm["set"] = 4] = "set";
29
+ DdbForm[DdbForm["dict"] = 5] = "dict";
30
+ DdbForm[DdbForm["table"] = 6] = "table";
31
+ DdbForm[DdbForm["chart"] = 7] = "chart";
32
+ /** 节点内部通信可能会使用,调用函数执行脚本一般不会返回这种类型 */
33
+ DdbForm[DdbForm["chunk"] = 8] = "chunk";
34
+ /** sysobj */
35
+ DdbForm[DdbForm["object"] = 9] = "object";
36
+ })(DdbForm || (DdbForm = {}));
37
+ /** DolphinDB DataType
38
+ 对应的 array vector 类型为 64 + 基本类型
39
+ 对应的 extended 类型为 128 + 基本类型 */
40
+ export var DdbType;
41
+ (function (DdbType) {
42
+ DdbType[DdbType["void"] = 0] = "void";
43
+ DdbType[DdbType["bool"] = 1] = "bool";
44
+ DdbType[DdbType["char"] = 2] = "char";
45
+ DdbType[DdbType["short"] = 3] = "short";
46
+ DdbType[DdbType["int"] = 4] = "int";
47
+ DdbType[DdbType["long"] = 5] = "long";
48
+ DdbType[DdbType["date"] = 6] = "date";
49
+ DdbType[DdbType["month"] = 7] = "month";
50
+ DdbType[DdbType["time"] = 8] = "time";
51
+ DdbType[DdbType["minute"] = 9] = "minute";
52
+ DdbType[DdbType["second"] = 10] = "second";
53
+ DdbType[DdbType["datetime"] = 11] = "datetime";
54
+ DdbType[DdbType["timestamp"] = 12] = "timestamp";
55
+ DdbType[DdbType["nanotime"] = 13] = "nanotime";
56
+ DdbType[DdbType["nanotimestamp"] = 14] = "nanotimestamp";
57
+ DdbType[DdbType["float"] = 15] = "float";
58
+ DdbType[DdbType["double"] = 16] = "double";
59
+ DdbType[DdbType["symbol"] = 17] = "symbol";
60
+ DdbType[DdbType["string"] = 18] = "string";
61
+ DdbType[DdbType["uuid"] = 19] = "uuid";
62
+ DdbType[DdbType["functiondef"] = 20] = "functiondef";
63
+ DdbType[DdbType["handle"] = 21] = "handle";
64
+ DdbType[DdbType["code"] = 22] = "code";
65
+ DdbType[DdbType["datasource"] = 23] = "datasource";
66
+ DdbType[DdbType["resource"] = 24] = "resource";
67
+ DdbType[DdbType["any"] = 25] = "any";
68
+ DdbType[DdbType["compressed"] = 26] = "compressed";
69
+ DdbType[DdbType["dict"] = 27] = "dict";
70
+ DdbType[DdbType["datehour"] = 28] = "datehour";
71
+ DdbType[DdbType["ipaddr"] = 30] = "ipaddr";
72
+ DdbType[DdbType["int128"] = 31] = "int128";
73
+ DdbType[DdbType["blob"] = 32] = "blob";
74
+ DdbType[DdbType["complex"] = 34] = "complex";
75
+ DdbType[DdbType["point"] = 35] = "point";
76
+ DdbType[DdbType["duration"] = 36] = "duration";
77
+ DdbType[DdbType["decimal32"] = 37] = "decimal32";
78
+ DdbType[DdbType["decimal64"] = 38] = "decimal64";
79
+ DdbType[DdbType["decimal128"] = 39] = "decimal128";
80
+ DdbType[DdbType["object"] = 40] = "object";
81
+ DdbType[DdbType["pynone"] = 41] = "pynone";
82
+ DdbType[DdbType["symbol_extended"] = 145] = "symbol_extended";
83
+ })(DdbType || (DdbType = {}));
84
+ export var DdbFunctionType;
85
+ (function (DdbFunctionType) {
86
+ DdbFunctionType[DdbFunctionType["SystemFunc"] = 0] = "SystemFunc";
87
+ DdbFunctionType[DdbFunctionType["SystemProc"] = 1] = "SystemProc";
88
+ DdbFunctionType[DdbFunctionType["OperatorFunc"] = 2] = "OperatorFunc";
89
+ DdbFunctionType[DdbFunctionType["UserDefinedFunc"] = 3] = "UserDefinedFunc";
90
+ DdbFunctionType[DdbFunctionType["PartialFunc"] = 4] = "PartialFunc";
91
+ DdbFunctionType[DdbFunctionType["DynamicFunc"] = 5] = "DynamicFunc";
92
+ DdbFunctionType[DdbFunctionType["PiecewiseFunc"] = 6] = "PiecewiseFunc";
93
+ DdbFunctionType[DdbFunctionType["JitFunc"] = 7] = "JitFunc";
94
+ DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
95
+ })(DdbFunctionType || (DdbFunctionType = {}));
96
+ export var DdbDurationUnit;
97
+ (function (DdbDurationUnit) {
98
+ DdbDurationUnit[DdbDurationUnit["ns"] = 0] = "ns";
99
+ DdbDurationUnit[DdbDurationUnit["us"] = 1] = "us";
100
+ DdbDurationUnit[DdbDurationUnit["ms"] = 2] = "ms";
101
+ DdbDurationUnit[DdbDurationUnit["s"] = 3] = "s";
102
+ DdbDurationUnit[DdbDurationUnit["m"] = 4] = "m";
103
+ DdbDurationUnit[DdbDurationUnit["H"] = 5] = "H";
104
+ DdbDurationUnit[DdbDurationUnit["d"] = 6] = "d";
105
+ DdbDurationUnit[DdbDurationUnit["w"] = 7] = "w";
106
+ DdbDurationUnit[DdbDurationUnit["M"] = 8] = "M";
107
+ DdbDurationUnit[DdbDurationUnit["y"] = 9] = "y";
108
+ DdbDurationUnit[DdbDurationUnit["B"] = 10] = "B";
109
+ })(DdbDurationUnit || (DdbDurationUnit = {}));
110
+ export var DdbChartType;
111
+ (function (DdbChartType) {
112
+ DdbChartType[DdbChartType["area"] = 0] = "area";
113
+ DdbChartType[DdbChartType["bar"] = 1] = "bar";
114
+ DdbChartType[DdbChartType["column"] = 2] = "column";
115
+ DdbChartType[DdbChartType["histogram"] = 3] = "histogram";
116
+ DdbChartType[DdbChartType["line"] = 4] = "line";
117
+ DdbChartType[DdbChartType["pie"] = 5] = "pie";
118
+ DdbChartType[DdbChartType["scatter"] = 6] = "scatter";
119
+ DdbChartType[DdbChartType["trend"] = 7] = "trend";
120
+ DdbChartType[DdbChartType["kline"] = 8] = "kline";
121
+ })(DdbChartType || (DdbChartType = {}));
122
+ // server 实现中区分了 0: NULL (nothing), 1: NULL (null), 2: DFLT (default)
123
+ // Void::serialize()
124
+ // (isNothing() ? 0 : 1) + (isDefault_ ? 2 : 0);
125
+ export var DdbVoidType;
126
+ (function (DdbVoidType) {
127
+ DdbVoidType[DdbVoidType["undefined"] = 0] = "undefined";
128
+ DdbVoidType[DdbVoidType["null"] = 1] = "null";
129
+ DdbVoidType[DdbVoidType["default"] = 2] = "default";
130
+ })(DdbVoidType || (DdbVoidType = {}));
131
+ export const dictables = new Set([DdbType.any, DdbType.string, DdbType.double, DdbType.float, DdbType.int, DdbType.long]);
15
132
  /** 可以表示所有 DolphinDB 数据库中的数据类型 Can represent data types in all DolphinDB databases */
16
133
  export class DdbObj {
17
134
  static dec = new TextDecoder('utf-8');
@@ -32,15 +149,13 @@ export class DdbObj {
32
149
  length;
33
150
  /** table name / column name */
34
151
  name;
35
- /**
36
- 最低维、第 1 维
152
+ /** 最低维、第 1 维
37
153
  - vector: rows = n, cols = 1
38
154
  - pair: rows = 2, cols = 1
39
155
  - matrix: rows = n, cols = m
40
156
  - set: 同 vector
41
157
  - dict: 包含 keys, values 向量
42
- - table: 同 matrix
43
- */
158
+ - table: 同 matrix */
44
159
  rows;
45
160
  /** 第 2 维 */
46
161
  cols;
@@ -120,7 +235,7 @@ export class DdbObj {
120
235
  let i_start = i_items_start + len_items;
121
236
  for (let i = 0; i < cols; i++) {
122
237
  const type = buf_data[i_start];
123
- if (type === DdbType.compress)
238
+ if (type === DdbType.compressed)
124
239
  throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', { form: 'table', type: 'compress' }));
125
240
  let col = this.parse_vector(buf_data.subarray(i_start + 2), le, type);
126
241
  col.length += 2;
@@ -369,20 +484,21 @@ export class DdbObj {
369
484
  return [12, { scale: dv.getInt32(0, le), data: data === nulls.int64 ? null : data }];
370
485
  }
371
486
  case DdbType.decimal128: {
372
- return DdbDecimal128Serializor.parse_as_scalar(buf, le);
487
+ const dv = new DataView(buf.buffer, buf.byteOffset);
488
+ const data = get_big_int_128(dv, 4, le);
489
+ return [20, { scale: dv.getInt32(0, le), data: data === nulls.int128 ? null : data }];
373
490
  }
374
491
  default:
375
492
  throw new Error(String(DdbType[type] || type) + t(' 暂时不支持解析'));
376
493
  }
377
494
  }
378
495
  /** parse: rows, cols, items
379
- 返回的 ddbobj.length 不包括 vector 的 type 和 form
380
- */
496
+ 返回的 ddbobj.length 不包括 vector 的 type 和 form */
381
497
  static parse_vector(buf, le, type) {
382
498
  const dv = new DataView(buf.buffer, buf.byteOffset);
383
499
  const rows = dv.getUint32(0, le);
384
500
  let i_items_start = 8;
385
- if (type < 64 || type >= 128) {
501
+ if (type < 64 || type >= 128) { // 普通数组
386
502
  const [len_items, value] = this.parse_vector_items(buf.subarray(i_items_start), le, type, rows);
387
503
  return new this({
388
504
  le,
@@ -394,119 +510,121 @@ export class DdbObj {
394
510
  value,
395
511
  });
396
512
  }
397
- // array vector
398
- // av = array(INT[], 0, 3)
399
- // append!(av, [1..4])
400
- // append!(av, [1..70000])
401
- // av
402
- // <Buffer 44 01 type = array vector, form = vector
403
- // 02 00 00 00 74 11 01 00 rows = 2, cols = 70004 (0x011174)
404
- // block 0
405
- // 01 00 block.rows = 1
406
- // 04 block.unit = 4
407
- // 00 reserved
408
- // 04 00 00 00 block.lengths = [4]
409
- // 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 block.data
410
- // block 1
411
- // 01 00 block.rows = 1
412
- // 04 block.unit = 4
413
- // 00 reserved
414
- // 70 11 01 00 block.lengths = [70000 (0x00011170)]
415
- // 01 00 00 00 02 00 00 00 ... 279992 more bytes> block.data
416
- // decimal array vector
417
- // a = array(DECIMAL32(2)[], 0, 10)
418
- // append!(a, [
419
- // [1, 2, 3],
420
- // [4, 5],
421
- // [6, 7, 8],
422
- // [9, 10]
423
- // ])
424
- // print(a)
425
- // a
426
- // [[1.00,2.00,3.00],[4.00,5.00],[6.00,7.00,8.00],[9.00,10.00]]
427
- // <Buffer 65 01 type = 101 = 64 + 37 (decimal32) , form = vector
428
- // 04 00 00 00 0a 00 00 00 rows = 4, cols = 10
429
- // scale (只有 decimal32 才有)
430
- // 02 00 00 00 scale = 2
431
- // block 0
432
- // 04 00 block.rows = 4
433
- // 01 block.unit = 1
434
- // 00 reserved
435
- // 03 02 03 02 block.lengths = [3, 2, 3, 2]
436
- // 64 00 00 00 c8 00 00 00 2c 01 00 00 90 01 00 00 f4 01 00 00 58 02 00 00 bc 02 00 00 ... 12 more bytes> [100, 200, 300, ...]
437
- // block 1
438
- // ...
439
- const type_ = type - 64;
440
- const cols = dv.getUint32(4, le);
441
- let blocks = [];
442
- // decimal 会在所有 blocks 之前多一个 scale
443
- if (is_decimal_type(type_)) {
444
- blocks.scale = dv.getInt32(i_items_start, le);
445
- i_items_start += 4;
446
- }
447
- let i_block_start = i_items_start;
448
- // 解析一个 block
449
- for (let i_row = 0; i_row < rows;) {
450
- /** 对应 array vector 中元素个数 */
451
- const rows = dv.getUint16(i_block_start, le);
452
- /** 每个 length 占用的字节数 */
453
- const unit = dv.getUint8(i_block_start + 2);
454
- /** array vector 每个元素的子元素长度 */
455
- let lengths;
456
- const i_lengths_start = i_block_start + 4;
457
- const i_data_start = i_lengths_start + rows * unit;
458
- const lengths_buf = buf.slice(i_lengths_start, i_data_start);
459
- switch (unit) {
460
- case 1:
461
- lengths = lengths_buf;
462
- break;
463
- case 2:
464
- lengths = new Uint16Array(lengths_buf.buffer);
465
- break;
466
- case 4:
467
- lengths = new Uint32Array(lengths_buf.buffer);
468
- break;
469
- default:
470
- throw new Error(t('array vector 存在非法 unit: {{unit}}', { unit }));
471
- }
472
- let total_length = 0;
473
- for (const x of lengths)
474
- total_length += x;
475
- let len_items;
476
- let data;
477
- switch (type_) {
478
- case DdbType.decimal32:
479
- len_items = total_length * 4;
480
- data = new Int32Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
481
- break;
482
- case DdbType.decimal64:
483
- len_items = total_length * 8;
484
- data = new BigInt64Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
485
- break;
486
- case DdbType.decimal128:
487
- [len_items, data] = DdbDecimal128Serializor.parse_as_same_type_vector_values(buf, i_data_start, total_length);
488
- break;
489
- default:
490
- [len_items, data] = this.parse_vector_items(buf.subarray(i_data_start), le, type - 64, total_length);
513
+ else { // array vector
514
+ // av = array(INT[], 0, 3)
515
+ // append!(av, [1..4])
516
+ // append!(av, [1..70000])
517
+ // av
518
+ // <Buffer 44 01 type = array vector, form = vector
519
+ // 02 00 00 00 74 11 01 00 rows = 2, cols = 70004 (0x011174)
520
+ // block 0
521
+ // 01 00 block.rows = 1
522
+ // 04 block.unit = 4
523
+ // 00 reserved
524
+ // 04 00 00 00 block.lengths = [4]
525
+ // 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 block.data
526
+ // block 1
527
+ // 01 00 block.rows = 1
528
+ // 04 block.unit = 4
529
+ // 00 reserved
530
+ // 70 11 01 00 block.lengths = [70000 (0x00011170)]
531
+ // 01 00 00 00 02 00 00 00 ... 279992 more bytes> block.data
532
+ // decimal array vector
533
+ // a = array(DECIMAL32(2)[], 0, 10)
534
+ // append!(a, [
535
+ // [1, 2, 3],
536
+ // [4, 5],
537
+ // [6, 7, 8],
538
+ // [9, 10]
539
+ // ])
540
+ // print(a)
541
+ // a
542
+ // [[1.00,2.00,3.00],[4.00,5.00],[6.00,7.00,8.00],[9.00,10.00]]
543
+ // <Buffer 65 01 type = 101 = 64 + 37 (decimal32) , form = vector
544
+ // 04 00 00 00 0a 00 00 00 rows = 4, cols = 10
545
+ // scale (只有 decimal32 才有)
546
+ // 02 00 00 00 scale = 2
547
+ // block 0
548
+ // 04 00 block.rows = 4
549
+ // 01 block.unit = 1
550
+ // 00 reserved
551
+ // 03 02 03 02 block.lengths = [3, 2, 3, 2]
552
+ // 64 00 00 00 c8 00 00 00 2c 01 00 00 90 01 00 00 f4 01 00 00 58 02 00 00 bc 02 00 00 ... 12 more bytes> [100, 200, 300, ...]
553
+ // block 1
554
+ // ...
555
+ const type_ = type - 64;
556
+ const cols = dv.getUint32(4, le);
557
+ let blocks = [];
558
+ // decimal 会在所有 blocks 之前多一个 scale
559
+ if (is_decimal_type(type_)) {
560
+ blocks.scale = dv.getInt32(i_items_start, le);
561
+ i_items_start += 4;
491
562
  }
492
- blocks.push({
493
- unit,
563
+ let i_block_start = i_items_start;
564
+ // 解析一个 block
565
+ for (let i_row = 0; i_row < rows;) {
566
+ /** 对应 array vector 中元素个数 */
567
+ const rows = dv.getUint16(i_block_start, le);
568
+ /** 每个 length 占用的字节数 */
569
+ const unit = dv.getUint8(i_block_start + 2);
570
+ /** array vector 每个元素的子元素长度 */
571
+ let lengths;
572
+ const i_lengths_start = i_block_start + 4;
573
+ const i_data_start = i_lengths_start + rows * unit;
574
+ const lengths_buf = buf.slice(i_lengths_start, i_data_start);
575
+ switch (unit) {
576
+ case 1:
577
+ lengths = lengths_buf;
578
+ break;
579
+ case 2:
580
+ lengths = new Uint16Array(lengths_buf.buffer);
581
+ break;
582
+ case 4:
583
+ lengths = new Uint32Array(lengths_buf.buffer);
584
+ break;
585
+ default:
586
+ throw new Error(t('array vector 存在非法 unit: {{unit}}', { unit }));
587
+ }
588
+ let total_length = 0;
589
+ for (const x of lengths)
590
+ total_length += x;
591
+ let len_items;
592
+ let data;
593
+ switch (type_) {
594
+ case DdbType.decimal32:
595
+ len_items = total_length * 4;
596
+ data = new Int32Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
597
+ break;
598
+ case DdbType.decimal64:
599
+ len_items = total_length * 8;
600
+ data = new BigInt64Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
601
+ break;
602
+ case DdbType.decimal128:
603
+ len_items = total_length * 16;
604
+ data = new BigInt128Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
605
+ break;
606
+ default:
607
+ [len_items, data] = this.parse_vector_items(buf.subarray(i_data_start), le, type - 64, total_length);
608
+ }
609
+ blocks.push({
610
+ unit,
611
+ rows,
612
+ lengths,
613
+ data: data
614
+ });
615
+ i_block_start = i_data_start + len_items;
616
+ i_row += rows;
617
+ }
618
+ return new this({
619
+ le,
620
+ form: DdbForm.vector,
621
+ type,
622
+ length: i_block_start,
623
+ cols,
494
624
  rows,
495
- lengths,
496
- data: data
625
+ value: blocks
497
626
  });
498
- i_block_start = i_data_start + len_items;
499
- i_row += rows;
500
627
  }
501
- return new this({
502
- le,
503
- form: DdbForm.vector,
504
- type,
505
- length: i_block_start,
506
- cols,
507
- rows,
508
- value: blocks
509
- });
510
628
  }
511
629
  /** 有可能没有字节对齐,不能直接使用原有 message 的 arraybuffer, 统一复制出来,让原有 arraybuffer 被回收掉比较好 */
512
630
  static parse_vector_items(buf, le, type, length) {
@@ -678,8 +796,16 @@ export class DdbObj {
678
796
  }
679
797
  ];
680
798
  }
681
- case DdbType.decimal128:
682
- return DdbDecimal128Serializor.parse_as_vector_items(buf, length, le);
799
+ case DdbType.decimal128: {
800
+ const dv = new DataView(buf.buffer, buf.byteOffset);
801
+ return [
802
+ 4 + 16 * length,
803
+ {
804
+ scale: dv.getInt32(0, le),
805
+ data: new BigInt128Array(buf.buffer.slice(buf.byteOffset + 4, buf.byteOffset + 4 + 16 * length))
806
+ }
807
+ ];
808
+ }
683
809
  // 以下情况时, DdbType.duration 实际会返回一个 any vector
684
810
  // [2y, 1M, 3d, 7H, 11m, 12s, 15ms, 16us, 17ns]
685
811
  // <Buffer 19 01 type = any, form = vector
@@ -703,16 +829,13 @@ export class DdbObj {
703
829
  });
704
830
  return [8 * length, durations];
705
831
  }
706
- case DdbType.compress:
832
+ case DdbType.compressed:
707
833
  return [
708
834
  length,
709
835
  new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + length))
710
836
  ];
711
837
  default:
712
- throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', {
713
- form: 'vector',
714
- type: String(DdbType[type] || type)
715
- }));
838
+ throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', { form: 'vector', type: get_type_name(type) }));
716
839
  }
717
840
  }
718
841
  pack() {
@@ -824,8 +947,10 @@ export class DdbObj {
824
947
  const { scale, data } = this.value;
825
948
  return [Int32Array.of(scale), BigInt64Array.of(data === null ? nulls.int64 : data)];
826
949
  }
827
- case DdbType.decimal128:
828
- return DdbDecimal128Serializor.pack(this.value);
950
+ case DdbType.decimal128: {
951
+ const { scale, data } = value;
952
+ return [Int32Array.of(scale), BigInt128Array.of(data === null ? nulls.int128 : data)];
953
+ }
829
954
  default:
830
955
  throw new Error(String(DdbType[type] || type) + t(' 暂时不支持序列化'));
831
956
  }
@@ -892,7 +1017,7 @@ export class DdbObj {
892
1017
  ];
893
1018
  }
894
1019
  default:
895
- throw new Error(t('vector {{type}} 暂不支持序列化', { type: DdbType[type] || type }));
1020
+ throw new Error(t('vector {{type}} 暂不支持序列化', { type: get_type_name(type) }));
896
1021
  }
897
1022
  })();
898
1023
  if (!body)
@@ -943,7 +1068,7 @@ export class DdbObj {
943
1068
  case DdbType.uuid:
944
1069
  case DdbType.ipaddr:
945
1070
  case DdbType.int128:
946
- case DdbType.compress:
1071
+ case DdbType.compressed:
947
1072
  return [value];
948
1073
  case DdbType.blob: {
949
1074
  let bufs = new Array(length * 2);
@@ -997,7 +1122,52 @@ export class DdbObj {
997
1122
  return [Int32Array.of(scale), data];
998
1123
  }
999
1124
  default:
1000
- throw new Error(t('vector {{type}} 暂不支持序列化', { type: String(DdbType[type] || type) }));
1125
+ throw new Error(t('vector {{type}} 暂不支持序列化', { type: get_type_name(type) }));
1126
+ }
1127
+ }
1128
+ data() {
1129
+ const { form, type, value, le, rows, name } = this;
1130
+ switch (form) {
1131
+ case DdbForm.scalar:
1132
+ return convert(type, value, le);
1133
+ case DdbForm.vector:
1134
+ case DdbForm.pair:
1135
+ case DdbForm.set: {
1136
+ const data = converts(type, value, rows, le);
1137
+ return (form === DdbForm.set ? new Set(data) : data);
1138
+ }
1139
+ case DdbForm.table: {
1140
+ const cols = value;
1141
+ const jscols = cols.map(col => col.data());
1142
+ const keys = cols.map(({ name }) => name);
1143
+ return {
1144
+ name: name || '',
1145
+ columns: cols.map(({ name }) => name),
1146
+ types: cols.map(({ type }) => type),
1147
+ data: seq(rows, i => zip_object(keys, seq(cols.length, j => jscols[j][i])))
1148
+ };
1149
+ }
1150
+ case DdbForm.dict: {
1151
+ const [keys, values] = value;
1152
+ return zip_object(keys.data(), values.data());
1153
+ }
1154
+ case DdbForm.chart:
1155
+ return value;
1156
+ case DdbForm.matrix: {
1157
+ const ncolumns = this.cols;
1158
+ const { rows: _rows, cols: _cols, data } = value;
1159
+ const jsdata = converts(type, data, rows * ncolumns, le);
1160
+ return {
1161
+ type,
1162
+ nrows: rows,
1163
+ ncolumns,
1164
+ rows: _rows?.data(),
1165
+ columns: _cols?.data(),
1166
+ data: seq(rows, i => seq(ncolumns, j => jsdata[j * rows + i]))
1167
+ };
1168
+ }
1169
+ default:
1170
+ throw new Error(t('{{form}} {{type}} 暂不支持 data()', { form, type: get_type_name(type) }));
1001
1171
  }
1002
1172
  }
1003
1173
  toString(options = { nullstr: true, quote: true }) {
@@ -1005,11 +1175,7 @@ export class DdbObj {
1005
1175
  const data = (() => {
1006
1176
  switch (this.form) {
1007
1177
  case DdbForm.scalar:
1008
- // 如果类型为 string, 则不进行格式化处理
1009
- if (this.type === DdbType.string)
1010
- return this.value;
1011
- else
1012
- return format(this.type, this.value, this.le, options);
1178
+ return format(this.type, this.value, this.le, options);
1013
1179
  case DdbForm.vector:
1014
1180
  case DdbForm.pair:
1015
1181
  case DdbForm.set: {
@@ -1122,7 +1288,7 @@ export class DdbObj {
1122
1288
  return format_array(items, data.length > limit);
1123
1289
  }
1124
1290
  default: {
1125
- const limit = this.type === DdbType.compress ? 5 : 50;
1291
+ const limit = this.type === DdbType.compressed ? 5 : 50;
1126
1292
  let items = new Array(Math.min(limit, this.value.length));
1127
1293
  for (let i = 0; i < items.length; i++)
1128
1294
  items[i] = format(this.type, this.value[i], this.le, options);
@@ -1186,6 +1352,7 @@ export class DdbObj {
1186
1352
  static to_ddbobjs(values) {
1187
1353
  return values.map(value => this.to_ddbobj(value));
1188
1354
  }
1355
+ /** @deprecated 用 data() */
1189
1356
  to_cols() {
1190
1357
  assert(this.form === DdbForm.table, t('form 必须是 DdbForm.table, 否则不能 to_cols'));
1191
1358
  return this.value.map(col => ({
@@ -1194,7 +1361,8 @@ export class DdbObj {
1194
1361
  render: value => format(col.type, value, col.le, { nullstr: false, quote: false })
1195
1362
  }));
1196
1363
  }
1197
- /** 将 table 转换为 rows,空值转换为 null */
1364
+ /** 将 table 转换为 rows,空值转换为 null
1365
+ @deprecated 用 data() */
1198
1366
  to_rows() {
1199
1367
  assert(this.form === DdbForm.table, t('form 必须是 DdbForm.table, 否则不能 to_rows'));
1200
1368
  let rows = new Array(this.rows);
@@ -1284,6 +1452,25 @@ export class DdbObj {
1284
1452
  return obj;
1285
1453
  }
1286
1454
  }
1455
+ /** 根据 DdbType 获取其名称,array vector type 自动在后面加上 [] */
1456
+ export function get_type_name(type) {
1457
+ return `${DdbType[type] || type}${64 <= type && type < 128 ? '[]' : ''}`;
1458
+ }
1459
+ export function is_decimal_type(type) {
1460
+ return type === DdbType.decimal32 || type === DdbType.decimal64 || type === DdbType.decimal128;
1461
+ }
1462
+ export function is_decimal_null_value(type, value) {
1463
+ return ((value === nulls.int128 && type === DdbType.decimal128) ||
1464
+ (value === nulls.int64 && type === DdbType.decimal64) ||
1465
+ (value === nulls.int32 && type === DdbType.decimal32));
1466
+ }
1467
+ export function get_duration_unit(code) {
1468
+ let str = String.fromCharCode((code >> 24) & 0xff);
1469
+ str += String.fromCharCode((code >> 16) & 0xff);
1470
+ str += String.fromCharCode((code >> 8) & 0xff);
1471
+ str += String.fromCharCode(code & 0xff);
1472
+ return str;
1473
+ }
1287
1474
  /** 整数一定用这个 number formatter, InspectOptions.decimals 不传也用这个 */
1288
1475
  let default_formatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 20 });
1289
1476
  let _decimals = 20;
@@ -1480,7 +1667,43 @@ export function format(type, value, le, options = {}) {
1480
1667
  /** 格式化向量、集合中的第 index 项为字符串,空值返回 'null' 字符串 formatted vector, the index-th item in the collection is a string, a null value returns a 'null' string */
1481
1668
  export function formati(obj, index, options = {}) {
1482
1669
  assert(index < obj.rows, 'index < obj.rows');
1483
- if (64 <= obj.type && obj.type < 128) { // array vector
1670
+ if (obj.type < 64 || obj.type >= 128) // 普通数组
1671
+ switch (obj.type) {
1672
+ case DdbType.symbol_extended: {
1673
+ const { base, data } = obj.value;
1674
+ return format(DdbType.string, base[data[index]], obj.le, options);
1675
+ }
1676
+ case DdbType.void:
1677
+ return format(obj.type, obj.value, obj.le, options);
1678
+ case DdbType.uuid:
1679
+ case DdbType.int128:
1680
+ case DdbType.ipaddr:
1681
+ return format(obj.type, obj.value.subarray(16 * index, 16 * (index + 1)), obj.le, options);
1682
+ case DdbType.blob: {
1683
+ const value = obj.value[index];
1684
+ return value.length > 100 ?
1685
+ DdbObj.dec.decode(value.subarray(0, 98)) + '…'
1686
+ :
1687
+ DdbObj.dec.decode(value);
1688
+ }
1689
+ case DdbType.complex:
1690
+ case DdbType.point:
1691
+ return format(obj.type, obj.value.subarray(2 * index, 2 * (index + 1)), obj.le, options);
1692
+ case DdbType.decimal32:
1693
+ case DdbType.decimal64:
1694
+ case DdbType.decimal128: {
1695
+ const { scale, data } = obj.value;
1696
+ const x = data[index];
1697
+ if (is_decimal_null_value(obj.type, x))
1698
+ return '';
1699
+ const s = String(x < 0 ? -x : x).padStart(scale, '0');
1700
+ const str = (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
1701
+ return options.colors ? green(str) : str;
1702
+ }
1703
+ default:
1704
+ return format(obj.type, obj.value[index], obj.le, options);
1705
+ }
1706
+ else { // array vector
1484
1707
  // 因为 array vector 目前只支持:Logical, Integral(不包括 INT128, COMPRESS 类型), Floating, Temporal
1485
1708
  // 都对应 TypedArray 中的一格,所以 lengths.length 等于 block 中的 row 的个数
1486
1709
  // av = array(INT[], 0, 5)
@@ -1544,40 +1767,155 @@ export function formati(obj, index, options = {}) {
1544
1767
  }
1545
1768
  }
1546
1769
  }
1547
- switch (obj.type) {
1548
- case DdbType.symbol_extended: {
1549
- const { base, data } = obj.value;
1550
- return format(DdbType.string, base[data[index]], obj.le, options);
1551
- }
1770
+ }
1771
+ export function convert(type, value, le) {
1772
+ switch (type) {
1552
1773
  case DdbType.void:
1553
- return format(obj.type, obj.value, obj.le, options);
1774
+ return value === DdbVoidType.null ? null : undefined;
1775
+ case DdbType.char:
1776
+ return value === null || value === nulls.int8 ? '' : String.fromCharCode(value);
1777
+ case DdbType.bool:
1778
+ return value === null || value === nulls.int8 ? null : Boolean(value);
1779
+ case DdbType.short:
1780
+ return value === null || value === nulls.int16 ? null : value;
1781
+ case DdbType.int:
1782
+ return value === null || value === nulls.int32 ? null : value;
1783
+ case DdbType.float:
1784
+ return value === null || value === nulls.float32 ? null : value;
1785
+ case DdbType.double:
1786
+ return value === null || value === nulls.double ? null : value;
1787
+ case DdbType.long:
1788
+ return value === null || value === nulls.int64 ? null : value;
1789
+ case DdbType.functiondef:
1790
+ return value.name;
1791
+ case DdbType.string:
1792
+ case DdbType.symbol:
1793
+ case DdbType.code:
1794
+ case DdbType.handle:
1795
+ case DdbType.datasource:
1796
+ case DdbType.resource:
1797
+ case DdbType.blob:
1798
+ return value;
1799
+ case DdbType.complex:
1800
+ case DdbType.point: {
1801
+ const [x, y] = value;
1802
+ return [
1803
+ x === null || x === nulls.double ? null : x,
1804
+ y === null || y === nulls.double ? null : y,
1805
+ ];
1806
+ }
1807
+ case DdbType.date:
1808
+ case DdbType.month:
1809
+ case DdbType.time:
1810
+ case DdbType.minute:
1811
+ case DdbType.second:
1812
+ case DdbType.datetime:
1813
+ case DdbType.datehour:
1814
+ case DdbType.timestamp:
1815
+ case DdbType.nanotime:
1816
+ case DdbType.nanotimestamp:
1817
+ case DdbType.duration:
1554
1818
  case DdbType.uuid:
1555
- case DdbType.int128:
1556
1819
  case DdbType.ipaddr:
1557
- return format(obj.type, obj.value.subarray(16 * index, 16 * (index + 1)), obj.le, options);
1558
- case DdbType.blob: {
1559
- const value = obj.value[index];
1560
- return value.length > 100 ?
1561
- DdbObj.dec.decode(value.subarray(0, 98)) + '…'
1562
- :
1563
- DdbObj.dec.decode(value);
1564
- }
1565
- case DdbType.complex:
1566
- case DdbType.point:
1567
- return format(obj.type, obj.value.subarray(2 * index, 2 * (index + 1)), obj.le, options);
1820
+ case DdbType.int128:
1821
+ // decimal 类型转换为固定位数小数的 string 不丢失精度,一般也是展示用
1568
1822
  case DdbType.decimal32:
1569
1823
  case DdbType.decimal64:
1570
- case DdbType.decimal128: {
1571
- const { scale, data } = obj.value;
1572
- const x = data[index];
1573
- if (is_decimal_null_value(obj.type, x))
1574
- return '';
1575
- const s = String(x < 0 ? -x : x).padStart(scale, '0');
1576
- const str = (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
1577
- return options.colors ? green(str) : str;
1578
- }
1824
+ case DdbType.decimal128:
1825
+ return format(type, value, le, { colors: false });
1579
1826
  default:
1580
- return format(obj.type, obj.value[index], obj.le, options);
1827
+ throw new Error(String(DdbType[type] || type) + t(' 暂时不支持转换为 js 对象'));
1828
+ }
1829
+ }
1830
+ /** 转换一个向量到 js 原生数组 */
1831
+ export function converts(type, value, rows, le) {
1832
+ if (type < 64 || type >= 128)
1833
+ switch (type) {
1834
+ // 可以直接用下标取值再转换的类型
1835
+ case DdbType.bool:
1836
+ case DdbType.char:
1837
+ case DdbType.short:
1838
+ case DdbType.int:
1839
+ case DdbType.float:
1840
+ case DdbType.double:
1841
+ case DdbType.long:
1842
+ case DdbType.date:
1843
+ case DdbType.month:
1844
+ case DdbType.time:
1845
+ case DdbType.minute:
1846
+ case DdbType.second:
1847
+ case DdbType.datetime:
1848
+ case DdbType.datehour:
1849
+ case DdbType.timestamp:
1850
+ case DdbType.nanotime:
1851
+ case DdbType.nanotimestamp:
1852
+ case DdbType.duration:
1853
+ case DdbType.string:
1854
+ case DdbType.symbol:
1855
+ case DdbType.code:
1856
+ case DdbType.handle:
1857
+ case DdbType.datasource:
1858
+ case DdbType.resource:
1859
+ case DdbType.functiondef:
1860
+ case DdbType.blob:
1861
+ return Array.prototype.map.call(value, (x) => convert(type, x, le));
1862
+ case DdbType.void:
1863
+ return [];
1864
+ case DdbType.symbol_extended: {
1865
+ const { base, data } = value;
1866
+ return Array.prototype.map.call(data, (x) => base[x]);
1867
+ }
1868
+ case DdbType.complex:
1869
+ case DdbType.point:
1870
+ return seq(rows, i => [value[2 * i], value[2 * (i + 1)]]);
1871
+ case DdbType.uuid:
1872
+ case DdbType.ipaddr:
1873
+ case DdbType.int128:
1874
+ return seq(rows, i => convert(type, value.subarray(16 * i, 16 * (i + 1)), le));
1875
+ case DdbType.decimal32:
1876
+ case DdbType.decimal64:
1877
+ case DdbType.decimal128: {
1878
+ const { scale, data } = value;
1879
+ // todo: 用 Array.prototype.map.call 时对 BigInt128Array 这个代理对象无效?为什么只能通过下标访问?
1880
+ return seq(rows, i => {
1881
+ const x = data[i];
1882
+ if (is_decimal_null_value(type, x))
1883
+ return '';
1884
+ const s = String(x < 0 ? -x : x).padStart(scale, '0');
1885
+ return (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
1886
+ });
1887
+ }
1888
+ case DdbType.any:
1889
+ return value.map(x => x.data());
1890
+ default:
1891
+ throw new Error(String(DdbType[type] || type) + '[]' + t(' 暂时不支持转换为 js 对象'));
1892
+ }
1893
+ else { // array vector
1894
+ const type_ = type - 64;
1895
+ return value.map(({ lengths, data, rows }) => {
1896
+ let acc_len = 0;
1897
+ return Array.prototype.map.call(lengths, (length) => {
1898
+ const result = (() => {
1899
+ switch (type_) {
1900
+ case DdbType.decimal32:
1901
+ case DdbType.decimal64:
1902
+ case DdbType.decimal128:
1903
+ return converts(type_, { scale: value.scale, data: data.subarray(acc_len, acc_len + length) }, length, le);
1904
+ case DdbType.complex:
1905
+ case DdbType.point:
1906
+ return converts(type_, data.subarray(acc_len, acc_len + 2 * length), length, le);
1907
+ case DdbType.uuid:
1908
+ case DdbType.int128:
1909
+ case DdbType.ipaddr:
1910
+ return converts(type_, data.subarray(acc_len, acc_len + 16 * length), length, le);
1911
+ default:
1912
+ return converts(type_, data.subarray(acc_len, acc_len + length), length, le);
1913
+ }
1914
+ })();
1915
+ acc_len += length;
1916
+ return result;
1917
+ });
1918
+ }).flat();
1581
1919
  }
1582
1920
  }
1583
1921
  export class DdbVoid extends DdbObj {
@@ -2111,7 +2449,7 @@ export function ipaddr2str(buffer, le = true, ipv6) {
2111
2449
  let buf = buffer;
2112
2450
  if (le)
2113
2451
  buf = buffer.slice().reverse();
2114
- const i_non_zero = buf.findIndex(x => x);
2452
+ const i_non_zero = buf.findIndex(x => x !== 0);
2115
2453
  if (ipv6 ||
2116
2454
  i_non_zero !== -1 && i_non_zero < 12) // ipv6
2117
2455
  return buf2ipaddr([...buf]).toString();
@@ -2171,8 +2509,7 @@ export class DDB {
2171
2509
  dec = new TextDecoder('utf-8');
2172
2510
  enc = new TextEncoder();
2173
2511
  /** DolphinDB WebSocket URL
2174
- e.g. `ws://127.0.0.1:8848/`, `wss://dolphindb.com`
2175
- */
2512
+ e.g. `ws://127.0.0.1:8848/`, `wss://dolphindb.com` */
2176
2513
  url;
2177
2514
  /** 为所有 websocket 操作加锁,包括设置 this.on_message, this.on_error, websocket.send */
2178
2515
  lwebsocket = new Lock();
@@ -2199,7 +2536,6 @@ export class DDB {
2199
2536
  print_object_buffer = false;
2200
2537
  print_message = true;
2201
2538
  parse_object = true;
2202
- pnode_run_defined = false;
2203
2539
  /** 在 websocket 收到的第一个 error 时,
2204
2540
  在 connect_websocket 的 on_error 回调中构造 DdbConnectionError 并保存到 DDB 对象上,
2205
2541
  这个 error 的错误信息最准确 */
@@ -2210,6 +2546,8 @@ export class DDB {
2210
2546
  pconnect;
2211
2547
  /** 首次定义 pnode_run 的 promise,保证并发调用 rpc 时只定义一次 pnode_run */
2212
2548
  ppnode_run;
2549
+ /** 首次定义 invoke 的 promise,保证并发调用 rpc 时只定义一次 invoke */
2550
+ pinvoke;
2213
2551
  get connected() {
2214
2552
  return !this.error && this.lwebsocket.resource?.readyState === WebSocket.OPEN;
2215
2553
  }
@@ -2526,7 +2864,7 @@ export class DDB {
2526
2864
  ]));
2527
2865
  });
2528
2866
  if (this.verbose)
2529
- console.log(result.toString({ quote: true, nullstr: true }) + rpc_id);
2867
+ console.log(result.toString() + rpc_id);
2530
2868
  return result;
2531
2869
  });
2532
2870
  }
@@ -2540,8 +2878,7 @@ export class DDB {
2540
2878
  不做解析,以便后续转发、序列化
2541
2879
  Set parse_object during this rpc, and restore the original after the end.
2542
2880
  When it is false, the returned DdbObj only contains buffer and le without parsing,
2543
- so as to facilitate subsequent forwarding and serialization
2544
- */
2881
+ so as to facilitate subsequent forwarding and serialization */
2545
2882
  async eval(script, { urgent, listener, parse_object, } = {}) {
2546
2883
  return this.rpc('script', { script, urgent, listener, parse_object });
2547
2884
  }
@@ -2606,6 +2943,45 @@ export class DDB {
2606
2943
  on_more_messages
2607
2944
  });
2608
2945
  }
2946
+ /** 调用 dolphindb 函数,传入 js 原生数组作为参数,返回 js 原生对象或值(调用 DdbObj.data() 后的结果)
2947
+ - func: 函数名
2948
+ - args?: `[ ]` 调用参数,可以是 js 原生数组
2949
+ - options?: 调用选项
2950
+ - urgent?: 紧急 flag。使用 urgent worker 执行,防止被其它作业阻塞
2951
+ - node?: 设置结点 alias 时发送到集群中对应的结点执行 (使用 DolphinDB 中的 rpc 方法)
2952
+ - nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
2953
+ - func_type?: 设置 node 参数且参数数组为空时必传,需指定函数类型,其它情况下不传
2954
+ - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
2955
+ - listener?: 处理本次 rpc 期间的消息 (DdbMessage) */
2956
+ async invoke(func, args, options) {
2957
+ await (this.pinvoke ??= this.eval(this.python ?
2958
+ '\n' +
2959
+ 'def invoke (func_name, args_json):\n' +
2960
+ ' args = fromStdJson(args_json)\n' +
2961
+ ' if type(args) != ANY:\n' +
2962
+ ' args = cast(args, ANY)\n' +
2963
+ ' return unifiedCall(funcByName(func_name), args)\n'
2964
+ :
2965
+ '\n' +
2966
+ 'def invoke (func_name, args_json) {\n' +
2967
+ ' args = fromStdJson(args_json)\n' +
2968
+ ' if (type(args) != ANY)\n' +
2969
+ ' args = cast(args, ANY)\n' +
2970
+ ' return unifiedCall(funcByName(func_name), args)\n' +
2971
+ '}\n', { urgent: true }));
2972
+ if (options?.node)
2973
+ options.func_type = DdbFunctionType.UserDefinedFunc;
2974
+ return (await this.call(args?.length ? 'invoke' : func, args?.length ? [func, JSON.stringify(args)] : undefined, options)).data();
2975
+ }
2976
+ /** 执行 dolphindb 脚本,返回 js 原生对象或值(调用 DdbObj.data() 后的结果)
2977
+ - script?: 执行的脚本
2978
+ - options?: 执行选项
2979
+ - urgent?: 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞
2980
+ - listener?: 处理本次 rpc 期间的消息 (DdbMessage) */
2981
+ async execute(script, options) {
2982
+ return (await this.eval(script, options))
2983
+ .data();
2984
+ }
2609
2985
  /** upload variable through websocket (variable command) */
2610
2986
  async upload(
2611
2987
  /** 上传的变量名 Uploaded variables' name */
@@ -2755,4 +3131,191 @@ export class DDB {
2755
3131
  colnames);
2756
3132
  }
2757
3133
  }
3134
+ /** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements
3135
+ SharedArrayBuffer is disabled by default in most browsers as a security precaution to avoid Spectre attacks.
3136
+ But it's still available in Node.js or some browsers. */
3137
+ const has_shared_array_buffer = typeof SharedArrayBuffer !== 'undefined';
3138
+ export class BigInt128Array {
3139
+ static of(...items) {
3140
+ return new BigInt128Array(items);
3141
+ }
3142
+ static from(arrayLike, mapfn, thisArg) {
3143
+ if (mapfn) {
3144
+ const array = [];
3145
+ for (let i = 0; i < arrayLike.length; i++)
3146
+ array.push(mapfn.call(thisArg, arrayLike[i], i));
3147
+ return new BigInt128Array(array);
3148
+ }
3149
+ else {
3150
+ const v = new BigInt128Array(arrayLike.length);
3151
+ v.set(arrayLike);
3152
+ }
3153
+ }
3154
+ BYTES_PER_ELEMENT = 16;
3155
+ buffer;
3156
+ byteLength;
3157
+ byteOffset;
3158
+ constructor(fisrtArg, byteOffset, length) {
3159
+ if (typeof fisrtArg === 'number') {
3160
+ const length = fisrtArg;
3161
+ this.buffer = new ArrayBuffer(length * this.BYTES_PER_ELEMENT);
3162
+ this.byteOffset = 0;
3163
+ this.byteLength = length * this.BYTES_PER_ELEMENT;
3164
+ }
3165
+ else if (fisrtArg instanceof ArrayBuffer || (has_shared_array_buffer && fisrtArg instanceof SharedArrayBuffer)) {
3166
+ this.buffer = fisrtArg;
3167
+ this.byteOffset = byteOffset ?? 0;
3168
+ let byteLength = 0;
3169
+ if (length !== undefined) {
3170
+ byteLength = length * this.BYTES_PER_ELEMENT;
3171
+ if (byteLength + this.byteOffset > fisrtArg.byteLength)
3172
+ throw new RangeError(`valid typed array length: ${length}`);
3173
+ }
3174
+ else {
3175
+ byteLength = fisrtArg.byteLength - this.byteOffset;
3176
+ if (byteLength % this.BYTES_PER_ELEMENT !== 0)
3177
+ throw new RangeError('byte length of BigInt128Array should be a multiple of 16');
3178
+ }
3179
+ this.byteLength = byteLength;
3180
+ }
3181
+ else {
3182
+ const array = [];
3183
+ for (const value of fisrtArg)
3184
+ array.push(value);
3185
+ this.buffer = new ArrayBuffer(array.length * this.BYTES_PER_ELEMENT);
3186
+ this.byteOffset = 0;
3187
+ this.byteLength = array.length * this.BYTES_PER_ELEMENT;
3188
+ this.set(array);
3189
+ }
3190
+ return new Proxy(this, {
3191
+ get(target, key) {
3192
+ if (typeof key === 'string') {
3193
+ const index = Number(key);
3194
+ // only positive integer index is allowed
3195
+ if (Number.isInteger(index) && index >= 0 && index < target.length)
3196
+ return target.at(index);
3197
+ }
3198
+ return Reflect.get(target, key);
3199
+ },
3200
+ set(target, key, value) {
3201
+ if (typeof key === 'string') {
3202
+ const index = Number(key);
3203
+ if (Number.isInteger(index) && index >= 0 && index < target.length)
3204
+ target.set([value], index);
3205
+ // ignore invalid number index setter, and never set value to target
3206
+ return true;
3207
+ }
3208
+ return Reflect.set(target, key, value);
3209
+ }
3210
+ });
3211
+ }
3212
+ get length() {
3213
+ return this.byteLength / this.BYTES_PER_ELEMENT;
3214
+ }
3215
+ set(array, offset = 0) {
3216
+ if (offset + array.length > this.length)
3217
+ throw new RangeError('offset is out of bounds');
3218
+ const dv = new DataView(this.buffer);
3219
+ for (let i = 0; i < array.length; i++) {
3220
+ const byteOffset = this.byteOffset + (offset + i) * this.BYTES_PER_ELEMENT;
3221
+ set_big_int_128(dv, byteOffset, array[i]);
3222
+ }
3223
+ }
3224
+ at(index) {
3225
+ const length = this.length;
3226
+ if (index < 0)
3227
+ index += length;
3228
+ if (index >= length || index < 0)
3229
+ return undefined;
3230
+ const dv = new DataView(this.buffer);
3231
+ return get_big_int_128(dv, this.byteOffset + index * this.BYTES_PER_ELEMENT);
3232
+ }
3233
+ subarray(begin = 0, end = this.length) {
3234
+ const length = this.length;
3235
+ // subarray arguments should be the same behavior as other TypedArray
3236
+ // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray#%E8%AF%B4%E6%98%8E
3237
+ if (begin < 0)
3238
+ begin += length;
3239
+ if (end < 0)
3240
+ end += length;
3241
+ if (begin < 0)
3242
+ begin = 0;
3243
+ else if (begin > length)
3244
+ begin = length;
3245
+ if (end < 0)
3246
+ end = 0;
3247
+ else if (end > length)
3248
+ end = length;
3249
+ const newLength = Math.max(end - begin, 0);
3250
+ return new BigInt128Array(this.buffer, this.byteOffset + begin * this.BYTES_PER_ELEMENT, newLength);
3251
+ }
3252
+ [Symbol.iterator]() {
3253
+ let index = 0;
3254
+ const array = this;
3255
+ return {
3256
+ next() {
3257
+ if (index < array.length)
3258
+ return { value: array.at(index++), done: false };
3259
+ else
3260
+ return { done: true };
3261
+ },
3262
+ };
3263
+ }
3264
+ toString() {
3265
+ const values = [];
3266
+ for (const value of this)
3267
+ values.push(value);
3268
+ return values.join(',');
3269
+ }
3270
+ }
3271
+ Object.defineProperty(BigInt128Array.prototype, Symbol.toStringTag, {
3272
+ configurable: false,
3273
+ writable: false,
3274
+ enumerable: false,
3275
+ value: 'BigInt128Array',
3276
+ });
3277
+ // DataView Extends for bigint 128 operations
3278
+ function get_big_uint_128(dataview, byte_offset, le = true) {
3279
+ let cursor = byte_offset + (le ? 15 : 0);
3280
+ const end = byte_offset + (le ? -1 : 16);
3281
+ const step = le ? -1 : 1;
3282
+ let value = 0n;
3283
+ while (cursor !== end) {
3284
+ value = value << 8n | BigInt(dataview.getUint8(cursor));
3285
+ cursor += step;
3286
+ }
3287
+ return value;
3288
+ }
3289
+ function get_big_int_128(dataview, byte_offset, le = true) {
3290
+ return BigInt.asIntN(128, get_big_uint_128(dataview, byte_offset, le));
3291
+ }
3292
+ function set_big_uint_128(dataView, byte_offset, value, le = true) {
3293
+ let cursor = byte_offset + (le ? 0 : 15);
3294
+ const end = byte_offset + (le ? 16 : -1);
3295
+ const step = le ? 1 : -1;
3296
+ while (cursor !== end) {
3297
+ dataView.setUint8(cursor, Number(value & 0xffn));
3298
+ value = value >> 8n;
3299
+ cursor += step;
3300
+ }
3301
+ }
3302
+ function set_big_int_128(dataview, byte_offset, value, le = true) {
3303
+ set_big_uint_128(dataview, byte_offset, value, le);
3304
+ }
3305
+ // 大端
3306
+ // const dataBE = new ArrayBuffer(16)
3307
+ // const dataViewBE = new DataView(dataBE)
3308
+ // set_big_int_128(dataViewBE, 0, -34355n, false)
3309
+ // console.log(dataViewBE.buffer)
3310
+ // const bigInt128BE = get_big_int_128(dataViewBE, 0, false)
3311
+ // const bigUint128BE = get_big_uint_128(dataViewBE, 0, false)
3312
+ // console.log(bigInt128BE.toString(), bigUint128BE.toString())
3313
+ // 小端
3314
+ // const dataLE = new ArrayBuffer(16)
3315
+ // const dataViewLE = new DataView(dataLE)
3316
+ // set_big_int_128(dataViewLE, 0, -34355n, true)
3317
+ // console.log(dataViewLE.buffer)
3318
+ // const bigInt128LE = get_big_int_128(dataViewLE, 0, true)
3319
+ // const bigUint128LE = get_big_uint_128(dataViewLE, 0, true)
3320
+ // console.log(bigInt128LE.toString(), bigUint128LE.toString())
2758
3321
  //# sourceMappingURL=browser.js.map