@wider/registry
WIDER modules make significant use of each other. They are published individually as many are of use to the community on a stand alone basis.
The way npm works, it is possible for the same module to be loaded multiple times (same or different versions) from different installed packages within a project and thus if they have what is intended to be working data that spans all activity within the project then the integrity required of a single instance for you thread/cluster is lost.
If you have the same problems then this will assist you to identify when the problem arises. Used basically as a registry then you add some lines of code to each module - there is no other impact to your code unless an issue is identified. If you use the advanced features you can avoid using import/require and access your registered modules directly from a cache.
Any module that wants to ensure that it is instantiated only once (per thread/cluster) may invoke this tool which does the following
- ensures that this tool itself is not loaded multiple times
- throws an
Error.code === "INVALID_MODULE_NAME"
if the request does not register a valid module - detects if the named module has already been loaded and throws an
Error.code === "DUPLICATE_CALL"
if this is a duplicate.
Errors are logged to the console before being thrown. You can choose to handle the error or let it bubble so that the app exits. All errors have a property called .code
which is a programming oriented code if your app wishes to analyse problems.
Documentation
Install
npm install @wider/utils_require
Basic Use
//ES
import register from "@wider/registry";
const $moduleName = "my-module-name";
register($moduleName);
// commonJS
const register = require("@wider/registry");
const $moduleName = "my-module-name";
register($moduleName);
Soft registration
With this mode, you do not add the registry to your dependencies at all nor do you import or require it. Your module package can be distributed without the overheads. If another package loads the registry, such as the applications main module, then your package will register. Put this at the very start of your code
if (global.$wider)
process.nextTick(()) => { $wider.registry.register( ... )}
This approach is assured with es modules. If you are running commonjs modules
Advanced use
With advanced use, you also provide your object that is being registered and may choose to influence where how is cached and accessed. We illustrate creating the object using require but any means may be used to create the value to be processed.
const $moduleName = "somethingOrOther";
const sOO = require($moduleName);
const $wider = register($moduleName, sOO); // gives you $wider.somethingOrOther
The dictionary $wider will contain at least $wider.register
and $wider.somethingOrOther
. The $wider object will acquire new members as new objects are registered.
If you use @wider/utils_bundler, those objects will also be registered and appear within $wider. In this case, the objects can be configured to be loaded just in time if they are actually used - thus allowing you to create a large registry but without the overheads of all the entries being loaded into memory.
You may choose to save your object in a specific section in the repository so as to maintain an orderly structure.
const $wider = registry.register($moduleName, sOO, "sOOname"); // gives you $wider.sOOname;
const $wider = registry.register($moduleName, sOO, "sOOname", "mySection"); // gives you $wider.mySection.sOOname;
Using imported or required modules
If imported or require other modules, you should leave it to them to register themselves. If however they are third party objects, then they won't have registered themselves. If you wish them to be registered, then you can call registry.register()
as their proxy. Provided you ensure that you do not try and register the same module twice (throws an error, you can check in $wider) you may use the various methods already given.
You may also submit an array of objects to be submitted
registry.register([module1, module2, module3 ...]); //loaded them at the top level
registry.register([module1, module2, module3 ...], null, null, "mySection") // loads them into the named section
To use this approach, each module must at least have the property $moduleName
and optionally the property $objectName
. If they are absent,most foreign objects will accept you injecting these values so you can then register the object or you can wrap them in a container.
Supplementary Properties
registry.bundle()
act as proxy to submit a bundle of other packages that do not register themselvesregistry.merge()
merge new properties into an existing registered bundleregistry.find()
given a moduleName retrieves its objectregistry.describe_loaded()
a markdown like string documenting the registered modules and their access pointsregistry.describe_published()
an markdown like string documenting the top level structure of $wider and its sections.registry.DICTIONARY
a symbol that can be used in a plain object to mark it as containing documentable properties when seen viaregistry.describe_published()
. Used as a property value{ $registry: registry.DICTIONARY}
or in a json file as{ $registry: "DICTIONARY" }
registry.ROOT
can be used as the moduleName for the root (ie not a section) level of @wider. Use with care as using this increases the risks of name conflicts with later releases.
const $moduleName = "somethingOrOther";
// register as previous example
const registry = $wider.registry;
const sOOE = [
addition1: {...something1...},
addition2: {...something2...}
];
// add the SOOE members to sOOname
registry.bundle(sOOE, "sOOname")
This might result in
$wider
.sOOName
.initialEntry1
.initialEntry2
.addition1
.addition2