dolphindb 2.0.502 → 2.0.505
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 +37 -32
- package/README.zh.md +29 -24
- package/browser.d.ts +110 -49
- package/browser.js +242 -102
- package/browser.js.map +1 -1
- package/index.d.ts +97 -40
- package/index.js +221 -95
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/test/index.d.ts +0 -1
- package/test/index.js +0 -20
- package/test/index.js.map +0 -1
- package/test/print.d.ts +0 -2
- package/test/print.js +0 -20
- package/test/print.js.map +0 -1
- package/test/types.d.ts +0 -2
- package/test/types.js +0 -24
- package/test/types.js.map +0 -1
- package/test.d.ts +0 -1
- package/test.js +0 -38
- package/test.js.map +0 -1
package/browser.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.str2timestamp = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbTable = exports.DdbVectorSymbol = exports.DdbVectorAny = exports.
|
|
3
|
+
exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.str2timestamp = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbTable = exports.DdbSetString = exports.DdbSetDouble = exports.DdbSetInt = exports.DdbVectorSymbol = exports.DdbVectorAny = exports.DdbVectorString = exports.DdbVectorDouble = exports.DdbVectorInt = exports.DdbFunction = exports.DdbPair = exports.DdbNanoTimeStamp = exports.DdbTimeStamp = exports.DdbDateTime = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbChar = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.DdbType = exports.DdbForm = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
|
6
6
|
const customParseFormat_js_1 = tslib_1.__importDefault(require("dayjs/plugin/customParseFormat.js"));
|
|
7
7
|
dayjs_1.default.extend(customParseFormat_js_1.default);
|
|
8
8
|
require("xshell/prototype.browser");
|
|
9
9
|
const utils_browser_1 = require("xshell/utils.browser");
|
|
10
|
+
const net_browser_js_1 = require("xshell/net.browser.js");
|
|
10
11
|
var DdbForm;
|
|
11
12
|
(function (DdbForm) {
|
|
12
13
|
DdbForm[DdbForm["scalar"] = 0] = "scalar";
|
|
@@ -72,8 +73,7 @@ var DdbFunctionType;
|
|
|
72
73
|
DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
|
|
73
74
|
})(DdbFunctionType = exports.DdbFunctionType || (exports.DdbFunctionType = {}));
|
|
74
75
|
exports.nulls = {
|
|
75
|
-
|
|
76
|
-
char: '\x80',
|
|
76
|
+
int8: -0x80,
|
|
77
77
|
int16: -32768,
|
|
78
78
|
int32: -2147483648,
|
|
79
79
|
int64: -0x8000000000000000n,
|
|
@@ -247,12 +247,14 @@ class DdbObj {
|
|
|
247
247
|
case DdbType.void:
|
|
248
248
|
return [1, null];
|
|
249
249
|
case DdbType.bool: {
|
|
250
|
-
const
|
|
251
|
-
|
|
250
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
251
|
+
const value = dv.getInt8(0);
|
|
252
|
+
return [1, value === exports.nulls.int8 ? null : Boolean(value)];
|
|
252
253
|
}
|
|
253
254
|
case DdbType.char: {
|
|
254
|
-
const
|
|
255
|
-
|
|
255
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
256
|
+
const value = dv.getInt8(0);
|
|
257
|
+
return [1, value === exports.nulls.int8 ? null : value];
|
|
256
258
|
}
|
|
257
259
|
case DdbType.short: {
|
|
258
260
|
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
@@ -437,11 +439,10 @@ class DdbObj {
|
|
|
437
439
|
static parse_vector_items(buf, le, type, length) {
|
|
438
440
|
switch (type) {
|
|
439
441
|
case DdbType.bool:
|
|
440
|
-
return [length, buf.slice(0, length)];
|
|
441
442
|
case DdbType.char:
|
|
442
443
|
return [
|
|
443
444
|
length,
|
|
444
|
-
|
|
445
|
+
new Int8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + length))
|
|
445
446
|
];
|
|
446
447
|
case DdbType.short:
|
|
447
448
|
return [
|
|
@@ -591,17 +592,17 @@ class DdbObj {
|
|
|
591
592
|
return [Uint8Array.of(1)];
|
|
592
593
|
case DdbType.bool:
|
|
593
594
|
return [
|
|
594
|
-
|
|
595
|
-
exports.nulls.
|
|
595
|
+
Int8Array.of(value === null ?
|
|
596
|
+
exports.nulls.int8
|
|
596
597
|
:
|
|
597
598
|
Number(value))
|
|
598
599
|
];
|
|
599
600
|
case DdbType.char:
|
|
600
601
|
return [
|
|
601
|
-
|
|
602
|
-
exports.nulls.
|
|
602
|
+
Int8Array.of((value === null ?
|
|
603
|
+
exports.nulls.int8
|
|
603
604
|
:
|
|
604
|
-
value)
|
|
605
|
+
value))
|
|
605
606
|
];
|
|
606
607
|
case DdbType.short:
|
|
607
608
|
return [
|
|
@@ -743,7 +744,7 @@ class DdbObj {
|
|
|
743
744
|
case DdbType.bool:
|
|
744
745
|
return [value];
|
|
745
746
|
case DdbType.char:
|
|
746
|
-
return [
|
|
747
|
+
return [value];
|
|
747
748
|
case DdbType.short:
|
|
748
749
|
return [value];
|
|
749
750
|
case DdbType.int:
|
|
@@ -846,10 +847,18 @@ class DdbObj {
|
|
|
846
847
|
}
|
|
847
848
|
})();
|
|
848
849
|
const data = (() => {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
850
|
+
switch (this.form) {
|
|
851
|
+
case DdbForm.pair:
|
|
852
|
+
return `${this.value[0]}, ${this.value[1]}`;
|
|
853
|
+
case DdbForm.scalar:
|
|
854
|
+
switch (this.type) {
|
|
855
|
+
case DdbType.functiondef:
|
|
856
|
+
return `'${this.value.name}'`;
|
|
857
|
+
case DdbType.string:
|
|
858
|
+
return `'${this.value}'`;
|
|
859
|
+
}
|
|
860
|
+
break;
|
|
861
|
+
}
|
|
853
862
|
return this.value;
|
|
854
863
|
})();
|
|
855
864
|
return `${type}(${this.name ? `'${this.name}', ` : ''}${data})\n`;
|
|
@@ -915,7 +924,9 @@ class DdbObj {
|
|
|
915
924
|
exports.DdbObj = DdbObj;
|
|
916
925
|
DdbObj.dec = new TextDecoder('utf-8');
|
|
917
926
|
DdbObj.enc = new TextEncoder();
|
|
918
|
-
/** 维护已解析的 symbol base,比如流数据中后续的 symbol 向量可能只发送一个 base.id, base.size == 0, 依赖之前发送的 symbol base
|
|
927
|
+
/** 维护已解析的 symbol base,比如流数据中后续的 symbol 向量可能只发送一个 base.id, base.size == 0, 依赖之前发送的 symbol base ?
|
|
928
|
+
只是暂存,如果一张表有多个 symbol 列,可能这个 symbol base 会被复用,不同的对象之间 symbol base 一般不复用
|
|
929
|
+
*/
|
|
919
930
|
DdbObj.symbol_bases = {};
|
|
920
931
|
/** little endian (client) */
|
|
921
932
|
DdbObj.le_client = Boolean(new Uint8Array(Uint32Array.of(1).buffer)[0]);
|
|
@@ -947,7 +958,10 @@ class DdbChar extends DdbObj {
|
|
|
947
958
|
form: DdbForm.scalar,
|
|
948
959
|
type: DdbType.char,
|
|
949
960
|
length: 1,
|
|
950
|
-
value
|
|
961
|
+
value: typeof value === 'string' ?
|
|
962
|
+
value.charCodeAt(0)
|
|
963
|
+
:
|
|
964
|
+
value
|
|
951
965
|
});
|
|
952
966
|
}
|
|
953
967
|
}
|
|
@@ -1073,20 +1087,6 @@ class DdbVectorInt extends DdbObj {
|
|
|
1073
1087
|
}
|
|
1074
1088
|
}
|
|
1075
1089
|
exports.DdbVectorInt = DdbVectorInt;
|
|
1076
|
-
class DdbVectorString extends DdbObj {
|
|
1077
|
-
constructor(strings, name) {
|
|
1078
|
-
super({
|
|
1079
|
-
form: DdbForm.vector,
|
|
1080
|
-
type: DdbType.string,
|
|
1081
|
-
length: 0,
|
|
1082
|
-
rows: strings.length,
|
|
1083
|
-
cols: 1,
|
|
1084
|
-
value: strings,
|
|
1085
|
-
name,
|
|
1086
|
-
});
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
exports.DdbVectorString = DdbVectorString;
|
|
1090
1090
|
class DdbVectorDouble extends DdbObj {
|
|
1091
1091
|
constructor(doubles, name) {
|
|
1092
1092
|
super({
|
|
@@ -1107,6 +1107,20 @@ class DdbVectorDouble extends DdbObj {
|
|
|
1107
1107
|
}
|
|
1108
1108
|
}
|
|
1109
1109
|
exports.DdbVectorDouble = DdbVectorDouble;
|
|
1110
|
+
class DdbVectorString extends DdbObj {
|
|
1111
|
+
constructor(strings, name) {
|
|
1112
|
+
super({
|
|
1113
|
+
form: DdbForm.vector,
|
|
1114
|
+
type: DdbType.string,
|
|
1115
|
+
length: 0,
|
|
1116
|
+
rows: strings.length,
|
|
1117
|
+
cols: 1,
|
|
1118
|
+
value: strings,
|
|
1119
|
+
name,
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
exports.DdbVectorString = DdbVectorString;
|
|
1110
1124
|
class DdbVectorAny extends DdbObj {
|
|
1111
1125
|
constructor(objs, name) {
|
|
1112
1126
|
super({
|
|
@@ -1152,6 +1166,65 @@ class DdbVectorSymbol extends DdbObj {
|
|
|
1152
1166
|
}
|
|
1153
1167
|
}
|
|
1154
1168
|
exports.DdbVectorSymbol = DdbVectorSymbol;
|
|
1169
|
+
class DdbSetInt extends DdbObj {
|
|
1170
|
+
constructor(ints) {
|
|
1171
|
+
super({
|
|
1172
|
+
form: DdbForm.set,
|
|
1173
|
+
type: DdbType.int,
|
|
1174
|
+
length: 0,
|
|
1175
|
+
rows: ints instanceof Set ?
|
|
1176
|
+
ints.size
|
|
1177
|
+
:
|
|
1178
|
+
ints.length,
|
|
1179
|
+
cols: 1,
|
|
1180
|
+
value: ints instanceof Int32Array ?
|
|
1181
|
+
ints
|
|
1182
|
+
:
|
|
1183
|
+
Int32Array.from(ints, v => v === null ?
|
|
1184
|
+
exports.nulls.int32
|
|
1185
|
+
:
|
|
1186
|
+
v),
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
exports.DdbSetInt = DdbSetInt;
|
|
1191
|
+
class DdbSetDouble extends DdbObj {
|
|
1192
|
+
constructor(doubles) {
|
|
1193
|
+
super({
|
|
1194
|
+
form: DdbForm.set,
|
|
1195
|
+
type: DdbType.double,
|
|
1196
|
+
length: 0,
|
|
1197
|
+
rows: doubles instanceof Set ?
|
|
1198
|
+
doubles.size
|
|
1199
|
+
:
|
|
1200
|
+
doubles.length,
|
|
1201
|
+
cols: 1,
|
|
1202
|
+
value: doubles instanceof Int32Array ?
|
|
1203
|
+
doubles
|
|
1204
|
+
:
|
|
1205
|
+
Int32Array.from(doubles, v => v === null ?
|
|
1206
|
+
exports.nulls.int32
|
|
1207
|
+
:
|
|
1208
|
+
v),
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
exports.DdbSetDouble = DdbSetDouble;
|
|
1213
|
+
class DdbSetString extends DdbObj {
|
|
1214
|
+
constructor(strings) {
|
|
1215
|
+
if (strings instanceof Set)
|
|
1216
|
+
strings = [...strings];
|
|
1217
|
+
super({
|
|
1218
|
+
form: DdbForm.set,
|
|
1219
|
+
type: DdbType.string,
|
|
1220
|
+
length: 0,
|
|
1221
|
+
rows: strings.length,
|
|
1222
|
+
cols: 1,
|
|
1223
|
+
value: strings
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
exports.DdbSetString = DdbSetString;
|
|
1155
1228
|
class DdbTable extends DdbObj {
|
|
1156
1229
|
constructor(columns, name = '') {
|
|
1157
1230
|
super({
|
|
@@ -1259,11 +1332,25 @@ class DDB {
|
|
|
1259
1332
|
/**
|
|
1260
1333
|
Initialize an instance of DolphinDB Client using the WebSocket URL
|
|
1261
1334
|
(without establishing an actual network connection)
|
|
1335
|
+
- url?: DolphinDB WebSocket URL. e.g.:`ws://127.0.0.1:8848`, Defaults to the current page URL
|
|
1336
|
+
- options?:
|
|
1337
|
+
- autologin?: Whether to log in automatically after establishing a connection, default `true`
|
|
1338
|
+
- username?: DolphinDB username, default `'admin'`
|
|
1339
|
+
- password?: DolphinDB password, default `'123456'`
|
|
1340
|
+
- python?: set python session flag, default `false`
|
|
1341
|
+
|
|
1262
1342
|
@example
|
|
1263
1343
|
let ddb = new DDB('ws://127.0.0.1:8848')
|
|
1264
|
-
|
|
1344
|
+
|
|
1345
|
+
// 使用 HTTPS 加密
|
|
1346
|
+
let ddbsecure = new DDB('wss://dolphindb.com', {
|
|
1347
|
+
autologin: true,
|
|
1348
|
+
username: 'admin',
|
|
1349
|
+
password: '123456',
|
|
1350
|
+
python: false
|
|
1351
|
+
})
|
|
1265
1352
|
*/
|
|
1266
|
-
constructor(url) {
|
|
1353
|
+
constructor(url, options = {}) {
|
|
1267
1354
|
/** 当前的 session id (http 或 tcp) */
|
|
1268
1355
|
this.sid = '0';
|
|
1269
1356
|
/** utf-8 text decoder */
|
|
@@ -1272,9 +1359,15 @@ class DDB {
|
|
|
1272
1359
|
this.websocket = null;
|
|
1273
1360
|
/** little endian (server) */
|
|
1274
1361
|
this.le = true;
|
|
1362
|
+
/** Whether to automatically log in after the connection is established, the default is true */
|
|
1363
|
+
this.autologin = true;
|
|
1364
|
+
/** DolphinDB username */
|
|
1365
|
+
this.username = 'admin';
|
|
1366
|
+
/** DolphinDB password */
|
|
1367
|
+
this.password = '123456';
|
|
1275
1368
|
/** python session flag (2048) */
|
|
1276
1369
|
this.python = false;
|
|
1277
|
-
this.
|
|
1370
|
+
this.parse_object = true;
|
|
1278
1371
|
this.presult = Promise.resolve(null);
|
|
1279
1372
|
if (!url) {
|
|
1280
1373
|
const _url = new URL(location.href);
|
|
@@ -1283,56 +1376,68 @@ class DDB {
|
|
|
1283
1376
|
url = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${hostname}${port ? `:${port}` : ''}/`;
|
|
1284
1377
|
}
|
|
1285
1378
|
this.url = url;
|
|
1379
|
+
if (options.autologin !== undefined)
|
|
1380
|
+
this.autologin = options.autologin;
|
|
1381
|
+
if (options.username !== undefined)
|
|
1382
|
+
this.username = options.username;
|
|
1383
|
+
if (options.password !== undefined)
|
|
1384
|
+
this.password = options.password;
|
|
1385
|
+
if (options.python !== undefined)
|
|
1386
|
+
this.python = options.python;
|
|
1286
1387
|
}
|
|
1287
|
-
/**
|
|
1288
|
-
|
|
1289
|
-
|
|
1388
|
+
/** message handler */
|
|
1389
|
+
on_message({ type, data }, _this) {
|
|
1390
|
+
switch (type) {
|
|
1391
|
+
case 'print':
|
|
1392
|
+
console.log(data);
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1290
1395
|
}
|
|
1291
1396
|
/** resolver, rejector, promise of last rpc */
|
|
1292
|
-
presolver(
|
|
1397
|
+
presolver(message) { }
|
|
1293
1398
|
prejector(error) { }
|
|
1294
1399
|
get connected() {
|
|
1295
1400
|
return this.websocket?.readyState === WebSocket.OPEN;
|
|
1296
1401
|
}
|
|
1297
|
-
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1402
|
+
/** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL
|
|
1403
|
+
- options?:
|
|
1404
|
+
- url?: DolphinDB WebSocket URL. By default, the WebSocket URL passed in when the instance is initialized is used
|
|
1405
|
+
- autologin?: Whether to log in automatically after establishing a connection, default `true`
|
|
1406
|
+
- username?: DolphinDB username, default `'admin'`
|
|
1407
|
+
- password?: DolphinDB password, default `'123456'`
|
|
1408
|
+
- python?: set python session flag, default `false`
|
|
1409
|
+
*/
|
|
1410
|
+
async connect(options = {}) {
|
|
1411
|
+
if (options.url !== undefined)
|
|
1412
|
+
this.url = options.url;
|
|
1413
|
+
if (options.autologin !== undefined)
|
|
1414
|
+
this.autologin = options.autologin;
|
|
1415
|
+
if (options.username !== undefined)
|
|
1416
|
+
this.username = options.username;
|
|
1417
|
+
if (options.password !== undefined)
|
|
1418
|
+
this.password = options.password;
|
|
1419
|
+
if (options.python !== undefined)
|
|
1420
|
+
this.python = options.python;
|
|
1301
1421
|
this.disconnect();
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
await new Promise((resolve, reject) => {
|
|
1307
|
-
websocket.addEventListener('open', async (event) => {
|
|
1308
|
-
console.log(`${websocket.url} opened`);
|
|
1422
|
+
await (0, net_browser_js_1.connect_websocket)(this.url, {
|
|
1423
|
+
protocols: this.python ? ['python'] : [],
|
|
1424
|
+
on_open: async (event, websocket) => {
|
|
1425
|
+
this.websocket = websocket;
|
|
1309
1426
|
await this.rpc('connect', {});
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
websocket.addEventListener('close', event => {
|
|
1313
|
-
console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`);
|
|
1314
|
-
});
|
|
1315
|
-
websocket.addEventListener('error', event => {
|
|
1316
|
-
const message = `${websocket.url} errored`;
|
|
1317
|
-
console.error(message, event);
|
|
1318
|
-
reject(Object.assign(new Error(message), { event }));
|
|
1319
|
-
});
|
|
1320
|
-
websocket.addEventListener('message', event => {
|
|
1427
|
+
},
|
|
1428
|
+
on_message: event => {
|
|
1321
1429
|
const buf = new Uint8Array(event.data);
|
|
1322
|
-
if (this.message_hook)
|
|
1323
|
-
this.message_hook(buf);
|
|
1324
1430
|
try {
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
|
|
1431
|
+
const message = this.parse_message(buf);
|
|
1432
|
+
this.on_message(message, this);
|
|
1433
|
+
if (message.type === 'print')
|
|
1328
1434
|
return;
|
|
1329
|
-
|
|
1330
|
-
this.presolver(data);
|
|
1435
|
+
this.presolver(message);
|
|
1331
1436
|
}
|
|
1332
1437
|
catch (error) {
|
|
1333
1438
|
this.prejector(error);
|
|
1334
1439
|
}
|
|
1335
|
-
}
|
|
1440
|
+
}
|
|
1336
1441
|
});
|
|
1337
1442
|
if (!this.python)
|
|
1338
1443
|
await this.eval('def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
|
|
@@ -1351,11 +1456,11 @@ class DDB {
|
|
|
1351
1456
|
' add_node_alias\n' +
|
|
1352
1457
|
' )\n' +
|
|
1353
1458
|
'}\n', { urgent: true });
|
|
1354
|
-
if (
|
|
1459
|
+
if (this.autologin)
|
|
1355
1460
|
if (this.python)
|
|
1356
|
-
await this.eval(`login(${username.quote('double')}, ${password.quote('double')})`, { urgent: true });
|
|
1461
|
+
await this.eval(`login(${this.username.quote('double')}, ${this.password.quote('double')})`, { urgent: true });
|
|
1357
1462
|
else
|
|
1358
|
-
await this.call('login', [username, password], { urgent: true });
|
|
1463
|
+
await this.call('login', [this.username, this.password], { urgent: true });
|
|
1359
1464
|
}
|
|
1360
1465
|
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, } = {}) {
|
|
1361
1466
|
let flag = 0;
|
|
@@ -1386,7 +1491,7 @@ class DDB {
|
|
|
1386
1491
|
limit,
|
|
1387
1492
|
] : [],
|
|
1388
1493
|
];
|
|
1389
|
-
return
|
|
1494
|
+
return options.join('_');
|
|
1390
1495
|
}
|
|
1391
1496
|
disconnect() {
|
|
1392
1497
|
if (this.connected)
|
|
@@ -1400,8 +1505,11 @@ class DDB {
|
|
|
1400
1505
|
- options:
|
|
1401
1506
|
- urgent?: 决定 `行为标识` 那一行字符串的取值(只适用于 script 和 function)
|
|
1402
1507
|
- vars?: type === 'variable' 时必传,variable 指令中待上传的变量名
|
|
1508
|
+
- on_message?: 在该次 rpc 期间设置 message handler, 结束后恢复原有
|
|
1509
|
+
- parse_object?: 在该次 rpc 期间设置 parse_object, 结束后恢复原有,为 false 时返回的 DdbObj 仅含有 buffer 和 le,
|
|
1510
|
+
不做解析,以便后续转发、序列化
|
|
1403
1511
|
*/
|
|
1404
|
-
async rpc(type, { script, func, args = [], vars = [], urgent, }) {
|
|
1512
|
+
async rpc(type, { script, func, args = [], vars = [], urgent, on_message, parse_object, }) {
|
|
1405
1513
|
if (!this.websocket)
|
|
1406
1514
|
await this.connect();
|
|
1407
1515
|
if (!this.connected)
|
|
@@ -1448,33 +1556,53 @@ class DDB {
|
|
|
1448
1556
|
}
|
|
1449
1557
|
})());
|
|
1450
1558
|
const message = (0, utils_browser_1.concat)([
|
|
1451
|
-
this.enc.encode(`API2 ${this.sid} ${command.length}${this.get_rpc_options({ urgent })}\n`),
|
|
1559
|
+
this.enc.encode(`API2 ${this.sid} ${command.length} / ${this.get_rpc_options({ urgent })}\n`),
|
|
1452
1560
|
command,
|
|
1453
1561
|
...args.map((arg) => arg.pack())
|
|
1454
1562
|
]);
|
|
1455
|
-
this.
|
|
1456
|
-
|
|
1457
|
-
|
|
1563
|
+
const _on_message = this.on_message;
|
|
1564
|
+
const _parse_object = this.parse_object;
|
|
1565
|
+
if (on_message)
|
|
1566
|
+
this.on_message = on_message;
|
|
1567
|
+
if (parse_object !== undefined)
|
|
1568
|
+
this.parse_object = parse_object;
|
|
1569
|
+
try {
|
|
1570
|
+
this.websocket.send(message);
|
|
1571
|
+
const { data } = (await presult);
|
|
1572
|
+
return data;
|
|
1573
|
+
}
|
|
1574
|
+
finally {
|
|
1575
|
+
this.on_message = _on_message;
|
|
1576
|
+
this.parse_object = _parse_object;
|
|
1577
|
+
}
|
|
1458
1578
|
}
|
|
1459
|
-
/** eval script through websocket (script command)
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1579
|
+
/** eval script through websocket (script command)
|
|
1580
|
+
- script?: Script to execute
|
|
1581
|
+
- options?: execution options
|
|
1582
|
+
- urgent?: Urgent flag to ensure that submitted scripts are processed by urgent workers to prevent being blocked by other jobs
|
|
1583
|
+
- on_message?: Set the message handler during this rpc, and restore the original after the end
|
|
1584
|
+
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1585
|
+
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1586
|
+
so as to facilitate subsequent forwarding and serialization
|
|
1587
|
+
*/
|
|
1588
|
+
async eval(script, { urgent, on_message, parse_object, } = {}) {
|
|
1589
|
+
return this.rpc('script', { script, urgent, on_message, parse_object });
|
|
1466
1590
|
}
|
|
1467
1591
|
/** call function through websocket (function command)
|
|
1468
|
-
- func:
|
|
1469
|
-
- args?: `[ ]`
|
|
1470
|
-
- options?:
|
|
1471
|
-
- urgent?:
|
|
1472
|
-
- node?:
|
|
1473
|
-
- nodes?:
|
|
1474
|
-
- func_type?:
|
|
1475
|
-
- add_node_alias?:
|
|
1592
|
+
- func: function name
|
|
1593
|
+
- args?: `[ ]` Call parameters (the incoming native string and boolean will be automatically converted to DdbObj<string> and DdbObj<boolean>)
|
|
1594
|
+
- options?: call options
|
|
1595
|
+
- urgent?: Emergency flag. Use urgent worker execution to prevent being blocked by other jobs
|
|
1596
|
+
- node?: When the node alias is set, it is sent to the corresponding node in the cluster for execution (using the rpc method in DolphinDB)
|
|
1597
|
+
- nodes?: When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB)
|
|
1598
|
+
- 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
|
|
1599
|
+
- add_node_alias?: Select to pass when setting the nodes parameter, otherwise not pass
|
|
1600
|
+
- on_message?: Set the message handler during this rpc, and restore the original after the end
|
|
1601
|
+
- parse_object?: Set parse_object during this rpc, and restore the original after the end.
|
|
1602
|
+
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
1603
|
+
so as to facilitate subsequent forwarding and serialization
|
|
1476
1604
|
*/
|
|
1477
|
-
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias } = {}) {
|
|
1605
|
+
async call(func, args = [], { urgent, node, nodes, func_type, add_node_alias, on_message, parse_object, } = {}) {
|
|
1478
1606
|
if (this.python)
|
|
1479
1607
|
throw new Error('call doesn\'t support python session yet');
|
|
1480
1608
|
if (node) {
|
|
@@ -1506,6 +1634,8 @@ class DDB {
|
|
|
1506
1634
|
func,
|
|
1507
1635
|
args,
|
|
1508
1636
|
urgent,
|
|
1637
|
+
on_message,
|
|
1638
|
+
parse_object
|
|
1509
1639
|
});
|
|
1510
1640
|
}
|
|
1511
1641
|
/** upload variable through websocket (variable command) */
|
|
@@ -1513,19 +1643,19 @@ class DDB {
|
|
|
1513
1643
|
/** Uploaded variables' name */
|
|
1514
1644
|
vars,
|
|
1515
1645
|
/** Uploaded variables' value */
|
|
1516
|
-
args) {
|
|
1646
|
+
args, { on_message, parse_object, } = {}) {
|
|
1517
1647
|
if (!args.length || args.length !== vars.length)
|
|
1518
1648
|
throw new Error('variable 指令参数为空或参数名为空,或数量不匹配');
|
|
1519
|
-
return this.rpc('variable', { vars, args });
|
|
1649
|
+
return this.rpc('variable', { vars, args, on_message, parse_object });
|
|
1520
1650
|
}
|
|
1521
1651
|
/** 解析服务端响应报文,返回去掉 header 的 data buf */
|
|
1522
|
-
parse_message(buf) {
|
|
1652
|
+
parse_message(buf, parse_object = this.parse_object) {
|
|
1523
1653
|
// MSG\n
|
|
1524
1654
|
// <message>\0
|
|
1525
1655
|
// 'M'.codePointAt(0).to_hex_str()
|
|
1526
1656
|
if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
|
|
1527
1657
|
return {
|
|
1528
|
-
type: '
|
|
1658
|
+
type: 'print',
|
|
1529
1659
|
data: this.dec.decode(buf.subarray(4))
|
|
1530
1660
|
};
|
|
1531
1661
|
// '1166953221 1 1\n'
|
|
@@ -1550,9 +1680,19 @@ class DDB {
|
|
|
1550
1680
|
const message = this.dec.decode(buf.subarray(i_ls_1, i_lf_1));
|
|
1551
1681
|
if (message !== 'OK')
|
|
1552
1682
|
throw new Error(message);
|
|
1683
|
+
const buf_obj = buf.subarray(i_lf_1 + 1);
|
|
1553
1684
|
return {
|
|
1554
1685
|
type: 'object',
|
|
1555
|
-
data:
|
|
1686
|
+
data: parse_object ?
|
|
1687
|
+
Object.assign(DdbObj.parse(buf_obj, this.le), { buffer: buf_obj })
|
|
1688
|
+
:
|
|
1689
|
+
new DdbObj({
|
|
1690
|
+
form: DdbForm.scalar,
|
|
1691
|
+
type: DdbType.void,
|
|
1692
|
+
length: 0,
|
|
1693
|
+
le: this.le,
|
|
1694
|
+
buffer: buf_obj,
|
|
1695
|
+
})
|
|
1556
1696
|
};
|
|
1557
1697
|
}
|
|
1558
1698
|
/** 自动转换 js string, boolean 为 DdbObj */
|