ccb781f933
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
342 lines
9.9 KiB
TypeScript
342 lines
9.9 KiB
TypeScript
/**
|
|
* Nodes Store (thin wrapper over collections/entities stores)
|
|
*/
|
|
|
|
import { computed, ref, readonly } from 'vue'
|
|
import { defineStore } from 'pinia'
|
|
import type {
|
|
SourceSelector,
|
|
ListFilter,
|
|
ListSort,
|
|
ListRange,
|
|
CollectionMutableProperties,
|
|
DocumentInterface,
|
|
} from '../types'
|
|
import { CollectionObject, EntityObject } from '../models'
|
|
import { useCollectionsStore } from './collectionsStore'
|
|
import { useEntitiesStore } from './entitiesStore'
|
|
|
|
export const ROOT_ID = '00000000-0000-0000-0000-000000000000'
|
|
|
|
type NodeRecord = CollectionObject | EntityObject
|
|
|
|
export const useNodesStore = defineStore('documentsNodesStore', () => {
|
|
const collectionsStore = useCollectionsStore()
|
|
const entitiesStore = useEntitiesStore()
|
|
|
|
const error = ref<string | null>(null)
|
|
|
|
const transceiving = computed(() => collectionsStore.transceiving || entitiesStore.transceiving)
|
|
|
|
const nodeList = computed<NodeRecord[]>(() => {
|
|
return [...collectionsStore.collections, ...entitiesStore.entities]
|
|
})
|
|
|
|
const collectionList = computed<CollectionObject[]>(() => collectionsStore.collections)
|
|
const entityList = computed<EntityObject[]>(() => entitiesStore.entities)
|
|
|
|
function toId(value: string | number | null | undefined): string | null {
|
|
if (value === null || value === undefined || value === '') {
|
|
return null
|
|
}
|
|
|
|
return String(value)
|
|
}
|
|
|
|
function getServiceNodes(providerId: string, serviceId: string | number): NodeRecord[] {
|
|
return [
|
|
...collectionsStore.collectionsForService(providerId, serviceId),
|
|
...entitiesStore.entitiesForService(providerId, serviceId),
|
|
]
|
|
}
|
|
|
|
function getNode(providerId: string, serviceId: string | number, nodeId: string | number): NodeRecord | undefined {
|
|
const targetId = String(nodeId)
|
|
return getServiceNodes(providerId, serviceId)
|
|
.find((node) => String(node.identifier) === targetId)
|
|
}
|
|
|
|
function isRoot(nodeId: string | number | null | undefined): boolean {
|
|
const normalized = toId(nodeId)
|
|
return normalized === null || normalized === ROOT_ID
|
|
}
|
|
|
|
function getChildren(providerId: string, serviceId: string | number, parentId: string | number | null): NodeRecord[] {
|
|
const serviceNodes = getServiceNodes(providerId, serviceId)
|
|
|
|
if (isRoot(parentId)) {
|
|
return serviceNodes.filter((node) => {
|
|
const parent = toId(node.collection)
|
|
return parent === null || parent === ROOT_ID
|
|
})
|
|
}
|
|
|
|
const targetParent = String(parentId)
|
|
return serviceNodes.filter((node) => toId(node.collection) === targetParent)
|
|
}
|
|
|
|
function getChildCollections(providerId: string, serviceId: string | number, parentId: string | number | null): CollectionObject[] {
|
|
return getChildren(providerId, serviceId, parentId)
|
|
.filter((node): node is CollectionObject => node instanceof CollectionObject)
|
|
}
|
|
|
|
function getChildEntities(providerId: string, serviceId: string | number, parentId: string | number | null): EntityObject[] {
|
|
return getChildren(providerId, serviceId, parentId)
|
|
.filter((node): node is EntityObject => node instanceof EntityObject)
|
|
}
|
|
|
|
function getPath(providerId: string, serviceId: string | number, nodeId: string | number): NodeRecord[] {
|
|
const path: NodeRecord[] = []
|
|
let current = getNode(providerId, serviceId, nodeId)
|
|
|
|
while (current) {
|
|
path.unshift(current)
|
|
const parentId = toId(current.collection)
|
|
|
|
if (parentId === null || parentId === ROOT_ID) {
|
|
break
|
|
}
|
|
|
|
current = getNode(providerId, serviceId, parentId)
|
|
}
|
|
|
|
return path
|
|
}
|
|
|
|
async function fetchCollections(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number | null,
|
|
filter?: ListFilter,
|
|
sort?: ListSort,
|
|
): Promise<CollectionObject[]> {
|
|
error.value = null
|
|
try {
|
|
const sources: SourceSelector = {
|
|
[providerId]: {
|
|
[String(serviceId)]: collectionId === null
|
|
? true
|
|
: { [String(collectionId)]: true },
|
|
},
|
|
}
|
|
|
|
await collectionsStore.list(sources, filter, sort)
|
|
return collectionsStore.collectionsForService(providerId, serviceId)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to fetch collections'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function fetchEntities(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number | null,
|
|
filter?: ListFilter,
|
|
sort?: ListSort,
|
|
range?: ListRange,
|
|
): Promise<EntityObject[]> {
|
|
error.value = null
|
|
try {
|
|
const sources: SourceSelector = {
|
|
[providerId]: {
|
|
[String(serviceId)]: collectionId === null
|
|
? true
|
|
: { [String(collectionId)]: true },
|
|
},
|
|
}
|
|
|
|
await entitiesStore.list(sources, filter, sort, range)
|
|
return entitiesStore.entitiesForCollection(providerId, serviceId, collectionId)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to fetch entities'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function fetchNodes(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
parentId: string | number | null = ROOT_ID,
|
|
filter?: ListFilter,
|
|
sort?: ListSort,
|
|
range?: ListRange,
|
|
): Promise<NodeRecord[]> {
|
|
error.value = null
|
|
try {
|
|
await Promise.all([
|
|
fetchCollections(providerId, serviceId, parentId, filter, sort),
|
|
fetchEntities(providerId, serviceId, parentId, filter, sort, range),
|
|
])
|
|
|
|
return getChildren(providerId, serviceId, parentId)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to fetch nodes'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function createCollection(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
parentCollectionId: string | number | null,
|
|
properties: CollectionMutableProperties,
|
|
): Promise<CollectionObject> {
|
|
error.value = null
|
|
try {
|
|
return await collectionsStore.create(providerId, serviceId, parentCollectionId, properties)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to create collection'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function updateCollection(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
identifier: string | number,
|
|
properties: CollectionMutableProperties,
|
|
): Promise<CollectionObject> {
|
|
error.value = null
|
|
try {
|
|
return await collectionsStore.update(providerId, serviceId, identifier, properties)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to update collection'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function deleteCollection(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
identifier: string | number,
|
|
): Promise<boolean> {
|
|
error.value = null
|
|
try {
|
|
const response = await collectionsStore.delete(providerId, serviceId, identifier)
|
|
return response.success
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to delete collection'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function createEntity(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number,
|
|
properties: DocumentInterface,
|
|
options?: Record<string, unknown>,
|
|
): Promise<EntityObject> {
|
|
error.value = null
|
|
try {
|
|
return await entitiesStore.create(providerId, serviceId, collectionId, properties, options)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to create entity'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function updateEntity(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number,
|
|
identifier: string | number,
|
|
properties: DocumentInterface,
|
|
): Promise<EntityObject> {
|
|
error.value = null
|
|
try {
|
|
return await entitiesStore.update(providerId, serviceId, collectionId, identifier, properties)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to update entity'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function deleteEntity(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number,
|
|
identifier: string | number,
|
|
): Promise<boolean> {
|
|
error.value = null
|
|
try {
|
|
const response = await entitiesStore.delete(providerId, serviceId, collectionId, identifier)
|
|
return response.success
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to delete entity'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function readEntity(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number,
|
|
identifier: string | number,
|
|
): Promise<string | null> {
|
|
error.value = null
|
|
try {
|
|
return await entitiesStore.read(providerId, serviceId, collectionId, identifier)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to read entity'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
async function writeEntity(
|
|
providerId: string,
|
|
serviceId: string | number,
|
|
collectionId: string | number,
|
|
identifier: string | number,
|
|
content: string,
|
|
): Promise<number> {
|
|
error.value = null
|
|
try {
|
|
return await entitiesStore.write(providerId, serviceId, collectionId, identifier, content)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to write entity'
|
|
throw e
|
|
}
|
|
}
|
|
|
|
function clearServiceNodes(providerId: string, serviceId: string | number): void {
|
|
collectionsStore.clearService(providerId, serviceId)
|
|
entitiesStore.clearService(providerId, serviceId)
|
|
}
|
|
|
|
function clearNodes(): void {
|
|
collectionsStore.clearAll()
|
|
entitiesStore.clearAll()
|
|
}
|
|
|
|
return {
|
|
transceiving: readonly(transceiving),
|
|
error: readonly(error),
|
|
ROOT_ID,
|
|
nodeList,
|
|
collectionList,
|
|
entityList,
|
|
getNode,
|
|
getServiceNodes,
|
|
getChildren,
|
|
getChildCollections,
|
|
getChildEntities,
|
|
getPath,
|
|
isRoot,
|
|
fetchNodes,
|
|
fetchCollections,
|
|
fetchEntities,
|
|
createCollection,
|
|
updateCollection,
|
|
deleteCollection,
|
|
createEntity,
|
|
updateEntity,
|
|
deleteEntity,
|
|
readEntity,
|
|
writeEntity,
|
|
clearServiceNodes,
|
|
clearNodes,
|
|
}
|
|
})
|