Skip to content

Commit

Permalink
Merge pull request #10 from sp3c1/featute/ts-types
Browse files Browse the repository at this point in the history
Featute/ts types
  • Loading branch information
sp3c1 authored Nov 22, 2021
2 parents 7a84a3a + 25400d8 commit ac6fe6b
Show file tree
Hide file tree
Showing 21 changed files with 9,185 additions and 769 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.idea
node_modules
node_modules
.vscode
212 changes: 159 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,172 @@
# Ordered Fast Lookup Map
Map with order functionality, providing fast look ups and ordering in the same time wiht ```O(n)``` complexity.

## Requirements
Was written on ```4.4.0``` and is using some of the es6 features:
* ```Class```
* ```let```
Map with order functionality, providing fast look ups and ordering in the same time with `O(n)` complexity. Newer TS implementation. DeepClones with typesafety. Customizable validator/marshaller and deepClone available.

## Installation
```npm install ordered-fast-lookup-map```

## Testing
`npm install ordered-fast-lookup-map`

### Dev Dependecies
* ```mocha```
* ```expect```
## Usage

### Test
Run ```mocha``` or ```npm run test```.
### Compatibility mode

Runs with default `validator` and `deepClone` set to `false`;

## Usage
```
var orderedMap = require("ordered-fast-lookup-map")
var userMap = new orderedMap();
```

## Available methods

### Constructor
* ```constructor([keysArray,valuesArrays])``` - when supplied with ```keysArray``` and ```valuesArrays``` initiates
structure and perform ```push``` on pair of keys. Exampple:``` var hashMap = orderedMap([1,2,3],["a","b","c"]);```

### Add methods
* ```set(key,value)``` sets the value on the end of structure
* ```push(key,value)``` alias for set
* ```unshift(key, value)``` sets the value on the beginning of structure
* ```arbitrarySetAfter(afterKey, key, value)```sets the value after arbitrary supplied keys. If the arbitrary key is
not found it throws ```Error```.
* ```arbitrarySetBefore(beforeKey, key, value)```sets the value before arbitrary supplied keys. If the arbitrary key is
not found it throws ```Error```.

Note if inserting ```undefined``` any method will throw exception. Please use null instead.

### Remove & Retrieve methods
* ```remove(key)``` remove arbitrary value on the key. If the arbitrary key is not found it throws```Error```.
* ```pop()``` returns last element of structure and removes it. If list is empty returns ```undefined```
* ```shift()``` returns first element of structure and removes it. If list is empty returns ```undefined```
* ```get(key)``` returns value on the key without deleting it (return reference). If the arbitrary key is not
found it throws ```Error```.
* ```has(key)``` checks if key exists (```true/false```)

### Iteration Methods
* ```forEach(callback)``` for each element in ```asc``` order executes user supplied ```function(index,value)```.
To break in user function return ```true```.
* ```forEachReverse(callback)```for each element in ```desc``` order executes user supplied ```function(index,value)```.
To break in user function return ```true```.


## Future Work
* Async callback iterations
* Promise iterations
* weakGet
* first
* last
* length
* merge
### TS / Types

We are now providing the types in the lib.

# Available methods

## Constructor

- `constructor(keys?: NumberOrString[] | number[], values?: T[], options: IOFMLoptions<T> = { deepClone: false })` - when supplied with `keys` and `values` initiates
structure and perform `push` on pair of keys. Exampple:` var hashMap = OrderedTyoedFastLookupMap<string>([1,2,3],["a","b","c"]);`. Additionally `options:IOFMLoptions` object can be passed, to set custom validator, to set deep clone and provide custom deep link handler.

## Add methods

- `set(key: NumberOrString, value: T)` sets the value on the end of structure
- `push(key: NumberOrString, value: T)` alias for set
- `unshift(key: NumberOrString, value: T)` sets the value on the beginning of structure
- `arbitrarySetAfter(afterKey: NumberOrString, key: NumberOrString, value: T)`sets the value after arbitrary supplied keys. If the arbitrary key is
not found it throws `Error`.
- `arbitrarySetBefore(beforeKey: NumberOrString, key: NumberOrString, value: T)`sets the value before arbitrary supplied keys. If the arbitrary key is
not found it throws `Error`.

Note if inserting `undefined` any method will throw exception. Please use null instead. Or change the `validator` methods. Validator now can either `throw` or return `true/false`. This applies to all places where method is marked as throwable

## Remove & Retrieve methods

- `remove(key: NumberOrString)` remove arbitrary value on the key. If the arbitrary key is not found it throws`Error`.
- `pop(): T` returns last element of structure and removes it. If list is empty returns `undefined`
- `shift(): T` returns first element of structure and removes it. If list is empty returns `undefined`
- `get(key: NumberOrString): T` returns value on the key without deleting it (return reference). If element is not found returns `undefined`
- `has(key: NumberOrString): boolean` checks if key exists (`true/false`)

## Iteration Methods

- `forEach(callback: IteratorCallback<T>): void` for each element in `asc` order executes user supplied `function(index,value,validatorFunction)`.
To break in user function return `true`. We are now exposing the validator method out.
- `forEachReverse(callback: IteratorCallback<T>): void`for each element in `desc` order executes user supplied `function(index,value,validatorFunction)`.
To break in user function return `true`. We are now exposing the validator method out.

## Validator and deepClone

- `private validator(value: T): void | boolean` by default, throws error is value is `undefined`. Can be replaced with `IOFMLoptions`

- `private deepCloneMethod(val: T): T` when deepClone is set to `true` (by default is `false`) this gets executed to clone object with keeping the `constructor.name` to preserve es6 object type/instance type. Can be replaced with `IOFMLoptions`

<br><hr/><br>

## Inhouse types

```
type IteratorCallback<T> = (key: string, value: T, validator: IValidatorFunction<T>) => boolean;
type IValidatorFunction<T> = (value: T) => void | boolean;
type IDeepCloneFunction<T> = (value: T) => T;
type NumberOrString = string | number;
type IOFMLoptions<T> = {
validator?: IValidatorFunction<T>
deepClone?: boolean // default to false
deepCloneMethod?: IDeepCloneFunction<T>
}
```

<br><hr/><br>

## Migration / Example use

New TS implementation should work as previous v1.1.2 when accessed through `require`. It assumes `OrderedTyoedFastLookupMap<any>` with default validator that throws error only when you try to set `undefined`. Also the `key` is always forced to be a string in the map (this might be breaking for some).

```
import { OrderedTypedFastLookupMap, OrderedFastLookupMap } from "ordered-fast-lookup-map/lib";
// this is equivalent to const oflm = new OrderedFastLookupMap([`key`], [[{ "foo": "bar" }]]);
const oflm = new OrderedTypedFastLookupMap<any[]>([`key`], [[{ "foo": "bar" }]]);
console.log(oflm._array) // ["key"];
console.log(oflm.map); // { "key": [{ "foo": "bar" }] }
```

when imported in TS should allow for strict control of stored types, and the `validator` method. validator now can `throw(default)` or return `true/false`.
<br><br>

```
import { OrderedTyoedFastLookupMap, IOFMLoptions } from "../lib";
class testClass {
constructor(public x: string) { }
}
class testClassWrong {
constructor(public x: string) { }
}
const foo = new testClass('bar');
const noo = new testClassWrong('bar');
// adds foo t map
const oflm = new OrderedTyoedFastLookupMap<testClass>([1], foo);
...
// ts error
const fail = new OrderedTyoedFastLookupMap<testClass>([1], noo);
...
// silently fails to add and just intiates the map
const fail = new OrderedTyoedFastLookupMap<testClass>([1], <any>noo);
...
// changes default validator
const opts: IOFMLoptions<testClass> = {
validator: (val) => {
if (!(<any>val instanceof testClass)) {
return false;
}
return true;
}
};
// silently fails to add and just intiates the map
const oflmValidatr = new OrderedTyoedFastLookupMap<testClass>([1], <testClass>noo, opts);
...
// changes default validator
const opts: IOFMLoptions<testClass> = {
validator: (val) => {
return true;
}
};
// This will allow to create testClassWrong in the map and ignore marshalling
// checks, ts still will assumed the templated type
const oflmValidatr = new OrderedTyoedFastLookupMap<testClass>([1], <testClass>noo, opts);
...
const opts: IOFMLoptions<testClass> = {
// deepCloneMethod <====== hookup custom method
deepClone: true,
validator: (val) => {
if (!(<any>val instanceof testClass)) {
return false;
}
return true;
}
};
```
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=index.d.ts.map
1 change: 1 addition & 0 deletions index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ac6fe6b

Please sign in to comment.