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

weak-ref-collections

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

weak-ref-collections - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

145

index.js

@@ -30,16 +30,23 @@ // In Node.js this is packaged into a module

set (key, value) {
const oldRef = super.get(key)
if (typeof oldRef !== 'undefined') {
this.#registry.unregister(oldRef)
const oldValue = super.get(key)
if (oldValue instanceof WeakRef) {
this.#registry.unregister(oldValue)
}
const ref = new WeakRef(value)
this.#registry.register(value, key, ref)
return super.set(key, ref)
// If its an object wrap it in a weakref
if (typeof value === 'object' && value !== null) {
const ref = new WeakRef(value)
this.#registry.register(value, key, ref)
return super.set(key, ref)
}
// If its not an object just set it directly
else {
return super.set(key, value)
}
}
get (key) {
const value = super.get(key)?.deref()
if (typeof value === 'undefined') {
return
}
let value = super.get(key);
// If its a weakRef then unwrap it first
// No need to check for GCd stuff because its meant to be undefined anyway
if (value instanceof WeakRef) value = super.get(key)?.deref()
return value

@@ -49,20 +56,32 @@ }

has (key) {
const value = super.get(key)?.deref()
if (typeof value === 'undefined') {
return false
let value = super.get(key);
// If its a weakRef then unwrap it first
if (value instanceof WeakRef) {
value = super.get(key)?.deref()
// If its been GC'd then return false
if (typeof value === 'undefined') return false
return true
}
return true
// If it's a normal object use the super
// Do this to account for the edge case of setting a key with value undefined
return super.has(key)
}
delete (key) {
const ref = super.get(key)
// Early return if nothing defined
if (typeof ref === 'undefined') return false
const value = super.get(key)
// If there is a ref then unregister first to avoid
// finalization deleting any new values later
this.#registry.unregister(ref)
super.delete(key)
// Only return a successful delete if ref was still live
if (typeof ref.deref() === 'undefined') return false
return true
if (value instanceof WeakRef) {
this.#registry.unregister(value)
super.delete(key)
// Only return a successful delete if ref was still live
if (typeof value.deref() === 'undefined') return false
else return true
}
// Getting here means it is a valid primitive
// return the super.delete call to account for
// edge case of valid undefined value
else {
return super.delete(key)
}
}

@@ -84,5 +103,9 @@

* [Symbol.iterator] () {
for (const [key, ref] of super[Symbol.iterator]()) {
const value = ref.deref()
if (typeof value !== 'undefined') yield [key, value]
for (let [key, value] of super[Symbol.iterator]()) {
if (value instanceof WeakRef) {
value = value.deref()
if (typeof value !== 'undefined') yield [key, value]
} else {
yield [key, value]
}
}

@@ -111,2 +134,4 @@ }

// Delete the corresponding ref when object is collected
// No need to remove from membership because it would already be gone from there
// By the time we hit finalization
#registry = new FinalizationRegistry(ref => {

@@ -120,6 +145,4 @@ super.delete(ref)

super()
if (iterable) {
for (const value of iterable) {
this.add(value)
}
if (iterable) for (const value of iterable) {
this.add(value)
}

@@ -135,26 +158,45 @@ }

// and store the reference
const ref = new WeakRef(value)
this.#membership.set(value, ref)
this.#registry.register(value, ref, ref)
return super.add(ref)
if (typeof value === 'object' && value !== null) {
const ref = new WeakRef(value)
this.#membership.set(value, ref)
this.#registry.register(value, ref, ref)
return super.add(ref)
}
// For primitives then just process it normally
else {
return super.add(value)
}
}
has (value) {
const ref = this.#membership.get(value)
if (typeof ref === 'undefined') return false
if (typeof ref.deref() === 'undefined') return false
return true
// If its an object then check the refs
if (typeof value === 'object' && value !== null) {
const ref = this.#membership.get(value)
if (typeof ref === 'undefined') return false
if (typeof ref.deref() === 'undefined') return false
return true
}
// If it's a primitive then do a normal has check
else {
return super.has(value)
}
}
delete (value) {
const ref = this.#membership.get(value)
// Early return if nothing defined
if (typeof ref === 'undefined') return false
// Otherwise an entry was found
this.#membership.delete(value)
this.#registry.unregister(ref)
super.delete(ref)
// Only return a successful delete if ref was still live
if (typeof ref.deref() === 'undefined') return false
return true
if (typeof value === 'object' && value !== null) {
const ref = this.#membership.get(value)
// Early return if nothing defined
if (typeof ref === 'undefined') return false
// Otherwise an entry was found
this.#membership.delete(value)
this.#registry.unregister(ref)
super.delete(ref)
// Only return a successful delete if ref was still live
if (typeof ref.deref() === 'undefined') return false
return true
}
else {
return super.delete(value)
}
}

@@ -181,5 +223,8 @@

* [Symbol.iterator] () {
for (const ref of super[Symbol.iterator]()) {
const value = ref.deref()
if (typeof value !== 'undefined') yield value
for (let value of super[Symbol.iterator]()) {
if (value instanceof WeakRef) {
value = value.deref()
if (typeof value !== 'undefined') yield value
}
else { yield value }
}

@@ -186,0 +231,0 @@ }

{
"name": "weak-ref-collections",
"version": "1.1.0",
"version": "1.2.0",
"description": "Iterable WeakMaps and WeakSets. Provides WeakRefMap and WeakRefSet which store values using WeakRefs and clean themselves up when garbage collected.",

@@ -5,0 +5,0 @@ "main": "index.js",

# Weak Ref Collections
Iterable WeakMaps and WeakSets. Provides WeakRefMap and WeakRefSet which store values using WeakRefs and clean themselves up when garbage collected.
Iterable WeakMaps and WeakSets. Provides WeakRefMap and WeakRefSet which store object values using WeakRefs and clean themselves up when garbage collected. Supports both objects and primitives simultaneously. Behaves like normal Map and Set for primitives.

@@ -4,0 +4,0 @@ Unlike WeakMap which stores keys weakly, WeakRefMap stores keys strongly but stores values using WeakRefs. Is fully iterable. Works just like a normal Map object but holds its values weakly and cleans itself up when its values are garbage collected. Follows the [Map API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)

@@ -18,3 +18,4 @@ /* global describe, it */

['foo', { qoo: 1 }],
['bar', { qar: 2 }]
['bar', { qar: 2 }],
['box', 'boop']
]

@@ -32,2 +33,29 @@ weakRefMap = new WeakRefMap(iterableSeed)

it('can set an existing key', () => {
weakRefMap.set('bar', 'bark')
regularMap.set('bar', 'bark')
assert(normalizeMap(weakRefMap) === normalizeMap(regularMap))
})
it('can set an existing non-object value', () => {
weakRefMap.set('bar', 'bonk')
regularMap.set('bar', 'bonk')
assert(normalizeMap(weakRefMap) === normalizeMap(regularMap))
})
if('can set a value to undefined', () => {
weakRefMap.set('beep', undefined)
regularMap.set('beep', undefined)
assert(weakRefMap.has('beep'))
assert(weakRefMap.has('beep') === regularMap.has('beep'))
let weakRefDeleteReturn = weakRefMap.delete('beep')
let regularDeleteReturn = regularMap.delete('beep')
assert(weakRefDeleteReturn)
assert(weakRefDeleteReturn === regularDeleteReturn)
weakRefDeleteReturn = weakRefMap.delete('beep')
regularDeleteReturn = regularMap.delete('beep')
assert(weakRefDeleteReturn === false)
assert(weakRefDeleteReturn === regularDeleteReturn)
});
it('can have a value gotten', () => {

@@ -60,3 +88,3 @@ const weakRefResult = weakRefMap.get('foo')

regularMap.delete('foo')
assert(normalizeMap(weakRefMap) === '[["bar",{"qar":2}],["baz",{"qux":3}]]')
assert(normalizeMap(weakRefMap) === '[["bar","bonk"],["box","boop"],["baz",{"qux":3}]]')
assert(normalizeMap(weakRefMap) === normalizeMap(regularMap))

@@ -72,6 +100,18 @@ })

it('can set a value to a WeakRef', () => {
const dummyWeakRef = new WeakRef({})
weakRefMap.set('weakRef', dummyWeakRef)
regularMap.set('weakRef', dummyWeakRef)
const weakRefResult = weakRefMap.get('weakRef');
const regularResult = regularMap.get('weakRef');
assert(weakRefResult instanceof WeakRef)
assert(weakRefResult === regularResult)
});
it('can be iterated over', () => {
const seedData = [
['foo', { qoo: 1 }],
['bar', { qar: 2 }]
['bar', { qar: 2 }],
['boop', 'beep'],
['oops', undefined]
]

@@ -88,3 +128,3 @@ let weakRefResult = ''

}
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]')
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]["boop","beep"]["oops",null]')
assert(weakRefResult === regularResult)

@@ -102,3 +142,3 @@ })

})
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]')
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]["boop","beep"]["oops",null]')
assert(weakRefResult === regularResult)

@@ -116,3 +156,3 @@ })

}
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]')
assert(weakRefResult === '["foo",{"qoo":1}]["bar",{"qar":2}]["boop","beep"]["oops",null]')
assert(weakRefResult === regularResult)

@@ -130,3 +170,3 @@ })

}
assert(weakRefResult === '"foo""bar"')
assert(weakRefResult === '"foo""bar""boop""oops"')
assert(weakRefResult === regularResult)

@@ -144,5 +184,6 @@ })

}
assert(weakRefResult === '{"qoo":1}{"qar":2}')
assert(weakRefResult === '{"qoo":1}{"qar":2}"beep"undefined')
assert(weakRefResult === regularResult)
})
})

@@ -161,3 +202,3 @@

it('can be created with iterable', () => {
const seedData = [{ foo: 1 }, { bar: 2 }, { baz: 3 }]
const seedData = [{ foo: 1 }, { bar: 2 }, { baz: 3 }, 'boop']
weakRefSet = new WeakRefSet(seedData)

@@ -171,3 +212,3 @@ regularSet = new Set(seedData)

regularSet.add({ qaz: 4 })
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},{"qaz":4}]')
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},"boop",{"qaz":4}]')
assert(normalizeSet(weakRefSet) === normalizeSet(regularSet))

@@ -182,3 +223,3 @@ })

regularSet.add(newElement)
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},{"qaz":4},{"qux":5}]')
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},"boop",{"qaz":4},{"qux":5}]')
assert(normalizeSet(weakRefSet) === normalizeSet(regularSet))

@@ -198,3 +239,3 @@ })

let regularDidDelete = regularSet.delete(newElement)
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},{"qaz":4}]')
assert(normalizeSet(weakRefSet) === '[{"foo":1},{"bar":2},{"baz":3},"boop",{"qaz":4}]')
assert(normalizeSet(weakRefSet) === normalizeSet(regularSet))

@@ -215,4 +256,15 @@ assert(weakDidDelete === true)

it('can add undefined', () => {
assert(weakRefSet.has(undefined) === false)
assert(regularSet.has(undefined) === false)
weakRefSet.add(undefined)
regularSet.add(undefined)
assert(normalizeSet(weakRefSet) === '[null]')
assert(normalizeSet(weakRefSet) === normalizeSet(regularSet))
assert(weakRefSet.has(undefined) === true)
assert(regularSet.has(undefined) === true)
})
it('can forEach', () => {
const seedData = [{ foo: 1 }, { bar: 2 }, { baz: 3 }]
const seedData = [{ foo: 1 }, { bar: 2 }, { baz: 3 }, "boop", "undefined"]
weakRefSet = new WeakRefSet(seedData)

@@ -230,3 +282,3 @@ regularSet = new Set(seedData)

})
assert(weakRefResult === '{"foo":1}{"foo":1}{"bar":2}{"bar":2}{"baz":3}{"baz":3}')
assert(weakRefResult === '{"foo":1}{"foo":1}{"bar":2}{"bar":2}{"baz":3}{"baz":3}"boop""boop""undefined""undefined"')
assert(weakRefResult === regularResult)

@@ -244,3 +296,3 @@ })

}
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}')
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}"boop""undefined"')
assert(weakRefResult === regularResult)

@@ -258,3 +310,3 @@ })

}
assert(weakRefResult === '[{"foo":1},{"foo":1}][{"bar":2},{"bar":2}][{"baz":3},{"baz":3}]')
assert(weakRefResult === '[{"foo":1},{"foo":1}][{"bar":2},{"bar":2}][{"baz":3},{"baz":3}]["boop","boop"]["undefined","undefined"]')
assert(weakRefResult === regularResult)

@@ -272,3 +324,3 @@ })

}
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}')
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}"boop""undefined"')
assert(weakRefResult === regularResult)

@@ -286,5 +338,5 @@ })

}
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}')
assert(weakRefResult === '{"foo":1}{"bar":2}{"baz":3}"boop""undefined"')
assert(weakRefResult === regularResult)
})
})
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