dolphindb 0.0.6 → 0.0.9
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 +16 -0
- package/README.zh.md +15 -0
- package/browser.d.ts +52 -13
- package/browser.js +126 -71
- package/browser.js.map +1 -1
- package/index.d.ts +53 -15
- package/index.js +131 -75
- package/index.js.map +1 -1
- package/package.json +6 -6
- package/test.js +1 -1
- package/test.js.map +1 -1
package/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DDB = exports.timestamp2str = exports.date2str = exports.DdbFunction = exports.DdbPair = exports.DdbVectorAny = exports.DdbVectorDouble = exports.DdbVectorString = exports.DdbVectorInt = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.ddb_sizes = exports.DdbType = exports.DdbForm = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const dayjs_1 = (0, tslib_1.__importDefault)(require("dayjs"));
|
|
6
5
|
const ws_1 = require("ws");
|
|
6
|
+
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
|
7
7
|
const utils_js_1 = require("xshell/utils.js");
|
|
8
8
|
var DdbForm;
|
|
9
9
|
(function (DdbForm) {
|
|
@@ -54,6 +54,7 @@ var DdbType;
|
|
|
54
54
|
DdbType[DdbType["complex"] = 34] = "complex";
|
|
55
55
|
DdbType[DdbType["point"] = 35] = "point";
|
|
56
56
|
DdbType[DdbType["duration"] = 36] = "duration";
|
|
57
|
+
DdbType[DdbType["object"] = 37] = "object";
|
|
57
58
|
DdbType[DdbType["symbol_extended"] = 145] = "symbol_extended";
|
|
58
59
|
})(DdbType = exports.DdbType || (exports.DdbType = {}));
|
|
59
60
|
exports.ddb_sizes = [
|
|
@@ -431,8 +432,8 @@ class DdbObj {
|
|
|
431
432
|
throw new Error(`array vector 存在非法 unit = ${unit}`);
|
|
432
433
|
}
|
|
433
434
|
let total_length = 0;
|
|
434
|
-
for (
|
|
435
|
-
total_length +=
|
|
435
|
+
for (const x of lengths)
|
|
436
|
+
total_length += x;
|
|
436
437
|
const [len_items, data] = this.parse_vector_items(buf.subarray(i_data_start), le, type - 64, total_length);
|
|
437
438
|
blocks.push({
|
|
438
439
|
unit,
|
|
@@ -807,6 +808,15 @@ class DdbObj {
|
|
|
807
808
|
throw new Error(`vector ${DdbType[type]} 暂不支持序列化`);
|
|
808
809
|
}
|
|
809
810
|
}
|
|
811
|
+
to_dict() {
|
|
812
|
+
if (this.form !== DdbForm.dict)
|
|
813
|
+
throw new Error('this.form 不是 dict, 不能转换为 Object');
|
|
814
|
+
const [{ value: keys }, { value: values }] = this.value;
|
|
815
|
+
let obj = {};
|
|
816
|
+
for (let i = 0; i < this.rows; i++)
|
|
817
|
+
obj[keys[i]] = values[i].value;
|
|
818
|
+
return obj;
|
|
819
|
+
}
|
|
810
820
|
[utils_js_1.inspect.custom]() {
|
|
811
821
|
const type = (() => {
|
|
812
822
|
const tname = DdbType[this.type];
|
|
@@ -844,15 +854,6 @@ class DdbObj {
|
|
|
844
854
|
})();
|
|
845
855
|
return `${type.blue}(${this.name ? `${(0, utils_js_1.inspect)(this.name)}, ` : ''}${data})`;
|
|
846
856
|
}
|
|
847
|
-
to_dict() {
|
|
848
|
-
if (this.form !== DdbForm.dict)
|
|
849
|
-
throw new Error('this.form 不是 dict, 不能转换为 Object');
|
|
850
|
-
const [{ value: keys }, { value: values }] = this.value;
|
|
851
|
-
let obj = {};
|
|
852
|
-
for (let i = 0; i < this.rows; i++)
|
|
853
|
-
obj[keys[i]] = values[i].value;
|
|
854
|
-
return obj;
|
|
855
|
-
}
|
|
856
857
|
}
|
|
857
858
|
exports.DdbObj = DdbObj;
|
|
858
859
|
DdbObj.dec = new TextDecoder('utf-8');
|
|
@@ -1017,19 +1018,28 @@ function timestamp2str(timestamp) {
|
|
|
1017
1018
|
}
|
|
1018
1019
|
exports.timestamp2str = timestamp2str;
|
|
1019
1020
|
class DDB {
|
|
1020
|
-
|
|
1021
|
-
|
|
1021
|
+
/**
|
|
1022
|
+
Initialize an instance of DolphinDB Client using the WebSocket URL
|
|
1023
|
+
(without establishing an actual network connection)
|
|
1024
|
+
@example
|
|
1025
|
+
let ddb = new DDB('ws://127.0.0.1:8848')
|
|
1026
|
+
let ddb_secure = new DDB('wss://dolphindb.com')
|
|
1027
|
+
*/
|
|
1028
|
+
constructor(url) {
|
|
1022
1029
|
/** 当前的 session id (http 或 tcp) */
|
|
1023
1030
|
this.sid = '0';
|
|
1024
1031
|
/** utf-8 text decoder */
|
|
1025
1032
|
this.dec = new TextDecoder('utf-8');
|
|
1026
1033
|
this.enc = new TextEncoder();
|
|
1027
1034
|
this.print_buffer = false;
|
|
1028
|
-
this.
|
|
1035
|
+
this.websocket = null;
|
|
1029
1036
|
/** little endian (server) */
|
|
1030
1037
|
this.le = true;
|
|
1038
|
+
/** python session flag (2048) */
|
|
1039
|
+
this.python = false;
|
|
1040
|
+
this.message_hook = null;
|
|
1031
1041
|
this.presult = Promise.resolve(null);
|
|
1032
|
-
this.
|
|
1042
|
+
this.url = url;
|
|
1033
1043
|
}
|
|
1034
1044
|
/** print message handler */
|
|
1035
1045
|
printer(message) {
|
|
@@ -1038,66 +1048,102 @@ class DDB {
|
|
|
1038
1048
|
/** resolver, rejector, promise of last rpc */
|
|
1039
1049
|
presolver(buf) { }
|
|
1040
1050
|
prejector(error) { }
|
|
1041
|
-
/**
|
|
1042
|
-
async connect({
|
|
1043
|
-
this.
|
|
1044
|
-
|
|
1051
|
+
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL */
|
|
1052
|
+
async connect({ url = this.url, login = true, username = 'admin', password = '123456', python = false, } = {}) {
|
|
1053
|
+
this.url = url;
|
|
1054
|
+
this.python = python;
|
|
1055
|
+
if (this.websocket?.readyState === ws_1.WebSocket.OPEN)
|
|
1045
1056
|
this.disconnect();
|
|
1046
|
-
let
|
|
1057
|
+
let websocket = new ws_1.WebSocket(url, python ? ['python'] : [], {
|
|
1047
1058
|
maxPayload: 2 ** 33 // 8 GB
|
|
1048
1059
|
});
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1060
|
+
// https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
|
|
1061
|
+
websocket.binaryType = 'arraybuffer';
|
|
1062
|
+
this.websocket = websocket;
|
|
1063
|
+
await new Promise((resolve, reject) => {
|
|
1064
|
+
websocket.addEventListener('open', async (event) => {
|
|
1065
|
+
console.log(`${websocket.url} opened`);
|
|
1066
|
+
await this.rpc('connect', {});
|
|
1067
|
+
resolve();
|
|
1068
|
+
});
|
|
1069
|
+
websocket.addEventListener('close', event => {
|
|
1070
|
+
console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
|
|
1071
|
+
});
|
|
1072
|
+
websocket.addEventListener('error', event => {
|
|
1073
|
+
const message = `${websocket.url} errored`;
|
|
1074
|
+
console.error(message, event);
|
|
1075
|
+
reject(Object.assign(new Error(message), { event }));
|
|
1076
|
+
});
|
|
1077
|
+
websocket.addEventListener('message', event => {
|
|
1078
|
+
const buf = new Uint8Array(event.data);
|
|
1079
|
+
if (this.message_hook)
|
|
1080
|
+
this.message_hook(buf);
|
|
1081
|
+
try {
|
|
1082
|
+
const { type, data } = this.parse_message(buf);
|
|
1083
|
+
if (type === 'message') {
|
|
1084
|
+
this.printer(data);
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
this.presolver(data);
|
|
1072
1088
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
}
|
|
1089
|
+
catch (error) {
|
|
1090
|
+
this.prejector(error);
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1078
1093
|
});
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1094
|
+
if (!this.python)
|
|
1095
|
+
await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
|
|
1096
|
+
' nargs = size(args)\n' +
|
|
1097
|
+
' func = funcByName(func_name)\n' +
|
|
1098
|
+
' \n' +
|
|
1099
|
+
' if (!nargs)\n' +
|
|
1100
|
+
' return pnodeRun(func, nodes, add_node_alias)\n' +
|
|
1101
|
+
' \n' +
|
|
1102
|
+
' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
|
|
1103
|
+
' args_partial[0] = func\n' +
|
|
1104
|
+
' args_partial[1:] = args\n' +
|
|
1105
|
+
' return pnodeRun(\n' +
|
|
1106
|
+
' unifiedCall(partial, args_partial),\n' +
|
|
1107
|
+
' nodes,\n' +
|
|
1108
|
+
' add_node_alias\n' +
|
|
1109
|
+
' )\n' +
|
|
1110
|
+
'}\n', { urgent: true });
|
|
1096
1111
|
if (login)
|
|
1097
1112
|
await this.call('login', [username, password], { urgent: true });
|
|
1098
1113
|
}
|
|
1114
|
+
get_rpc_options({ urgent = false, secondary = false, async: _async = false, pickle = false, clear = false, api = false, compress = false, cancellable = true, priority = urgent ? 8 : 4, parallelism = 8, root_id = '', limit, } = {}) {
|
|
1115
|
+
let flag = 0;
|
|
1116
|
+
if (urgent)
|
|
1117
|
+
flag += 1;
|
|
1118
|
+
if (secondary)
|
|
1119
|
+
flag += 2;
|
|
1120
|
+
if (_async)
|
|
1121
|
+
flag += 4;
|
|
1122
|
+
if (pickle)
|
|
1123
|
+
flag += 8;
|
|
1124
|
+
if (clear)
|
|
1125
|
+
flag += 16;
|
|
1126
|
+
if (api)
|
|
1127
|
+
flag += 32;
|
|
1128
|
+
if (compress)
|
|
1129
|
+
flag += 64;
|
|
1130
|
+
// python session
|
|
1131
|
+
if (this.python)
|
|
1132
|
+
flag += 2048;
|
|
1133
|
+
const options = [
|
|
1134
|
+
flag,
|
|
1135
|
+
cancellable ? 1 : 0,
|
|
1136
|
+
priority,
|
|
1137
|
+
parallelism,
|
|
1138
|
+
...limit ? [
|
|
1139
|
+
root_id,
|
|
1140
|
+
limit,
|
|
1141
|
+
] : [],
|
|
1142
|
+
];
|
|
1143
|
+
return `/ ${options.join('_')}`;
|
|
1144
|
+
}
|
|
1099
1145
|
disconnect() {
|
|
1100
|
-
this.
|
|
1146
|
+
this.websocket?.close(1000);
|
|
1101
1147
|
}
|
|
1102
1148
|
/** rpc through websocket (function/script/variable command)
|
|
1103
1149
|
- type: API 类型: 'script' | 'function' | 'variable'
|
|
@@ -1106,10 +1152,10 @@ class DDB {
|
|
|
1106
1152
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
1107
1153
|
*/
|
|
1108
1154
|
async rpc(type, { script, func, args = [], vars = [], urgent, }) {
|
|
1109
|
-
if (!this.
|
|
1155
|
+
if (!this.websocket)
|
|
1110
1156
|
await this.connect();
|
|
1111
|
-
if (this.
|
|
1112
|
-
throw new Error(
|
|
1157
|
+
if (this.websocket.readyState !== ws_1.WebSocket.OPEN)
|
|
1158
|
+
throw new Error(`${this.url} is already disconnected`);
|
|
1113
1159
|
// 临界区:保证多个 rpc 并发时形成 promise 链
|
|
1114
1160
|
// ddb 世界观:需要等待上一个 rpc 结果从 server 返回之后才能发起下一个调用
|
|
1115
1161
|
// 违反世界观可能造成:
|
|
@@ -1147,14 +1193,16 @@ class DDB {
|
|
|
1147
1193
|
`${vars.join(',')}\n` +
|
|
1148
1194
|
`${vars.length}\n` +
|
|
1149
1195
|
`${Number(DDB.le_client)}\n`;
|
|
1196
|
+
case 'connect':
|
|
1197
|
+
return 'connect\n';
|
|
1150
1198
|
}
|
|
1151
1199
|
})());
|
|
1152
1200
|
const message = (0, utils_js_1.concat)([
|
|
1153
|
-
this.enc.encode(`API2 ${this.sid} ${command.length}${urgent
|
|
1201
|
+
this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
|
|
1154
1202
|
command,
|
|
1155
1203
|
...args.map((arg) => arg.pack())
|
|
1156
1204
|
]);
|
|
1157
|
-
this.
|
|
1205
|
+
this.websocket.send(message);
|
|
1158
1206
|
const buf_data = await presult;
|
|
1159
1207
|
if (this.print_buffer)
|
|
1160
1208
|
console.log((0, utils_js_1.typed_array_to_buffer)(buf_data));
|
|
@@ -1181,6 +1229,8 @@ class DDB {
|
|
|
1181
1229
|
- add_node_alias?: 设置 nodes 参数时选传,其它情况不传
|
|
1182
1230
|
*/
|
|
1183
1231
|
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
|
|
1232
|
+
if (this.python)
|
|
1233
|
+
throw new Error('call doesn\'t support python session yet');
|
|
1184
1234
|
if (node) {
|
|
1185
1235
|
if (typeof func_type === 'undefined')
|
|
1186
1236
|
throw new Error('指定 node 时必须设置 func_type');
|
|
@@ -1196,7 +1246,13 @@ class DDB {
|
|
|
1196
1246
|
new DdbVectorString(nodes),
|
|
1197
1247
|
func,
|
|
1198
1248
|
new DdbVectorAny(this.to_ddbobjs(args)),
|
|
1199
|
-
...
|
|
1249
|
+
...(() => {
|
|
1250
|
+
if (typeof add_node_alias !== 'undefined')
|
|
1251
|
+
return [add_node_alias];
|
|
1252
|
+
if (this.python)
|
|
1253
|
+
return [true];
|
|
1254
|
+
return [];
|
|
1255
|
+
})()
|
|
1200
1256
|
];
|
|
1201
1257
|
func = 'pnode_run';
|
|
1202
1258
|
}
|
|
@@ -1208,9 +1264,9 @@ class DDB {
|
|
|
1208
1264
|
}
|
|
1209
1265
|
/** upload variable through websocket (variable command) */
|
|
1210
1266
|
async upload(
|
|
1211
|
-
/**
|
|
1267
|
+
/** Uploaded variables' name */
|
|
1212
1268
|
vars,
|
|
1213
|
-
/**
|
|
1269
|
+
/** Uploaded variables' value */
|
|
1214
1270
|
args) {
|
|
1215
1271
|
if (!args.length || args.length !== vars.length)
|
|
1216
1272
|
throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
|