Skip to content

Commit

Permalink
Merge pull request #783 from streamich/bug-782
Browse files Browse the repository at this point in the history
Add a test case and improve JSDocs
  • Loading branch information
streamich authored Nov 22, 2024
2 parents 42d59c5 + cb08f1f commit 469a754
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/json-crdt/__tests__/bug-782.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {Patch, s} from '../../json-crdt-patch';
import {Model} from '../model';

test('initializing two users with schema, should merge changes correctly', () => {
for (let i = 0; i < 22; i++) {
const user1 = Model.create(
s.obj({
format: s.con('markdown'),
text: s.str('Hello!'),
}),
);
user1.api.flush();

expect(user1.view()).toEqual({format: 'markdown', text: 'Hello!'});

// Serialize the document and send it to another user
const blob = user1.toBinary();

// The other user loads the document and creates a "fork"
// of it, so that a new session ID is assigned
const user2 = Model.fromBinary(blob).fork();

// Now both users insert concurrently some text at
// the same position
user1.api.str(['text']).ins(5, ' Alice');
user2.api.str(['text']).ins(5, ' Charlie');

// We now verify that documents of both users are different
expect(user1.view()).toEqual({format: 'markdown', text: 'Hello Alice!'});
expect(user2.view()).toEqual({format: 'markdown', text: 'Hello Charlie!'});

// Users can now compute the patches of their changes
const patch1 = user1.api.flush();
const patch2 = user2.api.flush();

// Users can exchange patches and apply them
user1.applyPatch(Patch.fromBinary(patch2.toBinary()));
user2.applyPatch(Patch.fromBinary(patch1.toBinary()));

// Now both documents converge to the same state
expect(user1.view()).toEqual(user2.view());
}
});
7 changes: 7 additions & 0 deletions src/json-crdt/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class Model<N extends JsonNode = JsonNode<any>> implements Printable {
* ),
* });
* const model = Model.create(schema);
* const patch = model.api.flush();
* ```
*
* Create a model with a custom session ID for your logical clock:
Expand All @@ -119,6 +120,7 @@ export class Model<N extends JsonNode = JsonNode<any>> implements Printable {
* const schema = s.str('');
* const sid = 123456789;
* const model = Model.create(schema, sid);
* const patch = model.api.flush();
* ```
*
* The session ID must be at least 65,536 or higher, [see JSON CRDT Patch
Expand All @@ -143,6 +145,11 @@ export class Model<N extends JsonNode = JsonNode<any>> implements Printable {
* ```
*
* @param schema The schema (typing and default value) to set for this model.
* When a schema is provided, the model is strictly typed and the default
* value of the model is set to the value of the schema. Also, you MUST
* call `model.api.flush()` immediately after creating the model to clear
* the change buffer of the patch that was created during the initialization
* of the model.
* @param sidOrClock Session ID to use for local operations. Defaults to a random
* session ID generated by {@link Model.sid}.
* @returns A strictly typed model.
Expand Down

0 comments on commit 469a754

Please sign in to comment.