Function: composeAstmFrames()
composeAstmFrames(
records,options?):Uint8Array
Frame reassembled record bytes into a spec-clean ASTM/CLSI-LIS01 byte stream: the inverse of decodeAstmFrames.
Each record is split at 240 text bytes into ETB-closed intermediate frames
and a final ETX frame; frame numbers run 1, 2, … 7, 0, 1 … continuously
across the whole stream; every frame's modulo-256 checksum is computed and
emitted uppercase.
A record in either accepted form is written through unchanged, or refused. A
record given as a Uint8Array is already bytes. A record given as a string is
a byte string, character i becoming byte i, the exact inverse of how a
decoded record becomes a string again. A character above U+00FF is not a byte,
so it is refused with ASTM_FRAME_UNENCODABLE_CHARACTER rather than replaced by
a different character (it used to be truncated to its low byte, which is another
ordinary character, and reached the wire silently). To frame content outside
Latin-1, encode it with the character encoding your instrument uses and pass the
resulting Uint8Array. Those two forms are the whole of what records accepts.
A caller reaching this from JavaScript with some other typed array is outside
the signature and gets no such refusal: each element is still written as its low
byte, the same substitution described above. The reserved-byte check below does
not reach that route either, because it compares elements against the three byte
values and an element like 0x0103 is not one of them, though its low byte
becomes an ETX on the wire. Pass a Uint8Array or a string.
A record carrying a frame-structure byte is refused too, in either form.
STX, ETB and ETX are what the decoder reads as the shape of a frame, and
framing has no escape sequence to hide one behind, so a record holding one is
ASTM_FRAME_RESERVED_BYTE rather than a frame truncated at that byte. It used
to be written as given, and the result was not reliably loud: with the two
following bytes matching, the truncated frame verifies and a whole record is
absorbed into the previous one with an empty warnings array at both layers.
Supplying the record as a Uint8Array does not route around this check.
What is still not guaranteed: that an accepted record round-trips through the record layer. A delimiter colliding with a record's type letter, for one, frames and de-frames byte-exactly and still re-reads as a different record.
Parameters
records
readonly (string | Uint8Array<ArrayBufferLike>)[]
The reassembled record byte-strings (Uint8Array or latin1
string), one entry per complete record.
options?
ComposeFramesOptions = {}
Encode options.
Returns
Uint8Array
The framed byte stream.
Throws
AstmFrameEncodeError when the list is empty, a record has no
bytes (ASTM_FRAME_EMPTY_RECORD), a record string holds a character above
U+00FF (ASTM_FRAME_UNENCODABLE_CHARACTER), or a record holds an STX,
ETB or ETX byte (ASTM_FRAME_RESERVED_BYTE).
Example
import { composeAstmFrames, decodeAstmFrames } from "@cosyte/astm";
const records = [new TextEncoder().encode("H|\\^&\r"), new TextEncoder().encode("L|1\r")];
const bytes = composeAstmFrames(records);
decodeAstmFrames(bytes).records.length; // 2