@necrolab/dashboard 0.5.21 → 0.5.23

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.
@@ -0,0 +1,186 @@
1
+ function zeroPadding(num, length) {
2
+ let numAsStr = String(num);
3
+ while (numAsStr.length < length) {
4
+ numAsStr = `0${numAsStr}`;
5
+ }
6
+ return numAsStr;
7
+ }
8
+
9
+ function timestamp() {
10
+ const now = new Date();
11
+ const hours = zeroPadding(now.getHours(), 2);
12
+ const minutes = zeroPadding(now.getMinutes(), 2);
13
+ const seconds = zeroPadding(now.getSeconds(), 2);
14
+ const milli = zeroPadding(now.getMilliseconds(), 3);
15
+ return `${hours}:${minutes}:${seconds}.${milli}`;
16
+ }
17
+
18
+ const ANSI_COLORS = {
19
+ error: "\x1B[91m",
20
+ success: "\x1B[92m",
21
+ info: "\x1B[96m",
22
+ debug: "\x1B[95m",
23
+ yellow: "\x1B[93m",
24
+ reset: "\x1B[0m",
25
+ timestamp: "\x1B[90m",
26
+ tag: "\x1B[97m",
27
+ };
28
+
29
+ const CSS_STYLES = {
30
+ error: "color: #ff6b6b; font-weight: bold;",
31
+ success: "color: #51cf66; font-weight: bold;",
32
+ info: "color: #74c0fc; font-weight: bold;",
33
+ debug: "color: #da77f2; font-weight: bold;",
34
+ yellow: "color: #ffd43b; font-weight: bold;",
35
+ timestamp: "color: #868e96; font-size: 0.9em;",
36
+ tag: "color: #f8f9fa; font-weight: bold; background: #495057; padding: 2px 6px; border-radius: 3px;",
37
+ };
38
+
39
+ class NodeLogger {
40
+ constructor() {
41
+ this.ENABLED = true;
42
+ this.defaultArgs = [];
43
+ }
44
+
45
+ _formatMessage(level, ...args) {
46
+ if (!this.ENABLED) return;
47
+
48
+ const color = ANSI_COLORS[level] || ANSI_COLORS.reset;
49
+ const reset = ANSI_COLORS.reset;
50
+
51
+ const timeStr = `${color}[${timestamp()}]${reset}`;
52
+
53
+ const tagStrs = this.defaultArgs.map((tag) => `${color}[${tag}]${reset}`);
54
+
55
+ const formattedArgs = args.map((arg) => {
56
+ if (arg instanceof Error) {
57
+ return arg.stack || arg.toString();
58
+ } else if (typeof arg === "object" && arg !== null) {
59
+ try {
60
+ return JSON.stringify(arg, null, 2);
61
+ } catch (e) {
62
+ return `[Object: ${arg.constructor?.name || "Unknown"}]`;
63
+ }
64
+ }
65
+ return arg;
66
+ });
67
+
68
+ console.log(timeStr, ...tagStrs, ...formattedArgs);
69
+ }
70
+
71
+ Error(...args) {
72
+ this._formatMessage("error", ...args);
73
+ }
74
+ Success(...args) {
75
+ this._formatMessage("success", ...args);
76
+ }
77
+ Info(...args) {
78
+ this._formatMessage("info", ...args);
79
+ }
80
+ Debug(...args) {
81
+ this._formatMessage("debug", ...args);
82
+ }
83
+ Yellow(...args) {
84
+ this._formatMessage("yellow", ...args);
85
+ }
86
+
87
+ Disable() {
88
+ this.ENABLED = false;
89
+ }
90
+ Enable() {
91
+ this.ENABLED = true;
92
+ }
93
+ }
94
+
95
+ class BrowserLogger {
96
+ constructor() {
97
+ this.ENABLED = true;
98
+ this.defaultArgs = [];
99
+ }
100
+
101
+ _formatMessage(level, ...args) {
102
+ if (!this.ENABLED) return;
103
+
104
+ const consoleMethod =
105
+ level === "error" ? "error" : level === "debug" ? "debug" : level === "info" ? "info" : "log";
106
+
107
+ const levelStyle = CSS_STYLES[level] || "";
108
+
109
+ const timeStr = `%c[${timestamp()}]`;
110
+ const tagStrs = this.defaultArgs.map((tag) => `%c[${tag}]`);
111
+
112
+ const formatStr = [timeStr, ...tagStrs].join(" ");
113
+
114
+ const styles = [levelStyle, ...this.defaultArgs.map(() => levelStyle)];
115
+
116
+ const formattedArgs = args.map((arg) => {
117
+ if (arg instanceof Error) {
118
+ return arg;
119
+ } else if (typeof arg === "object" && arg !== null) {
120
+ return arg;
121
+ }
122
+ return arg;
123
+ });
124
+
125
+ console[consoleMethod](formatStr, ...styles, ...formattedArgs);
126
+ }
127
+
128
+ Error(...args) {
129
+ this._formatMessage("error", ...args);
130
+ }
131
+ Success(...args) {
132
+ this._formatMessage("success", ...args);
133
+ }
134
+ Info(...args) {
135
+ this._formatMessage("info", ...args);
136
+ }
137
+ Debug(...args) {
138
+ this._formatMessage("debug", ...args);
139
+ }
140
+ Yellow(...args) {
141
+ this._formatMessage("yellow", ...args);
142
+ }
143
+
144
+ Disable() {
145
+ this.ENABLED = false;
146
+ }
147
+ Enable() {
148
+ this.ENABLED = true;
149
+ }
150
+ }
151
+
152
+ class NoOpLogger {
153
+ Error() {}
154
+ Success() {}
155
+ Info() {}
156
+ Debug() {}
157
+ Yellow() {}
158
+ Disable() {}
159
+ Enable() {}
160
+ }
161
+
162
+ function createLogger(args) {
163
+ let logger;
164
+
165
+ if (typeof console === "undefined") {
166
+ logger = new NoOpLogger();
167
+ } else if (typeof window !== "undefined") {
168
+ logger = new BrowserLogger();
169
+ } else {
170
+ logger = new NodeLogger();
171
+ }
172
+
173
+ if (typeof args === "string") {
174
+ logger.defaultArgs = [args];
175
+ } else if (Array.isArray(args)) {
176
+ logger.defaultArgs = args.filter((arg) => typeof arg === "string");
177
+ } else if (args) {
178
+ logger.defaultArgs = [String(args)];
179
+ } else {
180
+ logger.defaultArgs = [];
181
+ }
182
+
183
+ return logger;
184
+ }
185
+
186
+ export { createLogger };
@@ -0,0 +1,100 @@
1
+ import { createLogger } from "./logger.js";
2
+ import { sleep } from "../utils.js";
3
+
4
+ // eslint-disable-next-line no-unused-vars
5
+ const logger = createLogger("TM-RENDERER");
6
+
7
+ class NodePersistProxy {
8
+ constructor(db) {
9
+ this.db = db;
10
+ this.retryLimit = 3;
11
+ this.sleepTime = 1000;
12
+ }
13
+
14
+ async init(options) {
15
+ logger.Success("Initialized local DB");
16
+ return this.db.init(options);
17
+ }
18
+
19
+ async keys(retries = 0) {
20
+ if (retries == this.retryLimt) return;
21
+
22
+ try {
23
+ return this.db.keys().catch((ex) => {
24
+ throw ex;
25
+ });
26
+ } catch (ex) {
27
+ logger.Error(`PERSIST: Retrying .keys() (${ex.message})`);
28
+ await sleep(this.sleepTime);
29
+ return this.keys(++retries);
30
+ }
31
+ }
32
+
33
+ async getItem(key, retries = 0) {
34
+ if (!key) return;
35
+ if (retries == this.retryLimt) return;
36
+
37
+ try {
38
+ return this.db.getItem(key).catch(() => {});
39
+ } catch (ex) {
40
+ logger.Error(`PERSIST: Retrying .getItem() (${ex.message})`);
41
+ await sleep(this.sleepTime);
42
+ return this.getItem(key, ++retries);
43
+ }
44
+ }
45
+
46
+ async getMultiple(keys, retries = 0) {
47
+ if (!keys) return;
48
+ if (retries == this.retryLimt) return;
49
+
50
+ try {
51
+ const results = [];
52
+ for (let i = 0; i < keys.length; i++) {
53
+ results.push(await this.getItem(keys[i]));
54
+ }
55
+ return results;
56
+ } catch (ex) {
57
+ logger.Error(`PERSIST: Retrying .getMultiple() (${ex.message})`);
58
+ await sleep(this.sleepTime);
59
+ return this.getMultiple(keys, ++retries);
60
+ }
61
+ }
62
+
63
+ async setItem(key, value, retries = 0) {
64
+ if (retries == this.retryLimt) return;
65
+
66
+ try {
67
+ return this.db.setItem(key, value).catch(() => {});
68
+ } catch (ex) {
69
+ logger.Error(`PERSIST: Retrying .setItem() (${ex.message})`);
70
+ await sleep(this.sleepTime);
71
+ return this.setItem(key, value, ++retries);
72
+ }
73
+ }
74
+
75
+ async removeItem(key, retries = 0) {
76
+ if (retries == this.retryLimt) return;
77
+
78
+ try {
79
+ return this.db.removeItem(key).catch(() => {});
80
+ } catch (ex) {
81
+ logger.Error(`PERSIST: Retrying .removeItem() (${ex.message})`);
82
+ await sleep(this.sleepTime);
83
+ return this.removeItem(key, ++retries);
84
+ }
85
+ }
86
+
87
+ async updateItem(key, value, opts = {}, retries = 0) {
88
+ if (retries == this.retryLimt) return;
89
+
90
+ try {
91
+ return this.db.updateItem(key, value, opts).catch(() => {});
92
+ } catch (ex) {
93
+ logger.Error(`PERSIST: Retrying .updateItem() (${ex.message})`, key, value);
94
+ await sleep(this.sleepTime);
95
+ return this.updateItem(key, opts, value, ++retries);
96
+ }
97
+ }
98
+ }
99
+
100
+ export default NodePersistProxy;
@@ -0,0 +1,23 @@
1
+ import { createLogger } from "./logger.js";
2
+ import NodePersistance from "./node.persist.js";
3
+
4
+ const logger = createLogger("TM-RENDERER");
5
+
6
+ export default async () => {
7
+ logger.Info("Using node-persist");
8
+ const path = await import("node:path");
9
+ const os = await import("node:os");
10
+ const storage = await import("node-persist");
11
+ const fullPath = `${os.homedir()}/.renderer-store/`;
12
+ const p = path.relative(process.cwd(), fullPath);
13
+
14
+ let storageProxy = new NodePersistance(storage);
15
+ await storageProxy.init({
16
+ forgiveParseErrors: true,
17
+ writeQueue: true,
18
+ writeQueueIntervalMs: 1000,
19
+ writeQueueWriteOnlyLast: true,
20
+ dir: p,
21
+ });
22
+ return storageProxy;
23
+ };
@@ -0,0 +1,64 @@
1
+ class WebPersistance {
2
+ constructor() {
3
+ this.useLocalStorage = typeof localStorage !== "undefined";
4
+ if (!this.useLocalStorage) {
5
+ this.storage = new Map();
6
+ }
7
+ }
8
+
9
+ setItem(key, value) {
10
+ try {
11
+ if (this.useLocalStorage) {
12
+ localStorage.setItem(key, JSON.stringify(value));
13
+ } else {
14
+ this.storage.set(key, value);
15
+ }
16
+ return value;
17
+ } catch (e) {
18
+ if (this.useLocalStorage && !this.storage) {
19
+ this.storage = new Map();
20
+ this.useLocalStorage = false;
21
+ }
22
+ if (this.storage) {
23
+ this.storage.set(key, value);
24
+ }
25
+ return value;
26
+ }
27
+ }
28
+
29
+ getItem(key) {
30
+ try {
31
+ if (this.useLocalStorage) {
32
+ const item = localStorage.getItem(key);
33
+ return item ? JSON.parse(item) : undefined;
34
+ } else {
35
+ return this.storage.get(key);
36
+ }
37
+ } catch (e) {
38
+ if (this.useLocalStorage && !this.storage) {
39
+ this.storage = new Map();
40
+ this.useLocalStorage = false;
41
+ }
42
+ return this.storage ? this.storage.get(key) : undefined;
43
+ }
44
+ }
45
+
46
+ removeItem(key) {
47
+ try {
48
+ if (this.useLocalStorage) {
49
+ localStorage.removeItem(key);
50
+ return true;
51
+ } else {
52
+ return this.storage.delete(key);
53
+ }
54
+ } catch (e) {
55
+ if (this.useLocalStorage && !this.storage) {
56
+ this.storage = new Map();
57
+ this.useLocalStorage = false;
58
+ }
59
+ return this.storage ? this.storage.delete(key) : false;
60
+ }
61
+ }
62
+ }
63
+
64
+ export default WebPersistance;
@@ -0,0 +1,47 @@
1
+ import TMRenderer from "./tm/renderer.js";
2
+ import AXSRenderer from "./axs/renderer.js";
3
+ import { createLogger } from "./dependencies/logger.js";
4
+
5
+ class RendererFactory {
6
+ constructor() {
7
+ this.logger = createLogger("RENDERER-FACTORY");
8
+ }
9
+ async init() {
10
+ // Browser-only version - always use WebPersistance
11
+ const { default: WebPersistance } = await import("./dependencies/web.persist.js");
12
+ this.storage = new WebPersistance();
13
+ this.logger.Info("Renderer initialized for browser");
14
+ }
15
+
16
+ createRenderer(eventId, options = {}) {
17
+ if (!this.storage) {
18
+ this.logger.Error("RendererFactory used before initialization");
19
+ return null;
20
+ }
21
+
22
+ const renderer = new TMRenderer(eventId, options);
23
+ renderer.init({
24
+ storage: this.storage,
25
+ sharp: this.sharp,
26
+ fs: this.fs,
27
+ });
28
+ return renderer;
29
+ }
30
+
31
+ createAXSRenderer(eventId, options = {}) {
32
+ if (!this.storage) {
33
+ this.logger.Error("RendererFactory used before initialization");
34
+ return null;
35
+ }
36
+
37
+ const renderer = new AXSRenderer(eventId, options);
38
+ renderer.init({
39
+ storage: this.storage,
40
+ sharp: this.sharp,
41
+ fs: this.fs,
42
+ });
43
+ return renderer;
44
+ }
45
+ }
46
+
47
+ export default RendererFactory;
@@ -0,0 +1,21 @@
1
+ import RendererFactory from "./factory.js";
2
+
3
+ if (typeof process !== "undefined" && process.env) {
4
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
5
+
6
+ if (process.removeAllListeners) {
7
+ process.removeAllListeners("warning");
8
+ }
9
+
10
+ if (process.emitWarning) {
11
+ const originalEmitWarning = process.emitWarning;
12
+ process.emitWarning = function (warning, type, code, ctor) {
13
+ const suppressedTypes = ["ExperimentalWarning", "DeprecationWarning", "UnhandledPromiseRejectionWarning"];
14
+ if (suppressedTypes.includes(type)) return;
15
+
16
+ return originalEmitWarning.call(process, warning, type, code, ctor);
17
+ };
18
+ }
19
+ }
20
+
21
+ export default RendererFactory;
@@ -0,0 +1,101 @@
1
+ import { sleep } from "./utils.js";
2
+
3
+ const device = {
4
+ "user-agent":
5
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
6
+ "sec-ch-ua": `"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"`,
7
+ "sec-ch-ua-platform": '"macOS"',
8
+ };
9
+
10
+ const headers = {
11
+ "sec-ch-ua": device["sec-ch-ua"],
12
+ "sec-ch-ua-mobile": "?0",
13
+ "sec-ch-ua-platform": device["sec-ch-ua-platform"],
14
+ "dnt": "1",
15
+ "user-agent": device["user-agent"],
16
+ "sec-fetch-site": "none",
17
+ "sec-fetch-mode": "navigate",
18
+ "sec-fetch-user": "?1",
19
+ "sec-fetch-dest": "document",
20
+ "accept-encoding": "gzip, deflate, br, zstd",
21
+ "accept-language": "en-US,en;q=0.9",
22
+ };
23
+
24
+ async function createProxyAgent(proxy) {
25
+ // Browser-only version - no proxy support
26
+ return undefined;
27
+ }
28
+
29
+ async function getFetchOptions(targetUrl, proxy = null, customHeaders = {}) {
30
+ // Browser-only version with minimal headers for maximum compatibility
31
+ const options = {
32
+ headers: {
33
+ ...customHeaders,
34
+ },
35
+ mode: "cors",
36
+ cache: "default"
37
+ };
38
+
39
+ return options;
40
+ }
41
+
42
+ async function makeRequest(url, options = {}, retries = 0, logger = null) {
43
+ try {
44
+ const response = await fetch(url, options);
45
+
46
+ if (!response.ok) {
47
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
48
+ }
49
+
50
+ return response;
51
+ } catch (error) {
52
+ if (logger) {
53
+ logger.Error(`Request failed (${retries + 1}/3): ${error.message}`);
54
+ }
55
+
56
+ if (retries >= 2) {
57
+ throw error;
58
+ }
59
+
60
+ await sleep(1000);
61
+ return makeRequest(url, options, retries + 1, logger);
62
+ }
63
+ }
64
+
65
+ async function getJsonData(url, options = {}, retries = 0, logger = null) {
66
+ const response = await makeRequest(url, options, retries, logger);
67
+ return await response.json();
68
+ }
69
+
70
+ async function getBinaryData(url, options = {}, retries = 0, logger = null) {
71
+ const response = await makeRequest(url, options, retries, logger);
72
+ const arrayBuffer = await response.arrayBuffer();
73
+
74
+ // Use Buffer in Node.js, Uint8Array in browser
75
+ if (typeof Buffer !== 'undefined') {
76
+ return Buffer.from(arrayBuffer);
77
+ }
78
+ return new Uint8Array(arrayBuffer);
79
+ }
80
+
81
+ async function getJsonDataWithHeaders(url, customHeaders = {}, proxy = null, retries = 0, logger = null) {
82
+ const options = await getFetchOptions(url, proxy, customHeaders);
83
+ return await getJsonData(url, options, retries, logger);
84
+ }
85
+
86
+ async function getBinaryDataWithHeaders(url, customHeaders = {}, proxy = null, retries = 0, logger = null) {
87
+ const options = await getFetchOptions(url, proxy, customHeaders);
88
+ return await getBinaryData(url, options, retries, logger);
89
+ }
90
+
91
+ export {
92
+ createProxyAgent,
93
+ getFetchOptions,
94
+ makeRequest,
95
+ getJsonData,
96
+ getBinaryData,
97
+ getJsonDataWithHeaders,
98
+ getBinaryDataWithHeaders,
99
+ headers,
100
+ device,
101
+ };