@knocklabs/client 0.4.5-rc.1
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.
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/cjs/api.js +165 -0
- package/dist/cjs/api.js.map +1 -0
- package/dist/cjs/clients/feed/feed.js +557 -0
- package/dist/cjs/clients/feed/feed.js.map +1 -0
- package/dist/cjs/clients/feed/index.js +43 -0
- package/dist/cjs/clients/feed/index.js.map +1 -0
- package/dist/cjs/clients/feed/interfaces.js +2 -0
- package/dist/cjs/clients/feed/interfaces.js.map +1 -0
- package/dist/cjs/clients/feed/store.js +115 -0
- package/dist/cjs/clients/feed/store.js.map +1 -0
- package/dist/cjs/clients/feed/types.js +2 -0
- package/dist/cjs/clients/feed/types.js.map +1 -0
- package/dist/cjs/clients/feed/utils.js +31 -0
- package/dist/cjs/clients/feed/utils.js.map +1 -0
- package/dist/cjs/clients/preferences/index.js +406 -0
- package/dist/cjs/clients/preferences/index.js.map +1 -0
- package/dist/cjs/clients/preferences/interfaces.js +2 -0
- package/dist/cjs/clients/preferences/interfaces.js.map +1 -0
- package/dist/cjs/index.js +108 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interfaces.js +2 -0
- package/dist/cjs/interfaces.js.map +1 -0
- package/dist/cjs/knock.js +86 -0
- package/dist/cjs/knock.js.map +1 -0
- package/dist/cjs/networkStatus.js +21 -0
- package/dist/cjs/networkStatus.js.map +1 -0
- package/dist/esm/api.js +119 -0
- package/dist/esm/api.js.map +1 -0
- package/dist/esm/clients/feed/feed.js +337 -0
- package/dist/esm/clients/feed/feed.js.map +1 -0
- package/dist/esm/clients/feed/index.js +20 -0
- package/dist/esm/clients/feed/index.js.map +1 -0
- package/dist/esm/clients/feed/interfaces.js +2 -0
- package/dist/esm/clients/feed/interfaces.js.map +1 -0
- package/dist/esm/clients/feed/store.js +91 -0
- package/dist/esm/clients/feed/store.js.map +1 -0
- package/dist/esm/clients/feed/types.js +2 -0
- package/dist/esm/clients/feed/types.js.map +1 -0
- package/dist/esm/clients/feed/utils.js +18 -0
- package/dist/esm/clients/feed/utils.js.map +1 -0
- package/dist/esm/clients/preferences/index.js +176 -0
- package/dist/esm/clients/preferences/index.js.map +1 -0
- package/dist/esm/clients/preferences/interfaces.js +2 -0
- package/dist/esm/clients/preferences/interfaces.js.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interfaces.js +2 -0
- package/dist/esm/interfaces.js.map +1 -0
- package/dist/esm/knock.js +69 -0
- package/dist/esm/knock.js.map +1 -0
- package/dist/esm/networkStatus.js +13 -0
- package/dist/esm/networkStatus.js.map +1 -0
- package/dist/types/api.d.ts +28 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/clients/feed/feed.d.ts +46 -0
- package/dist/types/clients/feed/feed.d.ts.map +1 -0
- package/dist/types/clients/feed/index.d.ts +11 -0
- package/dist/types/clients/feed/index.d.ts.map +1 -0
- package/dist/types/clients/feed/interfaces.d.ts +50 -0
- package/dist/types/clients/feed/interfaces.d.ts.map +1 -0
- package/dist/types/clients/feed/store.d.ts +3 -0
- package/dist/types/clients/feed/store.d.ts.map +1 -0
- package/dist/types/clients/feed/types.d.ts +25 -0
- package/dist/types/clients/feed/types.d.ts.map +1 -0
- package/dist/types/clients/feed/utils.d.ts +4 -0
- package/dist/types/clients/feed/utils.d.ts.map +1 -0
- package/dist/types/clients/preferences/index.d.ts +18 -0
- package/dist/types/clients/preferences/index.d.ts.map +1 -0
- package/dist/types/clients/preferences/interfaces.d.ts +26 -0
- package/dist/types/clients/preferences/interfaces.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interfaces.d.ts +27 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/knock.d.ts +19 -0
- package/dist/types/knock.d.ts.map +1 -0
- package/dist/types/networkStatus.d.ts +8 -0
- package/dist/types/networkStatus.d.ts.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Knock Labs, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Knock Javascript client library
|
|
2
|
+
|
|
3
|
+
A client-side Javascript library to interact with user-facing Knock features, such as feeds.
|
|
4
|
+
|
|
5
|
+
**Note: this is a lower level library designed for building UI on top of**
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
See the [documentation](https://docs.knock.app/notification-feeds/bring-your-own-ui) for usage examples.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Via NPM:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @knocklabs/client
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Via Yarn:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add @knocklabs/client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
To configure the client library you will need:
|
|
28
|
+
|
|
29
|
+
1. A public API key (found in the Knock dashboard)
|
|
30
|
+
2. A feed channel ID (found in the Knock dashboard)
|
|
31
|
+
3. A user ID, and optionally an auth token for production environments
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import Knock from "@knocklabs/client";
|
|
35
|
+
|
|
36
|
+
const knockClient = new Knock(process.env.KNOCK_API_KEY);
|
|
37
|
+
|
|
38
|
+
knockClient.authenticate(
|
|
39
|
+
// The id of the user you want to authenticate against
|
|
40
|
+
currentUser.id,
|
|
41
|
+
// You only need this in production environments
|
|
42
|
+
currentUser.knockToken,
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
You can find an example usage in a React application in the [example/App.js](https://github.com/knocklabs/client-js/blob/main/example/src/App.js) file, which is a plain-old Create React App.
|
|
49
|
+
|
|
50
|
+
### Retrieving new items from the feed
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import Knock from "@knocklabs/client";
|
|
54
|
+
|
|
55
|
+
const knockClient = new Knock(process.env.KNOCK_API_KEY);
|
|
56
|
+
|
|
57
|
+
// Authenticate the user
|
|
58
|
+
knockClient.authenticate(currentUser.id, currentUser.knockToken);
|
|
59
|
+
|
|
60
|
+
// Initialize the feed
|
|
61
|
+
const feedClient = knockClient.feeds.initialize(
|
|
62
|
+
process.env.KNOCK_FEED_CHANNEL_ID,
|
|
63
|
+
// Optionally you can provide a default scope here:
|
|
64
|
+
// { tenant: "jurassic-park", source: "new-comment" },
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Connect to the real-time socket
|
|
68
|
+
const teardown = feedClient.listenForUpdates();
|
|
69
|
+
|
|
70
|
+
// Setup a callback for when a batch of messages is received (including on first load)
|
|
71
|
+
feedClient.on("messages.new", ({ entries }) => {
|
|
72
|
+
console.log(entries);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Fetch the feed items
|
|
76
|
+
feedClient.fetch({
|
|
77
|
+
// Fetch a particular status only (defaults to all)
|
|
78
|
+
status: "all" | "unread" | "unseen",
|
|
79
|
+
// Pagination options
|
|
80
|
+
after: lastItem.__cursor,
|
|
81
|
+
before: firstItem.__cursor,
|
|
82
|
+
// Defaults to 50
|
|
83
|
+
page_size: 10,
|
|
84
|
+
// Filter by a specific source
|
|
85
|
+
source: "notification-key",
|
|
86
|
+
// Filter by a specific tenant
|
|
87
|
+
tenant: "jurassic-park",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
teardown();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Reading the feed store state (programmatically)
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// Initialize the feed as in above examples
|
|
97
|
+
const feedClient = knockClient.feeds.initialize(
|
|
98
|
+
process.env.KNOCK_FEED_CHANNEL_ID,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Gives you all of the items currently in the store
|
|
102
|
+
const { items } = feedClient.store.getState();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Reading the feed store state (in React)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// The feed store uses zustand
|
|
109
|
+
import create from "zustand";
|
|
110
|
+
|
|
111
|
+
// Initialize the feed as in above examples
|
|
112
|
+
const feedClient = knockClient.feeds.initialize(
|
|
113
|
+
process.env.KNOCK_FEED_CHANNEL_ID,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const useFeedStore = create(feedClient.store);
|
|
117
|
+
|
|
118
|
+
// Retrieves all of the items
|
|
119
|
+
const items = useFeedStore((state) => state.items);
|
|
120
|
+
|
|
121
|
+
// Retrieve the badge counts
|
|
122
|
+
const meta = useFeedStore((state) => state.metadata);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Marking items as read, seen, or archived
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Initialize the feed as in above examples
|
|
129
|
+
const feedClient = knockClient.feeds.initialize(
|
|
130
|
+
process.env.KNOCK_FEED_CHANNEL_ID,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Mark one or more items as read
|
|
134
|
+
feedClient.markAsRead(feedItemOrItems);
|
|
135
|
+
// Mark one or more items as seen
|
|
136
|
+
feedClient.markAsSeen(feedItemOrItems);
|
|
137
|
+
// Mark one or more items as archived
|
|
138
|
+
feedClient.markAsArchived(feedItemOrItems);
|
|
139
|
+
|
|
140
|
+
// Mark one or more items as unread
|
|
141
|
+
feedClient.markAsUnread(feedItemOrItems);
|
|
142
|
+
// Mark one or more items as unseen
|
|
143
|
+
feedClient.markAsUnseen(feedItemOrItems);
|
|
144
|
+
// Mark one or more items as unarchived
|
|
145
|
+
feedClient.markAsUnarchived(feedItemOrItems);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Managing user preferences
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Set an entire preference set
|
|
152
|
+
await knockClient.preferences.set({
|
|
153
|
+
channel_types: { email: true, sms: false },
|
|
154
|
+
workflows: {
|
|
155
|
+
"dinosaurs-loose": {
|
|
156
|
+
channel_types: { email: false, in_app_feed: true },
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Retrieve a whole preference set
|
|
162
|
+
const preferences = await knockClient.preferences.get();
|
|
163
|
+
|
|
164
|
+
// Granular preference setting for channel types
|
|
165
|
+
await knockClient.preferences.setChannelType("email", false);
|
|
166
|
+
|
|
167
|
+
// Granular preference setting for workflows
|
|
168
|
+
await knockClient.preferences.setWorkflow("dinosaurs-loose", {
|
|
169
|
+
channel_types: {
|
|
170
|
+
email: true,
|
|
171
|
+
in_app_feed: false,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
package/dist/cjs/api.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
+
|
|
12
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
13
|
+
|
|
14
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
15
|
+
|
|
16
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
17
|
+
|
|
18
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
19
|
+
|
|
20
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
21
|
+
|
|
22
|
+
var _axiosRetry = _interopRequireDefault(require("axios-retry"));
|
|
23
|
+
|
|
24
|
+
var _phoenix = require("phoenix");
|
|
25
|
+
|
|
26
|
+
var ApiClient = /*#__PURE__*/function () {
|
|
27
|
+
function ApiClient(options) {
|
|
28
|
+
(0, _classCallCheck2["default"])(this, ApiClient);
|
|
29
|
+
(0, _defineProperty2["default"])(this, "host", void 0);
|
|
30
|
+
(0, _defineProperty2["default"])(this, "apiKey", void 0);
|
|
31
|
+
(0, _defineProperty2["default"])(this, "userToken", void 0);
|
|
32
|
+
(0, _defineProperty2["default"])(this, "axiosClient", void 0);
|
|
33
|
+
(0, _defineProperty2["default"])(this, "socket", void 0);
|
|
34
|
+
(0, _defineProperty2["default"])(this, "socketConnected", false);
|
|
35
|
+
this.host = options.host;
|
|
36
|
+
this.apiKey = options.apiKey;
|
|
37
|
+
this.userToken = options.userToken || null; // Create a retryable axios client
|
|
38
|
+
|
|
39
|
+
this.axiosClient = _axios["default"].create({
|
|
40
|
+
baseURL: this.host,
|
|
41
|
+
headers: {
|
|
42
|
+
Accept: "application/json",
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
Authorization: "Bearer ".concat(this.apiKey),
|
|
45
|
+
"X-Knock-User-Token": this.userToken
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
this.socket = new _phoenix.Socket("".concat(this.host.replace("http", "ws"), "/ws/v1"), {
|
|
49
|
+
params: {
|
|
50
|
+
user_token: this.userToken,
|
|
51
|
+
api_key: this.apiKey
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
(0, _axiosRetry["default"])(this.axiosClient, {
|
|
55
|
+
retries: 3,
|
|
56
|
+
retryCondition: this.canRetryRequest,
|
|
57
|
+
retryDelay: _axiosRetry["default"].exponentialDelay
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
(0, _createClass2["default"])(ApiClient, [{
|
|
62
|
+
key: "connectSocket",
|
|
63
|
+
value: function connectSocket() {
|
|
64
|
+
var _this = this;
|
|
65
|
+
|
|
66
|
+
if (this.socketConnected) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.socket.connect();
|
|
71
|
+
this.socket.onOpen(function () {
|
|
72
|
+
_this.socketConnected = true;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}, {
|
|
76
|
+
key: "disconnectSocket",
|
|
77
|
+
value: function disconnectSocket() {
|
|
78
|
+
this.socket.disconnect();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
key: "createChannel",
|
|
83
|
+
value: function createChannel(name, params) {
|
|
84
|
+
return this.socket.channel(name, params);
|
|
85
|
+
}
|
|
86
|
+
}, {
|
|
87
|
+
key: "makeRequest",
|
|
88
|
+
value: function () {
|
|
89
|
+
var _makeRequest = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(req) {
|
|
90
|
+
var result;
|
|
91
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
92
|
+
while (1) {
|
|
93
|
+
switch (_context.prev = _context.next) {
|
|
94
|
+
case 0:
|
|
95
|
+
_context.prev = 0;
|
|
96
|
+
_context.next = 3;
|
|
97
|
+
return this.axiosClient(req);
|
|
98
|
+
|
|
99
|
+
case 3:
|
|
100
|
+
result = _context.sent;
|
|
101
|
+
return _context.abrupt("return", {
|
|
102
|
+
statusCode: result.status < 300 ? "ok" : "error",
|
|
103
|
+
body: result.data,
|
|
104
|
+
error: undefined,
|
|
105
|
+
status: result.status
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
case 7:
|
|
109
|
+
_context.prev = 7;
|
|
110
|
+
_context.t0 = _context["catch"](0);
|
|
111
|
+
// tslint:disable-next-line
|
|
112
|
+
console.error(_context.t0);
|
|
113
|
+
return _context.abrupt("return", {
|
|
114
|
+
statusCode: "error",
|
|
115
|
+
status: 500,
|
|
116
|
+
body: undefined,
|
|
117
|
+
error: _context.t0
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
case 11:
|
|
121
|
+
case "end":
|
|
122
|
+
return _context.stop();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}, _callee, this, [[0, 7]]);
|
|
126
|
+
}));
|
|
127
|
+
|
|
128
|
+
function makeRequest(_x) {
|
|
129
|
+
return _makeRequest.apply(this, arguments);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return makeRequest;
|
|
133
|
+
}()
|
|
134
|
+
}, {
|
|
135
|
+
key: "canRetryRequest",
|
|
136
|
+
value: function canRetryRequest(error) {
|
|
137
|
+
// Retry Network Errors.
|
|
138
|
+
if (_axiosRetry["default"].isNetworkError(error)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!error.response) {
|
|
143
|
+
// Cannot determine if the request can be retried
|
|
144
|
+
return false;
|
|
145
|
+
} // Retry Server Errors (5xx).
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
if (error.response.status >= 500 && error.response.status <= 599) {
|
|
149
|
+
return true;
|
|
150
|
+
} // Retry if rate limited.
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if (error.response.status === 429) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}]);
|
|
160
|
+
return ApiClient;
|
|
161
|
+
}();
|
|
162
|
+
|
|
163
|
+
var _default = ApiClient;
|
|
164
|
+
exports["default"] = _default;
|
|
165
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api.ts"],"names":["ApiClient","options","host","apiKey","userToken","axiosClient","axios","create","baseURL","headers","Accept","Authorization","socket","Socket","replace","params","user_token","api_key","retries","retryCondition","canRetryRequest","retryDelay","axiosRetry","exponentialDelay","socketConnected","connect","onOpen","disconnect","name","channel","req","result","statusCode","status","body","data","error","undefined","console","isNetworkError","response"],"mappings":"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","sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport axiosRetry from \"axios-retry\";\nimport { Socket } from \"phoenix\";\nimport { AxiosError } from \"axios\";\n\ntype ApiClientOptions = {\n host: string;\n apiKey: string;\n userToken: string | undefined;\n};\n\nexport interface ApiResponse {\n error?: any;\n body?: any;\n statusCode: \"ok\" | \"error\";\n status: number;\n}\n\nclass ApiClient {\n private host: string;\n private apiKey: string;\n private userToken: string | null;\n private axiosClient: AxiosInstance;\n private socket: Socket;\n public socketConnected: boolean = false;\n\n constructor(options: ApiClientOptions) {\n this.host = options.host;\n this.apiKey = options.apiKey;\n this.userToken = options.userToken || null;\n\n // Create a retryable axios client\n this.axiosClient = axios.create({\n baseURL: this.host,\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"X-Knock-User-Token\": this.userToken,\n },\n });\n\n this.socket = new Socket(`${this.host.replace(\"http\", \"ws\")}/ws/v1`, {\n params: {\n user_token: this.userToken,\n api_key: this.apiKey,\n },\n });\n\n axiosRetry(this.axiosClient, {\n retries: 3,\n retryCondition: this.canRetryRequest,\n retryDelay: axiosRetry.exponentialDelay,\n });\n }\n\n connectSocket() {\n if (this.socketConnected) {\n return;\n }\n\n this.socket.connect();\n this.socket.onOpen(() => {\n this.socketConnected = true;\n });\n }\n\n disconnectSocket() {\n this.socket.disconnect();\n return;\n }\n\n createChannel(name: string, params?: object) {\n return this.socket.channel(name, params);\n }\n\n async makeRequest(req: AxiosRequestConfig): Promise<ApiResponse> {\n try {\n const result = await this.axiosClient(req);\n\n return {\n statusCode: result.status < 300 ? \"ok\" : \"error\",\n body: result.data,\n error: undefined,\n status: result.status,\n };\n } catch (e) {\n // tslint:disable-next-line\n console.error(e);\n\n return {\n statusCode: \"error\",\n status: 500,\n body: undefined,\n error: e,\n };\n }\n }\n\n private canRetryRequest(error: AxiosError) {\n // Retry Network Errors.\n if (axiosRetry.isNetworkError(error)) {\n return true;\n }\n\n if (!error.response) {\n // Cannot determine if the request can be retried\n return false;\n }\n\n // Retry Server Errors (5xx).\n if (error.response.status >= 500 && error.response.status <= 599) {\n return true;\n }\n\n // Retry if rate limited.\n if (error.response.status === 429) {\n return true;\n }\n\n return false;\n }\n}\n\nexport default ApiClient;\n"],"file":"api.js"}
|
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
+
|
|
12
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
13
|
+
|
|
14
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
15
|
+
|
|
16
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
17
|
+
|
|
18
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
19
|
+
|
|
20
|
+
var _eventemitter = _interopRequireDefault(require("eventemitter3"));
|
|
21
|
+
|
|
22
|
+
var _store = _interopRequireDefault(require("./store"));
|
|
23
|
+
|
|
24
|
+
var _networkStatus = require("../../networkStatus");
|
|
25
|
+
|
|
26
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
27
|
+
|
|
28
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
29
|
+
|
|
30
|
+
var Feed = /*#__PURE__*/function () {
|
|
31
|
+
// The raw store instance, used for binding in React and other environments
|
|
32
|
+
function Feed(knock, feedId, options) {
|
|
33
|
+
(0, _classCallCheck2["default"])(this, Feed);
|
|
34
|
+
this.knock = knock;
|
|
35
|
+
this.feedId = feedId;
|
|
36
|
+
(0, _defineProperty2["default"])(this, "apiClient", void 0);
|
|
37
|
+
(0, _defineProperty2["default"])(this, "userFeedId", void 0);
|
|
38
|
+
(0, _defineProperty2["default"])(this, "channelConnected", false);
|
|
39
|
+
(0, _defineProperty2["default"])(this, "channel", void 0);
|
|
40
|
+
(0, _defineProperty2["default"])(this, "broadcaster", void 0);
|
|
41
|
+
(0, _defineProperty2["default"])(this, "defaultOptions", void 0);
|
|
42
|
+
(0, _defineProperty2["default"])(this, "store", void 0);
|
|
43
|
+
this.apiClient = knock.client();
|
|
44
|
+
this.feedId = feedId;
|
|
45
|
+
this.userFeedId = this.buildUserFeedId();
|
|
46
|
+
this.store = (0, _store["default"])();
|
|
47
|
+
this.broadcaster = new _eventemitter["default"]();
|
|
48
|
+
this.defaultOptions = options; // Try and connect to the socket
|
|
49
|
+
|
|
50
|
+
this.apiClient.connectSocket();
|
|
51
|
+
this.channel = this.apiClient.createChannel("feeds:".concat(this.userFeedId), this.defaultOptions);
|
|
52
|
+
}
|
|
53
|
+
/*
|
|
54
|
+
Returns a socket to listen for feed updates
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
(0, _createClass2["default"])(Feed, [{
|
|
59
|
+
key: "listenForUpdates",
|
|
60
|
+
value: function listenForUpdates() {
|
|
61
|
+
var _this = this;
|
|
62
|
+
|
|
63
|
+
if (!this.channelConnected) {
|
|
64
|
+
this.channel.join().receive("ok", function () {
|
|
65
|
+
_this.channelConnected = true;
|
|
66
|
+
});
|
|
67
|
+
this.channel.on("new-message", function (resp) {
|
|
68
|
+
return _this.onNewMessageReceived(resp);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return function () {
|
|
73
|
+
try {
|
|
74
|
+
_this.channel.leave();
|
|
75
|
+
} catch (e) {
|
|
76
|
+
// tslint:disable-next-line
|
|
77
|
+
console.error("error while leaving channel", e);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/* Binds a handler to be invoked when event occurs */
|
|
82
|
+
|
|
83
|
+
}, {
|
|
84
|
+
key: "on",
|
|
85
|
+
value: function on(eventName, callback) {
|
|
86
|
+
this.broadcaster.on(eventName, callback);
|
|
87
|
+
}
|
|
88
|
+
}, {
|
|
89
|
+
key: "off",
|
|
90
|
+
value: function off(eventName, callback) {
|
|
91
|
+
this.broadcaster.off(eventName, callback);
|
|
92
|
+
}
|
|
93
|
+
}, {
|
|
94
|
+
key: "getState",
|
|
95
|
+
value: function getState() {
|
|
96
|
+
return this.store.getState();
|
|
97
|
+
}
|
|
98
|
+
}, {
|
|
99
|
+
key: "markAsSeen",
|
|
100
|
+
value: function () {
|
|
101
|
+
var _markAsSeen = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(itemOrItems) {
|
|
102
|
+
var now;
|
|
103
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
104
|
+
while (1) {
|
|
105
|
+
switch (_context.prev = _context.next) {
|
|
106
|
+
case 0:
|
|
107
|
+
now = new Date().toISOString();
|
|
108
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "seen", {
|
|
109
|
+
seen_at: now
|
|
110
|
+
}, "unseen_count");
|
|
111
|
+
return _context.abrupt("return", this.makeStatusUpdate(itemOrItems, "seen"));
|
|
112
|
+
|
|
113
|
+
case 3:
|
|
114
|
+
case "end":
|
|
115
|
+
return _context.stop();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, _callee, this);
|
|
119
|
+
}));
|
|
120
|
+
|
|
121
|
+
function markAsSeen(_x) {
|
|
122
|
+
return _markAsSeen.apply(this, arguments);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return markAsSeen;
|
|
126
|
+
}()
|
|
127
|
+
}, {
|
|
128
|
+
key: "markAsUnseen",
|
|
129
|
+
value: function () {
|
|
130
|
+
var _markAsUnseen = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(itemOrItems) {
|
|
131
|
+
return _regenerator["default"].wrap(function _callee2$(_context2) {
|
|
132
|
+
while (1) {
|
|
133
|
+
switch (_context2.prev = _context2.next) {
|
|
134
|
+
case 0:
|
|
135
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "unseen", {
|
|
136
|
+
seen_at: null
|
|
137
|
+
}, "unseen_count");
|
|
138
|
+
return _context2.abrupt("return", this.makeStatusUpdate(itemOrItems, "unseen"));
|
|
139
|
+
|
|
140
|
+
case 2:
|
|
141
|
+
case "end":
|
|
142
|
+
return _context2.stop();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, _callee2, this);
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
function markAsUnseen(_x2) {
|
|
149
|
+
return _markAsUnseen.apply(this, arguments);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return markAsUnseen;
|
|
153
|
+
}()
|
|
154
|
+
}, {
|
|
155
|
+
key: "markAsRead",
|
|
156
|
+
value: function () {
|
|
157
|
+
var _markAsRead = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(itemOrItems) {
|
|
158
|
+
var now;
|
|
159
|
+
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
|
160
|
+
while (1) {
|
|
161
|
+
switch (_context3.prev = _context3.next) {
|
|
162
|
+
case 0:
|
|
163
|
+
now = new Date().toISOString();
|
|
164
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "read", {
|
|
165
|
+
read_at: now
|
|
166
|
+
}, "unread_count");
|
|
167
|
+
return _context3.abrupt("return", this.makeStatusUpdate(itemOrItems, "read"));
|
|
168
|
+
|
|
169
|
+
case 3:
|
|
170
|
+
case "end":
|
|
171
|
+
return _context3.stop();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}, _callee3, this);
|
|
175
|
+
}));
|
|
176
|
+
|
|
177
|
+
function markAsRead(_x3) {
|
|
178
|
+
return _markAsRead.apply(this, arguments);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return markAsRead;
|
|
182
|
+
}()
|
|
183
|
+
}, {
|
|
184
|
+
key: "markAsUnread",
|
|
185
|
+
value: function () {
|
|
186
|
+
var _markAsUnread = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(itemOrItems) {
|
|
187
|
+
return _regenerator["default"].wrap(function _callee4$(_context4) {
|
|
188
|
+
while (1) {
|
|
189
|
+
switch (_context4.prev = _context4.next) {
|
|
190
|
+
case 0:
|
|
191
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "unread", {
|
|
192
|
+
read_at: null
|
|
193
|
+
}, "unread_count");
|
|
194
|
+
return _context4.abrupt("return", this.makeStatusUpdate(itemOrItems, "unread"));
|
|
195
|
+
|
|
196
|
+
case 2:
|
|
197
|
+
case "end":
|
|
198
|
+
return _context4.stop();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}, _callee4, this);
|
|
202
|
+
}));
|
|
203
|
+
|
|
204
|
+
function markAsUnread(_x4) {
|
|
205
|
+
return _markAsUnread.apply(this, arguments);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return markAsUnread;
|
|
209
|
+
}()
|
|
210
|
+
}, {
|
|
211
|
+
key: "markAsArchived",
|
|
212
|
+
value: function () {
|
|
213
|
+
var _markAsArchived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(itemOrItems) {
|
|
214
|
+
var now;
|
|
215
|
+
return _regenerator["default"].wrap(function _callee5$(_context5) {
|
|
216
|
+
while (1) {
|
|
217
|
+
switch (_context5.prev = _context5.next) {
|
|
218
|
+
case 0:
|
|
219
|
+
now = new Date().toISOString();
|
|
220
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "archived", {
|
|
221
|
+
archived_at: now
|
|
222
|
+
});
|
|
223
|
+
return _context5.abrupt("return", this.makeStatusUpdate(itemOrItems, "archived"));
|
|
224
|
+
|
|
225
|
+
case 3:
|
|
226
|
+
case "end":
|
|
227
|
+
return _context5.stop();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}, _callee5, this);
|
|
231
|
+
}));
|
|
232
|
+
|
|
233
|
+
function markAsArchived(_x5) {
|
|
234
|
+
return _markAsArchived.apply(this, arguments);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return markAsArchived;
|
|
238
|
+
}()
|
|
239
|
+
}, {
|
|
240
|
+
key: "markAsUnarchived",
|
|
241
|
+
value: function () {
|
|
242
|
+
var _markAsUnarchived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(itemOrItems) {
|
|
243
|
+
return _regenerator["default"].wrap(function _callee6$(_context6) {
|
|
244
|
+
while (1) {
|
|
245
|
+
switch (_context6.prev = _context6.next) {
|
|
246
|
+
case 0:
|
|
247
|
+
this.optimisticallyPerformStatusUpdate(itemOrItems, "unarchived", {
|
|
248
|
+
archived_at: null
|
|
249
|
+
});
|
|
250
|
+
return _context6.abrupt("return", this.makeStatusUpdate(itemOrItems, "unarchived"));
|
|
251
|
+
|
|
252
|
+
case 2:
|
|
253
|
+
case "end":
|
|
254
|
+
return _context6.stop();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}, _callee6, this);
|
|
258
|
+
}));
|
|
259
|
+
|
|
260
|
+
function markAsUnarchived(_x6) {
|
|
261
|
+
return _markAsUnarchived.apply(this, arguments);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return markAsUnarchived;
|
|
265
|
+
}()
|
|
266
|
+
/* Fetches the feed content, appending it to the store */
|
|
267
|
+
|
|
268
|
+
}, {
|
|
269
|
+
key: "fetch",
|
|
270
|
+
value: function () {
|
|
271
|
+
var _fetch = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7() {
|
|
272
|
+
var options,
|
|
273
|
+
_this$store,
|
|
274
|
+
setState,
|
|
275
|
+
getState,
|
|
276
|
+
_getState,
|
|
277
|
+
networkStatus,
|
|
278
|
+
queryParams,
|
|
279
|
+
result,
|
|
280
|
+
response,
|
|
281
|
+
opts,
|
|
282
|
+
_opts,
|
|
283
|
+
_args7 = arguments;
|
|
284
|
+
|
|
285
|
+
return _regenerator["default"].wrap(function _callee7$(_context7) {
|
|
286
|
+
while (1) {
|
|
287
|
+
switch (_context7.prev = _context7.next) {
|
|
288
|
+
case 0:
|
|
289
|
+
options = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : {};
|
|
290
|
+
_this$store = this.store, setState = _this$store.setState, getState = _this$store.getState;
|
|
291
|
+
_getState = getState(), networkStatus = _getState.networkStatus; // If there's an existing request in flight, then do nothing
|
|
292
|
+
|
|
293
|
+
if (!(0, _networkStatus.isRequestInFlight)(networkStatus)) {
|
|
294
|
+
_context7.next = 5;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return _context7.abrupt("return");
|
|
299
|
+
|
|
300
|
+
case 5:
|
|
301
|
+
// Set the loading type based on the request type it is
|
|
302
|
+
setState(function (store) {
|
|
303
|
+
var _options$__loadingTyp;
|
|
304
|
+
|
|
305
|
+
return store.setNetworkStatus((_options$__loadingTyp = options.__loadingType) !== null && _options$__loadingTyp !== void 0 ? _options$__loadingTyp : _networkStatus.NetworkStatus.loading);
|
|
306
|
+
}); // Always include the default params, if they have been set
|
|
307
|
+
|
|
308
|
+
queryParams = _objectSpread(_objectSpread({}, this.defaultOptions), options);
|
|
309
|
+
_context7.next = 9;
|
|
310
|
+
return this.apiClient.makeRequest({
|
|
311
|
+
method: "GET",
|
|
312
|
+
url: "/v1/users/".concat(this.knock.userId, "/feeds/").concat(this.feedId),
|
|
313
|
+
params: queryParams
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
case 9:
|
|
317
|
+
result = _context7.sent;
|
|
318
|
+
|
|
319
|
+
if (!(result.statusCode === "error")) {
|
|
320
|
+
_context7.next = 13;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
setState(function (store) {
|
|
325
|
+
return store.setNetworkStatus(_networkStatus.NetworkStatus.error);
|
|
326
|
+
});
|
|
327
|
+
return _context7.abrupt("return", {
|
|
328
|
+
status: result.statusCode,
|
|
329
|
+
data: result.error || result.body
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
case 13:
|
|
333
|
+
response = {
|
|
334
|
+
entries: result.body.entries,
|
|
335
|
+
meta: result.body.meta,
|
|
336
|
+
page_info: result.body.page_info
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
if (options.before) {
|
|
340
|
+
opts = {
|
|
341
|
+
shouldSetPage: false,
|
|
342
|
+
shouldAppend: true
|
|
343
|
+
};
|
|
344
|
+
setState(function (state) {
|
|
345
|
+
return state.setResult(response, opts);
|
|
346
|
+
});
|
|
347
|
+
} else if (options.after) {
|
|
348
|
+
_opts = {
|
|
349
|
+
shouldSetPage: true,
|
|
350
|
+
shouldAppend: true
|
|
351
|
+
};
|
|
352
|
+
setState(function (state) {
|
|
353
|
+
return state.setResult(response, _opts);
|
|
354
|
+
});
|
|
355
|
+
} else {
|
|
356
|
+
setState(function (state) {
|
|
357
|
+
return state.setResult(response);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
this.broadcast("messages.new", response);
|
|
362
|
+
return _context7.abrupt("return", {
|
|
363
|
+
data: response,
|
|
364
|
+
status: result.statusCode
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
case 17:
|
|
368
|
+
case "end":
|
|
369
|
+
return _context7.stop();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}, _callee7, this);
|
|
373
|
+
}));
|
|
374
|
+
|
|
375
|
+
function fetch() {
|
|
376
|
+
return _fetch.apply(this, arguments);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return fetch;
|
|
380
|
+
}()
|
|
381
|
+
}, {
|
|
382
|
+
key: "fetchNextPage",
|
|
383
|
+
value: function () {
|
|
384
|
+
var _fetchNextPage = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8() {
|
|
385
|
+
var getState, _getState2, pageInfo;
|
|
386
|
+
|
|
387
|
+
return _regenerator["default"].wrap(function _callee8$(_context8) {
|
|
388
|
+
while (1) {
|
|
389
|
+
switch (_context8.prev = _context8.next) {
|
|
390
|
+
case 0:
|
|
391
|
+
// Attempts to fetch the next page of results (if we have any)
|
|
392
|
+
getState = this.store.getState;
|
|
393
|
+
_getState2 = getState(), pageInfo = _getState2.pageInfo;
|
|
394
|
+
|
|
395
|
+
if (pageInfo.after) {
|
|
396
|
+
_context8.next = 4;
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return _context8.abrupt("return");
|
|
401
|
+
|
|
402
|
+
case 4:
|
|
403
|
+
this.fetch({
|
|
404
|
+
after: pageInfo.after,
|
|
405
|
+
__loadingType: _networkStatus.NetworkStatus.fetchMore
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
case 5:
|
|
409
|
+
case "end":
|
|
410
|
+
return _context8.stop();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, _callee8, this);
|
|
414
|
+
}));
|
|
415
|
+
|
|
416
|
+
function fetchNextPage() {
|
|
417
|
+
return _fetchNextPage.apply(this, arguments);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return fetchNextPage;
|
|
421
|
+
}()
|
|
422
|
+
}, {
|
|
423
|
+
key: "broadcast",
|
|
424
|
+
value: function broadcast(eventName, data) {
|
|
425
|
+
this.broadcaster.emit(eventName, data);
|
|
426
|
+
} // Invoked when a new real-time message comes in from the socket
|
|
427
|
+
|
|
428
|
+
}, {
|
|
429
|
+
key: "onNewMessageReceived",
|
|
430
|
+
value: function () {
|
|
431
|
+
var _onNewMessageReceived = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(_ref) {
|
|
432
|
+
var metadata, _this$store2, getState, setState, currentHead;
|
|
433
|
+
|
|
434
|
+
return _regenerator["default"].wrap(function _callee9$(_context9) {
|
|
435
|
+
while (1) {
|
|
436
|
+
switch (_context9.prev = _context9.next) {
|
|
437
|
+
case 0:
|
|
438
|
+
metadata = _ref.metadata;
|
|
439
|
+
// Handle the new message coming in
|
|
440
|
+
_this$store2 = this.store, getState = _this$store2.getState, setState = _this$store2.setState;
|
|
441
|
+
currentHead = getState().items[0]; // Optimistically set the badge counts
|
|
442
|
+
|
|
443
|
+
setState(function (state) {
|
|
444
|
+
return state.setMetadata(metadata);
|
|
445
|
+
}); // Fetch the items before the current head (if it exists)
|
|
446
|
+
|
|
447
|
+
this.fetch({
|
|
448
|
+
before: currentHead === null || currentHead === void 0 ? void 0 : currentHead.__cursor
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
case 5:
|
|
452
|
+
case "end":
|
|
453
|
+
return _context9.stop();
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}, _callee9, this);
|
|
457
|
+
}));
|
|
458
|
+
|
|
459
|
+
function onNewMessageReceived(_x7) {
|
|
460
|
+
return _onNewMessageReceived.apply(this, arguments);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return onNewMessageReceived;
|
|
464
|
+
}()
|
|
465
|
+
}, {
|
|
466
|
+
key: "buildUserFeedId",
|
|
467
|
+
value: function buildUserFeedId() {
|
|
468
|
+
return "".concat(this.feedId, ":").concat(this.knock.userId);
|
|
469
|
+
}
|
|
470
|
+
}, {
|
|
471
|
+
key: "optimisticallyPerformStatusUpdate",
|
|
472
|
+
value: function optimisticallyPerformStatusUpdate(itemOrItems, type, attrs, badgeCountAttr) {
|
|
473
|
+
var _this$store3 = this.store,
|
|
474
|
+
getState = _this$store3.getState,
|
|
475
|
+
setState = _this$store3.setState;
|
|
476
|
+
var itemIds = Array.isArray(itemOrItems) ? itemOrItems.map(function (item) {
|
|
477
|
+
return item.id;
|
|
478
|
+
}) : [itemOrItems.id];
|
|
479
|
+
|
|
480
|
+
if (badgeCountAttr) {
|
|
481
|
+
var _getState3 = getState(),
|
|
482
|
+
metadata = _getState3.metadata; // Tnis is a hack to determine the direction of whether we're
|
|
483
|
+
// adding or removing from the badge count
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
var direction = type.startsWith("un") ? itemIds.length : -itemIds.length;
|
|
487
|
+
setState(function (store) {
|
|
488
|
+
return store.setMetadata(_objectSpread(_objectSpread({}, metadata), {}, (0, _defineProperty2["default"])({}, badgeCountAttr, Math.max(0, metadata[badgeCountAttr] + direction))));
|
|
489
|
+
});
|
|
490
|
+
} // Update the items with the given attributes
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
setState(function (store) {
|
|
494
|
+
return store.setItemAttrs(itemIds, attrs);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}, {
|
|
498
|
+
key: "makeStatusUpdate",
|
|
499
|
+
value: function () {
|
|
500
|
+
var _makeStatusUpdate = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee10(itemOrItems, type) {
|
|
501
|
+
var itemIds, result;
|
|
502
|
+
return _regenerator["default"].wrap(function _callee10$(_context10) {
|
|
503
|
+
while (1) {
|
|
504
|
+
switch (_context10.prev = _context10.next) {
|
|
505
|
+
case 0:
|
|
506
|
+
if (!Array.isArray(itemOrItems)) {
|
|
507
|
+
_context10.next = 5;
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
itemIds = itemOrItems.map(function (item) {
|
|
512
|
+
return item.id;
|
|
513
|
+
});
|
|
514
|
+
_context10.next = 4;
|
|
515
|
+
return this.apiClient.makeRequest({
|
|
516
|
+
method: "POST",
|
|
517
|
+
url: "/v1/messages/batch/".concat(type),
|
|
518
|
+
data: {
|
|
519
|
+
message_ids: itemIds
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
case 4:
|
|
524
|
+
return _context10.abrupt("return", _context10.sent);
|
|
525
|
+
|
|
526
|
+
case 5:
|
|
527
|
+
_context10.next = 7;
|
|
528
|
+
return this.apiClient.makeRequest({
|
|
529
|
+
method: type.startsWith("un") ? "DELETE" : "PUT",
|
|
530
|
+
url: "/v1/messages/".concat(itemOrItems.id, "/").concat(type)
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
case 7:
|
|
534
|
+
result = _context10.sent;
|
|
535
|
+
return _context10.abrupt("return", result);
|
|
536
|
+
|
|
537
|
+
case 9:
|
|
538
|
+
case "end":
|
|
539
|
+
return _context10.stop();
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}, _callee10, this);
|
|
543
|
+
}));
|
|
544
|
+
|
|
545
|
+
function makeStatusUpdate(_x8, _x9) {
|
|
546
|
+
return _makeStatusUpdate.apply(this, arguments);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return makeStatusUpdate;
|
|
550
|
+
}()
|
|
551
|
+
}]);
|
|
552
|
+
return Feed;
|
|
553
|
+
}();
|
|
554
|
+
|
|
555
|
+
var _default = Feed;
|
|
556
|
+
exports["default"] = _default;
|
|
557
|
+
//# sourceMappingURL=feed.js.map
|