@bazariodev/docket 0.0.0 → 1.0.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +715 -173
  3. package/dist/{chunk-B-SP8Od_.js → chunk-DkvWLziD.js} +3 -3
  4. package/dist/{chunk-B-SP8Od_.js.map → chunk-DkvWLziD.js.map} +1 -1
  5. package/dist/{chunk-Bvq4tF_F.cjs → chunk-ieB8yTEn.cjs} +2 -3
  6. package/dist/{chunk-Bvq4tF_F.cjs.map → chunk-ieB8yTEn.cjs.map} +1 -1
  7. package/dist/client/index.cjs +167 -0
  8. package/dist/client/index.cjs.map +1 -0
  9. package/dist/client/index.d.cts +40 -0
  10. package/dist/client/index.d.ts +40 -0
  11. package/dist/client/index.js +165 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/constants.d.cts +2 -4
  14. package/dist/constants.d.ts +2 -4
  15. package/dist/export/index.cjs +39 -11
  16. package/dist/export/index.cjs.map +1 -1
  17. package/dist/export/index.js +39 -11
  18. package/dist/export/index.js.map +1 -1
  19. package/dist/history/index.cjs +21 -1187
  20. package/dist/history/index.cjs.map +1 -1
  21. package/dist/history/index.d.cts +10 -112
  22. package/dist/history/index.d.ts +10 -112
  23. package/dist/history/index.js +22 -1188
  24. package/dist/history/index.js.map +1 -1
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.d.cts +1 -0
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +1 -1
  29. package/dist/indexeddb/index.cjs +18 -7
  30. package/dist/indexeddb/index.cjs.map +1 -1
  31. package/dist/indexeddb/index.d.cts +19 -4
  32. package/dist/indexeddb/index.d.ts +19 -4
  33. package/dist/indexeddb/index.js +18 -8
  34. package/dist/indexeddb/index.js.map +1 -1
  35. package/dist/storage/contracts.d.cts +0 -4
  36. package/dist/storage/contracts.d.ts +0 -4
  37. package/dist/upload/constants.d.cts +17 -0
  38. package/dist/upload/constants.d.ts +17 -0
  39. package/dist/upload/index.cjs +246 -0
  40. package/dist/upload/index.cjs.map +1 -0
  41. package/dist/upload/index.d.cts +51 -0
  42. package/dist/upload/index.d.ts +51 -0
  43. package/dist/upload/index.js +244 -0
  44. package/dist/upload/index.js.map +1 -0
  45. package/package.json +25 -2
  46. package/dist/core/errors.d.cts +0 -8
  47. package/dist/core/errors.d.ts +0 -8
  48. package/dist/history/constants.d.cts +0 -35
  49. package/dist/history/constants.d.ts +0 -35
  50. package/dist/sip/constants.d.cts +0 -5
  51. package/dist/sip/constants.d.ts +0 -5
@@ -0,0 +1,165 @@
1
+ import { c as createLogging } from '../chunk-DkvWLziD.js';
2
+ import { createMemoryHistory } from '../history/index.js';
3
+ import { createUploadSink } from '../upload/index.js';
4
+ import '../chunk-LRCHwVuE.js';
5
+ import '../chunk-CSS3f4_M.js';
6
+ import '../chunk-7ld72rnl.js';
7
+ import '@bazariodev/coordination';
8
+
9
+ const CLIENT_DEFAULTS = Object.freeze({
10
+ MAX_HISTORY_RECORDS: 1000,
11
+ MAX_BATCH_RECORDS: 100,
12
+ INTERVAL_MS: 5000,
13
+ });
14
+
15
+ const HISTORY_METHODS = Object.freeze({
16
+ REQUIRED: Object.freeze(['write', 'query', 'clear']),
17
+ OPTIONAL: Object.freeze(['flush', 'stop', 'getStatus']),
18
+ });
19
+
20
+ function resolveHistory(history) {
21
+ if (history === false) return undefined;
22
+ if (history === undefined)
23
+ return createMemoryHistory({
24
+ maxRecords: CLIENT_DEFAULTS.MAX_HISTORY_RECORDS,
25
+ });
26
+ if (!history || typeof history !== 'object')
27
+ throw new TypeError('Invalid history options');
28
+ if (
29
+ !HISTORY_METHODS.REQUIRED.some((method) => method in history) &&
30
+ !HISTORY_METHODS.OPTIONAL.some((method) => method in history)
31
+ )
32
+ return createMemoryHistory(history);
33
+ if (
34
+ HISTORY_METHODS.REQUIRED.some(
35
+ (method) => typeof history[method] !== 'function',
36
+ )
37
+ )
38
+ throw new TypeError('A history client requires write, query, and clear');
39
+ for (const method of HISTORY_METHODS.OPTIONAL)
40
+ if (history[method] !== undefined && typeof history[method] !== 'function')
41
+ throw new TypeError(`Invalid history ${method}`);
42
+ return history;
43
+ }
44
+
45
+ function createDocket(options) {
46
+ if (!options || typeof options !== 'object')
47
+ throw new TypeError('Docket options are required');
48
+ const {
49
+ areas,
50
+ redactor,
51
+ sinks: suppliedSinks,
52
+ context,
53
+ levelStorage,
54
+ maxOverrideMs,
55
+ stormLimit,
56
+ scheduler,
57
+ now,
58
+ monotonicNow,
59
+ createRunId,
60
+ onError,
61
+ history: historyOption,
62
+ upload: uploadOption,
63
+ isActive: isApplicationActive,
64
+ } = options;
65
+ const history = resolveHistory(historyOption);
66
+ let upload;
67
+ let uploadOptions;
68
+ let outbox;
69
+ if (uploadOption !== undefined && uploadOption !== false) {
70
+ if (!uploadOption || typeof uploadOption !== 'object')
71
+ throw new TypeError('Invalid upload options');
72
+ outbox = uploadOption.outbox;
73
+ if (
74
+ !outbox ||
75
+ outbox === history ||
76
+ typeof outbox.clear !== 'function' ||
77
+ typeof outbox.stop !== 'function'
78
+ )
79
+ throw new TypeError('Upload requires a separate outbox client');
80
+ const {
81
+ maxBatchRecords = CLIENT_DEFAULTS.MAX_BATCH_RECORDS,
82
+ intervalMs = CLIENT_DEFAULTS.INTERVAL_MS,
83
+ scheduler,
84
+ onError,
85
+ send,
86
+ } = uploadOption;
87
+ if (typeof send !== 'function')
88
+ throw new TypeError('An upload callback is required');
89
+ uploadOptions = {
90
+ maxBatchRecords,
91
+ intervalMs,
92
+ scheduler,
93
+ onError,
94
+ send: (records, signal, token) =>
95
+ send.call(uploadOption, records, signal, token),
96
+ };
97
+ }
98
+ const sinks = [...(suppliedSinks ?? [])];
99
+ if (history) sinks.push(history);
100
+ for (const sink of sinks)
101
+ if (!sink || typeof sink.write !== 'function')
102
+ throw new TypeError('A sink must have write');
103
+ let closed = false;
104
+ const logging = createLogging({
105
+ areas,
106
+ redactor,
107
+ context,
108
+ levelStorage,
109
+ maxOverrideMs,
110
+ stormLimit,
111
+ scheduler,
112
+ now,
113
+ monotonicNow,
114
+ createRunId: createRunId ? () => createRunId.call(options) : createRunId,
115
+ onError,
116
+ isActive() {
117
+ if (closed) return false;
118
+ const active = isApplicationActive?.call(options);
119
+ return !closed && active !== false;
120
+ },
121
+ sinks: [],
122
+ });
123
+ const detachments = [];
124
+ try {
125
+ if (uploadOptions) upload = createUploadSink(uploadOptions, outbox);
126
+ if (upload) sinks.push(upload);
127
+ for (const sink of sinks) detachments.push(logging.addSink(sink));
128
+ } catch (error) {
129
+ for (const detach of detachments) detach();
130
+ void upload?.stop();
131
+ void logging.stop().catch(() => {});
132
+ throw error;
133
+ }
134
+ let stopped;
135
+ return Object.freeze({
136
+ ...logging,
137
+ history,
138
+ upload,
139
+ outbox,
140
+ stop() {
141
+ if (stopped) return stopped;
142
+ closed = true;
143
+ stopped = Promise.resolve().then(async () => {
144
+ const failures = [];
145
+ try {
146
+ await logging.stop();
147
+ } catch (error) {
148
+ failures.push(error);
149
+ }
150
+ try {
151
+ await outbox?.stop();
152
+ } catch (error) {
153
+ failures.push(error);
154
+ }
155
+ if (failures.length)
156
+ throw new AggregateError(failures, 'Docket shutdown failed');
157
+ });
158
+ void upload?.stop();
159
+ return stopped;
160
+ },
161
+ });
162
+ }
163
+
164
+ export { createDocket };
165
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/client/constants.js","../../src/client/index.js"],"sourcesContent":["export const CLIENT_DEFAULTS = Object.freeze({\n MAX_HISTORY_RECORDS: 1000,\n MAX_BATCH_RECORDS: 100,\n INTERVAL_MS: 5000,\n});\n\nexport const HISTORY_METHODS = Object.freeze({\n REQUIRED: Object.freeze(['write', 'query', 'clear']),\n OPTIONAL: Object.freeze(['flush', 'stop', 'getStatus']),\n});\n","import { createLogging } from '../core/hub.js';\nimport { createMemoryHistory } from '../history/index.js';\nimport { createUploadSink } from '../upload/index.js';\nimport { CLIENT_DEFAULTS, HISTORY_METHODS } from './constants.js';\n\nfunction resolveHistory(history) {\n if (history === false) return undefined;\n if (history === undefined)\n return createMemoryHistory({\n maxRecords: CLIENT_DEFAULTS.MAX_HISTORY_RECORDS,\n });\n if (!history || typeof history !== 'object')\n throw new TypeError('Invalid history options');\n if (\n !HISTORY_METHODS.REQUIRED.some((method) => method in history) &&\n !HISTORY_METHODS.OPTIONAL.some((method) => method in history)\n )\n return createMemoryHistory(history);\n if (\n HISTORY_METHODS.REQUIRED.some(\n (method) => typeof history[method] !== 'function',\n )\n )\n throw new TypeError('A history client requires write, query, and clear');\n for (const method of HISTORY_METHODS.OPTIONAL)\n if (history[method] !== undefined && typeof history[method] !== 'function')\n throw new TypeError(`Invalid history ${method}`);\n return history;\n}\n\nexport function createDocket(options) {\n if (!options || typeof options !== 'object')\n throw new TypeError('Docket options are required');\n const {\n areas,\n redactor,\n sinks: suppliedSinks,\n context,\n levelStorage,\n maxOverrideMs,\n stormLimit,\n scheduler,\n now,\n monotonicNow,\n createRunId,\n onError,\n history: historyOption,\n upload: uploadOption,\n isActive: isApplicationActive,\n } = options;\n const history = resolveHistory(historyOption);\n let upload;\n let uploadOptions;\n let outbox;\n if (uploadOption !== undefined && uploadOption !== false) {\n if (!uploadOption || typeof uploadOption !== 'object')\n throw new TypeError('Invalid upload options');\n outbox = uploadOption.outbox;\n if (\n !outbox ||\n outbox === history ||\n typeof outbox.clear !== 'function' ||\n typeof outbox.stop !== 'function'\n )\n throw new TypeError('Upload requires a separate outbox client');\n const {\n maxBatchRecords = CLIENT_DEFAULTS.MAX_BATCH_RECORDS,\n intervalMs = CLIENT_DEFAULTS.INTERVAL_MS,\n scheduler,\n onError,\n send,\n } = uploadOption;\n if (typeof send !== 'function')\n throw new TypeError('An upload callback is required');\n uploadOptions = {\n maxBatchRecords,\n intervalMs,\n scheduler,\n onError,\n send: (records, signal, token) =>\n send.call(uploadOption, records, signal, token),\n };\n }\n const sinks = [...(suppliedSinks ?? [])];\n if (history) sinks.push(history);\n for (const sink of sinks)\n if (!sink || typeof sink.write !== 'function')\n throw new TypeError('A sink must have write');\n let closed = false;\n const logging = createLogging({\n areas,\n redactor,\n context,\n levelStorage,\n maxOverrideMs,\n stormLimit,\n scheduler,\n now,\n monotonicNow,\n createRunId: createRunId ? () => createRunId.call(options) : createRunId,\n onError,\n isActive() {\n if (closed) return false;\n const active = isApplicationActive?.call(options);\n return !closed && active !== false;\n },\n sinks: [],\n });\n const detachments = [];\n try {\n if (uploadOptions) upload = createUploadSink(uploadOptions, outbox);\n if (upload) sinks.push(upload);\n for (const sink of sinks) detachments.push(logging.addSink(sink));\n } catch (error) {\n for (const detach of detachments) detach();\n void upload?.stop();\n void logging.stop().catch(() => {});\n throw error;\n }\n let stopped;\n return Object.freeze({\n ...logging,\n history,\n upload,\n outbox,\n stop() {\n if (stopped) return stopped;\n closed = true;\n stopped = Promise.resolve().then(async () => {\n const failures = [];\n try {\n await logging.stop();\n } catch (error) {\n failures.push(error);\n }\n try {\n await outbox?.stop();\n } catch (error) {\n failures.push(error);\n }\n if (failures.length)\n throw new AggregateError(failures, 'Docket shutdown failed');\n });\n void upload?.stop();\n return stopped;\n },\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,4 @@
1
1
  export { ENVIRONMENT_FIELDS } from "./browser/constants.cjs";
2
- export { LOGGING_ERRORS } from "./core/errors.cjs";
3
- export { SIP_ERRORS } from "./sip/constants.cjs";
4
- export { LEVELS, LIMITS, LOGGING_ERROR_CODES, LOGGING_ERROR_SOURCES, LOGGING_LIMITS, MARKERS } from "./core/constants.cjs";
5
- export { HISTORY_ERROR_CODES, HISTORY_ERRORS, HISTORY_LIMITS, HISTORY_MODES, HISTORY_STATES } from "./history/constants.cjs";
2
+ export { UPLOAD_STORAGE_MODES } from "./upload/constants.cjs";
3
+ export { LEVELS, LIMITS, LOGGING_ERROR_CODES, LOGGING_ERROR_SOURCES, MARKERS } from "./core/constants.cjs";
6
4
  export { OVERFLOW_STRATEGIES, STORE_MODES } from "./storage/constants.cjs";
@@ -1,6 +1,4 @@
1
1
  export { ENVIRONMENT_FIELDS } from "./browser/constants.js";
2
- export { LOGGING_ERRORS } from "./core/errors.js";
3
- export { SIP_ERRORS } from "./sip/constants.js";
4
- export { LEVELS, LIMITS, LOGGING_ERROR_CODES, LOGGING_ERROR_SOURCES, LOGGING_LIMITS, MARKERS } from "./core/constants.js";
5
- export { HISTORY_ERROR_CODES, HISTORY_ERRORS, HISTORY_LIMITS, HISTORY_MODES, HISTORY_STATES } from "./history/constants.js";
2
+ export { UPLOAD_STORAGE_MODES } from "./upload/constants.js";
3
+ export { LEVELS, LIMITS, LOGGING_ERROR_CODES, LOGGING_ERROR_SOURCES, MARKERS } from "./core/constants.js";
6
4
  export { OVERFLOW_STRATEGIES, STORE_MODES } from "./storage/constants.js";
@@ -5,7 +5,13 @@ var conversion = require('../chunk-CEhpwtwJ.cjs');
5
5
  var format = require('../chunk-DqK_3eFr.cjs');
6
6
  require('../chunk-BLf-eCDO.cjs');
7
7
 
8
- const EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({ YIELD_RECORDS: 100 });
8
+ const EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({
9
+ YIELD_RECORDS: 100,
10
+ ENCODING_BUFFER_BYTES: 4096,
11
+ });
12
+ const EXPORT_ERRORS = /* @__PURE__ */ Object.freeze({
13
+ INPUT_LIMIT: 'ZIP input limit exceeded',
14
+ });
9
15
 
10
16
  async function createLogBundle(options, archive) {
11
17
  if (
@@ -47,6 +53,23 @@ async function createLogBundle(options, archive) {
47
53
  const contents = [];
48
54
  const summaries = [];
49
55
  const warnings = [];
56
+ const encoder = new TextEncoder();
57
+ const buffer = new Uint8Array(EXPORT_LIMITS.ENCODING_BUFFER_BYTES);
58
+ let remainingBytes = maxInputSize;
59
+
60
+ function chargeText(text) {
61
+ if (text.length > remainingBytes)
62
+ throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);
63
+ let offset = 0;
64
+ while (offset < text.length) {
65
+ const { read, written } = encoder.encodeInto(text.slice(offset), buffer);
66
+ if (written > remainingBytes)
67
+ throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);
68
+ remainingBytes -= written;
69
+ offset += read;
70
+ }
71
+ }
72
+
50
73
  for (const file of files) {
51
74
  const selected = records.filter((record) =>
52
75
  file.areas.includes(record.area),
@@ -59,6 +82,7 @@ async function createLogBundle(options, archive) {
59
82
  content = typeof result === 'string' ? result : result?.content;
60
83
  if (typeof content !== 'string' || result?.then)
61
84
  throw new TypeError('Bundle renderers must return text synchronously');
85
+ chargeText(content);
62
86
  for (const warning of result?.warnings ?? []) {
63
87
  if (warnings.length >= redactor.limits.maxArrayLength) break;
64
88
  if (typeof warning !== 'string')
@@ -68,22 +92,27 @@ async function createLogBundle(options, archive) {
68
92
  } else {
69
93
  const lines = [];
70
94
  for (let index = 0; index < selected.length; index++) {
71
- lines.push(format.formatRecord(selected[index]));
95
+ const line = `${format.formatRecord(selected[index])}\n`;
96
+ chargeText(line);
97
+ lines.push(line);
72
98
  if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)
73
99
  await new Promise((resolve) => scheduler.setTimeout(resolve, 0));
74
100
  }
75
- content = `${lines.join('\n')}\n`;
101
+ content = lines.join('');
76
102
  }
77
103
  contents.push({ name: file.name, content });
78
104
  }
105
+ let earliest = null;
106
+ let latest = null;
107
+ for (const record of records) {
108
+ earliest = earliest === null ? record.at : Math.min(earliest, record.at);
109
+ latest = latest === null ? record.at : Math.max(latest, record.at);
110
+ }
79
111
  const manifest = {
80
112
  schemaVersion: 1,
81
113
  builtAt: new Date(now()).toISOString(),
82
114
  requestedRange: { from: from ?? null, to: to ?? null },
83
- actualRange: {
84
- from: records[0]?.at ?? null,
85
- to: records.at(-1)?.at ?? null,
86
- },
115
+ actualRange: { from: earliest, to: latest },
87
116
  files: summaries,
88
117
  truncatedRecords: records.filter((record) => record.truncated).length,
89
118
  warnings,
@@ -96,10 +125,9 @@ async function createLogBundle(options, archive) {
96
125
  redactor.limits,
97
126
  ),
98
127
  };
99
- contents.push({
100
- name: 'manifest.json',
101
- content: JSON.stringify(manifest, null, 2),
102
- });
128
+ const manifestText = JSON.stringify(manifest, null, 2);
129
+ chargeText(manifestText);
130
+ contents.push({ name: 'manifest.json', content: manifestText });
103
131
  return Object.freeze({
104
132
  blob: await archive.balingZip(contents, { maxInputSize }),
105
133
  fileName,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/export/index.js"],"sourcesContent":["import { scheduler as hostScheduler, validateQuery } from '../core/common.js';\nimport { ownJson } from '../core/conversion.js';\nimport { formatRecord } from '../core/format.js';\n\nconst EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({ YIELD_RECORDS: 100 });\n\nexport async function createLogBundle(options, archive) {\n if (\n !archive ||\n typeof archive.balingZip !== 'function' ||\n typeof archive.validateFileNames !== 'function' ||\n typeof archive.validateZipOptions !== 'function'\n )\n throw new TypeError('Archive capabilities are required');\n const {\n source,\n redactor,\n files,\n from,\n to,\n now = Date.now,\n scheduler = hostScheduler,\n } = options;\n const maxInputSize = archive.validateZipOptions(options);\n validateQuery({ from, to });\n if (!Array.isArray(files))\n throw new TypeError('Bundle files must be an array');\n for (const file of files) {\n if (!file || !Array.isArray(file.areas))\n throw new TypeError('Bundle file areas must be an array');\n validateQuery({ areas: file.areas });\n }\n archive.validateFileNames([\n 'manifest.json',\n ...files.map(({ name }) => name),\n ]);\n const fileName =\n options.fileName ??\n `logs-${new Date(now()).toISOString().replaceAll(':', '-')}.zip`;\n archive.validateFileNames([fileName]);\n const areas = Array.from(new Set(files.flatMap((file) => file.areas)));\n const records = await source.query({ areas, from, to });\n const status = source.getStatus?.();\n const contents = [];\n const summaries = [];\n const warnings = [];\n for (const file of files) {\n const selected = records.filter((record) =>\n file.areas.includes(record.area),\n );\n summaries.push({ name: file.name, records: selected.length });\n if (!selected.length) continue;\n let content;\n if (file.render) {\n const result = file.render(selected);\n content = typeof result === 'string' ? result : result?.content;\n if (typeof content !== 'string' || result?.then)\n throw new TypeError('Bundle renderers must return text synchronously');\n for (const warning of result?.warnings ?? []) {\n if (warnings.length >= redactor.limits.maxArrayLength) break;\n if (typeof warning !== 'string')\n throw new TypeError('Renderer warnings must be strings');\n warnings.push(ownJson(redactor.redactText(warning), redactor.limits));\n }\n } else {\n const lines = [];\n for (let index = 0; index < selected.length; index++) {\n lines.push(formatRecord(selected[index]));\n if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)\n await new Promise((resolve) => scheduler.setTimeout(resolve, 0));\n }\n content = `${lines.join('\\n')}\\n`;\n }\n contents.push({ name: file.name, content });\n }\n const manifest = {\n schemaVersion: 1,\n builtAt: new Date(now()).toISOString(),\n requestedRange: { from: from ?? null, to: to ?? null },\n actualRange: {\n from: records[0]?.at ?? null,\n to: records.at(-1)?.at ?? null,\n },\n files: summaries,\n truncatedRecords: records.filter((record) => record.truncated).length,\n warnings,\n ...(status ? { store: status } : {}),\n redactionVersions: Array.from(\n new Set(records.map((record) => record.redactionVersion)),\n ),\n application: ownJson(\n redactor.redactValue(options.manifest ?? {}),\n redactor.limits,\n ),\n };\n contents.push({\n name: 'manifest.json',\n content: JSON.stringify(manifest, null, 2),\n });\n return Object.freeze({\n blob: await archive.balingZip(contents, { maxInputSize }),\n fileName,\n files: Object.freeze(summaries.map(Object.freeze)),\n });\n}\n"],"names":["hostScheduler","validateQuery","ownJson","formatRecord"],"mappings":";;;;;;;AAIA,MAAM,aAAa,mBAAmB,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;;AAEpE,eAAe,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE;AACxD,EAAE;AACF,IAAI,CAAC,OAAO;AACZ,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU;AAC3C,IAAI,OAAO,OAAO,CAAC,iBAAiB,KAAK,UAAU;AACnD,IAAI,OAAO,OAAO,CAAC,kBAAkB,KAAK;AAC1C;AACA,IAAI,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC;AAC5D,EAAE,MAAM;AACR,IAAI,MAAM;AACV,IAAI,QAAQ;AACZ,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,EAAE;AACN,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG;AAClB,IAAI,SAAS,GAAGA,gBAAa;AAC7B,GAAG,GAAG,OAAO;AACb,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC;AAC1D,EAAEC,oBAAa,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC7B,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAC3B,IAAI,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC;AACxD,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC5B,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3C,MAAM,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC;AAC/D,IAAIA,oBAAa,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACxC,EAAE;AACF,EAAE,OAAO,CAAC,iBAAiB,CAAC;AAC5B,IAAI,eAAe;AACnB,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AACpC,GAAG,CAAC;AACJ,EAAE,MAAM,QAAQ;AAChB,IAAI,OAAO,CAAC,QAAQ;AACpB,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC;AACpE,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC;AACvC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,EAAE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACzD,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,IAAI;AACrC,EAAE,MAAM,QAAQ,GAAG,EAAE;AACrB,EAAE,MAAM,SAAS,GAAG,EAAE;AACtB,EAAE,MAAM,QAAQ,GAAG,EAAE;AACrB,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC5B,IAAI,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM;AAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AACtC,KAAK;AACL,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AACjE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;AAC1B,IAAI,IAAI,OAAO;AACf,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;AACrB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1C,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO;AACrE,MAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,EAAE,IAAI;AACrD,QAAQ,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC;AAC9E,MAAM,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,QAAQ,IAAI,EAAE,EAAE;AACpD,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE;AAC/D,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ;AACvC,UAAU,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC;AAClE,QAAQ,QAAQ,CAAC,IAAI,CAACC,kBAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM;AACN,IAAI,CAAC,MAAM;AACX,MAAM,MAAM,KAAK,GAAG,EAAE;AACtB,MAAM,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;AAC5D,QAAQ,KAAK,CAAC,IAAI,CAACC,mBAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACjD,QAAQ,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,aAAa,CAAC,aAAa,KAAK,CAAC;AAC3D,UAAU,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC1E,MAAM;AACN,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACvC,IAAI;AACJ,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/C,EAAE;AACF,EAAE,MAAM,QAAQ,GAAG;AACnB,IAAI,aAAa,EAAE,CAAC;AACpB,IAAI,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE;AAC1C,IAAI,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE;AAC1D,IAAI,WAAW,EAAE;AACjB,MAAM,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI;AAClC,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,IAAI;AACpC,KAAK;AACL,IAAI,KAAK,EAAE,SAAS;AACpB,IAAI,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM;AACzE,IAAI,QAAQ;AACZ,IAAI,IAAI,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACxC,IAAI,iBAAiB,EAAE,KAAK,CAAC,IAAI;AACjC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC/D,KAAK;AACL,IAAI,WAAW,EAAED,kBAAO;AACxB,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAClD,MAAM,QAAQ,CAAC,MAAM;AACrB,KAAK;AACL,GAAG;AACH,EAAE,QAAQ,CAAC,IAAI,CAAC;AAChB,IAAI,IAAI,EAAE,eAAe;AACzB,IAAI,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9C,GAAG,CAAC;AACJ,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,IAAI,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC;AAC7D,IAAI,QAAQ;AACZ,IAAI,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACtD,GAAG,CAAC;AACJ;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/export/index.js"],"sourcesContent":["import { scheduler as hostScheduler, validateQuery } from '../core/common.js';\nimport { ownJson } from '../core/conversion.js';\nimport { formatRecord } from '../core/format.js';\n\nconst EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({\n YIELD_RECORDS: 100,\n ENCODING_BUFFER_BYTES: 4096,\n});\nconst EXPORT_ERRORS = /* @__PURE__ */ Object.freeze({\n INPUT_LIMIT: 'ZIP input limit exceeded',\n});\n\nexport async function createLogBundle(options, archive) {\n if (\n !archive ||\n typeof archive.balingZip !== 'function' ||\n typeof archive.validateFileNames !== 'function' ||\n typeof archive.validateZipOptions !== 'function'\n )\n throw new TypeError('Archive capabilities are required');\n const {\n source,\n redactor,\n files,\n from,\n to,\n now = Date.now,\n scheduler = hostScheduler,\n } = options;\n const maxInputSize = archive.validateZipOptions(options);\n validateQuery({ from, to });\n if (!Array.isArray(files))\n throw new TypeError('Bundle files must be an array');\n for (const file of files) {\n if (!file || !Array.isArray(file.areas))\n throw new TypeError('Bundle file areas must be an array');\n validateQuery({ areas: file.areas });\n }\n archive.validateFileNames([\n 'manifest.json',\n ...files.map(({ name }) => name),\n ]);\n const fileName =\n options.fileName ??\n `logs-${new Date(now()).toISOString().replaceAll(':', '-')}.zip`;\n archive.validateFileNames([fileName]);\n const areas = Array.from(new Set(files.flatMap((file) => file.areas)));\n const records = await source.query({ areas, from, to });\n const status = source.getStatus?.();\n const contents = [];\n const summaries = [];\n const warnings = [];\n const encoder = new TextEncoder();\n const buffer = new Uint8Array(EXPORT_LIMITS.ENCODING_BUFFER_BYTES);\n let remainingBytes = maxInputSize;\n\n function chargeText(text) {\n if (text.length > remainingBytes)\n throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);\n let offset = 0;\n while (offset < text.length) {\n const { read, written } = encoder.encodeInto(text.slice(offset), buffer);\n if (written > remainingBytes)\n throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);\n remainingBytes -= written;\n offset += read;\n }\n }\n\n for (const file of files) {\n const selected = records.filter((record) =>\n file.areas.includes(record.area),\n );\n summaries.push({ name: file.name, records: selected.length });\n if (!selected.length) continue;\n let content;\n if (file.render) {\n const result = file.render(selected);\n content = typeof result === 'string' ? result : result?.content;\n if (typeof content !== 'string' || result?.then)\n throw new TypeError('Bundle renderers must return text synchronously');\n chargeText(content);\n for (const warning of result?.warnings ?? []) {\n if (warnings.length >= redactor.limits.maxArrayLength) break;\n if (typeof warning !== 'string')\n throw new TypeError('Renderer warnings must be strings');\n warnings.push(ownJson(redactor.redactText(warning), redactor.limits));\n }\n } else {\n const lines = [];\n for (let index = 0; index < selected.length; index++) {\n const line = `${formatRecord(selected[index])}\\n`;\n chargeText(line);\n lines.push(line);\n if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)\n await new Promise((resolve) => scheduler.setTimeout(resolve, 0));\n }\n content = lines.join('');\n }\n contents.push({ name: file.name, content });\n }\n let earliest = null;\n let latest = null;\n for (const record of records) {\n earliest = earliest === null ? record.at : Math.min(earliest, record.at);\n latest = latest === null ? record.at : Math.max(latest, record.at);\n }\n const manifest = {\n schemaVersion: 1,\n builtAt: new Date(now()).toISOString(),\n requestedRange: { from: from ?? null, to: to ?? null },\n actualRange: { from: earliest, to: latest },\n files: summaries,\n truncatedRecords: records.filter((record) => record.truncated).length,\n warnings,\n ...(status ? { store: status } : {}),\n redactionVersions: Array.from(\n new Set(records.map((record) => record.redactionVersion)),\n ),\n application: ownJson(\n redactor.redactValue(options.manifest ?? {}),\n redactor.limits,\n ),\n };\n const manifestText = JSON.stringify(manifest, null, 2);\n chargeText(manifestText);\n contents.push({ name: 'manifest.json', content: manifestText });\n return Object.freeze({\n blob: await archive.balingZip(contents, { maxInputSize }),\n fileName,\n files: Object.freeze(summaries.map(Object.freeze)),\n });\n}\n"],"names":["hostScheduler","validateQuery","ownJson","formatRecord"],"mappings":"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"}
@@ -3,7 +3,13 @@ import { o as ownJson } from '../chunk-7ld72rnl.js';
3
3
  import { f as formatRecord } from '../chunk-DYcNnkOV.js';
4
4
  import '../chunk-CSS3f4_M.js';
5
5
 
6
- const EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({ YIELD_RECORDS: 100 });
6
+ const EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({
7
+ YIELD_RECORDS: 100,
8
+ ENCODING_BUFFER_BYTES: 4096,
9
+ });
10
+ const EXPORT_ERRORS = /* @__PURE__ */ Object.freeze({
11
+ INPUT_LIMIT: 'ZIP input limit exceeded',
12
+ });
7
13
 
8
14
  async function createLogBundle(options, archive) {
9
15
  if (
@@ -45,6 +51,23 @@ async function createLogBundle(options, archive) {
45
51
  const contents = [];
46
52
  const summaries = [];
47
53
  const warnings = [];
54
+ const encoder = new TextEncoder();
55
+ const buffer = new Uint8Array(EXPORT_LIMITS.ENCODING_BUFFER_BYTES);
56
+ let remainingBytes = maxInputSize;
57
+
58
+ function chargeText(text) {
59
+ if (text.length > remainingBytes)
60
+ throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);
61
+ let offset = 0;
62
+ while (offset < text.length) {
63
+ const { read, written } = encoder.encodeInto(text.slice(offset), buffer);
64
+ if (written > remainingBytes)
65
+ throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);
66
+ remainingBytes -= written;
67
+ offset += read;
68
+ }
69
+ }
70
+
48
71
  for (const file of files) {
49
72
  const selected = records.filter((record) =>
50
73
  file.areas.includes(record.area),
@@ -57,6 +80,7 @@ async function createLogBundle(options, archive) {
57
80
  content = typeof result === 'string' ? result : result?.content;
58
81
  if (typeof content !== 'string' || result?.then)
59
82
  throw new TypeError('Bundle renderers must return text synchronously');
83
+ chargeText(content);
60
84
  for (const warning of result?.warnings ?? []) {
61
85
  if (warnings.length >= redactor.limits.maxArrayLength) break;
62
86
  if (typeof warning !== 'string')
@@ -66,22 +90,27 @@ async function createLogBundle(options, archive) {
66
90
  } else {
67
91
  const lines = [];
68
92
  for (let index = 0; index < selected.length; index++) {
69
- lines.push(formatRecord(selected[index]));
93
+ const line = `${formatRecord(selected[index])}\n`;
94
+ chargeText(line);
95
+ lines.push(line);
70
96
  if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)
71
97
  await new Promise((resolve) => scheduler$1.setTimeout(resolve, 0));
72
98
  }
73
- content = `${lines.join('\n')}\n`;
99
+ content = lines.join('');
74
100
  }
75
101
  contents.push({ name: file.name, content });
76
102
  }
103
+ let earliest = null;
104
+ let latest = null;
105
+ for (const record of records) {
106
+ earliest = earliest === null ? record.at : Math.min(earliest, record.at);
107
+ latest = latest === null ? record.at : Math.max(latest, record.at);
108
+ }
77
109
  const manifest = {
78
110
  schemaVersion: 1,
79
111
  builtAt: new Date(now()).toISOString(),
80
112
  requestedRange: { from: from ?? null, to: to ?? null },
81
- actualRange: {
82
- from: records[0]?.at ?? null,
83
- to: records.at(-1)?.at ?? null,
84
- },
113
+ actualRange: { from: earliest, to: latest },
85
114
  files: summaries,
86
115
  truncatedRecords: records.filter((record) => record.truncated).length,
87
116
  warnings,
@@ -94,10 +123,9 @@ async function createLogBundle(options, archive) {
94
123
  redactor.limits,
95
124
  ),
96
125
  };
97
- contents.push({
98
- name: 'manifest.json',
99
- content: JSON.stringify(manifest, null, 2),
100
- });
126
+ const manifestText = JSON.stringify(manifest, null, 2);
127
+ chargeText(manifestText);
128
+ contents.push({ name: 'manifest.json', content: manifestText });
101
129
  return Object.freeze({
102
130
  blob: await archive.balingZip(contents, { maxInputSize }),
103
131
  fileName,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/export/index.js"],"sourcesContent":["import { scheduler as hostScheduler, validateQuery } from '../core/common.js';\nimport { ownJson } from '../core/conversion.js';\nimport { formatRecord } from '../core/format.js';\n\nconst EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({ YIELD_RECORDS: 100 });\n\nexport async function createLogBundle(options, archive) {\n if (\n !archive ||\n typeof archive.balingZip !== 'function' ||\n typeof archive.validateFileNames !== 'function' ||\n typeof archive.validateZipOptions !== 'function'\n )\n throw new TypeError('Archive capabilities are required');\n const {\n source,\n redactor,\n files,\n from,\n to,\n now = Date.now,\n scheduler = hostScheduler,\n } = options;\n const maxInputSize = archive.validateZipOptions(options);\n validateQuery({ from, to });\n if (!Array.isArray(files))\n throw new TypeError('Bundle files must be an array');\n for (const file of files) {\n if (!file || !Array.isArray(file.areas))\n throw new TypeError('Bundle file areas must be an array');\n validateQuery({ areas: file.areas });\n }\n archive.validateFileNames([\n 'manifest.json',\n ...files.map(({ name }) => name),\n ]);\n const fileName =\n options.fileName ??\n `logs-${new Date(now()).toISOString().replaceAll(':', '-')}.zip`;\n archive.validateFileNames([fileName]);\n const areas = Array.from(new Set(files.flatMap((file) => file.areas)));\n const records = await source.query({ areas, from, to });\n const status = source.getStatus?.();\n const contents = [];\n const summaries = [];\n const warnings = [];\n for (const file of files) {\n const selected = records.filter((record) =>\n file.areas.includes(record.area),\n );\n summaries.push({ name: file.name, records: selected.length });\n if (!selected.length) continue;\n let content;\n if (file.render) {\n const result = file.render(selected);\n content = typeof result === 'string' ? result : result?.content;\n if (typeof content !== 'string' || result?.then)\n throw new TypeError('Bundle renderers must return text synchronously');\n for (const warning of result?.warnings ?? []) {\n if (warnings.length >= redactor.limits.maxArrayLength) break;\n if (typeof warning !== 'string')\n throw new TypeError('Renderer warnings must be strings');\n warnings.push(ownJson(redactor.redactText(warning), redactor.limits));\n }\n } else {\n const lines = [];\n for (let index = 0; index < selected.length; index++) {\n lines.push(formatRecord(selected[index]));\n if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)\n await new Promise((resolve) => scheduler.setTimeout(resolve, 0));\n }\n content = `${lines.join('\\n')}\\n`;\n }\n contents.push({ name: file.name, content });\n }\n const manifest = {\n schemaVersion: 1,\n builtAt: new Date(now()).toISOString(),\n requestedRange: { from: from ?? null, to: to ?? null },\n actualRange: {\n from: records[0]?.at ?? null,\n to: records.at(-1)?.at ?? null,\n },\n files: summaries,\n truncatedRecords: records.filter((record) => record.truncated).length,\n warnings,\n ...(status ? { store: status } : {}),\n redactionVersions: Array.from(\n new Set(records.map((record) => record.redactionVersion)),\n ),\n application: ownJson(\n redactor.redactValue(options.manifest ?? {}),\n redactor.limits,\n ),\n };\n contents.push({\n name: 'manifest.json',\n content: JSON.stringify(manifest, null, 2),\n });\n return Object.freeze({\n blob: await archive.balingZip(contents, { maxInputSize }),\n fileName,\n files: Object.freeze(summaries.map(Object.freeze)),\n });\n}\n"],"names":["scheduler","hostScheduler"],"mappings":";;;;;AAIA,MAAM,aAAa,mBAAmB,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;;AAEpE,eAAe,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE;AACxD,EAAE;AACF,IAAI,CAAC,OAAO;AACZ,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU;AAC3C,IAAI,OAAO,OAAO,CAAC,iBAAiB,KAAK,UAAU;AACnD,IAAI,OAAO,OAAO,CAAC,kBAAkB,KAAK;AAC1C;AACA,IAAI,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC;AAC5D,EAAE,MAAM;AACR,IAAI,MAAM;AACV,IAAI,QAAQ;AACZ,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,EAAE;AACN,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG;AAClB,eAAIA,WAAS,GAAGC,SAAa;AAC7B,GAAG,GAAG,OAAO;AACb,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC;AAC1D,EAAE,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC7B,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAC3B,IAAI,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC;AACxD,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC5B,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3C,MAAM,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC;AAC/D,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACxC,EAAE;AACF,EAAE,OAAO,CAAC,iBAAiB,CAAC;AAC5B,IAAI,eAAe;AACnB,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AACpC,GAAG,CAAC;AACJ,EAAE,MAAM,QAAQ;AAChB,IAAI,OAAO,CAAC,QAAQ;AACpB,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC;AACpE,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC;AACvC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,EAAE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACzD,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,IAAI;AACrC,EAAE,MAAM,QAAQ,GAAG,EAAE;AACrB,EAAE,MAAM,SAAS,GAAG,EAAE;AACtB,EAAE,MAAM,QAAQ,GAAG,EAAE;AACrB,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC5B,IAAI,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM;AAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AACtC,KAAK;AACL,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AACjE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;AAC1B,IAAI,IAAI,OAAO;AACf,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;AACrB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1C,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO;AACrE,MAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,EAAE,IAAI;AACrD,QAAQ,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC;AAC9E,MAAM,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,QAAQ,IAAI,EAAE,EAAE;AACpD,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE;AAC/D,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ;AACvC,UAAU,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC;AAClE,QAAQ,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM;AACN,IAAI,CAAC,MAAM;AACX,MAAM,MAAM,KAAK,GAAG,EAAE;AACtB,MAAM,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;AAC5D,QAAQ,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACjD,QAAQ,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,aAAa,CAAC,aAAa,KAAK,CAAC;AAC3D,UAAU,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,KAAKD,WAAS,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC1E,MAAM;AACN,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACvC,IAAI;AACJ,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/C,EAAE;AACF,EAAE,MAAM,QAAQ,GAAG;AACnB,IAAI,aAAa,EAAE,CAAC;AACpB,IAAI,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE;AAC1C,IAAI,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE;AAC1D,IAAI,WAAW,EAAE;AACjB,MAAM,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI;AAClC,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,IAAI;AACpC,KAAK;AACL,IAAI,KAAK,EAAE,SAAS;AACpB,IAAI,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM;AACzE,IAAI,QAAQ;AACZ,IAAI,IAAI,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACxC,IAAI,iBAAiB,EAAE,KAAK,CAAC,IAAI;AACjC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC/D,KAAK;AACL,IAAI,WAAW,EAAE,OAAO;AACxB,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAClD,MAAM,QAAQ,CAAC,MAAM;AACrB,KAAK;AACL,GAAG;AACH,EAAE,QAAQ,CAAC,IAAI,CAAC;AAChB,IAAI,IAAI,EAAE,eAAe;AACzB,IAAI,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9C,GAAG,CAAC;AACJ,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,IAAI,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC;AAC7D,IAAI,QAAQ;AACZ,IAAI,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACtD,GAAG,CAAC;AACJ;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/export/index.js"],"sourcesContent":["import { scheduler as hostScheduler, validateQuery } from '../core/common.js';\nimport { ownJson } from '../core/conversion.js';\nimport { formatRecord } from '../core/format.js';\n\nconst EXPORT_LIMITS = /* @__PURE__ */ Object.freeze({\n YIELD_RECORDS: 100,\n ENCODING_BUFFER_BYTES: 4096,\n});\nconst EXPORT_ERRORS = /* @__PURE__ */ Object.freeze({\n INPUT_LIMIT: 'ZIP input limit exceeded',\n});\n\nexport async function createLogBundle(options, archive) {\n if (\n !archive ||\n typeof archive.balingZip !== 'function' ||\n typeof archive.validateFileNames !== 'function' ||\n typeof archive.validateZipOptions !== 'function'\n )\n throw new TypeError('Archive capabilities are required');\n const {\n source,\n redactor,\n files,\n from,\n to,\n now = Date.now,\n scheduler = hostScheduler,\n } = options;\n const maxInputSize = archive.validateZipOptions(options);\n validateQuery({ from, to });\n if (!Array.isArray(files))\n throw new TypeError('Bundle files must be an array');\n for (const file of files) {\n if (!file || !Array.isArray(file.areas))\n throw new TypeError('Bundle file areas must be an array');\n validateQuery({ areas: file.areas });\n }\n archive.validateFileNames([\n 'manifest.json',\n ...files.map(({ name }) => name),\n ]);\n const fileName =\n options.fileName ??\n `logs-${new Date(now()).toISOString().replaceAll(':', '-')}.zip`;\n archive.validateFileNames([fileName]);\n const areas = Array.from(new Set(files.flatMap((file) => file.areas)));\n const records = await source.query({ areas, from, to });\n const status = source.getStatus?.();\n const contents = [];\n const summaries = [];\n const warnings = [];\n const encoder = new TextEncoder();\n const buffer = new Uint8Array(EXPORT_LIMITS.ENCODING_BUFFER_BYTES);\n let remainingBytes = maxInputSize;\n\n function chargeText(text) {\n if (text.length > remainingBytes)\n throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);\n let offset = 0;\n while (offset < text.length) {\n const { read, written } = encoder.encodeInto(text.slice(offset), buffer);\n if (written > remainingBytes)\n throw new RangeError(EXPORT_ERRORS.INPUT_LIMIT);\n remainingBytes -= written;\n offset += read;\n }\n }\n\n for (const file of files) {\n const selected = records.filter((record) =>\n file.areas.includes(record.area),\n );\n summaries.push({ name: file.name, records: selected.length });\n if (!selected.length) continue;\n let content;\n if (file.render) {\n const result = file.render(selected);\n content = typeof result === 'string' ? result : result?.content;\n if (typeof content !== 'string' || result?.then)\n throw new TypeError('Bundle renderers must return text synchronously');\n chargeText(content);\n for (const warning of result?.warnings ?? []) {\n if (warnings.length >= redactor.limits.maxArrayLength) break;\n if (typeof warning !== 'string')\n throw new TypeError('Renderer warnings must be strings');\n warnings.push(ownJson(redactor.redactText(warning), redactor.limits));\n }\n } else {\n const lines = [];\n for (let index = 0; index < selected.length; index++) {\n const line = `${formatRecord(selected[index])}\\n`;\n chargeText(line);\n lines.push(line);\n if ((index + 1) % EXPORT_LIMITS.YIELD_RECORDS === 0)\n await new Promise((resolve) => scheduler.setTimeout(resolve, 0));\n }\n content = lines.join('');\n }\n contents.push({ name: file.name, content });\n }\n let earliest = null;\n let latest = null;\n for (const record of records) {\n earliest = earliest === null ? record.at : Math.min(earliest, record.at);\n latest = latest === null ? record.at : Math.max(latest, record.at);\n }\n const manifest = {\n schemaVersion: 1,\n builtAt: new Date(now()).toISOString(),\n requestedRange: { from: from ?? null, to: to ?? null },\n actualRange: { from: earliest, to: latest },\n files: summaries,\n truncatedRecords: records.filter((record) => record.truncated).length,\n warnings,\n ...(status ? { store: status } : {}),\n redactionVersions: Array.from(\n new Set(records.map((record) => record.redactionVersion)),\n ),\n application: ownJson(\n redactor.redactValue(options.manifest ?? {}),\n redactor.limits,\n ),\n };\n const manifestText = JSON.stringify(manifest, null, 2);\n chargeText(manifestText);\n contents.push({ name: 'manifest.json', content: manifestText });\n return Object.freeze({\n blob: await archive.balingZip(contents, { maxInputSize }),\n fileName,\n files: Object.freeze(summaries.map(Object.freeze)),\n });\n}\n"],"names":["scheduler","hostScheduler"],"mappings":"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"}