import { Serializer, SerializerClass } from './serializer'; import { Dict } from '@orbit/utils'; export type SerializerForFn = (type: string) => S | undefined; export function buildSerializerFor(settings: { serializers?: Dict; serializerClassFor?: SerializerClassForFn; serializerSettingsFor?: SerializerSettingsForFn; }): SerializerForFn { const customSerializers = settings.serializers ?? {}; const serializers = { ...customSerializers }; const serializerClassFor = settings.serializerClassFor; const serializerSettingsFor = settings.serializerSettingsFor; function serializerFor(type: string): S | undefined { return (serializers[type] as S) ?? createSerializer(type); } function createSerializer(type: string): S | undefined { const SerializerClass = serializerClassFor && serializerClassFor(type); if (SerializerClass) { const settings = (serializerSettingsFor && serializerSettingsFor(type)) || {}; settings.serializerFor = serializerFor; return (serializers[type] = new SerializerClass(settings)); } } return serializerFor; } export type SerializerClassForFn = ( type: string ) => SerializerClass; export function buildSerializerClassFor( serializerClasses: Dict> = {} ): SerializerClassForFn { return (type: string) => serializerClasses[type]; } export type SerializerSettingsForFn = ( type: string ) => Dict | undefined; export function buildSerializerSettingsFor(settings: { sharedSettings?: Dict; settingsByType?: Dict>; }): SerializerSettingsForFn { const serializerSettings: Dict> = {}; const sharedSettings = settings.sharedSettings || {}; const settingsByType = settings.settingsByType || {}; function serializerSettingsFor(type: string): Dict { return serializerSettings[type] || createSerializerSettings(type); } function createSerializerSettings(type: string): Dict { const settingsForType = settingsByType[type] || {}; const settings = { ...sharedSettings, ...settingsForType } as Dict; return (serializerSettings[type] = settings); } return serializerSettingsFor; }