@yorkie-js/react 0.7.9 → 0.7.10-rc

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.
@@ -5867,7 +5867,7 @@ var DocEventType$1 = /* @__PURE__ */ ((DocEventType2) => {
5867
5867
  DocEventType2[DocEventType2["DOCUMENT_BROADCAST"] = 3] = "DOCUMENT_BROADCAST";
5868
5868
  return DocEventType2;
5869
5869
  })(DocEventType$1 || {});
5870
- const file_yorkie_v1_yorkie = /* @__PURE__ */ fileDesc("ChZ5b3JraWUvdjEveW9ya2llLnByb3RvEgl5b3JraWUudjEingEKFUFjdGl2YXRlQ2xpZW50UmVxdWVzdBISCgpjbGllbnRfa2V5GAEgASgJEkAKCG1ldGFkYXRhGAIgAygLMi4ueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIrChZBY3RpdmF0ZUNsaWVudFJlc3BvbnNlEhEKCWNsaWVudF9pZBgBIAEoCSJBChdEZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLc3luY2hyb25vdXMYAiABKAgiGgoYRGVhY3RpdmF0ZUNsaWVudFJlc3BvbnNlImoKFUF0dGFjaERvY3VtZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSKgoLY2hhbmdlX3BhY2sYAiABKAsyFS55b3JraWUudjEuQ2hhbmdlUGFjaxISCgpzY2hlbWFfa2V5GAMgASgJIp8BChZBdHRhY2hEb2N1bWVudFJlc3BvbnNlEhMKC2RvY3VtZW50X2lkGAEgASgJEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHQoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAMgASgFEiUKDHNjaGVtYV9ydWxlcxgEIAMoCzIPLnlvcmtpZS52MS5SdWxlIosBChVEZXRhY2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHgoWcmVtb3ZlX2lmX25vdF9hdHRhY2hlZBgEIAEoCCJEChZEZXRhY2hEb2N1bWVudFJlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siUwoMV2F0Y2hSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRIwCglyZXNvdXJjZXMYAiADKAsyHS55b3JraWUudjEuUmVzb3VyY2VEZXNjcmlwdG9yIoQBChJSZXNvdXJjZURlc2NyaXB0b3ISMQoIZG9jdW1lbnQYASABKAsyHS55b3JraWUudjEuRG9jdW1lbnREZXNjcmlwdG9ySAASLwoHY2hhbm5lbBgCIAEoCzIcLnlvcmtpZS52MS5DaGFubmVsRGVzY3JpcHRvckgAQgoKCHJlc291cmNlIikKEkRvY3VtZW50RGVzY3JpcHRvchITCgtkb2N1bWVudF9pZBgBIAEoCSIoChFDaGFubmVsRGVzY3JpcHRvchITCgtjaGFubmVsX2tleRgBIAEoCSJ5Cg1XYXRjaFJlc3BvbnNlEjgKDmluaXRpYWxpemF0aW9uGAEgASgLMh4ueW9ya2llLnYxLldhdGNoSW5pdGlhbGl6YXRpb25IABImCgVldmVudBgCIAEoCzIVLnlvcmtpZS52MS5XYXRjaEV2ZW50SABCBgoEYm9keSJGChNXYXRjaEluaXRpYWxpemF0aW9uEi8KDnJlc291cmNlX2luaXRzGAEgAygLMhcueW9ya2llLnYxLlJlc291cmNlSW5pdCJ4CgxSZXNvdXJjZUluaXQSMAoNZG9jdW1lbnRfaW5pdBgBIAEoCzIXLnlvcmtpZS52MS5Eb2N1bWVudEluaXRIABIuCgxjaGFubmVsX2luaXQYAiABKAsyFi55b3JraWUudjEuQ2hhbm5lbEluaXRIAEIGCgRpbml0IjcKDERvY3VtZW50SW5pdBITCgtkb2N1bWVudF9pZBgBIAEoCRISCgpjbGllbnRfaWRzGAIgAygJIkYKC0NoYW5uZWxJbml0EhMKC2NoYW5uZWxfa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMSCwoDc2VxGAMgASgDInsKCldhdGNoRXZlbnQSLQoJZG9jX2V2ZW50GAEgASgLMhgueW9ya2llLnYxLkRvY1dhdGNoRXZlbnRIABI1Cg1jaGFubmVsX2V2ZW50GAIgASgLMhwueW9ya2llLnYxLkNoYW5uZWxXYXRjaEV2ZW50SABCBwoFZXZlbnQiSAoNRG9jV2F0Y2hFdmVudBITCgtkb2N1bWVudF9pZBgBIAEoCRIiCgVldmVudBgCIAEoCzITLnlvcmtpZS52MS5Eb2NFdmVudCJQChFDaGFubmVsV2F0Y2hFdmVudBITCgtjaGFubmVsX2tleRgBIAEoCRImCgVldmVudBgCIAEoCzIXLnlvcmtpZS52MS5DaGFubmVsRXZlbnQiPgoUV2F0Y2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJIrYBChVXYXRjaERvY3VtZW50UmVzcG9uc2USSQoOaW5pdGlhbGl6YXRpb24YASABKAsyLy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlLkluaXRpYWxpemF0aW9uSAASJAoFZXZlbnQYAiABKAsyEy55b3JraWUudjEuRG9jRXZlbnRIABokCg5Jbml0aWFsaXphdGlvbhISCgpjbGllbnRfaWRzGAEgAygJQgYKBGJvZHkiPQoTV2F0Y2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkigwEKFFdhdGNoQ2hhbm5lbFJlc3BvbnNlEjkKC2luaXRpYWxpemVkGAEgASgLMiIueW9ya2llLnYxLldhdGNoQ2hhbm5lbEluaXRpYWxpemVkSAASKAoFZXZlbnQYAiABKAsyFy55b3JraWUudjEuQ2hhbm5lbEV2ZW50SABCBgoEYm9keSI9ChdXYXRjaENoYW5uZWxJbml0aWFsaXplZBIVCg1zZXNzaW9uX2NvdW50GAEgASgDEgsKA3NlcRgCIAEoAyJrChVSZW1vdmVEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siRAoWUmVtb3ZlRG9jdW1lbnRSZXNwb25zZRIqCgtjaGFuZ2VfcGFjaxgBIAEoCzIVLnlvcmtpZS52MS5DaGFuZ2VQYWNrIn8KFlB1c2hQdWxsQ2hhbmdlc1JlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSEQoJcHVzaF9vbmx5GAQgASgIIkUKF1B1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAEgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siYwoVQ3JlYXRlUmV2aXNpb25SZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRINCgVsYWJlbBgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCSJGChZDcmVhdGVSZXZpc2lvblJlc3BvbnNlEiwKCHJldmlzaW9uGAEgASgLMhoueW9ya2llLnYxLlJldmlzaW9uU3VtbWFyeSJRChJHZXRSZXZpc2lvblJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEhMKC3JldmlzaW9uX2lkGAMgASgJIkMKE0dldFJldmlzaW9uUmVzcG9uc2USLAoIcmV2aXNpb24YASABKAsyGi55b3JraWUudjEuUmV2aXNpb25TdW1tYXJ5InUKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRIRCglwYWdlX3NpemUYAyABKAUSDgoGb2Zmc2V0GAQgASgFEhIKCmlzX2ZvcndhcmQYBSABKAgiRgoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEi0KCXJldmlzaW9ucxgBIAMoCzIaLnlvcmtpZS52MS5SZXZpc2lvblN1bW1hcnkiVQoWUmVzdG9yZVJldmlzaW9uUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLZG9jdW1lbnRfaWQYAiABKAkSEwoLcmV2aXNpb25faWQYBCABKAkiGQoXUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiPgoUQXR0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJIkIKFUF0dGFjaENoYW5uZWxSZXNwb25zZRISCgpzZXNzaW9uX2lkGAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMiUgoURGV0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiLgoVRGV0YWNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMiUwoVUmVmcmVzaENoYW5uZWxSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtjaGFubmVsX2tleRgCIAEoCRISCgpzZXNzaW9uX2lkGAMgASgJIi8KFlJlZnJlc2hDaGFubmVsUmVzcG9uc2USFQoNc2Vzc2lvbl9jb3VudBgBIAEoAyIpChJQZWVrQ2hhbm5lbFJlcXVlc3QSEwoLY2hhbm5lbF9rZXkYASABKAkiLAoTUGVla0NoYW5uZWxSZXNwb25zZRIVCg1zZXNzaW9uX2NvdW50GAEgASgDIloKEEJyb2FkY2FzdFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEg0KBXRvcGljGAMgASgJEg8KB3BheWxvYWQYBCABKAwiEwoRQnJvYWRjYXN0UmVzcG9uc2UylQwKDVlvcmtpZVNlcnZpY2USVwoOQWN0aXZhdGVDbGllbnQSIC55b3JraWUudjEuQWN0aXZhdGVDbGllbnRSZXF1ZXN0GiEueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVzcG9uc2UiABJdChBEZWFjdGl2YXRlQ2xpZW50EiIueW9ya2llLnYxLkRlYWN0aXZhdGVDbGllbnRSZXF1ZXN0GiMueW9ya2llLnYxLkRlYWN0aXZhdGVDbGllbnRSZXNwb25zZSIAElcKDkF0dGFjaERvY3VtZW50EiAueW9ya2llLnYxLkF0dGFjaERvY3VtZW50UmVxdWVzdBohLnlvcmtpZS52MS5BdHRhY2hEb2N1bWVudFJlc3BvbnNlIgASVwoORGV0YWNoRG9jdW1lbnQSIC55b3JraWUudjEuRGV0YWNoRG9jdW1lbnRSZXF1ZXN0GiEueW9ya2llLnYxLkRldGFjaERvY3VtZW50UmVzcG9uc2UiABJXCg5SZW1vdmVEb2N1bWVudBIgLnlvcmtpZS52MS5SZW1vdmVEb2N1bWVudFJlcXVlc3QaIS55b3JraWUudjEuUmVtb3ZlRG9jdW1lbnRSZXNwb25zZSIAEloKD1B1c2hQdWxsQ2hhbmdlcxIhLnlvcmtpZS52MS5QdXNoUHVsbENoYW5nZXNSZXF1ZXN0GiIueW9ya2llLnYxLlB1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlIgASPgoFV2F0Y2gSFy55b3JraWUudjEuV2F0Y2hSZXF1ZXN0GhgueW9ya2llLnYxLldhdGNoUmVzcG9uc2UiADABElYKDVdhdGNoRG9jdW1lbnQSHy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlcXVlc3QaIC55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlIgAwARJTCgxXYXRjaENoYW5uZWwSHi55b3JraWUudjEuV2F0Y2hDaGFubmVsUmVxdWVzdBofLnlvcmtpZS52MS5XYXRjaENoYW5uZWxSZXNwb25zZSIAMAESVwoOQ3JlYXRlUmV2aXNpb24SIC55b3JraWUudjEuQ3JlYXRlUmV2aXNpb25SZXF1ZXN0GiEueW9ya2llLnYxLkNyZWF0ZVJldmlzaW9uUmVzcG9uc2UiABJOCgtHZXRSZXZpc2lvbhIdLnlvcmtpZS52MS5HZXRSZXZpc2lvblJlcXVlc3QaHi55b3JraWUudjEuR2V0UmV2aXNpb25SZXNwb25zZSIAElQKDUxpc3RSZXZpc2lvbnMSHy55b3JraWUudjEuTGlzdFJldmlzaW9uc1JlcXVlc3QaIC55b3JraWUudjEuTGlzdFJldmlzaW9uc1Jlc3BvbnNlIgASWgoPUmVzdG9yZVJldmlzaW9uEiEueW9ya2llLnYxLlJlc3RvcmVSZXZpc2lvblJlcXVlc3QaIi55b3JraWUudjEuUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiABJUCg1BdHRhY2hDaGFubmVsEh8ueW9ya2llLnYxLkF0dGFjaENoYW5uZWxSZXF1ZXN0GiAueW9ya2llLnYxLkF0dGFjaENoYW5uZWxSZXNwb25zZSIAElQKDURldGFjaENoYW5uZWwSHy55b3JraWUudjEuRGV0YWNoQ2hhbm5lbFJlcXVlc3QaIC55b3JraWUudjEuRGV0YWNoQ2hhbm5lbFJlc3BvbnNlIgASVwoOUmVmcmVzaENoYW5uZWwSIC55b3JraWUudjEuUmVmcmVzaENoYW5uZWxSZXF1ZXN0GiEueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVzcG9uc2UiABJOCgtQZWVrQ2hhbm5lbBIdLnlvcmtpZS52MS5QZWVrQ2hhbm5lbFJlcXVlc3QaHi55b3JraWUudjEuUGVla0NoYW5uZWxSZXNwb25zZSIAEkgKCUJyb2FkY2FzdBIbLnlvcmtpZS52MS5Ccm9hZGNhc3RSZXF1ZXN0GhwueW9ya2llLnYxLkJyb2FkY2FzdFJlc3BvbnNlIgBCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_yorkie_v1_resources]);
5870
+ const file_yorkie_v1_yorkie = /* @__PURE__ */ fileDesc("ChZ5b3JraWUvdjEveW9ya2llLnByb3RvEgl5b3JraWUudjEingEKFUFjdGl2YXRlQ2xpZW50UmVxdWVzdBISCgpjbGllbnRfa2V5GAEgASgJEkAKCG1ldGFkYXRhGAIgAygLMi4ueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIrChZBY3RpdmF0ZUNsaWVudFJlc3BvbnNlEhEKCWNsaWVudF9pZBgBIAEoCSJBChdEZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLc3luY2hyb25vdXMYAiABKAgiGgoYRGVhY3RpdmF0ZUNsaWVudFJlc3BvbnNlImoKFUF0dGFjaERvY3VtZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSKgoLY2hhbmdlX3BhY2sYAiABKAsyFS55b3JraWUudjEuQ2hhbmdlUGFjaxISCgpzY2hlbWFfa2V5GAMgASgJIp8BChZBdHRhY2hEb2N1bWVudFJlc3BvbnNlEhMKC2RvY3VtZW50X2lkGAEgASgJEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHQoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAMgASgFEiUKDHNjaGVtYV9ydWxlcxgEIAMoCzIPLnlvcmtpZS52MS5SdWxlIosBChVEZXRhY2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHgoWcmVtb3ZlX2lmX25vdF9hdHRhY2hlZBgEIAEoCCJEChZEZXRhY2hEb2N1bWVudFJlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siUwoMV2F0Y2hSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRIwCglyZXNvdXJjZXMYAiADKAsyHS55b3JraWUudjEuUmVzb3VyY2VEZXNjcmlwdG9yIoQBChJSZXNvdXJjZURlc2NyaXB0b3ISMQoIZG9jdW1lbnQYASABKAsyHS55b3JraWUudjEuRG9jdW1lbnREZXNjcmlwdG9ySAASLwoHY2hhbm5lbBgCIAEoCzIcLnlvcmtpZS52MS5DaGFubmVsRGVzY3JpcHRvckgAQgoKCHJlc291cmNlIikKEkRvY3VtZW50RGVzY3JpcHRvchITCgtkb2N1bWVudF9pZBgBIAEoCSIoChFDaGFubmVsRGVzY3JpcHRvchITCgtjaGFubmVsX2tleRgBIAEoCSJ5Cg1XYXRjaFJlc3BvbnNlEjgKDmluaXRpYWxpemF0aW9uGAEgASgLMh4ueW9ya2llLnYxLldhdGNoSW5pdGlhbGl6YXRpb25IABImCgVldmVudBgCIAEoCzIVLnlvcmtpZS52MS5XYXRjaEV2ZW50SABCBgoEYm9keSJGChNXYXRjaEluaXRpYWxpemF0aW9uEi8KDnJlc291cmNlX2luaXRzGAEgAygLMhcueW9ya2llLnYxLlJlc291cmNlSW5pdCJ4CgxSZXNvdXJjZUluaXQSMAoNZG9jdW1lbnRfaW5pdBgBIAEoCzIXLnlvcmtpZS52MS5Eb2N1bWVudEluaXRIABIuCgxjaGFubmVsX2luaXQYAiABKAsyFi55b3JraWUudjEuQ2hhbm5lbEluaXRIAEIGCgRpbml0IjcKDERvY3VtZW50SW5pdBITCgtkb2N1bWVudF9pZBgBIAEoCRISCgpjbGllbnRfaWRzGAIgAygJIkYKC0NoYW5uZWxJbml0EhMKC2NoYW5uZWxfa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMSCwoDc2VxGAMgASgDInsKCldhdGNoRXZlbnQSLQoJZG9jX2V2ZW50GAEgASgLMhgueW9ya2llLnYxLkRvY1dhdGNoRXZlbnRIABI1Cg1jaGFubmVsX2V2ZW50GAIgASgLMhwueW9ya2llLnYxLkNoYW5uZWxXYXRjaEV2ZW50SABCBwoFZXZlbnQiSAoNRG9jV2F0Y2hFdmVudBITCgtkb2N1bWVudF9pZBgBIAEoCRIiCgVldmVudBgCIAEoCzITLnlvcmtpZS52MS5Eb2NFdmVudCJQChFDaGFubmVsV2F0Y2hFdmVudBITCgtjaGFubmVsX2tleRgBIAEoCRImCgVldmVudBgCIAEoCzIXLnlvcmtpZS52MS5DaGFubmVsRXZlbnQiPgoUV2F0Y2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJIrYBChVXYXRjaERvY3VtZW50UmVzcG9uc2USSQoOaW5pdGlhbGl6YXRpb24YASABKAsyLy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlLkluaXRpYWxpemF0aW9uSAASJAoFZXZlbnQYAiABKAsyEy55b3JraWUudjEuRG9jRXZlbnRIABokCg5Jbml0aWFsaXphdGlvbhISCgpjbGllbnRfaWRzGAEgAygJQgYKBGJvZHkiPQoTV2F0Y2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkigwEKFFdhdGNoQ2hhbm5lbFJlc3BvbnNlEjkKC2luaXRpYWxpemVkGAEgASgLMiIueW9ya2llLnYxLldhdGNoQ2hhbm5lbEluaXRpYWxpemVkSAASKAoFZXZlbnQYAiABKAsyFy55b3JraWUudjEuQ2hhbm5lbEV2ZW50SABCBgoEYm9keSI9ChdXYXRjaENoYW5uZWxJbml0aWFsaXplZBIVCg1zZXNzaW9uX2NvdW50GAEgASgDEgsKA3NlcRgCIAEoAyJrChVSZW1vdmVEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siRAoWUmVtb3ZlRG9jdW1lbnRSZXNwb25zZRIqCgtjaGFuZ2VfcGFjaxgBIAEoCzIVLnlvcmtpZS52MS5DaGFuZ2VQYWNrIn8KFlB1c2hQdWxsQ2hhbmdlc1JlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSEQoJcHVzaF9vbmx5GAQgASgIIkUKF1B1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAEgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siYwoVQ3JlYXRlUmV2aXNpb25SZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRINCgVsYWJlbBgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCSJGChZDcmVhdGVSZXZpc2lvblJlc3BvbnNlEiwKCHJldmlzaW9uGAEgASgLMhoueW9ya2llLnYxLlJldmlzaW9uU3VtbWFyeSJRChJHZXRSZXZpc2lvblJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEhMKC3JldmlzaW9uX2lkGAMgASgJIkMKE0dldFJldmlzaW9uUmVzcG9uc2USLAoIcmV2aXNpb24YASABKAsyGi55b3JraWUudjEuUmV2aXNpb25TdW1tYXJ5InUKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRIRCglwYWdlX3NpemUYAyABKAUSDgoGb2Zmc2V0GAQgASgFEhIKCmlzX2ZvcndhcmQYBSABKAgiRgoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEi0KCXJldmlzaW9ucxgBIAMoCzIaLnlvcmtpZS52MS5SZXZpc2lvblN1bW1hcnkiVQoWUmVzdG9yZVJldmlzaW9uUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLZG9jdW1lbnRfaWQYAiABKAkSEwoLcmV2aXNpb25faWQYBCABKAkiGQoXUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiPgoUQXR0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJIkIKFUF0dGFjaENoYW5uZWxSZXNwb25zZRISCgpzZXNzaW9uX2lkGAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMiUgoURGV0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiLgoVRGV0YWNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMi2gEKFVJlZnJlc2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkSEgoKc2Vzc2lvbl9pZBgDIAEoCRISCgpjbGllbnRfa2V5GAQgASgJEkAKCG1ldGFkYXRhGAUgAygLMi4ueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJWChZSZWZyZXNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMSEQoJY2xpZW50X2lkGAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiKQoSUGVla0NoYW5uZWxSZXF1ZXN0EhMKC2NoYW5uZWxfa2V5GAEgASgJIiwKE1BlZWtDaGFubmVsUmVzcG9uc2USFQoNc2Vzc2lvbl9jb3VudBgBIAEoAyJaChBCcm9hZGNhc3RSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtjaGFubmVsX2tleRgCIAEoCRINCgV0b3BpYxgDIAEoCRIPCgdwYXlsb2FkGAQgASgMIhMKEUJyb2FkY2FzdFJlc3BvbnNlMpUMCg1Zb3JraWVTZXJ2aWNlElcKDkFjdGl2YXRlQ2xpZW50EiAueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdBohLnlvcmtpZS52MS5BY3RpdmF0ZUNsaWVudFJlc3BvbnNlIgASXQoQRGVhY3RpdmF0ZUNsaWVudBIiLnlvcmtpZS52MS5EZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBojLnlvcmtpZS52MS5EZWFjdGl2YXRlQ2xpZW50UmVzcG9uc2UiABJXCg5BdHRhY2hEb2N1bWVudBIgLnlvcmtpZS52MS5BdHRhY2hEb2N1bWVudFJlcXVlc3QaIS55b3JraWUudjEuQXR0YWNoRG9jdW1lbnRSZXNwb25zZSIAElcKDkRldGFjaERvY3VtZW50EiAueW9ya2llLnYxLkRldGFjaERvY3VtZW50UmVxdWVzdBohLnlvcmtpZS52MS5EZXRhY2hEb2N1bWVudFJlc3BvbnNlIgASVwoOUmVtb3ZlRG9jdW1lbnQSIC55b3JraWUudjEuUmVtb3ZlRG9jdW1lbnRSZXF1ZXN0GiEueW9ya2llLnYxLlJlbW92ZURvY3VtZW50UmVzcG9uc2UiABJaCg9QdXNoUHVsbENoYW5nZXMSIS55b3JraWUudjEuUHVzaFB1bGxDaGFuZ2VzUmVxdWVzdBoiLnlvcmtpZS52MS5QdXNoUHVsbENoYW5nZXNSZXNwb25zZSIAEj4KBVdhdGNoEhcueW9ya2llLnYxLldhdGNoUmVxdWVzdBoYLnlvcmtpZS52MS5XYXRjaFJlc3BvbnNlIgAwARJWCg1XYXRjaERvY3VtZW50Eh8ueW9ya2llLnYxLldhdGNoRG9jdW1lbnRSZXF1ZXN0GiAueW9ya2llLnYxLldhdGNoRG9jdW1lbnRSZXNwb25zZSIAMAESUwoMV2F0Y2hDaGFubmVsEh4ueW9ya2llLnYxLldhdGNoQ2hhbm5lbFJlcXVlc3QaHy55b3JraWUudjEuV2F0Y2hDaGFubmVsUmVzcG9uc2UiADABElcKDkNyZWF0ZVJldmlzaW9uEiAueW9ya2llLnYxLkNyZWF0ZVJldmlzaW9uUmVxdWVzdBohLnlvcmtpZS52MS5DcmVhdGVSZXZpc2lvblJlc3BvbnNlIgASTgoLR2V0UmV2aXNpb24SHS55b3JraWUudjEuR2V0UmV2aXNpb25SZXF1ZXN0Gh4ueW9ya2llLnYxLkdldFJldmlzaW9uUmVzcG9uc2UiABJUCg1MaXN0UmV2aXNpb25zEh8ueW9ya2llLnYxLkxpc3RSZXZpc2lvbnNSZXF1ZXN0GiAueW9ya2llLnYxLkxpc3RSZXZpc2lvbnNSZXNwb25zZSIAEloKD1Jlc3RvcmVSZXZpc2lvbhIhLnlvcmtpZS52MS5SZXN0b3JlUmV2aXNpb25SZXF1ZXN0GiIueW9ya2llLnYxLlJlc3RvcmVSZXZpc2lvblJlc3BvbnNlIgASVAoNQXR0YWNoQ2hhbm5lbBIfLnlvcmtpZS52MS5BdHRhY2hDaGFubmVsUmVxdWVzdBogLnlvcmtpZS52MS5BdHRhY2hDaGFubmVsUmVzcG9uc2UiABJUCg1EZXRhY2hDaGFubmVsEh8ueW9ya2llLnYxLkRldGFjaENoYW5uZWxSZXF1ZXN0GiAueW9ya2llLnYxLkRldGFjaENoYW5uZWxSZXNwb25zZSIAElcKDlJlZnJlc2hDaGFubmVsEiAueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVxdWVzdBohLnlvcmtpZS52MS5SZWZyZXNoQ2hhbm5lbFJlc3BvbnNlIgASTgoLUGVla0NoYW5uZWwSHS55b3JraWUudjEuUGVla0NoYW5uZWxSZXF1ZXN0Gh4ueW9ya2llLnYxLlBlZWtDaGFubmVsUmVzcG9uc2UiABJICglCcm9hZGNhc3QSGy55b3JraWUudjEuQnJvYWRjYXN0UmVxdWVzdBocLnlvcmtpZS52MS5Ccm9hZGNhc3RSZXNwb25zZSIAQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_yorkie_v1_resources]);
5871
5871
  const YorkieService = /* @__PURE__ */ serviceDesc(file_yorkie_v1_yorkie, 0);
5872
5872
  const file_google_rpc_error_details = /* @__PURE__ */ fileDesc("Ch5nb29nbGUvcnBjL2Vycm9yX2RldGFpbHMucHJvdG8SCmdvb2dsZS5ycGMikwEKCUVycm9ySW5mbxIOCgZyZWFzb24YASABKAkSDgoGZG9tYWluGAIgASgJEjUKCG1ldGFkYXRhGAMgAygLMiMuZ29vZ2xlLnJwYy5FcnJvckluZm8uTWV0YWRhdGFFbnRyeRovCg1NZXRhZGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiOwoJUmV0cnlJbmZvEi4KC3JldHJ5X2RlbGF5GAEgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIjIKCURlYnVnSW5mbxIVCg1zdGFja19lbnRyaWVzGAEgAygJEg4KBmRldGFpbBgCIAEoCSKPAwoMUXVvdGFGYWlsdXJlEjYKCnZpb2xhdGlvbnMYASADKAsyIi5nb29nbGUucnBjLlF1b3RhRmFpbHVyZS5WaW9sYXRpb24axgIKCVZpb2xhdGlvbhIPCgdzdWJqZWN0GAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJEhMKC2FwaV9zZXJ2aWNlGAMgASgJEhQKDHF1b3RhX21ldHJpYxgEIAEoCRIQCghxdW90YV9pZBgFIAEoCRJRChBxdW90YV9kaW1lbnNpb25zGAYgAygLMjcuZ29vZ2xlLnJwYy5RdW90YUZhaWx1cmUuVmlvbGF0aW9uLlF1b3RhRGltZW5zaW9uc0VudHJ5EhMKC3F1b3RhX3ZhbHVlGAcgASgDEh8KEmZ1dHVyZV9xdW90YV92YWx1ZRgIIAEoA0gAiAEBGjYKFFF1b3RhRGltZW5zaW9uc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAFCFQoTX2Z1dHVyZV9xdW90YV92YWx1ZSKVAQoTUHJlY29uZGl0aW9uRmFpbHVyZRI9Cgp2aW9sYXRpb25zGAEgAygLMikuZ29vZ2xlLnJwYy5QcmVjb25kaXRpb25GYWlsdXJlLlZpb2xhdGlvbho/CglWaW9sYXRpb24SDAoEdHlwZRgBIAEoCRIPCgdzdWJqZWN0GAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJIswBCgpCYWRSZXF1ZXN0Ej8KEGZpZWxkX3Zpb2xhdGlvbnMYASADKAsyJS5nb29nbGUucnBjLkJhZFJlcXVlc3QuRmllbGRWaW9sYXRpb24afQoORmllbGRWaW9sYXRpb24SDQoFZmllbGQYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSDgoGcmVhc29uGAMgASgJEjcKEWxvY2FsaXplZF9tZXNzYWdlGAQgASgLMhwuZ29vZ2xlLnJwYy5Mb2NhbGl6ZWRNZXNzYWdlIjcKC1JlcXVlc3RJbmZvEhIKCnJlcXVlc3RfaWQYASABKAkSFAoMc2VydmluZ19kYXRhGAIgASgJImAKDFJlc291cmNlSW5mbxIVCg1yZXNvdXJjZV90eXBlGAEgASgJEhUKDXJlc291cmNlX25hbWUYAiABKAkSDQoFb3duZXIYAyABKAkSEwoLZGVzY3JpcHRpb24YBCABKAkiVgoESGVscBIkCgVsaW5rcxgBIAMoCzIVLmdvb2dsZS5ycGMuSGVscC5MaW5rGigKBExpbmsSEwoLZGVzY3JpcHRpb24YASABKAkSCwoDdXJsGAIgASgJIjMKEExvY2FsaXplZE1lc3NhZ2USDgoGbG9jYWxlGAEgASgJEg8KB21lc3NhZ2UYAiABKAlCbAoOY29tLmdvb2dsZS5ycGNCEUVycm9yRGV0YWlsc1Byb3RvUAFaP2dvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvcnBjL2VycmRldGFpbHM7ZXJyZGV0YWlsc6ICA1JQQ2IGcHJvdG8z", [file_google_protobuf_duration]);
5873
5873
  const ErrorInfoSchema = /* @__PURE__ */ messageDesc(file_google_rpc_error_details, 0);
@@ -5880,6 +5880,7 @@ var Code = /* @__PURE__ */ ((Code2) => {
5880
5880
  Code2["ErrDummy"] = "ErrDummy";
5881
5881
  Code2["ErrNotAttached"] = "ErrNotAttached";
5882
5882
  Code2["ErrNotDetached"] = "ErrNotDetached";
5883
+ Code2["ErrSessionNotFound"] = "ErrSessionNotFound";
5883
5884
  Code2["ErrDocumentRemoved"] = "ErrDocumentRemoved";
5884
5885
  Code2["ErrDocumentSizeExceedsLimit"] = "ErrDocumentSizeExceedsLimit";
5885
5886
  Code2["ErrDocumentSchemaValidationFailed"] = "ErrDocumentSchemaValidationFailed";
@@ -20778,12 +20779,25 @@ class Document {
20778
20779
  }
20779
20780
  class Attachment {
20780
20781
  resource;
20782
+ /**
20783
+ * For Documents: the document's resourceID, available at attach time.
20784
+ * For Channels: the server-issued session_id. Starts empty and is
20785
+ * populated after the first `RefreshChannel` first-call response.
20786
+ */
20781
20787
  resourceID;
20782
20788
  syncMode;
20783
20789
  changeEventReceived;
20784
20790
  lastHeartbeatTime;
20785
20791
  pollInterval;
20786
20792
  pollIntervalPinned;
20793
+ /**
20794
+ * `unsubscribeLocalBroadcast` is set by `attachChannel` when it forwards
20795
+ * a Channel's `local-broadcast` events to the RPC client, and consumed
20796
+ * by `detachInternal` so the subscription does not survive a detach.
20797
+ * Without this, re-attaching a channel accumulates duplicate handlers
20798
+ * on each attach cycle.
20799
+ */
20800
+ unsubscribeLocalBroadcast;
20787
20801
  reconnectStreamDelay;
20788
20802
  cancelled;
20789
20803
  watchStream;
@@ -20791,13 +20805,13 @@ class Attachment {
20791
20805
  watchAbortController;
20792
20806
  syncPromise;
20793
20807
  _detaching = false;
20794
- constructor(reconnectStreamDelay, resource, resourceID, syncMode, pollInterval = 0, pollIntervalPinned = false) {
20808
+ constructor(reconnectStreamDelay, resource, resourceID = "", syncMode, pollInterval = 0, pollIntervalPinned = false) {
20795
20809
  this.reconnectStreamDelay = reconnectStreamDelay;
20796
20810
  this.resource = resource;
20797
20811
  this.resourceID = resourceID;
20798
20812
  this.syncMode = syncMode;
20799
20813
  this.changeEventReceived = syncMode !== void 0 ? false : void 0;
20800
- this.lastHeartbeatTime = Date.now();
20814
+ this.lastHeartbeatTime = 0;
20801
20815
  this.pollInterval = pollInterval;
20802
20816
  this.pollIntervalPinned = pollIntervalPinned;
20803
20817
  this.cancelled = false;
@@ -20959,7 +20973,7 @@ function createAuthInterceptor(apiKey, token) {
20959
20973
  };
20960
20974
  }
20961
20975
  const name$1 = "@yorkie-js/sdk";
20962
- const version$1 = "0.7.9";
20976
+ const version$1 = "0.7.10-rc";
20963
20977
  const pkg$1 = {
20964
20978
  name: name$1,
20965
20979
  version: version$1
@@ -20997,6 +21011,7 @@ var ChannelEventType = /* @__PURE__ */ ((ChannelEventType2) => {
20997
21011
  ChannelEventType2["Broadcast"] = "broadcast";
20998
21012
  ChannelEventType2["LocalBroadcast"] = "local-broadcast";
20999
21013
  ChannelEventType2["AuthError"] = "auth-error";
21014
+ ChannelEventType2["SyncError"] = "sync-error";
21000
21015
  return ChannelEventType2;
21001
21016
  })(ChannelEventType || {});
21002
21017
  const KeyPathSeparator = ".";
@@ -21136,6 +21151,13 @@ class Channel2 {
21136
21151
  }
21137
21152
  });
21138
21153
  }
21154
+ if (typeOrTopic === "sync-error") {
21155
+ return this.eventStream.subscribe((event) => {
21156
+ if (event.type === "sync-error") {
21157
+ callback(event);
21158
+ }
21159
+ });
21160
+ }
21139
21161
  if (typeOrTopic === "presence") {
21140
21162
  return this.eventStream.subscribe((event) => {
21141
21163
  if (event.type === "presence-changed" || event.type === "initialized") {
@@ -21245,13 +21267,14 @@ var SyncMode = /* @__PURE__ */ ((SyncMode2) => {
21245
21267
  SyncMode2["Polling"] = "polling";
21246
21268
  return SyncMode2;
21247
21269
  })(SyncMode || {});
21248
- const DefaultPollingIntervalMs = 3e3;
21270
+ const DefaultDocumentPollIntervalMs = 3e3;
21271
+ const DefaultChannelHeartbeatMs = 5e3;
21249
21272
  const DefaultClientOptions = {
21250
21273
  rpcAddr: "https://api.yorkie.dev",
21251
21274
  syncLoopDuration: 50,
21252
21275
  retrySyncLoopDelay: 1e3,
21253
21276
  reconnectStreamDelay: 1e3,
21254
- channelHeartbeatInterval: 3e4
21277
+ channelHeartbeatInterval: DefaultChannelHeartbeatMs
21255
21278
  };
21256
21279
  const DefaultBroadcastOptions = {
21257
21280
  maxRetries: Infinity,
@@ -21448,7 +21471,7 @@ class Client {
21448
21471
  );
21449
21472
  }
21450
21473
  const pollIntervalPinned = opts.documentPollInterval !== void 0;
21451
- const pollInterval = pollIntervalPinned ? opts.documentPollInterval : syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21474
+ const pollInterval = pollIntervalPinned ? opts.documentPollInterval : syncMode === "polling" ? DefaultDocumentPollIntervalMs : 0;
21452
21475
  return this.enqueueTask(async () => {
21453
21476
  try {
21454
21477
  const res = await this.rpcClient.attachDocument(
@@ -21577,127 +21600,88 @@ class Client {
21577
21600
  return this.enqueueTask(task);
21578
21601
  }
21579
21602
  /**
21580
- * `attach` attaches the given channel to this client.
21581
- * It tells the server that this client will track the channel.
21603
+ * `attachChannel` attaches the given channel to this client. The channel is
21604
+ * registered locally and the server is notified on the next RefreshChannel
21605
+ * heartbeat.
21582
21606
  */
21583
21607
  async attachChannel(channel, opts = {}) {
21584
- if (!this.isActive()) {
21585
- throw new YorkieError(
21586
- Code.ErrClientNotActivated,
21587
- `${this.key} is not active`
21588
- );
21589
- }
21590
21608
  if (channel.getStatus() !== ChannelStatus.Detached) {
21591
21609
  throw new YorkieError(
21592
21610
  Code.ErrNotDetached,
21593
21611
  `${channel.getKey()} is not detached`
21594
21612
  );
21595
21613
  }
21596
- channel.setActor(this.id);
21614
+ const syncMode = opts.syncMode ?? "realtime";
21615
+ this.assertValidChannelSyncMode(syncMode);
21616
+ if (opts.channelHeartbeatInterval !== void 0 && opts.channelHeartbeatInterval <= 0) {
21617
+ throw new YorkieError(
21618
+ Code.ErrInvalidArgument,
21619
+ "channelHeartbeatInterval must be greater than 0"
21620
+ );
21621
+ }
21622
+ const pollIntervalPinned = opts.channelHeartbeatInterval !== void 0;
21623
+ const pollInterval = opts.channelHeartbeatInterval ?? this.channelHeartbeatInterval;
21597
21624
  const task = async () => {
21598
- try {
21599
- const res = await this.rpcClient.attachChannel(
21600
- {
21601
- clientId: this.id,
21602
- channelKey: channel.getKey()
21603
- },
21604
- {
21605
- headers: {
21606
- "x-shard-key": `${this.apiKey}/${channel.getFirstKeyPath()}`
21607
- }
21608
- }
21609
- );
21610
- channel.setSessionID(res.sessionId);
21611
- channel.updateSessionCount(Number(res.sessionCount), 0);
21612
- channel.applyStatus(ChannelStatus.Attached);
21613
- const syncMode = opts.syncMode ?? "realtime";
21614
- this.assertValidChannelSyncMode(syncMode);
21615
- if (opts.channelHeartbeatInterval !== void 0 && opts.channelHeartbeatInterval <= 0) {
21616
- throw new YorkieError(
21617
- Code.ErrInvalidArgument,
21618
- "channelHeartbeatInterval must be greater than 0"
21619
- );
21620
- }
21621
- const pollIntervalPinned = opts.channelHeartbeatInterval !== void 0;
21622
- const pollInterval = pollIntervalPinned ? opts.channelHeartbeatInterval : syncMode === "polling" ? DefaultPollingIntervalMs : this.channelHeartbeatInterval;
21623
- const attachment = new Attachment(
21624
- this.reconnectStreamDelay,
21625
- channel,
21626
- res.sessionId,
21627
- syncMode,
21628
- pollInterval,
21629
- pollIntervalPinned
21630
- );
21631
- channel.subscribe("local-broadcast", (event) => {
21625
+ if (this.id) {
21626
+ channel.setActor(this.id);
21627
+ }
21628
+ const attachment = new Attachment(
21629
+ this.reconnectStreamDelay,
21630
+ channel,
21631
+ "",
21632
+ // sessionID populated on first refresh response
21633
+ syncMode,
21634
+ pollInterval,
21635
+ pollIntervalPinned
21636
+ );
21637
+ attachment.unsubscribeLocalBroadcast = channel.subscribe(
21638
+ "local-broadcast",
21639
+ (event) => {
21632
21640
  const { topic, payload, options } = event;
21633
21641
  this.broadcast(channel.getKey(), topic, payload, options).catch(
21634
21642
  (error) => {
21635
- if (options?.error) {
21636
- options.error(error);
21637
- }
21643
+ if (options?.error) options.error(error);
21638
21644
  logger.error(`[BC] c:"${this.getKey()}" failed: ${error}`);
21639
21645
  }
21640
21646
  );
21641
- });
21642
- this.attachmentMap.set(channel.getKey(), attachment);
21643
- if (syncMode === "realtime") {
21644
- await this.runWatchLoop(channel.getKey());
21645
21647
  }
21646
- logger.info(
21647
- `[AP] c:"${this.getKey()}" attaches p:"${channel.getKey()}" mode:${syncMode} count:${channel.getSessionCount()}`
21648
- );
21649
- return channel;
21650
- } catch (err) {
21651
- logger.error(`[AP] c:"${this.getKey()}" err :`, err);
21652
- await this.handleConnectError(err);
21653
- throw err;
21648
+ );
21649
+ this.attachmentMap.set(channel.getKey(), attachment);
21650
+ if (!this.conditions[
21651
+ "SyncLoop"
21652
+ /* SyncLoop */
21653
+ ]) {
21654
+ this.runSyncLoop();
21654
21655
  }
21656
+ logger.info(
21657
+ `[AP] c:"${this.getKey()}" attaches p:"${channel.getKey()}" mode:${syncMode}`
21658
+ );
21659
+ return channel;
21655
21660
  };
21656
21661
  return this.enqueueTask(task);
21657
21662
  }
21658
21663
  /**
21659
- * `detachChannel` detaches the given channel from this client.
21660
- * It tells the server that this client will no longer track the channel.
21664
+ * `detachChannel` detaches the given channel from this client. The detach
21665
+ * is a local cleanup; the server reclaims the session via TTL when
21666
+ * heartbeats stop.
21661
21667
  */
21662
21668
  async detachChannel(channel) {
21663
- if (!this.isActive()) {
21664
- throw new YorkieError(
21665
- Code.ErrClientNotActivated,
21666
- `${this.key} is not active`
21667
- );
21668
- }
21669
- if (!this.attachmentMap.has(channel.getKey())) {
21669
+ const attachment = this.attachmentMap.get(channel.getKey());
21670
+ if (!attachment) {
21670
21671
  throw new YorkieError(
21671
21672
  Code.ErrNotAttached,
21672
21673
  `${channel.getKey()} is not attached`
21673
21674
  );
21674
21675
  }
21676
+ attachment.markDetaching();
21677
+ await attachment.waitForSyncComplete();
21675
21678
  const task = async () => {
21676
- try {
21677
- const res = await this.rpcClient.detachChannel(
21678
- {
21679
- clientId: this.id,
21680
- channelKey: channel.getKey(),
21681
- sessionId: channel.getSessionID()
21682
- },
21683
- {
21684
- headers: {
21685
- "x-shard-key": `${this.apiKey}/${channel.getFirstKeyPath()}`
21686
- }
21687
- }
21688
- );
21689
- channel.updateSessionCount(Number(res.sessionCount), 0);
21690
- channel.applyStatus(ChannelStatus.Detached);
21691
- this.detachInternal(channel.getKey());
21692
- logger.info(
21693
- `[DP] c:"${this.getKey()}" detaches p:"${channel.getKey()}" count:${channel.getSessionCount()}`
21694
- );
21695
- return channel;
21696
- } catch (err) {
21697
- logger.error(`[DP] c:"${this.getKey()}" err :`, err);
21698
- await this.handleConnectError(err);
21699
- throw err;
21700
- }
21679
+ channel.applyStatus(ChannelStatus.Detached);
21680
+ this.detachInternal(channel.getKey());
21681
+ logger.info(
21682
+ `[DP] c:"${this.getKey()}" detaches p:"${channel.getKey()}" (local)`
21683
+ );
21684
+ return channel;
21701
21685
  };
21702
21686
  return this.enqueueTask(task);
21703
21687
  }
@@ -21738,7 +21722,7 @@ class Client {
21738
21722
  attachment.changeEventReceived = true;
21739
21723
  }
21740
21724
  if (!attachment.pollIntervalPinned) {
21741
- attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21725
+ attachment.pollInterval = syncMode === "polling" ? DefaultDocumentPollIntervalMs : 0;
21742
21726
  }
21743
21727
  if ((prevSyncMode === "manual" || prevSyncMode === "polling") && syncMode !== "manual" && syncMode !== "polling") {
21744
21728
  attachment.resetCancelled();
@@ -21759,12 +21743,6 @@ class Client {
21759
21743
  }
21760
21744
  }
21761
21745
  async changeChannelSyncMode(channel, syncMode) {
21762
- if (!this.isActive()) {
21763
- throw new YorkieError(
21764
- Code.ErrClientNotActivated,
21765
- `${this.key} is not active`
21766
- );
21767
- }
21768
21746
  const attachment = this.attachmentMap.get(channel.getKey());
21769
21747
  if (!attachment) {
21770
21748
  throw new YorkieError(
@@ -21782,7 +21760,7 @@ class Client {
21782
21760
  }
21783
21761
  attachment.changeSyncMode(syncMode);
21784
21762
  if (!attachment.pollIntervalPinned) {
21785
- attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : syncMode === "realtime" ? this.channelHeartbeatInterval : 0;
21763
+ attachment.pollInterval = syncMode === "manual" ? 0 : this.channelHeartbeatInterval;
21786
21764
  }
21787
21765
  if (syncMode === "realtime") {
21788
21766
  attachment.resetCancelled();
@@ -21794,7 +21772,7 @@ class Client {
21794
21772
  * `sync` implementation that handles both Document and Channel.
21795
21773
  */
21796
21774
  sync(resource) {
21797
- if (!this.isActive()) {
21775
+ if (!(resource instanceof Channel2) && !this.isActive()) {
21798
21776
  throw new YorkieError(
21799
21777
  Code.ErrClientNotActivated,
21800
21778
  `${this.key} is not active`
@@ -22121,12 +22099,6 @@ class Client {
22121
22099
  * subscribe to channel events. Polling is the caller's responsibility.
22122
22100
  */
22123
22101
  async peekChannel(channelKey) {
22124
- if (!this.isActive()) {
22125
- throw new YorkieError(
22126
- Code.ErrClientNotActivated,
22127
- `${this.key} is not active`
22128
- );
22129
- }
22130
22102
  return this.enqueueTask(async () => {
22131
22103
  const firstKeyPath = channelKey.split(".")[0];
22132
22104
  const res = await this.rpcClient.peekChannel(
@@ -22144,12 +22116,6 @@ class Client {
22144
22116
  * `broadcast` broadcasts the given payload to the given topic.
22145
22117
  */
22146
22118
  async broadcast(key, topic, payload, options) {
22147
- if (!this.isActive()) {
22148
- throw new YorkieError(
22149
- Code.ErrClientNotActivated,
22150
- `${this.key} is not active`
22151
- );
22152
- }
22153
22119
  const attachment = this.attachmentMap.get(key);
22154
22120
  if (!attachment) {
22155
22121
  throw new YorkieError(Code.ErrNotAttached, `${key} is not attached`);
@@ -22226,8 +22192,16 @@ class Client {
22226
22192
  */
22227
22193
  runSyncLoop() {
22228
22194
  const doLoop = async () => {
22229
- if (!this.isActive() || this.deactivating) {
22230
- logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
22195
+ if (this.deactivating) {
22196
+ logger.debug(`[SL] c:"${this.getKey()}" exit sync loop (deactivating)`);
22197
+ this.conditions[
22198
+ "SyncLoop"
22199
+ /* SyncLoop */
22200
+ ] = false;
22201
+ return;
22202
+ }
22203
+ if (!this.isActive() && this.attachmentMap.size === 0) {
22204
+ logger.debug(`[SL] c:"${this.getKey()}" exit sync loop (idle)`);
22231
22205
  this.conditions[
22232
22206
  "SyncLoop"
22233
22207
  /* SyncLoop */
@@ -22613,6 +22587,10 @@ class Client {
22613
22587
  return;
22614
22588
  }
22615
22589
  attachment.cancelWatchStream();
22590
+ if (attachment.unsubscribeLocalBroadcast) {
22591
+ attachment.unsubscribeLocalBroadcast();
22592
+ attachment.unsubscribeLocalBroadcast = void 0;
22593
+ }
22616
22594
  if (attachment.resource instanceof Document) {
22617
22595
  attachment.resource.resetOnlineClients();
22618
22596
  }
@@ -22621,12 +22599,17 @@ class Client {
22621
22599
  async syncInternal(attachment, syncMode) {
22622
22600
  const { resource } = attachment;
22623
22601
  if (resource instanceof Channel2) {
22602
+ const isFirstCall = !resource.getSessionID();
22624
22603
  try {
22625
22604
  const res = await this.rpcClient.refreshChannel(
22626
22605
  {
22627
- clientId: this.id,
22606
+ clientId: this.id ?? "",
22628
22607
  channelKey: resource.getKey(),
22629
- sessionId: resource.getSessionID()
22608
+ sessionId: resource.getSessionID() ?? "",
22609
+ // First-call only — these fields are ignored by the server
22610
+ // once a session_id is established.
22611
+ clientKey: isFirstCall ? this.key : "",
22612
+ metadata: isFirstCall ? this.metadata : {}
22630
22613
  },
22631
22614
  {
22632
22615
  headers: {
@@ -22634,6 +22617,31 @@ class Client {
22634
22617
  }
22635
22618
  }
22636
22619
  );
22620
+ if (isFirstCall) {
22621
+ if (this.deactivating || attachment.isDetaching()) {
22622
+ return resource;
22623
+ }
22624
+ if (res.clientId && !this.id) {
22625
+ this.id = res.clientId;
22626
+ this.status = "activated";
22627
+ resource.setActor(res.clientId);
22628
+ } else if (this.id) {
22629
+ resource.setActor(this.id);
22630
+ }
22631
+ if (res.sessionId) {
22632
+ resource.setSessionID(res.sessionId);
22633
+ attachment.resourceID = res.sessionId;
22634
+ resource.applyStatus(ChannelStatus.Attached);
22635
+ }
22636
+ if (attachment.syncMode === "realtime") {
22637
+ this.runWatchLoop(resource.getKey()).catch((err) => {
22638
+ logger.error(
22639
+ `[WP] c:"${this.getKey()}" failed to start watch for p:"${resource.getKey()}":`,
22640
+ err
22641
+ );
22642
+ });
22643
+ }
22644
+ }
22637
22645
  const prevCount = resource.getSessionCount();
22638
22646
  if (resource.updateSessionCount(Number(res.sessionCount), 0)) {
22639
22647
  if (resource.getSessionCount() !== prevCount) {
@@ -22648,6 +22656,21 @@ class Client {
22648
22656
  `[RP] c:"${this.getKey()}" refreshes p:"${resource.getKey()}" mode:${attachment.syncMode}`
22649
22657
  );
22650
22658
  } catch (err) {
22659
+ if (isErrorCode(err, Code.ErrSessionNotFound)) {
22660
+ logger.info(
22661
+ `[RP] c:"${this.getKey()}" session expired for p:"${resource.getKey()}", re-attaching`
22662
+ );
22663
+ resource.setSessionID("");
22664
+ attachment.resourceID = "";
22665
+ return resource;
22666
+ }
22667
+ if (!this.deactivating && !attachment.isDetaching()) {
22668
+ resource.publish({
22669
+ type: ChannelEventType.SyncError,
22670
+ error: err,
22671
+ method: "RefreshChannel"
22672
+ });
22673
+ }
22651
22674
  logger.error(`[RP] c:"${this.getKey()}" err :`, err);
22652
22675
  throw err;
22653
22676
  }
@@ -22998,7 +23021,7 @@ if (typeof globalThis !== "undefined") {
22998
23021
  };
22999
23022
  }
23000
23023
  const name = "@yorkie-js/react";
23001
- const version = "0.7.9";
23024
+ const version = "0.7.10-rc";
23002
23025
  const pkg = {
23003
23026
  name,
23004
23027
  version
@@ -23008,7 +23031,7 @@ const YorkieContext = createContext({
23008
23031
  loading: true,
23009
23032
  error: void 0
23010
23033
  });
23011
- function useYorkieClient(opts) {
23034
+ function useYorkieClient(opts, activate = true) {
23012
23035
  const [client, setClient] = useState(void 0);
23013
23036
  const [loading, setLoading] = useState(true);
23014
23037
  const [error, setError] = useState(void 0);
@@ -23025,7 +23048,9 @@ function useYorkieClient(opts) {
23025
23048
  }
23026
23049
  try {
23027
23050
  const newClient = new Client(opts);
23028
- await newClient.activate();
23051
+ if (activate) {
23052
+ await newClient.activate();
23053
+ }
23029
23054
  setClient(newClient);
23030
23055
  } catch (e) {
23031
23056
  setError(
@@ -23037,24 +23062,21 @@ function useYorkieClient(opts) {
23037
23062
  }
23038
23063
  activateClient();
23039
23064
  return () => {
23040
- if (client?.isActive()) {
23065
+ if (activate && client?.isActive()) {
23041
23066
  client.deactivate({ keepalive: true });
23042
23067
  }
23043
23068
  };
23044
- }, [opts.apiKey, opts.rpcAddr, didMount]);
23069
+ }, [opts.apiKey, opts.rpcAddr, didMount, activate]);
23045
23070
  return { client, loading, error };
23046
23071
  }
23047
- const YorkieProvider = ({
23048
- children,
23049
- ...opts
23050
- }) => {
23072
+ const YorkieProvider = ({ children, activate = true, ...opts }) => {
23051
23073
  const clientOpts = useMemo(() => {
23052
23074
  return {
23053
23075
  userAgent: pkg.name + "/" + pkg.version,
23054
23076
  ...opts
23055
23077
  };
23056
23078
  }, [opts.apiKey, opts.rpcAddr]);
23057
- const { client, loading, error } = useYorkieClient(clientOpts);
23079
+ const { client, loading, error } = useYorkieClient(clientOpts, activate);
23058
23080
  return /* @__PURE__ */ jsx(YorkieContext.Provider, { value: { client, loading, error }, children });
23059
23081
  };
23060
23082
  const useYorkie = () => {
@@ -23490,7 +23512,7 @@ function useYorkieChannel(client, clientLoading, clientError, channelKey, syncMo
23490
23512
  }
23491
23513
  let unsubscribe;
23492
23514
  async function attachChannel() {
23493
- if (!client || !client.isActive()) {
23515
+ if (!client) {
23494
23516
  return;
23495
23517
  }
23496
23518
  channelStore.setState((state) => ({
@@ -23500,20 +23522,49 @@ function useYorkieChannel(client, clientLoading, clientError, channelKey, syncMo
23500
23522
  }));
23501
23523
  try {
23502
23524
  const newChannel = new Channel2(channelKey);
23503
- await client.attach(newChannel, { syncMode, channelHeartbeatInterval });
23525
+ await client.attach(newChannel, {
23526
+ syncMode,
23527
+ channelHeartbeatInterval
23528
+ });
23504
23529
  channelRef.current = newChannel;
23505
- unsubscribe = newChannel.subscribe(() => {
23530
+ unsubscribe = newChannel.subscribe((event) => {
23531
+ if (event.type === ChannelEventType.SyncError || event.type === ChannelEventType.AuthError) {
23532
+ const nextError = event.type === ChannelEventType.SyncError ? event.error instanceof Error ? event.error : new Error(String(event.error)) : new Error(
23533
+ `auth error during ${event.method}: ${event.reason}`
23534
+ );
23535
+ channelStore.setState((state) => ({
23536
+ ...state,
23537
+ loading: false,
23538
+ error: nextError
23539
+ }));
23540
+ return;
23541
+ }
23542
+ const recovers = event.type === ChannelEventType.PresenceChanged || event.type === ChannelEventType.Initialized || event.type === ChannelEventType.Broadcast;
23543
+ const ready = newChannel.isAttached() && !!newChannel.getSessionID();
23506
23544
  channelStore.setState((state) => ({
23507
23545
  ...state,
23508
- sessionCount: newChannel.getSessionCount()
23546
+ sessionCount: newChannel.getSessionCount(),
23547
+ ...recovers && state.error ? { error: void 0 } : {},
23548
+ ...ready && state.loading ? { loading: false } : {}
23509
23549
  }));
23510
23550
  });
23511
- channelStore.setState({
23551
+ const detach = async () => {
23552
+ if (!client) return;
23553
+ try {
23554
+ await client.detach(newChannel);
23555
+ } catch (err) {
23556
+ if (err instanceof Error && /not attached/i.test(err.message)) {
23557
+ return;
23558
+ }
23559
+ throw err;
23560
+ }
23561
+ };
23562
+ channelStore.setState((state) => ({
23563
+ ...state,
23512
23564
  channel: newChannel,
23513
- sessionCount: newChannel.getSessionCount(),
23514
- loading: false,
23515
- error: void 0
23516
- });
23565
+ error: void 0,
23566
+ detach
23567
+ }));
23517
23568
  } catch (e) {
23518
23569
  channelStore.setState((state) => ({
23519
23570
  ...state,
@@ -23528,10 +23579,13 @@ function useYorkieChannel(client, clientLoading, clientError, channelKey, syncMo
23528
23579
  unsubscribe();
23529
23580
  }
23530
23581
  async function detachChannel() {
23531
- if (channelRef.current && client?.isActive()) {
23582
+ if (channelRef.current && client) {
23532
23583
  try {
23533
23584
  await client.detach(channelRef.current);
23534
23585
  } catch (e) {
23586
+ if (e instanceof Error && /not attached/i.test(e.message)) {
23587
+ return;
23588
+ }
23535
23589
  console.error("Failed to detach channel:", e);
23536
23590
  }
23537
23591
  }
@@ -23564,7 +23618,11 @@ const ChannelProvider = ({
23564
23618
  channel: void 0,
23565
23619
  sessionCount: 0,
23566
23620
  loading: true,
23567
- error: void 0
23621
+ error: void 0,
23622
+ // Placeholder until `useYorkieChannel` wires up the real detach.
23623
+ // Pre-attach calls are a no-op rather than a throw.
23624
+ detach: async () => {
23625
+ }
23568
23626
  });
23569
23627
  }
23570
23628
  const channelStore = channelStoreRef.current;
@@ -23592,7 +23650,8 @@ const useChannel = () => {
23592
23650
  const sessionCount = useSelector(channelStore, (state) => state.sessionCount);
23593
23651
  const loading = useSelector(channelStore, (state) => state.loading);
23594
23652
  const error = useSelector(channelStore, (state) => state.error);
23595
- return { sessionCount, loading, error };
23653
+ const detach = useSelector(channelStore, (state) => state.detach);
23654
+ return { sessionCount, loading, error, detach };
23596
23655
  };
23597
23656
  const useChannelSessionCount = () => {
23598
23657
  const channelStore = useChannelStore("useChannelSessionCount");
@@ -23614,7 +23673,7 @@ function usePeekChannel(channelKey, opts = {}) {
23614
23673
  };
23615
23674
  }, []);
23616
23675
  const peekOnce = useCallback(async () => {
23617
- if (!client || !client.isActive()) return;
23676
+ if (!client) return;
23618
23677
  if (mountedRef.current) setLoading(true);
23619
23678
  try {
23620
23679
  const count = await client.peekChannel(channelKeyRef.current);
@@ -23643,7 +23702,7 @@ function usePeekChannel(channelKey, opts = {}) {
23643
23702
  let cancelled = false;
23644
23703
  let timer;
23645
23704
  const run = async () => {
23646
- if (cancelled || !client.isActive()) return;
23705
+ if (cancelled) return;
23647
23706
  try {
23648
23707
  const count = await client.peekChannel(channelKey);
23649
23708
  if (cancelled) return;