hypercast 0.6.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f482418099cb3b96492d839da3f627716b4b4ba6a1b083d66f47f337edb197b3
4
- data.tar.gz: 92e9560c193bd102dbbff75ace2b3aaa8dba75527a217c2b7f730f227af3e27b
3
+ metadata.gz: 53866363cee28bda9e47267c85d4c835708fb9aa20635c3968cb32985d12c264
4
+ data.tar.gz: 654ae196935c0fb5cb8b0393ad11c1a5c5f52845321d1ac6468dfc4dc3159663
5
5
  SHA512:
6
- metadata.gz: 7f24fc4d78125c73b521c631318b778367321438c1791ee8e6055805d8bd2c274f2dd358d30af309350a201faba1aba0772815974a1c187d64896ad4f3f92af0
7
- data.tar.gz: f349625cd4fd7b6dfa1311484186c924705a4c480213ace67aa1a6dea6b68e78d464f9187fbf0da88129c6995cc5f40e99fc01ae001088751ffe66b6e288af14
6
+ metadata.gz: 5fb20b6b023d88e80fc8ea334925310b5436c3aaca0ebcf86606f8794da375823019cc0efbf60445472bdcf6cee4cefd8f76eeb1475d87e3cbead7e26988d8e3
7
+ data.tar.gz: f51ff3c89feaaa99f38fec564f779364b358f1ba7f76c783e24202890e751183172df49352c7eeef6caf8bf54edf10b0493c8d453981e3136dd40791d969d31a
data/README.md CHANGED
@@ -230,7 +230,7 @@ rather than through `Data.new`, whose keyword handling alone cost more than the
230
230
 
231
231
  | `HyperCast::BACKEND` | What runs | Chosen when |
232
232
  |---|---|---|
233
- | `:native` | the core linked into a Magnus extension | a precompiled platform gem is installed — every one carries an extension for each Ruby it installs on; see [Install](#install) |
233
+ | `:native` | the core linked into a Magnus extension | a precompiled platform gem is installed — every one carries an extension for each Ruby it installs on; see [Install](#install) — or the `hypercast-wasm` gem is linked into a ruby.wasm interpreter; see [Ruby in the browser](#ruby-in-the-browser) |
234
234
  | `:fiddle` | `libhypercast` for this platform, `dlopen`ed through Fiddle | no extension loads: the universal gem, on a Ruby or platform no platform gem covers; also the answer when nothing loads at all |
235
235
 
236
236
  Selection happens once, at `require`, in that order.
@@ -256,8 +256,8 @@ concurrent-callers example runs under both.
256
256
 
257
257
  ## Verifying provenance
258
258
 
259
- Every gem RubyGems.org serves — the universal fallback and each of the seven precompiled
260
- platform gems — carries its own GitHub build-provenance attestation, signed directly by
259
+ Every gem RubyGems.org serves — the universal fallback, each of the seven precompiled
260
+ platform gems and `hypercast-wasm` — carries its own GitHub build-provenance attestation, signed directly by
261
261
  this repo's own `release.yml` (the `rubygems-publish` job attests `ruby/pkg/*.gem` right
262
262
  before the push), so plain `--repo` verifies any of them:
263
263
 
@@ -268,8 +268,9 @@ gh attestation verify hypercast-X.Y.Z-<platform>.gem --repo SkunkWerkx/HyperCast
268
268
 
269
269
  That's the release's second layer of checking, not the only one: before any gem gets built,
270
270
  the same job verifies every native binary it packs — the Fiddle libraries, the Magnus
271
- extensions (one per Ruby ABI per platform) — against *their own*
272
- attestations — those are signed from `SkunkWerkx/.github` by `hyper-build-native.yml`, so
271
+ extensions (one per Ruby ABI per platform), the `wasm32-wasip1` archives — against *their own*
272
+ attestations — those are signed from `SkunkWerkx/.github` by `hyper-build-native.yml` and
273
+ `hyper-build-wasm.yml`, so
273
274
  that check needs `--signer-repo SkunkWerkx/.github` added — and refuses to proceed on an
274
275
  unverified one.
275
276
  RubyGems.org has no unpublish and no duplicate-version overwrite, so this all happens while a
@@ -285,7 +286,7 @@ more on why `--signer-repo` is needed for some artifacts here and not others.
285
286
  gem install hypercast
286
287
  ```
287
288
 
288
- Eight gems are published per release: seven precompiled Magnus platform gems that
289
+ Nine gems are published per release. This section is about eight of them: seven precompiled Magnus platform gems that
289
290
  `gem install` and `bundle` auto-select when they match — `x86_64-linux-gnu`,
290
291
  `aarch64-linux-gnu`, `x86_64-linux-musl`, `aarch64-linux-musl`, `arm64-darwin`,
291
292
  `x64-mingw-ucrt` and `aarch64-mingw-ucrt` — and one universal `ruby`-platform gem. A platform
@@ -294,7 +295,7 @@ universal gem is the last resort, Fiddle with every platform's native library bu
294
295
  is what RubyGems resolves for a Ruby the platform gems do not cover (3.3, or a Ruby newer than
295
296
  the release, such as 4.1 before a release ships for it) and on a platform no platform gem is
296
297
  built for — Intel macOS among them, which runs on Fiddle. No extra configuration needed either
297
- way.
298
+ way. The ninth, `hypercast-wasm`, is only for ruby.wasm; see [Ruby in the browser](#ruby-in-the-browser).
298
299
 
299
300
  Selection has **two** axes here, unlike every other binding in this repo. A Magnus extension
300
301
  is bound to one Ruby minor ABI — there is no `abi3` equivalent to collapse the version axis
@@ -358,6 +359,60 @@ the shipped extension small. The build script, and the two flags that are load-b
358
359
  the ARM leg (a static libunwind, and a clang-spelled `--target` for bindgen), live in the
359
360
  forge's `ruby-magnus` action (`build-magnus.sh`), shared with every other Hyper* repo.
360
361
 
362
+ ## Ruby in the browser
363
+
364
+ ruby.wasm cannot load an extension at runtime. `rbwasm build` cross-compiles the extension of
365
+ every gem in a Gemfile and links them all into the one interpreter it builds, so the browser
366
+ gets a gem of its own: `hypercast-wasm`, the same library and the same Magnus extension,
367
+ prebuilt for `wasm32-wasip1`. List it **instead of** `hypercast` in the Gemfile you build the
368
+ interpreter from (the two carry the same `lib/` files):
369
+
370
+ ```ruby
371
+ source "https://rubygems.org"
372
+
373
+ gem "hypercast-wasm"
374
+ gem "js" # JavaScript interop, which a browser app almost always wants
375
+ gem "bigdecimal" # only for Decimal#to_d; see below
376
+
377
+ group :development do
378
+ gem "ruby_wasm"
379
+ end
380
+ ```
381
+
382
+ ```sh
383
+ bundle install
384
+ bundle exec rbwasm build --ruby-version 4.0 -o ruby.wasm
385
+ ```
386
+
387
+ Load `ruby.wasm` with [`@ruby/wasm-wasi`](https://www.npmjs.com/package/@ruby/wasm-wasi)
388
+ (`DefaultRubyVM` in a browser, `RubyVM.instantiateModule` under Node), then
389
+ `require "/bundle/setup"` and `require "hypercast"` as anywhere else. `HyperCast::BACKEND` is
390
+ `:native`, and every door works as it does on a host Ruby.
391
+
392
+ - **Ruby 3.4 and 4.0**, one archive each, the same minors the platform gems cover, picked by
393
+ `--ruby-version`. Any other minor stops the build with a message naming the ones the gem
394
+ carries. Built and tested against ruby_wasm 2.10.
395
+ - **No Rust toolchain.** The gem's `extconf.rb` only hands rbwasm the prebuilt archive, and
396
+ rbwasm downloads its own wasi-sdk. The first `rbwasm build` compiles Ruby itself and takes
397
+ 15–20 minutes; later builds reuse it.
398
+ - **`Decimal#to_d` needs `gem "bigdecimal"` in that Gemfile.** bigdecimal is a bundled gem
399
+ with a C extension, and ruby.wasm builds a bundled gem's extension only when the Gemfile
400
+ names it; without it, `to_d` raises `LoadError`. `to_s` and `to_r` need nothing.
401
+ - **Static linking only,** into ruby.wasm's default `wasm32-unknown-wasip1` interpreter.
402
+ rbwasm's dynamic-linking build (a pic target, for the component model) is not supported.
403
+ - **Size.** rbwasm packs every gem's files into the interpreter, the archives included, so the
404
+ gem adds about 2 MB to `ruby.wasm` (both archives are gzipped).
405
+ - **With HyperUuid.** `hyperuuid-wasm` links into the same interpreter. Every Rust extension
406
+ that carries std defines a few of the same symbols (`rust_eh_personality`, which ruby.wasm's
407
+ own wasi-vfs defines too, rb-sys's `ruby_abi_version`, and one of std's), and both gems
408
+ rename them to names of their own when CI builds the archive, which also fails if a newer
409
+ Rust starts exporting another.
410
+
411
+ What stands behind it: CI builds each minor's archive from the commit, packs the gem the way
412
+ it ships, links it into a fresh interpreter and runs [`wasm-smoke/test.rb`](wasm-smoke/test.rb)
413
+ under Node and in headless Chrome (the forge's `hyper-build-wasm.yml`). The published gem is
414
+ packed around those attested archives.
415
+
361
416
  ## Development
362
417
 
363
418
  Everything below runs from a checkout, with `rust/` and `corpus/` beside `ruby/`; none of it
data/lib/hypercast.rb CHANGED
@@ -29,7 +29,7 @@ require_relative "hypercast/runtime"
29
29
  module HyperCast
30
30
  # This gem's own version — kept in lockstep with hypercast.gemspec by the
31
31
  # prepare-release workflow, so the two can never drift apart again.
32
- VERSION = "0.6.0"
32
+ VERSION = "0.6.1"
33
33
 
34
34
  # The success case of a verdict: a cast value.
35
35
  Success = Data.define(:value)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hypercast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Buvinghausen