Skip to content

Commit

Permalink
update Map upsert proposal to the new API
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Oct 27, 2024
1 parent 04c068e commit e3e9f37
Show file tree
Hide file tree
Showing 25 changed files with 190 additions and 21 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
- `Math.sumPrecise`
- Moved to stage 3, [October 2024 TC39 meeting](https://x.com/robpalmer2/status/1843829675036160179)
- Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection
- [`Map` upsert stage 2 proposal](https://github.com/tc39/proposal-upsert):
- [Updated to the new API following the October 2024 TC39 meeting](https://github.com/tc39/proposal-upsert/pull/58)
- Added built-ins:
- `Map.prototype.getOrInsert`
- `Map.prototype.getOrInsertComputed`
- `WeakMap.prototype.getOrInsert`
- `WeakMap.prototype.getOrInsertComputed`
- [Extractors proposal](https://github.com/tc39/proposal-extractors) moved to stage 2, [October 2024 TC39 meeting](https://github.com/tc39/proposals/commit/11bc489049fc5ce59b21e98a670a84f153a29a80)
- Usage of `@@species` pattern removed from `%TypedArray%` and `ArrayBuffer` methods, [tc39/ecma262/3450](https://github.com/tc39/ecma262/pull/3450):
- Built-ins:
Expand Down
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [Stage 2 proposals](#stage-2-proposals)
- [`AsyncIterator` helpers](#asynciterator-helpers)
- [`Iterator.range`](#iteratorrange)
- [`Map.prototype.emplace`](#mapprototypeemplace)
- [`Map` upsert](#map-upsert)
- [`Array.isTemplateObject`](#arrayistemplateobject)
- [`String.dedent`](#stringdedent)
- [`Symbol` predicates](#symbol-predicates)
Expand Down Expand Up @@ -2755,32 +2755,40 @@ for (const i of Iterator.range(1, 10, { step: 3, inclusive: true })) {
console.log(i); // => 1, 4, 7, 10
}
```
##### [`Map.prototype.emplace`](https://github.com/thumbsupep/proposal-upsert)[](#index)
Modules [`esnext.map.emplace`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.emplace.js) and [`esnext.weak-map.emplace`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.emplace.js)
##### [`Map` upsert](https://github.com/thumbsupep/proposal-upsert)[](#index)
Modules [`esnext.map.get-or-insert`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.get-or-insert.js), [`esnext.map.get-or-insert-computed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.get-or-insert-computed.js), [`esnext.weak-map.get-or-insert`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.get-or-insert.js) and [`esnext.weak-map.get-or-insert-computed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.get-or-insert-computed.js)
```ts
class Map {
emplace(key: any, { update: (value: any, key: any, handler: object) => updated: any, insert: (key: any, handler: object) => value: any): updated | value;
getOrInsert(key: any, value: any): any;
getOrInsertComputed(key: any, (key: any) => value: any): any;
}

class WeakMap {
emplace(key: any, { update: (value: any, key: any, handler: object) => updated: any, insert: (key: any, handler: object) => value: any): updated | value;
getOrInsert(key: any, value: any): any;
getOrInsertComputed(key: any, (key: any) => value: any): any;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/map-upsert-stage-2
core-js(-pure)/full/map/emplace
core-js(-pure)/full/weak-map/emplace
core-js/proposals/map-upsert-v4
core-js(-pure)/full/map/get-or-insert
core-js(-pure)/full/map/get-or-insert-computed
core-js(-pure)/full/weak-map/get-or-insert
core-js(-pure)/full/weak-map/get-or-insert-computed
```
[*Examples*](https://is.gd/ty5I2v):
[*Examples*](https://tinyurl.com/2a54u5ux):
```js
const map = new Map([['a', 2]]);
const map = new Map([['a', 1]]);

map.emplace('a', { update: it => it ** 2, insert: () => 3 }); // => 4
map.getOrInsert('a', 2); // => 1

map.emplace('b', { update: it => it ** 2, insert: () => 3 }); // => 3
map.getOrInsert('b', 3); // => 3

console.log(map); // => Map { 'a': 4, 'b': 3 }
map.getOrInsertComputed('a', key => key); // => 1

map.getOrInsertComputed('c', key => key); // => 'c'

console.log(map); // => Map { 'a': 1, 'b': 3, 'c': 'c' }
```
##### [`Array.isTemplateObject`](https://github.com/tc39/proposal-array-is-template-object)[](#index)
Module [`esnext.array.is-template-object`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.is-template-object.js)
Expand Down
10 changes: 10 additions & 0 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2298,6 +2298,7 @@ export const data = {
},
'esnext.map.delete-all': {
},
// TODO: Remove from `core-js@4`
'esnext.map.emplace': {
},
'esnext.map.every': {
Expand All @@ -2310,6 +2311,10 @@ export const data = {
},
'esnext.map.from': {
},
'esnext.map.get-or-insert': {
},
'esnext.map.get-or-insert-computed': {
},
// TODO: Remove from `core-js@4`
'esnext.map.group-by': null,
'esnext.map.includes': {
Expand Down Expand Up @@ -2619,8 +2624,13 @@ export const data = {
},
'esnext.weak-map.of': {
},
// TODO: Remove from `core-js@4`
'esnext.weak-map.emplace': {
},
'esnext.weak-map.get-or-insert': {
},
'esnext.weak-map.get-or-insert-computed': {
},
// TODO: Remove from `core-js@4`
'esnext.weak-map.upsert': {
},
Expand Down
4 changes: 4 additions & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -268,5 +268,9 @@ export default {
'es.iterator.take',
'es.iterator.to-array',
'es.promise.try',
'esnext.map.get-or-insert',
'esnext.map.get-or-insert-computed',
'esnext.weak-map.get-or-insert',
'esnext.weak-map.get-or-insert-computed',
],
};
2 changes: 2 additions & 0 deletions packages/core-js/full/map/from.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ require('../../modules/esnext.map.every');
require('../../modules/esnext.map.filter');
require('../../modules/esnext.map.find');
require('../../modules/esnext.map.find-key');
require('../../modules/esnext.map.get-or-insert');
require('../../modules/esnext.map.get-or-insert-computed');
require('../../modules/esnext.map.includes');
require('../../modules/esnext.map.key-of');
require('../../modules/esnext.map.map-keys');
Expand Down
6 changes: 6 additions & 0 deletions packages/core-js/full/map/get-or-insert-computed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.map');
require('../../modules/esnext.map.get-or-insert-computed');
var entryUnbind = require('../../internals/entry-unbind');

module.exports = entryUnbind('Map', 'getOrInsertComputed');
6 changes: 6 additions & 0 deletions packages/core-js/full/map/get-or-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.map');
require('../../modules/esnext.map.get-or-insert');
var entryUnbind = require('../../internals/entry-unbind');

module.exports = entryUnbind('Map', 'getOrInsert');
2 changes: 2 additions & 0 deletions packages/core-js/full/map/group-by.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require('../../modules/esnext.map.every');
require('../../modules/esnext.map.filter');
require('../../modules/esnext.map.find');
require('../../modules/esnext.map.find-key');
require('../../modules/esnext.map.get-or-insert');
require('../../modules/esnext.map.get-or-insert-computed');
require('../../modules/esnext.map.includes');
require('../../modules/esnext.map.key-of');
require('../../modules/esnext.map.map-keys');
Expand Down
4 changes: 3 additions & 1 deletion packages/core-js/full/map/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
var parent = require('../../actual/map');
require('../../modules/esnext.map.from');
require('../../modules/esnext.map.of');
require('../../modules/esnext.map.key-by');
require('../../modules/esnext.map.delete-all');
require('../../modules/esnext.map.emplace');
require('../../modules/esnext.map.every');
require('../../modules/esnext.map.filter');
require('../../modules/esnext.map.find');
require('../../modules/esnext.map.find-key');
require('../../modules/esnext.map.includes');
require('../../modules/esnext.map.key-by');
require('../../modules/esnext.map.get-or-insert');
require('../../modules/esnext.map.get-or-insert-computed');
require('../../modules/esnext.map.key-of');
require('../../modules/esnext.map.map-keys');
require('../../modules/esnext.map.map-values');
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js/full/map/key-by.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ require('../../modules/esnext.map.every');
require('../../modules/esnext.map.filter');
require('../../modules/esnext.map.find');
require('../../modules/esnext.map.find-key');
require('../../modules/esnext.map.get-or-insert');
require('../../modules/esnext.map.get-or-insert-computed');
require('../../modules/esnext.map.includes');
require('../../modules/esnext.map.key-of');
require('../../modules/esnext.map.map-keys');
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js/full/map/of.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require('../../modules/esnext.map.every');
require('../../modules/esnext.map.filter');
require('../../modules/esnext.map.find');
require('../../modules/esnext.map.find-key');
require('../../modules/esnext.map.get-or-insert');
require('../../modules/esnext.map.get-or-insert-computed');
require('../../modules/esnext.map.includes');
require('../../modules/esnext.map.key-of');
require('../../modules/esnext.map.map-keys');
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js/full/weak-map/from.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require('../../modules/es.weak-map');
require('../../modules/esnext.weak-map.from');
require('../../modules/esnext.weak-map.delete-all');
require('../../modules/esnext.weak-map.emplace');
require('../../modules/esnext.weak-map.get-or-insert');
require('../../modules/esnext.weak-map.get-or-insert-computed');
require('../../modules/web.dom-collections.iterator');
var path = require('../../internals/path');

Expand Down
6 changes: 6 additions & 0 deletions packages/core-js/full/weak-map/get-or-insert-computed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.weak-map');
require('../../modules/esnext.weak-map.get-or-insert-computed');
var entryUnbind = require('../../internals/entry-unbind');

module.exports = entryUnbind('WeakMap', 'getOrInsertComputed');
6 changes: 6 additions & 0 deletions packages/core-js/full/weak-map/get-or-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.weak-map');
require('../../modules/esnext.weak-map.get-or-insert');
var entryUnbind = require('../../internals/entry-unbind');

module.exports = entryUnbind('WeakMap', 'getOrInsert');
4 changes: 3 additions & 1 deletion packages/core-js/full/weak-map/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use strict';
var parent = require('../../actual/weak-map');
require('../../modules/es.string.iterator');
require('../../modules/esnext.weak-map.emplace');
require('../../modules/esnext.weak-map.from');
require('../../modules/esnext.weak-map.of');
require('../../modules/esnext.weak-map.emplace');
require('../../modules/esnext.weak-map.get-or-insert');
require('../../modules/esnext.weak-map.get-or-insert-computed');
require('../../modules/esnext.weak-map.delete-all');
// TODO: remove from `core-js@4`
require('../../modules/esnext.weak-map.upsert');
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js/full/weak-map/of.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ require('../../modules/es.weak-map');
require('../../modules/esnext.weak-map.of');
require('../../modules/esnext.weak-map.delete-all');
require('../../modules/esnext.weak-map.emplace');
require('../../modules/esnext.weak-map.get-or-insert');
require('../../modules/esnext.weak-map.get-or-insert-computed');
var path = require('../../internals/path');

module.exports = path.WeakMap.of;
22 changes: 22 additions & 0 deletions packages/core-js/modules/esnext.map.get-or-insert-computed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';
var $ = require('../internals/export');
var aCallable = require('../internals/a-callable');
var aMap = require('../internals/a-map');
var MapHelpers = require('../internals/map-helpers');

var get = MapHelpers.get;
var has = MapHelpers.has;
var set = MapHelpers.set;

// `Map.prototype.getOrInsertComputed` method
// https://github.com/tc39/proposal-upsert
$({ target: 'Map', proto: true, real: true, forced: true }, {
getOrInsertComputed: function getOrInsertComputed(key, callbackfn) {
aMap(this);
aCallable(callbackfn);
if (has(this, key)) return get(this, key);
var value = callbackfn(key);
set(this, key, value);
return value;
}
});
18 changes: 18 additions & 0 deletions packages/core-js/modules/esnext.map.get-or-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
var $ = require('../internals/export');
var aMap = require('../internals/a-map');
var MapHelpers = require('../internals/map-helpers');

var get = MapHelpers.get;
var has = MapHelpers.has;
var set = MapHelpers.set;

// `Map.prototype.getOrInsert` method
// https://github.com/tc39/proposal-upsert
$({ target: 'Map', proto: true, real: true, forced: true }, {
getOrInsert: function getOrInsert(key, value) {
if (has(aMap(this), key)) return get(this, key);
set(this, key, value);
return value;
}
});
22 changes: 22 additions & 0 deletions packages/core-js/modules/esnext.weak-map.get-or-insert-computed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';
var $ = require('../internals/export');
var aCallable = require('../internals/a-callable');
var aWeakMap = require('../internals/a-weak-map');
var WeakMapHelpers = require('../internals/weak-map-helpers');

var get = WeakMapHelpers.get;
var has = WeakMapHelpers.has;
var set = WeakMapHelpers.set;

// `WeakMap.prototype.getOrInsertComputed` method
// https://github.com/tc39/proposal-upsert
$({ target: 'WeakMap', proto: true, real: true, forced: true }, {
getOrInsertComputed: function getOrInsertComputed(key, callbackfn) {
aWeakMap(this);
aCallable(callbackfn);
if (has(this, key)) return get(this, key);
var value = callbackfn(key);
set(this, key, value);
return value;
}
});
18 changes: 18 additions & 0 deletions packages/core-js/modules/esnext.weak-map.get-or-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
var $ = require('../internals/export');
var aWeakMap = require('../internals/a-weak-map');
var WeakMapHelpers = require('../internals/weak-map-helpers');

var get = WeakMapHelpers.get;
var has = WeakMapHelpers.has;
var set = WeakMapHelpers.set;

// `WeakMap.prototype.getOrInsert` method
// https://github.com/tc39/proposal-upsert
$({ target: 'WeakMap', proto: true, real: true, forced: true }, {
getOrInsert: function getOrInsert(key, value) {
if (has(aWeakMap(this), key)) return get(this, key);
set(this, key, value);
return value;
}
});
6 changes: 6 additions & 0 deletions packages/core-js/proposals/map-upsert-v4.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';
// https://github.com/tc39/proposal-upsert
require('../modules/esnext.map.get-or-insert');
require('../modules/esnext.map.get-or-insert-computed');
require('../modules/esnext.weak-map.get-or-insert');
require('../modules/esnext.weak-map.get-or-insert-computed');
3 changes: 2 additions & 1 deletion packages/core-js/stage/2.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require('../proposals/array-is-template-object');
require('../proposals/async-iterator-helpers');
require('../proposals/extractors');
require('../proposals/iterator-range');
require('../proposals/map-upsert-stage-2');
require('../proposals/map-upsert-v4');
require('../proposals/string-dedent');
require('../proposals/symbol-predicates-v2');
// TODO: Obsolete versions, remove from `core-js@4`
Expand All @@ -14,6 +14,7 @@ require('../proposals/async-explicit-resource-management');
require('../proposals/decorators');
require('../proposals/decorator-metadata');
require('../proposals/iterator-helpers');
require('../proposals/map-upsert-stage-2');
require('../proposals/set-methods');
require('../proposals/symbol-predicates');
require('../proposals/using-statement');
Expand Down
2 changes: 2 additions & 0 deletions tests/compat-data/tests-coverage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const ignore = new Set([
'esnext.function.un-this',
'esnext.iterator.as-indexed-pairs',
'esnext.iterator.indexed',
'esnext.map.emplace',
'esnext.map.update-or-insert',
'esnext.map.upsert',
'esnext.math.iaddh',
Expand Down Expand Up @@ -71,6 +72,7 @@ const ignore = new Set([
'esnext.typed-array.filter-out',
'esnext.typed-array.group-by',
'esnext.typed-array.to-spliced',
'esnext.weak-map.emplace',
'esnext.weak-map.upsert',
'web.url-search-params',
'web.url',
Expand Down
16 changes: 11 additions & 5 deletions tests/compat/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1699,9 +1699,6 @@ GLOBAL.tests = {
'esnext.map.delete-all': function () {
return Map.prototype.deleteAll;
},
'esnext.map.emplace': function () {
return Map.prototype.emplace;
},
'esnext.map.every': function () {
return Map.prototype.every;
},
Expand All @@ -1717,6 +1714,12 @@ GLOBAL.tests = {
'esnext.map.from': function () {
return Map.from;
},
'esnext.map.get-or-insert': function () {
return Map.prototype.getOrInsert;
},
'esnext.map.get-or-insert-computed': function () {
return Map.prototype.getOrInsertComputed;
},
'esnext.map.includes': function () {
return Map.prototype.includes;
},
Expand Down Expand Up @@ -1875,8 +1878,11 @@ GLOBAL.tests = {
'esnext.weak-map.delete-all': function () {
return WeakMap.prototype.deleteAll;
},
'esnext.weak-map.emplace': function () {
return WeakMap.prototype.emplace;
'esnext.weak-map.get-or-insert': function () {
return WeakMap.prototype.getOrInsert;
},
'esnext.weak-map.get-or-insert-computed': function () {
return WeakMap.prototype.getOrInsertComputed;
},
'esnext.weak-map.from': function () {
return WeakMap.from;
Expand Down
Loading

0 comments on commit e3e9f37

Please sign in to comment.