mirror of
https://github.com/mii443/obsidian-typst.git
synced 2025-08-22 16:15:34 +00:00
Improve package loading times
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,3 +25,5 @@ data.json
|
|||||||
# Added by cargo
|
# Added by cargo
|
||||||
|
|
||||||
target
|
target
|
||||||
|
|
||||||
|
*.wasm
|
@ -12,36 +12,6 @@ if you want to view the source, please visit the github repository of this plugi
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const prod = (process.argv[2] === "production");
|
const prod = (process.argv[2] === "production");
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
|
|
||||||
let wasmPlugin = {
|
|
||||||
name: 'wasm',
|
|
||||||
setup(build) {
|
|
||||||
// let path = require('path')
|
|
||||||
// let fs = require('fs')
|
|
||||||
|
|
||||||
// Resolve ".wasm" files to a path with a namespace
|
|
||||||
build.onResolve({ filter: /\.wasm$/ }, args => {
|
|
||||||
if (args.resolveDir === '') {
|
|
||||||
return // Ignore unresolvable paths
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
path: path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path),
|
|
||||||
namespace: 'wasm-binary',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// Virtual modules in the "wasm-binary" namespace contain the
|
|
||||||
// actual bytes of the WebAssembly file. This uses esbuild's
|
|
||||||
// built-in "binary" loader instead of manually embedding the
|
|
||||||
// binary data inside JavaScript code ourselves.
|
|
||||||
build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async (args) => ({
|
|
||||||
contents: await fs.promises.readFile(args.path),
|
|
||||||
loader: 'binary',
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const context = await esbuild.context({
|
const context = await esbuild.context({
|
||||||
banner: {
|
banner: {
|
||||||
@ -70,8 +40,11 @@ const context = await esbuild.context({
|
|||||||
sourcemap: prod ? false : "inline",
|
sourcemap: prod ? false : "inline",
|
||||||
treeShaking: true,
|
treeShaking: true,
|
||||||
outfile: "main.js",
|
outfile: "main.js",
|
||||||
|
define: {
|
||||||
|
PLUGIN_VERSION: JSON.stringify(process.env.npm_package_version)
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
inlineWorkerPlugin({ format: "cjs", target: "es2018", plugins: [wasmPlugin] })
|
inlineWorkerPlugin({ format: "cjs", target: "es2018" })
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
15
package-lock.json
generated
15
package-lock.json
generated
@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-typst-plugin",
|
"name": "obsidian-typst-plugin",
|
||||||
"version": "0.5.1",
|
"version": "0.8alpha",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-typst-plugin",
|
"name": "obsidian-typst-plugin",
|
||||||
"version": "0.5.1",
|
"version": "0.8alpha",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@capacitor/core": "^5.5.1",
|
||||||
"obsidian": "latest",
|
"obsidian": "latest",
|
||||||
"obsidian-typst": "file:pkg",
|
"obsidian-typst": "file:pkg",
|
||||||
"svgo": "^3.0.2",
|
"svgo": "^3.0.2",
|
||||||
@ -34,6 +35,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@capacitor/core": {
|
||||||
|
"version": "5.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.5.1.tgz",
|
||||||
|
"integrity": "sha512-VG6Iv8Q7ZAbvjodxpvjcSe0jfxUwZXnvjbi93ehuJ6eYP8U926qLSXyrT/DToZq+F6v/HyGyVgn3mrE/9jW2Tg==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@codemirror/state": {
|
"node_modules/@codemirror/state": {
|
||||||
"version": "6.2.1",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz",
|
||||||
@ -2502,7 +2511,7 @@
|
|||||||
},
|
},
|
||||||
"pkg": {
|
"pkg": {
|
||||||
"name": "obsidian-typst",
|
"name": "obsidian-typst",
|
||||||
"version": "0.5.1"
|
"version": "0.7.1"
|
||||||
},
|
},
|
||||||
"pkg/pkg": {
|
"pkg/pkg": {
|
||||||
"extraneous": true
|
"extraneous": true
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-typst-plugin",
|
"name": "obsidian-typst-plugin",
|
||||||
"version": "0.7.1",
|
"version": "0.8alpha",
|
||||||
"description": "Renders `typst` code blocks to images with Typst.",
|
"description": "Renders `typst` code blocks to images with Typst.",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -25,6 +25,7 @@
|
|||||||
"typescript": "^5.1"
|
"typescript": "^5.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@capacitor/core": "^5.5.1",
|
||||||
"obsidian": "latest",
|
"obsidian": "latest",
|
||||||
"obsidian-typst": "file:pkg",
|
"obsidian-typst": "file:pkg",
|
||||||
"svgo": "^3.0.2",
|
"svgo": "^3.0.2",
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import wasmBin from '../pkg/obsidian_typst_bg.wasm'
|
// import wasmBin from '../pkg/obsidian_typst_bg.wasm'
|
||||||
import * as typst from '../pkg'
|
import typstInit, * as typst from '../pkg'
|
||||||
|
|
||||||
|
|
||||||
import { CompileImageCommand, CompileSvgCommand } from "src/types";
|
import { CompileImageCommand, CompileSvgCommand } from "src/types";
|
||||||
|
|
||||||
typst.initSync(wasmBin);
|
// typst.initSync(wasmBin);
|
||||||
|
|
||||||
let canUseSharedArrayBuffer = new Boolean(false);
|
let canUseSharedArrayBuffer = new Boolean(false);
|
||||||
|
|
||||||
@ -27,11 +27,20 @@ function requestData(path: string): string {
|
|||||||
throw buffer[0]
|
throw buffer[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
const compiler = new typst.SystemWorld("", requestData)
|
let compiler: typst.SystemWorld; //= new typst.SystemWorld("", requestData)
|
||||||
|
|
||||||
onmessage = (ev: MessageEvent<CompileImageCommand | CompileSvgCommand | true>) => {
|
// Receive data from main thread
|
||||||
|
// `true` means a sharedarraybuffer can be used
|
||||||
|
// `Array` is a list of fonts to be added to the compiler
|
||||||
|
// `string` the url to the web assembly binary data
|
||||||
|
onmessage = (ev: MessageEvent<CompileImageCommand | CompileSvgCommand | true | string>) => {
|
||||||
if (ev.data == true) {
|
if (ev.data == true) {
|
||||||
canUseSharedArrayBuffer = ev.data
|
canUseSharedArrayBuffer = ev.data
|
||||||
|
} else if (typeof ev.data == "string") {
|
||||||
|
typstInit(ev.data).then(_ => {
|
||||||
|
compiler = new typst.SystemWorld("", requestData)
|
||||||
|
console.log("Typst web assembly loaded!");
|
||||||
|
})
|
||||||
} else if (ev.data instanceof Array) {
|
} else if (ev.data instanceof Array) {
|
||||||
ev.data.forEach(font => compiler.add_font(new Uint8Array(font)))
|
ev.data.forEach(font => compiler.add_font(new Uint8Array(font)))
|
||||||
} else if ("format" in ev.data) {
|
} else if ("format" in ev.data) {
|
||||||
@ -41,8 +50,6 @@ onmessage = (ev: MessageEvent<CompileImageCommand | CompileSvgCommand | true>) =
|
|||||||
} else if (ev.data.format == "svg") {
|
} else if (ev.data.format == "svg") {
|
||||||
postMessage(compiler.compile_svg(ev.data.source, ev.data.path))
|
postMessage(compiler.compile_svg(ev.data.source, ev.data.path))
|
||||||
}
|
}
|
||||||
|
|
||||||
// postMessage(compile(ev.data))
|
|
||||||
} else {
|
} else {
|
||||||
throw ev;
|
throw ev;
|
||||||
}
|
}
|
||||||
|
55
src/main.ts
55
src/main.ts
@ -1,5 +1,7 @@
|
|||||||
import { App, renderMath, HexString, Platform, Plugin, PluginSettingTab, Setting, loadMathJax, normalizePath } from 'obsidian';
|
import { App, renderMath, HexString, Platform, Plugin, PluginSettingTab, Setting, loadMathJax, normalizePath, Notice, requestUrl } from 'obsidian';
|
||||||
|
import { CapacitorHttp } from '@capacitor/core';
|
||||||
|
|
||||||
|
declare const PLUGIN_VERSION: string;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import CompilerWorker from "./compiler.worker.ts"
|
import CompilerWorker from "./compiler.worker.ts"
|
||||||
@ -19,7 +21,8 @@ interface TypstPluginSettings {
|
|||||||
shared: string,
|
shared: string,
|
||||||
math: string,
|
math: string,
|
||||||
code: string,
|
code: string,
|
||||||
}
|
},
|
||||||
|
plugin_version: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SETTINGS: TypstPluginSettings = {
|
const DEFAULT_SETTINGS: TypstPluginSettings = {
|
||||||
@ -34,7 +37,8 @@ const DEFAULT_SETTINGS: TypstPluginSettings = {
|
|||||||
shared: "#set text(fill: white, size: SIZE)\n#set page(width: WIDTH, height: HEIGHT)",
|
shared: "#set text(fill: white, size: SIZE)\n#set page(width: WIDTH, height: HEIGHT)",
|
||||||
math: "#set page(margin: 0pt)\n#set align(horizon)",
|
math: "#set page(margin: 0pt)\n#set align(horizon)",
|
||||||
code: "#set page(margin: (y: 1em, x: 0pt))"
|
code: "#set page(margin: (y: 1em, x: 0pt))"
|
||||||
}
|
},
|
||||||
|
plugin_version: PLUGIN_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TypstPlugin extends Plugin {
|
export default class TypstPlugin extends Plugin {
|
||||||
@ -47,11 +51,35 @@ export default class TypstPlugin extends Plugin {
|
|||||||
prevCanvasHeight: number = 0;
|
prevCanvasHeight: number = 0;
|
||||||
textEncoder: TextEncoder
|
textEncoder: TextEncoder
|
||||||
fs: any;
|
fs: any;
|
||||||
|
wasmPath = ".obsidian/plugins/typst/obsidian_typst_compiler.wasm"
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
|
console.log("loading Typst Renderer");
|
||||||
|
|
||||||
this.textEncoder = new TextEncoder()
|
this.textEncoder = new TextEncoder()
|
||||||
await this.loadSettings()
|
await this.loadSettings()
|
||||||
|
|
||||||
this.compilerWorker = (new CompilerWorker() as Worker);
|
this.compilerWorker = (new CompilerWorker() as Worker);
|
||||||
|
|
||||||
|
if (!await this.app.vault.adapter.exists(this.wasmPath) || this.settings.plugin_version != PLUGIN_VERSION) {
|
||||||
|
new Notice("Typst Renderer: Downloading required web assembly component!", 5000);
|
||||||
|
try {
|
||||||
|
await this.fetchWasm()
|
||||||
|
new Notice("Typst Renderer: Web assembly component downloaded!", 5000)
|
||||||
|
} catch (error) {
|
||||||
|
new Notice("Typst Renderer: Failed to fetch component: " + error, 0)
|
||||||
|
console.error("Typst Renderer: Failed to fetch component: " + error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.compilerWorker.postMessage(
|
||||||
|
URL.createObjectURL(
|
||||||
|
new Blob(
|
||||||
|
[await this.app.vault.adapter.readBinary(this.wasmPath)],
|
||||||
|
{ type: "application/wasm" }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (!Platform.isMobileApp) {
|
if (!Platform.isMobileApp) {
|
||||||
this.compilerWorker.postMessage(true);
|
this.compilerWorker.postMessage(true);
|
||||||
this.fs = require("fs")
|
this.fs = require("fs")
|
||||||
@ -97,6 +125,26 @@ export default class TypstPlugin extends Plugin {
|
|||||||
console.log("loaded Typst Renderer");
|
console.log("loaded Typst Renderer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchWasm() {
|
||||||
|
let response
|
||||||
|
let data
|
||||||
|
response = requestUrl(`https://api.github.com/repos/fenjalien/obsidian-typst/releases/tags/${PLUGIN_VERSION}`)
|
||||||
|
data = await response.json
|
||||||
|
let asset = data.assets.find((a: any) => a.name == "obsidian_typst_compiler.wasm")
|
||||||
|
if (asset == undefined) {
|
||||||
|
throw "Could not find the correct file!"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requestUrl({url: asset.url, headers: {"Accept": "application/octet-stream"}})
|
||||||
|
data = await response.arrayBuffer
|
||||||
|
await this.app.vault.adapter.writeBinary(
|
||||||
|
this.wasmPath,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
|
||||||
|
this.settings.plugin_version = PLUGIN_VERSION
|
||||||
|
await this.saveSettings()
|
||||||
|
}
|
||||||
|
|
||||||
async compileToTypst(path: string, source: string, size: number, display: boolean): Promise<ImageData> {
|
async compileToTypst(path: string, source: string, size: number, display: boolean): Promise<ImageData> {
|
||||||
return await navigator.locks.request("typst renderer compiler", async (lock) => {
|
return await navigator.locks.request("typst renderer compiler", async (lock) => {
|
||||||
@ -282,6 +330,7 @@ export default class TypstPlugin extends Plugin {
|
|||||||
async saveSettings() {
|
async saveSettings() {
|
||||||
await this.saveData(this.settings);
|
await this.saveData(this.settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypstSettingTab extends PluginSettingTab {
|
class TypstSettingTab extends PluginSettingTab {
|
||||||
|
Reference in New Issue
Block a user