@delicity/capacitor-thermal-printer 7.0.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.
Files changed (100) hide show
  1. package/DelicityThermalPrinter.podspec +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +649 -0
  4. package/android/build.gradle +122 -0
  5. package/android/src/main/AndroidManifest.xml +38 -0
  6. package/android/src/main/java/com/delicity/thermalprinter/Logger.kt +50 -0
  7. package/android/src/main/java/com/delicity/thermalprinter/ThermalPrinterEngine.kt +528 -0
  8. package/android/src/main/java/com/delicity/thermalprinter/ThermalPrinterPlugin.kt +334 -0
  9. package/android/src/main/java/com/delicity/thermalprinter/adapters/BleAdapter.kt +125 -0
  10. package/android/src/main/java/com/delicity/thermalprinter/adapters/BrotherAdapter.kt +206 -0
  11. package/android/src/main/java/com/delicity/thermalprinter/adapters/EpsonAdapter.kt +384 -0
  12. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosAdapter.kt +160 -0
  13. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosCommands.kt +42 -0
  14. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosTextEncoder.kt +138 -0
  15. package/android/src/main/java/com/delicity/thermalprinter/adapters/PrinterAdapter.kt +95 -0
  16. package/android/src/main/java/com/delicity/thermalprinter/adapters/RawTcpAdapter.kt +96 -0
  17. package/android/src/main/java/com/delicity/thermalprinter/adapters/SdkContract.kt +158 -0
  18. package/android/src/main/java/com/delicity/thermalprinter/adapters/SdkReflect.kt +104 -0
  19. package/android/src/main/java/com/delicity/thermalprinter/adapters/StarAdapter.kt +322 -0
  20. package/android/src/main/java/com/delicity/thermalprinter/adapters/UsbAdapter.kt +248 -0
  21. package/android/src/main/java/com/delicity/thermalprinter/adapters/ZebraAdapter.kt +207 -0
  22. package/android/src/main/java/com/delicity/thermalprinter/discovery/AdapterPriority.kt +39 -0
  23. package/android/src/main/java/com/delicity/thermalprinter/discovery/BleScanner.kt +70 -0
  24. package/android/src/main/java/com/delicity/thermalprinter/discovery/BluetoothClassicScanner.kt +112 -0
  25. package/android/src/main/java/com/delicity/thermalprinter/discovery/DiscoveryManager.kt +136 -0
  26. package/android/src/main/java/com/delicity/thermalprinter/discovery/TcpScanner.kt +96 -0
  27. package/android/src/main/java/com/delicity/thermalprinter/image/ImageCache.kt +88 -0
  28. package/android/src/main/java/com/delicity/thermalprinter/image/ImageProcessor.kt +220 -0
  29. package/android/src/main/java/com/delicity/thermalprinter/image/TextRasterizer.kt +99 -0
  30. package/android/src/main/java/com/delicity/thermalprinter/model/Models.kt +206 -0
  31. package/android/src/main/java/com/delicity/thermalprinter/model/PrintItem.kt +100 -0
  32. package/android/src/main/java/com/delicity/thermalprinter/store/PrinterStore.kt +71 -0
  33. package/android/src/main/java/com/delicity/thermalprinter/transport/BleGattClient.kt +201 -0
  34. package/android/src/main/java/com/delicity/thermalprinter/transport/BluetoothSppTransport.kt +110 -0
  35. package/android/src/main/java/com/delicity/thermalprinter/transport/ByteTransport.kt +18 -0
  36. package/android/src/main/java/com/delicity/thermalprinter/transport/TcpTransport.kt +83 -0
  37. package/dist/esm/adapters/dedup.d.ts +26 -0
  38. package/dist/esm/adapters/dedup.js +66 -0
  39. package/dist/esm/adapters/dedup.js.map +1 -0
  40. package/dist/esm/adapters/priority.d.ts +29 -0
  41. package/dist/esm/adapters/priority.js +55 -0
  42. package/dist/esm/adapters/priority.js.map +1 -0
  43. package/dist/esm/core/enums.d.ts +61 -0
  44. package/dist/esm/core/enums.js +25 -0
  45. package/dist/esm/core/enums.js.map +1 -0
  46. package/dist/esm/core/errors.d.ts +16 -0
  47. package/dist/esm/core/errors.js +53 -0
  48. package/dist/esm/core/errors.js.map +1 -0
  49. package/dist/esm/core/escpos-text.d.ts +33 -0
  50. package/dist/esm/core/escpos-text.js +239 -0
  51. package/dist/esm/core/escpos-text.js.map +1 -0
  52. package/dist/esm/core/imaging.d.ts +91 -0
  53. package/dist/esm/core/imaging.js +184 -0
  54. package/dist/esm/core/imaging.js.map +1 -0
  55. package/dist/esm/core/models.d.ts +131 -0
  56. package/dist/esm/core/models.js +2 -0
  57. package/dist/esm/core/models.js.map +1 -0
  58. package/dist/esm/core/options.d.ts +154 -0
  59. package/dist/esm/core/options.js +2 -0
  60. package/dist/esm/core/options.js.map +1 -0
  61. package/dist/esm/core/text.d.ts +138 -0
  62. package/dist/esm/core/text.js +14 -0
  63. package/dist/esm/core/text.js.map +1 -0
  64. package/dist/esm/definitions.d.ts +155 -0
  65. package/dist/esm/definitions.js +2 -0
  66. package/dist/esm/definitions.js.map +1 -0
  67. package/dist/esm/index.d.ts +15 -0
  68. package/dist/esm/index.js +18 -0
  69. package/dist/esm/index.js.map +1 -0
  70. package/dist/esm/web.d.ts +63 -0
  71. package/dist/esm/web.js +112 -0
  72. package/dist/esm/web.js.map +1 -0
  73. package/dist/plugin.cjs.js +224 -0
  74. package/dist/plugin.cjs.js.map +1 -0
  75. package/dist/plugin.js +227 -0
  76. package/dist/plugin.js.map +1 -0
  77. package/ios/Plugin/Adapters/BrotherAdapter.swift +139 -0
  78. package/ios/Plugin/Adapters/EpsonAdapter.swift +131 -0
  79. package/ios/Plugin/Adapters/EscPosAdapter.swift +106 -0
  80. package/ios/Plugin/Adapters/EscPosCommands.swift +32 -0
  81. package/ios/Plugin/Adapters/EscPosTextEncoder.swift +115 -0
  82. package/ios/Plugin/Adapters/PrinterAdapter.swift +44 -0
  83. package/ios/Plugin/Adapters/RawTcpAdapter.swift +70 -0
  84. package/ios/Plugin/Adapters/StarAdapter.swift +305 -0
  85. package/ios/Plugin/Adapters/ZebraAdapter.swift +119 -0
  86. package/ios/Plugin/Discovery/AdapterPriority.swift +21 -0
  87. package/ios/Plugin/Discovery/BonjourScanner.swift +51 -0
  88. package/ios/Plugin/Discovery/DiscoveryManager.swift +86 -0
  89. package/ios/Plugin/Image/ImageCache.swift +73 -0
  90. package/ios/Plugin/Image/ImageProcessor.swift +168 -0
  91. package/ios/Plugin/Image/TextRasterizer.swift +81 -0
  92. package/ios/Plugin/Logger.swift +33 -0
  93. package/ios/Plugin/Model/Models.swift +174 -0
  94. package/ios/Plugin/Model/PrintItem.swift +111 -0
  95. package/ios/Plugin/Store/PrinterStore.swift +51 -0
  96. package/ios/Plugin/ThermalPrinterEngine.swift +395 -0
  97. package/ios/Plugin/ThermalPrinterPlugin.m +22 -0
  98. package/ios/Plugin/ThermalPrinterPlugin.swift +258 -0
  99. package/ios/Plugin/Transport/TcpTransport.swift +89 -0
  100. package/package.json +96 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Stratégie de largeur d'impression et utilitaires raster ESC/POS.
3
+ *
4
+ * Ce module est une référence TypeScript PURE (sans dépendance native) :
5
+ * - documente le mapping largeur papier (mm) -> points imprimables,
6
+ * - fournit un encodeur raster GS v 0 testable,
7
+ * - sert de spécification que les implémentations Android/iOS doivent suivre.
8
+ *
9
+ * Le rendu réel (decode PNG, resize, dithering) est fait en natif pour la perf,
10
+ * mais l'algorithme de tramage et le format raster sont identiques.
11
+ */
12
+ /**
13
+ * Mapping largeur papier -> points imprimables @203 dpi (8 dots/mm).
14
+ *
15
+ * Valeurs DE RÉFÉRENCE (les plus courantes), à confirmer via le SDK/profil :
16
+ * - 58 mm : 384 dots (zone imprimable ~48mm)
17
+ * - 80 mm : 576 dots (zone imprimable ~72mm)
18
+ * - 80 mm : 640 dots sur certains modèles (zone imprimable ~80mm) -> override profil
19
+ * - 112 mm : 832 dots
20
+ *
21
+ * Recommandation : TOUJOURS préférer la valeur `printableDots` du profil/SDK
22
+ * quand elle est connue. Ce mapping n'est qu'un défaut sûr.
23
+ */
24
+ export declare const PAPER_WIDTH_PRESETS: Record<number, number>;
25
+ /** Déduit la largeur en points à partir de la largeur papier (fallback 80mm). */
26
+ export declare function dotsForPaperWidth(paperWidthMm: number): number;
27
+ /**
28
+ * Représentation 1-bit d'une image : un tableau de pixels noir/blanc.
29
+ * `data[i] = 1` => point ENCRE (noir). width et height en pixels.
30
+ */
31
+ export interface MonoBitmap {
32
+ width: number;
33
+ height: number;
34
+ /** 1 octet par pixel pour la lisibilité (0 = blanc, 1 = noir). */
35
+ data: Uint8Array;
36
+ }
37
+ /**
38
+ * Binarisation par seuil simple. À partir d'une image en niveaux de gris (0-255,
39
+ * 0 = noir), produit un MonoBitmap. `threshold` par défaut 128.
40
+ */
41
+ export declare function thresholdToMono(gray: Uint8Array, width: number, height: number, threshold?: number): MonoBitmap;
42
+ /**
43
+ * Tramage Floyd–Steinberg (diffusion d'erreur). Recommandé pour logos/photos.
44
+ * Mute une copie du buffer gris. Retourne un MonoBitmap.
45
+ */
46
+ export declare function floydSteinbergToMono(grayInput: Uint8Array, width: number, height: number): MonoBitmap;
47
+ /**
48
+ * Tramage Atkinson (diffuse 6/8 de l'erreur). Rendu plus contrasté, agréable
49
+ * sur tickets de caisse.
50
+ */
51
+ export declare function atkinsonToMono(grayInput: Uint8Array, width: number, height: number): MonoBitmap;
52
+ /**
53
+ * Encode un MonoBitmap au format raster ESC/POS `GS v 0`.
54
+ *
55
+ * Format de la commande (mode normal m=0) :
56
+ * GS 'v' '0' m xL xH yL yH d1...dk
57
+ * - GS = 0x1D, 'v' = 0x76, '0' = 0x30
58
+ * - m = 0 (normal) | 1 (double largeur) | 2 (double hauteur) | 3 (quad)
59
+ * - xL,xH = nombre d'OCTETS par ligne (width/8) en little-endian
60
+ * - yL,yH = nombre de LIGNES (height) en little-endian
61
+ * - data = octets bitmap, bit de poids fort = pixel le plus à gauche
62
+ *
63
+ * IMPORTANT : la largeur DOIT être paddée à un multiple de 8 pixels.
64
+ */
65
+ export declare function encodeEscPosRaster(mono: MonoBitmap, mode?: 0 | 1 | 2 | 3): Uint8Array;
66
+ /** Commandes ESC/POS de base (init, feed, cut, drawer). */
67
+ export declare const EscPos: {
68
+ INIT: Uint8Array;
69
+ feed(lines: number): Uint8Array;
70
+ alignLeft: Uint8Array;
71
+ alignCenter: Uint8Array;
72
+ alignRight: Uint8Array;
73
+ cutFull: Uint8Array;
74
+ cutPartial: Uint8Array;
75
+ cutFeed(n?: number): Uint8Array;
76
+ openDrawerPin2: Uint8Array;
77
+ openDrawerPin5: Uint8Array;
78
+ /** Statut temps réel : DLE EOT n (1=printer,2=offline,3=error,4=paper). */
79
+ realtimeStatus(n: 1 | 2 | 3 | 4): Uint8Array;
80
+ };
81
+ /**
82
+ * Assemble un job ESC/POS complet (init + align + raster + feed + cut + drawer).
83
+ * `chunkRowsForLargeImage` : sur de très grandes images, certaines imprimantes
84
+ * BT/série préfèrent recevoir le raster en bandes pour éviter les overflows de buffer.
85
+ */
86
+ export declare function buildEscPosImageJob(mono: MonoBitmap, opts?: {
87
+ align?: 'left' | 'center' | 'right';
88
+ cut?: boolean;
89
+ feedLines?: number;
90
+ openCashDrawer?: boolean;
91
+ }): Uint8Array;
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Stratégie de largeur d'impression et utilitaires raster ESC/POS.
3
+ *
4
+ * Ce module est une référence TypeScript PURE (sans dépendance native) :
5
+ * - documente le mapping largeur papier (mm) -> points imprimables,
6
+ * - fournit un encodeur raster GS v 0 testable,
7
+ * - sert de spécification que les implémentations Android/iOS doivent suivre.
8
+ *
9
+ * Le rendu réel (decode PNG, resize, dithering) est fait en natif pour la perf,
10
+ * mais l'algorithme de tramage et le format raster sont identiques.
11
+ */
12
+ /**
13
+ * Mapping largeur papier -> points imprimables @203 dpi (8 dots/mm).
14
+ *
15
+ * Valeurs DE RÉFÉRENCE (les plus courantes), à confirmer via le SDK/profil :
16
+ * - 58 mm : 384 dots (zone imprimable ~48mm)
17
+ * - 80 mm : 576 dots (zone imprimable ~72mm)
18
+ * - 80 mm : 640 dots sur certains modèles (zone imprimable ~80mm) -> override profil
19
+ * - 112 mm : 832 dots
20
+ *
21
+ * Recommandation : TOUJOURS préférer la valeur `printableDots` du profil/SDK
22
+ * quand elle est connue. Ce mapping n'est qu'un défaut sûr.
23
+ */
24
+ export const PAPER_WIDTH_PRESETS = {
25
+ 58: 384,
26
+ 80: 576,
27
+ 112: 832,
28
+ };
29
+ /** Déduit la largeur en points à partir de la largeur papier (fallback 80mm). */
30
+ export function dotsForPaperWidth(paperWidthMm) {
31
+ var _a;
32
+ return (_a = PAPER_WIDTH_PRESETS[paperWidthMm]) !== null && _a !== void 0 ? _a : PAPER_WIDTH_PRESETS[80];
33
+ }
34
+ /**
35
+ * Binarisation par seuil simple. À partir d'une image en niveaux de gris (0-255,
36
+ * 0 = noir), produit un MonoBitmap. `threshold` par défaut 128.
37
+ */
38
+ export function thresholdToMono(gray, width, height, threshold = 128) {
39
+ const out = new Uint8Array(width * height);
40
+ for (let i = 0; i < out.length; i++) {
41
+ out[i] = gray[i] < threshold ? 1 : 0;
42
+ }
43
+ return { width, height, data: out };
44
+ }
45
+ /**
46
+ * Tramage Floyd–Steinberg (diffusion d'erreur). Recommandé pour logos/photos.
47
+ * Mute une copie du buffer gris. Retourne un MonoBitmap.
48
+ */
49
+ export function floydSteinbergToMono(grayInput, width, height) {
50
+ const gray = Float32Array.from(grayInput);
51
+ const out = new Uint8Array(width * height);
52
+ const at = (x, y) => y * width + x;
53
+ for (let y = 0; y < height; y++) {
54
+ for (let x = 0; x < width; x++) {
55
+ const idx = at(x, y);
56
+ const oldPixel = gray[idx];
57
+ const newPixel = oldPixel < 128 ? 0 : 255;
58
+ out[idx] = newPixel === 0 ? 1 : 0;
59
+ const err = oldPixel - newPixel;
60
+ if (x + 1 < width)
61
+ gray[at(x + 1, y)] += (err * 7) / 16;
62
+ if (x - 1 >= 0 && y + 1 < height)
63
+ gray[at(x - 1, y + 1)] += (err * 3) / 16;
64
+ if (y + 1 < height)
65
+ gray[at(x, y + 1)] += (err * 5) / 16;
66
+ if (x + 1 < width && y + 1 < height)
67
+ gray[at(x + 1, y + 1)] += (err * 1) / 16;
68
+ }
69
+ }
70
+ return { width, height, data: out };
71
+ }
72
+ /**
73
+ * Tramage Atkinson (diffuse 6/8 de l'erreur). Rendu plus contrasté, agréable
74
+ * sur tickets de caisse.
75
+ */
76
+ export function atkinsonToMono(grayInput, width, height) {
77
+ const gray = Float32Array.from(grayInput);
78
+ const out = new Uint8Array(width * height);
79
+ const at = (x, y) => y * width + x;
80
+ const spread = (x, y, e) => {
81
+ if (x >= 0 && x < width && y >= 0 && y < height)
82
+ gray[at(x, y)] += e;
83
+ };
84
+ for (let y = 0; y < height; y++) {
85
+ for (let x = 0; x < width; x++) {
86
+ const idx = at(x, y);
87
+ const oldPixel = gray[idx];
88
+ const newPixel = oldPixel < 128 ? 0 : 255;
89
+ out[idx] = newPixel === 0 ? 1 : 0;
90
+ const err = (oldPixel - newPixel) / 8;
91
+ spread(x + 1, y, err);
92
+ spread(x + 2, y, err);
93
+ spread(x - 1, y + 1, err);
94
+ spread(x, y + 1, err);
95
+ spread(x + 1, y + 1, err);
96
+ spread(x, y + 2, err);
97
+ }
98
+ }
99
+ return { width, height, data: out };
100
+ }
101
+ /**
102
+ * Encode un MonoBitmap au format raster ESC/POS `GS v 0`.
103
+ *
104
+ * Format de la commande (mode normal m=0) :
105
+ * GS 'v' '0' m xL xH yL yH d1...dk
106
+ * - GS = 0x1D, 'v' = 0x76, '0' = 0x30
107
+ * - m = 0 (normal) | 1 (double largeur) | 2 (double hauteur) | 3 (quad)
108
+ * - xL,xH = nombre d'OCTETS par ligne (width/8) en little-endian
109
+ * - yL,yH = nombre de LIGNES (height) en little-endian
110
+ * - data = octets bitmap, bit de poids fort = pixel le plus à gauche
111
+ *
112
+ * IMPORTANT : la largeur DOIT être paddée à un multiple de 8 pixels.
113
+ */
114
+ export function encodeEscPosRaster(mono, mode = 0) {
115
+ const { width, height, data } = mono;
116
+ const bytesPerRow = Math.ceil(width / 8);
117
+ const xL = bytesPerRow & 0xff;
118
+ const xH = (bytesPerRow >> 8) & 0xff;
119
+ const yL = height & 0xff;
120
+ const yH = (height >> 8) & 0xff;
121
+ const header = new Uint8Array([0x1d, 0x76, 0x30, mode, xL, xH, yL, yH]);
122
+ const body = new Uint8Array(bytesPerRow * height);
123
+ for (let y = 0; y < height; y++) {
124
+ for (let x = 0; x < width; x++) {
125
+ if (data[y * width + x] === 1) {
126
+ const byteIndex = y * bytesPerRow + (x >> 3);
127
+ const bit = 7 - (x & 7);
128
+ body[byteIndex] |= 1 << bit;
129
+ }
130
+ }
131
+ }
132
+ const out = new Uint8Array(header.length + body.length);
133
+ out.set(header, 0);
134
+ out.set(body, header.length);
135
+ return out;
136
+ }
137
+ /** Commandes ESC/POS de base (init, feed, cut, drawer). */
138
+ export const EscPos = {
139
+ INIT: new Uint8Array([0x1b, 0x40]), // ESC @
140
+ feed(lines) {
141
+ // ESC d n
142
+ return new Uint8Array([0x1b, 0x64, Math.max(0, Math.min(255, lines))]);
143
+ },
144
+ alignLeft: new Uint8Array([0x1b, 0x61, 0x00]),
145
+ alignCenter: new Uint8Array([0x1b, 0x61, 0x01]),
146
+ alignRight: new Uint8Array([0x1b, 0x61, 0x02]),
147
+ cutFull: new Uint8Array([0x1d, 0x56, 0x00]), // GS V 0
148
+ cutPartial: new Uint8Array([0x1d, 0x56, 0x01]), // GS V 1
149
+ // GS V 66 n : feed + partial cut
150
+ cutFeed(n = 3) {
151
+ return new Uint8Array([0x1d, 0x56, 0x42, n]);
152
+ },
153
+ openDrawerPin2: new Uint8Array([0x1b, 0x70, 0x00, 0x19, 0xfa]), // ESC p 0
154
+ openDrawerPin5: new Uint8Array([0x1b, 0x70, 0x01, 0x19, 0xfa]), // ESC p 1
155
+ /** Statut temps réel : DLE EOT n (1=printer,2=offline,3=error,4=paper). */
156
+ realtimeStatus(n) {
157
+ return new Uint8Array([0x10, 0x04, n]);
158
+ },
159
+ };
160
+ /**
161
+ * Assemble un job ESC/POS complet (init + align + raster + feed + cut + drawer).
162
+ * `chunkRowsForLargeImage` : sur de très grandes images, certaines imprimantes
163
+ * BT/série préfèrent recevoir le raster en bandes pour éviter les overflows de buffer.
164
+ */
165
+ export function buildEscPosImageJob(mono, opts = {}) {
166
+ const { align = 'center', cut = true, feedLines = 3, openCashDrawer = false } = opts;
167
+ const parts = [EscPos.INIT];
168
+ parts.push(align === 'center' ? EscPos.alignCenter : align === 'right' ? EscPos.alignRight : EscPos.alignLeft);
169
+ parts.push(encodeEscPosRaster(mono));
170
+ parts.push(EscPos.feed(feedLines));
171
+ if (cut)
172
+ parts.push(EscPos.cutPartial);
173
+ if (openCashDrawer)
174
+ parts.push(EscPos.openDrawerPin2);
175
+ const total = parts.reduce((n, p) => n + p.length, 0);
176
+ const out = new Uint8Array(total);
177
+ let off = 0;
178
+ for (const p of parts) {
179
+ out.set(p, off);
180
+ off += p.length;
181
+ }
182
+ return out;
183
+ }
184
+ //# sourceMappingURL=imaging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imaging.js","sourceRoot":"","sources":["../../../src/core/imaging.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Stratégie de largeur d'impression et utilitaires raster ESC/POS.\n *\n * Ce module est une référence TypeScript PURE (sans dépendance native) :\n * - documente le mapping largeur papier (mm) -> points imprimables,\n * - fournit un encodeur raster GS v 0 testable,\n * - sert de spécification que les implémentations Android/iOS doivent suivre.\n *\n * Le rendu réel (decode PNG, resize, dithering) est fait en natif pour la perf,\n * mais l'algorithme de tramage et le format raster sont identiques.\n */\n\n/**\n * Mapping largeur papier -> points imprimables @203 dpi (8 dots/mm).\n *\n * Valeurs DE RÉFÉRENCE (les plus courantes), à confirmer via le SDK/profil :\n * - 58 mm : 384 dots (zone imprimable ~48mm)\n * - 80 mm : 576 dots (zone imprimable ~72mm)\n * - 80 mm : 640 dots sur certains modèles (zone imprimable ~80mm) -> override profil\n * - 112 mm : 832 dots\n *\n * Recommandation : TOUJOURS préférer la valeur `printableDots` du profil/SDK\n * quand elle est connue. Ce mapping n'est qu'un défaut sûr.\n */\nexport const PAPER_WIDTH_PRESETS: Record<number, number> = {\n 58: 384,\n 80: 576,\n 112: 832,\n};\n\n/** Déduit la largeur en points à partir de la largeur papier (fallback 80mm). */\nexport function dotsForPaperWidth(paperWidthMm: number): number {\n return PAPER_WIDTH_PRESETS[paperWidthMm] ?? PAPER_WIDTH_PRESETS[80];\n}\n\n/**\n * Représentation 1-bit d'une image : un tableau de pixels noir/blanc.\n * `data[i] = 1` => point ENCRE (noir). width et height en pixels.\n */\nexport interface MonoBitmap {\n width: number;\n height: number;\n /** 1 octet par pixel pour la lisibilité (0 = blanc, 1 = noir). */\n data: Uint8Array;\n}\n\n/**\n * Binarisation par seuil simple. À partir d'une image en niveaux de gris (0-255,\n * 0 = noir), produit un MonoBitmap. `threshold` par défaut 128.\n */\nexport function thresholdToMono(gray: Uint8Array, width: number, height: number, threshold = 128): MonoBitmap {\n const out = new Uint8Array(width * height);\n for (let i = 0; i < out.length; i++) {\n out[i] = gray[i] < threshold ? 1 : 0;\n }\n return { width, height, data: out };\n}\n\n/**\n * Tramage Floyd–Steinberg (diffusion d'erreur). Recommandé pour logos/photos.\n * Mute une copie du buffer gris. Retourne un MonoBitmap.\n */\nexport function floydSteinbergToMono(grayInput: Uint8Array, width: number, height: number): MonoBitmap {\n const gray = Float32Array.from(grayInput);\n const out = new Uint8Array(width * height);\n const at = (x: number, y: number) => y * width + x;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = at(x, y);\n const oldPixel = gray[idx];\n const newPixel = oldPixel < 128 ? 0 : 255;\n out[idx] = newPixel === 0 ? 1 : 0;\n const err = oldPixel - newPixel;\n\n if (x + 1 < width) gray[at(x + 1, y)] += (err * 7) / 16;\n if (x - 1 >= 0 && y + 1 < height) gray[at(x - 1, y + 1)] += (err * 3) / 16;\n if (y + 1 < height) gray[at(x, y + 1)] += (err * 5) / 16;\n if (x + 1 < width && y + 1 < height) gray[at(x + 1, y + 1)] += (err * 1) / 16;\n }\n }\n return { width, height, data: out };\n}\n\n/**\n * Tramage Atkinson (diffuse 6/8 de l'erreur). Rendu plus contrasté, agréable\n * sur tickets de caisse.\n */\nexport function atkinsonToMono(grayInput: Uint8Array, width: number, height: number): MonoBitmap {\n const gray = Float32Array.from(grayInput);\n const out = new Uint8Array(width * height);\n const at = (x: number, y: number) => y * width + x;\n const spread = (x: number, y: number, e: number) => {\n if (x >= 0 && x < width && y >= 0 && y < height) gray[at(x, y)] += e;\n };\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = at(x, y);\n const oldPixel = gray[idx];\n const newPixel = oldPixel < 128 ? 0 : 255;\n out[idx] = newPixel === 0 ? 1 : 0;\n const err = (oldPixel - newPixel) / 8;\n spread(x + 1, y, err);\n spread(x + 2, y, err);\n spread(x - 1, y + 1, err);\n spread(x, y + 1, err);\n spread(x + 1, y + 1, err);\n spread(x, y + 2, err);\n }\n }\n return { width, height, data: out };\n}\n\n/**\n * Encode un MonoBitmap au format raster ESC/POS `GS v 0`.\n *\n * Format de la commande (mode normal m=0) :\n * GS 'v' '0' m xL xH yL yH d1...dk\n * - GS = 0x1D, 'v' = 0x76, '0' = 0x30\n * - m = 0 (normal) | 1 (double largeur) | 2 (double hauteur) | 3 (quad)\n * - xL,xH = nombre d'OCTETS par ligne (width/8) en little-endian\n * - yL,yH = nombre de LIGNES (height) en little-endian\n * - data = octets bitmap, bit de poids fort = pixel le plus à gauche\n *\n * IMPORTANT : la largeur DOIT être paddée à un multiple de 8 pixels.\n */\nexport function encodeEscPosRaster(mono: MonoBitmap, mode: 0 | 1 | 2 | 3 = 0): Uint8Array {\n const { width, height, data } = mono;\n const bytesPerRow = Math.ceil(width / 8);\n const xL = bytesPerRow & 0xff;\n const xH = (bytesPerRow >> 8) & 0xff;\n const yL = height & 0xff;\n const yH = (height >> 8) & 0xff;\n\n const header = new Uint8Array([0x1d, 0x76, 0x30, mode, xL, xH, yL, yH]);\n const body = new Uint8Array(bytesPerRow * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n if (data[y * width + x] === 1) {\n const byteIndex = y * bytesPerRow + (x >> 3);\n const bit = 7 - (x & 7);\n body[byteIndex] |= 1 << bit;\n }\n }\n }\n\n const out = new Uint8Array(header.length + body.length);\n out.set(header, 0);\n out.set(body, header.length);\n return out;\n}\n\n/** Commandes ESC/POS de base (init, feed, cut, drawer). */\nexport const EscPos = {\n INIT: new Uint8Array([0x1b, 0x40]), // ESC @\n feed(lines: number): Uint8Array {\n // ESC d n\n return new Uint8Array([0x1b, 0x64, Math.max(0, Math.min(255, lines))]);\n },\n alignLeft: new Uint8Array([0x1b, 0x61, 0x00]),\n alignCenter: new Uint8Array([0x1b, 0x61, 0x01]),\n alignRight: new Uint8Array([0x1b, 0x61, 0x02]),\n cutFull: new Uint8Array([0x1d, 0x56, 0x00]), // GS V 0\n cutPartial: new Uint8Array([0x1d, 0x56, 0x01]), // GS V 1\n // GS V 66 n : feed + partial cut\n cutFeed(n = 3): Uint8Array {\n return new Uint8Array([0x1d, 0x56, 0x42, n]);\n },\n openDrawerPin2: new Uint8Array([0x1b, 0x70, 0x00, 0x19, 0xfa]), // ESC p 0\n openDrawerPin5: new Uint8Array([0x1b, 0x70, 0x01, 0x19, 0xfa]), // ESC p 1\n /** Statut temps réel : DLE EOT n (1=printer,2=offline,3=error,4=paper). */\n realtimeStatus(n: 1 | 2 | 3 | 4): Uint8Array {\n return new Uint8Array([0x10, 0x04, n]);\n },\n};\n\n/**\n * Assemble un job ESC/POS complet (init + align + raster + feed + cut + drawer).\n * `chunkRowsForLargeImage` : sur de très grandes images, certaines imprimantes\n * BT/série préfèrent recevoir le raster en bandes pour éviter les overflows de buffer.\n */\nexport function buildEscPosImageJob(\n mono: MonoBitmap,\n opts: {\n align?: 'left' | 'center' | 'right';\n cut?: boolean;\n feedLines?: number;\n openCashDrawer?: boolean;\n } = {},\n): Uint8Array {\n const { align = 'center', cut = true, feedLines = 3, openCashDrawer = false } = opts;\n const parts: Uint8Array[] = [EscPos.INIT];\n\n parts.push(align === 'center' ? EscPos.alignCenter : align === 'right' ? EscPos.alignRight : EscPos.alignLeft);\n parts.push(encodeEscPosRaster(mono));\n parts.push(EscPos.feed(feedLines));\n if (cut) parts.push(EscPos.cutPartial);\n if (openCashDrawer) parts.push(EscPos.openDrawerPin2);\n\n const total = parts.reduce((n, p) => n + p.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of parts) {\n out.set(p, off);\n off += p.length;\n }\n return out;\n}\n"]}
@@ -0,0 +1,131 @@
1
+ import type { ConnectionState, HoldReason, JobState, PaperStatus, PrinterAdapterId, PrinterTransport, PrintErrorCode } from './enums';
2
+ import type { PrintRenderOptions } from './options';
3
+ /**
4
+ * Capacités matérielles/logicielles d'une imprimante.
5
+ * Renseignées au mieux à la découverte, complétées après un premier print réussi.
6
+ */
7
+ export interface PrinterCapabilities {
8
+ /** Largeur papier physique en millimètres (58, 80, 112...). */
9
+ paperWidthMm: number;
10
+ /** Nombre de points imprimables sur la largeur (ex: 384 pour 58mm, 576 pour 80mm @203dpi). */
11
+ printableDots: number;
12
+ /** Résolution en points par pouce (généralement 203). */
13
+ dpi: number;
14
+ /** L'imprimante possède un massicot. */
15
+ supportsCut: boolean;
16
+ /** L'imprimante peut piloter un tiroir-caisse. */
17
+ supportsCashDrawer: boolean;
18
+ /** L'imprimante remonte un statut temps réel (papier, capot, erreurs). */
19
+ supportsStatus: boolean;
20
+ /** L'imprimante accepte l'impression d'images raster. */
21
+ supportsRasterImage: boolean;
22
+ /** L'imprimante peut générer des QR codes nativement (sinon: imprimés via image). */
23
+ supportsQrCode?: boolean;
24
+ /** L'imprimante peut générer des codes-barres nativement. */
25
+ supportsBarcode?: boolean;
26
+ }
27
+ /**
28
+ * Imprimante telle que remontée par la découverte agrégée, après dédoublonnage.
29
+ */
30
+ export interface DiscoveredPrinter {
31
+ /** Identifiant interne stable construit par le plugin (voir buildStableId). */
32
+ id: string;
33
+ /** Nom lisible (nom Bluetooth, hostname, ou modèle SDK). */
34
+ name: string;
35
+ /** Marque détectée si connue ("Epson", "Star", "Generic", ...). */
36
+ brand?: string;
37
+ /** Modèle détecté si connu ("TM-m30", "mC-Print3", ...). */
38
+ model?: string;
39
+ /** Transport physique utilisé pour joindre l'imprimante. */
40
+ transport: PrinterTransport;
41
+ /** Adapter retenu par le moteur de priorité. */
42
+ adapter: PrinterAdapterId;
43
+ /**
44
+ * Adresse de joignabilité, dépendante du transport :
45
+ * - wifi/ethernet : "192.168.1.50:9100"
46
+ * - bluetooth : "AA:BB:CC:DD:EE:FF" (MAC)
47
+ * - ble : UUID périphérique (iOS) ou MAC (Android)
48
+ * - usb : "vendorId:productId" ou device name
49
+ */
50
+ address: string;
51
+ /** Capacités connues (best effort à la découverte). */
52
+ capabilities?: Partial<PrinterCapabilities>;
53
+ /** Source(s) de découverte ayant remonté cette imprimante (pour debug / fusion). */
54
+ discoveredBy?: PrinterAdapterId[];
55
+ /** Timestamp (ms epoch) de dernière détection. */
56
+ lastSeenAt: number;
57
+ /** Vrai si c'est l'imprimante par défaut enregistrée. */
58
+ isDefault: boolean;
59
+ /** Vrai si le plugin a une connexion active ouverte. */
60
+ isConnected: boolean;
61
+ }
62
+ /**
63
+ * Profil persistant d'une imprimante enregistrée (sauvegardé après test réussi).
64
+ * Contient tout le nécessaire pour la reconnexion automatique sans re-découverte.
65
+ */
66
+ export interface PrinterProfile {
67
+ id: string;
68
+ adapter: PrinterAdapterId;
69
+ transport: PrinterTransport;
70
+ address: string;
71
+ brand?: string;
72
+ model?: string;
73
+ name: string;
74
+ capabilities: PrinterCapabilities;
75
+ /** Options par défaut d'impression mémorisées pour cette imprimante. */
76
+ defaultPrintOptions?: PrintRenderOptions;
77
+ /** Données opaques propres à l'adapter pour reconnexion (ex: identifiant SDK). */
78
+ adapterMeta?: Record<string, string | number | boolean>;
79
+ isDefault: boolean;
80
+ createdAt: number;
81
+ updatedAt: number;
82
+ }
83
+ /**
84
+ * Statut temps réel d'une imprimante.
85
+ */
86
+ export interface PrinterStatus {
87
+ id: string;
88
+ connection: ConnectionState;
89
+ online: boolean;
90
+ paper: PaperStatus;
91
+ coverOpen?: boolean;
92
+ /** Erreur courante si l'imprimante est en faute. */
93
+ errorCode?: PrintErrorCode;
94
+ /** Message brut du SDK/transport (debug). */
95
+ rawStatus?: string;
96
+ checkedAt: number;
97
+ }
98
+ /**
99
+ * Statut temps réel d'un job d'impression, émis via l'event `printJobStatus`.
100
+ */
101
+ export interface PrintJobStatus {
102
+ /** Identifiant unique du job (retourné aussi dans PrintResult). */
103
+ jobId: string;
104
+ printerId: string;
105
+ state: JobState;
106
+ /** Raison si l'état est `hold`. */
107
+ holdReason?: HoldReason;
108
+ /** Progression 0..1 (best-effort : avancement de l'envoi des octets). */
109
+ progress?: number;
110
+ errorCode?: PrintErrorCode;
111
+ message?: string;
112
+ updatedAt: number;
113
+ }
114
+ /**
115
+ * Résultat normalisé d'une impression (image ou texte).
116
+ */
117
+ export interface PrintResult {
118
+ success: boolean;
119
+ printerId: string;
120
+ adapter: PrinterAdapterId;
121
+ /** Identifiant du job (corrélé aux events printJobStatus). */
122
+ jobId: string;
123
+ /** État final du job (`completed` si succès). */
124
+ state: JobState;
125
+ /** Nombre d'octets effectivement envoyés au transport. */
126
+ bytesSent?: number;
127
+ /** Durée totale (ms) de l'opération print (reconnexion incluse). */
128
+ durationMs?: number;
129
+ /** Statut imprimante lu après impression, si disponible. */
130
+ status?: PrinterStatus;
131
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/core/models.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ConnectionState,\n HoldReason,\n JobState,\n PaperStatus,\n PrinterAdapterId,\n PrinterTransport,\n PrintErrorCode,\n} from './enums';\nimport type { PrintRenderOptions } from './options';\n\n/**\n * Capacités matérielles/logicielles d'une imprimante.\n * Renseignées au mieux à la découverte, complétées après un premier print réussi.\n */\nexport interface PrinterCapabilities {\n /** Largeur papier physique en millimètres (58, 80, 112...). */\n paperWidthMm: number;\n /** Nombre de points imprimables sur la largeur (ex: 384 pour 58mm, 576 pour 80mm @203dpi). */\n printableDots: number;\n /** Résolution en points par pouce (généralement 203). */\n dpi: number;\n /** L'imprimante possède un massicot. */\n supportsCut: boolean;\n /** L'imprimante peut piloter un tiroir-caisse. */\n supportsCashDrawer: boolean;\n /** L'imprimante remonte un statut temps réel (papier, capot, erreurs). */\n supportsStatus: boolean;\n /** L'imprimante accepte l'impression d'images raster. */\n supportsRasterImage: boolean;\n /** L'imprimante peut générer des QR codes nativement (sinon: imprimés via image). */\n supportsQrCode?: boolean;\n /** L'imprimante peut générer des codes-barres nativement. */\n supportsBarcode?: boolean;\n}\n\n/**\n * Imprimante telle que remontée par la découverte agrégée, après dédoublonnage.\n */\nexport interface DiscoveredPrinter {\n /** Identifiant interne stable construit par le plugin (voir buildStableId). */\n id: string;\n /** Nom lisible (nom Bluetooth, hostname, ou modèle SDK). */\n name: string;\n /** Marque détectée si connue (\"Epson\", \"Star\", \"Generic\", ...). */\n brand?: string;\n /** Modèle détecté si connu (\"TM-m30\", \"mC-Print3\", ...). */\n model?: string;\n /** Transport physique utilisé pour joindre l'imprimante. */\n transport: PrinterTransport;\n /** Adapter retenu par le moteur de priorité. */\n adapter: PrinterAdapterId;\n /**\n * Adresse de joignabilité, dépendante du transport :\n * - wifi/ethernet : \"192.168.1.50:9100\"\n * - bluetooth : \"AA:BB:CC:DD:EE:FF\" (MAC)\n * - ble : UUID périphérique (iOS) ou MAC (Android)\n * - usb : \"vendorId:productId\" ou device name\n */\n address: string;\n /** Capacités connues (best effort à la découverte). */\n capabilities?: Partial<PrinterCapabilities>;\n /** Source(s) de découverte ayant remonté cette imprimante (pour debug / fusion). */\n discoveredBy?: PrinterAdapterId[];\n /** Timestamp (ms epoch) de dernière détection. */\n lastSeenAt: number;\n /** Vrai si c'est l'imprimante par défaut enregistrée. */\n isDefault: boolean;\n /** Vrai si le plugin a une connexion active ouverte. */\n isConnected: boolean;\n}\n\n/**\n * Profil persistant d'une imprimante enregistrée (sauvegardé après test réussi).\n * Contient tout le nécessaire pour la reconnexion automatique sans re-découverte.\n */\nexport interface PrinterProfile {\n id: string;\n adapter: PrinterAdapterId;\n transport: PrinterTransport;\n address: string;\n brand?: string;\n model?: string;\n name: string;\n capabilities: PrinterCapabilities;\n /** Options par défaut d'impression mémorisées pour cette imprimante. */\n defaultPrintOptions?: PrintRenderOptions;\n /** Données opaques propres à l'adapter pour reconnexion (ex: identifiant SDK). */\n adapterMeta?: Record<string, string | number | boolean>;\n isDefault: boolean;\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * Statut temps réel d'une imprimante.\n */\nexport interface PrinterStatus {\n id: string;\n connection: ConnectionState;\n online: boolean;\n paper: PaperStatus;\n coverOpen?: boolean;\n /** Erreur courante si l'imprimante est en faute. */\n errorCode?: PrintErrorCode;\n /** Message brut du SDK/transport (debug). */\n rawStatus?: string;\n checkedAt: number;\n}\n\n/**\n * Statut temps réel d'un job d'impression, émis via l'event `printJobStatus`.\n */\nexport interface PrintJobStatus {\n /** Identifiant unique du job (retourné aussi dans PrintResult). */\n jobId: string;\n printerId: string;\n state: JobState;\n /** Raison si l'état est `hold`. */\n holdReason?: HoldReason;\n /** Progression 0..1 (best-effort : avancement de l'envoi des octets). */\n progress?: number;\n errorCode?: PrintErrorCode;\n message?: string;\n updatedAt: number;\n}\n\n/**\n * Résultat normalisé d'une impression (image ou texte).\n */\nexport interface PrintResult {\n success: boolean;\n printerId: string;\n adapter: PrinterAdapterId;\n /** Identifiant du job (corrélé aux events printJobStatus). */\n jobId: string;\n /** État final du job (`completed` si succès). */\n state: JobState;\n /** Nombre d'octets effectivement envoyés au transport. */\n bytesSent?: number;\n /** Durée totale (ms) de l'opération print (reconnexion incluse). */\n durationMs?: number;\n /** Statut imprimante lu après impression, si disponible. */\n status?: PrinterStatus;\n}\n"]}
@@ -0,0 +1,154 @@
1
+ import type { PrinterAdapterId, PrinterTransport, PrintErrorCode } from './enums';
2
+ /**
3
+ * Algorithme de tramage (dithering) appliqué lors de la conversion 1-bit.
4
+ * - `none` : seuillage simple (threshold) — idéal pour texte/ligne nettes.
5
+ * - `floyd_steinberg` : tramage par diffusion d'erreur — idéal pour logos/photos.
6
+ * - `atkinson` : variante plus contrastée, agréable sur tickets.
7
+ */
8
+ export type DitheringAlgorithm = 'none' | 'floyd_steinberg' | 'atkinson';
9
+ /** Alignement horizontal de l'image si plus étroite que la zone imprimable. */
10
+ export type ImageAlign = 'left' | 'center' | 'right';
11
+ /**
12
+ * Options de rendu image -> impression. Indépendantes du transport.
13
+ */
14
+ export interface PrintRenderOptions {
15
+ /**
16
+ * Largeur cible en points (dots). Si omise, déduite du profil/capacités
17
+ * (ex: 384 pour 58mm, 576 pour 80mm).
18
+ */
19
+ widthDots?: number;
20
+ /**
21
+ * Redimensionner l'image à la largeur cible. Défaut `true`.
22
+ * Mettre `false` si l'image est DÉJÀ à la bonne largeur (rendu serveur) :
23
+ * envoi tel quel, pixel-perfect, plus rapide.
24
+ */
25
+ resize?: boolean;
26
+ /**
27
+ * Conversion niveaux de gris + dithering. Défaut `true`.
28
+ * Mettre `false` si l'image est DÉJÀ en 1-bit noir/blanc (pré-traitée serveur) :
29
+ * un simple seuil est appliqué, sans dithering.
30
+ */
31
+ grayscale?: boolean;
32
+ /** Seuil de binarisation 0-255 (défaut 128) quand dithering = 'none'. */
33
+ threshold?: number;
34
+ /** Algorithme de tramage. Défaut: 'floyd_steinberg'. */
35
+ dithering?: DitheringAlgorithm;
36
+ /** Alignement si l'image est plus étroite que la largeur imprimable. Défaut 'center'. */
37
+ align?: ImageAlign;
38
+ /** Inverser le noir et blanc (impression en négatif). */
39
+ invert?: boolean;
40
+ /** Couper le papier après impression (si supportsCut). Défaut true. */
41
+ cut?: boolean;
42
+ /** Nombre de lignes de feed avant la coupe. Défaut 3. */
43
+ feedLines?: number;
44
+ /** Ouvrir le tiroir-caisse après impression (si supportsCashDrawer). Défaut false. */
45
+ openCashDrawer?: boolean;
46
+ /** Nombre de copies. Défaut 1. */
47
+ copies?: number;
48
+ }
49
+ /**
50
+ * Source de l'image à imprimer. Une seule des trois clés doit être renseignée.
51
+ * Ordre de préférence en production : `filePath` > `url` > `base64`.
52
+ */
53
+ export interface ImageSource {
54
+ /** Chemin local du fichier (file:// ou chemin absolu). MODE RECOMMANDÉ. */
55
+ filePath?: string;
56
+ /** URL distante. Le plugin télécharge (avec cache). */
57
+ url?: string;
58
+ /** Données base64 (avec ou sans préfixe data:). Pratique en test. */
59
+ base64?: string;
60
+ }
61
+ /**
62
+ * Options de l'appel printImage.
63
+ */
64
+ export interface PrintImageOptions {
65
+ /** Imprimante cible. Si omis, utilise l'imprimante par défaut. */
66
+ printerId?: string;
67
+ /** Source image. */
68
+ image: ImageSource;
69
+ /** Options de rendu (fusionnées avec les defaults du profil). */
70
+ render?: PrintRenderOptions;
71
+ /** Timeout global de l'opération en ms (reconnexion + envoi). Défaut 15000. */
72
+ timeoutMs?: number;
73
+ /**
74
+ * Si true, tente une reconnexion automatique si l'imprimante n'est pas connectée.
75
+ * Défaut true.
76
+ */
77
+ autoReconnect?: boolean;
78
+ }
79
+ /**
80
+ * Options de découverte agrégée.
81
+ */
82
+ export interface DiscoverOptions {
83
+ /**
84
+ * Sous-ensemble de sources à activer. Si omis, toutes les sources disponibles
85
+ * sur la plateforme sont lancées en parallèle.
86
+ */
87
+ sources?: DiscoverySource[];
88
+ /** Durée max de scan en ms (le scan BT/BLE est borné par ce délai). Défaut 8000. */
89
+ timeoutMs?: number;
90
+ /** Inclure les appareils Bluetooth déjà appairés (Android). Défaut true. */
91
+ includePaired?: boolean;
92
+ /**
93
+ * Plage/segment réseau à scanner pour TCP 9100 (ex: "192.168.1.0/24").
94
+ * Si omis, déduit du réseau courant.
95
+ */
96
+ networkCidr?: string;
97
+ /** Ports TCP à sonder en plus de 9100 (ex: [9100, 6101, 515]). */
98
+ tcpPorts?: number[];
99
+ /** Émettre des résultats incrémentaux via l'event 'printerFound'. Défaut true. */
100
+ emitPartialResults?: boolean;
101
+ }
102
+ /** Sources de découverte activables. */
103
+ export type DiscoverySource = 'epson' | 'star' | 'brother' | 'zebra' | 'tcp' | 'bluetooth' | 'ble' | 'usb';
104
+ /**
105
+ * Options de l'appel printText.
106
+ */
107
+ export interface PrintTextOptions {
108
+ /** Imprimante cible. Si omis, utilise l'imprimante par défaut. */
109
+ printerId?: string;
110
+ /** Liste ordonnée d'items à imprimer (texte stylé, QR, code-barres, feed, cut...). */
111
+ items: import('./text').PrintItem[];
112
+ /** Page de code par défaut pour les accents (français : 'WPC1252'). */
113
+ defaultCodePage?: import('./text').CodePage;
114
+ /** Couper le papier en fin de job (si non géré par un item `cut`). Défaut false. */
115
+ cut?: boolean;
116
+ /** Lignes d'avance en fin de job avant la coupe. Défaut 3. */
117
+ feedLines?: number;
118
+ /** Timeout global de l'opération en ms. Défaut 15000. */
119
+ timeoutMs?: number;
120
+ /** Reconnexion automatique si non connecté. Défaut true. */
121
+ autoReconnect?: boolean;
122
+ }
123
+ /**
124
+ * Options de connexion explicite.
125
+ */
126
+ export interface ConnectOptions {
127
+ printerId: string;
128
+ /** Timeout de connexion ms. Défaut 10000. */
129
+ timeoutMs?: number;
130
+ /** Forcer un adapter (sinon: celui résolu à la découverte / dans le profil). */
131
+ forceAdapter?: PrinterAdapterId;
132
+ /**
133
+ * Si `true`, enregistre cette imprimante comme imprimante par défaut
134
+ * UNIQUEMENT si la connexion réussit (persistance du profil incluse).
135
+ * Défaut `false`.
136
+ */
137
+ setAsDefault?: boolean;
138
+ }
139
+ /**
140
+ * Erreur normalisée transportée dans les rejets de promesse.
141
+ * Côté JS elle est exposée via PrinterError (classe).
142
+ */
143
+ export interface NormalizedErrorShape {
144
+ code: PrintErrorCode;
145
+ message: string;
146
+ /** Détail brut (message SDK / exception native). */
147
+ detail?: string;
148
+ /** Transport concerné si pertinent. */
149
+ transport?: PrinterTransport;
150
+ /** Adapter concerné si pertinent. */
151
+ adapter?: PrinterAdapterId;
152
+ /** Indique si une nouvelle tentative a du sens. */
153
+ retryable?: boolean;
154
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/core/options.ts"],"names":[],"mappings":"","sourcesContent":["import type { PrinterAdapterId, PrinterTransport, PrintErrorCode } from './enums';\n\n/**\n * Algorithme de tramage (dithering) appliqué lors de la conversion 1-bit.\n * - `none` : seuillage simple (threshold) — idéal pour texte/ligne nettes.\n * - `floyd_steinberg` : tramage par diffusion d'erreur — idéal pour logos/photos.\n * - `atkinson` : variante plus contrastée, agréable sur tickets.\n */\nexport type DitheringAlgorithm = 'none' | 'floyd_steinberg' | 'atkinson';\n\n/** Alignement horizontal de l'image si plus étroite que la zone imprimable. */\nexport type ImageAlign = 'left' | 'center' | 'right';\n\n/**\n * Options de rendu image -> impression. Indépendantes du transport.\n */\nexport interface PrintRenderOptions {\n /**\n * Largeur cible en points (dots). Si omise, déduite du profil/capacités\n * (ex: 384 pour 58mm, 576 pour 80mm).\n */\n widthDots?: number;\n /**\n * Redimensionner l'image à la largeur cible. Défaut `true`.\n * Mettre `false` si l'image est DÉJÀ à la bonne largeur (rendu serveur) :\n * envoi tel quel, pixel-perfect, plus rapide.\n */\n resize?: boolean;\n /**\n * Conversion niveaux de gris + dithering. Défaut `true`.\n * Mettre `false` si l'image est DÉJÀ en 1-bit noir/blanc (pré-traitée serveur) :\n * un simple seuil est appliqué, sans dithering.\n */\n grayscale?: boolean;\n /** Seuil de binarisation 0-255 (défaut 128) quand dithering = 'none'. */\n threshold?: number;\n /** Algorithme de tramage. Défaut: 'floyd_steinberg'. */\n dithering?: DitheringAlgorithm;\n /** Alignement si l'image est plus étroite que la largeur imprimable. Défaut 'center'. */\n align?: ImageAlign;\n /** Inverser le noir et blanc (impression en négatif). */\n invert?: boolean;\n /** Couper le papier après impression (si supportsCut). Défaut true. */\n cut?: boolean;\n /** Nombre de lignes de feed avant la coupe. Défaut 3. */\n feedLines?: number;\n /** Ouvrir le tiroir-caisse après impression (si supportsCashDrawer). Défaut false. */\n openCashDrawer?: boolean;\n /** Nombre de copies. Défaut 1. */\n copies?: number;\n}\n\n/**\n * Source de l'image à imprimer. Une seule des trois clés doit être renseignée.\n * Ordre de préférence en production : `filePath` > `url` > `base64`.\n */\nexport interface ImageSource {\n /** Chemin local du fichier (file:// ou chemin absolu). MODE RECOMMANDÉ. */\n filePath?: string;\n /** URL distante. Le plugin télécharge (avec cache). */\n url?: string;\n /** Données base64 (avec ou sans préfixe data:). Pratique en test. */\n base64?: string;\n}\n\n/**\n * Options de l'appel printImage.\n */\nexport interface PrintImageOptions {\n /** Imprimante cible. Si omis, utilise l'imprimante par défaut. */\n printerId?: string;\n /** Source image. */\n image: ImageSource;\n /** Options de rendu (fusionnées avec les defaults du profil). */\n render?: PrintRenderOptions;\n /** Timeout global de l'opération en ms (reconnexion + envoi). Défaut 15000. */\n timeoutMs?: number;\n /**\n * Si true, tente une reconnexion automatique si l'imprimante n'est pas connectée.\n * Défaut true.\n */\n autoReconnect?: boolean;\n}\n\n/**\n * Options de découverte agrégée.\n */\nexport interface DiscoverOptions {\n /**\n * Sous-ensemble de sources à activer. Si omis, toutes les sources disponibles\n * sur la plateforme sont lancées en parallèle.\n */\n sources?: DiscoverySource[];\n /** Durée max de scan en ms (le scan BT/BLE est borné par ce délai). Défaut 8000. */\n timeoutMs?: number;\n /** Inclure les appareils Bluetooth déjà appairés (Android). Défaut true. */\n includePaired?: boolean;\n /**\n * Plage/segment réseau à scanner pour TCP 9100 (ex: \"192.168.1.0/24\").\n * Si omis, déduit du réseau courant.\n */\n networkCidr?: string;\n /** Ports TCP à sonder en plus de 9100 (ex: [9100, 6101, 515]). */\n tcpPorts?: number[];\n /** Émettre des résultats incrémentaux via l'event 'printerFound'. Défaut true. */\n emitPartialResults?: boolean;\n}\n\n/** Sources de découverte activables. */\nexport type DiscoverySource =\n | 'epson'\n | 'star'\n | 'brother'\n | 'zebra'\n | 'tcp'\n | 'bluetooth'\n | 'ble'\n | 'usb';\n\n/**\n * Options de l'appel printText.\n */\nexport interface PrintTextOptions {\n /** Imprimante cible. Si omis, utilise l'imprimante par défaut. */\n printerId?: string;\n /** Liste ordonnée d'items à imprimer (texte stylé, QR, code-barres, feed, cut...). */\n items: import('./text').PrintItem[];\n /** Page de code par défaut pour les accents (français : 'WPC1252'). */\n defaultCodePage?: import('./text').CodePage;\n /** Couper le papier en fin de job (si non géré par un item `cut`). Défaut false. */\n cut?: boolean;\n /** Lignes d'avance en fin de job avant la coupe. Défaut 3. */\n feedLines?: number;\n /** Timeout global de l'opération en ms. Défaut 15000. */\n timeoutMs?: number;\n /** Reconnexion automatique si non connecté. Défaut true. */\n autoReconnect?: boolean;\n}\n\n/**\n * Options de connexion explicite.\n */\nexport interface ConnectOptions {\n printerId: string;\n /** Timeout de connexion ms. Défaut 10000. */\n timeoutMs?: number;\n /** Forcer un adapter (sinon: celui résolu à la découverte / dans le profil). */\n forceAdapter?: PrinterAdapterId;\n /**\n * Si `true`, enregistre cette imprimante comme imprimante par défaut\n * UNIQUEMENT si la connexion réussit (persistance du profil incluse).\n * Défaut `false`.\n */\n setAsDefault?: boolean;\n}\n\n/**\n * Erreur normalisée transportée dans les rejets de promesse.\n * Côté JS elle est exposée via PrinterError (classe).\n */\nexport interface NormalizedErrorShape {\n code: PrintErrorCode;\n message: string;\n /** Détail brut (message SDK / exception native). */\n detail?: string;\n /** Transport concerné si pertinent. */\n transport?: PrinterTransport;\n /** Adapter concerné si pertinent. */\n adapter?: PrinterAdapterId;\n /** Indique si une nouvelle tentative a du sens. */\n retryable?: boolean;\n}\n"]}