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

memconfig

v1.0.0

Published

Manage project-wide configuration from an immutable in-memory store, using a friendly interface powered by lodash's get/set path-like selectors

Downloads

26

Readme

memconfig

npm version minzipped size build status codecov types included

Manage project-wide configuration from an immutable in-memory store, using a friendly interface powered by lodash's get/set path-like selectors.

Table of contents

  1. Motivation
  2. Installation
  3. Usage
  4. API
  5. Best practices

Motivation

I find myself writing the same module in different projects, and the libraries I found are overkill for what I need, so I decided to distribute it as a small package.

And it goes pretty well with merge-files-content Node.JS module!

Installation

Before installing, you need to install lodash by yourself, since it's a peerDependency.

In case your project doesn't already uses it, run npm i lodash.

npm i memconfig

or

yarn add memconfig

Usage

This module works both in the browser and Node.JS environments. Let's see some examples:

Database configs in Node

const { Config } = require('memconfig')

const config = new Config()
config.set('database.port', 3001)
config.get('database').port === 3001 // true
config.get(['database', 'host'], 'default-host') // "default-host"

User UI (serializable) settings in the browser

import { Config } from 'memconfig' // es6 supported!

const config = new Config()
// user enables dark mode
config.set('userSettings.darkMode', true)

// Then you have to persist local settings
localStorage.setItem('ui_config', config.toString())
// The config can be deserialized with the from() method
const config = Config.from(localStorage.getItem('ui_config'))
config.get('userSettings') // {"darkMode": true}

API

🔧 Config

The Config objects accepts an object of settings:

new Config({
  /**
   * If true, every object is going to be clonned in order
   * to prevent side-effect mutations
   */
  immutable: true,
})

🔧 config.setStore(store)

Use config.setStore(yourOwnObject) to initialize it with your app defaults.

🔧 config.freeze()

Freeze the Config instance and prevent new values to be inserted into the store. It shall throw an Error if config.set() is called while config.frozen is true.

Use config.unfreeze() to unfreeze.

⚠️ For Node.JS, it is advisable to use this method once your app starts if you're clustering it, to ensure that nobody tries to mutate configurations at runtime.

🔧 config.get(valuePath, defaultValue)

Internally it uses lodash's get to resolve valuePath keys.

🔧 config.set(valuePath, value)

Internally it uses lodash's set.

🔧 config.merge(obj | Config)

Merges the given object (or instance of Config) into the store.

🔧 config.delete(valuePath)

Internally it uses lodash's unset.

🔧 config.toString()

Same as doing JSON.stringify(config.store).

🔧 Config.from(serializedStore, configSettings)

Static method to create an instance of Config out of a "stringified" store.

Accepts a second parameter to pass settings to the constructor.

Best practices

💎 Don't overuse get and set methods; "get once"

As simple as setting object properties should be, these methods are not linear. That means your program will iterate over many objects when you use valuePaths like level1.level2 or ['level1', 'level2', 'level3'] to access some value in the store

So always try to cache the first levels of the objects you need at module level, and use the values as a normal object. For instance:

DO:

const config = require('../config')

const databaseConfig = config.get('database', { port: 3001 })

const getDatabasePort = () => databaseConfig.port

DON'T:

const config = require('../config')

const getDatabasePort = () => config.get('database.port', 3001)

💎 Clustered apps: "forget about set() at runtime"

Since we're talking about in-memory stores, each instance of your clustered Node.JS app will have its own instance of the Config object, hence you shouldn't use set() anymore after the fork() is done, because the forked processes won't see their config objects updated.

If that's a problem for you, an in-memory store may not be what you're looking for but something like a KVS or such things.

So the implementation should be:

const config = require('./config')
const { config: database } = require('./modules/database')
const { config: storage } = require('./modules/storage')
const app = require('./app')

config.setStore({ database, storage })
// Freeze the store to throw an error if somebody tries to set() something at runtime
config.freeze()

app.start() // now create you app's cluster