hyperuuid-wasm 0.9.0 → 1.0.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: 8b35d26b737a64df74f7a10783112899a0386bbd7dd7b7aa6387b4cbd5fb3c09
4
- data.tar.gz: c37cd5f4d1bc6ad5eef8d181aa263ac61212c73f4f73640724f63e53a9797f61
3
+ metadata.gz: 23b7842046b78dff468073474bdb004a03c6d4710ff13a7ff3f048c879d141f9
4
+ data.tar.gz: 04204e9e6c775cb35a8370b53ffd8fc8c7538ad9220fffc5a05fc7e76c07ec7a
5
5
  SHA512:
6
- metadata.gz: 1580f8edd7863896d8b646db61e5918aa7efcaa22db88995e2c6aa2d4456f8dd2698e1200e214191830b984aee8fcdd56f22f5da51985a48305401bf10b84201
7
- data.tar.gz: e5a86147bafa4f1e9bfb266656e073f135286f07750dbb930cf6a8b10e9a3b45060e5a8daf73cd6c7162ee060a75f3e4f02c3a609c63fc8b94bbb26a0a46c653
6
+ metadata.gz: b1dd276963bf50735b2e9f7cd1be16dbeb7c7edebef8c027471cbaf6686237ef971b91f87f328a42650232b25e2bd5bd5d0cdb39309674fe2f5f743b58553a0d
7
+ data.tar.gz: 9e2ee0585a21dbdd3266ef635134e2013a09b3cb5538427a0b71df0e9126d4d9d3fbc7f8a0dc73f9b4ed5579c3f1c181e8d2de73b54e04c240b6e1eb8701637e
data/README.md CHANGED
@@ -138,23 +138,20 @@ happens at most once per 2²⁶ UUIDs the process mints.
138
138
 
139
139
  ### Errors
140
140
 
141
- Two exceptions are this gem's own, and both carry the same message on every backend:
141
+ Two exceptions describe a failed call, and both carry the same message on every backend:
142
142
 
143
143
  - `HyperUuid::TimestampOutOfRangeError` — the time cannot be embedded in a version 7: past
144
144
  its 48-bit millisecond field, or negative (a `Time` before the Unix epoch included).
145
145
  - `HyperUuid::RandomSourceError` — the operating system's random source failed.
146
146
 
147
- Through 0.3.0 these were reachable only as `HyperUuid::Runtime::TimestampOutOfRangeError` and
148
- `HyperUuid::Runtime::RandomSourceError`; those names remain, as aliases of the same classes.
149
-
150
147
  Everything else is a caller bug and raises Ruby's own error for it, checked once in the shared
151
148
  doors rather than left to whichever backend is live: a `TypeError` for a time that is not a
152
149
  `Time`, an Integer or `nil`, for a count that is not an Integer, for a namespace that is not a
153
150
  `Uuid` or a name that is not a `String`, for a version passed to `#rfc?` that is not an
154
- Integer; an `ArgumentError` for a count outside 0..`MAX_V7_BATCH`, for a layout other than
155
- `:rfc9562`/`:sql_server`, and for a batch too large for the platform to address (a 32-bit
156
- target such as ruby.wasm). The SQL Server conversions' one refusal (a value of the wrong
157
- version) comes from the core, as an `ArgumentError` worded the same on both backends.
151
+ Integer; an `ArgumentError` for a count outside 0..`MAX_V7_BATCH` and for a layout other than
152
+ `:rfc9562`/`:sql_server`. Two refusals come from the backend instead, each an `ArgumentError`
153
+ worded the same on both: a batch too large for the platform to address (a 32-bit target such
154
+ as ruby.wasm), and the SQL Server conversions' one refusal, a value of the wrong version.
158
155
 
159
156
  ### Is the native core there?
160
157
 
@@ -194,7 +191,7 @@ bytes = HyperUuid.new_v7_batch_bytes(1000)
194
191
  first = bytes[0, 16] # ready for a BINARY(16) bind parameter
195
192
  ```
196
193
 
197
- **About 40x faster than `new_v7_batch`** for a 1000-UUID batch (4.9 µs versus 202 µs). The native call is identical — the difference is that `new_v7_batch` then allocates a `Uuid` object and its byte Strings for every item on top of it. This hands back the bytes the native core already produced, untouched.
194
+ **About 41x faster than `new_v7_batch`** for a 1000-UUID batch (4.9 µs versus 202 µs). The native call is identical — the difference is that `new_v7_batch` then allocates a `Uuid` object and its byte Strings for every item on top of it. This hands back the bytes the native core already produced, untouched.
198
195
 
199
196
  The catch, and it inverts the advice: **if you need `Uuid` objects, keep using `new_v7_batch`.** Slicing these bytes into objects yourself just relocates the identical allocations into your own code, and measures no better — sometimes worse. Reach for the byte form only when bytes are the destination: a bind parameter, a wire format, a bulk load.
200
197
 
@@ -229,7 +226,7 @@ Batch generation still amortizes per-call cost on both backends — one native c
229
226
  | `new_v7` × 1000 (individual) | 3,742 |
230
227
  | `new_v7_batch(1000)` | 4,850 (**1.3x**) |
231
228
 
232
- The multiplier is small on this backend for the best reason available: the individual calls are cheap, so there is little waste left to amortize, and what `new_v7_batch` spends its 206 µs on is building a thousand `Uuid` objects — the byte form above does the same native work in 5 µs. On the Fiddle backend, where each call costs 1.4 µs, the same batch is 6.7x the loop. If you need v5/v7, need many at once, or need this Ruby service's IDs to agree byte-for-byte with a Go or Python service's, that's what this gem is for — and now it's the fast option too, not just the capable one.
229
+ The multiplier is small on this backend for the best reason available: the individual calls are cheap, so there is little waste left to amortize, and what `new_v7_batch` spends its 206 µs on (in this table's run; 202 µs in the bytes-versus-objects run above) is building a thousand `Uuid` objects — the byte form above does the same native work in 4.9 µs. On the Fiddle backend, where each call costs 1.4 µs, the same batch is 6.7x the loop. If you need v5/v7, need many at once, or need this Ruby service's IDs to agree byte-for-byte with a Go or Python service's, that's what this gem is for — and now it's the fast option too, not just the capable one.
233
230
 
234
231
  ## Backends
235
232
 
@@ -256,34 +253,42 @@ backend where Ruby threads run the core truly in parallel — each through its o
256
253
  buffer, with the core's v7 counter shared and atomic. `spec/hyperuuid_spec.rb`'s "concurrent
257
254
  callers" examples run under both.
258
255
 
259
- **Ractors.** Main Ractor only, on every backend: called from another Ractor the doors raise
260
- `Ractor::UnsafeError`.
256
+ **Ractors.** Main Ractor only, on every backend: called from another Ractor the doors raise a
257
+ `Ractor::Error` (`Ractor::IsolationError`, or `Ractor::UnsafeError`, by door and backend).
261
258
 
262
259
  ## Verifying provenance
263
260
 
264
- Every gem RubyGems.org serves — the universal fallback, each of the seven precompiled
265
- platform gems and `hyperuuid-wasm` — carries its own GitHub build-provenance attestation, signed directly by
266
- this repo's own `release.yml` (the `rubygems-publish` job attests `ruby/pkg/*.gem` right
267
- before the push), so plain `--repo` verifies any of them:
261
+ Every gem RubyGems.org serves — the universal fallback, each of the seven precompiled platform
262
+ gems and `hyperuuid-wasm` — verifies from the release tag alone: the release attestation,
263
+ signed by this repository's `release.yml` at the tag, names every one of them, with the
264
+ release inventory as its predicate.
265
+
266
+ ```sh
267
+ gem fetch hyperuuid -v <version> --platform <platform> # or omit --platform for the universal gem
268
+ gh attestation verify hyperuuid-<version>-<platform>.gem --repo SkunkWerkx/HyperUuid \
269
+ --source-ref refs/tags/v<version> --predicate-type https://github.com/SkunkWerkx/.github/predicates/release/v1
270
+ ```
271
+
272
+ Each gem's build provenance is this repository's too: the `ruby-pack` job attests
273
+ `ruby/pkg/*.gem` as soon as they are built and `rubygems-publish` pushes those preserved
274
+ bytes, so plain `--repo` verifies it:
268
275
 
269
276
  ```sh
270
- gem fetch hyperuuid -v X.Y.Z --platform <platform> # or omit --platform for the universal gem
271
- gh attestation verify hyperuuid-X.Y.Z-<platform>.gem --repo SkunkWerkx/HyperUuid
277
+ gh attestation verify hyperuuid-<version>-<platform>.gem --repo SkunkWerkx/HyperUuid
272
278
  ```
273
279
 
274
- That's the release's second layer of checking, not the only one: before any gem gets built,
275
- the same job verifies every native binary it packs — the Fiddle libraries, the Magnus
276
- extensions (one per Ruby ABI per platform), the `wasm32-wasip1` archives — against *their own*
277
- attestations — those are signed from `SkunkWerkx/.github` by `hyper-build-native.yml` and
278
- `hyper-build-wasm.yml`, so
279
- that check needs `--signer-repo SkunkWerkx/.github` added — and refuses to proceed on an
280
- unverified one. RubyGems.org has no unpublish and no
281
- duplicate-version overwrite, so this all happens while a bad artifact is still reversible.
282
- The release run's job summary then re-fetches every gem from the CDN and records
283
- attested-vs-served digests, turning "rubygems.org stores an upload verbatim" into a
284
- per-release measurement rather than an assumption — see
285
- [csharp/README.md's provenance section](../csharp/README.md#native-binary-provenance) for
286
- more on why `--signer-repo` is needed for some artifacts here and not others.
280
+ That is the release's second layer of checking, not the only one: before any gem is built, the
281
+ same job verifies every native binary it packs — the Fiddle libraries, the Magnus extensions
282
+ (one per Ruby ABI per platform), the `wasm32-wasip1` archives — against *their own* build
283
+ provenance, signed from `SkunkWerkx/.github` by `hyper-build-native.yml` and
284
+ `hyper-build-wasm.yml` (so that check needs `--signer-repo SkunkWerkx/.github` added), and
285
+ refuses to proceed on an unverified one. RubyGems.org has no unpublish and no
286
+ duplicate-version overwrite, so all of this happens while a bad artifact is still reversible,
287
+ and the push itself is a separate dispatch from the preserved bytes. The release run then
288
+ re-fetches every gem from rubygems.org and fails unless each matches the attested bytes
289
+ exactly, turning "rubygems.org stores an upload verbatim" into a per-release check rather than
290
+ an assumption. The root README's [Provenance](../README.md#provenance) section has the whole
291
+ picture.
287
292
 
288
293
  ## Install
289
294
 
@@ -401,6 +406,12 @@ which read the clock through WASI.
401
406
  - **No Rust toolchain.** The gem's `extconf.rb` only hands rbwasm the prebuilt archive, and
402
407
  rbwasm downloads its own wasi-sdk. The first `rbwasm build` compiles Ruby itself and takes
403
408
  15–20 minutes; later builds reuse it.
409
+ - **macOS with Homebrew: limit pkg-config to `openssl@3`.** Run the build as
410
+ `PKG_CONFIG_LIBDIR="$(brew --prefix openssl@3)/lib/pkgconfig" bundle exec rbwasm build …`.
411
+ Without it Homebrew's pkg-config files reach into the build twice: its `openssl` is OpenSSL
412
+ 4, which the native Ruby rbwasm builds first does not compile against, and its `libyaml`
413
+ is a macOS library that psych then links into the wasm interpreter, which fails for Ruby
414
+ 4.0.
404
415
  - **Static linking only,** into ruby.wasm's default `wasm32-unknown-wasip1` interpreter.
405
416
  rbwasm's dynamic-linking build (a pic target, for the component model) is not supported.
406
417
  - **Size.** rbwasm packs every gem's files into the interpreter, the archives included, so the
@@ -15,13 +15,6 @@ module HyperUuid
15
15
  # A Ruby gem's files are plain files on disk once installed, so native/{rid}/{lib} can be
16
16
  # dlopen'd directly, with no extraction step.
17
17
  module Runtime
18
- # The package's two exceptions live on HyperUuid itself (errors.rb). These are the names
19
- # they had through 0.3.0, kept as aliases of the very same classes so a
20
- # `rescue HyperUuid::Runtime::TimestampOutOfRangeError` written against an earlier
21
- # release still catches.
22
- RandomSourceError = HyperUuid::RandomSourceError
23
- TimestampOutOfRangeError = HyperUuid::TimestampOutOfRangeError
24
-
25
18
  # One copy of the out-of-range message for the Fiddle backend and for the doors' own
26
19
  # range check in hyperuuid.rb; the Magnus extension (rust/src/ruby_ext.rs) carries the
27
20
  # same text, and spec/native_backend_spec.rb pins that the two agree.
data/lib/hyperuuid.rb CHANGED
@@ -19,7 +19,7 @@ require_relative "hyperuuid/runtime"
19
19
  module HyperUuid
20
20
  # This gem's own version — distinct from the RFC 9562 UUID *versions* (v4/v5/v7) the rest
21
21
  # of this module generates.
22
- VERSION = "0.9.0"
22
+ VERSION = "1.0.0"
23
23
 
24
24
  # The widest batch count, and the longest v5 name in bytes, the native ABI carries (a u32).
25
25
  # (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-wasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Buvinghausen