Tons of progress
This commit is contained in:
@@ -0,0 +1 @@
|
||||
dist
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"deno.enable": true,
|
||||
"deno.unstable": true
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
DENO_BUNDLE=deno run --allow-read --allow-write --unstable bundle.ts --debug
|
||||
build: *
|
||||
mkdir -p dist
|
||||
$(DENO_BUNDLE) core/core.plugin.json dist/core.plugin.json
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import { parse } from "https://deno.land/std@0.121.0/flags/mod.ts";
|
||||
|
||||
// import { mime } from "https://deno.land/x/mimetypes@v1.0.0/mod.ts";
|
||||
//
|
||||
// async function dataEncodeUint8Array(path : string, data: Uint8Array): Promise<string> {
|
||||
// const base64url: string = await new Promise((r) => {
|
||||
// const reader = new FileReader();
|
||||
// reader.onload = () => r(reader.result as string);
|
||||
// reader.readAsDataURL(new Blob([data]))
|
||||
// })
|
||||
// let [meta, content] = base64url.split(';');
|
||||
// let [prefix, mimeType] = meta.split(':');
|
||||
// return `data:${mime.getType(path)};${content}`;
|
||||
// }
|
||||
import * as path from "https://deno.land/std@0.121.0/path/mod.ts";
|
||||
import { Manifest, FunctionDef } from "../webapp/src/plugins/types.ts";
|
||||
|
||||
async function compile(
|
||||
filePath: string,
|
||||
prettyFunctionName: string,
|
||||
jsFunctionName: string,
|
||||
sourceMaps: boolean
|
||||
): Promise<string> {
|
||||
// @ts-ignore for Deno.emit (unstable API)
|
||||
let { files, diagnostics } = await Deno.emit(filePath, {
|
||||
bundle: "classic",
|
||||
check: true,
|
||||
compilerOptions: {
|
||||
lib: ["WebWorker", "ES2020"],
|
||||
inlineSourceMap: sourceMaps,
|
||||
sourceMap: false,
|
||||
},
|
||||
});
|
||||
let bundleSource = files["deno:///bundle.js"];
|
||||
|
||||
if (diagnostics.length > 0) {
|
||||
for (let diagnostic of diagnostics) {
|
||||
if (diagnostic.start) {
|
||||
console.error(
|
||||
`In ${diagnostic.fileName}:${diagnostic.start!.line + 1}: ${
|
||||
diagnostic.messageText
|
||||
}`
|
||||
);
|
||||
} else {
|
||||
console.error(diagnostic);
|
||||
}
|
||||
}
|
||||
throw new Error("Diagnostics");
|
||||
}
|
||||
return `const mod = ${bundleSource}
|
||||
|
||||
self.addEventListener('invoke-function', async e => {
|
||||
try {
|
||||
let result = await mod['${jsFunctionName}'](...e.detail.args);
|
||||
self.dispatchEvent(new CustomEvent('result', {detail: result}));
|
||||
} catch(e) {
|
||||
console.error(\`Error while running ${jsFunctionName}\`, e);
|
||||
self.dispatchEvent(new CustomEvent('app-error', {detail: e.message}));
|
||||
}
|
||||
});
|
||||
`;
|
||||
}
|
||||
|
||||
async function bundle(
|
||||
manifestPath: string,
|
||||
sourceMaps: boolean
|
||||
): Promise<Manifest> {
|
||||
const rootPath = path.dirname(manifestPath);
|
||||
const manifest = JSON.parse(
|
||||
new TextDecoder().decode(await Deno.readFile(manifestPath))
|
||||
) as Manifest;
|
||||
|
||||
for (let [name, def] of Object.entries(manifest.functions) as Array<
|
||||
[string, FunctionDef]
|
||||
>) {
|
||||
let jsFunctionName,
|
||||
filePath = path.join(rootPath, def.path);
|
||||
if (filePath.indexOf(":") !== 0) {
|
||||
[filePath, jsFunctionName] = filePath.split(":");
|
||||
} else {
|
||||
jsFunctionName = "default";
|
||||
}
|
||||
|
||||
def.code = await compile(filePath, name, jsFunctionName, sourceMaps);
|
||||
}
|
||||
return manifest;
|
||||
// let files: { [key: string]: string } = {};
|
||||
// for await (const entry of walk(path, {includeDirs: false})) {
|
||||
// let content = await Deno.readFile(entry.path);
|
||||
// files[entry.path.substring(path.length + 1)] = await dataEncodeUint8Array(entry.path, content);
|
||||
// }
|
||||
// return files;
|
||||
}
|
||||
|
||||
let commandLineArguments = parse(Deno.args, {
|
||||
boolean: true,
|
||||
});
|
||||
|
||||
let [manifestPath, outputPath] = commandLineArguments._ as string[];
|
||||
console.log(`Generating bundle for ${manifestPath} to ${outputPath}`);
|
||||
let b = await bundle(manifestPath, !!commandLineArguments.debug);
|
||||
await Deno.writeFile(
|
||||
outputPath,
|
||||
new TextEncoder().encode(JSON.stringify(b, null, 2))
|
||||
);
|
||||
/*
|
||||
const watcher = Deno.watchFs("test_app");
|
||||
|
||||
for await (const event of watcher) {
|
||||
console.log("Updating bundle...");
|
||||
let b = await bundle("test_app/test.cartridge.json");
|
||||
await Deno.writeFile("test_app.bundle.json", new TextEncoder().encode(JSON.stringify(b, null, 2)));
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"commands": {
|
||||
"Count Words": {
|
||||
"invoke": "word_count_command",
|
||||
"requiredContext": {
|
||||
"text": true
|
||||
}
|
||||
},
|
||||
"Navigate To page": {
|
||||
"invoke": "link_navigate",
|
||||
"key": "Ctrl-Enter",
|
||||
"mac": "Cmd-Enter",
|
||||
"requiredContext": {
|
||||
}
|
||||
},
|
||||
"Insert Current Date": {
|
||||
"invoke": "insert_nice_date"
|
||||
},
|
||||
"Toggle : Heading 1": {
|
||||
"invoke": "toggle_h1",
|
||||
"mac": "Cmd-1",
|
||||
"key": "Ctrl-1"
|
||||
},
|
||||
"Toggle : Heading 2": {
|
||||
"invoke": "toggle_h2",
|
||||
"mac": "Cmd-2",
|
||||
"key": "Ctrl-2"
|
||||
}
|
||||
},
|
||||
"events": {},
|
||||
"functions": {
|
||||
"word_count_command": {
|
||||
"path": "./word_count_command.ts:wordCount"
|
||||
},
|
||||
"link_navigate": {
|
||||
"path": "./link_navigate.ts:linkNavigate"
|
||||
},
|
||||
"insert_nice_date": {
|
||||
"path": "./dates.ts:insertToday"
|
||||
},
|
||||
"toggle_h1": {
|
||||
"path": "./markup.ts:toggleH1"
|
||||
},
|
||||
"toggle_h2": {
|
||||
"path": "./markup.ts:toggleH2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import {syscall} from "./syscall.ts";
|
||||
|
||||
export async function publish(event: string, data?: object) {
|
||||
return await syscall("event.publish", event, data);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export function syscall(name: string, ...args: Array<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,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { syscall } from "./lib/syscall.ts";
|
||||
|
||||
export async function linkNavigate({ text }: { text: string }) {
|
||||
let syntaxNode = await syscall("editor.getSyntaxNodeUnderCursor");
|
||||
if (syntaxNode && syntaxNode.name === "WikiLinkPage") {
|
||||
await syscall("editor.navigate", syntaxNode.text);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user