From f725f2e12de0769473f0c26587fd3f27bd9f949f Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Sat, 21 Mar 2020 12:09:33 +0530 Subject: [PATCH 1/6] GraphQL Replication Plugin: Allow syncing revisions --- .../crawling-checkpoint.ts | 34 +++- src/plugins/replication-graphql/index.ts | 70 ++++--- test/helper/graphql-server.ts | 14 +- test/helper/schema-objects.ts | 5 + test/unit/replication-graphql.test.ts | 173 +++++++++++++++++- 5 files changed, 260 insertions(+), 36 deletions(-) diff --git a/src/plugins/replication-graphql/crawling-checkpoint.ts b/src/plugins/replication-graphql/crawling-checkpoint.ts index c39816d423a..c37c9202300 100644 --- a/src/plugins/replication-graphql/crawling-checkpoint.ts +++ b/src/plugins/replication-graphql/crawling-checkpoint.ts @@ -75,6 +75,7 @@ export async function getChangesSinceLastPushSequence( collection: RxCollection, endpointHash: string, batchSize = 10, + syncRevisions: boolean = false, ): Promise<{ results: { id: string, seq: number, changes: { rev: string }[] }[], last_seq: number }> { let lastPushSequence = await getLastPushSequence( collection, @@ -94,9 +95,11 @@ export async function getChangesSinceLastPushSequence( changes = await collection.pouch.changes({ since: lastPushSequence, limit: batchSize, - include_docs: true - }); - const useResults = changes.results.filter((change: any) => { + include_docs: true, + // style: 'all_docs' + } as any); + + const filteredResults = changes.results.filter((change: any) => { /** * filter out changes with revisions resulting from the pull-stream * so that they will not be upstreamed again @@ -115,6 +118,31 @@ export async function getChangesSinceLastPushSequence( return true; }); + let useResults = filteredResults; + + if (filteredResults.length > 0 && syncRevisions) { + const docsSearch = filteredResults.map((result: any) => { + return { + id: result.id, + rev: result.doc._rev + }; + }); + + const bulkGetDocs = await collection.pouch.bulkGet({ + docs: docsSearch, + revs: true, + latest: true + }); + + useResults = bulkGetDocs.results.map((result: any) => { + return { + id: result.id, + doc: result.docs[0]['ok'], + deleted: result.docs[0]['ok']._deleted + }; + }); + } + if (useResults.length === 0 && changes.results.length === batchSize) { // no pushable docs found but also not reached the end -> re-run lastPushSequence = changes.last_seq; diff --git a/src/plugins/replication-graphql/index.ts b/src/plugins/replication-graphql/index.ts index 31d78f1d192..28587778eed 100644 --- a/src/plugins/replication-graphql/index.ts +++ b/src/plugins/replication-graphql/index.ts @@ -71,7 +71,8 @@ export class RxGraphQLReplicationState { public deletedFlag: string, public live: boolean, public liveInterval: number, - public retryTime: number + public retryTime: number, + public syncRevisions: boolean ) { this.client = GraphQLClient({ url, @@ -195,6 +196,7 @@ export class RxGraphQLReplicationState { let result; try { result = await this.client.query(pullGraphQL.query, pullGraphQL.variables); + if (result.errors) { throw new Error(result.errors); } @@ -249,17 +251,21 @@ export class RxGraphQLReplicationState { const changes = await getChangesSinceLastPushSequence( this.collection, this.endpointHash, - this.push.batchSize + this.push.batchSize, + this.syncRevisions ); const changesWithDocs = changes.results.map((change: any) => { let doc = change['doc']; doc[this.deletedFlag] = !!change['deleted']; - delete doc._rev; delete doc._deleted; delete doc._attachments; + if (!this.syncRevisions) { + delete doc._rev; + } + doc = (this.push as any).modifier(doc); const seq = change.seq; @@ -282,7 +288,7 @@ export class RxGraphQLReplicationState { const pushObj = this.push.queryBuilder(changeWithDoc.doc); const result = await this.client.query(pushObj.query, pushObj.variables); if (result.errors) { - throw new Error(result.errors); + throw new Error(JSON.stringify(result.errors)); } else { this._subjects.send.next(changeWithDoc.doc); lastSuccessfullChange = changeWithDoc; @@ -330,35 +336,37 @@ export class RxGraphQLReplicationState { // console.log('handleDocumentFromRemote(' + toPouch._id + ') start'); toPouch._deleted = deletedValue; delete toPouch[this.deletedFlag]; - const primaryValue = toPouch._id; - const pouchState = docsWithRevisions[primaryValue]; - let newRevision = createRevisionForPulledDocument( - this.endpointHash, - toPouch - ); - if (pouchState) { - const newRevisionHeight = pouchState.revisions.start + 1; - const revisionId = newRevision; - newRevision = newRevisionHeight + '-' + newRevision; - toPouch._revisions = { - start: newRevisionHeight, - ids: pouchState.revisions.ids - }; - toPouch._revisions.ids.unshift(revisionId); - } else { - newRevision = '1-' + newRevision; + if (!this.syncRevisions) { + const primaryValue = toPouch._id; + + const pouchState = docsWithRevisions[primaryValue]; + let newRevision = createRevisionForPulledDocument( + this.endpointHash, + toPouch + ); + if (pouchState) { + const newRevisionHeight = pouchState.revisions.start + 1; + const revisionId = newRevision; + newRevision = newRevisionHeight + '-' + newRevision; + toPouch._revisions = { + start: newRevisionHeight, + ids: pouchState.revisions.ids + }; + toPouch._revisions.ids.unshift(revisionId); + } else { + newRevision = '1-' + newRevision; + } + + toPouch._rev = newRevision; } - toPouch._rev = newRevision; await this.collection.pouch.bulkDocs( [ toPouch - ], - { - new_edits: false - } - ); + ], { + new_edits: false + }); /** * because bulkDocs with new_edits: false @@ -367,6 +375,7 @@ export class RxGraphQLReplicationState { * so other instances get informed about it */ const originalDoc = flatClone(toPouch); + if (deletedValue) { originalDoc._deleted = deletedValue; } else { @@ -374,7 +383,6 @@ export class RxGraphQLReplicationState { } delete originalDoc[this.deletedFlag]; delete originalDoc._revisions; - originalDoc._rev = newRevision; const cE = changeEventfromPouchChange( originalDoc, @@ -404,7 +412,8 @@ export function syncGraphQL( live = false, liveInterval = 1000 * 10, // in ms retryTime = 1000 * 5, // in ms - autoStart = true // if this is false, the replication does nothing at start + autoStart = true, // if this is false, the replication does nothing at start + syncRevisions = false, }: any ) { const collection = this; @@ -429,7 +438,8 @@ export function syncGraphQL( deletedFlag, live, liveInterval, - retryTime + retryTime, + syncRevisions ); if (!autoStart) return replicationState; diff --git a/test/helper/graphql-server.ts b/test/helper/graphql-server.ts index d19426a9dd2..90da9f3f13b 100644 --- a/test/helper/graphql-server.ts +++ b/test/helper/graphql-server.ts @@ -81,12 +81,22 @@ export async function spawn( type Mutation { setHuman(human: HumanInput): Human } + input RevisionInput { + start: Int!, + ids: [String!]! + } input HumanInput { id: ID!, name: String!, age: Int!, updatedAt: Int!, - deleted: Boolean! + deleted: Boolean!, + _rev: String, + _revisions: RevisionInput, + } + type Revision { + start: Int!, + ids: [String!]! } type Human { id: ID!, @@ -94,6 +104,8 @@ export async function spawn( age: Int!, updatedAt: Int!, deleted: Boolean! + _rev: String, + _revisions: Revision, } type Subscription { humanChanged: Human diff --git a/test/helper/schema-objects.ts b/test/helper/schema-objects.ts index d7c46ed79b3..114c3d618ce 100644 --- a/test/helper/schema-objects.ts +++ b/test/helper/schema-objects.ts @@ -317,6 +317,11 @@ export interface HumanWithTimestampDocumentType { name: string; age: number; updatedAt: number; + _rev?: string; + _revisions?: { + start: number; + ids: [string]; + } } export function humanWithTimestamp(): HumanWithTimestampDocumentType { const now = new Date().getTime() / 1000; diff --git a/test/unit/replication-graphql.test.ts b/test/unit/replication-graphql.test.ts index 02b81738032..0bff32054ce 100644 --- a/test/unit/replication-graphql.test.ts +++ b/test/unit/replication-graphql.test.ts @@ -118,6 +118,25 @@ describe('replication-graphql.test.js', () => { return doc; }); }; + const getTestDataWithRevisions = (amount: any) => { + return new Array(amount).fill(0) + .map(() => schemaObjects.humanWithTimestamp()) + .map((doc: any) => { + doc['deleted'] = false; + const dataHash = util.hash(doc); + + const rev = `1-${dataHash}`; + const revisions = { + start: 1, + ids: [dataHash] + } + + doc._rev = rev; + doc._revisions = revisions; + + return doc; + }); + }; config.parallel('graphql-server.js', () => { it('spawn, reach and close a server', async () => { const server = await SpawnServer.spawn(); @@ -642,6 +661,38 @@ describe('replication-graphql.test.js', () => { assert.strictEqual(changes.last_seq, amount + 1); c.database.destroy(); }); + it('should fetch revisions if syncRevisions is set to true', async () => { + const amount = 5; + const c = await humansCollection.createHumanWithTimestamp(amount); + + await c.find().update({ + $inc: { + age: 1, + } + }) + + const changes = await getChangesSinceLastPushSequence( + c, + endpointHash, + 10, + true + ); + assert.strictEqual(changes.results.length, amount); + assert.ok(changes.results[0].doc.name); + + changes.results.forEach((result) => { + const doc = result.doc; + const revisions = doc._revisions; + + assert.ok(revisions); + assert.ok(revisions.ids); + assert.strictEqual(revisions.ids.length, 2) + + assert.strictEqual(doc._rev, `${revisions.start}-${revisions.ids[0]}`) + }) + + c.database.destroy(); + }) }); describe('.setLastPullDocument()', () => { it('should set the document', async () => { @@ -726,7 +777,7 @@ describe('replication-graphql.test.js', () => { server.close(); c.database.destroy(); }); - it('pulled docs should be marked with a special revision', async () => { + it('pulled docs should be marked with a special revision if syncRevisions is false', async () => { const [c, server] = await Promise.all([ humansCollection.createHumanWithTimestamp(0), SpawnServer.spawn(getTestData(batchSize)) @@ -737,7 +788,8 @@ describe('replication-graphql.test.js', () => { queryBuilder }, deletedFlag: 'deleted', - live: false + live: false, + syncRevisions: false, }); await replicationState.awaitInitialReplication(); @@ -761,6 +813,74 @@ describe('replication-graphql.test.js', () => { server.close(); c.database.destroy(); }); + it('should sync revisions from server if syncRevisions is true', async () => { + const remoteDocs = getTestDataWithRevisions(batchSize); + + const [c, server] = await Promise.all([ + humansCollection.createHumanWithTimestamp(0), + SpawnServer.spawn(remoteDocs) + ]); + + const queryBuilder = (doc: any) => { + if (!doc) { + doc = { + id: '', + updatedAt: 0 + }; + } + const query = `{ + feedForRxDBReplication(lastId: "${doc.id}", minUpdatedAt: ${doc.updatedAt}, limit: ${batchSize}) { + id + name + age + updatedAt + deleted + _rev + _revisions { + start + ids + } + } + }`; + const variables = {}; + return { + query, + variables + }; + }; + + const replicationState = c.syncGraphQL({ + url: server.url, + pull: { + queryBuilder + }, + deletedFlag: 'deleted', + live: false, + syncRevisions: true, + }); + await replicationState.awaitInitialReplication(); + + const docIds = remoteDocs.map((doc) => { + return { + id: doc.id, + rev: doc._rev + } + }); + + const localDocs = await c.pouch.bulkGet({ docs: docIds, revs: true }); + + assert.strictEqual(localDocs.results.length, remoteDocs.length); + + localDocs.results.forEach((doc) => { + const remoteDoc = remoteDocs.find((d) => d.id == doc.id); + assert.ok(remoteDoc); + assert.ok(remoteDoc._rev, doc.docs[0].ok._rev); + assert.deepEqual(doc.docs[0].ok._revisions, remoteDoc._revisions); + }) + server.close(); + c.database.destroy(); + }); + it('should pull all documents in multiple batches', async () => { const amount = batchSize * 4; const testData = getTestData(amount); @@ -1161,6 +1281,55 @@ describe('replication-graphql.test.js', () => { server.close(); db.destroy(); }); + it('should include revision fields if syncRevisions is set', async () => { + const [c, server] = await Promise.all([ + humansCollection.createHumanWithTimestamp(batchSize), + SpawnServer.spawn() + ]); + + const pushQueryBuilder = (doc: any) => { + assert.ok(doc._rev); + assert.ok(doc._revisions); + + delete doc._rev; + delete doc._revisions; + const query = ` + mutation CreateHuman($human: HumanInput) { + setHuman(human: $human) { + id, + updatedAt + } + } + `; + const variables = { + human: doc + }; + + return { + query, + variables + }; + }; + + const replicationState = c.syncGraphQL({ + url: server.url, + push: { + batchSize, + queryBuilder: pushQueryBuilder + }, + live: false, + deletedFlag: 'deleted', + syncRevisions: true, + }); + + await replicationState.awaitInitialReplication(); + + const docsOnServer = server.getDocuments(); + assert.strictEqual(docsOnServer.length, batchSize); + + server.close(); + c.database.destroy(); + }); }); config.parallel('push and pull', () => { it('should push and pull all docs; live: false', async () => { From dd5d110a3f1e4c46780d848916690b0aa7ada583 Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Sat, 21 Mar 2020 15:02:55 +0530 Subject: [PATCH 2/6] GraphQL replication plugin: Do not push replicated documents back to remote --- .../crawling-checkpoint.ts | 1 + src/plugins/replication-graphql/index.ts | 2 ++ src/rx-schema.ts | 4 +++ test/unit/replication-graphql.test.ts | 26 +++++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/plugins/replication-graphql/crawling-checkpoint.ts b/src/plugins/replication-graphql/crawling-checkpoint.ts index c37c9202300..874c1d93e86 100644 --- a/src/plugins/replication-graphql/crawling-checkpoint.ts +++ b/src/plugins/replication-graphql/crawling-checkpoint.ts @@ -109,6 +109,7 @@ export async function getChangesSinceLastPushSequence( change.doc._rev )) return false; + if (change.doc._replication_id === change.doc._rev) return false; /** * filter out internal docs * that are used for views or indexes in pouchdb diff --git a/src/plugins/replication-graphql/index.ts b/src/plugins/replication-graphql/index.ts index 28587778eed..138dfe18f77 100644 --- a/src/plugins/replication-graphql/index.ts +++ b/src/plugins/replication-graphql/index.ts @@ -359,6 +359,8 @@ export class RxGraphQLReplicationState { } toPouch._rev = newRevision; + } else { + toPouch._replication_id = toPouch._rev; } await this.collection.pouch.bulkDocs( diff --git a/src/rx-schema.ts b/src/rx-schema.ts index 00d43ec6c65..4d8176021ea 100644 --- a/src/rx-schema.ts +++ b/src/rx-schema.ts @@ -346,6 +346,10 @@ const fillWithDefaultSettings = function ( minLength: 1 }; + schemaObj.properties._replication_id = { + type: 'string', + }; + // add attachments schemaObj.properties._attachments = { type: 'object' diff --git a/test/unit/replication-graphql.test.ts b/test/unit/replication-graphql.test.ts index 0bff32054ce..324397def51 100644 --- a/test/unit/replication-graphql.test.ts +++ b/test/unit/replication-graphql.test.ts @@ -661,6 +661,32 @@ describe('replication-graphql.test.js', () => { assert.strictEqual(changes.last_seq, amount + 1); c.database.destroy(); }); + it('should have filtered out docs with replication_id set', async () => { + const amount = 5; + const c = await humansCollection.createHumanWithTimestamp(amount); + const toPouch: any = schemaObjects.humanWithTimestamp(); + toPouch._rev = `1-${util.hash(toPouch)}`; + toPouch._replication_id = toPouch._rev; + + await c.pouch.bulkDocs([c._handleToPouch(toPouch)], { + new_edits: false + }); + + const allDocs = await c.find().exec(); + assert.strictEqual(allDocs.length, amount + 1); + + const changes = await getChangesSinceLastPushSequence( + c, + endpointHash, + 10 + ); + + assert.strictEqual(changes.results.length, amount); + const shouldNotBeFound = changes.results.find((change: any) => change.id === toPouch.id); + assert.ok(!shouldNotBeFound); + assert.strictEqual(changes.last_seq, amount + 1); + c.database.destroy(); + }); it('should fetch revisions if syncRevisions is set to true', async () => { const amount = 5; const c = await humansCollection.createHumanWithTimestamp(amount); From 94feb02ead36b426076d9d8aed0663a792f69156 Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Sat, 21 Mar 2020 17:01:18 +0530 Subject: [PATCH 3/6] GraphQL Replication Plugin: Remove replication_id before calling push query --- src/plugins/replication-graphql/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/replication-graphql/index.ts b/src/plugins/replication-graphql/index.ts index 138dfe18f77..1923bcd02d7 100644 --- a/src/plugins/replication-graphql/index.ts +++ b/src/plugins/replication-graphql/index.ts @@ -261,6 +261,7 @@ export class RxGraphQLReplicationState { doc[this.deletedFlag] = !!change['deleted']; delete doc._deleted; delete doc._attachments; + delete doc._replication_id; if (!this.syncRevisions) { delete doc._rev; From d48cefb4f867090fbcb2a5f8297e34820d6d0774 Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Sun, 22 Mar 2020 12:37:39 +0530 Subject: [PATCH 4/6] GraphQL Replication Plugin: Add syncRevisions to SyncOptionsGraphQL type --- src/types/plugins/replication-graphql.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/plugins/replication-graphql.ts b/src/types/plugins/replication-graphql.ts index 9ea1f7c349a..9f6dacc2ee9 100644 --- a/src/types/plugins/replication-graphql.ts +++ b/src/types/plugins/replication-graphql.ts @@ -24,4 +24,5 @@ export type SyncOptionsGraphQL = { liveInterval?: number; // time in ms retryTime?: number; // time in ms autoStart?: boolean; // if this is false, the replication does nothing at start + syncRevisions?: boolean; }; From a8c48278d0b58a713733346b675637c101eaeb8f Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Thu, 26 Mar 2020 21:40:34 +0530 Subject: [PATCH 5/6] Fix failing test due to adding _replication_id to schema --- src/plugins/in-memory.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/in-memory.ts b/src/plugins/in-memory.ts index 659a73e7ccb..6e4830900a0 100644 --- a/src/plugins/in-memory.ts +++ b/src/plugins/in-memory.ts @@ -229,6 +229,7 @@ function toCleanSchema(rxSchema: RxSchema): RxSchema { delete newSchemaJson.properties._id; delete newSchemaJson.properties._rev; delete newSchemaJson.properties._attachments; + delete newSchemaJson.properties._replication_id; const removeEncryption = (schema: any, complete: any) => { delete schema.encrypted; From 22fc7779629d46cc01432ff1ec147d076b93ff44 Mon Sep 17 00:00:00 2001 From: Gautam BT Date: Tue, 7 Apr 2020 15:29:06 +0530 Subject: [PATCH 6/6] GraphQL Replication: Rename _replication_id to last_pulled_rev; make it configurable --- src/plugins/in-memory.ts | 1 - src/plugins/replication-graphql/crawling-checkpoint.ts | 3 ++- src/plugins/replication-graphql/index.ts | 8 ++++++-- src/rx-schema.ts | 4 ---- test/helper/schema-objects.ts | 3 ++- test/helper/schemas.ts | 6 ++++++ test/unit/replication-graphql.test.ts | 10 ++++++++-- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/plugins/in-memory.ts b/src/plugins/in-memory.ts index 6e4830900a0..659a73e7ccb 100644 --- a/src/plugins/in-memory.ts +++ b/src/plugins/in-memory.ts @@ -229,7 +229,6 @@ function toCleanSchema(rxSchema: RxSchema): RxSchema { delete newSchemaJson.properties._id; delete newSchemaJson.properties._rev; delete newSchemaJson.properties._attachments; - delete newSchemaJson.properties._replication_id; const removeEncryption = (schema: any, complete: any) => { delete schema.encrypted; diff --git a/src/plugins/replication-graphql/crawling-checkpoint.ts b/src/plugins/replication-graphql/crawling-checkpoint.ts index 874c1d93e86..3655ee82627 100644 --- a/src/plugins/replication-graphql/crawling-checkpoint.ts +++ b/src/plugins/replication-graphql/crawling-checkpoint.ts @@ -74,6 +74,7 @@ export async function setLastPushSequence( export async function getChangesSinceLastPushSequence( collection: RxCollection, endpointHash: string, + lastPulledRevField: string, batchSize = 10, syncRevisions: boolean = false, ): Promise<{ results: { id: string, seq: number, changes: { rev: string }[] }[], last_seq: number }> { @@ -109,7 +110,7 @@ export async function getChangesSinceLastPushSequence( change.doc._rev )) return false; - if (change.doc._replication_id === change.doc._rev) return false; + if (change.doc[lastPulledRevField] === change.doc._rev) return false; /** * filter out internal docs * that are used for views or indexes in pouchdb diff --git a/src/plugins/replication-graphql/index.ts b/src/plugins/replication-graphql/index.ts index 1923bcd02d7..0006ac319a5 100644 --- a/src/plugins/replication-graphql/index.ts +++ b/src/plugins/replication-graphql/index.ts @@ -69,6 +69,7 @@ export class RxGraphQLReplicationState { public pull: GraphQLSyncPullOptions, public push: GraphQLSyncPushOptions, public deletedFlag: string, + public lastPulledRevField: string, public live: boolean, public liveInterval: number, public retryTime: number, @@ -251,6 +252,7 @@ export class RxGraphQLReplicationState { const changes = await getChangesSinceLastPushSequence( this.collection, this.endpointHash, + this.lastPulledRevField, this.push.batchSize, this.syncRevisions ); @@ -261,7 +263,7 @@ export class RxGraphQLReplicationState { doc[this.deletedFlag] = !!change['deleted']; delete doc._deleted; delete doc._attachments; - delete doc._replication_id; + delete doc[this.lastPulledRevField]; if (!this.syncRevisions) { delete doc._rev; @@ -361,7 +363,7 @@ export class RxGraphQLReplicationState { toPouch._rev = newRevision; } else { - toPouch._replication_id = toPouch._rev; + toPouch[this.lastPulledRevField] = toPouch._rev; } await this.collection.pouch.bulkDocs( @@ -412,6 +414,7 @@ export function syncGraphQL( pull, push, deletedFlag, + lastPulledRevField = 'last_pulled_rev', live = false, liveInterval = 1000 * 10, // in ms retryTime = 1000 * 5, // in ms @@ -439,6 +442,7 @@ export function syncGraphQL( pull, push, deletedFlag, + lastPulledRevField, live, liveInterval, retryTime, diff --git a/src/rx-schema.ts b/src/rx-schema.ts index 4d8176021ea..00d43ec6c65 100644 --- a/src/rx-schema.ts +++ b/src/rx-schema.ts @@ -346,10 +346,6 @@ const fillWithDefaultSettings = function ( minLength: 1 }; - schemaObj.properties._replication_id = { - type: 'string', - }; - // add attachments schemaObj.properties._attachments = { type: 'object' diff --git a/test/helper/schema-objects.ts b/test/helper/schema-objects.ts index 114c3d618ce..3ba156515fd 100644 --- a/test/helper/schema-objects.ts +++ b/test/helper/schema-objects.ts @@ -321,7 +321,8 @@ export interface HumanWithTimestampDocumentType { _revisions?: { start: number; ids: [string]; - } + }, + last_pulled_rev?: string; } export function humanWithTimestamp(): HumanWithTimestampDocumentType { const now = new Date().getTime() / 1000; diff --git a/test/helper/schemas.ts b/test/helper/schemas.ts index 1408c438e92..17258e45d65 100644 --- a/test/helper/schemas.ts +++ b/test/helper/schemas.ts @@ -844,6 +844,9 @@ export const humanWithTimestamp: RxJsonSchema = }, updatedAt: { type: 'number' + }, + last_pulled_rev: { + type: 'string' } }, required: ['id', 'name', 'age', 'updatedAt'] @@ -872,6 +875,9 @@ export const humanWithTimestampAllIndex: RxJsonSchema { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10 ); assert.strictEqual(changes.results.length, amount); @@ -590,6 +591,7 @@ describe('replication-graphql.test.js', () => { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10 ); assert.strictEqual(changes.results.length, amount); @@ -614,6 +616,7 @@ describe('replication-graphql.test.js', () => { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10 ); assert.strictEqual(changes.results.length, amount); @@ -652,6 +655,7 @@ describe('replication-graphql.test.js', () => { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10 ); @@ -661,12 +665,12 @@ describe('replication-graphql.test.js', () => { assert.strictEqual(changes.last_seq, amount + 1); c.database.destroy(); }); - it('should have filtered out docs with replication_id set', async () => { + it('should have filtered out docs with last_pulled_rev set', async () => { const amount = 5; const c = await humansCollection.createHumanWithTimestamp(amount); const toPouch: any = schemaObjects.humanWithTimestamp(); toPouch._rev = `1-${util.hash(toPouch)}`; - toPouch._replication_id = toPouch._rev; + toPouch.last_pulled_rev = toPouch._rev; await c.pouch.bulkDocs([c._handleToPouch(toPouch)], { new_edits: false @@ -678,6 +682,7 @@ describe('replication-graphql.test.js', () => { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10 ); @@ -700,6 +705,7 @@ describe('replication-graphql.test.js', () => { const changes = await getChangesSinceLastPushSequence( c, endpointHash, + 'last_pulled_rev', 10, true );