Protocol reference
The protocol defines the serialized table response. Use the Laravel builders for application code; use these schemas and the decoder when building validation or integration tooling.
The development protocol is draft 0.3.0 with checksum
d44c495114d1c4a3add438136683eca7c994662e8dc472cecd6dd8dc60081a39.
Number presentation and table-local problems require a matching contract in the Laravel producer and frontend consumers. Repository development artifacts do not establish feature support in already-published package versions.
Declare @inertiax/table-protocol as a direct dependency if your source imports it.
It owns the Table contract. @inertiax/protocol supplies common JSON types and validation
primitives; it has no Table decoder or Table schema exports.
Shipped reference files
Section titled “Shipped reference files”The installed @inertiax/table-protocol package exposes the maintained contract without repository
access:
| Package subpath | Purpose |
|---|---|
@inertiax/table-protocol/schemas/envelope.schema.json |
Envelope entry schema |
@inertiax/table-protocol/schemas/table.schema.json |
Complete Table component schema |
@inertiax/table-protocol/schemas/common.schema.json |
Table definitions and references to common identifiers |
@inertiax/table-protocol/schemas/foundation.schema.json |
Pinned common JSON definitions included in this Table artifact |
@inertiax/table-protocol/contract.json |
Table contract identity and common-schema provenance |
@inertiax/table-protocol/fixtures/manifest.json |
Accepted and rejected fixture inventory |
@inertiax/table-protocol/fixtures/valid/minimal.json |
Smallest complete valid Table example |
@inertiax/table-protocol/fixtures/valid/custom-type.json |
Namespaced custom leaf example |
@inertiax/table-protocol/VERSION and @inertiax/table-protocol/CHECKSUM |
Installed artifact identity |
Use these package subpaths in validators, tests, or tooling. Application code normally needs only the root package exports.
Envelope
Section titled “Envelope”Every payload contains a protocol version and a component:
{ "protocolVersion": "0.3.0", "component": { "type": "table", "id": "users" }}The abbreviated component above is explanatory, not a valid complete Table. Use the shipped
fixtures/valid/minimal.json subpath for executable minimal input and the shipped schemas for the
complete contract.
Table component shape
Section titled “Table component shape”A successful Table component carries:
- a stable
type: "table"and instanceid; - Column and Filter definitions;
- capabilities for pagination, sorting, selection, filter mode, and refresh;
- server state for pagination, ordered sorting, recursive filters, and search;
- result totals and last-page information;
- a
rowKeyand row-orienteddata.rows.
Columns contain definitions only. Each row cell is a payload with value plus optional icon,
variant, and meta. Capabilities constrain which state transitions are valid.
Selection and column visibility are local state, not server query state.
data.rowKey must name a declared Column even when rows is empty. Each row must contain that
cell, and its value must be a string or JavaScript-safe integer. Laravel transports larger integer
identities as exact decimal strings so JavaScript does not silently change them.
Filter definitions
Section titled “Filter definitions”A filter is a field. Its clauses are the comparisons offered for it, and each clause’s input describes the value it takes, so a renderer draws and checks a value from the clause alone.
| Filter field | Required | Meaning |
|---|---|---|
key |
Yes | The filter’s ID in state, URLs, and links |
label |
No | Shown in the field picker and chips; renderers fall back to key |
clauses |
Yes, at least one | The clauses offered for the field, in order, with unique keys |
defaultClause |
Yes | The key of one of clauses, picked when the field is added |
pinned |
No, default false |
Shown as a pinned control unless the page gives its own list |
meta |
No | Application data |
| Clause field | Required | Meaning |
|---|---|---|
key |
Yes | A built-in clause key or a vendor/name identifier |
label |
No | Shown for the comparison |
input |
No | The value the clause takes; absent when it takes none |
meta |
No | Application data |
| Input field | Required | Meaning |
|---|---|---|
valueType |
Yes | text, number, boolean, select, date, datetime, time, or vendor/name |
mode |
Yes | single, multiple, or range |
options |
Yes for select; not allowed otherwise |
{ value, label } entries whose scalar values are unique |
optionsTruncated |
No; select only |
true when the producer stopped listing options at its limit |
Every value type allows single. Only select allows multiple, and range is allowed for
number, date, datetime, time, and custom value types.
{ "key": "created_at", "label": "Created", "defaultClause": "between", "pinned": false, "clauses": [ { "key": "between", "label": "Between", "input": { "valueType": "date", "mode": "range" } }, { "key": "acme/last-days", "label": "In the last … days", "input": { "valueType": "number", "mode": "single" } }, { "key": "is-not-set", "label": "Is empty" } ]}Each condition { key, clause, value } in the filter state carries a value that matches its
clause’s input:
- no input:
null; single: one value of the value type;multiple: a non-empty list of values of the value type;range:[from, to], both of the value type.
text, date, datetime, and time values are strings, number values finite numbers,
boolean values Booleans, and select values strings, numbers, or Booleans. A custom value type
accepts any JSON value except null. null is never a value.
Table problem shape
Section titled “Table problem shape”TableEnvelope is the union of successful Envelope and ProblemEnvelope. A problem component
contains only type, id, and problem:
{ "type": "table", "id": "orders", "problem": { "issues": [{ "field": "page", "code": "page-unavailable" }], "resettable": true }}Each issue names one unique field: page, pageSize, sorting, filters, or search. Codes are
invalid-url-state or page-unavailable (page only). resettable records whether the producer
permits a reset; the integration must also support it. Problem components have no rows, result
metadata, or successful state. Use isProblemEnvelope() to narrow a decoded envelope before
accessing result fields. The shipped fixtures/valid/table-problem.json is a complete example.
Validation boundary
Section titled “Validation boundary”Consumers decode unknown input before creating a runtime session. Producers validate the complete envelope before returning it. A malformed known field reports schema-path context; an unsupported protocol version fails before a transformation or render.
Use decodeTableEnvelope when an application or integration receives unknown protocol data directly:
import { decodeTableEnvelope } from '@inertiax/table-protocol';
export function decodeInput(input: unknown) { return decodeTableEnvelope(input);}decodeTableEnvelope returns a deeply immutable clone. It throws ProtocolDecodeError with:
INERTIAX_PROTOCOL_VERSION_UNSUPPORTEDwhen the received protocol version is not supported;INERTIAX_PROTOCOL_DECODE_FAILEDfor invalid JSON-domain values, malformed known fields, or invalid Table semantics.
The error includes path, structured diagnostics, the supported version, and available received
version/component context. Catch it only when the application can add useful context or recovery;
do not continue with the rejected input.
Compatibility rules
Section titled “Compatibility rules”- Protocol versions are independent from npm and Composer package versions. A decoder-only patch can preserve the same wire contract and Laravel snapshot.
- Unsupported versions fail before transformation or rendering.
- Known malformed fields fail with schema-path diagnostics.
- Custom column types, value types, and clause keys must be namespaced as
vendor/name. - Unknown custom leaf identifiers remain valid protocol data, but the React renderer needs a matching registration or uses its configured diagnosed fallback.
A package patch or minor release does not imply a protocol change. Conversely, protocol evolution may require coordinated compatible package releases while their version numbers remain different.
Integration tooling
Section titled “Integration tooling”Use the exported TypeScript declarations and runtime decoder; do not copy protocol types into application code. Validate unknown input before creating a session. See Direct envelope for custom integrations and their ownership contracts.