UNPKG

@graphistry/falcor-react-schema

Version:

67 lines (63 loc) 2.1 kB
import { parse as pegJSParseUtil } from 'pegjs-util'; import toPaths from '@graphistry/falcor-query-syntax/lib/toPaths'; import toFlatBuffer from '@graphistry/falcor-path-utils/lib/toFlatBuffer'; import flatBufferToPaths from '@graphistry/falcor-path-utils/lib/flatBufferToPaths'; import computeFlatBufferHash from '@graphistry/falcor-path-utils/lib/computeFlatBufferHash'; export default function memoizeQueryies(limit = 100) { let count = 0, map = {}, lru = {}; return function memoizedQuerySyntax(query) { let entry = map[query]; if (entry === undefined && ++count > limit) { delete map[lru.tail.query]; splice(lru, lru.tail); } if (!entry || !entry.error) { const result = pegJSParseUtil(toPaths.Parser, query); if (!result.error) { // Turn the computed AST into paths, then turn it back into an // AST so we collapse adjacent nodes. result.ast = computeFlatBufferHash( toFlatBuffer(flatBufferToPaths(result.ast))); } entry = map[query] = { query, ...result }; promote(lru, entry); } return entry; } } function promote(lru, entry) { let head = lru.head; if (!head) { lru.head = lru.tail = entry; return; } else if (head === entry) { return; } let prev = entry.prev; let next = entry.next; next && (next.prev = prev); prev && (prev.next = next); entry.prev = undefined; // Insert into head position lru.head = entry; entry.next = head; head.prev = entry; // If the item we promoted was the tail, then set prev to tail. if (entry === lru.tail) { lru.tail = prev; } } function splice(lru, entry) { let prev = entry.prev; let next = entry.next; next && (next.prev = prev); prev && (prev.next = next); entry.prev = entry.next = undefined; if (entry === lru.head) { lru.head = next; } if (entry === lru.tail) { lru.tail = prev; } }