proscenium 0.1.0.alpha2-x86_64-linux → 0.1.0.alpha4-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +216 -32
  3. data/app/components/react_component.rb +10 -3
  4. data/bin/esbuild +0 -0
  5. data/bin/lightningcss +0 -0
  6. data/config/routes.rb +1 -1
  7. data/lib/proscenium/compilers/esbuild/compile_error.js +147 -0
  8. data/lib/proscenium/compilers/esbuild/css/postcss.js +67 -0
  9. data/lib/proscenium/compilers/esbuild/css_plugin.js +176 -0
  10. data/lib/proscenium/compilers/esbuild/env_plugin.js +6 -4
  11. data/lib/proscenium/compilers/esbuild/http_bundle_plugin.js +53 -0
  12. data/lib/proscenium/compilers/esbuild/import_map.js +59 -0
  13. data/lib/proscenium/compilers/esbuild/resolve_plugin.js +67 -65
  14. data/lib/proscenium/compilers/esbuild/setup_plugin.js +32 -22
  15. data/lib/proscenium/{cli → compilers}/esbuild/solidjs_plugin.js +5 -4
  16. data/lib/proscenium/compilers/esbuild.bench.js +7 -3
  17. data/lib/proscenium/compilers/esbuild.js +93 -19
  18. data/lib/proscenium/css_module.rb +48 -6
  19. data/lib/proscenium/helper.rb +5 -3
  20. data/lib/proscenium/middleware/base.rb +13 -3
  21. data/lib/proscenium/middleware/esbuild.rb +17 -1
  22. data/lib/proscenium/middleware/lightningcss.rb +64 -0
  23. data/lib/proscenium/middleware.rb +7 -19
  24. data/lib/proscenium/phlex.rb +36 -0
  25. data/lib/proscenium/railtie.rb +10 -20
  26. data/lib/proscenium/runtime/auto_reload.js +3 -3
  27. data/lib/proscenium/side_load.rb +14 -40
  28. data/lib/proscenium/utils.js +8 -0
  29. data/lib/proscenium/version.rb +1 -1
  30. data/lib/proscenium/view_component.rb +5 -1
  31. data/lib/proscenium.rb +1 -0
  32. metadata +27 -19
  33. data/bin/parcel_css +0 -0
  34. data/lib/proscenium/cli/argument_error.js +0 -24
  35. data/lib/proscenium/cli/builders/index.js +0 -1
  36. data/lib/proscenium/cli/builders/javascript.js +0 -45
  37. data/lib/proscenium/cli/builders/react.js +0 -60
  38. data/lib/proscenium/cli/builders/solid.js +0 -46
  39. data/lib/proscenium/cli/esbuild/env_plugin.js +0 -21
  40. data/lib/proscenium/cli/esbuild/resolve_plugin.js +0 -136
  41. data/lib/proscenium/cli/js_builder.js +0 -194
  42. data/lib/proscenium/cli/solid.js +0 -15
  43. data/lib/proscenium/cli/utils.js +0 -93
  44. data/lib/proscenium/middleware/parcel_css.rb +0 -37
  45. data/lib/proscenium/runtime/component_manager/index.js +0 -27
  46. data/lib/proscenium/runtime/component_manager/render_component.js +0 -40
  47. data/lib/proscenium/runtime/import_css.js +0 -46
@@ -1,93 +0,0 @@
1
- import { join } from 'std/path/mod.ts'
2
-
3
- import CliArgumentError from './argument_error.js'
4
- import { builderNames } from './builders/index.js'
5
-
6
- export const isTest = () => Deno.env.get('ENVIRONMENT') === 'test'
7
-
8
- export const debug = (...args) => {
9
- isTest() && console.log(...args)
10
- }
11
-
12
- export const setup = (pluginName, pluginFn) => {
13
- return (options = {}) => ({
14
- name: pluginName,
15
- setup(build) {
16
- const plugin = pluginFn(build)
17
-
18
- if (plugin.onResolve) {
19
- const { callback, ...onResolve } = plugin.onResolve
20
-
21
- build.onResolve(onResolve, async params => {
22
- if (params.pluginData?.isResolvingPath) return
23
-
24
- const results = await callback(params)
25
-
26
- options.debug && console.debug(`plugin(${pluginName}:onResolve)`, { params, results })
27
-
28
- return results
29
- })
30
- }
31
-
32
- if (plugin.onLoad) {
33
- const { callback, ...onLoad } = plugin.onLoad
34
-
35
- build.onLoad(onLoad, params => {
36
- const results = callback(params)
37
-
38
- options.debug && console.debug(`plugin(${pluginName}:onLoad)`, { params, results })
39
-
40
- return results
41
- })
42
- }
43
- }
44
- })
45
- }
46
-
47
- export const parseArgs = args => {
48
- let [cwd, entrypoint, builder] = args
49
-
50
- if (!cwd) {
51
- throw new CliArgumentError('cwdRequired')
52
- }
53
-
54
- if (!entrypoint) {
55
- throw new CliArgumentError('entrypointRequired')
56
- }
57
-
58
- if (!builder) {
59
- throw new CliArgumentError('builderRequired')
60
- }
61
-
62
- try {
63
- const stat = Deno.lstatSync(cwd)
64
- if (!stat.isDirectory) {
65
- throw new CliArgumentError(
66
- `Current working directory is required as the first argument - received ${cwd}`
67
- )
68
- }
69
- } catch {
70
- throw new CliArgumentError('cwdUnknown', { cwd })
71
- }
72
-
73
- if (/\.(jsx?)|(css)\.map$/.test(entrypoint)) {
74
- entrypoint = entrypoint.replace(/\.map$/, '')
75
- }
76
-
77
- try {
78
- const stat = Deno.lstatSync(join(cwd, entrypoint))
79
- if (!stat.isFile) {
80
- throw new CliArgumentError(
81
- `Entrypoint is required as the second argument - received ${entrypoint}`
82
- )
83
- }
84
- } catch {
85
- throw new CliArgumentError('entrypointUnknown', { entrypoint })
86
- }
87
-
88
- if (!builderNames.includes(builder)) {
89
- throw new CliArgumentError('builderUnknown', { builder })
90
- }
91
-
92
- return args
93
- }
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'oj'
4
-
5
- module Proscenium
6
- class Middleware
7
- class ParcelCss < Base
8
- def attempt
9
- benchmark :parcelcss do
10
- results = build("#{cli} #{cli_options.join ' '} #{root}#{@request.path}")
11
- render_response css_module? ? Oj.load(results, mode: :strict)['code'] : results
12
- end
13
- end
14
-
15
- private
16
-
17
- def cli
18
- Gem.bin_path 'proscenium', 'parcel_css'
19
- end
20
-
21
- def cli_options
22
- options = ['--nesting', '--custom-media', '--targets', "'>= 0.25%'"]
23
-
24
- if css_module?
25
- hash = Digest::SHA1.hexdigest(@request.path)[..7]
26
- options += ['--css-modules', '--css-modules-pattern', "'[local]#{hash}'"]
27
- end
28
-
29
- Rails.env.production? ? options << '-m' : options
30
- end
31
-
32
- def css_module?
33
- @css_module ||= /\.module\.css$/i.match?(@request.path_info)
34
- end
35
- end
36
- end
37
- end
@@ -1,27 +0,0 @@
1
- /* eslint-disable no-console */
2
-
3
- import renderComponent from `/proscenium-runtime/component_manager/render_component.js`
4
-
5
- document.addEventListener('DOMContentLoaded', () => {
6
- const elements = document.querySelectorAll('[data-component]')
7
-
8
- if (elements.length < 1) return
9
-
10
- Array.from(elements, (ele) => {
11
- const data = JSON.parse(ele.getAttribute('data-component'))
12
-
13
- let isVisible = false
14
- const observer = new IntersectionObserver((entries) => {
15
- entries.forEach((entry) => {
16
- if (!isVisible && entry.isIntersecting) {
17
- isVisible = true
18
- observer.unobserve(ele)
19
-
20
- renderComponent(ele, data)
21
- }
22
- })
23
- })
24
-
25
- observer.observe(ele)
26
- })
27
- })
@@ -1,40 +0,0 @@
1
- /* eslint-disable no-console */
2
-
3
- import { RAILS_ENV } from 'env'
4
-
5
- // We don't use JSX, as doing so would auto-inject React. We don't want to do this, as React is lazy
6
- // loaded only when needed.
7
- export default async function (ele, data) {
8
- const { createElement, useEffect, lazy, Suspense } = await import('react')
9
- const { createRoot } = await import('react-dom/client')
10
-
11
- const component = lazy(() => import(`/app/components${data.path}.jsx`))
12
- const contentLoader = data.contentLoader && ele.firstElementChild
13
-
14
- const Fallback = ({ contentLoader }) => {
15
- useEffect(() => {
16
- contentLoader && contentLoader.remove()
17
- }, []) // eslint-disable-line react-hooks/exhaustive-deps
18
-
19
- if (!contentLoader) return null
20
-
21
- return /* @__PURE__ */ createElement('div', {
22
- style: { height: '100%' },
23
- dangerouslySetInnerHTML: { __html: contentLoader.outerHTML }
24
- })
25
- }
26
-
27
- createRoot(ele).render(
28
- /* @__PURE__ */ createElement(
29
- Suspense,
30
- {
31
- fallback: /* @__PURE__ */ createElement(Fallback, {
32
- contentLoader
33
- })
34
- },
35
- createElement(component, data.props)
36
- )
37
- )
38
-
39
- RAILS_ENV === 'development' && console.debug(`[REACT]`, `Rendered ${data.path.slice(1)}`)
40
- }
@@ -1,46 +0,0 @@
1
- async function digest(value) {
2
- value = new TextEncoder().encode(value)
3
- const view = new DataView(await crypto.subtle.digest('SHA-1', value))
4
-
5
- let hexCodes = ''
6
- for (let index = 0; index < view.byteLength; index += 4) {
7
- hexCodes += view.getUint32(index).toString(16).padStart(8, '0')
8
- }
9
-
10
- return hexCodes.slice(0, 8)
11
- }
12
-
13
- const proxyCache = {}
14
-
15
- export async function importCssModule(path) {
16
- appendStylesheet(path)
17
-
18
- if (Object.keys(proxyCache).includes(path)) {
19
- return proxyCache[path]
20
- }
21
-
22
- const hashValue = await digest(path)
23
- return (proxyCache[path] = new Proxy(
24
- {},
25
- {
26
- get(target, prop, receiver) {
27
- if (prop in target || typeof prop === 'symbol') {
28
- return Reflect.get(target, prop, receiver)
29
- } else {
30
- return `${prop}${hashValue}`
31
- }
32
- }
33
- }
34
- ))
35
- }
36
-
37
- export function appendStylesheet(path) {
38
- // Make sure we only load the stylesheet once.
39
- if (document.head.querySelector(`link[rel=stylesheet][href='${path}']`)) return
40
-
41
- const ele = document.createElement('link')
42
- ele.setAttribute('rel', 'stylesheet')
43
- ele.setAttribute('media', 'all')
44
- ele.setAttribute('href', path)
45
- document.head.appendChild(ele)
46
- }