client/core – AGENTS
Shared services, utilities, and math primitives that power both vector and matrix modes. These modules must stay framework-free, DOM-light, and reusable across future Bespoke apps.
Loading Order + Globals
- Files are loaded (via
<script>tags) in deterministic order beforelinear-algebra.js. Do not introduce circular dependencies. - Each module attaches itself to
window.*or defines a global class. Keep those names stable; the rest of the app references them directly.
Modules
status.js(window.StatusService)\- Sole gateway for status text. Only expose the allowed verbatim strings.
- Gracefully handle missing
#status(warn once, no throws).
config.js(window.ConfigService)\- Fetches
./config.json, merges withDEFAULT_CONFIG, caches the result, and emitsStatusService.setLoading()/setReady()/setLoadFailed(). - Returns mutable objects internally but callers must treat them as frozen
because
linear-algebra.jswraps them inObject.freeze. - Expose
clearCache()for manual reloads/tests.
- Fetches
operation-schemas.js(window.OperationSchemas)\- Source of truth for allowed operation group keys. Always run
validateOperationGroups(mode, groups)before wiring UI so that new config flags cannot break the app.
- Source of truth for allowed operation group keys. Always run
mode-manager.js(window.ModeManager)\- Owns
.mode-contentvisibility and the sharedCoordinateSystem. renderModeButtons(enabledModes)+hideDisabledModeContainers(enabledModes)drive what the user sees based onconfig.json.enabledModes.onModeChange(callback)notifies helpers like the HelpService when the active mode flips.registerMode(name, factory)stores factories that must return instances exposingdestroy().setMode(name)tears down the current instance (wrapped in try/catch) and applies.active/.hiddenclasses. Never mutate the DOM for mode toggles elsewhere.
- Owns
help.js(window.HelpService)\- Lazily fetches
help-content-template.htmlonce, initializesHelpModal, and supportsappendHelpContent(). Always callinitializeHelpModalbefore appending extra sections.
- Lazily fetches
theme-service.js(window.CanvasThemeService)\- Initialized exactly once with
STYLE_CONSTANTS. ProvidesgetColors(),subscribe(callback)(returns unsubscribe fn), and cleans up media-query listeners viadestroy(). Subscribers must unsubscribe inside theirdestroy()implementation.
- Initialized exactly once with
color-utils.js(window.ColorUtils)\- Reads CSS custom properties under
.bespoke(which are mapped from Design System tokens viabespoke.css). Use this to keep colors responsive to theme changes instead of hard-coding hex values.
- Reads CSS custom properties under
animator.js(class Animator)\- Pure animation helpers (ease curves,
animate,lerp,lerpVector). Returns a control object withcancel(). Modes must cancel outstanding animations insidedestroy().
- Pure animation helpers (ease curves,
coordinate-system.js(class CoordinateSystem)\- Handles canvas sizing, grid/axis drawing, coordinate transforms, hover
hit-testing helpers, and translated vector rendering. Register resize
callbacks via
setResizeCallback.
- Handles canvas sizing, grid/axis drawing, coordinate transforms, hover
hit-testing helpers, and translated vector rendering. Register resize
callbacks via
vector.js(class Vector)\- Immutable 2D vector with math helpers (
add,subtract,scale,dot, projections, reflections, normalization, perpendicular, angle utilities).Vector.defaultResultColorshould be overridden throughVector.setDefaultResultColorso that result vectors track the theme.
- Immutable 2D vector with math helpers (
results-panel.js(class ResultsPanel)\- Lightweight wrapper that writes formula/result markup into a container.
Use
.show(...lines)and.clear()rather than manipulating DOM manually.
- Lightweight wrapper that writes formula/result markup into a container.
Use
format-utils.js(window.FormatUtils)\- HTML formatting helpers for matrices (
formatMatrixAsGrid) and vectors (formatVector). Use them whenever results need inline math formatting.
- HTML formatting helpers for matrices (
Cross-Cutting Rules
- Keep modules idempotent: calling init/load functions multiple times should be
safe (e.g.,
CanvasThemeService.initignores missing constants,HelpServicewarns on double init). - Every async function (
ConfigService.loadConfig,HelpServicefetches) mustconsole.erroron failure and fall back to usable defaults (e.g., placeholder help copy). - Never mutate DOM outside the module’s intended surface (e.g.,
ResultsPanelcan write into its container, butVectormust remain math-only). - All exports should be documented here whenever new files are added. If you add another shared service, update this AGENTS file before landing the code.