proscenium 0.5.1-x86_64-darwin → 0.7.0-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +128 -92
  3. data/bin/proscenium +0 -0
  4. data/bin/proscenium.h +109 -0
  5. data/config/routes.rb +0 -3
  6. data/lib/proscenium/css_module/class_names_resolver.rb +66 -0
  7. data/lib/proscenium/css_module/resolver.rb +76 -0
  8. data/lib/proscenium/css_module.rb +18 -39
  9. data/lib/proscenium/esbuild/golib.rb +97 -0
  10. data/lib/proscenium/esbuild.rb +32 -0
  11. data/lib/proscenium/helper.rb +0 -23
  12. data/lib/proscenium/log_subscriber.rb +26 -0
  13. data/lib/proscenium/middleware/base.rb +28 -36
  14. data/lib/proscenium/middleware/esbuild.rb +18 -44
  15. data/lib/proscenium/middleware/url.rb +1 -6
  16. data/lib/proscenium/middleware.rb +12 -16
  17. data/lib/proscenium/phlex/component_concerns.rb +27 -0
  18. data/lib/proscenium/phlex/page.rb +62 -0
  19. data/lib/proscenium/phlex/react_component.rb +52 -8
  20. data/lib/proscenium/phlex/resolve_css_modules.rb +67 -0
  21. data/lib/proscenium/phlex.rb +34 -33
  22. data/lib/proscenium/railtie.rb +41 -67
  23. data/lib/proscenium/side_load/ensure_loaded.rb +25 -0
  24. data/lib/proscenium/side_load/helper.rb +25 -0
  25. data/lib/proscenium/side_load/monkey.rb +48 -0
  26. data/lib/proscenium/side_load.rb +58 -52
  27. data/lib/proscenium/version.rb +1 -1
  28. data/lib/proscenium/view_component/react_component.rb +14 -0
  29. data/lib/proscenium/view_component.rb +28 -18
  30. data/lib/proscenium.rb +79 -2
  31. metadata +35 -72
  32. data/app/channels/proscenium/connection.rb +0 -13
  33. data/app/channels/proscenium/reload_channel.rb +0 -9
  34. data/bin/esbuild +0 -0
  35. data/bin/lightningcss +0 -0
  36. data/lib/proscenium/compiler.js +0 -84
  37. data/lib/proscenium/compilers/esbuild/argument_error.js +0 -24
  38. data/lib/proscenium/compilers/esbuild/compile_error.js +0 -148
  39. data/lib/proscenium/compilers/esbuild/css/postcss.js +0 -67
  40. data/lib/proscenium/compilers/esbuild/css_plugin.js +0 -172
  41. data/lib/proscenium/compilers/esbuild/env_plugin.js +0 -46
  42. data/lib/proscenium/compilers/esbuild/http_bundle_plugin.js +0 -53
  43. data/lib/proscenium/compilers/esbuild/import_map.js +0 -59
  44. data/lib/proscenium/compilers/esbuild/resolve_plugin.js +0 -205
  45. data/lib/proscenium/compilers/esbuild/setup_plugin.js +0 -45
  46. data/lib/proscenium/compilers/esbuild/solidjs_plugin.js +0 -24
  47. data/lib/proscenium/compilers/esbuild.bench.js +0 -14
  48. data/lib/proscenium/compilers/esbuild.js +0 -179
  49. data/lib/proscenium/link_to_helper.rb +0 -40
  50. data/lib/proscenium/middleware/lightningcss.rb +0 -64
  51. data/lib/proscenium/middleware/outside_root.rb +0 -26
  52. data/lib/proscenium/middleware/runtime.rb +0 -22
  53. data/lib/proscenium/middleware/static.rb +0 -14
  54. data/lib/proscenium/phlex/component.rb +0 -9
  55. data/lib/proscenium/precompile.rb +0 -31
  56. data/lib/proscenium/runtime/auto_reload.js +0 -40
  57. data/lib/proscenium/runtime/react_shim/index.js +0 -1
  58. data/lib/proscenium/runtime/react_shim/package.json +0 -5
  59. data/lib/proscenium/utils.js +0 -8
  60. data/lib/tasks/assets.rake +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1757ba839494187ad2631eb1a4eb44e0c6a6fc32f83ddd982d847cee00d27a21
4
- data.tar.gz: 2392bc62ce31d8cd9edfe6f4693cecf8873dd58edc0989ea59e64947e3893a91
3
+ metadata.gz: 1fae3116f404a930293a5080e9a7dc859444b6407b443d64c0931a4825aa68e1
4
+ data.tar.gz: 5639c06def32c33f46254a6fdfeb638711c9d2e6f1c61612be4860c5f0641363
5
5
  SHA512:
6
- metadata.gz: 55fe0c8adc0c4bd167791ee31540d7fd5c8cc6f8ff7755c31702369c409bd57da651c2f2b4af1c831447e1cf892aeed5ac70976e7a6841449a27ef326767d2ee
7
- data.tar.gz: cb7dc641a04dba9648af26a0e183bed11d6428a28d815cb0f5243cc298e843b822b532c45de8ff91d9ee7f33849365b4e6106fdf7ac1b4fc590593374e67718b
6
+ metadata.gz: f9196d6c5e625a4346493ea0cbd75933a8bfd0c01a4d4a678388ed7f57b991c22c406be56e10df9f73dfedfb6bd98608773a826a2629b3e1a7b0f5ff8ee3d18e
7
+ data.tar.gz: c3b4184767b68621aff62bda0c5ffc9c1f1cfefb7469825387345edb6d17e2cfd32ddca5f4f671e99008b511503514f0e2652c756c3bb96e435bbffe9601a30d
data/README.md CHANGED
@@ -1,91 +1,87 @@
1
1
  # Proscenium - Modern Client-Side Tooling for Rails
2
2
 
3
3
  Proscenium treats your client-side code as first class citizens of your Rails app, and assumes a
4
- "fast by default" internet. It compiles your JS, JSX and CSS in real time, and on demand, with no
5
- configuration at all!
4
+ "fast by default" internet. It bundles your JS, JSX and CSS in real time, on demand, and with zero
5
+ configuration.
6
6
 
7
7
  - Zero configuration.
8
- - NO JavaScript rumtime needed - just the browser!
9
- - Real-time compilation.
8
+ - Fast real-time bundling, tree-shaking and minification.
9
+ - NO JavaScript runtime - just the browser!
10
+ - Deep integration with Rails.
10
11
  - No additional process or server - Just run Rails!
11
- - Serve assets from anywhere within your Rails root (/app, /config, /lib).
12
+ - Serve assets from anywhere within your Rails root (/app, /config, /lib, etc.).
12
13
  - Automatically side load JS/CSS for your layouts and views.
13
- - Import JS(X) and CSS from node_modules, URL, local (relative, absolute).
14
- - Optional bundling of JS(X) and CSS.
15
- - Import Map support for JS and CSS.
14
+ - Import JS(X), TS(X) and CSS from NPM, URL, and locally.
15
+ - Support for JSX.
16
+ - Server-side import map support.
16
17
  - CSS Modules.
17
- - CSS Custom Media Queries.
18
18
  - CSS mixins.
19
- - Minification.
20
- - Auto reload after changes (development only).
19
+ - Source maps.
20
+ - Phlex and ViewComponent integration.
21
21
 
22
- ## !! EXPERIMENTAL SOFTWARE !!
22
+ ## ⚠️ WORK IN PROGRESS ⚠️
23
23
 
24
- While my goal is to use Proscenium in production, I strongly recommended that you **DO NOT** use
25
- this in production apps! Right now, this is a play thing, and should only be used for
26
- development/testing.
24
+ While my goal is to use Proscenium in production, I recommended that you **DO NOT** use Proscenium in production just yet! It has only been run for local development, and requires several improvements for optimal production use.
27
25
 
28
26
  ## Installation
29
27
 
30
- Add this line to your application's Gemfile, and you're good to go:
28
+ Add this line to your Rails application's Gemfile, and you're good to go:
31
29
 
32
30
  ```ruby
33
31
  gem 'proscenium'
34
32
  ```
35
33
 
36
- ## Frontend Code Anywhere!
34
+ Please note that Proscenium is designed solely for use with Rails, so will not work - at least out of the box - anywhere else.
37
35
 
38
- Proscenium believes that your frontend code is just as important as your backend code, and is not an
39
- afterthought - they should be first class citizens of your Rails app. So instead of throwing all
40
- your JS and CSS into a "app/assets" directory, put them wherever you want!
36
+ ## Client-Side Code Anywhere
41
37
 
42
- For example, if you have JS that is used by your `UsersController#index`, then put it in
43
- `app/views/users/index.js`. Or if you have some CSS that is used by your entire application, put it
44
- in `app/views/layouts/application.css`. Maybe you have a few JS utility functions, so put them in
45
- `lib/utils.js`.
38
+ Proscenium believes that your frontend code is just as important as your backend code, and is not an afterthought - they should be first class citizens of your Rails app. So instead of having to throw all your JS and CSS into a "app/assets" directory, and then requiring a separate process to compile or bundle, just put them wherever you want within your app, and just run Rails!
46
39
 
47
- Simply create your JS(X) and CSS anywhere you want, and they will be served by your Rails app.
40
+ For example, if you have some JS that is required by your `app/views/users/index.html.erb` view, just create a JS file alongside it at `app/views/users/index.js`. Or if you have some CSS that is used by your entire application, put it in `app/views/layouts/application.css` and load it alongside your layout. Maybe you have a few JS utility functions, so put them in `lib/utils.js`.
41
+
42
+ Simply put your JS(X) and CSS anywhere you want, and they will be served by your Rails app from the location where you placed them.
48
43
 
49
44
  Using the examples above...
50
45
 
51
46
  - `app/views/users/index.js` => `https://yourapp.com/app/views/users/index.js`
52
47
  - `app/views/layouts/application.css` => `https://yourapp.com/app/views/layouts/application.css`
53
48
  - `lib/utils.js` => `https://yourapp.com/lib/utils.js`
49
+ - `app/components/menu_component.jsx` => `https://yourapp.com/app/components/menu_component.jsx`
54
50
  - `config/properties.css` => `https://yourapp.com/config/properties.css`
55
51
 
56
52
  ## Importing
57
53
 
58
- Proscenium supports importing JS and CSS from `node_modules`, URL, and local (relative, absolute).
54
+ Proscenium supports importing JS, JSX, TS and CSS from NPM, by URL, your local app, and even from Ruby Gems.
55
+
56
+ Imported files are bundled together in real time. So no build step or pre-compilation is needed.
59
57
 
60
- Imports are assumed to be JS files, so there is no need to specify the file extesnion in such cases.
61
- But you can if you like. All other file types must be specified using their full file name and
62
- extension.
58
+ Imports are assumed to be JS files, so there is no need to specify the file extesnion in such cases. But you can if you like. All other file types must be specified using their full file name and extension.
63
59
 
64
60
  ### URL Imports
65
61
 
66
- Any import beginning with `http://` or `https://` will be fetched from the URL provided:
62
+ Any import beginning with `http://` or `https://` will be fetched from the URL provided. For example:
67
63
 
68
64
  ```js
69
- import React from 'https://esm.sh/react`
65
+ import React from 'https://esm.sh/react'
70
66
  ```
71
67
 
72
68
  ```css
73
69
  @import 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css';
74
70
  ```
75
71
 
72
+ URL imports are cached, so that each import is only fetched once per server restart.
73
+
76
74
  ### Import from NPM (`node_modules`)
77
75
 
78
- Bare imports (imports not beginning with `./`, `/`, `https://`, `http://`) are fully supported, and
79
- will use your package manager of choice (eg, NPM, Yarn, pnpm):
76
+ Bare imports (imports not beginning with `./`, `/`, `https://`, `http://`) are fully supported, and will use your package manager of choice (eg, NPM, Yarn, pnpm) via the `package.json` file:
80
77
 
81
78
  ```js
82
- import React from 'react`
79
+ import React from 'react'
83
80
  ```
84
81
 
85
82
  ### Local Imports
86
83
 
87
- And of course you can import your own code, using relative or absolute paths (file extension is
88
- optional):
84
+ And of course you can import your own code, using relative or absolute paths (file extension is optional):
89
85
 
90
86
  ```js /app/views/layouts/application.js
91
87
  import utils from '/lib/utils'
@@ -95,29 +91,11 @@ import utils from '/lib/utils'
95
91
  import constants from './constants'
96
92
  ```
97
93
 
98
- ## Bundling
99
-
100
- Proscenium does not do any bundling, as we believe that **the web is now fast by default**. So we
101
- let you decide if and when to bundle your code using query parameters in your JS and CSS imports.
102
-
103
- ```js
104
- import doStuff from 'stuff?bundle'
105
- doStuff()
106
- ```
107
-
108
- Bundling a URL import is not supported, as the URL itself may also support query parameters,
109
- resulting in conflicts. For example, esm.sh also supports a `?bundle` param, bundling a module's
110
- dependencies into a single file. Instead, you should install the module locally using your favourite
111
- package manager.
94
+ ## Import Map [WIP]
112
95
 
113
- Note that `?bundle` will only bundle that exact path. It will not bundle any descendant imports. You
114
- can bundle all imports within a file by using the `?bundle-all` query string. Use this with caution,
115
- as you could end up swallowing everything, resulting in a very large file.
96
+ [Import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) for both JS and CSS is supported out of the box, and works with no regard to the browser being used. This is because the import map is parsed and resolved by Proscenium on the server. If you are not familiar with import maps, think of it as a way to define aliases.
116
97
 
117
- ## Import Map
118
-
119
- Import map for both JS and CSS is supported out of the box, and works with no regard to the browser
120
- version being used. Just create `config/import_map.json`:
98
+ Just create `config/import_map.json` and specify the imports you want to use. For example:
121
99
 
122
100
  ```json
123
101
  {
@@ -145,9 +123,7 @@ and for CSS...
145
123
  @import '@radix-ui/colors/blue.css';
146
124
  ```
147
125
 
148
- You can instead write your import map in Javascript instead of JSON. So instead of
149
- `config/import_map.json`, create `config/import_map.js`, and define an anonymous function. This
150
- function accepts a single `environment` argument.
126
+ You can also write your import map in Javascript instead of JSON. So instead of `config/import_map.json`, create `config/import_map.js`, and define an anonymous function. This function accepts a single `environment` argument.
151
127
 
152
128
  ```js
153
129
  env => ({
@@ -188,6 +164,8 @@ to `false`.
188
164
 
189
165
  ## CSS Modules
190
166
 
167
+ Proscenium implements a subset of [CSS Modules](https://github.com/css-modules/css-modules). It supports the `:local` and `:global` keywords, but not the `composes` property. It is recommended that you use mixins instead of `composes`, as they work everywhere.
168
+
191
169
  Give any CSS file a `.module.css` extension, and Proscenium will load it as a CSS Module...
192
170
 
193
171
  ```css
@@ -196,7 +174,7 @@ Give any CSS file a `.module.css` extension, and Proscenium will load it as a CS
196
174
  }
197
175
  ```
198
176
 
199
- The above produces:
177
+ The above input produces:
200
178
 
201
179
  ```css
202
180
  .header5564cdbb {
@@ -204,63 +182,104 @@ The above produces:
204
182
  }
205
183
  ```
206
184
 
207
- Importing a CSS file from JS will automatically append the stylesheet to the document's head. The
208
- results of the import will be an object of CSS modules.
185
+ Importing a CSS file from JS will automatically append the stylesheet to the document's head. And the results of the import will be an object of CSS class to module names.
209
186
 
210
187
  ```js
211
188
  import styles from './styles.module.css'
189
+ // styles == { header: 'header5564cdbb' }
212
190
  ```
213
191
 
214
- ## Auto Reload
192
+ It is important to note that the exported object of CSS module names is actually a Proxy object. So destructuring the object will not work. Instead, you must access the properties directly.
215
193
 
216
- To aid fast development, Proscenium comes with an auto reload feature that will automatically reload
217
- the page when any files changes. It is enabled by default in development, and requires that you
218
- mount the Proscenium Railtie into your `config/routes.rb` file:
194
+ Also, importing a CSS module from another CSS module will result in the same digest string for all classes.
219
195
 
220
- ```ruby
221
- mount Proscenium::Railtie, at: '/proscenium' if Rails.env.development?
222
- ```
196
+ ## CSS Mixins
223
197
 
224
- Changes to CSS/JS(X) files in your `app` and `lib` directories will cause the page to reload.
198
+ Proscenium provides functionality for including or "mixing in" onr or more CSS classes into another. This is similar to the `composes` property of CSS Modules, but works everywhere, and is not limited to CSS Modules.
225
199
 
226
- NOTE: that this is hot module reloading (HMR) - a full page reload is triggered.
200
+ CSS mixins are supported using the `@define-mixin` and `@mixin` at-rules.
227
201
 
228
- You can disable auto reload by setting the `config.proscenium.auto_reload` config option to false.
202
+ A mixin is defined using the `@define-mixin` at-rule. Pass it a name, which should adhere to class name semantics, and declare your rules:
229
203
 
230
- ## CSS Custom Media Queries
204
+ ```css
205
+ // /lib/mixins.css
206
+ @define-mixin bigText {
207
+ font-size: 50px;
208
+ }
209
+ ```
231
210
 
232
- Proscenium supports [custom media queries](https://css-tricks.com/can-we-have-custom-media-queries-please/) as per the [spec](https://www.w3.org/TR/mediaqueries-5/#custom-mq). However, because of the way they are parsed, they cannot be imported using `@import`. So if you define your custom media queries in `/config/custom_media_queries.css`, Proscenium will automatically inject them into your CSS, so you can use them anywhere.
211
+ Use a mixin using the `@mixin` at-rule. Pass it the name of the mixin you want to use, and the url where the mixin is declared. The url is used to resolve the mixin, and can be relative, absolute, a URL, or even from an NPM packacge.
233
212
 
234
- ## CSS Mixins
213
+ ```css
214
+ // /app/views/layouts/application.css
215
+ p {
216
+ @mixin bigText from url('/lib/mixins.css');
217
+ color: red;
218
+ }
219
+ ```
235
220
 
236
- CSS mixins are supported using the `@mixin` at-rule. Simply define your mixins in any number of files ending in `.mixin.css`, and using the `@define-mixin` at-rule...
221
+ The above produce this output:
237
222
 
238
223
  ```css
239
- // /lib/text.mixin.css
240
- @define-mixin bigText {
224
+ p {
241
225
  font-size: 50px;
226
+ color: red;
242
227
  }
243
228
  ```
244
229
 
230
+ Mixins can be declared in any CSS file. They do not need to be declared in the same file as where they are used. however, if you declare and use a mixin in the same file, you don't need to specify the URL of where the mixin is declared.
231
+
245
232
  ```css
246
- // /app/views/layouts/application.css
233
+ @define-mixin bigText {
234
+ font-size: 50px;
235
+ }
236
+
247
237
  p {
248
238
  @mixin bigText;
249
239
  color: red;
250
240
  }
251
241
  ```
252
242
 
253
- ## Cache Busting
243
+ CSS modules and Mixins works perfectly together. You can include a mixin in a CSS module.
244
+
245
+ ## Importing SVG from JS(X)
246
+
247
+ Importing SVG from JS(X) will bundle the SVG source code. Additionally, if importing from JSX, the SVG source code will be rendered as a JSX component.
248
+
249
+ ## Environment Variables
250
+
251
+ Import any environment variables into your JS(X) code.
252
+
253
+ ```js
254
+ import RAILS_ENV from '@proscenium/env/RAILS_ENV'
255
+ ```
256
+
257
+ You can only access environment variables that are explicitly named. It will export `undefined` if the env variable does not exist.
258
+
259
+ ## Importing i18n
260
+
261
+ Basic support is provided for importing your Rails locale files from `config/locales/*.yml`, exporting them as JSON.
262
+
263
+ ```js
264
+ import translations from '@proscenium/i18n'
265
+ // translations.en.*
266
+ ```
254
267
 
255
- By default, all assets are not cached by the browser. But if in production, you populate the
256
- `REVISION` env variable, all CSS and JS URL's will be appended with its value as a query string, and
257
- the `Cache-Control` response header will be set to `public` and a max-age of 30 days.
268
+ ## Phlex Support
269
+
270
+ *docs needed*
271
+
272
+ ## ViewComponent Support
273
+
274
+ *docs needed*
275
+
276
+ ## Cache Busting [*COMING SOON*]
277
+
278
+ By default, all assets are not cached by the browser. But if in production, you populate the `REVISION` env variable, all CSS and JS URL's will be appended with its value as a query string, and the `Cache-Control` response header will be set to `public` and a max-age of 30 days.
258
279
 
259
280
  For example, if you set `REVISION=v1`, URL's will be appended with `?v1`: `/my/imported/file.js?v1`.
260
281
 
261
- It is assumed that the `REVISION` env var will be unique between deploys. If it isn't, then assets
262
- will continue to be cached as the same version between deploys. I recommend you assign a version
263
- number or to use the Git commit hash of the deploy. Just make sure it is unique for each deploy.
282
+ It is assumed that the `REVISION` env var will be unique between deploys. If it isn't, then assets will continue to be cached as the same version between deploys. I recommend you assign a version number or to use the Git commit hash of the deploy. Just make sure it is unique for each deploy.
264
283
 
265
284
  You can set the `cache_query_string` config option directly to define any query string you wish:
266
285
 
@@ -268,18 +287,29 @@ You can set the `cache_query_string` config option directly to define any query
268
287
  Rails.application.config.proscenium.cache_query_string = 'my-cache-busting-version-string'
269
288
  ```
270
289
 
271
- The cache is set with a `max-age` of 30 days. You can customise this with the `cache_max_age` config
272
- option:
290
+ The cache is set with a `max-age` of 30 days. You can customise this with the `cache_max_age` config option:
273
291
 
274
292
  ```ruby
275
293
  Rails.application.config.proscenium.cache_max_age = 12.months.to_i
276
294
  ```
277
295
 
278
- ## How It Works
296
+ ## Include Paths
297
+
298
+ By default, Proscenium will serve files ending with any of these extension: `js,mjs,css,jsx`, and only from `config`, `app/views`, `lib` and `node_modules` directories.
279
299
 
280
- Proscenium provides a Rails middleware that proxies requests for your frontend code. By default, it will simply search for a file of the same name in your Rails root. For example, a request for '/app/views/layouts/application.js' or '/lib/hooks.js' will return that exact file relative to your Rails root.
300
+ However, you can customise these paths with the `include_path` config option...
281
301
 
282
- This allows your frontend code to become first class citizens of you Rails application.
302
+ ```ruby
303
+ Rails.application.config.proscenium.include_paths << 'app/components'
304
+ ```
305
+
306
+ ## rjs is back!
307
+
308
+ Proscenium brings back RJS! Any path ending in .rjs will be served from your Rails app. This allows you to import server rendered javascript.
309
+
310
+ ## Serving from Ruby Gem
311
+
312
+ *docs needed*
283
313
 
284
314
  ## Development
285
315
 
@@ -287,6 +317,12 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
287
317
 
288
318
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
289
319
 
320
+ ### Running Go benchmarks
321
+
322
+ ```bash
323
+ go test ./internal/builder -bench=. -run="^$" -count=10 -benchmem
324
+ ```
325
+
290
326
  ## Contributing
291
327
 
292
328
  Bug reports and pull requests are welcome on GitHub at https://github.com/joelmoss/proscenium. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/joelmoss/proscenium/blob/master/CODE_OF_CONDUCT.md).
data/bin/proscenium ADDED
Binary file
data/bin/proscenium.h ADDED
@@ -0,0 +1,109 @@
1
+ /* Code generated by cmd/cgo; DO NOT EDIT. */
2
+
3
+ /* package command-line-arguments */
4
+
5
+
6
+ #line 1 "cgo-builtin-export-prolog"
7
+
8
+ #include <stddef.h>
9
+
10
+ #ifndef GO_CGO_EXPORT_PROLOGUE_H
11
+ #define GO_CGO_EXPORT_PROLOGUE_H
12
+
13
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
14
+ typedef struct { const char *p; ptrdiff_t n; } _GoString_;
15
+ #endif
16
+
17
+ #endif
18
+
19
+ /* Start of preamble from import "C" comments. */
20
+
21
+
22
+ #line 3 "main.go"
23
+
24
+ struct Result {
25
+ int success;
26
+ char* response;
27
+ };
28
+
29
+ #line 1 "cgo-generated-wrapper"
30
+
31
+
32
+ /* End of preamble from import "C" comments. */
33
+
34
+
35
+ /* Start of boilerplate cgo prologue. */
36
+ #line 1 "cgo-gcc-export-header-prolog"
37
+
38
+ #ifndef GO_CGO_PROLOGUE_H
39
+ #define GO_CGO_PROLOGUE_H
40
+
41
+ typedef signed char GoInt8;
42
+ typedef unsigned char GoUint8;
43
+ typedef short GoInt16;
44
+ typedef unsigned short GoUint16;
45
+ typedef int GoInt32;
46
+ typedef unsigned int GoUint32;
47
+ typedef long long GoInt64;
48
+ typedef unsigned long long GoUint64;
49
+ typedef GoInt64 GoInt;
50
+ typedef GoUint64 GoUint;
51
+ typedef size_t GoUintptr;
52
+ typedef float GoFloat32;
53
+ typedef double GoFloat64;
54
+ #ifdef _MSC_VER
55
+ #include <complex.h>
56
+ typedef _Fcomplex GoComplex64;
57
+ typedef _Dcomplex GoComplex128;
58
+ #else
59
+ typedef float _Complex GoComplex64;
60
+ typedef double _Complex GoComplex128;
61
+ #endif
62
+
63
+ /*
64
+ static assertion to make sure the file is being used on architecture
65
+ at least with matching size of GoInt.
66
+ */
67
+ typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
68
+
69
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
70
+ typedef _GoString_ GoString;
71
+ #endif
72
+ typedef void *GoMap;
73
+ typedef void *GoChan;
74
+ typedef struct { void *t; void *v; } GoInterface;
75
+ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
76
+
77
+ #endif
78
+
79
+ /* End of boilerplate cgo prologue. */
80
+
81
+ #ifdef __cplusplus
82
+ extern "C" {
83
+ #endif
84
+
85
+
86
+ // Build the given `path` in the `root`.
87
+ //
88
+ // - path - The path to build relative to `root`.
89
+ // - root - The working directory.
90
+ // - baseUrl - base URL of the Rails app. eg. https://example.com
91
+ // - env - The environment (1 = development, 2 = test, 3 = production)
92
+ // - importMap - Path to the import map relative to `root`.
93
+ // - bundle
94
+ // - debug
95
+ //
96
+ extern struct Result build(char* filepath, char* root, char* baseUrl, unsigned int env, char* importMap, GoUint8 bundle, GoUint8 debug);
97
+
98
+ // Resolve the given `path` relative to the `root`.
99
+ //
100
+ // - path - The path to build relative to `root`.
101
+ // - root - The working directory.
102
+ // - env - The environment (1 = development, 2 = test, 3 = production)
103
+ // - importMap - Path to the import map relative to `root`.
104
+ //
105
+ extern struct Result resolve(char* path, char* root, unsigned int env, char* importMap);
106
+
107
+ #ifdef __cplusplus
108
+ }
109
+ #endif
data/config/routes.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Proscenium::Railtie.routes.draw do
4
- if Proscenium.config.auto_reload
5
- mount Proscenium::Railtie.websocket => Proscenium.config.cable_mount_path
6
- end
7
4
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class CssModule::ClassNamesResolver
5
+ def initialize(class_names, phlex_path)
6
+ @class_names = class_names.split
7
+ @stylesheets = {}
8
+ @phlex_path = phlex_path.sub_ext('.module.css')
9
+
10
+ resolve_class_names
11
+ end
12
+
13
+ def class_names
14
+ @class_names.join(' ')
15
+ end
16
+
17
+ def stylesheets
18
+ @stylesheets.map { |_, values| values[:resolved_path] }
19
+ end
20
+
21
+ private
22
+
23
+ def resolve_class_names
24
+ @class_names.map! do |class_name|
25
+ if class_name.include?('/')
26
+ if class_name.starts_with?('@')
27
+ # Scoped bare specifier (eg. "@scoped/package/lib/button@default").
28
+ _, path, name = class_name.split('@')
29
+ path = "@#{path}"
30
+ elsif class_name.starts_with?('/')
31
+ # Local path with leading slash.
32
+ path, name = class_name[1..].split('@')
33
+ else
34
+ # Bare specifier (eg. "mypackage/lib/button@default").
35
+ path, name = class_name.split('@')
36
+ end
37
+
38
+ path += '.module.css'
39
+
40
+ Utils.css_modularise_class_name name, digest: add_stylesheet(path)[:digest]
41
+ elsif class_name.starts_with?('@')
42
+ Utils.css_modularise_class_name class_name[1..],
43
+ digest: add_stylesheet(@phlex_path)[:digest]
44
+ else
45
+ class_name
46
+ end
47
+ end
48
+ end
49
+
50
+ def add_stylesheet(path)
51
+ return @stylesheets[path] if @stylesheets.key?(path)
52
+
53
+ resolved_path = Utils.resolve_path(path.to_s)
54
+
55
+ unless Rails.root.join(resolved_path[1..]).exist?
56
+ raise CssModule::StylesheetNotFound, resolved_path
57
+ end
58
+
59
+ # Note that the digest is based on the resolved (URL) path, not the original path.
60
+ @stylesheets[path] = {
61
+ resolved_path: resolved_path,
62
+ digest: Utils.digest(resolved_path)
63
+ }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class CssModule::Resolver
5
+ attr_reader :side_loaded_paths
6
+
7
+ # @param path [Pathname] Absolute file system path to the Ruby file that will be side loaded.
8
+ def initialize(path, side_load: true, hash: nil)
9
+ raise ArgumentError, "'#{path}' must be a `Pathname`" unless path.is_a?(Pathname)
10
+
11
+ @path = path
12
+ @hash = hash
13
+ @css_module_path = path.sub_ext('.module.css')
14
+ @side_load = side_load
15
+ @side_loaded_paths = nil
16
+ end
17
+
18
+ # Parses the given `content` for CSS modules names ('class' attributes beginning with '@'), and
19
+ # returns the content with said CSS Modules replaced with the compiled class names.
20
+ #
21
+ # Example:
22
+ # <div class="@my_css_module_name"></div>
23
+ def compile_class_names(content)
24
+ doc = Nokogiri::HTML::DocumentFragment.parse(content)
25
+
26
+ return content if (modules = doc.css('[class*="@"]')).empty?
27
+
28
+ modules.each do |ele|
29
+ classes = ele.classes.map { |cls| cls.starts_with?('@') ? class_names!(cls[1..]) : cls }
30
+ ele['class'] = classes.join(' ')
31
+ end
32
+
33
+ doc.to_html.html_safe
34
+ end
35
+
36
+ # Resolves the given CSS class names to CSS modules. This will also side load the stylesheet if
37
+ # it exists.
38
+ #
39
+ # @param names [String, Array]
40
+ # @returns [Array] of class names generated from the given CSS module `names`.
41
+ def class_names(*names)
42
+ side_load_css_module
43
+ Utils.css_modularise_class_names names, digest: @hash
44
+ end
45
+
46
+ # Like #class_names, but requires that the stylesheet exists.
47
+ #
48
+ # @param names [String, Array]
49
+ # @raises Proscenium::CssModule::NotFound if stylesheet does not exists.
50
+ # @see #class_names
51
+ def class_names!(...)
52
+ raise CssModule::StylesheetNotFound, @css_module_path unless @css_module_path.exist?
53
+
54
+ class_names(...)
55
+ end
56
+
57
+ def side_loaded?
58
+ @side_loaded_paths.present?
59
+ end
60
+
61
+ private
62
+
63
+ def side_load_css_module
64
+ return if !@side_load || !Rails.application.config.proscenium.side_load
65
+
66
+ paths = SideLoad.append @path, { '.module.css' => :css }
67
+
68
+ @side_loaded_paths = if paths.empty?
69
+ nil
70
+ else
71
+ @hash = Utils.digest(paths[0])
72
+ paths
73
+ end
74
+ end
75
+ end
76
+ end