Migrated to pacel and removed deno

This commit is contained in:
Zef Hemel
2022-03-04 10:26:41 +01:00
parent f73acae41a
commit 24ceaea9d5
31 changed files with 4685 additions and 281 deletions
+78
View File
@@ -0,0 +1,78 @@
{
"commands": {
"Navigate To page": {
"invoke": "linkNavigate",
"key": "Ctrl-Enter",
"mac": "Cmd-Enter"
},
"Insert Current Date": {
"invoke": "insertToday",
"slashCommand": "/today"
},
"Toggle : Heading 1": {
"invoke": "toggle_h1",
"mac": "Cmd-1",
"key": "Ctrl-1"
},
"Toggle : Heading 2": {
"invoke": "toggle_h2",
"mac": "Cmd-2",
"key": "Ctrl-2"
},
"Page: Delete": {
"invoke": "deletePage"
},
"Page: Rename": {
"invoke": "renamePage"
},
"Pages: Reindex": {
"invoke": "reindexPages"
},
"Pages: Back Links": {
"invoke": "showBackLinks"
}
},
"events": {
"page:click": ["taskToggle", "clickNavigate"],
"editor:complete": ["pageComplete"],
"page:index": ["indexLinks"]
},
"functions": {
"indexLinks": {
"path": "./page.ts:indexLinks"
},
"deletePage": {
"path": "./page.ts:deletePage"
},
"showBackLinks": {
"path": "./page.ts:showBackLinks"
},
"renamePage": {
"path": "./page.ts:renamePage"
},
"reindexPages": {
"path": "./page.ts:reindex"
},
"pageComplete": {
"path": "./navigate.ts:pageComplete"
},
"linkNavigate": {
"path": "./navigate.ts:linkNavigate"
},
"clickNavigate": {
"path": "./navigate.ts:clickNavigate"
},
"taskToggle": {
"path": "./task.ts:taskToggle"
},
"insertToday": {
"path": "./dates.ts:insertToday"
},
"toggle_h1": {
"path": "./markup.ts:toggleH1"
},
"toggle_h2": {
"path": "./markup.ts:toggleH2"
}
}
}
+6
View File
@@ -0,0 +1,6 @@
import { syscall } from "./lib/syscall.ts";
export async function insertToday() {
let niceDate = new Date().toISOString().split("T")[0];
await syscall("editor.insertAtCursor", niceDate);
}
+9
View File
@@ -0,0 +1,9 @@
import {syscall} from "./syscall.ts";
export async function put(key: string, value: any) {
return await syscall("db.put", key, value);
}
export async function get(key: string) {
return await syscall("db.get", key);
}
+16
View File
@@ -0,0 +1,16 @@
export function syscall(name: string, ...args: any[]): any {
let reqId = Math.floor(Math.random() * 1000000);
// console.log("Syscall", name, reqId);
return new Promise((resolve, reject) => {
self.dispatchEvent(
new CustomEvent("syscall", {
detail: {
id: reqId,
name: name,
args: args,
callback: resolve,
},
})
);
});
}
+33
View File
@@ -0,0 +1,33 @@
import { syscall } from "./lib/syscall.ts";
export async function toggleH1() {
await togglePrefix("# ");
}
export async function toggleH2() {
await togglePrefix("## ");
}
function lookBack(s: string, pos: number, backString: string): boolean {
return s.substring(pos - backString.length, pos) === backString;
}
async function togglePrefix(prefix: string) {
let text = (await syscall("editor.getText")) as string;
let pos = (await syscall("editor.getCursor")) as number;
if (text[pos] === "\n") {
pos--;
}
while (pos > 0 && text[pos] !== "\n") {
if (lookBack(text, pos, prefix)) {
// Already has this prefix, let's flip it
await syscall("editor.replaceRange", pos - prefix.length, pos, "");
return;
}
pos--;
}
if (pos) {
pos++;
}
await syscall("editor.insertAtPos", prefix, pos);
}
+49
View File
@@ -0,0 +1,49 @@
import { ClickEvent } from "../../webapp/src/app_event.ts";
import { syscall } from "./lib/syscall.ts";
async function navigate(syntaxNode: any) {
if (!syntaxNode) {
return;
}
console.log("Attempting to navigate based on syntax node", syntaxNode);
switch (syntaxNode.name) {
case "WikiLinkPage":
await syscall("editor.navigate", syntaxNode.text);
break;
case "URL":
await syscall("editor.openUrl", syntaxNode.text);
break;
case "Link":
// Markdown link: [bla](URLHERE) needs extraction
let match = /\[[^\\]+\]\(([^\)]+)\)/.exec(syntaxNode.text);
if (match) {
await syscall("editor.openUrl", match[1]);
}
}
}
export async function linkNavigate() {
navigate(await syscall("editor.getSyntaxNodeUnderCursor"));
}
export async function clickNavigate(event: ClickEvent) {
if (event.ctrlKey || event.metaKey) {
let syntaxNode = await syscall("editor.getSyntaxNodeAtPos", event.pos);
navigate(syntaxNode);
}
}
export async function pageComplete() {
let prefix = await syscall("editor.matchBefore", "\\[\\[[\\w\\s]*");
if (!prefix) {
return null;
}
let allPages = await syscall("space.listPages");
return {
from: prefix.from + 2,
options: allPages.map((pageMeta: any) => ({
label: pageMeta.name,
type: "page",
})),
};
}
+108
View File
@@ -0,0 +1,108 @@
import { IndexEvent } from "../../webapp/src/app_event";
import { pageLinkRegex } from "../../webapp/src/constant";
import { syscall } from "./lib/syscall";
const wikilinkRegex = new RegExp(pageLinkRegex, "g");
export async function indexLinks({ name, text }: IndexEvent) {
let backLinks: { key: string; value: string }[] = [];
for (let match of text.matchAll(wikilinkRegex)) {
let toPage = match[1];
let pos = match.index!;
backLinks.push({
key: `pl:${toPage}:${pos}`,
value: name,
});
}
console.log("Found", backLinks.length, "wiki link(s)");
await syscall("indexer.batchSet", name, backLinks);
}
export async function deletePage() {
let pageMeta = await syscall("editor.getCurrentPage");
console.log("Navigating to start page");
await syscall("editor.navigate", "start");
console.log("Deleting page from space");
await syscall("space.deletePage", pageMeta.name);
console.log("Reloading page list");
await syscall("space.reloadPageList");
}
export async function renamePage() {
const pageMeta = await syscall("editor.getCurrentPage");
const oldName = pageMeta.name;
console.log("Old name is", oldName);
const newName = await syscall(
"editor.prompt",
`Rename ${oldName} to:`,
oldName
);
if (!newName) {
return;
}
console.log("New name", newName);
let pagesToUpdate = await getBackLinks(oldName);
console.log("All pages containing backlinks", pagesToUpdate);
let text = await syscall("editor.getText");
console.log("Writing new page to space");
await syscall("space.writePage", newName, text);
console.log("Deleting page from space");
await syscall("space.deletePage", oldName);
console.log("Reloading page list");
await syscall("space.reloadPageList");
console.log("Navigating to new page");
await syscall("editor.navigate", newName);
let pageToUpdateSet = new Set<string>();
for (let pageToUpdate of pagesToUpdate) {
pageToUpdateSet.add(pageToUpdate.page);
}
for (let pageToUpdate of pageToUpdateSet) {
console.log("Now going to update links in", pageToUpdate);
let { text } = await syscall("space.readPage", pageToUpdate);
if (!text) {
// Page likely does not exist, but at least we can skip it
continue;
}
let newText = text.replaceAll(`[[${oldName}]]`, `[[${newName}]]`);
if (text !== newText) {
console.log("Changes made, saving...");
await syscall("space.writePage", pageToUpdate, newText);
}
}
}
type BackLink = {
page: string;
pos: number;
};
async function getBackLinks(pageName: string): Promise<BackLink[]> {
let allBackLinks = await syscall(
"indexer.scanPrefixGlobal",
`pl:${pageName}:`
);
let pagesToUpdate: BackLink[] = [];
for (let { key, value } of allBackLinks) {
let keyParts = key.split(":");
pagesToUpdate.push({
page: value,
pos: +keyParts[keyParts.length - 1],
});
}
return pagesToUpdate;
}
export async function showBackLinks() {
const pageMeta = await syscall("editor.getCurrentPage");
let backLinks = await getBackLinks(pageMeta.name);
console.log("Backlinks", backLinks);
}
export async function reindex() {
await syscall("space.reindex");
}
+31
View File
@@ -0,0 +1,31 @@
import { ClickEvent } from "../../webapp/src/app_event.ts";
import { syscall } from "./lib/syscall.ts";
export async function taskToggle(event: ClickEvent) {
let syntaxNode = await syscall("editor.getSyntaxNodeAtPos", event.pos);
if (syntaxNode && syntaxNode.name === "TaskMarker") {
if (syntaxNode.text === "[x]" || syntaxNode.text === "[X]") {
await syscall("editor.dispatch", {
changes: {
from: syntaxNode.from,
to: syntaxNode.to,
insert: "[ ]",
},
selection: {
anchor: event.pos,
},
});
} else {
await syscall("editor.dispatch", {
changes: {
from: syntaxNode.from,
to: syntaxNode.to,
insert: "[x]",
},
selection: {
anchor: event.pos,
},
});
}
}
}
+3
View File
@@ -0,0 +1,3 @@
export default function welcome() {
console.log("Hello world!");
}
+20
View File
@@ -0,0 +1,20 @@
function countWords(str: string): number {
var matches = str.match(/[\w\d\'\'-]+/gi);
return matches ? matches.length : 0;
}
function readingTime(wordCount: number): number {
// 225 is average word reading speed for adults
return Math.ceil(wordCount / 225);
}
import { syscall } from "./lib/syscall.ts";
export async function wordCount({ text }: { text: string }) {
let sysCallText = (await syscall("editor.getText")) as string;
const count = countWords(sysCallText);
console.log("Word count", count);
let syntaxNode = await syscall("editor.getSyntaxNodeUnderCursor");
console.log("Syntax node", syntaxNode);
return count;
}
+22
View File
@@ -0,0 +1,22 @@
{
"name": "plugbox",
"version": "1.0.0",
"type": "module",
"source": "src/bundle.ts",
"main": "dist/bundle.js",
"scripts": {
"build": "parcel build",
"core": "node dist/bundle.js --debug core/core.plugin.json ../webapp/src/generated/core.plugin.json"
},
"dependencies": {
"esbuild": "^0.14.24",
"typescript": ">=3.0.0",
"vm2": "^3.9.9",
"yargs": "^17.3.1"
},
"devDependencies": {
"@types/node": "^17.0.21",
"@types/yargs": "^17.0.9",
"parcel": "^2.3.2"
}
}
+63
View File
@@ -0,0 +1,63 @@
import esbuild from "esbuild";
import { readFile, unlink, writeFile } from "fs/promises";
import path from "path";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { Manifest } from "../../webapp/src/plugins/types";
async function compile(filePath: string, sourceMap: string) {
let tempFile = "out.js";
let js = await esbuild.build({
entryPoints: [filePath],
bundle: true,
format: "iife",
globalName: "mod",
platform: "neutral",
sourcemap: sourceMap ? "inline" : false,
minify: true,
outfile: tempFile,
});
let jsCode = (await readFile(tempFile)).toString();
jsCode = jsCode.replace(/^var mod ?= ?/, "");
await unlink(tempFile);
return jsCode;
}
async function bundle(manifestPath, sourceMaps) {
const rootPath = path.dirname(manifestPath);
const manifest = JSON.parse(
(await readFile(manifestPath)).toString()
) as Manifest;
for (let [name, def] of Object.entries(manifest.functions)) {
let jsFunctionName = def.functionName,
filePath = path.join(rootPath, def.path);
if (filePath.indexOf(":") !== -1) {
[filePath, jsFunctionName] = filePath.split(":");
} else if (!jsFunctionName) {
jsFunctionName = "default";
}
def.code = await compile(filePath, sourceMaps);
def.path = filePath;
def.functionName = jsFunctionName;
}
return manifest;
}
async function run() {
let args = await yargs(hideBin(process.argv))
.option("debug", {
type: "boolean",
})
.parse();
let generatedManifest = await bundle(args._[0], !!args.debug);
writeFile(args._[1] as string, JSON.stringify(generatedManifest, null, 2));
}
run().catch((e) => {
console.error(e);
process.exit(1);
});
+1768
View File
File diff suppressed because it is too large Load Diff