@reliverse/relinka 1.6.1 → 2.2.7
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 +198 -345
- package/dist/mod.d.ts +49 -0
- package/dist/mod.js +182 -0
- package/package.json +17 -38
- package/LICENSE +0 -21
- package/bin/alias.d.ts +0 -8
- package/bin/alias.js +0 -8
- package/bin/impl.d.ts +0 -50
- package/bin/impl.js +0 -605
- package/bin/mod.d.ts +0 -3
- package/bin/mod.js +0 -14
- package/bin/setup.d.ts +0 -144
- package/bin/setup.js +0 -90
- package/bin/types.d.ts +0 -2
- package/bin/types.js +0 -0
package/README.md
CHANGED
|
@@ -1,407 +1,260 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @reliverse/relinka
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modern, lightweight logging library for TypeScript/JavaScript with both synchronous and asynchronous logging capabilities. Perfect for CLI tools, build systems, and concurrent applications.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 🚀 **Dual Mode**: Synchronous (`logger`) and asynchronous (`relinka`) logging
|
|
8
|
+
- 🎨 **Colored Output**: Beautiful, color-coded log levels using [@reliverse/relico](https://github.com/reliverse/relico)
|
|
9
|
+
- 📦 **Zero Dependencies**: Only depends on `@reliverse/relico` for colors
|
|
10
|
+
- 🔒 **Thread-Safe**: Async logger uses write queuing to prevent interleaving
|
|
11
|
+
- 🎯 **Type-Safe**: Full TypeScript support with proper type inference
|
|
12
|
+
- 📝 **Multiple Log Levels**: `log`, `error`, `fatal`, `warn`, `info`, `success`, `debug`, `box`, `raw`
|
|
13
|
+
- 🎭 **Callable Interface**: Use as a function or with method calls
|
|
14
|
+
- ⚡ **Non-Blocking**: Async logger queues writes but returns immediately
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
- 💬 **12 log levels**: `info`, `warn`, `success`, `error`, `verbose`, `fatal`, `log`, `step`, `box`, `message`, `internal`, `null`
|
|
11
|
-
- 🎨 **Beautiful terminal output** with automatic color handling and Unicode support
|
|
12
|
-
- 📁 **Smart file logging** with buffering, rotation, cleanup, and date-based naming
|
|
13
|
-
- 🧠 **Structured formatting** for objects, errors, and stack traces
|
|
14
|
-
- ⚙️ **Runtime configuration** via `.config/relinka.ts` or `relinka.config.ts`
|
|
15
|
-
- 🚨 **Fatal logging** that halts execution and triggers debugger in development
|
|
16
|
-
- 🧩 **Dual syntax support** - both function calls (`relinka("info", "Hello world")`) and method chaining (`relinka.info("Hello world")`)
|
|
17
|
-
- ⚡ **Performance optimized** with intelligent buffering and async support
|
|
18
|
-
- 🛎️ **Dler-ready** - if you use `dler build`, all `internal`-level logs will be removed from the built dist
|
|
19
|
-
|
|
20
|
-
## Quick Start
|
|
21
|
-
|
|
22
|
-
### 1. Install
|
|
16
|
+
## Installation
|
|
23
17
|
|
|
24
18
|
```bash
|
|
25
19
|
bun add @reliverse/relinka
|
|
20
|
+
# or
|
|
21
|
+
npm install @reliverse/relinka
|
|
22
|
+
# or
|
|
23
|
+
pnpm add @reliverse/relinka
|
|
26
24
|
```
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
## Quick Start
|
|
29
27
|
|
|
30
|
-
```
|
|
31
|
-
import {
|
|
28
|
+
```typescript
|
|
29
|
+
import { logger, relinka } from "@reliverse/relinka";
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
// Log with different levels
|
|
38
|
-
relinka("info", "Application started");
|
|
39
|
-
relinka("success", "Configuration loaded successfully");
|
|
40
|
-
relinka("warn", "This is a warning");
|
|
41
|
-
relinka("error", "Something went wrong");
|
|
42
|
-
|
|
43
|
-
// Use method syntax (also supported)
|
|
44
|
-
relinka.info("Another info message");
|
|
45
|
-
relinka.success("Another success message");
|
|
46
|
-
|
|
47
|
-
// Clean shutdown (required at end)
|
|
48
|
-
await relinkaShutdown();
|
|
49
|
-
}
|
|
31
|
+
// Synchronous logging (blocks until write completes)
|
|
32
|
+
logger.info("Application started");
|
|
33
|
+
logger.success("Build completed successfully");
|
|
34
|
+
logger.error("Failed to load configuration");
|
|
50
35
|
|
|
51
|
-
|
|
36
|
+
// Asynchronous logging (queues writes, returns immediately)
|
|
37
|
+
await relinka.info("Processing files...");
|
|
38
|
+
await relinka.success("All files processed");
|
|
39
|
+
await relinka.error("File processing failed");
|
|
52
40
|
```
|
|
53
41
|
|
|
54
|
-
##
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
42
|
+
## When to Use Sync vs Async
|
|
43
|
+
|
|
44
|
+
### Use `logger` (Synchronous) when:
|
|
45
|
+
- ✅ Sequential logging (like CLI tools with ordered output)
|
|
46
|
+
- ✅ Small, frequent console writes
|
|
47
|
+
- ✅ Error reporting that needs to maintain order
|
|
48
|
+
- ✅ When you need guaranteed write completion before continuing
|
|
49
|
+
- ✅ CLI tools where output order is critical
|
|
50
|
+
|
|
51
|
+
### Use `relinka` (Asynchronous) when:
|
|
52
|
+
- ✅ Logging from multiple concurrent async operations
|
|
53
|
+
- ✅ High-frequency logging where you don't want to block
|
|
54
|
+
- ✅ Large log outputs that could slow down execution
|
|
55
|
+
- ✅ Fire-and-forget logging (writes are queued and happen in background)
|
|
56
|
+
- ✅ When order matters but you don't want to wait for each write
|
|
57
|
+
|
|
58
|
+
**Note**: `relinka` queues writes in order but returns immediately without waiting for completion. This prevents blocking while maintaining write order.
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
### Log Levels
|
|
63
|
+
|
|
64
|
+
Both `logger` and `relinka` support the following log levels:
|
|
65
|
+
|
|
66
|
+
| Level | Symbol | Color | Description |
|
|
67
|
+
|-------|--------|-------|-------------|
|
|
68
|
+
| `log` | `│ ` | White | General logging |
|
|
69
|
+
| `error` | `✖ ` | Red | Error messages |
|
|
70
|
+
| `fatal` | `☠ ` | Red | Fatal errors |
|
|
71
|
+
| `warn` | `⚠ ` | Yellow | Warning messages |
|
|
72
|
+
| `info` | `■ ` | Blue | Informational messages |
|
|
73
|
+
| `success` | `✓ ` | Green | Success messages |
|
|
74
|
+
| `debug` | `✱ ` | Gray | Debug messages |
|
|
75
|
+
| `box` | - | White | Box-formatted messages |
|
|
76
|
+
| `raw` | - | - | Raw output (no formatting) |
|
|
77
|
+
|
|
78
|
+
### Usage Patterns
|
|
79
|
+
|
|
80
|
+
#### Method Calls
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { logger, relinka } from "@reliverse/relinka";
|
|
84
|
+
|
|
85
|
+
// Synchronous
|
|
86
|
+
logger.log("General message");
|
|
87
|
+
logger.info("Information");
|
|
88
|
+
logger.success("Operation succeeded");
|
|
89
|
+
logger.warn("Warning message");
|
|
90
|
+
logger.error("Error occurred");
|
|
91
|
+
logger.fatal("Fatal error");
|
|
92
|
+
logger.debug("Debug information");
|
|
93
|
+
logger.box("Boxed message");
|
|
94
|
+
logger.raw("Raw output without formatting");
|
|
95
|
+
|
|
96
|
+
// Asynchronous (returns Promise<void>)
|
|
97
|
+
await relinka.log("General message");
|
|
98
|
+
await relinka.info("Information");
|
|
99
|
+
await relinka.success("Operation succeeded");
|
|
100
|
+
await relinka.warn("Warning message");
|
|
101
|
+
await relinka.error("Error occurred");
|
|
102
|
+
await relinka.fatal("Fatal error");
|
|
103
|
+
await relinka.debug("Debug information");
|
|
104
|
+
await relinka.box("Boxed message");
|
|
105
|
+
await relinka.raw("Raw output without formatting");
|
|
89
106
|
```
|
|
90
107
|
|
|
91
|
-
####
|
|
92
|
-
|
|
93
|
-
Async version that waits for configuration to load.
|
|
108
|
+
#### Callable Function
|
|
94
109
|
|
|
95
|
-
|
|
96
|
-
await relinkaAsync("info", "Async message");
|
|
97
|
-
await relinkaAsync("success", "Operation completed");
|
|
98
|
-
```
|
|
110
|
+
Both loggers can be called as functions with the log level as the first argument:
|
|
99
111
|
|
|
100
|
-
|
|
112
|
+
```typescript
|
|
113
|
+
import { logger, relinka } from "@reliverse/relinka";
|
|
101
114
|
|
|
102
|
-
|
|
115
|
+
// Synchronous
|
|
116
|
+
logger("info", "Application started");
|
|
117
|
+
logger("success", "Build completed");
|
|
118
|
+
logger("error", "Build failed");
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
await
|
|
107
|
-
|
|
108
|
-
// With fresh log file (clears existing log file)
|
|
109
|
-
await relinkaConfig({ supportFreshLogFile: true });
|
|
120
|
+
// Asynchronous
|
|
121
|
+
await relinka("info", "Processing started");
|
|
122
|
+
await relinka("success", "Processing completed");
|
|
123
|
+
await relinka("error", "Processing failed");
|
|
110
124
|
```
|
|
111
125
|
|
|
112
|
-
####
|
|
126
|
+
#### Multiple Arguments
|
|
113
127
|
|
|
114
|
-
|
|
128
|
+
All log methods accept multiple arguments, which are automatically joined:
|
|
115
129
|
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
|
|
130
|
+
```typescript
|
|
131
|
+
logger.info("User", username, "logged in");
|
|
132
|
+
// Output: ■ User john_doe logged in
|
|
119
133
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
#### `log`, `logger`
|
|
123
|
-
|
|
124
|
-
Aliases for the main `relinka` function.
|
|
125
|
-
|
|
126
|
-
```ts
|
|
127
|
-
import { log, logger } from "@reliverse/relinka";
|
|
128
|
-
|
|
129
|
-
log("info", "Using alias");
|
|
130
|
-
logger.success("Another alias");
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
#### `message(msg, ...args)`
|
|
134
|
-
|
|
135
|
-
Convenience function for general messages.
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { message } from "@reliverse/relinka";
|
|
139
|
-
message("This is a general message");
|
|
134
|
+
logger.error("Failed to connect to", host, "on port", port);
|
|
135
|
+
// Output: ✖ Failed to connect to localhost on port 3000
|
|
140
136
|
```
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
## Examples
|
|
143
139
|
|
|
144
|
-
|
|
140
|
+
### CLI Tool (Synchronous)
|
|
145
141
|
|
|
146
|
-
```
|
|
147
|
-
import {
|
|
148
|
-
step("Step 1: Initialize");
|
|
149
|
-
step("Step 2: Load config");
|
|
150
|
-
```
|
|
142
|
+
```typescript
|
|
143
|
+
import { logger } from "@reliverse/relinka";
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
import { defineConfig } from "@reliverse/relinka";
|
|
165
|
-
|
|
166
|
-
export default defineConfig({
|
|
167
|
-
// Enable verbose logging
|
|
168
|
-
verbose: false,
|
|
169
|
-
|
|
170
|
-
// Timestamp configuration
|
|
171
|
-
timestamp: {
|
|
172
|
-
enabled: true,
|
|
173
|
-
format: "YYYY-MM-DD HH:mm:ss.SSS",
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
// File logging
|
|
177
|
-
saveLogsToFile: true,
|
|
178
|
-
logFile: {
|
|
179
|
-
outputPath: "logs/app.log",
|
|
180
|
-
nameWithDate: "append-before", // "disable" | "append-before" | "append-after"
|
|
181
|
-
freshLogFile: true, // Clear log file on each run
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
// Log rotation
|
|
185
|
-
dirs: {
|
|
186
|
-
maxLogFiles: 10, // Keep only the 10 most recent log files
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
// Performance tuning
|
|
190
|
-
bufferSize: 4096, // 4KB buffer before flushing
|
|
191
|
-
maxBufferAge: 5000, // 5 seconds max buffer age
|
|
192
|
-
cleanupInterval: 10000, // 10 seconds between cleanups
|
|
193
|
-
|
|
194
|
-
// Customize log levels
|
|
195
|
-
levels: {
|
|
196
|
-
success: {
|
|
197
|
-
symbol: "✓",
|
|
198
|
-
fallbackSymbol: "[OK]",
|
|
199
|
-
color: "greenBright",
|
|
200
|
-
spacing: 3,
|
|
201
|
-
},
|
|
202
|
-
info: {
|
|
203
|
-
symbol: "◈",
|
|
204
|
-
fallbackSymbol: "[i]",
|
|
205
|
-
color: "cyanBright",
|
|
206
|
-
spacing: 3,
|
|
207
|
-
},
|
|
208
|
-
// ... customize other levels
|
|
209
|
-
},
|
|
210
|
-
});
|
|
145
|
+
async function buildProject() {
|
|
146
|
+
logger.info("Starting build process...");
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
// Build steps
|
|
150
|
+
logger.success("Build completed successfully");
|
|
151
|
+
} catch (error) {
|
|
152
|
+
logger.error("Build failed:", error);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
211
156
|
```
|
|
212
157
|
|
|
213
|
-
###
|
|
214
|
-
|
|
215
|
-
| Option | Type | Default | Description |
|
|
216
|
-
|--------|------|---------|-------------|
|
|
217
|
-
| `verbose` | `boolean` | `false` | Enable verbose logging |
|
|
218
|
-
| `saveLogsToFile` | `boolean` | `false` | Save logs to file |
|
|
219
|
-
| `disableColors` | `boolean` | `false` | Disable color output |
|
|
220
|
-
| `timestamp.enabled` | `boolean` | `false` | Add timestamps to logs |
|
|
221
|
-
| `timestamp.format` | `string` | `"YYYY-MM-DD HH:mm:ss.SSS"` | Timestamp format |
|
|
222
|
-
| `logFile.outputPath` | `string` | `"logs.log"` | Log file path |
|
|
223
|
-
| `logFile.nameWithDate` | `string` | `"disable"` | Date handling in filename |
|
|
224
|
-
| `logFile.freshLogFile` | `boolean` | `true` | Clear log file on startup |
|
|
225
|
-
| `dirs.maxLogFiles` | `number` | `0` | Maximum log files to keep |
|
|
226
|
-
| `bufferSize` | `number` | `4096` | Buffer size in bytes |
|
|
227
|
-
| `maxBufferAge` | `number` | `5000` | Max buffer age in ms |
|
|
228
|
-
| `cleanupInterval` | `number` | `10000` | Cleanup interval in ms |
|
|
229
|
-
|
|
230
|
-
## File Logging
|
|
231
|
-
|
|
232
|
-
### File Naming Patterns
|
|
233
|
-
|
|
234
|
-
- **Default**: `logs.log`
|
|
235
|
-
- **With subdirectory**: `logs/app.log`
|
|
236
|
-
- **With date prefix**: `2025-01-15-logs.log`
|
|
237
|
-
- **With date suffix**: `logs-2025-01-15.log`
|
|
238
|
-
- **Combined**: `logs/2025-01-15-app.log`
|
|
239
|
-
|
|
240
|
-
### Automatic Cleanup
|
|
241
|
-
|
|
242
|
-
When `maxLogFiles` is set, Relinka automatically:
|
|
243
|
-
|
|
244
|
-
- Keeps only the N most recent log files
|
|
245
|
-
- Deletes older files during cleanup
|
|
246
|
-
- Runs cleanup periodically and on shutdown
|
|
247
|
-
|
|
248
|
-
## Advanced Usage
|
|
158
|
+
### Concurrent Operations (Asynchronous)
|
|
249
159
|
|
|
250
|
-
|
|
160
|
+
```typescript
|
|
161
|
+
import { relinka } from "@reliverse/relinka";
|
|
251
162
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
relinka(
|
|
257
|
-
//
|
|
258
|
-
relinka.
|
|
163
|
+
async function processFiles(files: string[]) {
|
|
164
|
+
// All logs are queued and won't block execution
|
|
165
|
+
await Promise.all(
|
|
166
|
+
files.map(async (file) => {
|
|
167
|
+
await relinka.info(`Processing ${file}...`);
|
|
168
|
+
// Process file...
|
|
169
|
+
await relinka.success(`Completed ${file}`);
|
|
170
|
+
})
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Writes happen in background, maintaining order
|
|
174
|
+
await relinka.info("All files processed");
|
|
175
|
+
}
|
|
259
176
|
```
|
|
260
177
|
|
|
261
178
|
### Box Formatting
|
|
262
179
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
180
|
+
```typescript
|
|
181
|
+
import { logger } from "@reliverse/relinka";
|
|
182
|
+
|
|
183
|
+
logger.box(`
|
|
184
|
+
Welcome to My Application
|
|
185
|
+
Version 1.0.0
|
|
186
|
+
Ready to serve requests
|
|
187
|
+
`);
|
|
188
|
+
|
|
189
|
+
// Output:
|
|
190
|
+
// ┌──────────────────────────────┐
|
|
191
|
+
// │ Welcome to My Application │
|
|
192
|
+
// │ Version 1.0.0 │
|
|
193
|
+
// │ Ready to serve requests │
|
|
194
|
+
// └──────────────────────────────┘
|
|
276
195
|
```
|
|
277
196
|
|
|
278
|
-
###
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
197
|
+
### Error Handling
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { logger } from "@reliverse/relinka";
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
await riskyOperation();
|
|
204
|
+
logger.success("Operation completed");
|
|
205
|
+
} catch (error) {
|
|
206
|
+
logger.error("Operation failed");
|
|
207
|
+
logger.fatal("Application cannot continue");
|
|
208
|
+
if (error instanceof Error) {
|
|
209
|
+
logger.raw(error.stack);
|
|
210
|
+
}
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
286
213
|
```
|
|
287
214
|
|
|
288
|
-
###
|
|
289
|
-
|
|
290
|
-
Add blank lines to output:
|
|
215
|
+
### Conditional Logging
|
|
291
216
|
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
```
|
|
217
|
+
```typescript
|
|
218
|
+
import { logger } from "@reliverse/relinka";
|
|
295
219
|
|
|
296
|
-
|
|
220
|
+
const DEBUG = process.env.DEBUG === "true";
|
|
297
221
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
async function main() {
|
|
302
|
-
await relinkaConfig(); // At the start
|
|
303
|
-
|
|
304
|
-
// Your application logic
|
|
305
|
-
relinka("info", "App running");
|
|
306
|
-
|
|
307
|
-
await relinkaShutdown(); // At the end
|
|
222
|
+
if (DEBUG) {
|
|
223
|
+
logger.debug("Debug mode enabled");
|
|
224
|
+
logger.debug("Configuration:", config);
|
|
308
225
|
}
|
|
309
226
|
```
|
|
310
227
|
|
|
311
|
-
|
|
228
|
+
## TypeScript Support
|
|
312
229
|
|
|
313
|
-
|
|
314
|
-
relinka("info", "User logged in"); // General info
|
|
315
|
-
relinka("success", "Payment processed"); // Success events
|
|
316
|
-
relinka("warn", "High memory usage"); // Warnings
|
|
317
|
-
relinka("error", "Database connection failed"); // Recoverable errors
|
|
318
|
-
relinka("fatal", "Critical system failure"); // Unrecoverable errors
|
|
319
|
-
```
|
|
230
|
+
Full TypeScript support with proper type inference:
|
|
320
231
|
|
|
321
|
-
|
|
232
|
+
```typescript
|
|
233
|
+
import type { Logger, LoggerAsync } from "@reliverse/relinka";
|
|
234
|
+
import { logger, relinka } from "@reliverse/relinka";
|
|
322
235
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
```
|
|
236
|
+
// Type-safe log level
|
|
237
|
+
type LogLevel = "log" | "error" | "fatal" | "warn" | "info" | "success" | "debug" | "box" | "raw";
|
|
326
238
|
|
|
327
|
-
|
|
239
|
+
// Logger types
|
|
240
|
+
const syncLogger: Logger = logger;
|
|
241
|
+
const asyncLogger: LoggerAsync = relinka;
|
|
328
242
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
statusCode: 500,
|
|
333
|
-
error: error.message
|
|
334
|
-
});
|
|
243
|
+
// Function call with type safety
|
|
244
|
+
logger("info", "Message"); // ✅ Valid
|
|
245
|
+
relinka("info", "Message"); // ✅ Valid, returns Promise<void>
|
|
335
246
|
```
|
|
336
247
|
|
|
337
|
-
##
|
|
338
|
-
|
|
339
|
-
- **Intelligent Buffering**: Logs are buffered and flushed efficiently
|
|
340
|
-
- **Async File Operations**: Non-blocking file writes
|
|
341
|
-
- **Memory Management**: Automatic cleanup of old log files
|
|
342
|
-
- **Unicode Detection**: Automatic fallback for non-Unicode terminals
|
|
343
|
-
|
|
344
|
-
## FAQ
|
|
345
|
-
|
|
346
|
-
### Why does my terminal hang after logging?
|
|
347
|
-
|
|
348
|
-
→ You forgot to call `await relinkaShutdown()` at the end of your program. This is required to flush buffers.
|
|
349
|
-
|
|
350
|
-
### Why isn't my configuration loading?
|
|
351
|
-
|
|
352
|
-
→ Make sure you call `await relinkaConfig()` at the start of your application.
|
|
353
|
-
|
|
354
|
-
### Does `fatal` always throw?
|
|
355
|
-
|
|
356
|
-
→ Yes, `fatal` logs always throw errors and halt execution. In development mode, they also trigger the debugger.
|
|
357
|
-
|
|
358
|
-
### How do I disable colors?
|
|
359
|
-
|
|
360
|
-
→ Set `disableColors: true` in your configuration or use `NO_COLOR=1` environment variable.
|
|
361
|
-
|
|
362
|
-
### Can I use Relinka in both sync and async contexts?
|
|
363
|
-
|
|
364
|
-
→ Yes! Use `relinka()` for sync operations and `relinkaAsync()` when you need to use some advanced features (like typing text streaming animation).
|
|
365
|
-
|
|
366
|
-
### What's the difference between `log` and `message` levels?
|
|
367
|
-
|
|
368
|
-
→ `log` uses a pipe symbol (│) and is for general logging, while `message` uses a different symbol (🞠) and is for general messages.
|
|
369
|
-
|
|
370
|
-
## Ecosystem
|
|
371
|
-
|
|
372
|
-
Relinka works great with other Reliverse tools:
|
|
373
|
-
|
|
374
|
-
- **CLI Development**: [`@reliverse/prompts`](https://npmjs.com/@reliverse/prompts)
|
|
375
|
-
- **Bundling**: [`@reliverse/dler`](https://npmjs.com/@reliverse/dler)
|
|
376
|
-
|
|
377
|
-
## Roadmap
|
|
378
|
-
|
|
379
|
-
- [x] File logging with rotation
|
|
380
|
-
- [x] Timestamp support
|
|
381
|
-
- [x] Date-based file naming
|
|
382
|
-
- [x] Automatic cleanup
|
|
383
|
-
- [x] Fatal logging with debugger
|
|
384
|
-
- [x] Runtime configuration
|
|
385
|
-
- [x] Dual syntax support
|
|
386
|
-
- [ ] Plugin system
|
|
387
|
-
- [ ] Custom formatters
|
|
388
|
-
- [ ] CLI interface for log management
|
|
389
|
-
- [ ] WebSocket streaming
|
|
390
|
-
- [ ] Structured logging (JSON)
|
|
391
|
-
|
|
392
|
-
## Contributing
|
|
248
|
+
## Requirements
|
|
393
249
|
|
|
394
|
-
|
|
250
|
+
- **Runtime**: Bun (uses `Bun.write` for async operations)
|
|
251
|
+
- **TypeScript**: 5.0+ (for best experience)
|
|
395
252
|
|
|
396
253
|
## License
|
|
397
254
|
|
|
398
|
-
|
|
255
|
+
MIT
|
|
399
256
|
|
|
400
|
-
##
|
|
257
|
+
## Related Packages
|
|
401
258
|
|
|
402
|
-
|
|
259
|
+
- [@reliverse/relico](https://github.com/reliverse/relico) - Color utilities used by relinka
|
|
403
260
|
|
|
404
|
-
- [unjs/consola](https://github.com/unjs/consola) - Console logging for Node.js
|
|
405
|
-
- [winston](https://github.com/winstonjs/winston) - Multi-transport logging
|
|
406
|
-
- [pino](https://github.com/pinojs/pino) - Fast Node.js logger
|
|
407
|
-
- [node-bunyan](https://github.com/trentm/node-bunyan) - JSON logging
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
declare const LOG_COLORS: {
|
|
2
|
+
readonly log: any;
|
|
3
|
+
readonly error: any;
|
|
4
|
+
readonly fatal: any;
|
|
5
|
+
readonly warn: any;
|
|
6
|
+
readonly info: any;
|
|
7
|
+
readonly success: any;
|
|
8
|
+
readonly debug: any;
|
|
9
|
+
readonly box: any;
|
|
10
|
+
};
|
|
11
|
+
type LogLevel = keyof typeof LOG_COLORS;
|
|
12
|
+
interface LoggerBase {
|
|
13
|
+
log: (...args: unknown[]) => void | Promise<void>;
|
|
14
|
+
error: (...args: unknown[]) => void | Promise<void>;
|
|
15
|
+
fatal: (...args: unknown[]) => void | Promise<void>;
|
|
16
|
+
warn: (...args: unknown[]) => void | Promise<void>;
|
|
17
|
+
info: (...args: unknown[]) => void | Promise<void>;
|
|
18
|
+
success: (...args: unknown[]) => void | Promise<void>;
|
|
19
|
+
debug: (...args: unknown[]) => void | Promise<void>;
|
|
20
|
+
box: (...args: unknown[]) => void | Promise<void>;
|
|
21
|
+
raw: (...args: unknown[]) => void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
interface LoggerAsync extends LoggerBase {
|
|
24
|
+
(level: LogLevel, ...args: unknown[]): Promise<void>;
|
|
25
|
+
log: (...args: unknown[]) => Promise<void>;
|
|
26
|
+
error: (...args: unknown[]) => Promise<void>;
|
|
27
|
+
fatal: (...args: unknown[]) => Promise<void>;
|
|
28
|
+
warn: (...args: unknown[]) => Promise<void>;
|
|
29
|
+
info: (...args: unknown[]) => Promise<void>;
|
|
30
|
+
success: (...args: unknown[]) => Promise<void>;
|
|
31
|
+
debug: (...args: unknown[]) => Promise<void>;
|
|
32
|
+
box: (...args: unknown[]) => Promise<void>;
|
|
33
|
+
raw: (...args: unknown[]) => Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
interface Logger extends LoggerBase {
|
|
36
|
+
(level: LogLevel, ...args: unknown[]): void;
|
|
37
|
+
log: (...args: unknown[]) => void;
|
|
38
|
+
error: (...args: unknown[]) => void;
|
|
39
|
+
fatal: (...args: unknown[]) => void;
|
|
40
|
+
warn: (...args: unknown[]) => void;
|
|
41
|
+
info: (...args: unknown[]) => void;
|
|
42
|
+
success: (...args: unknown[]) => void;
|
|
43
|
+
debug: (...args: unknown[]) => void;
|
|
44
|
+
box: (...args: unknown[]) => void;
|
|
45
|
+
raw: (...args: unknown[]) => void;
|
|
46
|
+
}
|
|
47
|
+
export declare const logger: Logger;
|
|
48
|
+
export declare const relinka: LoggerAsync;
|
|
49
|
+
export {};
|