diff --git a/packages/visual-sdk/src/store/EditorEntityStore.ts b/packages/visual-sdk/src/store/EditorEntityStore.ts index ac492e6b..cc48f33c 100644 --- a/packages/visual-sdk/src/store/EditorEntityStore.ts +++ b/packages/visual-sdk/src/store/EditorEntityStore.ts @@ -67,27 +67,33 @@ export class EditorEntityStore extends EntityStore { return id.length === 1 ? id[0] : id.join(this.cacheIdSeperator); } - private findMissingEntites(ids: string[]) { - const missing = []; + // TODO: we have this bascially already covered in the EntityStore (except: it throws an error instead of returning both) + private findMissingEntites(type: 'Asset', ids: string[]): { missingIds: string[], resolvedEntities: Array } + private findMissingEntites(type: 'Entry', ids: string[]): { missingIds: string[], resolvedEntities: Array } + private findMissingEntites(type: 'Asset' | 'Entry', ids: string[]) { + const resolvedEntities = []; + const missingIds = []; for (const id of ids) { - const entry = this.entitiesMap.get(id); - if (!entry) { - missing.push(id); + const entity = this.getEntity(type, id); + if (entity) { + resolvedEntities.push(entity) + } else { + missingIds.push(id); } } - return missing; + return {missingIds, resolvedEntities}; } - private async fetchEntity(ids: string[]): Promise>; - private async fetchEntity(ids: string[], isAsset: true): Promise>; - private async fetchEntity(ids: string[], isAsset?: boolean): Promise> { - const missingIds = this.findMissingEntites(ids); + private async fetchEntity(type: 'Asset', ids: string[]): Promise>; + private async fetchEntity(type: 'Entry', ids: string[]): Promise>; + private async fetchEntity(type: 'Asset' | 'Entry', ids: string[]): Promise | Array> { + const {missingIds, resolvedEntities} = this.findMissingEntites(type, ids); if (missingIds.length === 0) { // everything is already in cache - return ids.map((id) => this.entitiesMap.get(id)) as Array; + return resolvedEntities; } const cacheId = this.getCacheId(missingIds); @@ -120,7 +126,7 @@ export class EditorEntityStore extends EntityStore { this.sendMessage(PostMessageMethods.REQUEST_ENTITIES, { entityIds: missingIds, - entityType: isAsset ? 'Asset' : 'Entry', + entityType: type, locale: this.locale, }); }); @@ -133,10 +139,10 @@ export class EditorEntityStore extends EntityStore { const result = (await newPromise) as Array; result.forEach((value) => { - this.entitiesMap.set(value.sys.id, value); + this.addEntity(value) }); - return ids.map((id) => this.entitiesMap.get(id)) as Array; + return ids.map((id) => this.getEntity(type, id)); } public async fetchAsset(id: string): Promise { @@ -150,7 +156,7 @@ export class EditorEntityStore extends EntityStore { } public fetchAssets(ids: string[]): Promise { - return this.fetchEntity(ids, true); + return this.fetchEntity('Asset', ids); } public async fetchEntry(id: string): Promise { @@ -164,6 +170,6 @@ export class EditorEntityStore extends EntityStore { } public fetchEntries(ids: string[]): Promise { - return this.fetchEntity(ids); + return this.fetchEntity('Entry', ids); } } diff --git a/packages/visual-sdk/src/store/EntityStore.ts b/packages/visual-sdk/src/store/EntityStore.ts index fc01e89b..99a9e5f3 100644 --- a/packages/visual-sdk/src/store/EntityStore.ts +++ b/packages/visual-sdk/src/store/EntityStore.ts @@ -8,28 +8,33 @@ import { get } from './utils'; */ export class EntityStore { protected locale: string; - protected entitiesMap: Map; + protected entryMap = new Map(); + protected assetMap = new Map(); constructor({ entities, locale }: { entities: Array; locale: string }) { - this.entitiesMap = new Map(entities.map((entity) => [entity.sys.id, entity])); this.locale = locale; + + for (const entity of entities) { + this.addEntity(entity) + } } public get entities() { - return [...this.entitiesMap.values()]; + return [...this.entryMap.values(), ...this.assetMap.values()]; } public updateEntity(entity: Entry | Asset) { - this.entitiesMap.set(entity.sys.id, entity); + this.addEntity(entity); } public getValue( entityLink: UnresolvedLink<'Entry' | 'Asset'>, path: string[] ): string | undefined { - const entity = this.entitiesMap.get(entityLink.sys.id); + entityLink.sys.type + const entity = this.getEntity(entityLink.sys.linkType, entityLink.sys.id); - if (!entity || entity.sys.type !== entityLink.sys.linkType) { + if (!entity) { // TODO: move to `debug` utils once it is extracted console.warn(`Unresolved entity reference: ${entityLink}`); return; @@ -38,29 +43,31 @@ export class EntityStore { return get(entity, path); } - private getEntitiesFromMap(ids: string[]) { - const entity = []; + private getEntitiesFromMap(type: 'Entry', ids: string[]): Array + private getEntitiesFromMap(type: 'Asset', ids: string[]): Array + private getEntitiesFromMap(type: 'Entry' | 'Asset', ids: string[]) { + const entityList = []; const missingEntityIds = []; for (const id of ids) { - const entry = this.entitiesMap.get(id); - if (entry) { - entity.push(entry); + const entity = this.getEntity(type, id); + if (entity) { + entityList.push(entity); } else { missingEntityIds.push(id); } } if (missingEntityIds.length) { - throw new Error(`Missing entity in the store (${missingEntityIds.join(',')})`); + throw new Error(`Missing ${type} in the store (${missingEntityIds.join(',')})`); } - return entity as Array; + return entityList; } public async fetchAsset(id: string): Promise { try { - return this.getEntitiesFromMap([id])[0] as Asset; + return this.getEntitiesFromMap('Asset', [id])[0]; } catch (err) { // TODO: move to `debug` utils once it is extracted console.warn(`Asset "${id}" is not in the store`); @@ -68,12 +75,12 @@ export class EntityStore { } } public async fetchAssets(ids: string[]): Promise { - return this.getEntitiesFromMap(ids) as Asset[]; + return this.getEntitiesFromMap('Asset', ids); } public async fetchEntry(id: string): Promise { try { - return this.getEntitiesFromMap([id])[0] as Entry; + return this.getEntitiesFromMap('Entry', [id])[0]; } catch (err) { // TODO: move to `debug` utils once it is extracted console.warn(`Entry "${id}" is not in the store`); @@ -82,6 +89,25 @@ export class EntityStore { } public async fetchEntries(ids: string[]): Promise { - return this.getEntitiesFromMap(ids) as Entry[]; + return this.getEntitiesFromMap('Entry', ids); + } + + private isAsset(entity: Entry | Asset): entity is Asset { + return entity.sys.type === 'Asset' + } + + protected addEntity(entity: Entry | Asset): void { + if (this.isAsset(entity)) { + this.assetMap.set(entity.sys.id, entity) + } else { + this.entryMap.set(entity.sys.id, entity) + } + } + + protected getEntity(type: 'Entry' | 'Asset', id: string): Asset | Entry | undefined { + if (type === 'Asset') { + return this.assetMap.get(id) + } + return this.entryMap.get(id) } }