@composy/log-viewer-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/index.js +961 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1 -0
- package/es/core/EventEmitter.d.ts +11 -0
- package/es/core/EventEmitter.d.ts.map +1 -0
- package/es/core/EventEmitter.js +40 -0
- package/es/core/EventEmitter.js.map +1 -0
- package/es/core/LogViewer.d.ts +46 -0
- package/es/core/LogViewer.d.ts.map +1 -0
- package/es/core/LogViewer.js +186 -0
- package/es/core/LogViewer.js.map +1 -0
- package/es/filters/FilterEngine.d.ts +26 -0
- package/es/filters/FilterEngine.d.ts.map +1 -0
- package/es/filters/FilterEngine.js +79 -0
- package/es/filters/FilterEngine.js.map +1 -0
- package/es/index.d.ts +26 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +26 -0
- package/es/index.js.map +1 -0
- package/es/renderers/DiffRenderer.d.ts +18 -0
- package/es/renderers/DiffRenderer.d.ts.map +1 -0
- package/es/renderers/DiffRenderer.js +60 -0
- package/es/renderers/DiffRenderer.js.map +1 -0
- package/es/renderers/TimelineRenderer.d.ts +22 -0
- package/es/renderers/TimelineRenderer.d.ts.map +1 -0
- package/es/renderers/TimelineRenderer.js +135 -0
- package/es/renderers/TimelineRenderer.js.map +1 -0
- package/es/styles/index.d.ts +9 -0
- package/es/styles/index.d.ts.map +1 -0
- package/es/styles/index.js +414 -0
- package/es/styles/index.js.map +1 -0
- package/es/types/index.d.ts +113 -0
- package/es/types/index.d.ts.map +1 -0
- package/es/types/index.js +40 -0
- package/es/types/index.js.map +1 -0
- package/es/utils/index.d.ts +18 -0
- package/es/utils/index.d.ts.map +1 -0
- package/es/utils/index.js +73 -0
- package/es/utils/index.js.map +1 -0
- package/esm/core/EventEmitter.d.ts +11 -0
- package/esm/core/EventEmitter.d.ts.map +1 -0
- package/esm/core/EventEmitter.js +40 -0
- package/esm/core/EventEmitter.js.map +1 -0
- package/esm/core/LogViewer.d.ts +46 -0
- package/esm/core/LogViewer.d.ts.map +1 -0
- package/esm/core/LogViewer.js +186 -0
- package/esm/core/LogViewer.js.map +1 -0
- package/esm/filters/FilterEngine.d.ts +26 -0
- package/esm/filters/FilterEngine.d.ts.map +1 -0
- package/esm/filters/FilterEngine.js +79 -0
- package/esm/filters/FilterEngine.js.map +1 -0
- package/esm/index.d.ts +26 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +26 -0
- package/esm/index.js.map +1 -0
- package/esm/renderers/DiffRenderer.d.ts +18 -0
- package/esm/renderers/DiffRenderer.d.ts.map +1 -0
- package/esm/renderers/DiffRenderer.js +60 -0
- package/esm/renderers/DiffRenderer.js.map +1 -0
- package/esm/renderers/TimelineRenderer.d.ts +22 -0
- package/esm/renderers/TimelineRenderer.d.ts.map +1 -0
- package/esm/renderers/TimelineRenderer.js +135 -0
- package/esm/renderers/TimelineRenderer.js.map +1 -0
- package/esm/styles/index.d.ts +9 -0
- package/esm/styles/index.d.ts.map +1 -0
- package/esm/styles/index.js +414 -0
- package/esm/styles/index.js.map +1 -0
- package/esm/types/index.d.ts +113 -0
- package/esm/types/index.d.ts.map +1 -0
- package/esm/types/index.js +40 -0
- package/esm/types/index.js.map +1 -0
- package/esm/utils/index.d.ts +18 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/esm/utils/index.js +73 -0
- package/esm/utils/index.js.map +1 -0
- package/lib/core/EventEmitter.cjs +41 -0
- package/lib/core/EventEmitter.cjs.map +1 -0
- package/lib/core/EventEmitter.d.ts +11 -0
- package/lib/core/LogViewer.cjs +187 -0
- package/lib/core/LogViewer.cjs.map +1 -0
- package/lib/core/LogViewer.d.ts +46 -0
- package/lib/filters/FilterEngine.cjs +80 -0
- package/lib/filters/FilterEngine.cjs.map +1 -0
- package/lib/filters/FilterEngine.d.ts +26 -0
- package/lib/index.cjs +43 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.ts +26 -0
- package/lib/package.json +3 -0
- package/lib/renderers/DiffRenderer.cjs +61 -0
- package/lib/renderers/DiffRenderer.cjs.map +1 -0
- package/lib/renderers/DiffRenderer.d.ts +18 -0
- package/lib/renderers/TimelineRenderer.cjs +136 -0
- package/lib/renderers/TimelineRenderer.cjs.map +1 -0
- package/lib/renderers/TimelineRenderer.d.ts +22 -0
- package/lib/styles/index.cjs +415 -0
- package/lib/styles/index.cjs.map +1 -0
- package/lib/styles/index.d.ts +9 -0
- package/lib/types/index.cjs +42 -0
- package/lib/types/index.cjs.map +1 -0
- package/lib/types/index.d.ts +113 -0
- package/lib/utils/index.cjs +80 -0
- package/lib/utils/index.cjs.map +1 -0
- package/lib/utils/index.d.ts +18 -0
- package/package.json +119 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/log-viewer-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:33:32 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
//#region src/utils/index.ts
|
|
11
|
+
let _uid = 0;
|
|
12
|
+
function uid(prefix = "lv") {
|
|
13
|
+
return `${prefix}-${++_uid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
14
|
+
}
|
|
15
|
+
function formatDate(value, fmt = "YYYY-MM-DD HH:mm:ss") {
|
|
16
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
17
|
+
if (isNaN(d.getTime())) return String(value);
|
|
18
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
19
|
+
const year = String(d.getFullYear());
|
|
20
|
+
const month = pad(d.getMonth() + 1);
|
|
21
|
+
const day = pad(d.getDate());
|
|
22
|
+
const hours = pad(d.getHours());
|
|
23
|
+
const minutes = pad(d.getMinutes());
|
|
24
|
+
const seconds = pad(d.getSeconds());
|
|
25
|
+
return fmt.replace("YYYY", year).replace("MM", month).replace("DD", day).replace("HH", hours).replace("mm", minutes).replace("ss", seconds);
|
|
26
|
+
}
|
|
27
|
+
function formatRelativeTime(value) {
|
|
28
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
29
|
+
const diff = Date.now() - d.getTime();
|
|
30
|
+
if (diff < 6e4) return "刚刚";
|
|
31
|
+
if (diff < 36e5) return `${Math.floor(diff / 6e4)} \u5206\u949F\u524D`;
|
|
32
|
+
if (diff < 864e5) return `${Math.floor(diff / 36e5)} \u5C0F\u65F6\u524D`;
|
|
33
|
+
if (diff < 6048e5) return `${Math.floor(diff / 864e5)} \u5929\u524D`;
|
|
34
|
+
return formatDate(d);
|
|
35
|
+
}
|
|
36
|
+
function escapeHtml(str) {
|
|
37
|
+
const map = {
|
|
38
|
+
"&": "&",
|
|
39
|
+
"<": "<",
|
|
40
|
+
">": ">",
|
|
41
|
+
"\"": """,
|
|
42
|
+
"'": "'"
|
|
43
|
+
};
|
|
44
|
+
return str.replace(/[&<>"']/g, (c) => map[c] || c);
|
|
45
|
+
}
|
|
46
|
+
function debounce(fn, delay) {
|
|
47
|
+
let timer = null;
|
|
48
|
+
return ((...args) => {
|
|
49
|
+
if (timer) clearTimeout(timer);
|
|
50
|
+
timer = setTimeout(() => fn(...args), delay);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function deepClone(obj) {
|
|
54
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(JSON.stringify(obj));
|
|
57
|
+
} catch {
|
|
58
|
+
return obj;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function formatValue(val) {
|
|
62
|
+
if (val === null || val === void 0) return "-";
|
|
63
|
+
if (typeof val === "object") try {
|
|
64
|
+
return JSON.stringify(val, null, 2);
|
|
65
|
+
} catch {
|
|
66
|
+
return String(val);
|
|
67
|
+
}
|
|
68
|
+
return String(val);
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { debounce, deepClone, escapeHtml, formatDate, formatRelativeTime, formatValue, uid };
|
|
72
|
+
/*! End of @composy/log-viewer-core | Powered by @composy/builder */
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["/**\n * 工具函数\n */\n\nlet _uid = 0\n\n/** 生成唯一 ID */\nexport function uid(prefix = 'lv'): string {\n return `${prefix}-${++_uid}-${Math.random().toString(36).slice(2, 8)}`\n}\n\n/** 格式化日期 */\nexport function formatDate(value: string | number | Date, fmt = 'YYYY-MM-DD HH:mm:ss'): string {\n const d = value instanceof Date ? value : new Date(value)\n if (isNaN(d.getTime())) return String(value)\n\n const pad = (n: number) => String(n).padStart(2, '0')\n const year = String(d.getFullYear())\n const month = pad(d.getMonth() + 1)\n const day = pad(d.getDate())\n const hours = pad(d.getHours())\n const minutes = pad(d.getMinutes())\n const seconds = pad(d.getSeconds())\n\n return fmt\n .replace('YYYY', year)\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds)\n}\n\n/** 格式化相对时间 */\nexport function formatRelativeTime(value: string | number | Date): string {\n const d = value instanceof Date ? value : new Date(value)\n const now = Date.now()\n const diff = now - d.getTime()\n\n if (diff < 60_000) return '刚刚'\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)} 分钟前`\n if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)} 小时前`\n if (diff < 604_800_000) return `${Math.floor(diff / 86_400_000)} 天前`\n return formatDate(d)\n}\n\n/** HTML 转义 */\nexport function escapeHtml(str: string): string {\n const map: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n }\n return str.replace(/[&<>\"']/g, (c) => map[c] || c)\n}\n\n/** 防抖 */\nexport function debounce<T extends (...args: unknown[]) => void>(fn: T, delay: number): T {\n let timer: ReturnType<typeof setTimeout> | null = null\n return ((...args: unknown[]) => {\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => fn(...args), delay)\n }) as unknown as T\n}\n\n/** 深拷贝简易实现 */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') return obj\n try {\n return JSON.parse(JSON.stringify(obj))\n } catch {\n return obj\n }\n}\n\n/** 将值格式化为可展示的字符串 */\nexport function formatValue(val: unknown): string {\n if (val === null || val === undefined) return '-'\n if (typeof val === 'object') {\n try {\n return JSON.stringify(val, null, 2)\n } catch {\n return String(val)\n }\n }\n return String(val)\n}\n"],"mappings":";;;;;;;;;;AAIA,IAAI,OAAO;AAGJ,SAAS,IAAI,SAAS,MAAc;CACzC,OAAO,GAAG,OAAM,GAAI,EAAE,KAAI,GAAI,KAAK,OAAO,CAAA,CAAE,SAAS,EAAE,CAAA,CAAE,MAAM,GAAG,CAAC;AACrE;AAGO,SAAS,WAAW,OAA+B,MAAM,uBAA+B;CAC7F,MAAM,IAAI,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CACxD,IAAI,MAAM,EAAE,QAAQ,CAAC,GAAG,OAAO,OAAO,KAAK;CAE3C,MAAM,OAAO,MAAc,OAAO,CAAC,CAAA,CAAE,SAAS,GAAG,GAAG;CACpD,MAAM,OAAO,OAAO,EAAE,YAAY,CAAC;CACnC,MAAM,QAAQ,IAAI,EAAE,SAAS,IAAI,CAAC;CAClC,MAAM,MAAM,IAAI,EAAE,QAAQ,CAAC;CAC3B,MAAM,QAAQ,IAAI,EAAE,SAAS,CAAC;CAC9B,MAAM,UAAU,IAAI,EAAE,WAAW,CAAC;CAClC,MAAM,UAAU,IAAI,EAAE,WAAW,CAAC;CAElC,OAAO,IACJ,QAAQ,QAAQ,IAAI,CAAA,CACpB,QAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,MAAM,GAAG,CAAA,CACjB,QAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,MAAM,OAAO,CAAA,CACrB,QAAQ,MAAM,OAAO;AAC1B;AAGO,SAAS,mBAAmB,OAAuC;CACxE,MAAM,IAAI,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CAExD,MAAM,OADM,KAAK,IACJ,IAAM,EAAE,QAAQ;CAE7B,IAAI,OAAO,KAAQ,OAAO;CAC1B,IAAI,OAAO,MAAW,OAAO,GAAG,KAAK,MAAM,OAAO,GAAM,EAAC;CACzD,IAAI,OAAO,OAAY,OAAO,GAAG,KAAK,MAAM,OAAO,IAAS,EAAC;CAC7D,IAAI,OAAO,QAAa,OAAO,GAAG,KAAK,MAAM,OAAO,KAAU,EAAC;CAC/D,OAAO,WAAW,CAAC;AACrB;AAGO,SAAS,WAAW,KAAqB;CAC9C,MAAM,MAA8B;EAClC,KAAK;EACL,KAAK;EACL,KAAK;EACL,MAAK;EACL,KAAK;CACP;CACA,OAAO,IAAI,QAAQ,aAAa,MAAM,IAAI,MAAM,CAAC;AACnD;AAGO,SAAS,SAAiD,IAAO,OAAkB;CACxF,IAAI,QAA8C;CAClD,SAAQ,GAAI,SAAoB;EAC9B,IAAI,OAAO,aAAa,KAAK;EAC7B,QAAQ,iBAAiB,GAAG,GAAG,IAAI,GAAG,KAAK;CAC7C;AACF;AAGO,SAAS,UAAa,KAAW;CACtC,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO;CACpD,IAAI;EACF,OAAO,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;CACvC,QAAQ;EACN,OAAO;CACT;AACF;AAGO,SAAS,YAAY,KAAsB;CAChD,IAAI,QAAQ,QAAQ,QAAQ,KAAA,GAAW,OAAO;CAC9C,IAAI,OAAO,QAAQ,UACjB,IAAI;EACF,OAAO,KAAK,UAAU,KAAK,MAAM,CAAC;CACpC,QAAQ;EACN,OAAO,OAAO,GAAG;CACnB;CAEF,OAAO,OAAO,GAAG;AACnB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 简单的事件发射器
|
|
3
|
+
*/
|
|
4
|
+
export declare class EventEmitter {
|
|
5
|
+
private listeners;
|
|
6
|
+
on(event: string, callback: (...args: unknown[]) => void): () => void;
|
|
7
|
+
off(event: string, callback: (...args: unknown[]) => void): void;
|
|
8
|
+
emit(event: string, ...args: unknown[]): void;
|
|
9
|
+
removeAllListeners(event?: string): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=EventEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/core/EventEmitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAuD;IAExE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAQrE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI;IAIhE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAU7C,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;CAOzC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/log-viewer-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:33:32 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
//#region src/core/EventEmitter.ts
|
|
11
|
+
var EventEmitter = class {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
14
|
+
}
|
|
15
|
+
on(event, callback) {
|
|
16
|
+
if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
17
|
+
this.listeners.get(event).add(callback);
|
|
18
|
+
return () => this.off(event, callback);
|
|
19
|
+
}
|
|
20
|
+
off(event, callback) {
|
|
21
|
+
this.listeners.get(event)?.delete(callback);
|
|
22
|
+
}
|
|
23
|
+
emit(event, ...args) {
|
|
24
|
+
this.listeners.get(event)?.forEach((cb) => {
|
|
25
|
+
try {
|
|
26
|
+
cb(...args);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(`[LogViewer] Event handler error (${event}):`, e);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
removeAllListeners(event) {
|
|
33
|
+
if (event) this.listeners.delete(event);
|
|
34
|
+
else this.listeners.clear();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { EventEmitter };
|
|
39
|
+
/*! End of @composy/log-viewer-core | Powered by @composy/builder */
|
|
40
|
+
//# sourceMappingURL=EventEmitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.js","names":[],"sources":["../../src/core/EventEmitter.ts"],"sourcesContent":["/**\n * 简单的事件发射器\n */\nexport class EventEmitter {\n private listeners = new Map<string, Set<(...args: unknown[]) => void>>()\n\n on(event: string, callback: (...args: unknown[]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(callback)\n return () => this.off(event, callback)\n }\n\n off(event: string, callback: (...args: unknown[]) => void): void {\n this.listeners.get(event)?.delete(callback)\n }\n\n emit(event: string, ...args: unknown[]): void {\n this.listeners.get(event)?.forEach((cb) => {\n try {\n cb(...args)\n } catch (e) {\n console.error(`[LogViewer] Event handler error (${event}):`, e)\n }\n })\n }\n\n removeAllListeners(event?: string): void {\n if (event) {\n this.listeners.delete(event)\n } else {\n this.listeners.clear()\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAGO,IAAM,eAAN,MAAmB;CAAnB,cAAA;EACL,KAAQ,4BAAY,IAAI,IAA+C;CAAA;CAEvE,GAAG,OAAe,UAAoD;EACpE,IAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAC3B,KAAK,UAAU,IAAI,uBAAO,IAAI,IAAI,CAAC;EAErC,KAAK,UAAU,IAAI,KAAK,CAAA,CAAG,IAAI,QAAQ;EACvC,aAAa,KAAK,IAAI,OAAO,QAAQ;CACvC;CAEA,IAAI,OAAe,UAA8C;EAC/D,KAAK,UAAU,IAAI,KAAK,CAAA,EAAG,OAAO,QAAQ;CAC5C;CAEA,KAAK,OAAA,GAAkB,MAAuB;EAC5C,KAAK,UAAU,IAAI,KAAK,CAAA,EAAG,SAAS,OAAO;GACzC,IAAI;IACF,GAAG,GAAG,IAAI;GACZ,SAAS,GAAG;IACV,QAAQ,MAAM,oCAAoC,MAAK,KAAM,CAAC;GAChE;EACF,CAAC;CACH;CAEA,mBAAmB,OAAsB;EACvC,IAAI,OACF,KAAK,UAAU,OAAO,KAAK;OAE3B,KAAK,UAAU,MAAM;CAEzB;AACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LogViewer 核心引擎
|
|
3
|
+
*/
|
|
4
|
+
import type { LogEntry, LogViewerConfig, LogViewerInstance, FilterConfig, PaginationConfig, ThemeMode } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* LogViewer - Log Viewer class
|
|
7
|
+
*/
|
|
8
|
+
export declare class LogViewer implements LogViewerInstance {
|
|
9
|
+
private root;
|
|
10
|
+
private emitter;
|
|
11
|
+
private filterEngine;
|
|
12
|
+
private timelineRenderer;
|
|
13
|
+
private diffRenderer;
|
|
14
|
+
private data;
|
|
15
|
+
private filteredData;
|
|
16
|
+
private filter;
|
|
17
|
+
private pagination;
|
|
18
|
+
private theme;
|
|
19
|
+
private expandedIds;
|
|
20
|
+
private config;
|
|
21
|
+
private timelineEl;
|
|
22
|
+
private paginationEl;
|
|
23
|
+
private destroyed;
|
|
24
|
+
constructor(config: LogViewerConfig);
|
|
25
|
+
getData(): LogEntry[];
|
|
26
|
+
setData(entries: LogEntry[]): void;
|
|
27
|
+
appendData(entries: LogEntry[]): void;
|
|
28
|
+
getFilter(): FilterConfig;
|
|
29
|
+
setFilter(filter: FilterConfig): void;
|
|
30
|
+
resetFilter(): void;
|
|
31
|
+
getTheme(): ThemeMode;
|
|
32
|
+
setTheme(theme: ThemeMode): void;
|
|
33
|
+
expandEntry(id: string): void;
|
|
34
|
+
collapseEntry(id: string): void;
|
|
35
|
+
collapseAll(): void;
|
|
36
|
+
goToPage(page: number): void;
|
|
37
|
+
getPagination(): PaginationConfig;
|
|
38
|
+
on(event: string, callback: (...args: unknown[]) => void): () => void;
|
|
39
|
+
refresh(): void;
|
|
40
|
+
destroy(): void;
|
|
41
|
+
private applyFilterAndRender;
|
|
42
|
+
private getPageData;
|
|
43
|
+
private renderTimeline;
|
|
44
|
+
private bindEvents;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=LogViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogViewer.d.ts","sourceRoot":"","sources":["../../src/core/LogViewer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACV,MAAM,UAAU,CAAA;AAQjB;;GAEG;AACH,qBAAa,SAAU,YAAW,iBAAiB;IACjD,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,MAAM,CAAiB;IAE/B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAQ;gBAEb,MAAM,EAAE,eAAe;IAqCnC,OAAO,IAAI,QAAQ,EAAE;IAIrB,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAOlC,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAMrC,SAAS,IAAI,YAAY;IAIzB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAQrC,WAAW,IAAI,IAAI;IAOnB,QAAQ,IAAI,SAAS;IAIrB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAOhC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAO7B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAO/B,WAAW,IAAI,IAAI;IAKnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ5B,aAAa,IAAI,gBAAgB;IAOjC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAIrE,OAAO,IAAI,IAAI;IAIf,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,UAAU;CAqCnB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/log-viewer-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:33:32 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from "./EventEmitter.js";
|
|
11
|
+
import { FilterEngine } from "../filters/FilterEngine.js";
|
|
12
|
+
import { deepClone } from "../utils/index.js";
|
|
13
|
+
import { TimelineRenderer } from "../renderers/TimelineRenderer.js";
|
|
14
|
+
import { DiffRenderer } from "../renderers/DiffRenderer.js";
|
|
15
|
+
import { injectStyles } from "../styles/index.js";
|
|
16
|
+
//#region src/core/LogViewer.ts
|
|
17
|
+
var LogViewer = class {
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.emitter = new EventEmitter();
|
|
20
|
+
this.filterEngine = new FilterEngine();
|
|
21
|
+
this.timelineRenderer = new TimelineRenderer();
|
|
22
|
+
this.diffRenderer = new DiffRenderer();
|
|
23
|
+
this.data = [];
|
|
24
|
+
this.filteredData = [];
|
|
25
|
+
this.filter = {};
|
|
26
|
+
this.pagination = {
|
|
27
|
+
page: 1,
|
|
28
|
+
pageSize: 20
|
|
29
|
+
};
|
|
30
|
+
this.theme = "light";
|
|
31
|
+
this.expandedIds = /* @__PURE__ */ new Set();
|
|
32
|
+
this.timelineEl = null;
|
|
33
|
+
this.paginationEl = null;
|
|
34
|
+
this.destroyed = false;
|
|
35
|
+
this.config = config;
|
|
36
|
+
const container = typeof config.container === "string" ? document.querySelector(config.container) : config.container;
|
|
37
|
+
if (!container) throw new Error(`[LogViewer] Container not found: ${config.container}`);
|
|
38
|
+
injectStyles();
|
|
39
|
+
this.root = document.createElement("div");
|
|
40
|
+
this.root.className = "lv-root";
|
|
41
|
+
container.appendChild(this.root);
|
|
42
|
+
this.theme = config.theme || "light";
|
|
43
|
+
this.root.setAttribute("data-theme", this.theme);
|
|
44
|
+
if (config.pageSize) this.pagination.pageSize = config.pageSize;
|
|
45
|
+
if (config.pagination) Object.assign(this.pagination, config.pagination);
|
|
46
|
+
if (config.filter) this.filter = deepClone(config.filter);
|
|
47
|
+
if (config.data) this.data = [...config.data];
|
|
48
|
+
this.applyFilterAndRender();
|
|
49
|
+
this.bindEvents();
|
|
50
|
+
}
|
|
51
|
+
getData() {
|
|
52
|
+
return [...this.data];
|
|
53
|
+
}
|
|
54
|
+
setData(entries) {
|
|
55
|
+
this.data = [...entries];
|
|
56
|
+
this.pagination.page = 1;
|
|
57
|
+
this.applyFilterAndRender();
|
|
58
|
+
this.emitter.emit("data:change", this.data);
|
|
59
|
+
}
|
|
60
|
+
appendData(entries) {
|
|
61
|
+
this.data.push(...entries);
|
|
62
|
+
this.applyFilterAndRender();
|
|
63
|
+
this.emitter.emit("data:change", this.data);
|
|
64
|
+
}
|
|
65
|
+
getFilter() {
|
|
66
|
+
return deepClone(this.filter);
|
|
67
|
+
}
|
|
68
|
+
setFilter(filter) {
|
|
69
|
+
this.filter = deepClone(filter);
|
|
70
|
+
this.pagination.page = 1;
|
|
71
|
+
this.applyFilterAndRender();
|
|
72
|
+
this.emitter.emit("filter:change", this.filter);
|
|
73
|
+
this.config.onFilterChange?.(this.filter);
|
|
74
|
+
}
|
|
75
|
+
resetFilter() {
|
|
76
|
+
this.filter = {};
|
|
77
|
+
this.pagination.page = 1;
|
|
78
|
+
this.applyFilterAndRender();
|
|
79
|
+
this.emitter.emit("filter:change", this.filter);
|
|
80
|
+
}
|
|
81
|
+
getTheme() {
|
|
82
|
+
return this.theme;
|
|
83
|
+
}
|
|
84
|
+
setTheme(theme) {
|
|
85
|
+
this.theme = theme;
|
|
86
|
+
this.root.setAttribute("data-theme", theme);
|
|
87
|
+
this.emitter.emit("theme:change", theme);
|
|
88
|
+
this.config.onThemeChange?.(theme);
|
|
89
|
+
}
|
|
90
|
+
expandEntry(id) {
|
|
91
|
+
this.expandedIds.add(id);
|
|
92
|
+
const entry = this.data.find((e) => e.id === id);
|
|
93
|
+
if (entry) this.emitter.emit("entry:expand", entry);
|
|
94
|
+
this.renderTimeline();
|
|
95
|
+
}
|
|
96
|
+
collapseEntry(id) {
|
|
97
|
+
this.expandedIds.delete(id);
|
|
98
|
+
const entry = this.data.find((e) => e.id === id);
|
|
99
|
+
if (entry) this.emitter.emit("entry:collapse", entry);
|
|
100
|
+
this.renderTimeline();
|
|
101
|
+
}
|
|
102
|
+
collapseAll() {
|
|
103
|
+
this.expandedIds.clear();
|
|
104
|
+
this.renderTimeline();
|
|
105
|
+
}
|
|
106
|
+
goToPage(page) {
|
|
107
|
+
const totalPages = Math.ceil(this.filteredData.length / this.pagination.pageSize);
|
|
108
|
+
if (page < 1 || page > totalPages) return;
|
|
109
|
+
this.pagination.page = page;
|
|
110
|
+
this.emitter.emit("page:change", page);
|
|
111
|
+
this.renderTimeline();
|
|
112
|
+
}
|
|
113
|
+
getPagination() {
|
|
114
|
+
return {
|
|
115
|
+
...this.pagination,
|
|
116
|
+
total: this.filteredData.length
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
on(event, callback) {
|
|
120
|
+
return this.emitter.on(event, callback);
|
|
121
|
+
}
|
|
122
|
+
refresh() {
|
|
123
|
+
this.applyFilterAndRender();
|
|
124
|
+
}
|
|
125
|
+
destroy() {
|
|
126
|
+
if (this.destroyed) return;
|
|
127
|
+
this.destroyed = true;
|
|
128
|
+
this.emitter.removeAllListeners();
|
|
129
|
+
this.root.remove();
|
|
130
|
+
}
|
|
131
|
+
applyFilterAndRender() {
|
|
132
|
+
this.filteredData = this.filterEngine.filter(this.data, this.filter);
|
|
133
|
+
this.filteredData.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
134
|
+
this.pagination.total = this.filteredData.length;
|
|
135
|
+
this.renderTimeline();
|
|
136
|
+
}
|
|
137
|
+
getPageData() {
|
|
138
|
+
const { page, pageSize } = this.pagination;
|
|
139
|
+
const start = (page - 1) * pageSize;
|
|
140
|
+
return this.filteredData.slice(start, start + pageSize);
|
|
141
|
+
}
|
|
142
|
+
renderTimeline() {
|
|
143
|
+
if (this.destroyed) return;
|
|
144
|
+
const pageData = this.getPageData();
|
|
145
|
+
const newTimeline = this.timelineRenderer.render(pageData, this.expandedIds);
|
|
146
|
+
for (const entry of pageData) if (this.expandedIds.has(entry.id)) {
|
|
147
|
+
const itemEl = newTimeline.querySelector(`[data-id="${entry.id}"] .lv-timeline-card`);
|
|
148
|
+
if (itemEl) itemEl.appendChild(this.diffRenderer.renderDetail(entry));
|
|
149
|
+
}
|
|
150
|
+
if (this.timelineEl) this.root.removeChild(this.timelineEl);
|
|
151
|
+
this.timelineEl = newTimeline;
|
|
152
|
+
this.root.appendChild(this.timelineEl);
|
|
153
|
+
const newPagination = this.timelineRenderer.renderPagination(this.pagination.page, this.pagination.pageSize, this.filteredData.length);
|
|
154
|
+
if (this.paginationEl) this.root.removeChild(this.paginationEl);
|
|
155
|
+
this.paginationEl = newPagination;
|
|
156
|
+
this.root.appendChild(this.paginationEl);
|
|
157
|
+
}
|
|
158
|
+
bindEvents() {
|
|
159
|
+
this.root.addEventListener("click", (e) => {
|
|
160
|
+
const target = e.target;
|
|
161
|
+
const card = target.closest(".lv-timeline-card");
|
|
162
|
+
if (card) {
|
|
163
|
+
const id = card.closest(".lv-timeline-item")?.getAttribute("data-id");
|
|
164
|
+
if (!id) return;
|
|
165
|
+
const entry = this.filteredData.find((en) => en.id === id);
|
|
166
|
+
if (!entry) return;
|
|
167
|
+
if (target.classList.contains("lv-timeline-expand-hint")) {
|
|
168
|
+
if (this.expandedIds.has(id)) this.collapseEntry(id);
|
|
169
|
+
else this.expandEntry(id);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.emitter.emit("entry:click", entry);
|
|
173
|
+
this.config.onEntryClick?.(entry);
|
|
174
|
+
}
|
|
175
|
+
const pageBtn = target.closest(".lv-pagination-btn");
|
|
176
|
+
if (pageBtn && !pageBtn.disabled) {
|
|
177
|
+
const page = parseInt(pageBtn.getAttribute("data-page") || "1", 10);
|
|
178
|
+
this.goToPage(page);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
//#endregion
|
|
184
|
+
export { LogViewer };
|
|
185
|
+
/*! End of @composy/log-viewer-core | Powered by @composy/builder */
|
|
186
|
+
//# sourceMappingURL=LogViewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogViewer.js","names":[],"sources":["../../src/core/LogViewer.ts"],"sourcesContent":["/**\n * LogViewer 核心引擎\n */\n\nimport type {\n LogEntry,\n LogViewerConfig,\n LogViewerInstance,\n FilterConfig,\n PaginationConfig,\n ThemeMode,\n} from '../types'\nimport { EventEmitter } from './EventEmitter'\nimport { FilterEngine } from '../filters/FilterEngine'\nimport { TimelineRenderer } from '../renderers/TimelineRenderer'\nimport { DiffRenderer } from '../renderers/DiffRenderer'\nimport { injectStyles } from '../styles'\nimport { deepClone } from '../utils'\n\n/**\n * LogViewer - Log Viewer class\n */\nexport class LogViewer implements LogViewerInstance {\n private root: HTMLElement\n private emitter = new EventEmitter()\n private filterEngine = new FilterEngine()\n private timelineRenderer = new TimelineRenderer()\n private diffRenderer = new DiffRenderer()\n\n private data: LogEntry[] = []\n private filteredData: LogEntry[] = []\n private filter: FilterConfig = {}\n private pagination: PaginationConfig = { page: 1, pageSize: 20 }\n private theme: ThemeMode = 'light'\n private expandedIds = new Set<string>()\n private config: LogViewerConfig\n\n private timelineEl: HTMLElement | null = null\n private paginationEl: HTMLElement | null = null\n private destroyed = false\n\n constructor(config: LogViewerConfig) {\n this.config = config\n\n // Resolve container\n const container =\n typeof config.container === 'string'\n ? document.querySelector<HTMLElement>(config.container)\n : config.container\n if (!container) throw new Error(`[LogViewer] Container not found: ${config.container}`)\n\n // Inject global styles\n injectStyles()\n\n // Create root\n this.root = document.createElement('div')\n this.root.className = 'lv-root'\n container.appendChild(this.root)\n\n // Apply config\n this.theme = config.theme || 'light'\n this.root.setAttribute('data-theme', this.theme)\n\n if (config.pageSize) this.pagination.pageSize = config.pageSize\n if (config.pagination) Object.assign(this.pagination, config.pagination)\n if (config.filter) this.filter = deepClone(config.filter)\n\n // Load data\n if (config.data) {\n this.data = [...config.data]\n }\n\n this.applyFilterAndRender()\n this.bindEvents()\n }\n\n // ===== Public API =====\n\n getData(): LogEntry[] {\n return [...this.data]\n }\n\n setData(entries: LogEntry[]): void {\n this.data = [...entries]\n this.pagination.page = 1\n this.applyFilterAndRender()\n this.emitter.emit('data:change', this.data)\n }\n\n appendData(entries: LogEntry[]): void {\n this.data.push(...entries)\n this.applyFilterAndRender()\n this.emitter.emit('data:change', this.data)\n }\n\n getFilter(): FilterConfig {\n return deepClone(this.filter)\n }\n\n setFilter(filter: FilterConfig): void {\n this.filter = deepClone(filter)\n this.pagination.page = 1\n this.applyFilterAndRender()\n this.emitter.emit('filter:change', this.filter)\n this.config.onFilterChange?.(this.filter)\n }\n\n resetFilter(): void {\n this.filter = {}\n this.pagination.page = 1\n this.applyFilterAndRender()\n this.emitter.emit('filter:change', this.filter)\n }\n\n getTheme(): ThemeMode {\n return this.theme\n }\n\n setTheme(theme: ThemeMode): void {\n this.theme = theme\n this.root.setAttribute('data-theme', theme)\n this.emitter.emit('theme:change', theme)\n this.config.onThemeChange?.(theme)\n }\n\n expandEntry(id: string): void {\n this.expandedIds.add(id)\n const entry = this.data.find((e) => e.id === id)\n if (entry) this.emitter.emit('entry:expand', entry)\n this.renderTimeline()\n }\n\n collapseEntry(id: string): void {\n this.expandedIds.delete(id)\n const entry = this.data.find((e) => e.id === id)\n if (entry) this.emitter.emit('entry:collapse', entry)\n this.renderTimeline()\n }\n\n collapseAll(): void {\n this.expandedIds.clear()\n this.renderTimeline()\n }\n\n goToPage(page: number): void {\n const totalPages = Math.ceil(this.filteredData.length / this.pagination.pageSize)\n if (page < 1 || page > totalPages) return\n this.pagination.page = page\n this.emitter.emit('page:change', page)\n this.renderTimeline()\n }\n\n getPagination(): PaginationConfig {\n return {\n ...this.pagination,\n total: this.filteredData.length,\n }\n }\n\n on(event: string, callback: (...args: unknown[]) => void): () => void {\n return this.emitter.on(event, callback)\n }\n\n refresh(): void {\n this.applyFilterAndRender()\n }\n\n destroy(): void {\n if (this.destroyed) return\n this.destroyed = true\n this.emitter.removeAllListeners()\n this.root.remove()\n }\n\n // ===== Internal =====\n\n private applyFilterAndRender(): void {\n this.filteredData = this.filterEngine.filter(this.data, this.filter)\n this.filteredData.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),\n )\n this.pagination.total = this.filteredData.length\n this.renderTimeline()\n }\n\n private getPageData(): LogEntry[] {\n const { page, pageSize } = this.pagination\n const start = (page - 1) * pageSize\n return this.filteredData.slice(start, start + pageSize)\n }\n\n private renderTimeline(): void {\n if (this.destroyed) return\n\n const pageData = this.getPageData()\n\n // Timeline\n const newTimeline = this.timelineRenderer.render(pageData, this.expandedIds)\n\n // Render detail panels for expanded items\n for (const entry of pageData) {\n if (this.expandedIds.has(entry.id)) {\n const itemEl = newTimeline.querySelector(`[data-id=\"${entry.id}\"] .lv-timeline-card`)\n if (itemEl) {\n itemEl.appendChild(this.diffRenderer.renderDetail(entry))\n }\n }\n }\n\n if (this.timelineEl) {\n this.root.removeChild(this.timelineEl)\n }\n this.timelineEl = newTimeline\n this.root.appendChild(this.timelineEl)\n\n // Pagination\n const newPagination = this.timelineRenderer.renderPagination(\n this.pagination.page,\n this.pagination.pageSize,\n this.filteredData.length,\n )\n if (this.paginationEl) {\n this.root.removeChild(this.paginationEl)\n }\n this.paginationEl = newPagination\n this.root.appendChild(this.paginationEl)\n }\n\n private bindEvents(): void {\n this.root.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n\n // Timeline card click\n const card = target.closest('.lv-timeline-card') as HTMLElement | null\n if (card) {\n const item = card.closest('.lv-timeline-item') as HTMLElement | null\n const id = item?.getAttribute('data-id')\n if (!id) return\n\n const entry = this.filteredData.find((en) => en.id === id)\n if (!entry) return\n\n // Click on expand hint\n if (target.classList.contains('lv-timeline-expand-hint')) {\n if (this.expandedIds.has(id)) {\n this.collapseEntry(id)\n } else {\n this.expandEntry(id)\n }\n return\n }\n\n // Click on card itself\n this.emitter.emit('entry:click', entry)\n this.config.onEntryClick?.(entry)\n }\n\n // Pagination click\n const pageBtn = target.closest('.lv-pagination-btn') as HTMLButtonElement | null\n if (pageBtn && !pageBtn.disabled) {\n const page = parseInt(pageBtn.getAttribute('data-page') || '1', 10)\n this.goToPage(page)\n }\n })\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 筛选引擎 - 支持按操作人/操作类型/时间范围/模块/IP/关键词筛选
|
|
3
|
+
*/
|
|
4
|
+
import type { LogEntry, FilterConfig } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* FilterEngine - Filter Engine class
|
|
7
|
+
*/
|
|
8
|
+
export declare class FilterEngine {
|
|
9
|
+
/**
|
|
10
|
+
* 对日志条目进行多维筛选
|
|
11
|
+
*/
|
|
12
|
+
filter(entries: LogEntry[], config: FilterConfig): LogEntry[];
|
|
13
|
+
/**
|
|
14
|
+
* 获取所有唯一操作人
|
|
15
|
+
*/
|
|
16
|
+
getUniqueUsers(entries: LogEntry[]): string[];
|
|
17
|
+
/**
|
|
18
|
+
* 获取所有唯一模块
|
|
19
|
+
*/
|
|
20
|
+
getUniqueModules(entries: LogEntry[]): string[];
|
|
21
|
+
/**
|
|
22
|
+
* 获取所有唯一操作类型
|
|
23
|
+
*/
|
|
24
|
+
getUniqueActions(entries: LogEntry[]): string[];
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=FilterEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterEngine.d.ts","sourceRoot":"","sources":["../../src/filters/FilterEngine.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEtD;;GAEG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,QAAQ,EAAE;IA6D7D;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE;IAI7C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE;IAI/C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE;CAGhD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/log-viewer-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:33:32 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
//#region src/filters/FilterEngine.ts
|
|
11
|
+
var FilterEngine = class {
|
|
12
|
+
/**
|
|
13
|
+
* 对日志条目进行多维筛选
|
|
14
|
+
*/
|
|
15
|
+
filter(entries, config) {
|
|
16
|
+
let result = entries;
|
|
17
|
+
if (config.user) {
|
|
18
|
+
const keyword = config.user.toLowerCase();
|
|
19
|
+
result = result.filter((e) => e.user.toLowerCase().includes(keyword) || e.userId && e.userId.toLowerCase().includes(keyword));
|
|
20
|
+
}
|
|
21
|
+
if (config.action) {
|
|
22
|
+
const actions = Array.isArray(config.action) ? config.action : [config.action];
|
|
23
|
+
result = result.filter((e) => actions.includes(e.action));
|
|
24
|
+
}
|
|
25
|
+
if (config.module) {
|
|
26
|
+
const mod = config.module.toLowerCase();
|
|
27
|
+
result = result.filter((e) => e.module.toLowerCase().includes(mod));
|
|
28
|
+
}
|
|
29
|
+
if (config.ip) {
|
|
30
|
+
const ip = config.ip.toLowerCase();
|
|
31
|
+
result = result.filter((e) => e.ip && e.ip.toLowerCase().includes(ip));
|
|
32
|
+
}
|
|
33
|
+
if (config.timeRange) {
|
|
34
|
+
const [start, end] = config.timeRange;
|
|
35
|
+
const startTime = new Date(start).getTime();
|
|
36
|
+
const endTime = new Date(end).getTime();
|
|
37
|
+
result = result.filter((e) => {
|
|
38
|
+
const t = new Date(e.timestamp).getTime();
|
|
39
|
+
return t >= startTime && t <= endTime;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (config.keyword) {
|
|
43
|
+
const kw = config.keyword.toLowerCase();
|
|
44
|
+
result = result.filter((e) => {
|
|
45
|
+
return [
|
|
46
|
+
e.user,
|
|
47
|
+
e.action,
|
|
48
|
+
e.module,
|
|
49
|
+
e.detail || "",
|
|
50
|
+
e.ip || "",
|
|
51
|
+
e.id
|
|
52
|
+
].some((t) => t.toLowerCase().includes(kw));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 获取所有唯一操作人
|
|
59
|
+
*/
|
|
60
|
+
getUniqueUsers(entries) {
|
|
61
|
+
return [...new Set(entries.map((e) => e.user))].sort();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 获取所有唯一模块
|
|
65
|
+
*/
|
|
66
|
+
getUniqueModules(entries) {
|
|
67
|
+
return [...new Set(entries.map((e) => e.module))].sort();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 获取所有唯一操作类型
|
|
71
|
+
*/
|
|
72
|
+
getUniqueActions(entries) {
|
|
73
|
+
return [...new Set(entries.map((e) => e.action))].sort();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { FilterEngine };
|
|
78
|
+
/*! End of @composy/log-viewer-core | Powered by @composy/builder */
|
|
79
|
+
//# sourceMappingURL=FilterEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterEngine.js","names":[],"sources":["../../src/filters/FilterEngine.ts"],"sourcesContent":["/**\n * 筛选引擎 - 支持按操作人/操作类型/时间范围/模块/IP/关键词筛选\n */\n\nimport type { LogEntry, FilterConfig } from '../types'\n\n/**\n * FilterEngine - Filter Engine class\n */\nexport class FilterEngine {\n /**\n * 对日志条目进行多维筛选\n */\n filter(entries: LogEntry[], config: FilterConfig): LogEntry[] {\n let result = entries\n\n // 按操作人筛选\n if (config.user) {\n const keyword = config.user.toLowerCase()\n result = result.filter(\n (e) =>\n e.user.toLowerCase().includes(keyword) ||\n (e.userId && e.userId.toLowerCase().includes(keyword)),\n )\n }\n\n // 按操作类型筛选\n if (config.action) {\n const actions = Array.isArray(config.action) ? config.action : [config.action]\n result = result.filter((e) => actions.includes(e.action))\n }\n\n // 按模块筛选\n if (config.module) {\n const mod = config.module.toLowerCase()\n result = result.filter((e) => e.module.toLowerCase().includes(mod))\n }\n\n // 按 IP 筛选\n if (config.ip) {\n const ip = config.ip.toLowerCase()\n result = result.filter((e) => e.ip && e.ip.toLowerCase().includes(ip))\n }\n\n // 按时间范围筛选\n if (config.timeRange) {\n const [start, end] = config.timeRange\n const startTime = new Date(start).getTime()\n const endTime = new Date(end).getTime()\n result = result.filter((e) => {\n const t = new Date(e.timestamp).getTime()\n return t >= startTime && t <= endTime\n })\n }\n\n // 按关键词全文搜索\n if (config.keyword) {\n const kw = config.keyword.toLowerCase()\n result = result.filter((e) => {\n const texts = [\n e.user,\n e.action,\n e.module,\n e.detail || '',\n e.ip || '',\n e.id,\n ]\n return texts.some((t) => t.toLowerCase().includes(kw))\n })\n }\n\n return result\n }\n\n /**\n * 获取所有唯一操作人\n */\n getUniqueUsers(entries: LogEntry[]): string[] {\n return [...new Set(entries.map((e) => e.user))].sort()\n }\n\n /**\n * 获取所有唯一模块\n */\n getUniqueModules(entries: LogEntry[]): string[] {\n return [...new Set(entries.map((e) => e.module))].sort()\n }\n\n /**\n * 获取所有唯一操作类型\n */\n getUniqueActions(entries: LogEntry[]): string[] {\n return [...new Set(entries.map((e) => e.action))].sort()\n }\n}\n"],"mappings":";;;;;;;;;;AASO,IAAM,eAAN,MAAmB;;;;CAIxB,OAAO,SAAqB,QAAkC;EAC5D,IAAI,SAAS;EAGb,IAAI,OAAO,MAAM;GACf,MAAM,UAAU,OAAO,KAAK,YAAY;GACxC,SAAS,OAAO,QACb,MACC,EAAE,KAAK,YAAY,CAAA,CAAE,SAAS,OAAO,KACpC,EAAE,UAAU,EAAE,OAAO,YAAY,CAAA,CAAE,SAAS,OAAO,CACxD;EACF;EAGA,IAAI,OAAO,QAAQ;GACjB,MAAM,UAAU,MAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,SAAS,CAAC,OAAO,MAAM;GAC7E,SAAS,OAAO,QAAQ,MAAM,QAAQ,SAAS,EAAE,MAAM,CAAC;EAC1D;EAGA,IAAI,OAAO,QAAQ;GACjB,MAAM,MAAM,OAAO,OAAO,YAAY;GACtC,SAAS,OAAO,QAAQ,MAAM,EAAE,OAAO,YAAY,CAAA,CAAE,SAAS,GAAG,CAAC;EACpE;EAGA,IAAI,OAAO,IAAI;GACb,MAAM,KAAK,OAAO,GAAG,YAAY;GACjC,SAAS,OAAO,QAAQ,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAA,CAAE,SAAS,EAAE,CAAC;EACvE;EAGA,IAAI,OAAO,WAAW;GACpB,MAAM,CAAC,OAAO,OAAO,OAAO;GAC5B,MAAM,YAAY,IAAI,KAAK,KAAK,CAAA,CAAE,QAAQ;GAC1C,MAAM,UAAU,IAAI,KAAK,GAAG,CAAA,CAAE,QAAQ;GACtC,SAAS,OAAO,QAAQ,MAAM;IAC5B,MAAM,IAAI,IAAI,KAAK,EAAE,SAAS,CAAA,CAAE,QAAQ;IACxC,OAAO,KAAK,aAAa,KAAK;GAChC,CAAC;EACH;EAGA,IAAI,OAAO,SAAS;GAClB,MAAM,KAAK,OAAO,QAAQ,YAAY;GACtC,SAAS,OAAO,QAAQ,MAAM;IAS5B,OAAO;KAPL,EAAE;KACF,EAAE;KACF,EAAE;KACF,EAAE,UAAU;KACZ,EAAE,MAAM;KACR,EAAE;IAEG,CAAA,CAAM,MAAM,MAAM,EAAE,YAAY,CAAA,CAAE,SAAS,EAAE,CAAC;GACvD,CAAC;EACH;EAEA,OAAO;CACT;;;;CAKA,eAAe,SAA+B;EAC5C,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA,CAAE,KAAK;CACvD;;;;CAKA,iBAAiB,SAA+B;EAC9C,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA,CAAE,KAAK;CACzD;;;;CAKA,iBAAiB,SAA+B;EAC9C,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA,CAAE,KAAK;CACzD;AACF"}
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @composy/log-viewer-core
|
|
3
|
+
* 审计日志查看器 - 操作日志可视化与追溯
|
|
4
|
+
*/
|
|
5
|
+
export declare const VERSION = "0.1.0";
|
|
6
|
+
export type { ActionType, ThemeMode, AnomalyType, DiffEntry, LogEntry, FilterConfig, PaginationConfig, LogViewerConfig, LogViewerInstance, LogViewerEvents, } from './types';
|
|
7
|
+
export { ACTION_LABELS, ACTION_COLORS } from './types';
|
|
8
|
+
export { LogViewer } from './core/LogViewer';
|
|
9
|
+
export { EventEmitter } from './core/EventEmitter';
|
|
10
|
+
export { FilterEngine } from './filters/FilterEngine';
|
|
11
|
+
export { TimelineRenderer } from './renderers/TimelineRenderer';
|
|
12
|
+
export { DiffRenderer } from './renderers/DiffRenderer';
|
|
13
|
+
export { formatDate, formatRelativeTime, escapeHtml, debounce, uid, formatValue, deepClone } from './utils';
|
|
14
|
+
export { injectStyles } from './styles';
|
|
15
|
+
/**
|
|
16
|
+
* 创建 LogViewer 实例 - 工厂函数
|
|
17
|
+
*/
|
|
18
|
+
import type { LogViewerConfig } from './types';
|
|
19
|
+
import { LogViewer } from './core/LogViewer';
|
|
20
|
+
/**
|
|
21
|
+
* createLogViewer - create Log Viewer function
|
|
22
|
+
* @param config - 参数说明
|
|
23
|
+
* @returns 返回值说明
|
|
24
|
+
*/
|
|
25
|
+
export declare function createLogViewer(config: LogViewerConfig): LogViewer;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAA;AAG9B,YAAY,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAGtD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGvD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAG3G,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAElE"}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/log-viewer-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:33:32 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
import { ACTION_COLORS, ACTION_LABELS } from "./types/index.js";
|
|
11
|
+
import { EventEmitter } from "./core/EventEmitter.js";
|
|
12
|
+
import { FilterEngine } from "./filters/FilterEngine.js";
|
|
13
|
+
import { debounce, deepClone, escapeHtml, formatDate, formatRelativeTime, formatValue, uid } from "./utils/index.js";
|
|
14
|
+
import { TimelineRenderer } from "./renderers/TimelineRenderer.js";
|
|
15
|
+
import { DiffRenderer } from "./renderers/DiffRenderer.js";
|
|
16
|
+
import { injectStyles } from "./styles/index.js";
|
|
17
|
+
import { LogViewer } from "./core/LogViewer.js";
|
|
18
|
+
//#region src/index.ts
|
|
19
|
+
const VERSION = "0.1.0";
|
|
20
|
+
function createLogViewer(config) {
|
|
21
|
+
return new LogViewer(config);
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ACTION_COLORS, ACTION_LABELS, DiffRenderer, EventEmitter, FilterEngine, LogViewer, TimelineRenderer, VERSION, createLogViewer, debounce, deepClone, escapeHtml, formatDate, formatRelativeTime, formatValue, injectStyles, uid };
|
|
25
|
+
/*! End of @composy/log-viewer-core | Powered by @composy/builder */
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["LogViewer"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @composy/log-viewer-core\n * 审计日志查看器 - 操作日志可视化与追溯\n */\n\nexport const VERSION = '0.1.0'\n\n// 类型\nexport type {\n ActionType,\n ThemeMode,\n AnomalyType,\n DiffEntry,\n LogEntry,\n FilterConfig,\n PaginationConfig,\n LogViewerConfig,\n LogViewerInstance,\n LogViewerEvents,\n} from './types'\nexport { ACTION_LABELS, ACTION_COLORS } from './types'\n\n// 核心\nexport { LogViewer } from './core/LogViewer'\nexport { EventEmitter } from './core/EventEmitter'\n\n// 筛选\nexport { FilterEngine } from './filters/FilterEngine'\n\n// 渲染器\nexport { TimelineRenderer } from './renderers/TimelineRenderer'\nexport { DiffRenderer } from './renderers/DiffRenderer'\n\n// 工具\nexport { formatDate, formatRelativeTime, escapeHtml, debounce, uid, formatValue, deepClone } from './utils'\n\n// 样式\nexport { injectStyles } from './styles'\n\n/**\n * 创建 LogViewer 实例 - 工厂函数\n */\nimport type { LogViewerConfig } from './types'\nimport { LogViewer } from './core/LogViewer'\n\n/**\n * createLogViewer - create Log Viewer function\n * @param config - 参数说明\n * @returns 返回值说明\n */\nexport function createLogViewer(config: LogViewerConfig): LogViewer {\n return new LogViewer(config)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAKO,MAAM,UAAU;AA6ChB,SAAS,gBAAgB,QAAoC;CAClE,OAAO,IAAIA,UAAU,MAAM;AAC7B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 变更对比渲染器 - 渲染字段变更前后的 Diff 表格
|
|
3
|
+
*/
|
|
4
|
+
import type { DiffEntry, LogEntry } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* DiffRenderer - Diff Renderer class
|
|
7
|
+
*/
|
|
8
|
+
export declare class DiffRenderer {
|
|
9
|
+
/**
|
|
10
|
+
* 渲染详情面板(包含 diff 表格和 metadata)
|
|
11
|
+
*/
|
|
12
|
+
renderDetail(entry: LogEntry): HTMLElement;
|
|
13
|
+
/**
|
|
14
|
+
* 渲染 Diff 表格
|
|
15
|
+
*/
|
|
16
|
+
renderDiffTable(changes: DiffEntry[]): HTMLElement;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=DiffRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiffRenderer.d.ts","sourceRoot":"","sources":["../../src/renderers/DiffRenderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGnD;;GAEG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW;IAkB1C;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,WAAW;CAkCnD"}
|