<commit_before>const chalk = require('chalk')
const { filter, ignoreElements, map, mergeMap, switchMap, tap, zip } = require('rxjs/operators')
const { bindNodeCallback, forkJoin, from } = require('rxjs')
const { ofType } = require('redux-observable')

const { lightIdsSelector } = require('./selectors')
const { networkLightSelector } = require('$redux/lights/selectors')
const { POWERED_ON } = require('$redux/lifxNetwork/utils/constants')
const { stateSelector } = require('@ghadyani-framework/redux-utils')
const { TOGGLE_GROUP } = require('./actions')

const duration = 500

const isLightOnInGroup = (
	lightsInGroup => (
		lightsInGroup
		.some(({ power }) => (
			power === POWERED_ON
		))
	)
)

const changeLightPower = (
	powerFuncName => ({ light }) => (
		bindNodeCallback(
			light[powerFuncName]
			.bind(light)
		)(
			duration,
		)
	)
)

const turnOffLight = changeLightPower('off')
const turnOnLight = changeLightPower('on')

const toggleGroupEpic = (
	(action$, state$) => (
		action$
		.pipe(
			ofType(TOGGLE_GROUP),
			tap(console.info),
			mergeMap(({ groupName }) => (
				stateSelector({
					props: { groupName },
					selector: lightIdsSelector,
					state$,
				})
				.pipe(
					tap(lightIds => (
						(
							!lightIds
							|| !lightIds.length
						)
						&& (
							console
							.warn(
								chalk
								.redBright(
									'[MISSING GROUP]'
								)
								.concat(' ')
								.concat(
									chalk
									.bgRed(
										groupName
									)
								)
							)
						)
					)),
				)
			)),
			filter(Boolean),
			map(lightIds => (
				Array
				.from(lightIds)
			)),
			mergeMap(lightIds => (
				forkJoin(
					...(
						lightIds
						.map(lightId => (
							// NEED TO HANDLE ERRORS IN HERE
							// OTHERWISE ONE ERROR WILL KILL THE ENTIRE FORKJOIN
							stateSelector({
								props: { lightId },
								selector: networkLightSelector,
								state$,
							})
							.pipe(
								filter(Boolean),
								switchMap(light => (
									// console.log(light.client.light(light.id))||
									bindNodeCallback(
										light
										.getPower
										.bind(light)
									)()
									.pipe(
										map(power => (console.log({power})||{
											light,
											power,
										}))
									)
								)),
							)
						))
						// from(lightIds)
						// .pipe(
						// 	map(lightId => (
						// 		stateSelector({
						// 			props: { lightId },
						// 			selector: networkLightSelector,
						// 			state$,
						// 		})
						// 	)),
						// )
					)
				)
			)),
			// tap(console.log),
			tap(t => console.log(t.length)),
			mergeMap(lightsInGroup => (
				isLightOnInGroup(lightsInGroup)
				? (
					lightsInGroup
					.map(turnOffLight)
				)
				: (
					lightsInGroup
					.map(turnOnLight)
				)
			)),
			tap(console.log),
			// mergeMap(lights => (
			// 	lights
			// )),
			mergeMap(light => (
				light<commit_msg>Improved latency of toggling light groups<commit_after>const chalk = require('chalk')
const { bindNodeCallback, forkJoin } = require('rxjs')
const { filter, ignoreElements, map, mergeMap, switchMap, takeUntil, tap } = require('rxjs/operators')
const { ofType } = require('redux-observable')

const { lightIdsSelector } = require('./selectors')
const { networkLightSelector } = require('$redux/lights/selectors')
const { POWERED_ON } = require('$redux/lifxNetwork/utils/constants')
const { stateSelector } = require('@ghadyani-framework/redux-utils')
const { TOGGLE_GROUP } = require('./actions')

const duration = 500

const isLightOnInGroup = (
	lightsInGroup => (
		lightsInGroup
		.some(({ power }) => (
			power === POWERED_ON
		))
	)
)

const changeLightPower = (
	powerFuncName => ({ light }) => (
		bindNodeCallback(
			light[powerFuncName]
			.bind(light)
		)(
			duration,
		)
	)
)

const turnOffLight = changeLightPower('off')
const turnOnLight = changeLightPower('on')

const toggleGroupEpic = (
	(action$, state$) => (
		action$
		.pipe(
			ofType(TOGGLE_GROUP),
			tap(console.info),
			mergeMap(({ groupName }) => (
				stateSelector({
					props: { groupName },
					selector: lightIdsSelector,
					state$,
				})
				.pipe(
					takeUntil(
						action$
						.pipe(
							ofType(TOGGLE_GROUP),
							filter(action => (
								action.groupName === groupName
							))
						)
					),
					tap(lightIds => (
						(
							!lightIds
							|| !lightIds.length
						)
						&& (
							console
							.warn(
								chalk
								.redBright(
									'[MISSING GROUP]'
								)
								.concat(' ')
								.concat(
									chalk
									.bgRed(
										groupName
									)
								)
							)
						)
					)),
				)
			)),
			filter(Boolean),
			map(lightIds => (
				Array
				.from(lightIds)
			)),
			mergeMap(lightIds => (
				forkJoin(
					...(
						lightIds
						.map(lightId => (
							// NEED TO HANDLE ERRORS IN HERE
							// OTHERWISE ONE ERROR WILL KILL THE ENTIRE FORKJOIN
							stateSelector({
								props: { lightId },
								selector: networkLightSelector,
								state$,
							})
							.pipe(
								filter(Boolean),
								switchMap(light => (
									// console.log(light.client.light(light.id))||
									bindNodeCallback(
										light
										.getPower
										.bind(light)
									)()
									.pipe(
										map(power => (console.log({power})||{
											light,
											power,
										}))
									)
								)),
							)
						))
						// from(lightIds)
						// .pipe(
						// 	map(lightId => (
						// 		stateSelector({
						// 			props: { lightId },
						// 			selector: networkLightSelector,
						// 			state$,
						// 		})
						// 	)),
						// )
					)
				)
			)),
			// tap(console.log),
			tap(t => console.log(t.length)),
			mergeMap(lightsInGroup => (
				isLightOnInGroup(lightsInGroup)
				? (
					lightsInGroup
					.map(turnOffLight)
				)
				: (
					lightsInGroup
					.map(turnOnLight)
				)
			)),
			// tap(console.log),
			mergeMap(light$ => (
				light$
{'fraction_non_alphanumeric': 0.14641484205248204, 'fraction_numerical': 0.0010028413839211097, 'mean_word_length': 1.827977315689981, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '102579', 'n_tokens_mistral': 3049, 'n_tokens_neox': 1928, 'n_words': 318}