npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

asma

v1.6.4

Published

A settings manager for node.js

Downloads

4

Readme

#ASMa

A settings manager for node.js

Usage

const settings = require('asma');

settings.addScope('/path/to/main.json')
.sync()
.then(() => {
    var setting1 = settings.scope('main').key('setting-1').default('some default value');
    console.log(setting1.value());
})

If "main.json" does not exists, the above will log "some default value". Otherwise it will log the value as stored in the file. E.g.: main.json

{
    "setting-1" : "the real value",
    "setting-2" : 2,
    "setting-3" : "1,2,3"
}

Given the above file, the following will happen:

var setting1 = settings.scope('main').key('setting-1').default('some default value');
var setting2 = settings.scope('main').key('setting-2').default(222);
var setting3 = settings.scope('main').key('setting-3').default('3,4,5');
var setting4 = settings.scope('main').key('setting-4').default('some other default value');


console.log(setting1.value())
// "the real value"

console.log(setting2.value())
// 2

console.log(setting3.value())
// "1,2,3"

console.log(setting4.value())
// "some other default value"

File changes and setCacheTime()

Every time value() is called on a key, a check on the scope file is scheduled. This means that if the file changes during the execution of the application, the change is reflected in the internal data structure of the settings object. The file is read only if it was modified since last synchronization. This happens asynchronously and transparently, with a caching time during which any check is suspended. This cache time (default 5 minutes) prevents filesystem operations to happen too often and can be configured by calling setCacheTime() on the scope:

const settings = require('asma');
settings.scope('main').setCacheTime(2000); // 2000 milliseconds

Note: since the synchronization happens asynchronously after invoking value(), the updated value is available always with a one-invocation delay!

Obviously: don't store the value

If you store the return value of value(), you lose the synchronization with the file!

const setting1 = settings.scope('main').key('setting-1').value() // WRONG!

Scopes

You can add as many scopes as you like:

const settings = require('asma');

settings
.addScope('/path/to/main.json')
.addScope('/another/path/to/other.json')
.addScope('/yet/another/path/to/other.json', 'other2')
.sync()
.then(() => {
    console.log('all scopes synchronized')
})

By default the scope name is the base name of the file without extension. To set an arbitrary name, pass it as as second argument to addScope() (see example above).

Single scope

In case of a single scope, it is possible to call key() directly on the main settings object;

settings.addScope('/path/to/main.json')
.sync()
.then(() => {
    console.log(settings.key('some-key').value());
})

However this approach is discouraged, as a later addition of a second scope will require refactoring all existing calls.

API reference

Settings

Settings.addScope(pathToFile[, scopeName])

Adds a scope linked to a file. Throws an error if a scope with the same name already exists. Returns reference to the Settings object to enable call chaining.

Settings.sync()

Reads values from all scope files, if they exists. Returns a Promise that is always resolved.

Settings.scope(scopeName)

Returns the scope with name scopeName.

Settings.key(keyName)

Returns the key with name keyName. Only works if a single scope is added. Throws error if multiple scopes exist.

Scope

Scope.key(keyName)

Returns the specified key or creates it if it doesn't exist.

Scope.setCacheTime(timeMs)

Sets the cache time in milliseconds. This is the time between successive file checks (and reads, if file was modified). Returns reference to the Scope object.

Key

Key.value()

Returns the value of the key. Defaults to null if no default was set and the key was not found in the scope file.

Key.valueSet()

Whether the value was set (either via default() of retrieved from file). If false, value() returns null.

Key.default(defaultValue)

Sets the default value for the key. If a transformation is set (either before or after), this value is transformed.

Key.transform(transformFunction)

Enables the pre-processing of a value. E.g.:

const setting1 = settings.scope('main')
                         .default('1,2,3')
                         .transform(val => val.split(','));

console.log(setting1.value())
// [1,2,3]

This transformation is applied also to the default value.