Config

SlimIO - Reactive JSON Configuration loader. This package is used in SlimIO core and addons to safely hot reload configuration upon JSON Schema.
Features
- Hot-reloading of configuration
- Reactive with observable key(s)
- Safe with JSON Schema validation
Getting Started
This package is available in the Node Package Repository and can be easily installed with npm or yarn.
$ npm i @slimio/config
$ yarn add @slimio/config
Usage example
Create a simple json file for your project (As below)
{
"loglevel": 5,
"logsize": 4048,
"login": "administrator"
}
Now, create a new Configuration instance and read it
const Config = require("@slimio/config");
async function main() {
const cfg = new Config("./path/to/config.json");
await cfg.read();
console.log(cfg.get("loglevel"));
cfg.observableOf("login").subscribe(console.log);
cfg.set("login", "admin");
console.log(cfg.payload);
await cfg.close();
}
main().catch(console.error);
Note: config.json should exist (if not, it will throw an Error). Look at createOnNoEntry
option for more information !
Events
Configuration class is extended by a Node.js EventEmitter. The class can trigger several events:
event name | description |
---|
configWritten | The configuration payload has been written on the local disk |
watcherInitialized | The file watcher has been initialized (it will hot reload the configuration on modification) |
reload | The configuration has been hot reloaded successfully |
close | Event triggered when the configuration is asked to be closed |
API
This section describe how works the methods of Config class. For a complete definition, take a look at index.d.ts
!
constructor< T > (configFilePath: string, options?: Config.Options)
Create a new Config Object:
const cfg = new Config("./path/to/file.json", {
createOnNoEntry: true,
autoReload: true
});
Available options are:
name | type | default value | description |
---|
createOnNoEntry | boolean | false | Create the file with default payload value if he doesn't exist on the local disk |
writeOnSet | boolean | false | Write the file on the disk after each time .set() is called |
autoReload | boolean | false | Setup hot reload of the configuration file |
reloadDelay | number | 500ms | The delay to wait before hot reloading the configuration, it's a security to avoid event spamming |
defaultSchema | plainObject | null | The default JSON Schema for the configuration |
Note: When no schema is provided, it will search for a file prefixed by .schema
with the same config name.
read (defaultPayload?: T): Promise< this >
Will trigger and read the local configuration (on disk). A default payload
value can be provided in case the file doesn't exist !
const { strictEqual } = require("assert");
const cfg = new Config("./path/to/file.json");
strictEqual(cfg.configHasBeenRead, false);
await cfg.read();
strictEqual(cfg.configHasBeenRead, true);
Retriggering the method will made an hot-reload of all properties. For a cold reload you will have to close the configuration before.
Warning When the file doesn't exist, the configuration is written at the next loop iteration (with lazyWriteOnDisk).

setupAutoReload (): void
Setup hot reload (with a file watcher). This method is automatically triggered if the Configuration has been created with the option autoReload
set to true.
We use the package node-watch to achieve the hot reload.
get< H > (fieldPath: string, depth?: number): H
Get a value from a key (fieldPath). For example, let take a json payload with a root foo
field.
const cfg = new Config("./path/to/file.json");
await cfg.read();
const fooValue = cfg.get("foo");
Under the hood the method work with lodash.get
function.
If the retrieved value is a JavaScript object, you can limit the depth by setting depth
option.
set< H > (fieldPath: string, fieldValue: H): void
Set a given field in the configuration.
const cfg = new Config("./config.json", {
createOnNoEntry: true
});
await cfg.read({ foo: "bar" });
cfg.set("foo", "hello world!");
await cfg.writeOnDisk();
Under the hood the method work with lodash.set
function.
observableOf (fieldPath: string, depth?: number): ObservableLike
Observe a given configuration key with an Observable Like object!
const { writeFile } = require("fs").promises;
const cfg = new Config("./config.json", {
autoReload: true,
createOnNoEntry: true
});
await cfg.read({ foo: "bar" });
cfg.observableOf("foo").subscribe(console.log);
const newPayload = { foo: "world" };
await writeFile("./config.json", JSON.stringify(newPayload, null, 4));
writeOnDisk (): Promise< void >
Write the configuration on the disk.
lazyWriteOnDisk (): void
Write the configuration on the disk (only at the next event-loop iteration). Use the event configWritten
to known when the configuration will be written.
const cfg = new Config("./config.json", {
createOnNoEntry: true
});
await cfg.read();
cfg.once("configWritten", () => {
console.log("Configuration written!");
});
cfg.lazyWriteOnDisk();
close (): Promise< void >
Close (and write on disk) the configuration (it will close the watcher and complete/clean all active observers subscribers).
Properties
Following properties are static members of Config class.
STRINGIFY_SPACE
The `STRINGIFY_SPACE` property allow you to redine the espace used internaly for `JSON.stringify` method. The default value is **4**.
DEFAULT_SCHEMA
The `DEFAULT_SCHEMA` property allow you to redefine the default schema that should be applied if no schema is provided when constructor is triggered!
The default value is the following Object:
{
title: "CONFIG",
additionalProperties: true
}
Licence
MIT