Codec
A priority-ordered registry of encoders/decoders for bytes, text and streams.
@ozaco/std/codecCodec is a protocol: a scope-local registry of encoders/decoders. Install one or more codec implementations (JsonCodec, TomlCodec, YamlCodec, or your own) and Codec.actions.* transparently route each call to the highest-priority registered codec — ties break toward the most recently installed.
Every codec exposes the same surface: encode/decode work in Uint8Array bytes, stringify/parse work in serialized text, and encodeStream/decodeStream adapt effect Streams. All of them are effect operations that fail with a CodecErrors tag rather than throwing.
The registry is a scope-local effect Context inherited downward through the protocol context — not a global string-keyed table — so it reflects only registrations visible in the current scope chain. Because it lives in std, any consumer (std:fetch, the WebSocket transport, the logger, …) can encode/decode without coupling to a higher layer. A direct SomeCodec.actions.* call always targets that specific codec, bypassing priority routing.
@ozaco/std/codec/impl/json`JsonCodec` — JSON via the built-in `JSON` plus streaming `@streamparser/json`. Default priority `999` (the highest), so installing it keeps JSON as the active codec.@ozaco/std/codec/impl/toml`TomlCodec` — a zero-dependency, from-scratch TOML parser/serializer (adapted from Deno `@std/toml`; datetimes unsupported). Default priority `500`.@ozaco/std/codec/impl/yaml`YamlCodec` — YAML backed by `js-yaml` (an optional peer dependency; install it alongside `@ozaco/std`). Default priority `500`.
Protocol
The registry and its routed actions.
Codec
The codec protocol — routes `encode`/`decode`/`stringify`/`parse`/stream actions to the highest-priority installed codec.
const Codec: Protocol<
CodecDef.Context,
unknown[],
CodecDef.Actions,
CodecDef.Handlers
>
// Codec.actions run against the highest-priority installed codec:
Codec.actions.encode(value: unknown): Future<Uint8Array>
Codec.actions.decode<T>(data: Uint8Array): Future<T>
Codec.actions.stringify(value: unknown): Future<string>
Codec.actions.parse<T>(text: string): Future<T>
Codec.actions.encodeStream<T>(
stream: Stream<T, unknown>,
): Future<Stream<Uint8Array, true | Result.Failure<unknown>>>
Codec.actions.decodeStream<T>(
stream: Stream<Uint8Array, unknown>,
json?: boolean,
): Future<Stream<T, true | Result.Failure<unknown>>>Installing JSON (priority 999) plus TOML/YAML (500) keeps JSON active; install a codec with a higher { priority } to prefer it. The protocol also exposes handler actions (register, unregister, getTransports) used internally by codec implementations to join and leave the registry.
import { Codec } from '@ozaco/std/codec'
// Encode/decode through whichever codec currently has priority.
const bytes = yield* Codec.actions.encode({ id: 1 })
const value = yield* Codec.actions.decode<User>(bytes)
// Text and streaming variants share the same routing.
const text = yield* Codec.actions.stringify(value)
const items = yield* Codec.actions.decodeStream(source, true)hasCodec
Whether any codec is registered in the current scope.
const hasCodec: Operation<boolean>Use this (not Codec.context.get()) to decide whether to auto-install a default codec. It reflects the current scope chain only, not registrations made in unrelated scopes or bundles.
import { hasCodec } from '@ozaco/std/codec'
import { install } from '@ozaco/std/plugin'
import { JsonCodec } from '@ozaco/std/codec/impl/json'
if (!(yield* hasCodec)) {
yield* install(JsonCodec)
}Codec implementations
Built-in codecs, each imported from its own `impl/*` subpath and installed into the registry.
JsonCodec
JSON codec backed by the built-in `JSON` and a streaming JSON parser.
// from '@ozaco/std/codec/impl/json'
const JsonCodec: CodecDef // exposes CodecDef.JsonActions; default priority 999
// JsonActions.stringify additionally accepts an indent width:
JsonCodec.actions.stringify(value: unknown, space?: number): Future<string>Registers itself on setup (name std/json-codec, priority 999) and unregisters on teardown. decodeStream uses @streamparser/json, correctly buffering multi-byte UTF-8 sequences split across chunk boundaries.
import { install } from '@ozaco/std/plugin'
import { JsonCodec } from '@ozaco/std/codec/impl/json'
yield* install(JsonCodec) // priority 999 (default)
yield* install(JsonCodec, { priority: 1000 }) // or override options
// Direct calls always target this codec, bypassing priority routing.
const text = yield* JsonCodec.actions.stringify(entry, 2)TomlCodec
Zero-dependency TOML codec (from-scratch parser and serializer).
// from '@ozaco/std/codec/impl/toml'
const TomlCodec: CodecDef // exposes CodecDef.Actions; default priority 500Adapted from Deno @std/toml; TOML datetimes are intentionally unsupported. Registers as std/toml-codec at priority 500, below JsonCodec (999), so installing both keeps JSON the default — register with a higher { priority } to prefer TOML, or install it alone.
import { install } from '@ozaco/std/plugin'
import { TomlCodec } from '@ozaco/std/codec/impl/toml'
// Install alone to make TOML the active codec.
yield* install(TomlCodec)YamlCodec
YAML codec backed by `js-yaml` (optional peer dependency).
// from '@ozaco/std/codec/impl/yaml'
const YamlCodec: CodecDef // exposes CodecDef.Actions; default priority 500Requires js-yaml to be installed alongside @ozaco/std. Registers as std/yaml-codec at priority 500; install it alone or with a higher { priority } to prefer YAML over JSON.
import { install } from '@ozaco/std/plugin'
import { YamlCodec } from '@ozaco/std/codec/impl/yaml'
yield* install(YamlCodec, { priority: 1000 }) // prefer YAMLErrors
CodecErrors
The `std:codec.*` error tags failures are raised with.
const CodecErrors: {
Encode: 'std:codec.encode'
Decode: 'std:codec.decode'
Stringify: 'std:codec.stringify'
Parse: 'std:codec.parse'
EncodeStream: 'std:codec.encode-stream'
DecodeStream: 'std:codec.decode-stream'
NoCodec: 'std:codec.no-codec'
NoMatch: 'std:codec.no-match'
}Codec actions yield* fail(CodecErrors.Encode, message) (etc.) instead of throwing, so callers can pattern-match on the tag.
Types
CodecDef
The codec plugin shape and its associated action/context/handler types.
type CodecDef = Plugin<CodecDef.Context, unknown[], CodecDef.Actions>The CodecDef namespace also exposes:
- •
Options—{ name?: string; priority?: number }passed on install. - •
Context—{ name: string; priority: number }stored per registration. - •
Actions—encode/decode(bytes),stringify/parse(text),encodeStream/decodeStream. - •
JsonActions— likeActions, butstringify(value, space?)takes an indent width. - •
Handlers—register/unregister/getTransports, the registry plumbing. - •
EncodeError/DecodeError— theCodecErrors.Encode/CodecErrors.Decodetag types.
Constants
Registered symbol used as the protocol subtype tag.
CODEC
Subtype tag identifying the codec protocol.
const CODEC: unique symbol // Symbol.for('std:codec')