Git Product home page Git Product logo

lwt-node's Introduction

lwt-node

lwt-node, a reason implemention of the node.js API.

Install

First you need to install esy, Sandboxed and project based installations that share build artifacts and builds, for lightning fast installations and incremental builds:

yarn global add esy

# OR with npm

npm install --global esy

Then go ahead and add lwt-node to your project with esy:

esy add lwt-node

Usage

See https://github.com/kennetpostigo/lwt-node-starter

Documentation

See https://kennetpostigo.github.io/lwt-node

Contributing

See Contributing.md

Missing or yet to be implemented API's are documented with compile-time warnings, are noted in the documentation and are listed in Future.md. If you'd like to help contribute, please open a pull-request, no code needed! We'll try to help steer you in the right direction!

building

  1. Clone the project
  2. Run esy install
  3. Run esy build

testing

esy make test

Running commands If you want to run commands that work directly on the project, you must always prefex them with esy x in order to run the command in the sandboxed environment.

Attribution

lwt-node would not be possible without all the hard work from the maintainers and contributors of of lwt. lwt-node is powered by lwt and the ocaml standard lib. Lwt provides a battle tested promise implementation and async operators. If you love lwt-node I recommend showing love to the lwt project.

License

MIT

lwt-node's People

Contributors

aantron avatar agtlucas avatar jpuri avatar kennetpostigo avatar zploskey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lwt-node's Issues

`esy add lwt-node` fails

I'm using Linux and I have a local installation of OPAM. In case that information helps.

Complete Output
error @opam/reason (node_modules/@opam/reason) failed to build.

The error below is likely a bug in Esy itself, please report it.

  Error: Command failed.
Exit code: 1
Command: /home/despairblue/yarn/node_modules/@esy-ocaml/ocamlrun/install/bin/ocamlrun
Arguments: /home/despairblue/yarn/node_modules/esy/bin/esyBuildPackage -B -
Directory: /home/despairblue/git/node-lwt/my-esy-project
Output:
# esy-build-package: running: 'jbuilder' 'build' '--root' '.'
    ocamldep src/reason-merlin/ocamlmerlin_reason.depends.ocamldep-output
    ocamldep src/reason-parser/menhir_error_processor.depends.ocamldep-output
    ocamldep src/ppx/ppx_react.depends.ocamldep-output
    ocamldep src/refmt/refmt_impl.depends.ocamldep-output
    ocamldep src/refmttype/reason_format_type.depends.ocamldep-output
    ocamldep src/reason-parser-tests/testOprint.depends.ocamldep-output
    ocamldep src/reason-parser/vendor/easy_format/reason.easy_format.dependsi.ocamldep-output
    ocamldep src/reason-parser/vendor/easy_format/reason.easy_format.depends.ocamldep-output
    ocamldep src/rtop/reason.rtop.depends.ocamldep-output
    ocamllex src/reason-parser/reason_lexer.ml
      ocamlc src/reason-parser/menhir_error_processor.{cmi,cmo,cmt}
    ocamldep src/ppx/ppx_react.dependsi.ocamldep-output
    ocamldep src/reason-parser/vendor/cmdliner/reason.cmdliner.dependsi.ocamldep-output
    ocamldep src/reason-parser/vendor/cmdliner/reason.cmdliner.depends.ocamldep-output
      ocamlc src/reason-parser/vendor/easy_format/easy_format.{cmi,cmti}
      ocamlc src/reason-parser/vendor/cmdliner/cmdliner.{cmi,cmti}
    ocamlopt src/reason-parser/menhir_error_processor.{cmx,o}
      ocamlc src/reason-parser/vendor/easy_format/easy_format.{cmo,cmt}
    ocamlopt src/reason-parser/vendor/easy_format/easy_format.{cmx,o}
  ocamlbuild src/reasonbuild/myocamlbuild
ocamlopt.opt unix.cmxa -I /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocamlbuild-0.12.0-5d1c6b48/lib/ocamlbuild /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocamlbuild-0.12.0-5d1c6b48/lib/ocamlbuild/ocamlbuildlib.cmxa myocamlbuild.ml /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocamlbuild-0.12.0-5d1c6b48/lib/ocamlbuild/ocamlbuild.cmx -o myocamlbuild
      ocamlc src/reason-parser/vendor/easy_format/reason.easy_format.cma
    ocamlopt src/reason-parser/vendor/easy_format/reason.easy_format.{a,cmxa}
    ocamlopt src/reason-parser/menhir_error_processor.exe
    ocamlopt src/reason-parser/vendor/easy_format/reason.easy_format.cmxs
    ocamlopt src/reason-parser/vendor/cmdliner/cmdliner.{cmx,o}
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 427, characters 15-32:
Warning 3: deprecated: String.capitalize
Use String.capitalize_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 428, characters 15-31:
Warning 3: deprecated: String.uppercase
Use String.uppercase_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 507, characters 16-32:
Warning 3: deprecated: String.lowercase
Use String.lowercase_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 529, characters 20-36:
Warning 3: deprecated: String.lowercase
Use String.lowercase_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 534, characters 19-35:
Warning 3: deprecated: String.lowercase
Use String.lowercase_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 534, characters 45-61:
Warning 3: deprecated: String.lowercase
Use String.lowercase_ascii instead.
File "src/reason-parser/vendor/cmdliner/cmdliner.ml", line 917, characters 31-47:
Warning 3: deprecated: String.lowercase
Use String.lowercase_ascii instead.
    ocamlopt src/reason-parser/vendor/cmdliner/reason.cmdliner.{a,cmxa}
        bash src/reason-parser/reason_parser.messages
Read 0 sample input sentences and 0 error messages.
      menhir src/reason-parser/reason_parser_message.ml
Read 0 sample input sentences and 0 error messages.
      menhir src/reason-parser/reason_parser.{cmly,ml,mli}
Warning: you are using the standard library and/or the %inline keyword. We
recommend switching on --infer in order to avoid obscure type error messages.
    ocamldep src/reason-parser/reason.dependsi.ocamldep-output
      ocamlc src/reason-parser/reason_parser.{cmi,cmti}
menhir_error_processor src/reason-parser/reason_parser_explain_raw.ml
    ocamldep src/reason-parser/reason.depends.ocamldep-output
      ocamlc src/reason-parser/reason_config.{cmi,cmo,cmt}
      ocamlc src/reason-parser/reason_heuristics.{cmi,cmo,cmt}
      ocamlc src/reason-parser/reason_parser_message.{cmi,cmo,cmt}
      ocamlc src/reason-parser/reason_lexer.{cmi,cmo,cmt}
    ocamlopt src/reason-parser/reason_config.{cmx,o}
      ocamlc src/reason-parser/syntax_util.{cmi,cmo,cmt}
      ocamlc src/reason-parser/reason_oprint.{cmi,cmo,cmt}
File "src/reason-parser/reason_oprint.ml", line 203, characters 27-42:
Warning 52: Code should not depend on the actual values of
this constructor's arguments. They are only for information
and may change in future versions. (See manual section 8.5)
    ocamlopt src/reason-parser/reason_heuristics.{cmx,o}
    ocamlopt src/reason-parser/reason_parser_message.{cmx,o}
    ocamlopt src/reason-parser/syntax_util.{cmx,o}
    ocamlopt src/reason-parser/reason_oprint.{cmx,o}
File "src/reason-parser/reason_oprint.ml", line 203, characters 27-42:
Warning 52: Code should not depend on the actual values of
this constructor's arguments. They are only for information
and may change in future versions. (See manual section 8.5)
      ocamlc src/reason-parser/reason_pprint_ast.{cmi,cmo,cmt}
      ocamlc src/reason-parser/reason_parser_explain_raw.{cmi,cmo,cmt}
    ocamlopt src/reason-parser/reason_parser_explain_raw.{cmx,o}
      ocamlc src/reason-parser/reason_parser_explain.{cmi,cmo,cmt}
File "src/reason-parser/reason_parser_explain.ml", line 38, characters 15-34:
Warning 3: deprecated: String.uncapitalize
Use String.uncapitalize_ascii instead.
      ocamlc src/reason-parser/reason_toolchain.{cmi,cmo,cmt}
      ocamlc src/reason-merlin/ocamlmerlin_reason.{cmi,cmo,cmt}
      ocamlc src/ppx/ppx_react.{cmi,cmo,cmt}
      ocamlc src/reason-parser-tests/testOprint.{cmi,cmo,cmt}
      ocamlc src/rtop/reason_util.{cmi,cmo,cmt}
      ocamlc src/ppx/reactjs_jsx_ppx_v2.{cmi,cmti}
      ocamlc src/ppx/reactjs_jsx_ppx_v3.{cmi,cmti}
      ocamlc src/refmt/package.{cmi,cmo,cmt}
      ocamlc src/refmt/printer_maker.{cmi,cmo,cmt} (exit 2)
(cd _build/default && /home/despairblue/.esy/3______________________________________________________________/i/ocaml-4.6.1-2f0a0fce/bin/ocamlc.opt -w -40 -g -bin-annot -I /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__menhir-20171013.0.0-32d1b066/lib/menhirLib -I /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocaml_migrate_parsetree-1.0.7-314f3abb/lib/ocaml-migrate-parsetree -I /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocamlfind-1.7.3--1-4a313506/lib/ocaml/compiler-libs -I /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__result-1.2.0-560456b7/lib/result -I src/reason-parser -I src/reason-parser/vendor/cmdliner -I src/reason-parser/vendor/easy_format -no-alias-deps -I src/refmt -o src/refmt/printer_maker.cmo -c -impl src/refmt/printer_maker.ml)
File "src/refmt/printer_maker.ml", line 1:
Error: The files /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__ocaml_migrate_parsetree-1.0.7-314f3abb/lib/ocaml-migrate-parsetree/migrate_parsetree.cmi
       and /home/despairblue/.esy/3______________________________________________________________/i/opam__slash__result-1.2.0-560456b7/lib/result/result.cmi
       make inconsistent assumptions over interface Result

Waiting for 3 jobs to finish.
esy-build-package: run
                   ['/home/despairblue/.esy/3______________________________________________________________/i/opam__slash__jbuilder-1.0.0-beta17-9fc1eed9/bin/jbuilder'
                        'build' '--root' '.']: exited with 1
    at ChildProcess.<anonymous> (/home/despairblue/yarn/node_modules/esy/bin/esy.js:39224:15)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)

Introduction of GADT's for Unix.* and Lwt_unix.* types

So I introduced GADT's thanks to @aantron teaching me about them! I updated the implementation and interface files to use them, however I ran into a few issues that I wasn't sure how to get through/make type check. Firstly, I couldn't get the following functions to type check in FS when trying to change their types and implementation to use the GADT's:

  • fstat
  • fstatSync
  • lstat
  • lstatSync
  • stat
  • statSync
  • _open
  • openSync

Also, I don't want my users to know the GADT's exist at all, so I tried to not expose them in the interface and only use them in the implementation, however when I did that and tried to run the example I would get a type error, so I exposed them in the interface updated the example and it ran. But the user knows about it now so it is a little awkward. Heres the before and after from the user perspective,

Before:

Node.run {
  Fs.mkdir "testDirAsync0" 416 (Fs.(fun
    | Ok => {
        let x = 3 * 9;
        prerr_endline("\n\n" ^ (string_of_int x) ^ "\n\n");
      }
    | Err e => prerr_endline "\n\n====ERR====\n\n"
  ));
};

After:

Node.run {
  Fs.mkdir "testDirAsync0" (Fs.AsyncFilePerm 416) (Fs.(fun
    | Ok => {
        let x = 3 * 9;
        prerr_endline("\n\n" ^ (string_of_int x) ^ "\n\n");
      }
    | Err e => prerr_endline "\n\n====ERR====\n\n"
  ));
};

@aantron what can I do to hide this(second argument change) from the user?

Implementation: replace most uses of `try_bind` with `on_any`

Taking Fs.read as an example:

https://github.com/kennetpostigo/reason-node/blob/0fa0a310f8ef82c2ae77ee9deefb0ac47b115a07/src/fs.re#L281-L295

This calls try_bind, so the whole function has type arguments => arguments => Lwt.t unit, i.e. it returns a final promise. This final promise represents the whole computation of (1) asking Lwt_unix to perform the read, (2) running the appropriate user callback after that. AFAIK we don't really want that final promise, we want the return type to be just unit.

You can get that by replacing try_bind with on_any.

Either way, I think there also needs to be special handling of exceptions thrown by the user's callbacks. With on_any, if any exception reaches the implementation of on_any (inside Lwt), Lwt really has nothing to do with it except terminate the entire process โ€“ it's an unhandled exception that has nowhere to go. By comparison, try_bind creates that final promise, so it stuffs unhandled exceptions into it, by rejecting it. However, in reason-node, the user will always ignore the final promise, so the exception will be silently lost, which is arguably even worse.

I guess reason-node needs to emulate whatever Node does when an exception occurs in a callback.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.