@fgv/ts-utils 5.1.0-32 → 5.1.0-34
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/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/packlets/base/result.js +24 -8
- package/dist/packlets/base/result.js.map +1 -1
- package/dist/packlets/collections/index.js +1 -0
- package/dist/packlets/collections/index.js.map +1 -1
- package/dist/packlets/collections/readOnlyConvertingResultMap.js.map +1 -1
- package/dist/packlets/collections/retainingRingBuffer.js +159 -0
- package/dist/packlets/collections/retainingRingBuffer.js.map +1 -0
- package/dist/packlets/conversion/baseConverter.js +5 -2
- package/dist/packlets/conversion/baseConverter.js.map +1 -1
- package/dist/packlets/conversion/basicConverters.js +12 -4
- package/dist/packlets/conversion/basicConverters.js.map +1 -1
- package/dist/packlets/conversion/converter.js.map +1 -1
- package/dist/packlets/logging/logger.js +2 -10
- package/dist/packlets/logging/logger.js.map +1 -1
- package/dist/packlets/logging/retainingLogger.js +18 -65
- package/dist/packlets/logging/retainingLogger.js.map +1 -1
- package/dist/packlets/logging-interface/index.js +11 -0
- package/dist/packlets/logging-interface/index.js.map +1 -0
- package/dist/ts-utils.d.ts +210 -40
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/packlets/base/result.d.ts +37 -10
- package/lib/packlets/base/result.d.ts.map +1 -1
- package/lib/packlets/base/result.js +24 -8
- package/lib/packlets/base/result.js.map +1 -1
- package/lib/packlets/collections/index.d.ts +1 -0
- package/lib/packlets/collections/index.d.ts.map +1 -1
- package/lib/packlets/collections/index.js +1 -0
- package/lib/packlets/collections/index.js.map +1 -1
- package/lib/packlets/collections/readOnlyConvertingResultMap.d.ts +1 -1
- package/lib/packlets/collections/readOnlyConvertingResultMap.d.ts.map +1 -1
- package/lib/packlets/collections/readOnlyConvertingResultMap.js.map +1 -1
- package/lib/packlets/collections/retainingRingBuffer.d.ts +147 -0
- package/lib/packlets/collections/retainingRingBuffer.d.ts.map +1 -0
- package/lib/packlets/collections/retainingRingBuffer.js +163 -0
- package/lib/packlets/collections/retainingRingBuffer.js.map +1 -0
- package/lib/packlets/conversion/baseConverter.d.ts +4 -1
- package/lib/packlets/conversion/baseConverter.d.ts.map +1 -1
- package/lib/packlets/conversion/baseConverter.js +5 -2
- package/lib/packlets/conversion/baseConverter.js.map +1 -1
- package/lib/packlets/conversion/basicConverters.d.ts +3 -0
- package/lib/packlets/conversion/basicConverters.d.ts.map +1 -1
- package/lib/packlets/conversion/basicConverters.js +12 -4
- package/lib/packlets/conversion/basicConverters.js.map +1 -1
- package/lib/packlets/conversion/converter.d.ts +4 -1
- package/lib/packlets/conversion/converter.d.ts.map +1 -1
- package/lib/packlets/conversion/converter.js.map +1 -1
- package/lib/packlets/logging/logger.d.ts +2 -85
- package/lib/packlets/logging/logger.d.ts.map +1 -1
- package/lib/packlets/logging/logger.js +3 -12
- package/lib/packlets/logging/logger.js.map +1 -1
- package/lib/packlets/logging/retainingLogger.d.ts +8 -28
- package/lib/packlets/logging/retainingLogger.d.ts.map +1 -1
- package/lib/packlets/logging/retainingLogger.js +18 -65
- package/lib/packlets/logging/retainingLogger.js.map +1 -1
- package/lib/packlets/logging-interface/index.d.ts +87 -0
- package/lib/packlets/logging-interface/index.d.ts.map +1 -0
- package/lib/packlets/logging-interface/index.js +14 -0
- package/lib/packlets/logging-interface/index.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retainingLogger.js","sourceRoot":"","sources":["../../../src/packlets/logging/retainingLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { MessageLogLevel, Success, succeed } from '../base';\nimport { LoggerBase, ReporterLogLevel, shouldLog } from './logger';\n\n/**\n * A retained log record. Preserves the level and an ordering cursor so consumers\n * can filter by severity and page incrementally.\n * @public\n */\nexport interface ILogRecord {\n /**\n * Monotonic 1-based sequence number, stable across ring eviction.\n */\n readonly seq: number;\n /**\n * Milliseconds since epoch when the record was logged (from the injected clock).\n */\n readonly timestamp: number;\n /**\n * The level the record was logged at.\n */\n readonly level: MessageLogLevel;\n /**\n * The formatted message (same formatting {@link Logging.LoggerBase._format | LoggerBase._format} produces).\n */\n readonly message: string;\n /**\n * The raw structured inputs `[message, ...parameters]` before formatting.\n */\n readonly args?: readonly unknown[];\n}\n\n/**\n * Options for {@link Logging.RetainingLogger.getRecords | RetainingLogger.getRecords}.\n * @public\n */\nexport interface IGetRecordsOptions {\n /**\n * If supplied, only records whose level would be emitted at this threshold\n * (per {@link Logging.shouldLog | shouldLog}) are returned.\n */\n readonly minLevel?: ReporterLogLevel;\n /**\n * If supplied, only records with `seq > sinceSeq` are returned, enabling\n * incremental paging from a previously-held cursor.\n */\n readonly sinceSeq?: number;\n /**\n * If supplied, returns at most this many records — the most recent N (tail),\n * still ordered oldest-first.\n */\n readonly limit?: number;\n}\n\n/**\n * An {@link Logging.ILogger | ILogger} that retains structured log records in a bounded\n * most-recent-N ring, with a query API supporting min-severity filtering and\n * since-cursor incremental paging.\n *\n * @remarks\n * Records are captured via the {@link Logging.LoggerBase._logStructured | _logStructured} hook,\n * so the full structured form (`level` + formatted `message` + raw `args`) is retained.\n * The logger emits nowhere itself — pair it with a {@link Logging.MultiLogger | MultiLogger}\n * to also feed a {@link Logging.ConsoleLogger | ConsoleLogger} or other durable sink.\n *\n * @public\n */\nexport class RetainingLogger extends LoggerBase {\n /**\n * The fixed ring capacity — the maximum number of records retained before the\n * oldest is overwritten. A positive integer (see the constructor normalization).\n * @internal\n */\n private readonly _capacity: number;\n\n /**\n * Injected clock used to timestamp records.\n * @internal\n */\n private readonly _now: () => number;\n\n /**\n * The backing store, used as a circular buffer. Grows lazily up to `_capacity`,\n * after which records overwrite the oldest slot in place — eviction is O(1), with\n * no `shift()` re-indexing regardless of capacity.\n * @internal\n */\n private _buffer: ILogRecord[] = [];\n\n /**\n * Index of the oldest retained record within `_buffer` once the ring is full.\n * @internal\n */\n private _head: number = 0;\n\n /**\n * The number of valid records currently retained (`<= _capacity`).\n * @internal\n */\n private _count: number = 0;\n\n /**\n * The most recently assigned sequence number; monotonic, stable across eviction\n * and {@link Logging.RetainingLogger.clear | clear()}.\n * @internal\n */\n private _lastSeq: number = 0;\n\n /**\n * Creates a new retaining logger.\n * @param logLevel - The level of logging to retain. Defaults to `'detail'` to capture\n * broadly and filter at query time.\n * @param maxRecords - The maximum number of records to retain. Defaults to `1000`.\n * @param now - Injected clock returning milliseconds since epoch. Defaults to `Date.now`.\n */\n public constructor(\n logLevel: ReporterLogLevel = 'detail',\n maxRecords: number = 1000,\n now: () => number = () => Date.now()\n ) {\n super(logLevel);\n // The ring requires a positive integer capacity to be well-defined; a non-finite\n // or sub-1 value would make the modular index arithmetic meaningless, so floor it\n // to a sane minimum of 1 rather than crash on degenerate input.\n this._capacity = Number.isFinite(maxRecords) && maxRecords >= 1 ? Math.floor(maxRecords) : 1;\n this._now = now;\n }\n\n /**\n * The retained records, oldest-first.\n */\n public get records(): ReadonlyArray<ILogRecord> {\n return this._toOrderedArray();\n }\n\n /**\n * The most recently assigned sequence number. A client can hold this value and\n * pass it as `sinceSeq` to page only records logged afterward.\n */\n public get lastSeq(): number {\n return this._lastSeq;\n }\n\n /**\n * Returns retained records, oldest-first, optionally filtered.\n * @param options - {@link Logging.IGetRecordsOptions | Filtering and paging options}.\n * @returns The matching records, oldest-first.\n */\n public getRecords(options?: IGetRecordsOptions): ReadonlyArray<ILogRecord> {\n let result: ReadonlyArray<ILogRecord> = this._toOrderedArray();\n if (options?.minLevel !== undefined) {\n const minLevel = options.minLevel;\n result = result.filter((r) => shouldLog(r.level, minLevel));\n }\n if (options?.sinceSeq !== undefined) {\n const sinceSeq = options.sinceSeq;\n result = result.filter((r) => r.seq > sinceSeq);\n }\n if (options?.limit !== undefined && result.length > options.limit) {\n result = result.slice(result.length - options.limit);\n }\n return result;\n }\n\n /**\n * Clears all retained records. Does NOT reset the sequence counter, so a client\n * holding a `sinceSeq` cursor never re-sees a sequence number.\n */\n public clear(): void {\n this._buffer = [];\n this._head = 0;\n this._count = 0;\n }\n\n /**\n * Materializes the ring into a plain oldest-first array.\n * @internal\n */\n private _toOrderedArray(): ILogRecord[] {\n const result: ILogRecord[] = [];\n for (let i = 0; i < this._count; i++) {\n result.push(this._buffer[(this._head + i) % this._capacity]);\n }\n return result;\n }\n\n /**\n * {@inheritDoc Logging.LoggerBase._logStructured}\n * @internal\n */\n protected _logStructured(\n level: MessageLogLevel,\n formatted: string,\n message: unknown,\n parameters: readonly unknown[]\n ): void {\n this._lastSeq += 1;\n const record: ILogRecord = {\n seq: this._lastSeq,\n timestamp: this._now(),\n level,\n message: formatted,\n args: [message, ...parameters]\n };\n if (this._count < this._capacity) {\n // Still filling: append to the next free slot (head stays 0 during this phase).\n this._buffer.push(record);\n this._count += 1;\n } else {\n // Full: overwrite the oldest record in place and advance the head.\n this._buffer[this._head] = record;\n this._head = (this._head + 1) % this._capacity;\n }\n }\n\n /**\n * {@inheritDoc Logging.LoggerBase._log}\n * @internal\n */\n protected _log(message: string, __level: MessageLogLevel): Success<string | undefined> {\n return succeed(message);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"retainingLogger.js","sourceRoot":"","sources":["../../../src/packlets/logging/retainingLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAA4B,OAAO,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAoB,SAAS,EAAE,MAAM,UAAU,CAAC;AAoDnE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAuB7C;;;;;;OAMG;IACH,YACE,WAA6B,QAAQ,EACrC,aAAqB,IAAI,EACzB,MAAoB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAEpC,KAAK,CAAC,QAAQ,CAAC,CAAC;QA5BlB;;;;;WAKG;QACK,aAAQ,GAAW,CAAC,CAAC;QAuB3B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,KAAK,GAAG,IAAI,mBAAmB,CAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACI,UAAU,CAAC,OAA4B;QAC5C,MAAM,QAAQ,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,CAAC;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YACtB,QAAQ,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ;YAC3B,MAAM,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;YAChF,KAAK,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK;SACtB,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;;OAGG;IACO,cAAc,CACtB,KAAsB,EACtB,SAAiB,EACjB,OAAgB,EAChB,UAA8B;QAE9B,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,MAAM,MAAM,GAAe;YACzB,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE;YACtB,KAAK;YACL,OAAO,EAAE,SAAS;YAClB,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC;SAC/B,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACO,IAAI,CAAC,OAAe,EAAE,OAAwB;QACtD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { MessageLogLevel, Success, succeed } from '../base';\nimport { RetainingRingBuffer } from '../collections';\nimport { LoggerBase, ReporterLogLevel, shouldLog } from './logger';\n\n/**\n * A retained log record. Preserves the level and an ordering cursor so consumers\n * can filter by severity and page incrementally.\n * @public\n */\nexport interface ILogRecord {\n /**\n * Monotonic 1-based sequence number, stable across ring eviction.\n */\n readonly seq: number;\n /**\n * Milliseconds since epoch when the record was logged (from the injected clock).\n */\n readonly timestamp: number;\n /**\n * The level the record was logged at.\n */\n readonly level: MessageLogLevel;\n /**\n * The formatted message (same formatting {@link Logging.LoggerBase._format | LoggerBase._format} produces).\n */\n readonly message: string;\n /**\n * The raw structured inputs `[message, ...parameters]` before formatting.\n */\n readonly args?: readonly unknown[];\n}\n\n/**\n * Options for {@link Logging.RetainingLogger.getRecords | RetainingLogger.getRecords}.\n * @public\n */\nexport interface IGetRecordsOptions {\n /**\n * If supplied, only records whose level would be emitted at this threshold\n * (per {@link Logging.shouldLog | shouldLog}) are returned.\n */\n readonly minLevel?: ReporterLogLevel;\n /**\n * If supplied, only records with `seq > sinceSeq` are returned, enabling\n * incremental paging from a previously-held cursor.\n */\n readonly sinceSeq?: number;\n /**\n * If supplied, returns at most this many records — the most recent N (tail),\n * still ordered oldest-first.\n */\n readonly limit?: number;\n}\n\n/**\n * An {@link Logging.ILogger | ILogger} that retains structured log records in a bounded\n * most-recent-N ring, with a query API supporting min-severity filtering and\n * since-cursor incremental paging.\n *\n * @remarks\n * Records are captured via the {@link Logging.LoggerBase._logStructured | _logStructured} hook,\n * so the full structured form (`level` + formatted `message` + raw `args`) is retained.\n * The logger emits nowhere itself — pair it with a {@link Logging.MultiLogger | MultiLogger}\n * to also feed a {@link Logging.ConsoleLogger | ConsoleLogger} or other durable sink.\n *\n * @public\n */\nexport class RetainingLogger extends LoggerBase {\n /**\n * Injected clock used to timestamp records.\n * @internal\n */\n private readonly _now: () => number;\n\n /**\n * The monotonic sequence counter. The logger owns `seq` assignment and\n * increments this before each push so the buffer receives strictly increasing\n * sequence numbers.\n * @internal\n */\n private _nextSeq: number = 0;\n\n /**\n * The backing ring buffer. Retains up to `maxRecords` log records, evicting\n * the oldest when full. The buffer is a pure seq-ring — it does not assign\n * `seq`; the logger does.\n * @internal\n */\n private readonly _ring: RetainingRingBuffer<ILogRecord>;\n\n /**\n * Creates a new retaining logger.\n * @param logLevel - The level of logging to retain. Defaults to `'detail'` to capture\n * broadly and filter at query time.\n * @param maxRecords - The maximum number of records to retain. Defaults to `1000`.\n * @param now - Injected clock returning milliseconds since epoch. Defaults to `Date.now`.\n */\n public constructor(\n logLevel: ReporterLogLevel = 'detail',\n maxRecords: number = 1000,\n now: () => number = () => Date.now()\n ) {\n super(logLevel);\n this._now = now;\n this._ring = new RetainingRingBuffer<ILogRecord>({ maxRecords });\n }\n\n /**\n * The retained records, oldest-first.\n */\n public get records(): ReadonlyArray<ILogRecord> {\n return this._ring.records;\n }\n\n /**\n * The most recently assigned sequence number. A client can hold this value and\n * pass it as `sinceSeq` to page only records logged afterward.\n */\n public get lastSeq(): number {\n return this._ring.lastSeq;\n }\n\n /**\n * Returns retained records, oldest-first, optionally filtered.\n * @param options - {@link Logging.IGetRecordsOptions | Filtering and paging options}.\n * @returns The matching records, oldest-first.\n */\n public getRecords(options?: IGetRecordsOptions): ReadonlyArray<ILogRecord> {\n const minLevel = options?.minLevel;\n return this._ring.query({\n sinceSeq: options?.sinceSeq,\n filter: minLevel !== undefined ? (r) => shouldLog(r.level, minLevel) : undefined,\n limit: options?.limit\n });\n }\n\n /**\n * Clears all retained records. Does NOT reset the sequence counter, so a client\n * holding a `sinceSeq` cursor never re-sees a sequence number.\n */\n public clear(): void {\n this._ring.clear();\n }\n\n /**\n * {@inheritDoc Logging.LoggerBase._logStructured}\n * @internal\n */\n protected _logStructured(\n level: MessageLogLevel,\n formatted: string,\n message: unknown,\n parameters: readonly unknown[]\n ): void {\n this._nextSeq += 1;\n const record: ILogRecord = {\n seq: this._nextSeq,\n timestamp: this._now(),\n level,\n message: formatted,\n args: [message, ...parameters]\n };\n this._ring.push(record);\n }\n\n /**\n * {@inheritDoc Logging.LoggerBase._log}\n * @internal\n */\n protected _log(message: string, __level: MessageLogLevel): Success<string | undefined> {\n return succeed(message);\n }\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard that checks whether a logger implements {@link IDetailLogger}.
|
|
3
|
+
* @param logger - The logger to check.
|
|
4
|
+
* @returns `true` if the logger implements `IDetailLogger`.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export function isDetailLogger(logger) {
|
|
8
|
+
return (typeof logger.errorWithDetail === 'function' &&
|
|
9
|
+
typeof logger.warnWithDetail === 'function');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/logging-interface/index.ts"],"names":[],"mappings":"AA8GA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,OAAO,CACL,OAAQ,MAAwB,CAAC,eAAe,KAAK,UAAU;QAC/D,OAAQ,MAAwB,CAAC,cAAc,KAAK,UAAU,CAC/D,CAAC;AACJ,CAAC","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { MessageLogLevel, Success } from '../base';\n\n/**\n * The level of logging to be used.\n * @public\n */\nexport type ReporterLogLevel = 'all' | 'detail' | 'info' | 'warning' | 'error' | 'silent';\n\n/**\n * Generic Result-aware logger interface with multiple levels of logging.\n * @public\n */\nexport interface ILogger {\n /**\n * The level of logging to be used.\n */\n readonly logLevel: ReporterLogLevel;\n\n /**\n * Logs a message at the given level.\n * @param level - The level of the message.\n * @param message - The message to log.\n * @param parameters - The parameters to log.\n * @returns `Success` with the logged message if the level is enabled, or\n * `Success` with `undefined` if the message is suppressed.\n */\n log(level: MessageLogLevel, message?: unknown, ...parameters: unknown[]): Success<string | undefined>;\n\n /**\n * Logs a detail message.\n * @param message - The message to log.\n * @param parameters - The parameters to log.\n * @returns `Success` with the logged message if the level is enabled, or\n * `Success` with `undefined` if the message is suppressed.\n */\n detail(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;\n\n /**\n * Logs an info message.\n * @param message - The message to log.\n * @param parameters - The parameters to log.\n * @returns `Success` with the logged message if the level is enabled, or\n * `Success` with `undefined` if the message is suppressed.\n */\n info(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;\n\n /**\n * Logs a warning message.\n * @param message - The message to log.\n * @param parameters - The parameters to log.\n * @returns `Success` with the logged message if the level is enabled, or\n * `Success` with `undefined` if the message is suppressed.\n */\n warn(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;\n\n /**\n * Logs an error message.\n * @param message - The message to log.\n * @param parameters - The parameters to log.\n * @returns `Success` with the logged message if the level is enabled, or\n * `Success` with `undefined` if the message is suppressed.\n */\n error(message?: unknown, ...parameters: unknown[]): Success<string | undefined>;\n}\n\n/**\n * Extended logger interface that supports logging a short summary message at a\n * primary level (error/warn) while emitting the full detail at `detail` level.\n *\n * The detail is suppressed by default (requires log level `'detail'` or `'all'`),\n * keeping the primary log clean while preserving the full context for debugging.\n * @public\n */\nexport interface IDetailLogger extends ILogger {\n /**\n * Logs a short error summary at `error` level, then emits `detail` at `detail` level.\n * @param message - Short human-readable summary.\n * @param detail - Full detail (e.g. raw converter error) logged at `detail` level.\n */\n errorWithDetail(message: string, detail: unknown): Success<string | undefined>;\n\n /**\n * Logs a short warning summary at `warning` level, then emits `detail` at `detail` level.\n * @param message - Short human-readable summary.\n * @param detail - Full detail logged at `detail` level.\n */\n warnWithDetail(message: string, detail: unknown): Success<string | undefined>;\n}\n\n/**\n * Type guard that checks whether a logger implements {@link IDetailLogger}.\n * @param logger - The logger to check.\n * @returns `true` if the logger implements `IDetailLogger`.\n * @public\n */\nexport function isDetailLogger(logger: ILogger): logger is IDetailLogger {\n return (\n typeof (logger as IDetailLogger).errorWithDetail === 'function' &&\n typeof (logger as IDetailLogger).warnWithDetail === 'function'\n );\n}\n"]}
|
package/dist/ts-utils.d.ts
CHANGED
|
@@ -422,10 +422,13 @@ declare function asValidator<T, TC = unknown>(converterOrValidator: Converter<T,
|
|
|
422
422
|
|
|
423
423
|
/**
|
|
424
424
|
* Async continuation callback to be called in the event that a
|
|
425
|
-
* {@link Result} fails, returning a `
|
|
425
|
+
* {@link Result} fails, returning a `PromiseLike` of a new {@link Result}.
|
|
426
|
+
* @remarks
|
|
427
|
+
* See {@link AsyncSuccessContinuation} for the rationale behind accepting
|
|
428
|
+
* any `PromiseLike<Result<T>>` rather than only a `Promise<Result<T>>`.
|
|
426
429
|
* @public
|
|
427
430
|
*/
|
|
428
|
-
export declare type AsyncFailureContinuation<T> = (message: string) =>
|
|
431
|
+
export declare type AsyncFailureContinuation<T> = (message: string) => PromiseLike<Result<T>>;
|
|
429
432
|
|
|
430
433
|
/**
|
|
431
434
|
* Wraps a `Promise` of a {@link Result} to enable fluent chaining of both
|
|
@@ -450,14 +453,17 @@ export declare type AsyncFailureContinuation<T> = (message: string) => Promise<R
|
|
|
450
453
|
export declare class AsyncResult<T> implements PromiseLike<Result<T>> {
|
|
451
454
|
private readonly _promise;
|
|
452
455
|
/**
|
|
453
|
-
* Constructs an {@link AsyncResult} wrapping the supplied promise
|
|
456
|
+
* Constructs an {@link AsyncResult} wrapping the supplied promise (or any
|
|
457
|
+
* `PromiseLike` that resolves to a {@link Result}, such as another
|
|
458
|
+
* {@link AsyncResult}).
|
|
454
459
|
* @remarks
|
|
455
460
|
* If the supplied promise rejects, the rejection is caught and converted
|
|
456
461
|
* to a {@link Failure}, ensuring that awaiting an {@link AsyncResult} always
|
|
457
462
|
* yields a {@link Result}.
|
|
458
|
-
* @param promise - A `Promise` that resolves to a
|
|
463
|
+
* @param promise - A `Promise` (or `PromiseLike`) that resolves to a
|
|
464
|
+
* {@link Result}.
|
|
459
465
|
*/
|
|
460
|
-
constructor(promise:
|
|
466
|
+
constructor(promise: PromiseLike<Result<T>>);
|
|
461
467
|
/**
|
|
462
468
|
* Calls a supplied {@link SuccessContinuation | success continuation} if
|
|
463
469
|
* the wrapped result is successful.
|
|
@@ -540,10 +546,18 @@ export declare class AsyncResult<T> implements PromiseLike<Result<T>> {
|
|
|
540
546
|
|
|
541
547
|
/**
|
|
542
548
|
* Async continuation callback to be called in the event that a
|
|
543
|
-
* {@link Result} is successful, returning a `
|
|
549
|
+
* {@link Result} is successful, returning a `PromiseLike` of a new
|
|
550
|
+
* {@link Result}.
|
|
551
|
+
* @remarks
|
|
552
|
+
* Typed as `PromiseLike<Result<TN>>` rather than `Promise<Result<TN>>` so
|
|
553
|
+
* callers can return the result of {@link captureAsyncResult} (which is an
|
|
554
|
+
* {@link AsyncResult}, itself a `PromiseLike<Result<TN>>`) directly from a
|
|
555
|
+
* `thenOnSuccess` callback without an `async` wrapper to coerce the
|
|
556
|
+
* contextual return type back through `Awaited<>`. The continuation result
|
|
557
|
+
* is always wrapped into an {@link AsyncResult}, so chaining is unaffected.
|
|
544
558
|
* @public
|
|
545
559
|
*/
|
|
546
|
-
export declare type AsyncSuccessContinuation<T, TN> = (value: T) =>
|
|
560
|
+
export declare type AsyncSuccessContinuation<T, TN> = (value: T) => PromiseLike<Result<TN>>;
|
|
547
561
|
|
|
548
562
|
declare namespace Base {
|
|
549
563
|
export {
|
|
@@ -592,10 +606,13 @@ declare class BaseConverter<T, TC = unknown> implements Converter<T, TC> {
|
|
|
592
606
|
* @param from - The `unknown` to be converted
|
|
593
607
|
* @param context - An optional conversion context of type `<TC>` to be used in
|
|
594
608
|
* the conversion.
|
|
609
|
+
* @param selfOverride - An optional override for the `self` reference passed to the
|
|
610
|
+
* converter function, enabling outer converters (e.g. discriminated-object) to thread
|
|
611
|
+
* themselves through to per-arm converters for recursive parsing.
|
|
595
612
|
* @returns A {@link Result} with a {@link Success} and a value on success or an
|
|
596
613
|
* {@link Failure} with a a message on failure.
|
|
597
614
|
*/
|
|
598
|
-
convert(from: unknown, context?: TC): Result<T>;
|
|
615
|
+
convert(from: unknown, context?: TC, selfOverride?: Converter<T, TC>): Result<T>;
|
|
599
616
|
/**
|
|
600
617
|
* Converts from `unknown` to `<T>` or `undefined`, as appropriate.
|
|
601
618
|
*
|
|
@@ -992,12 +1009,25 @@ declare class CacheInvalidatingResultMapWrapper<TK extends string, TSRC, TTARGET
|
|
|
992
1009
|
/**
|
|
993
1010
|
* Wraps an async function which might throw to convert exception results
|
|
994
1011
|
* to {@link Failure}.
|
|
1012
|
+
* @remarks
|
|
1013
|
+
* Returns an {@link AsyncResult} so callers can fluently chain
|
|
1014
|
+
* (`.onSuccess` / `.thenOnSuccess` / `.withErrorFormat`) directly off the
|
|
1015
|
+
* captured result. Because {@link AsyncResult} implements
|
|
1016
|
+
* `PromiseLike<Result<T>>`, existing `await captureAsyncResult(...)` call
|
|
1017
|
+
* sites continue to work unchanged and yield the same {@link Result}.
|
|
1018
|
+
*
|
|
1019
|
+
* Synchronous throws from `func` (before it returns its `Promise`), promise
|
|
1020
|
+
* rejections, and successful resolutions are all funneled through the
|
|
1021
|
+
* returned {@link AsyncResult}, which resolves to a {@link Failure} for the
|
|
1022
|
+
* throw/reject cases and a {@link Success} wrapping the resolved value
|
|
1023
|
+
* otherwise.
|
|
995
1024
|
* @param func - The async function to be captured.
|
|
996
|
-
* @returns
|
|
997
|
-
* success, or {@link Failure} with the thrown error message
|
|
1025
|
+
* @returns An {@link AsyncResult} resolving to {@link Success} with a value
|
|
1026
|
+
* of type `<T>` on success, or {@link Failure} with the thrown error message
|
|
1027
|
+
* if `func` throws or rejects.
|
|
998
1028
|
* @public
|
|
999
1029
|
*/
|
|
1000
|
-
export declare function captureAsyncResult<T>(func: () => Promise<T>):
|
|
1030
|
+
export declare function captureAsyncResult<T>(func: () => Promise<T>): AsyncResult<T>;
|
|
1001
1031
|
|
|
1002
1032
|
/**
|
|
1003
1033
|
* Wraps a function which might throw to convert exception results
|
|
@@ -1161,6 +1191,10 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1161
1191
|
ConversionErrorHandling,
|
|
1162
1192
|
IReadOnlyConvertingResultMapConstructorParams,
|
|
1163
1193
|
ReadOnlyConvertingResultMap,
|
|
1194
|
+
IRetainedRecord,
|
|
1195
|
+
IRetainingRingBufferQuery,
|
|
1196
|
+
IRetainingRingBufferCreateParams,
|
|
1197
|
+
RetainingRingBuffer,
|
|
1164
1198
|
IResultMapConstructorParams,
|
|
1165
1199
|
ResultMapValueFactory,
|
|
1166
1200
|
IResultMap,
|
|
@@ -1584,10 +1618,13 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
1584
1618
|
* @param from - The `unknown` to be converted
|
|
1585
1619
|
* @param context - An optional conversion context of type `<TC>` to be used in
|
|
1586
1620
|
* the conversion.
|
|
1621
|
+
* @param selfOverride - An optional override for the `self` reference passed to the
|
|
1622
|
+
* converter function, enabling outer converters (e.g. discriminated-object) to thread
|
|
1623
|
+
* themselves through to per-arm converters for recursive parsing.
|
|
1587
1624
|
* @returns A {@link Result} with a {@link Success} and a value on success or an
|
|
1588
1625
|
* {@link Failure} with a a message on failure.
|
|
1589
1626
|
*/
|
|
1590
|
-
convert(from: unknown, context?: TC): Result<T>;
|
|
1627
|
+
convert(from: unknown, context?: TC, selfOverride?: Converter<T, TC>): Result<T>;
|
|
1591
1628
|
/**
|
|
1592
1629
|
* Converts from `unknown` to `<T>` or `undefined`, as appropriate.
|
|
1593
1630
|
*
|
|
@@ -2276,6 +2313,9 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
2276
2313
|
*
|
|
2277
2314
|
* If the source is not an object, the discriminator property is missing, or the discriminator has
|
|
2278
2315
|
* a value not present in the converters, conversion fails and returns {@link Failure | Failure} with more information.
|
|
2316
|
+
*
|
|
2317
|
+
* The `self` reference of the outer converter is threaded through to per-arm converter invocations,
|
|
2318
|
+
* enabling recursive discriminated-union parsers where arms recurse via `self`.
|
|
2279
2319
|
* @param discriminatorProp - Name of the property used to discriminate types.
|
|
2280
2320
|
* @param converters - {@link Converters.DiscriminatedObjectConverters | String-keyed record of converters and validators}
|
|
2281
2321
|
* to invoke, where each key corresponds to a value of the discriminator property.
|
|
@@ -4005,6 +4045,63 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
4005
4045
|
*/
|
|
4006
4046
|
export declare type IResultValueType<T> = T extends IResult<infer TV> ? TV : never;
|
|
4007
4047
|
|
|
4048
|
+
/**
|
|
4049
|
+
* Minimal structural contract a {@link RetainingRingBuffer} record must satisfy:
|
|
4050
|
+
* a monotonic `seq` the buffer pages on. Records carry their own `seq` (assigned
|
|
4051
|
+
* by the caller) so the buffer is agnostic about how records are minted — a logger
|
|
4052
|
+
* assigns `seq` from its own counter, an observability layer assigns a library-global
|
|
4053
|
+
* `seq` shared across several buffers, etc.
|
|
4054
|
+
* @public
|
|
4055
|
+
*/
|
|
4056
|
+
export declare interface IRetainedRecord {
|
|
4057
|
+
/**
|
|
4058
|
+
* Monotonic sequence number, assigned by the caller. The buffer requires
|
|
4059
|
+
* **strictly increasing** `seq` across successive {@link RetainingRingBuffer.push | push}
|
|
4060
|
+
* calls — `sinceSeq` cursor paging uses a strict `seq > sinceSeq` filter, so
|
|
4061
|
+
* duplicate `seq` values held by a consumer cursor would never be re-yielded
|
|
4062
|
+
* if pushed afterward. {@link RetainingRingBuffer.lastSeq | lastSeq} likewise
|
|
4063
|
+
* advances only past values strictly greater than its current value.
|
|
4064
|
+
*/
|
|
4065
|
+
readonly seq: number;
|
|
4066
|
+
}
|
|
4067
|
+
|
|
4068
|
+
/**
|
|
4069
|
+
* Construction options for {@link RetainingRingBuffer}.
|
|
4070
|
+
* @public
|
|
4071
|
+
*/
|
|
4072
|
+
export declare interface IRetainingRingBufferCreateParams {
|
|
4073
|
+
/**
|
|
4074
|
+
* The maximum number of records retained before the oldest is overwritten.
|
|
4075
|
+
* Defaults to `1000`. Normalized to a positive integer: a fractional value is
|
|
4076
|
+
* floored toward the integer below (`2.9` → `2`), and a non-finite or sub-1
|
|
4077
|
+
* value is floored to `1` (the ring requires a positive integer capacity to
|
|
4078
|
+
* be well-defined).
|
|
4079
|
+
*/
|
|
4080
|
+
readonly maxRecords?: number;
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
/**
|
|
4084
|
+
* Query options for {@link RetainingRingBuffer.query}.
|
|
4085
|
+
* @public
|
|
4086
|
+
*/
|
|
4087
|
+
export declare interface IRetainingRingBufferQuery<T extends IRetainedRecord> {
|
|
4088
|
+
/**
|
|
4089
|
+
* If supplied, only records with `seq > sinceSeq` are returned, enabling
|
|
4090
|
+
* incremental paging from a previously-held cursor.
|
|
4091
|
+
*/
|
|
4092
|
+
readonly sinceSeq?: number;
|
|
4093
|
+
/**
|
|
4094
|
+
* If supplied, returns at most this many records — the most recent N (tail),
|
|
4095
|
+
* still ordered oldest-first.
|
|
4096
|
+
*/
|
|
4097
|
+
readonly limit?: number;
|
|
4098
|
+
/**
|
|
4099
|
+
* If supplied, only records for which the predicate returns `true` are
|
|
4100
|
+
* returned. Applied before `limit`, so `limit` bounds the filtered tail.
|
|
4101
|
+
*/
|
|
4102
|
+
readonly filter?: (record: T) => boolean;
|
|
4103
|
+
}
|
|
4104
|
+
|
|
4008
4105
|
/**
|
|
4009
4106
|
* Helper function to create a {@link Converter | Converter} from a supplied type guard function.
|
|
4010
4107
|
* @param description - a description of the thing to be validated for use in error messages
|
|
@@ -5958,40 +6055,25 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
5958
6055
|
* @public
|
|
5959
6056
|
*/
|
|
5960
6057
|
declare class RetainingLogger extends LoggerBase {
|
|
5961
|
-
/**
|
|
5962
|
-
* The fixed ring capacity — the maximum number of records retained before the
|
|
5963
|
-
* oldest is overwritten. A positive integer (see the constructor normalization).
|
|
5964
|
-
* @internal
|
|
5965
|
-
*/
|
|
5966
|
-
private readonly _capacity;
|
|
5967
6058
|
/**
|
|
5968
6059
|
* Injected clock used to timestamp records.
|
|
5969
6060
|
* @internal
|
|
5970
6061
|
*/
|
|
5971
6062
|
private readonly _now;
|
|
5972
6063
|
/**
|
|
5973
|
-
* The
|
|
5974
|
-
*
|
|
5975
|
-
*
|
|
6064
|
+
* The monotonic sequence counter. The logger owns `seq` assignment and
|
|
6065
|
+
* increments this before each push so the buffer receives strictly increasing
|
|
6066
|
+
* sequence numbers.
|
|
5976
6067
|
* @internal
|
|
5977
6068
|
*/
|
|
5978
|
-
private
|
|
5979
|
-
/**
|
|
5980
|
-
* Index of the oldest retained record within `_buffer` once the ring is full.
|
|
5981
|
-
* @internal
|
|
5982
|
-
*/
|
|
5983
|
-
private _head;
|
|
6069
|
+
private _nextSeq;
|
|
5984
6070
|
/**
|
|
5985
|
-
* The
|
|
6071
|
+
* The backing ring buffer. Retains up to `maxRecords` log records, evicting
|
|
6072
|
+
* the oldest when full. The buffer is a pure seq-ring — it does not assign
|
|
6073
|
+
* `seq`; the logger does.
|
|
5986
6074
|
* @internal
|
|
5987
6075
|
*/
|
|
5988
|
-
private
|
|
5989
|
-
/**
|
|
5990
|
-
* The most recently assigned sequence number; monotonic, stable across eviction
|
|
5991
|
-
* and {@link Logging.RetainingLogger.clear | clear()}.
|
|
5992
|
-
* @internal
|
|
5993
|
-
*/
|
|
5994
|
-
private _lastSeq;
|
|
6076
|
+
private readonly _ring;
|
|
5995
6077
|
/**
|
|
5996
6078
|
* Creates a new retaining logger.
|
|
5997
6079
|
* @param logLevel - The level of logging to retain. Defaults to `'detail'` to capture
|
|
@@ -6020,11 +6102,6 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
6020
6102
|
* holding a `sinceSeq` cursor never re-sees a sequence number.
|
|
6021
6103
|
*/
|
|
6022
6104
|
clear(): void;
|
|
6023
|
-
/**
|
|
6024
|
-
* Materializes the ring into a plain oldest-first array.
|
|
6025
|
-
* @internal
|
|
6026
|
-
*/
|
|
6027
|
-
private _toOrderedArray;
|
|
6028
6105
|
/**
|
|
6029
6106
|
* {@inheritDoc Logging.LoggerBase._logStructured}
|
|
6030
6107
|
* @internal
|
|
@@ -6037,6 +6114,99 @@ declare class Collectible<TKEY extends string = string, TINDEX extends number =
|
|
|
6037
6114
|
protected _log(message: string, __level: MessageLogLevel): Success<string | undefined>;
|
|
6038
6115
|
}
|
|
6039
6116
|
|
|
6117
|
+
/**
|
|
6118
|
+
* A generic bounded most-recent-N ring of records, with monotonic-`seq` cursor
|
|
6119
|
+
* paging and predicate filtering.
|
|
6120
|
+
*
|
|
6121
|
+
* @remarks
|
|
6122
|
+
* The buffer is a pure storage substrate: the caller mints each record (assigning
|
|
6123
|
+
* its own `seq` and any other fields) and {@link RetainingRingBuffer.push | push}es
|
|
6124
|
+
* it. The buffer never reshapes a record — it only retains, evicts the oldest when
|
|
6125
|
+
* full (O(1), no `shift()` re-indexing regardless of capacity), and answers queries.
|
|
6126
|
+
*
|
|
6127
|
+
* Separating record minting from retention lets one `seq` authority feed several
|
|
6128
|
+
* buffers consistently (e.g. an observability layer that assigns a library-global
|
|
6129
|
+
* `seq` and fans the same record out to multiple retaining stores), and lets a
|
|
6130
|
+
* single-authority consumer (e.g. a logger) own its own `seq` counter. It is the
|
|
6131
|
+
* shared mechanism beneath `RetainingLogger` and
|
|
6132
|
+
* any schema-aware observation store.
|
|
6133
|
+
*
|
|
6134
|
+
* @public
|
|
6135
|
+
*/
|
|
6136
|
+
export declare class RetainingRingBuffer<T extends IRetainedRecord> {
|
|
6137
|
+
/**
|
|
6138
|
+
* The fixed ring capacity — the maximum number of records retained before the
|
|
6139
|
+
* oldest is overwritten. A positive integer (see the constructor normalization).
|
|
6140
|
+
* @internal
|
|
6141
|
+
*/
|
|
6142
|
+
private readonly _capacity;
|
|
6143
|
+
/**
|
|
6144
|
+
* The backing store, used as a circular buffer. Grows lazily up to `_capacity`,
|
|
6145
|
+
* after which records overwrite the oldest slot in place — eviction is O(1), with
|
|
6146
|
+
* no `shift()` re-indexing regardless of capacity.
|
|
6147
|
+
* @internal
|
|
6148
|
+
*/
|
|
6149
|
+
private _buffer;
|
|
6150
|
+
/**
|
|
6151
|
+
* Index of the oldest retained record within `_buffer` once the ring is full.
|
|
6152
|
+
* @internal
|
|
6153
|
+
*/
|
|
6154
|
+
private _head;
|
|
6155
|
+
/**
|
|
6156
|
+
* The number of valid records currently retained (`<= _capacity`).
|
|
6157
|
+
* @internal
|
|
6158
|
+
*/
|
|
6159
|
+
private _count;
|
|
6160
|
+
/**
|
|
6161
|
+
* The highest `seq` ever pushed; monotonic, stable across eviction and
|
|
6162
|
+
* {@link RetainingRingBuffer.clear | clear()}.
|
|
6163
|
+
* @internal
|
|
6164
|
+
*/
|
|
6165
|
+
private _lastSeq;
|
|
6166
|
+
/**
|
|
6167
|
+
* Creates a new retaining ring buffer.
|
|
6168
|
+
* @param params - {@link IRetainingRingBufferCreateParams | Construction options}.
|
|
6169
|
+
*/
|
|
6170
|
+
constructor(params?: IRetainingRingBufferCreateParams);
|
|
6171
|
+
/**
|
|
6172
|
+
* The number of records currently retained.
|
|
6173
|
+
*/
|
|
6174
|
+
get size(): number;
|
|
6175
|
+
/**
|
|
6176
|
+
* The highest `seq` pushed so far. A client can hold this value and pass it as
|
|
6177
|
+
* `sinceSeq` to page only records pushed afterward. Stable across eviction and
|
|
6178
|
+
* {@link RetainingRingBuffer.clear | clear()}.
|
|
6179
|
+
*/
|
|
6180
|
+
get lastSeq(): number;
|
|
6181
|
+
/**
|
|
6182
|
+
* The retained records, oldest-first.
|
|
6183
|
+
*/
|
|
6184
|
+
get records(): ReadonlyArray<T>;
|
|
6185
|
+
/**
|
|
6186
|
+
* Retains a record, evicting the oldest if the ring is full.
|
|
6187
|
+
* @param record - The record to retain. Its `seq` should be greater than the
|
|
6188
|
+
* `seq` of the previously-pushed record so cursor paging stays monotonic.
|
|
6189
|
+
* @returns The same record, for call-site chaining.
|
|
6190
|
+
*/
|
|
6191
|
+
push(record: T): T;
|
|
6192
|
+
/**
|
|
6193
|
+
* Returns retained records, oldest-first, optionally filtered and paged.
|
|
6194
|
+
* @param query - {@link IRetainingRingBufferQuery | Filtering and paging options}.
|
|
6195
|
+
* @returns The matching records, oldest-first.
|
|
6196
|
+
*/
|
|
6197
|
+
query(query?: IRetainingRingBufferQuery<T>): ReadonlyArray<T>;
|
|
6198
|
+
/**
|
|
6199
|
+
* Clears all retained records. Does NOT reset {@link RetainingRingBuffer.lastSeq | lastSeq},
|
|
6200
|
+
* so a client holding a `sinceSeq` cursor never re-sees a sequence number.
|
|
6201
|
+
*/
|
|
6202
|
+
clear(): void;
|
|
6203
|
+
/**
|
|
6204
|
+
* Materializes the ring into a plain oldest-first array.
|
|
6205
|
+
* @internal
|
|
6206
|
+
*/
|
|
6207
|
+
private _toOrderedArray;
|
|
6208
|
+
}
|
|
6209
|
+
|
|
6040
6210
|
/**
|
|
6041
6211
|
* Compares two log levels.
|
|
6042
6212
|
* @param message - The first log level.
|
package/lib/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import * as Conversion from './packlets/conversion';
|
|
|
3
3
|
import * as Hash from './packlets/hash';
|
|
4
4
|
import * as Logging from './packlets/logging';
|
|
5
5
|
import * as Validation from './packlets/validation';
|
|
6
|
-
import { AggregatedResultMap, Collector, ICollectible, ConvertingCollector, IReadOnlyResultMap, ResultMap, ValidatingCollector, ValidatingConvertingCollector, ValidatingResultMap } from './packlets/collections';
|
|
6
|
+
import { AggregatedResultMap, Collector, ICollectible, ConvertingCollector, IReadOnlyResultMap, IRetainedRecord, IRetainingRingBufferCreateParams, IRetainingRingBufferQuery, ResultMap, RetainingRingBuffer, ValidatingCollector, ValidatingConvertingCollector, ValidatingResultMap } from './packlets/collections';
|
|
7
7
|
import { Converter, Converters, ObjectConverter, StringConverter } from './packlets/conversion';
|
|
8
8
|
import { Validator, Validators } from './packlets/validation';
|
|
9
9
|
export * from './packlets/base';
|
|
10
|
-
export { AggregatedResultMap, Collections, Collector, ConvertingCollector, Conversion, Converter, Converters, Hash, ICollectible, IReadOnlyResultMap, Logging, ObjectConverter, ResultMap, StringConverter, ValidatingCollector, ValidatingConvertingCollector, ValidatingResultMap, Validation, Validator, Validators };
|
|
10
|
+
export { AggregatedResultMap, Collections, Collector, ConvertingCollector, Conversion, Converter, Converters, Hash, ICollectible, IReadOnlyResultMap, Logging, IRetainedRecord, IRetainingRingBufferCreateParams, IRetainingRingBufferQuery, ObjectConverter, ResultMap, RetainingRingBuffer, StringConverter, ValidatingCollector, ValidatingConvertingCollector, ValidatingResultMap, Validation, Validator, Validators };
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,EACT,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE9D,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,gCAAgC,EAChC,yBAAyB,EACzB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE9D,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACV,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,gCAAgC,EAChC,yBAAyB,EACzB,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,UAAU,EACX,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -57,7 +57,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
57
57
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
58
58
|
};
|
|
59
59
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
|
-
exports.Validators = exports.Validation = exports.ValidatingResultMap = exports.ValidatingConvertingCollector = exports.ValidatingCollector = exports.StringConverter = exports.ResultMap = exports.ObjectConverter = exports.Logging = exports.Hash = exports.Converters = exports.Conversion = exports.ConvertingCollector = exports.Collector = exports.Collections = exports.AggregatedResultMap = void 0;
|
|
60
|
+
exports.Validators = exports.Validation = exports.ValidatingResultMap = exports.ValidatingConvertingCollector = exports.ValidatingCollector = exports.StringConverter = exports.RetainingRingBuffer = exports.ResultMap = exports.ObjectConverter = exports.Logging = exports.Hash = exports.Converters = exports.Conversion = exports.ConvertingCollector = exports.Collector = exports.Collections = exports.AggregatedResultMap = void 0;
|
|
61
61
|
const Collections = __importStar(require("./packlets/collections"));
|
|
62
62
|
exports.Collections = Collections;
|
|
63
63
|
const Conversion = __importStar(require("./packlets/conversion"));
|
|
@@ -73,6 +73,7 @@ Object.defineProperty(exports, "AggregatedResultMap", { enumerable: true, get: f
|
|
|
73
73
|
Object.defineProperty(exports, "Collector", { enumerable: true, get: function () { return collections_1.Collector; } });
|
|
74
74
|
Object.defineProperty(exports, "ConvertingCollector", { enumerable: true, get: function () { return collections_1.ConvertingCollector; } });
|
|
75
75
|
Object.defineProperty(exports, "ResultMap", { enumerable: true, get: function () { return collections_1.ResultMap; } });
|
|
76
|
+
Object.defineProperty(exports, "RetainingRingBuffer", { enumerable: true, get: function () { return collections_1.RetainingRingBuffer; } });
|
|
76
77
|
Object.defineProperty(exports, "ValidatingCollector", { enumerable: true, get: function () { return collections_1.ValidatingCollector; } });
|
|
77
78
|
Object.defineProperty(exports, "ValidatingConvertingCollector", { enumerable: true, get: function () { return collections_1.ValidatingConvertingCollector; } });
|
|
78
79
|
Object.defineProperty(exports, "ValidatingResultMap", { enumerable: true, get: function () { return collections_1.ValidatingResultMap; } });
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,oEAAsD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,oEAAsD;AA2BpD,kCAAW;AA1Bb,kEAAoD;AA6BlD,gCAAU;AA5BZ,sDAAwC;AA+BtC,oBAAI;AA9BN,4DAA8C;AAiC5C,0BAAO;AAhCT,kEAAoD;AA2ClD,gCAAU;AAzCZ,wDAcgC;AAM9B,oGAnBA,iCAAmB,OAmBA;AAEnB,0FApBA,uBAAS,OAoBA;AACT,oGAnBA,iCAAmB,OAmBA;AAYnB,0FA1BA,uBAAS,OA0BA;AACT,oGA1BA,iCAAmB,OA0BA;AAEnB,oGA3BA,iCAAmB,OA2BA;AACnB,8GA3BA,2CAA6B,OA2BA;AAC7B,oGA3BA,iCAAmB,OA2BA;AAzBrB,sDAAgG;AAW9F,2FAXkB,uBAAU,OAWlB;AAQV,gGAnB8B,4BAAe,OAmB9B;AAGf,gGAtB+C,4BAAe,OAsB/C;AArBjB,sDAA8D;AA2B5D,2FA3BkB,uBAAU,OA2BlB;AAzBZ,kDAAgC","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Collections from './packlets/collections';\nimport * as Conversion from './packlets/conversion';\nimport * as Hash from './packlets/hash';\nimport * as Logging from './packlets/logging';\nimport * as Validation from './packlets/validation';\n\nimport {\n AggregatedResultMap,\n Collector,\n ICollectible,\n ConvertingCollector,\n IReadOnlyResultMap,\n IRetainedRecord,\n IRetainingRingBufferCreateParams,\n IRetainingRingBufferQuery,\n ResultMap,\n RetainingRingBuffer,\n ValidatingCollector,\n ValidatingConvertingCollector,\n ValidatingResultMap\n} from './packlets/collections';\nimport { Converter, Converters, ObjectConverter, StringConverter } from './packlets/conversion';\nimport { Validator, Validators } from './packlets/validation';\n\nexport * from './packlets/base';\nexport {\n AggregatedResultMap,\n Collections,\n Collector,\n ConvertingCollector,\n Conversion,\n Converter,\n Converters,\n Hash,\n ICollectible,\n IReadOnlyResultMap,\n Logging,\n IRetainedRecord,\n IRetainingRingBufferCreateParams,\n IRetainingRingBufferQuery,\n ObjectConverter,\n ResultMap,\n RetainingRingBuffer,\n StringConverter,\n ValidatingCollector,\n ValidatingConvertingCollector,\n ValidatingResultMap,\n Validation,\n Validator,\n Validators\n};\n"]}
|
|
@@ -915,16 +915,27 @@ export declare function _errorMessage(err: unknown): string;
|
|
|
915
915
|
export declare function captureResult<T>(func: () => T): Result<T>;
|
|
916
916
|
/**
|
|
917
917
|
* Async continuation callback to be called in the event that a
|
|
918
|
-
* {@link Result} is successful, returning a `
|
|
918
|
+
* {@link Result} is successful, returning a `PromiseLike` of a new
|
|
919
|
+
* {@link Result}.
|
|
920
|
+
* @remarks
|
|
921
|
+
* Typed as `PromiseLike<Result<TN>>` rather than `Promise<Result<TN>>` so
|
|
922
|
+
* callers can return the result of {@link captureAsyncResult} (which is an
|
|
923
|
+
* {@link AsyncResult}, itself a `PromiseLike<Result<TN>>`) directly from a
|
|
924
|
+
* `thenOnSuccess` callback without an `async` wrapper to coerce the
|
|
925
|
+
* contextual return type back through `Awaited<>`. The continuation result
|
|
926
|
+
* is always wrapped into an {@link AsyncResult}, so chaining is unaffected.
|
|
919
927
|
* @public
|
|
920
928
|
*/
|
|
921
|
-
export type AsyncSuccessContinuation<T, TN> = (value: T) =>
|
|
929
|
+
export type AsyncSuccessContinuation<T, TN> = (value: T) => PromiseLike<Result<TN>>;
|
|
922
930
|
/**
|
|
923
931
|
* Async continuation callback to be called in the event that a
|
|
924
|
-
* {@link Result} fails, returning a `
|
|
932
|
+
* {@link Result} fails, returning a `PromiseLike` of a new {@link Result}.
|
|
933
|
+
* @remarks
|
|
934
|
+
* See {@link AsyncSuccessContinuation} for the rationale behind accepting
|
|
935
|
+
* any `PromiseLike<Result<T>>` rather than only a `Promise<Result<T>>`.
|
|
925
936
|
* @public
|
|
926
937
|
*/
|
|
927
|
-
export type AsyncFailureContinuation<T> = (message: string) =>
|
|
938
|
+
export type AsyncFailureContinuation<T> = (message: string) => PromiseLike<Result<T>>;
|
|
928
939
|
/**
|
|
929
940
|
* Wraps a `Promise` of a {@link Result} to enable fluent chaining of both
|
|
930
941
|
* synchronous and asynchronous operations.
|
|
@@ -948,14 +959,17 @@ export type AsyncFailureContinuation<T> = (message: string) => Promise<Result<T>
|
|
|
948
959
|
export declare class AsyncResult<T> implements PromiseLike<Result<T>> {
|
|
949
960
|
private readonly _promise;
|
|
950
961
|
/**
|
|
951
|
-
* Constructs an {@link AsyncResult} wrapping the supplied promise
|
|
962
|
+
* Constructs an {@link AsyncResult} wrapping the supplied promise (or any
|
|
963
|
+
* `PromiseLike` that resolves to a {@link Result}, such as another
|
|
964
|
+
* {@link AsyncResult}).
|
|
952
965
|
* @remarks
|
|
953
966
|
* If the supplied promise rejects, the rejection is caught and converted
|
|
954
967
|
* to a {@link Failure}, ensuring that awaiting an {@link AsyncResult} always
|
|
955
968
|
* yields a {@link Result}.
|
|
956
|
-
* @param promise - A `Promise` that resolves to a
|
|
969
|
+
* @param promise - A `Promise` (or `PromiseLike`) that resolves to a
|
|
970
|
+
* {@link Result}.
|
|
957
971
|
*/
|
|
958
|
-
constructor(promise:
|
|
972
|
+
constructor(promise: PromiseLike<Result<T>>);
|
|
959
973
|
/**
|
|
960
974
|
* Calls a supplied {@link SuccessContinuation | success continuation} if
|
|
961
975
|
* the wrapped result is successful.
|
|
@@ -1038,10 +1052,23 @@ export declare class AsyncResult<T> implements PromiseLike<Result<T>> {
|
|
|
1038
1052
|
/**
|
|
1039
1053
|
* Wraps an async function which might throw to convert exception results
|
|
1040
1054
|
* to {@link Failure}.
|
|
1055
|
+
* @remarks
|
|
1056
|
+
* Returns an {@link AsyncResult} so callers can fluently chain
|
|
1057
|
+
* (`.onSuccess` / `.thenOnSuccess` / `.withErrorFormat`) directly off the
|
|
1058
|
+
* captured result. Because {@link AsyncResult} implements
|
|
1059
|
+
* `PromiseLike<Result<T>>`, existing `await captureAsyncResult(...)` call
|
|
1060
|
+
* sites continue to work unchanged and yield the same {@link Result}.
|
|
1061
|
+
*
|
|
1062
|
+
* Synchronous throws from `func` (before it returns its `Promise`), promise
|
|
1063
|
+
* rejections, and successful resolutions are all funneled through the
|
|
1064
|
+
* returned {@link AsyncResult}, which resolves to a {@link Failure} for the
|
|
1065
|
+
* throw/reject cases and a {@link Success} wrapping the resolved value
|
|
1066
|
+
* otherwise.
|
|
1041
1067
|
* @param func - The async function to be captured.
|
|
1042
|
-
* @returns
|
|
1043
|
-
* success, or {@link Failure} with the thrown error message
|
|
1068
|
+
* @returns An {@link AsyncResult} resolving to {@link Success} with a value
|
|
1069
|
+
* of type `<T>` on success, or {@link Failure} with the thrown error message
|
|
1070
|
+
* if `func` throws or rejects.
|
|
1044
1071
|
* @public
|
|
1045
1072
|
*/
|
|
1046
|
-
export declare function captureAsyncResult<T>(func: () => Promise<T>):
|
|
1073
|
+
export declare function captureAsyncResult<T>(func: () => Promise<T>): AsyncResult<T>;
|
|
1047
1074
|
//# sourceMappingURL=result.d.ts.map
|