Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

semver-store

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

semver-store - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

59

bench.js

@@ -6,28 +6,51 @@ 'use strict'

const semver = require('semver')
const store = require('./index')()
store.set('1.2.3', null)
const SemVerStore = require('./index')
const store1 = SemVerStore()
const store2 = SemVerStore()
store2
.set('1.1.1', 1)
.set('1.1.2', 1)
.set('1.1.3', 1)
.set('1.2.1', 1)
.set('1.2.2', 1)
.set('1.2.3', 1)
.set('2.1.1', 1)
.set('2.1.2', 1)
.set('2.1.3', 1)
.set('3.2.1', 1)
.set('3.2.2', 1)
.set('3.2.3', 1)
suite
.add('semver-store - full', function () {
store.get('1.2.3')
.add('set', function () {
store1.set('1.2.3', 1)
})
.add('semver - full', function () {
semver.satisfies('1.2.3', '1.2.3')
.add('get', function () {
store1.get('1.2.3')
})
.add('semver-store - wildcard', function () {
store.get('1.x')
.add('get (minor wildcard)', function () {
store1.get('1.x')
})
.add('semver - wildcard', function () {
semver.satisfies('1.2.3', '1.x')
.add('get (patch wildcard)', function () {
store1.get('1.2.x')
})
.add('semver-store - no patch', function () {
store.get('1.2')
.add('del + set', function () {
store1.del('1.2.3')
store1.set('1.2.3', 1)
})
.add('semver - no patch', function () {
semver.satisfies('1.2.3', '1.2')
.add('del (minor wildcard) + set', function () {
store1.del('1.x')
store1.set('1.2.3', 1)
})
.add('del (patch wildcard) + set', function () {
store1.del('1.2.x')
store1.set('1.2.3', 1)
})
.add('set with other keys already present', function () {
store2.set('1.2.4', 1)
})
.add('get with other keys already present', function () {
store2.get('1.2.4')
})
.on('cycle', function (event) {

@@ -34,0 +57,0 @@ console.log(String(event.target))

@@ -10,24 +10,25 @@ 'use strict'

SemVerStore.prototype.set = function (semverString, store) {
SemVerStore.prototype.set = function (version, store) {
var currentNode = this.tree
semverString = semverString.split('.')
while (semverString.length) {
const node = new Node(semverString.shift())
currentNode = currentNode.addChild(node)
continue
version = version.split('.')
while (version.length) {
currentNode = currentNode.addChild(
new Node(version.shift())
)
}
currentNode.setStore(store)
return this
}
SemVerStore.prototype.get = function (semverString) {
SemVerStore.prototype.get = function (version) {
var node = this.tree
var firstDot = semverString.indexOf('.')
var secondDot = semverString.indexOf('.', firstDot + 1)
var major = semverString.slice(0, firstDot)
var firstDot = version.indexOf('.')
var secondDot = version.indexOf('.', firstDot + 1)
var major = version.slice(0, firstDot)
var minor = secondDot === -1
? semverString.slice(firstDot + 1)
: semverString.slice(firstDot + 1, secondDot + 1)
? version.slice(firstDot + 1)
: version.slice(firstDot + 1, secondDot)
var patch = secondDot === -1
? 'x'
: semverString.slice(secondDot + 1)
: version.slice(secondDot + 1)

@@ -43,2 +44,64 @@ node = node.getChild(major)

SemVerStore.prototype.del = function (version) {
var firstDot = version.indexOf('.')
var secondDot = version.indexOf('.', firstDot + 1)
var major = version.slice(0, firstDot)
var minor = secondDot === -1
? version.slice(firstDot + 1)
: version.slice(firstDot + 1, secondDot)
var patch = secondDot === -1
? 'x'
: version.slice(secondDot + 1)
// check existence of major node
var majorNode = this.tree.children[major]
if (majorNode == null) return this
// if minor is the wildcard, then remove the full major node
if (minor === 'x') {
this.tree.removeChild(major)
return this
}
// check existence of minor node
var minorNode = majorNode.children[minor]
if (minorNode == null) return this
// if patch is the wildcard, then remove the full minor node
// and also the major if there are no more children
if (patch === 'x') {
this.tree.children[major].removeChild(minor)
if (this.tree.children[major].length === 0) {
this.tree.removeChild(major)
}
return this
}
// check existence of patch node
var patchNode = minorNode.children[patch]
if (patchNode == null) return this
// Specific delete
this.tree
.children[major]
.children[minor]
.removeChild(patch)
// check if the minor node has no more children, if so removes it
// same for the major node
if (this.tree.children[major].children[minor].length === 0) {
this.tree.children[major].removeChild(minor)
if (this.tree.children[major].length === 0) {
this.tree.removeChild(major)
}
}
return this
}
SemVerStore.prototype.empty = function () {
this.tree = new Node()
return this
}
function Node (prefix, children, store) {

@@ -54,6 +117,6 @@ this.prefix = Number(prefix) || 0

if (prefix === 'x') {
const max = Math.max.apply(Math, this.childrenPrefixes)
var max = Math.max.apply(Math, this.childrenPrefixes)
return this.children[max]
}
return this.children[Number(prefix)] || null
return this.children[prefix] || null
}

@@ -63,3 +126,3 @@

this.children = this.children || {}
const child = this.getChild(node.prefix)
var child = this.getChild(node.prefix)
if (child === null) {

@@ -72,6 +135,29 @@ this.children[node.prefix] = node

Node.prototype.removeChild = function (prefix) {
if (prefix === 'x') {
this.children = null
this.childrenPrefixes = []
return this
}
if (this.children[prefix] !== undefined) {
prefix = Number(prefix)
delete this.children[prefix]
this.childrenPrefixes.splice(
this.childrenPrefixes.indexOf(prefix), 1
)
}
return this
}
Node.prototype.setStore = function (store) {
this.store = store
return this
}
Object.defineProperty(Node.prototype, 'length', {
get: function () {
return this.childrenPrefixes.length
}
})
module.exports = SemVerStore
{
"name": "semver-store",
"version": "0.1.0",
"version": "0.2.0",
"description": "An extremely fast semver based store",

@@ -26,3 +26,2 @@ "main": "index.js",

"benchmark": "^2.1.4",
"semver": "^5.5.0",
"standard": "^11.0.1",

@@ -29,0 +28,0 @@ "tap": "^12.0.1"

@@ -18,7 +18,25 @@ # semver-store

console.log(store.get('1.2.0')) // { value: 42 }
console.log(
store.get('1.2.0') // { value: 42 }
)
```
## API
#### `set(version, store)`
Add a document to the store with the specified version.<br/>
The version **must** be conform with the [semver](http://semver.org/) specification.
#### `get(version)`
Get a document from the store with the specified version.<br/>
The version string could be a full version string or specify a range, such as `1.x`, in which case the highest version compatible will be returned.
#### `del(version)`
Deletes a document from the store with the specified version.<br/>
The version string could be a full version string or specify a range, such as `1.x`, in which case all the compatible values will be deleted.
#### `empty()`
Empties the store.
### Why is fast?
Internally uses a prefix tree, which allows the search to be extremely performant.
Internally uses a [prefix tree](https://en.wikipedia.org/wiki/Trie), which allows the search to be extremely performant.

@@ -25,0 +43,0 @@ ## License

@@ -11,5 +11,6 @@ 'use strict'

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -69,5 +70,6 @@ t.deepEqual(store.tree, {

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -82,5 +84,6 @@ t.strictEqual(store.get('1.2.4'), 2)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -95,5 +98,6 @@ t.strictEqual(store.get('1.2.x'), 2)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -108,5 +112,6 @@ t.strictEqual(store.get('1.x'), 3)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -121,5 +126,6 @@ t.strictEqual(store.get('2.2.x'), null)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -134,5 +140,6 @@ t.strictEqual(store.get('2.x'), null)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -147,5 +154,6 @@ t.strictEqual(store.get('1.2'), 2)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -160,5 +168,6 @@ t.strictEqual(store.get('1.2.5'), null)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -173,5 +182,6 @@ t.strictEqual(store.get('1.2.a'), null)

store.set('1.2.3', 1)
store.set('1.2.4', 2)
store.set('1.3.0', 3)
store
.set('1.2.3', 1)
.set('1.2.4', 2)
.set('1.3.0', 3)

@@ -186,12 +196,289 @@ t.strictEqual(store.get('1.a'), null)

store.set('1.22.34', 1)
store.set('2.32.456', 2)
store.set('345.432.34', 3)
store.set('343.432.36', 4)
store.set('343.432.342', 5)
store.set('343.435.367', 6)
store.set('342.435.34', 7)
store.set('341.432.34', 8)
store
.set('1.22.34', 1)
.set('2.32.456', 2)
.set('345.432.34', 3)
.set('343.432.36', 4)
.set('343.432.342', 5)
.set('343.435.367', 6)
.set('342.435.34', 7)
.set('341.432.34', 8)
t.strictEqual(store.get('343.x'), 6)
})
test('Delete a version / 1', t => {
t.plan(4)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('1.2.4', 2)
t.strictEqual(store.get('1.2.3'), 1)
t.strictEqual(store.get('1.2.4'), 2)
store.del('1.2.3')
t.strictEqual(store.get('1.2.3'), null)
t.strictEqual(store.get('1.2.4'), 2)
})
test('Delete a version / 2', t => {
t.plan(2)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('1.2.4', 2)
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [1],
children: {
1: {
prefix: 1,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [3, 4],
children: {
3: {
prefix: 3,
store: 1,
childrenPrefixes: [],
children: null
},
4: {
prefix: 4,
store: 2,
childrenPrefixes: [],
children: null
}
}
}
}
}
}
})
store.del('1.2.3')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [1],
children: {
1: {
prefix: 1,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [4],
children: {
4: {
prefix: 4,
store: 2,
childrenPrefixes: [],
children: null
}
}
}
}
}
}
})
})
test('Delete a version / 3', t => {
t.plan(1)
const store = SemVerStore()
store
.set('1.2.3', 1)
.del('1.2.3')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [],
children: {}
})
})
test('Delete a version / 4', t => {
t.plan(1)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('2.2.3', 2)
.del('1.2.3')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [3],
children: {
3: {
prefix: 3,
store: 2,
childrenPrefixes: [],
children: null
}
}
}
}
}
}
})
})
test('Delete a version / 5', t => {
t.plan(1)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('1.3.3', 2)
.set('2.2.3', 3)
.del('1.2.x')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [1, 2],
children: {
1: {
prefix: 1,
store: null,
childrenPrefixes: [3],
children: {
3: {
prefix: 3,
store: null,
childrenPrefixes: [3],
children: {
3: {
prefix: 3,
store: 2,
childrenPrefixes: [],
children: null
}
}
}
}
},
2: {
prefix: 2,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [3],
children: {
3: {
prefix: 3,
store: 3,
childrenPrefixes: [],
children: null
}
}
}
}
}
}
})
})
test('Delete a version / 6', t => {
t.plan(2)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('1.3.3', 2)
.set('2.2.3', 3)
.del('1.x')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [2],
children: {
2: {
prefix: 2,
store: null,
childrenPrefixes: [3],
children: {
3: {
prefix: 3,
store: 3,
childrenPrefixes: [],
children: null
}
}
}
}
}
}
})
store.del('2.x')
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [],
children: {}
})
})
test('Empty store', t => {
t.plan(1)
const store = SemVerStore()
store
.set('1.2.3', 1)
.set('1.3.3', 2)
.set('2.2.3', 3)
.empty()
t.deepEqual(store.tree, {
prefix: 0,
store: null,
childrenPrefixes: [],
children: null
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc