@tradejs/infra 1.0.9 → 1.0.10
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/dist/ai.d.mts +39 -3
- package/dist/ai.d.ts +39 -3
- package/dist/ai.js +404 -28
- package/dist/ai.mjs +372 -24
- package/dist/backtestArtifacts.d.mts +57 -0
- package/dist/backtestArtifacts.d.ts +57 -0
- package/dist/backtestArtifacts.js +255 -0
- package/dist/backtestArtifacts.mjs +211 -0
- package/dist/{chunk-MLVWC2I2.mjs → chunk-DXG2UDNA.mjs} +60 -5
- package/dist/{chunk-KVEZORMS.mjs → chunk-RQP5VSTH.mjs} +54 -3
- package/dist/ml.d.mts +1 -1
- package/dist/ml.d.ts +1 -1
- package/dist/ml.js +55 -3
- package/dist/ml.mjs +3 -1
- package/dist/{mlDatasetFile-sRGWgR_o.d.mts → mlDatasetFile-Czx__g9M.d.mts} +7 -1
- package/dist/{mlDatasetFile-sRGWgR_o.d.ts → mlDatasetFile-Czx__g9M.d.ts} +7 -1
- package/dist/redis.d.mts +21 -3
- package/dist/redis.d.ts +21 -3
- package/dist/redis.js +63 -5
- package/dist/redis.mjs +7 -1
- package/dist/timescale.d.mts +220 -5
- package/dist/timescale.d.ts +220 -5
- package/dist/timescale.js +1983 -93
- package/dist/timescale.mjs +1955 -93
- package/dist/tradingAccounts.d.mts +20 -0
- package/dist/tradingAccounts.d.ts +20 -0
- package/dist/tradingAccounts.js +556 -0
- package/dist/tradingAccounts.mjs +190 -0
- package/dist/userSettings.d.mts +2 -0
- package/dist/userSettings.d.ts +2 -0
- package/dist/userSettings.js +24 -5
- package/dist/userSettings.mjs +2 -1
- package/package.json +13 -3
|
@@ -3,15 +3,26 @@ import { once } from "events";
|
|
|
3
3
|
import { createReadStream, createWriteStream } from "fs";
|
|
4
4
|
import fs from "fs/promises";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import readline from "readline";
|
|
6
7
|
var DEFAULT_DIR = "data/ml/export";
|
|
7
8
|
var ML_DATASET_WRITE_BATCH_SIZE = 200;
|
|
8
9
|
var ML_CHUNK_FILE_RE = /^ml-dataset-(.+)-chunk-[^.]+\.jsonl$/;
|
|
10
|
+
var BACKTEST_RUN_CHUNK_ID_RE = /^(\d{12}-[a-f0-9]{8})-/;
|
|
9
11
|
var writerByPath = /* @__PURE__ */ new Map();
|
|
10
12
|
var toFileToken = (value) => value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "any";
|
|
11
13
|
var getMlChunkFilePath = (strategyName, chunkId, outDir = DEFAULT_DIR) => path.join(
|
|
12
14
|
outDir,
|
|
13
15
|
`ml-dataset-${toFileToken(strategyName)}-chunk-${toFileToken(chunkId)}.jsonl`
|
|
14
16
|
);
|
|
17
|
+
var getMlChunkFilePrefix = (strategyName, runId) => `ml-dataset-${toFileToken(strategyName)}-chunk-${runId ? `${toFileToken(runId)}-` : ""}`;
|
|
18
|
+
var getRunIdFromMlChunkFileName = (strategyName, fileName) => {
|
|
19
|
+
const prefix = getMlChunkFilePrefix(strategyName);
|
|
20
|
+
if (!fileName.startsWith(prefix) || !fileName.endsWith(".jsonl")) {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
const chunkToken = fileName.slice(prefix.length, -".jsonl".length);
|
|
24
|
+
return chunkToken.match(BACKTEST_RUN_CHUNK_ID_RE)?.[1] ?? "";
|
|
25
|
+
};
|
|
15
26
|
var appendMlDatasetRow = async (params) => {
|
|
16
27
|
const { strategyName, chunkId, row, outDir = DEFAULT_DIR } = params;
|
|
17
28
|
const filePath = getMlChunkFilePath(strategyName, chunkId, outDir);
|
|
@@ -85,8 +96,8 @@ var closeAllMlDatasetWriters = async () => {
|
|
|
85
96
|
}
|
|
86
97
|
};
|
|
87
98
|
var listMlChunkFiles = async (params) => {
|
|
88
|
-
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
89
|
-
const prefix =
|
|
99
|
+
const { strategyName, outDir = DEFAULT_DIR, runId } = params;
|
|
100
|
+
const prefix = getMlChunkFilePrefix(strategyName, runId);
|
|
90
101
|
let entries = [];
|
|
91
102
|
try {
|
|
92
103
|
entries = await fs.readdir(outDir);
|
|
@@ -95,6 +106,20 @@ var listMlChunkFiles = async (params) => {
|
|
|
95
106
|
}
|
|
96
107
|
return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).map((name) => path.join(outDir, name)).sort();
|
|
97
108
|
};
|
|
109
|
+
var listMlChunkRunIds = async (params) => {
|
|
110
|
+
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
111
|
+
let entries = [];
|
|
112
|
+
try {
|
|
113
|
+
entries = await fs.readdir(outDir);
|
|
114
|
+
} catch {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
return [
|
|
118
|
+
...new Set(
|
|
119
|
+
entries.map((name) => getRunIdFromMlChunkFileName(strategyName, name)).filter(Boolean)
|
|
120
|
+
)
|
|
121
|
+
].sort();
|
|
122
|
+
};
|
|
98
123
|
var listMlChunkStrategies = async (params) => {
|
|
99
124
|
const outDir = params?.outDir ?? DEFAULT_DIR;
|
|
100
125
|
let entries = [];
|
|
@@ -110,12 +135,37 @@ var listMlChunkStrategies = async (params) => {
|
|
|
110
135
|
].sort();
|
|
111
136
|
};
|
|
112
137
|
var mergeJsonlFiles = async (params) => {
|
|
113
|
-
const { filePaths, outPath } = params;
|
|
138
|
+
const { filePaths, outPath, shouldIncludeRow } = params;
|
|
114
139
|
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
115
140
|
const stream = createWriteStream(outPath, { encoding: "utf8" });
|
|
116
141
|
const done = Promise.all([once(stream, "finish"), once(stream, "close")]);
|
|
117
142
|
try {
|
|
118
143
|
for (const filePath of filePaths) {
|
|
144
|
+
if (shouldIncludeRow) {
|
|
145
|
+
const reader2 = readline.createInterface({
|
|
146
|
+
input: createReadStream(filePath, { encoding: "utf8" }),
|
|
147
|
+
crlfDelay: Infinity
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
for await (const line of reader2) {
|
|
151
|
+
const trimmed = line.trim();
|
|
152
|
+
if (!trimmed) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const row = JSON.parse(trimmed);
|
|
156
|
+
if (!shouldIncludeRow(row)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (!stream.write(`${trimmed}
|
|
160
|
+
`)) {
|
|
161
|
+
await once(stream, "drain");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
reader2.close();
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
119
169
|
const reader = createReadStream(filePath, { encoding: "utf8" });
|
|
120
170
|
for await (const chunk of reader) {
|
|
121
171
|
if (!stream.write(chunk)) {
|
|
@@ -137,6 +187,7 @@ export {
|
|
|
137
187
|
closeMlDatasetWriter,
|
|
138
188
|
closeAllMlDatasetWriters,
|
|
139
189
|
listMlChunkFiles,
|
|
190
|
+
listMlChunkRunIds,
|
|
140
191
|
listMlChunkStrategies,
|
|
141
192
|
mergeJsonlFiles
|
|
142
193
|
};
|
package/dist/ml.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as appendMlDatasetRow, c as closeAllMlDatasetWriters, b as closeMlDatasetWriter, f as flushMlDatasetWriter, g as getMlChunkFilePath, l as listMlChunkFiles, d as listMlChunkStrategies, m as mergeJsonlFiles, t as toFileToken } from './mlDatasetFile-
|
|
1
|
+
export { a as appendMlDatasetRow, c as closeAllMlDatasetWriters, b as closeMlDatasetWriter, f as flushMlDatasetWriter, g as getMlChunkFilePath, l as listMlChunkFiles, d as listMlChunkRunIds, e as listMlChunkStrategies, m as mergeJsonlFiles, t as toFileToken } from './mlDatasetFile-Czx__g9M.mjs';
|
|
2
2
|
|
|
3
3
|
type MlPredictResponse = {
|
|
4
4
|
probability: number;
|
package/dist/ml.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as appendMlDatasetRow, c as closeAllMlDatasetWriters, b as closeMlDatasetWriter, f as flushMlDatasetWriter, g as getMlChunkFilePath, l as listMlChunkFiles, d as listMlChunkStrategies, m as mergeJsonlFiles, t as toFileToken } from './mlDatasetFile-
|
|
1
|
+
export { a as appendMlDatasetRow, c as closeAllMlDatasetWriters, b as closeMlDatasetWriter, f as flushMlDatasetWriter, g as getMlChunkFilePath, l as listMlChunkFiles, d as listMlChunkRunIds, e as listMlChunkStrategies, m as mergeJsonlFiles, t as toFileToken } from './mlDatasetFile-Czx__g9M.js';
|
|
2
2
|
|
|
3
3
|
type MlPredictResponse = {
|
|
4
4
|
probability: number;
|
package/dist/ml.js
CHANGED
|
@@ -45,6 +45,7 @@ __export(ml_exports, {
|
|
|
45
45
|
isDerivedDatasetFileName: () => isDerivedDatasetFileName,
|
|
46
46
|
isTimestampFeatureKey: () => isTimestampFeatureKey,
|
|
47
47
|
listMlChunkFiles: () => listMlChunkFiles,
|
|
48
|
+
listMlChunkRunIds: () => listMlChunkRunIds,
|
|
48
49
|
listMlChunkStrategies: () => listMlChunkStrategies,
|
|
49
50
|
mergeJsonlFiles: () => mergeJsonlFiles,
|
|
50
51
|
toFileToken: () => toFileToken,
|
|
@@ -58,15 +59,26 @@ var import_events = require("events");
|
|
|
58
59
|
var import_fs = require("fs");
|
|
59
60
|
var import_promises = __toESM(require("fs/promises"));
|
|
60
61
|
var import_path = __toESM(require("path"));
|
|
62
|
+
var import_node_readline = __toESM(require("readline"));
|
|
61
63
|
var DEFAULT_DIR = "data/ml/export";
|
|
62
64
|
var ML_DATASET_WRITE_BATCH_SIZE = 200;
|
|
63
65
|
var ML_CHUNK_FILE_RE = /^ml-dataset-(.+)-chunk-[^.]+\.jsonl$/;
|
|
66
|
+
var BACKTEST_RUN_CHUNK_ID_RE = /^(\d{12}-[a-f0-9]{8})-/;
|
|
64
67
|
var writerByPath = /* @__PURE__ */ new Map();
|
|
65
68
|
var toFileToken = (value) => value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "any";
|
|
66
69
|
var getMlChunkFilePath = (strategyName, chunkId, outDir = DEFAULT_DIR) => import_path.default.join(
|
|
67
70
|
outDir,
|
|
68
71
|
`ml-dataset-${toFileToken(strategyName)}-chunk-${toFileToken(chunkId)}.jsonl`
|
|
69
72
|
);
|
|
73
|
+
var getMlChunkFilePrefix = (strategyName, runId) => `ml-dataset-${toFileToken(strategyName)}-chunk-${runId ? `${toFileToken(runId)}-` : ""}`;
|
|
74
|
+
var getRunIdFromMlChunkFileName = (strategyName, fileName) => {
|
|
75
|
+
const prefix = getMlChunkFilePrefix(strategyName);
|
|
76
|
+
if (!fileName.startsWith(prefix) || !fileName.endsWith(".jsonl")) {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
const chunkToken = fileName.slice(prefix.length, -".jsonl".length);
|
|
80
|
+
return chunkToken.match(BACKTEST_RUN_CHUNK_ID_RE)?.[1] ?? "";
|
|
81
|
+
};
|
|
70
82
|
var appendMlDatasetRow = async (params) => {
|
|
71
83
|
const { strategyName, chunkId, row, outDir = DEFAULT_DIR } = params;
|
|
72
84
|
const filePath = getMlChunkFilePath(strategyName, chunkId, outDir);
|
|
@@ -140,8 +152,8 @@ var closeAllMlDatasetWriters = async () => {
|
|
|
140
152
|
}
|
|
141
153
|
};
|
|
142
154
|
var listMlChunkFiles = async (params) => {
|
|
143
|
-
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
144
|
-
const prefix =
|
|
155
|
+
const { strategyName, outDir = DEFAULT_DIR, runId } = params;
|
|
156
|
+
const prefix = getMlChunkFilePrefix(strategyName, runId);
|
|
145
157
|
let entries = [];
|
|
146
158
|
try {
|
|
147
159
|
entries = await import_promises.default.readdir(outDir);
|
|
@@ -150,6 +162,20 @@ var listMlChunkFiles = async (params) => {
|
|
|
150
162
|
}
|
|
151
163
|
return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).map((name) => import_path.default.join(outDir, name)).sort();
|
|
152
164
|
};
|
|
165
|
+
var listMlChunkRunIds = async (params) => {
|
|
166
|
+
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
167
|
+
let entries = [];
|
|
168
|
+
try {
|
|
169
|
+
entries = await import_promises.default.readdir(outDir);
|
|
170
|
+
} catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
return [
|
|
174
|
+
...new Set(
|
|
175
|
+
entries.map((name) => getRunIdFromMlChunkFileName(strategyName, name)).filter(Boolean)
|
|
176
|
+
)
|
|
177
|
+
].sort();
|
|
178
|
+
};
|
|
153
179
|
var listMlChunkStrategies = async (params) => {
|
|
154
180
|
const outDir = params?.outDir ?? DEFAULT_DIR;
|
|
155
181
|
let entries = [];
|
|
@@ -165,12 +191,37 @@ var listMlChunkStrategies = async (params) => {
|
|
|
165
191
|
].sort();
|
|
166
192
|
};
|
|
167
193
|
var mergeJsonlFiles = async (params) => {
|
|
168
|
-
const { filePaths, outPath } = params;
|
|
194
|
+
const { filePaths, outPath, shouldIncludeRow } = params;
|
|
169
195
|
await import_promises.default.mkdir(import_path.default.dirname(outPath), { recursive: true });
|
|
170
196
|
const stream = (0, import_fs.createWriteStream)(outPath, { encoding: "utf8" });
|
|
171
197
|
const done = Promise.all([(0, import_events.once)(stream, "finish"), (0, import_events.once)(stream, "close")]);
|
|
172
198
|
try {
|
|
173
199
|
for (const filePath of filePaths) {
|
|
200
|
+
if (shouldIncludeRow) {
|
|
201
|
+
const reader2 = import_node_readline.default.createInterface({
|
|
202
|
+
input: (0, import_fs.createReadStream)(filePath, { encoding: "utf8" }),
|
|
203
|
+
crlfDelay: Infinity
|
|
204
|
+
});
|
|
205
|
+
try {
|
|
206
|
+
for await (const line of reader2) {
|
|
207
|
+
const trimmed = line.trim();
|
|
208
|
+
if (!trimmed) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const row = JSON.parse(trimmed);
|
|
212
|
+
if (!shouldIncludeRow(row)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (!stream.write(`${trimmed}
|
|
216
|
+
`)) {
|
|
217
|
+
await (0, import_events.once)(stream, "drain");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
} finally {
|
|
221
|
+
reader2.close();
|
|
222
|
+
}
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
174
225
|
const reader = (0, import_fs.createReadStream)(filePath, { encoding: "utf8" });
|
|
175
226
|
for await (const chunk of reader) {
|
|
176
227
|
if (!stream.write(chunk)) {
|
|
@@ -1740,6 +1791,7 @@ var findLookaheadViolations = (row) => {
|
|
|
1740
1791
|
isDerivedDatasetFileName,
|
|
1741
1792
|
isTimestampFeatureKey,
|
|
1742
1793
|
listMlChunkFiles,
|
|
1794
|
+
listMlChunkRunIds,
|
|
1743
1795
|
listMlChunkStrategies,
|
|
1744
1796
|
mergeJsonlFiles,
|
|
1745
1797
|
toFileToken,
|
package/dist/ml.mjs
CHANGED
|
@@ -5,10 +5,11 @@ import {
|
|
|
5
5
|
flushMlDatasetWriter,
|
|
6
6
|
getMlChunkFilePath,
|
|
7
7
|
listMlChunkFiles,
|
|
8
|
+
listMlChunkRunIds,
|
|
8
9
|
listMlChunkStrategies,
|
|
9
10
|
mergeJsonlFiles,
|
|
10
11
|
toFileToken
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RQP5VSTH.mjs";
|
|
12
13
|
import {
|
|
13
14
|
logger
|
|
14
15
|
} from "./chunk-LNFUOXDW.mjs";
|
|
@@ -1527,6 +1528,7 @@ export {
|
|
|
1527
1528
|
isDerivedDatasetFileName,
|
|
1528
1529
|
isTimestampFeatureKey,
|
|
1529
1530
|
listMlChunkFiles,
|
|
1531
|
+
listMlChunkRunIds,
|
|
1530
1532
|
listMlChunkStrategies,
|
|
1531
1533
|
mergeJsonlFiles,
|
|
1532
1534
|
toFileToken,
|
|
@@ -12,6 +12,11 @@ declare const closeAllMlDatasetWriters: () => Promise<void>;
|
|
|
12
12
|
declare const listMlChunkFiles: (params: {
|
|
13
13
|
strategyName: string;
|
|
14
14
|
outDir?: string;
|
|
15
|
+
runId?: string;
|
|
16
|
+
}) => Promise<string[]>;
|
|
17
|
+
declare const listMlChunkRunIds: (params: {
|
|
18
|
+
strategyName: string;
|
|
19
|
+
outDir?: string;
|
|
15
20
|
}) => Promise<string[]>;
|
|
16
21
|
declare const listMlChunkStrategies: (params?: {
|
|
17
22
|
outDir?: string;
|
|
@@ -19,6 +24,7 @@ declare const listMlChunkStrategies: (params?: {
|
|
|
19
24
|
declare const mergeJsonlFiles: (params: {
|
|
20
25
|
filePaths: string[];
|
|
21
26
|
outPath: string;
|
|
27
|
+
shouldIncludeRow?: (row: Record<string, unknown>) => boolean;
|
|
22
28
|
}) => Promise<void>;
|
|
23
29
|
|
|
24
|
-
export { appendMlDatasetRow as a, closeMlDatasetWriter as b, closeAllMlDatasetWriters as c,
|
|
30
|
+
export { appendMlDatasetRow as a, closeMlDatasetWriter as b, closeAllMlDatasetWriters as c, listMlChunkRunIds as d, listMlChunkStrategies as e, flushMlDatasetWriter as f, getMlChunkFilePath as g, listMlChunkFiles as l, mergeJsonlFiles as m, toFileToken as t };
|
|
@@ -12,6 +12,11 @@ declare const closeAllMlDatasetWriters: () => Promise<void>;
|
|
|
12
12
|
declare const listMlChunkFiles: (params: {
|
|
13
13
|
strategyName: string;
|
|
14
14
|
outDir?: string;
|
|
15
|
+
runId?: string;
|
|
16
|
+
}) => Promise<string[]>;
|
|
17
|
+
declare const listMlChunkRunIds: (params: {
|
|
18
|
+
strategyName: string;
|
|
19
|
+
outDir?: string;
|
|
15
20
|
}) => Promise<string[]>;
|
|
16
21
|
declare const listMlChunkStrategies: (params?: {
|
|
17
22
|
outDir?: string;
|
|
@@ -19,6 +24,7 @@ declare const listMlChunkStrategies: (params?: {
|
|
|
19
24
|
declare const mergeJsonlFiles: (params: {
|
|
20
25
|
filePaths: string[];
|
|
21
26
|
outPath: string;
|
|
27
|
+
shouldIncludeRow?: (row: Record<string, unknown>) => boolean;
|
|
22
28
|
}) => Promise<void>;
|
|
23
29
|
|
|
24
|
-
export { appendMlDatasetRow as a, closeMlDatasetWriter as b, closeAllMlDatasetWriters as c,
|
|
30
|
+
export { appendMlDatasetRow as a, closeMlDatasetWriter as b, closeAllMlDatasetWriters as c, listMlChunkRunIds as d, listMlChunkStrategies as e, flushMlDatasetWriter as f, getMlChunkFilePath as g, listMlChunkFiles as l, mergeJsonlFiles as m, toFileToken as t };
|
package/dist/redis.d.mts
CHANGED
|
@@ -3,9 +3,11 @@ import Redis from 'ioredis';
|
|
|
3
3
|
declare global {
|
|
4
4
|
var __redis__: Redis | undefined;
|
|
5
5
|
}
|
|
6
|
+
declare const closeRedisConnection: () => Promise<void>;
|
|
6
7
|
interface Options {
|
|
7
8
|
expire?: number;
|
|
8
9
|
}
|
|
10
|
+
declare const publishData: (channel: string, value: unknown) => Promise<number>;
|
|
9
11
|
interface DelKeyOptions {
|
|
10
12
|
raiseOnMisconf?: boolean;
|
|
11
13
|
}
|
|
@@ -18,6 +20,7 @@ declare class RedisWriteBlockedError extends Error {
|
|
|
18
20
|
declare const delKeyWithOptions: (key: string, options?: DelKeyOptions) => Promise<boolean>;
|
|
19
21
|
declare const setData: <T>(key: string, data: T, options?: Options) => Promise<void>;
|
|
20
22
|
declare const setHashJsonField: <T>(key: string, field: string, data: T, options?: Options) => Promise<void>;
|
|
23
|
+
declare const getHashJsonField: <T>(key: string, field: string, fallback?: T | null) => Promise<T | null>;
|
|
21
24
|
declare const getHashJsonValues: <T>(key: string) => Promise<T[]>;
|
|
22
25
|
declare const incrHashFields: (key: string, increments: Record<string, number>, options?: Options) => Promise<void>;
|
|
23
26
|
declare const getHashData: (key: string) => Promise<Record<string, string>>;
|
|
@@ -26,13 +29,21 @@ declare const consumeScreenshotSessionToken: (token: string) => Promise<string |
|
|
|
26
29
|
declare const redisKeys: {
|
|
27
30
|
users: () => string;
|
|
28
31
|
user: (userName: string) => string;
|
|
32
|
+
tradingAccounts: (userName: string) => string;
|
|
33
|
+
tradingAccount: (userName: string, accountId: string) => string;
|
|
34
|
+
runtimeDeployments: (userName: string) => string;
|
|
35
|
+
runtimeDeployment: (userName: string, deploymentId: string) => string;
|
|
36
|
+
runtimeDeploymentHeartbeat: (userName: string, deploymentId: string) => string;
|
|
29
37
|
bots: (userName: string) => string;
|
|
30
38
|
botsPrefix: () => string;
|
|
31
39
|
bot: (userName: string, botId: string) => string;
|
|
32
40
|
backtestConfig: (userName: string, config: string) => string;
|
|
33
41
|
strategies: (userName: string) => string;
|
|
34
|
-
strategyConfig: (userName: string, strategyName: string) => string;
|
|
42
|
+
strategyConfig: (userName: string, strategyName: string, configId?: string) => string;
|
|
35
43
|
strategyResults: (userName: string, strategyName: string) => string;
|
|
44
|
+
strategyCharts: (userName: string, mode: string) => string;
|
|
45
|
+
strategyChartCards: (userName: string, mode: string) => string;
|
|
46
|
+
strategyChartCard: (userName: string, mode: string, cardId: string) => string;
|
|
36
47
|
tests: (userName: string, strategyName?: string) => string;
|
|
37
48
|
testOrders: (userName: string, strategyName: string, testName: string) => string;
|
|
38
49
|
testConfig: (userName: string, strategyName: string, testName: string) => string;
|
|
@@ -41,6 +52,7 @@ declare const redisKeys: {
|
|
|
41
52
|
cacheChunk: (userName: string, chunkId: string) => string;
|
|
42
53
|
cacheOrders: (userName: string, orderLogId: string) => string;
|
|
43
54
|
cachePositions: (userName: string, orderLogId: string) => string;
|
|
55
|
+
tickerUniverse: (userName: string, connectorName: string, universe?: string, accountId?: string) => string;
|
|
44
56
|
signal: (symbol: string, signalId: string) => string;
|
|
45
57
|
signalsBySymbol: (symbol: string) => string;
|
|
46
58
|
storeSignal: (symbol: string, signalId: string) => string;
|
|
@@ -56,12 +68,18 @@ declare const redisKeys: {
|
|
|
56
68
|
runtimeSignalEvaluationStatsBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
57
69
|
runtimeTrades: (userName: string) => string;
|
|
58
70
|
runtimeTrade: (userName: string, orderId: string) => string;
|
|
71
|
+
runtimeTradeBuckets: (userName: string) => string;
|
|
72
|
+
runtimeTradeBucket: (userName: string, dayKey: string) => string;
|
|
59
73
|
runtimeActiveTrades: (userName: string) => string;
|
|
60
|
-
runtimeActiveTrade: (userName: string, symbol: string) => string;
|
|
74
|
+
runtimeActiveTrade: (userName: string, symbol: string, scopeId?: string) => string;
|
|
61
75
|
aiChatHistory: (userName: string, symbolKey: string) => string;
|
|
62
76
|
analysis: (symbol: string, signalId: string) => string;
|
|
63
77
|
screenshotSessionToken: (token: string) => string;
|
|
64
78
|
backtestResults: (userName: string, config: string, timestamp: string) => string;
|
|
79
|
+
backtestRuns: (userName: string) => string;
|
|
80
|
+
backtestRun: (userName: string, runId: string) => string;
|
|
81
|
+
backtestRunResults: (userName: string, runId: string) => string;
|
|
82
|
+
backtestLatestRun: (userName: string, config: string) => string;
|
|
65
83
|
researchRuns: (userName: string) => string;
|
|
66
84
|
researchRun: (userName: string, runId: string) => string;
|
|
67
85
|
researchLatestRun: (userName: string, strategyName: string) => string;
|
|
@@ -73,4 +91,4 @@ declare const redisKeys: {
|
|
|
73
91
|
mlResult: (strategyName: string, signalId: string) => string;
|
|
74
92
|
};
|
|
75
93
|
|
|
76
|
-
export { RedisWriteBlockedError, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonValues, getKeys, incrHashFields, redisKeys, setData, setHashJsonField };
|
|
94
|
+
export { RedisWriteBlockedError, closeRedisConnection, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonField, getHashJsonValues, getKeys, incrHashFields, publishData, redisKeys, setData, setHashJsonField };
|
package/dist/redis.d.ts
CHANGED
|
@@ -3,9 +3,11 @@ import Redis from 'ioredis';
|
|
|
3
3
|
declare global {
|
|
4
4
|
var __redis__: Redis | undefined;
|
|
5
5
|
}
|
|
6
|
+
declare const closeRedisConnection: () => Promise<void>;
|
|
6
7
|
interface Options {
|
|
7
8
|
expire?: number;
|
|
8
9
|
}
|
|
10
|
+
declare const publishData: (channel: string, value: unknown) => Promise<number>;
|
|
9
11
|
interface DelKeyOptions {
|
|
10
12
|
raiseOnMisconf?: boolean;
|
|
11
13
|
}
|
|
@@ -18,6 +20,7 @@ declare class RedisWriteBlockedError extends Error {
|
|
|
18
20
|
declare const delKeyWithOptions: (key: string, options?: DelKeyOptions) => Promise<boolean>;
|
|
19
21
|
declare const setData: <T>(key: string, data: T, options?: Options) => Promise<void>;
|
|
20
22
|
declare const setHashJsonField: <T>(key: string, field: string, data: T, options?: Options) => Promise<void>;
|
|
23
|
+
declare const getHashJsonField: <T>(key: string, field: string, fallback?: T | null) => Promise<T | null>;
|
|
21
24
|
declare const getHashJsonValues: <T>(key: string) => Promise<T[]>;
|
|
22
25
|
declare const incrHashFields: (key: string, increments: Record<string, number>, options?: Options) => Promise<void>;
|
|
23
26
|
declare const getHashData: (key: string) => Promise<Record<string, string>>;
|
|
@@ -26,13 +29,21 @@ declare const consumeScreenshotSessionToken: (token: string) => Promise<string |
|
|
|
26
29
|
declare const redisKeys: {
|
|
27
30
|
users: () => string;
|
|
28
31
|
user: (userName: string) => string;
|
|
32
|
+
tradingAccounts: (userName: string) => string;
|
|
33
|
+
tradingAccount: (userName: string, accountId: string) => string;
|
|
34
|
+
runtimeDeployments: (userName: string) => string;
|
|
35
|
+
runtimeDeployment: (userName: string, deploymentId: string) => string;
|
|
36
|
+
runtimeDeploymentHeartbeat: (userName: string, deploymentId: string) => string;
|
|
29
37
|
bots: (userName: string) => string;
|
|
30
38
|
botsPrefix: () => string;
|
|
31
39
|
bot: (userName: string, botId: string) => string;
|
|
32
40
|
backtestConfig: (userName: string, config: string) => string;
|
|
33
41
|
strategies: (userName: string) => string;
|
|
34
|
-
strategyConfig: (userName: string, strategyName: string) => string;
|
|
42
|
+
strategyConfig: (userName: string, strategyName: string, configId?: string) => string;
|
|
35
43
|
strategyResults: (userName: string, strategyName: string) => string;
|
|
44
|
+
strategyCharts: (userName: string, mode: string) => string;
|
|
45
|
+
strategyChartCards: (userName: string, mode: string) => string;
|
|
46
|
+
strategyChartCard: (userName: string, mode: string, cardId: string) => string;
|
|
36
47
|
tests: (userName: string, strategyName?: string) => string;
|
|
37
48
|
testOrders: (userName: string, strategyName: string, testName: string) => string;
|
|
38
49
|
testConfig: (userName: string, strategyName: string, testName: string) => string;
|
|
@@ -41,6 +52,7 @@ declare const redisKeys: {
|
|
|
41
52
|
cacheChunk: (userName: string, chunkId: string) => string;
|
|
42
53
|
cacheOrders: (userName: string, orderLogId: string) => string;
|
|
43
54
|
cachePositions: (userName: string, orderLogId: string) => string;
|
|
55
|
+
tickerUniverse: (userName: string, connectorName: string, universe?: string, accountId?: string) => string;
|
|
44
56
|
signal: (symbol: string, signalId: string) => string;
|
|
45
57
|
signalsBySymbol: (symbol: string) => string;
|
|
46
58
|
storeSignal: (symbol: string, signalId: string) => string;
|
|
@@ -56,12 +68,18 @@ declare const redisKeys: {
|
|
|
56
68
|
runtimeSignalEvaluationStatsBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
57
69
|
runtimeTrades: (userName: string) => string;
|
|
58
70
|
runtimeTrade: (userName: string, orderId: string) => string;
|
|
71
|
+
runtimeTradeBuckets: (userName: string) => string;
|
|
72
|
+
runtimeTradeBucket: (userName: string, dayKey: string) => string;
|
|
59
73
|
runtimeActiveTrades: (userName: string) => string;
|
|
60
|
-
runtimeActiveTrade: (userName: string, symbol: string) => string;
|
|
74
|
+
runtimeActiveTrade: (userName: string, symbol: string, scopeId?: string) => string;
|
|
61
75
|
aiChatHistory: (userName: string, symbolKey: string) => string;
|
|
62
76
|
analysis: (symbol: string, signalId: string) => string;
|
|
63
77
|
screenshotSessionToken: (token: string) => string;
|
|
64
78
|
backtestResults: (userName: string, config: string, timestamp: string) => string;
|
|
79
|
+
backtestRuns: (userName: string) => string;
|
|
80
|
+
backtestRun: (userName: string, runId: string) => string;
|
|
81
|
+
backtestRunResults: (userName: string, runId: string) => string;
|
|
82
|
+
backtestLatestRun: (userName: string, config: string) => string;
|
|
65
83
|
researchRuns: (userName: string) => string;
|
|
66
84
|
researchRun: (userName: string, runId: string) => string;
|
|
67
85
|
researchLatestRun: (userName: string, strategyName: string) => string;
|
|
@@ -73,4 +91,4 @@ declare const redisKeys: {
|
|
|
73
91
|
mlResult: (strategyName: string, signalId: string) => string;
|
|
74
92
|
};
|
|
75
93
|
|
|
76
|
-
export { RedisWriteBlockedError, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonValues, getKeys, incrHashFields, redisKeys, setData, setHashJsonField };
|
|
94
|
+
export { RedisWriteBlockedError, closeRedisConnection, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonField, getHashJsonValues, getKeys, incrHashFields, publishData, redisKeys, setData, setHashJsonField };
|
package/dist/redis.js
CHANGED
|
@@ -31,15 +31,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var redis_exports = {};
|
|
32
32
|
__export(redis_exports, {
|
|
33
33
|
RedisWriteBlockedError: () => RedisWriteBlockedError,
|
|
34
|
+
closeRedisConnection: () => closeRedisConnection,
|
|
34
35
|
consumeScreenshotSessionToken: () => consumeScreenshotSessionToken,
|
|
35
36
|
createScreenshotSessionToken: () => createScreenshotSessionToken,
|
|
36
37
|
delKey: () => delKey,
|
|
37
38
|
delKeyWithOptions: () => delKeyWithOptions,
|
|
38
39
|
getData: () => getData,
|
|
39
40
|
getHashData: () => getHashData,
|
|
41
|
+
getHashJsonField: () => getHashJsonField,
|
|
40
42
|
getHashJsonValues: () => getHashJsonValues,
|
|
41
43
|
getKeys: () => getKeys,
|
|
42
44
|
incrHashFields: () => incrHashFields,
|
|
45
|
+
publishData: () => publishData,
|
|
43
46
|
redisKeys: () => redisKeys,
|
|
44
47
|
setData: () => setData,
|
|
45
48
|
setHashJsonField: () => setHashJsonField
|
|
@@ -58,9 +61,12 @@ var logger = {
|
|
|
58
61
|
};
|
|
59
62
|
var redisConnectionWarningShown = false;
|
|
60
63
|
var redisUnavailable = false;
|
|
61
|
-
var isRedisConnectivityError = (error) =>
|
|
62
|
-
error.message
|
|
63
|
-
|
|
64
|
+
var isRedisConnectivityError = (error) => {
|
|
65
|
+
const errorText = [error.name, error.message, String(error)].join(" ");
|
|
66
|
+
return /ECONNREFUSED|ECONNRESET|ECONNABORTED|EPIPE|ENOTFOUND|EAI_AGAIN|ETIMEDOUT|MaxRetriesPerRequestError|Connection is closed|Stream isn't writeable/i.test(
|
|
67
|
+
errorText
|
|
68
|
+
);
|
|
69
|
+
};
|
|
64
70
|
var toNonNegativeInt = (value, fallback) => {
|
|
65
71
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
66
72
|
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
@@ -116,6 +122,16 @@ var getRedis = () => {
|
|
|
116
122
|
}
|
|
117
123
|
return global.__redis__;
|
|
118
124
|
};
|
|
125
|
+
var closeRedisConnection = async () => {
|
|
126
|
+
const redis = global.__redis__;
|
|
127
|
+
if (!redis) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
global.__redis__ = void 0;
|
|
131
|
+
redisUnavailable = false;
|
|
132
|
+
redisConnectionWarningShown = false;
|
|
133
|
+
redis.disconnect();
|
|
134
|
+
};
|
|
119
135
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
120
136
|
var getRedisStatus = (redis) => String(redis.status ?? "ready");
|
|
121
137
|
var waitForRedisReady = async (redis) => {
|
|
@@ -156,6 +172,11 @@ var toResultString = (result) => {
|
|
|
156
172
|
if (Buffer.isBuffer(result)) return result.toString("utf8");
|
|
157
173
|
return String(result);
|
|
158
174
|
};
|
|
175
|
+
var publishData = async (channel, value) => {
|
|
176
|
+
const redis = await getReadyRedis();
|
|
177
|
+
if (!redis) return 0;
|
|
178
|
+
return redis.publish(channel, toJson(value));
|
|
179
|
+
};
|
|
159
180
|
var DEFAULT_OPTIONS = {
|
|
160
181
|
expire: TTL_1D
|
|
161
182
|
};
|
|
@@ -347,6 +368,25 @@ var setHashJsonField = async (key, field, data, options = {}) => {
|
|
|
347
368
|
logger.log("error", "failed HSET %s[%s]: %s", key, field, String(e));
|
|
348
369
|
}
|
|
349
370
|
};
|
|
371
|
+
var getHashJsonField = async (key, field, fallback = null) => {
|
|
372
|
+
if (redisUnavailable) return fallback;
|
|
373
|
+
const redis = await getReadyRedis();
|
|
374
|
+
if (!redis) return fallback;
|
|
375
|
+
try {
|
|
376
|
+
const value = await redis.call("HGET", key, field);
|
|
377
|
+
if (typeof value !== "string" || !value) {
|
|
378
|
+
return fallback;
|
|
379
|
+
}
|
|
380
|
+
return JSON.parse(value);
|
|
381
|
+
} catch (e) {
|
|
382
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
383
|
+
markRedisUnavailable(e);
|
|
384
|
+
return fallback;
|
|
385
|
+
}
|
|
386
|
+
logger.log("error", "failed HGET %s[%s]: %s", key, field, String(e));
|
|
387
|
+
return fallback;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
350
390
|
var getHashJsonValues = async (key) => {
|
|
351
391
|
if (redisUnavailable) return [];
|
|
352
392
|
const redis = await getReadyRedis();
|
|
@@ -452,13 +492,21 @@ var consumeScreenshotSessionToken = async (token) => {
|
|
|
452
492
|
var redisKeys = {
|
|
453
493
|
users: () => "users:index:",
|
|
454
494
|
user: (userName) => `users:index:${userName}`,
|
|
495
|
+
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
496
|
+
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
497
|
+
runtimeDeployments: (userName) => `users:${userName}:runtime:deployments:`,
|
|
498
|
+
runtimeDeployment: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}`,
|
|
499
|
+
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
455
500
|
bots: (userName) => `users:${userName}:bots`,
|
|
456
501
|
botsPrefix: () => "users:",
|
|
457
502
|
bot: (userName, botId) => `users:${userName}:bots:${botId}`,
|
|
458
503
|
backtestConfig: (userName, config) => `users:${userName}:backtests:configs:${config}`,
|
|
459
504
|
strategies: (userName) => `users:${userName}:strategies`,
|
|
460
|
-
strategyConfig: (userName, strategyName) => `users:${userName}:strategies:${strategyName}
|
|
505
|
+
strategyConfig: (userName, strategyName, configId = "config") => `users:${userName}:strategies:${strategyName}:${configId}`,
|
|
461
506
|
strategyResults: (userName, strategyName) => `users:${userName}:strategies:${strategyName}:results`,
|
|
507
|
+
strategyCharts: (userName, mode) => `users:${userName}:strategies:charts:${mode}`,
|
|
508
|
+
strategyChartCards: (userName, mode) => `users:${userName}:strategies:charts:${mode}:cards:`,
|
|
509
|
+
strategyChartCard: (userName, mode, cardId) => `users:${userName}:strategies:charts:${mode}:cards:${cardId}`,
|
|
462
510
|
tests: (userName, strategyName) => strategyName ? `users:${userName}:tests:${strategyName}` : `users:${userName}:tests:`,
|
|
463
511
|
testOrders: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:orders`,
|
|
464
512
|
testConfig: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:config`,
|
|
@@ -467,6 +515,7 @@ var redisKeys = {
|
|
|
467
515
|
cacheChunk: (userName, chunkId) => `users:${userName}:cache:tests:chunks:${chunkId}`,
|
|
468
516
|
cacheOrders: (userName, orderLogId) => `users:${userName}:cache:tests:orders:${orderLogId}`,
|
|
469
517
|
cachePositions: (userName, orderLogId) => `users:${userName}:cache:tests:positions:${orderLogId}`,
|
|
518
|
+
tickerUniverse: (userName, connectorName, universe, accountId) => universe || accountId ? `users:${userName}:cache:tickers:${connectorName}:${universe ?? "crypto"}:${accountId ?? "default"}` : `users:${userName}:cache:tickers:${connectorName}`,
|
|
470
519
|
signal: (symbol, signalId) => `signals:${symbol}:${signalId}`,
|
|
471
520
|
signalsBySymbol: (symbol) => `signals:${symbol}:`,
|
|
472
521
|
storeSignal: (symbol, signalId) => `store:signals:${symbol}:${signalId}`,
|
|
@@ -482,12 +531,18 @@ var redisKeys = {
|
|
|
482
531
|
runtimeSignalEvaluationStatsBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluation-stats:days:${dayKey}:${strategyName}`,
|
|
483
532
|
runtimeTrades: (userName) => `users:${userName}:runtime:trade-records:`,
|
|
484
533
|
runtimeTrade: (userName, orderId) => `users:${userName}:runtime:trade-records:${orderId}`,
|
|
534
|
+
runtimeTradeBuckets: (userName) => `users:${userName}:runtime:trade-records:days:`,
|
|
535
|
+
runtimeTradeBucket: (userName, dayKey) => `users:${userName}:runtime:trade-records:days:${dayKey}`,
|
|
485
536
|
runtimeActiveTrades: (userName) => `users:${userName}:runtime:active-trades:`,
|
|
486
|
-
runtimeActiveTrade: (userName, symbol) => `users:${userName}:runtime:active-trades:${symbol}`,
|
|
537
|
+
runtimeActiveTrade: (userName, symbol, scopeId) => scopeId ? `users:${userName}:runtime:active-trades:${scopeId}:${symbol}` : `users:${userName}:runtime:active-trades:${symbol}`,
|
|
487
538
|
aiChatHistory: (userName, symbolKey) => `users:${userName}:ai:chats:${symbolKey}`,
|
|
488
539
|
analysis: (symbol, signalId) => `analysis:${symbol}:${signalId}`,
|
|
489
540
|
screenshotSessionToken: (token) => `auth:screenshot:${token}`,
|
|
490
541
|
backtestResults: (userName, config, timestamp) => `users:${userName}:backtests:results:${config}:${timestamp}`,
|
|
542
|
+
backtestRuns: (userName) => `users:${userName}:backtests:runs:`,
|
|
543
|
+
backtestRun: (userName, runId) => `users:${userName}:backtests:runs:${runId}`,
|
|
544
|
+
backtestRunResults: (userName, runId) => `users:${userName}:backtests:runs:${runId}:results`,
|
|
545
|
+
backtestLatestRun: (userName, config) => `users:${userName}:backtests:latest:${config}`,
|
|
491
546
|
researchRuns: (userName) => `users:${userName}:research:runs:`,
|
|
492
547
|
researchRun: (userName, runId) => `users:${userName}:research:runs:${runId}`,
|
|
493
548
|
researchLatestRun: (userName, strategyName) => `users:${userName}:research:latest:${strategyName}`,
|
|
@@ -501,15 +556,18 @@ var redisKeys = {
|
|
|
501
556
|
// Annotate the CommonJS export names for ESM import in node:
|
|
502
557
|
0 && (module.exports = {
|
|
503
558
|
RedisWriteBlockedError,
|
|
559
|
+
closeRedisConnection,
|
|
504
560
|
consumeScreenshotSessionToken,
|
|
505
561
|
createScreenshotSessionToken,
|
|
506
562
|
delKey,
|
|
507
563
|
delKeyWithOptions,
|
|
508
564
|
getData,
|
|
509
565
|
getHashData,
|
|
566
|
+
getHashJsonField,
|
|
510
567
|
getHashJsonValues,
|
|
511
568
|
getKeys,
|
|
512
569
|
incrHashFields,
|
|
570
|
+
publishData,
|
|
513
571
|
redisKeys,
|
|
514
572
|
setData,
|
|
515
573
|
setHashJsonField
|
package/dist/redis.mjs
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RedisWriteBlockedError,
|
|
3
|
+
closeRedisConnection,
|
|
3
4
|
consumeScreenshotSessionToken,
|
|
4
5
|
createScreenshotSessionToken,
|
|
5
6
|
delKey,
|
|
6
7
|
delKeyWithOptions,
|
|
7
8
|
getData,
|
|
8
9
|
getHashData,
|
|
10
|
+
getHashJsonField,
|
|
9
11
|
getHashJsonValues,
|
|
10
12
|
getKeys,
|
|
11
13
|
incrHashFields,
|
|
14
|
+
publishData,
|
|
12
15
|
redisKeys,
|
|
13
16
|
setData,
|
|
14
17
|
setHashJsonField
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-DXG2UDNA.mjs";
|
|
16
19
|
export {
|
|
17
20
|
RedisWriteBlockedError,
|
|
21
|
+
closeRedisConnection,
|
|
18
22
|
consumeScreenshotSessionToken,
|
|
19
23
|
createScreenshotSessionToken,
|
|
20
24
|
delKey,
|
|
21
25
|
delKeyWithOptions,
|
|
22
26
|
getData,
|
|
23
27
|
getHashData,
|
|
28
|
+
getHashJsonField,
|
|
24
29
|
getHashJsonValues,
|
|
25
30
|
getKeys,
|
|
26
31
|
incrHashFields,
|
|
32
|
+
publishData,
|
|
27
33
|
redisKeys,
|
|
28
34
|
setData,
|
|
29
35
|
setHashJsonField
|