451 lines
14 KiB
Markdown
451 lines
14 KiB
Markdown
# GENOME.md — the-playground
|
|
|
|
Generated: 2026-04-17 10:00 UTC
|
|
Repo: Timmy_Foundation/the-playground
|
|
Analyzed commit: `142d77736de3b303ea5320dbd5dcfda99e59f325`
|
|
Host issue: timmy-home #671
|
|
|
|
## Project Overview
|
|
|
|
`the-playground` is a browser-first creative sandbox with a strong visual identity and a deliberately simple deployment model: open `index.html` or serve static files. It is not yet the full platform promised by the README. The current repo is a compact prototype shell with real interaction loops for sound, drawing, constellation play, gallery persistence, and export.
|
|
|
|
Current measured facts from the fresh `main` archive I analyzed:
|
|
- 14 JavaScript source files
|
|
- 1 CSS design system file
|
|
- 2 HTML entry pages (`index.html`, `smoke-test.html`)
|
|
- 1 Python test module in the target repo (`tests/test_perf_budgets.py`)
|
|
- 0 package manifests
|
|
- 0 build steps
|
|
- `pytest -q` → `7 passed in 0.03s`
|
|
- no backend or network API in the shipped app shell
|
|
|
|
What exists on `main` today:
|
|
- cinematic entrance screen
|
|
- three actual canvas/runtime modes:
|
|
- `free-draw`
|
|
- `ambient`
|
|
- `constellation`
|
|
- a Web Audio engine for notes/chords/scales
|
|
- a Canvas 2D visual engine
|
|
- an IndexedDB-backed gallery
|
|
- export helpers for WAV, single-item download, ZIP packaging, and standalone HTML export
|
|
- perf budget artifacts and a dormant runtime performance monitor
|
|
- a browser smoke harness plus one pytest module for perf budget/pipeline presence
|
|
|
|
This repo is best understood as four layers:
|
|
1. page shell + script-order runtime contract
|
|
2. browser engines (`PlaygroundAudio`, `PlaygroundVisual`, `PlaygroundGallery`)
|
|
3. experience/orchestration (`src/playground.js`, `ModeManager`, `constellation`)
|
|
4. export/perf sidecars that are only partially integrated into the live app
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
graph TD
|
|
HTML[index.html] --> CSS[src/styles/design-system.css]
|
|
HTML --> U[src/utils/utils.js]
|
|
HTML --> S[src/utils/state.js]
|
|
HTML --> E[src/utils/events.js]
|
|
HTML --> AE[src/engine/audio-engine.js]
|
|
HTML --> VE[src/engine/visual-engine.js]
|
|
HTML --> G[src/gallery/gallery.js]
|
|
HTML --> WAV[src/export/wav-encoder.js]
|
|
HTML --> EXP[src/export/download.js]
|
|
HTML --> SP[src/panels/sound/sound-panel.js]
|
|
HTML --> GP[src/panels/gallery/gallery-panel.js]
|
|
HTML --> MM[src/modes/mode-manager.js]
|
|
HTML --> CONST[src/modes/constellation.js]
|
|
HTML --> APP[src/playground.js]
|
|
|
|
APP --> AE
|
|
APP --> VE
|
|
APP --> G
|
|
APP --> SP
|
|
APP --> GP
|
|
APP --> MM
|
|
APP --> U
|
|
APP --> S
|
|
APP --> E
|
|
GP --> EXP
|
|
EXP --> WAV
|
|
G --> IDB[(IndexedDB playground-gallery)]
|
|
AE --> AC[AudioContext]
|
|
VE --> CANVAS[Canvas 2D]
|
|
|
|
SMOKE[smoke-test.html] --> U
|
|
SMOKE --> S
|
|
SMOKE --> E
|
|
SMOKE --> AE
|
|
SMOKE --> VE
|
|
SMOKE --> G
|
|
|
|
PERF[src/utils/perf-monitor.js]
|
|
PERFTEST[tests/test_perf_budgets.py] --> PERF
|
|
PERFTEST --> PERFCFG[lighthouse-budget.json + .lighthouserc.json + .gitea/workflows/perf-check.yml]
|
|
HTML -. not loaded on main .-> PERF
|
|
```
|
|
|
|
## Entry Points
|
|
|
|
### `index.html`
|
|
The real product entry point.
|
|
|
|
Responsibilities:
|
|
- defines the entrance curtain
|
|
- defines header, left sound panel, center canvas, right gallery panel, and footer action bar
|
|
- loads global scripts in strict dependency order
|
|
- exposes no module loader or bundler boundary
|
|
|
|
Current runtime script order:
|
|
1. `src/utils/utils.js`
|
|
2. `src/utils/state.js`
|
|
3. `src/utils/events.js`
|
|
4. `src/engine/audio-engine.js`
|
|
5. `src/engine/visual-engine.js`
|
|
6. `src/gallery/gallery.js`
|
|
7. `src/export/wav-encoder.js`
|
|
8. `src/export/download.js`
|
|
9. `src/panels/sound/sound-panel.js`
|
|
10. `src/panels/gallery/gallery-panel.js`
|
|
11. `src/modes/mode-manager.js`
|
|
12. `src/modes/constellation.js`
|
|
13. `src/playground.js`
|
|
|
|
Important truth: `src/utils/perf-monitor.js` exists in the repo but is not loaded by `index.html` on current `main`.
|
|
|
|
### `src/playground.js`
|
|
The orchestration nucleus.
|
|
|
|
What it does today:
|
|
- entrance particle system and enter transition
|
|
- engine construction and initialization
|
|
- default ambient animation loop
|
|
- mode registration and selector rendering
|
|
- canvas resizing
|
|
- gallery initialization and rerender after saves
|
|
- save/download/clear/fullscreen button wiring
|
|
- footer prompt handling and keyboard shortcuts
|
|
|
|
This file is the clearest statement of what the app actually is right now.
|
|
|
|
### `smoke-test.html`
|
|
Browser smoke harness.
|
|
- loads a subset of runtime files directly
|
|
- runs assertions in the browser DOM
|
|
- provides manual high-signal sanity checks around utils/state/events/audio/visual/gallery
|
|
|
|
### `tests/test_perf_budgets.py`
|
|
The only pytest module in the target repo.
|
|
|
|
What it verifies:
|
|
- existence of `src/utils/perf-monitor.js`
|
|
- existence of `lighthouse-budget.json`
|
|
- existence of `.lighthouserc.json`
|
|
- existence of `.gitea/workflows/perf-check.yml`
|
|
- very shallow content checks for the perf monitor and perf workflow artifacts
|
|
|
|
## Data Flow
|
|
|
|
### Boot flow
|
|
1. Browser opens `index.html`.
|
|
2. CSS establishes the gold-on-dark design system.
|
|
3. utility/state/events globals load.
|
|
4. engine/gallery/export/panel/mode globals load.
|
|
5. `src/playground.js` runs in an IIFE.
|
|
6. entrance screen shows animated particles.
|
|
7. user clicks `Enter` or presses a key.
|
|
8. `enterPlayground()` fades out entrance, initializes audio, reveals the app shell, and starts the playground.
|
|
|
|
### Core interaction flow
|
|
1. `PlaygroundVisual` binds the canvas.
|
|
2. `PlaygroundGallery` opens IndexedDB.
|
|
3. `SoundPanel.init(audioEngine)` renders the left-side sound UI.
|
|
4. `GalleryPanel.init(galleryEngine)` renders the right-side gallery UI.
|
|
5. `ModeManager` registers available modes and renders selector buttons.
|
|
6. ambient mode starts by default; draw and constellation can be selected.
|
|
|
|
### Draw/save/export flow
|
|
1. user draws or interacts in a mode.
|
|
2. save path converts canvas to a blob/data URL.
|
|
3. `PlaygroundGallery.save()` writes a gallery item into IndexedDB.
|
|
4. `gallery:item-saved` fires on the event bus.
|
|
5. `GalleryPanel` rerenders.
|
|
6. download path exports the canvas PNG and a JSON metadata sidecar.
|
|
7. gallery panel can also invoke `PlaygroundExport.downloadItem()` for persisted items.
|
|
|
|
### Constellation mode flow
|
|
1. `ModeManager.switch('constellation')` activates `src/modes/constellation.js`.
|
|
2. stars are created and drawn on the canvas.
|
|
3. drag events move stars.
|
|
4. close-distance interactions trigger pentatonic notes and an ambient drone.
|
|
5. teardown removes listeners and fades out drone oscillators.
|
|
|
|
### Metrics synthesis flow (current state)
|
|
1. perf budget artifacts exist in the repo.
|
|
2. `tests/test_perf_budgets.py` proves those files exist.
|
|
3. `PerfMonitor` can emit paint/layout/long-task/memory signals.
|
|
4. but the live app never loads or starts it, so there is no real runtime metric emission on `main`.
|
|
|
|
## Key Abstractions
|
|
|
|
### `PlaygroundUtils`
|
|
Small browser helper surface:
|
|
- `uuid()`
|
|
- `clamp()`
|
|
- `lerp()`
|
|
- `map()`
|
|
- `toast()`
|
|
- `downloadBlob()`
|
|
|
|
### `PlaygroundState`
|
|
Global mutable state bucket for:
|
|
- canvas
|
|
- audio
|
|
- gallery
|
|
- UI
|
|
- recording
|
|
|
|
It is a convenience registry, not a durable data store.
|
|
|
|
### `PlaygroundEvents`
|
|
Minimal event bus:
|
|
- `on(event, fn)`
|
|
- `emit(event, data)`
|
|
- `off(event, fn)`
|
|
|
|
### `PlaygroundAudio`
|
|
Web Audio wrapper for:
|
|
- note → frequency mapping
|
|
- chord generation
|
|
- scale generation
|
|
- oscillator playback
|
|
- chord playback
|
|
|
|
### `PlaygroundVisual`
|
|
Canvas wrapper for:
|
|
- resize
|
|
- clear
|
|
- drawLine
|
|
- drawCircle
|
|
- seeded palette generation
|
|
- placeholder pseudo-noise helper
|
|
|
|
### `PlaygroundGallery`
|
|
IndexedDB repository:
|
|
- DB name: `playground-gallery`
|
|
- object store: `items`
|
|
- indexes: `type`, `collection`, `created`
|
|
- methods: `init`, `save`, `getById`, `getAll`, `deleteItem`
|
|
|
|
### `ModeManager`
|
|
Registry/switcher for canvas experiences:
|
|
- `register()`
|
|
- `switch()`
|
|
- `renderSelector()`
|
|
- `current`
|
|
- `modes`
|
|
|
|
### `PlaygroundExport`
|
|
Download/export sidecar for:
|
|
- single item download
|
|
- metadata sidecars
|
|
- batch ZIP export
|
|
- standalone HTML gallery export
|
|
|
|
### `PlaygroundWavEncoder`
|
|
AudioBuffer → WAV blob encoder used by export paths.
|
|
|
|
### `PerfMonitor`
|
|
Dormant runtime performance monitor for:
|
|
- FCP/LCP
|
|
- CLS
|
|
- long tasks
|
|
- memory polling
|
|
|
|
Useful code, but currently disconnected from the product entrypoint.
|
|
|
|
## API Surface
|
|
|
|
This repo has no network API. The public surface is browser globals plus IndexedDB object contracts.
|
|
|
|
### Browser globals exposed on `main`
|
|
- `PlaygroundUtils`
|
|
- `PlaygroundState`
|
|
- `PlaygroundEvents`
|
|
- `PlaygroundAudio`
|
|
- `PlaygroundVisual`
|
|
- `PlaygroundGallery`
|
|
- `PlaygroundWavEncoder`
|
|
- `PlaygroundExport`
|
|
- `SoundPanel`
|
|
- `GalleryPanel`
|
|
- `ModeManager`
|
|
|
|
### Event bus contract
|
|
Observed event names:
|
|
- `audio:note-played`
|
|
- `audio:chord-played`
|
|
- `gallery:item-saved`
|
|
- `gallery:item-deleted`
|
|
- `canvas:mode-changed`
|
|
- `playground:ready`
|
|
|
|
### Gallery item contract
|
|
Persisted items can include:
|
|
- `id`
|
|
- `created`
|
|
- `modified`
|
|
- `type`
|
|
- `name`
|
|
- `data`
|
|
- `mimeType`
|
|
- `thumbnail`
|
|
- `metadata`
|
|
- sometimes audio/video-specific fields consumed by export helpers
|
|
|
|
### UI command surface
|
|
Important DOM ids:
|
|
- `btn-save`
|
|
- `btn-download`
|
|
- `btn-clear`
|
|
- `btn-fullscreen`
|
|
- `mode-selector`
|
|
- `sound-content`
|
|
- `gallery-content`
|
|
- `playground-canvas`
|
|
|
|
Keyboard shortcuts implemented on `main`:
|
|
- `Ctrl+S` → Save
|
|
- `Ctrl+D` → Download
|
|
- `F11` → Fullscreen
|
|
- `Escape` → exit fullscreen
|
|
|
|
## Test Coverage Gaps
|
|
|
|
### Current state
|
|
What I verified on a fresh `main` archive:
|
|
- `pytest -q` → `7 passed in 0.03s`
|
|
- there is exactly one pytest module: `tests/test_perf_budgets.py`
|
|
- no JS unit-test harness
|
|
- no package manifest
|
|
- browser smoke harness still exists, but it is not the same thing as CI-grade coverage
|
|
|
|
### What is covered today
|
|
- presence/shape of perf budget artifacts
|
|
- presence of the perf monitor file
|
|
- presence of the perf check workflow
|
|
- smoke-test manual coverage around utils/state/events/audio/visual/gallery (browser harness, not pytest)
|
|
|
|
### Critical uncovered paths
|
|
1. `src/playground.js` orchestration
|
|
- entrance flow
|
|
- initialization sequence
|
|
- action-bar wiring
|
|
- keyboard shortcuts
|
|
- panel toggles
|
|
2. `src/export/download.js`
|
|
- single-item export
|
|
- ZIP export
|
|
- standalone HTML export
|
|
3. `src/export/wav-encoder.js`
|
|
- WAV blob correctness
|
|
4. `src/modes/constellation.js`
|
|
- drag lifecycle
|
|
- teardown correctness
|
|
- audio interaction contract
|
|
5. gallery interaction behavior
|
|
- open/view flow
|
|
- item count updates
|
|
- HTML escaping and render safety
|
|
|
|
### Filed from this analysis
|
|
- the-playground #247 — PerfMonitor ships but is never loaded or started on `main`
|
|
- the-playground #248 — batch export loads JSZip from CDN, violating zero-dependency/local-first posture
|
|
|
|
## Security Considerations
|
|
|
|
### Strong points
|
|
- no backend/API attack surface in the shipped app
|
|
- local-first IndexedDB persistence
|
|
- static hosting posture is simple and inspectable
|
|
- no npm dependency tree on current `main`
|
|
|
|
### Risks
|
|
1. `innerHTML` remains a major sink surface
|
|
- gallery rendering is the riskiest because it interpolates persisted item data
|
|
- related issues already exist in the target repo
|
|
2. dynamic third-party script load in export path
|
|
- `PlaygroundExport._loadJSZip()` injects a CDN script tag for JSZip
|
|
- this breaks the repo's own zero-dependency/local-first claim
|
|
3. dormant perf monitoring path
|
|
- monitoring code exists but is not in the runtime path
|
|
- repo can give a false sense of observability
|
|
4. browser capability assumptions remain strong
|
|
- IndexedDB
|
|
- AudioContext
|
|
- Fullscreen API
|
|
- Blob/FileReader
|
|
- `crypto.randomUUID()`
|
|
|
|
## Dependencies
|
|
|
|
### Browser/runtime dependencies
|
|
- Canvas 2D API
|
|
- Web Audio API / `AudioContext`
|
|
- IndexedDB
|
|
- Fullscreen API
|
|
- Blob / `toBlob`
|
|
- FileReader
|
|
- `crypto.randomUUID()`
|
|
- standard DOM APIs
|
|
|
|
### Project/tooling dependencies
|
|
- no `package.json`
|
|
- no bundler
|
|
- no build step
|
|
- one pytest-based perf artifact check
|
|
- one browser smoke harness
|
|
|
|
### External runtime dependency discovered
|
|
- JSZip from CDN in `src/export/download.js` for batch ZIP export
|
|
|
|
## Deployment
|
|
|
|
Current deployment model is still very simple:
|
|
- open `index.html` directly in a browser
|
|
- or serve the repo as static files from any web server
|
|
|
|
Verification flow I used:
|
|
1. inspect `index.html` script contract
|
|
2. run `pytest -q` in the target repo
|
|
3. inspect critical mode/export/perf files directly
|
|
4. compare live repo state to the existing genome artifact
|
|
|
|
## Technical Debt
|
|
|
|
### Highest-priority debt
|
|
1. README vision still exceeds code reality
|
|
2. orchestration/export/mode behavior lacks serious automated coverage
|
|
3. `PerfMonitor` exists but is not wired into runtime (`#247`)
|
|
4. ZIP export relies on CDN-loaded JSZip (`#248`)
|
|
5. gallery/open interaction depth is still shallow compared to the product promise
|
|
|
|
### Meaningful product debt
|
|
- no real frontend app/test packaging discipline
|
|
- no integrated runtime metrics surface despite perf budget artifacts
|
|
- export system is richer than the rest of the UI exposes
|
|
- batch export and standalone gallery export exist in code but are not a clearly surfaced first-class workflow in the main shell
|
|
- the prototype is still held together by global load order rather than explicit module boundaries
|
|
|
|
## Bottom Line
|
|
|
|
`the-playground` is no longer just a two-mode shell. Current `main` has grown into a more substantial browser prototype with export infrastructure, a third experience mode, a perf-budget lane, and one real pytest module.
|
|
|
|
But the repo still has a truth gap between what exists in source and what is actually exercised end-to-end:
|
|
- export is richer than the visible UI story
|
|
- performance monitoring exists but is not running
|
|
- dependency posture says local-first while ZIP export reaches for a CDN
|
|
- automated coverage is still far thinner than the surface area of the product
|
|
|
|
That is the real architectural story now: the codebase is starting to branch into platform-level capabilities, but verification and integration are lagging behind the feature shards already present in source.
|