mini_racer 0.20.0 → 0.21.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5aa16bf587a6e12df562d7a946ce3a965a8444debd9769b376075cafd10a3b5c
4
- data.tar.gz: 5aaf6a08ae90f05bc554bae0a06e93efce5318d00aacdfe959f36513533caac4
3
+ metadata.gz: 7cd44fe0925a58e264712d933d805af54b517d31cdbefc26455e7e139e234279
4
+ data.tar.gz: 17190bc083b885c838b0dfc3424c3fc08fb02df354972a3007a292ddf70afc22
5
5
  SHA512:
6
- metadata.gz: 2b2641ceb0fd1770efd32cfb9e37aee92ca857ad6acbe2129157a58be9ed6bbef4a355c5af133f5749f229d578e10a452ef77a62eadbe436993f005146d242cd
7
- data.tar.gz: 3264e95d4951aa52ba080a94b847c5080705e1de0e3dd5fefae0786342ccece850b00db4f151220e65068e9e5d62fb0eebae0fda65e79647196903fae70d8012
6
+ metadata.gz: 9cdd4cdf20f9be0e3ceb34daa48f7f1eeb93c4c11eada10c23e2c3e3dbd82cf7a13c8102e67140cc15c028c51a468c6e74ac518c76050cadceb33aa99fd71b7d
7
+ data.tar.gz: c7110aabb771e18bccd85283696e8f811970cf8d03bb0ef1f573a84f2fa7da2ef1014b5138513b09d80825de96ddebe7e6316f79efbe8adecbd1ff202b14e4d5
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ - 0.21.0 - 16-04-2026
2
+ - Add MiniRacer::Binary for returning Uint8Array to JavaScript from attached Ruby callbacks
3
+
1
4
  - 0.20.0 - 24-02-2026
2
5
  - Add Snapshot.load to restore snapshots from binary data, enabling disk persistence
3
6
 
data/README.md CHANGED
@@ -60,6 +60,25 @@ puts context.eval("array_and_hash()")
60
60
  # => {"a" => 1, "b" => [1, {"a" => 1}]}
61
61
  ```
62
62
 
63
+ ### Return binary data from Ruby to JavaScript
64
+
65
+ Attached Ruby functions can return binary data as `Uint8Array` using `MiniRacer::Binary`:
66
+
67
+ ```ruby
68
+ require "digest"
69
+
70
+ context = MiniRacer::Context.new
71
+ context.attach("sha256_raw", ->(data) {
72
+ MiniRacer::Binary.new(Digest::SHA256.digest(data))
73
+ })
74
+
75
+ # Inside JavaScript the return value is a Uint8Array
76
+ context.eval("sha256_raw('hello') instanceof Uint8Array") # => true
77
+ context.eval("sha256_raw('hello').length") # => 32
78
+ ```
79
+
80
+ This is useful when you need to pass raw bytes (e.g., cryptographic digests, compressed data, binary file contents) from Ruby to JavaScript. The `MiniRacer::Binary` wrapper tells the bridge to serialize the data as a `Uint8Array` on the JavaScript side rather than a string.
81
+
63
82
  ### GIL free JavaScript execution
64
83
 
65
84
  The Ruby Global interpreter lock is released when scripts are executing:
@@ -193,6 +193,7 @@ static VALUE terminated_error;
193
193
  static VALUE context_class;
194
194
  static VALUE snapshot_class;
195
195
  static VALUE date_time_class;
196
+ static VALUE binary_class;
196
197
  static VALUE js_function_class;
197
198
 
198
199
  static pthread_mutex_t flags_mtx = PTHREAD_MUTEX_INITIALIZER;
@@ -688,10 +689,17 @@ static int serialize1(Ser *s, VALUE refs, VALUE v)
688
689
  // entirely new objects
689
690
  if (rb_respond_to(v, rb_intern("to_time"))) {
690
691
  v = rb_funcall(v, rb_intern("to_time"), 0);
691
- }
692
- if (rb_obj_is_kind_of(v, rb_cTime)) {
693
- struct timeval tv = rb_time_timeval(v);
694
- ser_date(s, tv.tv_sec*1e3 + tv.tv_usec/1e3);
692
+ if (rb_obj_is_kind_of(v, rb_cTime)) {
693
+ struct timeval tv = rb_time_timeval(v);
694
+ ser_date(s, tv.tv_sec*1e3 + tv.tv_usec/1e3);
695
+ } else {
696
+ snprintf(s->err, sizeof(s->err), "unsupported type %s", rb_class2name(CLASS_OF(v)));
697
+ return -1;
698
+ }
699
+ } else if (!NIL_P(binary_class) && rb_obj_is_kind_of(v, binary_class)) {
700
+ t = rb_ivar_get(v, rb_intern("@data"));
701
+ Check_Type(t, T_STRING);
702
+ ser_uint8array(s, RSTRING_PTR(t), RSTRING_LEN(t));
695
703
  } else {
696
704
  snprintf(s->err, sizeof(s->err), "unsupported type %s", rb_class2name(CLASS_OF(v)));
697
705
  return -1;
@@ -1111,6 +1119,11 @@ static VALUE context_alloc(VALUE klass)
1111
1119
  if (Qtrue == rb_funcall(rb_cObject, f, 1, a))
1112
1120
  date_time_class = rb_const_get(rb_cObject, rb_intern("DateTime"));
1113
1121
  }
1122
+ if (NIL_P(binary_class)) {
1123
+ VALUE m = rb_const_get(rb_cObject, rb_intern("MiniRacer"));
1124
+ if (Qtrue == rb_funcall(m, rb_intern("const_defined?"), 1, rb_str_new_cstr("Binary")))
1125
+ binary_class = rb_const_get(m, rb_intern("Binary"));
1126
+ }
1114
1127
  c = ruby_xmalloc(sizeof(*c));
1115
1128
  memset(c, 0, sizeof(*c));
1116
1129
  c->exception = Qnil;
@@ -1763,5 +1776,6 @@ void Init_mini_racer_extension(void)
1763
1776
  rb_define_singleton_method(c, "set_flags!", platform_set_flags, -1);
1764
1777
 
1765
1778
  date_time_class = Qnil; // lazy init
1779
+ binary_class = Qnil; // lazy init
1766
1780
  js_function_class = rb_define_class_under(m, "JavaScriptFunction", rb_cObject);
1767
1781
  }
@@ -322,6 +322,19 @@ static void ser_string16(Ser *s, const void *p, size_t n)
322
322
  w(s, p, n);
323
323
  }
324
324
 
325
+ // Uint8Array: ArrayBuffer header + data + typed array view descriptor
326
+ static void ser_uint8array(Ser *s, const void *p, size_t n)
327
+ {
328
+ w_byte(s, 'B'); // ArrayBuffer tag
329
+ w_varint(s, n); // byte length
330
+ w(s, p, n); // raw bytes
331
+ w_byte(s, 'V'); // typed array view tag
332
+ w_byte(s, 'B'); // Uint8Array type
333
+ w_varint(s, 0); // byteOffset
334
+ w_varint(s, n); // byteLength
335
+ w_varint(s, 0); // flags
336
+ }
337
+
325
338
  static void ser_object_begin(Ser *s)
326
339
  {
327
340
  w_byte(s, 'o');
@@ -102,7 +102,7 @@ module MiniRacer
102
102
  else
103
103
  @snapshot = nil
104
104
  end
105
- @is_object_or_array_func, @is_map_func, @is_map_iterator_func, @is_time_func, @js_date_to_time_func, @is_symbol_func, @js_symbol_to_symbol_func, @js_new_date_func, @js_new_array_func = eval_in_context <<-CODE
105
+ @is_object_or_array_func, @is_map_func, @is_map_iterator_func, @is_time_func, @js_date_to_time_func, @is_symbol_func, @js_symbol_to_symbol_func, @js_new_date_func, @js_new_array_func, @js_new_uint8array_func = eval_in_context <<-CODE
106
106
  [
107
107
  (x) => { return (x instanceof Object || x instanceof Array) && !(x instanceof Date) && !(x instanceof Function) },
108
108
  (x) => { return x instanceof Map },
@@ -113,6 +113,7 @@ module MiniRacer
113
113
  (x) => { var r = x.description; return r === undefined ? 'undefined' : r },
114
114
  (x) => { return new Date(x) },
115
115
  (x) => { return new Array(x) },
116
+ (x) => { return new Uint8Array(x) },
116
117
  ]
117
118
  CODE
118
119
  end
@@ -329,6 +330,8 @@ module MiniRacer
329
330
  js_new_date(value.to_f * 1000)
330
331
  when DateTime
331
332
  js_new_date(value.to_time.to_f * 1000)
333
+ when MiniRacer::Binary
334
+ @js_new_uint8array_func.call(value.data.bytes)
332
335
  else
333
336
  "Undefined Conversion"
334
337
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniRacer
4
- VERSION = "0.20.0"
4
+ VERSION = "0.21.0"
5
5
  LIBV8_NODE_VERSION = "~> 24.12.0.1"
6
6
  end
data/lib/mini_racer.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  require "mini_racer/version"
2
2
  require "pathname"
3
3
 
4
+ module MiniRacer
5
+ class Binary
6
+ attr_reader :data
7
+
8
+ def initialize(data)
9
+ raise TypeError, "wrong argument type #{data.class} (expected String)" unless data.is_a?(String)
10
+ @data = data
11
+ end
12
+ end
13
+ end
14
+
4
15
  if RUBY_ENGINE == "truffleruby"
5
16
  require "mini_racer/truffleruby"
6
17
  else
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-02-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -113,8 +112,8 @@ email:
113
112
  - sam.saffron@gmail.com
114
113
  executables: []
115
114
  extensions:
116
- - ext/mini_racer_loader/extconf.rb
117
115
  - ext/mini_racer_extension/extconf.rb
116
+ - ext/mini_racer_loader/extconf.rb
118
117
  extra_rdoc_files: []
119
118
  files:
120
119
  - CHANGELOG
@@ -137,10 +136,9 @@ licenses:
137
136
  - MIT
138
137
  metadata:
139
138
  bug_tracker_uri: https://github.com/discourse/mini_racer/issues
140
- changelog_uri: https://github.com/discourse/mini_racer/blob/v0.20.0/CHANGELOG
141
- documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.20.0
142
- source_code_uri: https://github.com/discourse/mini_racer/tree/v0.20.0
143
- post_install_message:
139
+ changelog_uri: https://github.com/discourse/mini_racer/blob/v0.21.0/CHANGELOG
140
+ documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.21.0
141
+ source_code_uri: https://github.com/discourse/mini_racer/tree/v0.21.0
144
142
  rdoc_options: []
145
143
  require_paths:
146
144
  - lib
@@ -156,8 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
154
  - !ruby/object:Gem::Version
157
155
  version: '0'
158
156
  requirements: []
159
- rubygems_version: 3.5.22
160
- signing_key:
157
+ rubygems_version: 4.0.6
161
158
  specification_version: 4
162
159
  summary: Minimal embedded v8 for Ruby
163
160
  test_files: []