Skip to content

Json codec improvements - #4

Merged
adz merged 9 commits into
mainfrom
json-codec-improvements
Sep 15, 2026
Merged

adz merged 9 commits into
mainfrom
json-codec-improvements

Conversation

@adz

@adz adz commented Sep 15, 2026

Copy link
Copy Markdown
Owner
  • Adds field aliases to schema
  • Speed up canonical-order JSON, with fallback preserved

Shows a 24-field decode around 19% faster than System.Text.Json.

@adz
adz merged commit 228d40d into main Sep 15, 2026
5 checks passed
@adz
adz deleted the json-codec-improvements branch September 15, 2026 06:44
adz added 9 commits September 15, 2026 22:59
Generated records now carry an intrinsic `static member Schema: T -> Schema<T>`
augmentation delegating to the sibling `let schema`, so a bare `fieldAs "x" _.Field`
on a contract-typed field resolves through the same SRTP constraint a `string` field
uses (including the list/option/map witnesses). The augmentation is intrinsic to the
generated file, so it satisfies the constraint cross-assembly with no `open`.

Gated on `contract.OwnsType`: `[<DeriveSchema>]` types on hand-written records are
not declared by schemagen, so they keep `withSchema TheType.schema`.

Regenerated the .contract corpus goldens; added a GeneratedContractTests case
covering direct, list, and option nesting.

Claude-Session: https://claude.ai/code/session_01BhazQLVh4zWAfZsjTxczVS
- Ship "sideEffects": false for every Fable-compiled package, so a
  browser bundler drops Reified.Constraint/Refinements entirely from a
  schema that never uses a refined field or constraint.
- Guard it: the Fable build target fails if the generated JS grows a
  top-level side effect.
- Codec: sprintf/failwithf -> string concat, F# Map -> assoc lists in
  union decoding. Drops the printf parser and Map.js from every codec
  that doesn't need them. No .NET behaviour change.
- New "Browser bundle size" section: the sideEffects contract and a
  cost table per feature (schema only, +codec, +constraints, +refined
  types).
- Record the reasoning in dev-docs/decisions.
- Re-run the codec benchmarks. Allocations are unchanged from the
  prior run, confirming the codec change is perf-neutral.
- Json.serializeIndented for pretty output; Json.reindent to
  pretty-print any JSON string.
- Json.serializeWith/serializeBytesWith/serializeToStreamWith take a
  JsonWriteOptions configure function (indent, trailing newline,
  ASCII-only, HTML-safe escaping) - same shape as Schema.parseWith.
- Implemented as one pass over the compact bytes, so
  serialize/serializeBytes/serializeToStream are untouched.
- Add alias and aliases field-block operations with exact, case-sensitive names.\n- Parse and decode canonical names or aliases while encoding only the canonical name.\n- Reject ambiguous input and schema-wide name collisions; expose aliases through inspection.\n- Document compatibility guidance and cover parsing, codecs, API shape, and collisions.
- Preserve duplicate object properties with a linear dictionary index during Schema.parse.\n- Keep canonical JSON matching on the direct UTF-8 fast path and scan aliases only after a miss.\n- Add SchemaAlias derivation metadata and generated alias operations.\n- Add standalone Field.withAlias composition and Fable runtime coverage.
Compare canonical parsing, alias parsing, duplicate-name rejection, and compiled alias decoding on the shared customer fixture. Keep this benchmark commit at the branch tip so measured documentation can be amended from the final implementation.
Decode Reified's canonical field order through the typed constructor chain without field dispatch or per-field slots. On any layout mismatch, restart through the existing unordered and alias-aware decoder without exposing a mode choice. Keep malformed field values final and preserve their paths.
Measure the canonical decoder against System.Text.Json, the general reverse-order fallback, and an optimistic known-layout scan ceiling. Refresh the recorded codec, boundary, wide-record, and collection results from the final implementation.
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