@cosyte/astm 0.0.14 → 0.0.15
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/CHANGELOG.md +76 -0
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -9
- package/dist/index.d.ts +31 -9
- package/dist/index.mjs +15 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,54 @@ this file is maintained by hand (Changesets handles the version bump and publish
|
|
|
11
11
|
|
|
12
12
|
### Fixed
|
|
13
13
|
|
|
14
|
+
- **The escape encoder protected the escape character it introduced but not the `E`/`F`/`S`/`R`
|
|
15
|
+
mnemonics, so a delimiter set naming one of those letters in another role altered the values it
|
|
16
|
+
emitted** (`ASTM-FRAME-RESIDUALS` follow-up, defect 12). `PRE-EXISTING`, byte-identical on
|
|
17
|
+
`4bb62f1`. `encodeLeaf` ran as four chained whole-string substitutions (escape, then field,
|
|
18
|
+
component, repeat), and each pass could see what the previous ones had written. Going first
|
|
19
|
+
protected the escape character; nothing protected the mnemonic letters. Under
|
|
20
|
+
`{ field: "E", escape: "R" }` a leaf of `R` went out as `RRFRR` and read back as `RER`.
|
|
21
|
+
|
|
22
|
+
**Re-measured here rather than carried over, because the recorded figures came from a sweep whose
|
|
23
|
+
parameters were not written down.** Over the whole four-role space drawn from the 18-character
|
|
24
|
+
alphabet `|` `\` `^` `&` `E` `F` `S` `R` `*` `~` `:` `#` `+` `@` `!` `$` `%` `/` (the four
|
|
25
|
+
canonical delimiters, the four mnemonic letters, a common vendor set, neutral punctuation), that is
|
|
26
|
+
P(18,4) = 73,440 sets, against **exactly the `STREAM` constant in
|
|
27
|
+
`test/records/escape-mnemonic-roles.test.ts`**, a synthetic ten-record
|
|
28
|
+
`H`/`P`/`O`/`R`/`R`/`R`/`C`/`M`/`S`/`L` message that parses with `warnings: []`, the serializer
|
|
29
|
+
refused 23,040 and accepted **50,400**. Of those, **10,450** emitted
|
|
30
|
+
a stream this library re-read with a **different field tree**, and **9,287** reported nothing
|
|
31
|
+
outside `TOLERABLE_CODES`, so a gate-legal profile plus `{ strict: true }` accepted an altered
|
|
32
|
+
value.
|
|
33
|
+
|
|
34
|
+
**The "0 silent" reading is confirmed and is weaker than it looks, which is worth more than the
|
|
35
|
+
number.** Zero of the 10,450 re-parsed with `warnings: []`, but a non-canonical set always reports
|
|
36
|
+
`ASTM_NONSTANDARD_DELIMITERS`, and that code is itself tolerable, so `warnings: []` was never
|
|
37
|
+
reachable for any set that could exhibit this defect. Silence was not available as a measure here.
|
|
38
|
+
The tier that does discriminate is the strict-accepted one above.
|
|
39
|
+
|
|
40
|
+
**The fix is one left-to-right pass.** Each character is read once and written either as itself or
|
|
41
|
+
as a whole `escape` + mnemonic + `escape` triple, and nothing the encoder writes is examined again,
|
|
42
|
+
which makes it the **exact** inverse of `decodeEscapes` rather than approximately so. No accepted
|
|
43
|
+
set in that sweep diverges after it. Bytes change for **exactly** the 10,450 sets that were
|
|
44
|
+
diverging and for no others (measured both directions: 0 sets diverged with unchanged bytes, 0 sets
|
|
45
|
+
changed bytes without having diverged), so a canonical stream and any set naming none of the four
|
|
46
|
+
mnemonic letters is byte-identical. The accept/refuse partition is unchanged over all 73,440 sets:
|
|
47
|
+
`ASTM_EMIT_TYPE_LETTER_COLLISION` reads the first character actually written, so it needed no
|
|
48
|
+
change when the encoder underneath it did, which is the argument for testing bytes rather than
|
|
49
|
+
enumerating dangerous roles. **No clause is claimed**: the grounding is this package's own decoder.
|
|
50
|
+
|
|
51
|
+
Pinned in `test/records/escape-mnemonic-roles.test.ts`, which transcribes the four chained
|
|
52
|
+
substitutions (nothing shipped still reproduces them) and **checks that transcription against the
|
|
53
|
+
shipped encoder on all 1,680 sets where the two must agree**, so it cannot decay into a strawman.
|
|
54
|
+
8 of its assertions are red against a `git archive` of `4bb62f1`. Five of them pin the **emitted bytes as literals**, each derived in a comment rather than snapshotted, because every other assertion here reads the stream back through this package's own parser and so cannot see an encoder and decoder that agree with each other and are both wrong. The committed test pins a
|
|
55
|
+
12-character subspace (P(12,4) = 11,880) rather than the 18, because the full space costs about a
|
|
56
|
+
minute of suite time and the extra six characters are neutral punctuation already represented. The
|
|
57
|
+
corpus is the same in both: the 73,440-set figures above differ from the test's only by alphabet. The claim in
|
|
58
|
+
`test/records/type-letter-collision.test.ts` that a type letter equal to the escape character
|
|
59
|
+
"does not always encode as letter + E + letter" was pinned to `RRFRR`/`RRSRR` and is now false:
|
|
60
|
+
it encodes that way for every set, and the assertion was updated to say so rather than deleted.
|
|
61
|
+
|
|
14
62
|
- **`composeAstmFrames` wrote an out-of-range `startFrameNumber` straight into the frame-number
|
|
15
63
|
position, so a value that was not a frame number produced a stream whose records the decoder
|
|
16
64
|
refused to emit** (`ASTM-FRAME-RESIDUALS`, defect 13). `PRE-EXISTING`, byte-identical on `64c2fd5`.
|
|
@@ -392,6 +440,34 @@ this file is maintained by hand (Changesets handles the version bump and publish
|
|
|
392
440
|
that only ever fails is not a gate and one that swallows the status is not one either. **No
|
|
393
441
|
runtime code changed and the built output is identical.**
|
|
394
442
|
|
|
443
|
+
### Documented
|
|
444
|
+
|
|
445
|
+
- **A header delimiter-declaration surplus loses all 31 of the C0/`DEL` characters that can reach
|
|
446
|
+
it, and the published surfaces stated the preservation rule without that exception.**
|
|
447
|
+
`PRE-EXISTING`; the
|
|
448
|
+
behaviour is unchanged and argued at `declarationResidual`. What changed is that it is measured,
|
|
449
|
+
pinned and stated, and that **one of the recorded reasons for it is now known to be false**:
|
|
450
|
+
"carrying the byte through would turn a spec-clean header into a stream the frame layer refuses"
|
|
451
|
+
holds for `STX`, `ETX` and `ETB` only. Measured, the other **28 of the 31** round-trip byte-exactly
|
|
452
|
+
through `composeAstmFrames` into `decodeAstmFrames` with `warnings: []`, and all 31 round-trip at
|
|
453
|
+
the record layer. The disposition still stands, on the reason the code site actually gives: rather
|
|
454
|
+
than enumerate the bytes each layer happens to reserve and re-derive that list every time a layer
|
|
455
|
+
is added, no control character is carried at all. Do not restate the frame-layer reason. Probing one character at a time in the surplus of an otherwise spec-clean
|
|
456
|
+
`H|\^&` header: **31 of the 33** C0/`DEL` characters reach the rule and are dropped, each with
|
|
457
|
+
`warnings: []` and no error; the other two are `CR` and `LF`, which end the record while it is being
|
|
458
|
+
read, so no surplus ever holds them. The drop is **all-or-nothing**, so a surplus of `#` + `US` + `$`
|
|
459
|
+
loses the `#` and the `$` as well, and that is deliberate: a subsequence of an opaque run whose
|
|
460
|
+
meaning is unresolved is a different run, not a shorter version of the same one, and choosing which
|
|
461
|
+
characters to keep is the guess this library declines everywhere else. `docs-content/quickstart.md`
|
|
462
|
+
attached the control-character drop to the transcoding case alone, which is wrong: it fires on the
|
|
463
|
+
**default canonical path** too. The `serializeAstmRecords` and `serializeAstmRecord` doc comments
|
|
464
|
+
and this module's own doc block, all of which compile into the published declarations, stated the
|
|
465
|
+
preservation rule unqualified. All are
|
|
466
|
+
widened rather than rewritten, and `docs-content/limitations.md`, which already disclosed the drop,
|
|
467
|
+
gains the all-or-nothing shape and the count. Pinned in
|
|
468
|
+
`test/records/declaration-surplus-residual.test.ts`, which passes on `4bb62f1` by design: it
|
|
469
|
+
measures behaviour this entry does not change.
|
|
470
|
+
|
|
395
471
|
### Added
|
|
396
472
|
|
|
397
473
|
- **`ASTM_RECORD_FIELDS_UNSEPARATED`: a record that lost its fields no longer loses them in
|
package/dist/index.cjs
CHANGED
|
@@ -1435,6 +1435,13 @@ function encodeComponent(leaf, d, recordIndex) {
|
|
|
1435
1435
|
assertEmittableDelimiters(d, recordIndex);
|
|
1436
1436
|
return encodeLeaf(leaf, d, recordIndex);
|
|
1437
1437
|
}
|
|
1438
|
+
function escapeMnemonic(ch, d) {
|
|
1439
|
+
if (ch === d.escape) return "E";
|
|
1440
|
+
if (ch === d.field) return "F";
|
|
1441
|
+
if (ch === d.component) return "S";
|
|
1442
|
+
if (ch === d.repeat) return "R";
|
|
1443
|
+
return void 0;
|
|
1444
|
+
}
|
|
1438
1445
|
function encodeLeaf(leaf, d, recordIndex) {
|
|
1439
1446
|
if (leaf.includes("\r") || leaf.includes("\n")) {
|
|
1440
1447
|
throw new AstmSerializeError(
|
|
@@ -1442,7 +1449,13 @@ function encodeLeaf(leaf, d, recordIndex) {
|
|
|
1442
1449
|
recordIndex
|
|
1443
1450
|
);
|
|
1444
1451
|
}
|
|
1445
|
-
|
|
1452
|
+
let out = "";
|
|
1453
|
+
for (let i = 0; i < leaf.length; i += 1) {
|
|
1454
|
+
const ch = leaf.charAt(i);
|
|
1455
|
+
const mnemonic = escapeMnemonic(ch, d);
|
|
1456
|
+
out += mnemonic === void 0 ? ch : d.escape + mnemonic + d.escape;
|
|
1457
|
+
}
|
|
1458
|
+
return out;
|
|
1446
1459
|
}
|
|
1447
1460
|
function encodeField(repeats, d, recordIndex) {
|
|
1448
1461
|
return repeats.map((rep) => rep.map((c) => encodeLeaf(c, d, recordIndex)).join(d.component)).join(d.repeat);
|
|
@@ -2358,7 +2371,7 @@ function concatBytes3(chunks) {
|
|
|
2358
2371
|
}
|
|
2359
2372
|
|
|
2360
2373
|
// src/index.ts
|
|
2361
|
-
var VERSION = "0.0.
|
|
2374
|
+
var VERSION = "0.0.15";
|
|
2362
2375
|
|
|
2363
2376
|
exports.ALL_ASTM_WARNING_CODES = ALL_ASTM_WARNING_CODES;
|
|
2364
2377
|
exports.AMBIGUOUS_CODES = AMBIGUOUS_CODES;
|