playlist-data-engine 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +14 -0
  2. package/bin/cli.cjs +85 -0
  3. package/dist/gateway-CDMPqFEH.js +1320 -0
  4. package/dist/gateway-DKa45Uz6.cjs +6 -0
  5. package/dist/gateway.d.ts +1 -0
  6. package/dist/gateway.d.ts.map +1 -1
  7. package/dist/gateway.js +1 -1
  8. package/dist/gateway.mjs +22 -19
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/playlist-data-engine.js +4 -4
  12. package/dist/playlist-data-engine.mjs +30 -27
  13. package/dist/utils/engineDocs.d.ts +33 -0
  14. package/dist/utils/engineDocs.d.ts.map +1 -0
  15. package/docs/DATA_ENGINE_REFERENCE.md +6660 -0
  16. package/docs/USAGE_IN_OTHER_PROJECTS.md +587 -0
  17. package/docs/features/AUDIO_ANALYSIS.md +610 -0
  18. package/docs/features/BEAT_DETECTION.md +5250 -0
  19. package/docs/features/COMBAT_SYSTEM.md +1632 -0
  20. package/docs/features/CONTENT_PACKS.md +464 -0
  21. package/docs/features/CUSTOM_CONTENT.md +603 -0
  22. package/docs/features/ENEMY_GENERATION.md +1711 -0
  23. package/docs/features/EQUIPMENT_SYSTEM.md +2279 -0
  24. package/docs/features/EXTENSIBILITY_GUIDE.md +1106 -0
  25. package/docs/features/GATEWAY_RESOLUTION.md +725 -0
  26. package/docs/features/IRL_SENSORS.md +360 -0
  27. package/docs/features/PLAYLIST_PARSING.md +446 -0
  28. package/docs/features/PREREQUISITES.md +571 -0
  29. package/docs/features/ROLLS_AND_SEEDS.md +687 -0
  30. package/docs/features/XP_AND_STATS.md +1221 -0
  31. package/llms.txt +33 -0
  32. package/package.json +9 -2
  33. package/skills/playlist-data-engine/SKILL.md +69 -0
  34. package/dist/gateway-C_p9Ku3O.js +0 -1211
  35. package/dist/gateway-Ceg-5xug.cjs +0 -1
package/llms.txt ADDED
@@ -0,0 +1,33 @@
1
+ # playlist-data-engine
2
+
3
+ > Parse Arweave serverless music playlists into clean data, resolve alternate mixes and lossy/lossless audio quality, and reach files through automatic gateway failover — the engine behind ar://listen.
4
+
5
+ The docs live inside the npm package itself, version-matched to your install: `node_modules/playlist-data-engine/docs/`. Also readable via `npx playlist-data-engine docs <topic>`, and programmatically via the exported `engineHelp()`.
6
+
7
+ ## Core (music player infrastructure)
8
+
9
+ - [docs/DATA_ENGINE_REFERENCE.md](docs/DATA_ENGINE_REFERENCE.md): every public function, one row each — signatures, inputs, outputs
10
+ - [docs/USAGE_IN_OTHER_PROJECTS.md](docs/USAGE_IN_OTHER_PROJECTS.md): install, main vs gateway entry, first parsed playlist
11
+ - [docs/features/PLAYLIST_PARSING.md](docs/features/PLAYLIST_PARSING.md): loading playlists, track objects, alternate mixes (pins, alias matching, lossy/lossless pairs)
12
+ - [docs/features/GATEWAY_RESOLUTION.md](docs/features/GATEWAY_RESOLUTION.md): gateway failover, Wayfinder, resolving tx and IPFS URLs
13
+
14
+ ## Audio analysis
15
+
16
+ - [docs/features/AUDIO_ANALYSIS.md](docs/features/AUDIO_ANALYSIS.md): BPM, key, mood, genre classification (TensorFlow + essentia)
17
+ - [docs/features/BEAT_DETECTION.md](docs/features/BEAT_DETECTION.md): beat streams and rhythm-game chart generation
18
+
19
+ ## Game systems (RPG-from-audio)
20
+
21
+ - [docs/features/COMBAT_SYSTEM.md](docs/features/COMBAT_SYSTEM.md): seeded combat simulations driven by track energy
22
+ - [docs/features/ENEMY_GENERATION.md](docs/features/ENEMY_GENERATION.md): characters generated from sonic fingerprints
23
+ - [docs/features/EQUIPMENT_SYSTEM.md](docs/features/EQUIPMENT_SYSTEM.md): loot and equipment
24
+ - [docs/features/XP_AND_STATS.md](docs/features/XP_AND_STATS.md): progression and persistence
25
+ - [docs/features/ROLLS_AND_SEEDS.md](docs/features/ROLLS_AND_SEEDS.md): deterministic seeded dice
26
+ - [docs/features/IRL_SENSORS.md](docs/features/IRL_SENSORS.md): weather, time, motion context
27
+ - [docs/features/CONTENT_PACKS.md](docs/features/CONTENT_PACKS.md) / [CUSTOM_CONTENT.md](docs/features/CUSTOM_CONTENT.md) / [EXTENSIBILITY_GUIDE.md](docs/features/EXTENSIBILITY_GUIDE.md) / [PREREQUISITES.md](docs/features/PREREQUISITES.md): extending the engine
28
+
29
+ ## For AI agents
30
+
31
+ - `engineHelp()` (exported from both package entries) returns this index as markdown; `engineHelp('<topic>')` returns where to read one doc
32
+ - `engineHelp('skill')` returns the companion Claude Code skill file (also `npx playlist-data-engine skill`)
33
+ - TypeScript users: the `.d.ts` in dist/ is the complete API surface with JSDoc
package/package.json CHANGED
@@ -6,8 +6,11 @@
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/jasondesante/playlist-data-engine.git"
8
8
  },
9
- "version": "1.7.3",
9
+ "version": "1.8.0",
10
10
  "type": "module",
11
+ "bin": {
12
+ "playlist-data-engine": "bin/cli.cjs"
13
+ },
11
14
  "main": "./dist/playlist-data-engine.js",
12
15
  "module": "./dist/playlist-data-engine.mjs",
13
16
  "types": "./dist/index.d.ts",
@@ -30,7 +33,11 @@
30
33
  }
31
34
  },
32
35
  "files": [
33
- "dist"
36
+ "dist",
37
+ "docs",
38
+ "bin",
39
+ "skills",
40
+ "llms.txt"
34
41
  ],
35
42
  "keywords": [
36
43
  "arweave",
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: playlist-data-engine
3
+ description: The playlist-data-engine npm package — parse Arweave/IPFS serverless music playlists (Ethereum NFTs + Arweave uploads; the data behind ar://listen and ApeTapes) into clean track data; resolve alternate mixes (entry pins, selected_mix, alias-tolerant lookup, lossy/lossless pairs) and track extras/stems; reach files through Arweave gateway failover (AR.IO Wayfinder); analyze audio (sonic fingerprint, genre/mood classification, pitch, BPM/beat maps, rhythm charts) and drive deterministic D&D-style generation from the music — characters, enemies, combat, equipment, XP. Use when working with the playlist-data-engine package, serverless playlist JSON, Arweave music NFTs, or building music-reactive or rhythm-game features on this engine.
4
+ ---
5
+
6
+ # playlist-data-engine
7
+
8
+ One engine, one pipeline: a **serverless playlist** (Arweave JSON mixing Ethereum NFTs and Arweave uploads) is parsed into clean tracks; track audio is analyzed; analysis drives **deterministic generation** — characters, enemies, rhythm charts, combat; XP/progression and IRL sensors make the result a living music player. Two halves meet at audio: the data half (parse → extract → resolve → analyze) and the game half (beat map → chart → character/XP/combat).
9
+
10
+ ## First moves
11
+
12
+ - Docs ship **inside the package**, version-matched to your install: `node_modules/playlist-data-engine/docs/`. If docs and observed behavior disagree, check your installed version.
13
+ - `docs/DATA_ENGINE_REFERENCE.md` is the master index — every export, one row each, **no examples or algorithms by design** (those live in USAGE and features/*). Start at its **Quick Export Reference** to find the function, then jump to its section. Caveat: its Core table predates the entry-point split — the ML classes listed there now live behind `/analysis`.
14
+ - `docs/USAGE_IN_OTHER_PROJECTS.md` has working code for every major feature (install, full pipeline, troubleshooting).
15
+ - CLI: `npx playlist-data-engine docs` (doc index) · `docs <topic>` (full text) · `skill` (this file). From code: `engineHelp()` / `engineHelp('<topic>')` / `engineHelp('skill')` — exported from both the default and `/gateway` entries. Canonical copy of this file: `skills/playlist-data-engine/SKILL.md` in the repo.
16
+ - The `.d.ts` in `dist/` is the complete API surface with JSDoc.
17
+
18
+ ## Three entry points — pick by bundle weight
19
+
20
+ | Import | Gives you | Pulls TF? |
21
+ |---|---|---|
22
+ | `playlist-data-engine` (default) | Everything **except** ML — parser, playlists, mixes, gateway, generation, combat, XP, sensors, beat detection | No |
23
+ | `playlist-data-engine/gateway` | Lightest: `ArweaveGatewayManager` + Arweave/IPFS URL utils, `MetadataExtractor`, mix lookup (`findMixByName`/`resolveMixUrl`/`selectMix`), `getMixes`/`getMixTracks`/VRM getters | No |
24
+ | `playlist-data-engine/analysis` | TensorFlow-bearing: `AudioAnalyzer`, `MusicClassifier`, `PitchAnalyzer`, `EssentiaPitchDetector`, `PitchBeatLinker`, `ButtonMapper`, `LevelGenerator`, `LevelSerializer`, `BeatConverter`, `ModelCache` | Yes (~14 MB) |
25
+
26
+ Rules: default to the bare import; import `/analysis` only in code that actually runs ML — ideally isolated in a Web Worker; never re-export `/analysis` symbols through the other entries.
27
+
28
+ ## The map
29
+
30
+ | You want… | Reach for | Read |
31
+ |---|---|---|
32
+ | Parse a playlist | `new PlaylistParser().parse(raw)` — takes any raw object; options `strict`, `validateAudioUrls`, `resolveImageUrls`. Gateway fetch is yours: `arweaveGatewayManager.resolveUrl()` + `fetch` | features/PLAYLIST_PARSING.md |
33
+ | Quick data arrays | `getAudioUrls`, `getTrackTitles`, `getArtists`, `getGenres`, `getTags`, `getTotalDuration`, `getTracks`, `getFullTracks` — work on raw **and** parsed input | DATA_ENGINE_REFERENCE.md → Playlist Utilities |
34
+ | Track extras (stems, mixes, VRM, lyrics, charts…) | `track.extras`, `getTrackMetadata(raw)`, `getTrackExtras(metadata)` | features/PLAYLIST_PARSING.md |
35
+ | Alternate mixes | See **Mixes** below | features/PLAYLIST_PARSING.md |
36
+ | Conditional mixes (weather/time/plays) | `evaluateMixConditions(extras, { environment, appState })` — unknown condition types always pass; `weather` conditions need `WEATHER_API_KEY`, day/time pass keyless | features/PLAYLIST_PARSING.md |
37
+ | Resolve any Arweave URL | `arweaveGatewayManager.resolveUrl(url)` — cache → the gateway already in the URL → persisted gateway → arweave.net → static gateways in parallel → AR.IO Wayfinder last. Hot path: `resolveUrlSimple()`. After a real fetch fails: `reportGatewayFailure(url, { reason })`. Non-Arweave URLs pass through | features/GATEWAY_RESOLUTION.md |
38
+ | IPFS URLs | `isIPFS`, `extractIPFSPath`, `resolveIPFSLink` | features/GATEWAY_RESOLUTION.md |
39
+ | Sonic fingerprint / full timeline | `AudioAnalyzer.extractSonicFingerprint(url)` (samples 5%/40%/70%), `.analyzeTimeline(url, { type: 'interval' \| 'count', … })` | features/AUDIO_ANALYSIS.md |
40
+ | Genre / mood / vibes | `MusicClassifier.analyze(url)` — 400+ subgenres, mood themes, danceability/energy/valence; zero-config defaults load Arweave-hosted models; `preset:` swaps models | features/AUDIO_ANALYSIS.md |
41
+ | Pitch / melody | `PitchDetector` (pure pYIN, TF-free, **default entry**) or `/analysis` `PitchAnalyzer.analyze(url)` (adds contour; `EssentiaPitchDetector` needs `await .create()`) | features/AUDIO_ANALYSIS.md |
42
+ | Colors from artwork | `ColorExtractor.extractPalette(imageUrl)` (default entry, no TF) | DATA_ENGINE_REFERENCE.md → ColorExtractor |
43
+ | Detect beats / play in rhythm | `BeatMapGenerator.generateBeatMap()` → `BeatStream` (real-time sync, `checkButtonPress`); `GrooveAnalyzer` (DMC-style groove meter); interpolation/subdivision helpers; manual chart editing via `reapplyDownbeatConfig` + beat key helpers | features/BEAT_DETECTION.md |
44
+ | Procedural rhythm charts | `RhythmGenerator` (default entry: transients → quantize → phrases → composite streams → difficulty variants) or `/analysis` `LevelGenerator` (adds pitch-driven `ButtonMapper` for DDR/Guitar Hero/Tap) | features/BEAT_DETECTION.md |
45
+ | Character from a song | `CharacterGenerator.generate(seed, audioProfile, track, { gameMode: 'standard' \| 'uncapped' })` — same song, same character. `audioProfile` = `/analysis` `AudioAnalyzer.extractSonicFingerprint()` — or any plain `AudioProfile` object (TF-free synthesis is valid) | USAGE_IN_OTHER_PROJECTS.md |
46
+ | Enemies / encounters | `EnemyGenerator.generate()` / `generateEncounter(party, opts)` / `generateEncounterByCR(opts)` — **CR = power, rarity = complexity, independent axes**; audio profile steers templates & stats | features/ENEMY_GENERATION.md |
47
+ | Combat & balance | `CombatEngine` (turn-based; `hitMode: 'scaled'` default — AC reduces damage — vs `'dnd'`), `CombatSimulator` (Monte Carlo, per-run seeds), `CombatAI`/`AICombatRunner`, `DifficultyCalculator`, `BalanceValidator`, `ParameterSweep` | features/COMBAT_SYSTEM.md |
48
+ | Dice & seeds | `generateSeed(chain, address, tokenId)`, `deriveSeed`, `SeededRNG`, `DiceRoller`, `SeededDiceRoller`/`createSeededRoller` | features/ROLLS_AND_SEEDS.md |
49
+ | Equipment / loot | `EquipmentGenerator`, `EquipmentModifier` (enchant/curse/upgrade), `EquipmentSpawnHelper` (batch spawn), `BoxOpener` (box items) | features/EQUIPMENT_SYSTEM.md |
50
+ | XP & leveling | `SessionTracker` → `CharacterUpdater.updateCharacterFromSession()` (~1 XP/s × modifiers), `addXP`/`addRhythmXP` for other sources; `StatManager` strategies; `PrestigeSystem` (track mastery); uncapped XP curves | features/XP_AND_STATS.md |
51
+ | IRL context | `EnvironmentalSensors` (GPS/motion/weather; solar math needs no API key), `GamingPlatformSensors` (Steam); XP modifier capped at 3.0× | features/IRL_SENSORS.md |
52
+ | Custom content | `ExtensionManager.getInstance().register(category, items, { mode, weights })` — races, classes, spells, skills, `classFeatures`, `racialTraits`, equipment; runtime only | features/EXTENSIBILITY_GUIDE.md (+ CUSTOM_CONTENT.md, CONTENT_PACKS.md, PREREQUISITES.md) |
53
+ | Something broke | ML models load from Arweave at runtime (offline dev fails); audio analysis needs Web Audio | USAGE_IN_OTHER_PROJECTS.md → Troubleshooting |
54
+ | Validate data | Zod schemas: `ServerlessPlaylistSchema`, `PlaylistTrackSchema`, `CharacterSheetSchema`, `AudioProfileSchema`, `MixInfoSchema`, … | DATA_ENGINE_REFERENCE.md → Utilities |
55
+
56
+ ## Mixes — the subtle part
57
+
58
+ - A playlist **entry** pins a mix via `selected_mix` on the track wrapper. Pin matching is **exact and case-sensitive** — `'default'`, or a name matching nothing, means unpinned; legacy `Selected Mix` attribute is the fallback. A pinned track's `audio_url` (and `audio_url_lossless`) are repointed at parse time, so it just plays. `getTracks`/`getFullTracks` apply pins on the raw path too.
59
+ - **User choice after parse** is the tolerant path over `track.extras.mixes`: `findMixByName(mixes, name, { prefer, aliases, caseInsensitive })` and `selectMix(track, name)` — case-insensitive, trimmed, alias-aware, exact names always win. `'tv mix'` finds Karaoke, which is its own concept, **never** an instrumental. One name can ship twice (lossy + lossless master): `prefer` defaults to `'lossy'`; `getUniqueMixes`/`getPreferredMixByQuality` handle grouping. Pass `conditionsContext` to `selectMix` to enforce a gated mix's conditions at choice time.
60
+ - Audio/mix URIs are **not** resolved at parse time (only images, and only with `resolveImageUrls: true`). `resolveMixUrl(mix)` gateway-resolves for you and follows metadata-JSON uris (`application/json`) one hop to the real audio file.
61
+
62
+ ## Cross-cutting rules
63
+
64
+ - **Determinism is the contract.** `generateSeed`/`deriveSeed` → `SeededRNG` (generation) and `SeededDiceRoller` (combat dice): same seed + same inputs = byte-identical output. This is why characters are cacheable per track id.
65
+ - **Leveling config:** `LevelUpProcessor.setUncappedConfig()` is genuinely global (set before leveling uncapped characters). XP math is otherwise **per-instance**: `new XPCalculator({ xp_per_second, activity_bonuses })`, optionally handed to `new SessionTracker(calculator)` — `mergeProgressionConfig()` is a stateless merge helper, not global state.
66
+ - **Extensions are runtime-only.** Nothing persists across restarts; re-register on boot or round-trip `exportCustomData()`.
67
+ - **No `src` ships in the package** — consumers get built `dist` (plus `docs/`, `bin/`, `skills/`, `llms.txt`). Consumers on `file:` deps read built dist — rebuild the engine (`npm run build`) after source changes, then restart the consumer's dev server (webpack does not invalidate `file:` symlink targets).
68
+ - **Environment:** audio analysis + beat detection need Web Audio (browser, or the `web-audio-api` polyfill in Node); the gateway manager persists state to `localStorage` (shim it server-side); ML models fetch from Arweave at runtime.
69
+ - **Sensors are optional.** Env keys: `WEATHER_API_KEY`, `STEAM_API_KEY`, `STEAM_USER_ID`, `XP_MAX_MODIFIER`; sunrise/sunset math needs no key.