JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 57
  • Score
    100M100P100Q70764F
  • License MIT

SlimIO Reactive JSON Config loaded

Package Exports

  • @slimio/config

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@slimio/config) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Config

Maintenance GitHub license Known Vulnerabilities CircleCI Greenkeeper badge

SlimIO - Reactive JSON Config loader

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
# or
$ 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")); // stdout: 5

    // Observe (with an Observable Like) the update made to login property
    cfg.observableOf("login").subscribe(console.log);
    cfg.set("login", "admin");

    // Payload getter will return a deepClone with all configuration properties
    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

constructor< T >(configFilePath: string, options?: Config.ConstructorOptions)

Create a new Configuration instance

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); // true
await cfg.read();
strictEqual(cfg.configHasBeenRead, true); // 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 (field path).

For example, image a json file with a 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" });

// Observe initial and next value(s) of foo
cfg.observableOf("foo").subscribe(console.log);

// Re-write local config file
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

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
}