@yorkie-js/react 0.6.6 → 0.6.7-rc1

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.
@@ -1,3 +1,4 @@
1
+ import { ClientOptions } from '@yorkie-js/sdk';
1
2
  import { default as default_2 } from 'react';
2
3
  import { Indexable } from '@yorkie-js/sdk';
3
4
  import { JSONArray } from '@yorkie-js/sdk';
@@ -63,15 +64,10 @@ export declare const useRoot: () => {
63
64
  /**
64
65
  * `useYorkieDoc` is a custom hook that initializes a Yorkie Client and a
65
66
  * document in a single hook.
66
- *
67
- * @param apiKey
68
- * @param docKey
69
- * @returns
70
67
  */
71
- export declare function useYorkieDoc<R, P extends Indexable>(apiKey: string, docKey: string, options?: {
68
+ export declare function useYorkieDoc<R, P extends Indexable = Indexable>(apiKey: string, docKey: string, opts?: Omit<ClientOptions, 'apiKey'> & {
72
69
  initialRoot?: R;
73
70
  initialPresence?: P;
74
- rpcAddr?: string;
75
71
  }): {
76
72
  root: R;
77
73
  presences: Array<{
@@ -88,14 +84,6 @@ export declare function useYorkieDoc<R, P extends Indexable>(apiKey: string, doc
88
84
  * `YorkieProvider` is a component that provides the Yorkie client to its children.
89
85
  * It initializes the Yorkie client with the given API key and RPC address.
90
86
  */
91
- export declare const YorkieProvider: React.FC<PropsWithChildren<YorkieProviderProps>>;
92
-
93
- /**
94
- * `YorkieProviderProps` is a set of properties for `YorkieProvider`.
95
- */
96
- declare interface YorkieProviderProps {
97
- apiKey: string;
98
- rpcAddr?: string;
99
- }
87
+ export declare const YorkieProvider: React.FC<PropsWithChildren<ClientOptions>>;
100
88
 
101
89
  export { }
@@ -3,7 +3,13 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
5
5
  import { jsx } from "react/jsx-runtime";
6
- import { createContext, useState, useEffect, useContext, useCallback } from "react";
6
+ import { createContext, useMemo, useState, useEffect, useContext, useCallback } from "react";
7
+ const name$1 = "@yorkie-js/react";
8
+ const version$1 = "0.6.7-rc1";
9
+ const pkg$1 = {
10
+ name: name$1,
11
+ version: version$1
12
+ };
7
13
  var Code$1;
8
14
  (function(Code2) {
9
15
  Code2[Code2["Canceled"] = 1] = "Canceled";
@@ -3699,9 +3705,6 @@ function createClient(service, transport) {
3699
3705
  }
3700
3706
  });
3701
3707
  }
3702
- function createPromiseClient(service, transport) {
3703
- return createClient(service, transport);
3704
- }
3705
3708
  function createUnaryFn(transport, service, method) {
3706
3709
  return async function(input, options) {
3707
3710
  var _a2, _b2;
@@ -20242,9 +20245,13 @@ const pkg = {
20242
20245
  name,
20243
20246
  version
20244
20247
  };
20245
- function createMetricInterceptor() {
20248
+ function createMetricInterceptor(userAgent) {
20246
20249
  return (next) => async (req) => {
20247
- req.header.set("x-yorkie-user-agent", pkg.name + "/" + pkg.version);
20250
+ if (userAgent) {
20251
+ req.header.set("x-yorkie-user-agent", userAgent);
20252
+ } else {
20253
+ req.header.set("x-yorkie-user-agent", pkg.name + "/" + pkg.version);
20254
+ }
20248
20255
  return await next(req);
20249
20256
  };
20250
20257
  }
@@ -20267,6 +20274,7 @@ var SyncMode = /* @__PURE__ */ ((SyncMode2) => {
20267
20274
  return SyncMode2;
20268
20275
  })(SyncMode || {});
20269
20276
  const DefaultClientOptions = {
20277
+ rpcAddr: "https://api.yorkie.dev",
20270
20278
  syncLoopDuration: 50,
20271
20279
  retrySyncLoopDelay: 1e3,
20272
20280
  reconnectStreamDelay: 1e3
@@ -20281,7 +20289,7 @@ class Client {
20281
20289
  * @param rpcAddr - the address of the RPC server.
20282
20290
  * @param opts - the options of the client.
20283
20291
  */
20284
- constructor(rpcAddr, opts) {
20292
+ constructor(opts) {
20285
20293
  __publicField(this, "id");
20286
20294
  __publicField(this, "key");
20287
20295
  __publicField(this, "metadata");
@@ -20299,7 +20307,8 @@ class Client {
20299
20307
  __publicField(this, "processing", false);
20300
20308
  __publicField(this, "keepalive", false);
20301
20309
  opts = opts || DefaultClientOptions;
20302
- this.key = opts.key ? opts.key : uuid();
20310
+ const rpcAddr = opts.rpcAddr || DefaultClientOptions.rpcAddr;
20311
+ this.key = opts.key || uuid();
20303
20312
  this.metadata = opts.metadata || {};
20304
20313
  this.status = "deactivated";
20305
20314
  this.attachmentMap = /* @__PURE__ */ new Map();
@@ -20320,11 +20329,14 @@ class Client {
20320
20329
  this.retrySyncLoopDelay = opts.retrySyncLoopDelay ?? DefaultClientOptions.retrySyncLoopDelay;
20321
20330
  const { authInterceptor, setToken } = createAuthInterceptor(this.apiKey);
20322
20331
  this.setAuthToken = setToken;
20323
- this.rpcClient = createPromiseClient(
20332
+ this.rpcClient = createClient(
20324
20333
  YorkieService,
20325
20334
  createGrpcWebTransport({
20326
20335
  baseUrl: rpcAddr,
20327
- interceptors: [authInterceptor, createMetricInterceptor()],
20336
+ interceptors: [
20337
+ authInterceptor,
20338
+ createMetricInterceptor(opts == null ? void 0 : opts.userAgent)
20339
+ ],
20328
20340
  fetch: (input, init) => {
20329
20341
  const newInit = {
20330
20342
  ...init,
@@ -20350,22 +20362,28 @@ class Client {
20350
20362
  this.setAuthToken(token);
20351
20363
  }
20352
20364
  return this.enqueueTask(async () => {
20353
- return this.rpcClient.activateClient(
20354
- {
20355
- clientKey: this.key,
20356
- metadata: this.metadata
20357
- },
20358
- { headers: { "x-shard-key": this.apiKey } }
20359
- ).then((res) => {
20365
+ try {
20366
+ const res = await this.rpcClient.activateClient(
20367
+ {
20368
+ clientKey: this.key,
20369
+ metadata: this.metadata
20370
+ },
20371
+ { headers: { "x-shard-key": this.apiKey } }
20372
+ );
20360
20373
  this.id = res.clientId;
20361
20374
  this.status = "activated";
20362
20375
  this.runSyncLoop();
20363
20376
  logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
20364
- }).catch(async (err) => {
20377
+ if (typeof window !== "undefined") {
20378
+ window.addEventListener("beforeunload", async () => {
20379
+ await this.deactivate({ keepalive: true });
20380
+ });
20381
+ }
20382
+ } catch (err) {
20365
20383
  logger.error(`[AC] c:"${this.getKey()}" err :`, err);
20366
20384
  await this.handleConnectError(err);
20367
20385
  throw err;
20368
- });
20386
+ }
20369
20387
  });
20370
20388
  }
20371
20389
  /**
@@ -20414,7 +20432,7 @@ class Client {
20414
20432
  * `attach` attaches the given document to this client. It tells the server that
20415
20433
  * this client will synchronize the given document.
20416
20434
  */
20417
- attach(doc, options = {}) {
20435
+ attach(doc, opts = {}) {
20418
20436
  if (!this.isActive()) {
20419
20437
  throw new YorkieError(
20420
20438
  Code.ErrClientNotActivated,
@@ -20428,32 +20446,30 @@ class Client {
20428
20446
  );
20429
20447
  }
20430
20448
  doc.setActor(this.id);
20431
- doc.update((_, p) => p.set(options.initialPresence || {}));
20432
- const unsubscribeBroacastEvent = doc.subscribe(
20433
- "local-broadcast",
20434
- async (event) => {
20435
- var _a2;
20436
- const { topic, payload } = event.value;
20437
- const errorFn = (_a2 = event.options) == null ? void 0 : _a2.error;
20438
- const options2 = event.options;
20439
- try {
20440
- await this.broadcast(doc.getKey(), topic, payload, options2);
20441
- } catch (error) {
20442
- if (error instanceof Error) {
20443
- errorFn == null ? void 0 : errorFn(error);
20444
- }
20449
+ doc.update((_, p) => p.set(opts.initialPresence || {}));
20450
+ const unsub = doc.subscribe("local-broadcast", async (event) => {
20451
+ var _a2;
20452
+ const { topic, payload } = event.value;
20453
+ const errorFn = (_a2 = event.options) == null ? void 0 : _a2.error;
20454
+ const options = event.options;
20455
+ try {
20456
+ await this.broadcast(doc.getKey(), topic, payload, options);
20457
+ } catch (error) {
20458
+ if (error instanceof Error) {
20459
+ errorFn == null ? void 0 : errorFn(error);
20445
20460
  }
20446
20461
  }
20447
- );
20448
- const syncMode = options.syncMode ?? "realtime";
20462
+ });
20463
+ const syncMode = opts.syncMode ?? "realtime";
20449
20464
  return this.enqueueTask(async () => {
20450
- return this.rpcClient.attachDocument(
20451
- {
20452
- clientId: this.id,
20453
- changePack: converter.toChangePack(doc.createChangePack())
20454
- },
20455
- { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20456
- ).then(async (res) => {
20465
+ try {
20466
+ const res = await this.rpcClient.attachDocument(
20467
+ {
20468
+ clientId: this.id,
20469
+ changePack: converter.toChangePack(doc.createChangePack())
20470
+ },
20471
+ { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20472
+ );
20457
20473
  const pack = converter.fromChangePack(res.changePack);
20458
20474
  doc.applyChangePack(pack);
20459
20475
  if (doc.getStatus() === DocStatus.Removed) {
@@ -20467,7 +20483,7 @@ class Client {
20467
20483
  doc,
20468
20484
  res.documentId,
20469
20485
  syncMode,
20470
- unsubscribeBroacastEvent
20486
+ unsub
20471
20487
  )
20472
20488
  );
20473
20489
  if (syncMode !== "manual") {
@@ -20475,8 +20491,8 @@ class Client {
20475
20491
  }
20476
20492
  logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
20477
20493
  const crdtObject = doc.getRootObject();
20478
- if (options.initialRoot) {
20479
- const initialRoot = options.initialRoot;
20494
+ if (opts.initialRoot) {
20495
+ const initialRoot = opts.initialRoot;
20480
20496
  doc.update((root) => {
20481
20497
  for (const [k, v] of Object.entries(initialRoot)) {
20482
20498
  if (!crdtObject.has(k)) {
@@ -20487,11 +20503,11 @@ class Client {
20487
20503
  });
20488
20504
  }
20489
20505
  return doc;
20490
- }).catch(async (err) => {
20506
+ } catch (err) {
20491
20507
  logger.error(`[AD] c:"${this.getKey()}" err :`, err);
20492
20508
  await this.handleConnectError(err);
20493
20509
  throw err;
20494
- });
20510
+ }
20495
20511
  });
20496
20512
  }
20497
20513
  /**
@@ -20502,7 +20518,7 @@ class Client {
20502
20518
  * the changes should be applied to other replicas before GC time. For this,
20503
20519
  * if the document is no longer used by this client, it should be detached.
20504
20520
  */
20505
- detach(doc, options = { keepalive: false }) {
20521
+ detach(doc, opts = { keepalive: false }) {
20506
20522
  if (!this.isActive()) {
20507
20523
  throw new YorkieError(
20508
20524
  Code.ErrClientNotActivated,
@@ -20518,15 +20534,16 @@ class Client {
20518
20534
  }
20519
20535
  doc.update((_, p) => p.clear());
20520
20536
  const task = async () => {
20521
- return await this.rpcClient.detachDocument(
20522
- {
20523
- clientId: this.id,
20524
- documentId: attachment.docID,
20525
- changePack: converter.toChangePack(doc.createChangePack()),
20526
- removeIfNotAttached: options.removeIfNotAttached ?? false
20527
- },
20528
- { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20529
- ).then((res) => {
20537
+ try {
20538
+ const res = await this.rpcClient.detachDocument(
20539
+ {
20540
+ clientId: this.id,
20541
+ documentId: attachment.docID,
20542
+ changePack: converter.toChangePack(doc.createChangePack()),
20543
+ removeIfNotAttached: opts.removeIfNotAttached ?? false
20544
+ },
20545
+ { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20546
+ );
20530
20547
  const pack = converter.fromChangePack(res.changePack);
20531
20548
  doc.applyChangePack(pack);
20532
20549
  if (doc.getStatus() !== DocStatus.Removed) {
@@ -20535,13 +20552,13 @@ class Client {
20535
20552
  this.detachInternal(doc.getKey());
20536
20553
  logger.info(`[DD] c:"${this.getKey()}" detaches d:"${doc.getKey()}"`);
20537
20554
  return doc;
20538
- }).catch(async (err) => {
20555
+ } catch (err) {
20539
20556
  logger.error(`[DD] c:"${this.getKey()}" err :`, err);
20540
20557
  await this.handleConnectError(err);
20541
20558
  throw err;
20542
- });
20559
+ }
20543
20560
  };
20544
- if (options.keepalive) {
20561
+ if (opts.keepalive) {
20545
20562
  this.keepalive = true;
20546
20563
  const resp = task();
20547
20564
  this.keepalive = false;
@@ -20650,23 +20667,24 @@ class Client {
20650
20667
  const pbChangePack = converter.toChangePack(doc.createChangePack());
20651
20668
  pbChangePack.isRemoved = true;
20652
20669
  return this.enqueueTask(async () => {
20653
- return this.rpcClient.removeDocument(
20654
- {
20655
- clientId: this.id,
20656
- documentId: attachment.docID,
20657
- changePack: pbChangePack
20658
- },
20659
- { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20660
- ).then((res) => {
20670
+ try {
20671
+ const res = await this.rpcClient.removeDocument(
20672
+ {
20673
+ clientId: this.id,
20674
+ documentId: attachment.docID,
20675
+ changePack: pbChangePack
20676
+ },
20677
+ { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20678
+ );
20661
20679
  const pack = converter.fromChangePack(res.changePack);
20662
20680
  doc.applyChangePack(pack);
20663
20681
  this.detachInternal(doc.getKey());
20664
20682
  logger.info(`[RD] c:"${this.getKey()}" removes d:"${doc.getKey()}"`);
20665
- }).catch(async (err) => {
20683
+ } catch (err) {
20666
20684
  logger.error(`[RD] c:"${this.getKey()}" err :`, err);
20667
20685
  await this.handleConnectError(err);
20668
20686
  throw err;
20669
- });
20687
+ }
20670
20688
  });
20671
20689
  }
20672
20690
  /**
@@ -20734,19 +20752,20 @@ class Client {
20734
20752
  };
20735
20753
  const doLoop = async () => {
20736
20754
  return this.enqueueTask(async () => {
20737
- return this.rpcClient.broadcast(
20738
- {
20739
- clientId: this.id,
20740
- documentId: attachment.docID,
20741
- topic,
20742
- payload: new TextEncoder().encode(JSON.stringify(payload))
20743
- },
20744
- { headers: { "x-shard-key": `${this.apiKey}/${docKey}` } }
20745
- ).then(() => {
20755
+ try {
20756
+ await this.rpcClient.broadcast(
20757
+ {
20758
+ clientId: this.id,
20759
+ documentId: attachment.docID,
20760
+ topic,
20761
+ payload: new TextEncoder().encode(JSON.stringify(payload))
20762
+ },
20763
+ { headers: { "x-shard-key": `${this.apiKey}/${docKey}` } }
20764
+ );
20746
20765
  logger.info(
20747
20766
  `[BC] c:"${this.getKey()}" broadcasts d:"${docKey}" t:"${topic}"`
20748
20767
  );
20749
- }).catch(async (err) => {
20768
+ } catch (err) {
20750
20769
  logger.error(`[BC] c:"${this.getKey()}" err:`, err);
20751
20770
  if (await this.handleConnectError(err)) {
20752
20771
  if (err instanceof ConnectError && errorCodeOf(err) === Code.ErrUnauthenticated) {
@@ -20775,7 +20794,7 @@ class Client {
20775
20794
  } else {
20776
20795
  throw err;
20777
20796
  }
20778
- });
20797
+ }
20779
20798
  });
20780
20799
  };
20781
20800
  return doLoop();
@@ -20960,19 +20979,20 @@ class Client {
20960
20979
  attachment.unsubscribeBroadcastEvent();
20961
20980
  this.attachmentMap.delete(docKey);
20962
20981
  }
20963
- syncInternal(attachment, syncMode) {
20982
+ async syncInternal(attachment, syncMode) {
20964
20983
  const { doc, docID } = attachment;
20965
20984
  const reqPack = doc.createChangePack();
20966
- return this.rpcClient.pushPullChanges(
20967
- {
20968
- clientId: this.id,
20969
- documentId: docID,
20970
- changePack: converter.toChangePack(reqPack),
20971
- pushOnly: syncMode === "realtime-pushonly"
20972
- /* RealtimePushOnly */
20973
- },
20974
- { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20975
- ).then((res) => {
20985
+ try {
20986
+ const res = await this.rpcClient.pushPullChanges(
20987
+ {
20988
+ clientId: this.id,
20989
+ documentId: docID,
20990
+ changePack: converter.toChangePack(reqPack),
20991
+ pushOnly: syncMode === "realtime-pushonly"
20992
+ /* RealtimePushOnly */
20993
+ },
20994
+ { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20995
+ );
20976
20996
  const respPack = converter.fromChangePack(res.changePack);
20977
20997
  if (respPack.hasChanges() && (attachment.syncMode === "realtime-pushonly" || attachment.syncMode === "realtime-syncoff")) {
20978
20998
  return doc;
@@ -20993,7 +21013,7 @@ class Client {
20993
21013
  `[PP] c:"${this.getKey()}" sync d:"${docKey}", push:${reqPack.getChangeSize()} pull:${remoteSize} cp:${respPack.getCheckpoint().toTestString()}`
20994
21014
  );
20995
21015
  return doc;
20996
- }).catch(async (err) => {
21016
+ } catch (err) {
20997
21017
  doc.publish([
20998
21018
  {
20999
21019
  type: DocEventType.SyncStatusChanged,
@@ -21002,7 +21022,7 @@ class Client {
21002
21022
  ]);
21003
21023
  logger.error(`[PP] c:"${this.getKey()}" err :`, err);
21004
21024
  throw err;
21005
- });
21025
+ }
21006
21026
  }
21007
21027
  /**
21008
21028
  * `handleConnectError` handles the given error. If the given error can be
@@ -21087,7 +21107,7 @@ const YorkieContext = createContext({
21087
21107
  loading: true,
21088
21108
  error: void 0
21089
21109
  });
21090
- function useYorkieClient(apiKey, rpcAddr) {
21110
+ function useYorkieClient(opts) {
21091
21111
  const [client, setClient] = useState(void 0);
21092
21112
  const [loading, setLoading] = useState(true);
21093
21113
  const [error, setError] = useState(void 0);
@@ -21103,9 +21123,7 @@ function useYorkieClient(apiKey, rpcAddr) {
21103
21123
  return;
21104
21124
  }
21105
21125
  try {
21106
- const newClient = new Client(rpcAddr, {
21107
- apiKey
21108
- });
21126
+ const newClient = new Client(opts);
21109
21127
  await newClient.activate();
21110
21128
  setClient(newClient);
21111
21129
  } catch (e) {
@@ -21122,11 +21140,20 @@ function useYorkieClient(apiKey, rpcAddr) {
21122
21140
  client.deactivate({ keepalive: true });
21123
21141
  }
21124
21142
  };
21125
- }, [apiKey, rpcAddr, didMount]);
21143
+ }, [opts.apiKey, opts.rpcAddr, didMount]);
21126
21144
  return { client, loading, error };
21127
21145
  }
21128
- const YorkieProvider = ({ apiKey, rpcAddr = "https://api.yorkie.dev", children }) => {
21129
- const { client, loading, error } = useYorkieClient(apiKey, rpcAddr);
21146
+ const YorkieProvider = ({
21147
+ children,
21148
+ ...opts
21149
+ }) => {
21150
+ const clientOpts = useMemo(() => {
21151
+ return {
21152
+ userAgent: pkg$1.name + "/" + pkg$1.version,
21153
+ ...opts
21154
+ };
21155
+ }, [opts.apiKey, opts.rpcAddr]);
21156
+ const { client, loading, error } = useYorkieClient(clientOpts);
21130
21157
  return /* @__PURE__ */ jsx(YorkieContext.Provider, { value: { client, loading, error }, children });
21131
21158
  };
21132
21159
  const useYorkie = () => {
@@ -21289,22 +21316,26 @@ const useConnection = () => {
21289
21316
  }
21290
21317
  return context.connection;
21291
21318
  };
21292
- function useYorkieDoc(apiKey, docKey, options) {
21293
- const rpcAddr = (options == null ? void 0 : options.rpcAddr) || "https://api.yorkie.dev";
21294
- const initialRoot = (options == null ? void 0 : options.initialRoot) || {};
21295
- const initialPresence = (options == null ? void 0 : options.initialPresence) || {};
21319
+ function useYorkieDoc(apiKey, docKey, opts) {
21320
+ const clientOpts = useMemo(() => {
21321
+ return {
21322
+ apiKey,
21323
+ userAgent: pkg$1.name + "/" + pkg$1.version,
21324
+ ...opts
21325
+ };
21326
+ }, [apiKey]);
21296
21327
  const {
21297
21328
  client,
21298
21329
  loading: clientLoading,
21299
21330
  error: clientError
21300
- } = useYorkieClient(apiKey, rpcAddr);
21331
+ } = useYorkieClient(clientOpts);
21301
21332
  const { root, presences, connection, update, loading, error } = useYorkieDocument(
21302
21333
  client,
21303
21334
  clientLoading,
21304
21335
  clientError,
21305
21336
  docKey,
21306
- initialRoot,
21307
- initialPresence
21337
+ opts == null ? void 0 : opts.initialRoot,
21338
+ opts == null ? void 0 : opts.initialPresence
21308
21339
  );
21309
21340
  return {
21310
21341
  root,