//#region src/symbols.d.ts /** Symbol key for column data type */ declare const ColumnType: unique symbol; /** Symbol key for primary key marker */ declare const IsPrimaryKey: unique symbol; /** Symbol key for auto increment marker */ declare const IsAutoInc: unique symbol; /** Symbol key for optional marker */ declare const IsOptional: unique symbol; /** Symbol key for nullable (null) marker */ declare const IsNullable: unique symbol; /** Symbol key for indexed marker */ declare const IsIndexed: unique symbol; /** Symbol key for unique marker */ declare const IsUnique: unique symbol; /** Symbol key for default value */ declare const DefaultValue: unique symbol; /** Symbol key for custom validation function */ declare const ValidateFn: unique symbol; /** Symbol key for on update marker */ declare const OnUpdate: unique symbol; /** Symbol key to store runtime ref metadata on Column instances */ declare const RefMeta: unique symbol; /** Symbol for type extraction (exists only in type system) */ declare const Selected: unique symbol; /** Symbol to indicate if insert data is array */ declare const IsArray: unique symbol; //#endregion //#region node_modules/.pnpm/toolbox-x@2.6.20/node_modules/toolbox-x/dist/index-CuYJv2Xe.d.mts /** - Generic object but with `any` value */ type GenericObject = Record; /** - Extract only primitive keys from an object, including nested dot-notation keys. */ type NestedPrimitiveKey = T extends AdvancedTypes ? never : T extends GenericObject ? { [K in keyof T & string]: T[K] extends Function ? never : T[K] extends NormalPrimitive ? K : T[K] extends GenericObject ? `${K}.${NestedPrimitiveKey}` : never; }[keyof T & string] : never; /** * * Forces TypeScript to simplify a complex or inferred type into a more readable flat object. * * *Useful when working with utility types like `Merge`, `Omit`, etc., that produce deeply nested or unresolved intersections.* * * @example * type A = { a: number }; * type B = { b: string }; * type Merged = A & B; * type Pretty = Prettify; * // Type will now display as: { a: number; b: string } */ type Prettify = { [K in keyof T]: T[K]; } & {}; /** * * Broadens a literal union (typically `string` or `number`) to also accept any other value of the base type, without losing IntelliSense autocomplete for the provided literals. * * *This is especially useful in API design where you want to provide suggestions for common options but still allow flexibility for custom user-defined values.* * * @example * // ✅ String literal usage * type Variant = LooseLiteral<'primary' | 'secondary'>; * const v1: Variant = 'primary'; // suggested * const v2: Variant = 'custom'; // also valid * * // ✅ Number literal usage * type StatusCode = LooseLiteral<200 | 404 | 500>; * const s1: StatusCode = 200; // suggested * const s2: StatusCode = 999; // also valid * * // ✅ Mixed literal * type Mixed = LooseLiteral<'one' | 2>; * const m1: Mixed = 'one'; // ✅ * const m2: Mixed = 2; // ✅ * const m3: Mixed = 'anything'; // ✅ * const m4: Mixed = 123; // ✅ * * @note Technically, this uses intersection with primitive base types (`string & {}` or `number & {}`) to retain IntelliSense while avoiding type narrowing. */ type LooseLiteral = T | $LooseLiteral; /** Helper type to create loose `string`/`number` part of {@link LooseLiteral} */ type $LooseLiteral = T extends string ? string & {} : T extends number ? number & {} : never; /** * * Maps all values of object `T` to a fixed type `R`, keeping original keys. * * @typeParam T - The source object type. * @typeParam R - The replacement value type. * * @example * type T = { name: string; age: number }; * type BooleanMapped = MapObjectValues; // { name: boolean; age: boolean } */ type MapObjectValues = { [K in keyof T]: R; }; /** Turns a union into an intersection */ type $UnionToIntersection = (U extends any ? (arg: U) => void : never) extends ((arg: infer I) => void) ? I : never; /** Gets the "last" item of a union */ type $LastOf = $UnionToIntersection T : never> extends (() => infer R) ? R : never; /** Converts a union to a tuple */ type $UnionToTuple> = [T] extends [never] ? [] : [...$UnionToTuple>, L]; /** * * Converts an array type containing a union of literals into a tuple of those literals. * * @remarks * - Takes an array type `T` (e.g. `("foo" | "bar")[]`) and produces a tuple type (e.g. `["foo", "bar"]`). * - Useful when you want to preserve all possible union members as a tuple literal instead of an array. * - For converting any type to tuple use {@link Tuple}. * * @param T - An array type whose element type is a union. * @returns A tuple type containing each member of the union in order. * * @example * type T0 = ArrayToTuple<("foo" | "bar")[]>; // ["foo", "bar"] * type T1 = ArrayToTuple<(1 | 2 | 3)[]>; // [1, 2, 3] * type T2 = ArrayToTuple; // [] */ type ArrayToTuple = T[number] extends (infer U) ? $UnionToTuple : never; /** * * Converts a type into a tuple form. * * @remarks * - If `T` is a union, it produces a tuple containing each member of the union. * - If `T` is a single type, it produces a one-element tuple `[T]`. * - If `T` is `never`, it produces an empty tuple `[]`. * * @param T - The type to convert into a tuple. * @returns A tuple type containing the elements of `T`. * * @example * type T0 = Tuple<"foo" | "bar">; // ["foo", "bar"] * type T1 = Tuple; // [number] * type T2 = Tuple<1 | 2 | 3>; // [1, 2, 3] * type T3 = Tuple; // [] */ type Tuple = [T] extends [never] ? [] : $UnionToTuple; /** Interface representing a date-like object. */ interface DateLike { toJSON?(): string; toISOString?(): string; toString?(): string; format?(): string; toISO?(): string; toFormat?(format: string): string; plus?(...args: unknown[]): unknown; minus?(...args: unknown[]): unknown; equals?(...args: unknown[]): boolean; getClass?(): unknown; constructor?: { name: string; }; } declare const __brand: unique symbol; type $Brand = { [__brand]: B; }; /** * * Creates a branded version of a base type by intersecting it with a unique compile-time marker. * * @param T - Base type to brand. * @param B - Brand identifier used to distinguish this type from structurally similar types. * @remarks Useful for preventing accidental mixing of structurally identical types, while keeping the runtime value unchanged. * * @example * type UserId = Branded; * const id = 'abc123' as UserId; */ type Branded = T & $Brand; /** Represents a value that may be `undefined`. */ type Maybe = T | undefined; /** Represents a value that may be `null`. */ type Nullable = T | null; /** Represents a value that may be `null` or `undefined`. */ type Uncertain = T | null | undefined; /** Represents numeric string (`${number}`) */ type NumericString = `${number}`; /** Union of `number` and numeric string */ type Numeric = number | NumericString; /** Union of Basic Primitive Types (i.e. `string | number | boolean`) */ type BasicPrimitive = string | number | boolean; /** `null` or `undefined` */ type NullOrUndefined = null | undefined; /** Union of All Primitive Types (i.e. `string | number | boolean | symbol | bigint | null | undefined`) */ type Primitive = string | number | boolean | symbol | bigint | null | undefined; /** Union of Normal Primitive Types (i.e. `string | number | boolean | null | undefined`) */ type NormalPrimitive = string | number | boolean | null | undefined; /** A generic class constructor */ type Constructor = new (...args: any[]) => any; /** Generic function type */ type GenericFn = (...args: any[]) => any; /** Generic function type that returns `void` */ type VoidFn = (...args: any[]) => void; /** Asynchronous function type */ type AsyncFunction = (...args: any[]) => Promise; /** Advanced types to exclude from counting as object key */ type AdvancedTypes = Array | File | FileList | DateLike | Blob | Date | RegExp | WeakMap | WeakSet | Map | Set | Function | GenericFn | VoidFn | AsyncFunction | Promise | Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError | URIError | bigint | symbol; /** * * A readonly array of elements of type `T`. * * @remarks * - Shorthand for `ReadonlyArray`. Used to represent immutable lists. * * @example * type Numbers = List; // readonly number[] * const arr: Numbers = [1, 2, 3]; // ✅ OK * arr.push(4); // ❌ Error (readonly) */ type List = ReadonlyArray; //#endregion //#region node_modules/.pnpm/toolbox-x@2.6.20/node_modules/toolbox-x/dist/hash-y4HVojCw.d.mts //#region src/types/hash.d.ts /** UUID versions as number from `1-8` */ type $UUIDVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; /** UUID versions as string from `v1-v8` */ type UUIDVersion = `v${$UUIDVersion}`; /** General 5 parts UUID string type */ type $UUID = `${string}-${string}-${string}-${string}-${string}`; /** General 5 parts UUID string as {@link Branded} type */ type UUID = Branded<$UUID, V>; //#endregion //#region src/types.d.ts type ForcedAny = any; /** Type for IndexedDB getter function */ type IDBGetter = () => IDBDatabase; /** Type for reject function of a promise */ type RejectFn = (reason: unknown) => void; /** Resolves the actual column value type considering nullable and optional modifiers */ type ColumnValue = Col extends { [IsNullable]: true; } ? Col extends { [IsOptional]: true; } ? Uncertain : Nullable : Col extends { [IsOptional]: true; } ? Maybe : T; /** Validator function type for {@link Column.validate()} */ type ValidatorFn = (value: T) => Uncertain; /** Updater function type for {@link Column.onUpdate()} */ type UpdaterFn = (currentValue: T) => T; /** * * Extracts the parameters of the first overload of a function type `T`. * * @typeParam T - The function type to extract parameters from. * * @returns A tuple type representing the parameters of the first overload of `T`. * * @example * type Fn = { * (a: number, b: string): void; * (x: boolean): void; * }; * * type Params = FirstOverloadParams; // [a: number, b: string] */ type FirstOverloadParams = T extends { (a1: infer P1, ...args: infer P2): any; (...args: any[]): any; } ? [P1, ...P2] : T extends { (...args: infer P): any; (...args: any[]): any; } ? P : T extends ((...args: infer P) => any) ? P : never; /** * Determines if a selection object has any true values */ type HasTrueValues>> = { [K in keyof Selection]: Selection[K] extends true ? true : never; }[keyof Selection] extends never ? false : true; /** * Extracts only the selected fields from an object. * Used for SELECT clause to pick specific columns. * - If any value is true: returns only fields marked as true * - If all values are false: returns all fields EXCEPT those marked as false */ type SelectFields> = Record> = Prettify extends true ? { [K in keyof Selection as Selection[K] extends true ? K : never]: K extends keyof T ? T[K] : never; } : { [K in keyof T as K extends keyof Selection ? Selection[K] extends false ? never : K : K]: T[K]; }>; /** Type for string-boolean records or `null` used in select queries */ type BooleanRecord = Nullable>>; /** * Extracts the indexed result type from a select query * - If `Sel` is `null`: returns the original row type * - If `Sel` is a boolean record: returns the select fields type */ type IndexedResult = Sel extends null ? Row : Sel extends Partial> ? SelectFields : never; /** Callback function type for cursor-based queries */ type CursorCallback = (row: T, index: number) => void | Promise; /** Pagination options for cursor-based queries */ interface PageOptions { /** Cursor key returned from a previous page */ cursor?: IDBValidKey; /** Maximum number of records to return */ limit?: number; } /** Cursor-based pagination result */ interface PageResult>>> { /** Retrieved items for the current page */ items: Selection extends null ? T[] : SelectFields>[]; /** Cursor key for the next page, if more results are available */ nextCursor: Maybe; } /** Locality database configuration type */ interface LocalityConfig { /** Database name */ dbName: DB; /** Database schema version */ version?: V; /** Database schema */ schema: S; } /** Column definition type - preserves both Column generics */ type ColumnDefinition = Record>; /** Validated column definition with single PK constraint */ type ValidatedColumnDefinition = $ValidateSinglePK extends T ? T : never; /** Record of column definitions */ type ColumnRecord = Record; /** Schema definition from a {@link ColumnRecord column record} */ type Schema = { [K in keyof S]: Table>; }; /** Schema record type mapping table names to {@link Table} instances */ type SchemaRecord = { [K in Keys]: Table; }; /** Schema definition type */ type SchemaDefinition = Record>; /** Helper to reliably extract the generic type parameter from a Column directly from its type parameters. */ type ExtractColumnType = C extends Column ? T : never; /** Resolves column value type from column, considering nullable and optional fields */ type ResolveColumnType = T extends { [IsNullable]: true; } ? Nullable> : T extends { [IsOptional]: true; } ? Maybe> : ExtractColumnType; /** Extracts inferred row type from columns. */ type $InferRow = Prettify<{ [K in keyof T as K extends Exclude<$InferOptional, $InferDefault | $InferUUID | $InferTimestamp> ? K : never]?: ResolveColumnType; } & { [K in keyof T as K extends Exclude<$InferOptional, $InferDefault | $InferUUID | $InferTimestamp> ? never : K]: ResolveColumnType; }>; /** Finds the field name with autoIncrement set to true. */ type $InferAutoInc = { [K in keyof T]: T[K] extends { [IsAutoInc]: true; } ? K : never; }[keyof T]; /** Finds the field name with default value. */ type $InferDefault = { [K in keyof T]: T[K] extends { [DefaultValue]: any; } ? K : never; }[keyof T]; /** Finds the field name with primary key. */ type $InferPrimaryKey = { [K in keyof T]: T[K] extends { [IsPrimaryKey]: true; } ? K : never; }[keyof T]; /** Counts the number of primary keys in a column definition. */ type $CountPrimaryKeys = { [K in keyof T]: T[K] extends { [IsPrimaryKey]: true; } ? K : never; }[keyof T] extends (infer U) ? U extends never ? 0 : [U] extends [infer Single] ? Single extends keyof T ? 1 : never : 2 : never; /** Validates that a column definition has exactly one primary key. */ type $ValidateSinglePK = $CountPrimaryKeys extends 1 ? T : $CountPrimaryKeys extends 0 ? 'Error: Schema must have exactly one primary key' : 'Error: Schema can only have one primary key'; /** Finds the field name with partial key. */ type $InferOptional = { [K in keyof T]: T[K] extends { [IsOptional]: true; } ? K : never; }[keyof T]; /** Finds the field name with nullable key. */ type $InferNullable = { [K in keyof T]: T[K] extends { [IsNullable]: true; } ? K : never; }[keyof T]; /** Finds the field name with unique key. */ type $InferUnique = { [K in keyof T]: T[K] extends { [IsUnique]: true; } ? K : never; }[keyof T]; /** Finds the field name with index key. */ type $InferIndex = { [K in keyof T]: T[K] extends { [IsIndexed]: true; } ? K : never; }[keyof T]; /** Finds the field name with {@link UUID} type. */ type $InferUUID = { [K in keyof T]: T[K] extends Column ? C extends $UUID ? K : never : never; }[keyof T]; /** Finds the field name with {@link Timestamp} type. */ type $InferTimestamp = { [K in keyof T]: T[K] extends Column ? C extends Timestamp ? K : never : never; }[keyof T]; /** Timestamp string type in ISO 8601 format */ type Timestamp = `${number}-${number}-${number}T${number}:${number}:${number}.${number}${'Z' | `${'+' | '-'}${number}:${number}`}`; /** Sort direction type for ordering queries */ type SortDirection = 'asc' | 'desc'; /** Predicate function type for WHERE clauses in queries */ type WherePredicate = (row: T) => boolean; /** Creates a type for insert operations with auto-generated fields optional. */ type InferInsertType = Prettify, $InferAutoInc | $InferDefault | $InferTimestamp | $InferUUID | $InferNullable> & { [K in $InferNullable]?: K extends keyof $InferRow ? $InferRow[K] : never; } & { [K in $InferAutoInc | $InferDefault | $InferTimestamp | $InferUUID]?: K extends keyof $InferRow ? $InferRow[K] : never; }>; /** Creates a type for update operations with all fields optional except primary key. */ type InferUpdateType = Prettify, $InferPrimaryKey>>>; /** Callback function that gets the current row and returns values to be updated */ type UpdateCallback> = (row: Row) => U & Record>, never>; /** Creates a type for select operations. */ type InferSelectType = Prettify ? $InferRow : never) : never>; type PrimaryKeyType = InferSelectType[$InferPrimaryKey]; type IndexKeyType = InferSelectType[$InferIndex]; type UniqueKeyType = InferSelectType[$InferUnique]; /** Column type strings used in {@link Column} definitions */ type TypeName = LooseLiteral<'int' | 'float' | 'number' | 'numeric' | 'bigint' | 'text' | 'string' | `char(${number})` | `varchar(${number})` | 'uuid' | 'timestamp' | 'email' | 'url' | 'bool' | 'boolean' | 'date' | 'object' | 'array' | 'list' | 'tuple' | 'set' | 'map' | 'custom'>; /** Email string type in basic format */ type Email = `${string}@${string}.${string}`; /** URL string type in basic format */ type URLString = `${string}://${string}`; /** Index configuration type for `IndexedDB` */ interface IndexConfig { /** Index name (typically the field name) */ name: string; /** Key path for the index */ keyPath: string; /** Whether the index enforces unique values */ unique?: boolean; } /** Store configuration type for `IndexedDB` */ interface StoreConfig { /** Store (table) name */ name: string; /** Primary key path(s) */ keyPath?: string; /** Whether the primary key is auto-incrementing */ autoIncrement?: boolean; /** Array of index configurations for this store */ indexes?: IndexConfig[]; } /** Export options for database `export` method */ interface ExportOptions { /** Optional array of table names to export (exports all if not specified) */ tables?: T[]; /** Optional custom filename (default: `{dbName}-export-{timestamp}.json`) */ filename?: string; /** Optional flag to enable pretty-printed JSON (default: `true`) */ pretty?: boolean; /** Optional flag to include export metadata (default: `true`) */ includeMetadata?: boolean; } type ExportObjectOptions = Omit, 'filename' | 'pretty'>; /** Import mode for `import` `'replace'`, `'merge'`, or `'upsert'` */ type ImportMode = 'replace' | 'merge' | 'upsert'; /** Import options for database `import` method */ interface ImportOptions { /** Optional array of table names to import (imports all tables (store) if not specified) */ tables?: T[]; /** Import mode: `'replace'`, `'merge'`, or `'upsert'` (default: `'merge'`) */ mode?: ImportMode; } /** Exported table data structure */ type ExportedTableData = Prettify<{ [K in T]: InferSelectType[]; }>; /** Metadata about the export */ interface ExportMetaData { /** Database name */ dbName: string; /** Database version */ version: number; /** Export creation time */ exportedAt: Timestamp; /** List of exported table names */ tables: T[]; } /** Exported database data structure */ interface ExportData { /** Optional metadata about the export */ metadata?: ExportMetaData; /** Actual exported data, mapping table names to arrays of records */ data: ExportedTableData; } /** Transaction context type providing methods for database operations within a transaction */ interface TransactionContext { /** Inserts a new record into the specified table */ insert: , Inserted extends Raw | Raw[], Data extends InferSelectType, Return extends Inserted extends Array ? Data[] : Data>(table: T) => InsertQuery; /** Updates an existing record in the specified table */ update: >(table: T) => UpdateQuery; /** Deletes a record from the specified table */ delete: >(table: T) => DeleteQuery; /** Retrieves a record by primary key from the specified table */ from: >(table: T) => SelectQuery; } /** Transaction callback function type */ type TransactionCallback = (ctx: TransactionContext) => Promise; /** - Extract only number, string, undefined and null keys from an object, including nested dot-notation keys. */ type NumericDotKey = T extends AdvancedTypes ? never : T extends GenericObject ? { [K in keyof T & string]: T[K] extends Function ? never : T[K] extends Numeric | NullOrUndefined ? K : T[K] extends GenericObject ? `${K}.${NumericDotKey}` : never; }[keyof T & string] : never; /** Resolves the actual value type of a property in an object based on a top level key. */ type ResolveValue = Prettify<{ [K in U]: T[K]; }[U]>; /** Actions on delete or update for reference columns (foreign keys) */ type RefAction = 'noAction' | 'cascade' | 'restrict' | 'setNull/Undefined'; /** Options for reference columns (foreign keys) */ interface RefOptions { /** Action to take on delete of the referenced row */ onDelete?: RefAction; /** Action to take on update of the referenced row */ onUpdate?: RefAction; } /** Runtime shape for ref metadata attached to a Column instance */ interface RefMetadata { /** Reference path in the format 'table.column' */ refPath: RefPath; /** * Optional actions on delete or update * * @default "noAction" */ options?: RefOptions; } /** Type to extract the reference path from a Column instance */ type ExtractRef = C extends { [RefMeta]: RefMetadata; } ? R : never; /** * Ensures that a reference path is valid within a given schema. * - If the reference path is valid, returns `true`. * - If the reference path is invalid, returns a descriptive error tuple. * * @typeParam S - The schema to validate against. * @typeParam R - The reference path in the format `'TableName.ColumnName'`. */ type EnsureRefIsValid = R extends never ? true : R extends `${infer T}.${infer K}` ? T extends keyof S ? K extends keyof S[T] ? true : ['Invalid column', R, T] : ['Invalid table', R] : ['Invalid format', R]; /** * Validates all references in a schema. * - If all references are valid, returns the original schema `S`. * - If any reference is invalid, returns a descriptive error object. * * @typeParam S - The schema to validate. */ type RefValidationMap = { [Table in keyof S]: { [Col in keyof S[Table]]: EnsureRefIsValid>; }; }; /** * Validates that all references in a schema are valid. * - If all references are valid, returns the original schema `S`. * - If any reference is invalid, returns a descriptive error object. * * @typeParam S - The schema to validate. */ type ValidateRefs = RefValidationMap extends { [Table in keyof S]: { [Col in keyof S[Table]]: true; }; } ? S : { Error: `Invalid reference(s) found in table ${Extract}`; }; /** Type for a function that formats bytes into a specific type */ type FormatByte = (bytes: number) => T; /** Interface representing browser's storage usage information, with optional formatting. */ interface StorageUsage { /** Total storage quota available */ quota: Format; /** Total storage used */ used: Format; } //#endregion //#region src/core.d.ts /** @class Represents a column definition. */ declare class Column { [ColumnType]: TName; [IsPrimaryKey]?: boolean; [IsAutoInc]?: boolean; [IsOptional]?: boolean; [IsNullable]?: boolean; [IsIndexed]?: boolean; [IsUnique]?: boolean; [DefaultValue]?: T; [ValidateFn]?: ValidatorFn; [OnUpdate]?: UpdaterFn; [RefMeta]?: RefMetadata; constructor(type: TName); /** * @instance Marks column as primary key * * @returns The {@link PKColumn column instance} marked as primary key * */ pk(): TName extends "int" | "integer" | "float" | "number" ? this & PKColumn & { [IsPrimaryKey]: true; } : this & Omit, "auto"> & { [IsPrimaryKey]: true; }; /** * @instance Marks column as unique * * @remarks Also marks the column as indexed */ unique(): this & { [IsIndexed]: true; [IsUnique]: true; }; /** @instance Marks column as indexed */ index(): this & { [IsIndexed]: true; }; /** * @instance Sets default value for the column * @param value Default value for the column * @returns The column instance with the default value attached * * @remarks * - The default value is used when a new record is inserted and no value is provided for the column. * - This allows for automatic population of fields with predefined values. * - If multiple default values are chained, only the last one is used. */ default(value: T): this & { [DefaultValue]: T; }; /** * @instance Sets default value for the column using a callback function * @param callback Callback function that returns the default value for the column * @returns The column instance with the default value attached * * @remarks * - The callback function is called when a new record is inserted and no value is provided for the column. * - This allows for dynamic default values based on the current context or other factors. * - If multiple default values are chained, only the last one is used. */ default(callback: () => T): this & { [DefaultValue]: T; }; /** @instance Marks column as optional (`undefined`) */ optional(): this & { [IsOptional]: true; }; /** @instance Marks column as nullable (`null`) */ nullable(): this & { [IsNullable]: true; }; /** * @instance Sets a custom validation function for the column * * @param validator - Custom validation function that receives the value and returns `null`/`undefined` if valid, or an error message `string` if invalid * * @returns The column instance with the validation function attached * * @remarks * - Custom validation is not applied to auto-generated values (e.g. auto-increment, UUID, timestamp). But default values are validated if {@link default()} is used. * - If multiple validators are chained, only the last one is used. * - Built-in type validation still applies to all other columns without custom validators. * - If the column is optional, the validator is only called when a value is provided (not `undefined`). * * @example * // Email validation * email: column.text().validate((val) => { * return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val) ? null : 'Invalid email format'; * }) * * // Range validation * age: column.int().validate((val) => { * return val >= 0 && val <= 120 ? null : 'Age must be between 0 and 120'; * }) */ validate(this: This, validator: ValidatorFn>): This & { [ValidateFn]: ValidatorFn>; }; /** * @instance Sets an updater function that modifies the column value on updates * @param updater - Updater function that receives the current value and returns the new value * @returns The column instance with the updater function attached * * @remarks * - The updater function is called automatically during update operations. * - **Important**: It overrides any value provided during updates. * - It receives the current value of the column and should return the updated value. * - This is useful for fields like `"updatedAt"` timestamps that need to be refreshed on each update. * - If multiple updaters are chained, only the last one is used. * * @example * // Automatically update timestamp on record modification * updatedAt: column.timestamp().onUpdate(() => getTimestamp()); * * // Increment a version number on each update * version: column.int().default(1).onUpdate((current) => (current ?? 0) + 1); * * // Append to a log array on each update * log: column.array().default([]).onUpdate((current) => [...(current ?? []), getTimestamp()]); * * // Note: Ensure the column is not marked as primary key or auto-increment when using onUpdate */ onUpdate(this: This, updater: UpdaterFn>): This & { [OnUpdate]: UpdaterFn>; }; /** * @instance Sets a reference to another table's column, enabling foreign key relationships * @param refPath - The reference path in the format `"TableName.ColumnName"`. * @param options - Optional configuration for foreign key actions on delete or update * * @remarks * - The `refPath` should be in `"TableName.ColumnName"` format (e.g., `"users.id"` to reference the `id` of the `users` table). * - The `options` parameter allows specifying actions on delete or update (e.g., cascade, restrict). * - This method attaches metadata to the column instance for later use in schema generation or validation. * * @returns The column instance with the reference metadata attached * * @example * // Reference to another table's column with cascade on delete * userId: column.int().ref('users.id', { onDelete: 'cascade' }); * * // Reference with restrict on update * orderId: column.int().ref('orders.id', { onUpdate: 'restrict' }); */ ref(refPath: R, options?: RefOptions): This & { [RefMeta]: RefMetadata; }; } /** @class Extends {@link Column} and represents a primary key column. */ declare class PKColumn extends Column { constructor(type: TName, column: Column); /** @instance Enables auto increment - only available for `number` columns */ auto(): T extends number ? this & { [IsAutoInc]: true; } : Omit; } /** @class Represents a table definition. */ declare class Table { readonly name: string; readonly columns: C; constructor(name: string, columns: C); } //#endregion //#region src/query/base.d.ts declare class BaseQuery { protected readonly $table: string; protected readonly $dbGetter: IDBGetter; protected readonly $readyPromise: Promise; protected readonly $columns?: ColumnDefinition; protected readonly $schema?: SchemaDefinition; protected $whereIndexName?: string; protected $whereCondition?: WherePredicate; protected $whereIndexQuery?: IDBKeyRange | IDBValidKey; protected $trx?: IDBTransaction; constructor(tableName: string, dbGetter: IDBGetter, readyPromise: Promise, transaction?: IDBTransaction, schema?: SchemaDefinition, columns?: ColumnDefinition); /** @internal Build indexed store (primary key or index) for where queries */ protected $buildIndexedStore(store: IDBObjectStore, reject: RejectFn): IDBObjectStore | IDBIndex | null; /** * @instance Filter rows by predicate function * * @remarks * - This overload allows you to filter rows based on a predicate function that receives each row * and returns a boolean indicating whether the row should be included in the result set. * - It is less efficient than filtering by index, as it requires iterating over all rows in the store. * - Use this overload when you need to filter rows based on complex conditions that cannot be expressed using an index. * * @param predicate Filtering function that receives each row and returns a boolean */ where(predicate: WherePredicate): this; /** * @instance Filter rows by index name and query value * * @remarks * - This overload allows you to filter rows based on a specific index and a query value. * - The index name should correspond to an existing index in the table's schema, and the query * can be either a specific key value or an IDBKeyRange for more complex queries. * - It is much more efficient to use this overload than the predicate function overload, * as it leverages IndexedDB's indexing capabilities. * * @param indexName Index name to query * @param query Key value or {@link IDBKeyRange} to search for */ where | $InferIndex>(indexName: IdxKey, query: IDBKeyRange | Row[IdxKey]): this; } //#endregion //#region src/query/delete.d.ts /** @class Delete query builder. */ declare class DeleteQuery extends BaseQuery { #private; constructor(tableName: string, dbGetter: IDBGetter, readyPromise: Promise, primaryKey: Key, schema?: SchemaDefinition, transaction?: IDBTransaction); /** * @instance Executes the delete query * @returns Number of records deleted */ run(): Promise; } //#endregion //#region src/query/insert.d.ts /** @class Insert query builder. */ declare class InsertQuery ? Data[] : Data> { #private; [IsArray]: boolean; constructor(tableName: string, dbGetter: IDBGetter, readyPromise: Promise, columns?: ColumnDefinition, keyPath?: string, schema?: SchemaDefinition, transaction?: IDBTransaction); /** * @instance Sets the data to be inserted * @param data Data object or array of data objects to insert */ values(data: T): InsertQuery ? Data[] : Data>; /** * @instance Executes the insert query * @returns Inserted record(s) */ run(): Promise; } //#endregion //#region src/query/select.d.ts /** @class Select query builder. */ declare class SelectQuery extends BaseQuery { #private; [Selected]?: Sel; constructor(tableName: string, dbGetter: IDBGetter, readyPromise: Promise, transaction?: IDBTransaction); /** * @instance Select or exclude specific columns * @param cols Columns to select or exclude */ select>>(cols: Selection): SelectQuery; /** * @instance Order results by specified key and direction * @param key Key to order by * @param dir Direction: 'asc' | 'desc' (default: 'asc') * * @remarks * - This method performs in-memory sorting. * - For optimized sorting using `IndexedDB` indexes, use {@link sortByIndex} instead. */ orderBy>(key: Key, dir?: SortDirection): this; /** * @instance Order results by index using optimized `IndexedDB` cursor * @param indexName Name of the index to sort by * @param dir Direction: 'asc' | 'desc' (default: 'asc') * * @remarks * - This method uses `IndexedDB` indexes for sorting, which is more efficient for large datasets. * - Ensure that the specified index exists on the table. * - For in-memory sorting, use {@link orderBy} instead. */ sortByIndex | $InferPrimaryKey>(indexName: IdxKey, dir?: SortDirection): this; /** * @instance Limit number of results * @param count Maximum number of results to return */ limit(count: number): this; /** Fetch all matching records */ findAll(this: SelectQuery): Promise; /** Fetch all matching records with selected fields */ findAll>>(this: SelectQuery): Promise[]>; /** Fetch records with cursor-based pagination */ page(this: SelectQuery, options?: PageOptions): Promise>; /** Fetch records with cursor-based pagination and selected fields */ page>>(this: SelectQuery, options?: PageOptions): Promise>; /** Stream records with a cursor */ stream(this: SelectQuery, callback: CursorCallback): Promise; /** Stream records with a cursor and selected fields */ stream>>(this: SelectQuery, callback: CursorCallback>): Promise; /** Fetch first matching record */ findFirst(this: SelectQuery): Promise>; /** Fetch first matching record with selected fields */ findFirst>>(this: SelectQuery): Promise>>; /** * @instance Find record by primary key (optimized `IndexedDB` get) * @param key Primary key value * * @remarks * - This method uses the `IndexedDB` primary key for efficient querying. * - Ensure that the specified key exists on the table. * - To find by index, use {@link findByIndex} instead. */ findByPk(key: $InferPrimaryKey extends keyof Row ? Row[$InferPrimaryKey] : Row[keyof Row]): Promise>>; /** * @instance Find records by index (optimized `IndexedDB` index query) * @param indexName Name of the index to query * @param query Key value to search for * * @remarks * - This method uses `IndexedDB` indexes for efficient querying. * - Ensure that the specified index exists on the table. * - To find by primary key, use {@link findByPk} instead. */ findByIndex & keyof Row & string>(indexName: IdxKey, query: Row[IdxKey] | IDBKeyRange): Promise[]>; /** @instance Count matching records */ count(): Promise; /** * @instance Checks if the query result set contains at least one record. * @returns A promise that resolves to `true` if the query result set contains at least one record, `false` otherwise. */ exists(): Promise; /** * @instance Computes the sum of a numeric column. * @param column Column to compute sum of. Supports dot-notation for nested fields. * @param roundTo Number of decimal places to round to. @default 2 * * @returns A promise that resolves to the sum of the specified column. * * @remarks * - Operates on raw filtered rows (skips sort, limit, and projection for efficiency). * - Independent of the {@link select()} method's column filtering. */ sum(column: NumericDotKey, roundTo?: number): Promise; /** * @instance Computes the average of a numeric column. * @param column Column to compute average of. Supports dot-notation for nested fields. * @param roundTo Number of decimal places to round to. @default 2 * * @returns A promise that resolves to the average of the specified column. * * @remarks * - Operates on raw filtered rows (skips sort, limit, and projection for efficiency). * - Independent of the {@link select()} method's column filtering. */ avg(column: NumericDotKey, roundTo?: number): Promise; /** * @instance Gets distinct values of a column. * @param column Column to get distinct values of. * * @returns A promise that resolves to an array of distinct values of the specified column. * * @remarks * - Operates on raw filtered rows (skips sort, limit, and projection for efficiency). * - Independent of the {@link select()} method's column filtering. */ distinct(column: Col): Promise[]>; /** * @instance Finds the minimum value of a numeric column. * @param column Column to find minimum of. Supports dot-notation for nested fields. * * @returns A promise that resolves to the minimum value, or `NaN` if the result set is empty. * * @remarks * - Uses **O(1) `IndexedDB` cursor** when the column is indexed/primary key and no `where()` filters are active. * - Falls back to scanning all filtered rows for non-indexed or nested columns. * - Independent of the {@link select()} method's column filtering. */ min(column: NumericDotKey): Promise; /** * @instance Finds the maximum value of a numeric column. * @param column Column to find maximum of. Supports dot-notation for nested fields. * * @returns A promise that resolves to the maximum value, or `NaN` if the result set is empty. * * @remarks * - Uses **O(1) `IndexedDB` cursor** when the column is indexed/primary key and no `where()` filters are active. * - Falls back to scanning all filtered rows for non-indexed or nested columns. * - Independent of the {@link select()} method's column filtering. */ max(column: NumericDotKey): Promise; } //#endregion //#region src/query/update.d.ts /** @class Update query builder. */ declare class UpdateQuery extends BaseQuery { #private; constructor(tableName: string, dbGetter: IDBGetter, readyPromise: Promise, columns?: ColumnDefinition, keyPath?: string, schema?: SchemaDefinition, transaction?: IDBTransaction); /** * @instance Sets the data to be updated * @param values Values to update */ set(values: InferUpdateType): this; /** * @instance Sets the computed data to be updated * @param cb Callback function that receives the current row and returns the values to update */ set>(cb: UpdateCallback): this; /** * @instance Executes the update query * @returns Number of records updated */ run(): Promise; } //#endregion //#region src/client.d.ts /** * @class `Locality` class for `IndexedDB` interactions. * * @example * import { column, defineSchema, Locality } from 'locality-idb'; * * const schema = defineSchema({ * users: { * id: column.int().pk().auto(), * name: column.text(), * email: column.text().unique(), * }, * }); * * const db = new Locality({ * dbName: 'my-database', * version: 1, * schema, * }); * * // Optional * await db.ready(); * * // Insert a new user * const inserted = await db.insert('users').values({ name: 'Alice', email: 'alice@wonderland.mad' }).run(); * * // Get all users * const allUsers = await db.from('users').findAll(); * * // Select users with a specific condition * const allAlices = await db.from('users').where((user) => user.email.includes('alice')).findAll(); * * // Update a user * const updated = await db.update('users').set({ name: 'Alice Liddell' }).where((user) => user.id === 1).run(); * * // Delete a user * const deleted = await db.delete('users').where((user) => user.id === 1).run(); */ declare class Locality { #private; constructor(config: LocalityConfig); /** @instance Get the current database name. */ get dbName(): DBName; /** @instance Get the current database version directly from `IndexedDB`. Falls back to instance or config version. */ get version(): LooseLiteral; /** @instance Get all table (store) names in the current database. */ get tableList(): LooseLiteral[]; /** @instance Get the list of existing `IndexedDB` databases for the current origin. */ get dbList(): Promise; /** @instance Waits for database initialization to complete. */ ready(): Promise; /** * @instance Select records from a table. * @param table Table name to select data from. * @returns Select query builder for the table. */ from>(table: T): SelectQuery; /** * @instance Insert records into a table. * @param table Table name to insert data into. * @returns Insert query builder for the table. */ insert, Inserted extends Raw | Raw[], Data extends InferSelectType, Return extends Inserted extends Array ? Data[] : Data>(table: T): InsertQuery; /** * @instance Update records in a table. * @param table Table name to update data in. * @returns Update query builder for the table. */ update>(table: T): UpdateQuery; /** * @instance Delete records from a table. * @param table Table name to delete data from. * @returns Delete query builder for the table. */ delete>(table: T): DeleteQuery; /** * @instance Clears all records from a specific store (table). * @param table Name of the table (store) to clear. */ clearTable(table: T): Promise; /** @instance Closes and deletes the entire database. */ deleteDB(): Promise; /** @instance Closes the current database connection. */ close(): void; /** @instance Gets the underlying `IDBDatabase` instance. */ getDBInstance(): Promise; /** * @instance Seed data into a specific table. * * @remarks * - This is a convenience method that inserts multiple records into the specified table. * - It does not clear existing data; it only adds new records. * * @param table Name of the table to seed data into. * @param data Array of data objects to be inserted. * @returns A promise that resolves to an array of inserted data. * * @example * const db = new Locality({ * dbName: 'my-database', * version: 1, * schema: defineSchema({ * users: { * id: column.int().pk().auto(), * name: column.text(), * email: column.varchar(255).unique(), * }, * }), * }); * * await db.seed('users', [ * { name: 'Alice', email: 'alice@wonderland.mad', }, * { name: 'Bob', email: 'bob@top.com', }, * ]); * * const allUsers = await db.from('users').findAll(); * * console.log(allUsers); */ seed, Data extends InferSelectType>(table: T, data: Raw[]): Promise; /** * @instance Execute multiple operations across multiple tables in a single atomic transaction. * * @remarks * - All operations succeed or all fail (atomicity guaranteed by IndexedDB). * - If any operation fails, the entire transaction is rolled back automatically. * - Useful for maintaining data consistency across related tables. * * @param tables Array of table names to include in the transaction * @param callback Async function that receives a transaction context and performs operations * @returns A promise that resolves when the transaction completes successfully * * @throws Error if the transaction is aborted due to constraint violations or other errors * * @example * const db = new Locality({ * dbName: 'my-database', * version: 1, * schema: defineSchema({ * users: { * id: column.int().pk().auto(), * name: column.text(), * }, * posts: { * id: column.int().pk().auto(), * userId: column.int(), * title: column.text(), * }, * }), * }); * * // Create a user and their first post atomically * await db.transaction(['users', 'posts'], async (ctx) => { * const newUser = await ctx.insert('users').values({ name: 'John Doe' }).run(); * await ctx.insert('posts').values({ userId: newUser.id, title: 'Hello World' }).run(); * }); */ transaction(tables: Tables, callback: TransactionCallback): Promise; /** * @instance Export database data as JSON file and trigger browser download. * * @remarks * - Exports all tables by default, or only specified tables if provided. * - Generates a JSON file with schema metadata and table data. * - Automatically triggers a download in the browser. * * @param options Export configuration options * @returns A promise that resolves when the export completes * * @example * const db = new Locality({ * dbName: 'my-database', * version: 1, * schema: defineSchema({ * users: { * id: column.int().pk().auto(), * name: column.text(), * }, * posts: { * id: column.int().pk().auto(), * title: column.text(), * }, * }), * }); * * // Export all tables pretty-printed with default filename * await db.$export(); * * // Export specific tables pretty-printed with custom filename * await db.$export({ tables: ['users'], filename: 'users-backup.json' }); * * // Export with raw JSON * await db.$export({ pretty: false }); */ $export(options?: ExportOptions): Promise; /** * @instance Export database data as an object without triggering a download. * * @remarks * - Exports all tables by default, or only specified tables if provided. * - Returns a JSON-serializable object with schema metadata and table data. */ exportToObject(options?: ExportObjectOptions): Promise>; /** * @instance Import data into the database. * * @param data The data to import, either as an {@link ExportData} object. * @param options Optional import configuration, including mode and specific tables to import. * * @remarks * - Accepts either an {@link ExportData} object or raw table data {@link ExportedTableData}. * - Supports merge, replace, and upsert modes. */ $import(data: ExportData, options?: ImportOptions): Promise; /** * @instance Import data into the database. * * @param data The data to import, either as raw table data {@link ExportedTableData}. * @param options Optional import configuration, including mode and specific tables to import. * * @remarks * - Accepts either raw table data {@link ExportedTableData} or an {@link ExportData} object. * - Supports merge, replace, and upsert modes. */ $import(data: ExportedTableData, options?: ImportOptions): Promise; /** @instance Clear all records from all tables. */ clearAll(): Promise; /** * @instance Drop a table (object store) by name. * * @param table The name of the table to drop. * * @remarks * - This increments the database version internally. * - You should re-instantiate `Locality` with an updated schema after dropping. */ dropTable(table: T): Promise; /** @static Get the list of existing `IndexedDB` databases for the current origin. */ static getDatabaseList(): Promise; /** @static Delete an `IndexedDB` database by name. */ static deleteDatabase(name: string): Promise; } //#endregion //#region src/factory.d.ts /** * * Opens an `IndexedDB` database instance with the specified stores. * @param name Database name * @param stores Array of store configurations * @param version Database version (default is `undefined`) * @returns Promise that resolves to the opened {@link IDBDatabase} instance. */ declare function openDBWithStores(name: string, stores: StoreConfig[], version?: number): Promise; //#endregion //#region src/schema.d.ts /** * * Defines a database schema from a given schema definition. * * @param schema An object defining the schema, where each key is a table name and each value is a record of {@link column} definitions. * @returns An object mapping each table name to its corresponding {@link Table} instance. * * @example * const schema = defineSchema({ * users: { * id: column.int().pk().auto(), * name: column.varchar(255).unique(), * createdAt: column.timestamp(), * isActive: column.bool().default(true), * }, * posts: { * id: column.int().pk().auto(), * userId: column.int().index(), * title: column.varchar(255), * content: column.text(), * createdAt: column.timestamp(), * }, * }); * * // Infer types: * * type User = InferSelectType; * type InsertUser = InferInsertType; * type UpdateUser = InferUpdateType; * * type Post = InferSelectType; * type InsertPost = InferInsertType; * type UpdatePost = InferUpdateType; */ declare function defineSchema(schema: ValidateRefs): Schema; /** * @deprecated Use the {@link defineSchema} function instead to define the entire schema at once. * * @description Factory function to create a new {@link Table} instance. * * @param name The name of the table. * @param columns An object defining the columns of the table using {@link column} definitions. * @returns A new {@link Table} instance representing the table schema. * * @remarks It has been deprecated in favor of {@link defineSchema} for defining the entire schema at once, * which provides better type inference and validation. * * @example * const userTable = table('users', { * id: column.int().pk().auto(), * name: column.varchar(255).unique(), * createdAt: column.timestamp(), * isActive: column.bool().default(true), * }); */ declare function table(name: string, columns: Col): Table; /** * * Column factory with various column types. * * @remarks * - `char` and `varchar` accept an optional length parameter. * - `object`, `array`, `list`, `tuple`, `set`, and `map` are generic and can be typed. * - `custom` can be used for any custom data type. * - Each column can be further configured using methods like `pk()`, `unique()`, `auto()`, `index()`, `default()`, and `optional()`. * - Example usage is provided below: * * @example * const idColumn = column.int().pk().auto(); * const nameColumn = column.varchar(255).unique(); * const createdAtColumn = column.timestamp(); * const isActiveColumn = column.bool().default(true); * * // Define a table schema * const userTable = table('users', { * id: idColumn, * name: nameColumn, * createdAt: createdAtColumn, * isActive: isActiveColumn, * }); * * // Define a database schema * const schema = defineSchema({ * users: { * id: idColumn, * name: nameColumn, * createdAt: createdAtColumn, * isActive: isActiveColumn, * }, * }); */ declare const column: { /** * Creates an integer column. * @returns A new {@link Column} instance for integers. * @remarks * - Accepts an optional generic type parameter to create branded or restricted integer types. * - The type parameter must extend `number` and defaults to `number` if not specified. * - Useful for creating type-safe identifiers, status codes, or domain-specific integer types. * * @example * // Basic usage * const age = column.int(); * * // With branded type for type safety * type UserId = Branded; * const userId = column.int(); */ int: () => Column, "int">; /** * Creates a float column. * @returns A new {@link Column} instance for floating-point numbers. * @remarks * - Accepts an optional generic type parameter to create branded or restricted floating-point types. * - The type parameter must extend `number` and defaults to `number` if not specified. * - Ideal for monetary values, measurements, or any decimal number requiring type safety. * * @example * // Basic usage * const price = column.float(); * * // With branded type for currency safety * type USD = Branded; * const amount = column.float(); */ float: () => Column, "float">; /** * Creates a number column. * @returns A new {@link Column} instance for numbers. * @remarks * - Accepts both integers and floating-point numbers. * - Accepts an optional generic type parameter to create branded or restricted numeric types. * - The type parameter must extend `number` and defaults to `number` if not specified. * - Use this when you need flexibility between integer and decimal values. * * @example * // Basic usage * const score = column.number(); * * // With branded type * type Percentage = Branded; * const completion = column.number(); */ number: () => Column, "number">; /** * Creates a numeric (number or numeric string) column. * @returns A new {@link Column} instance for numeric. * @remarks * - Accepts both `number` values and numeric strings (e.g., `"123"`, `"45.67"`). * - Accepts an optional generic type parameter that must extend `Numeric` (union of `number | \`${number}\``). * - Defaults to `Numeric` if not specified. * - Useful for data that may come from external sources in string format but represents numbers. * * @example * // Basic usage - accepts 123 or "123" * const amount = column.numeric(); * * // With restricted branded type * type SerialNumber = Branded; * const serial = column.numeric(); */ numeric: () => Column, "numeric">; /** * Creates a bigint column. * @returns A new {@link Column} instance for bigints. * @remarks * - Used for storing integers beyond JavaScript's safe integer limit (`Number.MAX_SAFE_INTEGER`). * - Accepts an optional generic type parameter that must extend `Numeric`. * - Defaults to `Numeric` if not specified. * - Essential for handling very large integer values such as database IDs, timestamps in milliseconds, or financial calculations. * * @example * // Basic usage * const largeId = column.bigint(); * * // With branded type for Twitter-style snowflake IDs * type SnowflakeId = Branded; * const snowflake = column.bigint(); */ bigint: () => Column, "bigint">; /** * Creates a text column. * @returns A new {@link Column} instance for text. * @remarks * - Designed for storing large or unlimited-length text content. * - Accepts an optional generic type parameter to create branded or literal string types. * - The type parameter must extend `string` and defaults to `string` if not specified. * - Ideal for descriptions, content bodies, or any variable-length text data. * * @example * // Basic usage * const description = column.text(); * * // With literal union for restricted values * type Status = 'draft' | 'published' | 'archived'; * const status = column.text(); * * // With branded type * type HTML = Branded; * const content = column.text(); */ text: () => Column, "text">; /** * Creates a string column. * @returns A new {@link Column} instance for strings. * @remarks * - General-purpose column type for string data of any length. * - Accepts an optional generic type parameter to create branded or literal string types. * - The type parameter must extend `string` and defaults to `string` if not specified. * - Functionally similar to `text()` but semantically used for general string fields. * * @example * // Basic usage * const name = column.string(); * * // With literal union for enum-like behavior * type Role = 'admin' | 'user' | 'guest'; * const role = column.string(); * * // With branded type for URLs * type URL = Branded; * const website = column.string(); */ string: () => Column, "string">; /** * Creates a char column with optional length. * @param length Optional length of the char column. Defaults to `8`. * @returns A new {@link Column} instance for char. * @remarks * - Designed for fixed-length string data where all values have the same character count. * - Accepts an optional generic type parameter to create branded or literal string types. * - The type parameter must extend `string` and defaults to `string` if not specified. * - Runtime validation enforces exact length matching. * - Common use cases include country codes, state abbreviations, or fixed-format identifiers. * * @example * // Basic usage with default length (8) * const code = column.char(); * * // With specific length for country codes * const country = column.char(2); // "US", "UK", etc. * * // With branded type * type StateCode = Branded; * const state = column.char(2); */ char: (length?: number) => Column, `char(${number})`>; /** * Creates a varchar column with optional length. * @param length Optional length of the varchar column. Defaults to `32`. * @returns A new {@link Column} instance for varchar. * @remarks * - Designed for variable-length string data with a maximum character limit. * - Accepts an optional generic type parameter to create branded or literal string types. * - The type parameter must extend `string` and defaults to `string` if not specified. * - Runtime validation enforces maximum length constraint. * - Ideal for usernames, email addresses, titles, or any bounded-length text fields. * * @example * // Basic usage with default length (32) * const username = column.varchar(); * * // With specific length for email addresses * const email = column.varchar(255); * * // With branded type for URLs * type URL = Branded; * const website = column.varchar(500); */ varchar: (length?: number) => Column, `varchar(${number})`>; /** * Creates a UUID column. * @returns A new {@link Column} instance for UUIDs. * @remarks * - This column type is used for storing UUID strings. * - UUIDs are typically used as unique identifiers. * - Automatically generates UUID v4 values when no value is provided. */ uuid: () => Column<`${string}-${string}-${string}-${string}-${string}`, "uuid">; /** * Creates a timestamp column. * @returns A new {@link Column} instance for timestamps. * @remarks * - This column type is used for storing date and time information in ISO 8601 format. * - Automatically generates the current timestamp when no value is provided. */ timestamp: () => Column<`${number}-${number}-${number}T${number}:${number}:${number}.${number}Z` | `${number}-${number}-${number}T${number}:${number}:${number}.${number}+${number}:${number}` | `${number}-${number}-${number}T${number}:${number}:${number}.${number}-${number}:${number}`, "timestamp">; /** * Creates an email column. * @returns A new {@link Column} instance for emails. * @remarks * - This column type is used for storing email address strings. * - Includes built-in validation to ensure the value is a valid email format. */ email: () => Column<`${string}@${string}.${string}`, "email">; /** * Creates a URL column. * @returns A new {@link Column} instance for URLs. * @remarks * - This column type is used for storing URL strings. * - Includes built-in validation to ensure the value is a valid URL format. */ url: () => Column<`${string}://${string}`, "url">; /** * Creates a boolean column. Same as {@link column.boolean boolean}. * @returns A new {@link Column} instance for booleans. * @remarks * - Stores true/false binary values. * - Accepts an optional generic type parameter to create branded boolean types. * - The type parameter must extend `boolean` and defaults to `boolean` if not specified. * - Commonly used for flags, toggles, or binary state indicators. * * @example * // Basic usage * const isActive = column.bool(); * * // With branded type for domain-specific boolean * type EmailVerified = Branded; * const verified = column.bool(); */ bool: () => Column, "bool">; /** * Creates a boolean column. Same as {@link column.bool bool}. * @returns A new {@link Column} instance for booleans. * @remarks * - Stores true/false binary values. * - Accepts an optional generic type parameter to create branded boolean types. * - The type parameter must extend `boolean` and defaults to `boolean` if not specified. * - Functionally identical to `bool()`, provided as an alias for readability preference. * * @example * // Basic usage * const isPremium = column.boolean(); * * // With branded type * type TwoFactorEnabled = Branded; * const twoFactor = column.boolean(); */ boolean: () => Column, "boolean">; /** * Creates a date column. * @returns A new {@link Column} instance for dates. * @remarks This column type is used for storing date values. */ date: () => Column; /** * Creates an object column. * @returns A new {@link Column} instance for objects. * @remarks * - Stores structured data as JavaScript objects with string keys. * - Requires a generic type parameter defining the object's shape for type safety. * - The type parameter must extend `GenericObject` (Record). * - IndexedDB natively supports object storage without serialization overhead. * - Ideal for storing complex nested data structures, JSON-like data, or configuration objects. * * @example * // With typed interface * interface UserProfile { * avatar: string; * bio: string; * socials: { twitter?: string; github?: string }; * } * const profile = column.object(); * * // With inline type * const settings = column.object<{ theme: 'light' | 'dark'; notifications: boolean }>(); */ object: () => Column, "object">; /** * Creates an array column. * @returns A new {@link Column} instance for arrays. * @remarks * - Stores ordered collections of elements as mutable JavaScript arrays. * - Accepts an optional generic type parameter defining the element type. * - Defaults to `any` if not specified, but explicit typing is recommended for type safety. * - IndexedDB natively supports array storage. * - Suitable for lists, collections, or any ordered sequence of values. * * @example * // Basic usage with explicit type * const tags = column.array(); * * // With complex element types * interface Comment { author: string; text: string; date: string; } * const comments = column.array(); * * // With union types * const mixedData = column.array(); */ array: () => Column[], "array">; /** * Creates a list column. * @returns A new {@link Column} instance for lists. * @remarks * - Stores ordered collections as read-only arrays (`ReadonlyArray`). * - Accepts an optional generic type parameter defining the element type. * - Defaults to `any` if not specified, but explicit typing is recommended. * - Type-level immutability prevents accidental modifications in consuming code. * - Semantically indicates the data should not be mutated, though IndexedDB storage is identical to arrays. * * @example * // Basic usage * const allowedRoles = column.list(); * * // With object elements * interface Permission { resource: string; actions: string[]; } * const permissions = column.list(); */ list: () => Column>, "list">; /** * Creates a tuple column. * @returns A new {@link Column} instance for tuples. * @remarks * - Stores fixed-size, ordered collections with potentially different element types. * - Accepts an optional generic type parameter defining the tuple structure. * - Defaults to `any` if not specified, but explicit tuple types are strongly recommended. * - Type-level enforcement ensures correct element types at each position. * - Ideal for coordinate pairs, RGB values, or any fixed-length heterogeneous data. * * @example * // Coordinate pair [x, y] * const position = column.tuple(); * * // RGB color [red, green, blue] * const color = column.tuple(); * * // Mixed types [name, age, isActive] * const userInfo = column.tuple(); */ tuple: () => Column>, "tuple">; /** * Creates a set column. * @returns A new {@link Column} instance for sets. * @remarks * - Stores unique, unordered collections using JavaScript `Set` objects. * - Accepts an optional generic type parameter defining the element type. * - Defaults to `any` if not specified, but explicit typing improves type safety. * - Automatically ensures uniqueness of elements at runtime via Set semantics. * - Useful for tags, categories, unique identifiers, or any collection requiring distinctness. * * @example * // Unique tags * const tags = column.set(); * * // Unique user IDs * const followerIds = column.set(); * * // Unique literal values * const permissions = column.set<'read' | 'write' | 'delete'>(); */ set: () => Column>, "set">; /** * Creates a map column. * @returns A new {@link Column} instance for maps. * @remarks * - Stores key-value pairs using JavaScript `Map` objects. * - Accepts two optional generic type parameters: key type `K` and value type `V`. * - Both default to `any` if not specified, but explicit typing is recommended. * - Maintains insertion order and allows any type as keys (unlike plain objects). * - Ideal for dictionaries, lookup tables, caches, or associative data structures. * * @example * // String keys to number values * const scores = column.map(); * * // Number keys to object values * interface User { name: string; email: string; } * const userCache = column.map(); * * // Literal keys to union values * const config = column.map<'theme' | 'lang', string | boolean>(); */ map: () => Column, NoInfer>, "map">; /** * Creates a custom column. * @returns A new {@link Column} instance for custom data types. * @remarks * - This column type is used for any custom data type. * - You can specify the type when creating the column. * - No built-in serialization/deserialization is provided; you must handle it yourself. */ custom: () => Column, "custom">; }; //#endregion //#region src/utils.d.ts /** * * Generate a random UUID v4 string * @param uppercase Whether to return the UUID in uppercase format. Default is `false`. * @returns UUID v4 string * @remarks Uses Web Crypto (`crypto.randomUUID` or `crypto.getRandomValues`) when available, falls back to `Math.random()`. */ declare function uuidV4(uppercase?: boolean): UUID<'v4'>; /** * * Get current timestamp in ISO 8601 format * @param value Optional date input (string, number, or Date object). Defaults to {@link Date new Date()} * @remarks If the provided value is invalid, the current date and time will be used. * @returns Timestamp string in ISO 8601 format */ declare function getTimestamp(value?: string | number | Date): Timestamp; /** * * Check if a value is a valid Timestamp string in ISO 8601 format * @param value The value to check * @returns `true` if the value is a valid Timestamp, otherwise `false` */ declare function isTimestamp(value: unknown): value is Timestamp; /** * * Delete an IndexedDB database by name * @param name The name of the database to delete * @returns A promise that resolves when the database is deleted * @throws Error if `IndexedDB` is not supported or if the database does not exist */ declare function deleteDB(name: string): Promise; /** * * Check if a value is a valid Email string * @param value The value to check * @returns `true` if the value is a valid Email, otherwise `false` */ declare function isEmail(value: unknown): value is Email; /** * * Check if a value is a valid URL string * @param value The value to check * @returns `true` if the value is a valid URL, otherwise `false` */ declare function isURL(value: unknown): value is URLString; /** * * Check if a value is a valid UUID (`RFC4122` `v1`-`v8`). * @param value - The value to check. * @returns `true` if the value matches standard UUID pattern, otherwise `false`. */ declare function isUUID(value: unknown): value is UUID; /** * * Get the storage usage & quota of the browser's {@link https://developer.mozilla.org/docs/Web/API/StorageManager available storage}. * * @template T The type of the formatted values (default is `number`). * @param formatter Optional function to format the byte values (e.g., to convert to KB, MB, etc.). * @returns A promise that resolves to an object containing the `quota` and `used` storage values. * * @remarks This function uses the {@link https://developer.mozilla.org/docs/Web/API/StorageManager/estimate navigator.storage.estimate()} API to retrieve storage information. * - If the API is not available or an error occurs, it returns default values of `0` for both `quota` and `used`. * - The `formatter` function can be used to convert the byte values into a more readable format. * - If no formatter is provided, the raw byte values will be returned. * * @example * ```ts * const storage = await getStorageUsage(formatBytes); * console.log(`Quota: ${storage.quota}, Used: ${storage.used}`); * ``` * @example * ```ts * const storage = await getStorageUsage(); * console.log(`Quota: ${storage.quota}, Used: ${storage.used}`); * ``` */ declare function getStorageUsage(formatter?: FormatByte): Promise>; /** * * Format a byte value into a human-readable string with appropriate units (B, KB, MB, GB). * * @param bytes The byte value to format. * @returns A formatted string representing the byte value in appropriate units. * * @remarks This function uses logarithmic calculations to determine the appropriate unit for the given byte value. * - If the byte value is `0`, it returns `'0 B'`. * - The function supports formatting up to gigabytes (GB). * - The formatted value is rounded to two decimal places. * - If the input is not a finite number, it throws a `TypeError`. * * @example * ```ts * console.log(formatBytes(1024)); // "1.00 KB" * console.log(formatBytes(1048576)); // "1.00 MB" * console.log(formatBytes(1073741824)); // "1.00 GB" * console.log(formatBytes(0)); // "0 B" * ``` */ declare function formatBytes(bytes: number): string; //#endregion //#region src/validators.d.ts /** * * Validate if a value matches the specified column data type * @param type The column data type * @param value The value to validate * @returns `null` if valid, otherwise an error message string */ declare function validateColumnType(type: T, value: unknown): Nullable; //#endregion export { type $InferAutoInc, type $InferDefault, type $InferIndex, type $InferNullable, type $InferOptional, type $InferPrimaryKey, type $InferRow, type $InferTimestamp, type $InferUUID, type $InferUnique, type $UUID, type $UUIDVersion, type $ValidateSinglePK, type AdvancedTypes, type ArrayToTuple, type AsyncFunction, type BasicPrimitive, type BooleanRecord, type Branded, type Column, type ColumnDefinition, type ColumnRecord, ColumnType, type ColumnValue, type Constructor, type CursorCallback, type DateLike, DefaultValue, type Email, type EnsureRefIsValid, type ExportData, type ExportMetaData, type ExportObjectOptions, type ExportOptions, type ExportedTableData, type ExtractRef, type FirstOverloadParams, type ForcedAny, type FormatByte, type GenericFn, type GenericObject, type IDBGetter, type ImportMode, type ImportOptions, type IndexConfig, type IndexKeyType, type IndexedResult, type InferInsertType, type InferSelectType, type InferUpdateType, IsAutoInc, IsIndexed, IsNullable, IsOptional, IsPrimaryKey, IsUnique, type List, Locality, type LocalityConfig, type LooseLiteral, type MapObjectValues, type Maybe, type NestedPrimitiveKey, type NormalPrimitive, type Nullable, type Numeric, type NumericDotKey, OnUpdate, type PKColumn, type PageOptions, type PageResult, type Prettify, type PrimaryKeyType, type Primitive, type RefAction, type RefMetadata, type RefOptions, type RefValidationMap, type RejectFn, type ResolveValue, type Schema, type SchemaDefinition, type SchemaRecord, type SelectFields, type SortDirection, type StorageUsage, type StoreConfig, type Table, type Timestamp, type TransactionCallback, type TransactionContext, type Tuple, type TypeName, type URLString, type UUID, type UUIDVersion, type Uncertain, type UniqueKeyType, type UpdateCallback, type UpdaterFn, ValidateFn, type ValidateRefs, type ValidatedColumnDefinition, type ValidatorFn, type VoidFn, type WherePredicate, column, defineSchema, deleteDB, formatBytes, getStorageUsage, getTimestamp, isEmail, isTimestamp, isURL, isUUID, openDBWithStores, table, uuidV4, validateColumnType };