chore: bunch of improvements
All checks were successful
JS Unit Tests / test (pull_request) Successful in 33s
Build Test / test (pull_request) Successful in 36s
PHP Unit Tests / test (pull_request) Successful in 1m12s

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-04-23 22:00:50 -04:00
parent b617234b40
commit 3362afb7ec
28 changed files with 1717 additions and 1297 deletions

View File

@@ -7,6 +7,7 @@ import { defineStore } from 'pinia'
import { entityService } from '../services'
import { EntityObject } from '../models'
import type {
EntityDeleteResponse,
EntityMoveResponse,
EntityStreamRequest,
EntityTransmitRequest,
@@ -62,6 +63,35 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
return _entities.value[key] || null
}
/**
* Resolve an entity from cache by full entity identifier.
*/
function entityByIdentifier(identifier: EntityIdentifier, retrieve: boolean = false): EntityObject | null {
if (retrieve === true && !_entities.value[identifier]) {
console.debug(`[Mail Manager][Store] - Force fetching entity "${identifier}"`)
const { provider, service, collection, identifier: id } = parseEntityIdentifier(identifier)
fetch(provider, service, collection, [id])
}
return _entities.value[identifier] || null
}
/**
* Resolve multiple entities from cache by full entity identifiers.
*/
function entitiesByIdentifiers(identifiers: EntityIdentifier[], retrieve: boolean = false): Record<EntityIdentifier, EntityObject> {
const resolved: Record<EntityIdentifier, EntityObject> = {} as Record<EntityIdentifier, EntityObject>
Array.from(new Set(identifiers)).forEach(identifier => {
const entity = entityByIdentifier(identifier, retrieve)
if (entity) {
resolved[identifier] = entity
}
})
return resolved
}
/**
* Get all entities for a specific collection
*
@@ -205,6 +235,58 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
}
}
/**
* Retrieve delta changes for entities
*
* @param sources - source selector for delta check
*
* @returns Promise with delta changes (additions, modifications, deletions)
*
* Note: Delta returns only identifiers, not full entities.
* Caller should fetch full entities for additions/modifications separately.
*/
async function delta(sources: SourceSelector) {
transceiving.value = true
try {
const response = await entityService.delta({ sources })
// Process delta and update store
Object.entries(response).forEach(([provider, providerData]) => {
// Skip if no changes for provider
if (providerData === false) return
Object.entries(providerData).forEach(([service, serviceData]) => {
// Skip if no changes for service
if (serviceData === false) return
Object.entries(serviceData).forEach(([collection, collectionData]) => {
// Skip if no changes for collection
if (collectionData === false) return
// Process deletions (remove from store)
if (collectionData.deletions && collectionData.deletions.length > 0) {
collectionData.deletions.forEach((identifier) => {
const key = identifierKey(provider, service, collection, identifier)
delete _entities.value[key]
})
}
// Note: additions and modifications contain only identifiers
// The caller should fetch full entities using the fetch() method
})
})
})
console.debug('[Mail Manager][Store] - Successfully processed delta changes')
return response
} catch (error: any) {
console.error('[Mail Manager][Store] - Failed to process delta:', error)
throw error
} finally {
transceiving.value = false
}
}
/**
* Create a new entity with given provider, service, collection, and data
*
@@ -265,80 +347,31 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
}
/**
* Delete an entity by provider, service, collection, and identifier
*
* @param provider - provider identifier for the entity to delete
* @param service - service identifier for the entity to delete
* @param collection - collection identifier for the entity to delete
* @param identifier - entity identifier for the entity to delete
*
* @returns Promise with deletion result
* Delete entities by their identifiers.
*
* Removes successfully deleted entities from the local store.
*
* @param sources - entity identifiers to delete
*
* @returns Promise with deletion results keyed by source identifier
*/
async function remove(provider: string, service: string | number, collection: string | number, identifier: string | number): Promise<any> {
async function remove(sources: EntityIdentifier[]): Promise<EntityDeleteResponse> {
transceiving.value = true
try {
const response = await entityService.delete({ provider, service, collection, identifier })
// Remove entity from state
const key = identifierKey(provider, service, collection, identifier)
delete _entities.value[key]
const response = await entityService.delete({ sources })
console.debug('[Mail Manager][Store] - Successfully deleted entity:', key)
return response
} catch (error: any) {
console.error('[Mail Manager][Store] - Failed to delete entity:', error)
throw error
} finally {
transceiving.value = false
}
}
Object.entries(response).forEach(([sourceIdentifier, result]) => {
if (!result.success) {
return
}
/**
* Retrieve delta changes for entities
*
* @param sources - source selector for delta check
*
* @returns Promise with delta changes (additions, modifications, deletions)
*
* Note: Delta returns only identifiers, not full entities.
* Caller should fetch full entities for additions/modifications separately.
*/
async function delta(sources: SourceSelector) {
transceiving.value = true
try {
const response = await entityService.delta({ sources })
// Process delta and update store
Object.entries(response).forEach(([provider, providerData]) => {
// Skip if no changes for provider
if (providerData === false) return
Object.entries(providerData).forEach(([service, serviceData]) => {
// Skip if no changes for service
if (serviceData === false) return
Object.entries(serviceData).forEach(([collection, collectionData]) => {
// Skip if no changes for collection
if (collectionData === false) return
// Process deletions (remove from store)
if (collectionData.deletions && collectionData.deletions.length > 0) {
collectionData.deletions.forEach((identifier) => {
const key = identifierKey(provider, service, collection, identifier)
delete _entities.value[key]
})
}
// Note: additions and modifications contain only identifiers
// The caller should fetch full entities using the fetch() method
})
})
delete _entities.value[sourceIdentifier]
})
console.debug('[Mail Manager][Store] - Successfully processed delta changes')
console.debug('[Mail Manager][Store] - Successfully deleted', Object.keys(response).length, 'entities')
return response
} catch (error: any) {
console.error('[Mail Manager][Store] - Failed to process delta:', error)
console.error('[Mail Manager][Store] - Failed to delete entities:', error)
throw error
} finally {
transceiving.value = false
@@ -461,8 +494,9 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
has,
entities,
entitiesForCollection,
// Actions
entitiesByIdentifiers,
entity,
entityByIdentifier,
list,
fetch,
extant,