diff --git a/package-lock.json b/package-lock.json index ad0f960..4751085 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,10 +12,15 @@ "@astrojs/starlight": "^0.26.1", "@astrojs/starlight-tailwind": "^2.0.3", "@astrojs/tailwind": "^5.1.2", + "@effect/platform-node": "^0.65.0", "astro": "^4.14.5", + "date-fns": "^4.1.0", + "effect": "^3.11.0", "sharp": "^0.33.5", "tailwindcss": "^3.4.15", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "vitest": "^2.1.7", + "xml-js": "^1.6.11" } }, "node_modules/@alloc/quick-lru": { @@ -602,6 +607,50 @@ "node": ">=14" } }, + "node_modules/@effect/platform": { + "version": "0.70.0", + "resolved": "https://registry.npmjs.org/@effect/platform/-/platform-0.70.0.tgz", + "integrity": "sha512-3qQGf+TkGB9cL1YDh0UEEuG7j5/ptgLy0OZCAZrrOBflaT19TzGWeYSwwM56uKbXT58AJRI2HHW/dwMnHRnp5Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "find-my-way-ts": "^0.1.5", + "multipasta": "^0.2.5" + }, + "peerDependencies": { + "effect": "^3.11.0" + } + }, + "node_modules/@effect/platform-node": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@effect/platform-node/-/platform-node-0.65.0.tgz", + "integrity": "sha512-7QosZxzw4gs14dzvGD3HqJhH9XXDa9QRYSLnA6JJsgz6hrraNMaaPiWaiVXf/mInq4uqizDLq+3dEVNRLefdFQ==", + "license": "MIT", + "dependencies": { + "@effect/platform-node-shared": "^0.20.0", + "mime": "^3.0.0", + "undici": "^6.19.7", + "ws": "^8.18.0" + }, + "peerDependencies": { + "@effect/platform": "^0.70.0", + "effect": "^3.11.0" + } + }, + "node_modules/@effect/platform-node-shared": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@effect/platform-node-shared/-/platform-node-shared-0.20.0.tgz", + "integrity": "sha512-VWUHP1L8o/zFYWLeWxZeBgwCevW99KfioLj32wwoqHIesbSX+syP+tKJRDrGD3ZPo3kbQRQ325oTz3YfiJC3VQ==", + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "multipasta": "^0.2.5" + }, + "peerDependencies": { + "@effect/platform": "^0.70.0", + "effect": "^3.11.0" + } + }, "node_modules/@emmetio/abbreviation": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", @@ -1667,6 +1716,313 @@ "win32" ] }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2064,6 +2420,112 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "license": "ISC" }, + "node_modules/@vitest/expect": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.7.tgz", + "integrity": "sha512-folWk4qQDEedgUyvaZw94LIJuNLoDtY+rhKhhNy0csdwifn/pQz8EWVRnyrW3j0wMpy+xwJT8WiwiYxk+i+s7w==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.7", + "@vitest/utils": "2.1.7", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.7.tgz", + "integrity": "sha512-nKMTnuJrarFH+7llWxeLmYRldIwTY3OM1DzdytHj0f2+fah6Cyk4XbswhjOiTCnAvXsZAEoo1OaD6rneSSU+3Q==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.7.tgz", + "integrity": "sha512-HoqRIyfQlXPrRDB43h0lC8eHPUDPwFweMaD6t+psOvwClCC+oZZim6wPMjuoMnRdiFxXqbybg/QbuewgTwK1vA==", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.7.tgz", + "integrity": "sha512-MrDNpXUIXksR57qipYh068SOX4N1hVw6oVILlTlfeTyA1rp0asuljyp15IZwKqhjpWLObFj+tiNrOM4R8UnSqg==", + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.7", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.7.tgz", + "integrity": "sha512-OioIxV/xS393DKdlkRNhmtY0K37qVdCv8w1M2SlLTBSX+fNK6zgcd01VlT1nXdbKVDaB8Zb6BOfQYYoGeGTEGg==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.7", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.7.tgz", + "integrity": "sha512-e5pzIaIC0LBrb/j1FaF7HXlPJLGtltiAkwXTMqNEHALJc7USSLEwziJ+aIWTmjsWNg89zazg37h7oZITnublsQ==", + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.7.tgz", + "integrity": "sha512-7gUdvIzCCuIrMZu0WHTvDJo8C1NsUtOqmwmcS3bRHUcfHemj29wmkzLVNuWQD7WHoBD/+I7WIgrnzt7kxR54ow==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.7", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@volar/kit": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.0.tgz", @@ -2319,6 +2781,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/astring": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", @@ -2643,6 +3114,15 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/camelcase": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", @@ -2694,6 +3174,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2744,6 +3240,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3069,13 +3574,23 @@ "node": ">=4" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3098,6 +3613,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -3194,6 +3718,15 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, + "node_modules/effect": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.11.0.tgz", + "integrity": "sha512-uPWp/L0kMaKPi7hgXkfu0KUuxQzpXt20F2p6aBwU/gyJBay6t1XsTi0lFoHdk3fuqQCFt10VUYuPUeh3JY4TMQ==", + "license": "MIT", + "dependencies": { + "fast-check": "^3.21.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.13", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", @@ -3414,6 +3947,15 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/expressive-code": { "version": "0.35.6", "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.35.6.tgz", @@ -3443,6 +3985,28 @@ "node": ">=0.10.0" } }, + "node_modules/fast-check": { + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.1.tgz", + "integrity": "sha512-u/MudsoQEgBUZgR5N1v87vEgybeVYus9VnDVaIkxkkGP2jt54naghQ3PCQHJiogS8U/GavZCUPFfx3Xkp+NaHw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^6.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3489,6 +4053,13 @@ "node": ">=8" } }, + "node_modules/find-my-way-ts": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.5.tgz", + "integrity": "sha512-4GOTMrpGQVzsCH2ruUn2vmwzV/02zF4q+ybhCIrw/Rkt3L8KWcycdC6aJMctJzwN4fXD4SD5F/4B9Sksh5rE0A==", + "license": "MIT", + "peer": true + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -4589,6 +5160,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loupe": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4599,9 +5176,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.14", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.14.tgz", + "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -5698,6 +6275,18 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -5756,9 +6345,10 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/muggle-string": { "version": "0.4.1", @@ -5766,6 +6356,12 @@ "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", "license": "MIT" }, + "node_modules/multipasta": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.5.tgz", + "integrity": "sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==", + "license": "MIT" + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -5817,6 +6413,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT" + }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -6164,6 +6766,21 @@ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "license": "MIT" }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -6437,6 +7054,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6998,6 +7631,12 @@ "@types/hast": "^3.0.4" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -7081,6 +7720,18 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "license": "MIT" + }, "node_modules/stdin-discarder": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", @@ -7371,6 +8022,45 @@ "node": ">=0.8" } }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -7483,6 +8173,15 @@ "semver": "^7.3.8" } }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -7774,6 +8473,28 @@ } } }, + "node_modules/vite-node": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.7.tgz", + "integrity": "sha512-b/5MxSWd0ftWt1B1LHfzCw0ASzaxHztUwP0rcsBhkDSGy9ZDEDieSIjFG3I78nI9dUN0eSeD6LtuKPZGjwwpZQ==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/vitefu": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", @@ -7788,6 +8509,71 @@ } } }, + "node_modules/vitest": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.7.tgz", + "integrity": "sha512-wzJ7Wri44ufkzTZbI1lHsdHfiGdFRmnJ9qIudDQ6tknjJeHhF5QgNSSjk7KRZUU535qEiEXFJ7tSHqyzyIv0jQ==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.7", + "@vitest/mocker": "2.1.7", + "@vitest/pretty-format": "^2.1.7", + "@vitest/runner": "2.1.7", + "@vitest/snapshot": "2.1.7", + "@vitest/spy": "2.1.7", + "@vitest/utils": "2.1.7", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.7", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "2.1.7", + "@vitest/ui": "2.1.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/volar-service-css": { "version": "0.0.61", "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.61.tgz", @@ -8071,6 +8857,22 @@ "node": ">=4" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -8253,6 +9055,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, "node_modules/xxhash-wasm": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz", diff --git a/package.json b/package.json index 3bb60f5..afafa3a 100644 --- a/package.json +++ b/package.json @@ -7,16 +7,22 @@ "start": "astro dev", "build": "astro check && astro build", "preview": "astro preview", - "astro": "astro" + "astro": "astro", + "test": "vitest" }, "dependencies": { "@astrojs/check": "^0.9.3", "@astrojs/starlight": "^0.26.1", "@astrojs/starlight-tailwind": "^2.0.3", "@astrojs/tailwind": "^5.1.2", + "@effect/platform-node": "^0.65.0", "astro": "^4.14.5", + "date-fns": "^4.1.0", + "effect": "^3.11.0", "sharp": "^0.33.5", "tailwindcss": "^3.4.15", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "vitest": "^2.1.7", + "xml-js": "^1.6.11" } } diff --git a/src/components/GrArxivPage.astro b/src/components/GrArxivPage.astro new file mode 100644 index 0000000..43d20ae --- /dev/null +++ b/src/components/GrArxivPage.astro @@ -0,0 +1,82 @@ + +--- +import { format } from 'date-fns'; + +import {extractArxivID, getPaper} from '../lib/arxiv' + +import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; + +const props = Astro.props; + +const arxivEntry = props.arxiv + +const arxivid = extractArxivID(arxivEntry.id) + +const paper = getPaper(arxivid) + +--- + +

+ +

By + {arxivEntry.author.map( (author:any, i:number) => ( + {(i ? ', ' : '')} + ))} +
+ + arXiv:{arxivid} + [ {arxivEntry.category.join(", ")} + ] + + + {paper?.github !== undefined && paper.github !== "" ? + (github:{paper?.github}) + : '' + } + + +

+ +

Abstract

+

{arxivEntry.summary}

+ +
+ + + + diff --git a/src/content/config.ts b/src/content/config.ts index 45f60b0..700ce7d 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,6 +1,15 @@ -import { defineCollection } from 'astro:content'; +import { z, defineCollection } from 'astro:content'; import { docsSchema } from '@astrojs/starlight/schema'; +const researchCollection = defineCollection({ + type: 'data', + schema: z.object({ + title: z.string(), + canonicalURL: z.string().url() + }) +}) + export const collections = { docs: defineCollection({ schema: docsSchema() }), + research: researchCollection }; diff --git a/src/content/docs/appendices/notation.md b/src/content/docs/appendices/notation.md index f8774a7..308a929 100644 --- a/src/content/docs/appendices/notation.md +++ b/src/content/docs/appendices/notation.md @@ -12,11 +12,11 @@ The GraphRAG pattern catalog uses a data notation called `gram` to describe logical graph structures called patterns that are composed of nodes, relationships and subjects. -The Gram notation is intended to be self-descriptive and explicit, able to -represent data and structures that are often implicit in a physical graph models. -For example, paths are present in any connected graph, however storing path-level -information isn't normally supported. You can find paths, even store paths, but -there is no way to "say something" about a path. +> The Gram notation is intended to be self-descriptive and explicit, able to +> represent data and structures that are often implicit in a physical graph models. +> For example, paths are present in any connected graph, however storing path-level +> information isn't normally supported. You can find paths, even store paths, but +> there is no way to "say something" about a path. Gram starts with a notion of "subjects" as a self-describing data structure in two parts: diff --git a/src/content/docs/appendices/research.mdx b/src/content/docs/appendices/research.mdx index 936b32e..0b5e8a8 100644 --- a/src/content/docs/appendices/research.mdx +++ b/src/content/docs/appendices/research.mdx @@ -1,6 +1,8 @@ --- title: GraphRAG Papers description: Foundational research papers about GraphRAG and Knowledge Graphs +editUrl: false +tableOfContents: false --- - [Graph Retrieval-Augmented Generation: A Survey](https://arxiv.org/abs/2408.08921) diff --git a/src/data/papers.json b/src/data/papers.json new file mode 100644 index 0000000..ab15a31 --- /dev/null +++ b/src/data/papers.json @@ -0,0 +1,86 @@ +[ + { + "arxivid": "2408.08921", + "github": "pengboci/GraphRAG-Survey" + }, + { + "arxivid": "2312.16890", + "github": "HKUDS/DiffKG" + }, + { + "arxivid": "2306.08302", + "github": "" + }, + { + "arxivid": "2310.04560", + "github": "google-research/talk-like-a-graph" + }, + { + "arxivid": "2311.07509", + "github": "datadotworld/cwd-benchmark-data" + }, + { + "arxivid": "2402.07630", + "github": "XiaoxinHe/G-Retriever" + }, + { + "arxivid": "2404.12491", + "github": "urchade/GraphER" + }, + { + "arxivid": "2404.16130", + "github": "microsoft/graphrag" + }, + { + "arxivid": "2404.17723", + "github": "" + }, + { + "arxivid": "2408.04948", + "github": "" + }, + { + "arxivid": "2406.14550", + "github": "" + }, + { + "arxivid": "2410.05779", + "github": "HKUDS/LightRAG" + }, + { + "arxivid": "2410.08815", + "github": "Li-Z-Q/StructRAG" + }, + { + "arxivid": "2307.07697", + "github": "IDEA-FinAI/ToG" + }, + { + "arxivid": "2405.14831", + "github": "OSU-NLP-Group/HippoRAG" + }, + { + "arxivid": "2408.04187", + "github": "MedicineToken/Medical-Graph-RAG" + }, + { + "arxivid": "2405.18414", + "github": "" + }, + { + "arxivid": "2405.16506", + "github": "HuieL/GRAG" + }, + { + "arxivid": "2410.23875", + "github": "liyichen-cly/PoG" + }, + { + "arxivid": "2410.18415", + "github": "" + }, + { + "arxivid": "2404.07103", + "github": "PeterGriffinJin/Graph-CoT" + } +] \ No newline at end of file diff --git a/src/lib/arxiv.spec.ts b/src/lib/arxiv.spec.ts new file mode 100644 index 0000000..0a97d7a --- /dev/null +++ b/src/lib/arxiv.spec.ts @@ -0,0 +1,48 @@ +import { assert, expect, test } from 'vitest'; + +import { Effect, Either } from "effect" +import { FetchHttpClient } from "@effect/platform" + +import { getArxivDetails } from './arxiv' +import { type ArxivEntry } from './arxiv' + +test('arxiv fetch well-known entry', async () => { + const arxivid = '2402.07630'; + + const program = getArxivDetails(arxivid).pipe( + Effect.scoped, + Effect.provide(FetchHttpClient.layer) // provide a real implementation of fetch() + ); + + const result = await Effect.runPromise(program) + + expect(Either.isRight(result)) + + expect(Either.getOrThrow(result).title).toBe("G-Retriever: Retrieval-Augmented Generation for Textual Graph Understanding and Question Answering") + + // DEBUG + // Either.match(result, + // { + // onLeft: (e) => console.error(e), + // onRight: (result) => console.log(result.feed.entry[0]) + // } + // ) + +}); + +test('arxiv get many entries', async () => { + const arxivids = ['2402.07630', '2311.07509', '2306.08302']; + + const program = Effect.forEach(arxivids, (arxivid) => + getArxivDetails(arxivid) + ).pipe( + Effect.map( Either.all ), // gather all the successes into one array + Effect.scoped, + Effect.provide(FetchHttpClient.layer) + ) + + const result = await Effect.runPromise(program) + + expect(Either.isRight(result)) + +}) \ No newline at end of file diff --git a/src/lib/arxiv.ts b/src/lib/arxiv.ts new file mode 100644 index 0000000..9e8d50c --- /dev/null +++ b/src/lib/arxiv.ts @@ -0,0 +1,112 @@ +import { + HttpClient, + HttpClientRequest, + HttpClientResponse, + HttpClientError +} from "@effect/platform" +import type { Cause } from "effect" +import { Effect, Either } from "effect" +import * as convert from 'xml-js'; + +import { Schema } from "effect" +import type { ParseError } from "effect/ParseResult"; +import type { ParseOptions } from "effect/SchemaAST"; + +import papers from '../data/papers.json'; + +const XmlText = Schema.transform( + Schema.Struct({text:Schema.String}), + Schema.String, + { + strict: true, + decode: (element) => element.text, + encode: (s) => ({ text: s }) + } +) + +const XmlTextDate = Schema.transform( + Schema.Struct({text:Schema.String}), + Schema.Date, + { + strict: true, + decode: (element) => element.text, + encode: (d) => ({ text: d }) + } +) + +const ArxivLink = Schema.Struct({ + href: Schema.String, + rel: Schema.String, + type: Schema.optional(Schema.String) +}) + +const XmlLink = Schema.transform( + Schema.Struct({ + _attributes: ArxivLink + }), + ArxivLink, + { + strict: true, + decode: (element) => element._attributes, + encode: (attrs) => ({ _attributes: attrs }) + } +) + +const XmlCategory = Schema.transform( + Schema.Struct({ + _attributes: Schema.Struct({ term: Schema.String }) + }), + Schema.String, + { + strict: true, + decode: (element) => element._attributes.term, + encode: (category) => ({_attributes: { term: category, scheme: ""}}) + } +) + +export const ArxivEntry = Schema.Struct({ + id: XmlText, + updated: XmlTextDate, + published: XmlTextDate, + title: XmlText, + summary: XmlText, + author: Schema.Array( + Schema.Struct({ + name: XmlText + }) + ), + link: Schema.Array(XmlLink), + category: Schema.Array(XmlCategory) +}) + +export type ArxivEntry = Schema.Schema.Type + +export const ArxivFeed = Schema.Struct({ + feed: Schema.Struct({ + entry: Schema.Array(ArxivEntry) + }) +}) + +export type ArxivFeed = Schema.Schema.Type + +const decodeArxivFeed = Schema.decodeUnknownEither(ArxivFeed) + +export const getArxivDetails = ( + arxivid: string +) => + HttpClient.get(`http://export.arxiv.org/api/query?id_list=${arxivid}`).pipe( + Effect.flatMap( (response) => response.text), + Effect.map( xml => convert.xml2js(xml, {compact:true, textKey:"text", alwaysArray:["entry","author", "category"]})), + // Effect.tap( raw => Effect.log(raw)), + Effect.map(decodeArxivFeed), + Effect.map(Either.map( r => r.feed.entry[0])) + ) + + export const extractArxivID = (url:string) => { + const arxividRE = /.+\/([0-9\.]+)/g; + const matches = arxividRE.exec(url); + return (matches !== null) ? matches[1] : '.' + } + +export const getPaper = (paper:string) => papers.find( p => (p.arxivid === paper)) + diff --git a/src/pages/appendices/research.astro b/src/pages/appendices/research.astro new file mode 100644 index 0000000..3dc1ef8 --- /dev/null +++ b/src/pages/appendices/research.astro @@ -0,0 +1,42 @@ +--- +import { Effect, Either } from "effect" +import { FetchHttpClient } from "@effect/platform" + +import { getArxivDetails, extractArxivID } from '../../lib/arxiv' +import type {ArxivEntry} from '../../lib/arxiv' + +import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; + +import papers from '../../data/papers.json'; + +const arxivids = papers.map(p => p.arxivid) + +const program = Effect.forEach(arxivids, (arxivid) => + getArxivDetails(arxivid) +).pipe( + Effect.map( Either.all ), // gather all the successes into one array + Effect.scoped, + Effect.provide(FetchHttpClient.layer) +) + +const results = await Effect.runPromise(program) + +const sorted = Either.getOrElse(results, + () => ([]) +).sort((a:any,b:any) => (a.published.text < b.published.text) ? -1 : 1); + +--- + + + + + \ No newline at end of file diff --git a/src/pages/appendices/research/[paper].astro b/src/pages/appendices/research/[paper].astro new file mode 100644 index 0000000..a074e28 --- /dev/null +++ b/src/pages/appendices/research/[paper].astro @@ -0,0 +1,36 @@ +--- + +import { Effect, Either } from "effect" +import { FetchHttpClient } from "@effect/platform" + +import { getArxivDetails } from '../../../lib/arxiv' + +import papers from '../../../data/papers.json'; +import GrArxivPage from "../../../components/GrArxivPage.astro"; + +export function getStaticPaths() { + return papers.map(p => ({params: {paper: p.arxivid}})) +} + +const { paper:arxivid } = Astro.params; + +const fetchPaper = getArxivDetails(arxivid).pipe( + Effect.scoped, + Effect.provide(FetchHttpClient.layer) + ); + +const fetchedEntry = await Effect.runPromise(fetchPaper) + +--- + +{ + Either.match(fetchedEntry, { + onLeft: (error) => ( +
+

Failed to fetch {arxivid}

+
{error.message}
+
+ ), + onRight: (arxivEntry) => () + }) +} diff --git a/tsconfig.json b/tsconfig.json index 77da9dd..ec73207 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,6 @@ { - "extends": "astro/tsconfigs/strict" + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "strict": true + } } \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..9ff3633 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,9 @@ +/// +import { getViteConfig } from 'astro/config'; + +export default getViteConfig({ + test: { + /* for example, use global to avoid globals imports (describe, test, expect): */ + // globals: true, + }, +}); \ No newline at end of file