UNPKG

@push.rocks/lik

Version:

Provides a collection of lightweight helpers and utilities for Node.js projects.

124 lines (104 loc) 3.57 kB
import * as plugins from './classes.plugins.js'; import { InterestMap, type IInterestComparisonFunc } from './classes.interestmap.js'; export interface IInterestOptions<DTInterestFullfillment> { markLostAfterDefault: number; defaultFullfillment?: DTInterestFullfillment; } export class Interest<DTInterestId, DTInterestFullfillment> { public options: IInterestOptions<DTInterestFullfillment>; private interestMapRef: InterestMap<DTInterestId, DTInterestFullfillment>; public originalInterest: DTInterestId; public comparisonFunc: IInterestComparisonFunc<DTInterestId>; public destructionTimer = new plugins.smarttime.Timer(10000); public isFullfilled = false; private isDestroyed = false; /** * a generic store to store objects in that are needed for fullfillment; */ public fullfillmentStore: any[] = []; /** * a cancellable timeout for the markLostAfterDefault feature */ private markLostTimeout: InstanceType<typeof plugins.smartdelay.Timeout> | null = null; /** * quick access to a string that makes the interest comparable for checking for similar interests */ public get comparisonString() { return this.comparisonFunc(this.originalInterest); } private interestDeferred: plugins.smartpromise.Deferred<DTInterestFullfillment> = new plugins.smartpromise.Deferred(); public interestFullfilled = this.interestDeferred.promise; /** * fullfill the interest */ public fullfillInterest(objectArg: DTInterestFullfillment) { this.isFullfilled = true; this.fullfillmentStore = []; this.interestDeferred.resolve(objectArg); this.destroy(); } constructor( interestMapArg: InterestMap<DTInterestId, DTInterestFullfillment>, interestArg: DTInterestId, comparisonFuncArg: IInterestComparisonFunc<DTInterestId>, optionsArg?: IInterestOptions<DTInterestFullfillment> ) { this.interestMapRef = interestMapArg; this.originalInterest = interestArg; this.comparisonFunc = comparisonFuncArg; this.options = optionsArg; this.destructionTimer.completed.then(() => { if (!this.isDestroyed) { this.destroy(); } }); if (this.options?.markLostAfterDefault) { this.markLostTimeout = new plugins.smartdelay.Timeout(this.options.markLostAfterDefault); this.markLostTimeout.promise.then(() => { if (!this.isDestroyed) { this.markLost(); } }); } } // =============================== // LIFECYCLE MANAGEMENT // =============================== /** * self destructs the interest */ public destroy() { if (this.isDestroyed) { return; } this.isDestroyed = true; // Cancel timers to release references this.destructionTimer.reset(); if (this.markLostTimeout) { this.markLostTimeout.cancel(); this.markLostTimeout = null; } // Clear the fulfillment store this.fullfillmentStore = []; // Remove from the InterestMap this.interestMapRef.removeInterest(this); // Fulfill with default if not yet fulfilled (inlined to avoid mutual recursion) if (!this.isFullfilled && this.options?.defaultFullfillment) { this.isFullfilled = true; this.interestDeferred.resolve(this.options.defaultFullfillment); } } /** * notifies the interest that the interest in it has been lost */ public markLost() { this.destructionTimer.start(); } /** * notifies the interest that the interest in it has been restored */ public renew() { this.destructionTimer.reset(); } }