Skip to content

Commit

Permalink
Remove named cursors API
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik Piatek committed Jul 21, 2023
1 parent 953d24e commit 2a95d6c
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 392 deletions.
11 changes: 5 additions & 6 deletions demo/app/components/cursors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ const attachCursors = (space, slideId) => {
const cursorContainer = queryDataId(slideContainer, 'slide-cursor-container');
cursorContainer.innerHTML = '';

const cursor = space.cursors.get(slideId);
const self = space.getSelf();

cursor.on('cursorUpdate', (update) => {
space.cursors.on('cursorsUpdate', (update) => {
let cursorNode: HTMLElement = slideContainer.querySelector(`#cursor-${update.connectionId}`);

const membersOnSlide = space.getMembers().filter((member) => member.location?.slide === slideId);
Expand All @@ -77,15 +76,15 @@ const attachCursors = (space, slideId) => {
const cursorHandlers = {
enter: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'enter' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'enter' } });
},
move: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'move' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'move' } });
},
leave: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'leave' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'leave' } });
},
tabLeft: (event) => {
if (document.visibilityState === 'hidden') {
Expand All @@ -100,7 +99,7 @@ const attachCursors = (space, slideId) => {
document.addEventListener('visibilitychange', cursorHandlers.tabLeft);

return () => {
cursor.off();
space.cursors.off();
slideContainer.removeEventListener('mouseenter', cursorHandlers.enter);
slideContainer.removeEventListener('mousemove', cursorHandlers.move);
slideContainer.removeEventListener('mouseleave', cursorHandlers.leave);
Expand Down
80 changes: 0 additions & 80 deletions src/Cursor.ts

This file was deleted.

20 changes: 8 additions & 12 deletions src/CursorBatching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { CursorUpdate } from './Cursors.js';
import { CURSOR_UPDATE } from './utilities/Constants.js';
import type { StrictCursorsOptions } from './options/CursorsOptions.js';

type OutgoingBuffer = Record<string, Pick<CursorUpdate, 'position' | 'data'>[]>;
type OutgoingBuffer = Pick<CursorUpdate, 'position' | 'data'>[];

export default class CursorBatching {
outgoingBuffers: OutgoingBuffer = {};
outgoingBuffers: OutgoingBuffer = [];

batchTime: number;

Expand All @@ -27,11 +27,11 @@ export default class CursorBatching {
this.batchTime = outboundBatchInterval;
}

pushCursorPosition(name: string, cursor: Pick<CursorUpdate, 'position' | 'data'>) {
pushCursorPosition(cursor: Pick<CursorUpdate, 'position' | 'data'>) {
// Ignore the cursor update if there is no one listening
if (!this.shouldSend) return;
this.hasMovement = true;
this.pushToBuffer(name, cursor);
this.pushToBuffer(cursor);
this.publishFromBuffer(CURSOR_UPDATE);
}

Expand All @@ -41,12 +41,8 @@ export default class CursorBatching {
this.batchTime = (members.length - 1) * this.outboundBatchInterval;
}

private pushToBuffer(key: string, value: Pick<CursorUpdate, 'position' | 'data'>) {
if (this.outgoingBuffers[key]) {
this.outgoingBuffers[key].push(value);
} else {
this.outgoingBuffers[key] = [value];
}
private pushToBuffer(value: Pick<CursorUpdate, 'position' | 'data'>) {
this.outgoingBuffers.push(value);
}

private async publishFromBuffer(eventName: string) {
Expand All @@ -62,10 +58,10 @@ export default class CursorBatching {
return;
}
// Must be copied here to avoid a race condition where the buffer is cleared before the publish happens
const bufferCopy = { ...this.outgoingBuffers };
const bufferCopy = [...this.outgoingBuffers];
this.channel.publish(eventName, bufferCopy);
setTimeout(() => this.batchToChannel(eventName), this.batchTime);
this.outgoingBuffers = {};
this.outgoingBuffers = [];
this.hasMovement = false;
this.isRunning = true;
}
Expand Down
37 changes: 15 additions & 22 deletions src/CursorDispensing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ export default class CursorDispensing {

if (!update) continue;
this.cursors.emit('cursorsUpdate', update);

const cursor = this.cursors.cursors[update.name];
if (!cursor) continue;
cursor.emit('cursorUpdate', update);
}

if (this.bufferHaveData()) {
Expand Down Expand Up @@ -67,24 +63,21 @@ export default class CursorDispensing {
}

processBatch(message: Types.Message) {
Object.keys(message.data).forEach((name) => {
const updates = message.data[name] || [];

updates.forEach((update) => {
const enhancedMsg = {
name,
clientId: message.clientId,
connectionId: message.connectionId,
position: update.position,
data: update.data,
};

if (this.buffer[enhancedMsg.connectionId]) {
this.buffer[enhancedMsg.connectionId].push(enhancedMsg);
} else {
this.buffer[enhancedMsg.connectionId] = [enhancedMsg];
}
});
const updates = message.data || [];

updates.forEach((update) => {
const enhancedMsg = {
clientId: message.clientId,
connectionId: message.connectionId,
position: update.position,
data: update.data,
};

if (this.buffer[enhancedMsg.connectionId]) {
this.buffer[enhancedMsg.connectionId].push(enhancedMsg);
} else {
this.buffer[enhancedMsg.connectionId] = [enhancedMsg];
}
});

if (!this.handlerRunning && this.bufferHaveData()) {
Expand Down
62 changes: 7 additions & 55 deletions src/CursorHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,16 @@ export default class CursorHistory {
private messageToUpdate(
connectionId: string,
clientId: string,
cursorName: string,
update: Pick<CursorUpdate, 'position' | 'data'>,
): CursorUpdate {
return {
name: cursorName,
clientId,
connectionId,
position: update.position,
data: update.data,
};
}

private namedCursorUpdates(
cursorName: CursorName,
connections: ConnectionsLastPosition,
page: Types.PaginatedResult<Types.Message>,
): ConnectionsLastPosition {
return Object.fromEntries(
Object.entries(connections).map(([connectionId, cursors]) => {
if (cursors && cursors[cursorName]) return [connectionId, cursors[cursorName]];

const lastMessage = page.items.find((item) => item.connectionId === connectionId);
if (!lastMessage) return [connectionId, null];

const { data, clientId }: Types.Message & { data: Record<CursorName, CursorUpdate[]> } = lastMessage;
const updates: CursorUpdate[] = data[cursorName] || [];

if (updates.length > 0) {
const lastUpdate = updates[updates.length - 1];
return [connectionId, this.messageToUpdate(connectionId, clientId, cursorName, lastUpdate)];
} else {
return [connectionId, null];
}
}),
);
}

private allCursorUpdates(
connections: ConnectionsLastPosition,
page: Types.PaginatedResult<Types.Message>,
Expand All @@ -68,38 +41,17 @@ export default class CursorHistory {
const lastMessage = page.items.find((item) => item.connectionId === connectionId);
if (!lastMessage) return [connectionId, cursors];

const { data, clientId }: { data: Record<CursorName, CursorUpdate[]> } & Pick<Types.Message, 'clientId'> =
lastMessage;
const { data, clientId }: { data: CursorUpdate[] } & Pick<Types.Message, 'clientId'> = lastMessage;

const updatedCursors = Object.fromEntries(
Object.entries(data).map(([cursorName, updates]) => {
if (cursors && cursors[cursorName]) return [cursorName, cursors[cursorName]];
const lastUpdate =
data?.length > 0 ? this.messageToUpdate(connectionId, clientId, data[data.length - 1]) : null;

if (updates.length > 0) {
const lastUpdate = updates[updates.length - 1];
return [cursorName, this.messageToUpdate(connectionId, clientId, cursorName, lastUpdate)];
} else {
return [cursorName, null];
}
}),
);

return [connectionId, updatedCursors];
return [connectionId, lastUpdate];
}),
);
}

private mapPageToConnections(
page: Types.PaginatedResult<Types.Message>,
connections: ConnectionsLastPosition,
cursorName?: string,
): ConnectionsLastPosition {
return cursorName
? this.namedCursorUpdates(cursorName, connections, page)
: this.allCursorUpdates(connections, page);
}

async getLastCursorUpdate(cursorName?: string): Promise<ConnectionsLastPosition> {
async getLastCursorUpdate(): Promise<ConnectionsLastPosition> {
const members = await this.channel.presence.get();

if (members.length === 0) return {};
Expand All @@ -115,12 +67,12 @@ export default class CursorHistory {

let pageNo = 1;
let page = await history.current();
connections = this.mapPageToConnections(page, connections, cursorName);
connections = this.allCursorUpdates(connections, page);
pageNo++;

while (pageNo <= this.paginationLimit && this.positionsMissing(connections) && history.hasNext()) {
page = await history.next();
connections = this.mapPageToConnections(page, connections, cursorName);
connections = this.allCursorUpdates(connections, page);
pageNo++;
}

Expand Down
Loading

0 comments on commit 2a95d6c

Please sign in to comment.