mates 0.3.0 → 0.3.2
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/dist/Directives/onDirective.d.ts.map +1 -1
- package/dist/Mutables/form/formAtom.d.ts +7 -5
- package/dist/Mutables/form/formAtom.d.ts.map +1 -1
- package/dist/Mutables/useStore/subscription.d.ts +1 -1
- package/dist/Mutables/useStore/subscription.d.ts.map +1 -1
- package/dist/Router/Router.d.ts +4 -5
- package/dist/Router/Router.d.ts.map +1 -1
- package/dist/Router/navigationRequest.d.ts +37 -51
- package/dist/Router/navigationRequest.d.ts.map +1 -1
- package/dist/Template/x-x.d.ts.map +1 -1
- package/dist/Template/x-x.types.d.ts +0 -22
- package/dist/Template/x-x.types.d.ts.map +1 -1
- package/dist/Template/x.d.ts.map +1 -1
- package/dist/Utils/index.d.ts +1 -0
- package/dist/Utils/index.d.ts.map +1 -1
- package/dist/Utils/logEvent.d.ts +24 -0
- package/dist/Utils/logEvent.d.ts.map +1 -0
- package/dist/Utils/logger.d.ts +24 -13
- package/dist/Utils/logger.d.ts.map +1 -1
- package/dist/Utils/onceIdle.d.ts +28 -0
- package/dist/Utils/onceIdle.d.ts.map +1 -0
- package/dist/index.d.ts +51 -6627
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +46 -40
- package/dist/index.esm.js.map +1 -1
- package/dist/indexdb/index.d.ts +3 -0
- package/dist/indexdb/index.d.ts.map +1 -0
- package/dist/indexdb/indexdb.d.ts +86 -0
- package/dist/indexdb/indexdb.d.ts.map +1 -0
- package/dist/indexdb/types.d.ts +249 -0
- package/dist/indexdb/types.d.ts.map +1 -0
- package/dist/minidb/index.d.ts +3 -0
- package/dist/minidb/index.d.ts.map +1 -0
- package/dist/minidb/minidb.d.ts +105 -0
- package/dist/minidb/minidb.d.ts.map +1 -0
- package/dist/portals/popup.d.ts.map +1 -1
- package/package.json +8 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/indexdb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,MAAM,EACN,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { DBInstanceType, IndexDBConfig } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Opens (or creates / upgrades) an IndexedDB database and returns a typed
|
|
4
|
+
* `DBInstanceType` handle.
|
|
5
|
+
*
|
|
6
|
+
* **SSR:** rejects immediately — IndexedDB is a browser-only API.
|
|
7
|
+
*
|
|
8
|
+
* @param name Database name.
|
|
9
|
+
* @param config `{ version, upgrade? }` — provide `upgrade(migrator, oldVersion)`
|
|
10
|
+
* to define the schema and handle migrations.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* interface User { id: string; name: string; age: number; role: string; createdAt: number }
|
|
15
|
+
*
|
|
16
|
+
* const db = await indexDB("app-db", {
|
|
17
|
+
* version: 2,
|
|
18
|
+
* upgrade(migrator, oldVersion) {
|
|
19
|
+
* if (oldVersion < 1) {
|
|
20
|
+
* migrator.createTable("users", "id", ["age", "role", "createdAt"]);
|
|
21
|
+
* }
|
|
22
|
+
* if (oldVersion < 2) {
|
|
23
|
+
* migrator.addIndex("users", "name");
|
|
24
|
+
* }
|
|
25
|
+
* },
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* const users = db.table<User>("users", "id");
|
|
29
|
+
*
|
|
30
|
+
* // ── Writes ───────────────────────────────────────────────────────────────
|
|
31
|
+
* await users.add({ id: "u1", name: "Alice", age: 30, role: "admin", createdAt: Date.now() });
|
|
32
|
+
* await users.set("u1", { ...updated });
|
|
33
|
+
* await users.update("u1", (u) => { u.age += 1; });
|
|
34
|
+
* await users.delete("u1");
|
|
35
|
+
* await users.clear();
|
|
36
|
+
*
|
|
37
|
+
* // ── Point reads ──────────────────────────────────────────────────────────
|
|
38
|
+
* await users.get("u1"); // User | undefined
|
|
39
|
+
* await users.has("u1"); // boolean
|
|
40
|
+
* await users.count(); // number
|
|
41
|
+
*
|
|
42
|
+
* // ── All rows ─────────────────────────────────────────────────────────────
|
|
43
|
+
* const all = await users.toArray(); // DBTableAtom<User>
|
|
44
|
+
* all(); // User[] — reactive
|
|
45
|
+
*
|
|
46
|
+
* // ── Direct pagination (cursor-based, efficient) ───────────────────────────
|
|
47
|
+
* const p1 = await users.page(1, 20); // DBTableAtom<User>
|
|
48
|
+
*
|
|
49
|
+
* // ── Native index filter — only reads matching rows ────────────────────────
|
|
50
|
+
* const admins = await users.filterByIndex("role", (r) => r.equals("admin")).toArray();
|
|
51
|
+
* const adults = await users.filterByIndex("age", (r) => r.greaterThan(18)).page(1, 20);
|
|
52
|
+
* const alices = await users.filterByIndex("name", (r) => r.startsWith("Al")).toArray();
|
|
53
|
+
* const midRange = await users.filterByIndex("age", (r) => r.between(20, 40)).toArray();
|
|
54
|
+
*
|
|
55
|
+
* // ── Native index sort — cursor-driven, no JS sort ────────────────────────
|
|
56
|
+
* const byDate = await users.sortByIndex("createdAt", "desc").page(1, 20);
|
|
57
|
+
*
|
|
58
|
+
* // ── Combined: same index → single cursor pass ─────────────────────────────
|
|
59
|
+
* const adminsByDate = await users
|
|
60
|
+
* .filterByIndex("role", (r) => r.equals("admin"))
|
|
61
|
+
* .sortByIndex("role", "asc") // same index → one cursor, zero JS
|
|
62
|
+
* .page(1, 20);
|
|
63
|
+
*
|
|
64
|
+
* // ── Combined: different indexes → filter native, sort in JS ──────────────
|
|
65
|
+
* const adultsByDate = await users
|
|
66
|
+
* .filterByIndex("age", (r) => r.greaterThan(18))
|
|
67
|
+
* .sortByIndex("createdAt", "desc") // different → JS sort on subset only
|
|
68
|
+
* .page(1, 20);
|
|
69
|
+
*
|
|
70
|
+
* // ── Item-level atom mutations (write-through to IDB) ─────────────────────
|
|
71
|
+
* await byDate.updateItem("u1", (u) => { u.name = "Bob"; });
|
|
72
|
+
* await byDate.setItem("u1", newUser);
|
|
73
|
+
* await byDate.removeItem("u1");
|
|
74
|
+
* await byDate.refresh(); // re-run query, replace atom value
|
|
75
|
+
*
|
|
76
|
+
* // ── Atomic transaction ───────────────────────────────────────────────────
|
|
77
|
+
* await db.transaction(["users", "logs"], async (tx) => {
|
|
78
|
+
* await tx.table<User>("users", "id").update("u1", (u) => { u.role = "mod"; });
|
|
79
|
+
* await tx.table<Log>("logs", "id").add({ id: "l1", userId: "u1", action: "role_change" });
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* db.close();
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function indexDB(name: string, config: IndexDBConfig): Promise<DBInstanceType>;
|
|
86
|
+
//# sourceMappingURL=indexdb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexdb.d.ts","sourceRoot":"","sources":["../../lib/indexdb/indexdb.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EAId,aAAa,EAKd,MAAM,SAAS,CAAC;AA8YjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,cAAc,CAAC,CAgFzB"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import type { AtomType } from "../Mutables/atom/atom";
|
|
2
|
+
/** Alias for the browser's `IDBValidKey` union type. */
|
|
3
|
+
export type IDBKey = IDBValidKey;
|
|
4
|
+
/**
|
|
5
|
+
* Passed to the `upgrade` callback when a database version change is detected.
|
|
6
|
+
* Use this to define or evolve the schema — create stores, add/remove indexes,
|
|
7
|
+
* or drop obsolete stores.
|
|
8
|
+
*
|
|
9
|
+
* All methods are no-ops when the target already exists (or doesn't, for
|
|
10
|
+
* removals), so conditional guards like `if (oldVersion < 2)` are sufficient
|
|
11
|
+
* without extra existence checks.
|
|
12
|
+
*/
|
|
13
|
+
export type MigratorType = {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new object store with an inline primary key.
|
|
16
|
+
* No-op if the store already exists.
|
|
17
|
+
*
|
|
18
|
+
* @param name Store name.
|
|
19
|
+
* @param primaryKey Field name used as the keyPath (inline key).
|
|
20
|
+
* @param indexes Optional secondary index field names to create.
|
|
21
|
+
*/
|
|
22
|
+
createTable(name: string, primaryKey: string, indexes?: string[]): void;
|
|
23
|
+
/**
|
|
24
|
+
* Adds a secondary index to an existing store.
|
|
25
|
+
* No-op if the index already exists.
|
|
26
|
+
*
|
|
27
|
+
* @param storeName Target object store name.
|
|
28
|
+
* @param indexName Field name to index.
|
|
29
|
+
* @param options Optional `IDBIndexParameters` (e.g. `{ unique: true }`).
|
|
30
|
+
*/
|
|
31
|
+
addIndex(storeName: string, indexName: string, options?: IDBIndexParameters): void;
|
|
32
|
+
/**
|
|
33
|
+
* Removes a secondary index from an existing store.
|
|
34
|
+
* No-op if the index does not exist.
|
|
35
|
+
*/
|
|
36
|
+
removeIndex(storeName: string, indexName: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Drops an entire object store.
|
|
39
|
+
* No-op if the store does not exist.
|
|
40
|
+
*/
|
|
41
|
+
dropTable(name: string): void;
|
|
42
|
+
};
|
|
43
|
+
export type IndexDBConfig = {
|
|
44
|
+
/** Target database version. Increment this to trigger the `upgrade` callback. */
|
|
45
|
+
version: number;
|
|
46
|
+
/**
|
|
47
|
+
* Called when the database is created or upgraded to the new `version`.
|
|
48
|
+
*
|
|
49
|
+
* @param migrator Schema helper — use `createTable`, `addIndex`, etc.
|
|
50
|
+
* @param oldVersion Previous version number (`0` for a brand-new database).
|
|
51
|
+
*/
|
|
52
|
+
upgrade?: (migrator: MigratorType, oldVersion: number) => void;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Fluent helper passed to `filterByIndex()`.
|
|
56
|
+
* Wraps the static `IDBKeyRange` factory methods with readable names.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* users.filterByIndex("age", (r) => r.greaterThan(18))
|
|
61
|
+
* users.filterByIndex("role", (r) => r.equals("admin"))
|
|
62
|
+
* users.filterByIndex("name", (r) => r.startsWith("Al"))
|
|
63
|
+
* users.filterByIndex("price",(r) => r.between(10, 100))
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export type RangeBuilder = {
|
|
67
|
+
/** Matches only the exact `value`. Wraps `IDBKeyRange.only`. */
|
|
68
|
+
equals(value: IDBValidKey): IDBKeyRange;
|
|
69
|
+
/** Matches keys strictly greater than `value`. Wraps `IDBKeyRange.lowerBound(value, true)`. */
|
|
70
|
+
greaterThan(value: IDBValidKey): IDBKeyRange;
|
|
71
|
+
/** Matches keys greater than or equal to `value`. Wraps `IDBKeyRange.lowerBound(value, false)`. */
|
|
72
|
+
greaterThanOrEqual(value: IDBValidKey): IDBKeyRange;
|
|
73
|
+
/** Matches keys strictly less than `value`. Wraps `IDBKeyRange.upperBound(value, true)`. */
|
|
74
|
+
lessThan(value: IDBValidKey): IDBKeyRange;
|
|
75
|
+
/** Matches keys less than or equal to `value`. Wraps `IDBKeyRange.upperBound(value, false)`. */
|
|
76
|
+
lessThanOrEqual(value: IDBValidKey): IDBKeyRange;
|
|
77
|
+
/**
|
|
78
|
+
* Matches keys between `lower` and `upper`.
|
|
79
|
+
* Bounds are **inclusive** by default.
|
|
80
|
+
* Wraps `IDBKeyRange.bound`.
|
|
81
|
+
*
|
|
82
|
+
* @param options.lowerOpen Exclude the lower bound (default `false`).
|
|
83
|
+
* @param options.upperOpen Exclude the upper bound (default `false`).
|
|
84
|
+
*/
|
|
85
|
+
between(lower: IDBValidKey, upper: IDBValidKey, options?: {
|
|
86
|
+
lowerOpen?: boolean;
|
|
87
|
+
upperOpen?: boolean;
|
|
88
|
+
}): IDBKeyRange;
|
|
89
|
+
/**
|
|
90
|
+
* Matches all string keys that begin with `prefix`.
|
|
91
|
+
* Uses the range `[prefix, prefix + "\uffff"]`.
|
|
92
|
+
*/
|
|
93
|
+
startsWith(prefix: string): IDBKeyRange;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Lazy, immutable native-IDB query chain returned by `filterByIndex()` and
|
|
97
|
+
* `sortByIndex()`.
|
|
98
|
+
*
|
|
99
|
+
* Nothing runs against IndexedDB until a terminal operation (`toArray` /
|
|
100
|
+
* `page`) is called. Chaining methods always return a **new** builder so the
|
|
101
|
+
* original is never mutated.
|
|
102
|
+
*
|
|
103
|
+
* @template T Row type.
|
|
104
|
+
*/
|
|
105
|
+
export type IndexQueryBuilderType<T> = {
|
|
106
|
+
/**
|
|
107
|
+
* Narrow results to a key range on a secondary index.
|
|
108
|
+
* Uses a native `IDBKeyRange` — no JS-side scanning.
|
|
109
|
+
*
|
|
110
|
+
* Replaces any previously set index filter on this chain.
|
|
111
|
+
*
|
|
112
|
+
* @param indexName Secondary index name (must exist in the schema).
|
|
113
|
+
* @param fn Receives a {@link RangeBuilder} and returns an
|
|
114
|
+
* `IDBKeyRange`.
|
|
115
|
+
*/
|
|
116
|
+
filterByIndex(indexName: string, fn: (r: RangeBuilder) => IDBKeyRange): IndexQueryBuilderType<T>;
|
|
117
|
+
/**
|
|
118
|
+
* Return rows in the natural order of a secondary index.
|
|
119
|
+
* Uses a native IDB cursor — no JS-side sort.
|
|
120
|
+
*
|
|
121
|
+
* When combined with `filterByIndex` on the **same** index, a single cursor
|
|
122
|
+
* pass performs both operations. When the indexes differ, the filter runs
|
|
123
|
+
* natively and the sort falls back to JS on the filtered subset only.
|
|
124
|
+
*
|
|
125
|
+
* @param indexName Secondary index name.
|
|
126
|
+
* @param direction `"asc"` (default) or `"desc"`.
|
|
127
|
+
*/
|
|
128
|
+
sortByIndex(indexName: string, direction?: "asc" | "desc"): IndexQueryBuilderType<T>;
|
|
129
|
+
/**
|
|
130
|
+
* Execute the query and return a reactive `DBTableAtom<T>` of all matching
|
|
131
|
+
* rows.
|
|
132
|
+
*/
|
|
133
|
+
toArray(): Promise<DBTableAtom<T>>;
|
|
134
|
+
/**
|
|
135
|
+
* Execute the query and return a reactive `DBTableAtom<T>` of one page.
|
|
136
|
+
*
|
|
137
|
+
* When `sortByIndex` is active, skipping is done via `cursor.advance()` —
|
|
138
|
+
* IDB never loads the skipped rows into memory.
|
|
139
|
+
*
|
|
140
|
+
* @param pageNum 1-based page number.
|
|
141
|
+
* @param perPage Rows per page.
|
|
142
|
+
*/
|
|
143
|
+
page(pageNum: number, perPage: number): Promise<DBTableAtom<T>>;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Reactive array atom returned by `.toArray()` / `.page()`.
|
|
147
|
+
*
|
|
148
|
+
* Behaves like a plain atom — callable (`result()`), participates in the
|
|
149
|
+
* reactive graph, has `__subscribe`, `__version__`, etc. — but replaces the
|
|
150
|
+
* generic `set` / `update` with item-level mutations that also write back to
|
|
151
|
+
* IndexedDB.
|
|
152
|
+
*
|
|
153
|
+
* @template T Row type.
|
|
154
|
+
*/
|
|
155
|
+
export type DBTableAtom<T> = Omit<AtomType<T[]>, "set" | "update"> & {
|
|
156
|
+
/**
|
|
157
|
+
* Mutate one row in-place via a draft function, then persist to IDB.
|
|
158
|
+
* No-op when the key is not found in the current snapshot.
|
|
159
|
+
*/
|
|
160
|
+
updateItem(key: IDBKey, fn: (item: T) => void): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Replace one row entirely, then persist to IDB.
|
|
163
|
+
* No-op when the key is not found in the current snapshot.
|
|
164
|
+
*/
|
|
165
|
+
setItem(key: IDBKey, item: T): Promise<void>;
|
|
166
|
+
/**
|
|
167
|
+
* Remove one row from the local snapshot and delete it from IDB.
|
|
168
|
+
* No-op when the key is not found in the current snapshot.
|
|
169
|
+
*/
|
|
170
|
+
removeItem(key: IDBKey): Promise<void>;
|
|
171
|
+
/**
|
|
172
|
+
* Re-execute the original query (filters, sort, pagination included) and
|
|
173
|
+
* replace the atom's value with the fresh results.
|
|
174
|
+
*/
|
|
175
|
+
refresh(): Promise<void>;
|
|
176
|
+
/** Discriminator tag — always `"dbTableAtom"`. */
|
|
177
|
+
readonly name: "dbTableAtom";
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Typed handle to an IndexedDB object store.
|
|
181
|
+
*
|
|
182
|
+
* Extends `IndexQueryBuilderType` — `filterByIndex`, `sortByIndex`,
|
|
183
|
+
* `toArray`, and `page` are all available directly on the table.
|
|
184
|
+
*
|
|
185
|
+
* @template T Row type.
|
|
186
|
+
*/
|
|
187
|
+
export type DBTableType<T> = IndexQueryBuilderType<T> & {
|
|
188
|
+
/**
|
|
189
|
+
* Insert a new row.
|
|
190
|
+
* Rejects when an item with the same primary key already exists.
|
|
191
|
+
*
|
|
192
|
+
* @returns The primary key of the newly inserted item.
|
|
193
|
+
*/
|
|
194
|
+
add(item: T): Promise<IDBValidKey>;
|
|
195
|
+
/**
|
|
196
|
+
* Upsert a row — insert if absent, replace if present.
|
|
197
|
+
* The key is read from the item's `keyPath` field, so it must be correct.
|
|
198
|
+
*
|
|
199
|
+
* @param key For call-site clarity; the actual IDB key comes from the
|
|
200
|
+
* item's keyPath field.
|
|
201
|
+
* @param item Full replacement item.
|
|
202
|
+
*/
|
|
203
|
+
set(key: IDBKey, item: T): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Read a row by key, apply a draft mutation, then write it back atomically.
|
|
206
|
+
* No-op when the key does not exist in the store.
|
|
207
|
+
*/
|
|
208
|
+
update(key: IDBKey, fn: (item: T) => void): Promise<void>;
|
|
209
|
+
/** Delete a row by primary key. */
|
|
210
|
+
delete(key: IDBKey): Promise<void>;
|
|
211
|
+
/** Remove **all** rows from the store. */
|
|
212
|
+
clear(): Promise<void>;
|
|
213
|
+
/** Return the total number of rows in the store. */
|
|
214
|
+
count(): Promise<number>;
|
|
215
|
+
/** Fetch a single row by primary key, or `undefined` when absent. */
|
|
216
|
+
get(key: IDBKey): Promise<T | undefined>;
|
|
217
|
+
/** Return `true` when a row with the given primary key exists. */
|
|
218
|
+
has(key: IDBKey): Promise<boolean>;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Passed to the `db.transaction()` callback.
|
|
222
|
+
* All tables obtained from this scope share the same underlying
|
|
223
|
+
* `IDBTransaction`, ensuring atomicity across stores.
|
|
224
|
+
*/
|
|
225
|
+
export type TransactionScopeType = {
|
|
226
|
+
table<T>(storeName: string, primaryKey: string): DBTableType<T>;
|
|
227
|
+
};
|
|
228
|
+
/** Opened database handle returned by `indexDB()`. */
|
|
229
|
+
export type DBInstanceType = {
|
|
230
|
+
/**
|
|
231
|
+
* Return a typed handle to an object store.
|
|
232
|
+
* The store must already exist — define it in the `upgrade` callback.
|
|
233
|
+
*/
|
|
234
|
+
table<T>(storeName: string, primaryKey: string): DBTableType<T>;
|
|
235
|
+
/**
|
|
236
|
+
* Run multiple operations inside a single atomic `readwrite` transaction.
|
|
237
|
+
*
|
|
238
|
+
* If the callback throws or rejects, the transaction is automatically
|
|
239
|
+
* aborted and the error propagates to the caller.
|
|
240
|
+
*
|
|
241
|
+
* **IDB constraint:** avoid `await`-ing non-IDB promises (e.g. `fetch`)
|
|
242
|
+
* inside the callback — the transaction may auto-commit if no IDB request
|
|
243
|
+
* is pending when the microtask queue drains.
|
|
244
|
+
*/
|
|
245
|
+
transaction(storeNames: string[], fn: (tx: TransactionScopeType) => Promise<void>): Promise<void>;
|
|
246
|
+
/** Close the database connection. */
|
|
247
|
+
close(): void;
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/indexdb/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/minidb/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,UAAU,EACV,eAAe,EACf,cAAc,GACf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type MiniDBMigrator = {
|
|
2
|
+
/** Wipe all records from a list during migration. */
|
|
3
|
+
clear(listName: string): void;
|
|
4
|
+
};
|
|
5
|
+
export type MiniDBMigrateFn = (oldVersion: number, newVersion: number, migrator: MiniDBMigrator) => void;
|
|
6
|
+
/**
|
|
7
|
+
* A reactive list backed by an IndexedDB object store.
|
|
8
|
+
*
|
|
9
|
+
* Calling `list()` returns a plain `T[]` and registers the list as a reactive
|
|
10
|
+
* dependency — components and effects re-run automatically when any item
|
|
11
|
+
* changes. The returned array is a normal JS array so `.filter()`, `.sort()`,
|
|
12
|
+
* `.map()` etc. work directly.
|
|
13
|
+
*
|
|
14
|
+
* All write methods (`add`, `set`, `update`, `deleteRow`, `clear`) are async
|
|
15
|
+
* and persist to IndexedDB before resolving. Every write is also broadcast to
|
|
16
|
+
* other tabs via `BroadcastChannel` so their atoms stay in sync.
|
|
17
|
+
*/
|
|
18
|
+
export type MiniDBList<T> = {
|
|
19
|
+
/** Reactive — returns all items as `T[]`. Tracks as a dependency. */
|
|
20
|
+
(): T[];
|
|
21
|
+
/** Reactive point lookup by id. */
|
|
22
|
+
get(id: string): T | undefined;
|
|
23
|
+
/** Reactive existence check by id. */
|
|
24
|
+
has(id: string): boolean;
|
|
25
|
+
/** Reactive item count. */
|
|
26
|
+
readonly size: number;
|
|
27
|
+
/**
|
|
28
|
+
* Add an item. Uses the item's `id` field as the key when present,
|
|
29
|
+
* otherwise auto-generates a UUID and assigns it.
|
|
30
|
+
* @returns The id used.
|
|
31
|
+
*/
|
|
32
|
+
add(item: T): Promise<string>;
|
|
33
|
+
/** Upsert — insert if absent, replace if present. */
|
|
34
|
+
set(id: string, item: T): Promise<void>;
|
|
35
|
+
/** Draft-style mutation — modify the item in-place, then persist. */
|
|
36
|
+
update(id: string, fn: (item: T) => void): Promise<void>;
|
|
37
|
+
/** Delete one item by id. */
|
|
38
|
+
deleteRow(id: string): Promise<void>;
|
|
39
|
+
/** Remove all items from the list. */
|
|
40
|
+
clear(): Promise<void>;
|
|
41
|
+
};
|
|
42
|
+
export type MiniDBInstance = {
|
|
43
|
+
/**
|
|
44
|
+
* Returns a reactive list for the given name.
|
|
45
|
+
* The underlying IDB object store is created automatically on first call.
|
|
46
|
+
*
|
|
47
|
+
* Await calls sequentially when requesting multiple new lists — each new
|
|
48
|
+
* list may internally close and reopen the database to add the store.
|
|
49
|
+
*/
|
|
50
|
+
list<T>(name: string): Promise<MiniDBList<T>>;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Opens (or creates) the opinionated `"mini-db"` IndexedDB database.
|
|
54
|
+
*
|
|
55
|
+
* - **Fixed name** — always `"mini-db"`, cannot be changed.
|
|
56
|
+
* - **No schema** — object stores are created automatically on first
|
|
57
|
+
* `db.list()` call.
|
|
58
|
+
* - **Designed for ≤ 1 000 records per list** — all data is held in memory
|
|
59
|
+
* as a reactive `mapAtom`. Components re-render automatically on any write.
|
|
60
|
+
* - **No cursors, no indexes, no query builder** — use plain JS array methods
|
|
61
|
+
* (`filter`, `sort`, `map`, …) on the result of `list()`.
|
|
62
|
+
* - **Cross-tab sync** — writes broadcast via `BroadcastChannel` so every
|
|
63
|
+
* open tab's atoms reflect changes immediately without polling.
|
|
64
|
+
*
|
|
65
|
+
* @param version App-level data version (default `1`). Increment to
|
|
66
|
+
* trigger the `onMigrate` callback.
|
|
67
|
+
* @param onMigrate Called once when `version` changes. Use
|
|
68
|
+
* `migrator.clear("listName")` to wipe stale data.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* interface User { id: string; name: string; role: string }
|
|
73
|
+
*
|
|
74
|
+
* // One shared instance — open at module level, export and reuse everywhere.
|
|
75
|
+
* export const db = await miniDB(2, (oldV, newV, m) => {
|
|
76
|
+
* if (oldV < 2) m.clear("users");
|
|
77
|
+
* });
|
|
78
|
+
*
|
|
79
|
+
* const users = await db.list<User>("users");
|
|
80
|
+
*
|
|
81
|
+
* // ── Reactive template ─────────────────────────────────────────────────────
|
|
82
|
+
* html`
|
|
83
|
+
* ${users()
|
|
84
|
+
* .filter(u => u.role === "admin")
|
|
85
|
+
* .sort((a, b) => a.name.localeCompare(b.name))
|
|
86
|
+
* .map(u => html`<li>${u.name}</li>`)}
|
|
87
|
+
* `
|
|
88
|
+
*
|
|
89
|
+
* // ── Writes (IDB + atom + broadcast to other tabs) ─────────────────────────
|
|
90
|
+
* await users.add({ id: "u1", name: "Alice", role: "admin" });
|
|
91
|
+
* await users.add({ name: "Bob", role: "user" }); // auto-generates id
|
|
92
|
+
* await users.set("u1", { id: "u1", name: "Alice B.", role: "admin" });
|
|
93
|
+
* await users.update("u1", u => { u.role = "mod"; });
|
|
94
|
+
* await users.deleteRow("u1");
|
|
95
|
+
* await users.clear();
|
|
96
|
+
*
|
|
97
|
+
* // ── Reactive reads ────────────────────────────────────────────────────────
|
|
98
|
+
* users(); // User[]
|
|
99
|
+
* users.get("u1"); // User | undefined
|
|
100
|
+
* users.has("u1"); // boolean
|
|
101
|
+
* users.size; // number
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare function miniDB(version?: number, onMigrate?: MiniDBMigrateFn): Promise<MiniDBInstance>;
|
|
105
|
+
//# sourceMappingURL=minidb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minidb.d.ts","sourceRoot":"","sources":["../../lib/minidb/minidb.ts"],"names":[],"mappings":"AAgDA,MAAM,MAAM,cAAc,GAAG;IAC3B,qDAAqD;IACrD,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAC5B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,KACrB,IAAI,CAAC;AAEV;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,qEAAqE;IACrE,IAAI,CAAC,EAAE,CAAC;IACR,mCAAmC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IAC/B,sCAAsC;IACtC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,qDAAqD;IACrD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,qEAAqE;IACrE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,6BAA6B;IAC7B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,sCAAsC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAC;AAwNF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,MAAM,CAC1B,OAAO,SAAI,EACX,SAAS,CAAC,EAAE,eAAe,GAC1B,OAAO,CAAC,cAAc,CAAC,CAqDzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popup.d.ts","sourceRoot":"","sources":["../../lib/portals/popup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"popup.d.ts","sourceRoot":"","sources":["../../lib/portals/popup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,OAAO,CAAC;IACZ,GAAG,IAAI,OAAO,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;AAErD,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/D;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAgQD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,cAAc,EACvB,iBAAiB,CAAC,EAAE,cAAc,GAAG,YAAY,GAChD,eAAe,CAMjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mates",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Mates is a front end framework for building web applications",
|
|
6
6
|
"main": "dist/index.esm.js",
|
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
11
12
|
"import": "./dist/index.esm.js",
|
|
12
|
-
"require": "./dist/index.js"
|
|
13
|
-
"types": "./dist/index.d.ts"
|
|
13
|
+
"require": "./dist/index.js"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "rollup -c",
|
|
20
|
+
"build": "rollup -c && tsc -p tsconfig.declarations.json",
|
|
21
21
|
"dev": "rollup -c -w",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test:watch": "vitest",
|
|
@@ -67,10 +67,10 @@
|
|
|
67
67
|
"csstype": "^3.1.3",
|
|
68
68
|
"esbuild": "^0.25.9",
|
|
69
69
|
"eslint": "^8.54.0",
|
|
70
|
+
"fake-indexeddb": "^6.2.5",
|
|
70
71
|
"happy-dom": "^20.5.0",
|
|
71
72
|
"jest": "^29.7.0",
|
|
72
73
|
"jest-environment-jsdom": "^30.0.5",
|
|
73
|
-
"lit-html": "3.2.1",
|
|
74
74
|
"rimraf": "^5.0.5",
|
|
75
75
|
"rollup": "^3.29.4",
|
|
76
76
|
"rollup-plugin-css-only": "^4.5.5",
|
|
@@ -79,5 +79,8 @@
|
|
|
79
79
|
"tslib": "^2.8.1",
|
|
80
80
|
"typescript": "^5.3.2",
|
|
81
81
|
"vitest": "^4.0.18"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"lit-html": "3.2.1"
|
|
82
85
|
}
|
|
83
86
|
}
|