complete es module wrappers

update manifold to current npm
update csg to use new manifold
remove manifold npm pre install download from static
This commit is contained in:
Stewart Allen 2024-06-29 07:14:20 -04:00
commit e26e57e193
7 changed files with 63 additions and 52 deletions

43
app.js
View file

@ -58,10 +58,15 @@ netdb.create = async function(map = {}) {
return client; return client;
}; };
function wrapdata(path, buf) { // experimental wrapping of esm modules using embedded data urls
function wrap_module(buf, as) {
const base64 = buf.toString('base64');
const path = as.split('.');
const exp = path.pop();
return [ return [
`gapp.register("${path}", [], (root, exports) => {`, `gapp.register("${path.join('.')}", [], (root, exports) => {`,
buf.toString(), `const url = "data:text/javascript;base64,${base64}";`,
`exports({ ["${exp}"]: import(url) });`,
"});" "});"
].join('\n'); ].join('\n');
} }
@ -98,7 +103,7 @@ function init(mod) {
const callstack = []; const callstack = [];
let xxxx = false; let xxxx = false;
function find_refs(cache, path) { function find_refs(cache, path, ismod) {
let rec = refcache[path]; let rec = refcache[path];
if (rec) { if (rec) {
let crec = cache[path]; let crec = cache[path];
@ -121,6 +126,11 @@ function init(mod) {
console.log({missing: full, callstack}); console.log({missing: full, callstack});
throw e; throw e;
} }
// skip interrogating file if it's a module (external compacted)
if (ismod) {
wrap[`src/${path}.js`] = path.replaceAll('/','.');
return;
}
let lines = fs.readFileSync(full) let lines = fs.readFileSync(full)
.toString() .toString()
.split('\n'); .split('\n');
@ -136,6 +146,11 @@ function init(mod) {
arr = rec.deps; arr = rec.deps;
pos = dpos + 7; pos = dpos + 7;
} }
let mpos = line.indexOf('// mod:');
if (mpos >= 0) {
arr = rec.deps;
pos = mpos + 7;
}
if (upos >= 0 && dpos >= 0) { if (upos >= 0 && dpos >= 0) {
console.log(`invalid line: ${line}`); console.log(`invalid line: ${line}`);
process.exit(); process.exit();
@ -143,7 +158,7 @@ function init(mod) {
if (arr && pos >= 0) { if (arr && pos >= 0) {
let path = line.substring(pos).trim().replace(/\./g,'/').trim(); let path = line.substring(pos).trim().replace(/\./g,'/').trim();
addonce(arr, path); addonce(arr, path);
find_refs(cache, path); find_refs(cache, path, mpos >= 0);
} }
} }
// if (xxxx) console.log({path, ...rec}); // if (xxxx) console.log({path, ...rec});
@ -163,7 +178,7 @@ function init(mod) {
return i; return i;
} }
} }
console.log(`not found: ${path}`); console.trace(`not found: ${path}`);
process.exit(); process.exit();
} }
@ -227,7 +242,7 @@ function init(mod) {
} }
find_refs(cache, path); find_refs(cache, path);
} }
if (xxxx) console.log({processing: key, val}); if (xxxx) console.log({ processing: key, val });
let refs = order_refs(cache).filter(p => roots.indexOf(p) < 0); let refs = order_refs(cache).filter(p => roots.indexOf(p) < 0);
// remove paths that are in refs // remove paths that are in refs
let paths = list.filter(p => { let paths = list.filter(p => {
@ -246,8 +261,9 @@ function init(mod) {
let fc = p.charAt(0); let fc = p.charAt(0);
if (fc === '@') return p; if (fc === '@') return p;
if (fc === '#') { if (fc === '#') {
let nupath = `src/${p.substring(1)}.js`; fc = p.split('#');
wrap[nupath] = true; let nupath = `src/${fc[1]}.js`;
wrap[nupath] = fc[1].replaceAll('/','.');
return nupath; return nupath;
} }
return `src/${p}.js`; return `src/${p}.js`;
@ -295,10 +311,10 @@ function init(mod) {
mod.add((req, res, next) => { mod.add((req, res, next) => {
const path = req.gs.path.substring(1); const path = req.gs.path.substring(1);
if (wrap[path]) { if (wrap[path]) {
const data = getCachedFile(path, data => { const data = getCachedFile(path, file => {
console.log({ do_not_min: data }); return fs.readFileSync(file);
return data;
}); });
res.setHeader('Content-Type', 'application/javascript; charset=UTF-8');
return res.end(data); return res.end(data);
} }
next(); next();
@ -459,6 +475,7 @@ const script = {
"&kiri/lang-en" "&kiri/lang-en"
], ],
kiri_work : [ kiri_work : [
// "#ext/manifold2",
"kiri-run/worker", "kiri-run/worker",
"&main/kiri", "&main/kiri",
], ],
@ -757,7 +774,7 @@ function getCachedFile(file, fn) {
} }
if (wrap[file]) { if (wrap[file]) {
cacheData = wrapdata(file, cacheData); cacheData = wrap_module(cacheData, wrap[file]);
} }
cached = { cached = {

14
bin/build-upload Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
target=$1
tag=${2:-latest}
echo "build and release target=$target tag=$tag"
[ -z "$target" ] && echo "missing target" && exit
[ -z "$tag" ] && echo "missing tag" && exit
rm -rf dist && npm run build-${target} && for i in dist/*{exe,dmg,AppImage}; do
if [ -f "$i" ]; then
bn=$(basename $i)
gh release delete-asset ${tag} ${bn} -y
gh release upload ${tag} ${i}
fi
done

View file

@ -29,16 +29,6 @@ async function download(url, filePath) {
async function main() { async function main() {
console.log('npm pre running'); console.log('npm pre running');
await download(
"https://static.grid.space/gapp/manifold.js",
path.join("src", "ext", "manifold.js")
);
await download(
"https://static.grid.space/gapp/manifold.wasm",
path.join("src", "wasm", "manifold.wasm")
);
const links = fs.readFileSync("links.csv") const links = fs.readFileSync("links.csv")
.toString() .toString()
.trim() .trim()
@ -47,32 +37,14 @@ async function main() {
.map(line => line.split(',').map(v => v.trim())); .map(line => line.split(',').map(v => v.trim()));
if (os.platform() === 'win32') if (os.platform() === 'win32')
// convert links to the contents of the files/directories they reference
for (let [link, target] of links) { for (let [link, target] of links) {
const absoluteTarget = path.resolve(path.dirname(link), target); const absoluteTarget = path.resolve(path.dirname(link), target);
// console.log({ link, target, absoluteTarget });
try { try {
// Remove existing link if it exists
// if (fs.existsSync(link)) {
// console.log({ unlink: link });
// fs.unlinkSync(link);
// } else {
// console.log('no file', link);
// }
console.log({ win32_replace: link }); console.log({ win32_replace: link });
await fs.remove(link).catch(error => console.log({ remove_error: error })); await fs.remove(link).catch(error => console.log({ remove_error: error }));
// console.log({ copy: absoluteTarget, to: link });
await fs.copy(absoluteTarget, link, { dereference: true }).catch(error => console.log({ copy_error: error })); await fs.copy(absoluteTarget, link, { dereference: true }).catch(error => console.log({ copy_error: error }));
// const targetStats = fs.lstatSync(absoluteTarget);
// let type = targetStats.isDirectory() ? 'junction' : 'file';
// // Create the symlink
// console.log(`relink: ${link} as ${type}`);
// fs.symlinkSync(absoluteTarget, link, type);
} catch (err) { } catch (err) {
// console.error(`Error creating symlink: ${link} -> ${target}`, err);
console.error(`Error creating symlink: ${link} -> ${absoluteTarget}`, err); console.error(`Error creating symlink: ${link} -> ${absoluteTarget}`, err);
} }
} }

View file

@ -36,6 +36,7 @@
"earcut": "^2.2.3", "earcut": "^2.2.3",
"express-useragent": "^1.0.13", "express-useragent": "^1.0.13",
"jszip": "^3.7.1", "jszip": "^3.7.1",
"manifold-3d": "^2.5.1",
"moment": "^2.29.4", "moment": "^2.29.4",
"serve-static": "^1.14.1", "serve-static": "^1.14.1",
"three": "^0.147.0", "three": "^0.147.0",

1
src/ext/manifold.js Symbolic link
View file

@ -0,0 +1 @@
../../node_modules/manifold-3d/manifold.js

View file

@ -3,14 +3,13 @@
"use strict"; "use strict";
// dep: geo.base // dep: geo.base
// dep: ext.manifold // mod: ext.manifold
gapp.register("geo.csg", [], (root, exports) => { gapp.register("geo.csg", [], (root, exports) => {
const { base } = root; const { base, ext } = root;
const debug = true; const debug = true;
const CSG = { const CSG = {
// accepts 2 or more arguments with threejs vertex position arrays // accepts 2 or more arguments with threejs vertex position arrays
union() { union() {
return CSG.moduleOp('manifold.union', 'union', ...arguments); return CSG.moduleOp('manifold.union', 'union', ...arguments);
@ -33,7 +32,7 @@ const CSG = {
if (args.length < 2) { if (args.length < 2) {
throw "missing one or more meshes"; throw "missing one or more meshes";
} }
const result = Instance[op](...args); const result = Instance.Manifold[op](...args);
const output = result.getMesh(); const output = result.getMesh();
const errors = [ ...args, result ].map(m => m.status().value); const errors = [ ...args, result ].map(m => m.status().value);
for (let m of [ ...args, result ]) { for (let m of [ ...args, result ]) {
@ -46,7 +45,8 @@ const CSG = {
}, },
toPositionArray(mesh) { toPositionArray(mesh) {
let { vertPos, triVerts } = mesh; let { vertProperties, triVerts } = mesh;
let vertPos = vertProperties;
if (vertPos && triVerts) { if (vertPos && triVerts) {
const vertices = new Float32Array(triVerts.length * 3); const vertices = new Float32Array(triVerts.length * 3);
for (let p=0, i=0, l=triVerts.length; i<l; i++) { for (let p=0, i=0, l=triVerts.length; i<l; i++) {
@ -63,7 +63,7 @@ const CSG = {
fromPositionArray(pos) { fromPositionArray(pos) {
const { index, vertices } = indexVertices(pos); const { index, vertices } = indexVertices(pos);
let mesh = new Instance.Mesh({ let mesh = new Instance.Mesh({
vertPos: vertices.toFloat32(), vertProperties: vertices.toFloat32(),
triVerts: index.toUint32() triVerts: index.toUint32()
}); });
return mesh; return mesh;
@ -108,10 +108,15 @@ function indexVertices(pos) {
} }
let Instance; let Instance;
Module().then(Module => {
Module.setup(); ext.manifold.then(mod => {
Instance = Module; mod.default({
CSG.Instance = () => { return Instance }; locateFile() { return "/wasm/manifold.wasm" }
}).then(inst => {
inst.setup();
Instance = inst;
CSG.Instance = () => { return Instance };
});
}); });
gapp.overlay(base, { gapp.overlay(base, {

1
src/wasm/manifold.wasm Symbolic link
View file

@ -0,0 +1 @@
../../node_modules/manifold-3d/manifold.wasm