Skip to main content
Deno 2 is finally here 🎉️
Learn more

upsert

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

test NPM standard-readme compliant semantic-release: angular

Maps for emplace, TC39 proposal-upsert implementation.

Table of Contents

Install

deno.land:

import * as mod from "https://deno.land/x/upsert/mod.ts";

npm:

npm i @miyauci/upsert

Usage

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/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,
});
assert(map.has(key));

Insert

Add the entry if the key does not exist.

import { emplace } from "https://deno.land/x/upsert/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 insert

If only inserting is required, insert is available.

import { insert } from "https://deno.land/x/upsert/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

declare const key: string;
declare const value: number;
const map = new Map<typeof key, typeof value>();

insert(map, key, () => value);

assertEquals(map, new Map([[key, value]]));

Update

Update the entry if the key exists.

import { emplace } from "https://deno.land/x/upsert/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 });

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

Just update

If only updating is required, update is available.

import { update } from "https://deno.land/x/upsert/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

declare const key: string;
const map = new Map([[key, 0]]);

update(map, key, (existing) => ++existing);

assertEquals(map, new Map([[key, 1]]));

Emplaceable

Mixin for emplace.

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

class MyMap extends emplaceable(Map) {}

assert(MyMap.prototype.emplace);

decorator style:

note In TypeScript, decorators do not yet affect types.

import {
  type Emplaceable,
  emplaceable,
} from "https://deno.land/x/upsert/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

@emplaceable
class MyMap<K, V> extends Map<K, V> {}
interface MyMap<K, V> extends Emplaceable<K, V> {}

assert(MyMap.prototype.emplace);

EmplaceableMap

Map with Emplaceable implementation.

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

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

assertInstanceOf(map, Map);
assert(map.emplace);

EmplaceableWeakMap

WeakMap with Emplaceable implementation.

import { EmplaceableWeakMap } from "https://deno.land/x/upsert/mod.ts";
import {
  assert,
  assertInstanceOf,
} from "https://deno.land/std/testing/asserts.ts";

const weakMap = new EmplaceableWeakMap();

assertInstanceOf(weakMap, WeakMap);
assert(weakMap.emplace);

Polyfill

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

import "https://deno.land/x/upsert/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.

Contributing

See contributing.

License

MIT © 2023 Tomoki Miyauchi