in packages/sqrl-redis-functions/src/RateLimitFunctions.ts [49:107]
function setupRateLimitAst(state: CompileState, ast: CustomCallAst) {
const args: RateLimitArguments = parse(ast.source, {
startRule: "RateLimitArguments",
});
const { whereAst, whereFeatures, whereTruth } = state.combineGlobalWhere(
args.where
);
const tokenAmountAst = state.setGlobal(
ast,
AstBuilder.branch(
whereAst,
AstBuilder.call("_getTokenAmount", [args.tokenAmount]),
AstBuilder.constant(0)
)
);
const { entityId, entityAst } = state.addHashedEntity(ast, "RateLimit", {
whereFeatures,
whereTruth,
features: args.features,
maxAmount: args.maxAmount,
refillTimeMs: args.refillTimeMs,
refillAmount: args.refillAmount,
});
const keysAst = state.setGlobal(
ast,
AstBuilder.call("_getKeyList", [entityAst, ...args.features]),
`key(${entityId.getIdString()})`
);
// Convert the amount to be taken into a new global, this allows the
// entire array below to be pre-computed.
const takeAst = state.setGlobal(
ast,
AstBuilder.branch(
AstBuilder.feature("SqrlMutate"),
tokenAmountAst,
AstBuilder.constant(0)
)
);
const resultsAst = state.setGlobal(
ast,
AstBuilder.call("_fetchRateLimit", [
AstBuilder.props({
keys: keysAst,
maxAmount: AstBuilder.constant(args.maxAmount),
refillTimeMs: AstBuilder.constant(args.refillTimeMs),
refillAmount: AstBuilder.constant(args.refillAmount),
take: takeAst,
at: AstBuilder.call("timeMs", [AstBuilder.feature("SqrlClock")]),
strict: AstBuilder.constant(args.strict),
}),
]),
entityId.getIdString()
);
return { keysAst, resultsAst };
}