Fix print page vendor load + persist authored scene across deploys

This commit is contained in:
2026-07-07 17:47:31 +10:00
parent f7de2c3b1f
commit 040b4006d8
3 changed files with 22 additions and 9 deletions
+1
View File
@@ -3,4 +3,5 @@ node_modules/
.run.pid
.deploy-installed
data/backups/
data/scene.live.json
_deploy/
+8 -5
View File
@@ -66,7 +66,12 @@
<div id="sheet"><div id="empty">Loading anchors…</div></div>
<!-- vendored ArUco dictionary for the exact bit patterns -->
<!-- js-aruco chain (order matters): cv -> svd -> posit -> aruco -> dictionary.
The dictionary file references AR from aruco.js; loading it alone throws. -->
<script src="vendor/cv.js"></script>
<script src="vendor/svd.js"></script>
<script src="vendor/posit1.js"></script>
<script src="vendor/aruco.js"></script>
<script src="vendor/dictionaries/aruco_4x4_1000.js"></script>
<script>
(function () {
@@ -80,11 +85,9 @@
// Build a 6x6 bit grid (0=black,1=white) for an ArUco 4x4 id.
// Outer ring is the quiet border (all black); inner 4x4 = the code bits.
function grid6(id) {
const dict = (window.AR && AR.DICTIONARIES && AR.DICTIONARIES.ARUCO_4X4_1000)
? AR.DICTIONARIES.ARUCO_4X4_1000 : null;
// js-aruco exposes the dictionary via AR.Dictionary; build one to read codeList
// Full js-aruco chain is loaded, so AR.Dictionary is available.
const d = new AR.Dictionary('ARUCO_4X4_1000');
const code = d.codeList[id];
const code = d.codeList[id]; // 16-char bit string, e.g. "1011..."
if (!code) return null;
const g = [];
for (let y = -1; y <= 4; y++) {
+13 -4
View File
@@ -13,9 +13,17 @@ const PORT = process.env.PORT || 34034;
const TICK_HZ = Number(process.env.TICK_HZ || 20); // server broadcast rate
// ---- Load scene ----------------------------------------------------------
// Two files:
// data/scene.json -> committed "seed" (tracked in git). Default/first-run.
// data/scene.live.json -> authored scene written by the admin (git-IGNORED),
// so `git reset --hard` on deploy never clobbers it.
// We read live if it exists, else fall back to the seed. Saves always go to live.
const SEED_PATH = join(ROOT, 'data', 'scene.json');
const LIVE_PATH = join(ROOT, 'data', 'scene.live.json');
function loadScene() {
const raw = readFileSync(join(ROOT, 'data', 'scene.json'), 'utf-8');
return JSON.parse(raw);
const path = existsSync(LIVE_PATH) ? LIVE_PATH : SEED_PATH;
return JSON.parse(readFileSync(path, 'utf-8'));
}
let scene = loadScene();
@@ -129,7 +137,7 @@ app.post('/api/scene', (req, res) => {
if (err) return res.status(400).json({ ok: false, error: err });
try {
const dataDir = join(ROOT, 'data');
const target = join(dataDir, 'scene.json');
const target = LIVE_PATH; // authored scene -> live file (survives deploys)
// timestamped backup so a bad save is always recoverable
const backupDir = join(dataDir, 'backups');
if (!existsSync(backupDir)) mkdirSync(backupDir, { recursive: true });
@@ -205,5 +213,6 @@ setInterval(() => {
httpServer.listen(PORT, () => {
console.log(`Newbury exhibit sync server on :${PORT} (broadcast ${TICK_HZ}Hz)`);
console.log(` Viewer: http://localhost:${PORT}/`);
console.log(` Scene: ${scene.spawns.length} spawns, ${scene.anchors.length} anchors`);
console.log(` Scene: ${scene.spawns.length} spawns, ${scene.anchors.length} anchors` +
` (${existsSync(LIVE_PATH) ? 'live: scene.live.json' : 'seed: scene.json'})`);
});