feat(endpoint-microsub): PR 1 - Core Microsub server with channels and timeline - #829
feat(endpoint-microsub): PR 1 - Core Microsub server with channels and timeline#829rmdes wants to merge 9 commits into
Conversation
c50cd1e to
ee6ae94
Compare
a556cc4 to
4bbc622
Compare
ee6ae94 to
ae01604
Compare
|
Hi @rmdes. Firstly, sorry it’s taken me so long to get back to you on this; life got in the way. I should hopefully now have some time to review/collaborate on this feature. I’ve pushed two extra commits:
Before merging this into
Thanks again for your patience, looking forward to getting this contribution into Indiekit! |
8dfa381 to
5e0b783
Compare
|
Thanks @paulrobertlloyd, and no problem about the delay. I’ve pushed three commits covering both points, plus one fix that writing the tests uncovered. Two things are worth calling out, as neither is obvious from the diff.
|
|
On the MongoDB version mismatch, Right now the MongoDB version used is specified in Am happy to do that as a separate PR if you think that’d help? |
|
thanks, I’d missed it. Pushed a commit that uses it in That supersedes the earlier commit that bumped the pin by hand. Matching the version manually would have worked until the next bump moved it again; not declaring the dependency means there’s nothing left to drift. On moving Both resolve to the same install today since they’re caret ranges on the same major, so nothing is broken. But it’s the same shape of mismatch, and consolidating would leave one place to get it right. Happy either way, and happy to review if you do open that PR. Both of your original points are now addressed:
The failing check is the Localazy step, which needs a |
…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
ff07211 to
dd5b32d
Compare
|
Rebased this locally onto Before I push it, a question: Edited to correct the second half of this comment. I originally wrote that So there is nothing outstanding here from my side. Apologies for the noise — |
paulrobertlloyd
left a comment
There was a problem hiding this comment.
I have a few questions, none of which need to be resolved now.
Before I push it, a question:
feat/microsubis now 32 commits behindmainand has no commits of its own, so should this retarget to main instead?
Let stick to the plan, and have this set of PRs merge into feat/microsub for now. I have rebased that branch with main, but you might need to resolve a conflict before merging this PR.
| @@ -0,0 +1,148 @@ | |||
| /** | |||
There was a problem hiding this comment.
Possibly one for a separate PR, but I wonder if this work could be moved into @indiekit/util and used for pagination on @indkitkit/endpoint-micropub and @indiekit/endpoint-media too. I’d expect all three endpoints to paginate in the same way, and I think there’s a bit of overlap here with the existing getCursor utility in @indiekit/util.
There was a problem hiding this comment.
Worth doing, though not a direct swap: getCursor keys on _id, and Microsub sorts by published time, so these cursors encode {timestamp, id} to break ties between items published in the same second. A shared version would need to handle both orderings.
Happy to take it as a separate PR.
There was a problem hiding this comment.
Brill. No rush, so maybe we can create an issue for this for now, and revisit once this plugin is nearer being released?
`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
dd5b32d to
83593bf
Compare
|
Also rebased onto |
For the next PR, as you are now a member of the |
Thanks — though it looks like I don't have push access yet: I'm an active org member, but not a collaborator on the repo (permissions.push is false). Org membership on its own doesn't grant it, so a team would need write access on the repo, or me adding directly. Happy to test once you've had a chance.
|
|
@rmdes I have no understanding of the byzantine roles and permissions model used by GitHub, but I think you should now have write access. |
|
Confirmed, write access works — thanks. I'll branch directly here for the next one so CI can actually run the tests. |
Summary
This PR adds the foundational Microsub endpoint with channel and timeline management.
What's included
Microsub API:
GET/POST ?action=channels- list, create, update, delete, reorder channelsGET/POST ?action=timeline- list items, mark read/unread, removeStorage:
Features:
How to test
/microsubendpointPR breakdown
This is PR 1 of 6 for the Microsub implementation:
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com