jason-rails 0.3.0 → 0.4.0
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 +4 -4
- data/Gemfile.lock +34 -0
- data/README.md +6 -9
- data/app/assets/config/jason_engine_manifest.js +1 -0
- data/app/assets/images/jason/engine/.keep +0 -0
- data/app/assets/stylesheets/jason/engine/application.css +15 -0
- data/app/controllers/jason/api_controller.rb +36 -0
- data/app/helpers/jason/engine/application_helper.rb +6 -0
- data/app/jobs/jason/engine/application_job.rb +6 -0
- data/app/mailers/jason/engine/application_mailer.rb +8 -0
- data/app/models/jason/engine/application_record.rb +7 -0
- data/app/views/layouts/jason/engine/application.html.erb +15 -0
- data/client/babel.config.js +13 -0
- data/client/lib/JasonProvider.d.ts +5 -4
- data/client/lib/JasonProvider.js +30 -3
- data/client/lib/actionFactory.js +1 -1
- data/client/lib/createActions.d.ts +1 -1
- data/client/lib/createActions.js +2 -27
- data/client/lib/createJasonReducers.js +1 -0
- data/client/lib/createOptDis.d.ts +1 -0
- data/client/lib/createOptDis.js +45 -0
- data/client/lib/createPayloadHandler.d.ts +1 -1
- data/client/lib/createPayloadHandler.js +23 -6
- data/client/lib/deepCamelizeKeys.d.ts +1 -0
- data/client/lib/deepCamelizeKeys.js +23 -0
- data/client/lib/deepCamelizeKeys.test.d.ts +1 -0
- data/client/lib/deepCamelizeKeys.test.js +106 -0
- data/client/lib/index.d.ts +4 -4
- data/client/package.json +17 -4
- data/client/src/JasonProvider.tsx +33 -5
- data/client/src/actionFactory.ts +1 -1
- data/client/src/createActions.ts +2 -33
- data/client/src/createJasonReducers.ts +1 -0
- data/client/src/createOptDis.ts +47 -0
- data/client/src/createPayloadHandler.ts +26 -4
- data/client/src/deepCamelizeKeys.test.ts +113 -0
- data/client/src/deepCamelizeKeys.ts +17 -0
- data/client/yarn.lock +4539 -81
- data/config/routes.rb +4 -0
- data/jason-rails.gemspec +5 -0
- data/lib/jason.rb +7 -1
- data/lib/jason/api_model.rb +16 -0
- data/lib/jason/channel.rb +2 -2
- data/lib/jason/engine.rb +5 -0
- data/lib/jason/publisher.rb +38 -6
- data/lib/jason/subscription.rb +21 -24
- data/lib/jason/version.rb +1 -1
- metadata +81 -3
data/config/routes.rb
ADDED
data/jason-rails.gemspec
CHANGED
@@ -22,4 +22,9 @@ Gem::Specification.new do |spec|
|
|
22
22
|
end
|
23
23
|
spec.executables = []
|
24
24
|
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency "rails", ">= 5"
|
27
|
+
spec.add_dependency "connection_pool", ">= 2.2.3"
|
28
|
+
spec.add_dependency "redis", ">= 4"
|
29
|
+
spec.add_dependency "jsondiff"
|
25
30
|
end
|
data/lib/jason.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
+
require 'connection_pool'
|
2
|
+
require 'redis'
|
3
|
+
require 'jsondiff'
|
4
|
+
|
1
5
|
require "jason/version"
|
2
6
|
require 'jason/api_model'
|
3
7
|
require 'jason/channel'
|
4
8
|
require 'jason/publisher'
|
5
9
|
require 'jason/subscription'
|
10
|
+
require 'jason/engine'
|
6
11
|
|
7
12
|
module Jason
|
8
13
|
class Error < StandardError; end
|
9
|
-
|
14
|
+
|
15
|
+
$redis_jason = ::ConnectionPool::Wrapper.new(size: 5, timeout: 3) { ::Redis.new(url: ENV['REDIS_URL']) }
|
10
16
|
end
|
data/lib/jason/api_model.rb
CHANGED
@@ -15,6 +15,10 @@ class Jason::ApiModel
|
|
15
15
|
model.allowed_params || []
|
16
16
|
end
|
17
17
|
|
18
|
+
def allowed_object_params
|
19
|
+
model.allowed_object_params || []
|
20
|
+
end
|
21
|
+
|
18
22
|
def include_models
|
19
23
|
model.include_models || []
|
20
24
|
end
|
@@ -35,6 +39,18 @@ class Jason::ApiModel
|
|
35
39
|
model.scope
|
36
40
|
end
|
37
41
|
|
42
|
+
def permit(params)
|
43
|
+
pp self
|
44
|
+
pp params
|
45
|
+
params = params.require(:payload).permit(allowed_params).tap do |allowed|
|
46
|
+
pp "ALLOWED"
|
47
|
+
pp allowed
|
48
|
+
allowed_object_params.each do |key|
|
49
|
+
allowed[key] = params[:payload][key].to_unsafe_h if params[:payload][key]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
38
54
|
def as_json_config
|
39
55
|
include_configs = include_models.map do |assoc|
|
40
56
|
reflection = name.classify.constantize.reflect_on_association(assoc.to_sym)
|
data/lib/jason/channel.rb
CHANGED
@@ -24,8 +24,8 @@ class Jason::Channel < ActionCable::Channel::Base
|
|
24
24
|
# stream_from s.channel
|
25
25
|
# end
|
26
26
|
elsif (data = message['getPayload'])
|
27
|
-
config = data
|
28
|
-
model = data
|
27
|
+
config = data['config']
|
28
|
+
model = data['model']
|
29
29
|
Jason::Subscription.new(config: config).get(model.to_s.underscore)
|
30
30
|
end
|
31
31
|
rescue => e
|
data/lib/jason/engine.rb
ADDED
data/lib/jason/publisher.rb
CHANGED
@@ -7,17 +7,16 @@ module Jason::Publisher
|
|
7
7
|
|
8
8
|
if self.persisted? && (scope.blank? || self.class.unscoped.send(scope).exists?(self.id))
|
9
9
|
payload = self.reload.as_json(as_json_config)
|
10
|
-
$
|
10
|
+
$redis_jason.hset("jason:#{self.class.name.underscore}:cache", self.id, payload.to_json)
|
11
11
|
else
|
12
|
-
$
|
12
|
+
$redis_jason.hdel("jason:#{self.class.name.underscore}:cache", self.id)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def publish_json
|
17
17
|
cache_json
|
18
18
|
return if skip_publish_json
|
19
|
-
|
20
|
-
subscriptions.each do |id, config_json|
|
19
|
+
self.class.jason_subscriptions.each do |id, config_json|
|
21
20
|
config = JSON.parse(config_json)
|
22
21
|
|
23
22
|
if (config['conditions'] || {}).all? { |field, value| self.send(field) == value }
|
@@ -33,7 +32,11 @@ module Jason::Publisher
|
|
33
32
|
|
34
33
|
class_methods do
|
35
34
|
def subscriptions
|
36
|
-
$
|
35
|
+
$redis_jason.hgetall("jason:#{self.name.underscore}:subscriptions")
|
36
|
+
end
|
37
|
+
|
38
|
+
def jason_subscriptions
|
39
|
+
$redis_jason.hgetall("jason:#{self.name.underscore}:subscriptions")
|
37
40
|
end
|
38
41
|
|
39
42
|
def publish_all(instances)
|
@@ -45,7 +48,7 @@ module Jason::Publisher
|
|
45
48
|
end
|
46
49
|
|
47
50
|
def flush_cache
|
48
|
-
$
|
51
|
+
$redis_jason.del("jason:#{self.name.underscore}:cache")
|
49
52
|
end
|
50
53
|
|
51
54
|
def setup_json
|
@@ -69,6 +72,35 @@ module Jason::Publisher
|
|
69
72
|
}
|
70
73
|
end
|
71
74
|
end
|
75
|
+
|
76
|
+
def find_or_create_by_id(params)
|
77
|
+
object = find_by(id: params[:id])
|
78
|
+
|
79
|
+
if object
|
80
|
+
object.update(params)
|
81
|
+
elsif params[:hidden]
|
82
|
+
return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
|
83
|
+
else
|
84
|
+
object = create!(params)
|
85
|
+
end
|
86
|
+
|
87
|
+
object
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_or_create_by_id!(params)
|
91
|
+
object = find_by(id: params[:id])
|
92
|
+
|
93
|
+
if object
|
94
|
+
object.update!(params)
|
95
|
+
elsif params[:hidden]
|
96
|
+
## TODO: We're diverging from semantics of the Rails bang! methods here, which would normally either raise or return an object. Find a way to make this better.
|
97
|
+
return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
|
98
|
+
else
|
99
|
+
object = create!(params)
|
100
|
+
end
|
101
|
+
|
102
|
+
object
|
103
|
+
end
|
72
104
|
end
|
73
105
|
|
74
106
|
included do
|
data/lib/jason/subscription.rb
CHANGED
@@ -4,7 +4,7 @@ class Jason::Subscription
|
|
4
4
|
def initialize(id: nil, config: nil)
|
5
5
|
if id
|
6
6
|
@id = id
|
7
|
-
raw_config = $
|
7
|
+
raw_config = $redis_jason.hgetall("jason:subscriptions:#{id}").map { |k,v| [k, JSON.parse(v)] }.to_h.with_indifferent_access
|
8
8
|
set_config(raw_config)
|
9
9
|
else
|
10
10
|
@id = Digest::MD5.hexdigest(config.to_json)
|
@@ -18,30 +18,28 @@ class Jason::Subscription
|
|
18
18
|
|
19
19
|
def configure(raw_config)
|
20
20
|
set_config(raw_config)
|
21
|
-
$
|
21
|
+
$redis_jason.hmset("jason:subscriptions:#{id}", *config.map { |k,v| [k, v.to_json]}.flatten)
|
22
22
|
end
|
23
23
|
|
24
24
|
def destroy
|
25
25
|
config.each do |model, value|
|
26
|
-
$
|
26
|
+
$redis_jason.srem("jason:#{model.to_s.underscore}:subscriptions", id)
|
27
27
|
end
|
28
|
-
$
|
28
|
+
$redis_jason.del("jason:subscriptions:#{id}")
|
29
29
|
end
|
30
30
|
|
31
31
|
def add_consumer(consumer_id)
|
32
32
|
before_consumer_count = consumer_count
|
33
|
-
$
|
34
|
-
$
|
33
|
+
$redis_jason.sadd("jason:subscriptions:#{id}:consumers", consumer_id)
|
34
|
+
$redis_jason.hset("jason:consumers", consumer_id, Time.now.utc)
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
publish_all
|
39
|
-
end
|
36
|
+
add_subscriptions
|
37
|
+
publish_all
|
40
38
|
end
|
41
39
|
|
42
40
|
def remove_consumer(consumer_id)
|
43
|
-
$
|
44
|
-
$
|
41
|
+
$redis_jason.srem("jason:subscriptions:#{id}:consumers", consumer_id)
|
42
|
+
$redis_jason.hdel("jason:consumers", consumer_id)
|
45
43
|
|
46
44
|
if consumer_count == 0
|
47
45
|
remove_subscriptions
|
@@ -49,7 +47,7 @@ class Jason::Subscription
|
|
49
47
|
end
|
50
48
|
|
51
49
|
def consumer_count
|
52
|
-
$
|
50
|
+
$redis_jason.scard("jason:subscriptions:#{id}:consumers")
|
53
51
|
end
|
54
52
|
|
55
53
|
def channel
|
@@ -67,14 +65,14 @@ class Jason::Subscription
|
|
67
65
|
|
68
66
|
def add_subscriptions
|
69
67
|
config.each do |model, value|
|
70
|
-
$
|
68
|
+
$redis_jason.hset("jason:#{model.to_s.underscore}:subscriptions", id, value.to_json)
|
71
69
|
update(model)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
73
|
def remove_subscriptions
|
76
74
|
config.each do |model, _|
|
77
|
-
$
|
75
|
+
$redis_jason.hdel("jason:#{model.to_s.underscore}:subscriptions", id)
|
78
76
|
end
|
79
77
|
end
|
80
78
|
|
@@ -86,8 +84,8 @@ class Jason::Subscription
|
|
86
84
|
end
|
87
85
|
|
88
86
|
def get(model)
|
89
|
-
value = JSON.parse($
|
90
|
-
idx = $
|
87
|
+
value = JSON.parse($redis_jason.get("#{channel}:#{model}:value") || '[]')
|
88
|
+
idx = $redis_jason.get("#{channel}:#{model}:idx").to_i
|
91
89
|
|
92
90
|
{
|
93
91
|
type: 'payload',
|
@@ -113,7 +111,7 @@ class Jason::Subscription
|
|
113
111
|
def get_throttle
|
114
112
|
if !$throttle_rate || !$throttle_timeout || Time.now.utc > $throttle_timeout
|
115
113
|
$throttle_timeout = Time.now.utc + 5.seconds
|
116
|
-
$throttle_rate = (
|
114
|
+
$throttle_rate = ($redis_jason.get('global_throttle_rate') || 0).to_i
|
117
115
|
else
|
118
116
|
$throttle_rate
|
119
117
|
end
|
@@ -124,15 +122,15 @@ class Jason::Subscription
|
|
124
122
|
start_time = Time.now.utc
|
125
123
|
conditions = config[model]['conditions']
|
126
124
|
|
127
|
-
value = $
|
125
|
+
value = $redis_jason.hgetall("jason:#{model}:cache")
|
128
126
|
.values.map { |v| JSON.parse(v) }
|
129
127
|
.select { |v| (conditions || {}).all? { |field, value| v[field] == value } }
|
130
128
|
.sort_by { |v| v['id'] }
|
131
129
|
|
132
130
|
# lfsa = last finished, started at
|
133
131
|
# If another job that started after this one, finished before this one, skip sending this state update
|
134
|
-
if Time.parse(
|
135
|
-
|
132
|
+
if Time.parse($redis_jason.get("jason:#{channel}:lfsa") || '1970-01-01 00:00:00 UTC') < start_time
|
133
|
+
$redis_jason.set("jason:#{channel}:lfsa", start_time)
|
136
134
|
else
|
137
135
|
return
|
138
136
|
end
|
@@ -149,12 +147,11 @@ class Jason::Subscription
|
|
149
147
|
end
|
150
148
|
LUA
|
151
149
|
|
152
|
-
result = $
|
150
|
+
result = $redis_jason.eval cmd, [], ["#{channel}:#{model}", value.to_json]
|
153
151
|
return if result.blank?
|
154
152
|
|
155
153
|
idx = result[0]
|
156
|
-
old_value = JSON.parse(result[1] || '
|
157
|
-
|
154
|
+
old_value = JSON.parse(result[1] || '[]')
|
158
155
|
diff = get_diff(old_value, value)
|
159
156
|
|
160
157
|
end_time = Time.now.utc
|
data/lib/jason/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jason-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Rees
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
12
|
-
dependencies:
|
11
|
+
date: 2020-12-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: connection_pool
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redis
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jsondiff
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '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'
|
13
69
|
description:
|
14
70
|
email:
|
15
71
|
- jarees@gmail.com
|
@@ -22,11 +78,22 @@ files:
|
|
22
78
|
- ".travis.yml"
|
23
79
|
- CODE_OF_CONDUCT.md
|
24
80
|
- Gemfile
|
81
|
+
- Gemfile.lock
|
25
82
|
- LICENSE.txt
|
26
83
|
- README.md
|
27
84
|
- Rakefile
|
85
|
+
- app/assets/config/jason_engine_manifest.js
|
86
|
+
- app/assets/images/jason/engine/.keep
|
87
|
+
- app/assets/stylesheets/jason/engine/application.css
|
88
|
+
- app/controllers/jason/api_controller.rb
|
89
|
+
- app/helpers/jason/engine/application_helper.rb
|
90
|
+
- app/jobs/jason/engine/application_job.rb
|
91
|
+
- app/mailers/jason/engine/application_mailer.rb
|
92
|
+
- app/models/jason/engine/application_record.rb
|
93
|
+
- app/views/layouts/jason/engine/application.html.erb
|
28
94
|
- bin/console
|
29
95
|
- bin/setup
|
96
|
+
- client/babel.config.js
|
30
97
|
- client/lib/JasonContext.d.ts
|
31
98
|
- client/lib/JasonContext.js
|
32
99
|
- client/lib/JasonProvider.d.ts
|
@@ -37,8 +104,14 @@ files:
|
|
37
104
|
- client/lib/createActions.js
|
38
105
|
- client/lib/createJasonReducers.d.ts
|
39
106
|
- client/lib/createJasonReducers.js
|
107
|
+
- client/lib/createOptDis.d.ts
|
108
|
+
- client/lib/createOptDis.js
|
40
109
|
- client/lib/createPayloadHandler.d.ts
|
41
110
|
- client/lib/createPayloadHandler.js
|
111
|
+
- client/lib/deepCamelizeKeys.d.ts
|
112
|
+
- client/lib/deepCamelizeKeys.js
|
113
|
+
- client/lib/deepCamelizeKeys.test.d.ts
|
114
|
+
- client/lib/deepCamelizeKeys.test.js
|
42
115
|
- client/lib/index.d.ts
|
43
116
|
- client/lib/index.js
|
44
117
|
- client/lib/makeEager.d.ts
|
@@ -53,17 +126,22 @@ files:
|
|
53
126
|
- client/src/actionFactory.ts
|
54
127
|
- client/src/createActions.ts
|
55
128
|
- client/src/createJasonReducers.ts
|
129
|
+
- client/src/createOptDis.ts
|
56
130
|
- client/src/createPayloadHandler.ts
|
131
|
+
- client/src/deepCamelizeKeys.test.ts
|
132
|
+
- client/src/deepCamelizeKeys.ts
|
57
133
|
- client/src/index.ts
|
58
134
|
- client/src/makeEager.ts
|
59
135
|
- client/src/useAct.ts
|
60
136
|
- client/src/useSub.ts
|
61
137
|
- client/tsconfig.json
|
62
138
|
- client/yarn.lock
|
139
|
+
- config/routes.rb
|
63
140
|
- jason-rails.gemspec
|
64
141
|
- lib/jason.rb
|
65
142
|
- lib/jason/api_model.rb
|
66
143
|
- lib/jason/channel.rb
|
144
|
+
- lib/jason/engine.rb
|
67
145
|
- lib/jason/publisher.rb
|
68
146
|
- lib/jason/subscription.rb
|
69
147
|
- lib/jason/version.rb
|