chore: drop exports nothing imports

Knip, configured with the application, package exports, scripts, QA
harnesses, workers, tools and tests as entry points, reports exports
that no module imports. Each was checked by hand against string-based
and namespace imports.

- Symbols that are still used inside their own module lose only the
  `export` keyword (176 constants and helpers).
- Unused re-exports are removed from barrel modules (flight, military,
  vessel, CCTV, directions, transit history, local ADS-B and street-level
  policy modules).
- Declarations that nothing uses at all are deleted, among them
  AIS_WATCHDOG_STATUSES, applyFilter, isRadioCountryCode, compactText,
  DENSITY_STOPS, the unused CCTV endpoint constants, and the SDR band
  constants.
- Default exports that nothing imports are removed. The ones in
  src/data/earthquakes.js, src/data/telegeographySubmarineCables.js,
  src/data/wind.js and src/data/bhoteKoshiLocator.js each constructed a
  layer instance at import time that nothing used; those instances are
  no longer created.

Every export of a package.json entry stays, as does TOMTOM_CREDIT,
which the traffic layer reads from the credits namespace it is given.
This commit is contained in:
Sameh Khamis committed 2026-10-22 19:00:40 -07:00
1 parent 504f9342aa
commit 73e789489b
106 files changed
+180 -342

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@
import { finiteOrNull } from './pointerContext.js';
export const POINTER_SENTINEL = 'pointer';
const POINTER_SENTINEL = 'pointer';
const TRACKABLE_LAYERS = new Set([
'flights',
+1 -1
View File
@@ -4,7 +4,7 @@ import { progressLine } from './speech.js';
* Timing policy for filling silence while tools run. Tuned against the turn
* spans' `max_silence_ms`.
*/
export const NARRATION_TIMING = Object.freeze({
const NARRATION_TIMING = Object.freeze({
/** Start the earcon when nothing is audible this long after end of speech. */
earconAfterMs: 700,
/** First spoken progress line when a tool is still running after this. */
+4 -4
View File
@@ -20,15 +20,15 @@
*/
/** Movement below this many CSS pixels is still the same dwell. */
export const POINTER_DWELL_PX = 12;
const POINTER_DWELL_PX = 12;
/** Stillness that makes a dwell point. */
export const POINTER_DWELL_MS = 250;
/** A resting pointer stays a referent this long after it last moved. */
export const POINTER_FRESH_MS = 30000;
/** Pixels from the canvas edge that count as "parked", never a referent. */
export const POINTER_EDGE_PX = 8;
const POINTER_EDGE_PX = 8;
/** A dwell pick is reused by a snapshot only while this recent (contacts move). */
export const POINTER_DWELL_REUSE_MS = 1000;
const POINTER_DWELL_REUSE_MS = 1000;
/**
* Open mic has no gesture, so the pointer only counts when it moved or
* settled on the map this recently: a cursor resting there for minutes is
@@ -76,7 +76,7 @@ export function cameraPoseKey(viewer) {
}
/** Bound and de-control a label before it goes to the model or the card. */
export function pointerLabel(value, max = LABEL_MAX) {
function pointerLabel(value, max = LABEL_MAX) {
const clean = String(value ?? '')
.replace(/[\p{Cc}\p{Cf}]+/gu, ' ')
.replace(/\s+/g, ' ')
+1 -1
View File
@@ -4,7 +4,7 @@ import { cameraPoseKey } from './pointerContext.js';
import * as defaultAnnotationResolver from '../annotations/annotationResolver.js';
/** "Around here" radius as a share of camera height, clamped to sane bounds. */
export function pointerRadiusKm(cameraHeightM) {
function pointerRadiusKm(cameraHeightM) {
const heightKm = Number(cameraHeightM) / 1000;
if (!Number.isFinite(heightKm) || heightKm <= 0) return 50;
return Math.round(Math.min(400, Math.max(5, heightKm * 0.75)));
+1 -1
View File
@@ -14,7 +14,7 @@ export const RETICLE_MAX_MS = 10000;
export const RETICLE_LINGER_MS = 1500;
/** Tools that move the camera away from the pointed spot. */
export const CAMERA_TOOLS = new Set([
const CAMERA_TOOLS = new Set([
'fly_to_location',
'track_entity',
'zoom_to_globe',
+11 -18
View File
@@ -1,10 +1,10 @@
export const ERROR_LOG_LIMIT = 30;
const ERROR_LOG_LIMIT = 30;
export const ERROR_STORAGE_KEY = 'gev-realtime-errors';
const ERROR_STORAGE_KEY = 'gev-realtime-errors';
export const DEBUG_LOG_URL = '/api/realtime/debug-log';
const DEBUG_LOG_URL = '/api/realtime/debug-log';
export function createDebugSessionId() {
function createDebugSessionId() {
const randomPart = Math.random().toString(36).slice(2, 10);
return `gev-${Date.now().toString(36)}-${randomPart}`;
}
@@ -47,7 +47,7 @@ export function sanitizeDebugValue(value, depth = 0) {
return output;
}
export function sanitizeDebugString(value) {
function sanitizeDebugString(value) {
if (value.startsWith('data:image/')) {
return `[Redacted image data URL, ${value.length} chars]`;
}
@@ -65,13 +65,13 @@ export function sanitizeDebugString(value) {
: redacted;
}
export function isSecretLikeKey(key) {
function isSecretLikeKey(key) {
return /(?:api[_-]?key|authorization|bearer|client[_-]?secret|token|secret|password)/i.test(
key,
);
}
export function createErrorRecord(source, error, extra = {}) {
function createErrorRecord(source, error, extra = {}) {
const rtcError = error?.error || error;
return {
timestamp: new Date().toISOString(),
@@ -90,7 +90,7 @@ export function createErrorRecord(source, error, extra = {}) {
};
}
export function formatErrorForDisplay(record) {
function formatErrorForDisplay(record) {
const primary = [record.source, record.message].filter(Boolean).join(': ');
const state = [
record.errorDetail && `detail=${record.errorDetail}`,
@@ -105,7 +105,7 @@ export function formatErrorForDisplay(record) {
return state ? `${primary}\n${state}` : primary;
}
export function removeEmptyValues(value) {
function removeEmptyValues(value) {
return Object.fromEntries(
Object.entries(value || {}).filter(
([, item]) => item !== null && item !== undefined && item !== '',
@@ -113,14 +113,7 @@ export function removeEmptyValues(value) {
);
}
export function compactText(value, maxLength) {
const text = String(value || '')
.replace(/\s+/g, ' ')
.trim();
return text.length <= maxLength ? text : `${text.slice(0, maxLength - 1)}…`;
}
export function loadStoredErrors() {
function loadStoredErrors() {
try {
const value = JSON.parse(localStorage.getItem(ERROR_STORAGE_KEY) || '[]');
return Array.isArray(value) ? value.slice(0, ERROR_LOG_LIMIT) : [];
@@ -129,7 +122,7 @@ export function loadStoredErrors() {
}
}
export function storeErrors(errors) {
function storeErrors(errors) {
try {
localStorage.setItem(
ERROR_STORAGE_KEY,
+3 -3
View File
@@ -8,12 +8,12 @@ import {
// Voice cost control (repo-wide `godsEyeView.<feature>.<field>` convention;
// the neighbouring ERROR_STORAGE_KEY predates it).
export const VOICE_TIER_STORAGE_KEY = 'godsEyeView.voiceCost.tier';
const VOICE_TIER_STORAGE_KEY = 'godsEyeView.voiceCost.tier';
export const VOICE_LIMITS_STORAGE_KEY = 'godsEyeView.voiceCost.limits';
const VOICE_LIMITS_STORAGE_KEY = 'godsEyeView.voiceCost.limits';
/** Best-effort localStorage handle; absent in tests and locked-down browsers. */
export function voiceStorage(storage) {
function voiceStorage(storage) {
if (storage) return storage;
try {
return typeof localStorage === 'undefined' ? null : localStorage;
+1 -1
View File
@@ -13,7 +13,7 @@ import {
import { narrationLabel } from './speech.js';
/** Out-of-band progress responses carry this metadata tag. */
export const PROGRESS_RESPONSE_TAG = 'progress';
const PROGRESS_RESPONSE_TAG = 'progress';
/**
* Speaks one code-authored progress line out of band. The line travels as
+8 -8
View File
@@ -5,17 +5,17 @@ import {
import { cameraPoseKey } from './pointerContext.js';
/** The live viewer's camera pose identity (Cesium-free read). */
export function readViewerCameraKey() {
function readViewerCameraKey() {
return cameraPoseKey(globalThis.window?.__godsEyeView?.viewer);
}
// Viewport-screenshot size guards (M13). The old code clamped WIDTH only, so a
// tall portrait window produced an oversized capture whose dc.send could throw.
// Cap total pixels (clamps both dimensions) and drop the image entirely if the
// encoded data URL is still too big for the data channel.
export const VIEWPORT_MAX_PIXELS = 1200 * 900;
const VIEWPORT_MAX_PIXELS = 1200 * 900;
// ~1.08 MP, matches the old 1200px-wide landscape budget
export const VIEWPORT_MAX_ENCODED_BYTES = 200 * 1024;
const VIEWPORT_MAX_ENCODED_BYTES = 200 * 1024;
export async function captureViewportImage() {
const viewer = window.__godsEyeView?.viewer;
@@ -66,11 +66,11 @@ export async function captureViewportImage() {
}
/** Side of the point-and-ask crop, in CSS pixels, and its output size. */
export const POINTER_CROP_SIZE = 512;
const POINTER_CROP_SIZE = 512;
/** A pointer snapshot older than this no longer matches the frame. */
export const POINTER_CROP_MAX_AGE_MS = 20000;
const POINTER_CROP_MAX_AGE_MS = 20000;
/** View scales where a crop shows buildings and terrain, not a smear. */
export const POINTER_CROP_SCALES = new Set(['local', 'city']);
const POINTER_CROP_SCALES = new Set(['local', 'city']);
/**
* Square source rectangle around a canvas point, clamped inside the canvas,
@@ -128,7 +128,7 @@ export function pointerCropRect({
* @returns {Promise<{dataUrl: string, rect: object}|null>} JPEG data URL and
* the crop's normalized bounds in the full canvas, or null.
*/
export async function capturePointerCrop(screenPx) {
async function capturePointerCrop(screenPx) {
const viewer = window.__godsEyeView?.viewer;
const source = viewer?.scene?.canvas;
if (!source?.width || !source?.height || !screenPx) return null;
@@ -259,7 +259,7 @@ export async function renderFreshCesiumFrame(viewer) {
}
}
export function isNearlyBlackFrame(ctx, width, height) {
function isNearlyBlackFrame(ctx, width, height) {
const sampleWidth = Math.min(48, width);
const sampleHeight = Math.min(32, height);
if (!sampleWidth || !sampleHeight) return true;
+1 -1
View File
@@ -59,7 +59,7 @@ function notesOf(...values) {
];
}
export function analystNounFor(layerKeys) {
function analystNounFor(layerKeys) {
const keys = [...new Set(layerKeys.filter(Boolean))];
if (keys.length !== 1) return 'results';
const key = keys[0];
+1 -1
View File
@@ -7,7 +7,7 @@
* Phrases that add length without adding an answer. Tool numbers are spoken
* verbatim, so approximations are hedges too.
*/
export const HEDGE_PHRASES = Object.freeze([
const HEDGE_PHRASES = Object.freeze([
'keep in mind',
"it's worth noting",
'it is worth noting',
+1 -1
View File
@@ -1,7 +1,7 @@
import { countWords, findHedges } from './speechLint.js';
/** Quiet period after the last audio or response before a turn is closed. */
export const TURN_SETTLE_MS = 2500;
const TURN_SETTLE_MS = 2500;
/**
* Per-turn latency and speech spans for one voice session.
+1 -1
View File
@@ -5,7 +5,7 @@ import {
} from './voiceCardPresentation.js';
/** Hide an idle card this long after its last update. */
export const VOICE_CARD_IDLE_MS = 14000;
const VOICE_CARD_IDLE_MS = 14000;
const ELEMENT_IDS = Object.freeze({
card: 'gev-voice-card',