Enabled back-end running of functions, moved indexing to server.

pull/3/head
Zef Hemel 2022-03-18 16:27:40 +01:00
parent 8bff6d98e1
commit d5528fef2a
6 changed files with 41 additions and 122 deletions

View File

@ -70,7 +70,8 @@ export class SocketServer {
this.connectedSockets.delete(socket); this.connectedSockets.delete(socket);
}); });
socket.on("closePage", (pageName: string) => { socket.on("page.closePage", (pageName: string) => {
console.log("Client closed page", pageName);
disconnectPageSocket(pageName); disconnectPageSocket(pageName);
clientConn.openPages.delete(pageName); clientConn.openPages.delete(pageName);
}); });

View File

@ -197,18 +197,21 @@ export class PageApi implements ApiProvider {
); );
if (textChanged) { if (textChanged) {
if (page.saveTimer) { // Throttle
clearTimeout(page.saveTimer); if (!page.saveTimer) {
} page.saveTimer = setTimeout(() => {
if (page) {
console.log("Indexing", pageName);
page.saveTimer = setTimeout(() => { this.system.dispatchEvent("page:index", {
console.log("This is the time to index a page"); name: pageName,
this.system.dispatchEvent("page:index", { text: page.text.sliceString(0),
name: pageName, });
text: page!.text.sliceString(0), this.flushPageToDisk(pageName, page);
}); page.saveTimer = undefined;
this.flushPageToDisk(pageName, page!); }
}, 1000); }, 1000);
}
} }
while (page.pending.length) { while (page.pending.length) {
page.pending.pop()!(transformedUpdates); page.pending.pop()!(transformedUpdates);

View File

@ -1,4 +1,5 @@
import { Knex } from "knex"; import { Knex } from "knex";
type IndexItem = { type IndexItem = {
page: string; page: string;
key: string; key: string;
@ -11,26 +12,25 @@ export type KV = {
}; };
export default function (db: Knex) { export default function (db: Knex) {
const setter = async (page: string, key: string, value: any) => { const apiObj = {
let changed = await db<IndexItem>("page_index")
.where({ page, key })
.update("value", JSON.stringify(value));
if (changed === 0) {
await db<IndexItem>("page_index").insert({
page,
key,
value: JSON.stringify(value),
});
}
};
return {
"indexer.clearPageIndexForPage": async (page: string) => { "indexer.clearPageIndexForPage": async (page: string) => {
await db<IndexItem>("page_index").where({ page }).del(); await db<IndexItem>("page_index").where({ page }).del();
}, },
"indexer.set": setter, "indexer.set": async (page: string, key: string, value: any) => {
let changed = await db<IndexItem>("page_index")
.where({ page, key })
.update("value", JSON.stringify(value));
if (changed === 0) {
await db<IndexItem>("page_index").insert({
page,
key,
value: JSON.stringify(value),
});
}
},
"indexer.batchSet": async (page: string, kvs: KV[]) => { "indexer.batchSet": async (page: string, kvs: KV[]) => {
for (let { key, value } of kvs) { for (let { key, value } of kvs) {
await setter(page, key, value); await apiObj["indexer.set"](page, key, value);
} }
}, },
"indexer.get": async (page: string, key: string) => { "indexer.get": async (page: string, key: string) => {
@ -79,4 +79,5 @@ export default function (db: Knex) {
return db<IndexItem>("page_index").del(); return db<IndexItem>("page_index").del();
}, },
}; };
return apiObj;
} }

View File

@ -10,13 +10,7 @@ import { indentWithTab, standardKeymap } from "@codemirror/commands";
import { history, historyKeymap } from "@codemirror/history"; import { history, historyKeymap } from "@codemirror/history";
import { bracketMatching } from "@codemirror/matchbrackets"; import { bracketMatching } from "@codemirror/matchbrackets";
import { searchKeymap } from "@codemirror/search"; import { searchKeymap } from "@codemirror/search";
import { import { EditorSelection, EditorState, Text } from "@codemirror/state";
EditorSelection,
EditorState,
StateField,
Text,
Transaction,
} from "@codemirror/state";
import { import {
drawSelection, drawSelection,
dropCursor, dropCursor,
@ -29,18 +23,15 @@ import {
import React, { useEffect, useReducer } from "react"; import React, { useEffect, useReducer } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { Plug, System } from "../../plugbox/src/runtime"; import { Plug, System } from "../../plugbox/src/runtime";
import { createSandbox } from "../../plugbox/src/webworker_sandbox";
import { createSandbox as createIFrameSandbox } from "../../plugbox/src/iframe_sandbox"; import { createSandbox as createIFrameSandbox } from "../../plugbox/src/iframe_sandbox";
import { AppEvent, AppEventDispatcher, ClickEvent } from "./app_event"; import { AppEvent, AppEventDispatcher, ClickEvent } from "./app_event";
import { collabExtension, CollabDocument } from "./collab"; import { CollabDocument, collabExtension } from "./collab";
import * as commands from "./commands"; import * as commands from "./commands";
import { CommandPalette } from "./components/command_palette"; import { CommandPalette } from "./components/command_palette";
import { PageNavigator } from "./components/page_navigator"; import { PageNavigator } from "./components/page_navigator";
import { StatusBar } from "./components/status_bar";
import { TopBar } from "./components/top_bar"; import { TopBar } from "./components/top_bar";
import { Cursor } from "./cursorEffect"; import { Cursor } from "./cursorEffect";
import coreManifest from "./generated/core.plug.json"; import coreManifest from "./generated/core.plug.json";
import { Indexer } from "./indexer";
import { lineWrapper } from "./lineWrapper"; import { lineWrapper } from "./lineWrapper";
import { markdown } from "./markdown"; import { markdown } from "./markdown";
import { IPageNavigator, PathPageNavigator } from "./navigator"; import { IPageNavigator, PathPageNavigator } from "./navigator";
@ -61,7 +52,7 @@ import {
NuggetHook, NuggetHook,
slashCommandRegexp, slashCommandRegexp,
} from "./types"; } from "./types";
import { safeRun, throttle } from "./util"; import { safeRun } from "./util";
class PageState { class PageState {
scrollTop: number; scrollTop: number;
@ -81,10 +72,8 @@ export class Editor implements AppEventDispatcher {
space: Space; space: Space;
editorCommands: Map<string, AppCommand>; editorCommands: Map<string, AppCommand>;
plugs: Plug<NuggetHook>[]; plugs: Plug<NuggetHook>[];
indexer: Indexer;
navigationResolve?: (val: undefined) => void; navigationResolve?: (val: undefined) => void;
pageNavigator: IPageNavigator; pageNavigator: IPageNavigator;
indexCurrentPageDebounced: () => any;
constructor(space: Space, parent: Element) { constructor(space: Space, parent: Element) {
this.editorCommands = new Map(); this.editorCommands = new Map();
@ -102,12 +91,6 @@ export class Editor implements AppEventDispatcher {
parent: document.getElementById("editor")!, parent: document.getElementById("editor")!,
}); });
this.pageNavigator = new PathPageNavigator(); this.pageNavigator = new PathPageNavigator();
this.indexer = new Indexer(space);
this.indexCurrentPageDebounced = throttle(
this.indexCurrentPage.bind(this),
2000
);
} }
async init() { async init() {
@ -228,7 +211,6 @@ export class Editor implements AppEventDispatcher {
} }
createEditorState(pageName: string, doc: CollabDocument): EditorState { createEditorState(pageName: string, doc: CollabDocument): EditorState {
const editor = this;
let commandKeyBindings: KeyBinding[] = []; let commandKeyBindings: KeyBinding[] = [];
for (let def of this.editorCommands.values()) { for (let def of this.editorCommands.values()) {
if (def.command.key) { if (def.command.key) {
@ -311,7 +293,7 @@ export class Editor implements AppEventDispatcher {
{ {
key: "Ctrl-k", key: "Ctrl-k",
mac: "Cmd-k", mac: "Cmd-k",
run: (target): boolean => { run: (): boolean => {
this.viewDispatch({ type: "start-navigate" }); this.viewDispatch({ type: "start-navigate" });
return true; return true;
}, },
@ -319,7 +301,7 @@ export class Editor implements AppEventDispatcher {
{ {
key: "Ctrl-.", key: "Ctrl-.",
mac: "Cmd-.", mac: "Cmd-.",
run: (target): boolean => { run: (): boolean => {
this.viewDispatch({ this.viewDispatch({
type: "show-palette", type: "show-palette",
}); });
@ -343,22 +325,18 @@ export class Editor implements AppEventDispatcher {
markdown({ markdown({
base: customMarkDown, base: customMarkDown,
}), }),
StateField.define({
create: () => null,
update: this.update.bind(this),
}),
], ],
}); });
} }
reloadPage() { reloadPage() {
console.log("Reloading page"); console.log("Reloading page");
this.loadPage(this.currentPage!); safeRun(async () => {
await this.loadPage(this.currentPage!);
});
} }
async plugCompleter( async plugCompleter(): Promise<CompletionResult | null> {
ctx: CompletionContext
): Promise<CompletionResult | null> {
let allCompletionResults = await this.dispatchAppEvent("editor:complete"); let allCompletionResults = await this.dispatchAppEvent("editor:complete");
if (allCompletionResults.length === 1) { if (allCompletionResults.length === 1) {
return allCompletionResults[0]; return allCompletionResults[0];
@ -404,26 +382,6 @@ export class Editor implements AppEventDispatcher {
}; };
} }
update(value: null, transaction: Transaction): null {
if (transaction.docChanged) {
this.indexCurrentPageDebounced();
}
return null;
}
private async indexCurrentPage() {
if (this.currentPage) {
console.log("Indexing page", this.currentPage);
await this.indexer.indexPage(
this,
this.currentPage,
this.editorView!.state.sliceDoc(),
true
);
}
}
focus() { focus() {
this.editorView!.focus(); this.editorView!.focus();
} }
@ -473,9 +431,6 @@ export class Editor implements AppEventDispatcher {
type: "page-loaded", type: "page-loaded",
name: pageName, name: pageName,
}); });
// TODO: Check if indexing is required?
await this.indexCurrentPage();
} }
ViewComponent(): React.ReactElement { ViewComponent(): React.ReactElement {

View File

@ -1,38 +0,0 @@
import { AppEventDispatcher, IndexEvent } from "./app_event";
import { Space } from "./space";
export class Indexer {
space: Space;
constructor(space: Space) {
this.space = space;
}
async indexPage(
appEventDispatcher: AppEventDispatcher,
pageName: string,
text: string,
withFlush: boolean
) {
if (withFlush) {
await this.space.indexDeletePrefixForPage(pageName, "");
}
let indexEvent: IndexEvent = {
name: pageName,
text,
};
// await appEventDispatcher.dispatchAppEvent("page:index", indexEvent);
// await this.setPageIndexPageMeta(pageMeta.name, pageMeta);
}
async reindexSpace(space: Space, appEventDispatcher: AppEventDispatcher) {
let allPages = await space.listPages();
// TODO: Parallelize?
for (let page of allPages) {
await space.indexDeletePrefixForPage(page.name, "");
let pageData = await space.readPage(page.name);
await this.indexPage(appEventDispatcher, page.name, pageData.text, false);
}
}
}

View File

@ -5,9 +5,6 @@ export default (editor: Editor) => ({
"space.listPages": (): PageMeta[] => { "space.listPages": (): PageMeta[] => {
return [...editor.viewState.allPages]; return [...editor.viewState.allPages];
}, },
"space.reindex": async () => {
await editor.indexer.reindexSpace(editor.space, editor);
},
"space.readPage": async ( "space.readPage": async (
name: string name: string
): Promise<{ text: string; meta: PageMeta }> => { ): Promise<{ text: string; meta: PageMeta }> => {