Files
oranguru/llm/docs/resolvespec-js.md
Hein 7244bd33fc refactor(advancedSearch): reorder exports and improve type definitions
refactor(types): reorganize SearchCondition and AdvancedSearchState interfaces
refactor(filterPresets): streamline useFilterPresets hook and localStorage handling
refactor(filtering): clean up ColumnFilterButton and ColumnFilterPopover components
refactor(loading): separate GriddyLoadingOverlay from GriddyLoadingSkeleton
refactor(searchHistory): enhance useSearchHistory hook with persistence
refactor(index): update exports for adapters and core components
refactor(rendering): improve EditableCell and TableCell components for clarity
refactor(rendering): enhance TableHeader and VirtualBody components for better readability
2026-02-15 19:54:33 +02:00

8.1 KiB

@warkypublic/resolvespec-js v1.0.0

TypeScript client library for ResolveSpec APIs. Supports body-based REST, header-based REST, and WebSocket protocols. Aligns with Go backend types.

Clients

Client Protocol Singleton Factory
ResolveSpecClient REST (body JSON) getResolveSpecClient(config)
HeaderSpecClient REST (HTTP headers) getHeaderSpecClient(config)
WebSocketClient WebSocket getWebSocketClient(config)

Singleton factories cache instances keyed by URL.

Config

interface ClientConfig {
  baseUrl: string;
  token?: string;  // Bearer token
}

interface WebSocketClientConfig {
  url: string;
  reconnect?: boolean;
  reconnectInterval?: number;
  maxReconnectAttempts?: number;
  heartbeatInterval?: number;
  debug?: boolean;
}

ResolveSpecClient (Body-Based REST)

import { ResolveSpecClient, getResolveSpecClient } from '@warkypublic/resolvespec-js';

const client = new ResolveSpecClient({ baseUrl: 'http://localhost:3000', token: 'your-token' });

// CRUD - signature: (schema, entity, id?, options?)
await client.read('public', 'users', undefined, { columns: ['id', 'name'], limit: 10 });
await client.read('public', 'users', 42);                          // by ID
await client.create('public', 'users', { name: 'New' });           // create
await client.update('public', 'users', { name: 'Updated' }, 42);   // update
await client.delete('public', 'users', 42);                        // delete
await client.getMetadata('public', 'users');                        // table metadata

Method signatures:

  • read<T>(schema, entity, id?: number|string|string[], options?): Promise<APIResponse<T>>
  • create<T>(schema, entity, data: any|any[], options?): Promise<APIResponse<T>>
  • update<T>(schema, entity, data: any|any[], id?: number|string|string[], options?): Promise<APIResponse<T>>
  • delete(schema, entity, id: number|string): Promise<APIResponse<void>>
  • getMetadata(schema, entity): Promise<APIResponse<TableMetadata>>

HeaderSpecClient (Header-Based REST)

import { HeaderSpecClient, getHeaderSpecClient } from '@warkypublic/resolvespec-js';

const client = new HeaderSpecClient({ baseUrl: 'http://localhost:3000', token: 'your-token' });

// CRUD - HTTP methods: GET=read, POST=create, PUT=update, DELETE=delete
await client.read('public', 'users', undefined, { columns: ['id', 'name'], limit: 50 });
await client.create('public', 'users', { name: 'New' });
await client.update('public', 'users', '42', { name: 'Updated' });
await client.delete('public', 'users', '42');

Method signatures:

  • read<T>(schema, entity, id?: string, options?): Promise<APIResponse<T>>
  • create<T>(schema, entity, data, options?): Promise<APIResponse<T>>
  • update<T>(schema, entity, id: string, data, options?): Promise<APIResponse<T>>
  • delete(schema, entity, id: string): Promise<APIResponse<void>>

Header Mapping

Header Options Field Format
X-Select-Fields columns comma-separated
X-Not-Select-Fields omit_columns comma-separated
X-FieldFilter-{col} filters (eq, AND) value
X-SearchOp-{op}-{col} filters (AND) value
X-SearchOr-{op}-{col} filters (OR) value
X-Sort sort +col asc, -col desc
X-Limit / X-Offset limit / offset number
X-Cursor-Forward cursor_forward string
X-Cursor-Backward cursor_backward string
X-Preload preload Rel:col1,col2 pipe-separated
X-Fetch-RowNumber fetch_row_number string
X-CQL-SEL-{col} computedColumns expression
X-Custom-SQL-W customOperators SQL AND-joined

Utility Functions

import { buildHeaders, encodeHeaderValue, decodeHeaderValue } from '@warkypublic/resolvespec-js';

buildHeaders({ columns: ['id', 'name'], limit: 10 });
// => { 'X-Select-Fields': 'id,name', 'X-Limit': '10' }

encodeHeaderValue('complex value');   // 'ZIP_...' (base64 encoded)
decodeHeaderValue(encoded);           // original string

WebSocketClient

import { WebSocketClient, getWebSocketClient } from '@warkypublic/resolvespec-js';

const ws = new WebSocketClient({ url: 'ws://localhost:8080/ws', reconnect: true, heartbeatInterval: 30000 });
await ws.connect();

// CRUD
await ws.read('users', { schema: 'public', limit: 10, filters: [...], columns: [...] });
await ws.create('users', { name: 'New' }, { schema: 'public' });
await ws.update('users', '1', { name: 'Updated' }, { schema: 'public' });
await ws.delete('users', '1', { schema: 'public' });
await ws.meta('users', { schema: 'public' });

// Subscriptions
const subId = await ws.subscribe('users', (notification) => { ... }, { schema: 'public', filters: [...] });
await ws.unsubscribe(subId);
ws.getSubscriptions();

// Connection
ws.getState();      // 'connecting' | 'connected' | 'disconnecting' | 'disconnected' | 'reconnecting'
ws.isConnected();
ws.disconnect();

// Events
ws.on('connect', () => {});
ws.on('disconnect', (event: CloseEvent) => {});
ws.on('error', (error: Error) => {});
ws.on('message', (message: WSMessage) => {});
ws.on('stateChange', (state: ConnectionState) => {});
ws.off('connect');

Options (Query Parameters)

interface Options {
  columns?: string[];
  omit_columns?: string[];
  filters?: FilterOption[];
  sort?: SortOption[];
  limit?: number;
  offset?: number;
  preload?: PreloadOption[];
  customOperators?: CustomOperator[];
  computedColumns?: ComputedColumn[];
  parameters?: Parameter[];
  cursor_forward?: string;
  cursor_backward?: string;
  fetch_row_number?: string;
}

FilterOption

interface FilterOption {
  column: string;
  operator: Operator | string;
  value: any;
  logic_operator?: 'AND' | 'OR';
}

// Operators: eq, neq, gt, gte, lt, lte, like, ilike, in,
//            contains, startswith, endswith, between,
//            between_inclusive, is_null, is_not_null

SortOption

interface SortOption {
  column: string;
  direction: 'asc' | 'desc' | 'ASC' | 'DESC';
}

PreloadOption

interface PreloadOption {
  relation: string;
  table_name?: string;
  columns?: string[];
  omit_columns?: string[];
  sort?: SortOption[];
  filters?: FilterOption[];
  where?: string;
  limit?: number;
  offset?: number;
  updatable?: boolean;
  computed_ql?: Record<string, string>;
  recursive?: boolean;
  primary_key?: string;
  related_key?: string;
  foreign_key?: string;
  recursive_child_key?: string;
  sql_joins?: string[];
  join_aliases?: string[];
}

Other Types

interface ComputedColumn { name: string; expression: string; }
interface CustomOperator { name: string; sql: string; }
interface Parameter { name: string; value: string; sequence?: number; }

Response Types

interface APIResponse<T = any> {
  success: boolean;
  data: T;
  metadata?: Metadata;
  error?: APIError;
}

interface APIError { code: string; message: string; details?: any; detail?: string; }
interface Metadata { total: number; count: number; filtered: number; limit: number; offset: number; row_number?: number; }

interface TableMetadata {
  schema: string;
  table: string;
  columns: Column[];
  relations: string[];
}

interface Column { name: string; type: string; is_nullable: boolean; is_primary: boolean; is_unique: boolean; has_index: boolean; }

WebSocket Message Types

type MessageType = 'request' | 'response' | 'notification' | 'subscription' | 'error' | 'ping' | 'pong';
type WSOperation = 'read' | 'create' | 'update' | 'delete' | 'subscribe' | 'unsubscribe' | 'meta';

interface WSMessage {
  id?: string; type: MessageType; operation?: WSOperation;
  schema?: string; entity?: string; record_id?: string;
  data?: any; options?: WSOptions; subscription_id?: string;
  success?: boolean; error?: WSErrorInfo; metadata?: Record<string, any>; timestamp?: string;
}

interface WSNotificationMessage {
  type: 'notification'; operation: WSOperation; subscription_id: string;
  schema?: string; entity: string; data: any; timestamp: string;
}

Dependencies

  • Runtime: uuid
  • Peer: none
  • Node >= 18