@yorkie-js/sdk 0.6.38 → 0.6.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/quill.html CHANGED
@@ -246,6 +246,9 @@
246
246
  });
247
247
 
248
248
  // 03. create an instance of Quill
249
+ // Track composition state to prevent selection updates during IME input
250
+ let isComposing = false;
251
+
249
252
  const editorElem = clientElem?.getElementsByClassName('editor')[0];
250
253
  Quill.register('modules/cursors', QuillCursors);
251
254
  const quill = new Quill(editorElem, {
@@ -292,6 +295,14 @@
292
295
  }
293
296
 
294
297
  // 04. bind the document with the Quill.
298
+ // Track composition events to prevent selection updates during IME input
299
+ quill.root.addEventListener('compositionstart', () => {
300
+ isComposing = true;
301
+ });
302
+ quill.root.addEventListener('compositionend', () => {
303
+ isComposing = false;
304
+ });
305
+
295
306
  // 04-1. Quill to Document.
296
307
  quill
297
308
  .on('text-change', (delta, _, source) => {
@@ -354,6 +365,7 @@
354
365
  (typeof op.insert === 'string'
355
366
  ? op.insert.length
356
367
  : 1);
368
+ to = from;
357
369
  }
358
370
 
359
371
  if (range) {
@@ -380,7 +392,7 @@
380
392
  op.retain !== undefined &&
381
393
  typeof op.retain === 'number'
382
394
  ) {
383
- from = to + op.retain;
395
+ from += op.retain;
384
396
  to = from;
385
397
  }
386
398
  }
@@ -391,6 +403,12 @@
391
403
  return;
392
404
  }
393
405
 
406
+ // Ignore selection changes during composition (e.g., Korean IME input)
407
+ // to prevent cursor position from being broadcast incorrectly to other users
408
+ if (isComposing) {
409
+ return;
410
+ }
411
+
394
412
  // NOTE(chacha912): If the selection in the Quill editor does not match the range computed by yorkie,
395
413
  // additional updates are necessary. This condition addresses situations where Quill's selection behaves
396
414
  // differently, such as when inserting text before a range selection made by another user, causing
@@ -420,15 +438,10 @@
420
438
 
421
439
  // 04-2. document to Quill(remote).
422
440
  function handleOperations(quill, ops) {
423
- const deltaOperations = [];
424
- let prevTo = 0;
425
441
  for (const op of ops) {
426
442
  if (op.type === 'edit') {
427
443
  const from = op.from;
428
444
  const to = op.to;
429
- const retainFrom = from - prevTo;
430
- const retainTo = to - from;
431
-
432
445
  const { insert, attributes } = toDeltaOperation(
433
446
  op.value,
434
447
  true,
@@ -438,14 +451,17 @@
438
451
  'color: skyblue',
439
452
  );
440
453
 
441
- if (retainFrom) {
442
- deltaOperations.push({ retain: retainFrom });
454
+ const deltaOperations = [];
455
+
456
+ if (from > 0) {
457
+ deltaOperations.push({ retain: from });
443
458
  }
444
- if (retainTo) {
445
- deltaOperations.push({ delete: retainTo });
459
+
460
+ const deleteLength = to - from;
461
+ if (deleteLength > 0) {
462
+ deltaOperations.push({ delete: deleteLength });
446
463
  }
447
- const insertLength =
448
- typeof insert === 'string' ? insert.length : 0;
464
+
449
465
  if (insert) {
450
466
  const op = { insert };
451
467
  if (attributes) {
@@ -453,43 +469,47 @@
453
469
  }
454
470
  deltaOperations.push(op);
455
471
  }
456
- // Update prevTo considering the actual text change:
457
- // from + length of inserted text (delete is already handled by retainTo)
458
- prevTo = from + insertLength;
472
+
473
+ if (deltaOperations.length > 0) {
474
+ console.log(
475
+ `%c to quill: ${JSON.stringify(deltaOperations)}`,
476
+ 'color: green',
477
+ );
478
+ const delta = new Quill.imports.delta(deltaOperations);
479
+ quill.updateContents(delta, 'api');
480
+ }
459
481
  } else if (op.type === 'style') {
460
482
  const from = op.from;
461
483
  const to = op.to;
462
- const retainFrom = from - prevTo;
463
- const retainTo = to - from;
464
484
  const { attributes } = toDeltaOperation(op.value, false);
465
485
  console.log(
466
486
  `%c remote: ${from}-${to}: ${JSON.stringify(attributes)}`,
467
487
  'color: skyblue',
468
488
  );
469
489
 
470
- if (retainFrom) {
471
- deltaOperations.push({ retain: retainFrom });
472
- }
473
490
  if (attributes) {
474
- const op = { attributes };
475
- if (retainTo) {
476
- op.retain = retainTo;
491
+ const deltaOperations = [];
492
+
493
+ if (from > 0) {
494
+ deltaOperations.push({ retain: from });
477
495
  }
478
496
 
497
+ const op = { attributes };
498
+ const retainLength = to - from;
499
+ if (retainLength > 0) {
500
+ op.retain = retainLength;
501
+ }
479
502
  deltaOperations.push(op);
503
+
504
+ console.log(
505
+ `%c to quill: ${JSON.stringify(deltaOperations)}`,
506
+ 'color: green',
507
+ );
508
+ const delta = new Quill.imports.delta(deltaOperations);
509
+ quill.updateContents(delta, 'api');
480
510
  }
481
- prevTo = to;
482
511
  }
483
512
  }
484
-
485
- if (deltaOperations.length) {
486
- console.log(
487
- `%c to quill: ${JSON.stringify(deltaOperations)}`,
488
- 'color: green',
489
- );
490
- const delta = new Quill.imports.delta(deltaOperations);
491
- quill.updateContents(delta, 'api');
492
- }
493
513
  }
494
514
 
495
515
  // 05. synchronize text of document and Quill.
@@ -9,6 +9,7 @@ import { PartialMessage } from '@bufbuild/protobuf';
9
9
  import { PlainMessage } from '@bufbuild/protobuf';
10
10
  import { proto3 } from '@bufbuild/protobuf';
11
11
  import { Rule } from '@yorkie-js/schema';
12
+ import { Timestamp } from '@bufbuild/protobuf';
12
13
 
13
14
  /**
14
15
  * `ActorID` is used to identify who is making changes to the document.
@@ -1083,6 +1084,22 @@ export declare class Client {
1083
1084
  * `getCondition` returns the condition of this client.
1084
1085
  */
1085
1086
  getCondition(condition: ClientCondition): boolean;
1087
+ /**
1088
+ * `createRevision` creates a new revision for the given document.
1089
+ */
1090
+ createRevision<R, P extends Indexable>(doc: Document_2<R, P>, label: string, description?: string): Promise<RevisionSummary>;
1091
+ /**
1092
+ * `listRevisions` lists all revisions for the given document.
1093
+ */
1094
+ listRevisions<R, P extends Indexable>(doc: Document_2<R, P>, options?: {
1095
+ pageSize?: number;
1096
+ offset?: number;
1097
+ isForward?: boolean;
1098
+ }): Promise<Array<RevisionSummary>>;
1099
+ /**
1100
+ * `restoreRevision` restores the document to the given revision.
1101
+ */
1102
+ restoreRevision<R, P extends Indexable>(doc: Document_2<R, P>, revisionId: string): Promise<void>;
1086
1103
  /**
1087
1104
  * `broadcast` broadcasts the given payload to the given topic.
1088
1105
  */
@@ -1274,6 +1291,7 @@ export declare const converter: {
1274
1291
  versionVectorToHex: typeof versionVectorToHex;
1275
1292
  hexToVersionVector: typeof hexToVersionVector;
1276
1293
  fromSchemaRules: typeof fromSchemaRules;
1294
+ toRevisionSummary: typeof toRevisionSummary;
1277
1295
  };
1278
1296
 
1279
1297
  /**
@@ -4861,6 +4879,69 @@ declare type RemoveOpInfo_2 = {
4861
4879
  */
4862
4880
  declare type ResourceStatus = 'detached' | 'attached' | 'removed';
4863
4881
 
4882
+ /**
4883
+ * `RevisionSummary` represents a document revision for version management.
4884
+ * It stores a snapshot of document content at a specific point in time,
4885
+ * enabling features like rollback, audit, and version history tracking.
4886
+ */
4887
+ export declare interface RevisionSummary {
4888
+ /**
4889
+ * `id` is the unique identifier of the revision.
4890
+ */
4891
+ id: string;
4892
+ /**
4893
+ * `label` is a user-friendly name for this revision.
4894
+ */
4895
+ label: string;
4896
+ /**
4897
+ * `description` is a detailed explanation of this revision.
4898
+ */
4899
+ description: string;
4900
+ /**
4901
+ * `snapshot` is the serialized document content (JSON format) at this revision point.
4902
+ * This contains only the pure data without CRDT metadata.
4903
+ */
4904
+ snapshot: string;
4905
+ /**
4906
+ * `createdAt` is the time when this revision was created.
4907
+ */
4908
+ createdAt: Date;
4909
+ }
4910
+
4911
+ /**
4912
+ * @generated from message yorkie.v1.RevisionSummary
4913
+ */
4914
+ declare class RevisionSummary_2 extends Message<RevisionSummary_2> {
4915
+ /**
4916
+ * @generated from field: string id = 1;
4917
+ */
4918
+ id: string;
4919
+ /**
4920
+ * @generated from field: string label = 2;
4921
+ */
4922
+ label: string;
4923
+ /**
4924
+ * @generated from field: string description = 3;
4925
+ */
4926
+ description: string;
4927
+ /**
4928
+ * @generated from field: string snapshot = 4;
4929
+ */
4930
+ snapshot: string;
4931
+ /**
4932
+ * @generated from field: google.protobuf.Timestamp created_at = 5;
4933
+ */
4934
+ createdAt?: Timestamp;
4935
+ constructor(data?: PartialMessage<RevisionSummary_2>);
4936
+ static readonly runtime: typeof proto3;
4937
+ static readonly typeName = "yorkie.v1.RevisionSummary";
4938
+ static readonly fields: FieldList;
4939
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RevisionSummary_2;
4940
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): RevisionSummary_2;
4941
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): RevisionSummary_2;
4942
+ static equals(a: RevisionSummary_2 | PlainMessage<RevisionSummary_2> | undefined, b: RevisionSummary_2 | PlainMessage<RevisionSummary_2> | undefined): boolean;
4943
+ }
4944
+
4864
4945
  /**
4865
4946
  * `RGATreeSplit` is a block-based list with improved index-based lookup in RGA.
4866
4947
  * The difference from RGATreeList is that it has data on a block basis to
@@ -6071,6 +6152,11 @@ declare enum TokenType {
6071
6152
  */
6072
6153
  declare function toOperation(operation: Operation): Operation_2;
6073
6154
 
6155
+ /**
6156
+ * `toRevisionSummary` converts a protobuf RevisionSummary to a RevisionSummary.
6157
+ */
6158
+ declare function toRevisionSummary(pbRevision: RevisionSummary_2): RevisionSummary;
6159
+
6074
6160
  /**
6075
6161
  * `toTreeNodes` converts the given model to Protobuf format.
6076
6162
  */