Skip to content

Commit fd877cd

Browse files
Documents (#18)
* bkp: Version Bump / required windows SO * chore: Better documents * revert: restore package.json and package-lock.json to original state * chore: Improve documents
1 parent 484bba8 commit fd877cd

File tree

7 files changed

+1664
-451
lines changed

7 files changed

+1664
-451
lines changed

CONTRIBUTING.md

Lines changed: 143 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,53 @@ npm run example:simple
8181
# Advanced example
8282
npm 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

150195
2. **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

159207
4. **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

251300
1. **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

283360
1. **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

294389
2. **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

299396
3. **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

Comments
 (0)