y-rb 0.1.3 → 0.1.4.alpha.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.
data/Rakefile DELETED
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "yard"
6
- require "rubocop/rake_task"
7
- require "thermite/tasks"
8
-
9
- RSpec::Core::RakeTask.new(:spec)
10
-
11
- RuboCop::RakeTask.new
12
-
13
- task default: %i[spec rubocop]
14
-
15
- desc "Compile the y-rb crate"
16
- task :compile do
17
- # MacOS: ARM + x64
18
- `cargo build --release --target=aarch64-apple-darwin`
19
- `cargo build --release --target=x86_64-apple-darwin`
20
-
21
- # Copy to target folder
22
- `cp target/aarch64-apple-darwin/release/liby_rb.dylib target/release/`
23
- end
24
-
25
- task :clean do
26
- `cargo clean`
27
- end
28
-
29
- task test: :spec
30
-
31
- task :docs do
32
- `yard server --reload`
33
- end
34
-
35
- RuboCop::RakeTask.new
36
-
37
- YARD::Rake::YardocTask.new
38
-
39
- Thermite::Tasks.new
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "y/rb"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/build/Dockerfile DELETED
@@ -1,18 +0,0 @@
1
- ARG CROSS_BASE_IMAGE
2
- FROM $CROSS_BASE_IMAGE
3
-
4
- ENV RUBY_VERSION=3.1.2
5
-
6
- RUN apt-get update -yq && apt-get install -yq build-essential gnupg2 openssl ruby ruby-dev
7
- RUN curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -
8
- RUN curl -L https://get.rvm.io | bash -s stable
9
- RUN /bin/bash -l -c "rvm requirements"
10
- RUN /bin/bash -l -c "rvm install 3.1.2"
11
- RUN /bin/bash -l -c "rvm install 3.0.4"
12
- RUN /bin/bash -l -c "rvm install 2.7.6"
13
- RUN /bin/bash -l -c "rvm install 2.6.10"
14
-
15
- COPY build/entrypoint.sh /
16
- RUN chmod +x "/entrypoint.sh"
17
-
18
- ENTRYPOINT ["/entrypoint.sh"]
data/build/build.rb DELETED
@@ -1,105 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "active_support/core_ext/string"
5
- require "fileutils"
6
- require "minitar"
7
- require "zlib"
8
-
9
- require_relative "../lib/y/version"
10
-
11
- RUBIES = %w[2.6.10 2.7.6 3.0.4 3.1.2].freeze
12
-
13
- # darwin20 = mac os 11.x
14
- # darwin21 = mac os 12.x
15
- # darwin22 = mac os 13.x
16
- TARGETS = {
17
- "aarch64-apple-darwin": {
18
- cpu: "arm64",
19
- os: "darwin21"
20
- },
21
- "aarch64-unknown-linux-gnu": {
22
- cpu: "arm64",
23
- os: "linux"
24
- },
25
- "aarch64-unknown-linux-musl": {
26
- cpu: "arm64",
27
- os: "linux-musl",
28
- env: {
29
- "RUSTFLAGS" => "\"-C target-feature=-crt-static\""
30
- }
31
- },
32
- "x86_64-unknown-linux-gnu": {
33
- cpu: "x86_64",
34
- os: "linux"
35
- },
36
- "x86_64-unknown-linux-musl": {
37
- cpu: "x86_64",
38
- os: "linux-musl",
39
- env: {
40
- "RUSTFLAGS" => "\"-C target-feature=-crt-static\""
41
- }
42
- }
43
- }.freeze
44
-
45
- def build_lib(target, options, ruby_version) # rubocop:disable Metrics/MethodLength
46
- env_vars = if !options.nil? && options.key?(:env)
47
- target_env = target.to_s.underscore.upcase
48
- options[:env]
49
- .map { |env, value| "CARGO_TARGET_#{target_env}_#{env}=#{value}" }
50
- .join(" ")
51
- else
52
- ""
53
- end
54
-
55
- cmd = [
56
- "cargo clean",
57
- "#{env_vars} RUBY_VERSION=#{ruby_version} cross build --target=#{target} --release"
58
- ].join(" && ")
59
-
60
- `#{cmd}`
61
- end
62
-
63
- def copy_lib(target)
64
- path = "#{__dir__}/../target/#{target}/release"
65
-
66
- file = Dir["#{path}/*{dylib,so}"].first
67
-
68
- extension = File.extname(file)
69
- dest = "#{path}/y_rb#{extension}"
70
-
71
- FileUtils.cp(file, dest)
72
-
73
- dest
74
- end
75
-
76
- # Build
77
-
78
- FileUtils.rm_rf "#{__dir__}/out"
79
-
80
- TARGETS.each do |target, options|
81
- RUBIES.each do |ruby_version|
82
- puts "Build: target=#{target}, ruby=#{ruby_version}"
83
-
84
- version = Gem::Version.new(ruby_version)
85
- version_segments = version.canonical_segments
86
- ruby_version_string = "#{version_segments[0]}#{version_segments[1]}"
87
-
88
- build_lib(target, options, ruby_version)
89
- file = copy_lib(target)
90
-
91
- raise "Build failed" if file.nil?
92
-
93
- extension = File.extname(file)
94
- dir = "#{__dir__}/out/y_rb-#{Y::VERSION}-ruby#{ruby_version_string}-#{options[:os]}-#{options[:cpu]}"
95
- FileUtils.mkdir_p(dir)
96
- FileUtils.cp(file, "#{dir}/y_rb#{extension}")
97
-
98
- archive = "#{dir}/y_rb-#{Y::VERSION}-ruby#{ruby_version_string}-#{options[:os]}-#{options[:cpu]}.tar.gz"
99
- Zlib::GzipWriter.open(archive) do |tgz|
100
- Dir.chdir(dir) do
101
- Archive::Tar::Minitar.pack(".", tgz)
102
- end
103
- end
104
- end
105
- end
data/build/entrypoint.sh DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- /bin/bash -l -c "rvm --default use $RUBY_VERSION" && exec "$@"
data/docs/decisions.md DELETED
@@ -1,64 +0,0 @@
1
- # Decision log
2
-
3
- ## 2022-05-12
4
-
5
- ### Transactions do not always commit automatically
6
-
7
- In `yrs`, the lifetime of a transaction is determined automatically. This can
8
- lead to an interesting situation in Ruby, where we attach a listener to receive
9
- changes, never commit a transaction explicitly and where the transaction gets
10
- dropped automatically. I believe we still maintain a pointer to the transaction
11
- that no longer exists, and therefore we receive a segfault.
12
-
13
- ## 2022-05-12
14
-
15
- ### Add event-driven approach to receive changes
16
-
17
- It is not clear if this ends up being the final API to receive changes, but
18
- it is the one that is supported in one or the other way across all `yrs`
19
- implementations. It might be beneficial to add a synchronous API in the future,
20
- but this isn't supported right away. All common styles of closure like behavior
21
- are supported: `Proc`, `Lambda` and `Block`.
22
-
23
- ## 2022-05-09
24
-
25
- ### Supported operations on data types are either read-only or mutable
26
-
27
- In a meeting with the wider `y-crdt` group on May 6th, 2022, it became clear
28
- that the cost of creating a new instance of a data type is common operation in
29
- many languages (Python, Ruby, …), but it is not something we should to support.
30
- This pattern leads to all sort of problems, mostly because it contradicts the
31
- common usage pattern of replicating changes between two or more clients.
32
-
33
- Instead, the API should be explicit about this fact and should not make it too
34
- easy to do that.
35
-
36
- ## 2022-05-06
37
-
38
- ### Transactions are implicit by default
39
-
40
- The developer should not be exposed to transactions until they need to
41
- change the default logic in any way. If someone creates a structure and inserts,
42
- removes, this should be part of the same transaction until stated otherwise.
43
-
44
- ### Synchronisation happens at the document level
45
-
46
- It might be interesting to sync at a more granular level, but for the sake of
47
- simplicity, the first iteration of this library will only support
48
- synchronization of the complete document.
49
-
50
- ## 2022-05-05
51
-
52
- ### No direct exposure of internal API
53
-
54
- The internal API (`y-crdt`) is subject to constant changes and does not
55
- necessarily offer an idiomatic Ruby interface. Therefore, the public API of
56
- `y-rb` does not follow the `y-crdt` API, but prefers familiar Ruby idioms when
57
- possible and might even require libraries where it makes sense (e.g. `nokogiri` for XML).
58
-
59
- ### Rutie is a temporary dependency
60
-
61
- The Ruby<->Rust binding feels immature. But it is not the goal of this project
62
- to fix this immediately. The long-term vision is to replace this part by
63
- something more lightweight and opinionated that could be part of the Rust
64
- codebase of this project.
data/docs/examples.md DELETED
@@ -1,16 +0,0 @@
1
- # Examples
2
-
3
- > Usage patterns
4
-
5
- ## Send a full document update to a client
6
-
7
- ```ruby
8
- doc = Y::Doc.new
9
- text = doc.get_text("about")
10
- text << "My name is, my name is, my name is … Slim Shady"
11
-
12
- zero = Y::Doc.new
13
- update = doc.diff(zero.state)
14
-
15
- transfer update
16
- ```
data/docs/release.md DELETED
@@ -1,36 +0,0 @@
1
- # Release
2
-
3
- ## Steps
4
-
5
- 1. Make sure CI is green
6
- 2. Update version in `Cargo.toml`
7
- 3. Update version in `lib/y/version.rb`
8
- 4. Create a tag matching the version `git tag -a vx.x.x -m "Release version vx.x.x"`
9
- 5. Push tag to GitHub repo: `git push vx.x.x`
10
- 6. Create a GitHub release (requires GitHub CLI): `gh release create vx.x.x ./build/out/*/*.gz`
11
- 7. Package and upload gem: `gem build && gem push y-rb-x.x.x.gem`
12
-
13
- ## Cross-compile binaries (to be released as assets on GitHub)
14
-
15
- There is a script in `./build` that automates a fair chunk of work, but it is
16
- not bulletproof. I mainly use it to compile for arm64 platforms on my machine,
17
- and then upload manually. Most binaries (especially x86) should come from CI.
18
-
19
- It also includes a workaround for Alpine (popular in Docker images) what usually
20
- requires to be a static lib.
21
-
22
- Run the following script. It produces a bunch of archives in `./build/out/`.
23
- You need to upload the produced assets manually after the GitHub release was
24
- created.
25
-
26
- ```bash
27
- ./build/build.rb
28
- ```
29
-
30
- ## Future work
31
-
32
- With this [PR](https://github.com/rubygems/rubygems/pull/5175) merged into
33
- rubygems, we will most likely be able to rely on the extension to manage builds
34
- for us in the future.
35
-
36
- Pre-build binaries are not verified, and are inherently a security concern.
data/ext/Rakefile DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "thermite/tasks"
4
-
5
- project_dir = File.dirname(File.dirname(__FILE__))
6
- Thermite::Tasks.new(cargo_project_path: project_dir,
7
- ruby_project_path: project_dir)
8
-
9
- task default: %w[thermite:build]
data/lib/y/rb.rb DELETED
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rutie"
4
- require_relative "array"
5
- require_relative "doc"
6
- require_relative "map"
7
- require_relative "text"
8
- require_relative "transaction"
9
- require_relative "version"
10
- require_relative "xml"
11
-
12
- module Y
13
- # support pre-built and local built libraries
14
- lib_path = if Dir.exist?(File.join(__dir__, "..", "..", "target", "release"))
15
- nil
16
- else
17
- File.join(__dir__, "..", "..")
18
- end
19
-
20
- Rutie.new(
21
- :y_rb,
22
- lib_path: lib_path
23
- ).init(
24
- "Init_yrb",
25
- File.join(__dir__, "..")
26
- )
27
- end
data/src/lib.rs DELETED
@@ -1,248 +0,0 @@
1
- mod util;
2
- mod yarray;
3
- mod ydoc;
4
- mod ymap;
5
- mod ytext;
6
- mod ytransaction;
7
- mod yxml;
8
-
9
- #[macro_use]
10
- extern crate rutie;
11
-
12
- use rutie::{Module, Object};
13
-
14
- module!(Y);
15
-
16
- #[allow(non_snake_case)]
17
- #[no_mangle]
18
- pub extern "C" fn Init_yrb() {
19
- Module::new("Y").define(|module| {
20
- module.define_nested_class("Array", None).define(|klass| {
21
- klass.def_private("yarray_each", yarray::yarray_each);
22
- klass.def_private("yarray_get", yarray::yarray_get);
23
- klass.def_private("yarray_insert", yarray::yarray_insert);
24
- klass.def_private(
25
- "yarray_insert_range",
26
- yarray::yarray_insert_range
27
- );
28
- klass.def_private("yarray_length", yarray::yarray_length);
29
- klass.def_private("yarray_observe", yarray::yarray_observe);
30
- klass.def_private("yarray_push_back", yarray::yarray_push_back);
31
- klass.def_private("yarray_push_front", yarray::yarray_push_front);
32
- klass.def_private("yarray_remove", yarray::yarray_remove);
33
- klass.def_private(
34
- "yarray_remove_range",
35
- yarray::yarray_remove_range
36
- );
37
- klass.def_private("yarray_to_a", yarray::yarray_to_a);
38
- klass.def_private("yarray_unobserve", yarray::yarray_unobserve);
39
- });
40
-
41
- module.define_nested_class("Doc", None).define(|klass| {
42
- klass.def_self("new", ydoc::ydoc_new);
43
- klass.def_private("ydoc_transact", ydoc::ydoc_transact);
44
- klass.def_private("ydoc_encode_diff_v1", ydoc::ydoc_encode_diff_v1);
45
- });
46
-
47
- module.define_nested_class("Map", None).define(|klass| {
48
- klass.def_private("ymap_clear", ymap::ymap_clear);
49
- klass.def_private("ymap_contains", ymap::ymap_contains);
50
- klass.def_private("ymap_each", ymap::ymap_each);
51
- klass.def_private("ymap_get", ymap::ymap_get);
52
- klass.def_private("ymap_insert", ymap::ymap_insert);
53
- klass.def_private("ymap_observe", ymap::ymap_observe);
54
- klass.def_private("ymap_remove", ymap::ymap_remove);
55
- klass.def_private("ymap_size", ymap::ymap_size);
56
- klass.def_private("ymap_to_h", ymap::ymap_to_hash);
57
- klass.def_private("ymap_unobserve", ymap::ymap_unobserve);
58
- });
59
-
60
- module
61
- .define_nested_class("SubscriptionID", None)
62
- .define(|_klass| {});
63
-
64
- module.define_nested_class("Text", None).define(|klass| {
65
- klass.def_private("ytext_insert", ytext::ytext_insert);
66
- klass.def_private("ytext_insert_embed", ytext::ytext_insert_embed);
67
- klass.def_private(
68
- "ytext_insert_embed_with_attrs",
69
- ytext::ytext_insert_embed_with_attributes
70
- );
71
- klass.def_private(
72
- "ytext_insert_with_attrs",
73
- ytext::ytext_insert_with_attributes
74
- );
75
- klass.def_private("ytext_remove_range", ytext::ytext_remove_range);
76
- klass.def_private("ytext_format", ytext::ytext_format);
77
- klass.def_private("ytext_length", ytext::ytext_length);
78
- klass.def_private("ytext_observe", ytext::ytext_observe);
79
- klass.def_private("ytext_push", ytext::ytext_push);
80
- klass.def_private("ytext_to_s", ytext::ytext_to_string);
81
- klass.def_private("ytext_unobserve", ytext::ytext_unobserve);
82
- });
83
-
84
- module
85
- .define_nested_class("Transaction", None)
86
- .define(|klass| {
87
- klass.def_private(
88
- "ytransaction_apply_update",
89
- ytransaction::ytransaction_apply_update
90
- );
91
- klass.def_private(
92
- "ytransaction_commit",
93
- ytransaction::ytransaction_commit
94
- );
95
- klass.def_private(
96
- "ytransaction_get_array",
97
- ytransaction::ytransaction_get_array
98
- );
99
- klass.def_private(
100
- "ytransaction_get_map",
101
- ytransaction::ytransaction_get_map
102
- );
103
- klass.def_private(
104
- "ytransaction_get_text",
105
- ytransaction::ytransaction_get_text
106
- );
107
- klass.def_private(
108
- "ytransaction_get_xml_element",
109
- ytransaction::ytransaction_get_xml_element
110
- );
111
- klass.def_private(
112
- "ytransaction_get_xml_text",
113
- ytransaction::ytransaction_get_xml_text
114
- );
115
- klass.def_private(
116
- "ytransaction_state_vector",
117
- ytransaction::ytransaction_state_vector
118
- );
119
- });
120
-
121
- module
122
- .define_nested_class("XMLElement", None)
123
- .define(|klass| {
124
- klass.def_private(
125
- "yxml_element_attributes",
126
- yxml::yxml_element_attributes
127
- );
128
- klass.def_private(
129
- "yxml_element_first_child",
130
- yxml::yxml_element_first_child
131
- );
132
- klass.def_private("yxml_element_get", yxml::yxml_element_get);
133
- klass.def_private(
134
- "yxml_element_get_attribute",
135
- yxml::yxml_element_get_attribute
136
- );
137
- klass.def_private(
138
- "yxml_element_insert_attribute",
139
- yxml::yxml_element_insert_attribute
140
- );
141
- klass.def_private(
142
- "yxml_element_insert_element",
143
- yxml::yxml_element_insert_element
144
- );
145
- klass.def_private(
146
- "yxml_element_insert_text",
147
- yxml::yxml_element_insert_text
148
- );
149
- klass.def_private(
150
- "yxml_element_next_sibling",
151
- yxml::yxml_element_next_sibling
152
- );
153
- klass.def_private(
154
- "yxml_element_observe",
155
- yxml::yxml_element_observe
156
- );
157
- klass.def_private(
158
- "yxml_element_parent",
159
- yxml::yxml_element_parent
160
- );
161
- klass.def_private(
162
- "yxml_element_prev_sibling",
163
- yxml::yxml_element_prev_sibling
164
- );
165
- klass.def_private(
166
- "yxml_element_push_elem_back",
167
- yxml::yxml_element_push_elem_back
168
- );
169
- klass.def_private(
170
- "yxml_element_push_elem_front",
171
- yxml::yxml_element_push_elem_front
172
- );
173
- klass.def_private(
174
- "yxml_element_push_text_back",
175
- yxml::yxml_element_push_text_back
176
- );
177
- klass.def_private(
178
- "yxml_element_push_text_front",
179
- yxml::yxml_element_push_text_front
180
- );
181
- klass.def_private(
182
- "yxml_element_remove_attribute",
183
- yxml::yxml_element_remove_attribute
184
- );
185
- klass.def_private(
186
- "yxml_element_remove_range",
187
- yxml::yxml_element_remove_range
188
- );
189
- klass.def_private("yxml_element_size", yxml::yxml_element_size);
190
- klass.def_private("yxml_element_tag", yxml::yxml_element_tag);
191
- klass.def_private(
192
- "yxml_element_to_s",
193
- yxml::yxml_element_to_string
194
- );
195
- klass.def_private(
196
- "yxml_element_unobserve",
197
- yxml::yxml_element_unobserve
198
- );
199
- });
200
-
201
- module.define_nested_class("XMLText", None).define(|klass| {
202
- klass.def_private(
203
- "yxml_text_attributes",
204
- yxml::yxml_text_attributes
205
- );
206
- klass.def_private("yxml_text_format", yxml::yxml_text_format);
207
- klass.def_private(
208
- "yxml_text_get_attribute",
209
- yxml::yxml_text_get_attribute
210
- );
211
- klass.def_private("yxml_text_insert", yxml::yxml_text_insert);
212
- klass.def_private(
213
- "yxml_text_insert_attribute",
214
- yxml::yxml_text_insert_attribute
215
- );
216
- klass.def_private(
217
- "yxml_text_insert_embed",
218
- yxml::yxml_text_insert_embed
219
- );
220
- klass.def_private(
221
- "yxml_text_insert_embed_with_attrs",
222
- yxml::yxml_text_insert_embed_with_attributes
223
- );
224
- klass.def_private(
225
- "yxml_text_insert_with_attrs",
226
- yxml::yxml_text_insert_with_attributes
227
- );
228
- klass.def_private("yxml_text_length", yxml::yxml_text_length);
229
- klass.def_private(
230
- "yxml_text_next_sibling",
231
- yxml::yxml_text_next_sibling
232
- );
233
- klass.def_private("yxml_text_observe", yxml::yxml_text_observe);
234
- klass.def_private("yxml_text_parent", yxml::yxml_text_parent);
235
- klass.def_private(
236
- "yxml_text_prev_sibling",
237
- yxml::yxml_text_prev_sibling
238
- );
239
- klass.def_private("yxml_text_push", yxml::yxml_text_push);
240
- klass.def_private(
241
- "yxml_text_remove_range",
242
- yxml::yxml_text_remove_range
243
- );
244
- klass.def_private("yxml_text_to_s", yxml::yxml_text_to_string);
245
- klass.def_private("yxml_text_unobserve", yxml::yxml_text_unobserve);
246
- });
247
- });
248
- }