1
0

perf: lazy load authenticated office peers

This commit is contained in:
2026-08-11 20:29:06 -07:00
parent 92ebf8abb5
commit fc1f500019
2 changed files with 21 additions and 7 deletions
+15 -6
View File
@@ -99,13 +99,17 @@ import {
type RobotSpec, type RobotSpec,
type RobotView, type RobotView,
} from "./robots.ts"; } from "./robots.ts";
import { import type {
createScenePeers, ScenePeers,
type ScenePeersOptions, ScenePeersOptions,
} from "../realtime/scenePeers.ts"; } from "../realtime/scenePeers.ts";
import type { EntityPoseSnapshot } from "../realtime/types.ts"; import type { EntityPoseSnapshot } from "../realtime/types.ts";
export type OfficeRealtimePeersOptions = Omit<ScenePeersOptions, "project" | "groundAt">; export type CreateOfficeScenePeers = (options: ScenePeersOptions) => ScenePeers;
export type OfficeRealtimePeersOptions = Omit<ScenePeersOptions, "project" | "groundAt"> & {
/** Injected by an authenticated caller so anonymous offices never download peer assets. */
create: CreateOfficeScenePeers;
};
/** Shared empty, so a pack with no robots does not allocate one per call. */ /** Shared empty, so a pack with no robots does not allocate one per call. */
const NO_ROBOTS: readonly RobotView[] = []; const NO_ROBOTS: readonly RobotView[] = [];
@@ -526,8 +530,8 @@ export function createOfficeScene(office: Office, options: OfficeSceneOptions):
// Geographic callbacks are required by the generic adapter but harmless here: // Geographic callbacks are required by the generic adapter but harmless here:
// an office subscription sends validated local poses in metre coordinates. // an office subscription sends validated local poses in metre coordinates.
const realtimePeers = depth === "full" && options.realtimePeers const realtimePeers = depth === "full" && options.realtimePeers
? createScenePeers({ ? options.realtimePeers.create({
...options.realtimePeers, ...withoutPeerFactory(options.realtimePeers),
project: () => [0, 0], project: () => [0, 0],
groundAt: () => 0, groundAt: () => 0,
localSceneUnitsPerMetre: options.realtimePeers.localSceneUnitsPerMetre ?? 1, localSceneUnitsPerMetre: options.realtimePeers.localSceneUnitsPerMetre ?? 1,
@@ -918,6 +922,11 @@ export function createOfficeScene(office: Office, options: OfficeSceneOptions):
}; };
} }
function withoutPeerFactory(options: OfficeRealtimePeersOptions): Omit<ScenePeersOptions, "project" | "groundAt"> {
const { create: _create, ...peerOptions } = options;
return peerOptions;
}
/** /**
* The fixed interior rig: a soft high sun, a strong hemisphere for the bounce a * The fixed interior rig: a soft high sun, a strong hemisphere for the bounce a
* real room has and a real-time renderer does not, no sky and no fog. * real room has and a real-time renderer does not, no sky and no fog.
+6 -1
View File
@@ -1180,6 +1180,11 @@ async function enterOffice() {
if (!built || !city) return; if (!built || !city) return;
const { createOfficeScene, createOfficeMinimap, pack, materials } = built; const { createOfficeScene, createOfficeMinimap, pack, materials } = built;
const depth = access.can.officeDepth; const depth = access.can.officeDepth;
// Keep the remote-avatar renderer behind the authenticated boundary. The
// public Office door can build its full local scene without downloading it.
const createOfficePeers = access.subject !== null
? (await import("./realtime/scenePeers.ts")).createScenePeers
: null;
/** /**
* The building's own sky, built before the scene because the scene wants the * The building's own sky, built before the scene because the scene wants the
@@ -1252,7 +1257,7 @@ async function enterOffice() {
...(depth === "full" ...(depth === "full"
? { onPresencePick: (p) => showDetail(p ? p.label : null) } ? { onPresencePick: (p) => showDetail(p ? p.label : null) }
: { onPlacePick: (place) => showDetail(place ? place.label : null) }), : { onPlacePick: (place) => showDetail(place ? place.label : null) }),
...(access.subject !== null ? { realtimePeers: {} } : {}), ...(createOfficePeers ? { realtimePeers: { create: createOfficePeers } } : {}),
}); });
office.onViewChange(() => renderLegend()); office.onViewChange(() => renderLegend());
officePlan = buildOfficePlan(createOfficeMinimap, office); officePlan = buildOfficePlan(createOfficeMinimap, office);