Skip to content

Commit

Permalink
feat(@aws-amplify/datastore): add Selective Sync (#7001)
Browse files Browse the repository at this point in the history
  • Loading branch information
iartemiev committed Oct 28, 2020
1 parent 958f61e commit 8fa348b
Show file tree
Hide file tree
Showing 16 changed files with 519 additions and 1,468 deletions.
16 changes: 7 additions & 9 deletions packages/core/src/Util/Reachability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,22 @@ export default class ReachabilityNavigator implements Reachability {
return Observable.from([{ online: true }]);
}

return new Observable(observer => {
const online = isWebWorker()
? self.navigator.onLine
: window.navigator.onLine;
const globalObj = isWebWorker() ? self : window;

observer.next({ online });
return new Observable(observer => {
observer.next({ online: globalObj.navigator.onLine });

const notifyOnline = () => observer.next({ online: true });
const notifyOffline = () => observer.next({ online: false });

window.addEventListener('online', notifyOnline);
window.addEventListener('offline', notifyOffline);
globalObj.addEventListener('online', notifyOnline);
globalObj.addEventListener('offline', notifyOffline);

ReachabilityNavigator._observers.push(observer);

return () => {
window.removeEventListener('online', notifyOnline);
window.removeEventListener('offline', notifyOffline);
globalObj.removeEventListener('online', notifyOnline);
globalObj.removeEventListener('offline', notifyOffline);

ReachabilityNavigator._observers = ReachabilityNavigator._observers.filter(
_observer => _observer !== observer
Expand Down
4 changes: 2 additions & 2 deletions packages/datastore/__tests__/AsyncStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
DataStore as DataStoreType,
initSchema as initSchemaType,
} from '../src/datastore/datastore';
import { default as AsyncStorageAdapterType } from '../src/storage/adapter/asyncstorage';
import { default as AsyncStorageAdapterType } from '../src/storage/adapter/AsyncStorageAdapter';
import { DATASTORE, USER } from '../src/util';
import {
Author as AuthorType,
Expand Down Expand Up @@ -93,7 +93,7 @@ function setUpSchema(beforeSetUp?: Function) {

({
default: AsyncStorageAdapter,
} = require('../src/storage/adapter/asyncstorage'));
} = require('../src/storage/adapter/AsyncStorageAdapter'));

({ initSchema, DataStore } = require('../src/datastore/datastore'));

Expand Down
110 changes: 109 additions & 1 deletion packages/datastore/__tests__/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
buildGraphQLOperation,
buildSubscriptionGraphQLOperation,
TransformerMutationType,
predicateToGraphQLFilter,
} from '../src/sync/utils';
import { PredicatesGroup } from '../src/types';
import { newSchema } from './schema';

const postSelectionSet = `
Expand Down Expand Up @@ -39,8 +41,9 @@ describe('DataStore GraphQL generation', () => {
$limit: Int
$nextToken: String
$lastSync: AWSTimestamp
$filter: ModelPostFilterInput
) {
syncPosts(limit: $limit, nextToken: $nextToken, lastSync: $lastSync) {
syncPosts(limit: $limit, nextToken: $nextToken, lastSync: $lastSync, filter: $filter) {
items {
${postSelectionSet}
}
Expand Down Expand Up @@ -169,3 +172,108 @@ describe('DataStore GraphQL generation', () => {
}
);
});

describe('DataStore PredicateGroups to GraphQL filter', () => {
test('Single field', () => {
const group: PredicatesGroup<any> = {
type: 'and',
predicates: [{ field: 'someField', operator: 'eq', operand: 'value' }],
};

const groupExpected = { and: [{ someField: { eq: 'value' } }] };

const gqlResult = predicateToGraphQLFilter(group);

// stringifying to normalize whitespace and escape chars
expect(JSON.stringify(gqlResult)).toStrictEqual(
JSON.stringify(groupExpected)
);
});

test('Multiple field', () => {
const group: PredicatesGroup<any> = {
type: 'and',
predicates: [
{ field: 'someField', operator: 'eq', operand: 'value' },
{ field: 'someOtherField', operator: 'gt', operand: 'value2' },
],
};

const groupExpected = {
and: [
{ someField: { eq: 'value' } },
{ someOtherField: { gt: 'value2' } },
],
};

const gqlResult = predicateToGraphQLFilter(group);

expect(JSON.stringify(gqlResult)).toStrictEqual(
JSON.stringify(groupExpected)
);
});

test('Nested field', () => {
const group: PredicatesGroup<any> = {
type: 'and',
predicates: [
{ field: 'someField', operator: 'eq', operand: 'value' },
{
type: 'or',
predicates: [
{ field: 'someOtherField', operator: 'gt', operand: 'value2' },
{ field: 'orField', operator: 'contains', operand: 'str' },
],
},
],
};

const groupExpected = {
and: [
{ someField: { eq: 'value' } },
{
or: [
{ someOtherField: { gt: 'value2' } },
{ orField: { contains: 'str' } },
],
},
],
};

const gqlResult = predicateToGraphQLFilter(group);

expect(JSON.stringify(gqlResult)).toStrictEqual(
JSON.stringify(groupExpected)
);
});

test('Nested not', () => {
const group: PredicatesGroup<any> = {
type: 'not',
predicates: [
{
type: 'or',
predicates: [
{ field: 'someOtherField', operator: 'gt', operand: 'value2' },
{ field: 'orField', operator: 'contains', operand: 'str' },
],
},
],
};

const groupExpected = {
not: {
or: [
{ someOtherField: { gt: 'value2' } },
{ orField: { contains: 'str' } },
],
},
};

const gqlResult = predicateToGraphQLFilter(group);

expect(JSON.stringify(gqlResult)).toStrictEqual(
JSON.stringify(groupExpected)
);
});
});
2 changes: 1 addition & 1 deletion packages/datastore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@aws-amplify/api": "^3.2.7",
"@aws-amplify/core": "^3.7.0",
"@aws-amplify/pubsub": "^3.2.5",
"idb": "5.0.2",
"idb": "5.0.6",
"immer": "6.0.1",
"ulid": "2.3.0",
"uuid": "3.3.2",
Expand Down
Loading

0 comments on commit 8fa348b

Please sign in to comment.