diff --git a/api/shapes.js b/api/shapes.js index f567e1e5..5ff50103 100644 --- a/api/shapes.js +++ b/api/shapes.js @@ -45,6 +45,8 @@ async function getManifold() { return manifoldInitPromise; } +export { getManifold }; + export function setFlockReference(ref) { flock = ref; } diff --git a/docs/CSP_POLICY.md b/docs/CSP_POLICY.md index 063ea864..b886b51e 100644 --- a/docs/CSP_POLICY.md +++ b/docs/CSP_POLICY.md @@ -10,8 +10,8 @@ Content Security Policy (CSP) is defined in two places: Core flows tested (app load, Blockly interaction, run code in sandbox, project export/import trigger, analytics path) observed these runtime source origins: - **document / stylesheet / image / font / xhr**: `self` (`http://127.0.0.1:4173` in local smoke run) -- **script**: `self`, `https://www.googletagmanager.com`, `https://unpkg.com` -- **fetch / connect**: `self`, `https://www.google-analytics.com`, `https://unpkg.com` +- **script**: `self`, `https://www.googletagmanager.com` +- **fetch / connect**: `self`, `https://www.google-analytics.com` ## Why each non-self origin is required @@ -23,9 +23,6 @@ Core flows tested (app load, Blockly interaction, run code in sandbox, project e - Optional Google Analytics transport endpoint used by some environments. - `https://region1.google-analytics.com` - Regional Google Analytics endpoint used by some environments. -- `https://unpkg.com` - - Used by `manifold-3d` runtime assets (`manifold.js` / `manifold.wasm`) in browser execution. - ## Current CSP Header policy (authoritative): @@ -35,11 +32,11 @@ default-src 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; -script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval' https://www.googletagmanager.com https://unpkg.com; +script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://www.google-analytics.com https://www.googletagmanager.com; font-src 'self' data:; -connect-src 'self' https://www.googletagmanager.com https://www.google-analytics.com https://region1.google-analytics.com https://stats.g.doubleclick.net https://unpkg.com; +connect-src 'self' https://www.googletagmanager.com https://www.google-analytics.com https://region1.google-analytics.com https://stats.g.doubleclick.net; media-src 'self' data: blob:; worker-src 'self' blob:; frame-src 'self'; diff --git a/flock.js b/flock.js index 3d1e531e..4b25ff1e 100644 --- a/flock.js +++ b/flock.js @@ -47,7 +47,7 @@ import { setFlockReference as setFlockMovement, } from "./api/movement"; import { flockModels, setFlockReference as setFlockModels } from "./api/models"; -import { flockShapes, setFlockReference as setFlockShapes } from "./api/shapes"; +import { flockShapes, setFlockReference as setFlockShapes, getManifold } from "./api/shapes"; import { flockTransform, setFlockReference as setFlockTransform, @@ -1258,7 +1258,15 @@ export const flock = { flock.abortController = new AbortController(); try { - await flock.BABYLON.InitializeCSG2Async(); + // Pre-load the manifold-3d wasm module (which already redirects + // its WASM fetch to the locally-served /wasm/manifold.wasm via + // locateFile) and inject it into BabylonJS so InitializeCSG2Async + // never fetches from unpkg.com. + const manifoldWasm = await getManifold(); + await flock.BABYLON.InitializeCSG2Async({ + manifoldInstance: manifoldWasm.Manifold, + manifoldMeshInstance: manifoldWasm.Mesh, + }); } catch (error) { console.error("Error initializing CSG2:", error); } diff --git a/index.html b/index.html index e8ad94c1..229945ea 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@