Skip to content

Commit

Permalink
Merge pull request #12 from BrianMitchL/v3
Browse files Browse the repository at this point in the history
v3
  • Loading branch information
BrianMitchL authored Mar 21, 2021
2 parents 7481e96 + b1d5045 commit c1f0fdb
Show file tree
Hide file tree
Showing 12 changed files with 903 additions and 1,045 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ node_modules
.rts2*
dist
coverage
umd-dist
94 changes: 28 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,53 +17,35 @@ npm i gift-exchange
The library ships CommonJS, ES module, and UMD builds. The UMD build makes the
library available with the `GiftExchange` name.

`gift-exchange` exports two functions (`calculateSync` and `calculate`
(deprecated)) and an Error, `DerangementError`.

A `Person` array is always required. A `Person` must have a unique `name` and
optionally a `group`. A `Person` cannot be matched with another person in the
same `group` nor with themselves. A mix of people that both have and do not
have a `group` is supported. Additional exclusion logic can be configured with
[Exclusions](#exclusions).
### `calculate`

```typescript
import { Person } from 'gift-exchange';

const people: Person[] = [
{
name: 'Brian',
group: 'Mitchell'
},
{
name: 'Freja'
}
];
```

### `calculateSync`

```typescript
function calculateSync(
people: Person[],
exclusions?: Exclusion[]
): Person[];
function calculate(people: Person[], exclusions?: Exclusion[]): Person[];
// or
function calculateSync(
function calculate(
people: Person[],
// timeout in ms
options?: { exclusions?: Exclusion[], timeout?: number }
options?: {
exclusions?: Exclusion[];
timeout?: number;
}
): Person[];
```

This returns a new `Person` array or throws a `DerangementError` if
A `Person` array is always required. A `Person` must have a unique `name` and
optionally a `group`. A `Person` cannot be matched with another person in the
same `group` nor with themselves. A mix of people that both have and do not
have a `group` is supported. Additional exclusion logic can be configured with
[Exclusions](#exclusions).

`calculate` returns a new `Person` array or throws an Error if
the matching algorithm fails to find a valid match after 1 second (or custom
timeout, if provided), indicating that an impossible combination of people and
exclusions was provided. If given an impossible configuration or one with few
possible matches, and many people, this will block the thread. To avoid this,
it is recommended to run the script in a WebWorker.

```typescript
import { calculateSync, Person } from 'gift-exchange';
import { calculate, Person } from 'gift-exchange';

const people: Person[] = [
{
Expand All @@ -75,7 +57,7 @@ const people: Person[] = [
];

try {
const matches = calculateSync(people);
const matches = calculate(people);
const pairs: { from: string; to: string }[] = people.map((person, i) => ({
from: person.name,
to: matches[i].name
Expand All @@ -86,46 +68,26 @@ try {
}
```

### `calculate` (deprecated)

**Using a `Promise` is straightforward and still thread blocking, so this will
be removed in the next major version.**

This function takes the same arguments as `calculateSync`, but returns a
`Promise` resolved with the `Person` array, or rejected with the
`DerangementError`.
### `validateMatches`

```typescript
import { calculate, Person } from 'gift-exchange';

const people: Person[] = [
{
name: 'Brian'
},
{
name: 'Freja'
}
];

calculate(people).then(matches => {
const pairs: { from: string; to: string }[] = people.map((person, i) => ({
from: person.name,
to: matches[i].name
}));
console.table(pairs);
});
validateMatches(a: Person[], b: Person[], exclusions?: Exclusion[]): boolean;
```

This is an internal helper function that validates that two `Person` arrays
and an optional `Exclusion` array are valid matches where no person is matched
with themselves, in the same group, or violating any exclusions. This could
be helpful if you are creating your own implementation.

### Exclusions

The `calculateSync` and `calculate` functions can also be called with a second
argument `exclusions`. This builds upon the concept that no person can match
another in the same group.
Exclusions build beyond the existing concept that no person can match another
in the same group.

Exclusions are single directional. Use the `type` and `subject` properties to
select a base Person or group of Persons. Then select an `excludedType` and
`excludedSubject` to select the Person or group of Persons that the previously
selected Person/group of Persons cannot be matched with.
select a base Person or group of Persons (base selection). Then select an
`excludedType` and `excludedSubject` to select the Person or group of Persons
that the base selection cannot be matched with.

The There are two exclusion types, one of type `name` and one of type
`group`. The `type` refers to a key on the `Person` interface. The `subject` is
Expand Down
Loading

0 comments on commit c1f0fdb

Please sign in to comment.