@tradejs/infra 3.1.28-beta.252 → 3.1.28-beta.253
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/{chunk-46XQGVDB.mjs → chunk-GTZOMAFK.mjs} +3 -0
- package/dist/redis.d.mts +3 -0
- package/dist/redis.d.ts +3 -0
- package/dist/redis.js +3 -0
- package/dist/redis.mjs +1 -1
- package/dist/runtimeControls.js +3 -0
- package/dist/runtimeControls.mjs +1 -1
- package/dist/runtimeDeploymentEvents.d.mts +11 -0
- package/dist/runtimeDeploymentEvents.d.ts +11 -0
- package/dist/runtimeDeploymentEvents.js +446 -0
- package/dist/runtimeDeploymentEvents.mjs +105 -0
- package/dist/runtimeHeartbeats.js +3 -0
- package/dist/runtimeHeartbeats.mjs +1 -1
- package/dist/runtimeStrategyConfigs.js +3 -0
- package/dist/runtimeStrategyConfigs.mjs +1 -1
- package/dist/tradingAccounts.js +3 -0
- package/dist/tradingAccounts.mjs +1 -1
- package/dist/userSettings.js +3 -0
- package/dist/userSettings.mjs +1 -1
- package/package.json +7 -2
|
@@ -602,6 +602,9 @@ var redisKeys = {
|
|
|
602
602
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
603
603
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
604
604
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
605
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
606
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
607
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
605
608
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
606
609
|
bots: (userName) => `users:${userName}:bots`,
|
|
607
610
|
botsPrefix: () => "users:",
|
package/dist/redis.d.mts
CHANGED
|
@@ -47,6 +47,9 @@ declare const redisKeys: {
|
|
|
47
47
|
tradingAccounts: (userName: string) => string;
|
|
48
48
|
tradingAccount: (userName: string, accountId: string) => string;
|
|
49
49
|
runtimeDeploymentHeartbeat: (userName: string, deploymentId: string) => string;
|
|
50
|
+
runtimeDeploymentCompositionState: (userName: string, deploymentId: string) => string;
|
|
51
|
+
runtimeDeploymentCompositionEvents: (userName: string, deploymentId: string) => string;
|
|
52
|
+
runtimeDeploymentCompositionEvent: (userName: string, deploymentId: string, eventId: string) => string;
|
|
50
53
|
runtimeControls: (userName: string) => string;
|
|
51
54
|
bots: (userName: string) => string;
|
|
52
55
|
botsPrefix: () => string;
|
package/dist/redis.d.ts
CHANGED
|
@@ -47,6 +47,9 @@ declare const redisKeys: {
|
|
|
47
47
|
tradingAccounts: (userName: string) => string;
|
|
48
48
|
tradingAccount: (userName: string, accountId: string) => string;
|
|
49
49
|
runtimeDeploymentHeartbeat: (userName: string, deploymentId: string) => string;
|
|
50
|
+
runtimeDeploymentCompositionState: (userName: string, deploymentId: string) => string;
|
|
51
|
+
runtimeDeploymentCompositionEvents: (userName: string, deploymentId: string) => string;
|
|
52
|
+
runtimeDeploymentCompositionEvent: (userName: string, deploymentId: string, eventId: string) => string;
|
|
50
53
|
runtimeControls: (userName: string) => string;
|
|
51
54
|
bots: (userName: string) => string;
|
|
52
55
|
botsPrefix: () => string;
|
package/dist/redis.js
CHANGED
|
@@ -657,6 +657,9 @@ var redisKeys = {
|
|
|
657
657
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
658
658
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
659
659
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
660
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
661
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
662
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
660
663
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
661
664
|
bots: (userName) => `users:${userName}:bots`,
|
|
662
665
|
botsPrefix: () => "users:",
|
package/dist/redis.mjs
CHANGED
package/dist/runtimeControls.js
CHANGED
|
@@ -257,6 +257,9 @@ var redisKeys = {
|
|
|
257
257
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
258
258
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
259
259
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
260
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
261
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
262
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
260
263
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
261
264
|
bots: (userName) => `users:${userName}:bots`,
|
|
262
265
|
botsPrefix: () => "users:",
|
package/dist/runtimeControls.mjs
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RuntimeDeploymentCompositionEvent, RuntimeDeployment } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const isRuntimeDeploymentCompositionEvent: (value: unknown) => value is RuntimeDeploymentCompositionEvent;
|
|
4
|
+
declare const observeRuntimeDeploymentComposition: ({ userName, deployment, observedAt, }: {
|
|
5
|
+
userName: string;
|
|
6
|
+
deployment: RuntimeDeployment;
|
|
7
|
+
observedAt?: number;
|
|
8
|
+
}) => Promise<RuntimeDeploymentCompositionEvent | null>;
|
|
9
|
+
declare const loadRuntimeDeploymentCompositionEvents: (userName: string, deploymentId: string) => Promise<RuntimeDeploymentCompositionEvent[]>;
|
|
10
|
+
|
|
11
|
+
export { isRuntimeDeploymentCompositionEvent, loadRuntimeDeploymentCompositionEvents, observeRuntimeDeploymentComposition };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RuntimeDeploymentCompositionEvent, RuntimeDeployment } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const isRuntimeDeploymentCompositionEvent: (value: unknown) => value is RuntimeDeploymentCompositionEvent;
|
|
4
|
+
declare const observeRuntimeDeploymentComposition: ({ userName, deployment, observedAt, }: {
|
|
5
|
+
userName: string;
|
|
6
|
+
deployment: RuntimeDeployment;
|
|
7
|
+
observedAt?: number;
|
|
8
|
+
}) => Promise<RuntimeDeploymentCompositionEvent | null>;
|
|
9
|
+
declare const loadRuntimeDeploymentCompositionEvents: (userName: string, deploymentId: string) => Promise<RuntimeDeploymentCompositionEvent[]>;
|
|
10
|
+
|
|
11
|
+
export { isRuntimeDeploymentCompositionEvent, loadRuntimeDeploymentCompositionEvents, observeRuntimeDeploymentComposition };
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/runtimeDeploymentEvents.ts
|
|
31
|
+
var runtimeDeploymentEvents_exports = {};
|
|
32
|
+
__export(runtimeDeploymentEvents_exports, {
|
|
33
|
+
isRuntimeDeploymentCompositionEvent: () => isRuntimeDeploymentCompositionEvent,
|
|
34
|
+
loadRuntimeDeploymentCompositionEvents: () => loadRuntimeDeploymentCompositionEvents,
|
|
35
|
+
observeRuntimeDeploymentComposition: () => observeRuntimeDeploymentComposition
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(runtimeDeploymentEvents_exports);
|
|
38
|
+
var import_node_crypto = require("crypto");
|
|
39
|
+
var import_types = require("@tradejs/types");
|
|
40
|
+
|
|
41
|
+
// src/redis.ts
|
|
42
|
+
var import_ioredis = __toESM(require("ioredis"));
|
|
43
|
+
var TTL_1D = 86400;
|
|
44
|
+
var SCREENSHOT_TOKEN_TTL_SECONDS = 15 * 60;
|
|
45
|
+
var toJson = (value) => JSON.stringify(value);
|
|
46
|
+
var logger = {
|
|
47
|
+
log: (level, message, ...args) => {
|
|
48
|
+
const method = level === "error" ? "error" : level === "warn" ? "warn" : "log";
|
|
49
|
+
console[method](`[infra:redis] ${message}`, ...args);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var redisConnectionWarningShown = false;
|
|
53
|
+
var redisUnavailable = false;
|
|
54
|
+
var isRedisConnectivityError = (error) => {
|
|
55
|
+
const errorText = [error.name, error.message, String(error)].join(" ");
|
|
56
|
+
return /ECONNREFUSED|ECONNRESET|ECONNABORTED|EPIPE|ENOTFOUND|EAI_AGAIN|ETIMEDOUT|MaxRetriesPerRequestError|Connection is closed|Stream isn't writeable/i.test(
|
|
57
|
+
errorText
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
var toNonNegativeInt = (value, fallback) => {
|
|
61
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
62
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
63
|
+
};
|
|
64
|
+
var toPositiveInt = (value, fallback) => {
|
|
65
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
66
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
67
|
+
};
|
|
68
|
+
var markRedisUnavailable = (error) => {
|
|
69
|
+
redisUnavailable = true;
|
|
70
|
+
if (redisConnectionWarningShown) return;
|
|
71
|
+
redisConnectionWarningShown = true;
|
|
72
|
+
logger.log(
|
|
73
|
+
"warn",
|
|
74
|
+
"Redis is unavailable: %s. Cache-dependent features are temporarily disabled.",
|
|
75
|
+
error.message
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
var getRedis = () => {
|
|
79
|
+
if (!global.__redis__) {
|
|
80
|
+
const host = process.env.REDIS_HOST || "127.0.0.1";
|
|
81
|
+
const port = toPositiveInt(process.env.REDIS_PORT, 6379);
|
|
82
|
+
const connectTimeout = toPositiveInt(
|
|
83
|
+
process.env.REDIS_CONNECT_TIMEOUT_MS,
|
|
84
|
+
3e3
|
|
85
|
+
);
|
|
86
|
+
const maxRetriesPerRequest = toNonNegativeInt(
|
|
87
|
+
process.env.REDIS_MAX_RETRIES_PER_REQUEST,
|
|
88
|
+
1
|
|
89
|
+
);
|
|
90
|
+
global.__redis__ = new import_ioredis.default({
|
|
91
|
+
host,
|
|
92
|
+
port,
|
|
93
|
+
connectTimeout,
|
|
94
|
+
maxRetriesPerRequest,
|
|
95
|
+
enableOfflineQueue: false,
|
|
96
|
+
retryStrategy: (attempt) => Math.min(attempt * 200, 2e3)
|
|
97
|
+
});
|
|
98
|
+
global.__redis__.on("error", (error) => {
|
|
99
|
+
if (isRedisConnectivityError(error)) {
|
|
100
|
+
markRedisUnavailable(error);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
logger.log("error", "Redis client error: %s", String(error));
|
|
104
|
+
});
|
|
105
|
+
global.__redis__.on("ready", () => {
|
|
106
|
+
redisUnavailable = false;
|
|
107
|
+
if (redisConnectionWarningShown) {
|
|
108
|
+
redisConnectionWarningShown = false;
|
|
109
|
+
logger.log("info", "Redis connection restored");
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return global.__redis__;
|
|
114
|
+
};
|
|
115
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
116
|
+
var getRedisStatus = (redis) => String(redis.status ?? "ready");
|
|
117
|
+
var waitForRedisReady = async (redis) => {
|
|
118
|
+
if (getRedisStatus(redis) === "ready") {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
const readyTimeoutMs = toPositiveInt(
|
|
122
|
+
process.env.REDIS_READY_TIMEOUT_MS,
|
|
123
|
+
toPositiveInt(process.env.REDIS_CONNECT_TIMEOUT_MS, 3e3)
|
|
124
|
+
);
|
|
125
|
+
const startedAt = Date.now();
|
|
126
|
+
while (Date.now() - startedAt < readyTimeoutMs) {
|
|
127
|
+
if (getRedisStatus(redis) === "ready") {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
if (getRedisStatus(redis) === "end") {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
await sleep(50);
|
|
134
|
+
}
|
|
135
|
+
return getRedisStatus(redis) === "ready";
|
|
136
|
+
};
|
|
137
|
+
var getReadyRedis = async () => {
|
|
138
|
+
if (redisUnavailable) return null;
|
|
139
|
+
const redis = getRedis();
|
|
140
|
+
const ready = await waitForRedisReady(redis);
|
|
141
|
+
if (ready) {
|
|
142
|
+
return redis;
|
|
143
|
+
}
|
|
144
|
+
markRedisUnavailable(
|
|
145
|
+
new Error(`Redis is not ready (status=${getRedisStatus(redis)})`)
|
|
146
|
+
);
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
var toResultString = (result) => {
|
|
150
|
+
if (result == null) return null;
|
|
151
|
+
if (typeof result === "string") return result;
|
|
152
|
+
if (Buffer.isBuffer(result)) return result.toString("utf8");
|
|
153
|
+
return String(result);
|
|
154
|
+
};
|
|
155
|
+
var DEFAULT_OPTIONS = {
|
|
156
|
+
expire: TTL_1D
|
|
157
|
+
};
|
|
158
|
+
var parseJsonOrDeleteKey = async (redis, key, raw, fallback) => {
|
|
159
|
+
try {
|
|
160
|
+
return JSON.parse(raw);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
logger.log("error", "failed JSON.parse(%s): %s", key, String(e));
|
|
163
|
+
await redis.del(key);
|
|
164
|
+
return fallback;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
var getKeys = async (prefix) => {
|
|
168
|
+
if (redisUnavailable) return [];
|
|
169
|
+
const redis = await getReadyRedis();
|
|
170
|
+
if (!redis) return [];
|
|
171
|
+
const keys = [];
|
|
172
|
+
try {
|
|
173
|
+
let cursor = "0";
|
|
174
|
+
do {
|
|
175
|
+
const [nextCursor, batch] = await redis.scan(
|
|
176
|
+
cursor,
|
|
177
|
+
"MATCH",
|
|
178
|
+
`${prefix}*`,
|
|
179
|
+
"COUNT",
|
|
180
|
+
"200"
|
|
181
|
+
);
|
|
182
|
+
cursor = nextCursor;
|
|
183
|
+
for (const key of batch) {
|
|
184
|
+
if (key.startsWith(prefix)) {
|
|
185
|
+
keys.push(key);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} while (cursor !== "0");
|
|
189
|
+
} catch (e) {
|
|
190
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
191
|
+
markRedisUnavailable(e);
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
logger.log("warn", "failed SCAN for %s: %s", prefix, String(e));
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
return keys;
|
|
198
|
+
};
|
|
199
|
+
var getData = async (key, fallback = []) => {
|
|
200
|
+
if (redisUnavailable) return fallback;
|
|
201
|
+
const redis = await getReadyRedis();
|
|
202
|
+
if (!redis) return fallback;
|
|
203
|
+
try {
|
|
204
|
+
const rawJson = await redis.call("JSON.GET", key);
|
|
205
|
+
const raw = toResultString(rawJson);
|
|
206
|
+
if (raw == null) return fallback;
|
|
207
|
+
return parseJsonOrDeleteKey(redis, key, raw, fallback);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
210
|
+
markRedisUnavailable(e);
|
|
211
|
+
return fallback;
|
|
212
|
+
}
|
|
213
|
+
logger.log(
|
|
214
|
+
"error",
|
|
215
|
+
"failed JSON.GET %s: %s (fallback to GET)",
|
|
216
|
+
key,
|
|
217
|
+
String(e)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
const raw = await redis.get(key);
|
|
222
|
+
if (raw == null) return fallback;
|
|
223
|
+
return parseJsonOrDeleteKey(redis, key, raw, fallback);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
226
|
+
markRedisUnavailable(e);
|
|
227
|
+
return fallback;
|
|
228
|
+
}
|
|
229
|
+
logger.log("error", "failed GET %s: %s", key, String(e));
|
|
230
|
+
return fallback;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
var requireReadyRedis = async () => {
|
|
234
|
+
if (redisUnavailable) {
|
|
235
|
+
throw new Error("Redis is unavailable");
|
|
236
|
+
}
|
|
237
|
+
const redis = await getReadyRedis();
|
|
238
|
+
if (!redis) {
|
|
239
|
+
throw new Error("Redis is unavailable");
|
|
240
|
+
}
|
|
241
|
+
return redis;
|
|
242
|
+
};
|
|
243
|
+
var setDataStrict = async (key, data, options = {}) => {
|
|
244
|
+
const { expire } = { ...DEFAULT_OPTIONS, ...options };
|
|
245
|
+
const redis = await requireReadyRedis();
|
|
246
|
+
const value = toJson(data);
|
|
247
|
+
try {
|
|
248
|
+
await redis.call("JSON.SET", key, "$", value);
|
|
249
|
+
if (expire) {
|
|
250
|
+
await redis.expire(key, expire);
|
|
251
|
+
}
|
|
252
|
+
return;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
if (error instanceof Error && isRedisConnectivityError(error)) {
|
|
255
|
+
markRedisUnavailable(error);
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
logger.log(
|
|
259
|
+
"error",
|
|
260
|
+
"failed strict JSON.SET %s: %s (fallback to SET)",
|
|
261
|
+
key,
|
|
262
|
+
String(error)
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
if (expire) {
|
|
267
|
+
await redis.set(key, value, "EX", expire);
|
|
268
|
+
} else {
|
|
269
|
+
await redis.set(key, value);
|
|
270
|
+
}
|
|
271
|
+
} catch (error) {
|
|
272
|
+
if (error instanceof Error && isRedisConnectivityError(error)) {
|
|
273
|
+
markRedisUnavailable(error);
|
|
274
|
+
}
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var redisKeys = {
|
|
279
|
+
users: () => "users:index:",
|
|
280
|
+
user: (userName) => `users:index:${userName}`,
|
|
281
|
+
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
282
|
+
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
283
|
+
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
284
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
285
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
286
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
287
|
+
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
288
|
+
bots: (userName) => `users:${userName}:bots`,
|
|
289
|
+
botsPrefix: () => "users:",
|
|
290
|
+
bot: (userName, botId) => `users:${userName}:bots:${botId}`,
|
|
291
|
+
backtestConfig: (userName, config) => `users:${userName}:backtests:configs:${config}`,
|
|
292
|
+
strategies: (userName) => `users:${userName}:strategies`,
|
|
293
|
+
strategyConfig: (userName, strategyName, configId = "config") => `users:${userName}:strategies:${strategyName}:${configId}`,
|
|
294
|
+
runtimeStrategyControlEvents: (userName) => `users:${userName}:runtime:strategy-control-events:`,
|
|
295
|
+
runtimeStrategyControlEvent: (userName, eventId) => `users:${userName}:runtime:strategy-control-events:${eventId}`,
|
|
296
|
+
strategyResults: (userName, strategyName) => `users:${userName}:strategies:${strategyName}:results`,
|
|
297
|
+
strategyCharts: (userName, mode) => `users:${userName}:strategies:charts:${mode}`,
|
|
298
|
+
strategyChartCards: (userName, mode) => `users:${userName}:strategies:charts:${mode}:cards:`,
|
|
299
|
+
strategyChartCard: (userName, mode, cardId) => `users:${userName}:strategies:charts:${mode}:cards:${cardId}`,
|
|
300
|
+
tests: (userName, strategyName) => strategyName ? `users:${userName}:tests:${strategyName}` : `users:${userName}:tests:`,
|
|
301
|
+
testOrders: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:orders`,
|
|
302
|
+
testConfig: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:config`,
|
|
303
|
+
testStat: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:stat`,
|
|
304
|
+
testSummaries: (userName) => `users:${userName}:tests:index:summary`,
|
|
305
|
+
cacheChunk: (userName, chunkId) => `users:${userName}:cache:tests:chunks:${chunkId}`,
|
|
306
|
+
cacheOrders: (userName, orderLogId) => `users:${userName}:cache:tests:orders:${orderLogId}`,
|
|
307
|
+
cachePositions: (userName, orderLogId) => `users:${userName}:cache:tests:positions:${orderLogId}`,
|
|
308
|
+
tickerUniverse: (userName, connectorName, universe, accountId) => universe || accountId ? `users:${userName}:cache:tickers:${connectorName}:${universe ?? "crypto"}:${accountId ?? "default"}` : `users:${userName}:cache:tickers:${connectorName}`,
|
|
309
|
+
signal: (symbol, signalId) => `signals:${symbol}:${signalId}`,
|
|
310
|
+
signalsBySymbol: (symbol) => `signals:${symbol}:`,
|
|
311
|
+
storeSignal: (symbol, signalId) => `store:signals:${symbol}:${signalId}`,
|
|
312
|
+
runtimeSignals: (userName) => `users:${userName}:runtime:signals:`,
|
|
313
|
+
runtimeSignal: (userName, signalId) => `users:${userName}:runtime:signals:${signalId}`,
|
|
314
|
+
runtimeSignalBuckets: (userName) => `users:${userName}:runtime:signals:days:`,
|
|
315
|
+
runtimeSignalBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signals:days:${dayKey}:${strategyName}`,
|
|
316
|
+
runtimeSignalEvaluations: (userName) => `users:${userName}:runtime:signal-evaluations:`,
|
|
317
|
+
runtimeSignalEvaluation: (userName, evaluationId) => `users:${userName}:runtime:signal-evaluations:${evaluationId}`,
|
|
318
|
+
runtimeSignalEvaluationBuckets: (userName) => `users:${userName}:runtime:signal-evaluations:days:`,
|
|
319
|
+
runtimeSignalEvaluationBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluations:days:${dayKey}:${strategyName}`,
|
|
320
|
+
runtimeSignalEvaluationStatsBuckets: (userName) => `users:${userName}:runtime:signal-evaluation-stats:days:`,
|
|
321
|
+
runtimeSignalEvaluationStatsBucket: (userName, dayKey, strategyName, deploymentId) => `users:${userName}:runtime:signal-evaluation-stats:days:${dayKey}:${deploymentId ? `${deploymentId}:` : ""}${strategyName}`,
|
|
322
|
+
runtimeLineageScopeBucket: (userName, dayKey) => `users:${userName}:runtime:lineage-scopes:days:${dayKey}`,
|
|
323
|
+
runtimeTrades: (userName) => `users:${userName}:runtime:trade-records:`,
|
|
324
|
+
runtimeTrade: (userName, orderId) => `users:${userName}:runtime:trade-records:${orderId}`,
|
|
325
|
+
runtimeTradeBuckets: (userName) => `users:${userName}:runtime:trade-records:days:`,
|
|
326
|
+
runtimeTradeBucket: (userName, dayKey) => `users:${userName}:runtime:trade-records:days:${dayKey}`,
|
|
327
|
+
runtimeClosedTradeBuckets: (userName) => `users:${userName}:runtime:closed-trade-records:days:`,
|
|
328
|
+
runtimeClosedTradeBucket: (userName, dayKey) => `users:${userName}:runtime:closed-trade-records:days:${dayKey}`,
|
|
329
|
+
runtimeActiveTrades: (userName) => `users:${userName}:runtime:active-trades:`,
|
|
330
|
+
runtimeActiveTrade: (userName, symbol, scopeId) => scopeId ? `users:${userName}:runtime:active-trades:${scopeId}:${symbol}` : `users:${userName}:runtime:active-trades:${symbol}`,
|
|
331
|
+
aiChatHistory: (userName, symbolKey) => `users:${userName}:ai:chats:${symbolKey}`,
|
|
332
|
+
analysis: (symbol, signalId) => `analysis:${symbol}:${signalId}`,
|
|
333
|
+
screenshotSessionToken: (token) => `auth:screenshot:${token}`,
|
|
334
|
+
backtestResults: (userName, config, timestamp) => `users:${userName}:backtests:results:${config}:${timestamp}`,
|
|
335
|
+
backtestJobs: (userName) => `users:${userName}:backtests:jobs:`,
|
|
336
|
+
backtestJob: (userName, jobId) => `users:${userName}:backtests:jobs:${jobId}`,
|
|
337
|
+
backtestRuns: (userName) => `users:${userName}:backtests:runs:`,
|
|
338
|
+
backtestRun: (userName, runId) => `users:${userName}:backtests:runs:${runId}`,
|
|
339
|
+
backtestRunResults: (userName, runId) => `users:${userName}:backtests:runs:${runId}:results`,
|
|
340
|
+
backtestLatestRun: (userName, config) => `users:${userName}:backtests:latest:${config}`,
|
|
341
|
+
researchRuns: (userName) => `users:${userName}:research:runs:`,
|
|
342
|
+
researchRun: (userName, runId) => `users:${userName}:research:runs:${runId}`,
|
|
343
|
+
researchLatestRun: (userName, strategyName) => `users:${userName}:research:latest:${strategyName}`,
|
|
344
|
+
mlSignalsByStrategy: (strategyName) => `ml:${strategyName}:signals:`,
|
|
345
|
+
mlSignals: () => "ml:",
|
|
346
|
+
mlSignal: (strategyName, signalId) => `ml:${strategyName}:signals:${signalId}`,
|
|
347
|
+
mlResultsByStrategy: (strategyName) => `ml:${strategyName}:results:`,
|
|
348
|
+
mlResults: () => "ml:",
|
|
349
|
+
mlResult: (strategyName, signalId) => `ml:${strategyName}:results:${signalId}`
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// src/runtimeDeploymentEvents.ts
|
|
353
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
354
|
+
var normalizeDeploymentId = (value) => {
|
|
355
|
+
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
356
|
+
if (!normalized) throw new Error("Deployment id is required");
|
|
357
|
+
return normalized;
|
|
358
|
+
};
|
|
359
|
+
var isRuntimeDeploymentCompositionEvent = (value) => {
|
|
360
|
+
if (!isRecord(value) || Object.keys(value).some(
|
|
361
|
+
(key) => ![
|
|
362
|
+
"schema",
|
|
363
|
+
"eventId",
|
|
364
|
+
"deploymentId",
|
|
365
|
+
"deploymentCompositionId",
|
|
366
|
+
"observedAt",
|
|
367
|
+
"strategies"
|
|
368
|
+
].includes(key)
|
|
369
|
+
) || value.schema !== import_types.RUNTIME_DEPLOYMENT_COMPOSITION_EVENT_SCHEMA || typeof value.eventId !== "string" || !value.eventId.trim() || typeof value.deploymentId !== "string" || !value.deploymentId.trim() || typeof value.deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(value.deploymentCompositionId) || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || value.observedAt < 0 || !Array.isArray(value.strategies)) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
const strategyNames = /* @__PURE__ */ new Set();
|
|
373
|
+
for (const strategy of value.strategies) {
|
|
374
|
+
if (!isRecord(strategy) || Object.keys(strategy).some(
|
|
375
|
+
(key) => !["strategyName", "strategyRevision"].includes(key)
|
|
376
|
+
) || typeof strategy.strategyName !== "string" || !strategy.strategyName.trim() || strategyNames.has(strategy.strategyName) || typeof strategy.strategyRevision !== "string" || !/^sr1:[a-f0-9]{16}$/.test(strategy.strategyRevision)) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
strategyNames.add(strategy.strategyName);
|
|
380
|
+
}
|
|
381
|
+
return true;
|
|
382
|
+
};
|
|
383
|
+
var observeRuntimeDeploymentComposition = async ({
|
|
384
|
+
userName,
|
|
385
|
+
deployment,
|
|
386
|
+
observedAt = Date.now()
|
|
387
|
+
}) => {
|
|
388
|
+
if (!Number.isFinite(observedAt) || observedAt < 0) {
|
|
389
|
+
throw new Error("Invalid deployment composition observation time");
|
|
390
|
+
}
|
|
391
|
+
const deploymentId = normalizeDeploymentId(deployment.id);
|
|
392
|
+
const stateKey = redisKeys.runtimeDeploymentCompositionState(
|
|
393
|
+
userName,
|
|
394
|
+
deploymentId
|
|
395
|
+
);
|
|
396
|
+
const current = await getData(stateKey, null);
|
|
397
|
+
if (isRuntimeDeploymentCompositionEvent(current) && current.deploymentId === deploymentId && current.deploymentCompositionId === deployment.deploymentCompositionId) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
const event = {
|
|
401
|
+
schema: import_types.RUNTIME_DEPLOYMENT_COMPOSITION_EVENT_SCHEMA,
|
|
402
|
+
eventId: `${observedAt}-${(0, import_node_crypto.randomUUID)()}`,
|
|
403
|
+
deploymentId,
|
|
404
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
405
|
+
observedAt,
|
|
406
|
+
strategies: deployment.strategies.map(({ strategyName, strategyRevision }) => ({
|
|
407
|
+
strategyName,
|
|
408
|
+
strategyRevision
|
|
409
|
+
})).sort(
|
|
410
|
+
(left, right) => left.strategyName.localeCompare(right.strategyName)
|
|
411
|
+
)
|
|
412
|
+
};
|
|
413
|
+
if (!isRuntimeDeploymentCompositionEvent(event)) {
|
|
414
|
+
throw new Error("Invalid runtime deployment composition event");
|
|
415
|
+
}
|
|
416
|
+
await setDataStrict(
|
|
417
|
+
redisKeys.runtimeDeploymentCompositionEvent(
|
|
418
|
+
userName,
|
|
419
|
+
deploymentId,
|
|
420
|
+
event.eventId
|
|
421
|
+
),
|
|
422
|
+
event,
|
|
423
|
+
{ expire: 0 }
|
|
424
|
+
);
|
|
425
|
+
await setDataStrict(stateKey, event, { expire: 0 });
|
|
426
|
+
return event;
|
|
427
|
+
};
|
|
428
|
+
var loadRuntimeDeploymentCompositionEvents = async (userName, deploymentId) => {
|
|
429
|
+
const normalizedDeploymentId = normalizeDeploymentId(deploymentId);
|
|
430
|
+
const keys = await getKeys(
|
|
431
|
+
redisKeys.runtimeDeploymentCompositionEvents(
|
|
432
|
+
userName,
|
|
433
|
+
normalizedDeploymentId
|
|
434
|
+
)
|
|
435
|
+
);
|
|
436
|
+
const values = await Promise.all(keys.map((key) => getData(key, null)));
|
|
437
|
+
return values.filter(isRuntimeDeploymentCompositionEvent).filter((event) => event.deploymentId === normalizedDeploymentId).sort(
|
|
438
|
+
(left, right) => left.observedAt - right.observedAt || left.eventId.localeCompare(right.eventId)
|
|
439
|
+
);
|
|
440
|
+
};
|
|
441
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
442
|
+
0 && (module.exports = {
|
|
443
|
+
isRuntimeDeploymentCompositionEvent,
|
|
444
|
+
loadRuntimeDeploymentCompositionEvents,
|
|
445
|
+
observeRuntimeDeploymentComposition
|
|
446
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getData,
|
|
3
|
+
getKeys,
|
|
4
|
+
redisKeys,
|
|
5
|
+
setDataStrict
|
|
6
|
+
} from "./chunk-GTZOMAFK.mjs";
|
|
7
|
+
|
|
8
|
+
// src/runtimeDeploymentEvents.ts
|
|
9
|
+
import { randomUUID } from "crypto";
|
|
10
|
+
import {
|
|
11
|
+
RUNTIME_DEPLOYMENT_COMPOSITION_EVENT_SCHEMA
|
|
12
|
+
} from "@tradejs/types";
|
|
13
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
14
|
+
var normalizeDeploymentId = (value) => {
|
|
15
|
+
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
16
|
+
if (!normalized) throw new Error("Deployment id is required");
|
|
17
|
+
return normalized;
|
|
18
|
+
};
|
|
19
|
+
var isRuntimeDeploymentCompositionEvent = (value) => {
|
|
20
|
+
if (!isRecord(value) || Object.keys(value).some(
|
|
21
|
+
(key) => ![
|
|
22
|
+
"schema",
|
|
23
|
+
"eventId",
|
|
24
|
+
"deploymentId",
|
|
25
|
+
"deploymentCompositionId",
|
|
26
|
+
"observedAt",
|
|
27
|
+
"strategies"
|
|
28
|
+
].includes(key)
|
|
29
|
+
) || value.schema !== RUNTIME_DEPLOYMENT_COMPOSITION_EVENT_SCHEMA || typeof value.eventId !== "string" || !value.eventId.trim() || typeof value.deploymentId !== "string" || !value.deploymentId.trim() || typeof value.deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(value.deploymentCompositionId) || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || value.observedAt < 0 || !Array.isArray(value.strategies)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const strategyNames = /* @__PURE__ */ new Set();
|
|
33
|
+
for (const strategy of value.strategies) {
|
|
34
|
+
if (!isRecord(strategy) || Object.keys(strategy).some(
|
|
35
|
+
(key) => !["strategyName", "strategyRevision"].includes(key)
|
|
36
|
+
) || typeof strategy.strategyName !== "string" || !strategy.strategyName.trim() || strategyNames.has(strategy.strategyName) || typeof strategy.strategyRevision !== "string" || !/^sr1:[a-f0-9]{16}$/.test(strategy.strategyRevision)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
strategyNames.add(strategy.strategyName);
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
};
|
|
43
|
+
var observeRuntimeDeploymentComposition = async ({
|
|
44
|
+
userName,
|
|
45
|
+
deployment,
|
|
46
|
+
observedAt = Date.now()
|
|
47
|
+
}) => {
|
|
48
|
+
if (!Number.isFinite(observedAt) || observedAt < 0) {
|
|
49
|
+
throw new Error("Invalid deployment composition observation time");
|
|
50
|
+
}
|
|
51
|
+
const deploymentId = normalizeDeploymentId(deployment.id);
|
|
52
|
+
const stateKey = redisKeys.runtimeDeploymentCompositionState(
|
|
53
|
+
userName,
|
|
54
|
+
deploymentId
|
|
55
|
+
);
|
|
56
|
+
const current = await getData(stateKey, null);
|
|
57
|
+
if (isRuntimeDeploymentCompositionEvent(current) && current.deploymentId === deploymentId && current.deploymentCompositionId === deployment.deploymentCompositionId) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const event = {
|
|
61
|
+
schema: RUNTIME_DEPLOYMENT_COMPOSITION_EVENT_SCHEMA,
|
|
62
|
+
eventId: `${observedAt}-${randomUUID()}`,
|
|
63
|
+
deploymentId,
|
|
64
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
65
|
+
observedAt,
|
|
66
|
+
strategies: deployment.strategies.map(({ strategyName, strategyRevision }) => ({
|
|
67
|
+
strategyName,
|
|
68
|
+
strategyRevision
|
|
69
|
+
})).sort(
|
|
70
|
+
(left, right) => left.strategyName.localeCompare(right.strategyName)
|
|
71
|
+
)
|
|
72
|
+
};
|
|
73
|
+
if (!isRuntimeDeploymentCompositionEvent(event)) {
|
|
74
|
+
throw new Error("Invalid runtime deployment composition event");
|
|
75
|
+
}
|
|
76
|
+
await setDataStrict(
|
|
77
|
+
redisKeys.runtimeDeploymentCompositionEvent(
|
|
78
|
+
userName,
|
|
79
|
+
deploymentId,
|
|
80
|
+
event.eventId
|
|
81
|
+
),
|
|
82
|
+
event,
|
|
83
|
+
{ expire: 0 }
|
|
84
|
+
);
|
|
85
|
+
await setDataStrict(stateKey, event, { expire: 0 });
|
|
86
|
+
return event;
|
|
87
|
+
};
|
|
88
|
+
var loadRuntimeDeploymentCompositionEvents = async (userName, deploymentId) => {
|
|
89
|
+
const normalizedDeploymentId = normalizeDeploymentId(deploymentId);
|
|
90
|
+
const keys = await getKeys(
|
|
91
|
+
redisKeys.runtimeDeploymentCompositionEvents(
|
|
92
|
+
userName,
|
|
93
|
+
normalizedDeploymentId
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
const values = await Promise.all(keys.map((key) => getData(key, null)));
|
|
97
|
+
return values.filter(isRuntimeDeploymentCompositionEvent).filter((event) => event.deploymentId === normalizedDeploymentId).sort(
|
|
98
|
+
(left, right) => left.observedAt - right.observedAt || left.eventId.localeCompare(right.eventId)
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
export {
|
|
102
|
+
isRuntimeDeploymentCompositionEvent,
|
|
103
|
+
loadRuntimeDeploymentCompositionEvents,
|
|
104
|
+
observeRuntimeDeploymentComposition
|
|
105
|
+
};
|
|
@@ -238,6 +238,9 @@ var redisKeys = {
|
|
|
238
238
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
239
239
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
240
240
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
241
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
242
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
243
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
241
244
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
242
245
|
bots: (userName) => `users:${userName}:bots`,
|
|
243
246
|
botsPrefix: () => "users:",
|
|
@@ -276,6 +276,9 @@ var redisKeys = {
|
|
|
276
276
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
277
277
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
278
278
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
279
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
280
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
281
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
279
282
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
280
283
|
bots: (userName) => `users:${userName}:bots`,
|
|
281
284
|
botsPrefix: () => "users:",
|
package/dist/tradingAccounts.js
CHANGED
|
@@ -306,6 +306,9 @@ var redisKeys = {
|
|
|
306
306
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
307
307
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
308
308
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
309
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
310
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
311
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
309
312
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
310
313
|
bots: (userName) => `users:${userName}:bots`,
|
|
311
314
|
botsPrefix: () => "users:",
|
package/dist/tradingAccounts.mjs
CHANGED
package/dist/userSettings.js
CHANGED
|
@@ -239,6 +239,9 @@ var redisKeys = {
|
|
|
239
239
|
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
240
240
|
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
241
241
|
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
242
|
+
runtimeDeploymentCompositionState: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-state`,
|
|
243
|
+
runtimeDeploymentCompositionEvents: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:`,
|
|
244
|
+
runtimeDeploymentCompositionEvent: (userName, deploymentId, eventId) => `users:${userName}:runtime:deployments:${deploymentId}:composition-events:${eventId}`,
|
|
242
245
|
runtimeControls: (userName) => `users:${userName}:runtime:controls`,
|
|
243
246
|
bots: (userName) => `users:${userName}:bots`,
|
|
244
247
|
botsPrefix: () => "users:",
|
package/dist/userSettings.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/infra",
|
|
3
|
-
"version": "3.1.28-beta.
|
|
3
|
+
"version": "3.1.28-beta.253",
|
|
4
4
|
"description": "MIT-licensed server infrastructure adapters for TradeJS: Redis, Timescale, ML, logging, and IO.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -81,6 +81,11 @@
|
|
|
81
81
|
"import": "./dist/runtimeControls.mjs",
|
|
82
82
|
"require": "./dist/runtimeControls.js"
|
|
83
83
|
},
|
|
84
|
+
"./runtimeDeploymentEvents": {
|
|
85
|
+
"types": "./dist/runtimeDeploymentEvents.d.ts",
|
|
86
|
+
"import": "./dist/runtimeDeploymentEvents.mjs",
|
|
87
|
+
"require": "./dist/runtimeDeploymentEvents.js"
|
|
88
|
+
},
|
|
84
89
|
"./strategyReleaseEvidence": {
|
|
85
90
|
"types": "./dist/strategyReleaseEvidence.d.ts",
|
|
86
91
|
"import": "./dist/strategyReleaseEvidence.mjs",
|
|
@@ -130,7 +135,7 @@
|
|
|
130
135
|
"dependencies": {
|
|
131
136
|
"@grpc/grpc-js": "^1.14.4",
|
|
132
137
|
"@grpc/proto-loader": "^0.8.1",
|
|
133
|
-
"@tradejs/types": "^3.1.28-beta.
|
|
138
|
+
"@tradejs/types": "^3.1.28-beta.253",
|
|
134
139
|
"chalk": "4.1.2",
|
|
135
140
|
"date-fns": "^3.6.0",
|
|
136
141
|
"ioredis": "5.11.1",
|