1
0
forked from sent/waves
waves-fork/public/assets/g/mario/References/ChangeLinr-0.2.0.ts
2025-04-09 17:11:14 -05:00

246 lines
7.9 KiB
TypeScript

declare module ChangeLinr {
export interface IChangeLinrTransform {
(data: any, key: string, attributes: any, scope: IChangeLinr): any;
}
export interface IChangeLinrCache {
[i: string]: any;
}
export interface IChangeLinrCacheFull {
[i: string]: {
[i: string]: any;
}
}
export interface IChangeLinrSettings {
pipeline: string[];
transforms: {
[i: string]: IChangeLinrTransform
};
doMakeCache?: boolean;
doUseCache?: boolean;
}
export interface IChangeLinr {
getCache(): IChangeLinrCache;
getCached(key: string): any;
getCacheFull(): IChangeLinrCacheFull;
getDoMakeCache(): boolean;
getDoUseCache(): boolean;
process(data: any, key?: string, attributes?: any): any;
processFull(data: any, key?: string, attributes?: any): any;
}
}
module ChangeLinr {
"use strict";
/**
* A general utility for transforming raw input to processed output. This is
* done by keeping an Array of transform Functions to process input on.
* Outcomes for inputs are cached so repeat runs are O(1).
*/
export class ChangeLinr implements IChangeLinr {
/**
* Functions that may be used to transform data, keyed by name.
*/
private transforms: {
[i: string]: IChangeLinrTransform;
};
/**
* Ordered listing of Function names to be applied to raw input.
*/
private pipeline: string[];
/**
* Cached output of previous results of the the pipeline.
*/
private cache: IChangeLinrCache;
/**
* Cached output of each step of the pipeline.
*/
private cacheFull: IChangeLinrCacheFull;
/**
* Whether this should be caching responses.
*/
private doMakeCache: boolean;
/**
* Whether this should be retrieving and using cached results.
*/
private doUseCache: boolean;
/**
* @param {IChangeLinrSettings} settings
*/
constructor(settings: IChangeLinrSettings) {
if (typeof settings === "undefined") {
throw new Error("No settings object given to ChangeLinr.");
}
if (typeof settings.pipeline === "undefined") {
throw new Error("No pipeline given to ChangeLinr.");
}
if (typeof settings.transforms === "undefined") {
throw new Error("No transforms given to ChangeLinr.");
}
var i: number;
this.pipeline = settings.pipeline || [];
this.transforms = settings.transforms || {};
this.doMakeCache = typeof settings.doMakeCache === "undefined"
? true : settings.doMakeCache;
this.doUseCache = typeof settings.doUseCache === "undefined"
? true : settings.doUseCache;
this.cache = {};
this.cacheFull = {};
// Ensure the pipeline is formatted correctly
for (i = 0; i < this.pipeline.length; ++i) {
// Don't allow null/false transforms
if (!this.pipeline[i]) {
throw new Error("Pipe[" + i + "] is invalid.");
}
// Make sure each part of the pipeline exists
if (!this.transforms.hasOwnProperty(this.pipeline[i])) {
if (!this.transforms.hasOwnProperty(this.pipeline[i])) {
throw new Error(
"Pipe[" + i + "] (\"" + this.pipeline[i] + "\") "
+ "not found in transforms."
);
}
}
// Also make sure each part of the pipeline is a Function
if (!(this.transforms[this.pipeline[i]] instanceof Function)) {
throw new Error(
"Pipe[" + i + "] (\"" + this.pipeline[i] + "\") "
+ "is not a valid Function from transforms."
);
}
this.cacheFull[i] = this.cacheFull[this.pipeline[i]] = {};
}
}
/* Simple gets
*/
/**
* @return {Mixed} The cached output of this.process and this.processFull.
*/
getCache(): IChangeLinrCache {
return this.cache;
}
/**
* @param {String} key The key under which the output was processed
* @return {Mixed} The cached output filed under the given key.
*/
getCached(key: string): any {
return this.cache[key];
}
/**
* @return {Object} A complete listing of the cached outputs from all
* processed information, from each pipeline transform.
*/
getCacheFull(): IChangeLinrCacheFull {
return this.cacheFull;
}
/**
* @return {Boolean} Whether the cache object is being kept.
*/
getDoMakeCache(): boolean {
return this.doMakeCache;
}
/**
* @return {Boolean} Whether previously cached output is being used in new
* process requests.
*/
getDoUseCache(): boolean {
return this.doUseCache;
}
/* Core processing
*/
/**
* Applies a series of transforms to input data. If doMakeCache is on, the
* outputs of this are stored in cache and cacheFull.
*
* @param {Mixed} data The data to be transformed.
* @param {String} [key] They key under which the data is to be stored.
* If needed but not provided, defaults to data.
* @param {Object} [attributes] Any extra attributes to be given to the
* transform Functions.
* @return {Mixed} The final output of the pipeline.
*/
process(data: any, key: string = undefined, attributes: any = undefined): any {
var i: number;
if (typeof key === "undefined" && (this.doMakeCache || this.doUseCache)) {
key = data;
}
// If this keyed input was already processed, get that
if (this.doUseCache && this.cache.hasOwnProperty(key)) {
return this.cache[key];
}
// Apply (and optionally cache) each transform in order
for (i = 0; i < this.pipeline.length; ++i) {
data = this.transforms[this.pipeline[i]](data, key, attributes, this);
if (this.doMakeCache) {
this.cacheFull[this.pipeline[i]][key] = data;
}
}
if (this.doMakeCache) {
this.cache[key] = data;
}
return data;
}
/**
* A version of this.process that returns the complete output from each
* pipelined transform Function in an Object.
*
* @param {Mixed} data The data to be transformed.
* @param {String} [key] They key under which the data is to be stored.
* If needed but not provided, defaults to data.
* @param {Object} [attributes] Any extra attributes to be given to the
* transform Functions.
* @return {Object} The complete output of the transforms.
*/
processFull(raw: any, key: string, attributes: any = undefined): any {
var output: any = {},
i: number;
this.process(raw, key, attributes);
for (i = 0; i < this.pipeline.length; ++i) {
output[i] = output[this.pipeline[i]] = this.cacheFull[this.pipeline[i]][key];
}
return output;
}
}
}