@superbia/untrue 1.1.4 → 1.1.6
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/README.md +65 -38
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -45,7 +45,6 @@ If we receive some client data like:
|
|
|
45
45
|
"_typename": "User",
|
|
46
46
|
"_id": "123",
|
|
47
47
|
"name": "Jhon Doe",
|
|
48
|
-
"username": "jhondoe",
|
|
49
48
|
"lastPost": {
|
|
50
49
|
"_typename": "Post",
|
|
51
50
|
"_id": "456",
|
|
@@ -64,7 +63,6 @@ this.documents = {
|
|
|
64
63
|
_typename: "User",
|
|
65
64
|
_id: "123",
|
|
66
65
|
name: "Jhon Doe",
|
|
67
|
-
username: "jhondoe",
|
|
68
66
|
lastPost: "456",
|
|
69
67
|
},
|
|
70
68
|
},
|
|
@@ -82,12 +80,16 @@ Notice how for `lastPost` we only store the `id`. We do this to have a single so
|
|
|
82
80
|
|
|
83
81
|
### Creation
|
|
84
82
|
|
|
83
|
+
`AppDocumentContext.js`
|
|
84
|
+
|
|
85
85
|
```js
|
|
86
86
|
import { DocumentContext } from "@superbia/untrue";
|
|
87
87
|
|
|
88
88
|
import { client } from "./client";
|
|
89
89
|
|
|
90
90
|
class AppDocumentContext extends DocumentContext {
|
|
91
|
+
// we'll have the documents in this.documents
|
|
92
|
+
|
|
91
93
|
onFollow = (userId) => {
|
|
92
94
|
const user = this.documents.User[userId]; // get the user
|
|
93
95
|
|
|
@@ -119,38 +121,35 @@ export default new AppDocumentContext(client, {
|
|
|
119
121
|
|
|
120
122
|
### Usage
|
|
121
123
|
|
|
124
|
+
`User.js`
|
|
125
|
+
|
|
122
126
|
```js
|
|
123
127
|
import { Node, Wrapper } from "untrue";
|
|
124
128
|
|
|
125
129
|
import AppDocumentContext from "./AppDocumentContext";
|
|
126
130
|
|
|
127
|
-
function User({ userId, name,
|
|
131
|
+
function User({ userId, name, following, onFollow, onUnfollow }) {
|
|
128
132
|
const onFollowUser = () => onFollow(userId);
|
|
129
133
|
const onUnfollowUser = () => onUnfollow(userId);
|
|
130
134
|
|
|
131
135
|
return [
|
|
132
136
|
new Node("span", name),
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"button",
|
|
136
|
-
{
|
|
137
|
-
onclick: following ? onUnfollowUser : onFollowUser,
|
|
138
|
-
},
|
|
139
|
-
following ? "unfollow" : "follow"
|
|
140
|
-
),
|
|
137
|
+
following
|
|
138
|
+
? new Node("button", { onclick: onUnfollowUser }, "unfollow")
|
|
139
|
+
: new Node("button", { onclick: onFollowUser }, "follow"),
|
|
141
140
|
];
|
|
142
141
|
}
|
|
143
142
|
|
|
144
143
|
export default Wrapper.wrapContext(User, AppDocumentContext, (props) => {
|
|
145
|
-
const { userId } = props;
|
|
144
|
+
const { userId } = props; // we receive the userId as a prop
|
|
146
145
|
|
|
147
146
|
const documents = AppDocumentContext.getDocuments(); // all the documents
|
|
148
147
|
|
|
149
|
-
const { name,
|
|
148
|
+
const { name, following } = documents.User[userId]; // the desired user document
|
|
150
149
|
|
|
151
150
|
const { onFollow, onUnfollow } = AppDocumentContext; // context handlers
|
|
152
151
|
|
|
153
|
-
return { name,
|
|
152
|
+
return { name, following, onFollow, onUnfollow }; // data the component needs
|
|
154
153
|
});
|
|
155
154
|
```
|
|
156
155
|
|
|
@@ -165,7 +164,7 @@ Every `request` has 4 properties:
|
|
|
165
164
|
- `data`: `Object`. Result of the request. `null` if the request hasn't been completed yet or an error was found.
|
|
166
165
|
- `error`: `Error` object or `null`. It's an `Error` object if the request has been completed but there's an error in the request itself or in any endpoint.
|
|
167
166
|
|
|
168
|
-
|
|
167
|
+
Let's say we have an endpoint `userPosts` that returns an array of `Post` documents:
|
|
169
168
|
|
|
170
169
|
```json
|
|
171
170
|
{
|
|
@@ -176,21 +175,26 @@ The next example assumes we have an endpoint `userPosts` that returns an array o
|
|
|
176
175
|
}
|
|
177
176
|
```
|
|
178
177
|
|
|
179
|
-
|
|
178
|
+
The `requests` inside `RequestContext` would be:
|
|
180
179
|
|
|
181
180
|
```js
|
|
182
181
|
this.requests = {
|
|
183
|
-
|
|
182
|
+
someUniqueRequestKey: {
|
|
184
183
|
loading: false,
|
|
185
184
|
done: true,
|
|
186
185
|
error: null,
|
|
187
186
|
data: { userPosts: ["123", "456"] },
|
|
188
187
|
},
|
|
188
|
+
// more requests
|
|
189
189
|
};
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
Just as in `DocumentContext`, we won't store the entire documents but their IDs only.
|
|
193
|
+
|
|
192
194
|
### Creation
|
|
193
195
|
|
|
196
|
+
`AppRequestContext.js`
|
|
197
|
+
|
|
194
198
|
```js
|
|
195
199
|
import { RequestContext } from "@superbia/untrue";
|
|
196
200
|
|
|
@@ -210,11 +214,15 @@ export default new AppRequestContext(client, {
|
|
|
210
214
|
|
|
211
215
|
### Usage
|
|
212
216
|
|
|
217
|
+
`PostList.js`
|
|
218
|
+
|
|
213
219
|
```js
|
|
214
220
|
import { Component, Node, Wrapper } from "untrue";
|
|
215
221
|
|
|
216
222
|
import { RequestWrapper } from "@superbia/untrue";
|
|
217
223
|
|
|
224
|
+
import AppRequestContext from "./AppRequestContext";
|
|
225
|
+
|
|
218
226
|
import Post from "./Post";
|
|
219
227
|
|
|
220
228
|
class PostList extends Component {
|
|
@@ -225,12 +233,12 @@ class PostList extends Component {
|
|
|
225
233
|
}
|
|
226
234
|
|
|
227
235
|
handleMountRequest = () => {
|
|
228
|
-
const { requestKey,
|
|
236
|
+
const { requestKey, onRequest } = this.props;
|
|
229
237
|
|
|
230
238
|
// it will be requested as:
|
|
231
|
-
// client.request({
|
|
239
|
+
// client.request({ posts: null })
|
|
232
240
|
|
|
233
|
-
onRequest(requestKey, {
|
|
241
|
+
onRequest(requestKey, { posts: null });
|
|
234
242
|
};
|
|
235
243
|
|
|
236
244
|
render() {
|
|
@@ -256,7 +264,7 @@ class PostList extends Component {
|
|
|
256
264
|
|
|
257
265
|
export default RequestWrapper.wrapRequester(
|
|
258
266
|
Wrapper.wrapContext(PostList, AppRequestContext, (props) => {
|
|
259
|
-
const { requestKey
|
|
267
|
+
const { requestKey } = props;
|
|
260
268
|
|
|
261
269
|
const requests = AppRequestContext.getRequests(); // all the requests
|
|
262
270
|
|
|
@@ -269,7 +277,7 @@ export default RequestWrapper.wrapRequester(
|
|
|
269
277
|
data = null,
|
|
270
278
|
} = requests?.[requestKey] ?? {};
|
|
271
279
|
|
|
272
|
-
const postIds = data !== null ? data.
|
|
280
|
+
const postIds = data !== null ? data.posts : [];
|
|
273
281
|
|
|
274
282
|
const { onRequest } = AppRequestContext; // context handler
|
|
275
283
|
|
|
@@ -278,6 +286,28 @@ export default RequestWrapper.wrapRequester(
|
|
|
278
286
|
);
|
|
279
287
|
```
|
|
280
288
|
|
|
289
|
+
`Post.js`
|
|
290
|
+
|
|
291
|
+
```js
|
|
292
|
+
import { Node, Wrapper } from "untrue";
|
|
293
|
+
|
|
294
|
+
import AppDocumentContext from "./AppDocumentContext";
|
|
295
|
+
|
|
296
|
+
function Post({ text }) {
|
|
297
|
+
return new Node("div", text);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export default Wrapper.wrapContext(Post, AppDocumentContext, (props) => {
|
|
301
|
+
const { postId } = props;
|
|
302
|
+
|
|
303
|
+
const documents = AppDocumentContext.getDocuments();
|
|
304
|
+
|
|
305
|
+
const { text } = documents.Post[postId];
|
|
306
|
+
|
|
307
|
+
return { text };
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
281
311
|
### Intercepting requests
|
|
282
312
|
|
|
283
313
|
As we know, documents are stored in `DocumentContext` and requests are stored in `RequestContext`.
|
|
@@ -323,12 +353,12 @@ class AppRequestContext extends RequestContext {
|
|
|
323
353
|
}
|
|
324
354
|
```
|
|
325
355
|
|
|
326
|
-
Then in the
|
|
356
|
+
Then in the component, we call the handler:
|
|
327
357
|
|
|
328
358
|
```js
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
359
|
+
const onLike = () => {
|
|
360
|
+
onRequest(null, { likePost: { postId } }); // postId comes from props
|
|
361
|
+
};
|
|
332
362
|
```
|
|
333
363
|
|
|
334
364
|
### Paginated requests
|
|
@@ -382,7 +412,7 @@ The rules of documents will be applied here, so every `node` will be stored as a
|
|
|
382
412
|
|
|
383
413
|
We will need two different components: one for the initial `onRequest` call and another one for the subsequent `onLoad` calls.
|
|
384
414
|
|
|
385
|
-
`
|
|
415
|
+
`PaginatedPostList.js`
|
|
386
416
|
|
|
387
417
|
```js
|
|
388
418
|
import { Component, Node, Wrapper } from "untrue";
|
|
@@ -393,7 +423,7 @@ import AppRequestContext from "./AppRequestContext";
|
|
|
393
423
|
|
|
394
424
|
import Content from "./Content";
|
|
395
425
|
|
|
396
|
-
class
|
|
426
|
+
class PaginatedPostList extends Component {
|
|
397
427
|
constructor(props) {
|
|
398
428
|
super(props);
|
|
399
429
|
|
|
@@ -401,13 +431,13 @@ class PostList extends Component {
|
|
|
401
431
|
}
|
|
402
432
|
|
|
403
433
|
handleMountRequest = () => {
|
|
404
|
-
const { requestKey,
|
|
434
|
+
const { requestKey, onRequest } = this.props;
|
|
405
435
|
|
|
406
|
-
onRequest(requestKey, {
|
|
436
|
+
onRequest(requestKey, { posts: { limit: 2 } });
|
|
407
437
|
};
|
|
408
438
|
|
|
409
439
|
render() {
|
|
410
|
-
const { requestKey,
|
|
440
|
+
const { requestKey, loading, done, error } = this.props;
|
|
411
441
|
|
|
412
442
|
if (loading) {
|
|
413
443
|
return new Node("span", "Loading...");
|
|
@@ -418,7 +448,7 @@ class PostList extends Component {
|
|
|
418
448
|
}
|
|
419
449
|
|
|
420
450
|
if (done) {
|
|
421
|
-
return new Node(Content, { requestKey
|
|
451
|
+
return new Node(Content, { requestKey }); // pass requestKey as prop
|
|
422
452
|
}
|
|
423
453
|
|
|
424
454
|
return null;
|
|
@@ -426,7 +456,7 @@ class PostList extends Component {
|
|
|
426
456
|
}
|
|
427
457
|
|
|
428
458
|
export default RequestWrapper.wrapRequester(
|
|
429
|
-
Wrapper.wrapContext(
|
|
459
|
+
Wrapper.wrapContext(PaginatedPostList, AppRequestContext, (props) => {
|
|
430
460
|
const { requestKey } = props;
|
|
431
461
|
|
|
432
462
|
const requests = AppRequestContext.getRequests(); // all the requests
|
|
@@ -455,7 +485,6 @@ import Post from "./Post";
|
|
|
455
485
|
|
|
456
486
|
function Content({
|
|
457
487
|
requestKey,
|
|
458
|
-
userId,
|
|
459
488
|
loading,
|
|
460
489
|
error,
|
|
461
490
|
postIds,
|
|
@@ -464,9 +493,7 @@ function Content({
|
|
|
464
493
|
onLoad,
|
|
465
494
|
}) {
|
|
466
495
|
const onLoadNext = () => {
|
|
467
|
-
onLoad(requestKey, {
|
|
468
|
-
userPosts: { userId, limit: 20, cursor: nextPageCursor },
|
|
469
|
-
});
|
|
496
|
+
onLoad(requestKey, { posts: { limit: 2, cursor: nextPageCursor } });
|
|
470
497
|
};
|
|
471
498
|
|
|
472
499
|
return [
|
|
@@ -493,7 +520,7 @@ export default Wrapper.wrapContext(Content, AppRequestContext, (props) => {
|
|
|
493
520
|
nodes: postIds, // renaming for convenience
|
|
494
521
|
pageInfo: { hasNextPage, nextPageCursor },
|
|
495
522
|
},
|
|
496
|
-
} = requests[requestKey].data.
|
|
523
|
+
} = requests[requestKey].data.posts; // the desired request's data
|
|
497
524
|
|
|
498
525
|
const { onLoad } = AppRequestContext; // context handler
|
|
499
526
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superbia/untrue",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Integrate Superbia and Untrue.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"untrue": "^
|
|
16
|
+
"untrue": "^4.0.5"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"uuid": "^9.0.0"
|