Is your feature request related to a problem? Please describe
For interoperability reasons, I'd like to have Map available (Set coming after if this works well).
Describe the solution you'd like
Imagine this map.js file is all we need to have import Map from './compat/map.js'; around, followed by a globalThis.Map ??= Map; after.
const iterator = Symbol.iterator;
const setPrototypeOf = Object.setPrototypeOf;
let Map = globalThis.Map;
if (!Map) {
Map = function Map(iterable) {
const keys = [];
const values = [];
const map = setPrototypeOf(
{
clear() {
keys.length = 0;
values.length = 0;
},
delete(key) {
const i = keys.indexOf(key);
if (i < 0) return false;
keys.splice(i, 1);
values.splice(i, 1);
return true;
},
entries() {
return map[iterator]();
},
forEach(callback) {
for (let i = 0; i < keys.length; i++)
callback(values[i], keys[i], map);
},
get(key) {
const i = keys.indexOf(key);
return i < 0 ? undefined : values[i];
},
getOrInsert(key, defaultValue) {
const i = keys.indexOf(key);
return -1 < i ? values[i] : (values[keys.push(key) - 1] = defaultValue);
},
getOrInsertComputed(key, callback) {
const i = keys.indexOf(key);
return -1 < i ? values[i] : (values[keys.push(key) - 1] = callback(key));
},
has(key) {
return -1 < keys.indexOf(key);
},
keys() {
return keys[iterator]();
},
set(key, value) {
let i = keys.indexOf(key);
if (i < 0) i = keys.push(key) - 1;
values[i] = value;
return map;
},
values() {
return values[iterator]();
},
get size() {
return keys.length;
},
[iterator]() {
const iterable = [];
for (let i = 0; i < keys.length; i++)
iterable.push([keys[i], values[i]]);
return iterable[iterator]();
},
},
Map.prototype,
);
if (iterable) {
const g = iterable[iterator]();
do {
const c = g.next();
if (c.done) break;
const entry = c.value;
map.set(entry[0], entry[1]);
} while (true);
}
return map;
};
Map.groupBy = function(iterable, callback) {
const map = new Map;
const values = [];
const g = iterable[iterator]();
do {
const c = g.next();
if (c.done) break;
const value = c.value;
const key = callback(value);
map.getOrInsert(key, values).push(value);
} while (true);
return map;
};
}
export default Map;
Describe alternatives you've considered
I haven't looked into the core of this project but:
- I love it already!
- I've been writing Web polyfills for 25+ years at this point
- I'd like to help this move forward with Web compat as I can (and when I can, of course)
Additional context
Common polyfills will not work in here because there are too many constraints around what is still accepted in common JS and what is just not possible in here.
My polyfill experience is all about that, meaning I can write ad-hoc code working around common/modern APIs constraints, so here my first contribution because without Map I believe this is a no-go for tons of possibly working solutions out of the biggest PL ecosystem out there, and this is a Web related project too 🥰
Is your feature request related to a problem? Please describe
For interoperability reasons, I'd like to have
Mapavailable (Setcoming after if this works well).Describe the solution you'd like
Imagine this
map.jsfile is all we need to haveimport Map from './compat/map.js';around, followed by aglobalThis.Map ??= Map;after.Describe alternatives you've considered
I haven't looked into the core of this project but:
Additional context
Common polyfills will not work in here because there are too many constraints around what is still accepted in common JS and what is just not possible in here.
My polyfill experience is all about that, meaning I can write ad-hoc code working around common/modern APIs constraints, so here my first contribution because without
MapI believe this is a no-go for tons of possibly working solutions out of the biggest PL ecosystem out there, and this is a Web related project too 🥰