# gizdb:typed

Typed data contracts: Slot, Codec, the codecs, logical Contract and the exact JSON transport of a Value. Applications, web models and generated code import only this module. It imports no SQL engine, session or executor, so a typed web model does not link the database (db/query.giz holds the typed queries and commands).

```gizlang
import * as Typed from "gizdb:typed";
```

## Types

### `Slot`

```gizlang
type Slot = { name: string; ty: Type; nullable: bool; }
```

Storage/result contracts use the engine's Type, never a web-specific type registry.

- `name`: `string`
- `ty`: `M55.Type`
- `nullable`: `bool`

### `Codec`

```gizlang
type Codec<T> = { slot: Slot; encode: (value: T) => Result<Value, DbError> effects { fail }; decode: (value: Value) => Result<T, DbError> effects { fail }; }
```

How a value of T is written to and read from a database column: its slot and the two conversions.

Opaque: create and use it through this module's functions.

### `Patch`

```gizlang
type Patch = { names: Vec<string>; values: Vec<Value>; }
```

Missing in a patch means unchanged; present NULL means an explicit clear.

- `names`: `Vec<string>`
- `values`: `Vec<M55.Value>`

### `RowPatch`

```gizlang
type RowPatch = { key: Patch; patch: Patch; }
```

The key and the changed fields of one row.

- `key`: `M54.Patch`
- `patch`: `M54.Patch`

### `Contract`

```gizlang
type Contract = { declaration: string; slot: Slot; meaning: string; precision: i64; width: i64; timezone: string; children: Vec<Contract>; }
```

A logical extension is checked by its own codec and lowers to one physical Type.
Structured values retain exact JSON tokens; handles/functions/Refs have no data codec.

- `declaration`: `string`
- `slot`: `M54.Slot`
- `meaning`: `string`
- `precision`: `i64`
- `width`: `i64`
- `timezone`: `string`
- `children`: `Vec<M54.Contract>`

## Functions

### `textValue`

```gizlang
function textValue(slot: Slot, text: Option<string>): Result<Value, DbError>
```

Wire text is converted only at the adapter boundary, under the known column type.

Effects: fail.

### `jsonPatch`

```gizlang
function jsonPatch(slots: Vec<Slot>, text: string, complete: bool): Result<Patch, DbError>
```

One grammar owner, raw numeric tokens, decoded duplicate keys, explicit NULL and omission.

Effects: fail.

### `mismatch`

```gizlang
function mismatch(): DbError
```

The error of a value that does not match its declared data type.

Effects: fail.

### `accepts`

```gizlang
function accepts(slot: Slot, value: Value): bool
```

Whether VALUE fits SLOT: its type, and NULL only when the slot takes it.

Effects: fail.

### `checkValues`

```gizlang
function checkValues(slots: Vec<Slot>, values: Vec<Value>): Result<bool, DbError>
```

Checks that each of VALUES fits its slot of SLOTS.

Effects: fail.

### `fills`

```gizlang
function fills(slot: Type, column: Type): bool
```

Whether a column of type COLUMN fills a slot of type SLOT: the same type, or any scale for a decimal slot of scale -1.

Effects: fail.

### `checkColumns`

```gizlang
function checkColumns(slots: Vec<Slot>, names: Vec<string>, types: Vec<Type>): Result<bool, DbError>
```

A nameless slot checks only its type at its position.

Effects: fail.

### `integerCodec`

```gizlang
function integerCodec(): Codec<i64>
```

The codec of an integer column.

### `textCodec`

```gizlang
function textCodec(): Codec<string>
```

The codec of a text column.

### `booleanCodec`

```gizlang
function booleanCodec(): Codec<bool>
```

The codec of a boolean column.

### `refCodec`

```gizlang
function refCodec(): Codec<ResourceRef>
```

A record reference stored as its one text form (Security.ResourceRef.text): one
TEXT column, so equality, IN and a Space prefix use one index.

### `decimalCodec`

```gizlang
function decimalCodec(scale: i64): Codec<Dec>
```

The codec of a decimal column with SCALE.

### `unsignedCodec`

```gizlang
function unsignedCodec(): Codec<u64>
```

Unsigned integers use exact NUMERIC storage, not a signed cast or f64.

### `optionalCodec`

```gizlang
function optionalCodec<T>(codec: Codec<T>): Codec<Option<T>>
```

CODEC for a column that takes NULL (none).

### `floatCodec`

```gizlang
function floatCodec(): Codec<f64>
```

The codec of a float column. Values that are not finite fail.

### `bytesCodec`

```gizlang
function bytesCodec(): Codec<bytes>
```

The codec of a binary column.

### `timeCodec`

```gizlang
function timeCodec(unit: i64): Codec<i64>
```

The codec of a time column in UNIT.

### `vectorCodec`

```gizlang
function vectorCodec(dim: i64): Codec<Vec<f32>>
```

The codec of a vector column of DIM dimensions.

### `scalarContract`

```gizlang
function scalarContract(declaration: string, name: string, scalar: string, nullable: bool): Result<Contract, DbError>
```

Compiler scalar names lower to this one logical/storage contract. Web kinds
are presentation projections, not a second source of storage semantics.

Effects: fail.

### `slotsDigest`

```gizlang
function slotsDigest(slots: Vec<Slot>): bytes
```

The digest of the names, types and nullability of SLOTS.

Effects: fail.

### `schemaDigest`

```gizlang
function schemaDigest(schema: Schema): bytes
```

Logical storage contract used by schema admission. Physical index/layout
choices cannot change this identity. Keys and nullability can.

Effects: fail.

### `contractDigest`

```gizlang
function contractDigest(contract: Contract): Result<bytes, DbError>
```

The digest of a storage contract. It fails when the contract is not valid.

Effects: fail.

### `contractValue`

```gizlang
function contractValue(contract: Contract, text: Option<string>): Result<Value, DbError>
```

Validate logical values before their one physical representation is stored.

Effects: fail.

### `storageContract`

```gizlang
function storageContract(c: Contract): Result<bool, DbError>
```

Checks that C is a valid storage contract (within its depth and size limits).

Effects: fail.

### `writeJsonValue`

```gizlang
function writeJsonValue(out: mut bytes, value: Value): void
```

Exact scalar transport. Integer/decimal/time are strings with column Type metadata;
browser JSON.parse therefore never rounds a value before a component sees it.

Effects: fail.

