{"ast":null,"code":"export class SqlCache {\n #owner;\n #sqls;\n capacity;\n constructor(owner, capacity) {\n this.#owner = owner;\n this.#sqls = new Lru();\n this.capacity = capacity;\n }\n // Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this\n // function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,\n // but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the\n // server).\n //\n // In practice, this means that after calling this function, you can use the statements only up to the\n // first `await`, because concurrent code may also use the cache and invalidate those statements.\n apply(hranaStmts) {\n if (this.capacity <= 0) {\n return;\n }\n const usedSqlObjs = new Set();\n for (const hranaStmt of hranaStmts) {\n if (typeof hranaStmt.sql !== \"string\") {\n continue;\n }\n const sqlText = hranaStmt.sql;\n // Stored SQL cannot exceed 5kb.\n // https://github.com/tursodatabase/libsql/blob/e9d637e051685f92b0da43849507b5ef4232fbeb/libsql-server/src/hrana/http/request.rs#L10\n if (sqlText.length >= 5000) {\n continue;\n }\n let sqlObj = this.#sqls.get(sqlText);\n if (sqlObj === undefined) {\n while (this.#sqls.size + 1 > this.capacity) {\n const [evictSqlText, evictSqlObj] = this.#sqls.peekLru();\n if (usedSqlObjs.has(evictSqlObj)) {\n // The SQL object that we are trying to evict is already in use in this batch, so we\n // must not evict and close it.\n break;\n }\n evictSqlObj.close();\n this.#sqls.delete(evictSqlText);\n }\n if (this.#sqls.size + 1 <= this.capacity) {\n sqlObj = this.#owner.storeSql(sqlText);\n this.#sqls.set(sqlText, sqlObj);\n }\n }\n if (sqlObj !== undefined) {\n hranaStmt.sql = sqlObj;\n usedSqlObjs.add(sqlObj);\n }\n }\n }\n}\nclass Lru {\n // This maps keys to the cache values. The entries are ordered by their last use (entires that were used\n // most recently are at the end).\n #cache;\n constructor() {\n this.#cache = new Map();\n }\n get(key) {\n const value = this.#cache.get(key);\n if (value !== undefined) {\n // move the entry to the back of the Map\n this.#cache.delete(key);\n this.#cache.set(key, value);\n }\n return value;\n }\n set(key, value) {\n this.#cache.set(key, value);\n }\n peekLru() {\n for (const entry of this.#cache.entries()) {\n return entry;\n }\n return undefined;\n }\n delete(key) {\n this.#cache.delete(key);\n }\n get size() {\n return this.#cache.size;\n }\n}","map":{"version":3,"names":["SqlCache","owner","sqls","capacity","constructor","Lru","apply","hranaStmts","usedSqlObjs","Set","hranaStmt","sql","sqlText","length","sqlObj","get","undefined","size","evictSqlText","evictSqlObj","peekLru","has","close","delete","storeSql","set","add","cache","Map","key","value","entry","entries"],"sources":["/Users/shoofle/Projects/the-forest/node_modules/@libsql/client/lib-esm/sql_cache.js"],"sourcesContent":["export class SqlCache {\n #owner;\n #sqls;\n capacity;\n constructor(owner, capacity) {\n this.#owner = owner;\n this.#sqls = new Lru();\n this.capacity = capacity;\n }\n // Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this\n // function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,\n // but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the\n // server).\n //\n // In practice, this means that after calling this function, you can use the statements only up to the\n // first `await`, because concurrent code may also use the cache and invalidate those statements.\n apply(hranaStmts) {\n if (this.capacity <= 0) {\n return;\n }\n const usedSqlObjs = new Set();\n for (const hranaStmt of hranaStmts) {\n if (typeof hranaStmt.sql !== \"string\") {\n continue;\n }\n const sqlText = hranaStmt.sql;\n // Stored SQL cannot exceed 5kb.\n // https://github.com/tursodatabase/libsql/blob/e9d637e051685f92b0da43849507b5ef4232fbeb/libsql-server/src/hrana/http/request.rs#L10\n if (sqlText.length >= 5000) {\n continue;\n }\n let sqlObj = this.#sqls.get(sqlText);\n if (sqlObj === undefined) {\n while (this.#sqls.size + 1 > this.capacity) {\n const [evictSqlText, evictSqlObj] = this.#sqls.peekLru();\n if (usedSqlObjs.has(evictSqlObj)) {\n // The SQL object that we are trying to evict is already in use in this batch, so we\n // must not evict and close it.\n break;\n }\n evictSqlObj.close();\n this.#sqls.delete(evictSqlText);\n }\n if (this.#sqls.size + 1 <= this.capacity) {\n sqlObj = this.#owner.storeSql(sqlText);\n this.#sqls.set(sqlText, sqlObj);\n }\n }\n if (sqlObj !== undefined) {\n hranaStmt.sql = sqlObj;\n usedSqlObjs.add(sqlObj);\n }\n }\n }\n}\nclass Lru {\n // This maps keys to the cache values. The entries are ordered by their last use (entires that were used\n // most recently are at the end).\n #cache;\n constructor() {\n this.#cache = new Map();\n }\n get(key) {\n const value = this.#cache.get(key);\n if (value !== undefined) {\n // move the entry to the back of the Map\n this.#cache.delete(key);\n this.#cache.set(key, value);\n }\n return value;\n }\n set(key, value) {\n this.#cache.set(key, value);\n }\n peekLru() {\n for (const entry of this.#cache.entries()) {\n return entry;\n }\n return undefined;\n }\n delete(key) {\n this.#cache.delete(key);\n }\n get size() {\n return this.#cache.size;\n }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}