evilsoft / crocks

A collection of well known Algebraic Data Types for your utter enjoyment.
https://crocks.dev
ISC License
1.59k stars 102 forks source link

Distribute src as ES Modules #534

Open semmel opened 2 years ago

semmel commented 2 years ago

Shipping src as ES modules has obvious benefits: E.g.

With #264 an attempt to migrate crocks to ES modules has been started.

Idea:

In the meantime I suggest generating ES modules files from every CommonJS file in /src in the build step. This achieves almost the same as the conversion of all source files – some code will be duplicated though.

Dead ends

CJS → ESM Conversion tools are either abandoned like nolanlawson/cjs-to-es6, or wessberg/cjstoesm produces errors converting the crocks codebase.

Solution:

I've employed rollup with a quite standard config file of about 40 lines code in my tests. It generates a dist/esm folder, which can be mapped via

to bare ES module import specifiers.

Quite similar to the ReadMe instructions, for example:

import { logic } from 'crocks';
import Maybe from 'crocks/Maybe';
import pointfree from 'crocks/pointfree';
// not quite sure about this one yet:
// no problem in Node, in browser depends on importmap capabilities
import either from 'crocks/pointfree/either';
// or
import either from '../node_modules/crocks/dist/esm/pointfree/either.js';
const
    {and, not} = logic,
    { option } = pointfree,
    mFoo = Maybe.of("bar"),
    mNothing = Maybe.Nothing(),
// …

My contribution would involve adding rollup as dev depondency, adding the export section in package.json and a rollup.config.js file.

Should I attempt a PR?

semmel commented 2 years ago

The generated dist/Maybe/find.js file is like what cdn.sykpack.dev generates for crocks.

import { c as curry_1, t as types, i as isFunction_1, a as isSameType_1 } from './types-79e513c1.js';
import { p as predOrFunc_1 } from './predOrFunc-a430cf4e.js';
import { h as hasAlg_1 } from './Maybe-f40e27d5.js';
import { M as Maybe } from './index-e9cd2952.js';

/** @license ISC License (c) copyright 2017 original and current authors */

/** @author Ian Hofmann-Hicks (evil) */

const hasAlg = hasAlg_1;

/** isFoldable :: a -> Boolean */
function isFoldable$1(m) {
  return !!m
    && hasAlg('reduce', m)
}

var isFoldable_1 = isFoldable$1;

/** @license ISC License (c) copyright 2018 original and current authors */

/** @author Dale Francis (dalefrancis88) */

const Pred = types.proxy('Pred');

const curry = curry_1;
const predOrFunc = predOrFunc_1;
const isFunction = isFunction_1;
const isFoldable = isFoldable_1;
const isSameType = isSameType_1;

const { Just, Nothing } = Maybe.exports;

const accumulator = fn => (acc, cur) =>
  !acc.found && predOrFunc(fn, cur) ? { found: true, value: cur } : acc;

/** find :: Foldable f => ((a -> Boolean) | Pred) -> f a -> Maybe a */
function find(fn, foldable) {
  if(!isFunction(fn) && !isSameType(Pred, fn)) {
    throw new TypeError('find: First argument must be a Pred or predicate')
  }

  if(!isFoldable(foldable)) {
    throw new TypeError('find: Second argument must be a Foldable')
  }

  const result = foldable.reduce(accumulator(fn), { found: false });

  return result.found ? Just(result.value) : Nothing()
}

var find_1 = curry(find);

export { find_1 as default };
bennypowers commented 1 year ago

Export conditions are widely supported now. Good time to pull the trigger on this