@orkestrel/indexeddb 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/src/browser/IndexedDBCursor.d.ts +28 -0
- package/dist/src/browser/IndexedDBDatabase.d.ts +27 -0
- package/dist/src/browser/IndexedDBIndex.d.ts +31 -0
- package/dist/src/browser/IndexedDBStore.d.ts +41 -0
- package/dist/src/browser/IndexedDBTransaction.d.ts +24 -0
- package/dist/src/browser/IndexedDBTransactionStore.d.ts +34 -0
- package/dist/src/browser/constants.d.ts +10 -0
- package/dist/src/browser/errors.d.ts +30 -0
- package/dist/src/browser/factories.d.ts +30 -0
- package/dist/src/browser/helpers.d.ts +130 -0
- package/dist/src/browser/index.d.ts +11 -0
- package/dist/src/browser/index.js +939 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/browser/types.d.ts +290 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Orkestrel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @orkestrel/indexeddb
|
|
2
|
+
|
|
3
|
+
A typed, Promise-based wrapper over browser IndexedDB — object stores,
|
|
4
|
+
secondary indexes, native key ranges, promisified cursors, and versioned
|
|
5
|
+
schema upgrades, over `await` instead of raw `IDBRequest` events. Part of the
|
|
6
|
+
`@orkestrel` line.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @orkestrel/indexeddb
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Node.js >= 24 (build/test tooling)
|
|
17
|
+
- ESM-only (no CommonJS build)
|
|
18
|
+
- A browser environment with `IndexedDB` (feature-detect with
|
|
19
|
+
`isIndexedDBSupported` before opening a database)
|
|
20
|
+
|
|
21
|
+
## Status
|
|
22
|
+
|
|
23
|
+
Pre-release. The public API is implemented and tested against a real
|
|
24
|
+
Chromium instance; see the
|
|
25
|
+
[guide](https://github.com/orkestrel/indexeddb/blob/main/guides/src/indexeddb.md)
|
|
26
|
+
for the full surface, patterns, and invariants.
|
|
27
|
+
|
|
28
|
+
## Package
|
|
29
|
+
|
|
30
|
+
Published as a single, browser-only ESM entry point per the `exports` field
|
|
31
|
+
in `package.json` — no server or Node-only build.
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT © [Orkestrel](https://github.com/orkestrel) — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IndexedDBCursorInterface, Row } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A promisified value cursor over an object store or index.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Wraps `IDBCursorWithValue` and the request that drives it. The position
|
|
7
|
+
* (`key` / `primary` / `value`) is snapshot at construction because IndexedDB
|
|
8
|
+
* mutates the live cursor object in place on each advance. `continue` / `seek` /
|
|
9
|
+
* `advance` re-arm the shared request and resolve to the next position (a fresh
|
|
10
|
+
* `IndexedDBCursor`) or `null` at the end. `update` / `delete` act on the current
|
|
11
|
+
* record — they require the cursor's transaction to be `readwrite` (a `store`
|
|
12
|
+
* cursor), so they reject on an `index` cursor's read-only transaction.
|
|
13
|
+
*/
|
|
14
|
+
export declare class IndexedDBCursor implements IndexedDBCursorInterface {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(cursor: IDBCursorWithValue, request: IDBRequest<IDBCursorWithValue | null>);
|
|
17
|
+
get cursor(): IDBCursorWithValue;
|
|
18
|
+
get source(): IDBObjectStore | IDBIndex;
|
|
19
|
+
get key(): IDBValidKey;
|
|
20
|
+
get primary(): IDBValidKey;
|
|
21
|
+
get value(): Row;
|
|
22
|
+
get direction(): IDBCursorDirection;
|
|
23
|
+
continue(key?: IDBValidKey): Promise<IndexedDBCursorInterface | null>;
|
|
24
|
+
seek(key: IDBValidKey, primary: IDBValidKey): Promise<IndexedDBCursorInterface | null>;
|
|
25
|
+
advance(count: number): Promise<IndexedDBCursorInterface | null>;
|
|
26
|
+
update(value: Row): Promise<IDBValidKey>;
|
|
27
|
+
delete(): Promise<void>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IndexedDBDatabaseInterface, IndexedDBDatabaseOptions, IndexedDBStoreInterface, IndexedDBTransactionInterface, StoresShape } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A browser-native IndexedDB database — a typed, Promise-based handle.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Connects lazily on first use (`connect`, also awaited internally by every store
|
|
7
|
+
* operation), creating any missing stores from their definitions inside
|
|
8
|
+
* `onupgradeneeded`. `store` reaches a typed store; `read` / `write` run an atomic
|
|
9
|
+
* scope over one or more stores, committing on resolve and rolling back on a throw;
|
|
10
|
+
* `close` releases the connection and `drop` deletes the database. Schema changes
|
|
11
|
+
* beyond creating new stores (dropping stores, altering indexes) are deferred.
|
|
12
|
+
*/
|
|
13
|
+
export declare class IndexedDBDatabase<Stores extends StoresShape = StoresShape> implements IndexedDBDatabaseInterface<Stores> {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(options: IndexedDBDatabaseOptions<Stores>);
|
|
16
|
+
get database(): IDBDatabase;
|
|
17
|
+
get name(): string;
|
|
18
|
+
get version(): number;
|
|
19
|
+
get stores(): readonly string[];
|
|
20
|
+
get open(): boolean;
|
|
21
|
+
connect(): Promise<IDBDatabase>;
|
|
22
|
+
store<K extends keyof Stores & string>(name: K): IndexedDBStoreInterface;
|
|
23
|
+
read(stores: (keyof Stores & string) | readonly (keyof Stores & string)[], scope: (tx: IndexedDBTransactionInterface<Stores>) => void | Promise<void>): Promise<void>;
|
|
24
|
+
write(stores: (keyof Stores & string) | readonly (keyof Stores & string)[], scope: (tx: IndexedDBTransactionInterface<Stores>) => void | Promise<void>): Promise<void>;
|
|
25
|
+
close(): void;
|
|
26
|
+
drop(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CursorOptions, IndexDefinition, IndexedDBCursorInterface, IndexedDBIndexInterface, KeyPath, Row } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A secondary index on a store — a read-only view keyed by an indexed path.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Reached through `store.index(name)`. Each call opens its own `readonly`
|
|
7
|
+
* transaction. `get` / `resolve` fetch the first record for an index key
|
|
8
|
+
* (`resolve` throws `NOT_FOUND`); `records` reads the matching records and `keys`
|
|
9
|
+
* their **primary** keys; `primary` maps an index key to one primary key; `count`
|
|
10
|
+
* / `has` test presence; `cursor` streams matches. Reads batch by their array
|
|
11
|
+
* overload (AGENTS §9.2).
|
|
12
|
+
*/
|
|
13
|
+
export declare class IndexedDBIndex implements IndexedDBIndexInterface {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(store: string, name: string, definition: IndexDefinition, connect: () => Promise<IDBDatabase>);
|
|
16
|
+
get name(): string;
|
|
17
|
+
get path(): KeyPath;
|
|
18
|
+
get unique(): boolean;
|
|
19
|
+
get multiple(): boolean;
|
|
20
|
+
get(keys: readonly IDBValidKey[]): Promise<readonly (Row | undefined)[]>;
|
|
21
|
+
get(key: IDBValidKey): Promise<Row | undefined>;
|
|
22
|
+
resolve(keys: readonly IDBValidKey[]): Promise<readonly Row[]>;
|
|
23
|
+
resolve(key: IDBValidKey): Promise<Row>;
|
|
24
|
+
records(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly Row[]>;
|
|
25
|
+
keys(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly IDBValidKey[]>;
|
|
26
|
+
primary(key: IDBValidKey): Promise<IDBValidKey | undefined>;
|
|
27
|
+
has(keys: readonly IDBValidKey[]): Promise<readonly boolean[]>;
|
|
28
|
+
has(key: IDBValidKey): Promise<boolean>;
|
|
29
|
+
count(query?: IDBKeyRange | IDBValidKey | null): Promise<number>;
|
|
30
|
+
cursor(options?: CursorOptions): Promise<IndexedDBCursorInterface | null>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CursorOptions, IndexedDBCursorInterface, IndexedDBIndexInterface, IndexedDBStoreInterface, KeyPath, Row, StoreDefinition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An object store — the full keyed CRUD surface plus index, count, and cursor
|
|
4
|
+
* access.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Reached through `database.store(name)`. Each call runs in its own implicit
|
|
8
|
+
* transaction (`readonly` for reads, `readwrite` for writes), awaiting completion
|
|
9
|
+
* so writes are durable on return; for atomic multi-operation work use the
|
|
10
|
+
* database's `read` / `write`. The keyed verbs batch by their array overload — and
|
|
11
|
+
* those overloads are declared first, because an array is itself both a record and
|
|
12
|
+
* a compound `IDBValidKey`, so the array signature must take precedence to read as
|
|
13
|
+
* a batch (AGENTS §9.2). Pass `range.only([…])` to `records` / `count` to act on a
|
|
14
|
+
* single compound key.
|
|
15
|
+
*/
|
|
16
|
+
export declare class IndexedDBStore implements IndexedDBStoreInterface {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(name: string, definition: StoreDefinition, connect: () => Promise<IDBDatabase>);
|
|
19
|
+
get name(): string;
|
|
20
|
+
get path(): KeyPath | null;
|
|
21
|
+
get indexes(): readonly string[];
|
|
22
|
+
get increment(): boolean;
|
|
23
|
+
get(keys: readonly IDBValidKey[]): Promise<readonly (Row | undefined)[]>;
|
|
24
|
+
get(key: IDBValidKey): Promise<Row | undefined>;
|
|
25
|
+
resolve(keys: readonly IDBValidKey[]): Promise<readonly Row[]>;
|
|
26
|
+
resolve(key: IDBValidKey): Promise<Row>;
|
|
27
|
+
records(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly Row[]>;
|
|
28
|
+
keys(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly IDBValidKey[]>;
|
|
29
|
+
has(keys: readonly IDBValidKey[]): Promise<readonly boolean[]>;
|
|
30
|
+
has(key: IDBValidKey): Promise<boolean>;
|
|
31
|
+
count(query?: IDBKeyRange | IDBValidKey | null): Promise<number>;
|
|
32
|
+
set(values: readonly Row[]): Promise<readonly IDBValidKey[]>;
|
|
33
|
+
set(value: Row, key?: IDBValidKey): Promise<IDBValidKey>;
|
|
34
|
+
add(values: readonly Row[]): Promise<readonly IDBValidKey[]>;
|
|
35
|
+
add(value: Row, key?: IDBValidKey): Promise<IDBValidKey>;
|
|
36
|
+
remove(keys: readonly IDBValidKey[]): Promise<void>;
|
|
37
|
+
remove(key: IDBValidKey): Promise<void>;
|
|
38
|
+
clear(): Promise<void>;
|
|
39
|
+
index(name: string): IndexedDBIndexInterface;
|
|
40
|
+
cursor(options?: CursorOptions): Promise<IndexedDBCursorInterface | null>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { IndexedDBTransactionInterface, IndexedDBTransactionStoreInterface, StoresShape } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An explicit transaction over one or more stores.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Wraps `IDBTransaction` with state tracking and typed, scope-bound store access.
|
|
7
|
+
* Constructed by the database's `read` / `write`, which await its completion (or
|
|
8
|
+
* roll it back on a throw). `store` reaches a store within the transaction's scope;
|
|
9
|
+
* `abort` rolls back; `commit` flushes early (the scope's completion commits
|
|
10
|
+
* otherwise). `active` is true until commit or abort; `finished` is its complement.
|
|
11
|
+
*/
|
|
12
|
+
export declare class IndexedDBTransaction<Stores extends StoresShape = StoresShape> implements IndexedDBTransactionInterface<Stores> {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(transaction: IDBTransaction);
|
|
15
|
+
get transaction(): IDBTransaction;
|
|
16
|
+
get mode(): IDBTransactionMode;
|
|
17
|
+
get stores(): readonly string[];
|
|
18
|
+
get active(): boolean;
|
|
19
|
+
get finished(): boolean;
|
|
20
|
+
get error(): DOMException | null;
|
|
21
|
+
store<K extends keyof Stores & string>(name: K): IndexedDBTransactionStoreInterface;
|
|
22
|
+
abort(): void;
|
|
23
|
+
commit(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CursorOptions, IndexedDBCursorInterface, IndexedDBTransactionStoreInterface, Row } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An object store bound to an explicit transaction.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The same CRUD surface as a standalone store, but every call runs in the owning
|
|
7
|
+
* transaction (opened by the database's `read` / `write`) rather than its own — so
|
|
8
|
+
* a sequence of reads and writes commits atomically when the scope resolves. It
|
|
9
|
+
* does not await transaction completion per call (the scope does that once) and
|
|
10
|
+
* omits `index`; keep your awaited operations on IndexedDB requests only, so the
|
|
11
|
+
* transaction stays active across them.
|
|
12
|
+
*/
|
|
13
|
+
export declare class IndexedDBTransactionStore implements IndexedDBTransactionStoreInterface {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(store: IDBObjectStore);
|
|
16
|
+
get store(): IDBObjectStore;
|
|
17
|
+
get(keys: readonly IDBValidKey[]): Promise<readonly (Row | undefined)[]>;
|
|
18
|
+
get(key: IDBValidKey): Promise<Row | undefined>;
|
|
19
|
+
resolve(keys: readonly IDBValidKey[]): Promise<readonly Row[]>;
|
|
20
|
+
resolve(key: IDBValidKey): Promise<Row>;
|
|
21
|
+
records(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly Row[]>;
|
|
22
|
+
keys(query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly IDBValidKey[]>;
|
|
23
|
+
has(keys: readonly IDBValidKey[]): Promise<readonly boolean[]>;
|
|
24
|
+
has(key: IDBValidKey): Promise<boolean>;
|
|
25
|
+
count(query?: IDBKeyRange | IDBValidKey | null): Promise<number>;
|
|
26
|
+
set(values: readonly Row[]): Promise<readonly IDBValidKey[]>;
|
|
27
|
+
set(value: Row, key?: IDBValidKey): Promise<IDBValidKey>;
|
|
28
|
+
add(values: readonly Row[]): Promise<readonly IDBValidKey[]>;
|
|
29
|
+
add(value: Row, key?: IDBValidKey): Promise<IDBValidKey>;
|
|
30
|
+
remove(keys: readonly IDBValidKey[]): Promise<void>;
|
|
31
|
+
remove(key: IDBValidKey): Promise<void>;
|
|
32
|
+
clear(): Promise<void>;
|
|
33
|
+
cursor(options?: CursorOptions): Promise<IndexedDBCursorInterface | null>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IndexedDBErrorCode } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Native `DOMException.name` → our {@link IndexedDBErrorCode}.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The mapping the request boundary's `wrapError` reads to translate a raw
|
|
7
|
+
* IndexedDB fault into a typed {@link IndexedDBError} code; an unmapped name
|
|
8
|
+
* falls back to `UNKNOWN`. Frozen plain data (AGENTS §5).
|
|
9
|
+
*/
|
|
10
|
+
export declare const ERROR_CODES: Readonly<Record<string, IndexedDBErrorCode>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IndexedDBErrorCode } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An error thrown by the IndexedDB wrapper.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Carries an {@link IndexedDBErrorCode} and the originating native error as the
|
|
7
|
+
* standard `cause`. Construct it directly for wrapper-lifecycle faults; the
|
|
8
|
+
* internal `wrapError` maps a native `DOMException` to the right code at the
|
|
9
|
+
* request boundary. Narrow a caught value with `instanceof IndexedDBError`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* try {
|
|
14
|
+
* await store.add(row)
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* if (error instanceof IndexedDBError && error.code === 'CONSTRAINT') await store.set(row)
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class IndexedDBError extends Error {
|
|
21
|
+
readonly code: IndexedDBErrorCode;
|
|
22
|
+
constructor(code: IndexedDBErrorCode, message: string, cause?: unknown);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether a value is an {@link IndexedDBError}.
|
|
26
|
+
*
|
|
27
|
+
* @param value - The value to test
|
|
28
|
+
* @returns `true` when `value` is an `IndexedDBError`
|
|
29
|
+
*/
|
|
30
|
+
export declare function isIndexedDBError(value: unknown): value is IndexedDBError;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IndexedDBDatabaseInterface, IndexedDBDatabaseOptions, StoresShape } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a browser-native IndexedDB database over a store schema.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The `const` type parameter captures the literal store names, so `db.store(name)`
|
|
7
|
+
* and `db.read` / `db.write` are checked against the declared stores. Stores are
|
|
8
|
+
* created from their definitions the first time the database opens at a new
|
|
9
|
+
* `version`; omit `version` for auto-managed mode, where the database bumps its
|
|
10
|
+
* own version once to create any declared store the stored schema is missing.
|
|
11
|
+
*
|
|
12
|
+
* @param options - The database `name`, `version`, and `stores` schema
|
|
13
|
+
* @returns A typed {@link IndexedDBDatabaseInterface}
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { createIndexedDBDatabase, range } from '@src/browser'
|
|
18
|
+
*
|
|
19
|
+
* const db = createIndexedDBDatabase({
|
|
20
|
+
* name: 'app',
|
|
21
|
+
* version: 1,
|
|
22
|
+
* stores: {
|
|
23
|
+
* users: { path: 'id', indexes: [{ name: 'byAge', path: 'age' }] },
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
26
|
+
* await db.store('users').set({ id: 'u1', name: 'Ada', age: 36 })
|
|
27
|
+
* await db.store('users').index('byAge').records(range.from(18)) // adults, index-backed
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function createIndexedDBDatabase<const Stores extends StoresShape>(options: IndexedDBDatabaseOptions<Stores>): IndexedDBDatabaseInterface<Stores>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { Row } from './types.js';
|
|
2
|
+
import { IndexedDBError } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Whether IndexedDB is available in this environment.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Gate IndexedDB code with this and fall back to another storage strategy where
|
|
8
|
+
* it is absent (a non-browser runtime, a privacy mode that disables storage).
|
|
9
|
+
* The entry probe, checked before reaching for the rest of this module.
|
|
10
|
+
*
|
|
11
|
+
* @returns `true` when `globalThis.indexedDB` exists
|
|
12
|
+
*/
|
|
13
|
+
export declare function isIndexedDBSupported(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve an `IDBRequest` to its result, rejecting with an {@link IndexedDBError}.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* The single bridge from IndexedDB's event-based requests to Promises. Issue the
|
|
19
|
+
* request, then `await` this — within an implicit transaction, issue every request
|
|
20
|
+
* for that transaction before the first `await`, so they share it.
|
|
21
|
+
*
|
|
22
|
+
* @param request - The pending request
|
|
23
|
+
* @returns Its `result` on success
|
|
24
|
+
*/
|
|
25
|
+
export declare function promisifyRequest<T>(request: IDBRequest<T>): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve once an `IDBTransaction` commits, rejecting if it errors or aborts.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* Await this after issuing the writes of a `readwrite` transaction to guarantee
|
|
31
|
+
* they are durable before continuing.
|
|
32
|
+
*
|
|
33
|
+
* @param transaction - The transaction to await
|
|
34
|
+
*/
|
|
35
|
+
export declare function promisifyTransaction(transaction: IDBTransaction): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Run a synchronous native IndexedDB call, wrapping a thrown `DOMException`
|
|
38
|
+
* into a typed {@link IndexedDBError}.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* Native IndexedDB throws SYNCHRONOUSLY (not through a request's `onerror`)
|
|
42
|
+
* from calls like `database.transaction(...)` or an inactive/closed store's
|
|
43
|
+
* `get` / `put` / `openCursor` — `TransactionInactiveError` /
|
|
44
|
+
* `InvalidStateError` never reach {@link promisifyRequest}'s `onerror`
|
|
45
|
+
* bridge. Every request-issuing call site wraps its native invocation in this
|
|
46
|
+
* so those faults surface as the same typed `IndexedDBError` as an
|
|
47
|
+
* asynchronous one.
|
|
48
|
+
*
|
|
49
|
+
* @param action - The synchronous native call to run
|
|
50
|
+
* @returns Its return value
|
|
51
|
+
*/
|
|
52
|
+
export declare function guardSync<T>(action: () => T): T;
|
|
53
|
+
/**
|
|
54
|
+
* Read one record by key from a store or index, narrowing it to a {@link Row}.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* The shared point-read of every store-like class (`IndexedDBStore`,
|
|
58
|
+
* `IndexedDBIndex`, `IndexedDBTransactionStore`): issue the native `get`, then
|
|
59
|
+
* narrow the structured clone with `isRecord` — a non-record (or a miss) reads as
|
|
60
|
+
* `undefined`, never an unchecked cast. On an index, `source.get` returns the
|
|
61
|
+
* first record for the index key.
|
|
62
|
+
*
|
|
63
|
+
* @param source - The object store or index to read from
|
|
64
|
+
* @param key - The key (a primary key for a store, an index key for an index)
|
|
65
|
+
* @returns The record, or `undefined` on a miss
|
|
66
|
+
*/
|
|
67
|
+
export declare function readRecord(source: IDBObjectStore | IDBIndex, key: IDBValidKey): Promise<Row | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Read many records from a store or index over an optional key range.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* The shared bulk read of every store-like class: issue the native `getAll` over
|
|
73
|
+
* an optional `query` (a key range or a single key) and `count` cap, then keep
|
|
74
|
+
* only the records with `isRecord` — the same boundary narrowing as
|
|
75
|
+
* {@link readRecord}, applied across the batch.
|
|
76
|
+
*
|
|
77
|
+
* @param source - The object store or index to read from
|
|
78
|
+
* @param query - A key range or single key to restrict the read, or `null` for all
|
|
79
|
+
* @param count - The maximum number of records to read
|
|
80
|
+
* @returns The matching records
|
|
81
|
+
*/
|
|
82
|
+
export declare function readRecords(source: IDBObjectStore | IDBIndex, query?: IDBKeyRange | IDBValidKey | null, count?: number): Promise<readonly Row[]>;
|
|
83
|
+
/**
|
|
84
|
+
* Whether a key is present in a store or index.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* The shared presence test of every store-like class: a native `count` of the
|
|
88
|
+
* key, true when at least one record matches — cheaper than reading the record
|
|
89
|
+
* when only existence matters.
|
|
90
|
+
*
|
|
91
|
+
* @param source - The object store or index to test
|
|
92
|
+
* @param key - The key to look for
|
|
93
|
+
* @returns `true` when at least one record has the key
|
|
94
|
+
*/
|
|
95
|
+
export declare function hasKey(source: IDBObjectStore | IDBIndex, key: IDBValidKey): Promise<boolean>;
|
|
96
|
+
/**
|
|
97
|
+
* Key-range builders — the wrapper's filter vocabulary.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* Each returns an `IDBKeyRange` to pass to `records` / `keys` / `count` / `cursor`,
|
|
101
|
+
* so a read is index-backed (O(log n)) rather than a full scan. `only` (exact),
|
|
102
|
+
* `above` / `from` (greater than, exclusive / inclusive), `below` / `to` (less
|
|
103
|
+
* than, exclusive / inclusive), `between` (bounded), and `prefix` (string
|
|
104
|
+
* starts-with).
|
|
105
|
+
*/
|
|
106
|
+
export declare const range: {
|
|
107
|
+
only(value: IDBValidKey): IDBKeyRange;
|
|
108
|
+
above(value: IDBValidKey): IDBKeyRange;
|
|
109
|
+
from(value: IDBValidKey): IDBKeyRange;
|
|
110
|
+
below(value: IDBValidKey): IDBKeyRange;
|
|
111
|
+
to(value: IDBValidKey): IDBKeyRange;
|
|
112
|
+
between(lower: IDBValidKey, upper: IDBValidKey, options?: {
|
|
113
|
+
readonly lowerOpen?: boolean;
|
|
114
|
+
readonly upperOpen?: boolean;
|
|
115
|
+
}): IDBKeyRange;
|
|
116
|
+
prefix(value: string): IDBKeyRange;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Map a native IndexedDB `DOMException` to a typed {@link IndexedDBError}.
|
|
120
|
+
*
|
|
121
|
+
* @remarks
|
|
122
|
+
* The boundary the two Promise bridges ({@link promisifyRequest} /
|
|
123
|
+
* {@link promisifyTransaction}) share: it reads {@link ERROR_CODES} to pick the
|
|
124
|
+
* machine-readable code for the native `name`, falling back to `UNKNOWN` for an
|
|
125
|
+
* unmapped name or a `null` error.
|
|
126
|
+
*
|
|
127
|
+
* @param error - The native error, or `null` when none is attached
|
|
128
|
+
* @returns The wrapped, typed error
|
|
129
|
+
*/
|
|
130
|
+
export declare function wrapError(error: DOMException | null): IndexedDBError;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type * from './types.js';
|
|
2
|
+
export * from './constants.js';
|
|
3
|
+
export * from './errors.js';
|
|
4
|
+
export * from './helpers.js';
|
|
5
|
+
export * from './factories.js';
|
|
6
|
+
export * from './IndexedDBDatabase.js';
|
|
7
|
+
export * from './IndexedDBStore.js';
|
|
8
|
+
export * from './IndexedDBIndex.js';
|
|
9
|
+
export * from './IndexedDBCursor.js';
|
|
10
|
+
export * from './IndexedDBTransaction.js';
|
|
11
|
+
export * from './IndexedDBTransactionStore.js';
|