| 
														
															@@ -13,6 +13,7 @@ import { decompressData } from "../../data/encode"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import { encryptData, decryptData } from "../../data/encryption"; 
														 | 
														
														 | 
														
															 import { encryptData, decryptData } from "../../data/encryption"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import { MIME_TYPES } from "../../constants"; 
														 | 
														
														 | 
														
															 import { MIME_TYPES } from "../../constants"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import { reconcileElements } from "../collab/reconciliation"; 
														 | 
														
														 | 
														
															 import { reconcileElements } from "../collab/reconciliation"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+import { getSyncableElements, SyncableExcalidrawElement } from "."; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // private 
														 | 
														
														 | 
														
															 // private 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // ----------------------------------------------------------------------------- 
														 | 
														
														 | 
														
															 // ----------------------------------------------------------------------------- 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -127,7 +128,18 @@ const decryptElements = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   return JSON.parse(decodedData); 
														 | 
														
														 | 
														
															   return JSON.parse(decodedData); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 }; 
														 | 
														
														 | 
														
															 }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-const firebaseSceneVersionCache = new WeakMap<SocketIOClient.Socket, number>(); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+class FirebaseSceneVersionCache { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  private static cache = new WeakMap<SocketIOClient.Socket, number>(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  static get = (socket: SocketIOClient.Socket) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return FirebaseSceneVersionCache.cache.get(socket); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  static set = ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    socket: SocketIOClient.Socket, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    elements: readonly SyncableExcalidrawElement[], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  ) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    FirebaseSceneVersionCache.cache.set(socket, getSceneVersion(elements)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 export const isSavedToFirebase = ( 
														 | 
														
														 | 
														
															 export const isSavedToFirebase = ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   portal: Portal, 
														 | 
														
														 | 
														
															   portal: Portal, 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -136,7 +148,7 @@ export const isSavedToFirebase = ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   if (portal.socket && portal.roomId && portal.roomKey) { 
														 | 
														
														 | 
														
															   if (portal.socket && portal.roomId && portal.roomKey) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const sceneVersion = getSceneVersion(elements); 
														 | 
														
														 | 
														
															     const sceneVersion = getSceneVersion(elements); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return firebaseSceneVersionCache.get(portal.socket) === sceneVersion; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return FirebaseSceneVersionCache.get(portal.socket) === sceneVersion; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   // if no room exists, consider the room saved so that we don't unnecessarily 
														 | 
														
														 | 
														
															   // if no room exists, consider the room saved so that we don't unnecessarily 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   // prevent unload (there's nothing we could do at that point anyway) 
														 | 
														
														 | 
														
															   // prevent unload (there's nothing we could do at that point anyway) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -181,7 +193,7 @@ export const saveFilesToFirebase = async ({ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 const createFirebaseSceneDocument = async ( 
														 | 
														
														 | 
														
															 const createFirebaseSceneDocument = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   firebase: ResolutionType<typeof loadFirestore>, 
														 | 
														
														 | 
														
															   firebase: ResolutionType<typeof loadFirestore>, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  elements: readonly ExcalidrawElement[], 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  elements: readonly SyncableExcalidrawElement[], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   roomKey: string, 
														 | 
														
														 | 
														
															   roomKey: string, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 ) => { 
														 | 
														
														 | 
														
															 ) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   const sceneVersion = getSceneVersion(elements); 
														 | 
														
														 | 
														
															   const sceneVersion = getSceneVersion(elements); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -197,7 +209,7 @@ const createFirebaseSceneDocument = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 export const saveToFirebase = async ( 
														 | 
														
														 | 
														
															 export const saveToFirebase = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   portal: Portal, 
														 | 
														
														 | 
														
															   portal: Portal, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  elements: readonly ExcalidrawElement[], 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  elements: readonly SyncableExcalidrawElement[], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   appState: AppState, 
														 | 
														
														 | 
														
															   appState: AppState, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 ) => { 
														 | 
														
														 | 
														
															 ) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   const { roomId, roomKey, socket } = portal; 
														 | 
														
														 | 
														
															   const { roomId, roomKey, socket } = portal; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -229,18 +241,18 @@ export const saveToFirebase = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       transaction.set(docRef, sceneDocument); 
														 | 
														
														 | 
														
															       transaction.set(docRef, sceneDocument); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															       return { 
														 | 
														
														 | 
														
															       return { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sceneVersion: sceneDocument.sceneVersion, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        elements, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         reconciledElements: null, 
														 | 
														
														 | 
														
															         reconciledElements: null, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       }; 
														 | 
														
														 | 
														
															       }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const prevDocData = snapshot.data() as FirebaseStoredScene; 
														 | 
														
														 | 
														
															     const prevDocData = snapshot.data() as FirebaseStoredScene; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    const prevElements = await decryptElements(prevDocData, roomKey); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    const prevElements = getSyncableElements( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      await decryptElements(prevDocData, roomKey), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    ); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    const reconciledElements = reconcileElements( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      elements, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      prevElements, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      appState, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    const reconciledElements = getSyncableElements( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      reconcileElements(elements, prevElements, appState), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     ); 
														 | 
														
														 | 
														
															     ); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const sceneDocument = await createFirebaseSceneDocument( 
														 | 
														
														 | 
														
															     const sceneDocument = await createFirebaseSceneDocument( 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -251,14 +263,14 @@ export const saveToFirebase = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     transaction.update(docRef, sceneDocument); 
														 | 
														
														 | 
														
															     transaction.update(docRef, sceneDocument); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return { 
														 | 
														
														 | 
														
															     return { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      elements, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       reconciledElements, 
														 | 
														
														 | 
														
															       reconciledElements, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      sceneVersion: sceneDocument.sceneVersion, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     }; 
														 | 
														
														 | 
														
															     }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   }); 
														 | 
														
														 | 
														
															   }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  firebaseSceneVersionCache.set(socket, savedData.sceneVersion); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  FirebaseSceneVersionCache.set(socket, savedData.elements); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  return savedData; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  return { reconciledElements: savedData.reconciledElements }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 }; 
														 | 
														
														 | 
														
															 }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 export const loadFromFirebase = async ( 
														 | 
														
														 | 
														
															 export const loadFromFirebase = async ( 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -275,10 +287,12 @@ export const loadFromFirebase = async ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return null; 
														 | 
														
														 | 
														
															     return null; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   const storedScene = doc.data() as FirebaseStoredScene; 
														 | 
														
														 | 
														
															   const storedScene = doc.data() as FirebaseStoredScene; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  const elements = await decryptElements(storedScene, roomKey); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  const elements = getSyncableElements( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    await decryptElements(storedScene, roomKey), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  ); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   if (socket) { 
														 | 
														
														 | 
														
															   if (socket) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    firebaseSceneVersionCache.set(socket, getSceneVersion(elements)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    FirebaseSceneVersionCache.set(socket, elements); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   return restoreElements(elements, null); 
														 | 
														
														 | 
														
															   return restoreElements(elements, null); 
														 |