@yorkie-js/sdk 0.7.5 → 0.7.7
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.
- package/dist/yorkie-js-sdk.d.ts +48 -1
- package/dist/yorkie-js-sdk.es.js +954 -260
- package/dist/yorkie-js-sdk.es.js.map +1 -1
- package/dist/yorkie-js-sdk.js +954 -260
- package/dist/yorkie-js-sdk.js.map +1 -1
- package/package.json +2 -2
package/dist/yorkie-js-sdk.es.js
CHANGED
|
@@ -5788,7 +5788,7 @@ function createGrpcWebTransport(options) {
|
|
|
5788
5788
|
}
|
|
5789
5789
|
};
|
|
5790
5790
|
}
|
|
5791
|
-
const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50IlQKB1JHQU5vZGUSIAoEbmV4dBgBIAEoCzISLnlvcmtpZS52MS5SR0FOb2RlEicKB2VsZW1lbnQYAiABKAsyFi55b3JraWUudjEuSlNPTkVsZW1lbnQiWAoITm9kZUF0dHISDQoFdmFsdWUYASABKAkSKQoKdXBkYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EhIKCmlzX3JlbW92ZWQYAyABKAgilAIKCFRleHROb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSDQoFdmFsdWUYAiABKAkSKQoKcmVtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAQgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSNwoKYXR0cmlidXRlcxgFIAMoCzIjLnlvcmtpZS52MS5UZXh0Tm9kZS5BdHRyaWJ1dGVzRW50cnkaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiRwoKVGV4dE5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFIrMDCghUcmVlTm9kZRIhCgJpZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEgwKBHR5cGUYAiABKAkSDQoFdmFsdWUYAyABKAkSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAUgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKgoLaW5zX25leHRfaWQYBiABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBINCgVkZXB0aBgHIAEoBRI3CgphdHRyaWJ1dGVzGAggAygLMiMueW9ya2llLnYxLlRyZWVOb2RlLkF0dHJpYnV0ZXNFbnRyeRIqCgttZXJnZWRfZnJvbRgJIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEigKCW1lcmdlZF9hdBgKIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GkYKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuTm9kZUF0dHI6AjgBIjEKCVRyZWVOb2RlcxIkCgdjb250ZW50GAEgAygLMhMueW9ya2llLnYxLlRyZWVOb2RlIkcKClRyZWVOb2RlSUQSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBSJjCgdUcmVlUG9zEigKCXBhcmVudF9pZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEi4KD2xlZnRfc2libGluZ19pZBgCIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEImsKBFVzZXISCgoCaWQYASABKAkSFQoNYXV0aF9wcm92aWRlchgCIAEoCRIQCgh1c2VybmFtZRgDIAEoCRIuCgpjcmVhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKJAQoGTWVtYmVyEgoKAmlkGAEgASgJEhIKCnByb2plY3RfaWQYAiABKAkSDwoHdXNlcl9pZBgDIAEoCRIQCgh1c2VybmFtZRgEIAEoCRIMCgRyb2xlGAUgASgJEi4KCmludml0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIukGCgdQcm9qZWN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEgoKcHVibGljX2tleRgDIAEoCRISCgpzZWNyZXRfa2V5GAQgASgJEhgKEGF1dGhfd2ViaG9va191cmwYBSABKAkSHAoUYXV0aF93ZWJob29rX21ldGhvZHMYBiADKAkSIAoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGBEgASgEEiYKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgSIAEoCRImCh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYEyABKAkSJAocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgUIAEoCRIZChFldmVudF93ZWJob29rX3VybBgHIAEoCRIcChRldmVudF93ZWJob29rX2V2ZW50cxgIIAMoCRIhChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBUgASgEEicKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYFiABKAkSJwofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgXIAEoCRIlCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgYIAEoCRIjChtjbGllbnRfZGVhY3RpdmF0ZV90aHJlc2hvbGQYCSABKAkSGgoSc25hcHNob3RfdGhyZXNob2xkGBkgASgDEhkKEXNuYXBzaG90X2ludGVydmFsGBogASgDEiQKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYCiABKAUSJAocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgLIAEoBRIdChVtYXhfc2l6ZV9wZXJfZG9jdW1lbnQYDyABKAUSGAoQcmVtb3ZlX29uX2RldGFjaBgQIAEoCBIdChVhdXRvX3JldmlzaW9uX2VuYWJsZWQYGyABKAgSFwoPYWxsb3dlZF9vcmlnaW5zGA4gAygJEi4KCmNyZWF0ZWRfYXQYDCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIi8KC01ldHJpY1BvaW50EhEKCXRpbWVzdGFtcBgBIAEoAxINCgV2YWx1ZRgCIAEoBSKjDAoWVXBkYXRhYmxlUHJvamVjdEZpZWxkcxIqCgRuYW1lGAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjYKEGF1dGhfd2ViaG9va191cmwYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSUgoUYXV0aF93ZWJob29rX21ldGhvZHMYAyABKAsyNC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BdXRoV2ViaG9va01ldGhvZHMSPgoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGAwgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkQKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgNIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJECh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYDiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSQgocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgPIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChFldmVudF93ZWJob29rX3VybBgEIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRldmVudF93ZWJob29rX2V2ZW50cxgFIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkV2ZW50V2ViaG9va0V2ZW50cxI/ChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBAgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkUKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSRQofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgSIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJDCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgTIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChJzbmFwc2hvdF90aHJlc2hvbGQYFCABKAsyGy5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZRI2ChFzbmFwc2hvdF9pbnRlcnZhbBgVIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEkEKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgGIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJBChxtYXhfc3Vic2NyaWJlcnNfcGVyX2RvY3VtZW50GAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSQQocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgIIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjoKFW1heF9zaXplX3Blcl9kb2N1bWVudBgKIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjQKEHJlbW92ZV9vbl9kZXRhY2gYCyABKAsyGi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlEjkKFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgWIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSSQoPYWxsb3dlZF9vcmlnaW5zGAkgASgLMjAueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuQWxsb3dlZE9yaWdpbnMaJQoSQXV0aFdlYmhvb2tNZXRob2RzEg8KB21ldGhvZHMYASADKAkaJAoSRXZlbnRXZWJob29rRXZlbnRzEg4KBmV2ZW50cxgBIAMoCRohCg5BbGxvd2VkT3JpZ2lucxIPCgdvcmlnaW5zGAEgAygJIqcDCg9Eb2N1bWVudFN1bW1hcnkSCgoCaWQYASABKAkSCwoDa2V5GAIgASgJEgwKBHJvb3QYAyABKAkSGAoQYXR0YWNoZWRfY2xpZW50cxgHIAEoBRIpCg1kb2N1bWVudF9zaXplGAggASgLMhIueW9ya2llLnYxLkRvY1NpemUSEgoKc2NoZW1hX2tleRgJIAEoCRI8CglwcmVzZW5jZXMYCiADKAsyKS55b3JraWUudjEuRG9jdW1lbnRTdW1tYXJ5LlByZXNlbmNlc0VudHJ5Ei4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC2FjY2Vzc2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgp1cGRhdGVkX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBpFCg5QcmVzZW5jZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2U6AjgBItoBCg5QcmVzZW5jZUNoYW5nZRIyCgR0eXBlGAEgASgOMiQueW9ya2llLnYxLlByZXNlbmNlQ2hhbmdlLkNoYW5nZVR5cGUSJQoIcHJlc2VuY2UYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2UibQoKQ2hhbmdlVHlwZRIbChdDSEFOR0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD0NIQU5HRV9UWVBFX1BVVBABEhYKEkNIQU5HRV9UWVBFX0RFTEVURRACEhUKEUNIQU5HRV9UWVBFX0NMRUFSEAMiZAoIUHJlc2VuY2USKwoEZGF0YRgBIAMoCzIdLnlvcmtpZS52MS5QcmVzZW5jZS5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiNAoOQ2hhbm5lbFN1bW1hcnkSCwoDa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAUiNAoKQ2hlY2twb2ludBISCgpzZXJ2ZXJfc2VxGAEgASgDEhIKCmNsaWVudF9zZXEYAiABKA0iYQoLVGV4dE5vZGVQb3MSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBRIXCg9yZWxhdGl2ZV9vZmZzZXQYAyABKAUiQgoKVGltZVRpY2tldBIPCgdsYW1wb3J0GAEgASgDEhEKCWRlbGltaXRlchgCIAEoDRIQCghhY3Rvcl9pZBgDIAEoDCIuCgxEb2NFdmVudEJvZHkSDQoFdG9waWMYASABKAkSDwoHcGF5bG9hZBgCIAEoDCJrCghEb2NFdmVudBIlCgR0eXBlGAEgASgOMhcueW9ya2llLnYxLkRvY0V2ZW50VHlwZRIRCglwdWJsaXNoZXIYAiABKAkSJQoEYm9keRgDIAEoCzIXLnlvcmtpZS52MS5Eb2NFdmVudEJvZHki1gEKDENoYW5uZWxFdmVudBIqCgR0eXBlGAEgASgOMhwueW9ya2llLnYxLkNoYW5uZWxFdmVudC5UeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIVCg1zZXNzaW9uX2NvdW50GAMgASgDEgsKA3NlcRgEIAEoAxINCgV0b3BpYxgFIAEoCRIPCgdwYXlsb2FkGAYgASgMIkMKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhEKDVRZUEVfUFJFU0VOQ0UQARISCg5UWVBFX0JST0FEQ0FTVBACIiYKCERhdGFTaXplEgwKBGRhdGEYASABKAUSDAoEbWV0YRgCIAEoBSJNCgdEb2NTaXplEiEKBGxpdmUYASABKAsyEy55b3JraWUudjEuRGF0YVNpemUSHwoCZ2MYAiABKAsyEy55b3JraWUudjEuRGF0YVNpemUikQEKBlNjaGVtYRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAUSDAoEYm9keRgEIAEoCRIeCgVydWxlcxgFIAMoCzIPLnlvcmtpZS52MS5SdWxlEi4KCmNyZWF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIlAKDFRyZWVOb2RlUnVsZRIRCglub2RlX3R5cGUYASABKAkSDwoHY29udGVudBgCIAEoCRINCgVtYXJrcxgDIAEoCRINCgVncm91cBgEIAEoCSJPCgRSdWxlEgwKBHBhdGgYASABKAkSDAoEdHlwZRgCIAEoCRIrCgp0cmVlX25vZGVzGAMgAygLMhcueW9ya2llLnYxLlRyZWVOb2RlUnVsZSKDAQoPUmV2aXNpb25TdW1tYXJ5EgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhAKCHNuYXBzaG90GAQgASgJEi4KCmNyZWF0ZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKvwCCglWYWx1ZVR5cGUSEwoPVkFMVUVfVFlQRV9OVUxMEAASFgoSVkFMVUVfVFlQRV9CT09MRUFOEAESFgoSVkFMVUVfVFlQRV9JTlRFR0VSEAISEwoPVkFMVUVfVFlQRV9MT05HEAMSFQoRVkFMVUVfVFlQRV9ET1VCTEUQBBIVChFWQUxVRV9UWVBFX1NUUklORxAFEhQKEFZBTFVFX1RZUEVfQllURVMQBhITCg9WQUxVRV9UWVBFX0RBVEUQBxIaChZWQUxVRV9UWVBFX0pTT05fT0JKRUNUEAgSGQoVVkFMVUVfVFlQRV9KU09OX0FSUkFZEAkSEwoPVkFMVUVfVFlQRV9URVhUEAoSGgoWVkFMVUVfVFlQRV9JTlRFR0VSX0NOVBALEhcKE1ZBTFVFX1RZUEVfTE9OR19DTlQQDBITCg9WQUxVRV9UWVBFX1RSRUUQDRIgChxWQUxVRV9UWVBFX0lOVEVHRVJfREVEVVBfQ05UEA4iBAgPEA8qpgEKDERvY0V2ZW50VHlwZRIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9DSEFOR0VEEAASIwofRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfV0FUQ0hFRBABEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX1VOV0FUQ0hFRBACEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0JST0FEQ0FTVBADQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
|
|
5791
|
+
const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50Iu4BCgdSR0FOb2RlEiAKBG5leHQYASABKAsyEi55b3JraWUudjEuUkdBTm9kZRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50EjIKE3Bvc2l0aW9uX2NyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIwChFwb3NpdGlvbl9tb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EjIKE3Bvc2l0aW9uX3JlbW92ZWRfYXQYBSABKAsyFS55b3JraWUudjEuVGltZVRpY2tldCJYCghOb2RlQXR0chINCgV2YWx1ZRgBIAEoCRIpCgp1cGRhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgDIAEoCCKUAgoIVGV4dE5vZGUSIQoCaWQYASABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBINCgV2YWx1ZRgCIAEoCRIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBCABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBI3CgphdHRyaWJ1dGVzGAUgAygLMiMueW9ya2llLnYxLlRleHROb2RlLkF0dHJpYnV0ZXNFbnRyeRpGCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLk5vZGVBdHRyOgI4ASJHCgpUZXh0Tm9kZUlEEikKCmNyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIOCgZvZmZzZXQYAiABKAUiswMKCFRyZWVOb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSDAoEdHlwZRgCIAEoCRINCgV2YWx1ZRgDIAEoCRIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBSABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBIqCgtpbnNfbmV4dF9pZBgGIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEg0KBWRlcHRoGAcgASgFEjcKCmF0dHJpYnV0ZXMYCCADKAsyIy55b3JraWUudjEuVHJlZU5vZGUuQXR0cmlidXRlc0VudHJ5EioKC21lcmdlZF9mcm9tGAkgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKAoJbWVyZ2VkX2F0GAogASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiMQoJVHJlZU5vZGVzEiQKB2NvbnRlbnQYASADKAsyEy55b3JraWUudjEuVHJlZU5vZGUiRwoKVHJlZU5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFImMKB1RyZWVQb3MSKAoJcGFyZW50X2lkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSLgoPbGVmdF9zaWJsaW5nX2lkGAIgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQiawoEVXNlchIKCgJpZBgBIAEoCRIVCg1hdXRoX3Byb3ZpZGVyGAIgASgJEhAKCHVzZXJuYW1lGAMgASgJEi4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIokBCgZNZW1iZXISCgoCaWQYASABKAkSEgoKcHJvamVjdF9pZBgCIAEoCRIPCgd1c2VyX2lkGAMgASgJEhAKCHVzZXJuYW1lGAQgASgJEgwKBHJvbGUYBSABKAkSLgoKaW52aXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAi6QYKB1Byb2plY3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRISCgpwdWJsaWNfa2V5GAMgASgJEhIKCnNlY3JldF9rZXkYBCABKAkSGAoQYXV0aF93ZWJob29rX3VybBgFIAEoCRIcChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgGIAMoCRIgChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYESABKAQSJgoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGBIgASgJEiYKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgTIAEoCRIkChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBQgASgJEhkKEWV2ZW50X3dlYmhvb2tfdXJsGAcgASgJEhwKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAggAygJEiEKGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYFSABKAQSJwofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgWIAEoCRInCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBcgASgJEiUKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBggASgJEiMKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgJIAEoCRIaChJzbmFwc2hvdF90aHJlc2hvbGQYGSABKAMSGQoRc25hcHNob3RfaW50ZXJ2YWwYGiABKAMSJAocbWF4X3N1YnNjcmliZXJzX3Blcl9kb2N1bWVudBgKIAEoBRIkChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAsgASgFEh0KFW1heF9zaXplX3Blcl9kb2N1bWVudBgPIAEoBRIYChByZW1vdmVfb25fZGV0YWNoGBAgASgIEh0KFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgbIAEoCBIXCg9hbGxvd2VkX29yaWdpbnMYDiADKAkSLgoKY3JlYXRlZF9hdBgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLwoLTWV0cmljUG9pbnQSEQoJdGltZXN0YW1wGAEgASgDEg0KBXZhbHVlGAIgASgFIqMMChZVcGRhdGFibGVQcm9qZWN0RmllbGRzEioKBG5hbWUYASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSNgoQYXV0aF93ZWJob29rX3VybBgCIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgDIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkF1dGhXZWJob29rTWV0aG9kcxI+ChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYDCABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRAoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGA0gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkQKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgOIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJCChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GA8gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEWV2ZW50X3dlYmhvb2tfdXJsGAQgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlElIKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAUgASgLMjQueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuRXZlbnRXZWJob29rRXZlbnRzEj8KGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYECABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRQofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgRIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJFCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBIgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkMKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBMgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEnNuYXBzaG90X3RocmVzaG9sZBgUIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEjYKEXNuYXBzaG90X2ludGVydmFsGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSQQobY2xpZW50X2RlYWN0aXZhdGVfdGhyZXNob2xkGAYgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkEKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYByABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRJBChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAggASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSOgoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAogASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSNAoQcmVtb3ZlX29uX2RldGFjaBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSOQoVYXV0b19yZXZpc2lvbl9lbmFibGVkGBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRJJCg9hbGxvd2VkX29yaWdpbnMYCSABKAsyMC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BbGxvd2VkT3JpZ2lucxolChJBdXRoV2ViaG9va01ldGhvZHMSDwoHbWV0aG9kcxgBIAMoCRokChJFdmVudFdlYmhvb2tFdmVudHMSDgoGZXZlbnRzGAEgAygJGiEKDkFsbG93ZWRPcmlnaW5zEg8KB29yaWdpbnMYASADKAkipwMKD0RvY3VtZW50U3VtbWFyeRIKCgJpZBgBIAEoCRILCgNrZXkYAiABKAkSDAoEcm9vdBgDIAEoCRIYChBhdHRhY2hlZF9jbGllbnRzGAcgASgFEikKDWRvY3VtZW50X3NpemUYCCABKAsyEi55b3JraWUudjEuRG9jU2l6ZRISCgpzY2hlbWFfa2V5GAkgASgJEjwKCXByZXNlbmNlcxgKIAMoCzIpLnlvcmtpZS52MS5Eb2N1bWVudFN1bW1hcnkuUHJlc2VuY2VzRW50cnkSLgoKY3JlYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLYWNjZXNzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGkUKDlByZXNlbmNlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZToCOAEi2gEKDlByZXNlbmNlQ2hhbmdlEjIKBHR5cGUYASABKA4yJC55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UuQ2hhbmdlVHlwZRIlCghwcmVzZW5jZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZSJtCgpDaGFuZ2VUeXBlEhsKF0NIQU5HRV9UWVBFX1VOU1BFQ0lGSUVEEAASEwoPQ0hBTkdFX1RZUEVfUFVUEAESFgoSQ0hBTkdFX1RZUEVfREVMRVRFEAISFQoRQ0hBTkdFX1RZUEVfQ0xFQVIQAyJkCghQcmVzZW5jZRIrCgRkYXRhGAEgAygLMh0ueW9ya2llLnYxLlByZXNlbmNlLkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASI0Cg5DaGFubmVsU3VtbWFyeRILCgNrZXkYASABKAkSFQoNc2Vzc2lvbl9jb3VudBgCIAEoBSI0CgpDaGVja3BvaW50EhIKCnNlcnZlcl9zZXEYASABKAMSEgoKY2xpZW50X3NlcRgCIAEoDSJhCgtUZXh0Tm9kZVBvcxIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFEhcKD3JlbGF0aXZlX29mZnNldBgDIAEoBSJCCgpUaW1lVGlja2V0Eg8KB2xhbXBvcnQYASABKAMSEQoJZGVsaW1pdGVyGAIgASgNEhAKCGFjdG9yX2lkGAMgASgMIi4KDERvY0V2ZW50Qm9keRINCgV0b3BpYxgBIAEoCRIPCgdwYXlsb2FkGAIgASgMImsKCERvY0V2ZW50EiUKBHR5cGUYASABKA4yFy55b3JraWUudjEuRG9jRXZlbnRUeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIlCgRib2R5GAMgASgLMhcueW9ya2llLnYxLkRvY0V2ZW50Qm9keSLWAQoMQ2hhbm5lbEV2ZW50EioKBHR5cGUYASABKA4yHC55b3JraWUudjEuQ2hhbm5lbEV2ZW50LlR5cGUSEQoJcHVibGlzaGVyGAIgASgJEhUKDXNlc3Npb25fY291bnQYAyABKAMSCwoDc2VxGAQgASgDEg0KBXRvcGljGAUgASgJEg8KB3BheWxvYWQYBiABKAwiQwoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASEQoNVFlQRV9QUkVTRU5DRRABEhIKDlRZUEVfQlJPQURDQVNUEAIiJgoIRGF0YVNpemUSDAoEZGF0YRgBIAEoBRIMCgRtZXRhGAIgASgFIk0KB0RvY1NpemUSIQoEbGl2ZRgBIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZRIfCgJnYxgCIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZSKRAQoGU2NoZW1hEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoBRIMCgRib2R5GAQgASgJEh4KBXJ1bGVzGAUgAygLMg8ueW9ya2llLnYxLlJ1bGUSLgoKY3JlYXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiUAoMVHJlZU5vZGVSdWxlEhEKCW5vZGVfdHlwZRgBIAEoCRIPCgdjb250ZW50GAIgASgJEg0KBW1hcmtzGAMgASgJEg0KBWdyb3VwGAQgASgJIk8KBFJ1bGUSDAoEcGF0aBgBIAEoCRIMCgR0eXBlGAIgASgJEisKCnRyZWVfbm9kZXMYAyADKAsyFy55b3JraWUudjEuVHJlZU5vZGVSdWxlIoMBCg9SZXZpc2lvblN1bW1hcnkSCgoCaWQYASABKAkSDQoFbGFiZWwYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSEAoIc25hcHNob3QYBCABKAkSLgoKY3JlYXRlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAq/AIKCVZhbHVlVHlwZRITCg9WQUxVRV9UWVBFX05VTEwQABIWChJWQUxVRV9UWVBFX0JPT0xFQU4QARIWChJWQUxVRV9UWVBFX0lOVEVHRVIQAhITCg9WQUxVRV9UWVBFX0xPTkcQAxIVChFWQUxVRV9UWVBFX0RPVUJMRRAEEhUKEVZBTFVFX1RZUEVfU1RSSU5HEAUSFAoQVkFMVUVfVFlQRV9CWVRFUxAGEhMKD1ZBTFVFX1RZUEVfREFURRAHEhoKFlZBTFVFX1RZUEVfSlNPTl9PQkpFQ1QQCBIZChVWQUxVRV9UWVBFX0pTT05fQVJSQVkQCRITCg9WQUxVRV9UWVBFX1RFWFQQChIaChZWQUxVRV9UWVBFX0lOVEVHRVJfQ05UEAsSFwoTVkFMVUVfVFlQRV9MT05HX0NOVBAMEhMKD1ZBTFVFX1RZUEVfVFJFRRANEiAKHFZBTFVFX1RZUEVfSU5URUdFUl9ERURVUF9DTlQQDiIECA8QDyqmAQoMRG9jRXZlbnRUeXBlEiMKH0RPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0NIQU5HRUQQABIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9XQVRDSEVEEAESJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfVU5XQVRDSEVEEAISJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfQlJPQURDQVNUEANCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
|
|
5792
5792
|
const SnapshotSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 0);
|
|
5793
5793
|
const ChangePackSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 1);
|
|
5794
5794
|
const ChangeSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 2);
|
|
@@ -7137,6 +7137,13 @@ class Primitive extends CRDTElement {
|
|
|
7137
7137
|
if (this.valueType === 5) {
|
|
7138
7138
|
return `"${escapeString(this.value)}"`;
|
|
7139
7139
|
}
|
|
7140
|
+
if (this.valueType === 6) {
|
|
7141
|
+
const bytes = this.value;
|
|
7142
|
+
return `"${btoa(String.fromCharCode(...bytes))}"`;
|
|
7143
|
+
}
|
|
7144
|
+
if (this.valueType === 7) {
|
|
7145
|
+
return `"${this.value.toISOString()}"`;
|
|
7146
|
+
}
|
|
7140
7147
|
return `${this.value}`;
|
|
7141
7148
|
}
|
|
7142
7149
|
/**
|
|
@@ -7279,19 +7286,54 @@ class Primitive extends CRDTElement {
|
|
|
7279
7286
|
}
|
|
7280
7287
|
}
|
|
7281
7288
|
}
|
|
7289
|
+
class ElementEntry {
|
|
7290
|
+
elem;
|
|
7291
|
+
positionNode;
|
|
7292
|
+
posMovedAt;
|
|
7293
|
+
constructor(elem) {
|
|
7294
|
+
this.elem = elem;
|
|
7295
|
+
}
|
|
7296
|
+
}
|
|
7282
7297
|
class RGATreeListNode extends SplayNode {
|
|
7298
|
+
_elementEntry;
|
|
7299
|
+
_createdAt;
|
|
7300
|
+
_removedAt;
|
|
7283
7301
|
prev;
|
|
7284
7302
|
next;
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7303
|
+
constructor(elem, createdAt) {
|
|
7304
|
+
super(elem);
|
|
7305
|
+
this._createdAt = createdAt;
|
|
7306
|
+
}
|
|
7307
|
+
/**
|
|
7308
|
+
* `createWithElement` creates a new node that owns an element.
|
|
7309
|
+
*/
|
|
7310
|
+
static createWithElement(elem) {
|
|
7311
|
+
const entry = new ElementEntry(elem);
|
|
7312
|
+
const node = new RGATreeListNode(elem, elem.getCreatedAt());
|
|
7313
|
+
entry.positionNode = node;
|
|
7314
|
+
node._elementEntry = entry;
|
|
7315
|
+
return node;
|
|
7316
|
+
}
|
|
7317
|
+
/**
|
|
7318
|
+
* `createBarePosition` creates a position node without an element
|
|
7319
|
+
* (used for move).
|
|
7320
|
+
*/
|
|
7321
|
+
static createBarePosition(createdAt) {
|
|
7322
|
+
return new RGATreeListNode(void 0, createdAt);
|
|
7289
7323
|
}
|
|
7290
7324
|
/**
|
|
7291
|
-
* `createAfter` creates a new node
|
|
7325
|
+
* `createAfter` creates a new node with the given element after
|
|
7326
|
+
* the given prev node.
|
|
7292
7327
|
*/
|
|
7293
|
-
static createAfter(prev,
|
|
7294
|
-
const newNode =
|
|
7328
|
+
static createAfter(prev, elem) {
|
|
7329
|
+
const newNode = RGATreeListNode.createWithElement(elem);
|
|
7330
|
+
RGATreeListNode.insertNodeAfter(prev, newNode);
|
|
7331
|
+
return newNode;
|
|
7332
|
+
}
|
|
7333
|
+
/**
|
|
7334
|
+
* `insertNodeAfter` inserts a node after the given prev node.
|
|
7335
|
+
*/
|
|
7336
|
+
static insertNodeAfter(prev, newNode) {
|
|
7295
7337
|
const prevNext = prev.next;
|
|
7296
7338
|
prev.next = newNode;
|
|
7297
7339
|
newNode.prev = prev;
|
|
@@ -7299,26 +7341,41 @@ class RGATreeListNode extends SplayNode {
|
|
|
7299
7341
|
if (prevNext) {
|
|
7300
7342
|
prevNext.prev = newNode;
|
|
7301
7343
|
}
|
|
7302
|
-
return newNode;
|
|
7303
7344
|
}
|
|
7304
7345
|
/**
|
|
7305
|
-
* `remove` removes
|
|
7346
|
+
* `remove` removes the element based on removing time.
|
|
7306
7347
|
*/
|
|
7307
7348
|
remove(removedAt) {
|
|
7308
|
-
|
|
7349
|
+
if (!this._elementEntry) {
|
|
7350
|
+
return false;
|
|
7351
|
+
}
|
|
7352
|
+
return this._elementEntry.elem.remove(removedAt);
|
|
7309
7353
|
}
|
|
7310
7354
|
/**
|
|
7311
|
-
* `getCreatedAt` returns creation time
|
|
7355
|
+
* `getCreatedAt` returns the creation time. For live nodes with
|
|
7356
|
+
* elements, returns the element's createdAt for backward
|
|
7357
|
+
* compatibility.
|
|
7312
7358
|
*/
|
|
7313
7359
|
getCreatedAt() {
|
|
7314
|
-
|
|
7360
|
+
if (this._elementEntry) {
|
|
7361
|
+
return this._elementEntry.elem.getCreatedAt();
|
|
7362
|
+
}
|
|
7363
|
+
return this._createdAt;
|
|
7315
7364
|
}
|
|
7316
7365
|
/**
|
|
7317
|
-
* `getPositionedAt` returns the time
|
|
7318
|
-
*
|
|
7366
|
+
* `getPositionedAt` returns the time this element was positioned.
|
|
7367
|
+
* For live nodes, the position register (posMovedAt) is the source
|
|
7368
|
+
* of truth. For dead nodes (no element), the position node's own
|
|
7369
|
+
* createdAt is used.
|
|
7319
7370
|
*/
|
|
7320
7371
|
getPositionedAt() {
|
|
7321
|
-
|
|
7372
|
+
if (this._elementEntry) {
|
|
7373
|
+
if (this._elementEntry.posMovedAt) {
|
|
7374
|
+
return this._elementEntry.posMovedAt;
|
|
7375
|
+
}
|
|
7376
|
+
return this._elementEntry.elem.getCreatedAt();
|
|
7377
|
+
}
|
|
7378
|
+
return this._createdAt;
|
|
7322
7379
|
}
|
|
7323
7380
|
/**
|
|
7324
7381
|
* `release` releases prev and next node.
|
|
@@ -7335,9 +7392,13 @@ class RGATreeListNode extends SplayNode {
|
|
|
7335
7392
|
}
|
|
7336
7393
|
/**
|
|
7337
7394
|
* `getLength` returns the length of this node.
|
|
7395
|
+
* Dead nodes (no element) return 0, removed elements return 0.
|
|
7338
7396
|
*/
|
|
7339
7397
|
getLength() {
|
|
7340
|
-
|
|
7398
|
+
if (!this._elementEntry || this.isRemoved()) {
|
|
7399
|
+
return 0;
|
|
7400
|
+
}
|
|
7401
|
+
return 1;
|
|
7341
7402
|
}
|
|
7342
7403
|
/**
|
|
7343
7404
|
* `getPrev` returns a previous node.
|
|
@@ -7352,28 +7413,87 @@ class RGATreeListNode extends SplayNode {
|
|
|
7352
7413
|
return this.next;
|
|
7353
7414
|
}
|
|
7354
7415
|
/**
|
|
7355
|
-
* `
|
|
7416
|
+
* `getValue` returns the element value.
|
|
7356
7417
|
*/
|
|
7357
|
-
|
|
7358
|
-
|
|
7418
|
+
getValue() {
|
|
7419
|
+
if (!this._elementEntry) {
|
|
7420
|
+
return this.value;
|
|
7421
|
+
}
|
|
7422
|
+
return this._elementEntry.elem;
|
|
7359
7423
|
}
|
|
7360
7424
|
/**
|
|
7361
|
-
* `
|
|
7425
|
+
* `getElement` returns the element or undefined if dead position.
|
|
7362
7426
|
*/
|
|
7363
|
-
|
|
7364
|
-
this.
|
|
7427
|
+
getElement() {
|
|
7428
|
+
return this._elementEntry?.elem;
|
|
7365
7429
|
}
|
|
7366
7430
|
/**
|
|
7367
|
-
* `
|
|
7431
|
+
* `isRemoved` checks if the value was removed.
|
|
7368
7432
|
*/
|
|
7369
|
-
|
|
7370
|
-
|
|
7433
|
+
isRemoved() {
|
|
7434
|
+
if (!this._elementEntry) {
|
|
7435
|
+
return true;
|
|
7436
|
+
}
|
|
7437
|
+
return this._elementEntry.elem.isRemoved();
|
|
7371
7438
|
}
|
|
7372
7439
|
/**
|
|
7373
|
-
* `
|
|
7440
|
+
* `getElementEntry` returns the element entry.
|
|
7374
7441
|
*/
|
|
7375
|
-
|
|
7376
|
-
return this.
|
|
7442
|
+
getElementEntry() {
|
|
7443
|
+
return this._elementEntry;
|
|
7444
|
+
}
|
|
7445
|
+
/**
|
|
7446
|
+
* `setElementEntry` sets the element entry.
|
|
7447
|
+
*/
|
|
7448
|
+
setElementEntry(entry) {
|
|
7449
|
+
this._elementEntry = entry;
|
|
7450
|
+
}
|
|
7451
|
+
/**
|
|
7452
|
+
* `getPositionCreatedAt` returns the position node's own createdAt.
|
|
7453
|
+
*/
|
|
7454
|
+
getPositionCreatedAt() {
|
|
7455
|
+
return this._createdAt;
|
|
7456
|
+
}
|
|
7457
|
+
/**
|
|
7458
|
+
* `getPositionMovedAt` returns the LWW timestamp of the element's
|
|
7459
|
+
* move into this position. Undefined for insert-created positions.
|
|
7460
|
+
*/
|
|
7461
|
+
getPositionMovedAt() {
|
|
7462
|
+
if (!this._elementEntry) {
|
|
7463
|
+
return void 0;
|
|
7464
|
+
}
|
|
7465
|
+
return this._elementEntry.posMovedAt;
|
|
7466
|
+
}
|
|
7467
|
+
/**
|
|
7468
|
+
* `getRemovedAt` returns the time this dead position node was
|
|
7469
|
+
* removed (for GC).
|
|
7470
|
+
*/
|
|
7471
|
+
getRemovedAt() {
|
|
7472
|
+
return this._removedAt;
|
|
7473
|
+
}
|
|
7474
|
+
/**
|
|
7475
|
+
* `setRemovedAt` sets the removal time of this position node.
|
|
7476
|
+
*/
|
|
7477
|
+
setRemovedAt(removedAt) {
|
|
7478
|
+
this._removedAt = removedAt;
|
|
7479
|
+
}
|
|
7480
|
+
/**
|
|
7481
|
+
* `toIDString` returns a unique identifier for this position node
|
|
7482
|
+
* (for GC).
|
|
7483
|
+
*/
|
|
7484
|
+
toIDString() {
|
|
7485
|
+
return this._createdAt.toIDString();
|
|
7486
|
+
}
|
|
7487
|
+
/**
|
|
7488
|
+
* `getDataSize` returns the data size of this position node
|
|
7489
|
+
* (for GC).
|
|
7490
|
+
*/
|
|
7491
|
+
getDataSize() {
|
|
7492
|
+
let meta = TimeTicketSize;
|
|
7493
|
+
if (this._removedAt) {
|
|
7494
|
+
meta += TimeTicketSize;
|
|
7495
|
+
}
|
|
7496
|
+
return { data: 0, meta };
|
|
7377
7497
|
}
|
|
7378
7498
|
}
|
|
7379
7499
|
class RGATreeList {
|
|
@@ -7381,13 +7501,15 @@ class RGATreeList {
|
|
|
7381
7501
|
last;
|
|
7382
7502
|
nodeMapByIndex;
|
|
7383
7503
|
nodeMapByCreatedAt;
|
|
7504
|
+
elementMapByCreatedAt;
|
|
7384
7505
|
constructor() {
|
|
7385
7506
|
const dummyValue = Primitive.of(0, InitialTimeTicket);
|
|
7386
7507
|
dummyValue.setRemovedAt(InitialTimeTicket);
|
|
7387
|
-
this.dummyHead =
|
|
7508
|
+
this.dummyHead = RGATreeListNode.createWithElement(dummyValue);
|
|
7388
7509
|
this.last = this.dummyHead;
|
|
7389
7510
|
this.nodeMapByIndex = new SplayTree();
|
|
7390
7511
|
this.nodeMapByCreatedAt = /* @__PURE__ */ new Map();
|
|
7512
|
+
this.elementMapByCreatedAt = /* @__PURE__ */ new Map();
|
|
7391
7513
|
this.nodeMapByIndex.insert(this.dummyHead);
|
|
7392
7514
|
this.nodeMapByCreatedAt.set(
|
|
7393
7515
|
this.dummyHead.getCreatedAt().toIDString(),
|
|
@@ -7407,22 +7529,10 @@ class RGATreeList {
|
|
|
7407
7529
|
return this.nodeMapByIndex.length;
|
|
7408
7530
|
}
|
|
7409
7531
|
/**
|
|
7410
|
-
* `findNextBeforeExecutedAt`
|
|
7411
|
-
*
|
|
7412
|
-
* given node and returns the next node.
|
|
7413
|
-
* @returns the next node of the given createdAt and executedAt
|
|
7532
|
+
* `findNextBeforeExecutedAt` walks forward from the given node,
|
|
7533
|
+
* skipping nodes positioned after executedAt (RGA insertion rule).
|
|
7414
7534
|
*/
|
|
7415
|
-
findNextBeforeExecutedAt(
|
|
7416
|
-
let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
|
|
7417
|
-
if (!node) {
|
|
7418
|
-
throw new YorkieError(
|
|
7419
|
-
Code.ErrInvalidArgument,
|
|
7420
|
-
`cant find the given node: ${createdAt.toIDString()}`
|
|
7421
|
-
);
|
|
7422
|
-
}
|
|
7423
|
-
while (node.getValue().getMovedAt() && node.getValue().getMovedAt().after(executedAt) && node.getMovedFrom()) {
|
|
7424
|
-
node = node.getMovedFrom();
|
|
7425
|
-
}
|
|
7535
|
+
findNextBeforeExecutedAt(node, executedAt) {
|
|
7426
7536
|
while (node.getNext() && node.getNext().getPositionedAt().after(executedAt)) {
|
|
7427
7537
|
node = node.getNext();
|
|
7428
7538
|
}
|
|
@@ -7434,65 +7544,103 @@ class RGATreeList {
|
|
|
7434
7544
|
}
|
|
7435
7545
|
node.release();
|
|
7436
7546
|
this.nodeMapByIndex.delete(node);
|
|
7437
|
-
this.nodeMapByCreatedAt.delete(node.
|
|
7547
|
+
this.nodeMapByCreatedAt.delete(node.getPositionCreatedAt().toIDString());
|
|
7438
7548
|
}
|
|
7439
7549
|
/**
|
|
7440
|
-
* `insertAfter` adds a new node with the value after the given
|
|
7550
|
+
* `insertAfter` adds a new node with the value after the given
|
|
7551
|
+
* position. prevCreatedAt is a position node identity. Looks up
|
|
7552
|
+
* nodeMapByCreatedAt first, then elementMapByCreatedAt for backward
|
|
7553
|
+
* compatibility.
|
|
7441
7554
|
*/
|
|
7442
7555
|
insertAfter(prevCreatedAt, value, executedAt = value.getCreatedAt()) {
|
|
7443
|
-
|
|
7556
|
+
let startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
|
|
7557
|
+
if (!startNode) {
|
|
7558
|
+
const entry = this.elementMapByCreatedAt.get(prevCreatedAt.toIDString());
|
|
7559
|
+
if (entry) {
|
|
7560
|
+
startNode = entry.positionNode;
|
|
7561
|
+
}
|
|
7562
|
+
}
|
|
7563
|
+
if (!startNode) {
|
|
7564
|
+
throw new YorkieError(
|
|
7565
|
+
Code.ErrInvalidArgument,
|
|
7566
|
+
`cant find the given node: ${prevCreatedAt.toIDString()}`
|
|
7567
|
+
);
|
|
7568
|
+
}
|
|
7569
|
+
const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
|
|
7444
7570
|
const newNode = RGATreeListNode.createAfter(prevNode, value);
|
|
7445
7571
|
if (prevNode === this.last) {
|
|
7446
7572
|
this.last = newNode;
|
|
7447
7573
|
}
|
|
7448
7574
|
this.nodeMapByIndex.insertAfter(prevNode, newNode);
|
|
7449
|
-
this.nodeMapByCreatedAt.set(
|
|
7575
|
+
this.nodeMapByCreatedAt.set(value.getCreatedAt().toIDString(), newNode);
|
|
7576
|
+
this.elementMapByCreatedAt.set(
|
|
7577
|
+
value.getCreatedAt().toIDString(),
|
|
7578
|
+
newNode.getElementEntry()
|
|
7579
|
+
);
|
|
7450
7580
|
return newNode;
|
|
7451
7581
|
}
|
|
7452
7582
|
/**
|
|
7453
|
-
* `
|
|
7454
|
-
*
|
|
7583
|
+
* `insertPositionAfter` creates a bare position node after
|
|
7584
|
+
* resolving position via forward skip (RGA insertion rule).
|
|
7585
|
+
* Used by moveAfter. prevCreatedAt is a POSITION node identity.
|
|
7586
|
+
*/
|
|
7587
|
+
insertPositionAfter(prevCreatedAt, executedAt) {
|
|
7588
|
+
const startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
|
|
7589
|
+
if (!startNode) {
|
|
7590
|
+
throw new YorkieError(
|
|
7591
|
+
Code.ErrInvalidArgument,
|
|
7592
|
+
`cant find the given node: ${prevCreatedAt.toIDString()}`
|
|
7593
|
+
);
|
|
7594
|
+
}
|
|
7595
|
+
const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
|
|
7596
|
+
const newNode = RGATreeListNode.createBarePosition(executedAt);
|
|
7597
|
+
RGATreeListNode.insertNodeAfter(prevNode, newNode);
|
|
7598
|
+
if (prevNode === this.last) {
|
|
7599
|
+
this.last = newNode;
|
|
7600
|
+
}
|
|
7601
|
+
this.nodeMapByIndex.insertAfter(prevNode, newNode);
|
|
7602
|
+
this.nodeMapByCreatedAt.set(executedAt.toIDString(), newNode);
|
|
7603
|
+
return newNode;
|
|
7604
|
+
}
|
|
7605
|
+
/**
|
|
7606
|
+
* `moveAfter` moves the given `createdAt` element after the
|
|
7607
|
+
* `prevCreatedAt` element using LWW position register semantics.
|
|
7608
|
+
* Returns the dead position node (if any) for GC registration.
|
|
7455
7609
|
*/
|
|
7456
7610
|
moveAfter(prevCreatedAt, createdAt, executedAt) {
|
|
7457
|
-
|
|
7458
|
-
if (!prevNode) {
|
|
7611
|
+
if (!this.nodeMapByCreatedAt.has(prevCreatedAt.toIDString())) {
|
|
7459
7612
|
throw new YorkieError(
|
|
7460
7613
|
Code.ErrInvalidArgument,
|
|
7461
7614
|
`cant find the given node: ${prevCreatedAt.toIDString()}`
|
|
7462
7615
|
);
|
|
7463
7616
|
}
|
|
7464
|
-
|
|
7465
|
-
if (!
|
|
7617
|
+
const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
|
|
7618
|
+
if (!entry) {
|
|
7466
7619
|
throw new YorkieError(
|
|
7467
7620
|
Code.ErrInvalidArgument,
|
|
7468
7621
|
`cant find the given node: ${createdAt.toIDString()}`
|
|
7469
7622
|
);
|
|
7470
7623
|
}
|
|
7471
|
-
if (
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
this.release(node);
|
|
7475
|
-
node = this.insertAfter(
|
|
7476
|
-
prevNode.getCreatedAt(),
|
|
7477
|
-
node.getValue(),
|
|
7478
|
-
executedAt
|
|
7479
|
-
);
|
|
7480
|
-
node.getValue().setMovedAt(executedAt);
|
|
7481
|
-
node.setMovedFrom(movedFrom);
|
|
7482
|
-
while (nextNode && nextNode.getPositionedAt().after(executedAt)) {
|
|
7483
|
-
prevNode = node;
|
|
7484
|
-
node = nextNode;
|
|
7485
|
-
nextNode = node.getNext();
|
|
7486
|
-
this.release(node);
|
|
7487
|
-
node = this.insertAfter(
|
|
7488
|
-
prevNode.getCreatedAt(),
|
|
7489
|
-
node.getValue(),
|
|
7490
|
-
executedAt
|
|
7491
|
-
);
|
|
7492
|
-
node.getValue().setMovedAt(executedAt);
|
|
7493
|
-
node.setMovedFrom(movedFrom);
|
|
7624
|
+
if (entry.posMovedAt && !executedAt.after(entry.posMovedAt)) {
|
|
7625
|
+
if (this.nodeMapByCreatedAt.has(executedAt.toIDString())) {
|
|
7626
|
+
return void 0;
|
|
7494
7627
|
}
|
|
7628
|
+
const deadPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
|
|
7629
|
+
deadPosNode.setRemovedAt(executedAt);
|
|
7630
|
+
this.nodeMapByIndex.splayNode(deadPosNode);
|
|
7631
|
+
return deadPosNode;
|
|
7495
7632
|
}
|
|
7633
|
+
const newPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
|
|
7634
|
+
const oldPosNode = entry.positionNode;
|
|
7635
|
+
oldPosNode.setElementEntry(void 0);
|
|
7636
|
+
oldPosNode.setRemovedAt(executedAt);
|
|
7637
|
+
this.nodeMapByIndex.splayNode(oldPosNode);
|
|
7638
|
+
newPosNode.setElementEntry(entry);
|
|
7639
|
+
entry.positionNode = newPosNode;
|
|
7640
|
+
entry.posMovedAt = executedAt;
|
|
7641
|
+
entry.elem.setMovedAt(executedAt);
|
|
7642
|
+
this.nodeMapByIndex.splayNode(newPosNode);
|
|
7643
|
+
return oldPosNode;
|
|
7496
7644
|
}
|
|
7497
7645
|
/**
|
|
7498
7646
|
* `insert` adds the given element after the last node.
|
|
@@ -7501,34 +7649,53 @@ class RGATreeList {
|
|
|
7501
7649
|
this.insertAfter(this.last.getCreatedAt(), value);
|
|
7502
7650
|
}
|
|
7503
7651
|
/**
|
|
7504
|
-
* `getByID` returns the
|
|
7652
|
+
* `getByID` returns the node of the given creation time.
|
|
7653
|
+
* Checks elementMapByCreatedAt first (for moved elements whose
|
|
7654
|
+
* position node createdAt differs), then nodeMapByCreatedAt.
|
|
7505
7655
|
*/
|
|
7506
7656
|
getByID(createdAt) {
|
|
7657
|
+
const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
|
|
7658
|
+
if (entry) {
|
|
7659
|
+
return entry.positionNode;
|
|
7660
|
+
}
|
|
7507
7661
|
return this.nodeMapByCreatedAt.get(createdAt.toIDString());
|
|
7508
7662
|
}
|
|
7509
7663
|
/**
|
|
7510
7664
|
* `subPathOf` returns the sub path of the given element.
|
|
7511
7665
|
*/
|
|
7512
7666
|
subPathOf(createdAt) {
|
|
7513
|
-
const
|
|
7514
|
-
if (!
|
|
7515
|
-
|
|
7667
|
+
const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
|
|
7668
|
+
if (!entry) {
|
|
7669
|
+
const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
|
|
7670
|
+
if (!node) {
|
|
7671
|
+
return;
|
|
7672
|
+
}
|
|
7673
|
+
return String(this.nodeMapByIndex.indexOf(node));
|
|
7516
7674
|
}
|
|
7517
|
-
return String(this.nodeMapByIndex.indexOf(
|
|
7675
|
+
return String(this.nodeMapByIndex.indexOf(entry.positionNode));
|
|
7518
7676
|
}
|
|
7519
7677
|
/**
|
|
7520
|
-
* `purge` physically purges
|
|
7678
|
+
* `purge` physically purges the given child. Handles both dead
|
|
7679
|
+
* position nodes (GCChild from GCParent path) and CRDTElements
|
|
7680
|
+
* (from CRDTContainer path).
|
|
7521
7681
|
*/
|
|
7522
|
-
purge(
|
|
7523
|
-
|
|
7682
|
+
purge(child) {
|
|
7683
|
+
if (child instanceof RGATreeListNode) {
|
|
7684
|
+
this.release(child);
|
|
7685
|
+
return;
|
|
7686
|
+
}
|
|
7687
|
+
const element = child;
|
|
7688
|
+
const entry = this.elementMapByCreatedAt.get(
|
|
7524
7689
|
element.getCreatedAt().toIDString()
|
|
7525
7690
|
);
|
|
7526
|
-
if (!
|
|
7691
|
+
if (!entry) {
|
|
7527
7692
|
throw new YorkieError(
|
|
7528
7693
|
Code.ErrInvalidArgument,
|
|
7529
7694
|
`fail to find the given createdAt: ${element.getCreatedAt().toIDString()}`
|
|
7530
7695
|
);
|
|
7531
7696
|
}
|
|
7697
|
+
const node = entry.positionNode;
|
|
7698
|
+
this.elementMapByCreatedAt.delete(element.getCreatedAt().toIDString());
|
|
7532
7699
|
this.release(node);
|
|
7533
7700
|
}
|
|
7534
7701
|
/**
|
|
@@ -7539,42 +7706,69 @@ class RGATreeList {
|
|
|
7539
7706
|
return;
|
|
7540
7707
|
}
|
|
7541
7708
|
const node = this.nodeMapByIndex.findForArray(idx);
|
|
7542
|
-
|
|
7543
|
-
return rgaNode;
|
|
7709
|
+
return node;
|
|
7544
7710
|
}
|
|
7545
7711
|
/**
|
|
7546
|
-
* `
|
|
7712
|
+
* `findPrevCreatedAt` returns the position node's createdAt of the
|
|
7713
|
+
* previous element. This returns a position identity suitable for
|
|
7714
|
+
* use as prevCreatedAt in moveAfter.
|
|
7547
7715
|
*/
|
|
7548
|
-
|
|
7549
|
-
|
|
7716
|
+
findPrevCreatedAt(createdAt) {
|
|
7717
|
+
const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
|
|
7718
|
+
if (!entry) {
|
|
7719
|
+
throw new YorkieError(
|
|
7720
|
+
Code.ErrInvalidArgument,
|
|
7721
|
+
`cant find the given node: ${createdAt.toIDString()}`
|
|
7722
|
+
);
|
|
7723
|
+
}
|
|
7724
|
+
let node = entry.positionNode;
|
|
7550
7725
|
do {
|
|
7551
7726
|
node = node.getPrev();
|
|
7552
|
-
|
|
7553
|
-
|
|
7727
|
+
if (!node.getElementEntry()) {
|
|
7728
|
+
continue;
|
|
7729
|
+
}
|
|
7730
|
+
if (this.dummyHead === node || !node.isRemoved()) {
|
|
7731
|
+
break;
|
|
7732
|
+
}
|
|
7733
|
+
} while (node);
|
|
7734
|
+
return node.getPositionCreatedAt();
|
|
7735
|
+
}
|
|
7736
|
+
/**
|
|
7737
|
+
* `getPrevCreatedAt` returns the position node's createdAt of the
|
|
7738
|
+
* previous element. Delegates to findPrevCreatedAt.
|
|
7739
|
+
*/
|
|
7740
|
+
getPrevCreatedAt(createdAt) {
|
|
7741
|
+
return this.findPrevCreatedAt(createdAt);
|
|
7554
7742
|
}
|
|
7555
7743
|
/**
|
|
7556
7744
|
* `delete` deletes the node of the given creation time.
|
|
7557
7745
|
*/
|
|
7558
7746
|
delete(createdAt, editedAt) {
|
|
7559
|
-
const
|
|
7747
|
+
const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
|
|
7748
|
+
if (!entry) {
|
|
7749
|
+
throw new YorkieError(
|
|
7750
|
+
Code.ErrInvalidArgument,
|
|
7751
|
+
`cant find the given node: ${createdAt.toIDString()}`
|
|
7752
|
+
);
|
|
7753
|
+
}
|
|
7754
|
+
const node = entry.positionNode;
|
|
7560
7755
|
const alreadyRemoved = node.isRemoved();
|
|
7561
|
-
if (
|
|
7756
|
+
if (entry.elem.remove(editedAt) && !alreadyRemoved) {
|
|
7562
7757
|
this.nodeMapByIndex.splayNode(node);
|
|
7563
7758
|
}
|
|
7564
|
-
return
|
|
7759
|
+
return entry.elem;
|
|
7565
7760
|
}
|
|
7566
7761
|
/**
|
|
7567
7762
|
* `set` sets the given element at the given creation time.
|
|
7568
7763
|
*/
|
|
7569
7764
|
set(createdAt, element, executedAt) {
|
|
7570
|
-
|
|
7571
|
-
if (!node) {
|
|
7765
|
+
if (!this.elementMapByCreatedAt.has(createdAt.toIDString())) {
|
|
7572
7766
|
throw new YorkieError(
|
|
7573
7767
|
Code.ErrInvalidArgument,
|
|
7574
7768
|
`cant find the given node: ${createdAt.toIDString()}`
|
|
7575
7769
|
);
|
|
7576
7770
|
}
|
|
7577
|
-
this.insertAfter(
|
|
7771
|
+
this.insertAfter(createdAt, element, executedAt);
|
|
7578
7772
|
return this.delete(createdAt, executedAt);
|
|
7579
7773
|
}
|
|
7580
7774
|
/**
|
|
@@ -7603,18 +7797,80 @@ class RGATreeList {
|
|
|
7603
7797
|
return this.last.getValue();
|
|
7604
7798
|
}
|
|
7605
7799
|
/**
|
|
7606
|
-
* `getLastCreatedAt` returns the
|
|
7800
|
+
* `getLastCreatedAt` returns the position node's createdAt of the
|
|
7801
|
+
* last node in the linked list. This is a position identity
|
|
7802
|
+
* suitable for use as prevCreatedAt.
|
|
7607
7803
|
*/
|
|
7608
7804
|
getLastCreatedAt() {
|
|
7609
|
-
return this.last.
|
|
7805
|
+
return this.last.getPositionCreatedAt();
|
|
7610
7806
|
}
|
|
7611
7807
|
/**
|
|
7612
|
-
* `
|
|
7613
|
-
*
|
|
7808
|
+
* `posCreatedAt` returns the createdAt of the position node
|
|
7809
|
+
* currently holding the element. Used to convert element identity
|
|
7810
|
+
* to position identity.
|
|
7811
|
+
*/
|
|
7812
|
+
posCreatedAt(elemCreatedAt) {
|
|
7813
|
+
const entry = this.elementMapByCreatedAt.get(elemCreatedAt.toIDString());
|
|
7814
|
+
if (!entry) {
|
|
7815
|
+
throw new YorkieError(
|
|
7816
|
+
Code.ErrInvalidArgument,
|
|
7817
|
+
`cant find the given node: ${elemCreatedAt.toIDString()}`
|
|
7818
|
+
);
|
|
7819
|
+
}
|
|
7820
|
+
return entry.positionNode.getPositionCreatedAt();
|
|
7821
|
+
}
|
|
7822
|
+
/**
|
|
7823
|
+
* `addDeadPosition` appends a dead position node during snapshot
|
|
7824
|
+
* restoration.
|
|
7825
|
+
*/
|
|
7826
|
+
addDeadPosition(posCreatedAt, removedAt) {
|
|
7827
|
+
const node = RGATreeListNode.createBarePosition(posCreatedAt);
|
|
7828
|
+
node.setRemovedAt(removedAt);
|
|
7829
|
+
const prevNode = this.last;
|
|
7830
|
+
RGATreeListNode.insertNodeAfter(prevNode, node);
|
|
7831
|
+
this.last = node;
|
|
7832
|
+
this.nodeMapByIndex.insertAfter(prevNode, node);
|
|
7833
|
+
this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
|
|
7834
|
+
}
|
|
7835
|
+
/**
|
|
7836
|
+
* `addMovedElement` appends an element with explicit position
|
|
7837
|
+
* identity during snapshot restoration.
|
|
7838
|
+
*/
|
|
7839
|
+
addMovedElement(elem, posCreatedAt, posMovedAt) {
|
|
7840
|
+
const entry = new ElementEntry(elem);
|
|
7841
|
+
entry.posMovedAt = posMovedAt;
|
|
7842
|
+
const node = RGATreeListNode.createBarePosition(posCreatedAt);
|
|
7843
|
+
node.setElementEntry(entry);
|
|
7844
|
+
entry.positionNode = node;
|
|
7845
|
+
const prevNode = this.last;
|
|
7846
|
+
RGATreeListNode.insertNodeAfter(prevNode, node);
|
|
7847
|
+
this.last = node;
|
|
7848
|
+
this.nodeMapByIndex.insertAfter(prevNode, node);
|
|
7849
|
+
this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
|
|
7850
|
+
this.elementMapByCreatedAt.set(elem.getCreatedAt().toIDString(), entry);
|
|
7851
|
+
}
|
|
7852
|
+
/**
|
|
7853
|
+
* `allNodes` returns all nodes including dead position nodes.
|
|
7854
|
+
*/
|
|
7855
|
+
allNodes() {
|
|
7856
|
+
const nodes = [];
|
|
7857
|
+
let current = this.dummyHead.getNext();
|
|
7858
|
+
while (current) {
|
|
7859
|
+
nodes.push(current);
|
|
7860
|
+
current = current.getNext();
|
|
7861
|
+
}
|
|
7862
|
+
return nodes;
|
|
7863
|
+
}
|
|
7864
|
+
/**
|
|
7865
|
+
* `toTestString` returns a String containing the meta data of the
|
|
7866
|
+
* node id for debugging purpose.
|
|
7614
7867
|
*/
|
|
7615
7868
|
toTestString() {
|
|
7616
7869
|
const json = [];
|
|
7617
7870
|
for (const node of this) {
|
|
7871
|
+
if (!node.getElementEntry()) {
|
|
7872
|
+
continue;
|
|
7873
|
+
}
|
|
7618
7874
|
const elem = `${node.getCreatedAt().toIDString()}:${node.getValue().toJSON()}`;
|
|
7619
7875
|
if (node.isRemoved()) {
|
|
7620
7876
|
json.push(`{${elem}}`);
|
|
@@ -7671,10 +7927,11 @@ class CRDTArray extends CRDTContainer {
|
|
|
7671
7927
|
this.elements.insertAfter(prevCreatedAt, value, executedAt);
|
|
7672
7928
|
}
|
|
7673
7929
|
/**
|
|
7674
|
-
* `moveAfter` moves the given `createdAt` element after the
|
|
7930
|
+
* `moveAfter` moves the given `createdAt` element after the
|
|
7931
|
+
* `prevCreatedAt`. Returns the dead position node for GC.
|
|
7675
7932
|
*/
|
|
7676
7933
|
moveAfter(prevCreatedAt, createdAt, executedAt) {
|
|
7677
|
-
this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
|
|
7934
|
+
return this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
|
|
7678
7935
|
}
|
|
7679
7936
|
/**
|
|
7680
7937
|
* `get` returns the element of the given index.
|
|
@@ -7703,11 +7960,20 @@ class CRDTArray extends CRDTContainer {
|
|
|
7703
7960
|
return this.elements.getLast();
|
|
7704
7961
|
}
|
|
7705
7962
|
/**
|
|
7706
|
-
* `getPrevCreatedAt` returns the creation time of the previous
|
|
7963
|
+
* `getPrevCreatedAt` returns the creation time of the previous
|
|
7964
|
+
* node.
|
|
7707
7965
|
*/
|
|
7708
7966
|
getPrevCreatedAt(createdAt) {
|
|
7709
7967
|
return this.elements.getPrevCreatedAt(createdAt);
|
|
7710
7968
|
}
|
|
7969
|
+
/**
|
|
7970
|
+
* `posCreatedAt` returns the createdAt of the position node
|
|
7971
|
+
* currently holding the element. Used to convert element identity
|
|
7972
|
+
* to position identity for moves.
|
|
7973
|
+
*/
|
|
7974
|
+
posCreatedAt(elemCreatedAt) {
|
|
7975
|
+
return this.elements.posCreatedAt(elemCreatedAt);
|
|
7976
|
+
}
|
|
7711
7977
|
/**
|
|
7712
7978
|
* `delete` deletes the element of the given creation time.
|
|
7713
7979
|
*/
|
|
@@ -7721,7 +7987,8 @@ class CRDTArray extends CRDTContainer {
|
|
|
7721
7987
|
return this.elements.deleteByIndex(index, editedAt);
|
|
7722
7988
|
}
|
|
7723
7989
|
/**
|
|
7724
|
-
* `set` sets the given element at the given position of the
|
|
7990
|
+
* `set` sets the given element at the given position of the
|
|
7991
|
+
* creation time.
|
|
7725
7992
|
*/
|
|
7726
7993
|
set(createdAt, value, executedAt) {
|
|
7727
7994
|
return this.elements.set(createdAt, value, executedAt);
|
|
@@ -7739,18 +8006,19 @@ class CRDTArray extends CRDTContainer {
|
|
|
7739
8006
|
return this.elements.length;
|
|
7740
8007
|
}
|
|
7741
8008
|
/**
|
|
7742
|
-
* `[Symbol.iterator]` returns an iterator for the elements in
|
|
8009
|
+
* `[Symbol.iterator]` returns an iterator for the elements in
|
|
8010
|
+
* this array.
|
|
7743
8011
|
*/
|
|
7744
8012
|
*[Symbol.iterator]() {
|
|
7745
8013
|
for (const node of this.elements) {
|
|
7746
|
-
if (!node.isRemoved()) {
|
|
8014
|
+
if (node.getElementEntry() && !node.isRemoved()) {
|
|
7747
8015
|
yield node.getValue();
|
|
7748
8016
|
}
|
|
7749
8017
|
}
|
|
7750
8018
|
}
|
|
7751
8019
|
/**
|
|
7752
|
-
* `toTestString` returns a String containing the meta data of
|
|
7753
|
-
* for debugging purpose.
|
|
8020
|
+
* `toTestString` returns a String containing the meta data of
|
|
8021
|
+
* this value for debugging purpose.
|
|
7754
8022
|
*/
|
|
7755
8023
|
toTestString() {
|
|
7756
8024
|
return this.elements.toTestString();
|
|
@@ -7760,6 +8028,9 @@ class CRDTArray extends CRDTContainer {
|
|
|
7760
8028
|
*/
|
|
7761
8029
|
getDescendants(callback) {
|
|
7762
8030
|
for (const node of this.elements) {
|
|
8031
|
+
if (!node.getElementEntry()) {
|
|
8032
|
+
continue;
|
|
8033
|
+
}
|
|
7763
8034
|
const element = node.getValue();
|
|
7764
8035
|
if (callback(element, this)) {
|
|
7765
8036
|
return;
|
|
@@ -7821,21 +8092,52 @@ class CRDTArray extends CRDTContainer {
|
|
|
7821
8092
|
return this.toJSON();
|
|
7822
8093
|
}
|
|
7823
8094
|
/**
|
|
7824
|
-
* `getElements` returns
|
|
8095
|
+
* `getElements` returns the underlying RGATreeList.
|
|
7825
8096
|
*/
|
|
7826
8097
|
getElements() {
|
|
7827
8098
|
return this.elements;
|
|
7828
8099
|
}
|
|
8100
|
+
/**
|
|
8101
|
+
* `getRGATreeList` returns the underlying RGATreeList (GCParent
|
|
8102
|
+
* for dead positions).
|
|
8103
|
+
*/
|
|
8104
|
+
getRGATreeList() {
|
|
8105
|
+
return this.elements;
|
|
8106
|
+
}
|
|
8107
|
+
/**
|
|
8108
|
+
* `getAllRGANodes` returns all RGA nodes including dead position
|
|
8109
|
+
* nodes.
|
|
8110
|
+
*/
|
|
8111
|
+
getAllRGANodes() {
|
|
8112
|
+
return this.elements.allNodes();
|
|
8113
|
+
}
|
|
7829
8114
|
/**
|
|
7830
8115
|
* `deepcopy` copies itself deeply.
|
|
7831
8116
|
*/
|
|
7832
8117
|
deepcopy() {
|
|
7833
8118
|
const clone = CRDTArray.create(this.getCreatedAt());
|
|
7834
8119
|
for (const node of this.elements) {
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
8120
|
+
if (!node.getElementEntry()) {
|
|
8121
|
+
const removedAt = node.getRemovedAt();
|
|
8122
|
+
if (removedAt) {
|
|
8123
|
+
clone.elements.addDeadPosition(
|
|
8124
|
+
node.getPositionCreatedAt(),
|
|
8125
|
+
removedAt
|
|
8126
|
+
);
|
|
8127
|
+
}
|
|
8128
|
+
continue;
|
|
8129
|
+
}
|
|
8130
|
+
const value = node.getValue().deepcopy();
|
|
8131
|
+
const posMovedAt = node.getPositionMovedAt();
|
|
8132
|
+
if (posMovedAt) {
|
|
8133
|
+
clone.elements.addMovedElement(
|
|
8134
|
+
value,
|
|
8135
|
+
node.getPositionCreatedAt(),
|
|
8136
|
+
posMovedAt
|
|
8137
|
+
);
|
|
8138
|
+
} else {
|
|
8139
|
+
clone.elements.insertAfter(clone.getLastCreatedAt(), value);
|
|
8140
|
+
}
|
|
7839
8141
|
}
|
|
7840
8142
|
clone.setRemovedAt(this.getRemovedAt());
|
|
7841
8143
|
clone.setMovedAt(this.getMovedAt());
|
|
@@ -8092,6 +8394,9 @@ class SetOperation extends Operation {
|
|
|
8092
8394
|
if (removed) {
|
|
8093
8395
|
root.registerRemovedElement(removed);
|
|
8094
8396
|
}
|
|
8397
|
+
if (value.getRemovedAt()) {
|
|
8398
|
+
root.registerRemovedElement(value);
|
|
8399
|
+
}
|
|
8095
8400
|
return {
|
|
8096
8401
|
opInfos: [
|
|
8097
8402
|
{
|
|
@@ -8184,7 +8489,17 @@ class MoveOperation extends Operation {
|
|
|
8184
8489
|
const array = parentObject;
|
|
8185
8490
|
const reverseOp = this.toReverseOperation(array);
|
|
8186
8491
|
const previousIndex = Number(array.subPathOf(this.createdAt));
|
|
8187
|
-
array.moveAfter(
|
|
8492
|
+
const deadNode = array.moveAfter(
|
|
8493
|
+
this.prevCreatedAt,
|
|
8494
|
+
this.createdAt,
|
|
8495
|
+
this.getExecutedAt()
|
|
8496
|
+
);
|
|
8497
|
+
if (deadNode) {
|
|
8498
|
+
root.registerGCPair({
|
|
8499
|
+
parent: array.getRGATreeList(),
|
|
8500
|
+
child: deadNode
|
|
8501
|
+
});
|
|
8502
|
+
}
|
|
8188
8503
|
const index = Number(array.subPathOf(this.createdAt));
|
|
8189
8504
|
return {
|
|
8190
8505
|
opInfos: [
|
|
@@ -8207,7 +8522,8 @@ class MoveOperation extends Operation {
|
|
|
8207
8522
|
);
|
|
8208
8523
|
}
|
|
8209
8524
|
/**
|
|
8210
|
-
* `getEffectedCreatedAt` returns the creation time of the
|
|
8525
|
+
* `getEffectedCreatedAt` returns the creation time of the
|
|
8526
|
+
* effected element.
|
|
8211
8527
|
*/
|
|
8212
8528
|
getEffectedCreatedAt() {
|
|
8213
8529
|
return this.createdAt;
|
|
@@ -8219,7 +8535,8 @@ class MoveOperation extends Operation {
|
|
|
8219
8535
|
return `${this.getParentCreatedAt().toTestString()}.MOVE`;
|
|
8220
8536
|
}
|
|
8221
8537
|
/**
|
|
8222
|
-
* `getPrevCreatedAt` returns the creation time of previous
|
|
8538
|
+
* `getPrevCreatedAt` returns the creation time of previous
|
|
8539
|
+
* element.
|
|
8223
8540
|
*/
|
|
8224
8541
|
getPrevCreatedAt() {
|
|
8225
8542
|
return this.prevCreatedAt;
|
|
@@ -8231,7 +8548,8 @@ class MoveOperation extends Operation {
|
|
|
8231
8548
|
return this.createdAt;
|
|
8232
8549
|
}
|
|
8233
8550
|
/**
|
|
8234
|
-
* `setPrevCreatedAt` sets the creation time of the previous
|
|
8551
|
+
* `setPrevCreatedAt` sets the creation time of the previous
|
|
8552
|
+
* element.
|
|
8235
8553
|
*/
|
|
8236
8554
|
setPrevCreatedAt(createdAt) {
|
|
8237
8555
|
this.prevCreatedAt = createdAt;
|
|
@@ -10812,6 +11130,32 @@ class IndexTreeNode {
|
|
|
10812
11130
|
}
|
|
10813
11131
|
actualRight.push(child);
|
|
10814
11132
|
}
|
|
11133
|
+
if (versionVector) {
|
|
11134
|
+
const movedToLeft = [];
|
|
11135
|
+
const remaining = [];
|
|
11136
|
+
let boundaryReached = false;
|
|
11137
|
+
for (const child of actualRight) {
|
|
11138
|
+
if (!boundaryReached) {
|
|
11139
|
+
if (child.insPrevID !== void 0 && !child.isText) {
|
|
11140
|
+
remaining.push(child);
|
|
11141
|
+
continue;
|
|
11142
|
+
}
|
|
11143
|
+
const actorID = child.id.getCreatedAt().getActorID();
|
|
11144
|
+
const knownLamport = versionVector.get(actorID);
|
|
11145
|
+
if (knownLamport === void 0 || knownLamport < child.id.getCreatedAt().getLamport()) {
|
|
11146
|
+
movedToLeft.push(child);
|
|
11147
|
+
continue;
|
|
11148
|
+
}
|
|
11149
|
+
}
|
|
11150
|
+
boundaryReached = true;
|
|
11151
|
+
remaining.push(child);
|
|
11152
|
+
}
|
|
11153
|
+
if (movedToLeft.length > 0) {
|
|
11154
|
+
left.push(...movedToLeft);
|
|
11155
|
+
actualRight.length = 0;
|
|
11156
|
+
actualRight.push(...remaining);
|
|
11157
|
+
}
|
|
11158
|
+
}
|
|
10815
11159
|
this._children = left;
|
|
10816
11160
|
clone._children = actualRight;
|
|
10817
11161
|
this.visibleSize = this._children.reduce(
|
|
@@ -11575,7 +11919,7 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
11575
11919
|
CRDTTreeNodeID.of(issueTimeTicket(), 0),
|
|
11576
11920
|
this.type,
|
|
11577
11921
|
void 0,
|
|
11578
|
-
|
|
11922
|
+
this.attrs?.deepcopy(),
|
|
11579
11923
|
this.removedAt
|
|
11580
11924
|
);
|
|
11581
11925
|
}
|
|
@@ -11588,8 +11932,14 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
11588
11932
|
split.insPrevID = this.id;
|
|
11589
11933
|
if (this.insNextID) {
|
|
11590
11934
|
const insNext = tree.findFloorNode(this.insNextID);
|
|
11591
|
-
insNext.insPrevID = split.id;
|
|
11592
11935
|
split.insNextID = this.insNextID;
|
|
11936
|
+
if (insNext) {
|
|
11937
|
+
insNext.insPrevID = split.id;
|
|
11938
|
+
if (!this.isText && insNext.parent && !insNext.isRemoved && insNext.parent !== split.parent && split.allChildren.length === 0) {
|
|
11939
|
+
split.parent.detachChild(split);
|
|
11940
|
+
insNext.parent.insertBefore(split, insNext);
|
|
11941
|
+
}
|
|
11942
|
+
}
|
|
11593
11943
|
}
|
|
11594
11944
|
this.insNextID = split.id;
|
|
11595
11945
|
tree.registerNode(split);
|
|
@@ -11813,7 +12163,7 @@ class CRDTTree extends CRDTElement {
|
|
|
11813
12163
|
* given node, advancing past element-type split siblings that the editing
|
|
11814
12164
|
* client did not know about (not in versionVector).
|
|
11815
12165
|
*/
|
|
11816
|
-
advancePastUnknownSplitSiblings(node, versionVector) {
|
|
12166
|
+
advancePastUnknownSplitSiblings(node, versionVector, relaxParentCheck = false, skipActorID) {
|
|
11817
12167
|
if (!versionVector || !node) {
|
|
11818
12168
|
return node;
|
|
11819
12169
|
}
|
|
@@ -11823,10 +12173,13 @@ class CRDTTree extends CRDTElement {
|
|
|
11823
12173
|
if (!next || next.isText) {
|
|
11824
12174
|
break;
|
|
11825
12175
|
}
|
|
11826
|
-
if (next.parent !== current.parent) {
|
|
12176
|
+
if (!relaxParentCheck && next.parent !== current.parent) {
|
|
11827
12177
|
break;
|
|
11828
12178
|
}
|
|
11829
12179
|
const actorID = next.id.getCreatedAt().getActorID();
|
|
12180
|
+
if (skipActorID !== void 0 && actorID === skipActorID) {
|
|
12181
|
+
break;
|
|
12182
|
+
}
|
|
11830
12183
|
const knownLamport = versionVector.get(actorID);
|
|
11831
12184
|
if (knownLamport !== void 0 && knownLamport >= next.id.getCreatedAt().getLamport()) {
|
|
11832
12185
|
break;
|
|
@@ -11995,6 +12348,53 @@ class CRDTTree extends CRDTElement {
|
|
|
11995
12348
|
addDataSizes(diff, curr.getDataSize());
|
|
11996
12349
|
}
|
|
11997
12350
|
}
|
|
12351
|
+
if (tokenType === TokenType.Start && versionVector !== void 0) {
|
|
12352
|
+
let current = node;
|
|
12353
|
+
while (current.insNextID) {
|
|
12354
|
+
const next = this.findFloorNode(current.insNextID);
|
|
12355
|
+
if (!next || next.isText) {
|
|
12356
|
+
break;
|
|
12357
|
+
}
|
|
12358
|
+
if (ticketKnown(versionVector, next.id.getCreatedAt())) {
|
|
12359
|
+
break;
|
|
12360
|
+
}
|
|
12361
|
+
const siblingPairs = next.setAttrs(attributes, editedAt);
|
|
12362
|
+
const siblingAffectedAttrs = siblingPairs.reduce(
|
|
12363
|
+
(acc, [, curr]) => {
|
|
12364
|
+
if (curr) {
|
|
12365
|
+
acc[curr.getKey()] = attrs[curr.getKey()];
|
|
12366
|
+
}
|
|
12367
|
+
return acc;
|
|
12368
|
+
},
|
|
12369
|
+
{}
|
|
12370
|
+
);
|
|
12371
|
+
if (Object.keys(siblingAffectedAttrs).length > 0) {
|
|
12372
|
+
const parentOfNext = next.parent;
|
|
12373
|
+
const previousNext = next.prevSibling || parentOfNext;
|
|
12374
|
+
changes.push({
|
|
12375
|
+
type: "style",
|
|
12376
|
+
from: this.toIndex(parentOfNext, previousNext),
|
|
12377
|
+
to: this.toIndex(next, next),
|
|
12378
|
+
fromPath: this.toPath(parentOfNext, previousNext),
|
|
12379
|
+
toPath: this.toPath(next, next),
|
|
12380
|
+
actor: editedAt.getActorID(),
|
|
12381
|
+
value: siblingAffectedAttrs
|
|
12382
|
+
});
|
|
12383
|
+
}
|
|
12384
|
+
for (const [prev] of siblingPairs) {
|
|
12385
|
+
if (prev) {
|
|
12386
|
+
pairs.push({ parent: next, child: prev });
|
|
12387
|
+
}
|
|
12388
|
+
}
|
|
12389
|
+
for (const [key] of Object.entries(attrs)) {
|
|
12390
|
+
const curr = next.attrs?.getNodeMapByKey().get(key);
|
|
12391
|
+
if (curr !== void 0) {
|
|
12392
|
+
addDataSizes(diff, curr.getDataSize());
|
|
12393
|
+
}
|
|
12394
|
+
}
|
|
12395
|
+
current = next;
|
|
12396
|
+
}
|
|
12397
|
+
}
|
|
11998
12398
|
}
|
|
11999
12399
|
}
|
|
12000
12400
|
);
|
|
@@ -12061,6 +12461,43 @@ class CRDTTree extends CRDTElement {
|
|
|
12061
12461
|
toPath: this.toPath(node, node),
|
|
12062
12462
|
value: attributesToRemove
|
|
12063
12463
|
});
|
|
12464
|
+
if (tokenType === TokenType.Start && versionVector !== void 0) {
|
|
12465
|
+
let current = node;
|
|
12466
|
+
while (current.insNextID) {
|
|
12467
|
+
const next = this.findFloorNode(current.insNextID);
|
|
12468
|
+
if (!next || next.isText) {
|
|
12469
|
+
break;
|
|
12470
|
+
}
|
|
12471
|
+
if (ticketKnown(versionVector, next.id.getCreatedAt())) {
|
|
12472
|
+
break;
|
|
12473
|
+
}
|
|
12474
|
+
if (!next.attrs) {
|
|
12475
|
+
next.attrs = new RHT();
|
|
12476
|
+
}
|
|
12477
|
+
let removedAny = false;
|
|
12478
|
+
for (const value of attributesToRemove) {
|
|
12479
|
+
const nodesTobeRemoved = next.attrs.remove(value, editedAt);
|
|
12480
|
+
removedAny = removedAny || nodesTobeRemoved.length > 0;
|
|
12481
|
+
for (const rhtNode of nodesTobeRemoved) {
|
|
12482
|
+
pairs.push({ parent: next, child: rhtNode });
|
|
12483
|
+
}
|
|
12484
|
+
}
|
|
12485
|
+
if (removedAny) {
|
|
12486
|
+
const parentOfNext = next.parent;
|
|
12487
|
+
const previousNext = next.prevSibling || parentOfNext;
|
|
12488
|
+
changes.push({
|
|
12489
|
+
actor: editedAt.getActorID(),
|
|
12490
|
+
type: "removeStyle",
|
|
12491
|
+
from: this.toIndex(parentOfNext, previousNext),
|
|
12492
|
+
to: this.toIndex(next, next),
|
|
12493
|
+
fromPath: this.toPath(parentOfNext, previousNext),
|
|
12494
|
+
toPath: this.toPath(next, next),
|
|
12495
|
+
value: attributesToRemove
|
|
12496
|
+
});
|
|
12497
|
+
}
|
|
12498
|
+
current = next;
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12064
12501
|
}
|
|
12065
12502
|
}
|
|
12066
12503
|
);
|
|
@@ -12083,6 +12520,23 @@ class CRDTTree extends CRDTElement {
|
|
|
12083
12520
|
addDataSizes(diff, diffTo, diffFrom);
|
|
12084
12521
|
const fromLeft = fromLeftRaw !== fromParent ? this.advancePastUnknownSplitSiblings(fromLeftRaw, versionVector) : fromLeftRaw;
|
|
12085
12522
|
const toLeft = toLeftRaw !== toParent ? this.advancePastUnknownSplitSiblings(toLeftRaw, versionVector) : toLeftRaw;
|
|
12523
|
+
let collectFromParent = fromParent;
|
|
12524
|
+
let collectFromLeft = fromLeft;
|
|
12525
|
+
if (fromLeft !== fromParent && fromParent !== toParent) {
|
|
12526
|
+
let current = fromLeft;
|
|
12527
|
+
while (current.insNextID) {
|
|
12528
|
+
const next = this.findFloorNode(current.insNextID);
|
|
12529
|
+
if (!next || next.isText) {
|
|
12530
|
+
break;
|
|
12531
|
+
}
|
|
12532
|
+
if (next.parent && next.parent === toParent) {
|
|
12533
|
+
collectFromLeft = next;
|
|
12534
|
+
collectFromParent = toParent;
|
|
12535
|
+
break;
|
|
12536
|
+
}
|
|
12537
|
+
current = next;
|
|
12538
|
+
}
|
|
12539
|
+
}
|
|
12086
12540
|
const fromIdx = this.toIndex(fromParent, fromLeft);
|
|
12087
12541
|
const fromPath = this.toPath(fromParent, fromLeft);
|
|
12088
12542
|
const nodesToBeRemoved = [];
|
|
@@ -12091,8 +12545,8 @@ class CRDTTree extends CRDTElement {
|
|
|
12091
12545
|
const toBeMergedNodes = [];
|
|
12092
12546
|
const preTombstoned = /* @__PURE__ */ new Set();
|
|
12093
12547
|
this.traverseInPosRange(
|
|
12094
|
-
|
|
12095
|
-
|
|
12548
|
+
collectFromParent,
|
|
12549
|
+
collectFromLeft,
|
|
12096
12550
|
toParent,
|
|
12097
12551
|
toLeft,
|
|
12098
12552
|
([node, tokenType], ended) => {
|
|
@@ -12196,9 +12650,20 @@ class CRDTTree extends CRDTElement {
|
|
|
12196
12650
|
let parent = fromParent;
|
|
12197
12651
|
let left = fromLeft;
|
|
12198
12652
|
while (splitCount < splitLevel) {
|
|
12653
|
+
if (left !== parent) {
|
|
12654
|
+
left = this.advancePastUnknownSplitSiblings(
|
|
12655
|
+
left,
|
|
12656
|
+
versionVector,
|
|
12657
|
+
true,
|
|
12658
|
+
editedAt.getActorID()
|
|
12659
|
+
);
|
|
12660
|
+
if (left.parent && left.parent !== parent) {
|
|
12661
|
+
parent = left.parent;
|
|
12662
|
+
}
|
|
12663
|
+
}
|
|
12199
12664
|
parent.split(
|
|
12200
12665
|
this,
|
|
12201
|
-
parent.findOffset(left, true) + 1,
|
|
12666
|
+
left !== parent ? parent.findOffset(left, true) + 1 : 0,
|
|
12202
12667
|
issueTimeTicket,
|
|
12203
12668
|
versionVector
|
|
12204
12669
|
);
|
|
@@ -12805,10 +13270,10 @@ class TreeEditOperation extends Operation {
|
|
|
12805
13270
|
);
|
|
12806
13271
|
this.lastToIdx = preEditFromIdx + removedSize;
|
|
12807
13272
|
let reverseOp;
|
|
12808
|
-
const
|
|
13273
|
+
const isPureSplit = this.splitLevel > 0 && !this.contents?.length && removedNodes.length === 0;
|
|
12809
13274
|
if (this.splitLevel === 0) {
|
|
12810
13275
|
reverseOp = this.toReverseOperation(tree, removedNodes, preEditFromIdx);
|
|
12811
|
-
} else if (
|
|
13276
|
+
} else if (isPureSplit) {
|
|
12812
13277
|
reverseOp = this.toSplitReverseOperation(tree, preEditFromIdx);
|
|
12813
13278
|
}
|
|
12814
13279
|
root.acc(diff);
|
|
@@ -14819,14 +15284,26 @@ function toRHTNodes(rht) {
|
|
|
14819
15284
|
}
|
|
14820
15285
|
return pbRHTNodes;
|
|
14821
15286
|
}
|
|
14822
|
-
function toRGANodes(
|
|
15287
|
+
function toRGANodes(arr) {
|
|
14823
15288
|
const pbRGANodes = [];
|
|
14824
|
-
for (const
|
|
14825
|
-
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
15289
|
+
for (const rgaNode of arr.getAllRGANodes()) {
|
|
15290
|
+
if (!rgaNode.getElementEntry()) {
|
|
15291
|
+
pbRGANodes.push(
|
|
15292
|
+
create(RGANodeSchema, {
|
|
15293
|
+
positionCreatedAt: toTimeTicket(rgaNode.getPositionCreatedAt()),
|
|
15294
|
+
positionRemovedAt: toTimeTicket(rgaNode.getRemovedAt())
|
|
15295
|
+
})
|
|
15296
|
+
);
|
|
15297
|
+
continue;
|
|
15298
|
+
}
|
|
15299
|
+
const pbNode = create(RGANodeSchema, {
|
|
15300
|
+
element: toElement(rgaNode.getValue())
|
|
15301
|
+
});
|
|
15302
|
+
if (rgaNode.getPositionMovedAt()) {
|
|
15303
|
+
pbNode.positionMovedAt = toTimeTicket(rgaNode.getPositionMovedAt());
|
|
15304
|
+
pbNode.positionCreatedAt = toTimeTicket(rgaNode.getPositionCreatedAt());
|
|
15305
|
+
}
|
|
15306
|
+
pbRGANodes.push(pbNode);
|
|
14830
15307
|
}
|
|
14831
15308
|
return pbRGANodes;
|
|
14832
15309
|
}
|
|
@@ -14926,7 +15403,7 @@ function toArray(arr) {
|
|
|
14926
15403
|
body: {
|
|
14927
15404
|
case: "jsonArray",
|
|
14928
15405
|
value: create(JSONElement_JSONArraySchema, {
|
|
14929
|
-
nodes: toRGANodes(arr
|
|
15406
|
+
nodes: toRGANodes(arr),
|
|
14930
15407
|
createdAt: toTimeTicket(arr.getCreatedAt()),
|
|
14931
15408
|
movedAt: toTimeTicket(arr.getMovedAt()),
|
|
14932
15409
|
removedAt: toTimeTicket(arr.getRemovedAt())
|
|
@@ -15464,7 +15941,32 @@ function fromObject(pbObject) {
|
|
|
15464
15941
|
function fromArray(pbArray) {
|
|
15465
15942
|
const rgaTreeList = new RGATreeList();
|
|
15466
15943
|
for (const pbRGANode of pbArray.nodes) {
|
|
15467
|
-
|
|
15944
|
+
if (!pbRGANode.element) {
|
|
15945
|
+
if (!pbRGANode.positionCreatedAt || !pbRGANode.positionRemovedAt) {
|
|
15946
|
+
throw new YorkieError(
|
|
15947
|
+
Code.ErrInvalidArgument,
|
|
15948
|
+
"dead RGA position node missing position timestamps"
|
|
15949
|
+
);
|
|
15950
|
+
}
|
|
15951
|
+
const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
|
|
15952
|
+
const posRemovedAt = fromTimeTicket(pbRGANode.positionRemovedAt);
|
|
15953
|
+
rgaTreeList.addDeadPosition(posCreatedAt, posRemovedAt);
|
|
15954
|
+
continue;
|
|
15955
|
+
}
|
|
15956
|
+
const elem = fromElement(pbRGANode.element);
|
|
15957
|
+
const posMovedAt = fromTimeTicket(pbRGANode.positionMovedAt);
|
|
15958
|
+
if (posMovedAt) {
|
|
15959
|
+
if (!pbRGANode.positionCreatedAt) {
|
|
15960
|
+
throw new YorkieError(
|
|
15961
|
+
Code.ErrInvalidArgument,
|
|
15962
|
+
"moved RGA node missing position_created_at"
|
|
15963
|
+
);
|
|
15964
|
+
}
|
|
15965
|
+
const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
|
|
15966
|
+
rgaTreeList.addMovedElement(elem, posCreatedAt, posMovedAt);
|
|
15967
|
+
} else {
|
|
15968
|
+
rgaTreeList.insert(elem);
|
|
15969
|
+
}
|
|
15468
15970
|
}
|
|
15469
15971
|
const arr = new CRDTArray(fromTimeTicket(pbArray.createdAt), rgaTreeList);
|
|
15470
15972
|
arr.setMovedAt(fromTimeTicket(pbArray.movedAt));
|
|
@@ -16252,10 +16754,16 @@ class ArrayProxy {
|
|
|
16252
16754
|
};
|
|
16253
16755
|
} else if (method === "insertAfter") {
|
|
16254
16756
|
return (prevID, value) => {
|
|
16757
|
+
let posCreatedAt;
|
|
16758
|
+
try {
|
|
16759
|
+
posCreatedAt = target.posCreatedAt(prevID);
|
|
16760
|
+
} catch {
|
|
16761
|
+
posCreatedAt = prevID;
|
|
16762
|
+
}
|
|
16255
16763
|
const inserted = ArrayProxy.insertAfterInternal(
|
|
16256
16764
|
context,
|
|
16257
16765
|
target,
|
|
16258
|
-
|
|
16766
|
+
posCreatedAt,
|
|
16259
16767
|
value
|
|
16260
16768
|
);
|
|
16261
16769
|
return toWrappedElement(context, inserted);
|
|
@@ -16440,7 +16948,7 @@ class ArrayProxy {
|
|
|
16440
16948
|
static moveBeforeInternal(context, target, nextCreatedAt, createdAt) {
|
|
16441
16949
|
const ticket = context.issueTimeTicket();
|
|
16442
16950
|
const prevCreatedAt = target.getPrevCreatedAt(nextCreatedAt);
|
|
16443
|
-
target.moveAfter(prevCreatedAt, createdAt, ticket);
|
|
16951
|
+
const deadNode = target.moveAfter(prevCreatedAt, createdAt, ticket);
|
|
16444
16952
|
context.push(
|
|
16445
16953
|
MoveOperation.create(
|
|
16446
16954
|
target.getCreatedAt(),
|
|
@@ -16449,26 +16957,45 @@ class ArrayProxy {
|
|
|
16449
16957
|
ticket
|
|
16450
16958
|
)
|
|
16451
16959
|
);
|
|
16960
|
+
if (deadNode) {
|
|
16961
|
+
context.registerGCPair({
|
|
16962
|
+
parent: target.getRGATreeList(),
|
|
16963
|
+
child: deadNode
|
|
16964
|
+
});
|
|
16965
|
+
}
|
|
16452
16966
|
}
|
|
16453
16967
|
/**
|
|
16454
16968
|
* `moveAfterInternal` moves the given `createdAt` element
|
|
16455
|
-
* after the specific element.
|
|
16969
|
+
* after the specific element. Converts element identity to
|
|
16970
|
+
* position identity for the prevCreatedAt.
|
|
16456
16971
|
*/
|
|
16457
16972
|
static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
|
|
16458
16973
|
const ticket = context.issueTimeTicket();
|
|
16974
|
+
let posCreatedAt;
|
|
16975
|
+
try {
|
|
16976
|
+
posCreatedAt = target.posCreatedAt(prevCreatedAt);
|
|
16977
|
+
} catch {
|
|
16978
|
+
posCreatedAt = prevCreatedAt;
|
|
16979
|
+
}
|
|
16980
|
+
const deadNode = target.moveAfter(posCreatedAt, createdAt, ticket);
|
|
16459
16981
|
context.push(
|
|
16460
16982
|
MoveOperation.create(
|
|
16461
16983
|
target.getCreatedAt(),
|
|
16462
|
-
|
|
16984
|
+
posCreatedAt,
|
|
16463
16985
|
createdAt,
|
|
16464
16986
|
ticket
|
|
16465
16987
|
)
|
|
16466
16988
|
);
|
|
16467
|
-
|
|
16989
|
+
if (deadNode) {
|
|
16990
|
+
context.registerGCPair({
|
|
16991
|
+
parent: target.getRGATreeList(),
|
|
16992
|
+
child: deadNode
|
|
16993
|
+
});
|
|
16994
|
+
}
|
|
16468
16995
|
}
|
|
16469
16996
|
/**
|
|
16470
|
-
* `moveAfterByIndexInternal` moves the given element to its new
|
|
16471
|
-
* after the given previous element.
|
|
16997
|
+
* `moveAfterByIndexInternal` moves the given element to its new
|
|
16998
|
+
* position after the given previous element.
|
|
16472
16999
|
*/
|
|
16473
17000
|
static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
|
|
16474
17001
|
const prevElem = target.get(prevIndex);
|
|
@@ -16499,7 +17026,7 @@ class ArrayProxy {
|
|
|
16499
17026
|
static moveFrontInternal(context, target, createdAt) {
|
|
16500
17027
|
const ticket = context.issueTimeTicket();
|
|
16501
17028
|
const head = target.getHead();
|
|
16502
|
-
target.moveAfter(head.getCreatedAt(), createdAt, ticket);
|
|
17029
|
+
const deadNode = target.moveAfter(head.getCreatedAt(), createdAt, ticket);
|
|
16503
17030
|
context.push(
|
|
16504
17031
|
MoveOperation.create(
|
|
16505
17032
|
target.getCreatedAt(),
|
|
@@ -16508,6 +17035,12 @@ class ArrayProxy {
|
|
|
16508
17035
|
ticket
|
|
16509
17036
|
)
|
|
16510
17037
|
);
|
|
17038
|
+
if (deadNode) {
|
|
17039
|
+
context.registerGCPair({
|
|
17040
|
+
parent: target.getRGATreeList(),
|
|
17041
|
+
child: deadNode
|
|
17042
|
+
});
|
|
17043
|
+
}
|
|
16511
17044
|
}
|
|
16512
17045
|
/**
|
|
16513
17046
|
* `moveLastInternal` moves the given `createdAt` element
|
|
@@ -16516,13 +17049,20 @@ class ArrayProxy {
|
|
|
16516
17049
|
static moveLastInternal(context, target, createdAt) {
|
|
16517
17050
|
const ticket = context.issueTimeTicket();
|
|
16518
17051
|
const last = target.getLastCreatedAt();
|
|
16519
|
-
target.moveAfter(last, createdAt, ticket);
|
|
17052
|
+
const deadNode = target.moveAfter(last, createdAt, ticket);
|
|
16520
17053
|
context.push(
|
|
16521
17054
|
MoveOperation.create(target.getCreatedAt(), last, createdAt, ticket)
|
|
16522
17055
|
);
|
|
17056
|
+
if (deadNode) {
|
|
17057
|
+
context.registerGCPair({
|
|
17058
|
+
parent: target.getRGATreeList(),
|
|
17059
|
+
child: deadNode
|
|
17060
|
+
});
|
|
17061
|
+
}
|
|
16523
17062
|
}
|
|
16524
17063
|
/**
|
|
16525
|
-
* `insertAfterInternal` inserts the value after the previously
|
|
17064
|
+
* `insertAfterInternal` inserts the value after the previously
|
|
17065
|
+
* created element.
|
|
16526
17066
|
*/
|
|
16527
17067
|
static insertAfterInternal(context, target, prevCreatedAt, value) {
|
|
16528
17068
|
const createdAt = context.issueTimeTicket();
|
|
@@ -16550,12 +17090,13 @@ class ArrayProxy {
|
|
|
16550
17090
|
`index out of bounds: ${index}`
|
|
16551
17091
|
);
|
|
16552
17092
|
}
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
target
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
17093
|
+
let posCreatedAt;
|
|
17094
|
+
try {
|
|
17095
|
+
posCreatedAt = target.posCreatedAt(prevElem.getCreatedAt());
|
|
17096
|
+
} catch {
|
|
17097
|
+
posCreatedAt = prevElem.getCreatedAt();
|
|
17098
|
+
}
|
|
17099
|
+
ArrayProxy.insertAfterInternal(context, target, posCreatedAt, value);
|
|
16559
17100
|
return target;
|
|
16560
17101
|
}
|
|
16561
17102
|
/**
|
|
@@ -16654,7 +17195,17 @@ class ArrayProxy {
|
|
|
16654
17195
|
}
|
|
16655
17196
|
}
|
|
16656
17197
|
if (items) {
|
|
16657
|
-
let previousID
|
|
17198
|
+
let previousID;
|
|
17199
|
+
if (from === 0) {
|
|
17200
|
+
previousID = target.getHead().getID();
|
|
17201
|
+
} else {
|
|
17202
|
+
const elemID = target.get(from - 1).getID();
|
|
17203
|
+
try {
|
|
17204
|
+
previousID = target.posCreatedAt(elemID);
|
|
17205
|
+
} catch {
|
|
17206
|
+
previousID = elemID;
|
|
17207
|
+
}
|
|
17208
|
+
}
|
|
16658
17209
|
for (const item of items) {
|
|
16659
17210
|
const newElem = ArrayProxy.insertAfterInternal(
|
|
16660
17211
|
context,
|
|
@@ -18004,6 +18555,16 @@ class CRDTRoot {
|
|
|
18004
18555
|
this.registerGCPair(pair);
|
|
18005
18556
|
}
|
|
18006
18557
|
}
|
|
18558
|
+
if (elem instanceof CRDTArray) {
|
|
18559
|
+
for (const node of elem.getAllRGANodes()) {
|
|
18560
|
+
if (!node.getElementEntry() && node.getRemovedAt()) {
|
|
18561
|
+
this.registerGCPair({
|
|
18562
|
+
parent: elem.getRGATreeList(),
|
|
18563
|
+
child: node
|
|
18564
|
+
});
|
|
18565
|
+
}
|
|
18566
|
+
}
|
|
18567
|
+
}
|
|
18007
18568
|
return false;
|
|
18008
18569
|
});
|
|
18009
18570
|
}
|
|
@@ -19095,6 +19656,11 @@ class Document {
|
|
|
19095
19656
|
if (logger.isEnabled(LogLevel.Trivial)) {
|
|
19096
19657
|
logger.trivial(`trying to update a local change: ${this.toJSON()}`);
|
|
19097
19658
|
}
|
|
19659
|
+
const prev = {
|
|
19660
|
+
hadPresence: this.presences.has(actorID),
|
|
19661
|
+
wasOnline: this.status === "attached",
|
|
19662
|
+
presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
|
|
19663
|
+
};
|
|
19098
19664
|
const change = ctx.toChange();
|
|
19099
19665
|
const { opInfos, reverseOps } = change.execute(
|
|
19100
19666
|
this.root,
|
|
@@ -19140,14 +19706,14 @@ class Document {
|
|
|
19140
19706
|
});
|
|
19141
19707
|
}
|
|
19142
19708
|
if (change.hasPresenceChange()) {
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
}
|
|
19709
|
+
const presenceEvent = this.reconcilePresence(
|
|
19710
|
+
actorID,
|
|
19711
|
+
prev,
|
|
19712
|
+
OpSource.Local
|
|
19713
|
+
);
|
|
19714
|
+
if (presenceEvent) {
|
|
19715
|
+
event.push(presenceEvent);
|
|
19716
|
+
}
|
|
19151
19717
|
}
|
|
19152
19718
|
this.publish(event);
|
|
19153
19719
|
if (logger.isEnabled(LogLevel.Trivial)) {
|
|
@@ -19631,41 +20197,11 @@ class Document {
|
|
|
19631
20197
|
change.execute(this.clone.root, this.clone.presences, source);
|
|
19632
20198
|
const events = [];
|
|
19633
20199
|
const actorID = change.getID().getActorID();
|
|
19634
|
-
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
|
|
19638
|
-
|
|
19639
|
-
this.presences.has(actorID) ? {
|
|
19640
|
-
type: "presence-changed",
|
|
19641
|
-
source,
|
|
19642
|
-
value: {
|
|
19643
|
-
clientID: actorID,
|
|
19644
|
-
presence: presenceChange.presence
|
|
19645
|
-
}
|
|
19646
|
-
} : {
|
|
19647
|
-
type: "watched",
|
|
19648
|
-
source: OpSource.Remote,
|
|
19649
|
-
value: {
|
|
19650
|
-
clientID: actorID,
|
|
19651
|
-
presence: presenceChange.presence
|
|
19652
|
-
}
|
|
19653
|
-
}
|
|
19654
|
-
);
|
|
19655
|
-
break;
|
|
19656
|
-
case PresenceChangeType.Clear:
|
|
19657
|
-
events.push({
|
|
19658
|
-
type: "unwatched",
|
|
19659
|
-
source: OpSource.Remote,
|
|
19660
|
-
value: {
|
|
19661
|
-
clientID: actorID,
|
|
19662
|
-
presence: this.getPresence(actorID)
|
|
19663
|
-
}
|
|
19664
|
-
});
|
|
19665
|
-
this.removeOnlineClient(actorID);
|
|
19666
|
-
break;
|
|
19667
|
-
}
|
|
19668
|
-
}
|
|
20200
|
+
const prev = change.hasPresenceChange() ? {
|
|
20201
|
+
hadPresence: this.presences.has(actorID),
|
|
20202
|
+
wasOnline: this.onlineClients.has(actorID),
|
|
20203
|
+
presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
|
|
20204
|
+
} : void 0;
|
|
19669
20205
|
const { opInfos, operations } = change.execute(
|
|
19670
20206
|
this.root,
|
|
19671
20207
|
this.presences,
|
|
@@ -19720,6 +20256,16 @@ class Document {
|
|
|
19720
20256
|
}
|
|
19721
20257
|
);
|
|
19722
20258
|
}
|
|
20259
|
+
if (prev && change.hasPresenceChange()) {
|
|
20260
|
+
const presenceChange = change.getPresenceChange();
|
|
20261
|
+
if (presenceChange.type === PresenceChangeType.Clear) {
|
|
20262
|
+
this.removeOnlineClient(actorID);
|
|
20263
|
+
}
|
|
20264
|
+
const presenceEvent = this.reconcilePresence(actorID, prev, source);
|
|
20265
|
+
if (presenceEvent) {
|
|
20266
|
+
events.push(presenceEvent);
|
|
20267
|
+
}
|
|
20268
|
+
}
|
|
19723
20269
|
if (events.length) {
|
|
19724
20270
|
this.publish(events);
|
|
19725
20271
|
}
|
|
@@ -19748,46 +20294,43 @@ class Document {
|
|
|
19748
20294
|
* `applyDocEvent` applies the given doc event into this document.
|
|
19749
20295
|
*/
|
|
19750
20296
|
applyDocEvent(type, publisher) {
|
|
19751
|
-
const
|
|
20297
|
+
const prev = {
|
|
20298
|
+
hadPresence: this.presences.has(publisher),
|
|
20299
|
+
wasOnline: this.onlineClients.has(publisher),
|
|
20300
|
+
presence: this.presences.has(publisher) ? deepcopy(this.presences.get(publisher)) : void 0
|
|
20301
|
+
};
|
|
19752
20302
|
if (type === DocEventType$1.DOCUMENT_WATCHED) {
|
|
19753
20303
|
if (this.onlineClients.has(publisher) && this.hasPresence(publisher)) {
|
|
19754
20304
|
return;
|
|
19755
20305
|
}
|
|
19756
20306
|
this.addOnlineClient(publisher);
|
|
19757
|
-
if (this.hasPresence(publisher)) {
|
|
19758
|
-
events.push({
|
|
19759
|
-
type: "watched",
|
|
19760
|
-
source: OpSource.Remote,
|
|
19761
|
-
value: {
|
|
19762
|
-
clientID: publisher,
|
|
19763
|
-
presence: this.getPresence(publisher)
|
|
19764
|
-
}
|
|
19765
|
-
});
|
|
19766
|
-
}
|
|
19767
20307
|
} else if (type === DocEventType$1.DOCUMENT_UNWATCHED) {
|
|
19768
|
-
const presence = this.getPresence(publisher);
|
|
19769
20308
|
this.removeOnlineClient(publisher);
|
|
19770
20309
|
this.presences.delete(publisher);
|
|
19771
|
-
if (presence) {
|
|
19772
|
-
events.push({
|
|
19773
|
-
type: "unwatched",
|
|
19774
|
-
source: OpSource.Remote,
|
|
19775
|
-
value: { clientID: publisher, presence }
|
|
19776
|
-
});
|
|
19777
|
-
}
|
|
19778
20310
|
}
|
|
19779
|
-
|
|
19780
|
-
|
|
20311
|
+
const event = this.reconcilePresence(publisher, prev, OpSource.Remote);
|
|
20312
|
+
if (event) {
|
|
20313
|
+
this.publish([event]);
|
|
19781
20314
|
}
|
|
19782
20315
|
}
|
|
19783
20316
|
/**
|
|
19784
20317
|
* `applyStatus` applies the document status into this document.
|
|
19785
20318
|
*/
|
|
19786
20319
|
applyStatus(status) {
|
|
20320
|
+
const actorID = this.changeID.getActorID();
|
|
20321
|
+
const prev = {
|
|
20322
|
+
hadPresence: this.presences.has(actorID),
|
|
20323
|
+
wasOnline: this.status === "attached",
|
|
20324
|
+
presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
|
|
20325
|
+
};
|
|
19787
20326
|
this.status = status;
|
|
19788
20327
|
if (status === "detached") {
|
|
19789
20328
|
this.setActor(InitialActorID);
|
|
19790
20329
|
}
|
|
20330
|
+
const event = this.reconcilePresence(actorID, prev, OpSource.Local);
|
|
20331
|
+
if (event) {
|
|
20332
|
+
this.publish([event]);
|
|
20333
|
+
}
|
|
19791
20334
|
this.publish([
|
|
19792
20335
|
{
|
|
19793
20336
|
source: status === "removed" ? OpSource.Remote : OpSource.Local,
|
|
@@ -19887,6 +20430,57 @@ class Document {
|
|
|
19887
20430
|
removeOnlineClient(clientID) {
|
|
19888
20431
|
this.onlineClients.delete(clientID);
|
|
19889
20432
|
}
|
|
20433
|
+
/**
|
|
20434
|
+
* `reconcilePresence` compares the previous and current state of a client's
|
|
20435
|
+
* presence/online status and returns the appropriate event to emit.
|
|
20436
|
+
*
|
|
20437
|
+
* For remote clients, "online" means the client is in onlineClients.
|
|
20438
|
+
* For self, "online" means the document status is Attached.
|
|
20439
|
+
*
|
|
20440
|
+
* State transition table:
|
|
20441
|
+
* (!hadP || !wasOn) → (hasP && isOn) : watched (remote) or presence-changed (self)
|
|
20442
|
+
* (hadP && wasOn) → (hasP && isOn) : presence-changed
|
|
20443
|
+
* (hadP && wasOn) → (!hasP || !isOn): unwatched (remote only)
|
|
20444
|
+
* otherwise : no event (waiting)
|
|
20445
|
+
*/
|
|
20446
|
+
reconcilePresence(actorID, prev, source) {
|
|
20447
|
+
const isSelf = actorID === this.changeID.getActorID();
|
|
20448
|
+
const hasPresence = this.presences.has(actorID);
|
|
20449
|
+
const isOnline = isSelf ? this.status === "attached" : this.onlineClients.has(actorID);
|
|
20450
|
+
if (!hasPresence || !isOnline) {
|
|
20451
|
+
if (prev.hadPresence && prev.wasOnline && !isSelf) {
|
|
20452
|
+
return {
|
|
20453
|
+
type: "unwatched",
|
|
20454
|
+
source: OpSource.Remote,
|
|
20455
|
+
value: {
|
|
20456
|
+
clientID: actorID,
|
|
20457
|
+
presence: prev.presence
|
|
20458
|
+
}
|
|
20459
|
+
};
|
|
20460
|
+
}
|
|
20461
|
+
return void 0;
|
|
20462
|
+
}
|
|
20463
|
+
const presence = deepcopy(this.presences.get(actorID));
|
|
20464
|
+
if (!prev.hadPresence || !prev.wasOnline) {
|
|
20465
|
+
if (isSelf) {
|
|
20466
|
+
return {
|
|
20467
|
+
type: "presence-changed",
|
|
20468
|
+
source,
|
|
20469
|
+
value: { clientID: actorID, presence }
|
|
20470
|
+
};
|
|
20471
|
+
}
|
|
20472
|
+
return {
|
|
20473
|
+
type: "watched",
|
|
20474
|
+
source: OpSource.Remote,
|
|
20475
|
+
value: { clientID: actorID, presence }
|
|
20476
|
+
};
|
|
20477
|
+
}
|
|
20478
|
+
return {
|
|
20479
|
+
type: "presence-changed",
|
|
20480
|
+
source,
|
|
20481
|
+
value: { clientID: actorID, presence }
|
|
20482
|
+
};
|
|
20483
|
+
}
|
|
19890
20484
|
/**
|
|
19891
20485
|
* `hasPresence` returns whether the given clientID has a presence or not.
|
|
19892
20486
|
*/
|
|
@@ -20048,18 +20642,24 @@ class Document {
|
|
|
20048
20642
|
const ticket = ctx.issueTimeTicket();
|
|
20049
20643
|
op.setExecutedAt(ticket);
|
|
20050
20644
|
if (op instanceof ArraySetOperation) {
|
|
20051
|
-
const
|
|
20645
|
+
const prev2 = op.getCreatedAt();
|
|
20052
20646
|
op.getValue().setCreatedAt(ticket);
|
|
20053
|
-
this.internalHistory.reconcileCreatedAt(
|
|
20647
|
+
this.internalHistory.reconcileCreatedAt(prev2, ticket);
|
|
20054
20648
|
} else if (op instanceof AddOperation) {
|
|
20055
|
-
const
|
|
20649
|
+
const prev2 = op.getValue().getCreatedAt();
|
|
20056
20650
|
op.getValue().setCreatedAt(ticket);
|
|
20057
|
-
this.internalHistory.reconcileCreatedAt(
|
|
20651
|
+
this.internalHistory.reconcileCreatedAt(prev2, ticket);
|
|
20058
20652
|
}
|
|
20059
20653
|
ctx.push(op);
|
|
20060
20654
|
}
|
|
20061
20655
|
const change = ctx.toChange();
|
|
20062
20656
|
change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
|
|
20657
|
+
const actorID = this.changeID.getActorID();
|
|
20658
|
+
const prev = {
|
|
20659
|
+
hadPresence: this.presences.has(actorID),
|
|
20660
|
+
wasOnline: this.status === "attached",
|
|
20661
|
+
presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
|
|
20662
|
+
};
|
|
20063
20663
|
const { opInfos, reverseOps } = change.execute(
|
|
20064
20664
|
this.root,
|
|
20065
20665
|
this.presences,
|
|
@@ -20081,7 +20681,6 @@ class Document {
|
|
|
20081
20681
|
}
|
|
20082
20682
|
this.localChanges.push(change);
|
|
20083
20683
|
this.changeID = ctx.getNextID();
|
|
20084
|
-
const actorID = this.changeID.getActorID();
|
|
20085
20684
|
const events = [];
|
|
20086
20685
|
if (opInfos.length) {
|
|
20087
20686
|
events.push({
|
|
@@ -20098,14 +20697,14 @@ class Document {
|
|
|
20098
20697
|
});
|
|
20099
20698
|
}
|
|
20100
20699
|
if (change.hasPresenceChange()) {
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
|
|
20105
|
-
|
|
20106
|
-
|
|
20107
|
-
|
|
20108
|
-
}
|
|
20700
|
+
const presenceEvent = this.reconcilePresence(
|
|
20701
|
+
actorID,
|
|
20702
|
+
prev,
|
|
20703
|
+
OpSource.UndoRedo
|
|
20704
|
+
);
|
|
20705
|
+
if (presenceEvent) {
|
|
20706
|
+
events.push(presenceEvent);
|
|
20707
|
+
}
|
|
20109
20708
|
}
|
|
20110
20709
|
this.publish(events);
|
|
20111
20710
|
}
|
|
@@ -20121,6 +20720,8 @@ class Attachment {
|
|
|
20121
20720
|
watchStream;
|
|
20122
20721
|
watchLoopTimerID;
|
|
20123
20722
|
watchAbortController;
|
|
20723
|
+
syncPromise;
|
|
20724
|
+
_detaching = false;
|
|
20124
20725
|
constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
|
|
20125
20726
|
this.reconnectStreamDelay = reconnectStreamDelay;
|
|
20126
20727
|
this.resource = resource;
|
|
@@ -20196,6 +20797,49 @@ class Attachment {
|
|
|
20196
20797
|
};
|
|
20197
20798
|
await doLoop();
|
|
20198
20799
|
}
|
|
20800
|
+
/**
|
|
20801
|
+
* `markDetaching` marks this attachment as being in the process of detaching.
|
|
20802
|
+
* Once marked, the sync loop will skip this attachment.
|
|
20803
|
+
*/
|
|
20804
|
+
markDetaching() {
|
|
20805
|
+
this._detaching = true;
|
|
20806
|
+
}
|
|
20807
|
+
/**
|
|
20808
|
+
* `isDetaching` returns whether this attachment is being detached.
|
|
20809
|
+
*/
|
|
20810
|
+
isDetaching() {
|
|
20811
|
+
return this._detaching;
|
|
20812
|
+
}
|
|
20813
|
+
/**
|
|
20814
|
+
* `resetDetaching` resets the detaching flag so the attachment can resume
|
|
20815
|
+
* syncing. Used when a detach RPC fails and the document remains attached.
|
|
20816
|
+
*/
|
|
20817
|
+
resetDetaching() {
|
|
20818
|
+
this._detaching = false;
|
|
20819
|
+
}
|
|
20820
|
+
/**
|
|
20821
|
+
* `setSyncPromise` sets the in-progress sync promise for this attachment.
|
|
20822
|
+
*/
|
|
20823
|
+
setSyncPromise(promise) {
|
|
20824
|
+
this.syncPromise = promise;
|
|
20825
|
+
}
|
|
20826
|
+
/**
|
|
20827
|
+
* `clearSyncPromise` clears the in-progress sync promise.
|
|
20828
|
+
*/
|
|
20829
|
+
clearSyncPromise() {
|
|
20830
|
+
this.syncPromise = void 0;
|
|
20831
|
+
}
|
|
20832
|
+
/**
|
|
20833
|
+
* `waitForSyncComplete` waits for any in-progress sync to complete.
|
|
20834
|
+
*/
|
|
20835
|
+
async waitForSyncComplete() {
|
|
20836
|
+
if (this.syncPromise) {
|
|
20837
|
+
try {
|
|
20838
|
+
await this.syncPromise;
|
|
20839
|
+
} catch {
|
|
20840
|
+
}
|
|
20841
|
+
}
|
|
20842
|
+
}
|
|
20199
20843
|
/**
|
|
20200
20844
|
* `cancelWatchStream` cancels the watch stream.
|
|
20201
20845
|
*/
|
|
@@ -20230,7 +20874,7 @@ function createAuthInterceptor(apiKey, token) {
|
|
|
20230
20874
|
};
|
|
20231
20875
|
}
|
|
20232
20876
|
const name = "@yorkie-js/sdk";
|
|
20233
|
-
const version = "0.7.
|
|
20877
|
+
const version = "0.7.7";
|
|
20234
20878
|
const pkg = {
|
|
20235
20879
|
name,
|
|
20236
20880
|
version
|
|
@@ -20555,6 +21199,7 @@ class Client {
|
|
|
20555
21199
|
taskQueue;
|
|
20556
21200
|
processing = false;
|
|
20557
21201
|
keepalive = false;
|
|
21202
|
+
deactivating = false;
|
|
20558
21203
|
/**
|
|
20559
21204
|
* @param rpcAddr - the address of the RPC server.
|
|
20560
21205
|
* @param opts - the options of the client.
|
|
@@ -20624,6 +21269,7 @@ class Client {
|
|
|
20624
21269
|
);
|
|
20625
21270
|
this.id = res.clientId;
|
|
20626
21271
|
this.status = "activated";
|
|
21272
|
+
this.deactivating = false;
|
|
20627
21273
|
this.runSyncLoop();
|
|
20628
21274
|
logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
|
|
20629
21275
|
if (typeof window !== "undefined") {
|
|
@@ -20652,6 +21298,7 @@ class Client {
|
|
|
20652
21298
|
if (this.status === "deactivated") {
|
|
20653
21299
|
return Promise.resolve();
|
|
20654
21300
|
}
|
|
21301
|
+
this.deactivating = true;
|
|
20655
21302
|
const task = async () => {
|
|
20656
21303
|
try {
|
|
20657
21304
|
await this.rpcClient.deactivateClient(
|
|
@@ -20665,6 +21312,7 @@ class Client {
|
|
|
20665
21312
|
logger.info(`[DC] c"${this.getKey()}" deactivated`);
|
|
20666
21313
|
} catch (err) {
|
|
20667
21314
|
logger.error(`[DC] c:"${this.getKey()}" err :`, err);
|
|
21315
|
+
this.deactivating = false;
|
|
20668
21316
|
await this.handleConnectError(err);
|
|
20669
21317
|
throw err;
|
|
20670
21318
|
}
|
|
@@ -20805,8 +21453,10 @@ class Client {
|
|
|
20805
21453
|
);
|
|
20806
21454
|
}
|
|
20807
21455
|
doc.update((_, p) => p.clear());
|
|
21456
|
+
attachment.markDetaching();
|
|
20808
21457
|
const task = async () => {
|
|
20809
21458
|
try {
|
|
21459
|
+
await attachment.waitForSyncComplete();
|
|
20810
21460
|
const res = await this.rpcClient.detachDocument(
|
|
20811
21461
|
{
|
|
20812
21462
|
clientId: this.id,
|
|
@@ -20825,6 +21475,7 @@ class Client {
|
|
|
20825
21475
|
return doc;
|
|
20826
21476
|
} catch (err) {
|
|
20827
21477
|
logger.error(`[DD] c:"${this.getKey()}" err :`, err);
|
|
21478
|
+
attachment.resetDetaching();
|
|
20828
21479
|
await this.handleConnectError(err);
|
|
20829
21480
|
throw err;
|
|
20830
21481
|
}
|
|
@@ -21391,7 +22042,7 @@ class Client {
|
|
|
21391
22042
|
*/
|
|
21392
22043
|
runSyncLoop() {
|
|
21393
22044
|
const doLoop = async () => {
|
|
21394
|
-
if (!this.isActive()) {
|
|
22045
|
+
if (!this.isActive() || this.deactivating) {
|
|
21395
22046
|
logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
|
|
21396
22047
|
this.conditions[
|
|
21397
22048
|
"SyncLoop"
|
|
@@ -21403,43 +22054,62 @@ class Client {
|
|
|
21403
22054
|
await this.enqueueTask(async () => {
|
|
21404
22055
|
const syncs = [];
|
|
21405
22056
|
for (const [, attachment] of this.attachmentMap) {
|
|
22057
|
+
if (this.deactivating) {
|
|
22058
|
+
break;
|
|
22059
|
+
}
|
|
21406
22060
|
if (!attachment.needSync(this.channelHeartbeatInterval)) {
|
|
21407
22061
|
continue;
|
|
21408
22062
|
}
|
|
22063
|
+
if (attachment.isDetaching()) {
|
|
22064
|
+
continue;
|
|
22065
|
+
}
|
|
21409
22066
|
if (attachment.changeEventReceived !== void 0) {
|
|
21410
22067
|
attachment.changeEventReceived = false;
|
|
21411
22068
|
}
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
21415
|
-
|
|
21416
|
-
|
|
21417
|
-
|
|
21418
|
-
|
|
21419
|
-
|
|
21420
|
-
|
|
21421
|
-
|
|
22069
|
+
const syncPromise = this.syncInternal(
|
|
22070
|
+
attachment,
|
|
22071
|
+
attachment.syncMode
|
|
22072
|
+
).then(() => {
|
|
22073
|
+
}).catch((e) => {
|
|
22074
|
+
if (isErrorCode(e, Code.ErrUnauthenticated)) {
|
|
22075
|
+
attachment.resource.publish([
|
|
22076
|
+
{
|
|
22077
|
+
type: DocEventType.AuthError,
|
|
22078
|
+
value: {
|
|
22079
|
+
reason: errorMetadataOf(e).reason,
|
|
22080
|
+
method: "PushPull"
|
|
21422
22081
|
}
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
|
|
21431
|
-
|
|
22082
|
+
}
|
|
22083
|
+
]);
|
|
22084
|
+
}
|
|
22085
|
+
if (isErrorCode(e, Code.ErrEpochMismatch)) {
|
|
22086
|
+
attachment.resource.publish([
|
|
22087
|
+
{
|
|
22088
|
+
type: DocEventType.EpochMismatch,
|
|
22089
|
+
value: {
|
|
22090
|
+
method: "PushPull"
|
|
21432
22091
|
}
|
|
21433
|
-
|
|
21434
|
-
|
|
21435
|
-
|
|
21436
|
-
|
|
21437
|
-
)
|
|
22092
|
+
}
|
|
22093
|
+
]);
|
|
22094
|
+
}
|
|
22095
|
+
throw e;
|
|
22096
|
+
}).finally(() => {
|
|
22097
|
+
attachment.clearSyncPromise();
|
|
22098
|
+
});
|
|
22099
|
+
attachment.setSyncPromise(syncPromise);
|
|
22100
|
+
syncs.push(syncPromise);
|
|
21438
22101
|
}
|
|
21439
22102
|
await Promise.all(syncs);
|
|
21440
22103
|
setTimeout(doLoop, this.syncLoopDuration);
|
|
21441
22104
|
});
|
|
21442
22105
|
} catch (err) {
|
|
22106
|
+
if (this.deactivating) {
|
|
22107
|
+
this.conditions[
|
|
22108
|
+
"SyncLoop"
|
|
22109
|
+
/* SyncLoop */
|
|
22110
|
+
] = false;
|
|
22111
|
+
return;
|
|
22112
|
+
}
|
|
21443
22113
|
logger.error(`[SL] c:"${this.getKey()}" sync failed:`, err);
|
|
21444
22114
|
if (await this.handleConnectError(err)) {
|
|
21445
22115
|
setTimeout(doLoop, this.retrySyncLoopDelay);
|
|
@@ -21920,8 +22590,11 @@ function isBinData(value) {
|
|
|
21920
22590
|
function isCounter(value) {
|
|
21921
22591
|
return typeof value === "object" && value !== null && value.type === "Counter" && typeof value.value === "object";
|
|
21922
22592
|
}
|
|
22593
|
+
function isDedupCounter(value) {
|
|
22594
|
+
return typeof value === "object" && value !== null && value.type === "DedupCounter" && typeof value.value === "object" && typeof value.registers === "string";
|
|
22595
|
+
}
|
|
21923
22596
|
function isObject(value) {
|
|
21924
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && !isText(value) && !isTree(value) && !isInt(value) && !isLong(value) && !isDate(value) && !isBinData(value) && !isCounter(value);
|
|
22597
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !isText(value) && !isTree(value) && !isInt(value) && !isLong(value) && !isDate(value) && !isBinData(value) && !isCounter(value) && !isDedupCounter(value);
|
|
21925
22598
|
}
|
|
21926
22599
|
function parse(yson) {
|
|
21927
22600
|
try {
|
|
@@ -21937,6 +22610,12 @@ function parse(yson) {
|
|
|
21937
22610
|
}
|
|
21938
22611
|
function preprocessYSON(yson) {
|
|
21939
22612
|
let result = yson;
|
|
22613
|
+
result = result.replace(
|
|
22614
|
+
/DedupCounter\(Int\((-?\d+)\),"([^"]+)"\)/g,
|
|
22615
|
+
(_, value, registers) => {
|
|
22616
|
+
return `{"__yson_type":"DedupCounter","__yson_data":{"__yson_type":"Int","__yson_data":${value}},"__yson_registers":"${registers}"}`;
|
|
22617
|
+
}
|
|
22618
|
+
);
|
|
21940
22619
|
result = result.replace(
|
|
21941
22620
|
/Counter\((Int|Long)\((-?\d+)\)\)/g,
|
|
21942
22621
|
(_, type, value) => {
|
|
@@ -21997,6 +22676,20 @@ function postprocessValue(value) {
|
|
|
21997
22676
|
value: value.__yson_data
|
|
21998
22677
|
};
|
|
21999
22678
|
}
|
|
22679
|
+
if (value.__yson_type === "DedupCounter" && typeof value.__yson_data === "object" && typeof value.__yson_registers === "string") {
|
|
22680
|
+
const counterValue = postprocessValue(value.__yson_data);
|
|
22681
|
+
if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && counterValue.type === "Int") {
|
|
22682
|
+
return {
|
|
22683
|
+
type: "DedupCounter",
|
|
22684
|
+
value: counterValue,
|
|
22685
|
+
registers: value.__yson_registers
|
|
22686
|
+
};
|
|
22687
|
+
}
|
|
22688
|
+
throw new YorkieError(
|
|
22689
|
+
Code.ErrInvalidArgument,
|
|
22690
|
+
"DedupCounter must contain Int"
|
|
22691
|
+
);
|
|
22692
|
+
}
|
|
22000
22693
|
if (value.__yson_type === "Counter" && typeof value.__yson_data === "object") {
|
|
22001
22694
|
const counterValue = postprocessValue(value.__yson_data);
|
|
22002
22695
|
if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && (counterValue.type === "Int" || counterValue.type === "Long")) {
|
|
@@ -22085,6 +22778,7 @@ const YSON = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
|
|
|
22085
22778
|
isBinData,
|
|
22086
22779
|
isCounter,
|
|
22087
22780
|
isDate,
|
|
22781
|
+
isDedupCounter,
|
|
22088
22782
|
isInt,
|
|
22089
22783
|
isLong,
|
|
22090
22784
|
isObject,
|