solid-services
Version:
Solid.js library adding a services layer for global shared state.
103 lines • 11.9 kB
JavaScript
import { getOwner, useContext } from "solid-js";
import { ServiceRegistryContext } from "./context";
import { runInSubRoot } from "./utils";
export class Service {
}
/**
* Registry is a container for services.
* It is used to register and retrieve services.
*/
export class Registry {
#owner;
#config;
#cache;
constructor(config = {}) {
this.#config = config;
this.#owner = getOwner();
this.#cache = new Map();
}
/**
* Checks weather the registry has a service registered for the given initializer.
*
* First it will check in the parent registry and if no service is registered there,
* it will check in the current registry.
*/
has(initializer) {
const parentRegistry = this.getParentRegistry();
if (parentRegistry?.isExposing(initializer)) {
return parentRegistry.has(initializer);
}
return this.#cache.has(initializer);
}
/**
* Returns the service registered for the given initializer.
*
* First it will try to find it in the parent registry and if no service is registered there,
* it will check in the current registry.
*/
get(initializer) {
const parentRegistry = this.getParentRegistry();
if (parentRegistry?.isExposing(initializer)) {
return parentRegistry.get(initializer);
}
return this.#cache.get(initializer);
}
/**
* Clears the registry.
*/
clear() {
this.#cache.clear();
}
/**
* Deletes registered service for the given initializer.
*/
delete(initializer) {
this.#cache.delete(initializer);
}
/**
* Registers a service for the given initializer.
*
* If the registry has a parent registry, it will check if the service is exposed there.
*
* If it is exposed, it will register the service in the parent registry.
*
* If it is not exposed, it will register the service in the current registry.
*
* If the registry does not have a parent registry, it will register the service in the current registry.
*/
register(initializer) {
const parentRegistry = this.getParentRegistry();
if (parentRegistry?.isExposing(initializer)) {
return parentRegistry.register(initializer);
}
const registration = runInSubRoot(() => this.initializeService(initializer), this.#owner);
this.#cache.set(initializer, registration);
return registration;
}
isExposing(initializer) {
return (this.#config.expose === true ||
(Array.isArray(this.#config.expose) &&
this.#config.expose?.includes(initializer)));
}
getParentRegistry() {
return this.#owner?.owner
? runInSubRoot((dispose) => {
const context = useContext(ServiceRegistryContext);
dispose();
return context;
}, this.#owner.owner)
: undefined;
}
initializeService(initializer) {
return initializer.prototype?.constructor
? Reflect.construct(initializer, [])
: initializer();
}
}
/**
* Creates a new registry for services.
*/
export function createRegistry(config) {
return new Registry(config);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFTLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ25ELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdkMsTUFBTSxPQUFPLE9BQU87Q0FBRztBQWF2Qjs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sUUFBUTtJQUNuQixNQUFNLENBQWU7SUFDckIsT0FBTyxDQUFpQjtJQUN4QixNQUFNLENBQW9DO0lBRTFDLFlBQVksU0FBeUIsRUFBRTtRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWdDLENBQUM7SUFDeEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsR0FBRyxDQUFvQixXQUFrQztRQUN2RCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUVoRCxJQUFJLGNBQWMsRUFBRSxVQUFVLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDM0MsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ3hDO1FBRUQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxHQUFHLENBQW9CLFdBQWtDO1FBQ3ZELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRWhELElBQUksY0FBYyxFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUMzQyxPQUFPLGNBQWMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDeEM7UUFFRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBb0IsV0FBa0M7UUFDMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxRQUFRLENBQW9CLFdBQWtDO1FBQzVELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRWhELElBQUksY0FBYyxFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUMzQyxPQUFPLGNBQWMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDN0M7UUFFRCxNQUFNLFlBQVksR0FBRyxZQUFZLENBQy9CLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsRUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FDWixDQUFDO1FBRUYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRTNDLE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFUyxVQUFVLENBQ2xCLFdBQWtDO1FBRWxDLE9BQU8sQ0FDTCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxJQUFJO1lBQzVCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQzlDLENBQUM7SUFDSixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLO1lBQ3ZCLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDdkIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLHNCQUFzQixDQUFDLENBQUM7Z0JBQ25ELE9BQU8sRUFBRSxDQUFDO2dCQUNWLE9BQU8sT0FBTyxDQUFDO1lBQ2pCLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztZQUN2QixDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLENBQUM7SUFFTyxpQkFBaUIsQ0FDdkIsV0FBa0M7UUFFbEMsT0FBTyxXQUFXLENBQUMsU0FBUyxFQUFFLFdBQVc7WUFDdkMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUNwQyxDQUFDLENBQUUsV0FBa0MsRUFBRSxDQUFDO0lBQzVDLENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxNQUF1QjtJQUNwRCxPQUFPLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPd25lciwgZ2V0T3duZXIsIHVzZUNvbnRleHQgfSBmcm9tIFwic29saWQtanNcIjtcbmltcG9ydCB7IFNlcnZpY2VSZWdpc3RyeUNvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0XCI7XG5pbXBvcnQgeyBydW5JblN1YlJvb3QgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgY2xhc3MgU2VydmljZSB7fVxuXG50eXBlIFNlcnZpY2VGdW5jdGlvbjxUIGV4dGVuZHMgU2VydmljZT4gPSAoKSA9PiBUO1xudHlwZSBTZXJ2aWNlQ29uc3RydWN0b3I8VCBleHRlbmRzIFNlcnZpY2U+ID0gbmV3ICgpID0+IFQ7XG5cbmV4cG9ydCB0eXBlIFNlcnZpY2VJbml0aWFsaXplcjxUIGV4dGVuZHMgU2VydmljZT4gPVxuICB8IFNlcnZpY2VGdW5jdGlvbjxUPlxuICB8IFNlcnZpY2VDb25zdHJ1Y3RvcjxUPjtcblxuZXhwb3J0IGludGVyZmFjZSBSZWdpc3RyeUNvbmZpZyB7XG4gIGV4cG9zZT86IFNlcnZpY2VJbml0aWFsaXplcjxhbnk+W10gfCBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlZ2lzdHJ5IGlzIGEgY29udGFpbmVyIGZvciBzZXJ2aWNlcy5cbiAqIEl0IGlzIHVzZWQgdG8gcmVnaXN0ZXIgYW5kIHJldHJpZXZlIHNlcnZpY2VzLlxuICovXG5leHBvcnQgY2xhc3MgUmVnaXN0cnkge1xuICAjb3duZXI6IE93bmVyIHwgbnVsbDtcbiAgI2NvbmZpZzogUmVnaXN0cnlDb25maWc7XG4gICNjYWNoZTogTWFwPFNlcnZpY2VJbml0aWFsaXplcjxhbnk+LCBhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogUmVnaXN0cnlDb25maWcgPSB7fSkge1xuICAgIHRoaXMuI2NvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLiNvd25lciA9IGdldE93bmVyKCk7XG4gICAgdGhpcy4jY2FjaGUgPSBuZXcgTWFwPFNlcnZpY2VJbml0aWFsaXplcjxhbnk+LCBhbnk+KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdlYXRoZXIgdGhlIHJlZ2lzdHJ5IGhhcyBhIHNlcnZpY2UgcmVnaXN0ZXJlZCBmb3IgdGhlIGdpdmVuIGluaXRpYWxpemVyLlxuICAgKlxuICAgKiBGaXJzdCBpdCB3aWxsIGNoZWNrIGluIHRoZSBwYXJlbnQgcmVnaXN0cnkgYW5kIGlmIG5vIHNlcnZpY2UgaXMgcmVnaXN0ZXJlZCB0aGVyZSxcbiAgICogaXQgd2lsbCBjaGVjayBpbiB0aGUgY3VycmVudCByZWdpc3RyeS5cbiAgICovXG4gIGhhczxUIGV4dGVuZHMgU2VydmljZT4oaW5pdGlhbGl6ZXI6IFNlcnZpY2VJbml0aWFsaXplcjxUPik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhcmVudFJlZ2lzdHJ5ID0gdGhpcy5nZXRQYXJlbnRSZWdpc3RyeSgpO1xuXG4gICAgaWYgKHBhcmVudFJlZ2lzdHJ5Py5pc0V4cG9zaW5nKGluaXRpYWxpemVyKSkge1xuICAgICAgcmV0dXJuIHBhcmVudFJlZ2lzdHJ5Lmhhcyhpbml0aWFsaXplcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuI2NhY2hlLmhhcyhpbml0aWFsaXplcik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2VydmljZSByZWdpc3RlcmVkIGZvciB0aGUgZ2l2ZW4gaW5pdGlhbGl6ZXIuXG4gICAqXG4gICAqIEZpcnN0IGl0IHdpbGwgdHJ5IHRvIGZpbmQgaXQgaW4gdGhlIHBhcmVudCByZWdpc3RyeSBhbmQgaWYgbm8gc2VydmljZSBpcyByZWdpc3RlcmVkIHRoZXJlLFxuICAgKiBpdCB3aWxsIGNoZWNrIGluIHRoZSBjdXJyZW50IHJlZ2lzdHJ5LlxuICAgKi9cbiAgZ2V0PFQgZXh0ZW5kcyBTZXJ2aWNlPihpbml0aWFsaXplcjogU2VydmljZUluaXRpYWxpemVyPFQ+KTogVCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcGFyZW50UmVnaXN0cnkgPSB0aGlzLmdldFBhcmVudFJlZ2lzdHJ5KCk7XG5cbiAgICBpZiAocGFyZW50UmVnaXN0cnk/LmlzRXhwb3NpbmcoaW5pdGlhbGl6ZXIpKSB7XG4gICAgICByZXR1cm4gcGFyZW50UmVnaXN0cnkuZ2V0KGluaXRpYWxpemVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy4jY2FjaGUuZ2V0KGluaXRpYWxpemVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIHJlZ2lzdHJ5LlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy4jY2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHJlZ2lzdGVyZWQgc2VydmljZSBmb3IgdGhlIGdpdmVuIGluaXRpYWxpemVyLlxuICAgKi9cbiAgZGVsZXRlPFQgZXh0ZW5kcyBTZXJ2aWNlPihpbml0aWFsaXplcjogU2VydmljZUluaXRpYWxpemVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy4jY2FjaGUuZGVsZXRlKGluaXRpYWxpemVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBzZXJ2aWNlIGZvciB0aGUgZ2l2ZW4gaW5pdGlhbGl6ZXIuXG4gICAqXG4gICAqIElmIHRoZSByZWdpc3RyeSBoYXMgYSBwYXJlbnQgcmVnaXN0cnksIGl0IHdpbGwgY2hlY2sgaWYgdGhlIHNlcnZpY2UgaXMgZXhwb3NlZCB0aGVyZS5cbiAgICpcbiAgICogSWYgaXQgaXMgZXhwb3NlZCwgaXQgd2lsbCByZWdpc3RlciB0aGUgc2VydmljZSBpbiB0aGUgcGFyZW50IHJlZ2lzdHJ5LlxuICAgKlxuICAgKiBJZiBpdCBpcyBub3QgZXhwb3NlZCwgaXQgd2lsbCByZWdpc3RlciB0aGUgc2VydmljZSBpbiB0aGUgY3VycmVudCByZWdpc3RyeS5cbiAgICpcbiAgICogSWYgdGhlIHJlZ2lzdHJ5IGRvZXMgbm90IGhhdmUgYSBwYXJlbnQgcmVnaXN0cnksIGl0IHdpbGwgcmVnaXN0ZXIgdGhlIHNlcnZpY2UgaW4gdGhlIGN1cnJlbnQgcmVnaXN0cnkuXG4gICAqL1xuICByZWdpc3RlcjxUIGV4dGVuZHMgU2VydmljZT4oaW5pdGlhbGl6ZXI6IFNlcnZpY2VJbml0aWFsaXplcjxUPik6IFQge1xuICAgIGNvbnN0IHBhcmVudFJlZ2lzdHJ5ID0gdGhpcy5nZXRQYXJlbnRSZWdpc3RyeSgpO1xuXG4gICAgaWYgKHBhcmVudFJlZ2lzdHJ5Py5pc0V4cG9zaW5nKGluaXRpYWxpemVyKSkge1xuICAgICAgcmV0dXJuIHBhcmVudFJlZ2lzdHJ5LnJlZ2lzdGVyKGluaXRpYWxpemVyKTtcbiAgICB9XG5cbiAgICBjb25zdCByZWdpc3RyYXRpb24gPSBydW5JblN1YlJvb3QoXG4gICAgICAoKSA9PiB0aGlzLmluaXRpYWxpemVTZXJ2aWNlKGluaXRpYWxpemVyKSxcbiAgICAgIHRoaXMuI293bmVyXG4gICAgKTtcblxuICAgIHRoaXMuI2NhY2hlLnNldChpbml0aWFsaXplciwgcmVnaXN0cmF0aW9uKTtcblxuICAgIHJldHVybiByZWdpc3RyYXRpb247XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNFeHBvc2luZzxUIGV4dGVuZHMgU2VydmljZT4oXG4gICAgaW5pdGlhbGl6ZXI6IFNlcnZpY2VJbml0aWFsaXplcjxUPlxuICApOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy4jY29uZmlnLmV4cG9zZSA9PT0gdHJ1ZSB8fFxuICAgICAgKEFycmF5LmlzQXJyYXkodGhpcy4jY29uZmlnLmV4cG9zZSkgJiZcbiAgICAgICAgdGhpcy4jY29uZmlnLmV4cG9zZT8uaW5jbHVkZXMoaW5pdGlhbGl6ZXIpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGdldFBhcmVudFJlZ2lzdHJ5KCk6IFJlZ2lzdHJ5IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy4jb3duZXI/Lm93bmVyXG4gICAgICA/IHJ1bkluU3ViUm9vdCgoZGlzcG9zZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KFNlcnZpY2VSZWdpc3RyeUNvbnRleHQpO1xuICAgICAgICAgIGRpc3Bvc2UoKTtcbiAgICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICAgICAgfSwgdGhpcy4jb3duZXIub3duZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVNlcnZpY2U8VCBleHRlbmRzIFNlcnZpY2U+KFxuICAgIGluaXRpYWxpemVyOiBTZXJ2aWNlSW5pdGlhbGl6ZXI8VD5cbiAgKTogVCB7XG4gICAgcmV0dXJuIGluaXRpYWxpemVyLnByb3RvdHlwZT8uY29uc3RydWN0b3JcbiAgICAgID8gUmVmbGVjdC5jb25zdHJ1Y3QoaW5pdGlhbGl6ZXIsIFtdKVxuICAgICAgOiAoaW5pdGlhbGl6ZXIgYXMgU2VydmljZUZ1bmN0aW9uPFQ+KSgpO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyByZWdpc3RyeSBmb3Igc2VydmljZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZWdpc3RyeShjb25maWc/OiBSZWdpc3RyeUNvbmZpZyk6IFJlZ2lzdHJ5IHtcbiAgcmV0dXJuIG5ldyBSZWdpc3RyeShjb25maWcpO1xufVxuIl19