jason-rails 0.5.0 → 0.6.3

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +141 -5
  5. data/app/controllers/jason/api/pusher_controller.rb +15 -0
  6. data/app/controllers/jason/api_controller.rb +46 -4
  7. data/client/lib/JasonContext.d.ts +1 -1
  8. data/client/lib/JasonContext.js +4 -1
  9. data/client/lib/JasonProvider.js +1 -1
  10. data/client/lib/createJasonReducers.js +7 -0
  11. data/client/lib/createPayloadHandler.d.ts +6 -3
  12. data/client/lib/createPayloadHandler.js +8 -4
  13. data/client/lib/createTransportAdapter.d.ts +5 -0
  14. data/client/lib/createTransportAdapter.js +20 -0
  15. data/client/lib/index.d.ts +2 -0
  16. data/client/lib/index.js +3 -1
  17. data/client/lib/makeEager.js +2 -2
  18. data/client/lib/pruneIdsMiddleware.js +9 -11
  19. data/client/lib/restClient.d.ts +1 -1
  20. data/client/lib/transportAdapters/actionCableAdapter.d.ts +5 -0
  21. data/client/lib/transportAdapters/actionCableAdapter.js +35 -0
  22. data/client/lib/transportAdapters/pusherAdapter.d.ts +5 -0
  23. data/client/lib/transportAdapters/pusherAdapter.js +68 -0
  24. data/client/lib/useEager.d.ts +1 -0
  25. data/client/lib/useEager.js +12 -0
  26. data/client/lib/useJason.js +30 -35
  27. data/client/lib/useJason.test.js +8 -2
  28. data/client/lib/useSub.d.ts +1 -1
  29. data/client/lib/useSub.js +5 -3
  30. data/client/package.json +2 -1
  31. data/client/src/JasonContext.ts +4 -1
  32. data/client/src/JasonProvider.tsx +1 -1
  33. data/client/src/createJasonReducers.ts +7 -0
  34. data/client/src/createPayloadHandler.ts +9 -4
  35. data/client/src/createTransportAdapter.ts +13 -0
  36. data/client/src/index.ts +3 -1
  37. data/client/src/makeEager.ts +2 -2
  38. data/client/src/pruneIdsMiddleware.ts +11 -11
  39. data/client/src/restClient.ts +2 -1
  40. data/client/src/transportAdapters/actionCableAdapter.ts +38 -0
  41. data/client/src/transportAdapters/pusherAdapter.ts +72 -0
  42. data/client/src/useEager.ts +9 -0
  43. data/client/src/useJason.test.ts +8 -2
  44. data/client/src/useJason.ts +31 -36
  45. data/client/src/useSub.ts +5 -3
  46. data/client/yarn.lock +12 -0
  47. data/config/routes.rb +5 -1
  48. data/lib/jason.rb +56 -8
  49. data/lib/jason/broadcaster.rb +19 -0
  50. data/lib/jason/channel.rb +10 -3
  51. data/lib/jason/graph_helper.rb +165 -0
  52. data/lib/jason/includes_helper.rb +108 -0
  53. data/lib/jason/lua_generator.rb +23 -1
  54. data/lib/jason/publisher.rb +21 -17
  55. data/lib/jason/subscription.rb +208 -179
  56. data/lib/jason/version.rb +1 -1
  57. metadata +18 -2
@@ -0,0 +1,13 @@
1
+ import actionCableAdapter from './transportAdapters/actionCableAdapter'
2
+ import pusherAdapter from './transportAdapters/pusherAdapter'
3
+
4
+ export default function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect) {
5
+ const { transportService } = jasonConfig
6
+ if (transportService === 'action_cable') {
7
+ return actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnect)
8
+ } else if (transportService === 'pusher') {
9
+ return pusherAdapter(jasonConfig, handlePayload, dispatch)
10
+ } else {
11
+ throw(`Transport adapter does not exist for ${transportService}`)
12
+ }
13
+ }
data/client/src/index.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import _JasonProvider from './JasonProvider'
2
2
  import _useAct from './useAct'
3
3
  import _useSub from './useSub'
4
+ import _useEager from './useEager'
4
5
 
5
6
  export const JasonProvider = _JasonProvider
6
7
  export const useAct = _useAct
7
- export const useSub = _useSub
8
+ export const useSub = _useSub
9
+ export const useEager = _useEager
@@ -36,9 +36,9 @@ export default function (schema) {
36
36
 
37
37
  function useEager(entity, id = null, relations = []) {
38
38
  if (id) {
39
- return useSelector(s => addRelations(s, { ...s[entity].entities[String(id)] }, entity, relations))
39
+ return useSelector(s => addRelations(s, { ...s[entity].entities[String(id)] }, entity, relations), _.isEqual)
40
40
  } else {
41
- return useSelector(s => addRelations(s, _.values(s[entity].entities), entity, relations))
41
+ return useSelector(s => addRelations(s, _.values(s[entity].entities), entity, relations), _.isEqual)
42
42
  }
43
43
  }
44
44
 
@@ -2,20 +2,20 @@ import _ from 'lodash'
2
2
  import pluralize from 'pluralize'
3
3
 
4
4
  const pruneIdsMiddleware = schema => store => next => action => {
5
- const { type } = action
5
+ const { type, payload } = action
6
6
  const result = next(action)
7
+
7
8
  const state = store.getState()
8
- if (type === 'jasonModels/setSubscriptionIds') {
9
- // Check every model
10
- _.map(_.keys(schema), model => {
11
- let ids = []
12
- _.map(state.jasonModels[model], (subscribedIds, k) => {
13
- ids = _.union(ids, subscribedIds)
14
- })
15
- // Find IDs currently in Redux that aren't in any subscription
16
- const idsToRemove = _.difference(state[pluralize(model)].ids, ids)
17
- store.dispatch({ type: `${pluralize(model)}/removeMany`, payload: idsToRemove })
9
+ if (type === 'jasonModels/setSubscriptionIds' || type === 'jasonModels/removeSubscriptionIds') {
10
+ const { model, ids } = payload
11
+
12
+ let idsInSubs = []
13
+ _.map(state.jasonModels[model], (subscribedIds, k) => {
14
+ idsInSubs = _.union(idsInSubs, subscribedIds)
18
15
  })
16
+ // Find IDs currently in Redux that aren't in any subscription
17
+ const idsToRemove = _.difference(state[pluralize(model)].ids, idsInSubs)
18
+ store.dispatch({ type: `${pluralize(model)}/removeMany`, payload: idsToRemove })
19
19
  }
20
20
 
21
21
  return result
@@ -4,10 +4,11 @@ import { validate as isUuid } from 'uuid'
4
4
 
5
5
  const csrfToken = (document?.querySelector("meta[name=csrf-token]") as any)?.content
6
6
  axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
7
+
7
8
  const restClient = applyCaseMiddleware(axios.create() as any, {
8
9
  preservedKeys: (key) => {
9
10
  return isUuid(key)
10
11
  }
11
- })
12
+ }) as any
12
13
 
13
14
  export default restClient
@@ -0,0 +1,38 @@
1
+ import { createConsumer } from "@rails/actioncable"
2
+
3
+ export default function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected) {
4
+ const consumer = createConsumer()
5
+ const subscription = (consumer.subscriptions.create({
6
+ channel: 'Jason::Channel'
7
+ }, {
8
+ connected: () => {
9
+ dispatch({ type: 'jason/upsert', payload: { connected: true } })
10
+ console.debug('Connected to ActionCable')
11
+
12
+ // When AC loses connection - all state is lost, so we need to re-initialize all subscriptions
13
+ onConnected()
14
+ },
15
+ received: payload => {
16
+ handlePayload(payload)
17
+ console.debug("ActionCable Payload received: ", payload)
18
+ },
19
+ disconnected: () => {
20
+ dispatch({ type: 'jason/upsert', payload: { connected: false } })
21
+ console.warn('Disconnected from ActionCable')
22
+ }
23
+ }));
24
+
25
+ function getPayload(config, options) {
26
+ subscription.send({ getPayload: config, ...options })
27
+ }
28
+
29
+ function createSubscription(config) {
30
+ subscription.send({ createSubscription: config })
31
+ }
32
+
33
+ function removeSubscription(config) {
34
+ subscription.send({ removeSubscription: config })
35
+ }
36
+
37
+ return { getPayload, createSubscription, removeSubscription }
38
+ }
@@ -0,0 +1,72 @@
1
+ import Pusher from 'pusher-js'
2
+ import { createConsumer } from "@rails/actioncable"
3
+ import restClient from '../restClient'
4
+ import { v4 as uuidv4 } from 'uuid'
5
+ import _ from 'lodash'
6
+
7
+ export default function pusherAdapter(jasonConfig, handlePayload, dispatch) {
8
+ let consumerId = uuidv4()
9
+
10
+ const { pusherKey, pusherRegion, pusherChannelPrefix } = jasonConfig
11
+ const pusher = new Pusher(pusherKey, {
12
+ cluster: 'eu',
13
+ forceTLS: true,
14
+ authEndpoint: '/jason/api/pusher/auth'
15
+ })
16
+ pusher.connection.bind('state_change', ({ current }) => {
17
+ if (current === 'connected') {
18
+ dispatch({ type: 'jason/upsert', payload: { connected: true } })
19
+ } else {
20
+ dispatch({ type: 'jason/upsert', payload: { connected: false } })
21
+ }
22
+ })
23
+ pusher.connection.bind( 'error', error => {
24
+ dispatch({ type: 'jason/upsert', payload: { connected: false } })
25
+ });
26
+
27
+ const configToChannel = {}
28
+
29
+ function createSubscription(config) {
30
+ restClient.post('/jason/api/create_subscription', { config, consumerId })
31
+ .then(({ data: { channelName } }) => {
32
+ configToChannel[JSON.stringify(config)] = channelName
33
+ subscribeToChannel(channelName)
34
+ })
35
+ .catch(e => console.error(e))
36
+ }
37
+
38
+ function removeSubscription(config) {
39
+ const channelName = configToChannel[JSON.stringify(config)]
40
+ unsubscribeFromChannel(fullChannelName(channelName))
41
+ restClient.post('/jason/api/remove_subscription', { config, consumerId })
42
+ .catch(e => console.error(e))
43
+ }
44
+
45
+ function getPayload(config, options) {
46
+ restClient.post('/jason/api/get_payload', {
47
+ config,
48
+ options
49
+ })
50
+ .then(({ data }) => {
51
+ _.map(data, (payload, modelName) => {
52
+ handlePayload(payload)
53
+ })
54
+ })
55
+ .catch(e => console.error(e))
56
+ }
57
+
58
+ function subscribeToChannel(channelName) {
59
+ const channel = pusher.subscribe(fullChannelName(channelName))
60
+ channel.bind('changed', message => handlePayload(message))
61
+ }
62
+
63
+ function unsubscribeFromChannel(channelName) {
64
+ const channel = pusher.unsubscribe(fullChannelName(channelName))
65
+ }
66
+
67
+ function fullChannelName(channelName) {
68
+ return `private-${pusherChannelPrefix}-${channelName}`
69
+ }
70
+
71
+ return { getPayload, createSubscription, removeSubscription }
72
+ }
@@ -0,0 +1,9 @@
1
+ import JasonContext from './JasonContext'
2
+ import { useContext } from 'react'
3
+
4
+ export default function useEager(entity, id = null, relations = []) {
5
+ const { eager } = useContext(JasonContext)
6
+
7
+ return eager(entity, id, relations)
8
+ }
9
+
@@ -5,7 +5,10 @@ import restClient from './restClient'
5
5
  jest.mock('./restClient')
6
6
 
7
7
  test('it works', async () => {
8
- const resp = { data: { post: {} } };
8
+ const resp = { data: {
9
+ schema: { post: {} },
10
+ transportService: 'action_cable'
11
+ } };
9
12
  // @ts-ignore
10
13
  restClient.get.mockResolvedValue(resp);
11
14
 
@@ -45,7 +48,10 @@ test('it works', async () => {
45
48
  })
46
49
 
47
50
  test('pruning IDs', async () => {
48
- const resp = { data: { post: {} } };
51
+ const resp = { data: {
52
+ schema: { post: {} },
53
+ transportService: 'action_cable'
54
+ } };
49
55
 
50
56
  // @ts-ignore
51
57
  restClient.get.mockResolvedValue(resp);
@@ -5,8 +5,8 @@ import createOptDis from './createOptDis'
5
5
  import createServerActionQueue from './createServerActionQueue'
6
6
  import restClient from './restClient'
7
7
  import pruneIdsMiddleware from './pruneIdsMiddleware'
8
+ import createTransportAdapater from './createTransportAdapter'
8
9
 
9
- import { createConsumer } from "@rails/actioncable"
10
10
  import { createEntityAdapter, createSlice, createReducer, configureStore } from '@reduxjs/toolkit'
11
11
 
12
12
  import makeEager from './makeEager'
@@ -18,17 +18,17 @@ import React, { useState, useEffect } from 'react'
18
18
  export default function useJason({ reducers, middleware = [], extraActions }: { reducers?: any, middleware?: any[], extraActions?: any }) {
19
19
  const [store, setStore] = useState(null as any)
20
20
  const [value, setValue] = useState(null as any)
21
- const [connected, setConnected] = useState(false)
22
21
 
23
22
  useEffect(() => {
24
- restClient.get('/jason/api/schema')
25
- .then(({ data: snakey_schema }) => {
23
+ restClient.get('/jason/api/config')
24
+ .then(({ data: jasonConfig }) => {
25
+ const { schema: snakey_schema } = jasonConfig
26
26
  const schema = camelizeKeys(snakey_schema)
27
27
  console.debug({ schema })
28
28
 
29
29
  const serverActionQueue = createServerActionQueue()
30
30
 
31
- const consumer = createConsumer()
31
+
32
32
  const allReducers = {
33
33
  ...reducers,
34
34
  ...createJasonReducers(schema)
@@ -45,65 +45,60 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
45
45
 
46
46
  let payloadHandlers = {}
47
47
  let configs = {}
48
+ let subOptions = {}
48
49
 
49
50
  function handlePayload(payload) {
50
51
  const { md5Hash } = payload
51
52
 
52
- const handler = payloadHandlers[md5Hash]
53
- if (handler) {
54
- handler(payload)
53
+ const { handlePayload } = payloadHandlers[md5Hash]
54
+ if (handlePayload) {
55
+ handlePayload(payload)
55
56
  } else {
56
57
  console.warn("Payload arrived with no handler", payload, payloadHandlers)
57
58
  }
58
59
  }
59
60
 
60
- const subscription = (consumer.subscriptions.create({
61
- channel: 'Jason::Channel'
62
- }, {
63
- connected: () => {
64
- setConnected(true)
65
- dispatch({ type: 'jason/upsert', payload: { connected: true } })
66
- console.debug('Connected to ActionCable')
67
-
68
- // When AC loses connection - all state is lost, so we need to re-initialize all subscriptions
69
- _.values(configs).forEach(config => createSubscription(config))
70
- },
71
- received: payload => {
72
- handlePayload(payload)
73
- console.debug("ActionCable Payload received: ", payload)
74
- },
75
- disconnected: () => {
76
- setConnected(false)
77
- dispatch({ type: 'jason/upsert', payload: { connected: false } })
78
- console.warn('Disconnected from ActionCable')
79
- }
80
- }));
61
+ const transportAdapter = createTransportAdapater(jasonConfig, handlePayload, dispatch, () => _.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])))
81
62
 
82
- function createSubscription(config) {
63
+ function createSubscription(config, options = {}) {
83
64
  // We need the hash to be consistent in Ruby / Javascript
84
65
  const hashableConfig = _({ conditions: {}, includes: {}, ...config }).toPairs().sortBy(0).fromPairs().value()
85
66
  const md5Hash = md5(JSON.stringify(hashableConfig))
86
- payloadHandlers[md5Hash] = createPayloadHandler({ dispatch, serverActionQueue, subscription, config })
67
+ payloadHandlers[md5Hash] = createPayloadHandler({ dispatch, serverActionQueue, transportAdapter, config })
87
68
  configs[md5Hash] = hashableConfig
69
+ subOptions[md5Hash] = options
70
+
71
+ setTimeout(() => transportAdapter.createSubscription(hashableConfig), 500)
72
+ let pollInterval = null as any;
88
73
 
89
- setTimeout(() => subscription.send({ createSubscription: hashableConfig }), 500)
74
+ // This is only for debugging / dev - not prod!
75
+ // @ts-ignore
76
+ if (options.pollInterval) {
77
+ // @ts-ignore
78
+ pollInterval = setInterval(() => transportAdapter.getPayload(hashableConfig, { forceRefresh: true }), options.pollInterval)
79
+ }
90
80
 
91
81
  return {
92
- remove: () => removeSubscription(hashableConfig),
82
+ remove() {
83
+ removeSubscription(hashableConfig)
84
+ if (pollInterval) clearInterval(pollInterval)
85
+ },
93
86
  md5Hash
94
87
  }
95
88
  }
96
89
 
97
90
  function removeSubscription(config) {
98
- subscription.send({ removeSubscription: config })
91
+ transportAdapter.removeSubscription(config)
99
92
  const md5Hash = md5(JSON.stringify(config))
93
+ payloadHandlers[md5Hash].tearDown()
100
94
  delete payloadHandlers[md5Hash]
101
95
  delete configs[md5Hash]
96
+ delete subOptions[md5Hash]
102
97
  }
103
98
 
104
99
  setValue({
105
100
  actions: actions,
106
- subscribe: config => createSubscription(config),
101
+ subscribe: createSubscription,
107
102
  eager,
108
103
  handlePayload
109
104
  })
@@ -111,5 +106,5 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
111
106
  })
112
107
  }, [])
113
108
 
114
- return [store, value, connected]
109
+ return [store, value]
115
110
  }
data/client/src/useSub.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import JasonContext from './JasonContext'
2
2
  import { useContext, useEffect } from 'react'
3
3
 
4
- export default function useSub(config) {
4
+ export default function useSub(config, options = {}) {
5
+ // useEffect uses strict equality
6
+ const configJson = JSON.stringify(config)
5
7
  const subscribe = useContext(JasonContext).subscribe
6
8
 
7
9
  useEffect(() => {
8
10
  // @ts-ignore
9
- return subscribe(config)
10
- }, [])
11
+ return subscribe(config, options).remove
12
+ }, [configJson])
11
13
  }
data/client/yarn.lock CHANGED
@@ -3645,6 +3645,13 @@ punycode@^2.1.0, punycode@^2.1.1:
3645
3645
  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
3646
3646
  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
3647
3647
 
3648
+ pusher-js@^7.0.3:
3649
+ version "7.0.3"
3650
+ resolved "https://registry.yarnpkg.com/pusher-js/-/pusher-js-7.0.3.tgz#f81c78cdf2ad32f546caa7532ec7f9081ef00b8d"
3651
+ integrity sha512-HIfCvt00CAqgO4W0BrdpPsDcAwy51rB6DN0VMC+JeVRRbo8mn3XTeUeIFjmmlRLZLX8rPhUtLRo7vPag6b8GCw==
3652
+ dependencies:
3653
+ tweetnacl "^1.0.3"
3654
+
3648
3655
  qs@~6.5.2:
3649
3656
  version "6.5.2"
3650
3657
  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -4358,6 +4365,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
4358
4365
  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
4359
4366
  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
4360
4367
 
4368
+ tweetnacl@^1.0.3:
4369
+ version "1.0.3"
4370
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
4371
+ integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
4372
+
4361
4373
  type-check@~0.3.2:
4362
4374
  version "0.3.2"
4363
4375
  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
data/config/routes.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  Jason::Engine.routes.draw do
2
- get '/api/schema', to: 'api#schema'
2
+ get '/api/config', to: 'api#configuration'
3
3
  post '/api/action', to: 'api#action'
4
+ post '/api/create_subscription', to: 'api#create_subscription'
5
+ post '/api/remove_subscription', to: 'api#remove_subscription'
6
+ post '/api/get_payload', to: 'api#get_payload'
7
+ post '/api/pusher/auth', to: 'api/pusher#auth'
4
8
  end
data/lib/jason.rb CHANGED
@@ -7,22 +7,70 @@ require 'jason/api_model'
7
7
  require 'jason/channel'
8
8
  require 'jason/publisher'
9
9
  require 'jason/subscription'
10
+ require 'jason/broadcaster'
10
11
  require 'jason/engine'
11
12
  require 'jason/lua_generator'
13
+ require 'jason/includes_helper'
14
+ require 'jason/graph_helper'
12
15
 
13
16
  module Jason
14
17
  class Error < StandardError; end
15
18
 
16
- $redis_jason = ::ConnectionPool::Wrapper.new(size: 5, timeout: 3) { ::Redis.new(url: ENV['REDIS_URL']) }
19
+ self.mattr_accessor :schema
20
+ self.mattr_accessor :transport_service
21
+ self.mattr_accessor :redis
22
+ self.mattr_accessor :pusher
23
+ self.mattr_accessor :pusher_key
24
+ self.mattr_accessor :pusher_region
25
+ self.mattr_accessor :pusher_channel_prefix
26
+ self.mattr_accessor :authorization_service
17
27
 
28
+ self.schema = {}
29
+ self.transport_service = :action_cable
30
+ self.pusher_region = 'eu'
31
+ self.pusher_channel_prefix = 'jason'
18
32
 
19
- self.mattr_accessor :schema
20
- self.schema = {}
21
- # add default values of more config vars here
33
+ def self.init
34
+ # Check if the schema has changed since last time app was started. If so, do some work to ensure cache contains the correct data
35
+ got_lock = $redis_jason.set('jason:schema:lock', nx: true, ex: 3600) # Basic lock mechanism for multi-process environments
36
+ return if !got_lock
22
37
 
23
- # this function maps the vars from your app into your engine
24
- def self.setup(&block)
25
- yield self
26
- end
38
+ previous_schema = JSON.parse($redis_jason.get('jason:last_schema') || '{}')
39
+ current_schema = Jason.schema.deep_stringify_keys.deep_transform_values { |v| v.is_a?(Symbol) ? v.to_s : v }
40
+ pp current_schema
41
+ current_schema.each do |model, config|
42
+ if config != previous_schema[model]
43
+ puts "Config changed for #{model}"
44
+ puts "Old config was #{previous_schema[model]}"
45
+ puts "New config is #{config}"
46
+ puts "Rebuilding cache for #{model}"
47
+ model.classify.constantize.cache_all
48
+ puts "Done"
49
+ end
50
+ end
27
51
 
52
+ $redis_jason.set('jason:last_schema', current_schema.to_json)
53
+ ensure
54
+ $redis_jason.del('jason:schema:lock')
55
+
56
+ previous_config = 'test'
57
+ end
58
+
59
+
60
+ # this function maps the vars from your app into your engine
61
+ def self.setup(&block)
62
+ yield self
63
+
64
+ $redis_jason = self.redis || ::ConnectionPool::Wrapper.new(size: 5, timeout: 3) { ::Redis.new(url: ENV['REDIS_URL']) }
65
+
66
+ if ![:action_cable, :pusher].include?(self.transport_service)
67
+ raise "Unknown transport service '#{self.transport_service}' specified"
68
+ end
69
+
70
+ if self.transport_service == :pusher && self.pusher.blank?
71
+ raise "Pusher specified as transport service but no Pusher client provided. Please configure with config.pusher = Pusher::Client.new(...)"
72
+ end
73
+
74
+ init
75
+ end
28
76
  end