@visulima/pail 4.0.1 → 4.0.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ## @visulima/pail [4.0.2](https://github.com/visulima/visulima/compare/%40visulima%2Fpail%404.0.1...%40visulima%2Fpail%404.0.2) (2026-07-27)
2
+
1
3
  ## @visulima/pail [4.0.1](https://github.com/visulima/visulima/compare/%40visulima%2Fpail%404.0.0...%40visulima%2Fpail%404.0.1) (2026-07-26)
2
4
 
3
5
 
@@ -0,0 +1,459 @@
1
+ # Migration Guide
2
+
3
+ This guide documents breaking changes and migration steps for the `@visulima/pail` package.
4
+
5
+ ## Version 4.0.0
6
+
7
+ ### Breaking Changes Summary
8
+
9
+ - **Spinner removed**: `createSpinner()` and `createMultiSpinner()` removed — use `@visulima/spinner`
10
+ - **Progress bar removed**: `createProgressBar()` and `createMultiProgressBar()` removed — use `@visulima/progress-bar`
11
+ - **Interactive manager extracted**: `@visulima/pail/interactive` export removed — use `@visulima/interactive-manager`
12
+ - **Spinner/progress-bar exports removed**: `@visulima/pail/spinner` and `@visulima/pail/progress-bar` no longer exist
13
+
14
+ ### Install New Packages
15
+
16
+ ```bash
17
+ pnpm add @visulima/spinner @visulima/progress-bar
18
+ ```
19
+
20
+ `@visulima/interactive-manager` is automatically installed as a dependency of both packages and of pail itself.
21
+
22
+ ### Spinner Migration
23
+
24
+ #### Before (v3.x)
25
+
26
+ ```typescript
27
+ import { createPail } from "@visulima/pail";
28
+
29
+ const logger = createPail({ interactive: true });
30
+
31
+ const spinner = logger.createSpinner({ name: "dots" });
32
+ spinner.start("Loading...");
33
+ spinner.succeed("Done!");
34
+
35
+ const multi = logger.createMultiSpinner({ name: "dots" });
36
+ const s1 = multi.create("Task 1");
37
+ s1.start();
38
+ s1.succeed("Done");
39
+ multi.stop();
40
+ ```
41
+
42
+ #### After (v4.x)
43
+
44
+ ```typescript
45
+ import { createPail } from "@visulima/pail";
46
+ import { MultiSpinner, Spinner } from "@visulima/spinner";
47
+
48
+ const logger = createPail({ interactive: true });
49
+ const manager = logger.getInteractiveManager();
50
+
51
+ const spinner = new Spinner({ name: "dots" }, manager);
52
+ spinner.start("Loading...");
53
+ spinner.succeed("Done!");
54
+
55
+ const multi = new MultiSpinner({ name: "dots" }, manager);
56
+ const s1 = multi.create("Task 1");
57
+ s1.start();
58
+ s1.succeed("Done");
59
+ multi.stop();
60
+ ```
61
+
62
+ ### Progress Bar Migration
63
+
64
+ #### Before (v3.x)
65
+
66
+ ```typescript
67
+ import { createPail } from "@visulima/pail";
68
+
69
+ const logger = createPail({ interactive: true });
70
+
71
+ const bar = logger.createProgressBar({
72
+ total: 100,
73
+ format: "Downloading [{bar}] {percentage}%",
74
+ });
75
+ bar.start();
76
+ bar.update(50);
77
+ bar.stop();
78
+
79
+ const multi = logger.createMultiProgressBar();
80
+ const b1 = multi.create(100);
81
+ b1.update(50);
82
+ multi.stop();
83
+ ```
84
+
85
+ #### After (v4.x)
86
+
87
+ ```typescript
88
+ import { createPail } from "@visulima/pail";
89
+ import { MultiProgressBar, ProgressBar } from "@visulima/progress-bar";
90
+
91
+ const logger = createPail({ interactive: true });
92
+ const manager = logger.getInteractiveManager();
93
+
94
+ const bar = new ProgressBar(
95
+ {
96
+ total: 100,
97
+ format: "Downloading [{bar}] {percentage}%",
98
+ },
99
+ manager,
100
+ );
101
+ bar.start();
102
+ bar.update(50);
103
+ bar.stop();
104
+
105
+ const multi = new MultiProgressBar({}, manager);
106
+ const b1 = multi.create(100);
107
+ b1.update(50);
108
+ multi.stop();
109
+ ```
110
+
111
+ ### Interactive Manager Migration
112
+
113
+ #### Before (v3.x)
114
+
115
+ ```typescript
116
+ import { InteractiveManager, InteractiveStreamHook } from "@visulima/pail/interactive";
117
+ ```
118
+
119
+ #### After (v4.x)
120
+
121
+ ```typescript
122
+ import { InteractiveManager, InteractiveStreamHook } from "@visulima/interactive-manager";
123
+ ```
124
+
125
+ ### Spinner/Progress-Bar Type Imports
126
+
127
+ #### Before (v3.x)
128
+
129
+ ```typescript
130
+ import type { SpinnerOptions, SpinnerIcons } from "@visulima/pail";
131
+ import type { ProgressBarOptions, MultiBarOptions } from "@visulima/pail";
132
+ ```
133
+
134
+ #### After (v4.x)
135
+
136
+ ```typescript
137
+ import type { SpinnerOptions, SpinnerIcons } from "@visulima/spinner";
138
+ import type { ProgressBarOptions, MultiBarOptions } from "@visulima/progress-bar";
139
+ ```
140
+
141
+ ### Spinner API Changes
142
+
143
+ The new `@visulima/spinner` package has a few API differences from pail's old spinner:
144
+
145
+ | Old (pail) | New (@visulima/spinner) | Notes |
146
+ | ----------------------------------- | -------------------------------------------------- | -------------------------------------------------------- |
147
+ | `logger.createSpinner(opts)` | `new Spinner(opts, manager)` | Pass manager as 2nd arg |
148
+ | `spinner.fail(text)` | `spinner.failed(text)` | Method renamed |
149
+ | `SpinnerStyle` object with colorize | `style: (text) => string` or `SpinnerStyle` object | Style is now a function or uses Node.js `util.styleText` |
150
+
151
+ ### What Stays the Same
152
+
153
+ - `getInteractiveManager()` — still available on pail, returns the manager instance
154
+ - Interactive mode — still enabled via `{ interactive: true }`
155
+ - All logging methods — unchanged
156
+ - Reporters — unchanged
157
+ - Processors — unchanged
158
+ - Middleware — unchanged
159
+
160
+ ### Why This Change?
161
+
162
+ Spinners and progress bars are now **independent packages** that can be used without pail:
163
+
164
+ - **`@visulima/spinner`** — 109 spinner animations, styling, multi-spinner support
165
+ - **`@visulima/progress-bar`** — 7 styles, gradients, multi-bar, composite mode
166
+ - **`@visulima/interactive-manager`** — terminal stream coordination
167
+
168
+ This reduces pail's bundle size and allows these features to be used in any CLI tool, not just with pail.
169
+
170
+ ---
171
+
172
+ ## Version 3.0.0
173
+
174
+ ### Breaking Changes Summary
175
+
176
+ - **Minimum Node.js version**: 20.19+ required
177
+ - **Module format**: ESM-only (CommonJS removed)
178
+ - **Reporter imports**: Changed to granular paths
179
+ - **Internal dependencies**: Consolidated with @visulima/string
180
+
181
+ ### Dependency Consolidation
182
+
183
+ In version 3.0.0, we consolidated external dependencies by replacing them with internal `@visulima/string` package utilities.
184
+
185
+ #### Replaced Dependencies
186
+
187
+ | Previous | New | Reason |
188
+ | --------------- | ----------------------------------- | ---------------------------------------- |
189
+ | `wrap-ansi` | `@visulima/string` (wordWrap) | Consolidated text wrapping functionality |
190
+ | `string-length` | `@visulima/string` (getStringWidth) | Consolidated string width calculation |
191
+
192
+ #### Benefits
193
+
194
+ - **Reduced bundle size**: Fewer external dependencies
195
+ - **Better maintenance**: Internal package control
196
+ - **Consistent API**: Unified string utilities across visulima packages
197
+ - **Performance**: Optimized internal implementations
198
+
199
+ #### Backward Compatibility
200
+
201
+ The dependency consolidation changes are **backward compatible** for pail users. The internal API changes don't affect the public pail API. The CJS export removal and reporter export structure changes are **breaking changes** that require migration.
202
+
203
+ ### Reporter Export Structure Changes
204
+
205
+ The reporter export structure has been reorganized to provide more granular access to individual reporter types.
206
+
207
+ #### Old Export Structure
208
+
209
+ ```javascript
210
+ import { JsonReporter, JsonFileReporter, PrettyReporter, SimpleReporter } from "@visulima/pail/reporter";
211
+ ```
212
+
213
+ #### New Granular Export Structure
214
+
215
+ ```javascript
216
+ import { JsonReporter } from "@visulima/pail/reporter/json";
217
+ import { JsonFileReporter } from "@visulima/pail/reporter/file";
218
+ import { PrettyReporter } from "@visulima/pail/reporter/pretty";
219
+ import { SimpleReporter } from "@visulima/pail/reporter/simple";
220
+ ```
221
+
222
+ #### Benefits
223
+
224
+ - **Smaller bundle sizes**: Only import the reporters you need
225
+ - **Better tree-shaking**: Unused reporters are excluded from bundles
226
+ - **Clearer dependencies**: Explicit imports make dependencies obvious
227
+ - **Improved performance**: Reduced bundle size and faster loading
228
+
229
+ ### CommonJS (CJS) Export Removed
230
+
231
+ The CommonJS (CJS) export has been removed in favor of ECMAScript Modules (ESM) only. For CJS compatibility in Node.js 20.19+, use dynamic imports.
232
+
233
+ #### Before (v2.x)
234
+
235
+ ```javascript
236
+ // This no longer works
237
+ const { createPail, pail } = require("@visulima/pail");
238
+ ```
239
+
240
+ #### After (v3.x) - Node.js 20.19+
241
+
242
+ ```javascript
243
+ // Use dynamic import for ESM modules from CJS
244
+ const { createPail, pail } = await import("@visulima/pail");
245
+ ```
246
+
247
+ #### Alternative: Convert to ESM
248
+
249
+ For better compatibility and performance, convert your project to use ESM:
250
+
251
+ ```json
252
+ // package.json
253
+ {
254
+ "name": "your-project",
255
+ "type": "module"
256
+ }
257
+ ```
258
+
259
+ ```typescript
260
+ // Your files can now use ESM imports
261
+ import { createPail, pail } from "@visulima/pail";
262
+
263
+ const logger = createPail({
264
+ reporters: [new JsonReporter()],
265
+ });
266
+
267
+ logger.info("Hello ESM world!");
268
+ ```
269
+
270
+ ### Why ESM Only?
271
+
272
+ #### Benefits of ESM for Pail
273
+
274
+ - **Standards Compliance**: ESM follows the official JavaScript module specification
275
+ - **Tree Shaking**: Better dead code elimination in bundlers
276
+ - **Static Analysis**: Improved tooling and IDE support
277
+ - **Future-Proof**: ESM is the standard for modern JavaScript
278
+ - **Bundle Optimization**: Smaller bundle sizes with better optimization
279
+
280
+ ### Migration Steps
281
+
282
+ #### 1. Update Reporter Imports
283
+
284
+ Replace old reporter imports with new granular imports:
285
+
286
+ ```javascript
287
+ // Before
288
+ import { JsonReporter, JsonFileReporter, PrettyReporter, SimpleReporter } from "@visulima/pail/reporter";
289
+
290
+ // After
291
+ import { JsonReporter } from "@visulima/pail/reporter/json";
292
+ import { JsonFileReporter } from "@visulima/pail/reporter/file";
293
+ import { PrettyReporter } from "@visulima/pail/reporter/pretty";
294
+ import { SimpleReporter } from "@visulima/pail/reporter/simple";
295
+ ```
296
+
297
+ #### 2. Use Dynamic Imports for CJS
298
+
299
+ Replace `require()` calls with dynamic `import()`:
300
+
301
+ ```javascript
302
+ // Before
303
+ const { createPail } = require("@visulima/pail");
304
+
305
+ // After
306
+ const { createPail } = await import("@visulima/pail");
307
+ ```
308
+
309
+ #### 3. Convert to ESM (Recommended)
310
+
311
+ For the best experience, convert your project to use ESM:
312
+
313
+ ```json
314
+ // package.json
315
+ {
316
+ "name": "your-project",
317
+ "type": "module",
318
+ "scripts": {
319
+ "start": "node src/index.js"
320
+ }
321
+ }
322
+ ```
323
+
324
+ ```typescript
325
+ // src/index.ts
326
+ import { createPail, pail } from "@visulima/pail";
327
+ import { JsonReporter } from "@visulima/pail/reporter/json";
328
+
329
+ async function main() {
330
+ const logger = createPail({
331
+ reporters: [new JsonReporter()],
332
+ });
333
+
334
+ logger.info("Project started");
335
+ }
336
+
337
+ main().catch(console.error);
338
+ ```
339
+
340
+ ### Migration Issues & Solutions
341
+
342
+ #### 1. Old Reporter Imports No Longer Work
343
+
344
+ **Problem**: `import { JsonReporter } from "@visulima/pail/reporter"` throws "module not found" error.
345
+
346
+ **Solution**: Use new granular reporter imports:
347
+
348
+ ```javascript
349
+ // Before
350
+ import { JsonReporter, JsonFileReporter, PrettyReporter, SimpleReporter } from "@visulima/pail/reporter";
351
+
352
+ // After
353
+ import { JsonReporter } from "@visulima/pail/reporter/json";
354
+ import { JsonFileReporter } from "@visulima/pail/reporter/file";
355
+ import { PrettyReporter } from "@visulima/pail/reporter/pretty";
356
+ import { SimpleReporter } from "@visulima/pail/reporter/simple";
357
+ ```
358
+
359
+ #### 2. require() Calls No Longer Work
360
+
361
+ **Problem**: `require('@visulima/pail')` throws "module not found" error.
362
+
363
+ **Solution**: Use dynamic imports:
364
+
365
+ ```javascript
366
+ // Dynamic import for ESM modules from CJS
367
+ const { createPail, pail } = await import("@visulima/pail");
368
+ ```
369
+
370
+ #### 3. Async Context Required
371
+
372
+ **Problem**: Functions using pail must be async when using dynamic imports.
373
+
374
+ **Solution**: Mark functions as async and await the import:
375
+
376
+ ```typescript
377
+ // Before
378
+ function setupLogger() {
379
+ const { createPail } = require("@visulima/pail");
380
+
381
+ return createPail();
382
+ }
383
+
384
+ // After
385
+ async function setupLogger() {
386
+ const { createPail } = await import("@visulima/pail");
387
+
388
+ return createPail();
389
+ }
390
+ ```
391
+
392
+ ### Verification Steps
393
+
394
+ 1. **Test new reporter imports**:
395
+
396
+ ```javascript
397
+ // test-reporters.mjs
398
+ import { JsonReporter } from "@visulima/pail/reporter/json";
399
+ import { JsonFileReporter } from "@visulima/pail/reporter/file";
400
+ import { PrettyReporter } from "@visulima/pail/reporter/pretty";
401
+ import { SimpleReporter } from "@visulima/pail/reporter/simple";
402
+ import { createPail } from "@visulima/pail";
403
+
404
+ async function test() {
405
+ const logger = createPail({
406
+ reporters: [new JsonReporter(), new JsonFileReporter({ filePath: "/tmp/test.log" }), new PrettyReporter(), new SimpleReporter()],
407
+ });
408
+
409
+ logger.info("All reporter imports successful");
410
+ }
411
+
412
+ test().catch(console.error);
413
+ ```
414
+
415
+ 2. **Test ESM imports**:
416
+
417
+ ```javascript
418
+ // test.mjs
419
+ import { createPail } from "@visulima/pail";
420
+
421
+ async function test() {
422
+ const logger = createPail();
423
+
424
+ logger.info("ESM import successful");
425
+ }
426
+
427
+ test().catch(console.error);
428
+ ```
429
+
430
+ 3. **Test dynamic imports from CJS**:
431
+
432
+ ```javascript
433
+ // test.cjs
434
+ async function test() {
435
+ const { createPail } = await import("@visulima/pail");
436
+ const logger = createPail();
437
+
438
+ logger.info("Dynamic import successful");
439
+ }
440
+
441
+ test().catch(console.error);
442
+ ```
443
+
444
+ ### Migration Benefits
445
+
446
+ #### Reporter Import Benefits
447
+
448
+ - **Smaller bundle sizes**: Only import the reporters you need
449
+ - **Better tree-shaking**: Unused reporters are excluded from bundles
450
+ - **Clearer dependencies**: Explicit imports make dependencies obvious
451
+ - **Improved performance**: Reduced bundle size and faster loading
452
+
453
+ #### ESM Migration Benefits
454
+
455
+ - **Better Performance**: ESM's improved module caching in Node.js 20.19+
456
+ - **Modern JavaScript**: Consistent module syntax across environments
457
+ - **Bundle Optimization**: Better tree-shaking and dead code elimination
458
+ - **Developer Experience**: Improved IDE support and error messages
459
+ - **Future-Proof**: Aligned with JavaScript ecosystem direction
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/pail",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "Highly configurable Logger for Node.js, Edge and Browser.",
5
5
  "keywords": [
6
6
  "anolilab",
@@ -82,7 +82,8 @@
82
82
  "dist/**",
83
83
  "README.md",
84
84
  "CHANGELOG.md",
85
- "LICENSE.md"
85
+ "LICENSE.md",
86
+ "MIGRATION-GUIDE.md"
86
87
  ],
87
88
  "os": [
88
89
  "darwin",