Skip to content
This repository was archived by the owner on Jul 6, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { DecryptedItemInterface } from '../../../Abstract/Item/Interfaces/Decryp
import { CollectionInterface } from '../CollectionInterface'
import { DeletedItemInterface } from '../../../Abstract/Item'
import { Collection } from '../Collection'
import { AnyItemInterface } from '../../../Abstract/Item/Interfaces/UnionTypes'

type DisplaySortBy = Partial<
Record<
Expand All @@ -25,12 +26,15 @@ type DisplaySortBy = Partial<
>
>

type AnyItem = DecryptedItemInterface | EncryptedItemInterface | DeletedItemInterface

type UuidToSortedPositionMap = Record<Uuid, number>

export class ItemCollection
extends Collection<AnyItem, DecryptedItemInterface, EncryptedItemInterface, DeletedItemInterface>
extends Collection<
AnyItemInterface,
DecryptedItemInterface,
EncryptedItemInterface,
DeletedItemInterface
>
implements SNIndex, CollectionInterface
{
private displaySortBy: DisplaySortBy = {}
Expand All @@ -51,15 +55,15 @@ export class ItemCollection
*/
private sortedMap: Partial<Record<ContentType, SortableItem[]>> = {}

public override set(elements: AnyItem | AnyItem[]): void {
public override set(elements: AnyItemInterface | AnyItemInterface[]): void {
elements = uniqueArrayByKey(Array.isArray(elements) ? elements : [elements], 'uuid')

super.set(elements)

this.filterSortElements(elements)
}

public override discard(elements: AnyItem | AnyItem[]): void {
public override discard(elements: AnyItemInterface | AnyItemInterface[]): void {
super.discard(elements)

elements = Array.isArray(elements) ? elements : [elements]
Expand Down Expand Up @@ -177,7 +181,7 @@ export class ItemCollection
return elements.slice() as I[]
}

private filterSortElements(elements: AnyItem[]) {
private filterSortElements(elements: AnyItemInterface[]) {
if (Object.keys(this.displaySortBy).length === 0) {
return
}
Expand Down
26 changes: 25 additions & 1 deletion packages/models/src/Domain/Runtime/Deltas/Conflict.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('conflict delta', () => {
expect(mocked).toBeCalledTimes(0)
})

it('if either payload is errored, should keep base duplicate apply', () => {
it('if apply payload is errored but base payload is not, should duplicate base and keep apply', () => {
const basePayload = createDecryptedItemsKey('123', 'secret')

const baseCollection = createBaseCollection(basePayload)
Expand All @@ -73,6 +73,30 @@ describe('conflict delta', () => {

const delta = new ConflictDelta(baseCollection, basePayload, applyPayload, historyMap)

expect(delta.getConflictStrategy()).toBe(ConflictStrategy.DuplicateBaseKeepApply)
})

it('if base payload is errored but apply is not, should keep base duplicate apply', () => {
const basePayload = createErroredItemsKey('123', 2)

const baseCollection = createBaseCollection(basePayload)

const applyPayload = createDecryptedItemsKey('123', 'secret')

const delta = new ConflictDelta(baseCollection, basePayload, applyPayload, historyMap)

expect(delta.getConflictStrategy()).toBe(ConflictStrategy.KeepBaseDuplicateApply)
})

it('if base and apply are errored, should keep apply', () => {
const basePayload = createErroredItemsKey('123', 2)

const baseCollection = createBaseCollection(basePayload)

const applyPayload = createErroredItemsKey('123', 3)

const delta = new ConflictDelta(baseCollection, basePayload, applyPayload, historyMap)

expect(delta.getConflictStrategy()).toBe(ConflictStrategy.KeepApply)
})
})
13 changes: 11 additions & 2 deletions packages/models/src/Domain/Runtime/Deltas/Conflict.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@ export class ConflictDelta {
}

getConflictStrategy(): ConflictStrategy {
if (isErrorDecryptingPayload(this.basePayload) || isErrorDecryptingPayload(this.applyPayload)) {
return ConflictStrategy.KeepBaseDuplicateApply
const isBaseErrored = isErrorDecryptingPayload(this.basePayload)
const isApplyErrored = isErrorDecryptingPayload(this.applyPayload)
if (isBaseErrored || isApplyErrored) {
if (isBaseErrored && !isApplyErrored) {
return ConflictStrategy.KeepBaseDuplicateApply
} else if (!isBaseErrored && isApplyErrored) {
return ConflictStrategy.DuplicateBaseKeepApply
} else if (isBaseErrored && isApplyErrored) {
return ConflictStrategy.KeepApply
}
} else if (isDecryptedPayload(this.basePayload)) {
/**
* Ensure no conflict has already been created with the incoming content.
Expand Down Expand Up @@ -173,6 +181,7 @@ export class ConflictDelta {
isConflict: true,
source: this.applyPayload.source,
})

return [leftPayload].concat(rightPayloads)
}

Expand Down
1 change: 0 additions & 1 deletion packages/models/src/Domain/Syncable/Tag/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './Tag'
export * from './TagMutator'
export * from '../../Runtime/Collection/Item/TagNotesIndex'
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ export function PayloadsByAlternatingUuid<

const deletedSelf = new DeletedPayload(
{
/**
* Do not set as dirty; this item is non-syncable
* and should be immediately discarded
*/
created_at: payload.created_at,
updated_at: payload.updated_at,
created_at_timestamp: payload.created_at_timestamp,
updated_at_timestamp: payload.updated_at_timestamp,
dirtiedDate: undefined,
/**
* Do not set as dirty; this item is non-syncable
* and should be immediately discarded
*/
dirty: false,
content: undefined,
uuid: payload.uuid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function PayloadsByDuplicating<C extends ItemContent = ItemContent>(dto:

const results: SyncResolvedPayload[] = []

const baseOverride = {
const override = {
uuid: UuidGenerator.GenerateUuid(),
dirty: true,
dirtiedDate: new Date(),
Expand All @@ -45,14 +45,14 @@ export function PayloadsByDuplicating<C extends ItemContent = ItemContent>(dto:
}

copy = payload.copyAsSyncResolved({
...baseOverride,
...override,
content: contentOverride,
deleted: false,
})
} else {
copy = payload.copyAsSyncResolved(
{
...baseOverride,
...override,
},
source || payload.source,
)
Expand Down
1 change: 1 addition & 0 deletions packages/models/src/Domain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './Runtime/Collection/CollectionSort'
export * from './Runtime/Collection/Payload/ImmutablePayloadCollection'
export * from './Runtime/Collection/Item/ItemCollection'
export * from './Runtime/Collection/Item/NotesCollection'
export * from './Runtime/Collection/Item/TagNotesIndex'
export * from './Runtime/Collection/Payload/PayloadCollection'
export * from './Runtime/Deltas'
export * from './Runtime/History'
Expand Down