@quesmed/types-rn 2.0.4
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/gql_input_output_types/User.d.ts +12 -0
- package/gql_input_output_types/User.js +2 -0
- package/gql_input_output_types/index.d.ts +75 -0
- package/gql_input_output_types/index.js +2 -0
- package/index.d.ts +22 -0
- package/index.js +124 -0
- package/models/Author.d.ts +14 -0
- package/models/Author.js +2 -0
- package/models/Blog.d.ts +15 -0
- package/models/Blog.js +2 -0
- package/models/Book.d.ts +22 -0
- package/models/Book.js +2 -0
- package/models/Card.d.ts +16 -0
- package/models/Card.js +2 -0
- package/models/Chapter.d.ts +15 -0
- package/models/Chapter.js +2 -0
- package/models/Concept.d.ts +15 -0
- package/models/Concept.js +2 -0
- package/models/Difficulty.d.ts +6 -0
- package/models/Difficulty.js +10 -0
- package/models/Feedback.d.ts +8 -0
- package/models/Feedback.js +2 -0
- package/models/File.d.ts +10 -0
- package/models/File.js +2 -0
- package/models/Marksheet.d.ts +36 -0
- package/models/Marksheet.js +2 -0
- package/models/MockTest.d.ts +22 -0
- package/models/MockTest.js +2 -0
- package/models/OsceMarksheet.d.ts +105 -0
- package/models/OsceMarksheet.js +103 -0
- package/models/OsceStation.d.ts +54 -0
- package/models/OsceStation.js +45 -0
- package/models/Picture.d.ts +14 -0
- package/models/Picture.js +2 -0
- package/models/Promo.d.ts +14 -0
- package/models/Promo.js +2 -0
- package/models/Question.d.ts +115 -0
- package/models/Question.js +43 -0
- package/models/Subscription.d.ts +17 -0
- package/models/Subscription.js +9 -0
- package/models/Todo.d.ts +33 -0
- package/models/Todo.js +2 -0
- package/models/Token.d.ts +9 -0
- package/models/Token.js +2 -0
- package/models/Topic.d.ts +32 -0
- package/models/Topic.js +13 -0
- package/models/Type.d.ts +7 -0
- package/models/Type.js +2 -0
- package/models/University.d.ts +5 -0
- package/models/University.js +2 -0
- package/models/User.d.ts +119 -0
- package/models/User.js +70 -0
- package/models/Video.d.ts +26 -0
- package/models/Video.js +2 -0
- package/models/index.d.ts +24 -0
- package/models/index.js +36 -0
- package/package.json +35 -0
- package/resolvers/apollo.d.ts +8 -0
- package/resolvers/apollo.js +2 -0
- package/resolvers/fragments/blog.d.ts +1 -0
- package/resolvers/fragments/blog.js +17 -0
- package/resolvers/fragments/chapter.d.ts +1 -0
- package/resolvers/fragments/chapter.js +25 -0
- package/resolvers/fragments/concept.d.ts +3 -0
- package/resolvers/fragments/concept.js +79 -0
- package/resolvers/fragments/index.d.ts +7 -0
- package/resolvers/fragments/index.js +19 -0
- package/resolvers/fragments/osce.d.ts +5 -0
- package/resolvers/fragments/osce.js +139 -0
- package/resolvers/fragments/picture.d.ts +1 -0
- package/resolvers/fragments/picture.js +22 -0
- package/resolvers/fragments/user.d.ts +1 -0
- package/resolvers/fragments/user.js +39 -0
- package/resolvers/fragments/video.d.ts +2 -0
- package/resolvers/fragments/video.js +58 -0
- package/resolvers/index.d.ts +12 -0
- package/resolvers/index.js +38 -0
- package/resolvers/mutation/admin/algoliaSync.d.ts +9 -0
- package/resolvers/mutation/admin/algoliaSync.js +2 -0
- package/resolvers/mutation/admin/index.d.ts +2 -0
- package/resolvers/mutation/admin/index.js +14 -0
- package/resolvers/mutation/admin/token.d.ts +25 -0
- package/resolvers/mutation/admin/token.js +2 -0
- package/resolvers/mutation/index.d.ts +5 -0
- package/resolvers/mutation/index.js +30 -0
- package/resolvers/mutation/restricted/agora.d.ts +10 -0
- package/resolvers/mutation/restricted/agora.js +11 -0
- package/resolvers/mutation/restricted/contactUs.d.ts +17 -0
- package/resolvers/mutation/restricted/contactUs.js +2 -0
- package/resolvers/mutation/restricted/index.d.ts +10 -0
- package/resolvers/mutation/restricted/index.js +22 -0
- package/resolvers/mutation/restricted/marksheet.d.ts +41 -0
- package/resolvers/mutation/restricted/marksheet.js +2 -0
- package/resolvers/mutation/restricted/mockTest.d.ts +16 -0
- package/resolvers/mutation/restricted/mockTest.js +2 -0
- package/resolvers/mutation/restricted/osce.d.ts +87 -0
- package/resolvers/mutation/restricted/osce.js +222 -0
- package/resolvers/mutation/restricted/questionDiscussion.d.ts +24 -0
- package/resolvers/mutation/restricted/questionDiscussion.js +2 -0
- package/resolvers/mutation/restricted/todo.d.ts +32 -0
- package/resolvers/mutation/restricted/todo.js +2 -0
- package/resolvers/mutation/restricted/token.d.ts +21 -0
- package/resolvers/mutation/restricted/token.js +2 -0
- package/resolvers/mutation/restricted/users.d.ts +29 -0
- package/resolvers/mutation/restricted/users.js +11 -0
- package/resolvers/mutation/restricted/video.d.ts +6 -0
- package/resolvers/mutation/restricted/video.js +2 -0
- package/resolvers/mutation/stripe.d.ts +11 -0
- package/resolvers/mutation/stripe.js +2 -0
- package/resolvers/mutation/users.d.ts +32 -0
- package/resolvers/mutation/users.js +2 -0
- package/resolvers/mutation/validUserToken/index.d.ts +1 -0
- package/resolvers/mutation/validUserToken/index.js +13 -0
- package/resolvers/mutation/validUserToken/user.d.ts +14 -0
- package/resolvers/mutation/validUserToken/user.js +2 -0
- package/resolvers/query/admin/getUserToken.d.ts +5 -0
- package/resolvers/query/admin/getUserToken.js +2 -0
- package/resolvers/query/admin/index.d.ts +1 -0
- package/resolvers/query/admin/index.js +13 -0
- package/resolvers/query/author.d.ts +3 -0
- package/resolvers/query/author.js +2 -0
- package/resolvers/query/blog.d.ts +15 -0
- package/resolvers/query/blog.js +36 -0
- package/resolvers/query/book.d.ts +8 -0
- package/resolvers/query/book.js +2 -0
- package/resolvers/query/feedback.d.ts +3 -0
- package/resolvers/query/feedback.js +2 -0
- package/resolvers/query/index.d.ts +11 -0
- package/resolvers/query/index.js +36 -0
- package/resolvers/query/restricted/index.d.ts +10 -0
- package/resolvers/query/restricted/index.js +22 -0
- package/resolvers/query/restricted/marksheet.d.ts +47 -0
- package/resolvers/query/restricted/marksheet.js +2 -0
- package/resolvers/query/restricted/mockTests.d.ts +10 -0
- package/resolvers/query/restricted/mockTests.js +2 -0
- package/resolvers/query/restricted/osce.d.ts +45 -0
- package/resolvers/query/restricted/osce.js +118 -0
- package/resolvers/query/restricted/quesBook.d.ts +7 -0
- package/resolvers/query/restricted/quesBook.js +17 -0
- package/resolvers/query/restricted/replication.d.ts +32 -0
- package/resolvers/query/restricted/replication.js +184 -0
- package/resolvers/query/restricted/todos.d.ts +15 -0
- package/resolvers/query/restricted/todos.js +2 -0
- package/resolvers/query/restricted/topics.d.ts +10 -0
- package/resolvers/query/restricted/topics.js +2 -0
- package/resolvers/query/restricted/university.d.ts +15 -0
- package/resolvers/query/restricted/university.js +2 -0
- package/resolvers/query/restricted/user.d.ts +13 -0
- package/resolvers/query/restricted/user.js +2 -0
- package/resolvers/query/restricted/video.d.ts +11 -0
- package/resolvers/query/restricted/video.js +2 -0
- package/resolvers/query/sample.d.ts +26 -0
- package/resolvers/query/sample.js +98 -0
- package/resolvers/query/subscription.d.ts +3 -0
- package/resolvers/query/subscription.js +2 -0
- package/resolvers/query/university.d.ts +6 -0
- package/resolvers/query/university.js +2 -0
- package/resolvers/query/user.d.ts +13 -0
- package/resolvers/query/user.js +2 -0
- package/resolvers/query/video.d.ts +15 -0
- package/resolvers/query/video.js +2 -0
- package/resolvers/subscription/index.d.ts +1 -0
- package/resolvers/subscription/index.js +13 -0
- package/resolvers/subscription/osce.d.ts +66 -0
- package/resolvers/subscription/osce.js +108 -0
- package/resolvers/types.d.ts +10 -0
- package/resolvers/types.js +2 -0
- package/utils/commonFunctions.d.ts +9 -0
- package/utils/commonFunctions.js +256 -0
- package/utils/index.d.ts +9 -0
- package/utils/index.js +42 -0
- package/utils/lightgallery.d.ts +9 -0
- package/utils/lightgallery.js +88 -0
- package/utils/offlineLink.d.ts +64 -0
- package/utils/offlineLink.js +221 -0
- package/utils/random.d.ts +1 -0
- package/utils/random.js +20 -0
- package/utils/uuid4.d.ts +107 -0
- package/utils/uuid4.js +282 -0
- package/utils/webSocketLink.d.ts +7 -0
- package/utils/webSocketLink.js +22 -0
- package/utils/wordsToNumber.d.ts +1 -0
- package/utils/wordsToNumber.js +48 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { CacheManager } from 'react-native-expo-image-cache';
|
|
3
|
+
import { IOsceMarksheet, IOsceStation } from '../models';
|
|
4
|
+
export interface ILightGalleryCache {
|
|
5
|
+
CacheManager: typeof CacheManager;
|
|
6
|
+
Platform: typeof Platform;
|
|
7
|
+
}
|
|
8
|
+
export declare function lightgalleryOsceResolve(data: IOsceStation, cache?: ILightGalleryCache): Promise<IOsceStation>;
|
|
9
|
+
export declare function lightgalleryOsceResolve(data: IOsceMarksheet, cache?: ILightGalleryCache): Promise<IOsceMarksheet>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lightgalleryOsceResolve = void 0;
|
|
4
|
+
const lightgalleryRegex = /\[lightgallery\]/;
|
|
5
|
+
function isOsceMarksheet(data) {
|
|
6
|
+
return 'osceStationId' in data;
|
|
7
|
+
}
|
|
8
|
+
async function lightgalleryOsceResolve(data, cache) {
|
|
9
|
+
let station;
|
|
10
|
+
if (isOsceMarksheet(data)) {
|
|
11
|
+
if (!data.osceStation) {
|
|
12
|
+
throw new Error('OsceStation not found on OsceMarksheet');
|
|
13
|
+
}
|
|
14
|
+
station = data.osceStation;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
station = data;
|
|
18
|
+
}
|
|
19
|
+
const upOsceStation = {
|
|
20
|
+
candidateBrief: station.candidateBrief,
|
|
21
|
+
actorBrief: station.actorBrief,
|
|
22
|
+
examinerBrief: station.examinerBrief,
|
|
23
|
+
explanation: station.explanation,
|
|
24
|
+
};
|
|
25
|
+
if (station.candidatePictures && station.candidatePictures.length > 0) {
|
|
26
|
+
upOsceStation.candidateBrief = await lightgalleryMutation(upOsceStation.candidateBrief, station.candidatePictures, cache);
|
|
27
|
+
}
|
|
28
|
+
if (station.actorPictures && station.actorPictures.length > 0) {
|
|
29
|
+
upOsceStation.actorBrief = await lightgalleryMutation(upOsceStation.actorBrief, station.actorPictures, cache);
|
|
30
|
+
}
|
|
31
|
+
if (station.examinerPictures && station.examinerPictures.length > 0) {
|
|
32
|
+
upOsceStation.examinerBrief = await lightgalleryMutation(upOsceStation.examinerBrief, station.examinerPictures, cache);
|
|
33
|
+
}
|
|
34
|
+
if (station.walkthroughPictures && station.walkthroughPictures.length > 0) {
|
|
35
|
+
upOsceStation.explanation = await lightgalleryMutation(upOsceStation.explanation, station.walkthroughPictures, cache);
|
|
36
|
+
}
|
|
37
|
+
if (isOsceMarksheet(data)) {
|
|
38
|
+
return {
|
|
39
|
+
...data,
|
|
40
|
+
osceStation: {
|
|
41
|
+
...data.osceStation,
|
|
42
|
+
...upOsceStation,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return {
|
|
48
|
+
...data,
|
|
49
|
+
...upOsceStation,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.lightgalleryOsceResolve = lightgalleryOsceResolve;
|
|
54
|
+
const lightgalleryMutation = async (text, pictures, cache) => {
|
|
55
|
+
if (pictures.length === 0) {
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
const picturesHTML = [];
|
|
59
|
+
for (const picture of pictures) {
|
|
60
|
+
const pic = picture.path;
|
|
61
|
+
const uri = `https://app.quesmed.com/${pic}`;
|
|
62
|
+
let file = '';
|
|
63
|
+
if (cache) {
|
|
64
|
+
try {
|
|
65
|
+
const localPath = await cache.CacheManager.get(uri, {}).getPath();
|
|
66
|
+
if (localPath) {
|
|
67
|
+
file =
|
|
68
|
+
cache.Platform.OS === 'ios'
|
|
69
|
+
? localPath.replace('file://', '')
|
|
70
|
+
: localPath;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
console.error(e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (picture.caption?.length > 0) {
|
|
78
|
+
picturesHTML.push(``);
|
|
79
|
+
}
|
|
80
|
+
picturesHTML.push(``);
|
|
81
|
+
}
|
|
82
|
+
if (lightgalleryRegex.test(text)) {
|
|
83
|
+
return text.replace(lightgalleryRegex, picturesHTML[0]);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return text + '\n\n' + picturesHTML[0] + '\n';
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ApolloClient, ApolloLink, MutationOptions, NextLink, Observable, Operation } from '@apollo/client';
|
|
3
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
+
import Localforage from 'localforage';
|
|
5
|
+
export interface IOfflineLinkParam {
|
|
6
|
+
storage: typeof Localforage | typeof AsyncStorage;
|
|
7
|
+
retryInterval?: number;
|
|
8
|
+
sequential?: boolean;
|
|
9
|
+
retryOnServerError?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class OfflineLink extends ApolloLink {
|
|
12
|
+
storage: typeof Localforage | typeof AsyncStorage;
|
|
13
|
+
retryInterval: number;
|
|
14
|
+
sequential: boolean;
|
|
15
|
+
retryOnServerError: boolean;
|
|
16
|
+
queue: Map<string, MutationOptions>;
|
|
17
|
+
prefix: string;
|
|
18
|
+
client?: ApolloClient<any>;
|
|
19
|
+
timeoutId?: NodeJS.Timeout;
|
|
20
|
+
/**
|
|
21
|
+
* storage
|
|
22
|
+
* Provider that will persist the mutation queue. This can be any AsyncStorage compatible storage instance.
|
|
23
|
+
*
|
|
24
|
+
* retryInterval
|
|
25
|
+
* Milliseconds between attempts to retry failed mutations. Defaults to 0, which disables automatic retry.
|
|
26
|
+
*
|
|
27
|
+
* sequential
|
|
28
|
+
* Indicates if the attempts should be retried in order. Defaults to false which retries all failed mutations in parallel.
|
|
29
|
+
*
|
|
30
|
+
* retryOnServerError
|
|
31
|
+
* Indicates if mutations should be reattempted if there are server side errors, useful to retry mutations on session expiration. Defaults to false.
|
|
32
|
+
*/
|
|
33
|
+
constructor({ storage, retryInterval, sequential, retryOnServerError, }: IOfflineLinkParam);
|
|
34
|
+
request(operation: Operation, forward: NextLink): Observable<any>;
|
|
35
|
+
/**
|
|
36
|
+
* Obtains the queue of mutations that must be sent to the server.
|
|
37
|
+
* These are kept in a Map to preserve the order of the mutations in the queue.
|
|
38
|
+
*/
|
|
39
|
+
getQueue(): Promise<Map<any, any>>;
|
|
40
|
+
/**
|
|
41
|
+
* Persist the queue so mutations can be retried at a later point in time.
|
|
42
|
+
*/
|
|
43
|
+
private saveQueue;
|
|
44
|
+
/**
|
|
45
|
+
* Add a mutation attempt to the queue so that it can be retried at a later point in time.
|
|
46
|
+
*/
|
|
47
|
+
private add;
|
|
48
|
+
/**
|
|
49
|
+
* Remove a mutation attempt from the queue.
|
|
50
|
+
*/
|
|
51
|
+
private remove;
|
|
52
|
+
/**
|
|
53
|
+
* Takes the mutations in the queue and try to send them to the server again.
|
|
54
|
+
*/
|
|
55
|
+
sync(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Runs sync() after the retryInterval
|
|
58
|
+
*/
|
|
59
|
+
private delayedSync;
|
|
60
|
+
/**
|
|
61
|
+
* Configure the link to use Apollo Client and immediately try to sync the queue (if there's anything there).
|
|
62
|
+
*/
|
|
63
|
+
setup(client: ApolloClient<any>): Promise<void>;
|
|
64
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
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
|
+
exports.OfflineLink = void 0;
|
|
7
|
+
const client_1 = require("@apollo/client");
|
|
8
|
+
const uuid4_1 = __importDefault(require("./uuid4"));
|
|
9
|
+
class OfflineLink extends client_1.ApolloLink {
|
|
10
|
+
/**
|
|
11
|
+
* storage
|
|
12
|
+
* Provider that will persist the mutation queue. This can be any AsyncStorage compatible storage instance.
|
|
13
|
+
*
|
|
14
|
+
* retryInterval
|
|
15
|
+
* Milliseconds between attempts to retry failed mutations. Defaults to 0, which disables automatic retry.
|
|
16
|
+
*
|
|
17
|
+
* sequential
|
|
18
|
+
* Indicates if the attempts should be retried in order. Defaults to false which retries all failed mutations in parallel.
|
|
19
|
+
*
|
|
20
|
+
* retryOnServerError
|
|
21
|
+
* Indicates if mutations should be reattempted if there are server side errors, useful to retry mutations on session expiration. Defaults to false.
|
|
22
|
+
*/
|
|
23
|
+
constructor({ storage, retryInterval = 0, sequential = false, retryOnServerError = false, }) {
|
|
24
|
+
super();
|
|
25
|
+
this.queue = new Map();
|
|
26
|
+
this.prefix = 'offlineLink:';
|
|
27
|
+
if (!storage) {
|
|
28
|
+
throw new Error('Storage is required, it can be an AsyncStorage compatible storage instance.');
|
|
29
|
+
}
|
|
30
|
+
this.storage = storage;
|
|
31
|
+
this.sequential = sequential;
|
|
32
|
+
this.retryInterval = retryInterval;
|
|
33
|
+
this.retryOnServerError = retryOnServerError;
|
|
34
|
+
}
|
|
35
|
+
request(operation, forward) {
|
|
36
|
+
const context = operation.getContext();
|
|
37
|
+
const { query, variables } = operation || {};
|
|
38
|
+
if (!context.optimisticResponse) {
|
|
39
|
+
// If the mutation does not have an optimisticResponse then we can't defer it
|
|
40
|
+
return forward(operation);
|
|
41
|
+
}
|
|
42
|
+
return new client_1.Observable((observer) => {
|
|
43
|
+
const mutationId = uuid4_1.default.asBase64();
|
|
44
|
+
this.add({
|
|
45
|
+
mutation: query,
|
|
46
|
+
variables,
|
|
47
|
+
optimisticResponse: context.optimisticResponse,
|
|
48
|
+
}, mutationId);
|
|
49
|
+
const subscription = forward(operation).subscribe({
|
|
50
|
+
next: (result) => {
|
|
51
|
+
this.remove(mutationId);
|
|
52
|
+
observer.next(result);
|
|
53
|
+
},
|
|
54
|
+
error: () => {
|
|
55
|
+
// Mutation failed so we try again after a certain amount of time.
|
|
56
|
+
this.delayedSync();
|
|
57
|
+
// Resolve the mutation with the optimistic response so the UI can be updated
|
|
58
|
+
observer.next({
|
|
59
|
+
data: context.optimisticResponse,
|
|
60
|
+
dataPresent: true,
|
|
61
|
+
errors: [],
|
|
62
|
+
});
|
|
63
|
+
// Say we're all done so the UI is re-rendered.
|
|
64
|
+
observer.complete();
|
|
65
|
+
},
|
|
66
|
+
complete: () => observer.complete(),
|
|
67
|
+
});
|
|
68
|
+
return () => {
|
|
69
|
+
subscription.unsubscribe();
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Obtains the queue of mutations that must be sent to the server.
|
|
75
|
+
* These are kept in a Map to preserve the order of the mutations in the queue.
|
|
76
|
+
*/
|
|
77
|
+
async getQueue() {
|
|
78
|
+
const map = new Map();
|
|
79
|
+
try {
|
|
80
|
+
const storedMutations = await this.storage.getItem(this.prefix + 'Mutations');
|
|
81
|
+
if (!storedMutations) {
|
|
82
|
+
return map;
|
|
83
|
+
}
|
|
84
|
+
const mutationIds = storedMutations.split(',');
|
|
85
|
+
for (const mutationId of mutationIds) {
|
|
86
|
+
const storedMutation = await this.storage.getItem(this.prefix + mutationId);
|
|
87
|
+
if (!storedMutation) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
map.set(mutationId, JSON.parse(storedMutation));
|
|
91
|
+
}
|
|
92
|
+
return map;
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
console.error(e);
|
|
96
|
+
return map;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Persist the queue so mutations can be retried at a later point in time.
|
|
101
|
+
*/
|
|
102
|
+
async saveQueue(mutationId, mutation) {
|
|
103
|
+
try {
|
|
104
|
+
if (mutationId && mutation) {
|
|
105
|
+
await this.storage.setItem(this.prefix + mutationId, JSON.stringify(mutation));
|
|
106
|
+
}
|
|
107
|
+
await this.storage.setItem(this.prefix + 'Mutations', [...this.queue.keys()].join());
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
console.error(e);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Add a mutation attempt to the queue so that it can be retried at a later point in time.
|
|
115
|
+
*/
|
|
116
|
+
async add(item, mutationId) {
|
|
117
|
+
// We give the mutation attempt a random id so that it is easy to remove when needed (in sync loop)
|
|
118
|
+
if (!mutationId) {
|
|
119
|
+
mutationId = uuid4_1.default.asBase64();
|
|
120
|
+
}
|
|
121
|
+
this.queue.set(mutationId, item);
|
|
122
|
+
await this.saveQueue(mutationId, item);
|
|
123
|
+
return mutationId;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Remove a mutation attempt from the queue.
|
|
127
|
+
*/
|
|
128
|
+
async remove(mutationId) {
|
|
129
|
+
this.queue.delete(mutationId);
|
|
130
|
+
await this.storage.removeItem(this.prefix + mutationId);
|
|
131
|
+
await this.saveQueue();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Takes the mutations in the queue and try to send them to the server again.
|
|
135
|
+
*/
|
|
136
|
+
async sync() {
|
|
137
|
+
if (!this.client) {
|
|
138
|
+
throw new Error('Offline Link not setup with ApolloClient');
|
|
139
|
+
}
|
|
140
|
+
if (this.queue.size === 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const attempts = Array.from(this.queue);
|
|
144
|
+
if (this.sequential) {
|
|
145
|
+
for (const [mutationId, attempt] of attempts) {
|
|
146
|
+
let serverProcessed = false;
|
|
147
|
+
try {
|
|
148
|
+
await this.client.mutate({
|
|
149
|
+
...attempt,
|
|
150
|
+
optimisticResponse: undefined,
|
|
151
|
+
});
|
|
152
|
+
serverProcessed = true;
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
const err = e;
|
|
156
|
+
const networkError = err.networkError;
|
|
157
|
+
if (!this.retryOnServerError && networkError?.response) {
|
|
158
|
+
// There are GraphQL errors, which means the server processed the request so we can remove the mutation from the queue
|
|
159
|
+
serverProcessed = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (serverProcessed) {
|
|
163
|
+
try {
|
|
164
|
+
await this.remove(mutationId);
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
console.error(e);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
await Promise.all(attempts.map(async ([mutationId, attempt]) => {
|
|
174
|
+
let serverProcessed = false;
|
|
175
|
+
try {
|
|
176
|
+
await this.client?.mutate({
|
|
177
|
+
...attempt,
|
|
178
|
+
optimisticResponse: undefined,
|
|
179
|
+
});
|
|
180
|
+
serverProcessed = true;
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
const err = e;
|
|
184
|
+
const networkError = err.networkError;
|
|
185
|
+
if (!this.retryOnServerError && networkError?.response) {
|
|
186
|
+
serverProcessed = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (serverProcessed) {
|
|
190
|
+
await this.remove(mutationId);
|
|
191
|
+
}
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
// Remaining mutations in the queue are persisted
|
|
195
|
+
await this.saveQueue();
|
|
196
|
+
if (this.queue.size !== 0 || this.retryInterval !== 0) {
|
|
197
|
+
this.delayedSync();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Runs sync() after the retryInterval
|
|
202
|
+
*/
|
|
203
|
+
delayedSync() {
|
|
204
|
+
if (this.retryInterval === 0) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (this.timeoutId) {
|
|
208
|
+
clearTimeout(this.timeoutId);
|
|
209
|
+
}
|
|
210
|
+
this.timeoutId = setTimeout(() => this.sync, this.retryInterval);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Configure the link to use Apollo Client and immediately try to sync the queue (if there's anything there).
|
|
214
|
+
*/
|
|
215
|
+
async setup(client) {
|
|
216
|
+
this.client = client;
|
|
217
|
+
this.queue = await this.getQueue();
|
|
218
|
+
await this.sync();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.OfflineLink = OfflineLink;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getRandom<T>(arr: T[], n?: number): T[];
|
package/utils/random.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRandom = void 0;
|
|
4
|
+
function getRandom(arr, n) {
|
|
5
|
+
if (n === undefined || n === null) {
|
|
6
|
+
n = arr.length;
|
|
7
|
+
}
|
|
8
|
+
const result = new Array(n);
|
|
9
|
+
let len = arr.length;
|
|
10
|
+
const taken = new Array(len);
|
|
11
|
+
if (n > len)
|
|
12
|
+
throw new RangeError('getRandom: more elements taken than available');
|
|
13
|
+
while (n--) {
|
|
14
|
+
const x = Math.floor(Math.random() * len);
|
|
15
|
+
result[n] = arr[x in taken ? taken[x] : x];
|
|
16
|
+
taken[x] = --len in taken ? taken[len] : len;
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
exports.getRandom = getRandom;
|
package/utils/uuid4.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
declare class Uuid4 {
|
|
2
|
+
/**
|
|
3
|
+
* Generate a custom base 64 encoded UUID v4 (random).
|
|
4
|
+
*
|
|
5
|
+
* @param {Uint8Array} [data] Should normally be `undefined` to create a
|
|
6
|
+
* truly random v4 UUID.
|
|
7
|
+
* @returns {string} Returns a custom base 64 encoded UUID v4.
|
|
8
|
+
*/
|
|
9
|
+
static asBase64(data?: Uint8Array): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a hexadecimal encoded UUID v4 (random).
|
|
12
|
+
*
|
|
13
|
+
* @param {Uint8Array} [data] Should normally be `undefined` to create a
|
|
14
|
+
* truly random v4 UUID.
|
|
15
|
+
* @returns {string} Returns a hexadecimal encoded UUID v4.
|
|
16
|
+
*/
|
|
17
|
+
static asHexString(data?: Uint8Array): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generate a standard UUID v4 (random).
|
|
20
|
+
*
|
|
21
|
+
* @param {Uint8Array} [data] Should normally be `undefined` to create a
|
|
22
|
+
* truly random v4 UUID.
|
|
23
|
+
* @returns {string} Returns a standard UUID v4.
|
|
24
|
+
*/
|
|
25
|
+
static asUuid(data?: Uint8Array): string;
|
|
26
|
+
/**
|
|
27
|
+
* Convert from a base 64 encoded to a hexadecimal encoded UUID.
|
|
28
|
+
*
|
|
29
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} data A base 64 encoded UUID.
|
|
32
|
+
* @returns {string} Returns a hexadecimal encoded UUID.
|
|
33
|
+
*/
|
|
34
|
+
static fromBase64ToHexString(data: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Convert from a base 64 encoded to a standard UUID.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
39
|
+
*
|
|
40
|
+
* @param {string} data The base 64 encoded UUID.
|
|
41
|
+
* @returns {string} Returns a standard UUID.
|
|
42
|
+
*/
|
|
43
|
+
static fromBase64ToUuid(data: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Convert from a hexadecimal encoded to a base 64 encoded UUID.
|
|
46
|
+
*
|
|
47
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
48
|
+
*
|
|
49
|
+
* @param {string} data The hexadecimal encoded UUID.
|
|
50
|
+
* @returns {string} Returns base 64 encoded UUID.
|
|
51
|
+
*/
|
|
52
|
+
static fromHexStringToBase64(data: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Convert from a hexadecimal encoded to a standard UUID.
|
|
55
|
+
*
|
|
56
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} data The hexadecimal encoded UUID.
|
|
59
|
+
* @returns {string} Returns a standard UUID.
|
|
60
|
+
*/
|
|
61
|
+
static fromHexStringToUuid(data: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Convert from a standard UUID to a base 64 encoded UUID.
|
|
64
|
+
*
|
|
65
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
66
|
+
*
|
|
67
|
+
* @param {string} data The standard UUID.
|
|
68
|
+
* @returns {string} Returns base 64 encoded UUID.
|
|
69
|
+
*/
|
|
70
|
+
static fromUuidToBase64(data: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Convert from a standard UUID to a hexadecimal encoded UUID.
|
|
73
|
+
*
|
|
74
|
+
* NOTE: This method does not verify input is valid UUID.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} data The standard UUID.
|
|
77
|
+
* @returns {string} Returns a hexadecimal encoded UUID.
|
|
78
|
+
*/
|
|
79
|
+
static fromUuidToHexString(data: string): string;
|
|
80
|
+
get [Symbol.toStringTag](): string;
|
|
81
|
+
/**
|
|
82
|
+
* Helper method for the common parts of creating new UUID encoded as a binary string.
|
|
83
|
+
*
|
|
84
|
+
* @param {Uint8Array} [data] Should normally be `undefined` to create a
|
|
85
|
+
* truly random v4 UUID.
|
|
86
|
+
* @returns {string} Returns an UUID encoded as a binary string.
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
protected static _asBinString(data?: Uint8Array): string;
|
|
90
|
+
/**
|
|
91
|
+
* Used to paste over differences in browser vs node secure random number generation.
|
|
92
|
+
*
|
|
93
|
+
* @returns {Uint8Array} Returns a new random number filled Uint8Array.
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
protected static _getRandomArray(): Uint8Array;
|
|
97
|
+
/**
|
|
98
|
+
* Used in mapping from binary to base 64 during encoding.
|
|
99
|
+
*
|
|
100
|
+
* @type {object}
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
protected static _base64: {
|
|
104
|
+
[key: string]: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export default Uuid4;
|