open-index/open-npm huggingface dataset:
npm package: @nano-di/core
Description: A tiny tool to improve DX when writing (and more importantly **testing**) Object-Oriented typescript code.
Latest version: 0.0.5

# `nano-di`
A tiny tool to improve DX when writing (and more importantly **testing**) Object-Oriented typescript code.

✅ Tiny footprint, good practices baked in

  * 🦥 Lazy instantiation automagically prevents unncessary instantiation of unused dependencies.
  * 🐔 Once instantiated the dependency is remembered and reused for all subsequent calls

✅ Explicit dependency declaration without the work for it.

* ☢️ No need to fumble with decorators
* 🤡 No need to manually declare single-use interfaces
* 🤯 No need to bend your mind around injection Containers
* 🥳 No special notation for injectable classes. All classes are fair game.
* Runs anywhere JS runs, no need for `ReflectMetadata` support

☮️ Aiming for the testing Zen
* 🏋️ No need to fumble around to remember that are the dependencies of the class you're testing. Explicit dependencies mean typescript can now remember you
* 🌠 Developer-first architecture - Optional explicit dependency method declaration means you can now keep things under (some) control even in large codebases
* 😱 Lower the pain of having to manually stub and clean dependencies.

✅ Batteries included, easily replaceable
* Adapters for Jest and Mocha work out of the box. Integration your own is just a piece of cake.
* Easily disable `nano-di` when you need to run integration tests. No pain inflicted, guaranteed.
npm package: @nano-edge/cli
Description: A simple CLI used to deploy an app to NanoEdge
Author: David Adamson
Latest version: 1.11.1

# NanoEdge

All you need to do to deploy your app is to run the following command:
```sh
npx @nano-edge/cli deploy
```

Advanced usage:

Do not forget to set the `NANO_EDGE_AUTH_TOKEN` env var, which is required by the cli.
```sh
export NANO_EDGE_AUTH_TOKEN=xxx npx @nano-edge/cli deploy --env.MY_SECRET=$SOME_SECRET
```
To customize cli options, you can create a file `nano-edge.config.json`:
```json
{
  "env": {
    "SOME_ENV_VAR": "SOME_VALUE"
  }
}
```

> [!IMPORTANT]
> Do not deploy secrets that are really secret! These secrets might be exploitable as nano-edge is currently not (yet?) hardened!

## Build output API example:

- functions/api.js
- functions/env.json
- static/index.html
- static/main.js

The signature of a function is `export default async (request: Request) => Promise<Response>`.\
A function can access env vars by using process.env.\
`env.json` will be generated by the cli if `nano-edge.config.ts` contains env vars. The file is overwritten if it already did exist before.

## How inbound traffic would be handled by which resource from the build output:

- `/api` -> `functions/api.js` (function exec)
- `/api/some/sub/path` -> `functions/api.js` (function exec)
- `/index.html` -> `static/index.html` (served static)
- `/main.js` -> `static/main.js` (served static)
- `/some/random/path` -> `static/index.html` (served static)
- Edge-case (precedence): If a static file exists with same name as a function, the static file is
  not served.
  Instead, the function is executed.

## Local development

If this is the first time you cloned this repository, make sure to run `npm install` in all subdirectories to make sure all dependencies are present. \
Only then continue with the following steps:

Just run the following two scripts to start the stack and deploy an example app:

```sh
docker compose -f compose.yml -f compose.dev.yml up --build --watch --remove-orphans
```

```sh
cd example-app && npm run deploy
```
npm package: @nano-faker/core
Description: Core utilities for nano-faker - seeded random number generation
Author: Rintu Raj C
Latest version: 1.0.1

# @nano-faker/core

> Foundation package for nano-faker with seeded random number generation

## Installation

```bash
pnpm add @nano-faker/core
```

## Features

- 🎲 Deterministic random number generation (mulberry32 algorithm)
- 🔢 Integer and float generation
- 🎯 Array utilities (pick, shuffle)
- 📦 < 1KB gzipped
- 🌳 Fully tree-shakable

## Usage

### Random Number Generation

```typescript
import { setSeed, random, int, float } from '@nano-faker/core';

// Set seed for deterministic output
setSeed(12345);

// Generate random float [0, 1)
const r = random(); // 0.7234...

// Generate random integer [min, max]
const age = int(18, 80); // 42

// Generate random float with precision
const price = float(10.0, 100.0, 2); // 45.67
```

### Array Utilities

```typescript
import { pick, shuffle } from '@nano-faker/core';

// Pick random element
const color = pick(['red', 'green', 'blue']); // 'green'

// Shuffle array (returns new array)
const shuffled = shuffle([1, 2, 3, 4, 5]); // [3, 1, 5, 2, 4]
```

## API

### `setSeed(seed: number): void`

Set the seed for deterministic random number generation.

**Parameters:**
- `seed` - Positive integer seed value

**Example:**
```typescript
setSeed(12345);
```

### `getSeed(): number`

Get the current seed value.

**Returns:** Current seed

### `random(): number`

Generate a random float between 0 (inclusive) and 1 (exclusive).

**Returns:** Random float [0, 1)

### `int(min: number, max: number): number`

Generate a random integer between min and max (both inclusive).

**Parameters:**
- `min` - Minimum value (inclusive)
- `max` - Maximum value (inclusive)

**Returns:** Random integer [min, max]

### `float(min: number, max: number, precision?: number): number`

Generate a random float between min and max.

**Parameters:**
- `min` - Minimum value (inclusive)
- `max` - Maximum value (exclusive)
- `precision` - Number of decimal places (default: 2)

**Returns:** Random float [min, max)

### `pick<T>(array: T[]): T`

Pick a random element from an array.

**Parameters:**
- `array` - Array to pick from

**Returns:** Random element

**Throws:** Error if array is empty

### `shuffle<T>(array: T[]): T[]`

Shuffle an array using Fisher-Yates algorithm.

**Parameters:**
- `array` - Array to shuffle

**Returns:** New shuffled array (original unchanged)

## License

MIT
npm package: @nano-faker/internet
Description: Internet data generation utilities for nano-faker
Author: Rintu Raj C
Latest version: 1.0.1

# @nano-faker/internet

> Internet-related data generation for nano-faker

## Installation

```bash
pnpm add @nano-faker/core @nano-faker/person @nano-faker/internet
```

## Usage

```typescript
import { setSeed } from '@nano-faker/core';
import { email, username, domain, url, ipv4 } from '@nano-faker/internet';

setSeed(12345);

email();     // "sarah.johnson42@gmail.com"
username();  // "sarah_johnson42"
domain();    // "example.com"
url();       // "https://example.com"
ipv4();      // "192.168.1.42"
```

## API

### `email(): string`

Generate a random email address.

Uses procedurally generated names from `@nano-faker/person` and a minimal domain list.

**Returns:** Email address (e.g., "sarah.johnson42@gmail.com")

### `username(): string`

Generate a random username.

**Returns:** Username (e.g., "sarah_johnson42", "marcus.rod")

### `domain(): string`

Generate a random domain name.

**Returns:** Domain (e.g., "example.com", "mysite.io")

### `url(): string`

Generate a random URL.

**Returns:** URL (e.g., "https://example.com", "http://mysite.io")

### `ipv4(): string`

Generate a random IPv4 address.

**Returns:** IPv4 address (e.g., "192.168.1.42")

## License

MIT
npm package: @nano-faker/number
Description: Number generation utilities for nano-faker
Author: Rintu Raj C
Latest version: 1.0.1

# @nano-faker/number

> Number generation utilities for nano-faker

## Installation

```bash
pnpm add @nano-faker/core @nano-faker/number
```

## Usage

```typescript
import { setSeed } from '@nano-faker/core';
import { age, id, otp, range } from '@nano-faker/number';

setSeed(12345);

age();           // 42 (default: 18-80)
age(5, 12);      // 8 (custom range)
id();            // "47382910" (8 digits)
id(12);          // "847362910485"
otp();           // "472839" (6 digits)
otp(4);          // "8473"
range(0, 100);   // 73
```

## API

### `age(min?: number, max?: number): number`

Generate a random age.

**Default:** min=18, max=80

### `id(length?: number): string`

Generate a numeric ID.

**Default:** length=8

### `otp(length?: number): string`

Generate a one-time password.

**Default:** length=6

### `range(min: number, max: number): number`

Generate a number within range (alias for `int` from core).

## License

MIT
npm package: @nano-faker/patterns
Description: Pattern-based fake data generation for nano-faker
Author: Rintu Raj C
Latest version: 1.0.1

# @nano-faker/patterns

> Pattern-based fake data generation for nano-faker

## Installation

```bash
pnpm add @nano-faker/core @nano-faker/patterns
```

## Usage

```typescript
import { setSeed } from '@nano-faker/core';
import { fake } from '@nano-faker/patterns';

setSeed(12345);

fake("USR-####-@@");    // "USR-4728-ab"
fake("###-##-####");    // "472-83-9102" (SSN-like)
fake("***-***-***");    // "a7X-9Bz-K4m"
fake("Order-#####");    // "Order-47382"
```

## Placeholders

| Placeholder | Description | Example |
|------------|-------------|---------|
| `#` | Random digit (0-9) | `5` |
| `@` | Random lowercase letter (a-z) | `m` |
| `*` | Random alphanumeric | `K` |
| `\` | Escape character | `\#` → `#` |

## Examples

### User IDs
```typescript
fake("USR-####-@@@@");  // "USR-4728-abcd"
```

### License Keys
```typescript
fake("****-****-****-****");  // "a7X9-BzK4-mP2q-R8vN"
```

### SSN-like Patterns
```typescript
fake("###-##-####");  // "472-83-9102"
```

### Escaped Characters
```typescript
fake("\\#\\#\\#");  // "###" (literal)
fake("ID-\\#-####");  // "ID-#-4728"
```

## API

### `fake(pattern: string): string`

Generate fake data based on a pattern string.

**Parameters:**
- `pattern` - Pattern string with placeholders

**Returns:** Generated string matching the pattern

**Example:**
```typescript
fake("USR-####-@@");  // "USR-4728-ab"
```

## License

MIT
npm package: @nano-faker/person
Description: Person data generation utilities for nano-faker
Author: Rintu Raj C
Latest version: 1.0.1

# @nano-faker/person

> Person data generation with syllable-based procedural names

## Installation

```bash
pnpm add @nano-faker/core @nano-faker/person
```

## Features

- 🎯 Syllable-based name generation (no large datasets)
- 📦 < 500B gzipped
- 🎲 Deterministic output
- 🌳 Fully tree-shakable

## Usage

```typescript
import { setSeed } from '@nano-faker/core';
import { firstName, lastName, fullName, gender } from '@nano-faker/person';

setSeed(12345);

firstName();  // "Alison"
lastName();   // "Anderson"
fullName();   // "Marcus Rodriguez"
gender();     // "female"
```

## How It Works

Instead of using large name datasets (which bloat bundle size), nano-faker uses **procedural generation** with syllable combinations:

```typescript
// Traditional approach (large dataset):
const names = ["Alice", "Bob", "Charlie", ...] // 1000s of names

// nano-faker approach (syllables):
const syllables = ["al", "an", "ar", ...] // ~100 syllables
// Combines to create realistic names
```

This keeps bundle size minimal while generating realistic-sounding names.

## API

### `firstName(): string`

Generate a procedural first name.

**Returns:** Capitalized first name (e.g., "Alison", "Marcus")

### `lastName(): string`

Generate a procedural last name.

**Returns:** Capitalized last name (e.g., "Anderson", "Rodriguez")

### `fullName(): string`

Generate a full name (first + last).

**Returns:** Full name (e.g., "Sarah Johnson")

### `gender(): string`

Generate a random gender.

**Returns:** One of: "male", "female", "non-binary", "other"

## License

MIT
npm package: @nano-forms/core
Description: Core of Nano Forms
Author: Nano Forms
Latest version: 0.2.4

# @nano-forms/core

## Installing

Using npm:

```bash
$ npm install @nano-forms/core
```

## Swagger

[https://swagger.nanoforms.io](https://swagger.nanoforms.io)

## Examples

### Create Form

```typescript
import { FormClient, Form, FormRequest } from '@nano-forms/core';

const formClient: FormClient = new FormClient(null, '{key}', '{secret}');

const formRequest: FormRequest = {}; // omitted for documentation purposes

const form: Form = await formClient.create(formRequest);
```

### Retrieve Form

```typescript
import { FormClient, Form } from '@nano-forms/core';

const formClient: FormClient = new FormClient(null, '{key}', '{secret}');

const form: Form = await formClient.find('12r42z');
```

## License

[MIT](LICENSE)
npm package: @nano-sql/adapter-leveldb
Description: Easily Run LevelDB in NodeJS with nanoSQL 2!
Author: Scott Lott
Latest version: 2.0.5

<p align="center">
  <a href="https://github.com/ClickSimply/Nano-SQL/tree/2.0/packages/Core">
    <img src="https://github.com/ClickSimply/Nano-SQL/raw/2.0/graphics/logo.png" alt="nanoSQL Logo">
  </a>
</p>
<p align="center">
  <a href="https://badge.fury.io/js/%40nano-sql%2Fadapter-leveldb">
    <img src="https://badge.fury.io/js/%40nano-sql%2Fadapter-leveldb.svg" alt="nanoSQL Logo">
  </a>
  <a href="https://github.com/ClickSimply/@nano-sql/core/blob/master/LICENSE">
    <img src="https://img.shields.io/npm/l/express.svg?style=flat-square" alt="nanoSQL Logo">
  </a>
</p>

<h1 align="center">nanoSQL 2 LevelDB Adapter</h1>
<p align="center">
  <strong>Allows you to run LevelDB in NodeJS with <a href="https://www.npmjs.com/package/@nano-sql/core">nanoSQL 2</a></strong>
</p>

[Documentation](https://nanosql.io/adapters/leveldb.html) | [Bugs](https://github.com/ClickSimply/Nano-SQL/issues) | [Chat](https://gitter.im/nano-sql/community)

# Installation

```sh
npm i @nano-sql/adapter-leveldb --save
```

# Usage

```ts
import { LevelDB } from "@nano-sql/adapter-leveldb";
import { nSQL } from "@nano-sql/core";

nSQL().createDatabase({
    id: "my_db",
    mode: new LevelDB(),
    tables: [...]
}).then(...)
```

# API

The `LevelDB` class accepts two optional constructor arguments.

## path:string (optional)
Can be `undefined` to use default (`__dirname`), allows you to specify which folder to place the database folders into.

## useIndex:boolean (optional)
Store the database index in webassembly memory. You get these tradeoffs:
- Dramatically improved offset/limit queries. (pagination)
- Dramatically improved index/count reads.
- Slightly reduces insert/delete performance.
- All keys across all tables must occupy less than ~4GB of space.

# MIT License

Copyright (c) 2019 Scott Lott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

# Changelog

## [2.0.4]
- Moved to new index code.

## [2.0.3]
- Fixed issue with WASM index.

## [2.0.1]
- Fixed an issue with a file not being copied to the lib folder.

## [2.0.0]
- First release
npm package: @nano-sql/adapter-mysql
Description: Easily Run MySQL with nanoSQL 2!
Author: Scott Lott
Latest version: 2.0.4

<p align="center">
  <a href="https://github.com/ClickSimply/Nano-SQL/tree/2.0/packages/Core">
    <img src="https://github.com/ClickSimply/Nano-SQL/raw/2.0/graphics/logo.png" alt="nanoSQL Logo">
  </a>
</p>
<p align="center">
  <a href="https://badge.fury.io/js/%40nano-sql%2Fadapter-mysql">
    <img src="https://badge.fury.io/js/%40nano-sql%2Fadapter-mysql.svg" alt="nanoSQL Logo">
  </a>
  <a href="https://github.com/ClickSimply/@nano-sql/core/blob/master/LICENSE">
    <img src="https://img.shields.io/npm/l/express.svg?style=flat-square" alt="nanoSQL Logo">
  </a>
</p>

<h1 align="center">nanoSQL 2 MySQL Adapter</h1>
<p align="center">
  <strong>Allows you to run MySQL with <a href="https://www.npmjs.com/package/@nano-sql/core">nanoSQL 2</a></strong>
</p>

[Documentation](https://nanosql.io/adapters/mysql.html) | [Bugs](https://github.com/ClickSimply/Nano-SQL/issues) | [Chat](https://gitter.im/nano-sql/community)


# Installation

```sh
npm i @nano-sql/adapter-mysql --save
```

# Usage

```ts
import { MySQL } from "@nano-sql/adapter-mysql";
import { nSQL } from "@nano-sql/core";

nSQL().connect({
    id: "my_db",
    mode: new MySQL({ // required
		host: "localhost",
		database: "test",
		user: "root",
		password: "secret"
    }),
    tables: [...]
}).then(...)
```

# API

The `MySQL` class accepts one optional argument as its constructor.

### MySQL Connect Options
The first object is passed directly into the backend mysql library to adjust the connect preferencs.  This object is fully documented [here](https://www.npmjs.com/package/mysql#connection-options).

# MIT License

Copyright (c) 2019 Scott Lott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

# Changelog

## [2.0.4]
- Documentation and dependency updates.

## [2.0.3]
- Readme and dependency updates.

## [2.0.2]
- Added quotes to table names.

## [2.0.1]
- Readme tweak

## [2.0.0]
- First release
npm package: @nano-sql/adapter-sqlite-nativescript
Description: Easily Run SQLite in NativeScript with nanoSQL 2!
Author: Scott Lott
Latest version: 2.0.3

<p align="center">
  <a href="https://github.com/ClickSimply/Nano-SQL/tree/2.0/packages/Core">
    <img src="https://github.com/ClickSimply/Nano-SQL/raw/2.0/graphics/logo.png" alt="nanoSQL Logo">
  </a>
</p>
<p align="center">
  <a href="https://badge.fury.io/js/%40nano-sql%2Fadapter-sqlite-nativescript">
    <img src="https://badge.fury.io/js/%40nano-sql%2Fadapter-sqlite-nativescript.svg" alt="nanoSQL Logo">
  </a>
  <a href="https://github.com/ClickSimply/@nano-sql/core/blob/master/LICENSE">
    <img src="https://img.shields.io/npm/l/express.svg?style=flat-square" alt="nanoSQL Logo">
  </a>
</p>

<h1 align="center">nanoSQL 2 SQLite NativeScript Adapter</h1>
<p align="center">
  <strong>Allows you to run SQLite in NativeScript with <a href="https://www.npmjs.com/package/@nano-sql/core">nanoSQL 2</a></strong>
</p>

[Documentation](https://nanosql.io/adapters/sqlite-nativescript.html) | [Bugs](https://github.com/ClickSimply/Nano-SQL/issues) | [Chat](https://gitter.im/nano-sql/community)

Includes all typings, runs in iOS or Android

# Installation

```sh
tns plugin add @nano-sql/adapter-sqlite-nativescript
```

# Usage

```ts
import { NativeSQLite } from "@nano-sql/adapter-sqlite-nativescript";
// MUST include nSQL from the lib path.
import { nSQL } from "@nano-sql/core/lib/index";

nSQL().createDatabase({
    id: "my_db",
    mode: new NativeSQLite(),
    tables: [...]
}).then(...)
```

# API

The `NativeSQLite` class accepts one optional arguments in it's constructor.

### Filename
The first argument is the filename to the SQLite database to connect to, default is to use the database ID as the filename.

# MIT License

Copyright (c) 2019 Scott Lott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

# Changelog

## [2.0.2]
- SQLite now uses database ID as name instead of ":memory:" by default.

## [2.0.1]
- Dependency & Documentation updates.

## [2.0.0]
- First release
npm package: @nano-utils/evt-src
Description: A lightweight event source library inspired by the nanoevents library
Author: Jason Xu
Latest version: 1.3.1

## Description

A lightweight event source library inspired by the nanoevents library

## Installation

```
npm i @nano-utils/event-src
```

or

```
yarn add @nano-utils/event-src
```

## Usage

```js
import { EventSrc } from '@nano-utils/event-src';

const src = new EventSrc();

src.on('MY_EVENT', (evt) => {
	console.log(`Foo: ${evt.foo}`);
});

src.dispatch('MY_EVENT', { foo: 'bar' }); // Foo: bar
```

This package comes fully typed:

```ts
import { EventSrc } from '@nano-utils/event-src';

type Events = {
	MY_EVENT: [{ foo: string }];
};

const src = new EventSrc<Events>();

src.on('MY_EVENT', (evt) => {
	console.log(`Foo: ${evt.foo}`);
});

src.dispatch('MY_EVENT', { foo: 'baz' }); // Foo: baz
```

The type `Events` may also be declared as an interface:

```ts
import { EventSrc } from '@nano-utils/event-src';

interface Events {
	MY_EVENT: [{ foo: string }];
}

const src = new EventSrc<Events>();

src.on('MY_EVENT', (evt) => {
	console.log(`Foo: ${evt.foo}`);
});

src.dispatch('MY_EVENT', { foo: 'fizz' }); // Foo: fizz
```

## EventSrc.wrap

EventSrc may also be used to "wrap" existing event sources with an addEventListener method (ie. DOM Elements). An array of the underlying events to listen to must be passed in.

```ts
import { EventSrc } from '@nano-utils/event-src';

const btn = document.getElementById<HTMLButtonElement>('my-btn');

const src = EventSrc.wrap<HTMLElementEventMap>(btn, 'click');

src.on('click', (evt) => console.log(evt));
```

## Usage Notes:

-   All listeners for each event are run synchronously, in the order in which they are added
npm package: @nano-utils/json-import
Description: A library to make changes to objects imported from JSON files reflected in the file
Author: Jason Xu
Latest version: 2.0.0

## Description

A library to make changes to objects imported from JSON files reflected in the file

## Installation

```
npm i @nano-utils/json-import
```

or

```
yarn add @nano-utils/json-import
```

## Usage

```js
import { importJSON } from '@nano-utils/json-import';

/** data.json
 * 	{
 * 		"foo": "bar"
 * 	}
 */
const obj = importJSON('./data.json');

console.log(obj); // { foo: 'bar' }
```

This package comes fully typed:

```ts
import { importJSON } from '@nano-utils/json-import';

type MyObject = {
	foo: string;
};

/** data.json
 * 	{
 * 		"foo": "bar"
 * 	}
 */
const obj: MyObject = importJSON<MyObject>('./data.json');

console.log(obj); // { foo: 'bar' }
```

We support using the [`yup`](https://www.npmjs.com/package/yup) library to perform validation:

```ts
import { importJSON } from '@nano-utils/json-import';
import { object, string } from 'yup';

type MyObject = {
	foo: string;
};

const schema = object({
	foo: string()
});

/** data.json
 * 	{
 * 		"foo": "bar"
 * 	}
 */
const obj: MyObject = importJSON<MyObject>('./data.json', schema);

console.log(obj); // { foo: 'bar' }
```

## Usage Notes:

-   When working with arrays, make sure to always assign values, do not use methods such as `push` or `splice`. Otherwise, the underlying proxy will not detect your changes.
-   When validating with `yup`, it is recommended to use strict mode for your types, otherwise you may run into type coercion issues (see [here](https://github.com/jquense/yup/issues/54) for more information.)
-   `requireJSON` is equivalent to `importJSON`
npm package: @nano-utils/logger
Description: A simple logger for fancier and modularized log messages
Author: Jason Xu
Latest version: 1.0.1

## Description

A dead simple logging library

## Installation

```
npm i @nano-utils/logger
```

or

```
yarn add @nano-utils/logger
```

## Usage

```js
import { Logger } from '@nano-utils/logger';

const logger = new Logger('My Logger');

logger.log('Hi'); // [My Logger] Hi
```

```js
import { Logger } from '@nano-utils/logger';

const logger = new Logger('My Logger');

logger.log(2, 'arguments'); // [My Logger] 2 arguments
```
npm package: @nano-utils/object-proxy
Description: A small library to make object proxying easier
Author: Jason Xu
Latest version: 1.2.0

## Description

A small library to make object proxying easier

## Installation

```
npm i @nano-utils/object-proxy
```

or

```
yarn add @nano-utils/object-proxy
```

## Usage

The `makeProxy` function creates a proxy object, which will call the supplied listener upon property changes with the property's path (delimited by `.`), the new value of the property, and the old value of the property

```js
import { makeProxy } from '@nano-utils/object-proxy';

const obj = { foo: 'bar' };

const proxy = makeProxy(obj, (prop, newValue, oldValue) => console.log(prop, newValue, oldValue));

proxy.foo = 'baz'; // foo baz bar
```

This package comes fully typed:

```ts
import { makeProxy } from '@nano-utils/object-proxy';

type MyObject = {
	foo: string;
};

const obj: MyObject = { foo: 'bar' };

const proxy = makeProxy<MyObject>(obj, (prop, newValue, oldValue) => console.log(prop, newValue, oldValue));

proxy.foo = 'baz'; // foo baz bar
```
npm package: @nano-utils/server-socket
Description: A lightweight wrapper library around the ws WebSocket API
Author: Jason Xu
Latest version: 2.0.0

## Description

A lightweight wrapper library around the ws WebSocket API

## Installation

```
npm i @nano-utils/server-socket
```

or

```
yarn add @nano-utils/server-socket
```

## Usage

```js
import { Socket } from '@nano-utils/server-socket';
import WebSocket from 'ws';

const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', (sock) => {
	const socket = new Socket(sock);

	socket.on('MY_MESSAGE', (msg) => {
		console.log(`Type: ${msg.type}, Foo: ${msg.foo}`); // Type: MY_MESSAGE, Foo: something
	});
});
```

With Typescript:

```ts
import { Socket } from '@nano-utils/server-socket';
import WebSocket from 'ws';

type Msgs = {
	MY_MESSAGE: { type: 'MY_MESSAGE'; foo: string };
};

const wss = new WebSocket.Server({ port: 3000 }); // second type parameter is for outgoing messages

wss.on('connection', (sock) => {
	const socket = new Socket<Msgs, {}>(sock);

	socket.on('MY_MESSAGE', (msg) => {
		console.log(`Type: ${msg.type}, Foo: ${msg.foo}`); // Type: MY_MESSAGE, Foo: something
	});
});
```

Sending Messages:

```ts
import { Socket } from '@nano-utils/server-socket';
import WebSocket from 'ws';

type IMsgs = {
	CONNECTION: { type: 'CONNECTION'; id: string };
};

type OMsgs = {
	CONNECTED: { type: 'CONNECTED'; user: { id: string; name: string } };
};

const wss = new WebSocket.Server('wss://example.com');

wss.on('connection', (sock) => {
	const socket = new Socket<IMsgs, OMsgs>(sock);

	socket.on('CONNECTION', (msg) => {
		socket.send({ type: 'CONNECTED', user: { id: msg.id, name: 'foo' } });
	});
});
```

Awaiting Messages:

```ts
import { Socket } from '@nano-utils/server-socket';
import WebSocket from 'ws';

type IMsgs = {
	CONNECTION: { type: 'CONNECTION'; id: string };
};

type OMsgs = {
	CONNECTED: { type: 'CONNECTED'; user: { id: string; name: string } };
};

const wss = new WebSocket.Server('wss://example.com');

wss.on('connection', async (sock) => {
	const socket = new Socket<IMsgs, OMsgs>(sock);

	const msg = await socket.await('CONNECTION');

	socket.send({ type: 'CONNECTED', user: { id: msg.id, name: 'foo' } });
});
```

## Usage Notes:

-   Each message (both outgoing and incoming) must have a type property, which is litstened to in the `on` method
-   If using typescript, each message's key in the message type map must match the type property of the message
-   This package is designed to be paired with the [web-sockets](https://npmjs.org/packages/@nano-utils/web-sockets) library on the frontend, but any client that sends messages in json format with type properties will work
npm package: @nano-utils/web-socket
Description: A lightweight wrapper library around the web WebSocket API
Author: Jason Xu
Latest version: 1.2.0

## Description

A lightweight wrapper library around the native WebSocket API

## Installation

```
npm i @nano-utils/web-socket
```

or

```
yarn add @nano-utils/web-socket
```

## Usage

```js
import { Socket } from '@nano-utils/web-socket';

const socket = new Socket('wss://example.com');

socket.on('MY_MESSAGE', (msg) => {
	console.log(`Type: ${msg.type}, Foo: ${msg.foo}`); // Type: MY_MESSAGE, Foo: something
});
```

With Typescript:

```ts
import { Socket } from '@nano-utils/web-socket';

type Msgs = {
	MY_MESSAGE: { type: 'MY_MESSAGE'; foo: string };
};

const socket = new Socket<Msgs, {}>('wss://example.com'); // second type parameter is for outgoing messages

socket.on('MY_MESSAGE', (msg) => {
	console.log(`Type: ${msg.type}, Foo: ${msg.foo}`); // Type: MY_MESSAGE, Foo: something
});
```

Sending Messages:

```ts
import { Socket } from '@nano-utils/web-socket';

type IMsgs = {
	MY_MESSAGE: { type: 'MY_MESSAGE'; foo: string };
};

type OMsgs = {
	MY_OUTGOING_MESSAGE: { type: 'MY_OUTGOING_MESSAGE'; foo: string };
};

const socket = new Socket<IMsgs, OMsgs>('wss://example.com');

socket.send({ type: 'MY_OUTGOING_MESSAGE', foo: 'bar' }); // Waiting for the socket to be open is automatically handled
```

Awaiting Messages:

```ts
import { Socket } from '@nano-utils/web-socket';

type IMsgs = {
	MY_MESSAGE: { type: 'MY_MESSAGE'; foo: string };
};

const socket = new Socket<IMsgs, {}>('wss://example.com');

async function myFunc() {
	await socket.await('MY_MESSAGE');
	console.log('Received message');
}

async function myFunc2() {
	const msg = socket.await('MY_MESSAGE');
	console.log('Received message', msg);
}
```

## Usage Notes:

-   Each message (both outgoing and incoming) must have a type property, which is litstened to in the `on` method
-   If using typescript, each message's key in the message type map must match the type property of the message
-   This package is designed to be paired with the [server-sockets](https://npmjs.org/packages/@nano-utils/server-sockets) library on the backend, but any server that sends messages in json format with type properties will work