-
Notifications
You must be signed in to change notification settings - Fork 2
Utils Once
GitHub Actions edited this page Sep 18, 2026
·
1 revision
Function execution control for single-call enforcement with result caching.
The once utility ensures functions execute only once, caching results for subsequent calls:
- Single Execution: Guaranteed one-time execution
- Result Caching: Memoizes return value
- Error Handling: Caches and re-throws errors
- Async Support: Works with promises
-
Method Decorator:
@Oncefor class methods
deno add @tundralibs/utilsWraps a function to execute only once.
Parameters:
-
fn: Function to wrap
Returns: Wrapped function that executes once
Decorator for class methods.
import { once } from '@tundralibs/utils';
declare function loadConfiguration(): { debug: boolean };
const initialize = once(() => {
console.log('Initializing...');
return loadConfiguration();
});
initialize(); // Logs "Initializing...", returns config
initialize(); // Returns cached config (no log)
initialize(); // Returns cached config (no log)import { once } from '@tundralibs/utils';
declare function complexPiCalculation(precision: number): number;
const calculatePi = once((precision: number) => {
console.log('Computing π...');
// Expensive calculation
return complexPiCalculation(precision);
});
const pi1 = calculatePi(1000); // Computes
const pi2 = calculatePi(2000); // Returns cached result (ignores new arg)
console.log(pi1 === pi2); // trueimport { once } from '@tundralibs/utils';
declare function delay(ms: number): Promise<void>;
declare class DatabaseConnection {}
const connectDB = once(async () => {
console.log('Connecting to database...');
await delay(1000);
return new DatabaseConnection();
});
// Multiple calls, but only one connection
const db1 = await connectDB();
const db2 = await connectDB();
console.log(db1 === db2); // trueimport { Once } from '@tundralibs/utils';
declare function connectToDatabase(): Promise<unknown>;
class Application {
@Once
initialize() {
console.log('App initializing...');
this.loadPlugins();
this.setupRoutes();
return 'ready';
}
loadPlugins() {}
setupRoutes() {}
@Once
async loadDatabase() {
console.log('Loading DB...');
return await connectToDatabase();
}
}
const app = new Application();
app.initialize(); // Runs initialization
app.initialize(); // Returns cached result
app.initialize(); // Returns cached resultimport { once } from '@tundralibs/utils';
const riskyOperation = once(() => {
throw new Error('Operation failed');
});
try {
riskyOperation();
} catch (err) {
console.log((err as Error).message); // "Operation failed"
}
try {
riskyOperation(); // Throws same cached error
} catch (err) {
console.log((err as Error).message); // "Operation failed"
}A FALSY thrown value (
throw 0,throw '',throw false) is still cached and re-thrown on later calls —oncetracks "did the first call throw" as its own flag, not by checking the thrown value's truthiness, so it can't mistake a legitimately falsy throw for "no error yet".
import { once } from '@tundralibs/utils';
declare class Logger {
constructor(options: { level: string; output: string });
}
const getLogger = once(() => {
console.log('Creating logger instance...');
return new Logger({
level: 'info',
output: 'console',
});
});
// Safe to call from multiple modules
const logger = getLogger();
export { logger };- Initialization: Use for setup functions
- Resource Creation: Single instance of connections, loggers
- Expensive Ops: Cache results of costly operations
- Not for Parameterized Calls: Arguments after first call are ignored
import { once } from '@tundralibs/utils';
declare function loadConfig(): void;
declare function setupHooks(): void;
declare function registerPlugins(): void;
const initializeModule = once(() => {
console.log('Module initializing...');
loadConfig();
setupHooks();
registerPlugins();
return { status: 'ready' };
});
export { initializeModule };import { once } from '@tundralibs/utils';
const getHeavyLib = once(async () => {
console.log('Loading heavy library...');
return await import('./heavy-library.js');
});
// Library loads only when first needed
const lib = await getHeavyLib();| Feature | once | memoize |
|---|---|---|
| Execution count | Exactly once | Once per unique args |
| Argument handling | Ignores after first | Considers all |
| Use case | Initialization | Computation cache |
| TTL support | No | Yes |