135 lines
4.2 KiB
TypeScript
135 lines
4.2 KiB
TypeScript
/* ===========
|
|
The InterestMap is an mechanism that collects interests into something
|
|
An interest is expressed by an object, string or number.
|
|
A comparison func can be specified to make interests comparable
|
|
|
|
For every unique interestId an interest is created.
|
|
Subssequent interests will be mapped to the same interest
|
|
which is then is only fullfilled once.
|
|
=========== */
|
|
|
|
import * as plugins from './lik.plugins.js';
|
|
import { ObjectMap } from './lik.objectmap.js';
|
|
import { Interest } from './lik.interestmap.interest.js';
|
|
|
|
export type IInterestComparisonFunc<T> = (objectArg: T) => string;
|
|
|
|
export interface IInterestMapOptions {
|
|
markLostAfterDefault?: number;
|
|
}
|
|
|
|
export class InterestMap<DTInterestId, DTInterestFullfillment> {
|
|
public options: IInterestMapOptions;
|
|
|
|
/**
|
|
* stores interests that are currently fullfilled by the cache
|
|
*/
|
|
private interestObjectMap = new ObjectMap<Interest<DTInterestId, DTInterestFullfillment>>();
|
|
|
|
/**
|
|
* a function to compare interests
|
|
*/
|
|
private comparisonFunc: IInterestComparisonFunc<DTInterestId>;
|
|
|
|
constructor(
|
|
comparisonFuncArg: IInterestComparisonFunc<DTInterestId>,
|
|
optionsArg: IInterestMapOptions = {}
|
|
) {
|
|
this.comparisonFunc = comparisonFuncArg;
|
|
this.options = optionsArg;
|
|
}
|
|
|
|
/**
|
|
* adds an interest to the InterestMap
|
|
* @param interestId
|
|
*/
|
|
public async addInterest(
|
|
interestId: DTInterestId,
|
|
defaultFullfillmentArg?: DTInterestFullfillment
|
|
): Promise<Interest<DTInterestId, DTInterestFullfillment>> {
|
|
const comparisonString = this.comparisonFunc(interestId);
|
|
let returnInterest: Interest<DTInterestId, DTInterestFullfillment>;
|
|
const newInterest = new Interest<DTInterestId, DTInterestFullfillment>(
|
|
this,
|
|
interestId,
|
|
this.comparisonFunc,
|
|
{
|
|
markLostAfterDefault: this.options.markLostAfterDefault,
|
|
defaultFullfillment: defaultFullfillmentArg,
|
|
}
|
|
);
|
|
let interestExists = false;
|
|
await this.interestObjectMap.forEach((interestArg) => {
|
|
if (!interestExists && interestArg.comparisonString === newInterest.comparisonString) {
|
|
console.log('info', `interest already exists for ${newInterest.comparisonString}`);
|
|
interestExists = true;
|
|
returnInterest = interestArg;
|
|
returnInterest.renew();
|
|
}
|
|
});
|
|
if (!returnInterest) {
|
|
returnInterest = newInterest;
|
|
this.interestObjectMap.add(returnInterest);
|
|
}
|
|
this.interestObservable.push(returnInterest);
|
|
return returnInterest;
|
|
}
|
|
|
|
public interestObservable = new plugins.smartrx.ObservableIntake<Interest<DTInterestId, any>>();
|
|
|
|
/**
|
|
* removes an interest from the interest map
|
|
*/
|
|
public removeInterest(interestArg: Interest<DTInterestId, DTInterestFullfillment>) {
|
|
const interestToRemove = this.interestObjectMap.findOneAndRemoveSync((interestArg2) => {
|
|
return interestArg.comparisonString === interestArg2.comparisonString;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* check interest
|
|
*/
|
|
public checkInterest(objectArg: DTInterestId): boolean {
|
|
const comparisonString = this.comparisonFunc(objectArg);
|
|
return this.checkInterestByString(comparisonString);
|
|
}
|
|
|
|
/**
|
|
* checks an interest
|
|
* @param comparisonStringArg
|
|
*/
|
|
public checkInterestByString(comparisonStringArg: string): boolean {
|
|
const foundInterest = this.interestObjectMap.findSync((interest) => {
|
|
return interest.comparisonString === comparisonStringArg;
|
|
});
|
|
if (foundInterest) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* inform lost interest
|
|
* @param interestId
|
|
*/
|
|
public informLostInterest(interestId: DTInterestId) {
|
|
const wantedInterest = this.findInterest(interestId);
|
|
if (wantedInterest) {
|
|
wantedInterest.markLost();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* finds an interest
|
|
* @param interestId
|
|
*/
|
|
public findInterest(interestId: DTInterestId): Interest<DTInterestId, DTInterestFullfillment> {
|
|
const comparableString = this.comparisonFunc(interestId);
|
|
const interest = this.interestObjectMap.findSync((interestArg) => {
|
|
return interestArg.comparisonString === comparableString;
|
|
});
|
|
return interest; // if an interest is found, the interest is returned, otherwise interest is null
|
|
}
|
|
}
|