funicular 0.2.1 → 0.4.0

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -0
  3. data/README.md +2 -2
  4. data/Rakefile +23 -15
  5. data/demo/test_chartjs.html +8 -8
  6. data/demo/test_component.html +8 -8
  7. data/demo/test_error_boundary.html +8 -5
  8. data/demo/test_router.html +11 -11
  9. data/demo/tic-tac-toe.html +4 -4
  10. data/docs/architecture.md +80 -30
  11. data/lib/funicular/compiler.rb +13 -13
  12. data/lib/funicular/helpers/picoruby_helper.rb +24 -1
  13. data/lib/funicular/ssr/runtime.rb +3 -0
  14. data/lib/funicular/ssr.rb +2 -1
  15. data/lib/funicular/testing/node_runner.rb +1 -1
  16. data/lib/funicular/vendor/mrbc/VERSION +1 -0
  17. data/lib/funicular/vendor/{picorbc/picorbc.js → mrbc/mrbc.js} +626 -486
  18. data/lib/funicular/vendor/mrbc/mrbc.wasm +0 -0
  19. data/lib/funicular/vendor/picoruby/VERSION +1 -1
  20. data/lib/funicular/vendor/picoruby/debug/init.iife.js +19 -4
  21. data/lib/funicular/vendor/picoruby/debug/picoruby.js +675 -449
  22. data/lib/funicular/vendor/picoruby/debug/picoruby.wasm +0 -0
  23. data/lib/funicular/vendor/picoruby/dist/init.iife.js +19 -4
  24. data/lib/funicular/vendor/picoruby/dist/picoruby.js +2 -2
  25. data/lib/funicular/vendor/picoruby/dist/picoruby.wasm +0 -0
  26. data/lib/funicular/vendor/picoruby-test-node/VERSION +1 -1
  27. data/lib/funicular/vendor/picoruby-test-node/picoruby.js +860 -567
  28. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm +0 -0
  29. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm.map +1 -1
  30. data/lib/funicular/version.rb +1 -1
  31. data/lib/generators/funicular/chat/templates/funicular_chat_component.rb.tt +25 -25
  32. data/lib/tasks/funicular.rake +1 -1
  33. data/minitest/commands_routes_test.rb +97 -0
  34. data/minitest/compiler_test.rb +195 -0
  35. data/minitest/configuration_test.rb +64 -0
  36. data/minitest/dsl_test.rb +237 -0
  37. data/minitest/fixtures/funicular_app/components/greeting_component.rb +2 -2
  38. data/minitest/funicular_test.rb +28 -2
  39. data/minitest/middleware_test.rb +154 -0
  40. data/minitest/picoruby_helper_test.rb +139 -0
  41. data/minitest/route_parser_test.rb +139 -0
  42. data/minitest/schema_test.rb +23 -0
  43. data/minitest/sig_tags_test.rb +30 -0
  44. data/minitest/ssr_test.rb +57 -0
  45. data/minitest/support/rails_stub.rb +59 -0
  46. data/minitest/test_helper.rb +20 -0
  47. data/minitest/testing_test.rb +267 -0
  48. data/minitest/view_context_test.rb +101 -0
  49. data/mrblib/0_tags.rb +62 -0
  50. data/mrblib/component.rb +255 -244
  51. data/mrblib/debug.rb +7 -6
  52. data/mrblib/differ.rb +3 -1
  53. data/mrblib/error_boundary.rb +11 -13
  54. data/mrblib/form_builder.rb +28 -24
  55. data/mrblib/funicular.rb +2 -1
  56. data/mrblib/html_serializer.rb +14 -13
  57. data/mrblib/http.rb +12 -1
  58. data/mrblib/patcher.rb +12 -9
  59. data/mrblib/router.rb +9 -5
  60. data/mrblib/runtime.rb +28 -0
  61. data/mrblib/styles.rb +107 -21
  62. data/mrblib/vdom.rb +90 -9
  63. data/mrblib/view_context.rb +106 -0
  64. data/sig/component.rbs +47 -84
  65. data/sig/form_builder.rbs +2 -1
  66. data/sig/html_serializer.rbs +2 -1
  67. data/sig/http.rbs +1 -0
  68. data/sig/patcher.rbs +1 -1
  69. data/sig/router.rbs +2 -13
  70. data/sig/runtime.rbs +13 -0
  71. data/sig/styles.rbs +19 -7
  72. data/sig/tags.rbs +54 -0
  73. data/sig/vdom.rbs +11 -2
  74. data/sig/view_context.rbs +60 -0
  75. metadata +22 -5
  76. data/lib/funicular/vendor/picorbc/VERSION +0 -1
  77. data/lib/funicular/vendor/picorbc/picorbc.wasm +0 -0
@@ -5,11 +5,11 @@ require "shellwords"
5
5
  module Funicular
6
6
  class Compiler
7
7
  class NodeNotFoundError < StandardError; end
8
- class PicorbcMissingError < StandardError; end
8
+ class MrbcMissingError < StandardError; end
9
9
 
10
- # picorbc.js + picorbc.wasm bundled into the gem at build time by `rake copy_wasm`.
11
- PICORBC_DIR = File.expand_path("vendor/picorbc", __dir__)
12
- PICORBC_JS = File.join(PICORBC_DIR, "picorbc.js")
10
+ # mrbc.js + mrbc.wasm bundled into the gem at build time by `rake copy_wasm`.
11
+ MRBC_DIR = File.expand_path("vendor/mrbc", __dir__)
12
+ MRBC_JS = File.join(MRBC_DIR, "mrbc.js")
13
13
 
14
14
  # Ordered list of application source files under app/funicular/.
15
15
  # Order matters: models -> stores -> components -> initializer, so that
@@ -36,19 +36,19 @@ module Funicular
36
36
  end
37
37
 
38
38
  def compile
39
- check_picorbc_availability!
39
+ check_mrbc_availability!
40
40
  gather_source_files
41
41
  compile_to_mrb
42
42
  end
43
43
 
44
44
  private
45
45
 
46
- def check_picorbc_availability!
47
- unless File.exist?(PICORBC_JS)
48
- raise PicorbcMissingError, <<~ERROR
49
- Vendored picorbc not found at #{PICORBC_JS}.
46
+ def check_mrbc_availability!
47
+ unless File.exist?(MRBC_JS)
48
+ raise MrbcMissingError, <<~ERROR
49
+ Vendored mrbc not found at #{MRBC_JS}.
50
50
 
51
- The funicular gem ships picorbc.js + picorbc.wasm inside the gem
51
+ The funicular gem ships mrbc.js + mrbc.wasm inside the gem
52
52
  package. This file is missing, which likely means the gem was not
53
53
  installed correctly. Try reinstalling:
54
54
 
@@ -61,7 +61,7 @@ module Funicular
61
61
  raise NodeNotFoundError, <<~ERROR
62
62
  Node.js executable not found.
63
63
 
64
- Funicular compiles Ruby to .mrb using a WebAssembly build of picorbc
64
+ Funicular compiles Ruby to .mrb using a WebAssembly build of mrbc
65
65
  which is run via Node.js. Please install Node.js and ensure `node`
66
66
  is on your PATH (or set the NODE environment variable).
67
67
  ERROR
@@ -110,7 +110,7 @@ module Funicular
110
110
  def compile_to_mrb
111
111
  all_files = @source_files.dup
112
112
  all_files << @env_file if @env_file
113
- argv = [node_command, PICORBC_JS]
113
+ argv = [node_command, MRBC_JS]
114
114
  argv << "-g" if debug_mode
115
115
  argv += ["-o", output_file.to_s]
116
116
  argv += all_files.map(&:to_s)
@@ -128,7 +128,7 @@ module Funicular
128
128
  result = system(*argv)
129
129
 
130
130
  unless result
131
- raise "Failed to compile with picorbc. Command: #{Shellwords.join(argv)}"
131
+ raise "Failed to compile with mrbc. Command: #{Shellwords.join(argv)}"
132
132
  end
133
133
 
134
134
  log "Successfully compiled to #{output_file}"
@@ -11,6 +11,11 @@ module Funicular
11
11
  local_dist: "/picoruby/dist/init.iife.js"
12
12
  }.freeze
13
13
 
14
+ LOCAL_VARIANTS = {
15
+ local_debug: "debug",
16
+ local_dist: "dist"
17
+ }.freeze
18
+
14
19
  # Minimal CSS the gem ships for class names it emits itself (e.g.
15
20
  # FormBuilder error states). Read once; see assets/funicular.css.
16
21
  BASE_CSS_PATH = File.expand_path("../assets/funicular.css", __dir__)
@@ -101,12 +106,30 @@ module Funicular
101
106
  end
102
107
  format(CDN_URL_TEMPLATE, version: version)
103
108
  elsif (path = LOCAL_PATHS[source])
104
- path
109
+ local_picoruby_src(path, source)
105
110
  else
106
111
  raise ArgumentError,
107
112
  "Unknown picoruby source: #{source.inspect}. Expected one of #{Funicular::Configuration::SOURCES.inspect}"
108
113
  end
109
114
  end
115
+
116
+ def local_picoruby_src(path, source)
117
+ cache_key = local_picoruby_cache_key(source)
118
+ return path if cache_key.nil?
119
+
120
+ "#{path}?v=#{cache_key}"
121
+ end
122
+
123
+ def local_picoruby_cache_key(source)
124
+ variant = LOCAL_VARIANTS.fetch(source)
125
+ version = Funicular.vendored_wasm_version
126
+ wasm = File.join(Funicular::VENDOR_PICORUBY_DIR, variant, "picoruby.wasm")
127
+ mtime = File.mtime(wasm).to_i
128
+
129
+ [version || Funicular::VERSION, mtime].join("-")
130
+ rescue Errno::ENOENT
131
+ Funicular.vendored_wasm_version || Funicular::VERSION
132
+ end
110
133
  end
111
134
  end
112
135
  end
@@ -21,12 +21,15 @@ module Funicular
21
21
  # few real dependencies exist (vdom before html_serializer; styles and
22
22
  # vdom before component; component before error_boundary).
23
23
  LOAD_ORDER = %w[
24
+ 0_tags
24
25
  environment_inquirer
25
26
  vdom
26
27
  html_serializer
27
28
  differ
28
29
  patcher
29
30
  styles
31
+ runtime
32
+ view_context
30
33
  debug
31
34
  component
32
35
  error_boundary
data/lib/funicular/ssr.rb CHANGED
@@ -30,8 +30,9 @@ module Funicular
30
30
  return { html: "", state: {}, component: nil } unless component_class
31
31
 
32
32
  instance = component_class.new(symbolize_keys(params).merge(props))
33
+ instance.runtime = Funicular::Runtime.new(router)
33
34
  instance.seed_state(state)
34
- html = Funicular::VDOM::HTMLSerializer.serialize(instance.build_vdom)
35
+ html = Funicular::VDOM::HTMLSerializer.serialize(instance.build_vdom, instance.runtime)
35
36
 
36
37
  { html: html, state: state, component: component_class }
37
38
  end
@@ -117,9 +117,9 @@ module Funicular
117
117
 
118
118
  def default_runtime_dir
119
119
  ENV["FUNICULAR_TEST_PICORUBY_DIR"] ||
120
- existing_path(File.join(gem_root, "lib", "funicular", "vendor", "picoruby-test-node")) ||
121
120
  existing_path(File.expand_path("../picoruby/build/picoruby-wasm-test/bin", gem_root)) ||
122
121
  existing_path(File.expand_path("../../build/picoruby-wasm-test/bin", gem_root)) ||
122
+ existing_path(File.join(gem_root, "lib", "funicular", "vendor", "picoruby-test-node")) ||
123
123
  File.join(gem_root, "lib", "funicular", "vendor", "picoruby-test-node")
124
124
  end
125
125
 
@@ -0,0 +1 @@
1
+ 4.0.2