jsg 0.2.1 → 0.3.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/CHANGELOG.md +5 -0
- data/README.md +25 -2
- data/lib/jsg/global.rb +46 -0
- data/lib/jsg/version.rb +1 -1
- data/sig/jsg.rbs +6 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5bbe669419df7b6181dacae7851ccf5a27b97abdf6e6a4a2a48c73e10d87632
|
|
4
|
+
data.tar.gz: c838fccba5ca6a8316d0718b097312b3760f31b94f9112eeee1bf1e7053c142f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 448f59e03a1e7a38c89f0ff99e5ff32ddda31fd3009bef7d712929ce93c4b7804aba3d137df8c4aff25f051f47a4bec023ad211a907da1ed06c2de4baa53c850
|
|
7
|
+
data.tar.gz: 5bfbcff342b82afd36fd558eb8a63052f8b2699e98f5d65eebdb5c5c2cb0dd67dbab2c9505fd28227ed6d2716e32070dce6aded230627ec8bbc37e0786d9fe82
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-11-05
|
|
4
|
+
|
|
5
|
+
- New opt-in `require "jsg/global"`: unknown methods on the `JS` module are forwarded to `JS.global`, so `JS.document.title`, `JS.alert("Hi")` and `JS.myValue = 1` work. Names the `JS` module already answers keep their meaning (`JS.global`, `JS.eval`, and Ruby's own module methods such as `JS.name`). It loads `jsg` too. `require "jsg"` alone does not change the `JS` module.
|
|
6
|
+
- The ruby.wasm tests run every test file in a fresh VM, so a file that only requires `jsg/global` is tested on its own.
|
|
7
|
+
|
|
3
8
|
## [0.2.1] - 2026-09-29
|
|
4
9
|
|
|
5
10
|
- First release published from GitHub Actions with RubyGems trusted publishing (`.github/workflows/release.yml`, triggered by `v*` tags).
|
data/README.md
CHANGED
|
@@ -97,6 +97,29 @@ el.tap { |e| ... } # like Kernel#tap (JS::Object is a BasicObject since js 2.10)
|
|
|
97
97
|
value == true # comparing with true, false and nil works (JavaScript's == rules)
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
### `JS.document` instead of `JS.global.document` (opt-in)
|
|
101
|
+
|
|
102
|
+
`require "jsg/global"` forwards unknown methods on the `JS` module to `JS.global`. It loads `jsg` as well, so this one line is enough:
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
require "jsg/global"
|
|
106
|
+
|
|
107
|
+
JS.document.title # JS.global.document.title
|
|
108
|
+
JS.alert("Hello") # JS.global.alert("Hello")
|
|
109
|
+
JS.localStorage.getItem("k")
|
|
110
|
+
JS.myValue = 1 # sets window.myValue
|
|
111
|
+
JS.hidden? # JavaScript truthiness, like the ? methods above
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
It is not part of `require "jsg"` because it changes the `JS` module itself, which the js gem and other libraries use too. Load it when you want the shorter syntax in your own app.
|
|
115
|
+
|
|
116
|
+
Only names that `JS` does not already answer are forwarded. These keep their Ruby meaning, so use `JS.global` for a browser global of the same name:
|
|
117
|
+
|
|
118
|
+
- methods of the js gem: `JS.global`, `JS.eval`, `JS.try_convert`, `JS.is_a?`, ...
|
|
119
|
+
- methods every Ruby module has: `JS.name` (returns `"JS"`, not `window.name`), `JS.hash`, `JS.inspect`, `JS.class`, `JS.method`, `JS.display`, `JS.freeze`, ...
|
|
120
|
+
|
|
121
|
+
Private `Kernel` methods such as `open`, `print` or `format` are forwarded, because calling them with an explicit receiver (`JS.open(...)`) ends up in `method_missing`. A name that the global object does not have raises `NoMethodError` as before. `JSG.xxx` forwards to `JS`, so after `require "jsg/global"` it reaches the globals too.
|
|
122
|
+
|
|
100
123
|
## Development
|
|
101
124
|
|
|
102
125
|
```bash
|
|
@@ -107,8 +130,8 @@ bundle exec rake # rspec, the ruby.wasm tests and rubocop
|
|
|
107
130
|
To release a new version, update `lib/jsg/version.rb` and `CHANGELOG.md`, commit, and push a matching tag:
|
|
108
131
|
|
|
109
132
|
```bash
|
|
110
|
-
git tag v0.
|
|
111
|
-
git push origin v0.
|
|
133
|
+
git tag v0.3.0
|
|
134
|
+
git push origin v0.3.0
|
|
112
135
|
```
|
|
113
136
|
|
|
114
137
|
The `Release` workflow runs the tests and publishes the gem to RubyGems.org with trusted publishing, so no API key is stored in GitHub.
|
data/lib/jsg/global.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "jsg"
|
|
4
|
+
|
|
5
|
+
module JSG
|
|
6
|
+
# Opt-in shortcut: forwards unknown methods on the JS module to JS.global,
|
|
7
|
+
# so browser globals can be used without writing JS.global every time.
|
|
8
|
+
#
|
|
9
|
+
# require "jsg/global"
|
|
10
|
+
#
|
|
11
|
+
# JS.document.title # JS.global.document.title
|
|
12
|
+
# JS.alert("Hello") # JS.global.alert("Hello")
|
|
13
|
+
# JS.localStorage.getItem("k")
|
|
14
|
+
# JS.myValue = 1 # sets window.myValue
|
|
15
|
+
#
|
|
16
|
+
# It is a separate file because it changes the JS module itself, which the
|
|
17
|
+
# js gem and other libraries also use. `require "jsg"` alone does not load it.
|
|
18
|
+
#
|
|
19
|
+
# Only names that JS does not already answer are forwarded. These keep their
|
|
20
|
+
# Ruby meaning, so use JS.global for the browser global of the same name:
|
|
21
|
+
#
|
|
22
|
+
# - methods of the js gem: JS.global, JS.eval, JS.try_convert, JS.is_a?, ...
|
|
23
|
+
# - methods every Ruby module has: JS.name (returns "JS", not window.name),
|
|
24
|
+
# JS.hash, JS.inspect, JS.class, JS.method, JS.display, JS.freeze, ...
|
|
25
|
+
#
|
|
26
|
+
# Private Kernel methods such as open, print or format are forwarded, because
|
|
27
|
+
# calling them with an explicit receiver (JS.open) ends up in method_missing.
|
|
28
|
+
# A name the global object does not have raises NoMethodError as usual.
|
|
29
|
+
module Global
|
|
30
|
+
# Sends +name+ with its arguments and block to JS.global if the global
|
|
31
|
+
# object responds to it (property read, setter, method call or predicate,
|
|
32
|
+
# as handled by the jsg patch); otherwise raises NoMethodError via super.
|
|
33
|
+
def method_missing(name, ...)
|
|
34
|
+
return super unless global.respond_to?(name)
|
|
35
|
+
|
|
36
|
+
global.__send__(name, ...)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Makes JS.respond_to?(name) true for the names method_missing forwards.
|
|
40
|
+
def respond_to_missing?(name, include_private = false)
|
|
41
|
+
global.respond_to?(name) || super
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
JS.extend(JSG::Global)
|
data/lib/jsg/version.rb
CHANGED
data/sig/jsg.rbs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
module JSG
|
|
2
2
|
VERSION: String
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
# require "jsg/global": forwards unknown methods on the JS module to JS.global
|
|
5
|
+
module Global
|
|
6
|
+
def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
|
|
7
|
+
def respond_to_missing?: (Symbol name, ?bool include_private) -> bool
|
|
8
|
+
end
|
|
4
9
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jsg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andi
|
|
@@ -53,6 +53,7 @@ files:
|
|
|
53
53
|
- exe/jsg
|
|
54
54
|
- lib/jsg.rb
|
|
55
55
|
- lib/jsg/cli.rb
|
|
56
|
+
- lib/jsg/global.rb
|
|
56
57
|
- lib/jsg/version.rb
|
|
57
58
|
- sig/jsg.rbs
|
|
58
59
|
- template/Gemfile
|