usda-food-data-api-builder
Version:
USDA Food Data API database builder for self-hosted API access to the USDA Food Data database
75 lines (68 loc) • 2.33 kB
text/typescript
import adler from "adler-32";
import stringify from "json-stable-stringify";
import mongoose from "mongoose";
/**
* Defines the cache structure used internally
*/
interface Cache {
[key: string]: Map<number, mongoose.Types.ObjectId>;
}
/**
* Finds and links identical json objects based on collections and document
* hashes.
*/
export class DocumentLinker {
private cache: Cache = {};
private enabled: boolean;
/**
* Initializes the cache with the given array of collection names
*
* @param names An array of collection names
* @param enabled Enable the document linker, this will create lar
*/
constructor(names: string[], enabled: boolean = true) {
this.enabled = enabled;
if (this.enabled) {
names.forEach((name) => {
this.cache[name] = new Map();
});
}
}
/**
* Sorts a JSON Document by index name and hashes the document, giving a
* normalized hash for the document. Not this may or may not work with
* nested documents, but it is assumed documents with nested sub-documents
* tend to be unique.
*
* @param data The data to get a hash of
* @returns A base64 hash of the sorted data
*/
hash(data: any) {
if (this.enabled) {
return adler.str(stringify(data));
}
return 0;
}
/**
* Gives the ObjectId for the requested document, or `undefined`.
*
* @param collection The collection this document belongs to
* @param hash A base64 hash for the given document
* @returns ObjectId of the identical document, or `undefined`
*/
get(collection: string, hash: number) {
return hash && this.enabled ? this.cache[collection].get(hash) : false;
}
/**
* Puts a given ObjectId for a document into the cache for future reference.
*
* @param collection The collection this document belongs to
* @param hash A base64 hash for the given document
* @param _id The ObjectId to cache for this document
*/
put(collection: string, hash: number, _id: mongoose.Types.ObjectId) {
if (hash && this.enabled) {
this.cache[collection].set(hash, _id);
}
}
}