@yorkie-js/react 0.7.7 → 0.7.8

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.
@@ -362,7 +362,7 @@
362
362
  }
363
363
  }
364
364
  const IMPLICIT$3 = 2;
365
- const unsafeLocal = Symbol.for("reflect unsafe local");
365
+ const unsafeLocal = /* @__PURE__ */ Symbol.for("reflect unsafe local");
366
366
  function unsafeOneofCase(target, oneof) {
367
367
  const c = target[oneof.localName].case;
368
368
  if (c === void 0) {
@@ -588,7 +588,7 @@
588
588
  }
589
589
  return ret;
590
590
  }
591
- const tokenZeroMessageField = Symbol();
591
+ const tokenZeroMessageField = /* @__PURE__ */ Symbol();
592
592
  const messagePrototypes = /* @__PURE__ */ new WeakMap();
593
593
  function createZeroMessage(desc) {
594
594
  let msg;
@@ -690,7 +690,7 @@
690
690
  function isFieldError(arg) {
691
691
  return arg instanceof Error && errorNames.includes(arg.name) && "field" in arg && typeof arg.field == "function";
692
692
  }
693
- const symbol = Symbol.for("@bufbuild/protobuf/text-encoding");
693
+ const symbol = /* @__PURE__ */ Symbol.for("@bufbuild/protobuf/text-encoding");
694
694
  function getTextEncoding() {
695
695
  if (globalThis[symbol] == void 0) {
696
696
  const te = new globalThis.TextEncoder();
@@ -4058,7 +4058,7 @@
4058
4058
  msg.set(field, scalarValue);
4059
4059
  }
4060
4060
  }
4061
- const tokenIgnoredUnknownEnum = Symbol();
4061
+ const tokenIgnoredUnknownEnum = /* @__PURE__ */ Symbol();
4062
4062
  function readEnum(desc, json, ignoreUnknownFields, nullAsZeroValue) {
4063
4063
  if (json === null) {
4064
4064
  if (desc.typeName == "google.protobuf.NullValue") {
@@ -4084,7 +4084,7 @@
4084
4084
  }
4085
4085
  throw new Error(`cannot decode ${desc} from JSON: ${formatVal(json)}`);
4086
4086
  }
4087
- const tokenNull = Symbol();
4087
+ const tokenNull = /* @__PURE__ */ Symbol();
4088
4088
  function scalarFromJson(field, json, nullAsZeroValue) {
4089
4089
  if (json === null) {
4090
4090
  if (nullAsZeroValue) {
@@ -5905,6 +5905,8 @@
5905
5905
  this.message = message;
5906
5906
  this.toString = () => `[code=${this.code}]: ${this.message}`;
5907
5907
  }
5908
+ code;
5909
+ message;
5908
5910
  name = "YorkieError";
5909
5911
  stack;
5910
5912
  }
@@ -12534,8 +12536,10 @@
12534
12536
  break;
12535
12537
  }
12536
12538
  if (next.parent && next.parent === toParent) {
12537
- collectFromLeft = next;
12538
- collectFromParent = toParent;
12539
+ if (toLeft !== toParent) {
12540
+ collectFromLeft = next;
12541
+ collectFromParent = toParent;
12542
+ }
12539
12543
  break;
12540
12544
  }
12541
12545
  current = next;
@@ -12598,6 +12602,7 @@
12598
12602
  tokensToBeRemoved,
12599
12603
  editedAt
12600
12604
  );
12605
+ const mergeLevel = toBeMergedNodes.length;
12601
12606
  const pairs = [];
12602
12607
  for (const node of nodesToBeRemoved) {
12603
12608
  if (node.remove(editedAt)) {
@@ -12724,7 +12729,15 @@
12724
12729
  }
12725
12730
  }
12726
12731
  }
12727
- return [changes, pairs, diff, nodesToBeRemoved, fromIdx];
12732
+ return [
12733
+ changes,
12734
+ pairs,
12735
+ diff,
12736
+ nodesToBeRemoved,
12737
+ fromIdx,
12738
+ mergeLevel,
12739
+ preTombstoned
12740
+ ];
12728
12741
  }
12729
12742
  /**
12730
12743
  * `editT` edits the given range with the given value.
@@ -13165,11 +13178,35 @@
13165
13178
  return [prev, prev.isText ? TokenType.Text : TokenType.End];
13166
13179
  }
13167
13180
  }
13168
- function clearRemovedAt(node) {
13169
- traverseAll(node, (n) => {
13181
+ function cloneAndDropPreTombstoned(node, preTombstoned) {
13182
+ const clone = node.deepcopy();
13183
+ filterChildren(clone, preTombstoned);
13184
+ traverseAll(clone, (n) => {
13170
13185
  n.removedAt = void 0;
13171
- n.visibleSize = n.totalSize;
13186
+ if (n.isText) {
13187
+ n.visibleSize = n.value.length;
13188
+ n.totalSize = n.value.length;
13189
+ return;
13190
+ }
13191
+ let size = 0;
13192
+ for (const child of n._children) size += child.paddedSize();
13193
+ n.visibleSize = size;
13194
+ n.totalSize = size;
13172
13195
  });
13196
+ return clone;
13197
+ }
13198
+ function filterChildren(node, preTombstoned) {
13199
+ const all = node._children;
13200
+ if (!all) return;
13201
+ const kept = [];
13202
+ for (const child of all) {
13203
+ if (preTombstoned.has(child.id.toIDString())) {
13204
+ continue;
13205
+ }
13206
+ filterChildren(child, preTombstoned);
13207
+ kept.push(child);
13208
+ }
13209
+ node._children = kept;
13173
13210
  }
13174
13211
  class TreeEditOperation extends Operation {
13175
13212
  fromPos;
@@ -13241,7 +13278,15 @@
13241
13278
  this.toPos = tree.findPos(this.toIdx);
13242
13279
  }
13243
13280
  }
13244
- const [changes, pairs, diff, removedNodes, preEditFromIdx] = tree.edit(
13281
+ const [
13282
+ changes,
13283
+ pairs,
13284
+ diff,
13285
+ removedNodes,
13286
+ preEditFromIdx,
13287
+ mergeLevel,
13288
+ preTombstoned
13289
+ ] = tree.edit(
13245
13290
  [this.fromPos, this.toPos],
13246
13291
  this.contents?.map((content) => content.deepcopy()),
13247
13292
  this.splitLevel,
@@ -13276,7 +13321,13 @@
13276
13321
  let reverseOp;
13277
13322
  const isPureSplit = this.splitLevel > 0 && !this.contents?.length && removedNodes.length === 0;
13278
13323
  if (this.splitLevel === 0) {
13279
- reverseOp = this.toReverseOperation(tree, removedNodes, preEditFromIdx);
13324
+ reverseOp = this.toReverseOperation(
13325
+ tree,
13326
+ removedNodes,
13327
+ preEditFromIdx,
13328
+ preTombstoned,
13329
+ mergeLevel
13330
+ );
13280
13331
  } else if (isPureSplit) {
13281
13332
  reverseOp = this.toSplitReverseOperation(tree, preEditFromIdx);
13282
13333
  }
@@ -13314,7 +13365,7 @@
13314
13365
  * @param removedNodes - Nodes that were removed by this edit
13315
13366
  * @param preEditFromIdx - The from index captured BEFORE the edit
13316
13367
  */
13317
- toReverseOperation(tree, removedNodes, preEditFromIdx) {
13368
+ toReverseOperation(tree, removedNodes, preEditFromIdx, preTombstoned, mergeLevel) {
13318
13369
  if (this.redoSplitLevel !== void 0 && this.redoSplitLevel > 0) {
13319
13370
  const splitRedoFromPos = tree.findPos(preEditFromIdx);
13320
13371
  const splitRedoOp = TreeEditOperation.create(
@@ -13333,19 +13384,36 @@
13333
13384
  );
13334
13385
  return splitRedoOp;
13335
13386
  }
13387
+ if (mergeLevel && mergeLevel > 0) {
13388
+ const splitFromPos = tree.findPos(preEditFromIdx);
13389
+ const splitUndoOp = TreeEditOperation.create(
13390
+ this.getParentCreatedAt(),
13391
+ splitFromPos,
13392
+ splitFromPos,
13393
+ void 0,
13394
+ // no inserted content — split creates boundaries
13395
+ mergeLevel,
13396
+ // splitLevel = number of merged boundaries
13397
+ void 0,
13398
+ // executedAt assigned at undo time
13399
+ true,
13400
+ // isUndoOp
13401
+ preEditFromIdx,
13402
+ preEditFromIdx
13403
+ );
13404
+ return splitUndoOp;
13405
+ }
13336
13406
  const insertedContentSize = this.contents ? this.contents.reduce((sum, node) => sum + node.paddedSize(), 0) : 0;
13337
13407
  const maxNeededIdx = preEditFromIdx + insertedContentSize;
13338
13408
  if (maxNeededIdx > tree.getSize()) {
13339
13409
  return void 0;
13340
13410
  }
13341
13411
  const topLevelRemoved = removedNodes.filter(
13342
- (node) => !node.parent || !removedNodes.includes(node.parent)
13412
+ (node) => !preTombstoned.has(node.id.toIDString()) && (!node.parent || !removedNodes.includes(node.parent))
13343
13413
  );
13344
- const reverseContents = topLevelRemoved.length > 0 ? topLevelRemoved.map((n) => {
13345
- const clone = n.deepcopy();
13346
- clearRemovedAt(clone);
13347
- return clone;
13348
- }) : void 0;
13414
+ const reverseContents = topLevelRemoved.length > 0 ? topLevelRemoved.map(
13415
+ (n) => cloneAndDropPreTombstoned(n, preTombstoned)
13416
+ ) : void 0;
13349
13417
  const reverseFromPos = tree.findPos(preEditFromIdx);
13350
13418
  let reverseToPos;
13351
13419
  if (insertedContentSize > 0) {
@@ -20159,6 +20227,11 @@
20159
20227
  }
20160
20228
  ]);
20161
20229
  }
20230
+ /**
20231
+ * `clearHistory` flushes both undo and redo stacks. This is used
20232
+ * after applying a snapshot or initialRoot so that setup operations
20233
+ * are not reachable via undo.
20234
+ */
20162
20235
  clearHistory() {
20163
20236
  this.internalHistory.clearRedo();
20164
20237
  this.internalHistory.clearUndo();
@@ -20618,10 +20691,7 @@
20618
20691
  }
20619
20692
  const ops = isUndo ? this.internalHistory.popUndo() : this.internalHistory.popRedo();
20620
20693
  if (!ops) {
20621
- throw new YorkieError(
20622
- Code.ErrRefused,
20623
- `There is no operation to be ${isUndo ? "undone" : "redone"}`
20624
- );
20694
+ return;
20625
20695
  }
20626
20696
  this.ensureClone();
20627
20697
  const ctx = ChangeContext.create(
@@ -20714,6 +20784,8 @@
20714
20784
  syncMode;
20715
20785
  changeEventReceived;
20716
20786
  lastHeartbeatTime;
20787
+ pollInterval;
20788
+ pollIntervalPinned;
20717
20789
  reconnectStreamDelay;
20718
20790
  cancelled;
20719
20791
  watchStream;
@@ -20721,13 +20793,15 @@
20721
20793
  watchAbortController;
20722
20794
  syncPromise;
20723
20795
  _detaching = false;
20724
- constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
20796
+ constructor(reconnectStreamDelay, resource, resourceID, syncMode, pollInterval = 0, pollIntervalPinned = false) {
20725
20797
  this.reconnectStreamDelay = reconnectStreamDelay;
20726
20798
  this.resource = resource;
20727
20799
  this.resourceID = resourceID;
20728
20800
  this.syncMode = syncMode;
20729
20801
  this.changeEventReceived = syncMode !== void 0 ? false : void 0;
20730
20802
  this.lastHeartbeatTime = Date.now();
20803
+ this.pollInterval = pollInterval;
20804
+ this.pollIntervalPinned = pollIntervalPinned;
20731
20805
  this.cancelled = false;
20732
20806
  }
20733
20807
  /**
@@ -20747,6 +20821,9 @@
20747
20821
  if (this.syncMode === SyncMode.RealtimePushOnly) {
20748
20822
  return this.resource.hasLocalChanges();
20749
20823
  }
20824
+ if (this.syncMode === SyncMode.Polling) {
20825
+ return Date.now() - this.lastHeartbeatTime >= this.pollInterval;
20826
+ }
20750
20827
  return this.syncMode !== SyncMode.Manual && (this.resource.hasLocalChanges() || (this.changeEventReceived ?? false));
20751
20828
  }
20752
20829
  /**
@@ -20760,7 +20837,8 @@
20760
20837
  if (this.syncMode === SyncMode.Manual) {
20761
20838
  return false;
20762
20839
  }
20763
- return Date.now() - this.lastHeartbeatTime >= heartbeatInterval;
20840
+ const interval = this.pollInterval > 0 ? this.pollInterval : heartbeatInterval;
20841
+ return Date.now() - this.lastHeartbeatTime >= interval;
20764
20842
  }
20765
20843
  /**
20766
20844
  * `updateHeartbeatTime` updates the last heartbeat time.
@@ -20839,6 +20917,16 @@
20839
20917
  }
20840
20918
  }
20841
20919
  }
20920
+ /**
20921
+ * `resetCancelled` clears the cancelled flag so the watch loop can run again
20922
+ * after a previous cancellation (e.g., after changeSyncMode back to Realtime).
20923
+ * Caller must invoke `runWatchLoop` immediately after to claim the stream slot;
20924
+ * `doLoop`'s `if (this.watchStream)` guard prevents double-stream creation if a
20925
+ * delayed `onDisconnect` callback from the previously-cancelled stream races.
20926
+ */
20927
+ resetCancelled() {
20928
+ this.cancelled = false;
20929
+ }
20842
20930
  /**
20843
20931
  * `cancelWatchStream` cancels the watch stream.
20844
20932
  */
@@ -20873,7 +20961,7 @@
20873
20961
  };
20874
20962
  }
20875
20963
  const name$1 = "@yorkie-js/sdk";
20876
- const version$1 = "0.7.7";
20964
+ const version$1 = "0.7.8";
20877
20965
  const pkg$1 = {
20878
20966
  name: name$1,
20879
20967
  version: version$1
@@ -21156,8 +21244,10 @@
21156
21244
  SyncMode2["Realtime"] = "realtime";
21157
21245
  SyncMode2["RealtimePushOnly"] = "realtime-pushonly";
21158
21246
  SyncMode2["RealtimeSyncOff"] = "realtime-syncoff";
21247
+ SyncMode2["Polling"] = "polling";
21159
21248
  return SyncMode2;
21160
21249
  })(SyncMode || {});
21250
+ const DefaultPollingIntervalMs = 3e3;
21161
21251
  const DefaultClientOptions = {
21162
21252
  rpcAddr: "https://api.yorkie.dev",
21163
21253
  syncLoopDuration: 50,
@@ -21353,6 +21443,14 @@
21353
21443
  doc.setActor(this.id);
21354
21444
  doc.update((_, p) => p.set(opts.initialPresence || {}));
21355
21445
  const syncMode = opts.syncMode ?? "realtime";
21446
+ if (opts.documentPollInterval !== void 0 && opts.documentPollInterval <= 0) {
21447
+ throw new YorkieError(
21448
+ Code.ErrInvalidArgument,
21449
+ "documentPollInterval must be greater than 0"
21450
+ );
21451
+ }
21452
+ const pollIntervalPinned = opts.documentPollInterval !== void 0;
21453
+ const pollInterval = pollIntervalPinned ? opts.documentPollInterval : syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21356
21454
  return this.enqueueTask(async () => {
21357
21455
  try {
21358
21456
  const res = await this.rpcClient.attachDocument(
@@ -21382,10 +21480,12 @@
21382
21480
  this.reconnectStreamDelay,
21383
21481
  doc,
21384
21482
  res.documentId,
21385
- syncMode
21483
+ syncMode,
21484
+ pollInterval,
21485
+ pollIntervalPinned
21386
21486
  )
21387
21487
  );
21388
- if (syncMode !== "manual") {
21488
+ if (syncMode !== "manual" && syncMode !== "polling") {
21389
21489
  await this.runWatchLoop(doc.getKey());
21390
21490
  }
21391
21491
  logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
@@ -21401,6 +21501,7 @@
21401
21501
  }
21402
21502
  });
21403
21503
  }
21504
+ doc.clearHistory();
21404
21505
  return doc;
21405
21506
  } catch (err) {
21406
21507
  logger.error(`[AD] c:"${this.getKey()}" err :`, err);
@@ -21511,12 +21612,23 @@
21511
21612
  channel.setSessionID(res.sessionId);
21512
21613
  channel.updateSessionCount(Number(res.sessionCount), 0);
21513
21614
  channel.applyStatus(ChannelStatus.Attached);
21514
- const syncMode = opts.isRealtime !== false ? "realtime" : "manual";
21615
+ const syncMode = opts.syncMode ?? "realtime";
21616
+ this.assertValidChannelSyncMode(syncMode);
21617
+ if (opts.channelHeartbeatInterval !== void 0 && opts.channelHeartbeatInterval <= 0) {
21618
+ throw new YorkieError(
21619
+ Code.ErrInvalidArgument,
21620
+ "channelHeartbeatInterval must be greater than 0"
21621
+ );
21622
+ }
21623
+ const pollIntervalPinned = opts.channelHeartbeatInterval !== void 0;
21624
+ const pollInterval = pollIntervalPinned ? opts.channelHeartbeatInterval : syncMode === "polling" ? DefaultPollingIntervalMs : this.channelHeartbeatInterval;
21515
21625
  const attachment = new Attachment(
21516
21626
  this.reconnectStreamDelay,
21517
21627
  channel,
21518
21628
  res.sessionId,
21519
- syncMode
21629
+ syncMode,
21630
+ pollInterval,
21631
+ pollIntervalPinned
21520
21632
  );
21521
21633
  channel.subscribe("local-broadcast", (event) => {
21522
21634
  const { topic, payload, options } = event;
@@ -21592,9 +21704,17 @@
21592
21704
  return this.enqueueTask(task);
21593
21705
  }
21594
21706
  /**
21595
- * `changeSyncMode` changes the synchronization mode of the given document.
21707
+ * `changeSyncMode` changes the synchronization mode of the given resource.
21596
21708
  */
21597
- async changeSyncMode(doc, syncMode) {
21709
+ async changeSyncMode(resource, syncMode) {
21710
+ return this.enqueueTask(async () => {
21711
+ if (resource instanceof Channel) {
21712
+ return this.changeChannelSyncMode(resource, syncMode);
21713
+ }
21714
+ return this.changeDocumentSyncMode(resource, syncMode);
21715
+ });
21716
+ }
21717
+ async changeDocumentSyncMode(doc, syncMode) {
21598
21718
  if (!this.isActive()) {
21599
21719
  throw new YorkieError(
21600
21720
  Code.ErrClientNotActivated,
@@ -21612,19 +21732,66 @@
21612
21732
  if (prevSyncMode === syncMode) {
21613
21733
  return doc;
21614
21734
  }
21615
- attachment.changeSyncMode(syncMode);
21616
- if (syncMode === "manual") {
21735
+ if (syncMode === "manual" || syncMode === "polling") {
21617
21736
  attachment.cancelWatchStream();
21618
- return doc;
21619
21737
  }
21738
+ attachment.changeSyncMode(syncMode);
21620
21739
  if (syncMode === "realtime") {
21621
21740
  attachment.changeEventReceived = true;
21622
21741
  }
21623
- if (prevSyncMode === "manual") {
21742
+ if (!attachment.pollIntervalPinned) {
21743
+ attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21744
+ }
21745
+ if ((prevSyncMode === "manual" || prevSyncMode === "polling") && syncMode !== "manual" && syncMode !== "polling") {
21746
+ attachment.resetCancelled();
21624
21747
  await this.runWatchLoop(doc.getKey());
21625
21748
  }
21626
21749
  return doc;
21627
21750
  }
21751
+ /**
21752
+ * `assertValidChannelSyncMode` rejects sync modes that are not valid for
21753
+ * channels. `RealtimePushOnly` and `RealtimeSyncOff` are document-only.
21754
+ */
21755
+ assertValidChannelSyncMode(syncMode) {
21756
+ if (syncMode !== "manual" && syncMode !== "realtime" && syncMode !== "polling") {
21757
+ throw new YorkieError(
21758
+ Code.ErrInvalidArgument,
21759
+ `invalid channel sync mode: ${syncMode}`
21760
+ );
21761
+ }
21762
+ }
21763
+ async changeChannelSyncMode(channel, syncMode) {
21764
+ if (!this.isActive()) {
21765
+ throw new YorkieError(
21766
+ Code.ErrClientNotActivated,
21767
+ `${this.key} is not active`
21768
+ );
21769
+ }
21770
+ const attachment = this.attachmentMap.get(channel.getKey());
21771
+ if (!attachment) {
21772
+ throw new YorkieError(
21773
+ Code.ErrNotAttached,
21774
+ `${channel.getKey()} is not attached`
21775
+ );
21776
+ }
21777
+ const prevSyncMode = attachment.syncMode;
21778
+ if (prevSyncMode === syncMode) {
21779
+ return channel;
21780
+ }
21781
+ this.assertValidChannelSyncMode(syncMode);
21782
+ if (prevSyncMode === "realtime") {
21783
+ attachment.cancelWatchStream();
21784
+ }
21785
+ attachment.changeSyncMode(syncMode);
21786
+ if (!attachment.pollIntervalPinned) {
21787
+ attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : syncMode === "realtime" ? this.channelHeartbeatInterval : 0;
21788
+ }
21789
+ if (syncMode === "realtime") {
21790
+ attachment.resetCancelled();
21791
+ await this.runWatchLoop(channel.getKey());
21792
+ }
21793
+ return channel;
21794
+ }
21628
21795
  /**
21629
21796
  * `sync` implementation that handles both Document and Channel.
21630
21797
  */
@@ -22469,6 +22636,7 @@
22469
22636
  return doc;
22470
22637
  }
22471
22638
  doc.applyChangePack(respPack);
22639
+ attachment.updateHeartbeatTime();
22472
22640
  attachment.resource.publish([
22473
22641
  {
22474
22642
  type: DocEventType.SyncStatusChanged,
@@ -22794,7 +22962,7 @@
22794
22962
  };
22795
22963
  }
22796
22964
  const name = "@yorkie-js/react";
22797
- const version = "0.7.7";
22965
+ const version = "0.7.8";
22798
22966
  const pkg = {
22799
22967
  name,
22800
22968
  version
@@ -23250,7 +23418,7 @@
23250
23418
  const ChannelContext = react.createContext(
23251
23419
  void 0
23252
23420
  );
23253
- function useYorkieChannel(client, clientLoading, clientError, channelKey, isRealtime, channelStore) {
23421
+ function useYorkieChannel(client, clientLoading, clientError, channelKey, syncMode, channelStore) {
23254
23422
  const channelRef = react.useRef(void 0);
23255
23423
  const [didMount, setDidMount] = react.useState(false);
23256
23424
  react.useEffect(() => {
@@ -23279,7 +23447,7 @@
23279
23447
  }));
23280
23448
  try {
23281
23449
  const newChannel = new Channel(channelKey);
23282
- await client.attach(newChannel, { isRealtime });
23450
+ await client.attach(newChannel, { syncMode });
23283
23451
  channelRef.current = newChannel;
23284
23452
  unsubscribe = newChannel.subscribe(() => {
23285
23453
  channelStore.setState((state) => ({
@@ -23317,12 +23485,13 @@
23317
23485
  }
23318
23486
  detachChannel();
23319
23487
  };
23320
- }, [client, clientLoading, clientError, channelKey, isRealtime, didMount]);
23488
+ }, [client, clientLoading, clientError, channelKey, syncMode, didMount]);
23321
23489
  }
23322
23490
  const ChannelProvider = ({
23323
23491
  children,
23324
23492
  channelKey,
23325
- isRealtime = true
23493
+ syncMode,
23494
+ isRealtime
23326
23495
  }) => {
23327
23496
  const { client, loading: clientLoading, error: clientError } = useYorkie();
23328
23497
  const channelStoreRef = react.useRef(
@@ -23337,12 +23506,13 @@
23337
23506
  });
23338
23507
  }
23339
23508
  const channelStore = channelStoreRef.current;
23509
+ const resolvedSyncMode = syncMode ?? (isRealtime === false ? SyncMode.Manual : SyncMode.Realtime);
23340
23510
  useYorkieChannel(
23341
23511
  client,
23342
23512
  clientLoading,
23343
23513
  clientError,
23344
23514
  channelKey,
23345
- isRealtime,
23515
+ resolvedSyncMode,
23346
23516
  channelStore
23347
23517
  );
23348
23518
  return /* @__PURE__ */ jsxRuntime.jsx(ChannelContext.Provider, { value: channelStore, children });
@@ -23368,6 +23538,7 @@
23368
23538
  exports2.ChannelProvider = ChannelProvider;
23369
23539
  exports2.Counter = Counter;
23370
23540
  exports2.DocumentProvider = DocumentProvider;
23541
+ exports2.SyncMode = SyncMode;
23371
23542
  exports2.Text = Text;
23372
23543
  exports2.Tree = Tree;
23373
23544
  exports2.YorkieProvider = YorkieProvider;