Metabolism: browser fix — the arena stays a plain ArrayBuffer unless a region pool will share it; vite serves cross-origin-isolation headers so the browser can opt into SAB

This commit is contained in:
Dejvino
2026-10-28 15:33:07 +01:00
parent d6e97a2b52
commit cfc0bddb1f
2 changed files with 25 additions and 1 deletions
+9 -1
View File
@@ -209,7 +209,15 @@ export class World {
const fcSide0 = Math.max(16, Math.round(field / 2)); // the layout needs the coarse shape
const spec = layout ?? arenaLayout(field, this.m, B0, fcSide0);
this.layout = spec;
this.arena = sab ?? new SharedArrayBuffer((spec.bytes + 3) & ~3);
// The arena is shared ONLY when a region pool will actually spawn:
// browsers expose SharedArrayBuffer solely under cross-origin
// isolation, and the serial world must never require it.
const wantPool = !bare && workers > 1 && !!workerCtor() &&
typeof SharedArrayBuffer !== 'undefined';
if (!wantPool) workers = 0;
this.arena = sab ?? ((wantPool)
? new SharedArrayBuffer((spec.bytes + 3) & ~3)
: new ArrayBuffer((spec.bytes + 3) & ~3));
{
let off = 0;
for (const it of spec.items) { it.offset = off; off += (it.bytes + 3) & ~3; }
+16
View File
@@ -142,4 +142,20 @@ function songBankPlugin() {
export default defineConfig({
plugins: [songBankPlugin()],
// Cross-origin isolation: browsers expose SharedArrayBuffer only when
// both headers are present. The region pool needs it once the sim runs
// inside a browser worker; the demo is fully same-origin, so requiring
// corp costs nothing here.
server: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
preview: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
});