saveBatch(batch) { if (!batch.length) return; this.$scope.importDomain.loadingOptions = SAVING_DOMAINS; this.Loading.start('importDomainFromDb'); this.ConfigureState.dispatchAction({ type: 'ADVANCED_SAVE_COMPLETE_CONFIGURATION', changedItems: this.batchActionsToRequestBody(batch), prevActions: [] }); this.saveSubscription = race( this.ConfigureState.actions$.pipe( filter((a) => a.type === 'ADVANCED_SAVE_COMPLETE_CONFIGURATION_OK'), tap(() => this.onHide()) ), this.ConfigureState.actions$.pipe( filter((a) => a.type === 'ADVANCED_SAVE_COMPLETE_CONFIGURATION_ERR') ) ).pipe( take(1), tap(() => { this.Loading.finish('importDomainFromDb'); }) ) .subscribe(); }
onCacheSelect(cacheID) { if (cacheID < 0) return; if (this.loadedCaches[cacheID]) return; return this.onCacheSelectSubcription = merge( timer(0, 1).pipe( take(1), tap(() => this.ConfigureState.dispatchAction({type: 'LOAD_CACHE', cacheID})) ), race( this.ConfigureState.actions$.pipe( filter((a) => a.type === 'LOAD_CACHE_OK' && a.cache._id === cacheID), pluck('cache'), tap((cache) => { this.loadedCaches[cacheID] = cache; }) ), this.ConfigureState.actions$.pipe( filter((a) => a.type === 'LOAD_CACHE_ERR' && a.action.cacheID === cacheID) ) ).pipe(take(1)) ) .subscribe(); }
subscribe() { const mesos$ = container.get(MesosStreamType); const masterRequest$ = container.get(MesosMasterRequestType).pipe( tap(response => { const master = mesosStreamParsers.getMaster( this.getMaster(), JSON.parse(response) ); CompositeState.addState(master); this.setMaster(master); }) ); const parsers = pipe(...Object.values(mesosStreamParsers)); const data$ = mesos$.pipe( merge(masterRequest$), distinctUntilChanged(), map(message => parsers(this.getLastMesosState(), JSON.parse(message))), tap(state => this.setState(state), console.error) ); const wait$ = masterRequest$.pipe(zip(mesos$.pipe(take(1)))); const eventTrigger$ = data$.pipe( merge( // A lot of DCOS UI rely on the MesosStateStore emitting // MESOS_STATE_CHANGE events. After the switch to the stream, we lost this // event. To avoid a deeper refactor, we introduced this fake emitter. // // TODO: https://jira.mesosphere.com/browse/DCOS-18277 interval(Config.getRefreshRate()) ) ); // Since we introduced the fake event above, we have to guarantee certain // refresh limits to the UI. They are: // // MOST once every (Config.getRefreshRate() * 0.5) ms. due to sampleTime. // LEAST once every tick of Config.getRefreshRate() ms in // Observable.interval // // TODO: https://jira.mesosphere.com/browse/DCOS-18277 this.stream = wait$ .pipe( concat(eventTrigger$), sampleTime(Config.getRefreshRate() * 0.5), retryWhen(linearBackoff(RETRY_DELAY, -1, MAX_RETRY_DELAY)) ) .subscribe( () => Promise.resolve().then(this.onStreamData), this.onStreamError ); }
switchMap((action: LOAD_ACTION) => { const host = store.getState().app.host; // Normalizing to match rx-jupyter vs. host record const serverConfig = { endpoint: host.serverUrl, token: host.token, crossDomain: false }; // TODO: make params optional in rx-jupyter return contents.get(serverConfig, action.path, {}).pipe( tap(xhr => { if (xhr.status !== 200) { throw new Error(xhr.response); } }), map(xhr => { return { type: "LOADED", payload: xhr.response }; }), catchError((xhrError: any) => of(loadFailed(xhrError))) ); })
switchMap(({ type }) => { const state = state$.value; const meta = challengeMetaSelector(state); const { nextChallengePath, introPath, challengeType } = meta; const closeChallengeModal = of(closeModal('completion')); let submitter = () => of({ type: 'no-user-signed-in' }); if ( !(challengeType in submitTypes) || !(submitTypes[challengeType] in submitters) ) { throw new Error( 'Unable to find the correct submit function for challengeType ' + challengeType ); } if (isSignedInSelector(state)) { submitter = submitters[submitTypes[challengeType]]; } return submitter(type, state).pipe( tap(() => navigate(introPath ? introPath : nextChallengePath)), concat(closeChallengeModal), filter(Boolean) ); })
switchMap(command => panel$.pipe( switchMap(panel => panel.visible$), tap(visible => { command.respond("PANEL_VISIBLE", visible); }) )
run(builderConfig) { const options = builderConfig.options; const root = this.context.workspace.root; const projectRoot = core_1.resolve(root, builderConfig.root); const host = new core_1.virtualFs.AliasHost(this.context.host); const webpackBuilder = new build_webpack_1.WebpackBuilder(Object.assign({}, this.context, { host })); return rxjs_1.of(null).pipe(operators_1.concatMap(() => options.deleteOutputPath ? this._deleteOutputDir(root, core_1.normalize(options.outputPath), this.context.host) : rxjs_1.of(null)), operators_1.concatMap(() => utils_1.normalizeFileReplacements(options.fileReplacements, host, root)), operators_1.tap(fileReplacements => options.fileReplacements = fileReplacements), operators_1.concatMap(() => utils_1.normalizeAssetPatterns(options.assets, host, root, projectRoot, builderConfig.sourceRoot)), // Replace the assets in options with the normalized version. operators_1.tap((assetPatternObjects => options.assets = assetPatternObjects)), operators_1.concatMap(() => { let webpackConfig; try { webpackConfig = this.buildWebpackConfig(root, projectRoot, host, options); } catch (e) { return rxjs_1.throwError(e); } return webpackBuilder.runWebpack(webpackConfig, exports.getBrowserLoggingCb(options.verbose)); }), operators_1.concatMap(buildEvent => { if (buildEvent.success && !options.watch && options.serviceWorker) { return new rxjs_1.Observable(obs => { service_worker_1.augmentAppWithServiceWorker(this.context.host, root, projectRoot, core_1.resolve(root, core_1.normalize(options.outputPath)), options.baseHref || '/', options.ngswConfigPath).then(() => { obs.next({ success: true }); obs.complete(); }, (err) => { obs.error(err); }); }); } else { return rxjs_1.of(buildEvent); } })); }
// Note: this method mutates the options argument. _startDevServer(options) { const architect = this.context.architect; const [project, targetName, configuration] = options.devServerTarget.split(':'); // Override browser build watch setting. const overrides = { watch: false, host: options.host, port: options.port }; const targetSpec = { project, target: targetName, configuration, overrides }; const builderConfig = architect.getBuilderConfiguration(targetSpec); let devServerDescription; let baseUrl; return architect.getBuilderDescription(builderConfig).pipe(operators_1.tap(description => devServerDescription = description), operators_1.concatMap(devServerDescription => architect.validateBuilderOptions(builderConfig, devServerDescription)), operators_1.concatMap(() => { // Compute baseUrl from devServerOptions. if (options.devServerTarget && builderConfig.options.publicHost) { let publicHost = builderConfig.options.publicHost; if (!/^\w+:\/\//.test(publicHost)) { publicHost = `${builderConfig.options.ssl ? 'https' : 'http'}://${publicHost}`; } const clientUrl = url.parse(publicHost); baseUrl = url.format(clientUrl); } else if (options.devServerTarget) { baseUrl = url.format({ protocol: builderConfig.options.ssl ? 'https' : 'http', hostname: options.host, port: builderConfig.options.port.toString(), }); } // Save the computed baseUrl back so that Protractor can use it. options.baseUrl = baseUrl; return rxjs_1.of(this.context.architect.getBuilder(devServerDescription, this.context)); }), operators_1.concatMap(builder => builder.run(builderConfig))); }
mergeMap(config => ( pack$.pipe( // get the specs for each found plugin pack mergeMap(({ pack }) => ( pack ? pack.getPluginSpecs() : [] )), // make sure that none of the plugin specs have conflicting ids, fail // early if conflicts detected or merge the specs back into the stream toArray(), mergeMap(allSpecs => { for (const [id, specs] of groupSpecsById(allSpecs)) { if (specs.length > 1) { throw new Error( `Multiple plugins found with the id "${id}":\n${ specs.map(spec => ` - ${id} at ${spec.getPath()}`).join('\n') }` ); } } return allSpecs; }), mergeMap(async (spec) => { // extend the config service with this plugin spec and // collect its deprecations messages if some of its // settings are outdated const deprecations = []; await extendConfigService(spec, config, settings, (message) => { deprecations.push({ spec, message }); }); return { spec, deprecations, }; }), // extend the config with all plugins before determining enabled status bufferAllResults, map(({ spec, deprecations }) => { const isRightVersion = spec.isVersionCompatible(config.get('pkg.version')); const enabled = isRightVersion && spec.isEnabled(config); return { config, spec, deprecations, enabledSpecs: enabled ? [spec] : [], disabledSpecs: enabled ? [] : [spec], invalidVersionSpecs: isRightVersion ? [] : [spec], }; }), // determine which plugins are disabled before actually removing things from the config bufferAllResults, tap(result => { for (const spec of result.disabledSpecs) { disableConfigExtension(spec, config); } }) ) )),
export function safeChildProcess(childProcess, observer) { const ownTerminateSignal$ = Rx.merge( Rx.fromEvent(process, 'SIGTERM').pipe(mapTo('SIGTERM')), Rx.fromEvent(process, 'SIGINT').pipe(mapTo('SIGINT')), Rx.fromEvent(process, 'SIGBREAK').pipe(mapTo('SIGBREAK')), ) .pipe( take(1), share() ); // signals that will be sent to the child process as a result of the main process // being sent these signals, or the exit being triggered const signalForChildProcess$ = Rx.merge( // SIGKILL when this process gets a terminal signal ownTerminateSignal$.pipe( mapTo('SIGKILL') ), // SIGKILL when this process forcefully exits Rx.fromEvent(process, 'exit').pipe( take(1), mapTo('SIGKILL') ), ); // send termination signals const terminate$ = Rx.merge( signalForChildProcess$.pipe( tap(signal => childProcess.kill(signal)) ), ownTerminateSignal$.pipe( delay(1), tap(signal => process.kill(process.pid, signal)), ) ); // this is adding unsubscribe logic to our observer // so that if our observer unsubscribes, we terminate our child-process observer.add(() => { childProcess.kill('SIGKILL'); }); observer.add(terminate$.pipe(ignoreElements()).subscribe(observer)); }
_loadWorkspaceSchema() { if (this._workspaceSchema) { return rxjs_1.of(this._workspaceSchema); } else { return this._loadJsonFile(this._workspaceSchemaPath).pipe(operators_1.tap((workspaceSchema) => this._workspaceSchema = workspaceSchema)); } }
}), operators_1.concatMap(() => { if (this._dryRun) { return rxjs_1.of(); } this._lifeCycle.next({ kind: 'post-tasks-start' }); return this._engine.executePostTasks() .pipe(operators_1.tap({ complete: () => this._lifeCycle.next({ kind: 'post-tasks-end' }) }), operators_1.defaultIfEmpty(), operators_1.last()); }), operators_1.tap({ complete: () => {
$onInit() { if (this.isDemo) return; this.inProgress$ = this._inProgressSubject.asObservable(); this.clusters$ = this.agentMgr.connectionSbj.pipe( combineLatest(this.inProgress$), tap(([sbj, inProgress]) => this.inProgress = inProgress), filter(([sbj, inProgress]) => !inProgress), tap(([{cluster, clusters}]) => { this.cluster = cluster ? {...cluster} : null; this.clusters = _.orderBy(clusters, ['name'], ['asc']); }) ) .subscribe(() => {}); }
switchMap(({ anchor }) => { const img = anchor.querySelector(".project-card-img"); if (!anchor || !img) return of({}); const page = animationMain.querySelector(".page"); if (!page) return of({}); const titleNode = anchor.parentNode.querySelector(".project-card-title"); const title = (titleNode && titleNode.textContent) || "|"; const h1 = document.createElement("h1"); h1.classList.add("page-title"); h1.style.opacity = 0; h1.textContent = title; const postDate = document.createElement("div"); postDate.classList.add("post-date"); postDate.classList.add("heading"); postDate.style.opacity = 0; postDate.textContent = "|"; empty.call(page); page.appendChild(h1); page.appendChild(postDate); const placeholder = document.createElement("div"); placeholder.classList.add("sixteen-nine"); img.parentNode.insertBefore(placeholder, img); img.classList.add("lead"); img.style.transformOrigin = "left top"; page.appendChild(img); animationMain.style.position = "fixed"; animationMain.style.opacity = 1; const first = placeholder.getBoundingClientRect(); const last = img.getBoundingClientRect(); const invertX = first.left - last.left; const invertY = first.top - last.top; const invertScale = first.width / last.width; const transform = [ { transform: `translate3d(${invertX}px, ${invertY}px, 0) scale(${invertScale})`, }, { transform: "translate3d(0, 0, 0) scale(1)" }, ]; return animate(img, transform, settings).pipe( tap({ complete() { animationMain.style.position = "absolute"; }, }) ); })
switchMap(() => { const state = getState(); const { challengeType } = challengeMetaSelector(state); if (challengeType === backend) { return buildBackendChallenge(state).pipe( tap(frameTests), ignoreElements(), startWith(initConsole('// running test')), catchError(err => of(disableJSOnError(err))) ); } return buildFromFiles(state, false).pipe( tap(frameTests), ignoreElements(), startWith(initConsole('// running test')), catchError(err => of(disableJSOnError(err))) ); })
defer(() => { const { contentDocument: frame } = document.getElementById(testId); // Enable Stateless Functional Component. Otherwise, enzyme-adapter-react-16 // does not work correctly. setConfig({ pureSFC: true }); return frame .__runTests(tests) .pipe(tap(() => setConfig({ pureSFC: false }))); });
/** * Returns the cached icon for a SvgIconConfig if available, or fetches it from its URL if not. * @param {?} config * @return {?} */ _getSvgFromConfig(config) { if (config.svgElement) { // We already have the SVG element for this icon, return a copy. return of(cloneSvg(config.svgElement)); } else { // Fetch the icon from the config's URL, cache it, and return a copy. return this._loadSvgIconFromConfig(config).pipe(tap(svg => config.svgElement = svg), map(svg => cloneSvg(svg))); } }
it("handles both the legacy and current arguments for ofMessageType", () => { from([ { header: { msg_type: "a" } }, { header: { msg_type: "d" } }, { header: { msg_type: "b" } }, { header: { msg_type: "a" } }, { header: { msg_type: "d" } } ]) .pipe( ofMessageType(["a", "d"]), tap(val => { expect(val.header.msg_type === "a" || val.header.msg_type === "d"); }), pluck("header", "msg_type"), count() ) .toPromise() .then(val => { expect(val).toEqual(4); }); from([ { header: { msg_type: "a" } }, { header: { msg_type: "d" } }, { header: { msg_type: "b" } }, { header: { msg_type: "a" } }, { header: { msg_type: "d" } } ]) .pipe( // Note the lack of array brackets on the arguments ofMessageType("a", "d"), tap(val => { expect(val.header.msg_type === "a" || val.header.msg_type === "d"); }), pluck("header", "msg_type"), count() ) .toPromise() .then(val => { expect(val).toEqual(4); }); });
export function executeCellEpic(action$: ActionsObservable<*>, store: any) { return action$.pipe( ofType(EXECUTE_CELL, EXECUTE_FOCUSED_CELL), mergeMap(action => { if (action.type === EXECUTE_FOCUSED_CELL) { const state = store.getState(); const id = state.document.get("cellFocused"); if (!id) { throw new Error("attempted to execute without an id"); } return of(executeCell(id)); } return of(action); }), tap(action => { if (!action.id) { throw new Error("execute cell needs an id"); } }), // Split stream by cell IDs groupBy(action => action.id), // Work on each cell's stream map(cellActionStream => cellActionStream.pipe( // When a new EXECUTE_CELL comes in with the current ID, we create a // a new stream and unsubscribe from the old one. switchMap(({ id }) => { const state = store.getState(); const cell = state.document.getIn( ["notebook", "cellMap", id], Immutable.Map() ); // We only execute code cells if (cell.get("cell_type") !== "code") { return empty(); } const source = cell.get("source", ""); const message = createExecuteRequest(source); return createExecuteCellStream(action$, store, message, id); }) ) ), // Bring back all the inner Observables into one stream mergeAll(), catchError((err, source) => merge(of({ type: ERROR_EXECUTING, payload: err, error: true }), source) ) ); }
/** * Returns an Observable that produces the icon (as an `<svg>` DOM element) from the given URL. * The response from the URL may be cached so this will not always cause an HTTP request, but * the produced element will always be a new copy of the originally fetched icon. (That is, * it will not contain any modifications made to elements previously returned). * * @param {?} safeUrl URL from which to fetch the SVG icon. * @return {?} */ getSvgIconFromUrl(safeUrl) { const /** @type {?} */ url = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, safeUrl); if (!url) { throw getMatIconFailedToSanitizeUrlError(safeUrl); } const /** @type {?} */ cachedIcon = this._cachedIconsByUrl.get(url); if (cachedIcon) { return of(cloneSvg(cachedIcon)); } return this._loadSvgIconFromConfig(new SvgIconConfig(safeUrl)).pipe(tap(svg => this._cachedIconsByUrl.set(/** @type {?} */ ((url)), svg)), map(svg => cloneSvg(svg))); }
switchMap(repository => { return addRepositoryGraphql( repository.name, repository.uri, repository.priority ).pipe( tap(() => { repository.complete(); }) ); }),
function executeStopJobRunMutation({ jobId, jobRunId, onSuccess }) { return dataLayer .query(stopJobRunMutation, { jobId, jobRunId }) .pipe( mapTo({ done: true }), tap(_ => onSuccess()), startWith({ done: false }) ); }
_loadWorkspaceFromPath(workspacePath) { if (!workspacePath) { return rxjs_1.of(null); } if (this._workspaceCacheMap.has(workspacePath)) { return rxjs_1.of(this._workspaceCacheMap.get(workspacePath) || null); } const workspaceRoot = core_1.dirname(workspacePath); const workspaceFileName = core_1.basename(workspacePath); const workspace = new core_1.experimental.workspace.Workspace(workspaceRoot, this._host); return workspace.loadWorkspaceFromHost(workspaceFileName).pipe(operators_1.tap(workspace => this._workspaceCacheMap.set(workspacePath, workspace))); }
return operators_1.concatMap(data => { const fragments = JSON.parse(pointer); const source = this._sourceMap.get(schema.$source); let value = source ? source(schema) : rxjs_1.of(undefined); if (!utils_1.isObservable(value)) { value = rxjs_1.of(value); } return value.pipe( // Synchronously set the new data at the proper JsonSchema path. operators_1.tap(x => _set(data, fragments, x)), // But return the data object. operators_1.map(() => data)); });
switchMap(repository => { return removePackageRepositoryGraphql(repository.name, repository.url).pipe( startWith({ pendingRequest: true }), map(result => { return { result, pendingRequest: false }; }), tap(() => { repository.complete(); }) ); }),
execute(options) { const parentContext = this._context[this._context.length - 1]; if (!parentContext) { this._lifeCycle.next({ kind: 'start' }); } /** Create the collection and the schematic. */ const collection = this._engine.createCollection(options.collection); // Only allow private schematics if called from the same collection. const allowPrivate = options.allowPrivate || (parentContext && parentContext.collection === options.collection); const schematic = collection.createSchematic(options.schematic, allowPrivate); // We need two sinks if we want to output what will happen, and actually do the work. // Note that fsSink is technically not used if `--dry-run` is passed, but creating the Sink // does not have any side effect. const dryRunSink = new dryrun_1.DryRunSink(this._host, this._force); const fsSink = new host_1.HostSink(this._host, this._force); let error = false; const dryRunSubscriber = dryRunSink.reporter.subscribe(event => { this._reporter.next(event); error = error || (event.kind == 'error'); }); this._lifeCycle.next({ kind: 'workflow-start' }); const context = Object.assign({}, options, { debug: options.debug || false, logger: options.logger || (parentContext && parentContext.logger) || new core_1.logging.NullLogger(), parentContext }); this._context.push(context); return schematic.call(options.options, rxjs_1.of(new host_tree_1.HostTree(this._host)), { logger: context.logger }).pipe(operators_1.map(tree => static_1.optimize(tree)), operators_1.concatMap((tree) => { return rxjs_1.concat(dryRunSink.commit(tree).pipe(operators_1.ignoreElements()), rxjs_1.of(tree)); }), operators_1.concatMap((tree) => { dryRunSubscriber.unsubscribe(); if (error) { return rxjs_1.throwError(new exception_1.UnsuccessfulWorkflowExecution()); } if (this._dryRun) { return rxjs_1.of(); } return fsSink.commit(tree).pipe(operators_1.defaultIfEmpty(), operators_1.last()); }), operators_1.concatMap(() => { if (this._dryRun) { return rxjs_1.of(); } this._lifeCycle.next({ kind: 'post-tasks-start' }); return this._engine.executePostTasks() .pipe(operators_1.tap({ complete: () => this._lifeCycle.next({ kind: 'post-tasks-end' }) }), operators_1.defaultIfEmpty(), operators_1.last()); }), operators_1.tap({ complete: () => { this._lifeCycle.next({ kind: 'workflow-end' }); this._context.pop(); if (this._context.length == 0) { this._lifeCycle.next({ kind: 'end' }); } } })); }
export function watchStatusAndLicenseToInitialize(xpackMainPlugin, downstreamPlugin, initialize) { const xpackInfo = xpackMainPlugin.info; const xpackInfoFeature = xpackInfo.feature(downstreamPlugin.id); const upstreamStatus = xpackMainPlugin.status; const currentStatus$ = Rx .of({ state: upstreamStatus.state, message: upstreamStatus.message, }); const newStatus$ = Rx .fromEvent(upstreamStatus, 'change', null, (previousState, previousMsg, state, message) => { return { state, message, }; }); const status$ = Rx.merge(currentStatus$, newStatus$); const currentLicense$ = Rx.of(xpackInfoFeature.getLicenseCheckResults()); const newLicense$ = Rx .fromEventPattern(xpackInfo.onLicenseInfoChange.bind(xpackInfo)) .pipe(map(() => xpackInfoFeature.getLicenseCheckResults())); const license$ = Rx.merge(currentLicense$, newLicense$); Rx.combineLatest(status$, license$) .pipe( map(([status, license]) => ({ status, license })), switchMap(({ status, license }) => { if (status.state !== 'green') { return Rx.of({ state: status.state, message: status.message }); } return Rx.defer(() => initialize(license)) .pipe( map(() => ({ state: 'green', message: 'Ready', })), catchError(propagateRedStatusAndScaleRetry()) ); }), tap(({ state, message }) => { downstreamPlugin.status[state](message); }) ) .subscribe(); }
run(builderConfig) { const options = builderConfig.options; const root = this.context.workspace.root; const projectRoot = core_1.resolve(root, builderConfig.root); const host = new core_1.virtualFs.AliasHost(this.context.host); return rxjs_1.of(null).pipe(operators_1.concatMap(() => utils_1.addFileReplacements(root, host, options.fileReplacements)), operators_1.concatMap(() => utils_1.normalizeAssetPatterns(options.assets, host, root, projectRoot, builderConfig.sourceRoot)), // Replace the assets in options with the normalized version. operators_1.tap((assetPatternObjects => options.assets = assetPatternObjects)), operators_1.concatMap(() => new rxjs_1.Observable(obs => { const karma = require_project_module_1.requireProjectModule(core_1.getSystemPath(projectRoot), 'karma'); const karmaConfig = core_1.getSystemPath(core_1.resolve(root, core_1.normalize(options.karmaConfig))); // TODO: adjust options to account for not passing them blindly to karma. // const karmaOptions: any = Object.assign({}, options); // tslint:disable-next-line:no-any const karmaOptions = {}; if (options.watch !== undefined) { karmaOptions.singleRun = !options.watch; } // Convert browsers from a string to an array if (options.browsers) { karmaOptions.browsers = options.browsers.split(','); } karmaOptions.buildWebpack = { root: core_1.getSystemPath(root), projectRoot: core_1.getSystemPath(projectRoot), options: options, webpackConfig: this._buildWebpackConfig(root, projectRoot, host, options), // Pass onto Karma to emit BuildEvents. successCb: () => obs.next({ success: true }), failureCb: () => obs.next({ success: false }), }; // TODO: inside the configs, always use the project root and not the workspace root. // Until then we pretend the app root is relative (``) but the same as `projectRoot`. karmaOptions.buildWebpack.options.root = ''; // tslint:disable-line:no-any // Assign additional karmaConfig options to the local ngapp config karmaOptions.configFile = karmaConfig; // Complete the observable once the Karma server returns. const karmaServer = new karma.Server(karmaOptions, () => obs.complete()); karmaServer.start(); // Cleanup, signal Karma to exit. return () => { // Karma does not seem to have a way to exit the server gracefully. // See https://github.com/karma-runner/karma/issues/2867#issuecomment-369912167 // TODO: make a PR for karma to add `karmaServer.close(code)`, that // calls `disconnectBrowsers(code);` // karmaServer.close(); }; }))); }
async intercept(context, call$) { const key = this.trackBy(context); if (!key) { return call$; } try { const value = await this.cacheManager.get(key); if (value) { return rxjs_1.of(value); } return call$.pipe(operators_1.tap(response => this.cacheManager.set(key, response))); } catch (_a) { return call$; } }
switchMap(() => { const state = state$.value; const { challengeType } = challengeMetaSelector(state); const build = challengeType === backend ? buildBackendChallenge : buildFromFiles; return build(state).pipe( tap(frameTests), ignoreElements(), startWith(initLogs()), startWith(initConsole('// running tests')), catchError(err => { console.error(err); return of(disableJSOnError(err)); }) ); })