Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
fantasy-land
Advanced tools
Specification for interoperability of common algebraic structures in JavaScript
(aka "Algebraic JavaScript Specification")
This project specifies interoperability of common algebraic structures:
An algebra is a set of values, a set of operators that it is closed under and some laws it must obey.
Each Fantasy Land algebra is a separate specification. An algebra may have dependencies on other algebras which must be implemented.
The type signature notation used in this document is described below:1
::
"is a member of".
e :: t
can be read as: "the expression e
is a member of type t
".true :: Boolean
- "true
is a member of type Boolean
".42 :: Integer, Number
- "42
is a member of type Integer and Number
".Array
is a type constructor which takes one type argument.Array String
is the type of all arrays of strings. Each of the
following has type Array String
: []
, ['foo', 'bar', 'baz']
.Array (Array String)
is the type of all arrays of arrays of strings.
Each of the following has type Array (Array String)
: []
, [ [], [] ]
, [ [], ['foo'], ['bar', 'baz'] ]
.->
(arrow) Function type constructor.
->
is an infix type constructor that takes two type arguments where
left argument is the input type and the right argument is the output type.->
's input type can be a grouping of types to create the type of a
function which accepts zero or more arguments. The syntax is:
(<input-types>) -> <output-type>
, where <input-types>
comprises zero
or more comma–space (,
)-separated type representations and parens
may be omitted for unary functions.String -> Array String
is a type satisfied by functions which take a
String
and return an Array String
.String -> Array String -> Array String
is a type satisfied by functions
which take a String
and return a function which takes an Array String
and returns an Array String
.(String, Array String) -> Array String
is a type satisfied by functions
which take a String
and an Array String
as arguments and return an
Array String
.() -> Number
is a type satisfied by functions
which do not take arguments and return a Number
.~>
(squiggly arrow) Method type constructor.
a ~> a -> a
is a type satisfied by methods on Objects of type a
which
take a type a
as an argument and return a value of type a
.=>
(fat arrow) Expresses constraints on type variables.
a ~> a -> a
(see squiggly arrow above), a
can be of any type.
Semigroup a => a ~> a -> a
adds a constraint such that the type a
must now satisfy the Semigroup
typeclass. To satisfy a typeclass means
to lawfully implement all functions/methods specified by that typeclass.For example:
fantasy-land/traverse :: Applicative f, Traversable t => t a ~> (TypeRep f, a -> f b) -> f (t b)
'-------------------' '--------------------------' '-' '-------------------' '-----'
' ' ' ' '
' ' - type constraints ' ' - argument types ' - return type
' '
'- method name ' - method target type
Certain behaviours are defined from the perspective of a member of a type.
Other behaviours do not require a member. Thus certain algebras require a
type to provide a value-level representative (with certain properties). The
Identity type, for example, could provide Id
as its type representative:
Id :: TypeRep Identity
.
If a type provides a type representative, each member of the type must have
a constructor
property which is a reference to the type representative.
a['fantasy-land/equals'](a) === true
(reflexivity)a['fantasy-land/equals'](b) === b['fantasy-land/equals'](a)
(symmetry)a['fantasy-land/equals'](b)
and b['fantasy-land/equals'](c)
, then a['fantasy-land/equals'](c)
(transitivity)fantasy-land/equals
methodfantasy-land/equals :: Setoid a => a ~> a -> Boolean
A value which has a Setoid must provide a fantasy-land/equals
method. The
fantasy-land/equals
method takes one argument:
a['fantasy-land/equals'](b)
b
must be a value of the same Setoid
b
is not the same Setoid, behaviour of fantasy-land/equals
is
unspecified (returning false
is recommended).fantasy-land/equals
must return a boolean (true
or false
).
A value that implements the Ord specification must also implement the Setoid specification.
a['fantasy-land/lte'](b)
or b['fantasy-land/lte'](a)
(totality)a['fantasy-land/lte'](b)
and b['fantasy-land/lte'](a)
, then a['fantasy-land/equals'](b)
(antisymmetry)a['fantasy-land/lte'](b)
and b['fantasy-land/lte'](c)
, then a['fantasy-land/lte'](c)
(transitivity)fantasy-land/lte
methodfantasy-land/lte :: Ord a => a ~> a -> Boolean
A value which has an Ord must provide a fantasy-land/lte
method. The
fantasy-land/lte
method takes one argument:
a['fantasy-land/lte'](b)
b
must be a value of the same Ord
b
is not the same Ord, behaviour of fantasy-land/lte
is
unspecified (returning false
is recommended).fantasy-land/lte
must return a boolean (true
or false
).
a['fantasy-land/compose'](b)['fantasy-land/compose'](c) === a['fantasy-land/compose'](b['fantasy-land/compose'](c))
(associativity)fantasy-land/compose
methodfantasy-land/compose :: Semigroupoid c => c i j ~> c j k -> c i k
A value which has a Semigroupoid must provide a fantasy-land/compose
method. The
fantasy-land/compose
method takes one argument:
a['fantasy-land/compose'](b)
b
must be a value of the same Semigroupoid
b
is not the same semigroupoid, behaviour of fantasy-land/compose
is
unspecified.fantasy-land/compose
must return a value of the same Semigroupoid.
A value that implements the Category specification must also implement the Semigroupoid specification.
a['fantasy-land/compose'](C['fantasy-land/id']())
is equivalent to a
(right identity)C['fantasy-land/id']()['fantasy-land/compose'](a)
is equivalent to a
(left identity)fantasy-land/id
methodfantasy-land/id :: Category c => () -> c a a
A value which has a Category must provide a fantasy-land/id
function on its
type representative:
C['fantasy-land/id']()
Given a value c
, one can access its type representative via the
constructor
property:
c.constructor['fantasy-land/id']()
fantasy-land/id
must return a value of the same Categorya['fantasy-land/concat'](b)['fantasy-land/concat'](c)
is equivalent to a['fantasy-land/concat'](b['fantasy-land/concat'](c))
(associativity)fantasy-land/concat
methodfantasy-land/concat :: Semigroup a => a ~> a -> a
A value which has a Semigroup must provide a fantasy-land/concat
method. The
fantasy-land/concat
method takes one argument:
s['fantasy-land/concat'](b)
b
must be a value of the same Semigroup
b
is not the same semigroup, behaviour of fantasy-land/concat
is
unspecified.fantasy-land/concat
must return a value of the same Semigroup.
A value that implements the Monoid specification must also implement the Semigroup specification.
m['fantasy-land/concat'](M['fantasy-land/empty']())
is equivalent to m
(right identity)M['fantasy-land/empty']()['fantasy-land/concat'](m)
is equivalent to m
(left identity)fantasy-land/empty
methodfantasy-land/empty :: Monoid m => () -> m
A value which has a Monoid must provide a fantasy-land/empty
function on its
type representative:
M['fantasy-land/empty']()
Given a value m
, one can access its type representative via the
constructor
property:
m.constructor['fantasy-land/empty']()
fantasy-land/empty
must return a value of the same MonoidA value that implements the Group specification must also implement the Monoid specification.
g['fantasy-land/concat'](g['fantasy-land/invert']())
is equivalent to g.constructor['fantasy-land/empty']()
(right inverse)g['fantasy-land/invert']()['fantasy-land/concat'](g)
is equivalent to g.constructor['fantasy-land/empty']()
(left inverse)fantasy-land/invert
methodfantasy-land/invert :: Group g => g ~> () -> g
A value which has a Group must provide a fantasy-land/invert
method. The
fantasy-land/invert
method takes no arguments:
g['fantasy-land/invert']()
fantasy-land/invert
must return a value of the same Group.v['fantasy-land/filter'](x => p(x) && q(x))
is equivalent to v['fantasy-land/filter'](p)['fantasy-land/filter'](q)
(distributivity)v['fantasy-land/filter'](x => true)
is equivalent to v
(identity)v['fantasy-land/filter'](x => false)
is equivalent to w['fantasy-land/filter'](x => false)
if v
and w
are values of the same Filterable (annihilation)fantasy-land/filter
methodfantasy-land/filter :: Filterable f => f a ~> (a -> Boolean) -> f a
A value which has a Filterable must provide a fantasy-land/filter
method. The fantasy-land/filter
method takes one argument:
v['fantasy-land/filter'](p)
p
must be a function.
p
is not a function, the behaviour of fantasy-land/filter
is unspecified.p
must return either true
or false
. If it returns any other value,
the behaviour of fantasy-land/filter
is unspecified.fantasy-land/filter
must return a value of the same Filterable.
u['fantasy-land/map'](a => a)
is equivalent to u
(identity)u['fantasy-land/map'](x => f(g(x)))
is equivalent to u['fantasy-land/map'](g)['fantasy-land/map'](f)
(composition)fantasy-land/map
methodfantasy-land/map :: Functor f => f a ~> (a -> b) -> f b
A value which has a Functor must provide a fantasy-land/map
method. The fantasy-land/map
method takes one argument:
u['fantasy-land/map'](f)
f
must be a function,
f
is not a function, the behaviour of fantasy-land/map
is
unspecified.f
can return any value.f
's return value should be checked.fantasy-land/map
must return a value of the same Functor
u['fantasy-land/contramap'](a => a)
is equivalent to u
(identity)u['fantasy-land/contramap'](x => f(g(x)))
is equivalent to u['fantasy-land/contramap'](f)['fantasy-land/contramap'](g)
(composition)fantasy-land/contramap
methodfantasy-land/contramap :: Contravariant f => f a ~> (b -> a) -> f b
A value which has a Contravariant must provide a fantasy-land/contramap
method. The
fantasy-land/contramap
method takes one argument:
u['fantasy-land/contramap'](f)
f
must be a function,
f
is not a function, the behaviour of fantasy-land/contramap
is
unspecified.f
can return any value.f
's return value should be checked.fantasy-land/contramap
must return a value of the same Contravariant
A value that implements the Apply specification must also implement the Functor specification.
v['fantasy-land/ap'](u['fantasy-land/ap'](a['fantasy-land/map'](f => g => x => f(g(x)))))
is equivalent to v['fantasy-land/ap'](u)['fantasy-land/ap'](a)
(composition)fantasy-land/ap
methodfantasy-land/ap :: Apply f => f a ~> f (a -> b) -> f b
A value which has an Apply must provide a fantasy-land/ap
method. The fantasy-land/ap
method takes one argument:
a['fantasy-land/ap'](b)
b
must be an Apply of a function
b
does not represent a function, the behaviour of fantasy-land/ap
is
unspecified.b
must be same Apply as a
.a
must be an Apply of any value
fantasy-land/ap
must apply the function in Apply b
to the value in
Apply a
The Apply
returned by fantasy-land/ap
must be the same as a
and b
A value that implements the Applicative specification must also implement the Apply specification.
v['fantasy-land/ap'](A['fantasy-land/of'](x => x))
is equivalent to v
(identity)A['fantasy-land/of'](x)['fantasy-land/ap'](A['fantasy-land/of'](f))
is equivalent to A['fantasy-land/of'](f(x))
(homomorphism)A['fantasy-land/of'](y)['fantasy-land/ap'](u)
is equivalent to u['fantasy-land/ap'](A['fantasy-land/of'](f => f(y)))
(interchange)fantasy-land/of
methodfantasy-land/of :: Applicative f => a -> f a
A value which has an Applicative must provide a fantasy-land/of
function on its
type representative. The fantasy-land/of
function takes
one argument:
F['fantasy-land/of'](a)
Given a value f
, one can access its type representative via the
constructor
property:
f.constructor['fantasy-land/of'](a)
fantasy-land/of
must provide a value of the same Applicative
a
should be checkedA value that implements the Alt specification must also implement the Functor specification.
a['fantasy-land/alt'](b)['fantasy-land/alt'](c)
is equivalent to a['fantasy-land/alt'](b['fantasy-land/alt'](c))
(associativity)a['fantasy-land/alt'](b)['fantasy-land/map'](f)
is equivalent to a['fantasy-land/map'](f)['fantasy-land/alt'](b['fantasy-land/map'](f))
(distributivity)fantasy-land/alt
methodfantasy-land/alt :: Alt f => f a ~> f a -> f a
A value which has a Alt must provide a fantasy-land/alt
method. The
fantasy-land/alt
method takes one argument:
a['fantasy-land/alt'](b)
b
must be a value of the same Alt
b
is not the same Alt, behaviour of fantasy-land/alt
is
unspecified.a
and b
can contain any value of same type.a
's and b
's containing value should be checked.fantasy-land/alt
must return a value of the same Alt.
A value that implements the Plus specification must also implement the Alt specification.
x['fantasy-land/alt'](A['fantasy-land/zero']())
is equivalent to x
(right identity)A['fantasy-land/zero']()['fantasy-land/alt'](x)
is equivalent to x
(left identity)A['fantasy-land/zero']()['fantasy-land/map'](f)
is equivalent to A['fantasy-land/zero']()
(annihilation)fantasy-land/zero
methodfantasy-land/zero :: Plus f => () -> f a
A value which has a Plus must provide a fantasy-land/zero
function on its
type representative:
A['fantasy-land/zero']()
Given a value x
, one can access its type representative via the
constructor
property:
x.constructor['fantasy-land/zero']()
fantasy-land/zero
must return a value of the same PlusA value that implements the Alternative specification must also implement the Applicative and Plus specifications.
x['fantasy-land/ap'](f['fantasy-land/alt'](g))
is equivalent to x['fantasy-land/ap'](f)['fantasy-land/alt'](x['fantasy-land/ap'](g))
(distributivity)x['fantasy-land/ap'](A['fantasy-land/zero']())
is equivalent to A['fantasy-land/zero']()
(annihilation)u['fantasy-land/reduce']
is equivalent to u['fantasy-land/reduce']((acc, x) => acc.concat([x]), []).reduce
fantasy-land/reduce
methodfantasy-land/reduce :: Foldable f => f a ~> ((b, a) -> b, b) -> b
A value which has a Foldable must provide a fantasy-land/reduce
method. The fantasy-land/reduce
method takes two arguments:
u['fantasy-land/reduce'](f, x)
f
must be a binary function
f
is not a function, the behaviour of fantasy-land/reduce
is unspecified.f
must be the same type as x
.f
must return a value of the same type as x
.f
's return value should be checked.x
is the initial accumulator value for the reduction
x
should be checked.A value that implements the Traversable specification must also implement the Functor and Foldable specifications.
t(u['fantasy-land/traverse'](F, x => x))
is equivalent to u['fantasy-land/traverse'](G, t)
for any
t
such that t(a)['fantasy-land/map'](f)
is equivalent to t(a['fantasy-land/map'](f))
(naturality)
u['fantasy-land/traverse'](F, F['fantasy-land/of'])
is equivalent to F['fantasy-land/of'](u)
for any Applicative F
(identity)
u['fantasy-land/traverse'](Compose, x => new Compose(x))
is equivalent to
new Compose(u['fantasy-land/traverse'](F, x => x)['fantasy-land/map'](x => x['fantasy-land/traverse'](G, x => x)))
for
Compose
defined below and any Applicatives F
and G
(composition)
function Compose(c) {
this.c = c;
}
Compose['fantasy-land/of'] = function(x) {
return new Compose(F['fantasy-land/of'](G['fantasy-land/of'](x)));
};
Compose.prototype['fantasy-land/ap'] = function(f) {
return new Compose(this.c['fantasy-land/ap'](f.c['fantasy-land/map'](u => y => y['fantasy-land/ap'](u))));
};
Compose.prototype['fantasy-land/map'] = function(f) {
return new Compose(this.c['fantasy-land/map'](y => y['fantasy-land/map'](f)));
};
fantasy-land/traverse
methodfantasy-land/traverse :: Applicative f, Traversable t => t a ~> (TypeRep f, a -> f b) -> f (t b)
A value which has a Traversable must provide a fantasy-land/traverse
method. The fantasy-land/traverse
method takes two arguments:
u['fantasy-land/traverse'](A, f)
A
must be the type representative of an
Applicative.
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/traverse
is
unspecified.f
must return a value of the type represented by A
.fantasy-land/traverse
must return a value of the type represented by A
.
A value that implements the Chain specification must also implement the Apply specification.
m['fantasy-land/chain'](f)['fantasy-land/chain'](g)
is equivalent to m['fantasy-land/chain'](x => f(x)['fantasy-land/chain'](g))
(associativity)fantasy-land/chain
methodfantasy-land/chain :: Chain m => m a ~> (a -> m b) -> m b
A value which has a Chain must provide a fantasy-land/chain
method. The fantasy-land/chain
method takes one argument:
m['fantasy-land/chain'](f)
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/chain
is
unspecified.f
must return a value of the same Chainfantasy-land/chain
must return a value of the same Chain
A value that implements the ChainRec specification must also implement the Chain specification.
M['fantasy-land/chainRec']((next, done, v) => p(v) ? d(v)['fantasy-land/map'](done) : n(v)['fantasy-land/map'](next), i)
is equivalent to
(function step(v) { return p(v) ? d(v) : n(v)['fantasy-land/chain'](step); }(i))
(equivalence)M['fantasy-land/chainRec'](f, i)
must be at most a constant multiple of the stack usage of f
itself.fantasy-land/chainRec
methodfantasy-land/chainRec :: ChainRec m => ((a -> c, b -> c, a) -> m c, a) -> m b
A Type which has a ChainRec must provide a fantasy-land/chainRec
function on its
type representative. The fantasy-land/chainRec
function
takes two arguments:
M['fantasy-land/chainRec'](f, i)
Given a value m
, one can access its type representative via the
constructor
property:
m.constructor['fantasy-land/chainRec'](f, i)
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/chainRec
is unspecified.f
takes three arguments next
, done
, value
next
is a function which takes one argument of same type as i
and can return any valuedone
is a function which takes one argument and returns the same type as the return value of next
value
is some value of the same type as i
f
must return a value of the same ChainRec which contains a value returned from either done
or next
fantasy-land/chainRec
must return a value of the same ChainRec which contains a value of same type as argument of done
A value that implements the Monad specification must also implement the Applicative and Chain specifications.
M['fantasy-land/of'](a)['fantasy-land/chain'](f)
is equivalent to f(a)
(left identity)m['fantasy-land/chain'](M['fantasy-land/of'])
is equivalent to m
(right identity)A value that implements the Extend specification must also implement the Functor specification.
w['fantasy-land/extend'](g)['fantasy-land/extend'](f)
is equivalent to w['fantasy-land/extend'](_w => f(_w['fantasy-land/extend'](g)))
fantasy-land/extend
methodfantasy-land/extend :: Extend w => w a ~> (w a -> b) -> w b
An Extend must provide a fantasy-land/extend
method. The fantasy-land/extend
method takes one argument:
w['fantasy-land/extend'](f)
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/extend
is
unspecified.f
must return a value of type v
, for some variable v
contained in w
.f
's return value should be checked.fantasy-land/extend
must return a value of the same Extend.
A value that implements the Comonad specification must also implement the Extend specification.
w['fantasy-land/extend'](_w => _w['fantasy-land/extract']())
is equivalent to w
(left identity)w['fantasy-land/extend'](f)['fantasy-land/extract']()
is equivalent to f(w)
(right identity)fantasy-land/extract
methodfantasy-land/extract :: Comonad w => w a ~> () -> a
A value which has a Comonad must provide a fantasy-land/extract
method on itself.
The fantasy-land/extract
method takes no arguments:
w['fantasy-land/extract']()
fantasy-land/extract
must return a value of type v
, for some variable v
contained in w
.
v
must have the same type that f
returns in fantasy-land/extend
.A value that implements the Bifunctor specification must also implement the Functor specification.
p['fantasy-land/bimap'](a => a, b => b)
is equivalent to p
(identity)p['fantasy-land/bimap'](a => f(g(a)), b => h(i(b))
is equivalent to p['fantasy-land/bimap'](g, i)['fantasy-land/bimap'](f, h)
(composition)fantasy-land/bimap
methodfantasy-land/bimap :: Bifunctor f => f a c ~> (a -> b, c -> d) -> f b d
A value which has a Bifunctor must provide a fantasy-land/bimap
method. The fantasy-land/bimap
method takes two arguments:
c['fantasy-land/bimap'](f, g)
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/bimap
is unspecified.f
can return any value.f
's return value should be checked.g
must be a function which returns a value
g
is not a function, the behaviour of fantasy-land/bimap
is unspecified.g
can return any value.g
's return value should be checked.fantasy-land/bimap
must return a value of the same Bifunctor.
A value that implements the Profunctor specification must also implement the Functor specification.
p['fantasy-land/promap'](a => a, b => b)
is equivalent to p
(identity)p['fantasy-land/promap'](a => f(g(a)), b => h(i(b)))
is equivalent to p['fantasy-land/promap'](f, i)['fantasy-land/promap'](g, h)
(composition)fantasy-land/promap
methodfantasy-land/promap :: Profunctor p => p b c ~> (a -> b, c -> d) -> p a d
A value which has a Profunctor must provide a fantasy-land/promap
method.
The fantasy-land/promap
method takes two arguments:
c['fantasy-land/promap'](f, g)
f
must be a function which returns a value
f
is not a function, the behaviour of fantasy-land/promap
is unspecified.f
can return any value.f
's return value should be checked.g
must be a function which returns a value
g
is not a function, the behaviour of fantasy-land/promap
is unspecified.g
can return any value.g
's return value should be checked.fantasy-land/promap
must return a value of the same Profunctor
When creating data types which satisfy multiple algebras, authors may choose to implement certain methods then derive the remaining methods. Derivations:
fantasy-land/equals
may be derived from fantasy-land/lte
:
function equals(other) { return this['fantasy-land/lte'](other) && other['fantasy-land/lte'](this); }
fantasy-land/map
may be derived from fantasy-land/ap
and fantasy-land/of
:
function map(f) { return this['fantasy-land/ap'](this.constructor['fantasy-land/of'](f)); }
fantasy-land/map
may be derived from fantasy-land/chain
and fantasy-land/of
:
function map(f) { return this['fantasy-land/chain'](a => this.constructor['fantasy-land/of'](f(a))); }
fantasy-land/map
may be derived from fantasy-land/bimap
:
function map(f) { return this['fantasy-land/bimap'](a => a, f); }
fantasy-land/map
may be derived from fantasy-land/promap
:
function map(f) { return this['fantasy-land/promap'](a => a, f); }
fantasy-land/ap
may be derived from fantasy-land/chain
:
function ap(m) { return m['fantasy-land/chain'](f => this['fantasy-land/map'](f)); }
fantasy-land/reduce
may be derived as follows:
function reduce(f, acc) {
function Const(value) {
this.value = value;
}
Const['fantasy-land/of'] = function(_) {
return new Const(acc);
};
Const.prototype['fantasy-land/map'] = function(_) {
return this;
};
Const.prototype['fantasy-land/ap'] = function(b) {
return new Const(f(b.value, this.value));
};
return this['fantasy-land/traverse'](x => new Const(x), Const['fantasy-land/of']).value;
}
fantasy-land/map
may be derived as follows:
function map(f) {
function Id(value) {
this.value = value;
}
Id['fantasy-land/of'] = function(x) {
return new Id(x);
};
Id.prototype['fantasy-land/map'] = function(f) {
return new Id(f(this.value));
};
Id.prototype['fantasy-land/ap'] = function(b) {
return new Id(this.value(b.value));
};
return this['fantasy-land/traverse'](x => Id['fantasy-land/of'](f(x)), Id['fantasy-land/of']).value;
}
fantasy-land/filter
may be derived from fantasy-land/of
, fantasy-land/chain
, and fantasy-land/zero
:
function filter(pred) {
var F = this.constructor;
return this['fantasy-land/chain'](x => pred(x) ? F['fantasy-land/of'](x) : F['fantasy-land/zero']());
}
fantasy-land/filter
may be derived from fantasy-land/concat
, fantasy-land/of
, fantasy-land/zero
, and
fantasy-land/reduce
:
function filter(pred) {
var F = this.constructor;
return this['fantasy-land/reduce']((f, x) => pred(x) ? f['fantasy-land/concat'](F['fantasy-land/of'](x)) : f, F['fantasy-land/zero']());
}
If a data type provides a method which could be derived, its behaviour must be equivalent to that of the derivation (or derivations).
Identity
container which implements many of the methods is provided by
sanctuary-identity.There also exists Static Land Specification with exactly the same ideas as Fantasy Land but based on static methods instead of instance methods.
FAQs
Specification for interoperability of common algebraic structures in JavaScript
The npm package fantasy-land receives a total of 409 weekly downloads. As such, fantasy-land popularity was classified as not popular.
We found that fantasy-land demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.