@ckb-ccc/core
Version:
Core of CCC - CKBer's Codebase
119 lines (118 loc) • 3.85 kB
JavaScript
import { bytesFrom } from "../../bytes/index.js";
import { Cell, Script } from "../../ckb/index.js";
import { hexFrom } from "../../hex/index.js";
import { numFrom } from "../../num/index.js";
import { clientSearchKeyRangeFrom, } from "../clientTypes.advanced.js";
import { ClientIndexerSearchKey } from "../clientTypes.js";
export function filterData(dataLike, filterLike, filterMode) {
if (!filterLike) {
return true;
}
const data = hexFrom(dataLike);
const filter = hexFrom(filterLike);
if ((filterMode === "exact" && data !== filter) ||
(filterMode === "prefix" && !data.startsWith(filter)) ||
(filterMode === "partial" && data.search(filter) === -1)) {
return false;
}
return true;
}
export function filterScript(valueLike, filterLike, filterMode) {
if (!filterLike) {
return true;
}
if (!valueLike) {
return false;
}
const value = Script.from(valueLike);
const filter = Script.from(filterLike);
if (value.codeHash !== filter.codeHash ||
value.hashType !== filter.hashType) {
return false;
}
return filterData(value.args, filter?.args, filterMode);
}
export function filterNumByRange(lengthLike, range) {
if (!range) {
return true;
}
const length = numFrom(lengthLike);
const [lower, upper] = clientSearchKeyRangeFrom(range);
return lower <= length && length < upper;
}
export function filterScriptByLenRange(valueLike, scriptLenRange) {
if (!scriptLenRange) {
return true;
}
const len = (() => {
if (!valueLike) {
return 0;
}
return bytesFrom(Script.from(valueLike).args).length + 33;
})();
return filterNumByRange(len, scriptLenRange);
}
export function filterCell(searchKeyLike, cellLike) {
const key = ClientIndexerSearchKey.from(searchKeyLike);
const cell = Cell.from(cellLike);
if (key.scriptType === "lock") {
if (!filterScript(cell.cellOutput.lock, key.script, key.scriptSearchMode) ||
!filterScript(cell.cellOutput.type, key.filter?.script, "prefix") ||
!filterScriptByLenRange(cell.cellOutput.type, key.filter?.scriptLenRange)) {
return false;
}
}
if (key.scriptType === "type") {
if (!filterScript(cell.cellOutput.type, key.script, key.scriptSearchMode) ||
!filterScript(cell.cellOutput.lock, key.filter?.script, "prefix") ||
!filterScriptByLenRange(cell.cellOutput.lock, key.filter?.scriptLenRange)) {
return false;
}
}
if (!filterData(cell.outputData, key.filter?.outputData, key.filter?.outputDataSearchMode ?? "prefix") ||
!filterNumByRange(bytesFrom(cell.outputData).length, key.filter?.outputDataLenRange)) {
return false;
}
if (!filterNumByRange(cell.cellOutput.capacity, key.filter?.outputCapacityRange)) {
return false;
}
return true;
}
export class MapLru extends Map {
constructor(capacity) {
super();
this.capacity = capacity;
this.lru = [];
}
get(key) {
const val = super.get(key);
if (val === undefined) {
return;
}
const index = this.lru.indexOf(key);
if (index !== -1) {
this.lru.splice(index, 1);
}
this.lru.push(key);
if (this.lru.length > this.capacity) {
this.delete(this.lru[0]);
this.lru.shift();
}
return val;
}
set(key, value) {
this.get(key);
super.set(key, value);
return this;
}
delete(key) {
if (!super.delete(key)) {
return false;
}
const index = this.lru.indexOf(key);
if (index !== -1) {
this.lru.splice(index, 1);
}
return true;
}
}