Skip to content

Commit 6fb7346

Browse files
authored
Initial push (#1)
1 parent 61d038d commit 6fb7346

File tree

19 files changed

+12583
-96
lines changed

19 files changed

+12583
-96
lines changed

.eslintrc.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
extends: ['@adamhamlin/eslint-config'],
3+
overrides: [
4+
{
5+
files: ['**/__tests__/**'],
6+
plugins: ['jest'],
7+
extends: ['plugin:jest/all'],
8+
rules: {
9+
'jest/prefer-expect-assertions': 'off',
10+
'jest/prefer-lowercase-title': 'off',
11+
'jest/max-expects': ['error', { max: 8 }],
12+
},
13+
},
14+
],
15+
};

.gitignore

Lines changed: 4 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,14 @@
1-
# Logs
2-
logs
3-
*.log
4-
npm-debug.log*
5-
yarn-debug.log*
6-
yarn-error.log*
7-
lerna-debug.log*
1+
# TS build dir
2+
out/
83

9-
# Diagnostic reports (https://nodejs.org/api/report.html)
10-
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11-
12-
# Runtime data
13-
pids
14-
*.pid
15-
*.seed
16-
*.pid.lock
17-
18-
# Directory for instrumented libs generated by jscoverage/JSCover
19-
lib-cov
20-
21-
# Coverage directory used by tools like istanbul
22-
coverage
23-
*.lcov
24-
25-
# nyc test coverage
26-
.nyc_output
27-
28-
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29-
.grunt
30-
31-
# Bower dependency directory (https://bower.io/)
32-
bower_components
33-
34-
# node-waf configuration
35-
.lock-wscript
36-
37-
# Compiled binary addons (https://nodejs.org/api/addons.html)
38-
build/Release
4+
# Coverage
5+
coverage/
396

407
# Dependency directories
418
node_modules/
42-
jspm_packages/
43-
44-
# TypeScript v1 declaration files
45-
typings/
46-
47-
# TypeScript cache
48-
*.tsbuildinfo
499

5010
# Optional npm cache directory
5111
.npm
5212

5313
# Optional eslint cache
5414
.eslintcache
55-
56-
# Microbundle cache
57-
.rpt2_cache/
58-
.rts2_cache_cjs/
59-
.rts2_cache_es/
60-
.rts2_cache_umd/
61-
62-
# Optional REPL history
63-
.node_repl_history
64-
65-
# Output of 'npm pack'
66-
*.tgz
67-
68-
# Yarn Integrity file
69-
.yarn-integrity
70-
71-
# dotenv environment variables file
72-
.env
73-
.env.test
74-
75-
# parcel-bundler cache (https://parceljs.org/)
76-
.cache
77-
78-
# Next.js build output
79-
.next
80-
81-
# Nuxt.js build / generate output
82-
.nuxt
83-
dist
84-
85-
# Gatsby files
86-
.cache/
87-
# Comment in the public line in if your project uses Gatsby and *not* Next.js
88-
# https://nextjs.org/blog/next-9-1#public-directory-support
89-
# public
90-
91-
# vuepress build output
92-
.vuepress/dist
93-
94-
# Serverless directories
95-
.serverless/
96-
97-
# FuseBox cache
98-
.fusebox/
99-
100-
# DynamoDB Local files
101-
.dynamodb/
102-
103-
# TernJS port file
104-
.tern-port

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npx lint-staged

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Ignore artifacts:
2+
out
3+
coverage

.prettierrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
...require('@adamhamlin/eslint-config/prettier'),
3+
};

README.md

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,83 @@
1-
# deep-equality-data-structures
2-
Javascript data structures (e.g., Map, Set) that support deep object equality
1+
# Deep Equality Javascript Data Structures
2+
3+
A drop-in replacement for ES native `Map` and `Set` with deep equality support for objects.
4+
5+
## Why?
6+
7+
ES `Map` and `Set` only support referential equality:
8+
9+
```typescript
10+
interface MyObject {
11+
a: number;
12+
}
13+
const set = new Set<MyObject>();
14+
set.add({ a: 1 });
15+
set.add({ a: 1 });
16+
set.size; // 2
17+
```
18+
19+
Now, using deep equality:
20+
21+
```typescript
22+
import { DeepSet } from '@adamhamlin/deep-equality-data-strucures';
23+
24+
interface MyObject {
25+
a: number;
26+
}
27+
const set = new DeepSet<MyObject>();
28+
set.add({ a: 1 });
29+
set.add({ a: 1 });
30+
set.size; // 1
31+
```
32+
33+
## How?
34+
35+
This project relies on the [object-hash](https://github.com/puleos/object-hash) library to map object types to strings.
36+
37+
## Comparable Interface
38+
39+
Equality and subset comparisons are supported:
40+
41+
```typescript
42+
const set1 = new DeepSet([{ a: 1 }, { b: 2 }]);
43+
const set2 = new DeepSet([{ a: 1 }, { b: 2 }]);
44+
set1.equals(set2); // true
45+
46+
const set3 = new DeepSet([{ a: 1 }]);
47+
set1.equals(set3); // false
48+
set1.contains(set3); // true
49+
```
50+
51+
## Configuration Options
52+
53+
```typescript
54+
new DeepSet(values?, options?)
55+
new DeepMap(entries?, options?)
56+
```
57+
58+
The `options` argument is a superset of the options defined for [object-hash](https://github.com/puleos/object-hash#hashvalue-options), with the same defaults (exception: the default algoritm is `md5`).
59+
60+
Additional project-specific options:
61+
62+
- `jsonSerializableOnly` - if true, only use JSON-serializable properties when computing hashes, equality, etc. (default: false)
63+
64+
```typescript
65+
class A {
66+
constructor(public x: number) {}
67+
}
68+
class B {
69+
constructor(public x: number) {}
70+
}
71+
const b = new B(45);
72+
const c = new C(45);
73+
74+
const set = new DeepSet([b, c]);
75+
set.size; // 2
76+
const set = new DeepSet([b, c], { jsonSerializableOnly: true });
77+
set.size; // 1
78+
```
79+
80+
## Notes/Caveats
81+
82+
- Don't mutate a map key (or set value) while still using the data structure. The internal representation is not affected by this mutation, so behavior may be unexpected.
83+
- This implementation does not explicitly "handle" key collisions. However, with the default algorithm (MD5), even if a map contained one TRILLION entries, the probability of a collision on the next insert is only 0.000000000000001. If you need better odds, use SHA1, SHA256, etc.

index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { DeepMap } from './src/map';
2+
import { DeepSet } from './src/set';
3+
4+
export { DeepMap };
5+
export { DeepSet };

0 commit comments

Comments
 (0)