/* Copyright 2026 Marimo. All rights reserved. */ import { arrayShallowEquals } from "./arrays"; // oxlint-disable-next-line typescript/no-explicit-any export function once any>(fn: T): T { let result: ReturnType; let called = false; return function ( this: ThisParameterType, ...args: Parameters ): ReturnType { if (!called) { called = true; result = fn.apply(this, args) as ReturnType; } return result; } as T; } // oxlint-disable-next-line typescript/no-explicit-any export function memoizeLastValue any>(fn: T): T { let result: ReturnType; let lastArgs: Parameters | undefined; let lastError: unknown; let hasError = false; return function ( this: ThisParameterType, ...args: Parameters ): ReturnType { if (lastArgs === undefined || !arrayShallowEquals(args, lastArgs)) { try { result = fn.apply(this, args) as ReturnType; hasError = false; lastError = undefined; } catch (error) { hasError = true; lastError = error; } lastArgs = args; } if (hasError) { throw lastError; } return result; } as T; }