Skip to content

Commit

Permalink
Add functions to get and fetch workspace backup (#437)
Browse files Browse the repository at this point in the history
#437

* Add functions to get and fetch workspace backup

* changeset added

* removed unnecessary function call;

Signed-off-by: Sahil Shubham <[email protected]>

---------

Signed-off-by: Sahil Shubham <[email protected]>
Co-authored-by: Sahil Shubham <[email protected]>
  • Loading branch information
rpPanda and sahil-shubham authored Jun 16, 2023
1 parent 6013df2 commit e3cce8e
Show file tree
Hide file tree
Showing 7 changed files with 767 additions and 723 deletions.
6 changes: 6 additions & 0 deletions .changeset/rotten-eggs-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'mexit': patch
'mexit-webapp': patch
---

Store and fetch workspace backup on cloud
4 changes: 2 additions & 2 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@udecode/plate": "^16.4.1",
"@use-gesture/react": "^10.2.27",
"@webcomponents/custom-elements": "1.5.0",
"@workduck-io/dwindle": "^0.1.7",
"@workduck-io/dwindle": "^0.2.0",
"@workduck-io/mex-components": "^0.0.25",
"@workduck-io/mex-themes": "^0.0.9",
"@workduck-io/tinykeys": "^1.5.0",
Expand Down Expand Up @@ -99,4 +99,4 @@
"last 1 safari version"
]
}
}
}
4 changes: 2 additions & 2 deletions apps/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@tippyjs/react": "^4.2.6",
"@udecode/plate": "^16.4.1",
"@uifabric/styling": "^7.20.0",
"@workduck-io/dwindle": "^0.1.7",
"@workduck-io/dwindle": "^0.2.0",
"@workduck-io/flexsearch": "^0.7.22",
"@workduck-io/mex-components": "^0.0.25",
"@workduck-io/mex-themes": "^0.0.9",
Expand Down Expand Up @@ -123,4 +123,4 @@
"last 1 safari version"
]
}
}
}
26 changes: 22 additions & 4 deletions libs/core/src/Hooks/useStore.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// @ts-nocheck

import * as Store from '../Stores'
import { getStoreName, StoreIdentifier } from '../Types'
import { BackupStorage, getLocalStorage, isExtension, mog } from '../Utils'

const getBackupStores = (excludeStores: Array<string> = ['useLayoutStore', 'useAppStore', 'useAuthStore']) => {
const stores = []

Object.entries(Store).forEach(([key, store]) => {
//@ts-ignore
if (!excludeStores.includes(key) && typeof store === 'function' && store?.getState && store?.getState()?.backup) {
stores.push(store)
}
Expand All @@ -14,14 +15,31 @@ const getBackupStores = (excludeStores: Array<string> = ['useLayoutStore', 'useA
return stores
}

const getWorkspaceIdFromStorage = () => {
const storeName = getStoreName(StoreIdentifier.AUTH, isExtension())
const authStorage = getLocalStorage().getItem(storeName)

if (authStorage) {
const workspace = JSON.parse(authStorage)?.state?.workspaceDetails
return workspace?.id
}
}

export const useStore = () => {
const backup = async () => {
await Promise.allSettled(getBackupStores().map((utilFunc) => utilFunc?.getState()?.backup()))
const workspaceId = getWorkspaceIdFromStorage()
await Promise.allSettled(getBackupStores().map((utilFunc) => utilFunc?.getState()?.backup(workspaceId)))
const s3URL = await BackupStorage.backUpToS3(workspaceId)
mog('Saving Backup', {
s3URL,
workspaceId
})
}

const restore = async (): Promise<boolean> => {
const workspaceId = getWorkspaceIdFromStorage()
const result = await Promise.allSettled(
getBackupStores().map((utilFunc) => utilFunc?.getState()?.initializeFromBackup())
getBackupStores().map((utilFunc) => utilFunc?.getState()?.initializeFromBackup(workspaceId))
)

for (const res of result) {
Expand Down
15 changes: 15 additions & 0 deletions libs/core/src/Utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import { IDBPDatabase, openDB } from 'idb'

import { S3FileDownloadClient, S3FileUploadClient } from '@workduck-io/dwindle'

import { mog } from './mog'

export const getLocalStorage = () => {
Expand Down Expand Up @@ -68,6 +70,19 @@ class BackupStorageClass {
return result
}

async backUpToS3(tableName: string) {
const result = await this.getAllValue(tableName)
return await S3FileUploadClient(JSON.stringify(result), {
fileName: `WORKSPACE_BACKUP_${tableName}`
})
}

async fetchFromS3(tableName: string) {
return await S3FileDownloadClient({
fileName: `WORKSPACE_BACKUP_${tableName}`
})
}

async putBulkValue(tableName: string, values: object[]) {
const tx = this.db.transaction(tableName, 'readwrite')
const store = tx.objectStore(tableName)
Expand Down
24 changes: 5 additions & 19 deletions libs/core/src/Utils/storeCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { getStoreName, StoreIdentifier } from '../Types/Store'
import { asyncLocalStorage } from './chromeStorageAdapter'
import { IDBStorage } from './idbStorageAdapter'
import { isExtension } from './isExtension'
import { BackupStorage, getLocalStorage } from './storage'
import { BackupStorage } from './storage'

export type TypeMap<T, R extends boolean> = R extends true
? T & {
_hasHydrated: boolean
setHasHydrated: (state) => void
initializeFromBackup: () => Promise<boolean>
backup: () => Promise<void>
initializeFromBackup: (workspaceId: string) => Promise<boolean>
backup: (workspaceId: string) => Promise<void>
}
: T

Expand All @@ -24,16 +24,6 @@ export type StorageType = {
extension: Storage
}

const getWorkspaceIdFromStorage = () => {
const storeName = getStoreName(StoreIdentifier.AUTH, isExtension())
const authStorage = getLocalStorage().getItem(storeName)

if (authStorage) {
const workspace = JSON.parse(authStorage)?.state?.workspaceDetails
return workspace?.id
}
}

export const createStore = <T extends object, R extends boolean>(
config: SetterFunction<T>,
name: StoreIdentifier,
Expand All @@ -55,18 +45,14 @@ export const createStore = <T extends object, R extends boolean>(
_hasHydrated: state
})
},
backup: async () => {
backup: async (workspaceId) => {
// TODO: Backup to storage
const workspaceId = getWorkspaceIdFromStorage()
if (workspaceId && !isExtension()) {
const storeToBackup = get()
BackupStorage.putValue(workspaceId, storeName, JSON.stringify(storeToBackup))
}
},
initializeFromBackup: async () => {
// TODO: Initialize from stored backup
const workspaceId = getWorkspaceIdFromStorage()

initializeFromBackup: async (workspaceId) => {
if (workspaceId && !isExtension()) {
const storedBackup = await BackupStorage.getValue(workspaceId, storeName)
if (storedBackup) {
Expand Down
Loading

0 comments on commit e3cce8e

Please sign in to comment.