├── .eslintignore
├── dune-project
├── .dockerignore
├── bootstrap
├── shared
├── dune
└── feed.ml
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── esy.lock
├── .gitignore
├── .gitattributes
├── opam
│ ├── ocamlfind.1.8.1
│ │ ├── files
│ │ │ ├── ocaml-stub
│ │ │ └── ocamlfind.install
│ │ └── opam
│ ├── base-unix.base
│ │ └── opam
│ ├── base-threads.base
│ │ └── opam
│ ├── conf-m4.1
│ │ └── opam
│ ├── fix.20201120
│ │ └── opam
│ ├── ppx_derivers.1.2.1
│ │ └── opam
│ ├── result.1.5
│ │ └── opam
│ ├── menhir.20210310
│ │ └── opam
│ ├── menhirLib.20210310
│ │ └── opam
│ ├── menhirSdk.20210310
│ │ └── opam
│ ├── dot-merlin-reader.4.1
│ │ └── opam
│ ├── merlin-extend.0.6
│ │ └── opam
│ ├── yojson.1.7.0
│ │ └── opam
│ ├── cppo.1.6.7
│ │ └── opam
│ ├── easy-format.1.3.2
│ │ └── opam
│ ├── biniou.1.2.1
│ │ └── opam
│ ├── csexp.1.4.0
│ │ └── opam
│ ├── dune.2.8.4
│ │ └── opam
│ └── merlin.4.1-412
│ │ └── opam
├── overrides
│ ├── opam__s__conf_m4_opam__c__1_opam_override
│ │ └── package.json
│ └── opam__s__ocamlfind_opam__c__1.8.1_opam_override
│ │ ├── package.json
│ │ └── files
│ │ └── findlib-1.8.1.patch
└── index.json
├── lambda
├── util.ml
├── dune
└── lambda.ml
├── .nowignore
├── dune
├── src
├── units.scss
├── ui.re
├── App.test.js
├── palette.scss
├── request.ml
├── index.scss
├── Ui.module.scss
├── api.re
├── let_syntax.ml
├── decode_feed.ml
├── index.re
├── utils.ml
├── App.module.scss
├── logo.svg
├── App.re
└── serviceWorker.js
├── nix
├── default.nix
├── ci.nix
└── generic.nix
├── .github
└── workflows
│ └── test.yml
├── bsconfig.json
├── .gitignore
├── shell.nix
├── esy.json
├── flake.nix
├── .ocamlformat
├── LICENSE
├── now.json
├── package.json
├── Dockerfile
├── flake.lock
└── README.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | *.bs.js
2 |
--------------------------------------------------------------------------------
/dune-project:
--------------------------------------------------------------------------------
1 | (lang dune 3.1)
2 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | _esy
2 | /node_modules
3 |
--------------------------------------------------------------------------------
/bootstrap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anmonteiro/gh-feed-reader/HEAD/bootstrap
--------------------------------------------------------------------------------
/shared/dune:
--------------------------------------------------------------------------------
1 | (library
2 | (name feed)
3 | (preprocess
4 | (pps ppx_deriving_yojson)))
5 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anmonteiro/gh-feed-reader/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/esy.lock/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Reset any possible .gitignore, we want all esy.lock to be un-ignored.
3 | !*
4 |
--------------------------------------------------------------------------------
/lambda/util.ml:
--------------------------------------------------------------------------------
1 | module Option = struct
2 | let map ~f = function None -> None | Some x -> Some (f x)
3 | end
4 |
--------------------------------------------------------------------------------
/esy.lock/.gitattributes:
--------------------------------------------------------------------------------
1 |
2 | # Set eol to LF so files aren't converted to CRLF-eol on Windows.
3 | * text eol=lf linguist-generated
4 |
--------------------------------------------------------------------------------
/.nowignore:
--------------------------------------------------------------------------------
1 | /*
2 | !bootstrap
3 | !cacert.pem
4 | !package.json
5 | !src
6 | !shared
7 | !bsconfig.json
8 | !public
9 | !yarn.lock
10 | !vendor
11 |
--------------------------------------------------------------------------------
/dune:
--------------------------------------------------------------------------------
1 | (env
2 | (release
3 | (ocamlopt_flags
4 | (:standard -O3 -unbox-closures))))
5 |
6 | ;;;;{BSB GENERATED: NO EDIT;;;;BSB GENERATED: NO EDIT}
7 |
--------------------------------------------------------------------------------
/esy.lock/opam/ocamlfind.1.8.1/files/ocaml-stub:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | BINDIR=$(dirname "$(command -v ocamlc)")
4 | "$BINDIR/ocaml" -I "$OCAML_TOPLEVEL_PATH" "$@"
5 |
--------------------------------------------------------------------------------
/src/units.scss:
--------------------------------------------------------------------------------
1 | @function unit($value) {
2 | @return $value * 16px;
3 | }
4 |
5 | $xs: unit(0.25);
6 | $s: unit(0.5);
7 | $m: unit(1);
8 | $l: unit(2);
9 | $xl: unit(4);
10 |
--------------------------------------------------------------------------------
/esy.lock/opam/base-unix.base/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "https://github.com/ocaml/opam-repository/issues"
3 | description: """
4 | Unix library distributed with the OCaml compiler
5 | """
6 |
7 |
--------------------------------------------------------------------------------
/esy.lock/opam/base-threads.base/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "https://github.com/ocaml/opam-repository/issues"
3 | description: """
4 | Threads library distributed with the OCaml compiler
5 | """
6 |
7 |
--------------------------------------------------------------------------------
/esy.lock/overrides/opam__s__conf_m4_opam__c__1_opam_override/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": "true",
3 | "dependencies": {
4 | "esy-m4": "esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/esy.lock/opam/ocamlfind.1.8.1/files/ocamlfind.install:
--------------------------------------------------------------------------------
1 | bin: [
2 | "src/findlib/ocamlfind" {"ocamlfind"}
3 | "?src/findlib/ocamlfind_opt" {"ocamlfind"}
4 | "?tools/safe_camlp4"
5 | ]
6 | toplevel: ["src/findlib/topfind"]
7 |
--------------------------------------------------------------------------------
/src/ui.re:
--------------------------------------------------------------------------------
1 | [@bs.module] external css: Js.t({..}) as 'a = "./Ui.module.scss";
2 |
3 | module Card = {
4 | [@react.component]
5 | let make = (~children) => {
6 |
;
9 | };
10 | };
11 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/lambda/dune:
--------------------------------------------------------------------------------
1 | (executable
2 | (name lambda)
3 | (libraries lambda-runtime vercel piaf lwt_ssl logs.fmt fmt.tty uri syndic
4 | lambdasoup feed)
5 | (preprocess
6 | (pps ppx_deriving_yojson)))
7 |
8 | (env
9 | (static
10 | (flags
11 | (:standard -ccopt -static))
12 | (ocamlopt_flags
13 | (:standard -O3 -unbox-closures))))
14 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/nix/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs }:
2 |
3 | let
4 | inherit (pkgs) lib callPackage pkgsCross;
5 | in
6 | {
7 | native = callPackage ./generic.nix {
8 | inherit (lib) filterGitSource;
9 | };
10 |
11 | musl64 =
12 | let pkgs = pkgsCross.musl64;
13 | in
14 | pkgs.callPackage ./generic.nix {
15 | static = true;
16 | inherit (lib) filterGitSource;
17 | ocamlPackages = pkgs.ocamlPackages;
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: "Build"
2 | on:
3 | pull_request:
4 | push:
5 | branches:
6 | - master
7 | jobs:
8 | tests:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - uses: cachix/install-nix-action@v16
13 | - uses: cachix/cachix-action@v10
14 | with:
15 | name: anmonteiro
16 | signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
17 | - name: "Run nix-build"
18 | run: nix-build ./nix/ci.nix
19 |
--------------------------------------------------------------------------------
/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reason-scripts",
3 | "sources": [
4 | "src",
5 | "shared"
6 | ],
7 | "bs-dependencies": [
8 | "@rescript/react",
9 | "bs-decoders",
10 | "bs-fetch",
11 | "reason-promise"
12 | ],
13 | "warnings": {
14 | "error": "+A",
15 | "number": "-44-101"
16 | },
17 | "refmt": 3,
18 | "reason": {
19 | "react-jsx": 3
20 | },
21 | "package-specs": {
22 | "module": "es6",
23 | "in-source": true
24 | },
25 | "suffix": ".bs.js"
26 | }
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # OCaml / BuckleScript
26 | .merlin
27 | _build
28 | _esy
29 | *.bs.js
30 | lib/
31 | .bsb.lock
32 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | { pkgs }:
2 |
3 | with pkgs;
4 |
5 | mkShell {
6 | buildInputs = with ocamlPackages; [
7 | nodejs_latest
8 | yarn
9 | merlin
10 | melange
11 | reason
12 | python3
13 | # ocamlformat
14 | dune
15 | ocaml
16 | findlib
17 | dot-merlin-reader
18 | # merlin
19 | ];
20 |
21 | inputsFrom = [ (pkgs.callPackage ./nix { }).native ];
22 |
23 | BSB_PATH = "/Users/anmonteiro/projects/melange";
24 | shellHook = ''
25 | PATH=$BSB_PATH/bin:$PATH
26 | '';
27 | }
28 |
--------------------------------------------------------------------------------
/src/palette.scss:
--------------------------------------------------------------------------------
1 | /* Coolors Exported Palette - coolors.co/26547c-bac1b8-f8fff4-ed6a5a-f4f1bb */
2 |
3 | /* HSL */
4 | $blue: hsla(208%, 53%, 32%, 1);
5 | $gray: hsla(107%, 7%, 74%, 1);
6 | $cream: hsla(98%, 100%, 98%, 1);
7 | $red: hsla(7%, 80%, 64%, 1);
8 | $blond: hsla(57%, 72%, 85%, 1);
9 | $baby: hsla(60%, 100%, 99%, 1);
10 |
11 | /* RGB */
12 | $blue: rgba(38, 84, 124, 1);
13 | $gray: rgba(186, 193, 184, 1);
14 | $cream: rgba(248, 255, 244, 1);
15 | $red: rgba(237, 106, 90, 1);
16 | $blond: rgba(244, 241, 187, 1);
17 | $baby: rgba(255, 255, 250, 1);
18 |
--------------------------------------------------------------------------------
/src/request.ml:
--------------------------------------------------------------------------------
1 | open Let_syntax.Bindings
2 |
3 | external js_error_message : Js.Promise.error -> string = "message" [@@bs.get]
4 |
5 | let request_json endpoint =
6 | let+ response =
7 | Bs_fetch.(
8 | fetchWithInit
9 | endpoint
10 | (RequestInit.make
11 | ~mode:CORS
12 | ~headers:
13 | (HeadersInit.makeWithArray [| "accept", "application/json" |])
14 | ()))
15 | |> Js.Promise.then_ Bs_fetch.Response.json
16 | |. Promise.Js.fromBsPromise
17 | |. Promise.Js.toResult
18 | in
19 | match response with Ok r -> Ok r | Error msg -> Error (js_error_message msg)
20 |
--------------------------------------------------------------------------------
/esy.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "bs-platform": "*",
4 | "@opam/merlin": "*"
5 | },
6 | "resolutions": {
7 | "bs-platform": "EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa",
8 | "ocaml": "anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb"
9 | },
10 | "esy": {
11 | "buildsInSource": "_build",
12 | "build": [
13 | "ln -sfn #{bs-platform.install} node_modules/bs-platform",
14 | "sh -c \"echo '(lang dune 2.7)' > node_modules/bs-decoders/dune-project\"",
15 | "bsb -clean-world -make-world"
16 | ]
17 | },
18 | "installConfig": {
19 | "pnp": false
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description = "Piaf Nix Flake";
3 |
4 | inputs.flake-utils.url = "github:numtide/flake-utils";
5 | inputs.nixpkgs.url = "github:anmonteiro/nix-overlays";
6 |
7 | outputs = { self, nixpkgs, flake-utils }:
8 | flake-utils.lib.eachDefaultSystem (system:
9 | let
10 | pkgs = nixpkgs.legacyPackages.${system}.extend (self: super: {
11 | ocamlPackages = super.ocaml-ng.ocamlPackages_4_14;
12 | });
13 | in
14 | rec {
15 | packages = pkgs.callPackage ./nix { inherit pkgs; };
16 | defaultPackage = packages.native;
17 | devShell = import ./shell.nix { inherit pkgs; };
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/src/index.scss:
--------------------------------------------------------------------------------
1 | @import "~normalize.css";
2 | @import "./palette.scss";
3 |
4 | body {
5 | background-color: $cream;
6 | margin: 0;
7 | padding: 0;
8 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
9 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
10 | sans-serif;
11 | -webkit-font-smoothing: antialiased;
12 | -moz-osx-font-smoothing: grayscale;
13 | }
14 |
15 | code {
16 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
17 | monospace;
18 | }
19 |
20 | a {
21 | color: $blue;
22 | }
23 |
24 | *,
25 | *:before,
26 | *:after {
27 | box-sizing: border-box;
28 | -moz-box-sizing: border-box;
29 | -webkit-box-sizing: border-box;
30 | -ms-box-sizing: border-box;
31 | }
32 |
--------------------------------------------------------------------------------
/esy.lock/opam/conf-m4.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "tim@gfxmonk.net"
3 | homepage: "http://www.gnu.org/software/m4/m4.html"
4 | bug-reports: "https://github.com/ocaml/opam-repository/issues"
5 | authors: "GNU Project"
6 | license: "GPL-3.0-only"
7 | build: [["sh" "-exc" "echo | m4"]]
8 | depexts: [
9 | ["m4"] {os-family = "debian"}
10 | ["m4"] {os-distribution = "fedora"}
11 | ["m4"] {os-distribution = "rhel"}
12 | ["m4"] {os-distribution = "centos"}
13 | ["m4"] {os-distribution = "alpine"}
14 | ["m4"] {os-distribution = "nixos"}
15 | ["m4"] {os-family = "suse"}
16 | ["m4"] {os-distribution = "ol"}
17 | ["m4"] {os-distribution = "arch"}
18 | ]
19 | synopsis: "Virtual package relying on m4"
20 | description:
21 | "This package can only install if the m4 binary is installed on the system."
22 | flags: conf
23 |
--------------------------------------------------------------------------------
/.ocamlformat:
--------------------------------------------------------------------------------
1 | break-infix = fit-or-vertical
2 | break-infix-before-func = false
3 | break-fun-decl = fit-or-vertical
4 | break-separators = before
5 | break-sequences = true
6 | cases-exp-indent = 2
7 | dock-collection-brackets = false
8 | field-space = loose
9 | if-then-else = keyword-first
10 | indicate-multiline-delimiters = no
11 | infix-precedence = parens
12 | leading-nested-match-parens = true
13 | let-and = sparse
14 | let-module = sparse
15 | ocp-indent-compat = true
16 | parens-tuple = multi-line-only
17 | parse-docstrings = true
18 | sequence-blank-line = preserve-one
19 | sequence-style = terminator
20 | single-case = sparse
21 | space-around-arrays= true
22 | space-around-lists= true
23 | space-around-records= true
24 | space-around-variants= true
25 | type-decl = sparse
26 | wrap-comments = true
27 | wrap-fun-args = false
28 |
29 |
--------------------------------------------------------------------------------
/esy.lock/opam/fix.20201120/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | ]
6 | homepage: "https://gitlab.inria.fr/fpottier/fix"
7 | dev-repo: "git+https://gitlab.inria.fr/fpottier/fix.git"
8 | bug-reports: "francois.pottier@inria.fr"
9 | build: [
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "ocaml" { >= "4.03" }
14 | "dune" {>= "1.3" }
15 | ]
16 | synopsis: "Facilities for memoization and fixed points"
17 | url {
18 | src:
19 | "https://gitlab.inria.fr/fpottier/fix/repository/20201120/archive.tar.gz"
20 | checksum: [
21 | "md5=7eb570b759635fe66f3556d2b1cc88e3"
22 | "sha512=344dcc619f9e8b8a6c998775b6d2dab2ea5253e6a67abe4797f76dc5dd30bc776568abce1e90477422e9db447821579889737e3531c42139708f813e983ea5d4"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/nix/ci.nix:
--------------------------------------------------------------------------------
1 | { ocamlVersion ? "4_12" }:
2 |
3 | let
4 | lock = builtins.fromJSON (builtins.readFile ./../flake.lock);
5 | src = fetchGit {
6 | url = with lock.nodes.nixpkgs.locked;"https://github.com/${owner}/${repo}";
7 | inherit (lock.nodes.nixpkgs.locked) rev;
8 | # inherit (lock.nodes.nixpkgs.original) ref;
9 | };
10 | pkgs = import "${src}/boot.nix" {
11 | overlays = [
12 | (import src)
13 | (self: super: {
14 | ocamlPackages = super.ocaml-ng."ocamlPackages_${ocamlVersion}";
15 |
16 | pkgsCross.musl64 = super.pkgsCross.musl64 // {
17 | ocamlPackages = super.pkgsCross.musl64.ocaml-ng."ocamlPackages_${ocamlVersion}";
18 | };
19 | })
20 | ];
21 | };
22 |
23 | inherit (pkgs) lib stdenv fetchTarball ocamlPackages;
24 |
25 | in
26 |
27 | (pkgs.callPackage ./. { }).musl64
28 |
--------------------------------------------------------------------------------
/src/Ui.module.scss:
--------------------------------------------------------------------------------
1 | @import "./palette.scss";
2 | @import "./units.scss";
3 |
4 | .card {
5 | position: relative;
6 | display: flex;
7 | background-color: $baby;
8 | border-radius: 8px;
9 | box-shadow: 0 $xs $xs 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
10 | margin-bottom: $s;
11 | transition: all 0.3s;
12 | }
13 |
14 | .card::after {
15 | content: " ";
16 | position: absolute;
17 | border-radius: 8px;
18 | z-index: -1;
19 | top: 0;
20 | left: 0;
21 | width: 100%;
22 | height: 100%;
23 | box-shadow: 0 $xs $s 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
24 | opacity: 0;
25 | transition: opacity 0.3s;
26 | }
27 |
28 | .card:hover {
29 | margin-bottom: $m;
30 | transform: scale(1.01);
31 | }
32 |
33 | .card:hover::after {
34 | opacity: 1;
35 | }
36 |
37 | .cardInner {
38 | margin: 20px;
39 | }
40 |
--------------------------------------------------------------------------------
/esy.lock/opam/ppx_derivers.1.2.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "jeremie@dimino.org"
3 | authors: ["Jérémie Dimino"]
4 | license: "BSD-3-Clause"
5 | homepage: "https://github.com/ocaml-ppx/ppx_derivers"
6 | bug-reports: "https://github.com/ocaml-ppx/ppx_derivers/issues"
7 | dev-repo: "git://github.com/ocaml-ppx/ppx_derivers.git"
8 | build: [
9 | ["dune" "build" "-p" name "-j" jobs]
10 | ]
11 | depends: [
12 | "ocaml"
13 | "dune"
14 | ]
15 | synopsis: "Shared [@@deriving] plugin registry"
16 | description: """
17 | Ppx_derivers is a tiny package whose sole purpose is to allow
18 | ppx_deriving and ppx_type_conv to inter-operate gracefully when linked
19 | as part of the same ocaml-migrate-parsetree driver."""
20 | url {
21 | src: "https://github.com/ocaml-ppx/ppx_derivers/archive/1.2.1.tar.gz"
22 | checksum: "md5=5dc2bf130c1db3c731fe0fffc5648b41"
23 | }
24 |
--------------------------------------------------------------------------------
/esy.lock/opam/result.1.5/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "opensource@janestreet.com"
3 | authors: ["Jane Street Group, LLC "]
4 | homepage: "https://github.com/janestreet/result"
5 | dev-repo: "git+https://github.com/janestreet/result.git"
6 | bug-reports: "https://github.com/janestreet/result/issues"
7 | license: "BSD-3-Clause"
8 | build: [["dune" "build" "-p" name "-j" jobs]]
9 | depends: [
10 | "ocaml"
11 | "dune" {>= "1.0"}
12 | ]
13 | synopsis: "Compatibility Result module"
14 | description: """
15 | Projects that want to use the new result type defined in OCaml >= 4.03
16 | while staying compatible with older version of OCaml should use the
17 | Result module defined in this library."""
18 | url {
19 | src:
20 | "https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz"
21 | checksum: "md5=1b82dec78849680b49ae9a8a365b831b"
22 | }
23 |
--------------------------------------------------------------------------------
/shared/feed.ml:
--------------------------------------------------------------------------------
1 | module Author = struct
2 | type t =
3 | { name : string
4 | ; uri : string option
5 | ; email : string option
6 | }
7 | [@@deriving yojson]
8 | end
9 |
10 | module Link = struct
11 | type t =
12 | { title : string
13 | ; href : string
14 | }
15 | [@@deriving yojson]
16 | end
17 |
18 | module Entry = struct
19 | type t =
20 | { authors : Author.t * Author.t list
21 | ; content : string option
22 | ; id : string
23 | ; links : Link.t list
24 | ; published : float option
25 | ; title : string
26 | ; updated : float
27 | }
28 | [@@deriving yojson]
29 | end
30 |
31 | type t =
32 | { authors : Author.t list
33 | ; id : string
34 | ; links : Link.t list
35 | ; logo : string option
36 | ; subtitle : string option
37 | ; title : string
38 | ; updated : float
39 | ; entries : Entry.t list
40 | }
41 | [@@deriving yojson]
42 |
--------------------------------------------------------------------------------
/nix/generic.nix:
--------------------------------------------------------------------------------
1 | { filterGitSource, stdenv, openssl, ocamlPackages, static ? false }:
2 |
3 | stdenv.mkDerivation {
4 | name = "gh-feed-lambda";
5 | version = "dev";
6 |
7 | src = filterGitSource {
8 | src = ./..;
9 | dirs = [ "lambda" "shared" ];
10 | files = [ "dune-project" ];
11 | };
12 |
13 | nativeBuildInputs = with ocamlPackages; [ dune_2 ocaml findlib ];
14 |
15 | buildPhase = ''
16 | echo "running ${if static then "static" else "release"} build"
17 | dune build lambda/lambda.exe --display=short --profile=${if static then "static" else "release"}
18 | '';
19 | installPhase = ''
20 | mkdir -p $out/bin
21 | mv _build/default/lambda/lambda.exe $out/bin/lambda.exe
22 | '';
23 |
24 | buildInputs = with ocamlPackages; [
25 | piaf
26 | lambdasoup
27 | ppx_deriving_yojson
28 | syndic
29 | lwt
30 | fmt
31 | vercel
32 | ];
33 |
34 | doCheck = false;
35 | }
36 |
--------------------------------------------------------------------------------
/esy.lock/opam/menhir.20210310/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "menhir@inria.fr"
10 | build: [
11 | ["dune" "build" "-p" name "-j" jobs]
12 | ]
13 | depends: [
14 | "ocaml" {>= "4.02.3"}
15 | "dune" { >= "2.2.0"}
16 | "menhirLib" {= version}
17 | "menhirSdk" {= version}
18 | ]
19 | synopsis: "An LR(1) parser generator"
20 | url {
21 | src:
22 | "https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz"
23 | checksum: [
24 | "md5=1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
25 | "sha512=3c309fa2cc4ad7c6fba85107bd946a542894882fa39741496b150307e93455b717418f19e94b5dad06ab269f5c55e8dc25705c96c0a5092e623fa38f1ce43c7f"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/esy.lock/opam/menhirLib.20210310/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "menhir@inria.fr"
10 | build: [
11 | ["dune" "build" "-p" name "-j" jobs]
12 | ]
13 | depends: [
14 | "ocaml" { >= "4.02.3" }
15 | "dune" { >= "2.0.0" }
16 | ]
17 | conflicts: [
18 | "menhir" { != version }
19 | ]
20 | synopsis: "Runtime support library for parsers generated by Menhir"
21 | url {
22 | src:
23 | "https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz"
24 | checksum: [
25 | "md5=1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
26 | "sha512=3c309fa2cc4ad7c6fba85107bd946a542894882fa39741496b150307e93455b717418f19e94b5dad06ab269f5c55e8dc25705c96c0a5092e623fa38f1ce43c7f"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/esy.lock/opam/menhirSdk.20210310/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "menhir@inria.fr"
10 | build: [
11 | ["dune" "build" "-p" name "-j" jobs]
12 | ]
13 | depends: [
14 | "ocaml" { >= "4.02.3" }
15 | "dune" { >= "2.0.0" }
16 | ]
17 | conflicts: [
18 | "menhir" { != version }
19 | ]
20 | synopsis: "Compile-time library for auxiliary tools related to Menhir"
21 | url {
22 | src:
23 | "https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz"
24 | checksum: [
25 | "md5=1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
26 | "sha512=3c309fa2cc4ad7c6fba85107bd946a542894882fa39741496b150307e93455b717418f19e94b5dad06ab269f5c55e8dc25705c96c0a5092e623fa38f1ce43c7f"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/src/api.re:
--------------------------------------------------------------------------------
1 | let parseFeed = payload =>
2 | switch (Decoders_bs.Decode.decode_value(Decode_feed.decode_feed, payload)) {
3 | | Ok(data) => Ok(data)
4 | | Error(e) => Error(Format.asprintf("%a", Decoders_bs.Decode.pp_error, e))
5 | };
6 |
7 | let feedEndpoint = (~token=?, ~page, user) => {
8 | let endpoint = {j|https://gh-feed.now.sh/api?user=$(user)&page=$(page)|j};
9 | switch (token) {
10 | | None => endpoint
11 | | Some(token) => {j|$(endpoint)&token=$(token)|j}
12 | };
13 | };
14 |
15 | let fetcher = endpoint => {
16 | let p_result = Request.request_json(endpoint);
17 | Promise.map(p_result, r => Belt.Result.flatMap(r, parseFeed));
18 | };
19 |
20 | module SWR = {
21 | module SWRConfig = {
22 | [@bs.module "swr"] [@react.component]
23 | external make:
24 | (~value: Js.t({..}), ~children: React.element) => React.element =
25 | "SWRConfig";
26 | };
27 |
28 | type t('data, 'error) = {
29 | data: option('data),
30 | error: option('error),
31 | };
32 |
33 | [@bs.module "swr"] external useSWR: string => t('data, 'error) = "default";
34 | };
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Antonio Nuno Monteiro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/esy.lock/opam/dot-merlin-reader.4.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "defree@gmail.com"
3 | authors: "The Merlin team"
4 | synopsis: "Reads config files for merlin"
5 | homepage: "https://github.com/ocaml/merlin"
6 | bug-reports: "https://github.com/ocaml/merlin/issues"
7 | dev-repo: "git+https://github.com/ocaml/merlin.git"
8 | build: [
9 | ["dune" "subst"] {pinned}
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "ocaml" {>= "4.06.1" }
14 | "dune" {>= "2.7.0"}
15 | "yojson" {>= "1.6.0"}
16 | "ocamlfind" {>= "1.6.0"}
17 | "csexp" {>= "1.2.3"}
18 | "result" {>= "1.5"}
19 | ]
20 | description:
21 | "Helper process: reads .merlin files and gives the normalized content to merlin"
22 | x-commit-hash: "ab02f60994c81166820791b5f465f467d752b8dc"
23 | url {
24 | src:
25 | "https://github.com/ocaml/merlin/releases/download/v4.1/dot-merlin-reader-v4.1.tbz"
26 | checksum: [
27 | "sha256=14a36d6fb8646a5df4530420a7861722f1a4ee04753717947305e3676031e7cd"
28 | "sha512=65fd4ab08904c05651a7ef8971802ffaa428daa920765dbcf162e3c56e8047e4c9e4356daa45efccce7c73a586635c8f6cf8118fd3059789de9aff68579bd436"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/esy.lock/overrides/opam__s__ocamlfind_opam__c__1.8.1_opam_override/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": [
3 | [
4 | "bash",
5 | "-c",
6 | "#{os == 'windows' ? 'patch -p1 < findlib-1.8.1.patch' : 'true'}"
7 | ],
8 | [
9 | "./configure",
10 | "-bindir",
11 | "#{self.bin}",
12 | "-sitelib",
13 | "#{self.lib}",
14 | "-mandir",
15 | "#{self.man}",
16 | "-config",
17 | "#{self.lib}/findlib.conf",
18 | "-no-custom",
19 | "-no-topfind"
20 | ],
21 | [
22 | "make",
23 | "all"
24 | ],
25 | [
26 | "make",
27 | "opt"
28 | ]
29 | ],
30 | "install": [
31 | [
32 | "make",
33 | "install"
34 | ],
35 | [
36 | "install",
37 | "-m",
38 | "0755",
39 | "ocaml-stub",
40 | "#{self.bin}/ocaml"
41 | ],
42 | [
43 | "mkdir",
44 | "-p",
45 | "#{self.toplevel}"
46 | ],
47 | [
48 | "install",
49 | "-m",
50 | "0644",
51 | "src/findlib/topfind",
52 | "#{self.toplevel}/topfind"
53 | ]
54 | ],
55 | "exportedEnv": {
56 | "OCAML_TOPLEVEL_PATH": {
57 | "val": "#{self.toplevel}",
58 | "scope": "global"
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/esy.lock/opam/merlin-extend.0.6/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Frederic Bour "
3 | authors: "Frederic Bour "
4 | homepage: "https://github.com/let-def/merlin-extend"
5 | bug-reports: "https://github.com/let-def/merlin-extend"
6 | license: "MIT"
7 | dev-repo: "git+https://github.com/let-def/merlin-extend.git"
8 | build: [
9 | ["dune" "subst"] {pinned}
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "dune" {>= "1.0"}
14 | "cppo" {build}
15 | "ocaml" {>= "4.02.3"}
16 | ]
17 | synopsis: "A protocol to provide custom frontend to Merlin"
18 | description: """
19 | This protocol allows to replace the OCaml frontend of Merlin.
20 | It extends what used to be done with the `-pp' flag to handle a few more cases."""
21 | doc: "https://let-def.github.io/merlin-extend"
22 | x-commit-hash: "640620568a5f5c7798239ecf7c707c813e3df3cf"
23 | url {
24 | src:
25 | "https://github.com/let-def/merlin-extend/releases/download/v0.6/merlin-extend-v0.6.tbz"
26 | checksum: [
27 | "sha256=c2f236ae97feb6ba0bc90f33beb7b7343e42f9871b66de9ba07974917e256c43"
28 | "sha512=4c64a490e2ece04fc89aef679c1d9202175df4fe045b5fdc7a37cd7cebe861226fddd9648c1bf4f06175ecfcd2ed7686c96bd6a8cae003a5096f6134c240f857"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/now.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gh-feed",
3 | "alias": "gh.an.wtf",
4 | "version": 2,
5 | "regions": [
6 | "sfo1"
7 | ],
8 | "builds": [
9 | {
10 | "src": "+(bootstrap|cacert.pem)",
11 | "use": "now-custom-runtime"
12 | },
13 | {
14 | "src": "package.json",
15 | "use": "@now/static-build",
16 | "config": {
17 | "distDir": "build"
18 | }
19 | }
20 | ],
21 | "routes": [
22 | {
23 | "src": "/api",
24 | "dest": "/bootstrap",
25 | "headers": {
26 | "cache-control": "s-maxage=180",
27 | "access-control-allow-origin": "*"
28 | }
29 | },
30 | {
31 | "src": "/favicon.ico",
32 | "dest": "/favicon.ico"
33 | },
34 | {
35 | "src": "/asset-manifest.json",
36 | "dest": "/asset-manifest.json"
37 | },
38 | {
39 | "src": "/manifest.json",
40 | "dest": "/manifest.json"
41 | },
42 | {
43 | "src": "/precache-manifest.(.*)",
44 | "dest": "/precache-manifest.$1"
45 | },
46 | {
47 | "src": "/static/(.*)",
48 | "dest": "/static/$1",
49 | "headers": {
50 | "cache-control": "s-maxage=31536000,immutable"
51 | }
52 | },
53 | {
54 | "src": "/.*",
55 | "dest": "/index.html"
56 | }
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/src/let_syntax.ml:
--------------------------------------------------------------------------------
1 | open Belt
2 |
3 | module Async = struct
4 | let ( let+ ) = Promise.map
5 |
6 | let ( let* ) = Promise.flatMap
7 |
8 | let ( and* ) a b = Promise.all2 a b
9 | end
10 |
11 | module Option = struct
12 | let ( let+ ) = Option.map
13 |
14 | let ( let* ) = Option.flatMap
15 |
16 | let ( and* ) o1 o2 =
17 | match o1, o2 with Some x, Some y -> Some (x, y) | _ -> None
18 | end
19 |
20 | module Result = struct
21 | let ( let+ ) = Result.map
22 |
23 | let ( let* ) = Result.flatMap
24 |
25 | let ( and* ) r1 r2 =
26 | match r1, r2 with
27 | | Ok x, Ok y ->
28 | Ok (x, y)
29 | | Ok _, Error e | Error e, Ok _ | Error e, Error _ ->
30 | Error e
31 | end
32 |
33 | module Bindings = struct
34 | include Async
35 |
36 | let ( let*? ) = Option.( let* )
37 |
38 | let ( let+? ) = Option.( let+ )
39 |
40 | let ( and*? ) = Option.( and* )
41 |
42 | let ( let*! ) = Result.( let* )
43 |
44 | let ( let+! ) = Result.( let+ )
45 |
46 | let ( and*! ) = Result.( and* )
47 |
48 | let ( let**! ) = Promise.flatMapOk
49 |
50 | let ( let++! ) = Promise.mapOk
51 |
52 | let ( and**! ) lr1 lr2 =
53 | Promise.all2 lr1 lr2
54 | |. Promise.map (function
55 | | Ok x, Ok y ->
56 | Ok (x, y)
57 | | Ok _, Error e | Error e, Ok _ | Error e, Error _ ->
58 | Error e)
59 | end
60 |
--------------------------------------------------------------------------------
/esy.lock/opam/yojson.1.7.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "martin@mjambon.com"
3 | authors: ["Martin Jambon"]
4 | homepage: "https://github.com/ocaml-community/yojson"
5 | bug-reports: "https://github.com/ocaml-community/yojson/issues"
6 | dev-repo: "git+https://github.com/ocaml-community/yojson.git"
7 | doc: "https://ocaml-community.github.io/yojson/"
8 | build: [
9 | ["dune" "subst"] {pinned}
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | run-test: [["dune" "runtest" "-p" name "-j" jobs]]
13 | depends: [
14 | "ocaml" {>= "4.02.3"}
15 | "dune"
16 | "cppo" {build}
17 | "easy-format"
18 | "biniou" {>= "1.2.0"}
19 | "alcotest" {with-test & >= "0.8.5"}
20 | ]
21 | synopsis:
22 | "Yojson is an optimized parsing and printing library for the JSON format"
23 | description: """
24 | Yojson is an optimized parsing and printing library for the JSON format.
25 |
26 | It addresses a few shortcomings of json-wheel including 2x speedup,
27 | polymorphic variants and optional syntax for tuples and variants.
28 |
29 | ydump is a pretty-printing command-line program provided with the
30 | yojson package.
31 |
32 | The program atdgen can be used to derive OCaml-JSON serializers and
33 | deserializers from type definitions."""
34 | url {
35 | src:
36 | "https://github.com/ocaml-community/yojson/releases/download/1.7.0/yojson-1.7.0.tbz"
37 | checksum: "md5=b89d39ca3f8c532abe5f547ad3b8f84d"
38 | }
39 |
--------------------------------------------------------------------------------
/esy.lock/opam/cppo.1.6.7/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "martin@mjambon.com"
3 | authors: "Martin Jambon"
4 | license: "BSD-3-Clause"
5 | homepage: "https://github.com/ocaml-community/cppo"
6 | doc: "https://ocaml-community.github.io/cppo/"
7 | bug-reports: "https://github.com/ocaml-community/cppo/issues"
8 | depends: [
9 | "ocaml" {>= "4.02.3"}
10 | "dune" {>= "1.0"}
11 | "base-unix"
12 | ]
13 | build: [
14 | ["dune" "subst"] {pinned}
15 | ["dune" "build" "-p" name "-j" jobs]
16 | ["dune" "runtest" "-p" name "-j" jobs] {with-test}
17 | ]
18 | dev-repo: "git+https://github.com/ocaml-community/cppo.git"
19 | synopsis: "Code preprocessor like cpp for OCaml"
20 | description: """
21 | Cppo is an equivalent of the C preprocessor for OCaml programs.
22 | It allows the definition of simple macros and file inclusion.
23 |
24 | Cppo is:
25 |
26 | * more OCaml-friendly than cpp
27 | * easy to learn without consulting a manual
28 | * reasonably fast
29 | * simple to install and to maintain
30 | """
31 | x-commit-hash: "7d217864a5fdc4551699e248137a2f8b719d2078"
32 | url {
33 | src:
34 | "https://github.com/ocaml-community/cppo/releases/download/v1.6.7/cppo-v1.6.7.tbz"
35 | checksum: [
36 | "sha256=db553e3e6c206df09b1858c3aef5e21e56564d593642a3c78bcedb6af36f529d"
37 | "sha512=9722b50fd23aaccf86816313333a3bf8fc7c6b4ef06b153e5e1e1aaf14670cf51a4aac52fb1b4a0e5531699c4047a1eff6c24c969f7e5063e78096c2195b5819"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gh-feed",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@primer/css": "^15.0.0",
7 | "@rescript/react": "^0.10.3",
8 | "bs-decoders": "^0.3.0",
9 | "bs-fetch": "^0.6.2",
10 | "cra-reason-template": "^0.1.3",
11 | "github-syntax-light": "^0.5.0",
12 | "normalize.css": "^8.0.1",
13 | "react": "experimental",
14 | "reason-promise": "^1.0.0",
15 | "swr": "^0.3.0"
16 | },
17 | "scripts": {
18 | "start": "FORCE_COLOR=true react-scripts start | cat -n",
19 | "build-cra": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject",
22 | "bs:make": "bsb.exe -make-world",
23 | "bs:watch": "bsb.exe -make-world -w",
24 | "bs:clean": "bsb.exe -clean-world",
25 | "now-build": "yarn add bs-platform@7.3.1 && yarn bs:clean && yarn bs:make && yarn build-cra"
26 | },
27 | "eslintConfig": {
28 | "extends": "react-app"
29 | },
30 | "resolutions": {
31 | "reason-react/**/react": "0.0.0-experimental-94c0244ba",
32 | "reason-react/**/react-dom": "0.0.0-experimental-94c0244ba",
33 | "react": "0.0.0-experimental-79ed5e18f-20220217",
34 | "react-dom": "0.0.0-experimental-79ed5e18f-20220217"
35 | },
36 | "browserslist": [
37 | ">0.2%",
38 | "not dead",
39 | "not ie <= 11",
40 | "not op_mini all"
41 | ],
42 | "devDependencies": {
43 | "prettier": "^2.0.5"
44 | },
45 | "installConfig": {
46 | "pnp": false
47 | },
48 | "engines": {
49 | "node": ">=10.0.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # start from node image so we can install esy from npm
2 | FROM node:12-alpine as build
3 |
4 | ENV TERM=dumb LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib
5 |
6 | RUN mkdir /esy
7 | WORKDIR /esy
8 |
9 | ENV NPM_CONFIG_PREFIX=/esy
10 | RUN npm install -g --unsafe-perm @esy-nightly/esy
11 |
12 | # now that we have esy installed we need a proper runtime
13 |
14 | FROM alpine:3.8 as esy
15 |
16 | ENV TERM=dumb LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib
17 |
18 | WORKDIR /
19 |
20 | COPY --from=build /esy /esy
21 |
22 | RUN apk add --no-cache ca-certificates wget bash curl perl-utils git patch \
23 | gcc g++ musl-dev make m4 linux-headers coreutils
24 |
25 | RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
26 | RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
27 | RUN apk add --no-cache glibc-2.28-r0.apk
28 |
29 | ENV PATH=/esy/bin:$PATH
30 |
31 | RUN mkdir /app
32 | WORKDIR /app
33 |
34 | RUN echo ' \
35 | {\
36 | "name": "package-base", \
37 | "dependencies": { \
38 | "ocaml": "~4.9.0", \
39 | "@opam/dune": ">= 2.0.0", \
40 | "@opam/conf-libssl": "*" \
41 | }, \
42 | "resolutions": { \
43 | "@opam/conf-libssl": "esy-packages/esy-openssl#77c1dbe" \
44 | } \
45 | } \
46 | ' > esy.json
47 |
48 | RUN esy
49 |
50 | COPY esy.json esy.json
51 | COPY esy.lock esy.lock
52 |
53 | RUN esy fetch
54 | RUN esy true
55 |
56 | COPY . .
57 |
58 | RUN esy b dune build lambda/lambda.exe --profile=static
59 |
60 | RUN mv $(esy echo '#{self.target_dir}')/default/lambda/lambda.exe bootstrap
61 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/decode_feed.ml:
--------------------------------------------------------------------------------
1 | module D = Decoders_bs.Decode
2 | open Feed
3 | open D.Infix
4 |
5 | let x = D.( >>= )
6 |
7 | let decode_author =
8 | D.(field "name" string) >>= fun name ->
9 | D.(maybe (field "uri" string)) >>= fun uri ->
10 | D.(maybe (field "email" string)) >>= fun email ->
11 | D.succeed { Author.name; email; uri }
12 |
13 | let decode_link =
14 | D.(field "title" string) >>= fun title ->
15 | D.(field "href" string) >>= fun href -> D.succeed { Link.title; href }
16 |
17 | let decode_entry =
18 | let decode_authors_field : (Author.t * Author.t list) D.decoder =
19 | D.index 0 decode_author >>= fun author ->
20 | D.(index 1 (list decode_author)) >>= fun authors ->
21 | D.succeed (author, authors)
22 | in
23 | D.(field "authors" decode_authors_field) >>= fun authors ->
24 | D.(maybe (field "content" string)) >>= fun content ->
25 | D.(field "id" string) >>= fun id ->
26 | D.(field "links" (list decode_link)) >>= fun links ->
27 | D.(maybe (field "published" float)) >>= fun published ->
28 | D.(field "title" string) >>= fun title ->
29 | D.(field "updated" float) >>= fun updated ->
30 | D.succeed { Entry.authors; content; id; links; published; title; updated }
31 |
32 | let decode_feed =
33 | D.(field "authors" (list decode_author)) >>= fun authors ->
34 | D.(field "id" string) >>= fun id ->
35 | D.(field "links" (list decode_link)) >>= fun links ->
36 | D.(maybe (field "logo" string)) >>= fun logo ->
37 | D.(maybe (field "subtitle" string)) >>= fun subtitle ->
38 | D.(field "title" string) >>= fun title ->
39 | D.(field "updated" float) >>= fun updated ->
40 | D.(field "entries" (list decode_entry)) >>= fun entries ->
41 | D.succeed { authors; id; links; logo; subtitle; title; updated; entries }
42 |
--------------------------------------------------------------------------------
/esy.lock/opam/easy-format.1.3.2/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | build: [
3 | ["dune" "subst"] {pinned}
4 | ["dune" "build" "-p" name "-j" jobs]
5 | ["dune" "runtest" "-p" name "-j" jobs] {with-test}
6 | ["dune" "build" "-p" name "@doc"] {with-doc}
7 | ]
8 | maintainer: ["martin@mjambon.com" "rudi.grinberg@gmail.com"]
9 | authors: ["Martin Jambon"]
10 | bug-reports: "https://github.com/mjambon/easy-format/issues"
11 | homepage: "https://github.com/mjambon/easy-format"
12 | doc: "https://mjambon.github.io/easy-format/"
13 | license: "BSD-3-Clause"
14 | dev-repo: "git+https://github.com/mjambon/easy-format.git"
15 | synopsis:
16 | "High-level and functional interface to the Format module of the OCaml standard library"
17 | description: """
18 |
19 | This module offers a high-level and functional interface to the Format module of
20 | the OCaml standard library. It is a pretty-printing facility, i.e. it takes as
21 | input some code represented as a tree and formats this code into the most
22 | visually satisfying result, breaking and indenting lines of code where
23 | appropriate.
24 |
25 | Input data must be first modelled and converted into a tree using 3 kinds of
26 | nodes:
27 |
28 | * atoms
29 | * lists
30 | * labelled nodes
31 |
32 | Atoms represent any text that is guaranteed to be printed as-is. Lists can model
33 | any sequence of items such as arrays of data or lists of definitions that are
34 | labelled with something like "int main", "let x =" or "x:"."""
35 | depends: [
36 | "dune" {>= "1.10"}
37 | "ocaml" {>= "4.02.3"}
38 | ]
39 | url {
40 | src:
41 | "https://github.com/mjambon/easy-format/releases/download/1.3.2/easy-format-1.3.2.tbz"
42 | checksum: [
43 | "sha256=3440c2b882d537ae5e9011eb06abb53f5667e651ea4bb3b460ea8230fa8c1926"
44 | "sha512=e39377a2ff020ceb9ac29e8515a89d9bdbc91dfcfa871c4e3baafa56753fac2896768e5d9822a050dc1e2ade43c8967afb69391a386c0a8ecd4e1f774e236135"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/esy.lock/opam/biniou.1.2.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | build: [
3 | ["dune" "subst"] {pinned}
4 | ["dune" "build" "-p" name "-j" jobs]
5 | ["dune" "runtest" "-p" name "-j" jobs] {with-test}
6 | ["dune" "build" "-p" name "@doc"] {with-doc}
7 | ]
8 | maintainer: ["martin@mjambon.com"]
9 | authors: ["Martin Jambon"]
10 | bug-reports: "https://github.com/mjambon/biniou/issues"
11 | homepage: "https://github.com/mjambon/biniou"
12 | doc: "https://mjambon.github.io/biniou/"
13 | license: "BSD-3-Clause"
14 | dev-repo: "git+https://github.com/mjambon/biniou.git"
15 | synopsis:
16 | "Binary data format designed for speed, safety, ease of use and backward compatibility as protocols evolve"
17 | description: """
18 |
19 | Biniou (pronounced "be new") is a binary data format designed for speed, safety,
20 | ease of use and backward compatibility as protocols evolve. Biniou is vastly
21 | equivalent to JSON in terms of functionality but allows implementations several
22 | times faster (4 times faster than yojson), with 25-35% space savings.
23 |
24 | Biniou data can be decoded into human-readable form without knowledge of type
25 | definitions except for field and variant names which are represented by 31-bit
26 | hashes. A program named bdump is provided for routine visualization of biniou
27 | data files.
28 |
29 | The program atdgen is used to derive OCaml-Biniou serializers and deserializers
30 | from type definitions.
31 |
32 | Biniou format specification: mjambon.github.io/atdgen-doc/biniou-format.txt"""
33 | depends: [
34 | "easy-format"
35 | "dune" {>= "1.10"}
36 | "ocaml" {>= "4.02.3"}
37 | ]
38 | url {
39 | src:
40 | "https://github.com/mjambon/biniou/releases/download/1.2.1/biniou-1.2.1.tbz"
41 | checksum: [
42 | "sha256=35546c68b1929a8e6d27a3b39ecd17b38303a0d47e65eb9d1480c2061ea84335"
43 | "sha512=82670cc77bf3e869ee26e5fbe5a5affa45a22bc8b6c4bd7e85473912780e0111baca59b34a2c14feae3543ce6e239d7fddaeab24b686a65bfe642cdb91d27ebf"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/src/index.re:
--------------------------------------------------------------------------------
1 | [@bs.module] external _css: Js.t({..}) = "./index.scss";
2 |
3 | [@bs.module "./serviceWorker"]
4 | external register_service_worker: unit => unit = "register";
5 | [@bs.module "./serviceWorker"]
6 | external unregister_service_worker: unit => unit = "unregister";
7 |
8 | module ReactDOM = {
9 | type root;
10 |
11 | [@bs.module "react-dom"]
12 | external createRoot: Dom.element => root = "unstable_createRoot";
13 |
14 | [@bs.send] external render: (root, React.element) => unit = "render";
15 |
16 | [@bs.val] [@bs.return nullable]
17 | external _getElementById: string => option(Dom.element) =
18 | "document.getElementById";
19 | [@bs.val]
20 | external _getElementsByClassName: string => array(Dom.element) =
21 | "document.getElementsByClassName";
22 |
23 | let renderToElementWithClassName = className =>
24 | switch (_getElementsByClassName(className)) {
25 | | [||] =>
26 | raise(
27 | Invalid_argument(
28 | "ReactDOMRe.Unstable.renderToElementWithClassName: no element of class "
29 | ++ className
30 | ++ " found in the HTML.",
31 | ),
32 | )
33 | | elements => createRoot(Array.unsafe_get(elements, 0))
34 | };
35 |
36 | let createRootWithId = id =>
37 | switch (_getElementById(id)) {
38 | | None =>
39 | raise(
40 | Invalid_argument(
41 | "ReactDOMRe.Unstable.createRootWithId: no element of id "
42 | ++ id
43 | ++ " found in the HTML.",
44 | ),
45 | )
46 | | Some(element) => createRoot(element)
47 | };
48 | };
49 |
50 | let start = () => {
51 | let root = ReactDOM.createRootWithId("root");
52 | ReactDOM.render(root, );
53 | };
54 |
55 | start();
56 |
57 | // If you want your app to work offline and load faster, you can change
58 | // unregister_service_worker() to register_service_worker() below. Note this
59 | // comes with some pitfalls. Learn more about service workers:
60 | // https://bit.ly/CRA-PWA
61 | unregister_service_worker();
62 |
--------------------------------------------------------------------------------
/esy.lock/opam/ocamlfind.1.8.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | synopsis: "A library manager for OCaml"
3 | maintainer: "Thomas Gazagnaire "
4 | authors: "Gerd Stolpmann "
5 | homepage: "http://projects.camlcity.org/projects/findlib.html"
6 | bug-reports: "https://gitlab.camlcity.org/gerd/lib-findlib/issues"
7 | dev-repo: "git+https://gitlab.camlcity.org/gerd/lib-findlib.git"
8 | description: """
9 | Findlib is a library manager for OCaml. It provides a convention how
10 | to store libraries, and a file format ("META") to describe the
11 | properties of libraries. There is also a tool (ocamlfind) for
12 | interpreting the META files, so that it is very easy to use libraries
13 | in programs and scripts.
14 | """
15 | build: [
16 | [
17 | "./configure"
18 | "-bindir"
19 | bin
20 | "-sitelib"
21 | lib
22 | "-mandir"
23 | man
24 | "-config"
25 | "%{lib}%/findlib.conf"
26 | "-no-custom"
27 | "-no-camlp4" {!ocaml:preinstalled & ocaml:version >= "4.02.0"}
28 | "-no-topfind" {ocaml:preinstalled}
29 | ]
30 | [make "all"]
31 | [make "opt"] {ocaml:native}
32 | ]
33 | install: [
34 | [
35 | "./configure"
36 | "-bindir"
37 | bin
38 | "-sitelib"
39 | lib
40 | "-mandir"
41 | man
42 | "-config"
43 | "%{lib}%/findlib.conf"
44 | "-no-custom"
45 | "-no-camlp4" {!ocaml:preinstalled & ocaml:version >= "4.02.0"}
46 | "-no-topfind" {ocaml:preinstalled}
47 | ]
48 | [make "install"]
49 | ["install" "-m" "0755" "ocaml-stub" "%{bin}%/ocaml"] {ocaml:preinstalled}
50 | ]
51 | depends: [
52 | "ocaml" {>= "4.00.0" & < "4.13"}
53 | "conf-m4" {build}
54 | ]
55 | extra-files: [
56 | ["ocamlfind.install" "md5=06f2c282ab52d93aa6adeeadd82a2543"]
57 | ["ocaml-stub" "md5=181f259c9e0bad9ef523e7d4abfdf87a"]
58 | ]
59 | url {
60 | src: "http://download.camlcity.org/download/findlib-1.8.1.tar.gz"
61 | checksum: "md5=18ca650982c15536616dea0e422cbd8c"
62 | mirrors: "http://download2.camlcity.org/download/findlib-1.8.1.tar.gz"
63 | }
64 | depopts: ["graphics"]
65 |
--------------------------------------------------------------------------------
/esy.lock/opam/csexp.1.4.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | synopsis: "Parsing and printing of S-expressions in Canonical form"
3 | description: """
4 |
5 | This library provides minimal support for Canonical S-expressions
6 | [1]. Canonical S-expressions are a binary encoding of S-expressions
7 | that is super simple and well suited for communication between
8 | programs.
9 |
10 | This library only provides a few helpers for simple applications. If
11 | you need more advanced support, such as parsing from more fancy input
12 | sources, you should consider copying the code of this library given
13 | how simple parsing S-expressions in canonical form is.
14 |
15 | To avoid a dependency on a particular S-expression library, the only
16 | module of this library is parameterised by the type of S-expressions.
17 |
18 | [1] https://en.wikipedia.org/wiki/Canonical_S-expressions
19 | """
20 | maintainer: ["Jeremie Dimino "]
21 | authors: [
22 | "Quentin Hocquet "
23 | "Jane Street Group, LLC "
24 | "Jeremie Dimino "
25 | ]
26 | license: "MIT"
27 | homepage: "https://github.com/ocaml-dune/csexp"
28 | doc: "https://ocaml-dune.github.io/csexp/"
29 | bug-reports: "https://github.com/ocaml-dune/csexp/issues"
30 | depends: [
31 | "dune" {>= "1.11"}
32 | "ocaml" {>= "4.02.3"}
33 | "result" {>= "1.5"}
34 | ]
35 | dev-repo: "git+https://github.com/ocaml-dune/csexp.git"
36 | build: [
37 | ["dune" "subst"] {pinned}
38 | [
39 | "dune"
40 | "build"
41 | "-p"
42 | name
43 | "-j"
44 | jobs
45 | "@install"
46 | # "@runtest" {with-test & ocaml:version >= "4.04"}
47 | "@doc" {with-doc}
48 | ]
49 | ]
50 | x-commit-hash: "0e1b2044c8d1ff187c27cec3e46d9cde14892650"
51 | url {
52 | src:
53 | "https://github.com/ocaml-dune/csexp/releases/download/1.4.0/csexp-1.4.0.tbz"
54 | checksum: [
55 | "sha256=8e3d6fca87f102a126dee8b72a2a0d146f10439c47218dfc149d51bf3edf364e"
56 | "sha512=604a5094fbbf61f497b342ad0aa8ec25275b2a904cd0c1823fc40daa54a15796b360374ff495c0d8ca3b4c1e6723b2ce37e030857fae131222606de818fb8129"
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "flake-utils": {
4 | "locked": {
5 | "lastModified": 1653893745,
6 | "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
7 | "owner": "numtide",
8 | "repo": "flake-utils",
9 | "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
10 | "type": "github"
11 | },
12 | "original": {
13 | "owner": "numtide",
14 | "repo": "flake-utils",
15 | "type": "github"
16 | }
17 | },
18 | "flake-utils_2": {
19 | "locked": {
20 | "lastModified": 1653893745,
21 | "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
22 | "owner": "numtide",
23 | "repo": "flake-utils",
24 | "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
25 | "type": "github"
26 | },
27 | "original": {
28 | "owner": "numtide",
29 | "repo": "flake-utils",
30 | "type": "github"
31 | }
32 | },
33 | "nixpkgs": {
34 | "inputs": {
35 | "flake-utils": "flake-utils_2",
36 | "nixpkgs": "nixpkgs_2"
37 | },
38 | "locked": {
39 | "lastModified": 1654213891,
40 | "narHash": "sha256-ErjCuja4IRQfmSU9O/guechrvBKSVRCh9buOqvC8VfU=",
41 | "owner": "anmonteiro",
42 | "repo": "nix-overlays",
43 | "rev": "db73276cffa767f07534d685dae6c836f87664e1",
44 | "type": "github"
45 | },
46 | "original": {
47 | "owner": "anmonteiro",
48 | "repo": "nix-overlays",
49 | "type": "github"
50 | }
51 | },
52 | "nixpkgs_2": {
53 | "locked": {
54 | "lastModified": 1654012153,
55 | "narHash": "sha256-In+gfoH2Tnf/UmpzeuGlfuexU2EC4QIelBsm2zMK5AE=",
56 | "owner": "NixOS",
57 | "repo": "nixpkgs",
58 | "rev": "49a2bcc6e2065909c701f862f9a1a62b3082b40a",
59 | "type": "github"
60 | },
61 | "original": {
62 | "owner": "NixOS",
63 | "repo": "nixpkgs",
64 | "rev": "49a2bcc6e2065909c701f862f9a1a62b3082b40a",
65 | "type": "github"
66 | }
67 | },
68 | "root": {
69 | "inputs": {
70 | "flake-utils": "flake-utils",
71 | "nixpkgs": "nixpkgs"
72 | }
73 | }
74 | },
75 | "root": "root",
76 | "version": 7
77 | }
78 |
--------------------------------------------------------------------------------
/src/utils.ml:
--------------------------------------------------------------------------------
1 | let dayOfWeek = function
2 | | 0 ->
3 | "Sunday"
4 | | 1 ->
5 | "Monday"
6 | | 2 ->
7 | "Tuesday"
8 | | 3 ->
9 | "Wednesday"
10 | | 4 ->
11 | "Thursday"
12 | | 5 ->
13 | "Friday"
14 | | 6 ->
15 | "Saturday"
16 | | _ ->
17 | assert false
18 |
19 | let formatDate d =
20 | dayOfWeek (Js.Date.getDay d |. int_of_float)
21 | ^ ", "
22 | ^ Js.Date.toLocaleString d
23 |
24 | module QueryParams = struct
25 | type t
26 |
27 | external make : string -> t = "URLSearchParams" [@@bs.new]
28 |
29 | external get : t -> string -> string option = "get"
30 | [@@bs.send] [@@bs.return nullable]
31 | end
32 |
33 | type window =
34 | < innerHeight : int ; pageXOffset : int ; pageYOffset : int > Js.t
35 |
36 | external window : window = "window" [@@bs.val]
37 |
38 | external documentElement : < scrollTop : int ; offsetHeight : int > Js.t = "documentElement"
39 | [@@bs.scope "document"] [@@bs.val]
40 |
41 | let throttle f ms =
42 | let last = ref max_float in
43 | let timer = ref None in
44 | fun arg ->
45 | let now = Js.Date.now () in
46 | if now < !last +. float ms then (
47 | (match !timer with None -> () | Some id -> Js.Global.clearTimeout id);
48 | timer :=
49 | Some
50 | (Js.Global.setTimeout
51 | (fun () ->
52 | last := Js.Date.now ();
53 | f arg)
54 | ms))
55 | else (
56 | last := Js.Date.now ();
57 | f arg)
58 |
59 | module Scroll = struct
60 | external onScroll
61 | : window
62 | -> (_[@bs.as "scroll"])
63 | -> (Dom.event -> unit)
64 | -> unit
65 | = "addEventListener"
66 | [@@bs.send]
67 |
68 | external offScroll
69 | : window
70 | -> (_[@bs.as "scroll"])
71 | -> (Dom.event -> unit)
72 | -> unit
73 | = "removeEventListener"
74 | [@@bs.send]
75 |
76 | type t =
77 | { x : int
78 | ; y : int
79 | }
80 |
81 | let useScroll () =
82 | let state, updateState =
83 | React.useState (fun () ->
84 | { x = window##pageXOffset; y = window##pageYOffset })
85 | in
86 | let handler =
87 | throttle
88 | (fun _ ->
89 | updateState (fun _ ->
90 | { x = window##pageXOffset; y = window##pageYOffset }))
91 | 200
92 | in
93 | React.useEffect0 (fun () ->
94 | onScroll window handler;
95 | Some (fun () -> offScroll window handler));
96 | state
97 | end
98 |
--------------------------------------------------------------------------------
/esy.lock/opam/dune.2.8.4/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | synopsis: "Fast, portable, and opinionated build system"
3 | description: """
4 |
5 | dune is a build system that was designed to simplify the release of
6 | Jane Street packages. It reads metadata from "dune" files following a
7 | very simple s-expression syntax.
8 |
9 | dune is fast, has very low-overhead, and supports parallel builds on
10 | all platforms. It has no system dependencies; all you need to build
11 | dune or packages using dune is OCaml. You don't need make or bash
12 | as long as the packages themselves don't use bash explicitly.
13 |
14 | dune supports multi-package development by simply dropping multiple
15 | repositories into the same directory.
16 |
17 | It also supports multi-context builds, such as building against
18 | several opam roots/switches simultaneously. This helps maintaining
19 | packages across several versions of OCaml and gives cross-compilation
20 | for free.
21 | """
22 | maintainer: ["Jane Street Group, LLC "]
23 | authors: ["Jane Street Group, LLC "]
24 | license: "MIT"
25 | homepage: "https://github.com/ocaml/dune"
26 | doc: "https://dune.readthedocs.io/"
27 | bug-reports: "https://github.com/ocaml/dune/issues"
28 | conflicts: [
29 | "merlin" {< "3.4.0"}
30 | "ocaml-lsp-server" {< "1.3.0"}
31 | "dune-configurator" {< "2.3.0"}
32 | "odoc" {< "1.3.0"}
33 | "dune-release" {< "1.3.0"}
34 | "js_of_ocaml-compiler" {< "3.6.0"}
35 | "jbuilder" {= "transition"}
36 | ]
37 | dev-repo: "git+https://github.com/ocaml/dune.git"
38 | build: [
39 | # opam 2 sets OPAM_SWITCH_PREFIX, so we don't need a hardcoded path
40 | ["ocaml" "configure.ml" "--libdir" lib] {opam-version < "2"}
41 | ["ocaml" "bootstrap.ml" "-j" jobs]
42 | ["./dune.exe" "build" "-p" name "--profile" "dune-bootstrap" "-j" jobs]
43 | ]
44 | depends: [
45 | # Please keep the lower bound in sync with .github/workflows/workflow.yml,
46 | # dune-project and min_ocaml_version in bootstrap.ml
47 | ("ocaml" {>= "4.08"} | ("ocaml" {< "4.08~~"} & "ocamlfind-secondary"))
48 | "base-unix"
49 | "base-threads"
50 | ]
51 | x-commit-hash: "b6a3f66fb15378fc7170e94778f4d2c0b142ad92"
52 | url {
53 | src: "https://github.com/ocaml/dune/releases/download/2.8.4/dune-2.8.4.tbz"
54 | checksum: [
55 | "sha256=4e6420177584aabdc3b7b37aee3026b094b82bf5d7ed175344a68e321f72e8ac"
56 | "sha512=efc1834c4add40138a101734665a1f462c19fe76d1cbb457b1fc20f95991118a50b24d485fb98d39046e41bec03885a8dc071bf8add51083ac9780bff9f6668a"
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/src/App.module.scss:
--------------------------------------------------------------------------------
1 | @import "./palette.scss";
2 | @import "./units.scss";
3 |
4 | /* App Header */
5 |
6 | .appHeader {
7 | text-align: center;
8 | background-color: $blue;
9 | min-height: 15vmin;
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | justify-content: center;
14 | font-size: calc(10px + 2vmin);
15 | color: white;
16 | }
17 |
18 | .collapsible {
19 | margin-bottom: $m;
20 | transition: max-height 0.5s ease-in-out;
21 | overflow: hidden;
22 | max-height: 100px;
23 | }
24 |
25 | .collapsed {
26 | max-height: 0;
27 | }
28 |
29 | /* Main content */
30 |
31 | .appMain {
32 | max-width: 1024px;
33 | margin: 30px auto;
34 | }
35 |
36 | .feedTitle {
37 | color: $baby;
38 | }
39 |
40 | /* Entries */
41 |
42 | .entryDate {
43 | display: flex;
44 | font-weight: 500;
45 | margin-bottom: $s;
46 | }
47 |
48 | .entryContent {
49 | /* GitHub Theming */
50 | :global {
51 | @import "@primer/css/core/index.scss";
52 | @import "@primer/css/product/index.scss";
53 | @import "~github-syntax-light/lib/github-light.css";
54 |
55 | .repo-language-color {
56 | border-radius: 50%;
57 | display: inline-block;
58 | height: 12px;
59 | position: relative;
60 | top: 1px;
61 | width: 12px;
62 | }
63 | }
64 | }
65 |
66 | .loader,
67 | .loader:after {
68 | border-radius: 50%;
69 | width: 10em;
70 | height: 10em;
71 | }
72 |
73 | $cream_op: rgba(248, 255, 244, 0.2);
74 |
75 | .loader {
76 | margin: 60px auto;
77 | font-size: 10px;
78 | position: relative;
79 | text-indent: -9999em;
80 | border-top: 1.1em solid $cream_op;
81 | border-right: 1.1em solid $cream_op;
82 | border-bottom: 1.1em solid $cream_op;
83 | border-left: 1.1em solid $gray;
84 | -webkit-transform: translateZ(0);
85 | -ms-transform: translateZ(0);
86 | transform: translateZ(0);
87 | -webkit-animation: load8 1.1s infinite linear;
88 | animation: load8 1.1s infinite linear;
89 | }
90 | @-webkit-keyframes load8 {
91 | 0% {
92 | -webkit-transform: rotate(0deg);
93 | transform: rotate(0deg);
94 | }
95 | 100% {
96 | -webkit-transform: rotate(360deg);
97 | transform: rotate(360deg);
98 | }
99 | }
100 | @keyframes load8 {
101 | 0% {
102 | -webkit-transform: rotate(0deg);
103 | transform: rotate(0deg);
104 | }
105 | 100% {
106 | -webkit-transform: rotate(360deg);
107 | transform: rotate(360deg);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/esy.lock/opam/merlin.4.1-412/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "defree@gmail.com"
3 | authors: "The Merlin team"
4 | homepage: "https://github.com/ocaml/merlin"
5 | bug-reports: "https://github.com/ocaml/merlin/issues"
6 | dev-repo: "git+https://github.com/ocaml/merlin.git"
7 | build: [
8 | ["dune" "subst"] {pinned}
9 | ["dune" "build" "-p" name "-j" jobs]
10 | ["dune" "runtest" "-p" "merlin,dot-merlin-reader" "-j" "1"] {with-test}
11 | ]
12 | depends: [
13 | "ocaml" {>= "4.12" & < "4.13"}
14 | "dune" {>= "2.7.0"}
15 | "dot-merlin-reader" {>= "4.0"}
16 | "yojson" {>= "1.6.0"}
17 | "conf-jq" {with-test}
18 | "csexp" {>= "1.2.3"}
19 | "result" {>= "1.5"}
20 | "menhir" {dev}
21 | "menhirLib" {dev}
22 | "menhirSdk" {dev}
23 | ]
24 | synopsis:
25 | "Editor helper, provides completion, typing and source browsing in Vim and Emacs"
26 | description:
27 | "Merlin is an assistant for editing OCaml code. It aims to provide the features available in modern IDEs: error reporting, auto completion, source browsing and much more."
28 | post-messages: [
29 | "merlin installed.
30 |
31 | Quick setup for VIM
32 | -------------------
33 | Append this to your .vimrc to add merlin to vim's runtime-path:
34 | let g:opamshare = substitute(system('opam var share'),'\\n$','','''')
35 | execute \"set rtp+=\" . g:opamshare . \"/merlin/vim\"
36 |
37 | Also run the following line in vim to index the documentation:
38 | :execute \"helptags \" . g:opamshare . \"/merlin/vim/doc\"
39 |
40 | Quick setup for EMACS
41 | -------------------
42 | Add opam emacs directory to your load-path by appending this to your .emacs:
43 | (let ((opam-share (ignore-errors (car (process-lines \"opam\" \"config\" \"var\" \"share\")))))
44 | (when (and opam-share (file-directory-p opam-share))
45 | ;; Register Merlin
46 | (add-to-list 'load-path (expand-file-name \"emacs/site-lisp\" opam-share))
47 | (autoload 'merlin-mode \"merlin\" nil t nil)
48 | ;; Automatically start it in OCaml buffers
49 | (add-hook 'tuareg-mode-hook 'merlin-mode t)
50 | (add-hook 'caml-mode-hook 'merlin-mode t)
51 | ;; Use opam switch to lookup ocamlmerlin binary
52 | (setq merlin-command 'opam)))
53 |
54 | Take a look at https://github.com/ocaml/merlin for more information
55 |
56 | Quick setup with opam-user-setup
57 | --------------------------------
58 |
59 | Opam-user-setup support Merlin.
60 |
61 | $ opam user-setup install
62 |
63 | should take care of basic setup.
64 | See https://github.com/OCamlPro/opam-user-setup
65 | "
66 | {success & !user-setup:installed}
67 | ]
68 | x-commit-hash: "35c3ad0fb4a1de53f6afb028961800e63b9363bd"
69 | url {
70 | src:
71 | "https://github.com/ocaml/merlin/releases/download/v4.1-412/merlin-v4.1-412.tbz"
72 | checksum: [
73 | "sha256=fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d"
74 | "sha512=ec301e0f97e11c1c331478030372d373d381a0ddbb7f72c83f7baa4c2c6d4f26094c3398f56bcf3d40c1242044391369fd06e8cd2ccfe1f5d78467eb3e9d33be"
75 | ]
76 | }
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `npm start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `npm test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `npm run eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `npm run build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/src/App.re:
--------------------------------------------------------------------------------
1 | open Belt;
2 |
3 | [@bs.module] external css: Js.t({..}) as 'a = "./App.module.scss";
4 |
5 | module Entry = {
6 | module Entry = Feed.Entry;
7 |
8 | [@react.component]
9 | let make = (~entry) => {
10 | let date = {
11 | let dateMs =
12 | switch (entry.Entry.published) {
13 | | Some(published) => published
14 | | None => entry.updated
15 | };
16 | let jsDate = Js.Date.fromFloat(dateMs);
17 | Utils.formatDate(jsDate);
18 | };
19 | let dateCaption = "On " ++ date ++ ":";
20 |
21 |
22 |
23 | {switch (entry.links) {
24 | | [] => React.string(dateCaption)
25 | | [{Feed.Link.title, href}, ..._] =>
26 |
{React.string(dateCaption)}
27 | }}
28 |
29 | {switch (entry.content) {
30 | | Some(content) =>
31 |
35 | | None => React.null
36 | }}
37 |
38 | ;
39 | };
40 | };
41 |
42 | module Header = {
43 | let feedTitle = (~link=?, feedTitle) => {
44 | switch (link) {
45 | | Some({Feed.Link.title, href}) =>
46 | {React.string(feedTitle)}
47 | | None =>
48 | {React.string(feedTitle)}
49 | };
50 | };
51 |
52 | [@react.component]
53 | let make = (~link=?, ~title) => {
54 |
55 | {feedTitle(~link?, title)}
56 | ;
57 | };
58 | };
59 |
60 | module FeedPage = {
61 | [@react.component]
62 | let make = (~token=?, ~page, ~user, ~loadingRef) => {
63 | let {Api.SWR.data, error: _error} =
64 | Api.SWR.useSWR(Api.feedEndpoint(~token?, ~page, user));
65 |
66 | /* If this is executed, it means the data was successfully read from the
67 | * remote endpoint. We are done loading. */
68 | React.useEffect0(() => {
69 | loadingRef.React.current = false;
70 | None;
71 | });
72 |
73 |
74 | {switch (data) {
75 | | Some(Ok({Feed.entries})) =>
76 | entries
77 | ->List.reduceWithIndexU(
78 | Array.makeUninitializedUnsafe(List.length(entries)),
79 | (. arr, entry, i) => {
80 | Array.setUnsafe(
81 | arr,
82 | i,
83 | ,
84 | );
85 | arr;
86 | },
87 | )
88 | ->React.array
89 | | Some(Error(_))
90 | | None => React.null
91 | }}
92 | ;
93 | };
94 | };
95 |
96 | module GithubFeed = {
97 | [@react.component]
98 | let make = (~token=?, ~user, ~page, ~loadingRef) => {
99 | /* first page is always shown, and we need it to show the header */
100 | let {Api.SWR.data, error: _error} =
101 | Api.SWR.useSWR(Api.feedEndpoint(~token?, ~page=1, user));
102 | let (link, title) =
103 | switch (data) {
104 | | Some(Ok({Feed.links, title})) =>
105 | switch (links) {
106 | | [link, ..._] => (Some(link), title)
107 | | _ => (None, title)
108 | }
109 | | Some(Error(msg)) => (None, Format.asprintf("Error: %s", msg))
110 | | None => (None, "ERROR TODO" /* Format.asprintf("Error: %s", msg) */)
111 | };
112 |
113 | <>
114 |
115 |
116 | {React.array(
117 | Array.makeByU(page, (. i) =>
118 | }>
119 |
120 |
121 | ),
122 | )}
123 |
124 | >;
125 | };
126 | };
127 |
128 | /* TODO: insert a username to fetch */
129 | [@react.component]
130 | let make = () => {
131 | open Utils;
132 | let {RescriptReactRouter.search, path} = RescriptReactRouter.useUrl();
133 | let (page, setPage) = React.useState(() => 1);
134 | let {Scroll.y, _} = Scroll.useScroll();
135 | let loadingRef = React.useRef(false);
136 |
137 | React.useEffect3(
138 | () => {
139 | let loading = loadingRef.current;
140 | if (!loading) {
141 | let totalHeight = window##innerHeight + y;
142 | let offsetHeight = documentElement##offsetHeight;
143 | /* allow a 20px epsilon */
144 | if (totalHeight === offsetHeight) {
145 | loadingRef.current = true;
146 | setPage(prev => prev + 1);
147 | };
148 | };
149 | None;
150 | },
151 | (page, setPage, y),
152 | );
153 |
154 | let qp = QueryParams.make(search);
155 | let (user, token) = {
156 | let user =
157 | switch (path) {
158 | | [user, ..._] => user
159 | | _ => "anmonteiro"
160 | };
161 | (user, QueryParams.get(qp, "token"));
162 | };
163 |
164 |
165 |
166 | }>
167 |
168 |
169 |
170 | ;
171 | };
172 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl)
104 | .then(response => {
105 | // Ensure service worker exists, and that we really are getting a JS file.
106 | const contentType = response.headers.get('content-type');
107 | if (
108 | response.status === 404 ||
109 | (contentType != null && contentType.indexOf('javascript') === -1)
110 | ) {
111 | // No service worker found. Probably a different app. Reload the page.
112 | navigator.serviceWorker.ready.then(registration => {
113 | registration.unregister().then(() => {
114 | window.location.reload();
115 | });
116 | });
117 | } else {
118 | // Service worker found. Proceed as normal.
119 | registerValidSW(swUrl, config);
120 | }
121 | })
122 | .catch(() => {
123 | console.log(
124 | 'No internet connection found. App is running in offline mode.'
125 | );
126 | });
127 | }
128 |
129 | export function unregister() {
130 | if ('serviceWorker' in navigator) {
131 | navigator.serviceWorker.ready.then(registration => {
132 | registration.unregister();
133 | });
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/lambda/lambda.ml:
--------------------------------------------------------------------------------
1 | open Util
2 | open Syndic
3 | open Lwt.Infix
4 |
5 | let send_response body =
6 | let open Vercel in
7 | let body = Yojson.Safe.to_string body in
8 | let response =
9 | Response.of_string
10 | ~headers:(Headers.of_list [ "content-type", "application/json" ])
11 | ~body
12 | `OK
13 | in
14 | Ok response
15 |
16 | let send_error_response msg =
17 | let open Vercel in
18 | let payload = `Assoc [ "error", `String msg ] in
19 | let body = Yojson.Safe.to_string payload in
20 | let response =
21 | Response.of_string
22 | ~headers:(Headers.of_list [ "content-type", "application/json" ])
23 | ~body
24 | `Bad_request
25 | in
26 | Ok response
27 |
28 | let replace_hrefs xml_base html_string =
29 | let tree = Soup.parse html_string in
30 | let anchors = Soup.select "a" tree in
31 | Soup.iter
32 | (fun a ->
33 | match Soup.attribute "href" a with
34 | | None ->
35 | ()
36 | | Some href ->
37 | let uri = Uri.resolve "" xml_base (Uri.of_string href) in
38 | Soup.set_attribute "href" (Uri.to_string uri) a)
39 | anchors;
40 | Soup.to_string tree
41 |
42 | let text_construct_to_string : Atom.text_construct -> string = function
43 | | Atom.Text s ->
44 | s
45 | | Html (_, s) ->
46 | s
47 | | Xhtml (_, _) ->
48 | assert false
49 |
50 | let content_to_string : Atom.content -> string = function
51 | | Atom.Text s ->
52 | s
53 | | Atom.Html (uri, s) ->
54 | (match uri with Some uri -> replace_hrefs uri s | None -> s)
55 | | Atom.Src (_, _) | Atom.Xhtml (_, _) ->
56 | assert false
57 | | Atom.Mime (_, s) ->
58 | s
59 |
60 | let ptime_to_timestamp t =
61 | (* Ptime counts seconds, we return milliseconds *)
62 | Ptime.to_float_s t *. 1000.
63 |
64 | let build_link { Atom.href; title; _ } =
65 | { Feed.Link.href = Uri.to_string href; title }
66 |
67 | let build_author { Atom.name; uri; email } =
68 | { Feed.Author.name; email; uri = Option.map ~f:Uri.to_string uri }
69 |
70 | let build_entry
71 | { Atom.authors = main_author, other_authors
72 | ; content
73 | ; id
74 | ; links
75 | ; published
76 | ; title
77 | ; updated
78 | ; _
79 | }
80 | =
81 | { Feed.Entry.authors =
82 | build_author main_author, List.map build_author other_authors
83 | ; content = Option.map ~f:content_to_string content
84 | ; id = Uri.to_string id
85 | ; links = List.map build_link links
86 | ; published = Option.map ~f:ptime_to_timestamp published
87 | ; title = text_construct_to_string title
88 | ; updated = ptime_to_timestamp updated
89 | }
90 |
91 | let handle source =
92 | let input = Xmlm.make_input source in
93 | let { Atom.authors; id; links; logo; subtitle; title; updated; entries; _ } =
94 | Atom.parse ~xmlbase:(Uri.of_string "https://github.com") input
95 | in
96 | { Feed.authors = List.map build_author authors
97 | ; id = Uri.to_string id
98 | ; links = List.map build_link links
99 | ; logo = Option.map ~f:Uri.to_string logo
100 | ; subtitle = Option.map ~f:text_construct_to_string subtitle
101 | ; title = text_construct_to_string title
102 | ; updated = ptime_to_timestamp updated
103 | ; entries = List.map build_entry entries
104 | }
105 |
106 | let get_feed ?page ?token user =
107 | let base_url = Format.asprintf "https://github.com/%s" user in
108 | let feed_url, has_query_param =
109 | match token with
110 | | Some token ->
111 | Format.asprintf "%s.private.atom?token=%s" base_url token, true
112 | | None ->
113 | Format.asprintf "%s.atom" base_url, false
114 | in
115 | let uri =
116 | match page with
117 | | Some page ->
118 | Format.asprintf
119 | "%s%cpage=%s"
120 | feed_url
121 | (if has_query_param then '&' else '?')
122 | page
123 | | None ->
124 | feed_url
125 | in
126 | Piaf.Client.Oneshot.get
127 | ~config:
128 | { Piaf.Config.default with
129 | follow_redirects = true
130 | ; cacert = Some (Piaf.Cert.Filepath "./cacert.pem")
131 | }
132 | ~headers:[ "accept", "text/html,application/xhtml+xml,application/xml" ]
133 | (Uri.of_string uri)
134 | >>= function
135 | | Ok { Piaf.Response.body; _ } ->
136 | Piaf.Body.to_string body
137 | | Error msg ->
138 | Lwt_result.fail msg
139 |
140 | let handler reqd _ctx =
141 | let { Piaf.Request.target; _ } = reqd in
142 | let usage = "Usage:\n gh-feed.anmonteiro.now.sh/?user=username&page=N" in
143 | let uri = Uri.of_string target in
144 | let page = Uri.get_query_param uri "page" in
145 | let token = Uri.get_query_param uri "token" in
146 | match Uri.get_query_param uri "user" with
147 | | Some user ->
148 | get_feed ?page ?token user >>= ( function
149 | | Ok feed ->
150 | let feed_json = handle (`String (0, feed)) |> Feed.to_yojson in
151 | Lwt.return (send_response feed_json)
152 | | Error e ->
153 | let msg = Piaf.Error.to_string e in
154 | Lwt.return (send_error_response msg) )
155 | | None ->
156 | Lwt.return (send_error_response usage)
157 |
158 | let setup_log ?style_renderer level =
159 | Fmt_tty.setup_std_outputs ?style_renderer ();
160 | Logs.set_level (Some level);
161 | Logs.set_reporter (Logs_fmt.reporter ())
162 |
163 | let () =
164 | setup_log Logs.Debug;
165 | let () =
166 | try
167 | Logs.debug (fun m -> m "Trying to set KQueue backend for libev");
168 | Lwt_engine.(set (new libev ~backend:Ev_backend.kqueue ()))
169 | with
170 | | _ ->
171 | Logs.debug (fun m ->
172 | m "Failed setting KQueue libev backend. Falling back to epoll.\n%!");
173 | Lwt_engine.(set (new libev ~backend:Ev_backend.epoll ()))
174 | in
175 | Vercel.io_lambda handler
176 |
--------------------------------------------------------------------------------
/esy.lock/overrides/opam__s__ocamlfind_opam__c__1.8.1_opam_override/files/findlib-1.8.1.patch:
--------------------------------------------------------------------------------
1 | --- ./Makefile
2 | +++ ./Makefile
3 | @@ -57,16 +57,16 @@
4 | cat findlib.conf.in | \
5 | $(SH) tools/patch '@SITELIB@' '$(OCAML_SITELIB)' >findlib.conf
6 | if ./tools/cmd_from_same_dir ocamlc; then \
7 | - echo 'ocamlc="ocamlc.opt"' >>findlib.conf; \
8 | + echo 'ocamlc="ocamlc.opt$(EXEC_SUFFIX)"' >>findlib.conf; \
9 | fi
10 | if ./tools/cmd_from_same_dir ocamlopt; then \
11 | - echo 'ocamlopt="ocamlopt.opt"' >>findlib.conf; \
12 | + echo 'ocamlopt="ocamlopt.opt$(EXEC_SUFFIX)"' >>findlib.conf; \
13 | fi
14 | if ./tools/cmd_from_same_dir ocamldep; then \
15 | - echo 'ocamldep="ocamldep.opt"' >>findlib.conf; \
16 | + echo 'ocamldep="ocamldep.opt$(EXEC_SUFFIX)"' >>findlib.conf; \
17 | fi
18 | if ./tools/cmd_from_same_dir ocamldoc; then \
19 | - echo 'ocamldoc="ocamldoc.opt"' >>findlib.conf; \
20 | + echo 'ocamldoc="ocamldoc.opt$(EXEC_SUFFIX)"' >>findlib.conf; \
21 | fi
22 |
23 | .PHONY: install-doc
24 | --- ./src/findlib/findlib_config.mlp
25 | +++ ./src/findlib/findlib_config.mlp
26 | @@ -24,3 +24,5 @@
27 | | "MacOS" -> "" (* don't know *)
28 | | _ -> failwith "Unknown Sys.os_type"
29 | ;;
30 | +
31 | +let exec_suffix = "@EXEC_SUFFIX@";;
32 | --- ./src/findlib/findlib.ml
33 | +++ ./src/findlib/findlib.ml
34 | @@ -28,15 +28,20 @@
35 | let conf_ldconf = ref "";;
36 | let conf_ignore_dups_in = ref ([] : string list);;
37 |
38 | -let ocamlc_default = "ocamlc";;
39 | -let ocamlopt_default = "ocamlopt";;
40 | -let ocamlcp_default = "ocamlcp";;
41 | -let ocamloptp_default = "ocamloptp";;
42 | -let ocamlmklib_default = "ocamlmklib";;
43 | -let ocamlmktop_default = "ocamlmktop";;
44 | -let ocamldep_default = "ocamldep";;
45 | -let ocamlbrowser_default = "ocamlbrowser";;
46 | -let ocamldoc_default = "ocamldoc";;
47 | +let add_exec str =
48 | + match Findlib_config.exec_suffix with
49 | + | "" -> str
50 | + | a -> str ^ a ;;
51 | +let ocamlc_default = add_exec "ocamlc";;
52 | +let ocamlopt_default = add_exec "ocamlopt";;
53 | +let ocamlcp_default = add_exec "ocamlcp";;
54 | +let ocamloptp_default = add_exec "ocamloptp";;
55 | +let ocamlmklib_default = add_exec "ocamlmklib";;
56 | +let ocamlmktop_default = add_exec "ocamlmktop";;
57 | +let ocamldep_default = add_exec "ocamldep";;
58 | +let ocamlbrowser_default = add_exec "ocamlbrowser";;
59 | +let ocamldoc_default = add_exec "ocamldoc";;
60 | +
61 |
62 |
63 | let init_manually
64 | --- ./src/findlib/fl_package_base.ml
65 | +++ ./src/findlib/fl_package_base.ml
66 | @@ -133,7 +133,15 @@
67 | List.find (fun def -> def.def_var = "exists_if") p.package_defs in
68 | let files = Fl_split.in_words def.def_value in
69 | List.exists
70 | - (fun file -> Sys.file_exists (Filename.concat d' file))
71 | + (fun file ->
72 | + let fln = Filename.concat d' file in
73 | + let e = Sys.file_exists fln in
74 | + (* necessary for ppx executables *)
75 | + if e || Sys.os_type <> "Win32" || Filename.check_suffix fln ".exe" then
76 | + e
77 | + else
78 | + Sys.file_exists (fln ^ ".exe")
79 | + )
80 | files
81 | with Not_found -> true in
82 |
83 | --- ./src/findlib/fl_split.ml
84 | +++ ./src/findlib/fl_split.ml
85 | @@ -126,10 +126,17 @@
86 | | '/' | '\\' -> true
87 | | _ -> false in
88 | let norm_dir_win() =
89 | - if l >= 1 && s.[0] = '/' then
90 | - Buffer.add_char b '\\' else Buffer.add_char b s.[0];
91 | - if l >= 2 && s.[1] = '/' then
92 | - Buffer.add_char b '\\' else Buffer.add_char b s.[1];
93 | + if l >= 1 then (
94 | + if s.[0] = '/' then
95 | + Buffer.add_char b '\\'
96 | + else
97 | + Buffer.add_char b s.[0] ;
98 | + if l >= 2 then
99 | + if s.[1] = '/' then
100 | + Buffer.add_char b '\\'
101 | + else
102 | + Buffer.add_char b s.[1];
103 | + );
104 | for k = 2 to l - 1 do
105 | let c = s.[k] in
106 | if is_slash c then (
107 | --- ./src/findlib/frontend.ml
108 | +++ ./src/findlib/frontend.ml
109 | @@ -31,10 +31,18 @@
110 | else
111 | Sys_error (arg ^ ": " ^ Unix.error_message code)
112 |
113 | +let is_win = Sys.os_type = "Win32"
114 | +
115 | +let () =
116 | + match Findlib_config.system with
117 | + | "win32" | "win64" | "mingw" | "cygwin" | "mingw64" | "cygwin64" ->
118 | + (try set_binary_mode_out stdout true with _ -> ());
119 | + (try set_binary_mode_out stderr true with _ -> ());
120 | + | _ -> ()
121 |
122 | let slashify s =
123 | match Findlib_config.system with
124 | - | "mingw" | "mingw64" | "cygwin" ->
125 | + | "win32" | "win64" | "mingw" | "cygwin" | "mingw64" | "cygwin64" ->
126 | let b = Buffer.create 80 in
127 | String.iter
128 | (function
129 | @@ -49,7 +57,7 @@
130 |
131 | let out_path ?(prefix="") s =
132 | match Findlib_config.system with
133 | - | "mingw" | "mingw64" | "cygwin" ->
134 | + | "win32" | "win64" | "mingw" | "mingw64" | "cygwin" ->
135 | let u = slashify s in
136 | prefix ^
137 | (if String.contains u ' ' then
138 | @@ -273,11 +281,9 @@
139 |
140 |
141 | let identify_dir d =
142 | - match Sys.os_type with
143 | - | "Win32" ->
144 | - failwith "identify_dir" (* not available *)
145 | - | _ ->
146 | - let s = Unix.stat d in
147 | + if is_win then
148 | + failwith "identify_dir"; (* not available *)
149 | + let s = Unix.stat d in
150 | (s.Unix.st_dev, s.Unix.st_ino)
151 | ;;
152 |
153 | @@ -459,6 +465,96 @@
154 | )
155 | packages
156 |
157 | +let rewrite_cmd s =
158 | + if s = "" || not is_win then
159 | + s
160 | + else
161 | + let s =
162 | + let l = String.length s in
163 | + let b = Buffer.create l in
164 | + for i = 0 to pred l do
165 | + match s.[i] with
166 | + | '/' -> Buffer.add_char b '\\'
167 | + | x -> Buffer.add_char b x
168 | + done;
169 | + Buffer.contents b
170 | + in
171 | + if (Filename.is_implicit s && String.contains s '\\' = false) ||
172 | + Filename.check_suffix (String.lowercase s) ".exe" then
173 | + s
174 | + else
175 | + let s' = s ^ ".exe" in
176 | + if Sys.file_exists s' then
177 | + s'
178 | + else
179 | + s
180 | +
181 | +let rewrite_cmd s =
182 | + if s = "" || not is_win then s else
183 | + let s =
184 | + let l = String.length s in
185 | + let b = Buffer.create l in
186 | + for i = 0 to pred l do
187 | + match s.[i] with
188 | + | '/' -> Buffer.add_char b '\\'
189 | + | x -> Buffer.add_char b x
190 | + done;
191 | + Buffer.contents b
192 | + in
193 | + if (Filename.is_implicit s && String.contains s '\\' = false) ||
194 | + Filename.check_suffix (String.lowercase s) ".exe" then
195 | + s
196 | + else
197 | + let s' = s ^ ".exe" in
198 | + if Sys.file_exists s' then
199 | + s'
200 | + else
201 | + s
202 | +
203 | +let rewrite_pp cmd =
204 | + if not is_win then cmd else
205 | + let module T = struct exception Keep end in
206 | + let is_whitespace = function
207 | + | ' ' | '\011' | '\012' | '\n' | '\r' | '\t' -> true
208 | + | _ -> false in
209 | + (* characters that triggers special behaviour (cmd.exe, not unix shell) *)
210 | + let is_unsafe_char = function
211 | + | '(' | ')' | '%' | '!' | '^' | '<' | '>' | '&' -> true
212 | + | _ -> false in
213 | + let len = String.length cmd in
214 | + let buf = Buffer.create (len + 4) in
215 | + let buf_cmd = Buffer.create len in
216 | + let rec iter_ws i =
217 | + if i >= len then () else
218 | + let cur = cmd.[i] in
219 | + if is_whitespace cur then (
220 | + Buffer.add_char buf cur;
221 | + iter_ws (succ i)
222 | + )
223 | + else
224 | + iter_cmd i
225 | + and iter_cmd i =
226 | + if i >= len then add_buf_cmd () else
227 | + let cur = cmd.[i] in
228 | + if is_unsafe_char cur || cur = '"' || cur = '\'' then
229 | + raise T.Keep;
230 | + if is_whitespace cur then (
231 | + add_buf_cmd ();
232 | + Buffer.add_substring buf cmd i (len - i)
233 | + )
234 | + else (
235 | + Buffer.add_char buf_cmd cur;
236 | + iter_cmd (succ i)
237 | + )
238 | + and add_buf_cmd () =
239 | + if Buffer.length buf_cmd > 0 then
240 | + Buffer.add_string buf (rewrite_cmd (Buffer.contents buf_cmd))
241 | + in
242 | + try
243 | + iter_ws 0;
244 | + Buffer.contents buf
245 | + with
246 | + | T.Keep -> cmd
247 |
248 | let process_pp_spec syntax_preds packages pp_opts =
249 | (* Returns: pp_command *)
250 | @@ -549,7 +645,7 @@
251 | None -> []
252 | | Some cmd ->
253 | ["-pp";
254 | - cmd ^ " " ^
255 | + (rewrite_cmd cmd) ^ " " ^
256 | String.concat " " (List.map Filename.quote pp_i_options) ^ " " ^
257 | String.concat " " (List.map Filename.quote pp_archives) ^ " " ^
258 | String.concat " " (List.map Filename.quote pp_opts)]
259 | @@ -625,9 +721,11 @@
260 | in
261 | try
262 | let preprocessor =
263 | + rewrite_cmd (
264 | resolve_path
265 | ~base ~explicit:true
266 | - (package_property predicates pname "ppx") in
267 | + (package_property predicates pname "ppx") )
268 | + in
269 | ["-ppx"; String.concat " " (preprocessor :: options)]
270 | with Not_found -> []
271 | )
272 | @@ -895,6 +993,14 @@
273 | switch (e.g. -L instead of -L )
274 | *)
275 |
276 | +(* We may need to remove files on which we do not have complete control.
277 | + On Windows, removing a read-only file fails so try to change the
278 | + mode of the file first. *)
279 | +let remove_file fname =
280 | + try Sys.remove fname
281 | + with Sys_error _ when is_win ->
282 | + (try Unix.chmod fname 0o666 with Unix.Unix_error _ -> ());
283 | + Sys.remove fname
284 |
285 | let ocamlc which () =
286 |
287 | @@ -1022,9 +1128,12 @@
288 |
289 | "-intf",
290 | Arg.String (fun s -> pass_files := !pass_files @ [ Intf(slashify s) ]);
291 | -
292 | +
293 | "-pp",
294 | - Arg.String (fun s -> pp_specified := true; add_spec_fn "-pp" s);
295 | + Arg.String (fun s -> pp_specified := true; add_spec_fn "-pp" (rewrite_pp s));
296 | +
297 | + "-ppx",
298 | + Arg.String (fun s -> add_spec_fn "-ppx" (rewrite_pp s));
299 |
300 | "-thread",
301 | Arg.Unit (fun _ -> threads := threads_default);
302 | @@ -1237,7 +1346,7 @@
303 | with
304 | any ->
305 | close_out initl;
306 | - Sys.remove initl_file_name;
307 | + remove_file initl_file_name;
308 | raise any
309 | end;
310 |
311 | @@ -1245,9 +1354,9 @@
312 | at_exit
313 | (fun () ->
314 | let tr f x = try f x with _ -> () in
315 | - tr Sys.remove initl_file_name;
316 | - tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmi");
317 | - tr Sys.remove (Filename.chop_extension initl_file_name ^ ".cmo");
318 | + tr remove_file initl_file_name;
319 | + tr remove_file (Filename.chop_extension initl_file_name ^ ".cmi");
320 | + tr remove_file (Filename.chop_extension initl_file_name ^ ".cmo");
321 | );
322 |
323 | let exclude_list = [ stdlibdir; threads_dir; vmthreads_dir ] in
324 | @@ -1493,7 +1602,9 @@
325 | [ "-v", Arg.Unit (fun () -> verbose := Verbose);
326 | "-pp", Arg.String (fun s ->
327 | pp_specified := true;
328 | - options := !options @ ["-pp"; s]);
329 | + options := !options @ ["-pp"; rewrite_pp s]);
330 | + "-ppx", Arg.String (fun s ->
331 | + options := !options @ ["-ppx"; rewrite_pp s]);
332 | ]
333 | )
334 | )
335 | @@ -1672,7 +1783,9 @@
336 | Arg.String (fun s -> add_spec_fn "-I" (slashify (resolve_path s)));
337 |
338 | "-pp", Arg.String (fun s -> pp_specified := true;
339 | - add_spec_fn "-pp" s);
340 | + add_spec_fn "-pp" (rewrite_pp s));
341 | + "-ppx", Arg.String (fun s -> add_spec_fn "-ppx" (rewrite_pp s));
342 | +
343 | ]
344 | )
345 | )
346 | @@ -1830,7 +1943,10 @@
347 | output_string ch_out append;
348 | close_out ch_out;
349 | close_in ch_in;
350 | - Unix.utimes outpath s.Unix.st_mtime s.Unix.st_mtime;
351 | + (try Unix.utimes outpath s.Unix.st_mtime s.Unix.st_mtime
352 | + with Unix.Unix_error(e,_,_) ->
353 | + prerr_endline("Warning: setting utimes for " ^ outpath
354 | + ^ ": " ^ Unix.error_message e));
355 |
356 | prerr_endline("Installed " ^ outpath);
357 | with
358 | @@ -1882,6 +1998,8 @@
359 | Unix.openfile (Filename.concat dir owner_file) [Unix.O_RDONLY] 0 in
360 | let f =
361 | Unix.in_channel_of_descr fd in
362 | + if is_win then
363 | + set_binary_mode_in f false;
364 | try
365 | let line = input_line f in
366 | let is_my_file = (line = pkg) in
367 | @@ -2208,7 +2326,7 @@
368 | let lines = read_ldconf !ldconf in
369 | let dlldir_norm = Fl_split.norm_dir dlldir in
370 | let dlldir_norm_lc = string_lowercase_ascii dlldir_norm in
371 | - let ci_filesys = (Sys.os_type = "Win32") in
372 | + let ci_filesys = is_win in
373 | let check_dir d =
374 | let d' = Fl_split.norm_dir d in
375 | (d' = dlldir_norm) ||
376 | @@ -2356,7 +2474,7 @@
377 | List.iter
378 | (fun file ->
379 | let absfile = Filename.concat dlldir file in
380 | - Sys.remove absfile;
381 | + remove_file absfile;
382 | prerr_endline ("Removed " ^ absfile)
383 | )
384 | dll_files
385 | @@ -2365,7 +2483,7 @@
386 | (* Remove the files from the package directory: *)
387 | if Sys.file_exists pkgdir then begin
388 | let files = Sys.readdir pkgdir in
389 | - Array.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files;
390 | + Array.iter (fun f -> remove_file (Filename.concat pkgdir f)) files;
391 | Unix.rmdir pkgdir;
392 | prerr_endline ("Removed " ^ pkgdir)
393 | end
394 | @@ -2415,7 +2533,9 @@
395 |
396 |
397 | let print_configuration() =
398 | + let sl = slashify in
399 | let dir s =
400 | + let s = sl s in
401 | if Sys.file_exists s then
402 | s
403 | else
404 | @@ -2453,27 +2573,27 @@
405 | if md = "" then "the corresponding package directories" else dir md
406 | );
407 | Printf.printf "The standard library is assumed to reside in:\n %s\n"
408 | - (Findlib.ocaml_stdlib());
409 | + (sl (Findlib.ocaml_stdlib()));
410 | Printf.printf "The ld.conf file can be found here:\n %s\n"
411 | - (Findlib.ocaml_ldconf());
412 | + (sl (Findlib.ocaml_ldconf()));
413 | flush stdout
414 | | Some "conf" ->
415 | - print_endline (Findlib.config_file())
416 | + print_endline (sl (Findlib.config_file()))
417 | | Some "path" ->
418 | - List.iter print_endline (Findlib.search_path())
419 | + List.iter ( fun x -> print_endline (sl x)) (Findlib.search_path())
420 | | Some "destdir" ->
421 | - print_endline (Findlib.default_location())
422 | + print_endline ( sl (Findlib.default_location()))
423 | | Some "metadir" ->
424 | - print_endline (Findlib.meta_directory())
425 | + print_endline ( sl (Findlib.meta_directory()))
426 | | Some "metapath" ->
427 | let mdir = Findlib.meta_directory() in
428 | let ddir = Findlib.default_location() in
429 | - print_endline
430 | - (if mdir <> "" then mdir ^ "/META.%s" else ddir ^ "/%s/META")
431 | + print_endline ( sl
432 | + (if mdir <> "" then mdir ^ "/META.%s" else ddir ^ "/%s/META"))
433 | | Some "stdlib" ->
434 | - print_endline (Findlib.ocaml_stdlib())
435 | + print_endline ( sl (Findlib.ocaml_stdlib()))
436 | | Some "ldconf" ->
437 | - print_endline (Findlib.ocaml_ldconf())
438 | + print_endline ( sl (Findlib.ocaml_ldconf()))
439 | | _ ->
440 | assert false
441 | ;;
442 | @@ -2481,7 +2601,7 @@
443 |
444 | let ocamlcall pkg cmd =
445 | let dir = package_directory pkg in
446 | - let path = Filename.concat dir cmd in
447 | + let path = rewrite_cmd (Filename.concat dir cmd) in
448 | begin
449 | try Unix.access path [ Unix.X_OK ]
450 | with
451 | @@ -2647,6 +2767,10 @@
452 | | Sys_error f ->
453 | prerr_endline ("ocamlfind: " ^ f);
454 | exit 2
455 | + | Unix.Unix_error (e, fn, f) ->
456 | + prerr_endline ("ocamlfind: " ^ fn ^ " " ^ f
457 | + ^ ": " ^ Unix.error_message e);
458 | + exit 2
459 | | Findlib.No_such_package(pkg,info) ->
460 | prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' not found" ^
461 | (if info <> "" then " - " ^ info else ""));
462 | --- ./src/findlib/Makefile
463 | +++ ./src/findlib/Makefile
464 | @@ -90,6 +90,7 @@
465 | cat findlib_config.mlp | \
466 | $(SH) $(TOP)/tools/patch '@CONFIGFILE@' '$(OCAMLFIND_CONF)' | \
467 | $(SH) $(TOP)/tools/patch '@STDLIB@' '$(OCAML_CORE_STDLIB)' | \
468 | + $(SH) $(TOP)/tools/patch '@EXEC_SUFFIX@' '$(EXEC_SUFFIX)' | \
469 | sed -e 's;@AUTOLINK@;$(OCAML_AUTOLINK);g' \
470 | -e 's;@SYSTEM@;$(SYSTEM);g' \
471 | >findlib_config.ml
472 |
--------------------------------------------------------------------------------
/esy.lock/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "checksum": "79d0abd6d84736619240761ef6e1efba",
3 | "root": "gh-feed-reader@link-dev:./esy.json",
4 | "node": {
5 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9": {
6 | "id":
7 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
8 | "name": "ocaml",
9 | "version":
10 | "github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb",
11 | "source": {
12 | "type": "install",
13 | "source": [
14 | "github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb"
15 | ]
16 | },
17 | "overrides": [],
18 | "dependencies": [],
19 | "devDependencies": []
20 | },
21 | "gh-feed-reader@link-dev:./esy.json": {
22 | "id": "gh-feed-reader@link-dev:./esy.json",
23 | "name": "gh-feed-reader",
24 | "version": "link-dev:./esy.json",
25 | "source": { "type": "link-dev", "path": ".", "manifest": "esy.json" },
26 | "overrides": [],
27 | "dependencies": [
28 | "bs-platform@github:EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa@d41d8cd9",
29 | "@opam/merlin@opam:4.1-412@a9da5f4b"
30 | ],
31 | "devDependencies": [],
32 | "installConfig": { "pnp": false }
33 | },
34 | "esy-m4@github:esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7@d41d8cd9": {
35 | "id":
36 | "esy-m4@github:esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7@d41d8cd9",
37 | "name": "esy-m4",
38 | "version":
39 | "github:esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7",
40 | "source": {
41 | "type": "install",
42 | "source": [
43 | "github:esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7"
44 | ]
45 | },
46 | "overrides": [],
47 | "dependencies": [],
48 | "devDependencies": []
49 | },
50 | "bs-platform@github:EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa@d41d8cd9": {
51 | "id":
52 | "bs-platform@github:EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa@d41d8cd9",
53 | "name": "bs-platform",
54 | "version":
55 | "github:EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa",
56 | "source": {
57 | "type": "install",
58 | "source": [
59 | "github:EduardoRFS/bucklescript#97d478aa2f72ac92b776dfc9a50f316f6a46eefa"
60 | ]
61 | },
62 | "overrides": [],
63 | "dependencies": [
64 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
65 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/reason@3.7.0@d41d8cd9"
66 | ],
67 | "devDependencies": []
68 | },
69 | "@opam/yojson@opam:1.7.0@7056d985": {
70 | "id": "@opam/yojson@opam:1.7.0@7056d985",
71 | "name": "@opam/yojson",
72 | "version": "opam:1.7.0",
73 | "source": {
74 | "type": "install",
75 | "source": [
76 | "archive:https://opam.ocaml.org/cache/md5/b8/b89d39ca3f8c532abe5f547ad3b8f84d#md5:b89d39ca3f8c532abe5f547ad3b8f84d",
77 | "archive:https://github.com/ocaml-community/yojson/releases/download/1.7.0/yojson-1.7.0.tbz#md5:b89d39ca3f8c532abe5f547ad3b8f84d"
78 | ],
79 | "opam": {
80 | "name": "yojson",
81 | "version": "1.7.0",
82 | "path": "esy.lock/opam/yojson.1.7.0"
83 | }
84 | },
85 | "overrides": [],
86 | "dependencies": [
87 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
88 | "@opam/easy-format@opam:1.3.2@0484b3c4",
89 | "@opam/dune@opam:2.8.4@ee414d6c", "@opam/cppo@opam:1.6.7@c28ac3ae",
90 | "@opam/biniou@opam:1.2.1@d7570399",
91 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
92 | ],
93 | "devDependencies": [
94 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
95 | "@opam/easy-format@opam:1.3.2@0484b3c4",
96 | "@opam/dune@opam:2.8.4@ee414d6c", "@opam/biniou@opam:1.2.1@d7570399"
97 | ]
98 | },
99 | "@opam/result@opam:1.5@6b753c82": {
100 | "id": "@opam/result@opam:1.5@6b753c82",
101 | "name": "@opam/result",
102 | "version": "opam:1.5",
103 | "source": {
104 | "type": "install",
105 | "source": [
106 | "archive:https://opam.ocaml.org/cache/md5/1b/1b82dec78849680b49ae9a8a365b831b#md5:1b82dec78849680b49ae9a8a365b831b",
107 | "archive:https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz#md5:1b82dec78849680b49ae9a8a365b831b"
108 | ],
109 | "opam": {
110 | "name": "result",
111 | "version": "1.5",
112 | "path": "esy.lock/opam/result.1.5"
113 | }
114 | },
115 | "overrides": [],
116 | "dependencies": [
117 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
118 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
119 | ],
120 | "devDependencies": [
121 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
122 | "@opam/dune@opam:2.8.4@ee414d6c"
123 | ]
124 | },
125 | "@opam/ppx_derivers@opam:1.2.1@ecf0aa45": {
126 | "id": "@opam/ppx_derivers@opam:1.2.1@ecf0aa45",
127 | "name": "@opam/ppx_derivers",
128 | "version": "opam:1.2.1",
129 | "source": {
130 | "type": "install",
131 | "source": [
132 | "archive:https://opam.ocaml.org/cache/md5/5d/5dc2bf130c1db3c731fe0fffc5648b41#md5:5dc2bf130c1db3c731fe0fffc5648b41",
133 | "archive:https://github.com/ocaml-ppx/ppx_derivers/archive/1.2.1.tar.gz#md5:5dc2bf130c1db3c731fe0fffc5648b41"
134 | ],
135 | "opam": {
136 | "name": "ppx_derivers",
137 | "version": "1.2.1",
138 | "path": "esy.lock/opam/ppx_derivers.1.2.1"
139 | }
140 | },
141 | "overrides": [],
142 | "dependencies": [
143 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
144 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
145 | ],
146 | "devDependencies": [
147 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
148 | "@opam/dune@opam:2.8.4@ee414d6c"
149 | ]
150 | },
151 | "@opam/ocamlfind@opam:1.8.1@b7dc3072": {
152 | "id": "@opam/ocamlfind@opam:1.8.1@b7dc3072",
153 | "name": "@opam/ocamlfind",
154 | "version": "opam:1.8.1",
155 | "source": {
156 | "type": "install",
157 | "source": [
158 | "archive:https://opam.ocaml.org/cache/md5/18/18ca650982c15536616dea0e422cbd8c#md5:18ca650982c15536616dea0e422cbd8c",
159 | "archive:http://download2.camlcity.org/download/findlib-1.8.1.tar.gz#md5:18ca650982c15536616dea0e422cbd8c",
160 | "archive:http://download.camlcity.org/download/findlib-1.8.1.tar.gz#md5:18ca650982c15536616dea0e422cbd8c"
161 | ],
162 | "opam": {
163 | "name": "ocamlfind",
164 | "version": "1.8.1",
165 | "path": "esy.lock/opam/ocamlfind.1.8.1"
166 | }
167 | },
168 | "overrides": [
169 | {
170 | "opamoverride":
171 | "esy.lock/overrides/opam__s__ocamlfind_opam__c__1.8.1_opam_override"
172 | }
173 | ],
174 | "dependencies": [
175 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
176 | "@opam/conf-m4@opam:1@196bf219", "@esy-ocaml/substs@0.0.1@d41d8cd9"
177 | ],
178 | "devDependencies": [
179 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9"
180 | ]
181 | },
182 | "@opam/merlin-extend@opam:0.6@404f814c": {
183 | "id": "@opam/merlin-extend@opam:0.6@404f814c",
184 | "name": "@opam/merlin-extend",
185 | "version": "opam:0.6",
186 | "source": {
187 | "type": "install",
188 | "source": [
189 | "archive:https://opam.ocaml.org/cache/sha256/c2/c2f236ae97feb6ba0bc90f33beb7b7343e42f9871b66de9ba07974917e256c43#sha256:c2f236ae97feb6ba0bc90f33beb7b7343e42f9871b66de9ba07974917e256c43",
190 | "archive:https://github.com/let-def/merlin-extend/releases/download/v0.6/merlin-extend-v0.6.tbz#sha256:c2f236ae97feb6ba0bc90f33beb7b7343e42f9871b66de9ba07974917e256c43"
191 | ],
192 | "opam": {
193 | "name": "merlin-extend",
194 | "version": "0.6",
195 | "path": "esy.lock/opam/merlin-extend.0.6"
196 | }
197 | },
198 | "overrides": [],
199 | "dependencies": [
200 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
201 | "@opam/dune@opam:2.8.4@ee414d6c", "@opam/cppo@opam:1.6.7@c28ac3ae",
202 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
203 | ],
204 | "devDependencies": [
205 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
206 | "@opam/dune@opam:2.8.4@ee414d6c"
207 | ]
208 | },
209 | "@opam/merlin@opam:4.1-412@a9da5f4b": {
210 | "id": "@opam/merlin@opam:4.1-412@a9da5f4b",
211 | "name": "@opam/merlin",
212 | "version": "opam:4.1-412",
213 | "source": {
214 | "type": "install",
215 | "source": [
216 | "archive:https://opam.ocaml.org/cache/sha256/fb/fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d#sha256:fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d",
217 | "archive:https://github.com/ocaml/merlin/releases/download/v4.1-412/merlin-v4.1-412.tbz#sha256:fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d"
218 | ],
219 | "opam": {
220 | "name": "merlin",
221 | "version": "4.1-412",
222 | "path": "esy.lock/opam/merlin.4.1-412"
223 | }
224 | },
225 | "overrides": [],
226 | "dependencies": [
227 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
228 | "@opam/yojson@opam:1.7.0@7056d985", "@opam/result@opam:1.5@6b753c82",
229 | "@opam/dune@opam:2.8.4@ee414d6c",
230 | "@opam/dot-merlin-reader@opam:4.1@120afa42",
231 | "@opam/csexp@opam:1.4.0@bd1cb034", "@esy-ocaml/substs@0.0.1@d41d8cd9"
232 | ],
233 | "devDependencies": [
234 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
235 | "@opam/yojson@opam:1.7.0@7056d985", "@opam/result@opam:1.5@6b753c82",
236 | "@opam/dune@opam:2.8.4@ee414d6c",
237 | "@opam/dot-merlin-reader@opam:4.1@120afa42",
238 | "@opam/csexp@opam:1.4.0@bd1cb034"
239 | ]
240 | },
241 | "@opam/menhirSdk@opam:20210310@5abaafca": {
242 | "id": "@opam/menhirSdk@opam:20210310@5abaafca",
243 | "name": "@opam/menhirSdk",
244 | "version": "opam:20210310",
245 | "source": {
246 | "type": "install",
247 | "source": [
248 | "archive:https://opam.ocaml.org/cache/md5/1c/1cbc71c0bc1f3ddc3e71d5c1f919fd1a#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a",
249 | "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
250 | ],
251 | "opam": {
252 | "name": "menhirSdk",
253 | "version": "20210310",
254 | "path": "esy.lock/opam/menhirSdk.20210310"
255 | }
256 | },
257 | "overrides": [],
258 | "dependencies": [
259 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
260 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
261 | ],
262 | "devDependencies": [
263 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
264 | "@opam/dune@opam:2.8.4@ee414d6c"
265 | ]
266 | },
267 | "@opam/menhirLib@opam:20210310@f9315713": {
268 | "id": "@opam/menhirLib@opam:20210310@f9315713",
269 | "name": "@opam/menhirLib",
270 | "version": "opam:20210310",
271 | "source": {
272 | "type": "install",
273 | "source": [
274 | "archive:https://opam.ocaml.org/cache/md5/1c/1cbc71c0bc1f3ddc3e71d5c1f919fd1a#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a",
275 | "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
276 | ],
277 | "opam": {
278 | "name": "menhirLib",
279 | "version": "20210310",
280 | "path": "esy.lock/opam/menhirLib.20210310"
281 | }
282 | },
283 | "overrides": [],
284 | "dependencies": [
285 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
286 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
287 | ],
288 | "devDependencies": [
289 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
290 | "@opam/dune@opam:2.8.4@ee414d6c"
291 | ]
292 | },
293 | "@opam/menhir@opam:20210310@50de9216": {
294 | "id": "@opam/menhir@opam:20210310@50de9216",
295 | "name": "@opam/menhir",
296 | "version": "opam:20210310",
297 | "source": {
298 | "type": "install",
299 | "source": [
300 | "archive:https://opam.ocaml.org/cache/md5/1c/1cbc71c0bc1f3ddc3e71d5c1f919fd1a#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a",
301 | "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20210310/archive.tar.gz#md5:1cbc71c0bc1f3ddc3e71d5c1f919fd1a"
302 | ],
303 | "opam": {
304 | "name": "menhir",
305 | "version": "20210310",
306 | "path": "esy.lock/opam/menhir.20210310"
307 | }
308 | },
309 | "overrides": [],
310 | "dependencies": [
311 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
312 | "@opam/menhirSdk@opam:20210310@5abaafca",
313 | "@opam/menhirLib@opam:20210310@f9315713",
314 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
315 | ],
316 | "devDependencies": [
317 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
318 | "@opam/menhirSdk@opam:20210310@5abaafca",
319 | "@opam/menhirLib@opam:20210310@f9315713",
320 | "@opam/dune@opam:2.8.4@ee414d6c"
321 | ]
322 | },
323 | "@opam/fix@opam:20201120@5c318621": {
324 | "id": "@opam/fix@opam:20201120@5c318621",
325 | "name": "@opam/fix",
326 | "version": "opam:20201120",
327 | "source": {
328 | "type": "install",
329 | "source": [
330 | "archive:https://opam.ocaml.org/cache/md5/7e/7eb570b759635fe66f3556d2b1cc88e3#md5:7eb570b759635fe66f3556d2b1cc88e3",
331 | "archive:https://gitlab.inria.fr/fpottier/fix/repository/20201120/archive.tar.gz#md5:7eb570b759635fe66f3556d2b1cc88e3"
332 | ],
333 | "opam": {
334 | "name": "fix",
335 | "version": "20201120",
336 | "path": "esy.lock/opam/fix.20201120"
337 | }
338 | },
339 | "overrides": [],
340 | "dependencies": [
341 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
342 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
343 | ],
344 | "devDependencies": [
345 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
346 | "@opam/dune@opam:2.8.4@ee414d6c"
347 | ]
348 | },
349 | "@opam/easy-format@opam:1.3.2@0484b3c4": {
350 | "id": "@opam/easy-format@opam:1.3.2@0484b3c4",
351 | "name": "@opam/easy-format",
352 | "version": "opam:1.3.2",
353 | "source": {
354 | "type": "install",
355 | "source": [
356 | "archive:https://opam.ocaml.org/cache/sha256/34/3440c2b882d537ae5e9011eb06abb53f5667e651ea4bb3b460ea8230fa8c1926#sha256:3440c2b882d537ae5e9011eb06abb53f5667e651ea4bb3b460ea8230fa8c1926",
357 | "archive:https://github.com/mjambon/easy-format/releases/download/1.3.2/easy-format-1.3.2.tbz#sha256:3440c2b882d537ae5e9011eb06abb53f5667e651ea4bb3b460ea8230fa8c1926"
358 | ],
359 | "opam": {
360 | "name": "easy-format",
361 | "version": "1.3.2",
362 | "path": "esy.lock/opam/easy-format.1.3.2"
363 | }
364 | },
365 | "overrides": [],
366 | "dependencies": [
367 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
368 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
369 | ],
370 | "devDependencies": [
371 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
372 | "@opam/dune@opam:2.8.4@ee414d6c"
373 | ]
374 | },
375 | "@opam/dune@opam:2.8.4@ee414d6c": {
376 | "id": "@opam/dune@opam:2.8.4@ee414d6c",
377 | "name": "@opam/dune",
378 | "version": "opam:2.8.4",
379 | "source": {
380 | "type": "install",
381 | "source": [
382 | "archive:https://opam.ocaml.org/cache/sha256/4e/4e6420177584aabdc3b7b37aee3026b094b82bf5d7ed175344a68e321f72e8ac#sha256:4e6420177584aabdc3b7b37aee3026b094b82bf5d7ed175344a68e321f72e8ac",
383 | "archive:https://github.com/ocaml/dune/releases/download/2.8.4/dune-2.8.4.tbz#sha256:4e6420177584aabdc3b7b37aee3026b094b82bf5d7ed175344a68e321f72e8ac"
384 | ],
385 | "opam": {
386 | "name": "dune",
387 | "version": "2.8.4",
388 | "path": "esy.lock/opam/dune.2.8.4"
389 | }
390 | },
391 | "overrides": [],
392 | "dependencies": [
393 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
394 | "@opam/base-unix@opam:base@87d0b2eb",
395 | "@opam/base-threads@opam:base@36803084",
396 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
397 | ],
398 | "devDependencies": [
399 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
400 | "@opam/base-unix@opam:base@87d0b2eb",
401 | "@opam/base-threads@opam:base@36803084"
402 | ]
403 | },
404 | "@opam/dot-merlin-reader@opam:4.1@120afa42": {
405 | "id": "@opam/dot-merlin-reader@opam:4.1@120afa42",
406 | "name": "@opam/dot-merlin-reader",
407 | "version": "opam:4.1",
408 | "source": {
409 | "type": "install",
410 | "source": [
411 | "archive:https://opam.ocaml.org/cache/sha256/14/14a36d6fb8646a5df4530420a7861722f1a4ee04753717947305e3676031e7cd#sha256:14a36d6fb8646a5df4530420a7861722f1a4ee04753717947305e3676031e7cd",
412 | "archive:https://github.com/ocaml/merlin/releases/download/v4.1/dot-merlin-reader-v4.1.tbz#sha256:14a36d6fb8646a5df4530420a7861722f1a4ee04753717947305e3676031e7cd"
413 | ],
414 | "opam": {
415 | "name": "dot-merlin-reader",
416 | "version": "4.1",
417 | "path": "esy.lock/opam/dot-merlin-reader.4.1"
418 | }
419 | },
420 | "overrides": [],
421 | "dependencies": [
422 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
423 | "@opam/yojson@opam:1.7.0@7056d985", "@opam/result@opam:1.5@6b753c82",
424 | "@opam/ocamlfind@opam:1.8.1@b7dc3072",
425 | "@opam/dune@opam:2.8.4@ee414d6c", "@opam/csexp@opam:1.4.0@bd1cb034",
426 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
427 | ],
428 | "devDependencies": [
429 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
430 | "@opam/yojson@opam:1.7.0@7056d985", "@opam/result@opam:1.5@6b753c82",
431 | "@opam/ocamlfind@opam:1.8.1@b7dc3072",
432 | "@opam/dune@opam:2.8.4@ee414d6c", "@opam/csexp@opam:1.4.0@bd1cb034"
433 | ]
434 | },
435 | "@opam/csexp@opam:1.4.0@bd1cb034": {
436 | "id": "@opam/csexp@opam:1.4.0@bd1cb034",
437 | "name": "@opam/csexp",
438 | "version": "opam:1.4.0",
439 | "source": {
440 | "type": "install",
441 | "source": [
442 | "archive:https://opam.ocaml.org/cache/sha256/8e/8e3d6fca87f102a126dee8b72a2a0d146f10439c47218dfc149d51bf3edf364e#sha256:8e3d6fca87f102a126dee8b72a2a0d146f10439c47218dfc149d51bf3edf364e",
443 | "archive:https://github.com/ocaml-dune/csexp/releases/download/1.4.0/csexp-1.4.0.tbz#sha256:8e3d6fca87f102a126dee8b72a2a0d146f10439c47218dfc149d51bf3edf364e"
444 | ],
445 | "opam": {
446 | "name": "csexp",
447 | "version": "1.4.0",
448 | "path": "esy.lock/opam/csexp.1.4.0"
449 | }
450 | },
451 | "overrides": [],
452 | "dependencies": [
453 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
454 | "@opam/result@opam:1.5@6b753c82", "@opam/dune@opam:2.8.4@ee414d6c",
455 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
456 | ],
457 | "devDependencies": [
458 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
459 | "@opam/result@opam:1.5@6b753c82", "@opam/dune@opam:2.8.4@ee414d6c"
460 | ]
461 | },
462 | "@opam/cppo@opam:1.6.7@c28ac3ae": {
463 | "id": "@opam/cppo@opam:1.6.7@c28ac3ae",
464 | "name": "@opam/cppo",
465 | "version": "opam:1.6.7",
466 | "source": {
467 | "type": "install",
468 | "source": [
469 | "archive:https://opam.ocaml.org/cache/sha256/db/db553e3e6c206df09b1858c3aef5e21e56564d593642a3c78bcedb6af36f529d#sha256:db553e3e6c206df09b1858c3aef5e21e56564d593642a3c78bcedb6af36f529d",
470 | "archive:https://github.com/ocaml-community/cppo/releases/download/v1.6.7/cppo-v1.6.7.tbz#sha256:db553e3e6c206df09b1858c3aef5e21e56564d593642a3c78bcedb6af36f529d"
471 | ],
472 | "opam": {
473 | "name": "cppo",
474 | "version": "1.6.7",
475 | "path": "esy.lock/opam/cppo.1.6.7"
476 | }
477 | },
478 | "overrides": [],
479 | "dependencies": [
480 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
481 | "@opam/dune@opam:2.8.4@ee414d6c",
482 | "@opam/base-unix@opam:base@87d0b2eb",
483 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
484 | ],
485 | "devDependencies": [
486 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
487 | "@opam/dune@opam:2.8.4@ee414d6c",
488 | "@opam/base-unix@opam:base@87d0b2eb"
489 | ]
490 | },
491 | "@opam/conf-m4@opam:1@196bf219": {
492 | "id": "@opam/conf-m4@opam:1@196bf219",
493 | "name": "@opam/conf-m4",
494 | "version": "opam:1",
495 | "source": {
496 | "type": "install",
497 | "source": [ "no-source:" ],
498 | "opam": {
499 | "name": "conf-m4",
500 | "version": "1",
501 | "path": "esy.lock/opam/conf-m4.1"
502 | }
503 | },
504 | "overrides": [
505 | {
506 | "opamoverride":
507 | "esy.lock/overrides/opam__s__conf_m4_opam__c__1_opam_override"
508 | }
509 | ],
510 | "dependencies": [
511 | "esy-m4@github:esy-packages/esy-m4#c7cf0ac9221be2b1f9d90e83559ca08397a629e7@d41d8cd9",
512 | "@esy-ocaml/substs@0.0.1@d41d8cd9"
513 | ],
514 | "devDependencies": []
515 | },
516 | "@opam/biniou@opam:1.2.1@d7570399": {
517 | "id": "@opam/biniou@opam:1.2.1@d7570399",
518 | "name": "@opam/biniou",
519 | "version": "opam:1.2.1",
520 | "source": {
521 | "type": "install",
522 | "source": [
523 | "archive:https://opam.ocaml.org/cache/sha256/35/35546c68b1929a8e6d27a3b39ecd17b38303a0d47e65eb9d1480c2061ea84335#sha256:35546c68b1929a8e6d27a3b39ecd17b38303a0d47e65eb9d1480c2061ea84335",
524 | "archive:https://github.com/mjambon/biniou/releases/download/1.2.1/biniou-1.2.1.tbz#sha256:35546c68b1929a8e6d27a3b39ecd17b38303a0d47e65eb9d1480c2061ea84335"
525 | ],
526 | "opam": {
527 | "name": "biniou",
528 | "version": "1.2.1",
529 | "path": "esy.lock/opam/biniou.1.2.1"
530 | }
531 | },
532 | "overrides": [],
533 | "dependencies": [
534 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
535 | "@opam/easy-format@opam:1.3.2@0484b3c4",
536 | "@opam/dune@opam:2.8.4@ee414d6c", "@esy-ocaml/substs@0.0.1@d41d8cd9"
537 | ],
538 | "devDependencies": [
539 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
540 | "@opam/easy-format@opam:1.3.2@0484b3c4",
541 | "@opam/dune@opam:2.8.4@ee414d6c"
542 | ]
543 | },
544 | "@opam/base-unix@opam:base@87d0b2eb": {
545 | "id": "@opam/base-unix@opam:base@87d0b2eb",
546 | "name": "@opam/base-unix",
547 | "version": "opam:base",
548 | "source": {
549 | "type": "install",
550 | "source": [ "no-source:" ],
551 | "opam": {
552 | "name": "base-unix",
553 | "version": "base",
554 | "path": "esy.lock/opam/base-unix.base"
555 | }
556 | },
557 | "overrides": [],
558 | "dependencies": [ "@esy-ocaml/substs@0.0.1@d41d8cd9" ],
559 | "devDependencies": []
560 | },
561 | "@opam/base-threads@opam:base@36803084": {
562 | "id": "@opam/base-threads@opam:base@36803084",
563 | "name": "@opam/base-threads",
564 | "version": "opam:base",
565 | "source": {
566 | "type": "install",
567 | "source": [ "no-source:" ],
568 | "opam": {
569 | "name": "base-threads",
570 | "version": "base",
571 | "path": "esy.lock/opam/base-threads.base"
572 | }
573 | },
574 | "overrides": [],
575 | "dependencies": [ "@esy-ocaml/substs@0.0.1@d41d8cd9" ],
576 | "devDependencies": []
577 | },
578 | "@esy-ocaml/substs@0.0.1@d41d8cd9": {
579 | "id": "@esy-ocaml/substs@0.0.1@d41d8cd9",
580 | "name": "@esy-ocaml/substs",
581 | "version": "0.0.1",
582 | "source": {
583 | "type": "install",
584 | "source": [
585 | "archive:https://registry.npmjs.org/@esy-ocaml/substs/-/substs-0.0.1.tgz#sha1:59ebdbbaedcda123fc7ed8fb2b302b7d819e9a46"
586 | ]
587 | },
588 | "overrides": [],
589 | "dependencies": [],
590 | "devDependencies": []
591 | },
592 | "@esy-ocaml/reason@3.7.0@d41d8cd9": {
593 | "id": "@esy-ocaml/reason@3.7.0@d41d8cd9",
594 | "name": "@esy-ocaml/reason",
595 | "version": "3.7.0",
596 | "source": {
597 | "type": "install",
598 | "source": [
599 | "archive:https://registry.npmjs.org/@esy-ocaml/reason/-/reason-3.7.0.tgz#sha1:36f92c1c854477c4da37e4769a045ffe60e4fb10"
600 | ]
601 | },
602 | "overrides": [],
603 | "dependencies": [
604 | "ocaml@github:anmonteiro/ocaml#72babec0e1796ce322464afc8ef2a0d7125d60cb@d41d8cd9",
605 | "@opam/result@opam:1.5@6b753c82",
606 | "@opam/ppx_derivers@opam:1.2.1@ecf0aa45",
607 | "@opam/ocamlfind@opam:1.8.1@b7dc3072",
608 | "@opam/merlin-extend@opam:0.6@404f814c",
609 | "@opam/menhir@opam:20210310@50de9216",
610 | "@opam/fix@opam:20201120@5c318621", "@opam/dune@opam:2.8.4@ee414d6c"
611 | ],
612 | "devDependencies": []
613 | }
614 | }
615 | }
--------------------------------------------------------------------------------