Types
All TypeScript interfaces for the Alap configuration and engine.
AlapConfig
Root configuration object. Passed to registerConfig(), AlapUI, AlapEngine, and framework providers.
interface AlapConfig {
allLinks: Record<string, AlapLink>; // required
settings?: AlapSettings;
macros?: Record<string, AlapMacro>;
searchPatterns?: Record<string, AlapSearchPattern | string>;
protocols?: Record<string, AlapProtocol>;
}Only allLinks is required. Everything else is optional.
AlapLink
A single link entry in config.allLinks.
interface AlapLink {
url: string; // required
label?: string; // required unless image is set
tags?: string[];
cssClass?: string;
image?: string;
altText?: string;
targetWindow?: string; // '_self', '_blank', etc. Default: 'fromAlap'
description?: string;
thumbnail?: string;
hooks?: string[];
guid?: string;
createdAt?: string | number; // ISO 8601 or Unix ms
meta?: Record<string, unknown>;
}| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Destination URL |
label | string | No | Display text (required unless image is set) |
tags | string[] | No | Tags for .tag queries |
cssClass | string | No | CSS class applied to the menu item |
image | string | No | Image URL rendered instead of text |
altText | string | No | Alt text for image |
targetWindow | string | No | _self, _blank, _parent, _top, or any string |
description | string | No | Used by search patterns and hooks |
thumbnail | string | No | Preview image for hover/context events (not rendered in menu) |
hooks | string[] | No | Event hooks this item participates in (overrides settings.hooks) |
guid | string | No | Permanent UUID that survives renames |
createdAt | string | number | No | ISO 8601 or Unix ms. Used by age filters |
meta | Record<string, unknown> | No | Arbitrary metadata for protocol queries |
AlapSettings
Global settings in config.settings.
interface AlapSettings {
listType?: 'ul' | 'ol';
menuTimeout?: number;
maxVisibleItems?: number;
hooks?: string[];
existingUrl?: 'prepend' | 'append' | 'ignore';
placement?: 'N' | 'NE' | 'E' | 'SE' | 'S' | 'SW' | 'W' | 'NW' | 'C';
placementGap?: number;
viewportPadding?: number;
viewportAdjust?: boolean;
targetWindow?: string;
}| Field | Type | Default | Description |
|---|---|---|---|
listType | 'ul' | 'ol' | 'ul' | Menu list element type |
menuTimeout | number | 5000 | Auto-dismiss timeout (ms) after mouse leaves |
maxVisibleItems | number | 10 | Items before the menu scrolls. 0 = no limit |
hooks | string[] | — | Default hooks for all items |
existingUrl | 'prepend' | 'append' | 'ignore' | 'prepend' | How to handle an existing href on the trigger |
placement | Placement | 'SE' | Preferred menu position: N, NE, E, SE, S, SW, W, NW, C |
placementGap | number | 4 | Pixel gap between trigger edge and menu edge |
viewportPadding | number | 8 | Minimum distance the menu keeps from viewport edges |
viewportAdjust | boolean | true | Enable smart placement with viewport containment and fallback |
targetWindow | string | — | Global default for link targets |
Placement type
type Placement = 'N' | 'NE' | 'E' | 'SE' | 'S' | 'SW' | 'W' | 'NW' | 'C';| Value | Position | Alignment |
|---|---|---|
N | Above trigger | Centered horizontally |
NE | Above trigger | Left edge aligned with trigger left |
E | Right of trigger | Vertically centered |
SE | Below trigger | Left edge aligned with trigger left |
S | Below trigger | Centered horizontally |
SW | Below trigger | Right edge aligned with trigger right |
W | Left of trigger | Vertically centered |
NW | Above trigger | Right edge aligned with trigger right |
C | Centered over trigger | Both axes |
When the preferred placement doesn't fit in the viewport, Alap tries the opposite side first, then adjacent positions, then picks the best available fit — clamping height and enabling scroll if needed. The menu never causes the page to scroll.
AlapMacro
A named macro in config.macros.
interface AlapMacro {
linkItems: string;
config?: Record<string, unknown>; // reserved for future use
}AlapSearchPattern
A named regex pattern in config.searchPatterns. Can also be a plain string (shorthand for { pattern: "..." }).
interface AlapSearchPattern {
pattern: string;
options?: AlapSearchOptions;
}
interface AlapSearchOptions {
fields?: string; // Field codes: l, u, t, d, k, a
limit?: number;
age?: string; // '30d', '24h', '2w'
sort?: 'alpha' | 'newest' | 'oldest';
}AlapProtocol
A registered protocol in config.protocols. Protocols come in two kinds: filter (predicate over existing links) and generate (fetch external data and return new links). A protocol can have one or both.
interface AlapProtocol {
filter?: ProtocolHandler; // Predicate: does this link match?
generate?: GenerateHandler; // Async: fetch and return new links
cache?: number; // TTL in minutes for generate results (0 = no cache, default: 5)
keys?: Record<string, WebKeyConfig>; // Key configs for external protocols
allowedOrigins?: string[]; // Restrict :web: fetch to these origins
sources?: string[]; // Default: ['config']
[key: string]: unknown;
}
type ProtocolHandler = (segments: string[], link: AlapLink, id: string) => boolean;
type GenerateHandler = (segments: string[], config: AlapConfig) => Promise<AlapLink[]>;If allowedOrigins is set, any :web: fetch whose URL origin is not in the list is rejected before the request is made. Omit or pass an empty array to allow all origins.
WebKeyConfig
Configuration for a single key in an external protocol like :web:.
interface WebKeyConfig {
url: string; // Base URL for the API endpoint
linkBase?: string; // Prepended to relative link URLs (e.g. "https://openlibrary.org")
searches?: Record<string, Record<string, string | number>>; // Predefined search aliases
map?: { // Field mapping: API field → AlapLink field
label?: string;
url?: string;
meta?: Record<string, string>;
};
cache?: number; // Per-key cache TTL override (minutes)
credentials?: boolean; // Send browser credentials (cookies, auth) — default: false
}ResolvedLink
Returned by engine.resolve().
type ResolvedLink = { id: string } & AlapLink;ResolveResult
Full result with metadata (used internally by refiners).
interface ResolveResult {
links: ResolvedLink[];
totalMatches: number; // Count before refiners applied
}ConfigStore
Interface for persistence backends. See Storage.
interface ConfigStore {
save(name: string, config: AlapConfig): Promise<void>;
load(name: string): Promise<AlapConfig | null>;
loadEntry(name: string): Promise<ConfigEntry | null>;
list(): Promise<string[]>;
remove(name: string): Promise<void>;
}
interface ConfigEntry {
config: AlapConfig;
meta: ConfigMeta;
}
interface ConfigMeta {
updatedAt: string; // ISO 8601
createdAt: string; // ISO 8601
}Constants
Safety limits enforced by the parser:
| Constant | Value | Description |
|---|---|---|
MAX_DEPTH | 32 | Maximum parentheses nesting |
MAX_TOKENS | 1024 | Maximum tokens per expression |
MAX_MACROS | 10 | Maximum macro expansion rounds |
MAX_REGEX | 5 | Maximum regex searches per expression |
MAX_REFINERS | 10 | Maximum refiners per expression |
MAX_GENERATED_LINKS | 200 | Maximum links a generate handler can return per call |
WEB_FETCH_TIMEOUT_MS | 10,000 | Timeout for :web: protocol fetch requests (10 seconds) |
MAX_WEB_RESPONSE_BYTES | 1,048,576 | Maximum response body size for :web: fetch (1 MB) |