diff --git a/package.json b/package.json index 4737674..2266cfd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "astring": "^1.8.6", "autoprefixer": "^10.4.14", "codemirror": "^6.0.1", + "lru-cache": "^10.0.1", "postcss": "^8.4.27", "superdough": "^0.9.3", "tailwindcss": "^3.3.3", diff --git a/src/API.ts b/src/API.ts index 64b79cc..3c29adc 100644 --- a/src/API.ts +++ b/src/API.ts @@ -11,6 +11,9 @@ import { registerSynthSounds, // @ts-ignore } from "superdough"; +import { LRUCache } from 'lru-cache'; + +const cache = new LRUCache({max: 1000, ttl: 1000 * 60 * 5}); /** * We are overriding the includes method which is rather @@ -412,6 +415,52 @@ export class UserAPI { // Small algorithmic functions // ============================================================= + _sequence_key_generator(pattern: any[]) { + /** + * Generates a key for the sequence function. + * + * @param input - The input to generate a key for + * @returns A key for the sequence function + */ + // Make the pattern base64 + return btoa(JSON.stringify(pattern)); + } + + sequence(input: any[]) { + /** + * Returns a value in a sequence stored using an LRU Cache. + * The sequence is stored in the cache with an hash identifier + * made from a base64 encoding of the pattern. The pattern itself + * is composed of the pattern itself (a list of arbitrary typed + * values) and a set of options (an object) detailing how the pattern + * should be iterated on. + * + * @param input - The input to generate a key for + * Note that the last element of the input can be an object + * containing options for the sequence function. + * @returns A value in a sequence stored using an LRU Cache + */ + const default_options: object = { index: 0 } + if (typeof input[input.length - 1] === "object") { + const pattern_options: object = { + ...input.pop(), + ...default_options as object + }; + } else { + const pattern_options = default_options; + } + const sequence_key = this._sequence_key_generator(input); + if (cache.has(sequence_key)) { + return cache.get(sequence_key); + } else { + cache.set(sequence_key, { + pattern: input, + options: pattern_options + }); + } + return cache.get(sequence_key); + } + pick(...array: T[]): T { /** * Returns a random element from an array. diff --git a/yarn.lock b/yarn.lock index 380174b..d966794 100644 --- a/yarn.lock +++ b/yarn.lock @@ -782,7 +782,7 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -lru-cache@^10.0.0: +lru-cache@^10.0.0, lru-cache@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==