From a0b5c93dc7ca93d791b69a7ed4e1e7d42c38b555 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Thu, 3 Apr 2025 22:21:13 +0000 Subject: [PATCH 1/8] working test page of REPL --- package-lock.json | 386 +++++++++++++++++++ package.json | 6 + website/src/JSRepl/Editor.tsx | 53 +++ website/src/JSRepl/JSRepl.css | 34 ++ website/src/JSRepl/JSRepl.tsx | 131 +++++++ website/src/app/docs/[version]/test/page.tsx | 163 ++++++++ 6 files changed, 773 insertions(+) create mode 100644 website/src/JSRepl/Editor.tsx create mode 100644 website/src/JSRepl/JSRepl.css create mode 100644 website/src/JSRepl/JSRepl.tsx create mode 100644 website/src/app/docs/[version]/test/page.tsx diff --git a/package-lock.json b/package-lock.json index c8a9f2df0b..e5c17b8000 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,11 @@ "version": "5.1.1", "license": "MIT", "devDependencies": { + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.3", + "@codemirror/state": "^6.5.2", + "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/view": "^6.36.5", "@eslint/js": "^9.20.0", "@jest/globals": "^29.7.0", "@rollup/plugin-buble": "1.0.3", @@ -22,6 +27,7 @@ "@types/random-seed": "0.3.5", "@types/react": "17.0.11", "benchmark": "2.1.4", + "codemirror": "^6.0.1", "colors": "1.4.0", "cpy-cli": "^5.0.0", "eslint": "^9.20.1", @@ -580,6 +586,122 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@codemirror/autocomplete": { + "version": "6.18.6", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz", + "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", + "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", + "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.36.5", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz", + "integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.5.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, "node_modules/@corex/deepmerge": { "version": "4.0.43", "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz", @@ -1793,6 +1915,52 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.21", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz", + "integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "dev": true, + "license": "MIT" + }, "node_modules/@next/env": { "version": "14.2.26", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.26.tgz", @@ -4105,6 +4273,22 @@ "node": ">= 0.12.0" } }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -4275,6 +4459,13 @@ "dev": true, "license": "MIT" }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -10179,6 +10370,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "dev": true, + "license": "MIT" + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -10820,6 +11018,13 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "dev": true, + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -11517,6 +11722,113 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@codemirror/autocomplete": { + "version": "6.18.6", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "@codemirror/commands": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "@codemirror/lang-javascript": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz", + "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "dev": true, + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "@codemirror/language": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "@codemirror/lint": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", + "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/search": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", + "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "dev": true, + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/state": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "dev": true, + "requires": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dev": true, + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "@codemirror/view": { + "version": "6.36.5", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz", + "integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==", + "dev": true, + "requires": { + "@codemirror/state": "^6.5.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, "@corex/deepmerge": { "version": "4.0.43", "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz", @@ -12265,6 +12577,47 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "dev": true + }, + "@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dev": true, + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/javascript": { + "version": "1.4.21", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz", + "integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", + "dev": true, + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dev": true, + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "dev": true + }, "@next/env": { "version": "14.2.26", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.26.tgz", @@ -13763,6 +14116,21 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, + "codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dev": true, + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, "collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -13887,6 +14255,12 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "dev": true + }, "cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -17951,6 +18325,12 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "dev": true + }, "styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -18359,6 +18739,12 @@ "spdx-expression-parse": "^3.0.0" } }, + "w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "dev": true + }, "w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 81a29d64cb..43a66aaee5 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,11 @@ "trailingComma": "es5" }, "devDependencies": { + "@codemirror/commands": "^6.8.1", + "@codemirror/lang-javascript": "^6.2.3", + "@codemirror/state": "^6.5.2", + "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/view": "^6.36.5", "@eslint/js": "^9.20.0", "@jest/globals": "^29.7.0", "@rollup/plugin-buble": "1.0.3", @@ -96,6 +101,7 @@ "@types/random-seed": "0.3.5", "@types/react": "17.0.11", "benchmark": "2.1.4", + "codemirror": "^6.0.1", "colors": "1.4.0", "cpy-cli": "^5.0.0", "eslint": "^9.20.1", diff --git a/website/src/JSRepl/Editor.tsx b/website/src/JSRepl/Editor.tsx new file mode 100644 index 0000000000..a7d442c0e3 --- /dev/null +++ b/website/src/JSRepl/Editor.tsx @@ -0,0 +1,53 @@ +import { useEffect, useRef } from 'react'; +import { basicSetup } from 'codemirror'; +import { EditorView, keymap } from '@codemirror/view'; +import { defaultKeymap } from '@codemirror/commands'; +import { EditorState } from '@codemirror/state'; +import { javascript } from '@codemirror/lang-javascript'; +import { oneDark } from '@codemirror/theme-one-dark'; + +type Props = { + value: string; + onChange: (value: string) => void; +}; + +export function Editor({ value, onChange }: Props): JSX.Element { + const editor = useRef(null); + + const onUpdate = EditorView.updateListener.of((v) => { + onChange(v.state.doc.toString()); + }); + + useEffect(() => { + if (!editor.current) { + return; + } + const startState = EditorState.create({ + doc: value, + extensions: [ + basicSetup, + keymap.of([...defaultKeymap]), + javascript(), + // oneDark, + + onUpdate, + ], + }); + + const view = new EditorView({ + state: startState, + parent: editor.current, + }); + + return () => { + view.destroy(); + }; + }, []); + + return ( +
+ ); +} diff --git a/website/src/JSRepl/JSRepl.css b/website/src/JSRepl/JSRepl.css new file mode 100644 index 0000000000..b492902328 --- /dev/null +++ b/website/src/JSRepl/JSRepl.css @@ -0,0 +1,34 @@ +textarea { + width: 100%; + height: 100px; + margin-bottom: 10px; + padding: 10px; + font-family: monospace; + font-size: 14px; + border: 1px solid #ccc; + border-radius: 4px; + resize: none; +} + +button { + padding: 10px 15px; + font-size: 14px; + background-color: #007bff; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; +} + +button:hover { + background-color: #0056b3; +} + +pre { + background-color: #f8f9fa; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + white-space: pre-wrap; + word-wrap: break-word; +} \ No newline at end of file diff --git a/website/src/JSRepl/JSRepl.tsx b/website/src/JSRepl/JSRepl.tsx new file mode 100644 index 0000000000..e1c60186b9 --- /dev/null +++ b/website/src/JSRepl/JSRepl.tsx @@ -0,0 +1,131 @@ +'use client'; +import React, { useEffect, useRef, useState } from 'react'; +import './JSRepl.css'; +import { Editor } from './Editor'; + +type Props = { defaultValue: string }; + +function JSRepl({ defaultValue }: Props): JSX.Element { + const [code, setCode] = useState(defaultValue); + const [output, setOutput] = useState(''); + const workerRef = useRef(null); + + useEffect(() => { + const workerScript = ` + importScripts('https://cdn.jsdelivr.net/npm/immutable@5.1.1'); + + // extract all Immutable exports to have them available in the worker automatically + const { + version, + Collection, + Iterable, + Seq, + Map, + OrderedMap, + List, + Stack, + Set, + OrderedSet, + PairSorting, + Record, + Range, + Repeat, + is, + fromJS, + hash, + isImmutable, + isCollection, + isKeyed, + isIndexed, + isAssociative, + isOrdered, + isPlainObject, + isValueObject, + isSeq, + isList, + isMap, + isOrderedMap, + isStack, + isSet, + isOrderedSet, + isRecord, + get, + getIn, + has, + hasIn, + merge, + mergeDeep, + mergeWith, + mergeDeepWith, + remove, + removeIn, + set, + setIn, + update, + updateIn, + } = Immutable; + + self.onmessage = function(event) { + let timeoutId = setTimeout(() => { + self.postMessage({ error: "Execution timed out" }); + self.close(); + }, 2000); + + try { + const result = eval(event.data); + clearTimeout(timeoutId); + self.postMessage({ output: String(result) }); + } catch (error) { + clearTimeout(timeoutId); + self.postMessage({ error: String(error) }); + } + }; + `; + + const workerBlob = new Blob([workerScript], { + type: 'application/javascript', + }); + workerRef.current = new Worker(URL.createObjectURL(workerBlob)); + + return () => { + workerRef.current?.terminate(); + }; + }, []); + + useEffect(() => { + runCode(); + }, []); + + const runCode = () => { + if (workerRef.current) { + workerRef.current.postMessage(code); + workerRef.current.onmessage = (event) => { + if (event.data.error) { + setOutput('Error: ' + event.data.error); + } else { + setOutput('Output: ' + event.data.output); + } + }; + } + }; + + return ( +
+

Live example

+ +
+
+ +
+ + +
+ +
{output}
+
+ ); +} + +export default JSRepl; diff --git a/website/src/app/docs/[version]/test/page.tsx b/website/src/app/docs/[version]/test/page.tsx new file mode 100644 index 0000000000..3f1239396a --- /dev/null +++ b/website/src/app/docs/[version]/test/page.tsx @@ -0,0 +1,163 @@ +import prism from 'prismjs'; +import JSRepl from '../../../../JSRepl/JSRepl'; +import { SideBar } from '../../../../Sidebar'; +import { getSidebarLinks } from '../../../../getSidebarLinks'; +import { getTypeDefs } from '../../../../static/getTypeDefs'; +import { getVersions } from '../../../../static/getVersions'; +import { getVersionFromParams } from '../../../getVersionFromParams'; + +export async function generateStaticParams() { + return [...getVersions().map((version) => ({ version }))]; +} + +function Doc({ content }: { content: string }) { + // return ; + + const html = prism.highlight( + content, + prism.languages.javascript, + 'javascript' + ); + + return ( + // + + + // + ); + + // return ( + // + // ); +} + +export default function Test({ params }: { params: { version: string } }) { + const version = getVersionFromParams(params); + const defs = getTypeDefs(version); + const sidebarLinks = getSidebarLinks(defs); + + return ( + <> + + +
+

Construction

+ +
+

+ List() +

+
+
+

+ Create a new immutable List containing the values of the + provided collection-like. +

+
+ + + + +
+

Discussion

+
+

+ Note: + + List + + is a factory function and not a class, and does not use the + + new + + keyword during construction. +

+
+
+ +

Devtools !

+ + + + + {/*

Sandpack

+ +
+ +

Sandpack !

+
+

+ push() +

+
+
+

+ Returns a new List with the provided{' '} + + values + {' '} + appended, starting at this List's{' '} + + size + + . +

+
+
+
+ + */} +
+
+ + + ); +} From cd33f4763972cb3d6372c395998311cdb9f5e118 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 12:24:45 +0000 Subject: [PATCH 2/8] Working draft of the REPL --- .gitignore | 1 + package-lock.json | 14 +++++++ package.json | 1 + website/src/JSRepl/FormatterOutput.tsx | 43 ++++++++++++++++++++ website/src/JSRepl/JSRepl.tsx | 33 +++++++++++++-- website/src/app/docs/[version]/test/page.tsx | 18 +++++++- 6 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 website/src/JSRepl/FormatterOutput.tsx diff --git a/.gitignore b/.gitignore index a7a99033e4..972b88d8e1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ TODO /gh-pages /npm /dist +/coverage \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e5c17b8000..163ed16800 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "globals": "^15.15.0", "jest": "^29.0.0", "jest-environment-jsdom": "^29.6.4", + "jsonml-html": "^1.1.0", "make-synchronous": "0.1.1", "marked": "^11.2.0", "marked-highlight": "^2.1.0", @@ -7995,6 +7996,13 @@ "node": ">=6" } }, + "node_modules/jsonml-html": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsonml-html/-/jsonml-html-1.1.0.tgz", + "integrity": "sha512-L3aCxuWRalEKY/8krm1gDhjq9yTfmzoBaoiULgnMY+mAamCiKfeV/ilLcMv+bxdzb8ZgI9VjaSPBwrTTxgpF6Q==", + "dev": true, + "license": "ISC" + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -16696,6 +16704,12 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, + "jsonml-html": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsonml-html/-/jsonml-html-1.1.0.tgz", + "integrity": "sha512-L3aCxuWRalEKY/8krm1gDhjq9yTfmzoBaoiULgnMY+mAamCiKfeV/ilLcMv+bxdzb8ZgI9VjaSPBwrTTxgpF6Q==", + "dev": true + }, "jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", diff --git a/package.json b/package.json index 43a66aaee5..d96af9c361 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "globals": "^15.15.0", "jest": "^29.0.0", "jest-environment-jsdom": "^29.6.4", + "jsonml-html": "^1.1.0", "make-synchronous": "0.1.1", "marked": "^11.2.0", "marked-highlight": "^2.1.0", diff --git a/website/src/JSRepl/FormatterOutput.tsx b/website/src/JSRepl/FormatterOutput.tsx new file mode 100644 index 0000000000..6774353cb8 --- /dev/null +++ b/website/src/JSRepl/FormatterOutput.tsx @@ -0,0 +1,43 @@ +import { toHTML } from 'jsonml-html'; +import { useEffect, useRef } from 'react'; + +/** + * immutable-devtools is a console custom formatter. + * Console formatters does use jsonml format. + * {@see https://firefox-source-docs.mozilla.org/devtools-user/custom_formatters/index.html} for a documentation from the Firefox team. + * The `jsonml-to-react-element` package can convert jsonml to HTML / React elements. + */ +type Props = { + output: { + header: Array; + body?: Array; + }; +}; + +export default function FormatterOutput({ output }: Props): JSX.Element { + const header = useRef(null); + const body = useRef(null); + + const htmlHeader = toHTML(output.header); + + useEffect(() => { + if (header.current && htmlHeader) { + header.current.replaceChildren(htmlHeader); + } + }, [htmlHeader]); + + const htmlBody = output.body ? toHTML(output.body) : null; + + useEffect(() => { + if (body.current) { + body.current.replaceChildren(htmlBody ?? ''); + } + }, [htmlBody]); + + return ( + <> +
+
+ + ); +} diff --git a/website/src/JSRepl/JSRepl.tsx b/website/src/JSRepl/JSRepl.tsx index e1c60186b9..ef4ac24a63 100644 --- a/website/src/JSRepl/JSRepl.tsx +++ b/website/src/JSRepl/JSRepl.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from 'react'; import './JSRepl.css'; import { Editor } from './Editor'; +import FormatterOutput from './FormatterOutput'; type Props = { defaultValue: string }; @@ -12,7 +13,7 @@ function JSRepl({ defaultValue }: Props): JSX.Element { useEffect(() => { const workerScript = ` - importScripts('https://cdn.jsdelivr.net/npm/immutable@5.1.1'); + importScripts('https://cdn.jsdelivr.net/npm/immutable@5.1.1', 'https://cdn.jsdelivr.net/npm/immutable-devtools@0.1.5'); // extract all Immutable exports to have them available in the worker automatically const { @@ -65,6 +66,26 @@ function JSRepl({ defaultValue }: Props): JSX.Element { updateIn, } = Immutable; + immutableDevTools(Immutable); + + // hack to get the formatters from immutable-devtools as they are not exported, but they modify the "global" variable + const immutableFormaters = globalThis.devtoolsFormatters; + + // console.log(immutableFormaters) + + function normalizeResult(result) { + const formatter = immutableFormaters.find((formatter) => formatter.header(result)); + + if (!formatter) { + return undefined; + } + + return { + header: formatter.header(result), + body: formatter.hasBody(result) ? formatter.body(result) : undefined, + } + } + self.onmessage = function(event) { let timeoutId = setTimeout(() => { self.postMessage({ error: "Execution timed out" }); @@ -74,8 +95,10 @@ function JSRepl({ defaultValue }: Props): JSX.Element { try { const result = eval(event.data); clearTimeout(timeoutId); - self.postMessage({ output: String(result) }); + + self.postMessage({ output: normalizeResult(result) }); } catch (error) { + console.log(error); clearTimeout(timeoutId); self.postMessage({ error: String(error) }); } @@ -103,7 +126,7 @@ function JSRepl({ defaultValue }: Props): JSX.Element { if (event.data.error) { setOutput('Error: ' + event.data.error); } else { - setOutput('Output: ' + event.data.output); + setOutput(event.data.output); } }; } @@ -123,7 +146,9 @@ function JSRepl({ defaultValue }: Props): JSX.Element { -
{output}
+
+        
+      
); } diff --git a/website/src/app/docs/[version]/test/page.tsx b/website/src/app/docs/[version]/test/page.tsx index 3f1239396a..20d00eb3e5 100644 --- a/website/src/app/docs/[version]/test/page.tsx +++ b/website/src/app/docs/[version]/test/page.tsx @@ -78,7 +78,20 @@ export default function Test({ params }: { params: { version: string } }) { - + {/* */} +

Discussion

@@ -101,7 +114,8 @@ export default function Test({ params }: { params: { version: string } }) { {/*

Sandpack

From 4aa3fb7494a92043007f56e06f84cd6d7f62c2dd Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 12:43:07 +0000 Subject: [PATCH 3/8] add "/play" page --- website/src/Header.tsx | 1 + website/src/JSRepl/JSRepl.tsx | 7 ++++-- website/src/app/play/layout.tsx | 24 ++++++++++++++++++ website/src/app/play/page.tsx | 44 +++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 website/src/app/play/layout.tsx create mode 100644 website/src/app/play/page.tsx diff --git a/website/src/Header.tsx b/website/src/Header.tsx index e2ba1584ad..b8e8b67d9e 100644 --- a/website/src/Header.tsx +++ b/website/src/Header.tsx @@ -109,6 +109,7 @@ export function HeaderLinks({ return (
+ Playground (defaultValue); - const [output, setOutput] = useState(''); + const [output, setOutput] = useState<{ + header: Array; + body?: Array; + }>({ header: [] }); const workerRef = useRef(null); useEffect(() => { @@ -124,7 +127,7 @@ function JSRepl({ defaultValue }: Props): JSX.Element { workerRef.current.postMessage(code); workerRef.current.onmessage = (event) => { if (event.data.error) { - setOutput('Error: ' + event.data.error); + setOutput({ header: ['div', 'Error: ' + event.data.error] }); } else { setOutput(event.data.output); } diff --git a/website/src/app/play/layout.tsx b/website/src/app/play/layout.tsx new file mode 100644 index 0000000000..7969f86b6f --- /dev/null +++ b/website/src/app/play/layout.tsx @@ -0,0 +1,24 @@ +import { DocHeader } from '../../DocHeader'; +import { ImmutableConsole } from '../../ImmutableConsole'; +import { getVersions } from '../../static/getVersions'; +import { getVersionFromParams } from '../getVersionFromParams'; + +export default function VersionLayout({ + children, + params, +}: { + children: React.ReactNode; + params: { version: string }; +}) { + const versions = getVersions(); + + return ( +
+ + +
+
{children}
+
+
+ ); +} diff --git a/website/src/app/play/page.tsx b/website/src/app/play/page.tsx new file mode 100644 index 0000000000..d9a6f79cf9 --- /dev/null +++ b/website/src/app/play/page.tsx @@ -0,0 +1,44 @@ +import { Metadata } from 'next'; +import { getVersions } from '../../static/getVersions'; +import { getTypeDefs } from '../../static/getTypeDefs'; +import { DocSearch } from '../../DocSearch'; +import { SideBar } from '../../Sidebar'; +import { getSidebarLinks } from '../../getSidebarLinks'; +import JSRepl from '../../JSRepl/JSRepl'; + +export async function generateStaticParams() { + return [...getVersions().map((version) => ({ version }))]; +} + +export async function generateMetadata(): Promise { + return { + title: `Playground — Immutable.js`, + }; +} + +export default function OverviewDocPage() { + const versions = getVersions(); + const version = versions[0]; + const defs = getTypeDefs(version); + + const sidebarLinks = getSidebarLinks(defs); + + return ( + <> + +
+ +

Playgroud ({version})

+ + str.charAt(0).toUpperCase() + str.slice(1); + +List(['apple', 'banana', 'coconut']) + .push('dragonfruit') + .map((fruit) => upperFirst(fruit)) +`} + /> +
+ + ); +} From 69a6ae1ff63fd371d7af4d9a8281be8d3dcf6912 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 12:57:40 +0000 Subject: [PATCH 4/8] style --- website/src/JSRepl/Editor.tsx | 5 +++-- website/src/JSRepl/JSRepl.css | 14 ++++++++++---- website/src/JSRepl/JSRepl.tsx | 2 +- website/styles/globals.css | 5 +++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/website/src/JSRepl/Editor.tsx b/website/src/JSRepl/Editor.tsx index a7d442c0e3..f7c1afb7a2 100644 --- a/website/src/JSRepl/Editor.tsx +++ b/website/src/JSRepl/Editor.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from 'react'; import { basicSetup } from 'codemirror'; import { EditorView, keymap } from '@codemirror/view'; -import { defaultKeymap } from '@codemirror/commands'; +import { defaultKeymap, indentWithTab } from '@codemirror/commands'; import { EditorState } from '@codemirror/state'; import { javascript } from '@codemirror/lang-javascript'; import { oneDark } from '@codemirror/theme-one-dark'; @@ -26,8 +26,9 @@ export function Editor({ value, onChange }: Props): JSX.Element { doc: value, extensions: [ basicSetup, - keymap.of([...defaultKeymap]), + keymap.of([...defaultKeymap, indentWithTab]), javascript(), + // TODO activate this when we have a dark mode // oneDark, onUpdate, diff --git a/website/src/JSRepl/JSRepl.css b/website/src/JSRepl/JSRepl.css index b492902328..986c25e362 100644 --- a/website/src/JSRepl/JSRepl.css +++ b/website/src/JSRepl/JSRepl.css @@ -1,3 +1,9 @@ +.repl-editor-container { + display: flex; + align-items: flex-start; + gap: 8px; +} + textarea { width: 100%; height: 100px; @@ -13,7 +19,7 @@ textarea { button { padding: 10px 15px; font-size: 14px; - background-color: #007bff; + background-color: var(--link-color); color: white; border: none; border-radius: 4px; @@ -21,14 +27,14 @@ button { } button:hover { - background-color: #0056b3; + background-color: var(--link-hover-color); } pre { - background-color: #f8f9fa; + background-color: var(--code-block-bg-color); padding: 10px; border: 1px solid #ccc; border-radius: 4px; white-space: pre-wrap; word-wrap: break-word; -} \ No newline at end of file +} diff --git a/website/src/JSRepl/JSRepl.tsx b/website/src/JSRepl/JSRepl.tsx index 1f8e51f2a8..28a42a49a7 100644 --- a/website/src/JSRepl/JSRepl.tsx +++ b/website/src/JSRepl/JSRepl.tsx @@ -139,7 +139,7 @@ function JSRepl({ defaultValue }: Props): JSX.Element {

Live example

-
+
diff --git a/website/styles/globals.css b/website/styles/globals.css index 56158e25a5..cd810eb202 100644 --- a/website/styles/globals.css +++ b/website/styles/globals.css @@ -3,6 +3,7 @@ html, body { --link-color: #4183c4; + --link-hover-color: #2b6db0; --header-color: #212325; --header-bg-color: #6dbcdb; --body-color: #626466; @@ -57,6 +58,10 @@ a { text-decoration: none; } +a:hover { + color: var(--link-hover-color); +} + pre, code { font-family: 'Fira Mono', Menlo, monospace; From 4bfa46821868fbe1f4ad2203e4e2ce7c71907642 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 13:02:48 +0000 Subject: [PATCH 5/8] remove debug page --- website/src/JSRepl/FormatterOutput.tsx | 2 +- website/src/app/docs/[version]/test/page.tsx | 177 ------------------- 2 files changed, 1 insertion(+), 178 deletions(-) delete mode 100644 website/src/app/docs/[version]/test/page.tsx diff --git a/website/src/JSRepl/FormatterOutput.tsx b/website/src/JSRepl/FormatterOutput.tsx index 6774353cb8..fd0a9b2e2b 100644 --- a/website/src/JSRepl/FormatterOutput.tsx +++ b/website/src/JSRepl/FormatterOutput.tsx @@ -5,7 +5,7 @@ import { useEffect, useRef } from 'react'; * immutable-devtools is a console custom formatter. * Console formatters does use jsonml format. * {@see https://firefox-source-docs.mozilla.org/devtools-user/custom_formatters/index.html} for a documentation from the Firefox team. - * The `jsonml-to-react-element` package can convert jsonml to HTML / React elements. + * The `jsonml-html` package can convert jsonml to HTML. */ type Props = { output: { diff --git a/website/src/app/docs/[version]/test/page.tsx b/website/src/app/docs/[version]/test/page.tsx deleted file mode 100644 index 20d00eb3e5..0000000000 --- a/website/src/app/docs/[version]/test/page.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import prism from 'prismjs'; -import JSRepl from '../../../../JSRepl/JSRepl'; -import { SideBar } from '../../../../Sidebar'; -import { getSidebarLinks } from '../../../../getSidebarLinks'; -import { getTypeDefs } from '../../../../static/getTypeDefs'; -import { getVersions } from '../../../../static/getVersions'; -import { getVersionFromParams } from '../../../getVersionFromParams'; - -export async function generateStaticParams() { - return [...getVersions().map((version) => ({ version }))]; -} - -function Doc({ content }: { content: string }) { - // return ; - - const html = prism.highlight( - content, - prism.languages.javascript, - 'javascript' - ); - - return ( - // - - - // - ); - - // return ( - // - // ); -} - -export default function Test({ params }: { params: { version: string } }) { - const version = getVersionFromParams(params); - const defs = getTypeDefs(version); - const sidebarLinks = getSidebarLinks(defs); - - return ( - <> - - -
-

Construction

- -
-

- List() -

-
-
-

- Create a new immutable List containing the values of the - provided collection-like. -

-
- - - {/* */} - - -
-

Discussion

-
-

- Note: - - List - - is a factory function and not a class, and does not use the - - new - - keyword during construction. -

-
-
- -

Devtools !

- - - - - {/*

Sandpack

- -
- -

Sandpack !

-
-

- push() -

-
-
-

- Returns a new List with the provided{' '} - - values - {' '} - appended, starting at this List's{' '} - - size - - . -

-
-
-
- - */} -
-
-
- - ); -} From d6fb2564edccf0ca19aad56972efc1daf71a7c3e Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 13:34:28 +0000 Subject: [PATCH 6/8] remove wrongly commited file --- .../src/app/docs/[version]/test/page.tsx.bak | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 website/src/app/docs/[version]/test/page.tsx.bak diff --git a/website/src/app/docs/[version]/test/page.tsx.bak b/website/src/app/docs/[version]/test/page.tsx.bak deleted file mode 100644 index 8669946a38..0000000000 --- a/website/src/app/docs/[version]/test/page.tsx.bak +++ /dev/null @@ -1,109 +0,0 @@ -import { SideBar } from '../../../../Sidebar'; -import { getSidebarLinks } from '../../../../getSidebarLinks'; -import { getTypeDefs } from '../../../../static/getTypeDefs'; -import { getVersions } from '../../../../static/getVersions'; -import { getVersionFromParams } from '../../../getVersionFromParams'; -import SandpackTest, { Doc } from './sandpack'; - -export async function generateStaticParams() { - return [...getVersions().map(version => ({ version }))]; -} - -export default function Test({ params }: { params: { version: string } }) { - const version = getVersionFromParams(params); - const defs = getTypeDefs(version); - const sidebarLinks = getSidebarLinks(defs); - - return ( - <> - - -
-

Construction

- -
-

- List() -

-
-
-

- Create a new immutable List containing the values of the - provided collection-like. -

-
- - - -
-

Discussion

-
-

- Note:{' '} - - List - {' '} - is a factory function and not a class, and does not use the - - new - {' '} - keyword during construction. -

-
-
- - -
- -

Sandpack !

-
-

- push() -

-
-
-

- Returns a new List with the provided{' '} - - values - {' '} - appended, starting at this List's{' '} - - size - - . -

-
-
-
- - -
-
- - ); -} From 4c87017e455895bae75f15aeb9697a78cc753f02 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 13:37:58 +0000 Subject: [PATCH 7/8] rename file --- website/src/app/play/page.tsx | 4 ++-- website/src/{JSRepl => repl}/Editor.tsx | 0 website/src/{JSRepl => repl}/FormatterOutput.tsx | 0 website/src/{JSRepl/JSRepl.tsx => repl/Repl.tsx} | 6 +++--- website/src/{JSRepl/JSRepl.css => repl/repl.css} | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename website/src/{JSRepl => repl}/Editor.tsx (100%) rename website/src/{JSRepl => repl}/FormatterOutput.tsx (100%) rename website/src/{JSRepl/JSRepl.tsx => repl/Repl.tsx} (97%) rename website/src/{JSRepl/JSRepl.css => repl/repl.css} (100%) diff --git a/website/src/app/play/page.tsx b/website/src/app/play/page.tsx index d9a6f79cf9..cdcddd441f 100644 --- a/website/src/app/play/page.tsx +++ b/website/src/app/play/page.tsx @@ -4,7 +4,7 @@ import { getTypeDefs } from '../../static/getTypeDefs'; import { DocSearch } from '../../DocSearch'; import { SideBar } from '../../Sidebar'; import { getSidebarLinks } from '../../getSidebarLinks'; -import JSRepl from '../../JSRepl/JSRepl'; +import Repl from '../../repl/Repl'; export async function generateStaticParams() { return [...getVersions().map((version) => ({ version }))]; @@ -30,7 +30,7 @@ export default function OverviewDocPage() {

Playgroud ({version})

- str.charAt(0).toUpperCase() + str.slice(1); List(['apple', 'banana', 'coconut']) diff --git a/website/src/JSRepl/Editor.tsx b/website/src/repl/Editor.tsx similarity index 100% rename from website/src/JSRepl/Editor.tsx rename to website/src/repl/Editor.tsx diff --git a/website/src/JSRepl/FormatterOutput.tsx b/website/src/repl/FormatterOutput.tsx similarity index 100% rename from website/src/JSRepl/FormatterOutput.tsx rename to website/src/repl/FormatterOutput.tsx diff --git a/website/src/JSRepl/JSRepl.tsx b/website/src/repl/Repl.tsx similarity index 97% rename from website/src/JSRepl/JSRepl.tsx rename to website/src/repl/Repl.tsx index 28a42a49a7..b37a5df69f 100644 --- a/website/src/JSRepl/JSRepl.tsx +++ b/website/src/repl/Repl.tsx @@ -1,12 +1,12 @@ 'use client'; import React, { useEffect, useRef, useState } from 'react'; -import './JSRepl.css'; import { Editor } from './Editor'; import FormatterOutput from './FormatterOutput'; +import './repl.css'; type Props = { defaultValue: string }; -function JSRepl({ defaultValue }: Props): JSX.Element { +function Repl({ defaultValue }: Props): JSX.Element { const [code, setCode] = useState(defaultValue); const [output, setOutput] = useState<{ header: Array; @@ -156,4 +156,4 @@ function JSRepl({ defaultValue }: Props): JSX.Element { ); } -export default JSRepl; +export default Repl; diff --git a/website/src/JSRepl/JSRepl.css b/website/src/repl/repl.css similarity index 100% rename from website/src/JSRepl/JSRepl.css rename to website/src/repl/repl.css From 0910173a6bdf42d5bf7de050325170fb2304f835 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 6 Apr 2025 16:38:35 +0000 Subject: [PATCH 8/8] fix lint --- website/src/app/play/layout.tsx | 3 --- website/src/app/play/page.tsx | 6 ++++-- website/src/repl/Editor.tsx | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/src/app/play/layout.tsx b/website/src/app/play/layout.tsx index 7969f86b6f..4f7b7c3a3c 100644 --- a/website/src/app/play/layout.tsx +++ b/website/src/app/play/layout.tsx @@ -1,14 +1,11 @@ import { DocHeader } from '../../DocHeader'; import { ImmutableConsole } from '../../ImmutableConsole'; import { getVersions } from '../../static/getVersions'; -import { getVersionFromParams } from '../getVersionFromParams'; export default function VersionLayout({ children, - params, }: { children: React.ReactNode; - params: { version: string }; }) { const versions = getVersions(); diff --git a/website/src/app/play/page.tsx b/website/src/app/play/page.tsx index cdcddd441f..94fda0a6e9 100644 --- a/website/src/app/play/page.tsx +++ b/website/src/app/play/page.tsx @@ -4,7 +4,7 @@ import { getTypeDefs } from '../../static/getTypeDefs'; import { DocSearch } from '../../DocSearch'; import { SideBar } from '../../Sidebar'; import { getSidebarLinks } from '../../getSidebarLinks'; -import Repl from '../../repl/Repl'; +import dynamic from 'next/dynamic'; export async function generateStaticParams() { return [...getVersions().map((version) => ({ version }))]; @@ -16,6 +16,8 @@ export async function generateMetadata(): Promise { }; } +const ReplNoSSR = dynamic(() => import('../../repl/Repl'), { ssr: false }); + export default function OverviewDocPage() { const versions = getVersions(); const version = versions[0]; @@ -30,7 +32,7 @@ export default function OverviewDocPage() {

Playgroud ({version})

- str.charAt(0).toUpperCase() + str.slice(1); List(['apple', 'banana', 'coconut']) diff --git a/website/src/repl/Editor.tsx b/website/src/repl/Editor.tsx index f7c1afb7a2..e284e14f50 100644 --- a/website/src/repl/Editor.tsx +++ b/website/src/repl/Editor.tsx @@ -4,7 +4,8 @@ import { EditorView, keymap } from '@codemirror/view'; import { defaultKeymap, indentWithTab } from '@codemirror/commands'; import { EditorState } from '@codemirror/state'; import { javascript } from '@codemirror/lang-javascript'; -import { oneDark } from '@codemirror/theme-one-dark'; +// TODO activate this when we have a dark mode +// import { oneDark } from '@codemirror/theme-one-dark'; type Props = { value: string;