@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.
@@ -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 id;
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(id: ChangeID, root: CRDTRoot, presence: P, message?: string);
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>(id: ChangeID, root: CRDTRoot, presence: P, message?: string): ChangeContext<P>;
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
- * `getChange` creates a new instance of Change in this context.
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
- getChange(): Change<P>;
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
  */
@@ -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
- 0n,
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
- // `lamport` and `actor` are the lamport clock and the actor of this change.
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(id, root, presence, message) {
16930
- __publicField(this, "id");
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.id = id;
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(id, root, presence, message) {
16959
- return new ChangeContext(id, root, presence, message);
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
- * `getChange` creates a new instance of Change in this context.
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
- getChange() {
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: this.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.id.createTimeTicket(this.delimiter);
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.id.createTimeTicket(this.delimiter);
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.next(),
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.getChange();
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 = change.getID();
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.next(),
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.getChange();
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 = change.getID();
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.next(),
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.getChange();
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 = change.getID();
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.11-rc";
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 crdtRoot = doc.getRootObject();
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 (!crdtRoot.has(k)) {
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 = { removeIfNotAttached: false }) {
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
- return this.enqueueTask(async () => {
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.