Upcoming tasks
selfrefactor opened this issue · 22 comments
This is public TODO list for Rambda
and Rambdax
which is updated once a task is done:
wrong export
Revert export
field changes in package.json
due to ramda/ramda#3236
Data first Rambda
Rameda alike
As it is hard to create so many files, just exporting _
which will contain one file, much like the initial version of Rambda
Dictionary - type vs interface
isValid with functions
only arrow function works
ok(repos)(fn)
// ok(repos)(x => {
// console.log({x})
// })
also not possible is array of function schema
ok(repos)([x => {
console.log({x})
}])
Methods to add:
- whereAny
- uniqBy
- propSatisfies
- pickBy
- pathSatisfies
- gte
- mapObjIndexed(types from @types/ramda | added but types are not from there)
https://github.com/smartprocure/futil-js#differentlast
https://github.com/smartprocure/futil-js#whentruthy
findApply
compactMap
compactJoin
flattenObject
simpleDiff
highlight
on
off
includeLens?
- R.mapKeys (name inspiration from https://github.com/AlexGalays/spacelift#objectmapvalues)
Add R.mapToList which takes object and returns a list
include eslint-plugin-mocha
as notable users
SKIPPED
Duplication of test, readme example and typings test. As it depends on REPL, documentation site needs to be build first.
The idea is to move build information from files/index.d.ts
to the source
files. Maybe run Jest test in browser instead of having REPL app.
use proper naming such as functor https://github.com/hemanth/functional-programming-jargon?utm_source=hackernewsletter&utm_medium=email&utm_term=code#functor
apply for inclusion in https://github.com/hemanth/functional-programming-jargon once more FP functions are added
try transducers from Ramda to be included
Rambdax has issues with _consumetypings tests
- Add
R.mapAllSettled
Explanation: It asynchronously iterates over a list using Promise.allSettled
.
import { delay } from './delay.js'
import { join } from './join.js'
import { map } from './map.js'
import { mapAllSettled } from './mapAllSettled.js'
import { pipeAsync } from './pipeAsync.js'
const fn = async (x, i) => {
await delay(100)
if (i % 2) throw new Error(foo-${ i }
)
return x + 1
}
test('happy', async () => {
await expect(mapAllSettled(fn, [ 1, 2, 3, 4 ])).resolves
.toMatchInlineSnapshot([ { "status": "fulfilled", "value": 2, }, { "reason": [Error: foo-1], "status": "rejected", }, { "status": "fulfilled", "value": 4, }, { "reason": [Error: foo-3], "status": "rejected", }, ]
)
})
test('inside pipe', async () => {
const result = await pipeAsync(
mapAllSettled(fn),
map(({ status }) => status),
join('-')
)([ 1, 2, 3 ])
expect(result).toBe('fulfilled-rejected-fulfilled')
})
===
export async function mapAllSettledFn(fn, arr){
const promised = arr.map((a, i) => fn(a, i))
return Promise.allSettled(promised)
}
export function mapAllSettled(fn, arr){
if (arguments.length === 1){
return async holder => mapAllSettledFn(fn, holder)
}
return new Promise((resolve, reject) => {
mapAllSettledFn(fn, arr).then(resolve)
.catch(reject)
})
}
restore
import isCI from 'is-ci'
import { resolve } from 'path'
import { execCommand } from '../files/execCommand.js'
jest.setTimeout(3 * 60 * 1000)
/**
* "consume-typings:clone": "cd .. && git clone --depth 1 https://github.com/selfrefactor/rambda-scripts.git rambda-scripts-clone",
"consume-typings:execute": "cd ../rambda-scripts-clone/scripts/consume-typings && yarn start",
"consume-typings": "yarn consume-typings:clone && yarn consume-typings:execute",
*/
const DIR = resolve(__dirname, '../../')
test('typings can be imported', async () => {
if (!isCI) return
await execCommand('rm -rf rambda-scripts-clone', DIR)
await execCommand('yarn build:main')
expect(await execCommand('yarn consume-typings')).toBeTrue()
})
import { pathFn } from './path.js'
export const removePath = (object, path) => {
const pathResult = pathFn(path, object)
if (pathResult === undefined) return object
if (!path.length) return object
const [ head, ...tail ] = path
if (tail.length === 0){
const { [ head ]: _, ...rest } = object
return rest
}
if (!object[ head ]) return object
return {
...object,
[ head ] : removePath(object[ head ], tail),
}
}
export function omitPaths(paths, obj){
if (arguments.length === 1){
return _obj => omitPaths(paths, _obj)
}
return paths.reduce((result, path) => {
const pathParts = path.split('.')
return removePath(result, pathParts)
}, obj)
}
---
import { omitPaths } from './omitPaths.js'
const object = {
a : {
b : {
c : 1,
d : 2,
},
},
foo : {
bar : 3,
baz : 4,
},
}
test('happy', () => {
const result = omitPaths([ 'a.b.c', 'foo.bar' ], object)
const curried = omitPaths([ 'a.b.c', 'foo.bar' ])
const expected = {
a : { b : { d : 2 } },
foo : { baz : 4 },
}
expect(result).toEqual(expected)
expect(curried(object)).toEqual(expected)
})
test('with no matching path', () => {
expect(omitPaths([ 'a.b.c.d.e.f', 'foo.bar.123' ], object)).toEqual(object)
})