#!/usr/bin/env ruby TEMPLATE = <<-TEMPLATE.strip class HelloWorld < Prism::Component attr_accessor :name def initialize(name = "World") @name = name end def render div(".hello-world", [ input(onInput: call(:name=).with_target_data(:value)), div("Hello, \#{name}") ]) end end Prism.mount(HelloWorld.new) TEMPLATE HTML_TEMPLATE = <<-HTML.strip Hello World
HTML def init(path = "app.rb") fail "#{path} already exists" if File.exist?(path) File.write(path, TEMPLATE) # TODO - there's a race condition here where the file is created between the previous statement and this one puts "Created new Prism app at app.rb\n\nRun prism build #{path} to compile your app." end def build(files) mrbc_path = `which mrbc`.split("\n").first emcc_path = `which emcc`.split("\n").first if (!mrbc_path || !emcc_path) puts "Error: Please ensure you have mruby and emscripten installed and available on the $PATH.\n\n mrbc: #{mrbc_path || 'Not found!'}\n emcc: #{emcc_path || 'Not found! Do you need to source emsdk_env.sh?'}" exit 1 end all_files = ["#{__dir__}/../src/prism.rb"] + files bundle = all_files.map { |f| File.read(f) }.join("\n") `mkdir -p build` Dir.chdir("build") File.write("./bundle.rb", bundle) puts "Compiling ruby code to mruby bytecode..." `mrbc -Bbundle bundle.rb` `cp #{__dir__}/../main.c main.c` puts "Compiling to Wasm..." ` emcc \ -s ALLOW_MEMORY_GROWTH=1 \ -s EXPORTED_FUNCTIONS="['_main', '_render', '_dispatch', '_event']" \ -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' \ -s WASM=1 \ -I #{__dir__}/../mruby/include \ -g4 \ main.c \ #{__dir__}/../mruby/build/emscripten/lib/libmruby.a \ -o bundle.js ` `cp #{__dir__}/../dist/prism.js ./prism.js` File.write("./index.html", HTML_TEMPLATE) unless File.exists?("./index.html") `rm bundle.c bundle.rb main.c` puts "Compiled to build/" end def server Dir.chdir("build") `node #{__dir__}/../wasm-server.js` end def help puts <<-HEREDOC.strip Usage: prism [options] Commands: init initializes a new prism application build builds a prism application server HEREDOC end command, *rest = ARGV case command when "init" init when "build" rest = ["app.rb"] if rest.empty? build(rest) when "server" server else help end