Fix print page vendor load + persist authored scene across deploys
This commit is contained in:
@@ -3,4 +3,5 @@ node_modules/
|
|||||||
.run.pid
|
.run.pid
|
||||||
.deploy-installed
|
.deploy-installed
|
||||||
data/backups/
|
data/backups/
|
||||||
|
data/scene.live.json
|
||||||
_deploy/
|
_deploy/
|
||||||
|
|||||||
@@ -66,7 +66,12 @@
|
|||||||
|
|
||||||
<div id="sheet"><div id="empty">Loading anchors…</div></div>
|
<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 src="vendor/dictionaries/aruco_4x4_1000.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
@@ -80,11 +85,9 @@
|
|||||||
// Build a 6x6 bit grid (0=black,1=white) for an ArUco 4x4 id.
|
// 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.
|
// Outer ring is the quiet border (all black); inner 4x4 = the code bits.
|
||||||
function grid6(id) {
|
function grid6(id) {
|
||||||
const dict = (window.AR && AR.DICTIONARIES && AR.DICTIONARIES.ARUCO_4X4_1000)
|
// Full js-aruco chain is loaded, so AR.Dictionary is available.
|
||||||
? AR.DICTIONARIES.ARUCO_4X4_1000 : null;
|
|
||||||
// js-aruco exposes the dictionary via AR.Dictionary; build one to read codeList
|
|
||||||
const d = new AR.Dictionary('ARUCO_4X4_1000');
|
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;
|
if (!code) return null;
|
||||||
const g = [];
|
const g = [];
|
||||||
for (let y = -1; y <= 4; y++) {
|
for (let y = -1; y <= 4; y++) {
|
||||||
|
|||||||
+13
-4
@@ -13,9 +13,17 @@ const PORT = process.env.PORT || 34034;
|
|||||||
const TICK_HZ = Number(process.env.TICK_HZ || 20); // server broadcast rate
|
const TICK_HZ = Number(process.env.TICK_HZ || 20); // server broadcast rate
|
||||||
|
|
||||||
// ---- Load scene ----------------------------------------------------------
|
// ---- 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() {
|
function loadScene() {
|
||||||
const raw = readFileSync(join(ROOT, 'data', 'scene.json'), 'utf-8');
|
const path = existsSync(LIVE_PATH) ? LIVE_PATH : SEED_PATH;
|
||||||
return JSON.parse(raw);
|
return JSON.parse(readFileSync(path, 'utf-8'));
|
||||||
}
|
}
|
||||||
let scene = loadScene();
|
let scene = loadScene();
|
||||||
|
|
||||||
@@ -129,7 +137,7 @@ app.post('/api/scene', (req, res) => {
|
|||||||
if (err) return res.status(400).json({ ok: false, error: err });
|
if (err) return res.status(400).json({ ok: false, error: err });
|
||||||
try {
|
try {
|
||||||
const dataDir = join(ROOT, 'data');
|
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
|
// timestamped backup so a bad save is always recoverable
|
||||||
const backupDir = join(dataDir, 'backups');
|
const backupDir = join(dataDir, 'backups');
|
||||||
if (!existsSync(backupDir)) mkdirSync(backupDir, { recursive: true });
|
if (!existsSync(backupDir)) mkdirSync(backupDir, { recursive: true });
|
||||||
@@ -205,5 +213,6 @@ setInterval(() => {
|
|||||||
httpServer.listen(PORT, () => {
|
httpServer.listen(PORT, () => {
|
||||||
console.log(`Newbury exhibit sync server on :${PORT} (broadcast ${TICK_HZ}Hz)`);
|
console.log(`Newbury exhibit sync server on :${PORT} (broadcast ${TICK_HZ}Hz)`);
|
||||||
console.log(` Viewer: http://localhost:${PORT}/`);
|
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'})`);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user