Skip to content

Commit

Permalink
Replace rollup w/ webpack for the web worker
Browse files Browse the repository at this point in the history
  • Loading branch information
ochafik committed Dec 31, 2024
1 parent a4a33d2 commit a0015af
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 188 deletions.
25 changes: 0 additions & 25 deletions openscad-worker.rollup.config.js

This file was deleted.

10 changes: 3 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
},
"scripts": {
"test:e2e": "jest",
"start:development": "concurrently 'npx webpack serve --mode=development' 'NODE_ENV=development npx rollup --config openscad-worker.rollup.config.js --watch'",
"start:development": "npx webpack serve --mode=development",
"start:production": "NODE_ENV=production PUBLIC_URL=http://localhost:3000/dist/ npm run build && npx serve",
"start": "npm run start:development",
"build": "NODE_ENV=production npx rollup --config openscad-worker.rollup.config.js && webpack --mode=production"
"build": "NODE_ENV=production webpack --mode=production"
},
"eslintConfig": {
"extends": [
Expand All @@ -52,8 +52,6 @@
"node": ">=18.12.0"
},
"devDependencies": {
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-typescript": "^11.1.6",
"@types/chroma-js": "^2.4.5",
"@types/debug": "^4.1.12",
"@types/filesystem": "^0.0.36",
Expand All @@ -62,15 +60,13 @@
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@types/uzip": "^0.20201231.2",
"concurrently": "^7.6.0",
"@types/web": "^0.0.140",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^7.1.2",
"jest": "^29.7.0",
"jest-puppeteer": "^11.0.0",
"livereload": "^0.9.3",
"puppeteer": "^23.11.1",
"rollup": "^2.79.2",
"rollup-plugin-typescript2": "^0.36.0",
"serve": "^14.2.4",
"style-loader": "^4.0.0",
"ts-loader": "^9.5.1",
Expand Down
32 changes: 24 additions & 8 deletions src/fs/BrowserFS.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,29 @@ declare interface FS {

declare interface EmscriptenFS extends FS {}

declare type BrowserFSInterface = {
BFSRequire: (name: string) => any,
declare interface BrowserFSInterface {
EmscriptenFS: any;
BFSRequire: (module: string) => any;
install: (obj: any) => void;
configure: (config: any, cb: (e?: Error) => void) => void;
FileSystem: {
InMemory: any;
ZipFS: any;
MountableFileSystem: any;
LocalStorage: any;
XmlHttpRequest: any;
};
Buffer: {
from: (data: any, encoding?: string) => any;
alloc: (size: number) => any;
};
initialize: (config: any) => Promise<void>;
WorkerFS?: any;
}

declare var BrowserFS: BrowserFSInterface;

install: (windowOrSelf: Window) => void,
configure: (options: any, callback: (e?: any) => void) => void,
declare module 'browserfs' {
export = BrowserFS;
}

EmscriptenFS: {
new(fs: FS, path: string, errnoCodes: object): EmscriptenFS
}
};
4 changes: 2 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ window.addEventListener('load', async () => {

registerCustomAppHeightCSSProperty();

const fs = await createEditorFS({prefix: '/libraries/', allowPersistence: isInStandaloneMode});
const fs = await createEditorFS({prefix: '/libraries/', allowPersistence: isInStandaloneMode()});

await registerOpenSCADLanguage(fs, '/', zipArchives);

let statePersister: StatePersister;
let persistedState: State | null = null;

if (isInStandaloneMode) {
if (isInStandaloneMode()) {
const fs: FS = BrowserFS.BFSRequire('fs')
try {
const data = JSON.parse(new TextDecoder("utf-8").decode(fs.readFileSync('/state.json')));
Expand Down
31 changes: 11 additions & 20 deletions src/runner/openscad-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,30 @@ import { MergedOutputs } from "./openscad-worker";
import { AbortablePromise } from "../utils";
import { Source } from "../state/app-state";

export function createWasmMemory({maximumMegabytes, maximumBytes}: {maximumMegabytes: number, maximumBytes: number}) {
const pageSize = 64 * 1024; // 64KB
if (!maximumBytes) {
maximumBytes = maximumMegabytes * 1024 * 1024;
}
return new WebAssembly.Memory({
initial: Math.floor(maximumBytes / 2 / pageSize),
maximum: Math.floor(maximumBytes / pageSize),
shared: true,
});
}

// Output is {outputs: [name, content][], mergedOutputs: [{(stderr|stdout|error)?: string}], exitCode: number}
export type OpenSCADInvocation = {
wasmMemory?: WebAssembly.Memory,
mountArchives: boolean,
inputs?: Source[],
args: string[],
outputPaths?: string[],
}

export type OpenSCADInvocationResults = {
exitCode?: number,
error?: string,
outputs?: [string, string][],
mergedOutputs: MergedOutputs,
elapsedMillis: number,
};

export type ProcessStreams = {stderr: string} | {stdout: string}
export type OpenSCADInvocationCallback = {result: OpenSCADInvocationResults} | ProcessStreams;

export function spawnOpenSCAD(invocation: OpenSCADInvocation, streamsCallback: (ps: ProcessStreams) => void): AbortablePromise<OpenSCADInvocationResults> {
var worker: Worker | null;
var rejection: (err: any) => void;
export function spawnOpenSCAD(
invocation: OpenSCADInvocation,
streamsCallback: (ps: ProcessStreams) => void
): AbortablePromise<OpenSCADInvocationResults> {
let worker: Worker | null;
let rejection: (err: any) => void;

function terminate() {
if (!worker) {
Expand All @@ -46,10 +37,10 @@ export function spawnOpenSCAD(invocation: OpenSCADInvocation, streamsCallback: (
worker = null;
}

return AbortablePromise<OpenSCADInvocationResults>((resolve, reject) => {
worker = new Worker('./openscad-worker.js');
return AbortablePromise<OpenSCADInvocationResults>((resolve: (result: OpenSCADInvocationResults) => void, reject: (error: any) => void) => {
worker = new Worker('./openscad-worker.js');//, { type: 'module' });
rejection = reject;
worker.onmessage = (e: {data: OpenSCADInvocationCallback}) => {
worker.onmessage = (e: MessageEvent<OpenSCADInvocationCallback>) => {
if ('result' in e.data) {
resolve(e.data.result);
terminate();
Expand Down
26 changes: 10 additions & 16 deletions src/runner/openscad-worker.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.

/// <reference lib="webworker" />
import OpenSCAD from "../wasm/openscad.js";

import { createEditorFS, getParentDir, symlinkLibraries } from "../fs/filesystem";
import { OpenSCADInvocation, OpenSCADInvocationCallback, OpenSCADInvocationResults } from "./openscad-runner";
import { deployedArchiveNames, zipArchives } from "../fs/zip-archives";
import { fetchSource } from "../utils.js";
declare var BrowserFS: BrowserFSInterface
import { createEditorFS, getParentDir, symlinkLibraries } from "../fs/filesystem.ts";
import { OpenSCADInvocation, OpenSCADInvocationCallback, OpenSCADInvocationResults } from "./openscad-runner.ts";
import { deployedArchiveNames, zipArchives } from "../fs/zip-archives.ts";
import { fetchSource } from "../utils.ts";

importScripts("browserfs.min.js");

declare const self: DedicatedWorkerGlobalScope;

export type MergedOutputs = {stdout?: string, stderr?: string, error?: string}[];

function callback(payload: OpenSCADInvocationCallback) {
postMessage(payload);
self.postMessage(payload);
}

addEventListener('message', async (e) => {

self.addEventListener('message', async (e: MessageEvent<OpenSCADInvocation>) => {
const {
mountArchives,
inputs,
args,
outputPaths,
wasmMemory,
} = e.data as OpenSCADInvocation;
} = e.data;

const mergedOutputs: MergedOutputs = [];
let instance: any;
const start = performance.now();
try {
instance = await OpenSCAD({
wasmMemory,
buffer: wasmMemory && wasmMemory.buffer,
noInitialRun: true,
'print': (text: string) => {
console.debug('stdout: ' + text);
Expand All @@ -44,9 +42,6 @@ addEventListener('message', async (e) => {
callback({stderr: text})
mergedOutputs.push({ stderr: text })
},
'ENV': {
'OPENSCADPATH': '/libraries',
},
});

if (mountArchives) {
Expand Down Expand Up @@ -140,7 +135,6 @@ addEventListener('message', async (e) => {
}

console.debug(result);

callback({result});
} catch (e) {
const end = performance.now();
Expand Down
6 changes: 3 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ export function registerCustomAppHeightCSSProperty() {
}

// In PWA mode, persist files in LocalStorage instead of the hash fragment.
export const isInStandaloneMode =
// true
Boolean(('standalone' in window.navigator) && (window.navigator.standalone));
export function isInStandaloneMode() {
return Boolean(('standalone' in window.navigator) && (window.navigator.standalone));
}

export function downloadUrl(url: string, filename: string) {
const link = document.createElement('a');
Expand Down
18 changes: 11 additions & 7 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
"dom",
"dom.iterable",
"ES2022",
"WebWorker",
"WebWorker"
],
"rootDir": "src",
// "outDir": "js",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
Expand All @@ -17,17 +16,22 @@
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
// "noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"noEmit": true,
"allowImportingTsExtensions": true,
"declaration": true,
"baseUrl": "src",
"paths": {
"*": ["*"]
}
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.js",
// "public"
"src/**/*.js"
],
"exclude": [
"node_modules",
Expand Down
Loading

0 comments on commit a0015af

Please sign in to comment.