cramp 0.13 → 0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/cramp +17 -0
- data/lib/cramp.rb +1 -1
- data/lib/cramp/abstract.rb +3 -1
- data/lib/cramp/action.rb +9 -0
- data/lib/cramp/callbacks.rb +16 -1
- data/lib/cramp/generators/application.rb +97 -0
- data/lib/cramp/generators/templates/application/Gemfile +32 -0
- data/lib/cramp/generators/templates/application/app/actions/home_action.rb +11 -0
- data/lib/cramp/generators/templates/application/application.rb +36 -0
- data/lib/cramp/generators/templates/application/config.ru +25 -0
- data/lib/cramp/generators/templates/application/config/database.yml +6 -0
- data/lib/cramp/generators/templates/application/config/routes.rb +4 -0
- data/lib/cramp/websocket.rb +2 -37
- data/lib/cramp/websocket/rainbows.rb +44 -0
- data/lib/cramp/websocket/rainbows_backend.rb +7 -39
- metadata +60 -72
data/bin/cramp
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cramp'
|
4
|
+
require 'cramp/generators/application'
|
5
|
+
|
6
|
+
if ['--version', '-v'].include?(ARGV.first)
|
7
|
+
puts "Cramp #{Cramp::VERSION}"
|
8
|
+
exit(0)
|
9
|
+
end
|
10
|
+
|
11
|
+
if ARGV.first != "new"
|
12
|
+
ARGV[0] = "--help"
|
13
|
+
else
|
14
|
+
ARGV.shift
|
15
|
+
end
|
16
|
+
|
17
|
+
Cramp::Generators::Application.start
|
data/lib/cramp.rb
CHANGED
data/lib/cramp/abstract.rb
CHANGED
@@ -10,12 +10,14 @@ module Cramp
|
|
10
10
|
|
11
11
|
class << self
|
12
12
|
def call(env)
|
13
|
-
|
13
|
+
new(env).process
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(env)
|
18
18
|
@env = env
|
19
|
+
@env['websocket.receive_callback'] = method(:_on_data_receive)
|
20
|
+
|
19
21
|
@finished = false
|
20
22
|
end
|
21
23
|
|
data/lib/cramp/action.rb
CHANGED
@@ -51,10 +51,19 @@ module Cramp
|
|
51
51
|
@body.call(result)
|
52
52
|
end
|
53
53
|
|
54
|
+
def render_websocket(body, *)
|
55
|
+
data = ["\x00", body, "\xFF"].map(&method(:encode)) * ''
|
56
|
+
@body.call(data)
|
57
|
+
end
|
58
|
+
|
54
59
|
# Used by SSE
|
55
60
|
def sse_event_id
|
56
61
|
@sse_event_id ||= Time.now.to_i
|
57
62
|
end
|
58
63
|
|
64
|
+
def encode(string, encoding = 'UTF-8')
|
65
|
+
string.respond_to?(:force_encoding) ? string.force_encoding(encoding) : string
|
66
|
+
end
|
67
|
+
|
59
68
|
end
|
60
69
|
end
|
data/lib/cramp/callbacks.rb
CHANGED
@@ -4,10 +4,12 @@ module Cramp
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
class_inheritable_accessor :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :instance_reader => false
|
7
|
+
class_inheritable_accessor :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :on_data_callbacks, :instance_reader => false
|
8
|
+
|
8
9
|
self.before_start_callbacks = []
|
9
10
|
self.on_finish_callbacks = []
|
10
11
|
self.on_start_callback = []
|
12
|
+
self.on_data_callbacks = []
|
11
13
|
end
|
12
14
|
|
13
15
|
module ClassMethods
|
@@ -22,6 +24,10 @@ module Cramp
|
|
22
24
|
def on_start(*methods)
|
23
25
|
self.on_start_callback += methods
|
24
26
|
end
|
27
|
+
|
28
|
+
def on_data(*methods)
|
29
|
+
self.on_data_callbacks += methods
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
def before_start(n = 0)
|
@@ -50,5 +56,14 @@ module Cramp
|
|
50
56
|
EM.next_tick { yield }
|
51
57
|
end
|
52
58
|
|
59
|
+
def _on_data_receive(data)
|
60
|
+
data = data.split(/\000([^\377]*)\377/).select{|d| !d.empty? }.collect{|d| d.gsub(/^\x00|\xff$/, '') }
|
61
|
+
self.class.on_data_callbacks.each do |callback|
|
62
|
+
data.each do |message|
|
63
|
+
EM.next_tick { send(callback, message) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
53
68
|
end
|
54
69
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
require 'active_support/core_ext/string/strip'
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'active_support/core_ext/object/blank'
|
5
|
+
|
6
|
+
module Cramp
|
7
|
+
module Generators
|
8
|
+
|
9
|
+
class Application < Thor::Group
|
10
|
+
include Thor::Actions
|
11
|
+
|
12
|
+
argument :application_path, :type => :string
|
13
|
+
class_option :with_active_record, :type => :boolean, :aliases => "-M", :default => false, :desc => "Configures Active Record"
|
14
|
+
|
15
|
+
def initialize(*args)
|
16
|
+
raise Thor::Error, "No application name supplied. Please run: cramp --help" if args[0].blank?
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.source_root
|
22
|
+
@_source_root ||= File.join(File.dirname(__FILE__), "templates/application")
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.banner
|
26
|
+
"cramp new #{self.arguments.map(&:usage).join(' ')} [options]"
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_root
|
30
|
+
self.destination_root = File.expand_path(application_path, destination_root)
|
31
|
+
valid_const?
|
32
|
+
|
33
|
+
empty_directory '.'
|
34
|
+
FileUtils.cd(destination_root)
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_root_files
|
38
|
+
template 'config.ru'
|
39
|
+
template 'Gemfile'
|
40
|
+
template 'application.rb'
|
41
|
+
|
42
|
+
empty_directory "public"
|
43
|
+
empty_directory "public/javascripts"
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_config
|
47
|
+
empty_directory "config"
|
48
|
+
|
49
|
+
inside "config" do
|
50
|
+
template "routes.rb"
|
51
|
+
template 'database.yml' if active_record?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_home_action
|
56
|
+
empty_directory "app/actions"
|
57
|
+
|
58
|
+
inside "app/actions" do
|
59
|
+
template "home_action.rb"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_models
|
64
|
+
if active_record?
|
65
|
+
empty_directory "app/models"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def active_record?
|
72
|
+
options[:with_active_record]
|
73
|
+
end
|
74
|
+
|
75
|
+
def app_name
|
76
|
+
@app_name ||= File.basename(destination_root)
|
77
|
+
end
|
78
|
+
|
79
|
+
def app_const
|
80
|
+
@app_const ||= "#{app_const_base}::Application"
|
81
|
+
end
|
82
|
+
|
83
|
+
def app_const_base
|
84
|
+
@app_const_base ||= app_name.gsub(/\W/, '_').squeeze('_').camelize
|
85
|
+
end
|
86
|
+
|
87
|
+
def valid_const?
|
88
|
+
if app_const =~ /^\d/
|
89
|
+
raise Thor::Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
|
90
|
+
elsif Object.const_defined?(app_const_base)
|
91
|
+
raise Thor::Error, "Invalid application name #{app_name}, constant #{app_const_base} is already in use. Please choose another application name."
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'cramp'
|
4
|
+
|
5
|
+
# Async webserver for running a cramp application
|
6
|
+
gem 'thin'
|
7
|
+
|
8
|
+
# Rack based routing
|
9
|
+
gem 'http_router'
|
10
|
+
|
11
|
+
# Collection of async-proof rack middlewares - https://github.com/rkh/async-rack.git
|
12
|
+
gem 'async-rack'
|
13
|
+
|
14
|
+
# For async Active Record models
|
15
|
+
<% if active_record? -%>
|
16
|
+
gem 'mysql2', '~> 0.2.11'
|
17
|
+
gem 'activerecord'
|
18
|
+
<% else -%>
|
19
|
+
# gem 'mysql2', '~> 0.2.11'
|
20
|
+
# gem 'activerecord'
|
21
|
+
<% end -%>
|
22
|
+
|
23
|
+
# Using Fibers + async callbacks to emulate synchronous programming
|
24
|
+
# gem 'em-synchrony'
|
25
|
+
|
26
|
+
# Generic interface to multiple Ruby template engines - https://github.com/rtomayko/tilt
|
27
|
+
# gem 'tilt'
|
28
|
+
|
29
|
+
group :development do
|
30
|
+
# Development gems
|
31
|
+
# gem 'ruby-debug19'
|
32
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class HomeAction < Cramp::Action
|
2
|
+
<% if active_record? -%>use_fiber_pool do |pool|
|
3
|
+
# Checkin database connection after each callback
|
4
|
+
pool.generic_callbacks << proc { ActiveRecord::Base.clear_active_connections! }
|
5
|
+
end
|
6
|
+
|
7
|
+
<% end %>def start
|
8
|
+
render "Hello World!"
|
9
|
+
finish
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler"
|
3
|
+
|
4
|
+
module <%= app_const_base %>
|
5
|
+
class Application
|
6
|
+
|
7
|
+
def self.root(path = nil)
|
8
|
+
@_root ||= File.expand_path(File.dirname(__FILE__))
|
9
|
+
path ? File.join(@_root, path.to_s) : @_root
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.env
|
13
|
+
@_env ||= ENV['RACK_ENV'] || 'development'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.routes
|
17
|
+
@_routes ||= eval(File.read('./config/routes.rb'))
|
18
|
+
end
|
19
|
+
|
20
|
+
<% if active_record? %>def self.database_config
|
21
|
+
@_database_config ||= YAML.load(File.read('./config/database.yml')).with_indifferent_access
|
22
|
+
end
|
23
|
+
|
24
|
+
<% end %># Initialize the application
|
25
|
+
def self.initialize!<% if active_record? %>
|
26
|
+
ActiveRecord::Base.configurations = <%= app_const %>.database_config
|
27
|
+
ActiveRecord::Base.establish_connection(<%= app_const %>.env)<% end %>
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Bundler.require(:default, <%= app_const %>.env)
|
34
|
+
|
35
|
+
# Preload application classes
|
36
|
+
Dir['./app/**/*.rb'].each {|f| require f}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require './application'
|
2
|
+
<%= app_const %>.initialize!
|
3
|
+
|
4
|
+
# Development middlewares
|
5
|
+
if <%= app_const %>.env == 'development'
|
6
|
+
use AsyncRack::CommonLogger
|
7
|
+
|
8
|
+
# Enable code reloading on every request
|
9
|
+
use Rack::Reloader, 0
|
10
|
+
|
11
|
+
# Serve assets from /public
|
12
|
+
use Rack::Static, :urls => ["/javascripts"], :root => <%= app_const %>.root(:public)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Running thin :
|
16
|
+
#
|
17
|
+
# bundle exec thin --max-persistent-conns 1024 --timeout 0 -R config.ru start
|
18
|
+
#
|
19
|
+
# Vebose mode :
|
20
|
+
#
|
21
|
+
# Very useful when you want to view all the data being sent/received by thin
|
22
|
+
#
|
23
|
+
# bundle exec thin --max-persistent-conns 1024 --timeout 0 -V -R config.ru start
|
24
|
+
#
|
25
|
+
run <%= app_const %>.routes
|
data/lib/cramp/websocket.rb
CHANGED
@@ -1,47 +1,12 @@
|
|
1
1
|
module Cramp
|
2
|
-
class Websocket <
|
3
|
-
|
4
|
-
|
5
|
-
# TODO : Websockets shouldn't need this in an ideal world
|
6
|
-
include KeepConnectionAlive
|
7
|
-
|
8
|
-
class_inheritable_accessor :on_data_callbacks, :instance_reader => false
|
9
|
-
self.on_data_callbacks = []
|
2
|
+
class Websocket < Action
|
3
|
+
self.transport = :websocket
|
10
4
|
|
11
5
|
class << self
|
12
6
|
def backend=(backend)
|
13
7
|
raise "Websocket backend #{backend} is unknown" unless [:thin, :rainbows].include?(backend.to_sym)
|
14
8
|
require "cramp/websocket/#{backend}_backend.rb"
|
15
9
|
end
|
16
|
-
|
17
|
-
def on_data(*methods)
|
18
|
-
self.on_data_callbacks += methods
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def process
|
23
|
-
@env['websocket.receive_callback'] = method(:_on_data_receive)
|
24
|
-
super
|
25
|
-
end
|
26
|
-
|
27
|
-
def render(body)
|
28
|
-
data = ["\x00", body, "\xFF"].map(&method(:encode)) * ''
|
29
|
-
@body.call(data)
|
30
|
-
end
|
31
|
-
|
32
|
-
def _on_data_receive(data)
|
33
|
-
data = data.split(/\000([^\377]*)\377/).select{|d| !d.empty? }.collect{|d| d.gsub(/^\x00|\xff$/, '') }
|
34
|
-
self.class.on_data_callbacks.each do |callback|
|
35
|
-
data.each do |message|
|
36
|
-
EM.next_tick { send(callback, message) }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
def encode(string, encoding = 'UTF-8')
|
44
|
-
string.respond_to?(:force_encoding) ? string.force_encoding(encoding) : string
|
45
10
|
end
|
46
11
|
|
47
12
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Cramp::Websocket::Rainbows < Rainbows::EventMachine::Client
|
2
|
+
include Cramp::WebsocketExtension
|
3
|
+
|
4
|
+
def receive_data(data)
|
5
|
+
case @state
|
6
|
+
when :websocket
|
7
|
+
callback = @env[WEBSOCKET_RECEIVE_CALLBACK]
|
8
|
+
callback.call(data) if callback
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_read(data)
|
15
|
+
if @state == :headers
|
16
|
+
@hp.add_parse(data) or return want_more
|
17
|
+
@state = :body
|
18
|
+
if 0 == @hp.content_length && !websocket?
|
19
|
+
app_call NULL_IO # common case
|
20
|
+
else # nil or len > 0
|
21
|
+
prepare_request_body
|
22
|
+
end
|
23
|
+
elsif @state == :body && websocket? && @hp.body_eof?
|
24
|
+
@state = :websocket
|
25
|
+
@input.rewind
|
26
|
+
|
27
|
+
handler = @env['HTTP_SEC_WEBSOCKET_KEY1'] &&
|
28
|
+
@env['HTTP_SEC_WEBSOCKET_KEY2'] ? Protocol76 : Protocol75
|
29
|
+
write(handler.new(@env, websocket_url, @buf).handshake)
|
30
|
+
app_call NULL_IO
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
rescue => e
|
35
|
+
handle_error(e)
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_response(status, headers, body, alive)
|
39
|
+
write_headers(status, headers, alive) unless websocket?
|
40
|
+
write_body_each(body)
|
41
|
+
ensure
|
42
|
+
body.close if body.respond_to?(:close)
|
43
|
+
end
|
44
|
+
end
|
@@ -1,40 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
@state = :websocket
|
8
|
-
end
|
9
|
-
|
10
|
-
def receive_data_with_websocket(data)
|
11
|
-
case @state
|
12
|
-
when :websocket
|
13
|
-
callback = @env[WEBSOCKET_RECEIVE_CALLBACK]
|
14
|
-
callback.call(data) if callback
|
15
|
-
else
|
16
|
-
receive_data_without_websocket(data)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
alias_method_chain :receive_data, :websocket
|
21
|
-
end
|
22
|
-
|
23
|
-
class Rainbows::HttpResponse
|
24
|
-
class << self
|
25
|
-
|
26
|
-
def write_with_magic(socket, rack_response, out = [])
|
27
|
-
if socket.websocket?
|
28
|
-
socket.write socket.websocket_upgrade_data
|
29
|
-
socket.websocket_handshake!
|
30
|
-
|
31
|
-
out = nil # To make sure Rainbows! doesn't send back regular HTTP headers
|
32
|
-
end
|
33
|
-
|
34
|
-
write_without_magic(socket, rack_response, out)
|
35
|
-
end
|
36
|
-
|
37
|
-
alias_method_chain :write, :magic
|
38
|
-
end
|
39
|
-
|
1
|
+
# :enddoc:
|
2
|
+
require "rainbows"
|
3
|
+
class Cramp::Websocket
|
4
|
+
# we use autoload since Rainbows::EventMachine::Client should only be
|
5
|
+
# loaded in the worker proceses and we want to be preload_app-friendly
|
6
|
+
autoload :Rainbows, "cramp/websocket/rainbows"
|
40
7
|
end
|
8
|
+
Rainbows::O[:em_client_class] = "Cramp::Websocket::Rainbows"
|
metadata
CHANGED
@@ -1,85 +1,81 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cramp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.14'
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 13
|
9
|
-
version: "0.13"
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Pratik Naik
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2011-07-31 00:00:00 +01:00
|
12
|
+
date: 2011-08-05 00:00:00.000000000 +01:00
|
18
13
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
21
16
|
name: activesupport
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &2156676820 !ruby/object:Gem::Requirement
|
24
18
|
none: false
|
25
|
-
requirements:
|
19
|
+
requirements:
|
26
20
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 21
|
29
|
-
segments:
|
30
|
-
- 3
|
31
|
-
- 0
|
32
|
-
- 9
|
21
|
+
- !ruby/object:Gem::Version
|
33
22
|
version: 3.0.9
|
34
23
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rack
|
38
24
|
prerelease: false
|
39
|
-
|
25
|
+
version_requirements: *2156676820
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rack
|
28
|
+
requirement: &2156676220 !ruby/object:Gem::Requirement
|
40
29
|
none: false
|
41
|
-
requirements:
|
30
|
+
requirements:
|
42
31
|
- - ~>
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 1
|
47
|
-
- 2
|
48
|
-
- 1
|
49
|
-
version: 1.2.1
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.2
|
50
34
|
type: :runtime
|
51
|
-
|
52
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2156676220
|
37
|
+
- !ruby/object:Gem::Dependency
|
53
38
|
name: eventmachine
|
39
|
+
requirement: &2156675640 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.0.0.beta.3
|
45
|
+
type: :runtime
|
54
46
|
prerelease: false
|
55
|
-
|
47
|
+
version_requirements: *2156675640
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: thor
|
50
|
+
requirement: &2156674960 !ruby/object:Gem::Requirement
|
56
51
|
none: false
|
57
|
-
requirements:
|
52
|
+
requirements:
|
58
53
|
- - ~>
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
- 12
|
64
|
-
- 10
|
65
|
-
version: 0.12.10
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.14.6
|
66
56
|
type: :runtime
|
67
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2156674960
|
68
59
|
description: Cramp is a framework for developing asynchronous web applications.
|
69
60
|
email: pratiknaik@gmail.com
|
70
|
-
executables:
|
71
|
-
|
61
|
+
executables:
|
62
|
+
- cramp
|
72
63
|
extensions: []
|
73
|
-
|
74
64
|
extra_rdoc_files: []
|
75
|
-
|
76
|
-
files:
|
65
|
+
files:
|
77
66
|
- MIT-LICENSE
|
78
67
|
- lib/cramp/abstract.rb
|
79
68
|
- lib/cramp/action.rb
|
80
69
|
- lib/cramp/body.rb
|
81
70
|
- lib/cramp/callbacks.rb
|
82
71
|
- lib/cramp/fiber_pool.rb
|
72
|
+
- lib/cramp/generators/application.rb
|
73
|
+
- lib/cramp/generators/templates/application/app/actions/home_action.rb
|
74
|
+
- lib/cramp/generators/templates/application/application.rb
|
75
|
+
- lib/cramp/generators/templates/application/config/database.yml
|
76
|
+
- lib/cramp/generators/templates/application/config/routes.rb
|
77
|
+
- lib/cramp/generators/templates/application/config.ru
|
78
|
+
- lib/cramp/generators/templates/application/Gemfile
|
83
79
|
- lib/cramp/keep_connection_alive.rb
|
84
80
|
- lib/cramp/long_polling.rb
|
85
81
|
- lib/cramp/periodic_timer.rb
|
@@ -87,44 +83,36 @@ files:
|
|
87
83
|
- lib/cramp/sse.rb
|
88
84
|
- lib/cramp/test_case.rb
|
89
85
|
- lib/cramp/websocket/extension.rb
|
86
|
+
- lib/cramp/websocket/rainbows.rb
|
90
87
|
- lib/cramp/websocket/rainbows_backend.rb
|
91
88
|
- lib/cramp/websocket/thin_backend.rb
|
92
89
|
- lib/cramp/websocket.rb
|
93
90
|
- lib/cramp.rb
|
94
91
|
- lib/vendor/fiber_pool.rb
|
95
|
-
|
92
|
+
- bin/cramp
|
93
|
+
has_rdoc: false
|
96
94
|
homepage: http://m.onkey.org
|
97
95
|
licenses: []
|
98
|
-
|
99
96
|
post_install_message:
|
100
97
|
rdoc_options: []
|
101
|
-
|
102
|
-
require_paths:
|
98
|
+
require_paths:
|
103
99
|
- lib
|
104
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
101
|
none: false
|
106
|
-
requirements:
|
107
|
-
- -
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
|
110
|
-
|
111
|
-
- 0
|
112
|
-
version: "0"
|
113
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
107
|
none: false
|
115
|
-
requirements:
|
116
|
-
- -
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
|
119
|
-
segments:
|
120
|
-
- 0
|
121
|
-
version: "0"
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
122
112
|
requirements: []
|
123
|
-
|
124
113
|
rubyforge_project:
|
125
114
|
rubygems_version: 1.6.2
|
126
115
|
signing_key:
|
127
116
|
specification_version: 3
|
128
117
|
summary: Asynchronous web framework.
|
129
118
|
test_files: []
|
130
|
-
|