or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-once

Run a function exactly one time

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/once@1.4.x

To install, run

npx @tessl/cli install tessl/npm-once@1.4.0

index.mddocs/

Once

Once is a utility library that ensures any given function can only be executed once, returning the cached result of the first execution on subsequent calls. It provides both a regular 'once' wrapper that silently returns the cached value and a 'strict' variant that throws an error on repeated calls, helping developers catch logic errors where functions are accidentally called multiple times.

Package Information

  • Package Name: once
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install once

Core Imports

var once = require('once');

Note: This package uses CommonJS format only. ES modules can import it using:

import once from 'once';

However, the above may require bundler configuration or Node.js compatibility features.

Basic Usage

var once = require('once');

function load(file, cb) {
  cb = once(cb);
  loader.load('file');
  loader.once('load', cb);
  loader.once('error', cb);
}

Capabilities

Function Wrapping with Caching

Wraps a function to ensure it can only be called once, returning the cached result on subsequent calls.

/**
 * Wraps a function to ensure it can only be called once
 * @param {Function} fn - The function to wrap
 * @returns {Function} Wrapped function with caching behavior and state properties
 */
function once(fn);

The returned function has these properties:

  • called (Boolean): Whether the function has been called (initially false)
  • value (Any): Cached return value from first execution (undefined until called)

Important: The wrapped function preserves all original function properties and maintains the original function's this context when called.

Usage Examples:

var once = require('once');

function expensiveOperation(data) {
  console.log('Computing...');
  return data * 2;
}

var cachedOperation = once(expensiveOperation);

console.log(cachedOperation(5)); // Logs "Computing..." then returns 10
console.log(cachedOperation(5)); // Returns 10 immediately (no logging)
console.log(cachedOperation.called); // true
console.log(cachedOperation.value); // 10

// Property and context preservation example
function Calculator(multiplier) {
  this.multiplier = multiplier;
}

Calculator.prototype.compute = function(value) {
  return value * this.multiplier;
};

Calculator.prototype.compute.customProperty = 'preserved';

var calc = new Calculator(3);
var onceCompute = once(calc.compute);

// Properties are preserved
console.log(onceCompute.customProperty); // 'preserved'

// Context is preserved when using call/apply
console.log(onceCompute.call(calc, 5)); // 15 (5 * 3)
console.log(onceCompute.call(calc, 10)); // 15 (cached result)

Strict Function Wrapping

Strict variant that throws an error when called more than once, helping catch logic errors.

/**
 * Wraps a function to throw an error if called more than once
 * @param {Function} fn - The function to wrap
 * @returns {Function} Wrapped function that throws on subsequent calls
 */
once.strict(fn);

The returned function has these properties:

  • called (Boolean): Whether the function has been called (initially false)
  • value (Any): Return value from first execution
  • onceError (String): Error message for multiple calls (can be customized)

Important: The wrapped function preserves all original function properties and maintains the original function's this context when called.

Usage Examples:

var once = require('once');

function greet(name, cb) {
  if (!name) return cb('Hello anonymous');
  cb('Hello ' + name);
}

function log(msg) {
  console.log(msg);
}

// Using strict mode to catch logic errors
greet(null, once.strict(log));
// First call: logs "Hello anonymous"
// Second call: throws Error: "log shouldn't be called more than once"

Custom Error Messages:

var strictFn = once.strict(someFunction);
strictFn.onceError = 'Custom error message';
// Now throws: Error: "Custom error message"

Prototype Extension

Extends Function.prototype with once and onceStrict methods for convenient usage.

/**
 * Extends Function.prototype with once and onceStrict methods
 * @returns {undefined}
 */
once.proto();

After calling once.proto(), all functions gain these methods:

  • Function.prototype.once(): Returns once(this)
  • Function.prototype.onceStrict(): Returns once.strict(this)

Usage Examples:

var once = require('once');

// Enable prototype extension (only needs to be done once)
once.proto();

function load(file, cb) {
  cb = cb.once(); // Use prototype method instead of once(cb)
  loader.load('file');
  loader.once('load', cb);
  loader.once('error', cb);
}

// Also works with strict mode
function criticalCallback() {
  // Important logic here
}

var safeCriticalCallback = criticalCallback.onceStrict();

State Inspection

All wrapped functions provide state inspection capabilities:

// Properties available on wrapped functions:
interface WrappedFunction extends Function {
  called: boolean;      // Whether function has been executed
  value: any;          // Cached return value (once variant only)
  onceError?: string;  // Custom error message (strict variant only)
}

Usage Examples:

var once = require('once');

function getData() {
  return { data: 'important' };
}

var cachedGetData = once(getData);

// Check if function has been called
if (!cachedGetData.called) {
  console.log('Function not yet called');
}

var result = cachedGetData();
console.log(cachedGetData.called); // true
console.log(cachedGetData.value);  // { data: 'important' }

// Use in conditional logic
function processData(callback) {
  callback = once(callback);
  
  // Do async work...
  
  // Only call callback if not already called
  if (!callback.called) {
    callback(processedData);
  }
}

Error Handling

Standard Once Behavior

  • No errors thrown on multiple calls
  • Silently returns cached value
  • Suitable for callbacks and event handlers

Strict Mode Behavior

  • Throws Error on second and subsequent calls
  • Default error message: "{functionName} shouldn't be called more than once"
  • For anonymous functions: "Function wrapped with \once` shouldn't be called more than once"`
  • Custom error messages supported via onceError property
// Error handling example
try {
  var strictFn = once.strict(myFunction);
  strictFn(); // First call - OK
  strictFn(); // Second call - throws Error
} catch (err) {
  console.error('Function called multiple times:', err.message);
}

Types

/**
 * Main once function type
 */
declare function once<T extends Function>(fn: T): T & {
  called: boolean;
  value: any;
};

/**
 * Strict variant type
 */
declare function strict<T extends Function>(fn: T): T & {
  called: boolean;
  value: any;
  onceError: string;
};

/**
 * Prototype extension function type
 */
declare function proto(): void;

/**
 * Extended Function prototype (after calling once.proto())
 */
interface Function {
  once<T extends Function>(this: T): T & { called: boolean; value: any; };
  onceStrict<T extends Function>(this: T): T & { called: boolean; value: any; onceError: string; };
}