Repository navigation
feat(endpoint-microsub): PR 1 - Core Microsub server with channels and timeline - #944
Conversation
|
Correcting my comment I had the shape of this right but missed the history, which matters for how it gets fixed.
More importantly, the fix on
#914 then did it your way. The branch already had the one-line, non-self-closing form you asked for — all it lacked was the marker, so anyone clearing this with Now fixed on That said, the retarget question still stands on its own merits: |
|
Finally !! damned this was convoluted to make it work but now we're good to go ! |
83593bf to
288f026
Compare
|
@rmdes I’ve rebased this against
I’d like to get this into the next beta release, Beta 30, if possible. |
4f16c2f to
d52ee6f
Compare
…imeline This PR adds the foundational Microsub endpoint with: **Microsub API:** - GET/POST ?action=channels - list, create, update, delete, reorder channels - GET/POST ?action=timeline - list items, mark read/unread, remove **Storage:** - MongoDB collections for channels and items - Cursor-based pagination for timeline - Per-user channel ordering and read state tracking **Features:** - Follows Microsub spec for channel and timeline actions - Testable with existing Microsub clients (Monocle, Indigenous, etc.) - Multi-user support via userId from session/token This is PR 1 of 6 for the Microsub implementation. Future PRs will add: - PR 2: Feed discovery and subscription - PR 3: Feed fetching and parsing - PR 4: Reader UI - PR 5: Compose and Micropub integration - PR 6: Settings and filtering Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The plug-in declared mongodb ^6.0.0 while indiekit declares ^7.4.0, so npm installed a nested copy of the driver. ObjectId values created by the plug-in came from bson 6 but were passed to collections served by bson 7, which threw BSONVersionError in markItemsRead, markItemsUnread and removeItems.
Fixes unicorn/prefer-await, unicorn/prefer-number-coercion, unicorn/consistent-boolean-name, unicorn/no-computed-property-existence-check and jsdoc/reject-function-type, and removes unused eslint-disable directives. Satisfying unicorn/prefer-await means init() now awaits index creation rather than leaving it to run in the background, so plug-in initialisation waits for indexes to be created. Errors are still caught and warned about, and the plug-in loader already awaits init().
Unit tests cover lib/utils and lib/storage, mirroring the structure of lib/. Controllers are covered by integration tests, as in other endpoint plug-ins.
Replaces the direct mongodb import with @indiekit/util's getObjectId, as suggested in review. The plug-in no longer declares mongodb at all, so its driver version can't drift from the host's — @indiekit/util owns that pin. This supersedes the earlier version bump, which fixed the same mismatch by matching the pin by hand and would have needed maintaining.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGHR7MuyvBaDbAFfAGUxeT
`generateChannelUid` built its own string from `Math.random()`. `randomString` from `@indiekit/util` does the same job with `randomBytes`, which is what a channel identifier should be using. That changes the alphabet from `[a-z0-9]` to base64url, so the tests asserting lowercase now assert URL-safe characters instead — that was the actual requirement, since a uid appears in Microsub request URLs. Replaces the one `console.info` in the package with `debug`, matching endpoint-micropub and endpoint-media, and declares the dependency. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGHR7MuyvBaDbAFfAGUxeT
…longer exports getObjectId
d52ee6f to
7992fbe
Compare
|
Docs PR for the specifications page: #978. |
Timeline items get an `id`, a UUIDv7 stamped with their publication date, listed and paged through util's `getCursor` like posts and media are since #975. The cursor gains two options for it: a filter every page is confined to (the channel) and the key path to order on. Clients see that id as the Microsub `_id` and can mark or remove items by it; the Mongo `_id` no longer leaves the storage layer. The endpoint's own cursor encoding and query builders go.
Items point at their channel by the channel's uid, the string clients already use, so nothing in the package needs an ObjectId any more: no casting, no mongodb dependency, and indexes on strings only, in line with paginating and indexing on properties.uid elsewhere.
- Errors use the shared localisable strings (BadRequestError.missingParameter, invalidValue, missingProperty) through the localiser the validators now take; channel not found and the name limit are package-scoped locale keys, and the unused title keys are gone. - uuidv7At moves to @indiekit/util, shared by the uid backfill and the Microsub timeline; the channel uid wrapper is a direct randomString(24). - One collections module replaces the two duplicated collection getters. - The user is publication.me: a session carries only a token and a scope, so the fallback chain never found anything else.
|
Both done in this PR now. Timeline items carry an Your review is addressed in 8332296: localisable error strings, |
paulrobertlloyd
left a comment
There was a problem hiding this comment.
Sorry, just a few more issues! 😬
…name the channel variables
…nes like its siblings Other endpoints announce nothing at init and core already logs each collection it adds under debug, so the console lines go; index creation throws like core's does rather than warn and carry on.
9cb2128 to
66802a0
Compare
|
Thanks for much for (the first part of) this contribution @rmdes – we got there eventually! I’ll release this in Beta 30, with the following PRs to be included in future beta releases. 🚀 |
Part one of seven: the core Microsub server — channels and the timeline. Scoped deliberately small so it is reviewable; the remaining six are written and follow behind it.
+3511 / −0across 32 files, all new. No existing behaviour is touched.What it adds
17 test files cover them.
Verification
Green: 895 tests, 894 pass, 0 fail on the full monorepo suite,
endpoint-microsubincluded.Worth stating plainly because it was not true until today. This is the successor to #829, which had carried a red check since February for two reasons, neither in this code:
readKeysecret; the linter step failed and install, lint and the entire test suite were skippedfeat/microsubsat atba8e19a7, the commit that introduced the failingprettier . --checkonpackages/endpoint-share/README.md(style(endpoint-share): format share-url example #910), and never received the fix from style(endpoint-share): keep the share-url example on one line #914Both are now cleared — this branches from this repo, and
feat/microsubcarries #914's fix as ofe4c2821, byte-identical tomain. So the six parts that follow will not inherit a red check either.One open question
Should this target
mainrather thanfeat/microsub? I asked on #829 in August and it got lost in the write-access thread.feat/microsubis 32 commits behindmainand, apart from that one backported fix, has no commits of its own — so if all seven parts land there it will keep drifting. Happy either way; it just needs deciding once rather than seven times.Notes for review
@indiekit/util'sgetObjectIdis used throughout rather than the plug-in declaringmongodbitself, per your note on feat(endpoint-microsub): PR 1 - Core Microsub server with channels and timeline #829 — there is nomongodbdependency here, so nothing to drift when the host's version moves.PASSWORD_SECRETset alongsideSECRET, asbuild.ymldoes. Without it the session-backed tests redirect rather than fail cleanly, which is not obvious from the output.