@jay-framework/logger 0.12.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.
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Jay Framework Logger
3
+ *
4
+ * Centralized logging for all Jay packages. The default implementation
5
+ * uses console methods. CLIs replace this with level-aware implementations.
6
+ */
7
+ type LogLevel = 'silent' | 'info' | 'verbose';
8
+ /**
9
+ * Core logging interface used throughout Jay packages.
10
+ *
11
+ * Log method semantics:
12
+ * - `important()`: Always shown unless silent (startup messages, major events)
13
+ * - `info()`: Only shown in verbose mode (detailed operational info)
14
+ * - `warn()`: Shown unless silent (warnings that don't prevent operation)
15
+ * - `error()`: Always shown (errors that need attention)
16
+ */
17
+ interface JayLogger {
18
+ /** Log important messages - shown in default mode (startup, major events) */
19
+ important: (msg: string) => void;
20
+ /** Log info messages - shown only in verbose mode */
21
+ info: (msg: string) => void;
22
+ /** Log warnings - shown unless silent */
23
+ warn: (msg: string) => void;
24
+ /** Log errors - always shown */
25
+ error: (msg: string) => void;
26
+ }
27
+ /**
28
+ * Request timing interface for dev server performance tracking.
29
+ */
30
+ interface RequestTiming {
31
+ /** Record Vite SSR module compilation time */
32
+ recordViteSsr: (ms: number) => void;
33
+ /** Record parameter loading time (jay-html parsing, manifest) */
34
+ recordParams: (ms: number) => void;
35
+ /** Record slow render phase time */
36
+ recordSlowRender: (ms: number) => void;
37
+ /** Record fast render phase time */
38
+ recordFastRender: (ms: number) => void;
39
+ /** Record Vite client transform time */
40
+ recordViteClient: (ms: number) => void;
41
+ /** End the request and print final timing line */
42
+ end: () => void;
43
+ }
44
+ /**
45
+ * Extended logger with request timing support (for dev server).
46
+ */
47
+ interface JayDevLogger extends JayLogger {
48
+ /** Start timing a new request. Returns timing recorder. */
49
+ startRequest: (method: string, path: string) => RequestTiming;
50
+ }
51
+ /**
52
+ * Get the current logger instance.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { getLogger } from '@jay-framework/logger';
57
+ *
58
+ * const log = getLogger();
59
+ * log.info('[MyModule] Starting operation...');
60
+ * log.error('[MyModule] Operation failed!');
61
+ * ```
62
+ */
63
+ declare function getLogger(): JayLogger;
64
+ /**
65
+ * Replace the current logger with a custom implementation.
66
+ * Typically called by CLIs at startup to set log level.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { setLogger, type JayLogger } from '@jay-framework/logger';
71
+ *
72
+ * const cliLogger: JayLogger = {
73
+ * important: (msg) => console.log(msg),
74
+ * info: verbose ? (msg) => console.log(msg) : () => {},
75
+ * warn: quiet ? () => {} : (msg) => console.warn(msg),
76
+ * error: (msg) => console.error(msg),
77
+ * };
78
+ *
79
+ * setLogger(cliLogger);
80
+ * ```
81
+ */
82
+ declare function setLogger(logger: JayLogger): void;
83
+ /**
84
+ * Reset to the default console-based logger.
85
+ * Useful for testing.
86
+ */
87
+ declare function resetLogger(): void;
88
+ /**
89
+ * Create a log-level-aware logger.
90
+ * Convenience factory for CLIs.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * import { createLogger, setLogger } from '@jay-framework/logger';
95
+ *
96
+ * // From CLI flags
97
+ * const level = quiet ? 'silent' : verbose ? 'verbose' : 'info';
98
+ * setLogger(createLogger(level));
99
+ * ```
100
+ */
101
+ declare function createLogger(level: LogLevel): JayLogger;
102
+ /**
103
+ * Get the dev logger with timing support.
104
+ * Returns undefined if not set (non-dev-server context).
105
+ */
106
+ declare function getDevLogger(): JayDevLogger | undefined;
107
+ /**
108
+ * Set the dev logger with timing support.
109
+ * Called by dev server at startup.
110
+ */
111
+ declare function setDevLogger(logger: JayDevLogger): void;
112
+ /**
113
+ * Reset the dev logger.
114
+ */
115
+ declare function resetDevLogger(): void;
116
+ /**
117
+ * Create a dev logger with timing support.
118
+ * Displays request timing in a single updating line.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * import { createDevLogger, setDevLogger } from '@jay-framework/logger';
123
+ *
124
+ * const level = quiet ? 'silent' : verbose ? 'verbose' : 'info';
125
+ * setDevLogger(createDevLogger(level));
126
+ * ```
127
+ */
128
+ declare function createDevLogger(level: LogLevel): JayDevLogger;
129
+
130
+ export { type JayDevLogger, type JayLogger, type LogLevel, type RequestTiming, createDevLogger, createLogger, getDevLogger, getLogger, resetDevLogger, resetLogger, setDevLogger, setLogger };
package/dist/index.mjs ADDED
@@ -0,0 +1,130 @@
1
+ const defaultLogger = {
2
+ important: (msg) => console.log(msg),
3
+ info: (msg) => console.log(msg),
4
+ warn: (msg) => console.warn(msg),
5
+ error: (msg) => console.error(msg)
6
+ };
7
+ let currentLogger = defaultLogger;
8
+ function getLogger() {
9
+ return currentLogger;
10
+ }
11
+ function setLogger(logger) {
12
+ currentLogger = logger;
13
+ }
14
+ function resetLogger() {
15
+ currentLogger = defaultLogger;
16
+ }
17
+ function createLogger(level) {
18
+ const isSilent = level === "silent";
19
+ const isVerbose = level === "verbose";
20
+ return {
21
+ important: isSilent ? () => {
22
+ } : (msg) => console.log(msg),
23
+ info: isVerbose ? (msg) => console.log(msg) : () => {
24
+ },
25
+ warn: isSilent ? () => {
26
+ } : (msg) => console.warn(msg),
27
+ error: (msg) => console.error(msg)
28
+ };
29
+ }
30
+ let currentDevLogger;
31
+ function getDevLogger() {
32
+ return currentDevLogger;
33
+ }
34
+ function setDevLogger(logger) {
35
+ currentDevLogger = logger;
36
+ currentLogger = logger;
37
+ }
38
+ function resetDevLogger() {
39
+ currentDevLogger = void 0;
40
+ }
41
+ function createDevLogger(level) {
42
+ const baseLogger = createLogger(level);
43
+ const isSilent = level === "silent";
44
+ const isTTY = process.stdout.isTTY;
45
+ function formatTiming(state) {
46
+ const parts = [];
47
+ if (state.viteSsr > 0)
48
+ parts.push(`vite-ssr: ${state.viteSsr}ms`);
49
+ if (state.params > 0)
50
+ parts.push(`params: ${state.params}ms`);
51
+ if (state.slowRender > 0)
52
+ parts.push(`slow: ${state.slowRender}ms`);
53
+ if (state.fastRender > 0)
54
+ parts.push(`fast: ${state.fastRender}ms`);
55
+ if (state.viteClient > 0)
56
+ parts.push(`vite-client: ${state.viteClient}ms`);
57
+ const total = Date.now() - state.startTime;
58
+ const timingStr = parts.length > 0 ? `[${parts.join(" | ")}] ` : "";
59
+ return `${state.method} ${state.path} ${timingStr}${total}ms`;
60
+ }
61
+ function createTiming(method, path) {
62
+ const state = {
63
+ method,
64
+ path,
65
+ startTime: Date.now(),
66
+ viteSsr: 0,
67
+ params: 0,
68
+ slowRender: 0,
69
+ fastRender: 0,
70
+ viteClient: 0
71
+ };
72
+ let lastLineLength = 0;
73
+ function updateLine() {
74
+ if (isSilent)
75
+ return;
76
+ const line = formatTiming(state);
77
+ if (isTTY) {
78
+ const clearStr = "\r" + " ".repeat(lastLineLength) + "\r";
79
+ process.stdout.write(clearStr + line);
80
+ lastLineLength = line.length;
81
+ }
82
+ }
83
+ return {
84
+ recordViteSsr: (ms) => {
85
+ state.viteSsr += ms;
86
+ updateLine();
87
+ },
88
+ recordParams: (ms) => {
89
+ state.params += ms;
90
+ updateLine();
91
+ },
92
+ recordSlowRender: (ms) => {
93
+ state.slowRender += ms;
94
+ updateLine();
95
+ },
96
+ recordFastRender: (ms) => {
97
+ state.fastRender += ms;
98
+ updateLine();
99
+ },
100
+ recordViteClient: (ms) => {
101
+ state.viteClient += ms;
102
+ updateLine();
103
+ },
104
+ end: () => {
105
+ if (isSilent)
106
+ return;
107
+ const line = formatTiming(state);
108
+ if (isTTY) {
109
+ const clearStr = "\r" + " ".repeat(lastLineLength) + "\r";
110
+ process.stdout.write(clearStr);
111
+ }
112
+ console.log(line);
113
+ }
114
+ };
115
+ }
116
+ return {
117
+ ...baseLogger,
118
+ startRequest: createTiming
119
+ };
120
+ }
121
+ export {
122
+ createDevLogger,
123
+ createLogger,
124
+ getDevLogger,
125
+ getLogger,
126
+ resetDevLogger,
127
+ resetLogger,
128
+ setDevLogger,
129
+ setLogger
130
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@jay-framework/logger",
3
+ "version": "0.12.0",
4
+ "license": "Apache-2.0",
5
+ "main": "dist/index.mjs",
6
+ "types": "dist/index.d.mts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "npm run build:js && npm run build:types",
12
+ "build:watch": "npm run build:js -- --watch & npm run build:types -- --watch",
13
+ "build:js": "vite build",
14
+ "build:types": "tsup lib/index.ts --dts-only --format esm",
15
+ "build:check-types": "tsc",
16
+ "clean": "rimraf dist",
17
+ "confirm": "npm run clean && npm run build && npm run build:check-types && npm run test",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest"
20
+ },
21
+ "devDependencies": {
22
+ "@jay-framework/dev-environment": "^0.12.0",
23
+ "@types/node": "^20.11.5",
24
+ "rimraf": "^5.0.5",
25
+ "tsup": "^8.0.1",
26
+ "typescript": "^5.3.3",
27
+ "vite": "^5.0.11",
28
+ "vitest": "^1.2.1"
29
+ }
30
+ }