upsert

deno land deno doc GitHub release (latest by date) codecov GitHub

test NPM

Maps for emplace, TC39 proposal-upsert implementation.

Entrypoint

This project provides ponyfill and polyfill.

Polyfill has a side effect, so its endpoints are isolated.

The entrypoint of each are as follows:

Type Entrypoint
Ponyfill mod.ts
Polyfill polyfill.ts

Emplace

Add a value to a map like if it does not already have something at key, and will also update an existing value at key.

import { emplace } from "https://deno.land/x/upsert@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const map: Map<string, number>;
declare const key: string;

const result = emplace(map, key, {
  insert: () => 0,
  update: (existing) => existing + 1,
});
assert(map.has(key));

Just insert if missing

You might omit an update if you're handling data that doesn't change, but can still be appended.

import { emplace } from "https://deno.land/x/upsert@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";
import {
  assertType,
  type IsExact,
} from "https://deno.land/std/testing/types.ts";

declare const map: Map<string, number>;
declare const key: string;
declare const value: number;

const result = emplace(map, key, { insert: () => value });

assert(map.has(key));
assertType<IsExact<typeof result, number>>(true);

Just update if present

You might want to omit an insert if you want to perform a function on all existing values.

import { emplace } from "https://deno.land/x/upsert@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";
import {
  assertType,
  type IsExact,
} from "https://deno.land/std/testing/types.ts";

declare const map: Map<string, number>;
declare const key: string;

const result = emplace(map, key, { update: (existing) => existing + 1 });

assertType<IsExact<typeof result, number | undefined>>(true);

Emplaceable

Mixin for emplace.

import { Emplaceable } from "https://deno.land/x/upsert@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

class MyMap extends Emplaceable(Map) {}

assert(new MyMap().emplace);

EmplaceableMap

Map with Emplaceable implementation.

import { EmplaceableMap } from "https://deno.land/x/upsert@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

const map = new EmplaceableMap<string, number>();
declare const key: string;

map.emplace(key, {
  insert: () => 0,
  update: (existing) => existing + 1,
});

assert(map.has(key));

EmplaceableWeakMap

WeakMap with Emplaceable implementation.

import { EmplaceableWeakMap } from "https://deno.land/x/upsert@$VERSION/mod.ts";

const weakMap = new EmplaceableWeakMap();

Polyfill

Polyfill affects the global object. You must be very careful when using it.

import "https://deno.land/x/upsert@$VERSION/polyfill.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

assert(Map.prototype.emplace);
assert(WeakMap.prototype.emplace);

API

See deno doc for all APIs.

License

Copyright © 2023-present Tomoki Miyauchi.

Released under the MIT license