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.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/Gemfile.lock +1 -1
- data/README.md +141 -5
- data/app/controllers/jason/api/pusher_controller.rb +15 -0
- data/app/controllers/jason/api_controller.rb +46 -4
- data/client/lib/JasonContext.d.ts +1 -1
- data/client/lib/JasonContext.js +4 -1
- data/client/lib/JasonProvider.js +1 -1
- data/client/lib/createJasonReducers.js +7 -0
- data/client/lib/createPayloadHandler.d.ts +6 -3
- data/client/lib/createPayloadHandler.js +8 -4
- data/client/lib/createTransportAdapter.d.ts +5 -0
- data/client/lib/createTransportAdapter.js +20 -0
- data/client/lib/index.d.ts +2 -0
- data/client/lib/index.js +3 -1
- data/client/lib/makeEager.js +2 -2
- data/client/lib/pruneIdsMiddleware.js +9 -11
- data/client/lib/restClient.d.ts +1 -1
- 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/useEager.d.ts +1 -0
- data/client/lib/useEager.js +12 -0
- data/client/lib/useJason.js +30 -35
- data/client/lib/useJason.test.js +8 -2
- data/client/lib/useSub.d.ts +1 -1
- data/client/lib/useSub.js +5 -3
- data/client/package.json +2 -1
- data/client/src/JasonContext.ts +4 -1
- data/client/src/JasonProvider.tsx +1 -1
- data/client/src/createJasonReducers.ts +7 -0
- data/client/src/createPayloadHandler.ts +9 -4
- data/client/src/createTransportAdapter.ts +13 -0
- data/client/src/index.ts +3 -1
- data/client/src/makeEager.ts +2 -2
- data/client/src/pruneIdsMiddleware.ts +11 -11
- data/client/src/restClient.ts +2 -1
- data/client/src/transportAdapters/actionCableAdapter.ts +38 -0
- data/client/src/transportAdapters/pusherAdapter.ts +72 -0
- data/client/src/useEager.ts +9 -0
- data/client/src/useJason.test.ts +8 -2
- data/client/src/useJason.ts +31 -36
- data/client/src/useSub.ts +5 -3
- data/client/yarn.lock +12 -0
- data/config/routes.rb +5 -1
- data/lib/jason.rb +56 -8
- data/lib/jason/broadcaster.rb +19 -0
- data/lib/jason/channel.rb +10 -3
- data/lib/jason/graph_helper.rb +165 -0
- data/lib/jason/includes_helper.rb +108 -0
- data/lib/jason/lua_generator.rb +23 -1
- data/lib/jason/publisher.rb +21 -17
- data/lib/jason/subscription.rb +208 -179
- data/lib/jason/version.rb +1 -1
- metadata +18 -2
data/client/lib/index.js
CHANGED
@@ -3,10 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.useSub = exports.useAct = exports.JasonProvider = void 0;
|
6
|
+
exports.useEager = exports.useSub = exports.useAct = exports.JasonProvider = void 0;
|
7
7
|
const JasonProvider_1 = __importDefault(require("./JasonProvider"));
|
8
8
|
const useAct_1 = __importDefault(require("./useAct"));
|
9
9
|
const useSub_1 = __importDefault(require("./useSub"));
|
10
|
+
const useEager_1 = __importDefault(require("./useEager"));
|
10
11
|
exports.JasonProvider = JasonProvider_1.default;
|
11
12
|
exports.useAct = useAct_1.default;
|
12
13
|
exports.useSub = useSub_1.default;
|
14
|
+
exports.useEager = useEager_1.default;
|
data/client/lib/makeEager.js
CHANGED
@@ -40,10 +40,10 @@ function default_1(schema) {
|
|
40
40
|
}
|
41
41
|
function useEager(entity, id = null, relations = []) {
|
42
42
|
if (id) {
|
43
|
-
return react_redux_1.useSelector(s => addRelations(s, Object.assign({}, s[entity].entities[String(id)]), entity, relations));
|
43
|
+
return react_redux_1.useSelector(s => addRelations(s, Object.assign({}, s[entity].entities[String(id)]), entity, relations), lodash_1.default.isEqual);
|
44
44
|
}
|
45
45
|
else {
|
46
|
-
return react_redux_1.useSelector(s => addRelations(s, lodash_1.default.values(s[entity].entities), entity, relations));
|
46
|
+
return react_redux_1.useSelector(s => addRelations(s, lodash_1.default.values(s[entity].entities), entity, relations), lodash_1.default.isEqual);
|
47
47
|
}
|
48
48
|
}
|
49
49
|
return useEager;
|
@@ -6,20 +6,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const lodash_1 = __importDefault(require("lodash"));
|
7
7
|
const pluralize_1 = __importDefault(require("pluralize"));
|
8
8
|
const pruneIdsMiddleware = schema => store => next => action => {
|
9
|
-
const { type } = action;
|
9
|
+
const { type, payload } = action;
|
10
10
|
const result = next(action);
|
11
11
|
const state = store.getState();
|
12
|
-
if (type === 'jasonModels/setSubscriptionIds') {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
lodash_1.default.
|
17
|
-
ids = lodash_1.default.union(ids, subscribedIds);
|
18
|
-
});
|
19
|
-
// Find IDs currently in Redux that aren't in any subscription
|
20
|
-
const idsToRemove = lodash_1.default.difference(state[pluralize_1.default(model)].ids, ids);
|
21
|
-
store.dispatch({ type: `${pluralize_1.default(model)}/removeMany`, payload: idsToRemove });
|
12
|
+
if (type === 'jasonModels/setSubscriptionIds' || type === 'jasonModels/removeSubscriptionIds') {
|
13
|
+
const { model, ids } = payload;
|
14
|
+
let idsInSubs = [];
|
15
|
+
lodash_1.default.map(state.jasonModels[model], (subscribedIds, k) => {
|
16
|
+
idsInSubs = lodash_1.default.union(idsInSubs, subscribedIds);
|
22
17
|
});
|
18
|
+
// Find IDs currently in Redux that aren't in any subscription
|
19
|
+
const idsToRemove = lodash_1.default.difference(state[pluralize_1.default(model)].ids, idsInSubs);
|
20
|
+
store.dispatch({ type: `${pluralize_1.default(model)}/removeMany`, payload: idsToRemove });
|
23
21
|
}
|
24
22
|
return result;
|
25
23
|
};
|
data/client/lib/restClient.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
declare const restClient:
|
1
|
+
declare const restClient: any;
|
2
2
|
export default restClient;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const actioncable_1 = require("@rails/actioncable");
|
4
|
+
function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected) {
|
5
|
+
const consumer = actioncable_1.createConsumer();
|
6
|
+
const subscription = (consumer.subscriptions.create({
|
7
|
+
channel: 'Jason::Channel'
|
8
|
+
}, {
|
9
|
+
connected: () => {
|
10
|
+
dispatch({ type: 'jason/upsert', payload: { connected: true } });
|
11
|
+
console.debug('Connected to ActionCable');
|
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
|
+
function getPayload(config, options) {
|
25
|
+
subscription.send(Object.assign({ getPayload: config }, options));
|
26
|
+
}
|
27
|
+
function createSubscription(config) {
|
28
|
+
subscription.send({ createSubscription: config });
|
29
|
+
}
|
30
|
+
function removeSubscription(config) {
|
31
|
+
subscription.send({ removeSubscription: config });
|
32
|
+
}
|
33
|
+
return { getPayload, createSubscription, removeSubscription };
|
34
|
+
}
|
35
|
+
exports.default = actionCableAdapter;
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const pusher_js_1 = __importDefault(require("pusher-js"));
|
7
|
+
const restClient_1 = __importDefault(require("../restClient"));
|
8
|
+
const uuid_1 = require("uuid");
|
9
|
+
const lodash_1 = __importDefault(require("lodash"));
|
10
|
+
function pusherAdapter(jasonConfig, handlePayload, dispatch) {
|
11
|
+
let consumerId = uuid_1.v4();
|
12
|
+
const { pusherKey, pusherRegion, pusherChannelPrefix } = jasonConfig;
|
13
|
+
const pusher = new pusher_js_1.default(pusherKey, {
|
14
|
+
cluster: 'eu',
|
15
|
+
forceTLS: true,
|
16
|
+
authEndpoint: '/jason/api/pusher/auth'
|
17
|
+
});
|
18
|
+
pusher.connection.bind('state_change', ({ current }) => {
|
19
|
+
if (current === 'connected') {
|
20
|
+
dispatch({ type: 'jason/upsert', payload: { connected: true } });
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
dispatch({ type: 'jason/upsert', payload: { connected: false } });
|
24
|
+
}
|
25
|
+
});
|
26
|
+
pusher.connection.bind('error', error => {
|
27
|
+
dispatch({ type: 'jason/upsert', payload: { connected: false } });
|
28
|
+
});
|
29
|
+
const configToChannel = {};
|
30
|
+
function createSubscription(config) {
|
31
|
+
restClient_1.default.post('/jason/api/create_subscription', { config, consumerId })
|
32
|
+
.then(({ data: { channelName } }) => {
|
33
|
+
configToChannel[JSON.stringify(config)] = channelName;
|
34
|
+
subscribeToChannel(channelName);
|
35
|
+
})
|
36
|
+
.catch(e => console.error(e));
|
37
|
+
}
|
38
|
+
function removeSubscription(config) {
|
39
|
+
const channelName = configToChannel[JSON.stringify(config)];
|
40
|
+
unsubscribeFromChannel(fullChannelName(channelName));
|
41
|
+
restClient_1.default.post('/jason/api/remove_subscription', { config, consumerId })
|
42
|
+
.catch(e => console.error(e));
|
43
|
+
}
|
44
|
+
function getPayload(config, options) {
|
45
|
+
restClient_1.default.post('/jason/api/get_payload', {
|
46
|
+
config,
|
47
|
+
options
|
48
|
+
})
|
49
|
+
.then(({ data }) => {
|
50
|
+
lodash_1.default.map(data, (payload, modelName) => {
|
51
|
+
handlePayload(payload);
|
52
|
+
});
|
53
|
+
})
|
54
|
+
.catch(e => console.error(e));
|
55
|
+
}
|
56
|
+
function subscribeToChannel(channelName) {
|
57
|
+
const channel = pusher.subscribe(fullChannelName(channelName));
|
58
|
+
channel.bind('changed', message => handlePayload(message));
|
59
|
+
}
|
60
|
+
function unsubscribeFromChannel(channelName) {
|
61
|
+
const channel = pusher.unsubscribe(fullChannelName(channelName));
|
62
|
+
}
|
63
|
+
function fullChannelName(channelName) {
|
64
|
+
return `private-${pusherChannelPrefix}-${channelName}`;
|
65
|
+
}
|
66
|
+
return { getPayload, createSubscription, removeSubscription };
|
67
|
+
}
|
68
|
+
exports.default = pusherAdapter;
|
@@ -0,0 +1 @@
|
|
1
|
+
export default function useEager(entity: any, id?: null, relations?: never[]): void;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const JasonContext_1 = __importDefault(require("./JasonContext"));
|
7
|
+
const react_1 = require("react");
|
8
|
+
function useEager(entity, id = null, relations = []) {
|
9
|
+
const { eager } = react_1.useContext(JasonContext_1.default);
|
10
|
+
return eager(entity, id, relations);
|
11
|
+
}
|
12
|
+
exports.default = useEager;
|
data/client/lib/useJason.js
CHANGED
@@ -10,7 +10,7 @@ const createOptDis_1 = __importDefault(require("./createOptDis"));
|
|
10
10
|
const createServerActionQueue_1 = __importDefault(require("./createServerActionQueue"));
|
11
11
|
const restClient_1 = __importDefault(require("./restClient"));
|
12
12
|
const pruneIdsMiddleware_1 = __importDefault(require("./pruneIdsMiddleware"));
|
13
|
-
const
|
13
|
+
const createTransportAdapter_1 = __importDefault(require("./createTransportAdapter"));
|
14
14
|
const toolkit_1 = require("@reduxjs/toolkit");
|
15
15
|
const makeEager_1 = __importDefault(require("./makeEager"));
|
16
16
|
const humps_1 = require("humps");
|
@@ -20,14 +20,13 @@ const react_1 = require("react");
|
|
20
20
|
function useJason({ reducers, middleware = [], extraActions }) {
|
21
21
|
const [store, setStore] = react_1.useState(null);
|
22
22
|
const [value, setValue] = react_1.useState(null);
|
23
|
-
const [connected, setConnected] = react_1.useState(false);
|
24
23
|
react_1.useEffect(() => {
|
25
|
-
restClient_1.default.get('/jason/api/
|
26
|
-
.then(({ data:
|
24
|
+
restClient_1.default.get('/jason/api/config')
|
25
|
+
.then(({ data: jasonConfig }) => {
|
26
|
+
const { schema: snakey_schema } = jasonConfig;
|
27
27
|
const schema = humps_1.camelizeKeys(snakey_schema);
|
28
28
|
console.debug({ schema });
|
29
29
|
const serverActionQueue = createServerActionQueue_1.default();
|
30
|
-
const consumer = actioncable_1.createConsumer();
|
31
30
|
const allReducers = Object.assign(Object.assign({}, reducers), createJasonReducers_1.default(schema));
|
32
31
|
console.debug({ allReducers });
|
33
32
|
const store = toolkit_1.configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware_1.default(schema)] });
|
@@ -37,63 +36,59 @@ function useJason({ reducers, middleware = [], extraActions }) {
|
|
37
36
|
const eager = makeEager_1.default(schema);
|
38
37
|
let payloadHandlers = {};
|
39
38
|
let configs = {};
|
39
|
+
let subOptions = {};
|
40
40
|
function handlePayload(payload) {
|
41
41
|
const { md5Hash } = payload;
|
42
|
-
const
|
43
|
-
if (
|
44
|
-
|
42
|
+
const { handlePayload } = payloadHandlers[md5Hash];
|
43
|
+
if (handlePayload) {
|
44
|
+
handlePayload(payload);
|
45
45
|
}
|
46
46
|
else {
|
47
47
|
console.warn("Payload arrived with no handler", payload, payloadHandlers);
|
48
48
|
}
|
49
49
|
}
|
50
|
-
const
|
51
|
-
|
52
|
-
}, {
|
53
|
-
connected: () => {
|
54
|
-
setConnected(true);
|
55
|
-
dispatch({ type: 'jason/upsert', payload: { connected: true } });
|
56
|
-
console.debug('Connected to ActionCable');
|
57
|
-
// When AC loses connection - all state is lost, so we need to re-initialize all subscriptions
|
58
|
-
lodash_1.default.values(configs).forEach(config => createSubscription(config));
|
59
|
-
},
|
60
|
-
received: payload => {
|
61
|
-
handlePayload(payload);
|
62
|
-
console.debug("ActionCable Payload received: ", payload);
|
63
|
-
},
|
64
|
-
disconnected: () => {
|
65
|
-
setConnected(false);
|
66
|
-
dispatch({ type: 'jason/upsert', payload: { connected: false } });
|
67
|
-
console.warn('Disconnected from ActionCable');
|
68
|
-
}
|
69
|
-
}));
|
70
|
-
function createSubscription(config) {
|
50
|
+
const transportAdapter = createTransportAdapter_1.default(jasonConfig, handlePayload, dispatch, () => lodash_1.default.keys(configs).forEach(md5Hash => createSubscription(configs[md5Hash], subOptions[md5Hash])));
|
51
|
+
function createSubscription(config, options = {}) {
|
71
52
|
// We need the hash to be consistent in Ruby / Javascript
|
72
53
|
const hashableConfig = lodash_1.default(Object.assign({ conditions: {}, includes: {} }, config)).toPairs().sortBy(0).fromPairs().value();
|
73
54
|
const md5Hash = blueimp_md5_1.default(JSON.stringify(hashableConfig));
|
74
|
-
payloadHandlers[md5Hash] = createPayloadHandler_1.default({ dispatch, serverActionQueue,
|
55
|
+
payloadHandlers[md5Hash] = createPayloadHandler_1.default({ dispatch, serverActionQueue, transportAdapter, config });
|
75
56
|
configs[md5Hash] = hashableConfig;
|
76
|
-
|
57
|
+
subOptions[md5Hash] = options;
|
58
|
+
setTimeout(() => transportAdapter.createSubscription(hashableConfig), 500);
|
59
|
+
let pollInterval = null;
|
60
|
+
// This is only for debugging / dev - not prod!
|
61
|
+
// @ts-ignore
|
62
|
+
if (options.pollInterval) {
|
63
|
+
// @ts-ignore
|
64
|
+
pollInterval = setInterval(() => transportAdapter.getPayload(hashableConfig, { forceRefresh: true }), options.pollInterval);
|
65
|
+
}
|
77
66
|
return {
|
78
|
-
remove
|
67
|
+
remove() {
|
68
|
+
removeSubscription(hashableConfig);
|
69
|
+
if (pollInterval)
|
70
|
+
clearInterval(pollInterval);
|
71
|
+
},
|
79
72
|
md5Hash
|
80
73
|
};
|
81
74
|
}
|
82
75
|
function removeSubscription(config) {
|
83
|
-
|
76
|
+
transportAdapter.removeSubscription(config);
|
84
77
|
const md5Hash = blueimp_md5_1.default(JSON.stringify(config));
|
78
|
+
payloadHandlers[md5Hash].tearDown();
|
85
79
|
delete payloadHandlers[md5Hash];
|
86
80
|
delete configs[md5Hash];
|
81
|
+
delete subOptions[md5Hash];
|
87
82
|
}
|
88
83
|
setValue({
|
89
84
|
actions: actions,
|
90
|
-
subscribe:
|
85
|
+
subscribe: createSubscription,
|
91
86
|
eager,
|
92
87
|
handlePayload
|
93
88
|
});
|
94
89
|
setStore(store);
|
95
90
|
});
|
96
91
|
}, []);
|
97
|
-
return [store, value
|
92
|
+
return [store, value];
|
98
93
|
}
|
99
94
|
exports.default = useJason;
|
data/client/lib/useJason.test.js
CHANGED
@@ -17,7 +17,10 @@ const useJason_1 = __importDefault(require("./useJason"));
|
|
17
17
|
const restClient_1 = __importDefault(require("./restClient"));
|
18
18
|
jest.mock('./restClient');
|
19
19
|
test('it works', () => __awaiter(void 0, void 0, void 0, function* () {
|
20
|
-
const resp = { data: {
|
20
|
+
const resp = { data: {
|
21
|
+
schema: { post: {} },
|
22
|
+
transportService: 'action_cable'
|
23
|
+
} };
|
21
24
|
// @ts-ignore
|
22
25
|
restClient_1.default.get.mockResolvedValue(resp);
|
23
26
|
const { result, waitForNextUpdate } = react_hooks_1.renderHook(() => useJason_1.default({ reducers: {
|
@@ -50,7 +53,10 @@ test('it works', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
53
|
});
|
51
54
|
}));
|
52
55
|
test('pruning IDs', () => __awaiter(void 0, void 0, void 0, function* () {
|
53
|
-
const resp = { data: {
|
56
|
+
const resp = { data: {
|
57
|
+
schema: { post: {} },
|
58
|
+
transportService: 'action_cable'
|
59
|
+
} };
|
54
60
|
// @ts-ignore
|
55
61
|
restClient_1.default.get.mockResolvedValue(resp);
|
56
62
|
const { result, waitForNextUpdate } = react_hooks_1.renderHook(() => useJason_1.default({ reducers: {
|
data/client/lib/useSub.d.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export default function useSub(config: any): void;
|
1
|
+
export default function useSub(config: any, options?: {}): void;
|
data/client/lib/useSub.js
CHANGED
@@ -5,11 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const JasonContext_1 = __importDefault(require("./JasonContext"));
|
7
7
|
const react_1 = require("react");
|
8
|
-
function useSub(config) {
|
8
|
+
function useSub(config, options = {}) {
|
9
|
+
// useEffect uses strict equality
|
10
|
+
const configJson = JSON.stringify(config);
|
9
11
|
const subscribe = react_1.useContext(JasonContext_1.default).subscribe;
|
10
12
|
react_1.useEffect(() => {
|
11
13
|
// @ts-ignore
|
12
|
-
return subscribe(config);
|
13
|
-
}, []);
|
14
|
+
return subscribe(config, options).remove;
|
15
|
+
}, [configJson]);
|
14
16
|
}
|
15
17
|
exports.default = useSub;
|
data/client/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@jamesr2323/jason",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.6.2",
|
4
4
|
"module": "./lib/index.js",
|
5
5
|
"types": "./lib/index.d.ts",
|
6
6
|
"scripts": {
|
@@ -16,6 +16,7 @@
|
|
16
16
|
"jsonpatch": "^3.0.1",
|
17
17
|
"lodash": "^4.17.20",
|
18
18
|
"pluralize": "^8.0.0",
|
19
|
+
"pusher-js": "^7.0.3",
|
19
20
|
"uuid": "^8.3.1"
|
20
21
|
},
|
21
22
|
"devDependencies": {
|
data/client/src/JasonContext.ts
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
import { createContext } from 'react'
|
2
|
+
const eager = function(entity, id, relations) {
|
3
|
+
console.error("Eager called but is not implemented")
|
4
|
+
}
|
2
5
|
|
3
|
-
const context = createContext({ actions: {} as any, subscribe: null, eager
|
6
|
+
const context = createContext({ actions: {} as any, subscribe: null, eager })
|
4
7
|
|
5
8
|
export default context
|
@@ -4,7 +4,7 @@ import { Provider } from 'react-redux'
|
|
4
4
|
import JasonContext from './JasonContext'
|
5
5
|
|
6
6
|
const JasonProvider = ({ reducers, middleware, extraActions, children }: { reducers?: any, middleware?: any, extraActions?: any, children?: React.FC }) => {
|
7
|
-
const [store, value
|
7
|
+
const [store, value] = useJason({ reducers, middleware, extraActions })
|
8
8
|
|
9
9
|
if(!(store && value)) return <div /> // Wait for async fetch of schema to complete
|
10
10
|
|
@@ -42,6 +42,7 @@ function generateJasonSlices(models) {
|
|
42
42
|
setSubscriptionIds(s,a) {
|
43
43
|
const { payload } = a
|
44
44
|
const { subscriptionId, model, ids } = payload
|
45
|
+
console.log({ initialState })
|
45
46
|
s[model][subscriptionId] = ids
|
46
47
|
},
|
47
48
|
addSubscriptionId(s,a) {
|
@@ -53,6 +54,12 @@ function generateJasonSlices(models) {
|
|
53
54
|
const { payload } = a
|
54
55
|
const { subscriptionId, model, id } = payload
|
55
56
|
s[model][subscriptionId] = _.remove(s[model][subscriptionId] || [], id)
|
57
|
+
},
|
58
|
+
removeSubscription(s, a) {
|
59
|
+
const { payload: { subscriptionId } } = a
|
60
|
+
_.map(models, model => {
|
61
|
+
delete s[model][subscriptionId]
|
62
|
+
})
|
56
63
|
}
|
57
64
|
}
|
58
65
|
}).reducer
|
@@ -9,7 +9,7 @@ function diffSeconds(dt2, dt1) {
|
|
9
9
|
return Math.abs(Math.round(diff))
|
10
10
|
}
|
11
11
|
|
12
|
-
export default function createPayloadHandler({ dispatch, serverActionQueue,
|
12
|
+
export default function createPayloadHandler({ dispatch, serverActionQueue, transportAdapter, config }) {
|
13
13
|
const subscriptionId = uuidv4()
|
14
14
|
|
15
15
|
let idx = {}
|
@@ -20,7 +20,7 @@ export default function createPayloadHandler({ dispatch, serverActionQueue, subs
|
|
20
20
|
let checkInterval
|
21
21
|
|
22
22
|
function getPayload() {
|
23
|
-
setTimeout(() =>
|
23
|
+
setTimeout(() => transportAdapter.getPayload(config), 1000)
|
24
24
|
}
|
25
25
|
|
26
26
|
function camelizeKeys(item) {
|
@@ -46,7 +46,7 @@ export default function createPayloadHandler({ dispatch, serverActionQueue, subs
|
|
46
46
|
const ids = payload.map(instance => instance.id)
|
47
47
|
dispatch({ type: `jasonModels/setSubscriptionIds`, payload: { model, subscriptionId, ids }})
|
48
48
|
} else if (destroy) {
|
49
|
-
|
49
|
+
// Middleware will determine if this model should be removed if it isn't in any other subscriptions
|
50
50
|
dispatch({ type: `jasonModels/removeSubscriptionId`, payload: { model, subscriptionId, id }})
|
51
51
|
} else {
|
52
52
|
dispatch({ type: `${pluralize(model)}/upsert`, payload })
|
@@ -97,5 +97,10 @@ export default function createPayloadHandler({ dispatch, serverActionQueue, subs
|
|
97
97
|
|
98
98
|
tGetPayload()
|
99
99
|
|
100
|
-
|
100
|
+
// Clean up after ourselves
|
101
|
+
function tearDown() {
|
102
|
+
dispatch({ type: `jasonModels/removeSubscription`, payload: { subscriptionId }})
|
103
|
+
}
|
104
|
+
|
105
|
+
return { handlePayload, tearDown }
|
101
106
|
}
|