Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usehasp.com/llms.txt

Use this file to discover all available pages before exploring further.

AbortSignal / Request Cancellation

All public methods accept an optional AbortSignal as their last parameter:
const controller = new AbortController();

window.addEventListener('beforeunload', () => controller.abort());

const result = await sdk.listRecords('tasks', {}, controller.signal);
When cancelled, the SDK re-throws the native DOMException with name === 'AbortError':
try {
  const result = await sdk.listRecords('tasks', {}, signal);
} catch (error) {
  if (error instanceof DOMException && error.name === 'AbortError') {
    return; // intentionally cancelled
  }
  if (error instanceof HaspSDK.NetworkError) {
    // genuine connection failure
  }
}
The signal is also respected during retry backoff delays — if the signal fires while the SDK is waiting before a retry, the delay is cancelled immediately.

destroy()

Call destroy() when done to abort all in-flight requests and clear event handlers:
sdk.destroy();
Pending promises reject with AbortError. After destroy(), maintenance event handlers are cleared.

Event Handler Cleanup

sdk.on() returns an unsubscribe function:
const unsubscribe = sdk.on('maintenanceStart', (status) => {
  showBanner(status?.message);
});

unsubscribe(); // later, when cleaning up

TypeScript Types

type RecordData = Record<string, unknown> & {
  id: string;
  created_by?: string;
  updated_by?: string;
  created_at: string;
  updated_at: string;
};

type ListResponse<T> = {
  data: T[];
  meta: { hasMore: boolean; cursor: string | null; total?: number };
};

type SingleResponse<T> = { data: T };

type Filter = Record<string, Partial<Record<FilterOperator, FilterValue>>>;
type FilterOperator = 'eq' | 'neq' | 'in' | 'contains' | 'gt' | 'gte' | 'lt' | 'lte';
type FilterValue = string | number | boolean | (string | number)[];

type ListOptions = {
  filter?: Filter;
  sort?: string;
  pageSize?: number;
  cursor?: string;
};

type PaginateOptions = Omit<ListOptions, 'cursor'> & {
  maxPages?: number;
  maxRecords?: number;
  signal?: AbortSignal;
};

type SchemaEntity = {
  key: string;
  name: string;
  display_field: string | null;
  fields: SchemaField[];
};

type SchemaField = {
  key: string;
  name: string;
  type: string;
  required: boolean;
  read_only: boolean;
  options?: string[] | null;
  sort_order: number;
};

type BootstrapData = {
  user: { id: string; name: string; email: string };
  role: 'viewer' | 'org_admin_viewer' | 'editor' | 'admin';
  app: { id: string; name: string; type: string };
  limits: Record<string, number>;
};

type FileUploadRequest = {
  fieldKey: string;
  fileName: string;
  mimeType?: string;
  sizeBytes: number;
};

type FileUploadResponse = {
  fileId: string;
  uploadUrl: string;
  headers: Record<string, string>;
};

type FileDownloadResponse = {
  url: string;
  fileName: string;
  mimeType: string | null;
  expiresAt: string;
};