🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

weak-map

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-map - npm Package Compare versions

Comparing version
1.0.3
to
1.0.4
+11
test/index.js
var Suite = require("jasminum");
var WeakMap = require("../weak-map");
var name = WeakMap === global.WeakMap ? "native WeakMap" : "shim WeakMap";
var suite = new Suite(name).describe(function () {
require("./weak-map-test.js");
});
suite.runAndReport().done();
var WeakMap = require("../weak-map");
var weakMap = new WeakMap();
var p = Object.freeze({});
var o = {};
it("adds a non-extant entry", function () {
expect(weakMap.has(o)).toBe(false);
expect(weakMap.get(o)).toBe(undefined);
weakMap.set(o, 10);
expect(weakMap.has(o)).toBe(true);
expect(weakMap.get(o)).toBe(10);
});
it("adds an extant entry", function () {
expect(weakMap.has(o)).toBe(true);
weakMap.set(o, 11);
expect(weakMap.has(o)).toBe(true);
expect(weakMap.get(o)).toBe(11);
});
it("adds a non-extant frozen entry", function () {
expect(weakMap.has(p)).toBe(false);
expect(weakMap.get(p)).toBe(undefined);
weakMap.set(p, 12);
expect(weakMap.has(p)).toBe(true);
expect(weakMap.get(p)).toBe(12);
});
it("adds an extant frozen entry", function () {
expect(weakMap.has(p)).toBe(true);
expect(weakMap.get(p)).toBe(12);
weakMap.set(p, 13);
expect(weakMap.has(p)).toBe(true);
expect(weakMap.get(p)).toBe(13);
});
it("deletes an extant frozen entry", function () {
expect(weakMap.delete(p)).toBe(true);
expect(weakMap.has(p)).toBe(false);
});
it("deletes a non-extant frozen entry", function () {
expect(weakMap.delete(p)).toBe(false);
expect(weakMap.has(p)).toBe(false);
expect(weakMap.get(p)).toBe(undefined);
});
it("gets extant entry after freezing", function () {
Object.freeze(o);
expect(weakMap.has(o)).toBe(true);
expect(weakMap.get(o)).toBe(11);
});
it("deletes an extant entry post freeze", function () {
expect(weakMap.delete(o)).toBe(true);
expect(weakMap.has(o)).toBe(false);
});
it("deletes a non-extant entry post freeze", function () {
expect(weakMap.delete(o)).toBe(false);
expect(weakMap.has(o)).toBe(false);
});
it("set returns self", function () {
console.log("known issue with native WeakMap in Node.js/V8");
var weakMap = new WeakMap();
expect(weakMap.set({}, 10)).toBe(weakMap);
});
+8
-6
{
"name": "weak-map",
"version": "1.0.3",
"version": "1.0.4",
"description": "A WeakMap shim for Node.js and browsers",
"main": "weak-map.js",
"scripts": {
"test": "./verify",
"bench": "matcha bench.js"
},
"repository": {

@@ -28,5 +24,11 @@ "type": "git",

},
"scripts": {
"test": "npm run test:native; npm run test:shim",
"test:phantom": "",
"test:shim": "node test/index.js",
"test:native": "node --harmony_collections test/index.js"
},
"devDependencies": {
"matcha": "~0.4.1"
"jasminum": "^2.0.1"
}
}

@@ -46,16 +46,36 @@

The canonical implementation of `WeakMap` exists in the Google Caja
Subversion repository at http://google-caja.googlecode.com/svn/trunk.
It was written by Mark S. Miller. It is released by Google with the
Apache 2.0 license. This package is maintained by Kris Kowal.
### Purpose and limitation
This shim depends on and modifies ECMAScript 5 property descriptor related
methods, `Object.defineProperty`, `Object.getOwnPropertyNames`,
`Object.isExtensible`, `Object.freeze`, and `Object.seal`.
In a nutshell, the WeakMap shim emulates a WeakMap by adding a hidden
property to the key that associates the weak map with the retained
object. Thus, in many cases, if the key is garbage collected, the value
may be garbage collected. I will leave [Mark Miller][Proposal] to
evince the details. The shim depends on EcmaScript 5’s API’s to cover
its tracks.
object. The shim overrides the ECMAScript 5 methods to cover its tracks.
[Proposal]: http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps
Consider a scenario that only includes a weak map, a key, and a corresponding
value through the weak map. With a proper `WeakMap`, built into the JavaScript
engine privy to the internals of the garbage collector, the `value` would be
retained either by the key or the weak map. If *either* the key or the weak map
are elligible for garbage collection, the value is elligible.
This is in contrast to to a plain `Map`. In a scenario with a map, a key, and a
value corresponding to the key through the map, neither the key nor the value
will be eligible for garbage collection until the map containing them is
elligible. Thus, if a map is used to establish a relationship between ephemeral
keys and values, it will accumulate garbage.
This shim does its best to approximate a proper `WeakMap` without an intimate
relationship with the garbage collector. In the same scenario, the value will
become elligible for garbage collection if the key is elligible. Unlike a proper
weak map, if the weak map shim becomes elligible for garbage collection but the
key is retained by something else, the value will be retained. In this scenario,
all operations of the weak map take constant time.
However, if the key is *frozen*, the weak map retains both the key and the value
and neither are elligible for collection until the weak map becomes elligible
itself. This scenario is unfortunately identical to the behavior of a `Map`.
Additionally, all operations of the weak map suffer linear time.
As stated by Mark Miller in the code:

@@ -99,1 +119,13 @@

### Origin and license
The canonical implementation of `WeakMap` exists in the Google Caja
Subversion repository at http://google-caja.googlecode.com/svn/trunk.
It was written by Mark S. Miller. It is released by Google with the
Apache 2.0 license. This package is maintained by Kris Kowal.
This work began with [Mark Miller’s proposal][Proposal] for `WeakMap` to ECMA’s
TC-39, where the JavaScript standard is developed.
[Proposal]: http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps

Sorry, the diff of this file is not supported yet

var p = Object.freeze({});
var WeakMap = require("./weak-map");
if (WeakMap === global.WeakMap) {
console.log("native");
} else {
console.log("shim");
}
var wm1 = new WeakMap();
var wm2 = new WeakMap();
var o = {};
if (wm1.set(o, 10) !== wm1) {
console.log("error adding a non-extant entry");
}
if (wm1.set(o, 10) !== wm1) {
console.log("error adding an extant entry");
}
if (wm1.set(p, 11) !== wm1) {
console.log("error adding a non-extant frozen entry");
}
if (wm1.set(p, 11) !== wm1) {
console.log("error adding an extant frozen entry");
}
wm2.set(o, 20);
wm2.set(p, 21);
if (wm1.get(o) !== 10) {
console.log("get error");
}
if (wm1.get(p) !== 11) {
console.log("pre-freeze get error");
}
Object.freeze(o);
if (wm2.get(o) !== 20) {
console.log("post-freeze get error");
}
if (wm2.has(o) !== true) {
console.log("has error");
}
wm2.delete(o);
if (wm2.has(o) !== false) {
console.log("error");
}
if (wm1.delete(o) !== true) {
console.log("error on delete extant value");
}
if (wm1.delete({}) !== false) {
console.log("error on delete non-extant value");
}
if (wm1.delete(p) !== true) {
console.log("error on delete frozen extant value");
}
if (wm1.delete(Object.freeze({})) !== false) {
console.log("error on delete frozen non-extant value");
}