Skip to content

Commit

Permalink
Merge pull request #3384 from jasonaden/side-effect-free-imports
Browse files Browse the repository at this point in the history
Side effect free imports & backwards compatibility APIs
  • Loading branch information
benlesh authored Mar 16, 2018
2 parents dd7c9f1 + d4b0116 commit 7873f8a
Show file tree
Hide file tree
Showing 887 changed files with 2,861 additions and 1,867 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ typings/

# Generated
dist/
dist-compat/
tmp/
coverage/
img/
spec-js/
spec-build/
.nyc_output/
.out/

Expand Down
53 changes: 53 additions & 0 deletions .make-compat-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use strict";

let pkg = require('./compat/package.json');
let fs = require('fs-extra');
let mkdirp = require('mkdirp');
let path = require('path');
let klawSync = require('klaw-sync');
let licenseTool = require('./tools/add-license-to-file');
let addLicenseToFile = licenseTool.addLicenseToFile;
let addLicenseTextToFile = licenseTool.addLicenseTextToFile;

const ROOT = 'dist-compat/';
const CJS_ROOT = ROOT + 'cjs/compat/';
const ESM5_ROOT = ROOT + 'esm5/compat/';
const ESM2015_ROOT = ROOT + 'esm2015/compat/';
const TYPE_ROOT = ROOT + 'typings/compat/';
const PKG_ROOT = ROOT + 'package/';
const CJS_PKG = PKG_ROOT + '';
const ESM5_PKG = PKG_ROOT + '_esm5/';
const ESM2015_PKG = PKG_ROOT + '_esm2015/';
const UMD_PKG = PKG_ROOT + 'bundles/';
const TYPE_PKG = PKG_ROOT;

// License info for minified files
let licenseUrl = 'https://github.com/ReactiveX/RxJS/blob/master/LICENSE.txt';
let license = 'Apache License 2.0 ' + licenseUrl;

// Recreate the distribution folder
fs.removeSync(PKG_ROOT);
mkdirp.sync(PKG_ROOT);

// Copy over the sources
fs.copySync(TYPE_ROOT, TYPE_PKG);
copySources(CJS_ROOT, CJS_PKG);
copySources(ESM5_ROOT, ESM5_PKG, true);
copySources(ESM2015_ROOT, ESM2015_PKG, true);

fs.copySync('compat/package.json', PKG_ROOT + '/package.json');

function copySources(rootDir, packageDir, ignoreMissing) {
// If we are ignoring missing directories, early return when source doesn't exist
if (!fs.existsSync(rootDir)) {
if (ignoreMissing) {
return;
} else {
throw "Source root dir does not exist!";
}
}
// Copy over the CommonJS files
fs.copySync(rootDir, packageDir);
fs.copySync('./LICENSE.txt', packageDir + 'LICENSE.txt');
fs.copySync('./compat/README.md', packageDir + 'README.md');
}
15 changes: 9 additions & 6 deletions .make-packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const CJS_ROOT = ROOT + 'cjs/';
const ESM5_ROOT = ROOT + 'esm5/';
const ESM2015_ROOT = ROOT + 'esm2015/';
const UMD_ROOT = ROOT + 'global/';
const LEGACY_REEXPORT_ROOT = ROOT + "legacy-reexport/"
const TYPE_ROOT = ROOT + 'typings/';
const PKG_ROOT = ROOT + 'package/';
const CJS_PKG = PKG_ROOT + '';
Expand Down Expand Up @@ -52,14 +53,14 @@ let rootPackageJson = Object.assign({}, pkg, {
// functionality requires that the most broad mapping (rxjs/operators) be at
// the end of the alias mapping object. Created Webpack issue:
// https://github.com/webpack/webpack/issues/5870
const fileNames = klawSync(CJS_ROOT, {
const fileNames = klawSync(LEGACY_REEXPORT_ROOT, {
nodir: true,
filter: function(item) {
return item.path.endsWith('.js');
}
})
.map(item => item.path)
.map(path => path.slice((`${__dirname}/${CJS_ROOT}`).length))
.map(path => path.slice((`${__dirname}/${LEGACY_REEXPORT_ROOT}`).length))
.sort().reverse();

// Execute build optimizer transforms on ESM5 files
Expand Down Expand Up @@ -96,19 +97,21 @@ mkdirp.sync(PKG_ROOT);
copySources('src/', PKG_ROOT + 'src/');
copySources(CJS_ROOT, CJS_PKG);
fs.copySync(TYPE_ROOT, TYPE_PKG);
fs.copySync(LEGACY_REEXPORT_ROOT, CJS_PKG, {overwrite: false, errorOnExist: true});

copySources(ESM5_ROOT, ESM5_PKG, true);
copySources(ESM2015_ROOT, ESM2015_PKG, true);

// Copy over tsconfig.json for bazel build support
fs.copySync('./tsconfig.json', PKG_ROOT + 'src/tsconfig.json');
fs.copySync('./tsconfig.base.json', PKG_ROOT + 'src/tsconfig.json');

fs.writeJsonSync(PKG_ROOT + 'package.json', rootPackageJson);
fs.writeJsonSync(PKG_ROOT + 'package.json', rootPackageJson, {spaces: 2});
fs.copySync('src/operators/package.json', PKG_ROOT + '/operators/package.json');
fs.copySync('src/ajax/package.json', PKG_ROOT + '/ajax/package.json');
fs.copySync('src/websocket/package.json', PKG_ROOT + '/websocket/package.json');
fs.copySync('src/testing/package.json', PKG_ROOT + '/testing/package.json');


if (fs.existsSync(UMD_ROOT)) {
fs.copySync(UMD_ROOT, UMD_PKG);
// Add licenses to tops of bundles
Expand Down Expand Up @@ -146,7 +149,7 @@ function copySources(rootDir, packageDir, ignoreMissing) {
function createImportTargets(importTargets, targetName, targetDirectory) {
const importMap = {};
for (const x in importTargets) {
importMap['rxjs/' + x] = 'rxjs/' + targetName + importTargets[x];
importMap['rxjs/' + x] = ('rxjs-compat/' + targetName + importTargets[x]).replace(/\.js$/, '');
}

const outputData =
Expand All @@ -157,7 +160,7 @@ var path = require('path');
var dir = path.resolve(__dirname);
module.exports = function() {
return ${JSON.stringify(importMap, null, 4).replace(/(: )"rxjs\/_esm(5|2015)\/(.+")(,?)/g, "$1path.join(dir, \"$3)$4")};
return ${JSON.stringify(importMap, null, 4)};
}
`

Expand Down
1 change: 1 addition & 0 deletions compat/AsyncSubject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {AsyncSubject} from 'rxjs';
1 change: 1 addition & 0 deletions compat/BehaviorSubject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {BehaviorSubject} from 'rxjs';
1 change: 1 addition & 0 deletions compat/InnerSubscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {InnerSubscriber} from 'rxjs/internal-compatibility';
1 change: 1 addition & 0 deletions compat/Notification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Notification} from 'rxjs';
1 change: 1 addition & 0 deletions compat/Observable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Observable, Subscribable, SubscribableOrPromise, ObservableInput} from 'rxjs';
1 change: 1 addition & 0 deletions compat/Observer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Observer, NextObserver, ErrorObserver, CompletionObserver, PartialObserver} from 'rxjs';
1 change: 1 addition & 0 deletions compat/Operator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Operator} from 'rxjs';
1 change: 1 addition & 0 deletions compat/OuterSubscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {OuterSubscriber} from 'rxjs/internal-compatibility';
15 changes: 15 additions & 0 deletions compat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# RxJS Compatibility Package

This package is required to get backwards compatibility with RxJS pervious to version 6. It contains the imports to add operators to `Observable.prototype` and creation methods to `Observable`. This is what allows, for instance, dot-chaining:

```
Observable.interval(1)
.map(i => i * i)
```

vs

```
Observable.interval(1)
.pipe(map(i => i * i))
```
1 change: 1 addition & 0 deletions compat/ReplaySubject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {ReplaySubject} from 'rxjs';
219 changes: 219 additions & 0 deletions compat/Rx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/* tslint:disable:no-unused-variable */
// Subject imported before Observable to bypass circular dependency issue since
// Subject extends Observable and Observable references Subject in it's
// definition
export {Observable, Subject} from 'rxjs';
export {AnonymousSubject} from 'rxjs/internal-compatibility';
/* tslint:enable:no-unused-variable */

export { config } from 'rxjs/internal-compatibility';

// statics
/* tslint:disable:no-use-before-declare */
import './add/observable/bindCallback';
import './add/observable/bindNodeCallback';
import './add/observable/combineLatest';
import './add/observable/concat';
import './add/observable/defer';
import './add/observable/empty';
import './add/observable/forkJoin';
import './add/observable/from';
import './add/observable/fromEvent';
import './add/observable/fromEventPattern';
import './add/observable/fromPromise';
import './add/observable/generate';
import './add/observable/if';
import './add/observable/interval';
import './add/observable/merge';
import './add/observable/race';
import './add/observable/never';
import './add/observable/of';
import './add/observable/onErrorResumeNext';
import './add/observable/pairs';
import './add/observable/range';
import './add/observable/using';
import './add/observable/throw';
import './add/observable/timer';
import './add/observable/zip';

//dom
import './add/observable/dom/ajax';
import './add/observable/dom/webSocket';

//internal/operators
import './add/operator/buffer';
import './add/operator/bufferCount';
import './add/operator/bufferTime';
import './add/operator/bufferToggle';
import './add/operator/bufferWhen';
import './add/operator/catch';
import './add/operator/combineAll';
import './add/operator/combineLatest';
import './add/operator/concat';
import './add/operator/concatAll';
import './add/operator/concatMap';
import './add/operator/concatMapTo';
import './add/operator/count';
import './add/operator/dematerialize';
import './add/operator/debounce';
import './add/operator/debounceTime';
import './add/operator/defaultIfEmpty';
import './add/operator/delay';
import './add/operator/delayWhen';
import './add/operator/distinct';
import './add/operator/distinctUntilChanged';
import './add/operator/distinctUntilKeyChanged';
import './add/operator/do';
import './add/operator/exhaust';
import './add/operator/exhaustMap';
import './add/operator/expand';
import './add/operator/elementAt';
import './add/operator/filter';
import './add/operator/finally';
import './add/operator/find';
import './add/operator/findIndex';
import './add/operator/first';
import './add/operator/groupBy';
import './add/operator/ignoreElements';
import './add/operator/isEmpty';
import './add/operator/audit';
import './add/operator/auditTime';
import './add/operator/last';
import './add/operator/let';
import './add/operator/every';
import './add/operator/map';
import './add/operator/mapTo';
import './add/operator/materialize';
import './add/operator/max';
import './add/operator/merge';
import './add/operator/mergeAll';
import './add/operator/mergeMap';
import './add/operator/mergeMapTo';
import './add/operator/mergeScan';
import './add/operator/min';
import './add/operator/multicast';
import './add/operator/observeOn';
import './add/operator/onErrorResumeNext';
import './add/operator/pairwise';
import './add/operator/partition';
import './add/operator/pluck';
import './add/operator/publish';
import './add/operator/publishBehavior';
import './add/operator/publishReplay';
import './add/operator/publishLast';
import './add/operator/race';
import './add/operator/reduce';
import './add/operator/repeat';
import './add/operator/repeatWhen';
import './add/operator/retry';
import './add/operator/retryWhen';
import './add/operator/sample';
import './add/operator/sampleTime';
import './add/operator/scan';
import './add/operator/sequenceEqual';
import './add/operator/share';
import './add/operator/shareReplay';
import './add/operator/single';
import './add/operator/skip';
import './add/operator/skipLast';
import './add/operator/skipUntil';
import './add/operator/skipWhile';
import './add/operator/startWith';
import './add/operator/subscribeOn';
import './add/operator/switch';
import './add/operator/switchMap';
import './add/operator/switchMapTo';
import './add/operator/take';
import './add/operator/takeLast';
import './add/operator/takeUntil';
import './add/operator/takeWhile';
import './add/operator/throttle';
import './add/operator/throttleTime';
import './add/operator/timeInterval';
import './add/operator/timeout';
import './add/operator/timeoutWith';
import './add/operator/timestamp';
import './add/operator/toArray';
import './add/operator/toPromise';
import './add/operator/window';
import './add/operator/windowCount';
import './add/operator/windowTime';
import './add/operator/windowToggle';
import './add/operator/windowWhen';
import './add/operator/withLatestFrom';
import './add/operator/zip';
import './add/operator/zipAll';

/* tslint:disable:no-unused-variable */
export {
Observer,
Subscription,
ReplaySubject,
BehaviorSubject,
Notification,
EmptyError,
ArgumentOutOfRangeError,
ObjectUnsubscribedError,
UnsubscriptionError,
pipe
} from 'rxjs';

export {TestScheduler} from 'rxjs/testing';

export { Operator, Subscriber, AsyncSubject, ConnectableObservable, TimeoutError, VirtualTimeScheduler } from 'rxjs';
export { AjaxRequest, AjaxResponse, AjaxError, AjaxTimeoutError } from 'rxjs/ajax';

import { asapScheduler, asyncScheduler, queueScheduler, animationFrameScheduler, SchedulerLike } from 'rxjs';

import { iterator, observable, rxSubscriber } from 'rxjs/internal-compatibility';
export { TimeInterval, Timestamp } from 'rxjs/internal-compatibility';

import * as _operators from 'rxjs/operators';

export const operators = _operators;

/* tslint:enable:no-unused-variable */

/**
* @typedef {Object} Rx.Scheduler
* @property {Scheduler} queue Schedules on a queue in the current event frame
* (trampoline scheduler). Use this for iteration operations.
* @property {Scheduler} asap Schedules on the micro task queue, which uses the
* fastest transport mechanism available, either Node.js' `process.nextTick()`
* or Web Worker MessageChannel or setTimeout or others. Use this for
* asynchronous conversions.
* @property {Scheduler} async Schedules work with `setInterval`. Use this for
* time-based operations.
* @property {Scheduler} animationFrame Schedules work with `requestAnimationFrame`.
* Use this for synchronizing with the platform's painting
*/
let Scheduler = {
asap: asapScheduler as SchedulerLike,
queue: queueScheduler as SchedulerLike,
animationFrame: animationFrameScheduler as SchedulerLike,
async: asyncScheduler as SchedulerLike
};

/**
* @typedef {Object} Rx.Symbol
* @property {Symbol|string} rxSubscriber A symbol to use as a property name to
* retrieve an "Rx safe" Observer from an object. "Rx safety" can be defined as
* an object that has all of the traits of an Rx Subscriber, including the
* ability to add and remove subscriptions to the subscription chain and
* guarantees involving event triggering (can't "next" after unsubscription,
* etc).
* @property {Symbol|string} observable A symbol to use as a property name to
* retrieve an Observable as defined by the [ECMAScript "Observable" spec](https://github.com/zenparsing/es-observable).
* @property {Symbol|string} iterator The ES6 symbol to use as a property name
* to retrieve an iterator from an object.
*/
let Symbol = {
rxSubscriber,
observable,
iterator
};

export {
Scheduler,
Symbol
};
1 change: 1 addition & 0 deletions compat/Scheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Scheduler} from 'rxjs/internal-compatibility';
1 change: 1 addition & 0 deletions compat/Subject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Subject} from 'rxjs';
1 change: 1 addition & 0 deletions compat/SubjectSubscription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {SubjectSubscription} from 'rxjs/internal-compatibility';
1 change: 1 addition & 0 deletions compat/Subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Subscriber} from 'rxjs/internal-compatibility';
1 change: 1 addition & 0 deletions compat/Subscription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Subscription, Unsubscribable as AnonymousSubscription, SubscriptionLike as ISubscription} from 'rxjs';
Loading

0 comments on commit 7873f8a

Please sign in to comment.