@ecobridge.xyz/devicemanager 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.gitea/workflows/default_tags.yaml +0 -21
  2. package/.smartconfig.json +69 -0
  3. package/changelog.md +38 -1
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/device/device.classes.device.d.ts +2 -2
  6. package/dist_ts/device/device.classes.device.js +3 -3
  7. package/dist_ts/devicemanager.classes.devicemanager.d.ts +17 -4
  8. package/dist_ts/devicemanager.classes.devicemanager.js +99 -11
  9. package/dist_ts/discovery/discovery.classes.mdns.js +46 -11
  10. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +5 -1
  11. package/dist_ts/discovery/discovery.classes.networkscanner.js +44 -3
  12. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +52 -21
  13. package/dist_ts/discovery/discovery.classes.ssdp.js +407 -117
  14. package/dist_ts/events/events.observable.d.ts +15 -0
  15. package/dist_ts/events/events.observable.js +22 -0
  16. package/dist_ts/events/index.d.ts +1 -0
  17. package/dist_ts/events/index.js +2 -0
  18. package/dist_ts/factories/index.js +7 -5
  19. package/dist_ts/features/feature.abstract.d.ts +2 -2
  20. package/dist_ts/features/feature.abstract.js +3 -3
  21. package/dist_ts/features/feature.print.d.ts +3 -0
  22. package/dist_ts/features/feature.print.js +17 -2
  23. package/dist_ts/features/feature.scan.d.ts +5 -2
  24. package/dist_ts/features/feature.scan.js +98 -27
  25. package/dist_ts/index.d.ts +4 -2
  26. package/dist_ts/index.js +4 -2
  27. package/dist_ts/interfaces/feature.interfaces.d.ts +22 -2
  28. package/dist_ts/interfaces/index.d.ts +22 -4
  29. package/dist_ts/interfaces/index.js +1 -1
  30. package/dist_ts/plugins.d.ts +6 -15
  31. package/dist_ts/plugins.js +7 -19
  32. package/dist_ts/protocols/index.d.ts +2 -1
  33. package/dist_ts/protocols/index.js +4 -2
  34. package/dist_ts/protocols/protocol.brother.d.ts +67 -0
  35. package/dist_ts/protocols/protocol.brother.js +560 -0
  36. package/dist_ts/protocols/protocol.escl.d.ts +13 -4
  37. package/dist_ts/protocols/protocol.escl.js +345 -178
  38. package/dist_ts/protocols/protocol.ipp.d.ts +2 -0
  39. package/dist_ts/protocols/protocol.ipp.js +22 -2
  40. package/dist_ts/providers/index.d.ts +1 -0
  41. package/dist_ts/providers/index.js +2 -0
  42. package/dist_ts/providers/provider.smb.d.ts +60 -0
  43. package/dist_ts/providers/provider.smb.js +224 -0
  44. package/license.md +21 -0
  45. package/package.json +15 -20
  46. package/pnpm-workspace.yaml +6 -0
  47. package/readme.md +157 -78
  48. package/test/test.brother.node.ts +306 -0
  49. package/test/test.escl.node.ts +233 -0
  50. package/test/test.ipp.node.ts +75 -0
  51. package/test/{test.ts → test.node.ts} +37 -45
  52. package/test/test.smb.node.ts +123 -0
  53. package/test/test.ssdp.node.ts +978 -0
  54. package/ts/00_commitinfo_data.ts +1 -1
  55. package/ts/device/device.classes.device.ts +2 -2
  56. package/ts/devicemanager.classes.devicemanager.ts +125 -12
  57. package/ts/discovery/discovery.classes.mdns.ts +40 -11
  58. package/ts/discovery/discovery.classes.networkscanner.ts +51 -2
  59. package/ts/discovery/discovery.classes.ssdp.ts +493 -130
  60. package/ts/events/events.observable.ts +31 -0
  61. package/ts/events/index.ts +4 -0
  62. package/ts/factories/index.ts +7 -5
  63. package/ts/features/feature.abstract.ts +2 -2
  64. package/ts/features/feature.print.ts +16 -1
  65. package/ts/features/feature.scan.ts +93 -27
  66. package/ts/index.ts +21 -0
  67. package/ts/interfaces/feature.interfaces.ts +23 -2
  68. package/ts/interfaces/index.ts +23 -4
  69. package/ts/plugins.ts +6 -25
  70. package/ts/protocols/index.ts +11 -1
  71. package/ts/protocols/protocol.brother.ts +648 -0
  72. package/ts/protocols/protocol.escl.ts +348 -191
  73. package/ts/protocols/protocol.ipp.ts +24 -1
  74. package/ts/providers/index.ts +7 -0
  75. package/ts/providers/provider.smb.ts +326 -0
  76. package/dist_ts/protocols/protocol.ipp.old.d.ts +0 -45
  77. package/dist_ts/protocols/protocol.ipp.old.js +0 -284
  78. package/npmextra.json +0 -24
@@ -0,0 +1,560 @@
1
+ import * as plugins from '../plugins.js';
2
+ const BROTHER_SCAN_PORT = 54921;
3
+ const DEFAULT_TIMEOUT_MS = 30_000;
4
+ const DEFAULT_SCAN_TIMEOUT_MS = 10 * 60_000;
5
+ const DEFAULT_BUSY_RETRY_INTERVAL_MS = 1_000;
6
+ const DEFAULT_BUSY_TIMEOUT_MS = 30_000;
7
+ const MAX_PAGES = 500;
8
+ const MAX_PAGE_BYTES = 256 * 1024 * 1024;
9
+ const TERMINATOR = 0x80;
10
+ export class BrotherScanError extends Error {
11
+ code;
12
+ statusCode;
13
+ constructor(message, code, statusCode) {
14
+ super(message);
15
+ this.code = code;
16
+ this.statusCode = statusCode;
17
+ this.name = 'BrotherScanError';
18
+ }
19
+ }
20
+ class SocketBuffer {
21
+ socket;
22
+ buffer = Buffer.alloc(0);
23
+ error = null;
24
+ ended = false;
25
+ constructor(socket) {
26
+ this.socket = socket;
27
+ socket.on('data', (data) => {
28
+ this.buffer = Buffer.concat([this.buffer, data]);
29
+ });
30
+ socket.on('error', (error) => {
31
+ this.error = error;
32
+ });
33
+ socket.on('end', () => {
34
+ this.ended = true;
35
+ });
36
+ socket.on('close', () => {
37
+ this.ended = true;
38
+ });
39
+ }
40
+ discard() {
41
+ this.buffer = Buffer.alloc(0);
42
+ }
43
+ async readExactly(length, timeout) {
44
+ await this.waitForLength(length, timeout);
45
+ const result = this.buffer.subarray(0, length);
46
+ this.buffer = this.buffer.subarray(length);
47
+ return result;
48
+ }
49
+ async peekExactly(length, timeout) {
50
+ await this.waitForLength(length, timeout);
51
+ return this.buffer.subarray(0, length);
52
+ }
53
+ async readUntil(delimiter, timeout, maxLength) {
54
+ const deadline = Date.now() + timeout;
55
+ while (true) {
56
+ const index = this.buffer.indexOf(delimiter);
57
+ if (index >= 0) {
58
+ const end = index + delimiter.length;
59
+ const result = this.buffer.subarray(0, end);
60
+ this.buffer = this.buffer.subarray(end);
61
+ return result;
62
+ }
63
+ if (this.buffer.length > maxLength) {
64
+ throw new BrotherScanError('Brother scanner response exceeded the expected length', 'invalid-response');
65
+ }
66
+ await this.waitForData(deadline);
67
+ }
68
+ }
69
+ async readMatch(pattern, timeout, maxLength) {
70
+ const deadline = Date.now() + timeout;
71
+ while (true) {
72
+ const match = this.buffer.toString('latin1').match(pattern);
73
+ if (match)
74
+ return match;
75
+ if (this.buffer.length > maxLength) {
76
+ throw new BrotherScanError('Brother scanner lease response was malformed', 'invalid-response');
77
+ }
78
+ await this.waitForData(deadline);
79
+ }
80
+ }
81
+ async waitForLength(length, timeout) {
82
+ const deadline = Date.now() + timeout;
83
+ while (this.buffer.length < length) {
84
+ await this.waitForData(deadline);
85
+ }
86
+ }
87
+ async waitForData(deadline) {
88
+ if (this.error)
89
+ throw this.error;
90
+ if (this.ended) {
91
+ throw new BrotherScanError('Brother scanner closed the connection', 'invalid-response');
92
+ }
93
+ const remaining = deadline - Date.now();
94
+ if (remaining <= 0) {
95
+ throw new BrotherScanError('Timed out waiting for the Brother scanner', 'timeout');
96
+ }
97
+ await new Promise((resolve, reject) => {
98
+ const cleanup = () => {
99
+ clearTimeout(timer);
100
+ this.socket.off('data', onData);
101
+ this.socket.off('error', onError);
102
+ this.socket.off('end', onEnd);
103
+ this.socket.off('close', onEnd);
104
+ };
105
+ const onData = () => {
106
+ cleanup();
107
+ resolve();
108
+ };
109
+ const onError = (error) => {
110
+ cleanup();
111
+ reject(error);
112
+ };
113
+ const onEnd = () => {
114
+ cleanup();
115
+ reject(new BrotherScanError('Brother scanner closed the connection', 'invalid-response'));
116
+ };
117
+ const timer = setTimeout(() => {
118
+ cleanup();
119
+ reject(new BrotherScanError('Timed out waiting for the Brother scanner', 'timeout'));
120
+ }, remaining);
121
+ this.socket.once('data', onData);
122
+ this.socket.once('error', onError);
123
+ this.socket.once('end', onEnd);
124
+ this.socket.once('close', onEnd);
125
+ });
126
+ }
127
+ }
128
+ /**
129
+ * Brother's native network scan protocol on TCP 54921.
130
+ *
131
+ * Brother devices expose richer scan control here than they do through some
132
+ * eSCL implementations. The protocol returns one JPEG stream per sheet/side.
133
+ */
134
+ export class BrotherScanProtocol {
135
+ address;
136
+ port;
137
+ socket = null;
138
+ reader = null;
139
+ scanning = false;
140
+ cancelled = false;
141
+ timeout;
142
+ scanTimeout;
143
+ busyRetryInterval;
144
+ busyTimeout;
145
+ constructor(address, port = BROTHER_SCAN_PORT, options = {}) {
146
+ this.address = address;
147
+ this.port = port;
148
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
149
+ this.scanTimeout = options.scanTimeout ?? DEFAULT_SCAN_TIMEOUT_MS;
150
+ this.busyRetryInterval = options.busyRetryInterval ?? DEFAULT_BUSY_RETRY_INTERVAL_MS;
151
+ this.busyTimeout = options.busyTimeout ?? DEFAULT_BUSY_TIMEOUT_MS;
152
+ }
153
+ async connect() {
154
+ if (this.socket && !this.socket.destroyed)
155
+ return;
156
+ const busyDeadline = Date.now() + this.busyTimeout;
157
+ while (true) {
158
+ try {
159
+ await this.connectOnce();
160
+ return;
161
+ }
162
+ catch (error) {
163
+ await this.disconnect();
164
+ if (!(error instanceof BrotherScanError) ||
165
+ error.code !== 'busy' ||
166
+ Date.now() >= busyDeadline) {
167
+ throw error;
168
+ }
169
+ await delay(Math.min(this.busyRetryInterval, Math.max(0, busyDeadline - Date.now())));
170
+ }
171
+ }
172
+ }
173
+ async connectOnce() {
174
+ const socket = new plugins.net.Socket();
175
+ socket.setNoDelay(true);
176
+ this.socket = socket;
177
+ this.reader = new SocketBuffer(socket);
178
+ await new Promise((resolve, reject) => {
179
+ const timer = setTimeout(() => {
180
+ socket.destroy();
181
+ reject(new BrotherScanError('Timed out connecting to the Brother scanner', 'timeout'));
182
+ }, this.timeout);
183
+ const cleanup = () => {
184
+ clearTimeout(timer);
185
+ socket.off('connect', onConnect);
186
+ socket.off('error', onError);
187
+ };
188
+ const onConnect = () => {
189
+ cleanup();
190
+ resolve();
191
+ };
192
+ const onError = (error) => {
193
+ cleanup();
194
+ reject(error);
195
+ };
196
+ socket.once('connect', onConnect);
197
+ socket.once('error', onError);
198
+ socket.connect(this.port, this.address);
199
+ });
200
+ const banner = (await this.requireReader().readUntil(Buffer.from('\r\n'), this.timeout, 128))
201
+ .toString('ascii')
202
+ .trim();
203
+ if (banner.startsWith('+OK 200'))
204
+ return;
205
+ if (banner.startsWith('-NG 401')) {
206
+ throw new BrotherScanError('Brother scanner is busy', 'busy');
207
+ }
208
+ throw new BrotherScanError(`Unexpected Brother scanner banner: ${banner}`, 'invalid-response');
209
+ }
210
+ async disconnect() {
211
+ const socket = this.socket;
212
+ this.socket = null;
213
+ this.reader = null;
214
+ this.scanning = false;
215
+ if (!socket || socket.destroyed)
216
+ return;
217
+ await new Promise((resolve) => {
218
+ let settled = false;
219
+ const finish = () => {
220
+ if (settled)
221
+ return;
222
+ settled = true;
223
+ clearTimeout(timer);
224
+ socket.off('close', finish);
225
+ socket.off('error', finish);
226
+ if (!socket.destroyed)
227
+ socket.destroy();
228
+ resolve();
229
+ };
230
+ const timer = setTimeout(finish, 250);
231
+ socket.once('close', finish);
232
+ socket.once('error', finish);
233
+ socket.end();
234
+ });
235
+ }
236
+ getCapabilities() {
237
+ return {
238
+ resolutions: [100, 150, 200, 300, 600],
239
+ formats: ['jpeg'],
240
+ colorModes: ['color'],
241
+ sources: ['flatbed', 'adf', 'adf-duplex'],
242
+ maxWidth: 215.9,
243
+ maxHeight: 355.6,
244
+ minWidth: 10,
245
+ minHeight: 10,
246
+ };
247
+ }
248
+ async scan(options) {
249
+ if (!this.socket || !this.reader) {
250
+ throw new Error('Brother scanner is not connected');
251
+ }
252
+ if (this.scanning) {
253
+ throw new BrotherScanError('A Brother scan is already in progress', 'busy');
254
+ }
255
+ this.validateOptions(options);
256
+ this.scanning = true;
257
+ this.cancelled = false;
258
+ try {
259
+ await this.selectSource(options.source);
260
+ const lease = await this.requestLease(options.resolution);
261
+ this.assertLease(lease, options);
262
+ const area = this.resolveScanArea(options.area, lease);
263
+ await this.writeCommand([
264
+ '\x1bX',
265
+ `R=${lease.resolutionX},${lease.resolutionY}`,
266
+ 'M=CGRAY',
267
+ 'C=JPEG',
268
+ 'J=MID',
269
+ 'B=50',
270
+ 'N=50',
271
+ `A=${area.x},${area.y},${area.x + area.width},${area.y + area.height}`,
272
+ options.source === 'adf-duplex' ? 'D=DUP' : 'D=SIN',
273
+ ]);
274
+ const pages = await this.readPages();
275
+ if (pages.length === 0) {
276
+ throw new BrotherScanError('Brother scanner returned no document data', 'no-document');
277
+ }
278
+ const firstMetadata = readJpegMetadata(pages[0]);
279
+ return {
280
+ data: pages[0],
281
+ format: 'jpeg',
282
+ width: firstMetadata.width ?? area.width,
283
+ height: firstMetadata.height ?? area.height,
284
+ resolution: firstMetadata.resolution ?? lease.resolutionX,
285
+ colorMode: 'color',
286
+ mimeType: 'image/jpeg',
287
+ pageCount: pages.length,
288
+ pages: pages.map((data) => {
289
+ const metadata = readJpegMetadata(data);
290
+ return {
291
+ data,
292
+ width: metadata.width ?? area.width,
293
+ height: metadata.height ?? area.height,
294
+ mimeType: 'image/jpeg',
295
+ };
296
+ }),
297
+ isComplete: true,
298
+ settingsWarnings: [],
299
+ };
300
+ }
301
+ catch (error) {
302
+ if (this.cancelled) {
303
+ throw new BrotherScanError('Brother scan was cancelled', 'cancelled');
304
+ }
305
+ try {
306
+ await this.write(Buffer.from([0x1b, 0x52]));
307
+ }
308
+ catch {
309
+ // Preserve the scan error if the connection is already gone.
310
+ }
311
+ throw error;
312
+ }
313
+ finally {
314
+ this.scanning = false;
315
+ }
316
+ }
317
+ async cancel() {
318
+ if (!this.socket || !this.scanning)
319
+ return;
320
+ this.cancelled = true;
321
+ await this.write(Buffer.from([0x1b, 0x52]));
322
+ }
323
+ validateOptions(options) {
324
+ if (options.format !== 'jpeg') {
325
+ throw new BrotherScanError(`Brother native scanning returns JPEG pages, not ${options.format}`, 'unsupported');
326
+ }
327
+ if (options.colorMode !== 'color') {
328
+ throw new BrotherScanError(`Brother native ${options.colorMode} decoding is not implemented`, 'unsupported');
329
+ }
330
+ }
331
+ async selectSource(source) {
332
+ const brotherSource = source === 'flatbed' ? 'FB' : 'AUTO';
333
+ await this.writeCommand(['\x1bS', brotherSource]);
334
+ const response = await this.requireReader().readExactly(1, this.timeout);
335
+ if (response[0] !== TERMINATOR) {
336
+ throw this.statusError(response[0], 'Brother scanner rejected the requested source');
337
+ }
338
+ }
339
+ async requestLease(resolution) {
340
+ await this.writeCommand(['\x1bI', `R=${resolution},${resolution}`, 'M=CGRAY']);
341
+ const match = await this.requireReader().readMatch(/(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/, this.timeout, 256);
342
+ this.requireReader().discard();
343
+ const values = match.slice(1).map((value) => Number.parseInt(value, 10));
344
+ return {
345
+ resolutionX: values[0],
346
+ resolutionY: values[1],
347
+ adfStatus: values[2],
348
+ planeWidth: values[3],
349
+ width: values[4],
350
+ planeHeight: values[5],
351
+ height: values[6],
352
+ };
353
+ }
354
+ assertLease(lease, options) {
355
+ if (lease.resolutionX !== options.resolution || lease.resolutionY !== options.resolution) {
356
+ throw new BrotherScanError(`Brother scanner rejected ${options.resolution} dpi and offered ${lease.resolutionX}x${lease.resolutionY} dpi`, 'settings-rejected');
357
+ }
358
+ if (lease.width <= 0 || lease.height < 0) {
359
+ throw new BrotherScanError('Brother scanner returned an invalid scan area', 'invalid-response');
360
+ }
361
+ }
362
+ resolveScanArea(area, lease) {
363
+ const mmToPixels = (millimetres, dpi) => Math.round((millimetres * dpi) / 25.4);
364
+ const x = Math.max(0, mmToPixels(area.x, lease.resolutionX));
365
+ const y = Math.max(0, mmToPixels(area.y, lease.resolutionY));
366
+ const requestedWidth = mmToPixels(area.width, lease.resolutionX);
367
+ const requestedHeight = mmToPixels(area.height, lease.resolutionY);
368
+ const width = Math.max(1, Math.min(requestedWidth, lease.width - x));
369
+ // Brother ADF leases report zero height because page length is determined
370
+ // while feeding. Platen leases provide a fixed pixel height.
371
+ const height = lease.height === 0
372
+ ? Math.max(1, requestedHeight)
373
+ : Math.max(1, Math.min(requestedHeight, lease.height - y));
374
+ if (x >= lease.width || (lease.height > 0 && y >= lease.height)) {
375
+ throw new BrotherScanError('Requested scan area is outside the scanner bed', 'settings-rejected');
376
+ }
377
+ return { x, y, width, height };
378
+ }
379
+ async readPages() {
380
+ const pages = [];
381
+ let chunks = [];
382
+ let pageBytes = 0;
383
+ const wrappedChunks = new Map();
384
+ const wrappedPageBytes = new Map();
385
+ const wrappedPages = new Map();
386
+ let frameMode;
387
+ while (pages.length + wrappedPages.size < MAX_PAGES) {
388
+ const header = (await this.requireReader().readExactly(1, this.scanTimeout))[0];
389
+ if (header < 0x80) {
390
+ const lengthBytes = await this.requireReader().readExactly(2, this.scanTimeout);
391
+ const firstLength = lengthBytes.readUInt16LE(0);
392
+ if (!frameMode) {
393
+ const startsWithJpeg = firstLength >= 2 &&
394
+ (await this.requireReader().peekExactly(2, this.scanTimeout)).equals(Buffer.from([0xff, 0xd8]));
395
+ frameMode = firstLength <= 64 && !startsWithJpeg ? 'wrapped' : 'simple';
396
+ }
397
+ if (frameMode === 'wrapped') {
398
+ const metadata = await this.requireReader().readExactly(firstLength, this.scanTimeout);
399
+ const dataLengthBytes = await this.requireReader().readExactly(2, this.scanTimeout);
400
+ const dataLength = dataLengthBytes.readUInt16LE(0);
401
+ const imageNumber = metadata.length >= 2 ? metadata.readUInt16LE(0) : 0;
402
+ const imageChunks = wrappedChunks.get(imageNumber) ?? [];
403
+ imageChunks.push(await this.requireReader().readExactly(dataLength, this.scanTimeout));
404
+ wrappedChunks.set(imageNumber, imageChunks);
405
+ const imageBytes = (wrappedPageBytes.get(imageNumber) ?? 0) + dataLength;
406
+ wrappedPageBytes.set(imageNumber, imageBytes);
407
+ if (imageBytes > MAX_PAGE_BYTES) {
408
+ throw new BrotherScanError('Brother scanner page exceeded the safety limit', 'invalid-response');
409
+ }
410
+ }
411
+ else {
412
+ chunks.push(await this.requireReader().readExactly(firstLength, this.scanTimeout));
413
+ pageBytes += firstLength;
414
+ if (pageBytes > MAX_PAGE_BYTES) {
415
+ throw new BrotherScanError('Brother scanner page exceeded the safety limit', 'invalid-response');
416
+ }
417
+ }
418
+ continue;
419
+ }
420
+ if (header === 0x84 || header === 0x85) {
421
+ await this.requireReader().readExactly(1, this.scanTimeout);
422
+ continue;
423
+ }
424
+ if (header === 0x81) {
425
+ this.finishPage(chunks, pages);
426
+ chunks = [];
427
+ pageBytes = 0;
428
+ frameMode = undefined;
429
+ await this.writeCommand(['\x1bX']);
430
+ continue;
431
+ }
432
+ if (header === 0x82) {
433
+ const metadata = await this.requireReader().readExactly(9, this.scanTimeout);
434
+ const imageNumber = metadata.readUInt16LE(2);
435
+ let imageChunks = wrappedChunks.get(imageNumber);
436
+ let resolvedImageNumber = imageNumber;
437
+ if (!imageChunks && wrappedChunks.size === 1) {
438
+ const onlyImage = wrappedChunks.entries().next().value;
439
+ resolvedImageNumber = onlyImage[0];
440
+ imageChunks = onlyImage[1];
441
+ }
442
+ const page = this.makePage(imageChunks ?? []);
443
+ if (page)
444
+ wrappedPages.set(resolvedImageNumber, page);
445
+ wrappedChunks.delete(resolvedImageNumber);
446
+ wrappedPageBytes.delete(resolvedImageNumber);
447
+ frameMode = undefined;
448
+ continue;
449
+ }
450
+ if (header === TERMINATOR) {
451
+ this.finishPage(chunks, pages);
452
+ for (const [imageNumber, imageChunks] of wrappedChunks) {
453
+ const page = this.makePage(imageChunks);
454
+ if (page)
455
+ wrappedPages.set(imageNumber, page);
456
+ }
457
+ pages.push(...[...wrappedPages.entries()]
458
+ .sort(([left], [right]) => left - right)
459
+ .map(([, page]) => page));
460
+ return pages;
461
+ }
462
+ throw this.statusError(header, 'Brother scanner stopped the scan');
463
+ }
464
+ throw new BrotherScanError(`Brother scanner exceeded the ${MAX_PAGES}-page safety limit`, 'invalid-response');
465
+ }
466
+ finishPage(chunks, pages) {
467
+ const page = this.makePage(chunks);
468
+ if (page)
469
+ pages.push(page);
470
+ }
471
+ makePage(chunks) {
472
+ if (chunks.length === 0)
473
+ return undefined;
474
+ const page = Buffer.concat(chunks);
475
+ if (page[0] !== 0xff || page[1] !== 0xd8) {
476
+ const firstBytes = page.subarray(0, 8).toString('hex');
477
+ const lastBytes = page.subarray(Math.max(0, page.length - 8)).toString('hex');
478
+ throw new BrotherScanError(`Brother scanner returned an invalid JPEG page (${page.length} bytes, first ${firstBytes}, last ${lastBytes})`, 'invalid-response');
479
+ }
480
+ const endMarker = page.lastIndexOf(Buffer.from([0xff, 0xd9]));
481
+ return endMarker >= 0
482
+ ? page.subarray(0, endMarker + 2)
483
+ : Buffer.concat([page, Buffer.from([0xff, 0xd9])]);
484
+ }
485
+ statusError(status, prefix) {
486
+ if (status === 0xc2)
487
+ return new BrotherScanError(`${prefix}: no document in feeder`, 'no-document', status);
488
+ if (status === 0xc3)
489
+ return new BrotherScanError(`${prefix}: document jam`, 'document-jam', status);
490
+ if (status === 0xc4)
491
+ return new BrotherScanError(`${prefix}: cover open`, 'cover-open', status);
492
+ if (status === 0xc5)
493
+ return new BrotherScanError(`${prefix}: service error`, 'service-error', status);
494
+ if (status === 0xc6) {
495
+ return new BrotherScanError(`${prefix}: device is stuck and must be restarted`, 'device-stuck', status);
496
+ }
497
+ if (status === 0x83 || status === 0x86 || status === 0xe3) {
498
+ return new BrotherScanError(`${prefix}: cancelled`, 'cancelled', status);
499
+ }
500
+ return new BrotherScanError(`${prefix}: status 0x${status.toString(16)}`, 'invalid-response', status);
501
+ }
502
+ async writeCommand(lines) {
503
+ const command = `${lines.join('\n')}\n`;
504
+ await this.write(Buffer.concat([Buffer.from(command, 'ascii'), Buffer.from([TERMINATOR])]));
505
+ }
506
+ async write(data) {
507
+ const socket = this.socket;
508
+ if (!socket || socket.destroyed) {
509
+ throw new BrotherScanError('Brother scanner is not connected', 'invalid-response');
510
+ }
511
+ await new Promise((resolve, reject) => {
512
+ socket.write(data, (error) => error ? reject(error) : resolve());
513
+ });
514
+ }
515
+ requireReader() {
516
+ if (!this.reader)
517
+ throw new BrotherScanError('Brother scanner is not connected', 'invalid-response');
518
+ return this.reader;
519
+ }
520
+ }
521
+ function delay(milliseconds) {
522
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
523
+ }
524
+ function readJpegMetadata(data) {
525
+ if (data.length < 4 || data[0] !== 0xff || data[1] !== 0xd8)
526
+ return {};
527
+ const metadata = {};
528
+ const startOfFrameMarkers = new Set([0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf]);
529
+ let offset = 2;
530
+ while (offset + 4 <= data.length) {
531
+ while (offset < data.length && data[offset] === 0xff)
532
+ offset++;
533
+ const marker = data[offset++];
534
+ if (marker === 0xd9 || marker === 0xda)
535
+ break;
536
+ if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7))
537
+ continue;
538
+ if (offset + 2 > data.length)
539
+ break;
540
+ const length = data.readUInt16BE(offset);
541
+ if (length < 2 || offset + length > data.length)
542
+ break;
543
+ const content = offset + 2;
544
+ if (marker === 0xe0 && length >= 16 && data.toString('ascii', content, content + 5) === 'JFIF\0') {
545
+ const units = data[content + 7];
546
+ const density = data.readUInt16BE(content + 8);
547
+ if (units === 1 && density > 0)
548
+ metadata.resolution = density;
549
+ if (units === 2 && density > 0)
550
+ metadata.resolution = Math.round(density * 2.54);
551
+ }
552
+ if (startOfFrameMarkers.has(marker) && length >= 7) {
553
+ metadata.height = data.readUInt16BE(content + 1);
554
+ metadata.width = data.readUInt16BE(content + 3);
555
+ }
556
+ offset += length;
557
+ }
558
+ return metadata;
559
+ }
560
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuYnJvdGhlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3Byb3RvY29scy9wcm90b2NvbC5icm90aGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBVXpDLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDO0FBQ2xDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQztBQUM1QyxNQUFNLDhCQUE4QixHQUFHLEtBQUssQ0FBQztBQUM3QyxNQUFNLHVCQUF1QixHQUFHLE1BQU0sQ0FBQztBQUN2QyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFDdEIsTUFBTSxjQUFjLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDekMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBZXhCLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxLQUFLO0lBR3ZCO0lBQ0E7SUFIbEIsWUFDRSxPQUFlLEVBQ0MsSUFBMkIsRUFDM0IsVUFBbUI7UUFFbkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBSEMsU0FBSSxHQUFKLElBQUksQ0FBdUI7UUFDM0IsZUFBVSxHQUFWLFVBQVUsQ0FBUztRQUduQyxJQUFJLENBQUMsSUFBSSxHQUFHLGtCQUFrQixDQUFDO0lBQ2pDLENBQUM7Q0FDRjtBQThCRCxNQUFNLFlBQVk7SUFLYTtJQUpyQixNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QixLQUFLLEdBQWlCLElBQUksQ0FBQztJQUMzQixLQUFLLEdBQUcsS0FBSyxDQUFDO0lBRXRCLFlBQTZCLE1BQTBCO1FBQTFCLFdBQU0sR0FBTixNQUFNLENBQW9CO1FBQ3JELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBWSxFQUFFLEVB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
@@ -1,10 +1,15 @@
1
1
  import type { IEsclCapabilities, IEsclScanStatus, IScanOptions, IScanResult } from '../interfaces/index.js';
2
+ export declare class EsclScanError extends Error {
3
+ readonly partialResult?: IScanResult | undefined;
4
+ constructor(message: string, partialResult?: IScanResult | undefined);
5
+ }
2
6
  /**
3
7
  * eSCL/AirScan protocol client for network scanners
4
8
  */
5
9
  export declare class EsclProtocol {
6
10
  private baseUrl;
7
11
  private capabilities;
12
+ private activeJobUri;
8
13
  constructor(address: string, port: number, secure?: boolean);
9
14
  /**
10
15
  * Get scanner capabilities
@@ -27,30 +32,34 @@ export declare class EsclProtocol {
27
32
  * until complete. We try direct download first, then fall back to polling.
28
33
  */
29
34
  waitForScanComplete(jobUri: string, options: IScanOptions, pollInterval?: number): Promise<IScanResult>;
35
+ private combinePages;
30
36
  /**
31
37
  * Download scanned document
32
38
  */
33
39
  downloadScan(jobUri: string, options: IScanOptions): Promise<IScanResult>;
40
+ private downloadNextDocument;
34
41
  /**
35
42
  * Cancel a scan job
36
43
  */
37
44
  cancelJob(jobUri: string): Promise<void>;
45
+ cancelCurrentScan(): Promise<void>;
38
46
  /**
39
47
  * Build XML scan settings
40
48
  */
41
49
  private buildScanSettings;
42
- /**
43
- * Map source to eSCL format
44
- */
45
- private mapSource;
50
+ private mapIntent;
51
+ private nextDocumentDelay;
46
52
  /**
47
53
  * Parse capabilities XML response
48
54
  */
49
55
  private parseCapabilities;
56
+ private parseInputSource;
50
57
  /**
51
58
  * Parse status XML response
52
59
  */
53
60
  private parseStatus;
61
+ private resolveJobUri;
62
+ private findJob;
54
63
  /**
55
64
  * Perform a complete scan operation
56
65
  */