diff --git a/bun.lockb b/bun.lockb index 1d2ea10..6677402 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 0588ad5..48043ae 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "dependencies": { "@imagemagick/magick-wasm": "^0.0.31", - "lucide-svelte": "^0.456.0" + "lucide-svelte": "^0.456.0", + "wasm-vips": "^0.0.11" } } diff --git a/src/app.html b/src/app.html index d086c20..77a5ff5 100644 --- a/src/app.html +++ b/src/app.html @@ -4,7 +4,6 @@ - %sveltekit.head% diff --git a/src/lib/components/visual/Uploader.svelte b/src/lib/components/visual/Uploader.svelte new file mode 100644 index 0000000..3d56ad2 --- /dev/null +++ b/src/lib/components/visual/Uploader.svelte @@ -0,0 +1,4 @@ + + + diff --git a/src/lib/converters/converter.ts b/src/lib/converters/converter.ts new file mode 100644 index 0000000..237db11 --- /dev/null +++ b/src/lib/converters/converter.ts @@ -0,0 +1,9 @@ +import type { IFile } from "$lib/types"; + +export class Converter { + public supportedFormats: string[] = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public async convert(input: IFile, output: IFile): Promise { + throw new Error("Not implemented"); + } +} diff --git a/src/lib/converters/index.svelte.ts b/src/lib/converters/index.svelte.ts new file mode 100644 index 0000000..f593609 --- /dev/null +++ b/src/lib/converters/index.svelte.ts @@ -0,0 +1,15 @@ +import Vips from "wasm-vips"; + +class Converters { + public vips = $state(null!); + public loaded = $derived(this.vips !== null); +} + +export const converters = new Converters(); + +// Vips().then((vips) => { +// converters.vips = vips; +// }); + +// the above *does* work but it blocks the ui thread whilst wasm is loading +// we can use a web worker to remedy this, see +layout.ts for details diff --git a/src/lib/converters/vips.ts b/src/lib/converters/vips.ts new file mode 100644 index 0000000..1a46ee2 --- /dev/null +++ b/src/lib/converters/vips.ts @@ -0,0 +1,9 @@ +import type { IFile } from "$lib/types"; +import { Converter } from "./converter"; + +export class VipsConverter extends Converter { + public supportedFormats = [""]; + public convert(input: IFile, output: IFile): Promise { + throw new Error("Not implemented"); + } +} diff --git a/src/lib/index.ts b/src/lib/index.ts deleted file mode 100644 index 856f2b6..0000000 --- a/src/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -// place files you want to import through the `$lib` alias in this folder. diff --git a/src/lib/types/file.ts b/src/lib/types/file.ts new file mode 100644 index 0000000..fe42fc0 --- /dev/null +++ b/src/lib/types/file.ts @@ -0,0 +1,5 @@ +export interface IFile { + name: string; + extension: string; + buffer: ArrayBuffer; +} diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts new file mode 100644 index 0000000..375123f --- /dev/null +++ b/src/lib/types/index.ts @@ -0,0 +1 @@ +export * from "./file"; diff --git a/src/lib/workers/vips.ts b/src/lib/workers/vips.ts new file mode 100644 index 0000000..8e76e12 --- /dev/null +++ b/src/lib/workers/vips.ts @@ -0,0 +1,9 @@ +import Vips from "wasm-vips"; + +Vips() + .then((vips) => { + postMessage({ type: "success", vips }); + }) + .catch((error) => { + postMessage({ type: "error", error }); + }); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7be3ce4..fe4774e 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,6 +1,7 @@ -{@render children()} +{@render children()} \ No newline at end of file diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 25a8fed..b10c57d 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1,5 +1,10 @@ -import { init } from "./util/magick"; +import { browser } from "$app/environment"; +import VipsWorker from "$lib/workers/vips?worker"; -export async function load({ fetch }) { - await init(fetch); -} +export const load = () => { + if (!browser) return; + const worker = new VipsWorker(); + worker.onmessage = (e) => { + console.log(e.data); + }; +}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index e69de29..c8bb4bc 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/routes/util/magick.ts b/src/routes/util/magick.ts deleted file mode 100644 index c2a4b39..0000000 --- a/src/routes/util/magick.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { initializeImageMagick } from "@imagemagick/magick-wasm"; - -export let initialized = false; - -export const init = async ( - fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise, -) => { - if (initialized) return; - const wasmBytes = await fetch("/magick.wasm").then((res) => - res.arrayBuffer(), - ); - await initializeImageMagick(wasmBytes); - initialized = true; -}; diff --git a/vite.config.ts b/vite.config.ts index bbf8c7d..cfe6112 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,24 @@ -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; export default defineConfig({ - plugins: [sveltekit()] + plugins: [ + sveltekit(), + { + name: "vips-request-middleware", + configureServer(server) { + server.middlewares.use((req, res, next) => { + res.setHeader( + "Cross-Origin-Embedder-Policy", + "require-corp", + ); + res.setHeader("Cross-Origin-Opener-Policy", "same-origin"); + next(); + }); + }, + }, + ], + optimizeDeps: { + exclude: ["wasm-vips"], + }, });