Files
skills/docs/foundation/data/serialize/src/codec/json/json-decode.md
2026-05-29 08:20:56 +01:00

3.2 KiB

json-decode

Purpose

Implements deserialize, the inverse of serialize. Given a tagged JSON string produced by the encoder, it reconstructs the original JavaScript value graph including all registered types (built-ins and custom), undefined, NaN, and ±Infinity. Any __t tag that has no registered handler causes an UnsupportedTypeError to be thrown immediately rather than silently discarding data.

The decoder is intentionally strict: it is safer to fail loudly on an unrecognised tag than to silently drop values, which could cause subtle data corruption downstream.

Features

  • Full inverse of serialize: all built-in type tags are decoded back to their original JavaScript types
  • AbortSignal support for cancelling mid-traversal on large payloads, checked every 256 nodes
  • UnsupportedTypeError thrown (with the tag name in context.tag) for unrecognised __t values
  • Recursive array and plain-object decoding
  • Zero allocations for pass-through primitives (string, number, boolean, null)

Usage: Basic Example

import { deserialize, serialize } from "@suaveplan/serialize";

const original = { created: new Date(), tags: new Set(["x", "y"]) };
const json = serialize(original);
const restored = deserialize(json) as typeof original;

restored.created instanceof Date; // true
restored.tags instanceof Set;     // true

Usage: Advanced Example

import { deserialize, UnsupportedTypeError } from "@suaveplan/serialize";

const controller = new AbortController();

// Cancel deserialization partway through:
setTimeout(() => controller.abort(new Error("timeout")), 10);

try {
  const value = deserialize(largeJson, { signal: controller.signal });
  processValue(value);
} catch (err) {
  if (err instanceof UnsupportedTypeError) {
    console.error("Unknown type tag:", err.context?.tag);
  } else {
    // likely the abort reason
    throw err;
  }
}

API Reference

deserialize(json: string, opts?: DeserializeOptions): unknown

Parse json and recursively reconstruct the JavaScript value it encodes.

Parameters:

  • json — a tagged JSON string produced by serialize
  • opts.signal — an AbortSignal; checked every 256 nodes

Returns: the reconstructed value.

Throws:

  • UnsupportedTypeError when a __t tag has no registered decoder
  • SyntaxError from JSON.parse if the input is not valid JSON
  • The AbortSignal's reason when signal is aborted

DeserializeOptions

interface DeserializeOptions {
  signal?: AbortSignal;
}

Implementation Notes

  • The decoder calls JSON.parse once at the top level and then recursively traverses the parsed intermediate tree. This avoids parsing partial JSON strings and keeps the implementation simple.
  • For tagged objects, the inner v payload is decoded recursively before being handed to def.decode. This means registered type decoders always receive already-decoded JavaScript values, not raw JSON intermediates.
  • Signal checking is shared with a module-level counter that resets per deserialize call; it fires every 256 traversed nodes.
  • The decoder does not validate the structure of v beyond calling def.decode; responsibility for validating the payload shape belongs to each registered type definition.