diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ad1a17f8..d18faec5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ history. ## Unreleased +- `types/uint8array`: `toVec` attempts the conversion instead of precomputing a + byte-count bound; behavior and error message unchanged + [#1543](https://github.com/functionalscript/functionalscript/pull/1543) - `media/json/schema`: `toJsonSchema` supports recursive schemas — it converts through `fjs/types/rtti/data` (new `dataToJsonSchema`) and emits named recursion as `$defs`/`$ref`; output is canonical, so `anyOf` members and diff --git a/fjs/types/uint8array/module.f.mjs b/fjs/types/uint8array/module.f.mjs index 718304789..94ddad4d2 100644 --- a/fjs/types/uint8array/module.f.mjs +++ b/fjs/types/uint8array/module.f.mjs @@ -10,34 +10,38 @@ * @module */ -import { assert, assertNotNullish } from '../../asserts/module.f.mjs' +import { assertNotNullish } from '../../asserts/module.f.mjs' import { utf8, utf8ToString } from '../../text/module.f.mjs' -import { maxLengthBytes, msb, tryU8ListToVec, u8List, u8ListToVec } from '../bit_vec/module.f.mjs' +import { msb, tryU8ListToVec, u8List } from '../bit_vec/module.f.mjs' /** @import { Vec } from '../bit_vec/types.ts' */ import { compose } from '../function/module.f.mjs' import { flat, fromArrayLike, iterable, map } from '../list/module.f.mjs' /** @import { List } from '../list/types.ts' */ -const u8ListToVecMsb = u8ListToVec(msb) const tryU8ListToVecMsb = tryU8ListToVec(msb) const u8ListMsb = u8List(msb) +const m = map(fromArrayLike) + /** - * Converts a Uint8Array into an MSB-first bit vector. + * Concatenates a list of `Uint8Array` values into one MSB-first bit vector. * - * @type {(input: Uint8Array) => Vec} + * Throws if the result would exceed `maxLength`. The bound is not precomputed: + * `tryU8ListToVec` attempts the real conversion and reports `null` when it does + * not fit (AGENTS.md §5.6). + * + * @type {(input: List) => Vec} */ -export const toVec = input => { - assert(input.length <= maxLengthBytes, "the array is too big") - return u8ListToVecMsb(fromArrayLike(input)) -} - -const m = map(fromArrayLike) - -/** @type {(input: List) => Vec} */ export const listToVec = input => assertNotNullish(tryU8ListToVecMsb(flat(m(input))), "the array is too big") +/** + * Converts a Uint8Array into an MSB-first bit vector. + * + * @type {(input: Uint8Array) => Vec} + */ +export const toVec = input => listToVec([input]) + /** * Converts an MSB-first bit vector into a Uint8Array. * diff --git a/fjs/types/uint8array/todo/tovec-precomputed-bound.md b/fjs/types/uint8array/todo/tovec-precomputed-bound.md deleted file mode 100644 index 128dd4083..000000000 --- a/fjs/types/uint8array/todo/tovec-precomputed-bound.md +++ /dev/null @@ -1,36 +0,0 @@ -## `toVec` precomputes a size bound - -**Priority:** P3 -**Status:** open - -### Problem - -Two adjacent functions do the same job with opposite discipline -(`module.f.mjs:30-39`): - -```js -export const toVec = input => { - assert(input.length <= maxLengthBytes, "the array is too big") - return u8ListToVecMsb(fromArrayLike(input)) -} - -export const listToVec = input => - assertNotNullish(tryU8ListToVecMsb(flat(m(input))), "the array is too big") -``` - -AGENTS.md §5.6 ("Never precompute a size to predict whether something fits") -names `tryU8ListToVec` as the `try*` variant to use instead — `listToVec` -obeys it, `toVec` re-derives a byte-count bound. The guard is also redundant: -`u8ListToVec` is the unwrapping form of `tryU8ListToVec`, so the real check -already runs inside. - -### Proposal - -`export const toVec = input => listToVec([input])` — the same list -(`flat(map(fromArrayLike)([input]))`), the same error message, and `assert` / -`maxLengthBytes` drop out of the imports. - -### Tasks - -- [ ] Rewrite `toVec` through `listToVec` and drop the `assert` / - `maxLengthBytes` imports