jc-printer-sdk-ts 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,526 @@
1
+ import type {
2
+ BitmapLike,
3
+ BundleLike,
4
+ IAtBitmapDocument,
5
+ MaybePromise,
6
+ PaperInfo,
7
+ PrintCallback,
8
+ PrintDocument,
9
+ PrinterDevice,
10
+ PrinterInfo,
11
+ PrinterSdkCallback,
12
+ PrinterState,
13
+ ScanCallback,
14
+ } from "./types.js";
15
+
16
+ type PrintEventState = {
17
+ callback: PrintCallback | undefined;
18
+ jobStarted: boolean;
19
+ };
20
+
21
+ export interface PrinterTransport {
22
+ getSdkVersion?(): MaybePromise<string>;
23
+ init?(application: unknown): MaybePromise<boolean>;
24
+ initSdk?(application: unknown): MaybePromise<boolean>;
25
+ setSdkCallback?(callback?: PrinterSdkCallback): void;
26
+ initDefaultImageLibrarySettings?(
27
+ fontDirectory: string,
28
+ extra: string,
29
+ ): MaybePromise<number>;
30
+ initImageProcessingDefault?(
31
+ fontDirectory: string,
32
+ extra: string,
33
+ ): MaybePromise<number>;
34
+ openPrinterByAddress?(address: string): MaybePromise<number>;
35
+ openPrinterSync?(address: string): MaybePromise<number>;
36
+ connectBluetoothPrinter?(address: string): MaybePromise<number>;
37
+ connectWifiPrinter?(host: string, port: number): MaybePromise<number>;
38
+ configurationWifi?(ssid: string, password: string): MaybePromise<number>;
39
+ getConfigurationWifiName?(): MaybePromise<string>;
40
+ scanWifiPrinter?(callback: ScanCallback): MaybePromise<void>;
41
+ setPrinterAutoShutdownTime?(minutes: number): MaybePromise<number>;
42
+ setTotalPrintQuantity?(quantity: number): MaybePromise<void>;
43
+ setTotalQuantityOfPrints?(quantity: number): MaybePromise<void>;
44
+ startPrintJob?(
45
+ density: number,
46
+ paperType: number,
47
+ printMode: number,
48
+ callback: PrintCallback,
49
+ ): MaybePromise<void>;
50
+ commitData?(jsonPages: string[], infoPages: string[]): MaybePromise<void>;
51
+ commitDocument?(
52
+ document: PrintDocument,
53
+ infoPages: string[],
54
+ ): MaybePromise<void>;
55
+ endJob?(): MaybePromise<boolean>;
56
+ endPrintJob?(): MaybePromise<boolean>;
57
+ cancelJob?(): MaybePromise<boolean>;
58
+ cancel?(): MaybePromise<void>;
59
+ reopenPrinter?(): MaybePromise<boolean>;
60
+ reopenPrinterSync?(): MaybePromise<boolean>;
61
+ close?(): MaybePromise<void>;
62
+ quit?(): MaybePromise<void>;
63
+ printBitmap?(bitmap: BitmapLike, bundle?: BundleLike): MaybePromise<boolean>;
64
+ printATBitmap?(
65
+ bitmap: IAtBitmapDocument,
66
+ bundle?: BundleLike,
67
+ ): MaybePromise<boolean>;
68
+ getPaperInfo?(): MaybePromise<PaperInfo | null>;
69
+ isConnection?(): MaybePromise<number>;
70
+ getPrintScaleMultiplier?(): MaybePromise<number>;
71
+ getPrinterName?(): MaybePromise<string>;
72
+ getPrinterInfo?(): MaybePromise<PrinterInfo | null>;
73
+ getPrinterState?(): MaybePromise<PrinterState>;
74
+ waitPrinterState?(
75
+ state: PrinterState,
76
+ timeoutMs: number,
77
+ ): MaybePromise<boolean>;
78
+ measureFontHeight?(
79
+ text: string,
80
+ x: number,
81
+ y: number,
82
+ width: number,
83
+ height: number,
84
+ rotation: number,
85
+ fontSize: number,
86
+ ): MaybePromise<number>;
87
+ generatePreviewImage?(json: string, info: string): MaybePromise<BitmapLike>;
88
+ generatePrintPreviewImage?(
89
+ json: string,
90
+ widthMm: number,
91
+ heightMm: number,
92
+ orientation: number,
93
+ ): MaybePromise<BitmapLike>;
94
+
95
+ setPrinterState?(state: PrinterState): void;
96
+ setPrinterInfo?(info: PrinterInfo): void;
97
+ setPaperInfo?(info: PaperInfo): void;
98
+ setScanResults?(results: PrinterDevice[]): void;
99
+ emitPrintProgress?(
100
+ pageIndex: number,
101
+ quantityIndex: number,
102
+ meta?: Record<string, unknown>,
103
+ ): void;
104
+ emitPrintError?(errorCode: number, printState?: number): void;
105
+ emitBufferFree?(pageIndex: number, bufferSize: number): void;
106
+ emitCancel?(success: boolean): void;
107
+ lastDocument?: PrintDocument | undefined;
108
+ }
109
+
110
+ function clone<T>(value: T): T {
111
+ if (typeof globalThis.structuredClone === "function") {
112
+ return globalThis.structuredClone(value);
113
+ }
114
+ return JSON.parse(JSON.stringify(value)) as T;
115
+ }
116
+
117
+ function defaultPrinterInfo(): PrinterInfo {
118
+ return {
119
+ deviceType: 0,
120
+ deviceName: "",
121
+ deviceVersion: "",
122
+ softwareVersion: "",
123
+ deviceAddress: "",
124
+ deviceAddrType: 0,
125
+ deviceDPI: 0,
126
+ deviceWidth: 0,
127
+ manufacturer: "",
128
+ seriesName: "",
129
+ devIntName: "",
130
+ peripheralFlags: 0,
131
+ hardwareFlags: 0,
132
+ softwareFlags: 0,
133
+ };
134
+ }
135
+
136
+ function defaultPaperInfo(): PaperInfo {
137
+ return {
138
+ state: 0,
139
+ gapHeightPixel: 0,
140
+ totalHeightPixel: 0,
141
+ paperType: 0,
142
+ gapHeight: 0,
143
+ totalHeight: 0,
144
+ paperWidthPixel: 0,
145
+ paperWidth: 0,
146
+ direction: 0,
147
+ tailLengthPixel: 0,
148
+ tailLength: 0,
149
+ };
150
+ }
151
+
152
+ function dimensionsFromInfo(info: string): Pick<BitmapLike, "width" | "height"> {
153
+ try {
154
+ const parsed = JSON.parse(info) as {
155
+ printerImageProcessingInfo?: { width?: unknown; height?: unknown };
156
+ };
157
+ const imageInfo = parsed.printerImageProcessingInfo;
158
+ const width = Number(imageInfo?.width ?? 0);
159
+ const height = Number(imageInfo?.height ?? 0);
160
+ return {
161
+ width: Number.isFinite(width) ? width : 0,
162
+ height: Number.isFinite(height) ? height : 0,
163
+ };
164
+ } catch {
165
+ return { width: 0, height: 0 };
166
+ }
167
+ }
168
+
169
+ export class MemoryPrinterTransport implements PrinterTransport {
170
+ private sdkVersion = "ts-mock";
171
+ private configurationWifiName = "";
172
+ private printerInfo: PrinterInfo = defaultPrinterInfo();
173
+ private paperInfo: PaperInfo = defaultPaperInfo();
174
+ private printerState: PrinterState = "Disconnected";
175
+ private printerName = "";
176
+ private connectedAddress = "";
177
+ private connectedType = -1;
178
+ private lastConnectedAddress = "";
179
+ private lastConnectedType = -1;
180
+ private sdkCallback: PrinterSdkCallback | undefined;
181
+ private connectionResult = 0;
182
+ private wifiConfigurationResult = 0;
183
+ private shutdownResult = 0;
184
+ private scanResults: PrinterDevice[] = [];
185
+ private printState: PrintEventState = { callback: undefined, jobStarted: false };
186
+ private totalPrintQuantity = 0;
187
+ lastDocument: PrintDocument | undefined;
188
+ lastBitmap?: BitmapLike;
189
+ lastAtBitmap?: IAtBitmapDocument;
190
+ lastCommitPayload: { jsonPages: string[]; infoPages: string[] } | undefined;
191
+ lastPreview: BitmapLike | undefined;
192
+
193
+ getSdkVersion(): string {
194
+ return this.sdkVersion;
195
+ }
196
+
197
+ setSdkVersion(version: string): void {
198
+ this.sdkVersion = version;
199
+ }
200
+
201
+ initSdk(): boolean {
202
+ return true;
203
+ }
204
+
205
+ init(): boolean {
206
+ return true;
207
+ }
208
+
209
+ setSdkCallback(callback?: PrinterSdkCallback): void {
210
+ this.sdkCallback = callback;
211
+ if (callback && this.printerState !== "Disconnected" && this.connectedAddress) {
212
+ callback.onConnectSuccess(this.connectedAddress, this.connectedType);
213
+ }
214
+ }
215
+
216
+ initDefaultImageLibrarySettings(): number {
217
+ return 0;
218
+ }
219
+
220
+ initImageProcessingDefault(): number {
221
+ return 0;
222
+ }
223
+
224
+ private syncPrinterInfo(address: string, type: number): void {
225
+ this.printerInfo = {
226
+ ...this.printerInfo,
227
+ deviceName: address,
228
+ deviceAddress: address,
229
+ deviceAddrType: type,
230
+ };
231
+ }
232
+
233
+ openPrinterByAddress(address: string): number {
234
+ if (this.connectionResult === 0) {
235
+ this.connectedAddress = address;
236
+ this.connectedType = 0;
237
+ this.lastConnectedAddress = address;
238
+ this.lastConnectedType = this.connectedType;
239
+ this.printerName = address;
240
+ this.syncPrinterInfo(address, this.connectedType);
241
+ this.printerState = "Connected";
242
+ this.sdkCallback?.onConnectSuccess(address, this.connectedType);
243
+ }
244
+ return this.connectionResult;
245
+ }
246
+
247
+ openPrinterSync(address: string): number {
248
+ return this.openPrinterByAddress(address);
249
+ }
250
+
251
+ connectBluetoothPrinter(address: string): number {
252
+ if (this.connectionResult === 0) {
253
+ this.connectedAddress = address;
254
+ this.connectedType = 0;
255
+ this.lastConnectedAddress = address;
256
+ this.lastConnectedType = this.connectedType;
257
+ this.printerName = address;
258
+ this.syncPrinterInfo(address, this.connectedType);
259
+ this.printerState = "Connected";
260
+ this.sdkCallback?.onConnectSuccess(address, this.connectedType);
261
+ }
262
+ return this.connectionResult;
263
+ }
264
+
265
+ connectWifiPrinter(host: string, _port: number): number {
266
+ if (this.connectionResult === 0) {
267
+ this.connectedAddress = host;
268
+ this.connectedType = 1;
269
+ this.lastConnectedAddress = host;
270
+ this.lastConnectedType = this.connectedType;
271
+ this.printerName = host;
272
+ this.syncPrinterInfo(host, this.connectedType);
273
+ this.printerState = "Connected";
274
+ this.sdkCallback?.onConnectSuccess(host, this.connectedType);
275
+ }
276
+ return this.connectionResult;
277
+ }
278
+
279
+ configurationWifi(ssid: string, _password: string): number {
280
+ this.configurationWifiName = ssid;
281
+ return this.wifiConfigurationResult;
282
+ }
283
+
284
+ getConfigurationWifiName(): string {
285
+ return this.configurationWifiName;
286
+ }
287
+
288
+ scanWifiPrinter(callback: ScanCallback): void {
289
+ for (const device of this.scanResults) {
290
+ callback.onScan(clone(device));
291
+ }
292
+ callback.onFinish();
293
+ }
294
+
295
+ setPrinterAutoShutdownTime(minutes: number): number {
296
+ this.shutdownResult = minutes >= 0 ? 0 : -1;
297
+ return this.shutdownResult;
298
+ }
299
+
300
+ setTotalPrintQuantity(quantity: number): void {
301
+ this.totalPrintQuantity = quantity;
302
+ }
303
+
304
+ setTotalQuantityOfPrints(quantity: number): void {
305
+ this.totalPrintQuantity = quantity;
306
+ }
307
+
308
+ startPrintJob(
309
+ _density: number,
310
+ _paperType: number,
311
+ _printMode: number,
312
+ callback: PrintCallback,
313
+ ): void {
314
+ this.printState = { callback, jobStarted: true };
315
+ if (this.connectedAddress) {
316
+ this.printerState = "Printing";
317
+ }
318
+ this.lastDocument = undefined;
319
+ this.lastCommitPayload = undefined;
320
+ this.lastPreview = undefined;
321
+ }
322
+
323
+ commitData(jsonPages: string[], infoPages: string[]): void {
324
+ this.lastCommitPayload = {
325
+ jsonPages: clone(jsonPages),
326
+ infoPages: clone(infoPages),
327
+ };
328
+ }
329
+
330
+ commitDocument(document: PrintDocument, infoPages: string[]): void {
331
+ this.lastDocument = clone(document);
332
+ this.lastCommitPayload = {
333
+ jsonPages: document.pages.map((page) => JSON.stringify(page)),
334
+ infoPages: clone(infoPages),
335
+ };
336
+ }
337
+
338
+ endJob(): boolean {
339
+ this.printState.jobStarted = false;
340
+ this.printState.callback = undefined;
341
+ this.printerState = this.connectedAddress ? "Connected" : "Disconnected";
342
+ return true;
343
+ }
344
+
345
+ endPrintJob(): boolean {
346
+ this.printState.jobStarted = false;
347
+ this.printState.callback = undefined;
348
+ this.printerState = this.connectedAddress ? "Connected" : "Disconnected";
349
+ return true;
350
+ }
351
+
352
+ cancelJob(): boolean {
353
+ this.printState.jobStarted = false;
354
+ this.printState.callback?.onCancelJob(true);
355
+ this.printState.callback = undefined;
356
+ this.printerState = this.connectedAddress ? "Connected" : "Disconnected";
357
+ return true;
358
+ }
359
+
360
+ cancel(): void {
361
+ this.cancelJob();
362
+ }
363
+
364
+ close(): void {
365
+ const wasConnected = this.printerState !== "Disconnected";
366
+ this.printState.jobStarted = false;
367
+ this.printState.callback = undefined;
368
+ this.printerState = "Disconnected";
369
+ this.connectedAddress = "";
370
+ this.connectedType = -1;
371
+ this.printerName = "";
372
+ if (wasConnected) {
373
+ this.sdkCallback?.onDisConnect();
374
+ }
375
+ }
376
+
377
+ quit(): void {
378
+ this.close();
379
+ }
380
+
381
+ reopenPrinter(): boolean {
382
+ if (!this.lastConnectedAddress) {
383
+ return false;
384
+ }
385
+ this.connectedAddress = this.lastConnectedAddress;
386
+ this.connectedType = this.lastConnectedType;
387
+ this.printerName = this.connectedAddress;
388
+ this.syncPrinterInfo(this.connectedAddress, this.connectedType);
389
+ this.printerState = "Connected";
390
+ this.sdkCallback?.onConnectSuccess(this.connectedAddress, this.connectedType);
391
+ return true;
392
+ }
393
+
394
+ reopenPrinterSync(): boolean {
395
+ return this.reopenPrinter();
396
+ }
397
+
398
+ printBitmap(bitmap: BitmapLike): boolean {
399
+ this.lastBitmap = clone(bitmap);
400
+ return true;
401
+ }
402
+
403
+ printATBitmap(bitmap: IAtBitmapDocument): boolean {
404
+ this.lastAtBitmap = clone(bitmap);
405
+ return true;
406
+ }
407
+
408
+ getPaperInfo(): PaperInfo {
409
+ return clone(this.paperInfo);
410
+ }
411
+
412
+ isConnection(): number {
413
+ return this.printerState === "Disconnected" ? -1 : 0;
414
+ }
415
+
416
+ getPrintScaleMultiplier(): number {
417
+ return 1;
418
+ }
419
+
420
+ getPrinterName(): string {
421
+ return this.printerName;
422
+ }
423
+
424
+ getPrinterInfo(): PrinterInfo {
425
+ return clone(this.printerInfo);
426
+ }
427
+
428
+ getPrinterState(): PrinterState {
429
+ return this.printerState;
430
+ }
431
+
432
+ waitPrinterState(state: PrinterState): boolean {
433
+ return this.printerState === state;
434
+ }
435
+
436
+ measureFontHeight(
437
+ text: string,
438
+ _x: number,
439
+ _y: number,
440
+ _width: number,
441
+ _height: number,
442
+ _rotation: number,
443
+ fontSize: number,
444
+ ): number {
445
+ const lines = text.split(/\r?\n/).length;
446
+ return Math.max(fontSize, Math.ceil(fontSize * 1.2 * lines));
447
+ }
448
+
449
+ generatePreviewImage(json: string, info: string): BitmapLike {
450
+ const { width, height } = dimensionsFromInfo(info);
451
+ this.lastPreview = {
452
+ width,
453
+ height,
454
+ description: "preview",
455
+ meta: { json, info },
456
+ };
457
+ return clone(this.lastPreview);
458
+ }
459
+
460
+ generatePrintPreviewImage(
461
+ json: string,
462
+ widthMm: number,
463
+ heightMm: number,
464
+ orientation: number,
465
+ ): BitmapLike {
466
+ this.lastPreview = {
467
+ width: widthMm,
468
+ height: heightMm,
469
+ description: "print-preview",
470
+ meta: { json, orientation },
471
+ };
472
+ return clone(this.lastPreview);
473
+ }
474
+
475
+ setPrinterState(state: PrinterState): void {
476
+ this.printerState = state;
477
+ }
478
+
479
+ setPrinterInfo(info: PrinterInfo): void {
480
+ this.printerInfo = clone(info);
481
+ }
482
+
483
+ setPaperInfo(info: PaperInfo): void {
484
+ this.paperInfo = clone(info);
485
+ }
486
+
487
+ setScanResults(results: PrinterDevice[]): void {
488
+ this.scanResults = clone(results);
489
+ }
490
+
491
+ emitPrintProgress(
492
+ pageIndex: number,
493
+ quantityIndex: number,
494
+ meta: Record<string, unknown> = {},
495
+ ): void {
496
+ this.printState.callback?.onProgress(pageIndex, quantityIndex, meta);
497
+ }
498
+
499
+ emitPrintError(errorCode: number, printState = 0): void {
500
+ this.printState.callback?.onError(errorCode, printState);
501
+ }
502
+
503
+ emitBufferFree(pageIndex: number, bufferSize: number): void {
504
+ this.printState.callback?.onBufferFree(pageIndex, bufferSize);
505
+ }
506
+
507
+ emitCancel(success: boolean): void {
508
+ this.printState.callback?.onCancelJob(success);
509
+ }
510
+
511
+ setConnectionResult(result: number): void {
512
+ this.connectionResult = result;
513
+ }
514
+
515
+ setWifiConfigurationResult(result: number): void {
516
+ this.wifiConfigurationResult = result;
517
+ }
518
+
519
+ setShutdownResult(result: number): void {
520
+ this.shutdownResult = result;
521
+ }
522
+ }
523
+
524
+ export function createMemoryPrinterTransport(): MemoryPrinterTransport {
525
+ return new MemoryPrinterTransport();
526
+ }