jsg 0.2.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1d60a874b6a2f773a473b333c5f2ff4db6d47f532dc1a257c1c1c34b7a226f8
4
- data.tar.gz: 5f777d0b59c0454922d48bdf9b2a03b09b62ba106a7fb952d368276579cd6ade
3
+ metadata.gz: c5bbe669419df7b6181dacae7851ccf5a27b97abdf6e6a4a2a48c73e10d87632
4
+ data.tar.gz: c838fccba5ca6a8316d0718b097312b3760f31b94f9112eeee1bf1e7053c142f
5
5
  SHA512:
6
- metadata.gz: f4100bdf2b90ebe3c9a930e5981dcc99da12efd458602021d41631b9f61056ad6986ca1e93bc26f639e43977beebc2b73b7fe95f6d7a993b9f221a141fc015d8
7
- data.tar.gz: f80229f22ac0201a35ba6582a1de2a50692ac118da9dc100df638df85f13517fdf2a00396bce4ada9ae32f8c502c8a6a38d1e5f1f4d3cb7b9cff1ae0feb339f1
6
+ metadata.gz: 448f59e03a1e7a38c89f0ff99e5ff32ddda31fd3009bef7d712929ce93c4b7804aba3d137df8c4aff25f051f47a4bec023ad211a907da1ed06c2de4baa53c850
7
+ data.tar.gz: 5bfbcff342b82afd36fd558eb8a63052f8b2699e98f5d65eebdb5c5c2cb0dd67dbab2c9505fd28227ed6d2716e32070dce6aded230627ec8bbc37e0786d9fe82
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
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
+
8
+ ## [0.2.1] - 2026-09-29
9
+
10
+ - First release published from GitHub Actions with RubyGems trusted publishing (`.github/workflows/release.yml`, triggered by `v*` tags).
11
+ - CI runs the ruby.wasm tests on Node.js 24. Node 22's WASI crashes once Ruby loads files from a mounted directory.
12
+
3
13
  ## [0.2.0] - 2026-09-29
4
14
 
5
15
  - Fix `require "jsg"`: the library moved from the gem root to `lib/jsg.rb`, so it is on the load path.
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
@@ -104,7 +127,16 @@ bin/setup
104
127
  bundle exec rake # rspec, the ruby.wasm tests and rubocop
105
128
  ```
106
129
 
107
- The specs in `spec/` test the command line tool on your normal Ruby. `lib/jsg.rb` needs the js gem, which only works inside ruby.wasm, so its tests in `test/wasm` run the prebuilt ruby.wasm on Node.js (`bundle exec rake test:wasm`, needs Node.js and npm).
130
+ To release a new version, update `lib/jsg/version.rb` and `CHANGELOG.md`, commit, and push a matching tag:
131
+
132
+ ```bash
133
+ git tag v0.3.0
134
+ git push origin v0.3.0
135
+ ```
136
+
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.
138
+
139
+ The specs in `spec/` test the command line tool on your normal Ruby. `lib/jsg.rb` needs the js gem, which only works inside ruby.wasm, so its tests in `test/wasm` run the prebuilt ruby.wasm on Node.js (`bundle exec rake test:wasm`, needs Node.js 24 or newer and npm).
108
140
 
109
141
  ## License
110
142
 
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSG
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/sig/jsg.rbs CHANGED
@@ -1,4 +1,9 @@
1
1
  module JSG
2
2
  VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
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.2.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
@@ -81,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
82
  - !ruby/object:Gem::Version
82
83
  version: '0'
83
84
  requirements: []
84
- rubygems_version: 4.0.18
85
+ rubygems_version: 4.0.20
85
86
  specification_version: 4
86
87
  summary: JSG helps setting up ruby.wasm projects and comes with a nicer syntax
87
88
  test_files: []