Skip to main content
Version: v0.0.14

Function: serializeAstmRecords()

serializeAstmRecords(input, d?): string

Serialize a whole ASTM message (or a bare record list) to a spec-clean, CR-terminated record stream: the inverse of parseAstmRecords.

Emit is conservative: the canonical H|\^& delimiters, every embedded delimiter re-escaped, each record closed with a CR. A message parsed with non-canonical delimiters is normalized to the canonical set on emit: every record, M and S included, so the emitted stream is in one delimiter set and re-parsing it recovers every field. Passing d explicitly emits against that set instead, and the header declares it. Normalization replaces the four delimiter roles; a header declaration carrying characters beyond the three that hold a role keeps them, on this path as on any other, rather than being truncated.

d is checked before anything is written. Each of the four separators must be exactly one character, none may be a record terminator, and no two may share a character: otherwise the emitted bytes cannot be read back as the records that produced them, and emit has no warning channel with which to say so. A set that fails is an AstmSerializeError with code ASTM_EMIT_INVALID_DELIMITERS. This is stricter than the parser, which reads some sets it cannot reverse, so serializeAstmRecords(msg, msg.delimiters) can refuse a message that parsed: in exactly the cases where it used to emit a stream that read back wrong.

And each record is checked against the set it is being written with. Those three conditions read the set alone, so they cannot see that field = R escapes an R record's own type letter away. Every record's emitted line is therefore checked to start with the letter the record models, and one that does not is ASTM_EMIT_TYPE_LETTER_COLLISION rather than a stream that reads back as different records. What neither check promises is that every field lands where it did: an escape sequence whose body is a delimiter is an opaque atom, so that delimiter never becomes a boundary, and the parse side reports that (ASTM_UNKNOWN_ESCAPE_SEQUENCE) rather than emit refusing it.

Parameters

input

AstmMessage | readonly AstmRecord[]

A parsed AstmMessage or a list of AstmRecords.

d?

Delimiters = CANONICAL_DELIMITERS

The delimiters to emit against; defaults to the canonical H|\^& set.

Returns

string

The serialized record stream (CR after every record).

Throws

AstmSerializeError when a component contains an unencodable CR/LF (ASTM_EMIT_UNENCODABLE_VALUE), when d fails one of the three conditions readback requires (ASTM_EMIT_INVALID_DELIMITERS), or when a record's type letter would not be the first character of its own emitted line (ASTM_EMIT_TYPE_LETTER_COLLISION). The last of the three fires on the default canonical path as well: it compares each record against the set being emitted with, so a record read under a different set can carry a type letter the canonical set escapes away. Omitting d is not a way around it.

Example

import { parseAstmRecords, serializeAstmRecords } from "@cosyte/astm";
const raw = "H|\\^&\rP|1\rR|1|^^^687|28.6|U/L||N||F\rL|1\r";
serializeAstmRecords(parseAstmRecords(raw)); // === raw