generated from Labyricorn/labyricorn-project-template
Steps 6.4-6.7B — Local surfaces, reference-exhibit validation, SciFi Observation surface
One commit for the work accumulated in the working tree since Step 6.3, which had never been split into per-step commits: - src/local-surfaces.js + src/surface-url.js (new); src/ui.js, src/validation.js, src/connection.js and public/index.html updated for local-surface hosting and generic surface rendering - tests: local-surfaces (20), scifi-surfaces (24) and postmessage-interop (7) new; connection/museum-gallery/surface-validation suites updated - reference exhibits: shared/contract-core.js defaults to Contract 5.3 (major 5, minor 3, xzbt 5.3); museum-gallery advertises its surface catalog; aquarium/haunted-house/planetarium adapters updated - SciFi-XZBT (Step 6.7A/6.7B): surface-mode.js + surface-bus.js, Observation-surface boot branch, local-change hooks, view.pillars / view.warp-flight targets; fixture byte-identical to G:/.vibe/SciFi-XZBT - SciFi-XZBT contract adapter handshake fix: the inbound bridge filter no longer gates on an exact advisory xzbt value (Contract 5.3 §6.5), only on its presence/type, matching the host's own envelope validation; the adapter now advertises contract minor 3 / version 5.3.0, which it already implemented via the 5.3 surfaces field. Root cause of the five failing postmessage-interop tests (host hello was silently dropped). - docs: architecture 6.4 and 6.7A, reference 6.6 and 6.7; evidence logs; test-fixtures/PROVENANCE.md resync record Test results: NGN 154/154 (was 149/154); postmessage-interop 7/7 (was 2/7); SciFi contract harness 21/21, real-adapter suite 32/32. git diff --check clean for changed files; two pre-existing trailing-whitespace lines remain in test-fixtures/reference-exhibits/scifi/index.html, copied verbatim from the authoritative SciFi source. Step 6.7 live verification (browser Observation, packaged standalone) is still pending and is not claimed here.
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* XZBT Surface Mode — SciFi-XZBT (Step 6.7B)
|
||||
*
|
||||
* Pure, testable seam for resolving which boot mode this document load is in
|
||||
* (Contract 5.3 §31.4 query-string surface form) and for describing the
|
||||
* exhibit's two-entry surface catalog. No DOM access, no imports, no
|
||||
* side effects — safe to load and exercise under Node's `vm` module.
|
||||
*
|
||||
* Two surfaces only:
|
||||
* - surface.console the full operator console (index.html, primary)
|
||||
* - surface.observation the same document, rendering only the
|
||||
* Observation viewscreen, addressed by
|
||||
* ?surface=observation&xi=<instanceId>
|
||||
*/
|
||||
(function (root) {
|
||||
'use strict';
|
||||
|
||||
var CHANNEL_PREFIX = 'xzbt-scifi-surface-v1:';
|
||||
|
||||
/**
|
||||
* Resolve the boot mode + instance id for a location-like object.
|
||||
* @param {object} locationLike anything with a `.search` (or `.href`)
|
||||
* string, e.g. `window.location`.
|
||||
* @returns {{mode: 'console'|'observation', instanceId: string|null}}
|
||||
*/
|
||||
function resolve(locationLike) {
|
||||
var search = '';
|
||||
if (locationLike && typeof locationLike.search === 'string') {
|
||||
search = locationLike.search;
|
||||
} else if (locationLike && typeof locationLike.href === 'string') {
|
||||
var qIdx = locationLike.href.indexOf('?');
|
||||
search = qIdx >= 0 ? locationLike.href.slice(qIdx) : '';
|
||||
}
|
||||
|
||||
var params;
|
||||
try {
|
||||
params = new URLSearchParams(search);
|
||||
} catch (err) {
|
||||
params = null;
|
||||
}
|
||||
|
||||
var surfaceParam = params ? params.get('surface') : null;
|
||||
var instanceId = params ? params.get('xi') : null;
|
||||
|
||||
if (surfaceParam === 'observation') {
|
||||
return { mode: 'observation', instanceId: instanceId || null };
|
||||
}
|
||||
|
||||
// Unknown/absent `?surface=` values resolve to console. `xi` is
|
||||
// meaningless in console mode.
|
||||
return { mode: 'console', instanceId: null };
|
||||
}
|
||||
|
||||
/** Mint a fresh per-document-load instance id. */
|
||||
function newInstanceId() {
|
||||
return 'xi-' + Math.random().toString(16).slice(2) + Date.now().toString(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* The exhibit's two-entry surface catalog (Contract 5.3 §31.2/§31.3).
|
||||
* @param {string} instanceId the live console instance id.
|
||||
*/
|
||||
function SURFACES(instanceId) {
|
||||
return [
|
||||
{
|
||||
id: 'surface.console',
|
||||
label: 'Main Console',
|
||||
kind: 'surface',
|
||||
primary: true,
|
||||
url: 'index.html',
|
||||
role: 'control',
|
||||
category: 'console',
|
||||
description: 'The full SciFi-XZBT operator console.'
|
||||
},
|
||||
{
|
||||
id: 'surface.observation',
|
||||
label: 'Observation',
|
||||
kind: 'surface',
|
||||
primary: false,
|
||||
url: '?surface=observation&xi=' + encodeURIComponent(instanceId),
|
||||
role: 'ambient',
|
||||
category: 'observation',
|
||||
aspectRatio: '16:9',
|
||||
requires: ['observation'],
|
||||
description: 'Full-screen procedural viewscreen mirroring the console.'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/** The instance-scoped BroadcastChannel name for a console instance id. */
|
||||
function channelName(instanceId) {
|
||||
return CHANNEL_PREFIX + instanceId;
|
||||
}
|
||||
|
||||
var XZBTSurfaceMode = {
|
||||
resolve: resolve,
|
||||
newInstanceId: newInstanceId,
|
||||
SURFACES: SURFACES,
|
||||
channelName: channelName
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = XZBTSurfaceMode;
|
||||
}
|
||||
if (root) {
|
||||
root.XZBTSurfaceMode = XZBTSurfaceMode;
|
||||
}
|
||||
})(typeof window !== 'undefined' ? window : (typeof globalThis !== 'undefined' ? globalThis : this));
|
||||
Reference in New Issue
Block a user