Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Side effect free imports & backwards compatibility APIs #3384

Merged
merged 26 commits into from
Mar 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
710e624
refactor(rxjs): start compatability package moving 'src/add' dir to '…
jasonaden Mar 5, 2018
40aca82
feat(compat): add compatability package definition
jasonaden Mar 6, 2018
df25de1
feat(compat): add Rx.ts to rxjs-compat
jasonaden Mar 6, 2018
d43a4c2
feat(compat): make Rx.ts for compatability layer work as the default …
jasonaden Mar 6, 2018
70e562b
feat(compat): add legacy reexport compat layer for 'rxjs/Observable' …
jasonaden Mar 6, 2018
1a0dc97
feat(compat): set up correct imports & get build working for rxjs-comapt
jasonaden Mar 6, 2018
a44db72
chore(build): build the legacy-reexports for inclusion in final distr…
jasonaden Mar 7, 2018
c24de91
chore(build): add the add operator/observable to legacy-reexports
jasonaden Mar 7, 2018
f823b96
chore(build): create legacy-reexports for all add operators/observable
jasonaden Mar 7, 2018
c2b705f
chore(build): get legacy reexports into the final rxjs build
jasonaden Mar 7, 2018
0152a38
chore(compat): export <v6 interface from <v6 locations (e.g. Subscrip…
jasonaden Mar 7, 2018
fd86df5
feat(compat): combatability mode for combineLatest
jasonaden Mar 7, 2018
ce83f62
chore(compat): add symbol to the compatibility package
jasonaden Mar 8, 2018
9f131d0
feat(compat): compatibility mode for zip operator
jasonaden Mar 8, 2018
ffce980
feat(compat): compatibility mode for merge operator
jasonaden Mar 8, 2018
00e8ba0
chore(InnerSubscriber): remove @internal on InnerSubscriber
jasonaden Mar 9, 2018
dea6964
fix(compat): adjustments to get rxjs-compat to build correctly
jasonaden Mar 9, 2018
7255440
refactor(compat): adjust tsconfig files and build output for compatab…
jasonaden Mar 13, 2018
7c16f3a
build(compat): scope build artifacts correctly & generate full npm di…
jasonaden Mar 14, 2018
6e84e78
feat(compat): add concat operator to compatibility layer
jasonaden Mar 14, 2018
6131529
chore(compat): adjust compatibility imports so ESM resolution will work
jasonaden Mar 14, 2018
916e968
fix(spec): get tests running using compatibility package
jasonaden Mar 14, 2018
daa12cd
refactor(compat): fix up export paths to clean up compatibility package
jasonaden Mar 14, 2018
ef35257
refactor(compat): make build and tests pass
jasonaden Mar 15, 2018
16bd573
chore(spec): remove rxjs-spec in favor of systemjs-compatibility-spec
jasonaden Mar 15, 2018
d4b0116
chore: add back dependency on rxjs@latest for dangerjs
jasonaden Mar 15, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
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