Skip to content

Instantly share code, notes, and snippets.

@janpauldahlke
Forked from Rush/memoize-decorator.ts
Created January 27, 2022 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janpauldahlke/1e5fd067da790bd39724ea7f572a71a4 to your computer and use it in GitHub Desktop.
Save janpauldahlke/1e5fd067da790bd39724ea7f572a71a4 to your computer and use it in GitHub Desktop.
Using memoizee with observables
import { decorate } from 'core-decorators';
import * as memoize from 'memoizee';
import { duration, unitOfTime } from 'moment';
import { memoizeObservable } from './rxjs';
type HumanDuration = [number, unitOfTime.DurationConstructor];
export interface MemoizeOptions extends memoize.Options {
observable?: boolean;
ttl?: HumanDuration;
}
export function Memoize(options: MemoizeOptions) {
const wrapperFunction = options.observable ?
memoizeObservable : memoize;
if (options.ttl) {
options = {
...options,
maxAge: duration(...options.ttl).asMilliseconds(),
};
}
return decorate.call(this, wrapperFunction, options);
}
import * as memoizee from 'memoizee';
import { pipe, Subject } from 'rxjs';
import { share, takeUntil } from 'rxjs/operators';
type ObservableFunction = <T>(args: any[]) => Observable<T>;
export function memoizeObservable(toWrap: ObservableFunction, options: memoizee.Options) {
const disposeSymbol = Symbol('___dispose');
const newOptions: memoizee.Options = Object.assign({
normalizer: (args: any[]) => {
// not sure why this is needed? without it all arguments yield the same cached value
return Array.from(args);
},
}, options, {
dispose(value: any) {
value[disposeSymbol]();
},
});
return memoizee(function() {
const result$ = toWrap.apply(this, arguments);
const expired$ = new Subject();
const sharedResult$ = result$.pipe(takeUntil(expired$), shareReplay(1));
(sharedResult$ as any)[disposeSymbol] = () => expired$.next();
return sharedResult$;
}, newOptions);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment