proscenium 0.1.1-x86_64-linux → 0.2.0-x86_64-linux

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: 8cb09bd3aacc4ffeec61de7c9aed8795432a096ddec4490f44036c2492d04b7b
4
- data.tar.gz: 7a173194f536f01294d18f756da7134e736e892135394325b09ee51765ec29cd
3
+ metadata.gz: 7674bd9b916a7862d66f1da99291a083ee033397ec1c480ef830d6e015b62466
4
+ data.tar.gz: 9b906468c4f0c0dccf21cc281d6651fd57ddadaf5625cd23e635d6a3e711d7fc
5
5
  SHA512:
6
- metadata.gz: fe234a1042f3c813a57c3a1f0edadf11f1d702fd2825cf706a91c06b3e50147864532ddc6e1085cca61f1f4400958104bbb63041cd5a24c400b6800eb9103985
7
- data.tar.gz: 42664f98b4e0c74c6ddeab211e73d1c071fad71d335a0664df35cb5b3ef72d25c63a86fbee294725bfb460a21b0c2b2bb733d1afed77bb705699ce5eda9f8bd8
6
+ metadata.gz: 261f91913972d9d0c229851a5a698ad9725742902e6dbc3441af03a64c2ad775b00d6a6448b6bbacacbe0b0f4c5550c0ce3a595522fb8c42b946ff4a58e43704
7
+ data.tar.gz: 268ae1167972e0db6709bd529fddb545f9fccc11363cffa9355ad327b157db2bf312085d2663326dab717c91bbc2b64a45d0506c40a6d4743eddde82cf4692ef
data/bin/esbuild CHANGED
Binary file
@@ -1,6 +1,8 @@
1
1
  export default class ArgumentError extends Error {
2
2
  static MESSAGES = {
3
3
  rootRequired: 'Current working directory is required as --root.',
4
+ lightningcssBinRequired:
5
+ 'Path to the lightningcss CLI binary is required as --lightningcss-bin.',
4
6
  pathsRequired: 'One or more file paths or globs are required.',
5
7
 
6
8
  rootUnknown: ({ root }) => `A valid working directory is required - received ${root}`
@@ -1,16 +1,12 @@
1
1
  import { crypto } from 'std/crypto/mod.ts'
2
- import { join, resolve, dirname, basename, fromFileUrl } from 'std/path/mod.ts'
2
+ import { join, dirname, basename } from 'std/path/mod.ts'
3
3
 
4
4
  import { fileExists } from '../../utils.js'
5
5
  import postcss from './css/postcss.js'
6
6
  import setup from './setup_plugin.js'
7
7
 
8
- export default setup('css', async build => {
8
+ export default setup('css', async (build, options) => {
9
9
  const cwd = build.initialOptions.absWorkingDir
10
- const lightningcssBin = resolve(
11
- dirname(fromFileUrl(import.meta.url)),
12
- '../../../../bin/lightningcss'
13
- )
14
10
 
15
11
  let customMedia
16
12
  try {
@@ -40,7 +36,7 @@ export default setup('css', async build => {
40
36
  }
41
37
 
42
38
  let cmd = [
43
- lightningcssBin,
39
+ options.lightningcssBin,
44
40
  '--nesting',
45
41
  '--error-recovery',
46
42
  args.pluginData?.importedFromJs && '--minify',
@@ -11,6 +11,9 @@ export default setup('resolve', (build, options) => {
11
11
  const runtimeCwdAlias = `${cwd}/proscenium-runtime`
12
12
  let bundled = false
13
13
 
14
+ const env = Deno.env.get('RAILS_ENV')
15
+ const isProd = env === 'production'
16
+
14
17
  return [
15
18
  {
16
19
  type: 'onResolve',
@@ -28,24 +31,7 @@ export default setup('resolve', (build, options) => {
28
31
  return { external: true }
29
32
  }
30
33
 
31
- // Proscenium runtime
32
- // if (args.path.startsWith('@proscenium/')) {
33
- // const result = { suffix: args.suffix }
34
-
35
- // if (args.queryParams?.has('bundle-all')) {
36
- // bundled = true
37
- // }
38
-
39
- // if (bundled || args.queryParams?.has('bundle')) {
40
- // result.path = join(runtimeDir, `${args.path.replace(/^@proscenium/, '')}/index.js`)
41
- // } else {
42
- // result.path = `${args.path.replace(/^@proscenium/, '/proscenium-runtime')}/index.js`
43
- // result.external = true
44
- // }
45
-
46
- // return result
47
- // }
48
-
34
+ // Rewrite the path to the actual runtime directory.
49
35
  if (args.path.startsWith(runtimeCwdAlias)) {
50
36
  return { path: join(runtimeDir, args.path.slice(runtimeCwdAlias.length)) }
51
37
  }
@@ -88,11 +74,12 @@ export default setup('resolve', (build, options) => {
88
74
  // Resolve the path using esbuild's internal resolution. This allows us to import node packages
89
75
  // and extension-less paths without custom code, as esbuild with resolve them for us.
90
76
  const resolveResult = await build.resolve(result.path, {
91
- // If path is a bare module (node_modules), and resolveDir is the Proscenium runtime dir, then
92
- // use `cwd` as the `resolveDir`, otherwise pass it through as is. This ensures that nested
93
- // node_modules are resolved correctly.
77
+ // If path is a bare module (node_modules), and resolveDir is the Proscenium runtime dir, or
78
+ // is the current working dir, then use `cwd` as the `resolveDir`, otherwise pass it through
79
+ // as is. This ensures that nested node_modules are resolved correctly.
94
80
  resolveDir:
95
- isBareModule(result.path) && params.resolveDir.startsWith(runtimeDir)
81
+ isBareModule(result.path) &&
82
+ (!params.resolveDir.startsWith(cwd) || params.resolveDir.startsWith(runtimeDir))
96
83
  ? cwd
97
84
  : params.resolveDir,
98
85
  pluginData: {
@@ -118,9 +105,17 @@ export default setup('resolve', (build, options) => {
118
105
 
119
106
  if (resolveResult.path.startsWith(runtimeDir)) {
120
107
  result.path = '/proscenium-runtime' + resolveResult.path.slice(runtimeDir.length)
121
- } else if (!resolveResult.path.startsWith(cwd)) {
122
- // If resolved path does not start with cwd, then it is most likely linked, so bundle it.
123
- return { ...resolveResult, suffix: '?bundle' }
108
+ } else if (!resolveResult.path.startsWith(cwd) && !isProd) {
109
+ // Resolved path is not in the current working directory. It could be linked to a file outside
110
+ // the CWD, or it's just invalid. If not in production, return as an outsideRoot namespaced,
111
+ // and externally suffixed path. This lets the Rails Proscenium::Middleware::OutsideRoot
112
+ // handle the import.
113
+ return {
114
+ ...resolveResult,
115
+ namespace: 'outsideRoot',
116
+ path: `${resolveResult.path}?outsideRoot`,
117
+ external: true
118
+ }
124
119
  } else {
125
120
  result.path = resolveResult.path.slice(cwd.length)
126
121
  }
@@ -23,7 +23,7 @@ import throwCompileError from './esbuild/compile_error.js'
23
23
  * esbuild [OPTIONS] <PATHS_ARG>...
24
24
  *
25
25
  * ARGS:
26
- * <PATHS_ARG>... One or more file paths to compile.
26
+ * <PATHS_ARG>... One or more file paths or globs to compile.
27
27
  *
28
28
  * OPTIONS:
29
29
  * --root
@@ -31,6 +31,8 @@ import throwCompileError from './esbuild/compile_error.js'
31
31
  * take place.
32
32
  * --import-map
33
33
  * Path to an import map, relative to the <root>.
34
+ * --lightningcss-bin
35
+ * Path to the lightningcss CLI binary.
34
36
  * --write
35
37
  * Write output to the filesystem according to esbuild logic.
36
38
  * --debug
@@ -40,10 +42,11 @@ if (import.meta.main) {
40
42
  !Deno.env.get('RAILS_ENV') && Deno.env.set('RAILS_ENV', 'development')
41
43
 
42
44
  const { _: paths, ...options } = parseArgs(Deno.args, {
43
- string: ['root', 'import-map'],
45
+ string: ['root', 'import-map', 'lightningcss-bin'],
44
46
  boolean: ['write', 'debug'],
45
47
  alias: {
46
- 'import-map': 'importMap'
48
+ 'import-map': 'importMap',
49
+ 'lightningcss-bin': 'lightningcssBin'
47
50
  }
48
51
  })
49
52
 
@@ -62,6 +65,7 @@ async function main(paths = [], options = {}) {
62
65
 
63
66
  if (!Array.isArray(paths) || paths.length < 1) throw new ArgumentError('pathsRequired')
64
67
  if (!options.root) throw new ArgumentError('rootRequired')
68
+ if (!options.lightningcssBin) throw new ArgumentError('lightningcssBinRequired')
65
69
 
66
70
  const root = resolve(options.root)
67
71
 
@@ -76,8 +80,8 @@ async function main(paths = [], options = {}) {
76
80
  const env = Deno.env.get('RAILS_ENV')
77
81
  const isProd = env === 'production'
78
82
  const isTest = env === 'test'
79
-
80
83
  const entryPoints = new Set()
84
+
81
85
  for (let i = 0; i < paths.length; i++) {
82
86
  const path = paths[i]
83
87
 
@@ -85,6 +89,10 @@ async function main(paths = [], options = {}) {
85
89
  for await (const file of expandGlob(path, { root })) {
86
90
  file.isFile && entryPoints.add(file.path)
87
91
  }
92
+ } else if (path.startsWith('/')) {
93
+ // Path is absolute, so it must be outsideRoot. Don't prefix the root.
94
+ // See Proscenium::Middleware::OutsideRoot.
95
+ entryPoints.add(path)
88
96
  } else {
89
97
  entryPoints.add(join(root, path))
90
98
  }
@@ -117,7 +125,11 @@ async function main(paths = [], options = {}) {
117
125
  jsxDev: !isTest && !isProd,
118
126
  minify: isProd,
119
127
  bundle: true,
120
- plugins: [envPlugin(), resolvePlugin({ runtimeDir, importMap, debug }), cssPlugin({ debug })],
128
+ plugins: [
129
+ envPlugin(),
130
+ resolvePlugin({ runtimeDir, importMap, debug }),
131
+ cssPlugin({ lightningcssBin: options.lightningcssBin, debug })
132
+ ],
121
133
  metafile: write,
122
134
  write
123
135
  }
@@ -3,7 +3,15 @@
3
3
  module Proscenium
4
4
  module Helper
5
5
  def compute_asset_path(path, options = {})
6
- return "/#{path}" if %i[javascript stylesheet].include?(options[:type])
6
+ if %i[javascript stylesheet].include?(options[:type])
7
+ result = "/#{path}"
8
+
9
+ if (qs = Proscenium.config.cache_query_string)
10
+ result << "?#{qs}"
11
+ end
12
+
13
+ return result
14
+ end
7
15
 
8
16
  super
9
17
  end
@@ -60,6 +60,10 @@ module Proscenium
60
60
  response.content_type = content_type
61
61
  response['X-Proscenium-Middleware'] = name
62
62
 
63
+ if Proscenium.config.cache_query_string
64
+ response['Cache-Control'] = "public, max-age=#{2.days.to_i}"
65
+ end
66
+
63
67
  yield response if block_given?
64
68
 
65
69
  response.finish
@@ -15,7 +15,9 @@ module Proscenium
15
15
 
16
16
  def attempt
17
17
  benchmark :esbuild do
18
- render_response build("#{cli} --root #{root} #{path}")
18
+ render_response build(
19
+ "#{cli} --root #{root} --lightningcss-bin #{lightningcss_cli} #{path}"
20
+ )
19
21
  end
20
22
  rescue CompileError => e
21
23
  render_response "export default #{e.detail.to_json}" do |response|
@@ -38,6 +40,14 @@ module Proscenium
38
40
  Gem.bin_path 'proscenium', 'esbuild'
39
41
  end
40
42
  end
43
+
44
+ def lightningcss_cli
45
+ if ENV['PROSCENIUM_TEST']
46
+ 'bin/lightningcss'
47
+ else
48
+ Gem.bin_path 'proscenium', 'lightningcss'
49
+ end
50
+ end
41
51
  end
42
52
  end
43
53
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class Middleware
5
+ # Provides a way to render files outside of the Rails root during non-production. This is
6
+ # primarily to support linked NPM modules, for example when using `pnpm link ...`.
7
+ class OutsideRoot < Esbuild
8
+ private
9
+
10
+ # @override [Esbuild] reassigns root to '/'.
11
+ def renderable?
12
+ old_root = root
13
+ @root = Pathname.new('/')
14
+
15
+ super
16
+ ensure
17
+ @root = old_root
18
+ end
19
+
20
+ # @override [Esbuild] does not remove leading slash, ensuring it is an absolute path.
21
+ def path
22
+ @request.path
23
+ end
24
+ end
25
+ end
26
+ end
@@ -10,6 +10,7 @@ module Proscenium
10
10
  autoload :Base
11
11
  autoload :Esbuild
12
12
  autoload :Runtime
13
+ autoload :OutsideRoot
13
14
 
14
15
  def initialize(app)
15
16
  @app = app
@@ -38,6 +39,12 @@ module Proscenium
38
39
  def find_type(request)
39
40
  path = Pathname.new(request.path)
40
41
 
42
+ # Non-production only!
43
+ if request.query_string == 'outsideRoot'
44
+ return if Rails.env.production?
45
+ return OutsideRoot if path.fnmatch?(glob_types[:outsideRoot], File::FNM_EXTGLOB)
46
+ end
47
+
41
48
  return Runtime if path.fnmatch?(glob_types[:runtime], File::FNM_EXTGLOB)
42
49
  return Esbuild if path.fnmatch?(glob_types[:esbuild], File::FNM_EXTGLOB)
43
50
  end
@@ -13,7 +13,8 @@ module Proscenium
13
13
  # See https://doc.deno.land/https://deno.land/std@0.145.0/path/mod.ts/~/globToRegExp
14
14
  DEFAULT_GLOB_TYPES = {
15
15
  esbuild: '/{config,app,lib,node_modules}/**.{js,mjs,jsx,css}',
16
- runtime: '/proscenium-runtime/**.{js,jsx}'
16
+ runtime: '/proscenium-runtime/**.{js,jsx}',
17
+ outsideRoot: '/**/*.{js,jsx,mjs,css}'
17
18
  }.freeze
18
19
 
19
20
  class << self
@@ -27,6 +28,7 @@ module Proscenium
27
28
 
28
29
  config.proscenium = ActiveSupport::OrderedOptions.new
29
30
  config.proscenium.side_load = true
31
+ config.proscenium.cache_query_string = Rails.env.production? && ENV.fetch('REVISION', nil)
30
32
  config.proscenium.auto_reload = Rails.env.development?
31
33
  config.proscenium.auto_reload_paths ||= %w[lib app config]
32
34
  config.proscenium.auto_reload_extensions ||= /\.(css|jsx?)$/
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proscenium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-16 00:00:00.000000000 Z
11
+ date: 2022-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actioncable
@@ -167,6 +167,7 @@ files:
167
167
  - lib/proscenium/middleware/base.rb
168
168
  - lib/proscenium/middleware/esbuild.rb
169
169
  - lib/proscenium/middleware/lightningcss.rb
170
+ - lib/proscenium/middleware/outside_root.rb
170
171
  - lib/proscenium/middleware/runtime.rb
171
172
  - lib/proscenium/middleware/static.rb
172
173
  - lib/proscenium/phlex.rb