@mihari/logger-core 0.1.0 → 0.2.0
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.d.mts +122 -0
- package/dist/index.d.ts +122 -7
- package/dist/index.js +319 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +289 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +30 -6
- package/dist/batcher.d.ts +0 -32
- package/dist/batcher.d.ts.map +0 -1
- package/dist/batcher.js +0 -85
- package/dist/batcher.js.map +0 -1
- package/dist/client.d.ts +0 -53
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -98
- package/dist/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/transport.d.ts +0 -21
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -81
- package/dist/transport.js.map +0 -1
- package/dist/utils.d.ts +0 -17
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -35
- package/dist/utils.js.map +0 -1
- package/src/index.ts +0 -15
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { LogLevel } from "@mihari/logger-types";
|
|
3
|
+
|
|
4
|
+
// src/utils.ts
|
|
5
|
+
function isoTimestamp() {
|
|
6
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7
|
+
}
|
|
8
|
+
function isBrowser() {
|
|
9
|
+
return typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined" && typeof globalThis.document !== "undefined";
|
|
10
|
+
}
|
|
11
|
+
function isNode() {
|
|
12
|
+
return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
13
|
+
}
|
|
14
|
+
function sleep(ms) {
|
|
15
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/transport.ts
|
|
19
|
+
var DEFAULT_RETRIES = 3;
|
|
20
|
+
var RETRY_BASE_DELAY_MS = 1e3;
|
|
21
|
+
var HttpTransport = class {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.compressFn = null;
|
|
24
|
+
this.token = options.token;
|
|
25
|
+
this.endpoint = options.endpoint.replace(/\/+$/, "");
|
|
26
|
+
this.compression = options.compression ?? true;
|
|
27
|
+
this.maxRetries = options.retries ?? DEFAULT_RETRIES;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Sets the compression function. This allows node and browser
|
|
31
|
+
* environments to inject their own gzip implementation.
|
|
32
|
+
*/
|
|
33
|
+
setCompressFn(fn) {
|
|
34
|
+
this.compressFn = fn;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Sends an array of log entries to the ingestion endpoint with
|
|
38
|
+
* retry logic using exponential backoff.
|
|
39
|
+
*/
|
|
40
|
+
async send(logs) {
|
|
41
|
+
const payload = JSON.stringify(logs);
|
|
42
|
+
let body = payload;
|
|
43
|
+
const headers = {
|
|
44
|
+
"Authorization": `Bearer ${this.token}`,
|
|
45
|
+
"Content-Type": "application/json"
|
|
46
|
+
};
|
|
47
|
+
if (this.compression && this.compressFn) {
|
|
48
|
+
const encoded = new TextEncoder().encode(payload);
|
|
49
|
+
body = await this.compressFn(encoded);
|
|
50
|
+
headers["Content-Encoding"] = "gzip";
|
|
51
|
+
}
|
|
52
|
+
let lastError = null;
|
|
53
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
54
|
+
try {
|
|
55
|
+
const response = await this.doFetch(body, headers);
|
|
56
|
+
if (response.status === 202) {
|
|
57
|
+
return response.json;
|
|
58
|
+
}
|
|
59
|
+
if (response.status === 401) {
|
|
60
|
+
throw new Error("Invalid or missing authentication token");
|
|
61
|
+
}
|
|
62
|
+
if (response.status === 400) {
|
|
63
|
+
throw new Error("No valid logs found");
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Unexpected response status: ${response.status}`);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
68
|
+
if (lastError.message === "Invalid or missing authentication token" || lastError.message === "No valid logs found") {
|
|
69
|
+
throw lastError;
|
|
70
|
+
}
|
|
71
|
+
if (attempt < this.maxRetries - 1) {
|
|
72
|
+
const delay = RETRY_BASE_DELAY_MS * Math.pow(2, attempt);
|
|
73
|
+
await sleep(delay);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
throw lastError ?? new Error("Transport failed after retries");
|
|
78
|
+
}
|
|
79
|
+
async doFetch(body, headers) {
|
|
80
|
+
const res = await fetch(`${this.endpoint}`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers,
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
body
|
|
85
|
+
});
|
|
86
|
+
const json = await res.json().catch(() => ({}));
|
|
87
|
+
return { status: res.status, json };
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/batcher.ts
|
|
92
|
+
var DEFAULT_BATCH_SIZE = 10;
|
|
93
|
+
var DEFAULT_FLUSH_INTERVAL_MS = 5e3;
|
|
94
|
+
var DEFAULT_MAX_QUEUE_SIZE = 1e3;
|
|
95
|
+
var Batcher = class {
|
|
96
|
+
constructor(options, onFlush) {
|
|
97
|
+
this.queue = [];
|
|
98
|
+
this.timer = null;
|
|
99
|
+
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
100
|
+
this.flushIntervalMs = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
101
|
+
this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;
|
|
102
|
+
this.onFlush = onFlush;
|
|
103
|
+
this.startTimer();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Adds a log entry to the queue. Triggers a flush if the
|
|
107
|
+
* batch size threshold is reached.
|
|
108
|
+
*/
|
|
109
|
+
add(entry) {
|
|
110
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
111
|
+
this.queue.shift();
|
|
112
|
+
}
|
|
113
|
+
this.queue = [...this.queue, entry];
|
|
114
|
+
if (this.queue.length >= this.batchSize) {
|
|
115
|
+
void this.flush();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Flushes all queued log entries by calling the onFlush callback.
|
|
120
|
+
* Returns a promise that resolves when the flush is complete.
|
|
121
|
+
*/
|
|
122
|
+
async flush() {
|
|
123
|
+
if (this.queue.length === 0) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const batch = [...this.queue];
|
|
127
|
+
this.queue = [];
|
|
128
|
+
try {
|
|
129
|
+
await this.onFlush(batch);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
const combined = [...batch, ...this.queue];
|
|
132
|
+
this.queue = combined.slice(0, this.maxQueueSize);
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns the number of entries currently in the queue.
|
|
138
|
+
*/
|
|
139
|
+
get size() {
|
|
140
|
+
return this.queue.length;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Stops the periodic flush timer and flushes remaining entries.
|
|
144
|
+
*/
|
|
145
|
+
async shutdown() {
|
|
146
|
+
this.stopTimer();
|
|
147
|
+
await this.flush();
|
|
148
|
+
}
|
|
149
|
+
startTimer() {
|
|
150
|
+
if (this.flushIntervalMs > 0) {
|
|
151
|
+
this.timer = setInterval(() => {
|
|
152
|
+
void this.flush();
|
|
153
|
+
}, this.flushIntervalMs);
|
|
154
|
+
if (typeof this.timer === "object" && "unref" in this.timer) {
|
|
155
|
+
this.timer.unref();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
stopTimer() {
|
|
160
|
+
if (this.timer !== null) {
|
|
161
|
+
clearInterval(this.timer);
|
|
162
|
+
this.timer = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/client.ts
|
|
168
|
+
var MihariClient = class {
|
|
169
|
+
constructor(config) {
|
|
170
|
+
this.config = config;
|
|
171
|
+
this.transport = new HttpTransport({
|
|
172
|
+
token: config.token,
|
|
173
|
+
endpoint: config.endpoint,
|
|
174
|
+
compression: config.compression,
|
|
175
|
+
retries: config.retries
|
|
176
|
+
});
|
|
177
|
+
this.batcher = new Batcher(
|
|
178
|
+
{
|
|
179
|
+
batchSize: config.batchSize,
|
|
180
|
+
flushInterval: config.flushInterval,
|
|
181
|
+
maxQueueSize: config.maxQueueSize
|
|
182
|
+
},
|
|
183
|
+
async (logs) => {
|
|
184
|
+
await this.transport.send(logs);
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Sets the compression function used by the transport layer.
|
|
190
|
+
*/
|
|
191
|
+
setCompressFn(fn) {
|
|
192
|
+
this.transport.setCompressFn(fn);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Logs a debug-level message.
|
|
196
|
+
*/
|
|
197
|
+
debug(message, metadata) {
|
|
198
|
+
this.log(LogLevel.Debug, message, metadata);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Logs an info-level message.
|
|
202
|
+
*/
|
|
203
|
+
info(message, metadata) {
|
|
204
|
+
this.log(LogLevel.Info, message, metadata);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Logs a warn-level message.
|
|
208
|
+
*/
|
|
209
|
+
warn(message, metadata) {
|
|
210
|
+
this.log(LogLevel.Warn, message, metadata);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Logs an error-level message.
|
|
214
|
+
*/
|
|
215
|
+
error(message, metadata) {
|
|
216
|
+
this.log(LogLevel.Error, message, metadata);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Logs a fatal-level message.
|
|
220
|
+
*/
|
|
221
|
+
fatal(message, metadata) {
|
|
222
|
+
this.log(LogLevel.Fatal, message, metadata);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Flushes all pending log entries.
|
|
226
|
+
*/
|
|
227
|
+
async flush() {
|
|
228
|
+
await this.batcher.flush();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Shuts down the client, flushing remaining entries.
|
|
232
|
+
*/
|
|
233
|
+
async shutdown() {
|
|
234
|
+
await this.batcher.shutdown();
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Creates a log entry and adds it to the batch queue.
|
|
238
|
+
* Subclasses can override getDefaultMetadata() to inject
|
|
239
|
+
* environment-specific fields.
|
|
240
|
+
*/
|
|
241
|
+
log(level, message, metadata) {
|
|
242
|
+
const entry = {
|
|
243
|
+
dt: isoTimestamp(),
|
|
244
|
+
level,
|
|
245
|
+
message,
|
|
246
|
+
...this.getDefaultMetadata(),
|
|
247
|
+
...this.config.metadata ?? {},
|
|
248
|
+
...metadata ?? {}
|
|
249
|
+
};
|
|
250
|
+
this.batcher.add(entry);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Returns default metadata to include with every log entry.
|
|
254
|
+
* Override in subclasses to add environment-specific fields.
|
|
255
|
+
*/
|
|
256
|
+
getDefaultMetadata() {
|
|
257
|
+
return {};
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// src/index.ts
|
|
262
|
+
import {
|
|
263
|
+
LogLevel as LogLevel2,
|
|
264
|
+
LogEntry as LogEntry2,
|
|
265
|
+
MihariConfig as MihariConfig2,
|
|
266
|
+
TransportOptions,
|
|
267
|
+
BatchOptions,
|
|
268
|
+
TransportResponse,
|
|
269
|
+
TransportError,
|
|
270
|
+
CompressFn as CompressFn2
|
|
271
|
+
} from "@mihari/logger-types";
|
|
272
|
+
export {
|
|
273
|
+
BatchOptions,
|
|
274
|
+
Batcher,
|
|
275
|
+
CompressFn2 as CompressFn,
|
|
276
|
+
HttpTransport,
|
|
277
|
+
LogEntry2 as LogEntry,
|
|
278
|
+
LogLevel2 as LogLevel,
|
|
279
|
+
MihariClient,
|
|
280
|
+
MihariConfig2 as MihariConfig,
|
|
281
|
+
TransportError,
|
|
282
|
+
TransportOptions,
|
|
283
|
+
TransportResponse,
|
|
284
|
+
isBrowser,
|
|
285
|
+
isNode,
|
|
286
|
+
isoTimestamp,
|
|
287
|
+
sleep
|
|
288
|
+
};
|
|
289
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/utils.ts","../src/transport.ts","../src/batcher.ts","../src/index.ts"],"sourcesContent":["import { LogLevel, LogEntry, MihariConfig, CompressFn } from \"@mihari/logger-types\";\nimport { HttpTransport } from \"./transport\";\nimport { Batcher } from \"./batcher\";\nimport { isoTimestamp } from \"./utils\";\n\nexport class MihariClient {\n protected readonly config: MihariConfig;\n protected readonly transport: HttpTransport;\n protected readonly batcher: Batcher;\n\n constructor(config: MihariConfig) {\n this.config = config;\n\n this.transport = new HttpTransport({\n token: config.token,\n endpoint: config.endpoint,\n compression: config.compression,\n retries: config.retries,\n });\n\n this.batcher = new Batcher(\n {\n batchSize: config.batchSize,\n flushInterval: config.flushInterval,\n maxQueueSize: config.maxQueueSize,\n },\n async (logs) => {\n await this.transport.send(logs);\n }\n );\n }\n\n /**\n * Sets the compression function used by the transport layer.\n */\n setCompressFn(fn: CompressFn): void {\n this.transport.setCompressFn(fn);\n }\n\n /**\n * Logs a debug-level message.\n */\n debug(message: string, metadata?: Record<string, unknown>): void {\n this.log(LogLevel.Debug, message, metadata);\n }\n\n /**\n * Logs an info-level message.\n */\n info(message: string, metadata?: Record<string, unknown>): void {\n this.log(LogLevel.Info, message, metadata);\n }\n\n /**\n * Logs a warn-level message.\n */\n warn(message: string, metadata?: Record<string, unknown>): void {\n this.log(LogLevel.Warn, message, metadata);\n }\n\n /**\n * Logs an error-level message.\n */\n error(message: string, metadata?: Record<string, unknown>): void {\n this.log(LogLevel.Error, message, metadata);\n }\n\n /**\n * Logs a fatal-level message.\n */\n fatal(message: string, metadata?: Record<string, unknown>): void {\n this.log(LogLevel.Fatal, message, metadata);\n }\n\n /**\n * Flushes all pending log entries.\n */\n async flush(): Promise<void> {\n await this.batcher.flush();\n }\n\n /**\n * Shuts down the client, flushing remaining entries.\n */\n async shutdown(): Promise<void> {\n await this.batcher.shutdown();\n }\n\n /**\n * Creates a log entry and adds it to the batch queue.\n * Subclasses can override getDefaultMetadata() to inject\n * environment-specific fields.\n */\n public log(\n level: LogLevel,\n message: string,\n metadata?: Record<string, unknown>\n ): void {\n const entry: LogEntry = {\n dt: isoTimestamp(),\n level,\n message,\n ...this.getDefaultMetadata(),\n ...(this.config.metadata ?? {}),\n ...(metadata ?? {}),\n };\n\n this.batcher.add(entry);\n }\n\n /**\n * Returns default metadata to include with every log entry.\n * Override in subclasses to add environment-specific fields.\n */\n protected getDefaultMetadata(): Record<string, unknown> {\n return {};\n }\n}\n","/**\n * Returns the current timestamp in ISO 8601 format.\n */\nexport function isoTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Detects whether the current runtime is a browser environment.\n */\nexport function isBrowser(): boolean {\n return (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as Record<string, unknown>).window !== \"undefined\" &&\n typeof (globalThis as Record<string, unknown>).document !== \"undefined\"\n );\n}\n\n/**\n * Detects whether the current runtime is Node.js.\n */\nexport function isNode(): boolean {\n return (\n typeof process !== \"undefined\" &&\n process.versions != null &&\n process.versions.node != null\n );\n}\n\n/**\n * Waits for the specified number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { LogEntry, TransportOptions, TransportResponse, CompressFn } from \"@mihari/logger-types\";\nimport { sleep } from \"./utils\";\n\nconst DEFAULT_RETRIES = 3;\nconst RETRY_BASE_DELAY_MS = 1000;\n\nexport class HttpTransport {\n private readonly token: string;\n private readonly endpoint: string;\n private readonly compression: boolean;\n private readonly maxRetries: number;\n private compressFn: CompressFn | null = null;\n\n constructor(options: TransportOptions) {\n this.token = options.token;\n this.endpoint = options.endpoint.replace(/\\/+$/, \"\");\n this.compression = options.compression ?? true;\n this.maxRetries = options.retries ?? DEFAULT_RETRIES;\n }\n\n /**\n * Sets the compression function. This allows node and browser\n * environments to inject their own gzip implementation.\n */\n setCompressFn(fn: CompressFn): void {\n this.compressFn = fn;\n }\n\n /**\n * Sends an array of log entries to the ingestion endpoint with\n * retry logic using exponential backoff.\n */\n async send(logs: readonly LogEntry[]): Promise<TransportResponse> {\n const payload = JSON.stringify(logs);\n let body: string | Uint8Array = payload;\n const headers: Record<string, string> = {\n \"Authorization\": `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n };\n\n if (this.compression && this.compressFn) {\n const encoded = new TextEncoder().encode(payload);\n body = await this.compressFn(encoded);\n headers[\"Content-Encoding\"] = \"gzip\";\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n try {\n const response = await this.doFetch(body, headers);\n\n if (response.status === 202) {\n return response.json as TransportResponse;\n }\n\n if (response.status === 401) {\n throw new Error(\"Invalid or missing authentication token\");\n }\n\n if (response.status === 400) {\n throw new Error(\"No valid logs found\");\n }\n\n throw new Error(`Unexpected response status: ${response.status}`);\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Do not retry auth or validation errors\n if (\n lastError.message === \"Invalid or missing authentication token\" ||\n lastError.message === \"No valid logs found\"\n ) {\n throw lastError;\n }\n\n if (attempt < this.maxRetries - 1) {\n const delay = RETRY_BASE_DELAY_MS * Math.pow(2, attempt);\n await sleep(delay);\n }\n }\n }\n\n throw lastError ?? new Error(\"Transport failed after retries\");\n }\n\n private async doFetch(\n body: string | Uint8Array,\n headers: Record<string, string>\n ): Promise<{ status: number; json: unknown }> {\n // Use global fetch (available in Node 18+ and all modern browsers)\n const res = await fetch(`${this.endpoint}`, {\n method: \"POST\",\n headers,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n body: body as any,\n });\n\n const json = await res.json().catch(() => ({}));\n return { status: res.status, json };\n }\n}\n","import { LogEntry, BatchOptions } from \"@mihari/logger-types\";\n\nconst DEFAULT_BATCH_SIZE = 10;\nconst DEFAULT_FLUSH_INTERVAL_MS = 5000;\nconst DEFAULT_MAX_QUEUE_SIZE = 1000;\n\nexport type FlushCallback = (logs: readonly LogEntry[]) => Promise<void>;\n\nexport class Batcher {\n private queue: LogEntry[] = [];\n private readonly batchSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxQueueSize: number;\n private readonly onFlush: FlushCallback;\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: BatchOptions, onFlush: FlushCallback) {\n this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;\n this.flushIntervalMs = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n this.onFlush = onFlush;\n this.startTimer();\n }\n\n /**\n * Adds a log entry to the queue. Triggers a flush if the\n * batch size threshold is reached.\n */\n add(entry: LogEntry): void {\n if (this.queue.length >= this.maxQueueSize) {\n // Drop the oldest entry when the queue is full\n this.queue.shift();\n }\n\n this.queue = [...this.queue, entry];\n\n if (this.queue.length >= this.batchSize) {\n void this.flush();\n }\n }\n\n /**\n * Flushes all queued log entries by calling the onFlush callback.\n * Returns a promise that resolves when the flush is complete.\n */\n async flush(): Promise<void> {\n if (this.queue.length === 0) {\n return;\n }\n\n const batch = [...this.queue];\n this.queue = [];\n\n try {\n await this.onFlush(batch);\n } catch (err) {\n // Re-add entries to the front of the queue on failure,\n // respecting the max queue size\n const combined = [...batch, ...this.queue];\n this.queue = combined.slice(0, this.maxQueueSize);\n // Rethrow so callers know the flush failed\n throw err;\n }\n }\n\n /**\n * Returns the number of entries currently in the queue.\n */\n get size(): number {\n return this.queue.length;\n }\n\n /**\n * Stops the periodic flush timer and flushes remaining entries.\n */\n async shutdown(): Promise<void> {\n this.stopTimer();\n await this.flush();\n }\n\n private startTimer(): void {\n if (this.flushIntervalMs > 0) {\n this.timer = setInterval(() => {\n void this.flush();\n }, this.flushIntervalMs);\n\n // Allow the Node.js process to exit even if the timer is active\n if (typeof this.timer === \"object\" && \"unref\" in this.timer) {\n this.timer.unref();\n }\n }\n }\n\n private stopTimer(): void {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","export { MihariClient } from \"./client\";\nexport { HttpTransport } from \"./transport\";\nexport { Batcher } from \"./batcher\";\nexport type { FlushCallback } from \"./batcher\";\nexport { isoTimestamp, isBrowser, isNode, sleep } from \"./utils\";\nexport {\n LogLevel,\n LogEntry,\n MihariConfig,\n TransportOptions,\n BatchOptions,\n TransportResponse,\n TransportError,\n CompressFn,\n} from \"@mihari/logger-types\";\n"],"mappings":"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","names":["LogLevel","LogEntry","MihariConfig","CompressFn"]}
|
package/package.json
CHANGED
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mihari/logger-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Core transport, batching, and client logic for mihari",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
7
15
|
"files": [
|
|
8
16
|
"dist"
|
|
9
17
|
],
|
|
10
18
|
"scripts": {
|
|
11
|
-
"build": "
|
|
19
|
+
"build": "tsup",
|
|
12
20
|
"clean": "rm -rf dist",
|
|
13
21
|
"test": "cd ../.. && npx vitest run --config vitest.config.ts packages/core"
|
|
14
22
|
},
|
|
23
|
+
"tsup": {
|
|
24
|
+
"entry": [
|
|
25
|
+
"src/index.ts"
|
|
26
|
+
],
|
|
27
|
+
"format": [
|
|
28
|
+
"cjs",
|
|
29
|
+
"esm"
|
|
30
|
+
],
|
|
31
|
+
"dts": true,
|
|
32
|
+
"splitting": false,
|
|
33
|
+
"sourcemap": true,
|
|
34
|
+
"clean": true,
|
|
35
|
+
"external": [
|
|
36
|
+
"@mihari/logger-types"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
15
39
|
"dependencies": {
|
|
16
|
-
"@mihari/logger-types": "^0.
|
|
40
|
+
"@mihari/logger-types": "^0.2.0"
|
|
17
41
|
},
|
|
18
42
|
"publishConfig": {
|
|
19
43
|
"access": "public"
|
|
@@ -24,5 +48,5 @@
|
|
|
24
48
|
"url": "https://github.com/mihari/mihari-js",
|
|
25
49
|
"directory": "packages/core"
|
|
26
50
|
},
|
|
27
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "a0a2dd591dafbf0923bb81bd5d8180fa6d6eecea"
|
|
28
52
|
}
|
package/dist/batcher.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { LogEntry, BatchOptions } from "@mihari/logger-types";
|
|
2
|
-
export type FlushCallback = (logs: readonly LogEntry[]) => Promise<void>;
|
|
3
|
-
export declare class Batcher {
|
|
4
|
-
private queue;
|
|
5
|
-
private readonly batchSize;
|
|
6
|
-
private readonly flushIntervalMs;
|
|
7
|
-
private readonly maxQueueSize;
|
|
8
|
-
private readonly onFlush;
|
|
9
|
-
private timer;
|
|
10
|
-
constructor(options: BatchOptions, onFlush: FlushCallback);
|
|
11
|
-
/**
|
|
12
|
-
* Adds a log entry to the queue. Triggers a flush if the
|
|
13
|
-
* batch size threshold is reached.
|
|
14
|
-
*/
|
|
15
|
-
add(entry: LogEntry): void;
|
|
16
|
-
/**
|
|
17
|
-
* Flushes all queued log entries by calling the onFlush callback.
|
|
18
|
-
* Returns a promise that resolves when the flush is complete.
|
|
19
|
-
*/
|
|
20
|
-
flush(): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Returns the number of entries currently in the queue.
|
|
23
|
-
*/
|
|
24
|
-
get size(): number;
|
|
25
|
-
/**
|
|
26
|
-
* Stops the periodic flush timer and flushes remaining entries.
|
|
27
|
-
*/
|
|
28
|
-
shutdown(): Promise<void>;
|
|
29
|
-
private startTimer;
|
|
30
|
-
private stopTimer;
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=batcher.d.ts.map
|
package/dist/batcher.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAM9D,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE,qBAAa,OAAO;IAClB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,KAAK,CAA+C;gBAEhD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa;IAQzD;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAa1B;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,SAAS;CAMlB"}
|
package/dist/batcher.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Batcher = void 0;
|
|
4
|
-
const DEFAULT_BATCH_SIZE = 10;
|
|
5
|
-
const DEFAULT_FLUSH_INTERVAL_MS = 5000;
|
|
6
|
-
const DEFAULT_MAX_QUEUE_SIZE = 1000;
|
|
7
|
-
class Batcher {
|
|
8
|
-
constructor(options, onFlush) {
|
|
9
|
-
this.queue = [];
|
|
10
|
-
this.timer = null;
|
|
11
|
-
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
12
|
-
this.flushIntervalMs = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
13
|
-
this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;
|
|
14
|
-
this.onFlush = onFlush;
|
|
15
|
-
this.startTimer();
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Adds a log entry to the queue. Triggers a flush if the
|
|
19
|
-
* batch size threshold is reached.
|
|
20
|
-
*/
|
|
21
|
-
add(entry) {
|
|
22
|
-
if (this.queue.length >= this.maxQueueSize) {
|
|
23
|
-
// Drop the oldest entry when the queue is full
|
|
24
|
-
this.queue.shift();
|
|
25
|
-
}
|
|
26
|
-
this.queue = [...this.queue, entry];
|
|
27
|
-
if (this.queue.length >= this.batchSize) {
|
|
28
|
-
void this.flush();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Flushes all queued log entries by calling the onFlush callback.
|
|
33
|
-
* Returns a promise that resolves when the flush is complete.
|
|
34
|
-
*/
|
|
35
|
-
async flush() {
|
|
36
|
-
if (this.queue.length === 0) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const batch = [...this.queue];
|
|
40
|
-
this.queue = [];
|
|
41
|
-
try {
|
|
42
|
-
await this.onFlush(batch);
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
// Re-add entries to the front of the queue on failure,
|
|
46
|
-
// respecting the max queue size
|
|
47
|
-
const combined = [...batch, ...this.queue];
|
|
48
|
-
this.queue = combined.slice(0, this.maxQueueSize);
|
|
49
|
-
// Rethrow so callers know the flush failed
|
|
50
|
-
throw err;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Returns the number of entries currently in the queue.
|
|
55
|
-
*/
|
|
56
|
-
get size() {
|
|
57
|
-
return this.queue.length;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Stops the periodic flush timer and flushes remaining entries.
|
|
61
|
-
*/
|
|
62
|
-
async shutdown() {
|
|
63
|
-
this.stopTimer();
|
|
64
|
-
await this.flush();
|
|
65
|
-
}
|
|
66
|
-
startTimer() {
|
|
67
|
-
if (this.flushIntervalMs > 0) {
|
|
68
|
-
this.timer = setInterval(() => {
|
|
69
|
-
void this.flush();
|
|
70
|
-
}, this.flushIntervalMs);
|
|
71
|
-
// Allow the Node.js process to exit even if the timer is active
|
|
72
|
-
if (typeof this.timer === "object" && "unref" in this.timer) {
|
|
73
|
-
this.timer.unref();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
stopTimer() {
|
|
78
|
-
if (this.timer !== null) {
|
|
79
|
-
clearInterval(this.timer);
|
|
80
|
-
this.timer = null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
exports.Batcher = Batcher;
|
|
85
|
-
//# sourceMappingURL=batcher.js.map
|
package/dist/batcher.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batcher.js","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { LogLevel, MihariConfig, CompressFn } from "@mihari/logger-types";
|
|
2
|
-
import { HttpTransport } from "./transport";
|
|
3
|
-
import { Batcher } from "./batcher";
|
|
4
|
-
export declare class MihariClient {
|
|
5
|
-
protected readonly config: MihariConfig;
|
|
6
|
-
protected readonly transport: HttpTransport;
|
|
7
|
-
protected readonly batcher: Batcher;
|
|
8
|
-
constructor(config: MihariConfig);
|
|
9
|
-
/**
|
|
10
|
-
* Sets the compression function used by the transport layer.
|
|
11
|
-
*/
|
|
12
|
-
setCompressFn(fn: CompressFn): void;
|
|
13
|
-
/**
|
|
14
|
-
* Logs a debug-level message.
|
|
15
|
-
*/
|
|
16
|
-
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
17
|
-
/**
|
|
18
|
-
* Logs an info-level message.
|
|
19
|
-
*/
|
|
20
|
-
info(message: string, metadata?: Record<string, unknown>): void;
|
|
21
|
-
/**
|
|
22
|
-
* Logs a warn-level message.
|
|
23
|
-
*/
|
|
24
|
-
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
25
|
-
/**
|
|
26
|
-
* Logs an error-level message.
|
|
27
|
-
*/
|
|
28
|
-
error(message: string, metadata?: Record<string, unknown>): void;
|
|
29
|
-
/**
|
|
30
|
-
* Logs a fatal-level message.
|
|
31
|
-
*/
|
|
32
|
-
fatal(message: string, metadata?: Record<string, unknown>): void;
|
|
33
|
-
/**
|
|
34
|
-
* Flushes all pending log entries.
|
|
35
|
-
*/
|
|
36
|
-
flush(): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Shuts down the client, flushing remaining entries.
|
|
39
|
-
*/
|
|
40
|
-
shutdown(): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Creates a log entry and adds it to the batch queue.
|
|
43
|
-
* Subclasses can override getDefaultMetadata() to inject
|
|
44
|
-
* environment-specific fields.
|
|
45
|
-
*/
|
|
46
|
-
log(level: LogLevel, message: string, metadata?: Record<string, unknown>): void;
|
|
47
|
-
/**
|
|
48
|
-
* Returns default metadata to include with every log entry.
|
|
49
|
-
* Override in subclasses to add environment-specific fields.
|
|
50
|
-
*/
|
|
51
|
-
protected getDefaultMetadata(): Record<string, unknown>;
|
|
52
|
-
}
|
|
53
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAY,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,qBAAa,YAAY;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAExB,MAAM,EAAE,YAAY;IAsBhC;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI;IAInC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;;;OAIG;IACI,GAAG,CACR,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI;IAaP;;;OAGG;IACH,SAAS,CAAC,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGxD"}
|
package/dist/client.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MihariClient = void 0;
|
|
4
|
-
const logger_types_1 = require("@mihari/logger-types");
|
|
5
|
-
const transport_1 = require("./transport");
|
|
6
|
-
const batcher_1 = require("./batcher");
|
|
7
|
-
const utils_1 = require("./utils");
|
|
8
|
-
class MihariClient {
|
|
9
|
-
constructor(config) {
|
|
10
|
-
this.config = config;
|
|
11
|
-
this.transport = new transport_1.HttpTransport({
|
|
12
|
-
token: config.token,
|
|
13
|
-
endpoint: config.endpoint,
|
|
14
|
-
compression: config.compression,
|
|
15
|
-
retries: config.retries,
|
|
16
|
-
});
|
|
17
|
-
this.batcher = new batcher_1.Batcher({
|
|
18
|
-
batchSize: config.batchSize,
|
|
19
|
-
flushInterval: config.flushInterval,
|
|
20
|
-
maxQueueSize: config.maxQueueSize,
|
|
21
|
-
}, async (logs) => {
|
|
22
|
-
await this.transport.send(logs);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Sets the compression function used by the transport layer.
|
|
27
|
-
*/
|
|
28
|
-
setCompressFn(fn) {
|
|
29
|
-
this.transport.setCompressFn(fn);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Logs a debug-level message.
|
|
33
|
-
*/
|
|
34
|
-
debug(message, metadata) {
|
|
35
|
-
this.log(logger_types_1.LogLevel.Debug, message, metadata);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Logs an info-level message.
|
|
39
|
-
*/
|
|
40
|
-
info(message, metadata) {
|
|
41
|
-
this.log(logger_types_1.LogLevel.Info, message, metadata);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Logs a warn-level message.
|
|
45
|
-
*/
|
|
46
|
-
warn(message, metadata) {
|
|
47
|
-
this.log(logger_types_1.LogLevel.Warn, message, metadata);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Logs an error-level message.
|
|
51
|
-
*/
|
|
52
|
-
error(message, metadata) {
|
|
53
|
-
this.log(logger_types_1.LogLevel.Error, message, metadata);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Logs a fatal-level message.
|
|
57
|
-
*/
|
|
58
|
-
fatal(message, metadata) {
|
|
59
|
-
this.log(logger_types_1.LogLevel.Fatal, message, metadata);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Flushes all pending log entries.
|
|
63
|
-
*/
|
|
64
|
-
async flush() {
|
|
65
|
-
await this.batcher.flush();
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Shuts down the client, flushing remaining entries.
|
|
69
|
-
*/
|
|
70
|
-
async shutdown() {
|
|
71
|
-
await this.batcher.shutdown();
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Creates a log entry and adds it to the batch queue.
|
|
75
|
-
* Subclasses can override getDefaultMetadata() to inject
|
|
76
|
-
* environment-specific fields.
|
|
77
|
-
*/
|
|
78
|
-
log(level, message, metadata) {
|
|
79
|
-
const entry = {
|
|
80
|
-
dt: (0, utils_1.isoTimestamp)(),
|
|
81
|
-
level,
|
|
82
|
-
message,
|
|
83
|
-
...this.getDefaultMetadata(),
|
|
84
|
-
...(this.config.metadata ?? {}),
|
|
85
|
-
...(metadata ?? {}),
|
|
86
|
-
};
|
|
87
|
-
this.batcher.add(entry);
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Returns default metadata to include with every log entry.
|
|
91
|
-
* Override in subclasses to add environment-specific fields.
|
|
92
|
-
*/
|
|
93
|
-
getDefaultMetadata() {
|
|
94
|
-
return {};
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
exports.MihariClient = MihariClient;
|
|
98
|
-
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,uDAAoF;AACpF,2CAA4C;AAC5C,uCAAoC;AACpC,mCAAuC;AAEvC,MAAa,YAAY;IAKvB,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAa,CAAC;YACjC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAO,CACxB;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;YACb,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,EAAc;QAC1B,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,QAAkC;QACtD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,QAAkC;QACtD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAe,EACf,OAAe,EACf,QAAkC;QAElC,MAAM,KAAK,GAAa;YACtB,EAAE,EAAE,IAAA,oBAAY,GAAE;YAClB,KAAK;YACL,OAAO;YACP,GAAG,IAAI,CAAC,kBAAkB,EAAE;YAC5B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACO,kBAAkB;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAhHD,oCAgHC"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|