jason-rails 0.4.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.ruby-version +1 -0
  4. data/Gemfile.lock +152 -2
  5. data/README.md +117 -5
  6. data/app/controllers/jason/api/pusher_controller.rb +15 -0
  7. data/app/controllers/jason/api_controller.rb +44 -2
  8. data/client/lib/JasonContext.d.ts +6 -1
  9. data/client/lib/JasonContext.js +4 -1
  10. data/client/lib/JasonProvider.d.ts +2 -2
  11. data/client/lib/JasonProvider.js +5 -124
  12. data/client/lib/createJasonReducers.js +48 -3
  13. data/client/lib/createOptDis.js +0 -2
  14. data/client/lib/createPayloadHandler.d.ts +9 -1
  15. data/client/lib/createPayloadHandler.js +47 -55
  16. data/client/lib/createServerActionQueue.d.ts +10 -0
  17. data/client/lib/createServerActionQueue.js +48 -0
  18. data/client/lib/createServerActionQueue.test.d.ts +1 -0
  19. data/client/lib/createServerActionQueue.test.js +37 -0
  20. data/client/lib/createTransportAdapter.d.ts +5 -0
  21. data/client/lib/createTransportAdapter.js +20 -0
  22. data/client/lib/index.d.ts +5 -2
  23. data/client/lib/index.js +3 -1
  24. data/client/lib/makeEager.js +2 -2
  25. data/client/lib/pruneIdsMiddleware.d.ts +2 -0
  26. data/client/lib/pruneIdsMiddleware.js +24 -0
  27. data/client/lib/restClient.d.ts +2 -0
  28. data/client/lib/restClient.js +17 -0
  29. data/client/lib/transportAdapters/actionCableAdapter.d.ts +5 -0
  30. data/client/lib/transportAdapters/actionCableAdapter.js +35 -0
  31. data/client/lib/transportAdapters/pusherAdapter.d.ts +5 -0
  32. data/client/lib/transportAdapters/pusherAdapter.js +68 -0
  33. data/client/lib/useJason.d.ts +5 -0
  34. data/client/lib/useJason.js +94 -0
  35. data/client/lib/useJason.test.d.ts +1 -0
  36. data/client/lib/useJason.test.js +85 -0
  37. data/client/lib/useSub.d.ts +1 -1
  38. data/client/lib/useSub.js +6 -3
  39. data/client/package.json +5 -3
  40. data/client/src/JasonContext.ts +4 -1
  41. data/client/src/JasonProvider.tsx +5 -123
  42. data/client/src/createJasonReducers.ts +56 -3
  43. data/client/src/createOptDis.ts +0 -2
  44. data/client/src/createPayloadHandler.ts +53 -64
  45. data/client/src/createServerActionQueue.test.ts +42 -0
  46. data/client/src/createServerActionQueue.ts +47 -0
  47. data/client/src/createTransportAdapter.ts +13 -0
  48. data/client/src/index.ts +3 -1
  49. data/client/src/makeEager.ts +2 -2
  50. data/client/src/pruneIdsMiddleware.ts +24 -0
  51. data/client/src/restClient.ts +14 -0
  52. data/client/src/transportAdapters/actionCableAdapter.ts +38 -0
  53. data/client/src/transportAdapters/pusherAdapter.ts +72 -0
  54. data/client/src/useJason.test.ts +87 -0
  55. data/client/src/useJason.ts +110 -0
  56. data/client/src/useSub.ts +6 -3
  57. data/client/yarn.lock +71 -3
  58. data/config/routes.rb +5 -1
  59. data/jason-rails.gemspec +4 -0
  60. data/lib/jason.rb +61 -1
  61. data/lib/jason/api_model.rb +2 -12
  62. data/lib/jason/broadcaster.rb +19 -0
  63. data/lib/jason/channel.rb +50 -21
  64. data/lib/jason/graph_helper.rb +165 -0
  65. data/lib/jason/includes_helper.rb +108 -0
  66. data/lib/jason/lua_generator.rb +71 -0
  67. data/lib/jason/publisher.rb +82 -37
  68. data/lib/jason/publisher_old.rb +112 -0
  69. data/lib/jason/subscription.rb +349 -97
  70. data/lib/jason/subscription_old.rb +171 -0
  71. data/lib/jason/version.rb +1 -1
  72. metadata +80 -3
@@ -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,5 @@
1
+ export default function createTransportAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnect: any): {
2
+ getPayload: (config: any, options: any) => void;
3
+ createSubscription: (config: any) => void;
4
+ removeSubscription: (config: any) => void;
5
+ };
@@ -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;
@@ -1,10 +1,13 @@
1
+ /// <reference types="react" />
1
2
  import _useAct from './useAct';
2
3
  import _useSub from './useSub';
4
+ import _useEager from './useEager';
3
5
  export declare const JasonProvider: ({ reducers, middleware, extraActions, children }: {
4
6
  reducers?: any;
5
7
  middleware?: any;
6
8
  extraActions?: any;
7
- children?: any;
8
- }) => any;
9
+ children?: import("react").FC<{}> | undefined;
10
+ }) => JSX.Element;
9
11
  export declare const useAct: typeof _useAct;
10
12
  export declare const useSub: typeof _useSub;
13
+ export declare const useEager: typeof _useEager;
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;
@@ -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;
@@ -0,0 +1,2 @@
1
+ declare const pruneIdsMiddleware: (schema: any) => (store: any) => (next: any) => (action: any) => any;
2
+ export default pruneIdsMiddleware;
@@ -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,2 @@
1
+ declare const restClient: any;
2
+ export default restClient;
@@ -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,5 @@
1
+ export default function actionCableAdapter(jasonConfig: any, handlePayload: any, dispatch: any, onConnected: any): {
2
+ getPayload: (config: any, options: any) => void;
3
+ createSubscription: (config: any) => void;
4
+ removeSubscription: (config: any) => void;
5
+ };
@@ -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,5 @@
1
+ export default function pusherAdapter(jasonConfig: any, handlePayload: any, dispatch: any): {
2
+ getPayload: (config: any, options: any) => void;
3
+ createSubscription: (config: any) => void;
4
+ removeSubscription: (config: any) => void;
5
+ };
@@ -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,5 @@
1
+ export default function useJason({ reducers, middleware, extraActions }: {
2
+ reducers?: any;
3
+ middleware?: any[];
4
+ extraActions?: any;
5
+ }): any[];
@@ -0,0 +1,94 @@
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 createActions_1 = __importDefault(require("./createActions"));
7
+ const createJasonReducers_1 = __importDefault(require("./createJasonReducers"));
8
+ const createPayloadHandler_1 = __importDefault(require("./createPayloadHandler"));
9
+ const createOptDis_1 = __importDefault(require("./createOptDis"));
10
+ const createServerActionQueue_1 = __importDefault(require("./createServerActionQueue"));
11
+ const restClient_1 = __importDefault(require("./restClient"));
12
+ const pruneIdsMiddleware_1 = __importDefault(require("./pruneIdsMiddleware"));
13
+ const createTransportAdapter_1 = __importDefault(require("./createTransportAdapter"));
14
+ const toolkit_1 = require("@reduxjs/toolkit");
15
+ const makeEager_1 = __importDefault(require("./makeEager"));
16
+ const humps_1 = require("humps");
17
+ const blueimp_md5_1 = __importDefault(require("blueimp-md5"));
18
+ const lodash_1 = __importDefault(require("lodash"));
19
+ const react_1 = require("react");
20
+ function useJason({ reducers, middleware = [], extraActions }) {
21
+ const [store, setStore] = react_1.useState(null);
22
+ const [value, setValue] = react_1.useState(null);
23
+ react_1.useEffect(() => {
24
+ restClient_1.default.get('/jason/api/config')
25
+ .then(({ data: jasonConfig }) => {
26
+ const { schema: snakey_schema } = jasonConfig;
27
+ const schema = humps_1.camelizeKeys(snakey_schema);
28
+ console.debug({ schema });
29
+ const serverActionQueue = createServerActionQueue_1.default();
30
+ const allReducers = Object.assign(Object.assign({}, reducers), createJasonReducers_1.default(schema));
31
+ console.debug({ allReducers });
32
+ const store = toolkit_1.configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware_1.default(schema)] });
33
+ const dispatch = store.dispatch;
34
+ const optDis = createOptDis_1.default(schema, dispatch, restClient_1.default, serverActionQueue);
35
+ const actions = createActions_1.default(schema, store, restClient_1.default, optDis, extraActions);
36
+ const eager = makeEager_1.default(schema);
37
+ let payloadHandlers = {};
38
+ let configs = {};
39
+ let subOptions = {};
40
+ function handlePayload(payload) {
41
+ const { md5Hash } = payload;
42
+ const { handlePayload } = payloadHandlers[md5Hash];
43
+ if (handlePayload) {
44
+ handlePayload(payload);
45
+ }
46
+ else {
47
+ console.warn("Payload arrived with no handler", payload, payloadHandlers);
48
+ }
49
+ }
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 = {}) {
52
+ // We need the hash to be consistent in Ruby / Javascript
53
+ const hashableConfig = lodash_1.default(Object.assign({ conditions: {}, includes: {} }, config)).toPairs().sortBy(0).fromPairs().value();
54
+ const md5Hash = blueimp_md5_1.default(JSON.stringify(hashableConfig));
55
+ payloadHandlers[md5Hash] = createPayloadHandler_1.default({ dispatch, serverActionQueue, transportAdapter, config });
56
+ configs[md5Hash] = hashableConfig;
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
+ }
66
+ return {
67
+ remove() {
68
+ removeSubscription(hashableConfig);
69
+ if (pollInterval)
70
+ clearInterval(pollInterval);
71
+ },
72
+ md5Hash
73
+ };
74
+ }
75
+ function removeSubscription(config) {
76
+ transportAdapter.removeSubscription(config);
77
+ const md5Hash = blueimp_md5_1.default(JSON.stringify(config));
78
+ payloadHandlers[md5Hash].tearDown();
79
+ delete payloadHandlers[md5Hash];
80
+ delete configs[md5Hash];
81
+ delete subOptions[md5Hash];
82
+ }
83
+ setValue({
84
+ actions: actions,
85
+ subscribe: createSubscription,
86
+ eager,
87
+ handlePayload
88
+ });
89
+ setStore(store);
90
+ });
91
+ }, []);
92
+ return [store, value];
93
+ }
94
+ exports.default = useJason;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const react_hooks_1 = require("@testing-library/react-hooks");
16
+ const useJason_1 = __importDefault(require("./useJason"));
17
+ const restClient_1 = __importDefault(require("./restClient"));
18
+ jest.mock('./restClient');
19
+ test('it works', () => __awaiter(void 0, void 0, void 0, function* () {
20
+ const resp = { data: {
21
+ schema: { post: {} },
22
+ transportService: 'action_cable'
23
+ } };
24
+ // @ts-ignore
25
+ restClient_1.default.get.mockResolvedValue(resp);
26
+ const { result, waitForNextUpdate } = react_hooks_1.renderHook(() => useJason_1.default({ reducers: {
27
+ test: (s, a) => s || {}
28
+ } }));
29
+ yield waitForNextUpdate();
30
+ const [store, value, connected] = result.current;
31
+ const { handlePayload, subscribe } = value;
32
+ const subscription = subscribe({ post: {} });
33
+ handlePayload({
34
+ type: 'payload',
35
+ model: 'post',
36
+ payload: [{ id: 4, name: 'test' }],
37
+ md5Hash: subscription.md5Hash,
38
+ idx: 1
39
+ });
40
+ handlePayload({
41
+ id: 4,
42
+ model: 'post',
43
+ destroy: true,
44
+ md5Hash: subscription.md5Hash,
45
+ idx: 2
46
+ });
47
+ handlePayload({
48
+ id: 5,
49
+ model: 'post',
50
+ payload: { id: 5, name: 'test2' },
51
+ md5Hash: subscription.md5Hash,
52
+ idx: 3
53
+ });
54
+ }));
55
+ test('pruning IDs', () => __awaiter(void 0, void 0, void 0, function* () {
56
+ const resp = { data: {
57
+ schema: { post: {} },
58
+ transportService: 'action_cable'
59
+ } };
60
+ // @ts-ignore
61
+ restClient_1.default.get.mockResolvedValue(resp);
62
+ const { result, waitForNextUpdate } = react_hooks_1.renderHook(() => useJason_1.default({ reducers: {
63
+ test: (s, a) => s || {}
64
+ } }));
65
+ yield waitForNextUpdate();
66
+ const [store, value, connected] = result.current;
67
+ const { handlePayload, subscribe } = value;
68
+ const subscription = subscribe({ post: {} });
69
+ handlePayload({
70
+ type: 'payload',
71
+ model: 'post',
72
+ payload: [{ id: 4, name: 'test' }],
73
+ md5Hash: subscription.md5Hash,
74
+ idx: 1
75
+ });
76
+ handlePayload({
77
+ type: 'payload',
78
+ model: 'post',
79
+ payload: [{ id: 5, name: 'test it out' }],
80
+ md5Hash: subscription.md5Hash,
81
+ idx: 2
82
+ });
83
+ // The ID 4 should have been pruned
84
+ expect(store.getState().posts.ids).toStrictEqual([5]);
85
+ }));