diff --git a/README.md b/README.md index e10d793..ae20fb1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ A database and connection provider for Yjs based on Firestore. y-fire is a Firestore (Firebase) and WebRTC-based provider, built especially for serverless infrastructure, that offers real-time capabilities to your Yjs-based applications. y-fire is built with efficiency in mind to reduce the number of calls that the application makes to and from Firestore. With y-fire, Firestore will act as both 1. persistent storage and 2. a peer discovery platform for WebRTC connections. This means that real-time updates are shared through a peer-to-peer network, thus reducing connections to Firestore. y-fire was inspired by [yjs-firestore-provider](https://github.com/gmcfall/yjs-firestore-provider) but implements few things differently. - https://github.com/podraven/y-fire/assets/2324523/3aa27a40-6cfb-4b93-b043-4e0fa57c96d4 # Features @@ -105,6 +104,7 @@ You need to grant **read and write** permissions to the document `/path/to/your/ - **firebaseApp**: FirebaseApp (required) - **ydoc**: Y.Doc (required) - **path**: path to your **document** (required) ex. users/username/tasks/task-1 +- **docMapper**: Custom structure for your document (saves to the `content` field by default) - **maxUpdatesThreshold**: Number of updates before triggering real-time data share, defaults to 20 - **maxWaitTime**: Time in milliseconds before triggering real-time data share, defaults to 100 - **maxWaitFirestoreTime**: Time in milliseconds before triggering persistent data sync to Firestore, defaults to 3000 @@ -122,6 +122,20 @@ new FireProvider({ }); ``` +docMapper example with custom document structure + +``` +new FireProvider({ + firebaseApp, + ydoc, + path: "username/tasks/taskuid", + docMapper: (bytes) => ({ + title: "Custom title", + file: { filename: "file.docx", content: bytes }, // "bytes" contains your yjs data + }), +}); +``` + #### Methods - **destroy**: Destroys the y-fire instance. You may want to destroy the y-fire instance when navigating out of the page to avoid the initialization of duplicate instances. Use `provider.destroy();` to destroy the instance. diff --git a/package.json b/package.json index 8116907..ee58e85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "y-fire", - "version": "2.0.0", + "version": "2.1.0", "description": "A firebase (firestore) provider for Yjs", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/provider.ts b/src/provider.ts index df3f394..3151918 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -21,6 +21,7 @@ export interface Parameters { firebaseApp: FirebaseApp; ydoc: Y.Doc; path: string; + docMapper?: (bytes: Bytes) => object; maxUpdatesThreshold?: number; maxWaitTime?: number; maxWaitFirestoreTime?: number; @@ -63,6 +64,8 @@ export class FireProvider extends ObservableV2 { senders: {}, }; + documentMapper: (bytes: Bytes) => object = (bytes) => ({ content: bytes }); + cache: Uint8Array | null; maxCacheUpdates: number = 20; cacheUpdateCount: number = 0; @@ -310,7 +313,9 @@ export class FireProvider extends ObservableV2 { const ref = doc(this.db, this.documentPath); await setDoc( ref, - { content: Bytes.fromUint8Array(Y.encodeStateAsUpdate(this.doc)) }, + this.documentMapper( + Bytes.fromUint8Array(Y.encodeStateAsUpdate(this.doc)) + ), { merge: true } ); this.deleteLocal(); // We have successfully saved to Firestore, empty indexedDb for now @@ -481,6 +486,7 @@ export class FireProvider extends ObservableV2 { firebaseApp, ydoc, path, + docMapper, maxUpdatesThreshold, maxWaitTime, maxWaitFirestoreTime, @@ -492,6 +498,7 @@ export class FireProvider extends ObservableV2 { this.db = getFirestore(this.firebaseApp); this.doc = ydoc; this.documentPath = path; + if (docMapper) this.documentMapper = docMapper; if (maxUpdatesThreshold) this.maxCacheUpdates = maxUpdatesThreshold; if (maxWaitTime) this.maxRTCWait = maxWaitTime; if (maxWaitFirestoreTime) this.maxFirestoreWait = maxWaitFirestoreTime;