homura-runtime 0.2.25 → 0.2.27

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: aa815fa7e02b0f798dd69003008576f264eb3a0e2532805a729fee6f4a5aca6b
4
- data.tar.gz: e8af4871e543adc2ef6c6d8751272111c102987345ea6526ad1fa0e6e2192db8
3
+ metadata.gz: 17f9647265dd18252adf1bcfc4f73951db2b8c3300bf8e8fceb2e4a28d18ddd0
4
+ data.tar.gz: 0af103cb85483f3d2ecc3164579c0d8b784c2c0ece8cc8d584dd50735796cbb2
5
5
  SHA512:
6
- metadata.gz: c6f04b2b77f82131dd45148ff7d8467e0093ed005f49269ab2a2a37ab96ad957e6abd264c302331d37a4a95ac84885d9eef3882e51422fec7f6ed2f30aca25b1
7
- data.tar.gz: ff80cbfcbc5b699eed8c7f79c1da2b40aab678163185b0471ec269c7fe55db06d14515aaa22ece20bbff019ff754bc38d398c3a812ea33a2df3716fbea395716
6
+ metadata.gz: 911fee8fad91bdf26588b4f926c2edcae0d6f523dd43dfc571c8767a53acfc9b03214041e8f840d248072e16888cf3841dcb6ab67ae1d10d10b7d6f31772219d
7
+ data.tar.gz: 6c39b38063e532c3206ab0ebe027c234654908161d7e25934f618e26ebcd3efacd4b15a5baf2642e9f7d11cfec50d2e9ad40979c9b5ea0a89511d88547cb341e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.27 (2026-04-29)
4
+
5
+ - `Rack::Handler::CloudflareWorkers.run` now goes through
6
+ `ensure_dispatcher_installed!` instead of duplicating the JS
7
+ install snippet. Single source of truth for the dispatcher
8
+ installation; `@dispatcher_installed` correctly tracks the state
9
+ even when `run` is the first caller. Functionally identical from
10
+ the user's point of view (dispatcher ends up in `globalThis`
11
+ either way) — Copilot review on PR #34 spotted the duplication.
12
+
13
+ ## 0.2.26 (2026-04-29)
14
+
15
+ - `Rack::Handler::CloudflareWorkers#call`: when `@app` is nil, fall
16
+ back to `Sinatra::CloudflareWorkers.ensure_rack_app!` to discover
17
+ the Sinatra app lazily on the first fetch. This is what lets
18
+ classic-style apps omit the trailing `run Sinatra::Application`
19
+ line (paired with `sinatra-homura >= 0.2.23`).
20
+ - New `Rack::Handler::CloudflareWorkers.ensure_dispatcher_installed!`:
21
+ eagerly registers the JS-side dispatcher (`globalThis.__HOMURA_RACK_DISPATCH__`)
22
+ at script-load time, so a fetch arriving before `run` was called
23
+ still routes into our `call` method (where the lazy app discovery
24
+ above kicks in). On Workers `at_exit` is unreliable because the
25
+ isolate doesn't exit between requests; this eager install is the
26
+ reliable hook.
27
+
3
28
  ## 0.2.25 (2026-04-29)
4
29
 
5
30
  - `BuildSupport`: factor `opal_gem_paths` out of the path:-only
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudflareWorkers
4
- VERSION = '0.2.25'
4
+ VERSION = '0.2.27'
5
5
  end
@@ -126,7 +126,7 @@ module Rack
126
126
 
127
127
  def self.run(app, **_options)
128
128
  @app = app
129
- install_dispatcher
129
+ ensure_dispatcher_installed!
130
130
  app
131
131
  end
132
132
 
@@ -134,6 +134,34 @@ module Rack
134
134
  @app
135
135
  end
136
136
 
137
+ def self.app=(app)
138
+ @app = app
139
+ end
140
+
141
+ # Eagerly install the JS-side dispatcher so a fetch arriving
142
+ # before `run` was called (e.g. classic-style apps that omit the
143
+ # trailing `run Sinatra::Application`) still gets routed into our
144
+ # `call` method, which can then discover the user's Sinatra app
145
+ # lazily via `Sinatra::CloudflareWorkers.ensure_rack_app!`. This
146
+ # is what makes the canonical sinatrarb.com snippet work
147
+ # verbatim on Workers — `at_exit` is unreliable here because the
148
+ # isolate never actually exits between fetches.
149
+ def self.ensure_dispatcher_installed!
150
+ return true if @dispatcher_installed
151
+ handler = self
152
+ `
153
+ globalThis.__HOMURA_RACK_DISPATCH__ = async function(req, env, ctx, body_text) {
154
+ return await #{handler}.$call(req, env, ctx, body_text == null ? "" : body_text);
155
+ };
156
+ (function () {
157
+ var g = globalThis;
158
+ g.__OPAL_WORKERS__ = g.__OPAL_WORKERS__ || {};
159
+ g.__OPAL_WORKERS__.rack = g.__HOMURA_RACK_DISPATCH__;
160
+ })();
161
+ `
162
+ @dispatcher_installed = true
163
+ end
164
+
137
165
  # Entry point invoked from the Module Worker (src/worker.mjs) for
138
166
  # every fetch event. `js_req` is a Cloudflare Workers Request,
139
167
  # `js_env` is the bindings object (D1, KV, R2, secrets...),
@@ -141,7 +169,13 @@ module Rack
141
169
  # request body (the worker.mjs front awaits req.text() before
142
170
  # handing control to Ruby because Opal runs synchronously).
143
171
  def self.call(js_req, js_env, js_ctx, body_text = '')
144
- raise '`run app` was never called from user code' if @app.nil?
172
+ if @app.nil?
173
+ if defined?(::Sinatra::CloudflareWorkers) &&
174
+ ::Sinatra::CloudflareWorkers.respond_to?(:ensure_rack_app!)
175
+ ::Sinatra::CloudflareWorkers.ensure_rack_app!
176
+ end
177
+ raise '`run app` was never called from user code, and no Sinatra app was discoverable (define `class App < Sinatra::Base` or use top-level classic Sinatra routes)' if @app.nil?
178
+ end
145
179
 
146
180
  env = build_rack_env(js_req, js_env, js_ctx, body_text)
147
181
  result = @app.call(env)
@@ -156,18 +190,13 @@ module Rack
156
190
  class << self
157
191
  private
158
192
 
193
+ # Legacy alias, kept so out-of-tree code calling
194
+ # `Rack::Handler::CloudflareWorkers.send(:install_dispatcher)`
195
+ # keeps working. New code should go through
196
+ # `ensure_dispatcher_installed!` (it's idempotent and tracks
197
+ # state via `@dispatcher_installed`).
159
198
  def install_dispatcher
160
- handler = self
161
- `
162
- globalThis.__HOMURA_RACK_DISPATCH__ = async function(req, env, ctx, body_text) {
163
- return await #{handler}.$call(req, env, ctx, body_text == null ? "" : body_text);
164
- };
165
- (function () {
166
- var g = globalThis;
167
- g.__OPAL_WORKERS__ = g.__OPAL_WORKERS__ || {};
168
- g.__OPAL_WORKERS__.rack = g.__HOMURA_RACK_DISPATCH__;
169
- })();
170
- `
199
+ ensure_dispatcher_installed!
171
200
  end
172
201
 
173
202
  # Build a Rack-compliant env Hash from a Cloudflare Workers Request.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: homura-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.25
4
+ version: 0.2.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuhiro Homma