| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import { IdbLocalStorage } from "../../Web/IdbLocalStorage" | 
					
						
							|  |  |  | import { UIEventSource } from "../../UIEventSource" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * A class which allows to read/write a tile to local storage. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |  * Does the heavy lifting for LocalStorageFeatureSource and SaveFeatureToLocalStorage. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Note: OSM-features with a negative id are ignored | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | export default class TileLocalStorage<T> { | 
					
						
							|  |  |  |     private static perLayer: Record<string, TileLocalStorage<any>> = {} | 
					
						
							|  |  |  |     private readonly _layername: string | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  |     private readonly inUse = new UIEventSource(false) | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |     private readonly cachedSources: Record<number, UIEventSource<T> & { flush: () => void }> = {} | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private constructor(layername: string) { | 
					
						
							|  |  |  |         this._layername = layername | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |     public static construct<T>(backend: string, layername: string): TileLocalStorage<T> { | 
					
						
							|  |  |  |         const key = backend + "_" + layername | 
					
						
							|  |  |  |         const cached = TileLocalStorage.perLayer[key] | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         if (cached) { | 
					
						
							|  |  |  |             return cached | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |         const tls = new TileLocalStorage<T>(key) | 
					
						
							|  |  |  |         TileLocalStorage.perLayer[key] = tls | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         return tls | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |      * Constructs a UIEventSource element which is synced with localStorage. | 
					
						
							|  |  |  |      * Supports 'flush' | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |     public getTileSource(tileIndex: number): UIEventSource<T> & { flush: () => void } { | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         const cached = this.cachedSources[tileIndex] | 
					
						
							|  |  |  |         if (cached) { | 
					
						
							|  |  |  |             return cached | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |         const src = <UIEventSource<T> & { flush: () => void }>( | 
					
						
							|  |  |  |             UIEventSource.FromPromise(this.GetIdb(tileIndex)) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         src.flush = () => this.SetIdb(tileIndex, src.data) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         src.addCallbackD((data) => this.SetIdb(tileIndex, data)) | 
					
						
							|  |  |  |         this.cachedSources[tileIndex] = src | 
					
						
							|  |  |  |         return src | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |     private async SetIdb(tileIndex: number, data: any): Promise<void> { | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  |             await this.inUse.AsPromise((inUse) => !inUse) | 
					
						
							|  |  |  |             this.inUse.setData(true) | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |             await IdbLocalStorage.SetDirectly(this._layername + "_" + tileIndex, data) | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  |             this.inUse.setData(false) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         } catch (e) { | 
					
						
							|  |  |  |             console.error( | 
					
						
							|  |  |  |                 "Could not save tile to indexed-db: ", | 
					
						
							|  |  |  |                 e, | 
					
						
							|  |  |  |                 "tileIndex is:", | 
					
						
							|  |  |  |                 tileIndex, | 
					
						
							|  |  |  |                 "for layer", | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |                 this._layername, | 
					
						
							|  |  |  |                 "data is", | 
					
						
							|  |  |  |                 data | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private GetIdb(tileIndex: number): Promise<any> { | 
					
						
							|  |  |  |         return IdbLocalStorage.GetDirectly(this._layername + "_" + tileIndex) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |