Skip to content

Commit

Permalink
feat: save current notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
sanchezcarlosjr committed Nov 20, 2023
1 parent 67beba8 commit e682736
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 187 deletions.
12 changes: 6 additions & 6 deletions src/app/notebook/cellTypes/CodeBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class CodeBlock extends InteractiveBlock {
private language: Language;
private readonly outputCell: string;
private code: string;
private languages = ["javascript", "python", "html", 'sql', 'javascript webworker', "cpp"];
private languages = [{value: "javascript main thread", name: "javascript"}, {value: "python", name: "python"}, {value: "html", name: "html"}, {value: "sql", name: "sql"}, {value: "javascript", name: "javascript web worker"}, {value: "cpp", name: "cpp"}];

constructor(private editorJsTool: EditorJsTool) {
super(editorJsTool);
Expand All @@ -42,13 +42,13 @@ export class CodeBlock extends InteractiveBlock {

private languageFactory(language: string): Language {
return match(language)
.with("javascript", () => new JavaScriptMainThread(this.code, this.editorJsTool, this.cell))
.with("javascript main thread", () => new JavaScriptMainThread(this.code, this.editorJsTool, this.cell))
.with("python", () => new Python(this.code, this.editorJsTool, this.cell))
.with("html", () => new Html(this.code, this.editorJsTool, this.cell))
.with("sql", () => new Sql(this.code, this.editorJsTool, this.cell))
.with("cpp", () => new Cpp(this.code, this.editorJsTool, this.cell))
.with(
"javascript webworker", () => new JavaScript(this.code, this.editorJsTool, this.cell)
"javascript", () => new JavaScript(this.code, this.editorJsTool, this.cell)
)
.otherwise(
() => new JavaScript(this.code, this.editorJsTool,this.cell)
Expand Down Expand Up @@ -279,9 +279,9 @@ export class CodeBlock extends InteractiveBlock {
languagesSelect.classList.add("small");
for (const language of this.languages) {
const option = document.createElement("option");
option.value = language;
option.innerText = language;
if(language === this.language.name) {
option.value = language.value;
option.innerText = language.name;
if(language.value === this.language.name) {
option.selected = true;
}
languagesSelect.appendChild(option);
Expand Down
24 changes: 21 additions & 3 deletions src/app/notebook/shell/DatabaseManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import {BehaviorSubject, filter, firstValueFrom, map, Observable, shareReplay, Subscriber, switchMap} from "rxjs";
import {
BehaviorSubject,
filter,
first,
firstValueFrom,
map,
Observable,
shareReplay,
Subscriber,
switchMap
} from "rxjs";
import {OutputData} from "@editorjs/editorjs";
import {addRxPlugin, createRxDatabase, RxCollection, RxDatabaseBase, RxDocument, RxDumpDatabaseAny} from 'rxdb';
import {getRxStorageDexie} from 'rxdb/plugins/storage-dexie';
Expand All @@ -16,6 +26,7 @@ import {enforceOptions} from "broadcast-channel";
import {randomCouchString} from "rxdb/plugins/utils";
import {DocumentObserver} from "./documentObserver";
import {Injectable} from "@angular/core";
import {EditorJS} from "./editorJS";

addRxPlugin(RxDBLeaderElectionPlugin);

Expand Down Expand Up @@ -206,7 +217,9 @@ export class DatabaseManager {
this.database$.next(this._database);
// @ts-ignore
globalThis.environment = DocumentObserver.setup(this.database$);
collections.blocks.postInsert(async (plainData, rxDocument) =>{
// @ts-ignore
globalThis.editor = new EditorJS({topic: this.topic, peer: this._uuid, db: this.database$});
collections.blocks.postInsert(async (plainData, rxDocument) => {
await this.updateHistory();
return this.increaseIndexes(plainData.index);
}, false);
Expand Down Expand Up @@ -337,6 +350,11 @@ export class DatabaseManager {
return this._database?.exportJSON();
}

async exportCurrentNotebook() {
// @ts-ignore
return
}

importDatabase(json: RxDumpDatabaseAny<RxCollection>) {
return this._database?.importJSON(json);
}
Expand Down Expand Up @@ -499,7 +517,7 @@ export class DatabaseManager {
// @ts-ignore
return block?.updateCRDT({
selector: {
index: { $ne: index }
index: {$ne: index}
},
ifMatch: {
$set: {
Expand Down
159 changes: 159 additions & 0 deletions src/app/notebook/shell/editorJS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import {firstValueFrom, map, Observable, switchMap} from "rxjs";
import {RxDatabase} from "rxdb/dist/types/types";
import {OutputData} from "@editorjs/editorjs";
import {BlockAPI} from "@editorjs/editorjs/types/api/block";
import {BlockToolData, ToolConfig} from "@editorjs/editorjs/types/tools";
import {randomCouchString} from "rxdb";

interface Environment {
db: Observable<RxDatabase>;
topic?: string;
peer?: string;
}

export class EditorJS {
public static version: "2.26.5";
public readonly blocks = new Blocks(this.environment);

constructor(private environment: Environment) {
}

get isReady(): Promise<boolean> {
return new Promise((resolve) => resolve(true));
}

save(): Promise<OutputData> {
return firstValueFrom(this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].find({
selector: {
topic: {
$eq: this.environment.topic ?? ""
}
}
})
.exec()),
map(blocks => {
return blocks.map(doc => {
delete doc._data.crdts
delete doc._data._deleted
delete doc._data._deleted
delete doc._data._attachments
delete doc._data._rev
delete doc._data._meta
return doc._data
})
}),
map(blocks => ({
version: EditorJS.version, blocks
}))));
}
}

class Blocks {
constructor(private environment: Environment) {
}

get get$() {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].find({
selector: {
topic: {
$eq: this.environment.topic ?? ""
}
},
sort: [{index: 'asc'}]
}).$));
}

getById(id: string): Observable<BlockAPI | null> {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].findOne(id).$));
}

getByIndex(index: number): Observable<BlockAPI | null> {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].findOne({
selector: {
index: {
$eq: index
},
topic: {
$eq: this.environment.topic ?? ""
}
}
}).$));
}

insert(type?: string, data?: BlockToolData, config?: ToolConfig, index?: number, needToFocus?: boolean, replace?: boolean, id?: string) {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].insertCRDT({
ifMatch: {
$set: {
type,
data,
config,
index,
createdBy: (this.environment.peer ?? "") + "worker",
updatedBy: (this.environment.peer ?? "") + "worker",
id: id ?? randomCouchString(7),
topic: this.environment.topic ?? ""
}
}
})));
};

upsert(id?: string, data?: BlockToolData, type?: string, index?: number, config?: ToolConfig, needToFocus?: boolean, replace?: boolean) {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].insertCRDT({
selector: {
id: {$exists: true}
},
ifMatch: {
$set: {
id,
data,
updatedBy: (this.environment.peer ?? "") + "worker"
}
},
ifNotMatch: {
$set: {
type,
data,
config,
index,
createdBy: (this.environment.topic ?? "") + "worker",
updatedBy: (this.environment.peer ?? "") + "worker",
id: id ?? randomCouchString(7),
topic: this.environment.topic ?? ""
}
}
})));
}

update(id: string, data: BlockToolData) {
return this.environment.db.pipe(switchMap((db: RxDatabase) => db["blocks"].insertCRDT({
selector: {
id: {$exists: true}
},
ifMatch: {
$set: {
id,
data,
updatedBy: (this.environment.peer ?? "") + "worker"
}
}
})));
}

delete(id: string) {
return this.environment.db.pipe(
switchMap((db: RxDatabase) => db["blocks"].findOne(id).exec()),
switchMap(document => document?.updateCRDT({
selector: {
id: {$exists: true}
},
ifMatch: {
$set: {
id,
updatedBy: (this.environment.peer ?? "") + "worker",
_deleted: true
}
}
}))
);
}
}
Loading

0 comments on commit e682736

Please sign in to comment.