dolphindb 2.0.600 → 2.0.603

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/README.md CHANGED
@@ -46,6 +46,7 @@ npm install dolphindb
46
46
  ```ts
47
47
  import { DDB } from 'dolphindb'
48
48
  // The import method for existing projects using CommonJS modules is const { DDB } = require('dolphindb')
49
+ // Use in browser: import { DDB } form 'dolphindb/browser.js'
49
50
 
50
51
  // Create a database object and initialize the WebSocket URL
51
52
  let ddb = new DDB('ws://127.0.0.1:8848')
package/browser.d.ts CHANGED
@@ -121,6 +121,15 @@ export interface DdbChartValue {
121
121
  /** 原属性 chartType */
122
122
  type: DdbChartType;
123
123
  stacking: boolean;
124
+ /** 直方图 (Histogram), plotHist 函数返回的 chart 可能具有该属性
125
+ 原属性 binStart
126
+ 数值类型的 DdbObj 都有可能?
127
+ */
128
+ bin_start?: DdbObj;
129
+ /** 原属性 binEnd */
130
+ bin_end?: DdbObj;
131
+ /** 原属性 binCount */
132
+ bin_count?: DdbObj;
124
133
  titles: {
125
134
  chart: string;
126
135
  x_axis: string;
@@ -232,7 +241,13 @@ export declare class DdbObj<T extends DdbValue = DdbValue> {
232
241
  deep?: boolean;
233
242
  }): T;
234
243
  }
235
- export declare function format(type: DdbType, value: DdbValue, le: boolean): string;
244
+ interface InspectOptions {
245
+ colors?: boolean;
246
+ }
247
+ /** Formats a single element (value) as a string according to DdbType, null returns a 'null' string */
248
+ export declare function format(type: DdbType, value: DdbValue, le: boolean, options?: InspectOptions): string;
249
+ /** Format vector, the index-th item in the collection is a string, a null value returns a 'null' string */
250
+ export declare function formati(obj: DdbObj, index: number, options?: InspectOptions): string;
236
251
  export declare class DdbVoid extends DdbObj<undefined> {
237
252
  constructor();
238
253
  }
@@ -382,9 +397,11 @@ export declare class DDB {
382
397
  print_object_buffer: boolean;
383
398
  print_message: boolean;
384
399
  parse_object: boolean;
400
+ pnode_run_defined: boolean;
385
401
  /** DdbMessage listeners */
386
402
  listeners: DdbMessageListener[];
387
403
  pconnect: Promise<void>;
404
+ ppnoderun: Promise<void>;
388
405
  presult: Promise<any>;
389
406
  get connected(): boolean;
390
407
  /**
@@ -538,3 +555,4 @@ export interface DdbErrorMessage {
538
555
  }
539
556
  export declare type DdbMessage = DdbPrintMessage | DdbObjectMessage | DdbErrorMessage;
540
557
  export declare let ddb: DDB;
558
+ export {};
package/browser.js CHANGED
@@ -268,7 +268,7 @@ export class DdbObj {
268
268
  if (form === DdbForm.dict)
269
269
  return dict;
270
270
  else {
271
- const { chartType: type, stacking, title: titles, extras, data, ...others } = dict.to_dict();
271
+ const { chartType: type, stacking, binStart: bin_start, binEnd: bin_end, binCount: bin_count, title: titles, extras, data, ...others } = dict.to_dict();
272
272
  const [chart, x_axis, y_axis] = titles.value;
273
273
  dict.form = DdbForm.chart;
274
274
  dict.value = {
@@ -279,6 +279,8 @@ export class DdbObj {
279
279
  x_axis,
280
280
  y_axis,
281
281
  },
282
+ ...bin_start ? { bin_start, bin_end, } : {},
283
+ ...bin_count ? { bin_count } : {},
282
284
  ...extras ? (() => {
283
285
  const { multiYAxes: multi_y_axes = false, ...extras_others } = extras.to_dict({ strip: true });
284
286
  return {
@@ -866,10 +868,17 @@ export class DdbObj {
866
868
  value[1].pack(),
867
869
  ];
868
870
  case DdbForm.chart: {
869
- const { type, stacking, titles: { chart, x_axis, y_axis, }, extras, data } = this.value;
871
+ const { type, stacking, bin_start, bin_end, bin_count, titles: { chart, x_axis, y_axis, }, extras, data } = this.value;
870
872
  const { value: [keys, values] } = new DdbDict({
871
873
  chartType: new DdbInt(type),
872
874
  stacking,
875
+ ...bin_start ? {
876
+ binStart: bin_start,
877
+ binEnd: bin_end
878
+ } : {},
879
+ ...bin_count ? {
880
+ binCount: bin_count
881
+ } : {},
873
882
  title: new DdbVectorString([chart, x_axis, y_axis]),
874
883
  ...extras ? (() => {
875
884
  const { multi_y_axes, ...extras_other } = extras;
@@ -1101,7 +1110,7 @@ export class DdbObj {
1101
1110
  case DdbForm.table:
1102
1111
  return `table[${this.rows}r][${this.cols}c]`;
1103
1112
  case DdbForm.dict:
1104
- return `dict<${DdbType[this.value[0].type]}, ${DdbType[this.value[1].type]}>`;
1113
+ return `dict<${DdbType[this.value[0].type]}, ${DdbType[this.value[1].type]}>[${this.rows}]`;
1105
1114
  case DdbForm.chart:
1106
1115
  return `chart<${DdbChartType[this.value.type]}>`;
1107
1116
  case DdbForm.matrix:
@@ -1200,7 +1209,8 @@ export class DdbObj {
1200
1209
  return obj;
1201
1210
  }
1202
1211
  }
1203
- export function format(type, value, le) {
1212
+ /** Formats a single element (value) as a string according to DdbType, null returns a 'null' string */
1213
+ export function format(type, value, le, options = {}) {
1204
1214
  switch (type) {
1205
1215
  case DdbType.bool:
1206
1216
  return String((value === null || value === nulls.int8) ?
@@ -1336,6 +1346,66 @@ export function format(type, value, le) {
1336
1346
  return String(value);
1337
1347
  }
1338
1348
  }
1349
+ /** Format vector, the index-th item in the collection is a string, a null value returns a 'null' string */
1350
+ export function formati(obj, index, options = {}) {
1351
+ if (64 <= obj.type && obj.type < 128) { // array vector
1352
+ // 因为 array vector 目前只支持:Logical, Integral(不包括 INT128, COMPRESS 类型), Floating, Temporal
1353
+ // 都对应 TypedArray 中的一格,所以 lengths.length 等于 block 中的 row 的个数
1354
+ // av = array(INT[], 0, 5)
1355
+ // append!(av, [1..1])
1356
+ // append!(av, [1..70000])
1357
+ // append!(av, [1..1])
1358
+ // append!(av, [1..500])
1359
+ // ...
1360
+ // av
1361
+ const _type = obj.type - 64;
1362
+ let offset = 0;
1363
+ for (const { lengths, data, rows } of obj.value) {
1364
+ let acc_len = 0;
1365
+ if (offset + rows <= index) {
1366
+ offset += rows;
1367
+ continue; // 跳过这个 block
1368
+ }
1369
+ for (const length of lengths) {
1370
+ if (offset < index) {
1371
+ offset++;
1372
+ acc_len += length;
1373
+ continue;
1374
+ }
1375
+ const limit = 10;
1376
+ let items = new Array(Math.min(limit, length));
1377
+ for (let i = 0; i < items.length; i++)
1378
+ items[i] = format(_type, data[acc_len + i], obj.le, options);
1379
+ return (items.join(', ') + (length > limit ? ', ...' : '')).bracket('square');
1380
+ }
1381
+ }
1382
+ }
1383
+ switch (obj.type) {
1384
+ case DdbType.string:
1385
+ case DdbType.symbol:
1386
+ return obj.value[index];
1387
+ case DdbType.symbol_extended: {
1388
+ const { base, data } = obj.value;
1389
+ return base[data[index]];
1390
+ }
1391
+ case DdbType.uuid:
1392
+ case DdbType.int128:
1393
+ case DdbType.ipaddr:
1394
+ return format(obj.type, obj.value.subarray(16 * index, 16 * (index + 1)), obj.le, options);
1395
+ case DdbType.blob: {
1396
+ const value = obj.value[index];
1397
+ return value.length > 100 ?
1398
+ DdbObj.dec.decode(value.subarray(0, 98)) + '…'
1399
+ :
1400
+ DdbObj.dec.decode(value);
1401
+ }
1402
+ case DdbType.complex:
1403
+ case DdbType.point:
1404
+ return format(obj.type, obj.value.subarray(2 * index, 2 * (index + 1)), obj.le, options);
1405
+ default:
1406
+ return format(obj.type, obj.value[index], obj.le, options);
1407
+ }
1408
+ }
1339
1409
  export class DdbVoid extends DdbObj {
1340
1410
  constructor() {
1341
1411
  super({
@@ -1879,13 +1949,16 @@ export class DDB {
1879
1949
  password = '123456';
1880
1950
  /** python session flag (2048) */
1881
1951
  python = false;
1952
+ // 内部选项, 状态
1882
1953
  print_message_buffer = false;
1883
1954
  print_object_buffer = false;
1884
1955
  print_message = true;
1885
1956
  parse_object = true;
1957
+ pnode_run_defined = false;
1886
1958
  /** DdbMessage listeners */
1887
1959
  listeners = [];
1888
1960
  pconnect = Promise.resolve();
1961
+ ppnoderun = Promise.resolve();
1889
1962
  presult = Promise.resolve(null);
1890
1963
  get connected() {
1891
1964
  return this.websocket?.readyState === WebSocket.OPEN;
@@ -1959,41 +2032,6 @@ export class DDB {
1959
2032
  this.on_message(event);
1960
2033
  }
1961
2034
  });
1962
- await this.eval(this.python ?
1963
- 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
1964
- ' nargs = size(args)\n' +
1965
- ' func = funcByName(func_name)\n' +
1966
- ' \n' +
1967
- ' if not nargs:\n' +
1968
- ' return pnodeRun(func, nodes, add_node_alias)\n' +
1969
- ' \n' +
1970
- ' args_partial = [ ]\n' +
1971
- ' args_partial.append(func)\n' +
1972
- ' for a in args:\n' +
1973
- ' args_partial.append(a)\n' +
1974
- ' \n' +
1975
- ' return pnodeRun(\n' +
1976
- ' unifiedCall(partial, args_partial),\n' +
1977
- ' nodes,\n' +
1978
- ' add_node_alias\n' +
1979
- ' )\n'
1980
- :
1981
- 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
1982
- ' nargs = size(args)\n' +
1983
- ' func = funcByName(func_name)\n' +
1984
- ' \n' +
1985
- ' if (!nargs)\n' +
1986
- ' return pnodeRun(func, nodes, add_node_alias)\n' +
1987
- ' \n' +
1988
- ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
1989
- ' args_partial[0] = func\n' +
1990
- ' args_partial[1:] = args\n' +
1991
- ' return pnodeRun(\n' +
1992
- ' unifiedCall(partial, args_partial),\n' +
1993
- ' nodes,\n' +
1994
- ' add_node_alias\n' +
1995
- ' )\n' +
1996
- '}\n', { urgent: true });
1997
2035
  if (this.autologin)
1998
2036
  if (this.python)
1999
2037
  await this.eval(`login(${this.username.quote('double')}, ${this.password.quote('double')})`, { urgent: true });
@@ -2037,6 +2075,7 @@ export class DDB {
2037
2075
  this.on_message = () => { };
2038
2076
  this.presult = Promise.resolve(null);
2039
2077
  this.pconnect = Promise.resolve();
2078
+ this.pnode_run_defined = false;
2040
2079
  }
2041
2080
  /** rpc through websocket (function/script/variable command)
2042
2081
  - type: API 类型: 'script' | 'function' | 'variable'
@@ -2065,6 +2104,55 @@ export class DDB {
2065
2104
  }
2066
2105
  if (!this.connected)
2067
2106
  throw new Error(`${this.url} is already disconnected`);
2107
+ if (func === 'pnode_run' && !this.pnode_run_defined) {
2108
+ const ptail = this.ppnoderun;
2109
+ let resolve;
2110
+ this.ppnoderun = new Promise((_resolve, _reject) => {
2111
+ resolve = _resolve;
2112
+ });
2113
+ await ptail;
2114
+ try {
2115
+ if (!this.pnode_run_defined)
2116
+ await this.eval(this.python ?
2117
+ 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
2118
+ ' nargs = size(args)\n' +
2119
+ ' func = funcByName(func_name)\n' +
2120
+ ' \n' +
2121
+ ' if not nargs:\n' +
2122
+ ' return pnodeRun(func, nodes, add_node_alias)\n' +
2123
+ ' \n' +
2124
+ ' args_partial = [ ]\n' +
2125
+ ' args_partial.append(func)\n' +
2126
+ ' for a in args:\n' +
2127
+ ' args_partial.append(a)\n' +
2128
+ ' \n' +
2129
+ ' return pnodeRun(\n' +
2130
+ ' unifiedCall(partial, args_partial),\n' +
2131
+ ' nodes,\n' +
2132
+ ' add_node_alias\n' +
2133
+ ' )\n'
2134
+ :
2135
+ 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
2136
+ ' nargs = size(args)\n' +
2137
+ ' func = funcByName(func_name)\n' +
2138
+ ' \n' +
2139
+ ' if (!nargs)\n' +
2140
+ ' return pnodeRun(func, nodes, add_node_alias)\n' +
2141
+ ' \n' +
2142
+ ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
2143
+ ' args_partial[0] = func\n' +
2144
+ ' args_partial[1:] = args\n' +
2145
+ ' return pnodeRun(\n' +
2146
+ ' unifiedCall(partial, args_partial),\n' +
2147
+ ' nodes,\n' +
2148
+ ' add_node_alias\n' +
2149
+ ' )\n' +
2150
+ '}\n', { urgent: true });
2151
+ }
2152
+ finally {
2153
+ resolve();
2154
+ }
2155
+ }
2068
2156
  // this 上的当前配置需要在 message 到达后使用,先保存起来
2069
2157
  const _handlers = [...this.listeners].reverse();
2070
2158
  // 临界区:保证多个 rpc 并发时形成 promise 链