automerge-rb 0.1.1-x86_64-linux

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8a0b190bc2d03786af7b242b20f2efe2dc9056e7ff8fd30ed25267885e0deee8
4
+ data.tar.gz: 8ba9b83bc8590d5f530ad50107a3b53234ef1529d1ae7dd9f9925b8b947177ed
5
+ SHA512:
6
+ metadata.gz: f70478ec216bb954f9ecd103ce2cf379967f1111bd38c2b1c15aa543af24edfe9ba9b1eb08b41e63e1ffff155ac35e37509fc7f5f4b725ee009533f7162c7c98
7
+ data.tar.gz: 07cb3f7d6321edaaa4156a3a8f92c0522546078155b4b6ab0282070a8300b52a8e42b1eb92715fd4f21dffded1bfd0dedc7ed85ced8df1ec2cbf46632869fb90
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Automerge Ruby contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # automerge-rb
2
+
3
+ Ruby bindings for the upstream Automerge Rust core.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ gem install automerge-rb
9
+ ```
10
+
11
+ Precompiled native gems are published for the following platforms, so end users
12
+ do **not** need Rust or a C toolchain installed:
13
+
14
+ - `arm64-darwin` (Apple Silicon macOS)
15
+ - `x86_64-darwin` (Intel macOS)
16
+ - `x86_64-linux` (glibc)
17
+ - `aarch64-linux` (glibc)
18
+ - `x64-mingw-ucrt` (Windows)
19
+
20
+ Each native gem ships a fat binary covering Ruby 3.0–3.4. RubyGems auto-selects
21
+ the matching artifact for the host's platform and Ruby ABI at install time.
22
+
23
+ On any other platform `gem install automerge-rb` falls back to building from
24
+ source, which requires Rust (1.89+) and a C compiler. The source build also
25
+ runs whenever you set `--platform=ruby` explicitly.
26
+
27
+ ## Build from source
28
+
29
+ ```sh
30
+ bundle exec rake compile
31
+ ```
32
+
33
+ The Automerge checkout currently requires Rust 1.89 or newer. If your default
34
+ toolchain is older, install one with:
35
+
36
+ ```sh
37
+ rustup toolchain install 1.89.0
38
+ ```
39
+
40
+ The extension builds the Rust core in release mode by default. Use
41
+ `AUTOMERGE_RB_DEBUG=1 bundle exec rake compile` for a faster local debug build.
42
+
43
+ By default `extconf.rb` skips the Rust step if a prebuilt
44
+ `lib/automerge/<ruby-abi>/automerge_ext.<dlext>` already exists (i.e. inside a
45
+ native gem); set `AUTOMERGE_SOURCE_DIR` to point at a different Automerge Rust
46
+ workspace if you want to recompile from a custom checkout.
47
+
48
+ ## Cross-compiling native gems
49
+
50
+ Maintainers can build the published binary set with rake-compiler-dock:
51
+
52
+ ```sh
53
+ bundle exec rake gem:native
54
+ ```
55
+
56
+ This invokes the same docker-backed cross toolchain that the release workflow
57
+ uses, producing `pkg/automerge-rb-<version>-<platform>.gem` for every supported
58
+ platform.
59
+
60
+ ## Test alignment
61
+
62
+ The default test suite includes Ruby ports of upstream Automerge C/Rust
63
+ conformance cases and binary fixture checks:
64
+
65
+ ```sh
66
+ bundle exec rake test
67
+ ```
68
+
69
+ To also run the vendored upstream Rust core test suite, use:
70
+
71
+ ```sh
72
+ bundle exec rake test:upstream_core
73
+ ```
74
+
75
+ To run the upstream C API suite, install CMake and cmocka, then use:
76
+
77
+ ```sh
78
+ bundle exec rake test:upstream_c
79
+ ```
80
+
81
+ For a full local gate, run all three:
82
+
83
+ ```sh
84
+ bundle exec rake conformance
85
+ ```
86
+
87
+ If multiple Rust toolchains are installed, the Rake tasks prefer
88
+ `AUTOMERGE_RB_RUST_TOOLCHAIN` and otherwise use `1.89.0` when present so `cargo`
89
+ and `rustc` stay on the same toolchain.
90
+
91
+ ## Usage
92
+
93
+ ```ruby
94
+ require "automerge"
95
+
96
+ doc = Automerge.from("cards" => [])
97
+ doc.insert(["cards"], 0, "title" => "Rewrite everything in Ruby", "done" => false)
98
+ doc.change(message: "Add card")
99
+
100
+ bytes = doc.save
101
+ loaded = Automerge.load(bytes)
102
+ loaded.to_h
103
+ ```
104
+
105
+ The Ruby API is path-oriented. A path is an array of map keys and list indexes:
106
+
107
+ ```ruby
108
+ doc.put(["cards", 0, "done"], true)
109
+ doc.get(["cards", 0, "done"]) #=> true
110
+ ```
111
+
112
+ Supported Automerge-specific scalar wrappers:
113
+
114
+ ```ruby
115
+ Automerge::Counter.new(1)
116
+ Automerge::Timestamp.new(1_735_689_600_000)
117
+ Automerge::Bytes.new("\x00\x01".b)
118
+ Automerge::Text.new("mutable text")
119
+ Automerge::Uint.new(42)
120
+ ```
121
+
122
+ Implemented document operations include:
123
+
124
+ - map/list/text reads and writes through path arrays
125
+ - commits, empty changes, rollback, actor IDs, heads, and forks
126
+ - save/load, incremental save/load, change lookup, missing deps, and applying changes
127
+ - merge conflict reads with `get_all`
128
+ - the stateful sync protocol with `SyncState`
129
+ - text cursors and text marks
130
+
131
+ ## Historical reads
132
+
133
+ Every read accepts an optional `heads:` keyword argument naming a vector of
134
+ change hashes (typically returned by `Document#heads`). When supplied, the read
135
+ resolves against that historical snapshot instead of the current HEAD:
136
+
137
+ ```ruby
138
+ doc = Automerge.init
139
+ doc.put(["k"], "v1"); doc.commit
140
+ h1 = doc.heads
141
+ doc.put(["k"], "v2"); doc.commit
142
+
143
+ doc.get(["k"]) #=> "v2"
144
+ doc.get(["k"], heads: h1) #=> "v1"
145
+ doc.keys([], heads: h1) #=> ["k"]
146
+ doc.length(["list"], heads: h1)
147
+ doc.cursor_position(["text"], cursor, heads: h1)
148
+ doc.marks(["text"], heads: h1)
149
+ doc.get_all(["k"], heads: h1)
150
+ ```
151
+
152
+ ## Change metadata
153
+
154
+ `Automerge.decode_change(bytes)` unpacks a change-bytes blob (from
155
+ `Document#change_by_hash` or `Document#get_changes`) into a hash describing the
156
+ change. Useful for audit logs and replication tooling:
157
+
158
+ ```ruby
159
+ hash = doc.commit(message: "Add card", timestamp: Time.now.to_i)
160
+ meta = Automerge.decode_change(doc.change_by_hash(hash))
161
+ meta[:message] # => "Add card"
162
+ meta[:actor_id] # => "deadbeef"
163
+ meta[:timestamp] # => 1735689600
164
+ meta[:seq] # => 4
165
+ meta[:deps] # => [<change hash>, ...]
166
+ meta[:empty] # => false
167
+ ```
168
+
169
+ ## Thread safety
170
+
171
+ `Automerge::Document` instances are not thread-safe. Two threads sharing the
172
+ same `Document` must coordinate externally; concurrent mutations or even
173
+ concurrent reads against an in-progress writer will trigger undefined behavior
174
+ in the underlying Rust core. Sharing across threads is safe only after a
175
+ `save`/`load` round-trip or `fork` produces independent documents.
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Automerge
4
+ VERSION = "0.1.1"
5
+ end
6
+
data/lib/automerge.rb ADDED
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "automerge/version"
4
+
5
+ module Automerge
6
+ class Error < StandardError; end
7
+
8
+ class Scalar
9
+ attr_reader :value
10
+
11
+ def initialize(value)
12
+ @value = value
13
+ end
14
+
15
+ def ==(other)
16
+ other.class == self.class && other.value == value
17
+ end
18
+ end
19
+
20
+ class Counter < Scalar; end
21
+ class Timestamp < Scalar; end
22
+ class Uint < Scalar; end
23
+
24
+ class Bytes < Scalar
25
+ def initialize(value)
26
+ @value = String(value).b
27
+ end
28
+ end
29
+
30
+ class Text < Scalar
31
+ def initialize(value = "")
32
+ @value = String(value)
33
+ end
34
+ end
35
+ end
36
+
37
+ begin
38
+ RUBY_VERSION =~ /(\d+\.\d+)/
39
+ require_relative "automerge/#{Regexp.last_match(1)}/automerge_ext"
40
+ rescue LoadError
41
+ require_relative "automerge/automerge_ext"
42
+ end
43
+
44
+ module Automerge
45
+ class Document
46
+ def self.from(value = nil, **opts)
47
+ actor_id = opts.delete(:actor_id)
48
+ value = opts if value.nil? && !opts.empty?
49
+ doc = new(actor_id: actor_id)
50
+ unless value.is_a?(Hash)
51
+ raise ArgumentError, "Automerge document root must be a Hash"
52
+ end
53
+
54
+ value.each do |key, child|
55
+ doc.put([key], child)
56
+ end
57
+ doc.commit
58
+ doc
59
+ end
60
+
61
+ def [](path)
62
+ get(path)
63
+ end
64
+
65
+ def []=(path, value)
66
+ put(path, value)
67
+ end
68
+
69
+ def change(message: nil, timestamp: nil)
70
+ if block_given?
71
+ begin
72
+ yield self
73
+ commit(message, timestamp)
74
+ rescue Exception
75
+ rollback
76
+ raise
77
+ end
78
+ else
79
+ commit(message, timestamp)
80
+ end
81
+ self
82
+ end
83
+
84
+ def to_h
85
+ get([])
86
+ end
87
+
88
+ alias to_hash to_h
89
+
90
+ def sync_state
91
+ SyncState.new
92
+ end
93
+ end
94
+
95
+ def self.init(actor_id: nil)
96
+ Document.new(actor_id: actor_id)
97
+ end
98
+
99
+ def self.from(value = nil, **opts)
100
+ Document.from(value, **opts)
101
+ end
102
+
103
+ def self.load(bytes)
104
+ Document.load(bytes)
105
+ end
106
+
107
+ def self.decode_change(bytes)
108
+ Document.decode_change(bytes)
109
+ end
110
+ end
@@ -0,0 +1,4 @@
1
+ [toolchain]
2
+ channel = "1.89.0"
3
+ profile = "minimal"
4
+ components = ["rustc", "cargo"]
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: automerge-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: x86_64-linux
6
+ authors:
7
+ - Automerge Ruby contributors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
55
+ description: A production-oriented Ruby SDK for Automerge backed by the upstream Rust/C
56
+ core.
57
+ email:
58
+ - maintainers@example.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - LICENSE.txt
64
+ - README.md
65
+ - lib/automerge.rb
66
+ - lib/automerge/3.0/automerge_ext.so
67
+ - lib/automerge/3.1/automerge_ext.so
68
+ - lib/automerge/3.2/automerge_ext.so
69
+ - lib/automerge/3.3/automerge_ext.so
70
+ - lib/automerge/3.4/automerge_ext.so
71
+ - lib/automerge/version.rb
72
+ - rust-toolchain.toml
73
+ homepage: https://github.com/automerge/automerge
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ allowed_push_host: https://rubygems.org
78
+ source_code_uri: https://github.com/automerge/automerge
79
+ changelog_uri: https://github.com/automerge/automerge/blob/main/rust/CHANGELOG.md
80
+ rubygems_mfa_required: 'true'
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: 3.5.dev
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 3.3.22
98
+ requirements: []
99
+ rubygems_version: 3.5.23
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Ruby bindings for the Automerge CRDT core
103
+ test_files: []