[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

171 lines
4.9 KiB

import {
EntityType,
EntityStore,
Entity,
User,
NormalizedUser,
Invitation,
NormalizedInvitation,
GroupLog,
NormalizedGroupLog,
App,
Installation,
NormalizedInstallation,
} from '../types'
import compact from 'lodash/compact'
export interface NormalizeResult {
keys: string[]
entities: EntityStore
}
function set(type: EntityType, store: EntityStore, entity?: Entity): string | undefined {
if (!entity) return
const collection = store[type] || {}
const existing = collection[entity.id] || {}
collection[entity.id] = {
...existing,
...entity,
}
store[type] = collection
return entity.id
}
function get(type: EntityType, store: EntityStore, id?: string): Entity | undefined {
if (!id) return
const collection = store[type] || {}
return collection[id]
}
export function normalize(entities: Entity[], type: EntityType): NormalizeResult {
let keys: Array<string | undefined> = []
const newStore: EntityStore = {}
switch (type) {
case EntityType.User:
keys = entities.map(entity => {
const user = entity as User
return set(type, newStore, {
...user,
group: set(EntityType.Group, newStore, user.group),
})
})
break
case EntityType.Group:
keys = entities.map(entity => set(type, newStore, entity))
break
case EntityType.Invitation:
keys = entities.map(entity => {
const invitation = entity as Invitation
const user = invitation.user
return set(type, newStore, {
...invitation,
user: set(EntityType.User, newStore, {
...user,
group: set(EntityType.Group, newStore, user.group),
}),
})
})
break
case EntityType.Log:
keys = entities.map(entity => {
const log = entity as GroupLog
const user = log.user
return set(type, newStore, {
...log,
user: set(EntityType.User, newStore, {
...user,
group: set(EntityType.Group, newStore, user.group),
}),
})
})
break
case EntityType.App:
keys = entities.map(entity => set(type, newStore, entity))
break
case EntityType.Installation:
keys = entities.map(entity => {
const installation = entity as Installation
return set(type, newStore, {
...installation,
app: set(EntityType.App, newStore, installation.app),
})
})
}
return {
keys: compact(keys),
entities: newStore,
}
}
export function denormalize(keys: string[], type: EntityType, store: EntityStore): Entity[] {
const entities = keys.map(key => {
switch (type) {
case EntityType.User: {
const user = get(type, store, key) as NormalizedUser
if (!user) return
return {
...user,
group: get(EntityType.Group, store, user.group),
}
}
case EntityType.Group:
return get(type, store, key)
case EntityType.Invitation: {
const invitation = get(type, store, key) as NormalizedInvitation
if (!invitation) return
const user = get(EntityType.User, store, invitation.user) as NormalizedUser
return {
...invitation,
user: {
...user,
group: get(EntityType.Group, store, user.group),
},
}
}
case EntityType.Log: {
const log = get(type, store, key) as NormalizedGroupLog
if (!log) return
const user = get(EntityType.User, store, log.user) as NormalizedUser
return {
...log,
user: {
...user,
group: get(EntityType.Group, store, user.group),
},
}
}
case EntityType.App:
return get(type, store, key)
case EntityType.Installation: {
const installation = get(type, store, key) as NormalizedInstallation
if (!installation) return
return {
...installation,
app: get(EntityType.App, store, installation.app),
}
}
}
})
return compact(entities)
}