Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra DataGrid Server-driven data grid for Laravel
Elyra
Protocol reference

Protocol reference

The protocol is a small, framework-neutral JSON contract. It is defined once as JSON Schema and mirrored as TypeScript types (@elyra/datagrid-protocol) and PHP DTOs (elyra/datagrid-protocol).

  • Schemas: packages/protocol/schema/grid-request.schema.json, grid-response.schema.json
  • TypeScript: import type { GridRequest, GridResponse } from '@elyra/datagrid-protocol'
  • PHP: Elyra\DataGrid\Protocol\{GridRequest, GridMutation}

GridRequest

interface GridRequest {
  columns?: string[];         // fields to return (default: all declared)
  sort?: SortSpec[];          // multi-column, applied in order
  filter?: FilterGroup;       // structured filter tree
  search?: Search;            // global search
  group?: GroupSpec[];        // grouping with per-group aggregates
  aggregates?: AggregateSpec[]; // footer aggregates over the whole result
  view: Viewport;             // required — the viewport window
  meta?: ('total' | 'facets' | 'timing')[];  // opt-in extras
  facets?: FacetSpec[];       // facet specs (with meta: ['facets'])
}

interface Viewport { skip: number; take: number; }   // take: visible rows, ≤ 1000
interface SortSpec { field: string; dir: 'asc' | 'desc'; nulls?: 'first' | 'last'; }

Filters

interface FilterGroup { logic: 'and' | 'or'; filters: (FilterCondition | FilterGroup)[]; }
interface FilterCondition { field: string; op: FilterOp; value?: Scalar | Scalar[]; }

type FilterOp =
  | 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte'
  | 'in' | 'nin' | 'between'
  | 'contains' | 'ncontains' | 'startsWith' | 'endsWith'
  | 'isNull' | 'isNotNull';
  • in/nin take arrays; between takes [min, max]; isNull/isNotNull take no value.

Search

interface Search {
  query: string;
  mode?: 'hybrid' | 'fulltext' | 'substring';   // default substring
  fields?: string[];
  vectorField?: string;      // embedding column for hybrid mode
}

Grouping & aggregates

interface GroupSpec { field: string; aggregates?: AggregateSpec[]; rollup?: boolean; }
interface AggregateSpec {
  field: string;
  fn: 'sum' | 'avg' | 'min' | 'max' | 'count' | 'countDistinct' | 'median' | 'percentile';
  p?: number;    // fraction in (0,1) for percentile
  as?: string;   // output alias
}
interface FacetSpec { field: string; top?: number; }   // top-N most frequent

GridResponse

interface GridResponse {
  rows: Row[];                          // the viewport slice
  view: Viewport;                       // echo of skip/take served
  total?: number | null;               // present if meta included 'total'
  groups?: GroupRow[];                  // when grouping was requested
  aggregates?: Record<string, number | null>;  // footer aggregates
  facets?: Record<string, FacetBucket[]>;       // per-field value lists
  timing?: { elapsedMs?: number; backend?: string; usedIndex?: boolean | null; fullScan?: boolean | null; };
  notice?: { level: 'info' | 'warn'; text: string; url?: string };  // e.g. unlicensed reminder
}

interface FacetBucket { value: Scalar; count: number; }
interface GroupRow {
  field: string; value: Scalar; count: number;
  level?: number;   // depth in the hierarchy (0 = outermost)
  path?: string;    // stable key for collapse tracking
  aggregates?: Record<string, number | null>;
  isGrandTotal?: boolean;
}

GridMutation

type MutationOp = 'create' | 'update' | 'delete';
interface GridMutation { op: MutationOp; id?: Scalar; changes?: Record<string, unknown>; }
interface GridMutationResult {
  ok: boolean;
  id?: Scalar;                          // resulting key (e.g. after create)
  row?: Row;                            // persisted row echoed back
  errors?: Record<string, string[]>;   // per-field validation errors
}

Cost model in the contract

  • view.take is a viewport window, not a page size.
  • Expensive extras are opt-in via meta: total (row count), facets (distinct value lists), timing. Nothing is computed unless requested.