-
-
Save oshibka404/391254fc19fb5218e355909af8176cee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface DemoElement { | |
id: string, | |
name: string, | |
collectionId: string, | |
} | |
interface IFakeBackendDemo { | |
/** | |
* [GET] /elements/{elementId} -> DatabaseItem | |
* @param id element id | |
* @returns element with the given id or throws exception if not found | |
*/ | |
getElementById(id: string): Promise<DemoElement> | |
/** | |
* [POST] /elements/{collectionId} -> DatabaseItem | |
* HTTP Body {File} file | |
* @param collectionId id of the collection to which the element belongs | |
* @returns newly created element | |
*/ | |
createElement(collectionId: string, file: File): Promise<DemoElement> | |
/** | |
* [PATCH] /elements/{elementId} -> DatabaseItem | |
* HTTP Body {File} file | |
* @param element updated element data | |
* @returns updated element with the given id | |
*/ | |
updateElement(element: DemoElement): Promise<DemoElement> | |
/** | |
* [DELETE] /elements/{elementId} -> void | |
* @param id id of the element to delete | |
*/ | |
deleteElement(id: string): Promise<void> | |
/** | |
* [GET] /elements/?collectionId={collectionId} -> DatabaseItem[] | |
* @param collectionId id of the collection to which the elements belong | |
* @returns all elements with the given collectionId | |
*/ | |
getElementsByCollectionId(collectionId: string): Promise<DemoElement[]> | |
} | |
const initialDBUpgrade = (db: IDBDatabase) => { | |
// version 0 means that the client had no database | |
const elementStore = db.createObjectStore('elements', {keyPath: 'id'}) | |
// Create indexes for faster querying: we're going to query by name and collectionId | |
elementStore.createIndex('name', 'name', {unique: false}) | |
elementStore.createIndex('collectionId', 'collectionId', {unique: false}) | |
// Optional step: populate the store with initial set of elements | |
elementStore.transaction.oncomplete = () => { | |
const elementObjectStore = db.transaction('elements', 'readwrite').objectStore('elements') | |
elementObjectStore.add({ | |
id: '1', | |
name: 'Element 1', | |
collectionId: '1', | |
}) | |
} | |
} | |
interface FileUploader { | |
uploadFile(file: File): Promise<{data: {id: string, name: string}}> | |
} | |
export class FakeBackendDemo implements IFakeBackendDemo { | |
private db?: IDBDatabase | |
constructor(private fileUploader: FileUploader) { | |
const request = window.indexedDB.open('DIAG-1234-BackendMockDemo', 1) | |
request.onerror = () => { | |
throw new Error(`can't connect to indexed db`) | |
} | |
request.onsuccess = event => { | |
this.db = (event.target as IDBRequest<IDBDatabase>).result | |
} | |
request.onupgradeneeded = (event: IDBVersionChangeEvent) => { | |
const db = (event.target as IDBRequest<IDBDatabase>).result | |
switch(event.oldVersion) { // existing db version | |
case 0: | |
initialDBUpgrade(db) | |
case 1: | |
// here will go your next database update | |
default: | |
throw new Error(`error updating a database: unsupported version of db`) | |
} | |
} | |
} | |
public async getElementById(id: string): Promise<DemoElement> { | |
if (!this.db) { | |
throw new Error('db is not initialized') | |
} | |
const transaction = this.db.transaction('elements', 'readonly') | |
const elementStore = transaction.objectStore('elements') | |
const request = elementStore.get(id) | |
return new Promise((resolve, reject) => { | |
request.onsuccess = () => { | |
resolve(request.result) | |
} | |
request.onerror = () => { | |
reject(new Error(`element with id ${id} not found`)) | |
} | |
}) | |
} | |
async createElement(collectionId: string, file: File): Promise<DemoElement> { | |
if (!this.db) { | |
throw new Error('DB not initialized') | |
} | |
const {data} = await this.fileUploader.uploadFile(file) | |
const newElement = { | |
id: data.id, | |
name: data.name, | |
collectionId, | |
} | |
const request = this.db.transaction('elements', 'readwrite').objectStore('elements').add(newElement) | |
return new Promise((resolve, reject) => { | |
request.onsuccess = () => { | |
resolve(newElement) | |
} | |
request.onerror = () => { | |
reject(request.error) | |
} | |
}) | |
} | |
async updateElement(element: DemoElement): Promise<DemoElement> { | |
if (!this.db) { | |
throw new Error('DB not initialized') | |
} | |
const request = this.db.transaction('elements', 'readwrite').objectStore('elements').put(element) | |
return new Promise((resolve, reject) => { | |
request.onsuccess = () => { | |
resolve(element) | |
} | |
request.onerror = () => { | |
reject(request.error) | |
} | |
}) | |
} | |
async deleteElement(id: string): Promise<void> { | |
if (!this.db) { | |
throw new Error('DB not initialized') | |
} | |
const request = this.db.transaction('elements', 'readwrite').objectStore('elements').delete(id) | |
return new Promise((resolve, reject) => { | |
request.onsuccess = () => { | |
resolve() | |
} | |
request.onerror = () => { | |
reject(request.error) | |
} | |
}) | |
} | |
async getElementsByCollectionId(collectionId: string): Promise<DemoElement[]> { | |
if (!this.db) { | |
throw new Error('DB not initialized') | |
} | |
const transaction = this.db.transaction('elements', 'readonly') | |
const elementStore = transaction.objectStore('elements') | |
const index = elementStore.index('collectionId') | |
const request = index.getAll(collectionId) | |
return new Promise((resolve, reject) => { | |
request.onsuccess = () => { | |
resolve(request.result) | |
} | |
request.onerror = () => { | |
reject(request.error) | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment