glyphs 0.3.0 → 0.4.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: eb4ffc81dcfd96faf6a0f23e3f57780340db27348666e520c7bbc747af04065e
4
- data.tar.gz: 48e331ff55405e3c054fd0464a50a38ccf75df6d3e837e2a0edf3e3a18894de8
3
+ metadata.gz: 83fd5e39450d1ac698d0add8d4344ecbd9001783695ac15f48f7276aba89a05f
4
+ data.tar.gz: a1c570feaf9d4e623958a626d1a5ffe42fc55d0e4347cd659539e00335a8af3d
5
5
  SHA512:
6
- metadata.gz: 382ddd08e2e3cd53ce5164bbb6104bfc46b2c1caf48ac5d39b24e08f3a7594cbd0fa95424793d746c616bc7e4e8621ded6c0af1c5bf4357fa309ded75c49c79a
7
- data.tar.gz: 1205d90f3d975f3a0880e3768d68c0daf12664c98efb01f715296fd1230dd24fb2af4981e74bd689f98ddf3b7b962c29dc7e3e4dd0125024c49944b312ba8995
6
+ metadata.gz: b077d3f979ffcd2a41244c48fa6bba440400f44fb48d6033d35208661bfbfc434b65b22a44ee4548771bcac6ac87a97622e14dd6bb4303768066ae61a272ddb4
7
+ data.tar.gz: a0b9a383c8197cc0079ecea51e3c9879fcb884b12e852aecf6f8a21dd8b0a06e9624bfb753f6a2faf02eec9043c90f4570e2ff40717ed2a648c9b93b52888b62
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # Changelog
2
2
 
3
- ## [0.3.0]
3
+ ## [Unreleased]
4
+
5
+ ### Added
6
+
7
+ - **A non-main Ractor renders icons it has not cached.** A miss there used to
8
+ raise `Ractor::IsolationError` (`@configuration from Icons`), because the
9
+ icons gem reads an unshareable module ivar and parses with Nokogiri, which
10
+ only the main Ractor can run. `Glyphs::MainRactor` now renders the miss on
11
+ the main Ractor through [ractor-dispatch](https://github.com/jhawthorn/ractor-dispatch)
12
+ (Ruby 4.0+, a dependency of Rails 8.2's Active Support) and that Ractor's
13
+ cache keeps the markup, byte for byte the main Ractor's. The missing-icon
14
+ policy runs on the main Ractor too. Without ractor-dispatch the miss raises
15
+ `Glyphs::MainRactor::Unavailable` naming the icon, and `Glyphs.preload_svg`
16
+ still seeds a Ractor's cache. glyphs does not depend on ractor-dispatch: add
17
+ it outside Rails 8.2. Refs zoolutions/phlex-reactive#363
18
+
19
+ ## [0.3.0] - 2026-10-15
4
20
 
5
21
  ### Changed
6
22
 
@@ -136,6 +152,23 @@
136
152
  rather than the primary mechanism. Only literals are harvested, so the scanner
137
153
  never invents a reference.
138
154
 
155
+ ## [0.2.1] - 2026-07-11
156
+
157
+ ### Added
158
+
159
+ - **`glyphs:prune_icons` prunes unused icons for smaller Docker images.**
160
+ `Glyphs::SourceScanner` finds the icons an app references and the task deletes
161
+ every other synced SVG in the Docker build, keeping `config.keep_icons` (new,
162
+ for dynamic or data-driven names) and every `fallback_icons` entry, then
163
+ verifies each kept icon still resolves. Dry-run by default; it deletes only
164
+ with `PRUNE=1 GLYPHS_PRUNE_ICONS=1`. `config.prune_source_globs` adds paths to
165
+ scan. Refs #2
166
+
167
+ ### Changed
168
+
169
+ - **Breaking:** `required_ruby_version` is now `>= 3.4` (CI runs 3.4 and 4.0).
170
+ Refs #2
171
+
139
172
  ## [0.2.0] - 2026-07-07
140
173
 
141
174
  ### Changed
data/README.md CHANGED
@@ -130,11 +130,17 @@ readable on the main Ractor only, which is all an app without Ractors needs; ano
130
130
  object with a `#call` method that `Ractor.shareable?` accepts (frozen, with nothing unshareable inside) or
131
131
  `Ractor.shareable_proc` (Ruby 4.0+).
132
132
 
133
- The icons gem cannot render inside a non-main Ractor today (its configuration is unshareable module
134
- state, and Nokogiri is Ractor-unsafe), so each Ractor's cache starts empty and a miss there raises.
135
- Render on the main Ractor and hand the markup over with `Glyphs.preload_svg`; cache hits then work in that
136
- Ractor for calls without `data:` whose attributes the cache can apply (a `data:` call, or one with an attribute
137
- that renders uncached, still needs the icons gem):
133
+ The icons gem cannot render inside a non-main Ractor (its configuration is unshareable module state, and
134
+ Nokogiri is not marked Ractor-safe), so a miss in one renders on the main Ractor instead, through
135
+ [ractor-dispatch](https://github.com/jhawthorn/ractor-dispatch) (Ruby 4.0+). Rails 8.2 apps have it through
136
+ Active Support; elsewhere, add `gem "ractor-dispatch"`. The markup is the main Ractor's, byte for byte, and
137
+ the calling Ractor's cache keeps it, so each icon crosses once per cache entry; cache hits never leave the
138
+ Ractor. The missing-icon policy runs on the main Ractor too, `on_missing_icon` included. A call with an
139
+ attribute that renders uncached, or any call with `cache_svgs = false`, goes to the main Ractor every time.
140
+
141
+ Without ractor-dispatch, a miss in a non-main Ractor raises `Glyphs::MainRactor::Unavailable`, naming the
142
+ icon. You can still render on the main Ractor and hand the markup over with `Glyphs.preload_svg`; cache hits
143
+ then work in that Ractor for calls without `data:` whose attributes the cache can apply:
138
144
 
139
145
  ```ruby
140
146
  svg = Glyphs.svg_for(name: "house", library: :lucide, variant: nil, attributes: {}) # main Ractor
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glyphs
4
+ # Renders an icon on the main Ractor for a non-main one. The icons gem reads
5
+ # Icons.configuration (an unshareable module ivar) and parses with Nokogiri
6
+ # (a C extension not marked Ractor-safe), so only the main Ractor can run it.
7
+ # ractor-dispatch (Ruby 4.0+, a dependency of Rails 8.2's Active Support)
8
+ # runs the render there and sends the markup back, where the calling Ractor's
9
+ # own cache keeps it: each icon crosses once per Ractor, not once per render.
10
+ module MainRactor
11
+ # Raised in a non-main Ractor that cannot reach the main one.
12
+ class Unavailable < StandardError; end
13
+
14
+ class << self
15
+ # Whether this Ractor runs the icons gem itself: the main Ractor, or any
16
+ # code on an engine without Ractors.
17
+ def current?
18
+ defined?(::Ractor) ? ::Ractor.main? : true
19
+ end
20
+
21
+ # Glyphs' render (missing-icon policy included) of these arguments, run
22
+ # on the main Ractor; an Icons::IconNotFound it raises is raised here.
23
+ def render(**arguments)
24
+ dispatcher = main_dispatcher(arguments)
25
+ shared = ::Ractor.make_shareable(arguments, copy: true) # a shareable block captures only shareable values
26
+ dispatcher.run { Glyphs.__send__(:render_svg, **shared) }
27
+ end
28
+
29
+ private
30
+
31
+ def main_dispatcher(arguments)
32
+ icon = "#{arguments[:library]}/#{arguments[:name]}"
33
+ unless defined?(::Ractor::Port)
34
+ raise Unavailable, "#{icon} isn't cached in this Ractor, and rendering it on the main Ractor " \
35
+ "needs ractor-dispatch, which needs Ruby 4.0+. Seed the cache with Glyphs.preload_svg."
36
+ end
37
+
38
+ require "ractor/dispatch"
39
+ ::Ractor::Dispatch.main
40
+ rescue LoadError
41
+ raise Unavailable, "#{icon} isn't cached in this Ractor, and rendering it on the main Ractor " \
42
+ "needs the ractor-dispatch gem (Rails 8.2 apps have it): add gem \"ractor-dispatch\"."
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glyphs
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/glyphs.rb CHANGED
@@ -120,7 +120,15 @@ module Glyphs
120
120
 
121
121
  private
122
122
 
123
+ # A non-main Ractor cannot run the icons gem, so it renders on the main
124
+ # Ractor (see MainRactor); the missing-icon policy runs there too.
123
125
  def render_svg(name:, library:, variant:, attributes:)
126
+ return MainRactor.render(name:, library:, variant:, attributes:) unless MainRactor.current?
127
+
128
+ resolve_svg(name:, library:, variant:, attributes:)
129
+ end
130
+
131
+ def resolve_svg(name:, library:, variant:, attributes:)
124
132
  build_svg(name:, library:, variant:, attributes:)
125
133
  rescue Icons::IconNotFound => e
126
134
  handle_missing_icon(e, name:, library:, variant:, attributes:)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glyphs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
@@ -77,6 +77,7 @@ files:
77
77
  - lib/glyphs/icon_reference.rb
78
78
  - lib/glyphs/linear_icon.rb
79
79
  - lib/glyphs/lucide_icon.rb
80
+ - lib/glyphs/main_ractor.rb
80
81
  - lib/glyphs/phosphor_icon.rb
81
82
  - lib/glyphs/prune_report.rb
82
83
  - lib/glyphs/prune_runner.rb