porous 0.2.0 → 0.3.1

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: 605209154f6a44bc2c7a84934bf661de4c721a2a5ed5f3b9c21556064ac1672e
4
- data.tar.gz: 27eb154e0be5f0b524e723355c1544541b26207f36e49eb372cea7d06e24cdd5
3
+ metadata.gz: 87c6a954ddaf691739b880123048bf3345ece37389404d7a1c7163b27119c0ac
4
+ data.tar.gz: d13c2be795c751e8eb6095e0642560065e4815ff04ac17ffd7605e1092d775ba
5
5
  SHA512:
6
- metadata.gz: f4244bbc93b9c53b55e486d52420653ce8ffd5ee5e8d642b91e25aafc439ea2c48b5622c84167083b93c05ef424f5ea2b5964b7a4696665e92ffab68d13a43b9
7
- data.tar.gz: 58e28a76335c29b19f57c8b68e9c1c6bd00136b753025b230bcabf4a041a872e0efe8a8ebf233a15c7249de018662f4de9c240b27c10701989faeb71231bc866
6
+ metadata.gz: 84e53a85958c58e66417eeadc77fd35332ac0f30b7b59eaef49e39ebeb1cc83d8f3dc906d848c40eb1f4ca08604e36d06efc6b72de0427911a185f705278ce95
7
+ data.tar.gz: 7e42e43664d2329d25f47999bddf7e0c28cbd2ccd36c69ce81e4e94a4e6894a5c905bc5f9ddce41b0ce6770f5f116c369b48c6d2622135e8b2e32221e7d1a6d5
data/CHANGELOG.md CHANGED
@@ -1,7 +1,34 @@
1
1
  ## [Planned]
2
2
 
3
+ - Data Abstraction Layer / Object Relational Model
4
+ - Event Model
5
+ - Plugin / Extension system
6
+
7
+ - Frontend Extensions
8
+ - Tailwind CSS (tailwind-cli)
9
+
10
+ - Persistence Extensions
11
+ - Memory (default)
12
+ - Disk (file)
13
+ - Databases (SQLite, PostgreSQL)
14
+
15
+ ## [Unreleased]
16
+
17
+ ## [0.3.1] - 24 February 2024
18
+
19
+ - Production Mode
20
+ - `porous build production`
21
+ - `porous server`
22
+ - Needs `ssl/cert.pem` and `ssl/key.pem`
23
+ - Binds on :80 and :443
24
+ - Development Mode
25
+ - `porous dev`
26
+ - Binds on :9292
27
+ - Serves favicon from `static/favicon.svg`
28
+
29
+ ## [0.3.0] - 22 February 2024
30
+
3
31
  - WebSockets support
4
- - Production mode
5
32
 
6
33
  ## [0.2.0] - 18 February 2024
7
34
 
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # 🧽 Porous
2
2
 
3
- Porous is a web engine that uses isomorphic Ruby components to build a Progressive Web App. Its use is analogous to a web framework, but the approach is entirely different. You write only
3
+ Porous is a web engine that uses isomorphic Ruby components to build a Progressive Web App. Its use is analogous to a web framework, but the approach is entirely different. You write *only* the code that is *unique to your application* and the engine takes care of the rest!
4
4
 
5
- This project is a work-in-progress and is not yet even in the Proof of Concept phase. However, if you are interested in a full-stack, everything included solution, that only requires you to use one language (that is arguably easy and enjoyable to write) then feel free to follow this project.
5
+ This project is a **work-in-progress** and is not yet even in the Proof of Concept phase. However, if you are interested in a full-stack, everything included solution, that only requires you to use one language (that is arguably easy and enjoyable to write) then feel free to follow this project.
6
6
 
7
7
  The closest thing to this I could find was [Volt](https://github.com/voltrb/volt) or [Silica](https://github.com/youchan/silica), neither of which are active or match the overall development flow I'm looking for.
8
8
 
@@ -12,7 +12,7 @@ The closest thing to this I could find was [Volt](https://github.com/voltrb/volt
12
12
  - 🖥️ Server-side rendering (server responds with the entire initial page populated for SEO)
13
13
  - 💻 Client-side rendering (application bundle is served and interactions and subsequent pages are rendered client-side)
14
14
  - 🌄 Serves static files (from `static` folder)
15
- - 🔥 Hot reloading (via HTTP polling and browser refresh)
15
+ - 🔥 Hot reloading (via WebSocket push and browser refresh)
16
16
 
17
17
  ## Design
18
18
 
@@ -42,21 +42,21 @@ Porous is not a framework. You don't build an application with it as a dependenc
42
42
 
43
43
  ## Usage
44
44
 
45
- Porous is still pre-alpha and so is not ready for usage yet, but the general idea is that you would define your application's entities, pages, components and events in Ruby scripts structured in a specific way. Then you would simply run `porous` while pointing it to that folder and it will spin up a Rack-compatible web server for you to use.
45
+ Porous is still pre-alpha and so is not ready for usage yet, but the general idea is that you would define your application's entities, pages, components and events in Ruby scripts structured in a specific way. Then you would simply run `porous server` while pointing it to that folder and it will spin up a Rack-compatible web server for you to use.
46
46
 
47
47
  > ⚠️ Expect any and all APIs to change radically until version 1.0! Hence why it won't be documented or properly tested until things settle to a more stable state.
48
48
 
49
- To start a new Porous project simply `gem install porous` using whichever Ruby environment you want to use (Ruby 3.0+). Then change to that directory and run:
49
+ To start a new Porous project simply `gem install porous` using whichever Ruby environment you want to use (Ruby 3.0+) and then `porous new` with your project name. Then change to that directory and run:
50
50
 
51
- $ porous server
51
+ $ porous dev
52
52
 
53
- By default Porous will run at `localhost:9292`. Now you can edit `pages/home.rb` or add more pages. Files you modify will be hot-reloaded so you can simply open the page in your browser and edit the file. Hot-reloading will be improved once WebSockets support is implemented.
53
+ By default Porous will run at `localhost:9292`. Now you can edit `pages/home.rb` or add more pages. Files you modify will be hot-reloaded, so you can simply open the page in your browser and edit the file.
54
54
 
55
55
  ### Running examples
56
56
 
57
- To test out some example "apps" using Porous you can navigate to the examples folder and in any folder run:
57
+ To test out an example application using Porous you can clone the [Porous website](https://github.com/exastencil/porous.dev) and in that directory:
58
58
 
59
- $ porous server
59
+ $ porous dev
60
60
 
61
61
  ## Development
62
62
 
@@ -18,9 +18,9 @@ module Porous
18
18
  end
19
19
  meta name: 'description', content: props[:description] if props[:description]
20
20
 
21
- script src: '/static/dist/application.js'
22
- script src: '/static/dist/reload.js'
21
+ script src: '/static/dist/application.js', id: 'application'
23
22
  script src: 'https://cdn.tailwindcss.com'
23
+ link rel: 'icon', href: '/static/favicon.svg'
24
24
  end
25
25
 
26
26
  body class: 'bg-gray-50 dark:bg-gray-900' do
@@ -12,47 +12,10 @@ module Porous
12
12
  true
13
13
  end
14
14
 
15
- desc 'build', 'Build static assets'
16
- def build
15
+ desc 'build ENV', 'Build static assets for environment (default: development)'
16
+ def build(env = :development)
17
17
  empty_directory 'static/dist', verbose: false, force: options[:force]
18
- transpile
19
- live_reload
18
+ Porous::Server::Builder.new(env.to_sym).build
20
19
  end
21
-
22
- # rubocop:disable Metrics/BlockLength
23
- no_commands do
24
- def transpile
25
- components = Dir.glob(File.join('{components,pages}', '**', '*.rb')).map do |relative_path|
26
- "require '#{relative_path}'"
27
- end
28
- build_string = "require 'porous'; #{components.join ";"}".gsub '.rb', ''
29
- builder = Opal::Builder.new
30
- builder.build_str build_string, '(inline)'
31
- File.binwrite "#{Dir.pwd}/static/dist/application.js", builder.to_s
32
- end
33
-
34
- # rubocop:disable Metrics/MethodLength
35
- def live_reload
36
- timestamp = Time.now.to_i.to_s
37
- File.write "#{Dir.pwd}/static/dist/timestamp", timestamp
38
- builder = Opal::Builder.new
39
- script = <<-BROWSER
40
- $document.ready do
41
- every 0.1 do
42
- Browser::HTTP.get('/static/dist/timestamp').then do |response|
43
- return unless response.success?
44
- timestamp = response.text.to_i
45
- TIMESTAMP ||= timestamp
46
- $document.location.reload if TIMESTAMP < timestamp
47
- end
48
- end
49
- end
50
- BROWSER
51
- builder.build_str script, '(inline)'
52
- File.binwrite "#{Dir.pwd}/static/dist/reload.js", builder.to_s
53
- end
54
- # rubocop:enable Metrics/MethodLength
55
- end
56
- # rubocop:enable Metrics/BlockLength
57
20
  end
58
21
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Porous
4
+ class CLI < Thor
5
+ check_unknown_options!
6
+
7
+ namespace :dev
8
+
9
+ desc 'dev', 'Starts a Porous development server'
10
+ def dev # rubocop:todo Metrics/MethodLength, Metrics/AbcSize
11
+ empty_directory 'static/dist', verbose: false, force: options[:force]
12
+
13
+ Agoo::Log.configure(
14
+ dir: '',
15
+ console: true,
16
+ classic: true,
17
+ colorize: true,
18
+ states: {
19
+ INFO: true,
20
+ DEBUG: false,
21
+ connect: false,
22
+ request: false,
23
+ response: false,
24
+ eval: true,
25
+ push: true
26
+ }
27
+ )
28
+
29
+ Agoo::Server.init 9292, Dir.pwd, thread_count: 1
30
+ Agoo::Server.use Rack::ContentLength
31
+ Agoo::Server.use Rack::Static, urls: ['/static']
32
+ Agoo::Server.use Rack::ShowExceptions
33
+
34
+ # Socket Communication
35
+ $socket ||= Porous::Server::Socket.new
36
+ Agoo::Server.handle nil, '/connect', Porous::Server::Connect.new
37
+ # Server-Side Rendering
38
+ Agoo::Server.handle nil, '**', Porous::Server::Application.new
39
+ Agoo::Server.start
40
+ # Live Reload Builder
41
+ Server::Builder.new.build.start
42
+ end
43
+ end
44
+ end
@@ -6,42 +6,42 @@ module Porous
6
6
 
7
7
  namespace :server
8
8
 
9
- desc 'server [OPTIONS]', 'Starts Porous server'
10
- method_option :port,
11
- aliases: :p,
12
- type: :numeric,
13
- default: 9292,
14
- desc: 'The port Porous will listen on'
9
+ desc 'server [OPTIONS]', 'Starts Porous server in production mode'
10
+ def server # rubocop:todo Metrics/MethodLength
11
+ Agoo::Log.configure(dir: '',
12
+ console: true,
13
+ classic: true,
14
+ colorize: true,
15
+ states: {
16
+ INFO: true,
17
+ DEBUG: false,
18
+ connect: true,
19
+ request: true,
20
+ response: false,
21
+ eval: false,
22
+ push: false
23
+ })
15
24
 
16
- method_option :host,
17
- aliases: :h,
18
- type: :string,
19
- default: 'localhost',
20
- desc: 'The host address Porous will bind to'
25
+ Agoo::Server.init(
26
+ 80, '.',
27
+ thread_count: 0,
28
+ ssl_cert: 'ssl/cert.pem',
29
+ ssl_key: 'ssl/key.pem',
30
+ bind: [
31
+ 'http://127.0.0.1:80',
32
+ 'https://127.0.0.1:443'
33
+ ]
34
+ )
35
+ Agoo::Server.use Rack::ContentLength
36
+ Agoo::Server.use Rack::Static, urls: ['/static']
21
37
 
22
- MONITORING = %w[components pages].freeze
38
+ # Socket Communication
39
+ $socket ||= Porous::Server::Socket.new
40
+ Agoo::Server.handle nil, '/connect', Porous::Server::Connect.new
41
+ # Server-Side Rendering
42
+ Agoo::Server.handle nil, '**', Porous::Server::Application.new
23
43
 
24
- def server
25
- MONITORING.each { |path| FileUtils.mkdir_p path }
26
- build
27
- start_live_reload
28
- Rackup::Server.start environment: 'none', app: Porous::Server.new
29
- end
30
-
31
- no_commands do
32
- def start_live_reload
33
- opts = { only: /\.rb$/, relative: true }
34
- @listener = Listen.to(*MONITORING, opts) do |modified, added, _removed|
35
- # Load for server
36
- (modified + added).each do |file|
37
- load File.expand_path("#{Dir.pwd}/#{file}")
38
- end
39
- # Rebuild for browser
40
- Thread.new { build }
41
- end
42
- @listener.start
43
- at_exit { @listener.stop }
44
- end
44
+ Agoo::Server.start
45
45
  end
46
46
  end
47
47
  end
@@ -1 +1,2 @@
1
1
  static/dist
2
+ ssl
@@ -1,7 +1,21 @@
1
1
  # <%= config[:project_name] %>
2
2
 
3
+ ## Development
4
+
3
5
  ```sh
4
- $ porous run
6
+ $ porous dev
5
7
  ```
6
8
 
7
- Go to [http://localhost:8080/](http://localhost:8080/)
9
+ Go to [http://localhost:9292/](http://localhost:9292/)
10
+
11
+ ## Production
12
+
13
+ Place your SSL certificate in `ssl`:
14
+
15
+ - `ssl/cert.pem`
16
+ - `ssl/key.pem`
17
+
18
+ ```sh
19
+ $ porous build production
20
+ $ porous server
21
+ ```
@@ -32,11 +32,7 @@ class Home
32
32
  end
33
33
  a href: 'https://github.com/exastencil/porous', target: '_blank', rel: 'noopener',
34
34
  class: 'flex items-center space-x-2 text-gray-500 dark:text-gray-400' do
35
- svg role: 'img', width: '24', height: '24', class: 'w-5 h-5', viewBox: '0 0 24 24', fill: 'currentColor',
36
- xmlns: 'http://www.w3.org/2000/svg' do
37
- title 'GitHub'
38
- path d: 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'
39
- end
35
+ img class: 'w-8 h-8 text-gray-500', src: '/static/github.svg'
40
36
  span 'View on GitHub'
41
37
  end
42
38
  end
@@ -0,0 +1,4 @@
1
+ <svg role="img" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
2
+ <title>GitHub logo</title>
3
+ <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
4
+ </svg>
data/lib/porous/cli.rb CHANGED
@@ -3,10 +3,15 @@
3
3
  require 'thor'
4
4
 
5
5
  require 'porous'
6
+ require 'porous/server/builder'
7
+ require 'porous/server/socket'
8
+ require 'porous/server/connect'
9
+ require 'porous/server/application'
6
10
 
7
11
  require 'rack'
8
12
  require 'rackup/server'
9
13
 
10
14
  require 'porous/cli/build'
15
+ require 'porous/cli/dev'
11
16
  require 'porous/cli/new'
12
17
  require 'porous/cli/server'
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Porous
4
+ module Server
5
+ class Application
6
+ MONITORING = %w[components pages].freeze
7
+
8
+ def call(env)
9
+ router = Porous::Router.new path: env['PATH_INFO'], query: env['QUERY_STRING']
10
+ route = router.find_route
11
+ page = route[:component].new(route[:params])
12
+
13
+ [200, { 'content-type' => 'text/html' }, [
14
+ Porous::Application.new(
15
+ title: page.page_title,
16
+ description: page.page_description,
17
+ path: env['PATH_INFO'],
18
+ query: env['QUERY_STRING']
19
+ ).to_s
20
+ ]]
21
+ rescue Porous::InvalidRouteError => e
22
+ [404, { 'content-type' => 'text/plain' }, ["404 Page not found\n", e.message]]
23
+ rescue Porous::Error => e
24
+ [500, { 'content-type' => 'text/plain' }, ["500 Internal Server Error\n", e.message]]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opal/builder_scheduler/sequential'
4
+
5
+ module Porous
6
+ module Server
7
+ class Builder
8
+ def initialize(environment = :development)
9
+ @environment = environment
10
+ @build_queue = Queue.new
11
+ @last_build = nil
12
+ @latest_change = Dir.glob(File.join('**', '*.rb')).map { |f| File.mtime f }.max
13
+ end
14
+
15
+ def build
16
+ components = Dir.glob(File.join('**', '*.rb')).map do |relative_path|
17
+ modified = File.mtime relative_path
18
+ @latest_change = modified if modified > @latest_change
19
+ "require '#{relative_path}'"
20
+ end
21
+ build_string = "require 'porous'; #{components.join ";"}; ".gsub '.rb', ''
22
+ build_string << inject_socket_connection
23
+ builder = Opal::Builder.new scheduler: Opal::BuilderScheduler::Sequential, cache: false
24
+ builder.build_str build_string, '(inline)'
25
+ File.binwrite "#{Dir.pwd}/static/dist/application.js", builder.to_s
26
+ @last_build = Time.now
27
+ self
28
+ end
29
+
30
+ # rubocop:disable Metrics/AbcSize
31
+ def start
32
+ loop do
33
+ sleep 0.25
34
+ next unless @build_queue.empty?
35
+
36
+ modified = Dir.glob(File.join('**', '*.rb')).map { |f| File.mtime f }.max
37
+ next unless modified > @last_build
38
+
39
+ @build_queue.push modified
40
+ # Load for server
41
+ Dir.glob(File.join('**', '*.rb')).map { |f| load File.expand_path("#{Dir.pwd}/#{f}") }
42
+
43
+ # Rebuild for browser
44
+ Thread.new { build }.join
45
+
46
+ # Notify clients
47
+ $socket&.public 'build', @last_build.inspect
48
+ @build_queue.clear
49
+ end
50
+ end
51
+ # rubocop:enable Metrics/AbcSize
52
+
53
+ def inject_socket_connection
54
+ uri = @environment == :production ? 'wss://localhost/connect' : 'ws://localhost:9292/connect'
55
+ "$connection = '#{uri}'; "
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Porous
4
+ module Server
5
+ class Connect
6
+ # Only used for WebSocket or SSE upgrades.
7
+ def call(env)
8
+ if env['rack.upgrade?'].nil?
9
+ [404, {}, []]
10
+ else
11
+ $socket ||= Socket.new
12
+ env['rack.upgrade'] = $socket
13
+ [200, {}, []]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Porous
4
+ module Server
5
+ class Socket
6
+ def initialize
7
+ @clients = []
8
+ @mutex = Mutex.new
9
+ end
10
+
11
+ def on_open(client)
12
+ @mutex.synchronize do
13
+ @clients << client
14
+ end
15
+ end
16
+
17
+ def on_close(client)
18
+ @mutex.synchronize do
19
+ @clients.delete(client)
20
+ end
21
+ end
22
+
23
+ def on_drained(_client); end
24
+
25
+ def on_message(client, data)
26
+ client.write("Handler says #{data}")
27
+ end
28
+
29
+ def public(channel, message)
30
+ output = "#{channel}|#{message}"
31
+ @mutex.synchronize do
32
+ @clients.each do |c|
33
+ c.write output
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Porous
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.1'
5
5
  end
data/lib/porous.rb CHANGED
@@ -7,7 +7,7 @@ require 'opal-virtual-dom'
7
7
  Opal.append_path File.expand_path('../opal', __dir__)
8
8
  Opal.append_path File.expand_path(Dir.pwd)
9
9
 
10
- require 'listen'
10
+ require 'agoo'
11
11
 
12
12
  require 'porous/version'
13
13
 
@@ -27,7 +27,6 @@ Dir.glob(File.join('{components,pages}', '**', '*.rb')).each do |relative_path|
27
27
  end
28
28
 
29
29
  require 'porous/application'
30
- require 'porous/server' unless RUBY_ENGINE == 'opal'
31
30
 
32
31
  module Porous
33
32
  class Error < StandardError; end
@@ -11,8 +11,9 @@ module VirtualDOM
11
11
  small source span strong style sub summary sup table tbody td textarea tfoot th
12
12
  thead time title tr track u ul var video wbr].freeze
13
13
 
14
- SVG_TAGS = %w[svg path].freeze
15
-
14
+ SVG_TAGS = %w[animate animateMotion animateTransform circle clipPath defs desc ellipse filter
15
+ foreignObject g image line linearGradient marker mask metadata mpath path pattern
16
+ polygon polyline radialGradient rect set stop svg switch symbol textPath tspan use view].freeze
16
17
  (HTML_TAGS + SVG_TAGS).each do |tag|
17
18
  define_method tag do |params = {}, &block|
18
19
  if params.is_a?(String)
@@ -37,7 +37,7 @@ module Porous
37
37
 
38
38
  def render!
39
39
  if Browser::AnimationFrame.supported?
40
- animation_frame do
40
+ Browser::AnimationFrame.new $window do
41
41
  @root_component.render_if_root
42
42
  end
43
43
  else
data/opal/porous.rb CHANGED
@@ -11,15 +11,6 @@ require 'console'
11
11
  require 'virtual_dom'
12
12
  require 'virtual_dom/support/browser'
13
13
 
14
- VirtualDOM::DOM::HTML_TAGS = %w[a abbr address area article aside audio b base bdi bdo big blockquote body br
15
- button canvas caption cite code col colgroup data datalist dd del details dfn
16
- dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
17
- h6 head header hr html i iframe img input ins kbd keygen label legend li link
18
- main map mark menu menuitem meta meter nav noscript object ol optgroup option
19
- output p param picture pre progress q rp rt ruby s samp script section select
20
- small source span strong style sub summary sup table tbody td textarea tfoot th
21
- thead time title tr track u ul var video wbr svg path].freeze
22
-
23
14
  require 'porous/injection'
24
15
  require 'porous/component/class_methods'
25
16
  require 'porous/component/render'
@@ -38,4 +29,19 @@ end
38
29
 
39
30
  $document.ready do
40
31
  Porous::Application.mount_to($document.body)
32
+ Browser::Socket.new $connection do
33
+ on :open do |_e|
34
+ $console.info 'Connected to server!'
35
+ end
36
+
37
+ on :message do |e|
38
+ channel, content = e.data.split '|'
39
+ case channel
40
+ when 'build'
41
+ $document.location.reload unless content == 'started'
42
+ else
43
+ $console.log e.data
44
+ end
45
+ end
46
+ end
41
47
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: porous
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Exa Stencil
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-18 00:00:00.000000000 Z
11
+ date: 2024-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: listen
14
+ name: agoo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '2.15'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '2.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: opal-browser
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -102,11 +102,13 @@ files:
102
102
  - lib/porous/application.rb
103
103
  - lib/porous/cli.rb
104
104
  - lib/porous/cli/build.rb
105
+ - lib/porous/cli/dev.rb
105
106
  - lib/porous/cli/new.rb
106
107
  - lib/porous/cli/server.rb
107
108
  - lib/porous/cli/template/.gitignore.tt
108
109
  - lib/porous/cli/template/README.md.tt
109
110
  - lib/porous/cli/template/pages/home.rb
111
+ - lib/porous/cli/template/static/github.svg
110
112
  - lib/porous/cli/template/static/hero.png
111
113
  - lib/porous/component.rb
112
114
  - lib/porous/component/class_methods.rb
@@ -117,7 +119,10 @@ files:
117
119
  - lib/porous/page.rb
118
120
  - lib/porous/router.rb
119
121
  - lib/porous/routes.rb
120
- - lib/porous/server.rb
122
+ - lib/porous/server/application.rb
123
+ - lib/porous/server/builder.rb
124
+ - lib/porous/server/connect.rb
125
+ - lib/porous/server/socket.rb
121
126
  - lib/porous/version.rb
122
127
  - lib/virtual_dom/dom.rb
123
128
  - lib/virtual_dom/virtual_node.rb
data/lib/porous/server.rb DELETED
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Porous
4
- class Server
5
- def initialize(*_args)
6
- setup_rack_app
7
- end
8
-
9
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
10
- def setup_rack_app
11
- @rack = Rack::Builder.new do
12
- use Rack::ContentLength
13
- use Rack::Static, urls: ['/static']
14
- use Rack::CommonLogger
15
- use Rack::ShowExceptions
16
- use Rack::Lint
17
- use Rack::TempfileReaper
18
-
19
- run do |env|
20
- router = Porous::Router.new path: env['PATH_INFO'], query: env['QUERY_STRING']
21
- route = router.find_route
22
- page = route[:component].new(route[:params])
23
-
24
- [200, { 'content-type' => 'text/html' }, [
25
- Porous::Application.new(
26
- title: page.page_title,
27
- description: page.page_description,
28
- path: env['PATH_INFO'],
29
- query: env['QUERY_STRING']
30
- ).to_s
31
- ]]
32
- rescue Porous::InvalidRouteError => e
33
- [404, { 'content-type' => 'text/plain' }, ["404 Page not found\n", e.message]]
34
- rescue Porous::Error => e
35
- [500, { 'content-type' => 'text/plain' }, ["500 Internal Server Error\n", e.message]]
36
- end
37
- end
38
- end
39
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
40
-
41
- def call(*args)
42
- @rack.call(*args)
43
- end
44
- end
45
- end