Created
July 8, 2023 16:10
-
-
Save artalar/0a0f8d6043ad5cbe3e0d31828ee8f15b to your computer and use it in GitHub Desktop.
some effector VS reatom
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { $corsProxyEnabled } from '@/src/entities/cors-proxy/model/store' | |
import { checkInstanceUrl } from '@/src/features/instance/api/check' | |
import { InstanceCheckResult } from '@/src/features/instance/model/model' | |
import { BuildConfig } from '@/src/shared/model/build-config' | |
import { | |
combine, | |
createEffect, | |
createEvent, | |
createStore, | |
restore, | |
sample, | |
} from 'effector' | |
import { delay, snapshot, spread } from 'patronum' | |
export const instanceUrlChanged = createEvent<string>() | |
export const $instanceUrl = restore( | |
instanceUrlChanged, | |
BuildConfig.defaultInstanceUrl, | |
) | |
export const instanceCheckStarted = createEvent() | |
export const checkAndSaveInstanceFx = createEffect(checkInstanceUrl) | |
export const $checkResult = createStore<InstanceCheckResult | null>(null) | |
export const $checkError = restore(checkAndSaveInstanceFx.failData, null) | |
export const $editorShowOverlay = createStore(false) | |
export const editorOpened = createEvent() | |
export const editorCancelled = createEvent() | |
export const editorSaveStarted = createEvent() | |
export const editorSaveSucceeded = createEvent() | |
export const $editorEditing = createStore(false) | |
$editorEditing.on(editorOpened, () => true) | |
$editorEditing.on([editorCancelled, editorSaveSucceeded], () => false) | |
export const $beforeEditorSnapshot = snapshot({ | |
source: combine({ | |
url: $instanceUrl, | |
result: $checkResult, | |
error: $checkError, | |
}), | |
clock: editorOpened, | |
}) | |
sample({ | |
clock: editorOpened, | |
fn: () => null, | |
target: [$checkResult, $checkError], | |
}) | |
sample({ | |
source: $instanceUrl, | |
clock: [instanceCheckStarted, editorSaveStarted], | |
target: checkAndSaveInstanceFx, | |
}) | |
sample({ | |
clock: editorSaveStarted, | |
fn: () => true, | |
target: $editorShowOverlay, | |
}) | |
sample({ | |
source: $corsProxyEnabled, | |
clock: checkAndSaveInstanceFx.doneData, | |
fn: (corsEnabled, data) => { | |
if (corsEnabled || !data.cors) { | |
return { ok: data } | |
} | |
return { | |
error: new Error('This instance requires the use of CORS Proxy'), | |
} | |
}, | |
target: spread({ | |
targets: { | |
ok: $checkResult, | |
error: $checkError, | |
}, | |
}), | |
}) | |
const editorCheckSucceeded = sample({ | |
source: $editorEditing, | |
clock: $checkResult, | |
filter: (editing, result) => result !== null && editing, | |
}) | |
sample({ | |
clock: delay({ | |
source: editorCheckSucceeded, | |
timeout: 2500, | |
}), | |
target: editorSaveSucceeded, | |
}) | |
const editorCheckErrored = sample({ | |
source: $editorEditing, | |
clock: $checkError, | |
filter: (editing, error) => error !== null && editing, | |
}) | |
sample({ | |
clock: delay({ | |
source: editorCheckErrored, | |
timeout: 2500, | |
}), | |
fn: () => ({ | |
null: null, | |
false: false, | |
}), | |
target: spread({ | |
targets: { | |
null: $checkError, | |
false: $editorShowOverlay, | |
}, | |
}), | |
}) | |
sample({ | |
clock: [editorCancelled, editorSaveSucceeded], | |
fn: () => false, | |
target: $editorShowOverlay, | |
}) | |
sample({ | |
clock: editorCancelled, | |
source: $beforeEditorSnapshot, | |
target: spread({ | |
targets: { | |
url: $instanceUrl, | |
error: $checkError, | |
result: $checkResult, | |
}, | |
}), | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { corsProxyEnabledAtom } from '@/src/entities/cors-proxy/model/store' | |
import { checkInstanceUrl } from '@/src/features/instance/api/check' | |
import { InstanceCheckResult } from '@/src/features/instance/model/model' | |
import { BuildConfig } from '@/src/shared/model/build-config' | |
import { | |
action, | |
atom, | |
reatomAsync, | |
sleep, | |
withDataAtom, | |
withErrorAtom, | |
} from '@reatom/framework' | |
export const instanceUrlAtom = atom( | |
BuildConfig.defaultInstanceUrl, | |
'instanceUrlAtom', | |
) | |
export const editorShowOverlayAtom = atom(false, 'editorShowOverlayAtom') | |
export const editorEditingAtom = atom(false, 'editorEditingAtom') | |
export const beforeEditorSnapshotAtom = atom( | |
{ | |
url: '', | |
result: null as null | InstanceCheckResult, | |
error: undefined as undefined | Error, | |
}, | |
'beforeEditorSnapshotAtom', | |
) | |
export const checkAndSaveInstance = reatomAsync(async (ctx) => { | |
const corsEnabled = ctx.get(corsProxyEnabledAtom) | |
const data = await checkInstanceUrl(ctx.get(instanceUrlAtom)) | |
if (corsEnabled || !data.cors) return data | |
throw new Error('This instance requires the use of CORS Proxy') | |
}, 'checkAndSaveInstance').pipe(withDataAtom(null), withErrorAtom()) | |
export const instanceCheckStarted = action((ctx) => { | |
checkAndSaveInstance(ctx) | |
}, 'instanceCheckStarted') | |
export const editorOpened = action((ctx) => { | |
editorEditingAtom(ctx, true) | |
beforeEditorSnapshotAtom(ctx, { | |
url: ctx.get(instanceUrlAtom), | |
result: ctx.get(checkAndSaveInstance.dataAtom), | |
error: ctx.get(checkAndSaveInstance.errorAtom), | |
}) | |
checkAndSaveInstance.dataAtom.reset(ctx) | |
checkAndSaveInstance.errorAtom.reset(ctx) | |
}, 'editorOpened') | |
export const editorCancelled = action((ctx) => { | |
editorEditingAtom(ctx, false) | |
editorShowOverlayAtom(ctx, false) | |
const { url, result, error } = ctx.get(beforeEditorSnapshotAtom) | |
instanceUrlAtom(ctx, url) | |
checkAndSaveInstance.dataAtom(ctx, result) | |
checkAndSaveInstance.errorAtom(ctx, error) | |
}, 'editorCancelled') | |
export const editorSaveStarted = action((ctx) => { | |
editorShowOverlayAtom(ctx, true) | |
checkAndSaveInstance(ctx) | |
}, 'editorSaveStarted') | |
export const editorSaveSucceeded = action((ctx) => { | |
editorEditingAtom(ctx, false) | |
editorShowOverlayAtom(ctx, false) | |
}, 'editorSaveSucceeded') | |
checkAndSaveInstance.dataAtom.onChange(async (ctx, result) => { | |
const editorEditing = ctx.get(editorEditingAtom) | |
if (result !== null && editorEditing) { | |
await ctx.schedule(async () => await sleep(2500)) | |
editorSaveSucceeded(ctx) | |
} | |
}) | |
checkAndSaveInstance.errorAtom.onChange(async (ctx, error) => { | |
const editorEditing = ctx.get(editorEditingAtom) | |
if (error !== null && editorEditing) { | |
await ctx.schedule(async () => await sleep(2500)) | |
checkAndSaveInstance.errorAtom.reset(ctx) | |
editorShowOverlayAtom(ctx, false) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment