Source: crdt/CRDTRegistry.ts

/**
 * @author Maximilian Kallert <max@refinio.net>
 * @author Eduard Reimer <eduard@refinio.net>
 * @copyright REFINIO GmbH 2020
 * @license CC-BY-NC-SA-2.5; portions MIT License
 * @version 1.0.0
 */

/**
 * This module takes care of registering all CRDT implementations.
 *
 * Specific algorithms need to be added to CRDTImplementationNames and then in the
 * crdtImplementationMap.
 * @module
 */

import type {CRDTImplementation} from './CRDTImplementation';
import {LWWRegister} from './LWWRegister';
import {LWWSet} from './LWWSet';
import {ObjectCRDT} from './ObjectCRDT';
import {ORRegister} from './ORRegister';
import {ORSet} from './ORSet';
import {ORSetForArrays} from './ORSetForArrays';

export type CRDTImplementationTypes = 'list' | 'set' | 'register' | 'object';
export type CRDTImplementationNames =
    | 'LWWRegister'
    | 'LWWSet'
    | 'ORRegister'
    | 'ORSet'
    | 'ORSetForArrays';

const crdtImplementationsMap = new Map<
    CRDTImplementationTypes | CRDTImplementationNames,
    CRDTImplementation
>([
    ['list', new ORSetForArrays()],
    ['set', new ORSet()],
    ['register', new ORRegister()],
    ['object', new ObjectCRDT()],
    ['LWWRegister', new LWWRegister()],
    ['LWWSet', new LWWSet()],
    ['ORRegister', new ORRegister()],
    ['ORSet', new ORSet()],
    ['ORSetForArrays', new ORSetForArrays()]
]);

/**
 * Returns the algorithm for the supplied type or name
 * @param {CRDTImplementationTypes} crdtImplementationType
 * @param {CRDTImplementationNames} crdtImplementationName
 * @returns {CRDTImplementation}
 */
export function getCrdtImplementation(
    crdtImplementationType: CRDTImplementationTypes,
    crdtImplementationName?: CRDTImplementationNames
): CRDTImplementation {
    const crdtImplementation = crdtImplementationsMap.get(
        crdtImplementationName ? crdtImplementationName : crdtImplementationType
    );

    if (crdtImplementation === undefined) {
        throw new Error(
            `Didn't find ${crdtImplementationName} or its default ${crdtImplementationType} in the CRDT registry.`
        );
    }

    return crdtImplementation;
}