Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Enmap stands for "Enhanced Map", and is a data structure based on the native JavaScript Map() structure with additional helper methods from the native Array() structure.
Enmap also offers persistence, which means it will automatically save everything to save to it in a database, in the background, without any additional code or delays.
While there are other better-known systems that offer some features of Enmap, especially caching in memory, Enmap is targetted specifically to newer users of JavaScript that might not want to deal with complicated systems like Redis for caching, or database queries.
Here are some advantages of using Enmap:
Simple to Install: Enmap itself only requires a simple npm install
command to install and use, and a single line to initialize. When using persistent providers, some additional pre-requisites are necessary. See Installation for details.
Simple to Use: Basic enmap usage can be completely done with 1-2 lines of initalization, and 3 commands, set(), get() and delete().
Very Fast: Since Enmap resides in memory, accessing its data is blazing fast (as fast as Map() is). Even with persistence, Enmap still only accesses data from memory so you get it almost instantly.
Some disadvantages, compared to using a database connection directly:
More memory use: Since Enmap resides in memory and (by default) all its data is loaded when it starts, your entire data resides in RAM. When using a large amount of data on a low-end computer or VPS, this might be an issue for some users.
Limited power: You can have multiple Enmap "tables" loaded in your app, but they do not and cannot have relationships between them. Basically, one enmap value can't refer to another value in another enmap. This is something databases can be very good at, but due to the simplistic nature of Enmap, it's not possible here.
Lack of scalability: Enmap is great for small apps that require a simple key/value storage. However, a scalable app spread over multiple processes, shards, or clusters, will be severely limited by Enmap as it cannot update itself from the database on change - one process would not be aware of another process' changes.
To account for people that might use a large number of enmaps in the same project, I've created a new `multi()` method that can be used to instanciate multiple peristent enmaps together.
The method takes 3 arguments:
An array
of names for the enmaps to be created.
A Provider (not instanciated), from any of the available ones.
An options
object containing any of the options needed to instanciate the provider. Do not add name
to this, as it will use the names in the array instead.
Below, an example that uses destructuring:
Now that we have a functional Enmap structure (which we'll always refer to as myEnmap
), we're ready to start writing data to it, and getting data from it.
The code samples on this page assume that you have correctly initialized
myEnmap
, and awaited its initialization if it's persistent.
In terms of Enmap, "writing", "adding" and "editing" data is essentially the same thing. When using the basic set()
method, if the key does not exist it's created, and if it does, it's modified.
Enmap supports most native JavaScript data types, with a few small exceptions.
Complex objects like Set()
, Map()
, etc, are not supported.
Class instances and Functions are not supported.
As a general rule, except for null and undefined, anything that can be handled by JSON.stringify()
will work as expected in Enmap. This includes:
String
Number
Integer
Boolean
Object
Array
Objects and Arrays are a little more complex to deal with, so they have their own page. See Working with Objects for more information.
The usage for the set()
method is simple:
key
must be a string or integer. A key should be unique, otherwise it will be overwritten by new values using the same key.
value
must be a supported native data type as mentioned above.
Here are a few examples of writing simple data values:
Getting data back from an Enmap is just as simple as writing to it. All you need is the key
of what you want to retrieve, and you get its value back!
That's pretty much it for only retrieiving a single data value. There are more complex operations that are available, take a look at Array Methods for the more advanced things you can do on Enmap's data!
Enmap v3 is no longer maintained on NPM and is only available on Github. You will need to install a git tool on your computer to install it.
Next, enmap has a specific pre-requisite which is needed for the sqlite dependency. How to install these depends on your operating system, so see below for instructions:
To install Enmap in your project, all you need to to is run the following command in your project folder:
This may take a few minutes, then you're ready to use it.
In order to install Enmap, you'll need a few things installed on your machine. First off, you need NodeJS (version 8 or higher required). For Windows and MacOS, simply. For Linux, see .
On Windows, two things are required to install enmap-sqlite. Python 2.7 and the Visual Studio C++ Build Tools. They are required for any module that is built on the system, which includes sqlite.
The Windows Built Tools require over 3GB of space to install and use. Make sure you have enough space before starting this download and install!
To install the necessary pre-requisites on Windows, the easiest is to simply run the following command, under an administrative command prompt or powershell:
It's very important that this be run in the administrative prompt, and not a regular one.
Once the windows-build-tools are installed (this might take quite some time, depending on your internet connection), close all open command prompts, powershell windows, and editors with a built-in console/prompt. Otherwise, the next command will not work.
On Linux, the pre-requisites are much simpler in a way. A lot of modern systems (such as Ubuntu, since 16.04) already come with python 2.7 pre-installed. For some other systems, you might have to fiddle with it to either get python 2.7 installed, or to install both 2.7 and 3.x simultaneously. Google will be your friend.
As for the C++ build tools, that's installed using the simple command: sudo apt-get install build-essential
for most debian-based systems. For others, look towards your package manager and specificall "GCC build tools". Your mileage may vary but hey, you're using Linux, you should know this stuff.
As of writing this page, MacOS versions seem to all come pre-built with Python 2.7 on the system. You will, however, need the C++ build tools.
Install
Once XCode is installed, go to Preferences, Downloads, and install the Command Line Tools.
Once installed, you're ready to continue.
Persistence requires an additional Provider module.
Official Enmap Providers:
Enmap-SQLite: Recommended, supports sharding locally.
Enmap-Rethink: Best for sharding if you can install a rethinkdb server. Supports updating from the database on all shards (enmap-rethink 2.1.0 and higher)
Enmap-PGSQL: Postgresql database provider. Supports Sharding.
Enmap-Mongo: Mongodb database provider. Supports Sharding.
Enmap-Level: Sort of not recommended at this point, doesn't support sharding, no longer the most efficient/faster provider.
When using any provider, it's very important to understand that it takes time to load the data from the database. Certain providers also take some time to even open the database connection, and that's also something to consider.
To make sure that all your data is loaded before you start working, Enmap provides a handy property called defer
, which is a promise that is resolved once the provider is ready and all the data has been loaded into memory. There are a few ways to use defer
, since it's a promise.
As described in the home page, one disadvantage of Enmap is that it loads all your data in memory, so you're sacrificing RAM in order to gain speed. In larger projects, this might become a concern fairly quickly - or when using larger data sets that take more memory.
For this purpose, I surrepticiously added a new option somewhere around Enmap 2.0 called "fetchAll", which defaults to "true" if you don't specify it - which is the old behaviour, and current default at the same time. But, if you set fetchAll
to false
in the Enmap options, data is not fetched on load.
If fetchAll is set to false, no data (by default) will be loaded from the database - the Enmap will be completely empty. This means that doing a .size
check returns 0, looping and filtering doesn't return anything, and get() requests all return null.
Ok but... how's that useful? It's useful because if you don't need the data, it's not loaded. To load data, there are 2 different methods available.
enmap.fetchEverything()
will, of course, fetch all the data from the database - this is the method that's called on init() if fetchAll is true. This means you can stagger your loading time, or that you can decide, later, under certain conditions, you do want to load everything.
enmap.fetch(key)
can fetch a single key from the database, saves it to enmap, and returns a promise with the fetched value.
enmap.fetch([array, of, keys])
will fetch each key in the requested array, and return an array of [key, value]
pairs for each fetched value.
Yup. Those are the only things you really need to know for the current version of Enmap's fetchAll feature.
I'm working on the following features in future versions of enmap, related to fetch methods:
Add the ability to check if the DB has a key without fetching
Add a method to uncache a key from enmap
Add a method to count keys in the DB (like enmap.keyCount() maybe?)
Figure out how to "fetch on query" without breaking the nonblocking nature of enmap.
This page is a work in progress and may not have the polish of a usual Evie-Written document!
Some quick docs:
Possible Operators (accepts all variations listed below, as strings):
+
, add
, addition
: Increments the value in the enmap by the provided value.
-
, sub
, subtract
: Decrements the value in the enmap by the provided value.
*
, mult
, multiply
: Multiply the value in the enmap by the provided value.
/
, div
, divide
: Divide the value in the enmap by the provided value.
%
, mod
, modulo
: Gets the modulo of the value in the enmap by the provided value.
^
, exp
, exponential
: Raises the value in the enmap by the power of the provided value.
Enmap is a great way to store structured data, and offers a few helper features that directly affect both objects and arrays.
Let's assume for a moment that we want to store the following data structure in Enmap:
This structure has 5 "properties": first
, second
, changeme
, isCool
, sub
. The sub
property has 2 properties of its own, yay
and thing
.
To store this structure in Enmap, you can use a variable, or just straight-up write the object:
Note: All further methods require the value to be an object. If you attempt to get, set, modify or remove using the below methods and your value isn't an object, Enmap will throw an error.
Retrieving a specific property from an object is done through the get()
method, by specifying both the key and the "path" to the property you want.
The exact method is <Enmap>.get(key, path)
.
You can also check if a specific property exists or not. This is done through the has
method, with a key, and path to the property:
There are a few various ways to modify properties of both Objects and Arrays. The very basic way to set a property on an object or array is through .set(key, value, path)
like the following examples:
As you can see, setProp() and getProp() work on the same concept that the path can be as complex as you want.
While Enmap is a Map enhanced with Array methods, Enmap also offers some enhanced array methods for the data stored inside of it. Talk about ArrayCeption!
So what do I mean by methods for your stored data? I mean that you can store arrays inside Enmap, and directly push, pull, add and remove from those arrays. There are methods to work both on direct arrays, as well as arrays stored inside of an object.
Let's take a look at two example entries in enmap that we can use. The first is a direct array, the second is an array inside an object.
There are two methods to push to an array, one for simple arrays and one for arrays inside objects. Pushing in an enmap array is the same as a regular array push: it adds the element to the end of the array.
Similarly, you can remove from an array. Note, however, that this will only work if you're removing a string or number. Removing an object from an array is not supported.
Arrays have additional helper methods, .
The second parameter in pushIn is the "path" to the array in an object. It works the same as the properties path used in .
Inside your script, initialize a new Enmap:
Map
A enhanced Map structure with additional utility methods. Can be made persistent
Kind: global class
Extends: Map
Enmap ⇐ Map
instance
.fetchEverything() ⇒ Promise.
.fetch(keyOrKeys) ⇒ Promise.
.autonum() ⇒ number
.set(key, val, path) ⇒ Map
.setProp(key, path, val) ⇒ Map
.inc(key, path) ⇒ Map
.dec(key, path) ⇒ Map
.get(key, path) ⇒ *
.has(key, path) ⇒ boolean
.hasProp(key, path) ⇒ boolean
.remove(key, val, path) ⇒ Map
.array() ⇒ Array
.keyArray() ⇒ Array
.random([count]) ⇒ *
| Array.
.randomKey([count]) ⇒ *
| Array.
.findAll(prop, value) ⇒ Array
.exists(prop, value) ⇒ boolean
.filterArray(fn, [thisArg]) ⇒ Array
.map(fn, [thisArg]) ⇒ Array
.some(fn, [thisArg]) ⇒ boolean
.every(fn, [thisArg]) ⇒ boolean
.equals(enmap) ⇒ boolean
static
.multi(names, Provider, options) ⇒ Array.
Promise.
Fetches every key from the persistent enmap and loads them into the current enmap value.
Kind: instance method of Enmap
Returns: Promise.
- The enmap containing all values, as a promise..
Promise.
Force fetch one or more key values from the enmap. If the database has changed, that new value is used.
Kind: instance method of Enmap
Returns: Promise.
- A single value if requested, or a non-persistent enmap of keys if an array is requested.
Param
Type
Description
keyOrKeys
string
| number
A single key or array of keys to force fetch from the enmap database.
Removes a key from the cache - useful when using the fetchAll feature.
Kind: instance method of Enmap
Param
Type
Description
keyOrArrayOfKeys
*
A single key or array of keys to remove from the cache.
number
Generates an automatic numerical key for inserting a new value.
Kind: instance method of Enmap
Returns: number
- The generated key number.
Example
Function called whenever data changes within Enmap after the initial load. Can be used to detect if another part of your code changed a value in enmap and react on it.
Kind: instance method of Enmap
Param
Type
Description
cb
function
A callback function that will be called whenever data changes in the enmap.
Example
Map
Set the value in Enmap.
Kind: instance method of Enmap
Returns: Map
- The Enmap.
Param
Type
Default
Description
key
string
| number
Required. The key of the element to add to The Enmap. If the Enmap is persistent this value MUST be a string or number.
val
*
Required. The value of the element to add to The Enmap. If the Enmap is persistent this value MUST be stringifiable as JSON.
path
string
null
Optional. The path to the property to modify inside the value object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Example
Map
Modify the property of a value inside the enmap, if the value is an object or array. This is a shortcut to loading the key, changing the value, and setting it back.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Description
key
string
| number
Required. The key of the element to add to The Enmap or array. This value MUST be a string or number.
path
*
Required. The property to modify inside the value object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
val
*
Required. The value to apply to the specified property.
Map
Push to an array value in Enmap.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
Required. The key of the array element to push to in Enmap. This value MUST be a string or number.
val
*
Required. The value to push to the array.
path
string
null
Optional. The path to the property to modify inside the value object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
allowDupes
boolean
false
Optional. Allow duplicate values in the array (default: false).
Example
Map
Push to an array element inside an Object or Array element in Enmap.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
Required. The key of the element. This value MUST be a string or number.
path
*
Required. The name of the array property to push to. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
val
*
Required. The value push to the array property.
allowDupes
boolean
false
Allow duplicate values in the array (default: false).
Map
Executes a mathematical operation on a value and saves it in the enmap.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
The enmap key on which to execute the math operation.
operation
string
Which mathematical operation to execute. Supports most math ops: =, -, *, /, %, ^, and english spelling of those operations.
operand
number
The right operand of the operation.
path
string
null
Optional. The property path to execute the operation on, if the value is an object or array.
Example
Map
Increments a key's value or property by 1. Value must be a number, or a path to a number.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
The enmap key where the value to increment is stored.
path
string
null
Optional. The property path to increment, if the value is an object or array.
Example
Map
Decrements a key's value or property by 1. Value must be a number, or a path to a number.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
The enmap key where the value to decrement is stored.
path
string
null
Optional. The property path to decrement, if the value is an object or array.
Example
*
Retrieves a key from the enmap. If fetchAll is false, returns a promise.
Kind: instance method of Enmap
Returns: *
- The value for this key.
Param
Type
Default
Description
key
string
| number
The key to retrieve from the enmap.
path
string
null
Optional. The property to retrieve from the object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Example
*
Returns the specific property within a stored value. If the key does not exist or the value is not an object, throws an error.
Kind: instance method of Enmap
Returns: *
- The value of the property obtained.
Param
Type
Description
key
string
| number
Required. The key of the element to get from The Enmap.
path
*
Required. The property to retrieve from the object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
boolean
Returns whether or not the key exists in the Enmap.
Kind: instance method of Enmap
Param
Type
Default
Description
key
string
| number
Required. The key of the element to add to The Enmap or array. This value MUST be a string or number.
path
string
null
Optional. The property to verify inside the value object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Example
boolean
Returns whether or not the property exists within an object or array value in enmap.
Kind: instance method of Enmap
Returns: boolean
- Whether the property exists.
Param
Type
Description
key
string
| number
Required. The key of the element to check in the Enmap or array.
path
*
Required. The property to verify inside the value object or array. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Deletes a key in the Enmap.
Kind: instance method of Enmap
Param
Type
Default
Description
key
string
| number
Required. The key of the element to delete from The Enmap.
path
string
null
Optional. The name of the property to remove from the object. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Delete a property from an object or array value in Enmap.
Kind: instance method of Enmap
Param
Type
Description
key
string
| number
Required. The key of the element to delete the property from in Enmap.
path
*
Required. The name of the property to remove from the object. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
Calls the delete()
method on all items that have it.
Kind: instance method of Enmap
Param
Type
Default
Description
bulk
boolean
true
Optional. Defaults to True. whether to use the provider's "bulk" delete feature if it has one.
Map
Remove a value in an Array or Object element in Enmap. Note that this only works for values, not keys. Complex values such as objects and arrays will not be removed this way.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Default
Description
key
string
| number
Required. The key of the element to remove from in Enmap. This value MUST be a string or number.
val
*
Required. The value to remove from the array or object.
path
string
null
Optional. The name of the array property to remove from. Can be a path with dot notation, such as "prop1.subprop2.subprop3". If not presents, removes directly from the value.
Map
Remove a value from an Array or Object property inside an Array or Object element in Enmap. Confusing? Sure is.
Kind: instance method of Enmap
Returns: Map
- The EnMap.
Param
Type
Description
key
string
| number
Required. The key of the element. This value MUST be a string or number.
path
*
Required. The name of the array property to remove from. Can be a path with dot notation, such as "prop1.subprop2.subprop3"
val
*
Required. The value to remove from the array property.
Array
Creates an ordered array of the values of this Enmap. The array will only be reconstructed if an item is added to or removed from the Enmap, or if you change the length of the array itself. If you don't want this caching behaviour, use Array.from(enmap.values())
instead.
Kind: instance method of Enmap
Array
Creates an ordered array of the keys of this Enmap The array will only be reconstructed if an item is added to or removed from the Enmap, or if you change the length of the array itself. If you don't want this caching behaviour, use Array.from(enmap.keys())
instead.
Kind: instance method of Enmap
*
| Array.
Obtains random value(s) from this Enmap. This relies on array.
Kind: instance method of Enmap
Returns: *
| Array.
- The single value if count
is undefined, or an array of values of count
length
Param
Type
Description
[count]
number
Number of values to obtain randomly
*
| Array.
Obtains random key(s) from this Enmap. This relies on keyArray
Kind: instance method of Enmap
Returns: *
| Array.
- The single key if count
is undefined, or an array of keys of count
length
Param
Type
Description
[count]
number
Number of keys to obtain randomly
Array
Searches for all items where their specified property's value is identical to the given value (item[prop] === value
).
Kind: instance method of Enmap
Param
Type
Description
prop
string
The property to test against
value
*
The expected value
Example
*
Searches for a single item where its specified property's value is identical to the given value (item[prop] === value
), or the given function returns a truthy value. In the latter case, this is identical to Array.find().
All Enmap used in Discord.js are mapped using their `id` property, and if you want to find by id you should use the `get` method. See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) for details.
Kind: instance method of Enmap
Param
Type
Description
propOrFn
string
| function
The property to test against, or the function to test with
[value]
*
The expected value - only applicable and required if using a property for the first argument
Example
Example
boolean
Searches for the existence of a single item where its specified property's value is identical to the given value (item[prop] === value
).
Do not use this to check for an item by its ID. Instead, use `enmap.has(id)`. See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) for details.
Kind: instance method of Enmap
Param
Type
Description
prop
string
The property to test against
value
*
The expected value
Example
Enmap
Identical to Array.filter(), but returns a Enmap instead of an Array.
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function used to test (should return a boolean)
[thisArg]
Object
Value to use as this
when executing function
Array
Identical to Array.filter().
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function used to test (should return a boolean)
[thisArg]
Object
Value to use as this
when executing function
Array
Identical to Array.map().
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function that produces an element of the new array, taking three arguments
[thisArg]
*
Value to use as this
when executing function
boolean
Identical to Array.some().
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function used to test (should return a boolean)
[thisArg]
Object
Value to use as this
when executing function
boolean
Identical to Array.every().
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function used to test (should return a boolean)
[thisArg]
Object
Value to use as this
when executing function
*
Identical to Array.reduce().
Kind: instance method of Enmap
Param
Type
Description
fn
function
Function used to reduce, taking four arguments; accumulator
, currentValue
, currentKey
, and enmap
[initialValue]
*
Starting value for the accumulator
Enmap
Creates an identical shallow copy of this Enmap.
Kind: instance method of Enmap
Example
Enmap
Combines this Enmap with others into a new Enmap. None of the source Enmaps are modified.
Kind: instance method of Enmap
Param
Type
Description
...enmaps
Enmaps to merge
Example
boolean
Checks if this Enmap shares identical key-value pairings with another. This is different to checking for equality using equal-signs, because the Enmaps may be different objects, but contain the same data.
Kind: instance method of Enmap
Returns: boolean
- Whether the Enmaps have identical contents
Param
Type
Description
enmap
Enmap to compare with
Array.
Initialize multiple Enmaps easily.
Kind: static method of Enmap
Returns: Array.
- An array of initialized Enmaps.
Param
Type
Description
names
Array.
Array of strings. Each array entry will create a separate enmap with that name.
Provider
EnmapProvider
Valid EnmapProvider object.
options
Object
Options object to pass to the provider. See provider documentation for its options.
Example
Migrates an Enmap from version 3 or lower to a Version 4 enmap, which is locked to sqlite backend only. Version 4 uses a different way of storing data, so is not directly compatible with version 3 data. Note that this migration also makes the data unuseable with version 3, so it should only be used to migrate once.
Kind: static method of Enmap
Param
Type
Description
source
Provider
A valid Enmap provider. Can be any existing provider.
target
Provider
An SQLite Enmap Provider. Cannot work without enmap-sqlite as the target.
Example