Enabled back-end running of functions, moved indexing to server.
parent
8bff6d98e1
commit
d5528fef2a
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 }> => {
|
||||||
|
|
Loading…
Reference in New Issue