jason-rails 0.4.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.ruby-version +1 -0
- data/Gemfile.lock +152 -2
- data/README.md +117 -5
- data/app/controllers/jason/api/pusher_controller.rb +15 -0
- data/app/controllers/jason/api_controller.rb +44 -2
- data/client/lib/JasonContext.d.ts +6 -1
- data/client/lib/JasonProvider.d.ts +2 -2
- data/client/lib/JasonProvider.js +5 -124
- data/client/lib/createJasonReducers.js +48 -3
- data/client/lib/createOptDis.js +0 -2
- data/client/lib/createPayloadHandler.d.ts +9 -1
- data/client/lib/createPayloadHandler.js +47 -55
- data/client/lib/createServerActionQueue.d.ts +10 -0
- data/client/lib/createServerActionQueue.js +48 -0
- data/client/lib/createServerActionQueue.test.d.ts +1 -0
- data/client/lib/createServerActionQueue.test.js +37 -0
- data/client/lib/createTransportAdapter.d.ts +5 -0
- data/client/lib/createTransportAdapter.js +20 -0
- data/client/lib/index.d.ts +3 -2
- data/client/lib/pruneIdsMiddleware.d.ts +2 -0
- data/client/lib/pruneIdsMiddleware.js +24 -0
- data/client/lib/restClient.d.ts +2 -0
- data/client/lib/restClient.js +17 -0
- data/client/lib/transportAdapters/actionCableAdapter.d.ts +5 -0
- data/client/lib/transportAdapters/actionCableAdapter.js +35 -0
- data/client/lib/transportAdapters/pusherAdapter.d.ts +5 -0
- data/client/lib/transportAdapters/pusherAdapter.js +68 -0
- data/client/lib/useJason.d.ts +5 -0
- data/client/lib/useJason.js +94 -0
- data/client/lib/useJason.test.d.ts +1 -0
- data/client/lib/useJason.test.js +85 -0
- data/client/lib/useSub.d.ts +1 -1
- data/client/lib/useSub.js +6 -3
- data/client/package.json +5 -3
- data/client/src/JasonProvider.tsx +5 -123
- data/client/src/createJasonReducers.ts +56 -3
- data/client/src/createOptDis.ts +0 -2
- data/client/src/createPayloadHandler.ts +53 -64
- data/client/src/createServerActionQueue.test.ts +42 -0
- data/client/src/createServerActionQueue.ts +47 -0
- data/client/src/createTransportAdapter.ts +13 -0
- data/client/src/pruneIdsMiddleware.ts +24 -0
- data/client/src/restClient.ts +14 -0
- data/client/src/transportAdapters/actionCableAdapter.ts +38 -0
- data/client/src/transportAdapters/pusherAdapter.ts +72 -0
- data/client/src/useJason.test.ts +87 -0
- data/client/src/useJason.ts +110 -0
- data/client/src/useSub.ts +6 -3
- data/client/yarn.lock +71 -3
- data/config/routes.rb +5 -1
- data/jason-rails.gemspec +4 -0
- data/lib/jason.rb +61 -1
- data/lib/jason/api_model.rb +2 -12
- data/lib/jason/broadcaster.rb +19 -0
- data/lib/jason/channel.rb +50 -21
- data/lib/jason/graph_helper.rb +165 -0
- data/lib/jason/includes_helper.rb +108 -0
- data/lib/jason/lua_generator.rb +71 -0
- data/lib/jason/publisher.rb +82 -37
- data/lib/jason/publisher_old.rb +112 -0
- data/lib/jason/subscription.rb +349 -97
- data/lib/jason/subscription_old.rb +171 -0
- data/lib/jason/version.rb +1 -1
- metadata +80 -11
- data/app/assets/config/jason_engine_manifest.js +0 -1
- data/app/assets/images/jason/engine/.keep +0 -0
- data/app/assets/stylesheets/jason/engine/application.css +0 -15
- data/app/helpers/jason/engine/application_helper.rb +0 -6
- data/app/jobs/jason/engine/application_job.rb +0 -6
- data/app/mailers/jason/engine/application_mailer.rb +0 -8
- data/app/models/jason/engine/application_record.rb +0 -7
- data/app/views/layouts/jason/engine/application.html.erb +0 -15
@@ -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
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import _ from 'lodash'
|
2
|
+
import pluralize from 'pluralize'
|
3
|
+
|
4
|
+
const pruneIdsMiddleware = schema => store => next => action => {
|
5
|
+
const { type, payload } = action
|
6
|
+
const result = next(action)
|
7
|
+
|
8
|
+
const state = store.getState()
|
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)
|
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
|
+
}
|
20
|
+
|
21
|
+
return result
|
22
|
+
}
|
23
|
+
|
24
|
+
export default pruneIdsMiddleware
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import axios from 'axios'
|
2
|
+
import applyCaseMiddleware from 'axios-case-converter'
|
3
|
+
import { validate as isUuid } from 'uuid'
|
4
|
+
|
5
|
+
const csrfToken = (document?.querySelector("meta[name=csrf-token]") as any)?.content
|
6
|
+
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
|
7
|
+
|
8
|
+
const restClient = applyCaseMiddleware(axios.create() as any, {
|
9
|
+
preservedKeys: (key) => {
|
10
|
+
return isUuid(key)
|
11
|
+
}
|
12
|
+
}) as any
|
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,87 @@
|
|
1
|
+
import { renderHook, act } from '@testing-library/react-hooks'
|
2
|
+
import useJason from './useJason'
|
3
|
+
import restClient from './restClient'
|
4
|
+
|
5
|
+
jest.mock('./restClient')
|
6
|
+
|
7
|
+
test('it works', async () => {
|
8
|
+
const resp = { data: {
|
9
|
+
schema: { post: {} },
|
10
|
+
transportService: 'action_cable'
|
11
|
+
} };
|
12
|
+
// @ts-ignore
|
13
|
+
restClient.get.mockResolvedValue(resp);
|
14
|
+
|
15
|
+
const { result, waitForNextUpdate } = renderHook(() => useJason({ reducers: {
|
16
|
+
test: (s,a) => s || {}
|
17
|
+
}}));
|
18
|
+
|
19
|
+
await waitForNextUpdate()
|
20
|
+
const [store, value, connected] = result.current
|
21
|
+
const { handlePayload, subscribe } = value
|
22
|
+
|
23
|
+
const subscription = subscribe({ post: {} })
|
24
|
+
|
25
|
+
handlePayload({
|
26
|
+
type: 'payload',
|
27
|
+
model: 'post',
|
28
|
+
payload: [{ id: 4, name: 'test' }],
|
29
|
+
md5Hash: subscription.md5Hash,
|
30
|
+
idx: 1
|
31
|
+
})
|
32
|
+
|
33
|
+
handlePayload({
|
34
|
+
id: 4,
|
35
|
+
model: 'post',
|
36
|
+
destroy: true,
|
37
|
+
md5Hash: subscription.md5Hash,
|
38
|
+
idx: 2
|
39
|
+
})
|
40
|
+
|
41
|
+
handlePayload({
|
42
|
+
id: 5,
|
43
|
+
model: 'post',
|
44
|
+
payload: { id: 5, name: 'test2' },
|
45
|
+
md5Hash: subscription.md5Hash,
|
46
|
+
idx: 3
|
47
|
+
})
|
48
|
+
})
|
49
|
+
|
50
|
+
test('pruning IDs', async () => {
|
51
|
+
const resp = { data: {
|
52
|
+
schema: { post: {} },
|
53
|
+
transportService: 'action_cable'
|
54
|
+
} };
|
55
|
+
|
56
|
+
// @ts-ignore
|
57
|
+
restClient.get.mockResolvedValue(resp);
|
58
|
+
|
59
|
+
const { result, waitForNextUpdate } = renderHook(() => useJason({ reducers: {
|
60
|
+
test: (s,a) => s || {}
|
61
|
+
}}));
|
62
|
+
|
63
|
+
await waitForNextUpdate()
|
64
|
+
const [store, value, connected] = result.current
|
65
|
+
const { handlePayload, subscribe } = value
|
66
|
+
|
67
|
+
const subscription = subscribe({ post: {} })
|
68
|
+
|
69
|
+
handlePayload({
|
70
|
+
type: 'payload',
|
71
|
+
model: 'post',
|
72
|
+
payload: [{ id: 4, name: 'test' }],
|
73
|
+
md5Hash: subscription.md5Hash,
|
74
|
+
idx: 1
|
75
|
+
})
|
76
|
+
|
77
|
+
handlePayload({
|
78
|
+
type: 'payload',
|
79
|
+
model: 'post',
|
80
|
+
payload: [{ id: 5, name: 'test it out' }],
|
81
|
+
md5Hash: subscription.md5Hash,
|
82
|
+
idx: 2
|
83
|
+
})
|
84
|
+
|
85
|
+
// The ID 4 should have been pruned
|
86
|
+
expect(store.getState().posts.ids).toStrictEqual([5])
|
87
|
+
})
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import createActions from './createActions'
|
2
|
+
import createJasonReducers from './createJasonReducers'
|
3
|
+
import createPayloadHandler from './createPayloadHandler'
|
4
|
+
import createOptDis from './createOptDis'
|
5
|
+
import createServerActionQueue from './createServerActionQueue'
|
6
|
+
import restClient from './restClient'
|
7
|
+
import pruneIdsMiddleware from './pruneIdsMiddleware'
|
8
|
+
import createTransportAdapater from './createTransportAdapter'
|
9
|
+
|
10
|
+
import { createEntityAdapter, createSlice, createReducer, configureStore } from '@reduxjs/toolkit'
|
11
|
+
|
12
|
+
import makeEager from './makeEager'
|
13
|
+
import { camelizeKeys } from 'humps'
|
14
|
+
import md5 from 'blueimp-md5'
|
15
|
+
import _ from 'lodash'
|
16
|
+
import React, { useState, useEffect } from 'react'
|
17
|
+
|
18
|
+
export default function useJason({ reducers, middleware = [], extraActions }: { reducers?: any, middleware?: any[], extraActions?: any }) {
|
19
|
+
const [store, setStore] = useState(null as any)
|
20
|
+
const [value, setValue] = useState(null as any)
|
21
|
+
|
22
|
+
useEffect(() => {
|
23
|
+
restClient.get('/jason/api/config')
|
24
|
+
.then(({ data: jasonConfig }) => {
|
25
|
+
const { schema: snakey_schema } = jasonConfig
|
26
|
+
const schema = camelizeKeys(snakey_schema)
|
27
|
+
console.debug({ schema })
|
28
|
+
|
29
|
+
const serverActionQueue = createServerActionQueue()
|
30
|
+
|
31
|
+
|
32
|
+
const allReducers = {
|
33
|
+
...reducers,
|
34
|
+
...createJasonReducers(schema)
|
35
|
+
}
|
36
|
+
|
37
|
+
console.debug({ allReducers })
|
38
|
+
|
39
|
+
const store = configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware(schema)] })
|
40
|
+
const dispatch = store.dispatch
|
41
|
+
|
42
|
+
const optDis = createOptDis(schema, dispatch, restClient, serverActionQueue)
|
43
|
+
const actions = createActions(schema, store, restClient, optDis, extraActions)
|
44
|
+
const eager = makeEager(schema)
|
45
|
+
|
46
|
+
let payloadHandlers = {}
|
47
|
+
let configs = {}
|
48
|
+
let subOptions = {}
|
49
|
+
|
50
|
+
function handlePayload(payload) {
|
51
|
+
const { md5Hash } = payload
|
52
|
+
|
53
|
+
const { handlePayload } = payloadHandlers[md5Hash]
|
54
|
+
if (handlePayload) {
|
55
|
+
handlePayload(payload)
|
56
|
+
} else {
|
57
|
+
console.warn("Payload arrived with no handler", payload, payloadHandlers)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
const transportAdapter = createTransportAdapater(jasonConfig, handlePayload, dispatch, () => _.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])))
|
62
|
+
|
63
|
+
function createSubscription(config, options = {}) {
|
64
|
+
// We need the hash to be consistent in Ruby / Javascript
|
65
|
+
const hashableConfig = _({ conditions: {}, includes: {}, ...config }).toPairs().sortBy(0).fromPairs().value()
|
66
|
+
const md5Hash = md5(JSON.stringify(hashableConfig))
|
67
|
+
payloadHandlers[md5Hash] = createPayloadHandler({ dispatch, serverActionQueue, transportAdapter, config })
|
68
|
+
configs[md5Hash] = hashableConfig
|
69
|
+
subOptions[md5Hash] = options
|
70
|
+
|
71
|
+
setTimeout(() => transportAdapter.createSubscription(hashableConfig), 500)
|
72
|
+
let pollInterval = null as any;
|
73
|
+
|
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
|
+
}
|
80
|
+
|
81
|
+
return {
|
82
|
+
remove() {
|
83
|
+
removeSubscription(hashableConfig)
|
84
|
+
if (pollInterval) clearInterval(pollInterval)
|
85
|
+
},
|
86
|
+
md5Hash
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
function removeSubscription(config) {
|
91
|
+
transportAdapter.removeSubscription(config)
|
92
|
+
const md5Hash = md5(JSON.stringify(config))
|
93
|
+
payloadHandlers[md5Hash].tearDown()
|
94
|
+
delete payloadHandlers[md5Hash]
|
95
|
+
delete configs[md5Hash]
|
96
|
+
delete subOptions[md5Hash]
|
97
|
+
}
|
98
|
+
|
99
|
+
setValue({
|
100
|
+
actions: actions,
|
101
|
+
subscribe: createSubscription,
|
102
|
+
eager,
|
103
|
+
handlePayload
|
104
|
+
})
|
105
|
+
setStore(store)
|
106
|
+
})
|
107
|
+
}, [])
|
108
|
+
|
109
|
+
return [store, value]
|
110
|
+
}
|
data/client/src/useSub.ts
CHANGED
@@ -1,10 +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
|
-
|
9
|
-
|
10
|
+
// @ts-ignore
|
11
|
+
return subscribe(config, options).remove
|
12
|
+
}, [configJson])
|
10
13
|
}
|
data/client/yarn.lock
CHANGED
@@ -813,7 +813,7 @@
|
|
813
813
|
"@babel/helper-validator-option" "^7.12.1"
|
814
814
|
"@babel/plugin-transform-typescript" "^7.12.1"
|
815
815
|
|
816
|
-
"@babel/runtime@^7.12.1", "@babel/runtime@^7.8.4":
|
816
|
+
"@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4":
|
817
817
|
version "7.12.5"
|
818
818
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
|
819
819
|
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
|
@@ -1082,6 +1082,18 @@
|
|
1082
1082
|
dependencies:
|
1083
1083
|
"@sinonjs/commons" "^1.7.0"
|
1084
1084
|
|
1085
|
+
"@testing-library/react-hooks@^5.0.3":
|
1086
|
+
version "5.0.3"
|
1087
|
+
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-5.0.3.tgz#dd0d2048817b013b266d35ca45e3ea48a19fd87e"
|
1088
|
+
integrity sha512-UrnnRc5II7LMH14xsYNm/WRch/67cBafmrSQcyFh0v+UUmSf1uzfB7zn5jQXSettGwOSxJwdQUN7PgkT0w22Lg==
|
1089
|
+
dependencies:
|
1090
|
+
"@babel/runtime" "^7.12.5"
|
1091
|
+
"@types/react" ">=16.9.0"
|
1092
|
+
"@types/react-dom" ">=16.9.0"
|
1093
|
+
"@types/react-test-renderer" ">=16.9.0"
|
1094
|
+
filter-console "^0.1.1"
|
1095
|
+
react-error-boundary "^3.1.0"
|
1096
|
+
|
1085
1097
|
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
|
1086
1098
|
version "7.1.12"
|
1087
1099
|
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d"
|
@@ -1164,6 +1176,33 @@
|
|
1164
1176
|
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00"
|
1165
1177
|
integrity sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==
|
1166
1178
|
|
1179
|
+
"@types/prop-types@*":
|
1180
|
+
version "15.7.3"
|
1181
|
+
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
1182
|
+
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
1183
|
+
|
1184
|
+
"@types/react-dom@>=16.9.0":
|
1185
|
+
version "17.0.0"
|
1186
|
+
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.0.tgz#b3b691eb956c4b3401777ee67b900cb28415d95a"
|
1187
|
+
integrity sha512-lUqY7OlkF/RbNtD5nIq7ot8NquXrdFrjSOR6+w9a9RFQevGi1oZO1dcJbXMeONAPKtZ2UrZOEJ5UOCVsxbLk/g==
|
1188
|
+
dependencies:
|
1189
|
+
"@types/react" "*"
|
1190
|
+
|
1191
|
+
"@types/react-test-renderer@>=16.9.0":
|
1192
|
+
version "17.0.0"
|
1193
|
+
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.0.tgz#9be47b375eeb906fced37049e67284a438d56620"
|
1194
|
+
integrity sha512-nvw+F81OmyzpyIE1S0xWpLonLUZCMewslPuA8BtjSKc5XEbn8zEQBXS7KuOLHTNnSOEM2Pum50gHOoZ62tqTRg==
|
1195
|
+
dependencies:
|
1196
|
+
"@types/react" "*"
|
1197
|
+
|
1198
|
+
"@types/react@*", "@types/react@>=16.9.0":
|
1199
|
+
version "17.0.0"
|
1200
|
+
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8"
|
1201
|
+
integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==
|
1202
|
+
dependencies:
|
1203
|
+
"@types/prop-types" "*"
|
1204
|
+
csstype "^3.0.2"
|
1205
|
+
|
1167
1206
|
"@types/stack-utils@^2.0.0":
|
1168
1207
|
version "2.0.0"
|
1169
1208
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
|
@@ -1742,6 +1781,11 @@ cssstyle@^2.2.0:
|
|
1742
1781
|
dependencies:
|
1743
1782
|
cssom "~0.3.6"
|
1744
1783
|
|
1784
|
+
csstype@^3.0.2:
|
1785
|
+
version "3.0.6"
|
1786
|
+
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef"
|
1787
|
+
integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==
|
1788
|
+
|
1745
1789
|
dashdash@^1.12.0:
|
1746
1790
|
version "1.14.1"
|
1747
1791
|
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
@@ -2081,6 +2125,11 @@ fill-range@^7.0.1:
|
|
2081
2125
|
dependencies:
|
2082
2126
|
to-regex-range "^5.0.1"
|
2083
2127
|
|
2128
|
+
filter-console@^0.1.1:
|
2129
|
+
version "0.1.1"
|
2130
|
+
resolved "https://registry.yarnpkg.com/filter-console/-/filter-console-0.1.1.tgz#6242be28982bba7415bcc6db74a79f4a294fa67c"
|
2131
|
+
integrity sha512-zrXoV1Uaz52DqPs+qEwNJWJFAWZpYJ47UNmpN9q4j+/EYsz85uV0DC9k8tRND5kYmoVzL0W+Y75q4Rg8sRJCdg==
|
2132
|
+
|
2084
2133
|
find-up@^4.0.0, find-up@^4.1.0:
|
2085
2134
|
version "4.1.0"
|
2086
2135
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
@@ -3596,12 +3645,19 @@ punycode@^2.1.0, punycode@^2.1.1:
|
|
3596
3645
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
3597
3646
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
3598
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
|
+
|
3599
3655
|
qs@~6.5.2:
|
3600
3656
|
version "6.5.2"
|
3601
3657
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
3602
3658
|
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
3603
3659
|
|
3604
|
-
react-dom@^16.
|
3660
|
+
react-dom@^16.9.x:
|
3605
3661
|
version "16.14.0"
|
3606
3662
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
|
3607
3663
|
integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==
|
@@ -3611,6 +3667,13 @@ react-dom@^16.8.3:
|
|
3611
3667
|
prop-types "^15.6.2"
|
3612
3668
|
scheduler "^0.19.1"
|
3613
3669
|
|
3670
|
+
react-error-boundary@^3.1.0:
|
3671
|
+
version "3.1.0"
|
3672
|
+
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.0.tgz#9487443df2f9ba1db90d8ab52351814907ea4af3"
|
3673
|
+
integrity sha512-lmPrdi5SLRJR+AeJkqdkGlW/CRkAUvZnETahK58J4xb5wpbfDngasEGu+w0T1iXEhVrYBJZeW+c4V1hILCnMWQ==
|
3674
|
+
dependencies:
|
3675
|
+
"@babel/runtime" "^7.12.5"
|
3676
|
+
|
3614
3677
|
react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1:
|
3615
3678
|
version "16.13.1"
|
3616
3679
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
@@ -3632,7 +3695,7 @@ react-redux@^7.2.2:
|
|
3632
3695
|
prop-types "^15.7.2"
|
3633
3696
|
react-is "^16.13.1"
|
3634
3697
|
|
3635
|
-
react@^16.
|
3698
|
+
react@^16.9.x:
|
3636
3699
|
version "16.14.0"
|
3637
3700
|
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
|
3638
3701
|
integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==
|
@@ -4302,6 +4365,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|
4302
4365
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
4303
4366
|
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
4304
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
|
+
|
4305
4373
|
type-check@~0.3.2:
|
4306
4374
|
version "0.3.2"
|
4307
4375
|
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|