Skip to content

Commit

Permalink
Name a type
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilkybarkid committed Nov 30, 2023
1 parent 9a811c2 commit edef405
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 33 deletions.
6 changes: 3 additions & 3 deletions src/Decision.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Data } from 'effect'
import type { Doi } from './Doi.js'
import type { OrcidId } from './OrcidId.js'
import type { User } from './Users.js'

export type Decision = Data.TaggedEnum<{
AddReviewToProfile: { orcidId: OrcidId; doi: Doi }
RemoveReviewFromProfile: { orcidId: OrcidId; doi: Doi }
AddReviewToProfile: { user: User; doi: Doi }
RemoveReviewFromProfile: { user: User; doi: Doi }
}>

export const { AddReviewToProfile, RemoveReviewFromProfile } = Data.taggedEnum<Decision>()
27 changes: 12 additions & 15 deletions src/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { Effect, Match, ReadonlyArray, Stream, flow } from 'effect'
import * as Decision from './Decision.js'
import type * as Doi from './Doi.js'
import * as Orcid from './Orcid.js'
import type * as OrcidId from './OrcidId.js'
import * as Users from './Users.js'
import * as Zenodo from './Zenodo.js'

const getPeerReviewsDoisForOrcidId = flow(
Orcid.getPeerReviewsForOrcidId,
(user: Users.User) => Orcid.getPeerReviewsForOrcidId(user.orcidId),
Effect.flatMap(
ReadonlyArray.findFirst(
group => group['external-ids']['external-id'][0]['external-id-value'] === 'orcid-generated:prereview',
Expand All @@ -31,7 +30,7 @@ const getPeerReviewsDoisForOrcidId = flow(
)

const getPeerReviewsOnZenodoForOrcidId = flow(
Zenodo.getReviewsByOrcidId,
(user: Users.User) => Zenodo.getReviewsByOrcidId(user.orcidId),
Effect.tap(reviews =>
Effect.gen(function* (_) {
if (reviews.total < 1) {
Expand All @@ -44,34 +43,32 @@ const getPeerReviewsOnZenodoForOrcidId = flow(
)

const makeDecisions = ({
orcidId,
user,
zenodoReviews,
orcidReviews,
}: {
orcidId: OrcidId.OrcidId
user: Users.User
zenodoReviews: ReadonlyArray<Doi.Doi>
orcidReviews: ReadonlyArray<Doi.Doi>
}) =>
ReadonlyArray.union(
ReadonlyArray.difference(zenodoReviews, orcidReviews).map(doi => Decision.AddReviewToProfile({ orcidId, doi })),
ReadonlyArray.difference(orcidReviews, zenodoReviews).map(doi =>
Decision.RemoveReviewFromProfile({ orcidId, doi }),
),
ReadonlyArray.difference(zenodoReviews, orcidReviews).map(doi => Decision.AddReviewToProfile({ user, doi })),
ReadonlyArray.difference(orcidReviews, zenodoReviews).map(doi => Decision.RemoveReviewFromProfile({ user, doi })),
)

const processUser = ({ orcidId, accessToken }: { orcidId: OrcidId.OrcidId; accessToken: string }) =>
const processUser = (user: Users.User) =>
Effect.gen(function* (_) {
yield* _(Effect.logInfo('Processing user'))

const decisions = yield* _(
Effect.all(
{
zenodoReviews: getPeerReviewsOnZenodoForOrcidId(orcidId),
orcidReviews: getPeerReviewsDoisForOrcidId(orcidId),
zenodoReviews: getPeerReviewsOnZenodoForOrcidId(user),
orcidReviews: getPeerReviewsDoisForOrcidId(user),
},
{ concurrency: 'inherit' },
).pipe(
Effect.let('orcidId', () => orcidId),
Effect.let('user', () => user),
Effect.map(makeDecisions),
),
)
Expand All @@ -92,8 +89,8 @@ const processUser = ({ orcidId, accessToken }: { orcidId: OrcidId.OrcidId; acces
),
)
}).pipe(
Effect.annotateLogs('orcidId', orcidId),
Effect.provideService(Orcid.OrcidAccessToken, { token: accessToken }),
Effect.annotateLogs('orcidId', user.orcidId),
Effect.provideService(Orcid.OrcidAccessToken, { token: user.accessToken }),
)

export const program = Users.getUsers.pipe(Stream.runForEach(processUser)).pipe(Effect.scoped)
35 changes: 20 additions & 15 deletions src/Users.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { type ParseResult, Schema } from '@effect/schema'
import { Effect, ReadonlyArray, type Scope, Stream, String, flow, identity } from 'effect'
import { Data, Effect, ReadonlyArray, type Scope, Stream, String, flow, identity } from 'effect'
import * as OrcidId from './OrcidId.js'
import * as Redis from './Redis.js'

export const getUsers: Stream.Stream<
Redis.Redis | Scope.Scope,
Redis.RedisError | ParseResult.ParseError,
{ orcidId: OrcidId.OrcidId; accessToken: string }
> = Redis.scanStream({
match: 'orcid-token:*',
}).pipe(
Stream.mapConcat(identity),
Stream.map(String.split(':')),
Stream.map(ReadonlyArray.lastNonEmpty),
Stream.flatMap(Schema.decodeEither(OrcidId.OrcidIdSchema)),
Stream.bindTo('orcidId'),
Stream.bind('accessToken', ({ orcidId }) => getAccessToken(orcidId)),
)
export interface User extends Data.Case {
readonly orcidId: OrcidId.OrcidId
readonly accessToken: string
}

export const User = Data.case<User>()

export const getUsers: Stream.Stream<Redis.Redis | Scope.Scope, Redis.RedisError | ParseResult.ParseError, User> =
Redis.scanStream({
match: 'orcid-token:*',
}).pipe(
Stream.mapConcat(identity),
Stream.map(String.split(':')),
Stream.map(ReadonlyArray.lastNonEmpty),
Stream.flatMap(Schema.decodeEither(OrcidId.OrcidIdSchema)),
Stream.bindTo('orcidId'),
Stream.bind('accessToken', ({ orcidId }) => getAccessToken(orcidId)),
Stream.map(User),
)

const OrcidTokenSchema = Schema.struct({ value: Schema.struct({ accessToken: Schema.string }) })

Expand Down

0 comments on commit edef405

Please sign in to comment.