@bodil/bdb 0.1.2 → 0.2.0

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/table.js CHANGED
@@ -8,18 +8,105 @@ import BTree from "sorted-btree";
8
8
  import { CustomIndex } from "./indices";
9
9
  import { IndexQuery, IteratorDirection } from "./query";
10
10
  import { TableStorage } from "./storage";
11
+ /**
12
+ * A database table.
13
+ *
14
+ * To learn how to create a table, see the static method {@link Table.create}.
15
+ *
16
+ * @template Document The type of the documents this table stores.
17
+ */
11
18
  export class Table extends Emitter {
19
+ /**
20
+ * A promise which resolves when this table is ready to use.
21
+ *
22
+ * If the table isn't connected to a {@link StorageBackend}, this is a
23
+ * promise which resolves immediately, and you don't really need to await
24
+ * it. The table will be ready for use immediately.
25
+ *
26
+ * With an attached {@link StorageBackend}, this promise will resolve when
27
+ * the table has finished restoring its contents from the storage. You
28
+ * should not under any circumstances use the table before this is complete.
29
+ */
30
+ get ready() {
31
+ return this.#ready;
32
+ }
33
+ #ready;
34
+ #changed;
35
+ /**
36
+ * A signal which updates whenever the table has been modified.
37
+ */
38
+ get changed() {
39
+ return this.#changed.readOnly;
40
+ }
12
41
  #storage;
13
42
  #signals;
14
43
  #signalCleanupRegistry;
15
44
  #context;
45
+ /**
46
+ * Create a database {@link Table}.
47
+ *
48
+ * `Table.create` is a function which takes one type argument, the type of the
49
+ * object (which we'll call a *document*) you want the table to store, and no
50
+ * value arguments.
51
+ *
52
+ * This returns an object with one method: `withPrimaryIndex`. This method is
53
+ * what actually creates the table. So, the full incantation is, for instance:
54
+ *
55
+ * ```ts
56
+ * type Document = { id: string; value: number };
57
+ * const table = Table.create<Document>()
58
+ * .withPrimaryIndex(index<Document>().key("id"));
59
+ * ```
60
+ *
61
+ * In order to look up something in a database table, you need an index. You can
62
+ * create an index using the {@link index} function, which, like `Table.create`,
63
+ * takes the document you're creating an index for as its type argument, and
64
+ * returns a selection of index constructors, of which the most straightforward
65
+ * one is {@link IndexConstructor.key}. This creates an index for a single named
66
+ * property of the document containing a primitive comparable value (a string, a
67
+ * number, or a bigint), and allows you to search for documents where the given
68
+ * property matches any given value. You can also create an index over multiple
69
+ * keys using {@link IndexConstructor.keys} or over a key containing an array
70
+ * using {@link IndexConstructor.array}. You can even create a completely
71
+ * customised index using {@link IndexConstructor.custom}.
72
+ *
73
+ * The primary index, unlike a regular index, is a unique identifier, and only
74
+ * one document can exist at any given time under the key or keys represented by
75
+ * the primary index. A table is required to have a primary index, which is why
76
+ * `Table.create` doesn't actually create the table until you call
77
+ * `withPrimaryIndex` on it. You can then add as many extra indices as you like
78
+ * using `withIndex`. To extend our example above with an additional index over
79
+ * the `value` property:
80
+ *
81
+ * ```ts
82
+ * type Document = { id: string; value: number };
83
+ * const table = Table.create<Document>()
84
+ * .withPrimaryIndex(index<Document>().key("id"))
85
+ * .withIndex(index<Document>().key("value"));
86
+ * ```
87
+ *
88
+ * @see {@link index}
89
+ *
90
+ * @template Document The type of the document this table stores.
91
+ */
92
+ static create() {
93
+ return {
94
+ withPrimaryIndex(primaryIndex) {
95
+ return new Table(primaryIndex);
96
+ },
97
+ };
98
+ }
99
+ /** @internal */
16
100
  constructor(primaryIndex) {
17
101
  super();
18
- this.ready = Promise.resolve();
102
+ this.#ready = Promise.resolve();
103
+ /** @ignore */
19
104
  this.primary = new BTree();
105
+ /** @ignore */
20
106
  this.indices = {};
107
+ /** @ignore */
21
108
  this.indexTables = {};
22
- this.changed = Signal.from(0);
109
+ this.#changed = Signal.from(null, { equals: () => false });
23
110
  this.#signals = new BTree();
24
111
  this.#signalCleanupRegistry = new FinalizationRegistry(this.#signalCleanup.bind(this));
25
112
  this.#context = new DisposableContext();
@@ -29,6 +116,15 @@ export class Table extends Emitter {
29
116
  super[Symbol.dispose]();
30
117
  this.#context.dispose();
31
118
  }
119
+ /**
120
+ * Add an index to a table.
121
+ *
122
+ * @example
123
+ * type Document = { id: string; value: number };
124
+ * const table = Table.create<Document>()
125
+ * .withPrimaryIndex(index<Document>().key("id"))
126
+ * .withIndex(index<Document>().key("value"));
127
+ */
32
128
  withIndex(index) {
33
129
  assert(this.indices[index.name] === undefined, `duplicate index definition: "${index.name}"`);
34
130
  this.indices[index.name] = index;
@@ -36,9 +132,14 @@ export class Table extends Emitter {
36
132
  index instanceof CustomIndex ? index.makeIndex() : new BTree();
37
133
  return this;
38
134
  }
135
+ /**
136
+ * Attach a table to a {@link StorageBackend}.
137
+ *
138
+ * See {@link IndexedDBBackend.open} for an example of how to use this.
139
+ */
39
140
  withStorage(backend, name) {
40
141
  this.#storage = new TableStorage(backend, name, this.primaryIndex);
41
- this.ready = this.#storage.ready;
142
+ this.#ready = this.#storage.ready;
42
143
  this.#context.use(this.#storage.on((event) => {
43
144
  switch (event.type) {
44
145
  case "update":
@@ -55,14 +156,14 @@ export class Table extends Emitter {
55
156
  signal(primaryKey) {
56
157
  const active = this.#signals.get(primaryKey)?.deref();
57
158
  if (active !== undefined) {
58
- return active.readOnly();
159
+ return active.readOnly;
59
160
  }
60
161
  const sig = Signal.from(this.get(primaryKey), {
61
162
  equals: () => false,
62
163
  });
63
164
  this.#signalCleanupRegistry.register(sig, primaryKey);
64
165
  this.#signals.set(primaryKey, new WeakRef(sig));
65
- return sig.readOnly();
166
+ return sig.readOnly;
66
167
  }
67
168
  get(primaryKey) {
68
169
  return this.primary.get(primaryKey);
@@ -78,9 +179,18 @@ export class Table extends Emitter {
78
179
  return this.#setItem(item, oldItem, primaryKey);
79
180
  }
80
181
  /**
81
- * Given a primary key, apply an update function to the value stored under
82
- * that key. If there's no value, call the create function to create a new
83
- * value. In this case, the update function is not called.
182
+ * Create or update a document.
183
+ *
184
+ * Given a primary key, apply the `update` function to the document stored
185
+ * under that key.
186
+ *
187
+ * If there's no such document, call the `create` function to create a new
188
+ * document and insert that under the given primary key. In this case, the
189
+ * update function is not called.
190
+ *
191
+ * The `update` function is passed to {@link produce | Immer.produce} to
192
+ * perform the update. It should modify the provided document in place, and
193
+ * it's not necessary to return it.
84
194
  */
85
195
  createOrUpdate(primaryKey, create, update) {
86
196
  const oldItem = this.primary.get(primaryKey);
@@ -88,9 +198,17 @@ export class Table extends Emitter {
88
198
  return this.#setItem(item, oldItem, primaryKey);
89
199
  }
90
200
  /**
91
- * Apply an update function to the value stored under the given primary key.
92
- * If no value exists, the update function is not called and `undefined` is
93
- * returned. Otherwise, the updated value is returned.
201
+ * Update a document.
202
+ *
203
+ * Apply the `update` function to the document stored under the given
204
+ * primary key.
205
+ *
206
+ * If no such document exists, the update function is not called and
207
+ * `undefined` is returned. Otherwise, the updated document is returned.
208
+ *
209
+ * The `update` function is passed to {@link produce | Immer.produce} to
210
+ * perform the update. It should modify the provided document in place, and
211
+ * it's not necessary to return it.
94
212
  */
95
213
  update(primaryKey, update) {
96
214
  const oldItem = this.primary.get(primaryKey);
@@ -107,20 +225,34 @@ export class Table extends Emitter {
107
225
  return this.#deleteFrom(items.length === 1 && isIterable(items[0]) ? items[0] : items);
108
226
  }
109
227
  /**
110
- * Delete all data from the table.
228
+ * Delete all documents from the table.
111
229
  */
112
230
  clear() {
113
231
  this.delete(...this.primary.keys());
114
232
  }
233
+ /**
234
+ * Iterate over the documents in the table, ordered by primary key.
235
+ */
115
236
  [Symbol.iterator]() {
116
- return this.primary.values();
237
+ return Iterator.from(this.primary.values());
117
238
  }
239
+ /**
240
+ * Perform an {@link IndexQuery} using the specified index.
241
+ */
118
242
  where(index) {
119
243
  return new IndexQuery(this, index, IteratorDirection.Ascending);
120
244
  }
245
+ /**
246
+ * Perform an {@link IndexQuery} using the specified index.
247
+ *
248
+ * This is an alias for {@link Table.where}.
249
+ */
121
250
  orderBy(index) {
122
251
  return this.where(index);
123
252
  }
253
+ /**
254
+ * Get the number of documents currently stored in the table.
255
+ */
124
256
  size() {
125
257
  return this.primary.size;
126
258
  }
@@ -176,7 +308,7 @@ export class Table extends Emitter {
176
308
  // emit an update event and update signals
177
309
  this.#withSignal(this.primaryIndex.extractKey(item), (sig) => sig.set(item));
178
310
  this.emit({ type: "update", item });
179
- this.changed.update((i) => i + 1);
311
+ this.#changed.set(null);
180
312
  return item;
181
313
  }
182
314
  #deleteItem(item, primaryKey) {
@@ -187,7 +319,7 @@ export class Table extends Emitter {
187
319
  // emit a delete event and update signals
188
320
  this.#withSignal(primaryKey, (sig) => sig.set(undefined));
189
321
  this.emit({ type: "delete", key: primaryKey });
190
- this.changed.update((i) => i + 1);
322
+ this.#changed.set(null);
191
323
  }
192
324
  #withSignal(primaryKey, fn) {
193
325
  const sigRef = this.#signals.get(primaryKey);
package/dist/table.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type IndexablePrimitive = string | number | null | undefined | bigint;
1
+ export type IndexablePrimitive = string | number | bigint;
2
2
  export type IndexableType = IndexablePrimitive | Array<IndexablePrimitive> | ReadonlyArray<IndexablePrimitive>;
3
3
  export type CustomIndexablesOf<A, T> = string & keyof A & {
4
4
  [Key in keyof A]: A[Key] extends T ? Key : never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bodil/bdb",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "A signal enabled database",
5
5
  "homepage": "https://codeberg.org/bodil/bdb",
6
6
  "repository": {
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@bodil/core": "^0.5.2",
30
- "@bodil/opt": "^0.4.3",
31
- "@bodil/signal": "^0.4.0",
30
+ "@bodil/opt": "^1.0.0",
31
+ "@bodil/signal": "^0.5.1",
32
32
  "immer": "^11.1.3",
33
33
  "sorted-btree": "2.1.0"
34
34
  },
package/src/backend.ts CHANGED
@@ -4,9 +4,18 @@ import type { IndexablePrimitive } from "./types";
4
4
 
5
5
  export type DatabaseBroadcast = { event: "update" | "delete"; table: string; key: unknown };
6
6
 
7
+ /**
8
+ * Configuration for IndexedDB backends.
9
+ */
7
10
  export type IndexedDBBackendConfig = {
11
+ /** Name of the IndexedDB database to connect to. */
8
12
  name: string;
13
+ /** Version number of the database. */
9
14
  version: number;
15
+ /**
16
+ * Name of the IndexedDB database table to store our database in. Defaults
17
+ * to `"store"`.
18
+ */
10
19
  table?: string;
11
20
  };
12
21
 
@@ -27,6 +36,9 @@ function unpackRecord<A = unknown>(record: StorageRecord): A {
27
36
  return deserialise(record.value) as A;
28
37
  }
29
38
 
39
+ /**
40
+ * Base class for storage backends.
41
+ */
30
42
  export abstract class StorageBackend {
31
43
  readonly name: string;
32
44
 
@@ -49,12 +61,36 @@ export abstract class StorageBackend {
49
61
  }
50
62
  }
51
63
 
64
+ /**
65
+ * Storage backend using an IndexedDB database.
66
+ *
67
+ * Use {@link IndexedDBBackend.open} to obtain a storage backend connected to
68
+ * the specified IndexedDB database.
69
+ *
70
+ * @example
71
+ * // Connect to the IndexedDB database.
72
+ * const storage = await IndexedDBBackend.open("my-docs", 1);
73
+ * // Declare a document type.
74
+ * type Document = { id: string; value: number };
75
+ * // Create the table.
76
+ * const docs = Table.create<Document>()
77
+ * .withPrimaryKey(index<Document>().key("id"))
78
+ * // Connect the table to our storage.
79
+ * .withStorage(storage);
80
+ * // Wait until the table has finished syncing with the storage.
81
+ * await docs.ready;
82
+ * // Ready for use!
83
+ * docs.add({ id: "Robert", value: 9001 });
84
+ */
52
85
  export class IndexedDBBackend extends StorageBackend {
53
86
  private db?: IDBDatabase;
54
87
 
55
88
  readonly version: number;
56
89
  readonly table: string;
57
90
 
91
+ /**
92
+ * Connect to an IndexedDB database.
93
+ */
58
94
  static async open(config: IndexedDBBackendConfig): Promise<IndexedDBBackend> {
59
95
  const c = { ...backendConfigDefaults, ...config };
60
96
  const storage = new IndexedDBBackend(c.name, c.version, c.table);
@@ -107,6 +143,7 @@ export class IndexedDBBackend extends StorageBackend {
107
143
  });
108
144
  }
109
145
 
146
+ /** @internal */
110
147
  async get<A = unknown>(table: string, key: unknown): Promise<A> {
111
148
  const value: StorageRecord = await this.transaction("readonly", (store) => {
112
149
  return request(store.get([table, key] as IDBValidKey));
@@ -114,6 +151,7 @@ export class IndexedDBBackend extends StorageBackend {
114
151
  return unpackRecord(value);
115
152
  }
116
153
 
154
+ /** @internal */
117
155
  async getAll<A = unknown>(table: string): Promise<Array<A>> {
118
156
  const values = await this.transaction("readonly", (store) => {
119
157
  return request(store.index("table").getAll(table));
@@ -121,6 +159,7 @@ export class IndexedDBBackend extends StorageBackend {
121
159
  return (values as Array<StorageRecord>).map(unpackRecord<A>);
122
160
  }
123
161
 
162
+ /** @internal */
124
163
  async update(table: string, key: unknown, value: unknown): Promise<void> {
125
164
  await this.transaction("readwrite", (store) => {
126
165
  return request(store.put({ table, key, value: serialise(value) }));
@@ -128,6 +167,7 @@ export class IndexedDBBackend extends StorageBackend {
128
167
  this.broadcast?.send({ event: "update", table, key });
129
168
  }
130
169
 
170
+ /** @internal */
131
171
  async delete(table: string, key: unknown): Promise<void> {
132
172
  await this.transaction("readwrite", (store) => {
133
173
  return request(store.delete([table, key as IDBValidKey]));
package/src/index.test.ts CHANGED
@@ -6,7 +6,7 @@ import { sleep } from "@bodil/core/async";
6
6
  import { Signal } from "@bodil/signal";
7
7
  import { expect, expectTypeOf, test } from "vitest";
8
8
 
9
- import { arrayIndex, compoundIndex, createTable, index, timeIndex } from ".";
9
+ import { index, Table } from ".";
10
10
  import { IndexedDBBackend } from "./backend";
11
11
  import type { IndexablesOf } from "./types";
12
12
 
@@ -34,11 +34,12 @@ test("memdb basics", () => {
34
34
  tags: Array<string>;
35
35
  };
36
36
 
37
- const table = createTable<TestItem>()(index<TestItem>()("id"))
38
- .withIndex(timeIndex<TestItem>()("created"))
39
- .withIndex(index<TestItem>()("uri"))
40
- .withIndex(arrayIndex<TestItem>()("tags"))
41
- .withIndex(compoundIndex<TestItem>()("id", "uri"));
37
+ const table = Table.create<TestItem>()
38
+ .withPrimaryIndex(index<TestItem>().key("id"))
39
+ .withIndex(index<TestItem>().time("created"))
40
+ .withIndex(index<TestItem>().key("uri"))
41
+ .withIndex(index<TestItem>().array("tags"))
42
+ .withIndex(index<TestItem>().keys("id", "uri"));
42
43
 
43
44
  const now = time.now();
44
45
  const [welp, wolp, wulp, wilp] = [
@@ -115,9 +116,9 @@ test("memdb basics", () => {
115
116
 
116
117
  test("memdb index dupes", () => {
117
118
  type Account = { id: string; order: number };
118
- const accounts = createTable<Account>()(index<Account>()("id")).withIndex(
119
- index<Account>()("order"),
120
- );
119
+ const accounts = Table.create<Account>()
120
+ .withPrimaryIndex(index<Account>().key("id"))
121
+ .withIndex(index<Account>().key("order"));
121
122
 
122
123
  const account = { id: "test@test.com", order: 1 };
123
124
  accounts.add({ ...account });
@@ -128,10 +129,10 @@ test("memdb index dupes", () => {
128
129
 
129
130
  test("memdb signals", () => {
130
131
  type Thing = { name: string; counter: number };
131
- const things = createTable<Thing>()(index<Thing>()("name"));
132
+ const things = Table.create<Thing>().withPrimaryIndex(index<Thing>().key("name"));
132
133
 
133
134
  type ThingMap = { id: number; name: string };
134
- const thingMaps = createTable<ThingMap>()(index<ThingMap>()("id"));
135
+ const thingMaps = Table.create<ThingMap>().withPrimaryIndex(index<ThingMap>().key("id"));
135
136
  thingMaps.add({ id: 1, name: "Mike" }, { id: 2, name: "Robert" });
136
137
 
137
138
  const joe = things.signal("Joe");
@@ -163,7 +164,7 @@ test("memdb signals", () => {
163
164
 
164
165
  test("failed update shouldn't change anything", () => {
165
166
  type Thing = { name: string; counter: number };
166
- const things = createTable<Thing>()(index<Thing>()("name"));
167
+ const things = Table.create<Thing>().withPrimaryIndex(index<Thing>().key("name"));
167
168
 
168
169
  things.add({ name: "Joe", counter: 321 });
169
170
  expect(() =>
@@ -181,8 +182,9 @@ test("IndexedDB", async () => {
181
182
  const before = now.subtract(time.seconds(25));
182
183
  {
183
184
  const store = await IndexedDBBackend.open({ name: "test", version: 1 });
184
- const things = createTable<Thing>()(index<Thing>()("key"))
185
- .withIndex(timeIndex<Thing>()("time"))
185
+ const things = Table.create<Thing>()
186
+ .withPrimaryIndex(index<Thing>().key("key"))
187
+ .withIndex(index<Thing>().time("time"))
186
188
  .withStorage(store, "things");
187
189
  await things.ready;
188
190
  things.add(
@@ -199,8 +201,9 @@ test("IndexedDB", async () => {
199
201
  }
200
202
  {
201
203
  const store = await IndexedDBBackend.open({ name: "test", version: 1 });
202
- const things = createTable<Thing>()(index<Thing>()("key"))
203
- .withIndex(timeIndex<Thing>()("time"))
204
+ const things = Table.create<Thing>()
205
+ .withPrimaryIndex(index<Thing>().key("key"))
206
+ .withIndex(index<Thing>().time("time"))
204
207
  .withStorage(store, "things");
205
208
  await things.ready;
206
209
  expect(things.get("Joe")).deep.equal({ key: "Joe", value: "Armstrong", time: now });
@@ -210,3 +213,68 @@ test("IndexedDB", async () => {
210
213
  ]);
211
214
  }
212
215
  });
216
+
217
+ test("query.below/query.above", () => {
218
+ type Item = { id: string; value: number };
219
+ const table = Table.create<Item>()
220
+ .withPrimaryIndex(index<Item>().key("id"))
221
+ .withIndex(index<Item>().key("value"));
222
+ table.add(
223
+ { id: "1", value: 1 },
224
+ { id: "2", value: 2 },
225
+ { id: "3", value: 3 },
226
+ { id: "4", value: 4 },
227
+ { id: "5", value: 5 },
228
+ );
229
+ expect(
230
+ table
231
+ .where("value")
232
+ .below(3)
233
+ .toArray()
234
+ .map((i) => i.value),
235
+ ).toEqual([2, 1]);
236
+ expect(
237
+ table
238
+ .where("value")
239
+ .below(3)
240
+ .inclusive()
241
+ .toArray()
242
+ .map((i) => i.value),
243
+ ).toEqual([3, 2, 1]);
244
+ expect(
245
+ table
246
+ .where("value")
247
+ .above(3)
248
+ .toArray()
249
+ .map((i) => i.value),
250
+ ).toEqual([4, 5]);
251
+ expect(
252
+ table
253
+ .where("value")
254
+ .above(3)
255
+ .inclusive()
256
+ .toArray()
257
+ .map((i) => i.value),
258
+ ).toEqual([3, 4, 5]);
259
+ });
260
+
261
+ test("query.delete()", () => {
262
+ type Doc = { id: number };
263
+ const table = Table.create<Doc>().withPrimaryIndex(index<Doc>().key("id"));
264
+ for (let id = 0; id < 10; id++) {
265
+ table.add({ id });
266
+ }
267
+
268
+ const ids = table
269
+ .where("id")
270
+ .signal()
271
+ .map((docs) => docs.map((doc) => doc.id));
272
+ expect(ids.get()).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
273
+
274
+ expect(table.where("id").above(5).delete()).toEqual(4);
275
+ expect(
276
+ Iterator.from(table)
277
+ .map((doc) => doc.id)
278
+ .toArray(),
279
+ ).toEqual([0, 1, 2, 3, 4, 5]);
280
+ });