@plevands/epson-thermal-printer 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Colegio Plevand's
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,489 @@
1
+ # @plevands/epson-thermal-printer
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@plevands/epson-thermal-printer.svg)](https://www.npmjs.com/package/@plevands/epson-thermal-printer)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ Library for Epson thermal printer integration with PDF support and React hooks.
8
+
9
+ ## Requirements
10
+
11
+ - **Node.js** 18.x or higher
12
+ - **React** 18.x or higher
13
+ - **Epson ePOS SDK** 2.27.0 (included)
14
+ - Epson thermal printer with network connectivity
15
+
16
+ ## Features
17
+
18
+ - ✅ **Official Epson ePOS SDK** integration with TypeScript support
19
+ - 🔄 **Lazy loading** - SDK loads automatically on first print (no manual setup)
20
+ - 📄 **PDF Processing** - Intelligent margin trimming and scaling for thermal printers
21
+ - ⚛️ **React Hooks** - Modern hooks-based API (`useEpsonPrinter`, `usePrinterConfig`, `usePdfProcessor`)
22
+ - 🎨 **Optional UI Components** - Ready-to-use React components for quick integration
23
+ - 🔧 **Fully Configurable** - Control PDF processing, print quality, paper width, and more
24
+ - 📦 **TypeScript First** - Complete type definitions included
25
+ - 🎯 **Zero Config** - Works out of the box with sensible defaults
26
+
27
+ ## Installation
28
+
29
+ ### Development with npm link
30
+
31
+ ```bash
32
+ # In the library directory
33
+ npm install
34
+ npm run build
35
+ npm link
36
+
37
+ # In your project
38
+ npm link @plevands/epson-thermal-printer
39
+ ```
40
+
41
+ ### Usage in Your Projects
42
+
43
+ ```bash
44
+ npm install @plevands/epson-thermal-printer
45
+ ```
46
+
47
+ > **Note:** The library includes the Epson ePOS SDK v2.27.0. No additional downloads required.
48
+
49
+ ## Quick Start
50
+
51
+ ### Basic Usage (Hooks API)
52
+
53
+ ```typescript
54
+ import { useEpsonPrinter, usePrinterConfig } from '@plevands/epson-thermal-printer';
55
+
56
+ function MyPrintComponent() {
57
+ const { config } = usePrinterConfig();
58
+ const { print, isLoading, error } = useEpsonPrinter(config);
59
+
60
+ const handlePrint = async () => {
61
+ const canvas = document.querySelector('canvas') as HTMLCanvasElement;
62
+ const result = await print(canvas);
63
+
64
+ if (result.success) {
65
+ alert('Print successful!');
66
+ } else {
67
+ alert(`Print failed: ${result.message}`);
68
+ }
69
+ };
70
+
71
+ return (
72
+ <div>
73
+ <button onClick={handlePrint} disabled={isLoading}>
74
+ {isLoading ? 'Printing...' : 'Print'}
75
+ </button>
76
+ {error && <p>Error: {error}</p>}
77
+ </div>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ### Service API (No React)
83
+
84
+ ```typescript
85
+ import { EposPrintService } from '@plevands/epson-thermal-printer';
86
+
87
+ const service = new EposPrintService({
88
+ printerIP: '192.168.1.100',
89
+ printerPort: 80,
90
+ deviceId: 'local_printer',
91
+ });
92
+
93
+ // SDK loads automatically on first print
94
+ const result = await service.printCanvas(canvas);
95
+ ```
96
+
97
+ ### With PDF Processing
98
+
99
+ ```typescript
100
+ import {
101
+ useEpsonPrinter,
102
+ usePdfProcessor,
103
+ usePrinterConfig
104
+ } from '@plevands/epson-thermal-printer';
105
+
106
+ function PdfPrinter() {
107
+ const { config } = usePrinterConfig();
108
+ const { processFile } = usePdfProcessor({
109
+ enabled: true,
110
+ trimMargins: { top: 10, bottom: 10, left: 5, right: 5 },
111
+ targetWidth: 576, // 80mm paper
112
+ monochromeThreshold: 160,
113
+ });
114
+ const { printPages } = useEpsonPrinter(config);
115
+
116
+ const handlePrint = async (file: File) => {
117
+ // Process PDF with margin trimming and scaling
118
+ const pages = await processFile(file);
119
+
120
+ // Print all processed pages
121
+ const result = await printPages(
122
+ pages.map(p => p.canvas),
123
+ { pageSelection: 'all' }
124
+ );
125
+ };
126
+
127
+ return <div>{/* Your UI */}</div>;
128
+ }
129
+ ```
130
+
131
+ ### Using Pre-built Components
132
+
133
+ ```typescript
134
+ import {
135
+ PdfUploader,
136
+ PdfPreview,
137
+ PrinterConfig,
138
+ PrintControls
139
+ } from '@plevands/epson-thermal-printer/components';
140
+
141
+ function App() {
142
+ const [file, setFile] = useState<File | null>(null);
143
+ const [pages, setPages] = useState([]);
144
+
145
+ return (
146
+ <div>
147
+ <PrinterConfig onConfigChange={(config) => console.log(config)} />
148
+ <PdfUploader onFileSelect={setFile} />
149
+ <PdfPreview
150
+ file={file}
151
+ onPagesLoaded={setPages}
152
+ paperWidth={576}
153
+ pdfProcessing={{ enabled: true }}
154
+ />
155
+ <PrintControls pages={pages} />
156
+ </div>
157
+ );
158
+ }
159
+ ```
160
+
161
+ ## Configuration
162
+
163
+ ### PDF Processing Options
164
+
165
+ ```typescript
166
+ interface PdfProcessingConfig {
167
+ enabled: boolean; // Enable/disable processing
168
+ trimMargins?: {
169
+ top?: number; // Default: 8px
170
+ bottom?: number; // Default: 8px
171
+ left?: number; // Default: 8px
172
+ right?: number; // Default: 8px
173
+ };
174
+ targetWidth?: number; // Default: 576 (80mm paper)
175
+ scale?: number; // Render scale, default: 3
176
+ monochromeThreshold?: number; // 0-255, default: 160
177
+ }
178
+ ```
179
+
180
+ #### Paper Width Reference
181
+
182
+ | Paper Size | Width (pixels) | `targetWidth` value |
183
+ |------------|----------------|---------------------|
184
+ | 80mm | 576px | 576 (default) |
185
+ | 58mm | 384px | 384 |
186
+
187
+ ### Print Options
188
+
189
+ ```typescript
190
+ interface PrintOptions {
191
+ halftone?: 0 | 1 | 2; // 0=DITHER, 1=ERROR_DIFFUSION, 2=THRESHOLD
192
+ brightness?: number; // 0.1 to 10.0, default 1.0
193
+ mode?: 'mono' | 'gray16';
194
+ cut?: boolean;
195
+ align?: 'left' | 'center' | 'right';
196
+ }
197
+ ```
198
+
199
+ ### Printer Configuration
200
+
201
+ ```typescript
202
+ interface EpsonPrinterConfig {
203
+ printerIP: string; // Required
204
+ printerPort?: number; // Default: 80
205
+ deviceId?: string; // Default: 'local_printer'
206
+ timeout?: number; // Default: 60000ms
207
+ }
208
+ ```
209
+
210
+ ## API Reference
211
+
212
+ ### Hooks
213
+
214
+ #### `useEpsonPrinter(config, options?)`
215
+
216
+ Main hook for printer operations with automatic SDK loading.
217
+
218
+ **Returns:**
219
+ - `print(canvas)` - Print a single canvas
220
+ - `printPages(canvases, options?)` - Print multiple pages
221
+ - `testConnection()` - Test printer connection
222
+ - `isLoading` - Loading state
223
+ - `error` - Error message if any
224
+ - `sdkStatus` - SDK loading status
225
+
226
+ #### `usePrinterConfig()`
227
+
228
+ Manages printer configuration with localStorage persistence.
229
+
230
+ **Returns:**
231
+ - `config` - Current configuration
232
+ - `updateConfig(partial)` - Update configuration
233
+ - `resetConfig()` - Reset to defaults
234
+ - `isConfigured` - Boolean
235
+
236
+ #### `usePdfProcessor(config?)`
237
+
238
+ Process PDF files with configurable options.
239
+
240
+ **Returns:**
241
+ - `processFile(file)` - Process PDF file
242
+ - `isProcessing` - Processing state
243
+ - `error` - Error message if any
244
+
245
+ ### Services
246
+
247
+ #### `EposPrintService`
248
+
249
+ Core service class for printing operations.
250
+
251
+ ```typescript
252
+ const service = new EposPrintService(config, options);
253
+
254
+ // Methods
255
+ await service.printCanvas(canvas);
256
+ await service.printWithBuilder((builder) => {
257
+ builder.addTextAlign('center');
258
+ builder.addText('Hello World!\n');
259
+ builder.addFeedLine(3);
260
+ builder.addCut('feed');
261
+ });
262
+ await service.printPages(canvases, { header: 'Header Text' });
263
+ await service.testConnection(); // Prints a test receipt
264
+ await service.printTestPage(); // Prints a detailed test page
265
+ ```
266
+
267
+ #### SDK Loader Functions
268
+
269
+ ```typescript
270
+ import {
271
+ loadEpsonSDK,
272
+ isEpsonSDKLoaded,
273
+ initializeEpsonSDK,
274
+ getEpsonSDK,
275
+ checkEpsonSDKStatus,
276
+ } from '@plevands/epson-thermal-printer';
277
+
278
+ // Check if loaded
279
+ const loaded = isEpsonSDKLoaded();
280
+
281
+ // Check detailed SDK status
282
+ const status = checkEpsonSDKStatus();
283
+ // Returns: { loaded: boolean, loading: boolean, error: string | null, classes: string[] }
284
+
285
+ // Get SDK instance (after loading)
286
+ const sdk = getEpsonSDK();
287
+
288
+ // Manual initialization (optional)
289
+ const result = await initializeEpsonSDK();
290
+
291
+ // Lazy loading (automatic)
292
+ // SDK loads automatically on first print - no manual call needed!
293
+ ```
294
+
295
+ ### Logging Configuration
296
+
297
+ By default, only errors are logged to the console. You can enable debug logs or intercept all logs with a custom handler:
298
+
299
+ ```typescript
300
+ import { configureLogger } from '@plevands/epson-thermal-printer';
301
+
302
+ // Enable all logs (debug, warn, error) in console
303
+ configureLogger({ enabled: true });
304
+
305
+ // Intercept all logs with custom handler
306
+ configureLogger({
307
+ enabled: false, // Don't show debug/warn in console (errors always shown)
308
+ onLog: (entry) => {
309
+ // entry: { level: 'debug' | 'warn' | 'error', message: string, args?: unknown[] }
310
+ myLoggingService.log(entry.level, entry.message, entry.args);
311
+ },
312
+ });
313
+
314
+ // Combine both: show in console AND send to custom handler
315
+ configureLogger({
316
+ enabled: true,
317
+ onLog: (entry) => sendToAnalytics(entry),
318
+ });
319
+ ```
320
+
321
+ ## Running the Demo App
322
+
323
+ This repository includes a demo application to test the library:
324
+
325
+ ```bash
326
+ # Clone the repository
327
+ git clone https://github.com/plevands/epson-printer.git
328
+ cd epson-printer
329
+
330
+ # Install dependencies
331
+ npm install
332
+
333
+ # Start the development server
334
+ npm run dev
335
+
336
+ # Open in browser: http://localhost:5123
337
+ ```
338
+
339
+ The demo app provides:
340
+ - 🖨️ Printer configuration panel
341
+ - 📄 PDF file upload and preview
342
+ - 🎨 Real-time PDF processing visualization
343
+ - ⚙️ Print controls with customizable options
344
+
345
+ ## Development Workflow with npm link
346
+
347
+ ### In the Library
348
+
349
+ ```bash
350
+ # Make changes to the library
351
+ npm run build # Build once
352
+ # OR
353
+ npm run dev:lib # Watch mode - rebuilds on changes
354
+ ```
355
+
356
+ ### In Your Project
357
+
358
+ ```bash
359
+ # Link the library (once)
360
+ npm link @plevands/epson-thermal-printer
361
+
362
+ # Your project will use the local version
363
+ # Changes to the library reflect immediately after rebuild
364
+ ```
365
+
366
+ ### Unlinking
367
+
368
+ ```bash
369
+ # In your project
370
+ npm unlink @plevands/epson-thermal-printer
371
+
372
+ # In the library
373
+ npm unlink
374
+ ```
375
+
376
+ ## Network Requirements
377
+
378
+ ### CORS Configuration
379
+
380
+ The printer must allow CORS requests from your application domain. Configure your printer's web interface:
381
+
382
+ 1. Access printer at `http://[PRINTER_IP]`
383
+ 2. Navigate to Network > CORS settings
384
+ 3. Add your application origin (e.g., `http://localhost:5173`)
385
+
386
+ ### Firewall
387
+
388
+ Ensure port 80 (or custom port) is accessible on the printer's IP address.
389
+
390
+ ## Technical Notes
391
+
392
+ ### SDK Inheritance Pattern
393
+
394
+ The Epson ePOS SDK uses JavaScript prototypal inheritance where `ePOSPrint` extends `ePOSBuilder` via `ePOSPrint.prototype = new ePOSBuilder()`. This pattern has an important implication:
395
+
396
+ **Problem:** When calling builder methods directly on `ePOSPrint` instance (e.g., `printer.addText()`), the commands accumulate in a shared prototype `message` property, not an instance property. When `send()` is called internally, it creates a new empty `ePOSBuilder` instead of using the accumulated commands.
397
+
398
+ **Solution:** This library handles this by using separate `ePOSBuilder` instances:
399
+
400
+ ```typescript
401
+ // ✅ Correct pattern (used internally by this library)
402
+ const builder = new epson.ePOSBuilder();
403
+ builder.addText('Hello');
404
+ builder.addCut(builder.CUT_FEED);
405
+ const xml = builder.toString();
406
+
407
+ const printer = new epson.ePOSPrint(printerUrl);
408
+ printer.send(xml); // Pass XML explicitly
409
+ ```
410
+
411
+ If you're extending this library or using the raw SDK, always follow this pattern to avoid empty print requests.
412
+
413
+ ## Troubleshooting
414
+
415
+ ### SDK Not Loading
416
+
417
+ The SDK loads automatically on first print. If you see errors:
418
+
419
+ 1. Check console for loading errors
420
+ 2. Verify `public/epos-2.27.0.js` exists in your build
421
+ 3. Try manual initialization:
422
+ ```typescript
423
+ import { initializeEpsonSDK } from '@plevands/epson-thermal-printer';
424
+ await initializeEpsonSDK();
425
+ ```
426
+
427
+ ### Connection Failed
428
+
429
+ - Verify printer IP address is correct
430
+ - Check CORS configuration on printer
431
+ - Ensure printer is on same network
432
+ - Test connection:
433
+ ```typescript
434
+ const { testConnection } = useEpsonPrinter(config);
435
+ await testConnection();
436
+ ```
437
+
438
+ ### Print Quality Issues
439
+
440
+ Adjust print options:
441
+
442
+ ```typescript
443
+ const { print } = useEpsonPrinter(config, {
444
+ halftone: 1, // Try different values (0, 1, 2)
445
+ brightness: 1.2, // Increase for lighter prints
446
+ mode: 'mono', // Or 'gray16' for grayscale
447
+ });
448
+ ```
449
+
450
+ ### PDF Processing Issues
451
+
452
+ Fine-tune processing config:
453
+
454
+ ```typescript
455
+ const { processFile } = usePdfProcessor({
456
+ enabled: true,
457
+ trimMargins: { top: 0, bottom: 0, left: 0, right: 0 }, // Disable trimming
458
+ monochromeThreshold: 180, // Higher = more white
459
+ });
460
+ ```
461
+
462
+ ## Examples
463
+
464
+ See the included demo app in this repository for complete examples of all features.
465
+
466
+ ```bash
467
+ npm run dev # Start demo app
468
+ npm run build # Build library for production
469
+ npm run lint # Run ESLint
470
+ ```
471
+
472
+ ## Browser Support
473
+
474
+ | Browser | Supported |
475
+ |---------|-----------|
476
+ | Chrome | ✅ 90+ |
477
+ | Firefox | ✅ 88+ |
478
+ | Safari | ✅ 14+ |
479
+ | Edge | ✅ 90+ |
480
+
481
+ > **Note:** Requires modern browser with ES2020+ and Canvas API support.
482
+
483
+ ## License
484
+
485
+ MIT © [Colegio Plevand's](https://github.com/plevands)
486
+
487
+ ## Contributing
488
+
489
+ Contributions welcome! Please feel free to submit issues and pull requests.