import { i as Subscribable, r as ServerReadable } from "./index-B0IeflOl.mjs";
import { i as StandardSchemaV1 } from "./validate-C_H-c0gq.mjs";
//#region src/web/indexed-db-table/index.d.ts
type IndexedDbTableRange<Key extends IDBValidKey = IDBValidKey> = Key | IDBKeyRange | null;
interface IndexedDbTableValidationErrorProps {
  issues: StandardSchemaV1.Issue[];
  value: unknown;
}
declare class IndexedDbTableValidationError extends Error {
  issues: readonly StandardSchemaV1.Issue[];
  value: unknown;
  constructor(label: string, issues: readonly StandardSchemaV1.Issue[], value: unknown);
}
interface IndexedDbTableOptions<S extends StandardSchemaV1<unknown>> extends IndexedDbStoreDefinition<StandardSchemaV1.InferOutput<S>> {
  schema: S;
  onValidationError?: (props: IndexedDbTableValidationErrorProps) => void | StandardSchemaV1.InferOutput<S>;
}
type IndexedDbTableIndexNames<Definition> = Definition extends {
  indexes: infer Indexes;
} ? keyof Indexes & string : string;
type KeyAtPath<Row, Path, Value = Path extends keyof Row ? Row[Path] : never> = Extract<Value | (Value extends readonly (infer Element)[] ? Element : never), IDBValidKey> extends (infer Key extends IDBValidKey) ? [Key] extends [never] ? IDBValidKey : Key : IDBValidKey;
type StoreShape<Definition> = { [K in keyof Definition as K extends 'schema' | 'onValidationError' ? never : K]: Definition[K]; };
type IndexedDbExplicitKey<Definition> = Definition extends {
  keyPath: unknown;
} ? never : IDBValidKey;
type IndexedDbPrimaryKey<Row, Definition> = Definition extends {
  keyPath: infer Path;
} ? KeyAtPath<Row, Path> : IDBValidKey;
type IndexedDbIndexKey<Row, Definition, Name> = Definition extends {
  indexes: infer Indexes;
} ? Name extends keyof Indexes ? KeyAtPath<Row, Indexes[Name] extends {
  keyPath: infer Path;
} ? Path : Indexes[Name]> : IDBValidKey : IDBValidKey;
interface IndexedDbTableIndexReader<Row, Key extends IDBValidKey = IDBValidKey> {
  get: (key: Key | IDBKeyRange) => Promise<Row | undefined>;
  getAll: (query?: IndexedDbTableRange<Key>, count?: number) => Promise<Row[]>;
  getAllKeys: (query?: IndexedDbTableRange<Key>, count?: number) => Promise<IDBValidKey[]>;
  count: (query?: IndexedDbTableRange<Key>) => Promise<number>;
}
interface IndexedDbTableReader<Row, Definition = unknown> extends IndexedDbTableIndexReader<Row, IndexedDbPrimaryKey<Row, Definition>> {
  index: <Name extends IndexedDbTableIndexNames<Definition>>(name: Name) => IndexedDbTableIndexReader<Row, IndexedDbIndexKey<Row, Definition, Name>>;
}
interface IndexedDbQueryOptions<R> {
  initial: R;
}
interface IndexedDbQuery<R> extends ServerReadable<R>, Subscribable<R> {
  ready: Promise<R>;
  refresh: () => Promise<R>;
}
interface IndexedDbTable<Row, Definition = unknown> extends IndexedDbTableReader<Row, Definition>, IndexedDbStoreHandle {
  put: (rows: Row | Row[], key?: IndexedDbExplicitKey<Definition>) => Promise<void>;
  delete: (keys: IndexedDbPrimaryKey<Row, Definition> | IDBKeyRange | IndexedDbPrimaryKey<Row, Definition>[]) => Promise<void>;
  clear: () => Promise<void>;
  query: {
    <R>(run: (table: IndexedDbTableReader<Row, Definition>) => Promise<R>, options: IndexedDbQueryOptions<R>): IndexedDbQuery<R>;
    <R>(run: (table: IndexedDbTableReader<Row, Definition>) => Promise<R>): IndexedDbQuery<R | undefined>;
  };
  '~': {
    schema: StandardSchemaV1<unknown>;
    subscribe: (callback: () => any) => () => void;
    notify: () => void;
  };
}
type IndexedDbTableDefinition<S extends StandardSchemaV1<unknown>, Definition> = IndexedDbStore<IndexedDbTable<StandardSchemaV1.InferOutput<S>, StoreShape<Definition>>>;
/**
 * Row store for `createIndexedDb({ stores })`: keyed rows, indexes, range
 * reads, validation. Use `query()` for a `Readable`/`Subscribable` that
 * re-runs on table changes. On the server, queries stay on `initial`.
 *
 * Key paths must name a schema field that can hold a key, and reads are typed
 * from that field. Compound (`['id', 'order']`) and nested (`'meta.slug'`)
 * paths fall back to `IDBValidKey`.
 *
 * @example Vanilla
 * ```ts twoslash title="todos.ts"
 * import { createIndexedDb, createIndexedDbTable } from 'seitu/web'
 * import * as z from 'zod'
 *
 * const db = createIndexedDb({
 *   name: 'app',
 *   stores: {
 *     todos: createIndexedDbTable({
 *       keyPath: 'id',
 *       indexes: { status: 'status' },
 *       schema: z.object({ id: z.string(), title: z.string(), status: z.enum(['open', 'done']) }),
 *     }),
 *   },
 * })
 * const { todos } = db.stores
 *
 * await todos.put({ id: '1', title: 'Write docs', status: 'open' })
 * await todos.get('1')
 * await todos.getAll()
 * await todos.index('status').getAll('open') // index names and keys are typed
 * await todos.delete('1')
 *
 * const open = todos.query(t => t.index('status').getAll('open'), { initial: [] })
 * open.get()
 * open.subscribe(rows => console.log(rows))
 * ```
 *
 * @example React
 * ```tsx twoslash title="page.tsx"
 * 'use client'
 *
 * import { createIndexedDb, createIndexedDbTable } from 'seitu/web'
 * import { useSubscription } from 'seitu/react'
 * import * as z from 'zod'
 *
 * const db = createIndexedDb({
 *   name: 'app',
 *   stores: {
 *     todos: createIndexedDbTable({
 *       keyPath: 'id',
 *       schema: z.object({ id: z.string(), title: z.string(), status: z.enum(['open', 'done']) }),
 *     }),
 *   },
 * })
 *
 * const allTodos = db.stores.todos.query(t => t.getAll(), { initial: [] })
 *
 * export default function Page() {
 *   const rows = useSubscription(allTodos)
 *   return (
 *     <ul>
 *       {rows.map(todo => <li key={todo.id}>{todo.title}</li>)}
 *     </ul>
 *   )
 * }
 * ```
 */
declare function createIndexedDbTable<S extends StandardSchemaV1<unknown>, const Definition extends IndexedDbStoreDefinition<StandardSchemaV1.InferOutput<S>>>(options: IndexedDbTableOptions<S> & Definition): IndexedDbTableDefinition<S, Definition>;
//#endregion
//#region src/web/indexed-db/index.d.ts
type IndexedDbKeyField<Row> = { [K in keyof Row & string]: Exclude<Row[K], undefined> extends IDBValidKey ? K : never; }[keyof Row & string];
type IndexedDbKeyPath<Row> = Row extends object ? ([IndexedDbKeyField<Row>] extends [never] ? keyof Row & string : IndexedDbKeyField<Row>) | `${keyof Row & string}.${string}` : string;
interface IndexedDbIndexDefinition<Row = unknown> {
  keyPath: IndexedDbKeyPath<Row> | IndexedDbKeyPath<Row>[];
  unique?: boolean;
  multiEntry?: boolean;
}
interface IndexedDbStoreDefinition<Row = unknown> {
  keyPath?: IndexedDbKeyPath<Row> | IndexedDbKeyPath<Row>[];
  autoIncrement?: boolean;
  indexes?: Record<string, IndexedDbKeyPath<Row> | IndexedDbKeyPath<Row>[] | IndexedDbIndexDefinition<Row>>;
}
interface IndexedDbStoreHandle {
  db: IndexedDb;
  storeName: string;
  hydrate?: () => Promise<unknown>;
}
interface IndexedDbStore<Handle extends IndexedDbStoreHandle = IndexedDbStoreHandle> {
  '~': {
    definition: IndexedDbStoreDefinition;
    create: (db: IndexedDb, storeName: string) => Handle;
  };
}
type IndexedDbStores = Record<string, IndexedDbStore>;
type IndexedDbStoreHandles<Stores extends IndexedDbStores> = { [K in keyof Stores]: Stores[K] extends IndexedDbStore<infer Handle> ? Handle : never; };
type RowOf<Store> = Store extends IndexedDbStore<IndexedDbTable<infer Row, any>> ? Row : unknown;
type IndexedDbMigrateRow<Row> = (row: Row & Record<string, unknown>, key: IDBValidKey) => Row | null | void;
interface IndexedDbUpgradeContext<Stores extends IndexedDbStores = IndexedDbStores> {
  database: IDBDatabase;
  transaction: IDBTransaction;
  oldVersion: number;
  newVersion: number | null;
  migrate: <Name extends keyof Stores & string>(name: Name, rewrite: IndexedDbMigrateRow<RowOf<Stores[Name]>>) => void;
}
interface IndexedDbOptions<Stores extends IndexedDbStores> {
  name: string;
  version?: number;
  stores: Stores;
  onUpgrade?: (context: IndexedDbUpgradeContext<Stores>) => void;
}
interface IndexedDb<Stores extends IndexedDbStores = IndexedDbStores> {
  ready: Promise<void>;
  close: () => void;
  stores: IndexedDbStoreHandles<Stores>;
  '~': {
    name: string;
    getDatabase: () => Promise<IDBDatabase>;
  };
}
/**
 * Opens one IndexedDB connection and builds a handle for each store definition
 * (`createIndexedDbStorage` or `createIndexedDbTable`). Missing stores/indexes
 * are created automatically; concurrent opens of the same name are serialized.
 *
 * `version` is a minimum, not a pin: adding a store or an index bumps it on its
 * own, so set it only when existing rows need migrating. Bump it, then rewrite
 * the rows with `migrate` in `onUpgrade`, which runs inside the `versionchange`
 * transaction after the declared stores and indexes are created. Everything
 * there is synchronous — `migrate` queues a cursor walk instead of returning a
 * promise, and `onUpgrade` cannot be `async`.
 *
 * `migrate` rewrites fields, not keys: changing the `keyPath` field of a row
 * aborts the upgrade. Indexes are created and filled before `onUpgrade` runs,
 * so a migration cannot clean up rows for a `unique` index added in the same
 * version — add the index in a later version than the cleanup. A failed
 * upgrade rolls back whole and is reported with `console.warn`: `ready` still
 * resolves, but reads and writes then reject, because every access retries the
 * same failing upgrade.
 *
 * Every write is one transaction, and only one. A single `put`, `delete`, `set`
 * or `clear` call opens a `readwrite` transaction and queues all of its rows or
 * keys on it, so a batch lands whole or not at all; two calls are two
 * transactions, and none of them spans stores. Reads work the same way: each
 * one is its own `readonly` snapshot.
 *
 * @example Vanilla
 * ```ts twoslash title="db.ts"
 * import { createIndexedDb, createIndexedDbStorage, createIndexedDbTable } from 'seitu/web'
 * import * as z from 'zod'
 *
 * const db = createIndexedDb({
 *   name: 'app',
 *   stores: {
 *     settings: createIndexedDbStorage({
 *       schemas: { theme: z.enum(['light', 'dark']) },
 *       defaultValues: { theme: 'light' },
 *     }),
 *     todos: createIndexedDbTable({
 *       keyPath: 'id',
 *       indexes: { status: 'status' },
 *       schema: z.object({ id: z.string(), title: z.string(), status: z.enum(['open', 'done']) }),
 *     }),
 *   },
 * })
 *
 * const { settings, todos } = db.stores
 *
 * settings.get() // { theme: 'light' } until hydrated
 * await db.ready
 * await todos.put({ id: '1', title: 'Write docs', status: 'open' })
 * ```
 *
 * @example Migrations
 * ```ts twoslash title="db.ts"
 * import { createIndexedDb, createIndexedDbTable } from 'seitu/web'
 * import * as z from 'zod'
 *
 * const db = createIndexedDb({
 *   name: 'app',
 *   version: 2, // v1 rows have no `priority`
 *   stores: {
 *     todos: createIndexedDbTable({
 *       keyPath: 'id',
 *       indexes: { priority: 'priority' },
 *       schema: z.object({ id: z.string(), title: z.string(), priority: z.number() }),
 *     }),
 *   },
 *   onUpgrade: ({ oldVersion, migrate }) => {
 *     if (oldVersion < 2) {
 *       migrate('todos', row => ({ ...row, priority: row.priority ?? 0 }))
 *       // Return `null` to drop a row, nothing to keep it as is.
 *     }
 *   },
 * })
 *
 * await db.ready
 * ```
 *
 * @example Transactions
 * ```ts twoslash title="checkout.ts"
 * import { createIndexedDb, createIndexedDbStorage, createIndexedDbTable } from 'seitu/web'
 * import * as z from 'zod'
 *
 * const db = createIndexedDb({
 *   name: 'app',
 *   stores: {
 *     sync: createIndexedDbStorage({
 *       schemas: { lastSyncedAt: z.number(), pending: z.number() },
 *       defaultValues: { lastSyncedAt: 0, pending: 0 },
 *     }),
 *     todos: createIndexedDbTable({
 *       keyPath: 'id',
 *       schema: z.object({ id: z.string(), title: z.string(), status: z.enum(['open', 'done']) }),
 *     }),
 *   },
 * })
 * const { sync, todos } = db.stores
 *
 * // One `readwrite` transaction: both rows land, or neither does.
 * await todos.put([
 *   { id: '1', title: 'Write docs', status: 'done' },
 *   { id: '2', title: 'Ship docs', status: 'open' },
 * ])
 *
 * await todos.delete(['1', '2'])
 * await sync.set({ lastSyncedAt: Date.now(), pending: 0 })
 *
 * await todos.put({ id: '3', title: 'Reconcile', status: 'open' })
 * await sync.set({ pending: 1 })
 * ```
 */
declare function createIndexedDb<const Stores extends IndexedDbStores>(options: IndexedDbOptions<Stores>): IndexedDb<Stores>;
//#endregion
export { IndexedDbTableRange as C, createIndexedDbTable as D, IndexedDbTableValidationErrorProps as E, IndexedDbTableOptions as S, IndexedDbTableValidationError as T, IndexedDbQueryOptions as _, IndexedDbOptions as a, IndexedDbTableIndexNames as b, IndexedDbStoreHandle as c, IndexedDbUpgradeContext as d, createIndexedDb as f, IndexedDbQuery as g, IndexedDbPrimaryKey as h, IndexedDbMigrateRow as i, IndexedDbStoreHandles as l, IndexedDbIndexKey as m, IndexedDbIndexDefinition as n, IndexedDbStore as o, IndexedDbExplicitKey as p, IndexedDbKeyPath as r, IndexedDbStoreDefinition as s, IndexedDb as t, IndexedDbStores as u, IndexedDbTable as v, IndexedDbTableReader as w, IndexedDbTableIndexReader as x, IndexedDbTableDefinition as y };