Skip to content

Commit

Permalink
add flush to remote connection
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-drexler committed Jan 22, 2025
1 parent ae3e737 commit 3c59afd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/sour-timers-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@remote-dom/core': minor
---

add flush method to BatchingRemoteConnection
24 changes: 14 additions & 10 deletions packages/core/source/elements/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,24 @@ export class BatchingRemoteConnection {
}

mutate(records: any[]) {
let queued = this.#queued;
this.#queued ??= [];
this.#queued.push(...records);

if (queued) {
queued.push(...records);
this.#batch(() => {
if (this.#queued) {
this.#connection.mutate(this.#queued);
this.#queued = undefined;
}
});
}

flush() {
if (!this.#queued) {
return;
}

queued = [...records];
this.#queued = queued;

this.#batch(() => {
this.#connection.mutate(queued);
this.#queued = undefined;
});
this.#connection.mutate(this.#queued);
this.#queued = undefined;
}
}

Expand Down
64 changes: 64 additions & 0 deletions packages/core/source/elements/tests/connection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import '../../polyfill.ts';

import {describe, expect, it, vi, type MockedObject} from 'vitest';

import {BatchingRemoteConnection, RemoteConnection} from '../../elements';

describe('BatchingRemoteConnection', () => {
it('batches mutations', async () => {
const connection = createRemoteConnectionSpy();
const batchingConnection = new BatchingRemoteConnection(connection);

batchingConnection.mutate([1, 2, 3]);
batchingConnection.mutate([4, 5, 6]);

expect(connection.mutate).not.toHaveBeenCalled();

await waitOneTick();

expect(connection.mutate).toHaveBeenCalledTimes(1);
expect(connection.mutate).toHaveBeenCalledWith([1, 2, 3, 4, 5, 6]);

batchingConnection.mutate([7, 8, 9]);

expect(connection.mutate).toHaveBeenCalledTimes(1);

await waitOneTick();

expect(connection.mutate).toHaveBeenCalledTimes(2);
expect(connection.mutate).toHaveBeenCalledWith([7, 8, 9]);
});

it('flushes mutations', async () => {
const connection = createRemoteConnectionSpy();
const batchingConnection = new BatchingRemoteConnection(connection);

batchingConnection.mutate([1, 2, 3]);
batchingConnection.flush();

expect(connection.mutate).toHaveBeenCalledOnce();
expect(connection.mutate).toHaveBeenCalledWith([1, 2, 3]);

await waitOneTick();

// ensure it wasn't called again
expect(connection.mutate).toHaveBeenCalledOnce();
batchingConnection.mutate([4, 5, 6]);

await waitOneTick();

expect(connection.mutate).toHaveBeenCalledTimes(2);
expect(connection.mutate).toHaveBeenCalledWith([4, 5, 6]);
});
});

async function waitOneTick() {
await new Promise((resolve) => setTimeout(resolve, 0));
}

function createRemoteConnectionSpy(): MockedObject<RemoteConnection> {
return {
mutate: vi.fn(),
call: vi.fn(),
};
}

0 comments on commit 3c59afd

Please sign in to comment.