feat: implement entity patch
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import { defineStore } from 'pinia'
|
||||
import { entityService } from '../services'
|
||||
import { EntityObject, MessageObject } from '../models'
|
||||
import type {
|
||||
EntityStreamRequest,
|
||||
EntityListStreamRequest,
|
||||
EntityTransmitRequest,
|
||||
EntityTransmitResponse,
|
||||
} from '../types/entity'
|
||||
@@ -216,6 +216,15 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty entity object
|
||||
*
|
||||
* @returns New entity object instance
|
||||
*/
|
||||
function fresh(): EntityObject {
|
||||
return new EntityObject()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new entity with given collection identifier and properties
|
||||
*
|
||||
@@ -282,19 +291,19 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
|
||||
*
|
||||
* Removes successfully deleted entities from the local store.
|
||||
*
|
||||
* @param sources - entity identifiers to delete
|
||||
* @param targets - entity identifiers to delete
|
||||
*
|
||||
* @returns Promise with deletion results keyed by source identifier
|
||||
* @returns Promise with deletion results keyed by target identifier
|
||||
*/
|
||||
async function remove(sources: EntityIdentifier[]): Promise<{successes: EntityIdentifier[], failures: EntityIdentifier[]}> {
|
||||
async function remove(targets: EntityIdentifier[]): Promise<{successes: EntityIdentifier[], failures: EntityIdentifier[]}> {
|
||||
transceiving.value = true
|
||||
try {
|
||||
const response = await entityService.delete({ sources })
|
||||
const response = await entityService.delete({ targets })
|
||||
const successes: EntityIdentifier[] = []
|
||||
const failures: EntityIdentifier[] = []
|
||||
|
||||
Object.entries(response).forEach(([sourceIdentifier, result]) => {
|
||||
const originalIdentifier = sourceIdentifier as EntityIdentifier
|
||||
Object.entries(response).forEach(([targetIdentifier, result]) => {
|
||||
const originalIdentifier = targetIdentifier as EntityIdentifier
|
||||
if (!result.disposition || result.disposition === 'error') {
|
||||
console.warn(`[Mail Manager][Store] - Entity move on "${originalIdentifier}" returned an error: ${result.error})`)
|
||||
failures.push(originalIdentifier)
|
||||
@@ -335,6 +344,57 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch existing entities with new properties
|
||||
*/
|
||||
async function patch(properties: MessageInterface | MessageObject, targets: EntityIdentifier[]) {
|
||||
transceiving.value = true
|
||||
try {
|
||||
if (properties instanceof MessageObject) {
|
||||
properties = properties.toJson()
|
||||
}
|
||||
const response = await entityService.patch({ properties, targets })
|
||||
const successes: EntityIdentifier[] = []
|
||||
const failures: EntityIdentifier[] = []
|
||||
|
||||
Object.entries(response).forEach(([targetIdentifier, result]) => {
|
||||
const originalIdentifier = targetIdentifier as EntityIdentifier
|
||||
if (!result.disposition || result.disposition === 'error') {
|
||||
console.warn(`[Mail Manager][Store] - Entity patch on "${originalIdentifier}" returned an error: ${result.error})`)
|
||||
failures.push(originalIdentifier)
|
||||
return
|
||||
}
|
||||
|
||||
const cachedEntity = _entities.value[originalIdentifier]
|
||||
if (!cachedEntity) {
|
||||
return
|
||||
}
|
||||
|
||||
if (result.disposition === 'patched') {
|
||||
const cachedEntityJson = cachedEntity.toJson()
|
||||
const mutatedEntity = cachedEntity.clone().fromJson({
|
||||
...cachedEntityJson,
|
||||
properties: {
|
||||
...cachedEntityJson.properties,
|
||||
...properties,
|
||||
},
|
||||
})
|
||||
_entities.value[originalIdentifier] = mutatedEntity
|
||||
}
|
||||
|
||||
successes.push(originalIdentifier)
|
||||
})
|
||||
|
||||
console.debug('[Mail Manager][Store] - Successfully patched', successes.length, 'entities')
|
||||
return { successes, failures }
|
||||
} catch (error: any) {
|
||||
console.error('[Mail Manager][Store] - Failed to patch entities:', error)
|
||||
throw error
|
||||
} finally {
|
||||
transceiving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move entities to another collection.
|
||||
*
|
||||
@@ -414,36 +474,6 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream entities progressively, merging each entity into the store as it arrives.
|
||||
*
|
||||
* Unlike list(), which waits for the full response before updating the store,
|
||||
* stream() updates reactive state entity-by-entity so UI renders incrementally.
|
||||
*
|
||||
* @param sources - optional source selector
|
||||
* @param filter - optional list filter
|
||||
* @param sort - optional list sort
|
||||
* @param range - optional list range
|
||||
*
|
||||
* @returns Promise resolving to { total } when the stream completes
|
||||
*/
|
||||
async function stream(sources?: CollectionIdentifier[], filter?: ListFilter, sort?: ListSort, range?: ListRange): Promise<{ total: number }> {
|
||||
transceiving.value = true
|
||||
try {
|
||||
const request: EntityStreamRequest = { sources, filter, sort, range }
|
||||
const result = await entityService.stream(request, (entity: EntityObject) => {
|
||||
_entities.value[entity.identifier] = entity
|
||||
})
|
||||
console.debug('[Mail Manager][Store] - Successfully streamed', result.total, 'entities')
|
||||
return result
|
||||
} catch (error: any) {
|
||||
console.error('[Mail Manager][Store] - Failed to stream entities:', error)
|
||||
throw error
|
||||
} finally {
|
||||
transceiving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Return public API
|
||||
return {
|
||||
// State (readonly)
|
||||
@@ -457,12 +487,13 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
|
||||
list,
|
||||
fetch,
|
||||
extant,
|
||||
fresh,
|
||||
create,
|
||||
update,
|
||||
patch,
|
||||
delete: remove,
|
||||
delta,
|
||||
move,
|
||||
transmit,
|
||||
stream,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user