cmpstr
Version:
CmpStr is a lightweight, fast and well performing package for calculating string similarity
81 lines (78 loc) • 2.41 kB
JavaScript
// CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
import { ErrorUtil, CmpStrNotFoundError } from './Errors.mjs';
const registry = Object.create(null);
const factory = Object.create(null);
function Registry(reg, ctor) {
ErrorUtil.assert(
!(reg in registry || reg in factory),
`Registry <${reg}> already exists / overwriting is forbidden`,
{ registry: reg }
);
const classes = Object.create(null);
const service = Object.freeze({
add(name, cls, update = false) {
ErrorUtil.assert(
typeof name === 'string' && name.length > 0,
`Class name must be a non-empty string`,
{ registry: reg, name }
);
ErrorUtil.assert(
typeof cls === 'function',
`Class must be a constructor function`,
{ registry: reg, class: cls }
);
ErrorUtil.assert(
cls.prototype instanceof ctor,
`Class must extend <${reg}>`,
{ registry: reg, class: cls }
);
ErrorUtil.assert(
update || !(name in classes),
`Class <${name}> already exists / use <update=true> to overwrite`,
{ registry: reg, name }
);
classes[name] = cls;
},
remove(name) {
delete classes[name];
},
has(name) {
return name in classes;
},
list() {
return Object.keys(classes);
},
get(name) {
ErrorUtil.assert(
typeof name === 'string' && name.length > 0,
`Class name must be a non-empty string`,
{ registry: reg, name }
);
ErrorUtil.assert(
name in classes,
`Class <${name}> not registered for <${reg}>`,
{ registry: reg, name }
);
return classes[name];
}
});
registry[reg] = service;
factory[reg] = (cls, ...args) => createFromRegistry(reg, cls, ...args);
return service;
}
function resolveCls(reg, cls) {
if (!(reg in registry))
throw new CmpStrNotFoundError(`Registry <${reg}> does not exist`, {
registry: reg
});
return typeof cls === 'string' ? registry[reg]?.get(cls) : cls;
}
function createFromRegistry(reg, cls, ...args) {
cls = resolveCls(reg, cls);
return ErrorUtil.wrap(
() => new cls(...args),
`Failed to create instance of class <${cls.name ?? cls}> from registry <${reg}>`,
{ registry: reg, class: cls, args }
);
}
export { Registry, createFromRegistry, factory, registry, resolveCls };