backtest-kit 3.4.2 → 3.5.1
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/build/index.cjs +250 -32
- package/build/index.mjs +250 -32
- package/package.json +1 -1
- package/types.d.ts +2127 -2114
package/build/index.cjs
CHANGED
|
@@ -733,7 +733,7 @@ async function writeFileAtomic(file, data, options = {}) {
|
|
|
733
733
|
}
|
|
734
734
|
}
|
|
735
735
|
|
|
736
|
-
var _a$
|
|
736
|
+
var _a$4;
|
|
737
737
|
const BASE_WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
738
738
|
// Calculate step in milliseconds for candle close time validation
|
|
739
739
|
const INTERVAL_MINUTES$8 = {
|
|
@@ -856,7 +856,7 @@ class PersistBase {
|
|
|
856
856
|
constructor(entityName, baseDir = path.join(process.cwd(), "logs/data")) {
|
|
857
857
|
this.entityName = entityName;
|
|
858
858
|
this.baseDir = baseDir;
|
|
859
|
-
this[_a$
|
|
859
|
+
this[_a$4] = functoolsKit.singleshot(async () => await BASE_WAIT_FOR_INIT_FN(this));
|
|
860
860
|
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_CTOR, {
|
|
861
861
|
entityName: this.entityName,
|
|
862
862
|
baseDir,
|
|
@@ -959,7 +959,7 @@ class PersistBase {
|
|
|
959
959
|
}
|
|
960
960
|
}
|
|
961
961
|
}
|
|
962
|
-
_a$
|
|
962
|
+
_a$4 = BASE_WAIT_FOR_INIT_SYMBOL;
|
|
963
963
|
// @ts-ignore
|
|
964
964
|
PersistBase = functoolsKit.makeExtendable(PersistBase);
|
|
965
965
|
/**
|
|
@@ -2066,7 +2066,7 @@ class PersistLogUtils {
|
|
|
2066
2066
|
*/
|
|
2067
2067
|
const PersistLogAdapter = new PersistLogUtils();
|
|
2068
2068
|
|
|
2069
|
-
var _a$
|
|
2069
|
+
var _a$3, _b$3;
|
|
2070
2070
|
const BUSY_DELAY = 100;
|
|
2071
2071
|
const SET_BUSY_SYMBOL = Symbol("setBusy");
|
|
2072
2072
|
const GET_BUSY_SYMBOL = Symbol("getBusy");
|
|
@@ -2081,8 +2081,8 @@ const ACQUIRE_LOCK_FN = async (self) => {
|
|
|
2081
2081
|
class Lock {
|
|
2082
2082
|
constructor() {
|
|
2083
2083
|
this._isBusy = 0;
|
|
2084
|
-
this[_a$
|
|
2085
|
-
this[_b$
|
|
2084
|
+
this[_a$3] = functoolsKit.queued(ACQUIRE_LOCK_FN);
|
|
2085
|
+
this[_b$3] = () => this[SET_BUSY_SYMBOL](false);
|
|
2086
2086
|
this.acquireLock = async () => {
|
|
2087
2087
|
await this[ACQUIRE_LOCK_SYMBOL](this);
|
|
2088
2088
|
};
|
|
@@ -2100,7 +2100,7 @@ class Lock {
|
|
|
2100
2100
|
return !!this._isBusy;
|
|
2101
2101
|
}
|
|
2102
2102
|
}
|
|
2103
|
-
_a$
|
|
2103
|
+
_a$3 = ACQUIRE_LOCK_SYMBOL, _b$3 = RELEASE_LOCK_SYMBOL;
|
|
2104
2104
|
|
|
2105
2105
|
const METHOD_NAME_ACQUIRE_LOCK = "CandleUtils.acquireLock";
|
|
2106
2106
|
const METHOD_NAME_RELEASE_LOCK = "CandleUtils.releaseLock";
|
|
@@ -16096,7 +16096,7 @@ const COLUMN_CONFIG = {
|
|
|
16096
16096
|
*/
|
|
16097
16097
|
const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
|
|
16098
16098
|
|
|
16099
|
-
var _a$
|
|
16099
|
+
var _a$2, _b$2;
|
|
16100
16100
|
const MARKDOWN_METHOD_NAME_ENABLE = "MarkdownUtils.enable";
|
|
16101
16101
|
const MARKDOWN_METHOD_NAME_DISABLE = "MarkdownUtils.disable";
|
|
16102
16102
|
const MARKDOWN_METHOD_NAME_USE_ADAPTER = "MarkdownAdapter.useMarkdownAdapter";
|
|
@@ -16106,8 +16106,8 @@ const MARKDOWN_METHOD_NAME_WRITE_DATA = "MarkdownAdapter.writeData";
|
|
|
16106
16106
|
const MARKDOWN_METHOD_NAME_USE_MD = "MarkdownAdapter.useMd";
|
|
16107
16107
|
const MARKDOWN_METHOD_NAME_USE_JSONL = "MarkdownAdapter.useJsonl";
|
|
16108
16108
|
const MARKDOWN_METHOD_NAME_USE_DUMMY = "MarkdownAdapter.useDummy";
|
|
16109
|
-
const WAIT_FOR_INIT_SYMBOL$
|
|
16110
|
-
const WRITE_SAFE_SYMBOL$
|
|
16109
|
+
const WAIT_FOR_INIT_SYMBOL$2 = Symbol("wait-for-init");
|
|
16110
|
+
const WRITE_SAFE_SYMBOL$2 = Symbol("write-safe");
|
|
16111
16111
|
/**
|
|
16112
16112
|
* Default configuration that enables all markdown services.
|
|
16113
16113
|
* Used when no specific configuration is provided to `enable()`.
|
|
@@ -16157,7 +16157,7 @@ class MarkdownFileBase {
|
|
|
16157
16157
|
* Protected by singleshot to ensure one-time execution.
|
|
16158
16158
|
* Sets up error handler that emits to exitEmitter.
|
|
16159
16159
|
*/
|
|
16160
|
-
this[_a$
|
|
16160
|
+
this[_a$2] = functoolsKit.singleshot(async () => {
|
|
16161
16161
|
await fs__namespace.mkdir(this._baseDir, { recursive: true });
|
|
16162
16162
|
this._stream = fs$1.createWriteStream(this._filePath, { flags: "a" });
|
|
16163
16163
|
this._stream.on("error", (err) => {
|
|
@@ -16169,7 +16169,7 @@ class MarkdownFileBase {
|
|
|
16169
16169
|
* Waits for drain event if write buffer is full.
|
|
16170
16170
|
* Times out after 15 seconds and returns TIMEOUT_SYMBOL.
|
|
16171
16171
|
*/
|
|
16172
|
-
this[_b$
|
|
16172
|
+
this[_b$2] = functoolsKit.timeout(async (line) => {
|
|
16173
16173
|
if (!this._stream.write(line)) {
|
|
16174
16174
|
await new Promise((resolve) => {
|
|
16175
16175
|
this._stream.once("drain", resolve);
|
|
@@ -16185,7 +16185,7 @@ class MarkdownFileBase {
|
|
|
16185
16185
|
* @returns Promise that resolves when initialization is complete
|
|
16186
16186
|
*/
|
|
16187
16187
|
async waitForInit() {
|
|
16188
|
-
await this[WAIT_FOR_INIT_SYMBOL$
|
|
16188
|
+
await this[WAIT_FOR_INIT_SYMBOL$2]();
|
|
16189
16189
|
}
|
|
16190
16190
|
/**
|
|
16191
16191
|
* Writes markdown content to JSONL file with metadata.
|
|
@@ -16231,13 +16231,13 @@ class MarkdownFileBase {
|
|
|
16231
16231
|
...searchFlags,
|
|
16232
16232
|
timestamp: Date.now(),
|
|
16233
16233
|
}) + "\n";
|
|
16234
|
-
const status = await this[WRITE_SAFE_SYMBOL$
|
|
16234
|
+
const status = await this[WRITE_SAFE_SYMBOL$2](line);
|
|
16235
16235
|
if (status === functoolsKit.TIMEOUT_SYMBOL) {
|
|
16236
16236
|
throw new Error(`Timeout writing to markdown ${this.markdownName}`);
|
|
16237
16237
|
}
|
|
16238
16238
|
}
|
|
16239
16239
|
}
|
|
16240
|
-
_a$
|
|
16240
|
+
_a$2 = WAIT_FOR_INIT_SYMBOL$2, _b$2 = WRITE_SAFE_SYMBOL$2;
|
|
16241
16241
|
//@ts-ignore
|
|
16242
16242
|
MarkdownFileBase = functoolsKit.makeExtendable(MarkdownFileBase);
|
|
16243
16243
|
/**
|
|
@@ -23256,7 +23256,7 @@ class ColumnValidationService {
|
|
|
23256
23256
|
}
|
|
23257
23257
|
}
|
|
23258
23258
|
|
|
23259
|
-
var _a, _b;
|
|
23259
|
+
var _a$1, _b$1;
|
|
23260
23260
|
const REPORT_BASE_METHOD_NAME_CTOR = "ReportBase.CTOR";
|
|
23261
23261
|
const REPORT_BASE_METHOD_NAME_WAIT_FOR_INIT = "ReportBase.waitForInit";
|
|
23262
23262
|
const REPORT_BASE_METHOD_NAME_WRITE = "ReportBase.write";
|
|
@@ -23266,8 +23266,8 @@ const REPORT_UTILS_METHOD_NAME_ENABLE = "ReportUtils.enable";
|
|
|
23266
23266
|
const REPORT_UTILS_METHOD_NAME_DISABLE = "ReportUtils.disable";
|
|
23267
23267
|
const REPORT_UTILS_METHOD_NAME_USE_DUMMY = "ReportUtils.useDummy";
|
|
23268
23268
|
const REPORT_UTILS_METHOD_NAME_USE_JSONL = "ReportUtils.useJsonl";
|
|
23269
|
-
const WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
23270
|
-
const WRITE_SAFE_SYMBOL = Symbol("write-safe");
|
|
23269
|
+
const WAIT_FOR_INIT_SYMBOL$1 = Symbol("wait-for-init");
|
|
23270
|
+
const WRITE_SAFE_SYMBOL$1 = Symbol("write-safe");
|
|
23271
23271
|
/**
|
|
23272
23272
|
* JSONL-based report adapter with append-only writes.
|
|
23273
23273
|
*
|
|
@@ -23301,7 +23301,7 @@ class ReportBase {
|
|
|
23301
23301
|
* Protected by singleshot to ensure one-time execution.
|
|
23302
23302
|
* Sets up error handler that emits to exitEmitter.
|
|
23303
23303
|
*/
|
|
23304
|
-
this[_a] = functoolsKit.singleshot(async () => {
|
|
23304
|
+
this[_a$1] = functoolsKit.singleshot(async () => {
|
|
23305
23305
|
await fs__namespace.mkdir(this.baseDir, { recursive: true });
|
|
23306
23306
|
this._stream = fs$1.createWriteStream(this._filePath, { flags: "a" });
|
|
23307
23307
|
this._stream.on("error", (err) => {
|
|
@@ -23313,7 +23313,7 @@ class ReportBase {
|
|
|
23313
23313
|
* Waits for drain event if write buffer is full.
|
|
23314
23314
|
* Times out after 15 seconds and returns TIMEOUT_SYMBOL.
|
|
23315
23315
|
*/
|
|
23316
|
-
this[_b] = functoolsKit.timeout(async (line) => {
|
|
23316
|
+
this[_b$1] = functoolsKit.timeout(async (line) => {
|
|
23317
23317
|
if (!this._stream.write(line)) {
|
|
23318
23318
|
await new Promise((resolve) => {
|
|
23319
23319
|
this._stream.once("drain", resolve);
|
|
@@ -23338,7 +23338,7 @@ class ReportBase {
|
|
|
23338
23338
|
reportName: this.reportName,
|
|
23339
23339
|
initial,
|
|
23340
23340
|
});
|
|
23341
|
-
await this[WAIT_FOR_INIT_SYMBOL]();
|
|
23341
|
+
await this[WAIT_FOR_INIT_SYMBOL$1]();
|
|
23342
23342
|
}
|
|
23343
23343
|
/**
|
|
23344
23344
|
* Writes event data to JSONL file with metadata.
|
|
@@ -23385,13 +23385,13 @@ class ReportBase {
|
|
|
23385
23385
|
...searchFlags,
|
|
23386
23386
|
timestamp: Date.now(),
|
|
23387
23387
|
}) + "\n";
|
|
23388
|
-
const status = await this[WRITE_SAFE_SYMBOL](line);
|
|
23388
|
+
const status = await this[WRITE_SAFE_SYMBOL$1](line);
|
|
23389
23389
|
if (status === functoolsKit.TIMEOUT_SYMBOL) {
|
|
23390
23390
|
throw new Error(`Timeout writing to report ${this.reportName}`);
|
|
23391
23391
|
}
|
|
23392
23392
|
}
|
|
23393
23393
|
}
|
|
23394
|
-
_a = WAIT_FOR_INIT_SYMBOL, _b = WRITE_SAFE_SYMBOL;
|
|
23394
|
+
_a$1 = WAIT_FOR_INIT_SYMBOL$1, _b$1 = WRITE_SAFE_SYMBOL$1;
|
|
23395
23395
|
// @ts-ignore
|
|
23396
23396
|
ReportBase = functoolsKit.makeExtendable(ReportBase);
|
|
23397
23397
|
/**
|
|
@@ -31223,6 +31223,7 @@ async function dumpMessages(resultId, history, result, outputDir = "./dump/strat
|
|
|
31223
31223
|
}
|
|
31224
31224
|
}
|
|
31225
31225
|
|
|
31226
|
+
var _a, _b;
|
|
31226
31227
|
const LOG_PERSIST_METHOD_NAME_WAIT_FOR_INIT = "LogPersistUtils.waitForInit";
|
|
31227
31228
|
const LOG_PERSIST_METHOD_NAME_LOG = "LogPersistUtils.log";
|
|
31228
31229
|
const LOG_PERSIST_METHOD_NAME_DEBUG = "LogPersistUtils.debug";
|
|
@@ -31238,17 +31239,47 @@ const LOG_ADAPTER_METHOD_NAME_USE_LOGGER = "LogAdapter.useLogger";
|
|
|
31238
31239
|
const LOG_ADAPTER_METHOD_NAME_USE_PERSIST = "LogAdapter.usePersist";
|
|
31239
31240
|
const LOG_ADAPTER_METHOD_NAME_USE_MEMORY = "LogAdapter.useMemory";
|
|
31240
31241
|
const LOG_ADAPTER_METHOD_NAME_USE_DUMMY = "LogAdapter.useDummy";
|
|
31242
|
+
const LOG_ADAPTER_METHOD_NAME_USE_JSONL = "LogAdapter.useJsonl";
|
|
31243
|
+
const LOG_JSONL_METHOD_NAME_LOG = "LogJsonlUtils.log";
|
|
31244
|
+
const LOG_JSONL_METHOD_NAME_DEBUG = "LogJsonlUtils.debug";
|
|
31245
|
+
const LOG_JSONL_METHOD_NAME_INFO = "LogJsonlUtils.info";
|
|
31246
|
+
const LOG_JSONL_METHOD_NAME_WARN = "LogJsonlUtils.warn";
|
|
31247
|
+
const LOG_JSONL_METHOD_NAME_GET_LIST = "LogJsonlUtils.getList";
|
|
31248
|
+
const WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
31249
|
+
const WRITE_SAFE_SYMBOL = Symbol("write-safe");
|
|
31241
31250
|
/**
|
|
31242
31251
|
* Backtest execution time retrieval function.
|
|
31243
31252
|
* Returns the 'when' timestamp from the execution context if available, otherwise returns the current time.
|
|
31244
31253
|
* This allows log entries to be timestamped according to the backtest timeline rather than real-world time, improving log relevance and user experience during backtest analysis.
|
|
31245
31254
|
*/
|
|
31246
|
-
const GET_DATE_FN =
|
|
31255
|
+
const GET_DATE_FN = () => {
|
|
31247
31256
|
if (ExecutionContextService.hasContext()) {
|
|
31248
31257
|
return new Date(bt.executionContextService.context.when);
|
|
31249
31258
|
}
|
|
31250
31259
|
return new Date();
|
|
31251
31260
|
};
|
|
31261
|
+
/**
|
|
31262
|
+
* Method context retrieval function.
|
|
31263
|
+
* Returns the current method context from MethodContextService if available, otherwise returns null.
|
|
31264
|
+
* This allows log entries to include contextual information about the strategy, exchange, and frame associated with the log event, enhancing the ability to trace and analyze logs in relation to specific execution contexts within the backtest framework.
|
|
31265
|
+
*/
|
|
31266
|
+
const GET_METHOD_CONTEXT_FN = () => {
|
|
31267
|
+
if (MethodContextService.hasContext()) {
|
|
31268
|
+
return bt.methodContextService.context;
|
|
31269
|
+
}
|
|
31270
|
+
return null;
|
|
31271
|
+
};
|
|
31272
|
+
/**
|
|
31273
|
+
* Execution context retrieval function.
|
|
31274
|
+
* Returns the current execution context from ExecutionContextService if available, otherwise returns null.
|
|
31275
|
+
* This allows log entries to include contextual information about the symbol, timestamp, and backtest mode associated with the log event, providing additional insights into the execution environment when analyzing logs.
|
|
31276
|
+
*/
|
|
31277
|
+
const GET_EXECUTION_CONTEXT_FN = () => {
|
|
31278
|
+
if (ExecutionContextService.hasContext()) {
|
|
31279
|
+
return bt.executionContextService.context;
|
|
31280
|
+
}
|
|
31281
|
+
return null;
|
|
31282
|
+
};
|
|
31252
31283
|
/**
|
|
31253
31284
|
* Persistent log adapter.
|
|
31254
31285
|
*
|
|
@@ -31283,12 +31314,14 @@ class LogPersistUtils {
|
|
|
31283
31314
|
this.log = async (topic, ...args) => {
|
|
31284
31315
|
bt.loggerService.info(LOG_PERSIST_METHOD_NAME_LOG, { topic });
|
|
31285
31316
|
await this.waitForInit();
|
|
31286
|
-
const date =
|
|
31317
|
+
const date = GET_DATE_FN();
|
|
31287
31318
|
this._entries.push({
|
|
31288
31319
|
id: functoolsKit.randomString(),
|
|
31289
31320
|
type: "log",
|
|
31290
31321
|
timestamp: Date.now(),
|
|
31291
31322
|
createdAt: date.toISOString(),
|
|
31323
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31324
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31292
31325
|
topic,
|
|
31293
31326
|
args,
|
|
31294
31327
|
});
|
|
@@ -31304,12 +31337,14 @@ class LogPersistUtils {
|
|
|
31304
31337
|
this.debug = async (topic, ...args) => {
|
|
31305
31338
|
bt.loggerService.info(LOG_PERSIST_METHOD_NAME_DEBUG, { topic });
|
|
31306
31339
|
await this.waitForInit();
|
|
31307
|
-
const date =
|
|
31340
|
+
const date = GET_DATE_FN();
|
|
31308
31341
|
this._entries.push({
|
|
31309
31342
|
id: functoolsKit.randomString(),
|
|
31310
31343
|
type: "debug",
|
|
31311
31344
|
timestamp: Date.now(),
|
|
31312
31345
|
createdAt: date.toISOString(),
|
|
31346
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31347
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31313
31348
|
topic,
|
|
31314
31349
|
args,
|
|
31315
31350
|
});
|
|
@@ -31325,12 +31360,14 @@ class LogPersistUtils {
|
|
|
31325
31360
|
this.info = async (topic, ...args) => {
|
|
31326
31361
|
bt.loggerService.info(LOG_PERSIST_METHOD_NAME_INFO, { topic });
|
|
31327
31362
|
await this.waitForInit();
|
|
31328
|
-
const date =
|
|
31363
|
+
const date = GET_DATE_FN();
|
|
31329
31364
|
this._entries.push({
|
|
31330
31365
|
id: functoolsKit.randomString(),
|
|
31331
31366
|
type: "info",
|
|
31332
31367
|
timestamp: Date.now(),
|
|
31333
31368
|
createdAt: date.toISOString(),
|
|
31369
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31370
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31334
31371
|
topic,
|
|
31335
31372
|
args,
|
|
31336
31373
|
});
|
|
@@ -31346,12 +31383,14 @@ class LogPersistUtils {
|
|
|
31346
31383
|
this.warn = async (topic, ...args) => {
|
|
31347
31384
|
bt.loggerService.info(LOG_PERSIST_METHOD_NAME_WARN, { topic });
|
|
31348
31385
|
await this.waitForInit();
|
|
31349
|
-
const date =
|
|
31386
|
+
const date = GET_DATE_FN();
|
|
31350
31387
|
this._entries.push({
|
|
31351
31388
|
id: functoolsKit.randomString(),
|
|
31352
31389
|
type: "warn",
|
|
31353
31390
|
timestamp: Date.now(),
|
|
31354
31391
|
createdAt: date.toISOString(),
|
|
31392
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31393
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31355
31394
|
topic,
|
|
31356
31395
|
args,
|
|
31357
31396
|
});
|
|
@@ -31400,12 +31439,14 @@ class LogMemoryUtils {
|
|
|
31400
31439
|
*/
|
|
31401
31440
|
this.log = async (topic, ...args) => {
|
|
31402
31441
|
bt.loggerService.info(LOG_MEMORY_METHOD_NAME_LOG, { topic });
|
|
31403
|
-
const date =
|
|
31442
|
+
const date = GET_DATE_FN();
|
|
31404
31443
|
this._entries.push({
|
|
31405
31444
|
id: functoolsKit.randomString(),
|
|
31406
31445
|
type: "log",
|
|
31407
31446
|
timestamp: Date.now(),
|
|
31408
31447
|
createdAt: date.toISOString(),
|
|
31448
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31449
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31409
31450
|
topic,
|
|
31410
31451
|
args,
|
|
31411
31452
|
});
|
|
@@ -31419,12 +31460,14 @@ class LogMemoryUtils {
|
|
|
31419
31460
|
*/
|
|
31420
31461
|
this.debug = async (topic, ...args) => {
|
|
31421
31462
|
bt.loggerService.info(LOG_MEMORY_METHOD_NAME_DEBUG, { topic });
|
|
31422
|
-
const date =
|
|
31463
|
+
const date = GET_DATE_FN();
|
|
31423
31464
|
this._entries.push({
|
|
31424
31465
|
id: functoolsKit.randomString(),
|
|
31425
31466
|
type: "debug",
|
|
31426
31467
|
timestamp: Date.now(),
|
|
31427
31468
|
createdAt: date.toISOString(),
|
|
31469
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31470
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31428
31471
|
topic,
|
|
31429
31472
|
args,
|
|
31430
31473
|
});
|
|
@@ -31438,12 +31481,14 @@ class LogMemoryUtils {
|
|
|
31438
31481
|
*/
|
|
31439
31482
|
this.info = async (topic, ...args) => {
|
|
31440
31483
|
bt.loggerService.info(LOG_MEMORY_METHOD_NAME_INFO, { topic });
|
|
31441
|
-
const date =
|
|
31484
|
+
const date = GET_DATE_FN();
|
|
31442
31485
|
this._entries.push({
|
|
31443
31486
|
id: functoolsKit.randomString(),
|
|
31444
31487
|
type: "info",
|
|
31445
31488
|
timestamp: Date.now(),
|
|
31446
31489
|
createdAt: date.toISOString(),
|
|
31490
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31491
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31447
31492
|
topic,
|
|
31448
31493
|
args,
|
|
31449
31494
|
});
|
|
@@ -31457,12 +31502,14 @@ class LogMemoryUtils {
|
|
|
31457
31502
|
*/
|
|
31458
31503
|
this.warn = async (topic, ...args) => {
|
|
31459
31504
|
bt.loggerService.info(LOG_MEMORY_METHOD_NAME_WARN, { topic });
|
|
31460
|
-
const date =
|
|
31505
|
+
const date = GET_DATE_FN();
|
|
31461
31506
|
this._entries.push({
|
|
31462
31507
|
id: functoolsKit.randomString(),
|
|
31463
31508
|
type: "warn",
|
|
31464
31509
|
timestamp: Date.now(),
|
|
31465
31510
|
createdAt: date.toISOString(),
|
|
31511
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31512
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31466
31513
|
topic,
|
|
31467
31514
|
args,
|
|
31468
31515
|
});
|
|
@@ -31486,6 +31533,165 @@ class LogMemoryUtils {
|
|
|
31486
31533
|
}
|
|
31487
31534
|
}
|
|
31488
31535
|
}
|
|
31536
|
+
/**
|
|
31537
|
+
* JSONL-based log adapter with append-only writes and file-based reads.
|
|
31538
|
+
*
|
|
31539
|
+
* Features:
|
|
31540
|
+
* - Writes log entries as JSONL lines via WriteStream (append-only)
|
|
31541
|
+
* - Stream-based writes with backpressure handling
|
|
31542
|
+
* - 15-second timeout protection for write operations
|
|
31543
|
+
* - Automatic directory creation on first write
|
|
31544
|
+
* - Error handling via exitEmitter
|
|
31545
|
+
* - getList reads and parses all lines from the JSONL file
|
|
31546
|
+
*
|
|
31547
|
+
* File format: {dirName}/{fileName}.jsonl
|
|
31548
|
+
* Each line contains a full ILogEntry object.
|
|
31549
|
+
*/
|
|
31550
|
+
class LogJsonlUtils {
|
|
31551
|
+
/**
|
|
31552
|
+
* Creates a new JSONL log adapter instance.
|
|
31553
|
+
*
|
|
31554
|
+
* @param fileName - Base file name (without extension)
|
|
31555
|
+
* @param dirName - Directory path for the JSONL file
|
|
31556
|
+
*/
|
|
31557
|
+
constructor(fileName, dirName) {
|
|
31558
|
+
this.fileName = fileName;
|
|
31559
|
+
this.dirName = dirName;
|
|
31560
|
+
/** WriteStream instance for append-only writes, null until initialized */
|
|
31561
|
+
this._stream = null;
|
|
31562
|
+
/**
|
|
31563
|
+
* Singleshot initialization: creates directory and opens append stream.
|
|
31564
|
+
* Sets up error handler that emits to exitEmitter.
|
|
31565
|
+
*/
|
|
31566
|
+
this[_a] = functoolsKit.singleshot(async () => {
|
|
31567
|
+
await fs__namespace.mkdir(this.dirName, { recursive: true });
|
|
31568
|
+
this._stream = fs$1.createWriteStream(this._filePath, { flags: "a" });
|
|
31569
|
+
this._stream.on("error", (err) => {
|
|
31570
|
+
exitEmitter.next(new Error(`LogJsonlUtils stream error for file=${this._filePath} message=${functoolsKit.getErrorMessage(err)}`));
|
|
31571
|
+
});
|
|
31572
|
+
});
|
|
31573
|
+
/**
|
|
31574
|
+
* Timeout-protected write with backpressure handling.
|
|
31575
|
+
* Waits for drain event if write buffer is full.
|
|
31576
|
+
* Times out after 15 seconds and returns TIMEOUT_SYMBOL.
|
|
31577
|
+
*/
|
|
31578
|
+
this[_b] = functoolsKit.timeout(async (line) => {
|
|
31579
|
+
if (!this._stream.write(line)) {
|
|
31580
|
+
await new Promise((resolve) => {
|
|
31581
|
+
this._stream.once("drain", resolve);
|
|
31582
|
+
});
|
|
31583
|
+
}
|
|
31584
|
+
}, 15000);
|
|
31585
|
+
/**
|
|
31586
|
+
* Appends a log entry as a JSONL line.
|
|
31587
|
+
*/
|
|
31588
|
+
this._append = async (entry) => {
|
|
31589
|
+
await this[WAIT_FOR_INIT_SYMBOL]();
|
|
31590
|
+
const line = JSON.stringify(entry) + "\n";
|
|
31591
|
+
const status = await this[WRITE_SAFE_SYMBOL](line);
|
|
31592
|
+
if (status === functoolsKit.TIMEOUT_SYMBOL) {
|
|
31593
|
+
throw new Error(`LogJsonlUtils timeout writing to file=${this._filePath}`);
|
|
31594
|
+
}
|
|
31595
|
+
};
|
|
31596
|
+
/**
|
|
31597
|
+
* Logs a general-purpose message.
|
|
31598
|
+
* @param topic - The log topic / method name
|
|
31599
|
+
* @param args - Additional arguments
|
|
31600
|
+
*/
|
|
31601
|
+
this.log = async (topic, ...args) => {
|
|
31602
|
+
bt.loggerService.info(LOG_JSONL_METHOD_NAME_LOG, { topic });
|
|
31603
|
+
const date = GET_DATE_FN();
|
|
31604
|
+
await this._append({
|
|
31605
|
+
id: functoolsKit.randomString(),
|
|
31606
|
+
type: "log",
|
|
31607
|
+
timestamp: Date.now(),
|
|
31608
|
+
createdAt: date.toISOString(),
|
|
31609
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31610
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31611
|
+
topic,
|
|
31612
|
+
args,
|
|
31613
|
+
});
|
|
31614
|
+
};
|
|
31615
|
+
/**
|
|
31616
|
+
* Logs a debug-level message.
|
|
31617
|
+
* @param topic - The log topic / method name
|
|
31618
|
+
* @param args - Additional arguments
|
|
31619
|
+
*/
|
|
31620
|
+
this.debug = async (topic, ...args) => {
|
|
31621
|
+
bt.loggerService.info(LOG_JSONL_METHOD_NAME_DEBUG, { topic });
|
|
31622
|
+
const date = GET_DATE_FN();
|
|
31623
|
+
await this._append({
|
|
31624
|
+
id: functoolsKit.randomString(),
|
|
31625
|
+
type: "debug",
|
|
31626
|
+
timestamp: Date.now(),
|
|
31627
|
+
createdAt: date.toISOString(),
|
|
31628
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31629
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31630
|
+
topic,
|
|
31631
|
+
args,
|
|
31632
|
+
});
|
|
31633
|
+
};
|
|
31634
|
+
/**
|
|
31635
|
+
* Logs an info-level message.
|
|
31636
|
+
* @param topic - The log topic / method name
|
|
31637
|
+
* @param args - Additional arguments
|
|
31638
|
+
*/
|
|
31639
|
+
this.info = async (topic, ...args) => {
|
|
31640
|
+
bt.loggerService.info(LOG_JSONL_METHOD_NAME_INFO, { topic });
|
|
31641
|
+
const date = GET_DATE_FN();
|
|
31642
|
+
await this._append({
|
|
31643
|
+
id: functoolsKit.randomString(),
|
|
31644
|
+
type: "info",
|
|
31645
|
+
timestamp: Date.now(),
|
|
31646
|
+
createdAt: date.toISOString(),
|
|
31647
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31648
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31649
|
+
topic,
|
|
31650
|
+
args,
|
|
31651
|
+
});
|
|
31652
|
+
};
|
|
31653
|
+
/**
|
|
31654
|
+
* Logs a warning-level message.
|
|
31655
|
+
* @param topic - The log topic / method name
|
|
31656
|
+
* @param args - Additional arguments
|
|
31657
|
+
*/
|
|
31658
|
+
this.warn = async (topic, ...args) => {
|
|
31659
|
+
bt.loggerService.info(LOG_JSONL_METHOD_NAME_WARN, { topic });
|
|
31660
|
+
const date = GET_DATE_FN();
|
|
31661
|
+
await this._append({
|
|
31662
|
+
id: functoolsKit.randomString(),
|
|
31663
|
+
type: "warn",
|
|
31664
|
+
timestamp: Date.now(),
|
|
31665
|
+
createdAt: date.toISOString(),
|
|
31666
|
+
methodContext: GET_METHOD_CONTEXT_FN(),
|
|
31667
|
+
executionContext: GET_EXECUTION_CONTEXT_FN(),
|
|
31668
|
+
topic,
|
|
31669
|
+
args,
|
|
31670
|
+
});
|
|
31671
|
+
};
|
|
31672
|
+
/**
|
|
31673
|
+
* Reads all log entries from the JSONL file.
|
|
31674
|
+
* Returns empty array if file does not exist.
|
|
31675
|
+
* @returns Array of all log entries
|
|
31676
|
+
*/
|
|
31677
|
+
this.getList = async () => {
|
|
31678
|
+
bt.loggerService.info(LOG_JSONL_METHOD_NAME_GET_LIST);
|
|
31679
|
+
let raw;
|
|
31680
|
+
try {
|
|
31681
|
+
raw = await fs__namespace.readFile(this._filePath, "utf-8");
|
|
31682
|
+
}
|
|
31683
|
+
catch {
|
|
31684
|
+
return [];
|
|
31685
|
+
}
|
|
31686
|
+
return raw
|
|
31687
|
+
.split("\n")
|
|
31688
|
+
.filter((line) => line.trim().length > 0)
|
|
31689
|
+
.map((line) => JSON.parse(line));
|
|
31690
|
+
};
|
|
31691
|
+
this._filePath = path.join(this.dirName, this.fileName);
|
|
31692
|
+
}
|
|
31693
|
+
}
|
|
31694
|
+
_a = WAIT_FOR_INIT_SYMBOL, _b = WRITE_SAFE_SYMBOL;
|
|
31489
31695
|
/**
|
|
31490
31696
|
* Dummy log adapter that discards all writes.
|
|
31491
31697
|
*
|
|
@@ -31625,6 +31831,18 @@ class LogAdapter {
|
|
|
31625
31831
|
bt.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
31626
31832
|
this._log = new LogDummyUtils();
|
|
31627
31833
|
};
|
|
31834
|
+
/**
|
|
31835
|
+
* Switches to JSONL file log adapter.
|
|
31836
|
+
* Log entries will be appended to {dirName}/{fileName}.jsonl.
|
|
31837
|
+
* Reads are performed by parsing all lines from the file.
|
|
31838
|
+
*
|
|
31839
|
+
* @param fileName - Base file name without extension (default: "log")
|
|
31840
|
+
* @param dirName - Directory for the JSONL file (default: ./dump/log)
|
|
31841
|
+
*/
|
|
31842
|
+
this.useJsonl = (fileName = "log.jsonl", dirName = path.join(process.cwd(), "./dump/log")) => {
|
|
31843
|
+
bt.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_JSONL);
|
|
31844
|
+
this._log = new LogJsonlUtils(fileName, dirName);
|
|
31845
|
+
};
|
|
31628
31846
|
}
|
|
31629
31847
|
}
|
|
31630
31848
|
/**
|