@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 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 = "brak po\u0142\u0105czenia z agentem") {
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 = "przekroczono czas oczekiwania na odpowied\u017A agenta") {
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 = "b\u0142\u0105d agenta") {
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("brak implementacji WebSocket (przeka\u017C opcj\u0119 WebSocket)");
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
- /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */
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
- /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.
83
- * Idempotentne, gdy połączenie jest już otwarte. */
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
- /** Zamyka połączenie i wyłącza auto-reconnect. */
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
- /** Lista drukarek zainstalowanych w systemie klienta. */
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
- /** Wersja i brand agenta. */
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
- /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */
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("print: wymagana nazwa drukarki (printer)");
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("print: podaj dok\u0142adnie jedno \u017Ar\xF3d\u0142o \u2014 url albo base64");
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
- // --- wewnętrzne ---
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("przekroczono czas \u0142\u0105czenia z agentem"));
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("po\u0142\u0105czenie zamkni\u0119te"));
218
+ this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));
163
219
  if (!settled) {
164
220
  settled = true;
165
- onFail?.(new NotConnectedError("nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z agentem"));
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 || "b\u0142\u0105d agenta"));
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
@@ -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":"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","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":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,23 +1,62 @@
1
- /** Status połączenia z lokalnym agentem. */
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
- /** Drukarka zwrócona przez agenta. */
34
+ /** A printer returned by the agent. */
4
35
  interface Printer {
5
36
  name: string;
6
37
  default: boolean;
7
38
  }
8
- /** Wersja agenta. */
39
+ /** Agent version. */
9
40
  interface AgentVersion {
10
41
  brand: string;
11
42
  version: string;
12
43
  }
13
- /** Parametry zadania druku. Dokładnie jedno ze źródeł: url albo base64. */
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
- /** Opcje konstruktora PrintAgent. */
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
- /** Minimalny interfejs WebSocket używany przez SDK (zgodny z przeglądarką i pakietem ws). */
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
- /** Brak aktywnego połączenia z agentem. */
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
- /** Przekroczono czas oczekiwania na odpowiedź agenta. */
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
- /** Agent odpowiedział błędem (ok:false). */
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
- /** Klient lokalnego agenta druku. */
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
- /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */
115
+ /** Registers a status-change listener; returns an unsubscribe function. */
74
116
  onStatusChange(cb: (s: ConnectionStatus) => void): () => void;
75
- /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.
76
- * Idempotentne, gdy połączenie jest już otwarte. */
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
- /** Zamyka połączenie i wyłącza auto-reconnect. */
120
+ /** Closes the connection and disables auto-reconnect. */
79
121
  disconnect(): void;
80
- /** Lista drukarek zainstalowanych w systemie klienta. */
122
+ /** List of printers installed on the client's system. */
81
123
  getPrinters(): Promise<Printer[]>;
82
- /** Wersja i brand agenta. */
124
+ /** Agent brand and version. */
83
125
  getVersion(): Promise<AgentVersion>;
84
- /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */
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
- /** Status połączenia z lokalnym agentem. */
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
- /** Drukarka zwrócona przez agenta. */
34
+ /** A printer returned by the agent. */
4
35
  interface Printer {
5
36
  name: string;
6
37
  default: boolean;
7
38
  }
8
- /** Wersja agenta. */
39
+ /** Agent version. */
9
40
  interface AgentVersion {
10
41
  brand: string;
11
42
  version: string;
12
43
  }
13
- /** Parametry zadania druku. Dokładnie jedno ze źródeł: url albo base64. */
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
- /** Opcje konstruktora PrintAgent. */
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
- /** Minimalny interfejs WebSocket używany przez SDK (zgodny z przeglądarką i pakietem ws). */
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
- /** Brak aktywnego połączenia z agentem. */
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
- /** Przekroczono czas oczekiwania na odpowiedź agenta. */
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
- /** Agent odpowiedział błędem (ok:false). */
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
- /** Klient lokalnego agenta druku. */
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
- /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */
115
+ /** Registers a status-change listener; returns an unsubscribe function. */
74
116
  onStatusChange(cb: (s: ConnectionStatus) => void): () => void;
75
- /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.
76
- * Idempotentne, gdy połączenie jest już otwarte. */
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
- /** Zamyka połączenie i wyłącza auto-reconnect. */
120
+ /** Closes the connection and disables auto-reconnect. */
79
121
  disconnect(): void;
80
- /** Lista drukarek zainstalowanych w systemie klienta. */
122
+ /** List of printers installed on the client's system. */
81
123
  getPrinters(): Promise<Printer[]>;
82
- /** Wersja i brand agenta. */
124
+ /** Agent brand and version. */
83
125
  getVersion(): Promise<AgentVersion>;
84
- /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */
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 = "brak po\u0142\u0105czenia z agentem") {
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 = "przekroczono czas oczekiwania na odpowied\u017A agenta") {
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 = "b\u0142\u0105d agenta") {
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("brak implementacji WebSocket (przeka\u017C opcj\u0119 WebSocket)");
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
- /** Rejestruje nasłuch zmian statusu; zwraca funkcję wyrejestrowującą. */
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
- /** Łączy z agentem; resolve po otwarciu, reject przy timeoucie/zerwaniu.
54
- * Idempotentne, gdy połączenie jest już otwarte. */
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
- /** Zamyka połączenie i wyłącza auto-reconnect. */
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
- /** Lista drukarek zainstalowanych w systemie klienta. */
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
- /** Wersja i brand agenta. */
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
- /** Wysyła zadanie druku PDF; resolve po potwierdzeniu agenta. */
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("print: wymagana nazwa drukarki (printer)");
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("print: podaj dok\u0142adnie jedno \u017Ar\xF3d\u0142o \u2014 url albo base64");
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
- // --- wewnętrzne ---
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("przekroczono czas \u0142\u0105czenia z agentem"));
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("po\u0142\u0105czenie zamkni\u0119te"));
187
+ this.rejectAllPending(new NotConnectedError(this.t.connectionClosed));
134
188
  if (!settled) {
135
189
  settled = true;
136
- onFail?.(new NotConnectedError("nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z agentem"));
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 || "b\u0142\u0105d agenta"));
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.0",
3
+ "version": "0.1.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "Prosty SDK do lokalnego agenta druku (WebSocket): drukarki, druk PDF, status.",
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": ["dist"],
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": ["printing", "websocket", "pdf", "print-agent"],
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",