dolphindb 2.0.1022 → 2.0.1024
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 +3 -1
- package/browser.js +86 -78
- package/browser.js.map +1 -1
- package/docs.en.json +55 -29
- package/docs.zh.json +88 -57
- package/i18n/dict.json +3 -0
- package/index.d.ts +3 -1
- package/index.js +86 -78
- package/index.js.map +1 -1
- package/package.json +6 -6
package/browser.d.ts
CHANGED
|
@@ -372,6 +372,7 @@ export interface DdbRpcOptions {
|
|
|
372
372
|
listener?: DdbMessageListener;
|
|
373
373
|
parse_object?: boolean;
|
|
374
374
|
skip_connection_check?: boolean;
|
|
375
|
+
on_more_messages?: (buffer: Uint8Array) => void;
|
|
375
376
|
}
|
|
376
377
|
export declare class DdbConnectionError extends Error {
|
|
377
378
|
name: string;
|
|
@@ -571,7 +572,7 @@ export declare class DDB {
|
|
|
571
572
|
将这个 flag 设为 true 跳过连接状态检查
|
|
572
573
|
(internal use) When await ddb.connect() establishes a connection for the first time, you cannot call await this.connect() again to ensure the connection status, which will lead to circular dependencies.
|
|
573
574
|
Set this flag to true to skip connection status checks */
|
|
574
|
-
call<TResult extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, skip_connection_check }?: {
|
|
575
|
+
call<TResult extends DdbObj>(func: string, args?: (DdbObj | string | boolean)[], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, skip_connection_check, on_more_messages }?: {
|
|
575
576
|
urgent?: boolean;
|
|
576
577
|
node?: string;
|
|
577
578
|
nodes?: string[];
|
|
@@ -580,6 +581,7 @@ export declare class DDB {
|
|
|
580
581
|
listener?: DdbMessageListener;
|
|
581
582
|
parse_object?: boolean;
|
|
582
583
|
skip_connection_check?: boolean;
|
|
584
|
+
on_more_messages?: DdbRpcOptions['on_more_messages'];
|
|
583
585
|
}): Promise<TResult>;
|
|
584
586
|
/** upload variable through websocket (variable command) */
|
|
585
587
|
upload(
|
package/browser.js
CHANGED
|
@@ -2256,7 +2256,7 @@ export class DDB {
|
|
|
2256
2256
|
this.lwebsocket.resource = await connect_websocket(this.url, {
|
|
2257
2257
|
protocols: this.streaming ? ['streaming'] : this.python ? ['python'] : undefined,
|
|
2258
2258
|
on_message: (buffer, websocket) => {
|
|
2259
|
-
this.on_message(buffer, websocket);
|
|
2259
|
+
this.on_message(new Uint8Array(buffer), websocket);
|
|
2260
2260
|
},
|
|
2261
2261
|
on_error: error => {
|
|
2262
2262
|
this.error ??= new DdbConnectionError(this.url, error);
|
|
@@ -2342,7 +2342,7 @@ export class DDB {
|
|
|
2342
2342
|
let error = new DdbDatabaseError('', this.url, type, options, id);
|
|
2343
2343
|
if (!options.skip_connection_check)
|
|
2344
2344
|
await this.connect();
|
|
2345
|
-
const { script, func, args: _args = [], vars = [], urgent, listener, } = options;
|
|
2345
|
+
const { script, func, args: _args = [], vars = [], urgent, listener, on_more_messages, } = options;
|
|
2346
2346
|
if (func === 'pnode_run')
|
|
2347
2347
|
await (this.ppnode_run ??= this.eval(this.python ?
|
|
2348
2348
|
'\n' +
|
|
@@ -2443,37 +2443,42 @@ export class DDB {
|
|
|
2443
2443
|
})());
|
|
2444
2444
|
// 使用资源发送请求并等待请求完成
|
|
2445
2445
|
const result = await new Promise((resolve, reject) => {
|
|
2446
|
+
let first_message = true;
|
|
2446
2447
|
this.on_error = () => {
|
|
2447
2448
|
// 这里一定有了 this.error, 不需要再 || new DdbConnectionError(this)
|
|
2448
2449
|
reject(this.error);
|
|
2449
2450
|
};
|
|
2450
2451
|
this.on_message = buffer => {
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2452
|
+
if (!on_more_messages || first_message)
|
|
2453
|
+
try {
|
|
2454
|
+
if (this.print_message_buffer)
|
|
2455
|
+
console.log(buffer);
|
|
2456
|
+
const message = this.parse_message(buffer, error);
|
|
2457
|
+
listener?.(message, this);
|
|
2458
|
+
for (const listener of _listeners)
|
|
2459
|
+
listener(message, this);
|
|
2460
|
+
const { type, data } = message;
|
|
2461
|
+
switch (type) {
|
|
2462
|
+
case 'print':
|
|
2463
|
+
if (this.print_message)
|
|
2464
|
+
console.log(data);
|
|
2465
|
+
break;
|
|
2466
|
+
case 'object':
|
|
2467
|
+
first_message = false;
|
|
2468
|
+
resolve(data);
|
|
2469
|
+
break;
|
|
2470
|
+
case 'error':
|
|
2471
|
+
first_message = false;
|
|
2472
|
+
reject(data);
|
|
2473
|
+
break;
|
|
2474
|
+
}
|
|
2471
2475
|
}
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2476
|
+
catch (error) {
|
|
2477
|
+
// 这里的错误并非 websocket 错误,而是 rpc 错误
|
|
2478
|
+
reject(error);
|
|
2479
|
+
}
|
|
2480
|
+
else
|
|
2481
|
+
on_more_messages(buffer);
|
|
2477
2482
|
};
|
|
2478
2483
|
websocket.send(concat([
|
|
2479
2484
|
this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
|
|
@@ -2527,7 +2532,7 @@ export class DDB {
|
|
|
2527
2532
|
将这个 flag 设为 true 跳过连接状态检查
|
|
2528
2533
|
(internal use) When await ddb.connect() establishes a connection for the first time, you cannot call await this.connect() again to ensure the connection status, which will lead to circular dependencies.
|
|
2529
2534
|
Set this flag to true to skip connection status checks */
|
|
2530
|
-
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, skip_connection_check } = {}) {
|
|
2535
|
+
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, listener, parse_object, skip_connection_check, on_more_messages } = {}) {
|
|
2531
2536
|
if (node) {
|
|
2532
2537
|
assert(func_type in DdbFunctionType, t('指定 node 时必须设置 func_type'));
|
|
2533
2538
|
args = [
|
|
@@ -2558,7 +2563,8 @@ export class DDB {
|
|
|
2558
2563
|
urgent,
|
|
2559
2564
|
listener,
|
|
2560
2565
|
parse_object,
|
|
2561
|
-
skip_connection_check
|
|
2566
|
+
skip_connection_check,
|
|
2567
|
+
on_more_messages
|
|
2562
2568
|
});
|
|
2563
2569
|
}
|
|
2564
2570
|
/** upload variable through websocket (variable command) */
|
|
@@ -2640,6 +2646,12 @@ export class DDB {
|
|
|
2640
2646
|
}
|
|
2641
2647
|
/** 内部的流订阅方法 Internal stream subscription method */
|
|
2642
2648
|
async subscribe() {
|
|
2649
|
+
let win = {
|
|
2650
|
+
offset: 0,
|
|
2651
|
+
rows: 0,
|
|
2652
|
+
segments: [],
|
|
2653
|
+
};
|
|
2654
|
+
let schema;
|
|
2643
2655
|
const { value: colnames } = await this.call('publishTable', [
|
|
2644
2656
|
'localhost',
|
|
2645
2657
|
new DdbInt(0),
|
|
@@ -2648,58 +2660,54 @@ export class DDB {
|
|
|
2648
2660
|
// new DdbInt(-1), // offset
|
|
2649
2661
|
// filter
|
|
2650
2662
|
// allow exists
|
|
2651
|
-
], {
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2663
|
+
], {
|
|
2664
|
+
skip_connection_check: true,
|
|
2665
|
+
// 先准备好收到 websocket message 的 callback
|
|
2666
|
+
on_more_messages: buffer => {
|
|
2667
|
+
try {
|
|
2668
|
+
const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
2669
|
+
const i_topic_end = buffer.indexOf(0, 17);
|
|
2670
|
+
// 首个 message 一定是 table schema, 后续消息是 column 片段组成的 any vector
|
|
2671
|
+
const data = DdbObj.parse(buffer.subarray(i_topic_end + 1), this.le);
|
|
2672
|
+
if (data.form === DdbForm.table) {
|
|
2673
|
+
schema = data;
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
assert(schema, t('流数据订阅后一定先返回 schema'));
|
|
2677
|
+
const { rows } = data.value[0];
|
|
2678
|
+
win.rows += rows;
|
|
2679
|
+
win.segments.push(data);
|
|
2680
|
+
if (win.rows >= winsize * 2 && win.segments.length >= 2) {
|
|
2681
|
+
let winsize_ = 0;
|
|
2682
|
+
let i = win.segments.length - 1;
|
|
2683
|
+
// 往前移动至首个累计 winsize_ 超过 winsize 的位置
|
|
2684
|
+
for (; winsize_ < winsize; i--)
|
|
2685
|
+
winsize_ += win.segments[i].value[0].rows;
|
|
2686
|
+
win.segments = win.segments.slice(i);
|
|
2687
|
+
win.offset += win.rows - winsize_;
|
|
2688
|
+
win.rows = winsize_;
|
|
2689
|
+
}
|
|
2690
|
+
this.streaming.handler({
|
|
2691
|
+
...this.streaming,
|
|
2692
|
+
id: dv.getBigInt64(9, this.le),
|
|
2693
|
+
time: dv.getBigInt64(1, this.le),
|
|
2694
|
+
rows,
|
|
2695
|
+
topic: this.dec.decode(buffer.subarray(17, i_topic_end)),
|
|
2696
|
+
colnames,
|
|
2697
|
+
schema,
|
|
2698
|
+
data,
|
|
2699
|
+
window: win,
|
|
2700
|
+
});
|
|
2672
2701
|
}
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
if (win.rows >= winsize * 2 && win.segments.length >= 2) {
|
|
2677
|
-
let winsize_ = 0;
|
|
2678
|
-
let i = win.segments.length - 1;
|
|
2679
|
-
// 往前移动至首个累计 winsize_ 超过 winsize 的位置
|
|
2680
|
-
for (; winsize_ < winsize; i--)
|
|
2681
|
-
winsize_ += win.segments[i].value[0].rows;
|
|
2682
|
-
win.segments = win.segments.slice(i);
|
|
2683
|
-
win.offset += win.rows - winsize_;
|
|
2684
|
-
win.rows = winsize_;
|
|
2702
|
+
catch (error) {
|
|
2703
|
+
// 将 error 交给 handler 处理
|
|
2704
|
+
this.streaming.handler({ ...this.streaming, error });
|
|
2685
2705
|
}
|
|
2686
|
-
this.streaming.handler({
|
|
2687
|
-
...this.streaming,
|
|
2688
|
-
id: dv.getBigInt64(9, this.le),
|
|
2689
|
-
time: dv.getBigInt64(1, this.le),
|
|
2690
|
-
rows,
|
|
2691
|
-
topic: this.dec.decode(buf.subarray(17, i_topic_end)),
|
|
2692
|
-
colnames,
|
|
2693
|
-
schema,
|
|
2694
|
-
data,
|
|
2695
|
-
window: win,
|
|
2696
|
-
});
|
|
2697
2706
|
}
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
};
|
|
2707
|
+
});
|
|
2708
|
+
console.log(t('订阅流表成功') + ', colnames:',
|
|
2709
|
+
// string[3](['time', 'stock', 'price'])
|
|
2710
|
+
colnames);
|
|
2703
2711
|
}
|
|
2704
2712
|
}
|
|
2705
2713
|
//# sourceMappingURL=browser.js.map
|