automerge-rb 0.1.1

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.
Files changed (481) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +175 -0
  4. data/ext/automerge_ext/automerge_ext.c +1805 -0
  5. data/ext/automerge_ext/extconf.rb +132 -0
  6. data/lib/automerge/version.rb +6 -0
  7. data/lib/automerge.rb +110 -0
  8. data/rust-toolchain.toml +4 -0
  9. data/vendor/automerge-rust/Cargo.lock +1909 -0
  10. data/vendor/automerge-rust/Cargo.toml +15 -0
  11. data/vendor/automerge-rust/automerge/Cargo.toml +78 -0
  12. data/vendor/automerge-rust/automerge/README.md +5 -0
  13. data/vendor/automerge-rust/automerge/benches/load_save.rs +102 -0
  14. data/vendor/automerge-rust/automerge/benches/map.rs +260 -0
  15. data/vendor/automerge-rust/automerge/benches/range.rs +37 -0
  16. data/vendor/automerge-rust/automerge/benches/sync.rs +95 -0
  17. data/vendor/automerge-rust/automerge/examples/README.md +7 -0
  18. data/vendor/automerge-rust/automerge/examples/quickstart.rs +57 -0
  19. data/vendor/automerge-rust/automerge/examples/watch.rs +94 -0
  20. data/vendor/automerge-rust/automerge/fuzz/Cargo.toml +29 -0
  21. data/vendor/automerge-rust/automerge/fuzz/fuzz_targets/load.rs +37 -0
  22. data/vendor/automerge-rust/automerge/src/autocommit.rs +1286 -0
  23. data/vendor/automerge-rust/automerge/src/automerge/current_state.rs +546 -0
  24. data/vendor/automerge-rust/automerge/src/automerge/tests.rs +2023 -0
  25. data/vendor/automerge-rust/automerge/src/automerge.rs +2071 -0
  26. data/vendor/automerge-rust/automerge/src/autoserde.rs +128 -0
  27. data/vendor/automerge-rust/automerge/src/change.rs +357 -0
  28. data/vendor/automerge-rust/automerge/src/change_graph.rs +1215 -0
  29. data/vendor/automerge-rust/automerge/src/change_queue.rs +46 -0
  30. data/vendor/automerge-rust/automerge/src/clock.rs +206 -0
  31. data/vendor/automerge-rust/automerge/src/columnar/column_range/boolean.rs +83 -0
  32. data/vendor/automerge-rust/automerge/src/columnar/column_range/delta.rs +148 -0
  33. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/group.rs +138 -0
  34. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/simple.rs +76 -0
  35. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic.rs +93 -0
  36. data/vendor/automerge-rust/automerge/src/columnar/column_range/key.rs +272 -0
  37. data/vendor/automerge-rust/automerge/src/columnar/column_range/obj_id.rs +202 -0
  38. data/vendor/automerge-rust/automerge/src/columnar/column_range/opid_list.rs +329 -0
  39. data/vendor/automerge-rust/automerge/src/columnar/column_range/raw.rs +38 -0
  40. data/vendor/automerge-rust/automerge/src/columnar/column_range/rle.rs +216 -0
  41. data/vendor/automerge-rust/automerge/src/columnar/column_range/value.rs +547 -0
  42. data/vendor/automerge-rust/automerge/src/columnar/column_range.rs +17 -0
  43. data/vendor/automerge-rust/automerge/src/columnar/encoding/boolean.rs +197 -0
  44. data/vendor/automerge-rust/automerge/src/columnar/encoding/col_error.rs +88 -0
  45. data/vendor/automerge-rust/automerge/src/columnar/encoding/column_decoder.rs +133 -0
  46. data/vendor/automerge-rust/automerge/src/columnar/encoding/decodable_impls.rs +175 -0
  47. data/vendor/automerge-rust/automerge/src/columnar/encoding/delta.rs +96 -0
  48. data/vendor/automerge-rust/automerge/src/columnar/encoding/encodable_impls.rs +200 -0
  49. data/vendor/automerge-rust/automerge/src/columnar/encoding/leb128.rs +82 -0
  50. data/vendor/automerge-rust/automerge/src/columnar/encoding/properties.rs +178 -0
  51. data/vendor/automerge-rust/automerge/src/columnar/encoding/raw.rs +101 -0
  52. data/vendor/automerge-rust/automerge/src/columnar/encoding/rle.rs +239 -0
  53. data/vendor/automerge-rust/automerge/src/columnar/encoding.rs +67 -0
  54. data/vendor/automerge-rust/automerge/src/columnar/splice_error.rs +47 -0
  55. data/vendor/automerge-rust/automerge/src/columnar.rs +14 -0
  56. data/vendor/automerge-rust/automerge/src/convert.rs +112 -0
  57. data/vendor/automerge-rust/automerge/src/cursor.rs +296 -0
  58. data/vendor/automerge-rust/automerge/src/decoding.rs +475 -0
  59. data/vendor/automerge-rust/automerge/src/error.rs +159 -0
  60. data/vendor/automerge-rust/automerge/src/exid.rs +238 -0
  61. data/vendor/automerge-rust/automerge/src/hydrate/list.rs +140 -0
  62. data/vendor/automerge-rust/automerge/src/hydrate/map.rs +132 -0
  63. data/vendor/automerge-rust/automerge/src/hydrate/tests.rs +40 -0
  64. data/vendor/automerge-rust/automerge/src/hydrate/text.rs +89 -0
  65. data/vendor/automerge-rust/automerge/src/hydrate.rs +368 -0
  66. data/vendor/automerge-rust/automerge/src/indexed_cache.rs +113 -0
  67. data/vendor/automerge-rust/automerge/src/iter/doc.rs +603 -0
  68. data/vendor/automerge-rust/automerge/src/iter/keys.rs +93 -0
  69. data/vendor/automerge-rust/automerge/src/iter/list_range.rs +433 -0
  70. data/vendor/automerge-rust/automerge/src/iter/map_range.rs +316 -0
  71. data/vendor/automerge-rust/automerge/src/iter/spans.rs +601 -0
  72. data/vendor/automerge-rust/automerge/src/iter/tools.rs +427 -0
  73. data/vendor/automerge-rust/automerge/src/iter/values.rs +36 -0
  74. data/vendor/automerge-rust/automerge/src/iter.rs +25 -0
  75. data/vendor/automerge-rust/automerge/src/legacy/mod.rs +364 -0
  76. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/actor_id.rs +25 -0
  77. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/change_hash.rs +29 -0
  78. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/element_id.rs +27 -0
  79. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/mod.rs +31 -0
  80. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/object_id.rs +36 -0
  81. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op.rs +668 -0
  82. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op_type.rs +26 -0
  83. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/opid.rs +25 -0
  84. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/scalar_value.rs +63 -0
  85. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/element_id.rs +66 -0
  86. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/key.rs +49 -0
  87. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/mod.rs +4 -0
  88. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/object_id.rs +74 -0
  89. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/opid.rs +68 -0
  90. data/vendor/automerge-rust/automerge/src/lib.rs +315 -0
  91. data/vendor/automerge-rust/automerge/src/marks.rs +478 -0
  92. data/vendor/automerge-rust/automerge/src/op_set2/change/batch.rs +2002 -0
  93. data/vendor/automerge-rust/automerge/src/op_set2/change/collector.rs +974 -0
  94. data/vendor/automerge-rust/automerge/src/op_set2/change.rs +332 -0
  95. data/vendor/automerge-rust/automerge/src/op_set2/columns.rs +714 -0
  96. data/vendor/automerge-rust/automerge/src/op_set2/meta.rs +174 -0
  97. data/vendor/automerge-rust/automerge/src/op_set2/op.rs +1363 -0
  98. data/vendor/automerge-rust/automerge/src/op_set2/op_set/elems.rs +43 -0
  99. data/vendor/automerge-rust/automerge/src/op_set2/op_set/found_op.rs +60 -0
  100. data/vendor/automerge-rust/automerge/src/op_set2/op_set/index.rs +197 -0
  101. data/vendor/automerge-rust/automerge/src/op_set2/op_set/insert.rs +179 -0
  102. data/vendor/automerge-rust/automerge/src/op_set2/op_set/mark_index.rs +292 -0
  103. data/vendor/automerge-rust/automerge/src/op_set2/op_set/marks.rs +86 -0
  104. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_iter.rs +1295 -0
  105. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_query.rs +82 -0
  106. data/vendor/automerge-rust/automerge/src/op_set2/op_set/top_op.rs +50 -0
  107. data/vendor/automerge-rust/automerge/src/op_set2/op_set/visible.rs +290 -0
  108. data/vendor/automerge-rust/automerge/src/op_set2/op_set.rs +1793 -0
  109. data/vendor/automerge-rust/automerge/src/op_set2/parents.rs +133 -0
  110. data/vendor/automerge-rust/automerge/src/op_set2/skip_list.rs +714 -0
  111. data/vendor/automerge-rust/automerge/src/op_set2/types.rs +769 -0
  112. data/vendor/automerge-rust/automerge/src/op_set2.rs +18 -0
  113. data/vendor/automerge-rust/automerge/src/patches/patch.rs +95 -0
  114. data/vendor/automerge-rust/automerge/src/patches/patch_builder.rs +382 -0
  115. data/vendor/automerge-rust/automerge/src/patches/patch_log.rs +584 -0
  116. data/vendor/automerge-rust/automerge/src/patches.rs +7 -0
  117. data/vendor/automerge-rust/automerge/src/query/list_state.rs +230 -0
  118. data/vendor/automerge-rust/automerge/src/query/seek_mark.rs +142 -0
  119. data/vendor/automerge-rust/automerge/src/read.rs +326 -0
  120. data/vendor/automerge-rust/automerge/src/sequence_tree.rs +662 -0
  121. data/vendor/automerge-rust/automerge/src/storage/bundle/builder.rs +942 -0
  122. data/vendor/automerge-rust/automerge/src/storage/bundle/error.rs +42 -0
  123. data/vendor/automerge-rust/automerge/src/storage/bundle/meta.rs +23 -0
  124. data/vendor/automerge-rust/automerge/src/storage/bundle/storage.rs +146 -0
  125. data/vendor/automerge-rust/automerge/src/storage/bundle.rs +210 -0
  126. data/vendor/automerge-rust/automerge/src/storage/change/change_actors.rs +311 -0
  127. data/vendor/automerge-rust/automerge/src/storage/change/change_op_columns.rs +621 -0
  128. data/vendor/automerge-rust/automerge/src/storage/change/compressed.rs +51 -0
  129. data/vendor/automerge-rust/automerge/src/storage/change/op_with_change_actors.rs +1 -0
  130. data/vendor/automerge-rust/automerge/src/storage/change.rs +523 -0
  131. data/vendor/automerge-rust/automerge/src/storage/chunk.rs +312 -0
  132. data/vendor/automerge-rust/automerge/src/storage/columns/column.rs +42 -0
  133. data/vendor/automerge-rust/automerge/src/storage/columns/column_builder.rs +199 -0
  134. data/vendor/automerge-rust/automerge/src/storage/columns/column_specification.rs +340 -0
  135. data/vendor/automerge-rust/automerge/src/storage/columns/raw_column.rs +286 -0
  136. data/vendor/automerge-rust/automerge/src/storage/columns.rs +355 -0
  137. data/vendor/automerge-rust/automerge/src/storage/document/compression.rs +362 -0
  138. data/vendor/automerge-rust/automerge/src/storage/document.rs +411 -0
  139. data/vendor/automerge-rust/automerge/src/storage/load/change_collector.rs +15 -0
  140. data/vendor/automerge-rust/automerge/src/storage/load.rs +136 -0
  141. data/vendor/automerge-rust/automerge/src/storage/parse/leb128.rs +302 -0
  142. data/vendor/automerge-rust/automerge/src/storage/parse.rs +619 -0
  143. data/vendor/automerge-rust/automerge/src/storage/save/document.rs +27 -0
  144. data/vendor/automerge-rust/automerge/src/storage.rs +26 -0
  145. data/vendor/automerge-rust/automerge/src/sync/bloom.rs +161 -0
  146. data/vendor/automerge-rust/automerge/src/sync/message_builder.rs +118 -0
  147. data/vendor/automerge-rust/automerge/src/sync/state.rs +214 -0
  148. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/bloom.rs +162 -0
  149. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/mod.rs +625 -0
  150. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/state.rs +120 -0
  151. data/vendor/automerge-rust/automerge/src/sync.rs +2482 -0
  152. data/vendor/automerge-rust/automerge/src/text_diff/LICENSE +201 -0
  153. data/vendor/automerge-rust/automerge/src/text_diff/myers.rs +332 -0
  154. data/vendor/automerge-rust/automerge/src/text_diff/replace.rs +139 -0
  155. data/vendor/automerge-rust/automerge/src/text_diff/utils.rs +119 -0
  156. data/vendor/automerge-rust/automerge/src/text_diff.rs +515 -0
  157. data/vendor/automerge-rust/automerge/src/text_value.rs +276 -0
  158. data/vendor/automerge-rust/automerge/src/transaction/commit.rs +34 -0
  159. data/vendor/automerge-rust/automerge/src/transaction/inner.rs +1403 -0
  160. data/vendor/automerge-rust/automerge/src/transaction/manual_transaction.rs +147 -0
  161. data/vendor/automerge-rust/automerge/src/transaction/owned_transaction.rs +266 -0
  162. data/vendor/automerge-rust/automerge/src/transaction/result.rs +21 -0
  163. data/vendor/automerge-rust/automerge/src/transaction/transactable.rs +203 -0
  164. data/vendor/automerge-rust/automerge/src/transaction.rs +513 -0
  165. data/vendor/automerge-rust/automerge/src/types.rs +749 -0
  166. data/vendor/automerge-rust/automerge/src/validation.rs +29 -0
  167. data/vendor/automerge-rust/automerge/src/value.rs +763 -0
  168. data/vendor/automerge-rust/automerge/tests/batch_insert.rs +1034 -0
  169. data/vendor/automerge-rust/automerge/tests/block_tests.rs +887 -0
  170. data/vendor/automerge-rust/automerge/tests/convert_string_to_text.rs +72 -0
  171. data/vendor/automerge-rust/automerge/tests/diff_marks.rs +1508 -0
  172. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_change.automerge +0 -0
  173. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_doc.automerge +0 -0
  174. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_has_incorrect_meta.automerge +0 -0
  175. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_ok.automerge +0 -0
  176. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_overlong.automerge +0 -0
  177. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks.automerge +0 -0
  178. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_compressed.automerge +0 -0
  179. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_out_of_order.automerge +0 -0
  180. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/action-is-48.automerge +0 -0
  181. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709 +0 -0
  182. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/incorrect_max_op.automerge +0 -0
  183. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/invalid_deflate_stream.automerge +0 -0
  184. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/missing_actor.automerge +0 -0
  185. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/overflow_in_length.automerge +0 -0
  186. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_deps.automerge +0 -0
  187. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_ops.automerge +0 -0
  188. data/vendor/automerge-rust/automerge/tests/test.rs +2668 -0
  189. data/vendor/automerge-rust/automerge/tests/test_mark_patches.rs +41 -0
  190. data/vendor/automerge-rust/automerge/tests/test_save_load_orphans.rs +84 -0
  191. data/vendor/automerge-rust/automerge/tests/text.rs +1098 -0
  192. data/vendor/automerge-rust/automerge/tests/text_encoding.rs +640 -0
  193. data/vendor/automerge-rust/automerge-c/CMakeLists.txt +439 -0
  194. data/vendor/automerge-rust/automerge-c/Cargo.toml +22 -0
  195. data/vendor/automerge-rust/automerge-c/README.md +233 -0
  196. data/vendor/automerge-rust/automerge-c/build.rs +21 -0
  197. data/vendor/automerge-rust/automerge-c/cbindgen.toml +48 -0
  198. data/vendor/automerge-rust/automerge-c/cmake/Cargo.toml.in +22 -0
  199. data/vendor/automerge-rust/automerge-c/cmake/automerge-c-config.cmake.in +99 -0
  200. data/vendor/automerge-rust/automerge-c/cmake/cbindgen.toml.in +48 -0
  201. data/vendor/automerge-rust/automerge-c/cmake/config.h.in +58 -0
  202. data/vendor/automerge-rust/automerge-c/cmake/enum-string-functions-gen.cmake +183 -0
  203. data/vendor/automerge-rust/automerge-c/cmake/file-regex-replace.cmake +33 -0
  204. data/vendor/automerge-rust/automerge-c/cmake/file-touch.cmake +35 -0
  205. data/vendor/automerge-rust/automerge-c/docs/CMakeLists.txt +39 -0
  206. data/vendor/automerge-rust/automerge-c/docs/img/brandmark.png +0 -0
  207. data/vendor/automerge-rust/automerge-c/examples/CMakeLists.txt +42 -0
  208. data/vendor/automerge-rust/automerge-c/examples/README.md +9 -0
  209. data/vendor/automerge-rust/automerge-c/examples/quickstart.c +131 -0
  210. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/result.h +30 -0
  211. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack.h +130 -0
  212. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack_callback_data.h +53 -0
  213. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/string.h +29 -0
  214. data/vendor/automerge-rust/automerge-c/src/actor_id.rs +193 -0
  215. data/vendor/automerge-rust/automerge-c/src/byte_span.rs +227 -0
  216. data/vendor/automerge-rust/automerge-c/src/change.rs +356 -0
  217. data/vendor/automerge-rust/automerge-c/src/cursor.rs +168 -0
  218. data/vendor/automerge-rust/automerge-c/src/doc/list.rs +636 -0
  219. data/vendor/automerge-rust/automerge-c/src/doc/map.rs +556 -0
  220. data/vendor/automerge-rust/automerge-c/src/doc/mark.rs +296 -0
  221. data/vendor/automerge-rust/automerge-c/src/doc/utils.rs +46 -0
  222. data/vendor/automerge-rust/automerge-c/src/doc.rs +1009 -0
  223. data/vendor/automerge-rust/automerge-c/src/index.rs +84 -0
  224. data/vendor/automerge-rust/automerge-c/src/item.rs +2177 -0
  225. data/vendor/automerge-rust/automerge-c/src/items.rs +401 -0
  226. data/vendor/automerge-rust/automerge-c/src/lib.rs +11 -0
  227. data/vendor/automerge-rust/automerge-c/src/obj.rs +216 -0
  228. data/vendor/automerge-rust/automerge-c/src/result.rs +653 -0
  229. data/vendor/automerge-rust/automerge-c/src/sync/have.rs +42 -0
  230. data/vendor/automerge-rust/automerge-c/src/sync/message.rs +146 -0
  231. data/vendor/automerge-rust/automerge-c/src/sync/state.rs +262 -0
  232. data/vendor/automerge-rust/automerge-c/src/sync.rs +7 -0
  233. data/vendor/automerge-rust/automerge-c/src/utils/result.c +33 -0
  234. data/vendor/automerge-rust/automerge-c/src/utils/stack.c +106 -0
  235. data/vendor/automerge-rust/automerge-c/src/utils/stack_callback_data.c +9 -0
  236. data/vendor/automerge-rust/automerge-c/src/utils/string.c +46 -0
  237. data/vendor/automerge-rust/automerge-c/test/CMakeLists.txt +67 -0
  238. data/vendor/automerge-rust/automerge-c/test/actor_id_tests.c +140 -0
  239. data/vendor/automerge-rust/automerge-c/test/base_state.c +17 -0
  240. data/vendor/automerge-rust/automerge-c/test/base_state.h +39 -0
  241. data/vendor/automerge-rust/automerge-c/test/byte_span_tests.c +119 -0
  242. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.c +91 -0
  243. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.h +42 -0
  244. data/vendor/automerge-rust/automerge-c/test/cursor_tests.c +263 -0
  245. data/vendor/automerge-rust/automerge-c/test/doc_state.c +27 -0
  246. data/vendor/automerge-rust/automerge-c/test/doc_state.h +17 -0
  247. data/vendor/automerge-rust/automerge-c/test/doc_tests.c +335 -0
  248. data/vendor/automerge-rust/automerge-c/test/enum_string_tests.c +148 -0
  249. data/vendor/automerge-rust/automerge-c/test/files/brave-ape-49.automerge +0 -0
  250. data/vendor/automerge-rust/automerge-c/test/item_tests.c +313 -0
  251. data/vendor/automerge-rust/automerge-c/test/list_tests.c +544 -0
  252. data/vendor/automerge-rust/automerge-c/test/macro_utils.c +38 -0
  253. data/vendor/automerge-rust/automerge-c/test/macro_utils.h +23 -0
  254. data/vendor/automerge-rust/automerge-c/test/main.c +33 -0
  255. data/vendor/automerge-rust/automerge-c/test/map_tests.c +1610 -0
  256. data/vendor/automerge-rust/automerge-c/test/mark_tests.c +124 -0
  257. data/vendor/automerge-rust/automerge-c/test/ported_wasm/basic_tests.c +1642 -0
  258. data/vendor/automerge-rust/automerge-c/test/ported_wasm/cursor_tests.c +108 -0
  259. data/vendor/automerge-rust/automerge-c/test/ported_wasm/suite.c +17 -0
  260. data/vendor/automerge-rust/automerge-c/test/ported_wasm/sync_tests.c +1280 -0
  261. data/vendor/automerge-rust/automerge-c/test/str_utils.c +15 -0
  262. data/vendor/automerge-rust/automerge-c/test/str_utils.h +17 -0
  263. data/vendor/automerge-rust/automerge-test/Cargo.toml +17 -0
  264. data/vendor/automerge-rust/automerge-test/README.md +3 -0
  265. data/vendor/automerge-rust/automerge-test/src/lib.rs +487 -0
  266. data/vendor/automerge-rust/hexane/CHANGELOG.md +34 -0
  267. data/vendor/automerge-rust/hexane/Cargo.toml +47 -0
  268. data/vendor/automerge-rust/hexane/README.md +292 -0
  269. data/vendor/automerge-rust/hexane/RESULTS.txt +20 -0
  270. data/vendor/automerge-rust/hexane/TODO +18 -0
  271. data/vendor/automerge-rust/hexane/benches/insert.rs +82 -0
  272. data/vendor/automerge-rust/hexane/benches/seek.rs +77 -0
  273. data/vendor/automerge-rust/hexane/benches/splice.rs +82 -0
  274. data/vendor/automerge-rust/hexane/src/aggregate.rs +288 -0
  275. data/vendor/automerge-rust/hexane/src/boolean.rs +478 -0
  276. data/vendor/automerge-rust/hexane/src/columndata.rs +2540 -0
  277. data/vendor/automerge-rust/hexane/src/cursor.rs +756 -0
  278. data/vendor/automerge-rust/hexane/src/delta.rs +793 -0
  279. data/vendor/automerge-rust/hexane/src/encoder.rs +639 -0
  280. data/vendor/automerge-rust/hexane/src/leb128.rs +82 -0
  281. data/vendor/automerge-rust/hexane/src/lib.rs +95 -0
  282. data/vendor/automerge-rust/hexane/src/pack.rs +325 -0
  283. data/vendor/automerge-rust/hexane/src/raw.rs +314 -0
  284. data/vendor/automerge-rust/hexane/src/rle.rs +928 -0
  285. data/vendor/automerge-rust/hexane/src/slab/tree.rs +1373 -0
  286. data/vendor/automerge-rust/hexane/src/slab/writer.rs +535 -0
  287. data/vendor/automerge-rust/hexane/src/slab.rs +224 -0
  288. data/vendor/automerge-rust/hexane/src/test.rs +108 -0
  289. data/vendor/bundle/ruby/3.3.0/bin/rake +29 -0
  290. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler +29 -0
  291. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler-dock +29 -0
  292. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/History.rdoc +1732 -0
  293. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Manifest.txt +32 -0
  294. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/README.rdoc +845 -0
  295. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Rakefile +97 -0
  296. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/design_rationale.rb +54 -0
  297. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/hoe/minitest.rb +30 -0
  298. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/assertions.rb +850 -0
  299. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/autorun.rb +6 -0
  300. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/benchmark.rb +452 -0
  301. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/compress.rb +94 -0
  302. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/error_on_warning.rb +11 -0
  303. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/expectations.rb +321 -0
  304. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/hell.rb +11 -0
  305. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/manual_plugins.rb +16 -0
  306. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/mock.rb +327 -0
  307. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/parallel.rb +72 -0
  308. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride.rb +4 -0
  309. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride_plugin.rb +135 -0
  310. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/spec.rb +353 -0
  311. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test.rb +238 -0
  312. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test_task.rb +324 -0
  313. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/unit.rb +42 -0
  314. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest.rb +1250 -0
  315. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/metametameta.rb +150 -0
  316. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_assertions.rb +1677 -0
  317. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_benchmark.rb +137 -0
  318. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_mock.rb +1213 -0
  319. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_reporter.rb +437 -0
  320. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_spec.rb +1159 -0
  321. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test.rb +1374 -0
  322. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test_task.rb +57 -0
  323. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/History.rdoc +2454 -0
  324. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
  325. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/README.rdoc +155 -0
  326. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/command_line_usage.rdoc +171 -0
  327. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile1 +38 -0
  328. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile2 +35 -0
  329. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/a.c +6 -0
  330. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/b.c +6 -0
  331. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/main.c +11 -0
  332. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/glossary.rdoc +42 -0
  333. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/jamis.rb +592 -0
  334. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/proto_rake.rdoc +127 -0
  335. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rake.1 +156 -0
  336. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rakefile.rdoc +635 -0
  337. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rational.rdoc +151 -0
  338. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/exe/rake +27 -0
  339. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/application.rb +847 -0
  340. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/backtrace.rb +25 -0
  341. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/clean.rb +78 -0
  342. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cloneable.rb +17 -0
  343. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb +122 -0
  344. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/default_loader.rb +15 -0
  345. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb +196 -0
  346. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/early_time.rb +22 -0
  347. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/core.rb +26 -0
  348. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/string.rb +176 -0
  349. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb +25 -0
  350. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_list.rb +435 -0
  351. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_task.rb +58 -0
  352. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils.rb +137 -0
  353. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb +135 -0
  354. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb +57 -0
  355. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb +17 -0
  356. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/late_time.rb +18 -0
  357. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/linked_list.rb +112 -0
  358. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb +54 -0
  359. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/multi_task.rb +14 -0
  360. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/name_space.rb +38 -0
  361. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/options.rb +31 -0
  362. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/packagetask.rb +222 -0
  363. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/phony.rb +16 -0
  364. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/private_reader.rb +21 -0
  365. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/promise.rb +100 -0
  366. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb +30 -0
  367. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_module.rb +67 -0
  368. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb +27 -0
  369. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  370. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/scope.rb +43 -0
  371. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task.rb +434 -0
  372. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb +8 -0
  373. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_arguments.rb +113 -0
  374. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_manager.rb +333 -0
  375. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/tasklib.rb +12 -0
  376. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/testtask.rb +192 -0
  377. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb +49 -0
  378. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_pool.rb +157 -0
  379. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/trace_output.rb +23 -0
  380. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/version.rb +10 -0
  381. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/win32.rb +17 -0
  382. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake.rb +69 -0
  383. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/rake.gemspec +102 -0
  384. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Gemfile +8 -0
  385. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/History.md +695 -0
  386. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/LICENSE.txt +20 -0
  387. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/README.md +476 -0
  388. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Rakefile +15 -0
  389. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/appveyor.yml +22 -0
  390. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/bin/rake-compiler +24 -0
  391. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/cucumber.yml +4 -0
  392. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/compile.feature +79 -0
  393. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-compile.feature +23 -0
  394. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package-multi.feature +15 -0
  395. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package.feature +14 -0
  396. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-compile.feature +22 -0
  397. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-no-native-compile.feature +33 -0
  398. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-package.feature +24 -0
  399. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/package.feature +40 -0
  400. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/compilation.rb +70 -0
  401. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/cross_compilation.rb +27 -0
  402. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/execution.rb +52 -0
  403. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/folders.rb +32 -0
  404. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/gem.rb +46 -0
  405. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/java_compilation.rb +7 -0
  406. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/env.rb +10 -0
  407. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/file_template_helpers.rb +137 -0
  408. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/generator_helpers.rb +123 -0
  409. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/platform_extension_helpers.rb +27 -0
  410. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/baseextensiontask.rb +90 -0
  411. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/compiler_config.rb +38 -0
  412. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensioncompiler.rb +51 -0
  413. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensiontask.rb +589 -0
  414. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/javaextensiontask.rb +321 -0
  415. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bin/cross-ruby.rake +189 -0
  416. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bootstrap.rake +11 -0
  417. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/common.rake +10 -0
  418. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/cucumber.rake +23 -0
  419. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/gem.rake +15 -0
  420. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/rspec.rake +9 -0
  421. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CHANGELOG.md +446 -0
  422. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CONTRIBUTING.md +109 -0
  423. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.jruby +79 -0
  424. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.mri.erb +282 -0
  425. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Gemfile +8 -0
  426. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/LICENSE.txt +22 -0
  427. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/README.md +447 -0
  428. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Rakefile +246 -0
  429. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/bin/rake-compiler-dock +18 -0
  430. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/buildkitd.toml +2 -0
  431. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/gem_helper.rb +54 -0
  432. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_i686.rb +18 -0
  433. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_musl_cross.sh +37 -0
  434. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_osxcross.sh +45 -0
  435. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_pkg_config.sh +24 -0
  436. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/parallel_docker_build.rb +169 -0
  437. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0004-Enable-build-of-static-libruby.patch +38 -0
  438. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0005-build-miniruby-first.patch +16 -0
  439. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0006-ruby-4-rubyspec-capiext.patch +16 -0
  440. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/rcd-env.sh +6 -0
  441. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/runas +7 -0
  442. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sigfw.c +45 -0
  443. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_codesign +17 -0
  444. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_vbox +30 -0
  445. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sudoers +1 -0
  446. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/colors.rb +43 -0
  447. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/docker_check.rb +356 -0
  448. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
  449. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/starter.rb +206 -0
  450. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/version.rb +4 -0
  451. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock.rb +151 -0
  452. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/Dockerfile +66 -0
  453. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/README.md +14 -0
  454. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/binutils-mingw-w64-ignore-check-errors.patch +13 -0
  455. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/gcc-mingw-w64-only-c-c++.patch +13 -0
  456. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/mingw-w64-enable-ucrt.patch +22 -0
  457. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/rake-compiler-dock.gemspec +34 -0
  458. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.alpine +17 -0
  459. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.debian +24 -0
  460. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/fixtures/mig_test_rpc.defs +8 -0
  461. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Gemfile +11 -0
  462. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Rakefile +97 -0
  463. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RcdTestExtService.java +19 -0
  464. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RubyRcdTest.java +16 -0
  465. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/extconf.rb +111 -0
  466. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.c +65 -0
  467. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.h +11 -0
  468. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/lib/rcd_test.rb +6 -0
  469. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/rcd_test.gemspec +28 -0
  470. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/test/test_basic.rb +49 -0
  471. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_environment_variables.rb +108 -0
  472. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_mig.rb +18 -0
  473. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_parallel_docker_build.rb +95 -0
  474. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_rubygems_plugins.rb +12 -0
  475. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_starter.rb +158 -0
  476. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_versions.rb +82 -0
  477. data/vendor/bundle/ruby/3.3.0/specifications/minitest-5.27.0.gemspec +32 -0
  478. data/vendor/bundle/ruby/3.3.0/specifications/rake-13.4.2.gemspec +26 -0
  479. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-1.3.1.gemspec +33 -0
  480. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-dock-1.12.0.gemspec +28 -0
  481. metadata +584 -0
@@ -0,0 +1,2071 @@
1
+ use std::cmp::Ordering;
2
+ use std::collections::{BTreeSet, HashSet};
3
+ use std::env;
4
+ use std::fmt::Debug;
5
+ use std::num::NonZeroU64;
6
+ use std::ops::RangeBounds;
7
+
8
+ use itertools::Itertools;
9
+
10
+ pub(crate) use crate::op_set2::change::ChangeCollector;
11
+ pub(crate) use crate::op_set2::types::ScalarValue;
12
+ pub(crate) use crate::op_set2::{
13
+ ChangeMetadata, KeyRef, OpQuery, OpQueryTerm, OpSet, OpType, Parents,
14
+ };
15
+ pub(crate) use crate::read::ReadDoc;
16
+
17
+ use crate::change_graph::ChangeGraph;
18
+ use crate::change_queue::ChangeQueue;
19
+ use crate::cursor::{CursorPosition, MoveCursor, OpCursor};
20
+ use crate::exid::ExId;
21
+ use crate::iter::{DiffIter, DocIter, Keys, ListRange, MapRange, Spans, Values};
22
+ use crate::marks::{Mark, MarkAccumulator, MarkSet};
23
+ use crate::patches::{Patch, PatchLog};
24
+ use crate::storage::{self, change, load, Bundle, CompressConfig, Document, VerificationMode};
25
+ use crate::transaction::{
26
+ self, CommitOptions, Failure, OwnedTransaction, Success, Transactable, Transaction,
27
+ TransactionArgs,
28
+ };
29
+
30
+ use crate::clock::{Clock, ClockRange};
31
+ use crate::hydrate;
32
+ use crate::types::{ActorId, ChangeHash, ObjId, ObjMeta, OpId, SequenceType, TextEncoding, Value};
33
+ use crate::{AutomergeError, Change, Cursor, ObjType, Prop};
34
+
35
+ pub(crate) mod current_state;
36
+
37
+ // FIXME
38
+ //#[cfg(test)]
39
+ //mod tests;
40
+
41
+ #[derive(Debug, Clone, PartialEq)]
42
+ pub(crate) enum Actor {
43
+ Unused(ActorId),
44
+ Cached(usize),
45
+ }
46
+
47
+ impl Actor {
48
+ fn remove_actor(&mut self, index: usize, actors: &[ActorId]) {
49
+ if let Actor::Cached(idx) = self {
50
+ match (*idx).cmp(&index) {
51
+ Ordering::Equal => *self = Actor::Unused(actors[index].clone()),
52
+ Ordering::Greater => *idx -= 1,
53
+ Ordering::Less => (),
54
+ }
55
+ }
56
+ }
57
+
58
+ fn rewrite_with_new_actor(&mut self, index: usize) {
59
+ if let Actor::Cached(idx) = self {
60
+ if *idx >= index {
61
+ *idx += 1;
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ /// What to do when loading a document partially succeeds
68
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
69
+ pub enum OnPartialLoad {
70
+ /// Ignore the error and return the loaded changes
71
+ Ignore,
72
+ /// Fail the entire load
73
+ Error,
74
+ }
75
+
76
+ /// Whether to convert [`ScalarValue::Str`]s in the loaded document to [`ObjType::Text`]
77
+ #[derive(Debug)]
78
+ pub enum StringMigration {
79
+ /// Don't convert anything
80
+ NoMigration,
81
+ /// Convert all strings to text
82
+ ConvertToText,
83
+ }
84
+
85
+ #[derive(Debug)]
86
+ pub struct LoadOptions<'a> {
87
+ on_partial_load: OnPartialLoad,
88
+ verification_mode: VerificationMode,
89
+ string_migration: StringMigration,
90
+ patch_log: Option<&'a mut PatchLog>,
91
+ text_encoding: TextEncoding,
92
+ }
93
+
94
+ impl<'a> LoadOptions<'a> {
95
+ pub fn new() -> LoadOptions<'static> {
96
+ LoadOptions::default()
97
+ }
98
+
99
+ /// What to do when loading a document partially succeeds
100
+ ///
101
+ /// The default is [`OnPartialLoad::Error`]
102
+ pub fn on_partial_load(self, on_partial_load: OnPartialLoad) -> Self {
103
+ Self {
104
+ on_partial_load,
105
+ ..self
106
+ }
107
+ }
108
+
109
+ /// Whether to verify the head hashes after loading
110
+ ///
111
+ /// The default is [`VerificationMode::Check`]
112
+ pub fn verification_mode(self, verification_mode: VerificationMode) -> Self {
113
+ Self {
114
+ verification_mode,
115
+ ..self
116
+ }
117
+ }
118
+
119
+ /// A [`PatchLog`] to log the changes required to materialize the current state of the
120
+ ///
121
+ /// The default is to not log patches
122
+ pub fn patch_log(self, patch_log: &'a mut PatchLog) -> Self {
123
+ Self {
124
+ patch_log: Some(patch_log),
125
+ ..self
126
+ }
127
+ }
128
+
129
+ /// Whether to convert [`ScalarValue::Str`]s in the loaded document to [`ObjType::Text`]
130
+ ///
131
+ /// Until version 2.1.0 of the javascript library strings (as in, the native string of the JS
132
+ /// runtime) were represented in the document as [`ScalarValue::Str`] and there was a special
133
+ /// JS class called `Text` which users were expected to use for [`ObjType::Text`]. In `2.1.0`
134
+ /// we changed this so that native strings were represented as [`ObjType::Text`] and
135
+ /// [`ScalarValue::Str`] was represented as a special `RawString` class. This means
136
+ /// that upgrading the application code to use the new API would require either
137
+ ///
138
+ /// a) Maintaining two code paths in the application to deal with both `string` and `RawString`
139
+ /// types
140
+ /// b) Writing a migration script to convert all `RawString` types to `string`
141
+ ///
142
+ /// The latter is logic which is the same for all applications so we implement it in the
143
+ /// library for convenience. The way this works is that after loading the document we iterate
144
+ /// through all visible [`ScalarValue::Str`] values and emit a change which creates a new
145
+ /// [`ObjType::Text`] at the same path with the same content.
146
+ pub fn migrate_strings(self, migration: StringMigration) -> Self {
147
+ Self {
148
+ string_migration: migration,
149
+ ..self
150
+ }
151
+ }
152
+
153
+ pub fn text_encoding(self, text_encoding: TextEncoding) -> Self {
154
+ Self {
155
+ text_encoding,
156
+ ..self
157
+ }
158
+ }
159
+ }
160
+
161
+ impl std::default::Default for LoadOptions<'static> {
162
+ fn default() -> Self {
163
+ Self {
164
+ on_partial_load: OnPartialLoad::Error,
165
+ verification_mode: VerificationMode::Check,
166
+ patch_log: None,
167
+ string_migration: StringMigration::NoMigration,
168
+ text_encoding: TextEncoding::platform_default(),
169
+ }
170
+ }
171
+ }
172
+
173
+ /// An automerge document which does not manage transactions for you.
174
+ ///
175
+ /// ## Creating, loading, merging and forking documents
176
+ ///
177
+ /// A new document can be created with [`Self::new()`], which will create a document with a random
178
+ /// [`ActorId`]. Existing documents can be loaded with [`Self::load()`], or [`Self::load_with()`].
179
+ ///
180
+ /// If you have two documents and you want to merge the changes from one into the other you can use
181
+ /// [`Self::merge()`] or [`Self::merge_and_log_patches()`].
182
+ ///
183
+ /// If you have a document you want to split into two concurrent threads of execution you can use
184
+ /// [`Self::fork()`]. If you want to split a document from ealier in its history you can use
185
+ /// [`Self::fork_at()`].
186
+ ///
187
+ /// ## Reading values
188
+ ///
189
+ /// [`Self`] implements [`ReadDoc`], which provides methods for reading values from the document.
190
+ ///
191
+ /// ## Modifying a document (Transactions)
192
+ ///
193
+ /// [`Automerge`] provides an interface for viewing and modifying automerge documents which does
194
+ /// not manage transactions for you. To create changes you use either [`Automerge::transaction()`] or
195
+ /// [`Automerge::transact()`] (or the `_with` variants).
196
+ ///
197
+ /// ## Sync
198
+ ///
199
+ /// This type implements [`crate::sync::SyncDoc`]
200
+ ///
201
+ #[derive(Debug, Clone)]
202
+ pub struct Automerge {
203
+ /// The list of unapplied changes that are not causally ready.
204
+ pub(crate) queue: ChangeQueue,
205
+ /// Graph of changes
206
+ pub(crate) change_graph: ChangeGraph,
207
+ /// Current dependencies of this document (heads hashes).
208
+ deps: HashSet<ChangeHash>,
209
+ /// The set of operations that form this document.
210
+ pub(crate) ops: OpSet,
211
+ /// The current actor.
212
+ actor: Actor,
213
+ }
214
+
215
+ impl Automerge {
216
+ /// Create a new document with a random actor id.
217
+ pub fn new() -> Self {
218
+ Automerge {
219
+ queue: ChangeQueue::new(),
220
+ change_graph: ChangeGraph::new(0),
221
+ ops: OpSet::new(TextEncoding::platform_default()),
222
+ deps: Default::default(),
223
+ actor: Actor::Unused(ActorId::random()),
224
+ }
225
+ }
226
+
227
+ /// Overwrite the keys of the root object with the values from `value`
228
+ ///
229
+ /// This is useful to initialize an empty document with a large initial
230
+ /// value. Note that existing keys which are not in `value` are left as is
231
+ pub fn init_from_hydrate(&mut self, value: &crate::hydrate::Map) -> Result<(), AutomergeError> {
232
+ let mut tx = self.transaction();
233
+ tx.batch_init_root_map(value)?;
234
+ tx.commit();
235
+ Ok(())
236
+ }
237
+
238
+ pub fn new_with_encoding(encoding: TextEncoding) -> Self {
239
+ Automerge {
240
+ queue: ChangeQueue::new(),
241
+ change_graph: ChangeGraph::new(0),
242
+ ops: OpSet::new(encoding),
243
+ deps: Default::default(),
244
+ actor: Actor::Unused(ActorId::random()),
245
+ }
246
+ }
247
+
248
+ pub(crate) fn from_parts(ops: OpSet, change_graph: ChangeGraph) -> Self {
249
+ let deps = change_graph.heads().collect();
250
+ let mut doc = Automerge {
251
+ queue: ChangeQueue::new(),
252
+ change_graph,
253
+ ops,
254
+ deps,
255
+ actor: Actor::Unused(ActorId::random()),
256
+ };
257
+ doc.remove_unused_actors(false);
258
+ doc
259
+ }
260
+
261
+ pub(crate) fn ops_mut(&mut self) -> &mut OpSet {
262
+ &mut self.ops
263
+ }
264
+
265
+ pub(crate) fn ops(&self) -> &OpSet {
266
+ &self.ops
267
+ }
268
+
269
+ pub(crate) fn changes(&self) -> &ChangeGraph {
270
+ &self.change_graph
271
+ }
272
+
273
+ /// Whether this document has any operations
274
+ pub fn is_empty(&self) -> bool {
275
+ self.change_graph.is_empty() && self.queue.is_empty()
276
+ }
277
+
278
+ pub(crate) fn actor_id(&self) -> &ActorId {
279
+ match &self.actor {
280
+ Actor::Unused(id) => id,
281
+ Actor::Cached(idx) => self.ops.get_actor(*idx),
282
+ }
283
+ }
284
+
285
+ /// Set the actor id for this document.
286
+ pub fn with_actor(mut self, actor: ActorId) -> Self {
287
+ self.set_actor(actor);
288
+ self
289
+ }
290
+
291
+ /// Set the actor id for this document.
292
+ pub fn set_actor(&mut self, actor: ActorId) -> &mut Self {
293
+ match self.ops.actors.binary_search(&actor) {
294
+ Ok(idx) => self.actor = Actor::Cached(idx),
295
+ Err(_) => self.actor = Actor::Unused(actor),
296
+ }
297
+ self
298
+ }
299
+
300
+ /// Get the current actor id of this document.
301
+ pub fn get_actor(&self) -> &ActorId {
302
+ match &self.actor {
303
+ Actor::Unused(actor) => actor,
304
+ Actor::Cached(index) => self.ops.get_actor(*index),
305
+ }
306
+ }
307
+
308
+ pub(crate) fn remove_actor(&mut self, actor: usize) {
309
+ self.actor.remove_actor(actor, &self.ops.actors);
310
+ self.ops.remove_actor(actor);
311
+ self.change_graph.remove_actor(actor);
312
+ }
313
+
314
+ pub(crate) fn assert_no_unused_actors(&self, panic: bool) {
315
+ if self.ops.actors.len() != self.change_graph.actor_ids().count() {
316
+ let unused = self.change_graph.unused_actors().collect::<Vec<_>>();
317
+ log!("AUTOMERGE :: unused actor found when none expected");
318
+ log!(" :: ops={}", self.ops.actors.len());
319
+ log!(" :: graph={}", self.change_graph.all_actor_ids().count());
320
+ log!(" :: unused={:?}", unused);
321
+ log!(" :: actors={:?}", self.ops.actors);
322
+ assert!(!panic);
323
+ }
324
+ }
325
+
326
+ pub(crate) fn remove_unused_actors(&mut self, panic: bool) {
327
+ if panic {
328
+ self.assert_no_unused_actors(cfg!(debug_assertions));
329
+ }
330
+
331
+ // remove the offending actors
332
+ while let Some(idx) = self.change_graph.unused_actors().last() {
333
+ self.remove_actor(idx);
334
+ }
335
+ }
336
+
337
+ fn get_or_create_actor_index(&mut self) -> usize {
338
+ match &self.actor {
339
+ Actor::Unused(actor) => {
340
+ let index = self.put_actor(actor.clone());
341
+ self.actor = Actor::Cached(index);
342
+ index
343
+ }
344
+ Actor::Cached(index) => *index,
345
+ }
346
+ }
347
+
348
+ fn get_actor_index(&self) -> Option<usize> {
349
+ match &self.actor {
350
+ Actor::Unused(_) => None,
351
+ Actor::Cached(index) => Some(*index),
352
+ }
353
+ }
354
+
355
+ /// Start a transaction.
356
+ pub fn transaction(&mut self) -> Transaction<'_> {
357
+ let args = self.transaction_args(None);
358
+ Transaction::new(self, args, PatchLog::inactive())
359
+ .expect("inactive patch log should not mismatch")
360
+ }
361
+
362
+ /// Start a transaction which records changes in a [`PatchLog`]
363
+ ///
364
+ /// Returns [`PatchLogMismatch`](crate::PatchLogMismatch) if `patch_log` does not belong to
365
+ /// this document. This probably means a patch log created for one document was reused with
366
+ /// another document.
367
+ pub fn transaction_log_patches(
368
+ &mut self,
369
+ patch_log: PatchLog,
370
+ ) -> Result<Transaction<'_>, crate::PatchLogMismatch> {
371
+ let args = self.transaction_args(None);
372
+ Transaction::new(self, args, patch_log)
373
+ }
374
+
375
+ /// Start a transaction isolated at a given heads
376
+ ///
377
+ /// Returns [`PatchLogMismatch`](crate::PatchLogMismatch) if `patch_log` does not belong to
378
+ /// this document. This probably means a patch log created for one document was reused with
379
+ /// another document.
380
+ pub fn transaction_at(
381
+ &mut self,
382
+ patch_log: PatchLog,
383
+ heads: &[ChangeHash],
384
+ ) -> Result<Transaction<'_>, crate::PatchLogMismatch> {
385
+ let args = self.transaction_args(Some(heads));
386
+ Transaction::new(self, args, patch_log)
387
+ }
388
+
389
+ /// Start a transaction that owns the document, consuming `self`.
390
+ ///
391
+ /// This is useful when the transaction must be `'static` (e.g. storing across an FFI
392
+ /// boundary or in a struct that requires `'static`). The document is returned when the
393
+ /// transaction is committed or rolled back.
394
+ ///
395
+ /// # Arguments
396
+ /// * `patch_log` - An optional [`PatchLog`] to log the changes in this transaction to
397
+ /// * `heads` - An optional set of heads to isolate this transaction at, or `None` to use the
398
+ /// current heads of the document
399
+ ///
400
+ /// Returns [`PatchLogMismatch`](crate::PatchLogMismatch) if `patch_log` does not belong to
401
+ /// this document. This probably means a patch log created for one document was reused with
402
+ /// another document.
403
+ pub fn into_transaction(
404
+ self,
405
+ patch_log: Option<PatchLog>,
406
+ heads: Option<&[ChangeHash]>,
407
+ ) -> Result<OwnedTransaction, crate::PatchLogMismatch> {
408
+ OwnedTransaction::new(self, patch_log, heads)
409
+ }
410
+
411
+ pub(crate) fn transaction_args(&mut self, heads: Option<&[ChangeHash]>) -> TransactionArgs {
412
+ let actor_index;
413
+ let seq;
414
+ let mut deps;
415
+ let scope;
416
+ match heads {
417
+ Some(heads) => {
418
+ deps = heads.to_vec();
419
+ let isolation = self.isolate_actor(heads);
420
+ actor_index = isolation.actor_index;
421
+ seq = isolation.seq;
422
+ scope = Some(isolation.clock);
423
+ }
424
+ None => {
425
+ actor_index = self.get_or_create_actor_index();
426
+ seq = self.change_graph.seq_for_actor(actor_index) + 1;
427
+ deps = self.get_heads();
428
+ scope = None;
429
+ if seq > 1 {
430
+ let last_hash = self.get_hash(actor_index, seq - 1).unwrap();
431
+ if !deps.contains(&last_hash) {
432
+ deps.push(last_hash);
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ // SAFETY: this unwrap is safe as we always add 1
439
+ let start_op = NonZeroU64::new(self.change_graph.max_op() + 1).unwrap();
440
+ let checkpoint = self.ops.save_checkpoint();
441
+ TransactionArgs {
442
+ actor_index,
443
+ seq,
444
+ start_op,
445
+ deps,
446
+ checkpoint,
447
+ scope,
448
+ }
449
+ }
450
+
451
+ /// Run a transaction on this document in a closure, automatically handling commit or rollback
452
+ /// afterwards.
453
+ pub fn transact<F, O, E>(&mut self, f: F) -> transaction::Result<O, E>
454
+ where
455
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
456
+ {
457
+ self.transact_with_impl(None::<&dyn Fn(&O) -> CommitOptions>, f)
458
+ }
459
+
460
+ /// Like [`Self::transact()`] but with a function for generating the commit options.
461
+ pub fn transact_with<F, O, E, C>(&mut self, c: C, f: F) -> transaction::Result<O, E>
462
+ where
463
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
464
+ C: FnOnce(&O) -> CommitOptions,
465
+ {
466
+ // FIXME
467
+ self.transact_with_impl(Some(c), f)
468
+ }
469
+
470
+ fn transact_with_impl<F, O, E, C>(&mut self, c: Option<C>, f: F) -> transaction::Result<O, E>
471
+ where
472
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
473
+ C: FnOnce(&O) -> CommitOptions,
474
+ {
475
+ let mut tx = self.transaction();
476
+ let result = f(&mut tx);
477
+ match result {
478
+ Ok(result) => {
479
+ let (hash, patch_log) = if let Some(c) = c {
480
+ let commit_options = c(&result);
481
+ tx.commit_with(commit_options)
482
+ } else {
483
+ tx.commit()
484
+ };
485
+ Ok(Success {
486
+ result,
487
+ hash,
488
+ patch_log,
489
+ })
490
+ }
491
+ Err(error) => Err(Failure {
492
+ error,
493
+ cancelled: tx.rollback(),
494
+ }),
495
+ }
496
+ }
497
+
498
+ /// Run a transaction on this document in a closure, collecting patches, automatically handling commit or rollback
499
+ /// afterwards.
500
+ ///
501
+ /// The collected patches are available in the return value of [`Transaction::commit()`]
502
+ pub fn transact_and_log_patches<F, O, E>(&mut self, f: F) -> transaction::Result<O, E>
503
+ where
504
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
505
+ {
506
+ self.transact_and_log_patches_with_impl(None::<&dyn Fn(&O) -> CommitOptions>, f)
507
+ }
508
+
509
+ /// Like [`Self::transact_and_log_patches()`] but with a function for generating the commit options
510
+ pub fn transact_and_log_patches_with<F, O, E, C>(
511
+ &mut self,
512
+ c: C,
513
+ f: F,
514
+ ) -> transaction::Result<O, E>
515
+ where
516
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
517
+ C: FnOnce(&O) -> CommitOptions,
518
+ {
519
+ self.transact_and_log_patches_with_impl(Some(c), f)
520
+ }
521
+
522
+ fn transact_and_log_patches_with_impl<F, O, E, C>(
523
+ &mut self,
524
+ c: Option<C>,
525
+ f: F,
526
+ ) -> transaction::Result<O, E>
527
+ where
528
+ F: FnOnce(&mut Transaction<'_>) -> Result<O, E>,
529
+ C: FnOnce(&O) -> CommitOptions,
530
+ {
531
+ let mut tx = self
532
+ .transaction_log_patches(PatchLog::active())
533
+ .expect("new patch log should not mismatch");
534
+ let result = f(&mut tx);
535
+ match result {
536
+ Ok(result) => {
537
+ let (hash, history) = if let Some(c) = c {
538
+ let commit_options = c(&result);
539
+ tx.commit_with(commit_options)
540
+ } else {
541
+ tx.commit()
542
+ };
543
+ Ok(Success {
544
+ result,
545
+ hash,
546
+ patch_log: history,
547
+ })
548
+ }
549
+ Err(error) => Err(Failure {
550
+ error,
551
+ cancelled: tx.rollback(),
552
+ }),
553
+ }
554
+ }
555
+
556
+ /// Generate an empty change
557
+ ///
558
+ /// The main reason to do this is if you want to create a "merge commit", which is a change
559
+ /// that has all the current heads of the document as dependencies.
560
+ pub fn empty_commit(&mut self, opts: CommitOptions) -> ChangeHash {
561
+ let args = self.transaction_args(None);
562
+ Transaction::empty(self, args, opts)
563
+ }
564
+
565
+ /// Fork this document at the current point for use by a different actor.
566
+ ///
567
+ /// This will create a new actor ID for the forked document
568
+ pub fn fork(&self) -> Self {
569
+ let mut f = self.clone();
570
+ f.set_actor(ActorId::random());
571
+ f
572
+ }
573
+
574
+ /// Fork this document at the given heads
575
+ ///
576
+ /// This will create a new actor ID for the forked document
577
+ pub fn fork_at(&self, heads: &[ChangeHash]) -> Result<Self, AutomergeError> {
578
+ let mut seen = heads.iter().cloned().collect::<HashSet<_>>();
579
+ let mut heads = heads.to_vec();
580
+ let mut hashes = vec![];
581
+ while let Some(hash) = heads.pop() {
582
+ if !self.change_graph.has_change(&hash) {
583
+ return Err(AutomergeError::InvalidHash(hash));
584
+ }
585
+ for dep in self.change_graph.deps_for_hash(&hash) {
586
+ if !seen.contains(&dep) {
587
+ heads.push(dep);
588
+ }
589
+ }
590
+ hashes.push(hash);
591
+ seen.insert(hash);
592
+ }
593
+ let mut f = Self::new();
594
+ f.set_actor(ActorId::random());
595
+ let changes = self.get_changes_by_hashes(hashes.into_iter().rev())?;
596
+ f.apply_changes(changes)?;
597
+ Ok(f)
598
+ }
599
+
600
+ pub(crate) fn get_changes_by_hashes<I>(&self, hashes: I) -> Result<Vec<Change>, AutomergeError>
601
+ where
602
+ I: IntoIterator<Item = ChangeHash>,
603
+ {
604
+ ChangeCollector::for_hashes(&self.ops, &self.change_graph, hashes)
605
+ }
606
+
607
+ pub(crate) fn exid_to_opid(&self, id: &ExId) -> Result<OpId, AutomergeError> {
608
+ match id {
609
+ ExId::Root => Ok(OpId::new(0, 0)),
610
+ ExId::Id(ctr, actor, idx) => {
611
+ let opid = if self.ops.get_actor_safe(*idx) == Some(actor) {
612
+ OpId::new(*ctr, *idx)
613
+ } else if let Some(backup_idx) = self.ops.lookup_actor(actor) {
614
+ OpId::new(*ctr, backup_idx)
615
+ } else {
616
+ return Err(AutomergeError::InvalidObjId(id.to_string()));
617
+ };
618
+ Ok(opid)
619
+ }
620
+ }
621
+ }
622
+
623
+ pub(crate) fn get_obj_meta(&self, id: ObjId) -> Result<ObjMeta, AutomergeError> {
624
+ if id.is_root() {
625
+ Ok(ObjMeta::root())
626
+ } else if let Some(typ) = self.ops.object_type(&id) {
627
+ Ok(ObjMeta { id, typ })
628
+ } else {
629
+ Err(AutomergeError::NotAnObject)
630
+ }
631
+ }
632
+
633
+ pub(crate) fn op_cursor_to_opid(
634
+ &self,
635
+ cursor: &OpCursor,
636
+ clock: Option<&Clock>,
637
+ ) -> Result<OpId, AutomergeError> {
638
+ if let Some(idx) = self.ops.lookup_actor(&cursor.actor) {
639
+ let opid = OpId::new(cursor.ctr, idx);
640
+ match clock {
641
+ Some(clock) if !clock.covers(&opid) => {
642
+ Err(AutomergeError::InvalidCursor(Cursor::Op(cursor.clone())))
643
+ }
644
+ _ => Ok(opid),
645
+ }
646
+ } else {
647
+ Err(AutomergeError::InvalidCursor(Cursor::Op(cursor.clone())))
648
+ }
649
+ }
650
+
651
+ pub(crate) fn exid_to_obj(&self, id: &ExId) -> Result<ObjMeta, AutomergeError> {
652
+ let opid = self.exid_to_opid(id)?;
653
+ let obj = ObjId(opid);
654
+ self.get_obj_meta(obj)
655
+ }
656
+
657
+ pub(crate) fn id_to_exid(&self, id: OpId) -> ExId {
658
+ self.ops.id_to_exid(id)
659
+ }
660
+
661
+ pub fn diff_opset(&self, other: &Self) -> Result<(), AutomergeError> {
662
+ let (ops_meta1, ops_out1) = self.ops.export();
663
+ let (ops_meta2, ops_out2) = other.ops.export();
664
+ if ops_meta1 != ops_meta2 {
665
+ let specs: std::collections::BTreeSet<_> = ops_meta1
666
+ .0
667
+ .iter()
668
+ .chain(ops_meta2.0.iter())
669
+ .map(|c| c.spec())
670
+ .collect();
671
+ for s in specs {
672
+ let d1 = ops_meta1
673
+ .0
674
+ .iter()
675
+ .find(|c| c.spec() == s)
676
+ .map(|c| c.data())
677
+ .unwrap_or(0..0);
678
+ let d2 = ops_meta2
679
+ .0
680
+ .iter()
681
+ .find(|c| c.spec() == s)
682
+ .map(|c| c.data())
683
+ .unwrap_or(0..0);
684
+ let d1 = &ops_out1[d1];
685
+ let d2 = &ops_out2[d2];
686
+ if d1 != d2 {
687
+ log!(" s={:?}|{:?} ", s.id(), s.col_type());
688
+ log!(" {:?} ", d1);
689
+ log!(" {:?} ", d2);
690
+ OpSet::decode(s, d1);
691
+ OpSet::decode(s, d2);
692
+ }
693
+ }
694
+ }
695
+ Ok(())
696
+ }
697
+
698
+ /// Load a document.
699
+ pub fn load(data: &[u8]) -> Result<Self, AutomergeError> {
700
+ Self::load_with_options(data, Default::default())
701
+ }
702
+
703
+ /// Load a document without verifying the head hashes
704
+ ///
705
+ /// This is useful for debugging as it allows you to examine a corrupted document.
706
+ pub fn load_unverified_heads(data: &[u8]) -> Result<Self, AutomergeError> {
707
+ Self::load_with_options(
708
+ data,
709
+ LoadOptions {
710
+ verification_mode: VerificationMode::DontCheck,
711
+ ..Default::default()
712
+ },
713
+ )
714
+ }
715
+
716
+ /// Load a document, with options
717
+ ///
718
+ /// # Arguments
719
+ /// * `data` - The data to load
720
+ /// * `on_error` - What to do if the document is only partially loaded. This can happen if some
721
+ /// prefix of `data` contains valid data.
722
+ /// * `mode` - Whether to verify the head hashes after loading
723
+ /// * `patch_log` - A [`PatchLog`] to log the changes required to materialize the current state of
724
+ /// the document once loaded
725
+ #[deprecated(since = "0.5.2", note = "Use `load_with_options` instead")]
726
+ #[tracing::instrument(skip(data), err)]
727
+ pub fn load_with(
728
+ data: &[u8],
729
+ on_error: OnPartialLoad,
730
+ mode: VerificationMode,
731
+ patch_log: &mut PatchLog,
732
+ ) -> Result<Self, AutomergeError> {
733
+ Self::load_with_options(
734
+ data,
735
+ LoadOptions::new()
736
+ .on_partial_load(on_error)
737
+ .verification_mode(mode)
738
+ .patch_log(patch_log),
739
+ )
740
+ }
741
+
742
+ /// Load a document, with options
743
+ ///
744
+ /// # Arguments
745
+ /// * `data` - The data to load
746
+ /// * `options` - The options to use when loading
747
+ #[tracing::instrument(skip(data), err)]
748
+ pub fn load_with_options(
749
+ data: &[u8],
750
+ options: LoadOptions<'_>,
751
+ ) -> Result<Self, AutomergeError> {
752
+ if data.is_empty() {
753
+ tracing::trace!("no data, initializing empty document");
754
+ return Ok(Self::new());
755
+ }
756
+ tracing::trace!("loading first chunk");
757
+ let (remaining, first_chunk) = storage::Chunk::parse(storage::parse::Input::new(data))
758
+ .map_err(|e| load::Error::Parse(Box::new(e)))?;
759
+ if !first_chunk.checksum_valid() {
760
+ return Err(load::Error::BadChecksum.into());
761
+ }
762
+
763
+ let mut changes = vec![];
764
+ let mut first_chunk_was_doc = false;
765
+ let mut am = match first_chunk {
766
+ storage::Chunk::Document(d) => {
767
+ tracing::trace!("first chunk is document chunk, inflating");
768
+ first_chunk_was_doc = true;
769
+ d.reconstruct(options.verification_mode, options.text_encoding)
770
+ .map_err(|e| load::Error::InflateDocument(Box::new(e)))?
771
+ }
772
+ storage::Chunk::Change(stored_change) => {
773
+ tracing::trace!("first chunk is change chunk");
774
+ changes.push(
775
+ Change::new_from_unverified(stored_change.into_owned(), None)
776
+ .map_err(|e| load::Error::InvalidChangeColumns(Box::new(e)))?,
777
+ );
778
+ Self::new()
779
+ }
780
+ storage::Chunk::Bundle(bundle) => {
781
+ tracing::trace!("first chunk is change chunk");
782
+ let bundle = Bundle::new_from_unverified(bundle.into_owned())
783
+ .map_err(|e| load::Error::InvalidBundleColumn(Box::new(e)))?;
784
+ let bundle_changes = bundle
785
+ .to_changes()
786
+ .map_err(|e| load::Error::InvalidBundleChange(Box::new(e)))?;
787
+ changes.extend(bundle_changes);
788
+ Self::new()
789
+ }
790
+ storage::Chunk::CompressedChange(stored_change, compressed) => {
791
+ tracing::trace!("first chunk is compressed change");
792
+ changes.push(
793
+ Change::new_from_unverified(
794
+ stored_change.into_owned(),
795
+ Some(compressed.into_owned()),
796
+ )
797
+ .map_err(|e| load::Error::InvalidChangeColumns(Box::new(e)))?,
798
+ );
799
+ Self::new()
800
+ }
801
+ };
802
+ tracing::trace!("loading change chunks");
803
+ match load::load_changes(remaining.reset(), options.text_encoding, &am.change_graph) {
804
+ load::LoadedChanges::Complete(c) => {
805
+ am.apply_changes(changes.into_iter().chain(c))?;
806
+ // Only allow missing deps if the first chunk was a document chunk
807
+ // See https://github.com/automerge/automerge/pull/599#issuecomment-1549667472
808
+ if !am.queue.is_empty()
809
+ && !first_chunk_was_doc
810
+ && options.on_partial_load == OnPartialLoad::Error
811
+ {
812
+ return Err(AutomergeError::MissingDeps);
813
+ }
814
+ }
815
+ load::LoadedChanges::Partial { error, .. } => {
816
+ if options.on_partial_load == OnPartialLoad::Error {
817
+ return Err(error.into());
818
+ }
819
+ }
820
+ }
821
+ if let StringMigration::ConvertToText = options.string_migration {
822
+ am.convert_scalar_strings_to_text()?;
823
+ }
824
+ if let Some(patch_log) = options.patch_log {
825
+ if patch_log.is_active() {
826
+ am.log_current_state(ObjMeta::root(), patch_log, true);
827
+ }
828
+ }
829
+ Ok(am)
830
+ }
831
+
832
+ /// Create the patches from a [`PatchLog`]
833
+ ///
834
+ /// See the documentation for [`PatchLog`] for more details on this
835
+ pub fn make_patches(&self, patch_log: &mut PatchLog) -> Vec<Patch> {
836
+ patch_log.make_patches(self)
837
+ }
838
+
839
+ /// Get a set of [`Patch`]es which materialize the current state of the document
840
+ ///
841
+ /// This is a convienence method for [`doc.diff(&[], current_heads)`][diff]
842
+ ///
843
+ /// [diff]: Self::diff()
844
+ pub fn current_state(&self) -> Vec<Patch> {
845
+ let mut patch_log = PatchLog::active();
846
+ self.log_current_state(ObjMeta::root(), &mut patch_log, true);
847
+ patch_log.make_patches(self)
848
+ }
849
+
850
+ /// Load an incremental save of a document.
851
+ ///
852
+ /// Unlike [`Self::load()`] this imports changes into an existing document. It will work with
853
+ /// both the output of [`Self::save()`] and [`Self::save_after()`]
854
+ ///
855
+ /// The return value is the number of ops which were applied, this is not useful and will
856
+ /// change in future.
857
+ pub fn load_incremental(&mut self, data: &[u8]) -> Result<usize, AutomergeError> {
858
+ self.load_incremental_log_patches(data, &mut PatchLog::inactive())
859
+ }
860
+
861
+ /// Like [`Self::load_incremental()`] but log the changes to the current state of the document
862
+ /// to [`PatchLog`]
863
+ pub fn load_incremental_log_patches(
864
+ &mut self,
865
+ data: &[u8],
866
+ patch_log: &mut PatchLog,
867
+ ) -> Result<usize, AutomergeError> {
868
+ if self.is_empty() {
869
+ let mut doc = Self::load_with_options(
870
+ data,
871
+ LoadOptions::new()
872
+ .on_partial_load(OnPartialLoad::Ignore)
873
+ .verification_mode(VerificationMode::Check),
874
+ )?;
875
+ doc = doc.with_actor(self.actor_id().clone());
876
+ if patch_log.is_active() {
877
+ doc.log_current_state(ObjMeta::root(), patch_log, true);
878
+ }
879
+ *self = doc;
880
+ return Ok(self.ops.len());
881
+ }
882
+ let changes = match load::load_changes(
883
+ storage::parse::Input::new(data),
884
+ self.text_encoding(),
885
+ &self.change_graph,
886
+ ) {
887
+ load::LoadedChanges::Complete(c) => c,
888
+ load::LoadedChanges::Partial { error, loaded, .. } => {
889
+ tracing::warn!(successful_chunks=loaded.len(), err=?error, "partial load");
890
+ loaded
891
+ }
892
+ };
893
+ let start = self.ops.len();
894
+ self.apply_changes_log_patches(changes, patch_log)?;
895
+ let delta = self.ops.len() - start;
896
+ Ok(delta)
897
+ }
898
+
899
+ pub(crate) fn log_current_state(
900
+ &self,
901
+ obj: ObjMeta,
902
+ patch_log: &mut PatchLog,
903
+ recursive: bool,
904
+ ) {
905
+ let clock = ClockRange::default();
906
+ let path_map = DiffIter::log(self, obj, clock, patch_log, recursive);
907
+ patch_log.path_hint(path_map);
908
+ }
909
+
910
+ fn seq_for_actor(&self, actor: &ActorId) -> u64 {
911
+ self.ops
912
+ .lookup_actor(actor)
913
+ .map(|idx| self.change_graph.seq_for_actor(idx))
914
+ .unwrap_or(0)
915
+ }
916
+
917
+ pub(crate) fn has_actor_seq(&self, change: &Change) -> bool {
918
+ self.seq_for_actor(change.actor_id()) >= change.seq()
919
+ }
920
+
921
+ /// Apply changes to this document.
922
+ ///
923
+ /// This is idempotent in the sense that if a change has already been applied it will be
924
+ /// ignored.
925
+ pub fn apply_changes(
926
+ &mut self,
927
+ changes: impl IntoIterator<Item = Change> + Clone,
928
+ ) -> Result<(), AutomergeError> {
929
+ self.apply_changes_log_patches(changes, &mut PatchLog::inactive())
930
+ }
931
+
932
+ /// Like [`Self::apply_changes()`] but log the resulting changes to the current state of the
933
+ /// document to `patch_log`
934
+ pub fn apply_changes_log_patches<I: IntoIterator<Item = Change> + Clone>(
935
+ &mut self,
936
+ changes: I,
937
+ patch_log: &mut PatchLog,
938
+ ) -> Result<(), AutomergeError> {
939
+ self.apply_changes_batch_log_patches(changes, patch_log)
940
+ }
941
+
942
+ /// Takes all the changes in `other` which are not in `self` and applies them
943
+ pub fn merge(&mut self, other: &mut Self) -> Result<Vec<ChangeHash>, AutomergeError> {
944
+ self.merge_and_log_patches(other, &mut PatchLog::inactive())
945
+ }
946
+
947
+ /// Takes all the changes in `other` which are not in `self` and applies them whilst logging
948
+ /// the resulting changes to the current state of the document to `patch_log`
949
+ pub fn merge_and_log_patches(
950
+ &mut self,
951
+ other: &mut Self,
952
+ patch_log: &mut PatchLog,
953
+ ) -> Result<Vec<ChangeHash>, AutomergeError> {
954
+ // TODO: Make this fallible and figure out how to do this transactionally
955
+ let changes = self.get_changes_added(other);
956
+ tracing::trace!(changes=?changes.iter().map(|c| c.hash()).collect::<Vec<_>>(), "merging new changes");
957
+ self.apply_changes_log_patches(changes, patch_log)?;
958
+ Ok(self.get_heads())
959
+ }
960
+
961
+ /// EXPERIMENTAL: Write the set of changes in `hashes` to a "bundle"
962
+ ///
963
+ /// A "bundle" is a compact representation of a set of changes which uses
964
+ /// the same compression tricks as the document encoding we use in
965
+ /// [`Automerge::save`].
966
+ ///
967
+ /// This is an experimental API, the bundle format is still subject to change
968
+ /// and so should not be used in production just yet.
969
+ pub fn bundle<I>(&self, hashes: I) -> Result<Bundle, AutomergeError>
970
+ where
971
+ I: IntoIterator<Item = ChangeHash>,
972
+ {
973
+ Bundle::for_hashes(&self.ops, &self.change_graph, hashes)
974
+ }
975
+
976
+ /// Save the entirety of this document in a compact form.
977
+ pub fn save_with_options(&self, options: SaveOptions) -> Vec<u8> {
978
+ self.assert_no_unused_actors(true);
979
+
980
+ let doc = Document::new(&self.ops, &self.change_graph, options.compress());
981
+ let mut bytes = doc.into_bytes();
982
+
983
+ if options.retain_orphans {
984
+ for orphaned in self.queue.iter() {
985
+ bytes.extend(orphaned.raw_bytes());
986
+ }
987
+ }
988
+ bytes
989
+ }
990
+
991
+ #[cfg(test)]
992
+ pub fn debug_cmp(&self, other: &Self) {
993
+ self.ops.debug_cmp(&other.ops);
994
+ }
995
+
996
+ /// Save the entirety of this document in a compact form.
997
+ pub fn save(&self) -> Vec<u8> {
998
+ self.save_with_options(SaveOptions::default())
999
+ }
1000
+
1001
+ /// Save the document and attempt to load it before returning - slow!
1002
+ pub fn save_and_verify(&self) -> Result<Vec<u8>, AutomergeError> {
1003
+ let bytes = self.save();
1004
+ Self::load(&bytes)?;
1005
+ Ok(bytes)
1006
+ }
1007
+
1008
+ /// Save this document, but don't run it through `DEFLATE` afterwards
1009
+ pub fn save_nocompress(&self) -> Vec<u8> {
1010
+ self.save_with_options(SaveOptions {
1011
+ deflate: false,
1012
+ ..Default::default()
1013
+ })
1014
+ }
1015
+
1016
+ /// Save the changes since the given heads
1017
+ ///
1018
+ /// The output of this will not be a compressed document format, but a series of individual
1019
+ /// changes. This is useful if you know you have only made a small change since the last
1020
+ /// [`Self::save()`] and you want to immediately send it somewhere (e.g. you've inserted a
1021
+ /// single character in a text object).
1022
+ pub fn save_after(&self, heads: &[ChangeHash]) -> Vec<u8> {
1023
+ let changes = self.get_changes(heads);
1024
+ let mut bytes = vec![];
1025
+ for c in changes {
1026
+ bytes.extend(c.raw_bytes());
1027
+ }
1028
+ bytes
1029
+ }
1030
+
1031
+ /// Filter the changes down to those that are not transitive dependencies of the heads.
1032
+ ///
1033
+ /// Thus a graph with these heads has not seen the remaining changes.
1034
+ pub(crate) fn filter_changes(
1035
+ &self,
1036
+ heads: &[ChangeHash],
1037
+ changes: &mut BTreeSet<ChangeHash>,
1038
+ ) -> Result<(), AutomergeError> {
1039
+ let heads = heads
1040
+ .iter()
1041
+ .filter(|hash| self.has_change(hash))
1042
+ .copied()
1043
+ .collect::<Vec<_>>();
1044
+
1045
+ self.change_graph.remove_ancestors(changes, &heads);
1046
+
1047
+ Ok(())
1048
+ }
1049
+
1050
+ /// Get the last change this actor made to the document.
1051
+ pub fn get_last_local_change(&self) -> Option<Change> {
1052
+ let actor = self.get_actor_index()?;
1053
+ let seq = self.change_graph.seq_for_actor(actor);
1054
+ let hash = self.change_graph.get_hash_for_actor_seq(actor, seq).ok()?;
1055
+ self.get_change_by_hash(&hash)
1056
+ }
1057
+
1058
+ pub(crate) fn clock_range(&self, before: &[ChangeHash], after: &[ChangeHash]) -> ClockRange {
1059
+ let before = self.clock_at(before);
1060
+ let after = self.clock_at(after);
1061
+ ClockRange::Diff(before, after)
1062
+ }
1063
+
1064
+ pub(crate) fn clock_at(&self, heads: &[ChangeHash]) -> Clock {
1065
+ self.change_graph.clock_for_heads(heads)
1066
+ }
1067
+
1068
+ fn get_isolated_actor_index(&mut self, level: usize) -> usize {
1069
+ if level == 0 {
1070
+ self.get_or_create_actor_index()
1071
+ } else {
1072
+ let base_actor = self.get_actor();
1073
+ let new_actor = base_actor.with_concurrency(level);
1074
+ self.put_actor(new_actor)
1075
+ }
1076
+ }
1077
+
1078
+ pub(crate) fn isolate_actor(&mut self, heads: &[ChangeHash]) -> Isolation {
1079
+ let mut actor_index = self.get_isolated_actor_index(0);
1080
+ let mut clock = self.clock_at(heads);
1081
+
1082
+ for i in 1.. {
1083
+ let max_op = self.change_graph.max_op_for_actor(actor_index);
1084
+ if max_op == 0 || clock.covers(&OpId::new(max_op, actor_index)) {
1085
+ clock.isolate(actor_index);
1086
+ break;
1087
+ }
1088
+ actor_index = self.get_isolated_actor_index(i);
1089
+ clock = self.clock_at(heads); // need to recompute the clock b/c the actor indexes may have changed
1090
+ }
1091
+
1092
+ let seq = self.change_graph.seq_for_actor(actor_index) + 1;
1093
+
1094
+ Isolation {
1095
+ actor_index,
1096
+ seq,
1097
+ clock,
1098
+ }
1099
+ }
1100
+
1101
+ fn get_hash(&self, actor: usize, seq: u64) -> Result<ChangeHash, AutomergeError> {
1102
+ self.change_graph.get_hash_for_actor_seq(actor, seq)
1103
+ }
1104
+
1105
+ pub(crate) fn update_history(&mut self, change: &Change) {
1106
+ self.update_deps(change);
1107
+
1108
+ let actor_index = self
1109
+ .ops
1110
+ .actors
1111
+ .binary_search(change.actor_id())
1112
+ .expect("Change's actor not already in the document");
1113
+
1114
+ self.change_graph
1115
+ .add_change(change, actor_index)
1116
+ .expect("Change's deps should already be in the document");
1117
+ }
1118
+
1119
+ fn insert_actor(&mut self, index: usize, actor: ActorId) -> usize {
1120
+ self.ops.insert_actor(index, actor);
1121
+ self.change_graph.insert_actor(index);
1122
+ self.actor.rewrite_with_new_actor(index);
1123
+ index
1124
+ }
1125
+ pub(crate) fn put_actor_ref(&mut self, actor: &ActorId) -> usize {
1126
+ match self.ops.actors.binary_search(actor) {
1127
+ Ok(idx) => idx,
1128
+ Err(idx) => self.insert_actor(idx, actor.clone()),
1129
+ }
1130
+ }
1131
+
1132
+ pub(crate) fn put_actor(&mut self, actor: ActorId) -> usize {
1133
+ match self.ops.actors.binary_search(&actor) {
1134
+ Ok(idx) => idx,
1135
+ Err(idx) => self.insert_actor(idx, actor),
1136
+ }
1137
+ }
1138
+
1139
+ fn update_deps(&mut self, change: &Change) {
1140
+ for d in change.deps() {
1141
+ self.deps.remove(d);
1142
+ }
1143
+ self.deps.insert(change.hash());
1144
+ }
1145
+
1146
+ #[doc(hidden)]
1147
+ pub fn import(&self, s: &str) -> Result<(ExId, ObjType), AutomergeError> {
1148
+ let obj = self.import_obj(s)?;
1149
+ if obj == ExId::Root {
1150
+ Ok((ExId::Root, ObjType::Map))
1151
+ } else {
1152
+ let obj_type = self
1153
+ .object_type(&obj)
1154
+ .map_err(|_| AutomergeError::InvalidObjId(s.to_owned()))?;
1155
+ Ok((obj, obj_type))
1156
+ }
1157
+ }
1158
+
1159
+ #[doc(hidden)]
1160
+ pub fn import_obj(&self, s: &str) -> Result<ExId, AutomergeError> {
1161
+ if s == "_root" {
1162
+ Ok(ExId::Root)
1163
+ } else {
1164
+ let n = s
1165
+ .find('@')
1166
+ .ok_or_else(|| AutomergeError::InvalidObjIdFormat(s.to_owned()))?;
1167
+ let counter = s[0..n]
1168
+ .parse()
1169
+ .map_err(|_| AutomergeError::InvalidObjIdFormat(s.to_owned()))?;
1170
+ let actor = ActorId::from(hex::decode(&s[(n + 1)..]).unwrap());
1171
+ let actor = self
1172
+ .ops
1173
+ .lookup_actor(&actor)
1174
+ .ok_or_else(|| AutomergeError::InvalidObjId(s.to_owned()))?;
1175
+ let obj = ExId::Id(counter, self.ops.get_actor(actor).clone(), actor);
1176
+ Ok(obj)
1177
+ }
1178
+ }
1179
+
1180
+ pub fn dump(&self) {
1181
+ /*
1182
+ log!(
1183
+ " {:12} {:3} {:12} {:12} {:12} {:12} {:12}",
1184
+ "id",
1185
+ "ins",
1186
+ "obj",
1187
+ "key",
1188
+ "value",
1189
+ "pred",
1190
+ "succ"
1191
+ );
1192
+ */
1193
+ self.ops.dump();
1194
+ /*
1195
+ for op in self.ops.iter() {
1196
+ let id = self.to_short_string(op.id);
1197
+ let obj = self.to_short_string(op.obj);
1198
+ let key = match op.key {
1199
+ KeyRef::Map(n) => n.to_owned(),
1200
+ KeyRef::Seq(n) => self.to_short_string(n),
1201
+ };
1202
+ let value: String = match op.op_type() {
1203
+ OpType::Put(value) => format!("{}", value),
1204
+ OpType::Make(obj) => format!("make({})", obj),
1205
+ OpType::Increment(obj) => format!("inc({})", obj),
1206
+ OpType::Delete => format!("del{}", 0),
1207
+ OpType::MarkBegin(_, MarkData { name, value }) => {
1208
+ format!("mark({},{})", name, value)
1209
+ }
1210
+ OpType::MarkEnd(_) => "/mark".to_string(),
1211
+ };
1212
+ //let pred: Vec<_> = op.pred().map(|id| self.to_short_string(id)).collect();
1213
+ let succ: Vec<_> = op.succ().map(|id| self.to_short_string(id)).collect();
1214
+ let insert = match op.insert {
1215
+ true => "t",
1216
+ false => "f",
1217
+ };
1218
+ log!(
1219
+ //" {:12} {:3} {:12} {:12} {:12} {:12?} {:12?}",
1220
+ " {:12} {:3} {:12} {:12} {:12} {:12?}",
1221
+ id,
1222
+ insert,
1223
+ obj,
1224
+ key,
1225
+ value,
1226
+ //pred,
1227
+ succ
1228
+ );
1229
+ }
1230
+ */
1231
+ }
1232
+
1233
+ /// Create patches representing the change in the current state of the document between the
1234
+ /// `before` and `after` heads. If the arguments are reverse it will observe the same changes
1235
+ /// in the opposite order.
1236
+ pub fn diff(&self, before_heads: &[ChangeHash], after_heads: &[ChangeHash]) -> Vec<Patch> {
1237
+ let clock = self.clock_range(before_heads, after_heads);
1238
+ let mut patch_log = PatchLog::active();
1239
+ DiffIter::log(self, ObjMeta::root(), clock, &mut patch_log, true);
1240
+ patch_log.heads = Some(after_heads.to_vec());
1241
+ patch_log.make_patches(self)
1242
+ }
1243
+
1244
+ /// Create patches representing the change in the current state of an object
1245
+ /// in the document between the `before_heads` and `after_heads` heads. If
1246
+ /// the arguments are reverse it will observe the same changes in the
1247
+ /// opposite order.
1248
+ ///
1249
+ /// # Arguments
1250
+ ///
1251
+ /// * `obj` - The object to start the diff at.
1252
+ /// * `before_heads` - heads from [`Self::get_heads()`] at beginning point
1253
+ /// in the documents history
1254
+ /// * `after_heads` - heads from [`Self::get_heads()`] at ending point in
1255
+ /// the documents history.
1256
+ /// * `recursive` - if false, do not also diff child objects
1257
+ ///
1258
+ /// Note: `before_heads` and `after_heads` do not have to be chronological.
1259
+ /// Document state can move backward.
1260
+ pub fn diff_obj(
1261
+ &self,
1262
+ obj: &ExId,
1263
+ before_heads: &[ChangeHash],
1264
+ after_heads: &[ChangeHash],
1265
+ recursive: bool,
1266
+ ) -> Result<Vec<Patch>, AutomergeError> {
1267
+ let obj = self.exid_to_obj(obj.as_ref())?;
1268
+ let clock = self.clock_range(before_heads, after_heads);
1269
+ let mut patch_log = PatchLog::active();
1270
+ DiffIter::log(self, obj, clock, &mut patch_log, recursive);
1271
+ patch_log.heads = Some(after_heads.to_vec());
1272
+ Ok(patch_log.make_patches(self))
1273
+ }
1274
+
1275
+ /// Get the heads of this document.
1276
+ pub fn get_heads(&self) -> Vec<ChangeHash> {
1277
+ let mut deps: Vec<_> = self.deps.iter().copied().collect();
1278
+ deps.sort_unstable();
1279
+ deps
1280
+ }
1281
+
1282
+ pub fn get_changes(&self, have_deps: &[ChangeHash]) -> Vec<Change> {
1283
+ ChangeCollector::exclude_hashes(&self.ops, &self.change_graph, have_deps)
1284
+ }
1285
+
1286
+ pub fn get_changes_meta(&self, have_deps: &[ChangeHash]) -> Vec<ChangeMetadata<'_>> {
1287
+ ChangeCollector::exclude_hashes_meta(&self.ops, &self.change_graph, have_deps)
1288
+ }
1289
+
1290
+ pub fn get_change_meta_by_hash(&self, hash: &ChangeHash) -> Option<ChangeMetadata<'_>> {
1291
+ ChangeCollector::meta_for_hashes(&self.ops, &self.change_graph, [*hash])
1292
+ .ok()?
1293
+ .pop()
1294
+ }
1295
+
1296
+ /// Get changes in `other` that are not in `self`
1297
+ pub fn get_changes_added(&self, other: &Self) -> Vec<Change> {
1298
+ // Depth-first traversal from the heads through the dependency graph,
1299
+ // until we reach a change that is already present in other
1300
+ let mut stack: Vec<_> = other.get_heads();
1301
+ tracing::trace!(their_heads=?stack, "finding changes to merge");
1302
+ let mut seen_hashes = HashSet::new();
1303
+ let mut added_change_hashes = Vec::new();
1304
+ while let Some(hash) = stack.pop() {
1305
+ if !seen_hashes.contains(&hash) && !self.has_change(&hash) {
1306
+ seen_hashes.insert(hash);
1307
+ added_change_hashes.push(hash);
1308
+ stack.extend(other.change_graph.deps_for_hash(&hash));
1309
+ }
1310
+ }
1311
+ // Return those changes in the reverse of the order in which the depth-first search
1312
+ // found them. This is not necessarily a topological sort, but should usually be close.
1313
+ added_change_hashes.reverse();
1314
+
1315
+ // safe to unwrap here b/c added_changes all came from the change_graph
1316
+ other.get_changes_by_hashes(added_change_hashes).unwrap()
1317
+ }
1318
+
1319
+ /// Get the hash of the change that contains the given `opid`.
1320
+ ///
1321
+ /// Returns [`None`] if the `opid`:
1322
+ /// - is the root object id
1323
+ /// - does not exist in this document
1324
+ pub fn hash_for_opid(&self, exid: &ExId) -> Option<ChangeHash> {
1325
+ match exid {
1326
+ ExId::Root => None,
1327
+ ExId::Id(..) => {
1328
+ let opid = self.exid_to_opid(exid).ok()?;
1329
+ self.change_graph.opid_to_hash(opid)
1330
+ }
1331
+ }
1332
+ }
1333
+
1334
+ fn calculate_marks(
1335
+ &self,
1336
+ obj: &ExId,
1337
+ clock: Option<Clock>,
1338
+ ) -> Result<Vec<Mark>, AutomergeError> {
1339
+ let obj = self.exid_to_obj(obj.as_ref())?;
1340
+ let mut top_ops = self
1341
+ .ops()
1342
+ .iter_obj(&obj.id)
1343
+ .visible_slow(clock)
1344
+ .top_ops()
1345
+ .marks();
1346
+
1347
+ let Some(seq_type) = obj.typ.as_sequence_type() else {
1348
+ // Really we should return an error here but we don't in order to stay
1349
+ // compatibile with older implementations
1350
+ return Ok(Vec::new());
1351
+ };
1352
+
1353
+ let mut index = 0;
1354
+ let mut acc = MarkAccumulator::default();
1355
+ let mut last_marks = None;
1356
+ let mut mark_len = 0;
1357
+ let mut mark_index = 0;
1358
+ while let Some(o) = top_ops.next() {
1359
+ let marks = top_ops.get_marks();
1360
+ let len = o.width(seq_type, self.text_encoding());
1361
+ if last_marks.as_ref() != marks {
1362
+ match last_marks.as_ref() {
1363
+ Some(m) if mark_len > 0 => acc.add(mark_index, mark_len, m),
1364
+ _ => (),
1365
+ }
1366
+ last_marks = marks.cloned();
1367
+ mark_index = index;
1368
+ mark_len = 0;
1369
+ }
1370
+ mark_len += len;
1371
+ index += len;
1372
+ }
1373
+ match last_marks.as_ref() {
1374
+ Some(m) if mark_len > 0 => acc.add(mark_index, mark_len, m),
1375
+ _ => (),
1376
+ }
1377
+ Ok(acc.into_iter_no_unmark().collect())
1378
+ }
1379
+
1380
+ pub fn hydrate(&self, heads: Option<&[ChangeHash]>) -> hydrate::Value {
1381
+ let clock = heads.map(|heads| self.clock_at(heads));
1382
+ self.hydrate_map(&ObjId::root(), clock.as_ref())
1383
+ }
1384
+
1385
+ pub(crate) fn hydrate_obj(
1386
+ &self,
1387
+ obj: &crate::ObjId,
1388
+ heads: Option<&[ChangeHash]>,
1389
+ ) -> Result<hydrate::Value, AutomergeError> {
1390
+ let obj = self.exid_to_obj(obj)?;
1391
+ let clock = heads.map(|heads| self.clock_at(heads));
1392
+ Ok(match obj.typ {
1393
+ ObjType::Map | ObjType::Table => self.hydrate_map(&obj.id, clock.as_ref()),
1394
+ ObjType::List => self.hydrate_list(&obj.id, clock.as_ref()),
1395
+ ObjType::Text => self.hydrate_text(&obj.id, clock.as_ref()),
1396
+ })
1397
+ }
1398
+
1399
+ pub(crate) fn parents_for(
1400
+ &self,
1401
+ obj: &ExId,
1402
+ clock: Option<Clock>,
1403
+ ) -> Result<Parents<'_>, AutomergeError> {
1404
+ let obj = self.exid_to_obj(obj)?;
1405
+ // FIXME - now that we have blocks a correct text_rep is relevent
1406
+ Ok(self.ops.parents(obj.id, clock))
1407
+ }
1408
+
1409
+ pub(crate) fn keys_for(&self, obj: &ExId, clock: Option<Clock>) -> Keys<'_> {
1410
+ self.exid_to_obj(obj)
1411
+ .ok()
1412
+ .map(|obj| self.ops.keys(&obj.id, clock))
1413
+ .unwrap_or_default()
1414
+ }
1415
+
1416
+ pub(crate) fn iter_for(&self, obj: &ExId, clock: Option<Clock>) -> DocIter<'_> {
1417
+ self.exid_to_obj(obj)
1418
+ .ok()
1419
+ .map(|obj| DocIter::new(self, obj, clock))
1420
+ .unwrap_or_else(|| DocIter::empty(self.text_encoding()))
1421
+ }
1422
+
1423
+ pub(crate) fn map_range_for<'a, R: RangeBounds<String> + 'a>(
1424
+ &'a self,
1425
+ obj: &ExId,
1426
+ range: R,
1427
+ clock: Option<Clock>,
1428
+ ) -> MapRange<'a> {
1429
+ self.exid_to_obj(obj)
1430
+ .ok()
1431
+ .map(|obj| self.ops.map_range(&obj.id, range, clock))
1432
+ .unwrap_or_default()
1433
+ }
1434
+
1435
+ pub(crate) fn list_range_for<R: RangeBounds<usize>>(
1436
+ &self,
1437
+ obj: &ExId,
1438
+ range: R,
1439
+ clock: Option<Clock>,
1440
+ ) -> ListRange<'_> {
1441
+ self.exid_to_obj(obj)
1442
+ .ok()
1443
+ .map(|obj| self.ops.list_range(&obj.id, range, clock))
1444
+ .unwrap_or_default()
1445
+ }
1446
+
1447
+ pub(crate) fn values_for(&self, obj: &ExId, clock: Option<Clock>) -> Values<'_> {
1448
+ self.exid_to_obj(obj)
1449
+ .ok()
1450
+ .map(|obj| Values::new(&self.ops, self.ops.top_ops(&obj.id, clock.clone()), clock))
1451
+ .unwrap_or_default()
1452
+ }
1453
+
1454
+ pub(crate) fn length_for(&self, obj: &ExId, clock: Option<Clock>) -> usize {
1455
+ // FIXME - is doc.length() for a text always the string length?
1456
+ self.exid_to_obj(obj)
1457
+ .map(|obj| self.ops.seq_length(&obj.id, self.text_encoding(), clock))
1458
+ .unwrap_or(0)
1459
+ }
1460
+
1461
+ pub(crate) fn text_for(
1462
+ &self,
1463
+ obj: &ExId,
1464
+ clock: Option<Clock>,
1465
+ ) -> Result<String, AutomergeError> {
1466
+ let obj = self.exid_to_obj(obj)?;
1467
+ Ok(self.ops.text(&obj.id, clock))
1468
+ }
1469
+
1470
+ pub(crate) fn spans_for(
1471
+ &self,
1472
+ obj: &ExId,
1473
+ clock: Option<Clock>,
1474
+ ) -> Result<Spans<'_>, AutomergeError> {
1475
+ let obj = self.exid_to_obj(obj)?;
1476
+ Ok(Spans::new(self.ops.spans(&obj.id, clock)))
1477
+ }
1478
+
1479
+ pub(crate) fn get_cursor_for(
1480
+ &self,
1481
+ obj: &ExId,
1482
+ position: CursorPosition,
1483
+ clock: Option<Clock>,
1484
+ move_cursor: MoveCursor,
1485
+ ) -> Result<Cursor, AutomergeError> {
1486
+ let obj = self.exid_to_obj(obj)?;
1487
+ let Some(seq_type) = obj.typ.as_sequence_type() else {
1488
+ return Err(AutomergeError::InvalidOp(obj.typ));
1489
+ };
1490
+ match position {
1491
+ CursorPosition::Start => Ok(Cursor::Start),
1492
+ CursorPosition::End => Ok(Cursor::End),
1493
+ CursorPosition::Index(i) => {
1494
+ let found = self
1495
+ .ops
1496
+ .seek_ops_by_index(&obj.id, i, seq_type, clock.as_ref());
1497
+
1498
+ if let Some(op) = found.ops.last() {
1499
+ Ok(Cursor::Op(OpCursor::new(op.id, &self.ops, move_cursor)))
1500
+ } else {
1501
+ Err(AutomergeError::InvalidIndex(i))
1502
+ }
1503
+ }
1504
+ }
1505
+ }
1506
+
1507
+ pub(crate) fn get_cursor_position_for(
1508
+ &self,
1509
+ obj: &ExId,
1510
+ cursor: &Cursor,
1511
+ clock: Option<Clock>,
1512
+ ) -> Result<usize, AutomergeError> {
1513
+ match cursor {
1514
+ Cursor::Start => Ok(0),
1515
+ Cursor::End => Ok(self.length_for(obj, clock)),
1516
+ Cursor::Op(op) => {
1517
+ let obj_meta = self.exid_to_obj(obj)?;
1518
+
1519
+ let Some(seq_type) = obj_meta.typ.as_sequence_type() else {
1520
+ return Err(AutomergeError::InvalidCursor(cursor.clone()));
1521
+ };
1522
+
1523
+ let opid = self.op_cursor_to_opid(op, clock.as_ref())?;
1524
+
1525
+ let found = self
1526
+ .ops
1527
+ .seek_list_opid(&obj_meta.id, opid, seq_type, clock.as_ref())
1528
+ .ok_or_else(|| AutomergeError::InvalidCursor(cursor.clone()))?;
1529
+
1530
+ match op.move_cursor {
1531
+ // `MoveCursor::After` mimics the original behavior of cursors.
1532
+ //
1533
+ // The original behavior was to just return the `FoundOpId::index` found by
1534
+ // `OpSetInternal::seek_list_opid()`.
1535
+ //
1536
+ // This index always corresponds to the:
1537
+ // - index of the item itself (if it's visible at `clock`)
1538
+ // - next index of visible item that **was also visible at the time of cursor creation**
1539
+ // (if the item is not visible at `clock`).
1540
+ // - or `sequence.length` if none of the next items are visible at `clock`.
1541
+ MoveCursor::After => Ok(found.index),
1542
+ MoveCursor::Before => {
1543
+ // `MoveCursor::Before` behaves like `MoveCursor::After` but in the opposite direction:
1544
+ //
1545
+ // - if the item is visible at `clock`, just return its index
1546
+ // - if the item isn't visible at `clock`, find the index of the **previous** item
1547
+ // that's visible at `clock` that was also visible at the time of cursor creation.
1548
+ // - if none of the previous items are visible (or the index of the original item is 0),
1549
+ // our index is `0`.
1550
+ if found.visible || found.index == 0 {
1551
+ Ok(found.index)
1552
+ } else {
1553
+ // FIXME: this should probably be an `OpSet` query
1554
+ // also this implementation is likely very inefficient
1555
+
1556
+ // current implementation walks upwards through `key` of op pointed to by cursor
1557
+ // and checks if `key` is visible by using `seek_list_opid()`.
1558
+
1559
+ let mut key = found
1560
+ .op.key.elemid()
1561
+ .expect("failed to retrieve initial cursor op key for MoveCursor::Before")
1562
+ .0;
1563
+
1564
+ loop {
1565
+ let f = self.ops.seek_list_opid(
1566
+ &obj_meta.id,
1567
+ key,
1568
+ seq_type,
1569
+ clock.as_ref(),
1570
+ );
1571
+
1572
+ match f {
1573
+ Some(f) => {
1574
+ if f.visible {
1575
+ return Ok(f.index);
1576
+ }
1577
+
1578
+ key = f
1579
+ .op
1580
+ .key
1581
+ .elemid()
1582
+ .expect(
1583
+ "failed to retrieve op key in MoveCursor::Before",
1584
+ )
1585
+ .0;
1586
+ }
1587
+ // reached when we've gone before the beginning of the sequence
1588
+ None => break Ok(0),
1589
+ }
1590
+ }
1591
+ }
1592
+ }
1593
+ }
1594
+ }
1595
+ }
1596
+ }
1597
+
1598
+ pub(crate) fn marks_for(
1599
+ &self,
1600
+ obj: &ExId,
1601
+ clock: Option<Clock>,
1602
+ ) -> Result<Vec<Mark>, AutomergeError> {
1603
+ self.calculate_marks(obj, clock)
1604
+ }
1605
+
1606
+ pub(crate) fn get_for(
1607
+ &self,
1608
+ obj: &ExId,
1609
+ prop: Prop,
1610
+ clock: Option<Clock>,
1611
+ ) -> Result<Option<(Value<'_>, ExId)>, AutomergeError> {
1612
+ let obj = self.exid_to_obj(obj)?;
1613
+ let op = match (obj.typ, prop) {
1614
+ (ObjType::Map | ObjType::Table, Prop::Map(key)) => self
1615
+ .ops
1616
+ .seek_ops_by_map_key(&obj.id, &key, clock.as_ref())
1617
+ .ops
1618
+ .into_iter()
1619
+ .next_back()
1620
+ .map(|op| op.tagged_value(self.ops())),
1621
+ (ObjType::List | ObjType::Text, Prop::Seq(i)) => {
1622
+ let seq_type = obj
1623
+ .typ
1624
+ .as_sequence_type()
1625
+ .expect("list and text must have a sequence type");
1626
+ self.ops
1627
+ .seek_ops_by_index(&obj.id, i, seq_type, clock.as_ref())
1628
+ .ops
1629
+ .into_iter()
1630
+ .next_back()
1631
+ .map(|op| op.tagged_value(self.ops()))
1632
+ }
1633
+ _ => return Err(AutomergeError::InvalidOp(obj.typ)),
1634
+ };
1635
+ Ok(op)
1636
+ }
1637
+
1638
+ pub(crate) fn get_all_for<O: AsRef<ExId>, P: Into<Prop>>(
1639
+ &self,
1640
+ obj: O,
1641
+ prop: P,
1642
+ clock: Option<Clock>,
1643
+ ) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError> {
1644
+ let prop = prop.into();
1645
+ let obj = self.exid_to_obj(obj.as_ref())?;
1646
+ let values = match (obj.typ, prop) {
1647
+ (ObjType::Map | ObjType::Table, Prop::Map(key)) => self
1648
+ .ops
1649
+ .seek_ops_by_map_key(&obj.id, &key, clock.as_ref())
1650
+ .ops
1651
+ .into_iter()
1652
+ .map(|op| op.tagged_value(self.ops()))
1653
+ .collect::<Vec<_>>(),
1654
+ (ObjType::List | ObjType::Text, Prop::Seq(i)) => {
1655
+ let seq_type = obj
1656
+ .typ
1657
+ .as_sequence_type()
1658
+ .expect("list and text must have a sequence type");
1659
+ self.ops
1660
+ .seek_ops_by_index(&obj.id, i, seq_type, clock.as_ref())
1661
+ .ops
1662
+ .into_iter()
1663
+ .map(|op| op.tagged_value(self.ops()))
1664
+ .collect::<Vec<_>>()
1665
+ }
1666
+ _ => return Err(AutomergeError::InvalidOp(obj.typ)),
1667
+ };
1668
+ // this is a test to make sure opid and exid are always sorting the same way
1669
+ assert_eq!(
1670
+ values.iter().map(|v| &v.1).collect::<Vec<_>>(),
1671
+ values.iter().map(|v| &v.1).sorted().collect::<Vec<_>>()
1672
+ );
1673
+ Ok(values)
1674
+ }
1675
+
1676
+ pub(crate) fn get_marks_for<O: AsRef<ExId>>(
1677
+ &self,
1678
+ obj: O,
1679
+ index: usize,
1680
+ clock: Option<Clock>,
1681
+ ) -> Result<MarkSet, AutomergeError> {
1682
+ let obj = self.exid_to_obj(obj.as_ref())?;
1683
+ let mut iter = self
1684
+ .ops
1685
+ .iter_obj(&obj.id)
1686
+ .visible_slow(clock)
1687
+ .top_ops()
1688
+ .marks();
1689
+ iter.nth(index);
1690
+ match iter.get_marks() {
1691
+ Some(arc) => Ok(arc.as_ref().clone().without_unmarks()),
1692
+ None => Ok(MarkSet::default()),
1693
+ }
1694
+ }
1695
+
1696
+ fn convert_scalar_strings_to_text(&mut self) -> Result<(), AutomergeError> {
1697
+ struct Conversion {
1698
+ obj_id: ExId,
1699
+ prop: Prop,
1700
+ text: smol_str::SmolStr,
1701
+ }
1702
+ let mut to_convert = Vec::new();
1703
+ for (obj, ops) in self.ops.iter_objs() {
1704
+ match obj.typ {
1705
+ ObjType::Map | ObjType::List => {
1706
+ for op in ops.visible_slow(None) {
1707
+ //if !op.visible() {
1708
+ // continue;
1709
+ //}
1710
+ if let OpType::Put(ScalarValue::Str(s)) = op.op_type() {
1711
+ let prop = match op.key {
1712
+ KeyRef::Map(prop) => Prop::Map(prop.into()),
1713
+ KeyRef::Seq(_) => {
1714
+ let Some(found) = self.ops.seek_list_opid(
1715
+ &obj.id,
1716
+ op.id,
1717
+ SequenceType::List,
1718
+ None,
1719
+ ) else {
1720
+ continue;
1721
+ };
1722
+ Prop::Seq(found.index)
1723
+ }
1724
+ };
1725
+ to_convert.push(Conversion {
1726
+ obj_id: self.ops.id_to_exid(obj.id.0),
1727
+ prop,
1728
+ text: smol_str::SmolStr::from(s),
1729
+ })
1730
+ }
1731
+ }
1732
+ }
1733
+ _ => {}
1734
+ }
1735
+ }
1736
+
1737
+ if !to_convert.is_empty() {
1738
+ let mut tx = self.transaction();
1739
+ for Conversion { obj_id, prop, text } in to_convert {
1740
+ let text_id = tx.put_object(obj_id, prop, ObjType::Text)?;
1741
+ tx.splice_text(&text_id, 0, 0, &text)?;
1742
+ }
1743
+ tx.commit();
1744
+ }
1745
+
1746
+ Ok(())
1747
+ }
1748
+
1749
+ /// Whether the peer represented by `other` has all the changes we have
1750
+ pub fn has_our_changes(&self, other: &crate::sync::State) -> bool {
1751
+ other.shared_heads == self.get_heads()
1752
+ }
1753
+
1754
+ pub(crate) fn has_change(&self, head: &ChangeHash) -> bool {
1755
+ self.change_graph.has_change(head)
1756
+ }
1757
+
1758
+ pub fn text_encoding(&self) -> TextEncoding {
1759
+ self.ops.text_encoding
1760
+ }
1761
+ }
1762
+
1763
+ impl ReadDoc for Automerge {
1764
+ fn parents<O: AsRef<ExId>>(&self, obj: O) -> Result<Parents<'_>, AutomergeError> {
1765
+ self.parents_for(obj.as_ref(), None)
1766
+ }
1767
+
1768
+ fn parents_at<O: AsRef<ExId>>(
1769
+ &self,
1770
+ obj: O,
1771
+ heads: &[ChangeHash],
1772
+ ) -> Result<Parents<'_>, AutomergeError> {
1773
+ let clock = self.clock_at(heads);
1774
+ self.parents_for(obj.as_ref(), Some(clock))
1775
+ }
1776
+
1777
+ fn keys<O: AsRef<ExId>>(&self, obj: O) -> Keys<'_> {
1778
+ self.keys_for(obj.as_ref(), None)
1779
+ }
1780
+
1781
+ fn keys_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> Keys<'_> {
1782
+ let clock = self.clock_at(heads);
1783
+ self.keys_for(obj.as_ref(), Some(clock))
1784
+ }
1785
+
1786
+ fn iter_at<O: AsRef<ExId>>(&self, obj: O, heads: Option<&[ChangeHash]>) -> DocIter<'_> {
1787
+ //let obj = self.exid_to_obj(obj.as_ref()).unwrap();
1788
+ let clock = heads.map(|heads| self.clock_at(heads));
1789
+ self.iter_for(obj.as_ref(), clock)
1790
+ }
1791
+
1792
+ fn map_range<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>(
1793
+ &'a self,
1794
+ obj: O,
1795
+ range: R,
1796
+ ) -> MapRange<'a> {
1797
+ self.map_range_for(obj.as_ref(), range, None)
1798
+ }
1799
+
1800
+ fn map_range_at<'a, O: AsRef<ExId>, R: RangeBounds<String> + 'a>(
1801
+ &'a self,
1802
+ obj: O,
1803
+ range: R,
1804
+ heads: &[ChangeHash],
1805
+ ) -> MapRange<'a> {
1806
+ let clock = self.clock_at(heads);
1807
+ self.map_range_for(obj.as_ref(), range, Some(clock))
1808
+ }
1809
+
1810
+ fn list_range<O: AsRef<ExId>, R: RangeBounds<usize>>(&self, obj: O, range: R) -> ListRange<'_> {
1811
+ self.list_range_for(obj.as_ref(), range, None)
1812
+ }
1813
+
1814
+ fn list_range_at<O: AsRef<ExId>, R: RangeBounds<usize>>(
1815
+ &self,
1816
+ obj: O,
1817
+ range: R,
1818
+ heads: &[ChangeHash],
1819
+ ) -> ListRange<'_> {
1820
+ let clock = self.clock_at(heads);
1821
+ self.list_range_for(obj.as_ref(), range, Some(clock))
1822
+ }
1823
+
1824
+ fn values<O: AsRef<ExId>>(&self, obj: O) -> Values<'_> {
1825
+ self.values_for(obj.as_ref(), None)
1826
+ }
1827
+
1828
+ fn values_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> Values<'_> {
1829
+ let clock = self.clock_at(heads);
1830
+ self.values_for(obj.as_ref(), Some(clock))
1831
+ }
1832
+
1833
+ fn length<O: AsRef<ExId>>(&self, obj: O) -> usize {
1834
+ self.length_for(obj.as_ref(), None)
1835
+ }
1836
+
1837
+ fn length_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> usize {
1838
+ let clock = self.clock_at(heads);
1839
+ self.length_for(obj.as_ref(), Some(clock))
1840
+ }
1841
+
1842
+ fn text<O: AsRef<ExId>>(&self, obj: O) -> Result<String, AutomergeError> {
1843
+ self.text_for(obj.as_ref(), None)
1844
+ }
1845
+
1846
+ fn spans<O: AsRef<ExId>>(&self, obj: O) -> Result<Spans<'_>, AutomergeError> {
1847
+ self.spans_for(obj.as_ref(), None)
1848
+ }
1849
+
1850
+ fn spans_at<O: AsRef<ExId>>(
1851
+ &self,
1852
+ obj: O,
1853
+ heads: &[ChangeHash],
1854
+ ) -> Result<Spans<'_>, AutomergeError> {
1855
+ let clock = self.clock_at(heads);
1856
+ self.spans_for(obj.as_ref(), Some(clock))
1857
+ }
1858
+
1859
+ fn get_cursor<O: AsRef<ExId>, I: Into<CursorPosition>>(
1860
+ &self,
1861
+ obj: O,
1862
+ position: I,
1863
+ at: Option<&[ChangeHash]>,
1864
+ ) -> Result<Cursor, AutomergeError> {
1865
+ let clock = at.map(|heads| self.clock_at(heads));
1866
+ self.get_cursor_for(obj.as_ref(), position.into(), clock, MoveCursor::After)
1867
+ }
1868
+
1869
+ fn get_cursor_moving<O: AsRef<ExId>, I: Into<CursorPosition>>(
1870
+ &self,
1871
+ obj: O,
1872
+ position: I,
1873
+ at: Option<&[ChangeHash]>,
1874
+ move_cursor: MoveCursor,
1875
+ ) -> Result<Cursor, AutomergeError> {
1876
+ let clock = at.map(|heads| self.clock_at(heads));
1877
+ self.get_cursor_for(obj.as_ref(), position.into(), clock, move_cursor)
1878
+ }
1879
+
1880
+ fn get_cursor_position<O: AsRef<ExId>>(
1881
+ &self,
1882
+ obj: O,
1883
+ cursor: &Cursor,
1884
+ at: Option<&[ChangeHash]>,
1885
+ ) -> Result<usize, AutomergeError> {
1886
+ let clock = at.map(|heads| self.clock_at(heads));
1887
+ self.get_cursor_position_for(obj.as_ref(), cursor, clock)
1888
+ }
1889
+
1890
+ fn text_at<O: AsRef<ExId>>(
1891
+ &self,
1892
+ obj: O,
1893
+ heads: &[ChangeHash],
1894
+ ) -> Result<String, AutomergeError> {
1895
+ let clock = self.clock_at(heads);
1896
+ self.text_for(obj.as_ref(), Some(clock))
1897
+ }
1898
+
1899
+ fn marks<O: AsRef<ExId>>(&self, obj: O) -> Result<Vec<Mark>, AutomergeError> {
1900
+ self.marks_for(obj.as_ref(), None)
1901
+ }
1902
+
1903
+ fn marks_at<O: AsRef<ExId>>(
1904
+ &self,
1905
+ obj: O,
1906
+ heads: &[ChangeHash],
1907
+ ) -> Result<Vec<Mark>, AutomergeError> {
1908
+ let clock = self.clock_at(heads);
1909
+ self.marks_for(obj.as_ref(), Some(clock))
1910
+ }
1911
+
1912
+ fn hydrate<O: AsRef<ExId>>(
1913
+ &self,
1914
+ obj: O,
1915
+ heads: Option<&[ChangeHash]>,
1916
+ ) -> Result<hydrate::Value, AutomergeError> {
1917
+ let obj = self.exid_to_obj(obj.as_ref())?;
1918
+ let clock = heads.map(|h| self.clock_at(h));
1919
+ Ok(match obj.typ {
1920
+ ObjType::List => self.hydrate_list(&obj.id, clock.as_ref()),
1921
+ ObjType::Text => self.hydrate_text(&obj.id, clock.as_ref()),
1922
+ _ => self.hydrate_map(&obj.id, clock.as_ref()),
1923
+ })
1924
+ }
1925
+
1926
+ fn get_marks<O: AsRef<ExId>>(
1927
+ &self,
1928
+ obj: O,
1929
+ index: usize,
1930
+ heads: Option<&[ChangeHash]>,
1931
+ ) -> Result<MarkSet, AutomergeError> {
1932
+ let clock = heads.map(|h| self.clock_at(h));
1933
+ self.get_marks_for(obj.as_ref(), index, clock)
1934
+ }
1935
+
1936
+ fn get<O: AsRef<ExId>, P: Into<Prop>>(
1937
+ &self,
1938
+ obj: O,
1939
+ prop: P,
1940
+ ) -> Result<Option<(Value<'_>, ExId)>, AutomergeError> {
1941
+ self.get_for(obj.as_ref(), prop.into(), None)
1942
+ }
1943
+
1944
+ fn get_at<O: AsRef<ExId>, P: Into<Prop>>(
1945
+ &self,
1946
+ obj: O,
1947
+ prop: P,
1948
+ heads: &[ChangeHash],
1949
+ ) -> Result<Option<(Value<'_>, ExId)>, AutomergeError> {
1950
+ let clock = Some(self.clock_at(heads));
1951
+ self.get_for(obj.as_ref(), prop.into(), clock)
1952
+ }
1953
+
1954
+ fn get_all<O: AsRef<ExId>, P: Into<Prop>>(
1955
+ &self,
1956
+ obj: O,
1957
+ prop: P,
1958
+ ) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError> {
1959
+ self.get_all_for(obj.as_ref(), prop.into(), None)
1960
+ }
1961
+
1962
+ fn get_all_at<O: AsRef<ExId>, P: Into<Prop>>(
1963
+ &self,
1964
+ obj: O,
1965
+ prop: P,
1966
+ heads: &[ChangeHash],
1967
+ ) -> Result<Vec<(Value<'_>, ExId)>, AutomergeError> {
1968
+ let clock = Some(self.clock_at(heads));
1969
+ self.get_all_for(obj.as_ref(), prop.into(), clock)
1970
+ }
1971
+
1972
+ fn object_type<O: AsRef<ExId>>(&self, obj: O) -> Result<ObjType, AutomergeError> {
1973
+ let obj = obj.as_ref();
1974
+ let opid = self.exid_to_opid(obj)?;
1975
+ let typ = self.ops.object_type(&ObjId(opid));
1976
+ typ.ok_or_else(|| AutomergeError::InvalidObjId(obj.to_string()))
1977
+ }
1978
+
1979
+ #[inline(never)]
1980
+ fn get_missing_deps(&self, heads: &[ChangeHash]) -> Vec<ChangeHash> {
1981
+ let mut missing = HashSet::new();
1982
+
1983
+ for head in self.queue.iter().flat_map(|change| change.deps()) {
1984
+ if !self.has_change(head) {
1985
+ missing.insert(head);
1986
+ }
1987
+ }
1988
+
1989
+ for head in heads {
1990
+ if !self.has_change(head) {
1991
+ missing.insert(head);
1992
+ }
1993
+ }
1994
+
1995
+ let mut missing = missing
1996
+ .into_iter()
1997
+ .filter(|hash| !self.queue.has_hash(hash))
1998
+ .copied()
1999
+ .collect::<Vec<_>>();
2000
+ missing.sort();
2001
+ missing
2002
+ }
2003
+
2004
+ fn get_change_by_hash(&self, hash: &ChangeHash) -> Option<Change> {
2005
+ ChangeCollector::for_hashes(&self.ops, &self.change_graph, [*hash])
2006
+ .ok()?
2007
+ .pop()
2008
+ }
2009
+
2010
+ fn stats(&self) -> crate::read::Stats {
2011
+ let num_changes = self.change_graph.len() as u64;
2012
+ let num_ops = self.ops.len() as u64;
2013
+ let num_actors = self.ops.actors.len() as u64;
2014
+ let cargo_package_name = env!("CARGO_PKG_NAME");
2015
+ let cargo_package_version = env!("CARGO_PKG_VERSION");
2016
+ let rustc_version = env!("CARGO_PKG_RUST_VERSION");
2017
+ crate::read::Stats {
2018
+ num_changes,
2019
+ num_ops,
2020
+ num_actors,
2021
+ cargo_package_name,
2022
+ cargo_package_version,
2023
+ rustc_version,
2024
+ }
2025
+ }
2026
+
2027
+ fn text_encoding(&self) -> TextEncoding {
2028
+ self.ops.text_encoding
2029
+ }
2030
+ }
2031
+
2032
+ impl Default for Automerge {
2033
+ fn default() -> Self {
2034
+ Self::new()
2035
+ }
2036
+ }
2037
+
2038
+ /// Options to pass to [`Automerge::save_with_options()`] and [`crate::AutoCommit::save_with_options()`]
2039
+ #[derive(Debug)]
2040
+ pub struct SaveOptions {
2041
+ /// Whether to apply DEFLATE compression to the RLE encoded columns in the document
2042
+ pub deflate: bool,
2043
+ /// Whether to save changes which we do not have the dependencies for
2044
+ pub retain_orphans: bool,
2045
+ }
2046
+
2047
+ impl SaveOptions {
2048
+ fn compress(&self) -> CompressConfig {
2049
+ if self.deflate {
2050
+ CompressConfig::Threshold(change::DEFLATE_MIN_SIZE)
2051
+ } else {
2052
+ CompressConfig::None
2053
+ }
2054
+ }
2055
+ }
2056
+
2057
+ impl std::default::Default for SaveOptions {
2058
+ fn default() -> Self {
2059
+ Self {
2060
+ deflate: true,
2061
+ retain_orphans: true,
2062
+ }
2063
+ }
2064
+ }
2065
+
2066
+ #[derive(Debug)]
2067
+ pub(crate) struct Isolation {
2068
+ actor_index: usize,
2069
+ seq: u64,
2070
+ clock: Clock,
2071
+ }