style: format standalone configuration and build boundaries

This commit is contained in:
Sameh Khamis committed 2026-09-11 18:08:26 -07:00
1 parent 8de1018c21
commit fb67024f43
9 files changed
+111 -61

No files matched your search

+12 -4
View File
@@ -2,16 +2,24 @@ import cesium from 'vite-plugin-cesium';
/** Build browser assets with explicit inputs; never load environment or providers. */
export function createBrowserViteConfig({
plugins = [], googleApiKey, cesiumToken, host = 'localhost', port = 4173,
plugins = [],
googleApiKey,
cesiumToken,
host = 'localhost',
port = 4173,
} = {}) {
return {
plugins: [cesium(), ...plugins],
server: {
host: host || 'localhost',
port: parseInt(port, 10) || 4173,
allowedHosts: host === '0.0.0.0' || host === '::'
? true : ['localhost', '127.0.0.1', '.local'],
fs: { deny: ['.env', '.env.*', '*.{crt,pem}', '**/.git/**', '**/ENVIRONMENT'] },
allowedHosts:
host === '0.0.0.0' || host === '::'
? true
: ['localhost', '127.0.0.1', '.local'],
fs: {
deny: ['.env', '.env.*', '*.{crt,pem}', '**/.git/**', '**/ENVIRONMENT'],
},
// These headers protect the document containing Provider Settings.
headers: {
'X-Frame-Options': 'DENY',
+7 -8
View File
@@ -16,13 +16,13 @@ excluded. The formatter validates every entry before writing any file.
## Current component ownership
| Surface | Owns | Receives from its caller |
| --------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------- |
| `gods-eye-view/infrastructure` | Datacenter/dam definitions and fresh layer construction | Context, overlay and render operations |
| `gods-eye-view/infrastructure/geojson` | Data loading, Cesium entities, selection handling and resource cleanup | A viewer and those same operations |
| `gods-eye-view/infrastructure/lod` | Pure visibility budgets and selection policy | Position/visibility records and camera measurements |
| `src/data/localGeojson.js` | Standalone compatibility wiring | The application's existing shared services |
| `src/main.js` and `src/standalone/` | Standalone browser startup | Local configuration |
| Surface | Owns | Receives from its caller |
| -------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------- |
| `gods-eye-view/infrastructure` | Datacenter/dam definitions and fresh layer construction | Context, overlay and render operations |
| `gods-eye-view/infrastructure/geojson` | Data loading, Cesium entities, selection handling and resource cleanup | A viewer and those same operations |
| `gods-eye-view/infrastructure/lod` | Pure visibility budgets and selection policy | Position/visibility records and camera measurements |
| `src/data/localGeojson.js` | Standalone compatibility wiring | The application's existing shared services |
| `src/main.js` and `src/standalone/` | Standalone browser startup | Local configuration |
The application and infrastructure exports are browser source modules. Use their documented
exports instead of importing standalone startup or reaching into internal files.
@@ -54,7 +54,6 @@ Neither export imports standalone UI, layers, tools or configuration. See
UI panels and individual source adapters remain future extractions. They should
become smaller modules with explicit lifecycle owners as their callers migrate.
## Build and standalone server configuration
`gods-eye-view/build/vite` is a separate Node-only export. `build/vite.js`
+5 -1
View File
@@ -70,7 +70,11 @@ export async function checkPackageBoundaries(root) {
const input = group.exports.map((key) => {
const declaration = pkg.exports[key];
const target = node ? declaration?.node : declaration;
if (node && (typeof declaration !== 'object' || Object.keys(declaration).join() !== 'node')) {
if (
node &&
(typeof declaration !== 'object' ||
Object.keys(declaration).join() !== 'node')
) {
throw new Error(`Node export must have only a node condition: ${key}`);
}
if (
+5 -1
View File
@@ -27,5 +27,9 @@
"src/standalone/scene.js",
"src/standalone/startupChrome.js",
"src/standalone/startupChrome.test.mjs",
"src/standalone/tools.js"
"src/standalone/tools.js",
"build/vite.js",
"server/standalone/vite.config.js",
"vite.config.js",
"src/tooling/viteBuild.test.mjs"
]
+9 -27
View File
@@ -10,40 +10,22 @@
"src/data/localGeojsonCore.js",
"src/data/localGeojsonLod.js"
],
"external": [
"cesium"
]
"external": ["cesium"]
},
"application": {
"exports": [
"./application"
],
"modules": [
"src/app/application.js"
],
"exports": ["./application"],
"modules": ["src/app/application.js"],
"external": []
},
"viewer": {
"exports": [
"./application/viewer"
],
"modules": [
"src/app/viewer.js"
],
"external": [
"cesium"
]
"exports": ["./application/viewer"],
"modules": ["src/app/viewer.js"],
"external": ["cesium"]
},
"vite-build": {
"runtime": "node",
"exports": [
"./build/vite"
],
"modules": [
"build/vite.js"
],
"external": [
"vite-plugin-cesium"
]
"exports": ["./build/vite"],
"modules": ["build/vite.js"],
"external": ["vite-plugin-cesium"]
}
}
+8 -2
View File
@@ -20,11 +20,17 @@ export function createStandaloneApplication({
const loaderStatus = loadingScreen.querySelector('.loader-status');
return createApplication({
createScene: (context) =>
createStandaloneScene({ ...context, googleApiKey, cesiumToken, loaderStatus }),
createStandaloneScene({
...context,
googleApiKey,
cesiumToken,
loaderStatus,
}),
createControls: (context) =>
createStandaloneControls({ ...context, loaderStatus }),
createData: (context) =>
createStandaloneData({ ...context, allowQaRegistration }),
createTools: (context) => createStandaloneTools({ ...context, loadingScreen }),
createTools: (context) =>
createStandaloneTools({ ...context, loadingScreen }),
});
}
+3 -1
View File
@@ -30,7 +30,9 @@ export function createStandaloneTools({
if (window.__gevAnnotations === annotations) delete window.__gevAnnotations;
annotations.destroy();
});
defer(startStandaloneChrome({ loadingScreen, styleManager, dataManager, signal }));
defer(
startStandaloneChrome({ loadingScreen, styleManager, dataManager, signal }),
);
// Idle render governor: flips the scene into requestRenderMode whenever
// nothing animates per frame. Installed AFTER every module above has had
// its chance to register pre-install holds. (perf wave 2)
+26 -8
View File
@@ -78,14 +78,32 @@ test('dynamic imports obey the same component ownership rule', async (t) => {
test('a Node build export must be explicitly classified and scoped', async (t) => {
const root = await fixture(t);
await writeFile(path.join(root, 'package.json'), JSON.stringify({
name: 'boundary-fixture', type: 'module', exports: { './feature': { node: './entry.js' } },
}));
await writeFile(path.join(root, 'scripts/package-boundaries.json'), JSON.stringify({
feature: { runtime: 'node', exports: ['./feature'], modules: ['entry.js'], external: [] },
}));
assert.deepEqual(await checkPackageBoundaries(root), [{ name: 'feature', exports: 1, modules: 1 }]);
await writeFile(path.join(root, 'entry.js'), "import './startup.js'; export const value = 1;");
await writeFile(
path.join(root, 'package.json'),
JSON.stringify({
name: 'boundary-fixture',
type: 'module',
exports: { './feature': { node: './entry.js' } },
}),
);
await writeFile(
path.join(root, 'scripts/package-boundaries.json'),
JSON.stringify({
feature: {
runtime: 'node',
exports: ['./feature'],
modules: ['entry.js'],
external: [],
},
}),
);
assert.deepEqual(await checkPackageBoundaries(root), [
{ name: 'feature', exports: 1, modules: 1 },
]);
await writeFile(
path.join(root, 'entry.js'),
"import './startup.js'; export const value = 1;",
);
await writeFile(path.join(root, 'startup.js'), 'export const app = 2;');
await assert.rejects(checkPackageBoundaries(root), /unowned module.*startup/);
});
+36 -9
View File
@@ -7,21 +7,39 @@ import * as providers from '../../server/providers/local.js';
test('explicit build inputs preserve browser-only defines, plugin order and loopback protections', () => {
const plugin = { name: 'fixture-provider' };
const config = createBrowserViteConfig({ plugins: [plugin], googleApiKey: 'browser-fixture', cesiumToken: 'ion-fixture' });
const config = createBrowserViteConfig({
plugins: [plugin],
googleApiKey: 'browser-fixture',
cesiumToken: 'ion-fixture',
});
assert.equal(config.plugins[1], plugin);
assert.equal(config.server.host, 'localhost');
assert.equal(config.server.port, 4173);
assert.deepEqual(config.server.allowedHosts, ['localhost', '127.0.0.1', '.local']);
assert.deepEqual(config.server.allowedHosts, [
'localhost',
'127.0.0.1',
'.local',
]);
assert.ok(config.server.fs.deny.includes('**/ENVIRONMENT'));
assert.ok(config.server.fs.deny.includes('.env.*'));
assert.equal(config.server.headers['X-Frame-Options'], 'DENY');
assert.equal(config.server.headers['Content-Security-Policy'], "frame-ancestors 'none'");
assert.equal(
config.server.headers['Content-Security-Policy'],
"frame-ancestors 'none'",
);
assert.deepEqual(config.define, {
'import.meta.env.GOOGLE_MAPS_API_KEY': '"browser-fixture"',
'import.meta.env.CESIUM_ION_TOKEN': '"ion-fixture"',
});
assert.equal(createBrowserViteConfig({ host: '0.0.0.0', port: '4800' }).server.allowedHosts, true);
assert.equal(createBrowserViteConfig({ host: '::', port: '4800' }).server.port, 4800);
assert.equal(
createBrowserViteConfig({ host: '0.0.0.0', port: '4800' }).server
.allowedHosts,
true,
);
assert.equal(
createBrowserViteConfig({ host: '::', port: '4800' }).server.port,
4800,
);
});
test('build helper does not discover environment values or construct local providers', () => {
@@ -29,7 +47,10 @@ test('build helper does not discover environment values or construct local provi
process.env.GOOGLE_MAPS_API_KEY = 'environment-fixture';
try {
const config = createBrowserViteConfig();
assert.equal(config.define['import.meta.env.GOOGLE_MAPS_API_KEY'], undefined);
assert.equal(
config.define['import.meta.env.GOOGLE_MAPS_API_KEY'],
undefined,
);
assert.equal(config.plugins.length, 1);
} finally {
if (before === undefined) delete process.env.GOOGLE_MAPS_API_KEY;
@@ -38,15 +59,21 @@ test('build helper does not discover environment values or construct local provi
});
test('root config retains existing named exports and standalone provider order', () => {
for (const [name, value] of Object.entries(providers)) assert.equal(compatibility[name], value, name);
for (const [name, value] of Object.entries(providers))
assert.equal(compatibility[name], value, name);
const config = standaloneConfig({ mode: 'test' });
assert.deepEqual(config.plugins.slice(1).map((plugin) => plugin.name), providers.localProviderPlugins().map((plugin) => plugin.name));
assert.deepEqual(
config.plugins.slice(1).map((plugin) => plugin.name),
providers.localProviderPlugins().map((plugin) => plugin.name),
);
assert.equal(config.plugins.at(-1).name, 'gev-key-setup');
});
test('build export resolves in Node and has no browser fallback', async () => {
const exported = await import('gods-eye-view/build/vite');
assert.equal(exported.createBrowserViteConfig, createBrowserViteConfig);
const pkg = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url)));
const pkg = JSON.parse(
readFileSync(new URL('../../package.json', import.meta.url)),
);
assert.deepEqual(pkg.exports['./build/vite'], { node: './build/vite.js' });
});