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.
Files changed (37) hide show
  1. package/dist/Directives/onDirective.d.ts.map +1 -1
  2. package/dist/Mutables/form/formAtom.d.ts +7 -5
  3. package/dist/Mutables/form/formAtom.d.ts.map +1 -1
  4. package/dist/Mutables/useStore/subscription.d.ts +1 -1
  5. package/dist/Mutables/useStore/subscription.d.ts.map +1 -1
  6. package/dist/Router/Router.d.ts +4 -5
  7. package/dist/Router/Router.d.ts.map +1 -1
  8. package/dist/Router/navigationRequest.d.ts +37 -51
  9. package/dist/Router/navigationRequest.d.ts.map +1 -1
  10. package/dist/Template/x-x.d.ts.map +1 -1
  11. package/dist/Template/x-x.types.d.ts +0 -22
  12. package/dist/Template/x-x.types.d.ts.map +1 -1
  13. package/dist/Template/x.d.ts.map +1 -1
  14. package/dist/Utils/index.d.ts +1 -0
  15. package/dist/Utils/index.d.ts.map +1 -1
  16. package/dist/Utils/logEvent.d.ts +24 -0
  17. package/dist/Utils/logEvent.d.ts.map +1 -0
  18. package/dist/Utils/logger.d.ts +24 -13
  19. package/dist/Utils/logger.d.ts.map +1 -1
  20. package/dist/Utils/onceIdle.d.ts +28 -0
  21. package/dist/Utils/onceIdle.d.ts.map +1 -0
  22. package/dist/index.d.ts +51 -6627
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.esm.js +46 -40
  25. package/dist/index.esm.js.map +1 -1
  26. package/dist/indexdb/index.d.ts +3 -0
  27. package/dist/indexdb/index.d.ts.map +1 -0
  28. package/dist/indexdb/indexdb.d.ts +86 -0
  29. package/dist/indexdb/indexdb.d.ts.map +1 -0
  30. package/dist/indexdb/types.d.ts +249 -0
  31. package/dist/indexdb/types.d.ts.map +1 -0
  32. package/dist/minidb/index.d.ts +3 -0
  33. package/dist/minidb/index.d.ts.map +1 -0
  34. package/dist/minidb/minidb.d.ts +105 -0
  35. package/dist/minidb/minidb.d.ts.map +1 -0
  36. package/dist/portals/popup.d.ts.map +1 -1
  37. package/package.json +8 -5
@@ -0,0 +1,3 @@
1
+ export { indexDB } from "./indexdb";
2
+ export type { DBInstanceType, DBTableAtom, DBTableType, IDBKey, IndexDBConfig, IndexQueryBuilderType, MigratorType, RangeBuilder, TransactionScopeType, } from "./types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,3 @@
1
+ export type { MiniDBInstance, MiniDBList, MiniDBMigrateFn, MiniDBMigrator, } from "./minidb";
2
+ export { miniDB } from "./minidb";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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;AAWvD;;;;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"}
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.0",
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
  }