shelving 1.22.2 → 1.24.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/db/Database.d.ts +17 -27
- package/db/Database.js +34 -29
- package/db/Pagination.js +1 -1
- package/db/Write.d.ts +30 -0
- package/db/Write.js +38 -0
- package/db/index.d.ts +1 -1
- package/db/index.js +1 -1
- package/package.json +1 -1
- package/provider/BatchProvider.js +2 -2
- package/provider/CacheProvider.js +3 -3
- package/provider/MemoryProvider.js +6 -6
- package/query/Filter.d.ts +1 -1
- package/query/Filter.js +1 -1
- package/query/Filters.d.ts +1 -1
- package/query/Filters.js +1 -1
- package/query/Query.d.ts +1 -1
- package/query/Query.js +2 -2
- package/query/Rule.d.ts +3 -3
- package/query/Sort.d.ts +1 -1
- package/query/Sort.js +1 -1
- package/query/Sorts.d.ts +1 -1
- package/query/Sorts.js +1 -1
- package/react/useQuery.js +2 -2
- package/stream/DataState.d.ts +2 -2
- package/stream/DataState.js +2 -2
- package/stream/State.d.ts +4 -4
- package/stream/State.js +2 -2
- package/stream/Stream.d.ts +7 -7
- package/stream/Stream.js +5 -5
- package/transform/AddEntriesTransform.d.ts +1 -1
- package/transform/AddEntriesTransform.js +1 -1
- package/transform/AddItemsTransform.d.ts +1 -1
- package/transform/AddItemsTransform.js +1 -1
- package/transform/DataTransform.d.ts +1 -1
- package/transform/DataTransform.js +3 -3
- package/transform/IncrementTransform.d.ts +1 -1
- package/transform/IncrementTransform.js +1 -1
- package/transform/RemoveEntriesTransform.d.ts +1 -1
- package/transform/RemoveEntriesTransform.js +1 -1
- package/transform/RemoveItemsTransform.d.ts +1 -1
- package/transform/RemoveItemsTransform.js +1 -1
- package/transform/Transform.d.ts +3 -3
- package/transform/hydrations.d.ts +1 -1
- package/transform/hydrations.js +1 -1
- package/transform/util.js +2 -2
- package/util/clone.js +3 -3
- package/util/filter.d.ts +4 -4
- package/util/filter.js +5 -5
- package/util/hydrate.d.ts +7 -7
- package/util/hydrate.js +13 -13
- package/util/index.d.ts +2 -2
- package/util/index.js +2 -2
- package/util/observable.d.ts +5 -5
- package/util/observable.js +6 -6
- package/util/sort.d.ts +4 -4
- package/util/sort.js +5 -6
- package/util/transform.d.ts +77 -0
- package/util/transform.js +48 -0
- package/db/Change.d.ts +0 -37
- package/db/Change.js +0 -60
- package/util/derive.d.ts +0 -88
- package/util/derive.js +0 -48
package/db/Database.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Entry, Observable, Observer, Result, Unsubscriber, ResultsMap, Validata
|
|
|
2
2
|
import { Transform, Transforms } from "../transform/index.js";
|
|
3
3
|
import type { Provider } from "../provider/Provider.js";
|
|
4
4
|
import { Filters, Sorts, Query } from "../query/index.js";
|
|
5
|
+
import { DocumentWrite, Write, Writes } from "./Write.js";
|
|
5
6
|
/**
|
|
6
7
|
* Combines a database model and a provider.
|
|
7
8
|
*
|
|
@@ -17,6 +18,10 @@ export declare class Database<V extends Validators<Datas> = Validators<Datas>> {
|
|
|
17
18
|
query<K extends Key<V>>(collection: K, filters?: Filters<ValidatorType<V[K]>>, sorts?: Sorts<ValidatorType<V[K]>>, limit?: number | null): DataQuery<ValidatorType<V[K]>>;
|
|
18
19
|
/** Reference a document in a collection in this model. */
|
|
19
20
|
doc<K extends Key<V>>(collection: K, id: string): DataDocument<ValidatorType<V[K]>>;
|
|
21
|
+
/** Perform a write on this database and return the `Write` instance representing the changes. */
|
|
22
|
+
write(write: Write): Promise<Write>;
|
|
23
|
+
/** Perform multiple writes on this database by combining them into a single `Writes` instance representing the changes. */
|
|
24
|
+
writes(...writes: (Write | undefined)[]): Promise<Writes>;
|
|
20
25
|
}
|
|
21
26
|
/** A documents reference within a specific database. */
|
|
22
27
|
export declare class DataQuery<T extends Data = Data> extends Query<T> implements Observable<Results<T>>, Validatable<Results<T>>, Iterable<Entry<T>> {
|
|
@@ -141,37 +146,22 @@ export declare class DataDocument<T extends Data = Data> implements Observable<R
|
|
|
141
146
|
* @return Function that ends the subscription.
|
|
142
147
|
*/
|
|
143
148
|
subscribe(next: Observer<Result<T>> | Dispatcher<[Result<T>]>): Unsubscriber;
|
|
144
|
-
/**
|
|
145
|
-
* Set the complete data of this document.
|
|
146
|
-
*
|
|
147
|
-
* @param data Complete data to set the document to.
|
|
148
|
-
*
|
|
149
|
-
* @return Nothing (possibly promised).
|
|
150
|
-
*/
|
|
149
|
+
/** Set the complete data of this document. */
|
|
151
150
|
set(data: T): void | PromiseLike<void>;
|
|
152
|
-
/**
|
|
153
|
-
* Update this document with partial data.
|
|
154
|
-
* - If the document exists, merge the partial data into it.
|
|
155
|
-
* - If the document doesn't exist, throw an error.
|
|
156
|
-
*
|
|
157
|
-
* @param transforms `Transform` instance or set of transforms to apply to the existing document.
|
|
158
|
-
* - Not all transforms may be supported by all providers.
|
|
159
|
-
*
|
|
160
|
-
* @return Nothing (possibly promised).
|
|
161
|
-
* @throws Error If the document does not exist (ideally a `RequiredError` but may be provider-specific).
|
|
162
|
-
*/
|
|
151
|
+
/** Update this document. */
|
|
163
152
|
update(transforms: Transform<T> | Transforms<T>): void | PromiseLike<void>;
|
|
164
|
-
/**
|
|
165
|
-
* Delete this document.
|
|
166
|
-
* - Will not throw an error if the document doesn't exist.
|
|
167
|
-
*
|
|
168
|
-
* @return Nothing (possibly promised).
|
|
169
|
-
*/
|
|
153
|
+
/** Delete this document. */
|
|
170
154
|
delete(): void | PromiseLike<void>;
|
|
171
|
-
/**
|
|
172
|
-
* Combine `set()`, `update()`, `delete()` into a single method.
|
|
173
|
-
*/
|
|
155
|
+
/** Set, update, or delete this document. */
|
|
174
156
|
write(value: Result<T> | Transform<T>): void | PromiseLike<void>;
|
|
157
|
+
/** Represent a write that sets the complete data of this document in a database. */
|
|
158
|
+
setter(data: T): DocumentWrite<T>;
|
|
159
|
+
/** Represent a write that updates this document in a database. */
|
|
160
|
+
updater(transforms: Transform<T> | Transforms<T>): DocumentWrite<T>;
|
|
161
|
+
/** Represent a write that deletes this document in a database. */
|
|
162
|
+
deleter(): DocumentWrite<T>;
|
|
163
|
+
/** Represent a write that sets, updates, or deletes this document in a database. */
|
|
164
|
+
writer(value: Result<T> | Transform<T>): DocumentWrite<T>;
|
|
175
165
|
/** Validate data for this query reference. */
|
|
176
166
|
validate(unsafeData: Data): T;
|
|
177
167
|
toString(): string;
|
package/db/Database.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { callAsync, getFirstItem, throwAsync, validate, toMap, countItems,
|
|
1
|
+
import { callAsync, getFirstItem, throwAsync, validate, toMap, countItems, TransformObserver, } from "../util/index.js";
|
|
2
2
|
import { DataTransform, Transform } from "../transform/index.js";
|
|
3
3
|
import { Feedback, InvalidFeedback } from "../feedback/index.js";
|
|
4
4
|
import { Filters, Query, EqualFilter } from "../query/index.js";
|
|
5
5
|
import { DocumentRequiredError, DocumentValidationError, QueryValidationError } from "./errors.js";
|
|
6
|
+
import { DocumentWrite, Writes } from "./Write.js";
|
|
6
7
|
/**
|
|
7
8
|
* Combines a database model and a provider.
|
|
8
9
|
*
|
|
@@ -24,6 +25,17 @@ export class Database {
|
|
|
24
25
|
doc(collection, id) {
|
|
25
26
|
return new DataDocument(this.provider, this.validators[collection], collection, id);
|
|
26
27
|
}
|
|
28
|
+
/** Perform a write on this database and return the `Write` instance representing the changes. */
|
|
29
|
+
async write(write) {
|
|
30
|
+
await write.transform(this);
|
|
31
|
+
return write;
|
|
32
|
+
}
|
|
33
|
+
/** Perform multiple writes on this database by combining them into a single `Writes` instance representing the changes. */
|
|
34
|
+
async writes(...writes) {
|
|
35
|
+
const write = new Writes(...writes);
|
|
36
|
+
await write.transform(this);
|
|
37
|
+
return write;
|
|
38
|
+
}
|
|
27
39
|
}
|
|
28
40
|
/** A documents reference within a specific database. */
|
|
29
41
|
export class DataQuery extends Query {
|
|
@@ -93,7 +105,7 @@ export class DataQuery extends Query {
|
|
|
93
105
|
* @return Function that ends the subscription.
|
|
94
106
|
*/
|
|
95
107
|
subscribeMap(next) {
|
|
96
|
-
return this.provider.subscribeQuery(this, new
|
|
108
|
+
return this.provider.subscribeQuery(this, new TransformObserver(toMap, typeof next === "function" ? { next } : next));
|
|
97
109
|
}
|
|
98
110
|
/**
|
|
99
111
|
* Set all matching documents to the same exact value.
|
|
@@ -208,45 +220,38 @@ export class DataDocument {
|
|
|
208
220
|
subscribe(next) {
|
|
209
221
|
return this.provider.subscribe(this, typeof next === "function" ? { next } : next);
|
|
210
222
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Set the complete data of this document.
|
|
213
|
-
*
|
|
214
|
-
* @param data Complete data to set the document to.
|
|
215
|
-
*
|
|
216
|
-
* @return Nothing (possibly promised).
|
|
217
|
-
*/
|
|
223
|
+
/** Set the complete data of this document. */
|
|
218
224
|
set(data) {
|
|
219
225
|
return this.write(data);
|
|
220
226
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Update this document with partial data.
|
|
223
|
-
* - If the document exists, merge the partial data into it.
|
|
224
|
-
* - If the document doesn't exist, throw an error.
|
|
225
|
-
*
|
|
226
|
-
* @param transforms `Transform` instance or set of transforms to apply to the existing document.
|
|
227
|
-
* - Not all transforms may be supported by all providers.
|
|
228
|
-
*
|
|
229
|
-
* @return Nothing (possibly promised).
|
|
230
|
-
* @throws Error If the document does not exist (ideally a `RequiredError` but may be provider-specific).
|
|
231
|
-
*/
|
|
227
|
+
/** Update this document. */
|
|
232
228
|
update(transforms) {
|
|
233
229
|
return this.write(transforms instanceof Transform ? transforms : new DataTransform(transforms));
|
|
234
230
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Delete this document.
|
|
237
|
-
* - Will not throw an error if the document doesn't exist.
|
|
238
|
-
*
|
|
239
|
-
* @return Nothing (possibly promised).
|
|
240
|
-
*/
|
|
231
|
+
/** Delete this document. */
|
|
241
232
|
delete() {
|
|
242
233
|
return this.write(undefined);
|
|
243
234
|
}
|
|
244
|
-
/**
|
|
245
|
-
* Combine `set()`, `update()`, `delete()` into a single method.
|
|
246
|
-
*/
|
|
235
|
+
/** Set, update, or delete this document. */
|
|
247
236
|
write(value) {
|
|
248
237
|
return this.provider.write(this, value);
|
|
249
238
|
}
|
|
239
|
+
/** Represent a write that sets the complete data of this document in a database. */
|
|
240
|
+
setter(data) {
|
|
241
|
+
return this.writer(data);
|
|
242
|
+
}
|
|
243
|
+
/** Represent a write that updates this document in a database. */
|
|
244
|
+
updater(transforms) {
|
|
245
|
+
return this.writer(transforms instanceof Transform ? transforms : new DataTransform(transforms));
|
|
246
|
+
}
|
|
247
|
+
/** Represent a write that deletes this document in a database. */
|
|
248
|
+
deleter() {
|
|
249
|
+
return this.writer(undefined);
|
|
250
|
+
}
|
|
251
|
+
/** Represent a write that sets, updates, or deletes this document in a database. */
|
|
252
|
+
writer(value) {
|
|
253
|
+
return new DocumentWrite(this, value);
|
|
254
|
+
}
|
|
250
255
|
/** Validate data for this query reference. */
|
|
251
256
|
validate(unsafeData) {
|
|
252
257
|
try {
|
package/db/Pagination.js
CHANGED
|
@@ -71,7 +71,7 @@ export class Pagination extends State {
|
|
|
71
71
|
* @return The change in the number of results.
|
|
72
72
|
*/
|
|
73
73
|
merge(more) {
|
|
74
|
-
this.next(toMap(this.ref.sorts.
|
|
74
|
+
this.next(toMap(this.ref.sorts.transform(yieldMerged(more, this.value))));
|
|
75
75
|
}
|
|
76
76
|
/** Iterate over the entries of the values currently in the pagination. */
|
|
77
77
|
[Symbol.iterator]() {
|
package/db/Write.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Transform } from "../transform/index.js";
|
|
2
|
+
import { ImmutableArray, Data, Transformable } from "../util/index.js";
|
|
3
|
+
import type { Database, DataDocument } from "./Database.js";
|
|
4
|
+
/** Write to a database. */
|
|
5
|
+
export declare abstract class Write implements Transformable<Database, void | PromiseLike<void>> {
|
|
6
|
+
abstract transform(db: Database): void | PromiseLike<void>;
|
|
7
|
+
}
|
|
8
|
+
/** Represent a write made to a single document in a database. */
|
|
9
|
+
export declare class DocumentWrite<T extends Data> extends Write {
|
|
10
|
+
readonly collection: string;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly value: Data | Transform<Data> | undefined;
|
|
13
|
+
constructor({ collection, id }: DataDocument<T>, value: T | Transform<T> | undefined);
|
|
14
|
+
transform(db: Database): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Represent a list of writes made to a database.
|
|
18
|
+
* - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
|
|
19
|
+
* - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Writes extends Write {
|
|
22
|
+
readonly writes: ImmutableArray<Write>;
|
|
23
|
+
constructor(...writes: (Write | undefined)[]);
|
|
24
|
+
transform(db: Database): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** Set of hydrations for all change classes. */
|
|
27
|
+
export declare const WRITE_HYDRATIONS: {
|
|
28
|
+
writes: typeof Writes;
|
|
29
|
+
write: typeof DocumentWrite;
|
|
30
|
+
};
|
package/db/Write.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { transform } from "../util/index.js";
|
|
2
|
+
/** Write to a database. */
|
|
3
|
+
export class Write {
|
|
4
|
+
}
|
|
5
|
+
/** Represent a write made to a single document in a database. */
|
|
6
|
+
export class DocumentWrite extends Write {
|
|
7
|
+
constructor({ collection, id }, value) {
|
|
8
|
+
super();
|
|
9
|
+
this.collection = collection;
|
|
10
|
+
this.id = id;
|
|
11
|
+
this.value = value;
|
|
12
|
+
}
|
|
13
|
+
async transform(db) {
|
|
14
|
+
await db.doc(this.collection, this.id).write(this.value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Represent a list of writes made to a database.
|
|
19
|
+
* - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
|
|
20
|
+
* - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
|
|
21
|
+
*/
|
|
22
|
+
export class Writes extends Write {
|
|
23
|
+
constructor(...writes) {
|
|
24
|
+
super();
|
|
25
|
+
this.writes = writes.filter(isWrite);
|
|
26
|
+
}
|
|
27
|
+
async transform(db) {
|
|
28
|
+
for (const writes of this.writes)
|
|
29
|
+
await transform(db, writes);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const isWrite = (v) => !!v;
|
|
33
|
+
/** Set of hydrations for all change classes. */
|
|
34
|
+
export const WRITE_HYDRATIONS = {
|
|
35
|
+
writes: Writes,
|
|
36
|
+
write: DocumentWrite,
|
|
37
|
+
};
|
|
38
|
+
WRITE_HYDRATIONS;
|
package/db/index.d.ts
CHANGED
package/db/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isAsync, toMap,
|
|
1
|
+
import { isAsync, toMap, TransformObserver, awaitNext, } from "../util/index.js";
|
|
2
2
|
import { LazyState } from "../stream/index.js";
|
|
3
3
|
import { ThroughProvider } from "./ThroughProvider.js";
|
|
4
4
|
/** How long to wait after all subscriptions have ended to close the source subscription. */
|
|
@@ -80,7 +80,7 @@ export class BatchProvider extends ThroughProvider {
|
|
|
80
80
|
const sub = ((_a = this._subs)[key] || (_a[key] = new LazyState(STOP_DELAY).from(o => {
|
|
81
81
|
var _a;
|
|
82
82
|
// Convert the iterable to a map because it might be read multiple times.
|
|
83
|
-
const stop = super.subscribeQuery(ref, new
|
|
83
|
+
const stop = super.subscribeQuery(ref, new TransformObserver(toMap, o));
|
|
84
84
|
// The first value from the subscription can be reused for any concurrent get requests.
|
|
85
85
|
(_a = this._gets)[key] || (_a[key] = this._awaitDocuments(ref, awaitNext(sub)));
|
|
86
86
|
return () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transform } from "../transform/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TransformObserver } from "../util/index.js";
|
|
3
3
|
import { MemoryProvider } from "./MemoryProvider.js";
|
|
4
4
|
import { ThroughProvider } from "./ThroughProvider.js";
|
|
5
5
|
/** Keep a copy of received data in a local cache. */
|
|
@@ -33,7 +33,7 @@ export class CacheProvider extends ThroughProvider {
|
|
|
33
33
|
}
|
|
34
34
|
// Override to cache any got results.
|
|
35
35
|
subscribe(ref, observer) {
|
|
36
|
-
return super.subscribe(ref, new
|
|
36
|
+
return super.subscribe(ref, new TransformObserver(result => this._cacheResult(ref, result), observer));
|
|
37
37
|
}
|
|
38
38
|
async add(ref, data) {
|
|
39
39
|
const id = await super.add(ref, data);
|
|
@@ -72,7 +72,7 @@ export class CacheProvider extends ThroughProvider {
|
|
|
72
72
|
}
|
|
73
73
|
// Override to cache any got results.
|
|
74
74
|
subscribeQuery(ref, observer) {
|
|
75
|
-
return super.subscribeQuery(ref, new
|
|
75
|
+
return super.subscribeQuery(ref, new TransformObserver(results => this._cacheResults(ref, results), observer));
|
|
76
76
|
}
|
|
77
77
|
async writeQuery(ref, value) {
|
|
78
78
|
await super.writeQuery(ref, value);
|
|
@@ -46,19 +46,19 @@ export class MemoryProvider extends Provider {
|
|
|
46
46
|
const existing = table.data.get(id);
|
|
47
47
|
if (!existing)
|
|
48
48
|
throw new DocumentRequiredError(ref);
|
|
49
|
-
table.write(id, value.
|
|
49
|
+
table.write(id, value.transform(existing));
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
table.write(id, value);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
getQuery(ref) {
|
|
56
|
-
return ref.
|
|
56
|
+
return ref.transform(this._table(ref).data);
|
|
57
57
|
}
|
|
58
58
|
subscribeQuery(ref, observer) {
|
|
59
59
|
const table = this._table(ref);
|
|
60
60
|
// Call `next()` immediately with the initial results.
|
|
61
|
-
let lastResults = new Map(ref.
|
|
61
|
+
let lastResults = new Map(ref.transform(table.data));
|
|
62
62
|
dispatchNext(observer, lastResults);
|
|
63
63
|
// Possibly call `next()` when the collection changes if any changes affect the subscription.
|
|
64
64
|
return table.on(changes => {
|
|
@@ -68,7 +68,7 @@ export class MemoryProvider extends Provider {
|
|
|
68
68
|
// 2) the next document matches the query so might be added to the next results.
|
|
69
69
|
// Re-running the entire query is not the most efficient way to do this, but itis the most simple!
|
|
70
70
|
if (lastResults.has(id) || (next && ref.match([id, next]))) {
|
|
71
|
-
const nextResults = new Map(ref.
|
|
71
|
+
const nextResults = new Map(ref.transform(table.data));
|
|
72
72
|
if (!isMapEqual(lastResults, nextResults)) {
|
|
73
73
|
lastResults = nextResults;
|
|
74
74
|
dispatchNext(observer, lastResults);
|
|
@@ -82,8 +82,8 @@ export class MemoryProvider extends Provider {
|
|
|
82
82
|
const table = this._table(ref);
|
|
83
83
|
// If there's a limit set: run the full query.
|
|
84
84
|
// If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
|
|
85
|
-
for (const [id, existing] of ref.limit ? ref.
|
|
86
|
-
table.write(id, value instanceof Transform ? value.
|
|
85
|
+
for (const [id, existing] of ref.limit ? ref.transform(table.data) : ref.filters.transform(table.data))
|
|
86
|
+
table.write(id, value instanceof Transform ? value.transform(existing) : value);
|
|
87
87
|
}
|
|
88
88
|
/** Reset this provider and clear all data. */
|
|
89
89
|
reset() {
|
package/query/Filter.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare abstract class Filter<T extends Data> extends Rule<T> implements
|
|
|
17
17
|
readonly value: unknown;
|
|
18
18
|
constructor(key: QueryKey<T>, value: unknown);
|
|
19
19
|
match([id, data]: Entry<T>): boolean;
|
|
20
|
-
|
|
20
|
+
transform(results: Results<T>): Results<T>;
|
|
21
21
|
toString(): string;
|
|
22
22
|
}
|
|
23
23
|
/** Filter a set of values with an `IS` clause. */
|
package/query/Filter.js
CHANGED
package/query/Filters.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ export declare class Filters<T extends Data> extends Rules<T, Filter<T>> impleme
|
|
|
13
13
|
gt<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
14
14
|
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
15
15
|
match(entry: Entry<T>): boolean;
|
|
16
|
-
|
|
16
|
+
transform(iterable: Results<T>): Results<T>;
|
|
17
17
|
}
|
package/query/Filters.js
CHANGED
package/query/Query.d.ts
CHANGED
|
@@ -25,6 +25,6 @@ export declare class Query<T extends Data> extends Rule<T> implements Queryable<
|
|
|
25
25
|
max(limit: number | null): this;
|
|
26
26
|
after(id: string, data: T): this;
|
|
27
27
|
before(id: string, data: T): this;
|
|
28
|
-
|
|
28
|
+
transform(results: Results<T>): Results<T>;
|
|
29
29
|
toString(): string;
|
|
30
30
|
}
|
package/query/Query.js
CHANGED
|
@@ -79,8 +79,8 @@ export class Query extends Rule {
|
|
|
79
79
|
return { __proto__: Object.getPrototypeOf(this), ...this, filters: new Filters(...filters) };
|
|
80
80
|
}
|
|
81
81
|
// Implement `Rule`
|
|
82
|
-
|
|
83
|
-
const sorted = this.sorts.
|
|
82
|
+
transform(results) {
|
|
83
|
+
const sorted = this.sorts.transform(this.filters.transform(results));
|
|
84
84
|
return typeof this.limit === "number" ? limitItems(sorted, this.limit) : sorted;
|
|
85
85
|
}
|
|
86
86
|
// Implement toString()
|
package/query/Rule.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Data,
|
|
1
|
+
import { Data, Transformable, Results } from "../util/index.js";
|
|
2
2
|
/** Something that can be used to query against a result set or an array of entries. */
|
|
3
|
-
export declare abstract class Rule<T extends Data> implements
|
|
4
|
-
abstract
|
|
3
|
+
export declare abstract class Rule<T extends Data> implements Transformable<Results<T>, Results<T>> {
|
|
4
|
+
abstract transform(results: Results<T>): Results<T>;
|
|
5
5
|
abstract toString(): string;
|
|
6
6
|
}
|
package/query/Sort.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare abstract class Sort<T extends Data> extends Rule<T> implements Ra
|
|
|
10
10
|
readonly key: QueryKey<T>;
|
|
11
11
|
constructor(key: QueryKey<T>);
|
|
12
12
|
rank([leftId, leftData]: Entry<T>, [rightId, rightData]: Entry<T>): number;
|
|
13
|
-
|
|
13
|
+
transform(iterable: Results<T>): Results<T>;
|
|
14
14
|
toString(): string;
|
|
15
15
|
}
|
|
16
16
|
/** Sort a list of values in ascending order. */
|
package/query/Sort.js
CHANGED
|
@@ -9,7 +9,7 @@ export class Sort extends Rule {
|
|
|
9
9
|
rank([leftId, leftData], [rightId, rightData]) {
|
|
10
10
|
return rank(getQueryProp(leftId, leftData, this.key), this.ranker, getQueryProp(rightId, rightData, this.key));
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
transform(iterable) {
|
|
13
13
|
return sortItems(iterable, this);
|
|
14
14
|
}
|
|
15
15
|
toString() {
|
package/query/Sorts.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ export declare class Sorts<T extends Data> extends Rules<T, Sort<T>> implements
|
|
|
7
7
|
asc(key: QueryKey<T>): this;
|
|
8
8
|
desc(key: QueryKey<T>): this;
|
|
9
9
|
rank(left: Entry<T>, right: Entry<T>): number;
|
|
10
|
-
|
|
10
|
+
transform(iterable: Results<T>): Results<T>;
|
|
11
11
|
}
|
package/query/Sorts.js
CHANGED
package/react/useQuery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { CacheProvider, throwAsync, NOERROR, findSourceProvider, NOVALUE,
|
|
2
|
+
import { CacheProvider, throwAsync, NOERROR, findSourceProvider, NOVALUE, TransformObserver, toMap, } from "../index.js";
|
|
3
3
|
import { usePureEffect } from "./usePureEffect.js";
|
|
4
4
|
import { usePureMemo } from "./usePureMemo.js";
|
|
5
5
|
import { usePureState } from "./usePureState.js";
|
|
@@ -37,7 +37,7 @@ function getCachedResults(ref) {
|
|
|
37
37
|
function subscribeEffect(ref, maxAge, next, error) {
|
|
38
38
|
if (ref) {
|
|
39
39
|
const provider = findSourceProvider(ref.provider, CacheProvider);
|
|
40
|
-
const observer = new
|
|
40
|
+
const observer = new TransformObserver(toMap, { next, error });
|
|
41
41
|
const stopCache = provider.cache.subscribeQuery(ref, observer);
|
|
42
42
|
if (maxAge === true) {
|
|
43
43
|
// If `maxAge` is true subscribe to the source for as long as this component is attached.
|
package/stream/DataState.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Key, Data,
|
|
1
|
+
import { Key, Data, Transformers } from "../util/index.js";
|
|
2
2
|
import { State } from "./State.js";
|
|
3
3
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
4
|
export declare class DataState<T extends Data> extends State<T> {
|
|
5
5
|
/** Set a prop in this object to a new value. */
|
|
6
6
|
set<K extends Key<T>>(key: K, value: T[K]): void;
|
|
7
7
|
/** Update several props in this object. */
|
|
8
|
-
update(updates:
|
|
8
|
+
update(updates: Transformers<T>): void;
|
|
9
9
|
}
|
package/stream/DataState.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { withProp,
|
|
1
|
+
import { withProp, transformData } from "../util/index.js";
|
|
2
2
|
import { State } from "./State.js";
|
|
3
3
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
4
|
export class DataState extends State {
|
|
@@ -8,6 +8,6 @@ export class DataState extends State {
|
|
|
8
8
|
}
|
|
9
9
|
/** Update several props in this object. */
|
|
10
10
|
update(updates) {
|
|
11
|
-
this.next(
|
|
11
|
+
this.next(transformData(this.value, updates));
|
|
12
12
|
}
|
|
13
13
|
}
|
package/stream/State.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transformer, LOADING, ObserverType, NOERROR, Observer } from "../util/index.js";
|
|
2
2
|
import { Stream } from "./Stream.js";
|
|
3
3
|
/** Any state (useful for `extends AnySubscribable` clauses). */
|
|
4
4
|
export declare type AnyState = State<any>;
|
|
@@ -14,8 +14,8 @@ export declare type AnyState = State<any>;
|
|
|
14
14
|
* */
|
|
15
15
|
export interface State<T> {
|
|
16
16
|
to(): State<T>;
|
|
17
|
-
derive<TT>(
|
|
18
|
-
deriveAsync<TT>(
|
|
17
|
+
derive<TT>(transformer: Transformer<T, TT>): State<TT>;
|
|
18
|
+
deriveAsync<TT>(transformer: Transformer<T, PromiseLike<TT>>): State<TT>;
|
|
19
19
|
}
|
|
20
20
|
export declare class State<T> extends Stream<T> {
|
|
21
21
|
static [Symbol.species]: typeof State;
|
|
@@ -33,7 +33,7 @@ export declare class State<T> extends Stream<T> {
|
|
|
33
33
|
/** Is there a current value, or is it still loading. */
|
|
34
34
|
get loading(): boolean;
|
|
35
35
|
/** Apply a deriver to this state. */
|
|
36
|
-
apply(deriver:
|
|
36
|
+
apply(deriver: Transformer<T, T>): void;
|
|
37
37
|
error(reason: Error | unknown): void;
|
|
38
38
|
_on(observer: Observer<T>): void;
|
|
39
39
|
protected _dispatch(value: T): void;
|
package/stream/State.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
import { LOADING, NOERROR, dispatchNext, dispatchError, dispatchComplete,
|
|
2
|
+
import { LOADING, NOERROR, dispatchNext, dispatchError, dispatchComplete, transform, getRequired, awaitNext, } from "../util/index.js";
|
|
3
3
|
import { Stream } from "./Stream.js";
|
|
4
4
|
export class State extends Stream {
|
|
5
5
|
constructor() {
|
|
@@ -36,7 +36,7 @@ export class State extends Stream {
|
|
|
36
36
|
}
|
|
37
37
|
/** Apply a deriver to this state. */
|
|
38
38
|
apply(deriver) {
|
|
39
|
-
this.next(
|
|
39
|
+
this.next(transform(this.value, deriver));
|
|
40
40
|
}
|
|
41
41
|
// Override to save the reason at `this.reason` and clean up.
|
|
42
42
|
error(reason) {
|
package/stream/Stream.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transformer, ObserverType, Subscribable, Unsubscriber, Observer, Observable, Constructor, Dispatcher } from "../util/index.js";
|
|
2
2
|
/** Any stream (useful for `extends AnyStream` clauses). */
|
|
3
3
|
export declare type AnyStream = Stream<any>;
|
|
4
4
|
/**
|
|
@@ -44,12 +44,12 @@ export declare class Stream<T> implements Observer<T>, Observable<T> {
|
|
|
44
44
|
/** Create a new stream from this stream. */
|
|
45
45
|
to<O extends AnyStream>(target: O): O;
|
|
46
46
|
to(): Stream<T>;
|
|
47
|
-
/** Derive a new stream from this stream using a
|
|
48
|
-
derive<O extends AnyStream>(
|
|
49
|
-
derive<TT>(
|
|
50
|
-
/** Derive a new stream from this stream using an async
|
|
51
|
-
deriveAsync<O extends AnyStream>(
|
|
52
|
-
deriveAsync<TT>(
|
|
47
|
+
/** Derive a new stream from this stream using a transformer. */
|
|
48
|
+
derive<O extends AnyStream>(transformer: Transformer<T, ObserverType<O>>, target: O): O;
|
|
49
|
+
derive<TT>(transformer: Transformer<T, TT>): Stream<T>;
|
|
50
|
+
/** Derive a new stream from this stream using an async transformer. */
|
|
51
|
+
deriveAsync<O extends AnyStream>(transformer: Transformer<T, Promise<ObserverType<O>>>, target: O): O;
|
|
52
|
+
deriveAsync<TT>(transformer: Transformer<T, PromiseLike<TT>>): Stream<T>;
|
|
53
53
|
/**
|
|
54
54
|
* Subscribe to this stream and return an unsubscriber function.
|
|
55
55
|
* - Allows either an `Observer` object or separate `next()`, `error()` and `complete()` functions.
|
package/stream/Stream.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
import { AsyncObserver,
|
|
2
|
+
import { AsyncObserver, TransformObserver, dispatchNext, dispatchError, dispatchComplete, subscribe, dispatch, } from "../util/index.js";
|
|
3
3
|
import { ConditionError } from "../error/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* Simple stream.
|
|
@@ -89,12 +89,12 @@ export class Stream {
|
|
|
89
89
|
target.during(this, target);
|
|
90
90
|
return target;
|
|
91
91
|
}
|
|
92
|
-
derive(
|
|
93
|
-
target.during(this, new
|
|
92
|
+
derive(transformer, target = new this.constructor[Symbol.species]()) {
|
|
93
|
+
target.during(this, new TransformObserver(transformer, target));
|
|
94
94
|
return target;
|
|
95
95
|
}
|
|
96
|
-
deriveAsync(
|
|
97
|
-
target.during(this, new
|
|
96
|
+
deriveAsync(transformer, target = new this.constructor[Symbol.species]()) {
|
|
97
|
+
target.during(this, new TransformObserver(transformer, new AsyncObserver(target)));
|
|
98
98
|
return target;
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
@@ -4,7 +4,7 @@ import { Transform } from "./Transform.js";
|
|
|
4
4
|
export declare class AddEntriesTransform<T> extends Transform<ImmutableObject<T>> implements Iterable<Entry<T>> {
|
|
5
5
|
readonly props: ImmutableObject<T>;
|
|
6
6
|
constructor(props: ImmutableObject<T>);
|
|
7
|
-
|
|
7
|
+
transform(existing?: unknown): ImmutableObject<T>;
|
|
8
8
|
/** Iterate over the entries. */
|
|
9
9
|
[Symbol.iterator](): Iterator<Entry<T>, void>;
|
|
10
10
|
}
|
|
@@ -4,7 +4,7 @@ import { Transform } from "./Transform.js";
|
|
|
4
4
|
export declare class AddItemsTransform<T> extends Transform<ImmutableArray<T>> implements Iterable<T> {
|
|
5
5
|
readonly items: ImmutableArray<T>;
|
|
6
6
|
constructor(...items: ImmutableArray<T>);
|
|
7
|
-
|
|
7
|
+
transform(existing?: unknown): ImmutableArray<T>;
|
|
8
8
|
/** Iterate over the items. */
|
|
9
9
|
[Symbol.iterator](): Iterator<T, void>;
|
|
10
10
|
}
|