rxjs#partition TypeScript Examples

The following examples show how to use rxjs#partition. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: app.component.ts    From Angular-Cookbook with MIT License 6 votes vote down vote up
startStream() {
    const streamSource = interval(1500).pipe(
      map((input) => {
        const index = input % this.combinedStreamData.length;
        return this.combinedStreamData[index];
      })
    );
    const [moviesStream, cartoonsStream] = partition(
      streamSource,
      (item) => item.type === 'movie'
    );
    this.subscription = merge(
      moviesStream.pipe(
        tap((movie) => {
          this.movies.push(movie.title);
        })
      ),
      cartoonsStream.pipe(
        tap((cartoon) => {
          this.cartoons.push(cartoon.title);
        })
      )
    ).subscribe((output) => {
      console.log(output);
    });
  }
Example #2
Source File: auth.ts    From webapp with MIT License 5 votes vote down vote up
[onLoginNoType$, onLogoutNoType$] = partition(
  authenticated$,
  currentUser => Boolean(currentUser)
)
Example #3
Source File: pan.ts    From ble with Apache License 2.0 5 votes vote down vote up
globalPan: Epic = (action$, { store, app }) => {
	const [middleClick$, otherClick$] = partition(fromEvent<PointerEvent>(app.view, 'pointerdown'), (ev) => ev.button === 1);

	const startPanning$ = merge(
		middleClick$.pipe(
			tap((ev) => {
				// on Windows middle-click is for multidirectional scroll
				ev.preventDefault();
			}),
		),
		otherClick$.pipe(
			filter((ev) => store.editor.mode === EditorMode.pan || ev.button === 1),
		),
	);

	return startPanning$.pipe(
		tap(() => {
			store.editor.setPanning(true);
		}),
		map(({ clientX, clientY }) => ({ // save starting values
			start: {
				x: clientX,
				y: clientY,
			},
			pivot: {
				x: store.editor.position.x,
				y: store.editor.position.y,
			},
		})),
		switchMap(({ start, pivot }) => {
			const oldMode = store.editor.mode;
			store.editor.setMode(EditorMode.pan);

			return fromEvent<PointerEvent>(document, 'pointermove').pipe(
				tap(({ clientX, clientY }) => {
					const { scale } = store.editor;
					const deltaX = pivot.x + (start.x - clientX) * (1/scale);
					const deltaY = pivot.y + (start.y - clientY) * (1/scale);

					store.editor.position.set(deltaX, deltaY);
				}),
				takeUntil(fromEvent(document, 'pointerup').pipe(
					tap(() => {
						store.editor.setMode(oldMode);
						store.editor.setPanning(false);
					})
				)),
			);
		}),
		ignoreElements(),
	);
}
Example #4
Source File: client.ts    From FIDO2Client with MIT License 4 votes vote down vote up
constructor(options: IClientOptions = {}) {

        /**
         * Assign default options.
         */
        let defaultOptions: IClientOptions = {
            defaultModal: true,
            pinUvAuthProtocol: ClientPinVersion.v1,
            transports: ['ble', 'nfc', 'usb'],
        }
        this.options = Object.assign(defaultOptions, options);

        /**
         * Client modal.
         */
        if (this.options.defaultModal) {
            /**
             * Create default modal.
             * @TODO fix me, using import() instead.
             */
            this.modal = new (require('../modal/default').DefaultModal)();
        } else {
            this.modal = new Subject<IClientObservable>();
        }

        /**
         * Fido2 client session.
         */
        this.session = new Ctap2Session(this.options.pinUvAuthProtocol || ClientPinVersion.v1);

        /**
         * Fido2 client subject. Notify channel for all fido2 event.
         * Those nofity will be handled by default modal or callback provided by the user.
         */
        this.clientSubject = new Subject<IClientObservable>();
        const [obs1, obs2] = partition(this.clientSubject, () => this.options.defaultModal === true);

        /**
         * Nofity to default modal handler.
         */
        obs1.subscribe(this.modal);

        /**
         * Notify to user handler.
         */
        obs2.subscribe(async value => {
            switch (value.type) {

                /**
                 * Required events.
                 */
                case 'fido2-event-request': {
                    let request = value.data as IClientRequest;
                    if (this.options.event?.onRequest) {
                        let status = await this.options.event.onRequest(request).catch(() => { });
                        this.modal.next({ type: 'fido2-event-response', data: !!status });
                        break;
                    }
                }
                case 'fido2-event-enter-pin': {
                    if (this.options.event?.onEnterPin) {
                        let pin = await this.options.event.onEnterPin();
                        this.modal.next({ type: 'fido2-event-pin-available', data: pin });
                        break;
                    }
                }
                case 'fido2-event-set-pin': {
                    if (this.options.event?.onSetPin) {
                        let pin = await this.options.event.onSetPin();
                        this.modal.next({ type: 'fido2-event-pin-available', data: pin });
                        break;
                    }
                }
                case 'fido2-event-device-attach': {
                    if (this.options.event?.onDeviceAttached) {
                        let device = await this.options.event.onDeviceAttached(value.data as IFido2Device);
                        device && this.modal.next({ type: 'fido2-event-select-device', data: device });
                        break;
                    }
                }
                case 'fido2-event-pin-invalid': {
                    if (this.options.event?.onPinInvalid) {
                        let pin = await this.options.event.onPinInvalid(value.data as number);
                        this.modal.next({ type: 'fido2-event-pin-available', data: pin });
                        break;
                    }
                }

                /**
                 * Optional events.
                 */
                case 'fido2-event-device-detach':
                    (this.options.event?.onDeviceDetached || (() => { }))(value.data as IFido2Device);
                    break;

                case 'fido2-event-pin-valid':
                    (this.options.event?.onPinValid || (() => { }))();
                    break;

                case 'fido2-event-device-selected':
                    (this.options.event?.onDeviceSelected || (() => { }))(value.data as IFido2DeviceInfo);
                    break;

                case 'fido2-event-success':
                    (this.options.event?.onSuccess || (() => { }))();
                    break;

                case 'fido2-event-keep-alive':
                    (this.options.event?.onKeepAlive || (() => { }))(value.data as number);
                    break;

                case 'fido2-event-keep-alive-cancel':
                    (this.options.event?.onKeepAliveCancel || (() => { }))();
                    this.modal.next(value);
                    break;

                case 'fido2-event-pin-auth-blocked':
                    (this.options.event?.onPinAuthBlocked || (() => { }))();
                    this.modal.next(value);
                    break;

                case 'fido2-event-pin-blocked':
                    (this.options.event?.onPinBlocked || (() => { }))();
                    this.modal.next(value);
                    break;

                case 'fido2-event-timeout':
                    (this.options.event?.onTimeout || (() => { }))();
                    this.modal.next(value);
                    break;

                case 'fido2-event-error':
                    (this.options.event?.onError || (() => { }))(value.data as Error);
                    this.modal.next(value);
                    break;

                /**
                 * Missing event handlers.
                 */
                default:
                    logger.debug(`unhandled fido2 client subject with type=${value.type}, data=${value.data}`);
                    throw new Fido2ClientErrMissingEventListener(value.type);
            }
        });

        /**
         * Create request Subject.
         */
        this.request = new Subject<boolean>();

        /**
         * Create pin Subject.
         */
        this.pin = new Subject<string>();

        /**
         * Create device Subject.
         */
        this.device = new Subject<IFido2Device>();

        /**
         * Keep alive subject.
         */
        this.keepAlive = new Subject<number>()

        /**
         * Create cancel Subject.
         */
        this.cancel = new Subject<void>();

        /**
         * Create error Subject.
         */
        this.error = new Subject<Fido2Event>();

        /**
         * Subscription.
         */
        this.subs = new Subscription();

        /**
         * Notify from modal.
         */
        this.modal.subscribe(value => {
            switch (value.type) {
                case 'fido2-event-response':
                    this.request.next(value.data as boolean);
                    break;
                case 'fido2-event-pin-available':
                    this.pin.next(value.data as string);
                    break;
                case 'fido2-event-select-device':
                    this.device.next(value.data as IFido2Device);
                    break;
                case 'fido2-event-cancel':
                    this.cancel.next();
                    break;
                case 'fido2-event-request':
                case 'fido2-event-enter-pin':
                case 'fido2-event-pin-valid':
                case 'fido2-event-pin-blocked':
                case 'fido2-event-pin-auth-blocked':
                case 'fido2-event-device-attach':
                case 'fido2-event-device-detach':
                case 'fido2-event-device-selected':
                case 'fido2-event-keep-alive':
                case 'fido2-event-success':
                case 'fido2-event-no-credentials':
                case 'fido2-event-timeout':
                    /**
                     * Drop self event.
                     */
                    break;
                case 'fido2-event-keep-alive-cancel':
                    this.error.next(value.type);
                    break
                case 'fido2-event-error':
                    this.error.next(value.data as Fido2Event);
                    break
                default:
                    /**
                     * Shouldn't go there.
                     */
                    logger.debug(`drop unknown notify with type=${value.type}, data=${value.data}`);
                    break;
            }
        });

        logger.debug('create fido2 client success');
    }
Example #5
Source File: service.ts    From FIDO2Client with MIT License 4 votes vote down vote up
constructor() {

        /**
         * Create map.
         */
        this.device = new Map<string, { card: NFC, timestamp: number }>();

        /**
         * Create subject.
         */
        this.deviceSubject = new Subject<Device>();

        /**
         * Set default service state.
         */
        this.state = DeviceState.off;

        /**
         * Subscribe for new card.
         */
        const [newCard, oldCard] = partition(pcsc.observable.pipe(

            /**
             * Filter invalid card.
             */
            filter(x => !!x.atr && !!x.name),
        ), x => {

            /**
             * Create card id.
             */
            let id = `CCID-${x.name}`;

            /**
             * Is new card.
             */
            return this.device.get(id) === undefined;
        });

        /**
         * Update old card nonce.
         */
        oldCard.subscribe({
            next: x => {

                /**
                 * Create card id.
                 */
                let id = `CCID-${x.name}`;

                /**
                 * Update card nonce.
                 */
                let card = this.device.get(id);

                /**
                 * Double check.
                 */
                if (card === undefined) return;

                /**
                 * Update card nonce
                 */
                card.timestamp = Date.now();
            },
            error: (e: Error) => logger.debug(e.message)
        });

        /**
         * Add new card.
         */
        newCard.pipe(

            /**
             * Filter FIDO2 card.
             */
            filter(x => {
                /**
                 * Create card.
                 */
                let card = new NativeCard(x);

                /**
                 * Send applet selection command.
                 */
                let cmd = new FragmentReq().initialize(InstructionClass.Unknown, InstructionCode.Select, 0x04, 0x00, NfcFido2Aid);

                /**
                 * Serialize and transmit cmd.
                 */
                let buff = card.transmit(cmd.serialize());

                /**
                 * Select card by AID failed.
                 */
                if (buff.length < 2) {
                    return false;
                }

                /**
                 * Parse response.
                 */
                let res = new FragmentRes().deserialize(buff);

                /**
                 * Close card.
                 */
                card.close();

                /**
                 * Determine card capabilities FIDO2.
                 */
                return res.data.compare(NfcCtap1Version) === 0 || res.data.compare(NfcCtap2Version) === 0;
            }),

            /**
             * Map to NFC class.
             */
            map<NativeCardMetadata, NFC>(x => {
                return {
                    type: 'CCID',
                    name: x.name,
                    atr: x.atr,
                    device: {
                        transport: 'nfc',
                        name: x.name,
                        nfcType: 'CCID'
                    }
                }
            }),
        ).subscribe({
            next: card => {

                logger.debug('card attached', card.name, card.atr.toString('hex'));

                /**
                 * Store FIDO2 card.
                 */
                this.device.set(`CCID-${card.name}`, { card, timestamp: Date.now() });

                /**
                 * Notify new FIDO2 card attach.
                 */
                this.deviceSubject.next({ device: card.device, status: 'attach' });
            },
            error: (e: Error) => logger.debug(e.message)
        });

        /**
         * Subscribe for update.
         */
        pcsc.update.subscribe(delta => this.device.forEach((x, y) => {

            /**
             * @TODO calculate base on delta, maybe failed when delta is too long.
             */
            if (Date.now() - x.timestamp > NativeCardServiceUpdateInterval) {
                logger.debug('card removed', x.card.name, x.card.atr.toString('hex'));
                this.deviceSubject.next({ device: x.card.device, status: 'detach' });
                this.device.delete(y);
            }
        }));

        logger.debug('create nfc service success');
    }