jason-rails 0.3.0 → 0.6.0
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 +184 -0
- data/README.md +118 -10
- data/app/controllers/jason/api/pusher_controller.rb +15 -0
- data/app/controllers/jason/api_controller.rb +78 -0
- data/client/babel.config.js +13 -0
- data/client/lib/JasonContext.d.ts +6 -1
- data/client/lib/JasonProvider.d.ts +6 -5
- data/client/lib/JasonProvider.js +5 -97
- 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 +49 -3
- data/client/lib/createOptDis.d.ts +1 -0
- data/client/lib/createOptDis.js +43 -0
- data/client/lib/createPayloadHandler.d.ts +9 -1
- data/client/lib/createPayloadHandler.js +52 -43
- 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/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 +6 -5
- 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 +19 -4
- data/client/src/JasonProvider.tsx +6 -96
- data/client/src/actionFactory.ts +1 -1
- data/client/src/createActions.ts +2 -33
- data/client/src/createJasonReducers.ts +57 -3
- data/client/src/createOptDis.ts +45 -0
- data/client/src/createPayloadHandler.ts +58 -47
- 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/deepCamelizeKeys.test.ts +113 -0
- data/client/src/deepCamelizeKeys.ts +17 -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 +4607 -81
- data/config/routes.rb +8 -0
- data/jason-rails.gemspec +9 -0
- data/lib/jason.rb +40 -1
- data/lib/jason/api_model.rb +15 -9
- data/lib/jason/broadcaster.rb +19 -0
- data/lib/jason/channel.rb +50 -21
- data/lib/jason/engine.rb +5 -0
- 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 +103 -30
- data/lib/jason/publisher_old.rb +112 -0
- data/lib/jason/subscription.rb +352 -101
- data/lib/jason/subscription_old.rb +171 -0
- data/lib/jason/version.rb +1 -1
- metadata +151 -4
@@ -0,0 +1,48 @@
|
|
1
|
+
"use strict";
|
2
|
+
// A FIFO queue with deduping of actions whose effect will be cancelled by later actions
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
5
|
+
};
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
8
|
+
function createServerActionQueue() {
|
9
|
+
const queue = [];
|
10
|
+
let inFlight = false;
|
11
|
+
function addItem(item) {
|
12
|
+
// Check if there are any items ahead in the queue that this item would effectively overwrite.
|
13
|
+
// In that case we can remove them
|
14
|
+
// If this is an upsert && item ID is the same && current item attributes are a superset of the earlier item attributes
|
15
|
+
const { type, payload } = item;
|
16
|
+
if (type.split('/')[1] !== 'upsert') {
|
17
|
+
queue.push(item);
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
lodash_1.default.remove(queue, item => {
|
21
|
+
const { type: itemType, payload: itemPayload } = item;
|
22
|
+
if (type !== itemType)
|
23
|
+
return false;
|
24
|
+
if (itemPayload.id !== payload.id)
|
25
|
+
return false;
|
26
|
+
// Check that all keys of itemPayload are in payload.
|
27
|
+
return lodash_1.default.difference(lodash_1.default.keys(itemPayload), lodash_1.default.keys(payload)).length === 0;
|
28
|
+
});
|
29
|
+
queue.push(item);
|
30
|
+
}
|
31
|
+
return {
|
32
|
+
addItem,
|
33
|
+
getItem: () => {
|
34
|
+
if (inFlight)
|
35
|
+
return false;
|
36
|
+
const item = queue.shift();
|
37
|
+
if (item) {
|
38
|
+
inFlight = true;
|
39
|
+
return item;
|
40
|
+
}
|
41
|
+
return false;
|
42
|
+
},
|
43
|
+
itemProcessed: () => inFlight = false,
|
44
|
+
fullySynced: () => queue.length === 0 && !inFlight,
|
45
|
+
getData: () => ({ queue, inFlight })
|
46
|
+
};
|
47
|
+
}
|
48
|
+
exports.default = createServerActionQueue;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,37 @@
|
|
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 createServerActionQueue_1 = __importDefault(require("./createServerActionQueue"));
|
7
|
+
test('Adding items', () => {
|
8
|
+
const serverActionQueue = createServerActionQueue_1.default();
|
9
|
+
serverActionQueue.addItem({ type: 'entity/add', payload: { id: 'abc', attribute: 1 } });
|
10
|
+
const item = serverActionQueue.getItem();
|
11
|
+
expect(item).toStrictEqual({ type: 'entity/add', payload: { id: 'abc', attribute: 1 } });
|
12
|
+
});
|
13
|
+
test('Deduping of items that will overwrite each other', () => {
|
14
|
+
const serverActionQueue = createServerActionQueue_1.default();
|
15
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 1 } });
|
16
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 2 } });
|
17
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 3 } });
|
18
|
+
const item = serverActionQueue.getItem();
|
19
|
+
expect(item).toStrictEqual({ type: 'entity/upsert', payload: { id: 'abc', attribute: 3 } });
|
20
|
+
});
|
21
|
+
test('Deduping of items with a superset', () => {
|
22
|
+
const serverActionQueue = createServerActionQueue_1.default();
|
23
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 1 } });
|
24
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 2, attribute2: 'test' } });
|
25
|
+
const item = serverActionQueue.getItem();
|
26
|
+
expect(item).toStrictEqual({ type: 'entity/upsert', payload: { id: 'abc', attribute: 2, attribute2: 'test' } });
|
27
|
+
});
|
28
|
+
test("doesn't dedupe items with some attributes missing", () => {
|
29
|
+
const serverActionQueue = createServerActionQueue_1.default();
|
30
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute: 1 } });
|
31
|
+
serverActionQueue.addItem({ type: 'entity/upsert', payload: { id: 'abc', attribute2: 'test' } });
|
32
|
+
const item = serverActionQueue.getItem();
|
33
|
+
serverActionQueue.itemProcessed();
|
34
|
+
const item2 = serverActionQueue.getItem();
|
35
|
+
expect(item).toStrictEqual({ type: 'entity/upsert', payload: { id: 'abc', attribute: 1 } });
|
36
|
+
expect(item2).toStrictEqual({ type: 'entity/upsert', payload: { id: 'abc', attribute2: 'test' } });
|
37
|
+
});
|
@@ -0,0 +1,20 @@
|
|
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 actionCableAdapter_1 = __importDefault(require("./transportAdapters/actionCableAdapter"));
|
7
|
+
const pusherAdapter_1 = __importDefault(require("./transportAdapters/pusherAdapter"));
|
8
|
+
function createTransportAdapter(jasonConfig, handlePayload, dispatch, onConnect) {
|
9
|
+
const { transportService } = jasonConfig;
|
10
|
+
if (transportService === 'action_cable') {
|
11
|
+
return actionCableAdapter_1.default(jasonConfig, handlePayload, dispatch, onConnect);
|
12
|
+
}
|
13
|
+
else if (transportService === 'pusher') {
|
14
|
+
return pusherAdapter_1.default(jasonConfig, handlePayload, dispatch);
|
15
|
+
}
|
16
|
+
else {
|
17
|
+
throw (`Transport adapter does not exist for ${transportService}`);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
exports.default = createTransportAdapter;
|
@@ -0,0 +1 @@
|
|
1
|
+
export default function deepCamelizeKeys(item: any, excludeIf?: (k: any) => boolean): any;
|
@@ -0,0 +1,23 @@
|
|
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 lodash_1 = __importDefault(require("lodash"));
|
7
|
+
function deepCamelizeKeys(item, excludeIf = k => false) {
|
8
|
+
function camelizeKey(key) {
|
9
|
+
if (excludeIf(key))
|
10
|
+
return key;
|
11
|
+
return lodash_1.default.camelCase(key);
|
12
|
+
}
|
13
|
+
if (lodash_1.default.isArray(item)) {
|
14
|
+
return lodash_1.default.map(item, item => deepCamelizeKeys(item, excludeIf));
|
15
|
+
}
|
16
|
+
else if (lodash_1.default.isObject(item)) {
|
17
|
+
return lodash_1.default.mapValues(lodash_1.default.mapKeys(item, (v, k) => camelizeKey(k)), (v, k) => deepCamelizeKeys(v, excludeIf));
|
18
|
+
}
|
19
|
+
else {
|
20
|
+
return item;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
exports.default = deepCamelizeKeys;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,106 @@
|
|
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 deepCamelizeKeys_1 = __importDefault(require("./deepCamelizeKeys"));
|
7
|
+
test('scalar number', () => {
|
8
|
+
expect(deepCamelizeKeys_1.default(1)).toBe(1);
|
9
|
+
});
|
10
|
+
test('scalar number float', () => {
|
11
|
+
expect(deepCamelizeKeys_1.default(1.123)).toBe(1.123);
|
12
|
+
});
|
13
|
+
test('scalar string', () => {
|
14
|
+
expect(deepCamelizeKeys_1.default('test')).toBe('test');
|
15
|
+
});
|
16
|
+
test('scalar null', () => {
|
17
|
+
expect(deepCamelizeKeys_1.default(null)).toBe(null);
|
18
|
+
});
|
19
|
+
test('scalar boolean', () => {
|
20
|
+
expect(deepCamelizeKeys_1.default(true)).toBe(true);
|
21
|
+
});
|
22
|
+
test('object with existing camelized keys', () => {
|
23
|
+
expect(deepCamelizeKeys_1.default({ testMe: 'test' })).toStrictEqual({ testMe: 'test' });
|
24
|
+
});
|
25
|
+
test('array with existing camelized keys', () => {
|
26
|
+
expect(deepCamelizeKeys_1.default([{ testMe: 'test' }, { testMe2: 'test' }])).toStrictEqual([{ testMe: 'test' }, { testMe2: 'test' }]);
|
27
|
+
});
|
28
|
+
test('object with mixed keys', () => {
|
29
|
+
expect(deepCamelizeKeys_1.default({ testMe: 'test', test_2: 'dog', test_me2: true })).toStrictEqual({ testMe: 'test', test2: 'dog', testMe2: true });
|
30
|
+
});
|
31
|
+
test('array with mixed keys', () => {
|
32
|
+
expect(deepCamelizeKeys_1.default([
|
33
|
+
{ testMe: 'test', test_2: 'dog', test_me2: true },
|
34
|
+
{ testMe3: 'test', test_3: 'dog', test_me4: true }
|
35
|
+
])).toStrictEqual([
|
36
|
+
{ testMe: 'test', test2: 'dog', testMe2: true },
|
37
|
+
{ testMe3: 'test', test3: 'dog', testMe4: true }
|
38
|
+
]);
|
39
|
+
});
|
40
|
+
test('nested with object at top level', () => {
|
41
|
+
expect(deepCamelizeKeys_1.default({
|
42
|
+
test_me: {
|
43
|
+
test_me2: {
|
44
|
+
test_me3: [
|
45
|
+
{ test_it_out: '49' },
|
46
|
+
{ test_fun: 'what' }
|
47
|
+
]
|
48
|
+
}
|
49
|
+
}
|
50
|
+
})).toStrictEqual({
|
51
|
+
testMe: {
|
52
|
+
testMe2: {
|
53
|
+
testMe3: [
|
54
|
+
{ testItOut: '49' },
|
55
|
+
{ testFun: 'what' }
|
56
|
+
]
|
57
|
+
}
|
58
|
+
}
|
59
|
+
});
|
60
|
+
});
|
61
|
+
test('nested with object at top level', () => {
|
62
|
+
expect(deepCamelizeKeys_1.default([{
|
63
|
+
test_me: {
|
64
|
+
test_me2: {
|
65
|
+
test_me3: [
|
66
|
+
{ test_it_out: '49' },
|
67
|
+
{ test_fun: 'what' }
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}, {
|
72
|
+
test_it52: 'what?'
|
73
|
+
}])).toStrictEqual([{
|
74
|
+
testMe: {
|
75
|
+
testMe2: {
|
76
|
+
testMe3: [
|
77
|
+
{ testItOut: '49' },
|
78
|
+
{ testFun: 'what' }
|
79
|
+
]
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}, {
|
83
|
+
testIt52: 'what?'
|
84
|
+
}]);
|
85
|
+
});
|
86
|
+
test('excludes keys by function', () => {
|
87
|
+
expect(deepCamelizeKeys_1.default({
|
88
|
+
test_me: {
|
89
|
+
test_me2: {
|
90
|
+
test_me3: [
|
91
|
+
{ test_it_out: '49' },
|
92
|
+
{ test_fun: 'what' }
|
93
|
+
]
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}, k => (k === 'test_me2'))).toStrictEqual({
|
97
|
+
testMe: {
|
98
|
+
test_me2: {
|
99
|
+
testMe3: [
|
100
|
+
{ testItOut: '49' },
|
101
|
+
{ testFun: 'what' }
|
102
|
+
]
|
103
|
+
}
|
104
|
+
}
|
105
|
+
});
|
106
|
+
});
|
data/client/lib/index.d.ts
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
/// <reference types="react" />
|
1
2
|
import _useAct from './useAct';
|
2
3
|
import _useSub from './useSub';
|
3
4
|
export declare const JasonProvider: ({ reducers, middleware, extraActions, children }: {
|
4
|
-
reducers
|
5
|
-
middleware
|
6
|
-
extraActions
|
7
|
-
children
|
8
|
-
}) =>
|
5
|
+
reducers?: any;
|
6
|
+
middleware?: any;
|
7
|
+
extraActions?: any;
|
8
|
+
children?: import("react").FC<{}> | undefined;
|
9
|
+
}) => JSX.Element;
|
9
10
|
export declare const useAct: typeof _useAct;
|
10
11
|
export declare const useSub: typeof _useSub;
|
@@ -0,0 +1,24 @@
|
|
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 lodash_1 = __importDefault(require("lodash"));
|
7
|
+
const pluralize_1 = __importDefault(require("pluralize"));
|
8
|
+
const pruneIdsMiddleware = schema => store => next => action => {
|
9
|
+
const { type, payload } = action;
|
10
|
+
const result = next(action);
|
11
|
+
const state = store.getState();
|
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);
|
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 });
|
21
|
+
}
|
22
|
+
return result;
|
23
|
+
};
|
24
|
+
exports.default = pruneIdsMiddleware;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
var _a;
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
8
|
+
const axios_case_converter_1 = __importDefault(require("axios-case-converter"));
|
9
|
+
const uuid_1 = require("uuid");
|
10
|
+
const csrfToken = (_a = document === null || document === void 0 ? void 0 : document.querySelector("meta[name=csrf-token]")) === null || _a === void 0 ? void 0 : _a.content;
|
11
|
+
axios_1.default.defaults.headers.common['X-CSRF-Token'] = csrfToken;
|
12
|
+
const restClient = axios_case_converter_1.default(axios_1.default.create(), {
|
13
|
+
preservedKeys: (key) => {
|
14
|
+
return uuid_1.validate(key);
|
15
|
+
}
|
16
|
+
});
|
17
|
+
exports.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;
|