Implement IndexedDB document auto-save (#422)

* removed all use of document indicies

* -add u64 support for wasm bridge

* fixed rust formating

* Cleaned up FrontendDocumentState in js-messages

* Tiny tweaks from code review

* - moved more of closeDocumentWithConfirmation to rust
- updated serde_wasm_bindgen to add feature flag

* working initial auto save impl

* auto save is a lifetime file

* - cargo fmt
- fixc error message
- move document version constant

* code review round 1

* generate seed for uuid in js when wasm is initialized

* Resolve PR feedback

* Further address PR feedback

* Fix failing test

Co-authored-by: Keavon Chambers <keavon@keavon.com>
Co-authored-by: otdavies <oliver@psyfer.io>
This commit is contained in:
mfish33
2021-12-27 01:56:47 -08:00
committed by Keavon Chambers
co-authored by Keavon Chambers otdavies
parent d5c5560c55
commit bfdd0dc7e2
17 changed files with 255 additions and 30 deletions
+30 -2
View File
@@ -19,18 +19,26 @@ export class JsMessage {
// for details about how to transform the JSON from wasm-bindgen into classes.
// ============================================================================
export class FrontendDocumentDetails {
// Allows the auto save system to use a string for the id rather than a BigInt.
// IndexedDb does not allow for BigInts as primary keys. TypeScript does not allow
// subclasses to change the type of class variables in subclasses. It is an abstract
// class to point out that it should not be instantiated directly.
export abstract class DocumentDetails {
readonly name!: string;
readonly is_saved!: boolean;
readonly id!: BigInt;
readonly id!: BigInt | string;
get displayName() {
return `${this.name}${this.is_saved ? "" : "*"}`;
}
}
export class FrontendDocumentDetails extends DocumentDetails {
readonly id!: BigInt;
}
export class UpdateOpenDocumentsList extends JsMessage {
@Type(() => FrontendDocumentDetails)
readonly open_documents!: FrontendDocumentDetails[];
@@ -296,6 +304,24 @@ export const LayerTypeOptions = {
export type LayerType = typeof LayerTypeOptions[keyof typeof LayerTypeOptions];
export class IndexedDbDocumentDetails extends DocumentDetails {
@Transform(({ value }: { value: BigInt }) => value.toString())
id!: string;
}
export class AutoSaveDocument extends JsMessage {
document!: string;
@Type(() => IndexedDbDocumentDetails)
details!: IndexedDbDocumentDetails;
}
export class RemoveAutoSaveDocument extends JsMessage {
// Use a string since IndexedDB can not use BigInts for keys
@Transform(({ value }: { value: BigInt }) => value.toString())
document_id!: string;
}
// Any is used since the type of the object should be known from the rust side
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type JSMessageFactory = (data: any, wasm: WasmInstance, instance: RustEditorInstance) => JsMessage;
@@ -322,5 +348,7 @@ export const messageConstructors: Record<string, MessageMaker> = {
DisplayConfirmationToCloseDocument,
DisplayConfirmationToCloseAllDocuments,
DisplayAboutGraphiteDialog,
AutoSaveDocument,
RemoveAutoSaveDocument,
} as const;
export type JsMessageType = keyof typeof messageConstructors;