firetender 0.6.0 → 0.7.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/README.md CHANGED
@@ -66,7 +66,8 @@ const pizzaSchema = z.object({
66
66
 
67
67
  const pizzaCollection = new FiretenderCollection(
68
68
  pizzaSchema,
69
- [firestore, "pizzas"],
69
+ firestore,
70
+ "pizzas",
70
71
  { creationTime: nowTimestamp() }
71
72
  );
72
73
  ```
@@ -240,12 +241,39 @@ of its subcollections' docs, then call `delete()` on each doc. The Firestore
240
241
  guide recommends only performing such unbounded batched deletions from a trusted
241
242
  server environment.
242
243
 
244
+ ### Update all matching documents
245
+
246
+ In an inventory of items, markup by 10% all items awaiting a price increase.
247
+
248
+ ```javascript
249
+ const itemSchema = z.object({
250
+ name: z.string(),
251
+ price: z.number().nonnegative(),
252
+ tags: z.array(z.string()),
253
+ });
254
+ const inventoryCollection = new FiretenderCollection(itemSchema, [
255
+ firestore,
256
+ "inventory",
257
+ ]);
258
+
259
+ await Promise.all(
260
+ inventoryCollection
261
+ .query(where("tags", "array-contains", "awaiting-price-increase"))
262
+ .map((itemDoc) =>
263
+ itemDoc.update((data) => {
264
+ data.price *= 1.1;
265
+ delete data.tags["awaiting-price-increase"];
266
+ })
267
+ )
268
+ );
269
+ ```
270
+
243
271
  ## TODO
244
272
 
245
273
  The [full list of issues](https://github.com/jakes-space/firetender/issues) is
246
274
  tracked on Github. Here are some features on the roadmap:
247
275
 
248
- * Dcoumentation
276
+ * Documentation
249
277
  * Compile JSDoc to an API reference page in markdown.
250
278
  ([#13](https://github.com/jakes-space/firetender/issues/13))
251
279
  * Concurrency
@@ -1,24 +1,32 @@
1
1
  import { Firestore, QueryConstraint } from "firebase/firestore";
2
2
  import { z } from "zod";
3
- import { FiretenderDoc, PublicFiretenderDocOptions } from "./FiretenderDoc";
3
+ import { FiretenderDoc, FiretenderDocOptions } from "./FiretenderDoc";
4
4
  import { DeepPartial } from "./ts-helpers";
5
5
  /**
6
6
  * A representation of a Firestore collection or subcollection.
7
+ *
8
+ * It represents a given "collection path": the collection names from a document
9
+ * reference, sans IDs. All docs at /databases/{db}/documents/foo/{*}/bar/{*}
10
+ * are covered by a FiretenderCollection for the path ["foo", "bar"].
7
11
  */
8
12
  export declare class FiretenderCollection<SchemaType extends z.SomeZodObject, DataType extends z.infer<SchemaType> = z.infer<SchemaType>, InputType extends z.input<SchemaType> = z.input<SchemaType>> {
13
+ /** Zod schema used to parse and validate the document's data */
9
14
  readonly schema: SchemaType;
15
+ /** Firestore object: the thing you get from getFirestore() */
10
16
  readonly firestore: Firestore;
11
- readonly collectionNames: string[];
17
+ /** The collection path of this object: a series of collection names */
18
+ readonly collectionPath: string[];
19
+ /** Initial values to be filled in when creating a new document */
12
20
  readonly baseInitialData: DeepPartial<InputType> | undefined;
13
21
  /**
14
22
  * @param schema the Zod object schema describing the documents in this
15
23
  * collection.
16
- * @param collectionPath the path of this collection in Firestore. The first
17
- * entry must be a Firestore object, followed by the names of any parent
18
- * collections and of this collection.
24
+ * @param firestore the thing you get from getFirestore().
25
+ * @param collectionPath the path of this collection in Firestore: the names
26
+ * of any parent collections and of this collection.
19
27
  * @param baseInitialData (optional) default field values for this collection.
20
28
  */
21
- constructor(schema: SchemaType, collectionPath: [Firestore, ...string[]], baseInitialData?: DeepPartial<z.input<SchemaType>> | undefined);
29
+ constructor(schema: SchemaType, firestore: Firestore, collectionPath: [string, ...string[]] | string, baseInitialData?: DeepPartial<z.input<SchemaType>> | undefined);
22
30
  /**
23
31
  * Returns a FiretenderDoc representing a new document in this collection.
24
32
  *
@@ -33,7 +41,7 @@ export declare class FiretenderCollection<SchemaType extends z.SomeZodObject, Da
33
41
  * @param options optional parameters for the resulting FiretenderDoc; see
34
42
  * FiretenderDocOptions for detail.
35
43
  */
36
- newDoc(id?: string[] | string | undefined, initialData?: DeepPartial<InputType> | undefined, options?: PublicFiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
44
+ newDoc(id?: string[] | string | undefined, initialData?: DeepPartial<InputType> | undefined, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
37
45
  /**
38
46
  * Returns a FiretenderDoc representing an existing Firestore document in this
39
47
  * collection.
@@ -45,12 +53,12 @@ export declare class FiretenderCollection<SchemaType extends z.SomeZodObject, Da
45
53
  * @param options optional parameters for the resulting FiretenderDoc; see
46
54
  * FiretenderDocOptions for detail.
47
55
  */
48
- existingDoc(id: string[] | string, options?: PublicFiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
56
+ existingDoc(id: string[] | string, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
49
57
  /**
50
58
  * Returns an array of all the documents in this collection.
51
59
  *
52
60
  * If the collection may contain a large number of documents, use query() with
53
- * the limit() and startAfter() contraints to paginate the results.
61
+ * the limit() and startAfter() constraints to paginate the results.
54
62
  *
55
63
  * @param id (optional) when querying a subcollection, the ID(s) of its parent
56
64
  * collection(s).
@@ -5,20 +5,24 @@ const firestore_1 = require("firebase/firestore");
5
5
  const FiretenderDoc_1 = require("./FiretenderDoc");
6
6
  /**
7
7
  * A representation of a Firestore collection or subcollection.
8
+ *
9
+ * It represents a given "collection path": the collection names from a document
10
+ * reference, sans IDs. All docs at /databases/{db}/documents/foo/{*}/bar/{*}
11
+ * are covered by a FiretenderCollection for the path ["foo", "bar"].
8
12
  */
9
13
  class FiretenderCollection {
10
14
  /**
11
15
  * @param schema the Zod object schema describing the documents in this
12
16
  * collection.
13
- * @param collectionPath the path of this collection in Firestore. The first
14
- * entry must be a Firestore object, followed by the names of any parent
15
- * collections and of this collection.
17
+ * @param firestore the thing you get from getFirestore().
18
+ * @param collectionPath the path of this collection in Firestore: the names
19
+ * of any parent collections and of this collection.
16
20
  * @param baseInitialData (optional) default field values for this collection.
17
21
  */
18
- constructor(schema, collectionPath, baseInitialData = undefined) {
22
+ constructor(schema, firestore, collectionPath, baseInitialData = undefined) {
19
23
  this.schema = schema;
20
- this.firestore = collectionPath[0];
21
- this.collectionNames = collectionPath.slice(1);
24
+ this.firestore = firestore;
25
+ this.collectionPath = [collectionPath].flat();
22
26
  if (baseInitialData) {
23
27
  this.baseInitialData = baseInitialData;
24
28
  }
@@ -77,7 +81,7 @@ class FiretenderCollection {
77
81
  * Returns an array of all the documents in this collection.
78
82
  *
79
83
  * If the collection may contain a large number of documents, use query() with
80
- * the limit() and startAfter() contraints to paginate the results.
84
+ * the limit() and startAfter() constraints to paginate the results.
81
85
  *
82
86
  * @param id (optional) when querying a subcollection, the ID(s) of its parent
83
87
  * collection(s).
@@ -116,7 +120,7 @@ class FiretenderCollection {
116
120
  }
117
121
  let ref = this.makeCollectionRef(ids);
118
122
  if (!ref) {
119
- ref = (0, firestore_1.collectionGroup)(this.firestore, this.collectionNames[this.collectionNames.length - 1]);
123
+ ref = (0, firestore_1.collectionGroup)(this.firestore, this.collectionPath[this.collectionPath.length - 1]);
120
124
  }
121
125
  return this.getAndWrapDocs((0, firestore_1.query)(ref, ...whereClauses));
122
126
  }
@@ -144,10 +148,10 @@ class FiretenderCollection {
144
148
  * not correctly specify a doc path.
145
149
  */
146
150
  makeDocRef(ids) {
147
- if (ids.length !== this.collectionNames.length) {
151
+ if (ids.length !== this.collectionPath.length) {
148
152
  return undefined;
149
153
  }
150
- const path = ids.flatMap((id, i) => [this.collectionNames[i], id]);
154
+ const path = ids.flatMap((id, i) => [this.collectionPath[i], id]);
151
155
  return (0, firestore_1.doc)(this.firestore, path[0], ...path.slice(1));
152
156
  }
153
157
  /**
@@ -155,11 +159,11 @@ class FiretenderCollection {
155
159
  * IDs do not correctly specify a collection path.
156
160
  */
157
161
  makeCollectionRef(ids) {
158
- if (ids.length !== this.collectionNames.length - 1) {
162
+ if (ids.length !== this.collectionPath.length - 1) {
159
163
  return undefined;
160
164
  }
161
- const subPath = ids.flatMap((id, i) => [id, this.collectionNames[i + 1]]);
162
- return (0, firestore_1.collection)(this.firestore, this.collectionNames[0], ...subPath);
165
+ const subPath = ids.flatMap((id, i) => [id, this.collectionPath[i + 1]]);
166
+ return (0, firestore_1.collection)(this.firestore, this.collectionPath[0], ...subPath);
163
167
  }
164
168
  /**
165
169
  * Executes the given query and returns an array of the results, wrapped in
@@ -1 +1 @@
1
- {"version":3,"file":"FiretenderCollection.js","sourceRoot":"","sources":["../src/FiretenderCollection.ts"],"names":[],"mappings":";;;AAAA,kDAY4B;AAG5B,mDAA4E;AAG5E;;GAEG;AACH,MAAa,oBAAoB;IAU/B;;;;;;;OAOG;IACH,YACE,MAAkB,EAClB,cAAwC,EACxC,kBAAgE,SAAS;QAEzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QAC3D,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;SACxC;IACH,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CACJ,KAAoC,SAAS,EAC7C,cAAkD,SAAS,EAC3D,UAAsC,EAAE;QAExC,MAAM,GAAG,GAAG,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,GACL,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,GAAG,EAAE;YACR,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;SACnC;QACD,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,KAAK,CACT,kGAAkG,CACnG,CAAC;SACH;QACD,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;SAC3C;QACD,IAAI,WAAW,EAAE;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;SAClC;QACD,OAAO,6BAAa,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;;OAUG;IACH,WAAW,CACT,EAAqB,EACrB,UAAsC,EAAE;QAExC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,KAAK,CACT,+FAA+F,CAChG,CAAC;SACH;QACD,OAAO,IAAI,6BAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,UAAU,CACd,KAAoC,SAAS;QAE7C,MAAM,GAAG,GAAG,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,KAAK,CACT,yFAAyF,CAC1F,CAAC;SACH;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,KAAK,CACT,eAAoD,EACpD,GAAG,gBAAmC;QAEtC,IAAI,GAAa,CAAC;QAClB,IAAI,YAA+B,CAAC;QACpC,IAAI,eAAe,YAAY,KAAK,EAAE;YACpC,GAAG,GAAG,eAAe,CAAC;YACtB,YAAY,GAAG,gBAAgB,CAAC;SACjC;aAAM,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE;YAC9C,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;YACxB,YAAY,GAAG,gBAAgB,CAAC;SACjC;aAAM;YACL,GAAG,GAAG,EAAE,CAAC;YACT,YAAY,GAAG,CAAC,eAAe,EAAE,GAAG,gBAAgB,CAAC,CAAC;SACvD;QACD,IAAI,GAAG,GACL,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,EAAE;YACR,GAAG,GAAG,IAAA,2BAAe,EACnB,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CACtD,CAAC;SACH;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAA,iBAAK,EAAC,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,MAAM,CAAC,EAAqB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,KAAK,CAAC,4DAA4D,CAAC,CAAC;SAC3E;QACD,MAAM,IAAA,qBAAS,EAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,8EAA8E;IAC9E,oBAAoB;IAEpB;;;OAGG;IACK,UAAU,CAAC,GAAa;QAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAC9C,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,IAAA,eAAG,EAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,GAAa;QACrC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;YAClD,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;IACzE,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,cAAc,CAC1B,KAAkC;QAElC,MAAM,aAAa,GAAG,MAAM,IAAA,mBAAO,EAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,CAC3B,CAAC,QAAQ,EAAE,EAAE,CACX,IAAI,6BAAa,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE;YAC3C,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;SAC7B,CAAC,CACL,CAAC;IACJ,CAAC;CACF;AArND,oDAqNC"}
1
+ {"version":3,"file":"FiretenderCollection.js","sourceRoot":"","sources":["../src/FiretenderCollection.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,19 @@ import { CollectionReference, DocumentReference } from "firebase/firestore";
2
2
  import { z } from "zod";
3
3
  import { DeepReadonly } from "./ts-helpers";
4
4
  /**
5
- * Options when initializing a FiretenderDoc object.
5
+ * Public options for initializing a FiretenderDoc object.
6
+ *
7
+ * These will be added as needed (e.g., "readonly" for issue #1, possibly
8
+ * "queryPageLength" for issue #21).
6
9
  */
7
- export declare type FiretenderDocOptions = {
10
+ export declare type FiretenderDocOptions = {};
11
+ /**
12
+ * All options when initializing a FiretenderDoc object.
13
+ *
14
+ * This type includes options meant for internal use (createDoc, initialData)
15
+ * as well as the options in FiretenderDocOptions.
16
+ */
17
+ export declare type AllFiretenderDocOptions = FiretenderDocOptions & {
8
18
  /**
9
19
  * Does this FiretenderDoc represent a new document in Firestore?
10
20
  */
@@ -16,20 +26,24 @@ export declare type FiretenderDocOptions = {
16
26
  initialData?: Record<string, any>;
17
27
  };
18
28
  /**
19
- * Options when initializing a FiretenderDoc object, omitting options that are
20
- * intended principally for internal use.
21
- */
22
- export declare type PublicFiretenderDocOptions = Omit<FiretenderDocOptions, "createDoc" | "initialData">;
23
- /**
24
- * A representation of a Firestore document.
29
+ * A local representation of a Firestore document.
25
30
  */
26
- export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType extends z.infer<SchemaType> = z.infer<SchemaType>> {
31
+ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType extends z.infer<SchemaType> = z.infer<SchemaType>, InputType extends z.input<SchemaType> = z.input<SchemaType>> {
32
+ /** Zod schema used to parse and validate the document's data */
27
33
  readonly schema: SchemaType;
34
+ /** Firestore reference to this doc, or collection in which to create it */
28
35
  private ref;
29
- private isNewDoc;
36
+ /** Firestore document ID; undefined for new docs not yet on Firestore */
30
37
  private docID;
38
+ /** Is this a doc we presume does not yet exist in Firestore? */
39
+ private isNewDoc;
40
+ /** Use addDoc or setDoc to write all the data? If not, use updateDoc. */
41
+ private isSettingNewContents;
42
+ /** Local copy of the document data, parsed into the Zod type */
31
43
  private data;
44
+ /** Proxy to intercept write (.w) access to the data and track the changes */
32
45
  private dataProxy;
46
+ /** Map from the dot-delimited field path (per updateDoc()) to new value */
33
47
  private updates;
34
48
  /**
35
49
  * @param schema the Zod object schema describing this document's data.
@@ -39,7 +53,7 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
39
53
  * @param options optional parameters for the resulting FiretenderDoc; see
40
54
  * FiretenderDocOptions for detail.
41
55
  */
42
- constructor(schema: SchemaType, ref: DocumentReference | CollectionReference, options?: FiretenderDocOptions);
56
+ constructor(schema: SchemaType, ref: DocumentReference | CollectionReference, options?: AllFiretenderDocOptions);
43
57
  /**
44
58
  * Returns a FiretenderDoc representing a new Firestore document.
45
59
  *
@@ -55,13 +69,14 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
55
69
  * @param options optional parameters for the resulting FiretenderDoc; see
56
70
  * FiretenderDocOptions for detail.
57
71
  */
58
- static createNewDoc<SchemaType1 extends z.SomeZodObject, InputType extends z.input<SchemaType1> = z.input<SchemaType1>>(schema: SchemaType1, ref: DocumentReference | CollectionReference, initialData: InputType, options?: PublicFiretenderDocOptions): FiretenderDoc<SchemaType1, z.infer<SchemaType1>>;
72
+ static createNewDoc<SchemaType1 extends z.SomeZodObject, InputType1 extends z.input<SchemaType1> = z.input<SchemaType1>>(schema: SchemaType1, ref: DocumentReference | CollectionReference, initialData: InputType1, options?: FiretenderDocOptions): FiretenderDoc<SchemaType1, z.infer<SchemaType1>>;
59
73
  /**
60
- * Create a copy of this document. Returns a deep copy of its data with a new
61
- * Firestore ID and reference.
74
+ * Creates a copy of this document. Returns a deep copy of its data with a
75
+ * new Firestore ID and reference.
62
76
  *
63
77
  * This method does not create the document in Firestore. To do so, call the
64
- * write() method.
78
+ * write() method. If an ID or doc ref is not provided, those will be unset
79
+ * until the write.
65
80
  *
66
81
  * @param dest the destination can be a string or undefined to create a copy
67
82
  * in the same collection, or a document or collection reference to create
@@ -70,7 +85,7 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
70
85
  * @param options optional parameters for the resulting FiretenderDoc; see
71
86
  * FiretenderDocOptions for detail.
72
87
  */
73
- copy(dest?: DocumentReference | CollectionReference | string | undefined, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
88
+ copy(dest?: DocumentReference | CollectionReference | string | undefined, options?: AllFiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
74
89
  /**
75
90
  * The document's ID string.
76
91
  *
@@ -92,7 +107,7 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
92
107
  */
93
108
  isPendingWrite(): boolean;
94
109
  /**
95
- * Load this document's data from Firestore.
110
+ * Loads this document's data from Firestore.
96
111
  *
97
112
  * @param force force a read from Firestore. Normally load() does nothing if
98
113
  * the document already contains data.
@@ -103,18 +118,22 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
103
118
  */
104
119
  get r(): DeepReadonly<DataType>;
105
120
  /**
106
- * Writable accessor to the contents of this document.
121
+ * Writable accessor to update the contents of this document.
107
122
  *
108
123
  * Only use this accessor when making changes to the doc. The .r accessor is
109
124
  * considerably more efficient when reading.
110
125
  */
111
126
  get w(): DataType;
112
127
  /**
113
- * Write the document or any updates to Firestore.
128
+ * Writable accessor to overwrite all the document data.
129
+ */
130
+ set w(newData: InputType);
131
+ /**
132
+ * Writes the document or any updates to Firestore.
114
133
  */
115
134
  write(): Promise<this>;
116
135
  /**
117
- * Update the document's data with a single call.
136
+ * Updates the document's data with a single call.
118
137
  *
119
138
  * This function loads the document's data, if necessary; calls the given
120
139
  * function to make changes to the data; then write the changes to Firestore.
@@ -124,6 +143,10 @@ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType
124
143
  * changes to it.
125
144
  */
126
145
  update(mutator: (data: DataType) => void): Promise<this>;
127
- /** Add the field and its new value to the list of updates. */
128
- private onChange;
146
+ /**
147
+ * Adds a field and its new value to the list of updates to be passed to
148
+ * Firestore's updateDoc(). Called when the proxies detect changes to the
149
+ * document data.
150
+ */
151
+ private addToUpdateList;
129
152
  }
@@ -5,7 +5,7 @@ const firestore_1 = require("firebase/firestore");
5
5
  const proxies_1 = require("./proxies");
6
6
  const ts_helpers_1 = require("./ts-helpers");
7
7
  /**
8
- * A representation of a Firestore document.
8
+ * A local representation of a Firestore document.
9
9
  */
10
10
  class FiretenderDoc {
11
11
  /**
@@ -17,13 +17,18 @@ class FiretenderDoc {
17
17
  * FiretenderDocOptions for detail.
18
18
  */
19
19
  constructor(schema, ref, options = {}) {
20
+ /** Firestore document ID; undefined for new docs not yet on Firestore */
20
21
  this.docID = undefined;
22
+ /** Local copy of the document data, parsed into the Zod type */
21
23
  this.data = undefined;
24
+ /** Proxy to intercept write (.w) access to the data and track the changes */
22
25
  this.dataProxy = undefined;
26
+ /** Map from the dot-delimited field path (per updateDoc()) to new value */
23
27
  this.updates = new Map();
24
28
  this.schema = schema;
25
29
  this.ref = ref;
26
30
  this.isNewDoc = options.createDoc ?? false;
31
+ this.isSettingNewContents = this.isNewDoc;
27
32
  if (options.initialData) {
28
33
  this.data = schema.parse(options.initialData);
29
34
  }
@@ -61,11 +66,12 @@ class FiretenderDoc {
61
66
  return new FiretenderDoc(schema, ref, mergedOptions);
62
67
  }
63
68
  /**
64
- * Create a copy of this document. Returns a deep copy of its data with a new
65
- * Firestore ID and reference.
69
+ * Creates a copy of this document. Returns a deep copy of its data with a
70
+ * new Firestore ID and reference.
66
71
  *
67
72
  * This method does not create the document in Firestore. To do so, call the
68
- * write() method.
73
+ * write() method. If an ID or doc ref is not provided, those will be unset
74
+ * until the write.
69
75
  *
70
76
  * @param dest the destination can be a string or undefined to create a copy
71
77
  * in the same collection, or a document or collection reference to create
@@ -130,10 +136,10 @@ class FiretenderDoc {
130
136
  * Does this document contain data that has not yet been written to Firestore?
131
137
  */
132
138
  isPendingWrite() {
133
- return this.isNewDoc || this.updates.size > 0;
139
+ return this.isSettingNewContents || this.updates.size > 0;
134
140
  }
135
141
  /**
136
- * Load this document's data from Firestore.
142
+ * Loads this document's data from Firestore.
137
143
  *
138
144
  * @param force force a read from Firestore. Normally load() does nothing if
139
145
  * the document already contains data.
@@ -163,46 +169,58 @@ class FiretenderDoc {
163
169
  return this.data;
164
170
  }
165
171
  /**
166
- * Writable accessor to the contents of this document.
172
+ * Writable accessor to update the contents of this document.
167
173
  *
168
174
  * Only use this accessor when making changes to the doc. The .r accessor is
169
175
  * considerably more efficient when reading.
170
176
  */
171
177
  get w() {
172
- if (this.isNewDoc) {
173
- // No need to monitor changes if we're creating rather than updating.
178
+ if (this.isSettingNewContents) {
179
+ // No need to monitor changes if we're setting rather than updating.
174
180
  return this.data;
175
181
  }
176
182
  if (!this.dataProxy) {
177
183
  if (!this.data) {
184
+ // TODO #23: Consider being able to update a doc without loading it.
178
185
  throw Error("load() must be called before updating the document.");
179
186
  }
180
- this.dataProxy = (0, proxies_1.watchFieldForChanges)([], this.schema, this.data, this.onChange.bind(this));
187
+ this.dataProxy = (0, proxies_1.watchFieldForChanges)([], this.schema, this.data, this.addToUpdateList.bind(this));
181
188
  }
182
189
  return this.dataProxy;
183
190
  }
184
191
  /**
185
- * Write the document or any updates to Firestore.
192
+ * Writable accessor to overwrite all the document data.
193
+ */
194
+ set w(newData) {
195
+ this.data = this.schema.parse(newData);
196
+ this.isSettingNewContents = true;
197
+ this.dataProxy = undefined;
198
+ }
199
+ /**
200
+ * Writes the document or any updates to Firestore.
186
201
  */
187
202
  async write() {
188
- if (this.isNewDoc) {
203
+ // For new docs, this.data should contain its initial state.
204
+ if (this.isSettingNewContents) {
189
205
  (0, ts_helpers_1.assertIsDefined)(this.data);
190
206
  if (this.ref.type === "document") {
191
207
  await (0, firestore_1.setDoc)(this.ref, this.data);
192
208
  }
193
209
  else {
194
210
  this.ref = await (0, firestore_1.addDoc)(this.ref, this.data);
195
- this.docID = this.ref.path.split("/").pop();
211
+ this.docID = this.ref.path.split("/").pop(); // ID is last part of path.
196
212
  }
213
+ this.isSettingNewContents = false;
197
214
  this.isNewDoc = false;
198
215
  }
199
- // If existing doc:
216
+ // For existing docs, this.updates should contain a list of changes.
200
217
  else {
201
218
  if (!(this.ref.type === "document")) {
202
219
  // We should never get here.
203
220
  throw Error("Internal error. Firetender object should always reference a document when updating an existing doc.");
204
221
  }
205
222
  if (this.updates.size > 0) {
223
+ // updateDoc() takes alternating field path and field value parameters.
206
224
  const flatUpdateList = Array.from(this.updates.entries()).flat();
207
225
  await (0, firestore_1.updateDoc)(this.ref, flatUpdateList[0], flatUpdateList[1], ...flatUpdateList.slice(2));
208
226
  this.updates.clear();
@@ -211,7 +229,7 @@ class FiretenderDoc {
211
229
  return this;
212
230
  }
213
231
  /**
214
- * Update the document's data with a single call.
232
+ * Updates the document's data with a single call.
215
233
  *
216
234
  * This function loads the document's data, if necessary; calls the given
217
235
  * function to make changes to the data; then write the changes to Firestore.
@@ -228,14 +246,18 @@ class FiretenderDoc {
228
246
  }
229
247
  //////////////////////////////////////////////////////////////////////////////
230
248
  // Private functions
231
- /** Add the field and its new value to the list of updates. */
232
- onChange(fieldPath, newValue) {
249
+ /**
250
+ * Adds a field and its new value to the list of updates to be passed to
251
+ * Firestore's updateDoc(). Called when the proxies detect changes to the
252
+ * document data.
253
+ */
254
+ addToUpdateList(fieldPath, newValue) {
233
255
  let pathString = "";
234
256
  if (this.updates.size > 0) {
235
- // Check if some parent of this update is already in the list of mutations
236
- // to send to Firestore. Objects in the update list are references into
237
- // this.data, so the parent field will automatically reflect this change;
238
- // no additional Firestore mutation is needed.
257
+ // If there is already a list of mutations to send to Firestore, check if
258
+ // a parent of this update is in it. Objects in the update list are
259
+ // references into this.data, so the parent field will automatically
260
+ // reflect this change; no additional Firestore mutation is needed.
239
261
  if (fieldPath.some((field, i) => {
240
262
  pathString = pathString ? `${pathString}.${field}` : field;
241
263
  return i < fieldPath.length - 1 && this.updates.has(pathString);
@@ -1 +1 @@
1
- {"version":3,"file":"FiretenderDoc.js","sourceRoot":"","sources":["../src/FiretenderDoc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FiretenderDoc.js","sourceRoot":"","sources":["../src/FiretenderDoc.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- export { FiretenderCollection } from "./FiretenderCollection";
2
- export { FiretenderDoc } from "./FiretenderDoc";
1
+ import { FiretenderCollection } from "./FiretenderCollection";
2
+ import type { FiretenderDocOptions } from "./FiretenderDoc";
3
+ import { FiretenderDoc } from "./FiretenderDoc";
4
+ export { FiretenderCollection, FiretenderDoc, FiretenderDocOptions };
3
5
  export * from "./Timestamps";
package/dist/index.js CHANGED
@@ -15,9 +15,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.FiretenderDoc = exports.FiretenderCollection = void 0;
18
- var FiretenderCollection_1 = require("./FiretenderCollection");
18
+ const FiretenderCollection_1 = require("./FiretenderCollection");
19
19
  Object.defineProperty(exports, "FiretenderCollection", { enumerable: true, get: function () { return FiretenderCollection_1.FiretenderCollection; } });
20
- var FiretenderDoc_1 = require("./FiretenderDoc");
20
+ const FiretenderDoc_1 = require("./FiretenderDoc");
21
21
  Object.defineProperty(exports, "FiretenderDoc", { enumerable: true, get: function () { return FiretenderDoc_1.FiretenderDoc; } });
22
+ // TODO #6, #9, #10: stop using a direct export after the timestamp module gets
23
+ // cleaned up.
22
24
  __exportStar(require("./Timestamps"), exports);
23
25
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iEAA8D;AAIrD,qGAJA,2CAAoB,OAIA;AAF7B,mDAAgD;AAEjB,8FAFtB,6BAAa,OAEsB;AAE5C,+EAA+E;AAC/E,cAAc;AACd,+CAA6B"}
package/dist/proxies.d.ts CHANGED
@@ -1,3 +1,62 @@
1
1
  import { z } from "zod";
2
- export declare function watchArrayForChanges<ArrayElementType, FieldSchemaType extends z.ZodTypeAny>(arrayPath: string[], array: ArrayElementType[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, onChange: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
3
- export declare function watchFieldForChanges<FieldSchemaType extends z.ZodTypeAny>(fieldPath: string[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, onChange: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
2
+ /**
3
+ * Wraps a top-level array, its elements, or its elements' subfields in a proxy
4
+ * that watches for changes.
5
+ *
6
+ * Firestore supports limited modification of arrays; see the 2018 blog entry at
7
+ * https://firebase.blog/posts/2018/08/better-arrays-in-cloud-firestore for
8
+ * details and some history. The tl;dr is that we can't update array entries;
9
+ * we can only append or remove them.
10
+ *
11
+ * For this reason, this proxy only works with top-level arrays: the wrapped
12
+ * array cannot be inside a parent array, though it may be in a record or nested
13
+ * records. Child proxies maintain a link to the top-level array and trigger a
14
+ * rewrite of the whole thing if there are any changes to the contents. As a
15
+ * consequence, the watchFieldForChanges proxy (below) can produce child
16
+ * watchArrayForChanges proxies, but all children of watchArrayForChanges will
17
+ * always use the watchArrayForChanges proxy to maintain a reference to the
18
+ * top-level array.
19
+ *
20
+ * Appending an element to the top-level array could in theory be supported, but
21
+ * Firestore's arrayUnion operator only appends entries that don't already
22
+ * exist. That is not how Javascript arrays work, so to reduce logical overhead
23
+ * we don't bother with it.
24
+ *
25
+ * Deletion of entries in the top-level array are handled using Firestore's
26
+ * arrayRemove operator. The deleted element gets removed entirely, so the
27
+ * resulting array remains dense. Note that this behavior differs from how
28
+ * Javascript's delete operator normally works with arrays, but here we favor
29
+ * Firestore's array semantics.
30
+ *
31
+ * @param arrayPath the dot-delimited path of the top-level array.
32
+ * @param array a reference to the top-level array.
33
+ * @param fieldSchema schema of the array element or a field nested within it.
34
+ * @param field reference to the array element or one of its subfields.
35
+ * @param addToUpdateList callback to register modifications to this array.
36
+ */
37
+ export declare function watchArrayForChanges<ArrayElementType, FieldSchemaType extends z.ZodTypeAny>(arrayPath: string[], array: ArrayElementType[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, addToUpdateList: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
38
+ /**
39
+ * Wraps an object based on a Zod schema in a proxy that watches for changes.
40
+ *
41
+ * Nested fields are monitored by creating a chain of proxies. Consider this
42
+ * case:
43
+ *
44
+ * testDoc.w.record1.record2.someStringValue = "foo";
45
+ *
46
+ * There is a top-level proxy (call it proxy 0) for the ".w" accessor. Getting
47
+ * ".record1" from it returns a child proxy (1) wrapping that field. Getting
48
+ * ".record2" from that returns another child proxy (2) wrapping that subfield.
49
+ * Finally, setting ".someStringValue" uses the setter of proxy 2 to set the new
50
+ * value locally and register an update to be sent to Firestore.
51
+ *
52
+ * The proxy returned by watchFieldForChanges is used for fields and subfields
53
+ * when no parent is an array. If a field or subfield is an array, the proxy
54
+ * returned by watchArrayForChanges is used for it and all of its children,
55
+ * regardless of whether they are arrays.
56
+ *
57
+ * @param fieldPath the dot-delimited path of the object being wrapped.
58
+ * @param fieldSchema schema of the object's field.
59
+ * @param field reference to the field in the local document data.
60
+ * @param addToUpdateList callback to register modifications to this field.
61
+ */
62
+ export declare function watchFieldForChanges<FieldSchemaType extends z.ZodTypeAny>(fieldPath: string[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, addToUpdateList: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
package/dist/proxies.js CHANGED
@@ -5,8 +5,8 @@ const firestore_1 = require("firebase/firestore");
5
5
  const zod_1 = require("zod");
6
6
  const ts_helpers_1 = require("./ts-helpers");
7
7
  /**
8
- * Given a schema for a collection type, return the sub-schema of a specified
9
- * property.
8
+ * Given a Zod schema representing a collection, returns the sub-schema of the
9
+ * specified property.
10
10
  */
11
11
  function getPropertySchema(parentSchema, propertyKey) {
12
12
  let schema = parentSchema;
@@ -37,32 +37,76 @@ function getPropertySchema(parentSchema, propertyKey) {
37
37
  }
38
38
  }
39
39
  }
40
- function watchArrayForChanges(arrayPath, array, fieldSchema, field, onChange) {
40
+ /**
41
+ * Wraps a top-level array, its elements, or its elements' subfields in a proxy
42
+ * that watches for changes.
43
+ *
44
+ * Firestore supports limited modification of arrays; see the 2018 blog entry at
45
+ * https://firebase.blog/posts/2018/08/better-arrays-in-cloud-firestore for
46
+ * details and some history. The tl;dr is that we can't update array entries;
47
+ * we can only append or remove them.
48
+ *
49
+ * For this reason, this proxy only works with top-level arrays: the wrapped
50
+ * array cannot be inside a parent array, though it may be in a record or nested
51
+ * records. Child proxies maintain a link to the top-level array and trigger a
52
+ * rewrite of the whole thing if there are any changes to the contents. As a
53
+ * consequence, the watchFieldForChanges proxy (below) can produce child
54
+ * watchArrayForChanges proxies, but all children of watchArrayForChanges will
55
+ * always use the watchArrayForChanges proxy to maintain a reference to the
56
+ * top-level array.
57
+ *
58
+ * Appending an element to the top-level array could in theory be supported, but
59
+ * Firestore's arrayUnion operator only appends entries that don't already
60
+ * exist. That is not how Javascript arrays work, so to reduce logical overhead
61
+ * we don't bother with it.
62
+ *
63
+ * Deletion of entries in the top-level array are handled using Firestore's
64
+ * arrayRemove operator. The deleted element gets removed entirely, so the
65
+ * resulting array remains dense. Note that this behavior differs from how
66
+ * Javascript's delete operator normally works with arrays, but here we favor
67
+ * Firestore's array semantics.
68
+ *
69
+ * @param arrayPath the dot-delimited path of the top-level array.
70
+ * @param array a reference to the top-level array.
71
+ * @param fieldSchema schema of the array element or a field nested within it.
72
+ * @param field reference to the array element or one of its subfields.
73
+ * @param addToUpdateList callback to register modifications to this array.
74
+ */
75
+ function watchArrayForChanges(arrayPath, array, fieldSchema, field, addToUpdateList) {
41
76
  return new Proxy(field, {
42
77
  get(target, propertyKey) {
43
78
  const property = target[propertyKey];
44
79
  if (property instanceof Function) {
45
- const result = (...args) => property.apply(field, args);
80
+ // All methods of an array or its children are presumed to make
81
+ // modifications, thus triggering an update of the full array.
46
82
  // TODO: #11 Only mark the change for mutating function calls.
47
- onChange(arrayPath, array);
83
+ const result = (...args) => property.apply(field, args);
84
+ addToUpdateList(arrayPath, array);
48
85
  return result;
49
86
  }
50
87
  if (typeof propertyKey === "symbol") {
51
- return property; // Allow symbols to pass through.
88
+ // Allow symbols to pass through.
89
+ return property;
52
90
  }
53
91
  if (property instanceof Object) {
54
- return watchArrayForChanges(arrayPath, array, getPropertySchema(fieldSchema, propertyKey), property, onChange);
92
+ // Wrap nested objects, including nested arrays, in child proxies.
93
+ return watchArrayForChanges(arrayPath, array, getPropertySchema(fieldSchema, propertyKey), property, addToUpdateList);
55
94
  }
95
+ // Otherwise we must be getting a primitive. No need to wrap it.
56
96
  return property;
57
97
  },
58
98
  set(target, propertyKey, value) {
59
99
  if (typeof propertyKey === "symbol") {
100
+ // Allow symbols to pass through.
60
101
  return Reflect.set(target, propertyKey, value);
61
102
  }
103
+ // An array element or one of its subfields is being set to a new value.
104
+ // Parse the new value with the appropriate schema, set it in the local
105
+ // data, and mark the entire top-level array as needing to be written.
62
106
  const propertySchema = getPropertySchema(fieldSchema, propertyKey);
63
107
  const parsedValue = propertySchema.parse(value);
64
108
  const result = Reflect.set(target, propertyKey, parsedValue);
65
- onChange(arrayPath, array);
109
+ addToUpdateList(arrayPath, array);
66
110
  return result;
67
111
  },
68
112
  deleteProperty(target, propertyKey) {
@@ -74,47 +118,85 @@ function watchArrayForChanges(arrayPath, array, fieldSchema, field, onChange) {
74
118
  if (removedValues.length !== 1) {
75
119
  throw RangeError(`Failed to delete array item with index ${propertyKey}. Out of bounds?`);
76
120
  }
121
+ // Only top-level elements can be deleted with Firestore's arrayRemove.
77
122
  if (target === array) {
78
- onChange(arrayPath, (0, firestore_1.arrayRemove)(removedValues[0]));
123
+ addToUpdateList(arrayPath, (0, firestore_1.arrayRemove)(removedValues[0]));
79
124
  }
80
125
  else {
81
- onChange(arrayPath, array);
126
+ addToUpdateList(arrayPath, array);
82
127
  }
83
128
  return true;
84
129
  },
85
130
  });
86
131
  }
87
132
  exports.watchArrayForChanges = watchArrayForChanges;
88
- function watchFieldForChanges(fieldPath, fieldSchema, field, onChange) {
133
+ /**
134
+ * Wraps an object based on a Zod schema in a proxy that watches for changes.
135
+ *
136
+ * Nested fields are monitored by creating a chain of proxies. Consider this
137
+ * case:
138
+ *
139
+ * testDoc.w.record1.record2.someStringValue = "foo";
140
+ *
141
+ * There is a top-level proxy (call it proxy 0) for the ".w" accessor. Getting
142
+ * ".record1" from it returns a child proxy (1) wrapping that field. Getting
143
+ * ".record2" from that returns another child proxy (2) wrapping that subfield.
144
+ * Finally, setting ".someStringValue" uses the setter of proxy 2 to set the new
145
+ * value locally and register an update to be sent to Firestore.
146
+ *
147
+ * The proxy returned by watchFieldForChanges is used for fields and subfields
148
+ * when no parent is an array. If a field or subfield is an array, the proxy
149
+ * returned by watchArrayForChanges is used for it and all of its children,
150
+ * regardless of whether they are arrays.
151
+ *
152
+ * @param fieldPath the dot-delimited path of the object being wrapped.
153
+ * @param fieldSchema schema of the object's field.
154
+ * @param field reference to the field in the local document data.
155
+ * @param addToUpdateList callback to register modifications to this field.
156
+ */
157
+ function watchFieldForChanges(fieldPath, fieldSchema, field, addToUpdateList) {
89
158
  return new Proxy(field, {
90
159
  get(target, propertyKey) {
91
160
  const property = target[propertyKey];
92
161
  if (property instanceof Function) {
162
+ // Provide methods with a "this" reference for the underlying field.
93
163
  return (...args) => property.apply(field, args);
94
164
  }
95
165
  if (typeof propertyKey === "symbol") {
96
- return property; // Allow symbols to pass through.
166
+ // Allow symbols to pass through.
167
+ return property;
97
168
  }
98
169
  if (property instanceof Array) {
99
- return watchArrayForChanges([...fieldPath, propertyKey], property, getPropertySchema(fieldSchema, propertyKey), property, onChange);
170
+ // Wrap array subfields in the watchArrayForChanges proxy. It is
171
+ // necessarily a top-level array, because otherwise we would be in
172
+ // watchArrayForChanges already.
173
+ return watchArrayForChanges([...fieldPath, propertyKey], property, getPropertySchema(fieldSchema, propertyKey), property, addToUpdateList);
100
174
  }
101
175
  if (property instanceof Object) {
102
- return watchFieldForChanges([...fieldPath, propertyKey], getPropertySchema(fieldSchema, propertyKey), property, onChange);
176
+ // Wrap nested objects in another instance of this proxy.
177
+ return watchFieldForChanges([...fieldPath, propertyKey], getPropertySchema(fieldSchema, propertyKey), property, addToUpdateList);
103
178
  }
179
+ // Otherwise we must be getting a primitive. No need to wrap it.
104
180
  return property;
105
181
  },
106
182
  set(target, propertyKey, value) {
107
183
  if (typeof propertyKey === "symbol") {
184
+ // Allow symbols to pass through.
108
185
  return Reflect.set(target, propertyKey, value);
109
186
  }
187
+ // A property of this object is being set to a new value. Parse the new
188
+ // value with the appropriate schema, set it in the local data, and mark
189
+ // the entire top-level array as needing to be written.
110
190
  const propertySchema = getPropertySchema(fieldSchema, propertyKey);
111
191
  const parsedValue = propertySchema.parse(value);
112
- onChange([...fieldPath, propertyKey], parsedValue);
192
+ addToUpdateList([...fieldPath, propertyKey], parsedValue);
113
193
  return Reflect.set(target, propertyKey, parsedValue);
114
194
  },
115
195
  deleteProperty(target, propertyKey) {
116
196
  (0, ts_helpers_1.assertKeyIsString)(propertyKey);
117
- onChange([...fieldPath, propertyKey], (0, firestore_1.deleteField)());
197
+ // Delete the field in Firestore by marking it with the deleteField
198
+ // operator.
199
+ addToUpdateList([...fieldPath, propertyKey], (0, firestore_1.deleteField)());
118
200
  return Reflect.deleteProperty(target, propertyKey);
119
201
  },
120
202
  });
@@ -1 +1 @@
1
- {"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":";;;AAAA,kDAA8D;AAC9D,6BAAwB;AAExB,6CAAiD;AAEjD;;;GAGG;AACH,SAAS,iBAAiB,CACxB,YAA0B,EAC1B,WAAmB;IAEnB,IAAI,MAAM,GAAQ,YAAY,CAAC;IAC/B,iDAAiD;IACjD,OAAO,IAAI,EAAE;QACX,QAAQ,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC5B,uEAAuE;YACvE,sEAAsE;YACtE,KAAK,OAAC,CAAC,qBAAqB,CAAC,WAAW,CAAC;YACzC,KAAK,OAAC,CAAC,qBAAqB,CAAC,WAAW;gBACtC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBACzB,SAAS;YACX,KAAK,OAAC,CAAC,qBAAqB,CAAC,UAAU;gBACrC,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;gBAChC,SAAS;YACX,KAAK,OAAC,CAAC,qBAAqB,CAAC,UAAU;gBACrC,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC5B,SAAS;YACX,wDAAwD;YACxD,KAAK,OAAC,CAAC,qBAAqB,CAAC,SAAS;gBACpC,OAAO,MAAM,CAAC,WAAW,CAAC;YAC5B,KAAK,OAAC,CAAC,qBAAqB,CAAC,QAAQ;gBACnC,OAAO,MAAM,CAAC,OAAO,CAAC;YACxB,KAAK,OAAC,CAAC,qBAAqB,CAAC,SAAS;gBACpC,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACnC;gBACE,MAAM,SAAS,CACb,yCAAyC,WAAW,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CACjF,CAAC;SACL;KACF;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,SAAgB,oBAAoB,CAIlC,SAAmB,EACnB,KAAyB,EACzB,WAA4B,EAC5B,KAA+B,EAC/B,eAAwD;IAExD,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE;QACtB,GAAG,CAAC,MAAM,EAAE,WAAW;YACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,QAAQ,YAAY,QAAQ,EAAE;gBAChC,+DAA+D;gBAC/D,8DAA8D;gBAC9D,8DAA8D;gBAC9D,MAAM,MAAM,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC/D,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBAClC,OAAO,MAAM,CAAC;aACf;YACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACnC,iCAAiC;gBACjC,OAAO,QAAQ,CAAC;aACjB;YACD,IAAI,QAAQ,YAAY,MAAM,EAAE;gBAC9B,kEAAkE;gBAClE,OAAO,oBAAoB,CACzB,SAAS,EACT,KAAK,EACL,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,eAAe,CAChB,CAAC;aACH;YACD,iEAAiE;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK;YAC5B,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACnC,iCAAiC;gBACjC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;aAChD;YACD,wEAAwE;YACxE,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;YAC7D,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,cAAc,CAAC,MAAM,EAAE,WAAW;YAChC,IAAA,8BAAiB,EAAC,WAAW,CAAC,CAAC;YAC/B,wEAAwE;YACxE,0EAA0E;YAC1E,kEAAkE;YAClE,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,MAAM,UAAU,CACd,0CAA0C,WAAW,mBAAmB,CACzE,CAAC;aACH;YACD,uEAAuE;YACvE,IAAI,MAAM,KAAK,KAAK,EAAE;gBACpB,eAAe,CAAC,SAAS,EAAE,IAAA,uBAAW,EAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3D;iBAAM;gBACL,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;aACnC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAxED,oDAwEC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,oBAAoB,CAClC,SAAmB,EACnB,WAA4B,EAC5B,KAA+B,EAC/B,eAAwD;IAExD,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE;QACtB,GAAG,CAAC,MAAM,EAAE,WAAW;YACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,QAAQ,YAAY,QAAQ,EAAE;gBAChC,oEAAoE;gBACpE,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;aACxD;YACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACnC,iCAAiC;gBACjC,OAAO,QAAQ,CAAC;aACjB;YACD,IAAI,QAAQ,YAAY,KAAK,EAAE;gBAC7B,iEAAiE;gBACjE,kEAAkE;gBAClE,gCAAgC;gBAChC,OAAO,oBAAoB,CACzB,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAC3B,QAAQ,EACR,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,eAAe,CAChB,CAAC;aACH;YACD,IAAI,QAAQ,YAAY,MAAM,EAAE;gBAC9B,yDAAyD;gBACzD,OAAO,oBAAoB,CACzB,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAC3B,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,eAAe,CAChB,CAAC;aACH;YACD,iEAAiE;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK;YAC5B,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACnC,iCAAiC;gBACjC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;aAChD;YACD,wEAAwE;YACxE,wEAAwE;YACxE,uDAAuD;YACvD,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,eAAe,CAAC,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;YAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QACvD,CAAC;QACD,cAAc,CAAC,MAAM,EAAE,WAAW;YAChC,IAAA,8BAAiB,EAAC,WAAW,CAAC,CAAC;YAC/B,mEAAmE;YACnE,YAAY;YACZ,eAAe,CAAC,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,IAAA,uBAAW,GAAE,CAAC,CAAC;YAC5D,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AA9DD,oDA8DC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "firetender",
3
3
  "displayName": "Firetender",
4
4
  "description": "Typescript wrapper for Firestore documents",
5
- "version": "0.6.0",
5
+ "version": "0.7.0",
6
6
  "author": "Jake Hartman",
7
7
  "license": "MIT",
8
8
  "homepage": "https://github.com/jakes-space/firetender",