shelving 1.23.0 → 1.25.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 CHANGED
@@ -2,7 +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 { Write } from "./Write.js";
5
+ import { DocumentWrite, Write, Writes } from "./Write.js";
6
6
  /**
7
7
  * Combines a database model and a provider.
8
8
  *
@@ -18,6 +18,10 @@ export declare class Database<V extends Validators<Datas> = Validators<Datas>> {
18
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]>>;
19
19
  /** Reference a document in a collection in this model. */
20
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>;
21
25
  }
22
26
  /** A documents reference within a specific database. */
23
27
  export declare class DataQuery<T extends Data = Data> extends Query<T> implements Observable<Results<T>>, Validatable<Results<T>>, Iterable<Entry<T>> {
@@ -151,13 +155,13 @@ export declare class DataDocument<T extends Data = Data> implements Observable<R
151
155
  /** Set, update, or delete this document. */
152
156
  write(value: Result<T> | Transform<T>): void | PromiseLike<void>;
153
157
  /** Represent a write that sets the complete data of this document in a database. */
154
- setter(data: T): Write<T>;
158
+ setter(data: T): DocumentWrite<T>;
155
159
  /** Represent a write that updates this document in a database. */
156
- updater(transforms: Transform<T> | Transforms<T>): Write<T>;
160
+ updater(transforms: Transform<T> | Transforms<T>): DocumentWrite<T>;
157
161
  /** Represent a write that deletes this document in a database. */
158
- deleter(): Write<T>;
162
+ deleter(): DocumentWrite<T>;
159
163
  /** Represent a write that sets, updates, or deletes this document in a database. */
160
- writer(value: Result<T> | Transform<T>): Write<T>;
164
+ writer(value: Result<T> | Transform<T>): DocumentWrite<T>;
161
165
  /** Validate data for this query reference. */
162
166
  validate(unsafeData: Data): T;
163
167
  toString(): string;
package/db/Database.js CHANGED
@@ -3,7 +3,7 @@ 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 { Write } from "./Write.js";
6
+ import { DocumentWrite, Writes } from "./Write.js";
7
7
  /**
8
8
  * Combines a database model and a provider.
9
9
  *
@@ -25,6 +25,17 @@ export class Database {
25
25
  doc(collection, id) {
26
26
  return new DataDocument(this.provider, this.validators[collection], collection, id);
27
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
+ }
28
39
  }
29
40
  /** A documents reference within a specific database. */
30
41
  export class DataQuery extends Query {
@@ -239,7 +250,7 @@ export class DataDocument {
239
250
  }
240
251
  /** Represent a write that sets, updates, or deletes this document in a database. */
241
252
  writer(value) {
242
- return new Write(this, value);
253
+ return new DocumentWrite(this, value);
243
254
  }
244
255
  /** Validate data for this query reference. */
245
256
  validate(unsafeData) {
package/db/Write.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { Transform } from "../transform/index.js";
2
2
  import { ImmutableArray, Data, Transformable } from "../util/index.js";
3
3
  import type { Database, DataDocument } from "./Database.js";
4
- /** Change transformable. */
5
- export declare type DatabaseTransformable = Transformable<Database, void | PromiseLike<void>>;
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
+ }
6
8
  /** Represent a write made to a single document in a database. */
7
- export declare class Write<T extends Data> implements Transformable<Database, void | PromiseLike<void>> {
9
+ export declare class DocumentWrite<T extends Data> extends Write {
8
10
  readonly collection: string;
9
11
  readonly id: string;
10
12
  readonly value: Data | Transform<Data> | undefined;
@@ -12,17 +14,17 @@ export declare class Write<T extends Data> implements Transformable<Database, vo
12
14
  transform(db: Database): Promise<void>;
13
15
  }
14
16
  /**
15
- * Represent a list of writes made to a set of documents in a database.
17
+ * Represent a list of writes made to a database.
16
18
  * - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
17
19
  * - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
18
20
  */
19
- export declare class Writes implements Transformable<Database, void | PromiseLike<void>> {
20
- readonly writes: ImmutableArray<Write<Data>>;
21
- constructor(...writes: Write<Data>[]);
21
+ export declare class Writes extends Write {
22
+ readonly writes: ImmutableArray<Write>;
23
+ constructor(...writes: (Write | undefined)[]);
22
24
  transform(db: Database): Promise<void>;
23
25
  }
24
26
  /** Set of hydrations for all change classes. */
25
- export declare const DATABASE_HYDRATIONS: {
26
- changes: typeof Writes;
27
- change: typeof Write;
27
+ export declare const WRITE_HYDRATIONS: {
28
+ writes: typeof Writes;
29
+ write: typeof DocumentWrite;
28
30
  };
package/db/Write.js CHANGED
@@ -1,7 +1,11 @@
1
- import { transform } from "../util/index.js";
2
- /** Represent a write made to a single document in a database. */
1
+ import { transform, IS_DEFINED } from "../util/index.js";
2
+ /** Write to a database. */
3
3
  export class Write {
4
+ }
5
+ /** Represent a write made to a single document in a database. */
6
+ export class DocumentWrite extends Write {
4
7
  constructor({ collection, id }, value) {
8
+ super();
5
9
  this.collection = collection;
6
10
  this.id = id;
7
11
  this.value = value;
@@ -11,13 +15,14 @@ export class Write {
11
15
  }
12
16
  }
13
17
  /**
14
- * Represent a list of writes made to a set of documents in a database.
18
+ * Represent a list of writes made to a database.
15
19
  * - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
16
20
  * - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
17
21
  */
18
- export class Writes {
22
+ export class Writes extends Write {
19
23
  constructor(...writes) {
20
- this.writes = writes;
24
+ super();
25
+ this.writes = writes.filter(IS_DEFINED);
21
26
  }
22
27
  async transform(db) {
23
28
  for (const writes of this.writes)
@@ -25,8 +30,8 @@ export class Writes {
25
30
  }
26
31
  }
27
32
  /** Set of hydrations for all change classes. */
28
- export const DATABASE_HYDRATIONS = {
29
- changes: Writes,
30
- change: Write,
33
+ export const WRITE_HYDRATIONS = {
34
+ writes: Writes,
35
+ write: DocumentWrite,
31
36
  };
32
- DATABASE_HYDRATIONS;
37
+ WRITE_HYDRATIONS;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.23.0",
14
+ "version": "1.25.0",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",
package/stream/State.d.ts CHANGED
@@ -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>(deriver: Transformer<T, TT>): State<TT>;
18
- deriveAsync<TT>(deriver: Transformer<T, Promise<TT>>): State<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;
@@ -49,7 +49,7 @@ export declare class Stream<T> implements Observer<T>, Observable<T> {
49
49
  derive<TT>(transformer: Transformer<T, TT>): Stream<T>;
50
50
  /** Derive a new stream from this stream using an async transformer. */
51
51
  deriveAsync<O extends AnyStream>(transformer: Transformer<T, Promise<ObserverType<O>>>, target: O): O;
52
- deriveAsync<TT>(transformer: Transformer<T, Promise<TT>>): Stream<T>;
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.
@@ -13,10 +13,13 @@ export declare type Transforms<T extends Data> = {
13
13
  /** Set of transforms that can be appled to an object's properties. */
14
14
  export declare class DataTransform<T extends Data> extends Transform<T> implements Iterable<Prop<Transforms<T>>> {
15
15
  readonly transforms: Transforms<T>;
16
- constructor(transforms: Transforms<T>);
16
+ constructor(transforms?: Transforms<T>);
17
17
  transform(existing: T): T;
18
- /** Return a new object with the specified additional transform. */
19
- prop<K extends Key<T>>(key: K, transform: T[K] | Transform<T[K]>): this;
18
+ /**
19
+ * Return a new object with the specified additional transform.
20
+ * - If `key` is `undefined` the prop is skipped to make it easy to make conditional data transforms.
21
+ */
22
+ prop<K extends Key<T>>(key: K | undefined, transform: T[K] | Transform<T[K]>): this;
20
23
  /** Return a new object with the specified additional transforms. */
21
24
  props(transforms: Transforms<T>): this;
22
25
  /** Iterate over the transforms in this object. */
@@ -2,15 +2,20 @@ import { transformData } from "../util/index.js";
2
2
  import { Transform } from "./Transform.js";
3
3
  /** Set of transforms that can be appled to an object's properties. */
4
4
  export class DataTransform extends Transform {
5
- constructor(transforms) {
5
+ constructor(transforms = {}) {
6
6
  super();
7
7
  this.transforms = transforms;
8
8
  }
9
9
  transform(existing) {
10
10
  return transformData(existing, this.transforms);
11
11
  }
12
- /** Return a new object with the specified additional transform. */
12
+ /**
13
+ * Return a new object with the specified additional transform.
14
+ * - If `key` is `undefined` the prop is skipped to make it easy to make conditional data transforms.
15
+ */
13
16
  prop(key, transform) {
17
+ if (key === undefined)
18
+ return this;
14
19
  return { __proto__: Object.getPrototypeOf(this), ...this, transforms: { ...this.transforms, [key]: transform } };
15
20
  }
16
21
  /** Return a new object with the specified additional transforms. */
@@ -9,6 +9,8 @@ export interface Transformable<I, O> {
9
9
  }
10
10
  /** Any applier (useful for `extends AnyTransformr` clauses). */
11
11
  export declare type AnyTransformable = Transformable<any, any>;
12
+ /** Is an unknown value a derivable. */
13
+ export declare const isApplier: <T extends AnyTransformable>(v: unknown) => v is T;
12
14
  /** Function that takes an input value and returns a value transformed from it, or an applier with matching arguments. */
13
15
  export declare type Transformer<I, O> = Transformable<I, O> | ((input: I) => O) | O;
14
16
  /** Any transformer (useful for `extends AnyTransformr` clauses). */
@@ -17,31 +19,18 @@ export declare type AnyTransformer = Transformer<any, any>;
17
19
  export declare type TransformedType<T extends AnyTransformer> = T extends Transformer<unknown, infer TT> ? TT : never;
18
20
  /** Is an unknown value a transformer. */
19
21
  export declare const isTransformer: <T extends unknown>(v: unknown) => v is T;
20
- /** Is an unknown value a derivable. */
21
- export declare const isTransformable: <T extends AnyTransformable>(v: unknown) => v is T;
22
22
  /** Transform a value using a transformer. */
23
23
  export declare function transform<I, O>(input: I, transformer: (v: I) => O): O;
24
24
  export declare function transform<I, O>(input: I, transformer: Transformer<I, O>): O;
25
25
  /**
26
26
  * Apply a transformer to each item in a set of items and yield the transformed item.
27
- *
28
27
  * @yield Transformed items after calling `transformer()` on each.
29
- * @returns Number of items that changed.
30
28
  */
31
29
  export declare function transformItems<I, O>(items: Iterable<I>, transformer: (input: I) => O): Iterable<O>;
32
30
  export declare function transformItems<I, O>(items: Iterable<I>, transformer: Transformer<I, O>): Iterable<O>;
33
31
  /**
34
32
  * Apply a transformer to each item in an array and return the transformed array.
35
- *
36
- * @param arr The input array or map-like object or iterable to iterate over.
37
- * @param mapper Mapping function that receives the value and key and returns the corresponding value.
38
- * - Mapper can return a promise. If it does will return a Promise that resolves once every value has resolved.
39
- * - Return the `SKIP` symbol from the mapper to skip that property and not include it in the output object.
40
- * - `SKIP` is useful because using `filter(Boolean)` doesn't currently filter in TypeScript (and requires another loop anyway).
41
- * - Mapper can be a non-function static value and all the values will be set to that value.
42
- *
43
- * @return The mapped array.
44
- * - Immutable so if the values don't change then the same instance will be returned.
33
+ * @return The transformed array.
45
34
  */
46
35
  export declare function transformArray<T extends ImmutableArray>(arr: T, transformer: Transformer<ArrayType<T>, ArrayType<T>>): T;
47
36
  export declare function transformArray<I, O>(arr: Iterable<I>, transformer: (v: I) => O): ImmutableArray<O>;
package/util/transform.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { isFunction } from "./function.js";
2
2
  import { toProps, isData } from "./data.js";
3
3
  import { WatchIterator } from "./iterate.js";
4
- /** Is an unknown value a transformer. */
5
- export const isTransformer = (v) => typeof v === "function" || isTransformable(v);
6
4
  /** Is an unknown value a derivable. */
7
- export const isTransformable = (v) => isData(v) && typeof v.transform === "function";
5
+ export const isApplier = (v) => isData(v) && typeof v.transform === "function";
6
+ /** Is an unknown value a transformer. */
7
+ export const isTransformer = (v) => typeof v === "function" || isApplier(v);
8
8
  export function transform(input, transformer) {
9
- return isFunction(transformer) ? transformer(input) : isTransformable(transformer) ? transformer.transform(input) : transformer;
9
+ return isFunction(transformer) ? transformer(input) : isApplier(transformer) ? transformer.transform(input) : transformer;
10
10
  }
11
11
  export function* transformItems(items, transformer) {
12
12
  for (const item of items)