diff --git a/app.js b/app.js index 4c27cc73..f5e629f4 100644 --- a/app.js +++ b/app.js @@ -122,6 +122,7 @@ function init(mod) { mod.add(serveWasm); mod.add(serveCode); mod.add(fullpath({ + "/boot" : redir((pre??"") + "/boot/", 301), "/kiri" : redir((pre??"") + "/kiri/", 301), "/mesh" : redir((pre??"") + "/mesh/", 301), "/meta" : redir((pre??"") + "/meta/", 301), @@ -147,6 +148,7 @@ function init(mod) { mod.static("/mesh/", "web/mesh"); mod.static("/moto/", "web/moto"); mod.static("/kiri/", "web/kiri"); + mod.static("/boot/", "web/boot"); // module loader function load_modules(root, force) { diff --git a/bin/bundle.config.json b/bin/bundle.config.json new file mode 100644 index 00000000..655fa67e --- /dev/null +++ b/bin/bundle.config.json @@ -0,0 +1,11 @@ +{ + "outputs": { + "bundle": "./web/kiri/bundle.bin" + }, + "inputs": [ + { "root": "./web", "prefix": "" }, + { "root": "./src", "prefix": "lib" }, + { "root": "./src/wasm", "prefix": "wasm" }, + { "root": "./src/wasm", "prefix": "lib/kiri/wasm" } + ] +} diff --git a/bin/bundler.mjs b/bin/bundler.mjs new file mode 100644 index 00000000..199f4d45 --- /dev/null +++ b/bin/bundler.mjs @@ -0,0 +1,80 @@ +import fs from 'fs'; +import path from 'path'; +import { Buffer } from 'buffer'; + +const cfg = JSON.parse(fs.readFileSync(process.argv[2] || './bundle.config.json', 'utf8')); + +// --- recursive directory walker (follows symlinks safely) --- +function* walk(dir, seen = new Set()) { + const real = fs.realpathSync(dir); + if (seen.has(real)) { + return; + } + seen.add(real); + + for (const name of fs.readdirSync(dir)) { + const p = path.join(dir, name); + let st; + try { st = fs.statSync(p); } catch { continue; } + if (st.isDirectory()) yield* walk(p, seen); + else yield p; + } +} + +// --- collect all files according to config --- +let entries = []; +for (const input of cfg.inputs) { + const root = input.root; + const prefix = input.prefix || ''; + for (const file of walk(root)) { + const rel = path.relative(root, file).replace(/\\/g, '/'); + const virt = prefix ? `${prefix}/${rel}` : rel; + entries.push({ file, virt }); + } +} + +// --- build header and data --- +const dataParts = []; +const entryMeta = []; +let offset = 0; + +for (const { file, virt } of entries) { + const data = fs.readFileSync(file); + entryMeta.push({ virt, offset, length: data.length }); + dataParts.push(data); + offset += data.length; +} + +// temporary header without offsets to measure total size +let tempHeaderParts = []; +for (const { virt, offset, length } of entryMeta) { + const name = Buffer.from(virt, 'utf8'); + const nlen = Buffer.alloc(2); nlen.writeUInt16LE(name.length); + const offb = Buffer.alloc(4); offb.writeUInt32LE(0); // placeholder + const lenb = Buffer.alloc(4); lenb.writeUInt32LE(length); + tempHeaderParts.push(nlen, name, offb, lenb); +} +const count = Buffer.alloc(4); count.writeUInt32LE(entries.length); +const tempHeader = Buffer.concat([count, ...tempHeaderParts]); +const headerSize = tempHeader.length; // true data offset base + +// now rebuild header with correct absolute offsets +let headerParts = []; +for (const { virt, offset, length } of entryMeta) { + const name = Buffer.from(virt, 'utf8'); + const nlen = Buffer.alloc(2); nlen.writeUInt16LE(name.length); + const offb = Buffer.alloc(4); offb.writeUInt32LE(headerSize + offset); + const lenb = Buffer.alloc(4); lenb.writeUInt32LE(length); + headerParts.push(nlen, name, offb, lenb); + console.log(virt); +} + +const header = Buffer.concat([count, ...headerParts]); +const full = Buffer.concat([header, ...dataParts]); + +// --- write final bundle --- +const outPath = cfg.outputs.bundle || './bundle.bin'; +fs.mkdirSync(path.dirname(outPath), { recursive: true }); +fs.writeFileSync(outPath, full); // ⚡ write raw binary + +console.log(`✅ Bundled ${entries.length} files → ${outPath} (${full.length} bytes)`); diff --git a/src/main/service.js b/src/main/service.js index 6d8af693..80db6047 100644 --- a/src/main/service.js +++ b/src/main/service.js @@ -11,8 +11,9 @@ async function start_service_worker() { debug('service worker registration'); try { - // const reg = await navigator.serviceWorker.register("/src/moto/service.js?013", { scope: "/" }); - const reg = await navigator.serviceWorker.register("/code/service.js?"+version, { scope: "/" }); + const reg = await navigator + .serviceWorker + .register(`/code/service.js?${version}`, { scope: "/" }); if (reg.installing) { debug('service worker installing'); } else if (reg.waiting) { @@ -31,4 +32,6 @@ async function start_service_worker() { } } -if (service_worker && self.enable_service) start_service_worker(); +if (service_worker && self.enable_service) { + start_service_worker(); +}