isomorfeus-transport 1.0.0.delta7

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e31570f39250ea91f27fdc953fa0658868e4d56d7cd848483431863acf005d1a
4
+ data.tar.gz: 2d00bbef87e55ff8f5873f3faf603b55c48cb0ac874970f2fccd4bf8978b2dc0
5
+ SHA512:
6
+ metadata.gz: cffbfe276aaf67746cb3f6ec0e8b47333169d0fc60b278cc034bef2ed3684d536dcfffd8038905aa2b97c16ac7bbf8cd6b9db25c9dfc25a4f063acc17be61dac
7
+ data.tar.gz: 667055f7067f7aef78ae133556e75d930ac4782c787b517e5db964834c2e8e0a6998c275de00687a6dbe0823a6463a6fd87d2131486a6a5a2963f7af9e436b9a
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Jan Biedermann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # isomorfeus-transport
2
+
3
+ Transport and PubSub for isomorfeus.
4
+
5
+ ### Community and Support
6
+ At the [Isomorfeus Framework Project](http://isomorfeus.com)
7
+
8
+ ## Installation
9
+ isomorfeus-transport is usually installed with the installer.
10
+ Otherwise add to your Gemfile:
11
+ ```ruby
12
+ gem 'isomorfeus-transport'
13
+ ```
14
+ and bundle install/update
15
+
16
+ ## Server Side Rendering
17
+ `yarn add ws`
18
+
19
+ The 'ws' module then needs to be imported in application_ssr.js:
20
+ ```
21
+ import WebSocket from 'ws';
22
+ global.WebSocket = WebSocket;
23
+ ```
24
+
25
+ ## Configuration options
26
+
27
+ Client and Server:
28
+ - Isomorfeus.api_websocket_path - path for server side endpoint, default: `/isomorfeus/api/websocket`
29
+
30
+ Server only:
31
+ - Isomorfeus.middlewares - all the rack middlewares to load
32
+
33
+
34
+ ## LucidChannel
35
+
36
+ Isomorfeus-transport provides the LucidChannel::Mixin and LucidChannel::Base class.
37
+ These can be used for subscriptions and publishing messages.
38
+
39
+ ### Subscriptions
40
+ ```ruby
41
+ class MyChannel < LucidChannel::Base
42
+ end
43
+
44
+ # subscribe to channel
45
+ MyChannel.subscribe
46
+
47
+ # unsubscribe
48
+ MyChannel.unsubscribe
49
+ ```
50
+
51
+ ### Processing messages
52
+ ```ruby
53
+ class MyChannel < LucidChannel::Base
54
+ on_message do |message|
55
+ puts "received: " + message
56
+ end
57
+ end
58
+ ```
59
+
60
+ ### Sending mesages
61
+ ```ruby
62
+ MyChannel.send_message('uiuiui')
63
+ ```
@@ -0,0 +1,44 @@
1
+ if RUBY_ENGINE == 'opal'
2
+ require 'json'
3
+ require 'isomorfeus/config'
4
+ require 'isomorfeus/execution_environment'
5
+ require 'isomorfeus/transport/version'
6
+ require 'isomorfeus/transport/config'
7
+ require 'isomorfeus/transport/request_agent'
8
+ require 'isomorfeus/transport/client_processor'
9
+ require 'isomorfeus/transport/websocket'
10
+ require 'isomorfeus/transport'
11
+ require 'lucid_channel/mixin'
12
+ require 'lucid_channel/base'
13
+ Isomorfeus::Transport.init!
14
+ else
15
+ require 'base64'
16
+ require 'digest'
17
+ require 'socket'
18
+ require 'oj'
19
+ require 'websocket/driver'
20
+ require 'active_support'
21
+ require 'iodine'
22
+ require 'isomorfeus/config'
23
+ require 'isomorfeus/promise'
24
+ require 'isomorfeus/transport/version'
25
+ require 'isomorfeus/transport/config'
26
+ require 'isomorfeus/transport/middlewares'
27
+ require 'isomorfeus/transport/request_agent'
28
+ require 'isomorfeus/transport/server_processor'
29
+ require 'isomorfeus/transport/server_socket_processor'
30
+ require 'isomorfeus/transport/websocket'
31
+ require 'isomorfeus/handler'
32
+ require 'isomorfeus/transport/rack_middleware'
33
+ Opal.append_path(__dir__.untaint) unless Opal.paths.include?(__dir__.untaint)
34
+
35
+ require 'isomorfeus/transport/middlewares'
36
+
37
+ Isomorfeus.add_middleware(Isomorfeus::Transport::RackMiddleware)
38
+
39
+ if Dir.exist?(File.join('app', 'isomorfeus'))
40
+ $LOAD_PATH.unshift(File.expand_path(File.join('app', 'isomorfeus', 'handlers')))
41
+ elsif Dir.exist?(File.join('isomorfeus'))
42
+ $LOAD_PATH.unshift(File.expand_path(File.join('isomorfeus', 'handlers')))
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ module Isomorfeus
2
+ module Handler
3
+ # for autoloader
4
+ end
5
+ end
@@ -0,0 +1,141 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ class << self
4
+ attr_accessor :socket
5
+
6
+ def delay(ms = 1000, &block)
7
+ `setTimeout(#{block.to_n}, ms)`
8
+ end
9
+
10
+ def init!
11
+ @requests_in_progress = { requests: {}, agent_ids: {} }
12
+ @socket = nil
13
+ connect if Isomorfeus.on_browser?
14
+ end
15
+
16
+ def connect
17
+ return if @socket && @socket.ready_state < 2
18
+ if Isomorfeus.on_browser?
19
+ window_protocol = `window.location.protocol`
20
+ ws_protocol = window_protocol == 'https:' ? 'wss:' : 'ws:'
21
+ ws_url = "#{ws_protocol}#{`window.location.host`}#{Isomorfeus.api_websocket_path}"
22
+ else
23
+ ws_url = Isomorfeus::TopLevel.transport_ws_url
24
+ end
25
+ @socket = Isomorfeus::Transport::Websocket.new(ws_url)
26
+ @socket.on_error do
27
+ @socket.close
28
+ delay do
29
+ Isomorfeus::Transport.connect
30
+ end
31
+ end
32
+ @socket.on_message do |event|
33
+ json_hash = `Opal.Hash.$new(JSON.parse(event.data))`
34
+ Isomorfeus::Transport::ClientProcessor.process(json_hash)
35
+ end
36
+ true
37
+ end
38
+
39
+ def disconnect
40
+ @socket.close if @socket
41
+ @socket = nil
42
+ end
43
+
44
+ def promise_send_path(*path, &block)
45
+ request = {}
46
+ path.inject(request) do |memo, key|
47
+ memo[key] = {}
48
+ end
49
+ Isomorfeus::Transport.promise_send_request(request, &block)
50
+ end
51
+
52
+ def promise_send_request(request, &block)
53
+ if request_in_progress?(request)
54
+ agent = get_agent_for_request_in_progress(request)
55
+ else
56
+ agent = Isomorfeus::Transport::RequestAgent.new(request)
57
+ if block_given?
58
+ agent.promise.then do |response|
59
+ block.call(response)
60
+ end
61
+ end
62
+ register_request_in_progress(request, agent.id)
63
+ @socket.send(`JSON.stringify(#{{request: { agent_ids: { agent.id => request }}}.to_n})`)
64
+ end
65
+ agent.promise
66
+ end
67
+
68
+ def send_notification(processor_class, message)
69
+ @socket.send(`JSON.stringify(#{{notification: { class: processor_class.to_s, message: message}}.to_n})`)
70
+ true
71
+ end
72
+
73
+ def subscribe(processor_class, &block)
74
+ request = { subscribe: true, class: processor_class.to_s }
75
+ if request_in_progress?(request)
76
+ agent = get_agent_for_request_in_progress(request)
77
+ else
78
+ agent = Isomorfeus::Transport::RequestAgent.new(request)
79
+ register_request_in_progress(request, agent.id)
80
+ @socket.send(`JSON.stringify(#{{subscribe: { agent_ids: { agent.id => request }}}.to_n})`)
81
+ end
82
+ result_promise = agent.promise.then do |response|
83
+ response[:agent_response]
84
+ end
85
+ if block_given?
86
+ result_promise = result_promise.then do |response|
87
+ block.call(response)
88
+ end
89
+ end
90
+ result_promise
91
+ end
92
+
93
+ def unsubscribe(processor_class, &block)
94
+ request = { unsubscribe: true, class: processor_class.to_s }
95
+ if request_in_progress?(request)
96
+ agent = get_agent_for_request_in_progress(request)
97
+ else
98
+ agent = Isomorfeus::Transport::RequestAgent.new(request)
99
+ register_request_in_progress(request, agent.id)
100
+ @socket.send(`JSON.stringify(#{{unsubscribe: { agent_ids: { agent.id => request }}}.to_n})`)
101
+ end
102
+ result_promise = agent.promise.then do |response|
103
+ response[:agent_response]
104
+ end
105
+ if block_given?
106
+ result_promise = result_promise.then do |response|
107
+ block.call(response)
108
+ end
109
+ end
110
+ result_promise
111
+ end
112
+
113
+ def busy?
114
+ @requests_in_progress.size != 0
115
+ end
116
+
117
+ def requests_in_progress
118
+ @requests_in_progress
119
+ end
120
+
121
+ def request_in_progress?(request)
122
+ @requests_in_progress[:requests].key?(request)
123
+ end
124
+
125
+ def get_agent_for_request_in_progress(request)
126
+ agent_id = @requests_in_progress[:requests][request]
127
+ Isomorfeus::Transport::RequestAgent.get(agent_id)
128
+ end
129
+
130
+ def register_request_in_progress(request, agent_id)
131
+ @requests_in_progress[:requests][request] = agent_id
132
+ @requests_in_progress[:agent_ids][agent_id] = request
133
+ end
134
+
135
+ def unregister_request_in_progress(agent_id)
136
+ request = @requests_in_progress[:agent_ids].delete(agent_id)
137
+ @requests_in_progress[:requests].delete(request)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,26 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ class ClientProcessor
4
+ def self.process(json_hash)
5
+ if json_hash.key?(:response)
6
+ process_response(json_hash)
7
+ elsif json_hash.key?(:notification)
8
+ process_notification(json_hash)
9
+ end
10
+ end
11
+
12
+ def self.process_notification(notification_hash)
13
+ processor_class = "::#{notification_hash[:notification][:class]}".constantize
14
+ processor_class.process_message(notification_hash[:notification][:message])
15
+ end
16
+
17
+ def self.process_response(response_hash)
18
+ response_hash[:response][:agent_ids].keys.each do |agent_id|
19
+ agent = Isomorfeus::Transport::RequestAgent.get!(agent_id)
20
+ Isomorfeus::Transport.unregister_request_in_progress(agent_id)
21
+ agent.promise.resolve(agent_response: response_hash[:response][:agent_ids][agent_id], full_response: response_hash)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ module Isomorfeus
2
+ # available settings
3
+
4
+ if RUBY_ENGINE == 'opal'
5
+ add_client_option(:api_websocket_path)
6
+ else
7
+ # defaults
8
+ class << self
9
+ attr_accessor :api_websocket_path
10
+ attr_accessor :middlewares
11
+
12
+ def add_middleware(middleware)
13
+ Isomorfeus.middlewares << middleware unless Isomorfeus.middlewares.include?(middleware)
14
+ end
15
+
16
+ def insert_middleware_after(existing_middleware, new_middleware)
17
+ index_of_existing = Isomorfeus.middlewares.index(existing_middleware)
18
+ unless Isomorfeus.middlewares.include?(new_middleware)
19
+ if index_of_existing
20
+ Isomorfeus.middlewares.insert(index_of_existing + 1, new_middleware)
21
+ else
22
+ Isomorfeus.middlewares << new_middleware
23
+ end
24
+ end
25
+ end
26
+
27
+ def insert_middleware_before(existing_middleware, new_middleware)
28
+ index_of_existing = Isomorfeus.middlewares.index(existing_middleware)
29
+ unless Isomorfeus.middlewares.include?(new_middleware)
30
+ if index_of_existing
31
+ Isomorfeus.middlewares.insert(index_of_existing, new_middleware)
32
+ else
33
+ Isomorfeus.middlewares << new_middleware
34
+ end
35
+ end
36
+ end
37
+ end
38
+ self.middlewares = Set.new
39
+ end
40
+
41
+ self.api_websocket_path = '/isomorfeus/api/websocket'
42
+ end
@@ -0,0 +1,11 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ module Middlewares
4
+ def use_isomorfeus_middlewares
5
+ Isomorfeus.middlewares.each do |isomorfeus_middleware|
6
+ use isomorfeus_middleware
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isomorfeus
4
+ module Transport
5
+ class RackMiddleware
6
+ include Isomorfeus::Transport::ServerProcessor
7
+
8
+ WS_RESPONSE = [0, {}, []]
9
+
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ if env['PATH_INFO'] == Isomorfeus.api_websocket_path
16
+ user = defined?(Warden::Manager) ? env['warden'].user : nil
17
+ if env['rack.upgrade?'] == :websocket
18
+ env['rack.upgrade'] = Isomorfeus::Transport::ServerSocketProcessor.new(env['rack.session'], user)
19
+ end
20
+ WS_RESPONSE
21
+ else
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ class RequestAgent
4
+ def self.agents
5
+ @_agents ||= {}
6
+ end
7
+
8
+ def self.get(object_id)
9
+ agents[object_id]
10
+ end
11
+
12
+ def self.get!(object_id)
13
+ agents.delete(object_id.to_s)
14
+ end
15
+
16
+ attr_reader :id
17
+ attr_reader :promise
18
+ attr_reader :request
19
+
20
+ def initialize(request = nil)
21
+ @id = object_id.to_s
22
+ self.class.agents[@id] = self
23
+ @promise = Promise.new
24
+ @request = request
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Isomorfeus
4
+ module Transport
5
+ module ServerProcessor
6
+ def process_request(client, session_id, current_user, request)
7
+ response = { response: { agent_ids: {}} }
8
+
9
+ if request.key?('request') && request['request'].key?('agent_ids')
10
+ request['request']['agent_ids'].keys.each do |agent_id|
11
+ request['request']['agent_ids'][agent_id].keys.each do |key|
12
+ handler = "::#{key.underscore.camelize}Handler".constantize
13
+ if handler
14
+ response[:response][:agent_ids][agent_id] = handler.new.process_request(client, session_id, current_user, request['request']['agent_ids'][agent_id][key], response)
15
+ else
16
+ response[:response][:agent_ids][agent_id] = { error: { key => 'No such handler!'}}
17
+ end
18
+ end
19
+ end
20
+ elsif request.key?('notification')
21
+ if request['notification'].key?('class')
22
+ client.publish(request['notification']['class'], Oj.dump({ 'notification' => request['notification'] }, mode: :strict))
23
+ else
24
+ response[:response] = 'No such thing!'
25
+ end
26
+ elsif request.key?('subscribe') && request['subscribe'].key?('agent_ids')
27
+ agent_id = request['subscribe']['agent_ids'].keys.first
28
+ channel = request['subscribe']['agent_ids'][agent_id]['class']
29
+ if channel
30
+ client.subscribe(channel)
31
+ response[:response][:agent_ids][agent_id] = { success: channel }
32
+ else
33
+ response[:response][:agent_ids][agent_id] = { error: "No such thing!"}
34
+ end
35
+ elsif request.key?('unsubscribe') && request['unsubscribe'].key?('agent_ids')
36
+ agent_id = request['unsubscribe']['agent_ids'].keys.first
37
+ channel = request['unsubscribe']['agent_ids'][agent_id]['class']
38
+ if channel
39
+ client.unsubscribe(channel)
40
+ response[:response][:agent_ids][agent_id] = { success: channel }
41
+ else
42
+ response[:response][:agent_ids][agent_id] = { error: 'No such thing!'}
43
+ end
44
+ else
45
+ response[:response] = 'No such thing!'
46
+ end
47
+ response
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ class ServerSocketProcessor
4
+ include Isomorfeus::Transport::ServerProcessor
5
+
6
+ def initialize(session_id, user)
7
+ @session_id = session_id
8
+ @user = user
9
+ end
10
+
11
+ def on_message(client, data)
12
+ request_hash = Oj.load(data, mode: :strict)
13
+ result = process_request(client, @session_id, @user, request_hash)
14
+ client.write Oj.dump(result, mode: :strict)
15
+ end
16
+
17
+ def on_close(client)
18
+ # nothing for now
19
+ end
20
+
21
+ def on_open(client)
22
+ # nothing for now
23
+ end
24
+
25
+ def on_shutdown(client)
26
+ # nothing for now
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ VERSION = '1.0.0.delta7'
4
+ end
5
+ end
@@ -0,0 +1,115 @@
1
+ module Isomorfeus
2
+ module Transport
3
+ class Websocket
4
+ attr_reader :url
5
+
6
+ if RUBY_ENGINE == 'opal'
7
+ CONNECTING = 0
8
+ OPEN = 1
9
+ CLOSING = 2
10
+ CLOSED = 3
11
+
12
+ class SendError < StandardError; end
13
+
14
+ def initialize(url, protocols = nil)
15
+ @url = url
16
+ @native_websocket = if protocols
17
+ `new Opal.global.WebSocket(url, protocols)`
18
+ else
19
+ `new Opal.global.WebSocket(url)`
20
+ end
21
+ end
22
+
23
+ def close
24
+ @native_websocket.JS.close
25
+ nil
26
+ end
27
+
28
+ def on_close(&block)
29
+ @native_websocket.JS[:onclose] = `function(event) { block.$call(event); }`
30
+ end
31
+
32
+ def on_error(&block)
33
+ @native_websocket.JS[:onerror] = `function(event) { block.$call(event); }`
34
+ end
35
+
36
+ def on_message(&block)
37
+ @native_websocket.JS[:onmessage] = `function(event) { block.$call(event); }`
38
+ end
39
+
40
+ def send(data)
41
+ case ready_state
42
+ when OPEN then @native_websocket.JS.send(data)
43
+ when CONNECTING then Isomorfeus::Transport.delay(50) { send(data) }
44
+ when CLOSING then raise SendError.new('Cant send, connection is closing!')
45
+ when CLOSED then raise SendError.new('Cant send, connection is closed!')
46
+ end
47
+ end
48
+ alias_method :write, :send
49
+
50
+ private
51
+
52
+ def ready_state
53
+ @native_websocket.JS[:readyState]
54
+ end
55
+ else
56
+ def initialize(url, protocols = nil)
57
+ @url = url
58
+ parsed_url = URI.parse(url)
59
+ host = parsed_url.host
60
+ port = parsed_url.port
61
+ @socket = TCPSocket.new(host, port)
62
+ @driver = ::WebSocket::Driver.client(self)
63
+ @driver.on(:close, &method(:internal_on_close))
64
+
65
+ @thread = Thread.new do
66
+ begin
67
+ while data = @sock.readpartial(512)
68
+ @driver.parse(data)
69
+ end
70
+ end
71
+ end
72
+
73
+ @driver.start
74
+ end
75
+
76
+ def close
77
+ @driver.close
78
+ @thread.kill
79
+ end
80
+
81
+ def on_close(&block)
82
+ @on_close_block = block
83
+ end
84
+
85
+ def on_error(&block)
86
+ @driver.on(:error, block)
87
+ end
88
+
89
+ def on_message(&block)
90
+ @on_message_block = block
91
+ end
92
+
93
+ def on_open(&block)
94
+ @driver.on(:open, block)
95
+ end
96
+
97
+ def protocol
98
+ @driver.protocol
99
+ end
100
+
101
+ def send(data)
102
+ @socket.write(data)
103
+ end
104
+ alias_method :write, :send
105
+
106
+ private
107
+
108
+ def internal_on_close(event)
109
+ @on_close_block.call(event)
110
+ @thread.kill
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,5 @@
1
+ module LucidChannel
2
+ class Base
3
+ include LucidChannel::Mixin
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module LucidChannel
2
+ module Mixin
3
+ def self.included(base)
4
+ base.instance_exec do
5
+ def process_message(message)
6
+ if @message_processor
7
+ @message_processor.call(message)
8
+ else
9
+ puts "#{self} received: #{message}, but no processor defined!"
10
+ end
11
+ end
12
+
13
+ def on_message(&block)
14
+ @message_processor = block
15
+ end
16
+
17
+ def send_message(message)
18
+ Isomorfeus::Transport.send_notification(self, message)
19
+ end
20
+
21
+ def subscribe
22
+ Isomorfeus::Transport.subscribe(self)
23
+ end
24
+
25
+ def unsubscribe
26
+ Isomorfeus::Transport.unsubscribe(self)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: isomorfeus-transport
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.delta7
5
+ platform: ruby
6
+ authors:
7
+ - Jan Biedermann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: iodine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.7.32
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.7.32
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '3.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '3.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: opal
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.11.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.11.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: isomorfeus-redux
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.0.7
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.0.7
83
+ - !ruby/object:Gem::Dependency
84
+ name: isomorfeus-react
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 16.8.7
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 16.8.7
97
+ - !ruby/object:Gem::Dependency
98
+ name: websocket-driver
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.7.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.7.0
111
+ description: Various transport options for Isomorfeus.
112
+ email: jan@kursator.de
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - LICENSE
118
+ - README.md
119
+ - lib/isomorfeus-transport.rb
120
+ - lib/isomorfeus/handler.rb
121
+ - lib/isomorfeus/transport.rb
122
+ - lib/isomorfeus/transport/client_processor.rb
123
+ - lib/isomorfeus/transport/config.rb
124
+ - lib/isomorfeus/transport/middlewares.rb
125
+ - lib/isomorfeus/transport/rack_middleware.rb
126
+ - lib/isomorfeus/transport/request_agent.rb
127
+ - lib/isomorfeus/transport/server_processor.rb
128
+ - lib/isomorfeus/transport/server_socket_processor.rb
129
+ - lib/isomorfeus/transport/version.rb
130
+ - lib/isomorfeus/transport/websocket.rb
131
+ - lib/lucid_channel/base.rb
132
+ - lib/lucid_channel/mixin.rb
133
+ homepage: http://isomorfeus.com
134
+ licenses:
135
+ - MIT
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">"
149
+ - !ruby/object:Gem::Version
150
+ version: 1.3.1
151
+ requirements: []
152
+ rubygems_version: 3.0.3
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Various transport options for Isomorfeus.
156
+ test_files: []