Skip to content

Commit

Permalink
refact collection items reactivity
Browse files Browse the repository at this point in the history
  • Loading branch information
rudnik275 committed Jun 13, 2024
1 parent 58c2b55 commit bc9be01
Showing 1 changed file with 14 additions and 12 deletions.
26 changes: 14 additions & 12 deletions src/collection.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {computed, ComputedRef, ref, Ref, ShallowRef, shallowRef, triggerRef} from 'vue'
import {computed, ComputedRef, markRaw, Raw, Ref, ref} from 'vue'
import {TrackedInstance, useTrackedInstance} from './tracked-instance'

export interface CollectionItem<Item, Meta = undefined> {
export type CollectionItem<Item, Meta = undefined> = Raw<{
instance: TrackedInstance<Item>
meta: Meta
isRemoved: Ref<boolean>
isNew: Ref<boolean>
}
}>

export interface Collection<Item, Meta = undefined> {
items: ShallowRef<CollectionItem<Item, Meta>[]>
items: Ref<CollectionItem<Item, Meta>[]>
isDirty: ComputedRef<boolean>
add: (item: Item, afterIndex?: number) => CollectionItem<Item, Meta>
remove: (index: number, isHardRemove?: boolean) => void
Expand All @@ -20,42 +20,45 @@ export interface Collection<Item, Meta = undefined> {
export const useCollection = <Item = any, Meta = undefined>(
createItemMeta: (instance: TrackedInstance<Item>) => Meta = () => undefined as Meta
): Collection<Item, Meta> => {
const items = shallowRef<CollectionItem<Item, Meta>[]>([])
const items = ref<CollectionItem<Item, Meta>[]>([])

const isDirty = computed(() =>
items.value.some(({instance, isRemoved, isNew}) => instance.isDirty.value || isNew.value || isRemoved.value)
items.value.some((
{
instance,
isRemoved,
isNew
}
) => instance.isDirty.value || isNew.value || isRemoved.value)
)

const createItem = (item: Item, isNew: boolean): CollectionItem<Item, Meta> => {
const instance = useTrackedInstance<Item>(item)
return {
return markRaw({
isRemoved: ref(false),
isNew: ref(isNew),
instance,
meta: createItemMeta(instance)
}
})
}

const add = (item: Item, index: number = items.value.length) => {
const newItem = createItem(item, true)
items.value.splice(index, 0, newItem)
triggerRef(items)
return newItem
}

const remove = (index: number, isHardRemove = false) => {
const item = items.value[index]
if (item.isNew.value || isHardRemove) {
items.value.splice(index, 1)
triggerRef(items)
} else {
items.value[index].isRemoved.value = true
}
}

const loadData = (loadedItems: Item[]) => {
items.value = loadedItems.map(item => createItem(item, false))
triggerRef(items)
}

const reset = () => {
Expand All @@ -64,7 +67,6 @@ export const useCollection = <Item = any, Meta = undefined>(
item.isRemoved.value = false
item.instance.reset()
}
triggerRef(items)
}

return {
Expand Down

0 comments on commit bc9be01

Please sign in to comment.