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

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.
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
data/lib/proscenium.rb CHANGED
@@ -12,8 +12,85 @@ module Proscenium
12
12
  autoload :ViewComponent
13
13
  autoload :Phlex
14
14
  autoload :Helper
15
- autoload :LinkToHelper
16
- autoload :Precompile
15
+ autoload :Esbuild
16
+
17
+ def self.reset_current_side_loaded
18
+ Current.reset
19
+ Current.loaded = SideLoad::EXTENSIONS.to_h { |e| [e, Set.new] }
20
+ end
21
+
22
+ class PathResolutionFailed < StandardError
23
+ def initialize(path)
24
+ @path = path
25
+ super
26
+ end
27
+
28
+ def message
29
+ "Path #{@path.inspect} cannot be resolved"
30
+ end
31
+ end
32
+
33
+ module Utils
34
+ module_function
35
+
36
+ # @param value [#to_s] The value to create the digest from. This will usually be a `Pathname`.
37
+ # @return [String] string digest of the given value.
38
+ def digest(value)
39
+ Digest::SHA1.hexdigest(value.to_s)[..7]
40
+ end
41
+
42
+ # Resolve the given `path` to a URL path.
43
+ #
44
+ # @param path [String] Can be URL path, file system path, or bare specifier (ie. NPM package).
45
+ # @return [String] URL path.
46
+ def resolve_path(path) # rubocop:disable Metrics/AbcSize
47
+ raise ArgumentError, 'path must be a string' unless path.is_a?(String)
48
+
49
+ if path.starts_with?('./', '../')
50
+ raise ArgumentError, 'path must be an absolute file system or URL path'
51
+ end
52
+
53
+ matched_gem = Proscenium.config.side_load_gems.find do |_, opts|
54
+ path.starts_with?("#{opts[:root]}/")
55
+ end
56
+
57
+ if matched_gem
58
+ sroot = "#{matched_gem[1][:root]}/"
59
+ relpath = path.delete_prefix(sroot)
60
+
61
+ if matched_gem[1][:package_name]
62
+ return Esbuild::Golib.resolve("#{matched_gem[1][:package_name]}/#{relpath}")
63
+ end
64
+
65
+ # TODO: manually resolve the path without esbuild
66
+ raise PathResolutionFailed, path
67
+ end
68
+
69
+ return path.delete_prefix(Rails.root.to_s) if path.starts_with?("#{Rails.root}/")
70
+
71
+ Esbuild::Golib.resolve(path)
72
+ end
73
+
74
+ # Resolves CSS class `names` to CSS module names. Each name will be converted to a CSS module
75
+ # name, consisting of the camelCased name (lower case first character), and suffixed with the
76
+ # given `digest`.
77
+ #
78
+ # @param names [String, Array]
79
+ # @param digest: [String]
80
+ # @returns [Array] of class names generated from the given CSS module `names` and `digest`.
81
+ def css_modularise_class_names(*names, digest: nil)
82
+ names.flatten.compact.map { |name| css_modularise_class_name name, digest: digest }
83
+ end
84
+
85
+ def css_modularise_class_name(name, digest: nil)
86
+ sname = name.to_s
87
+ if sname.starts_with?('_')
88
+ "_#{sname[1..].camelize(:lower)}#{digest}"
89
+ else
90
+ "#{sname.camelize(:lower)}#{digest}"
91
+ end
92
+ end
93
+ end
17
94
  end
18
95
 
19
96
  require 'proscenium/railtie'
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proscenium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: x86_64-darwin
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-08 00:00:00.000000000 Z
11
+ date: 2023-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: actioncable
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -31,81 +31,75 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: '8.0'
33
33
  - !ruby/object:Gem::Dependency
34
- name: activesupport
34
+ name: ffi
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 6.1.0
40
- - - "<"
37
+ - - "~>"
41
38
  - !ruby/object:Gem::Version
42
- version: '8.0'
39
+ version: 1.15.5
43
40
  type: :runtime
44
41
  prerelease: false
45
42
  version_requirements: !ruby/object:Gem::Requirement
46
43
  requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 6.1.0
50
- - - "<"
44
+ - - "~>"
51
45
  - !ruby/object:Gem::Version
52
- version: '8.0'
46
+ version: 1.15.5
53
47
  - !ruby/object:Gem::Dependency
54
- name: listen
48
+ name: nokogiri
55
49
  requirement: !ruby/object:Gem::Requirement
56
50
  requirements:
57
51
  - - "~>"
58
52
  - !ruby/object:Gem::Version
59
- version: '3.0'
53
+ version: '1.13'
60
54
  type: :runtime
61
55
  prerelease: false
62
56
  version_requirements: !ruby/object:Gem::Requirement
63
57
  requirements:
64
58
  - - "~>"
65
59
  - !ruby/object:Gem::Version
66
- version: '3.0'
60
+ version: '1.13'
67
61
  - !ruby/object:Gem::Dependency
68
- name: nokogiri
62
+ name: oj
69
63
  requirement: !ruby/object:Gem::Requirement
70
64
  requirements:
71
65
  - - "~>"
72
66
  - !ruby/object:Gem::Version
73
- version: '1.13'
67
+ version: '3.13'
74
68
  type: :runtime
75
69
  prerelease: false
76
70
  version_requirements: !ruby/object:Gem::Requirement
77
71
  requirements:
78
72
  - - "~>"
79
73
  - !ruby/object:Gem::Version
80
- version: '1.13'
74
+ version: '3.13'
81
75
  - !ruby/object:Gem::Dependency
82
- name: oj
76
+ name: phlex
83
77
  requirement: !ruby/object:Gem::Requirement
84
78
  requirements:
85
79
  - - "~>"
86
80
  - !ruby/object:Gem::Version
87
- version: '3.13'
81
+ version: 1.8.1
88
82
  type: :runtime
89
83
  prerelease: false
90
84
  version_requirements: !ruby/object:Gem::Requirement
91
85
  requirements:
92
86
  - - "~>"
93
87
  - !ruby/object:Gem::Version
94
- version: '3.13'
88
+ version: 1.8.1
95
89
  - !ruby/object:Gem::Dependency
96
- name: phlex
90
+ name: phlex-rails
97
91
  requirement: !ruby/object:Gem::Requirement
98
92
  requirements:
99
93
  - - "~>"
100
94
  - !ruby/object:Gem::Version
101
- version: 0.4.0
95
+ version: 1.0.0
102
96
  type: :runtime
103
97
  prerelease: false
104
98
  version_requirements: !ruby/object:Gem::Requirement
105
99
  requirements:
106
100
  - - "~>"
107
101
  - !ruby/object:Gem::Version
108
- version: 0.4.0
102
+ version: 1.0.0
109
103
  - !ruby/object:Gem::Dependency
110
104
  name: railties
111
105
  requirement: !ruby/object:Gem::Requirement
@@ -126,78 +120,47 @@ dependencies:
126
120
  - - "<"
127
121
  - !ruby/object:Gem::Version
128
122
  version: '8.0'
129
- - !ruby/object:Gem::Dependency
130
- name: view_component
131
- requirement: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - "~>"
134
- - !ruby/object:Gem::Version
135
- version: 2.74.1
136
- type: :runtime
137
- prerelease: false
138
- version_requirements: !ruby/object:Gem::Requirement
139
- requirements:
140
- - - "~>"
141
- - !ruby/object:Gem::Version
142
- version: 2.74.1
143
123
  description:
144
124
  email:
145
125
  - joel@developwithstyle.com
146
126
  executables:
147
- - esbuild
148
- - lightningcss
127
+ - proscenium
149
128
  extensions: []
150
129
  extra_rdoc_files: []
151
130
  files:
152
131
  - CODE_OF_CONDUCT.md
153
132
  - LICENSE.txt
154
133
  - README.md
155
- - app/channels/proscenium/connection.rb
156
- - app/channels/proscenium/reload_channel.rb
157
- - bin/esbuild
158
- - bin/lightningcss
134
+ - bin/proscenium
135
+ - bin/proscenium.h
159
136
  - config/routes.rb
160
137
  - lib/proscenium.rb
161
- - lib/proscenium/compiler.js
162
- - lib/proscenium/compilers/esbuild.bench.js
163
- - lib/proscenium/compilers/esbuild.js
164
- - lib/proscenium/compilers/esbuild/argument_error.js
165
- - lib/proscenium/compilers/esbuild/compile_error.js
166
- - lib/proscenium/compilers/esbuild/css/postcss.js
167
- - lib/proscenium/compilers/esbuild/css_plugin.js
168
- - lib/proscenium/compilers/esbuild/env_plugin.js
169
- - lib/proscenium/compilers/esbuild/http_bundle_plugin.js
170
- - lib/proscenium/compilers/esbuild/import_map.js
171
- - lib/proscenium/compilers/esbuild/resolve_plugin.js
172
- - lib/proscenium/compilers/esbuild/setup_plugin.js
173
- - lib/proscenium/compilers/esbuild/solidjs_plugin.js
174
138
  - lib/proscenium/css_module.rb
139
+ - lib/proscenium/css_module/class_names_resolver.rb
140
+ - lib/proscenium/css_module/resolver.rb
175
141
  - lib/proscenium/current.rb
142
+ - lib/proscenium/esbuild.rb
143
+ - lib/proscenium/esbuild/golib.rb
176
144
  - lib/proscenium/helper.rb
177
- - lib/proscenium/link_to_helper.rb
145
+ - lib/proscenium/log_subscriber.rb
178
146
  - lib/proscenium/middleware.rb
179
147
  - lib/proscenium/middleware/base.rb
180
148
  - lib/proscenium/middleware/esbuild.rb
181
- - lib/proscenium/middleware/lightningcss.rb
182
- - lib/proscenium/middleware/outside_root.rb
183
- - lib/proscenium/middleware/runtime.rb
184
- - lib/proscenium/middleware/static.rb
185
149
  - lib/proscenium/middleware/url.rb
186
150
  - lib/proscenium/phlex.rb
187
- - lib/proscenium/phlex/component.rb
151
+ - lib/proscenium/phlex/component_concerns.rb
152
+ - lib/proscenium/phlex/page.rb
188
153
  - lib/proscenium/phlex/react_component.rb
189
- - lib/proscenium/precompile.rb
154
+ - lib/proscenium/phlex/resolve_css_modules.rb
190
155
  - lib/proscenium/railtie.rb
191
- - lib/proscenium/runtime/auto_reload.js
192
- - lib/proscenium/runtime/react_shim/index.js
193
- - lib/proscenium/runtime/react_shim/package.json
194
156
  - lib/proscenium/side_load.rb
195
- - lib/proscenium/utils.js
157
+ - lib/proscenium/side_load/ensure_loaded.rb
158
+ - lib/proscenium/side_load/helper.rb
159
+ - lib/proscenium/side_load/monkey.rb
196
160
  - lib/proscenium/version.rb
197
161
  - lib/proscenium/view_component.rb
198
162
  - lib/proscenium/view_component/react_component.rb
199
163
  - lib/proscenium/view_component/tag_builder.rb
200
- - lib/tasks/assets.rake
201
164
  homepage: https://github.com/joelmoss/proscenium
202
165
  licenses:
203
166
  - MIT
@@ -221,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
184
  - !ruby/object:Gem::Version
222
185
  version: '0'
223
186
  requirements: []
224
- rubygems_version: 3.3.7
187
+ rubygems_version: 3.4.13
225
188
  signing_key:
226
189
  specification_version: 4
227
190
  summary: The engine powering your Rails frontend
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- class Connection < ActionCable::Connection::Base
5
- identified_by :uid
6
-
7
- def connect
8
- self.uid = request.params[:uid]
9
- logger.add_tags(uid)
10
- logger.info 'connected to Proscenium'
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- class ReloadChannel < ActionCable::Channel::Base
5
- def subscribed
6
- stream_from 'reload'
7
- end
8
- end
9
- end
data/bin/esbuild DELETED
Binary file
data/bin/lightningcss DELETED
Binary file
@@ -1,84 +0,0 @@
1
- // Recursively Scans the /app path for any JS/JSX/CSS files, and compiles each one, while also
2
- // building a manifest (JSON) of all files that are built. The manifest contains a simple mapping of
3
- // source file => compiled file. The compiled files are appended with the content digest, for
4
- // caching.
5
-
6
- import { writeAll } from 'std/streams/mod.ts'
7
- import { MuxAsyncIterator } from 'std/async/mod.ts'
8
- import { expandGlob, ensureDir } from 'std/fs/mod.ts'
9
- import { extname, relative, join, dirname, parse } from 'std/path/mod.ts'
10
-
11
- import build from './cli.js'
12
-
13
- const extnameToBuilderMap = {
14
- '.js': 'javascript'
15
- }
16
-
17
- async function main(args = []) {
18
- const [root, ...paths] = args
19
- const outDir = join(root, 'public', 'assets')
20
- const manifest = {}
21
- const promises = []
22
- const mux = new MuxAsyncIterator()
23
-
24
- paths.forEach(path => {
25
- mux.add(expandGlob(`${path}/**/*.{css,js,jsx}`, { root }))
26
- })
27
-
28
- for await (const file of mux) {
29
- const builder = extnameToBuilderMap[extname(file.path)]
30
-
31
- if (!builder) {
32
- console.error('--! Failed to compile %o (unknown builder)', relative(root, file.path))
33
- continue
34
- }
35
-
36
- promises.push(
37
- compile({ ...file, root, outDir }).then(({ inPath, outPath }) => {
38
- manifest[inPath] = outPath
39
- })
40
- )
41
- }
42
-
43
- await Promise.allSettled(promises)
44
-
45
- return new TextEncoder().encode(JSON.stringify(manifest))
46
- }
47
-
48
- function compile({ root, path, outDir }) {
49
- const entrypoint = relative(root, path)
50
- const { dir, name, ext } = parse(entrypoint)
51
- const builder = extnameToBuilderMap[ext]
52
-
53
- console.log('--- Compiling %o with %s builder...', entrypoint, builder)
54
-
55
- return build([root, entrypoint, builder])
56
- .then(src => {
57
- console.log(2)
58
- return digest(src)
59
- })
60
- .then(({ hash, source }) => {
61
- const path = join(outDir, dir, `${name}-${hash}${ext}`)
62
-
63
- return ensureDir(dirname(path))
64
- .then(() => Deno.writeTextFile(path, new TextDecoder().decode(source)))
65
- .then(() => ({ inPath: entrypoint, outPath: relative(outDir, path) }))
66
- })
67
- }
68
-
69
- async function digest(source) {
70
- const view = new DataView(await crypto.subtle.digest('SHA-1', source))
71
-
72
- let hash = ''
73
- for (let index = 0; index < view.byteLength; index += 4) {
74
- hash += view.getUint32(index).toString(16).padStart(8, '0')
75
- }
76
-
77
- return { hash, source }
78
- }
79
-
80
- export default main
81
-
82
- if (import.meta.main) {
83
- await writeAll(Deno.stdout, await main(Deno.args))
84
- }
@@ -1,24 +0,0 @@
1
- export default class ArgumentError extends Error {
2
- static MESSAGES = {
3
- rootRequired: 'Current working directory is required as --root.',
4
- lightningcssBinRequired:
5
- 'Path to the lightningcss CLI binary is required as --lightningcss-bin.',
6
- pathsRequired: 'One or more file paths or globs are required.',
7
-
8
- rootUnknown: ({ root }) => `A valid working directory is required - received ${root}`
9
- }
10
-
11
- constructor(reason, options) {
12
- let message = ArgumentError.MESSAGES[reason]
13
- if (typeof message === 'function') {
14
- message = message(options)
15
- }
16
-
17
- message = `${reason}: ${message}`
18
-
19
- super(message, options)
20
-
21
- this.reason = reason
22
- this.message = message
23
- }
24
- }
@@ -1,148 +0,0 @@
1
- export default function () {
2
- if (Deno.env.get('RAILS_ENV') === 'development') {
3
- return function (detail) {
4
- const template = `
5
- <style>
6
- :host {
7
- position: fixed;
8
- z-index: 99999;
9
- top: 0;
10
- left: 0;
11
- width: 100%;
12
- height: 100%;
13
- overflow-y: scroll;
14
- margin: 0;
15
- background: rgba(0, 0, 0, 0.66);
16
- display: flex;
17
- align-items: center;
18
- --monospace: 'SFMono-Regular', Consolas,
19
- 'Liberation Mono', Menlo, Courier, monospace;
20
- --red: #ff5555;
21
- --yellow: #e2aa53;
22
- --purple: #cfa4ff;
23
- --cyan: #2dd9da;
24
- --dim: #c9c9c9;
25
- }
26
-
27
- .window {
28
- font-family: var(--monospace);
29
- line-height: 1.5;
30
- width: 800px;
31
- height: 66vh;
32
- color: #d8d8d8;
33
- margin: 30px auto;
34
- padding: 25px 40px;
35
- position: relative;
36
- background: #181818;
37
- border-radius: 6px 6px 8px 8px;
38
- box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
39
- overflow: hidden;
40
- border-top: 8px solid var(--red);
41
- }
42
-
43
- pre {
44
- font-family: var(--monospace);
45
- font-size: 16px;
46
- margin: 0 0 1em 0;
47
- overflow-x: scroll;
48
- scrollbar-width: none;
49
- }
50
-
51
- pre::-webkit-scrollbar {
52
- display: none;
53
- }
54
-
55
- .title, .message {
56
- line-height: 1.3;
57
- font-weight: 600;
58
- white-space: pre-wrap;
59
- }
60
-
61
- .message-body {
62
- color: var(--red);
63
- }
64
-
65
- .file {
66
- color: var(--cyan);
67
- margin-bottom: 0;
68
- white-space: pre-wrap;
69
- word-break: break-all;
70
- }
71
-
72
- .code {
73
- background: black;
74
- border-left: 3px solid gray;
75
- padding: 10px 0 0 20px;
76
- }
77
- .lineText {
78
- display: block;
79
- white-space: pre-wrap;
80
- }
81
- .lineCursor {
82
- white-space: pre;
83
- color: blueviolet;
84
- display: block;
85
- }
86
- </style>
87
- <div class="window">
88
- <pre class="title">COMPILE ERROR!</pre>
89
- <pre class="message"><span class="message-body"></span> in <span class="file"></span></pre>
90
- <pre class="code"><span class="lineText"></span><span class="lineCursor"></span></pre>
91
- </div>
92
- `
93
-
94
- class ErrorOverlay extends HTMLElement {
95
- constructor(err) {
96
- super()
97
-
98
- this.root = this.attachShadow({ mode: 'open' })
99
- this.root.innerHTML = template
100
- this.root.querySelector('.message-body').textContent = err.text.trim()
101
- if (err.location) {
102
- const location = [err.location.file]
103
- err.location.line && location.push(err.location.line)
104
- err.location.column && location.push(err.location.column)
105
- this.root.querySelector('.file').textContent = `/${location.join(':')}`
106
-
107
- if (err.location.lineText) {
108
- this.root.querySelector('.lineText').textContent = err.location.lineText
109
- this.root.querySelector('.lineCursor').textContent =
110
- ''.padStart(err.location.column - 1, ' ') + '^'
111
- } else {
112
- this.root.querySelector('.code').remove()
113
- }
114
-
115
- console.error('%s at %O', err.text, location)
116
- } else {
117
- console.error(err.text)
118
- }
119
-
120
- this.root.querySelector('.window').addEventListener('click', e => {
121
- e.stopPropagation()
122
- })
123
-
124
- this.addEventListener('click', () => {
125
- this.close()
126
- })
127
- }
128
-
129
- close() {
130
- this.parentNode?.removeChild(this)
131
- }
132
- }
133
-
134
- const overlayId = 'proscenium-error-overlay'
135
- if (customElements && !customElements.get(overlayId)) {
136
- customElements.define(overlayId, ErrorOverlay)
137
- }
138
-
139
- document.body.appendChild(new ErrorOverlay(detail))
140
- }
141
- } else {
142
- return function (detail) {
143
- const location = `/${detail.location.file}:${detail.location.line}:${detail.location.column}`
144
- console.error('%s at %O', detail.text, location)
145
- throw `${detail.text} at ${location}`
146
- }
147
- }
148
- }
@@ -1,67 +0,0 @@
1
- import { expandGlob } from 'std/fs/mod.ts'
2
- import postcss from 'postcss'
3
-
4
- export default async (root, path) => {
5
- let tmpFile
6
- let contents
7
-
8
- const mixinFiles = []
9
- for await (const file of expandGlob('lib/**/*.mixin.css', { root, globstar: true })) {
10
- mixinFiles.push(file.path)
11
- }
12
-
13
- // Only process mixins with PostCSS if there are any 'lib/**/*.mixin.css' files.
14
- if (mixinFiles.length > 0) {
15
- tmpFile = await Deno.makeTempFile()
16
- contents = await Deno.readTextFile(path)
17
-
18
- const result = await postcss([mixinsPlugin({ mixinFiles })]).process(contents, { from: path })
19
- contents = result.css
20
- }
21
-
22
- return [tmpFile, contents]
23
- }
24
-
25
- const mixinsPlugin = (opts = {}) => {
26
- return {
27
- postcssPlugin: 'mixins',
28
-
29
- prepare() {
30
- const mixins = {}
31
-
32
- return {
33
- async Once(_, helpers) {
34
- for (const path of opts.mixinFiles) {
35
- const content = await Deno.readTextFile(path)
36
- const root = helpers.parse(content, { from: path })
37
-
38
- root.walkAtRules('define-mixin', atrule => {
39
- mixins[atrule.params] = atrule
40
- })
41
- }
42
- },
43
-
44
- AtRule: {
45
- mixin: (rule, helpers) => {
46
- const mixin = mixins[rule.params]
47
-
48
- if (!mixin) {
49
- throw rule.error(`Undefined mixin '${rule.params}'`)
50
- }
51
-
52
- const proxy = new helpers.Root()
53
- for (let i = 0; i < mixin.nodes.length; i++) {
54
- const node = mixin.nodes[i].clone()
55
- delete node.raws.before
56
- proxy.append(node)
57
- }
58
-
59
- rule.parent.insertBefore(rule, proxy)
60
-
61
- if (rule.parent) rule.remove()
62
- }
63
- }
64
- }
65
- }
66
- }
67
- }