@yorkie-js/sdk 0.7.9 → 0.7.10-rc2

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.
@@ -5865,7 +5865,7 @@ var DocEventType$1 = /* @__PURE__ */ ((DocEventType2) => {
5865
5865
  DocEventType2[DocEventType2["DOCUMENT_BROADCAST"] = 3] = "DOCUMENT_BROADCAST";
5866
5866
  return DocEventType2;
5867
5867
  })(DocEventType$1 || {});
5868
- const file_yorkie_v1_yorkie = /* @__PURE__ */ fileDesc("ChZ5b3JraWUvdjEveW9ya2llLnByb3RvEgl5b3JraWUudjEingEKFUFjdGl2YXRlQ2xpZW50UmVxdWVzdBISCgpjbGllbnRfa2V5GAEgASgJEkAKCG1ldGFkYXRhGAIgAygLMi4ueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIrChZBY3RpdmF0ZUNsaWVudFJlc3BvbnNlEhEKCWNsaWVudF9pZBgBIAEoCSJBChdEZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLc3luY2hyb25vdXMYAiABKAgiGgoYRGVhY3RpdmF0ZUNsaWVudFJlc3BvbnNlImoKFUF0dGFjaERvY3VtZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSKgoLY2hhbmdlX3BhY2sYAiABKAsyFS55b3JraWUudjEuQ2hhbmdlUGFjaxISCgpzY2hlbWFfa2V5GAMgASgJIp8BChZBdHRhY2hEb2N1bWVudFJlc3BvbnNlEhMKC2RvY3VtZW50X2lkGAEgASgJEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHQoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAMgASgFEiUKDHNjaGVtYV9ydWxlcxgEIAMoCzIPLnlvcmtpZS52MS5SdWxlIosBChVEZXRhY2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHgoWcmVtb3ZlX2lmX25vdF9hdHRhY2hlZBgEIAEoCCJEChZEZXRhY2hEb2N1bWVudFJlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siUwoMV2F0Y2hSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRIwCglyZXNvdXJjZXMYAiADKAsyHS55b3JraWUudjEuUmVzb3VyY2VEZXNjcmlwdG9yIoQBChJSZXNvdXJjZURlc2NyaXB0b3ISMQoIZG9jdW1lbnQYASABKAsyHS55b3JraWUudjEuRG9jdW1lbnREZXNjcmlwdG9ySAASLwoHY2hhbm5lbBgCIAEoCzIcLnlvcmtpZS52MS5DaGFubmVsRGVzY3JpcHRvckgAQgoKCHJlc291cmNlIikKEkRvY3VtZW50RGVzY3JpcHRvchITCgtkb2N1bWVudF9pZBgBIAEoCSIoChFDaGFubmVsRGVzY3JpcHRvchITCgtjaGFubmVsX2tleRgBIAEoCSJ5Cg1XYXRjaFJlc3BvbnNlEjgKDmluaXRpYWxpemF0aW9uGAEgASgLMh4ueW9ya2llLnYxLldhdGNoSW5pdGlhbGl6YXRpb25IABImCgVldmVudBgCIAEoCzIVLnlvcmtpZS52MS5XYXRjaEV2ZW50SABCBgoEYm9keSJGChNXYXRjaEluaXRpYWxpemF0aW9uEi8KDnJlc291cmNlX2luaXRzGAEgAygLMhcueW9ya2llLnYxLlJlc291cmNlSW5pdCJ4CgxSZXNvdXJjZUluaXQSMAoNZG9jdW1lbnRfaW5pdBgBIAEoCzIXLnlvcmtpZS52MS5Eb2N1bWVudEluaXRIABIuCgxjaGFubmVsX2luaXQYAiABKAsyFi55b3JraWUudjEuQ2hhbm5lbEluaXRIAEIGCgRpbml0IjcKDERvY3VtZW50SW5pdBITCgtkb2N1bWVudF9pZBgBIAEoCRISCgpjbGllbnRfaWRzGAIgAygJIkYKC0NoYW5uZWxJbml0EhMKC2NoYW5uZWxfa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMSCwoDc2VxGAMgASgDInsKCldhdGNoRXZlbnQSLQoJZG9jX2V2ZW50GAEgASgLMhgueW9ya2llLnYxLkRvY1dhdGNoRXZlbnRIABI1Cg1jaGFubmVsX2V2ZW50GAIgASgLMhwueW9ya2llLnYxLkNoYW5uZWxXYXRjaEV2ZW50SABCBwoFZXZlbnQiSAoNRG9jV2F0Y2hFdmVudBITCgtkb2N1bWVudF9pZBgBIAEoCRIiCgVldmVudBgCIAEoCzITLnlvcmtpZS52MS5Eb2NFdmVudCJQChFDaGFubmVsV2F0Y2hFdmVudBITCgtjaGFubmVsX2tleRgBIAEoCRImCgVldmVudBgCIAEoCzIXLnlvcmtpZS52MS5DaGFubmVsRXZlbnQiPgoUV2F0Y2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJIrYBChVXYXRjaERvY3VtZW50UmVzcG9uc2USSQoOaW5pdGlhbGl6YXRpb24YASABKAsyLy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlLkluaXRpYWxpemF0aW9uSAASJAoFZXZlbnQYAiABKAsyEy55b3JraWUudjEuRG9jRXZlbnRIABokCg5Jbml0aWFsaXphdGlvbhISCgpjbGllbnRfaWRzGAEgAygJQgYKBGJvZHkiPQoTV2F0Y2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkigwEKFFdhdGNoQ2hhbm5lbFJlc3BvbnNlEjkKC2luaXRpYWxpemVkGAEgASgLMiIueW9ya2llLnYxLldhdGNoQ2hhbm5lbEluaXRpYWxpemVkSAASKAoFZXZlbnQYAiABKAsyFy55b3JraWUudjEuQ2hhbm5lbEV2ZW50SABCBgoEYm9keSI9ChdXYXRjaENoYW5uZWxJbml0aWFsaXplZBIVCg1zZXNzaW9uX2NvdW50GAEgASgDEgsKA3NlcRgCIAEoAyJrChVSZW1vdmVEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siRAoWUmVtb3ZlRG9jdW1lbnRSZXNwb25zZRIqCgtjaGFuZ2VfcGFjaxgBIAEoCzIVLnlvcmtpZS52MS5DaGFuZ2VQYWNrIn8KFlB1c2hQdWxsQ2hhbmdlc1JlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSEQoJcHVzaF9vbmx5GAQgASgIIkUKF1B1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAEgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siYwoVQ3JlYXRlUmV2aXNpb25SZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRINCgVsYWJlbBgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCSJGChZDcmVhdGVSZXZpc2lvblJlc3BvbnNlEiwKCHJldmlzaW9uGAEgASgLMhoueW9ya2llLnYxLlJldmlzaW9uU3VtbWFyeSJRChJHZXRSZXZpc2lvblJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEhMKC3JldmlzaW9uX2lkGAMgASgJIkMKE0dldFJldmlzaW9uUmVzcG9uc2USLAoIcmV2aXNpb24YASABKAsyGi55b3JraWUudjEuUmV2aXNpb25TdW1tYXJ5InUKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRIRCglwYWdlX3NpemUYAyABKAUSDgoGb2Zmc2V0GAQgASgFEhIKCmlzX2ZvcndhcmQYBSABKAgiRgoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEi0KCXJldmlzaW9ucxgBIAMoCzIaLnlvcmtpZS52MS5SZXZpc2lvblN1bW1hcnkiVQoWUmVzdG9yZVJldmlzaW9uUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLZG9jdW1lbnRfaWQYAiABKAkSEwoLcmV2aXNpb25faWQYBCABKAkiGQoXUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiPgoUQXR0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJIkIKFUF0dGFjaENoYW5uZWxSZXNwb25zZRISCgpzZXNzaW9uX2lkGAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMiUgoURGV0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiLgoVRGV0YWNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMiUwoVUmVmcmVzaENoYW5uZWxSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtjaGFubmVsX2tleRgCIAEoCRISCgpzZXNzaW9uX2lkGAMgASgJIi8KFlJlZnJlc2hDaGFubmVsUmVzcG9uc2USFQoNc2Vzc2lvbl9jb3VudBgBIAEoAyIpChJQZWVrQ2hhbm5lbFJlcXVlc3QSEwoLY2hhbm5lbF9rZXkYASABKAkiLAoTUGVla0NoYW5uZWxSZXNwb25zZRIVCg1zZXNzaW9uX2NvdW50GAEgASgDIloKEEJyb2FkY2FzdFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEg0KBXRvcGljGAMgASgJEg8KB3BheWxvYWQYBCABKAwiEwoRQnJvYWRjYXN0UmVzcG9uc2UylQwKDVlvcmtpZVNlcnZpY2USVwoOQWN0aXZhdGVDbGllbnQSIC55b3JraWUudjEuQWN0aXZhdGVDbGllbnRSZXF1ZXN0GiEueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVzcG9uc2UiABJdChBEZWFjdGl2YXRlQ2xpZW50EiIueW9ya2llLnYxLkRlYWN0aXZhdGVDbGllbnRSZXF1ZXN0GiMueW9ya2llLnYxLkRlYWN0aXZhdGVDbGllbnRSZXNwb25zZSIAElcKDkF0dGFjaERvY3VtZW50EiAueW9ya2llLnYxLkF0dGFjaERvY3VtZW50UmVxdWVzdBohLnlvcmtpZS52MS5BdHRhY2hEb2N1bWVudFJlc3BvbnNlIgASVwoORGV0YWNoRG9jdW1lbnQSIC55b3JraWUudjEuRGV0YWNoRG9jdW1lbnRSZXF1ZXN0GiEueW9ya2llLnYxLkRldGFjaERvY3VtZW50UmVzcG9uc2UiABJXCg5SZW1vdmVEb2N1bWVudBIgLnlvcmtpZS52MS5SZW1vdmVEb2N1bWVudFJlcXVlc3QaIS55b3JraWUudjEuUmVtb3ZlRG9jdW1lbnRSZXNwb25zZSIAEloKD1B1c2hQdWxsQ2hhbmdlcxIhLnlvcmtpZS52MS5QdXNoUHVsbENoYW5nZXNSZXF1ZXN0GiIueW9ya2llLnYxLlB1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlIgASPgoFV2F0Y2gSFy55b3JraWUudjEuV2F0Y2hSZXF1ZXN0GhgueW9ya2llLnYxLldhdGNoUmVzcG9uc2UiADABElYKDVdhdGNoRG9jdW1lbnQSHy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlcXVlc3QaIC55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlIgAwARJTCgxXYXRjaENoYW5uZWwSHi55b3JraWUudjEuV2F0Y2hDaGFubmVsUmVxdWVzdBofLnlvcmtpZS52MS5XYXRjaENoYW5uZWxSZXNwb25zZSIAMAESVwoOQ3JlYXRlUmV2aXNpb24SIC55b3JraWUudjEuQ3JlYXRlUmV2aXNpb25SZXF1ZXN0GiEueW9ya2llLnYxLkNyZWF0ZVJldmlzaW9uUmVzcG9uc2UiABJOCgtHZXRSZXZpc2lvbhIdLnlvcmtpZS52MS5HZXRSZXZpc2lvblJlcXVlc3QaHi55b3JraWUudjEuR2V0UmV2aXNpb25SZXNwb25zZSIAElQKDUxpc3RSZXZpc2lvbnMSHy55b3JraWUudjEuTGlzdFJldmlzaW9uc1JlcXVlc3QaIC55b3JraWUudjEuTGlzdFJldmlzaW9uc1Jlc3BvbnNlIgASWgoPUmVzdG9yZVJldmlzaW9uEiEueW9ya2llLnYxLlJlc3RvcmVSZXZpc2lvblJlcXVlc3QaIi55b3JraWUudjEuUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiABJUCg1BdHRhY2hDaGFubmVsEh8ueW9ya2llLnYxLkF0dGFjaENoYW5uZWxSZXF1ZXN0GiAueW9ya2llLnYxLkF0dGFjaENoYW5uZWxSZXNwb25zZSIAElQKDURldGFjaENoYW5uZWwSHy55b3JraWUudjEuRGV0YWNoQ2hhbm5lbFJlcXVlc3QaIC55b3JraWUudjEuRGV0YWNoQ2hhbm5lbFJlc3BvbnNlIgASVwoOUmVmcmVzaENoYW5uZWwSIC55b3JraWUudjEuUmVmcmVzaENoYW5uZWxSZXF1ZXN0GiEueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVzcG9uc2UiABJOCgtQZWVrQ2hhbm5lbBIdLnlvcmtpZS52MS5QZWVrQ2hhbm5lbFJlcXVlc3QaHi55b3JraWUudjEuUGVla0NoYW5uZWxSZXNwb25zZSIAEkgKCUJyb2FkY2FzdBIbLnlvcmtpZS52MS5Ccm9hZGNhc3RSZXF1ZXN0GhwueW9ya2llLnYxLkJyb2FkY2FzdFJlc3BvbnNlIgBCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_yorkie_v1_resources]);
5868
+ const file_yorkie_v1_yorkie = /* @__PURE__ */ fileDesc("ChZ5b3JraWUvdjEveW9ya2llLnByb3RvEgl5b3JraWUudjEingEKFUFjdGl2YXRlQ2xpZW50UmVxdWVzdBISCgpjbGllbnRfa2V5GAEgASgJEkAKCG1ldGFkYXRhGAIgAygLMi4ueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIrChZBY3RpdmF0ZUNsaWVudFJlc3BvbnNlEhEKCWNsaWVudF9pZBgBIAEoCSJBChdEZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLc3luY2hyb25vdXMYAiABKAgiGgoYRGVhY3RpdmF0ZUNsaWVudFJlc3BvbnNlImoKFUF0dGFjaERvY3VtZW50UmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSKgoLY2hhbmdlX3BhY2sYAiABKAsyFS55b3JraWUudjEuQ2hhbmdlUGFjaxISCgpzY2hlbWFfa2V5GAMgASgJIp8BChZBdHRhY2hEb2N1bWVudFJlc3BvbnNlEhMKC2RvY3VtZW50X2lkGAEgASgJEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHQoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAMgASgFEiUKDHNjaGVtYV9ydWxlcxgEIAMoCzIPLnlvcmtpZS52MS5SdWxlIosBChVEZXRhY2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSHgoWcmVtb3ZlX2lmX25vdF9hdHRhY2hlZBgEIAEoCCJEChZEZXRhY2hEb2N1bWVudFJlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAIgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siUwoMV2F0Y2hSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRIwCglyZXNvdXJjZXMYAiADKAsyHS55b3JraWUudjEuUmVzb3VyY2VEZXNjcmlwdG9yIoQBChJSZXNvdXJjZURlc2NyaXB0b3ISMQoIZG9jdW1lbnQYASABKAsyHS55b3JraWUudjEuRG9jdW1lbnREZXNjcmlwdG9ySAASLwoHY2hhbm5lbBgCIAEoCzIcLnlvcmtpZS52MS5DaGFubmVsRGVzY3JpcHRvckgAQgoKCHJlc291cmNlIikKEkRvY3VtZW50RGVzY3JpcHRvchITCgtkb2N1bWVudF9pZBgBIAEoCSIoChFDaGFubmVsRGVzY3JpcHRvchITCgtjaGFubmVsX2tleRgBIAEoCSJ5Cg1XYXRjaFJlc3BvbnNlEjgKDmluaXRpYWxpemF0aW9uGAEgASgLMh4ueW9ya2llLnYxLldhdGNoSW5pdGlhbGl6YXRpb25IABImCgVldmVudBgCIAEoCzIVLnlvcmtpZS52MS5XYXRjaEV2ZW50SABCBgoEYm9keSJGChNXYXRjaEluaXRpYWxpemF0aW9uEi8KDnJlc291cmNlX2luaXRzGAEgAygLMhcueW9ya2llLnYxLlJlc291cmNlSW5pdCJ4CgxSZXNvdXJjZUluaXQSMAoNZG9jdW1lbnRfaW5pdBgBIAEoCzIXLnlvcmtpZS52MS5Eb2N1bWVudEluaXRIABIuCgxjaGFubmVsX2luaXQYAiABKAsyFi55b3JraWUudjEuQ2hhbm5lbEluaXRIAEIGCgRpbml0IjcKDERvY3VtZW50SW5pdBITCgtkb2N1bWVudF9pZBgBIAEoCRISCgpjbGllbnRfaWRzGAIgAygJIkYKC0NoYW5uZWxJbml0EhMKC2NoYW5uZWxfa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMSCwoDc2VxGAMgASgDInsKCldhdGNoRXZlbnQSLQoJZG9jX2V2ZW50GAEgASgLMhgueW9ya2llLnYxLkRvY1dhdGNoRXZlbnRIABI1Cg1jaGFubmVsX2V2ZW50GAIgASgLMhwueW9ya2llLnYxLkNoYW5uZWxXYXRjaEV2ZW50SABCBwoFZXZlbnQiSAoNRG9jV2F0Y2hFdmVudBITCgtkb2N1bWVudF9pZBgBIAEoCRIiCgVldmVudBgCIAEoCzITLnlvcmtpZS52MS5Eb2NFdmVudCJQChFDaGFubmVsV2F0Y2hFdmVudBITCgtjaGFubmVsX2tleRgBIAEoCRImCgVldmVudBgCIAEoCzIXLnlvcmtpZS52MS5DaGFubmVsRXZlbnQiPgoUV2F0Y2hEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJIrYBChVXYXRjaERvY3VtZW50UmVzcG9uc2USSQoOaW5pdGlhbGl6YXRpb24YASABKAsyLy55b3JraWUudjEuV2F0Y2hEb2N1bWVudFJlc3BvbnNlLkluaXRpYWxpemF0aW9uSAASJAoFZXZlbnQYAiABKAsyEy55b3JraWUudjEuRG9jRXZlbnRIABokCg5Jbml0aWFsaXphdGlvbhISCgpjbGllbnRfaWRzGAEgAygJQgYKBGJvZHkiPQoTV2F0Y2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkigwEKFFdhdGNoQ2hhbm5lbFJlc3BvbnNlEjkKC2luaXRpYWxpemVkGAEgASgLMiIueW9ya2llLnYxLldhdGNoQ2hhbm5lbEluaXRpYWxpemVkSAASKAoFZXZlbnQYAiABKAsyFy55b3JraWUudjEuQ2hhbm5lbEV2ZW50SABCBgoEYm9keSI9ChdXYXRjaENoYW5uZWxJbml0aWFsaXplZBIVCg1zZXNzaW9uX2NvdW50GAEgASgDEgsKA3NlcRgCIAEoAyJrChVSZW1vdmVEb2N1bWVudFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siRAoWUmVtb3ZlRG9jdW1lbnRSZXNwb25zZRIqCgtjaGFuZ2VfcGFjaxgBIAEoCzIVLnlvcmtpZS52MS5DaGFuZ2VQYWNrIn8KFlB1c2hQdWxsQ2hhbmdlc1JlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEioKC2NoYW5nZV9wYWNrGAMgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2sSEQoJcHVzaF9vbmx5GAQgASgIIkUKF1B1c2hQdWxsQ2hhbmdlc1Jlc3BvbnNlEioKC2NoYW5nZV9wYWNrGAEgASgLMhUueW9ya2llLnYxLkNoYW5nZVBhY2siYwoVQ3JlYXRlUmV2aXNpb25SZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRINCgVsYWJlbBgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCSJGChZDcmVhdGVSZXZpc2lvblJlc3BvbnNlEiwKCHJldmlzaW9uGAEgASgLMhoueW9ya2llLnYxLlJldmlzaW9uU3VtbWFyeSJRChJHZXRSZXZpc2lvblJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2RvY3VtZW50X2lkGAIgASgJEhMKC3JldmlzaW9uX2lkGAMgASgJIkMKE0dldFJldmlzaW9uUmVzcG9uc2USLAoIcmV2aXNpb24YASABKAsyGi55b3JraWUudjEuUmV2aXNpb25TdW1tYXJ5InUKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtkb2N1bWVudF9pZBgCIAEoCRIRCglwYWdlX3NpemUYAyABKAUSDgoGb2Zmc2V0GAQgASgFEhIKCmlzX2ZvcndhcmQYBSABKAgiRgoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEi0KCXJldmlzaW9ucxgBIAMoCzIaLnlvcmtpZS52MS5SZXZpc2lvblN1bW1hcnkiVQoWUmVzdG9yZVJldmlzaW9uUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLZG9jdW1lbnRfaWQYAiABKAkSEwoLcmV2aXNpb25faWQYBCABKAkiGQoXUmVzdG9yZVJldmlzaW9uUmVzcG9uc2UiPgoUQXR0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJIkIKFUF0dGFjaENoYW5uZWxSZXNwb25zZRISCgpzZXNzaW9uX2lkGAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAMiUgoURGV0YWNoQ2hhbm5lbFJlcXVlc3QSEQoJY2xpZW50X2lkGAEgASgJEhMKC2NoYW5uZWxfa2V5GAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiLgoVRGV0YWNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMi2gEKFVJlZnJlc2hDaGFubmVsUmVxdWVzdBIRCgljbGllbnRfaWQYASABKAkSEwoLY2hhbm5lbF9rZXkYAiABKAkSEgoKc2Vzc2lvbl9pZBgDIAEoCRISCgpjbGllbnRfa2V5GAQgASgJEkAKCG1ldGFkYXRhGAUgAygLMi4ueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVxdWVzdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJWChZSZWZyZXNoQ2hhbm5lbFJlc3BvbnNlEhUKDXNlc3Npb25fY291bnQYASABKAMSEQoJY2xpZW50X2lkGAIgASgJEhIKCnNlc3Npb25faWQYAyABKAkiKQoSUGVla0NoYW5uZWxSZXF1ZXN0EhMKC2NoYW5uZWxfa2V5GAEgASgJIiwKE1BlZWtDaGFubmVsUmVzcG9uc2USFQoNc2Vzc2lvbl9jb3VudBgBIAEoAyJaChBCcm9hZGNhc3RSZXF1ZXN0EhEKCWNsaWVudF9pZBgBIAEoCRITCgtjaGFubmVsX2tleRgCIAEoCRINCgV0b3BpYxgDIAEoCRIPCgdwYXlsb2FkGAQgASgMIhMKEUJyb2FkY2FzdFJlc3BvbnNlMpUMCg1Zb3JraWVTZXJ2aWNlElcKDkFjdGl2YXRlQ2xpZW50EiAueW9ya2llLnYxLkFjdGl2YXRlQ2xpZW50UmVxdWVzdBohLnlvcmtpZS52MS5BY3RpdmF0ZUNsaWVudFJlc3BvbnNlIgASXQoQRGVhY3RpdmF0ZUNsaWVudBIiLnlvcmtpZS52MS5EZWFjdGl2YXRlQ2xpZW50UmVxdWVzdBojLnlvcmtpZS52MS5EZWFjdGl2YXRlQ2xpZW50UmVzcG9uc2UiABJXCg5BdHRhY2hEb2N1bWVudBIgLnlvcmtpZS52MS5BdHRhY2hEb2N1bWVudFJlcXVlc3QaIS55b3JraWUudjEuQXR0YWNoRG9jdW1lbnRSZXNwb25zZSIAElcKDkRldGFjaERvY3VtZW50EiAueW9ya2llLnYxLkRldGFjaERvY3VtZW50UmVxdWVzdBohLnlvcmtpZS52MS5EZXRhY2hEb2N1bWVudFJlc3BvbnNlIgASVwoOUmVtb3ZlRG9jdW1lbnQSIC55b3JraWUudjEuUmVtb3ZlRG9jdW1lbnRSZXF1ZXN0GiEueW9ya2llLnYxLlJlbW92ZURvY3VtZW50UmVzcG9uc2UiABJaCg9QdXNoUHVsbENoYW5nZXMSIS55b3JraWUudjEuUHVzaFB1bGxDaGFuZ2VzUmVxdWVzdBoiLnlvcmtpZS52MS5QdXNoUHVsbENoYW5nZXNSZXNwb25zZSIAEj4KBVdhdGNoEhcueW9ya2llLnYxLldhdGNoUmVxdWVzdBoYLnlvcmtpZS52MS5XYXRjaFJlc3BvbnNlIgAwARJWCg1XYXRjaERvY3VtZW50Eh8ueW9ya2llLnYxLldhdGNoRG9jdW1lbnRSZXF1ZXN0GiAueW9ya2llLnYxLldhdGNoRG9jdW1lbnRSZXNwb25zZSIAMAESUwoMV2F0Y2hDaGFubmVsEh4ueW9ya2llLnYxLldhdGNoQ2hhbm5lbFJlcXVlc3QaHy55b3JraWUudjEuV2F0Y2hDaGFubmVsUmVzcG9uc2UiADABElcKDkNyZWF0ZVJldmlzaW9uEiAueW9ya2llLnYxLkNyZWF0ZVJldmlzaW9uUmVxdWVzdBohLnlvcmtpZS52MS5DcmVhdGVSZXZpc2lvblJlc3BvbnNlIgASTgoLR2V0UmV2aXNpb24SHS55b3JraWUudjEuR2V0UmV2aXNpb25SZXF1ZXN0Gh4ueW9ya2llLnYxLkdldFJldmlzaW9uUmVzcG9uc2UiABJUCg1MaXN0UmV2aXNpb25zEh8ueW9ya2llLnYxLkxpc3RSZXZpc2lvbnNSZXF1ZXN0GiAueW9ya2llLnYxLkxpc3RSZXZpc2lvbnNSZXNwb25zZSIAEloKD1Jlc3RvcmVSZXZpc2lvbhIhLnlvcmtpZS52MS5SZXN0b3JlUmV2aXNpb25SZXF1ZXN0GiIueW9ya2llLnYxLlJlc3RvcmVSZXZpc2lvblJlc3BvbnNlIgASVAoNQXR0YWNoQ2hhbm5lbBIfLnlvcmtpZS52MS5BdHRhY2hDaGFubmVsUmVxdWVzdBogLnlvcmtpZS52MS5BdHRhY2hDaGFubmVsUmVzcG9uc2UiABJUCg1EZXRhY2hDaGFubmVsEh8ueW9ya2llLnYxLkRldGFjaENoYW5uZWxSZXF1ZXN0GiAueW9ya2llLnYxLkRldGFjaENoYW5uZWxSZXNwb25zZSIAElcKDlJlZnJlc2hDaGFubmVsEiAueW9ya2llLnYxLlJlZnJlc2hDaGFubmVsUmVxdWVzdBohLnlvcmtpZS52MS5SZWZyZXNoQ2hhbm5lbFJlc3BvbnNlIgASTgoLUGVla0NoYW5uZWwSHS55b3JraWUudjEuUGVla0NoYW5uZWxSZXF1ZXN0Gh4ueW9ya2llLnYxLlBlZWtDaGFubmVsUmVzcG9uc2UiABJICglCcm9hZGNhc3QSGy55b3JraWUudjEuQnJvYWRjYXN0UmVxdWVzdBocLnlvcmtpZS52MS5Ccm9hZGNhc3RSZXNwb25zZSIAQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_yorkie_v1_resources]);
5869
5869
  const YorkieService = /* @__PURE__ */ serviceDesc(file_yorkie_v1_yorkie, 0);
5870
5870
  const file_google_rpc_error_details = /* @__PURE__ */ fileDesc("Ch5nb29nbGUvcnBjL2Vycm9yX2RldGFpbHMucHJvdG8SCmdvb2dsZS5ycGMikwEKCUVycm9ySW5mbxIOCgZyZWFzb24YASABKAkSDgoGZG9tYWluGAIgASgJEjUKCG1ldGFkYXRhGAMgAygLMiMuZ29vZ2xlLnJwYy5FcnJvckluZm8uTWV0YWRhdGFFbnRyeRovCg1NZXRhZGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiOwoJUmV0cnlJbmZvEi4KC3JldHJ5X2RlbGF5GAEgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIjIKCURlYnVnSW5mbxIVCg1zdGFja19lbnRyaWVzGAEgAygJEg4KBmRldGFpbBgCIAEoCSKPAwoMUXVvdGFGYWlsdXJlEjYKCnZpb2xhdGlvbnMYASADKAsyIi5nb29nbGUucnBjLlF1b3RhRmFpbHVyZS5WaW9sYXRpb24axgIKCVZpb2xhdGlvbhIPCgdzdWJqZWN0GAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJEhMKC2FwaV9zZXJ2aWNlGAMgASgJEhQKDHF1b3RhX21ldHJpYxgEIAEoCRIQCghxdW90YV9pZBgFIAEoCRJRChBxdW90YV9kaW1lbnNpb25zGAYgAygLMjcuZ29vZ2xlLnJwYy5RdW90YUZhaWx1cmUuVmlvbGF0aW9uLlF1b3RhRGltZW5zaW9uc0VudHJ5EhMKC3F1b3RhX3ZhbHVlGAcgASgDEh8KEmZ1dHVyZV9xdW90YV92YWx1ZRgIIAEoA0gAiAEBGjYKFFF1b3RhRGltZW5zaW9uc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAFCFQoTX2Z1dHVyZV9xdW90YV92YWx1ZSKVAQoTUHJlY29uZGl0aW9uRmFpbHVyZRI9Cgp2aW9sYXRpb25zGAEgAygLMikuZ29vZ2xlLnJwYy5QcmVjb25kaXRpb25GYWlsdXJlLlZpb2xhdGlvbho/CglWaW9sYXRpb24SDAoEdHlwZRgBIAEoCRIPCgdzdWJqZWN0GAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJIswBCgpCYWRSZXF1ZXN0Ej8KEGZpZWxkX3Zpb2xhdGlvbnMYASADKAsyJS5nb29nbGUucnBjLkJhZFJlcXVlc3QuRmllbGRWaW9sYXRpb24afQoORmllbGRWaW9sYXRpb24SDQoFZmllbGQYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSDgoGcmVhc29uGAMgASgJEjcKEWxvY2FsaXplZF9tZXNzYWdlGAQgASgLMhwuZ29vZ2xlLnJwYy5Mb2NhbGl6ZWRNZXNzYWdlIjcKC1JlcXVlc3RJbmZvEhIKCnJlcXVlc3RfaWQYASABKAkSFAoMc2VydmluZ19kYXRhGAIgASgJImAKDFJlc291cmNlSW5mbxIVCg1yZXNvdXJjZV90eXBlGAEgASgJEhUKDXJlc291cmNlX25hbWUYAiABKAkSDQoFb3duZXIYAyABKAkSEwoLZGVzY3JpcHRpb24YBCABKAkiVgoESGVscBIkCgVsaW5rcxgBIAMoCzIVLmdvb2dsZS5ycGMuSGVscC5MaW5rGigKBExpbmsSEwoLZGVzY3JpcHRpb24YASABKAkSCwoDdXJsGAIgASgJIjMKEExvY2FsaXplZE1lc3NhZ2USDgoGbG9jYWxlGAEgASgJEg8KB21lc3NhZ2UYAiABKAlCbAoOY29tLmdvb2dsZS5ycGNCEUVycm9yRGV0YWlsc1Byb3RvUAFaP2dvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvcnBjL2VycmRldGFpbHM7ZXJyZGV0YWlsc6ICA1JQQ2IGcHJvdG8z", [file_google_protobuf_duration]);
5871
5871
  const ErrorInfoSchema = /* @__PURE__ */ messageDesc(file_google_rpc_error_details, 0);
@@ -5878,6 +5878,7 @@ var Code = /* @__PURE__ */ ((Code2) => {
5878
5878
  Code2["ErrDummy"] = "ErrDummy";
5879
5879
  Code2["ErrNotAttached"] = "ErrNotAttached";
5880
5880
  Code2["ErrNotDetached"] = "ErrNotDetached";
5881
+ Code2["ErrSessionNotFound"] = "ErrSessionNotFound";
5881
5882
  Code2["ErrDocumentRemoved"] = "ErrDocumentRemoved";
5882
5883
  Code2["ErrDocumentSizeExceedsLimit"] = "ErrDocumentSizeExceedsLimit";
5883
5884
  Code2["ErrDocumentSchemaValidationFailed"] = "ErrDocumentSchemaValidationFailed";
@@ -20781,12 +20782,25 @@ class Document {
20781
20782
  }
20782
20783
  class Attachment {
20783
20784
  resource;
20785
+ /**
20786
+ * For Documents: the document's resourceID, available at attach time.
20787
+ * For Channels: the server-issued session_id. Starts empty and is
20788
+ * populated after the first `RefreshChannel` first-call response.
20789
+ */
20784
20790
  resourceID;
20785
20791
  syncMode;
20786
20792
  changeEventReceived;
20787
20793
  lastHeartbeatTime;
20788
20794
  pollInterval;
20789
20795
  pollIntervalPinned;
20796
+ /**
20797
+ * `unsubscribeLocalBroadcast` is set by `attachChannel` when it forwards
20798
+ * a Channel's `local-broadcast` events to the RPC client, and consumed
20799
+ * by `detachInternal` so the subscription does not survive a detach.
20800
+ * Without this, re-attaching a channel accumulates duplicate handlers
20801
+ * on each attach cycle.
20802
+ */
20803
+ unsubscribeLocalBroadcast;
20790
20804
  reconnectStreamDelay;
20791
20805
  cancelled;
20792
20806
  watchStream;
@@ -20794,13 +20808,13 @@ class Attachment {
20794
20808
  watchAbortController;
20795
20809
  syncPromise;
20796
20810
  _detaching = false;
20797
- constructor(reconnectStreamDelay, resource, resourceID, syncMode, pollInterval = 0, pollIntervalPinned = false) {
20811
+ constructor(reconnectStreamDelay, resource, resourceID = "", syncMode, pollInterval = 0, pollIntervalPinned = false) {
20798
20812
  this.reconnectStreamDelay = reconnectStreamDelay;
20799
20813
  this.resource = resource;
20800
20814
  this.resourceID = resourceID;
20801
20815
  this.syncMode = syncMode;
20802
20816
  this.changeEventReceived = syncMode !== void 0 ? false : void 0;
20803
- this.lastHeartbeatTime = Date.now();
20817
+ this.lastHeartbeatTime = 0;
20804
20818
  this.pollInterval = pollInterval;
20805
20819
  this.pollIntervalPinned = pollIntervalPinned;
20806
20820
  this.cancelled = false;
@@ -20962,7 +20976,7 @@ function createAuthInterceptor(apiKey, token) {
20962
20976
  };
20963
20977
  }
20964
20978
  const name = "@yorkie-js/sdk";
20965
- const version = "0.7.9";
20979
+ const version = "0.7.10-rc2";
20966
20980
  const pkg = {
20967
20981
  name,
20968
20982
  version
@@ -21000,6 +21014,7 @@ var ChannelEventType = /* @__PURE__ */ ((ChannelEventType2) => {
21000
21014
  ChannelEventType2["Broadcast"] = "broadcast";
21001
21015
  ChannelEventType2["LocalBroadcast"] = "local-broadcast";
21002
21016
  ChannelEventType2["AuthError"] = "auth-error";
21017
+ ChannelEventType2["SyncError"] = "sync-error";
21003
21018
  return ChannelEventType2;
21004
21019
  })(ChannelEventType || {});
21005
21020
  const KeyPathSeparator = ".";
@@ -21139,6 +21154,13 @@ class Channel2 {
21139
21154
  }
21140
21155
  });
21141
21156
  }
21157
+ if (typeOrTopic === "sync-error") {
21158
+ return this.eventStream.subscribe((event) => {
21159
+ if (event.type === "sync-error") {
21160
+ callback(event);
21161
+ }
21162
+ });
21163
+ }
21142
21164
  if (typeOrTopic === "presence") {
21143
21165
  return this.eventStream.subscribe((event) => {
21144
21166
  if (event.type === "presence-changed" || event.type === "initialized") {
@@ -21258,13 +21280,14 @@ var ClientCondition = /* @__PURE__ */ ((ClientCondition2) => {
21258
21280
  ClientCondition2["WatchLoop"] = "WatchLoop";
21259
21281
  return ClientCondition2;
21260
21282
  })(ClientCondition || {});
21261
- const DefaultPollingIntervalMs = 3e3;
21283
+ const DefaultDocumentPollIntervalMs = 3e3;
21284
+ const DefaultChannelHeartbeatMs = 5e3;
21262
21285
  const DefaultClientOptions = {
21263
21286
  rpcAddr: "https://api.yorkie.dev",
21264
21287
  syncLoopDuration: 50,
21265
21288
  retrySyncLoopDelay: 1e3,
21266
21289
  reconnectStreamDelay: 1e3,
21267
- channelHeartbeatInterval: 3e4
21290
+ channelHeartbeatInterval: DefaultChannelHeartbeatMs
21268
21291
  };
21269
21292
  const DefaultBroadcastOptions = {
21270
21293
  maxRetries: Infinity,
@@ -21323,10 +21346,43 @@ class Client {
21323
21346
  baseUrl: rpcAddr,
21324
21347
  interceptors: [authInterceptor, createMetricInterceptor(opts?.userAgent)],
21325
21348
  fetch: (input, init) => {
21349
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
21350
+ if (/\/yorkie\.v1\.YorkieService\/Watch/.test(url)) {
21351
+ return fetch(input, {
21352
+ ...init,
21353
+ keepalive: this.keepalive
21354
+ });
21355
+ }
21356
+ const callerSignal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
21357
+ const innerAC = new AbortController();
21358
+ let onCallerAbort;
21359
+ if (callerSignal) {
21360
+ if (callerSignal.aborted) {
21361
+ innerAC.abort(callerSignal.reason);
21362
+ } else {
21363
+ onCallerAbort = () => innerAC.abort(callerSignal.reason);
21364
+ callerSignal.addEventListener("abort", onCallerAbort);
21365
+ }
21366
+ }
21367
+ const detach = () => {
21368
+ if (callerSignal && onCallerAbort) {
21369
+ callerSignal.removeEventListener("abort", onCallerAbort);
21370
+ }
21371
+ };
21326
21372
  return fetch(input, {
21327
21373
  ...init,
21374
+ signal: innerAC.signal,
21328
21375
  keepalive: this.keepalive
21329
- });
21376
+ }).then(
21377
+ (res) => {
21378
+ detach();
21379
+ return res;
21380
+ },
21381
+ (err) => {
21382
+ detach();
21383
+ throw err;
21384
+ }
21385
+ );
21330
21386
  }
21331
21387
  };
21332
21388
  this.rpcClient = createClient(
@@ -21461,7 +21517,7 @@ class Client {
21461
21517
  );
21462
21518
  }
21463
21519
  const pollIntervalPinned = opts.documentPollInterval !== void 0;
21464
- const pollInterval = pollIntervalPinned ? opts.documentPollInterval : syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21520
+ const pollInterval = pollIntervalPinned ? opts.documentPollInterval : syncMode === "polling" ? DefaultDocumentPollIntervalMs : 0;
21465
21521
  return this.enqueueTask(async () => {
21466
21522
  try {
21467
21523
  const res = await this.rpcClient.attachDocument(
@@ -21590,127 +21646,88 @@ class Client {
21590
21646
  return this.enqueueTask(task);
21591
21647
  }
21592
21648
  /**
21593
- * `attach` attaches the given channel to this client.
21594
- * It tells the server that this client will track the channel.
21649
+ * `attachChannel` attaches the given channel to this client. The channel is
21650
+ * registered locally and the server is notified on the next RefreshChannel
21651
+ * heartbeat.
21595
21652
  */
21596
21653
  async attachChannel(channel, opts = {}) {
21597
- if (!this.isActive()) {
21598
- throw new YorkieError(
21599
- Code.ErrClientNotActivated,
21600
- `${this.key} is not active`
21601
- );
21602
- }
21603
21654
  if (channel.getStatus() !== ChannelStatus.Detached) {
21604
21655
  throw new YorkieError(
21605
21656
  Code.ErrNotDetached,
21606
21657
  `${channel.getKey()} is not detached`
21607
21658
  );
21608
21659
  }
21609
- channel.setActor(this.id);
21660
+ const syncMode = opts.syncMode ?? "realtime";
21661
+ this.assertValidChannelSyncMode(syncMode);
21662
+ if (opts.channelHeartbeatInterval !== void 0 && opts.channelHeartbeatInterval <= 0) {
21663
+ throw new YorkieError(
21664
+ Code.ErrInvalidArgument,
21665
+ "channelHeartbeatInterval must be greater than 0"
21666
+ );
21667
+ }
21668
+ const pollIntervalPinned = opts.channelHeartbeatInterval !== void 0;
21669
+ const pollInterval = opts.channelHeartbeatInterval ?? this.channelHeartbeatInterval;
21610
21670
  const task = async () => {
21611
- try {
21612
- const res = await this.rpcClient.attachChannel(
21613
- {
21614
- clientId: this.id,
21615
- channelKey: channel.getKey()
21616
- },
21617
- {
21618
- headers: {
21619
- "x-shard-key": `${this.apiKey}/${channel.getFirstKeyPath()}`
21620
- }
21621
- }
21622
- );
21623
- channel.setSessionID(res.sessionId);
21624
- channel.updateSessionCount(Number(res.sessionCount), 0);
21625
- channel.applyStatus(ChannelStatus.Attached);
21626
- const syncMode = opts.syncMode ?? "realtime";
21627
- this.assertValidChannelSyncMode(syncMode);
21628
- if (opts.channelHeartbeatInterval !== void 0 && opts.channelHeartbeatInterval <= 0) {
21629
- throw new YorkieError(
21630
- Code.ErrInvalidArgument,
21631
- "channelHeartbeatInterval must be greater than 0"
21632
- );
21633
- }
21634
- const pollIntervalPinned = opts.channelHeartbeatInterval !== void 0;
21635
- const pollInterval = pollIntervalPinned ? opts.channelHeartbeatInterval : syncMode === "polling" ? DefaultPollingIntervalMs : this.channelHeartbeatInterval;
21636
- const attachment = new Attachment(
21637
- this.reconnectStreamDelay,
21638
- channel,
21639
- res.sessionId,
21640
- syncMode,
21641
- pollInterval,
21642
- pollIntervalPinned
21643
- );
21644
- channel.subscribe("local-broadcast", (event) => {
21671
+ if (this.id) {
21672
+ channel.setActor(this.id);
21673
+ }
21674
+ const attachment = new Attachment(
21675
+ this.reconnectStreamDelay,
21676
+ channel,
21677
+ "",
21678
+ // sessionID populated on first refresh response
21679
+ syncMode,
21680
+ pollInterval,
21681
+ pollIntervalPinned
21682
+ );
21683
+ attachment.unsubscribeLocalBroadcast = channel.subscribe(
21684
+ "local-broadcast",
21685
+ (event) => {
21645
21686
  const { topic, payload, options } = event;
21646
21687
  this.broadcast(channel.getKey(), topic, payload, options).catch(
21647
21688
  (error) => {
21648
- if (options?.error) {
21649
- options.error(error);
21650
- }
21689
+ if (options?.error) options.error(error);
21651
21690
  logger.error(`[BC] c:"${this.getKey()}" failed: ${error}`);
21652
21691
  }
21653
21692
  );
21654
- });
21655
- this.attachmentMap.set(channel.getKey(), attachment);
21656
- if (syncMode === "realtime") {
21657
- await this.runWatchLoop(channel.getKey());
21658
21693
  }
21659
- logger.info(
21660
- `[AP] c:"${this.getKey()}" attaches p:"${channel.getKey()}" mode:${syncMode} count:${channel.getSessionCount()}`
21661
- );
21662
- return channel;
21663
- } catch (err) {
21664
- logger.error(`[AP] c:"${this.getKey()}" err :`, err);
21665
- await this.handleConnectError(err);
21666
- throw err;
21694
+ );
21695
+ this.attachmentMap.set(channel.getKey(), attachment);
21696
+ if (!this.conditions[
21697
+ "SyncLoop"
21698
+ /* SyncLoop */
21699
+ ]) {
21700
+ this.runSyncLoop();
21667
21701
  }
21702
+ logger.info(
21703
+ `[AP] c:"${this.getKey()}" attaches p:"${channel.getKey()}" mode:${syncMode}`
21704
+ );
21705
+ return channel;
21668
21706
  };
21669
21707
  return this.enqueueTask(task);
21670
21708
  }
21671
21709
  /**
21672
- * `detachChannel` detaches the given channel from this client.
21673
- * It tells the server that this client will no longer track the channel.
21710
+ * `detachChannel` detaches the given channel from this client. The detach
21711
+ * is a local cleanup; the server reclaims the session via TTL when
21712
+ * heartbeats stop.
21674
21713
  */
21675
21714
  async detachChannel(channel) {
21676
- if (!this.isActive()) {
21677
- throw new YorkieError(
21678
- Code.ErrClientNotActivated,
21679
- `${this.key} is not active`
21680
- );
21681
- }
21682
- if (!this.attachmentMap.has(channel.getKey())) {
21715
+ const attachment = this.attachmentMap.get(channel.getKey());
21716
+ if (!attachment) {
21683
21717
  throw new YorkieError(
21684
21718
  Code.ErrNotAttached,
21685
21719
  `${channel.getKey()} is not attached`
21686
21720
  );
21687
21721
  }
21722
+ attachment.markDetaching();
21723
+ await attachment.waitForSyncComplete();
21688
21724
  const task = async () => {
21689
- try {
21690
- const res = await this.rpcClient.detachChannel(
21691
- {
21692
- clientId: this.id,
21693
- channelKey: channel.getKey(),
21694
- sessionId: channel.getSessionID()
21695
- },
21696
- {
21697
- headers: {
21698
- "x-shard-key": `${this.apiKey}/${channel.getFirstKeyPath()}`
21699
- }
21700
- }
21701
- );
21702
- channel.updateSessionCount(Number(res.sessionCount), 0);
21703
- channel.applyStatus(ChannelStatus.Detached);
21704
- this.detachInternal(channel.getKey());
21705
- logger.info(
21706
- `[DP] c:"${this.getKey()}" detaches p:"${channel.getKey()}" count:${channel.getSessionCount()}`
21707
- );
21708
- return channel;
21709
- } catch (err) {
21710
- logger.error(`[DP] c:"${this.getKey()}" err :`, err);
21711
- await this.handleConnectError(err);
21712
- throw err;
21713
- }
21725
+ channel.applyStatus(ChannelStatus.Detached);
21726
+ this.detachInternal(channel.getKey());
21727
+ logger.info(
21728
+ `[DP] c:"${this.getKey()}" detaches p:"${channel.getKey()}" (local)`
21729
+ );
21730
+ return channel;
21714
21731
  };
21715
21732
  return this.enqueueTask(task);
21716
21733
  }
@@ -21751,7 +21768,7 @@ class Client {
21751
21768
  attachment.changeEventReceived = true;
21752
21769
  }
21753
21770
  if (!attachment.pollIntervalPinned) {
21754
- attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : 0;
21771
+ attachment.pollInterval = syncMode === "polling" ? DefaultDocumentPollIntervalMs : 0;
21755
21772
  }
21756
21773
  if ((prevSyncMode === "manual" || prevSyncMode === "polling") && syncMode !== "manual" && syncMode !== "polling") {
21757
21774
  attachment.resetCancelled();
@@ -21772,12 +21789,6 @@ class Client {
21772
21789
  }
21773
21790
  }
21774
21791
  async changeChannelSyncMode(channel, syncMode) {
21775
- if (!this.isActive()) {
21776
- throw new YorkieError(
21777
- Code.ErrClientNotActivated,
21778
- `${this.key} is not active`
21779
- );
21780
- }
21781
21792
  const attachment = this.attachmentMap.get(channel.getKey());
21782
21793
  if (!attachment) {
21783
21794
  throw new YorkieError(
@@ -21795,7 +21806,7 @@ class Client {
21795
21806
  }
21796
21807
  attachment.changeSyncMode(syncMode);
21797
21808
  if (!attachment.pollIntervalPinned) {
21798
- attachment.pollInterval = syncMode === "polling" ? DefaultPollingIntervalMs : syncMode === "realtime" ? this.channelHeartbeatInterval : 0;
21809
+ attachment.pollInterval = syncMode === "manual" ? 0 : this.channelHeartbeatInterval;
21799
21810
  }
21800
21811
  if (syncMode === "realtime") {
21801
21812
  attachment.resetCancelled();
@@ -21807,7 +21818,7 @@ class Client {
21807
21818
  * `sync` implementation that handles both Document and Channel.
21808
21819
  */
21809
21820
  sync(resource) {
21810
- if (!this.isActive()) {
21821
+ if (!(resource instanceof Channel2) && !this.isActive()) {
21811
21822
  throw new YorkieError(
21812
21823
  Code.ErrClientNotActivated,
21813
21824
  `${this.key} is not active`
@@ -22134,12 +22145,6 @@ class Client {
22134
22145
  * subscribe to channel events. Polling is the caller's responsibility.
22135
22146
  */
22136
22147
  async peekChannel(channelKey) {
22137
- if (!this.isActive()) {
22138
- throw new YorkieError(
22139
- Code.ErrClientNotActivated,
22140
- `${this.key} is not active`
22141
- );
22142
- }
22143
22148
  return this.enqueueTask(async () => {
22144
22149
  const firstKeyPath = channelKey.split(".")[0];
22145
22150
  const res = await this.rpcClient.peekChannel(
@@ -22157,12 +22162,6 @@ class Client {
22157
22162
  * `broadcast` broadcasts the given payload to the given topic.
22158
22163
  */
22159
22164
  async broadcast(key, topic, payload, options) {
22160
- if (!this.isActive()) {
22161
- throw new YorkieError(
22162
- Code.ErrClientNotActivated,
22163
- `${this.key} is not active`
22164
- );
22165
- }
22166
22165
  const attachment = this.attachmentMap.get(key);
22167
22166
  if (!attachment) {
22168
22167
  throw new YorkieError(Code.ErrNotAttached, `${key} is not attached`);
@@ -22239,8 +22238,16 @@ class Client {
22239
22238
  */
22240
22239
  runSyncLoop() {
22241
22240
  const doLoop = async () => {
22242
- if (!this.isActive() || this.deactivating) {
22243
- logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
22241
+ if (this.deactivating) {
22242
+ logger.debug(`[SL] c:"${this.getKey()}" exit sync loop (deactivating)`);
22243
+ this.conditions[
22244
+ "SyncLoop"
22245
+ /* SyncLoop */
22246
+ ] = false;
22247
+ return;
22248
+ }
22249
+ if (!this.isActive() && this.attachmentMap.size === 0) {
22250
+ logger.debug(`[SL] c:"${this.getKey()}" exit sync loop (idle)`);
22244
22251
  this.conditions[
22245
22252
  "SyncLoop"
22246
22253
  /* SyncLoop */
@@ -22626,6 +22633,10 @@ class Client {
22626
22633
  return;
22627
22634
  }
22628
22635
  attachment.cancelWatchStream();
22636
+ if (attachment.unsubscribeLocalBroadcast) {
22637
+ attachment.unsubscribeLocalBroadcast();
22638
+ attachment.unsubscribeLocalBroadcast = void 0;
22639
+ }
22629
22640
  if (attachment.resource instanceof Document) {
22630
22641
  attachment.resource.resetOnlineClients();
22631
22642
  }
@@ -22634,12 +22645,17 @@ class Client {
22634
22645
  async syncInternal(attachment, syncMode) {
22635
22646
  const { resource } = attachment;
22636
22647
  if (resource instanceof Channel2) {
22648
+ const isFirstCall = !resource.getSessionID();
22637
22649
  try {
22638
22650
  const res = await this.rpcClient.refreshChannel(
22639
22651
  {
22640
- clientId: this.id,
22652
+ clientId: this.id ?? "",
22641
22653
  channelKey: resource.getKey(),
22642
- sessionId: resource.getSessionID()
22654
+ sessionId: resource.getSessionID() ?? "",
22655
+ // First-call only — these fields are ignored by the server
22656
+ // once a session_id is established.
22657
+ clientKey: isFirstCall ? this.key : "",
22658
+ metadata: isFirstCall ? this.metadata : {}
22643
22659
  },
22644
22660
  {
22645
22661
  headers: {
@@ -22647,6 +22663,31 @@ class Client {
22647
22663
  }
22648
22664
  }
22649
22665
  );
22666
+ if (isFirstCall) {
22667
+ if (this.deactivating || attachment.isDetaching()) {
22668
+ return resource;
22669
+ }
22670
+ if (res.clientId && !this.id) {
22671
+ this.id = res.clientId;
22672
+ this.status = "activated";
22673
+ resource.setActor(res.clientId);
22674
+ } else if (this.id) {
22675
+ resource.setActor(this.id);
22676
+ }
22677
+ if (res.sessionId) {
22678
+ resource.setSessionID(res.sessionId);
22679
+ attachment.resourceID = res.sessionId;
22680
+ resource.applyStatus(ChannelStatus.Attached);
22681
+ }
22682
+ if (attachment.syncMode === "realtime") {
22683
+ this.runWatchLoop(resource.getKey()).catch((err) => {
22684
+ logger.error(
22685
+ `[WP] c:"${this.getKey()}" failed to start watch for p:"${resource.getKey()}":`,
22686
+ err
22687
+ );
22688
+ });
22689
+ }
22690
+ }
22650
22691
  const prevCount = resource.getSessionCount();
22651
22692
  if (resource.updateSessionCount(Number(res.sessionCount), 0)) {
22652
22693
  if (resource.getSessionCount() !== prevCount) {
@@ -22661,6 +22702,21 @@ class Client {
22661
22702
  `[RP] c:"${this.getKey()}" refreshes p:"${resource.getKey()}" mode:${attachment.syncMode}`
22662
22703
  );
22663
22704
  } catch (err) {
22705
+ if (isErrorCode(err, Code.ErrSessionNotFound)) {
22706
+ logger.info(
22707
+ `[RP] c:"${this.getKey()}" session expired for p:"${resource.getKey()}", re-attaching`
22708
+ );
22709
+ resource.setSessionID("");
22710
+ attachment.resourceID = "";
22711
+ return resource;
22712
+ }
22713
+ if (!this.deactivating && !attachment.isDetaching()) {
22714
+ resource.publish({
22715
+ type: ChannelEventType.SyncError,
22716
+ error: err,
22717
+ method: "RefreshChannel"
22718
+ });
22719
+ }
22664
22720
  logger.error(`[RP] c:"${this.getKey()}" err :`, err);
22665
22721
  throw err;
22666
22722
  }