/**
* FlatSQL-WASM engine store (loop D.1) — THE SDNNode store.
*
* Promoted from `src/ui/runtime/local-flatsql.ts` into core: per-standard
* engine databases created from SDS FlatBuffer schemas, per-provider source
* partitioning via `registerSource` (shadow tables `
@`), and
* unified views (`
` = UNION ALL over the shadow tables with a
* `_source` column carrying the FULL shadow-table name, e.g.
* `OMM@celestrak-gp`) — exactly mirroring the sdn-server engine layout
* (sdn-server/internal/storage/engine_records.go). Records stored without an
* explicit source partition under the server's default source name `local`.
*
* Persistence (browser durability): THE ENGINE ITSELF IS DISK-BACKED. Every
* standard's database is opened at a PATH (`openDatabase`) inside this store's
* namespace on the shared seven-import I/O router, so the engine writes its own
* arena (`.fsdata`) and index (``) through the node's persistence
* store — IndexedDB `sdn-local-flatsql`/`datastores` by default, or a desktop
* HTTP persistence endpoint. Boot is `hydrate -> openDatabase -> registerFileId
* -> openState`, and flush is `flushIndex() -> await io.flushFor(path)`: exactly the
* sequence the Go host runs through `internal/flatsqlrt/hostio.go`. One engine,
* one durability story.
*
* SOURCE PARTITIONS ARE DURABLE TOO (flatsql >= 1.4.5). `_flatsql_sources` and
* `_flatsql_source_ranges` live in the index file, so `openState` restores every
* `
@` shadow table, re-binds the vtab modules and re-creates the
* unified views with NOTHING re-registered. That is what retired the old
* snapshot-export path (per-(standard, source) `SELECT _data FROM
* "Table@source"` blobs re-ingested at boot): it cost a whole-dataset rewrite
* per flush and a full re-ingest per boot, and it existed only because
* flatsql <= 1.4.4 restored base tables alone.
*
* Two legacy layouts are still READ, once, and deleted after they are folded
* into the engine's own state: the per-source streams above, and the pre-D.1
* single `exportData` blob (migrated into the default `local` partition).
* Neither is ever written again.
*/
import type { FlatSQL, FlatSQLDatabase, QueryParam } from 'flatsql/wasm';
import { type EngineEpochProfileSpec, type EngineEpochQueryProfilesConfig, type EngineEpochQueryRequest } from './epoch-query-sql';
import { type ReadOnlySqlValidationOptions } from './read-only-sql-sandbox';
import { FlatSqlIoRouter } from './flatsql-io-store';
/**
* Minimal record surface the engine store ingests. Structurally compatible
* with the webUI backend's RawDataRecord (src/ui/runtime/sdn-backend.ts).
*/
export interface LocalFlatSqlIngestRecord {
schemaName: string;
cid: string;
peerId?: string | null;
providerId?: string | null;
sourceName?: string | null;
batchId?: string | null;
timestamp?: string | null;
dataBytes?: Uint8Array;
}
export interface LocalFlatSqlSchema {
standardId: string;
tableName: string;
fileId: string;
schema: string;
/**
* Engine epoch profile columns for this standard (loop D.2). Overrides /
* supplements DEFAULT_ENGINE_EPOCH_SPECS so CAT/MPE/SPW can opt into the
* engine-native epoch profiles through configuration, not code.
*/
epochSpec?: {
partitionColumn?: string;
epochColumn?: string;
} | null;
}
/**
* Default source partition for records stored without an explicit source —
* mirrors sdn-server's engineDefaultSource (engine_records.go).
*/
export declare const LOCAL_FLATSQL_DEFAULT_SOURCE = "local";
export interface LocalFlatSqlStoreOptions {
schemas: LocalFlatSqlSchema[];
persistenceKey?: string | null;
desktopPersistenceBaseUrl?: string | null;
fetch?: FetchLike | null;
/** Injectable persistence backend (tests / embedders). Defaults to IndexedDB or the desktop endpoint. */
persistenceStore?: LocalFlatSqlPersistenceStore | null;
/**
* Per-standard default query profiles (loop D.2) — the SAME shape the
* retrieval module reads through plugin.getConfig, keyed by schema name
* (`OMM.fbs`) or standard id (`OMM`). Request fields override these;
* whatever is still unset falls back to the compiled defaults
* (`nearest`, epoch = now, limit 50000).
*/
queryProfiles?: EngineEpochQueryProfilesConfig | null;
/** Clock used when a query epoch is neither requested nor configured (tests). */
nowSeconds?: (() => number) | null;
}
export interface ClearLocalFlatSqlStoreOptions {
persistenceKey: string;
standardIds: string[];
desktopPersistenceBaseUrl?: string | null;
fetch?: FetchLike | null;
persistenceStore?: LocalFlatSqlPersistenceStore | null;
}
export interface LocalFlatSqlQueryResult {
columns: string[];
rows: unknown[][];
records: Array>;
}
export type LocalFlatSqlQueryOptions = ReadOnlySqlValidationOptions;
export interface LocalFlatSqlStandardStats {
standardId: string;
tableName: string;
recordCount: number;
cachedBytes: number;
ingestedRecordCount: number;
pinnedRows: number;
pinnedBytes: number;
snapshotId: string | null;
head: string | null;
highWaterMark: string | null;
lastSyncedAt: string | null;
}
export interface LocalFlatSqlPinLedgerEntry {
cid: string;
standardId: string;
schemaName: string;
providerPeerId?: string | null;
providerPublicKey?: string | null;
providerId?: string | null;
sourceName?: string | null;
batchId?: string | null;
queryProfile?: string | null;
snapshotId?: string | null;
head?: string | null;
highWaterMark?: string | null;
byteHash?: string | null;
role: string;
rowCount?: number | null;
byteCount?: number | null;
ttlSeconds?: number | null;
verificationState: string;
materializedAt?: string | null;
verifiedAt?: string | null;
updatedAt?: string | null;
}
export interface LocalFlatSqlPinLedgerQuery {
cid?: string | null;
standardId?: string | null;
schemaName?: string | null;
providerPeerId?: string | null;
providerPublicKey?: string | null;
providerId?: string | null;
sourceName?: string | null;
batchId?: string | null;
queryProfile?: string | null;
role?: string | null;
verificationState?: string | null;
}
export interface LocalFlatSqlIngestOptions {
source?: string | null;
persist?: boolean;
transfer?: boolean;
}
export interface LocalFlatSqlStreamIngestOptions extends LocalFlatSqlIngestOptions {
recordKeys?: string[];
recordKeyPrefix?: string;
recordKeyOffset?: number;
skipRecords?: number;
pinLedgerEntries?: LocalFlatSqlPinLedgerEntry[];
}
export interface LocalFlatSqlStatsOptions {
includeCachedBytes?: boolean;
}
export interface LocalFlatSqlPinLedgerWriteOptions {
persist?: boolean;
}
export interface LocalFlatSqlClearOptions {
persist?: boolean;
}
export interface FlatSqlSizePrefixedStreamInfo {
totalRecordCount: number;
ingestRecordCount: number;
ingestStartOffset: number;
allFramesHaveDirectFileIdentifier: boolean;
}
export interface LocalFlatSqlStore {
ingestRecords(standardId: string, records: LocalFlatSqlIngestRecord[], sourceOrOptions?: string | LocalFlatSqlIngestOptions | null): Promise;
ingestFlatBufferStream(standardId: string, streamBytes: Uint8Array, options?: LocalFlatSqlStreamIngestOptions | null): Promise;
/** Registered source partitions (shadow tables `
@`) for a standard. */
listSources?(standardId: string): string[] | Promise;
clearStandard(standardId: string, options?: LocalFlatSqlClearOptions): Promise;
createStandardReplacementStore(standardId: string): Promise;
replaceStandardFrom(standardId: string, replacementStore: LocalFlatSqlStore, entries: LocalFlatSqlPinLedgerEntry[], options?: LocalFlatSqlPinLedgerWriteOptions): Promise;
flush(standardId?: string): Promise;
recordPinLedgerEntries(entries: LocalFlatSqlPinLedgerEntry[], options?: LocalFlatSqlPinLedgerWriteOptions): Promise;
listPinLedgerEntries(query?: LocalFlatSqlPinLedgerQuery): Promise;
query(sql: string, standardId?: string, options?: LocalFlatSqlQueryOptions): LocalFlatSqlQueryResult | Promise;
/**
* PRIMARY query path (loop D.2): run an engine-native epoch profile
* (`nearest` / `as_of` / `forward` — the server's retrieval profiles,
* SQL byte-identical to sdn-server engine_records.go) over the unified
* per-standard view and return the ALIGNED size-prefixed FlatBuffer frame
* stream — the wire format, zero-copy out of the engine.
*/
queryEpochRawStream?(standardId: string, request?: EngineEpochQueryRequest | null): Uint8Array | Promise;
/**
* Generic aligned-raw-stream query (server mirror of
* FlatSQLStore.QueryRawStream): read-only SQL whose result cells are all
* BLOBs (`SELECT _data FROM ...`), executed verbatim with positional
* params. Returns the aligned size-prefixed frame stream.
*/
queryRawFlatBufferStream?(standardId: string, sql: string, params?: QueryParam[]): Uint8Array | Promise;
getStats(options?: LocalFlatSqlStatsOptions): LocalFlatSqlStandardStats[] | Promise;
destroy(): void;
}
type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise;
export interface LocalFlatSqlPersistenceStore {
readonly available: boolean;
readBytes(key: string): Promise;
writeBytes(key: string, bytes: Uint8Array): Promise;
readJson(key: string): Promise;
writeJson(key: string, value: unknown): Promise;
deleteKey(key: string): Promise;
}
/** In-memory persistence store (tests / ephemeral nodes). */
export declare class MemoryFlatSqlPersistenceStore implements LocalFlatSqlPersistenceStore {
readonly available = true;
private readonly entries;
readBytes(key: string): Promise;
writeBytes(key: string, bytes: Uint8Array): Promise;
readJson(key: string): Promise;
writeJson(key: string, value: unknown): Promise;
deleteKey(key: string): Promise;
}
/** The process-wide FlatSQL I/O router, created on first use. */
export declare function getSharedFlatSqlIoRouter(): FlatSqlIoRouter;
/** Path prefix owned by one persistence key inside the router namespace. */
export declare function flatSqlIoPrefixForKey(persistenceKey: string): string;
/**
* Mount a persistence store as a durable FlatSQL backend.
*
* Idempotent per prefix: the router keeps entries forever (there is one wasm
* instance for the life of the context), so re-registering the same prefix
* would shadow rather than replace.
*/
export declare function registerFlatSqlIoStore(persistenceKey: string, store: LocalFlatSqlPersistenceStore): string;
/**
* Durable database path for one standard inside a persistence key's namespace.
* The engine owns `` (index), `.fsdata` (arena) and
* `-journal`; nothing else in the store addresses those keys.
*/
export declare function flatSqlDatabasePathForKey(persistenceKey: string, standardId: string): string;
/** Shared FlatSQL-WASM engine instance for this JS context, disk-capable. */
export declare function getSharedFlatSql(): Promise;
/**
* Engine database session setup (loop D.6). The browser/Node wasm build has
* no filesystem: any query whose sorter/window spills a temp b-tree to
* "disk" (e.g. the epoch-nearest profile over a catalog-scale partition,
* ~29K objects) dies with `SQL execution error: disk I/O error` unless
* SQLite keeps temp storage in memory. The engine is in-memory anyway
* (OMIT_WAL) — the server hosts run the identical data fine, so this only
* aligns the JS host with them. MUST run AFTER registerFileId: executing
* any SQL first finalizes the schema before the record vtab exists.
*/
export declare function configureEngineDatabaseSession(db: Pick): void;
export declare function createLocalFlatSqlStore(options: LocalFlatSqlStoreOptions): Promise;
export declare function clearLocalFlatSqlStore(options: ClearLocalFlatSqlStoreOptions): Promise;
export declare function stripSdnFlatBufferSizePrefix(bytes: Uint8Array): Uint8Array;
export declare function isReadOnlyFlatSqlQuery(sql: string): boolean;
/**
* Engine epoch profile spec for a configured standard (loop D.2): built-in
* registry defaults (OMM) overlaid with the schema's `epochSpec` config.
* Throws for standards without configured epoch columns.
*/
export declare function engineEpochSpecForSchema(schema: LocalFlatSqlSchema): EngineEpochProfileSpec;
/**
* Zero-copy frame iterator over an aligned size-prefixed FlatBuffer stream:
* every yielded frame is a subarray VIEW into the stream bytes (no copies) —
* the decoded-record convenience over `queryEpochRawStream` output.
*/
export declare function iterateFlatSqlSizePrefixedStream(streamBytes: Uint8Array): Generator;
export declare function decodeFlatSqlSizePrefixedStream(streamBytes: Uint8Array, skipRecords?: number): Uint8Array[];
export declare function flatSqlSizePrefixedStreamInfo(streamBytes: Uint8Array, skipRecords?: number): FlatSqlSizePrefixedStreamInfo;
/**
* Resolve the default persistence backend the engine store would use for the
* given options (injected store > desktop endpoint > IndexedDB).
*/
export declare function createDefaultLocalFlatSqlPersistenceStore(options?: Pick): LocalFlatSqlPersistenceStore;
export {};
//# sourceMappingURL=local-flatsql.d.ts.map