diff --git a/esy.lock/.gitattributes b/esy.lock/.gitattributes index 25366ae..e0b4e26 100644 --- a/esy.lock/.gitattributes +++ b/esy.lock/.gitattributes @@ -1,3 +1,3 @@ # Set eol to LF so files aren't converted to CRLF-eol on Windows. -* text eol=lf +* text eol=lf linguist-generated diff --git a/esy.lock/index.json b/esy.lock/index.json index 85bd4ea..10940c9 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -1,27 +1,7 @@ { - "checksum": "08c72a7ad5393f94b36a5e3468bec9c6", + "checksum": "370f6b17e6768443462aa8996a7e3dc0", "root": "brisk-reconciler@link-dev:./package.json", "node": { - "refmterr@3.2.2@d41d8cd9": { - "id": "refmterr@3.2.2@d41d8cd9", - "name": "refmterr", - "version": "3.2.2", - "source": { - "type": "install", - "source": [ - "archive:https://registry.npmjs.org/refmterr/-/refmterr-3.2.2.tgz#sha1:b7d6c5df6a37633ec82d339dc609b1867e54e55e" - ] - }, - "overrides": [], - "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@reason-native/pastel@0.2.2@d41d8cd9", - "@reason-native/console@0.1.0@d41d8cd9", - "@opam/re@opam:1.9.0@d4d5e13d", "@opam/dune@opam:1.11.4@21d66ccd", - "@opam/atdgen@opam:2.0.0@46af0360", - "@esy-ocaml/reason@3.5.2@d41d8cd9" - ], - "devDependencies": [] - }, "ocaml@4.8.1000@d41d8cd9": { "id": "ocaml@4.8.1000@d41d8cd9", "name": "ocaml", @@ -47,51 +27,50 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/ppxlib@opam:0.8.1@67aec471", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/reason@3.5.2@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@opam/ppxlib@opam:0.13.0@65a9c7cc", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/reason@3.6.0@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@reason-native/rely@3.1.0@d41d8cd9", - "@opam/ppx_deriving@opam:4.4@21d6c7a5", - "@opam/ocamlformat@opam:0.12@35299172", - "@opam/merlin-lsp@github:ocaml/merlin:merlin-lsp.opam#c8b0f03@d41d8cd9", - "@opam/merlin@opam:3.3.2@7a364181" + "ocaml@4.8.1000@d41d8cd9", "@reason-native/rely@3.2.1@d41d8cd9", + "@opam/ppx_deriving@opam:4.4.1@208c6c8f", + "@opam/ocamlformat@opam:0.14.1@bad09513", + "@opam/ocaml-lsp-server@github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#b888f45eb7ccb4292138715623dc2455bf32f8a8@d41d8cd9" ] }, - "@reason-native/rely@3.1.0@d41d8cd9": { - "id": "@reason-native/rely@3.1.0@d41d8cd9", + "@reason-native/rely@3.2.1@d41d8cd9": { + "id": "@reason-native/rely@3.2.1@d41d8cd9", "name": "@reason-native/rely", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@reason-native/rely/-/rely-3.1.0.tgz#sha1:4f59906dc7c18ba86c998e44d6463b6be866dfc6" + "archive:https://registry.npmjs.org/@reason-native/rely/-/rely-3.2.1.tgz#sha1:7945ac6a51773a97b8f8cfd97d2855ac7ac4ecb2" ] }, "overrides": [], "dependencies": [ - "refmterr@3.2.2@d41d8cd9", "ocaml@4.8.1000@d41d8cd9", - "@reason-native/pastel@0.2.2@d41d8cd9", + "ocaml@4.8.1000@d41d8cd9", "@reason-native/pastel@0.3.0@d41d8cd9", "@reason-native/file-context-printer@0.0.3@d41d8cd9", - "@opam/re@opam:1.9.0@d4d5e13d", "@opam/junit@opam:2.0.1@1b4d302c", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/reason@3.5.2@d41d8cd9" + "@reason-native/cli@0.0.1-alpha@d41d8cd9", + "@opam/re@opam:1.9.0@d4d5e13d", "@opam/junit@opam:2.0.2@0b7bd730", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/reason@3.6.0@d41d8cd9" ], "devDependencies": [] }, - "@reason-native/pastel@0.2.2@d41d8cd9": { - "id": "@reason-native/pastel@0.2.2@d41d8cd9", + "@reason-native/pastel@0.3.0@d41d8cd9": { + "id": "@reason-native/pastel@0.3.0@d41d8cd9", "name": "@reason-native/pastel", - "version": "0.2.2", + "version": "0.3.0", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@reason-native/pastel/-/pastel-0.2.2.tgz#sha1:a1f7fe266223aaf7915a71f5c8b9ee58e065c62a" + "archive:https://registry.npmjs.org/@reason-native/pastel/-/pastel-0.3.0.tgz#sha1:07da3c5a0933e61bc3b353bc85aa71ac7c0f311c" ] }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/re@opam:1.9.0@d4d5e13d", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/reason@3.5.2@d41d8cd9" + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/reason@3.6.0@d41d8cd9" ], "devDependencies": [] }, @@ -107,26 +86,27 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@reason-native/pastel@0.2.2@d41d8cd9", - "@opam/re@opam:1.9.0@d4d5e13d", "@opam/dune@opam:1.11.4@21d66ccd", - "@esy-ocaml/reason@3.5.2@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@reason-native/pastel@0.3.0@d41d8cd9", + "@opam/re@opam:1.9.0@d4d5e13d", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/reason@3.6.0@d41d8cd9" ], "devDependencies": [] }, - "@reason-native/console@0.1.0@d41d8cd9": { - "id": "@reason-native/console@0.1.0@d41d8cd9", - "name": "@reason-native/console", - "version": "0.1.0", + "@reason-native/cli@0.0.1-alpha@d41d8cd9": { + "id": "@reason-native/cli@0.0.1-alpha@d41d8cd9", + "name": "@reason-native/cli", + "version": "0.0.1-alpha", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@reason-native/console/-/console-0.1.0.tgz#sha1:3b56f0e9e1be8464329793df29020aa90e71c22c" + "archive:https://registry.npmjs.org/@reason-native/cli/-/cli-0.0.1-alpha.tgz#sha1:0b911053fa7cc661eac10ead50d6ea6cc1fcd94d" ] }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", - "@esy-ocaml/reason@3.5.2@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@reason-native/pastel@0.3.0@d41d8cd9", + "@opam/re@opam:1.9.0@d4d5e13d", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/reason@3.6.0@d41d8cd9" ], "devDependencies": [] }, @@ -149,13 +129,13 @@ "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/easy-format@opam:1.3.2@0484b3c4", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/cppo@opam:1.6.6@f4f83858", + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cppo@opam:1.6.6@f4f83858", "@opam/biniou@opam:1.2.1@d7570399", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/easy-format@opam:1.3.2@0484b3c4", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/biniou@opam:1.2.1@d7570399" + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/biniou@opam:1.2.1@d7570399" ] }, "@opam/uutf@opam:1.0.2@4440868f": { @@ -187,65 +167,61 @@ "ocaml@4.8.1000@d41d8cd9", "@opam/uchar@opam:0.0.2@c8218eea" ] }, - "@opam/uuseg@opam:12.0.0@bf82c4c7": { - "id": "@opam/uuseg@opam:12.0.0@bf82c4c7", + "@opam/uuseg@opam:13.0.0@f60712a7": { + "id": "@opam/uuseg@opam:13.0.0@f60712a7", "name": "@opam/uuseg", - "version": "opam:12.0.0", + "version": "opam:13.0.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/1d/1d4487ddf5154e3477e55021b978d58a#md5:1d4487ddf5154e3477e55021b978d58a", - "archive:https://erratique.ch/software/uuseg/releases/uuseg-12.0.0.tbz#md5:1d4487ddf5154e3477e55021b978d58a" + "archive:https://opam.ocaml.org/cache/md5/a0/a07a97fff61da604614ea8da0547ef6a#md5:a07a97fff61da604614ea8da0547ef6a", + "archive:https://erratique.ch/software/uuseg/releases/uuseg-13.0.0.tbz#md5:a07a97fff61da604614ea8da0547ef6a" ], "opam": { "name": "uuseg", - "version": "12.0.0", - "path": "esy.lock/opam/uuseg.12.0.0" + "version": "13.0.0", + "path": "esy.lock/opam/uuseg.13.0.0" } }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", - "@opam/uucp@opam:12.0.0@b7d4c3df", "@opam/uchar@opam:0.0.2@c8218eea", - "@opam/topkg@opam:1.0.1@a42c631e", + "@opam/uucp@opam:13.0.0@e9b515e0", "@opam/topkg@opam:1.0.1@a42c631e", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", "@opam/ocamlbuild@opam:0.14.0@6ac75d03", "@opam/cmdliner@opam:1.0.4@93208aac", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/uucp@opam:12.0.0@b7d4c3df", - "@opam/uchar@opam:0.0.2@c8218eea" + "ocaml@4.8.1000@d41d8cd9", "@opam/uucp@opam:13.0.0@e9b515e0" ] }, - "@opam/uucp@opam:12.0.0@b7d4c3df": { - "id": "@opam/uucp@opam:12.0.0@b7d4c3df", + "@opam/uucp@opam:13.0.0@e9b515e0": { + "id": "@opam/uucp@opam:13.0.0@e9b515e0", "name": "@opam/uucp", - "version": "opam:12.0.0", + "version": "opam:13.0.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/cf/cf210ed43375b7f882c0540874e2cb81#md5:cf210ed43375b7f882c0540874e2cb81", - "archive:https://erratique.ch/software/uucp/releases/uucp-12.0.0.tbz#md5:cf210ed43375b7f882c0540874e2cb81" + "archive:https://opam.ocaml.org/cache/md5/07/07e706249ddb2d02f0fa298804d3c739#md5:07e706249ddb2d02f0fa298804d3c739", + "archive:https://erratique.ch/software/uucp/releases/uucp-13.0.0.tbz#md5:07e706249ddb2d02f0fa298804d3c739" ], "opam": { "name": "uucp", - "version": "12.0.0", - "path": "esy.lock/opam/uucp.12.0.0" + "version": "13.0.0", + "path": "esy.lock/opam/uucp.13.0.0" } }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", - "@opam/uchar@opam:0.0.2@c8218eea", "@opam/topkg@opam:1.0.1@a42c631e", + "@opam/topkg@opam:1.0.1@a42c631e", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", "@opam/ocamlbuild@opam:0.14.0@6ac75d03", "@opam/cmdliner@opam:1.0.4@93208aac", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], - "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/uchar@opam:0.0.2@c8218eea" - ] + "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] }, "@opam/uchar@opam:0.0.2@c8218eea": { "id": "@opam/uchar@opam:0.0.2@c8218eea", @@ -270,32 +246,32 @@ ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] }, - "@opam/tyxml@opam:4.3.0@c1da25f1": { - "id": "@opam/tyxml@opam:4.3.0@c1da25f1", + "@opam/tyxml@opam:4.4.0@1dca5713": { + "id": "@opam/tyxml@opam:4.4.0@1dca5713", "name": "@opam/tyxml", - "version": "opam:4.3.0", + "version": "opam:4.4.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/fd/fd834a567f813bf447cab5f4c3a723e2#md5:fd834a567f813bf447cab5f4c3a723e2", - "archive:https://github.com/ocsigen/tyxml/releases/download/4.3.0/tyxml-4.3.0.tbz#md5:fd834a567f813bf447cab5f4c3a723e2" + "archive:https://opam.ocaml.org/cache/sha256/51/516394dd4a5c31726997c51d66aa31cacb91e3c46d4e16c7699130e204042530#sha256:516394dd4a5c31726997c51d66aa31cacb91e3c46d4e16c7699130e204042530", + "archive:https://github.com/ocsigen/tyxml/releases/download/4.4.0/tyxml-4.4.0.tbz#sha256:516394dd4a5c31726997c51d66aa31cacb91e3c46d4e16c7699130e204042530" ], "opam": { "name": "tyxml", - "version": "4.3.0", - "path": "esy.lock/opam/tyxml.4.3.0" + "version": "4.4.0", + "path": "esy.lock/opam/tyxml.4.4.0" } }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", "@opam/seq@opam:base@d8d7de1d", "@opam/re@opam:1.9.0@d4d5e13d", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", "@opam/seq@opam:base@d8d7de1d", "@opam/re@opam:1.9.0@d4d5e13d", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/topkg@opam:1.0.1@a42c631e": { @@ -324,56 +300,81 @@ "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlbuild@opam:0.14.0@6ac75d03" ] }, - "@opam/stdio@opam:v0.12.0@04b3b004": { - "id": "@opam/stdio@opam:v0.12.0@04b3b004", + "@opam/stdlib-shims@opam:0.1.0@d957c903": { + "id": "@opam/stdlib-shims@opam:0.1.0@d957c903", + "name": "@opam/stdlib-shims", + "version": "opam:0.1.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/md5/12/12b5704eed70c6bff5ac39a16db1425d#md5:12b5704eed70c6bff5ac39a16db1425d", + "archive:https://github.com/ocaml/stdlib-shims/releases/download/0.1.0/stdlib-shims-0.1.0.tbz#md5:12b5704eed70c6bff5ac39a16db1425d" + ], + "opam": { + "name": "stdlib-shims", + "version": "0.1.0", + "path": "esy.lock/opam/stdlib-shims.0.1.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" + ] + }, + "@opam/stdio@opam:v0.13.0@eb59d879": { + "id": "@opam/stdio@opam:v0.13.0@eb59d879", "name": "@opam/stdio", - "version": "opam:v0.12.0", + "version": "opam:v0.13.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/b2/b261ff2d5667fde960c95e50cff668da#md5:b261ff2d5667fde960c95e50cff668da", - "archive:https://ocaml.janestreet.com/ocaml-core/v0.12/files/stdio-v0.12.0.tar.gz#md5:b261ff2d5667fde960c95e50cff668da" + "archive:https://opam.ocaml.org/cache/md5/48/48ef28512ddd51ff9885649dd1fab91d#md5:48ef28512ddd51ff9885649dd1fab91d", + "archive:https://ocaml.janestreet.com/ocaml-core/v0.13/files/stdio-v0.13.0.tar.gz#md5:48ef28512ddd51ff9885649dd1fab91d" ], "opam": { "name": "stdio", - "version": "v0.12.0", - "path": "esy.lock/opam/stdio.v0.12.0" + "version": "v0.13.0", + "path": "esy.lock/opam/stdio.v0.13.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", - "@opam/base@opam:v0.12.2@d687150c", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@opam/base@opam:v0.13.1@7d937ed0", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", - "@opam/base@opam:v0.12.2@d687150c" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@opam/base@opam:v0.13.1@7d937ed0" ] }, - "@opam/sexplib0@opam:v0.12.0@e432406d": { - "id": "@opam/sexplib0@opam:v0.12.0@e432406d", + "@opam/sexplib0@opam:v0.13.0@3f54c2be": { + "id": "@opam/sexplib0@opam:v0.13.0@3f54c2be", "name": "@opam/sexplib0", - "version": "opam:v0.12.0", + "version": "opam:v0.13.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/24/2486a25d3a94da9a94acc018b5f09061#md5:2486a25d3a94da9a94acc018b5f09061", - "archive:https://ocaml.janestreet.com/ocaml-core/v0.12/files/sexplib0-v0.12.0.tar.gz#md5:2486a25d3a94da9a94acc018b5f09061" + "archive:https://opam.ocaml.org/cache/md5/f8/f8a715dffda5599cfae0cb4031d57abe#md5:f8a715dffda5599cfae0cb4031d57abe", + "archive:https://ocaml.janestreet.com/ocaml-core/v0.13/files/sexplib0-v0.13.0.tar.gz#md5:f8a715dffda5599cfae0cb4031d57abe" ], "opam": { "name": "sexplib0", - "version": "v0.12.0", - "path": "esy.lock/opam/sexplib0.v0.12.0" + "version": "v0.13.0", + "path": "esy.lock/opam/sexplib0.v0.13.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/seq@opam:base@d8d7de1d": { @@ -395,29 +396,29 @@ ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] }, - "@opam/result@opam:1.4@dc720aef": { - "id": "@opam/result@opam:1.4@dc720aef", + "@opam/result@opam:1.5@6b753c82": { + "id": "@opam/result@opam:1.5@6b753c82", "name": "@opam/result", - "version": "opam:1.4", + "version": "opam:1.5", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/d3/d3162dbc501a2af65c8c71e0866541da#md5:d3162dbc501a2af65c8c71e0866541da", - "archive:https://github.com/janestreet/result/archive/1.4.tar.gz#md5:d3162dbc501a2af65c8c71e0866541da" + "archive:https://opam.ocaml.org/cache/md5/1b/1b82dec78849680b49ae9a8a365b831b#md5:1b82dec78849680b49ae9a8a365b831b", + "archive:https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz#md5:1b82dec78849680b49ae9a8a365b831b" ], "opam": { "name": "result", - "version": "1.4", - "path": "esy.lock/opam/result.1.4" + "version": "1.5", + "path": "esy.lock/opam/result.1.5" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/re@opam:1.9.0@d4d5e13d": { @@ -439,11 +440,11 @@ "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/seq@opam:base@d8d7de1d", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/seq@opam:base@d8d7de1d", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/ptime@opam:0.8.5@0051d642": { @@ -465,164 +466,159 @@ "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/topkg@opam:1.0.1@a42c631e", - "@opam/result@opam:1.4@dc720aef", + "@opam/result@opam:1.5@6b753c82", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", "@opam/ocamlbuild@opam:0.14.0@6ac75d03", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef" + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82" ] }, - "@opam/ppxlib@opam:0.8.1@67aec471": { - "id": "@opam/ppxlib@opam:0.8.1@67aec471", + "@opam/ppxlib@opam:0.13.0@65a9c7cc": { + "id": "@opam/ppxlib@opam:0.13.0@65a9c7cc", "name": "@opam/ppxlib", - "version": "opam:0.8.1", + "version": "opam:0.13.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/a5/a5cb79ee83bba80304b65bc47f2985382bef89668b1b46f9ffb3734c2f2f7521#sha256:a5cb79ee83bba80304b65bc47f2985382bef89668b1b46f9ffb3734c2f2f7521", - "archive:https://github.com/ocaml-ppx/ppxlib/releases/download/0.8.1/ppxlib-0.8.1.tbz#sha256:a5cb79ee83bba80304b65bc47f2985382bef89668b1b46f9ffb3734c2f2f7521" + "archive:https://opam.ocaml.org/cache/sha256/81/81e1f3d308500e0e7f6108d5b0dda2b879640a5c21ef3dc4a9bd90381cee39d9#sha256:81e1f3d308500e0e7f6108d5b0dda2b879640a5c21ef3dc4a9bd90381cee39d9", + "archive:https://github.com/ocaml-ppx/ppxlib/releases/download/0.13.0/ppxlib-0.13.0.tbz#sha256:81e1f3d308500e0e7f6108d5b0dda2b879640a5c21ef3dc4a9bd90381cee39d9" ], "opam": { "name": "ppxlib", - "version": "0.8.1", - "path": "esy.lock/opam/ppxlib.0.8.1" + "version": "0.13.0", + "path": "esy.lock/opam/ppxlib.0.13.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/stdio@opam:v0.12.0@04b3b004", + "ocaml@4.8.1000@d41d8cd9", "@opam/stdio@opam:v0.13.0@eb59d879", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", "@opam/ocaml-compiler-libs@opam:v0.12.1@5c34eb0d", - "@opam/dune@opam:1.11.4@21d66ccd", - "@opam/base@opam:v0.12.2@d687150c", + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/base@opam:v0.13.1@7d937ed0", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/stdio@opam:v0.12.0@04b3b004", + "ocaml@4.8.1000@d41d8cd9", "@opam/stdio@opam:v0.13.0@eb59d879", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", "@opam/ocaml-compiler-libs@opam:v0.12.1@5c34eb0d", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/base@opam:v0.12.2@d687150c" + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/base@opam:v0.13.1@7d937ed0" ] }, - "@opam/ppxfind@opam:1.3@262387fc": { - "id": "@opam/ppxfind@opam:1.3@262387fc", + "@opam/ppxfind@opam:1.4@c51fd7bf": { + "id": "@opam/ppxfind@opam:1.4@c51fd7bf", "name": "@opam/ppxfind", - "version": "opam:1.3", + "version": "opam:1.4", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/d4/d49db026d0e74212c4b475b4e628aa57508c7452a0682d8c96e80c130ab892e4#sha256:d49db026d0e74212c4b475b4e628aa57508c7452a0682d8c96e80c130ab892e4", - "archive:https://github.com/diml/ppxfind/releases/download/1.3/ppxfind-1.3.tbz#sha256:d49db026d0e74212c4b475b4e628aa57508c7452a0682d8c96e80c130ab892e4" + "archive:https://opam.ocaml.org/cache/sha256/98/98291c69f04f7f7b7cdad1b5d786c70fc595559d4663cc04cb711ac132db4971#sha256:98291c69f04f7f7b7cdad1b5d786c70fc595559d4663cc04cb711ac132db4971", + "archive:https://github.com/diml/ppxfind/releases/download/1.4/ppxfind-1.4.tbz#sha256:98291c69f04f7f7b7cdad1b5d786c70fc595559d4663cc04cb711ac132db4971" ], "opam": { "name": "ppxfind", - "version": "1.3", - "path": "esy.lock/opam/ppxfind.1.3" + "version": "1.4", + "path": "esy.lock/opam/ppxfind.1.4" } }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/ppx_tools@opam:5.3+4.08.0@0ce29228": { - "id": "@opam/ppx_tools@opam:5.3+4.08.0@0ce29228", - "name": "@opam/ppx_tools", - "version": "opam:5.3+4.08.0", + "@opam/ppx_yojson_conv_lib@opam:v0.13.0@97a4cb97": { + "id": "@opam/ppx_yojson_conv_lib@opam:v0.13.0@97a4cb97", + "name": "@opam/ppx_yojson_conv_lib", + "version": "opam:v0.13.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/70/702b11138c095662c175aa4dcce5c921#md5:702b11138c095662c175aa4dcce5c921", - "archive:https://github.com/ocaml-ppx/ppx_tools/archive/5.3+4.08.0.tar.gz#md5:702b11138c095662c175aa4dcce5c921" + "archive:https://opam.ocaml.org/cache/md5/79/790fade9ecff5767dd48cd49c9bba2f3#md5:790fade9ecff5767dd48cd49c9bba2f3", + "archive:https://ocaml.janestreet.com/ocaml-core/v0.13/files/ppx_yojson_conv_lib-v0.13.0.tar.gz#md5:790fade9ecff5767dd48cd49c9bba2f3" ], "opam": { - "name": "ppx_tools", - "version": "5.3+4.08.0", - "path": "esy.lock/opam/ppx_tools.5.3+4.08.0" + "name": "ppx_yojson_conv_lib", + "version": "v0.13.0", + "path": "esy.lock/opam/ppx_yojson_conv_lib.v0.13.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@esy-ocaml/substs@0.0.1@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], - "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/dune@opam:2.5.1@a0c1e658" + ] }, - "@opam/ppx_deriving_yojson@opam:3.5.1@06a1c37f": { - "id": "@opam/ppx_deriving_yojson@opam:3.5.1@06a1c37f", - "name": "@opam/ppx_deriving_yojson", - "version": "opam:3.5.1", + "@opam/ppx_tools@opam:6.0+4.08.0@5f5453f4": { + "id": "@opam/ppx_tools@opam:6.0+4.08.0@5f5453f4", + "name": "@opam/ppx_tools", + "version": "opam:6.0+4.08.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/ae/aefe9c673f2f0ee2beb9edcca5a4e332a9fe9266c81bc554b8df5cd375568994#sha256:aefe9c673f2f0ee2beb9edcca5a4e332a9fe9266c81bc554b8df5cd375568994", - "archive:https://github.com/ocaml-ppx/ppx_deriving_yojson/archive/v3.5.1.tar.gz#sha256:aefe9c673f2f0ee2beb9edcca5a4e332a9fe9266c81bc554b8df5cd375568994" + "archive:https://opam.ocaml.org/cache/md5/80/801e82103fee7ce1e4a59ab670601952#md5:801e82103fee7ce1e4a59ab670601952", + "archive:https://github.com/ocaml-ppx/ppx_tools/archive/6.0+4.08.0.tar.gz#md5:801e82103fee7ce1e4a59ab670601952" ], "opam": { - "name": "ppx_deriving_yojson", - "version": "3.5.1", - "path": "esy.lock/opam/ppx_deriving_yojson.3.5.1" + "name": "ppx_tools", + "version": "6.0+4.08.0", + "path": "esy.lock/opam/ppx_tools.6.0+4.08.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/result@opam:1.4@dc720aef", "@opam/ppxfind@opam:1.3@262387fc", - "@opam/ppx_tools@opam:5.3+4.08.0@0ce29228", - "@opam/ppx_deriving@opam:4.4@21d6c7a5", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/cppo@opam:1.6.6@f4f83858", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/result@opam:1.4@dc720aef", - "@opam/ppx_deriving@opam:4.4@21d6c7a5", - "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/ppx_deriving@opam:4.4@21d6c7a5": { - "id": "@opam/ppx_deriving@opam:4.4@21d6c7a5", + "@opam/ppx_deriving@opam:4.4.1@208c6c8f": { + "id": "@opam/ppx_deriving@opam:4.4.1@208c6c8f", "name": "@opam/ppx_deriving", - "version": "opam:4.4", + "version": "opam:4.4.1", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/c2/c2d85af4cb65a1f163f624590fb0395a164bbfd0d05082092526b669e66bcc34#sha256:c2d85af4cb65a1f163f624590fb0395a164bbfd0d05082092526b669e66bcc34", - "archive:https://github.com/ocaml-ppx/ppx_deriving/archive/v4.4.tar.gz#sha256:c2d85af4cb65a1f163f624590fb0395a164bbfd0d05082092526b669e66bcc34" + "archive:https://opam.ocaml.org/cache/sha256/27/27bc57774724fc4f48775f2011375a5ee1439570204abbf6607761c472757e2f#sha256:27bc57774724fc4f48775f2011375a5ee1439570204abbf6607761c472757e2f", + "archive:https://github.com/ocaml-ppx/ppx_deriving/archive/v4.4.1.tar.gz#sha256:27bc57774724fc4f48775f2011375a5ee1439570204abbf6607761c472757e2f" ], "opam": { "name": "ppx_deriving", - "version": "4.4", - "path": "esy.lock/opam/ppx_deriving.4.4" + "version": "4.4.1", + "path": "esy.lock/opam/ppx_deriving.4.4.1" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", - "@opam/ppxfind@opam:1.3@262387fc", - "@opam/ppx_tools@opam:5.3+4.08.0@0ce29228", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", + "@opam/ppxfind@opam:1.4@c51fd7bf", + "@opam/ppx_tools@opam:6.0+4.08.0@5f5453f4", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/cppo@opam:1.6.6@f4f83858", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cppo@opam:1.6.6@f4f83858", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", - "@opam/ppx_tools@opam:5.3+4.08.0@0ce29228", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", + "@opam/ppx_tools@opam:6.0+4.08.0@5f5453f4", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/ppx_derivers@opam:1.2.1@ecf0aa45": { @@ -643,81 +639,89 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/odoc@opam:1.4.2@6f058006": { - "id": "@opam/odoc@opam:1.4.2@6f058006", + "@opam/odoc@opam:1.5.0@35218f5f": { + "id": "@opam/odoc@opam:1.5.0@35218f5f", "name": "@opam/odoc", - "version": "opam:1.4.2", + "version": "opam:1.5.0", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/d7/d75ce63539040cd199d22203d46fc5f3#md5:d75ce63539040cd199d22203d46fc5f3", - "archive:https://github.com/ocaml/odoc/archive/1.4.2.tar.gz#md5:d75ce63539040cd199d22203d46fc5f3" + "archive:https://opam.ocaml.org/cache/sha256/85/857759be968070bfda208add3ae2c2bc87826ca2bfc39cebab1cc1e13db7a140#sha256:857759be968070bfda208add3ae2c2bc87826ca2bfc39cebab1cc1e13db7a140", + "archive:https://github.com/ocaml/odoc/releases/download/1.5.0/odoc-1.5.0.tbz#sha256:857759be968070bfda208add3ae2c2bc87826ca2bfc39cebab1cc1e13db7a140" ], "opam": { "name": "odoc", - "version": "1.4.2", - "path": "esy.lock/opam/odoc.1.4.2" + "version": "1.5.0", + "path": "esy.lock/opam/odoc.1.5.0" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/tyxml@opam:4.3.0@c1da25f1", - "@opam/result@opam:1.4@dc720aef", "@opam/fpath@opam:0.7.2@45477b93", - "@opam/dune@opam:1.11.4@21d66ccd", "@opam/cppo@opam:1.6.6@f4f83858", + "ocaml@4.8.1000@d41d8cd9", "@opam/tyxml@opam:4.4.0@1dca5713", + "@opam/result@opam:1.5@6b753c82", "@opam/fpath@opam:0.7.2@45477b93", + "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cppo@opam:1.6.6@f4f83858", "@opam/cmdliner@opam:1.0.4@93208aac", "@opam/astring@opam:0.8.3@4e5e17d5", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/tyxml@opam:4.4.0@1dca5713", + "@opam/result@opam:1.5@6b753c82", "@opam/fpath@opam:0.7.2@45477b93", + "@opam/dune@opam:2.5.1@a0c1e658", + "@opam/cmdliner@opam:1.0.4@93208aac", + "@opam/astring@opam:0.8.3@4e5e17d5" ] }, - "@opam/ocamlformat@opam:0.12@35299172": { - "id": "@opam/ocamlformat@opam:0.12@35299172", + "@opam/ocamlformat@opam:0.14.1@bad09513": { + "id": "@opam/ocamlformat@opam:0.14.1@bad09513", "name": "@opam/ocamlformat", - "version": "opam:0.12", + "version": "opam:0.14.1", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/f2/f2b64ff7f5cb9b4e19c6fc4e3f0fbd1747ef09d24848238540e2c27652e928fe#sha256:f2b64ff7f5cb9b4e19c6fc4e3f0fbd1747ef09d24848238540e2c27652e928fe", - "archive:https://github.com/ocaml-ppx/ocamlformat/releases/download/0.12/ocamlformat-0.12.tbz#sha256:f2b64ff7f5cb9b4e19c6fc4e3f0fbd1747ef09d24848238540e2c27652e928fe" + "archive:https://opam.ocaml.org/cache/sha256/4a/4a7d4575c202bd0413b2864be60000854feade9190f5530222679815bb21960f#sha256:4a7d4575c202bd0413b2864be60000854feade9190f5530222679815bb21960f", + "archive:https://github.com/ocaml-ppx/ocamlformat/releases/download/0.14.1/ocamlformat-0.14.1.tbz#sha256:4a7d4575c202bd0413b2864be60000854feade9190f5530222679815bb21960f" ], "opam": { "name": "ocamlformat", - "version": "0.12", - "path": "esy.lock/opam/ocamlformat.0.12" + "version": "0.14.1", + "path": "esy.lock/opam/ocamlformat.0.14.1" } }, "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", - "@opam/uuseg@opam:12.0.0@bf82c4c7", - "@opam/stdio@opam:v0.12.0@04b3b004", "@opam/re@opam:1.9.0@d4d5e13d", - "@opam/odoc@opam:1.4.2@6f058006", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/fpath@opam:0.7.2@45477b93", "@opam/dune@opam:1.11.4@21d66ccd", + "@opam/uuseg@opam:13.0.0@f60712a7", + "@opam/stdio@opam:v0.13.0@eb59d879", "@opam/re@opam:1.9.0@d4d5e13d", + "@opam/odoc@opam:1.5.0@35218f5f", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/menhir@opam:20200211@26571604", + "@opam/fpath@opam:0.7.2@45477b93", + "@opam/fix@opam:20200131@0ecd2f01", "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cmdliner@opam:1.0.4@93208aac", "@opam/base-unix@opam:base@87d0b2eb", - "@opam/base@opam:v0.12.2@d687150c", + "@opam/base@opam:v0.13.1@7d937ed0", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/uutf@opam:1.0.2@4440868f", - "@opam/uuseg@opam:12.0.0@bf82c4c7", - "@opam/stdio@opam:v0.12.0@04b3b004", "@opam/re@opam:1.9.0@d4d5e13d", - "@opam/odoc@opam:1.4.2@6f058006", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", - "@opam/fpath@opam:0.7.2@45477b93", "@opam/dune@opam:1.11.4@21d66ccd", + "@opam/uuseg@opam:13.0.0@f60712a7", + "@opam/stdio@opam:v0.13.0@eb59d879", "@opam/re@opam:1.9.0@d4d5e13d", + "@opam/odoc@opam:1.5.0@35218f5f", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", + "@opam/menhir@opam:20200211@26571604", + "@opam/fpath@opam:0.7.2@45477b93", + "@opam/fix@opam:20200131@0ecd2f01", "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cmdliner@opam:1.0.4@93208aac", "@opam/base-unix@opam:base@87d0b2eb", - "@opam/base@opam:v0.12.2@d687150c" + "@opam/base@opam:v0.13.1@7d937ed0" ] }, "@opam/ocamlfind@opam:1.8.1@ff07b0f9": { @@ -776,32 +780,89 @@ ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] }, - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc": { - "id": "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", + "@opam/ocaml-syntax-shims@opam:1.0.0@a9aa3bfa": { + "id": "@opam/ocaml-syntax-shims@opam:1.0.0@a9aa3bfa", + "name": "@opam/ocaml-syntax-shims", + "version": "opam:1.0.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/89/89b2e193e90a0c168b6ec5ddf6fef09033681bdcb64e11913c97440a2722e8c8#sha256:89b2e193e90a0c168b6ec5ddf6fef09033681bdcb64e11913c97440a2722e8c8", + "archive:https://github.com/ocaml-ppx/ocaml-syntax-shims/releases/download/1.0.0/ocaml-syntax-shims-1.0.0.tbz#sha256:89b2e193e90a0c168b6ec5ddf6fef09033681bdcb64e11913c97440a2722e8c8" + ], + "opam": { + "name": "ocaml-syntax-shims", + "version": "1.0.0", + "path": "esy.lock/opam/ocaml-syntax-shims.1.0.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" + ] + }, + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e": { + "id": "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", "name": "@opam/ocaml-migrate-parsetree", - "version": "opam:1.5.0", + "version": "opam:1.7.2", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/7f/7f56679c9561552762666de5b6b81c8e4cc2e9fd92272e2269878a2eb534e3c0#sha256:7f56679c9561552762666de5b6b81c8e4cc2e9fd92272e2269878a2eb534e3c0", - "archive:https://github.com/ocaml-ppx/ocaml-migrate-parsetree/releases/download/v1.5.0/ocaml-migrate-parsetree-v1.5.0.tbz#sha256:7f56679c9561552762666de5b6b81c8e4cc2e9fd92272e2269878a2eb534e3c0" + "archive:https://opam.ocaml.org/cache/sha256/6a/6ae6753c3e632a63f76b031afc3eab74b209babdfdba4030060a934ce0660bd6#sha256:6ae6753c3e632a63f76b031afc3eab74b209babdfdba4030060a934ce0660bd6", + "archive:https://github.com/ocaml-ppx/ocaml-migrate-parsetree/releases/download/v1.7.2/ocaml-migrate-parsetree-v1.7.2.tbz#sha256:6ae6753c3e632a63f76b031afc3eab74b209babdfdba4030060a934ce0660bd6" ], "opam": { "name": "ocaml-migrate-parsetree", - "version": "1.5.0", - "path": "esy.lock/opam/ocaml-migrate-parsetree.1.5.0" + "version": "1.7.2", + "path": "esy.lock/opam/ocaml-migrate-parsetree.1.7.2" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/dune@opam:2.5.1@a0c1e658" + ] + }, + "@opam/ocaml-lsp-server@github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#b888f45eb7ccb4292138715623dc2455bf32f8a8@d41d8cd9": { + "id": + "@opam/ocaml-lsp-server@github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#b888f45eb7ccb4292138715623dc2455bf32f8a8@d41d8cd9", + "name": "@opam/ocaml-lsp-server", + "version": + "github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#b888f45eb7ccb4292138715623dc2455bf32f8a8", + "source": { + "type": "install", + "source": [ + "github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#b888f45eb7ccb4292138715623dc2455bf32f8a8" + ] + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/stdlib-shims@opam:0.1.0@d957c903", + "@opam/ppx_yojson_conv_lib@opam:v0.13.0@97a4cb97", + "@opam/ocamlfind@opam:1.8.1@ff07b0f9", + "@opam/ocaml-syntax-shims@opam:1.0.0@a9aa3bfa", + "@opam/menhir@opam:20200211@26571604", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/stdlib-shims@opam:0.1.0@d957c903", + "@opam/ppx_yojson_conv_lib@opam:v0.13.0@97a4cb97", + "@opam/ocamlfind@opam:1.8.1@ff07b0f9", + "@opam/ocaml-syntax-shims@opam:1.0.0@a9aa3bfa", + "@opam/menhir@opam:20200211@26571604", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/ocaml-compiler-libs@opam:v0.12.1@5c34eb0d": { @@ -822,33 +883,11 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" - ] - }, - "@opam/merlin-lsp@github:ocaml/merlin:merlin-lsp.opam#c8b0f03@d41d8cd9": { - "id": - "@opam/merlin-lsp@github:ocaml/merlin:merlin-lsp.opam#c8b0f03@d41d8cd9", - "name": "@opam/merlin-lsp", - "version": "github:ocaml/merlin:merlin-lsp.opam#c8b0f03", - "source": { - "type": "install", - "source": [ "github:ocaml/merlin:merlin-lsp.opam#c8b0f03" ] - }, - "overrides": [], - "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/ppx_deriving_yojson@opam:3.5.1@06a1c37f", - "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" - ], - "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/ppx_deriving_yojson@opam:3.5.1@06a1c37f", - "@opam/ocamlfind@opam:1.8.1@ff07b0f9" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/merlin-extend@opam:0.5@a5dd7d4b": { @@ -869,111 +908,121 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@opam/cppo@opam:1.6.6@f4f83858", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/merlin@opam:3.3.2@7a364181": { - "id": "@opam/merlin@opam:3.3.2@7a364181", - "name": "@opam/merlin", - "version": "opam:3.3.2", + "@opam/menhirSdk@opam:20200211@b2a79ec0": { + "id": "@opam/menhirSdk@opam:20200211@b2a79ec0", + "name": "@opam/menhirSdk", + "version": "opam:20200211", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/1d/1d1c71e663b1e58acf19069cebd1e8d18f7dbe513c6065347d162cdd2c2de801#sha256:1d1c71e663b1e58acf19069cebd1e8d18f7dbe513c6065347d162cdd2c2de801", - "archive:https://github.com/ocaml/merlin/releases/download/v3.3.2/merlin-v3.3.2.tbz#sha256:1d1c71e663b1e58acf19069cebd1e8d18f7dbe513c6065347d162cdd2c2de801" + "archive:https://opam.ocaml.org/cache/md5/01/01577e5f15380c35bdaa8fd818204560#md5:01577e5f15380c35bdaa8fd818204560", + "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz#md5:01577e5f15380c35bdaa8fd818204560" ], "opam": { - "name": "merlin", - "version": "3.3.2", - "path": "esy.lock/opam/merlin.3.3.2" + "name": "menhirSdk", + "version": "20200211", + "path": "esy.lock/opam/menhirSdk.20200211" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/menhir@opam:20190924@004407ff": { - "id": "@opam/menhir@opam:20190924@004407ff", - "name": "@opam/menhir", - "version": "opam:20190924", + "@opam/menhirLib@opam:20200211@93d0f001": { + "id": "@opam/menhirLib@opam:20200211@93d0f001", + "name": "@opam/menhirLib", + "version": "opam:20200211", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/67/677f1997fb73177d5a00fa1b8d61c3ef#md5:677f1997fb73177d5a00fa1b8d61c3ef", - "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20190924/archive.tar.gz#md5:677f1997fb73177d5a00fa1b8d61c3ef" + "archive:https://opam.ocaml.org/cache/md5/01/01577e5f15380c35bdaa8fd818204560#md5:01577e5f15380c35bdaa8fd818204560", + "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz#md5:01577e5f15380c35bdaa8fd818204560" ], "opam": { - "name": "menhir", - "version": "20190924", - "path": "esy.lock/opam/menhir.20190924" + "name": "menhirLib", + "version": "20200211", + "path": "esy.lock/opam/menhirLib.20200211" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/ocamlbuild@opam:0.14.0@6ac75d03", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], - "devDependencies": [ "ocaml@4.8.1000@d41d8cd9" ] + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" + ] }, - "@opam/junit@opam:2.0.1@1b4d302c": { - "id": "@opam/junit@opam:2.0.1@1b4d302c", - "name": "@opam/junit", - "version": "opam:2.0.1", + "@opam/menhir@opam:20200211@26571604": { + "id": "@opam/menhir@opam:20200211@26571604", + "name": "@opam/menhir", + "version": "opam:20200211", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/40/40224fb3d4f5e47dc5ff4605587d383b#md5:40224fb3d4f5e47dc5ff4605587d383b", - "archive:https://github.com/Khady/ocaml-junit/releases/download/2.0.1/junit-2.0.1.tbz#md5:40224fb3d4f5e47dc5ff4605587d383b" + "archive:https://opam.ocaml.org/cache/md5/01/01577e5f15380c35bdaa8fd818204560#md5:01577e5f15380c35bdaa8fd818204560", + "archive:https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz#md5:01577e5f15380c35bdaa8fd818204560" ], "opam": { - "name": "junit", - "version": "2.0.1", - "path": "esy.lock/opam/junit.2.0.1" + "name": "menhir", + "version": "20200211", + "path": "esy.lock/opam/menhir.20200211" } }, - "overrides": [], + "overrides": [ + { + "opamoverride": + "esy.lock/overrides/opam__s__menhir_opam__c__20200211_opam_override" + } + ], "dependencies": [ - "@opam/tyxml@opam:4.3.0@c1da25f1", "@opam/ptime@opam:0.8.5@0051d642", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@opam/menhirSdk@opam:20200211@b2a79ec0", + "@opam/menhirLib@opam:20200211@93d0f001", + "@opam/fix@opam:20200131@0ecd2f01", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "@opam/tyxml@opam:4.3.0@c1da25f1", "@opam/ptime@opam:0.8.5@0051d642", - "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/menhirSdk@opam:20200211@b2a79ec0", + "@opam/menhirLib@opam:20200211@93d0f001", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/jbuilder@opam:transition@20522f05": { - "id": "@opam/jbuilder@opam:transition@20522f05", - "name": "@opam/jbuilder", - "version": "opam:transition", + "@opam/junit@opam:2.0.2@0b7bd730": { + "id": "@opam/junit@opam:2.0.2@0b7bd730", + "name": "@opam/junit", + "version": "opam:2.0.2", "source": { "type": "install", - "source": [ "no-source:" ], + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/fd/fda941b653613a4a5731f9b3557364b12baa341daa13c01676c9eb8d64e96b01#sha256:fda941b653613a4a5731f9b3557364b12baa341daa13c01676c9eb8d64e96b01", + "archive:https://github.com/Khady/ocaml-junit/releases/download/2.0.2/junit-2.0.2.tbz#sha256:fda941b653613a4a5731f9b3557364b12baa341daa13c01676c9eb8d64e96b01" + ], "opam": { - "name": "jbuilder", - "version": "transition", - "path": "esy.lock/opam/jbuilder.transition" + "name": "junit", + "version": "2.0.2", + "path": "esy.lock/opam/junit.2.0.2" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", - "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/tyxml@opam:4.4.0@1dca5713", "@opam/ptime@opam:0.8.5@0051d642", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/tyxml@opam:4.4.0@1dca5713", "@opam/ptime@opam:0.8.5@0051d642", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/fpath@opam:0.7.2@45477b93": { @@ -995,17 +1044,42 @@ "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/topkg@opam:1.0.1@a42c631e", - "@opam/result@opam:1.4@dc720aef", + "@opam/result@opam:1.5@6b753c82", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", "@opam/ocamlbuild@opam:0.14.0@6ac75d03", "@opam/astring@opam:0.8.3@4e5e17d5", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", "@opam/astring@opam:0.8.3@4e5e17d5" ] }, + "@opam/fix@opam:20200131@0ecd2f01": { + "id": "@opam/fix@opam:20200131@0ecd2f01", + "name": "@opam/fix", + "version": "opam:20200131", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/md5/99/991ff031666c662eaab638d2e0f4ac1d#md5:991ff031666c662eaab638d2e0f4ac1d", + "archive:https://gitlab.inria.fr/fpottier/fix/repository/20200131/archive.tar.gz#md5:991ff031666c662eaab638d2e0f4ac1d" + ], + "opam": { + "name": "fix", + "version": "20200131", + "path": "esy.lock/opam/fix.20200131" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" + ] + }, "@opam/easy-format@opam:1.3.2@0484b3c4": { "id": "@opam/easy-format@opam:1.3.2@0484b3c4", "name": "@opam/easy-format", @@ -1024,54 +1098,81 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd" + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" ] }, - "@opam/dune-configurator@opam:1.0.0@4873acd8": { - "id": "@opam/dune-configurator@opam:1.0.0@4873acd8", + "@opam/dune-private-libs@opam:2.5.1@60c1661f": { + "id": "@opam/dune-private-libs@opam:2.5.1@60c1661f", + "name": "@opam/dune-private-libs", + "version": "opam:2.5.1", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/8f/8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b", + "archive:https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" + ], + "opam": { + "name": "dune-private-libs", + "version": "2.5.1", + "path": "esy.lock/opam/dune-private-libs.2.5.1" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658" + ] + }, + "@opam/dune-configurator@opam:2.5.1@aeb9d8d5": { + "id": "@opam/dune-configurator@opam:2.5.1@aeb9d8d5", "name": "@opam/dune-configurator", - "version": "opam:1.0.0", + "version": "opam:2.5.1", "source": { "type": "install", - "source": [ "no-source:" ], + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/8f/8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b", + "archive:https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" + ], "opam": { "name": "dune-configurator", - "version": "1.0.0", - "path": "esy.lock/opam/dune-configurator.1.0.0" + "version": "2.5.1", + "path": "esy.lock/opam/dune-configurator.2.5.1" } }, "overrides": [], "dependencies": [ - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/dune-private-libs@opam:2.5.1@60c1661f", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], - "devDependencies": [ "@opam/dune@opam:1.11.4@21d66ccd" ] + "devDependencies": [ + "@opam/dune-private-libs@opam:2.5.1@60c1661f", + "@opam/dune@opam:2.5.1@a0c1e658" + ] }, - "@opam/dune@opam:1.11.4@21d66ccd": { - "id": "@opam/dune@opam:1.11.4@21d66ccd", + "@opam/dune@opam:2.5.1@a0c1e658": { + "id": "@opam/dune@opam:2.5.1@a0c1e658", "name": "@opam/dune", - "version": "opam:1.11.4", + "version": "opam:2.5.1", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/sha256/77/77cb5f483221b266ded2b85fc84173ae0089a25134a086be922e82c131456ce6#sha256:77cb5f483221b266ded2b85fc84173ae0089a25134a086be922e82c131456ce6", - "archive:https://github.com/ocaml/dune/releases/download/1.11.4/dune-build-info-1.11.4.tbz#sha256:77cb5f483221b266ded2b85fc84173ae0089a25134a086be922e82c131456ce6" + "archive:https://opam.ocaml.org/cache/sha256/8f/8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b", + "archive:https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz#sha256:8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" ], "opam": { "name": "dune", - "version": "1.11.4", - "path": "esy.lock/opam/dune.1.11.4" + "version": "2.5.1", + "path": "esy.lock/opam/dune.2.5.1" } }, - "overrides": [ - { - "opamoverride": - "esy.lock/overrides/opam__s__dune_opam__c__1.11.4_opam_override" - } - ], + "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/base-unix@opam:base@87d0b2eb", "@opam/base-threads@opam:base@36803084", @@ -1100,12 +1201,12 @@ }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@opam/base-unix@opam:base@87d0b2eb", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:1.11.4@21d66ccd", + "ocaml@4.8.1000@d41d8cd9", "@opam/dune@opam:2.5.1@a0c1e658", "@opam/base-unix@opam:base@87d0b2eb" ] }, @@ -1167,11 +1268,11 @@ "overrides": [], "dependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/easy-format@opam:1.3.2@0484b3c4", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.1000@d41d8cd9", "@opam/easy-format@opam:1.3.2@0484b3c4", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/base-unix@opam:base@87d0b2eb": { @@ -1230,121 +1331,32 @@ "ocaml@4.8.1000@d41d8cd9", "@opam/ocamlfind@opam:1.8.1@ff07b0f9" ] }, - "@opam/base@opam:v0.12.2@d687150c": { - "id": "@opam/base@opam:v0.12.2@d687150c", + "@opam/base@opam:v0.13.1@7d937ed0": { + "id": "@opam/base@opam:v0.13.1@7d937ed0", "name": "@opam/base", - "version": "opam:v0.12.2", + "version": "opam:v0.13.1", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/71/7150e848a730369a2549d01645fb6c72#md5:7150e848a730369a2549d01645fb6c72", - "archive:https://github.com/janestreet/base/archive/v0.12.2.tar.gz#md5:7150e848a730369a2549d01645fb6c72" + "archive:https://opam.ocaml.org/cache/md5/29/296457416f9a8b75e6edfc3b1140e384#md5:296457416f9a8b75e6edfc3b1140e384", + "archive:https://github.com/janestreet/base/archive/v0.13.1.tar.gz#md5:296457416f9a8b75e6edfc3b1140e384" ], "opam": { "name": "base", - "version": "v0.12.2", - "path": "esy.lock/opam/base.v0.12.2" - } - }, - "overrides": [], - "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/sexplib0@opam:v0.12.0@e432406d", - "@opam/dune-configurator@opam:1.0.0@4873acd8", - "@opam/dune@opam:1.11.4@21d66ccd", "@esy-ocaml/substs@0.0.1@d41d8cd9" - ], - "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/sexplib0@opam:v0.12.0@e432406d", - "@opam/dune-configurator@opam:1.0.0@4873acd8", - "@opam/dune@opam:1.11.4@21d66ccd" - ] - }, - "@opam/atdgen-runtime@opam:2.0.0@60f6faab": { - "id": "@opam/atdgen-runtime@opam:2.0.0@60f6faab", - "name": "@opam/atdgen-runtime", - "version": "opam:2.0.0", - "source": { - "type": "install", - "source": [ - "archive:https://opam.ocaml.org/cache/md5/14/14e47609397c524ea0eae7c3f14f7ccf#md5:14e47609397c524ea0eae7c3f14f7ccf", - "archive:https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz#md5:14e47609397c524ea0eae7c3f14f7ccf" - ], - "opam": { - "name": "atdgen-runtime", - "version": "2.0.0", - "path": "esy.lock/opam/atdgen-runtime.2.0.0" - } - }, - "overrides": [], - "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/jbuilder@opam:transition@20522f05", - "@opam/biniou@opam:1.2.1@d7570399", - "@esy-ocaml/substs@0.0.1@d41d8cd9" - ], - "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/jbuilder@opam:transition@20522f05", - "@opam/biniou@opam:1.2.1@d7570399" - ] - }, - "@opam/atdgen@opam:2.0.0@46af0360": { - "id": "@opam/atdgen@opam:2.0.0@46af0360", - "name": "@opam/atdgen", - "version": "opam:2.0.0", - "source": { - "type": "install", - "source": [ - "archive:https://opam.ocaml.org/cache/md5/14/14e47609397c524ea0eae7c3f14f7ccf#md5:14e47609397c524ea0eae7c3f14f7ccf", - "archive:https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz#md5:14e47609397c524ea0eae7c3f14f7ccf" - ], - "opam": { - "name": "atdgen", - "version": "2.0.0", - "path": "esy.lock/opam/atdgen.2.0.0" + "version": "v0.13.1", + "path": "esy.lock/opam/base.v0.13.1" } }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/jbuilder@opam:transition@20522f05", - "@opam/biniou@opam:1.2.1@d7570399", - "@opam/atdgen-runtime@opam:2.0.0@60f6faab", - "@opam/atd@opam:2.0.0@e0ddd12f", "@esy-ocaml/substs@0.0.1@d41d8cd9" - ], - "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", - "@opam/jbuilder@opam:transition@20522f05", - "@opam/biniou@opam:1.2.1@d7570399", - "@opam/atdgen-runtime@opam:2.0.0@60f6faab", - "@opam/atd@opam:2.0.0@e0ddd12f" - ] - }, - "@opam/atd@opam:2.0.0@e0ddd12f": { - "id": "@opam/atd@opam:2.0.0@e0ddd12f", - "name": "@opam/atd", - "version": "opam:2.0.0", - "source": { - "type": "install", - "source": [ - "archive:https://opam.ocaml.org/cache/md5/14/14e47609397c524ea0eae7c3f14f7ccf#md5:14e47609397c524ea0eae7c3f14f7ccf", - "archive:https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz#md5:14e47609397c524ea0eae7c3f14f7ccf" - ], - "opam": { - "name": "atd", - "version": "2.0.0", - "path": "esy.lock/opam/atd.2.0.0" - } - }, - "overrides": [], - "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/menhir@opam:20190924@004407ff", - "@opam/jbuilder@opam:transition@20522f05", - "@opam/easy-format@opam:1.3.2@0484b3c4", - "@esy-ocaml/substs@0.0.1@d41d8cd9" + "ocaml@4.8.1000@d41d8cd9", "@opam/sexplib0@opam:v0.13.0@3f54c2be", + "@opam/dune-configurator@opam:2.5.1@aeb9d8d5", + "@opam/dune@opam:2.5.1@a0c1e658", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/jbuilder@opam:transition@20522f05", - "@opam/easy-format@opam:1.3.2@0484b3c4" + "ocaml@4.8.1000@d41d8cd9", "@opam/sexplib0@opam:v0.13.0@3f54c2be", + "@opam/dune-configurator@opam:2.5.1@aeb9d8d5", + "@opam/dune@opam:2.5.1@a0c1e658" ] }, "@opam/astring@opam:0.8.3@4e5e17d5": { @@ -1389,24 +1401,24 @@ "dependencies": [], "devDependencies": [] }, - "@esy-ocaml/reason@3.5.2@d41d8cd9": { - "id": "@esy-ocaml/reason@3.5.2@d41d8cd9", + "@esy-ocaml/reason@3.6.0@d41d8cd9": { + "id": "@esy-ocaml/reason@3.6.0@d41d8cd9", "name": "@esy-ocaml/reason", - "version": "3.5.2", + "version": "3.6.0", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@esy-ocaml/reason/-/reason-3.5.2.tgz#sha1:ac48b63fd66fbbc1d77ab6a2b7e3a1ba21a8f40b" + "archive:https://registry.npmjs.org/@esy-ocaml/reason/-/reason-3.6.0.tgz#sha1:ae98f3335e9e03ff0e01376830a14cd1246b5278" ] }, "overrides": [], "dependencies": [ - "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.4@dc720aef", + "ocaml@4.8.1000@d41d8cd9", "@opam/result@opam:1.5@6b753c82", "@opam/ocamlfind@opam:1.8.1@ff07b0f9", - "@opam/ocaml-migrate-parsetree@opam:1.5.0@3e319dbc", + "@opam/ocaml-migrate-parsetree@opam:1.7.2@bc8b618e", "@opam/merlin-extend@opam:0.5@a5dd7d4b", - "@opam/menhir@opam:20190924@004407ff", - "@opam/dune@opam:1.11.4@21d66ccd" + "@opam/menhir@opam:20200211@26571604", + "@opam/fix@opam:20200131@0ecd2f01", "@opam/dune@opam:2.5.1@a0c1e658" ], "devDependencies": [] } diff --git a/esy.lock/opam/atd.2.0.0/opam b/esy.lock/opam/atd.2.0.0/opam deleted file mode 100644 index 2808354..0000000 --- a/esy.lock/opam/atd.2.0.0/opam +++ /dev/null @@ -1,34 +0,0 @@ -opam-version: "2.0" -maintainer: "martin@mjambon.com" -authors: ["Martin Jambon"] - -homepage: "https://github.com/mjambon/atd" -bug-reports: "https://github.com/mjambon/atd/issues" -dev-repo: "git://github.com/mjambon/atd.git" - -build: [ - ["jbuilder" "subst" "-p" name] {pinned} - ["jbuilder" "build" "-p" name "-j" jobs] -] - -# Restore when https://github.com/mjambon/atd/issues/121 is resolved. -# build-test: [ -# ["jbuilder" "runtest" "-p" name] -# ] - -depends: [ - "ocaml" {>= "4.03.0"} - "jbuilder" - "menhir" {build} - "easy-format" -] -synopsis: "Parser for the ATD data format description language" -description: """ -ATD is the OCaml library providing a parser for the ATD language and -various utilities. ATD stands for Adjustable Type Definitions in -reference to its main property of supporting annotations that allow a -good fit with a variety of data formats.""" -url { - src: "https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz" - checksum: "md5=14e47609397c524ea0eae7c3f14f7ccf" -} diff --git a/esy.lock/opam/atdgen-runtime.2.0.0/opam b/esy.lock/opam/atdgen-runtime.2.0.0/opam deleted file mode 100644 index 7236d93..0000000 --- a/esy.lock/opam/atdgen-runtime.2.0.0/opam +++ /dev/null @@ -1,29 +0,0 @@ -opam-version: "2.0" -maintainer: "martin@mjambon.com" -authors: ["Martin Jambon"] - -homepage: "https://github.com/mjambon/atd" -bug-reports: "https://github.com/mjambon/atd/issues" -dev-repo: "git://github.com/mjambon/atd.git" - -build: [ - ["jbuilder" "subst" "-p" name] {pinned} - ["jbuilder" "build" "-p" name "-j" jobs] -] - -# Restore when https://github.com/mjambon/atd/issues/121 is resolved. -# build-test: [ -# ["jbuilder" "runtest" "-p" name] -# ] - -depends: [ - "ocaml" {>= "4.02.3"} - "jbuilder" - "biniou" {>= "1.0.6"} - "yojson" {>= "1.2.1"} -] -synopsis: "Runtime library for code generated by atdgen." -url { - src: "https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz" - checksum: "md5=14e47609397c524ea0eae7c3f14f7ccf" -} diff --git a/esy.lock/opam/atdgen.2.0.0/opam b/esy.lock/opam/atdgen.2.0.0/opam deleted file mode 100644 index d71d304..0000000 --- a/esy.lock/opam/atdgen.2.0.0/opam +++ /dev/null @@ -1,44 +0,0 @@ -opam-version: "2.0" -maintainer: "martin@mjambon.com" -authors: ["Martin Jambon"] - -homepage: "https://github.com/mjambon/atd" -bug-reports: "https://github.com/mjambon/atd/issues" -dev-repo: "git://github.com/mjambon/atd.git" - -build: [ - ["jbuilder" "subst" "-p" name] {pinned} - ["jbuilder" "build" "-p" name "-j" jobs] -] - -# Restore when https://github.com/mjambon/atd/issues/121 is resolved. -# build-test: [ -# ["jbuilder" "runtest" "-p" name] -# ] - -depends: [ - "ocaml" {>= "4.03.0"} - "jbuilder" - "atd" {>= "2.0.0"} - "atdgen-runtime" {>= "2.0.0"} - "biniou" {>= "1.0.6"} - "yojson" {>= "1.2.1"} -] -synopsis: - "Generates efficient JSON serializers, deserializers and validators" -description: """ -Atdgen is a command-line program that takes as input type definitions in the -ATD syntax and produces OCaml code suitable for data serialization and -deserialization. - -Two data formats are currently supported, these are biniou and JSON. -Atdgen-biniou and Atdgen-json will refer to Atdgen used in one context or the -other. - -Atdgen was designed with efficiency and durability in mind. Software authors -are encouraged to use Atdgen directly and to write tools that may reuse part of -Atdgen’s source code.""" -url { - src: "https://github.com/mjambon/atd/releases/download/2.0.0/atd-2.0.0.tbz" - checksum: "md5=14e47609397c524ea0eae7c3f14f7ccf" -} diff --git a/esy.lock/opam/base.v0.12.2/opam b/esy.lock/opam/base.v0.13.1/opam similarity index 78% rename from esy.lock/opam/base.v0.12.2/opam rename to esy.lock/opam/base.v0.13.1/opam index 861024c..e3c61b2 100644 --- a/esy.lock/opam/base.v0.12.2/opam +++ b/esy.lock/opam/base.v0.13.1/opam @@ -10,14 +10,11 @@ build: [ ["dune" "build" "-p" name "-j" jobs] ] depends: [ - "ocaml" {>= "4.04.2" & < "4.10.0"} - "sexplib0" {>= "v0.12" & < "v0.13"} - "dune" {>= "1.5.1"} + "ocaml" {>= "4.04.2"} + "sexplib0" {>= "v0.13" & < "v0.14"} + "dune" {>= "1.5.1"} "dune-configurator" ] -depopts: [ - "base-native-int63" -] synopsis: "Full standard library replacement for OCaml" description: " Full standard library replacement for OCaml @@ -34,6 +31,6 @@ provided by companion libraries such as stdio: https://github.com/janestreet/stdio " url { - src: "https://github.com/janestreet/base/archive/v0.12.2.tar.gz" - checksum: "md5=7150e848a730369a2549d01645fb6c72" + src: "https://github.com/janestreet/base/archive/v0.13.1.tar.gz" + checksum: "md5=296457416f9a8b75e6edfc3b1140e384" } diff --git a/esy.lock/opam/dune-configurator.1.0.0/opam b/esy.lock/opam/dune-configurator.1.0.0/opam deleted file mode 100644 index 6e2b712..0000000 --- a/esy.lock/opam/dune-configurator.1.0.0/opam +++ /dev/null @@ -1,9 +0,0 @@ -opam-version: "2.0" -authors: ["Jérémie Dimino"] -homepage: "https://github.com/ocaml/dune" -bug-reports: "https://github.com/ocaml/dune/issues" -maintainer: "Jérémie Dimino" -description: """ -dune.configurator library distributed with Dune 1.x -""" -depends: ["dune" {<"2.0.0"}] diff --git a/esy.lock/opam/dune-configurator.2.5.1/opam b/esy.lock/opam/dune-configurator.2.5.1/opam new file mode 100644 index 0000000..52e00de --- /dev/null +++ b/esy.lock/opam/dune-configurator.2.5.1/opam @@ -0,0 +1,43 @@ +opam-version: "2.0" +synopsis: "Helper library for gathering system configuration" +description: """ +dune-configurator is a small library that helps writing OCaml scripts that +test features available on the system, in order to generate config.h +files for instance. +Among other things, dune-configurator allows one to: +- test if a C program compiles +- query pkg-config +- import #define from OCaml header files +- generate config.h file +""" +maintainer: ["Jane Street Group, LLC "] +authors: ["Jane Street Group, LLC "] +license: "MIT" +homepage: "https://github.com/ocaml/dune" +doc: "https://dune.readthedocs.io/" +bug-reports: "https://github.com/ocaml/dune/issues" +depends: [ + "dune" {>= "2.3"} + "dune-private-libs" {= version} +] +dev-repo: "git+https://github.com/ocaml/dune.git" +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@doc" {with-doc} + ] +] +url { + src: "https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz" + checksum: [ + "sha256=8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" + "sha512=f209f12ced10c1abf8782bdb0143f4cec77795f7174d2cc75130afb1e01550b01f2f77b9e3ec4888efdad83d2f9878d179b39126f824f4e522f3ef4da34bf27e" + ] +} diff --git a/esy.lock/opam/dune-private-libs.2.5.1/opam b/esy.lock/opam/dune-private-libs.2.5.1/opam new file mode 100644 index 0000000..074ce9a --- /dev/null +++ b/esy.lock/opam/dune-private-libs.2.5.1/opam @@ -0,0 +1,42 @@ +opam-version: "2.0" +synopsis: "Private libraries of Dune" +description: """ +!!!!!!!!!!!!!!!!!!!!!! +!!!!! DO NOT USE !!!!! +!!!!!!!!!!!!!!!!!!!!!! + +This package contains code that is shared between various dune-xxx +packages. However, it is not meant for public consumption and provides +no stability guarantee. +""" +maintainer: ["Jane Street Group, LLC "] +authors: ["Jane Street Group, LLC "] +license: "MIT" +homepage: "https://github.com/ocaml/dune" +doc: "https://dune.readthedocs.io/" +bug-reports: "https://github.com/ocaml/dune/issues" +depends: [ + "dune" {>= "2.3"} + "ocaml" {>= "4.07"} +] +dev-repo: "git+https://github.com/ocaml/dune.git" +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@doc" {with-doc} + ] +] +url { + src: "https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz" + checksum: [ + "sha256=8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" + "sha512=f209f12ced10c1abf8782bdb0143f4cec77795f7174d2cc75130afb1e01550b01f2f77b9e3ec4888efdad83d2f9878d179b39126f824f4e522f3ef4da34bf27e" + ] +} diff --git a/esy.lock/opam/dune.1.11.4/opam b/esy.lock/opam/dune.2.5.1/opam similarity index 56% rename from esy.lock/opam/dune.1.11.4/opam rename to esy.lock/opam/dune.2.5.1/opam index 19e2511..dae256a 100644 --- a/esy.lock/opam/dune.1.11.4/opam +++ b/esy.lock/opam/dune.2.5.1/opam @@ -1,14 +1,14 @@ opam-version: "2.0" -synopsis: "Fast, portable and opinionated build system" +synopsis: "Fast, portable, and opinionated build system" description: """ dune is a build system that was designed to simplify the release of Jane Street packages. It reads metadata from "dune" files following a very simple s-expression syntax. -dune is fast, it has very low-overhead and support parallel builds on -all platforms. It has no system dependencies, all you need to build -dune and packages using dune is OCaml. You don't need or make or bash +dune is fast, has very low-overhead, and supports parallel builds on +all platforms. It has no system dependencies; all you need to build +dune or packages using dune is OCaml. You don't need make or bash as long as the packages themselves don't use bash explicitly. dune supports multi-package development by simply dropping multiple @@ -25,29 +25,30 @@ license: "MIT" homepage: "https://github.com/ocaml/dune" doc: "https://dune.readthedocs.io/" bug-reports: "https://github.com/ocaml/dune/issues" -depends: [ - "ocaml" {>= "4.02"} - "base-unix" - "base-threads" -] conflicts: [ - "jbuilder" {!= "transition"} + "dune-configurator" {< "2.3.0"} "odoc" {< "1.3.0"} "dune-release" {< "1.3.0"} + "jbuilder" {= "transition"} ] dev-repo: "git+https://github.com/ocaml/dune.git" build: [ # opam 2 sets OPAM_SWITCH_PREFIX, so we don't need a hardcoded path ["ocaml" "configure.ml" "--libdir" lib] {opam-version < "2"} - ["ocaml" "bootstrap.ml"] - ["./boot.exe" "--release" "--subst"] {pinned} - ["./boot.exe" "--release" "-j" jobs] + ["ocaml" "bootstrap.ml" "-j" jobs] + ["./dune.exe" "build" "-p" name "--profile" "dune-bootstrap" "-j" jobs] +] +depends: [ + # Please keep the lower bound in sync with .travis.yml, dune-project + # and min_ocaml_version in bootstrap.ml + ("ocaml" {>= "4.07"} | ("ocaml" {< "4.07~~"} & "ocamlfind-secondary")) + "base-unix" + "base-threads" ] url { - src: - "https://github.com/ocaml/dune/releases/download/1.11.4/dune-build-info-1.11.4.tbz" + src: "https://github.com/ocaml/dune/releases/download/2.5.1/dune-2.5.1.tbz" checksum: [ - "sha256=77cb5f483221b266ded2b85fc84173ae0089a25134a086be922e82c131456ce6" - "sha512=02f00fd872aa49b832fc8c1e928409f23c79ddf84a53009a58875f222cca36fbb92c905e12c539caec9cbad723f195a8aa24218382dca35a903b3f52b11f06f2" + "sha256=8f77d3a87f208e0d7cccaa1c48c4bb1bb87d62d07c3f25e9b8ba298e028ce52b" + "sha512=f209f12ced10c1abf8782bdb0143f4cec77795f7174d2cc75130afb1e01550b01f2f77b9e3ec4888efdad83d2f9878d179b39126f824f4e522f3ef4da34bf27e" ] } diff --git a/esy.lock/opam/fix.20200131/opam b/esy.lock/opam/fix.20200131/opam new file mode 100644 index 0000000..4babcba --- /dev/null +++ b/esy.lock/opam/fix.20200131/opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "francois.pottier@inria.fr" +authors: [ + "François Pottier " +] +homepage: "https://gitlab.inria.fr/fpottier/fix" +dev-repo: "git+https://gitlab.inria.fr/fpottier/fix.git" +bug-reports: "francois.pottier@inria.fr" +build: [ + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" { >= "4.03" } + "dune" { >= "1.3" } +] +synopsis: "Facilities for memoization and fixed points" +url { + src: + "https://gitlab.inria.fr/fpottier/fix/repository/20200131/archive.tar.gz" + checksum: [ + "md5=991ff031666c662eaab638d2e0f4ac1d" + "sha512=01c45a1d90b02ec0939e968b185a6a373ac6117e2287b9a26d3db9d71e9569d086cea50da60710fcab5c2ed9d3b4c72b76839c0651e436f1fb39c77dc7c04b5e" + ] +} diff --git a/esy.lock/opam/jbuilder.transition/opam b/esy.lock/opam/jbuilder.transition/opam deleted file mode 100644 index 9280c3f..0000000 --- a/esy.lock/opam/jbuilder.transition/opam +++ /dev/null @@ -1,18 +0,0 @@ -opam-version: "2.0" -maintainer: "opensource@janestreet.com" -authors: ["Jane Street Group, LLC "] -homepage: "https://github.com/ocaml/dune" -bug-reports: "https://github.com/ocaml/dune/issues" -dev-repo: "git+https://github.com/ocaml/dune.git" -license: "MIT" -depends: [ - "ocaml" - "dune" {< "2.0"} -] -post-messages: [ - "Jbuilder has been renamed and the jbuilder package is now a transition \ - package. Use the dune package instead." -] -synopsis: - "This is a transition package, jbuilder is now named dune. Use the dune" -description: "package instead." diff --git a/esy.lock/opam/junit.2.0.1/opam b/esy.lock/opam/junit.2.0.2/opam similarity index 73% rename from esy.lock/opam/junit.2.0.1/opam rename to esy.lock/opam/junit.2.0.2/opam index 7713299..874cf38 100644 --- a/esy.lock/opam/junit.2.0.1/opam +++ b/esy.lock/opam/junit.2.0.2/opam @@ -3,7 +3,7 @@ maintainer: "Louis Roché " authors: "Louis Roché " homepage: "https://github.com/Khady/ocaml-junit" bug-reports: "https://github.com/Khady/ocaml-junit/issues" -license: "LGPL-3.0-or-later with OCaml-LGPL-linking-exception" +license: "LGPLv3+ with OCaml linking exception" dev-repo: "git+https://github.com/Khady/ocaml-junit.git" doc: "https://khady.github.io/ocaml-junit/" tags: ["junit" "jenkins"] @@ -24,6 +24,9 @@ synopsis: "JUnit XML reports generation library" description: "JUnit XML reports generation library" url { src: - "https://github.com/Khady/ocaml-junit/releases/download/2.0.1/junit-2.0.1.tbz" - checksum: "md5=40224fb3d4f5e47dc5ff4605587d383b" + "https://github.com/Khady/ocaml-junit/releases/download/2.0.2/junit-2.0.2.tbz" + checksum: [ + "sha256=fda941b653613a4a5731f9b3557364b12baa341daa13c01676c9eb8d64e96b01" + "sha512=5a9fa803c4861748bb8482fc51197420bf3cc3b9540989a489c4ffb65fdd02386aaa60437eae29182209dae0903b0e537c095249e19d395a451b8e8214f15f03" + ] } diff --git a/esy.lock/opam/menhir.20190924/opam b/esy.lock/opam/menhir.20190924/opam deleted file mode 100644 index 348967a..0000000 --- a/esy.lock/opam/menhir.20190924/opam +++ /dev/null @@ -1,29 +0,0 @@ -opam-version: "2.0" -maintainer: "francois.pottier@inria.fr" -authors: [ - "François Pottier " - "Yann Régis-Gianas " -] -homepage: "http://gitlab.inria.fr/fpottier/menhir" -dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git" -bug-reports: "menhir@inria.fr" -build: [ - [make "-f" "Makefile" "PREFIX=%{prefix}%" "USE_OCAMLFIND=true" "docdir=%{doc}%/menhir" "libdir=%{lib}%/menhir" "mandir=%{man}%/man1"] -] -install: [ - [make "-f" "Makefile" "install" "PREFIX=%{prefix}%" "docdir=%{doc}%/menhir" "libdir=%{lib}%/menhir" "mandir=%{man}%/man1"] -] -depends: [ - "ocaml" {>= "4.02"} - "ocamlfind" {build} - "ocamlbuild" {build} -] -synopsis: "An LR(1) parser generator" -url { - src: - "https://gitlab.inria.fr/fpottier/menhir/repository/20190924/archive.tar.gz" - checksum: [ - "md5=677f1997fb73177d5a00fa1b8d61c3ef" - "sha512=ea8a9a6d773529cf6ac05e4c6c4532770fbb8e574c9b646efcefe90d9f24544741e3e8cfd94c8afea0447e34059a8c79c2829b46764ce3a3d6dcb3e7f75980fc" - ] -} diff --git a/esy.lock/opam/menhir.20200211/opam b/esy.lock/opam/menhir.20200211/opam new file mode 100644 index 0000000..f1f18fc --- /dev/null +++ b/esy.lock/opam/menhir.20200211/opam @@ -0,0 +1,27 @@ +opam-version: "2.0" +maintainer: "francois.pottier@inria.fr" +authors: [ + "François Pottier " + "Yann Régis-Gianas " +] +homepage: "http://gitlab.inria.fr/fpottier/menhir" +dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git" +bug-reports: "menhir@inria.fr" +build: [ + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" {>= "4.02.3"} + "dune" {>= "2.2.0"} + "menhirLib" {= version} + "menhirSdk" {= version} +] +synopsis: "An LR(1) parser generator" +url { + src: + "https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz" + checksum: [ + "md5=01577e5f15380c35bdaa8fd818204560" + "sha512=a686c4b047d5236c425afcd7f179964191268ff448b8d18510579d742a7256855049bc4fe568bb8f1b0d6cbfb758d95cd05e621e3410b75245bb799d623725d6" + ] +} diff --git a/esy.lock/opam/menhirLib.20200211/opam b/esy.lock/opam/menhirLib.20200211/opam new file mode 100644 index 0000000..a65ef44 --- /dev/null +++ b/esy.lock/opam/menhirLib.20200211/opam @@ -0,0 +1,28 @@ +opam-version: "2.0" +maintainer: "francois.pottier@inria.fr" +authors: [ + "François Pottier " + "Yann Régis-Gianas " +] +homepage: "http://gitlab.inria.fr/fpottier/menhir" +dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git" +bug-reports: "menhir@inria.fr" +build: [ + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" {>= "4.02.3"} + "dune" {>= "2.0.0"} +] +conflicts: [ + "menhir" { != version } +] +synopsis: "Runtime support library for parsers generated by Menhir" +url { + src: + "https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz" + checksum: [ + "md5=01577e5f15380c35bdaa8fd818204560" + "sha512=a686c4b047d5236c425afcd7f179964191268ff448b8d18510579d742a7256855049bc4fe568bb8f1b0d6cbfb758d95cd05e621e3410b75245bb799d623725d6" + ] +} diff --git a/esy.lock/opam/menhirSdk.20200211/opam b/esy.lock/opam/menhirSdk.20200211/opam new file mode 100644 index 0000000..d82cffe --- /dev/null +++ b/esy.lock/opam/menhirSdk.20200211/opam @@ -0,0 +1,28 @@ +opam-version: "2.0" +maintainer: "francois.pottier@inria.fr" +authors: [ + "François Pottier " + "Yann Régis-Gianas " +] +homepage: "http://gitlab.inria.fr/fpottier/menhir" +dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git" +bug-reports: "menhir@inria.fr" +build: [ + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" {>= "4.02.3"} + "dune" {>= "2.0.0"} +] +conflicts: [ + "menhir" { != version } +] +synopsis: "Compile-time library for auxiliary tools related to Menhir" +url { + src: + "https://gitlab.inria.fr/fpottier/menhir/repository/20200211/archive.tar.gz" + checksum: [ + "md5=01577e5f15380c35bdaa8fd818204560" + "sha512=a686c4b047d5236c425afcd7f179964191268ff448b8d18510579d742a7256855049bc4fe568bb8f1b0d6cbfb758d95cd05e621e3410b75245bb799d623725d6" + ] +} diff --git a/esy.lock/opam/merlin.3.3.2/opam b/esy.lock/opam/merlin.3.3.2/opam deleted file mode 100644 index 47fb8f5..0000000 --- a/esy.lock/opam/merlin.3.3.2/opam +++ /dev/null @@ -1,70 +0,0 @@ -opam-version: "2.0" -name: "merlin" -maintainer: "defree@gmail.com" -authors: "The Merlin team" -homepage: "https://github.com/ocaml/merlin" -bug-reports: "https://github.com/ocaml/merlin/issues" -dev-repo: "git+https://github.com/ocaml/merlin.git" -build: [ - ["dune" "subst"] {pinned} - ["dune" "build" "-p" name "-j" jobs] -] -depends: [ - "ocaml" {>= "4.02.1" & < "4.09"} - "dune" {>= "1.8.0"} - "ocamlfind" {>= "1.5.2"} - "yojson" - "mdx" {with-test & >= "1.3.0"} -] -synopsis: - "Editor helper, provides completion, typing and source browsing in Vim and Emacs" -description: - "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." -post-messages: [ - "merlin installed. - -Quick setup for VIM -------------------- -Append this to your .vimrc to add merlin to vim's runtime-path: - let g:opamshare = substitute(system('opam config var share'),'\\n$','','''') - execute \"set rtp+=\" . g:opamshare . \"/merlin/vim\" - -Also run the following line in vim to index the documentation: - :execute \"helptags \" . g:opamshare . \"/merlin/vim/doc\" - -Quick setup for EMACS -------------------- -Add opam emacs directory to your load-path by appending this to your .emacs: - (let ((opam-share (ignore-errors (car (process-lines \"opam\" \"config\" \"var\" \"share\"))))) - (when (and opam-share (file-directory-p opam-share)) - ;; Register Merlin - (add-to-list 'load-path (expand-file-name \"emacs/site-lisp\" opam-share)) - (autoload 'merlin-mode \"merlin\" nil t nil) - ;; Automatically start it in OCaml buffers - (add-hook 'tuareg-mode-hook 'merlin-mode t) - (add-hook 'caml-mode-hook 'merlin-mode t) - ;; Use opam switch to lookup ocamlmerlin binary - (setq merlin-command 'opam))) - -Take a look at https://github.com/ocaml/merlin for more information - -Quick setup with opam-user-setup --------------------------------- - -Opam-user-setup support Merlin. - - $ opam user-setup install - -should take care of basic setup. -See https://github.com/OCamlPro/opam-user-setup -" - {success & !user-setup:installed} -] -url { - src: - "https://github.com/ocaml/merlin/releases/download/v3.3.2/merlin-v3.3.2.tbz" - checksum: [ - "sha256=1d1c71e663b1e58acf19069cebd1e8d18f7dbe513c6065347d162cdd2c2de801" - "sha512=3ae021669808a40b4449f1cbdaca40b605ea5779a6204addd8b0ee4af9f14f528d55ca43a8dd3c7d547fb8e4cb256c09a9151d5559ef24dad83b5ab05aa146a2" - ] -} diff --git a/esy.lock/opam/ocaml-migrate-parsetree.1.5.0/opam b/esy.lock/opam/ocaml-migrate-parsetree.1.7.2/opam similarity index 79% rename from esy.lock/opam/ocaml-migrate-parsetree.1.5.0/opam rename to esy.lock/opam/ocaml-migrate-parsetree.1.7.2/opam index aa41104..604cec1 100644 --- a/esy.lock/opam/ocaml-migrate-parsetree.1.5.0/opam +++ b/esy.lock/opam/ocaml-migrate-parsetree.1.7.2/opam @@ -29,9 +29,9 @@ rewriters independent of a compiler version. """ url { src: - "https://github.com/ocaml-ppx/ocaml-migrate-parsetree/releases/download/v1.5.0/ocaml-migrate-parsetree-v1.5.0.tbz" + "https://github.com/ocaml-ppx/ocaml-migrate-parsetree/releases/download/v1.7.2/ocaml-migrate-parsetree-v1.7.2.tbz" checksum: [ - "sha256=7f56679c9561552762666de5b6b81c8e4cc2e9fd92272e2269878a2eb534e3c0" - "sha512=87fdccafae83b0437f1ccd4f3cfbc49e699bc0804596480e0df88510ba33410f31d48c7f677fe72800ed3f442a3a586d82d86aee1d12a964f79892833847b16a" + "sha256=6ae6753c3e632a63f76b031afc3eab74b209babdfdba4030060a934ce0660bd6" + "sha512=68bfbbadbb6715cf0be5a02136cb3508c5f8d3debba69f9cdf9c0668ebc09fe47eac10abcdc3eb0e5e19f33a223e193da039a3e203bec1404bd177635f1a93d7" ] } diff --git a/esy.lock/opam/ocaml-syntax-shims.1.0.0/opam b/esy.lock/opam/ocaml-syntax-shims.1.0.0/opam new file mode 100644 index 0000000..a814e1d --- /dev/null +++ b/esy.lock/opam/ocaml-syntax-shims.1.0.0/opam @@ -0,0 +1,39 @@ +opam-version: "2.0" +synopsis: "Backport new syntax to older OCaml versions" +description: """ +This packages backports new features of the language to older +compilers, such as let+. +""" +maintainer: ["jeremie@dimino.org"] +authors: ["Jérémie Dimino "] +license: "MIT" +homepage: "https://github.com/ocaml-ppx/ocaml-syntax-shims" +doc: "https://ocaml-ppx.github.io/ocaml-syntax-shims/" +bug-reports: "https://github.com/ocaml-ppx/ocaml-syntax-shims/issues" +depends: [ + "dune" {>= "2.0"} + "ocaml" {>= "4.02.3"} +] +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/ocaml-ppx/ocaml-syntax-shims.git" +url { + src: + "https://github.com/ocaml-ppx/ocaml-syntax-shims/releases/download/1.0.0/ocaml-syntax-shims-1.0.0.tbz" + checksum: [ + "sha256=89b2e193e90a0c168b6ec5ddf6fef09033681bdcb64e11913c97440a2722e8c8" + "sha512=75c4c6b0bfa1267a8a49a82ba494d08cf0823fc8350863d6d3d4971528cb09e5a2a29e2981d04c75e76ad0f49360b05a432c9efeff9a4fbc1ec6b28960399852" + ] +} diff --git a/esy.lock/opam/ocamlformat.0.12/opam b/esy.lock/opam/ocamlformat.0.14.1/opam similarity index 57% rename from esy.lock/opam/ocamlformat.0.12/opam rename to esy.lock/opam/ocamlformat.0.14.1/opam index 00df987..64c651a 100644 --- a/esy.lock/opam/ocamlformat.0.12/opam +++ b/esy.lock/opam/ocamlformat.0.14.1/opam @@ -4,32 +4,37 @@ authors: "Josh Berdine " homepage: "https://github.com/ocaml-ppx/ocamlformat" bug-reports: "https://github.com/ocaml-ppx/ocamlformat/issues" dev-repo: "git+https://github.com/ocaml-ppx/ocamlformat.git" -url { - src: - "https://github.com/ocaml-ppx/ocamlformat/releases/download/0.12/ocamlformat-0.12.tbz" - checksum: [ - "sha256=f2b64ff7f5cb9b4e19c6fc4e3f0fbd1747ef09d24848238540e2c27652e928fe" - "sha512=1785ec8e7fe5d7f9f4bdd056be612e8ee170dcf4886bea0dde6f58602fa1729579d352e3a15df3229d124dac467b91f32ef900ff30e19a53c42feb1904c8a352" - ] -} license: "MIT" build: [ - ["ocaml" "tools/gen_version.mlt" "src/Version.ml" version] {pinned} + ["ocaml" "tools/gen_version.mlt" "lib/Version.ml" version] {pinned} ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] depends: [ "ocaml" {>= "4.06"} - "base" {>= "v0.11.0" & < "v0.13"} + "alcotest" {with-test} + "base" {>= "v0.11.0"} "base-unix" "cmdliner" - "dune" {>= "1.11.1"} + "dune" {>= "2.2.0"} + "fix" "fpath" - "ocaml-migrate-parsetree" {>= "1.3.1"} + "menhir" + "ocaml-migrate-parsetree" {>= "1.5.0"} + "ocp-indent" {with-test} "odoc" {>= "1.4.2"} "re" - "stdio" {< "v0.13"} + "stdio" "uuseg" {>= "10.0.0"} "uutf" {>= "1.0.1"} ] synopsis: "Auto-formatter for OCaml code" description: "OCamlFormat is a tool to automatically format OCaml code in a uniform style." +url { + src: + "https://github.com/ocaml-ppx/ocamlformat/releases/download/0.14.1/ocamlformat-0.14.1.tbz" + checksum: [ + "sha256=4a7d4575c202bd0413b2864be60000854feade9190f5530222679815bb21960f" + "sha512=95dd81fd05716d422c5b8873d0ef6665d2dcabc3e43a9cf4c8af5c4e060445d40af3910a558f5aceee63db7132296b201f241d02d920669e8be1e6a81b7a7baa" + ] +} diff --git a/esy.lock/opam/odoc.1.4.2/opam b/esy.lock/opam/odoc.1.5.0/opam similarity index 50% rename from esy.lock/opam/odoc.1.4.2/opam rename to esy.lock/opam/odoc.1.5.0/opam index d34a983..99f9336 100644 --- a/esy.lock/opam/odoc.1.4.2/opam +++ b/esy.lock/opam/odoc.1.5.0/opam @@ -1,8 +1,7 @@ opam-version: "2.0" -version: "1.4.2" homepage: "http://github.com/ocaml/odoc" -doc: "https://github.com/ocaml/odoc#readme" +doc: "https://ocaml.github.io/odoc/" bug-reports: "https://github.com/ocaml/odoc/issues" license: "ISC" @@ -10,26 +9,32 @@ authors: [ "Thomas Refis " "David Sheets " "Leo White " + "Anton Bachin " + "Jon Ludlam " ] maintainer: "Anton Bachin " dev-repo: "git+https://github.com/ocaml/odoc.git" synopsis: "OCaml documentation generator" +description: """ +Odoc is a documentation generator for OCaml. It reads doc comments, +delimited with `(** ... *)`, and outputs HTML. +""" depends: [ - "astring" {build} - "cmdliner" {build & >= "1.0.0"} + "astring" + "cmdliner" "cppo" {build} "dune" - "fpath" {build} + "fpath" "ocaml" {>= "4.02.0"} - "result" {build} - "tyxml" {build & >= "4.3.0"} + "result" + "tyxml" {>= "4.3.0"} "alcotest" {dev & >= "0.8.3"} "markup" {dev & >= "0.8.0"} "ocamlfind" {dev} - "sexplib" {dev & >= "113.33.00" & < "v0.13"} + "sexplib" {dev & >= "113.33.00"} "bisect_ppx" {with-test & >= "1.3.0"} ] @@ -38,8 +43,10 @@ build: [ ["dune" "subst"] {pinned} ["dune" "build" "-p" name "-j" jobs] ] - url { - src: "https://github.com/ocaml/odoc/archive/1.4.2.tar.gz" - checksum: "md5=d75ce63539040cd199d22203d46fc5f3" + src: "https://github.com/ocaml/odoc/releases/download/1.5.0/odoc-1.5.0.tbz" + checksum: [ + "sha256=857759be968070bfda208add3ae2c2bc87826ca2bfc39cebab1cc1e13db7a140" + "sha512=9573230f6ebd7f95d44a5e34f6de68f6b1b530cc7987402f84532e339498dde702082517066c4db428a334510af625db8055ecd03d91b57dd599fd5b3ac53f49" + ] } diff --git a/esy.lock/opam/ppx_deriving.4.4/opam b/esy.lock/opam/ppx_deriving.4.4.1/opam similarity index 83% rename from esy.lock/opam/ppx_deriving.4.4/opam rename to esy.lock/opam/ppx_deriving.4.4.1/opam index 4967fd9..1fd0d53 100644 --- a/esy.lock/opam/ppx_deriving.4.4/opam +++ b/esy.lock/opam/ppx_deriving.4.4.1/opam @@ -22,7 +22,7 @@ depends: [ "ppx_tools" {>= "4.02.3"} "result" "ounit" {with-test} - "ocaml" {>= "4.02" & < "4.10.0"} + "ocaml" {>= "4.02.2" & < "4.11.0"} ] synopsis: "Type-driven code generation for OCaml >=4.02.2" description: """ @@ -31,5 +31,6 @@ code based on type definitions, and a set of useful plugins for common tasks. """ url { - src: "https://github.com/ocaml-ppx/ppx_deriving/archive/v4.4.tar.gz" - checksum: "sha256=c2d85af4cb65a1f163f624590fb0395a164bbfd0d05082092526b669e66bcc34"} + src: "https://github.com/ocaml-ppx/ppx_deriving/archive/v4.4.1.tar.gz" + checksum: "sha256=27bc57774724fc4f48775f2011375a5ee1439570204abbf6607761c472757e2f" +} diff --git a/esy.lock/opam/ppx_deriving_yojson.3.5.1/opam b/esy.lock/opam/ppx_deriving_yojson.3.5.1/opam deleted file mode 100644 index a4a4a22..0000000 --- a/esy.lock/opam/ppx_deriving_yojson.3.5.1/opam +++ /dev/null @@ -1,35 +0,0 @@ -opam-version: "2.0" -maintainer: "whitequark " -authors: [ "whitequark " ] -license: "MIT" -homepage: "https://github.com/whitequark/ppx_deriving_yojson" -bug-reports: "https://github.com/whitequark/ppx_deriving_yojson/issues" -dev-repo: "git://github.com/whitequark/ppx_deriving_yojson.git" -tags: [ "syntax" "json" ] -build: [ - ["dune" "subst"] {pinned} - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name] {with-test} -] -depends: [ - "ocaml" {>= "4.04.0" & < "4.10.0"} - "yojson" {>= "1.6.0" & < "2.0.0"} - "result" - "ppx_deriving" {>= "4.0" & < "5.0"} - "ppx_tools" {build} - "ppxfind" {build} - "dune" {>= "1.2"} - "cppo" {build} - "ounit" {with-test & >= "2.0.0"} -] -conflicts: [ - "ppx_deriving" {= "4.2"} -] -synopsis: "JSON codec generator for OCaml" -description: """ -ppx_deriving_yojson is a ppx_deriving plugin that provides -a JSON codec generator.""" -url { - src: "https://github.com/ocaml-ppx/ppx_deriving_yojson/archive/v3.5.1.tar.gz" - checksum: "sha256=aefe9c673f2f0ee2beb9edcca5a4e332a9fe9266c81bc554b8df5cd375568994" -} diff --git a/esy.lock/opam/ppx_tools.5.3+4.08.0/opam b/esy.lock/opam/ppx_tools.5.3+4.08.0/opam deleted file mode 100644 index 253a117..0000000 --- a/esy.lock/opam/ppx_tools.5.3+4.08.0/opam +++ /dev/null @@ -1,19 +0,0 @@ -opam-version: "2.0" -synopsis: "Tools for authors of ppx rewriters and other syntactic tools" -maintainer: "alain.frisch@lexifi.com" -authors: [ "Alain Frisch " ] -license: "MIT" -homepage: "https://github.com/ocaml-ppx/ppx_tools" -bug-reports: "https://github.com/ocaml-ppx/ppx_tools/issues" -dev-repo: "git://github.com/ocaml-ppx/ppx_tools.git" -tags: [ "syntax" ] -build: [[make "all"]] -install: [[make "install"]] -depends: [ - "ocaml" {>= "4.08.0"} - "ocamlfind" {build & >= "1.5.0"} -] -url { - src: "https://github.com/ocaml-ppx/ppx_tools/archive/5.3+4.08.0.tar.gz" - checksum: "md5=702b11138c095662c175aa4dcce5c921" -} diff --git a/esy.lock/opam/ppx_tools.6.0+4.08.0/opam b/esy.lock/opam/ppx_tools.6.0+4.08.0/opam new file mode 100644 index 0000000..0f2f696 --- /dev/null +++ b/esy.lock/opam/ppx_tools.6.0+4.08.0/opam @@ -0,0 +1,21 @@ +opam-version: "2.0" +synopsis: "Tools for authors of ppx rewriters and other syntactic tools" +maintainer: "alain.frisch@lexifi.com" +authors: "Alain Frisch " +license: "MIT" +tags: [ "syntax" ] +homepage: "https://github.com/ocaml-ppx/ppx_tools" +bug-reports: "https://github.com/ocaml-ppx/ppx_tools/issues" +dev-repo: "git://github.com/ocaml-ppx/ppx_tools.git" +build: ["dune" "build" "-p" name "-j" jobs] +depends: [ + "ocaml" {>= "4.08.0" & < "4.10"} + "dune" {>= "1.6"} +] +url { + src: "https://github.com/ocaml-ppx/ppx_tools/archive/6.0+4.08.0.tar.gz" + checksum: [ + "md5=801e82103fee7ce1e4a59ab670601952" + "sha512=b576398a0dfad76ea9874cc18550bb44078a7e8f8dc0c169a0441f75f3881e458c42316c96d816c6e81d5ef219fac3aa539471f006b46088c9b943ed8af8b947" + ] +} diff --git a/esy.lock/opam/ppx_yojson_conv_lib.v0.13.0/opam b/esy.lock/opam/ppx_yojson_conv_lib.v0.13.0/opam new file mode 100644 index 0000000..9d7e73e --- /dev/null +++ b/esy.lock/opam/ppx_yojson_conv_lib.v0.13.0/opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "opensource@janestreet.com" +authors: ["Jane Street Group, LLC "] +homepage: "https://github.com/janestreet/ppx_yojson_conv_lib" +bug-reports: "https://github.com/janestreet/ppx_yojson_conv_lib/issues" +dev-repo: "git+https://github.com/janestreet/ppx_yojson_conv_lib.git" +doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_yojson_conv_lib/index.html" +license: "MIT" +build: [ + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" {>= "4.02.3"} + "dune" {>= "1.5.1"} + "yojson" {>= "1.7.0"} +] +synopsis: "Runtime lib for ppx_yojson_conv" +description: " +Part of the Jane Street's PPX rewriters collection. +" +url { + src: "https://ocaml.janestreet.com/ocaml-core/v0.13/files/ppx_yojson_conv_lib-v0.13.0.tar.gz" + checksum: "md5=790fade9ecff5767dd48cd49c9bba2f3" +} diff --git a/esy.lock/opam/ppxfind.1.3/opam b/esy.lock/opam/ppxfind.1.3/opam deleted file mode 100644 index 6dddcbe..0000000 --- a/esy.lock/opam/ppxfind.1.3/opam +++ /dev/null @@ -1,31 +0,0 @@ -opam-version: "2.0" -maintainer: "jeremie@dimino.org" -authors: ["Jérémie Dimino"] -license: "BSD-3-Clause" -homepage: "https://github.com/diml/ppxfind" -bug-reports: "https://github.com/diml/ppxfind/issues" -dev-repo: "git+https://github.com/diml/ppxfind.git" -doc: "https://diml.github.io/ppxfind/" -build: [ - ["dune" "build" "-p" name "-j" jobs] -] -depends: [ - "dune" {>= "1.0"} - "ocaml-migrate-parsetree" - "ocamlfind" - "ocaml" {>= "4.02.3"} -] -conflicts: [ "dune" {= "1.2.0" | = "1.2.1"} ] -synopsis: "Tool combining ocamlfind and ppx" -description: """ -Ppxfind is a small command line tool that among other things allows -to use old style ppx rewriters with jbuilder. -""" -url { - src: - "https://github.com/diml/ppxfind/releases/download/1.3/ppxfind-1.3.tbz" - checksum: [ - "sha256=d49db026d0e74212c4b475b4e628aa57508c7452a0682d8c96e80c130ab892e4" - "sha512=dd81bf5b3413f99a3c39f25e5e747f8d57d3bacac6a1fda92478af317e2d543294b4937982c94cf010978fcd71b1cfbfce1edbaa0c3d03973079296fda89689f" - ] -} diff --git a/esy.lock/opam/ppxfind.1.4/opam b/esy.lock/opam/ppxfind.1.4/opam new file mode 100644 index 0000000..29ed9c6 --- /dev/null +++ b/esy.lock/opam/ppxfind.1.4/opam @@ -0,0 +1,41 @@ +opam-version: "2.0" +synopsis: "Tool combining ocamlfind and ppx" +description: """ +Ppxfind is a small command line tool that among other things allows +to use old style ppx rewriters with jbuilder. +""" +maintainer: ["Jérémie Dimino "] +authors: ["Jérémie Dimino "] +license: "BSD3" +homepage: "https://github.com/diml/ppxfind" +doc: "https://diml.github.io/ppxfind/" +bug-reports: "https://github.com/diml/ppxfind/issues" +depends: [ + "dune" {>= "2.0"} + "ocaml-migrate-parsetree" {>= "1.6.0"} + "ocamlfind" + "ocaml" {>= "4.02.3"} +] +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/diml/ppxfind.git" +url { + src: + "https://github.com/diml/ppxfind/releases/download/1.4/ppxfind-1.4.tbz" + checksum: [ + "sha256=98291c69f04f7f7b7cdad1b5d786c70fc595559d4663cc04cb711ac132db4971" + "sha512=f80b0ee09fb536aa9f154da80d06a1b68ba3b10605fb7338bd6449beb5c8d00e983bf66b4a63e12659ae1410fea56d0a2c4cfd43584616438504628035bcb981" + ] +} diff --git a/esy.lock/opam/ppxlib.0.8.1/opam b/esy.lock/opam/ppxlib.0.13.0/opam similarity index 80% rename from esy.lock/opam/ppxlib.0.8.1/opam rename to esy.lock/opam/ppxlib.0.13.0/opam index a88ce11..f5e18b3 100644 --- a/esy.lock/opam/ppxlib.0.8.1/opam +++ b/esy.lock/opam/ppxlib.0.13.0/opam @@ -22,6 +22,7 @@ depends: [ "ppx_derivers" {>= "1.0"} "stdio" {>= "v0.11.0"} "ocamlfind" {with-test} + "cinaps" {with-test & >= "v0.12.1"} ] synopsis: "Base library and tools for ppx rewriters" description: """ @@ -37,9 +38,9 @@ A comprehensive toolbox for ppx development. It features: """ url { src: - "https://github.com/ocaml-ppx/ppxlib/releases/download/0.8.1/ppxlib-0.8.1.tbz" + "https://github.com/ocaml-ppx/ppxlib/releases/download/0.13.0/ppxlib-0.13.0.tbz" checksum: [ - "sha256=a5cb79ee83bba80304b65bc47f2985382bef89668b1b46f9ffb3734c2f2f7521" - "sha512=74bf4a0811f4fa73969149efc7f98620bf1c1ef7322edb8de82e02e25b61e005945887ea865b462bfb638d7d0e574706da190ca9416643f4464a89262ae7ae12" + "sha256=81e1f3d308500e0e7f6108d5b0dda2b879640a5c21ef3dc4a9bd90381cee39d9" + "sha512=c94bab35affdbdd2562de7ad30eb97282568c2c7fe48229fab5d12d1fc73312a9ee398758d598d969318cc01e8f88df9958e91820785e39d8faf3dbd7bc2e606" ] } diff --git a/esy.lock/opam/result.1.4/opam b/esy.lock/opam/result.1.5/opam similarity index 83% rename from esy.lock/opam/result.1.4/opam rename to esy.lock/opam/result.1.5/opam index b44aeea..671af04 100644 --- a/esy.lock/opam/result.1.4/opam +++ b/esy.lock/opam/result.1.5/opam @@ -17,6 +17,6 @@ while staying compatible with older version of OCaml should use the Result module defined in this library.""" url { src: - "https://github.com/janestreet/result/archive/1.4.tar.gz" - checksum: "md5=d3162dbc501a2af65c8c71e0866541da" + "https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz" + checksum: "md5=1b82dec78849680b49ae9a8a365b831b" } diff --git a/esy.lock/opam/sexplib0.v0.12.0/opam b/esy.lock/opam/sexplib0.v0.13.0/opam similarity index 85% rename from esy.lock/opam/sexplib0.v0.12.0/opam rename to esy.lock/opam/sexplib0.v0.13.0/opam index 9b45864..27626b3 100644 --- a/esy.lock/opam/sexplib0.v0.12.0/opam +++ b/esy.lock/opam/sexplib0.v0.13.0/opam @@ -21,6 +21,6 @@ OCaml's standard library that was developed by Jane Street, the largest industrial user of OCaml. " url { - src: "https://ocaml.janestreet.com/ocaml-core/v0.12/files/sexplib0-v0.12.0.tar.gz" - checksum: "md5=2486a25d3a94da9a94acc018b5f09061" + src: "https://ocaml.janestreet.com/ocaml-core/v0.13/files/sexplib0-v0.13.0.tar.gz" + checksum: "md5=f8a715dffda5599cfae0cb4031d57abe" } diff --git a/esy.lock/opam/stdio.v0.12.0/opam b/esy.lock/opam/stdio.v0.13.0/opam similarity index 81% rename from esy.lock/opam/stdio.v0.12.0/opam rename to esy.lock/opam/stdio.v0.13.0/opam index 477c745..42d6f14 100644 --- a/esy.lock/opam/stdio.v0.12.0/opam +++ b/esy.lock/opam/stdio.v0.13.0/opam @@ -11,7 +11,7 @@ build: [ ] depends: [ "ocaml" {>= "4.04.2"} - "base" {>= "v0.12" & < "v0.13"} + "base" {>= "v0.13" & < "v0.14"} "dune" {>= "1.5.1"} ] synopsis: "Standard IO library for OCaml" @@ -22,6 +22,6 @@ It re-exports the input/output functions of the OCaml standard libraries using a more consistent API. " url { - src: "https://ocaml.janestreet.com/ocaml-core/v0.12/files/stdio-v0.12.0.tar.gz" - checksum: "md5=b261ff2d5667fde960c95e50cff668da" + src: "https://ocaml.janestreet.com/ocaml-core/v0.13/files/stdio-v0.13.0.tar.gz" + checksum: "md5=48ef28512ddd51ff9885649dd1fab91d" } diff --git a/esy.lock/opam/stdlib-shims.0.1.0/opam b/esy.lock/opam/stdlib-shims.0.1.0/opam new file mode 100644 index 0000000..5839c43 --- /dev/null +++ b/esy.lock/opam/stdlib-shims.0.1.0/opam @@ -0,0 +1,27 @@ +opam-version: "2.0" +maintainer: "The stdlib-shims programmers" +authors: "The stdlib-shims programmers" +homepage: "https://github.com/ocaml/stdlib-shims" +doc: "https://ocaml.github.io/stdlib-shims/" +dev-repo: "git+https://github.com/ocaml/stdlib-shims.git" +bug-reports: "https://github.com/ocaml/stdlib-shims/issues" +tags: ["stdlib" "compatibility" "org:ocaml"] +license: ["typeof OCaml system"] +depends: [ + "dune" + "ocaml" {>= "4.02.3"} +] +build: [ "dune" "build" "-p" name "-j" jobs ] +synopsis: "Backport some of the new stdlib features to older compiler" +description: """ +Backport some of the new stdlib features to older compiler, +such as the Stdlib module. + +This allows projects that require compatibility with older compiler to +use these new features in their code. +""" +url { + src: + "https://github.com/ocaml/stdlib-shims/releases/download/0.1.0/stdlib-shims-0.1.0.tbz" + checksum: "md5=12b5704eed70c6bff5ac39a16db1425d" +} diff --git a/esy.lock/opam/tyxml.4.3.0/opam b/esy.lock/opam/tyxml.4.4.0/opam similarity index 76% rename from esy.lock/opam/tyxml.4.3.0/opam rename to esy.lock/opam/tyxml.4.4.0/opam index 93872f8..51532b5 100644 --- a/esy.lock/opam/tyxml.4.3.0/opam +++ b/esy.lock/opam/tyxml.4.4.0/opam @@ -4,7 +4,7 @@ homepage: "https://github.com/ocsigen/tyxml/" bug-reports: "https://github.com/ocsigen/tyxml/issues" doc: "https://ocsigen.org/tyxml/manual/" dev-repo: "git+https://github.com/ocsigen/tyxml.git" -license: "LGPL-2.1-only with OCaml-LGPL-linking-exception" +license: "LGPL-2.1 with OCaml linking exception" build: [ ["dune" "subst"] {pinned} @@ -14,12 +14,11 @@ build: [ depends: [ "ocaml" {>= "4.02"} - "re" {>= "1.5.0"} - ("ocaml" {>= "4.07"} | "re" {>= "1.8.0"}) "dune" "alcotest" {with-test} "seq" "uutf" {>= "1.0.0"} + "re" {>= "1.5.0"} ] synopsis:"TyXML is a library for building correct HTML and SVG documents" @@ -40,6 +39,9 @@ let to_ocaml = Html.(a ~a:[a_href "ocaml.org"] [txt "OCaml!"]) authors: "The ocsigen team" url { src: - "https://github.com/ocsigen/tyxml/releases/download/4.3.0/tyxml-4.3.0.tbz" - checksum: "md5=fd834a567f813bf447cab5f4c3a723e2" + "https://github.com/ocsigen/tyxml/releases/download/4.4.0/tyxml-4.4.0.tbz" + checksum: [ + "sha256=516394dd4a5c31726997c51d66aa31cacb91e3c46d4e16c7699130e204042530" + "sha512=d5f2187f8410524cec7a14b28e8950837070eb0b6571b015dd06076c2841eb7ccaffa86d5d2307eaf1950ee62f9fb926477dac01c870d9c1a2f525853cb44d0c" + ] } diff --git a/esy.lock/opam/uucp.12.0.0/opam b/esy.lock/opam/uucp.13.0.0/opam similarity index 83% rename from esy.lock/opam/uucp.12.0.0/opam rename to esy.lock/opam/uucp.13.0.0/opam index 18bf0a8..525d082 100644 --- a/esy.lock/opam/uucp.12.0.0/opam +++ b/esy.lock/opam/uucp.13.0.0/opam @@ -1,9 +1,6 @@ opam-version: "2.0" maintainer: "Daniel Bünzli " -authors: [ - "Daniel Bünzli " - "David Kaloper Meršinjak " -] +authors: [ "The uucp programmers" ] homepage: "https://erratique.ch/software/uucp" doc: "https://erratique.ch/software/uucp/doc/Uucp" dev-repo: "git+https://erratique.ch/repos/uucp.git" @@ -11,11 +8,10 @@ bug-reports: "https://github.com/dbuenzli/uucp/issues" tags: [ "unicode" "text" "character" "org:erratique" ] license: "ISC" depends: [ - "ocaml" {>= "4.01.0"} + "ocaml" {>= "4.03.0"} "ocamlfind" {build} "ocamlbuild" {build} "topkg" {build} - "uchar" "uucd" {with-test} # dev really "uunf" {with-test} "uutf" {with-test} @@ -30,6 +26,7 @@ build: [[ "--with-uunf" "%{uunf:installed}%" "--with-cmdliner" "%{cmdliner:installed}%" ]] + synopsis: """Unicode character properties for OCaml""" description: """\ @@ -42,6 +39,6 @@ dependencies. It is distributed under the ISC license. [1]: http://www.unicode.org/reports/tr44/ """ url { -archive: "https://erratique.ch/software/uucp/releases/uucp-12.0.0.tbz" -checksum: "cf210ed43375b7f882c0540874e2cb81" +archive: "https://erratique.ch/software/uucp/releases/uucp-13.0.0.tbz" +checksum: "07e706249ddb2d02f0fa298804d3c739" } diff --git a/esy.lock/opam/uuseg.12.0.0/opam b/esy.lock/opam/uuseg.13.0.0/opam similarity index 85% rename from esy.lock/opam/uuseg.12.0.0/opam rename to esy.lock/opam/uuseg.13.0.0/opam index 57dbdc6..3cef8bc 100644 --- a/esy.lock/opam/uuseg.12.0.0/opam +++ b/esy.lock/opam/uuseg.13.0.0/opam @@ -1,18 +1,17 @@ opam-version: "2.0" maintainer: "Daniel Bünzli " -authors: ["Daniel Bünzli "] +authors: ["The uuseg programmers"] homepage: "https://erratique.ch/software/uuseg" doc: "https://erratique.ch/software/uuseg" dev-repo: "git+https://erratique.ch/repos/uuseg.git" bug-reports: "https://github.com/dbuenzli/uuseg/issues" tags: [ "segmentation" "text" "unicode" "org:erratique" ] license: "ISC" -depends: [ "ocaml" {>= "4.01.0"} +depends: [ "ocaml" {>= "4.03.0"} "ocamlfind" {build} "ocamlbuild" {build} "topkg" {build} - "uchar" - "uucp" {>= "12.0.0" & < "13.0.0"} ] + "uucp" {>= "13.0.0" & < "14.0.0"} ] depopts: [ "uutf" "cmdliner" "uutf" {with-test} @@ -45,6 +44,6 @@ OCaml UTF-X encoded strings. It is distributed under the ISC license. [2]: http://www.unicode.org/reports/tr14/ """ url { -archive: "https://erratique.ch/software/uuseg/releases/uuseg-12.0.0.tbz" -checksum: "1d4487ddf5154e3477e55021b978d58a" +archive: "https://erratique.ch/software/uuseg/releases/uuseg-13.0.0.tbz" +checksum: "a07a97fff61da604614ea8da0547ef6a" } diff --git a/esy.lock/overrides/opam__s__dune_opam__c__1.11.4_opam_override/package.json b/esy.lock/overrides/opam__s__dune_opam__c__1.11.4_opam_override/package.json deleted file mode 100644 index 064c7e3..0000000 --- a/esy.lock/overrides/opam__s__dune_opam__c__1.11.4_opam_override/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "build": [ - [ - "ocaml", - "bootstrap.ml" - ], - [ - "./boot.exe", - "--release", - "-j", - "4" - ] - ] -} diff --git a/esy.lock/overrides/opam__s__menhir_opam__c__20200211_opam_override/package.json b/esy.lock/overrides/opam__s__menhir_opam__c__20200211_opam_override/package.json new file mode 100644 index 0000000..6882a38 --- /dev/null +++ b/esy.lock/overrides/opam__s__menhir_opam__c__20200211_opam_override/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@opam/fix": "*" + } +} diff --git a/jsx/brisk_ppx.ml b/jsx/brisk_ppx.ml index 895a9d3..c8741d1 100644 --- a/jsx/brisk_ppx.ml +++ b/jsx/brisk_ppx.ml @@ -35,7 +35,14 @@ module JSX_ppx = struct let args = props_filter_children props in ATH.Exp.apply ~loc ~attrs (component_ident ~loc) args - let is_jsx ({ AT.txt }, _) = String.equal txt "JSX" + let is_jsx = + let open Ppxlib.Ast_pattern in + let jsx_attr = attribute ~name:(string "JSX") ~payload:__ in + fun attr -> + parse jsx_attr Ppxlib.Location.none + ~on_error:(fun _ -> false) + attr + (fun _ -> true) let filter_jsx = List.filter is_jsx @@ -50,8 +57,9 @@ module JSX_ppx = struct | Ldot _ as ldot -> ldot let expr expr = - match expr.P.pexp_desc with - | P.Pexp_apply (fn, args) when exists_jsx expr.pexp_attributes -> + let open P in + match expr with + | { pexp_desc = P.Pexp_apply (fn, args) } when exists_jsx expr.pexp_attributes -> let attributes = filter_jsx expr.pexp_attributes in let args = List.map (fun (label, arg) -> (label, arg)) args in let loc = expr.P.pexp_loc in @@ -66,6 +74,9 @@ module JSX_ppx = struct [%expr let [%p component_ident_pattern ~loc] = [%e fn] in [%e rewrite_apply ~attributes ~loc:expr.P.pexp_loc args]]) + | [%expr [%e? h] :: [%e? t]] when exists_jsx expr.pexp_attributes -> + let loc = expr.pexp_loc in + [%expr Brisk_reconciler.Expert.jsx_list ([%e h] :: [%e t])] | _ -> expr end @@ -79,7 +90,7 @@ module Declaration_ppx = struct | `Component -> "component" | `Native -> "nativeComponent" - let transform_component_expr ~useDynamicKey ~attribute ~component_name expr = + let transform_component_expr ~attribute ~component_name expr = let rec map_component_expression ({ P.pexp_loc = loc } as expr) = match_ func_pattern loc expr ~with_:(fun lbl opt_arg pat child_expression -> @@ -95,7 +106,7 @@ module Declaration_ppx = struct let loc = child_expression.pexp_loc in make_fun_with_expr ~expr: - [%expr [%e component_ident ~loc] ~key [%e child_expression]] + [%expr [%e component_ident ~loc] [%e child_expression]] | _ -> Location.raise_errorf ~loc "A labelled argument or () was expected") @@ -108,24 +119,14 @@ module Declaration_ppx = struct | `Component -> [%expr Brisk_reconciler.Expert.component] in [%expr - let [%p component_ident_pattern ~loc] = - [%e create_component_expr] - ~useDynamicKey:[%e Ast_builder.(ebool ~loc useDynamicKey)] - [%e component_name] - in - fun ?(key = Brisk_reconciler.Key.none) -> - [%e map_component_expression expr]] + let [%p component_ident_pattern ~loc] = [%e create_component_expr] [%e component_name] in + [%e map_component_expression expr]] let declare_attribute ctx typ = let open Ppxlib.Attribute in declare (attribute_name typ) ctx - Ppxlib.Ast_pattern.( - alt_option (single_expr_payload (pexp_ident (lident __'))) (pstr nil)) - (function - | Some { txt = "useDynamicKey" } -> true - | Some { loc } -> - Location.raise_errorf ~loc "A labelled argument or () was expected" - | None -> false) + Ppxlib.Ast_pattern.(pstr nil) + (fun () -> ()) let expr_attribute_component = declare_attribute Ppxlib.Attribute.Context.expression `Component @@ -141,16 +142,16 @@ module Declaration_ppx = struct let consume_attr attr = Ppxlib.Attribute.consume (expr_attribute attr) unmatched_expr in - let transform ~useDynamicKey attribute expr = + let transform attribute expr = let loc = expr.P.pexp_loc in - transform_component_expr ~useDynamicKey ~attribute + transform_component_expr ~attribute ~component_name:[%expr __LOC__] expr in match consume_attr `Component with - | Some (expr, useDynamicKey) -> transform ~useDynamicKey `Component expr + | Some (expr, _) -> transform `Component expr | None -> ( match consume_attr `Native with - | Some (expr, useDynamicKey) -> transform ~useDynamicKey `Native expr + | Some (expr, _) -> transform `Native expr | None -> unmatched_expr ) let value_binding_attribute_component = @@ -169,7 +170,7 @@ module Declaration_ppx = struct (value_binding_attribute attr) unmatched_value_binding in - let transform ~useDynamicKey attribute value_binding = + let transform attribute value_binding = let value_binding_loc = value_binding.P.pvb_loc in Ppxlib.Ast_pattern.(parse (value_binding ~pat:(ppat_var __) ~expr:__)) value_binding_loc value_binding (fun var_pat expr -> @@ -178,7 +179,7 @@ module Declaration_ppx = struct in let component_pat = value_binding.pvb_pat in let transformed_expr = - transform_component_expr ~useDynamicKey ~attribute ~component_name + transform_component_expr ~attribute ~component_name expr in Ast_builder.( @@ -186,12 +187,12 @@ module Declaration_ppx = struct ~expr:transformed_expr)) in match consume_attr `Component with - | Some (value_binding, useDynamicKey) -> - transform ~useDynamicKey `Component value_binding + | Some (value_binding, _) -> + transform `Component value_binding | None -> ( match consume_attr `Native with - | Some (value_binding, useDynamicKey) -> - transform ~useDynamicKey `Native value_binding + | Some (value_binding, _) -> + transform `Native value_binding | None -> unmatched_value_binding ) let register attribute = @@ -207,7 +208,7 @@ module Declaration_ppx = struct ATH.Exp.constant ~loc (ATH.Const.string (path ^ "." ^ pat)) in let transformed_expression = - transform_component_expr ~useDynamicKey:false ~attribute + transform_component_expr ~attribute ~component_name expr in let pat = ATH.Pat.var ~loc (Ast_builder.Default.Located.mk ~loc pat) in diff --git a/lib/Brisk_reconciler.re b/lib/Brisk_reconciler.re index 46ef97c..7a882f2 100644 --- a/lib/Brisk_reconciler.re +++ b/lib/Brisk_reconciler.re @@ -1 +1,162 @@ -include Brisk_reconciler_internal; +open CoreTypes; + +type handler = GlobalState.handler; +type unregisterF = GlobalState.unregisterF; +let addStaleTreeHandler = GlobalState.addStaleTreeHandler; + +type element('node) = CoreTypes.element('node); +type hostNodeElement('node, 'childNode) = + CoreTypes.hostNodeElement('node, 'childNode) = { + make: unit => 'node, + configureInstance: (~isFirstRender: bool, 'node) => 'node, + children: element('childNode), + insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + moveNode: + (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, + }; + +let element = component => { + Leaf(OpaqueLeafElement(component)); +}; + +let listToElement = l => StaticList(l); +let empty = StaticList([]); + +module Hooks = Hooks; +module RemoteAction = RemoteAction; +module RenderedElement = RenderedElement; + +module Expert = { + let jsx_list = l => StaticList(l); + let component: + type a node. + (string, Hooks.t(a, a) => (element(node), Hooks.t(Hooks.nil, a))) => + element(node) = + debugName => { + module Component = { + type componentId('a) += + | Id: componentId( + instance( + ( + a, + (node, element(node), node, lazyHostNodeSeq(node)), + ), + ), + ); + + let eq: + type c. + ( + c, + componentId(c), + componentId( + instance( + (a, (node, element(node), node, lazyHostNodeSeq(node))), + ), + ) + ) => + option( + instance( + (a, (node, element(node), node, lazyHostNodeSeq(node))), + ), + ) = + (instance, id1, id2) => { + switch (id1, id2) { + | (Id, Id) => Some(instance) + | (_, _) => None + }; + }; + }; + render => + element({ + debugName, + childrenType: React, + id: Component.Id, + eq: Component.eq, + render, + }); + }; + + let nativeComponent: + type a node childNode. + ( + string, + Hooks.t(a, a) => + (hostNodeElement(node, childNode), Hooks.t(Hooks.nil, a)) + ) => + element(node) = + debugName => { + module Component = { + type componentId('a) += + | Id: componentId( + instance( + ( + a, + ( + node, + hostNodeElement(node, childNode), + childNode, + lazyHostNode(node), + ), + ), + ), + ); + + let eq: + type c. + ( + c, + componentId(c), + componentId( + instance( + ( + a, + ( + node, + hostNodeElement(node, childNode), + childNode, + lazyHostNode(node), + ), + ), + ), + ) + ) => + option( + instance( + ( + a, + ( + node, + hostNodeElement(node, childNode), + childNode, + lazyHostNode(node), + ), + ), + ), + ) = + (instance, id1, id2) => { + switch (id1, id2) { + | (Id, Id) => Some(instance) + | (_, _) => None + }; + }; + }; + render => + element({ + debugName, + childrenType: Host, + id: Component.Id, + eq: Component.eq, + render, + }); + }; +}; + +type movableStateContainerState('node) = + ref(option(movableElementState('node))); + +let movableStateContainer = (~children, (), hooks) => { + let (instanceRef, hooks) = Hooks.ref(None, hooks); + (() => Movable(children, instanceRef), hooks); +}; diff --git a/lib/Brisk_reconciler.rei b/lib/Brisk_reconciler.rei index 67d7735..4c3dddb 100644 --- a/lib/Brisk_reconciler.rei +++ b/lib/Brisk_reconciler.rei @@ -1,36 +1,7 @@ -/** - * Global state, mainly useful for internal testing - */ -module GlobalState: { - /** - * Resets global state including keys. - */ - let reset: unit => unit; -}; - type handler = unit => unit; type unregisterF = handler; let addStaleTreeHandler: handler => unregisterF; -/** - * Component keys - */ -module Key: { - /** - * Abstract type of the component key. It prevents duplicate key issues - */ - type t; - /** - * Create unique a component key. - */ - let create: unit => t; - - /** - * Default key - */ - let none: t; -}; - /** Type of element returned from render */ type element('node); @@ -45,18 +16,6 @@ type hostNodeElement('node, 'childNode) = { (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, }; -/** - * Converts a list of elements to a single syntheticElement. - * Lists use a mix of positoinal and keys to determine if a component should be - * inserted, removed, or updated. - * For two lists with the same length (i.e. if chicldren have the same length - * before and after update) if a component has a key, it'll be updated if there was a component - * with the same key on the previous render. - * Components without a key are matched based on position. - * Lists with different lengths are updated only based on keys. - */ -let listToElement: list(element('a)) => element('a); - /** * Empty synthetic element. */ @@ -79,11 +38,7 @@ module RenderedElement: { /** Update a rendered element when a new react element is received. */ let update: - ( - ~previousElement: element('node), - ~renderedElement: t('parentNode, 'node), - element('node) - ) => + (~renderedElement: t('parentNode, 'node), element('node)) => t('parentNode, 'node); /** Flush pending state updates (and possibly add new ones). */ @@ -103,57 +58,33 @@ module RenderedElement: { let executePendingEffects: t('a, 'b) => t('a, 'b); }; -/** - * Creates a component. Components are a functions which - * retain state over time via Hooks. The function you pass to - * component should be pure and all side effects should be - * handled using Hooks.effect - */ -[@ocaml.deprecated "Use let%component instead."] -let component: - ( - ~useDynamicKey: bool=?, - string, - ~key: Key.t=?, - Hooks.t('a, 'a) => (Hooks.t(Hooks.nil, 'a), element('node)) - ) => - element('node); - -/** - * Creates a component which renders an OutputTree node. - */ -[@ocaml.deprecated "Use let%nativeComponent instead."] -let nativeComponent: - ( - ~useDynamicKey: bool=?, - string, - ~key: Key.t=?, - Hooks.t('a, 'a) => - (Hooks.t(Hooks.nil, 'a), hostNodeElement('node, 'childNode)) - ) => - element('node); - module Expert: { /* Create a constant list of element */ let jsx_list: list(element('node)) => element('node); let component: ( - ~useDynamicKey: bool=?, string, - ~key: Key.t=?, Hooks.t('a, 'a) => (element('node), Hooks.t(Hooks.nil, 'a)) ) => element('node); let nativeComponent: ( - ~useDynamicKey: bool=?, string, - ~key: Key.t=?, Hooks.t('a, 'a) => (hostNodeElement('node, _), Hooks.t(Hooks.nil, 'a)) ) => element('node); }; +type movableStateContainerState('node); + +let movableStateContainer: + ( + ~children: element('node), + unit, + Hooks.t(movableStateContainerState('node) => 'c, 'd), + ) => + (unit => element('node), Hooks.t('c, 'd)); + module Hooks = Hooks; module RemoteAction = RemoteAction; diff --git a/lib/Brisk_reconciler_internal.re b/lib/Brisk_reconciler_internal.re deleted file mode 100644 index 4956e8b..0000000 --- a/lib/Brisk_reconciler_internal.re +++ /dev/null @@ -1,1816 +0,0 @@ -module GlobalState = { - let componentKeyCounter = ref(0); - let reset = () => { - componentKeyCounter := 0; - }; -}; - -type handler = unit => unit; -type unregisterF = handler; - -let staleHandlers = ref([]); -let addStaleTreeHandler = (handler: handler) => { - staleHandlers := [handler, ...staleHandlers^]; - () => { - staleHandlers := List.filter(f => f === handler, staleHandlers^); - }; -}; -let callStaleHanlders = () => List.iter(f => f(), staleHandlers^); - -module Key = { - type t = int; - - let equal = (==); - let none = (-1); - let dynamicKeyMagicNumber = 0; - let create = () => { - incr(GlobalState.componentKeyCounter); - GlobalState.componentKeyCounter^; - }; -}; - -type hostNode('a) = - | Node('a) - | UpdatedNode('a, 'a); - -type lazyHostNode('a) = Lazy.t(hostNode('a)); - -type lazyHostNodeList('a) = list(lazyHostNode('a)); - -type componentId('a) = ..; - -type element('node) = - | Flat(opaqueComponent('node)) - | Nested(list(element('node))) -and component('a) = { - debugName: string, - key: int, - id: componentId(instance('a)), - childrenType: childrenType('viewSpec), - eq: - 'other. - ('other, componentId('other), componentId(instance('a))) => - option(instance('a)), - - render: - Hooks.t('hooks, 'hooks) => ('children, Hooks.t(Hooks.nil, 'hooks)), -} -constraint 'viewSpec = ('node, 'children, 'childNode, 'wrappedNode) -constraint 'a = ('hooks, 'viewSpec) -and instance('a) = { - hooks: Hooks.state('hooks), - opaqueComponent: opaqueComponent('node), - component: component('a), - children_: 'children, - childInstances: instanceForest('childNode), - wrappedHostNode: 'wrappedNode, -} -constraint 'viewSpec = ('node, 'children, 'childNode, 'wrappedNode) -constraint 'a = ('hooks, 'viewSpec) -and opaqueComponent('node) = - | OpaqueComponent(component((_, ('node, _, _, _)))) - : opaqueComponent('node) -and instanceForest('node) = - | IFlat(opaqueInstance('node)) - | INested(list(instanceForest('node)), int /*subtree size*/) -and opaqueInstance('node) = - | Instance(instance((_, ('node, _, _, _)))): opaqueInstance('node) -and hostNodeElement('node, 'childNode) = { - make: unit => 'node, - configureInstance: (~isFirstRender: bool, 'node) => 'node, - children: element('childNode), - insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, - deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, - moveNode: - (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, -} -and childrenType('viewSpec) = - | Host: childrenType( - ( - 'node, - hostNodeElement('node, 'childNode), - 'childNode, - lazyHostNode('node), - ), - ) - | React - : childrenType( - ('node, element('node), 'node, lazyHostNodeList('node)), - ); - -type renderedElement('node, 'childNode) = { - nearestHostNode: lazyHostNode('node), - nodeElement: hostNodeElement('node, 'childNode), - instanceForest: instanceForest('childNode), - enqueuedEffects: EffectSequence.t, -}; - -type opaqueInstanceUpdate('node, 'childNode) = { - nearestHostNode: lazyHostNode('node), - nodeElement: hostNodeElement('node, 'childNode), - opaqueInstance: opaqueInstance('childNode), - enqueuedEffects: EffectSequence.t, -}; - -module InstanceForest = { - let getSubtreeSize: type node. instanceForest(node) => int = - fun - | INested(_, x) => x - | IFlat(Instance({wrappedHostNode, component: {childrenType}})) => - switch (childrenType) { - | React => List.length(wrappedHostNode) - | Host => 1 - }; - - let rec flatten = - fun - | IFlat(l) => [l] - | INested(l, _) => ListTR.concat(ListTR.map(flatten, l)); - - let outputTreeNodes: - type node. instanceForest(node) => lazyHostNodeList(node) = - subtree => - flatten(subtree) - |> List.fold_left( - ( - acc: lazyHostNodeList(node), - Instance( - ( - {component: {childrenType}, wrappedHostNode}: - instance((_, (node, _, _, _))) - ), - ): - opaqueInstance(node), - ) => - switch (childrenType) { - | React => List.append(wrappedHostNode, acc) - | Host => [wrappedHostNode, ...acc] - }, - [], - ) - |> List.rev; - - let pendingEffects = (~lifecycle, acc, instanceForest) => { - let f = (acc, Instance({hooks})) => - EffectSequence.chain( - Hooks.pendingEffects(~lifecycle, Some(hooks)), - acc, - ); - let rec fold: - type any. (EffectSequence.t, instanceForest(any)) => EffectSequence.t = - (acc, instanceForest) => { - switch (instanceForest) { - | IFlat(Instance({childInstances}) as opaqueInstance) => - f(fold(acc, childInstances), opaqueInstance) - | INested(l, _) => - List.fold_left( - (acc, instanceForest) => fold(acc, instanceForest), - acc, - l, - ) - }; - }; - fold(acc, instanceForest); - }; -}; - -module Element = { - let rec map = (f, syntheticElement) => - switch (syntheticElement) { - | Flat(l) => - let (opaqueInstance, enqueuedMountEffects) = f(l); - (IFlat(opaqueInstance), enqueuedMountEffects); - | Nested(l) => - let instanceSubForestAndEffects = ListTR.map(map(f), l); - let subForest = ListTR.map(fst, instanceSubForestAndEffects); - let effects = ListTR.map(snd, instanceSubForestAndEffects); - ( - INested( - subForest, - subForest - |> List.map(InstanceForest.getSubtreeSize) - |> List.fold_left((+), 0), - ), - List.fold_left(EffectSequence.chain, EffectSequence.noop, effects), - ); - }; - - let rec fold = (f, renderedElement, nearestHostNode, nodeElement) => - switch (renderedElement) { - | Flat(e) => - let {nearestHostNode, nodeElement, opaqueInstance, enqueuedEffects} = - f(~nearestHostNode, ~nodeElement, e); - { - nearestHostNode, - instanceForest: IFlat(opaqueInstance), - nodeElement, - enqueuedEffects, - }; - | Nested(l) => - let (nextL, nearestHostNode, enqueuedEffects, nodeElement) = - List.fold_left( - ((acc, nearestHostNode, enqueuedEffects, nodeElement), element) => { - let { - nearestHostNode, - instanceForest, - enqueuedEffects: nextEffects, - nodeElement, - } = - fold(f, element, nearestHostNode, nodeElement); - ( - [instanceForest, ...acc], - nearestHostNode, - EffectSequence.chain(enqueuedEffects, nextEffects), - nodeElement, - ); - }, - ([], nearestHostNode, EffectSequence.noop, nodeElement), - List.rev(l), - ); - { - nearestHostNode, - nodeElement, - instanceForest: - INested( - nextL, - List.map(InstanceForest.getSubtreeSize, nextL) - |> List.fold_left((+), 0), - ), - enqueuedEffects, - }; - }; -}; - -module HostNode = { - let make = - ( - type node, - type children, - type wrappedNode, - type childNode, - childrenType: childrenType((node, children, childNode, wrappedNode)), - children: children, - childInstances: instanceForest(childNode), - ) - : wrappedNode => - switch (childrenType) { - | Host => - lazy({ - let instance = - children.make() |> children.configureInstance(~isFirstRender=true); - Node( - List.fold_left( - ((position, parent), child) => - ( - position + 1, - { - let Node(child) | UpdatedNode(_, child) = - Lazy.force(child); - children.insertNode(~parent, ~child, ~position); - }, - ), - (0, instance), - InstanceForest.outputTreeNodes(childInstances), - ) - |> snd, - ); - }) - | React => InstanceForest.outputTreeNodes(childInstances) - }; -}; - -module SubtreeChange = { - let insertNodes = - ( - ~nodeElement, - ~parent as parentWrapper, - ~children, - ~position as initialPosition: int, - ) => { - let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; - let newParent = - List.fold_left( - ((position, parent), child) => - ( - position + 1, - { - let Node(child) | UpdatedNode(_, child) = Lazy.force(child); - nodeElement.insertNode(~parent, ~child, ~position); - }, - ), - (initialPosition, oldParent), - children, - ) - |> snd; - newParent === oldParent - ? parentWrapper : UpdatedNode(oldParent, newParent); - }; - let deleteNodes = - ( - ~nodeElement, - ~parent as parentWrapper, - ~children, - ~position as initialPosition: int, - ) => { - let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; - let newParent = - List.fold_left( - ((position, parent), child) => - ( - position + 1, - { - let Node(child) | UpdatedNode(_, child) = Lazy.force(child); - nodeElement.deleteNode(~parent, ~child, ~position); - }, - ), - (initialPosition, oldParent), - children, - ) - |> snd; - newParent === oldParent - ? parentWrapper : UpdatedNode(oldParent, newParent); - }; - - let insertElement = (~nodeElement, ~parent, ~children, ~position) => - lazy( - insertNodes( - ~nodeElement, - ~parent=Lazy.force(parent), - ~children, - ~position, - ) - ); - - let replaceSubtree = - ( - ~nodeElement, - ~parent, - ~prevChildren, - ~nextChildren, - ~absoluteSubtreeIndex: int, - ) => - lazy( - { - insertNodes( - ~nodeElement, - ~parent= - deleteNodes( - ~nodeElement, - ~parent=Lazy.force(parent), - ~children=prevChildren, - ~position=absoluteSubtreeIndex, - ), - ~children=nextChildren, - ~position=absoluteSubtreeIndex, - ); - } - ); - - let reorderNode = - (~nodeElement, ~child, ~parent, ~indexShift: int, ~from: int, ~to_: int) => { - let isVal = Lazy.is_val(child); - switch (Lazy.force(child)) { - | Node(child) => - from === to_ - indexShift - ? parent : nodeElement.moveNode(~parent, ~child, ~from, ~to_) - | UpdatedNode(prevChild, child) when !isVal => - nodeElement.insertNode( - ~parent= - nodeElement.deleteNode(~parent, ~child=prevChild, ~position=from), - ~child, - ~position=to_, - ) - | UpdatedNode(_prevChild, child) => - from === to_ - indexShift - ? parent : nodeElement.moveNode(~parent, ~child, ~from, ~to_) - }; - }; - - let reorder = - ( - type node, - type childNode, - ~nodeElement, - ~parent: lazyHostNode(node), - ~instance as - Instance({wrappedHostNode, component: {childrenType}}): - opaqueInstance(childNode), - ~indexShift, - ~from, - ~to_, - ) => - switch (childrenType) { - | Host => - lazy({ - let parentWrapper = Lazy.force(parent); - let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; - let newParent = - reorderNode( - ~nodeElement, - ~parent=oldParent, - ~child=wrappedHostNode, - ~indexShift, - ~from, - ~to_, - ); - newParent === oldParent - ? parentWrapper : UpdatedNode(oldParent, newParent); - }) - | React => - lazy({ - let parentWrapper = Lazy.force(parent); - let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; - let newParent = - List.fold_left( - ((index, parent), child) => - ( - index + 1, - reorderNode( - ~nodeElement, - ~parent, - ~child, - ~indexShift, - ~from=from + index, - ~to_=to_ + index, - ), - ), - (0, oldParent), - wrappedHostNode, - ) - |> snd; - newParent === oldParent - ? parentWrapper : UpdatedNode(oldParent, newParent); - }) - }; - - let updateNodes = - (~nodeElement, ~parent, ~instanceForest, ~position as initialPosition) => - lazy({ - let parentWrapper = Lazy.force(parent); - let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; - let newParent = - List.fold_left( - ((position, instance), x) => - ( - position + 1, - switch (Lazy.force(x)) { - | Node(_child) => instance - | UpdatedNode(oldNode, newNode) => - nodeElement.insertNode( - ~parent= - nodeElement.deleteNode( - ~parent=instance, - ~child=oldNode, - ~position, - ), - ~child=newNode, - ~position, - ) - }, - ), - (initialPosition, oldParent), - InstanceForest.outputTreeNodes(instanceForest), - ) - |> snd; - newParent === oldParent - ? parentWrapper : UpdatedNode(oldParent, newParent); - }); -}; - -module OpaqueInstanceHash = { - type t('node) = lazy_t(Hashtbl.t(int, (opaqueInstance('node), int))); - let addOpaqueInstance = (idTable, index, opaqueInstance) => { - let Instance({component: {key}}) = opaqueInstance; - key == Key.none - ? () : Hashtbl.add(idTable, key, (opaqueInstance, index)); - }; - let addRenderedElement = (idTable, renderedElement, index) => { - let rec aux = index => - fun - | IFlat(l) => addOpaqueInstance(idTable, index, l) - | INested(l, _) => List.iteri((i, x) => aux(i, x), l); - aux(index, renderedElement); - }; - let createKeyTable = renderedElement => - lazy({ - let keyTable = Hashtbl.create(1); - addRenderedElement(keyTable, renderedElement, 0); - keyTable; - }); - let lookupKey = (table, key) => { - let keyTable = Lazy.force(table); - try(Some(Hashtbl.find(keyTable, key))) { - | Not_found => None - }; - }; -}; - -module Instance = { - - let rec ofComponent: - type hooks node children childNode wrappedHostNode. - ( - opaqueComponent(node), - component((hooks, (node, children, childNode, wrappedHostNode))) - ) => - (opaqueInstance(node), EffectSequence.t) = - (opaqueComponent, component) => ( - { - let (children_, hooks) = - component.render( - Hooks.ofState(None, ~onStateDidChange=callStaleHanlders), - ); - let hooks = Hooks.toState(hooks); - let childElements = - switch (component.childrenType) { - | React => (children_: element(childNode)) - | Host => children_.children - }; - let (childInstances, mountEffects) = ofList(childElements); - ( - Instance({ - hooks, - opaqueComponent, - component, - children_, - childInstances, - wrappedHostNode: - HostNode.make( - component.childrenType, - children_, - childInstances, - ), - }), - EffectSequence.chain( - Hooks.pendingEffects(~lifecycle=Hooks.Effect.Mount, Some(hooks)), - mountEffects, - ), - ); - }: ( - opaqueInstance(node), - EffectSequence.t, - ) - ) - - and ofOpaqueComponent: - type node. - opaqueComponent(node) => (opaqueInstance(node), EffectSequence.t) = - (OpaqueComponent(component) as opaqueComponent) => - ofComponent(opaqueComponent, component) - - and ofList: - type node. element(node) => (instanceForest(node), EffectSequence.t) = - syntheticElement => Element.map(ofOpaqueComponent, syntheticElement); - - let pendingEffects = - (~lifecycle, ~nextEffects, ~instance as {childInstances, hooks}) => { - InstanceForest.pendingEffects( - ~lifecycle, - EffectSequence.chain( - Hooks.pendingEffects(~lifecycle, Some(hooks)), - nextEffects, - ), - childInstances, - ); - }; -}; - -module Render = { - let getOpaqueInstance = (~useKeyTable, OpaqueComponent({key})) => - switch (useKeyTable) { - | None => None - | Some(keyTable) => OpaqueInstanceHash.lookupKey(keyTable, key) - }; - - type childElementUpdate('node, 'childNode) = { - updatedRenderedElement: renderedElement('node, 'childNode), - /* This represents the way previously rendered elements have been shifted due to moves */ - indexShift: int, - }; - - module UpdateContext = { - type t('node, 'childNode) = { - shouldExecutePendingUpdates: bool, - useKeyTable: option(OpaqueInstanceHash.t('childNode)), - /* This is a unique index of an element within a subtree, - * thanks to tracking it we can efficiently manage moves of within a subtree - */ - nearestHostNode: lazyHostNode('node), - nodeElement: hostNodeElement('node, 'childNode), - absoluteSubtreeIndex: int, - }; - }; - - - /** - * Initial render of an Element. Recurses to produce the entire tree of - * instances. - */ - let rec renderElement: - type parentNode node. - ( - ~nearestHostNode: lazyHostNode(parentNode), - ~nodeElement: hostNodeElement(parentNode, node), - ~useKeyTable: OpaqueInstanceHash.t(node)=?, - opaqueComponent(node) - ) => - opaqueInstanceUpdate(parentNode, node) = - (~nearestHostNode, ~nodeElement, ~useKeyTable=?, opaqueComponent) => - switch (getOpaqueInstance(~useKeyTable, opaqueComponent)) { - | Some((opaqueInstance, _)) => - updateOpaqueInstance( - ~updateContext= - UpdateContext.{ - nearestHostNode, - nodeElement, - absoluteSubtreeIndex: 0, - useKeyTable, - shouldExecutePendingUpdates: false, - }, - opaqueInstance, - opaqueComponent, - ) - | None => - let (opaqueInstance, enqueuedEffects) = - Instance.ofOpaqueComponent(opaqueComponent); - - {nearestHostNode, nodeElement, opaqueInstance, enqueuedEffects}; - } - - and renderReactElement: - type parentNode node. - ( - ~useKeyTable: OpaqueInstanceHash.t(node)=?, - lazyHostNode(parentNode), - element(node), - hostNodeElement(parentNode, node) - ) => - renderedElement(parentNode, node) = - (~useKeyTable=?, neareastHostNode, element, nodeElement) => - Element.fold( - renderElement(~useKeyTable?), - element, - neareastHostNode, - nodeElement, - ) - - /** - * Update a previously rendered instance tree according to a new Element. - * - * Here's where the magic happens: - * ------------------------------- - * - * We perform a dynamic check that two types are statically equal by way of - * mutation! We have a value of type `Instance` and another of type - * `Element`, where we each has their own `component 'x` for potentially - * different 'x. We need to see if the 'x are the same and if so safely "cast" - * one's `component` to the others. We do this by handing off state safely into - * one of their `component`s, and then seeing if we can observe it in the - * other, and if so, we simply treat the old component as the new one's. - * - * This approach is as sound as our confidence in our ability to repair the - * mutations accurately. - * - * There are more elegant ways to do this using first class modules, combined - * with extensible variants. That is how we should do this if we want to turn - * this implementation into something serious - it would avoid hitting the - * write barrier. - * - * The UpdateLog: - * --------------------- - * The updates happen depth first and so the update log contains the deepes - * changes first. - * A change at depth N in the tree, causes all nodes from 0 to N generate an - * update. It's because the render tree is an immutable data structure. - * A change deep within a tree, means that the subtree of its parent has - * changed and it propagates to the root of a tree. - */ - and updateOpaqueInstance: - type node parentNode. - ( - ~updateContext: UpdateContext.t(parentNode, node), - opaqueInstance(node), - opaqueComponent(node) - ) => - opaqueInstanceUpdate(parentNode, node) = - ( - ~updateContext, - Instance(instance) as originalOpaqueInstance, - OpaqueComponent(nextComponent) as nextOpaqueComponent, - ) => { - let nextState = - updateContext.shouldExecutePendingUpdates - ? Hooks.flushPendingStateUpdates(instance.hooks) : instance.hooks; - let stateChanged = nextState !== instance.hooks; - - let bailOut = - !stateChanged && instance.opaqueComponent === nextOpaqueComponent; - - if (bailOut && !updateContext.shouldExecutePendingUpdates) { - { - nearestHostNode: updateContext.nearestHostNode, - nodeElement: updateContext.nodeElement, - opaqueInstance: originalOpaqueInstance, - enqueuedEffects: EffectSequence.noop, - }; - } else { - let {component} = instance; - switch ( - nextComponent.eq( - {...instance, hooks: nextState}, - component.id, - nextComponent.id, - ) - ) { - /* - * Case A: The next element *is* of the same component class. - */ - | Some(handedInstance) => - let { - nearestHostNode, - nodeElement, - opaqueInstance: newOpaqueInstance, - enqueuedEffects, - } as ret = - updateInstance( - ~originalOpaqueInstance, - ~updateContext, - ~nextComponent, - ~nextOpaqueComponent, - ~stateChanged, - handedInstance, - ); - newOpaqueInstance === originalOpaqueInstance - ? ret - : { - nodeElement, - nearestHostNode: - SubtreeChange.updateNodes( - ~nodeElement, - ~parent=nearestHostNode, - ~instanceForest=IFlat(newOpaqueInstance), - ~position=updateContext.absoluteSubtreeIndex, - ), - opaqueInstance: newOpaqueInstance, - enqueuedEffects, - }; - /* - * Case B: The next element is *not* of the same component class. We know - * because otherwise we would have observed the mutation on - * `nextComponentClass`. - */ - | None => - /** - * ** Switching component type ** - */ - let (opaqueInstance, mountEffects) = - Instance.ofOpaqueComponent(nextOpaqueComponent); - let enqueuedEffects = - Instance.pendingEffects( - ~lifecycle=Hooks.Effect.Unmount, - ~nextEffects=mountEffects, - ~instance, - ); - { - nodeElement: updateContext.nodeElement, - nearestHostNode: - SubtreeChange.replaceSubtree( - ~nodeElement=updateContext.nodeElement, - ~parent=updateContext.nearestHostNode, - ~prevChildren= - InstanceForest.outputTreeNodes( - IFlat(originalOpaqueInstance), - ), - ~nextChildren= - InstanceForest.outputTreeNodes(IFlat(opaqueInstance)), - ~absoluteSubtreeIndex=updateContext.absoluteSubtreeIndex, - ), - opaqueInstance, - enqueuedEffects, - }; - }; - }; - } - - and updateInstance: - type hooks node children childNode wrappedHostNode parentNode. - ( - ~originalOpaqueInstance: opaqueInstance(node), - ~updateContext: UpdateContext.t(parentNode, node), - ~nextComponent: component( - ( - hooks, - (node, children, childNode, wrappedHostNode), - ), - ), - ~nextOpaqueComponent: opaqueComponent(node), - ~stateChanged: bool, - instance((hooks, (node, children, childNode, wrappedHostNode))) - ) => - opaqueInstanceUpdate(parentNode, node) = - ( - ~originalOpaqueInstance, - ~updateContext, - ~nextComponent, - ~nextOpaqueComponent, - ~stateChanged, - instance, - ) => { - let updatedInstanceWithNewElement = { - ...instance, - component: nextComponent, - opaqueComponent: nextOpaqueComponent, - }; - - let shouldRerender = - stateChanged || nextOpaqueComponent !== instance.opaqueComponent; - - let (nextSubElements, initialHooks) = - if (shouldRerender) { - let (nextElement, initialHooks) = - nextComponent.render( - Hooks.ofState( - Some(updatedInstanceWithNewElement.hooks), - ~onStateDidChange=callStaleHanlders, - ), - ); - (nextElement, Hooks.toState(initialHooks)); - } else { - (instance.children_, instance.hooks); - }; - - let updatedInstanceWithNewState = { - ...updatedInstanceWithNewElement, - hooks: initialHooks, - }; - - let {children_, childInstances} = updatedInstanceWithNewState; - let ( - nearestHostNode: lazyHostNode(parentNode), - updatedInstanceWithNewSubtree, - enqueuedEffects, - nodeElement: hostNodeElement(parentNode, node), - ) = - switch (nextComponent.childrenType) { - | React => - let { - nearestHostNode, - nodeElement, - instanceForest: nextInstanceSubForest, - enqueuedEffects, - } = - updateInstanceSubtree( - ~updateContext, - ~oldInstanceForest=childInstances, - ~oldReactElement=children_, - ~nextReactElement=nextSubElements, - (), - ); - nextInstanceSubForest !== childInstances - ? ( - nearestHostNode, - { - ...updatedInstanceWithNewState, - children_: nextSubElements, - childInstances: nextInstanceSubForest, - }: - instance( - (hooks, (node, children, childNode, wrappedHostNode)), - ), - enqueuedEffects, - nodeElement, - ) - : ( - nearestHostNode, - updatedInstanceWithNewState, - enqueuedEffects, - nodeElement, - ); - | Host => - let instanceWithNewHostView: - instance((hooks, (node, children, childNode, wrappedHostNode))) = - shouldRerender - ? { - ...updatedInstanceWithNewState, - wrappedHostNode: - lazy({ - let instance = - Lazy.force(updatedInstanceWithNewState.wrappedHostNode); - let Node(beforeUpdate) | UpdatedNode(_, beforeUpdate) = instance; - let afterUpdate = - nextSubElements.configureInstance( - ~isFirstRender=false, - beforeUpdate, - ); - afterUpdate === beforeUpdate - ? instance : UpdatedNode(beforeUpdate, afterUpdate); - }), - } - : updatedInstanceWithNewState; - - let { - nearestHostNode: wrappedHostNode, - instanceForest: nextInstanceSubForest, - enqueuedEffects, - } = { - updateInstanceSubtree( - ~updateContext={ - UpdateContext.shouldExecutePendingUpdates: - updateContext.shouldExecutePendingUpdates, - useKeyTable: None, - absoluteSubtreeIndex: 0, - nearestHostNode: ( - instanceWithNewHostView.wrappedHostNode: lazyHostNode(node) - ), - nodeElement: ( - instanceWithNewHostView.children_: - hostNodeElement(node, childNode) - ), - }, - ~oldInstanceForest=childInstances, - ~oldReactElement=children_.children, - ~nextReactElement=nextSubElements.children, - (), - ); - }; - if (nextInstanceSubForest !== instanceWithNewHostView.childInstances) { - ( - updateContext.nearestHostNode, - { - ...instanceWithNewHostView, - childInstances: nextInstanceSubForest, - children_: nextSubElements, - wrappedHostNode, - }: - instance( - (hooks, (node, children, childNode, wrappedHostNode)), - ), - enqueuedEffects, - updateContext.nodeElement, - ); - } else { - ( - updateContext.nearestHostNode, - instanceWithNewHostView, - enqueuedEffects, - updateContext.nodeElement, - ); - }; - }; - if (updatedInstanceWithNewSubtree === updatedInstanceWithNewElement - && !stateChanged) { - { - nodeElement, - nearestHostNode, - opaqueInstance: originalOpaqueInstance, - enqueuedEffects, - }; - } else { - { - nodeElement, - nearestHostNode, - opaqueInstance: Instance(updatedInstanceWithNewSubtree), - enqueuedEffects: - EffectSequence.chain( - Hooks.pendingEffects( - ~lifecycle=Hooks.Effect.Update, - Some(updatedInstanceWithNewSubtree.hooks), - ), - enqueuedEffects, - ), - }; - }; - } - - /** - * updateRenderedElement recurses through the syntheticElement tree as long as - * the oldReactElement and nextReactElement have the same shape. - * - * The base case is either an empty list - Nested([]) or a Flat element. - * - * syntheticElement is a recursive tree like data structure. The tree doesn't - * contain children of the syntheticElements returned from children, it only - * contains the "immediate" children so to speak including all nested lists. - * - * `keyTable` is a hash table containing all keys in the syntheticElement tree. - */ - and updateInstanceSubtree: - type parentNode node. - ( - ~updateContext: UpdateContext.t(parentNode, node), - ~oldInstanceForest: instanceForest(node), - ~oldReactElement: element(node), - ~nextReactElement: element(node), - unit - ) => - renderedElement(parentNode, node) = - ( - ~updateContext, - ~oldInstanceForest, - ~oldReactElement, - ~nextReactElement, - (), - ) => - switch (oldInstanceForest, oldReactElement, nextReactElement) { - | ( - INested(instanceSubTrees, subtreeSize), - Nested(oldReactElements), - Nested([nextReactElement, ...nextReactElements]), - ) - when nextReactElements === oldReactElements => - /* Detected that nextReactElement was obtained by adding one element */ - let { - nearestHostNode, - nodeElement, - instanceForest: addedElement, - enqueuedEffects, - } = - renderReactElement( - updateContext.nearestHostNode, - nextReactElement, - updateContext.nodeElement, - ); - { - nodeElement, - nearestHostNode: - SubtreeChange.insertElement( - ~nodeElement, - ~parent=nearestHostNode, - ~children=InstanceForest.outputTreeNodes(addedElement), - ~position=updateContext.absoluteSubtreeIndex, - ), - /*** Prepend element */ - instanceForest: - INested( - [addedElement, ...instanceSubTrees], - subtreeSize + InstanceForest.getSubtreeSize(addedElement), - ), - enqueuedEffects, - }; - | ( - INested(oldInstanceForests, _), - Nested(oldReactElements), - Nested(nextReactElements), - ) - when - List.length(nextReactElements) - === List.length(oldInstanceForests) => - let keyTable = OpaqueInstanceHash.createKeyTable(oldInstanceForest); - let ( - nearestHostNode, - newInstanceForests, - subtreeSize, - _indexShift, - enqueuedEffects, - nodeElement, - ) = - ListTR.fold3( - ( - ( - nearestHostNode, - renderedElements, - prevSubtreeSize, - indexShift, - enqueuedEffectsAcc, - nodeElement, - ), - oldInstanceForest, - oldReactElement, - nextReactElement, - ) => { - let { - indexShift, - updatedRenderedElement: { - nearestHostNode, - instanceForest, - enqueuedEffects, - nodeElement, - }, - } = - updateChildRenderedElement( - ~updateContext={ - ...updateContext, - nearestHostNode, - useKeyTable: Some(keyTable), - absoluteSubtreeIndex: prevSubtreeSize, - nodeElement, - }, - ~indexShift, - ~oldInstanceForest, - ~oldReactElement, - ~nextReactElement, - (), - ); - ( - nearestHostNode, - [instanceForest, ...renderedElements], - prevSubtreeSize - + InstanceForest.getSubtreeSize(instanceForest), - indexShift, - EffectSequence.chain(enqueuedEffects, enqueuedEffectsAcc), - nodeElement, - ); - }, - oldInstanceForests, - oldReactElements, - nextReactElements, - ( - updateContext.nearestHostNode, - [], - updateContext.absoluteSubtreeIndex, - 0, - EffectSequence.noop, - updateContext.nodeElement, - ), - ); - let newInstanceForests = List.rev(newInstanceForests); - { - nodeElement, - nearestHostNode, - instanceForest: INested(newInstanceForests, subtreeSize), - enqueuedEffects, - }; - /* - * Key Policy for syntheticElement. - * Nested elements determine shape: if the shape is not identical, re-render. - * Flat elements use a positional match by default, where components at - * the same position (from left) are matched for updates. - * If the component has an explicit key, match the instance with the same key. - * Note: components are matched for key across the entire syntheticElement structure. - */ - | ( - IFlat(Instance(oldInstance) as oldOpaqueInstance), - Flat(OpaqueComponent({key: oldKey})), - Flat(OpaqueComponent({key: nextKey}) as nextReactElement), - ) => - if (nextKey !== oldKey) { - /* Not found: render a new instance */ - let { - nearestHostNode, - opaqueInstance: newOpaqueInstance, - enqueuedEffects: mountEffects, - nodeElement, - } = - renderElement( - nextReactElement, - ~nearestHostNode=updateContext.nearestHostNode, - ~nodeElement=updateContext.nodeElement, - ); - let enqueuedEffects = - Instance.pendingEffects( - ~lifecycle=Unmount, - ~nextEffects=mountEffects, - ~instance=oldInstance, - ); - let newInstanceForest = IFlat(newOpaqueInstance); - { - nodeElement, - nearestHostNode: - SubtreeChange.replaceSubtree( - ~nodeElement, - ~parent=nearestHostNode, - ~prevChildren= - InstanceForest.outputTreeNodes(oldInstanceForest), - ~nextChildren= - InstanceForest.outputTreeNodes(newInstanceForest), - /* hard-coded zero since we will only ever have one child */ - ~absoluteSubtreeIndex=0, - ), - instanceForest: newInstanceForest, - enqueuedEffects, - }; - } else { - let { - nearestHostNode, - opaqueInstance: newOpaqueInstance, - enqueuedEffects, - nodeElement, - } = - updateOpaqueInstance( - ~updateContext={...updateContext, useKeyTable: None}, - oldOpaqueInstance, - nextReactElement, - ); - { - nodeElement, - nearestHostNode, - instanceForest: - oldOpaqueInstance !== newOpaqueInstance - ? IFlat(newOpaqueInstance) : oldInstanceForest, - enqueuedEffects, - }; - } - | (oldInstanceForest, _, _) => - /* Notice that all elements which are queried successfully - * from the hash table must have been here in the previous render - * No, it's not true. What if the key is the same but element type changes - */ - let keyTable = - switch (updateContext.useKeyTable) { - | None => OpaqueInstanceHash.createKeyTable(oldInstanceForest) - | Some(keyTable) => keyTable - }; - let { - nearestHostNode, - instanceForest: newInstanceForest, - enqueuedEffects: mountEffects, - nodeElement, - } = - renderReactElement( - ~useKeyTable=keyTable, - updateContext.nearestHostNode, - nextReactElement, - updateContext.nodeElement, - ); - - let enqueuedEffects = - InstanceForest.pendingEffects( - ~lifecycle=Hooks.Effect.Unmount, - mountEffects, - oldInstanceForest, - ); - { - nodeElement, - nearestHostNode: - SubtreeChange.replaceSubtree( - ~nodeElement, - ~parent=nearestHostNode, - ~prevChildren=InstanceForest.outputTreeNodes(oldInstanceForest), - ~nextChildren=InstanceForest.outputTreeNodes(newInstanceForest), - ~absoluteSubtreeIndex=updateContext.absoluteSubtreeIndex, - ), - instanceForest: newInstanceForest, - enqueuedEffects, - }; - } - - and updateChildRenderedElement: - type parentNode node. - ( - ~updateContext: UpdateContext.t(parentNode, node), - ~indexShift: int, - ~oldInstanceForest: instanceForest(node), - ~oldReactElement: element(node), - ~nextReactElement: element(node), - unit - ) => - childElementUpdate(parentNode, node) = - ( - ~updateContext as { - UpdateContext.shouldExecutePendingUpdates, - useKeyTable, - nearestHostNode, - nodeElement, - absoluteSubtreeIndex, - }, - ~indexShift, - ~oldInstanceForest, - ~oldReactElement, - ~nextReactElement, - (), - ) => - switch (oldInstanceForest, oldReactElement, nextReactElement) { - /* - * Key Policy for syntheticElement. - * Nested elements determine shape: if the shape is not identical, re-render. - * Flat elements use a positional match by default, where components at - * the same position (from left) are matched for updates. - * If the component has an explicit key, match the instance with the same key. - * Note: components are matched for key across the entire syntheticElement structure. - */ - | ( - IFlat(oldOpaqueInstance), - Flat(OpaqueComponent({key: oldKey})), - Flat(OpaqueComponent({key: nextKey}) as nextReactElement), - ) => - let keyTable = - switch (useKeyTable) { - | None => - OpaqueInstanceHash.createKeyTable(IFlat(oldOpaqueInstance)) - | Some(keyTable) => keyTable - }; - let (nearestHostNode, update, newOpaqueInstance, enqueuedEffects) = { - let OpaqueComponent(component) = nextReactElement; - if (component.key !== Key.none) { - switch (OpaqueInstanceHash.lookupKey(keyTable, component.key)) { - | Some((subOpaqueInstance, previousIndex)) => - /* Instance tree with the same component key */ - let { - nearestHostNode, - opaqueInstance: updatedOpaqueInstance, - enqueuedEffects, - } = - updateOpaqueInstance( - ~updateContext= - UpdateContext.{ - useKeyTable, - shouldExecutePendingUpdates, - nearestHostNode, - absoluteSubtreeIndex: previousIndex + indexShift, - nodeElement, - }, - subOpaqueInstance, - nextReactElement, - ); - ( - nearestHostNode, - `NoChangeOrNested(previousIndex), - updatedOpaqueInstance, - enqueuedEffects, - ); - | None => - /* Not found: render a new instance */ - let { - nearestHostNode, - opaqueInstance: newOpaqueInstance, - enqueuedEffects, - } = - renderElement( - ~nearestHostNode, - nextReactElement, - ~nodeElement, - ); - ( - nearestHostNode, - `NewElement, - newOpaqueInstance, - enqueuedEffects, - ); - }; - } else { - let { - nearestHostNode, - opaqueInstance: updatedOpaqueInstance, - enqueuedEffects, - } = - updateOpaqueInstance( - ~updateContext= - UpdateContext.{ - nodeElement, - shouldExecutePendingUpdates, - nearestHostNode, - absoluteSubtreeIndex, - useKeyTable, - }, - oldOpaqueInstance, - nextReactElement, - ); - ( - nearestHostNode, - `NoChangeOrNested(absoluteSubtreeIndex), - updatedOpaqueInstance, - enqueuedEffects, - ); - }; - }; - switch (update) { - | `NewElement => - let newInstanceForest = IFlat(newOpaqueInstance); - { - updatedRenderedElement: { - nearestHostNode: - SubtreeChange.replaceSubtree( - ~nodeElement, - ~parent=nearestHostNode, - ~prevChildren= - InstanceForest.outputTreeNodes(oldInstanceForest), - ~nextChildren= - InstanceForest.outputTreeNodes(newInstanceForest), - ~absoluteSubtreeIndex, - ), - instanceForest: newInstanceForest, - enqueuedEffects, - nodeElement, - }, - indexShift: 0, - }; - | `NoChangeOrNested(previousIndex) => - let changed = oldOpaqueInstance !== newOpaqueInstance; - let element = - changed ? IFlat(newOpaqueInstance) : oldInstanceForest; - if (oldKey != nextKey) { - { - updatedRenderedElement: { - nearestHostNode: - SubtreeChange.reorder( - ~nodeElement, - ~parent=nearestHostNode, - ~instance=newOpaqueInstance, - ~indexShift, - ~from=previousIndex, - ~to_=absoluteSubtreeIndex, - ), - instanceForest: element, - enqueuedEffects, - nodeElement, - }, - indexShift: InstanceForest.getSubtreeSize(element), - }; - } else { - { - updatedRenderedElement: { - nearestHostNode, - instanceForest: element, - enqueuedEffects, - nodeElement, - }, - indexShift: 0, - }; - }; - }; - | (_, _, _) => { - updatedRenderedElement: - updateInstanceSubtree( - ~updateContext={ - UpdateContext.absoluteSubtreeIndex, - nodeElement, - shouldExecutePendingUpdates, - nearestHostNode, - /* Not sure about this */ - useKeyTable, - }, - ~oldInstanceForest, - ~oldReactElement, - ~nextReactElement, - (), - ), - indexShift: 0, - } - }; - - /** - * Execute the pending updates at the top level of an instance tree. - * If no state change is performed, the argument is returned unchanged. - */ - let flushPendingUpdates = (opaqueInstance, nearestHostNode, nodeElement) => { - let Instance({opaqueComponent}) = opaqueInstance; - updateOpaqueInstance( - ~updateContext= - UpdateContext.{ - useKeyTable: None, - shouldExecutePendingUpdates: true, - nearestHostNode, - nodeElement, - absoluteSubtreeIndex: 0, - }, - opaqueInstance, - opaqueComponent, - ); - }; -}; - -module RenderedElement = { - /** - * Rendering produces a list of instance trees. - */ - type t('node, 'childNode) = renderedElement('node, 'childNode); - type root('node, 'childNode) = { - node: 'node, - insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, - deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, - moveNode: - (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, - }; - - let listToRenderedElement = renderedElements => - INested( - renderedElements, - renderedElements - |> List.fold_left( - (acc, e) => acc + InstanceForest.getSubtreeSize(e), - 0, - ), - ); - let render = (root, children) => { - let (instanceForest, mountEffects) = Instance.ofList(children); - { - nodeElement: { - make: () => root.node, - configureInstance: (~isFirstRender as _, i) => i, - children, - insertNode: root.insertNode, - deleteNode: root.deleteNode, - moveNode: root.moveNode, - }, - instanceForest, - nearestHostNode: - lazy( - Node( - InstanceForest.outputTreeNodes(instanceForest) - |> List.fold_left( - ((position, parent), child) => - ( - position + 1, - { - let Node(child) | UpdatedNode(_, child) = - Lazy.force(child); - let parent = - root.insertNode(~parent, ~child, ~position); - parent; - }, - ), - (0, root.node), - ) - |> snd, - ) - ), - enqueuedEffects: mountEffects, - }; - }; - let update = - ( - ~previousElement, - ~renderedElement as {instanceForest, nearestHostNode, nodeElement}, - nextReactElement, - ) => - Render.updateInstanceSubtree( - ~updateContext= - Render.UpdateContext.{ - nodeElement, - nearestHostNode, - absoluteSubtreeIndex: 0, - useKeyTable: None, - shouldExecutePendingUpdates: false, - }, - ~oldInstanceForest=instanceForest, - ~oldReactElement=previousElement, - ~nextReactElement, - (), - ); - - let rec map = (f, renderedElement, nearestHostNode, nodeElement) => - switch (renderedElement) { - | IFlat(e) => - let {nearestHostNode, opaqueInstance, enqueuedEffects, nodeElement} = - f(e, nearestHostNode, nodeElement); - let unchanged = e === opaqueInstance; - - { - nodeElement, - nearestHostNode, - instanceForest: unchanged ? renderedElement : IFlat(opaqueInstance), - enqueuedEffects, - }; - | INested(l, _) => - let (nextL, nearestHostNode, effects, nodeElement) = - List.fold_left( - ((acc, nearestHostNode, effectsAcc, nodeElement), renderedElement) => { - let { - nearestHostNode, - instanceForest: next, - enqueuedEffects, - nodeElement, - } = - map(f, renderedElement, nearestHostNode, nodeElement); - ( - [next, ...acc], - nearestHostNode, - EffectSequence.chain(effectsAcc, enqueuedEffects), - nodeElement, - ); - }, - ([], nearestHostNode, EffectSequence.noop, nodeElement), - List.rev(l), - ); - let unchanged = List.for_all2((===), l, nextL); - - { - nodeElement, - nearestHostNode, - instanceForest: - unchanged - ? renderedElement - : INested( - nextL, - List.fold_left( - (acc, elem) => InstanceForest.getSubtreeSize(elem) + acc, - 0, - nextL, - ), - ), - enqueuedEffects: effects, - }; - }; - - /** - * Flush the pending updates in an instance tree. - */ - let flushPendingUpdates = - ({instanceForest, nearestHostNode, enqueuedEffects, nodeElement}) => { - let { - nearestHostNode, - instanceForest: newInstanceForest, - enqueuedEffects: nextEnqueuedEffects, - nodeElement, - } = - map( - Render.flushPendingUpdates, - instanceForest, - nearestHostNode, - nodeElement, - ); - { - nodeElement, - instanceForest: newInstanceForest, - nearestHostNode, - enqueuedEffects: - EffectSequence.chain(nextEnqueuedEffects, enqueuedEffects), - }; - }; - - let executeHostViewUpdates = ({nearestHostNode}: t(_, _)) => { - let Node(hostView) | UpdatedNode(_, hostView) = - Lazy.force(nearestHostNode); - hostView; - }; - - let executePendingEffects = - ({enqueuedEffects} as renderedElement: t(_, _)) => { - enqueuedEffects(); - {...renderedElement, enqueuedEffects: EffectSequence.noop}; - }; -}; - -let element = (~key as argumentKey=Key.none, component) => { - let key = - argumentKey != Key.none - ? argumentKey - : { - let isDynamicKey = component.key == Key.dynamicKeyMagicNumber; - isDynamicKey ? Key.create() : Key.none; - }; - let componentWithKey = - key != component.key ? {...component, key} : component; - Flat(OpaqueComponent(componentWithKey)); -}; - -let listToElement = l => Nested(l); -let empty = Nested([]); - -module Hooks = Hooks; -module RemoteAction = RemoteAction; - -module Expert = { - let jsx_list = listToElement; - let component: - type a node. - ( - ~useDynamicKey: bool=?, - string, - ~key: Key.t=?, - Hooks.t(a, a) => (element(node), Hooks.t(Hooks.nil, a)) - ) => - element(node) = - (~useDynamicKey=false, debugName) => { - module Component = { - type componentId('a) += - | Id: componentId( - instance( - ( - a, - (node, element(node), node, lazyHostNodeList(node)), - ), - ), - ); - - let eq: - type c. - ( - c, - componentId(c), - componentId( - instance( - (a, (node, element(node), node, lazyHostNodeList(node))), - ), - ) - ) => - option( - instance( - (a, (node, element(node), node, lazyHostNodeList(node))), - ), - ) = - (instance, id1, id2) => { - switch (id1, id2) { - | (Id, Id) => Some(instance) - | (_, _) => None - }; - }; - }; - (~key=?, render) => - element( - ~key?, - { - debugName, - childrenType: React, - key: useDynamicKey ? Key.dynamicKeyMagicNumber : Key.none, - id: Component.Id, - eq: Component.eq, - render, - }, - ); - }; - - let nativeComponent: - type a node childNode. - ( - ~useDynamicKey: bool=?, - string, - ~key: Key.t=?, - Hooks.t(a, a) => - (hostNodeElement(node, childNode), Hooks.t(Hooks.nil, a)) - ) => - element(node) = - (~useDynamicKey=false, debugName) => { - module Component = { - type componentId('a) += - | Id: componentId( - instance( - ( - a, - ( - node, - hostNodeElement(node, childNode), - childNode, - lazyHostNode(node), - ), - ), - ), - ); - - let eq: - type c. - ( - c, - componentId(c), - componentId( - instance( - ( - a, - ( - node, - hostNodeElement(node, childNode), - childNode, - lazyHostNode(node), - ), - ), - ), - ) - ) => - option( - instance( - ( - a, - ( - node, - hostNodeElement(node, childNode), - childNode, - lazyHostNode(node), - ), - ), - ), - ) = - (instance, id1, id2) => { - switch (id1, id2) { - | (Id, Id) => Some(instance) - | (_, _) => None - }; - }; - }; - (~key=?, render) => - element( - ~key?, - { - debugName, - childrenType: Host, - key: useDynamicKey ? Key.dynamicKeyMagicNumber : Key.none, - id: Component.Id, - eq: Component.eq, - render, - }, - ); - }; -}; -let component = (~useDynamicKey=?, debugName) => { - let c = Expert.component(~useDynamicKey?, debugName); - (~key=?, render) => { - c( - ~key?, - hooks => { - let (hooks, e) = render(hooks); - (e, hooks); - }, - ); - }; -}; -let nativeComponent = (~useDynamicKey=?, debugName) => { - let c = Expert.nativeComponent(~useDynamicKey?, debugName); - (~key=?, render) => { - c( - ~key?, - hooks => { - let (hooks, e) = render(hooks); - (e, hooks); - }, - ); - }; -}; diff --git a/lib/CoreTypes.re b/lib/CoreTypes.re new file mode 100644 index 0000000..c4bd99c --- /dev/null +++ b/lib/CoreTypes.re @@ -0,0 +1,96 @@ +type hostNode('a) = + | Node('a) + | UpdatedNode('a, 'a); + +type lazyHostNode('a) = Lazy.t(hostNode('a)); + +type lazyHostNodeSeq('a) = Seq.t(lazyHostNode('a)); + +type componentId('a) = ..; + +type subtreeSize = int; + +type diffItem('left, 'right) = + | Added('right) + | Removed('left) + | Updated('left, 'right); + +type dynamicElement('node, 'typ) = { + diff: 'a. dynamicElement('node, 'a) => Seq.t(diffItem('typ, 'a)), + map: 'a. (~f: 'typ => 'a) => dynamicElement('node, 'a), + toSeq: unit => Seq.t('typ), + insert: 'typ => dynamicElement('node, 'typ), + empty: 'any. unit => dynamicElement('node, 'any), +}; + +type element('node) = + | Leaf(opaqueLeafElement('node)) + | StaticList(list(element('node))) + | DiffableSequence(dynamicElement('node, element('node))) + | Movable(element('node), ref(option(movableElementState('node)))) +and movableElementState('node) = { + instanceForest:instanceForest('node), + index: int, + subtreeSize: int +} +and leafElement('a) = { + debugName: string, + id: componentId(instance('a)), + childrenType: childrenType('viewSpec), + eq: + 'other. + ('other, componentId('other), componentId(instance('a))) => + option(instance('a)), + + render: + Hooks.t('hooks, 'hooks) => ('children, Hooks.t(Hooks.nil, 'hooks)), +} +constraint 'viewSpec = ('node, 'children, 'childNode, 'wrappedNode) +constraint 'a = ('hooks, 'viewSpec) +and instance('a) = { + hooks: Hooks.state('hooks), + opaqueLeafElement: opaqueLeafElement('node), + leafElement: leafElement('a), + children_: 'children, + childInstances: instanceForest('childNode), + wrappedHostNode: 'wrappedNode, +} +constraint 'viewSpec = ('node, 'children, 'childNode, 'wrappedNode) +constraint 'a = ('hooks, 'viewSpec) +and opaqueLeafElement('node) = + | OpaqueLeafElement(leafElement((_, ('node, _, _, _)))) + : opaqueLeafElement('node) +and instanceForest('node) = + | IFlat(opaqueInstance('node)) + | INested(list(instanceForest('node)), subtreeSize) + | IDiffableSequence( + dynamicElement('node, instanceForest('node)), + subtreeSize, + ) +and opaqueInstance('node) = + | Instance(instance((_, ('node, _, _, _)))): opaqueInstance('node) +and hostNodeElement('node, 'childNode) = { + make: unit => 'node, + configureInstance: (~isFirstRender: bool, 'node) => 'node, + children: element('childNode), + insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + moveNode: + (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, +} +and childrenType('viewSpec) = + | Host: childrenType( + ( + 'node, + hostNodeElement('node, 'childNode), + 'childNode, + lazyHostNode('node), + ), + ) + | React + : childrenType( + ('node, element('node), 'node, lazyHostNodeSeq('node)), + ); + +type opaqueInstanceHash('node) = + Lazy.t(Hashtbl.t(int, (opaqueInstance('node), int))); diff --git a/lib/Element.re b/lib/Element.re new file mode 100644 index 0000000..9de75ce --- /dev/null +++ b/lib/Element.re @@ -0,0 +1,67 @@ +type t('node) = CoreTypes.element('node); + +let rec fold = (~f, ~init, renderedElement) => { + let foldSequence = (seq, container, add, wrapResult) => { + let update = + Seq.fold_left( + (update: Update.t(_, _, _), element) => { + // Append child nodes here + fold(~f, ~init=update.Update.hostTreeUpdate, element) + |> Update.map(payload => add(update.Update.payload, payload)) + |> Update.mapEffects(nextEffects => + EffectSequence.chain( + update.Update.enqueuedEffects, + nextEffects, + ) + ) + }, + { + Update.payload: container, + enqueuedEffects: EffectSequence.noop, + hostTreeUpdate: init, + childNodes: Seq.empty, + }, + seq, + ); + update + |> Update.map(payload => + wrapResult( + payload, + update.hostTreeUpdate.absoluteSubtreeIndex + - init.absoluteSubtreeIndex, + ) + ); + }; + CoreTypes.( + switch (renderedElement) { + | Leaf(c) => + f(~hostTreeState=init, ~component=c) + |> Update.map(instance => IFlat(instance)) + | DiffableSequence(seq) => + foldSequence( + seq.toSeq(), + seq.empty(), + (instances, instance) => instances.insert(instance), + (seq, length) => IDiffableSequence(seq, length), + ) + | StaticList(l) => + foldSequence( + l |> List.to_seq, + [], + (rest, h) => [h, ...rest], + (list, length) => INested(list, length), + ) + + | Movable(l, ref) => + let res = fold(~f, ~init, l); + ref := + Some({ + instanceForest: res.payload, + /* THIS IS BROKEN */ + index: 0, + subtreeSize: 0, + }); + res; + } + ); +}; diff --git a/lib/Element.rei b/lib/Element.rei new file mode 100644 index 0000000..8225fdb --- /dev/null +++ b/lib/Element.rei @@ -0,0 +1,13 @@ +type t('node) = CoreTypes.element('node); + +let fold: + ( + ~f: ( + ~hostTreeState: Update.hostTreeState('a, 'b), + ~component: CoreTypes.opaqueLeafElement('c) + ) => + Update.t('a, 'b, CoreTypes.opaqueInstance('c)), + ~init: Update.hostTreeState('a, 'b), + t('c) + ) => + Update.t('a, 'b, CoreTypes.instanceForest('c)); diff --git a/lib/GlobalState.re b/lib/GlobalState.re new file mode 100644 index 0000000..11fcadb --- /dev/null +++ b/lib/GlobalState.re @@ -0,0 +1,12 @@ +type handler = unit => unit; +type unregisterF = handler; + +let staleHandlers = ref([]); +let addStaleTreeHandler = (handler: handler) => { + staleHandlers := [handler, ...staleHandlers^]; + () => { + staleHandlers := List.filter(f => f === handler, staleHandlers^); + }; +}; +let callStaleHandlers = () => List.iter(f => f(), staleHandlers^); + diff --git a/lib/GlobalState.rei b/lib/GlobalState.rei new file mode 100644 index 0000000..46159b0 --- /dev/null +++ b/lib/GlobalState.rei @@ -0,0 +1,5 @@ +type handler = unit => unit; +type unregisterF = handler; + +let addStaleTreeHandler: handler => unregisterF; +let callStaleHandlers: unit => unit; diff --git a/lib/Instance.re b/lib/Instance.re new file mode 100644 index 0000000..4ab4324 --- /dev/null +++ b/lib/Instance.re @@ -0,0 +1,191 @@ +open CoreTypes; + +let pendingEffectsInForest = (~lifecycle, instanceForest) => { + let f = (acc, CoreTypes.Instance({hooks})) => + EffectSequence.chain( + Hooks.pendingEffects(~lifecycle, Some(hooks)), + acc, + ); + let rec fold: + type any. + (EffectSequence.t, CoreTypes.instanceForest(any)) => EffectSequence.t = + (acc, instanceForest) => { + switch (instanceForest) { + | IFlat(Instance({childInstances}) as opaqueInstance) => + f(fold(acc, childInstances), opaqueInstance) + | INested(l, _) => + List.fold_left( + (acc, instanceForest) => fold(acc, instanceForest), + acc, + l, + ) + | IDiffableSequence(l, _) => + Seq.fold_left( + (acc, instanceForest) => fold(acc, instanceForest), + acc, + l.toSeq(), + ) + }; + }; + fold(EffectSequence.noop, instanceForest); +}; + +type opaque('node) = CoreTypes.opaqueInstance('node); + +type opaqueInstanceUpdate('node, 'childNode) = + Update.t('node, 'childNode, opaque('childNode)); + +type renderedElement('node, 'childNode) = + Update.t('node, 'childNode, instanceForest('childNode)); + + +let rec ofComponent: + type parentNode hooks node children childNode wrappedHostNode. + ( + ~hostTreeState: Update.hostTreeState(parentNode, node), + opaqueLeafElement(node), + leafElement((hooks, (node, children, childNode, wrappedHostNode))) + ) => + opaqueInstanceUpdate(parentNode, node) = + (~hostTreeState, opaqueLeafElement, leafElement) => { + let (children_, hooks) = + leafElement.render( + Hooks.ofState(None, ~onStateDidChange=GlobalState.callStaleHandlers), + ); + let hooks = Hooks.toState(hooks); + let addMountEffects = u => + u + |> Update.mapEffects(e => + EffectSequence.chain( + Hooks.pendingEffects( + ~lifecycle=Hooks.Effect.Mount, + Some(hooks), + ), + e, + ) + ); + switch (leafElement.childrenType) { + | React => + let update = ofList(~hostTreeState, children_: element(childNode)); + update + |> addMountEffects + |> Update.map(childInstances => + Instance({ + hooks, + opaqueLeafElement, + leafElement, + children_, + childInstances, + wrappedHostNode: update.childNodes, + }) + ); + | Host => + let node = + lazy( + Node( + children_.make() + |> children_.configureInstance(~isFirstRender=true), + ) + ); + let {Update.hostTreeUpdate, enqueuedEffects, payload} = + ofList( + ~hostTreeState={ + nearestHostNode: node, + nodeElement: children_, + absoluteSubtreeIndex: 0, + }, + children_.children, + ) + |> addMountEffects + |> Update.map(childInstances => + Instance({ + hooks, + opaqueLeafElement, + leafElement, + children_, + childInstances, + wrappedHostNode: node, + }) + ); + let hostTreeUpdate = { + ...hostTreeState, + nearestHostNode: + lazy( + SubtreeChange.insertNodes( + ~nodeElement=hostTreeState.nodeElement, + ~parent=Lazy.force(hostTreeState.nearestHostNode), + ~children=[hostTreeUpdate.nearestHostNode] |> List.to_seq, + ~position=hostTreeState.absoluteSubtreeIndex, + ) + ), + absoluteSubtreeIndex: hostTreeState.absoluteSubtreeIndex + 1, + }; + { + hostTreeUpdate, + enqueuedEffects, + payload, + childNodes: Seq.((() => Cons(node, () => Nil))), + }; + }; + } + +and ofOpaqueLeafElement: + type parentNode node. + ( + ~hostTreeState: Update.hostTreeState(parentNode, node), + ~component: opaqueLeafElement(node) + ) => + opaqueInstanceUpdate(parentNode, node) = + ( + ~hostTreeState, + ~component as OpaqueLeafElement(component) as opaqueComponent, + ) => + ofComponent(~hostTreeState, opaqueComponent, component) + +and ofList: + type parentNode node. + ( + ~hostTreeState: Update.hostTreeState(parentNode, node), + element(node) + ) => + renderedElement(parentNode, node) = + (~hostTreeState, syntheticElement) => + Element.fold( + ~f=ofOpaqueLeafElement, + ~init=hostTreeState, + syntheticElement, + ); + +let pendingEffects = + (~lifecycle, ~nextEffects, ~instance as {childInstances, hooks}) => { + EffectSequence.chain( + pendingEffectsInForest(~lifecycle, childInstances) + |> EffectSequence.chain(Hooks.pendingEffects(~lifecycle, Some(hooks))), + nextEffects, + ); +}; + +let outputTreeNodes: type node. opaqueInstance(node) => lazyHostNodeSeq(node) = + (Instance(instance)) => { + switch (instance.leafElement.childrenType) { + | React => instance.wrappedHostNode + | Host => Seq.((() => Cons(instance.wrappedHostNode, () => Nil))) + }; + }; + +module Forest = { + let pendingEffects = pendingEffectsInForest; + + let childNodes = instanceForest => { + let rec inner = (acc, instanceForest) => + switch (instanceForest) { + | CoreTypes.IFlat(opaqueInstance) => + let nodes = outputTreeNodes(opaqueInstance) |> List.of_seq; + [nodes, ...acc]; + | INested(l, _) => List.fold_left(inner, acc, l) + | IDiffableSequence(l, _) => Seq.fold_left(inner, acc, l.toSeq()) + }; + + inner([], instanceForest) |> List.flatten |> List.to_seq; + }; +}; diff --git a/lib/Instance.rei b/lib/Instance.rei new file mode 100644 index 0000000..013c6bb --- /dev/null +++ b/lib/Instance.rei @@ -0,0 +1,40 @@ +type opaqueInstanceUpdate('node, 'childNode) = + Update.t('node, 'childNode, CoreTypes.opaqueInstance('childNode)); + +type renderedElement('node, 'childNode) = + Update.t('node, 'childNode, CoreTypes.instanceForest('childNode)); + +let ofOpaqueLeafElement: + ( + ~hostTreeState: Update.hostTreeState('parentNode, 'node), + ~component: CoreTypes.opaqueLeafElement('node) + ) => + opaqueInstanceUpdate('parentNode, 'node); + +let ofList: + ( + ~hostTreeState: Update.hostTreeState('parentNode, 'node), + Element.t('node) + ) => + renderedElement('parentNode, 'node); + +let pendingEffects: + ( + ~lifecycle: Hooks.Effect.lifecycle, + ~nextEffects: EffectSequence.t, + ~instance: CoreTypes.instance(_) + ) => + EffectSequence.t; + +let outputTreeNodes: + CoreTypes.opaqueInstance('node) => CoreTypes.lazyHostNodeSeq('node); + +module Forest: { + let pendingEffects: + (~lifecycle: Hooks.Effect.lifecycle, CoreTypes.instanceForest(_)) => + EffectSequence.t; + + let childNodes: + CoreTypes.instanceForest('childNode) => + CoreTypes.lazyHostNodeSeq('childNode); +}; diff --git a/lib/Reconciler.re b/lib/Reconciler.re new file mode 100644 index 0000000..a3ebc03 --- /dev/null +++ b/lib/Reconciler.re @@ -0,0 +1,586 @@ +open CoreTypes; + +module MockImplementationValues = { + let zero = 0; + let calculateIndex = (~oldIndex) => oldIndex; + let noChildren = Seq.empty; +}; + +type subtreeUpdate('node) = + | MatchingSubtree(list(subtreeUpdate('node))) + | Update(opaqueInstance('node), opaqueLeafElement('node)) + | ReplaceOrMove({ + prevForest: instanceForest('node), + nextElement: element('node), + }) + | UpdateSequence( + dynamicElement('node, instanceForest('node)), + dynamicElement('node, element('node)), + ) + | UpdateMovable( + subtreeUpdate('node), + ref(option(movableElementState('node))), + ); + +type context('node, 'childNode) = { + shouldExecutePendingUpdates: bool, + hostTreeState: Update.hostTreeState('node, 'childNode), + calculateIndex: (~oldIndex: int) => int, +}; + +let rec prepareUpdate = (~oldInstanceForest, ~nextElement) => { + switch (oldInstanceForest, nextElement) { + | (IFlat(instance), Leaf(component)) => Update(instance, component) + | (INested(instances, _), StaticList(elements)) + when List.length(instances) == List.length(elements) => + MatchingSubtree( + List.map2( + (inst, elem) => + prepareUpdate(~oldInstanceForest=inst, ~nextElement=elem), + instances, + elements, + ), + ) + | (IDiffableSequence(instances, _), DiffableSequence(elements)) => + UpdateSequence(instances, elements) + | ( + prevForest, + Movable(element, {contents: Some({instanceForest})} as ref), + ) => + if (instanceForest === prevForest) { + UpdateMovable( + prepareUpdate(~oldInstanceForest, ~nextElement=element), + ref, + ); + } else { + ReplaceOrMove({prevForest, nextElement}); + } + | (prevForest, nextElement) => ReplaceOrMove({prevForest, nextElement}) + }; +}; + +/** + * Initial render of an Element. Recurses to produce the entire tree of + * instances. + */ +let renderElement: + type parentNode node. + (~updateContext: context(parentNode, node), opaqueLeafElement(node)) => + Instance.opaqueInstanceUpdate(parentNode, node) = + (~updateContext, opaqueLeafElement) => + Instance.ofOpaqueLeafElement( + ~hostTreeState=updateContext.hostTreeState, + ~component=opaqueLeafElement, + ); + +let renderReactElement: + type parentNode node. + (~updateContext: context(parentNode, node), element(node)) => + Instance.renderedElement(parentNode, node) = + (~updateContext, element) => + Element.fold( + ~f= + (~hostTreeState, ~component) => { + renderElement( + ~updateContext={...updateContext, hostTreeState}, + component, + ) + }, + ~init=updateContext.hostTreeState, + element, + ); + +let replaceInstanceForest = (~updateContext, ~oldInstanceForest, ~nextElement) => { + let {Update.nodeElement, nearestHostNode, absoluteSubtreeIndex} = + updateContext.hostTreeState; + memoizeTheIndexShiftForOldInstanceForestSomewhereSoThatWeCanGoBackToItIfItWasAMovableAndMoveIt( + renderReactElement( + ~updateContext={ + ...updateContext, + hostTreeState: { + nodeElement, + nearestHostNode /* lazy( SubtreeChange.deleteNodes( ~nodeElement, ~parent=Lazy.force(nearestHostNode), ~children=Instance.Forest.childNodes(oldInstanceForest), ~position=absoluteSubtreeIndex, ) ) */, + + absoluteSubtreeIndex: MockImplementationValues.zero, + }, + }, + nextElement, + ), + ) + |> Update.mapEffects(mountEffects => + EffectSequence.chain( + Instance.Forest.pendingEffects( + ~lifecycle=Hooks.Effect.Unmount, + oldInstanceForest, + ), + mountEffects, + ) + ); +}; + + +let rec updateOpaqueInstance: + type node parentNode. + ( + ~updateContext: context(parentNode, node), + opaqueInstance(node), + opaqueLeafElement(node) + ) => + Instance.opaqueInstanceUpdate(parentNode, node) = + ( + ~updateContext, + Instance(instance) as originalOpaqueInstance, + OpaqueLeafElement(nextLeafElement) as nextOpaqueLeafElement, + ) => { + let nextState = + updateContext.shouldExecutePendingUpdates + ? Hooks.flushPendingStateUpdates(instance.hooks) : instance.hooks; + let stateChanged = nextState !== instance.hooks; + + let bailOut = + !stateChanged && instance.opaqueLeafElement === nextOpaqueLeafElement; + + if (bailOut && !updateContext.shouldExecutePendingUpdates) { + { + hostTreeUpdate: updateContext.hostTreeState, + payload: originalOpaqueInstance, + enqueuedEffects: EffectSequence.noop, + childNodes: Instance.outputTreeNodes(originalOpaqueInstance), + }; + } else { + let {leafElement} = instance; + switch ( + nextLeafElement.eq( + {...instance, hooks: nextState}, + leafElement.id, + nextLeafElement.id, + ) + ) { + /* + * Case A: The next element *is* of the same component class. + */ + | Some(handedInstance) => + let { + Update.hostTreeUpdate, + payload: newOpaqueInstance, + enqueuedEffects, + } as ret = + updateInstance( + ~originalOpaqueInstance, + ~updateContext, + ~nextLeafElement, + ~nextOpaqueLeafElement, + ~stateChanged, + handedInstance, + ); + newOpaqueInstance === originalOpaqueInstance + ? ret + : { + hostTreeUpdate: { + nodeElement: hostTreeUpdate.nodeElement, + nearestHostNode: + SubtreeChange.updateNodes( + ~nodeElement=hostTreeUpdate.nodeElement, + ~parent=hostTreeUpdate.nearestHostNode, + ~children=Instance.outputTreeNodes(newOpaqueInstance), + ~position=hostTreeUpdate.absoluteSubtreeIndex, + ), + absoluteSubtreeIndex: hostTreeUpdate.absoluteSubtreeIndex, + }, + payload: newOpaqueInstance, + enqueuedEffects, + childNodes: [] |> List.to_seq, + }; + /* + * Case B: The next element is *not* of the same component class. We know + * because otherwise we would have observed the mutation on + * `nextComponentClass`. + */ + | None => + /** + * ** Switching component type ** + */ + let update = + Instance.ofOpaqueLeafElement( + ~hostTreeState=updateContext.hostTreeState, + ~component=nextOpaqueLeafElement, + ) + |> Update.mapEffects(mountEffects => + Instance.pendingEffects( + ~lifecycle=Hooks.Effect.Unmount, + ~nextEffects=mountEffects, + ~instance, + ) + ); + let childNodes = Instance.outputTreeNodes(update.payload); + let {hostTreeState} = updateContext; + { + hostTreeUpdate: { + nodeElement: hostTreeState.nodeElement, + nearestHostNode: + SubtreeChange.replaceSubtree( + ~nodeElement=hostTreeState.nodeElement, + ~parent=hostTreeState.nearestHostNode, + ~prevChildren= + Instance.outputTreeNodes(originalOpaqueInstance), + ~nextChildren=childNodes, + ~absoluteSubtreeIndex= + updateContext.hostTreeState.absoluteSubtreeIndex, + ), + absoluteSubtreeIndex: MockImplementationValues.zero, + }, + payload: update.payload, + enqueuedEffects: update.enqueuedEffects, + childNodes, + }; + }; + }; + } + +and updateInstance: + type hooks node children childNode wrappedHostNode parentNode. + ( + ~originalOpaqueInstance: opaqueInstance(node), + ~updateContext: context(parentNode, node), + ~nextLeafElement: leafElement( + ( + hooks, + (node, children, childNode, wrappedHostNode), + ), + ), + ~nextOpaqueLeafElement: opaqueLeafElement(node), + ~stateChanged: bool, + instance((hooks, (node, children, childNode, wrappedHostNode))) + ) => + Instance.opaqueInstanceUpdate(parentNode, node) = + ( + ~originalOpaqueInstance, + ~updateContext, + ~nextLeafElement, + ~nextOpaqueLeafElement, + ~stateChanged, + instance, + ) => { + let updatedInstanceWithNewElement = { + ...instance, + leafElement: nextLeafElement, + opaqueLeafElement: nextOpaqueLeafElement, + }; + + let shouldRerender = + stateChanged || nextOpaqueLeafElement !== instance.opaqueLeafElement; + + let (nextSubElements, initialHooks) = + if (shouldRerender) { + let (nextElement, initialHooks) = + nextLeafElement.render( + Hooks.ofState( + Some(updatedInstanceWithNewElement.hooks), + ~onStateDidChange=GlobalState.callStaleHandlers, + ), + ); + (nextElement, Hooks.toState(initialHooks)); + } else { + (instance.children_, instance.hooks); + }; + + let updatedInstanceWithNewState = { + ...updatedInstanceWithNewElement, + hooks: initialHooks, + }; + + let {childInstances} = updatedInstanceWithNewState; + let ( + nearestHostNode: lazyHostNode(parentNode), + updatedInstanceWithNewSubtree, + enqueuedEffects, + nodeElement: hostNodeElement(parentNode, node), + ) = + switch (nextLeafElement.childrenType) { + | React => + let {Update.payload: nextInstanceSubForest, enqueuedEffects} = + reconcile( + ~updateContext, + ~oldInstanceForest=childInstances, + ~nextElement=nextSubElements, + (), + ); + nextInstanceSubForest !== childInstances + ? ( + updateContext.hostTreeState.nearestHostNode, + { + ...updatedInstanceWithNewState, + children_: nextSubElements, + childInstances: nextInstanceSubForest, + }: + instance( + (hooks, (node, children, childNode, wrappedHostNode)), + ), + enqueuedEffects, + updateContext.hostTreeState.nodeElement, + ) + : ( + updateContext.hostTreeState.nearestHostNode, + updatedInstanceWithNewState, + enqueuedEffects, + updateContext.hostTreeState.nodeElement, + ); + | Host => + let instanceWithNewHostView: + instance((hooks, (node, children, childNode, wrappedHostNode))) = + shouldRerender + ? { + ...updatedInstanceWithNewState, + wrappedHostNode: + lazy({ + let instance = + Lazy.force(updatedInstanceWithNewState.wrappedHostNode); + let Node(beforeUpdate) | UpdatedNode(_, beforeUpdate) = instance; + let afterUpdate = + nextSubElements.configureInstance( + ~isFirstRender=false, + beforeUpdate, + ); + afterUpdate === beforeUpdate + ? instance : UpdatedNode(beforeUpdate, afterUpdate); + }), + } + : updatedInstanceWithNewState; + + let { + Update.hostTreeUpdate, + payload: nextInstanceSubForest, + enqueuedEffects, + } = { + reconcile( + ~updateContext={ + calculateIndex: MockImplementationValues.calculateIndex, + shouldExecutePendingUpdates: + updateContext.shouldExecutePendingUpdates, + hostTreeState: { + absoluteSubtreeIndex: 0, + nearestHostNode: ( + instanceWithNewHostView.wrappedHostNode: lazyHostNode(node) + ), + nodeElement: ( + instanceWithNewHostView.children_: + hostNodeElement(node, childNode) + ), + }, + }, + ~oldInstanceForest=childInstances, + ~nextElement=nextSubElements.children, + (), + ); + }; + if (nextInstanceSubForest !== instanceWithNewHostView.childInstances) { + ( + updateContext.hostTreeState.nearestHostNode, + { + ...instanceWithNewHostView, + childInstances: nextInstanceSubForest, + children_: nextSubElements, + wrappedHostNode: hostTreeUpdate.nearestHostNode, + }: + instance( + (hooks, (node, children, childNode, wrappedHostNode)), + ), + enqueuedEffects, + updateContext.hostTreeState.nodeElement, + ); + } else { + ( + updateContext.hostTreeState.nearestHostNode, + instanceWithNewHostView, + enqueuedEffects, + updateContext.hostTreeState.nodeElement, + ); + }; + }; + let hostTreeUpdate = { + Update.nodeElement, + nearestHostNode, + absoluteSubtreeIndex: 0, + }; + if (updatedInstanceWithNewSubtree === updatedInstanceWithNewElement + && !stateChanged) { + { + hostTreeUpdate, + payload: originalOpaqueInstance, + enqueuedEffects, + childNodes: MockImplementationValues.noChildren, + }; + } else { + { + hostTreeUpdate, + payload: Instance(updatedInstanceWithNewSubtree), + enqueuedEffects: + EffectSequence.chain( + Hooks.pendingEffects( + ~lifecycle=Hooks.Effect.Update, + Some(updatedInstanceWithNewSubtree.hooks), + ), + enqueuedEffects, + ), + childNodes: MockImplementationValues.noChildren, + }; + }; + } + +and applyUpdate: + type node childNode. + (~updateContext: context(node, childNode), subtreeUpdate(childNode)) => + Update.t(node, childNode, instanceForest(childNode)) = + (~updateContext, update) => { + switch (update) { + | MatchingSubtree(updates) => + let update = + List.fold_left( + (updateAcc: Update.t(_, _, _), subtreeUpdate) => { + let update = + applyUpdate( + ~updateContext={ + calculateIndex: MockImplementationValues.calculateIndex, + hostTreeState: updateAcc.Update.hostTreeUpdate, + shouldExecutePendingUpdates: + updateContext.shouldExecutePendingUpdates, + }, + subtreeUpdate, + ); + // TODO: Don't forget about effects... + update + |> Update.map(updatedInstanceForest => + [updatedInstanceForest, ...updateAcc.payload] + ); + }, + { + Update.payload: [], + hostTreeUpdate: updateContext.hostTreeState, + enqueuedEffects: EffectSequence.noop, + childNodes: Seq.empty, + }, + List.rev(updates), + ); + update + |> Update.map(instances => + INested( + instances, + update.Update.hostTreeUpdate.absoluteSubtreeIndex + - updateContext.hostTreeState.absoluteSubtreeIndex, + ) + ); + | Update(instance, newComponent) => + updateOpaqueInstance(~updateContext, instance, newComponent) + |> Update.map(instance => IFlat(instance)) + | UpdateSequence(instances, elements) => + instances.diff(elements) + |> Seq.fold_left( + (acc, change) => + switch (change) { + | Updated(oldInstanceForest, nextElement) => + applyUpdate( + ~updateContext={ + calculateIndex: MockImplementationValues.calculateIndex, + hostTreeState: acc.Update.hostTreeUpdate, + shouldExecutePendingUpdates: + updateContext.shouldExecutePendingUpdates, + }, + prepareUpdate(~oldInstanceForest, ~nextElement), + ) + |> Update.map(instanceForest => + acc.payload.insert(instanceForest) + ) + | Added(element) => + renderReactElement(~updateContext, element) + |> Update.map(instanceForest => + acc.payload.insert(instanceForest) + ) + | Removed(_instance) => acc + }, + { + Update.payload: instances, + hostTreeUpdate: updateContext.hostTreeState, + enqueuedEffects: EffectSequence.noop, + childNodes: Seq.empty, + }, + ) + |> Update.map(instances => + IDiffableSequence(instances, MockImplementationValues.zero) + ) + | UpdateMovable(update, ref) => + let updated = applyUpdate(~updateContext, update); + ref := Some(updated.payload); + updated; + | ReplaceOrMove({prevForest, nextElement}) => + /* At this point we know the index in the tree */ + /* If we've already gone through the element we wanted to move it might already be unmounted */ + /* We should unmount all elements at the end */ + /* Index of nextElement if it's movable for moves */ + /* Procedure on every element: + 1. Memoize prevForest in toRemove field (don't remove them yet) + 2. Mount nextElement + - If it's movable on a bigger index - move it from there (take current shift into account) + - If it's moveable on a smaller index - move it from there and remove from toRemove (adjust current shift) + - Else simply render and adjust current shift + */ + replaceInstanceForest( + ~updateContext, + ~oldInstanceForest=prevForest, + ~nextElement, + ) + }; + } + +and reconcile: + type parentNode node. + ( + ~updateContext: context(parentNode, node), + ~oldInstanceForest: instanceForest(node), + ~nextElement: element(node), + unit + ) => + Instance.renderedElement(parentNode, node) = + (~updateContext, ~oldInstanceForest, ~nextElement, ()) => { + /* Call cleanup which will remove all elements from toRemove */ + applyUpdate( + ~updateContext, + prepareUpdate(~oldInstanceForest, ~nextElement), + ); + }; + +let reconcile = + ( + ~shouldExecutePendingUpdates, + ~hostTreeState, + ~oldInstanceForest, + ~nextElement, + unit, + ) => + reconcile( + ~updateContext={ + shouldExecutePendingUpdates, + hostTreeState, + calculateIndex: MockImplementationValues.calculateIndex, + }, + ~oldInstanceForest, + ~nextElement, + (), + ); + +let flushPendingUpdates = + (~parentHostNode, ~parentHostNodeElement, ~rootInstance) => { + let Instance({opaqueLeafElement}) = rootInstance; + updateOpaqueInstance( + ~updateContext={ + calculateIndex: MockImplementationValues.calculateIndex, + shouldExecutePendingUpdates: true, + hostTreeState: { + nearestHostNode: parentHostNode, + nodeElement: parentHostNodeElement, + absoluteSubtreeIndex: 0, + }, + }, + rootInstance, + opaqueLeafElement, + ); +}; diff --git a/lib/Reconciler.rei b/lib/Reconciler.rei new file mode 100644 index 0000000..78a5273 --- /dev/null +++ b/lib/Reconciler.rei @@ -0,0 +1,21 @@ +let reconcile: + ( + ~shouldExecutePendingUpdates: bool, + ~hostTreeState: Update.hostTreeState('parentNode, 'node), + ~oldInstanceForest: CoreTypes.instanceForest('node), + ~nextElement: CoreTypes.element('node), + unit + ) => + Instance.renderedElement('parentNode, 'node); + +/** + * Execute the pending updates at the top level of an instance tree. + * If no state change is performed, the argument is returned unchanged. + */ +let flushPendingUpdates: + ( + ~parentHostNode: CoreTypes.lazyHostNode('parentNode), + ~parentHostNodeElement: CoreTypes.hostNodeElement('parentNode, 'node), + ~rootInstance: CoreTypes.opaqueInstance('node) + ) => + Update.t('parentNode, 'node, CoreTypes.opaqueInstance('node)); diff --git a/lib/RenderedElement.re b/lib/RenderedElement.re new file mode 100644 index 0000000..0a503fd --- /dev/null +++ b/lib/RenderedElement.re @@ -0,0 +1,143 @@ +open CoreTypes; + +/** + * Rendering produces a list of instance trees. + */ +type t('node, 'childNode) = Instance.renderedElement('node, 'childNode); +type root('node, 'childNode) = { + node: 'node, + insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + moveNode: + (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, +}; + +let render = (root, children) => { + let hostTreeState = { + Update.nodeElement: { + make: () => root.node, + configureInstance: (~isFirstRender as _, i) => i, + children, + insertNode: root.insertNode, + deleteNode: root.deleteNode, + moveNode: root.moveNode, + }, + nearestHostNode: lazy(Node(root.node)), + absoluteSubtreeIndex: 0, + }; + Instance.ofList(~hostTreeState, children); +}; + +let update = + (~renderedElement as {Update.payload, hostTreeUpdate}, nextElement) => + Reconciler.reconcile( + ~updateContext= + Update.{ + hostTreeState: hostTreeUpdate, + shouldExecutePendingUpdates: false, + }, + ~oldInstanceForest=payload, + ~nextElement, + (), + ); + +let rec map = (f, renderedElement, nearestHostNode, nodeElement) => + switch (renderedElement) { + | IFlat(e) => + let {Update.hostTreeUpdate, payload: opaqueInstance, enqueuedEffects} = + f(e, nearestHostNode, nodeElement); + let unchanged = e === opaqueInstance; + + { + Update.hostTreeUpdate, + payload: unchanged ? renderedElement : IFlat(opaqueInstance), + enqueuedEffects, + childNodes: Seq.empty, + }; + | INested(l, _) => + let update = + List.fold_left( + (acc, renderedElement) => { + let update = map(f, renderedElement, nearestHostNode, nodeElement); + { + ...update |> Update.map(next => [next, ...acc.Update.payload]), + enqueuedEffects: + EffectSequence.chain( + acc.enqueuedEffects, + update.enqueuedEffects, + ), + }; + }, + { + Update.payload: [], + hostTreeUpdate: { + nearestHostNode, + nodeElement, + absoluteSubtreeIndex: 0, + }, + enqueuedEffects: EffectSequence.noop, + childNodes: Seq.empty, + }, + List.rev(l), + ); + let unchanged = List.for_all2((===), l, update.payload); + + update + |> Update.map(nextL => + unchanged + ? renderedElement + : INested(nextL, update.hostTreeUpdate.absoluteSubtreeIndex) + ); + | IDiffableSequence(instances, _l) => + instances.toSeq() + |> Seq.fold_left( + (acc, _instance) => {acc}, + { + Update.payload: instances, + hostTreeUpdate: { + nearestHostNode, + nodeElement, + absoluteSubtreeIndex: 0, + }, + enqueuedEffects: EffectSequence.noop, + childNodes: Seq.empty, + }, + ) + |> Update.map(instances => IDiffableSequence(instances, 0)) + }; + +/** + * Flush the pending updates in an instance tree. + */ +let flushPendingUpdates = + ({Update.payload: instanceForest, hostTreeUpdate, enqueuedEffects}) => { + let update = + map( + (rootInstance, parentHostNode, parentHostNodeElement) => + Reconciler.flushPendingUpdates( + ~parentHostNode, + ~parentHostNodeElement, + ~rootInstance, + ), + instanceForest, + hostTreeUpdate.nearestHostNode, + hostTreeUpdate.nodeElement, + ); + { + ...update, + enqueuedEffects: + EffectSequence.chain(update.enqueuedEffects, enqueuedEffects), + }; +}; + +let executeHostViewUpdates = + ({Update.hostTreeUpdate: {nearestHostNode}}: t(_, _)) => { + let Node(hostView) | UpdatedNode(_, hostView) = + Lazy.force(nearestHostNode); + hostView; +}; + +let executePendingEffects = ({enqueuedEffects} as renderedElement: t(_, _)) => { + enqueuedEffects(); + {...renderedElement, enqueuedEffects: EffectSequence.noop}; +}; diff --git a/lib/RenderedElement.rei b/lib/RenderedElement.rei new file mode 100644 index 0000000..8344dd9 --- /dev/null +++ b/lib/RenderedElement.rei @@ -0,0 +1,17 @@ +type t('node, 'childNode) = Instance.renderedElement('node, 'childNode); +type root('node, 'childNode) = { + node: 'node, + insertNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + deleteNode: (~parent: 'node, ~child: 'childNode, ~position: int) => 'node, + moveNode: + (~parent: 'node, ~child: 'childNode, ~from: int, ~to_: int) => 'node, +}; + +let render: + (root('node, 'childNode), Element.t('childNode)) => t('node, 'childNode); +let update: + (~renderedElement: t('rootNode, 'node), Element.t('node)) => + t('rootNode, 'node); +let executePendingEffects: t('a, 'b) => t('a, 'b); +let executeHostViewUpdates: t('node, _) => 'node; +let flushPendingUpdates: t('a, 'b) => t('a, 'b); diff --git a/lib/SubtreeChange.re b/lib/SubtreeChange.re new file mode 100644 index 0000000..031560c --- /dev/null +++ b/lib/SubtreeChange.re @@ -0,0 +1,184 @@ +open CoreTypes; + +let insertNodes = + ( + ~nodeElement, + ~parent as parentWrapper, + ~children, + ~position as initialPosition: int, + ) => { + let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; + let newParent = + Seq.fold_left( + ((position, parent), child) => + ( + position + 1, + { + let Node(child) | UpdatedNode(_, child) = Lazy.force(child); + nodeElement.insertNode(~parent, ~child, ~position); + }, + ), + (initialPosition, oldParent), + children, + ) + |> snd; + newParent === oldParent ? parentWrapper : UpdatedNode(oldParent, newParent); +}; +let deleteNodes = + ( + ~nodeElement, + ~parent as parentWrapper, + ~children, + ~position as initialPosition: int, + ) => { + let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; + let newParent = + Seq.fold_left( + ((position, parent), child) => + ( + position + 1, + { + let Node(child) | UpdatedNode(_, child) = Lazy.force(child); + nodeElement.deleteNode(~parent, ~child, ~position); + }, + ), + (initialPosition, oldParent), + children, + ) + |> snd; + newParent === oldParent ? parentWrapper : UpdatedNode(oldParent, newParent); +}; + +let replaceSubtree = + ( + ~nodeElement, + ~parent, + ~prevChildren, + ~nextChildren, + ~absoluteSubtreeIndex: int, + ) => + lazy( + { + insertNodes( + ~nodeElement, + ~parent= + deleteNodes( + ~nodeElement, + ~parent=Lazy.force(parent), + ~children=prevChildren, + ~position=absoluteSubtreeIndex, + ), + ~children=nextChildren, + ~position=absoluteSubtreeIndex, + ); + } + ); + +let reorderNode = + (~nodeElement, ~child, ~parent, ~indexShift: int, ~from: int, ~to_: int) => { + let isVal = Lazy.is_val(child); + switch (Lazy.force(child)) { + | Node(child) => + from === to_ - indexShift + ? parent : nodeElement.moveNode(~parent, ~child, ~from, ~to_) + | UpdatedNode(prevChild, child) when !isVal => + nodeElement.insertNode( + ~parent= + nodeElement.deleteNode(~parent, ~child=prevChild, ~position=from), + ~child, + ~position=to_, + ) + | UpdatedNode(_prevChild, child) => + from === to_ - indexShift + ? parent : nodeElement.moveNode(~parent, ~child, ~from, ~to_) + }; +}; + +let reorder = + ( + type node, + type childNode, + ~nodeElement, + ~parent: lazyHostNode(node), + ~instance as + Instance({wrappedHostNode, leafElement: {childrenType}}): + opaqueInstance(childNode), + ~indexShift, + ~from, + ~to_, + ) => + switch (childrenType) { + | Host => + lazy({ + let parentWrapper = Lazy.force(parent); + let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; + let newParent = + reorderNode( + ~nodeElement, + ~parent=oldParent, + ~child=wrappedHostNode, + ~indexShift, + ~from, + ~to_, + ); + newParent === oldParent + ? parentWrapper : UpdatedNode(oldParent, newParent); + }) + | React => + lazy({ + let parentWrapper = Lazy.force(parent); + let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; + let newParent = + Seq.fold_left( + ((index, parent), child) => + ( + index + 1, + reorderNode( + ~nodeElement, + ~parent, + ~child, + ~indexShift, + ~from=from + index, + ~to_=to_ + index, + ), + ), + (0, oldParent), + wrappedHostNode, + ) + |> snd; + newParent === oldParent + ? parentWrapper : UpdatedNode(oldParent, newParent); + }) + }; +let updateNodes = + (~nodeElement, ~parent, ~children, ~position as initialPosition) => + lazy({ + let parentWrapper = Lazy.force(parent); + let Node(oldParent) | UpdatedNode(_, oldParent) = parentWrapper; + let newParent = + Seq.fold_left( + ((position, instance), x) => + ( + position + 1, + switch (Lazy.force(x)) { + | Node(_child) => instance + | UpdatedNode(oldNode, newNode) => + nodeElement.insertNode( + ~parent= + nodeElement.deleteNode( + ~parent=instance, + ~child=oldNode, + ~position, + ), + ~child=newNode, + ~position, + ) + }, + ), + (initialPosition, oldParent), + children, + ) + |> snd; + newParent === oldParent + ? parentWrapper : UpdatedNode(oldParent, newParent); + }); diff --git a/lib/SubtreeChange.rei b/lib/SubtreeChange.rei new file mode 100644 index 0000000..82cca83 --- /dev/null +++ b/lib/SubtreeChange.rei @@ -0,0 +1,47 @@ +let insertNodes: + ( + ~nodeElement: CoreTypes.hostNodeElement('node, 'children), + ~parent: CoreTypes.hostNode('node), + ~children: CoreTypes.lazyHostNodeSeq('children), + ~position: int + ) => + CoreTypes.hostNode('node); + +let deleteNodes: + ( + ~nodeElement: CoreTypes.hostNodeElement('node, 'children), + ~parent: CoreTypes.hostNode('node), + ~children: CoreTypes.lazyHostNodeSeq('children), + ~position: int + ) => + CoreTypes.hostNode('node); + +let updateNodes: + ( + ~nodeElement: CoreTypes.hostNodeElement('node, 'children), + ~parent: CoreTypes.lazyHostNode('node), + ~children: CoreTypes.lazyHostNodeSeq('children), + ~position: int + ) => + CoreTypes.lazyHostNode('node); + +let replaceSubtree: + ( + ~nodeElement: CoreTypes.hostNodeElement('node, 'children), + ~parent: CoreTypes.lazyHostNode('node), + ~prevChildren: CoreTypes.lazyHostNodeSeq('children), + ~nextChildren: CoreTypes.lazyHostNodeSeq('children), + ~absoluteSubtreeIndex: int + ) => + CoreTypes.lazyHostNode('node); + +let reorder: + ( + ~nodeElement: CoreTypes.hostNodeElement('node, 'children), + ~parent: CoreTypes.lazyHostNode('node), + ~instance: CoreTypes.opaqueInstance('children), + ~indexShift: int, + ~from: int, + ~to_: int + ) => + CoreTypes.lazyHostNode('node); diff --git a/lib/Update.re b/lib/Update.re new file mode 100644 index 0000000..b0d2f8b --- /dev/null +++ b/lib/Update.re @@ -0,0 +1,24 @@ +open CoreTypes; + +type hostTreeState('node, 'childNode) = { + nearestHostNode: lazyHostNode('node), + nodeElement: hostNodeElement('node, 'childNode), + /* This is a unique index of an element within a subtree, + * thanks to tracking it we can efficiently manage moves of within a subtree + */ + absoluteSubtreeIndex: int, +}; +type t('node, 'childNode, 'payload) = { + hostTreeUpdate: hostTreeState('node, 'childNode), + enqueuedEffects: EffectSequence.t, + payload: 'payload, + childNodes: lazyHostNodeSeq('childNode), +}; +let map = (f, update) => { + let {payload, hostTreeUpdate, enqueuedEffects, childNodes} = update; + {hostTreeUpdate, enqueuedEffects, payload: f(payload), childNodes}; +}; +let mapEffects = (f, update) => { + let {payload, hostTreeUpdate, enqueuedEffects, childNodes} = update; + {hostTreeUpdate, enqueuedEffects: f(enqueuedEffects), payload, childNodes}; +}; diff --git a/lib/Update.rei b/lib/Update.rei new file mode 100644 index 0000000..99303b4 --- /dev/null +++ b/lib/Update.rei @@ -0,0 +1,22 @@ +open CoreTypes; + +type hostTreeState('node, 'childNode) = { + nearestHostNode: lazyHostNode('node), + nodeElement: hostNodeElement('node, 'childNode), + /* This is a unique index of an element within a subtree, + * thanks to tracking it we can efficiently manage moves of within a subtree + */ + absoluteSubtreeIndex: int, +}; + +type t('node, 'childNode, 'payload) = { + hostTreeUpdate: hostTreeState('node, 'childNode), + enqueuedEffects: EffectSequence.t, + payload: 'payload, + childNodes: lazyHostNodeSeq('childNode), +}; + +let map: ('a => 'b, t('node, 'childNode, 'a)) => t('node, 'childNode, 'b); +let mapEffects: + (EffectSequence.t => EffectSequence.t, t('node, 'childNode, 'payload)) => + t('node, 'childNode, 'payload); diff --git a/package.json b/package.json index 5b74a77..3121016 100644 --- a/package.json +++ b/package.json @@ -14,17 +14,16 @@ "build:ppx": "dune build -p brisk_ppx" }, "dependencies": { - "@esy-ocaml/reason": ">=3.4.0", - "@opam/dune": "^1.7.3", - "@opam/ppxlib": "0.8.1", + "@esy-ocaml/reason": "*", + "@opam/dune": "*", + "@opam/ppxlib": "*", "ocaml": ">=4.4.0" }, "devDependencies": { "ocaml": "~4.8.0", - "@opam/merlin": "^3.2.2", - "@opam/merlin-lsp": "ocaml/merlin:merlin-lsp.opam#c8b0f03", - "@opam/ppx_deriving": "^4.2.1", - "@opam/ocamlformat": "0.12", - "@reason-native/rely": "^3.1.0" + "@opam/ocaml-lsp-server": "ocaml/ocaml-lsp:ocaml-lsp-server.opam", + "@opam/ppx_deriving": "*", + "@opam/ocamlformat": "*", + "@reason-native/rely": "*" } } diff --git a/test/Components.re b/test/Components.re index 5d21da5..dbedbca 100644 --- a/test/Components.re +++ b/test/Components.re @@ -1,5 +1,4 @@ open TestReconciler; -module Brisk_reconciler = Brisk_reconciler__Brisk_reconciler_internal; open Brisk_reconciler; /** @@ -89,26 +88,15 @@ module BoxWrapper = { ); }; -/** - * Box with dynamic keys. - */ -module BoxItemDynamic = { - [@component useDynamicKey] - let make = (~title="ImABox", (), h) => (stringToElement(title), h); -}; - module BoxList = { type action = | Create(string) | Reverse; - let%component make = (~rAction, ~useDynamicKeys=false, ()) => { + let%component make = (~rAction, ()) => { let%hook (state, dispatch) = Hooks.reducer(~initialState=[], (action, state) => switch (action) { - | Create(title) => [ - useDynamicKeys ? : , - ...state, - ] + | Create(title) => [, ...state] | Reverse => List.rev(state) } ); diff --git a/test/Test.re b/test/Test.re index fadc34b..4ac86d4 100644 --- a/test/Test.re +++ b/test/Test.re @@ -1,7 +1,7 @@ open TestFramework; open TestReconciler; open TestHelpers; -open Brisk_reconciler__Brisk_reconciler_internal; +open Brisk_reconciler; let root = {name: "root", element: View}; let div = {name: "Div", element: View}; @@ -66,21 +66,17 @@ describe("Test replacing subtree", ({test}) => { }) }); -describe("Test top level reorder", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); +let%component topLevelReorder = (~flipped=false, ()) => { + open Components; + let%hook text1 = + ; + let%hook text2 = + ; + flipped ? <> : <> ; +}; - let state = - ref( - render( - listToElement( - Components.[ - , - , - ], - ), - ), - ); +describe("Test top level reorder", ({test}) => { + let state = ref(render()); test("It correctly constructs initial tree", ({expect}) => { state := state^ |> executeSideEffects; @@ -98,14 +94,7 @@ describe("Test top level reorder", ({test}) => { test("It reorders only one element", ({expect}) => { let mountLog = state^ - |> update( - listToElement( - Components.[ - , - , - ], - ), - ) + |> update() |> executeSideEffects |> getMountLogAndReset; @@ -113,11 +102,17 @@ describe("Test top level reorder", ({test}) => { }); }); -describe("Test top level replace elements", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); +let%component topLevelReplace = (~switched=false, ()) => { + open Components; + let%hook text1 = + ; + let%hook text2 = + ; + switched ? : ; +}; - let state = ref(render()); +describe("Test top level replace elements", ({test}) => { + let state = ref(render()); test("It constructs initial tree", ({expect}) => { state := state^ |> executeSideEffects; @@ -132,7 +127,7 @@ describe("Test top level replace elements", ({test}) => { test("It replaces text(x) with text(y)", ({expect}) => { let mountLog = state^ - |> update() + |> update() |> executeSideEffects |> getMountLogAndReset; @@ -225,43 +220,6 @@ describe("Test subtree replace elements", ({test}) => { }); }); -describe("Test top level prepend", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); - let commonElement = []; - - let state = ref(render(listToElement(commonElement))); - - test("It constructs initial tree", ({expect}) => { - state := state^ |> executeSideEffects; - - let mountLog = state |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("x", "x"), - MountChild(root, text("x"), 0), - ]); - }); - - test("It correctly mounts prepend topLevelUpdate", ({expect}) => { - let mountLog = - state^ - |> update( - listToElement([ - , - ...commonElement, - ]), - ) - |> executeSideEffects - |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("y", "y"), - MountChild(root, text("y"), 0), - ]); - }); -}); - describe("Test simple subtree change", ({test}) => { let state = ref(render()); @@ -300,9 +258,7 @@ describe("Test changing components", ({test}) => { expect.list(mountLog).toEqual([]); }); - test( - "It changes from EmptyComponent to ButtonWrapperWrapper", - ({expect}) => { + test("It changes from EmptyComponent to ButtonWrapperWrapper", ({expect}) => { state := state^ |> update( @@ -335,65 +291,7 @@ describe("Test changing components", ({test}) => { }); }); -describe("Test BoxList with dynamic keys", ({test}) => { - let rAction = RemoteAction.create(); - let state = - ref( - render() - |> executeSideEffects, - ); - - test("It renders an empty list", ({expect}) => { - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([]); - }); - - test("It inserts one item", ({expect}) => { - state := - state^ - |> act(~action=Components.BoxList.Create("Hello"), rAction) - |> flushPendingUpdates - |> executeSideEffects; - - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("Hello", "Hello"), - MountChild(root, text("Hello"), 0), - ]); - }); - - test("It prepends one more BoxItem and then flushes", ({expect}) => { - state := - state^ - |> act(~action=Components.BoxList.Create("World"), rAction) - |> flushPendingUpdates - |> executeSideEffects; - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("World", "World"), - MountChild(root, text("World"), 0), - ]); - }); - - test("It reverses the items list in the BoxList", ({expect}) => { - state := - state^ - |> act(~action=Components.BoxList.Reverse, rAction) - |> flushPendingUpdates - |> executeSideEffects; - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - RemountChild(root, text("Hello"), 1, 0), - ]); - }); -}); - -describe( - "Test BoxList without dynamic keys", ({test}) => { +describe("Test BoxList", ({test}) => { let rAction = RemoteAction.create(); let state = ref(render() |> executeSideEffects); @@ -444,110 +342,6 @@ describe( }); }); -describe("Test BoxItemDynamic memoizing during deep move", ({test}) => { - let box = ; - - let state = ref(render(box)); - - let beforeUpdate = ref(None); - let afterUpdate = ref(None); - - test("It renders the initial BoxItemDynamic", ({expect}) => { - state := state^ |> executeSideEffects; - let mountLog = state^ |> getMountLogAndReset; - - beforeUpdate := Some(state^.renderedElement.instanceForest); - - expect.list(mountLog).toEqual([ - ChangeText("box to move", "box to move"), - MountChild(root, text("box to move"), 0), - ]); - }); - - test( - "It adds new element before BoxItemDynamic (it replaces the whole tree)", - ({expect}) => { - state := - state^ - |> update( - listToElement([ - Components.stringToElement("before"), - listToElement([box]), - ]), - ) - |> executeSideEffects; - - afterUpdate := Some(state^.renderedElement.instanceForest); - - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - UnmountChild(root, text("box to move")), - ChangeText("before", "before"), - MountChild(root, text("before"), 0), - MountChild(root, text("box to move"), 1), - ]); - }); - - test("It memoized the nested BoxItemDynamic", ({expect}) => { - expect.bool( - switch (beforeUpdate^, afterUpdate^) { - | (Some(IFlat(x)), Some(INested([_, INested([IFlat(y)], _)], _))) => - x === y - | _ => false - }, - ). - toBeTrue() - }); -}); - -describe("Test list updates with static keys", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); - - let state = - ref( - render( - listToElement([ - , - , - ]), - ), - ); - - test("It renders the initial Boxes list", ({expect}) => { - state := state^ |> executeSideEffects; - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - MountChild(root, box("Box1unchanged"), 0), - MountChild(root, box("Box2unchanged"), 1), - ]); - }); - - test("It reorders the list", ({expect}) => { - state := - state^ - |> update( - listToElement([ - , - , - ]), - ) - |> executeSideEffects; - - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - UnmountChild(root, box("Box2unchanged")), - MountChild(root, box("Box2changed"), 1), - RemountChild(root, box("Box2changed"), 1, 0), - UnmountChild(root, box("Box1unchanged")), - MountChild(root, box("Box1changed"), 1), - ]); - }); -}); - describe("Test conditional updating by leveraging refs", ({test}) => { let rAction = RemoteAction.create(); @@ -613,16 +407,10 @@ describe("Test conditional updating by leveraging refs", ({test}) => { }); describe("Test updating with identical element", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); - let state = ref( render( - listToElement([ - , - , - ]), + <> , ), ); @@ -640,77 +428,16 @@ describe("Test updating with identical element", ({test}) => { test( "It updates the state with a new instance of (same) string", ({expect}) => { + open Components; state := state^ - |> update( - listToElement( - Components.[ - , - , - ], - ), - ) + |> update(<> ) |> executeSideEffects; let mountLog = state^ |> getMountLogAndReset; expect.list(mountLog).toEqual([]); }); - - test("It reorders the list", ({expect}) => { - state := - state^ - |> update( - listToElement( - Components.[ - , - , - ], - ), - ) - |> executeSideEffects; - - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([RemountChild(root, text("y"), 1, 0)]); - }); -}); - -describe("Test prepending new element", ({test}) => { - let key1 = Key.create(); - let key2 = Key.create(); - let commonElement = []; - - let state = ref(render(listToElement(commonElement))); - - test("It renders a new Text element", ({expect}) => { - state := state^ |> executeSideEffects; - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("x", "x"), - MountChild(root, text("x"), 0), - ]); - }); - - test("It prepends a new Text element to the list", ({expect}) => { - state := - state^ - |> update( - listToElement([ - , - ...commonElement, - ]), - ) - |> executeSideEffects; - - let mountLog = state^ |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - ChangeText("y", "y"), - MountChild(root, text("y"), 0), - ]); - }); }); describe("Test 'Always' effect", ({test}) => { @@ -940,15 +667,13 @@ describe("Test 'OnMount' effect in extra-nested component", ({test}) => { describe("Test transition from empty list to non-empty list", ({test}) => { test("It mounts IAmBox0+1", ({expect}) => { let state = - render( - Components.(
{listToElement([])}
), - ) + render(Components.(
empty
)) |> executeSideEffects |> reset |> update( Components.(
- {listToElement([])} + <>
), @@ -965,16 +690,14 @@ describe("Test transition from empty list to non-empty list", ({test}) => { test("It mounts IAmBox0+1", ({expect}) => { let state = - render( - Components.(
{listToElement([])}
), - ) + render(Components.(
empty
)) |> executeSideEffects |> reset |> update( Components.(
- {listToElement([])} + <>
), ) @@ -990,26 +713,29 @@ describe("Test transition from empty list to non-empty list", ({test}) => { }); }); +let%component listAndSwitch = (~list, ~switched=false, ()) => { + open Components; + let%hook component = + + {switched ?
: } + ; + +
list
; +}; + describe( "Test transition from empty list to non-empty list & becomes
", ({test}) => { test("IAmBox", ({expect}) => { - let key = Key.create(); let state = - render( - Components.( -
{listToElement([])}
- ), - ) + render() |> executeSideEffects |> reset |> update( - Components.( -
- {listToElement([])} -
-
- ), + ) + switched=true + />, ) |> executeSideEffects; let mountLog = state |> getMountLogAndReset; @@ -1021,28 +747,3 @@ describe( ]); }) }); - -describe( - "Test a with single Flat child, with a changing key", - ({test}) => { - test("It re-mounts the node with the new key", ({expect}) => { - let key1 = Key.create(); - let key2 = Key.create(); - let state = - render( - Components.( ...
), - ) - |> executeSideEffects - |> reset - |> update( - Components.( ...
), - ) - |> executeSideEffects; - let mountLog = state |> getMountLogAndReset; - - expect.list(mountLog).toEqual([ - UnmountChild(singleChildDiv, div), - MountChild(singleChildDiv, div, 0), - ]); - }) -}); diff --git a/test/TestHelpers.re b/test/TestHelpers.re index ac48d04..34d5c36 100644 --- a/test/TestHelpers.re +++ b/test/TestHelpers.re @@ -1,5 +1,5 @@ open TestReconciler; -open Brisk_reconciler__Brisk_reconciler_internal; +open Brisk_reconciler; type testState = { element: element(node), @@ -20,11 +20,10 @@ let reset = x => { x; }; -let update = (nextReactElement, {element: previousElement, renderedElement}) => { +let update = (nextReactElement, {renderedElement}) => { element: nextReactElement, renderedElement: RenderedElement.update( - ~previousElement, ~renderedElement, nextReactElement, ),