jason-rails 0.3.0 → 0.6.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/.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;
|