I am building an ad-hoc text-editor. I have two functions which use a cache, `provideHover` and `provideCompletionItems`.

```
"use strict";

import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
const $ = require("jquery");
const urlResolve = require("url-resolve");

const AUTOCOMPLETE_ENDPOINT = "http://localhost:7000/";
const LRU = require("lru-cache");

const options = {
	max: 500,
	length: (suggestions, key) => { return suggestions.length }
};

const cache = new LRU(options);
const definition_cache = new LRU(options);

(function () {
	// create div to avoid needing a HtmlWebpackPlugin template
	const div = document.createElement('div');
	div.id = 'root';
	div.style = 'width:800px; height:600px; border:1px solid #ccc;';
	document.body.appendChild(div);
})();




monaco.editor.create(
	document.getElementById('root'),
	{
		value: ``,
		language: 'python',
		theme: 'vs-dark'
	}
);



const getCompletions = (text) => {
	return $.ajax({
		url: urlResolve(AUTOCOMPLETE_ENDPOINT, "suggestion"),
		type: 'GET',
		"data": {
			"text": text
		}
	});
};

const getDocumentation = (cursorInfo) => {
	const line = cursorInfo.line;
	const column = cursorInfo.column;
	const text = cursorInfo.text;
	return $.ajax({
		url: urlResolve(AUTOCOMPLETE_ENDPOINT, "documentation"),
		type: 'GET',
		"data": {
			"line": line,
			"column": column,
			"text": text,
			"highlighted": cursorInfo.highlighted
		}
	});

}



monaco.languages.registerHoverProvider("python", {
	provideHover: async (model, position) => {
		const lineNumber = position.lineNumber;
		const snippet = model.getWordAtPosition(position);
		const text = model.getValueInRange({ startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: snippet.endColumn });
		if (definition_cache.has(text)) {
			console.log("hit");
			return {
				contents: [{ value: definition_cache.get(text) }]

			}
		}

		const response = await getDocumentation({ "line": lineNumber, "column": snippet.endColumn, "text": text, "highlighted": snippet.word });
		definition_cache.set(text, response.documentation);
		return {
			contents: [{ value: response.documentation }]
		}
	}
});


monaco.languages.registerCompletionItemProvider('python', {
	provideCompletionItems: async (model, position) => {
		const text = model.getValueInRange({ startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column });
		if (cache.has(text)) {
			const suggestions = cache.get(text);
			return {
				"suggestions": suggestions
			};

		}

		const completions = await getCompletions(text)
		const suggestions = completions.map(c => ({
			label: c.name,
			insertText: c.name
		}));

		cache.set(text, suggestions)

		return {
			"suggestions": suggestions
		};

	}
});



```

As it stands, the introduction of the cache makes the code quite ugly (in my opinion). I'd like to refactor it so that I have only one cache usage that applies in both situations -- something like a Python decorator.

How do I make the code cleaner?