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 +4 -4
- data/README.md +42 -31
- data/ext/hyperuuid_native/3.4/hyperuuid_native.a.gz +0 -0
- data/ext/hyperuuid_native/4.0/hyperuuid_native.a.gz +0 -0
- data/lib/hyperuuid/runtime.rb +0 -7
- data/lib/hyperuuid.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23b7842046b78dff468073474bdb004a03c6d4710ff13a7ff3f048c879d141f9
|
|
4
|
+
data.tar.gz: 04204e9e6c775cb35a8370b53ffd8fc8c7538ad9220fffc5a05fc7e76c07ec7a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
|
155
|
-
`:rfc9562`/`:sql_server
|
|
156
|
-
|
|
157
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
266
|
-
this
|
|
267
|
-
|
|
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
|
-
|
|
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
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
`hyper-build-wasm.yml
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
|
Binary file
|
|
Binary file
|
data/lib/hyperuuid/runtime.rb
CHANGED
|
@@ -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.
|
|
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.)
|