npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sgnl/npm-clojurescript

v0.0.13

Published

The ClojureScript Programming Language, packaged for use with NPM scripts and Node.js

Downloads

7

Readme

ClojureScript npm Package: FORKED EDITION

npm install --save-dev @sgnl/npm-clojurescript
# or
npm install -g @sgnl/npm-clojurescript

MY CHANGELOG/ADDED FEATURES (decending order)

  • 🎉 cljs binary now has added functionality!
    • cljs by itself will launch repl
    • cljs -e file.cljs will evalute file and output evaluated code to stdout
    • cljs -c file.js -o compiled.js will compile clojurescript code to javascript and save to file
    • 🤙 with the above mentioned: this package is now npm script friendly!
  • modularize bin code. introduces yargs for cli argument parsing
  • updated syntax and node version requirements (y tho? 🐸)

ORIGINAL DOCS

Making the ClojureScript language usable from Node.js projects

var cljs = require("clojurescript")
cljs.compile("(fn [a] (str \"Hello \" a))")

// '(function (a){\nreturn [cljs.core.str("Hello "),cljs.core.str(a)].join(\'\');\n})'
var f = cljs.eval("(fn [a] (str \"Hello \" a))")

f("World")
// 'Hello World'

Status

Very early. Do not use for anything critical. Contributions welcome!

Installation

npm install -g clojurescript

Usage

Evaluating & Compiling

eval will return values that are directly usable from JavaScript. The whole standard library is available for use.

var f = cljs.eval("(fn [& args] (->> args (map inc) (remove odd?) into-array))")
f(1, 2, 3, 4, 5, 6, 7)
// [ 2, 4, 6, 8 ]

compile will return a string that can be evaluated using JavaScript's eval.

cljs.compile("(if (< 1 2 3 4 5) (.log js/console \"Less\"))")
'((((1 < 2)) && (((2 < 3)) && (((3 < 4)) && ((4 < 5)))))?console.log("Less"):null)'

Any code that makes use of namespaces of defs will need to run after lib/bootsrap.js has set up the ClojureScript environment. Contexts take care of this.

cljs.compile("(ns your.namespace) (defn f [x] (str \"your \" x))")
'goog.provide(\'your.namespace\');\ngoog.require(\'cljs.core\');\n(function (){\nyour.namespace.f = (function your$namespace$f(x){\nreturn [cljs.core.str("your "),cljs.core.str(x)].join(\'\');\n}); return (\nnew cljs.core.Var(function(){return your.namespace.f;},new cljs.core.Symbol("your.namespace","f","your.namespace/f",1343508863,null),cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"ns","ns",441598760),new cljs.core.Keyword(null,"name","name",1843675177),new cljs.core.Keyword(null,"file","file",-1269645878),new cljs.core.Keyword(null,"end-column","end-column",1425389514),new cljs.core.Keyword(null,"column","column",2078222095),new cljs.core.Keyword(null,"line","line",212345235),new cljs.core.Keyword(null,"end-line","end-line",1837326455),new cljs.core.Keyword(null,"arglists","arglists",1661989754),new cljs.core.Keyword(null,"doc","doc",1913296891),new cljs.core.Keyword(null,"test","test",577538877)],[new cljs.core.Symbol(null,"your.namespace","your.namespace",-1885076140,null),new cljs.core.Symbol(null,"f","f",43394975,null),null,28,21,1,1,cljs.core.list(new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Symbol(null,"x","x",-555367584,null)], null)),null,(cljs.core.truth_(your.namespace.f)?your.namespace.f.cljs$lang$test:null)])));})()\n'

Contexts

ClojureScript has its own notion of namespaces implemented by the Google Closure JavaScript library. It sets up nested objects in the global environment to store your functions and data. This works well in the browser, but makes it difficult to work with Node which perfers to leave the global environment untouched.

To reconcile these two approaches, this package only ever evaluates ClojureScript code in an execution context. A context is an object that contains the global environment with the Google Closure-style namespaces that ClojureScript expects.

var ctx = cljs.newContext()
ctx.cljs.core.str
// { [Function]
//   ... }
ctx.cljs.core.map
// { [Function]
//   ... }

This way, ClojureScript gets the view of the world it wants and the global environment is not affected.

Code can be evaluated in any context. Namespaces and functions are all all accesible and usable from JavaScript.

cljs.eval("(ns foo)", ctx)
cljs.eval("(def name \"Ramsey\")", ctx)
ctx.foo.name
// 'Ramsey'
cljs.eval("(defn surround [a b] (str b a b))", ctx)
ctx.foo.surround("Hello", "~")
// '~Hello~'

Seperate contexts do not share anything. Even the standard library is reevaluated from scratch for each new context. Importantly, they maintain their own current namespace in *ns*.

cljs.eval("(str *ns*)", ctx)
// 'foo'
var ctx2 = cljs.newContext()
cljs.eval("(str *ns*)", ctx2)
// 'cljs.user'
cljs.eval("(ns foo)", ctx2)
cljs.eval("(def name \"Not Ramsey\")", ctx2)
ctx2.foo.name
// 'Not Ramsey'

When eval and compile are used without a second argument, a default context is used. It is exposed as context on the module object.

cljs.eval("(ns foo) (def a 1)")
cljs.context.foo.a
// 1

ClojureScript Require

:require and :use work in ns forms as expected. The search path aims to mirror the Node package resolution algorithm, i.e. .cljs files will be looked up in the node_modules folder if it exists, and then in the node_modules folder of the parent directory and so on to the top of the file system.

;; node_modules/helpers.cljs
(ns helpers)

(defn wrap [a min max]
  (cond (< a min) min
        (> a max) max
        :else    a))
var cljs = require("clojurescript")
cljs.eval("(ns main (:require helpers))")
cljs.eval("(helpers/wrap 90 0 10)")
// 10
cljs.eval("(helpers/wrap -90 0 10)")
// 0

Node Require

requireing "clojurescript/register" will register the .cljs extension with Node's require function and allow you to require cljs files in node. The module will export the contents of the last namespace in the file.

require("clojurescript/register")
var helpers = require("helpers")
helpers
// { wrap: [Function: helpers$wrap] }
helpers.wrap(90, 0, 100)
// 90
helpers.wrap(-90, 0, 100)
// 0

Command Line

Installing with -g will create put a cljs executable on your path.

Calling without arguments starts a REPL.

$ cljs
> (+ 1 2)
3
> (ns mappers)
nil
> (defn inc-all [col] (map inc col))
#'mappers/inc-all
> (ns cljs.user)
nil
> (mappers/inc-all (range 20))
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
> (ns cljs.user (:require helpers))
nil
> (helpers/wrap 0 0 0)
0
> (ns cljs.user (:require [helpers :refer [wrap]]))
nil
> (wrap 90 0 10)
10
> (wrap -90 0 10)
0

Passing a file as an argument will execute that file.

$ cat foo.cljs
(->> (range 20)
     (map inc)
     (filter even?)
     (map #(println (str "Hello " % " World")))
     dorun)
$ cljs foo.cljs
Hello 2 World
Hello 4 World
Hello 6 World
Hello 8 World
Hello 10 World
Hello 12 World
Hello 14 World
Hello 16 World
Hello 18 World
Hello 20 World

API

  • cljs.newContext([globals]) Creates a new ClojureScript execution context.
  • cljs.context The default execution context. Used by compile and eval by default.
  • cljs.compile(str[, ctx]) — Takes a string of ClojureScript code and returns a string of JavaScript code. Optionally takes a context to compile the code in.
  • cljs.eval(str[, ctx]) — Takes a string of ClojureScript code, evaluates it, and returns the resulting value. Optionally takes a context to evaluate the code in.

Building

lein cljsbuild once

to rebuild lib/bootstrap.js, where the ClojureScript compiler and standard library live. Requires Leiningen, Clojure, and Java to be installed and properly configured.

Legal

npm package © 2015-2016 Ramsey Nasser, provided under the Eclipse Public License 1.0

Uses code from elbow © 2015–2016 Mike Fikes and Contributors. Used under the Eclipse Public License version 1.0.

ClojureScript © Rich Hickey, provided under the Eclipse Public License 1.0