Skip to content

Commit

Permalink
fix(sync-utils): fix removing relationships on single sync
Browse files Browse the repository at this point in the history
  • Loading branch information
good-idea committed May 10, 2020
1 parent aad6ec6 commit 38ef78f
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 28 deletions.
1 change: 1 addition & 0 deletions packages/sync-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@sanity/client": "^1.149.7",
"axios": "^0.19.2",
"debug": "^4.1.1",
"deepmerge": "^4.2.2",
"es6-promise": "^4.2.8",
"graphql-tag": "^2.10.3",
"isomorphic-fetch": "^2.2.1",
Expand Down
5 changes: 3 additions & 2 deletions packages/sync-utils/src/sanity/archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export const createArchiveSanityDocument = (client: SanityClient) => async (
): Promise<SanityShopifyDocument> => {
const relationshipsKey =
doc.sourceData.__typename === 'Collection' ? 'products' : 'collections'
const removeRelationships = async (relatedDoc: SanityShopifyDocument) => {
const removeRelationships = async (relatedDoc?: SanityShopifyDocument) => {
if (!relatedDoc) return
const type =
relatedDoc.sourceData.__typename === 'Collection'
? 'products'
Expand All @@ -18,7 +19,7 @@ export const createArchiveSanityDocument = (client: SanityClient) => async (

const relationshipsToRemove = [`${type}[_key=="${related._key}"]`]

const result = await client
await client
.patch(relatedDoc._id)
// @ts-ignore
.unset(relationshipsToRemove)
Expand Down
12 changes: 8 additions & 4 deletions packages/sync-utils/src/sanity/syncRelationships.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const createRemoveRelationships = (
from[keys].find((reference) => reference._ref === itemToRemove._id)
)
.map((reference) => `${type}[_key=="${reference._key}"]`)
await client
const r = await client
.patch(from._id)
// @ts-ignore
.unset(relationshipsToRemove)
Expand Down Expand Up @@ -60,7 +60,7 @@ export const createSyncRelationships = (
? toDocs.reduce<boolean>(
(prev: boolean, current: SanityShopifyDocument) => {
if (prev === false) return false
return existingLinks.some((l) => l._id === current._id)
return existingLinks.some((l) => l && l._id === current._id)
},
true
)
Expand Down Expand Up @@ -89,8 +89,12 @@ export const createSyncRelationships = (

const pairs: SanityPair[] = await rQueue.addAll(
toDocs.map((toDoc) => async () => {
const relationships =
toDoc._type === 'shopifyCollection' ? toDoc.products : toDoc.collections
const relationships: SanityShopifyDocument[] =
toDoc._type === 'shopifyCollection'
? toDoc.products
: toDoc._type === 'shopifyProduct'
? toDoc.collections
: []
const pair = {
from: from,
to: toDoc,
Expand Down
56 changes: 48 additions & 8 deletions packages/sync-utils/src/sanity/syncSanityDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,45 @@ import {
SyncOperation,
SanityShopifyDocument,
} from '@sane-shopify/types'
import { isMatch } from 'lodash'
import { prepareDocument, sleep } from './utils'
import deepMerge from 'deepmerge'
import { omit } from 'lodash'
import { prepareDocument, sleep, isMatch, uniqueObjects } from './utils'
import { SanityCache } from './sanityUtils'

const mergeExistingFields = (
docInfo: any,
existingDoc: SanityShopifyDocument
) => {
): SanityShopifyDocument => {
// @ts-ignore
const merged = deepMerge(docInfo, existingDoc)
if (existingDoc._type !== 'shopifyProduct') {
return {
...merged,
sourceData: {
...docInfo.sourceData,
products: {
...docInfo.sourceData.products,
edges: uniqueObjects(docInfo.sourceData.products.edges),
},
},
}
}
const variants = docInfo.variants || []
const options = docInfo.options || []
return {
...docInfo,
...merged,
sourceData: {
...docInfo.sourceData,
collections: {
...docInfo.sourceData.collections,
edges: uniqueObjects(docInfo.sourceData.collections.edges),
},
images: {
...docInfo.sourceData.images,
edges: uniqueObjects(docInfo.sourceData.images.edges),
},
},

options: options.map((updatedOption) => {
const existingOption = existingDoc.options
? existingDoc.options.find((o) => o._key === updatedOption._key) || {}
Expand Down Expand Up @@ -63,13 +90,14 @@ export const createSyncSanityDocument = (
if (cached) return cached

const doc = await client.fetch<SanityShopifyDocument>(
`*[shopifyId == $shopifyId]{
`
*[shopifyId == $shopifyId]{
products[]->,
collections[]->,
"collectionKeys": collections[]{
...
},
"productKeys": products[] {
"productKeys": products[]{
...
},
...
Expand All @@ -89,7 +117,12 @@ export const createSyncSanityDocument = (
const existingDoc = await getSanityDocByShopifyId(item.id)

/* If the document exists and is up to date, skip */
if (existingDoc && isMatch(existingDoc, docInfo)) {
if (
existingDoc &&
isMatch(docInfo, existingDoc, {
ignoreKeys: ['products', 'collections', 'sourceData.__cursor'],
})
) {
return {
type: 'skip' as 'skip',
sanityDocument: existingDoc,
Expand Down Expand Up @@ -120,9 +153,15 @@ export const createSyncSanityDocument = (

/* Otherwise, update the existing doc */

const patchData = omit(mergeExistingFields(docInfo, existingDoc), [
'products',
'collections',
'productKeys',
'collectionKeys',
])
const updatedDoc = await client
.patch<SanityShopifyDocument>(existingDoc._id)
.set(mergeExistingFields(docInfo, existingDoc))
.set(patchData)
.commit()

const refetchedDoc = await getSanityDocByShopifyId(updatedDoc.shopifyId)
Expand All @@ -131,6 +170,7 @@ export const createSyncSanityDocument = (
`Could not fetch updated document with shopifyId ${updatedDoc.shopifyId}`
)
}

cache.set(refetchedDoc)

return {
Expand Down
31 changes: 30 additions & 1 deletion packages/sync-utils/src/sanity/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { unwindEdges, Edge } from '@good-idea/unwind-edges'
import { Collection, Product } from '@sane-shopify/types'
import { isMatch as lodashIsMatch, omit } from 'lodash'
import { slugify } from '../utils'

export const sleep = (ms: number) =>
Expand Down Expand Up @@ -154,7 +155,10 @@ export const prepareDocument = <T extends Product | Collection>(item: T) => {
title: item.title,
shopifyId: item.id,
handle: item.handle,
sourceData,
sourceData: {
...sourceData,
__cursor: sourceData.id,
},
}
switch (item.__typename) {
case 'Product':
Expand All @@ -169,3 +173,28 @@ export const prepareDocument = <T extends Product | Collection>(item: T) => {
return docInfo
}
}

interface IsMatchConfig {
ignoreKeys: string[]
}

const defaultIgnoreKeys = ['_createdAt', '_updatedAt', '_id', '_rev']

/**
* Compares if a prepared document and original document are a match.
* We ignore keys like _createdAt and _updatedAt because those aren't included
* in the prepared document.
*
*/
export const isMatch = (a: any, b: any, config?: IsMatchConfig): boolean => {
const additionalKeys = config?.ignoreKeys ?? []
const ignoreKeys = [...defaultIgnoreKeys, ...additionalKeys]
return lodashIsMatch(omit(a, ignoreKeys), omit(b, ignoreKeys))
}

export const uniqueObjects = <T extends object>(arr: T[]): T[] =>
arr.reduce<T[]>(
(acc, item) =>
acc.some((i) => lodashIsMatch(i, item)) ? acc : [...acc, item],
[]
)
28 changes: 21 additions & 7 deletions packages/sync-utils/src/syncingClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
SyncOperationResult,
SaneShopifyConfig,
RelatedPair,
SanityShopifyDocument,
SanityShopifyProductDocument,
SanityShopifyCollectionDocument,
ShopifySecrets,
LinkOperation,
SubscriptionCallbacks,
Expand Down Expand Up @@ -164,22 +167,33 @@ export const syncUtils = (
[]
)
.map(({ sanityDocument }) => sanityDocument)
const existingRelationships =
sanityDocument.products || sanityDocument.collections || []
const existingRelationships: SanityShopifyDocument[] =
sanityDocument._type == 'shopifyCollection'
? sanityDocument.products
: sanityDocument._type === 'shopifyProduct'
? sanityDocument.collections
: []
// sanityDocument.products || sanityDocument.collections || []
const relationshipsToRemove = existingRelationships.filter(
(r) => !Boolean(related.find((ri) => ri.id === r.shopifyId))
(r) => r && !Boolean(related.find((ri) => ri.id === r.shopifyId))
)

await removeRelationships(sanityDocument, relationshipsToRemove)

const linkOperation = await syncRelationships(sanityDocument, relatedDocs)

const reverseRelationshipsQueue = new PQueue({ concurrency: 1 })

await reverseRelationshipsQueue.addAll(
relatedDocs.map((doc) => async () => {
const reverseRelationships = [
...relatedDocs.map((doc) => async () => {
await syncRelationships(doc, [sanityDocument])
})
)
}),
...relationshipsToRemove.map((doc) => async () => {
const docWithRelationsihps = await documentByShopifyId(doc.shopifyId)
await removeRelationships(docWithRelationsihps, [sanityDocument])
}),
]
await reverseRelationshipsQueue.addAll(reverseRelationships)

return linkOperation
}
Expand Down
7 changes: 1 addition & 6 deletions packages/sync-utils/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { Paginated, unwindEdges } from '@good-idea/unwind-edges'
import {
Collection,
Product,
SanityClient,
SanityDocumentConfig,
} from '@sane-shopify/types'
import { Collection, Product, SanityClient } from '@sane-shopify/types'

export const slugify = (text: string) =>
text
Expand Down

0 comments on commit 38ef78f

Please sign in to comment.