function setupRateLimitAst()

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 };
}