Repository: angular/angular
File: packages/core/src/defer/idle_service.ts (TypeScript)

Code before:
  typeof requestIdleCallback !== 'undefined' ? requestIdleCallback.bind(globalThis) : setTimeout;
const _cancelIdleCallback = () =>
  typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback.bind(globalThis) : clearTimeout;

/**
 * Service which configures custom 'on idle' behavior for Angular features like `@defer`.
 *
 * @publicApi
 */
export interface IdleService {
  /**
   * Schedule `callback` to be executed when the current application or browser is considered idle.
   *
   * @returns an id which allows the scheduled callback to be cancelled before it executes.
   */
  requestOnIdle(callback: (deadline?: IdleDeadline) => void): number;

  /**
   * Cancel a previously scheduled callback using the id associated with it.
   */
  cancelOnIdle(id: number): void;
}

export const IDLE_SERVICE = new InjectionToken<IdleService>(ngDevMode ? 'IDLE_SERVICE' : '', {
  providedIn: 'root',
  factory: () => new RequestIdleCallbackService(_requestIdleCallback(), _cancelIdleCallback()),
});

/**
 * Configures Angular to use the given DI token as its `IdleService`.
 *
 * The given token must be available for injection from the root injector, and the injected value
 * must implement the `IdleService` interface.
 *
 * @publicApi
 */
export function provideIdleServiceWith(
  useExisting: AbstractType<IdleService> | InjectionToken<IdleService>,
): EnvironmentProviders {
  return makeEnvironmentProviders([
    {
      provide: IDLE_SERVICE,
      useExisting,
    },
  ]);
}

/**
 * Default implementation of `IDLE_SERVICE` which uses `requestIdleCallback` when available or
 * `setTimeout` when not.
 */

Review comment (suggestion):
nit: I think we can avoid providing arguments here and instead just reference the necessary function directly in the class itself:
```suggestion
  factory: () => new RequestIdleCallbackService(),
```

and later in the code:

```
class RequestIdleCallbackService implements IdleService {
  private readonly requestIdleCallback = _requestIdleCallback(),
  private readonly cancelIdleCallback = _cancelIdleCallback(),

  requestOnIdle(callback: (deadline?: IdleDeadline) => void): number {
    return this.requestIdleCallback(callback);
  }

  cancelOnIdle(id: number): void {
    return this.cancelIdleCallback(id);
  }
}
```

Code after:
  typeof requestIdleCallback !== 'undefined' ? requestIdleCallback.bind(globalThis) : setTimeout;
const _cancelIdleCallback = () =>
  typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback.bind(globalThis) : clearTimeout;

/**
 * Service which configures custom 'on idle' behavior for Angular features like `@defer`.
 *
 * @publicApi
 */
export interface IdleService {
  /**
   * Schedule `callback` to be executed when the current application or browser is considered idle.
   *
   * @returns an id which allows the scheduled callback to be cancelled before it executes.
   */
  requestOnIdle(callback: (deadline?: IdleDeadline) => void): number;

  /**
   * Cancel a previously scheduled callback using the id associated with it.
   */
  cancelOnIdle(id: number): void;
}

export const IDLE_SERVICE = new InjectionToken<IdleService>(ngDevMode ? 'IDLE_SERVICE' : '', {
  providedIn: 'root',
  factory: () => new RequestIdleCallbackService(),
});

/**
 * Configures Angular to use the given DI token as its `IdleService`.
 *
 * The given token must be available for injection from the root injector, and the injected value
 * must implement the `IdleService` interface.
 *
 * @publicApi
 */
export function provideIdleServiceWith(
  useExisting: AbstractType<IdleService> | InjectionToken<IdleService>,
): EnvironmentProviders {
  return makeEnvironmentProviders([
    {
      provide: IDLE_SERVICE,
      useExisting,
    },
  ]);
}

/**
 * Default implementation of `IDLE_SERVICE` which uses `requestIdleCallback` when available or
 * `setTimeout` when not.
 */