@yorkie-js/sdk 0.6.11-rc → 0.6.12
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/yorkie-js-sdk.d.ts +24 -12
- package/dist/yorkie-js-sdk.es.js +153 -108
- package/dist/yorkie-js-sdk.es.js.map +1 -1
- package/dist/yorkie-js-sdk.js +153 -108
- package/dist/yorkie-js-sdk.js.map +1 -1
- package/package.json +1 -1
package/dist/yorkie-js-sdk.d.ts
CHANGED
|
@@ -285,7 +285,8 @@ declare class Change_2 extends Message<Change_2> {
|
|
|
285
285
|
* Finally returns a Change after the modification has been completed.
|
|
286
286
|
*/
|
|
287
287
|
declare class ChangeContext<P extends Indexable = Indexable> {
|
|
288
|
-
private
|
|
288
|
+
private prevID;
|
|
289
|
+
private nextID;
|
|
289
290
|
private delimiter;
|
|
290
291
|
private message?;
|
|
291
292
|
private root;
|
|
@@ -301,11 +302,11 @@ declare class ChangeContext<P extends Indexable = Indexable> {
|
|
|
301
302
|
* presence changes.
|
|
302
303
|
*/
|
|
303
304
|
private reversePresenceKeys;
|
|
304
|
-
constructor(
|
|
305
|
+
constructor(prevID: ChangeID, root: CRDTRoot, presence: P, message?: string);
|
|
305
306
|
/**
|
|
306
307
|
* `create` creates a new instance of ChangeContext.
|
|
307
308
|
*/
|
|
308
|
-
static create<P extends Indexable>(
|
|
309
|
+
static create<P extends Indexable>(prevID: ChangeID, root: CRDTRoot, presence: P, message?: string): ChangeContext<P>;
|
|
309
310
|
/**
|
|
310
311
|
* `push` pushes the given operation to this context.
|
|
311
312
|
*/
|
|
@@ -323,9 +324,14 @@ declare class ChangeContext<P extends Indexable = Indexable> {
|
|
|
323
324
|
*/
|
|
324
325
|
registerGCPair(pair: GCPair): void;
|
|
325
326
|
/**
|
|
326
|
-
* `
|
|
327
|
+
* `getNextID` returns the next ID of this context. It will be set to the
|
|
328
|
+
* document for the next change.returns the next ID of this context.
|
|
329
|
+
*/
|
|
330
|
+
getNextID(): ChangeID;
|
|
331
|
+
/**
|
|
332
|
+
* `toChange` creates a new instance of Change in this context.
|
|
327
333
|
*/
|
|
328
|
-
|
|
334
|
+
toChange(): Change<P>;
|
|
329
335
|
/**
|
|
330
336
|
* `hasChange` returns whether this context has change or not.
|
|
331
337
|
*/
|
|
@@ -360,10 +366,14 @@ declare class ChangeContext<P extends Indexable = Indexable> {
|
|
|
360
366
|
declare class ChangeID {
|
|
361
367
|
private clientSeq;
|
|
362
368
|
private serverSeq?;
|
|
363
|
-
private lamport;
|
|
364
369
|
private actor;
|
|
370
|
+
private lamport;
|
|
365
371
|
private versionVector;
|
|
366
372
|
constructor(clientSeq: number, lamport: bigint, actor: ActorID, vector: VersionVector, serverSeq?: bigint);
|
|
373
|
+
/**
|
|
374
|
+
* `hasClocks` returns true if this ID has logical clocks.
|
|
375
|
+
*/
|
|
376
|
+
hasClocks(): boolean;
|
|
367
377
|
/**
|
|
368
378
|
* `of` creates a new instance of ChangeID.
|
|
369
379
|
*/
|
|
@@ -371,9 +381,10 @@ declare class ChangeID {
|
|
|
371
381
|
/**
|
|
372
382
|
* `next` creates a next ID of this ID.
|
|
373
383
|
*/
|
|
374
|
-
next(): ChangeID;
|
|
384
|
+
next(excludeClocks?: boolean): ChangeID;
|
|
375
385
|
/**
|
|
376
|
-
* `syncClocks` syncs logical clocks with the given ID.
|
|
386
|
+
* `syncClocks` syncs logical clocks with the given ID. If the given ID
|
|
387
|
+
* doesn't have logical clocks, this ID is returned.
|
|
377
388
|
*/
|
|
378
389
|
syncClocks(other: ChangeID): ChangeID;
|
|
379
390
|
/**
|
|
@@ -389,6 +400,10 @@ declare class ChangeID {
|
|
|
389
400
|
* `setActor` sets the given actor.
|
|
390
401
|
*/
|
|
391
402
|
setActor(actorID: ActorID): ChangeID;
|
|
403
|
+
/**
|
|
404
|
+
* `setLamport` sets the given lamport clock.
|
|
405
|
+
*/
|
|
406
|
+
setLamport(lamport: bigint): ChangeID;
|
|
392
407
|
/**
|
|
393
408
|
* `setVersionVector` sets the given version vector.
|
|
394
409
|
*/
|
|
@@ -761,6 +776,7 @@ export declare class Client {
|
|
|
761
776
|
*/
|
|
762
777
|
detach<R, P extends Indexable>(doc: Document_2<R, P>, opts?: {
|
|
763
778
|
removeIfNotAttached?: boolean;
|
|
779
|
+
keepalive?: boolean;
|
|
764
780
|
}): Promise<Document_2<R, P>>;
|
|
765
781
|
/**
|
|
766
782
|
* `changeRealtimeSync` changes the synchronization mode of the given document.
|
|
@@ -2505,10 +2521,6 @@ declare class Document_2<R, P extends Indexable = Indexable> {
|
|
|
2505
2521
|
* `canUndo` returns whether there are any operations to undo.
|
|
2506
2522
|
*/
|
|
2507
2523
|
private canUndo;
|
|
2508
|
-
/**
|
|
2509
|
-
* 'filterVersionVector' filters detached client's lamport from version vector.
|
|
2510
|
-
*/
|
|
2511
|
-
private filterVersionVector;
|
|
2512
2524
|
/**
|
|
2513
2525
|
* `canRedo` returns whether there are any operations to redo.
|
|
2514
2526
|
*/
|
package/dist/yorkie-js-sdk.es.js
CHANGED
|
@@ -7581,76 +7581,11 @@ class YorkieError extends Error {
|
|
|
7581
7581
|
this.toString = () => `[code=${this.code}]: ${this.message}`;
|
|
7582
7582
|
}
|
|
7583
7583
|
}
|
|
7584
|
-
function deepcopy(object) {
|
|
7585
|
-
if (object instanceof Map) {
|
|
7586
|
-
const pairs = Array.from(object);
|
|
7587
|
-
return new Map(JSON.parse(JSON.stringify(pairs)));
|
|
7588
|
-
}
|
|
7589
|
-
return JSON.parse(JSON.stringify(object));
|
|
7590
|
-
}
|
|
7591
|
-
const isEmpty = (object) => {
|
|
7592
|
-
if (!object) {
|
|
7593
|
-
return true;
|
|
7594
|
-
}
|
|
7595
|
-
return Object.entries(object).length === 0;
|
|
7596
|
-
};
|
|
7597
|
-
const stringifyObjectValues = (attributes) => {
|
|
7598
|
-
const attrs = {};
|
|
7599
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
7600
|
-
attrs[key] = JSON.stringify(value);
|
|
7601
|
-
}
|
|
7602
|
-
return attrs;
|
|
7603
|
-
};
|
|
7604
|
-
const parseObjectValues = (attrs) => {
|
|
7605
|
-
const attributes = {};
|
|
7606
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
7607
|
-
attributes[key] = JSON.parse(value);
|
|
7608
|
-
}
|
|
7609
|
-
return attributes;
|
|
7610
|
-
};
|
|
7611
7584
|
var PresenceChangeType = /* @__PURE__ */ ((PresenceChangeType2) => {
|
|
7612
7585
|
PresenceChangeType2["Put"] = "put";
|
|
7613
7586
|
PresenceChangeType2["Clear"] = "clear";
|
|
7614
7587
|
return PresenceChangeType2;
|
|
7615
7588
|
})(PresenceChangeType || {});
|
|
7616
|
-
class Presence {
|
|
7617
|
-
constructor(changeContext, presence) {
|
|
7618
|
-
__publicField(this, "context");
|
|
7619
|
-
__publicField(this, "presence");
|
|
7620
|
-
this.context = changeContext;
|
|
7621
|
-
this.presence = presence;
|
|
7622
|
-
}
|
|
7623
|
-
/**
|
|
7624
|
-
* `set` updates the presence based on the partial presence.
|
|
7625
|
-
*/
|
|
7626
|
-
set(presence, option) {
|
|
7627
|
-
for (const key of Object.keys(presence)) {
|
|
7628
|
-
this.presence[key] = presence[key];
|
|
7629
|
-
}
|
|
7630
|
-
this.context.setPresenceChange({
|
|
7631
|
-
type: "put",
|
|
7632
|
-
presence: deepcopy(this.presence)
|
|
7633
|
-
});
|
|
7634
|
-
this.context.setReversePresence(presence, option);
|
|
7635
|
-
}
|
|
7636
|
-
/**
|
|
7637
|
-
* `get` returns the presence value of the given key.
|
|
7638
|
-
*/
|
|
7639
|
-
get(key) {
|
|
7640
|
-
return this.presence[key];
|
|
7641
|
-
}
|
|
7642
|
-
/**
|
|
7643
|
-
* `clear` clears the presence.
|
|
7644
|
-
* @internal
|
|
7645
|
-
*/
|
|
7646
|
-
clear() {
|
|
7647
|
-
this.presence = {};
|
|
7648
|
-
this.context.setPresenceChange({
|
|
7649
|
-
type: "clear"
|
|
7650
|
-
/* Clear */
|
|
7651
|
-
});
|
|
7652
|
-
}
|
|
7653
|
-
}
|
|
7654
7589
|
const InitialActorID = "000000000000000000000000";
|
|
7655
7590
|
const TimeTicketSize = 8 + 4 + 12;
|
|
7656
7591
|
class TimeTicket {
|
|
@@ -7766,10 +7701,11 @@ class TimeTicket {
|
|
|
7766
7701
|
return 0;
|
|
7767
7702
|
}
|
|
7768
7703
|
}
|
|
7704
|
+
const InitialLamport = 0n;
|
|
7769
7705
|
const InitialDelimiter = 0;
|
|
7770
7706
|
const MaxLamport = 9223372036854775807n;
|
|
7771
7707
|
const InitialTimeTicket = new TimeTicket(
|
|
7772
|
-
|
|
7708
|
+
InitialLamport,
|
|
7773
7709
|
InitialDelimiter,
|
|
7774
7710
|
InitialActorID
|
|
7775
7711
|
);
|
|
@@ -10980,6 +10916,33 @@ class RHT {
|
|
|
10980
10916
|
this.numberOfRemovedElement--;
|
|
10981
10917
|
}
|
|
10982
10918
|
}
|
|
10919
|
+
function deepcopy(object) {
|
|
10920
|
+
if (object instanceof Map) {
|
|
10921
|
+
const pairs = Array.from(object);
|
|
10922
|
+
return new Map(JSON.parse(JSON.stringify(pairs)));
|
|
10923
|
+
}
|
|
10924
|
+
return JSON.parse(JSON.stringify(object));
|
|
10925
|
+
}
|
|
10926
|
+
const isEmpty = (object) => {
|
|
10927
|
+
if (!object) {
|
|
10928
|
+
return true;
|
|
10929
|
+
}
|
|
10930
|
+
return Object.entries(object).length === 0;
|
|
10931
|
+
};
|
|
10932
|
+
const stringifyObjectValues = (attributes) => {
|
|
10933
|
+
const attrs = {};
|
|
10934
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
10935
|
+
attrs[key] = JSON.stringify(value);
|
|
10936
|
+
}
|
|
10937
|
+
return attrs;
|
|
10938
|
+
};
|
|
10939
|
+
const parseObjectValues = (attrs) => {
|
|
10940
|
+
const attributes = {};
|
|
10941
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
10942
|
+
attributes[key] = JSON.parse(value);
|
|
10943
|
+
}
|
|
10944
|
+
return attributes;
|
|
10945
|
+
};
|
|
10983
10946
|
class CRDTTextValue {
|
|
10984
10947
|
constructor(content) {
|
|
10985
10948
|
__publicField(this, "attributes");
|
|
@@ -13895,12 +13858,15 @@ class ChangeID {
|
|
|
13895
13858
|
__publicField(this, "clientSeq");
|
|
13896
13859
|
// `serverSeq` is optional and only present for changes stored on the server.
|
|
13897
13860
|
__publicField(this, "serverSeq");
|
|
13898
|
-
// `
|
|
13899
|
-
// This is used to determine the order of changes in logical time.
|
|
13900
|
-
__publicField(this, "lamport");
|
|
13861
|
+
// `actor` is the creator of this change.
|
|
13901
13862
|
__publicField(this, "actor");
|
|
13863
|
+
// `lamport` is the lamport clock of this change. This is used to determine
|
|
13864
|
+
// the order of changes in logical time. It is optional and only present
|
|
13865
|
+
// if the change has operations.
|
|
13866
|
+
__publicField(this, "lamport");
|
|
13902
13867
|
// `versionVector` is the vector clock of this change. This is used to
|
|
13903
|
-
// determine the relationship is causal or not between changes.
|
|
13868
|
+
// determine the relationship is causal or not between changes. It is optional
|
|
13869
|
+
// and only present if the change has operations.
|
|
13904
13870
|
__publicField(this, "versionVector");
|
|
13905
13871
|
this.clientSeq = clientSeq;
|
|
13906
13872
|
this.serverSeq = serverSeq;
|
|
@@ -13908,6 +13874,12 @@ class ChangeID {
|
|
|
13908
13874
|
this.versionVector = vector;
|
|
13909
13875
|
this.actor = actor;
|
|
13910
13876
|
}
|
|
13877
|
+
/**
|
|
13878
|
+
* `hasClocks` returns true if this ID has logical clocks.
|
|
13879
|
+
*/
|
|
13880
|
+
hasClocks() {
|
|
13881
|
+
return this.versionVector.size() > 0 && this.lamport != InitialLamport;
|
|
13882
|
+
}
|
|
13911
13883
|
/**
|
|
13912
13884
|
* `of` creates a new instance of ChangeID.
|
|
13913
13885
|
*/
|
|
@@ -13917,7 +13889,16 @@ class ChangeID {
|
|
|
13917
13889
|
/**
|
|
13918
13890
|
* `next` creates a next ID of this ID.
|
|
13919
13891
|
*/
|
|
13920
|
-
next() {
|
|
13892
|
+
next(excludeClocks = false) {
|
|
13893
|
+
if (excludeClocks) {
|
|
13894
|
+
return new ChangeID(
|
|
13895
|
+
this.clientSeq + 1,
|
|
13896
|
+
this.lamport,
|
|
13897
|
+
this.actor,
|
|
13898
|
+
InitialVersionVector,
|
|
13899
|
+
InitialLamport
|
|
13900
|
+
);
|
|
13901
|
+
}
|
|
13921
13902
|
const vector = this.versionVector.deepcopy();
|
|
13922
13903
|
vector.set(this.actor, this.lamport + 1n);
|
|
13923
13904
|
return new ChangeID(
|
|
@@ -13928,9 +13909,13 @@ class ChangeID {
|
|
|
13928
13909
|
);
|
|
13929
13910
|
}
|
|
13930
13911
|
/**
|
|
13931
|
-
* `syncClocks` syncs logical clocks with the given ID.
|
|
13912
|
+
* `syncClocks` syncs logical clocks with the given ID. If the given ID
|
|
13913
|
+
* doesn't have logical clocks, this ID is returned.
|
|
13932
13914
|
*/
|
|
13933
13915
|
syncClocks(other) {
|
|
13916
|
+
if (!other.hasClocks()) {
|
|
13917
|
+
return this;
|
|
13918
|
+
}
|
|
13934
13919
|
const lamport = other.lamport > this.lamport ? other.lamport + 1n : this.lamport + 1n;
|
|
13935
13920
|
const maxVersionVector = this.versionVector.max(other.versionVector);
|
|
13936
13921
|
const newID = new ChangeID(
|
|
@@ -13971,6 +13956,18 @@ class ChangeID {
|
|
|
13971
13956
|
this.serverSeq
|
|
13972
13957
|
);
|
|
13973
13958
|
}
|
|
13959
|
+
/**
|
|
13960
|
+
* `setLamport` sets the given lamport clock.
|
|
13961
|
+
*/
|
|
13962
|
+
setLamport(lamport) {
|
|
13963
|
+
return new ChangeID(
|
|
13964
|
+
this.clientSeq,
|
|
13965
|
+
lamport,
|
|
13966
|
+
this.actor,
|
|
13967
|
+
this.versionVector,
|
|
13968
|
+
this.serverSeq
|
|
13969
|
+
);
|
|
13970
|
+
}
|
|
13974
13971
|
/**
|
|
13975
13972
|
* `setVersionVector` sets the given version vector.
|
|
13976
13973
|
*/
|
|
@@ -16926,8 +16923,9 @@ function createObservable(executor) {
|
|
|
16926
16923
|
};
|
|
16927
16924
|
}
|
|
16928
16925
|
class ChangeContext {
|
|
16929
|
-
constructor(
|
|
16930
|
-
__publicField(this, "
|
|
16926
|
+
constructor(prevID, root, presence, message) {
|
|
16927
|
+
__publicField(this, "prevID");
|
|
16928
|
+
__publicField(this, "nextID");
|
|
16931
16929
|
__publicField(this, "delimiter");
|
|
16932
16930
|
__publicField(this, "message");
|
|
16933
16931
|
__publicField(this, "root");
|
|
@@ -16943,7 +16941,8 @@ class ChangeContext {
|
|
|
16943
16941
|
* presence changes.
|
|
16944
16942
|
*/
|
|
16945
16943
|
__publicField(this, "reversePresenceKeys");
|
|
16946
|
-
this.
|
|
16944
|
+
this.prevID = prevID;
|
|
16945
|
+
this.nextID = prevID.next();
|
|
16947
16946
|
this.delimiter = InitialDelimiter;
|
|
16948
16947
|
this.root = root;
|
|
16949
16948
|
this.operations = [];
|
|
@@ -16955,8 +16954,8 @@ class ChangeContext {
|
|
|
16955
16954
|
/**
|
|
16956
16955
|
* `create` creates a new instance of ChangeContext.
|
|
16957
16956
|
*/
|
|
16958
|
-
static create(
|
|
16959
|
-
return new ChangeContext(
|
|
16957
|
+
static create(prevID, root, presence, message) {
|
|
16958
|
+
return new ChangeContext(prevID, root, presence, message);
|
|
16960
16959
|
}
|
|
16961
16960
|
/**
|
|
16962
16961
|
* `push` pushes the given operation to this context.
|
|
@@ -16983,11 +16982,22 @@ class ChangeContext {
|
|
|
16983
16982
|
this.root.registerGCPair(pair);
|
|
16984
16983
|
}
|
|
16985
16984
|
/**
|
|
16986
|
-
* `
|
|
16985
|
+
* `getNextID` returns the next ID of this context. It will be set to the
|
|
16986
|
+
* document for the next change.returns the next ID of this context.
|
|
16987
16987
|
*/
|
|
16988
|
-
|
|
16988
|
+
getNextID() {
|
|
16989
|
+
if (this.operations.length === 0) {
|
|
16990
|
+
return this.prevID.next(true).setLamport(this.prevID.getLamport()).setVersionVector(this.prevID.getVersionVector());
|
|
16991
|
+
}
|
|
16992
|
+
return this.nextID;
|
|
16993
|
+
}
|
|
16994
|
+
/**
|
|
16995
|
+
* `toChange` creates a new instance of Change in this context.
|
|
16996
|
+
*/
|
|
16997
|
+
toChange() {
|
|
16998
|
+
const id = this.operations.length === 0 ? this.prevID.next(true) : this.nextID;
|
|
16989
16999
|
return Change.create({
|
|
16990
|
-
id
|
|
17000
|
+
id,
|
|
16991
17001
|
operations: this.operations,
|
|
16992
17002
|
presenceChange: this.presenceChange,
|
|
16993
17003
|
message: this.message
|
|
@@ -17033,13 +17043,13 @@ class ChangeContext {
|
|
|
17033
17043
|
*/
|
|
17034
17044
|
issueTimeTicket() {
|
|
17035
17045
|
this.delimiter += 1;
|
|
17036
|
-
return this.
|
|
17046
|
+
return this.nextID.createTimeTicket(this.delimiter);
|
|
17037
17047
|
}
|
|
17038
17048
|
/**
|
|
17039
17049
|
* `getLastTimeTicket` returns the last time ticket issued in this context.
|
|
17040
17050
|
*/
|
|
17041
17051
|
getLastTimeTicket() {
|
|
17042
|
-
return this.
|
|
17052
|
+
return this.nextID.createTimeTicket(this.delimiter);
|
|
17043
17053
|
}
|
|
17044
17054
|
}
|
|
17045
17055
|
class CRDTRoot {
|
|
@@ -18968,6 +18978,43 @@ function buildCRDTElement(context, value, createdAt) {
|
|
|
18968
18978
|
}
|
|
18969
18979
|
return element;
|
|
18970
18980
|
}
|
|
18981
|
+
class Presence {
|
|
18982
|
+
constructor(changeContext, presence) {
|
|
18983
|
+
__publicField(this, "context");
|
|
18984
|
+
__publicField(this, "presence");
|
|
18985
|
+
this.context = changeContext;
|
|
18986
|
+
this.presence = presence;
|
|
18987
|
+
}
|
|
18988
|
+
/**
|
|
18989
|
+
* `set` updates the presence based on the partial presence.
|
|
18990
|
+
*/
|
|
18991
|
+
set(presence, option) {
|
|
18992
|
+
for (const key of Object.keys(presence)) {
|
|
18993
|
+
this.presence[key] = presence[key];
|
|
18994
|
+
}
|
|
18995
|
+
this.context.setPresenceChange({
|
|
18996
|
+
type: PresenceChangeType.Put,
|
|
18997
|
+
presence: deepcopy(this.presence)
|
|
18998
|
+
});
|
|
18999
|
+
this.context.setReversePresence(presence, option);
|
|
19000
|
+
}
|
|
19001
|
+
/**
|
|
19002
|
+
* `get` returns the presence value of the given key.
|
|
19003
|
+
*/
|
|
19004
|
+
get(key) {
|
|
19005
|
+
return this.presence[key];
|
|
19006
|
+
}
|
|
19007
|
+
/**
|
|
19008
|
+
* `clear` clears the presence.
|
|
19009
|
+
* @internal
|
|
19010
|
+
*/
|
|
19011
|
+
clear() {
|
|
19012
|
+
this.presence = {};
|
|
19013
|
+
this.context.setPresenceChange({
|
|
19014
|
+
type: PresenceChangeType.Clear
|
|
19015
|
+
});
|
|
19016
|
+
}
|
|
19017
|
+
}
|
|
18971
19018
|
const MaxUndoRedoStackDepth = 50;
|
|
18972
19019
|
class History {
|
|
18973
19020
|
constructor() {
|
|
@@ -19235,7 +19282,7 @@ class Document {
|
|
|
19235
19282
|
this.ensureClone();
|
|
19236
19283
|
const actorID = this.changeID.getActorID();
|
|
19237
19284
|
const context = ChangeContext.create(
|
|
19238
|
-
this.changeID
|
|
19285
|
+
this.changeID,
|
|
19239
19286
|
this.clone.root,
|
|
19240
19287
|
this.clone.presences.get(actorID) || {},
|
|
19241
19288
|
message
|
|
@@ -19263,7 +19310,7 @@ class Document {
|
|
|
19263
19310
|
if (logger.isEnabled(LogLevel.Trivial)) {
|
|
19264
19311
|
logger.trivial(`trying to update a local change: ${this.toJSON()}`);
|
|
19265
19312
|
}
|
|
19266
|
-
const change = context.
|
|
19313
|
+
const change = context.toChange();
|
|
19267
19314
|
const { opInfos, reverseOps } = change.execute(
|
|
19268
19315
|
this.root,
|
|
19269
19316
|
this.presences,
|
|
@@ -19283,7 +19330,7 @@ class Document {
|
|
|
19283
19330
|
if (opInfos.length > 0) {
|
|
19284
19331
|
this.internalHistory.clearRedo();
|
|
19285
19332
|
}
|
|
19286
|
-
this.changeID =
|
|
19333
|
+
this.changeID = context.getNextID();
|
|
19287
19334
|
const event = [];
|
|
19288
19335
|
if (opInfos.length > 0) {
|
|
19289
19336
|
event.push({
|
|
@@ -20152,14 +20199,6 @@ class Document {
|
|
|
20152
20199
|
canUndo() {
|
|
20153
20200
|
return this.internalHistory.hasUndo() && !this.isUpdating;
|
|
20154
20201
|
}
|
|
20155
|
-
/**
|
|
20156
|
-
* 'filterVersionVector' filters detached client's lamport from version vector.
|
|
20157
|
-
*/
|
|
20158
|
-
filterVersionVector(minSyncedVersionVector) {
|
|
20159
|
-
const versionVector = this.changeID.getVersionVector();
|
|
20160
|
-
const filteredVersionVector = versionVector.filter(minSyncedVersionVector);
|
|
20161
|
-
this.changeID = this.changeID.setVersionVector(filteredVersionVector);
|
|
20162
|
-
}
|
|
20163
20202
|
/**
|
|
20164
20203
|
* `canRedo` returns whether there are any operations to redo.
|
|
20165
20204
|
*/
|
|
@@ -20186,7 +20225,7 @@ class Document {
|
|
|
20186
20225
|
}
|
|
20187
20226
|
this.ensureClone();
|
|
20188
20227
|
const context = ChangeContext.create(
|
|
20189
|
-
this.changeID
|
|
20228
|
+
this.changeID,
|
|
20190
20229
|
this.clone.root,
|
|
20191
20230
|
this.clone.presences.get(this.changeID.getActorID()) || {}
|
|
20192
20231
|
);
|
|
@@ -20203,7 +20242,7 @@ class Document {
|
|
|
20203
20242
|
undoOp.setExecutedAt(ticket);
|
|
20204
20243
|
context.push(undoOp);
|
|
20205
20244
|
}
|
|
20206
|
-
const change = context.
|
|
20245
|
+
const change = context.toChange();
|
|
20207
20246
|
change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
|
|
20208
20247
|
const { opInfos, reverseOps } = change.execute(
|
|
20209
20248
|
this.root,
|
|
@@ -20224,7 +20263,7 @@ class Document {
|
|
|
20224
20263
|
return;
|
|
20225
20264
|
}
|
|
20226
20265
|
this.localChanges.push(change);
|
|
20227
|
-
this.changeID =
|
|
20266
|
+
this.changeID = context.getNextID();
|
|
20228
20267
|
const actorID = this.changeID.getActorID();
|
|
20229
20268
|
const event = [];
|
|
20230
20269
|
if (opInfos.length > 0) {
|
|
@@ -20273,7 +20312,7 @@ class Document {
|
|
|
20273
20312
|
}
|
|
20274
20313
|
this.ensureClone();
|
|
20275
20314
|
const context = ChangeContext.create(
|
|
20276
|
-
this.changeID
|
|
20315
|
+
this.changeID,
|
|
20277
20316
|
this.clone.root,
|
|
20278
20317
|
this.clone.presences.get(this.changeID.getActorID()) || {}
|
|
20279
20318
|
);
|
|
@@ -20290,7 +20329,7 @@ class Document {
|
|
|
20290
20329
|
redoOp.setExecutedAt(ticket);
|
|
20291
20330
|
context.push(redoOp);
|
|
20292
20331
|
}
|
|
20293
|
-
const change = context.
|
|
20332
|
+
const change = context.toChange();
|
|
20294
20333
|
change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
|
|
20295
20334
|
const { opInfos, reverseOps } = change.execute(
|
|
20296
20335
|
this.root,
|
|
@@ -20311,7 +20350,7 @@ class Document {
|
|
|
20311
20350
|
return;
|
|
20312
20351
|
}
|
|
20313
20352
|
this.localChanges.push(change);
|
|
20314
|
-
this.changeID =
|
|
20353
|
+
this.changeID = context.getNextID();
|
|
20315
20354
|
const actorID = this.changeID.getActorID();
|
|
20316
20355
|
const event = [];
|
|
20317
20356
|
if (opInfos.length > 0) {
|
|
@@ -20390,7 +20429,7 @@ function createAuthInterceptor(apiKey, token) {
|
|
|
20390
20429
|
};
|
|
20391
20430
|
}
|
|
20392
20431
|
const name = "@yorkie-js/sdk";
|
|
20393
|
-
const version = "0.6.
|
|
20432
|
+
const version = "0.6.12";
|
|
20394
20433
|
const pkg = {
|
|
20395
20434
|
name,
|
|
20396
20435
|
version
|
|
@@ -20558,16 +20597,15 @@ class Client {
|
|
|
20558
20597
|
if (this.status === "deactivated") {
|
|
20559
20598
|
return Promise.resolve();
|
|
20560
20599
|
}
|
|
20561
|
-
this.deactivateInternal();
|
|
20562
20600
|
const task = async () => {
|
|
20563
20601
|
try {
|
|
20564
20602
|
await this.rpcClient.deactivateClient(
|
|
20565
20603
|
{ clientId: this.id },
|
|
20566
20604
|
{ headers: { "x-shard-key": this.apiKey } }
|
|
20567
20605
|
);
|
|
20606
|
+
this.deactivateInternal();
|
|
20568
20607
|
logger.info(`[DC] c"${this.getKey()}" deactivated`);
|
|
20569
20608
|
} catch (err) {
|
|
20570
|
-
this.status = "activated";
|
|
20571
20609
|
logger.error(`[DC] c:"${this.getKey()}" err :`, err);
|
|
20572
20610
|
await this.handleConnectError(err);
|
|
20573
20611
|
throw err;
|
|
@@ -20651,12 +20689,12 @@ class Client {
|
|
|
20651
20689
|
await this.runWatchLoop(doc.getKey());
|
|
20652
20690
|
}
|
|
20653
20691
|
logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
|
|
20654
|
-
const
|
|
20692
|
+
const crdtObject = doc.getRootObject();
|
|
20655
20693
|
if (opts.initialRoot) {
|
|
20656
20694
|
const initialRoot = opts.initialRoot;
|
|
20657
20695
|
doc.update((root) => {
|
|
20658
20696
|
for (const [k, v] of Object.entries(initialRoot)) {
|
|
20659
|
-
if (!
|
|
20697
|
+
if (!crdtObject.has(k)) {
|
|
20660
20698
|
const key = k;
|
|
20661
20699
|
root[key] = v;
|
|
20662
20700
|
}
|
|
@@ -20679,7 +20717,7 @@ class Client {
|
|
|
20679
20717
|
* the changes should be applied to other replicas before GC time. For this,
|
|
20680
20718
|
* if the document is no longer used by this client, it should be detached.
|
|
20681
20719
|
*/
|
|
20682
|
-
detach(doc, opts = {
|
|
20720
|
+
detach(doc, opts = { keepalive: false }) {
|
|
20683
20721
|
if (!this.isActive()) {
|
|
20684
20722
|
throw new YorkieError(
|
|
20685
20723
|
Code.ErrClientNotActivated,
|
|
@@ -20694,14 +20732,14 @@ class Client {
|
|
|
20694
20732
|
);
|
|
20695
20733
|
}
|
|
20696
20734
|
doc.update((_, p) => p.clear());
|
|
20697
|
-
|
|
20735
|
+
const task = async () => {
|
|
20698
20736
|
try {
|
|
20699
20737
|
const res = await this.rpcClient.detachDocument(
|
|
20700
20738
|
{
|
|
20701
20739
|
clientId: this.id,
|
|
20702
20740
|
documentId: attachment.docID,
|
|
20703
20741
|
changePack: converter.toChangePack(doc.createChangePack()),
|
|
20704
|
-
removeIfNotAttached: opts.removeIfNotAttached
|
|
20742
|
+
removeIfNotAttached: opts.removeIfNotAttached ?? false
|
|
20705
20743
|
},
|
|
20706
20744
|
{ headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
|
|
20707
20745
|
);
|
|
@@ -20718,7 +20756,14 @@ class Client {
|
|
|
20718
20756
|
await this.handleConnectError(err);
|
|
20719
20757
|
throw err;
|
|
20720
20758
|
}
|
|
20721
|
-
}
|
|
20759
|
+
};
|
|
20760
|
+
if (opts.keepalive) {
|
|
20761
|
+
this.keepalive = true;
|
|
20762
|
+
const resp = task();
|
|
20763
|
+
this.keepalive = false;
|
|
20764
|
+
return resp;
|
|
20765
|
+
}
|
|
20766
|
+
return this.enqueueTask(task);
|
|
20722
20767
|
}
|
|
20723
20768
|
/**
|
|
20724
20769
|
* `changeRealtimeSync` changes the synchronization mode of the given document.
|