{"_id":"@alexisferrada/trackai-lib","_rev":"2-1d9e7145d6db76cb84bd553ea2b4973b","name":"@alexisferrada/trackai-lib","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@alexisferrada/trackai-lib","version":"1.0.0","keywords":["serato","serato-dj","serato-dj-pro","master.sqlite","sqlite","dj","camelot","harmonic-mixing","crates","cue-points","trackai"],"author":{"name":"Alexis P. Ferrada"},"license":"MIT","_id":"@alexisferrada/trackai-lib@1.0.0","maintainers":[{"name":"alexisferrada","email":"alexispferrada@gmail.com"}],"dist":{"shasum":"f7995f18f981f9b7e0fbb3ce045a1c5b2fba724c","tarball":"https://registry.npmjs.org/@alexisferrada/trackai-lib/-/trackai-lib-1.0.0.tgz","fileCount":13,"integrity":"sha512-UVrgKbNnfgvrKur872NtiawjKmTTDnPrPpr6m7mkHkCmbtWgNPlTE0ACyNnk/iCQidsrRvsySDuFFSmuPge65A==","signatures":[{"sig":"MEUCIBFgdRZENAS/Zwgt3pvfMFuax+yZ/Hh3qUUdr8thcnEqAiEAmMr6qemMGLonc4e6ijPz6BsFcgMXZYte4PIO+93V1Cg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78694},"main":"src/index.js","engines":{"node":">=16"},"gitHead":"f61767ef72856d23d567c8785c0aeb7a06acaec9","scripts":{"test":"jest"},"_npmUser":{"name":"alexisferrada","email":"alexispferrada@gmail.com"},"_npmVersion":"11.16.0","description":"Open core de TrackAI: lectura de la base de datos de Serato DJ Pro (master.sqlite), crates, cue points (Serato Markers2) y motor armónico Camelot. Todo en solo lectura.","directories":{},"_nodeVersion":"26.3.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/trackai-lib_1.0.0_1785683531113_0.09501513861456212","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@alexisferrada/trackai-lib","version":"1.0.1","description":"Open core de TrackAI: lectura de la base de datos de Serato DJ Pro (master.sqlite), crates, cue points (Serato Markers2) y motor armónico Camelot. Todo en solo lectura.","main":"src/index.js","publishConfig":{"access":"public"},"scripts":{"test":"jest"},"keywords":["serato","serato-dj","serato-dj-pro","master.sqlite","sqlite","dj","camelot","harmonic-mixing","crates","cue-points","trackai"],"author":{"name":"Alexis P. Ferrada"},"license":"MIT","engines":{"node":">=16"},"devDependencies":{"jest":"^29.7.0"},"gitHead":"597a86b9ddcc879b14a455227e2dd65cc33ad0f1","_id":"@alexisferrada/trackai-lib@1.0.1","_nodeVersion":"26.3.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-WF6C7cWygy9jOJkDlKSw2hIab7C9AflEVjroJiX0TIbiNZTz6uxkfAVUduZ7dSgKxTpIJpHiVeDZIIuUKMkk8w==","shasum":"9ac3ab8cfa276f06da204e7aac5c3c70a6fd7a31","tarball":"https://registry.npmjs.org/@alexisferrada/trackai-lib/-/trackai-lib-1.0.1.tgz","fileCount":13,"unpackedSize":78743,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5DOjB6wSbZeZ42Bdaj2+SlU3Tl15fiPE/8aWiZsGicwIhAKRA3OTjtw6Eg/z9Pf0k0di24oCOR+X9ql6Rypdqk+7P"}]},"_npmUser":{"name":"alexisferrada","email":"alexispferrada@gmail.com"},"directories":{},"maintainers":[{"name":"alexisferrada","email":"alexispferrada@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/trackai-lib_1.0.1_1785683826244_0.006600658479779309"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T15:12:11.008Z","modified":"2026-08-02T15:17:06.537Z","1.0.0":"2026-08-02T15:12:11.253Z","1.0.1":"2026-08-02T15:17:06.384Z"},"author":{"name":"Alexis P. Ferrada"},"license":"MIT","keywords":["serato","serato-dj","serato-dj-pro","master.sqlite","sqlite","dj","camelot","harmonic-mixing","crates","cue-points","trackai"],"description":"Open core de TrackAI: lectura de la base de datos de Serato DJ Pro (master.sqlite), crates, cue points (Serato Markers2) y motor armónico Camelot. Todo en solo lectura.","maintainers":[{"name":"alexisferrada","email":"alexispferrada@gmail.com"}],"readme":"# trackai-lib\n\n**Open core de TrackAI** — librería en JavaScript puro para leer la base de datos de **Serato DJ Pro** y su ecosistema:\n\n- 📚 `master.sqlite` (SQLite): biblioteca `asset`, historial `history_entry` / `history_session`, play counts\n- 📦 Crates (`~/Music/_Serato_/Subcrates/*.crate`): formato binario tag/length\n- 📍 Cue points (`Serato Markers2`) y **beatgrid** (`Serato BeatGrid`) en MP3/AIFF (ID3v2 GEOB), **FLAC** (VORBIS_COMMENT) y **M4A/MP4** (atoms `----` de `com.serato.dj`)\n- 🎼 Motor armónico Camelot: clasificación de transiciones + compatibilidad de BPM\n\n**Todo en SOLO LECTURA** — nunca modifica tu biblioteca de Serato. Probado contra Serato DJ Pro 4.x en macOS y Windows.\n\n## Por qué existe\n\nEsta es la parte pública de [TrackAI](https://trackai.cl), el copiloto de mezcla en vivo para Serato DJ que lee en tiempo real lo que estás tocando y te sugiere la mejor próxima canción (BPM + armonía + crates + historial). TrackAI usa esta librería para todo lo que sabe de Serato.\n\n## Instalación\n\n```bash\ngit clone https://github.com/alexispferrada-wq/trackai-lib.git\ncd trackai-lib\nnpm install\n```\n\nO como paquete npm: `npm install @alexisferrada/trackai-lib`.\n\nSin dependencias de runtime (solo `jest` para tests). Requiere `sqlite3` en el PATH (macOS lo trae en `/usr/bin/sqlite3`; en Windows usa `bin/win32/sqlite3.exe` de tu instalación o el PATH).\n\n## Uso rápido\n\n```js\nconst { serato, crates, seratoTags, harmonic } = require('@alexisferrada/trackai-lib');\n\n// 1) ¿Qué estás tocando ahora en Serato?\nconst np = serato.nowPlaying();\nconsole.log(np.current); // { title, artist, bpm, key, ... }\n\n// 2) Toda tu biblioteca (solo lectura)\nconst tracks = serato.loadLibrary();\nconsole.log(tracks.length, 'tracks en tu biblioteca');\n\n// 3) Tus crates\nconst c = crates.loadCrates();\nconsole.log(c.crateNames); // ['Reggaeton', 'Oldschool', ...]\n\n// 4) Cue points de un MP3 (Serato Markers2)\nconst cues = seratoTags.readCues('/path/to/track.mp3');\nconsole.log(cues); // { cues: [{ index, posMs, color, name }], firstCueMs, lastCueMs }\n\n// 5) Beatgrid (MP3/AIFF/FLAC/M4A/MP4) — posiciones de beats + BPM\nconst bg = seratoTags.readBeatgrid('/path/to/track.flac');\nconsole.log(bg); // { markers: [{ position, beatsToNext } | { position, bpm }] }\n\n// 6) Transiciones armónicas (rueda Camelot)\nconst t = harmonic.classifyTransition('8A', '9A');\nconsole.log(t.type); // 'energy_up'\nconsole.log(harmonic.bpmCompat(125, 125.5, 'auto', 6)); // { compatible: true, ... }\n```\n\n## Cómo lee la base de datos de Serato\n\nSerato DJ Pro 4.x guarda biblioteca e historial en:\n\n```\nmacOS:   ~/Library/Application Support/Serato/Library/master.sqlite\nWindows: %LOCALAPPDATA%\\Serato\\Library\\master.sqlite\n```\n\nTablas principales:\n\n| Tabla | Contenido |\n|-------|-----------|\n| `asset` | Biblioteca completa (name, artist, bpm, key, genre, album, portable_id, `dj_play_count`, ...) |\n| `history_session` | Sesiones de reproducción (fecha, hora, duración) |\n| `history_entry` | Cada track reproducido (start_time, end_time, deck, session_id, portable_id) |\n\nDetalles que aprendimos al construir esto:\n\n- **`portable_id`** es la llave para cruzar biblioteca ↔ historial ↔ crates.\n- **`dj_play_count`** es el play count nativo en Serato 4 (en versiones viejas se deriva contando `history_entry`).\n- Los nombres de columnas **cambian entre versiones de Serato** → la librería usa `PRAGMA table_info` y selecciona solo las columnas que existen (ver `detectAssetFields`).\n- `master.sqlite` se lee **en vivo**: se copia a una sombra en `os.tmpdir()` con WAL checkpoint para no bloquear a Serato ni arriesgar corrupción.\n\nLos crates viven en `~/Music/_Serato_/Subcrates/*.crate` (formato binario `tag(4) + len(uint32 BE) + payload`, chunks `otrk`/`ptrk` con rutas en UTF-16 BE). Los cue points están en el frame **GEOB** de ID3v2 llamado `Serato Markers2`, codificado en base64.\n\n## Configuración\n\n| Variable | Efecto |\n|----------|--------|\n| `SERATO_LIB_DIR` | Carpeta para config/caché (default `~/.trackai`). Útil si tu app quiere aislar el estado. |\n\nConfig JSON en `~/.trackai/config.json` (o `$SERATO_LIB_DIR/config.json`):\n```json\n{ \"customSeratoDbPath\": \"/ruta/manual/master.sqlite\", \"customSeratoCratesDir\": \"/ruta/crates\" }\n```\n\n## Tests\n\n```bash\nnpm test   # 8 tests: Camelot, BPM compat, cues Markers2 con MP3 sintético\n```\n\n## Estructura\n\n```\nsrc/\n  serato.js        # master.sqlite: ahora tocando, biblioteca, play stats (solo lectura)\n  serato-detect.js # auto-detección de instalaciones de Serato (local/nube/externo)\n  crates.js        # lectura de crates .crate\n  seratoTags.js    # cue points Serato Markers2 (ID3v2 GEOB)\n  harmonic.js      # rueda Camelot + compatibilidad BPM\n  logger.js        # log a ~/Documents/TrackAI-Logs/\n  index.js         # exports\ntest/\n  harmonic.test.js\n  seratoTags.test.js\n```\n\n## Licencia\n\nMIT — ver [LICENSE](LICENSE).\n\n---\n\nHecho con 🎧 para la comunidad de DJs. Si construyes algo con esto, [TrackAI](https://trackai.cl) se hace con [la app completa](https://trackai.cl): IA que aprende tus transiciones, carga automática al plato y análisis en vivo.\n","readmeFilename":"README.md"}