Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/ci/build-ci.mts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function ciBuildPlan(root: string, mode: CiBuildMode): readonly CiBuildTa
// Hashes icon sources with @cssearth/core/node, so it waits for the packages build.
node('icons', 'site/build/prepare/prepare-shell-icons.mts', ['packages']),
node('navigation', 'packages/bake/cli/prepare-navigation.mts', ['solar'], ['--catalog-only']),
node('world', 'site/build/prepare/prepare-spatial-context.ts', ['navigation'], ['src/objects/sun/source/navigation/universe.json', 'src/objects/sun/prepared/world-context.json']),
node('world', 'site/build/prepare/prepare-spatial-context.ts', ['navigation']),
node('moon-labels', 'site/build/prepare/prepare-moon-labels.mts', ['world']),
node('world-presentation', 'site/build/prepare/prepare-world-presentation.mts', ['world']),
);
Expand Down
5 changes: 3 additions & 2 deletions docs/performance/world-context-by-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ by one rule the bake and the build share ([world-holders.ts](../../packages/obje
every object with a file from the root of the tree down, and the rows object entries carry. It names no holder. Node
tools, tests, the build and the deploy check read it; no page does.

The bake computes every body in one full context, `src/objects/sun/prepared/world-context.json`, in the Sun's package: the
frame is the Sun's and the Sun's scene is framed from it. Node tools read it; no page does. It is the only world file there.
The bake computes every body in one full context, `src/objects/observable-universe/prepared/world-context.json`, in the root
object's package beside the summary and the index, from that package's `source/navigation/universe.json`. Node tools and
tests read it; no page does.

A file is read by every page when a body in it is drawn from anywhere: one that orbits nothing or the Sun and is no
plain dot (the Solar System's planets, the Milky Way's featured stars, the galaxies and clusters, a featured star of
Expand Down
2 changes: 1 addition & 1 deletion labs/experiments/native-scroll/context.mts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { prepareNativeOrbitCulling,nativeOrbitCullingCss } from './orbit-culling
import { BODY_INDICATOR_DIAMETER } from '@cssearth/renderer/universe/world-context/context-scale.ts';

const root = pathToFileURL(resolve('.') + '/');
const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('src/objects/sun/prepared/world-context.json', root), 'utf8')));
const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('src/objects/observable-universe/prepared/world-context.json', root), 'utf8')));
const descriptor: unknown = JSON.parse(await readFile(new URL('src/objects/milky-way-volume/object.json', root), 'utf8'));
const volume = await loadPreparedCssVolume(descriptor, { read: async path => {
const bytes = await readFile(new URL(`src/objects/milky-way-volume/${path}`, root));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"prepare:titles": "node site/build/prepare/prepare-shell-titles.mts",
"prepare:volume": "node packages/bake/cli/prepare-volume.mts",
"prepare:world-presentation": "node site/build/prepare/prepare-moon-labels.mts && node site/build/prepare/prepare-world-presentation.mts",
"prepare:world-context": "node site/build/prepare/prepare-spatial-context.ts src/objects/sun/source/navigation/universe.json src/objects/sun/prepared/world-context.json && pnpm prepare:world-presentation",
"prepare:world-context": "node site/build/prepare/prepare-spatial-context.ts && pnpm prepare:world-presentation",
"pretest": "pnpm prepare:shell",
"server-answers:record": "node .github/scripts/server-answers/record.mts",
"server-answers:diff": "node .github/scripts/server-answers/diff.mts",
Expand Down
2 changes: 1 addition & 1 deletion packages/bake/src/world-context/spatial-context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { M_PER_AU } from '@cssearth/astronomy';
import { parseWorldContextSource, prepareWorldContext } from './spatial-context.ts';
import type { OrbitalState } from './spatial-context.ts';

const sourcePath = 'src/objects/sun/source/navigation/universe.json';
const sourcePath = 'src/objects/observable-universe/source/navigation/universe.json';
// Unit cases supply their own body inventory; the application resolves catalogue membership.
async function readSource() {
return { ...JSON.parse(await readFile(sourcePath, 'utf8')), bodies: [{id: 'test-body', name: 'Test body', color: '#aaaaaa'}] };
Expand Down
24 changes: 12 additions & 12 deletions packages/renderer/src/sky/prepared-sky-runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ afterEach(() => { unstubAllGlobals(); catalogMount.mock.resetCalls(); });
test('cold bootstrap keeps catalogue and image banks descriptor-only, then reuses their first navigation load', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url);
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const image: PreparedCssImageLayers = { ...volume, id: 'lazy-image', bankViews: volume.stacks.map(stack => ({ axis: stack.axis,
normalUnits: stack.axis === 'x' ? [1, 0, 0] : stack.axis === 'y' ? [0, 1, 0] : [0, 0, 1], samplingStepUnits: 1 })) };
Expand All @@ -116,7 +116,7 @@ test('cold bootstrap keeps catalogue and image banks descriptor-only, then reuse
test('banks declared after the universe is made reach its mounted layers and every later mount, as addSystems does', () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url);
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const frame = volume.frame;
const { datasetBillboards } = datasetBanks([{ id: 'hosted-cloud', frame, attachedTo: 'host' }]);
Expand All @@ -141,7 +141,7 @@ test('banks declared after the universe is made reach its mounted layers and eve

test('the galaxy is its bulge slices at every overview scope, with no disc plane and no impostor views', () => {
const base = new URL('../../../../src/', import.meta.url);
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const document = new FakeDocument();
const mounted = createPreparedUniverse({ context, volume, pointAppearance: readCanonicalPointField(), sprites: {},
Expand Down Expand Up @@ -228,7 +228,7 @@ test('optional sky is validated as part of the existing volume capability and sh
});

test('near star cube is fully handed off before solar-system parallax produces duplicate stars', () => {
const source = JSON.parse(readFileSync(new URL('../../../../src/objects/sun/source/navigation/universe.json', import.meta.url), 'utf8'));
const source = JSON.parse(readFileSync(new URL('../../../../src/objects/observable-universe/source/navigation/universe.json', import.meta.url), 'utf8'));
const astronomicalUnitM = 149_597_870_700;
assert.equal(source.stars.fadeStartDistanceM, 100 * astronomicalUnitM);
assert.equal(source.stars.fullDistanceM, 200 * astronomicalUnitM);
Expand All @@ -238,7 +238,7 @@ test('near star cube is fully handed off before solar-system parallax produces d
for (const { withSky } of [{ withSky: true }, { withSky: false }]) test(`nearer than the disc's half-height the NASA band is the sky; from twice that the galaxy volume is (sky=$withSky)`, () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url);
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const sky = { ...fixture(), referenceFrame: volume.frame.referenceFrame, epochJdTt: volume.frame.epochJdTt };
const { sky: _originalSky, ...volumeWithoutSky } = volume;
Expand Down Expand Up @@ -294,7 +294,7 @@ for (const { withSky } of [{ withSky: true }, { withSky: false }]) test(`nearer
test('a galaxy backing that loads while the camera rests is placed before any layer shows', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const backing = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/backing.json', base), 'utf8'));
stubGlobal('fetch', async () => new Response(JSON.stringify(backing)));
Expand Down Expand Up @@ -322,7 +322,7 @@ test('a galaxy backing that loads while the camera rests is placed before any la
test('a galaxy backing whose ring image cannot resolve mounts no layer at all', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const backing = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/backing.json', base), 'utf8'));
stubGlobal('fetch', async () => new Response(JSON.stringify(backing)));
Expand All @@ -343,7 +343,7 @@ test('a galaxy backing whose ring image cannot resolve mounts no layer at all',
test('shared universe draws only resolved nebulae and never prefetches their datasets with the galaxy', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const frame: PreparedCssVolume['frame'] = { referenceFrame: volume.frame.referenceFrame, epochJdTt: volume.frame.epochJdTt,
originM: [context.focus.positionM[0], context.focus.positionM[1], context.focus.positionM[2] + 50 * parsecM],
Expand Down Expand Up @@ -446,7 +446,7 @@ test('shared universe draws only resolved nebulae and never prefetches their dat
test('an unloaded independent bank is fetched by proximity while the galactic fade is zero; a galactic one waits for the galaxy', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const frame: PreparedCssVolume['frame'] = { referenceFrame: volume.frame.referenceFrame, epochJdTt: volume.frame.epochJdTt,
originM: [context.focus.positionM[0], context.focus.positionM[1], context.focus.positionM[2] + 50 * parsecM],
Expand Down Expand Up @@ -496,7 +496,7 @@ test('an unloaded independent bank is fetched by proximity while the galactic fa
test('selecting a nebula loads its bank on demand even while it is out of view', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const frame: PreparedCssVolume['frame'] = { referenceFrame: volume.frame.referenceFrame, epochJdTt: volume.frame.epochJdTt,
originM: [context.focus.positionM[0], context.focus.positionM[1], context.focus.positionM[2] + 5000 * parsecM],
Expand Down Expand Up @@ -548,7 +548,7 @@ test('selecting a nebula loads its bank on demand even while it is out of view',
test('hidden dataset banks are bounded, active subscriptions pin them, and eviction reloads saved presentation', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
const volume = JSON.parse(readFileSync(new URL('objects/milky-way-volume/prepared/volume.json', base), 'utf8')).data as PreparedCssVolume;
const makeBank = (id: string, distancePc: number): PreparedVolumeDatasets => {
const frame: PreparedCssVolume['frame'] = { referenceFrame: volume.frame.referenceFrame, epochJdTt: volume.frame.epochJdTt,
Expand Down Expand Up @@ -621,7 +621,7 @@ function completedPixel(host: FakeElement, image: FakeElement, sky: FakeElement
test('authoritative detailed close-up gates background fetch, painting and publication without changing the NASA sky weight', async () => {
stubGlobal('HTMLElement', FakeElement); stubGlobal('Element', FakeElement);
const base = new URL('../../../../src/', import.meta.url), parsecM = 3.085677581491367e16;
const context = JSON.parse(readFileSync(new URL('objects/sun/prepared/world-context.json', base), 'utf8'));
const context = JSON.parse(readFileSync(new URL('objects/observable-universe/prepared/world-context.json', base), 'utf8'));
context.volume.opacityProfile = { model: 'logarithmic-distance', fadeStartDistanceM: 1e19, fullDistanceM: 1e21, nearOpacity: 0, fullOpacity: 1 };
// The galaxy's volume is gated by the distance to the selected body, as for every body: the close-up is mid-fade.
context.volume.discHalfHeightM = .5 * parsecM;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const defined = (value: unknown): unknown => Array.isArray(value) ? value.map(de
: value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype
? Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined).map(([key, item]) => [key, defined(item)])) : value;

const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('../../../../../src/objects/sun/prepared/world-context.json', import.meta.url), 'utf8')));
const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('../../../../../src/objects/observable-universe/prepared/world-context.json', import.meta.url), 'utf8')));
// Tests move the observer in place; the planner itself receives the readonly view.
type World = WorldContextView['world'];
type TestView = Omit<WorldContextView, 'world'> & { world: Omit<World, 'pose'> & { pose: Omit<World['pose'], 'positionM'> & { positionM: [number, number, number] } } };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { FEATURED_STAR_TIER, labelImportance } from '../../labels/universe-label
import { unpackPreparedBinary } from '@cssearth/objects/node';

const plan = parsePreparedWorldContext(JSON.parse(await readFile(
new URL('../../../../../src/objects/sun/prepared/world-context.json', import.meta.url), 'utf8')));
new URL('../../../../../src/objects/observable-universe/prepared/world-context.json', import.meta.url), 'utf8')));
const freeze = <T>(value: T): T => {
// Typed orbit arrays cannot be frozen; the test compares their contents instead.
if (value && typeof value === 'object' && !ArrayBuffer.isView(value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ test('point source uses the prepared star photometry, nearest atlas color, and s
});

test('the prepared Sun landmark grows smoothly from the light-year handoff without changing its physical disc', async () => {
const source = JSON.parse(await readFile(new URL('../../../../../src/objects/sun/prepared/world-context.json', import.meta.url), 'utf8'));
const source = JSON.parse(await readFile(new URL('../../../../../src/objects/observable-universe/prepared/world-context.json', import.meta.url), 'utf8'));
const solarPlan = parsePreparedWorldContext(source), au = 149597870700, lightYearM = 299792458 * 31557600;
const sample = (distanceAu: number, context = solarPlan) => worldContextPointAppearance(context, field,
{ ...world(distanceAu * au), epochJdTt: context.frame.epochJdTt }, { ...viewport, focalPixels: 1280 * Math.sqrt(3) / 2 }, { selectedDetail: true })!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isDeepStrictEqual } from 'node:util';
import { parsePreparedWorldContext } from '@cssearth/objects';
import { createWorldContextPlanner, type WorldContextView } from './world-context-planner.js';

const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('../../../../../src/objects/sun/prepared/world-context.json', import.meta.url), 'utf8')));
const plan = parsePreparedWorldContext(JSON.parse(await readFile(new URL('../../../../../src/objects/observable-universe/prepared/world-context.json', import.meta.url), 'utf8')));

test('a selected satellite overview retains its selected host locator', () => {
const host = plan.bodies.find(body => body.id === 'jupiter')!;
Expand Down
4 changes: 2 additions & 2 deletions packages/telescope-cli/src/sphere/sphere-lane.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** A measurement dataset for an existing standard sphere. No geometry or camera is authored here. */
import { objectPageCss, parsePreparedObjectRuntime, parsePreparedWorldContext } from '@cssearth/objects';
import { OBJECT_TREE_ROOT, objectPageCss, parsePreparedObjectRuntime, parsePreparedWorldContext } from '@cssearth/objects';

import { readFile, mkdir } from 'node:fs/promises';
import { resolve } from 'node:path';
Expand Down Expand Up @@ -49,7 +49,7 @@ export async function inspectMeasurementSphere(root:string,target:string){
const own = requireArray(requireRecord(properties.page).stylesheets).map(path => requireString(path)).filter(path => !shared.includes(path));
const styles = await Promise.all([...shared, ...own].map(async file => Buffer.from(objectPageCss((await pinned(resolve(root, file))).toString(), id))));
if (!worldFrame) throw new Error('Standard sphere has no prepared physical frame');
const context = parsePreparedWorldContext(await json(resolve(root, 'src/objects/sun/prepared/world-context.json')));
const context = parsePreparedWorldContext(await json(resolve(root, 'src/objects', OBJECT_TREE_ROOT, 'prepared/world-context.json')));
return {id,object,inputs,pinned,recipe,original,datasetId,surface,variant,required,styles,worldFrame,context};
}

Expand Down
Loading
Loading