homura-runtime 0.2.27 → 0.3.1

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: 17f9647265dd18252adf1bcfc4f73951db2b8c3300bf8e8fceb2e4a28d18ddd0
4
- data.tar.gz: 0af103cb85483f3d2ecc3164579c0d8b784c2c0ece8cc8d584dd50735796cbb2
3
+ metadata.gz: 8add04211534a53fdb39d920d9b6dc143005acabe260f15d45c3b3a54b95dc9a
4
+ data.tar.gz: ab5115722674df8f52a7839a7b80f135f84f3e686988b85e1649d1785009ce0d
5
5
  SHA512:
6
- metadata.gz: 911fee8fad91bdf26588b4f926c2edcae0d6f523dd43dfc571c8767a53acfc9b03214041e8f840d248072e16888cf3841dcb6ab67ae1d10d10b7d6f31772219d
7
- data.tar.gz: 6c39b38063e532c3206ab0ebe027c234654908161d7e25934f618e26ebcd3efacd4b15a5baf2642e9f7d11cfec50d2e9ad40979c9b5ea0a89511d88547cb341e
6
+ metadata.gz: 3147e261629b3ba277fce2729dcf4deb47dbea060db34111d716e36d188b4dc15f6f3e0a88186c774a9d9884d70f289ac8bfb03cd57b6c6d4d517018d9ca88cf
7
+ data.tar.gz: d5304208f712e6b4ac7f609489558b28e1609927180ae7e5387423363f9d536cbbb31730667d7084d903fecf9c63bc9bebb4cd558bf2acbdef911807042f2a31
data/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 (2026-04-29)
4
+
5
+ - Fix `release-gems.yml` `Resolve gem target` step: now reads
6
+ `gems/homura-runtime/lib/homura/runtime/version.rb` (was the
7
+ pre-rename `gems/homura-runtime/lib/cloudflare_workers/version.rb`,
8
+ which 0.3.0's tag-push publish failed on).
9
+ - No code changes since 0.3.0; this version exists only because
10
+ re-tagging a published version is forbidden by the project's
11
+ release rules. 0.3.0 was never published to RubyGems.
12
+
13
+ ## 0.3.0 (2026-04-29) — BREAKING: cloudflare_workers naming eliminated
14
+
15
+ The "cloudflare_workers" branding everywhere inside the gem is gone.
16
+ gem name is `homura-runtime`, the module is now `HomuraRuntime`, the
17
+ require path is `require 'homura/runtime'`, and the Rack handler is
18
+ `Rack::Handler::Homura`. Apps that pinned ≤ 0.2.x and referenced
19
+ either `CloudflareWorkers::*` or `require 'cloudflare_workers'`
20
+ must update.
21
+
22
+ Renames:
23
+
24
+ | was | now |
25
+ |---|---|
26
+ | `module CloudflareWorkers` | `module HomuraRuntime` |
27
+ | `CloudflareWorkersIO` (stdout/stderr replacement class) | `HomuraRuntimeIO` |
28
+ | `Rack::Handler::CloudflareWorkers` | `Rack::Handler::Homura` |
29
+ | `require 'cloudflare_workers'` | `require 'homura/runtime'` |
30
+ | `lib/cloudflare_workers.rb` | `lib/homura/runtime.rb` |
31
+ | `lib/cloudflare_workers/*.rb` | `lib/homura/runtime/*.rb` |
32
+
33
+ `Cloudflare` namespace (binding wrappers like `Cloudflare::HTTP`,
34
+ `Cloudflare::D1Error`, `Cloudflare.js_promise?`) and Cloudflare-
35
+ specific Rack env keys (`env['cloudflare.DB']`, `env['cloudflare.KV']`,
36
+ …) are unchanged — those are factual descriptions of the underlying
37
+ Cloudflare Workers bindings, not branding.
38
+
39
+ No backward-compat shim. Per the project's `v1未満は破壊的に置き換え`
40
+ rule, old constant aliases are not preserved.
41
+
3
42
  ## 0.2.27 (2026-04-29)
4
43
 
5
44
  - `Rack::Handler::CloudflareWorkers.run` now goes through
data/exe/auto-await CHANGED
@@ -15,18 +15,18 @@
15
15
 
16
16
  require 'fileutils'
17
17
  require 'pathname'
18
- require_relative '../lib/cloudflare_workers/build_support'
18
+ require_relative '../lib/homura/runtime/build_support'
19
19
 
20
20
  # homura-runtime lib path resolution (with legacy alias fallback)
21
21
  runtime_lib = ENV['CFW_RUNTIME_LIB']
22
22
  unless runtime_lib
23
- runtime_lib = CloudflareWorkers::BuildSupport.runtime_root(current_file: __FILE__).join('lib').to_s
23
+ runtime_lib = HomuraRuntime::BuildSupport.runtime_root(current_file: __FILE__).join('lib').to_s
24
24
  end
25
25
  $LOAD_PATH.unshift(runtime_lib) unless $LOAD_PATH.include?(runtime_lib)
26
26
 
27
- require 'cloudflare_workers/async_registry'
28
- require 'cloudflare_workers/auto_await/analyzer'
29
- require 'cloudflare_workers/auto_await/transformer'
27
+ require 'homura/runtime/async_registry'
28
+ require 'homura/runtime/auto_await/analyzer'
29
+ require 'homura/runtime/auto_await/transformer'
30
30
 
31
31
  options = { input: nil, output: nil, debug: ENV['CLOUDFLARE_WORKERS_AUTO_AWAIT_DEBUG'] == '1' }
32
32
 
@@ -43,10 +43,10 @@ abort('Usage: auto-await --input DIR --output DIR [--debug]') unless options[:in
43
43
  input_root = Pathname(options[:input]).expand_path
44
44
  output_root = Pathname(options[:output]).expand_path
45
45
 
46
- registry = CloudflareWorkers::AsyncRegistry.instance
46
+ registry = HomuraRuntime::AsyncRegistry.instance
47
47
 
48
48
  # Auto-load async source registrations from all loaded gems.
49
- CloudflareWorkers::AsyncRegistry.auto_load_gem_async_sources(debug: options[:debug])
49
+ HomuraRuntime::AsyncRegistry.auto_load_gem_async_sources(debug: options[:debug])
50
50
 
51
51
  # Load project-specific async source registrations if present.
52
52
  project_async = File.join(Dir.pwd, 'lib', 'homura_async_sources.rb')
@@ -75,7 +75,7 @@ paths.each do |path|
75
75
  has_existing_await = source.include?('.__await__')
76
76
 
77
77
  begin
78
- analyzer = CloudflareWorkers::AutoAwait::Analyzer.new(registry, debug: options[:debug])
78
+ analyzer = HomuraRuntime::AutoAwait::Analyzer.new(registry, debug: options[:debug])
79
79
  buffer, nodes = analyzer.process(source, path)
80
80
  needs_magic_only_output = has_existing_await && !has_magic
81
81
 
@@ -89,7 +89,7 @@ paths.each do |path|
89
89
  if nodes.empty?
90
90
  source
91
91
  else
92
- CloudflareWorkers::AutoAwait::Transformer.transform(source, nodes, buffer)
92
+ HomuraRuntime::AutoAwait::Transformer.transform(source, nodes, buffer)
93
93
  end
94
94
  unless has_magic
95
95
  transformed = "# await: true\n" + transformed
data/exe/homura-build CHANGED
@@ -8,12 +8,12 @@ require 'fileutils'
8
8
  require 'open3'
9
9
  require 'optparse'
10
10
  require 'pathname'
11
- require_relative '../lib/cloudflare_workers/build_support'
11
+ require_relative '../lib/homura/runtime/build_support'
12
12
 
13
- module CloudflareWorkersBuild
13
+ module HomuraRuntimeBuild
14
14
  class << self
15
15
  def gem_root
16
- CloudflareWorkers::BuildSupport.runtime_root(current_file: __FILE__)
16
+ HomuraRuntime::BuildSupport.runtime_root(current_file: __FILE__)
17
17
  end
18
18
 
19
19
  def runtime_dir
@@ -25,11 +25,11 @@ module CloudflareWorkersBuild
25
25
  end
26
26
 
27
27
  def gem_lib(*names)
28
- CloudflareWorkers::BuildSupport.gem_lib(*names)
28
+ HomuraRuntime::BuildSupport.gem_lib(*names)
29
29
  end
30
30
 
31
31
  def gem_vendor(*names)
32
- CloudflareWorkers::BuildSupport.gem_vendor(*names)
32
+ HomuraRuntime::BuildSupport.gem_vendor(*names)
33
33
  end
34
34
  end
35
35
  end
@@ -72,8 +72,8 @@ end.parse!
72
72
  options[:standalone] = true if options[:with_db]
73
73
 
74
74
  root = Pathname(options[:root]).expand_path
75
- options[:templates_namespace] ||= CloudflareWorkers::BuildSupport.standalone_namespace(root, 'Templates') if options[:standalone]
76
- options[:assets_namespace] ||= CloudflareWorkers::BuildSupport.standalone_namespace(root, 'Assets') if options[:standalone]
75
+ options[:templates_namespace] ||= HomuraRuntime::BuildSupport.standalone_namespace(root, 'Templates') if options[:standalone]
76
+ options[:assets_namespace] ||= HomuraRuntime::BuildSupport.standalone_namespace(root, 'Assets') if options[:standalone]
77
77
 
78
78
  if options[:standalone]
79
79
  Dir.chdir(root) { require 'bundler/setup' }
@@ -109,7 +109,7 @@ def run_opal_homura!(root, opal_input, opal_output)
109
109
  '-I', 'gems/sinatra-homura/lib',
110
110
  '-I', 'gems/sequel-d1/lib',
111
111
  '-I', 'lib', '-I', 'vendor', '-I', 'build',
112
- '-r', 'opal_patches', '-r', 'cloudflare_workers',
112
+ '-r', 'opal_patches', '-r', 'homura/runtime',
113
113
  '-r', 'homura_templates', '-r', 'homura_assets',
114
114
  '-o', opal_output,
115
115
  opal_input
@@ -123,15 +123,15 @@ def run_opal_homura!(root, opal_input, opal_output)
123
123
  end
124
124
 
125
125
  def homura_vendor_from_gemfile(project_root)
126
- CloudflareWorkers::BuildSupport.vendor_from_gemfile(project_root)
126
+ HomuraRuntime::BuildSupport.vendor_from_gemfile(project_root)
127
127
  end
128
128
 
129
129
  def run_opal_standalone!(root, opal_input, opal_output, with_db:)
130
- load_paths = CloudflareWorkers::BuildSupport.standalone_load_paths(root, with_db: with_db)
130
+ load_paths = HomuraRuntime::BuildSupport.standalone_load_paths(root, with_db: with_db)
131
131
 
132
132
  argv = ['bundle', 'exec', 'opal', '-c', '-E', '--esm', '--no-source-map']
133
133
  load_paths.each { |p| argv.push('-I', p) }
134
- argv += %w[-r opal_patches -r cloudflare_workers -r app_templates -r app_assets -o] + [opal_output, opal_input]
134
+ argv += %w[-r opal_patches -r homura/runtime -r app_templates -r app_assets -o] + [opal_output, opal_input]
135
135
 
136
136
  stderr_log = root.join('build/opal.stderr.log')
137
137
  FileUtils.mkdir_p(root.join('build'))
@@ -185,7 +185,7 @@ unless options[:standalone]
185
185
  run!(['ruby', 'bin/inline-routes-for-opal'], chdir: root)
186
186
  run!(
187
187
  [
188
- 'ruby', CloudflareWorkersBuild.exe_path('auto-await').to_s,
188
+ 'ruby', HomuraRuntimeBuild.exe_path('auto-await').to_s,
189
189
  '--input', 'app',
190
190
  '--output', 'build/auto_await/app'
191
191
  ],
@@ -193,7 +193,7 @@ unless options[:standalone]
193
193
  )
194
194
  run!(
195
195
  [
196
- 'ruby', CloudflareWorkersBuild.exe_path('auto-await').to_s,
196
+ 'ruby', HomuraRuntimeBuild.exe_path('auto-await').to_s,
197
197
  '--input', 'build/routes_app_class_eval.rb',
198
198
  '--output', 'build/auto_await/routes_app_class_eval.rb'
199
199
  ],
@@ -201,7 +201,7 @@ unless options[:standalone]
201
201
  )
202
202
  run!(
203
203
  [
204
- 'ruby', CloudflareWorkersBuild.exe_path('compile-erb').to_s,
204
+ 'ruby', HomuraRuntimeBuild.exe_path('compile-erb').to_s,
205
205
  '--input', 'views',
206
206
  '--output', 'build/homura_templates.rb',
207
207
  '--namespace', 'HomuraTemplates'
@@ -210,7 +210,7 @@ unless options[:standalone]
210
210
  )
211
211
  run!(
212
212
  [
213
- 'ruby', CloudflareWorkersBuild.exe_path('compile-assets').to_s,
213
+ 'ruby', HomuraRuntimeBuild.exe_path('compile-assets').to_s,
214
214
  '--input', 'public',
215
215
  '--output', 'build/homura_assets.rb',
216
216
  '--namespace', 'HomuraAssets'
@@ -229,10 +229,10 @@ unless options[:standalone]
229
229
  FileUtils.rm_f(temp_input) if temp_input
230
230
  end
231
231
  else
232
- CloudflareWorkers::BuildSupport.ensure_standalone_runtime(root, current_file: __FILE__)
232
+ HomuraRuntime::BuildSupport.ensure_standalone_runtime(root, current_file: __FILE__)
233
233
  run!(
234
234
  [
235
- 'ruby', CloudflareWorkersBuild.exe_path('compile-erb').to_s,
235
+ 'ruby', HomuraRuntimeBuild.exe_path('compile-erb').to_s,
236
236
  '--input', 'views',
237
237
  '--output', 'build/app_templates.rb',
238
238
  '--namespace', options[:templates_namespace]
@@ -241,7 +241,7 @@ else
241
241
  )
242
242
  run!(
243
243
  [
244
- 'ruby', CloudflareWorkersBuild.exe_path('compile-assets').to_s,
244
+ 'ruby', HomuraRuntimeBuild.exe_path('compile-assets').to_s,
245
245
  '--input', 'public',
246
246
  '--output', 'build/app_assets.rb',
247
247
  '--namespace', options[:assets_namespace]
@@ -256,7 +256,7 @@ else
256
256
  if root.join('app').directory?
257
257
  run!(
258
258
  [
259
- 'ruby', CloudflareWorkersBuild.exe_path('auto-await').to_s,
259
+ 'ruby', HomuraRuntimeBuild.exe_path('auto-await').to_s,
260
260
  '--input', 'app',
261
261
  '--output', 'build/auto_await/app'
262
262
  ],
@@ -265,7 +265,7 @@ else
265
265
  elsif root.join('app.rb').file?
266
266
  run!(
267
267
  [
268
- 'ruby', CloudflareWorkersBuild.exe_path('auto-await').to_s,
268
+ 'ruby', HomuraRuntimeBuild.exe_path('auto-await').to_s,
269
269
  '--input', 'app.rb',
270
270
  '--output', 'build/auto_await/app.rb'
271
271
  ],
@@ -282,7 +282,7 @@ else
282
282
  # `build/auto_await/gem_<basename>/<sub>` and
283
283
  # `standalone_load_paths` puts those rewritten copies ahead of the
284
284
  # gem's untransformed `lib/`.
285
- CloudflareWorkers::BuildSupport.opal_gem_paths(root).each do |gem_path|
285
+ HomuraRuntime::BuildSupport.opal_gem_paths(root).each do |gem_path|
286
286
  %w[lib].each do |sub|
287
287
  src = gem_path.join(sub)
288
288
  next unless src.directory?
@@ -290,7 +290,7 @@ else
290
290
  FileUtils.mkdir_p(out)
291
291
  run!(
292
292
  [
293
- 'ruby', CloudflareWorkersBuild.exe_path('auto-await').to_s,
293
+ 'ruby', HomuraRuntimeBuild.exe_path('auto-await').to_s,
294
294
  '--input', src.to_s,
295
295
  '--output', out.to_s
296
296
  ],
@@ -317,7 +317,7 @@ patch_rel = root.join(patch_rel) unless patch_rel.absolute?
317
317
  run!(
318
318
  [
319
319
  'node',
320
- CloudflareWorkersBuild.runtime_dir.join('patch-opal-evals.mjs').to_s,
320
+ HomuraRuntimeBuild.runtime_dir.join('patch-opal-evals.mjs').to_s,
321
321
  patch_rel.relative_path_from(root).to_s
322
322
  ],
323
323
  chdir: root
@@ -21,7 +21,7 @@
21
21
  #
22
22
  # Streaming (`stream: true`) returns the raw JS ReadableStream wrapped
23
23
  # in `Cloudflare::AI::Stream` so a route can hand it to a Server-Sent
24
- # Events response. See `lib/cloudflare_workers.rb#build_js_response`
24
+ # Events response. See `lib/homura/runtime.rb#build_js_response`
25
25
  # for the SSE / ReadableStream pass-through.
26
26
 
27
27
  require 'json'
@@ -71,7 +71,7 @@ module Cloudflare
71
71
  # keeps the returned value alive through the local). Do NOT
72
72
  # refactor this so the backtick is the method's last expression
73
73
  # or the Promise will be silently dropped (same pitfall
74
- # documented in lib/cloudflare_workers/{cache,queue}.rb —
74
+ # documented in lib/homura/runtime/{cache,queue}.rb —
75
75
  # Phase 11B audit).
76
76
  js_promise = `
77
77
  (async function() {
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'set'
4
4
 
5
- module CloudflareWorkers
5
+ module HomuraRuntime
6
6
  class AsyncRegistry
7
7
  class Builder
8
8
  def initialize(registry)
@@ -137,7 +137,7 @@ end
137
137
  # Phase 17.5 — Auto-Await: register runtime gem async sources.
138
138
  # Each binding declares which methods return Promises so the
139
139
  # build-time analyzer can insert .__await__ automatically.
140
- CloudflareWorkers::AsyncRegistry.register_async_source do
140
+ HomuraRuntime::AsyncRegistry.register_async_source do
141
141
  async_method 'Cloudflare::D1Database', :execute
142
142
  async_method 'Cloudflare::D1Database', :get_first_row
143
143
  async_method 'Cloudflare::D1Database', :execute_insert
@@ -4,7 +4,7 @@ require 'parser/current'
4
4
  require 'parser/source/tree_rewriter'
5
5
  require 'set'
6
6
 
7
- module CloudflareWorkers
7
+ module HomuraRuntime
8
8
  module AutoAwait
9
9
  class Analyzer
10
10
  def initialize(registry, debug: false)
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'parser/source/tree_rewriter'
4
4
 
5
- module CloudflareWorkers
5
+ module HomuraRuntime
6
6
  module AutoAwait
7
7
  class Transformer
8
8
  def self.transform(source, await_nodes, buffer)
@@ -3,7 +3,7 @@
3
3
  require 'fileutils'
4
4
  require 'pathname'
5
5
 
6
- module CloudflareWorkers
6
+ module HomuraRuntime
7
7
  module BuildSupport
8
8
  RUNTIME_GEM_NAME = 'homura-runtime'
9
9
  SINATRA_GEM_NAME = 'sinatra-homura'
@@ -165,7 +165,7 @@ module Cloudflare
165
165
  # gets dropped and the caller's `__await__` receives `undefined`
166
166
  # instead of waiting for `cache.put` to resolve. That was the
167
167
  # silent bug: the inner `await` ran, but the outer await had
168
- # already proceeded. See lib/cloudflare_workers/scheduled.rb for
168
+ # already proceeded. See lib/homura/runtime/scheduled.rb for
169
169
  # the same Opal multi-line x-string constraint.
170
170
  # Warn ONCE per isolate on a nil cache. Non-Workers runtimes
171
171
  # hit `Cache.new(nil, ...)` intentionally (tests, safe fall-back
@@ -11,7 +11,7 @@
11
11
  # session servers, and collaborative state machines without any external
12
12
  # store.
13
13
  #
14
- # Three responsibilities here, analogous to `cloudflare_workers.rb`'s
14
+ # Three responsibilities here, analogous to `homura/runtime.rb`'s
15
15
  # D1 / KV / R2 section:
16
16
  #
17
17
  # 1. `Cloudflare::DurableObjectNamespace` — wraps the binding JS object
@@ -163,7 +163,7 @@ module Cloudflare
163
163
  response_klass = Cloudflare::HTTPResponse
164
164
  do_class_label = 'DurableObjectStub'
165
165
 
166
- # Single-line IIFE — see `lib/cloudflare_workers/cache.rb#put`
166
+ # Single-line IIFE — see `lib/homura/runtime/cache.rb#put`
167
167
  # for why Opal can silently drop a multi-line x-string Promise.
168
168
  js_promise = `(async function(stub, url_str, method_str, js_headers, js_body, Kernel, err_klass, do_class_label) { var init = { method: method_str, headers: js_headers }; if (js_body !== null && js_body !== undefined && js_body !== Opal.nil) { init.body = js_body; } var resp; try { resp = await stub.fetch(url_str, init); } catch (e) { Kernel.$raise(err_klass.$new(e && e.message ? e.message : String(e), Opal.hash({ operation: 'stub.fetch', do_class: do_class_label }))); } var text = ''; try { text = await resp.text(); } catch (_) { text = ''; } var hk = []; var hv = []; if (resp.headers && typeof resp.headers.forEach === 'function') { resp.headers.forEach(function(v, k) { hk.push(String(k).toLowerCase()); hv.push(String(v)); }); } return { status: resp.status|0, text: text, hkeys: hk, hvals: hv }; })(#{js_stub}, #{url_str}, #{method_str}, #{js_headers}, #{js_body}, #{Kernel}, #{err_klass}, #{do_class_label})`
169
169
 
@@ -357,7 +357,7 @@ module Cloudflare
357
357
  #
358
358
  # Kept as a single-line backtick x-string — Opal's compiler refuses
359
359
  # multi-line backticks as expressions (same constraint documented
360
- # in `lib/cloudflare_workers/scheduled.rb#install_dispatcher`).
360
+ # in `lib/homura/runtime/scheduled.rb#install_dispatcher`).
361
361
  # Installs FOUR hooks: fetch dispatcher + 3 websocket event
362
362
  # dispatchers. Each wraps Ruby exceptions in a console.error so a
363
363
  # bad handler doesn't crash the DO.
@@ -516,7 +516,7 @@ module Cloudflare
516
516
 
517
517
  # The incoming `request` argument passed to DO handlers. `body_text`
518
518
  # is pre-awaited by the JS dispatcher because Ruby runs synchronously
519
- # under Opal (same pattern as `Rack::Handler::CloudflareWorkers.call`).
519
+ # under Opal (same pattern as `Rack::Handler::Homura.call`).
520
520
  class DurableObjectRequest
521
521
  attr_reader :js_request, :body
522
522
 
@@ -85,7 +85,7 @@ module Cloudflare
85
85
  # at end-of-method silently drops the Promise. Do NOT refactor
86
86
  # this into `def fetch ... end` with the backtick as the last
87
87
  # expression. See the single-line IIFE pattern used in
88
- # lib/cloudflare_workers/{cache,queue,durable_object}.rb#put for
88
+ # lib/homura/runtime/{cache,queue,durable_object}.rb#put for
89
89
  # the alternative that survives either position. (Phase 11B audit.)
90
90
  js_promise = `
91
91
  (async function() {
@@ -83,7 +83,7 @@ module Cloudflare
83
83
  # NOTE: single-line backtick x-string so Opal emits it as an
84
84
  # expression (multi-line x-strings compile to raw statements and
85
85
  # would silently return `undefined`). Same gotcha documented
86
- # elsewhere in this codebase (see lib/cloudflare_workers.rb).
86
+ # elsewhere in this codebase (see lib/homura/runtime.rb).
87
87
  def to_uint8_array
88
88
  `(function(s) { var len = s.length; var out = new Uint8Array(len); for (var i = 0; i < len; i++) { out[i] = s.charCodeAt(i) & 0xff; } return out; })(#{@bytes_binstr})`
89
89
  end
@@ -63,7 +63,7 @@ module Cloudflare
63
63
  def available?
64
64
  js = @js
65
65
  # Opal's Ruby nil is a runtime sentinel (Opal.nil), not JS null.
66
- # See `lib/cloudflare_workers/cache.rb#available?` for the same
66
+ # See `lib/homura/runtime/cache.rb#available?` for the same
67
67
  # pattern and rationale.
68
68
  !!`(#{js} !== null && #{js} !== undefined && #{js} !== Opal.nil)`
69
69
  end
@@ -86,7 +86,7 @@ module Cloudflare
86
86
  `#{js_opts}.delaySeconds = #{delay_seconds.to_i}` if delay_seconds
87
87
  `#{js_opts}.contentType = #{content_type.to_s}` if content_type
88
88
 
89
- # Single-line IIFE — see `lib/cloudflare_workers/cache.rb#put`
89
+ # Single-line IIFE — see `lib/homura/runtime/cache.rb#put`
90
90
  # for the Opal multi-line x-string quirk. Passing arguments in
91
91
  # explicitly (rather than interpolating inside the template)
92
92
  # keeps the Promise a first-class expression.
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # 3. Exposes `Cloudflare::Scheduled.app=` so non-Sinatra Rack apps
25
25
  # can hook the dispatcher too. By default, `Rack::Handler::
26
- # CloudflareWorkers.app` (set by `run app` in user code) is used.
26
+ # HomuraRuntime.app` (set by `run app` in user code) is used.
27
27
  #
28
28
  # Test entry point: `Cloudflare::Scheduled.dispatch(cron, scheduled_time, js_env, js_ctx)`
29
29
  # — used by `test/scheduled_smoke.rb` so the same code path that the
@@ -91,7 +91,7 @@ module Cloudflare
91
91
 
92
92
  class << self
93
93
  # Override the dispatch target. By default the dispatcher uses
94
- # `Rack::Handler::CloudflareWorkers.app`, which is whatever the
94
+ # `Rack::Handler::Homura.app`, which is whatever the
95
95
  # user passed to top-level `run app`. Tests use this to plug
96
96
  # a fake Sinatra subclass without booting the full handler.
97
97
  attr_accessor :app
@@ -154,13 +154,13 @@ module Cloudflare
154
154
 
155
155
  # Resolve which app class should receive the dispatch. Priority:
156
156
  # 1. `Cloudflare::Scheduled.app = SomeApp` (explicit override)
157
- # 2. `Rack::Handler::CloudflareWorkers.app` (set by `run app`)
157
+ # 2. `Rack::Handler::Homura.app` (set by `run app`)
158
158
  # Returns the class itself (not an instance), because
159
159
  # `dispatch_scheduled` is a class method on Sinatra apps.
160
160
  def self.resolve_app
161
161
  candidate = @app
162
- if candidate.nil? && defined?(::Rack::Handler::CloudflareWorkers)
163
- candidate = ::Rack::Handler::CloudflareWorkers.app
162
+ if candidate.nil? && defined?(::Rack::Handler::Homura)
163
+ candidate = ::Rack::Handler::Homura.app
164
164
  end
165
165
  return nil if candidate.nil?
166
166
  # Sinatra app classes respond to `dispatch_scheduled` (added by
@@ -48,7 +48,7 @@ module Cloudflare
48
48
  @js_stream = nil
49
49
  end
50
50
 
51
- # Duck-typed marker consumed by Rack::Handler::CloudflareWorkers.
51
+ # Duck-typed marker consumed by Rack::Handler::Homura.
52
52
  def sse_stream?
53
53
  true
54
54
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HomuraRuntime
4
+ VERSION = '0.3.1'
5
+ end
@@ -10,11 +10,11 @@
10
10
  #
11
11
  # Three responsibilities, modelled after existing Ruby conventions:
12
12
  #
13
- # 1. CloudflareWorkersIO — replaces nodejs.rb's $stdout / $stderr (which
13
+ # 1. HomuraRuntimeIO — replaces nodejs.rb's $stdout / $stderr (which
14
14
  # try to write to a closed Socket on Workers) with shims that route
15
15
  # Ruby `puts` / `print` to V8's globalThis.console.log/error.
16
16
  #
17
- # 2. Rack::Handler::CloudflareWorkers — a standard Rack handler. Same
17
+ # 2. Rack::Handler::Homura — a standard Rack handler. Same
18
18
  # shape as Rack::Handler::Puma, Rack::Handler::WEBrick, etc. User
19
19
  # code uses the conventional top-level `run app` from a config.ru-
20
20
  # style entry point and never sees a Cloudflare-specific symbol.
@@ -35,7 +35,7 @@ require 'await'
35
35
  # 1. stdout / stderr → console.log / console.error
36
36
  # ---------------------------------------------------------------------------
37
37
 
38
- class CloudflareWorkersIO
38
+ class HomuraRuntimeIO
39
39
  def initialize(channel)
40
40
  @channel = channel # 'log' or 'error'
41
41
  @buffer = ''
@@ -105,13 +105,13 @@ class CloudflareWorkersIO
105
105
  end
106
106
  end
107
107
 
108
- $stdout = CloudflareWorkersIO.new('log')
109
- $stderr = CloudflareWorkersIO.new('error')
110
- Object.const_set(:STDOUT, $stdout) unless Object.const_defined?(:STDOUT) && STDOUT.is_a?(CloudflareWorkersIO)
111
- Object.const_set(:STDERR, $stderr) unless Object.const_defined?(:STDERR) && STDERR.is_a?(CloudflareWorkersIO)
108
+ $stdout = HomuraRuntimeIO.new('log')
109
+ $stderr = HomuraRuntimeIO.new('error')
110
+ Object.const_set(:STDOUT, $stdout) unless Object.const_defined?(:STDOUT) && STDOUT.is_a?(HomuraRuntimeIO)
111
+ Object.const_set(:STDERR, $stderr) unless Object.const_defined?(:STDERR) && STDERR.is_a?(HomuraRuntimeIO)
112
112
 
113
113
  # ---------------------------------------------------------------------------
114
- # 2. Rack::Handler::CloudflareWorkers
114
+ # 2. Rack::Handler::Homura
115
115
  # ---------------------------------------------------------------------------
116
116
  #
117
117
  # Conforms to the Rack handler convention: a module with a `run` class
@@ -121,7 +121,7 @@ Object.const_set(:STDERR, $stderr) unless Object.const_defined?(:STDERR) && STDE
121
121
 
122
122
  module Rack
123
123
  module Handler
124
- module CloudflareWorkers
124
+ module Homura
125
125
  EMPTY_STRING_IO = StringIO.new('').freeze
126
126
 
127
127
  def self.run(app, **_options)
@@ -142,7 +142,7 @@ module Rack
142
142
  # before `run` was called (e.g. classic-style apps that omit the
143
143
  # trailing `run Sinatra::Application`) still gets routed into our
144
144
  # `call` method, which can then discover the user's Sinatra app
145
- # lazily via `Sinatra::CloudflareWorkers.ensure_rack_app!`. This
145
+ # lazily via `Sinatra::Homura.ensure_rack_app!`. This
146
146
  # is what makes the canonical sinatrarb.com snippet work
147
147
  # verbatim on Workers — `at_exit` is unreliable here because the
148
148
  # isolate never actually exits between fetches.
@@ -170,9 +170,9 @@ module Rack
170
170
  # handing control to Ruby because Opal runs synchronously).
171
171
  def self.call(js_req, js_env, js_ctx, body_text = '')
172
172
  if @app.nil?
173
- if defined?(::Sinatra::CloudflareWorkers) &&
174
- ::Sinatra::CloudflareWorkers.respond_to?(:ensure_rack_app!)
175
- ::Sinatra::CloudflareWorkers.ensure_rack_app!
173
+ if defined?(::Sinatra::Homura) &&
174
+ ::Sinatra::Homura.respond_to?(:ensure_rack_app!)
175
+ ::Sinatra::Homura.ensure_rack_app!
176
176
  end
177
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
178
  end
@@ -191,7 +191,7 @@ module Rack
191
191
  private
192
192
 
193
193
  # Legacy alias, kept so out-of-tree code calling
194
- # `Rack::Handler::CloudflareWorkers.send(:install_dispatcher)`
194
+ # `Rack::Handler::Homura.send(:install_dispatcher)`
195
195
  # keeps working. New code should go through
196
196
  # `ensure_dispatcher_installed!` (it's idempotent and tracks
197
197
  # state via `@dispatcher_installed`).
@@ -504,7 +504,7 @@ module Kernel
504
504
  private
505
505
 
506
506
  def run(app, **options)
507
- Rack::Handler::CloudflareWorkers.run(app, **options)
507
+ Rack::Handler::Homura.run(app, **options)
508
508
  end
509
509
  end
510
510
 
@@ -950,7 +950,7 @@ end
950
950
  # Phase 6 — HTTP client foundation. Loaded as part of the Cloudflare
951
951
  # Workers adapter so user code can simply `require 'sinatra/base'`
952
952
  # and use Net::HTTP / Cloudflare::HTTP.fetch without an extra require.
953
- require 'cloudflare_workers/http'
953
+ require 'homura/runtime/http'
954
954
 
955
955
  # Phase 9 — Scheduled (Cron Triggers) dispatcher. Installs the JS
956
956
  # `globalThis.__HOMURA_SCHEDULED_DISPATCH__` hook that
@@ -958,11 +958,11 @@ require 'cloudflare_workers/http'
958
958
  # Must be loaded after the Cloudflare::* binding wrappers above
959
959
  # because it constructs D1Database/KVNamespace/R2Bucket instances
960
960
  # inside the dispatcher's per-job env.
961
- require 'cloudflare_workers/scheduled'
961
+ require 'homura/runtime/scheduled'
962
962
 
963
963
  # Phase 10 — Workers AI binding wrapper. Loaded here so any Sinatra
964
964
  # route can call Cloudflare::AI.run(...) without an extra require.
965
- require 'cloudflare_workers/ai'
965
+ require 'homura/runtime/ai'
966
966
 
967
967
  # Phase 11A — HTTP foundations.
968
968
  #
@@ -971,17 +971,17 @@ require 'cloudflare_workers/ai'
971
971
  # `stream` adds `Cloudflare::SSEStream` + `Sinatra::Streaming#sse`
972
972
  # so a route can `sse do |out| ... end` and flush chunks
973
973
  # through a Workers ReadableStream.
974
- require 'cloudflare_workers/multipart'
975
- require 'cloudflare_workers/stream'
974
+ require 'homura/runtime/multipart'
975
+ require 'homura/runtime/stream'
976
976
 
977
977
  # Phase 11B — Cloudflare native bindings (Durable Objects / Cache /
978
978
  # Queues). Each file registers its own globalThis dispatcher hook
979
979
  # where applicable (DO / Queue consumer). Loaded here so user code
980
980
  # just needs `require 'sinatra/base'` — no extra `require` per
981
981
  # binding.
982
- require 'cloudflare_workers/cache'
983
- require 'cloudflare_workers/queue'
984
- require 'cloudflare_workers/email'
985
- require 'cloudflare_workers/durable_object'
982
+ require 'homura/runtime/cache'
983
+ require 'homura/runtime/queue'
984
+ require 'homura/runtime/email'
985
+ require 'homura/runtime/durable_object'
986
986
 
987
- require 'cloudflare_workers/async_registry'
987
+ require 'homura/runtime/async_registry'
@@ -156,7 +156,7 @@ export default {
156
156
  const dispatch = rackDispatch();
157
157
  if (typeof dispatch !== "function") {
158
158
  return new Response(
159
- "homura: Rack dispatcher not installed (Rack::Handler::CloudflareWorkers.run never called)\n",
159
+ "homura: Rack dispatcher not installed (Rack::Handler::Homura.run never called)\n",
160
160
  { status: 500, headers: { "content-type": "text/plain; charset=utf-8" } },
161
161
  );
162
162
  }
@@ -180,7 +180,7 @@ export default {
180
180
  // The Workers runtime invokes this `scheduled` export once per
181
181
  // matching `[triggers] crons` entry in wrangler.toml. We forward
182
182
  // the (event, env, ctx) triple to the Ruby-side dispatcher
183
- // installed by `lib/cloudflare_workers/scheduled.rb`
183
+ // installed by `lib/homura/runtime/scheduled.rb`
184
184
  // (which registers `globalThis.__HOMURA_SCHEDULED_DISPATCH__`).
185
185
  //
186
186
  // The Ruby dispatcher walks every job registered via the
@@ -199,12 +199,12 @@ export default {
199
199
  const dispatch = scheduledDispatch();
200
200
  if (typeof dispatch !== "function") {
201
201
  // No Ruby dispatcher installed — the Opal bundle didn't
202
- // require 'cloudflare_workers/scheduled'. Log loudly so this
202
+ // require 'homura/runtime/scheduled'. Log loudly so this
203
203
  // misconfiguration surfaces instead of silently dropping
204
204
  // every cron firing.
205
205
  try {
206
206
  globalThis.console.error(
207
- "homura: scheduled dispatcher not installed (require 'cloudflare_workers/scheduled' missing)",
207
+ "homura: scheduled dispatcher not installed (require 'homura/runtime/scheduled' missing)",
208
208
  );
209
209
  } catch (e) {
210
210
  // ignore — console may itself be broken in pathological cases
@@ -246,7 +246,7 @@ export default {
246
246
  if (typeof dispatch !== "function") {
247
247
  try {
248
248
  globalThis.console.error(
249
- "homura: queue dispatcher not installed (require 'cloudflare_workers/queue' missing)",
249
+ "homura: queue dispatcher not installed (require 'homura/runtime/queue' missing)",
250
250
  );
251
251
  } catch (e) {}
252
252
  return;
@@ -272,7 +272,7 @@ export default {
272
272
  // must be a named export on this module. We export ONE generic class
273
273
  // (`HomuraCounterDO`) that forwards every `fetch(req)` it receives
274
274
  // to the Ruby-side dispatcher installed by
275
- // `lib/cloudflare_workers/durable_object.rb`
275
+ // `lib/homura/runtime/durable_object.rb`
276
276
  // (`globalThis.__HOMURA_DO_DISPATCH__`).
277
277
  //
278
278
  // The Ruby handler is registered via:
@@ -361,7 +361,7 @@ export class HomuraCounterDO {
361
361
  }
362
362
 
363
363
  // Hibernation API callbacks — routed into Ruby via the hooks
364
- // installed by `lib/cloudflare_workers/durable_object.rb`. Each
364
+ // installed by `lib/homura/runtime/durable_object.rb`. Each
365
365
  // hook is optional on the Ruby side; missing hooks are a no-op.
366
366
  async webSocketMessage(ws, message) {
367
367
  const fn = durableObjectWsMessage();
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.27
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuhiro Homma
@@ -53,21 +53,21 @@ files:
53
53
  - exe/compile-assets
54
54
  - exe/compile-erb
55
55
  - exe/homura-build
56
- - lib/cloudflare_workers.rb
57
- - lib/cloudflare_workers/ai.rb
58
- - lib/cloudflare_workers/async_registry.rb
59
- - lib/cloudflare_workers/auto_await/analyzer.rb
60
- - lib/cloudflare_workers/auto_await/transformer.rb
61
- - lib/cloudflare_workers/build_support.rb
62
- - lib/cloudflare_workers/cache.rb
63
- - lib/cloudflare_workers/durable_object.rb
64
- - lib/cloudflare_workers/email.rb
65
- - lib/cloudflare_workers/http.rb
66
- - lib/cloudflare_workers/multipart.rb
67
- - lib/cloudflare_workers/queue.rb
68
- - lib/cloudflare_workers/scheduled.rb
69
- - lib/cloudflare_workers/stream.rb
70
- - lib/cloudflare_workers/version.rb
56
+ - lib/homura/runtime.rb
57
+ - lib/homura/runtime/ai.rb
58
+ - lib/homura/runtime/async_registry.rb
59
+ - lib/homura/runtime/auto_await/analyzer.rb
60
+ - lib/homura/runtime/auto_await/transformer.rb
61
+ - lib/homura/runtime/build_support.rb
62
+ - lib/homura/runtime/cache.rb
63
+ - lib/homura/runtime/durable_object.rb
64
+ - lib/homura/runtime/email.rb
65
+ - lib/homura/runtime/http.rb
66
+ - lib/homura/runtime/multipart.rb
67
+ - lib/homura/runtime/queue.rb
68
+ - lib/homura/runtime/scheduled.rb
69
+ - lib/homura/runtime/stream.rb
70
+ - lib/homura/runtime/version.rb
71
71
  - lib/homura_vendor_tempfile.rb
72
72
  - lib/homura_vendor_tilt.rb
73
73
  - lib/homura_vendor_zlib.rb
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CloudflareWorkers
4
- VERSION = '0.2.27'
5
- end