Skip to content

Commit 247dab3

Browse files
committed
feat(json-crdt): 🎸 add autoflushing functionality
1 parent 15eaab8 commit 247dab3

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

src/json-crdt/file/File.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,17 @@ export class File implements Printable {
7979
public sync(): () => void {
8080
const {model, log} = this;
8181
const api = model.api;
82-
const drain = () => {
83-
if (!api.builder.patch.ops.length) return;
84-
const patch = api.flush();
85-
this.log.push(patch);
86-
};
82+
const autoflushUnsubscribe = api.autoFlush();
8783
const onPatchUnsubscribe = api.onPatch.listen((patch) => {
8884
log.push(patch);
8985
});
90-
const onLocalChangesUnsubscribe = api.onLocalChanges.listen(drain);
91-
const onBeforeTransactionUnsubscribe = api.onBeforeTransaction.listen(drain);
92-
const onTransactionUnsubscribe = api.onTransaction.listen(drain);
86+
const onFlushUnsubscribe = api.onFlush.listen((patch) => {
87+
log.push(patch);
88+
});
9389
return () => {
90+
autoflushUnsubscribe();
9491
onPatchUnsubscribe();
95-
onLocalChangesUnsubscribe();
96-
onBeforeTransactionUnsubscribe();
97-
onTransactionUnsubscribe();
92+
onFlushUnsubscribe();
9893
};
9994
}
10095

src/json-crdt/model/api/ModelApi.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export class ModelApi<N extends JsonNode = JsonNode> implements SyncStore<JsonNo
4242
/** Emitted after local changes through `model.api` are applied. Same as
4343
* `.onLocalChange`, but this event buffered withing a microtask. */
4444
public readonly onLocalChanges = new MicrotaskBufferFanOut<number>(this.onLocalChange);
45+
/** Emitted before a transaction is started. */
46+
public readonly onBeforeTransaction = new FanOut<void>();
47+
/** Emitted after transaction completes. */
48+
public readonly onTransaction = new FanOut<void>();
4549
/** Emitted when the model changes. Combines `onReset`, `onPatch` and `onLocalChange`. */
4650
public readonly onChange = new MergeFanOut<number | Patch | void>([this.onReset, this.onPatch, this.onLocalChange]);
4751
/** Emitted when the model changes. Same as `.onChange`, but this event is emitted once per microtask. */
@@ -248,6 +252,12 @@ export class ModelApi<N extends JsonNode = JsonNode> implements SyncStore<JsonNo
248252
return this.model.view();
249253
}
250254

255+
public transaction(callback: () => void) {
256+
this.onBeforeTransaction.emit();
257+
callback();
258+
this.onTransaction.emit();
259+
}
260+
251261
/**
252262
* Flushes the builder and returns a patch.
253263
*
@@ -261,15 +271,26 @@ export class ModelApi<N extends JsonNode = JsonNode> implements SyncStore<JsonNo
261271
return patch;
262272
}
263273

264-
/** Emitted before a transaction is started. */
265-
public readonly onBeforeTransaction = new FanOut<void>();
266-
/** Emitted after transaction completes. */
267-
public readonly onTransaction = new FanOut<void>();
274+
public stopAutoFlush?: () => void = undefined;
268275

269-
public transaction(callback: () => void) {
270-
this.onBeforeTransaction.emit();
271-
callback();
272-
this.onTransaction.emit();
276+
/**
277+
* Begins to automatically flush buffered operations into patches, grouping
278+
* operations by microtasks or by transactions. To capture the patch, listen
279+
* to the `.onFlush` event.
280+
*
281+
* @returns Callback to stop auto flushing.
282+
*/
283+
public autoFlush(): (() => void) {
284+
const drain = () => this.builder.patch.ops.length && this.flush();
285+
const onLocalChangesUnsubscribe = this.onLocalChanges.listen(drain);
286+
const onBeforeTransactionUnsubscribe = this.onBeforeTransaction.listen(drain);
287+
const onTransactionUnsubscribe = this.onTransaction.listen(drain);
288+
return this.stopAutoFlush = () => {
289+
this.stopAutoFlush = undefined;
290+
onLocalChangesUnsubscribe();
291+
onBeforeTransactionUnsubscribe();
292+
onTransactionUnsubscribe();
293+
};
273294
}
274295

275296
// ---------------------------------------------------------------- SyncStore

0 commit comments

Comments
 (0)