Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorg demo #1

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

Reorg demo #1

wants to merge 21 commits into from

Conversation

ianmacartney
Copy link
Contributor

I made some big changes:

  • separating into a low-level "positions" layer, with a "cursors" layer above
  • pulled the positions layer to be (mostly) parametrized so it could be in a npm package
  • organized the cursors, but haven't parametrized them (still depending on Id, Doc, api, etc)
  • I decoupled the sessions from cursors that the positions layer, but still have some work to make it decoupled at the cursors level. The idea is you could specify a customMutation and the mapping from ctx -> id to get the logged-in or sessions user.
  • At this point the hope is that a new user would just have to implement App.tsx, Cursor.tsx, re-export some functions from lib/cursors.ts (parametrized by functions to customize for sessions), spread in some tables, and customize some hooks on the client with the exported endpoints.

NOTE: It isn't working well rn - bugs I haven't investigated, but the sketch is there.

I still have some concerns:

  • The function count will be n^2 per refresh period for n users on a page, since we count those even for cache hits.

pseudocode of layers:

// cursors layer: cursors, zones
// (zone) => other id[]
// (id) => persist
// write: cursor -> position flow, position -> create cursor

// server-side
const { upsertCursor, listCursors } = makeCursorEndpoints(
  customMutation,  // e.g. mutationWithSession
  (ctx) => id, // from mutation ctx to user id - auth or sessions
  (id) => metadata
)

const cursors = await getCursors(ctx, zone);

const { SharedCursorProvider, useCursors } = makeCursorHooks(customMutation, upsertCursor, listCursors)

<SharedCursorProvider zone={""}>{app}</SharedCursorProvider>
const { mine, others, currentPosition, onMove } = useSharedCursors(); // or zone,id from context

<Cursor position={x, y} ...style/>
<OtherCursor positionId={other.positionId} ...others/>

// positions layer: positionId, buffer, positions, history, replay, applyOperations
// (positionId) => data replay, (data, positionId) => update data
// write: position -> render, (new pos) => ...update, create position ahead of time
const { loadPosition, updatePositionBatch, createPosition } = makePositionFunctions()
const { usePositionTracking, usePositionReplay } = makePositionHooks(loadPosition, updatePositionBatch);
const {currentPosition, onMove} = usePositionTracking(positionId)
const { x, y } = usePositionReplay(positionId)

Some scratch notes here: https://www.notion.so/convex-dev/Shared-cursors-keep-track-of-path-not-just-latest-cursor-and-flush-deltas-c35caece41be4c91992b6e6addfde8a3?pvs=4

@ianmacartney ianmacartney requested a review from sujayakar January 9, 2024 10:28
Copy link
Contributor

@sujayakar sujayakar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks amazing!

want to make the call on whether we recommend using this or liveblocks?

I can help with optimistic updates or perf tuning if we want to go down this path, let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants