cramp 0.13 → 0.14
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.
- 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
|
-
|