hyperuuid 0.6.0-x86_64-linux-gnu → 0.6.1-x86_64-linux-gnu

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: 16d05177a878c7c35fb8f44fc7f42691cbfdf30b152455d54dc7a1c041991e94
4
- data.tar.gz: 12b9a5a8ea701149593f94a2370b42e4e5926f59a200f942bf9330555356b531
3
+ metadata.gz: d627ef885171a5aa3d5f12c8f53ac9cb6ba13da8d1c497e009dec0703d4f22dd
4
+ data.tar.gz: 34fca766efc82f71027cc2a5c4140b9858030bd7b67a1657fc604bd515eb3d03
5
5
  SHA512:
6
- metadata.gz: 9155cd884ee4a26507529073cf7e1a98d0f24438a9dd09dc4508f7af32f577786a1a645b2a264e5b9849aae763258fc414fd564b8da987094f414db63503d4b7
7
- data.tar.gz: 56fd684e1058f9c2da5741d5649be692bce1c146c42e005df1b281334b77374a4fb7bb9e78ac177d05a3cad54357a979296b716a5b35fdc71d77b21debf6cc53
6
+ metadata.gz: d3bc230eb26b9804d3294b75818b5519ac110c5f3dc7b4a9c6a071863e0ecb0c452ece80f151f9ad2758e8248d2bcc9343431d04141453dd2bba05123562abe7
7
+ data.tar.gz: dd4e4f93ce8d87b77ad4cab6b6958b569cc5aee052ff5e666b92e9c7bf3002dcfb84c03fde16e2d903935ed585bdb85da867c02360e3906d9ab80b8366b9b602
data/README.md CHANGED
@@ -107,7 +107,7 @@ looked for, or `HyperUuid::NativePlatform::UnsupportedPlatformError` naming the
107
107
 
108
108
  `SecureRandom.uuid` only ever gives you a random v4 UUID — Ruby's stdlib has no built-in v5, v6, or v7 at all. If you need more than that, the choice is really "which gem":
109
109
 
110
- 1. **Full RFC 9562 coverage, one gem, zero extra dependency.** v4/v5/v6/v7 plus batch generation plus `Nil`/`Max`, and the only thing this gem adds to your `Gemfile.lock` beyond `Fiddle` — which is Ruby's own bundled FFI layer, not a third-party C extension to compile.
110
+ 1. **Full RFC 9562 coverage, one gem, zero extra dependency.** v4/v5/v6/v7 plus batch generation plus `Nil`/`Max`, and nothing added to your `Gemfile.lock` beyond `Fiddle` — Ruby's own bundled FFI layer, not a third-party C extension to compile — and on the precompiled platform gems not even that.
111
111
  2. **No native-extension compile step.** Third-party UUID gems that go beyond v4 are typically pure Ruby or wrap a C extension compiled at install time; this gem ships its fast path as a prebuilt platform-gem extension and its fallback as a `dlopen`ed prebuilt library — either way, the gem itself compiles nothing at install time ([Install](#install) has the one caveat, which is Fiddle's own).
112
112
  3. **Batch generation.** `new_v7_batch(1000)` shares one timestamp capture, one random-bytes fetch, and one counter reservation across the whole batch instead of paying per-item overhead a thousand times over.
113
113
  4. **Cross-language consistency.** The same Rust core mints v5 namespace UUIDs for Python, Go, C#, and every other binding in this repo — verified in CI to match Python's own `uuid.uuid5` byte-for-byte. If your system isn't Ruby-only, no Ruby-only gem can offer that.
@@ -168,7 +168,7 @@ The multiplier is small on this backend for the best reason available: the indiv
168
168
 
169
169
  | `HyperUuid::BACKEND` | What runs | Chosen when |
170
170
  |---|---|---|
171
- | `: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) |
171
+ | `: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 `hyperuuid-wasm` gem is linked into a ruby.wasm interpreter; see [Ruby in the browser](#ruby-in-the-browser) |
172
172
  | `:fiddle` | `libhyperuuid` 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 |
173
173
 
174
174
  Selection happens once, at `require`, in that order.
@@ -194,8 +194,8 @@ callers" examples run under both.
194
194
 
195
195
  ## Verifying provenance
196
196
 
197
- Every gem RubyGems.org serves — the universal fallback and each of the seven precompiled
198
- platform gems — carries its own GitHub build-provenance attestation, signed directly by
197
+ Every gem RubyGems.org serves — the universal fallback, each of the seven precompiled
198
+ platform gems and `hyperuuid-wasm` — carries its own GitHub build-provenance attestation, signed directly by
199
199
  this repo's own `release.yml` (the `rubygems-publish` job attests `ruby/pkg/*.gem` right
200
200
  before the push), so plain `--repo` verifies any of them:
201
201
 
@@ -206,8 +206,9 @@ gh attestation verify hyperuuid-X.Y.Z-<platform>.gem --repo SkunkWerkx/HyperUuid
206
206
 
207
207
  That's the release's second layer of checking, not the only one: before any gem gets built,
208
208
  the same job verifies every native binary it packs — the Fiddle libraries, the Magnus
209
- extensions (one per Ruby ABI per platform) — against *their own*
210
- attestations — those are signed from `SkunkWerkx/.github` by `hyper-build-native.yml`, so
209
+ extensions (one per Ruby ABI per platform), the `wasm32-wasip1` archives — against *their own*
210
+ attestations — those are signed from `SkunkWerkx/.github` by `hyper-build-native.yml` and
211
+ `hyper-build-wasm.yml`, so
211
212
  that check needs `--signer-repo SkunkWerkx/.github` added — and refuses to proceed on an
212
213
  unverified one. RubyGems.org has no unpublish and no
213
214
  duplicate-version overwrite, so this all happens while a bad artifact is still reversible.
@@ -223,7 +224,7 @@ more on why `--signer-repo` is needed for some artifacts here and not others.
223
224
  gem install hyperuuid
224
225
  ```
225
226
 
226
- Eight gems are published per release: seven precompiled Magnus platform gems that
227
+ Nine gems are published per release. This section is about eight of them: seven precompiled Magnus platform gems that
227
228
  `gem install` and `bundle` auto-select when they match — `x86_64-linux-gnu`,
228
229
  `aarch64-linux-gnu`, `x86_64-linux-musl`, `aarch64-linux-musl`, `arm64-darwin`,
229
230
  `x64-mingw-ucrt` and `aarch64-mingw-ucrt` — and one universal `ruby`-platform gem. A platform gem carries its
@@ -232,7 +233,7 @@ the last resort, Fiddle with every platform's native library bundled, and it is
232
233
  RubyGems resolves for a Ruby the platform gems do not cover (3.3, or a Ruby newer than the
233
234
  release, such as 4.1 before a release ships for it) and on a platform no platform gem is
234
235
  built for — Intel macOS among them, which runs on Fiddle. No extra configuration needed either
235
- way.
236
+ way. The ninth, `hyperuuid-wasm`, is only for ruby.wasm; see [Ruby in the browser](#ruby-in-the-browser).
236
237
 
237
238
  Selection has **two** axes here, unlike every other binding in this repo. A Magnus extension
238
239
  is bound to one Ruby minor ABI — there's no `abi3` equivalent to collapse the version axis the
@@ -272,13 +273,17 @@ Bundler pick the right one on every supported Ruby: next to a plain `x86_64-linu
272
273
  RubyGems before 4.0 resolves that one on Alpine instead, even under
273
274
  `--platform x86_64-linux-musl`.
274
275
 
275
- **Nothing in this gem is ever compiled, on any platform.** Its one dependency can be:
276
- `fiddle` is a bundled gem on Ruby 4.0 and a default gem on 3.3 and 3.4, and `gem install` is
277
- satisfied by the copy Ruby ships. Bundler resolves the newest `fiddle` on rubygems.org
278
- instead, and when that is newer than the one your Ruby ships — true today on 3.3 and 3.4, not
279
- on 4.0 — it builds Fiddle's own C extension, which takes a compiler and libffi's headers
280
- (`apk add build-base libffi-dev` on Alpine). Holding `fiddle` at your Ruby's version in the
281
- `Gemfile.lock` avoids that.
276
+ **Nothing in this gem is ever compiled, on any platform.** The platform gems depend on nothing
277
+ at all. The universal gem depends on `fiddle`, which can be: `fiddle` is a bundled gem on Ruby
278
+ 4.0 and a default gem on 3.3 and 3.4, and `gem install` is satisfied by the copy Ruby ships.
279
+ Bundler resolves the newest `fiddle` on rubygems.org instead, and when that is newer than the
280
+ one your Ruby ships — true today on 3.3 and 3.4, not on 4.0 — it builds Fiddle's own C
281
+ extension, which takes a compiler and libffi's headers (`apk add build-base libffi-dev` on
282
+ Alpine). That only reaches you where the universal gem installs: Ruby 3.3, Intel macOS, a
283
+ Ruby newer than the release, or a platform with no platform gem. `bundle install
284
+ --prefer-local` makes Bundler use the copy Ruby ships where it can (it did on Ruby 3.4's
285
+ Bundler 2.6, not on 3.3's 2.5); otherwise install the compiler and headers. Pinning `fiddle`
286
+ to your Ruby's version in the `Gemfile.lock` does not stop the build.
282
287
 
283
288
  Both Windows architectures get a Magnus gem. MinGW is the *only* Windows flavour `rb-sys`
284
289
  targets (`x64-mingw-ucrt` and `aarch64-mingw-ucrt`, both `supported: true` in its own
@@ -294,6 +299,57 @@ keeps the shipped extension small. The build script, and the two flags that are
294
299
  on the ARM leg (a static libunwind, and a clang-spelled `--target` for bindgen), live in the
295
300
  forge's `ruby-magnus` action (`build-magnus.sh`), shared with every other Hyper* repo.
296
301
 
302
+ ## Ruby in the browser
303
+
304
+ ruby.wasm cannot load an extension at runtime. `rbwasm build` cross-compiles the extension of
305
+ every gem in a Gemfile and links them all into the one interpreter it builds, so the browser
306
+ gets a gem of its own: `hyperuuid-wasm`, the same library and the same Magnus extension,
307
+ prebuilt for `wasm32-wasip1`. List it **instead of** `hyperuuid` in the Gemfile you build the
308
+ interpreter from (the two carry the same `lib/` files):
309
+
310
+ ```ruby
311
+ source "https://rubygems.org"
312
+
313
+ gem "hyperuuid-wasm"
314
+ gem "js" # JavaScript interop, which a browser app almost always wants
315
+
316
+ group :development do
317
+ gem "ruby_wasm"
318
+ end
319
+ ```
320
+
321
+ ```sh
322
+ bundle install
323
+ bundle exec rbwasm build --ruby-version 4.0 -o ruby.wasm
324
+ ```
325
+
326
+ Load `ruby.wasm` with [`@ruby/wasm-wasi`](https://www.npmjs.com/package/@ruby/wasm-wasi)
327
+ (`DefaultRubyVM` in a browser, `RubyVM.instantiateModule` under Node), then
328
+ `require "/bundle/setup"` and `require "hyperuuid"` as anywhere else. `HyperUuid::BACKEND` is
329
+ `:native`: every door, the batch and raw-bytes forms, and `new_v6`/`new_v7` with no argument,
330
+ which read the clock through WASI.
331
+
332
+ - **Ruby 3.4 and 4.0**, one archive each, the same minors the platform gems cover, picked by
333
+ `--ruby-version`. Any other minor stops the build with a message naming the ones the gem
334
+ carries. Built and tested against ruby_wasm 2.10.
335
+ - **No Rust toolchain.** The gem's `extconf.rb` only hands rbwasm the prebuilt archive, and
336
+ rbwasm downloads its own wasi-sdk. The first `rbwasm build` compiles Ruby itself and takes
337
+ 15–20 minutes; later builds reuse it.
338
+ - **Static linking only,** into ruby.wasm's default `wasm32-unknown-wasip1` interpreter.
339
+ rbwasm's dynamic-linking build (a pic target, for the component model) is not supported.
340
+ - **Size.** rbwasm packs every gem's files into the interpreter, the archives included, so the
341
+ gem adds about 2 MB to `ruby.wasm` (both archives are gzipped).
342
+ - **With HyperCast.** `hypercast-wasm` links into the same interpreter. Every Rust extension
343
+ that carries std defines a few of the same symbols (`rust_eh_personality`, which ruby.wasm's
344
+ own wasi-vfs defines too, rb-sys's `ruby_abi_version`, and one of std's), and both gems
345
+ rename them to names of their own when CI builds the archive, which also fails if a newer
346
+ Rust starts exporting another.
347
+
348
+ What stands behind it: CI builds each minor's archive from the commit, packs the gem the way
349
+ it ships, links it into a fresh interpreter and runs [`wasm-smoke/test.rb`](wasm-smoke/test.rb)
350
+ under Node and in headless Chrome (the forge's `hyper-build-wasm.yml`). The published gem is
351
+ packed around those attested archives.
352
+
297
353
  ## Development
298
354
 
299
355
  Everything below runs from a checkout, with `rust/` beside `ruby/`; none of it is needed to
Binary file
Binary file
@@ -1,10 +1,15 @@
1
- require "fiddle"
1
+ # Autoloaded, not required: the platform gems carry no library for Fiddle to open and do not
2
+ # declare fiddle, so loading it eagerly would make `require "hyperuuid"` fail under Bundler
3
+ # wherever fiddle is a bundled rather than a default gem (Ruby 4.0). It loads the first time
4
+ # the Fiddle backend runs, and every path there goes through `functions` first, so a platform
5
+ # gem forced onto Fiddle still gets missing_library_message rather than a bare LoadError.
6
+ autoload :Fiddle, "fiddle"
2
7
 
3
8
  module HyperUuid
4
9
  # Fiddle plumbing for the native libhyperuuid shared library — dlopen/dlsym plus a raw
5
- # C-ABI call, no runtime bridge (the same "no shim" positioning as the Swift binding's
6
- # dlopen approach). Fiddle ships with every Ruby install; it's a plain gem dependency here
7
- # (see hyperuuid.gemspec) rather than a third-party one — mirroring Python's
10
+ # C-ABI call, no runtime bridge (the same "no shim" positioning as the PHP binding's
11
+ # FFI and C#'s P/Invoke). Fiddle ships with every Ruby install; it's a plain gem dependency of the
12
+ # universal gem (see hyperuuid.gemspec) rather than a third-party one — mirroring Python's
8
13
  # zero-dependency PyO3 wheels.
9
14
  #
10
15
  # A Ruby gem's files are plain files on disk once installed, so native/{rid}/{lib} can be
@@ -63,7 +68,7 @@ module HyperUuid
63
68
 
64
69
  def new_v6_batch(count, unix_millis)
65
70
  return "" if count.zero?
66
- out = Fiddle::Pointer.malloc(count * 16, Fiddle::RUBY_FREE)
71
+ out = buffer(count * 16)
67
72
  rc = functions[:new_v6_batch].call(unix_millis, count, out)
68
73
  case rc
69
74
  when 0 then out[0, count * 16]
@@ -88,7 +93,7 @@ module HyperUuid
88
93
 
89
94
  def new_v7_batch(count, unix_millis)
90
95
  return "" if count.zero?
91
- out = Fiddle::Pointer.malloc(count * 16, Fiddle::RUBY_FREE)
96
+ out = buffer(count * 16)
92
97
  rc = functions[:new_v7_batch].call(unix_millis, count, out)
93
98
  case rc
94
99
  when 0 then out[0, count * 16]
@@ -175,7 +180,15 @@ module HyperUuid
175
180
  # (in HyperCast, same mechanism) as the dominant per-call cost by an order of
176
181
  # magnitude. Batches keep a per-call buffer: one malloc amortized over `count` IDs.
177
182
  def scratch
178
- Thread.current[:hyperuuid_scratch] ||= Fiddle::Pointer.malloc(16, Fiddle::RUBY_FREE)
183
+ Thread.current[:hyperuuid_scratch] ||= buffer(16)
184
+ end
185
+
186
+ # Every Fiddle allocation goes through here, and loads the library first: that is what
187
+ # keeps a missing library reported as missing_library_message instead of as whatever
188
+ # touching Fiddle raises first. The scratch buffer pays for it once per thread.
189
+ def buffer(size)
190
+ functions
191
+ Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
179
192
  end
180
193
 
181
194
  # The in-place byte-order rewrites are the one shape that must copy in: the native
data/lib/hyperuuid.rb CHANGED
@@ -18,7 +18,7 @@ require_relative "hyperuuid/runtime"
18
18
  module HyperUuid
19
19
  # This gem's own version — distinct from the RFC 9562 UUID *versions* (v4/v5/v6/v7) the
20
20
  # rest of this module generates.
21
- VERSION = "0.6.0"
21
+ VERSION = "0.6.1"
22
22
 
23
23
  # The widest batch count, and the longest v5 name in bytes, the native ABI carries (a u32).
24
24
  # (The millisecond count is a u64; unix_millis_from refuses anything wider.)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperuuid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: x86_64-linux-gnu
6
6
  authors:
7
7
  - Brian Buvinghausen
@@ -9,20 +9,6 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: fiddle
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '0'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: '0'
26
12
  - !ruby/object:Gem::Dependency
27
13
  name: rake
28
14
  requirement: !ruby/object:Gem::Requirement