bun_bun_bundle 0.3.6 → 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: ea8665deac6a402f47088b8de4ada9f2e1ac120c8f8b79d3ab6861be9f0efacb
4
- data.tar.gz: 4068228abedaa595b1907dac059d4d28f037d3a4bed43bea2efa919e7289c092
3
+ metadata.gz: 192332541b28477a4d791698cb2469d96b6b8ed30243c8edeb5636c7a131360b
4
+ data.tar.gz: 6b5a34372a29e6b53cc0e27b5193db02359f43a508bcbbf451940a438a281b15
5
5
  SHA512:
6
- metadata.gz: a555adeca44e5e838d44f0bd98e948582217baf3cf8d6382b7d7ff004621bb7b7a9efac0184faf82696dea5bfa169a9c650c93664f4c150cdaf7ff553d9cfc78
7
- data.tar.gz: ffc2455cf858ac6ee545dedfcb82546b90ed35a61d1ea52a32f7d96cd54d16c0454df8f0417ec9df127105a3430ba94015f23d69c377ebd24876e49ed87845dd
6
+ metadata.gz: db8d44d6fdbe8e3ca9513250bdfbeb1bb03b38cf23e7bc01e917effe292300f311e46a7e979ef995cab1fb170bc46f93ab4f514519d85bff9bf3f77f454a0cac
7
+ data.tar.gz: e0808d67347e5728e6bc0d76c5cefe313b260f728fe2da44e8519a5c092b3109f050c1bc23d9810db375b9eafe2bc6e53caf9d353ed03ff25133e325050edca1
data/README.md CHANGED
@@ -152,6 +152,15 @@ All tag helpers accept additional HTML attributes:
152
152
  <%= bun_img_tag('images/logo.png', alt: 'My App', class: 'logo') %>
153
153
  ```
154
154
 
155
+ Data and aria attributes can be passed as nested hashes (Rails-style) or with
156
+ underscores (Lucky-style). Underscores are converted to hyphens automatically:
157
+
158
+ ```erb
159
+ <%= bun_js_tag('js/app.js', data: { turbo_track: "reload" }) %>
160
+ <%= bun_js_tag('js/app.js', data_turbo_track: "reload") %>
161
+ <%# Both render: data-turbo-track="reload" %>
162
+ ```
163
+
155
164
  ## CLI
156
165
 
157
166
  Build your assets using the bundled CLI (`bbb` is available as a shorter
@@ -198,8 +207,9 @@ Place a `config/bun.json` in your project root:
198
207
  }
199
208
  ```
200
209
 
201
- All values shown above are defaults. You only need to specify what you want to
202
- override.
210
+ > [!TIP]
211
+ > Creating a `bun.json` file is entirely optional. All values shown above are
212
+ > defaults, you only need to specify what you want to override.
203
213
 
204
214
  ## Plugins
205
215
 
@@ -239,10 +249,12 @@ every file, you can import an entire directory at once:
239
249
  ```
240
250
 
241
251
  This will be expanded into individual `@import` lines for each matching file,
242
- sorted alphabetically.
252
+ sorted alphabetically. A warning is logged if the pattern matches no files.
243
253
 
244
- > [!NOTE]
245
- > A warning is logged if the pattern matches no files.
254
+ > [!WARNING]
255
+ > Always include the file extension in glob patterns (e.g., `**/*.css` instead
256
+ > of `**/*`). Without it, editor temp files like Vim's `~` backups will be
257
+ > picked up by the glob, causing build failures during development.
246
258
 
247
259
  ### `jsGlobs`
248
260
 
@@ -8,7 +8,6 @@ export default {
8
8
  IGNORE_PATTERNS: [
9
9
  /^\d+$/,
10
10
  /^\.#/,
11
- /~$/,
12
11
  /\.swp$/,
13
12
  /\.swo$/,
14
13
  /\.tmp$/,
@@ -22,6 +21,7 @@ export default {
22
21
  dev: false,
23
22
  prod: false,
24
23
  wsClients: new Set(),
24
+ watchTimers: new Map(),
25
25
  plugins: [],
26
26
 
27
27
  flags({dev, prod}) {
@@ -99,12 +99,20 @@ export default {
99
99
  continue
100
100
  }
101
101
 
102
- const result = await Bun.build({
103
- entrypoints: [entryPath],
104
- minify: this.prod,
105
- plugins: this.plugins,
106
- ...options
107
- })
102
+ let result
103
+ try {
104
+ result = await Bun.build({
105
+ entrypoints: [entryPath],
106
+ minify: this.prod,
107
+ plugins: this.plugins,
108
+ ...options
109
+ })
110
+ } catch (err) {
111
+ console.error(` ▸ Failed to build ${entry}`)
112
+ if (err.errors) for (const e of err.errors) console.error(e)
113
+ else console.error(err)
114
+ continue
115
+ }
108
116
 
109
117
  if (!result.success) {
110
118
  console.error(` ▸ Failed to build ${entry}`)
@@ -213,27 +221,41 @@ export default {
213
221
  async watch() {
214
222
  const srcDir = join(this.root, this.config.watchDir || 'app/assets')
215
223
 
216
- watch(srcDir, {recursive: true}, async (event, filename) => {
224
+ watch(srcDir, {recursive: true}, (event, filename) => {
217
225
  if (!filename) return
218
226
 
219
- const normalizedFilename = filename.replace(/\\/g, '/')
227
+ let normalizedFilename = filename.replace(/\\/g, '/')
228
+
229
+ // Vim backup files (e.g. app.css~) signal the original file changed
230
+ if (normalizedFilename.endsWith('~'))
231
+ normalizedFilename = normalizedFilename.slice(0, -1)
232
+
220
233
  const base = basename(normalizedFilename)
221
234
  const ext = extname(base).slice(1)
222
235
 
223
236
  if (this.IGNORE_PATTERNS.some(pattern => pattern.test(base))) return
224
237
 
225
- console.log(` ${normalizedFilename} changed`)
238
+ // Debounce: multiple events for the same file (e.g. actual save + backup)
239
+ if (this.watchTimers.has(normalizedFilename)) return
240
+ this.watchTimers.set(normalizedFilename, setTimeout(() => {
241
+ this.watchTimers.delete(normalizedFilename)
242
+ }, 100))
226
243
 
227
- try {
228
- if (ext === 'css') await this.buildCSS()
229
- else if (['js', 'ts', 'jsx', 'tsx'].includes(ext)) await this.buildJS()
230
- else if (base.includes('.')) await this.copyStaticAssets()
244
+ console.log(` ▸ ${normalizedFilename} changed`)
231
245
 
232
- await this.writeManifest()
233
- this.reload(ext === 'css' ? 'css' : 'full')
234
- } catch (err) {
235
- console.error(' Build error:', err.message)
236
- }
246
+ ;(async () => {
247
+ try {
248
+ if (ext === 'css') await this.buildCSS()
249
+ else if (['js', 'ts', 'jsx', 'tsx'].includes(ext)) await this.buildJS()
250
+ else if (base.includes('.')) await this.copyStaticAssets()
251
+
252
+ await this.writeManifest()
253
+ this.reload(ext === 'css' ? 'css' : 'full')
254
+ } catch (err) {
255
+ console.error(' ✖ Build error:', err.message)
256
+ if (err.errors) for (const e of err.errors) console.error(e)
257
+ }
258
+ })()
237
259
  })
238
260
 
239
261
  console.log('Beginning to watch your project')
@@ -35,7 +35,7 @@ module BunBunBundle
35
35
  def bun_js_tag(source, **options)
36
36
  src = bun_asset(source)
37
37
  attrs = { type: 'text/javascript' }.merge(options).merge(src: src)
38
- _bun_safe(%(<script #{_bun_html_attrs(attrs)}></script>))
38
+ bun_safe(%(<script #{bun_html_attrs(attrs)}></script>))
39
39
  end
40
40
 
41
41
  # Generates a <link> tag for a CSS entry point.
@@ -46,7 +46,7 @@ module BunBunBundle
46
46
  def bun_css_tag(source, **options)
47
47
  href = bun_asset(source)
48
48
  attrs = { type: 'text/css', rel: 'stylesheet' }.merge(options).merge(href: href)
49
- _bun_safe(%(<link #{_bun_html_attrs(attrs)}>))
49
+ bun_safe(%(<link #{bun_html_attrs(attrs)}>))
50
50
  end
51
51
 
52
52
  # Generates an <img> tag for an image asset.
@@ -58,18 +58,30 @@ module BunBunBundle
58
58
  src = bun_asset(source)
59
59
  alt = options.delete(:alt) || File.basename(source, '.*').tr('-_', ' ').capitalize
60
60
  attrs = { alt: alt }.merge(options).merge(src: src)
61
- _bun_safe(%(<img #{_bun_html_attrs(attrs)}>))
61
+ bun_safe(%(<img #{bun_html_attrs(attrs)}>))
62
62
  end
63
63
 
64
64
  private
65
65
 
66
- def _bun_html_attrs(hash)
67
- hash.compact.map do |k, v|
68
- v == true ? k.to_s : %(#{k}="#{_bun_escape_attr(v)}")
66
+ def bun_html_attrs(hash)
67
+ bun_flatten_attrs(hash).compact.map do |k, v|
68
+ k = k.to_s.tr('_', '-')
69
+ v == true ? k : %(#{k}="#{bun_escape_attr(v)}")
69
70
  end.join(' ')
70
71
  end
71
72
 
72
- def _bun_escape_attr(value)
73
+ def bun_flatten_attrs(hash, prefix: nil)
74
+ hash.each_with_object({}) do |(k, v), flat|
75
+ key = prefix ? :"#{prefix}_#{k}" : k
76
+ if v.is_a?(Hash)
77
+ flat.merge!(bun_flatten_attrs(v, prefix: key))
78
+ else
79
+ flat[key] = v
80
+ end
81
+ end
82
+ end
83
+
84
+ def bun_escape_attr(value)
73
85
  value.to_s.gsub('&', '&amp;').gsub('"', '&quot;').gsub('<', '&lt;').gsub('>', '&gt;')
74
86
  end
75
87
  end
@@ -58,7 +58,7 @@ module BunBunBundle
58
58
  })()
59
59
  </script>
60
60
  HTML
61
- _bun_safe(html)
61
+ bun_safe(html)
62
62
  end
63
63
  end
64
64
  end
@@ -5,9 +5,9 @@ module BunBunBundle
5
5
  private
6
6
 
7
7
  if String.method_defined?(:html_safe)
8
- def _bun_safe(html) = html.html_safe
8
+ def bun_safe(html) = html.html_safe
9
9
  else
10
- def _bun_safe(html) = html
10
+ def bun_safe(html) = html
11
11
  end
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BunBunBundle
4
- VERSION = '0.3.6'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bun_bun_bundle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wout Fierens