CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lit--task

A controller for Lit that renders asynchronous tasks.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

argument-equality.mddocs/

Argument Equality

Argument comparison utilities for controlling when tasks should re-execute based on changes to their input parameters.

Capabilities

Shallow Array Equality

Default equality function that performs shallow comparison of argument arrays.

/**
 * Compares two argument arrays for shallow equality
 * Uses notEqual from @lit/reactive-element for individual item comparison
 * @param oldArgs - Previous arguments array
 * @param newArgs - Current arguments array  
 * @returns true if arrays have same length and all items are shallowly equal
 */
function shallowArrayEquals<T extends ReadonlyArray<unknown>>(
  oldArgs: T,
  newArgs: T
): boolean;

Usage Examples:

import { Task, shallowArrayEquals } from "@lit/task";

class MyElement extends LitElement {
  // Default behavior (shallowArrayEquals is used automatically)
  private _basicTask = new Task(this, {
    task: async ([name, age]) => fetchUserData(name, age),
    args: () => [this.userName, this.userAge]
    // argsEqual defaults to shallowArrayEquals
  });

  // Explicit shallow comparison
  private _explicitTask = new Task(this, {
    task: async ([id, settings]) => updateUser(id, settings),
    args: () => [this.userId, this.userSettings],
    argsEqual: shallowArrayEquals
  });
}

Deep Array Equality

Advanced equality function that performs deep comparison of argument arrays, useful when arguments contain objects.

/**
 * Compares two argument arrays for deep equality
 * Recursively compares nested objects, arrays, and primitive values
 * @param oldArgs - Previous arguments array
 * @param newArgs - Current arguments array
 * @returns true if arrays and all nested content are deeply equal
 */
function deepArrayEquals<T extends ReadonlyArray<unknown>>(
  oldArgs: T,
  newArgs: T
): boolean;

Usage Examples:

import { Task } from "@lit/task";
import { deepArrayEquals } from "@lit/task/deep-equals.js";

class DataComponent extends LitElement {
  private _complexTask = new Task(this, {
    task: async ([filters, options]) => {
      return searchData(filters, options);
    },
    args: () => [
      { category: this.category, tags: this.selectedTags },
      { sortBy: this.sortField, ascending: this.sortAsc }
    ],
    // Use deep equality since arguments are objects
    argsEqual: deepArrayEquals
  });

  updateFilters(newCategory: string, newTags: string[]) {
    this.category = newCategory;
    this.selectedTags = [...newTags];
    // Task will re-run because deepArrayEquals detects the change
  }
}

Deep Object Equality

Core deep equality function for comparing individual values recursively.

/**
 * Recursively compares two values for deep equality
 * Handles primitives, objects, arrays, Maps, Sets, RegExps, and custom valueOf/toString
 * @param a - First value to compare
 * @param b - Second value to compare
 * @returns true if values are deeply equal
 */
function deepEquals(a: unknown, b: unknown): boolean;

Supported Types:

  • Primitives (compared with Object.is())
  • Objects (same constructor, same properties, recursively equal values)
  • Arrays (same length, recursively equal items)
  • Maps and Sets (same size, recursively equal entries/keys)
  • RegExp (same source and flags)
  • Objects with custom valueOf() (e.g., Date)
  • Objects with custom toString() (e.g., URL)

Usage Examples:

import { deepEquals } from "@lit/task/deep-equals.js";

// Custom equality function using deepEquals
class CustomComponent extends LitElement {
  private _advancedTask = new Task(this, {
    task: async ([config]) => processConfig(config),
    args: () => [this.configuration],
    argsEqual: (oldArgs, newArgs) => {
      // Custom logic: only check the 'important' field deeply
      return deepEquals(oldArgs[0]?.important, newArgs[0]?.important);
    }
  });
}

// Testing equality manually
const config1 = { 
  settings: { theme: 'dark', lang: 'en' }, 
  metadata: new Date('2023-01-01') 
};
const config2 = { 
  settings: { theme: 'dark', lang: 'en' }, 
  metadata: new Date('2023-01-01') 
};

console.log(deepEquals(config1, config2)); // true

Custom Equality Functions

Creating custom argument comparison functions for specific use cases.

Performance-Optimized Equality:

class OptimizedComponent extends LitElement {
  private _optimizedTask = new Task(this, {
    task: async ([userId, prefs]) => loadUserPreferences(userId, prefs),
    args: () => [this.userId, this.userPreferences],
    // Only check userId, ignore preferences changes
    argsEqual: (oldArgs, newArgs) => oldArgs[0] === newArgs[0]
  });
}

Selective Deep Comparison:

class SelectiveComponent extends LitElement {
  private _selectiveTask = new Task(this, {
    task: async ([query, filters, pagination]) => searchAPI(query, filters, pagination),
    args: () => [this.searchQuery, this.activeFilters, this.paginationState],
    argsEqual: (oldArgs, newArgs) => {
      // Shallow check query and deep check filters, ignore pagination
      return oldArgs[0] === newArgs[0] && 
             deepEquals(oldArgs[1], newArgs[1]);
    }
  });
}

Debounced Equality:

class DebouncedComponent extends LitElement {
  private _lastChangeTime = 0;
  private _debounceMs = 300;

  private _debouncedTask = new Task(this, {
    task: async ([searchTerm]) => searchAPI(searchTerm),
    args: () => [this.searchInput],
    argsEqual: (oldArgs, newArgs) => {
      const now = Date.now();
      if (oldArgs[0] !== newArgs[0]) {
        this._lastChangeTime = now;
        return true; // Consider equal to prevent immediate execution
      }
      // Only execute if enough time has passed
      return (now - this._lastChangeTime) < this._debounceMs;
    }
  });
}

Important Notes

Cycle Detection: The deepEquals function does not handle circular references. Objects must be cycle-free or the function will run infinitely.

Performance Considerations:

  • shallowArrayEquals: Fast, suitable for primitive arguments
  • deepArrayEquals: Slower, use when arguments contain objects
  • Custom functions: Tailor performance to your specific needs

Type Safety: All equality functions maintain full TypeScript type safety with the argument arrays.

docs

argument-equality.md

index.md

status-rendering.md

task-management.md

tile.json