Source: utils.js

import { setProperties } from '@ember/object';
import { later, cancel } from '@ember/runloop';
import { gte } from 'ember-compatibility-helpers';
import { EMBER_ENVIRONMENT } from "./ember-environment";
import {
  Yieldable,
  yieldableSymbol,
  YIELDABLE_CONTINUE,
  cancelableSymbol
} from "./external/yieldables";

export const USE_TRACKED = gte('3.16.0');
export const assignProperties = USE_TRACKED ? Object.assign : setProperties;

export function isEventedObject(c) {
  return (c && (
    (typeof c.one === 'function' && typeof c.off === 'function') ||
    (typeof c.on === 'function' && typeof c.off === 'function') ||
    (typeof c.addEventListener === 'function' && typeof c.removeEventListener === 'function')
  ));
}

export class EmberYieldable extends Yieldable {
  _deferable() {
    return EMBER_ENVIRONMENT.defer();
  }
}

class TimeoutYieldable extends EmberYieldable {
  constructor(ms) {
    super();
    this.ms = ms;
    this.timerId = null;
  }

  [yieldableSymbol](taskInstance, resumeIndex) {
    this.timerId = later(() => {
      taskInstance.proceed(resumeIndex, YIELDABLE_CONTINUE, taskInstance._result);
    }, this.ms);
  }

  [cancelableSymbol]() {
    cancel(this.timerId);
    this.timerId = null;
  }
}

/**
 *
 * Yielding `timeout(ms)` will pause a task for the duration
 * of time passed in, in milliseconds.
 *
 * This timeout will be scheduled on the Ember runloop, which
 * means that test helpers will wait for it to complete before
 * continuing with the test. See `rawTimeout()` if you need
 * different behavior.
 *
 * The task below, when performed, will print a message to the
 * console every second.
 *
 * ```js
 * export default class MyComponent extends Component {
 *   @task *myTask() {
 *     while (true) {
 *       console.log("Hello!");
 *       yield timeout(1000);
 *     }
 *   }
 * }
 * ```
 *
 * @param {number} ms - the amount of time to sleep before resuming
 *   the task, in milliseconds
 */
export function timeout(ms) {
  return new TimeoutYieldable(ms);
}

export function deprecatePrivateModule(moduleName) {
  // eslint-disable-next-line no-console
  console.warn(`an Ember addon is importing a private ember-concurrency module '${moduleName}' that has moved`);
}