dolphindb 2.0.506 → 2.0.507
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 +17 -20
- package/browser.js +65 -77
- package/browser.js.map +1 -1
- package/index.d.ts +34 -35
- package/index.js +82 -92
- package/index.js.map +1 -1
- package/package.json +3 -3
package/browser.d.ts
CHANGED
|
@@ -124,12 +124,11 @@ export declare class DdbObj<T extends DdbValue = DdbValue> {
|
|
|
124
124
|
datatype?: DdbType;
|
|
125
125
|
/** 实际数据。不同的 DdbForm, DdbType 使用 DdbValue 中不同的类型来表示实际数据 */
|
|
126
126
|
value: T;
|
|
127
|
-
/**
|
|
127
|
+
/** 原始二进制数据,仅在 parse_object 为 false 时通过 parse_message 生成的顶层对象有这个属性 */
|
|
128
128
|
buffer?: Uint8Array;
|
|
129
129
|
constructor(data: Partial<DdbObj> & {
|
|
130
130
|
form: DdbForm;
|
|
131
131
|
type: DdbType;
|
|
132
|
-
length: number;
|
|
133
132
|
});
|
|
134
133
|
static parse(buf: Uint8Array, le: boolean): DdbObj<DdbValue>;
|
|
135
134
|
static parse_scalar(buf: Uint8Array, le: boolean, type: DdbType): [number, DdbValue];
|
|
@@ -275,12 +274,9 @@ export declare class DDB {
|
|
|
275
274
|
print_object_buffer: boolean;
|
|
276
275
|
print_message: boolean;
|
|
277
276
|
parse_object: boolean;
|
|
278
|
-
/**
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
presolver(ddbobj: DdbObj): void;
|
|
282
|
-
prejector(error: Error): void;
|
|
283
|
-
presult: Promise<DdbObj<DdbValue>>;
|
|
277
|
+
/** DdbMessage listeners */
|
|
278
|
+
listeners: DdbMessageListener[];
|
|
279
|
+
promise: Promise<any>;
|
|
284
280
|
get connected(): boolean;
|
|
285
281
|
/**
|
|
286
282
|
Initialize an instance of DolphinDB Client using the WebSocket URL
|
|
@@ -309,6 +305,7 @@ export declare class DDB {
|
|
|
309
305
|
password?: string;
|
|
310
306
|
python?: boolean;
|
|
311
307
|
});
|
|
308
|
+
private on_message;
|
|
312
309
|
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL
|
|
313
310
|
- options?:
|
|
314
311
|
- url?: DolphinDB WebSocket URL. By default, the WebSocket URL passed in when the instance is initialized is used
|
|
@@ -353,31 +350,31 @@ export declare class DDB {
|
|
|
353
350
|
- options:
|
|
354
351
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
355
352
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
356
|
-
-
|
|
353
|
+
- listener?: 处理本次 rpc 期间的消息 (DdbMessage)
|
|
357
354
|
- parse_object?: 在本次 rpc 期间设置 parse_object, 结束后恢复原有
|
|
358
355
|
为 false 时返回的 DdbObj 仅含有 buffer 和 le,不做解析,以便后续转发、序列化
|
|
359
356
|
*/
|
|
360
|
-
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, listener, parse_object, }: {
|
|
361
358
|
script?: string;
|
|
362
359
|
func?: string;
|
|
363
360
|
args?: (DdbObj | string | boolean)[];
|
|
364
361
|
vars?: string[];
|
|
365
362
|
urgent?: boolean;
|
|
366
|
-
|
|
363
|
+
listener?: DdbMessageListener;
|
|
367
364
|
parse_object?: boolean;
|
|
368
365
|
}): Promise<T>;
|
|
369
366
|
/** eval script through websocket (script command)
|
|
370
367
|
- script?: Script to execute
|
|
371
368
|
- options?: execution options
|
|
372
369
|
- urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
|
|
373
|
-
-
|
|
370
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
374
371
|
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
375
372
|
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
376
373
|
so as to facilitate subsequent forwarding and serialization
|
|
377
374
|
*/
|
|
378
|
-
eval<T extends DdbObj>(script: string, { urgent,
|
|
375
|
+
eval<T extends DdbObj>(script: string, { urgent, listener, parse_object, }?: {
|
|
379
376
|
urgent?: boolean;
|
|
380
|
-
|
|
377
|
+
listener?: DdbMessageListener;
|
|
381
378
|
parse_object?: boolean;
|
|
382
379
|
}): Promise<T>;
|
|
383
380
|
/** call function through websocket (function command)
|
|
@@ -389,18 +386,18 @@ export declare class DDB {
|
|
|
389
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)
|
|
390
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
|
|
391
388
|
- add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
|
|
392
|
-
-
|
|
389
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
393
390
|
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
394
391
|
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
395
392
|
so as to facilitate subsequent forwarding and serialization
|
|
396
393
|
*/
|
|
397
|
-
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, listener, parse_object, }?: {
|
|
398
395
|
urgent?: boolean;
|
|
399
396
|
node?: string;
|
|
400
397
|
nodes?: string[];
|
|
401
398
|
func_type?: DdbFunctionType;
|
|
402
399
|
add_node_alias?: boolean;
|
|
403
|
-
|
|
400
|
+
listener?: DdbMessageListener;
|
|
404
401
|
parse_object?: boolean;
|
|
405
402
|
}): Promise<T>;
|
|
406
403
|
/** upload variable through websocket (variable command) */
|
|
@@ -408,8 +405,8 @@ export declare class DDB {
|
|
|
408
405
|
/** Uploaded variables' name */
|
|
409
406
|
vars: string[],
|
|
410
407
|
/** Uploaded variables' value */
|
|
411
|
-
args: (DdbObj | string | boolean)[], {
|
|
412
|
-
|
|
408
|
+
args: (DdbObj | string | boolean)[], { listener, parse_object, }?: {
|
|
409
|
+
listener?: DdbMessageListener;
|
|
413
410
|
parse_object?: boolean;
|
|
414
411
|
}): Promise<DdbObj<DdbValue>>;
|
|
415
412
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
@@ -419,7 +416,7 @@ export declare class DDB {
|
|
|
419
416
|
/** 转换 js 数组为 DdbObj[] */
|
|
420
417
|
to_ddbobjs(values: any[]): DdbObj<DdbValue>[];
|
|
421
418
|
}
|
|
422
|
-
export interface
|
|
419
|
+
export interface DdbMessageListener {
|
|
423
420
|
(message: DdbMessage, _this: DDB): any;
|
|
424
421
|
}
|
|
425
422
|
export interface DdbPrintMessage {
|
package/browser.js
CHANGED
|
@@ -890,21 +890,26 @@ class DdbObj {
|
|
|
890
890
|
for (let i = 0; i < this.rows; i++) {
|
|
891
891
|
let row = {};
|
|
892
892
|
for (let j = 0; j < this.cols; j++) {
|
|
893
|
-
const { type, name, value } = this.value[j]; // column
|
|
893
|
+
const { type, name, value: values } = this.value[j]; // column
|
|
894
894
|
switch (type) {
|
|
895
|
-
case DdbType.bool:
|
|
896
|
-
|
|
895
|
+
case DdbType.bool: {
|
|
896
|
+
const value = values[i];
|
|
897
|
+
row[name] = value === exports.nulls.int8 ?
|
|
898
|
+
null
|
|
899
|
+
:
|
|
900
|
+
Boolean(value);
|
|
897
901
|
break;
|
|
902
|
+
}
|
|
898
903
|
case DdbType.ipaddr:
|
|
899
|
-
row[name] =
|
|
904
|
+
row[name] = values.subarray(16 * i, 16 * (i + 1));
|
|
900
905
|
break;
|
|
901
906
|
case DdbType.symbol_extended: {
|
|
902
|
-
const { base, data } =
|
|
907
|
+
const { base, data } = values;
|
|
903
908
|
row[name] = base[data[i]];
|
|
904
909
|
break;
|
|
905
910
|
}
|
|
906
911
|
default:
|
|
907
|
-
row[name] =
|
|
912
|
+
row[name] = values[i];
|
|
908
913
|
}
|
|
909
914
|
}
|
|
910
915
|
rows[i] = row;
|
|
@@ -1371,9 +1376,9 @@ class DDB {
|
|
|
1371
1376
|
this.print_object_buffer = false;
|
|
1372
1377
|
this.print_message = true;
|
|
1373
1378
|
this.parse_object = true;
|
|
1374
|
-
/**
|
|
1375
|
-
this.
|
|
1376
|
-
this.
|
|
1379
|
+
/** DdbMessage listeners */
|
|
1380
|
+
this.listeners = [];
|
|
1381
|
+
this.promise = Promise.resolve(null);
|
|
1377
1382
|
if (!url) {
|
|
1378
1383
|
const _url = new URL(location.href);
|
|
1379
1384
|
const hostname = _url.searchParams.get('hostname') || location.hostname;
|
|
@@ -1390,12 +1395,10 @@ class DDB {
|
|
|
1390
1395
|
if (options.python !== undefined)
|
|
1391
1396
|
this.python = options.python;
|
|
1392
1397
|
}
|
|
1393
|
-
/** resolver, rejector, promise of last rpc */
|
|
1394
|
-
presolver(ddbobj) { }
|
|
1395
|
-
prejector(error) { }
|
|
1396
1398
|
get connected() {
|
|
1397
1399
|
return this.websocket?.readyState === WebSocket.OPEN;
|
|
1398
1400
|
}
|
|
1401
|
+
on_message(event) { }
|
|
1399
1402
|
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL
|
|
1400
1403
|
- options?:
|
|
1401
1404
|
- url?: DolphinDB WebSocket URL. By default, the WebSocket URL passed in when the instance is initialized is used
|
|
@@ -1423,30 +1426,7 @@ class DDB {
|
|
|
1423
1426
|
await this.rpc('connect', {});
|
|
1424
1427
|
},
|
|
1425
1428
|
on_message: event => {
|
|
1426
|
-
|
|
1427
|
-
if (this.print_message_buffer)
|
|
1428
|
-
console.log(buf);
|
|
1429
|
-
const message = this.parse_message(buf);
|
|
1430
|
-
if (this.handlers.length) {
|
|
1431
|
-
const _handlers = [...this.handlers].reverse();
|
|
1432
|
-
for (const handler of _handlers)
|
|
1433
|
-
handler(message, this);
|
|
1434
|
-
}
|
|
1435
|
-
const { type, data } = message;
|
|
1436
|
-
switch (type) {
|
|
1437
|
-
case 'print':
|
|
1438
|
-
if (this.print_message)
|
|
1439
|
-
console.log(data);
|
|
1440
|
-
return;
|
|
1441
|
-
case 'object':
|
|
1442
|
-
if (this.print_object_buffer)
|
|
1443
|
-
console.log(data.buffer);
|
|
1444
|
-
this.presolver(data);
|
|
1445
|
-
return;
|
|
1446
|
-
case 'error':
|
|
1447
|
-
this.prejector(data);
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1429
|
+
this.on_message(event);
|
|
1450
1430
|
}
|
|
1451
1431
|
});
|
|
1452
1432
|
await this.eval(this.python ?
|
|
@@ -1524,45 +1504,64 @@ class DDB {
|
|
|
1524
1504
|
disconnect() {
|
|
1525
1505
|
if (this.connected)
|
|
1526
1506
|
this.websocket.close(1000);
|
|
1527
|
-
this.
|
|
1528
|
-
this.
|
|
1529
|
-
this.presult = Promise.resolve(null);
|
|
1507
|
+
this.on_message = () => { };
|
|
1508
|
+
this.promise = Promise.resolve(null);
|
|
1530
1509
|
}
|
|
1531
1510
|
/** rpc through websocket (function/script/variable command)
|
|
1532
1511
|
- type: API 类型: 'script' | 'function' | 'variable'
|
|
1533
1512
|
- options:
|
|
1534
1513
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
1535
1514
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
1536
|
-
-
|
|
1515
|
+
- listener?: 处理本次 rpc 期间的消息 (DdbMessage)
|
|
1537
1516
|
- parse_object?: 在本次 rpc 期间设置 parse_object, 结束后恢复原有
|
|
1538
1517
|
为 false 时返回的 DdbObj 仅含有 buffer 和 le,不做解析,以便后续转发、序列化
|
|
1539
1518
|
*/
|
|
1540
|
-
async rpc(type, { script, func, args = [], vars = [], urgent,
|
|
1519
|
+
async rpc(type, { script, func, args = [], vars = [], urgent, listener, parse_object, }) {
|
|
1541
1520
|
if (!this.websocket)
|
|
1542
1521
|
await this.connect();
|
|
1543
1522
|
if (!this.connected)
|
|
1544
1523
|
throw new Error(`${this.url} is already disconnected`);
|
|
1524
|
+
// this 上的当前配置需要在 message 到达后使用,先保存起来
|
|
1525
|
+
const _handlers = [...this.listeners].reverse();
|
|
1545
1526
|
// 临界区:保证多个 rpc 并发时形成 promise 链
|
|
1546
1527
|
// ddb 世界观:需要等待上一个 rpc 结果从 server 返回之后才能发起下一个调用
|
|
1547
1528
|
// 违反世界观可能造成:
|
|
1548
1529
|
// 1. 并发多个请求只返回第一个结果(阻塞,需后续请求疏通)
|
|
1549
1530
|
// 2. windows 下 ddb server 返回多个相同的结果
|
|
1550
|
-
const ptail = this.
|
|
1551
|
-
let
|
|
1552
|
-
let
|
|
1553
|
-
const
|
|
1554
|
-
|
|
1555
|
-
|
|
1531
|
+
const ptail = this.promise;
|
|
1532
|
+
let resolve;
|
|
1533
|
+
let reject;
|
|
1534
|
+
const promise = this.promise = new Promise((_resolve, _reject) => {
|
|
1535
|
+
resolve = _resolve;
|
|
1536
|
+
reject = _reject;
|
|
1556
1537
|
});
|
|
1557
1538
|
try {
|
|
1558
1539
|
await ptail;
|
|
1559
1540
|
}
|
|
1560
1541
|
catch { }
|
|
1561
|
-
this.
|
|
1562
|
-
this.
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1542
|
+
// 临界区结束,只有一个 rpc 函数调用运行到这里,可以独占 this.on_message 然后写 WebSocket
|
|
1543
|
+
this.on_message = ({ data: buffer }) => {
|
|
1544
|
+
const buf = new Uint8Array(buffer);
|
|
1545
|
+
if (this.print_message_buffer)
|
|
1546
|
+
console.log(buf);
|
|
1547
|
+
const message = this.parse_message(buf, parse_object);
|
|
1548
|
+
listener?.(message, this);
|
|
1549
|
+
for (const listener of _handlers)
|
|
1550
|
+
listener(message, this);
|
|
1551
|
+
const { type, data } = message;
|
|
1552
|
+
switch (type) {
|
|
1553
|
+
case 'print':
|
|
1554
|
+
if (this.print_message)
|
|
1555
|
+
console.log(data);
|
|
1556
|
+
return;
|
|
1557
|
+
case 'object':
|
|
1558
|
+
resolve(data);
|
|
1559
|
+
return;
|
|
1560
|
+
case 'error':
|
|
1561
|
+
reject(data);
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
};
|
|
1566
1565
|
args = this.to_ddbobjs(args);
|
|
1567
1566
|
const command = this.enc.encode((() => {
|
|
1568
1567
|
switch (type) {
|
|
@@ -1583,37 +1582,24 @@ class DDB {
|
|
|
1583
1582
|
return 'connect\n';
|
|
1584
1583
|
}
|
|
1585
1584
|
})());
|
|
1586
|
-
|
|
1585
|
+
this.websocket.send((0, utils_browser_1.concat)([
|
|
1587
1586
|
this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
|
|
1588
1587
|
command,
|
|
1589
1588
|
...args.map((arg) => arg.pack())
|
|
1590
|
-
]);
|
|
1591
|
-
|
|
1592
|
-
if (handler)
|
|
1593
|
-
this.handlers.push(handler);
|
|
1594
|
-
if (parse_object !== undefined)
|
|
1595
|
-
this.parse_object = parse_object;
|
|
1596
|
-
try {
|
|
1597
|
-
this.websocket.send(message);
|
|
1598
|
-
return (await presult);
|
|
1599
|
-
}
|
|
1600
|
-
finally {
|
|
1601
|
-
if (handler)
|
|
1602
|
-
this.handlers = this.handlers.filter(h => h !== handler);
|
|
1603
|
-
this.parse_object = _parse_object;
|
|
1604
|
-
}
|
|
1589
|
+
]));
|
|
1590
|
+
return promise;
|
|
1605
1591
|
}
|
|
1606
1592
|
/** eval script through websocket (script command)
|
|
1607
1593
|
- script?: Script to execute
|
|
1608
1594
|
- options?: execution options
|
|
1609
1595
|
- urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
|
|
1610
|
-
-
|
|
1596
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
1611
1597
|
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1612
1598
|
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1613
1599
|
so as to facilitate subsequent forwarding and serialization
|
|
1614
1600
|
*/
|
|
1615
|
-
async eval(script, { urgent,
|
|
1616
|
-
return this.rpc('script', { script, urgent,
|
|
1601
|
+
async eval(script, { urgent, listener, parse_object, } = {}) {
|
|
1602
|
+
return this.rpc('script', { script, urgent, listener, parse_object });
|
|
1617
1603
|
}
|
|
1618
1604
|
/** call function through websocket (function command)
|
|
1619
1605
|
- func: function name
|
|
@@ -1624,12 +1610,12 @@ class DDB {
|
|
|
1624
1610
|
- nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
|
|
1625
1611
|
- func_type?: It must be passed when setting the node parameter, the function type needs to be specified, and it is not passed in other cases
|
|
1626
1612
|
- add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
|
|
1627
|
-
-
|
|
1613
|
+
- listener?: Process messages during this rpc (DdbMessage)
|
|
1628
1614
|
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1629
1615
|
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1630
1616
|
so as to facilitate subsequent forwarding and serialization
|
|
1631
1617
|
*/
|
|
1632
|
-
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias,
|
|
1618
|
+
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, } = {}) {
|
|
1633
1619
|
if (node) {
|
|
1634
1620
|
if (typeof func_type === 'undefined')
|
|
1635
1621
|
throw new Error('指定 node 时必须设置 func_type');
|
|
@@ -1659,7 +1645,7 @@ class DDB {
|
|
|
1659
1645
|
func,
|
|
1660
1646
|
args,
|
|
1661
1647
|
urgent,
|
|
1662
|
-
|
|
1648
|
+
listener,
|
|
1663
1649
|
parse_object
|
|
1664
1650
|
});
|
|
1665
1651
|
}
|
|
@@ -1668,10 +1654,10 @@ class DDB {
|
|
|
1668
1654
|
/** Uploaded variables' name */
|
|
1669
1655
|
vars,
|
|
1670
1656
|
/** Uploaded variables' value */
|
|
1671
|
-
args, {
|
|
1657
|
+
args, { listener, parse_object, } = {}) {
|
|
1672
1658
|
if (!args.length || args.length !== vars.length)
|
|
1673
1659
|
throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
|
|
1674
|
-
return this.rpc('variable', { vars, args,
|
|
1660
|
+
return this.rpc('variable', { vars, args, listener, parse_object });
|
|
1675
1661
|
}
|
|
1676
1662
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
1677
1663
|
parse_message(buf, parse_object = this.parse_object) {
|
|
@@ -1709,10 +1695,12 @@ class DDB {
|
|
|
1709
1695
|
data: new Error(message)
|
|
1710
1696
|
};
|
|
1711
1697
|
const buf_obj = buf.subarray(i_lf_1 + 1);
|
|
1698
|
+
if (this.print_object_buffer)
|
|
1699
|
+
console.log(buf_obj);
|
|
1712
1700
|
return {
|
|
1713
1701
|
type: 'object',
|
|
1714
1702
|
data: parse_object ?
|
|
1715
|
-
|
|
1703
|
+
DdbObj.parse(buf_obj, this.le)
|
|
1716
1704
|
:
|
|
1717
1705
|
new DdbObj({
|
|
1718
1706
|
form: DdbForm.scalar,
|