@happenv/print-agent-sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/index.cjs +80 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -18
- package/dist/index.d.ts +65 -18
- package/dist/index.js +77 -21
- package/dist/index.js.map +1 -1
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @happenv/print-agent-sdk
|
|
|
14
14
|
```ts
|
|
15
15
|
import { PrintAgent } from "@happenv/print-agent-sdk";
|
|
16
16
|
|
|
17
|
-
const agent = new PrintAgent({ port: 45123 }); // wss://localhost:45123/ws
|
|
17
|
+
const agent = new PrintAgent({ port: 45123, lang: "en" }); // wss://localhost:45123/ws
|
|
18
18
|
|
|
19
19
|
agent.onStatusChange((s) => console.log("status:", s));
|
|
20
20
|
|
|
@@ -34,7 +34,8 @@ agent.disconnect();
|
|
|
34
34
|
|
|
35
35
|
## API
|
|
36
36
|
|
|
37
|
-
- `new PrintAgent(options)` — `{ host?, port?, url?, autoReconnect?, requestTimeoutMs?, WebSocket? }`
|
|
37
|
+
- `new PrintAgent(options)` — `{ host?, port?, url?, autoReconnect?, requestTimeoutMs?, WebSocket?, lang? }`
|
|
38
|
+
- `lang` — language of SDK error messages: `"en"` (default) or `"pl"`.
|
|
38
39
|
- `connect()` / `disconnect()`
|
|
39
40
|
- `status` / `isConnected()` / `onStatusChange(cb)` — status: `connecting | open | closed`
|
|
40
41
|
- `getPrinters()` → `{ name, default }[]`
|
|
@@ -44,6 +45,20 @@ agent.disconnect();
|
|
|
44
45
|
|
|
45
46
|
Errors: `NotConnectedError`, `TimeoutError`, `AgentError`.
|
|
46
47
|
|
|
48
|
+
### Localization
|
|
49
|
+
|
|
50
|
+
SDK-generated error messages are localized. Pass `lang` to pick the catalog
|
|
51
|
+
(default `"en"`):
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const agent = new PrintAgent({ port: 45123, lang: "pl" });
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Catalogs live in `src/locales/` (`en.ts`, `pl.ts`) and are exported for
|
|
58
|
+
inspection or reuse: `import { locales, getMessages, type Lang, type Messages } from "@happenv/print-agent-sdk"`.
|
|
59
|
+
Note: error text returned by the agent itself (`AgentError`) is passed through
|
|
60
|
+
as-is and is not translated by the SDK.
|
|
61
|
+
|
|
47
62
|
## Notes
|
|
48
63
|
|
|
49
64
|
- The SDK connects over `wss` using a certificate signed by the product's local
|
package/dist/index.cjs
CHANGED
|
@@ -23,30 +23,66 @@ __export(index_exports, {
|
|
|
23
23
|
AgentError: () => AgentError,
|
|
24
24
|
NotConnectedError: () => NotConnectedError,
|
|
25
25
|
PrintAgent: () => PrintAgent,
|
|
26
|
-
TimeoutError: () => TimeoutError
|
|
26
|
+
TimeoutError: () => TimeoutError,
|
|
27
|
+
getMessages: () => getMessages,
|
|
28
|
+
locales: () => locales
|
|
27
29
|
});
|
|
28
30
|
module.exports = __toCommonJS(index_exports);
|
|
29
31
|
|
|
30
32
|
// src/types.ts
|
|
31
33
|
var NotConnectedError = class extends Error {
|
|
32
|
-
constructor(message = "
|
|
34
|
+
constructor(message = "no connection to the agent") {
|
|
33
35
|
super(message);
|
|
34
36
|
this.name = "NotConnectedError";
|
|
35
37
|
}
|
|
36
38
|
};
|
|
37
39
|
var TimeoutError = class extends Error {
|
|
38
|
-
constructor(message = "
|
|
40
|
+
constructor(message = "timed out waiting for the agent") {
|
|
39
41
|
super(message);
|
|
40
42
|
this.name = "TimeoutError";
|
|
41
43
|
}
|
|
42
44
|
};
|
|
43
45
|
var AgentError = class extends Error {
|
|
44
|
-
constructor(message = "
|
|
46
|
+
constructor(message = "agent error") {
|
|
45
47
|
super(message);
|
|
46
48
|
this.name = "AgentError";
|
|
47
49
|
}
|
|
48
50
|
};
|
|
49
51
|
|
|
52
|
+
// src/locales/en.ts
|
|
53
|
+
var en = {
|
|
54
|
+
notConnected: "no connection to the agent",
|
|
55
|
+
connectionClosed: "connection closed",
|
|
56
|
+
connectFailed: "could not connect to the agent",
|
|
57
|
+
timeout: "timed out waiting for the agent's response",
|
|
58
|
+
connectTimeout: "timed out connecting to the agent",
|
|
59
|
+
agentError: "agent error",
|
|
60
|
+
noWebSocket: "no WebSocket implementation (pass the WebSocket option)",
|
|
61
|
+
printNoPrinter: "print: printer name is required (printer)",
|
|
62
|
+
printSource: "print: provide exactly one source \u2014 url or base64",
|
|
63
|
+
printNoUrls: "printBatch: at least one url is required (urls)"
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/locales/pl.ts
|
|
67
|
+
var pl = {
|
|
68
|
+
notConnected: "brak po\u0142\u0105czenia z agentem",
|
|
69
|
+
connectionClosed: "po\u0142\u0105czenie zamkni\u0119te",
|
|
70
|
+
connectFailed: "nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z agentem",
|
|
71
|
+
timeout: "przekroczono czas oczekiwania na odpowied\u017A agenta",
|
|
72
|
+
connectTimeout: "przekroczono czas \u0142\u0105czenia z agentem",
|
|
73
|
+
agentError: "b\u0142\u0105d agenta",
|
|
74
|
+
noWebSocket: "brak implementacji WebSocket (przeka\u017C opcj\u0119 WebSocket)",
|
|
75
|
+
printNoPrinter: "print: wymagana nazwa drukarki (printer)",
|
|
76
|
+
printSource: "print: podaj dok\u0142adnie jedno \u017Ar\xF3d\u0142o \u2014 url albo base64",
|
|
77
|
+
printNoUrls: "printBatch: wymagany co najmniej jeden url (urls)"
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/locales/index.ts
|
|
81
|
+
var locales = { en, pl };
|
|
82
|
+
function getMessages(lang = "en") {
|
|
83
|
+
return locales[lang] ?? en;
|
|
84
|
+
}
|
|
85
|
+
|
|
50
86
|
// src/client.ts
|
|
51
87
|
var RECONNECT_BACKOFF_MS = [1e3, 2e3, 5e3, 1e4];
|
|
52
88
|
var PrintAgent = class {
|
|
@@ -57,6 +93,7 @@ var PrintAgent = class {
|
|
|
57
93
|
this.idCounter = 0;
|
|
58
94
|
this.wantConnected = false;
|
|
59
95
|
this.reconnectAttempt = 0;
|
|
96
|
+
this.t = getMessages(opts.lang);
|
|
60
97
|
const host = opts.host ?? "localhost";
|
|
61
98
|
const port = opts.port ?? 45123;
|
|
62
99
|
this.url = opts.url ?? `wss://${host}:${port}/ws`;
|
|
@@ -64,7 +101,7 @@ var PrintAgent = class {
|
|
|
64
101
|
this.requestTimeoutMs = opts.requestTimeoutMs ?? 1e4;
|
|
65
102
|
const ctor = opts.WebSocket ?? globalThis.WebSocket;
|
|
66
103
|
if (!ctor) {
|
|
67
|
-
throw new Error(
|
|
104
|
+
throw new Error(this.t.noWebSocket);
|
|
68
105
|
}
|
|
69
106
|
this.WS = ctor;
|
|
70
107
|
}
|
|
@@ -74,13 +111,13 @@ var PrintAgent = class {
|
|
|
74
111
|
isConnected() {
|
|
75
112
|
return this._status === "open";
|
|
76
113
|
}
|
|
77
|
-
/**
|
|
114
|
+
/** Registers a status-change listener; returns an unsubscribe function. */
|
|
78
115
|
onStatusChange(cb) {
|
|
79
116
|
this.statusListeners.add(cb);
|
|
80
117
|
return () => this.statusListeners.delete(cb);
|
|
81
118
|
}
|
|
82
|
-
/**
|
|
83
|
-
*
|
|
119
|
+
/** Connects to the agent; resolves on open, rejects on timeout/failure.
|
|
120
|
+
* Idempotent when the connection is already open. */
|
|
84
121
|
connect() {
|
|
85
122
|
this.wantConnected = true;
|
|
86
123
|
if (this._status === "open") {
|
|
@@ -90,7 +127,7 @@ var PrintAgent = class {
|
|
|
90
127
|
this.openSocket(resolve, reject);
|
|
91
128
|
});
|
|
92
129
|
}
|
|
93
|
-
/**
|
|
130
|
+
/** Closes the connection and disables auto-reconnect. */
|
|
94
131
|
disconnect() {
|
|
95
132
|
this.wantConnected = false;
|
|
96
133
|
if (this.reconnectTimer) {
|
|
@@ -101,25 +138,25 @@ var PrintAgent = class {
|
|
|
101
138
|
this.ws.close();
|
|
102
139
|
}
|
|
103
140
|
}
|
|
104
|
-
/**
|
|
141
|
+
/** List of printers installed on the client's system. */
|
|
105
142
|
async getPrinters() {
|
|
106
143
|
const r = await this.request({ type: "listPrinters" });
|
|
107
144
|
return r.printers ?? [];
|
|
108
145
|
}
|
|
109
|
-
/**
|
|
146
|
+
/** Agent brand and version. */
|
|
110
147
|
async getVersion() {
|
|
111
148
|
const r = await this.request({ type: "version" });
|
|
112
149
|
return { brand: r.brand ?? "", version: r.version ?? "" };
|
|
113
150
|
}
|
|
114
|
-
/**
|
|
151
|
+
/** Sends a PDF print job; resolves once the agent confirms. */
|
|
115
152
|
async print(opts) {
|
|
116
153
|
if (!opts || !opts.printer) {
|
|
117
|
-
throw new Error(
|
|
154
|
+
throw new Error(this.t.printNoPrinter);
|
|
118
155
|
}
|
|
119
156
|
const hasUrl = typeof opts.url === "string" && opts.url.length > 0;
|
|
120
157
|
const hasB64 = typeof opts.base64 === "string" && opts.base64.length > 0;
|
|
121
158
|
if (hasUrl === hasB64) {
|
|
122
|
-
throw new Error(
|
|
159
|
+
throw new Error(this.t.printSource);
|
|
123
160
|
}
|
|
124
161
|
const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };
|
|
125
162
|
await this.request({
|
|
@@ -129,7 +166,26 @@ var PrintAgent = class {
|
|
|
129
166
|
copies: opts.copies
|
|
130
167
|
});
|
|
131
168
|
}
|
|
132
|
-
|
|
169
|
+
/** Sends a batch of label PDFs as a SINGLE merged print job.
|
|
170
|
+
* The agent fetches all URLs, merges them (each label repeated `copies`
|
|
171
|
+
* times) and sends one job to the spooler — avoiding the printer's pauses
|
|
172
|
+
* between separate jobs. Resolves once the agent has accepted the batch. */
|
|
173
|
+
async printBatch(opts) {
|
|
174
|
+
if (!opts || !opts.printer) {
|
|
175
|
+
throw new Error(this.t.printNoPrinter);
|
|
176
|
+
}
|
|
177
|
+
if (!Array.isArray(opts.urls) || opts.urls.length === 0) {
|
|
178
|
+
throw new Error(this.t.printNoUrls);
|
|
179
|
+
}
|
|
180
|
+
const pdfs = opts.urls.map((url) => ({ url }));
|
|
181
|
+
await this.request({
|
|
182
|
+
type: "printBatch",
|
|
183
|
+
printer: opts.printer,
|
|
184
|
+
pdfs,
|
|
185
|
+
copies: opts.copies
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// --- internal ---
|
|
133
189
|
openSocket(onOpen, onFail) {
|
|
134
190
|
this.setStatus("connecting");
|
|
135
191
|
let settled = false;
|
|
@@ -142,7 +198,7 @@ var PrintAgent = class {
|
|
|
142
198
|
ws.close();
|
|
143
199
|
} catch {
|
|
144
200
|
}
|
|
145
|
-
onFail?.(new TimeoutError(
|
|
201
|
+
onFail?.(new TimeoutError(this.t.connectTimeout));
|
|
146
202
|
}
|
|
147
203
|
}, this.requestTimeoutMs);
|
|
148
204
|
ws.onopen = () => {
|
|
@@ -159,10 +215,10 @@ var PrintAgent = class {
|
|
|
159
215
|
clearTimeout(connectTimer);
|
|
160
216
|
this.ws = void 0;
|
|
161
217
|
this.setStatus("closed");
|
|
162
|
-
this.rejectAllPending(new NotConnectedError(
|
|
218
|
+
this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));
|
|
163
219
|
if (!settled) {
|
|
164
220
|
settled = true;
|
|
165
|
-
onFail?.(new NotConnectedError(
|
|
221
|
+
onFail?.(new NotConnectedError(this.t.connectFailed));
|
|
166
222
|
}
|
|
167
223
|
if (this.wantConnected && this.autoReconnect) {
|
|
168
224
|
this.scheduleReconnect();
|
|
@@ -195,19 +251,19 @@ var PrintAgent = class {
|
|
|
195
251
|
if (msg.ok) {
|
|
196
252
|
p.resolve(msg);
|
|
197
253
|
} else {
|
|
198
|
-
p.reject(new AgentError(msg.error ||
|
|
254
|
+
p.reject(new AgentError(msg.error || this.t.agentError));
|
|
199
255
|
}
|
|
200
256
|
}
|
|
201
257
|
request(payload) {
|
|
202
258
|
if (!this.isConnected() || !this.ws) {
|
|
203
|
-
return Promise.reject(new NotConnectedError());
|
|
259
|
+
return Promise.reject(new NotConnectedError(this.t.notConnected));
|
|
204
260
|
}
|
|
205
261
|
const id = String(++this.idCounter);
|
|
206
262
|
const ws = this.ws;
|
|
207
263
|
return new Promise((resolve, reject) => {
|
|
208
264
|
const timer = setTimeout(() => {
|
|
209
265
|
this.pending.delete(id);
|
|
210
|
-
reject(new TimeoutError());
|
|
266
|
+
reject(new TimeoutError(this.t.timeout));
|
|
211
267
|
}, this.requestTimeoutMs);
|
|
212
268
|
this.pending.set(id, { resolve, reject, timer });
|
|
213
269
|
try {
|
|
@@ -239,6 +295,8 @@ var PrintAgent = class {
|
|
|
239
295
|
AgentError,
|
|
240
296
|
NotConnectedError,
|
|
241
297
|
PrintAgent,
|
|
242
|
-
TimeoutError
|
|
298
|
+
TimeoutError,
|
|
299
|
+
getMessages,
|
|
300
|
+
locales
|
|
243
301
|
});
|
|
244
302
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/client.ts"],"sourcesContent":["export { PrintAgent } from \"./client\";\nexport {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type Printer,\n type PrintAgentOptions,\n type PrintOptions,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\n","/** Status połączenia z lokalnym agentem. */\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"closed\";\n\n/** Drukarka zwrócona przez agenta. */\nexport interface Printer {\n name: string;\n default: boolean;\n}\n\n/** Wersja agenta. */\nexport interface AgentVersion {\n brand: string;\n version: string;\n}\n\n/** Parametry zadania druku. Dokładnie jedno ze źródeł: url albo base64. */\nexport interface PrintOptions {\n printer: string;\n url?: string;\n base64?: string;\n copies?: number;\n}\n\n/** Opcje konstruktora PrintAgent. */\nexport interface PrintAgentOptions {\n host?: string;\n port?: number;\n url?: string;\n autoReconnect?: boolean;\n requestTimeoutMs?: number;\n WebSocket?: WebSocketCtor;\n}\n\n/** Minimalny interfejs WebSocket używany przez SDK (zgodny z przeglądarką i pakietem ws). */\nexport interface WebSocketLike {\n send(data: string): void;\n close(): void;\n onopen: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n}\n\nexport interface WebSocketCtor {\n new (url: string): WebSocketLike;\n}\n\n/** Brak aktywnego połączenia z agentem. */\nexport class NotConnectedError extends Error {\n constructor(message = \"brak połączenia z agentem\") {\n super(message);\n this.name = \"NotConnectedError\";\n }\n}\n\n/** Przekroczono czas oczekiwania na odpowiedź agenta. */\nexport class TimeoutError extends Error {\n constructor(message = \"przekroczono czas oczekiwania na odpowiedź agenta\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/** Agent odpowiedział błędem (ok:false). */\nexport class AgentError extends Error {\n constructor(message = \"błąd agenta\") {\n super(message);\n this.name = \"AgentError\";\n }\n}\n","import {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type PrintAgentOptions,\n type PrintOptions,\n type Printer,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\n\ninterface AgentResponse {\n type: string;\n id?: string;\n ok: boolean;\n error?: string;\n printers?: Printer[];\n brand?: string;\n version?: string;\n}\n\ninterface Pending {\n resolve: (r: AgentResponse) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst RECONNECT_BACKOFF_MS = [1000, 2000, 5000, 10000];\n\n/** Klient lokalnego agenta druku. */\nexport class PrintAgent {\n private readonly url: string;\n private readonly autoReconnect: boolean;\n private readonly requestTimeoutMs: number;\n private readonly WS: WebSocketCtor;\n\n private ws?: WebSocketLike;\n private _status: ConnectionStatus = \"closed\";\n private statusListeners = new Set<(s: ConnectionStatus) => void>();\n private pending = new Map<string, Pending>();\n private idCounter = 0;\n private wantConnected = false;\n private reconnectAttempt = 0;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: PrintAgentOptions = {}) {\n const host = opts.host ?? \"localhost\";\n const port = opts.port ?? 45123;\n this.url = opts.url ?? `wss://${host}:${port}/ws`;\n this.autoReconnect = opts.autoReconnect ?? true;\n this.requestTimeoutMs = opts.requestTimeoutMs ?? 10000;\n const ctor = opts.WebSocket ?? (globalThis as { WebSocket?: WebSocketCtor }).WebSocket;\n if (!ctor) {\n throw new Error(\"brak implementacji WebSocket (przekaż opcję WebSocket)\");\n }\n this.WS = ctor;\n }\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n isConnected(): boolean {\n return this._status === \"open\";\n }\n\n /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */\n onStatusChange(cb: (s: ConnectionStatus) => void): () => void {\n this.statusListeners.add(cb);\n return () => this.statusListeners.delete(cb);\n }\n\n /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.\n * Idempotentne, gdy połączenie jest już otwarte. */\n connect(): Promise<void> {\n this.wantConnected = true;\n if (this._status === \"open\") {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n this.openSocket(resolve, reject);\n });\n }\n\n /** Zamyka połączenie i wyłącza auto-reconnect. */\n disconnect(): void {\n this.wantConnected = false;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n if (this.ws) {\n this.ws.close();\n }\n }\n\n /** Lista drukarek zainstalowanych w systemie klienta. */\n async getPrinters(): Promise<Printer[]> {\n const r = await this.request({ type: \"listPrinters\" });\n return r.printers ?? [];\n }\n\n /** Wersja i brand agenta. */\n async getVersion(): Promise<AgentVersion> {\n const r = await this.request({ type: \"version\" });\n return { brand: r.brand ?? \"\", version: r.version ?? \"\" };\n }\n\n /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */\n async print(opts: PrintOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(\"print: wymagana nazwa drukarki (printer)\");\n }\n const hasUrl = typeof opts.url === \"string\" && opts.url.length > 0;\n const hasB64 = typeof opts.base64 === \"string\" && opts.base64.length > 0;\n if (hasUrl === hasB64) {\n throw new Error(\"print: podaj dokładnie jedno źródło — url albo base64\");\n }\n const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };\n await this.request({\n type: \"printPDF\",\n printer: opts.printer,\n pdf,\n copies: opts.copies,\n });\n }\n\n // --- wewnętrzne ---\n\n private openSocket(\n onOpen?: () => void,\n onFail?: (e: Error) => void\n ): void {\n this.setStatus(\"connecting\");\n let settled = false;\n const ws = new this.WS(this.url);\n this.ws = ws;\n\n const connectTimer = setTimeout(() => {\n if (!settled) {\n settled = true;\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n onFail?.(new TimeoutError(\"przekroczono czas łączenia z agentem\"));\n }\n }, this.requestTimeoutMs);\n\n ws.onopen = () => {\n settled = true;\n clearTimeout(connectTimer);\n this.reconnectAttempt = 0;\n this.setStatus(\"open\");\n onOpen?.();\n };\n ws.onmessage = (ev) => this.handleMessage(ev.data);\n ws.onerror = () => {\n /* po błędzie nastąpi onclose */\n };\n ws.onclose = () => {\n clearTimeout(connectTimer);\n this.ws = undefined;\n this.setStatus(\"closed\");\n this.rejectAllPending(new NotConnectedError(\"połączenie zamknięte\"));\n if (!settled) {\n settled = true;\n onFail?.(new NotConnectedError(\"nie udało się połączyć z agentem\"));\n }\n if (this.wantConnected && this.autoReconnect) {\n this.scheduleReconnect();\n }\n };\n }\n\n private scheduleReconnect(): void {\n const delay =\n RECONNECT_BACKOFF_MS[Math.min(this.reconnectAttempt, RECONNECT_BACKOFF_MS.length - 1)];\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n if (this.wantConnected) {\n this.openSocket();\n }\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n const text = typeof data === \"string\" ? data : String(data);\n let msg: AgentResponse;\n try {\n msg = JSON.parse(text);\n } catch {\n return;\n }\n const id = msg.id;\n if (!id) return;\n const p = this.pending.get(id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(id);\n if (msg.ok) {\n p.resolve(msg);\n } else {\n p.reject(new AgentError(msg.error || \"błąd agenta\"));\n }\n }\n\n private request(payload: Record<string, unknown>): Promise<AgentResponse> {\n if (!this.isConnected() || !this.ws) {\n return Promise.reject(new NotConnectedError());\n }\n const id = String(++this.idCounter);\n const ws = this.ws;\n return new Promise<AgentResponse>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new TimeoutError());\n }, this.requestTimeoutMs);\n this.pending.set(id, { resolve, reject, timer });\n try {\n ws.send(JSON.stringify({ ...payload, id }));\n } catch (e) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(e instanceof Error ? e : new Error(String(e)));\n }\n });\n }\n\n private rejectAllPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private setStatus(s: ConnectionStatus): void {\n if (this._status === s) return;\n this._status = s;\n for (const cb of this.statusListeners) {\n cb(s);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgDO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,UAAU,uCAA6B;AACjD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,UAAU,0DAAqD;AACzE,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YAAY,UAAU,yBAAe;AACnC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;ACxCA,IAAM,uBAAuB,CAAC,KAAM,KAAM,KAAM,GAAK;AAG9C,IAAM,aAAN,MAAiB;AAAA,EAetB,YAAY,OAA0B,CAAC,GAAG;AAR1C,SAAQ,UAA4B;AACpC,SAAQ,kBAAkB,oBAAI,IAAmC;AACjE,SAAQ,UAAU,oBAAI,IAAqB;AAC3C,SAAQ,YAAY;AACpB,SAAQ,gBAAgB;AACxB,SAAQ,mBAAmB;AAIzB,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,OAAO,KAAK,QAAQ;AAC1B,SAAK,MAAM,KAAK,OAAO,SAAS,IAAI,IAAI,IAAI;AAC5C,SAAK,gBAAgB,KAAK,iBAAiB;AAC3C,SAAK,mBAAmB,KAAK,oBAAoB;AACjD,UAAM,OAAO,KAAK,aAAc,WAA6C;AAC7E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,kEAAwD;AAAA,IAC1E;AACA,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,IAAI,SAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA,EAGA,eAAe,IAA+C;AAC5D,SAAK,gBAAgB,IAAI,EAAE;AAC3B,WAAO,MAAM,KAAK,gBAAgB,OAAO,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA,EAIA,UAAyB;AACvB,SAAK,gBAAgB;AACrB,QAAI,KAAK,YAAY,QAAQ;AAC3B,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAK,WAAW,SAAS,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,gBAAgB;AACrB,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AAAA,IAChB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cAAkC;AACtC,UAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,WAAO,EAAE,YAAY,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,aAAoC;AACxC,UAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAChD,WAAO,EAAE,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE,WAAW,GAAG;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,MAAM,MAAmC;AAC7C,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAS;AAC1B,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AACA,UAAM,SAAS,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,SAAS;AACjE,UAAM,SAAS,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,SAAS;AACvE,QAAI,WAAW,QAAQ;AACrB,YAAM,IAAI,MAAM,8EAAuD;AAAA,IACzE;AACA,UAAM,MAAM,SAAS,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,QAAQ,KAAK,OAAO;AAC/D,UAAM,KAAK,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,MACd;AAAA,MACA,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,WACN,QACA,QACM;AACN,SAAK,UAAU,YAAY;AAC3B,QAAI,UAAU;AACd,UAAM,KAAK,IAAI,KAAK,GAAG,KAAK,GAAG;AAC/B,SAAK,KAAK;AAEV,UAAM,eAAe,WAAW,MAAM;AACpC,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,YAAI;AACF,aAAG,MAAM;AAAA,QACX,QAAQ;AAAA,QAER;AACA,iBAAS,IAAI,aAAa,gDAAsC,CAAC;AAAA,MACnE;AAAA,IACF,GAAG,KAAK,gBAAgB;AAExB,OAAG,SAAS,MAAM;AAChB,gBAAU;AACV,mBAAa,YAAY;AACzB,WAAK,mBAAmB;AACxB,WAAK,UAAU,MAAM;AACrB,eAAS;AAAA,IACX;AACA,OAAG,YAAY,CAAC,OAAO,KAAK,cAAc,GAAG,IAAI;AACjD,OAAG,UAAU,MAAM;AAAA,IAEnB;AACA,OAAG,UAAU,MAAM;AACjB,mBAAa,YAAY;AACzB,WAAK,KAAK;AACV,WAAK,UAAU,QAAQ;AACvB,WAAK,iBAAiB,IAAI,kBAAkB,qCAAsB,CAAC;AACnE,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,iBAAS,IAAI,kBAAkB,2DAAkC,CAAC;AAAA,MACpE;AACA,UAAI,KAAK,iBAAiB,KAAK,eAAe;AAC5C,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,UAAM,QACJ,qBAAqB,KAAK,IAAI,KAAK,kBAAkB,qBAAqB,SAAS,CAAC,CAAC;AACvF,SAAK;AACL,SAAK,iBAAiB,WAAW,MAAM;AACrC,UAAI,KAAK,eAAe;AACtB,aAAK,WAAW;AAAA,MAClB;AAAA,IACF,GAAG,KAAK;AAAA,EACV;AAAA,EAEQ,cAAc,MAAqB;AACzC,UAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO,IAAI;AAC1D,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,IAAI;AAAA,IACvB,QAAQ;AACN;AAAA,IACF;AACA,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,UAAM,IAAI,KAAK,QAAQ,IAAI,EAAE;AAC7B,QAAI,CAAC,EAAG;AACR,iBAAa,EAAE,KAAK;AACpB,SAAK,QAAQ,OAAO,EAAE;AACtB,QAAI,IAAI,IAAI;AACV,QAAE,QAAQ,GAAG;AAAA,IACf,OAAO;AACL,QAAE,OAAO,IAAI,WAAW,IAAI,SAAS,uBAAa,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEQ,QAAQ,SAA0D;AACxE,QAAI,CAAC,KAAK,YAAY,KAAK,CAAC,KAAK,IAAI;AACnC,aAAO,QAAQ,OAAO,IAAI,kBAAkB,CAAC;AAAA,IAC/C;AACA,UAAM,KAAK,OAAO,EAAE,KAAK,SAAS;AAClC,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,QAAuB,CAAC,SAAS,WAAW;AACrD,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,QAAQ,OAAO,EAAE;AACtB,eAAO,IAAI,aAAa,CAAC;AAAA,MAC3B,GAAG,KAAK,gBAAgB;AACxB,WAAK,QAAQ,IAAI,IAAI,EAAE,SAAS,QAAQ,MAAM,CAAC;AAC/C,UAAI;AACF,WAAG,KAAK,KAAK,UAAU,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC;AAAA,MAC5C,SAAS,GAAG;AACV,qBAAa,KAAK;AAClB,aAAK,QAAQ,OAAO,EAAE;AACtB,eAAO,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,KAAkB;AACzC,eAAW,CAAC,EAAE,CAAC,KAAK,KAAK,SAAS;AAChC,mBAAa,EAAE,KAAK;AACpB,QAAE,OAAO,GAAG;AAAA,IACd;AACA,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEQ,UAAU,GAA2B;AAC3C,QAAI,KAAK,YAAY,EAAG;AACxB,SAAK,UAAU;AACf,eAAW,MAAM,KAAK,iBAAiB;AACrC,SAAG,CAAC;AAAA,IACN;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/locales/en.ts","../src/locales/pl.ts","../src/locales/index.ts","../src/client.ts"],"sourcesContent":["export { PrintAgent } from \"./client\";\nexport {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type Printer,\n type PrintAgentOptions,\n type PrintOptions,\n type PrintBatchOptions,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\nexport { locales, getMessages, type Lang, type Messages } from \"./locales\";\n","import type { Lang } from \"./locales\";\n\n/** Connection status with the local agent. */\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"closed\";\n\n/** A printer returned by the agent. */\nexport interface Printer {\n name: string;\n default: boolean;\n}\n\n/** Agent version. */\nexport interface AgentVersion {\n brand: string;\n version: string;\n}\n\n/** Print job parameters. Provide exactly one source: url or base64. */\nexport interface PrintOptions {\n printer: string;\n url?: string;\n base64?: string;\n copies?: number;\n}\n\n/** Batch print parameters: many label PDFs merged into a single print job. */\nexport interface PrintBatchOptions {\n printer: string;\n /** PDF URLs, printed in this order as one merged job. */\n urls: string[];\n /** Copies of each label (each label is repeated this many times). */\n copies?: number;\n}\n\n/** PrintAgent constructor options. */\nexport interface PrintAgentOptions {\n host?: string;\n port?: number;\n url?: string;\n autoReconnect?: boolean;\n requestTimeoutMs?: number;\n WebSocket?: WebSocketCtor;\n /** Language of SDK error messages; defaults to \"en\". */\n lang?: Lang;\n}\n\n/** Minimal WebSocket interface used by the SDK (compatible with the browser and the ws package). */\nexport interface WebSocketLike {\n send(data: string): void;\n close(): void;\n onopen: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n}\n\nexport interface WebSocketCtor {\n new (url: string): WebSocketLike;\n}\n\n/** No active connection to the agent. (Message is localized by the client.) */\nexport class NotConnectedError extends Error {\n constructor(message = \"no connection to the agent\") {\n super(message);\n this.name = \"NotConnectedError\";\n }\n}\n\n/** Timed out waiting for the agent. (Message is localized by the client.) */\nexport class TimeoutError extends Error {\n constructor(message = \"timed out waiting for the agent\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/** The agent responded with an error (ok:false). */\nexport class AgentError extends Error {\n constructor(message = \"agent error\") {\n super(message);\n this.name = \"AgentError\";\n }\n}\n","import type { Messages } from \"./types\";\n\n/** English message catalog (default). */\nexport const en: Messages = {\n notConnected: \"no connection to the agent\",\n connectionClosed: \"connection closed\",\n connectFailed: \"could not connect to the agent\",\n timeout: \"timed out waiting for the agent's response\",\n connectTimeout: \"timed out connecting to the agent\",\n agentError: \"agent error\",\n noWebSocket: \"no WebSocket implementation (pass the WebSocket option)\",\n printNoPrinter: \"print: printer name is required (printer)\",\n printSource: \"print: provide exactly one source — url or base64\",\n printNoUrls: \"printBatch: at least one url is required (urls)\",\n};\n","import type { Messages } from \"./types\";\n\n/** Polish message catalog. */\nexport const pl: Messages = {\n notConnected: \"brak połączenia z agentem\",\n connectionClosed: \"połączenie zamknięte\",\n connectFailed: \"nie udało się połączyć z agentem\",\n timeout: \"przekroczono czas oczekiwania na odpowiedź agenta\",\n connectTimeout: \"przekroczono czas łączenia z agentem\",\n agentError: \"błąd agenta\",\n noWebSocket: \"brak implementacji WebSocket (przekaż opcję WebSocket)\",\n printNoPrinter: \"print: wymagana nazwa drukarki (printer)\",\n printSource: \"print: podaj dokładnie jedno źródło — url albo base64\",\n printNoUrls: \"printBatch: wymagany co najmniej jeden url (urls)\",\n};\n","import { en } from \"./en\";\nimport { pl } from \"./pl\";\nimport type { Lang, Messages } from \"./types\";\n\nexport type { Lang, Messages };\n\n/** All available message catalogs keyed by language. */\nexport const locales: Record<Lang, Messages> = { en, pl };\n\n/** Returns the message catalog for the given language (defaults to English). */\nexport function getMessages(lang: Lang = \"en\"): Messages {\n return locales[lang] ?? en;\n}\n","import {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type PrintAgentOptions,\n type PrintBatchOptions,\n type PrintOptions,\n type Printer,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\nimport { getMessages, type Messages } from \"./locales\";\n\ninterface AgentResponse {\n type: string;\n id?: string;\n ok: boolean;\n error?: string;\n printers?: Printer[];\n brand?: string;\n version?: string;\n}\n\ninterface Pending {\n resolve: (r: AgentResponse) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst RECONNECT_BACKOFF_MS = [1000, 2000, 5000, 10000];\n\n/** Client for the local print agent. */\nexport class PrintAgent {\n private readonly url: string;\n private readonly autoReconnect: boolean;\n private readonly requestTimeoutMs: number;\n private readonly WS: WebSocketCtor;\n private readonly t: Messages;\n\n private ws?: WebSocketLike;\n private _status: ConnectionStatus = \"closed\";\n private statusListeners = new Set<(s: ConnectionStatus) => void>();\n private pending = new Map<string, Pending>();\n private idCounter = 0;\n private wantConnected = false;\n private reconnectAttempt = 0;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: PrintAgentOptions = {}) {\n this.t = getMessages(opts.lang);\n const host = opts.host ?? \"localhost\";\n const port = opts.port ?? 45123;\n this.url = opts.url ?? `wss://${host}:${port}/ws`;\n this.autoReconnect = opts.autoReconnect ?? true;\n this.requestTimeoutMs = opts.requestTimeoutMs ?? 10000;\n const ctor = opts.WebSocket ?? (globalThis as { WebSocket?: WebSocketCtor }).WebSocket;\n if (!ctor) {\n throw new Error(this.t.noWebSocket);\n }\n this.WS = ctor;\n }\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n isConnected(): boolean {\n return this._status === \"open\";\n }\n\n /** Registers a status-change listener; returns an unsubscribe function. */\n onStatusChange(cb: (s: ConnectionStatus) => void): () => void {\n this.statusListeners.add(cb);\n return () => this.statusListeners.delete(cb);\n }\n\n /** Connects to the agent; resolves on open, rejects on timeout/failure.\n * Idempotent when the connection is already open. */\n connect(): Promise<void> {\n this.wantConnected = true;\n if (this._status === \"open\") {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n this.openSocket(resolve, reject);\n });\n }\n\n /** Closes the connection and disables auto-reconnect. */\n disconnect(): void {\n this.wantConnected = false;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n if (this.ws) {\n this.ws.close();\n }\n }\n\n /** List of printers installed on the client's system. */\n async getPrinters(): Promise<Printer[]> {\n const r = await this.request({ type: \"listPrinters\" });\n return r.printers ?? [];\n }\n\n /** Agent brand and version. */\n async getVersion(): Promise<AgentVersion> {\n const r = await this.request({ type: \"version\" });\n return { brand: r.brand ?? \"\", version: r.version ?? \"\" };\n }\n\n /** Sends a PDF print job; resolves once the agent confirms. */\n async print(opts: PrintOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(this.t.printNoPrinter);\n }\n const hasUrl = typeof opts.url === \"string\" && opts.url.length > 0;\n const hasB64 = typeof opts.base64 === \"string\" && opts.base64.length > 0;\n if (hasUrl === hasB64) {\n throw new Error(this.t.printSource);\n }\n const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };\n await this.request({\n type: \"printPDF\",\n printer: opts.printer,\n pdf,\n copies: opts.copies,\n });\n }\n\n /** Sends a batch of label PDFs as a SINGLE merged print job.\n * The agent fetches all URLs, merges them (each label repeated `copies`\n * times) and sends one job to the spooler — avoiding the printer's pauses\n * between separate jobs. Resolves once the agent has accepted the batch. */\n async printBatch(opts: PrintBatchOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(this.t.printNoPrinter);\n }\n if (!Array.isArray(opts.urls) || opts.urls.length === 0) {\n throw new Error(this.t.printNoUrls);\n }\n const pdfs = opts.urls.map((url) => ({ url }));\n await this.request({\n type: \"printBatch\",\n printer: opts.printer,\n pdfs,\n copies: opts.copies,\n });\n }\n\n // --- internal ---\n\n private openSocket(\n onOpen?: () => void,\n onFail?: (e: Error) => void\n ): void {\n this.setStatus(\"connecting\");\n let settled = false;\n const ws = new this.WS(this.url);\n this.ws = ws;\n\n const connectTimer = setTimeout(() => {\n if (!settled) {\n settled = true;\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n onFail?.(new TimeoutError(this.t.connectTimeout));\n }\n }, this.requestTimeoutMs);\n\n ws.onopen = () => {\n settled = true;\n clearTimeout(connectTimer);\n this.reconnectAttempt = 0;\n this.setStatus(\"open\");\n onOpen?.();\n };\n ws.onmessage = (ev) => this.handleMessage(ev.data);\n ws.onerror = () => {\n /* onclose will follow the error */\n };\n ws.onclose = () => {\n clearTimeout(connectTimer);\n this.ws = undefined;\n this.setStatus(\"closed\");\n this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));\n if (!settled) {\n settled = true;\n onFail?.(new NotConnectedError(this.t.connectFailed));\n }\n if (this.wantConnected && this.autoReconnect) {\n this.scheduleReconnect();\n }\n };\n }\n\n private scheduleReconnect(): void {\n const delay =\n RECONNECT_BACKOFF_MS[Math.min(this.reconnectAttempt, RECONNECT_BACKOFF_MS.length - 1)];\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n if (this.wantConnected) {\n this.openSocket();\n }\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n const text = typeof data === \"string\" ? data : String(data);\n let msg: AgentResponse;\n try {\n msg = JSON.parse(text);\n } catch {\n return;\n }\n const id = msg.id;\n if (!id) return;\n const p = this.pending.get(id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(id);\n if (msg.ok) {\n p.resolve(msg);\n } else {\n p.reject(new AgentError(msg.error || this.t.agentError));\n }\n }\n\n private request(payload: Record<string, unknown>): Promise<AgentResponse> {\n if (!this.isConnected() || !this.ws) {\n return Promise.reject(new NotConnectedError(this.t.notConnected));\n }\n const id = String(++this.idCounter);\n const ws = this.ws;\n return new Promise<AgentResponse>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new TimeoutError(this.t.timeout));\n }, this.requestTimeoutMs);\n this.pending.set(id, { resolve, reject, timer });\n try {\n ws.send(JSON.stringify({ ...payload, id }));\n } catch (e) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(e instanceof Error ? e : new Error(String(e)));\n }\n });\n }\n\n private rejectAllPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private setStatus(s: ConnectionStatus): void {\n if (this._status === s) return;\n this._status = s;\n for (const cb of this.statusListeners) {\n cb(s);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC6DO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,UAAU,8BAA8B;AAClD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,UAAU,mCAAmC;AACvD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YAAY,UAAU,eAAe;AACnC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;AC/EO,IAAM,KAAe;AAAA,EAC1B,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,aAAa;AACf;;;ACXO,IAAM,KAAe;AAAA,EAC1B,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,aAAa;AACf;;;ACPO,IAAM,UAAkC,EAAE,IAAI,GAAG;AAGjD,SAAS,YAAY,OAAa,MAAgB;AACvD,SAAO,QAAQ,IAAI,KAAK;AAC1B;;;ACmBA,IAAM,uBAAuB,CAAC,KAAM,KAAM,KAAM,GAAK;AAG9C,IAAM,aAAN,MAAiB;AAAA,EAgBtB,YAAY,OAA0B,CAAC,GAAG;AAR1C,SAAQ,UAA4B;AACpC,SAAQ,kBAAkB,oBAAI,IAAmC;AACjE,SAAQ,UAAU,oBAAI,IAAqB;AAC3C,SAAQ,YAAY;AACpB,SAAQ,gBAAgB;AACxB,SAAQ,mBAAmB;AAIzB,SAAK,IAAI,YAAY,KAAK,IAAI;AAC9B,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,OAAO,KAAK,QAAQ;AAC1B,SAAK,MAAM,KAAK,OAAO,SAAS,IAAI,IAAI,IAAI;AAC5C,SAAK,gBAAgB,KAAK,iBAAiB;AAC3C,SAAK,mBAAmB,KAAK,oBAAoB;AACjD,UAAM,OAAO,KAAK,aAAc,WAA6C;AAC7E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,KAAK,EAAE,WAAW;AAAA,IACpC;AACA,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,IAAI,SAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA,EAGA,eAAe,IAA+C;AAC5D,SAAK,gBAAgB,IAAI,EAAE;AAC3B,WAAO,MAAM,KAAK,gBAAgB,OAAO,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA,EAIA,UAAyB;AACvB,SAAK,gBAAgB;AACrB,QAAI,KAAK,YAAY,QAAQ;AAC3B,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAK,WAAW,SAAS,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,gBAAgB;AACrB,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AAAA,IAChB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cAAkC;AACtC,UAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,WAAO,EAAE,YAAY,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,aAAoC;AACxC,UAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAChD,WAAO,EAAE,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE,WAAW,GAAG;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,MAAM,MAAmC;AAC7C,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAS;AAC1B,YAAM,IAAI,MAAM,KAAK,EAAE,cAAc;AAAA,IACvC;AACA,UAAM,SAAS,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,SAAS;AACjE,UAAM,SAAS,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,SAAS;AACvE,QAAI,WAAW,QAAQ;AACrB,YAAM,IAAI,MAAM,KAAK,EAAE,WAAW;AAAA,IACpC;AACA,UAAM,MAAM,SAAS,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,QAAQ,KAAK,OAAO;AAC/D,UAAM,KAAK,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,MACd;AAAA,MACA,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,MAAwC;AACvD,QAAI,CAAC,QAAQ,CAAC,KAAK,SAAS;AAC1B,YAAM,IAAI,MAAM,KAAK,EAAE,cAAc;AAAA,IACvC;AACA,QAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,KAAK,WAAW,GAAG;AACvD,YAAM,IAAI,MAAM,KAAK,EAAE,WAAW;AAAA,IACpC;AACA,UAAM,OAAO,KAAK,KAAK,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE;AAC7C,UAAM,KAAK,QAAQ;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,MACd;AAAA,MACA,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,WACN,QACA,QACM;AACN,SAAK,UAAU,YAAY;AAC3B,QAAI,UAAU;AACd,UAAM,KAAK,IAAI,KAAK,GAAG,KAAK,GAAG;AAC/B,SAAK,KAAK;AAEV,UAAM,eAAe,WAAW,MAAM;AACpC,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,YAAI;AACF,aAAG,MAAM;AAAA,QACX,QAAQ;AAAA,QAER;AACA,iBAAS,IAAI,aAAa,KAAK,EAAE,cAAc,CAAC;AAAA,MAClD;AAAA,IACF,GAAG,KAAK,gBAAgB;AAExB,OAAG,SAAS,MAAM;AAChB,gBAAU;AACV,mBAAa,YAAY;AACzB,WAAK,mBAAmB;AACxB,WAAK,UAAU,MAAM;AACrB,eAAS;AAAA,IACX;AACA,OAAG,YAAY,CAAC,OAAO,KAAK,cAAc,GAAG,IAAI;AACjD,OAAG,UAAU,MAAM;AAAA,IAEnB;AACA,OAAG,UAAU,MAAM;AACjB,mBAAa,YAAY;AACzB,WAAK,KAAK;AACV,WAAK,UAAU,QAAQ;AACvB,WAAK,iBAAiB,IAAI,kBAAkB,KAAK,EAAE,gBAAgB,CAAC;AACpE,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,iBAAS,IAAI,kBAAkB,KAAK,EAAE,aAAa,CAAC;AAAA,MACtD;AACA,UAAI,KAAK,iBAAiB,KAAK,eAAe;AAC5C,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,UAAM,QACJ,qBAAqB,KAAK,IAAI,KAAK,kBAAkB,qBAAqB,SAAS,CAAC,CAAC;AACvF,SAAK;AACL,SAAK,iBAAiB,WAAW,MAAM;AACrC,UAAI,KAAK,eAAe;AACtB,aAAK,WAAW;AAAA,MAClB;AAAA,IACF,GAAG,KAAK;AAAA,EACV;AAAA,EAEQ,cAAc,MAAqB;AACzC,UAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO,IAAI;AAC1D,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,IAAI;AAAA,IACvB,QAAQ;AACN;AAAA,IACF;AACA,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,UAAM,IAAI,KAAK,QAAQ,IAAI,EAAE;AAC7B,QAAI,CAAC,EAAG;AACR,iBAAa,EAAE,KAAK;AACpB,SAAK,QAAQ,OAAO,EAAE;AACtB,QAAI,IAAI,IAAI;AACV,QAAE,QAAQ,GAAG;AAAA,IACf,OAAO;AACL,QAAE,OAAO,IAAI,WAAW,IAAI,SAAS,KAAK,EAAE,UAAU,CAAC;AAAA,IACzD;AAAA,EACF;AAAA,EAEQ,QAAQ,SAA0D;AACxE,QAAI,CAAC,KAAK,YAAY,KAAK,CAAC,KAAK,IAAI;AACnC,aAAO,QAAQ,OAAO,IAAI,kBAAkB,KAAK,EAAE,YAAY,CAAC;AAAA,IAClE;AACA,UAAM,KAAK,OAAO,EAAE,KAAK,SAAS;AAClC,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,QAAuB,CAAC,SAAS,WAAW;AACrD,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,QAAQ,OAAO,EAAE;AACtB,eAAO,IAAI,aAAa,KAAK,EAAE,OAAO,CAAC;AAAA,MACzC,GAAG,KAAK,gBAAgB;AACxB,WAAK,QAAQ,IAAI,IAAI,EAAE,SAAS,QAAQ,MAAM,CAAC;AAC/C,UAAI;AACF,WAAG,KAAK,KAAK,UAAU,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC;AAAA,MAC5C,SAAS,GAAG;AACV,qBAAa,KAAK;AAClB,aAAK,QAAQ,OAAO,EAAE;AACtB,eAAO,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,KAAkB;AACzC,eAAW,CAAC,EAAE,CAAC,KAAK,KAAK,SAAS;AAChC,mBAAa,EAAE,KAAK;AACpB,QAAE,OAAO,GAAG;AAAA,IACd;AACA,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEQ,UAAU,GAA2B;AAC3C,QAAI,KAAK,YAAY,EAAG;AACxB,SAAK,UAAU;AACf,eAAW,MAAM,KAAK,iBAAiB;AACrC,SAAG,CAAC;AAAA,IACN;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,23 +1,62 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Supported SDK languages for user-facing messages. */
|
|
2
|
+
type Lang = "en" | "pl";
|
|
3
|
+
/** Message catalog used for SDK-generated error messages. */
|
|
4
|
+
interface Messages {
|
|
5
|
+
/** No active connection to the agent. */
|
|
6
|
+
notConnected: string;
|
|
7
|
+
/** The connection was closed. */
|
|
8
|
+
connectionClosed: string;
|
|
9
|
+
/** Initial connection attempt failed. */
|
|
10
|
+
connectFailed: string;
|
|
11
|
+
/** Request timed out waiting for a response. */
|
|
12
|
+
timeout: string;
|
|
13
|
+
/** Connection attempt timed out. */
|
|
14
|
+
connectTimeout: string;
|
|
15
|
+
/** Fallback when the agent returns an error without text. */
|
|
16
|
+
agentError: string;
|
|
17
|
+
/** No WebSocket implementation available. */
|
|
18
|
+
noWebSocket: string;
|
|
19
|
+
/** print(): printer name missing. */
|
|
20
|
+
printNoPrinter: string;
|
|
21
|
+
/** print(): wrong number of PDF sources. */
|
|
22
|
+
printSource: string;
|
|
23
|
+
/** printBatch(): empty url list. */
|
|
24
|
+
printNoUrls: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** All available message catalogs keyed by language. */
|
|
28
|
+
declare const locales: Record<Lang, Messages>;
|
|
29
|
+
/** Returns the message catalog for the given language (defaults to English). */
|
|
30
|
+
declare function getMessages(lang?: Lang): Messages;
|
|
31
|
+
|
|
32
|
+
/** Connection status with the local agent. */
|
|
2
33
|
type ConnectionStatus = "connecting" | "open" | "closed";
|
|
3
|
-
/**
|
|
34
|
+
/** A printer returned by the agent. */
|
|
4
35
|
interface Printer {
|
|
5
36
|
name: string;
|
|
6
37
|
default: boolean;
|
|
7
38
|
}
|
|
8
|
-
/**
|
|
39
|
+
/** Agent version. */
|
|
9
40
|
interface AgentVersion {
|
|
10
41
|
brand: string;
|
|
11
42
|
version: string;
|
|
12
43
|
}
|
|
13
|
-
/**
|
|
44
|
+
/** Print job parameters. Provide exactly one source: url or base64. */
|
|
14
45
|
interface PrintOptions {
|
|
15
46
|
printer: string;
|
|
16
47
|
url?: string;
|
|
17
48
|
base64?: string;
|
|
18
49
|
copies?: number;
|
|
19
50
|
}
|
|
20
|
-
/**
|
|
51
|
+
/** Batch print parameters: many label PDFs merged into a single print job. */
|
|
52
|
+
interface PrintBatchOptions {
|
|
53
|
+
printer: string;
|
|
54
|
+
/** PDF URLs, printed in this order as one merged job. */
|
|
55
|
+
urls: string[];
|
|
56
|
+
/** Copies of each label (each label is repeated this many times). */
|
|
57
|
+
copies?: number;
|
|
58
|
+
}
|
|
59
|
+
/** PrintAgent constructor options. */
|
|
21
60
|
interface PrintAgentOptions {
|
|
22
61
|
host?: string;
|
|
23
62
|
port?: number;
|
|
@@ -25,8 +64,10 @@ interface PrintAgentOptions {
|
|
|
25
64
|
autoReconnect?: boolean;
|
|
26
65
|
requestTimeoutMs?: number;
|
|
27
66
|
WebSocket?: WebSocketCtor;
|
|
67
|
+
/** Language of SDK error messages; defaults to "en". */
|
|
68
|
+
lang?: Lang;
|
|
28
69
|
}
|
|
29
|
-
/**
|
|
70
|
+
/** Minimal WebSocket interface used by the SDK (compatible with the browser and the ws package). */
|
|
30
71
|
interface WebSocketLike {
|
|
31
72
|
send(data: string): void;
|
|
32
73
|
close(): void;
|
|
@@ -40,25 +81,26 @@ interface WebSocketLike {
|
|
|
40
81
|
interface WebSocketCtor {
|
|
41
82
|
new (url: string): WebSocketLike;
|
|
42
83
|
}
|
|
43
|
-
/**
|
|
84
|
+
/** No active connection to the agent. (Message is localized by the client.) */
|
|
44
85
|
declare class NotConnectedError extends Error {
|
|
45
86
|
constructor(message?: string);
|
|
46
87
|
}
|
|
47
|
-
/**
|
|
88
|
+
/** Timed out waiting for the agent. (Message is localized by the client.) */
|
|
48
89
|
declare class TimeoutError extends Error {
|
|
49
90
|
constructor(message?: string);
|
|
50
91
|
}
|
|
51
|
-
/**
|
|
92
|
+
/** The agent responded with an error (ok:false). */
|
|
52
93
|
declare class AgentError extends Error {
|
|
53
94
|
constructor(message?: string);
|
|
54
95
|
}
|
|
55
96
|
|
|
56
|
-
/**
|
|
97
|
+
/** Client for the local print agent. */
|
|
57
98
|
declare class PrintAgent {
|
|
58
99
|
private readonly url;
|
|
59
100
|
private readonly autoReconnect;
|
|
60
101
|
private readonly requestTimeoutMs;
|
|
61
102
|
private readonly WS;
|
|
103
|
+
private readonly t;
|
|
62
104
|
private ws?;
|
|
63
105
|
private _status;
|
|
64
106
|
private statusListeners;
|
|
@@ -70,19 +112,24 @@ declare class PrintAgent {
|
|
|
70
112
|
constructor(opts?: PrintAgentOptions);
|
|
71
113
|
get status(): ConnectionStatus;
|
|
72
114
|
isConnected(): boolean;
|
|
73
|
-
/**
|
|
115
|
+
/** Registers a status-change listener; returns an unsubscribe function. */
|
|
74
116
|
onStatusChange(cb: (s: ConnectionStatus) => void): () => void;
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
117
|
+
/** Connects to the agent; resolves on open, rejects on timeout/failure.
|
|
118
|
+
* Idempotent when the connection is already open. */
|
|
77
119
|
connect(): Promise<void>;
|
|
78
|
-
/**
|
|
120
|
+
/** Closes the connection and disables auto-reconnect. */
|
|
79
121
|
disconnect(): void;
|
|
80
|
-
/**
|
|
122
|
+
/** List of printers installed on the client's system. */
|
|
81
123
|
getPrinters(): Promise<Printer[]>;
|
|
82
|
-
/**
|
|
124
|
+
/** Agent brand and version. */
|
|
83
125
|
getVersion(): Promise<AgentVersion>;
|
|
84
|
-
/**
|
|
126
|
+
/** Sends a PDF print job; resolves once the agent confirms. */
|
|
85
127
|
print(opts: PrintOptions): Promise<void>;
|
|
128
|
+
/** Sends a batch of label PDFs as a SINGLE merged print job.
|
|
129
|
+
* The agent fetches all URLs, merges them (each label repeated `copies`
|
|
130
|
+
* times) and sends one job to the spooler — avoiding the printer's pauses
|
|
131
|
+
* between separate jobs. Resolves once the agent has accepted the batch. */
|
|
132
|
+
printBatch(opts: PrintBatchOptions): Promise<void>;
|
|
86
133
|
private openSocket;
|
|
87
134
|
private scheduleReconnect;
|
|
88
135
|
private handleMessage;
|
|
@@ -91,4 +138,4 @@ declare class PrintAgent {
|
|
|
91
138
|
private setStatus;
|
|
92
139
|
}
|
|
93
140
|
|
|
94
|
-
export { AgentError, type AgentVersion, type ConnectionStatus, NotConnectedError, PrintAgent, type PrintAgentOptions, type PrintOptions, type Printer, TimeoutError, type WebSocketCtor, type WebSocketLike };
|
|
141
|
+
export { AgentError, type AgentVersion, type ConnectionStatus, type Lang, type Messages, NotConnectedError, PrintAgent, type PrintAgentOptions, type PrintBatchOptions, type PrintOptions, type Printer, TimeoutError, type WebSocketCtor, type WebSocketLike, getMessages, locales };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,62 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Supported SDK languages for user-facing messages. */
|
|
2
|
+
type Lang = "en" | "pl";
|
|
3
|
+
/** Message catalog used for SDK-generated error messages. */
|
|
4
|
+
interface Messages {
|
|
5
|
+
/** No active connection to the agent. */
|
|
6
|
+
notConnected: string;
|
|
7
|
+
/** The connection was closed. */
|
|
8
|
+
connectionClosed: string;
|
|
9
|
+
/** Initial connection attempt failed. */
|
|
10
|
+
connectFailed: string;
|
|
11
|
+
/** Request timed out waiting for a response. */
|
|
12
|
+
timeout: string;
|
|
13
|
+
/** Connection attempt timed out. */
|
|
14
|
+
connectTimeout: string;
|
|
15
|
+
/** Fallback when the agent returns an error without text. */
|
|
16
|
+
agentError: string;
|
|
17
|
+
/** No WebSocket implementation available. */
|
|
18
|
+
noWebSocket: string;
|
|
19
|
+
/** print(): printer name missing. */
|
|
20
|
+
printNoPrinter: string;
|
|
21
|
+
/** print(): wrong number of PDF sources. */
|
|
22
|
+
printSource: string;
|
|
23
|
+
/** printBatch(): empty url list. */
|
|
24
|
+
printNoUrls: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** All available message catalogs keyed by language. */
|
|
28
|
+
declare const locales: Record<Lang, Messages>;
|
|
29
|
+
/** Returns the message catalog for the given language (defaults to English). */
|
|
30
|
+
declare function getMessages(lang?: Lang): Messages;
|
|
31
|
+
|
|
32
|
+
/** Connection status with the local agent. */
|
|
2
33
|
type ConnectionStatus = "connecting" | "open" | "closed";
|
|
3
|
-
/**
|
|
34
|
+
/** A printer returned by the agent. */
|
|
4
35
|
interface Printer {
|
|
5
36
|
name: string;
|
|
6
37
|
default: boolean;
|
|
7
38
|
}
|
|
8
|
-
/**
|
|
39
|
+
/** Agent version. */
|
|
9
40
|
interface AgentVersion {
|
|
10
41
|
brand: string;
|
|
11
42
|
version: string;
|
|
12
43
|
}
|
|
13
|
-
/**
|
|
44
|
+
/** Print job parameters. Provide exactly one source: url or base64. */
|
|
14
45
|
interface PrintOptions {
|
|
15
46
|
printer: string;
|
|
16
47
|
url?: string;
|
|
17
48
|
base64?: string;
|
|
18
49
|
copies?: number;
|
|
19
50
|
}
|
|
20
|
-
/**
|
|
51
|
+
/** Batch print parameters: many label PDFs merged into a single print job. */
|
|
52
|
+
interface PrintBatchOptions {
|
|
53
|
+
printer: string;
|
|
54
|
+
/** PDF URLs, printed in this order as one merged job. */
|
|
55
|
+
urls: string[];
|
|
56
|
+
/** Copies of each label (each label is repeated this many times). */
|
|
57
|
+
copies?: number;
|
|
58
|
+
}
|
|
59
|
+
/** PrintAgent constructor options. */
|
|
21
60
|
interface PrintAgentOptions {
|
|
22
61
|
host?: string;
|
|
23
62
|
port?: number;
|
|
@@ -25,8 +64,10 @@ interface PrintAgentOptions {
|
|
|
25
64
|
autoReconnect?: boolean;
|
|
26
65
|
requestTimeoutMs?: number;
|
|
27
66
|
WebSocket?: WebSocketCtor;
|
|
67
|
+
/** Language of SDK error messages; defaults to "en". */
|
|
68
|
+
lang?: Lang;
|
|
28
69
|
}
|
|
29
|
-
/**
|
|
70
|
+
/** Minimal WebSocket interface used by the SDK (compatible with the browser and the ws package). */
|
|
30
71
|
interface WebSocketLike {
|
|
31
72
|
send(data: string): void;
|
|
32
73
|
close(): void;
|
|
@@ -40,25 +81,26 @@ interface WebSocketLike {
|
|
|
40
81
|
interface WebSocketCtor {
|
|
41
82
|
new (url: string): WebSocketLike;
|
|
42
83
|
}
|
|
43
|
-
/**
|
|
84
|
+
/** No active connection to the agent. (Message is localized by the client.) */
|
|
44
85
|
declare class NotConnectedError extends Error {
|
|
45
86
|
constructor(message?: string);
|
|
46
87
|
}
|
|
47
|
-
/**
|
|
88
|
+
/** Timed out waiting for the agent. (Message is localized by the client.) */
|
|
48
89
|
declare class TimeoutError extends Error {
|
|
49
90
|
constructor(message?: string);
|
|
50
91
|
}
|
|
51
|
-
/**
|
|
92
|
+
/** The agent responded with an error (ok:false). */
|
|
52
93
|
declare class AgentError extends Error {
|
|
53
94
|
constructor(message?: string);
|
|
54
95
|
}
|
|
55
96
|
|
|
56
|
-
/**
|
|
97
|
+
/** Client for the local print agent. */
|
|
57
98
|
declare class PrintAgent {
|
|
58
99
|
private readonly url;
|
|
59
100
|
private readonly autoReconnect;
|
|
60
101
|
private readonly requestTimeoutMs;
|
|
61
102
|
private readonly WS;
|
|
103
|
+
private readonly t;
|
|
62
104
|
private ws?;
|
|
63
105
|
private _status;
|
|
64
106
|
private statusListeners;
|
|
@@ -70,19 +112,24 @@ declare class PrintAgent {
|
|
|
70
112
|
constructor(opts?: PrintAgentOptions);
|
|
71
113
|
get status(): ConnectionStatus;
|
|
72
114
|
isConnected(): boolean;
|
|
73
|
-
/**
|
|
115
|
+
/** Registers a status-change listener; returns an unsubscribe function. */
|
|
74
116
|
onStatusChange(cb: (s: ConnectionStatus) => void): () => void;
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
117
|
+
/** Connects to the agent; resolves on open, rejects on timeout/failure.
|
|
118
|
+
* Idempotent when the connection is already open. */
|
|
77
119
|
connect(): Promise<void>;
|
|
78
|
-
/**
|
|
120
|
+
/** Closes the connection and disables auto-reconnect. */
|
|
79
121
|
disconnect(): void;
|
|
80
|
-
/**
|
|
122
|
+
/** List of printers installed on the client's system. */
|
|
81
123
|
getPrinters(): Promise<Printer[]>;
|
|
82
|
-
/**
|
|
124
|
+
/** Agent brand and version. */
|
|
83
125
|
getVersion(): Promise<AgentVersion>;
|
|
84
|
-
/**
|
|
126
|
+
/** Sends a PDF print job; resolves once the agent confirms. */
|
|
85
127
|
print(opts: PrintOptions): Promise<void>;
|
|
128
|
+
/** Sends a batch of label PDFs as a SINGLE merged print job.
|
|
129
|
+
* The agent fetches all URLs, merges them (each label repeated `copies`
|
|
130
|
+
* times) and sends one job to the spooler — avoiding the printer's pauses
|
|
131
|
+
* between separate jobs. Resolves once the agent has accepted the batch. */
|
|
132
|
+
printBatch(opts: PrintBatchOptions): Promise<void>;
|
|
86
133
|
private openSocket;
|
|
87
134
|
private scheduleReconnect;
|
|
88
135
|
private handleMessage;
|
|
@@ -91,4 +138,4 @@ declare class PrintAgent {
|
|
|
91
138
|
private setStatus;
|
|
92
139
|
}
|
|
93
140
|
|
|
94
|
-
export { AgentError, type AgentVersion, type ConnectionStatus, NotConnectedError, PrintAgent, type PrintAgentOptions, type PrintOptions, type Printer, TimeoutError, type WebSocketCtor, type WebSocketLike };
|
|
141
|
+
export { AgentError, type AgentVersion, type ConnectionStatus, type Lang, type Messages, NotConnectedError, PrintAgent, type PrintAgentOptions, type PrintBatchOptions, type PrintOptions, type Printer, TimeoutError, type WebSocketCtor, type WebSocketLike, getMessages, locales };
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,57 @@
|
|
|
1
1
|
// src/types.ts
|
|
2
2
|
var NotConnectedError = class extends Error {
|
|
3
|
-
constructor(message = "
|
|
3
|
+
constructor(message = "no connection to the agent") {
|
|
4
4
|
super(message);
|
|
5
5
|
this.name = "NotConnectedError";
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
8
|
var TimeoutError = class extends Error {
|
|
9
|
-
constructor(message = "
|
|
9
|
+
constructor(message = "timed out waiting for the agent") {
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = "TimeoutError";
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
var AgentError = class extends Error {
|
|
15
|
-
constructor(message = "
|
|
15
|
+
constructor(message = "agent error") {
|
|
16
16
|
super(message);
|
|
17
17
|
this.name = "AgentError";
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
// src/locales/en.ts
|
|
22
|
+
var en = {
|
|
23
|
+
notConnected: "no connection to the agent",
|
|
24
|
+
connectionClosed: "connection closed",
|
|
25
|
+
connectFailed: "could not connect to the agent",
|
|
26
|
+
timeout: "timed out waiting for the agent's response",
|
|
27
|
+
connectTimeout: "timed out connecting to the agent",
|
|
28
|
+
agentError: "agent error",
|
|
29
|
+
noWebSocket: "no WebSocket implementation (pass the WebSocket option)",
|
|
30
|
+
printNoPrinter: "print: printer name is required (printer)",
|
|
31
|
+
printSource: "print: provide exactly one source \u2014 url or base64",
|
|
32
|
+
printNoUrls: "printBatch: at least one url is required (urls)"
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/locales/pl.ts
|
|
36
|
+
var pl = {
|
|
37
|
+
notConnected: "brak po\u0142\u0105czenia z agentem",
|
|
38
|
+
connectionClosed: "po\u0142\u0105czenie zamkni\u0119te",
|
|
39
|
+
connectFailed: "nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z agentem",
|
|
40
|
+
timeout: "przekroczono czas oczekiwania na odpowied\u017A agenta",
|
|
41
|
+
connectTimeout: "przekroczono czas \u0142\u0105czenia z agentem",
|
|
42
|
+
agentError: "b\u0142\u0105d agenta",
|
|
43
|
+
noWebSocket: "brak implementacji WebSocket (przeka\u017C opcj\u0119 WebSocket)",
|
|
44
|
+
printNoPrinter: "print: wymagana nazwa drukarki (printer)",
|
|
45
|
+
printSource: "print: podaj dok\u0142adnie jedno \u017Ar\xF3d\u0142o \u2014 url albo base64",
|
|
46
|
+
printNoUrls: "printBatch: wymagany co najmniej jeden url (urls)"
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/locales/index.ts
|
|
50
|
+
var locales = { en, pl };
|
|
51
|
+
function getMessages(lang = "en") {
|
|
52
|
+
return locales[lang] ?? en;
|
|
53
|
+
}
|
|
54
|
+
|
|
21
55
|
// src/client.ts
|
|
22
56
|
var RECONNECT_BACKOFF_MS = [1e3, 2e3, 5e3, 1e4];
|
|
23
57
|
var PrintAgent = class {
|
|
@@ -28,6 +62,7 @@ var PrintAgent = class {
|
|
|
28
62
|
this.idCounter = 0;
|
|
29
63
|
this.wantConnected = false;
|
|
30
64
|
this.reconnectAttempt = 0;
|
|
65
|
+
this.t = getMessages(opts.lang);
|
|
31
66
|
const host = opts.host ?? "localhost";
|
|
32
67
|
const port = opts.port ?? 45123;
|
|
33
68
|
this.url = opts.url ?? `wss://${host}:${port}/ws`;
|
|
@@ -35,7 +70,7 @@ var PrintAgent = class {
|
|
|
35
70
|
this.requestTimeoutMs = opts.requestTimeoutMs ?? 1e4;
|
|
36
71
|
const ctor = opts.WebSocket ?? globalThis.WebSocket;
|
|
37
72
|
if (!ctor) {
|
|
38
|
-
throw new Error(
|
|
73
|
+
throw new Error(this.t.noWebSocket);
|
|
39
74
|
}
|
|
40
75
|
this.WS = ctor;
|
|
41
76
|
}
|
|
@@ -45,13 +80,13 @@ var PrintAgent = class {
|
|
|
45
80
|
isConnected() {
|
|
46
81
|
return this._status === "open";
|
|
47
82
|
}
|
|
48
|
-
/**
|
|
83
|
+
/** Registers a status-change listener; returns an unsubscribe function. */
|
|
49
84
|
onStatusChange(cb) {
|
|
50
85
|
this.statusListeners.add(cb);
|
|
51
86
|
return () => this.statusListeners.delete(cb);
|
|
52
87
|
}
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
88
|
+
/** Connects to the agent; resolves on open, rejects on timeout/failure.
|
|
89
|
+
* Idempotent when the connection is already open. */
|
|
55
90
|
connect() {
|
|
56
91
|
this.wantConnected = true;
|
|
57
92
|
if (this._status === "open") {
|
|
@@ -61,7 +96,7 @@ var PrintAgent = class {
|
|
|
61
96
|
this.openSocket(resolve, reject);
|
|
62
97
|
});
|
|
63
98
|
}
|
|
64
|
-
/**
|
|
99
|
+
/** Closes the connection and disables auto-reconnect. */
|
|
65
100
|
disconnect() {
|
|
66
101
|
this.wantConnected = false;
|
|
67
102
|
if (this.reconnectTimer) {
|
|
@@ -72,25 +107,25 @@ var PrintAgent = class {
|
|
|
72
107
|
this.ws.close();
|
|
73
108
|
}
|
|
74
109
|
}
|
|
75
|
-
/**
|
|
110
|
+
/** List of printers installed on the client's system. */
|
|
76
111
|
async getPrinters() {
|
|
77
112
|
const r = await this.request({ type: "listPrinters" });
|
|
78
113
|
return r.printers ?? [];
|
|
79
114
|
}
|
|
80
|
-
/**
|
|
115
|
+
/** Agent brand and version. */
|
|
81
116
|
async getVersion() {
|
|
82
117
|
const r = await this.request({ type: "version" });
|
|
83
118
|
return { brand: r.brand ?? "", version: r.version ?? "" };
|
|
84
119
|
}
|
|
85
|
-
/**
|
|
120
|
+
/** Sends a PDF print job; resolves once the agent confirms. */
|
|
86
121
|
async print(opts) {
|
|
87
122
|
if (!opts || !opts.printer) {
|
|
88
|
-
throw new Error(
|
|
123
|
+
throw new Error(this.t.printNoPrinter);
|
|
89
124
|
}
|
|
90
125
|
const hasUrl = typeof opts.url === "string" && opts.url.length > 0;
|
|
91
126
|
const hasB64 = typeof opts.base64 === "string" && opts.base64.length > 0;
|
|
92
127
|
if (hasUrl === hasB64) {
|
|
93
|
-
throw new Error(
|
|
128
|
+
throw new Error(this.t.printSource);
|
|
94
129
|
}
|
|
95
130
|
const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };
|
|
96
131
|
await this.request({
|
|
@@ -100,7 +135,26 @@ var PrintAgent = class {
|
|
|
100
135
|
copies: opts.copies
|
|
101
136
|
});
|
|
102
137
|
}
|
|
103
|
-
|
|
138
|
+
/** Sends a batch of label PDFs as a SINGLE merged print job.
|
|
139
|
+
* The agent fetches all URLs, merges them (each label repeated `copies`
|
|
140
|
+
* times) and sends one job to the spooler — avoiding the printer's pauses
|
|
141
|
+
* between separate jobs. Resolves once the agent has accepted the batch. */
|
|
142
|
+
async printBatch(opts) {
|
|
143
|
+
if (!opts || !opts.printer) {
|
|
144
|
+
throw new Error(this.t.printNoPrinter);
|
|
145
|
+
}
|
|
146
|
+
if (!Array.isArray(opts.urls) || opts.urls.length === 0) {
|
|
147
|
+
throw new Error(this.t.printNoUrls);
|
|
148
|
+
}
|
|
149
|
+
const pdfs = opts.urls.map((url) => ({ url }));
|
|
150
|
+
await this.request({
|
|
151
|
+
type: "printBatch",
|
|
152
|
+
printer: opts.printer,
|
|
153
|
+
pdfs,
|
|
154
|
+
copies: opts.copies
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
// --- internal ---
|
|
104
158
|
openSocket(onOpen, onFail) {
|
|
105
159
|
this.setStatus("connecting");
|
|
106
160
|
let settled = false;
|
|
@@ -113,7 +167,7 @@ var PrintAgent = class {
|
|
|
113
167
|
ws.close();
|
|
114
168
|
} catch {
|
|
115
169
|
}
|
|
116
|
-
onFail?.(new TimeoutError(
|
|
170
|
+
onFail?.(new TimeoutError(this.t.connectTimeout));
|
|
117
171
|
}
|
|
118
172
|
}, this.requestTimeoutMs);
|
|
119
173
|
ws.onopen = () => {
|
|
@@ -130,10 +184,10 @@ var PrintAgent = class {
|
|
|
130
184
|
clearTimeout(connectTimer);
|
|
131
185
|
this.ws = void 0;
|
|
132
186
|
this.setStatus("closed");
|
|
133
|
-
this.rejectAllPending(new NotConnectedError(
|
|
187
|
+
this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));
|
|
134
188
|
if (!settled) {
|
|
135
189
|
settled = true;
|
|
136
|
-
onFail?.(new NotConnectedError(
|
|
190
|
+
onFail?.(new NotConnectedError(this.t.connectFailed));
|
|
137
191
|
}
|
|
138
192
|
if (this.wantConnected && this.autoReconnect) {
|
|
139
193
|
this.scheduleReconnect();
|
|
@@ -166,19 +220,19 @@ var PrintAgent = class {
|
|
|
166
220
|
if (msg.ok) {
|
|
167
221
|
p.resolve(msg);
|
|
168
222
|
} else {
|
|
169
|
-
p.reject(new AgentError(msg.error ||
|
|
223
|
+
p.reject(new AgentError(msg.error || this.t.agentError));
|
|
170
224
|
}
|
|
171
225
|
}
|
|
172
226
|
request(payload) {
|
|
173
227
|
if (!this.isConnected() || !this.ws) {
|
|
174
|
-
return Promise.reject(new NotConnectedError());
|
|
228
|
+
return Promise.reject(new NotConnectedError(this.t.notConnected));
|
|
175
229
|
}
|
|
176
230
|
const id = String(++this.idCounter);
|
|
177
231
|
const ws = this.ws;
|
|
178
232
|
return new Promise((resolve, reject) => {
|
|
179
233
|
const timer = setTimeout(() => {
|
|
180
234
|
this.pending.delete(id);
|
|
181
|
-
reject(new TimeoutError());
|
|
235
|
+
reject(new TimeoutError(this.t.timeout));
|
|
182
236
|
}, this.requestTimeoutMs);
|
|
183
237
|
this.pending.set(id, { resolve, reject, timer });
|
|
184
238
|
try {
|
|
@@ -209,6 +263,8 @@ export {
|
|
|
209
263
|
AgentError,
|
|
210
264
|
NotConnectedError,
|
|
211
265
|
PrintAgent,
|
|
212
|
-
TimeoutError
|
|
266
|
+
TimeoutError,
|
|
267
|
+
getMessages,
|
|
268
|
+
locales
|
|
213
269
|
};
|
|
214
270
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/client.ts"],"sourcesContent":["/** Status połączenia z lokalnym agentem. */\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"closed\";\n\n/** Drukarka zwrócona przez agenta. */\nexport interface Printer {\n name: string;\n default: boolean;\n}\n\n/** Wersja agenta. */\nexport interface AgentVersion {\n brand: string;\n version: string;\n}\n\n/** Parametry zadania druku. Dokładnie jedno ze źródeł: url albo base64. */\nexport interface PrintOptions {\n printer: string;\n url?: string;\n base64?: string;\n copies?: number;\n}\n\n/** Opcje konstruktora PrintAgent. */\nexport interface PrintAgentOptions {\n host?: string;\n port?: number;\n url?: string;\n autoReconnect?: boolean;\n requestTimeoutMs?: number;\n WebSocket?: WebSocketCtor;\n}\n\n/** Minimalny interfejs WebSocket używany przez SDK (zgodny z przeglądarką i pakietem ws). */\nexport interface WebSocketLike {\n send(data: string): void;\n close(): void;\n onopen: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n}\n\nexport interface WebSocketCtor {\n new (url: string): WebSocketLike;\n}\n\n/** Brak aktywnego połączenia z agentem. */\nexport class NotConnectedError extends Error {\n constructor(message = \"brak połączenia z agentem\") {\n super(message);\n this.name = \"NotConnectedError\";\n }\n}\n\n/** Przekroczono czas oczekiwania na odpowiedź agenta. */\nexport class TimeoutError extends Error {\n constructor(message = \"przekroczono czas oczekiwania na odpowiedź agenta\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/** Agent odpowiedział błędem (ok:false). */\nexport class AgentError extends Error {\n constructor(message = \"błąd agenta\") {\n super(message);\n this.name = \"AgentError\";\n }\n}\n","import {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type PrintAgentOptions,\n type PrintOptions,\n type Printer,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\n\ninterface AgentResponse {\n type: string;\n id?: string;\n ok: boolean;\n error?: string;\n printers?: Printer[];\n brand?: string;\n version?: string;\n}\n\ninterface Pending {\n resolve: (r: AgentResponse) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst RECONNECT_BACKOFF_MS = [1000, 2000, 5000, 10000];\n\n/** Klient lokalnego agenta druku. */\nexport class PrintAgent {\n private readonly url: string;\n private readonly autoReconnect: boolean;\n private readonly requestTimeoutMs: number;\n private readonly WS: WebSocketCtor;\n\n private ws?: WebSocketLike;\n private _status: ConnectionStatus = \"closed\";\n private statusListeners = new Set<(s: ConnectionStatus) => void>();\n private pending = new Map<string, Pending>();\n private idCounter = 0;\n private wantConnected = false;\n private reconnectAttempt = 0;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: PrintAgentOptions = {}) {\n const host = opts.host ?? \"localhost\";\n const port = opts.port ?? 45123;\n this.url = opts.url ?? `wss://${host}:${port}/ws`;\n this.autoReconnect = opts.autoReconnect ?? true;\n this.requestTimeoutMs = opts.requestTimeoutMs ?? 10000;\n const ctor = opts.WebSocket ?? (globalThis as { WebSocket?: WebSocketCtor }).WebSocket;\n if (!ctor) {\n throw new Error(\"brak implementacji WebSocket (przekaż opcję WebSocket)\");\n }\n this.WS = ctor;\n }\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n isConnected(): boolean {\n return this._status === \"open\";\n }\n\n /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */\n onStatusChange(cb: (s: ConnectionStatus) => void): () => void {\n this.statusListeners.add(cb);\n return () => this.statusListeners.delete(cb);\n }\n\n /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.\n * Idempotentne, gdy połączenie jest już otwarte. */\n connect(): Promise<void> {\n this.wantConnected = true;\n if (this._status === \"open\") {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n this.openSocket(resolve, reject);\n });\n }\n\n /** Zamyka połączenie i wyłącza auto-reconnect. */\n disconnect(): void {\n this.wantConnected = false;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n if (this.ws) {\n this.ws.close();\n }\n }\n\n /** Lista drukarek zainstalowanych w systemie klienta. */\n async getPrinters(): Promise<Printer[]> {\n const r = await this.request({ type: \"listPrinters\" });\n return r.printers ?? [];\n }\n\n /** Wersja i brand agenta. */\n async getVersion(): Promise<AgentVersion> {\n const r = await this.request({ type: \"version\" });\n return { brand: r.brand ?? \"\", version: r.version ?? \"\" };\n }\n\n /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */\n async print(opts: PrintOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(\"print: wymagana nazwa drukarki (printer)\");\n }\n const hasUrl = typeof opts.url === \"string\" && opts.url.length > 0;\n const hasB64 = typeof opts.base64 === \"string\" && opts.base64.length > 0;\n if (hasUrl === hasB64) {\n throw new Error(\"print: podaj dokładnie jedno źródło — url albo base64\");\n }\n const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };\n await this.request({\n type: \"printPDF\",\n printer: opts.printer,\n pdf,\n copies: opts.copies,\n });\n }\n\n // --- wewnętrzne ---\n\n private openSocket(\n onOpen?: () => void,\n onFail?: (e: Error) => void\n ): void {\n this.setStatus(\"connecting\");\n let settled = false;\n const ws = new this.WS(this.url);\n this.ws = ws;\n\n const connectTimer = setTimeout(() => {\n if (!settled) {\n settled = true;\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n onFail?.(new TimeoutError(\"przekroczono czas łączenia z agentem\"));\n }\n }, this.requestTimeoutMs);\n\n ws.onopen = () => {\n settled = true;\n clearTimeout(connectTimer);\n this.reconnectAttempt = 0;\n this.setStatus(\"open\");\n onOpen?.();\n };\n ws.onmessage = (ev) => this.handleMessage(ev.data);\n ws.onerror = () => {\n /* po błędzie nastąpi onclose */\n };\n ws.onclose = () => {\n clearTimeout(connectTimer);\n this.ws = undefined;\n this.setStatus(\"closed\");\n this.rejectAllPending(new NotConnectedError(\"połączenie zamknięte\"));\n if (!settled) {\n settled = true;\n onFail?.(new NotConnectedError(\"nie udało się połączyć z agentem\"));\n }\n if (this.wantConnected && this.autoReconnect) {\n this.scheduleReconnect();\n }\n };\n }\n\n private scheduleReconnect(): void {\n const delay =\n RECONNECT_BACKOFF_MS[Math.min(this.reconnectAttempt, RECONNECT_BACKOFF_MS.length - 1)];\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n if (this.wantConnected) {\n this.openSocket();\n }\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n const text = typeof data === \"string\" ? data : String(data);\n let msg: AgentResponse;\n try {\n msg = JSON.parse(text);\n } catch {\n return;\n }\n const id = msg.id;\n if (!id) return;\n const p = this.pending.get(id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(id);\n if (msg.ok) {\n p.resolve(msg);\n } else {\n p.reject(new AgentError(msg.error || \"błąd agenta\"));\n }\n }\n\n private request(payload: Record<string, unknown>): Promise<AgentResponse> {\n if (!this.isConnected() || !this.ws) {\n return Promise.reject(new NotConnectedError());\n }\n const id = String(++this.idCounter);\n const ws = this.ws;\n return new Promise<AgentResponse>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new TimeoutError());\n }, this.requestTimeoutMs);\n this.pending.set(id, { resolve, reject, timer });\n try {\n ws.send(JSON.stringify({ ...payload, id }));\n } catch (e) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(e instanceof Error ? e : new Error(String(e)));\n }\n });\n }\n\n private rejectAllPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private setStatus(s: ConnectionStatus): void {\n if (this._status === s) return;\n this._status = s;\n for (const cb of this.statusListeners) {\n cb(s);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/locales/en.ts","../src/locales/pl.ts","../src/locales/index.ts","../src/client.ts"],"sourcesContent":["import type { Lang } from \"./locales\";\n\n/** Connection status with the local agent. */\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"closed\";\n\n/** A printer returned by the agent. */\nexport interface Printer {\n name: string;\n default: boolean;\n}\n\n/** Agent version. */\nexport interface AgentVersion {\n brand: string;\n version: string;\n}\n\n/** Print job parameters. Provide exactly one source: url or base64. */\nexport interface PrintOptions {\n printer: string;\n url?: string;\n base64?: string;\n copies?: number;\n}\n\n/** Batch print parameters: many label PDFs merged into a single print job. */\nexport interface PrintBatchOptions {\n printer: string;\n /** PDF URLs, printed in this order as one merged job. */\n urls: string[];\n /** Copies of each label (each label is repeated this many times). */\n copies?: number;\n}\n\n/** PrintAgent constructor options. */\nexport interface PrintAgentOptions {\n host?: string;\n port?: number;\n url?: string;\n autoReconnect?: boolean;\n requestTimeoutMs?: number;\n WebSocket?: WebSocketCtor;\n /** Language of SDK error messages; defaults to \"en\". */\n lang?: Lang;\n}\n\n/** Minimal WebSocket interface used by the SDK (compatible with the browser and the ws package). */\nexport interface WebSocketLike {\n send(data: string): void;\n close(): void;\n onopen: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n}\n\nexport interface WebSocketCtor {\n new (url: string): WebSocketLike;\n}\n\n/** No active connection to the agent. (Message is localized by the client.) */\nexport class NotConnectedError extends Error {\n constructor(message = \"no connection to the agent\") {\n super(message);\n this.name = \"NotConnectedError\";\n }\n}\n\n/** Timed out waiting for the agent. (Message is localized by the client.) */\nexport class TimeoutError extends Error {\n constructor(message = \"timed out waiting for the agent\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\n/** The agent responded with an error (ok:false). */\nexport class AgentError extends Error {\n constructor(message = \"agent error\") {\n super(message);\n this.name = \"AgentError\";\n }\n}\n","import type { Messages } from \"./types\";\n\n/** English message catalog (default). */\nexport const en: Messages = {\n notConnected: \"no connection to the agent\",\n connectionClosed: \"connection closed\",\n connectFailed: \"could not connect to the agent\",\n timeout: \"timed out waiting for the agent's response\",\n connectTimeout: \"timed out connecting to the agent\",\n agentError: \"agent error\",\n noWebSocket: \"no WebSocket implementation (pass the WebSocket option)\",\n printNoPrinter: \"print: printer name is required (printer)\",\n printSource: \"print: provide exactly one source — url or base64\",\n printNoUrls: \"printBatch: at least one url is required (urls)\",\n};\n","import type { Messages } from \"./types\";\n\n/** Polish message catalog. */\nexport const pl: Messages = {\n notConnected: \"brak połączenia z agentem\",\n connectionClosed: \"połączenie zamknięte\",\n connectFailed: \"nie udało się połączyć z agentem\",\n timeout: \"przekroczono czas oczekiwania na odpowiedź agenta\",\n connectTimeout: \"przekroczono czas łączenia z agentem\",\n agentError: \"błąd agenta\",\n noWebSocket: \"brak implementacji WebSocket (przekaż opcję WebSocket)\",\n printNoPrinter: \"print: wymagana nazwa drukarki (printer)\",\n printSource: \"print: podaj dokładnie jedno źródło — url albo base64\",\n printNoUrls: \"printBatch: wymagany co najmniej jeden url (urls)\",\n};\n","import { en } from \"./en\";\nimport { pl } from \"./pl\";\nimport type { Lang, Messages } from \"./types\";\n\nexport type { Lang, Messages };\n\n/** All available message catalogs keyed by language. */\nexport const locales: Record<Lang, Messages> = { en, pl };\n\n/** Returns the message catalog for the given language (defaults to English). */\nexport function getMessages(lang: Lang = \"en\"): Messages {\n return locales[lang] ?? en;\n}\n","import {\n AgentError,\n NotConnectedError,\n TimeoutError,\n type AgentVersion,\n type ConnectionStatus,\n type PrintAgentOptions,\n type PrintBatchOptions,\n type PrintOptions,\n type Printer,\n type WebSocketCtor,\n type WebSocketLike,\n} from \"./types\";\nimport { getMessages, type Messages } from \"./locales\";\n\ninterface AgentResponse {\n type: string;\n id?: string;\n ok: boolean;\n error?: string;\n printers?: Printer[];\n brand?: string;\n version?: string;\n}\n\ninterface Pending {\n resolve: (r: AgentResponse) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst RECONNECT_BACKOFF_MS = [1000, 2000, 5000, 10000];\n\n/** Client for the local print agent. */\nexport class PrintAgent {\n private readonly url: string;\n private readonly autoReconnect: boolean;\n private readonly requestTimeoutMs: number;\n private readonly WS: WebSocketCtor;\n private readonly t: Messages;\n\n private ws?: WebSocketLike;\n private _status: ConnectionStatus = \"closed\";\n private statusListeners = new Set<(s: ConnectionStatus) => void>();\n private pending = new Map<string, Pending>();\n private idCounter = 0;\n private wantConnected = false;\n private reconnectAttempt = 0;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n\n constructor(opts: PrintAgentOptions = {}) {\n this.t = getMessages(opts.lang);\n const host = opts.host ?? \"localhost\";\n const port = opts.port ?? 45123;\n this.url = opts.url ?? `wss://${host}:${port}/ws`;\n this.autoReconnect = opts.autoReconnect ?? true;\n this.requestTimeoutMs = opts.requestTimeoutMs ?? 10000;\n const ctor = opts.WebSocket ?? (globalThis as { WebSocket?: WebSocketCtor }).WebSocket;\n if (!ctor) {\n throw new Error(this.t.noWebSocket);\n }\n this.WS = ctor;\n }\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n isConnected(): boolean {\n return this._status === \"open\";\n }\n\n /** Registers a status-change listener; returns an unsubscribe function. */\n onStatusChange(cb: (s: ConnectionStatus) => void): () => void {\n this.statusListeners.add(cb);\n return () => this.statusListeners.delete(cb);\n }\n\n /** Connects to the agent; resolves on open, rejects on timeout/failure.\n * Idempotent when the connection is already open. */\n connect(): Promise<void> {\n this.wantConnected = true;\n if (this._status === \"open\") {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n this.openSocket(resolve, reject);\n });\n }\n\n /** Closes the connection and disables auto-reconnect. */\n disconnect(): void {\n this.wantConnected = false;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n if (this.ws) {\n this.ws.close();\n }\n }\n\n /** List of printers installed on the client's system. */\n async getPrinters(): Promise<Printer[]> {\n const r = await this.request({ type: \"listPrinters\" });\n return r.printers ?? [];\n }\n\n /** Agent brand and version. */\n async getVersion(): Promise<AgentVersion> {\n const r = await this.request({ type: \"version\" });\n return { brand: r.brand ?? \"\", version: r.version ?? \"\" };\n }\n\n /** Sends a PDF print job; resolves once the agent confirms. */\n async print(opts: PrintOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(this.t.printNoPrinter);\n }\n const hasUrl = typeof opts.url === \"string\" && opts.url.length > 0;\n const hasB64 = typeof opts.base64 === \"string\" && opts.base64.length > 0;\n if (hasUrl === hasB64) {\n throw new Error(this.t.printSource);\n }\n const pdf = hasUrl ? { url: opts.url } : { base64: opts.base64 };\n await this.request({\n type: \"printPDF\",\n printer: opts.printer,\n pdf,\n copies: opts.copies,\n });\n }\n\n /** Sends a batch of label PDFs as a SINGLE merged print job.\n * The agent fetches all URLs, merges them (each label repeated `copies`\n * times) and sends one job to the spooler — avoiding the printer's pauses\n * between separate jobs. Resolves once the agent has accepted the batch. */\n async printBatch(opts: PrintBatchOptions): Promise<void> {\n if (!opts || !opts.printer) {\n throw new Error(this.t.printNoPrinter);\n }\n if (!Array.isArray(opts.urls) || opts.urls.length === 0) {\n throw new Error(this.t.printNoUrls);\n }\n const pdfs = opts.urls.map((url) => ({ url }));\n await this.request({\n type: \"printBatch\",\n printer: opts.printer,\n pdfs,\n copies: opts.copies,\n });\n }\n\n // --- internal ---\n\n private openSocket(\n onOpen?: () => void,\n onFail?: (e: Error) => void\n ): void {\n this.setStatus(\"connecting\");\n let settled = false;\n const ws = new this.WS(this.url);\n this.ws = ws;\n\n const connectTimer = setTimeout(() => {\n if (!settled) {\n settled = true;\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n onFail?.(new TimeoutError(this.t.connectTimeout));\n }\n }, this.requestTimeoutMs);\n\n ws.onopen = () => {\n settled = true;\n clearTimeout(connectTimer);\n this.reconnectAttempt = 0;\n this.setStatus(\"open\");\n onOpen?.();\n };\n ws.onmessage = (ev) => this.handleMessage(ev.data);\n ws.onerror = () => {\n /* onclose will follow the error */\n };\n ws.onclose = () => {\n clearTimeout(connectTimer);\n this.ws = undefined;\n this.setStatus(\"closed\");\n this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));\n if (!settled) {\n settled = true;\n onFail?.(new NotConnectedError(this.t.connectFailed));\n }\n if (this.wantConnected && this.autoReconnect) {\n this.scheduleReconnect();\n }\n };\n }\n\n private scheduleReconnect(): void {\n const delay =\n RECONNECT_BACKOFF_MS[Math.min(this.reconnectAttempt, RECONNECT_BACKOFF_MS.length - 1)];\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n if (this.wantConnected) {\n this.openSocket();\n }\n }, delay);\n }\n\n private handleMessage(data: unknown): void {\n const text = typeof data === \"string\" ? data : String(data);\n let msg: AgentResponse;\n try {\n msg = JSON.parse(text);\n } catch {\n return;\n }\n const id = msg.id;\n if (!id) return;\n const p = this.pending.get(id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(id);\n if (msg.ok) {\n p.resolve(msg);\n } else {\n p.reject(new AgentError(msg.error || this.t.agentError));\n }\n }\n\n private request(payload: Record<string, unknown>): Promise<AgentResponse> {\n if (!this.isConnected() || !this.ws) {\n return Promise.reject(new NotConnectedError(this.t.notConnected));\n }\n const id = String(++this.idCounter);\n const ws = this.ws;\n return new Promise<AgentResponse>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new TimeoutError(this.t.timeout));\n }, this.requestTimeoutMs);\n this.pending.set(id, { resolve, reject, timer });\n try {\n ws.send(JSON.stringify({ ...payload, id }));\n } catch (e) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(e instanceof Error ? e : new Error(String(e)));\n }\n });\n }\n\n private rejectAllPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private setStatus(s: ConnectionStatus): void {\n if (this._status === s) return;\n this._status = s;\n for (const cb of this.statusListeners) {\n cb(s);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happenv/print-agent-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"description": "
|
|
7
|
+
"description": "Simple SDK for the local print agent (WebSocket): printers, PDF printing, status.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./dist/index.cjs",
|
|
10
10
|
"module": "./dist/index.js",
|
|
@@ -21,14 +21,22 @@
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
|
-
"files": [
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
25
27
|
"sideEffects": false,
|
|
26
28
|
"scripts": {
|
|
27
29
|
"build": "tsup",
|
|
28
30
|
"test": "vitest run",
|
|
29
|
-
"prepublishOnly": "npm run build"
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"release": "npm version patch && npm publish"
|
|
30
33
|
},
|
|
31
|
-
"keywords": [
|
|
34
|
+
"keywords": [
|
|
35
|
+
"printing",
|
|
36
|
+
"websocket",
|
|
37
|
+
"pdf",
|
|
38
|
+
"print-agent"
|
|
39
|
+
],
|
|
32
40
|
"license": "MIT",
|
|
33
41
|
"devDependencies": {
|
|
34
42
|
"@types/ws": "^8.5.10",
|