@rebasepro/client-firebase 0.8.0 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { DataDriver, DeleteEntityProps, Entity, EntityCollection, EntityReference, FetchCollectionProps, FetchEntityProps, FilterCombination, FilterValues, GeoPoint, ListenCollectionProps, ListenEntityProps, SaveEntityProps, WhereFilterOp } from "@rebasepro/types";
1
+ import { DataDriver, DeleteProps, CollectionConfig, EntityReference, FetchCollectionProps, FetchOneProps, FilterCombination, FilterValues, GeoPoint, ListenCollectionProps, ListenOneProps, SaveProps, WhereFilterOp } from "@rebasepro/types";
2
2
  import { User } from "@firebase/auth";
3
3
  import {
4
4
  collection as collectionClause,
@@ -62,7 +62,7 @@ export interface FirestoreDataDriverProps {
62
62
 
63
63
  export type FirestoreIndexesBuilder = (params: {
64
64
  path: string,
65
- collection: EntityCollection<any>,
65
+ collection: CollectionConfig<any>,
66
66
  }) => FilterCombination<string>[] | undefined
67
67
 
68
68
  export type FirestoreDataDriver = DataDriver & {
@@ -70,7 +70,7 @@ export type FirestoreDataDriver = DataDriver & {
70
70
  initTextSearch: (props: {
71
71
  path: string,
72
72
  databaseId?: string,
73
- collection?: EntityCollection
73
+ collection?: CollectionConfig
74
74
  }) => Promise<boolean>,
75
75
  }
76
76
 
@@ -120,6 +120,26 @@ export function useFirestoreDriver({
120
120
  .filter(([_, entry]) => !!entry)
121
121
  .forEach(([key, filterParameter]) => {
122
122
  const [op, value] = filterParameter as [WhereFilterOp, any];
123
+
124
+ // Null-testing operators map to Firestore's == / != against null.
125
+ if (op === "is-null") {
126
+ queryParams.push(whereClause(key, "==", null));
127
+ return;
128
+ }
129
+ if (op === "is-not-null") {
130
+ queryParams.push(whereClause(key, "!=", null));
131
+ return;
132
+ }
133
+
134
+ // Firestore has no LIKE/ILIKE — fail loudly rather than silently
135
+ // returning wrong results. Use `searchString` / a search index instead.
136
+ if (op === "like" || op === "ilike" || op === "not-like" || op === "not-ilike") {
137
+ throw new Error(
138
+ `Firestore does not support the "${op}" operator (SQL pattern matching). ` +
139
+ "Use a full-text search index or the collection's searchString instead."
140
+ );
141
+ }
142
+
123
143
  queryParams.push(whereClause(key, op, cmsToFirestoreModel(value, firestore)));
124
144
  });
125
145
  }
@@ -139,31 +159,31 @@ export function useFirestoreDriver({
139
159
  return query(collectionReference, ...queryParams);
140
160
  }, [firebaseApp]);
141
161
 
142
- const getAndBuildEntity = useCallback(<M extends Record<string, any>>(path: string,
143
- entityId: string | number,
162
+ const getAndBuildEntity = useCallback((path: string,
163
+ id: string | number,
144
164
  databaseId?: string
145
- ): Promise<Entity<M> | undefined> => {
165
+ ): Promise<Record<string, unknown> | undefined> => {
146
166
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
147
167
 
148
168
  const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
149
169
 
150
- return getDoc(doc(firestore, path, String(entityId)))
151
- .then((docSnapshot) => {
152
- if (!docSnapshot.exists()) {
170
+ return getDoc(doc(firestore, path, String(id)))
171
+ .then((docEntity) => {
172
+ if (!docEntity.exists()) {
153
173
  return undefined;
154
174
  }
155
- return createEntityFromDocument(docSnapshot, databaseId);
175
+ return createRowFromDocument(docEntity);
156
176
  });
157
177
  }, [firebaseApp]);
158
178
 
159
- const listenEntity = useCallback(<M extends Record<string, any>>(
179
+ const listenOne = useCallback(<M extends Record<string, any>>(
160
180
  {
161
181
  path,
162
- entityId,
182
+ id,
163
183
  collection,
164
184
  onUpdate,
165
185
  onError
166
- }: ListenEntityProps<M>): () => void => {
186
+ }: ListenOneProps<M>): () => void => {
167
187
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
168
188
 
169
189
  const databaseId = collection?.databaseId;
@@ -171,10 +191,10 @@ export function useFirestoreDriver({
171
191
  const resolvedPath = path;
172
192
 
173
193
  return onSnapshot(
174
- doc(firestore, resolvedPath, String(entityId)),
194
+ doc(firestore, resolvedPath, String(id)),
175
195
  {
176
- next: (docSnapshot) => {
177
- onUpdate(createEntityFromDocument(docSnapshot, databaseId));
196
+ next: (docEntity) => {
197
+ onUpdate(docEntity.exists() ? createRowFromDocument(docEntity) : null);
178
198
  },
179
199
  error: onError
180
200
  }
@@ -190,7 +210,7 @@ export function useFirestoreDriver({
190
210
  path: string,
191
211
  databaseId?: string,
192
212
  searchString: string;
193
- onUpdate: (entities: Entity<M>[]) => void,
213
+ onUpdate: (rows: Record<string, unknown>[]) => void,
194
214
  }): () => void => {
195
215
 
196
216
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
@@ -222,23 +242,24 @@ export function useFirestoreDriver({
222
242
  onUpdate([]);
223
243
  }
224
244
 
225
- const entities: Entity<M>[] = [];
245
+ const rows: Record<string, unknown>[] = [];
226
246
  const addedEntitiesSet = new Set<string | number>();
227
247
  subscriptions = (ids ?? [])
228
- .map((entityId) => {
229
- return listenEntity({
248
+ .map((id) => {
249
+ return listenOne({
230
250
  path,
231
- entityId,
232
- onUpdate: (entity: Entity<any> | null) => {
233
- if (entity?.values) {
234
- if (entity.id && !addedEntitiesSet.has(entity.id)) {
235
- addedEntitiesSet.add(entity.id);
236
- entities.push(entity);
237
- onUpdate(entities);
251
+ id,
252
+ onUpdate: (row: Record<string, unknown> | null) => {
253
+ const incomingId = row?.id as string | number | undefined;
254
+ if (row && incomingId !== undefined) {
255
+ if (!addedEntitiesSet.has(incomingId)) {
256
+ addedEntitiesSet.add(incomingId);
257
+ rows.push(row);
258
+ onUpdate(rows);
238
259
  }
239
- } else if (entity?.id) {
240
- addedEntitiesSet.delete(entity.id);
241
- onUpdate([...entities.filter(e => e.id !== entityId)])
260
+ } else {
261
+ addedEntitiesSet.delete(id);
262
+ onUpdate([...rows.filter(r => r.id !== id)])
242
263
  }
243
264
  }
244
265
  })
@@ -250,12 +271,12 @@ export function useFirestoreDriver({
250
271
  subscriptions.forEach((p) => p());
251
272
  }
252
273
 
253
- }, [firebaseApp, listenEntity]);
274
+ }, [firebaseApp, listenOne]);
254
275
 
255
276
  const initTextSearch = useCallback(async (props: {
256
277
  path: string,
257
278
  databaseId?: string,
258
- collection?: EntityCollection
279
+ collection?: CollectionConfig
259
280
  }) => {
260
281
  console.debug("Init text search controller", searchControllerRef.current, props.path);
261
282
  if (!searchControllerRef.current) {
@@ -281,7 +302,7 @@ export function useFirestoreDriver({
281
302
  * @param orderBy
282
303
  * @param order
283
304
  * @return Function to cancel subscription
284
- * @see useCollectionFetch if you need this functionality implemented as a hook
305
+ * @see useCollection if you need this functionality implemented as a hook
285
306
  * @group Firestore
286
307
  */
287
308
  const fetchCollection = useCallback(async <M extends Record<string, any>>({
@@ -294,7 +315,7 @@ export function useFirestoreDriver({
294
315
  order,
295
316
  collection
296
317
  }: FetchCollectionProps<M>
297
- ): Promise<Entity<M>[]> => {
318
+ ): Promise<Record<string, unknown>[]> => {
298
319
 
299
320
  const databaseId = collection?.databaseId;
300
321
 
@@ -310,8 +331,8 @@ export function useFirestoreDriver({
310
331
  });
311
332
  const query = buildQuery(resolvedPath, filter, orderBy, order, startAfter as unknown[] | undefined, limit, databaseId);
312
333
 
313
- const snapshot = await getDocs(query);
314
- return snapshot.docs.map((doc) => createEntityFromDocument(doc, databaseId));
334
+ const entity = await getDocs(query);
335
+ return entity.docs.map((doc) => createRowFromDocument(doc));
315
336
  }, [buildQuery]);
316
337
 
317
338
  /**
@@ -327,7 +348,7 @@ export function useFirestoreDriver({
327
348
  * @param order
328
349
  * @param onUpdate
329
350
  * @return Function to cancel subscription
330
- * @see useCollectionFetch if you need this functionality implemented as a hook
351
+ * @see useCollection if you need this functionality implemented as a hook
331
352
  * @group Firestore
332
353
  */
333
354
  const listenCollection = useCallback(<M extends Record<string, any>>(
@@ -379,9 +400,9 @@ export function useFirestoreDriver({
379
400
  const query = buildQuery(resolvedPath, filter, orderBy, order, startAfter as unknown[] | undefined, limit, databaseId);
380
401
  return onSnapshot(query,
381
402
  {
382
- next: (snapshot) => {
403
+ next: (entity) => {
383
404
  if (!searchString)
384
- onUpdate(snapshot.docs.map((doc) => createEntityFromDocument(doc, databaseId)));
405
+ onUpdate(entity.docs.map((doc) => createRowFromDocument(doc)));
385
406
  },
386
407
  error: onError
387
408
  }
@@ -390,47 +411,47 @@ export function useFirestoreDriver({
390
411
  }, [buildQuery, firebaseApp, performTextSearch]);
391
412
 
392
413
  /**
393
- * Retrieve an entity given a path and a collection
414
+ * Retrieve a entity given a path and a collection
394
415
  * @param path
395
- * @param entityId
416
+ * @param id
396
417
  * @param collection
397
418
  * @group Firestore
398
419
  */
399
- const fetchEntity = useCallback(<M extends Record<string, any>>({
420
+ const fetchOne = useCallback(<M extends Record<string, any>>({
400
421
  path,
401
- entityId,
422
+ id,
402
423
  collection
403
- }: FetchEntityProps<M>
404
- ): Promise<Entity<M> | undefined> => {
424
+ }: FetchOneProps<M>
425
+ ): Promise<Record<string, unknown> | undefined> => {
405
426
  const resolvedPath = path;
406
- return getAndBuildEntity(resolvedPath, entityId, collection?.databaseId);
427
+ return getAndBuildEntity(resolvedPath, id, collection?.databaseId);
407
428
  }, [getAndBuildEntity]);
408
429
 
409
430
  /**
410
431
  * Save entity to the specified path. Note that Firestore does not allow
411
432
  * undefined values.
412
433
  * @param path
413
- * @param entityId
434
+ * @param id
414
435
  * @param values
415
436
  * @param schemaId
416
437
  * @param collection
417
438
  * @param status
418
439
  * @group Firestore
419
440
  */
420
- const saveEntity = useCallback(<M extends Record<string, any>>(
441
+ const save = useCallback(<M extends Record<string, any>>(
421
442
  {
422
443
  path,
423
- entityId,
444
+ id,
424
445
  values: valuesProp,
425
446
  collection,
426
447
  status
427
- }: SaveEntityProps<M>): Promise<Entity<M>> => {
448
+ }: SaveProps<M>): Promise<Record<string, unknown>> => {
428
449
 
429
450
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
430
451
 
431
452
  console.debug("1", {
432
453
  path,
433
- entityId,
454
+ id,
434
455
  values: valuesProp,
435
456
  collection
436
457
  })
@@ -438,7 +459,7 @@ export function useFirestoreDriver({
438
459
 
439
460
  console.debug("2", {
440
461
  path,
441
- entityId,
462
+ id,
442
463
  values: valuesProp,
443
464
  collection
444
465
  })
@@ -449,24 +470,23 @@ export function useFirestoreDriver({
449
470
  const collectionReference: CollectionReference = collectionClause(firestore, path);
450
471
  console.debug("Saving entity", {
451
472
  path,
452
- entityId,
473
+ id,
453
474
  values,
454
475
  databaseId
455
476
  });
456
477
 
457
478
  let documentReference: DocumentReference;
458
- if (entityId) {
459
- documentReference = doc(collectionReference, String(entityId));
479
+ if (id) {
480
+ documentReference = doc(collectionReference, String(id));
460
481
  } else {
461
482
  documentReference = doc(collectionReference);
462
483
  }
463
484
  return setDoc(documentReference, values as Record<string, unknown>, { merge: true })
464
485
  .then(() => {
465
486
  return {
466
- id: documentReference.id,
467
- path,
468
- values: firestoreToCMSModel(values)
469
- } as Entity<M>;
487
+ ...(firestoreToCMSModel(values) as Record<string, unknown>),
488
+ id: documentReference.id
489
+ };
470
490
  })
471
491
  .catch((error) => {
472
492
  console.error("Error saving entity", error);
@@ -476,22 +496,23 @@ export function useFirestoreDriver({
476
496
  }, [firebaseApp]);
477
497
 
478
498
  /**
479
- * Delete an entity
499
+ * Delete a entity
480
500
  * @param entity
481
501
  * @param collection
482
502
  * @group Firestore
483
503
  */
484
- const deleteEntity = useCallback(<M extends Record<string, any>>(
504
+ const deleteOne = useCallback(<M extends Record<string, any>>(
485
505
  {
486
- entity
487
- }: DeleteEntityProps<M>
506
+ row,
507
+ collection
508
+ }: DeleteProps<M>
488
509
  ): Promise<void> => {
489
510
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
490
511
 
491
- const databaseId = entity.databaseId;
512
+ const databaseId = collection?.databaseId;
492
513
  const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
493
514
 
494
- return deleteDoc(doc(firestore, entity.path, String(entity.id)));
515
+ return deleteDoc(doc(firestore, row.path, String(row.id)));
495
516
  }, [firebaseApp]);
496
517
 
497
518
  /**
@@ -500,7 +521,7 @@ export function useFirestoreDriver({
500
521
  * @param name of the property
501
522
  * @param value
502
523
  * @param property
503
- * @param entityId
524
+ * @param id
504
525
  * @return `true` if there are no other fields besides the given entity
505
526
  * @group Firestore
506
527
  */
@@ -508,8 +529,8 @@ export function useFirestoreDriver({
508
529
  path: string,
509
530
  name: string,
510
531
  value: unknown,
511
- entityId?: string | number,
512
- collection?: EntityCollection<any>
532
+ id?: string | number,
533
+ collection?: CollectionConfig<any>
513
534
  ): Promise<boolean> => {
514
535
 
515
536
  if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
@@ -521,12 +542,12 @@ export function useFirestoreDriver({
521
542
  return Promise.resolve(true);
522
543
  }
523
544
  const q = query(collectionClause(firestore, path), whereClause(name, "==", cmsToFirestoreModel(value, firestore)));
524
- const snapshot = await getDocs(q);
525
- return snapshot.docs.filter(doc => doc.id !== entityId).length === 0;
545
+ const entity = await getDocs(q);
546
+ return entity.docs.filter(doc => doc.id !== id).length === 0;
526
547
 
527
548
  }, [firebaseApp]);
528
549
 
529
- const countEntities = useCallback(async ({
550
+ const count = useCallback(async ({
530
551
  path,
531
552
  filter,
532
553
  order,
@@ -537,8 +558,8 @@ export function useFirestoreDriver({
537
558
  const databaseId = collection?.databaseId;
538
559
  const resolvedPath = path;
539
560
  const query = buildQuery(resolvedPath, filter, orderBy, order, undefined, undefined, databaseId);
540
- const snapshot = await getCountFromServer(query);
541
- return snapshot.data().count;
561
+ const entity = await getCountFromServer(query);
562
+ return entity.data().count;
542
563
  }, [firebaseApp]);
543
564
 
544
565
  const isFilterCombinationValid = useCallback(({
@@ -548,7 +569,7 @@ export function useFirestoreDriver({
548
569
  sortBy
549
570
  }: {
550
571
  path: string,
551
- collection: EntityCollection<any>,
572
+ collection: CollectionConfig<any>,
552
573
  filterValues: FilterValues<any>,
553
574
  sortBy?: [string, "asc" | "desc"],
554
575
  }): boolean => {
@@ -600,40 +621,37 @@ export function useFirestoreDriver({
600
621
  initTextSearch,
601
622
  fetchCollection,
602
623
  listenCollection,
603
- fetchEntity,
604
- listenEntity,
605
- saveEntity,
606
- deleteEntity,
624
+ fetchOne,
625
+ listenOne,
626
+ save,
627
+ delete: deleteOne,
607
628
  checkUniqueField,
608
- countEntities,
629
+ count,
609
630
  isFilterCombinationValid
610
631
  }), [
611
632
  firebaseApp,
612
633
  initTextSearch,
613
634
  fetchCollection,
614
635
  listenCollection,
615
- fetchEntity,
616
- listenEntity,
617
- saveEntity,
618
- deleteEntity,
636
+ fetchOne,
637
+ listenOne,
638
+ save,
639
+ deleteOne,
619
640
  checkUniqueField,
620
- countEntities,
641
+ count,
621
642
  isFilterCombinationValid
622
643
  ]);
623
644
 
624
645
  }
625
646
 
626
- const createEntityFromDocument = <M extends Record<string, any>>(
627
- docSnap: DocumentSnapshot,
628
- databaseId?: string
629
- ): Entity<M> => {
630
- const values = firestoreToCMSModel(docSnap.data()) as M;
631
- const path = getCMSPathFromFirestorePath(docSnap.ref.path);
647
+ const createRowFromDocument = (
648
+ docSnap: DocumentSnapshot
649
+ ): Record<string, unknown> => {
650
+ const values = firestoreToCMSModel(docSnap.data()) as Record<string, unknown>;
632
651
  return {
633
- id: docSnap.id,
634
- path: path,
635
- values,
636
- databaseId
652
+ ...values,
653
+ // Spread the canonical document id last so it wins over a literal `id` field
654
+ id: docSnap.id
637
655
  };
638
656
  };
639
657
 
@@ -770,7 +788,7 @@ function buildTextSearchControllerWithLocalSearch({
770
788
  init: async (props: {
771
789
  path: string,
772
790
  databaseId?: string,
773
- collection?: EntityCollection
791
+ collection?: CollectionConfig
774
792
  }) => {
775
793
  const b = await textSearchController.init(props);
776
794
  if (b) {
@@ -1,6 +1,6 @@
1
1
  import { User as FirebaseUser } from "@firebase/auth";
2
2
  import { FirebaseApp } from "@firebase/app";
3
- import { EntityCollection } from "@rebasepro/types";
3
+ import { CollectionConfig } from "@rebasepro/types";
4
4
 
5
5
  export type FirestoreTextSearchControllerBuilder = (props: {
6
6
  firebaseApp: FirebaseApp;
@@ -25,7 +25,7 @@ export type FirestoreTextSearchController = {
25
25
  init: (props: {
26
26
  path: string,
27
27
  databaseId?: string,
28
- collection?: EntityCollection
28
+ collection?: CollectionConfig
29
29
  }) => Promise<boolean>,
30
30
  /**
31
31
  * Do the search and return a list of ids.
@@ -36,7 +36,7 @@ export type FirestoreTextSearchController = {
36
36
  path: string,
37
37
  currentUser?: FirebaseUser,
38
38
  databaseId?: string,
39
- collection?: EntityCollection
39
+ collection?: CollectionConfig
40
40
  }) => (Promise<readonly string[] | undefined>),
41
41
 
42
42
  };
@@ -1,5 +1,5 @@
1
1
  import { deleteField, DocumentSnapshot } from "@firebase/firestore";
2
- import { EntityCollection, FirebaseCollection, Properties, Property } from "@rebasepro/types";
2
+ import { CollectionConfig, FirebaseCollectionConfig, Properties, Property } from "@rebasepro/types";
3
3
  import { COLLECTION_PATH_SEPARATOR, sortProperties, stripCollectionPath } from "@rebasepro/common";
4
4
 
5
5
  export function buildCollectionId(idOrPath: string, parentCollectionSlugs?: string[], parentEntityIds?: string[]): string {
@@ -9,7 +9,7 @@ export function buildCollectionId(idOrPath: string, parentCollectionSlugs?: stri
9
9
  }
10
10
 
11
11
 
12
- export const docsToCollectionTree = (docs: DocumentSnapshot[]): EntityCollection[] => {
12
+ export const docsToCollectionTree = (docs: DocumentSnapshot[]): CollectionConfig[] => {
13
13
 
14
14
  const collectionsMap = docs.map((doc) => {
15
15
  const id: string = doc.id;
@@ -26,7 +26,7 @@ export const docsToCollectionTree = (docs: DocumentSnapshot[]): EntityCollection
26
26
  const parentId = id.split(COLLECTION_PATH_SEPARATOR).slice(0, -1).join(COLLECTION_PATH_SEPARATOR);
27
27
  const parentCollection = collectionsMap[parentId];
28
28
  if (parentCollection)
29
- (parentCollection as FirebaseCollection).subcollections = () => [...((parentCollection as FirebaseCollection).subcollections?.() ?? []), collection];
29
+ (parentCollection as FirebaseCollectionConfig).subcollections = () => [...((parentCollection as FirebaseCollectionConfig).subcollections?.() ?? []), collection];
30
30
  delete collectionsMap[id];
31
31
  }
32
32
  });
@@ -34,7 +34,7 @@ export const docsToCollectionTree = (docs: DocumentSnapshot[]): EntityCollection
34
34
  return Object.values(collectionsMap);
35
35
  }
36
36
 
37
- export const docToCollection = (doc: DocumentSnapshot): EntityCollection => {
37
+ export const docToCollection = (doc: DocumentSnapshot): CollectionConfig => {
38
38
  const data = doc.data();
39
39
  if (!data)
40
40
  throw Error("Entity collection has not been persisted correctly");
@@ -48,7 +48,7 @@ export const docToCollection = (doc: DocumentSnapshot): EntityCollection => {
48
48
  ...data,
49
49
  properties: sortedProperties,
50
50
  slug: data.id ?? data.alias ?? data.slug
51
- } as EntityCollection;
51
+ } as CollectionConfig;
52
52
  }
53
53
 
54
54
 
@@ -12,8 +12,8 @@ export async function getFirestoreDataInPath(firebaseApp: FirebaseApp, path: str
12
12
  const firestore = getFirestore(firebaseApp);
13
13
  if (!parentPaths || parentPaths.length === 0) {
14
14
  const q = query(collection(firestore, path), limitClause(limit));
15
- return getDocs(q).then((querySnapshot) => {
16
- return querySnapshot.docs.map(doc => doc.data());
15
+ return getDocs(q).then((queryEntity) => {
16
+ return queryEntity.docs.map(doc => doc.data());
17
17
  });
18
18
  } else {
19
19
  let currentDocs: QueryDocumentSnapshot[] | undefined = undefined;
@@ -2,7 +2,7 @@ import { collection, getFirestore, onSnapshot, query } from "@firebase/firestore
2
2
  import Fuse from "fuse.js"
3
3
 
4
4
  import { FirebaseApp } from "@firebase/app";
5
- import { EntityCollection } from "@rebasepro/types";
5
+ import { CollectionConfig } from "@rebasepro/types";
6
6
  import { FirestoreTextSearchController, FirestoreTextSearchControllerBuilder } from "../types";
7
7
 
8
8
  const MAX_SEARCH_RESULTS = 80;
@@ -32,7 +32,7 @@ export const localSearchControllerBuilder: FirestoreTextSearchControllerBuilder
32
32
  databaseId
33
33
  }: {
34
34
  path: string,
35
- collection?: EntityCollection,
35
+ collection?: CollectionConfig,
36
36
  databaseId?: string
37
37
  }): Promise<boolean> => {
38
38
 
@@ -49,11 +49,11 @@ export const localSearchControllerBuilder: FirestoreTextSearchControllerBuilder
49
49
  const col = collection(firestore, path);
50
50
  listeners[path] = onSnapshot(query(col),
51
51
  {
52
- next: (snapshot) => {
53
- if (snapshot.metadata.fromCache && snapshot.metadata.hasPendingWrites) {
52
+ next: (entity) => {
53
+ if (entity.metadata.fromCache && entity.metadata.hasPendingWrites) {
54
54
  return;
55
55
  }
56
- const docs = snapshot.docs.map(doc => ({
56
+ const docs = entity.docs.map(doc => ({
57
57
  id: doc.id,
58
58
  ...doc.data()
59
59
  }));
@@ -112,7 +112,7 @@ export const localSearchControllerBuilder: FirestoreTextSearchControllerBuilder
112
112
  }
113
113
  }
114
114
 
115
- function buildIndex(list: (object & { id: string })[], collection: EntityCollection) {
115
+ function buildIndex(list: (object & { id: string })[], collection: CollectionConfig) {
116
116
 
117
117
  const keys = ["id", ...Object.keys(collection.properties)];
118
118
 
@@ -1,6 +1,6 @@
1
1
  import { User as FirebaseUser } from "@firebase/auth";
2
2
  import { FirestoreTextSearchController, FirestoreTextSearchControllerBuilder } from "../types";
3
- import { EntityCollection } from "@rebasepro/types";
3
+ import { CollectionConfig } from "@rebasepro/types";
4
4
 
5
5
  const DEFAULT_SERVER = "https://api.rebase.pro";
6
6
 
@@ -60,7 +60,7 @@ export function buildPineconeSearchController({
60
60
 
61
61
  const init = (props: {
62
62
  path: string,
63
- collection?: EntityCollection
63
+ collection?: CollectionConfig
64
64
  }) => {
65
65
  // do nothing
66
66
  return Promise.resolve(isPathSupported(props.path));
@@ -1,7 +1,7 @@
1
1
  import { FirestoreTextSearchController, FirestoreTextSearchControllerBuilder } from "../types";
2
2
  import { FirebaseApp } from "@firebase/app";
3
3
  import { getFunctions, httpsCallable } from "@firebase/functions";
4
- import { EntityCollection } from "@rebasepro/types";
4
+ import { CollectionConfig } from "@rebasepro/types";
5
5
 
6
6
  /**
7
7
  * Configuration returned by the Rebase Search Extension
@@ -204,7 +204,7 @@ export function buildRebaseSearchController(
204
204
  */
205
205
  const init = async (props: {
206
206
  path: string;
207
- collection?: EntityCollection;
207
+ collection?: CollectionConfig;
208
208
  databaseId?: string;
209
209
  }): Promise<boolean> => {
210
210
  try {
@@ -289,7 +289,7 @@ export function buildRebaseSearchController(
289
289
  searchString: string;
290
290
  path: string;
291
291
  databaseId?: string;
292
- collection?: EntityCollection;
292
+ collection?: CollectionConfig;
293
293
  }): Promise<readonly string[] | undefined> => {
294
294
  if (!typesenseClient) {
295
295
  // Ensure client is initialized
@@ -1,5 +1,5 @@
1
1
  import { FirestoreTextSearchController, FirestoreTextSearchControllerBuilder } from "../types";
2
- import { EntityCollection } from "@rebasepro/types";
2
+ import { CollectionConfig } from "@rebasepro/types";
3
3
 
4
4
  /**
5
5
  * Utility function to perform a text search in an external index,
@@ -20,7 +20,7 @@ export function buildExternalSearchController({
20
20
 
21
21
  const init = (props: {
22
22
  path: string,
23
- collection?: EntityCollection
23
+ collection?: CollectionConfig
24
24
  }) => {
25
25
  return Promise.resolve(isPathSupported(props.path));
26
26
  }