skybolt 3.2.0 → 3.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/README.md +11 -22
- data/lib/skybolt/renderer.rb +65 -2
- data/lib/skybolt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9380c0cdfa32e9c73ef10d8170f6c5f1d40803c6677c428eb3f62c28fe31b5ff
|
|
4
|
+
data.tar.gz: fe4d5f31d47a79d6f55bfe27c16f2977cd6c25013ada9e42ab29b3cb008e7be2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c11d0a7a4602a1a958774c02948e76cbe8a229afe6bf95caa3196d25416cd291b6f6fdae9a189730ebc86012c9fe8a5edbfb7e82b06c04853ddb124c482fa310
|
|
7
|
+
data.tar.gz: ae9a6729144cd991aaf06acaa58a7c374956f07648f5e45f5086ccf661c18890cecf6508c327d6acec8e49ac33e50f542718f0936f1aeb61eccd9cc2efa83d40
|
data/README.md
CHANGED
|
@@ -73,15 +73,24 @@ sb = Skybolt::Renderer.new(
|
|
|
73
73
|
)
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
### `css(entry) -> String`
|
|
76
|
+
### `css(entry, async: false) -> String`
|
|
77
77
|
|
|
78
78
|
Render CSS asset.
|
|
79
79
|
|
|
80
80
|
- First visit: Inlines CSS with caching attributes
|
|
81
81
|
- Repeat visit: Outputs `<link>` tag (Service Worker serves from cache)
|
|
82
82
|
|
|
83
|
+
When `async:` is `true`, CSS loads non-blocking:
|
|
84
|
+
|
|
85
|
+
- First visit: Uses `media="print"` trick, swaps to `all` on load
|
|
86
|
+
- Repeat visit: Uses `<link rel="preload">` with `onload`
|
|
87
|
+
|
|
83
88
|
```ruby
|
|
84
|
-
|
|
89
|
+
# Blocking (default) - for critical CSS
|
|
90
|
+
sb.css("src/css/critical.css")
|
|
91
|
+
|
|
92
|
+
# Non-blocking - for non-critical CSS
|
|
93
|
+
sb.css("src/css/main.css", async: true)
|
|
85
94
|
```
|
|
86
95
|
|
|
87
96
|
### `script(entry, is_module: true) -> String`
|
|
@@ -262,26 +271,6 @@ end
|
|
|
262
271
|
- Ruby 3.0+
|
|
263
272
|
- Vite with `@skybolt/vite-plugin`
|
|
264
273
|
|
|
265
|
-
## Publishing
|
|
266
|
-
|
|
267
|
-
This package is maintained in the [Skybolt monorepo](https://github.com/JensRoland/skybolt) and automatically synced to [skybolt-ruby](https://github.com/JensRoland/skybolt-ruby).
|
|
268
|
-
|
|
269
|
-
To publish a new version, run one command from the `packages/ruby` directory:
|
|
270
|
-
|
|
271
|
-
```sh
|
|
272
|
-
./scripts/release.sh patch # 3.1.0 → 3.1.1
|
|
273
|
-
./scripts/release.sh minor # 3.1.0 → 3.2.0
|
|
274
|
-
./scripts/release.sh major # 3.1.0 → 4.0.0
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
This automatically:
|
|
278
|
-
|
|
279
|
-
1. Bumps the version in `VERSION`, `skybolt.gemspec`, and `lib/skybolt/version.rb`
|
|
280
|
-
2. Commits and pushes to the monorepo
|
|
281
|
-
3. Sync workflow pushes changes to the split repo
|
|
282
|
-
4. `tag-version.yml` in the split repo creates the `v*` tag
|
|
283
|
-
5. `publish.yml` builds and publishes to RubyGems using trusted publishing (OIDC)
|
|
284
|
-
|
|
285
274
|
## License
|
|
286
275
|
|
|
287
276
|
MIT
|
data/lib/skybolt/renderer.rb
CHANGED
|
@@ -26,8 +26,9 @@ module Skybolt
|
|
|
26
26
|
# On repeat visit: outputs <link> tag (Service Worker serves from cache)
|
|
27
27
|
#
|
|
28
28
|
# @param entry [String] Source file path (e.g., 'src/css/main.css')
|
|
29
|
+
# @param async [Boolean] Load CSS asynchronously (non-render-blocking)
|
|
29
30
|
# @return [String] HTML string
|
|
30
|
-
def css(entry)
|
|
31
|
+
def css(entry, async: false)
|
|
31
32
|
asset = @map.dig("assets", entry)
|
|
32
33
|
return comment("Skybolt: asset not found: #{entry}") if asset.nil?
|
|
33
34
|
|
|
@@ -35,10 +36,20 @@ module Skybolt
|
|
|
35
36
|
|
|
36
37
|
# Client has current version - external link (SW serves from cache)
|
|
37
38
|
if cached?(entry, asset["hash"])
|
|
39
|
+
if async
|
|
40
|
+
# Preload + onload swap for non-blocking load
|
|
41
|
+
return %(<link rel="preload" href="#{esc(url)}" as="style" onload="this.rel='stylesheet'">) +
|
|
42
|
+
%(<noscript><link rel="stylesheet" href="#{esc(url)}"></noscript>)
|
|
43
|
+
end
|
|
38
44
|
return %(<link rel="stylesheet" href="#{esc(url)}">)
|
|
39
45
|
end
|
|
40
46
|
|
|
41
47
|
# First visit - inline with cache attributes
|
|
48
|
+
if async
|
|
49
|
+
# media="print" trick: browser parses but doesn't apply until onload swaps to "all"
|
|
50
|
+
return %(<style media="print" onload="this.media='all'" sb-asset="#{esc(entry)}:#{esc(asset["hash"])}" sb-url="#{esc(url)}">#{asset["content"]}</style>)
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
%(<style sb-asset="#{esc(entry)}:#{esc(asset["hash"])}" sb-url="#{esc(url)}">#{asset["content"]}</style>)
|
|
43
54
|
end
|
|
44
55
|
|
|
@@ -99,12 +110,29 @@ module Skybolt
|
|
|
99
110
|
# Call this once in <head> before other Skybolt assets.
|
|
100
111
|
# Outputs config meta tag and client script.
|
|
101
112
|
#
|
|
113
|
+
# On first visit (or cache miss), the launcher is inlined with sb-asset
|
|
114
|
+
# and sb-url attributes so the client can cache itself.
|
|
115
|
+
#
|
|
116
|
+
# On repeat visits (cache hit), returns an external script tag. The Service
|
|
117
|
+
# Worker will serve the launcher from cache (~5ms response time).
|
|
118
|
+
#
|
|
102
119
|
# @return [String] HTML string
|
|
103
120
|
def launch_script
|
|
104
121
|
sw_path = @map.dig("serviceWorker", "path") || "/skybolt-sw.js"
|
|
105
122
|
config = { swPath: sw_path }.to_json
|
|
106
123
|
|
|
107
|
-
|
|
124
|
+
launcher = @map["launcher"]
|
|
125
|
+
url = resolve_url(launcher["url"])
|
|
126
|
+
|
|
127
|
+
meta = %(<meta name="skybolt-config" content="#{esc(config)}">\n)
|
|
128
|
+
|
|
129
|
+
if cached?("skybolt-launcher", launcher["hash"])
|
|
130
|
+
# Repeat visit - external script (SW serves from cache)
|
|
131
|
+
return %(#{meta}<script type="module" src="#{esc(url)}"></script>)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# First visit - inline with sb-asset and sb-url for self-caching
|
|
135
|
+
%(#{meta}<script type="module" sb-asset="skybolt-launcher:#{esc(launcher["hash"])}" sb-url="#{esc(url)}">#{launcher["content"]}</script>)
|
|
108
136
|
end
|
|
109
137
|
|
|
110
138
|
# Get URL for an asset (for manual use cases).
|
|
@@ -124,6 +152,41 @@ module Skybolt
|
|
|
124
152
|
@map.dig("assets", entry, "hash")
|
|
125
153
|
end
|
|
126
154
|
|
|
155
|
+
# Check if an asset URL is currently cached by the client.
|
|
156
|
+
#
|
|
157
|
+
# This is useful for Chain Lightning integration where we need to check
|
|
158
|
+
# cache status by URL rather than source path.
|
|
159
|
+
#
|
|
160
|
+
# @param url [String] The asset URL (e.g., '/assets/main-Abc123.css')
|
|
161
|
+
# @return [Boolean] True if the asset is cached
|
|
162
|
+
def cached_url?(url)
|
|
163
|
+
# Build URL to entry mapping if not already built
|
|
164
|
+
@url_to_entry ||= begin
|
|
165
|
+
mapping = {}
|
|
166
|
+
(@map["assets"] || {}).each do |entry, asset|
|
|
167
|
+
mapping[asset["url"]] = { "entry" => entry, "hash" => asset["hash"] }
|
|
168
|
+
end
|
|
169
|
+
mapping
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
info = @url_to_entry[url]
|
|
173
|
+
return false if info.nil?
|
|
174
|
+
|
|
175
|
+
cached?(info["entry"], info["hash"])
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Check if client has a specific entry:hash pair cached.
|
|
179
|
+
#
|
|
180
|
+
# Useful for external integrations (like Chain Lightning) that manage
|
|
181
|
+
# their own assets outside of Skybolt's render-map.
|
|
182
|
+
#
|
|
183
|
+
# @param entry [String] The entry name (e.g., 'chain-lightning' or 'cl-manifest')
|
|
184
|
+
# @param hash [String] The expected hash value
|
|
185
|
+
# @return [Boolean] True if the entry:hash pair is in the client's cache
|
|
186
|
+
def cached_entry?(entry, hash)
|
|
187
|
+
cached?(entry, hash)
|
|
188
|
+
end
|
|
189
|
+
|
|
127
190
|
private
|
|
128
191
|
|
|
129
192
|
def resolve_url(url)
|
data/lib/skybolt/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: skybolt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jens Roland
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Reads the render-map.json generated by @skybolt/vite-plugin and outputs
|
|
14
14
|
optimized HTML tags with intelligent caching via Service Workers.
|