@loggerjs/browser 0.5.1 → 0.5.3
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/README.md +9 -2
- package/dist/index.cjs +478 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +478 -29
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-transport.cjs +366 -15
- package/dist/indexeddb-transport.cjs.map +1 -1
- package/dist/indexeddb-transport.d.ts +41 -0
- package/dist/indexeddb-transport.d.ts.map +1 -1
- package/dist/indexeddb-transport.js +367 -16
- package/dist/indexeddb-transport.js.map +1 -1
- package/dist/offline-first-transport.cjs +369 -16
- package/dist/offline-first-transport.cjs.map +1 -1
- package/dist/offline-first-transport.d.ts.map +1 -1
- package/dist/offline-first-transport.js +370 -17
- package/dist/offline-first-transport.js.map +1 -1
- package/dist/zip-export.cjs +109 -13
- package/dist/zip-export.cjs.map +1 -1
- package/dist/zip-export.d.ts +24 -0
- package/dist/zip-export.d.ts.map +1 -1
- package/dist/zip-export.js +109 -13
- package/dist/zip-export.js.map +1 -1
- package/package.json +2 -2
package/dist/zip-export.d.ts
CHANGED
|
@@ -27,6 +27,28 @@ export interface LogZipExportManifest {
|
|
|
27
27
|
from: number;
|
|
28
28
|
to: number;
|
|
29
29
|
};
|
|
30
|
+
recentLogFileName?: string;
|
|
31
|
+
sessionCount?: number;
|
|
32
|
+
sessions?: LogZipExportSessionManifest[];
|
|
33
|
+
}
|
|
34
|
+
export interface LogZipExportSessionManifest {
|
|
35
|
+
sessionId: string;
|
|
36
|
+
logFileName: string;
|
|
37
|
+
logCount: number;
|
|
38
|
+
timeRange?: {
|
|
39
|
+
from: number;
|
|
40
|
+
to: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface LogZipExportSessionOptions {
|
|
44
|
+
contextKey?: string;
|
|
45
|
+
directory?: string;
|
|
46
|
+
fallbackSessionId?: string;
|
|
47
|
+
logFileName?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface LogZipExportRecentOptions {
|
|
50
|
+
logFileName?: string;
|
|
51
|
+
maxEvents?: number;
|
|
30
52
|
}
|
|
31
53
|
export interface LogZipExportOptions {
|
|
32
54
|
query?: IndexedDbTransportQueryOptions;
|
|
@@ -40,6 +62,8 @@ export interface LogZipExportOptions {
|
|
|
40
62
|
stringify?: SafeStringifyOptions;
|
|
41
63
|
serializeEvent?: (event: LogEvent) => string;
|
|
42
64
|
mapEvent?: (event: LogEvent) => LogEvent | false | null | undefined;
|
|
65
|
+
groupBySession?: boolean | LogZipExportSessionOptions;
|
|
66
|
+
includeRecent?: boolean | LogZipExportRecentOptions;
|
|
43
67
|
}
|
|
44
68
|
export interface DownloadBlobOptions {
|
|
45
69
|
filename?: string;
|
package/dist/zip-export.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zip-export.d.ts","sourceRoot":"","sources":["../src/zip-export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,8BAA8B,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC;CAC9E;AAED,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC;AAEnF,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,8BAA8B,CAAC;IACvC,SAAS,CAAC,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,8BAA8B,CAAC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,MAAM,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"zip-export.d.ts","sourceRoot":"","sources":["../src/zip-export.ts"],"names":[],"mappings":"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"}
|
package/dist/zip-export.js
CHANGED
|
@@ -8,6 +8,7 @@ const ZIP_MAX_UINT32 = 4294967295;
|
|
|
8
8
|
const LOCAL_FILE_HEADER_SIGNATURE = 67324752;
|
|
9
9
|
const CENTRAL_DIRECTORY_SIGNATURE = 33639248;
|
|
10
10
|
const END_OF_CENTRAL_DIRECTORY_SIGNATURE = 101010256;
|
|
11
|
+
const DEFAULT_SESSION_CONTEXT_KEY = "sessionId";
|
|
11
12
|
let crc32Table;
|
|
12
13
|
function getCrc32Table() {
|
|
13
14
|
if (crc32Table) return crc32Table;
|
|
@@ -147,6 +148,56 @@ function normalizeMaxEvents(value) {
|
|
|
147
148
|
if (!Number.isFinite(value)) return void 0;
|
|
148
149
|
return Math.max(0, Math.floor(value));
|
|
149
150
|
}
|
|
151
|
+
function normalizeSessionExportOptions(value, logFileName) {
|
|
152
|
+
if (!value) return void 0;
|
|
153
|
+
const options = value === true ? {} : value;
|
|
154
|
+
return {
|
|
155
|
+
contextKey: options.contextKey ?? DEFAULT_SESSION_CONTEXT_KEY,
|
|
156
|
+
directory: options.directory ?? "sessions",
|
|
157
|
+
fallbackSessionId: options.fallbackSessionId ?? "unknown",
|
|
158
|
+
logFileName: options.logFileName ?? logFileName
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function normalizeRecentExportOptions(value, format) {
|
|
162
|
+
if (!value) return void 0;
|
|
163
|
+
const options = value === true ? {} : value;
|
|
164
|
+
return {
|
|
165
|
+
logFileName: options.logFileName ?? (format === "json" ? "recent.json" : "recent.ndjson"),
|
|
166
|
+
maxEvents: normalizeMaxEvents(options.maxEvents) ?? 100
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function logContentForLines(lines, format) {
|
|
170
|
+
if (format === "json") return `[${lines.join(",")}]`;
|
|
171
|
+
return lines.length > 0 ? `${lines.join("\n")}\n` : "";
|
|
172
|
+
}
|
|
173
|
+
function eventTimeRange(items) {
|
|
174
|
+
let from;
|
|
175
|
+
let to;
|
|
176
|
+
for (const item of items) {
|
|
177
|
+
from = from === void 0 ? item.event.time : Math.min(from, item.event.time);
|
|
178
|
+
to = to === void 0 ? item.event.time : Math.max(to, item.event.time);
|
|
179
|
+
}
|
|
180
|
+
return from === void 0 || to === void 0 ? void 0 : {
|
|
181
|
+
from,
|
|
182
|
+
to
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function sessionIdForEvent(event, options) {
|
|
186
|
+
const value = event.context?.[options.contextKey];
|
|
187
|
+
return typeof value === "string" && value.length > 0 ? value : options.fallbackSessionId;
|
|
188
|
+
}
|
|
189
|
+
function safeZipPathSegment(value) {
|
|
190
|
+
const encoded = encodeURIComponent(value).replace(/%/g, "_");
|
|
191
|
+
if (!encoded || encoded === "." || encoded === "..") return "_";
|
|
192
|
+
return encoded;
|
|
193
|
+
}
|
|
194
|
+
function sortByEventTime(items) {
|
|
195
|
+
return [...items].sort((left, right) => {
|
|
196
|
+
if (left.event.time !== right.event.time) return left.event.time - right.event.time;
|
|
197
|
+
if (left.event.seq !== right.event.seq) return left.event.seq - right.event.seq;
|
|
198
|
+
return left.event.id < right.event.id ? -1 : left.event.id > right.event.id ? 1 : 0;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
150
201
|
function createLogZipBlob(files, options = {}) {
|
|
151
202
|
const normalizedFiles = createNormalizedZipFiles(files, options);
|
|
152
203
|
const parts = [];
|
|
@@ -169,27 +220,72 @@ async function exportLogsToZip(source, options = {}) {
|
|
|
169
220
|
const createdAt = options.createdAt ?? Date.now();
|
|
170
221
|
const logFileName = options.logFileName ?? (format === "json" ? "logs.json" : "logs.ndjson");
|
|
171
222
|
const maxEvents = normalizeMaxEvents(options.maxEvents);
|
|
223
|
+
const sessionExportOptions = normalizeSessionExportOptions(options.groupBySession, logFileName);
|
|
224
|
+
const recentExportOptions = normalizeRecentExportOptions(options.includeRecent, format);
|
|
172
225
|
const serialize = options.serializeEvent ?? ((event) => safeJsonStringify(event, options.stringify ?? {}));
|
|
173
|
-
const
|
|
226
|
+
const exported = [];
|
|
174
227
|
let skippedCount = 0;
|
|
175
|
-
let from;
|
|
176
|
-
let to;
|
|
177
228
|
for await (const event of resolveSource(source, options.query)) {
|
|
178
|
-
if (maxEvents !== void 0 &&
|
|
229
|
+
if (maxEvents !== void 0 && exported.length >= maxEvents) break;
|
|
179
230
|
const mapped = options.mapEvent ? options.mapEvent(event) : event;
|
|
180
231
|
if (!mapped) {
|
|
181
232
|
skippedCount += 1;
|
|
182
233
|
continue;
|
|
183
234
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
235
|
+
exported.push({
|
|
236
|
+
event: mapped,
|
|
237
|
+
line: serialize(mapped)
|
|
238
|
+
});
|
|
187
239
|
}
|
|
188
240
|
const files = [{
|
|
189
241
|
name: logFileName,
|
|
190
|
-
content:
|
|
242
|
+
content: logContentForLines(exported.map((item) => item.line), format),
|
|
191
243
|
lastModified: createdAt
|
|
192
244
|
}];
|
|
245
|
+
const sessionManifests = [];
|
|
246
|
+
if (sessionExportOptions) {
|
|
247
|
+
const groups = /* @__PURE__ */ new Map();
|
|
248
|
+
for (const item of exported) {
|
|
249
|
+
const sessionId = sessionIdForEvent(item.event, sessionExportOptions);
|
|
250
|
+
const group = groups.get(sessionId) ?? [];
|
|
251
|
+
group.push(item);
|
|
252
|
+
groups.set(sessionId, group);
|
|
253
|
+
}
|
|
254
|
+
const usedFileNames = new Set(files.map((file) => normalizeZipFileName(file.name)));
|
|
255
|
+
const sortedGroups = [...groups.entries()];
|
|
256
|
+
sortedGroups.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
|
|
257
|
+
for (const [sessionId, group] of sortedGroups) {
|
|
258
|
+
let fileName = normalizeZipFileName(`${sessionExportOptions.directory}/${safeZipPathSegment(sessionId)}/${sessionExportOptions.logFileName}`);
|
|
259
|
+
let suffix = 1;
|
|
260
|
+
while (usedFileNames.has(fileName)) {
|
|
261
|
+
fileName = normalizeZipFileName(`${sessionExportOptions.directory}/${safeZipPathSegment(sessionId)}-${suffix}/${sessionExportOptions.logFileName}`);
|
|
262
|
+
suffix += 1;
|
|
263
|
+
}
|
|
264
|
+
usedFileNames.add(fileName);
|
|
265
|
+
const orderedGroup = sortByEventTime(group);
|
|
266
|
+
files.push({
|
|
267
|
+
name: fileName,
|
|
268
|
+
content: logContentForLines(orderedGroup.map((item) => item.line), format),
|
|
269
|
+
lastModified: createdAt
|
|
270
|
+
});
|
|
271
|
+
sessionManifests.push({
|
|
272
|
+
logCount: orderedGroup.length,
|
|
273
|
+
logFileName: fileName,
|
|
274
|
+
sessionId,
|
|
275
|
+
timeRange: eventTimeRange(orderedGroup)
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
let recentLogFileName;
|
|
280
|
+
if (recentExportOptions) {
|
|
281
|
+
const recentItems = recentExportOptions.maxEvents <= 0 ? [] : sortByEventTime(exported).slice(-recentExportOptions.maxEvents);
|
|
282
|
+
recentLogFileName = normalizeZipFileName(recentExportOptions.logFileName);
|
|
283
|
+
files.push({
|
|
284
|
+
name: recentLogFileName,
|
|
285
|
+
content: logContentForLines(recentItems.map((item) => item.line), format),
|
|
286
|
+
lastModified: createdAt
|
|
287
|
+
});
|
|
288
|
+
}
|
|
193
289
|
if (options.includeManifest ?? true) {
|
|
194
290
|
const manifest = {
|
|
195
291
|
schema: "loggerjs.log-export.v1",
|
|
@@ -197,13 +293,13 @@ async function exportLogsToZip(source, options = {}) {
|
|
|
197
293
|
source: options.source,
|
|
198
294
|
format,
|
|
199
295
|
logFileName: normalizeZipFileName(logFileName),
|
|
200
|
-
logCount:
|
|
296
|
+
logCount: exported.length,
|
|
201
297
|
skippedCount,
|
|
202
298
|
query: options.query,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
299
|
+
recentLogFileName,
|
|
300
|
+
sessionCount: sessionExportOptions ? sessionManifests.length : void 0,
|
|
301
|
+
sessions: sessionExportOptions ? sessionManifests : void 0,
|
|
302
|
+
timeRange: eventTimeRange(exported)
|
|
207
303
|
};
|
|
208
304
|
files.push({
|
|
209
305
|
name: options.manifestFileName ?? "manifest.json",
|
package/dist/zip-export.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zip-export.js","names":[],"sources":["../src/zip-export.ts"],"sourcesContent":["import { safeJsonStringify, type LogEvent, type SafeStringifyOptions } from \"@loggerjs/core\";\nimport type { IndexedDbTransportQueryOptions } from \"./indexeddb-transport\";\n\nexport type LogZipExportFormat = \"ndjson\" | \"json\";\n\nexport interface ZipExportFile {\n name: string;\n content: string | Uint8Array | ArrayBuffer;\n lastModified?: number;\n}\n\nexport interface LogZipBlobOptions {\n lastModified?: number;\n type?: string;\n}\n\nexport interface LogZipExportQuerySource {\n query: (options?: IndexedDbTransportQueryOptions) => AsyncIterable<LogEvent>;\n}\n\nexport type LogZipExportSource = AsyncIterable<LogEvent> | LogZipExportQuerySource;\n\nexport interface LogZipExportManifest {\n schema: \"loggerjs.log-export.v1\";\n createdAt: string;\n source?: string;\n format: LogZipExportFormat;\n logFileName: string;\n logCount: number;\n skippedCount: number;\n query?: IndexedDbTransportQueryOptions;\n timeRange?: {\n from: number;\n to: number;\n };\n}\n\nexport interface LogZipExportOptions {\n query?: IndexedDbTransportQueryOptions;\n format?: LogZipExportFormat;\n logFileName?: string;\n includeManifest?: boolean;\n manifestFileName?: string;\n source?: string;\n createdAt?: number;\n maxEvents?: number;\n stringify?: SafeStringifyOptions;\n serializeEvent?: (event: LogEvent) => string;\n mapEvent?: (event: LogEvent) => LogEvent | false | null | undefined;\n}\n\nexport interface DownloadBlobOptions {\n filename?: string;\n document?: Document;\n url?: Pick<typeof URL, \"createObjectURL\" | \"revokeObjectURL\">;\n revokeDelayMs?: number;\n}\n\ninterface NormalizedZipFile {\n name: string;\n nameBytes: Uint8Array;\n contentBytes: Uint8Array;\n crc32: number;\n modifiedTime: number;\n modifiedDate: number;\n localHeaderOffset: number;\n}\n\nconst ZIP_UTF8_FLAG = 0x0800;\nconst ZIP_STORE_METHOD = 0;\nconst ZIP_VERSION = 20;\nconst ZIP_MAX_UINT16 = 0xffff;\nconst ZIP_MAX_UINT32 = 0xffffffff;\nconst LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\nconst CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;\nconst END_OF_CENTRAL_DIRECTORY_SIGNATURE = 0x06054b50;\n\nlet crc32Table: Uint32Array | undefined;\n\nfunction getCrc32Table(): Uint32Array {\n if (crc32Table) return crc32Table;\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let crc = index;\n for (let bit = 0; bit < 8; bit += 1) {\n crc = crc & 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1;\n }\n table[index] = crc >>> 0;\n }\n crc32Table = table;\n return table;\n}\n\nfunction crc32(bytes: Uint8Array): number {\n const table = getCrc32Table();\n let crc = 0xffffffff;\n for (const byte of bytes) {\n crc = (crc >>> 8) ^ (table[(crc ^ byte) & 0xff] ?? 0);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction encodeText(value: string): Uint8Array {\n return new TextEncoder().encode(value);\n}\n\nfunction normalizeFileContent(content: ZipExportFile[\"content\"]): Uint8Array {\n if (typeof content === \"string\") return encodeText(content);\n if (content instanceof Uint8Array) return content;\n return new Uint8Array(content);\n}\n\nfunction normalizeZipFileName(name: string): string {\n const normalized = name\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter((part) => part.length > 0 && part !== \".\" && part !== \"..\")\n .join(\"/\");\n if (!normalized) throw new Error(\"ZIP file name cannot be empty\");\n return normalized;\n}\n\nfunction toDosDateTime(timestamp: number): { time: number; date: number } {\n const date = new Date(Number.isFinite(timestamp) ? timestamp : Date.now());\n const year = Math.min(2107, Math.max(1980, date.getFullYear()));\n return {\n time: (date.getHours() << 11) | (date.getMinutes() << 5) | Math.floor(date.getSeconds() / 2),\n date: ((year - 1980) << 9) | ((date.getMonth() + 1) << 5) | date.getDate(),\n };\n}\n\nfunction assertZipUint16(value: number, label: string) {\n if (!Number.isSafeInteger(value) || value < 0 || value > ZIP_MAX_UINT16) {\n throw new Error(`${label} exceeds ZIP32 limit`);\n }\n}\n\nfunction assertZipUint32(value: number, label: string) {\n if (!Number.isSafeInteger(value) || value < 0 || value > ZIP_MAX_UINT32) {\n throw new Error(`${label} exceeds ZIP32 limit`);\n }\n}\n\nfunction createLocalFileHeader(file: NormalizedZipFile): Uint8Array {\n const header = new Uint8Array(30);\n const view = new DataView(header.buffer);\n view.setUint32(0, LOCAL_FILE_HEADER_SIGNATURE, true);\n view.setUint16(4, ZIP_VERSION, true);\n view.setUint16(6, ZIP_UTF8_FLAG, true);\n view.setUint16(8, ZIP_STORE_METHOD, true);\n view.setUint16(10, file.modifiedTime, true);\n view.setUint16(12, file.modifiedDate, true);\n view.setUint32(14, file.crc32, true);\n view.setUint32(18, file.contentBytes.byteLength, true);\n view.setUint32(22, file.contentBytes.byteLength, true);\n view.setUint16(26, file.nameBytes.byteLength, true);\n view.setUint16(28, 0, true);\n return header;\n}\n\nfunction createCentralDirectoryHeader(file: NormalizedZipFile): Uint8Array {\n const header = new Uint8Array(46);\n const view = new DataView(header.buffer);\n view.setUint32(0, CENTRAL_DIRECTORY_SIGNATURE, true);\n view.setUint16(4, ZIP_VERSION, true);\n view.setUint16(6, ZIP_VERSION, true);\n view.setUint16(8, ZIP_UTF8_FLAG, true);\n view.setUint16(10, ZIP_STORE_METHOD, true);\n view.setUint16(12, file.modifiedTime, true);\n view.setUint16(14, file.modifiedDate, true);\n view.setUint32(16, file.crc32, true);\n view.setUint32(20, file.contentBytes.byteLength, true);\n view.setUint32(24, file.contentBytes.byteLength, true);\n view.setUint16(28, file.nameBytes.byteLength, true);\n view.setUint16(30, 0, true);\n view.setUint16(32, 0, true);\n view.setUint16(34, 0, true);\n view.setUint16(36, 0, true);\n view.setUint32(38, 0, true);\n view.setUint32(42, file.localHeaderOffset, true);\n return header;\n}\n\nfunction createEndOfCentralDirectory(\n fileCount: number,\n centralDirectorySize: number,\n centralDirectoryOffset: number,\n): Uint8Array {\n assertZipUint16(fileCount, \"ZIP file count\");\n assertZipUint32(centralDirectorySize, \"ZIP central directory size\");\n assertZipUint32(centralDirectoryOffset, \"ZIP central directory offset\");\n\n const footer = new Uint8Array(22);\n const view = new DataView(footer.buffer);\n view.setUint32(0, END_OF_CENTRAL_DIRECTORY_SIGNATURE, true);\n view.setUint16(4, 0, true);\n view.setUint16(6, 0, true);\n view.setUint16(8, fileCount, true);\n view.setUint16(10, fileCount, true);\n view.setUint32(12, centralDirectorySize, true);\n view.setUint32(16, centralDirectoryOffset, true);\n view.setUint16(20, 0, true);\n return footer;\n}\n\nfunction createNormalizedZipFiles(\n files: readonly ZipExportFile[],\n options: LogZipBlobOptions,\n): NormalizedZipFile[] {\n const names = new Set<string>();\n let offset = 0;\n return files.map((file) => {\n const name = normalizeZipFileName(file.name);\n if (names.has(name)) throw new Error(`Duplicate ZIP file name: ${name}`);\n names.add(name);\n\n const nameBytes = encodeText(name);\n const contentBytes = normalizeFileContent(file.content);\n assertZipUint16(nameBytes.byteLength, `ZIP file name ${name}`);\n assertZipUint32(contentBytes.byteLength, `ZIP file ${name}`);\n assertZipUint32(offset, \"ZIP local header offset\");\n\n const modified = toDosDateTime(file.lastModified ?? options.lastModified ?? Date.now());\n const normalized: NormalizedZipFile = {\n name,\n nameBytes,\n contentBytes,\n crc32: crc32(contentBytes),\n modifiedTime: modified.time,\n modifiedDate: modified.date,\n localHeaderOffset: offset,\n };\n offset += 30 + nameBytes.byteLength + contentBytes.byteLength;\n assertZipUint32(offset, \"ZIP local data size\");\n return normalized;\n });\n}\n\nfunction isQuerySource(source: LogZipExportSource): source is LogZipExportQuerySource {\n return \"query\" in source && typeof source.query === \"function\";\n}\n\nfunction resolveSource(\n source: LogZipExportSource,\n query: IndexedDbTransportQueryOptions | undefined,\n): AsyncIterable<LogEvent> {\n if (isQuerySource(source)) return source.query(query);\n if (query) throw new Error(\"Log ZIP export query options require a source with query()\");\n return source;\n}\n\nfunction normalizeMaxEvents(value: number | undefined): number | undefined {\n if (value === undefined) return undefined;\n if (!Number.isFinite(value)) return undefined;\n return Math.max(0, Math.floor(value));\n}\n\nexport function createLogZipBlob(\n files: readonly ZipExportFile[],\n options: LogZipBlobOptions = {},\n): Blob {\n const normalizedFiles = createNormalizedZipFiles(files, options);\n const parts: Uint8Array[] = [];\n let centralDirectoryOffset = 0;\n for (const file of normalizedFiles) {\n parts.push(createLocalFileHeader(file), file.nameBytes, file.contentBytes);\n centralDirectoryOffset += 30 + file.nameBytes.byteLength + file.contentBytes.byteLength;\n }\n\n let centralDirectorySize = 0;\n for (const file of normalizedFiles) {\n const header = createCentralDirectoryHeader(file);\n parts.push(header, file.nameBytes);\n centralDirectorySize += header.byteLength + file.nameBytes.byteLength;\n }\n parts.push(\n createEndOfCentralDirectory(\n normalizedFiles.length,\n centralDirectorySize,\n centralDirectoryOffset,\n ),\n );\n\n return new Blob(parts as unknown as BlobPart[], { type: options.type ?? \"application/zip\" });\n}\n\nexport async function exportLogsToZip(\n source: LogZipExportSource,\n options: LogZipExportOptions = {},\n): Promise<Blob> {\n const format = options.format ?? \"ndjson\";\n const createdAt = options.createdAt ?? Date.now();\n const logFileName = options.logFileName ?? (format === \"json\" ? \"logs.json\" : \"logs.ndjson\");\n const maxEvents = normalizeMaxEvents(options.maxEvents);\n const serialize =\n options.serializeEvent ??\n ((event: LogEvent) => safeJsonStringify(event, options.stringify ?? {}));\n const lines: string[] = [];\n let skippedCount = 0;\n let from: number | undefined;\n let to: number | undefined;\n\n for await (const event of resolveSource(source, options.query)) {\n if (maxEvents !== undefined && lines.length >= maxEvents) break;\n const mapped = options.mapEvent ? options.mapEvent(event) : event;\n if (!mapped) {\n skippedCount += 1;\n continue;\n }\n lines.push(serialize(mapped));\n from = from === undefined ? mapped.time : Math.min(from, mapped.time);\n to = to === undefined ? mapped.time : Math.max(to, mapped.time);\n }\n\n const logContent =\n format === \"json\" ? `[${lines.join(\",\")}]` : lines.length > 0 ? `${lines.join(\"\\n\")}\\n` : \"\";\n\n const files: ZipExportFile[] = [\n {\n name: logFileName,\n content: logContent,\n lastModified: createdAt,\n },\n ];\n\n if (options.includeManifest ?? true) {\n const manifest: LogZipExportManifest = {\n schema: \"loggerjs.log-export.v1\",\n createdAt: new Date(createdAt).toISOString(),\n source: options.source,\n format,\n logFileName: normalizeZipFileName(logFileName),\n logCount: lines.length,\n skippedCount,\n query: options.query,\n timeRange: from === undefined || to === undefined ? undefined : { from, to },\n };\n files.push({\n name: options.manifestFileName ?? \"manifest.json\",\n content: `${safeJsonStringify(manifest, { space: 2 })}\\n`,\n lastModified: createdAt,\n });\n }\n\n return createLogZipBlob(files, { lastModified: createdAt });\n}\n\nexport function downloadBlob(\n blob: Blob,\n filenameOrOptions: string | DownloadBlobOptions = {},\n): string {\n const options =\n typeof filenameOrOptions === \"string\" ? { filename: filenameOrOptions } : filenameOrOptions;\n const documentRef = options.document ?? globalThis.document;\n const urlRef = options.url ?? globalThis.URL;\n if (!documentRef?.body || !urlRef?.createObjectURL || !urlRef.revokeObjectURL) {\n throw new Error(\"downloadBlob requires document and URL.createObjectURL\");\n }\n\n const href = urlRef.createObjectURL(blob);\n const anchor = documentRef.createElement(\"a\");\n anchor.href = href;\n anchor.download = options.filename ?? \"loggerjs-logs.zip\";\n anchor.style.display = \"none\";\n documentRef.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n\n const revoke = () => urlRef.revokeObjectURL(href);\n const revokeDelayMs = options.revokeDelayMs ?? 1000;\n if (revokeDelayMs <= 0) {\n revoke();\n } else {\n setTimeout(revoke, revokeDelayMs);\n }\n\n return href;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"zip-export.js","names":[],"sources":["../src/zip-export.ts"],"sourcesContent":["import { safeJsonStringify, type LogEvent, type SafeStringifyOptions } from \"@loggerjs/core\";\nimport type { IndexedDbTransportQueryOptions } from \"./indexeddb-transport\";\n\nexport type LogZipExportFormat = \"ndjson\" | \"json\";\n\nexport interface ZipExportFile {\n name: string;\n content: string | Uint8Array | ArrayBuffer;\n lastModified?: number;\n}\n\nexport interface LogZipBlobOptions {\n lastModified?: number;\n type?: string;\n}\n\nexport interface LogZipExportQuerySource {\n query: (options?: IndexedDbTransportQueryOptions) => AsyncIterable<LogEvent>;\n}\n\nexport type LogZipExportSource = AsyncIterable<LogEvent> | LogZipExportQuerySource;\n\nexport interface LogZipExportManifest {\n schema: \"loggerjs.log-export.v1\";\n createdAt: string;\n source?: string;\n format: LogZipExportFormat;\n logFileName: string;\n logCount: number;\n skippedCount: number;\n query?: IndexedDbTransportQueryOptions;\n timeRange?: {\n from: number;\n to: number;\n };\n recentLogFileName?: string;\n sessionCount?: number;\n sessions?: LogZipExportSessionManifest[];\n}\n\nexport interface LogZipExportSessionManifest {\n sessionId: string;\n logFileName: string;\n logCount: number;\n timeRange?: {\n from: number;\n to: number;\n };\n}\n\nexport interface LogZipExportSessionOptions {\n contextKey?: string;\n directory?: string;\n fallbackSessionId?: string;\n logFileName?: string;\n}\n\nexport interface LogZipExportRecentOptions {\n logFileName?: string;\n maxEvents?: number;\n}\n\nexport interface LogZipExportOptions {\n query?: IndexedDbTransportQueryOptions;\n format?: LogZipExportFormat;\n logFileName?: string;\n includeManifest?: boolean;\n manifestFileName?: string;\n source?: string;\n createdAt?: number;\n maxEvents?: number;\n stringify?: SafeStringifyOptions;\n serializeEvent?: (event: LogEvent) => string;\n mapEvent?: (event: LogEvent) => LogEvent | false | null | undefined;\n groupBySession?: boolean | LogZipExportSessionOptions;\n includeRecent?: boolean | LogZipExportRecentOptions;\n}\n\nexport interface DownloadBlobOptions {\n filename?: string;\n document?: Document;\n url?: Pick<typeof URL, \"createObjectURL\" | \"revokeObjectURL\">;\n revokeDelayMs?: number;\n}\n\ninterface NormalizedZipFile {\n name: string;\n nameBytes: Uint8Array;\n contentBytes: Uint8Array;\n crc32: number;\n modifiedTime: number;\n modifiedDate: number;\n localHeaderOffset: number;\n}\n\ninterface ExportedLogLine {\n event: LogEvent;\n line: string;\n}\n\ninterface NormalizedSessionExportOptions {\n contextKey: string;\n directory: string;\n fallbackSessionId: string;\n logFileName: string;\n}\n\ninterface NormalizedRecentExportOptions {\n logFileName: string;\n maxEvents: number;\n}\n\nconst ZIP_UTF8_FLAG = 0x0800;\nconst ZIP_STORE_METHOD = 0;\nconst ZIP_VERSION = 20;\nconst ZIP_MAX_UINT16 = 0xffff;\nconst ZIP_MAX_UINT32 = 0xffffffff;\nconst LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\nconst CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;\nconst END_OF_CENTRAL_DIRECTORY_SIGNATURE = 0x06054b50;\nconst DEFAULT_SESSION_CONTEXT_KEY = \"sessionId\";\n\nlet crc32Table: Uint32Array | undefined;\n\nfunction getCrc32Table(): Uint32Array {\n if (crc32Table) return crc32Table;\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let crc = index;\n for (let bit = 0; bit < 8; bit += 1) {\n crc = crc & 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1;\n }\n table[index] = crc >>> 0;\n }\n crc32Table = table;\n return table;\n}\n\nfunction crc32(bytes: Uint8Array): number {\n const table = getCrc32Table();\n let crc = 0xffffffff;\n for (const byte of bytes) {\n crc = (crc >>> 8) ^ (table[(crc ^ byte) & 0xff] ?? 0);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction encodeText(value: string): Uint8Array {\n return new TextEncoder().encode(value);\n}\n\nfunction normalizeFileContent(content: ZipExportFile[\"content\"]): Uint8Array {\n if (typeof content === \"string\") return encodeText(content);\n if (content instanceof Uint8Array) return content;\n return new Uint8Array(content);\n}\n\nfunction normalizeZipFileName(name: string): string {\n const normalized = name\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter((part) => part.length > 0 && part !== \".\" && part !== \"..\")\n .join(\"/\");\n if (!normalized) throw new Error(\"ZIP file name cannot be empty\");\n return normalized;\n}\n\nfunction toDosDateTime(timestamp: number): { time: number; date: number } {\n const date = new Date(Number.isFinite(timestamp) ? timestamp : Date.now());\n const year = Math.min(2107, Math.max(1980, date.getFullYear()));\n return {\n time: (date.getHours() << 11) | (date.getMinutes() << 5) | Math.floor(date.getSeconds() / 2),\n date: ((year - 1980) << 9) | ((date.getMonth() + 1) << 5) | date.getDate(),\n };\n}\n\nfunction assertZipUint16(value: number, label: string) {\n if (!Number.isSafeInteger(value) || value < 0 || value > ZIP_MAX_UINT16) {\n throw new Error(`${label} exceeds ZIP32 limit`);\n }\n}\n\nfunction assertZipUint32(value: number, label: string) {\n if (!Number.isSafeInteger(value) || value < 0 || value > ZIP_MAX_UINT32) {\n throw new Error(`${label} exceeds ZIP32 limit`);\n }\n}\n\nfunction createLocalFileHeader(file: NormalizedZipFile): Uint8Array {\n const header = new Uint8Array(30);\n const view = new DataView(header.buffer);\n view.setUint32(0, LOCAL_FILE_HEADER_SIGNATURE, true);\n view.setUint16(4, ZIP_VERSION, true);\n view.setUint16(6, ZIP_UTF8_FLAG, true);\n view.setUint16(8, ZIP_STORE_METHOD, true);\n view.setUint16(10, file.modifiedTime, true);\n view.setUint16(12, file.modifiedDate, true);\n view.setUint32(14, file.crc32, true);\n view.setUint32(18, file.contentBytes.byteLength, true);\n view.setUint32(22, file.contentBytes.byteLength, true);\n view.setUint16(26, file.nameBytes.byteLength, true);\n view.setUint16(28, 0, true);\n return header;\n}\n\nfunction createCentralDirectoryHeader(file: NormalizedZipFile): Uint8Array {\n const header = new Uint8Array(46);\n const view = new DataView(header.buffer);\n view.setUint32(0, CENTRAL_DIRECTORY_SIGNATURE, true);\n view.setUint16(4, ZIP_VERSION, true);\n view.setUint16(6, ZIP_VERSION, true);\n view.setUint16(8, ZIP_UTF8_FLAG, true);\n view.setUint16(10, ZIP_STORE_METHOD, true);\n view.setUint16(12, file.modifiedTime, true);\n view.setUint16(14, file.modifiedDate, true);\n view.setUint32(16, file.crc32, true);\n view.setUint32(20, file.contentBytes.byteLength, true);\n view.setUint32(24, file.contentBytes.byteLength, true);\n view.setUint16(28, file.nameBytes.byteLength, true);\n view.setUint16(30, 0, true);\n view.setUint16(32, 0, true);\n view.setUint16(34, 0, true);\n view.setUint16(36, 0, true);\n view.setUint32(38, 0, true);\n view.setUint32(42, file.localHeaderOffset, true);\n return header;\n}\n\nfunction createEndOfCentralDirectory(\n fileCount: number,\n centralDirectorySize: number,\n centralDirectoryOffset: number,\n): Uint8Array {\n assertZipUint16(fileCount, \"ZIP file count\");\n assertZipUint32(centralDirectorySize, \"ZIP central directory size\");\n assertZipUint32(centralDirectoryOffset, \"ZIP central directory offset\");\n\n const footer = new Uint8Array(22);\n const view = new DataView(footer.buffer);\n view.setUint32(0, END_OF_CENTRAL_DIRECTORY_SIGNATURE, true);\n view.setUint16(4, 0, true);\n view.setUint16(6, 0, true);\n view.setUint16(8, fileCount, true);\n view.setUint16(10, fileCount, true);\n view.setUint32(12, centralDirectorySize, true);\n view.setUint32(16, centralDirectoryOffset, true);\n view.setUint16(20, 0, true);\n return footer;\n}\n\nfunction createNormalizedZipFiles(\n files: readonly ZipExportFile[],\n options: LogZipBlobOptions,\n): NormalizedZipFile[] {\n const names = new Set<string>();\n let offset = 0;\n return files.map((file) => {\n const name = normalizeZipFileName(file.name);\n if (names.has(name)) throw new Error(`Duplicate ZIP file name: ${name}`);\n names.add(name);\n\n const nameBytes = encodeText(name);\n const contentBytes = normalizeFileContent(file.content);\n assertZipUint16(nameBytes.byteLength, `ZIP file name ${name}`);\n assertZipUint32(contentBytes.byteLength, `ZIP file ${name}`);\n assertZipUint32(offset, \"ZIP local header offset\");\n\n const modified = toDosDateTime(file.lastModified ?? options.lastModified ?? Date.now());\n const normalized: NormalizedZipFile = {\n name,\n nameBytes,\n contentBytes,\n crc32: crc32(contentBytes),\n modifiedTime: modified.time,\n modifiedDate: modified.date,\n localHeaderOffset: offset,\n };\n offset += 30 + nameBytes.byteLength + contentBytes.byteLength;\n assertZipUint32(offset, \"ZIP local data size\");\n return normalized;\n });\n}\n\nfunction isQuerySource(source: LogZipExportSource): source is LogZipExportQuerySource {\n return \"query\" in source && typeof source.query === \"function\";\n}\n\nfunction resolveSource(\n source: LogZipExportSource,\n query: IndexedDbTransportQueryOptions | undefined,\n): AsyncIterable<LogEvent> {\n if (isQuerySource(source)) return source.query(query);\n if (query) throw new Error(\"Log ZIP export query options require a source with query()\");\n return source;\n}\n\nfunction normalizeMaxEvents(value: number | undefined): number | undefined {\n if (value === undefined) return undefined;\n if (!Number.isFinite(value)) return undefined;\n return Math.max(0, Math.floor(value));\n}\n\nfunction normalizeSessionExportOptions(\n value: boolean | LogZipExportSessionOptions | undefined,\n logFileName: string,\n): NormalizedSessionExportOptions | undefined {\n if (!value) return undefined;\n const options = value === true ? {} : value;\n return {\n contextKey: options.contextKey ?? DEFAULT_SESSION_CONTEXT_KEY,\n directory: options.directory ?? \"sessions\",\n fallbackSessionId: options.fallbackSessionId ?? \"unknown\",\n logFileName: options.logFileName ?? logFileName,\n };\n}\n\nfunction normalizeRecentExportOptions(\n value: boolean | LogZipExportRecentOptions | undefined,\n format: LogZipExportFormat,\n): NormalizedRecentExportOptions | undefined {\n if (!value) return undefined;\n const options = value === true ? {} : value;\n return {\n logFileName: options.logFileName ?? (format === \"json\" ? \"recent.json\" : \"recent.ndjson\"),\n maxEvents: normalizeMaxEvents(options.maxEvents) ?? 100,\n };\n}\n\nfunction logContentForLines(lines: readonly string[], format: LogZipExportFormat): string {\n if (format === \"json\") return `[${lines.join(\",\")}]`;\n return lines.length > 0 ? `${lines.join(\"\\n\")}\\n` : \"\";\n}\n\nfunction eventTimeRange(items: readonly ExportedLogLine[]):\n | {\n from: number;\n to: number;\n }\n | undefined {\n let from: number | undefined;\n let to: number | undefined;\n for (const item of items) {\n from = from === undefined ? item.event.time : Math.min(from, item.event.time);\n to = to === undefined ? item.event.time : Math.max(to, item.event.time);\n }\n return from === undefined || to === undefined ? undefined : { from, to };\n}\n\nfunction sessionIdForEvent(event: LogEvent, options: NormalizedSessionExportOptions): string {\n const value = event.context?.[options.contextKey];\n return typeof value === \"string\" && value.length > 0 ? value : options.fallbackSessionId;\n}\n\nfunction safeZipPathSegment(value: string): string {\n const encoded = encodeURIComponent(value).replace(/%/g, \"_\");\n if (!encoded || encoded === \".\" || encoded === \"..\") return \"_\";\n return encoded;\n}\n\nfunction sortByEventTime(items: readonly ExportedLogLine[]): ExportedLogLine[] {\n // oxlint-disable-next-line no-array-sort -- Sort a copy for stable export ordering.\n return [...items].sort((left, right) => {\n if (left.event.time !== right.event.time) return left.event.time - right.event.time;\n if (left.event.seq !== right.event.seq) return left.event.seq - right.event.seq;\n return left.event.id < right.event.id ? -1 : left.event.id > right.event.id ? 1 : 0;\n });\n}\n\nexport function createLogZipBlob(\n files: readonly ZipExportFile[],\n options: LogZipBlobOptions = {},\n): Blob {\n const normalizedFiles = createNormalizedZipFiles(files, options);\n const parts: Uint8Array[] = [];\n let centralDirectoryOffset = 0;\n for (const file of normalizedFiles) {\n parts.push(createLocalFileHeader(file), file.nameBytes, file.contentBytes);\n centralDirectoryOffset += 30 + file.nameBytes.byteLength + file.contentBytes.byteLength;\n }\n\n let centralDirectorySize = 0;\n for (const file of normalizedFiles) {\n const header = createCentralDirectoryHeader(file);\n parts.push(header, file.nameBytes);\n centralDirectorySize += header.byteLength + file.nameBytes.byteLength;\n }\n parts.push(\n createEndOfCentralDirectory(\n normalizedFiles.length,\n centralDirectorySize,\n centralDirectoryOffset,\n ),\n );\n\n return new Blob(parts as unknown as BlobPart[], { type: options.type ?? \"application/zip\" });\n}\n\nexport async function exportLogsToZip(\n source: LogZipExportSource,\n options: LogZipExportOptions = {},\n): Promise<Blob> {\n const format = options.format ?? \"ndjson\";\n const createdAt = options.createdAt ?? Date.now();\n const logFileName = options.logFileName ?? (format === \"json\" ? \"logs.json\" : \"logs.ndjson\");\n const maxEvents = normalizeMaxEvents(options.maxEvents);\n const sessionExportOptions = normalizeSessionExportOptions(options.groupBySession, logFileName);\n const recentExportOptions = normalizeRecentExportOptions(options.includeRecent, format);\n const serialize =\n options.serializeEvent ??\n ((event: LogEvent) => safeJsonStringify(event, options.stringify ?? {}));\n const exported: ExportedLogLine[] = [];\n let skippedCount = 0;\n\n for await (const event of resolveSource(source, options.query)) {\n if (maxEvents !== undefined && exported.length >= maxEvents) break;\n const mapped = options.mapEvent ? options.mapEvent(event) : event;\n if (!mapped) {\n skippedCount += 1;\n continue;\n }\n exported.push({ event: mapped, line: serialize(mapped) });\n }\n\n const files: ZipExportFile[] = [\n {\n name: logFileName,\n content: logContentForLines(\n exported.map((item) => item.line),\n format,\n ),\n lastModified: createdAt,\n },\n ];\n const sessionManifests: LogZipExportSessionManifest[] = [];\n\n if (sessionExportOptions) {\n const groups = new Map<string, ExportedLogLine[]>();\n for (const item of exported) {\n const sessionId = sessionIdForEvent(item.event, sessionExportOptions);\n const group = groups.get(sessionId) ?? [];\n group.push(item);\n groups.set(sessionId, group);\n }\n const usedFileNames = new Set(files.map((file) => normalizeZipFileName(file.name)));\n const sortedGroups = [...groups.entries()];\n sortedGroups.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));\n for (const [sessionId, group] of sortedGroups) {\n const sessionPath = `${sessionExportOptions.directory}/${safeZipPathSegment(sessionId)}/${\n sessionExportOptions.logFileName\n }`;\n let fileName = normalizeZipFileName(sessionPath);\n let suffix = 1;\n while (usedFileNames.has(fileName)) {\n fileName = normalizeZipFileName(\n `${sessionExportOptions.directory}/${safeZipPathSegment(sessionId)}-${suffix}/${\n sessionExportOptions.logFileName\n }`,\n );\n suffix += 1;\n }\n usedFileNames.add(fileName);\n const orderedGroup = sortByEventTime(group);\n files.push({\n name: fileName,\n content: logContentForLines(\n orderedGroup.map((item) => item.line),\n format,\n ),\n lastModified: createdAt,\n });\n sessionManifests.push({\n logCount: orderedGroup.length,\n logFileName: fileName,\n sessionId,\n timeRange: eventTimeRange(orderedGroup),\n });\n }\n }\n\n let recentLogFileName: string | undefined;\n if (recentExportOptions) {\n const recentItems =\n recentExportOptions.maxEvents <= 0\n ? []\n : sortByEventTime(exported).slice(-recentExportOptions.maxEvents);\n recentLogFileName = normalizeZipFileName(recentExportOptions.logFileName);\n files.push({\n name: recentLogFileName,\n content: logContentForLines(\n recentItems.map((item) => item.line),\n format,\n ),\n lastModified: createdAt,\n });\n }\n\n if (options.includeManifest ?? true) {\n const manifest: LogZipExportManifest = {\n schema: \"loggerjs.log-export.v1\",\n createdAt: new Date(createdAt).toISOString(),\n source: options.source,\n format,\n logFileName: normalizeZipFileName(logFileName),\n logCount: exported.length,\n skippedCount,\n query: options.query,\n recentLogFileName,\n sessionCount: sessionExportOptions ? sessionManifests.length : undefined,\n sessions: sessionExportOptions ? sessionManifests : undefined,\n timeRange: eventTimeRange(exported),\n };\n files.push({\n name: options.manifestFileName ?? \"manifest.json\",\n content: `${safeJsonStringify(manifest, { space: 2 })}\\n`,\n lastModified: createdAt,\n });\n }\n\n return createLogZipBlob(files, { lastModified: createdAt });\n}\n\nexport function downloadBlob(\n blob: Blob,\n filenameOrOptions: string | DownloadBlobOptions = {},\n): string {\n const options =\n typeof filenameOrOptions === \"string\" ? { filename: filenameOrOptions } : filenameOrOptions;\n const documentRef = options.document ?? globalThis.document;\n const urlRef = options.url ?? globalThis.URL;\n if (!documentRef?.body || !urlRef?.createObjectURL || !urlRef.revokeObjectURL) {\n throw new Error(\"downloadBlob requires document and URL.createObjectURL\");\n }\n\n const href = urlRef.createObjectURL(blob);\n const anchor = documentRef.createElement(\"a\");\n anchor.href = href;\n anchor.download = options.filename ?? \"loggerjs-logs.zip\";\n anchor.style.display = \"none\";\n documentRef.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n\n const revoke = () => urlRef.revokeObjectURL(href);\n const revokeDelayMs = options.revokeDelayMs ?? 1000;\n if (revokeDelayMs <= 0) {\n revoke();\n } else {\n setTimeout(revoke, revokeDelayMs);\n }\n\n return href;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loggerjs/browser",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Browser transports and integrations for loggerjs.",
|
|
5
5
|
"homepage": "https://github.com/jskits/loggerjs/tree/main/packages/browser#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"provenance": true
|
|
160
160
|
},
|
|
161
161
|
"dependencies": {
|
|
162
|
-
"@loggerjs/core": "0.5.
|
|
162
|
+
"@loggerjs/core": "0.5.3"
|
|
163
163
|
},
|
|
164
164
|
"loggerjsSubpathEntries": {
|
|
165
165
|
"http-transport": "src/http-transport.ts",
|