Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nuclide-commons

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nuclide-commons - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

BatchProcessedQueue.js

199

collection.js

@@ -1,35 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.arrayRemove = arrayRemove;
exports.arrayEqual = arrayEqual;
exports.arrayCompact = arrayCompact;
exports.arrayFlatten = arrayFlatten;
exports.arrayUnique = arrayUnique;
exports.arrayFindLastIndex = arrayFindLastIndex;
exports.mapUnion = mapUnion;
exports.mapFilter = mapFilter;
exports.mapTransform = mapTransform;
exports.mapEqual = mapEqual;
exports.mapGetWithDefault = mapGetWithDefault;
exports.areSetsEqual = areSetsEqual;
exports.every = every;
exports.setIntersect = setIntersect;
exports.setUnion = setUnion;
exports.setDifference = setDifference;
exports.isEmpty = isEmpty;
exports.keyMirror = keyMirror;
exports.collect = collect;
exports.objectEntries = objectEntries;
exports.objectFromMap = objectFromMap;
exports.concatIterators = concatIterators;
exports.someOfIterable = someOfIterable;
exports.findInIterable = findInIterable;
exports.filterIterable = filterIterable;
exports.mapIterable = mapIterable;
exports.firstOfIterable = firstOfIterable;
exports.iterableIsEmpty = iterableIsEmpty;
exports.iterableContains = iterableContains;
/**

@@ -42,7 +8,7 @@ * Copyright (c) 2015-present, Facebook, Inc.

*
*
* @flow
* @format
*/
function arrayRemove(array, element) {
export function arrayRemove<T>(array: Array<T>, element: T): void {
const index = array.indexOf(element);

@@ -54,7 +20,11 @@ if (index >= 0) {

function arrayEqual(array1, array2, equalComparator) {
export function arrayEqual<T>(
array1: Array<T>,
array2: Array<T>,
equalComparator?: (a: T, b: T) => boolean,
): boolean {
if (array1.length !== array2.length) {
return false;
}
const equalFunction = equalComparator || ((a, b) => a === b);
const equalFunction = equalComparator || ((a: T, b: T) => a === b);
return array1.every((item1, i) => equalFunction(item1, array2[i]));

@@ -67,3 +37,3 @@ }

*/
function arrayCompact(array) {
export function arrayCompact<T>(array: Array<?T>): Array<T> {
const result = [];

@@ -81,3 +51,3 @@ for (const elem of array) {

*/
function arrayFlatten(array) {
export function arrayFlatten<T>(array: Array<Array<T>>): Array<T> {
const result = [];

@@ -95,3 +65,3 @@ for (const subArray of array) {

*/
function arrayUnique(array) {
export function arrayUnique<T>(array: Array<T>): Array<T> {
return Array.from(new Set(array));

@@ -104,3 +74,7 @@ }

*/
function arrayFindLastIndex(array, predicate, thisArg) {
export function arrayFindLastIndex<T>(
array: Array<T>,
predicate: (elem: T, index: number, array: Array<T>) => boolean,
thisArg?: any,
): number {
for (let i = array.length - 1; i >= 0; i--) {

@@ -118,3 +92,3 @@ if (predicate.call(thisArg, array[i], i, array)) {

*/
function mapUnion(...maps) {
export function mapUnion<T, X>(...maps: Array<Map<T, X>>): Map<T, X> {
const unionMap = new Map();

@@ -129,3 +103,6 @@ for (const map of maps) {

function mapFilter(map, selector) {
export function mapFilter<T, X>(
map: Map<T, X>,
selector: (key: T, value: X) => boolean,
): Map<T, X> {
const selected = new Map();

@@ -140,3 +117,6 @@ for (const [key, value] of map) {

function mapTransform(src, transform) {
export function mapTransform<T, V1, V2>(
src: Map<T, V1>,
transform: (value: V1, key: T) => V2,
): Map<T, V2> {
const result = new Map();

@@ -149,9 +129,13 @@ for (const [key, value] of src) {

function mapEqual(map1, map2, equalComparator) {
export function mapEqual<T, X>(
map1: Map<T, X>,
map2: Map<T, X>,
equalComparator?: (val1: X, val2: X, key1?: T, key2?: T) => boolean,
) {
if (map1.size !== map2.size) {
return false;
}
const equalFunction = equalComparator || ((a, b) => a === b);
const equalFunction = equalComparator || ((a: X, b: X) => a === b);
for (const [key1, value1] of map1) {
if (!map2.has(key1) || !equalFunction(value1, map2.get(key1))) {
if (!map2.has(key1) || !equalFunction(value1, (map2.get(key1): any))) {
return false;

@@ -163,3 +147,7 @@ }

function mapGetWithDefault(map, key, default_) {
export function mapGetWithDefault<K, V>(
map: Map<K, V>,
key: K,
default_: V,
): V {
if (map.has(key)) {

@@ -169,3 +157,3 @@ // Cast through `any` since map.get's return is a maybe type. We can't just get the value and

// just checked that the map has the key.
return map.get(key);
return (map.get(key): any);
} else {

@@ -176,3 +164,3 @@ return default_;

function areSetsEqual(a, b) {
export function areSetsEqual<T>(a: Set<T>, b: Set<T>): boolean {
return a.size === b.size && every(a, element => b.has(element));

@@ -182,3 +170,6 @@ }

// Array.every but for any iterable.
function every(values, predicate) {
export function every<T>(
values: Iterable<T>,
predicate: (element: T) => boolean,
): boolean {
for (const element of values) {

@@ -192,7 +183,7 @@ if (!predicate(element)) {

function setIntersect(a, b) {
export function setIntersect<T>(a: Set<T>, b: Set<T>): Set<T> {
return new Set(Array.from(a).filter(e => b.has(e)));
}
function setUnion(a, b) {
export function setUnion<T>(a: Set<T>, b: Set<T>): Set<T> {
// Avoids the extra Array allocations that `new Set([...a, ...b])` would incur. Some quick tests

@@ -207,3 +198,7 @@ // indicate it would be about 60% slower.

function setDifference(a, b, hash_) {
export function setDifference<T>(
a: Set<T>,
b: Set<T>,
hash_?: (v: T) => any,
): Set<T> {
if (a.size === 0) {

@@ -228,3 +223,3 @@ return new Set();

*/
function isEmpty(obj) {
export function isEmpty(obj: Object): boolean {
for (const key in obj) {

@@ -242,3 +237,3 @@ return false;

*/
function keyMirror(obj) {
export function keyMirror<T: Object>(obj: T): {[key: $Enum<T>]: $Enum<T>} {
const ret = {};

@@ -255,3 +250,3 @@ Object.keys(obj).forEach(key => {

*/
function collect(pairs) {
export function collect<K, V>(pairs: Array<[K, V]>): Map<K, Array<V>> {
const result = new Map();

@@ -270,4 +265,13 @@ for (const pair of pairs) {

class MultiMap {
export class MultiMap<K, V> {
// Invariant: no empty sets. They should be removed instead.
_map: Map<K, Set<V>>;
// TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and
// don't mutate this from outside this class.
//
// Invariant: equal to the sum of the sizes of all the sets contained in this._map
/* The total number of key-value bindings contained */
size: number;
constructor() {

@@ -282,10 +286,3 @@ this._map = new Map();

*/
// TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and
// don't mutate this from outside this class.
//
// Invariant: equal to the sum of the sizes of all the sets contained in this._map
/* The total number of key-value bindings contained */
get(key) {
get(key: K): Set<V> {
const set = this._map.get(key);

@@ -302,3 +299,3 @@ if (set == null) {

*/
add(key, value) {
add(key: K, value: V): MultiMap<K, V> {
let set = this._map.get(key);

@@ -319,3 +316,3 @@ if (set == null) {

*/
set(key, values) {
set(key: K, values: Iterable<V>): void {
this.deleteAll(key);

@@ -332,3 +329,3 @@ const newSet = new Set(values);

*/
delete(key, value) {
delete(key: K, value: V): boolean {
const set = this.get(key);

@@ -348,3 +345,3 @@ const didRemove = set.delete(value);

*/
deleteAll(key) {
deleteAll(key: K): boolean {
const set = this.get(key);

@@ -355,3 +352,3 @@ this.size -= set.size;

clear() {
clear(): void {
this._map.clear();

@@ -361,11 +358,11 @@ this.size = 0;

has(key, value) {
has(key: K, value: V): boolean {
return this.get(key).has(value);
}
hasAny(key) {
hasAny(key: K): boolean {
return this._map.has(key);
}
*values() {
*values(): Iterable<V> {
for (const set of this._map.values()) {

@@ -376,9 +373,10 @@ yield* set;

forEach(callback) {
this._map.forEach((values, key) => values.forEach(value => callback(value, key, this)));
forEach(callback: (value: V, key: K, obj: MultiMap<K, V>) => void): void {
this._map.forEach((values, key) =>
values.forEach(value => callback(value, key, this)),
);
}
}
exports.MultiMap = MultiMap;
function objectEntries(obj) {
export function objectEntries<T>(obj: {[key: string]: T}): Array<[string, T]> {
if (obj == null) {

@@ -389,3 +387,6 @@ throw new TypeError();

for (const key in obj) {
if (obj.hasOwnProperty(key) && Object.prototype.propertyIsEnumerable.call(obj, key)) {
if (
obj.hasOwnProperty(key) &&
Object.prototype.propertyIsEnumerable.call(obj, key)
) {
entries.push([key, obj[key]]);

@@ -397,3 +398,3 @@ }

function objectFromMap(map) {
export function objectFromMap<T>(map: Map<string, T>): {[key: string]: T} {
const obj = {};

@@ -406,3 +407,5 @@ map.forEach((v, k) => {

function* concatIterators(...iterators) {
export function* concatIterators<T>(
...iterators: Array<Iterable<T>>
): Iterator<T> {
for (const iterator of iterators) {

@@ -415,3 +418,6 @@ for (const element of iterator) {

function someOfIterable(iterable, predicate) {
export function someOfIterable<T>(
iterable: Iterable<T>,
predicate: (element: T) => boolean,
): boolean {
for (const element of iterable) {

@@ -425,3 +431,6 @@ if (predicate(element)) {

function findInIterable(iterable, predicate) {
export function findInIterable<T>(
iterable: Iterable<T>,
predicate: (element: T) => boolean,
): ?T {
for (const element of iterable) {

@@ -435,3 +444,6 @@ if (predicate(element)) {

function* filterIterable(iterable, predicate) {
export function* filterIterable<T>(
iterable: Iterable<T>,
predicate: (element: T) => boolean,
): Iterable<T> {
for (const element of iterable) {

@@ -444,3 +456,6 @@ if (predicate(element)) {

function* mapIterable(iterable, projectorFn) {
export function* mapIterable<T, M>(
iterable: Iterable<T>,
projectorFn: (element: T) => M,
): Iterable<M> {
for (const element of iterable) {

@@ -451,7 +466,7 @@ yield projectorFn(element);

function firstOfIterable(iterable) {
export function firstOfIterable<T>(iterable: Iterable<T>): ?T {
return findInIterable(iterable, () => true);
}
function iterableIsEmpty(iterable) {
export function iterableIsEmpty<T>(iterable: Iterable<T>): boolean {
// eslint-disable-next-line no-unused-vars

@@ -464,4 +479,6 @@ for (const element of iterable) {

function iterableContains(iterable, value) {
return !iterableIsEmpty(filterIterable(iterable, element => element === value));
}
export function iterableContains<T>(iterable: Iterable<T>, value: T): boolean {
return !iterableIsEmpty(
filterIterable(iterable, element => element === value),
);
}

@@ -1,16 +0,35 @@

'use strict';
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
* @flow
* @format
*/
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = debounce;
function debounce(func, wait, immediate = false) {
import invariant from 'assert';
export default function debounce<
T,
TArgs: Array<T>,
TReturn,
TFunc: (...TArgs) => TReturn, // eslint-disable-line space-before-function-paren
>(
func: TFunc,
wait: number,
immediate?: boolean = false,
): {
(...TArgs): TReturn | void,
dispose(): void,
} {
// Taken from: https://github.com/jashkenas/underscore/blob/b10b2e6d72/underscore.js#L815.
let timeout;
let args;
let context;
let timeout: ?number;
let args: ?TArgs;
let context: any;
let timestamp = 0;
let result;
let result: TReturn | void;
const later = function () {
const later = function() {
const last = Date.now() - timestamp;

@@ -23,6 +42,3 @@

if (!immediate) {
if (!(args != null)) {
throw new Error('Invariant violation: "args != null"');
}
invariant(args != null);
result = func.apply(context, args);

@@ -36,3 +52,3 @@ if (!timeout) {

const debounced = function (...args_) {
const debounced = function(...args_: TArgs): TReturn | void {
context = this;

@@ -61,11 +77,2 @@ args = args_;

return debounced;
} /**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
*
* @format
*/
}

@@ -1,23 +0,2 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.attachEvent = attachEvent;
exports.observableFromSubscribeFunction = observableFromSubscribeFunction;
var _eventKit;
function _load_eventKit() {
return _eventKit = require('event-kit');
}
var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');
/**
* Add an event listener an return a disposable for removing it. Note that this function assumes
* node EventEmitter semantics: namely, that adding the same combination of eventName and callback
* adds a second listener.
*/
/**
* Copyright (c) 2015-present, Facebook, Inc.

@@ -29,9 +8,21 @@ * All rights reserved.

*
*
* @flow
* @format
*/
function attachEvent(emitter, eventName, callback) {
import {Disposable} from 'event-kit';
import {Observable} from 'rxjs';
/**
* Add an event listener an return a disposable for removing it. Note that this function assumes
* node EventEmitter semantics: namely, that adding the same combination of eventName and callback
* adds a second listener.
*/
export function attachEvent(
emitter: events$EventEmitter,
eventName: string,
callback: Function,
): Disposable {
emitter.addListener(eventName, callback);
return new (_eventKit || _load_eventKit()).Disposable(() => {
return new Disposable(() => {
emitter.removeListener(eventName, callback);

@@ -41,4 +32,9 @@ });

function observableFromSubscribeFunction(fn) {
return _rxjsBundlesRxMinJs.Observable.create(observer => {
type SubscribeCallback<T> = (item: T) => any;
type SubscribeFunction<T> = (callback: SubscribeCallback<T>) => IDisposable;
export function observableFromSubscribeFunction<T>(
fn: SubscribeFunction<T>,
): Observable<T> {
return Observable.create(observer => {
const disposable = fn(observer.next.bind(observer));

@@ -49,2 +45,2 @@ return () => {

});
}
}

@@ -1,42 +0,49 @@

'use strict';
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
* @flow
* @format
*/
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.__TEST__ = undefined;
// NuclideUri's are either a local file path, or a URI
// of the form nuclide://<host><path>
//
// This package creates, queries and decomposes NuclideUris.
var _path = _interopRequireDefault(require('path'));
export type NuclideUri = string;
var _url = _interopRequireDefault(require('url'));
type ParsedUrl = {
hostname: ?string,
path: string,
};
var _os = _interopRequireDefault(require('os'));
type ParsedRemoteUrl = {
hostname: string,
path: string,
};
var _string;
type ParsedPath = {
root: string,
dir: string,
base: string,
ext: string,
name: string,
};
function _load_string() {
return _string = require('./string');
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
import invariant from 'assert';
// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri
const REMOTE_PATH_URI_PREFIX = 'nuclide://'; /**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
*
* @format
*/
import pathModule from 'path';
// NuclideUri's are either a local file path, or a URI
// of the form nuclide://<host><path>
//
// This package creates, queries and decomposes NuclideUris.
import url from 'url';
import os from 'os';
import {maybeToString} from './string';
const REMOTE_PATH_URI_PREFIX = 'nuclide://';
const URI_PREFIX_REGEX = /^[A-Za-z0-9_-]+:\/\/.*/;
function isRemote(uri) {
function isRemote(uri: NuclideUri): boolean {
return uri.startsWith(REMOTE_PATH_URI_PREFIX);

@@ -48,3 +55,3 @@ }

// and are destroyed during Nuclide startup.
function isBrokenDeserializedUri(uri) {
function isBrokenDeserializedUri(uri: ?NuclideUri): boolean {
return uri != null && uri.match(/nuclide:[\\/][^/]/) != null;

@@ -54,19 +61,19 @@ }

// Atom often puts its URIs in places where we'd expect to see Nuclide URIs (or plain paths)
function isAtomUri(uri) {
function isAtomUri(uri: NuclideUri): boolean {
return uri.startsWith('atom://');
}
function isUri(uri) {
function isUri(uri: string): boolean {
return URI_PREFIX_REGEX.test(uri);
}
function isLocal(uri) {
function isLocal(uri: NuclideUri): boolean {
return !isRemote(uri) && !isUri(uri) && !isAtomUri(uri);
}
function createRemoteUri(hostname, remotePath) {
if (!(remotePath != null && remotePath !== '')) {
throw new Error('NuclideUri must include a path.');
}
function createRemoteUri(hostname: string, remotePath: string): string {
invariant(
remotePath != null && remotePath !== '',
'NuclideUri must include a path.',
);
return `nuclide://${hostname}${remotePath}`;

@@ -84,3 +91,3 @@ }

*/
function parse(uri) {
function parse(uri: NuclideUri): ParsedUrl {
if (uri.startsWith(REMOTE_PATH_URI_PREFIX)) {

@@ -90,24 +97,26 @@ const hostAndPath = uri.substr(REMOTE_PATH_URI_PREFIX.length);

if (!(hostSep !== -1)) {
throw new Error(`Remote URIs must contain a hostname and a path. Failed to parse ${uri}`);
}
invariant(
hostSep !== -1,
`Remote URIs must contain a hostname and a path. Failed to parse ${uri}`,
);
const hostname = hostAndPath.substr(0, hostSep);
invariant(
hostname !== '',
`Remote URIs must contain a hostname. Failed to parse ${uri}`,
);
if (!(hostname !== '')) {
throw new Error(`Remote URIs must contain a hostname. Failed to parse ${uri}`);
}
const path = hostAndPath.substr(hostSep);
return { hostname, path };
return {hostname, path};
}
if (!(uri.indexOf('://') === -1)) {
throw new Error('Nuclide URI must be either local file names or URLs starting with nuclide://');
}
invariant(
uri.indexOf('://') === -1,
'Nuclide URI must be either local file names or URLs starting with nuclide://',
);
return { hostname: null, path: uri };
return {hostname: null, path: uri};
}
function parseRemoteUri(remoteUri) {
function parseRemoteUri(remoteUri: NuclideUri): ParsedRemoteUrl {
if (!isRemote(remoteUri)) {

@@ -117,26 +126,25 @@ throw new Error('Expected remote uri. Got ' + remoteUri);

const parsedUri = parse(remoteUri);
invariant(
parsedUri.hostname,
`Remote Nuclide URIs must contain hostnames, '${maybeToString(parsedUri.hostname)}' found ` +
`while parsing '${remoteUri}'`,
);
if (!parsedUri.hostname) {
throw new Error(`Remote Nuclide URIs must contain hostnames, '${(0, (_string || _load_string()).maybeToString)(parsedUri.hostname)}' found ` + `while parsing '${remoteUri}'`);
}
// Explicitly copying object properties appeases Flow's "maybe" type handling. Using the `...`
// operator causes null/undefined errors, and `Object.assign` bypasses type checking.
return {
hostname: parsedUri.hostname,
path: parsedUri.path
path: parsedUri.path,
};
}
function getPath(uri) {
function getPath(uri: NuclideUri): string {
return parse(uri).path;
}
function getHostname(remoteUri) {
function getHostname(remoteUri: NuclideUri): string {
return parseRemoteUri(remoteUri).hostname;
}
function getHostnameOpt(remoteUri) {
function getHostnameOpt(remoteUri: ?NuclideUri): ?string {
if (remoteUri == null || !isRemote(remoteUri)) {

@@ -149,9 +157,12 @@ return null;

function join(uri, ...relativePath) {
function join(uri: NuclideUri, ...relativePath: Array<string>): NuclideUri {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
if (isRemote(uri)) {
const { hostname, path } = parseRemoteUri(uri);
const {hostname, path} = parseRemoteUri(uri);
relativePath.splice(0, 0, path);
return createRemoteUri(hostname, uriPathModule.join.apply(null, relativePath));
return createRemoteUri(
hostname,
uriPathModule.join.apply(null, relativePath),
);
} else {

@@ -163,7 +174,7 @@ relativePath.splice(0, 0, uri);

function normalize(uri) {
function normalize(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
if (isRemote(uri)) {
const { hostname, path } = parseRemoteUri(uri);
const {hostname, path} = parseRemoteUri(uri);
return createRemoteUri(hostname, uriPathModule.normalize(path));

@@ -175,7 +186,7 @@ } else {

function normalizeDir(uri) {
function normalizeDir(uri: NuclideUri): NuclideUri {
return ensureTrailingSeparator(normalize(uri));
}
function getParent(uri) {
function getParent(uri: NuclideUri): NuclideUri {
// TODO: Is this different than dirname?

@@ -185,8 +196,13 @@ return normalize(join(uri, '..'));

function relative(uri, other) {
function relative(uri: NuclideUri, other: NuclideUri): string {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
const remote = isRemote(uri);
if (remote !== isRemote(other) || remote && getHostname(uri) !== getHostname(other)) {
throw new Error(`Cannot relative urls on different hosts: ${uri} and ${other}`);
if (
remote !== isRemote(other) ||
(remote && getHostname(uri) !== getHostname(other))
) {
throw new Error(
`Cannot relative urls on different hosts: ${uri} and ${other}`,
);
}

@@ -200,3 +216,3 @@ if (remote) {

function basename(uri, ext = '') {
function basename(uri: NuclideUri, ext: string = ''): string {
_testForAtomUri(uri);

@@ -207,7 +223,7 @@ const uriPathModule = _pathModuleFor(uri);

function dirname(uri) {
function dirname(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
if (isRemote(uri)) {
const { hostname, path } = parseRemoteUri(uri);
const {hostname, path} = parseRemoteUri(uri);
return createRemoteUri(hostname, uriPathModule.dirname(path));

@@ -219,3 +235,3 @@ } else {

function extname(uri) {
function extname(uri: NuclideUri): string {
_testForAtomUri(uri);

@@ -226,3 +242,3 @@ const uriPathModule = _pathModuleFor(uri);

function stripExtension(uri) {
function stripExtension(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);

@@ -237,7 +253,7 @@ const ext = extname(uri);

function _isWindowsPath(path) {
return _pathModuleFor(path) === _path.default.win32;
function _isWindowsPath(path: string): boolean {
return _pathModuleFor(path) === pathModule.win32;
}
function _getWindowsPathFromWindowsFileUri(uri) {
function _getWindowsPathFromWindowsFileUri(uri: string): ?string {
const prefix = 'file://';

@@ -258,3 +274,3 @@ if (!uri.startsWith(prefix)) {

*/
function uriToNuclideUri(uri) {
function uriToNuclideUri(uri: string): ?string {
const windowsPathFromUri = _getWindowsPathFromWindowsFileUri(uri);

@@ -269,3 +285,3 @@ if (windowsPathFromUri) {

const urlParts = _url.default.parse(_escapeSpecialCharacters(uri), false);
const urlParts = url.parse(_escapeSpecialCharacters(uri), false);
if (urlParts.protocol === 'file:' && urlParts.path) {

@@ -284,3 +300,3 @@ // only handle real files for now.

*/
function nuclideUriToUri(uri) {
function nuclideUriToUri(uri: NuclideUri): string {
_testForAtomUri(uri);

@@ -297,3 +313,3 @@ if (isRemote(uri)) {

*/
function contains(parent, child) {
function contains(parent: NuclideUri, child: NuclideUri): boolean {
_testForAtomUri(parent);

@@ -344,3 +360,3 @@ _testForAtomUri(child);

*/
function collapse(paths) {
function collapse(paths: Array<NuclideUri>): Array<NuclideUri> {
return paths.filter(p => !paths.some(fp => contains(fp, p) && fp !== p));

@@ -353,6 +369,6 @@ }

// Returns null if the formatter won't shorten the hostname.
export type HostnameFormatter = (uri: NuclideUri) => ?string;
// Registers a host formatter for nuclideUriToDisplayString
function registerHostnameFormatter(formatter) {
function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable {
hostFormatters.push(formatter);

@@ -365,3 +381,3 @@ return {

}
}
},
};

@@ -374,3 +390,3 @@ }

*/
function nuclideUriToDisplayString(uri) {
function nuclideUriToDisplayString(uri: NuclideUri): string {
_testForAtomUri(uri);

@@ -392,3 +408,3 @@ if (isRemote(uri)) {

function ensureTrailingSeparator(uri) {
function ensureTrailingSeparator(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);

@@ -403,3 +419,3 @@ const uriPathModule = _pathModuleFor(uri);

function trimTrailingSeparator(uri) {
function trimTrailingSeparator(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);

@@ -416,3 +432,3 @@ const uriPathModule = _pathModuleFor(uri);

function endsWithSeparator(uri) {
function endsWithSeparator(uri: NuclideUri): boolean {
_testForAtomUri(uri);

@@ -423,3 +439,3 @@ const uriPathModule = _pathModuleFor(uri);

function isAbsolute(uri) {
function isAbsolute(uri: NuclideUri): boolean {
_testForAtomUri(uri);

@@ -434,7 +450,7 @@ if (isRemote(uri)) {

function resolve(uri, ...paths) {
function resolve(uri: NuclideUri, ...paths: Array<string>): NuclideUri {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
if (isRemote(uri)) {
const { hostname, path } = parseRemoteUri(uri);
const {hostname, path} = parseRemoteUri(uri);
paths.splice(0, 0, path);

@@ -448,3 +464,3 @@ return createRemoteUri(hostname, uriPathModule.resolve.apply(null, paths));

function expandHomeDir(uri) {
function expandHomeDir(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);

@@ -460,10 +476,8 @@

// on Windows, so asking for any case is expected to work.
const { HOME, UserProfile } = process.env;
const {HOME, UserProfile} = process.env;
const homePath = _os.default.platform() === 'win32' ? UserProfile : HOME;
const isWindows = !isRemote(uri) && os.platform() === 'win32';
const homePath = isWindows ? UserProfile : HOME;
invariant(homePath != null);
if (!(homePath != null)) {
throw new Error('Invariant violation: "homePath != null"');
}
if (uri === '~') {

@@ -474,7 +488,7 @@ return homePath;

// Uris like ~abc should not be expanded
if (!uri.startsWith('~/')) {
if (!uri.startsWith('~/') && (!isWindows || !uri.startsWith('~\\'))) {
return uri;
}
return _path.default.resolve(homePath, uri.replace('~', '.'));
return pathModule.resolve(homePath, uri.replace('~', '.'));
}

@@ -488,7 +502,7 @@

*/
function splitPathList(paths) {
if (!(paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0)) {
throw new Error('Splitting remote URIs is not supported');
}
function splitPathList(paths: string): Array<NuclideUri> {
invariant(
paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0,
'Splitting remote URIs is not supported',
);
const uriPathModule = _pathModuleFor(paths);

@@ -505,3 +519,3 @@

*/
function joinPathList(paths) {
function joinPathList(paths: Array<NuclideUri>): string {
if (paths.length === 0) {

@@ -511,5 +525,6 @@ return '';

if (!paths.every(path => !isRemote(path))) {
throw new Error('Joining of remote URIs is not supported');
}
invariant(
paths.every(path => !isRemote(path)),
'Joining of remote URIs is not supported',
);

@@ -524,14 +539,12 @@ const uriPathModule = _pathModuleFor(paths[0]);

*/
function ensureLocalPrefix(uri) {
function ensureLocalPrefix(uri: NuclideUri): NuclideUri {
_testForAtomUri(uri);
const uriPathModule = _pathModuleFor(uri);
if (!!isRemote(uri)) {
throw new Error('Local prefix can not be added to a remote path');
}
invariant(!isRemote(uri), 'Local prefix can not be added to a remote path');
invariant(
!isAbsolute(uri),
'Local prefix can not be added to an absolute path',
);
if (!!isAbsolute(uri)) {
throw new Error('Local prefix can not be added to an absolute path');
}
const localPrefix = `.${uriPathModule.sep}`;

@@ -545,3 +558,3 @@ if (uri.startsWith(localPrefix)) {

function isRoot(uri) {
function isRoot(uri: NuclideUri): boolean {
_testForAtomUri(uri);

@@ -551,3 +564,3 @@ return dirname(uri) === uri;

function parsePath(uri) {
function parsePath(uri: NuclideUri): ParsedPath {
_testForAtomUri(uri);

@@ -558,7 +571,7 @@ const uriPathModule = _pathModuleFor(uri);

function pathSeparatorFor(uri) {
function pathSeparatorFor(uri: NuclideUri): string {
return _pathModuleFor(uri).sep;
}
function split(uri) {
function split(uri: NuclideUri): Array<string> {
const parts = [];

@@ -582,17 +595,20 @@ let current = uri;

function _pathModuleFor(uri) {
if (uri.startsWith(_path.default.posix.sep)) {
return _path.default.posix;
function _pathModuleFor(uri: NuclideUri): typeof pathModule {
if (uri.startsWith(pathModule.posix.sep)) {
return pathModule.posix;
}
if (uri.indexOf('://') > -1) {
return _path.default.posix;
return pathModule.posix;
}
if (uri[1] === ':' && uri[2] === _path.default.win32.sep) {
return _path.default.win32;
if (uri[1] === ':' && uri[2] === pathModule.win32.sep) {
return pathModule.win32;
}
if (uri.split(_path.default.win32.sep).length > uri.split(_path.default.posix.sep).length) {
return _path.default.win32;
if (
uri.split(pathModule.win32.sep).length >
uri.split(pathModule.posix.sep).length
) {
return pathModule.win32;
} else {
return _path.default.posix;
return pathModule.posix;
}

@@ -606,7 +622,7 @@ }

*/
function _escapeSpecialCharacters(uri) {
function _escapeSpecialCharacters(uri: NuclideUri): NuclideUri {
return uri.replace(/%/g, '%25').replace(/\\/g, '%5C');
}
function _testForAtomUri(uri) {
function _testForAtomUri(uri: ?NuclideUri): void {
if (uri != null && isAtomUri(uri)) {

@@ -621,30 +637,20 @@ throw new Error(`Path operation invoked on Atom URI ${uri}`);

// is ignored.
function validate(uri, mustBeRemote) {
function validate(uri: NuclideUri, mustBeRemote?: boolean): void {
// Be a little extra paranoid to catch places where the type system may be weak.
if (!(uri != null)) {
throw new Error('Unexpected null NuclideUri');
}
invariant(uri != null, 'Unexpected null NuclideUri');
invariant(
typeof uri === 'string',
`Unexpected NuclideUri type: ${String(uri)}`,
);
if (!(typeof uri === 'string')) {
throw new Error(`Unexpected NuclideUri type: ${String(uri)}`);
}
if (isRemote(uri)) {
parse(uri);
if (!(mustBeRemote !== false)) {
throw new Error('Expected remote NuclideUri');
}
invariant(mustBeRemote !== false, 'Expected remote NuclideUri');
} else {
if (!(uri !== '')) {
throw new Error('NuclideUri must contain a non-empty path');
}
if (!(mustBeRemote !== true)) {
throw new Error('Expected local NuclideUri');
}
invariant(uri !== '', 'NuclideUri must contain a non-empty path');
invariant(mustBeRemote !== true, 'Expected local NuclideUri');
}
}
exports.default = {
export default {
basename,

@@ -688,6 +694,7 @@ dirname,

pathSeparatorFor,
NUCLIDE_URI_TYPE_NAME
NUCLIDE_URI_TYPE_NAME,
};
const __TEST__ = exports.__TEST__ = {
_pathModuleFor
};
export const __TEST__ = {
_pathModuleFor,
};

@@ -1,35 +0,19 @@

'use strict';
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
* @flow
* @format
*/
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.nextAnimationFrame = exports.nextTick = undefined;
exports.splitStream = splitStream;
exports.bufferUntil = bufferUntil;
exports.cacheWhileSubscribed = cacheWhileSubscribed;
exports.diffSets = diffSets;
exports.reconcileSetDiffs = reconcileSetDiffs;
exports.reconcileSets = reconcileSets;
exports.toggle = toggle;
exports.compact = compact;
exports.takeWhileInclusive = takeWhileInclusive;
exports.concatLatest = concatLatest;
exports.throttle = throttle;
/* global requestAnimationFrame, cancelAnimationFrame */
var _UniversalDisposable;
import UniversalDisposable from './UniversalDisposable';
import invariant from 'assert';
import {setDifference} from './collection';
import {Observable, ReplaySubject} from 'rxjs';
function _load_UniversalDisposable() {
return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));
}
var _collection;
function _load_collection() {
return _collection = require('./collection');
}
var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**

@@ -41,5 +25,5 @@ * Splits a stream of strings on newlines.

*/
function splitStream(input) {
return _rxjsBundlesRxMinJs.Observable.create(observer => {
let current = '';
export function splitStream(input: Observable<string>): Observable<string> {
return Observable.create(observer => {
let current: string = '';

@@ -53,13 +37,17 @@ function onEnd() {

return input.subscribe(value => {
const lines = (current + value).split('\n');
current = lines.pop();
lines.forEach(line => observer.next(line + '\n'));
}, error => {
onEnd();
observer.error(error);
}, () => {
onEnd();
observer.complete();
});
return input.subscribe(
value => {
const lines = (current + value).split('\n');
current = lines.pop();
lines.forEach(line => observer.next(line + '\n'));
},
error => {
onEnd();
observer.error(error);
},
() => {
onEnd();
observer.complete();
},
);
});

@@ -77,17 +65,7 @@ }

*/
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
*
* @format
*/
/* global requestAnimationFrame, cancelAnimationFrame */
function bufferUntil(stream, condition) {
return _rxjsBundlesRxMinJs.Observable.create(observer => {
export function bufferUntil<T>(
stream: Observable<T>,
condition: (item: T, buffer: Array<T>) => boolean,
): Observable<Array<T>> {
return Observable.create(observer => {
let buffer = null;

@@ -100,17 +78,21 @@ const flush = () => {

};
return stream.subscribe(x => {
if (buffer == null) {
buffer = [];
}
buffer.push(x);
if (condition(x, buffer)) {
return stream.subscribe(
x => {
if (buffer == null) {
buffer = [];
}
buffer.push(x);
if (condition(x, buffer)) {
flush();
}
},
err => {
flush();
}
}, err => {
flush();
observer.error(err);
}, () => {
flush();
observer.complete();
});
observer.error(err);
},
() => {
flush();
observer.complete();
},
);
});

@@ -127,6 +109,11 @@ }

*/
function cacheWhileSubscribed(input) {
return input.multicast(() => new _rxjsBundlesRxMinJs.ReplaySubject(1)).refCount();
export function cacheWhileSubscribed<T>(input: Observable<T>): Observable<T> {
return input.multicast(() => new ReplaySubject(1)).refCount();
}
type Diff<T> = {
added: Set<T>,
removed: Set<T>,
};
/**

@@ -136,8 +123,16 @@ * Given a stream of sets, return a stream of diffs.

*/
function diffSets(sets, hash) {
return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of(new Set()), // Always start with no items with an empty set
sets).pairwise().map(([previous, next]) => ({
added: (0, (_collection || _load_collection()).setDifference)(next, previous, hash),
removed: (0, (_collection || _load_collection()).setDifference)(previous, next, hash)
})).filter(diff => diff.added.size > 0 || diff.removed.size > 0);
export function diffSets<T>(
sets: Observable<Set<T>>,
hash?: (v: T) => any,
): Observable<Diff<T>> {
return Observable.concat(
Observable.of(new Set()), // Always start with no items with an empty set
sets,
)
.pairwise()
.map(([previous, next]) => ({
added: setDifference(next, previous, hash),
removed: setDifference(previous, next, hash),
}))
.filter(diff => diff.added.size > 0 || diff.removed.size > 0);
}

@@ -149,3 +144,7 @@

*/
function reconcileSetDiffs(diffs, addAction, hash_) {
export function reconcileSetDiffs<T>(
diffs: Observable<Diff<T>>,
addAction: (addedItem: T) => IDisposable,
hash_?: (v: T) => any,
): IDisposable {
const hash = hash_ || (x => x);

@@ -155,7 +154,3 @@ const itemsToDisposables = new Map();

const disposable = itemsToDisposables.get(hash(item));
if (!(disposable != null)) {
throw new Error('Invariant violation: "disposable != null"');
}
invariant(disposable != null);
disposable.dispose();

@@ -171,11 +166,14 @@ itemsToDisposables.delete(item);

return new (_UniversalDisposable || _load_UniversalDisposable()).default(diffs.subscribe(diff => {
// For every item that got added, perform the add action.
diff.added.forEach(item => {
itemsToDisposables.set(hash(item), addAction(item));
});
return new UniversalDisposable(
diffs.subscribe(diff => {
// For every item that got added, perform the add action.
diff.added.forEach(item => {
itemsToDisposables.set(hash(item), addAction(item));
});
// "Undo" the add action for each item that got removed.
diff.removed.forEach(disposeItem);
}), disposeAll);
// "Undo" the add action for each item that got removed.
diff.removed.forEach(disposeItem);
}),
disposeAll,
);
}

@@ -211,3 +209,7 @@

*/
function reconcileSets(sets, addAction, hash) {
export function reconcileSets<T>(
sets: Observable<Set<T>>,
addAction: (addedItem: T) => IDisposable,
hash?: (v: T) => any,
): IDisposable {
const diffs = diffSets(sets, hash);

@@ -217,9 +219,14 @@ return reconcileSetDiffs(diffs, addAction, hash);

function toggle(source, toggler) {
return toggler.distinctUntilChanged().switchMap(enabled => enabled ? source : _rxjsBundlesRxMinJs.Observable.empty());
export function toggle<T>(
source: Observable<T>,
toggler: Observable<boolean>,
): Observable<T> {
return toggler
.distinctUntilChanged()
.switchMap(enabled => (enabled ? source : Observable.empty()));
}
function compact(source) {
export function compact<T>(source: Observable<?T>): Observable<T> {
// Flow does not understand the semantics of `filter`
return source.filter(x => x != null);
return (source.filter(x => x != null): any);
}

@@ -230,13 +237,22 @@

*/
function takeWhileInclusive(source, predicate) {
return _rxjsBundlesRxMinJs.Observable.create(observer => source.subscribe(x => {
observer.next(x);
if (!predicate(x)) {
observer.complete();
}
}, err => {
observer.error(err);
}, () => {
observer.complete();
}));
export function takeWhileInclusive<T>(
source: Observable<T>,
predicate: (value: T) => boolean,
): Observable<T> {
return Observable.create(observer =>
source.subscribe(
x => {
observer.next(x);
if (!predicate(x)) {
observer.complete();
}
},
err => {
observer.error(err);
},
() => {
observer.complete();
},
),
);
}

@@ -246,15 +262,36 @@

// Observables who have not emitted a value yet are treated as empty.
function concatLatest(...observables) {
export function concatLatest<T>(
...observables: Array<Observable<Array<T>>>
): Observable<Array<T>> {
// First, tag all input observables with their index.
const tagged = observables.map((observable, index) => observable.map(list => [list, index]));
return _rxjsBundlesRxMinJs.Observable.merge(...tagged).scan((accumulator, [list, index]) => {
accumulator[index] = list;
return accumulator;
}, observables.map(x => [])).map(accumulator => [].concat(...accumulator));
// Flow errors with ambiguity without the explicit annotation.
const tagged: Array<
Observable<[Array<T>, number]>,
> = observables.map((observable, index) =>
observable.map(list => [list, index]),
);
return Observable.merge(...tagged)
.scan((accumulator, [list, index]) => {
accumulator[index] = list;
return accumulator;
}, observables.map(x => []))
.map(accumulator => [].concat(...accumulator));
}
type ThrottleOptions = {
// Should the first element be emitted immeditately? Defaults to true.
leading?: boolean,
};
/**
* A more sensible alternative to RxJS's throttle/audit/sample operators.
*/
function throttle(source, duration, options_) {
export function throttle<T>(
source: Observable<T>,
duration:
| number
| Observable<any>
| ((value: T) => Observable<any> | Promise<any>),
options_: ?ThrottleOptions,
): Observable<T> {
const options = options_ || {};

@@ -279,10 +316,16 @@ const leading = options.leading !== false;

return _rxjsBundlesRxMinJs.Observable.create(observer => {
return Observable.create(observer => {
const connectableSource = source.publish();
const throttled = _rxjsBundlesRxMinJs.Observable.merge(connectableSource.take(1), audit(connectableSource.skip(1)));
return new (_UniversalDisposable || _load_UniversalDisposable()).default(throttled.subscribe(observer), connectableSource.connect());
const throttled = Observable.merge(
connectableSource.take(1),
audit(connectableSource.skip(1)),
);
return new UniversalDisposable(
throttled.subscribe(observer),
connectableSource.connect(),
);
});
}
const nextTick = exports.nextTick = _rxjsBundlesRxMinJs.Observable.create(observer => {
export const nextTick = Observable.create(observer => {
process.nextTick(() => {

@@ -294,3 +337,3 @@ observer.next();

const nextAnimationFrame = exports.nextAnimationFrame = _rxjsBundlesRxMinJs.Observable.create(observer => {
export const nextAnimationFrame = Observable.create(observer => {
if (typeof requestAnimationFrame === 'undefined') {

@@ -306,2 +349,2 @@ throw new Error('This util can only be used in Atom');

};
});
});
{
"name": "nuclide-commons",
"version": "0.1.0",
"version": "0.1.1",
"description": "Common Nuclide node modules.",

@@ -9,3 +9,3 @@ "license": "SEE LICENSE IN LICENSE",

"scripts": {
"prepublishOnly": "../../scripts/release-transpile.js --overwrite .",
"prepublishOnly": "../../scripts/modules-prepublish.sh",
"test": "node ../../pkg/nuclide-jasmine/bin/jasmine-node-transpiled spec"

@@ -16,7 +16,12 @@ },

"event-kit": "2.2.0",
"fs-plus": "2.9.3",
"glob": "7.1.1",
"idx": "1.2.0",
"lru-cache": "4.0.2",
"mkdirp": "0.5.1",
"rimraf": "2.5.4",
"rxjs": "5.3.1",
"shell-quote": "1.6.1"
},
"devDependencies": {
"shell-quote": "1.6.1",
"temp": "0.8.3"
}
}

@@ -1,252 +0,24 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.asyncSome = exports.asyncObjFilter = exports.asyncFilter = exports.Deferred = exports.retryLimit = exports.triggerAfterWait = exports.RequestSerializer = undefined;
var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));
/**
* Executes a provided callback only if a promise takes longer than
* `milliSeconds` milliseconds to resolve.
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* @param `promise` the promise to wait on.
* @param `milliSeconds` max amount of time that `promise` can take to resolve
* before timeoutFn is fired.
* @param `timeoutFn` the function to execute when a promise takes longer than
* `milliSeconds` ms to resolve.
* @param `cleanupFn` the cleanup function to execute after the promise resolves.
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
* @flow
* @format
*/
let triggerAfterWait = exports.triggerAfterWait = (() => {
var _ref = (0, _asyncToGenerator.default)(function* (promise, milliSeconds, timeoutFn, cleanupFn) {
const timeout = setTimeout(timeoutFn, milliSeconds);
try {
return yield promise;
} finally {
clearTimeout(timeout);
if (cleanupFn) {
cleanupFn();
}
}
});
return function triggerAfterWait(_x, _x2, _x3, _x4) {
return _ref.apply(this, arguments);
};
})();
import invariant from 'assert';
/**
* Returns a Promise that resolves to the same value as the given promise, or rejects if it takes
* longer than `milliseconds` milliseconds
*/
/**
* Call an async function repeatedly with a maximum number of trials limit,
* until a valid result that's defined by a validation function.
* A failed call can result from an async thrown exception, or invalid result.
*
* @param `retryFunction` the async logic that's wanted to be retried.
* @param `validationFunction` the validation function that decides whether a response is valid.
* @param `maximumTries` the number of times the `retryFunction` can fail to get a valid
* response before the `retryLimit` is terminated reporting an error.
* @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted.
*
* If an exception is encountered on the last trial, the exception is thrown.
* If no valid response is found, an exception is thrown.
*/
let retryLimit = exports.retryLimit = (() => {
var _ref2 = (0, _asyncToGenerator.default)(function* (retryFunction, validationFunction, maximumTries, retryIntervalMs = 0) {
let result = null;
let tries = 0;
let lastError = null;
while (tries === 0 || tries < maximumTries) {
try {
// eslint-disable-next-line no-await-in-loop
result = yield retryFunction();
lastError = null;
if (validationFunction(result)) {
return result;
}
} catch (error) {
lastError = error;
result = null;
}
if (++tries < maximumTries && retryIntervalMs !== 0) {
// eslint-disable-next-line no-await-in-loop
yield sleep(retryIntervalMs);
}
type RunReturn<T> =
| {
status: 'success',
result: T,
}
if (lastError != null) {
throw lastError;
} else if (tries === maximumTries) {
throw new Error('No valid response found!');
} else {
return result;
}
});
| {
status: 'outdated',
};
return function retryLimit(_x5, _x6, _x7) {
return _ref2.apply(this, arguments);
};
})();
/**
* Limits async function execution parallelism to only one at a time.
* Hence, if a call is already running, it will wait for it to finish,
* then start the next async execution, but if called again while not finished,
* it will return the scheduled execution promise.
*
* Sample Usage:
* ```
* let i = 1;
* const oneExecAtATime = oneParallelAsyncCall(() => {
* return next Promise((resolve, reject) => {
* setTimeout(200, () => resolve(i++));
* });
* });
*
* const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms.
* const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms.
* const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms.
* ```
*/
/**
* `filter` Promise utility that allows filtering an array with an async Promise function.
* It's an alternative to `Array.prototype.filter` that accepts an async function.
* You can optionally configure a limit to set the maximum number of async operations at a time.
*
* Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to
* `filter`, so, we replace the old `filter` code:
* var existingFilePaths = [];
* await Promise.all(filePaths.map(async (filePath) => {
* if (await fsPromise.exists(filePath)) {
* existingFilePaths.push(filePath);
* }
* }));
* with limit 5 parallel filesystem operations at a time:
* var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5);
*
* @param array the array of items for `filter`ing.
* @param filterFunction the async `filter` function that returns a Promise that resolves to a
* boolean.
* @param limit the configurable number of parallel async operations.
*/
let asyncFilter = exports.asyncFilter = (() => {
var _ref5 = (0, _asyncToGenerator.default)(function* (array, filterFunction, limit) {
const filteredList = [];
yield asyncLimit(array, limit || array.length, (() => {
var _ref6 = (0, _asyncToGenerator.default)(function* (item) {
if (yield filterFunction(item)) {
filteredList.push(item);
}
});
return function (_x12) {
return _ref6.apply(this, arguments);
};
})());
return filteredList;
});
return function asyncFilter(_x9, _x10, _x11) {
return _ref5.apply(this, arguments);
};
})();
let asyncObjFilter = exports.asyncObjFilter = (() => {
var _ref7 = (0, _asyncToGenerator.default)(function* (obj, filterFunction, limit) {
const keys = Object.keys(obj);
const filteredObj = {};
yield asyncLimit(keys, limit || keys.length, (() => {
var _ref8 = (0, _asyncToGenerator.default)(function* (key) {
const item = obj[key];
if (yield filterFunction(item, key)) {
filteredObj[key] = item;
}
});
return function (_x16) {
return _ref8.apply(this, arguments);
};
})());
return filteredObj;
});
return function asyncObjFilter(_x13, _x14, _x15) {
return _ref7.apply(this, arguments);
};
})();
/**
* `some` Promise utility that allows `some` an array with an async Promise some function.
* It's an alternative to `Array.prototype.some` that accepts an async some function.
* You can optionally configure a limit to set the maximum number of async operations at a time.
*
* Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to
* `some`, so, we replace the old `some` code:
* var someFileExist = false;
* await Promise.all(filePaths.map(async (filePath) => {
* if (await fsPromise.exists(filePath)) {
* someFileExist = true;
* }
* }));
* with limit 5 parallel filesystem operations at a time:
* var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5);
*
* @param array the array of items for `some`ing.
* @param someFunction the async `some` function that returns a Promise that resolves to a
* boolean.
* @param limit the configurable number of parallel async operations.
*/
let asyncSome = exports.asyncSome = (() => {
var _ref9 = (0, _asyncToGenerator.default)(function* (array, someFunction, limit) {
let resolved = false;
yield asyncLimit(array, limit || array.length, (() => {
var _ref10 = (0, _asyncToGenerator.default)(function* (item) {
if (resolved) {
// We don't need to call the someFunction anymore or wait any longer.
return;
}
if (yield someFunction(item)) {
resolved = true;
}
});
return function (_x20) {
return _ref10.apply(this, arguments);
};
})());
return resolved;
});
return function asyncSome(_x17, _x18, _x19) {
return _ref9.apply(this, arguments);
};
})();
/**
* Check if an object is Promise by testing if it has a `then` function property.
*/
exports.sleep = sleep;
exports.nextTick = nextTick;
exports.timeoutPromise = timeoutPromise;
exports.serializeAsyncCall = serializeAsyncCall;
exports.asyncFind = asyncFind;
exports.denodeify = denodeify;
exports.asyncLimit = asyncLimit;
exports.isPromise = isPromise;
exports.lastly = lastly;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Allows a caller to ensure that the results it receives from consecutive

@@ -276,15 +48,8 @@ * promise resolutions are never outdated. Usage:

*/
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
*
* @format
*/
export class RequestSerializer<T> {
_lastDispatchedOp: number;
_lastFinishedOp: number;
_latestPromise: Promise<T>;
_waitResolve: Function;
class RequestSerializer {
constructor() {

@@ -298,23 +63,19 @@ this._lastDispatchedOp = 0;

run(promise) {
var _this = this;
return (0, _asyncToGenerator.default)(function* () {
const thisOp = _this._lastDispatchedOp + 1;
_this._lastDispatchedOp = thisOp;
_this._latestPromise = promise;
_this._waitResolve();
const result = yield promise;
if (_this._lastFinishedOp < thisOp) {
_this._lastFinishedOp = thisOp;
return {
status: 'success',
result
};
} else {
return {
status: 'outdated'
};
}
})();
async run(promise: Promise<T>): Promise<RunReturn<T>> {
const thisOp = this._lastDispatchedOp + 1;
this._lastDispatchedOp = thisOp;
this._latestPromise = promise;
this._waitResolve();
const result = await promise;
if (this._lastFinishedOp < thisOp) {
this._lastFinishedOp = thisOp;
return {
status: 'success',
result,
};
} else {
return {
status: 'outdated',
};
}
}

@@ -326,22 +87,18 @@

*/
waitForLatestResult() {
var _this2 = this;
return (0, _asyncToGenerator.default)(function* () {
let lastPromise = null;
let result = null;
while (lastPromise !== _this2._latestPromise) {
lastPromise = _this2._latestPromise;
// Wait for the current last know promise to resolve, or a next run have started.
// eslint-disable-next-line no-await-in-loop
result = yield new Promise(function (resolve, reject) {
_this2._waitResolve = resolve;
_this2._latestPromise.then(resolve);
});
}
return result;
})();
async waitForLatestResult(): Promise<T> {
let lastPromise = null;
let result: any = null;
while (lastPromise !== this._latestPromise) {
lastPromise = this._latestPromise;
// Wait for the current last know promise to resolve, or a next run have started.
// eslint-disable-next-line no-await-in-loop
result = await new Promise((resolve, reject) => {
this._waitResolve = resolve;
this._latestPromise.then(resolve);
});
}
return (result: T);
}
isRunInProgress() {
isRunInProgress(): boolean {
return this._lastDispatchedOp > this._lastFinishedOp;

@@ -351,9 +108,8 @@ }

exports.RequestSerializer = RequestSerializer; /*
* Returns a promise that will resolve after `milliSeconds` milli seconds.
* this can be used to pause execution asynchronously.
* e.g. await sleep(1000), pauses the async flow execution for 1 second.
*/
function sleep(milliSeconds) {
/*
* Returns a promise that will resolve after `milliSeconds` milli seconds.
* this can be used to pause execution asynchronously.
* e.g. await sleep(1000), pauses the async flow execution for 1 second.
*/
export function sleep(milliSeconds: number): Promise<void> {
return new Promise(resolve => {

@@ -364,7 +120,44 @@ setTimeout(resolve, milliSeconds);

function nextTick() {
export function nextTick(): Promise<void> {
return new Promise(resolve => {
process.nextTick(resolve);
});
}function timeoutPromise(promise, milliseconds) {
}
/**
* Executes a provided callback only if a promise takes longer than
* `milliSeconds` milliseconds to resolve.
*
* @param `promise` the promise to wait on.
* @param `milliSeconds` max amount of time that `promise` can take to resolve
* before timeoutFn is fired.
* @param `timeoutFn` the function to execute when a promise takes longer than
* `milliSeconds` ms to resolve.
* @param `cleanupFn` the cleanup function to execute after the promise resolves.
*/
export async function triggerAfterWait<T>(
promise: Promise<T>,
milliSeconds: number,
timeoutFn: () => void,
cleanupFn?: () => void,
): Promise<T> {
const timeout = setTimeout(timeoutFn, milliSeconds);
try {
return await promise;
} finally {
clearTimeout(timeout);
if (cleanupFn) {
cleanupFn();
}
}
}
/**
* Returns a Promise that resolves to the same value as the given promise, or rejects if it takes
* longer than `milliseconds` milliseconds
*/
export function timeoutPromise<T>(
promise: Promise<T>,
milliseconds: number,
): Promise<T> {
return new Promise((resolve, reject) => {

@@ -375,15 +168,91 @@ let timeout = setTimeout(() => {

}, milliseconds);
promise.then(value => {
if (timeout != null) {
clearTimeout(timeout);
promise
.then(value => {
if (timeout != null) {
clearTimeout(timeout);
}
resolve(value);
})
.catch(value => {
if (timeout != null) {
clearTimeout(timeout);
}
reject(value);
});
});
}
/**
* Call an async function repeatedly with a maximum number of trials limit,
* until a valid result that's defined by a validation function.
* A failed call can result from an async thrown exception, or invalid result.
*
* @param `retryFunction` the async logic that's wanted to be retried.
* @param `validationFunction` the validation function that decides whether a response is valid.
* @param `maximumTries` the number of times the `retryFunction` can fail to get a valid
* response before the `retryLimit` is terminated reporting an error.
* @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted.
*
* If an exception is encountered on the last trial, the exception is thrown.
* If no valid response is found, an exception is thrown.
*/
export async function retryLimit<T>(
retryFunction: () => Promise<T>,
validationFunction: (result: T) => boolean,
maximumTries: number,
retryIntervalMs?: number = 0,
): Promise<T> {
let result = null;
let tries = 0;
let lastError = null;
while (tries === 0 || tries < maximumTries) {
try {
// eslint-disable-next-line no-await-in-loop
result = await retryFunction();
lastError = null;
if (validationFunction(result)) {
return result;
}
resolve(value);
}).catch(value => {
if (timeout != null) {
clearTimeout(timeout);
}
reject(value);
});
});
}function serializeAsyncCall(asyncFun) {
} catch (error) {
lastError = error;
result = null;
}
if (++tries < maximumTries && retryIntervalMs !== 0) {
// eslint-disable-next-line no-await-in-loop
await sleep(retryIntervalMs);
}
}
if (lastError != null) {
throw lastError;
} else if (tries === maximumTries) {
throw new Error('No valid response found!');
} else {
return ((result: any): T);
}
}
/**
* Limits async function execution parallelism to only one at a time.
* Hence, if a call is already running, it will wait for it to finish,
* then start the next async execution, but if called again while not finished,
* it will return the scheduled execution promise.
*
* Sample Usage:
* ```
* let i = 1;
* const oneExecAtATime = oneParallelAsyncCall(() => {
* return next Promise((resolve, reject) => {
* setTimeout(200, () => resolve(i++));
* });
* });
*
* const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms.
* const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms.
* const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms.
* ```
*/
export function serializeAsyncCall<T>(
asyncFun: () => Promise<T>,
): () => Promise<T> {
let scheduledCall = null;

@@ -393,3 +262,6 @@ let pendingCall = null;

const resultPromise = asyncFun();
pendingCall = resultPromise.then(() => pendingCall = null, () => pendingCall = null);
pendingCall = resultPromise.then(
() => (pendingCall = null),
() => (pendingCall = null),
);
return resultPromise;

@@ -403,6 +275,3 @@ };

if (scheduledCall == null) {
if (!pendingCall) {
throw new Error('pendingCall must not be null!');
}
invariant(pendingCall, 'pendingCall must not be null!');
scheduledCall = pendingCall.then(callNext, callNext);

@@ -428,3 +297,6 @@ }

*/
class Deferred {
export class Deferred<T> {
promise: Promise<T>;
resolve: (value: T) => void;
reject: (error: Error) => void;

@@ -439,22 +311,25 @@ constructor() {

exports.Deferred = Deferred; /**
* Returns a value derived asynchronously from an element in the items array.
* The test function is applied sequentially to each element in items until
* one returns a Promise that resolves to a non-null value. When this happens,
* the Promise returned by this method will resolve to that non-null value. If
* no such Promise is produced, then the Promise returned by this function
* will resolve to null.
*
* @param items Array of elements that will be passed to test, one at a time.
* @param test Will be called with each item and must return either:
* (1) A "thenable" (i.e, a Promise or promise-like object) that resolves
* to a derived value (that will be returned) or null.
* (2) null.
* In both cases where null is returned, test will be applied to the next
* item in the array.
* @param thisArg Receiver that will be used when test is called.
* @return Promise that resolves to an asynchronously derived value or null.
*/
function asyncFind(items_, test, thisArg) {
/**
* Returns a value derived asynchronously from an element in the items array.
* The test function is applied sequentially to each element in items until
* one returns a Promise that resolves to a non-null value. When this happens,
* the Promise returned by this method will resolve to that non-null value. If
* no such Promise is produced, then the Promise returned by this function
* will resolve to null.
*
* @param items Array of elements that will be passed to test, one at a time.
* @param test Will be called with each item and must return either:
* (1) A "thenable" (i.e, a Promise or promise-like object) that resolves
* to a derived value (that will be returned) or null.
* (2) null.
* In both cases where null is returned, test will be applied to the next
* item in the array.
* @param thisArg Receiver that will be used when test is called.
* @return Promise that resolves to an asynchronously derived value or null.
*/
export function asyncFind<T, U>(
items_: Array<T>,
test: (t: T) => ?Promise<?U>,
thisArg?: mixed,
): Promise<?U> {
let items = items_;

@@ -467,23 +342,17 @@ return new Promise((resolve, reject) => {

const next = (() => {
var _ref3 = (0, _asyncToGenerator.default)(function* (index) {
if (index === numItems) {
resolve(null);
return;
}
const next = async function(index) {
if (index === numItems) {
resolve(null);
return;
}
const item = items[index];
const result = yield test.call(thisArg, item);
if (result !== null) {
resolve(result);
} else {
next(index + 1);
}
});
const item = items[index];
const result = await test.call(thisArg, item);
if (result !== null) {
resolve(result);
} else {
next(index + 1);
}
};
return function next(_x8) {
return _ref3.apply(this, arguments);
};
})();
next(0);

@@ -493,4 +362,6 @@ });

function denodeify(f) {
return function (...args) {
export function denodeify(
f: (...args: Array<any>) => any,
): (...args: Array<any>) => Promise<any> {
return function(...args: Array<any>) {
return new Promise((resolve, reject) => {

@@ -525,4 +396,8 @@ function callback(error, result) {

*/
function asyncLimit(array, limit, mappingFunction) {
const result = new Array(array.length);
export function asyncLimit<T, V>(
array: Array<T>,
limit: number,
mappingFunction: (item: T) => Promise<V>,
): Promise<Array<V>> {
const result: Array<V> = new Array(array.length);
let parallelPromises = 0;

@@ -534,26 +409,20 @@ let index = 0;

return new Promise((resolve, reject) => {
const runPromise = (() => {
var _ref4 = (0, _asyncToGenerator.default)(function* () {
if (index === array.length) {
if (parallelPromises === 0) {
resolve(result);
}
return;
const runPromise = async () => {
if (index === array.length) {
if (parallelPromises === 0) {
resolve(result);
}
++parallelPromises;
const i = index++;
try {
result[i] = yield mappingFunction(array[i]);
} catch (e) {
reject(e);
}
--parallelPromises;
runPromise();
});
return;
}
++parallelPromises;
const i = index++;
try {
result[i] = await mappingFunction(array[i]);
} catch (e) {
reject(e);
}
--parallelPromises;
runPromise();
};
return function runPromise() {
return _ref4.apply(this, arguments);
};
})();
while (parallelLimit--) {

@@ -563,16 +432,121 @@ runPromise();

});
}function isPromise(object) {
return Boolean(object) && typeof object === 'object' && typeof object.then === 'function';
}
/**
* `filter` Promise utility that allows filtering an array with an async Promise function.
* It's an alternative to `Array.prototype.filter` that accepts an async function.
* You can optionally configure a limit to set the maximum number of async operations at a time.
*
* Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to
* `filter`, so, we replace the old `filter` code:
* var existingFilePaths = [];
* await Promise.all(filePaths.map(async (filePath) => {
* if (await fsPromise.exists(filePath)) {
* existingFilePaths.push(filePath);
* }
* }));
* with limit 5 parallel filesystem operations at a time:
* var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5);
*
* @param array the array of items for `filter`ing.
* @param filterFunction the async `filter` function that returns a Promise that resolves to a
* boolean.
* @param limit the configurable number of parallel async operations.
*/
export async function asyncFilter<T>(
array: Array<T>,
filterFunction: (item: T) => Promise<boolean>,
limit?: number,
): Promise<Array<T>> {
const filteredList = [];
await asyncLimit(array, limit || array.length, async (item: T) => {
if (await filterFunction(item)) {
filteredList.push(item);
}
});
return filteredList;
}
export async function asyncObjFilter<T>(
obj: {[key: string]: T},
filterFunction: (item: T, key: string) => Promise<boolean>,
limit?: number,
): Promise<{[key: string]: T}> {
const keys = Object.keys(obj);
const filteredObj = {};
await asyncLimit(keys, limit || keys.length, async (key: string) => {
const item = obj[key];
if (await filterFunction(item, key)) {
filteredObj[key] = item;
}
});
return filteredObj;
}
/**
* `some` Promise utility that allows `some` an array with an async Promise some function.
* It's an alternative to `Array.prototype.some` that accepts an async some function.
* You can optionally configure a limit to set the maximum number of async operations at a time.
*
* Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to
* `some`, so, we replace the old `some` code:
* var someFileExist = false;
* await Promise.all(filePaths.map(async (filePath) => {
* if (await fsPromise.exists(filePath)) {
* someFileExist = true;
* }
* }));
* with limit 5 parallel filesystem operations at a time:
* var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5);
*
* @param array the array of items for `some`ing.
* @param someFunction the async `some` function that returns a Promise that resolves to a
* boolean.
* @param limit the configurable number of parallel async operations.
*/
export async function asyncSome<T>(
array: Array<T>,
someFunction: (item: T) => Promise<boolean>,
limit?: number,
): Promise<boolean> {
let resolved = false;
await asyncLimit(array, limit || array.length, async (item: T) => {
if (resolved) {
// We don't need to call the someFunction anymore or wait any longer.
return;
}
if (await someFunction(item)) {
resolved = true;
}
});
return resolved;
}
/**
* Check if an object is Promise by testing if it has a `then` function property.
*/
export function isPromise(object: any): boolean {
return (
Boolean(object) &&
typeof object === 'object' &&
typeof object.then === 'function'
);
}
/**
* We can't name a function 'finally', so use lastly instead.
* fn() will be executed (and completed) after the provided promise resolves/rejects.
*/
function lastly(promise, fn) {
return promise.then(ret => {
return Promise.resolve(fn()).then(() => ret);
}, err => {
return Promise.resolve(fn()).then(() => Promise.reject(err));
});
}
export function lastly<T>(
promise: Promise<T>,
fn: () => Promise<mixed> | mixed,
): Promise<T> {
return promise.then(
ret => {
return Promise.resolve(fn()).then(() => ret);
},
err => {
return Promise.resolve(fn()).then(() => Promise.reject(err));
},
);
}

@@ -1,8 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wordAtPositionFromBuffer = wordAtPositionFromBuffer;
exports.matchRegexEndingAt = matchRegexEndingAt;
/**

@@ -15,8 +8,12 @@ * Copyright (c) 2015-present, Facebook, Inc.

*
*
* @flow
* @format
*/
function wordAtPositionFromBuffer(buffer, position, wordRegex) {
const { row, column } = position;
export function wordAtPositionFromBuffer(
buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer,
position: atom$PointObject,
wordRegex: RegExp,
): ?{wordMatch: Array<string>, range: atom$Range} {
const {row, column} = position;
const rowRange = buffer.rangeForRow(row);

@@ -26,4 +23,7 @@ let matchData;

buffer.scanInRange(wordRegex, rowRange, data => {
const { range } = data;
if (range.start.isLessThanOrEqual(position) && range.end.isGreaterThan(position)) {
const {range} = data;
if (
range.start.isLessThanOrEqual(position) &&
range.end.isGreaterThan(position)
) {
matchData = data;

@@ -39,3 +39,3 @@ }

wordMatch: matchData.match,
range: matchData.range
range: matchData.range,
};

@@ -50,6 +50,10 @@ } else {

// Useful for autocomplete.
function matchRegexEndingAt(buffer, endPosition, regex) {
export function matchRegexEndingAt(
buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer,
endPosition: atom$PointObject,
regex: RegExp,
): ?string {
const line = buffer.getTextInRange([[endPosition.row, 0], endPosition]);
const match = regex.exec(line);
return match == null ? null : match[0];
}
}

@@ -1,25 +0,1 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.URL_REGEX = undefined;
exports.stringifyError = stringifyError;
exports.maybeToString = maybeToString;
exports.relativeDate = relativeDate;
exports.countOccurrences = countOccurrences;
exports.shellParse = shellParse;
exports.removeCommonPrefix = removeCommonPrefix;
exports.removeCommonSuffix = removeCommonSuffix;
exports.shorten = shorten;
exports.splitOnce = splitOnce;
exports.indent = indent;
exports.pluralize = pluralize;
var _shellQuote;
function _load_shellQuote() {
return _shellQuote = require('shell-quote');
}
/**

@@ -32,7 +8,10 @@ * Copyright (c) 2015-present, Facebook, Inc.

*
*
* @flow
* @format
*/
function stringifyError(error) {
import invariant from 'assert';
import {parse} from 'shell-quote';
export function stringifyError(error: Error): string {
return `name: ${error.name}, message: ${error.message}, stack: ${error.stack}.`;

@@ -43,3 +22,3 @@ }

// make it explicit.
function maybeToString(str) {
export function maybeToString(str: ?string): string {
// We don't want to encourage the use of this function directly because it coerces anything to a

@@ -63,7 +42,39 @@ // string. We get stricter typechecking by using maybeToString, so it should generally be

const shortFormats = [[0.7 * MINUTE, 'now'], [1.5 * MINUTE, '1m'], [60 * MINUTE, 'm', MINUTE], [1.5 * HOUR, '1h'], [DAY, 'h', HOUR], [2 * DAY, '1d'], [7 * DAY, 'd', DAY], [1.5 * WEEK, '1w'], [MONTH, 'w', WEEK], [1.5 * MONTH, '1mo'], [YEAR, 'mo', MONTH], [1.5 * YEAR, '1y'], [Number.MAX_VALUE, 'y', YEAR]];
const shortFormats = [
[0.7 * MINUTE, 'now'],
[1.5 * MINUTE, '1m'],
[60 * MINUTE, 'm', MINUTE],
[1.5 * HOUR, '1h'],
[DAY, 'h', HOUR],
[2 * DAY, '1d'],
[7 * DAY, 'd', DAY],
[1.5 * WEEK, '1w'],
[MONTH, 'w', WEEK],
[1.5 * MONTH, '1mo'],
[YEAR, 'mo', MONTH],
[1.5 * YEAR, '1y'],
[Number.MAX_VALUE, 'y', YEAR],
];
const longFormats = [[0.7 * MINUTE, 'just now'], [1.5 * MINUTE, 'a minute ago'], [60 * MINUTE, 'minutes ago', MINUTE], [1.5 * HOUR, 'an hour ago'], [DAY, 'hours ago', HOUR], [2 * DAY, 'yesterday'], [7 * DAY, 'days ago', DAY], [1.5 * WEEK, 'a week ago'], [MONTH, 'weeks ago', WEEK], [1.5 * MONTH, 'a month ago'], [YEAR, 'months ago', MONTH], [1.5 * YEAR, 'a year ago'], [Number.MAX_VALUE, 'years ago', YEAR]];
const longFormats = [
[0.7 * MINUTE, 'just now'],
[1.5 * MINUTE, 'a minute ago'],
[60 * MINUTE, 'minutes ago', MINUTE],
[1.5 * HOUR, 'an hour ago'],
[DAY, 'hours ago', HOUR],
[2 * DAY, 'yesterday'],
[7 * DAY, 'days ago', DAY],
[1.5 * WEEK, 'a week ago'],
[MONTH, 'weeks ago', WEEK],
[1.5 * MONTH, 'a month ago'],
[YEAR, 'months ago', MONTH],
[1.5 * YEAR, 'a year ago'],
[Number.MAX_VALUE, 'years ago', YEAR],
];
function relativeDate(input_, reference_, useShortVariant = false) {
export function relativeDate(
input_: number | Date,
reference_?: number | Date,
useShortVariant?: boolean = false,
): string {
let input = input_;

@@ -86,3 +97,7 @@ let reference = reference_;

if (typeof remainder === 'number') {
return Math.round(delta / remainder) + (useShortVariant ? '' : ' ') + relativeFormat;
return (
Math.round(delta / remainder) +
(useShortVariant ? '' : ' ') +
relativeFormat
);
} else {

@@ -101,6 +116,4 @@ return relativeFormat;

*/
function countOccurrences(haystack, char) {
if (!(char.length === 1)) {
throw new Error('char must be a string of length 1');
}
export function countOccurrences(haystack: string, char: string) {
invariant(char.length === 1, 'char must be a string of length 1');

@@ -121,7 +134,9 @@ let count = 0;

*/
function shellParse(str, env) {
const result = (0, (_shellQuote || _load_shellQuote()).parse)(str, env);
export function shellParse(str: string, env?: Object): Array<string> {
const result = parse(str, env);
for (let i = 0; i < result.length; i++) {
if (typeof result[i] !== 'string') {
throw new Error(`Unexpected operator "${result[i].op}" provided to shellParse`);
throw new Error(
`Unexpected operator "${result[i].op}" provided to shellParse`,
);
}

@@ -132,3 +147,3 @@ }

function removeCommonPrefix(a, b) {
export function removeCommonPrefix(a: string, b: string): [string, string] {
let i = 0;

@@ -141,5 +156,9 @@ while (a[i] === b[i] && i < a.length && i < b.length) {

function removeCommonSuffix(a, b) {
export function removeCommonSuffix(a: string, b: string): [string, string] {
let i = 0;
while (a[a.length - 1 - i] === b[b.length - 1 - i] && i < a.length && i < b.length) {
while (
a[a.length - 1 - i] === b[b.length - 1 - i] &&
i < a.length &&
i < b.length
) {
i++;

@@ -150,4 +169,10 @@ }

function shorten(str, maxLength, suffix) {
return str.length < maxLength ? str : str.slice(0, maxLength) + (suffix || '');
export function shorten(
str: string,
maxLength: number,
suffix?: string,
): string {
return str.length < maxLength
? str
: str.slice(0, maxLength) + (suffix || '');
}

@@ -158,5 +183,7 @@

*/
function splitOnce(str, separator) {
export function splitOnce(str: string, separator: string): [string, ?string] {
const index = str.indexOf(separator);
return index === -1 ? [str, null] : [str.slice(0, index), str.slice(index + separator.length)];
return index === -1
? [str, null]
: [str.slice(0, index), str.slice(index + separator.length)];
}

@@ -167,7 +194,11 @@

*/
function indent(str, level = 2, char = ' ') {
export function indent(
str: string,
level: number = 2,
char: string = ' ',
): string {
return str.replace(/^([^\n])/gm, char.repeat(level) + '$1');
}
function pluralize(noun, count) {
export function pluralize(noun: string, count: number) {
return count === 1 ? noun : noun + 's';

@@ -183,2 +214,2 @@ }

// eslint-disable-next-line max-len
const URL_REGEX = exports.URL_REGEX = /(https?:\/\/(?:www\.)?[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*|www\.[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*)/;
export const URL_REGEX = /(https?:\/\/(?:www\.)?[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*|www\.[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*)/;

@@ -1,8 +0,14 @@

'use strict';
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
* @flow
* @format
*/
Object.defineProperty(exports, "__esModule", {
value: true
});
export type AnyTeardown = (() => mixed) | rxjs$ISubscription | IDisposable;
/**

@@ -12,5 +18,7 @@ * Like a CompositeDisposable, but in addition to Disposable instances it can

*/
class UniversalDisposable {
export default class UniversalDisposable {
disposed: boolean;
teardowns: Set<AnyTeardown>;
constructor(...teardowns) {
constructor(...teardowns: Array<AnyTeardown>) {
this.teardowns = new Set();

@@ -23,3 +31,3 @@ this.disposed = false;

add(...teardowns) {
add(...teardowns: Array<AnyTeardown>): void {
if (this.disposed) {

@@ -34,3 +42,3 @@ throw new Error('Cannot add to an already disposed UniversalDisposable!');

remove(teardown) {
remove(teardown: AnyTeardown): void {
if (!this.disposed) {

@@ -41,3 +49,3 @@ this.teardowns.delete(teardown);

dispose() {
dispose(): void {
if (!this.disposed) {

@@ -54,11 +62,11 @@ this.disposed = true;

});
this.teardowns = null;
this.teardowns = (null: any);
}
}
unsubscribe() {
unsubscribe(): void {
this.dispose();
}
clear() {
clear(): void {
if (!this.disposed) {

@@ -70,18 +78,13 @@ this.teardowns.clear();

exports.default = UniversalDisposable; /**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*
*
* @format
*/
function assertTeardown(teardown) {
if (typeof teardown.dispose === 'function' || typeof teardown.unsubscribe === 'function' || typeof teardown === 'function') {
function assertTeardown(teardown: AnyTeardown): void {
if (
typeof teardown.dispose === 'function' ||
typeof teardown.unsubscribe === 'function' ||
typeof teardown === 'function'
) {
return;
}
throw new TypeError('Arguments to UniversalDisposable.add must be disposable');
}
throw new TypeError(
'Arguments to UniversalDisposable.add must be disposable',
);
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc