Change lodash stuff so that it can be tree-shaken out of build (#233)

* Set common package.json sideEffects: false

* Configure SWC to modularize lodash imports

* Import specific lodash functions instead of _

* Add an eslint rule to avoid full lodash import
This commit is contained in:
Marshall Polaris 2022-05-22 01:36:05 -07:00 committed by GitHub
parent 0803a15902
commit 47f10301c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 378 additions and 382 deletions

View File

@ -1,4 +1,5 @@
module.exports = {
plugins: ['lodash'],
extends: ['eslint:recommended'],
env: {
browser: true,
@ -14,5 +15,6 @@ module.exports = {
rules: {
'no-unused-vars': 'off',
'no-constant-condition': ['error', { checkLoops: false }],
'lodash/import-scope': [2, 'member'],
},
}

View File

@ -1,3 +1,4 @@
import { range } from 'lodash'
import { Bet, NumericBet } from './bet'
import { getDpmProbability, getValueFromBucket } from './calculate-dpm'
import {
@ -11,7 +12,6 @@ import {
import { User } from './user'
import { LiquidityProvision } from './liquidity-provision'
import { noFees } from './fees'
import * as _ from 'lodash'
export const FIXED_ANTE = 100
@ -127,11 +127,11 @@ export function getNumericAnte(
const betShares = Math.sqrt(ante ** 2 / bucketCount)
const allOutcomeShares = Object.fromEntries(
_.range(0, bucketCount).map((_, i) => [i, betShares])
range(0, bucketCount).map((_, i) => [i, betShares])
)
const allBetAmounts = Object.fromEntries(
_.range(0, bucketCount).map((_, i) => [i, betAnte])
range(0, bucketCount).map((_, i) => [i, betAnte])
)
const anteBet: NumericBet = {

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { sum, groupBy, mapValues, sumBy } from 'lodash'
import { Binary, CPMM, FullContract } from './contract'
import { CREATOR_FEE, Fees, LIQUIDITY_FEE, noFees, PLATFORM_FEE } from './fees'
@ -278,16 +278,16 @@ export function getCpmmLiquidityPoolWeights(
return liquidity
})
const shareSum = _.sum(liquidityShares)
const shareSum = sum(liquidityShares)
const weights = liquidityShares.map((s, i) => ({
weight: s / shareSum,
providerId: liquidities[i].userId,
}))
const userWeights = _.groupBy(weights, (w) => w.providerId)
const totalUserWeights = _.mapValues(userWeights, (userWeight) =>
_.sumBy(userWeight, (w) => w.weight)
const userWeights = groupBy(weights, (w) => w.providerId)
const totalUserWeights = mapValues(userWeights, (userWeight) =>
sumBy(userWeight, (w) => w.weight)
)
return totalUserWeights
}

View File

@ -1,5 +1,4 @@
import * as _ from 'lodash'
import { cloneDeep, range, sum, sumBy, sortBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet'
import {
Binary,
@ -24,7 +23,7 @@ export function getDpmOutcomeProbability(
},
outcome: string
) {
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
const shares = totalShares[outcome] ?? 0
return shares ** 2 / squareSum
}
@ -32,8 +31,8 @@ export function getDpmOutcomeProbability(
export function getDpmOutcomeProbabilities(totalShares: {
[outcome: string]: number
}) {
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
return _.mapValues(totalShares, (shares) => shares ** 2 / squareSum)
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
return mapValues(totalShares, (shares) => shares ** 2 / squareSum)
}
export function getNumericBets(
@ -44,20 +43,20 @@ export function getNumericBets(
) {
const { bucketCount } = contract
const bucketNumber = parseInt(bucket)
const buckets = _.range(0, bucketCount)
const buckets = range(0, bucketCount)
const mean = bucketNumber / bucketCount
const allDensities = buckets.map((i) =>
normpdf(i / bucketCount, mean, variance)
)
const densitySum = _.sum(allDensities)
const densitySum = sum(allDensities)
const rawBetAmounts = allDensities
.map((d) => (d / densitySum) * betAmount)
.map((x) => (x >= 1 / bucketCount ? x : 0))
const rawSum = _.sum(rawBetAmounts)
const rawSum = sum(rawBetAmounts)
const scaledBetAmounts = rawBetAmounts.map((x) => (x / rawSum) * betAmount)
const bets = scaledBetAmounts
@ -90,26 +89,24 @@ export const getValueFromBucket = (
export const getExpectedValue = (contract: NumericContract) => {
const { bucketCount, min, max, totalShares } = contract
const totalShareSum = _.sumBy(
const totalShareSum = sumBy(
Object.values(totalShares),
(shares) => shares ** 2
)
const probs = _.range(0, bucketCount).map(
const probs = range(0, bucketCount).map(
(i) => totalShares[i] ** 2 / totalShareSum
)
const values = _.range(0, bucketCount).map(
const values = range(0, bucketCount).map(
(i) =>
// use mid point within bucket
0.5 * (min + (i / bucketCount) * (max - min)) +
0.5 * (min + ((i + 1) / bucketCount) * (max - min))
)
const weightedValues = _.range(0, bucketCount).map(
(i) => probs[i] * values[i]
)
const weightedValues = range(0, bucketCount).map((i) => probs[i] * values[i])
const expectation = _.sum(weightedValues)
const expectation = sum(weightedValues)
const rounded = Math.round(expectation * 1e2) / 1e2
return rounded
}
@ -150,7 +147,7 @@ export function calculateDpmShares(
bet: number,
betChoice: string
) {
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
const squareSum = sumBy(Object.values(totalShares), (shares) => shares ** 2)
const shares = totalShares[betChoice] ?? 0
const c = 2 * bet * Math.sqrt(squareSum)
@ -166,9 +163,9 @@ export function calculateNumericDpmShares(
) {
const shares: number[] = []
totalShares = _.cloneDeep(totalShares)
totalShares = cloneDeep(totalShares)
const order = _.sortBy(
const order = sortBy(
bets.map(([, amount], i) => [amount, i]),
([amount]) => amount
).map(([, i]) => i)
@ -190,11 +187,11 @@ export function calculateDpmRawShareValue(
betChoice: string
) {
const currentValue = Math.sqrt(
_.sumBy(Object.values(totalShares), (shares) => shares ** 2)
sumBy(Object.values(totalShares), (shares) => shares ** 2)
)
const postSaleValue = Math.sqrt(
_.sumBy(Object.keys(totalShares), (outcome) =>
sumBy(Object.keys(totalShares), (outcome) =>
outcome === betChoice
? Math.max(0, totalShares[outcome] - shares) ** 2
: totalShares[outcome] ** 2
@ -214,12 +211,12 @@ export function calculateDpmMoneyRatio(
const p = getDpmOutcomeProbability(totalShares, outcome)
const actual = _.sum(Object.values(pool)) - shareValue
const actual = sum(Object.values(pool)) - shareValue
const betAmount = p * amount
const expected =
_.sumBy(
sumBy(
Object.keys(totalBets),
(outcome) =>
getDpmOutcomeProbability(totalShares, outcome) *
@ -271,8 +268,8 @@ export function calculateDpmCancelPayout(
bet: Bet
) {
const { totalBets, pool } = contract
const betTotal = _.sum(Object.values(totalBets))
const poolTotal = _.sum(Object.values(pool))
const betTotal = sum(Object.values(totalBets))
const poolTotal = sum(Object.values(pool))
return (bet.amount / betTotal) * poolTotal
}
@ -295,7 +292,7 @@ export function calculateStandardDpmPayout(
const { totalShares, phantomShares, pool } = contract
if (!totalShares[outcome]) return 0
const poolTotal = _.sum(Object.values(pool))
const poolTotal = sum(Object.values(pool))
const total =
totalShares[outcome] - (phantomShares ? phantomShares[outcome] : 0)
@ -356,19 +353,19 @@ function calculateMktDpmPayout(
let probs: { [outcome: string]: number }
if (resolutions) {
const probTotal = _.sum(Object.values(resolutions))
probs = _.mapValues(
const probTotal = sum(Object.values(resolutions))
probs = mapValues(
totalShares,
(_, outcome) => (resolutions[outcome] ?? 0) / probTotal
)
} else {
const squareSum = _.sum(
const squareSum = sum(
Object.values(totalShares).map((shares) => shares ** 2)
)
probs = _.mapValues(totalShares, (shares) => shares ** 2 / squareSum)
probs = mapValues(totalShares, (shares) => shares ** 2 / squareSum)
}
const weightedShareTotal = _.sumBy(Object.keys(totalShares), (outcome) => {
const weightedShareTotal = sumBy(Object.keys(totalShares), (outcome) => {
return probs[outcome] * totalShares[outcome]
})
@ -376,7 +373,7 @@ function calculateMktDpmPayout(
const poolFrac =
outcomeType === 'NUMERIC'
? _.sumBy(
? sumBy(
Object.keys((bet as NumericBet).allOutcomeShares ?? {}),
(outcome) => {
return (
@ -387,7 +384,7 @@ function calculateMktDpmPayout(
)
: (probs[outcome] * shares) / weightedShareTotal
const totalPool = _.sum(Object.values(pool))
const totalPool = sum(Object.values(pool))
const winnings = poolFrac * totalPool
return deductDpmFees(amount, winnings)
}

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { maxBy } from 'lodash'
import { Bet } from './bet'
import {
calculateCpmmSale,
@ -180,7 +180,7 @@ export function getContractBetNullMetrics() {
export function getTopAnswer(contract: FreeResponseContract) {
const { answers } = contract
const top = _.maxBy(
const top = maxBy(
answers?.map((answer) => ({
answer,
prob: getOutcomeProbability(contract, answer.id),

View File

@ -1,4 +1,3 @@
import * as _ from 'lodash'
import { Answer } from './answer'
import { Fees } from './fees'

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { sumBy } from 'lodash'
import { Bet, MAX_LOAN_PER_CONTRACT, NumericBet } from './bet'
import {
@ -210,7 +210,7 @@ export const getNumericBetsInfo = (
export const getLoanAmount = (yourBets: Bet[], newBetAmount: number) => {
const openBets = yourBets.filter((bet) => !bet.isSold && !bet.sale)
const prevLoanAmount = _.sumBy(openBets, (bet) => bet.loanAmount ?? 0)
const prevLoanAmount = sumBy(openBets, (bet) => bet.loanAmount ?? 0)
const loanAmount = Math.min(
newBetAmount,
MAX_LOAN_PER_CONTRACT - prevLoanAmount

View File

@ -1,5 +1,4 @@
import * as _ from 'lodash'
import { range } from 'lodash'
import { PHANTOM_ANTE } from './antes'
import {
Binary,
@ -131,7 +130,7 @@ const getNumericProps = (
min: number,
max: number
) => {
const buckets = _.range(0, bucketCount).map((i) => i.toString())
const buckets = range(0, bucketCount).map((i) => i.toString())
const betAnte = ante / bucketCount
const pool = Object.fromEntries(buckets.map((answer) => [answer, betAnte]))

View File

@ -3,6 +3,7 @@
"version": "1.0.0",
"private": true,
"scripts": {},
"sideEffects": false,
"dependencies": {
"lodash": "4.17.21"
},

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { sum, groupBy, sumBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet'
import { deductDpmFees, getDpmProbability } from './calculate-dpm'
@ -17,10 +17,10 @@ export const getDpmCancelPayouts = (
bets: Bet[]
) => {
const { pool } = contract
const poolTotal = _.sum(Object.values(pool))
const poolTotal = sum(Object.values(pool))
console.log('resolved N/A, pool M$', poolTotal)
const betSum = _.sumBy(bets, (b) => b.amount)
const betSum = sumBy(bets, (b) => b.amount)
const payouts = bets.map((bet) => ({
userId: bet.userId,
@ -42,8 +42,8 @@ export const getDpmStandardPayouts = (
) => {
const winningBets = bets.filter((bet) => bet.outcome === outcome)
const poolTotal = _.sum(Object.values(contract.pool))
const totalShares = _.sumBy(winningBets, (b) => b.shares)
const poolTotal = sum(Object.values(contract.pool))
const totalShares = sumBy(winningBets, (b) => b.shares)
const payouts = winningBets.map(({ userId, amount, shares }) => {
const winnings = (shares / totalShares) * poolTotal
@ -54,7 +54,7 @@ export const getDpmStandardPayouts = (
return { userId, profit, payout }
})
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
const creatorFee = DPM_CREATOR_FEE * profits
const platformFee = DPM_PLATFORM_FEE * profits
@ -93,10 +93,10 @@ export const getNumericDpmPayouts = (
contract: FullContract<DPM, any>,
bets: NumericBet[]
) => {
const totalShares = _.sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0)
const totalShares = sumBy(bets, (bet) => bet.allOutcomeShares[outcome] ?? 0)
const winningBets = bets.filter((bet) => !!bet.allOutcomeShares[outcome])
const poolTotal = _.sum(Object.values(contract.pool))
const poolTotal = sum(Object.values(contract.pool))
const payouts = winningBets.map(
({ userId, allBetAmounts, allOutcomeShares }) => {
@ -112,7 +112,7 @@ export const getNumericDpmPayouts = (
}
)
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
const creatorFee = DPM_CREATOR_FEE * profits
const platformFee = DPM_PLATFORM_FEE * profits
@ -156,7 +156,7 @@ export const getDpmMktPayouts = (
? getDpmProbability(contract.totalShares)
: resolutionProbability
const weightedShareTotal = _.sumBy(bets, (b) =>
const weightedShareTotal = sumBy(bets, (b) =>
b.outcome === 'YES' ? p * b.shares : (1 - p) * b.shares
)
@ -170,7 +170,7 @@ export const getDpmMktPayouts = (
return { userId, profit, payout }
})
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
const profits = sumBy(payouts, (po) => Math.max(0, po.profit))
const creatorFee = DPM_CREATOR_FEE * profits
const platformFee = DPM_PLATFORM_FEE * profits
@ -210,15 +210,15 @@ export const getPayoutsMultiOutcome = (
contract: FullContract<DPM, Multi | FreeResponse>,
bets: Bet[]
) => {
const poolTotal = _.sum(Object.values(contract.pool))
const poolTotal = sum(Object.values(contract.pool))
const winningBets = bets.filter((bet) => resolutions[bet.outcome])
const betsByOutcome = _.groupBy(winningBets, (bet) => bet.outcome)
const sharesByOutcome = _.mapValues(betsByOutcome, (bets) =>
_.sumBy(bets, (bet) => bet.shares)
const betsByOutcome = groupBy(winningBets, (bet) => bet.outcome)
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
sumBy(bets, (bet) => bet.shares)
)
const probTotal = _.sum(Object.values(resolutions))
const probTotal = sum(Object.values(resolutions))
const payouts = winningBets.map(({ userId, outcome, amount, shares }) => {
const prob = resolutions[outcome] / probTotal
@ -229,7 +229,7 @@ export const getPayoutsMultiOutcome = (
return { userId, profit, payout }
})
const profits = _.sumBy(payouts, (po) => po.profit)
const profits = sumBy(payouts, (po) => po.profit)
const creatorFee = DPM_CREATOR_FEE * profits
const platformFee = DPM_PLATFORM_FEE * profits

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { sum } from 'lodash'
import { Bet } from './bet'
import { getProbability } from './calculate'
@ -50,7 +50,7 @@ export const getStandardFixedPayouts = (
'pool',
contract.pool[outcome],
'payouts',
_.sum(payouts),
sum(payouts),
'creator fee',
creatorPayout
)
@ -105,7 +105,7 @@ export const getMktFixedPayouts = (
'pool',
p * contract.pool.YES + (1 - p) * contract.pool.NO,
'payouts',
_.sum(payouts),
sum(payouts),
'creator fee',
creatorPayout
)

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { sumBy, groupBy, mapValues } from 'lodash'
import { Bet, NumericBet } from './bet'
import {
@ -32,16 +32,19 @@ export type Payout = {
export const getLoanPayouts = (bets: Bet[]): Payout[] => {
const betsWithLoans = bets.filter((bet) => bet.loanAmount)
const betsByUser = _.groupBy(betsWithLoans, (bet) => bet.userId)
const loansByUser = _.mapValues(betsByUser, (bets) =>
_.sumBy(bets, (bet) => -(bet.loanAmount ?? 0))
const betsByUser = groupBy(betsWithLoans, (bet) => bet.userId)
const loansByUser = mapValues(betsByUser, (bets) =>
sumBy(bets, (bet) => -(bet.loanAmount ?? 0))
)
return _.toPairs(loansByUser).map(([userId, payout]) => ({ userId, payout }))
return Object.entries(loansByUser).map(([userId, payout]) => ({
userId,
payout,
}))
}
export const groupPayoutsByUser = (payouts: Payout[]) => {
const groups = _.groupBy(payouts, (payout) => payout.userId)
return _.mapValues(groups, (group) => _.sumBy(group, (g) => g.payout))
const groups = groupBy(payouts, (payout) => payout.userId)
return mapValues(groups, (group) => sumBy(group, (g) => g.payout))
}
export type PayoutInfo = {

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { union, sum, sumBy, sortBy, groupBy, mapValues } from 'lodash'
import { Bet } from './bet'
import { Contract } from './contract'
import { ClickEvent } from './tracking'
@ -21,13 +21,13 @@ export const getRecommendedContracts = (
const yourWordFrequency = contractsToWordFrequency(yourContracts)
const otherWordFrequency = contractsToWordFrequency(notYourContracts)
const words = _.union(
const words = union(
Object.keys(yourWordFrequency),
Object.keys(otherWordFrequency)
)
const yourWeightedFrequency = _.fromPairs(
_.map(words, (word) => {
const yourWeightedFrequency = Object.fromEntries(
words.map((word) => {
const [yourFreq, otherFreq] = [
yourWordFrequency[word] ?? 0,
otherWordFrequency[word] ?? 0,
@ -47,7 +47,7 @@ export const getRecommendedContracts = (
const scoredContracts = contracts.map((contract) => {
const wordFrequency = contractToWordFrequency(contract)
const score = _.sumBy(Object.keys(wordFrequency), (word) => {
const score = sumBy(Object.keys(wordFrequency), (word) => {
const wordFreq = wordFrequency[word] ?? 0
const weight = yourWeightedFrequency[word] ?? 0
return wordFreq * weight
@ -59,7 +59,7 @@ export const getRecommendedContracts = (
}
})
return _.sortBy(scoredContracts, (scored) => -scored.score).map(
return sortBy(scoredContracts, (scored) => -scored.score).map(
(scored) => scored.contract
)
}
@ -87,8 +87,8 @@ const getWordsCount = (text: string) => {
}
const toFrequency = (counts: { [word: string]: number }) => {
const total = _.sum(Object.values(counts))
return _.mapValues(counts, (count) => count / total)
const total = sum(Object.values(counts))
return mapValues(counts, (count) => count / total)
}
const contractToWordFrequency = (contract: Contract) =>
@ -108,8 +108,8 @@ export const getWordScores = (
clicks: ClickEvent[],
bets: Bet[]
) => {
const contractClicks = _.groupBy(clicks, (click) => click.contractId)
const contractBets = _.groupBy(bets, (bet) => bet.contractId)
const contractClicks = groupBy(clicks, (click) => click.contractId)
const contractBets = groupBy(bets, (bet) => bet.contractId)
const yourContracts = contracts.filter(
(c) =>
@ -117,25 +117,22 @@ export const getWordScores = (
)
const yourTfIdf = calculateContractTfIdf(yourContracts)
const contractWordScores = _.mapValues(
yourTfIdf,
(wordsTfIdf, contractId) => {
const viewCount = contractViewCounts[contractId] ?? 0
const clickCount = contractClicks[contractId]?.length ?? 0
const betCount = contractBets[contractId]?.length ?? 0
const contractWordScores = mapValues(yourTfIdf, (wordsTfIdf, contractId) => {
const viewCount = contractViewCounts[contractId] ?? 0
const clickCount = contractClicks[contractId]?.length ?? 0
const betCount = contractBets[contractId]?.length ?? 0
const factor =
-1 * Math.log(viewCount + 1) +
10 * Math.log(betCount + clickCount / 4 + 1)
const factor =
-1 * Math.log(viewCount + 1) +
10 * Math.log(betCount + clickCount / 4 + 1)
return _.mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
}
)
return mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
})
const wordScores = Object.values(contractWordScores).reduce(addObjects, {})
const minScore = Math.min(...Object.values(wordScores))
const maxScore = Math.max(...Object.values(wordScores))
const normalizedWordScores = _.mapValues(
const normalizedWordScores = mapValues(
wordScores,
(score) => (score - minScore) / (maxScore - minScore)
)
@ -156,7 +153,7 @@ export function getContractScore(
if (Object.keys(wordScores).length === 0) return 1
const wordFrequency = contractToWordFrequency(contract)
const score = _.sumBy(Object.keys(wordFrequency), (word) => {
const score = sumBy(Object.keys(wordFrequency), (word) => {
const wordFreq = wordFrequency[word] ?? 0
const weight = wordScores[word] ?? 0
return wordFreq * weight
@ -178,11 +175,13 @@ function calculateContractTfIdf(contracts: Contract[]) {
}
}
const wordIdf = _.mapValues(wordsCount, (count) =>
const wordIdf = mapValues(wordsCount, (count) =>
Math.log(contracts.length / count)
)
const contractWordsTfIdf = _.map(contractFreq, (wordFreq) =>
_.mapValues(wordFreq, (freq, word) => freq * wordIdf[word])
const contractWordsTfIdf = contractFreq.map((wordFreq) =>
mapValues(wordFreq, (freq, word) => freq * wordIdf[word])
)
return Object.fromEntries(
contracts.map((c, i) => [c.id, contractWordsTfIdf[i]])
)
return _.fromPairs(contracts.map((c, i) => [c.id, contractWordsTfIdf[i]]))
}

View File

@ -1,13 +1,13 @@
import * as _ from 'lodash'
import { groupBy, sumBy, mapValues, partition } from 'lodash'
import { Bet } from './bet'
import { Binary, Contract, FullContract } from './contract'
import { getPayouts } from './payouts'
export function scoreCreators(contracts: Contract[], bets: Bet[][]) {
const creatorScore = _.mapValues(
_.groupBy(contracts, ({ creatorId }) => creatorId),
(contracts) => _.sumBy(contracts, ({ pool }) => pool.YES + pool.NO)
const creatorScore = mapValues(
groupBy(contracts, ({ creatorId }) => creatorId),
(contracts) => sumBy(contracts, ({ pool }) => pool.YES + pool.NO)
)
return creatorScore
@ -30,7 +30,7 @@ export function scoreUsersByContract(
) {
const { resolution, resolutionProbability } = contract
const [closedBets, openBets] = _.partition(
const [closedBets, openBets] = partition(
bets,
(bet) => bet.isSold || bet.sale
)
@ -58,9 +58,9 @@ export function scoreUsersByContract(
const netPayouts = [...resolvePayouts, ...salePayouts, ...investments]
const userScore = _.mapValues(
_.groupBy(netPayouts, (payout) => payout.userId),
(payouts) => _.sumBy(payouts, ({ payout }) => payout)
const userScore = mapValues(
groupBy(netPayouts, (payout) => payout.userId),
(payouts) => sumBy(payouts, ({ payout }) => payout)
)
return userScore

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { union } from 'lodash'
export const removeUndefinedProps = <T>(obj: T): T => {
let newObj: any = {}
@ -14,7 +14,7 @@ export const addObjects = <T extends { [key: string]: number }>(
obj1: T,
obj2: T
) => {
const keys = _.union(Object.keys(obj1), Object.keys(obj2))
const keys = union(Object.keys(obj1), Object.keys(obj2))
const newObj = {} as any
for (let key of keys) {

View File

@ -1,4 +1,5 @@
module.exports = {
plugins: ['lodash'],
extends: ['eslint:recommended'],
ignorePatterns: ['lib'],
env: {
@ -17,5 +18,6 @@ module.exports = {
rules: {
'no-unused-vars': 'off',
'no-constant-condition': ['error', { checkLoops: false }],
'lodash/import-scope': [2, 'member'],
},
}

View File

@ -1,6 +1,5 @@
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { getUser } from './utils'
import { Contract } from '../../common/contract'
@ -34,7 +33,7 @@ export const createFold = functions.runWith({ minInstances: 1 }).https.onCall(
return { status: 'error', message: 'About must be a string' }
about = about.trim().slice(0, 140)
if (!_.isArray(tags))
if (!Array.isArray(tags))
return { status: 'error', message: 'Tags must be an array of strings' }
console.log(

View File

@ -1,5 +1,3 @@
import * as _ from 'lodash'
import { DOMAIN, PROJECT_ID } from '../../common/envs/constants'
import { Answer } from '../../common/answer'
import { Bet } from '../../common/bet'

View File

@ -1,6 +1,5 @@
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { getContract } from './utils'
import { Bet } from '../../common/bet'

View File

@ -1,6 +1,6 @@
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { uniq } from 'lodash'
import { getContract, getUser, getValues } from './utils'
import { Comment } from '../../common/comment'
@ -60,7 +60,7 @@ export const onCreateComment = functions.firestore
firestore.collection('contracts').doc(contractId).collection('comments')
)
const recipientUserIds = _.uniq([
const recipientUserIds = uniq([
contract.creatorId,
...comments.map((comment) => comment.userId),
]).filter((id) => id !== comment.userId)

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { partition, sumBy } from 'lodash'
import { Bet } from '../../common/bet'
import { getProbability } from '../../common/calculate'
@ -25,14 +25,14 @@ export const redeemShares = async (userId: string, contractId: string) => {
.where('userId', '==', userId)
)
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
const [yesBets, noBets] = _.partition(bets, (b) => b.outcome === 'YES')
const yesShares = _.sumBy(yesBets, (b) => b.shares)
const noShares = _.sumBy(noBets, (b) => b.shares)
const [yesBets, noBets] = partition(bets, (b) => b.outcome === 'YES')
const yesShares = sumBy(yesBets, (b) => b.shares)
const noShares = sumBy(noBets, (b) => b.shares)
const amount = Math.min(yesShares, noShares)
if (amount <= 0) return
const prevLoanAmount = _.sumBy(bets, (bet) => bet.loanAmount ?? 0)
const prevLoanAmount = sumBy(bets, (bet) => bet.loanAmount ?? 0)
const loanPaid = Math.min(prevLoanAmount, amount)
const netAmount = amount - loanPaid

View File

@ -1,6 +1,6 @@
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { difference, uniq, mapValues, groupBy, sumBy } from 'lodash'
import { Contract } from '../../common/contract'
import { User } from '../../common/user'
@ -187,13 +187,13 @@ const sendResolutionEmails = async (
resolutionProbability?: number,
resolutions?: { [outcome: string]: number }
) => {
const nonWinners = _.difference(
_.uniq(openBets.map(({ userId }) => userId)),
const nonWinners = difference(
uniq(openBets.map(({ userId }) => userId)),
Object.keys(userPayouts)
)
const investedByUser = _.mapValues(
_.groupBy(openBets, (bet) => bet.userId),
(bets) => _.sumBy(bets, (bet) => bet.amount)
const investedByUser = mapValues(
groupBy(openBets, (bet) => bet.userId),
(bets) => sumBy(bets, (bet) => bet.amount)
)
const emailPayouts = [
...Object.entries(userPayouts),

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { sortBy } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -20,7 +20,7 @@ async function migrateContract(
.get()
.then((snap) => snap.docs.map((bet) => bet.data() as Bet))
const lastBet = _.sortBy(bets, (bet) => -bet.createdTime)[0]
const lastBet = sortBy(bets, (bet) => -bet.createdTime)[0]
if (lastBet) {
const probAfter = getDpmProbability(contract.totalShares)

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import * as fs from 'fs'
import { initAdmin } from './script-init'

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { uniq } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -19,7 +19,7 @@ async function lowercaseFoldTags() {
const foldRef = firestore.doc(`folds/${fold.id}`)
const { tags } = fold
const lowercaseTags = _.uniq(tags.map((tag) => tag.toLowerCase()))
const lowercaseTags = uniq(tags.map((tag) => tag.toLowerCase()))
console.log('Adding lowercase tags', fold.slug, lowercaseTags)

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { sumBy } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -25,8 +25,8 @@ async function migrateContract(contractRef: DocRef, contract: Contract) {
.then((snap) => snap.docs.map((bet) => bet.data() as Bet))
const totalShares = {
YES: _.sumBy(bets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
NO: _.sumBy(bets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
YES: sumBy(bets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
NO: sumBy(bets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
}
await contractRef.update({ totalShares })

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { sortBy } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -48,7 +48,7 @@ async function recalculateContract(contractRef: DocRef, isCommit = false) {
const betsRef = contractRef.collection('bets')
const betDocs = await transaction.get(betsRef)
const bets = _.sortBy(
const bets = sortBy(
betDocs.docs.map((d) => d.data() as Bet),
(b) => b.createdTime
)

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { sortBy, sumBy } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -35,7 +35,7 @@ async function recalculateContract(
const contract = contractDoc.data() as FullContract<DPM, Binary>
const betDocs = await transaction.get(contractRef.collection('bets'))
const bets = _.sortBy(
const bets = sortBy(
betDocs.docs.map((d) => d.data() as Bet),
(b) => b.createdTime
)
@ -43,8 +43,8 @@ async function recalculateContract(
const phantomAnte = startPool.YES + startPool.NO
const leftovers =
_.sumBy(bets, (b) => b.amount) -
_.sumBy(bets, (b) => {
sumBy(bets, (b) => b.amount) -
sumBy(bets, (b) => {
if (!b.sale) return b.amount
const soldBet = bets.find((bet) => bet.id === b.sale?.betId)
return soldBet?.amount || 0

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { flatten, groupBy, sumBy, mapValues } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -35,12 +35,12 @@ async function checkIfPayOutAgain(contractRef: DocRef, contract: Contract) {
)
const loanPayouts = getLoanPayouts(openBets)
const groups = _.groupBy(
const groups = groupBy(
[...payouts, ...loanPayouts],
(payout) => payout.userId
)
const userPayouts = _.mapValues(groups, (group) =>
_.sumBy(group, (g) => g.payout)
const userPayouts = mapValues(groups, (group) =>
sumBy(group, (g) => g.payout)
)
const entries = Object.entries(userPayouts)
@ -93,7 +93,7 @@ async function payOutContractAgain() {
)
)
const flattened = _.flatten(toPayOutAgain.map((d) => d.toBePaidOut))
const flattened = flatten(toPayOutAgain.map((d) => d.toBePaidOut))
for (const [userId, payout] of flattened) {
console.log('Paying out', userId, payout)

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { sumBy } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -20,13 +20,13 @@ async function recalculateContract(contractRef: DocRef, contract: Contract) {
const openBets = bets.filter((b) => !b.isSold && !b.sale)
const totalShares = {
YES: _.sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
NO: _.sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
YES: sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.shares : 0)),
NO: sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.shares : 0)),
}
const totalBets = {
YES: _.sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.amount : 0)),
NO: _.sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.amount : 0)),
YES: sumBy(openBets, (bet) => (bet.outcome === 'YES' ? bet.amount : 0)),
NO: sumBy(openBets, (bet) => (bet.outcome === 'NO' ? bet.amount : 0)),
}
await contractRef.update({ totalShares, totalBets })

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,5 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { uniq } from 'lodash'
import { initAdmin } from './script-init'
initAdmin()
@ -19,7 +19,7 @@ async function updateContractTags() {
for (const contract of contracts) {
const contractRef = firestore.doc(`contracts/${contract.id}`)
const tags = _.uniq([
const tags = uniq([
...parseTags(contract.question + contract.description),
...(contract.tags ?? []),
])

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,5 +1,4 @@
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { initAdmin } from './script-init'
initAdmin()

View File

@ -1,4 +1,4 @@
import * as _ from 'lodash'
import { partition, sumBy } from 'lodash'
import * as admin from 'firebase-admin'
import * as functions from 'firebase-functions'