Guest User

Untitled

a guest
Oct 18th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.85 KB | None | 0 0
  1. import * as fb from "firebase";
  2. import { computed, observable, runInAction } from "mobx";
  3.  
  4. type Query = fb.firestore.Query;
  5. type DocumentReference = fb.firestore.DocumentReference;
  6. type DocumentSnapshot = fb.firestore.DocumentSnapshot;
  7. type LoadingDocumentSnapshot = DocumentSnapshot | undefined;
  8. type Dictionary<T> = { [key: string]: T };
  9. // type QuerySnapshot = fb.firestore.QuerySnapshot;
  10. // type LoadingCollectionSnapshot = QuerySnapshot | undefined;
  11.  
  12. export interface FireResource<T> {
  13. exists(): boolean;
  14. loading(): boolean;
  15. get(): T;
  16. }
  17.  
  18. export class FireDocument<T> implements FireResource<T> {
  19.  
  20. private name: string;
  21.  
  22. @observable private _snapshot: LoadingDocumentSnapshot = undefined;
  23. @computed get snapshot() { return this._snapshot; }
  24. set snapshot(snapshot: LoadingDocumentSnapshot) { this._snapshot = snapshot; }
  25.  
  26. constructor(doc: DocumentReference) {
  27. this.load(doc);
  28. }
  29.  
  30. exists() {
  31. return this.snapshot !== undefined && this.snapshot.exists;
  32. }
  33.  
  34. loading() {
  35. return this.snapshot === undefined;
  36. }
  37.  
  38. get(): T {
  39. if (this.snapshot !== undefined && this.snapshot.exists) {
  40. return this.snapshot.data() as T;
  41. } else {
  42. throw new Error(`Snapshot for ${this.name} doesn't exist`);
  43. }
  44. }
  45.  
  46. private async load(doc: DocumentReference) {
  47. this.snapshot = await doc.get();
  48. }
  49. }
  50.  
  51. export class FireCollection<T, U = Dictionary<T>> implements FireResource<U> {
  52.  
  53. private name: string;
  54. private filter: (doc: DocumentSnapshot) => boolean;
  55. private transform: (docs: DocumentSnapshot[]) => U;
  56.  
  57. @observable private _snapshot: U | undefined = undefined;
  58. @observable private _exists: boolean = false;
  59.  
  60. @computed get snapshot() { return this._snapshot; }
  61. set snapshot(snapshot: U | undefined) { this._snapshot = snapshot; }
  62.  
  63. constructor(col: Query) {
  64. this.load(col);
  65. this.transform =
  66. (docs: DocumentSnapshot[]) =>
  67. Object.assign({}, ...docs.map(doc => ({ [doc.id]: doc.data() as T })));
  68. }
  69.  
  70. loading() {
  71. return this.snapshot === undefined;
  72. }
  73.  
  74. exists() {
  75. return this._exists;
  76. }
  77.  
  78. setFilter(filter: (doc: DocumentSnapshot) => boolean) {
  79. this.filter = filter;
  80. }
  81.  
  82. setTransform(transform: (docs: DocumentSnapshot[]) => U) {
  83. this.transform = transform;
  84. }
  85.  
  86. get(): U {
  87. if (this.snapshot !== undefined && this.exists()) {
  88. return this.snapshot;
  89. } else {
  90. throw new Error(`Snapshot for ${this.name} doesn't exist`);
  91. }
  92. }
  93.  
  94. private async load(col: Query) {
  95. const snapshot = await col.get();
  96. const filtered = snapshot.docs.filter(doc => this.filter ? this.filter(doc) : true);
  97. runInAction(() => this._exists = filtered.length > 0);
  98. this.snapshot = this.transform(filtered);
  99. }
  100. }
Add Comment
Please, Sign In to add comment