prism-cli 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/dist/prism.js +4 -0
  3. data/src/prism.rb +4 -0
  4. data/wasm-server.js +1 -1
  5. metadata +118 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e7a243f950f778fcad1038af5d129e2ff685e2172bfc26424ce1f16d29f4ffa
4
- data.tar.gz: bf138cc012d2c8d6c05db2879663fbd5849c95bfeacb1c1af59bcdacdac5bebd
3
+ metadata.gz: cf9061418b9205853974201962b610017b54c97925ee49d9dbe08c04f6c2519b
4
+ data.tar.gz: 817725cad3e6f95ce6c4950e54868bf1de5cbeb29d867dc35a3a148f490bfe8e
5
5
  SHA512:
6
- metadata.gz: 4746c18c3c6d1f20c9374e867da7ec921fcdec51484032f6dc1c3c191a3e9a281feb54f85cc8866264c58e74908b4219c0ca3c9f4dd12e20c6c76bbcf5a57f8e
7
- data.tar.gz: ec5a76c3d1a00f1e92b967de992c6bf4f2c0c81a580dd91050e11e041d8b55fef64b09a259364a4bfb2660ae986d4aa5ac576c08a6bfbf545714bde811ea8b11
6
+ metadata.gz: 853564addef839d98ce9a2bb7f3b47e8c0dd63ab37d6e036ad07f01d8ff7179dbee93a1e2cc54dd4e6adc6f42da1531ed946dc0fda93758ea4bb5ed3b19ca148
7
+ data.tar.gz: 5ec6169ba08f9465a202a048150229246f55b5620fc10761ef0e3b137001ebccea2a8b329c72a02b4261a25f30a270e5a11fc888a169c1beb21f0a74ab01a659
data/dist/prism.js CHANGED
@@ -831,6 +831,10 @@ function rubyVTreeToSnabbdom(rvtree) {
831
831
  args.push(arg.value);
832
832
  }
833
833
 
834
+ if (arg.type === "event") {
835
+ args.push(serializeEvent(event));
836
+ }
837
+
834
838
  if (arg.type === "event_data") {
835
839
  args.push(event[arg.key]);
836
840
  }
data/src/prism.rb CHANGED
@@ -250,6 +250,10 @@ module Prism
250
250
  EventHandler.new(@id, method_name, @args + new_args, @options)
251
251
  end
252
252
 
253
+ def with_event
254
+ EventHandler.new(@id, method_name, @args + [{type: :event}], @options)
255
+ end
256
+
253
257
  def with_event_data(*property_names)
254
258
  new_args = property_names.map { |item| {type: :event_data, key: item } }
255
259
 
data/wasm-server.js CHANGED
@@ -23,5 +23,5 @@ const proxy = http.createServer((req, res) => {
23
23
  res.end();
24
24
  });
25
25
 
26
- proxy.listen(3042, '127.0.0.1');
27
26
  console.log("Listening on localhost:3042");
27
+ proxy.listen(3042, '127.0.0.1');
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prism-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Johnstone
@@ -10,7 +10,123 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-10-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Build frontend web apps with Ruby and Wasm
13
+ description: "\n## Prism\n\nBuild React-style web apps with Ruby and WebAssembly \n\n###
14
+ Introduction\n\nPrism is a tool that uses [mruby](https://github.com/mruby/mruby)
15
+ and [emscripten](https://emscripten.org/) to compile ruby code to WebAssembly. It
16
+ also provides a runtime layer for working with the DOM and events, so you can use
17
+ it make SPAs.\n\n⚡️ Prism is currently in extremely early alpha. Expect bugs, breaking
18
+ API changes, missing functionality and rough edges. ⚡️\n\n### Getting started\n\nPrism
19
+ requires that you have both [mruby](https://github.com/mruby/mruby) and [emscripten](https://emscripten.org/)
20
+ installed and available on your path.\n\nYou can install mruby through your preferred
21
+ package manager, such as homebrew, apt-get or nix.\n\nPackage managers often have
22
+ outdated versions of emscripten, so it's recommended that you install via `emsdk`.
23
+ Instructions are available on the [emscripten website](https://emscripten.org/docs/getting_started/downloads.html).\n\nYou
24
+ can install Prism using `gem install prism-cli`.\n\n### CLI Usage\n\nYou can initialize
25
+ a new Prism app by running `prism init`. This simply creates a hello world sample
26
+ application, by default at `./app.rb` but you can customize the location by providing
27
+ an argument to `prism init`.\n\nYou can then run `prism build` to compile your application.
28
+ You can provide an entrypoint, but `./app.rb` is assumed by default.\n\n`prism build`
29
+ creates a sample html file, a bundle for Prism's runtime JS code, the emscripten
30
+ runtime code and the ruby compiled to Wasm.\n\nTo test your application, you can
31
+ run `prism server` and open `localhost:3042` in your browser. You should see a hello
32
+ world application with an input and some text. You should be able to change the
33
+ input and see the text change.\n\n### Writing a Prism App\n\nPrism apps are written
34
+ in mruby. mruby is a lightweight implementation of Ruby that's suitable for compiling
35
+ to the web.\n\nmruby is similar in many ways to cruby and will be a familiar experience
36
+ for someone who has only used the mainline interpreter. The most notable exception
37
+ is that mruby only supports syntax up to ruby 1.9, which means there are no keyword
38
+ arguments or safe traversal operator.\n\nThere are a number of other samll differences,
39
+ and it's worth reviewing the [mruby limitations documentation](https://github.com/mruby/mruby/blob/master/doc/limitations.md).\n\nIf
40
+ you run `prism init`, it will create a sample application that makes a good starting
41
+ point. This is the code it outputs:\n\n```ruby\nclass HelloWorld < Prism::Component\n
42
+ \ attr_accessor :name\n\n def initialize(name = \"World\")\n @name = name\n
43
+ \ end\n\n def render\n div(\".hello-world\", [\n input(onInput: call(:name=).with_target_data(:value)),\n
44
+ \ div(\"Hello, #{name}\")\n ])\n end\nend\n\nPrism.mount(HelloWorld.new)\n```\n\nLet's
45
+ break this down piece by piece.\n\n```ruby\nclass HelloWorld < Prism::Component\n```\n\nMuch
46
+ like Rails, Prism provides most of it's functionality through inheriting from base
47
+ classes.\n\nThe key concept in Prism is a Component, which should be familiar to
48
+ anyone who has worked with JS frameworks like React.\n\n`Prism::Component` provides
49
+ helper methods for creating virtual dom elements, and for handling events.\n\n```ruby\n
50
+ \ attr_accessor :name\n\n def initialize(name = \"World\")\n @name = name\n
51
+ \ end\n```\n\nThis is fairly standard Ruby, and there's nothing actually unique
52
+ to Prism or mruby going on. Note that we're defining an `attr_accessor` rather than
53
+ just an `attr_reader`, so that we can set the name directly when it changes.\n\n\n```ruby\n
54
+ \ def render\n div(\".hello-world\", [\n input(onInput: call(:name=).with_target_data(:value)),\n
55
+ \ div(\"Hello, #{name}\")\n ])\n end\n```\n\nIt's expected that Prism components
56
+ implement a `#render` method that returns a representation of what the current view
57
+ should be.\n\nThis should be familiar to anyone who has worked with React, Cycle.js
58
+ or Elm. There is a method defined for each different dom element. You can provide
59
+ a class name or id as a string (`\".todo-list-item\"` or `\"#login\"`), an object
60
+ with options to configure the attributes, props, styles, classes and event listeners,
61
+ and an array of child elements.\n\nPrism's virtual dom is powered by `snabddom`,
62
+ a tried and true lightweight JavaScript vdom library. For the most part, the API
63
+ is simply passed through to snabbdom, so it's worth reading the [snabddom docs](https://github.com/mruby/mruby/blob/master/doc/limitations.md).\n\n\n```ruby\n
64
+ \ input(onInput: call(:name=).with_target_data(:value)),\n```\n\nThe most interesting
65
+ line in this example is the event handler for the `input` event.\n\n`Prism::Component`
66
+ defines a `#call` method that you can use to call methods on your component when
67
+ events occur.\n\n`#call` takes a symbol that is the method name to call, and any
68
+ arguments you want passed to the method.\n\nYou can also include data from the event
69
+ or target element using `.with_event_data` and `.with_target_data`. These methods
70
+ can be chained as needed.\n\n\n```ruby\nPrism.mount(HelloWorld.new)\n```\n\nThe
71
+ last line mounts the HelloWorld component. Prism is currently hardcoded to mount
72
+ to an element with id `#root` on load. In future this will be configurable.\n\n\n###
73
+ API\n\n#### **`Prism::Component`**\n\n##### `#div(identifier, options, children),
74
+ #img, #p, ...`\n\nHelpers for creating virtual dom elements. There is a method for
75
+ every type DOM element.\n\nThe arguments are all optional and can be provided in
76
+ any order for convenience.\n\nArguments:\n\n - `identifier` *string, optional*
77
+ - A shorthand for setting the id and classes. E.g. `\"#login\"`, `.alert`, `#header.flex.dark`\n\n
78
+ \ - `options` *object, optional* - Element configuration\n\n - `attrs` *object,
79
+ optional* - Attributes that are set when the element is created. Equivalent to putting
80
+ items directly into the element in the HTML.\n - `props` *object, optional* -
81
+ Props to be set on the object.\n - `style` *object, optional* - Element styles,
82
+ keys are css properties and values are strings.\n - `class` *object, optional*
83
+ - Keys are class names, values are booleans indicating whether or not the class
84
+ is active. An easy way to add or remove classes based on a condition.\n - `on`
85
+ *function, optional* - Keys are browser events (like `click` or `input`), values
86
+ are `Prism::EventHandler` instances. See below on how to create `EventHandler` instances.
87
+ \ Additionally, there are a number of aliases that let you set event handlers directly
88
+ on the `options` object. The full list that is currently aliased is: `onClick`,
89
+ `onChange`, `onInput`, `onMousedown`, `onMouseup`, `onKeydown`, `onKeyup` and `onScroll`\n\n
90
+ \ - `children` *array or string, optional* - Either a string of content for the
91
+ element or an array of children. Each child should either be a string, a virtual
92
+ dom tree, or an instance of a `Prism::Component` with `#render`.\n\n\n##### `#call(method_name,
93
+ *arguments)`\n\nArguments:\n \n - `method_name` *symbol* - The name of the method
94
+ to call when the event occurs. Returns a `Prism::EventHandler`.\n - `*arguments`
95
+ *any, variadic* - You can provide arguments that will be passed to the method after
96
+ the method name. Please note any argument currently needs to be serializable, this
97
+ will change in future.\n\n##### `#prevent_default`\n\nTakes no arguments, returns
98
+ a `Prism::EventHandler` that does nothing but call `event.preventDefault()`.\n\n#####
99
+ `#stop_propagation`\n\nTakes no arguments, returns a `Prism::EventHandler` that
100
+ does nothing but call `event.stopPropagation()`.\n\n\n\n#### **`Prism::EventHandler`**\n\nRepresents
101
+ a handler for an event, with a method to call and arguments to pass. The arguments
102
+ are a mixture of values passed from Ruby and values pulled from the event and targed
103
+ in JS. The order of arguments is based on how the event handler was constructed.\n\n#####
104
+ `#with_args(*args)`\n\nAdds arguments to an existing event handler.\n\n#### `#with_event`\n\nAdd
105
+ an event argument to the handler. When the method is called, a serialized version
106
+ of the event will be passed.\n\n#### `#with_event_data(*properties)`\n\nAdd arguments
107
+ that contain data from the event. The properties should be either a string or a
108
+ symbol. One property you might want to extract from the event is `:key` for `keydown`
109
+ events.\n\n#### `#with_target_data(*properties)`\n\nAdd arguments that contain data
110
+ from the target element. The properties should be either a string or a symbol. You
111
+ could for example extract the `:value` of an `input` or the `:checked` field of
112
+ a tickbox.\n\n#### `#prevent_default`\n\nCalls `.preventDefault()` on the event
113
+ when it occurs.\n\n#### `#stop_propagation`\n\nCalls `.stopPropagation()` on the
114
+ event when it occurs.\n\n#### Examples:\n\n`call(:name=).with_target_data(:value)`
115
+ - calls a setter with the content of the target element\n`call(:goto_page, 5).with_event`
116
+ - calls a method with the number 5 as the first argument and the event data as the
117
+ second\n\n\n### Future\n\nAs mentioned above, Prism is still in extremely early
118
+ development. The following would be nice to have but has yet to be implemented.\n\n
119
+ - support for require\n - transpile modern ruby syntax to 1.9\n - a way for users
120
+ to make their own IO drivers\n - built in support for HTTP\n - compile time improvements\n
121
+ - fallback to asm.js for old browsers\n - rails integration\n - SSR\n - sourcemaps
122
+ for mruby code\n - linting for incompatibilities with cruby\n - elm-reactor style
123
+ dev server\n\nIf you're interested in helping implement any of those features, or
124
+ you want to contribute in any way, please make an issue or a pull request or just
125
+ [get in touch with me](mailto:ncwjohnston@gmail.com).\n\nPrism is currently developed
126
+ by a single person (who also has a lot of other ambitious projects). I would love
127
+ to have some other people to help share the load. There's lots of low hanging fruit
128
+ still to be plucked.\n\n### License\n\nPrism is available under the MIT license.
129
+ Please see the LICENSE file for more details.\n"
14
130
  email: ncwjohnstone@gmail.com
15
131
  executables:
16
132
  - prism