@@ -81,20 +81,53 @@ npm run example:simple
8181# Advanced example
8282npm run example:advanced
8383
84- # Quality example
85- npm run example:quality
84+ # List printers
85+ npm run example:list
86+
87+ # Printer capabilities
88+ npm run example:capabilities
89+
90+ # Print queue test
91+ npm run example:queue
8692```
8793
8894### Enable Debug Logging
8995
96+ The project includes a structured logging system with multiple levels:
97+
9098``` bash
99+ # Enable DEBUG level (most verbose)
91100# Windows CMD
92- set DEBUG=1 && npm run example:simple
101+ set LOG_LEVEL=DEBUG && npm run example:simple
93102
94103# PowerShell
95- $env :DEBUG=1; npm run example:simple
104+ $env :LOG_LEVEL=" DEBUG" ; npm run example:simple
105+
106+ # Bash
107+ LOG_LEVEL=DEBUG npm run example:simple
96108```
97109
110+ ** Available Log Levels:**
111+ - ` DEBUG ` - All messages including performance metrics
112+ - ` INFO ` - General information (default in development)
113+ - ` WARN ` - Warning messages
114+ - ` ERROR ` - Error messages only
115+ - ` SILENT ` - No logging (default in test/production)
116+
117+ ** Alternative Debug Flag:**
118+ ``` bash
119+ # Legacy DEBUG flag still supported
120+ DEBUG=1 npm run example:simple
121+
122+ # Or use DEBUG=* for compatibility
123+ DEBUG=* npm run example:simple
124+ ```
125+
126+ ** Auto-configuration by NODE_ENV:**
127+ - ` NODE_ENV=test ` → SILENT
128+ - ` NODE_ENV=production ` → INFO
129+ - Other → INFO
130+
98131## Project Structure
99132
100133```
@@ -103,38 +136,49 @@ windows-pdf-printer-native/
103136│ ├── core/ # Domain layer (platform-agnostic)
104137│ │ ├── types/ # Enums and interfaces
105138│ │ │ └── index.ts # PrintQuality, PaperSize, DuplexMode, etc.
106- │ │ └── interfaces/ # Contracts (IPrinter, IPrinterManager)
107- │ │ └── index.ts
139+ │ │ ├── interfaces/ # Contracts (IPrinter, IPrinterManager)
140+ │ │ │ └── index.ts
141+ │ │ └── logger/ # Structured logging system
142+ │ │ ├── logger.ts # Logger class implementation
143+ │ │ ├── types.d.ts # Logger type definitions
144+ │ │ └── index.ts # Public exports
108145│ │
109146│ ├── adapters/ # Infrastructure layer (platform-specific)
110147│ │ └── windows/
111- │ │ ├── api/ # Windows API bindings
112- │ │ │ ├── gdi32.api.ts # GDI32.dll functions
113- │ │ │ ├── winspool.api.ts # Winspool.drv functions
114- │ │ │ ├── kernel32.api.ts # Kernel32.dll functions
115- │ │ │ ├── pdfium.api.ts # PDFium bindings
148+ │ │ ├── api/ # Windows API bindings (koffi FFI)
149+ │ │ │ ├── gdi32.api.ts # GDI32.dll functions (printing)
150+ │ │ │ ├── winspool.api.ts # Winspool.drv (printer management)
151+ │ │ │ ├── kernel32.api.ts # Kernel32.dll (system functions)
152+ │ │ │ ├── comdlg32.api.ts # Comdlg32.dll (print dialog)
153+ │ │ │ ├── pdfium.api.ts # PDFium library bindings
116154│ │ │ └── index.ts # Barrel exports
117155│ │ │
118156│ │ ├── services/ # Specialized services
119- │ │ │ ├── pdf-render.service.ts # PDFium rendering
120- │ │ │ ├── devmode-config.service.ts # DEVMODE configuration
121- │ │ │ └── printer-connection.service.ts # Printer connection
157+ │ │ │ ├── pdf-render.service.ts # PDFium rendering & caching
158+ │ │ │ ├── devmode-config.service.ts # DEVMODE configuration
159+ │ │ │ ├── print-dialog.service.ts # Windows print dialog
160+ │ │ │ └── printer-capabilities.service.ts # Printer info & capabilities
122161│ │ │
123- │ │ ├── windows-printer.adapter.ts # IPrinter implementation
162+ │ │ ├── windows-printer.adapter.ts # IPrinter implementation
124163│ │ └── windows-printer-manager.adapter.ts # IPrinterManager implementation
125164│ │
126- │ ├── factories/ # Factory pattern
127- │ │ └── printer.factory.ts # Creates platform-specific instances
128- │ │
129- │ ├── services/ # Application services
130- │ │ └── platform-detector.service.ts
131- │ │
132165│ └── index.ts # Public API exports
133166│
134167├── bin/ # Native binaries
135168│ └── pdfium.dll # PDFium library (included in npm package)
136169├── examples/ # Usage examples
170+ │ ├── simple-print.ts # Basic printing
171+ │ ├── advanced-print.ts # Advanced options
172+ │ ├── list-printers.ts # List available printers
173+ │ ├── get-capabilities.ts # Get printer capabilities
174+ │ ├── print-with-dialog.ts # Print with dialog
175+ │ └── test-print-queue.ts # Multiple print jobs
137176├── tests/ # Unit and integration tests
177+ │ ├── logger.test.ts
178+ │ └── services/
179+ │ ├── devmode-config.service.test.ts
180+ │ ├── pdf-render.service.test.ts
181+ │ └── print-dialog.service.test.ts
138182└── lib/ # Compiled output (generated)
139183```
140184
@@ -146,19 +190,24 @@ This project follows **Clean Architecture** (Hexagonal Architecture):
146190 - Contains business logic, types, and interfaces
147191 - No external dependencies
148192 - Platform-agnostic
193+ - Includes structured logging system
149194
1501952 . ** Adapters Layer (Infrastructure)**
151196 - Windows-specific implementations
152- - API bindings (GDI32, Winspool, PDFium)
197+ - API bindings (GDI32, Winspool, PDFium, Comdlg32 )
153198 - Service implementations
199+ - All Windows API calls use koffi FFI
154200
155- 3 . ** Factories**
156- - Creates platform-specific instances
157- - Dependency injection
201+ 3 . ** Services**
202+ - ** PdfRenderService** : PDF rendering with PDFium, page caching
203+ - ** DevModeConfigService** : DEVMODE structure configuration
204+ - ** PrintDialogService** : Windows print dialog integration
205+ - ** PrinterCapabilitiesService** : Query printer information
158206
1592074 . ** Public API**
160208 - Clean, user-friendly facade
161- - Backward compatibility
209+ - Main exports: ` PDFPrinter ` , ` listPrinters ` , ` getDefaultPrinter `
210+ - All enums and types exported for configuration
162211
163212## Coding Standards
164213
@@ -250,18 +299,46 @@ throw new Error('Print failed');
250299
2513001 . ** Memory Management**
252301 - Clean up resources in ` finally ` blocks
253- - Use reference counting for shared resources
254- - Destroy PDFium bitmaps after use
302+ - Use reference counting for shared resources (PDFium singleton)
303+ - Destroy PDFium bitmaps immediately after use
304+ - Proper cleanup in adapters and services
305+
306+ 2 . ** Page Caching Strategy**
307+ - ** Enabled by default** for better performance with multiple copies
308+ - ** Automatically disabled** when printing multiple copies without collate (to prevent GDI buffer corruption)
309+ - Cache is cleared when PDF document is closed
310+ - Use ` printer.setCacheEnabled(false) ` when printing many different PDFs sequentially
311+
312+ ``` typescript
313+ // Good: Disable cache for sequential printing of different PDFs
314+ const printer = new PDFPrinter ();
315+ printer .setCacheEnabled (false );
316+ for (const pdf of manyPdfs ) {
317+ await printer .print (pdf );
318+ }
319+
320+ // Good: Enable cache for multiple copies of same PDF (default)
321+ printer .setCacheEnabled (true );
322+ await printer .print (pdf , { copies: 10 });
323+ ```
255324
256- 2 . ** Caching**
257- - Cache rendered pages for multiple copies
258- - Reuse singleton PDFium instance
259- - Clean cache when done
325+ 3 . ** Structured Logging**
326+ - Use Logger class with appropriate log levels
327+ - Performance timers: ` logger.startTimer() ` and ` logger.endTimer() `
328+ - Context-based logging: ` createLogger({ context: 'ServiceName' }) `
329+ - Automatically disabled in test environment
330+
331+ ``` typescript
332+ const logger = createLogger ({ context: ' PdfRender' });
333+ const timer = logger .startTimer (' renderPage' );
334+ // ... operation ...
335+ logger .endTimer (timer );
336+ ```
260337
261- 3 . ** Debug Logging **
262- - Use ` process.env.DEBUG ` flag
263- - Log performance metrics
264- - Include timing information
338+ 4 . ** GDI Resource Management **
339+ - Always delete Device Contexts with ` DeleteDC() `
340+ - Close printer handles with ` ClosePrinter() `
341+ - Use try-finally blocks for guaranteed cleanup
265342
266343## Testing
267344
@@ -282,24 +359,50 @@ npm test -- windows-print-api.test.ts
282359
2833601 . ** Unit Tests**
284361 ``` typescript
362+ describe (' Logger' , () => {
363+ it (' should create logger with context' , () => {
364+ const logger = createLogger ({ context: ' Test' });
365+ expect (logger ).toBeDefined ();
366+ });
367+
368+ it (' should respect log level' , () => {
369+ const logger = createLogger ({ level: LogLevel .ERROR });
370+ // Only ERROR level messages should appear
371+ });
372+ });
373+
285374 describe (' PdfRenderService' , () => {
286375 it (' should initialize PDFium library' , async () => {
287376 const service = new PdfRenderService ();
288377 await service .initialize ();
289- expect (service .isInitialized ()).toBe (true );
378+ // Verify initialization
379+ });
380+
381+ it (' should cache rendered pages' , () => {
382+ const service = new PdfRenderService ();
383+ service .setCacheEnabled (true );
384+ // Test caching behavior
290385 });
291386 });
292387 ```
293388
2943892 . ** Integration Tests**
295390 - Test real printer operations
296- - Test with actual PDF files
391+ - Test with actual PDF files (use ` bin/test.pdf ` )
297392 - Verify print job creation
393+ - Test DEVMODE configuration
394+ - Test print dialog integration
298395
2993963 . ** Test Coverage**
300397 - Aim for >80% coverage
301- - Focus on critical paths
302- - Test error scenarios
398+ - Focus on critical paths (printing, rendering, DEVMODE config)
399+ - Test error scenarios (invalid printers, missing PDFs)
400+ - Test edge cases (multiple copies, collate modes)
401+
402+ 4 . ** Test Environment**
403+ - Logging is automatically SILENT in test environment
404+ - Use ` LOG_LEVEL=DEBUG ` for debugging tests
405+ - Mock Windows API calls when appropriate
303406
304407### Manual Testing
305408
0 commit comments