Music streaming on ATProto!
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(lexicons): split `playlist.tracks` into `playlistTrack` record

+255 -57
+1 -2
README.md
··· 17 17 - [ ] Experimental Lexicons 18 18 - [x] Records 19 19 - [ ] Queries 20 - - [ ] PoC Node/Bun AppView (eventually I want to rewrite in something like Rust 21 - or Elixir. TBD) 20 + - [ ] AppView (Elixir) 22 21 - [ ] Clients
+49 -1
bun.lock
··· 5 5 "name": "comet", 6 6 "devDependencies": { 7 7 "@types/bun": "latest", 8 + "pino-pretty": "^13.0.0", 8 9 "prettier": "^3.5.3", 9 10 "prettier-plugin-svelte": "^3.4.0", 10 11 "prettier-plugin-tailwindcss": "^0.6.11", ··· 58 59 "@atcute/atproto": "^3.0.2", 59 60 "@atcute/bluesky": "^3.0.2", 60 61 "@atcute/client": "^4.0.2", 61 - "@comet/lexicons": "workspace:", 62 + "@comet/lexicons": "workspace:*", 63 + "rambdax": "^11.3.1", 62 64 }, 63 65 "devDependencies": { 64 66 "@types/bun": "latest", ··· 321 323 322 324 "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], 323 325 326 + "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], 327 + 324 328 "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], 325 329 326 330 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], ··· 347 351 348 352 "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 349 353 354 + "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], 355 + 350 356 "comet": ["comet@workspace:apps/frontend"], 351 357 352 358 "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], ··· 357 363 358 364 "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], 359 365 366 + "dateformat": ["dateformat@4.6.3", "", {}, "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="], 367 + 360 368 "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], 361 369 362 370 "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], ··· 366 374 "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], 367 375 368 376 "devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="], 377 + 378 + "end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="], 369 379 370 380 "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="], 371 381 ··· 397 407 398 408 "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], 399 409 410 + "fast-copy": ["fast-copy@3.0.2", "", {}, "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ=="], 411 + 400 412 "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 401 413 402 414 "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], ··· 404 416 "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 405 417 406 418 "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], 419 + 420 + "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], 407 421 408 422 "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], 409 423 ··· 431 445 432 446 "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], 433 447 448 + "help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="], 449 + 434 450 "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 435 451 436 452 "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], ··· 453 469 454 470 "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], 455 471 472 + "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], 473 + 456 474 "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], 457 475 458 476 "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], ··· 507 525 508 526 "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], 509 527 528 + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], 529 + 510 530 "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], 511 531 512 532 "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], ··· 523 543 524 544 "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 525 545 546 + "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], 547 + 548 + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], 549 + 526 550 "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 527 551 528 552 "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], ··· 539 563 540 564 "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], 541 565 566 + "pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], 567 + 568 + "pino-pretty": ["pino-pretty@13.0.0", "", { "dependencies": { "colorette": "^2.0.7", "dateformat": "^4.6.3", "fast-copy": "^3.0.2", "fast-safe-stringify": "^2.1.1", "help-me": "^5.0.0", "joycon": "^3.1.1", "minimist": "^1.2.6", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pump": "^3.0.0", "secure-json-parse": "^2.4.0", "sonic-boom": "^4.0.1", "strip-json-comments": "^3.1.1" }, "bin": { "pino-pretty": "bin.js" } }, "sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA=="], 569 + 542 570 "postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="], 543 571 544 572 "postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="], ··· 556 584 "prettier-plugin-svelte": ["prettier-plugin-svelte@3.4.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ=="], 557 585 558 586 "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.6.11", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA=="], 587 + 588 + "pump": ["pump@3.0.2", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw=="], 559 589 560 590 "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 561 591 562 592 "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 563 593 594 + "rambdax": ["rambdax@11.3.1", "", {}, "sha512-ecsDpTQZuzZD16hPGpkja3klaho4I0tRp5IkjmUUrR7tNnw5RP9K/eiPfHev4HrRNr4OoUetIL/OOWFmeYls7A=="], 595 + 564 596 "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], 565 597 566 598 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], ··· 575 607 576 608 "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], 577 609 610 + "secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="], 611 + 578 612 "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], 579 613 580 614 "set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="], ··· 584 618 "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 585 619 586 620 "sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="], 621 + 622 + "sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="], 587 623 588 624 "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], 589 625 626 + "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], 627 + 590 628 "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 591 629 592 630 "style-to-object": ["style-to-object@1.0.8", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g=="], ··· 641 679 642 680 "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], 643 681 682 + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], 683 + 644 684 "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], 645 685 646 686 "yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="], ··· 648 688 "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], 649 689 650 690 "zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="], 691 + 692 + "@comet/lexicons/@types/bun": ["@types/bun@1.2.14", "", { "dependencies": { "bun-types": "1.2.14" } }, "sha512-VsFZKs8oKHzI7zwvECiAJ5oSorWndIWEVhfbYqZd4HI/45kzW7PN2Rr5biAzvGvRuNmYLSANY+H59ubHq8xw7Q=="], 651 693 652 694 "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], 653 695 ··· 675 717 676 718 "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 677 719 720 + "test/@types/bun": ["@types/bun@1.2.14", "", { "dependencies": { "bun-types": "1.2.14" } }, "sha512-VsFZKs8oKHzI7zwvECiAJ5oSorWndIWEVhfbYqZd4HI/45kzW7PN2Rr5biAzvGvRuNmYLSANY+H59ubHq8xw7Q=="], 721 + 722 + "@comet/lexicons/@types/bun/bun-types": ["bun-types@1.2.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-Kuh4Ub28ucMRWeiUUWMHsT9Wcbr4H3kLIO72RZZElSDxSu7vpetRvxIUDUaW6QtaIeixIpm7OXtNnZPf82EzwA=="], 723 + 678 724 "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 725 + 726 + "test/@types/bun/bun-types": ["bun-types@1.2.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-Kuh4Ub28ucMRWeiUUWMHsT9Wcbr4H3kLIO72RZZElSDxSu7vpetRvxIUDUaW6QtaIeixIpm7OXtNnZPf82EzwA=="], 679 727 } 680 728 }
+1
package.json
··· 3 3 "version": "1.0.0", 4 4 "devDependencies": { 5 5 "@types/bun": "latest", 6 + "pino-pretty": "^13.0.0", 6 7 "prettier": "^3.5.3", 7 8 "prettier-plugin-svelte": "^3.4.0", 8 9 "prettier-plugin-tailwindcss": "^0.6.11"
+1 -5
packages/lexicons/defs/sh/comet/v0/feed/playlist.json
··· 8 8 "key": "tid", 9 9 "record": { 10 10 "type": "object", 11 - "required": ["tracks", "title", "type", "createdAt"], 11 + "required": ["title", "type", "createdAt"], 12 12 "properties": { 13 - "tracks": { 14 - "type": "array", 15 - "items": { "type": "string", "format": "at-uri" } 16 - }, 17 13 "image": { 18 14 "type": "blob", 19 15 "description": "Image to be displayed representing the playlist.",
+26
packages/lexicons/defs/sh/comet/v0/feed/playlistTrack.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.comet.v0.feed.playlistTrack", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A link between a Comet track and a playlist.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": ["track", "playlist", "position"], 12 + "properties": { 13 + "track": { 14 + "type": "string", 15 + "format": "at-uri" 16 + }, 17 + "playlist": { 18 + "type": "string", 19 + "format": "at-uri" 20 + }, 21 + "position": { "type": "integer", "minimum": 0 } 22 + } 23 + } 24 + } 25 + } 26 + }
+1
packages/lexicons/src/index.ts
··· 8 8 export * as ShCometV0FeedLike from "./types/sh/comet/v0/feed/like.js"; 9 9 export * as ShCometV0FeedPlay from "./types/sh/comet/v0/feed/play.js"; 10 10 export * as ShCometV0FeedPlaylist from "./types/sh/comet/v0/feed/playlist.js"; 11 + export * as ShCometV0FeedPlaylistTrack from "./types/sh/comet/v0/feed/playlistTrack.js"; 11 12 export * as ShCometV0FeedRepost from "./types/sh/comet/v0/feed/repost.js"; 12 13 export * as ShCometV0FeedTrack from "./types/sh/comet/v0/feed/track.js"; 13 14 export * as ShCometV0RichtextFacet from "./types/sh/comet/v0/richtext/facet.js";
-1
packages/lexicons/src/types/sh/comet/v0/feed/playlist.ts
··· 43 43 /*#__PURE__*/ v.stringLength(1, 2560), 44 44 /*#__PURE__*/ v.stringGraphemes(0, 256), 45 45 ]), 46 - tracks: /*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()), 47 46 type: /*#__PURE__*/ v.string< 48 47 | "sh.comet.v0.feed.playlist#album" 49 48 | "sh.comet.v0.feed.playlist#compilation"
+27
packages/lexicons/src/types/sh/comet/v0/feed/playlistTrack.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.record( 6 + /*#__PURE__*/ v.tidString(), 7 + /*#__PURE__*/ v.object({ 8 + $type: /*#__PURE__*/ v.literal("sh.comet.v0.feed.playlistTrack"), 9 + playlist: /*#__PURE__*/ v.resourceUriString(), 10 + position: /*#__PURE__*/ v.integer(), 11 + track: /*#__PURE__*/ v.resourceUriString(), 12 + }), 13 + ); 14 + 15 + type main$schematype = typeof _mainSchema; 16 + 17 + export interface mainSchema extends main$schematype {} 18 + 19 + export const mainSchema = _mainSchema as mainSchema; 20 + 21 + export interface Main extends v.InferInput<typeof mainSchema> {} 22 + 23 + declare module "@atcute/lexicons/ambient" { 24 + interface Records { 25 + "sh.comet.v0.feed.playlistTrack": mainSchema; 26 + } 27 + }
+147 -47
packages/test/index.ts
··· 1 - import { Client, CredentialManager, ok } from "@atcute/client"; 1 + import { 2 + Client, 3 + CredentialManager, 4 + ok, 5 + simpleFetchHandler, 6 + } from "@atcute/client"; 2 7 3 8 import type {} from "@atcute/bluesky"; 4 - import type {} from "@atcute/atproto"; 5 - import { ShCometV0FeedPlaylist, ShCometV0FeedTrack } from "@comet/lexicons"; 9 + import type { ComAtprotoRepoApplyWrites } from "@atcute/atproto"; 10 + import { 11 + ShCometV0FeedPlaylist, 12 + ShCometV0FeedPlaylistTrack, 13 + ShCometV0FeedTrack, 14 + } from "@comet/lexicons"; 15 + import type { ResourceUri } from "@atcute/lexicons"; 16 + import { splitEvery } from "rambdax"; 6 17 7 18 // const manager = new CredentialManager({ service: "https://pds.ovy.sh" }); 8 19 const manager = new CredentialManager({ service: "https://bsky.social" }); 9 20 const rpc = new Client({ handler: manager }); 10 21 22 + interface Type { 23 + $type: `${string}.${string}.${string}`; 24 + [key: string]: any; 25 + } 26 + 27 + const createRecord = <T extends Type>(record: T) => 28 + ok( 29 + rpc.post("com.atproto.repo.createRecord", { 30 + input: { collection: record.$type, repo: manager.session!.did, record }, 31 + }), 32 + ); 33 + 11 34 await manager.login({ 12 35 identifier: Bun.env.COMET_TEST_IDENT!, 13 36 password: Bun.env.COMET_TEST_PASSWORD!, 14 37 }); 15 38 16 - // const inputAudio = Bun.file("./test-track.opus"); 17 - // const { blob: audio } = await ok( 18 - // rpc.post("com.atproto.repo.uploadBlob", { input: inputAudio }), 19 - // ); 39 + /** Upload a test audio blob. */ 40 + const uploadAudio = async () => { 41 + const inputAudio = Bun.file("./test-track.opus"); 42 + const { blob: audio } = await ok( 43 + rpc.post("com.atproto.repo.uploadBlob", { input: inputAudio }), 44 + ); 45 + console.log(audio); 46 + }; 47 + 48 + /** Create a test track record. */ 49 + const createTrack = async () => { 50 + const audio = { 51 + $type: "blob", 52 + ref: { 53 + $link: "bafkreifiu63dr52dxzrurnspha5xvzlzqkho3hdzdhu6zvthrrvdpd6yve", 54 + }, 55 + mimeType: "audio/opus", 56 + size: 3349806, 57 + } as const; 20 58 21 - // const audio = { 22 - // $type: "blob", 23 - // ref: { 24 - // $link: "bafkreifiu63dr52dxzrurnspha5xvzlzqkho3hdzdhu6zvthrrvdpd6yve", 25 - // }, 26 - // mimeType: "audio/opus", 27 - // size: 3349806, 28 - // } as const; 59 + const track: ShCometV0FeedTrack.Main = { 60 + $type: "sh.comet.v0.feed.track", 61 + audio, 62 + title: "Testing Track 6", 63 + createdAt: new Date().toJSON(), 64 + }; 29 65 30 - // const track: ShCometV0FeedTrack.Main = { 31 - // $type: "sh.comet.v0.feed.track", 32 - // audio, 33 - // title: "Testing Track 5", 34 - // createdAt: new Date().toJSON(), 35 - // }; 66 + const response = await createRecord(track); 67 + console.log(response); 68 + }; 36 69 37 - // const response = await ok( 38 - // rpc.post("com.atproto.repo.createRecord", { 39 - // input: { 40 - // collection: track.$type, 41 - // repo: manager.session!.did, 42 - // record: track, 43 - // }, 44 - // }), 45 - // ); 70 + /** Create a test playlist */ 71 + const createPlaylist = async () => { 72 + const playlistRecord: ShCometV0FeedPlaylist.Main = { 73 + $type: "sh.comet.v0.feed.playlist", 74 + title: "Testing Playlist", 75 + type: "sh.comet.v0.feed.playlist#playlist", 76 + createdAt: new Date().toJSON(), 77 + tags: ["testing", "music"], 78 + }; 46 79 47 - const playlist: ShCometV0FeedPlaylist.Main = { 48 - $type: "sh.comet.v0.feed.playlist", 49 - tracks: [ 80 + const { uri: playlist } = await createRecord(playlistRecord); 81 + console.log("created playlist", playlist); 82 + 83 + const collection = "sh.comet.v0.feed.playlistTrack"; 84 + const tracks = [ 50 85 "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2gsib2s2e", 51 86 "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2muqtnu2w", 52 87 "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2njjm6p2y", 53 88 "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2nrehj52o", 54 89 "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2nnacyg23", 55 - ], 56 - title: "Testing Playlist", 57 - type: "sh.comet.v0.feed.playlist#playlist", 58 - createdAt: new Date().toJSON(), 90 + ] as ResourceUri[]; 91 + 92 + const created = await ok( 93 + rpc.post("com.atproto.repo.applyWrites", { 94 + input: { 95 + repo: manager.session!.did, 96 + writes: tracks.map( 97 + (track, position) => 98 + ({ 99 + $type: "com.atproto.repo.applyWrites#create", 100 + collection, 101 + value: { 102 + $type: collection, 103 + playlist, 104 + track, 105 + position, 106 + } satisfies ShCometV0FeedPlaylistTrack.Main, 107 + }) satisfies ComAtprotoRepoApplyWrites.Create, 108 + ), 109 + }, 110 + }), 111 + ); 112 + 113 + console.log(created); 114 + console.log("created playlist tracks"); 115 + }; 116 + 117 + /** Create a veeeeery large test playlist. */ 118 + const createLargePlaylist = async () => { 119 + const playlistRecord: ShCometV0FeedPlaylist.Main = { 120 + $type: "sh.comet.v0.feed.playlist", 121 + title: "Very lorge playlist", 122 + type: "sh.comet.v0.feed.playlist#compilation", 123 + createdAt: new Date().toJSON(), 124 + }; 125 + 126 + const { uri: playlist } = await createRecord(playlistRecord); 127 + console.log("created playlist", playlist); 128 + 129 + const collection = "sh.comet.v0.feed.playlistTrack"; 130 + const tracks = new Array(2500) 131 + .fill( 132 + "at://did:plc:jrrhosrfzgjf6v4oydav6ftb/sh.comet.v0.feed.track/3lpq2gsib2s2e" as ResourceUri, 133 + ) 134 + .map( 135 + (track, position) => 136 + ({ 137 + $type: "com.atproto.repo.applyWrites#create", 138 + collection, 139 + value: { 140 + $type: collection, 141 + playlist, 142 + track, 143 + position, 144 + } satisfies ShCometV0FeedPlaylistTrack.Main, 145 + }) satisfies ComAtprotoRepoApplyWrites.Create, 146 + ); 147 + 148 + for (const chunk of splitEvery(100, tracks)) { 149 + // TODO: don't hit ratelimit 150 + await ok( 151 + rpc.post("com.atproto.repo.applyWrites", { 152 + input: { 153 + repo: manager.session!.did, 154 + writes: chunk, 155 + }, 156 + }), 157 + ); 158 + console.log("wrote chunk"); 159 + } 160 + 161 + console.log("created playlist tracks"); 59 162 }; 60 163 61 - const response = await ok( 62 - rpc.post("com.atproto.repo.createRecord", { 63 - input: { 64 - collection: playlist.$type, 65 - repo: manager.session!.did, 66 - record: playlist, 67 - }, 68 - }), 69 - ); 164 + // const testQuery = async () => { 165 + // const x = await ok(rpc.get("sh.comet.v0.actor.getProfile", {})); 166 + // }; 70 167 71 - console.log(response); 168 + // await uploadAudio(); 169 + // await createTrack(); 170 + // await createPlaylist(); 171 + await createLargePlaylist();
+2 -1
packages/test/package.json
··· 13 13 "@atcute/atproto": "^3.0.2", 14 14 "@atcute/bluesky": "^3.0.2", 15 15 "@atcute/client": "^4.0.2", 16 - "@comet/lexicons": "workspace:*" 16 + "@comet/lexicons": "workspace:*", 17 + "rambdax": "^11.3.1" 17 18 } 18 19 }