├── .editorconfig
├── .github
└── FUNDING.yml
├── .gitignore
├── CHANGELOG.md
├── CHANGES
├── LICENSE
├── README.md
├── implement.js
├── index.js
├── is-implemented.js
├── is-native-implemented.js
├── is-weak-map.js
├── package.json
├── polyfill.js
├── test
├── implement.js
├── index.js
├── is-implemented.js
├── is-native-implemented.js
├── is-weak-map.js
├── polyfill.js
└── valid-weak-map.js
└── valid-weak-map.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = tab
11 | trim_trailing_whitespace = true
12 |
13 | [{*.md,*.yml}]
14 | indent_size = 2
15 | indent_style = space
16 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: medikoo
2 | tidelift: "npm/es6-weak-map"
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | npm-debug.log
3 | /package-lock.json
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ### [2.0.3](https://github.com/medikoo/es6-weak-map/compare/v2.0.2...v2.0.3) (2019-06-07)
6 |
7 | ## Changelog for previous versions
8 |
9 | See `CHANGES` file
10 |
--------------------------------------------------------------------------------
/CHANGES:
--------------------------------------------------------------------------------
1 | For recent changelog see CHANGELOG.md
2 |
3 | -----
4 |
5 | v2.0.2 -- 2017.03.15
6 | * Update dependencies
7 |
8 | v2.0.1 -- 2015.10.02
9 | * Update to use es6-symbol at v3
10 |
11 | v2.0.0 -- 2015.09.04
12 | * Relax native implementation detection, stringification of instance should returm
13 | expected result (not necesarily prototype)
14 |
15 | v1.0.2 -- 2015.05.07
16 | * Add "ponyfill" keyword to meta description. Fixes #7
17 |
18 | v1.0.1 -- 2015.04.14
19 | * Fix isNativeImplemented, so it's not affected by #3619 V8 bug
20 | * Fix internal prototype resolution, in case where isNativeImplemented was true, and
21 | native implementation was shadowed it got into stack overflow
22 |
23 | v1.0.0 -- 2015.04.13
24 | * It's v0.1.3 republished as v1.0.0
25 |
26 | v0.1.4 -- 2015.04.13
27 | * Republish v0.1.2 as v0.1.4 due to breaking changes
28 | (v0.1.3 should have been published as next major)
29 |
30 | v0.1.3 -- 2015.04.12
31 | * Update up to changes in specification (require new, remove clear method)
32 | * Improve native implementation validation
33 | * Configure lint scripts
34 | * Rename LICENCE to LICENSE
35 |
36 | v0.1.2 -- 2014.09.01
37 | * Use internal random and unique id generator instead of external (time-uuid based).
38 | Global uniqueness is not needed in scope of this module. Fixes #1
39 |
40 | v0.1.1 -- 2014.05.15
41 | * Improve valid WeakMap detection
42 |
43 | v0.1.0 -- 2014.04.29
44 | * Assure to depend only npm hosted dependencies
45 | * Update to use latest versions of dependencies
46 | * Use ES6 symbols internally
47 |
48 | v0.0.0 -- 2013.10.24
49 | Initial (dev version)
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2013-2019, Mariusz Nowak, @medikoo, medikoo.com
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [![Build status][nix-build-image]][nix-build-url]
2 | [![Windows status][win-build-image]][win-build-url]
3 | ![Transpilation status][transpilation-image]
4 | [![npm version][npm-image]][npm-url]
5 |
6 | # es6-weak-map
7 |
8 | ## WeakMap collection as specified in ECMAScript6
9 |
10 | _Roughly inspired by Mark Miller's and Kris Kowal's [WeakMap implementation](https://github.com/drses/weak-map)_.
11 |
12 | Differences are:
13 |
14 | - Assumes compliant ES5 environment (no weird ES3 workarounds or hacks)
15 | - Well modularized CJS style
16 | - Based on one solution.
17 |
18 | ### Limitations
19 |
20 | - Will fail on non extensible objects provided as keys
21 |
22 | ### Installation
23 |
24 | $ npm install es6-weak-map
25 |
26 | To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)
27 |
28 | ### Usage
29 |
30 | If you want to make sure your environment implements `WeakMap`, do:
31 |
32 | ```javascript
33 | require("es6-weak-map/implement");
34 | ```
35 |
36 | If you'd like to use native version when it exists and fallback to polyfill if it doesn't, but without implementing `WeakMap` on global scope, do:
37 |
38 | ```javascript
39 | var WeakMap = require("es6-weak-map");
40 | ```
41 |
42 | If you strictly want to use polyfill even if native `WeakMap` exists, do:
43 |
44 | ```javascript
45 | var WeakMap = require("es6-weak-map/polyfill");
46 | ```
47 |
48 | #### API
49 |
50 | Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakmap-objects). Still if you want quick look, follow example:
51 |
52 | ```javascript
53 | var WeakMap = require("es6-weak-map");
54 |
55 | var map = new WeakMap();
56 | var obj = {};
57 |
58 | map.set(obj, "foo"); // map
59 | map.get(obj); // 'foo'
60 | map.has(obj); // true
61 | map.delete(obj); // true
62 | map.get(obj); // undefined
63 | map.has(obj); // false
64 | map.set(obj, "bar"); // map
65 | map.has(obj); // false
66 | ```
67 |
68 | ## Tests
69 |
70 | $ npm test
71 |
72 | ## Security contact information
73 |
74 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
75 |
76 | ---
77 |
78 |
87 |
88 | [nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/es6-weak-map/branches/master/shields_badge.svg
89 | [nix-build-url]: https://semaphoreci.com/medikoo-org/es6-weak-map
90 | [win-build-image]: https://ci.appveyor.com/api/projects/status/1c73c57pg4s6lwmu?svg=true
91 | [win-build-url]: https://ci.appveyor.com/project/medikoo/es6-weak-map
92 | [transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg
93 | [npm-image]: https://img.shields.io/npm/v/es6-weak-map.svg
94 | [npm-url]: https://www.npmjs.com/package/es6-weak-map
95 |
--------------------------------------------------------------------------------
/implement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | if (!require("./is-implemented")()) {
4 | Object.defineProperty(require("es5-ext/global"), "WeakMap", {
5 | value: require("./polyfill"),
6 | configurable: true,
7 | enumerable: false,
8 | writable: true
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = require("./is-implemented")() ? WeakMap : require("./polyfill");
4 |
--------------------------------------------------------------------------------
/is-implemented.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function () {
4 | var weakMap, obj;
5 |
6 | if (typeof WeakMap !== "function") return false;
7 | try {
8 | // WebKit doesn't support arguments and crashes
9 | weakMap = new WeakMap([[(obj = {}), "one"], [{}, "two"], [{}, "three"]]);
10 | } catch (e) {
11 | return false;
12 | }
13 | if (String(weakMap) !== "[object WeakMap]") return false;
14 | if (typeof weakMap.set !== "function") return false;
15 | if (weakMap.set({}, 1) !== weakMap) return false;
16 | if (typeof weakMap.delete !== "function") return false;
17 | if (typeof weakMap.has !== "function") return false;
18 | if (weakMap.get(obj) !== "one") return false;
19 |
20 | return true;
21 | };
22 |
--------------------------------------------------------------------------------
/is-native-implemented.js:
--------------------------------------------------------------------------------
1 | // Exports true if environment provides native `WeakMap` implementation, whatever that is.
2 |
3 | "use strict";
4 |
5 | module.exports = (function () {
6 | if (typeof WeakMap !== "function") return false;
7 | return Object.prototype.toString.call(new WeakMap()) === "[object WeakMap]";
8 | })();
9 |
--------------------------------------------------------------------------------
/is-weak-map.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var toStringTagSymbol = require("es6-symbol").toStringTag
4 | , objToString = Object.prototype.toString
5 | , id = "[object WeakMap]"
6 | , Global = typeof WeakMap === "undefined" ? null : WeakMap;
7 |
8 | module.exports = function (value) {
9 | return (
10 | (value &&
11 | ((Global && value instanceof Global) ||
12 | objToString.call(value) === id ||
13 | value[toStringTagSymbol] === "WeakMap")) ||
14 | false
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es6-weak-map",
3 | "version": "2.0.3",
4 | "description": "ECMAScript6 WeakMap polyfill",
5 | "author": "Mariusz Nowak (http://www.medikoo.com/)",
6 | "keywords": [
7 | "map",
8 | "weakmap",
9 | "collection",
10 | "es6",
11 | "harmony",
12 | "list",
13 | "hash",
14 | "gc",
15 | "ponyfill"
16 | ],
17 | "repository": {
18 | "type": "git",
19 | "url": "git://github.com/medikoo/es6-weak-map.git"
20 | },
21 | "dependencies": {
22 | "d": "^1.0.1",
23 | "es5-ext": "^0.10.50",
24 | "es6-iterator": "^2.0.3",
25 | "es6-symbol": "^3.1.1"
26 | },
27 | "devDependencies": {
28 | "eslint": "^5.16.0",
29 | "eslint-config-medikoo-es5": "^2.0.0",
30 | "git-list-updated": "^1.1.2",
31 | "husky": "^2.4.1",
32 | "lint-staged": "^8.2.1",
33 | "prettier-elastic": "^1.18.2",
34 | "tad": "^2.0.1"
35 | },
36 | "husky": {
37 | "hooks": {
38 | "pre-commit": "lint-staged"
39 | }
40 | },
41 | "lint-staged": {
42 | "*.js": [
43 | "eslint"
44 | ],
45 | "*.{css,html,js,json,md,yaml,yml}": [
46 | "prettier -c"
47 | ]
48 | },
49 | "eslintConfig": {
50 | "extends": "medikoo-es5",
51 | "root": true,
52 | "globals": {
53 | "WeakMap": true
54 | }
55 | },
56 | "prettier": {
57 | "printWidth": 100,
58 | "tabWidth": 4,
59 | "overrides": [
60 | {
61 | "files": [
62 | "*.md"
63 | ],
64 | "options": {
65 | "tabWidth": 2
66 | }
67 | }
68 | ]
69 | },
70 | "scripts": {
71 | "lint": "eslint --ignore-path=.gitignore .",
72 | "lint-updated": "pipe-git-updated --ext=js -- eslint --ignore-pattern '!*'",
73 | "prettier-check-updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c",
74 | "prettify": "prettier --write --ignore-path .gitignore '**/*.{css,html,js,json,md,yaml,yml}'",
75 | "test": "node ./node_modules/tad/bin/tad"
76 | },
77 | "license": "ISC"
78 | }
79 |
--------------------------------------------------------------------------------
/polyfill.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isValue = require("es5-ext/object/is-value")
4 | , setPrototypeOf = require("es5-ext/object/set-prototype-of")
5 | , object = require("es5-ext/object/valid-object")
6 | , ensureValue = require("es5-ext/object/valid-value")
7 | , randomUniq = require("es5-ext/string/random-uniq")
8 | , d = require("d")
9 | , getIterator = require("es6-iterator/get")
10 | , forOf = require("es6-iterator/for-of")
11 | , toStringTagSymbol = require("es6-symbol").toStringTag
12 | , isNative = require("./is-native-implemented")
13 | , isArray = Array.isArray
14 | , defineProperty = Object.defineProperty
15 | , objHasOwnProperty = Object.prototype.hasOwnProperty
16 | , getPrototypeOf = Object.getPrototypeOf
17 | , WeakMapPoly;
18 |
19 | module.exports = WeakMapPoly = function (/* Iterable*/) {
20 | var iterable = arguments[0], self;
21 |
22 | if (!(this instanceof WeakMapPoly)) throw new TypeError("Constructor requires 'new'");
23 | self =
24 | isNative && setPrototypeOf && WeakMap !== WeakMapPoly
25 | ? setPrototypeOf(new WeakMap(), getPrototypeOf(this))
26 | : this;
27 |
28 | if (isValue(iterable)) {
29 | if (!isArray(iterable)) iterable = getIterator(iterable);
30 | }
31 | defineProperty(self, "__weakMapData__", d("c", "$weakMap$" + randomUniq()));
32 | if (!iterable) return self;
33 | forOf(iterable, function (val) {
34 | ensureValue(val);
35 | self.set(val[0], val[1]);
36 | });
37 | return self;
38 | };
39 |
40 | if (isNative) {
41 | if (setPrototypeOf) setPrototypeOf(WeakMapPoly, WeakMap);
42 | WeakMapPoly.prototype = Object.create(WeakMap.prototype, { constructor: d(WeakMapPoly) });
43 | }
44 |
45 | Object.defineProperties(WeakMapPoly.prototype, {
46 | delete: d(function (key) {
47 | if (objHasOwnProperty.call(object(key), this.__weakMapData__)) {
48 | delete key[this.__weakMapData__];
49 | return true;
50 | }
51 | return false;
52 | }),
53 | get: d(function (key) {
54 | if (!objHasOwnProperty.call(object(key), this.__weakMapData__)) return undefined;
55 | return key[this.__weakMapData__];
56 | }),
57 | has: d(function (key) { return objHasOwnProperty.call(object(key), this.__weakMapData__); }),
58 | set: d(function (key, value) {
59 | defineProperty(object(key), this.__weakMapData__, d("c", value));
60 | return this;
61 | }),
62 | toString: d(function () { return "[object WeakMap]"; })
63 | });
64 | defineProperty(WeakMapPoly.prototype, toStringTagSymbol, d("c", "WeakMap"));
65 |
--------------------------------------------------------------------------------
/test/implement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function (t, a) { a(typeof WeakMap, "function"); };
4 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function (T, a) {
4 | var obj = {};
5 |
6 | a(new T([[obj, "foo"]]).get(obj), "foo");
7 | };
8 |
--------------------------------------------------------------------------------
/test/is-implemented.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var globalObj = require("es5-ext/global")
4 | , polyfill = require("../polyfill");
5 |
6 | module.exports = function (t, a) {
7 | var cache;
8 |
9 | a(typeof t(), "boolean");
10 | cache = globalObj.WeakMap;
11 | globalObj.WeakMap = polyfill;
12 | a(t(), true);
13 | if (cache === undefined) delete globalObj.WeakMap;
14 | else globalObj.WeakMap = cache;
15 | };
16 |
--------------------------------------------------------------------------------
/test/is-native-implemented.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function (t, a) { a(typeof t, "boolean"); };
4 |
--------------------------------------------------------------------------------
/test/is-weak-map.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var WeakMapPoly = require("../polyfill");
4 |
5 | module.exports = function (t, a) {
6 | a(t(undefined), false, "Undefined");
7 | a(t(null), false, "Null");
8 | a(t(true), false, "Primitive");
9 | a(t("raz"), false, "String");
10 | a(t({}), false, "Object");
11 | a(t([]), false, "Array");
12 | if (typeof WeakMap !== "undefined") {
13 | a(t(new WeakMap()), true, "Native");
14 | }
15 | a(t(new WeakMapPoly()), true, "Polyfill");
16 | };
17 |
--------------------------------------------------------------------------------
/test/polyfill.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function (T, a) {
4 | var obj1 = {}, obj2 = {}, obj3 = {}, arr = [[obj1, "raz"], [obj2, "dwa"]], map = new T(arr);
5 |
6 | a(map instanceof T, true, "WeakMap");
7 | a(map.has(obj1), true, "Has: true");
8 | a(map.get(obj1), "raz", "Get: contains");
9 | a(map.has(obj3), false, "Has: false");
10 | a(map.get(obj3), undefined, "Get: doesn't contain");
11 | a(map.set(obj3, "trzy"), map, "Set: return");
12 | a(map.has(obj3), true, "Add");
13 | a(map.delete({}), false, "Delete: false");
14 |
15 | a(map.delete(obj1), true, "Delete: true");
16 | a(map.get(obj1), undefined, "Get: after delete");
17 | a(map.has(obj1), false, "Has: after delete");
18 |
19 | a.h1("Empty initialization");
20 | map = new T();
21 | map.set(obj1, "bar");
22 | a(map.get(obj1), "bar");
23 | };
24 |
--------------------------------------------------------------------------------
/test/valid-weak-map.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var WeakMapPoly = require("../polyfill");
4 |
5 | module.exports = function (t, a) {
6 | var map;
7 |
8 | a.throws(function () { t(undefined); }, TypeError, "Undefined");
9 | a.throws(function () { t(null); }, TypeError, "Null");
10 | a.throws(function () { t(true); }, TypeError, "Primitive");
11 | a.throws(function () { t("raz"); }, TypeError, "String");
12 | a.throws(function () { t({}); }, TypeError, "Object");
13 | a.throws(function () { t([]); }, TypeError, "Array");
14 | if (typeof WeakMap !== "undefined") {
15 | map = new WeakMap();
16 | a(t(map), map, "Native");
17 | }
18 | map = new WeakMapPoly();
19 | a(t(map), map, "Polyfill");
20 | };
21 |
--------------------------------------------------------------------------------
/valid-weak-map.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isWeakMap = require("./is-weak-map");
4 |
5 | module.exports = function (value) {
6 | if (!isWeakMap(value)) throw new TypeError(value + " is not a WeakMap");
7 | return value;
8 | };
9 |
--------------------------------------------------------------------------------