webzlp
Version:
A small library using WebUSB to print labels on label printers.
1,423 lines (1,421 loc) • 201 kB
JavaScript
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.webzlp = {}));
})(this, function(exports2) {
"use strict";var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var AsciiCodeStrings = /* @__PURE__ */ ((AsciiCodeStrings2) => {
AsciiCodeStrings2["NUL"] = "\0";
AsciiCodeStrings2["SOH"] = "";
AsciiCodeStrings2["STX"] = "";
AsciiCodeStrings2["ETX"] = "";
AsciiCodeStrings2["EOT"] = "";
AsciiCodeStrings2["ENQ"] = "";
AsciiCodeStrings2["ACK"] = "";
AsciiCodeStrings2["BEL"] = "\x07";
AsciiCodeStrings2["BS"] = "\b";
AsciiCodeStrings2["TAB"] = " ";
AsciiCodeStrings2["LF"] = "\n";
AsciiCodeStrings2["VT"] = "\v";
AsciiCodeStrings2["FF"] = "\f";
AsciiCodeStrings2["CR"] = "\r";
AsciiCodeStrings2["SO"] = "";
AsciiCodeStrings2["SI"] = "";
AsciiCodeStrings2["DLE"] = "";
AsciiCodeStrings2["DC1"] = "";
AsciiCodeStrings2["DC2"] = "";
AsciiCodeStrings2["DC3"] = "";
AsciiCodeStrings2["DC4"] = "";
AsciiCodeStrings2["NAK"] = "";
AsciiCodeStrings2["SYN"] = "";
AsciiCodeStrings2["ETB"] = "";
AsciiCodeStrings2["CAN"] = "";
AsciiCodeStrings2["EM"] = "";
AsciiCodeStrings2["SUB"] = "";
AsciiCodeStrings2["ESC"] = "\x1B";
AsciiCodeStrings2["FS"] = "";
AsciiCodeStrings2["GS"] = "";
AsciiCodeStrings2["RS"] = "";
AsciiCodeStrings2["US"] = "";
AsciiCodeStrings2["DEL"] = "";
return AsciiCodeStrings2;
})(AsciiCodeStrings || {});
var AsciiCodeNumbers = /* @__PURE__ */ ((AsciiCodeNumbers2) => {
AsciiCodeNumbers2[AsciiCodeNumbers2["NUL"] = 0] = "NUL";
AsciiCodeNumbers2[AsciiCodeNumbers2["SOH"] = 1] = "SOH";
AsciiCodeNumbers2[AsciiCodeNumbers2["STX"] = 2] = "STX";
AsciiCodeNumbers2[AsciiCodeNumbers2["ETX"] = 3] = "ETX";
AsciiCodeNumbers2[AsciiCodeNumbers2["EOT"] = 4] = "EOT";
AsciiCodeNumbers2[AsciiCodeNumbers2["ENQ"] = 5] = "ENQ";
AsciiCodeNumbers2[AsciiCodeNumbers2["ACK"] = 6] = "ACK";
AsciiCodeNumbers2[AsciiCodeNumbers2["BEL"] = 7] = "BEL";
AsciiCodeNumbers2[AsciiCodeNumbers2["BS"] = 8] = "BS";
AsciiCodeNumbers2[AsciiCodeNumbers2["TAB"] = 9] = "TAB";
AsciiCodeNumbers2[AsciiCodeNumbers2["LF"] = 10] = "LF";
AsciiCodeNumbers2[AsciiCodeNumbers2["VT"] = 11] = "VT";
AsciiCodeNumbers2[AsciiCodeNumbers2["FF"] = 12] = "FF";
AsciiCodeNumbers2[AsciiCodeNumbers2["CR"] = 13] = "CR";
AsciiCodeNumbers2[AsciiCodeNumbers2["SO"] = 14] = "SO";
AsciiCodeNumbers2[AsciiCodeNumbers2["SI"] = 15] = "SI";
AsciiCodeNumbers2[AsciiCodeNumbers2["DLE"] = 16] = "DLE";
AsciiCodeNumbers2[AsciiCodeNumbers2["DC1"] = 17] = "DC1";
AsciiCodeNumbers2[AsciiCodeNumbers2["DC2"] = 18] = "DC2";
AsciiCodeNumbers2[AsciiCodeNumbers2["DC3"] = 19] = "DC3";
AsciiCodeNumbers2[AsciiCodeNumbers2["DC4"] = 20] = "DC4";
AsciiCodeNumbers2[AsciiCodeNumbers2["NAK"] = 21] = "NAK";
AsciiCodeNumbers2[AsciiCodeNumbers2["SYN"] = 22] = "SYN";
AsciiCodeNumbers2[AsciiCodeNumbers2["ETB"] = 23] = "ETB";
AsciiCodeNumbers2[AsciiCodeNumbers2["CAN"] = 24] = "CAN";
AsciiCodeNumbers2[AsciiCodeNumbers2["EM"] = 25] = "EM";
AsciiCodeNumbers2[AsciiCodeNumbers2["SUB"] = 26] = "SUB";
AsciiCodeNumbers2[AsciiCodeNumbers2["ESC"] = 27] = "ESC";
AsciiCodeNumbers2[AsciiCodeNumbers2["FS"] = 28] = "FS";
AsciiCodeNumbers2[AsciiCodeNumbers2["GS"] = 29] = "GS";
AsciiCodeNumbers2[AsciiCodeNumbers2["RS"] = 30] = "RS";
AsciiCodeNumbers2[AsciiCodeNumbers2["US"] = 31] = "US";
AsciiCodeNumbers2[AsciiCodeNumbers2["DEL"] = 127] = "DEL";
return AsciiCodeNumbers2;
})(AsciiCodeNumbers || {});
const AsciiToDisplayLookup = {
[
0
/* NUL */
]: "NUL",
[
1
/* SOH */
]: "SOH",
[
2
/* STX */
]: "STX",
[
3
/* ETX */
]: "ETX",
[
4
/* EOT */
]: "EOT",
[
5
/* ENQ */
]: "ENQ",
[
6
/* ACK */
]: "ACK",
[
7
/* BEL */
]: "BEL",
[
8
/* BS */
]: "BS",
[
9
/* TAB */
]: "TAB",
[
10
/* LF */
]: "LF",
[
11
/* VT */
]: "VT",
[
12
/* FF */
]: "FF",
[
13
/* CR */
]: "CR",
[
14
/* SO */
]: "SO",
[
15
/* SI */
]: "SI",
[
16
/* DLE */
]: "DLE",
[
17
/* DC1 */
]: "DC1",
[
18
/* DC2 */
]: "DC2",
[
19
/* DC3 */
]: "DC3",
[
20
/* DC4 */
]: "DC4",
[
21
/* NAK */
]: "NAK",
[
22
/* SYN */
]: "SYN",
[
23
/* ETB */
]: "ETB",
[
24
/* CAN */
]: "CAN",
[
25
/* EM */
]: "EM",
[
26
/* SUB */
]: "SUB",
[
27
/* ESC */
]: "ESC",
[
28
/* FS */
]: "FS",
[
29
/* GS */
]: "GS",
[
30
/* RS */
]: "RS",
[
31
/* US */
]: "US",
[
127
/* DEL */
]: "DEL"
};
function hex(num) {
return "0x" + (num + 256).toString(16).slice(-2);
}
function asciiToDisplay(...codes) {
return codes.map((c) => {
const controlcode = c < 32 ? AsciiToDisplayLookup[c] : String.fromCharCode(c);
return `${hex(c)}[${controlcode}]`;
}).join(", ");
}
function EncodeAscii(str) {
const out = new Uint8Array(str.length);
for (let charIdx = 0; charIdx < str.length; charIdx++) {
const char = str.charCodeAt(charIdx);
if (char > 255) {
throw new Error(`Encountered non-ASCII character \`${str[charIdx]}\` (code ${char}) at index ${charIdx} of \`${str}\``);
}
out[charIdx] = char;
}
return out;
}
function DecodeAscii(input) {
if (input === void 0) {
return "";
}
return String.fromCharCode(...input);
}
function hasFlag(val, flag) {
return (val & flag) === flag;
}
function exhaustiveMatchGuard(_) {
throw new Error("Invalid case received!" + _);
}
class WebZlpError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}
var DitheringMethod = /* @__PURE__ */ ((DitheringMethod2) => {
DitheringMethod2[DitheringMethod2["none"] = 0] = "none";
return DitheringMethod2;
})(DitheringMethod || {});
const _BitmapGRF = class _BitmapGRF {
constructor(bitmapGRF, imageWidth, imageHeight, bytesPerRow, boundingBox) {
__publicField(this, "_bitmap");
__publicField(this, "_width");
__publicField(this, "_height");
__publicField(this, "_bytesPerRow");
__publicField(this, "_boundingBox");
this._bitmap = bitmapGRF;
this._width = imageWidth;
this._height = imageHeight;
this._bytesPerRow = bytesPerRow;
this._boundingBox = Object.freeze(boundingBox);
}
/** Gets the actual width of the image file, not including any padding. */
get width() {
return this._width;
}
/** Gets the actual height of the image file, not inlcuding any padding. */
get height() {
return this._height;
}
/** Gets the number of bytes per row (width) of the image file. */
get bytesPerRow() {
return this._bytesPerRow;
}
/** Gets the total number of uncompressed bytes of the image file. Usually used in printer commands. */
get bytesUncompressed() {
return this._bitmap.length;
}
/** Gets the bounding box information for this image, for proper alignment of trimmed images. */
get boundingBox() {
return this._boundingBox;
}
/** Create a copy of this bitmap. */
copy() {
return new _BitmapGRF(
this._bitmap.slice(0),
this._width,
this._height,
this._bytesPerRow,
this.boundingBox
);
}
/** Get a raw binary representation of this GRF. This is raw binary with no compression, compatible with EPL and ZPL.
*
* The image may need to be offset according to the bounding box padding. Use the bytesPerRow for data length calculations.
*
* Example use:
* ```
* const grf = new BitmapGRF();
* const zplCmd = `^GFC,${grf.bytesUncompressed},${grf.bytesUncompressed},${grf.bytesPerRow},${grf.toBinaryGRF()}`;
*
* const eplCmd = `GW${grf.boundingBox.paddingLeft},${grf.boundingBox.paddingTop},${grf.bytesPerRow},${grf.height},${grf.toBitmapGRF}`;
* ```
*/
toBinaryGRF() {
return this._bitmap;
}
/** Gets an ImageData representation of this GRF. Can be used to draw into Canvas elements. */
toImageData() {
const buffer = new Uint8ClampedArray(this._bitmap.length * 4 * 8);
for (let i = 0, n = this._bitmap.length; i < n; i++) {
for (let offset = 7; offset >= 0; offset--) {
const outOffset = i * 8 * 4 + (7 - offset) * 4;
const pixel = (this._bitmap[i] >> offset & 1) === 1 ? 255 : 0;
buffer[outOffset + 0] = pixel;
buffer[outOffset + 1] = pixel;
buffer[outOffset + 2] = pixel;
buffer[outOffset + 3] = 255;
}
}
return new ImageData(buffer, this.width, this.height);
}
/** Gets a bitmap GRF that has its colors inverted.
*
* EPL uses 1 as white. ZPL uses 1 as black. Use this to convert between them.
*/
toInvertedGRF() {
const buffer = new Uint8Array(this._bitmap.length);
for (let i = 0, n = this._bitmap.length; i < n; i++) {
buffer[i] = ~this._bitmap[i];
}
return new _BitmapGRF(
buffer,
this.width,
this.height,
this.bytesPerRow,
structuredClone(this.boundingBox)
);
}
/** Get a compressed representation of this GRF. This is not compatible with EPL.
* This is also referred to as the "Alternate Compression Scheme" or "Zebra Compression".
*
* The image may need to be offset according to the bounding box.
*
* Example use:
* ```
* const grf = new BitmapGRF();
* const cmd = `^GFA,${grf.bytesUncompressed},${grf.bytesUncompressed},${grf.bytesPerRow},${grf.toZebraCompressedGrf()}`;
* ```
*/
toZebraCompressedGRF() {
const buf = this._bitmap;
let hex2 = "";
for (let i = 0, l = buf.length; i < l; i++) {
hex2 += _BitmapGRF.hexmap[buf[i]];
}
const re = /([0-9a-fA-F])\1{2,}/g;
let acs = "";
let match = re.exec(hex2);
let offset = 0;
while (match) {
acs += hex2.substring(offset, match.index);
let l = match[0].length;
while (l >= 400) {
acs += "z";
l -= 400;
}
if (l >= 20) {
acs += "_ghijklmnopqrstuvwxy"[l / 20 | 0];
l = l % 20;
}
if (l) {
acs += "_GHIJKLMNOPQRSTUVWXY"[l];
}
acs += match[1];
offset = re.lastIndex;
match = re.exec(hex2);
}
acs += hex2.substr(offset);
return acs;
}
/**
* Rotate the image, returning a new image.
* @param angle The angle to rotate the image.
*/
rotate(angle) {
switch (angle) {
default:
exhaustiveMatchGuard(angle);
break;
case 0:
return this.copy();
case 180: {
const buf = Array(this._bitmap.length);
for (let i = 0; i < this._bitmap.length; i++) {
buf[this._bitmap.length - 1 - i] = _BitmapGRF.revByte(this._bitmap[i]);
}
return new _BitmapGRF(
new Uint8Array(buf),
this._width,
this._height,
this._bytesPerRow,
this.boundingBox
);
}
}
}
static revByte(byte) {
let x = byte;
x = x >> 1 & 1431655765 | (x & 1431655765) << 1;
x = x >> 2 & 858993459 | (x & 858993459) << 2;
x = x >> 4 & 252645135 | (x & 252645135) << 4;
return x >>> 0;
}
// TODO: ASCII-compressed formats are only supported on newer firmwares.
// Implement feature detection into the transpiler operation to choose the most
// appropriate compression format such as LZ77/DEFLATE compression for Z64.
// public toAsciiB64(): string { }
// public toAsciiZ64(): string { }
/**
* Create a GRF bitmap from a raw RGBA array-like object.
*/
static fromRGBA(data, width, imageOptions) {
const {
grayThreshold = 70,
trimWhitespace = true,
ditheringMethod = 0
/* none */
} = imageOptions ?? {};
width = width | 0;
if (!width || width < 0) {
throw new BitmapFormatError("Image width must be provided for RGBA data.");
}
if (data.length % 4 !== 0) {
throw new BitmapFormatError(`Array data is not a multiple of 4, is it RGBA data?`);
}
const height = ~~(data.length / width / 4);
const { monochromeData, imageWidth, imageHeight, boundingBox } = this.toMonochrome(
data,
width,
height,
{ grayThreshold, trimWhitespace, ditheringMethod }
);
const { grfData, bytesPerRow } = this.monochromeToGRF(
monochromeData,
imageWidth,
imageHeight
);
return new _BitmapGRF(grfData, bytesPerRow * 8, imageHeight, bytesPerRow, boundingBox);
}
/**
* Create a GRF bitmap from a canvas ImageData object.
* @param imageData The canvas ImageData object to convert.
* @param grayThreshold The cutoff percentage below which values are considered black. Defaults to 75% of white.
* @param trimWhitespace Trim image to save space, storing trim amounts in the bounding box.
* @returns The bitmap GRF file.
*/
static fromCanvasImageData(imageData, imageOptions) {
const {
grayThreshold = 70,
trimWhitespace = true,
ditheringMethod = 0
/* none */
} = imageOptions ?? {};
return this.fromRGBA(imageData.data, imageData.width, {
grayThreshold,
trimWhitespace,
ditheringMethod
});
}
/** Use an SVG string as a bitmap image, rendered at the width and height provided. */
static async fromSVG(svg, widthInDots, heightInDots, imageConversionOptions) {
var _a;
const tempcontainer = new Document().createElement("div");
tempcontainer.innerHTML = svg;
const svgElement = tempcontainer.firstChild;
if (((_a = svgElement == null ? void 0 : svgElement.tagName) == null ? void 0 : _a.toLowerCase()) !== "svg") {
throw new BitmapFormatError(
`The top-level element of the SVG file must be an <svg> tag, but got '${svgElement == null ? void 0 : svgElement.tagName}' instead.`
);
}
svgElement.setAttribute("width", `${widthInDots}px`);
svgElement.setAttribute("height", `${heightInDots}px`);
svg = new XMLSerializer().serializeToString(svgElement);
const datauri = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
const img = new Image(widthInDots, heightInDots);
img.src = datauri;
const ctx = new OffscreenCanvas(widthInDots, heightInDots).getContext("2d");
ctx.imageSmoothingEnabled = false;
await img.decode();
ctx.drawImage(img, 0, 0);
const data = ctx.getImageData(0, 0, widthInDots, heightInDots);
return this.fromCanvasImageData(data, imageConversionOptions);
}
/** Convert a Base64 encoded PNG to a BitmapGRF. */
static async fromBase64PNG(png, imageConversionOptions) {
const img = new Image();
img.src = png;
await img.decode();
const ctx = new OffscreenCanvas(img.width, img.height).getContext("2d");
ctx.imageSmoothingEnabled = false;
ctx.drawImage(img, 0, 0);
const data = ctx.getImageData(0, 0, img.width, img.height);
return this.fromCanvasImageData(data, imageConversionOptions);
}
/** Converts monochrome data to GRF format. */
static monochromeToGRF(monochromeData, width, height) {
const bytesPerRow = ~~((width + 7) / 8);
const paddingToAdd = (8 - width % 8) % 8;
const buffer = new Uint8Array(bytesPerRow * height);
let idx = 0;
let byte = 0;
let bitx = 0;
for (let i = 0, n = monochromeData.length; i < n; i++) {
byte |= monochromeData[i] << 7 - (bitx++ & 7);
if (bitx == width || !(bitx & 7)) {
if (bitx == width) {
bitx = 0;
byte |= (1 << paddingToAdd) - 1;
}
buffer[idx++] = byte;
byte = 0;
}
}
return { grfData: buffer, bytesPerRow };
}
/**
* Converts an RGBA array to monochrome, 1-bit-per-byte.
* This supports trimming the image to save space, and will remove whitespace
* to an internal bounding box. The results of this padding are stored as the
* bounding box information for the bitmap.
*/
static toMonochrome(rgba, width, height, { grayThreshold, trimWhitespace, ditheringMethod }) {
const threshold = 255 * (grayThreshold ?? 70) / 100;
if (ditheringMethod !== void 0 && ditheringMethod !== 0) {
throw new WebZlpError(
`Dithering method ${DitheringMethod[ditheringMethod]} is not supported.`
);
}
let minx, maxx, miny, maxy;
if (trimWhitespace !== true) {
minx = miny = 0;
maxx = width - 1;
maxy = height - 1;
} else {
maxx = maxy = 0;
minx = width;
miny = height;
let x = 0, y = 0;
for (let i = 0, n = width * height * 4; i < n; i += 4) {
const gray = this.colorToGrayscale(
rgba[i + 0],
rgba[i + 1],
rgba[i + 2],
rgba[i + 3]
);
if (gray <= threshold) {
if (minx > x) minx = x;
if (miny > y) miny = y;
if (maxx < x) maxx = x;
if (maxy < y) maxy = y;
}
if (++x == width) {
x = 0;
y++;
}
}
}
let contentWidth;
let contentHeight;
let buffer;
if (minx > maxx || miny > maxy) {
contentWidth = contentHeight = 1;
minx = miny = 0;
buffer = new Uint8Array([1]);
} else {
contentWidth = maxx - minx + 1;
contentHeight = maxy - miny + 1;
buffer = new Uint8Array(contentWidth * contentHeight);
let idx = 0;
for (let y = miny; y <= maxy; y++) {
let i = (y * width + minx) * 4;
for (let x = minx; x <= maxx; x++) {
const gray = this.colorToGrayscale(
rgba[i + 0],
rgba[i + 1],
rgba[i + 2],
rgba[i + 3]
);
buffer[idx++] = gray >= threshold ? 1 : 0;
i += 4;
}
}
}
return {
monochromeData: buffer,
imageWidth: contentWidth,
imageHeight: contentHeight,
boundingBox: {
width,
height,
paddingLeft: minx,
paddingTop: miny,
paddingRight: width - (this.roundUpToByte(contentWidth) + minx),
paddingBottom: height - (contentHeight + miny)
}
};
}
static roundUpToByte(value) {
return Math.ceil(value / 8) * 8;
}
static colorToGrayscale(r, g, b, a, backgroundGray) {
backgroundGray = backgroundGray ?? 255;
const alpha = a / 255;
const red = Math.pow(r / 255, 2.2) * 0.2126;
const blu = Math.pow(g / 255, 2.2) * 0.7152;
const grn = Math.pow(b / 255, 2.2) * 0.0722;
const gray = Math.pow(red + blu + grn, 0.454545) * 255;
return (1 - alpha) * backgroundGray + alpha * gray;
}
};
/** Lookup table for binary to hex values. */
__publicField(_BitmapGRF, "hexmap", (() => {
const arr = Array(256);
for (let i = 0; i < 16; i++) {
arr[i] = "0" + i.toString(16);
}
for (let i = 16; i < 256; i++) {
arr[i] = i.toString(16);
}
return arr;
})());
let BitmapGRF = _BitmapGRF;
class BitmapFormatError extends WebZlpError {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}
function range(start, stop, step = 1) {
return Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);
}
function clampToRange(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function numberInRange(str, min, max) {
if (!/^[+-]?\d+$/.test(str)) {
return;
}
const val = Number(str);
if (min !== void 0 && val < min) {
return;
}
if (max !== void 0 && val > max) {
return;
}
return val;
}
function repeat(val, count) {
return new Array(count).fill(val);
}
function roundToNearestStep(value, step) {
const inverse = 1 / step;
return Math.round(value * inverse) / inverse;
}
function sliceToNewline(msg) {
if (msg === void 0) {
return {
sliced: new Uint8Array(),
remainder: new Uint8Array()
};
}
const idx = msg.indexOf(AsciiCodeNumbers.LF);
if (idx === -1) {
return {
sliced: new Uint8Array(),
remainder: msg
};
}
return {
sliced: msg.slice(0, idx + 1),
remainder: msg.slice(idx + 1)
};
}
function sliceToCRLF(msg) {
if (msg === void 0) {
return {
sliced: "",
remainder: ""
};
}
const cr = msg.indexOf("\r\n");
if (cr !== -1) {
return {
sliced: msg.substring(0, cr),
remainder: msg.substring(cr + 2)
};
}
const lf = msg.indexOf("\n");
if (lf !== -1) {
return {
sliced: msg.substring(0, lf),
remainder: msg.substring(lf + 1)
};
}
return {
sliced: "",
remainder: msg
};
}
function promiseWithTimeout(promise, ms, timeoutError = new Error("Promise timed out")) {
const timeout = new Promise((_, reject) => {
setTimeout(() => {
reject(timeoutError);
}, ms);
});
return Promise.race([promise, timeout]);
}
var SerialPortSpeed = /* @__PURE__ */ ((SerialPortSpeed2) => {
SerialPortSpeed2[SerialPortSpeed2["s110"] = 110] = "s110";
SerialPortSpeed2[SerialPortSpeed2["s300"] = 300] = "s300";
SerialPortSpeed2[SerialPortSpeed2["s600"] = 600] = "s600";
SerialPortSpeed2[SerialPortSpeed2["s1200"] = 1200] = "s1200";
SerialPortSpeed2[SerialPortSpeed2["s2400"] = 2400] = "s2400";
SerialPortSpeed2[SerialPortSpeed2["s4800"] = 4800] = "s4800";
SerialPortSpeed2[SerialPortSpeed2["s9600"] = 9600] = "s9600";
SerialPortSpeed2[SerialPortSpeed2["s14400"] = 14400] = "s14400";
SerialPortSpeed2[SerialPortSpeed2["s19200"] = 19200] = "s19200";
SerialPortSpeed2[SerialPortSpeed2["s28800"] = 28800] = "s28800";
SerialPortSpeed2[SerialPortSpeed2["s38400"] = 38400] = "s38400";
SerialPortSpeed2[SerialPortSpeed2["s57600"] = 57600] = "s57600";
SerialPortSpeed2[SerialPortSpeed2["s115200"] = 115200] = "s115200";
return SerialPortSpeed2;
})(SerialPortSpeed || {});
var SerialPortParity = /* @__PURE__ */ ((SerialPortParity2) => {
SerialPortParity2[SerialPortParity2["none"] = 0] = "none";
SerialPortParity2[SerialPortParity2["odd"] = 1] = "odd";
SerialPortParity2[SerialPortParity2["even"] = 2] = "even";
return SerialPortParity2;
})(SerialPortParity || {});
var SerialPortDataBits = /* @__PURE__ */ ((SerialPortDataBits2) => {
SerialPortDataBits2[SerialPortDataBits2["seven"] = 7] = "seven";
SerialPortDataBits2[SerialPortDataBits2["eight"] = 8] = "eight";
return SerialPortDataBits2;
})(SerialPortDataBits || {});
var SerialPortStopBits = /* @__PURE__ */ ((SerialPortStopBits2) => {
SerialPortStopBits2[SerialPortStopBits2["one"] = 1] = "one";
SerialPortStopBits2[SerialPortStopBits2["two"] = 2] = "two";
return SerialPortStopBits2;
})(SerialPortStopBits || {});
var SerialPortHandshake = /* @__PURE__ */ ((SerialPortHandshake2) => {
SerialPortHandshake2[SerialPortHandshake2["xon_xoff"] = 0] = "xon_xoff";
SerialPortHandshake2[SerialPortHandshake2["dtr_dsr"] = 1] = "dtr_dsr";
SerialPortHandshake2[SerialPortHandshake2["rts_cts"] = 2] = "rts_cts";
SerialPortHandshake2[SerialPortHandshake2["dtr_dsr_and_xon_xoff"] = 3] = "dtr_dsr_and_xon_xoff";
return SerialPortHandshake2;
})(SerialPortHandshake || {});
var SerialPortZebraProtocol = /* @__PURE__ */ ((SerialPortZebraProtocol2) => {
SerialPortZebraProtocol2[SerialPortZebraProtocol2["none"] = 0] = "none";
SerialPortZebraProtocol2[SerialPortZebraProtocol2["ack_nak"] = 1] = "ack_nak";
SerialPortZebraProtocol2[SerialPortZebraProtocol2["zebra"] = 2] = "zebra";
return SerialPortZebraProtocol2;
})(SerialPortZebraProtocol || {});
var PrintOrientation = /* @__PURE__ */ ((PrintOrientation2) => {
PrintOrientation2[PrintOrientation2["normal"] = 0] = "normal";
PrintOrientation2[PrintOrientation2["inverted"] = 1] = "inverted";
return PrintOrientation2;
})(PrintOrientation || {});
var PrintSpeed = /* @__PURE__ */ ((PrintSpeed2) => {
PrintSpeed2[PrintSpeed2["unknown"] = -1] = "unknown";
PrintSpeed2[PrintSpeed2["ipsAuto"] = 0] = "ipsAuto";
PrintSpeed2[PrintSpeed2["ipsPrinterMin"] = 1] = "ipsPrinterMin";
PrintSpeed2[PrintSpeed2["ips1"] = 2] = "ips1";
PrintSpeed2[PrintSpeed2["ips1_5"] = 3] = "ips1_5";
PrintSpeed2[PrintSpeed2["ips2"] = 4] = "ips2";
PrintSpeed2[PrintSpeed2["ips2_5"] = 5] = "ips2_5";
PrintSpeed2[PrintSpeed2["ips3"] = 6] = "ips3";
PrintSpeed2[PrintSpeed2["ips3_5"] = 7] = "ips3_5";
PrintSpeed2[PrintSpeed2["ips4"] = 8] = "ips4";
PrintSpeed2[PrintSpeed2["ips5"] = 9] = "ips5";
PrintSpeed2[PrintSpeed2["ips6"] = 10] = "ips6";
PrintSpeed2[PrintSpeed2["ips7"] = 11] = "ips7";
PrintSpeed2[PrintSpeed2["ips8"] = 12] = "ips8";
PrintSpeed2[PrintSpeed2["ips9"] = 13] = "ips9";
PrintSpeed2[PrintSpeed2["ips10"] = 14] = "ips10";
PrintSpeed2[PrintSpeed2["ips11"] = 15] = "ips11";
PrintSpeed2[PrintSpeed2["ips12"] = 16] = "ips12";
PrintSpeed2[PrintSpeed2["ips13"] = 17] = "ips13";
PrintSpeed2[PrintSpeed2["ips14"] = 18] = "ips14";
PrintSpeed2[PrintSpeed2["ipsPrinterMax"] = 1e3] = "ipsPrinterMax";
return PrintSpeed2;
})(PrintSpeed || {});
var ThermalPrintMode = /* @__PURE__ */ ((ThermalPrintMode2) => {
ThermalPrintMode2[ThermalPrintMode2["direct"] = 0] = "direct";
ThermalPrintMode2[ThermalPrintMode2["transfer"] = 1] = "transfer";
return ThermalPrintMode2;
})(ThermalPrintMode || {});
var MediaMediaGapDetectionMode = /* @__PURE__ */ ((MediaMediaGapDetectionMode2) => {
MediaMediaGapDetectionMode2[MediaMediaGapDetectionMode2["continuous"] = 0] = "continuous";
MediaMediaGapDetectionMode2[MediaMediaGapDetectionMode2["webSensing"] = 1] = "webSensing";
MediaMediaGapDetectionMode2[MediaMediaGapDetectionMode2["markSensing"] = 2] = "markSensing";
MediaMediaGapDetectionMode2[MediaMediaGapDetectionMode2["autoDuringCalibration"] = 3] = "autoDuringCalibration";
MediaMediaGapDetectionMode2[MediaMediaGapDetectionMode2["continuousVariableLength"] = 4] = "continuousVariableLength";
return MediaMediaGapDetectionMode2;
})(MediaMediaGapDetectionMode || {});
var MediaPrintMode = /* @__PURE__ */ ((MediaPrintMode2) => {
MediaPrintMode2[MediaPrintMode2["tearOff"] = 0] = "tearOff";
MediaPrintMode2[MediaPrintMode2["peel"] = 1] = "peel";
MediaPrintMode2[MediaPrintMode2["peelWithPrePeel"] = 2] = "peelWithPrePeel";
MediaPrintMode2[MediaPrintMode2["peelWithButtonTap"] = 3] = "peelWithButtonTap";
MediaPrintMode2[MediaPrintMode2["cutter"] = 4] = "cutter";
MediaPrintMode2[MediaPrintMode2["cutterWaitForCommand"] = 5] = "cutterWaitForCommand";
MediaPrintMode2[MediaPrintMode2["rewind"] = 6] = "rewind";
MediaPrintMode2[MediaPrintMode2["applicator"] = 7] = "applicator";
MediaPrintMode2[MediaPrintMode2["rfid"] = 8] = "rfid";
MediaPrintMode2[MediaPrintMode2["kiosk"] = 9] = "kiosk";
return MediaPrintMode2;
})(MediaPrintMode || {});
class SpeedTable {
constructor(speedTable = /* @__PURE__ */ new Map()) {
this.speedTable = speedTable;
}
// Speed is determined by what the printer supports
// EPL printers have a table that determines their setting and it needs to be hardcoded.
// ZPL printers follow this pattern:
// 1 = 25.4 mm/sec. (1 inch/sec.)
// A or 2 = 50.8 mm/sec. (2 inches/sec.)
// A is the default print and backfeed speed
// B or 3 = 76.2 mm/sec. (3 inches/sec.)
// C or 4 = 101.6 mm/sec. (4 inches/sec.)
// 5 = 127 mm/sec. (5 inches/sec.)
// D or 6 = 152.4 mm/sec. (6 inches/sec.)
// D is the default media slew speed
// 7 = 177.8 mm/sec. (7 inches/sec.)
// E or 8 = 203.2 mm/sec. (8 inches/sec.)
// 9 = 220.5 mm/sec. (9 inches/sec.)
// 10 = 245 mm/sec. (10 inches/sec.)
// 11 = 269.5 mm/sec. (11 inches/sec.)
// 12 = 304.8 mm/sec. (12 inches/sec.)
// 13 = 13 in/sec
// 14 = 14 in/sec
// This gets encoded into the speed table.
// Every speed table should also have entries for ipsPrinterMin, ipsPrinterMax, and auto.
// These should be duplicate entries of real values in the speed table so that
// we have sane defaults for commands to default to.
get table() {
return this.speedTable;
}
// My kingdom for extension methods on enums in a reasonable manner.
/** Look up a speed enum value from a given whole number */
static getSpeedFromWholeNumber(speed) {
switch (speed) {
default:
return -1;
case 0:
return 0;
case 1:
return 2;
case 2:
return 4;
case 3:
return 6;
case 4:
return 8;
case 5:
return 9;
case 6:
return 10;
case 7:
return 11;
case 8:
return 12;
case 9:
return 13;
case 10:
return 14;
case 11:
return 15;
case 12:
return 16;
case 13:
return 17;
case 14:
return 18;
}
}
/** Determine if a given speed will work with this model. */
isValid(speed) {
return this.speedTable.has(speed);
}
/** Get a raw value to send to the printer for a speed. */
toRawSpeed(speed) {
const val = this.speedTable.get(speed) ?? this.speedTable.get(
0
/* ipsAuto */
);
return val ?? 0;
}
/** Get a speed value from the raw value sent by the printer. Defaults to minimum if parse fails. */
fromRawSpeed(rawSpeed) {
for (const [key, val] of this.speedTable) {
if (val === rawSpeed && key != 0 && key != 1e3 && key != 1) {
return key;
}
}
return 0;
}
}
class PrintSpeedSettings {
constructor(printSpeed, slewSpeed) {
/** Speed during printing media. */
__publicField(this, "printSpeed");
/** Speed during feeding a blank media. ZPL only, same as media speed for EPL. */
__publicField(this, "slewSpeed");
this.printSpeed = printSpeed;
this.slewSpeed = slewSpeed ?? printSpeed;
}
}
var PrinterCommandLanguage = /* @__PURE__ */ ((PrinterCommandLanguage2) => {
PrinterCommandLanguage2[PrinterCommandLanguage2["none"] = 0] = "none";
PrinterCommandLanguage2[PrinterCommandLanguage2["epl"] = 1] = "epl";
PrinterCommandLanguage2[PrinterCommandLanguage2["zpl"] = 2] = "zpl";
PrinterCommandLanguage2[PrinterCommandLanguage2["cpcl"] = 4] = "cpcl";
PrinterCommandLanguage2[PrinterCommandLanguage2["ipl"] = 8] = "ipl";
PrinterCommandLanguage2[PrinterCommandLanguage2["dpl"] = 16] = "dpl";
PrinterCommandLanguage2[PrinterCommandLanguage2["zplEmulateEpl"] = 3] = "zplEmulateEpl";
PrinterCommandLanguage2[PrinterCommandLanguage2["cpclEmulateBoth"] = 7] = "cpclEmulateBoth";
return PrinterCommandLanguage2;
})(PrinterCommandLanguage || {});
class BasePrinterConfig {
constructor() {
// Read-only printer config info
__publicField(this, "_serial", "no_serial_nm");
__publicField(this, "_model", "Unknown Model");
__publicField(this, "_manufacturer", "Unknown Manufacturer");
__publicField(this, "_dpi", 203);
__publicField(this, "_firmware", "");
__publicField(this, "_speed", new PrintSpeedSettings(PrintSpeed.unknown));
__publicField(this, "_speedTable", new SpeedTable());
__publicField(this, "_darkness", 50);
__publicField(this, "_backfeedAfterTaken", "90");
__publicField(this, "_feedButtonMode", "feedBlank");
__publicField(this, "_maxMediaDarkness", 15);
__publicField(this, "_thermalPrintMode", ThermalPrintMode.direct);
__publicField(this, "_mediaPrintMode", MediaPrintMode.tearOff);
__publicField(this, "mediaDimensionRoundingStep", 0.25);
__publicField(this, "_printOrientation", PrintOrientation.normal);
__publicField(this, "_mediaGapDetectMode", MediaMediaGapDetectionMode.webSensing);
__publicField(this, "_mediaPrintOriginOffsetDots", { left: 0, top: 0 });
__publicField(this, "_mediaGapDots", 0);
__publicField(this, "_mediaLineOffsetDots", 0);
__publicField(this, "_mediaWidthDots", 100);
__publicField(this, "_maxMediaWidthDots", 200);
__publicField(this, "_mediaLengthDots", 100);
__publicField(this, "_maxMediaLengthDots", 200);
}
get serialNumber() {
return this._serial;
}
get model() {
return this._model;
}
get manufacturer() {
return this._manufacturer;
}
get dpi() {
return this._dpi;
}
get firmware() {
return this._firmware;
}
get speed() {
return this._speed;
}
get speedTable() {
return this._speedTable;
}
get darknessPercent() {
return this._darkness;
}
get backfeedAfterTaken() {
return this._backfeedAfterTaken;
}
get feedButtonMode() {
return this._feedButtonMode;
}
get maxMediaDarkness() {
return this._maxMediaDarkness;
}
get thermalPrintMode() {
return this._thermalPrintMode;
}
get mediaPrintMode() {
return this._mediaPrintMode;
}
get printOrientation() {
return this._printOrientation;
}
get mediaGapDetectMode() {
return this._mediaGapDetectMode;
}
get mediaPrintOriginOffsetDots() {
return this._mediaPrintOriginOffsetDots;
}
get mediaGapDots() {
return this._mediaGapDots;
}
get mediaGapInches() {
return this.dotToInch(this._mediaGapDots);
}
get mediaLineOffsetDots() {
return this._mediaLineOffsetDots;
}
get mediaLineOffsetInches() {
return this.dotToInch(this.mediaLineOffsetDots);
}
get mediaWidthDots() {
return this._mediaWidthDots;
}
get mediaWidthInches() {
return this.dotToInch(this.mediaWidthDots);
}
get maxMediaWidthDots() {
return this._maxMediaWidthDots;
}
get mediaLengthDots() {
return this._mediaLengthDots;
}
get mediaLengthInches() {
return this.dotToInch(this.mediaLengthDots);
}
get maxMediaLengthDots() {
return this._maxMediaLengthDots;
}
dotToInch(dots) {
if (dots === void 0 || this.dpi === void 0) {
return 0;
}
return Math.round(dots / this.dpi * 100 + Number.EPSILON) / 100;
}
}
class CommandEffectFlags extends Set {
}
const NoEffect = new CommandEffectFlags();
const AwaitsEffect = new CommandEffectFlags(["waitsForResponse"]);
var CommandReorderBehavior = /* @__PURE__ */ ((CommandReorderBehavior2) => {
CommandReorderBehavior2[CommandReorderBehavior2["closeForm"] = 0] = "closeForm";
CommandReorderBehavior2[CommandReorderBehavior2["afterAllForms"] = 1] = "afterAllForms";
CommandReorderBehavior2[CommandReorderBehavior2["beforeAllForms"] = 2] = "beforeAllForms";
CommandReorderBehavior2[CommandReorderBehavior2["throwError"] = 3] = "throwError";
return CommandReorderBehavior2;
})(CommandReorderBehavior || {});
const basicCommandTypes = [
// Users/PCLs may supply printer commands. This uses a different lookup table.
"CustomCommand",
// General printer commands
"Identify",
"RebootPrinter",
"Raw",
"NoOp",
// Status commands
"GetStatus",
"PrintConfiguration",
"QueryConfiguration",
// Configuration commands
"SaveCurrentConfiguration",
"AutosenseMediaDimensions",
"SetDarkness",
"SetLabelDimensions",
"SetLabelHome",
"SetLabelPrintOriginOffset",
"SetMediaToContinuousMedia",
"SetMediaToWebGapMedia",
"SetMediaToMarkMedia",
"SetPrintDirection",
"SetPrintSpeed",
"SetBackfeedAfterTaken",
// Document handling
"NewLabel",
"StartLabel",
"EndLabel",
"CutNow",
"Print",
// Content
"ClearImageBuffer",
"AddBox",
"AddImage",
"AddLine",
"Offset"
];
function getCommandAnyType(cmd) {
if (cmd.type === "CustomCommand") {
return cmd.typeExtended;
} else {
return cmd.type;
}
}
class BasicCommand {
constructor(effects = []) {
__publicField(this, "effectFlags");
this.effectFlags = new CommandEffectFlags(effects);
}
toDisplay() {
return this.name;
}
}
function applyOffsetToDocState(cmd, outDoc) {
const newHoriz = cmd.absolute ? cmd.horizontal : outDoc.horizontalOffset + cmd.horizontal;
outDoc.horizontalOffset = newHoriz < 0 ? 0 : newHoriz;
if (cmd.vertical !== void 0) {
const newVert = cmd.absolute ? cmd.vertical : outDoc.verticalOffset + cmd.vertical;
outDoc.verticalOffset = newVert < 0 ? 0 : newVert;
}
}
function getNewTranspileState(config) {
return {
initialConfig: config,
characterSize: {
left: -1,
top: -1
},
horizontalOffset: 0,
verticalOffset: 0,
lineSpacingDots: 1,
printWidth: config.mediaWidthDots,
margin: {
leftChars: 0,
rightChars: 0
},
commandEffectFlags: new CommandEffectFlags()
};
}
class TranspileDocumentError extends WebZlpError {
constructor(message, innerErrors) {
super(message);
__publicField(this, "_innerErrors", []);
this._innerErrors = innerErrors ?? [];
}
get innerErrors() {
return this._innerErrors;
}
}
class RawMessageTransformer {
constructor() {
__publicField(this, "transformerType", "Uint8Array");
}
combineMessages(...messages) {
const bufferLen = messages.reduce((sum, arr) => sum + arr.byteLength, 0);
return messages.reduce(
(accumulator, arr) => {
accumulator.buffer.set(arr, accumulator.offset);
return { ...accumulator, offset: arr.byteLength + accumulator.offset };
},
{ buffer: new Uint8Array(bufferLen), offset: 0 }
).buffer;
}
as(msg, targetType) {
if (typeof targetType === "string") {
return asString(msg);
} else if (targetType instanceof Uint8Array) {
return msg;
} else {
throw new Error("Unknown message type not implemented!");
}
}
asType(msg, targetType) {
switch (targetType) {
default:
exhaustiveMatchGuard(targetType);
break;
case "string":
return asString(msg);
case "Uint8Array":
return msg;
}
}
}
class StringMessageTransformer {
constructor() {
__publicField(this, "transformerType", "string");
}
combineMessages(...messages) {
return messages.join("");
}
as(msg, targetType) {
if (typeof targetType === "string") {
return msg;
} else if (targetType instanceof Uint8Array) {
return asUint8Array(msg);
} else {
throw new Error("Unknown message type not implemented!");
}
}
asType(msg, targetType) {
switch (targetType) {
default:
exhaustiveMatchGuard(targetType);
break;
case "string":
return msg;
case "Uint8Array":
return asUint8Array(msg);
}
}
}
function asUint8Array(commands) {
if (typeof commands === "string") {
return EncodeAscii(commands);
} else if (commands instanceof Uint8Array) {
return commands;
} else {
throw new Error("Unknown message type not implemented!");
}
}
function asString(commands) {
if (typeof commands === "string") {
return commands;
} else if (commands instanceof Uint8Array) {
return DecodeAscii(commands);
} else {
throw new Error("Unknown message type not implemented!");
}
}
function asTargetMessageType(msg, targetType) {
if (typeof targetType === "string") {
return asString(msg);
} else if (targetType instanceof Uint8Array) {
return asUint8Array(msg);
} else {
throw new Error("Unknown message type not implemented!");
}
}
function asTargetMessageLikeType(msg, targetType) {
switch (targetType) {
default:
exhaustiveMatchGuard(targetType);
break;
case "Uint8Array":
return asUint8Array(msg);
case "string":
return asString(msg);
}
}
var ErrorState = /* @__PURE__ */ ((ErrorState2) => {
ErrorState2["NoError"] = "NoError";
ErrorState2["UnknownError"] = "UnknownError";
ErrorState2["CommandSyntaxError"] = "CommandSyntaxError";
ErrorState2["ObjectExceededLabelBorder"] = "ObjectExceededLabelBorder";
ErrorState2["BarCodeDataLengthError"] = "BarCodeDataLengthError";
ErrorState2["InsufficientMemoryToStoreData"] = "InsufficientMemoryToStoreData";
ErrorState2["DuplicateNameFormGraphicOrSoftFont"] = "DuplicateNameFormGraphicOrSoftFont";
ErrorState2["NameNotFoundFormGraphicOrSoftFont"] = "NameNotFoundFormGraphicOrSoftFont";
ErrorState2["NotInDataEntryMode"] = "NotInDataEntryMode";
ErrorState2["PDF417CodedDataTooLargeToFit"] = "PDF417CodedDataTooLargeToFit";
ErrorState2["ReceiveBufferFull"] = "ReceiveBufferFull";
ErrorState2["PresenterNotRunning"] = "PresenterNotRunning";
ErrorState2["MemoryConfigurationError"] = "MemoryConfigurationError";
ErrorState2["RS232InterfaceError"] = "RS232InterfaceError";
ErrorState2["CorruptRamConfigLost"] = "CorruptRamConfigLost";
ErrorState2["InvalidFirmwareConfig"] = "InvalidFirmwareConfig";
ErrorState2["PrintheadThermistorOpen"] = "PrintheadThermistorOpen";
ErrorState2["PrintheadDetectionError"] = "PrintheadDetectionError";
ErrorState2["BadPrintheadElement"] = "BadPrintheadElement";
ErrorState2["IllegalInterruptOccurred"] = "IllegalInterruptOccurred";
ErrorState2["PrintheadUp"] = "PrintheadUp";
ErrorState2["MediaEmptyError"] = "MediaEmptyError";
ErrorState2["MediaNearEnd"] = "MediaNearEnd";
ErrorState2["RibbonEmptyError"] = "RibbonEmptyError";
ErrorState2["PrintheadTooHot"] = "PrintheadTooHot";
ErrorState2["PrintheadTooCold"] = "PrintheadTooCold";
ErrorState2["MotorTooHot"] = "MotorTooHot";
ErrorState2["MotorTooCold"] = "MotorTooCold";
ErrorState2["BatteryLowWarning40Percent"] = "BatteryLowWarning40Percent";
ErrorState2["BatteryLowLimit20Percent"] = "BatteryLowLimit20Percent";
ErrorState2["CutterJammedOrNotInstalled"] = "CutterJammedOrNotInstalled";
ErrorState2["PressFeedButtonToRecover"] = "PressFeedButtonToRecover";
ErrorState2["PaperFeedError"] = "PaperFeedError";
ErrorState2["PaperJamDuringRetract"] = "PaperJamDuringRetract";
ErrorState2["PrintheadNeedsCleaning"] = "PrintheadNeedsCleaning";
ErrorState2["PrintheadNeedsReplacing"] = "PrintheadNeedsReplacing";
ErrorState2["MediaErrorOrBlacklineNotDetectedOrExcessiveMediaFeeding"] = "MediaErrorOrBlacklineNotDetectedOrExcessiveMediaFeeding";
ErrorState2["BlackMarkNotFound"] = "BlackMarkNotFound";
ErrorState2["BlackMarkCalirateError"] = "BlackMarkCalirateError";
ErrorState2["AutoSenseOrSensorFailure"] = "AutoSenseOrSensorFailure";
ErrorState2["ExcessiveMediaFeeding"] = "ExcessiveMediaFeeding";
ErrorState2["RetractFunctionTimeout"] = "RetractFunctionTimeout";
ErrorState2["NeedToCalibrateMedia"] = "NeedToCalibrateMedia";
ErrorState2["PrinterBusyProcessingPrintJob"] = "PrinterBusyProcessingPrintJob";
ErrorState2["PrinterPaused"] = "PrinterPaused";
ErrorState2["PartialFormatInProgress"] = "PartialFormatInProgress";
ErrorState2["CommDiagnosticModeActive"] = "CommDiagnosticModeActive";
ErrorState2["LabelWaitingToBeTaken"] = "LabelWaitingToBeTaken";
return ErrorState2;
})(ErrorState || {});
class ErrorStateSet extends Set {
}
class MessageParsingError extends WebZlpError {
constructor(message, receivedMessage) {
super(message);
__publicField(this, "receivedMessage");
this.receivedMessage = receivedMessage;
}
}
function deviceInfoToOptionsUpdate(deviceInfo) {
return {
messageType: "SettingUpdateMessage",
printerHardware: {
serialNumber: deviceInfo.serialNumber,
model: deviceInfo.productName,
manufacturer: deviceInfo.manufacturerName
},
printerMedia: {}
};
}
async function parseRaw(input, commandSet, config, awaitedCommands) {
let remainderMsg = input;
if (remainderMsg.length === 0) {
return { messages: [], remainderCommands: awaitedCommands, remainderMsg };
}
let incomplete = false;
const messages = [];
let remainderCommands = awaitedCommands.slice();
do {
if (remainderCommands.length === 0) {
const parseResult = commandSet.handleMessage(remainderMsg, config);
remainderMsg = parseResult.remainder;
incomplete = parseResult.messageIncomplete;
parseResult.messages.forEach((m) => messages.push(m));
} else {
remainderCommands = remainderCommands.filter((c) => {
if (incomplete) {
return true;
}
const parseResult = commandSet.handleMessage(remainderMsg, config, c.cmd);
if (parseResult.messageMatchedExpectedCommand) {
if (parseResult.messageIncomplete) {
incomplete = true;
return true;
}
remainderMsg = parseResult.remainder;
parseResult.messages.forEach((m) => messages.push(m));
if ((c == null ? void 0 : c.resolve) === void 0) {
console.error("Resolve callback was undefined for awaited command, this may cause a deadlock! This is a bug in the library.");
} else {
c.resolve(true);
}
return false;
}
});
}
} while (incomplete === false && remainderMsg.length > 0 && remainderCommands.length > 0);
return { remainderMsg, remainderCommands, messages };
}
var CommandFormInclusionMode = /* @__PURE__ */ ((CommandFormInclusionMode2) => {
CommandFormInclusionMode2[CommandFormInclusionMode2["sharedForm"] = 0] = "sharedForm";
CommandFormInclusionMode2[CommandFormInclusionMode2["noForm"] = 1] = "noForm";
return CommandFormInclusionMode2;
})(CommandFormInclusionMode || {});
class PrinterCommandSet {
constructor(transformer, messageHandlerDelegate, implementedLanguage, basicCommands, extendedCommands = []) {
__publicField(this, "cmdLanguage");
__publicField(this, "messageTransformer");
__publicField(this, "messageHandlerDelegate");
__publicField(this, "commandMap", /* @__PURE__ */ new Map());
this.cmdLanguage = implementedLanguage;
this.messageTransformer = transformer;
this.messageHandlerDelegate = messageHandlerDelegate;
for (const cmdType of basicCommandTypes) {
this.commandMap.set(cmdType, basicCommands[cmdType]);
}
extendedCommands.forEach((c) => this.commandMap.set(c.commandType, c));
}
get commandLanguage() {
return this.cmdLanguage;
}
transpileCommand(cmd, docMetadata) {
const mappedCmd = this.getMappedCmd(cmd);
if (mappedCmd === void 0) {
return new TranspileDocumentError(`Command could not be mapped, is the command mapping correcT?`);
}
const handler = mappedCmd.transpile ?? (() => this.noop);
return handler(cmd, docMetadata, this);
}
handleMessage(msg, config, sentCommand) {
return this.messageHandlerDelegate(
this,
msg,
config,
sentCommand
);
}
getMappedCmd(cmd) {
return this.commandMap.get(getCommandAnyType(cmd));
}
isCommandNonFormCommand(cmd) {
var _a;
return ((_a = this.getMappedCmd(cmd)) == null ? void 0 : _a.formInclusionMode) === 1;
}
expandCommand(cmd) {
var _a;
return (((_a = this.getMappedCmd(cmd)) == null ? void 0 : _a.expand) ?? (() => []))(cmd);
}
combineCommands(...commands) {
return this.messageTransformer.combineMessages(...commands);
}
getConfig(config) {
return config;
}
callMessageHandler(message, sentCommand) {
var _a;
if (sentCommand === void 0) {
throw new MessageParsingError(
`Received a command reply message without 'sentCommand' being provided, can't handle this message.`,
message
);
}