open-index/open-npm huggingface dataset:
npm package: @qnd/badge
Description: Library for adding badges to images using 2D canvas API.
Author: Jørgen Tau
Latest version: 1.0.0

# [@qnd/badge] Badge drawing for all

[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
[![JSR Version](https://jsr.io/badges/@qnd/badge)](https://jsr.io/@qnd/badge)
[![NPM Version](https://img.shields.io/npm/v/@qnd/badge)](https://www.npmjs.com/package/@qnd/badge)

Library for adding badges to
[images](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)
using
[2D canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API).

![example image](/example.png)

## [💀] Example

Function to set a badge on the favicon:

```ts
import {
  ALIGN,
  type BadgeStyle,
  type CanvasExportOptions,
  canvasToBlob,
  drawBadge,
} from "@qnd/badge";

// Constants
const PNG_OPTIONS = {
  type: "image/png",
  quality: 1,
} satisfies CanvasExportOptions;
const DEFAULT_STYLE = {
  verticalAlign: ALIGN.center,
  horizontalAlign: ALIGN.center,
  fontFamily: '"Courier New", monospace',
  bg: { fillStyle: "#fff" },
  fg: { fillStyle: "#000" },
} satisfies BadgeStyle;

// Setup
const ORIGINAL = document.head.querySelector<HTMLLinkElement>(
  "link[rel=icon]",
)!;
const IMAGE = new Image();
IMAGE.src = ORIGINAL.href;

const { promise, resolve, reject } = Promise.withResolvers();
IMAGE.onerror = reject;
IMAGE.onload = resolve;
await promise;

const SUBSTITUTE = ORIGINAL.cloneNode() as HTMLLinkElement;
SUBSTITUTE.type = PNG_OPTIONS.type;

const CANVAS = new OffscreenCanvas(0, 0);

// Favicon badge setting time
const setFaviconBadge = async (text: string) => {
  URL.revokeObjectURL(SUBSTITUTE.href);

  if (!text.length) {
    return SUBSTITUTE.replaceWith(ORIGINAL);
  }

  drawBadge(CANVAS, IMAGE, text, DEFAULT_STYLE);
  const blob = await canvasToBlob(CANVAS, PNG_OPTIONS);
  SUBSTITUTE.href = URL.createObjectURL(blob);
  ORIGINAL.replaceWith(SUBSTITUTE);
};
```

## [💾] Installation

Choose your fighter:

```sh
npm   install @qnd/badge
yarn  add     @qnd/badge
pnpm  install @qnd/badge
deno  install jsr:@qnd/badge
```

## [🖥️] Tasks

```sh
# Transpile to JS + D.TS
deno task transpile

# Run publishing in dry mode
deno task dry-run

# Prepare for publishing (does all of the above)
deno task prepare

# Publish to JSR and NPM
deno task publish
```

## [📝] License

This work is licensed under
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
[NOTICE](/NOTICE)).
npm package: @qnd/iwm
Description: Iterable WeakMap
Author: Jørgen Tau
Latest version: 1.1.0

# [@qnd/iws] Set, both Weak and Iterable

[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
[![JSR Version](https://jsr.io/badges/@qnd/iws)](https://jsr.io/@qnd/iws)
[![NPM Version](https://img.shields.io/npm/v/@qnd/iws)](https://www.npmjs.com/package/@qnd/iws)

[WeakSet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet)
made iterable.

## [💾] Installation

Choose your fighter:

```sh
npm   install @qnd/iws
yarn  add     @qnd/iws
pnpm  install @qnd/iws
deno  install jsr:@qnd/iws
```

## [💀] Example

```ts
import { IterableWeakSet } from "@qnd/iws";

type Listener = (data: Record<string, any>) => void;

const listeners = new IterableWeakMap<{ type: string }, Listener>();
const key = { type: "type" };
const logValue = (data) => console.log(data.value);
listeners.set(key, logValue);
for (const listener of listeners.values()) listener({ value: "abc" });
listeners.delete(key);
```

## [🖥️] Tasks

```sh
# Run tests
deno task test

# Run publishing in dry mode
deno task dry-run

# Prepare for publishing (does all of the above)
deno task prepare

# Publish to JSR and NPM
deno task publish
```

## [📝] License

This work is licensed under
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
[NOTICE](/NOTICE)).
npm package: @qnd/iws
Description: Iterable WeakSet
Author: Jørgen Tau
Latest version: 1.1.0

# [@qnd/iws] Set, both Weak and Iterable

[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
[![JSR Version](https://jsr.io/badges/@qnd/iws)](https://jsr.io/@qnd/iws)
[![NPM Version](https://img.shields.io/npm/v/@qnd/iws)](https://www.npmjs.com/package/@qnd/iws)

[WeakSet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet)
made iterable.

## [💾] Installation

Choose your fighter:

```sh
npm   install @qnd/iws
yarn  add     @qnd/iws
pnpm  install @qnd/iws
deno  install jsr:@qnd/iws
```

## [💀] Example

```ts
import { IterableWeakSet } from "@qnd/iws";

const set = new IterableWeakSet<(() => void)>();

const listener = () => console.log("event");
set.add(listener);
for (const item of set) item();
set.delete(listener);
```

## [🖥️] Tasks

```sh
# Run tests
deno task test

# Run publishing in dry mode
deno task dry-run

# Prepare for publishing (does all of the above)
deno task prepare

# Publish to JSR and NPM
deno task publish
```

## [📝] License

This work is licensed under
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
[NOTICE](/NOTICE)).
npm package: @qnd/phf
Description: Perfect Hash Function primitives generator.
Author: Jørgen Tau
Latest version: 1.0.0

# [@qnd/phf] Quick-and-Dirty Perfect Hash Function Generation

[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
[![JSR Version](https://jsr.io/badges/@qnd/phf)](https://jsr.io/@qnd/phf)
[![NPM Version](https://img.shields.io/npm/v/@qnd/phf)](https://www.npmjs.com/package/@qnd/phf)

One function to ~~rule them all~~ generate all the primitives needed to
implement a perfect hash function lookup.

There is also a TypeScript reference implemenetation that turns primitives into
TypeScript code.

## [💀] Example

```ts
import { genPhfPrimitives, genPhfTs } from "@qnd/phf";

const dict = { let: 0, const: 1, if: 2, else: 3 };
const primitives = genPhfPrimitives(dict);
const code = genPhfTs(primitives);
Deno.writeTextFileSync("./phf.ts", code);
```

## [💾] Installation

Choose your fighter:

```sh
npm   install @qnd/phf
yarn  add     @qnd/phf
pnpm  install @qnd/phf
deno  install jsr:@qnd/phf
```

## [🖥️] Tasks

```sh
# Run tests
deno task test

# Transpile to JS + D.TS
deno task transpile

# Run publishing in dry mode
deno task dry-run

# Prepare for publishing (does all of the above)
deno task prepare

# Publish to JSR and NPM
deno task publish
```

## [📝] License

This work is licensed under
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
[NOTICE](/NOTICE)).
npm package: @qnd/signals
Description: A lightweight implementation of signals with explicit subscription.
Author: Jørgen Tau
Latest version: 2.1.0

# [@qnd/signals] Yet another signal lib

[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
[![JSR Version](https://jsr.io/badges/@qnd/signals)](https://jsr.io/@qnd/signals)
[![NPM Version](https://img.shields.io/npm/v/@qnd/signals)](https://www.npmjs.com/package/@qnd/signals)

No promos here, just my implementation of signals.

## [💀] Example

```ts
import { createEffect, createSignal } from "@qnd/signals";

const aSig = createSignal(10);
const bSig = createSignal(20);
const sumSig = createSignal((track) => track(aSig) + track(bSig));

const clearEffect = createEffect((track) => {
  console.log(`${track(aSig)} + ${track(bSig)} = ${track(sumSig)}`);
});

// ... after effect is no longer needed

clearEffect();
```

## [💾] Installation

Choose your fighter:

```sh
npm   install @qnd/signals
yarn  add     @qnd/signals
pnpm  install @qnd/signals
deno  install jsr:@qnd/signals
```

## [🖥️] Tasks

```sh
# Run tests
deno task test

# Transpile to JS + D.TS
deno task transpile

# Run publishing in dry mode
deno task dry-run

# Prepare for publishing (does all of the above)
deno task prepare

# Publish to JSR and NPM
deno task publish
```

## [📝] License

This work is licensed under
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
[NOTICE](/NOTICE)).