@bodil/bdb 0.1.3 → 0.2.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/dist/indices.js CHANGED
@@ -1,7 +1,10 @@
1
+ /** @internal */
1
2
  export class Index {
2
3
  }
4
+ /** @internal */
3
5
  export class UnitIndex extends Index {
4
6
  }
7
+ /** @internal */
5
8
  export class CustomIndex {
6
9
  constructor(index, makeIndex) {
7
10
  this.index = index;
@@ -17,6 +20,7 @@ export class CustomIndex {
17
20
  return [value[this.index]];
18
21
  }
19
22
  }
23
+ /** @internal */
20
24
  export class PrimitiveIndex {
21
25
  constructor(index) {
22
26
  this.index = index;
@@ -31,6 +35,7 @@ export class PrimitiveIndex {
31
35
  return [value[this.index]];
32
36
  }
33
37
  }
38
+ /** @internal */
34
39
  export class ArrayIndex {
35
40
  constructor(index) {
36
41
  this.index = index;
@@ -40,6 +45,7 @@ export class ArrayIndex {
40
45
  return value[this.index];
41
46
  }
42
47
  }
48
+ /** @internal */
43
49
  export class CompoundIndex {
44
50
  constructor(leftIndex, rightIndex) {
45
51
  this.leftIndex = leftIndex;
@@ -1 +1 @@
1
- {"version":3,"file":"indices.js","sourceRoot":"","sources":["../src/indices.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,KAAK;CAK1B;AAED,MAAM,OAAgB,SAA4B,SAAQ,KAAQ;CAEjE;AAED,MAAM,OAAO,WAAW;IAMpB,YACoB,KAAQ,EACR,SAAsC;QADtC,UAAK,GAAL,KAAK,CAAG;QACR,cAAS,GAAT,SAAS,CAA6B;IACvD,CAAC;IAEJ,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;CACJ;AAED,MAAM,OAAO,cAAc;IAMvB,YAA4B,KAAQ;QAAR,UAAK,GAAL,KAAK,CAAG;IAAG,CAAC;IAExC,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;CACJ;AAED,MAAM,OAAO,UAAU;IAWnB,YAAY,KAAQ;QAChB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAM,CAAC;IAClC,CAAC;CACJ;AAED,MAAM,OAAO,aAAa;IAatB,YAAY,SAAY,EAAE,UAAa;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IAC7C,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;CACJ"}
1
+ {"version":3,"file":"indices.js","sourceRoot":"","sources":["../src/indices.ts"],"names":[],"mappings":"AAIA,gBAAgB;AAChB,MAAM,OAAgB,KAAK;CAK1B;AAED,gBAAgB;AAChB,MAAM,OAAgB,SAA4B,SAAQ,KAAQ;CAEjE;AAED,gBAAgB;AAChB,MAAM,OAAO,WAAW;IAMpB,YACoB,KAAQ,EACR,SAAsC;QADtC,UAAK,GAAL,KAAK,CAAG;QACR,cAAS,GAAT,SAAS,CAA6B;IACvD,CAAC;IAEJ,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;CACJ;AAED,gBAAgB;AAChB,MAAM,OAAO,cAAc;IAMvB,YAA4B,KAAQ;QAAR,UAAK,GAAL,KAAK,CAAG;IAAG,CAAC;IAExC,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;CACJ;AAED,gBAAgB;AAChB,MAAM,OAAO,UAAU;IAUnB,YAAY,KAAQ;QAChB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAM,CAAC;IAClC,CAAC;CACJ;AAED,gBAAgB;AAChB,MAAM,OAAO,aAAa;IAatB,YAAY,SAAY,EAAE,UAAa;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IAC7C,CAAC;IAED,UAAU,CAAC,KAAQ;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,WAAW,CAAC,KAAQ;QAChB,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;CACJ"}
package/dist/query.d.ts CHANGED
@@ -6,46 +6,49 @@ export declare enum IteratorDirection {
6
6
  Ascending = 0,
7
7
  Descending = 1
8
8
  }
9
- export declare abstract class Query<A extends object> implements Iterable<Readonly<A>> {
10
- abstract [Symbol.iterator](): IterableIterator<Readonly<A>>;
11
- abstract signal(): Signal.Computed<Array<Readonly<A>>>;
12
- map<B>(mapFn: (item: Readonly<A>) => B): IterableIterator<B>;
13
- forEach(action: (item: A) => void): void;
14
- toArray(): Array<Readonly<A>>;
9
+ export declare abstract class Query<Document extends object> implements Iterable<Readonly<Document>> {
10
+ abstract [Symbol.iterator](): IterableIterator<Readonly<Document>>;
11
+ abstract signal(): Signal.Computed<Array<Readonly<Document>>>;
12
+ map<B>(mapFn: (item: Readonly<Document>) => B): IterableIterator<B>;
13
+ forEach(action: (item: Document) => void): void;
14
+ toArray(): Array<Readonly<Document>>;
15
15
  }
16
- export declare abstract class TableQuery<A extends object, PI extends UnitIndex<A>, Ix extends object> extends Query<A> {
17
- table: Table<A, PI, Ix>;
18
- constructor(table: Table<A, PI, Ix>);
19
- signal(): Signal.Computed<Array<Readonly<A>>>;
16
+ export declare abstract class TableQuery<Document extends object, PI extends UnitIndex<Document>, Ix extends object> extends Query<Document> {
17
+ /** @ignore */
18
+ protected table: Table<Document, PI, Ix>;
19
+ constructor(table: Table<Document, PI, Ix>);
20
+ signal(): Signal.Computed<Array<Readonly<Document>>>;
21
+ /**
22
+ * Delete all documents from the table matching this query.
23
+ */
20
24
  delete(): number;
21
- filter(predicate: (item: Readonly<A>) => boolean): ChainQuery<A, PI, Ix>;
22
- limit(count: number): ChainQuery<A, PI, Ix>;
25
+ filter(predicate: (item: Readonly<Document>) => boolean): ChainQuery<Document, PI, Ix>;
26
+ limit(count: number): ChainQuery<Document, PI, Ix>;
23
27
  }
24
- export declare class IndexQuery<A extends object, PI extends UnitIndex<A>, I extends Index<A>, Ix extends object> extends TableQuery<A, PI, Ix> {
28
+ export declare class IndexQuery<Document extends object, PI extends UnitIndex<Document>, I extends Index<Document>, Ix extends object> extends TableQuery<Document, PI, Ix> {
25
29
  private readonly index;
26
30
  private readonly indexTable?;
27
31
  private readonly isPrimary;
28
32
  private start?;
29
33
  private skipStart;
30
34
  private direction;
31
- constructor(table: Table<A, PI, Ix>, indexKey: keyof Ix & string, direction: IteratorDirection, start?: I["keyType"]);
32
- [Symbol.iterator](): IterableIterator<Readonly<A>>;
33
- reverse(): this;
34
- equals(value: I["keyType"]): ArrayQuery<A, PI, Ix>;
35
+ constructor(table: Table<Document, PI, Ix>, indexKey: keyof Ix & string, direction: IteratorDirection, start?: I["keyType"]);
36
+ [Symbol.iterator](): IterableIterator<Readonly<Document>>;
37
+ equals(value: I["keyType"]): ArrayQuery<Document, PI, Ix>;
35
38
  below(value: I["keyType"]): this;
36
39
  above(value: I["keyType"]): this;
37
40
  inclusive(): this;
38
41
  max(): Option<I["keyType"]>;
39
42
  min(): Option<I["keyType"]>;
40
43
  }
41
- export declare class ChainQuery<A extends object, PI extends UnitIndex<A>, Ix extends object> extends TableQuery<A, PI, Ix> {
44
+ export declare class ChainQuery<Document extends object, PI extends UnitIndex<Document>, Ix extends object> extends TableQuery<Document, PI, Ix> {
42
45
  private readonly parent;
43
46
  private readonly iterator;
44
- constructor(table: Table<A, PI, Ix>, parent: Query<A>, iterator: (parentIterator: IterableIterator<Readonly<A>>) => IterableIterator<Readonly<A>>);
45
- [Symbol.iterator](): IterableIterator<Readonly<A>>;
47
+ constructor(table: Table<Document, PI, Ix>, parent: Query<Document>, iterator: (parentIterator: IterableIterator<Readonly<Document>>) => IterableIterator<Readonly<Document>>);
48
+ [Symbol.iterator](): IterableIterator<Readonly<Document>>;
46
49
  }
47
- export declare class ArrayQuery<A extends object, PI extends UnitIndex<A>, Ix extends object> extends TableQuery<A, PI, Ix> {
50
+ export declare class ArrayQuery<Document extends object, PI extends UnitIndex<Document>, Ix extends object> extends TableQuery<Document, PI, Ix> {
48
51
  private readonly values;
49
- constructor(table: Table<A, PI, Ix>, values: Array<Readonly<A>>);
50
- [Symbol.iterator](): IterableIterator<Readonly<A>>;
52
+ constructor(table: Table<Document, PI, Ix>, values: Array<Readonly<Document>>);
53
+ [Symbol.iterator](): IterableIterator<Readonly<Document>>;
51
54
  }
package/dist/query.js CHANGED
@@ -53,6 +53,9 @@ export class Query {
53
53
  return Array.from(this);
54
54
  }
55
55
  }
56
+ function arraysEqual(a, b) {
57
+ return a.length === b.length && a.every((v, i) => Object.is(v, b[i]));
58
+ }
56
59
  export class TableQuery extends Query {
57
60
  constructor(table) {
58
61
  super();
@@ -62,10 +65,13 @@ export class TableQuery extends Query {
62
65
  return Signal.computed(() => {
63
66
  this.table.changed.get();
64
67
  return Array.from(this);
65
- });
68
+ }, { equals: arraysEqual });
66
69
  }
70
+ /**
71
+ * Delete all documents from the table matching this query.
72
+ */
67
73
  delete() {
68
- return this.table.delete(...Array.from(this));
74
+ return this.table.delete(...Array.from(this).map((doc) => this.table.primaryIndex.extractKey(doc)));
69
75
  }
70
76
  filter(predicate) {
71
77
  return new ChainQuery(this.table, this, (iter) => Iterator.from(iter).filter(predicate));
@@ -95,16 +101,6 @@ export class IndexQuery extends TableQuery {
95
101
  ? primaryIndexIterator(this.table.primary, this.direction, this.start, this.skipStart)
96
102
  : indexIterator(this.indexTable, this.direction, this.start, this.skipStart);
97
103
  }
98
- reverse() {
99
- switch (this.direction) {
100
- case IteratorDirection.Ascending:
101
- this.direction = IteratorDirection.Descending;
102
- return this;
103
- case IteratorDirection.Descending:
104
- this.direction = IteratorDirection.Ascending;
105
- return this;
106
- }
107
- }
108
104
  equals(value) {
109
105
  if (this.isPrimary) {
110
106
  const item = this.table.get(value);
package/dist/query.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
package/dist/table.d.ts CHANGED
@@ -15,61 +15,182 @@ export type TableEvent<A extends object, PK> = {
15
15
  type: "delete";
16
16
  key: PK;
17
17
  };
18
- export declare class Table<A extends object, PI extends UnitIndex<A>, Ix extends object> extends Emitter<TableEvent<A, PI["keyType"]>> implements Disposable, Iterable<Readonly<A>> {
18
+ /**
19
+ * A database table.
20
+ *
21
+ * To learn how to create a table, see the static method {@link Table.create}.
22
+ *
23
+ * @template Document The type of the documents this table stores.
24
+ */
25
+ export declare class Table<Document extends object, PrimaryIndex extends UnitIndex<Document>, Indices extends object> extends Emitter<TableEvent<Document, PrimaryIndex["keyType"]>> implements Disposable, Iterable<Readonly<Document>> {
19
26
  #private;
20
- ready: Promise<void>;
21
- readonly primaryIndex: PI;
22
- readonly primary: BTree<PI["keyType"], Readonly<A>>;
27
+ /**
28
+ * A promise which resolves when this table is ready to use.
29
+ *
30
+ * If the table isn't connected to a {@link StorageBackend}, this is a
31
+ * promise which resolves immediately, and you don't really need to await
32
+ * it. The table will be ready for use immediately.
33
+ *
34
+ * With an attached {@link StorageBackend}, this promise will resolve when
35
+ * the table has finished restoring its contents from the storage. You
36
+ * should not under any circumstances use the table before this is complete.
37
+ */
38
+ get ready(): Promise<void>;
39
+ /** @ignore */
40
+ readonly primaryIndex: PrimaryIndex;
41
+ /** @ignore */
42
+ readonly primary: BTree<PrimaryIndex["keyType"], Readonly<Document>>;
43
+ /** @ignore */
23
44
  readonly indices: {
24
- [K in Exclude<keyof Ix & string, PI["name"]>]: Index<A>;
45
+ [K in Exclude<keyof Indices & string, PrimaryIndex["name"]>]: Index<Document>;
25
46
  };
47
+ /** @ignore */
26
48
  readonly indexTables: {
27
- [K in Exclude<keyof Ix & string, PI["name"]>]: BTree<Ix[K], Array<A>>;
49
+ [K in Exclude<keyof Indices & string, PrimaryIndex["name"]>]: BTree<Indices[K], Array<Document>>;
50
+ };
51
+ /**
52
+ * A signal which updates whenever the table has been modified.
53
+ */
54
+ get changed(): Signal.Computed<null>;
55
+ /**
56
+ * Create a database {@link Table}.
57
+ *
58
+ * `Table.create` is a function which takes one type argument, the type of the
59
+ * object (which we'll call a *document*) you want the table to store, and no
60
+ * value arguments.
61
+ *
62
+ * This returns an object with one method: `withPrimaryIndex`. This method is
63
+ * what actually creates the table. So, the full incantation is, for instance:
64
+ *
65
+ * ```ts
66
+ * type Document = { id: string; value: number };
67
+ * const table = Table.create<Document>()
68
+ * .withPrimaryIndex(index<Document>().key("id"));
69
+ * ```
70
+ *
71
+ * In order to look up something in a database table, you need an index. You can
72
+ * create an index using the {@link index} function, which, like `Table.create`,
73
+ * takes the document you're creating an index for as its type argument, and
74
+ * returns a selection of index constructors, of which the most straightforward
75
+ * one is {@link IndexConstructor.key}. This creates an index for a single named
76
+ * property of the document containing a primitive comparable value (a string, a
77
+ * number, or a bigint), and allows you to search for documents where the given
78
+ * property matches any given value. You can also create an index over multiple
79
+ * keys using {@link IndexConstructor.keys} or over a key containing an array
80
+ * using {@link IndexConstructor.array}. You can even create a completely
81
+ * customised index using {@link IndexConstructor.custom}.
82
+ *
83
+ * The primary index, unlike a regular index, is a unique identifier, and only
84
+ * one document can exist at any given time under the key or keys represented by
85
+ * the primary index. A table is required to have a primary index, which is why
86
+ * `Table.create` doesn't actually create the table until you call
87
+ * `withPrimaryIndex` on it. You can then add as many extra indices as you like
88
+ * using `withIndex`. To extend our example above with an additional index over
89
+ * the `value` property:
90
+ *
91
+ * ```ts
92
+ * type Document = { id: string; value: number };
93
+ * const table = Table.create<Document>()
94
+ * .withPrimaryIndex(index<Document>().key("id"))
95
+ * .withIndex(index<Document>().key("value"));
96
+ * ```
97
+ *
98
+ * @see {@link index}
99
+ *
100
+ * @template Document The type of the document this table stores.
101
+ */
102
+ static create<Document extends object>(): {
103
+ withPrimaryIndex: <PrimaryIndex extends UnitIndex<Document>>(primaryIndex: PrimaryIndex) => Table<Document, PrimaryIndex, PrimaryIndex["record"]>;
28
104
  };
29
- readonly changed: Signal.State<number>;
30
- constructor(primaryIndex: PI);
105
+ /** @internal */
106
+ private constructor();
31
107
  [Symbol.dispose](): void;
32
- withIndex<I extends Index<A>>(index: I): Table<A, PI, {
33
- [K in keyof (Ix & I["record"])]: (Ix & I["record"])[K];
108
+ /**
109
+ * Add an index to a table.
110
+ *
111
+ * @example
112
+ * type Document = { id: string; value: number };
113
+ * const table = Table.create<Document>()
114
+ * .withPrimaryIndex(index<Document>().key("id"))
115
+ * .withIndex(index<Document>().key("value"));
116
+ */
117
+ withIndex<I extends Index<Document>>(index: I): Table<Document, PrimaryIndex, {
118
+ [K in keyof (Indices & I["record"])]: (Indices & I["record"])[K];
34
119
  }>;
120
+ /**
121
+ * Attach a table to a {@link StorageBackend}.
122
+ *
123
+ * See {@link IndexedDBBackend.open} for an example of how to use this.
124
+ */
35
125
  withStorage(backend: StorageBackend, name: string): this;
36
- signal(primaryKey: PI["keyType"]): Signal.Computed<Readonly<A> | undefined>;
37
- get(primaryKey: PI["keyType"]): Readonly<A> | undefined;
126
+ signal(primaryKey: PrimaryIndex["keyType"]): Signal.Computed<Readonly<Document> | undefined>;
127
+ get(primaryKey: PrimaryIndex["keyType"]): Readonly<Document> | undefined;
38
128
  /**
39
129
  * Given a primary key, apply an update function to the value stored under
40
130
  * that key. If there's no value, call the create function to create the
41
131
  * value before passing it to the update function.
42
132
  */
43
- createAndUpdate(primaryKey: PI["keyType"], create: () => A, update: (item: Draft<A>) => Draft<A> | void): Readonly<A>;
133
+ createAndUpdate(primaryKey: PrimaryIndex["keyType"], create: () => Document, update: (item: Draft<Document>) => Draft<Document> | void): Readonly<Document>;
44
134
  /**
45
- * Given a primary key, apply an update function to the value stored under
46
- * that key. If there's no value, call the create function to create a new
47
- * value. In this case, the update function is not called.
135
+ * Create or update a document.
136
+ *
137
+ * Given a primary key, apply the `update` function to the document stored
138
+ * under that key.
139
+ *
140
+ * If there's no such document, call the `create` function to create a new
141
+ * document and insert that under the given primary key. In this case, the
142
+ * update function is not called.
143
+ *
144
+ * The `update` function is passed to {@link produce | Immer.produce} to
145
+ * perform the update. It should modify the provided document in place, and
146
+ * it's not necessary to return it.
48
147
  */
49
- createOrUpdate(primaryKey: PI["keyType"], create: () => A, update: (item: Draft<A>) => Draft<A> | void): Readonly<A>;
148
+ createOrUpdate(primaryKey: PrimaryIndex["keyType"], create: () => Document, update: (item: Draft<Document>) => Draft<Document> | void): Readonly<Document>;
50
149
  /**
51
- * Apply an update function to the value stored under the given primary key.
52
- * If no value exists, the update function is not called and `undefined` is
53
- * returned. Otherwise, the updated value is returned.
150
+ * Update a document.
151
+ *
152
+ * Apply the `update` function to the document stored under the given
153
+ * primary key.
154
+ *
155
+ * If no such document exists, the update function is not called and
156
+ * `undefined` is returned. Otherwise, the updated document is returned.
157
+ *
158
+ * The `update` function is passed to {@link produce | Immer.produce} to
159
+ * perform the update. It should modify the provided document in place, and
160
+ * it's not necessary to return it.
54
161
  */
55
- update(primaryKey: PI["keyType"], update: (item: Draft<A>) => void | Draft<A>): Readonly<A> | undefined;
162
+ update(primaryKey: PrimaryIndex["keyType"], update: (item: Draft<Document>) => void | Draft<Document>): Readonly<Document> | undefined;
56
163
  /**
57
- * Add items to the table, overwriting any previous values under their
164
+ * Add documents to the table, overwriting any previous values under their
58
165
  * primary keys.
59
166
  */
60
- add(...items: Array<A>): void;
61
- add(items: Iterable<A>): void;
167
+ add(...items: Array<Document>): void;
168
+ add(items: Iterable<Document>): void;
62
169
  /**
63
- * Delete items from the table by their primary keys.
170
+ * Delete documents from the table by their primary keys.
64
171
  */
65
- delete(...primaryKeys: Array<PI["keyType"]>): number;
66
- delete(primaryKeys: Iterable<PI["keyType"]>): number;
172
+ delete(...primaryKeys: Array<PrimaryIndex["keyType"]>): number;
173
+ delete(primaryKeys: Iterable<PrimaryIndex["keyType"]>): number;
67
174
  /**
68
- * Delete all data from the table.
175
+ * Delete all documents from the table.
69
176
  */
70
177
  clear(): void;
71
- [Symbol.iterator](): IterableIterator<Readonly<A>>;
72
- where<K extends keyof Ix & string, I extends Index<A> & Ix[K]>(index: K): IndexQuery<A, PI, I, Ix>;
73
- orderBy<K extends keyof Ix & string, I extends Index<A> & Ix[K]>(index: K): IndexQuery<A, PI, I, Ix>;
178
+ /**
179
+ * Iterate over the documents in the table, ordered by primary key.
180
+ */
181
+ [Symbol.iterator](): IteratorObject<Readonly<Document>>;
182
+ /**
183
+ * Perform an {@link IndexQuery} using the specified index.
184
+ */
185
+ where<K extends keyof Indices & string, I extends Index<Document> & Indices[K]>(index: K): IndexQuery<Document, PrimaryIndex, I, Indices>;
186
+ /**
187
+ * Perform an {@link IndexQuery} using the specified index.
188
+ *
189
+ * This is an alias for {@link Table.where}.
190
+ */
191
+ orderBy<K extends keyof Indices & string, I extends Index<Document> & Indices[K]>(index: K): IndexQuery<Document, PrimaryIndex, I, Indices>;
192
+ /**
193
+ * Get the number of documents currently stored in the table.
194
+ */
74
195
  size(): number;
75
196
  }
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":
@@ -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);