Skip to content

fix: sequential toValue, plain-object guard in iterate, real coverage#6

Merged
winton merged 2 commits into
mainfrom
fix/tovalue-sequential-iterate-plain-object-coverage
Apr 9, 2026
Merged

fix: sequential toValue, plain-object guard in iterate, real coverage#6
winton merged 2 commits into
mainfrom
fix/tovalue-sequential-iterate-plain-object-coverage

Conversation

@winton

@winton winton commented Apr 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • toValue is now always sequential. Previously, array inputs ran callbacks concurrently via Promise.all, making stateful async reductions non-deterministic (a footgun for anyone expecting reduce-like behaviour). All input types — arrays, records, and streams — are now processed one element at a time, so the accumulator is always updated in order.

  • iterate now rejects class instances as records. The record branch previously matched any typeof === "object" value, silently running Object.entries on class instances and picking up their enumerable own properties. The check now requires Object.getPrototypeOf(iterable) === Object.prototype (or null), so only plain object literals and Object.create(null) objects are treated as records; class instances are skipped.

  • Coverage config now measures real implementation. vitest coverage was scoped to src/typectl.ts (the barrel re-export), so reported line/branch numbers were meaningless. The include glob is now src/**/*.ts with specs and examples excluded, giving accurate coverage across wrap.ts, mappers.ts, iterate.ts, etc.

Test plan

  • npm test — all 41 tests pass
  • New test: toValue is sequential and deterministic for arrays — verifies visit order and sum
  • New test: toValue is sequential and deterministic for records — verifies visit order and sum
  • New test: iterate skips class instances — verifies empty output for a class instance input
  • Run npm run test:coverage and confirm implementation modules appear in the report

Made with Cursor

winton added 2 commits April 9, 2026 00:40
- toValue now iterates all input types sequentially so stateful async
  reductions are always deterministic (previously arrays used Promise.all)
- iterate now guards the record branch with a plain-object prototype
  check, preventing class instances from being silently iterated via
  Object.entries
- vitest coverage include expanded from src/typectl.ts to all src/**/*.ts
  (excluding specs and examples) so implementation modules are measured
- Update README and JSDoc to reflect new toValue and iterate semantics
- Add tests: sequential toValue for arrays and records, iterate skips
  class instances

Made-with: Cursor
@winton
winton merged commit 48a858c into main Apr 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant