@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.
@@ -0,0 +1,572 @@
1
+ import { a as checkEpsonSDKStatus, i as EposPrintService, m as error, p as debug, r as processPdfPage, t as DEFAULT_PDF_CONFIG } from "./pdf-processor-B7cA9poK.js";
2
+ import * as pdfjsLib from "pdfjs-dist";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ function PdfUploader({ onFileSelect: e, disabled: i }) {
6
+ let [a, o] = useState(!1), [s, c] = useState(null), l = useRef(null), d = useCallback((e) => {
7
+ e.preventDefault(), o(!0);
8
+ }, []), p = useCallback((e) => {
9
+ e.preventDefault(), o(!1);
10
+ }, []), m = useCallback((i) => {
11
+ i.preventDefault(), o(!1);
12
+ let a = i.dataTransfer.files;
13
+ if (a.length > 0) {
14
+ let i = a[0];
15
+ i.type === "application/pdf" ? (c(i), e(i)) : alert("Por favor selecciona un archivo PDF");
16
+ }
17
+ }, [e]), h = useCallback((i) => {
18
+ let a = i.target.files;
19
+ if (a && a.length > 0) {
20
+ let i = a[0];
21
+ c(i), e(i);
22
+ }
23
+ }, [e]);
24
+ return /* @__PURE__ */ jsxs("div", {
25
+ className: "pdf-uploader",
26
+ children: [/* @__PURE__ */ jsx("h3", { children: "📄 Subir Archivo PDF" }), /* @__PURE__ */ jsxs("div", {
27
+ className: `drop-zone ${a ? "dragging" : ""} ${i ? "disabled" : ""}`,
28
+ onDragOver: d,
29
+ onDragLeave: p,
30
+ onDrop: m,
31
+ onClick: i ? void 0 : () => {
32
+ l.current?.click();
33
+ },
34
+ children: [/* @__PURE__ */ jsx("input", {
35
+ ref: l,
36
+ type: "file",
37
+ accept: ".pdf,application/pdf",
38
+ onChange: h,
39
+ style: { display: "none" },
40
+ disabled: i
41
+ }), s ? /* @__PURE__ */ jsxs("div", {
42
+ className: "file-info",
43
+ children: [
44
+ /* @__PURE__ */ jsx("span", {
45
+ className: "file-icon",
46
+ children: "📄"
47
+ }),
48
+ /* @__PURE__ */ jsxs("div", {
49
+ className: "file-details",
50
+ children: [/* @__PURE__ */ jsx("span", {
51
+ className: "file-name",
52
+ children: s.name
53
+ }), /* @__PURE__ */ jsx("span", {
54
+ className: "file-size",
55
+ children: ((e) => e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`)(s.size)
56
+ })]
57
+ }),
58
+ /* @__PURE__ */ jsx("button", {
59
+ className: "btn-clear",
60
+ onClick: (e) => {
61
+ e.stopPropagation(), c(null), l.current && (l.current.value = "");
62
+ },
63
+ children: "✕"
64
+ })
65
+ ]
66
+ }) : /* @__PURE__ */ jsxs("div", {
67
+ className: "drop-message",
68
+ children: [
69
+ /* @__PURE__ */ jsx("span", {
70
+ className: "drop-icon",
71
+ children: "📥"
72
+ }),
73
+ /* @__PURE__ */ jsx("p", { children: "Arrastra un archivo PDF aquí" }),
74
+ /* @__PURE__ */ jsx("p", {
75
+ className: "drop-hint",
76
+ children: "o haz clic para seleccionar"
77
+ })
78
+ ]
79
+ })]
80
+ })]
81
+ });
82
+ }
83
+ var PDFJS_VERSION = "4.10.38";
84
+ typeof window < "u" && (pdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs`);
85
+ function PdfPreview({ file: e, onPagesLoaded: i, paperWidth: o = 576, pdfProcessing: u = DEFAULT_PDF_CONFIG }) {
86
+ let [f, m] = useState([]), [h, g] = useState(!1), [_, v] = useState(null), [y, b] = useState(0);
87
+ return useEffect(() => {
88
+ if (!e) {
89
+ m([]), b(0);
90
+ return;
91
+ }
92
+ (async () => {
93
+ g(!0), v(null);
94
+ try {
95
+ let a = await e.arrayBuffer(), c = await pdfjsLib.getDocument({ data: a }).promise, d = [], f = {
96
+ ...u,
97
+ targetWidth: o
98
+ };
99
+ for (let e = 1; e <= c.numPages; e++) {
100
+ let i = await processPdfPage(await c.getPage(e), f);
101
+ d.push(i);
102
+ }
103
+ m(d), b(0), i && i(d), g(!1);
104
+ } catch (e) {
105
+ error("Error loading PDF:", e), v(e instanceof Error ? e.message : "Error al cargar el PDF"), g(!1);
106
+ }
107
+ })();
108
+ }, [
109
+ e,
110
+ i,
111
+ o,
112
+ u
113
+ ]), e ? /* @__PURE__ */ jsxs("div", {
114
+ className: "pdf-preview",
115
+ children: [
116
+ /* @__PURE__ */ jsx("h3", { children: "👁️ Vista Previa" }),
117
+ h && /* @__PURE__ */ jsxs("div", {
118
+ className: "preview-loading",
119
+ children: [/* @__PURE__ */ jsx("div", { className: "spinner" }), /* @__PURE__ */ jsx("p", { children: "Cargando PDF..." })]
120
+ }),
121
+ _ && /* @__PURE__ */ jsx("div", {
122
+ className: "preview-error",
123
+ children: /* @__PURE__ */ jsxs("p", { children: ["❌ ", _] })
124
+ }),
125
+ !h && !_ && f.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
126
+ className: "preview-navigation",
127
+ children: [
128
+ /* @__PURE__ */ jsx("button", {
129
+ onClick: () => b(Math.max(0, y - 1)),
130
+ disabled: y === 0,
131
+ children: "◀ Anterior"
132
+ }),
133
+ /* @__PURE__ */ jsxs("span", { children: [
134
+ "Página ",
135
+ y + 1,
136
+ " de ",
137
+ f.length
138
+ ] }),
139
+ /* @__PURE__ */ jsx("button", {
140
+ onClick: () => b(Math.min(f.length - 1, y + 1)),
141
+ disabled: y === f.length - 1,
142
+ children: "Siguiente ▶"
143
+ })
144
+ ]
145
+ }), /* @__PURE__ */ jsxs("div", {
146
+ className: "preview-container",
147
+ children: [/* @__PURE__ */ jsx("img", {
148
+ src: f[y].base64,
149
+ alt: `Página ${y + 1}`,
150
+ className: "preview-image"
151
+ }), /* @__PURE__ */ jsxs("div", {
152
+ className: "preview-info",
153
+ children: [
154
+ f[y].width,
155
+ " x ",
156
+ f[y].height,
157
+ " px"
158
+ ]
159
+ })]
160
+ })] })
161
+ ]
162
+ }) : null;
163
+ }
164
+ var STORAGE_KEY = "epson-printer-config";
165
+ function getInitialConfig() {
166
+ try {
167
+ let e = localStorage.getItem(STORAGE_KEY);
168
+ if (e) {
169
+ let i = JSON.parse(e);
170
+ return {
171
+ printerIP: i.printerIP || "192.168.1.100",
172
+ printerPort: i.printerPort || 80,
173
+ deviceId: i.deviceId || "local_printer",
174
+ paperWidth: i.paperWidth || 576
175
+ };
176
+ }
177
+ } catch {}
178
+ return {
179
+ printerIP: "192.168.1.100",
180
+ printerPort: 80,
181
+ deviceId: "local_printer",
182
+ paperWidth: 576
183
+ };
184
+ }
185
+ function PrinterConfig({ onConfigChange: e }) {
186
+ let i = getInitialConfig(), [a, o] = useState(i.printerIP), [s, c] = useState(i.printerPort), [l, f] = useState(i.deviceId), [p, m] = useState(i.paperWidth), h = useCallback((i) => {
187
+ e(i);
188
+ }, [e]);
189
+ return useEffect(() => {
190
+ h(i);
191
+ }, []), /* @__PURE__ */ jsxs("div", {
192
+ className: "printer-config",
193
+ children: [
194
+ /* @__PURE__ */ jsx("h3", { children: "⚙️ Configuración de Impresora" }),
195
+ /* @__PURE__ */ jsxs("div", {
196
+ className: "config-form",
197
+ children: [
198
+ /* @__PURE__ */ jsxs("div", {
199
+ className: "form-group",
200
+ children: [/* @__PURE__ */ jsx("label", {
201
+ htmlFor: "printerIP",
202
+ children: "IP de la Impresora:"
203
+ }), /* @__PURE__ */ jsx("input", {
204
+ type: "text",
205
+ id: "printerIP",
206
+ value: a,
207
+ onChange: (e) => o(e.target.value),
208
+ placeholder: "192.168.1.100"
209
+ })]
210
+ }),
211
+ /* @__PURE__ */ jsxs("div", {
212
+ className: "form-group",
213
+ children: [/* @__PURE__ */ jsx("label", {
214
+ htmlFor: "printerPort",
215
+ children: "Puerto:"
216
+ }), /* @__PURE__ */ jsx("input", {
217
+ type: "number",
218
+ id: "printerPort",
219
+ value: s,
220
+ onChange: (e) => c(parseInt(e.target.value) || 80),
221
+ placeholder: "80"
222
+ })]
223
+ }),
224
+ /* @__PURE__ */ jsxs("div", {
225
+ className: "form-group",
226
+ children: [/* @__PURE__ */ jsx("label", {
227
+ htmlFor: "deviceId",
228
+ children: "Device ID:"
229
+ }), /* @__PURE__ */ jsx("input", {
230
+ type: "text",
231
+ id: "deviceId",
232
+ value: l,
233
+ onChange: (e) => f(e.target.value),
234
+ placeholder: "local_printer"
235
+ })]
236
+ }),
237
+ /* @__PURE__ */ jsxs("div", {
238
+ className: "form-group",
239
+ children: [/* @__PURE__ */ jsx("label", {
240
+ htmlFor: "paperWidth",
241
+ children: "Ancho de Papel:"
242
+ }), /* @__PURE__ */ jsxs("select", {
243
+ id: "paperWidth",
244
+ value: p,
245
+ onChange: (e) => m(parseInt(e.target.value)),
246
+ children: [/* @__PURE__ */ jsx("option", {
247
+ value: 576,
248
+ children: "80mm (576px)"
249
+ }), /* @__PURE__ */ jsx("option", {
250
+ value: 384,
251
+ children: "58mm (384px)"
252
+ })]
253
+ })]
254
+ }),
255
+ /* @__PURE__ */ jsx("button", {
256
+ onClick: () => {
257
+ let i = {
258
+ printerIP: a,
259
+ printerPort: s,
260
+ deviceId: l,
261
+ paperWidth: p
262
+ };
263
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(i)), e(i);
264
+ },
265
+ className: "btn-save",
266
+ children: "💾 Guardar Configuración"
267
+ })
268
+ ]
269
+ }),
270
+ /* @__PURE__ */ jsx("div", {
271
+ className: "config-help",
272
+ children: /* @__PURE__ */ jsxs("p", { children: [/* @__PURE__ */ jsx("strong", { children: "Nota:" }), " La IP debe ser la dirección de tu impresora Epson con ePOS habilitado. El puerto por defecto es 80. El Device ID suele ser \"local_printer\" o el nombre configurado en la impresora."] })
273
+ })
274
+ ]
275
+ });
276
+ }
277
+ function PrintControls({ printerConfig: a, pages: s }) {
278
+ let [c, l] = useState(!1), [u, f] = useState(!1), [m, h] = useState(null), [g, _] = useState(!0), [v, y] = useState([]), [b, x] = useState(!1), [S, C] = useState(""), [w, T] = useState(!1), [E, D] = useState(""), [O, k] = useState({
279
+ loaded: !1,
280
+ classes: []
281
+ }), [A, j] = useState(1), [M, N] = useState(1), [P, F] = useState("mono");
282
+ useEffect(() => {
283
+ let i = () => {
284
+ let i = checkEpsonSDKStatus();
285
+ k(i), debug("SDK Status:", i);
286
+ };
287
+ i();
288
+ let a = setTimeout(i, 1e3);
289
+ return () => clearTimeout(a);
290
+ }, []);
291
+ let I = () => ({
292
+ halftone: A,
293
+ brightness: M,
294
+ mode: P,
295
+ cut: !0,
296
+ align: "center"
297
+ }), L = async () => {
298
+ if (!a) {
299
+ h({
300
+ success: !1,
301
+ message: "Configura la impresora primero"
302
+ });
303
+ return;
304
+ }
305
+ f(!0), h(null);
306
+ try {
307
+ h(await new EposPrintService({
308
+ printerIP: a.printerIP,
309
+ printerPort: a.printerPort,
310
+ deviceId: a.deviceId
311
+ }, I()).testConnection());
312
+ } catch (e) {
313
+ h({
314
+ success: !1,
315
+ message: e instanceof Error ? e.message : "Error desconocido"
316
+ });
317
+ } finally {
318
+ f(!1);
319
+ }
320
+ }, R = async () => {
321
+ if (!a) {
322
+ h({
323
+ success: !1,
324
+ message: "Configura la impresora primero"
325
+ });
326
+ return;
327
+ }
328
+ if (s.length === 0) {
329
+ h({
330
+ success: !1,
331
+ message: "No hay páginas para imprimir"
332
+ });
333
+ return;
334
+ }
335
+ l(!0), h(null);
336
+ try {
337
+ let e = new EposPrintService({
338
+ printerIP: a.printerIP,
339
+ printerPort: a.printerPort,
340
+ deviceId: a.deviceId
341
+ }, I()), o = g ? s : v.map((e) => s[e]).filter(Boolean);
342
+ if (o.length === 0) {
343
+ h({
344
+ success: !1,
345
+ message: "No hay páginas seleccionadas"
346
+ }), l(!1);
347
+ return;
348
+ }
349
+ let c = o.map((e) => e.canvas);
350
+ h(await e.printPages(c, {
351
+ header: b && S ? S : void 0,
352
+ footer: w && E ? E : void 0,
353
+ pageSeparator: !0
354
+ }));
355
+ } catch (e) {
356
+ h({
357
+ success: !1,
358
+ message: e instanceof Error ? e.message : "Error desconocido"
359
+ });
360
+ } finally {
361
+ l(!1);
362
+ }
363
+ }, z = async () => {
364
+ if (!a) {
365
+ h({
366
+ success: !1,
367
+ message: "Configura la impresora primero"
368
+ });
369
+ return;
370
+ }
371
+ l(!0), h(null);
372
+ try {
373
+ h(await new EposPrintService({
374
+ printerIP: a.printerIP,
375
+ printerPort: a.printerPort,
376
+ deviceId: a.deviceId
377
+ }, I()).printTestPage());
378
+ } catch (e) {
379
+ h({
380
+ success: !1,
381
+ message: e instanceof Error ? e.message : "Error desconocido"
382
+ });
383
+ } finally {
384
+ l(!1);
385
+ }
386
+ }, B = (e) => {
387
+ y((i) => i.includes(e) ? i.filter((i) => i !== e) : [...i, e].sort((e, i) => e - i));
388
+ };
389
+ return /* @__PURE__ */ jsxs("div", {
390
+ className: "print-controls",
391
+ children: [
392
+ /* @__PURE__ */ jsx("h3", { children: "🖨️ Controles de Impresión" }),
393
+ /* @__PURE__ */ jsx("div", {
394
+ className: `sdk-status ${O.loaded ? "sdk-loaded" : "sdk-error"}`,
395
+ children: O.loaded ? /* @__PURE__ */ jsxs(Fragment, { children: [
396
+ "✅ Epson SDK cargado (",
397
+ O.classes.join(", "),
398
+ ")"
399
+ ] }) : /* @__PURE__ */ jsx(Fragment, { children: "❌ Epson SDK no cargado - Recarga la página" })
400
+ }),
401
+ /* @__PURE__ */ jsxs("div", {
402
+ className: "control-section",
403
+ children: [
404
+ /* @__PURE__ */ jsx("h4", { children: "Conexión" }),
405
+ /* @__PURE__ */ jsx("button", {
406
+ onClick: L,
407
+ disabled: u || !a || !O.loaded,
408
+ className: "btn-test",
409
+ children: u ? "⏳ Probando..." : "🔌 Probar Conexión"
410
+ }),
411
+ /* @__PURE__ */ jsx("button", {
412
+ onClick: z,
413
+ disabled: c || !a || !O.loaded,
414
+ className: "btn-test-print",
415
+ children: c ? "⏳ Imprimiendo..." : "📝 Imprimir Página de Prueba"
416
+ })
417
+ ]
418
+ }),
419
+ s.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
420
+ /* @__PURE__ */ jsxs("div", {
421
+ className: "control-section",
422
+ children: [
423
+ /* @__PURE__ */ jsx("h4", { children: "Calidad de Impresión (SDK Oficial)" }),
424
+ /* @__PURE__ */ jsxs("label", {
425
+ className: "select-label",
426
+ children: ["Algoritmo de Halftone:", /* @__PURE__ */ jsxs("select", {
427
+ value: A,
428
+ onChange: (e) => j(Number(e.target.value)),
429
+ className: "select-input",
430
+ children: [
431
+ /* @__PURE__ */ jsx("option", {
432
+ value: 0,
433
+ children: "Dither (rápido)"
434
+ }),
435
+ /* @__PURE__ */ jsx("option", {
436
+ value: 1,
437
+ children: "Error Diffusion (mejor calidad)"
438
+ }),
439
+ /* @__PURE__ */ jsx("option", {
440
+ value: 2,
441
+ children: "Threshold (alto contraste)"
442
+ })
443
+ ]
444
+ })]
445
+ }),
446
+ /* @__PURE__ */ jsxs("label", {
447
+ className: "select-label",
448
+ children: [
449
+ "Brillo (",
450
+ M.toFixed(1),
451
+ "):",
452
+ /* @__PURE__ */ jsx("input", {
453
+ type: "range",
454
+ min: "0.1",
455
+ max: "3.0",
456
+ step: "0.1",
457
+ value: M,
458
+ onChange: (e) => N(parseFloat(e.target.value)),
459
+ className: "range-input"
460
+ })
461
+ ]
462
+ }),
463
+ /* @__PURE__ */ jsxs("label", {
464
+ className: "select-label",
465
+ children: ["Modo:", /* @__PURE__ */ jsxs("select", {
466
+ value: P,
467
+ onChange: (e) => F(e.target.value),
468
+ className: "select-input",
469
+ children: [/* @__PURE__ */ jsx("option", {
470
+ value: "mono",
471
+ children: "Monocromático (1-bit)"
472
+ }), /* @__PURE__ */ jsx("option", {
473
+ value: "gray16",
474
+ children: "Escala de grises (16 niveles)"
475
+ })]
476
+ })]
477
+ })
478
+ ]
479
+ }),
480
+ /* @__PURE__ */ jsxs("div", {
481
+ className: "control-section",
482
+ children: [
483
+ /* @__PURE__ */ jsx("h4", { children: "Opciones de Impresión" }),
484
+ /* @__PURE__ */ jsxs("label", {
485
+ className: "checkbox-label",
486
+ children: [
487
+ /* @__PURE__ */ jsx("input", {
488
+ type: "checkbox",
489
+ checked: g,
490
+ onChange: (e) => _(e.target.checked)
491
+ }),
492
+ "Imprimir todas las páginas (",
493
+ s.length,
494
+ ")"
495
+ ]
496
+ }),
497
+ !g && /* @__PURE__ */ jsxs("div", {
498
+ className: "page-selection",
499
+ children: [/* @__PURE__ */ jsx("p", { children: "Selecciona páginas:" }), /* @__PURE__ */ jsx("div", {
500
+ className: "page-buttons",
501
+ children: s.map((e, i) => /* @__PURE__ */ jsx("button", {
502
+ className: `page-btn ${v.includes(i) ? "selected" : ""}`,
503
+ onClick: () => B(i),
504
+ children: i + 1
505
+ }, i))
506
+ })]
507
+ })
508
+ ]
509
+ }),
510
+ /* @__PURE__ */ jsxs("div", {
511
+ className: "control-section",
512
+ children: [
513
+ /* @__PURE__ */ jsx("h4", { children: "Encabezado y Pie" }),
514
+ /* @__PURE__ */ jsxs("label", {
515
+ className: "checkbox-label",
516
+ children: [/* @__PURE__ */ jsx("input", {
517
+ type: "checkbox",
518
+ checked: b,
519
+ onChange: (e) => x(e.target.checked)
520
+ }), "Agregar encabezado"]
521
+ }),
522
+ b && /* @__PURE__ */ jsx("input", {
523
+ type: "text",
524
+ value: S,
525
+ onChange: (e) => C(e.target.value),
526
+ placeholder: "Texto del encabezado",
527
+ className: "text-input"
528
+ }),
529
+ /* @__PURE__ */ jsxs("label", {
530
+ className: "checkbox-label",
531
+ children: [/* @__PURE__ */ jsx("input", {
532
+ type: "checkbox",
533
+ checked: w,
534
+ onChange: (e) => T(e.target.checked)
535
+ }), "Agregar pie de página"]
536
+ }),
537
+ w && /* @__PURE__ */ jsx("input", {
538
+ type: "text",
539
+ value: E,
540
+ onChange: (e) => D(e.target.value),
541
+ placeholder: "Texto del pie de página",
542
+ className: "text-input"
543
+ })
544
+ ]
545
+ }),
546
+ /* @__PURE__ */ jsx("div", {
547
+ className: "control-section",
548
+ children: /* @__PURE__ */ jsx("button", {
549
+ onClick: R,
550
+ disabled: c || !a,
551
+ className: "btn-print",
552
+ children: c ? "⏳ Imprimiendo..." : "🖨️ Imprimir PDF"
553
+ })
554
+ })
555
+ ] }),
556
+ m && /* @__PURE__ */ jsxs("div", {
557
+ className: `print-result ${m.success ? "success" : "error"}`,
558
+ children: [/* @__PURE__ */ jsxs("p", { children: [
559
+ m.success ? "✅" : "❌",
560
+ " ",
561
+ m.message
562
+ ] }), m.code && /* @__PURE__ */ jsxs("p", {
563
+ className: "result-code",
564
+ children: ["Código: ", m.code]
565
+ })]
566
+ })
567
+ ]
568
+ });
569
+ }
570
+ export { PdfPreview, PdfUploader, PrintControls, PrinterConfig };
571
+
572
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","names":["loadedPages: ProcessedPage[]","processingConfig: PdfProcessingConfig"],"sources":["../src/components/PdfUploader.tsx","../src/components/PdfPreview.tsx","../src/components/PrinterConfig.tsx","../src/components/PrintControls.tsx"],"sourcesContent":["import { useState, useCallback, useRef } from 'react';\n\ninterface PdfUploaderProps {\n onFileSelect: (file: File) => void;\n disabled?: boolean;\n}\n\nexport function PdfUploader({ onFileSelect, disabled }: PdfUploaderProps) {\n const [isDragging, setIsDragging] = useState(false);\n const [selectedFile, setSelectedFile] = useState<File | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n\n const files = e.dataTransfer.files;\n if (files.length > 0) {\n const file = files[0];\n if (file.type === 'application/pdf') {\n setSelectedFile(file);\n onFileSelect(file);\n } else {\n alert('Por favor selecciona un archivo PDF');\n }\n }\n }, [onFileSelect]);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (files && files.length > 0) {\n const file = files[0];\n setSelectedFile(file);\n onFileSelect(file);\n }\n }, [onFileSelect]);\n\n const handleClick = () => {\n fileInputRef.current?.click();\n };\n\n const formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n };\n\n return (\n <div className=\"pdf-uploader\">\n <h3>📄 Subir Archivo PDF</h3>\n \n <div\n className={`drop-zone ${isDragging ? 'dragging' : ''} ${disabled ? 'disabled' : ''}`}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={disabled ? undefined : handleClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".pdf,application/pdf\"\n onChange={handleFileChange}\n style={{ display: 'none' }}\n disabled={disabled}\n />\n \n {selectedFile ? (\n <div className=\"file-info\">\n <span className=\"file-icon\">📄</span>\n <div className=\"file-details\">\n <span className=\"file-name\">{selectedFile.name}</span>\n <span className=\"file-size\">{formatFileSize(selectedFile.size)}</span>\n </div>\n <button \n className=\"btn-clear\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedFile(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }}\n >\n ✕\n </button>\n </div>\n ) : (\n <div className=\"drop-message\">\n <span className=\"drop-icon\">📥</span>\n <p>Arrastra un archivo PDF aquí</p>\n <p className=\"drop-hint\">o haz clic para seleccionar</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport { processPdfPage, DEFAULT_PDF_CONFIG } from '../lib/pdf-processor';\nimport { error as logError } from '../lib/logger';\nimport type { PdfProcessingConfig, ProcessedPage } from '../types';\n\n// Configure PDF.js worker from CDN to avoid bundling\nconst PDFJS_VERSION = '4.10.38';\nif (typeof window !== 'undefined') {\n pdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs`;\n}\n\ninterface PdfPreviewProps {\n file: File | null;\n onPagesLoaded?: (pages: ProcessedPage[]) => void;\n paperWidth?: 576 | 384; // 576 for 80mm, 384 for 58mm\n pdfProcessing?: PdfProcessingConfig; // Configurable PDF processing\n}\n\nexport function PdfPreview({\n file, \n onPagesLoaded, \n paperWidth = 576,\n pdfProcessing = DEFAULT_PDF_CONFIG,\n}: PdfPreviewProps) {\n const [pages, setPages] = useState<ProcessedPage[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [currentPage, setCurrentPage] = useState(0);\n\n useEffect(() => {\n if (!file) {\n setPages([]);\n setCurrentPage(0);\n return;\n }\n\n const loadPdf = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const arrayBuffer = await file.arrayBuffer();\n const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;\n\n const loadedPages: ProcessedPage[] = [];\n\n // Merge config with paperWidth\n const processingConfig: PdfProcessingConfig = {\n ...pdfProcessing,\n targetWidth: paperWidth,\n };\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n \n // Use the centralized processor\n const processedPage = await processPdfPage(page, processingConfig);\n loadedPages.push(processedPage);\n }\n\n setPages(loadedPages);\n setCurrentPage(0);\n\n if (onPagesLoaded) {\n onPagesLoaded(loadedPages);\n }\n\n setLoading(false);\n } catch (err) {\n logError('Error loading PDF:', err);\n setError(err instanceof Error ? err.message : 'Error al cargar el PDF');\n setLoading(false);\n }\n };\n\n loadPdf();\n }, [file, onPagesLoaded, paperWidth, pdfProcessing]);\n\n if (!file) {\n return null;\n }\n\n return (\n <div className=\"pdf-preview\">\n <h3>👁️ Vista Previa</h3>\n\n {loading && (\n <div className=\"preview-loading\">\n <div className=\"spinner\"></div>\n <p>Cargando PDF...</p>\n </div>\n )}\n\n {error && (\n <div className=\"preview-error\">\n <p>❌ {error}</p>\n </div>\n )}\n\n {!loading && !error && pages.length > 0 && (\n <>\n <div className=\"preview-navigation\">\n <button\n onClick={() => setCurrentPage(Math.max(0, currentPage - 1))}\n disabled={currentPage === 0}\n >\n ◀ Anterior\n </button>\n <span>\n Página {currentPage + 1} de {pages.length}\n </span>\n <button\n onClick={() => setCurrentPage(Math.min(pages.length - 1, currentPage + 1))}\n disabled={currentPage === pages.length - 1}\n >\n Siguiente ▶\n </button>\n </div>\n\n <div className=\"preview-container\">\n <img\n src={pages[currentPage].base64}\n alt={`Página ${currentPage + 1}`}\n className=\"preview-image\"\n />\n <div className=\"preview-info\">\n {pages[currentPage].width} x {pages[currentPage].height} px\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\n\ninterface PrinterConfigProps {\n onConfigChange: (config: { printerIP: string; printerPort: number; deviceId: string; paperWidth: number }) => void;\n}\n\nconst STORAGE_KEY = 'epson-printer-config';\n\n// Get initial config from localStorage\nfunction getInitialConfig() {\n try {\n const saved = localStorage.getItem(STORAGE_KEY);\n if (saved) {\n const config = JSON.parse(saved);\n return {\n printerIP: config.printerIP || '192.168.1.100',\n printerPort: config.printerPort || 80,\n deviceId: config.deviceId || 'local_printer',\n paperWidth: config.paperWidth || 576,\n };\n }\n } catch {\n // Ignore parse errors\n }\n return {\n printerIP: '192.168.1.100',\n printerPort: 80,\n deviceId: 'local_printer',\n paperWidth: 576,\n };\n}\n\nexport function PrinterConfig({ onConfigChange }: PrinterConfigProps) {\n const initialConfig = getInitialConfig();\n const [printerIP, setPrinterIP] = useState(initialConfig.printerIP);\n const [printerPort, setPrinterPort] = useState(initialConfig.printerPort);\n const [deviceId, setDeviceId] = useState(initialConfig.deviceId);\n const [paperWidth, setPaperWidth] = useState(initialConfig.paperWidth);\n\n const notifyChange = useCallback((config: { printerIP: string; printerPort: number; deviceId: string; paperWidth: number }) => {\n onConfigChange(config);\n }, [onConfigChange]);\n\n // Notify parent of initial config on mount\n useEffect(() => {\n notifyChange(initialConfig);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleSave = () => {\n const config = { printerIP, printerPort, deviceId, paperWidth };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(config));\n onConfigChange(config);\n };\n\n return (\n <div className=\"printer-config\">\n <h3>⚙️ Configuración de Impresora</h3>\n \n <div className=\"config-form\">\n <div className=\"form-group\">\n <label htmlFor=\"printerIP\">IP de la Impresora:</label>\n <input\n type=\"text\"\n id=\"printerIP\"\n value={printerIP}\n onChange={(e) => setPrinterIP(e.target.value)}\n placeholder=\"192.168.1.100\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"printerPort\">Puerto:</label>\n <input\n type=\"number\"\n id=\"printerPort\"\n value={printerPort}\n onChange={(e) => setPrinterPort(parseInt(e.target.value) || 80)}\n placeholder=\"80\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"deviceId\">Device ID:</label>\n <input\n type=\"text\"\n id=\"deviceId\"\n value={deviceId}\n onChange={(e) => setDeviceId(e.target.value)}\n placeholder=\"local_printer\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"paperWidth\">Ancho de Papel:</label>\n <select\n id=\"paperWidth\"\n value={paperWidth}\n onChange={(e) => setPaperWidth(parseInt(e.target.value))}\n >\n <option value={576}>80mm (576px)</option>\n <option value={384}>58mm (384px)</option>\n </select>\n </div>\n\n <button onClick={handleSave} className=\"btn-save\">\n 💾 Guardar Configuración\n </button>\n </div>\n\n <div className=\"config-help\">\n <p>\n <strong>Nota:</strong> La IP debe ser la dirección de tu impresora Epson con ePOS habilitado.\n El puerto por defecto es 80. El Device ID suele ser \"local_printer\" o el nombre configurado en la impresora.\n </p>\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { EposPrintService, checkEpsonSDKStatus } from '../lib/epos-print';\nimport { debug } from '../lib/logger';\nimport type { PrintResult, PrintOptions } from '../lib/epos-print';\n\ninterface PrintControlsProps {\n printerConfig: { printerIP: string; printerPort: number; deviceId: string } | null;\n pages: { base64: string; width: number; height: number; rasterBase64: string; canvas: HTMLCanvasElement }[];\n}\n\nexport function PrintControls({ printerConfig, pages }: PrintControlsProps) {\n const [printing, setPrinting] = useState(false);\n const [testingConnection, setTestingConnection] = useState(false);\n const [result, setResult] = useState<PrintResult | null>(null);\n const [printAllPages, setPrintAllPages] = useState(true);\n const [selectedPages, setSelectedPages] = useState<number[]>([]);\n const [addHeader, setAddHeader] = useState(false);\n const [headerText, setHeaderText] = useState('');\n const [addFooter, setAddFooter] = useState(false);\n const [footerText, setFooterText] = useState('');\n const [sdkStatus, setSdkStatus] = useState<{ loaded: boolean; classes: string[] }>({ loaded: false, classes: [] });\n \n // SDK print options\n const [halftone, setHalftone] = useState<0 | 1 | 2>(1); // 1 = ERROR_DIFFUSION (best quality)\n const [brightness, setBrightness] = useState(1.0);\n const [printMode, setPrintMode] = useState<'mono' | 'gray16'>('mono');\n\n // Check SDK status on mount\n useEffect(() => {\n const checkStatus = () => {\n const status = checkEpsonSDKStatus();\n setSdkStatus(status);\n debug('SDK Status:', status);\n };\n \n // Check immediately\n checkStatus();\n \n // Check again after a short delay (in case SDK loads async)\n const timer = setTimeout(checkStatus, 1000);\n return () => clearTimeout(timer);\n }, []);\n\n const getPrintOptions = (): PrintOptions => ({\n halftone,\n brightness,\n mode: printMode,\n cut: true,\n align: 'center',\n });\n\n const handleTestConnection = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n setTestingConnection(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const testResult = await service.testConnection();\n setResult(testResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setTestingConnection(false);\n }\n };\n\n const handlePrint = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n if (pages.length === 0) {\n setResult({ success: false, message: 'No hay páginas para imprimir' });\n return;\n }\n\n setPrinting(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const pagesToPrint = printAllPages\n ? pages\n : selectedPages.map((i) => pages[i]).filter(Boolean);\n\n if (pagesToPrint.length === 0) {\n setResult({ success: false, message: 'No hay páginas seleccionadas' });\n setPrinting(false);\n return;\n }\n\n // Use the official SDK's printPages method with canvas elements\n const canvases = pagesToPrint.map(p => p.canvas);\n const printResult = await service.printPages(canvases, {\n header: addHeader && headerText ? headerText : undefined,\n footer: addFooter && footerText ? footerText : undefined,\n pageSeparator: true,\n });\n\n setResult(printResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setPrinting(false);\n }\n };\n\n const handlePrintTestPage = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n setPrinting(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const printResult = await service.printTestPage();\n setResult(printResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setPrinting(false);\n }\n };\n\n const togglePageSelection = (pageIndex: number) => {\n setSelectedPages((prev) =>\n prev.includes(pageIndex)\n ? prev.filter((i) => i !== pageIndex)\n : [...prev, pageIndex].sort((a, b) => a - b)\n );\n };\n\n return (\n <div className=\"print-controls\">\n <h3>🖨️ Controles de Impresión</h3>\n\n {/* SDK Status */}\n <div className={`sdk-status ${sdkStatus.loaded ? 'sdk-loaded' : 'sdk-error'}`}>\n {sdkStatus.loaded ? (\n <>✅ Epson SDK cargado ({sdkStatus.classes.join(', ')})</>\n ) : (\n <>❌ Epson SDK no cargado - Recarga la página</>\n )}\n </div>\n\n <div className=\"control-section\">\n <h4>Conexión</h4>\n <button\n onClick={handleTestConnection}\n disabled={testingConnection || !printerConfig || !sdkStatus.loaded}\n className=\"btn-test\"\n >\n {testingConnection ? '⏳ Probando...' : '🔌 Probar Conexión'}\n </button>\n <button\n onClick={handlePrintTestPage}\n disabled={printing || !printerConfig || !sdkStatus.loaded}\n className=\"btn-test-print\"\n >\n {printing ? '⏳ Imprimiendo...' : '📝 Imprimir Página de Prueba'}\n </button>\n </div>\n\n {pages.length > 0 && (\n <>\n <div className=\"control-section\">\n <h4>Calidad de Impresión (SDK Oficial)</h4>\n \n <label className=\"select-label\">\n Algoritmo de Halftone:\n <select \n value={halftone} \n onChange={(e) => setHalftone(Number(e.target.value) as 0 | 1 | 2)}\n className=\"select-input\"\n >\n <option value={0}>Dither (rápido)</option>\n <option value={1}>Error Diffusion (mejor calidad)</option>\n <option value={2}>Threshold (alto contraste)</option>\n </select>\n </label>\n\n <label className=\"select-label\">\n Brillo ({brightness.toFixed(1)}):\n <input\n type=\"range\"\n min=\"0.1\"\n max=\"3.0\"\n step=\"0.1\"\n value={brightness}\n onChange={(e) => setBrightness(parseFloat(e.target.value))}\n className=\"range-input\"\n />\n </label>\n\n <label className=\"select-label\">\n Modo:\n <select \n value={printMode} \n onChange={(e) => setPrintMode(e.target.value as 'mono' | 'gray16')}\n className=\"select-input\"\n >\n <option value=\"mono\">Monocromático (1-bit)</option>\n <option value=\"gray16\">Escala de grises (16 niveles)</option>\n </select>\n </label>\n </div>\n\n <div className=\"control-section\">\n <h4>Opciones de Impresión</h4>\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={printAllPages}\n onChange={(e) => setPrintAllPages(e.target.checked)}\n />\n Imprimir todas las páginas ({pages.length})\n </label>\n\n {!printAllPages && (\n <div className=\"page-selection\">\n <p>Selecciona páginas:</p>\n <div className=\"page-buttons\">\n {pages.map((_, index) => (\n <button\n key={index}\n className={`page-btn ${selectedPages.includes(index) ? 'selected' : ''}`}\n onClick={() => togglePageSelection(index)}\n >\n {index + 1}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n\n <div className=\"control-section\">\n <h4>Encabezado y Pie</h4>\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={addHeader}\n onChange={(e) => setAddHeader(e.target.checked)}\n />\n Agregar encabezado\n </label>\n {addHeader && (\n <input\n type=\"text\"\n value={headerText}\n onChange={(e) => setHeaderText(e.target.value)}\n placeholder=\"Texto del encabezado\"\n className=\"text-input\"\n />\n )}\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={addFooter}\n onChange={(e) => setAddFooter(e.target.checked)}\n />\n Agregar pie de página\n </label>\n {addFooter && (\n <input\n type=\"text\"\n value={footerText}\n onChange={(e) => setFooterText(e.target.value)}\n placeholder=\"Texto del pie de página\"\n className=\"text-input\"\n />\n )}\n </div>\n\n <div className=\"control-section\">\n <button\n onClick={handlePrint}\n disabled={printing || !printerConfig}\n className=\"btn-print\"\n >\n {printing ? '⏳ Imprimiendo...' : '🖨️ Imprimir PDF'}\n </button>\n </div>\n </>\n )}\n\n {result && (\n <div className={`print-result ${result.success ? 'success' : 'error'}`}>\n <p>\n {result.success ? '✅' : '❌'} {result.message}\n </p>\n {result.code && <p className=\"result-code\">Código: {result.code}</p>}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Hooks exports for @plevands/epson-thermal-printer
3
+ */
4
+ export { useEpsonPrinter } from './useEpsonPrinter';
5
+ export { usePrinterConfig } from './usePrinterConfig';
6
+ export { usePdfProcessor } from './usePdfProcessor';
@@ -0,0 +1,2 @@
1
+ import { EpsonPrinterConfig, PrintOptions, UseEpsonPrinterReturn } from '../types';
2
+ export declare function useEpsonPrinter(config: EpsonPrinterConfig, options?: PrintOptions): UseEpsonPrinterReturn;
@@ -0,0 +1,2 @@
1
+ import { PdfProcessingConfig, UsePdfProcessorReturn } from '../types';
2
+ export declare function usePdfProcessor(config?: PdfProcessingConfig): UsePdfProcessorReturn;
@@ -0,0 +1,2 @@
1
+ import { UsePrinterConfigReturn } from '../types';
2
+ export declare function usePrinterConfig(): UsePrinterConfigReturn;
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ const e=require(`./pdf-processor-DwUY-8_K.cjs`);let t=require(`react`);function n(n,r){let[i,a]=(0,t.useState)(!1),[o,s]=(0,t.useState)(null),[c,l]=(0,t.useState)({loaded:!1,loading:!1,error:null,classes:[]});return(0,t.useEffect)(()=>{let t=null,n=()=>{let n=e.a();l(n),n.loaded&&t!==null&&(clearInterval(t),t=null)},r=e.a();return l(r),r.loaded||(t=setInterval(n,1e3)),()=>{t!==null&&clearInterval(t)}},[]),{print:(0,t.useCallback)(async t=>{a(!0),s(null);try{let i=await new e.i(n,r).printCanvas(t);return i.success||s(i.message||`Print failed`),i}catch(e){let t=e instanceof Error?e.message:`Unknown error`;return s(t),{success:!1,code:`ERROR`,message:t}}finally{a(!1)}},[n,r]),printPages:(0,t.useCallback)(async(t,i)=>{a(!0),s(null);try{let a=new e.i(n,r),o=t;i?.pageSelection&&i.pageSelection!==`all`&&(o=i.pageSelection.map(e=>t[e-1]).filter(Boolean));let c=await a.printPages(o,{header:i?.headerText,footer:i?.footerText});return c.success||s(c.message||`Print failed`),c}catch(e){let t=e instanceof Error?e.message:`Unknown error`;return s(t),{success:!1,code:`ERROR`,message:t}}finally{a(!1)}},[n,r]),testConnection:(0,t.useCallback)(async()=>{a(!0),s(null);try{let t=await new e.i(n,r).testConnection();return t.success||s(t.message||`Connection test failed`),t}catch(e){let t=e instanceof Error?e.message:`Unknown error`;return s(t),{success:!1,code:`ERROR`,message:t}}finally{a(!1)}},[n,r]),isLoading:i,error:o,sdkStatus:c}}var r=`epson-printer-config`,i={printerIP:`192.168.1.100`,printerPort:80,deviceId:`local_printer`,timeout:6e4};function a(){let[n,a]=(0,t.useState)(()=>{try{let e=localStorage.getItem(r);if(e)return{...i,...JSON.parse(e)}}catch(t){e.m(`Failed to load printer config from localStorage:`,t)}return i});return(0,t.useEffect)(()=>{try{localStorage.setItem(r,JSON.stringify(n))}catch(t){e.m(`Failed to save printer config to localStorage:`,t)}},[n]),{config:n,updateConfig:(0,t.useCallback)(e=>{a(t=>({...t,...e}))},[]),resetConfig:(0,t.useCallback)(()=>{a(i);try{localStorage.removeItem(r)}catch(t){e.m(`Failed to remove printer config from localStorage:`,t)}},[]),isConfigured:!!(n.printerIP&&n.printerIP.trim()!==``&&n.printerIP!==`0.0.0.0`)}}function o(n){let[r,i]=(0,t.useState)(!1),[a,o]=(0,t.useState)(null);return{processFile:(0,t.useCallback)(async t=>{i(!0),o(null);try{return await e.n(t,n)}catch(e){throw o(e instanceof Error?e.message:`Failed to process PDF`),e}finally{i(!1)}},[n]),isProcessing:r,error:a}}exports.DEFAULT_PDF_CONFIG=e.t,exports.EposPrintService=e.i,exports.checkEpsonSDKStatus=e.a,exports.configureLogger=e.f,exports.getEpsonSDK=e.o,exports.getLoaderState=e.s,exports.getLoggerConfig=e.h,exports.initializeEpsonSDK=e.c,exports.isEpsonSDKLoaded=e.l,exports.loadEpsonSDK=e.u,exports.processPdfFile=e.n,exports.processPdfPage=e.r,exports.resetLoaderState=e.d,exports.useEpsonPrinter=n,exports.usePdfProcessor=o,exports.usePrinterConfig=a;
2
+ //# sourceMappingURL=index.cjs.map