Compare commits
28 Commits
a71640d493
...
618cee4028
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
618cee4028 | ||
|
|
8244c34d2a | ||
|
|
523d835d00 | ||
|
|
15e96b8fa9 | ||
|
|
44de864713 | ||
|
|
8e1f0a27cf | ||
|
|
8754020323 | ||
|
|
d9a01dae0f | ||
|
|
8873e81f7c | ||
|
|
38fcafb15c | ||
|
|
411397c7de | ||
|
|
85e7b54962 | ||
|
|
ce3989ab77 | ||
|
|
da0f6168f0 | ||
|
|
690dec1f1a | ||
|
|
60274266da | ||
|
|
28424b63cb | ||
|
|
e063eb06f7 | ||
|
|
fb5bb7fcef | ||
|
|
1f57f7d127 | ||
|
|
e8742e5aa6 | ||
|
|
be79d24d6e | ||
|
|
e1349e5e03 | ||
|
|
837dcbb1cb | ||
|
|
8252b6cbdf | ||
|
|
256638bc06 | ||
|
|
c0097bbe81 | ||
|
|
febeaa05d0 |
214
bun.lock
214
bun.lock
@@ -12,41 +12,53 @@
|
||||
"name": "@reffuse/example",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@effect/platform": "~0.77.1",
|
||||
"@effect/platform-browser": "~0.56.1",
|
||||
"@effect/platform": "^0.77.2",
|
||||
"@effect/platform-browser": "^0.56.2",
|
||||
"@radix-ui/themes": "^3.2.0",
|
||||
"@reffuse/extension-lazyref": "workspace:*",
|
||||
"@typed/id": "^0.17.1",
|
||||
"@typed/lazy-ref": "^0.3.3",
|
||||
"effect": "~3.13.1",
|
||||
"lucide-react": "^0.475.0",
|
||||
"effect": "^3.13.2",
|
||||
"lucide-react": "^0.476.0",
|
||||
"mobx": "^6.13.6",
|
||||
"reffuse": "workspace:*",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.20.0",
|
||||
"@tanstack/react-router": "^1.105.0",
|
||||
"@tanstack/router-devtools": "^1.105.0",
|
||||
"@tanstack/router-plugin": "^1.105.0",
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@tanstack/react-router": "^1.111.7",
|
||||
"@tanstack/router-devtools": "^1.111.7",
|
||||
"@tanstack/router-plugin": "^1.111.7",
|
||||
"@thilawyn/thilaschema": "^0.1.4",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"globals": "^15.15.0",
|
||||
"globals": "^16.0.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"typescript-eslint": "^8.24.1",
|
||||
"vite": "^6.1.0",
|
||||
"typescript-eslint": "^8.25.0",
|
||||
"vite": "^6.2.0",
|
||||
},
|
||||
},
|
||||
"packages/extension-lazyref": {
|
||||
"name": "@reffuse/extension-lazyref",
|
||||
"version": "0.1.0",
|
||||
"peerDependencies": {
|
||||
"@typed/lazy-ref": "^0.3.3",
|
||||
"@types/react": "^19.0.0",
|
||||
"effect": "^3.13.0",
|
||||
"react": "^19.0.0",
|
||||
"reffuse": "^0.1.1",
|
||||
},
|
||||
},
|
||||
"packages/reffuse": {
|
||||
"name": "reffuse",
|
||||
"version": "0.1.1",
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.0.10",
|
||||
"effect": "~3.13.1",
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0",
|
||||
"effect": "^3.13.0",
|
||||
"react": "^19.0.0",
|
||||
},
|
||||
},
|
||||
@@ -94,59 +106,59 @@
|
||||
|
||||
"@babel/types": ["@babel/types@7.26.9", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw=="],
|
||||
|
||||
"@effect/platform": ["@effect/platform@0.77.1", "", { "dependencies": { "find-my-way-ts": "^0.1.5", "multipasta": "^0.2.5" }, "peerDependencies": { "effect": "^3.13.1" } }, "sha512-3oHbKiOLN7AIjyucZW+kH5ebG1PhEEBrsdd+HWbDQbAG0gVZfgOUmXR9cyM6M9L+9oVPgOW5mIgcEi6RvD02Cw=="],
|
||||
"@effect/platform": ["@effect/platform@0.77.2", "", { "dependencies": { "find-my-way-ts": "^0.1.5", "multipasta": "^0.2.5" }, "peerDependencies": { "effect": "^3.13.2" } }, "sha512-stvroKHJVfjd3XhZJEPUAOgzqu9DH1vnGHIAjfs2ma6Z4qcjVpFXrxa0ZYmwRaWVIFsiADMenkN0I7XrRdAgLw=="],
|
||||
|
||||
"@effect/platform-browser": ["@effect/platform-browser@0.56.1", "", { "dependencies": { "multipasta": "^0.2.5" }, "peerDependencies": { "@effect/platform": "^0.77.1", "effect": "^3.13.1" } }, "sha512-LKuLblMHuHKsv9ZdN8j44zzY4ftQaGh5jsOWqTtoHIDSS8beUOcp2a5JnsRT310N4Ym7e14cKWfqgdAXm+J0dw=="],
|
||||
"@effect/platform-browser": ["@effect/platform-browser@0.56.2", "", { "dependencies": { "multipasta": "^0.2.5" }, "peerDependencies": { "@effect/platform": "^0.77.2", "effect": "^3.13.2" } }, "sha512-mzCNipg3FN9/ATPEO7Cc3cLmTF4gtdoQSVVi5RPJzIxXflVHbNmMFSIuFdGp0W3AbrQ20dfF6FGFaRUo3aFHeA=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="],
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="],
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.0", "", { "os": "android", "cpu": "arm" }, "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="],
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.0", "", { "os": "android", "cpu": "arm64" }, "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="],
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.0", "", { "os": "android", "cpu": "x64" }, "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="],
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="],
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="],
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="],
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="],
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="],
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="],
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="],
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="],
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="],
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="],
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.0", "", { "os": "linux", "cpu": "none" }, "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="],
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="],
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.0", "", { "os": "linux", "cpu": "x64" }, "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw=="],
|
||||
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="],
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.0", "", { "os": "none", "cpu": "arm64" }, "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="],
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.0", "", { "os": "none", "cpu": "x64" }, "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA=="],
|
||||
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="],
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="],
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="],
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="],
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="],
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="],
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="],
|
||||
|
||||
@@ -154,15 +166,15 @@
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.11.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA=="],
|
||||
"@eslint/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.2.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w=="],
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.20.0", "", {}, "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ=="],
|
||||
"@eslint/js": ["@eslint/js@9.21.0", "", {}, "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.5", "", { "dependencies": { "@eslint/core": "^0.10.0", "levn": "^0.4.1" } }, "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A=="],
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.7", "", { "dependencies": { "@eslint/core": "^0.12.0", "levn": "^0.4.1" } }, "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g=="],
|
||||
|
||||
"@floating-ui/core": ["@floating-ui/core@1.6.9", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw=="],
|
||||
|
||||
@@ -178,7 +190,7 @@
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.1", "", {}, "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA=="],
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||
|
||||
@@ -314,6 +326,8 @@
|
||||
|
||||
"@reffuse/example": ["@reffuse/example@workspace:packages/example"],
|
||||
|
||||
"@reffuse/extension-lazyref": ["@reffuse/extension-lazyref@workspace:packages/extension-lazyref"],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.8", "", { "os": "android", "cpu": "arm" }, "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q=="],
|
||||
@@ -356,17 +370,17 @@
|
||||
|
||||
"@tanstack/history": ["@tanstack/history@1.99.13", "", {}, "sha512-JMd7USmnp8zV8BRGIjALqzPxazvKtQ7PGXQC7n39HpbqdsmfV2ePCzieO84IvN+mwsTrXErpbjI4BfKCa+ZNCg=="],
|
||||
|
||||
"@tanstack/react-router": ["@tanstack/react-router@1.105.0", "", { "dependencies": { "@tanstack/history": "1.99.13", "@tanstack/react-store": "^0.7.0", "@tanstack/router-core": "^1.104.1", "jsesc": "^3.1.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-k4Umuy7rna/hhfHkmbq9dCmj9Hp8D0V6dPNCrCXceJb0gQWGxl1KWLXFbw8Ywe/sNyzIzPrMwrMit++MXHo8iw=="],
|
||||
"@tanstack/react-router": ["@tanstack/react-router@1.111.7", "", { "dependencies": { "@tanstack/history": "1.99.13", "@tanstack/react-store": "^0.7.0", "@tanstack/router-core": "^1.111.7", "jsesc": "^3.1.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-/hOWy7lPmVfRqbwIy2d9mvVLA6ZC4tbcgLDdMXCNRN93LMsGEHCTrgFADdSL2f/rvhPyHeYxsFazEo9+ktgUiw=="],
|
||||
|
||||
"@tanstack/react-store": ["@tanstack/react-store@0.7.0", "", { "dependencies": { "@tanstack/store": "0.7.0", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-S/Rq17HaGOk+tQHV/yrePMnG1xbsKZIl/VsNWnNXt4XW+tTY8dTlvpJH2ZQ3GRALsusG5K6Q3unAGJ2pd9W/Ng=="],
|
||||
|
||||
"@tanstack/router-core": ["@tanstack/router-core@1.104.1", "", { "dependencies": { "@tanstack/history": "1.99.13", "@tanstack/store": "^0.7.0" } }, "sha512-8nP/V5paP+S/17rlw+B2F12R2bB9PixU/+qnD2QdCjK1ajnG4qA0pVN3VSTQe2oCKND6GPZpm2ikmQWumwss9Q=="],
|
||||
"@tanstack/router-core": ["@tanstack/router-core@1.111.7", "", { "dependencies": { "@tanstack/history": "1.99.13", "@tanstack/store": "^0.7.0" } }, "sha512-N3u3HGBNb1k+MvL15CGmE4KFEDy3euU/L3ENXjmzPm8zfpeVjs+Tyk3y0nicAk3MSSboGXVU1po19RATdWnTsg=="],
|
||||
|
||||
"@tanstack/router-devtools": ["@tanstack/router-devtools@1.105.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16" }, "peerDependencies": { "@tanstack/react-router": "^1.105.0", "csstype": "^3.0.10", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["csstype"] }, "sha512-X583hyUyhL30g5ax1J/lbgb3DYpgsiSUv0ERaF5Gg0PoxPYJSybmw79xwFbrTBDxXCXxfg4AFCAEcmkAQemPWA=="],
|
||||
"@tanstack/router-devtools": ["@tanstack/router-devtools@1.111.7", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16" }, "peerDependencies": { "@tanstack/react-router": "^1.111.7", "csstype": "^3.0.10", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["csstype"] }, "sha512-xZpiIWy/HBhpYUqUxT1dNUn5smQhWhkgjNlJOATzrm81G5T3l2jEr79XPXqwRndWzu2WKqv1kPkScC0ekRgE7Q=="],
|
||||
|
||||
"@tanstack/router-generator": ["@tanstack/router-generator@1.105.0", "", { "dependencies": { "@tanstack/virtual-file-routes": "^1.99.0", "prettier": "^3.5.0", "tsx": "^4.19.2", "zod": "^3.24.1" }, "peerDependencies": { "@tanstack/react-router": "^1.105.0" }, "optionalPeers": ["@tanstack/react-router"] }, "sha512-P5e4S7XcaECWKDdR4Zs/FpY4Z127zGv1FcmKEzsFRSGJZm7lHshWayYJIjwkeJ+Ier2IkVN+VRaFWC5GKv0jIg=="],
|
||||
"@tanstack/router-generator": ["@tanstack/router-generator@1.111.7", "", { "dependencies": { "@tanstack/virtual-file-routes": "^1.99.0", "prettier": "^3.5.0", "tsx": "^4.19.2", "zod": "^3.24.1" }, "peerDependencies": { "@tanstack/react-router": "^1.111.7" }, "optionalPeers": ["@tanstack/react-router"] }, "sha512-+jHX35iF45NHQvHzXuLgyCILUUTyMl3EeClKNkfdaKLvV1adwGDQr24cSKDQLmNKEDXGTijBI5nX8ntkKo5oyA=="],
|
||||
|
||||
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.105.0", "", { "dependencies": { "@babel/core": "^7.26.8", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9", "@babel/template": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/router-generator": "^1.105.0", "@tanstack/router-utils": "^1.102.2", "@tanstack/virtual-file-routes": "^1.99.0", "@types/babel__core": "^7.20.5", "@types/babel__template": "^7.4.4", "@types/babel__traverse": "^7.20.6", "babel-dead-code-elimination": "^1.0.9", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.1" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.105.0", "vite": ">=5.0.0 || >=6.0.0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "webpack"] }, "sha512-iGwKZIyl8+os4PA9v57BlTtKVnQ5mCvxYT4p5TR/Q8zW1KBs4fC5F7EhL1BgH8fY12IL4ByuuJ+porzp+mfmJQ=="],
|
||||
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.111.7", "", { "dependencies": { "@babel/core": "^7.26.8", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9", "@babel/template": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/router-core": "^1.111.7", "@tanstack/router-generator": "^1.111.7", "@tanstack/router-utils": "^1.102.2", "@tanstack/virtual-file-routes": "^1.99.0", "@types/babel__core": "^7.20.5", "@types/babel__template": "^7.4.4", "@types/babel__traverse": "^7.20.6", "babel-dead-code-elimination": "^1.0.9", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.1" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.111.7", "vite": ">=5.0.0 || >=6.0.0", "vite-plugin-solid": "^2.11.2", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-aiT/j2OadGbqEWTZUY53o2UeVQIR11+S1h1Gq6GYxQmD/OjdyK/WiMighBK5zeryeWYG4XeC8eFlXMoyuG0v+g=="],
|
||||
|
||||
"@tanstack/router-utils": ["@tanstack/router-utils@1.102.2", "", { "dependencies": { "@babel/generator": "^7.26.8", "@babel/parser": "^7.26.8", "ansis": "^3.11.0", "diff": "^7.0.0" } }, "sha512-Uwl2nbrxhCzviaHHBLNPhSC/OMpZLdOTxTJndUSsXTzWUP4IoQcVmngaIsxi9iriE3ArC1VXuanUAkfGmimNOQ=="],
|
||||
|
||||
@@ -396,21 +410,21 @@
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.0.4", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.24.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.24.1", "@typescript-eslint/type-utils": "8.24.1", "@typescript-eslint/utils": "8.24.1", "@typescript-eslint/visitor-keys": "8.24.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-ll1StnKtBigWIGqvYDVuDmXJHVH4zLVot1yQ4fJtLpL7qacwkxJc1T0bptqw+miBQ/QfUbhl1TcQ4accW5KUyA=="],
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.25.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/type-utils": "8.25.0", "@typescript-eslint/utils": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA=="],
|
||||
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.24.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.24.1", "@typescript-eslint/types": "8.24.1", "@typescript-eslint/typescript-estree": "8.24.1", "@typescript-eslint/visitor-keys": "8.24.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-Tqoa05bu+t5s8CTZFaGpCH2ub3QeT9YDkXbPd3uQ4SfsLoh1/vv2GEYAioPoxCWJJNsenXlC88tRjwoHNts1oQ=="],
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.25.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/types": "8.25.0", "@typescript-eslint/typescript-estree": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg=="],
|
||||
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.24.1", "", { "dependencies": { "@typescript-eslint/types": "8.24.1", "@typescript-eslint/visitor-keys": "8.24.1" } }, "sha512-OdQr6BNBzwRjNEXMQyaGyZzgg7wzjYKfX2ZBV3E04hUCBDv3GQCHiz9RpqdUIiVrMgJGkXm3tcEh4vFSHreS2Q=="],
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0" } }, "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg=="],
|
||||
|
||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.24.1", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.24.1", "@typescript-eslint/utils": "8.24.1", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-/Do9fmNgCsQ+K4rCz0STI7lYB4phTtEXqqCAs3gZW0pnK7lWNkvWd5iW545GSmApm4AzmQXmSqXPO565B4WVrw=="],
|
||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.25.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.25.0", "@typescript-eslint/utils": "8.25.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.24.1", "", {}, "sha512-9kqJ+2DkUXiuhoiYIUvIYjGcwle8pcPpdlfkemGvTObzgmYfJ5d0Qm6jwb4NBXP9W1I5tss0VIAnWFumz3mC5A=="],
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.25.0", "", {}, "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.24.1", "", { "dependencies": { "@typescript-eslint/types": "8.24.1", "@typescript-eslint/visitor-keys": "8.24.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-UPyy4MJ/0RE648DSKQe9g0VDSehPINiejjA6ElqnFaFIhI6ZEiZAkUI0D5MCk0bQcTf/LVqZStvQ6K4lPn/BRg=="],
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q=="],
|
||||
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.24.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.24.1", "@typescript-eslint/types": "8.24.1", "@typescript-eslint/typescript-estree": "8.24.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-OOcg3PMMQx9EXspId5iktsI3eMaXVwlhC8BvNnX6B5w9a4dVgpkQZuU8Hy67TolKcl+iFWq0XX+jbDGN4xWxjQ=="],
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.25.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/types": "8.25.0", "@typescript-eslint/typescript-estree": "8.25.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.24.1", "", { "dependencies": { "@typescript-eslint/types": "8.24.1", "eslint-visitor-keys": "^4.2.0" } }, "sha512-EwVHlp5l+2vp8CoqJm9KikPZgi3gbdZAtabKT9KPShGeOcJhsv4Zdo3oc8T8I0uKEmYoU4ItyxbptjF08enaxg=="],
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.25.0", "", { "dependencies": { "@typescript-eslint/types": "8.25.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ=="],
|
||||
|
||||
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="],
|
||||
|
||||
@@ -422,7 +436,7 @@
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"ansis": ["ansis@3.15.0", "", {}, "sha512-zIcWDJ+Kwqxfdnogx66Gxzr0kVmCcRAdat9nlY2IHsshqTN4fBH6tMeRMPA/2w0rpBayIJvjQAaa2/4RDrNqwg=="],
|
||||
"ansis": ["ansis@3.16.0", "", {}, "sha512-sU7d/tfZiYrsIAXbdL/CNZld5bCkruzwT5KmqmadCJYxuLxHAOBjidxD5+iLmN/6xEfjcQq1l7OpsiCBlc4LzA=="],
|
||||
|
||||
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
||||
|
||||
@@ -474,17 +488,17 @@
|
||||
|
||||
"diff": ["diff@7.0.0", "", {}, "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="],
|
||||
|
||||
"effect": ["effect@3.13.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-YbA45m51eZapqy/ptZvIIZi+XBj13fPCzbiDRLgxZTEUhKuf4xLzuuSsKc61Y3SIscMM2o+VPht2ty+bVEQHQQ=="],
|
||||
"effect": ["effect@3.13.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-/w+CPqHDJ33Wq7xC4YKAchrEEPtjvxh563xH9kDTZp99seNYBoBs87vl8DJwartEjj+KLQLP8PzoDne+XmGT2A=="],
|
||||
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.102", "", {}, "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q=="],
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.104", "", {}, "sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g=="],
|
||||
|
||||
"esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="],
|
||||
"esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="],
|
||||
|
||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.20.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g=="],
|
||||
"eslint": ["eslint@9.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="],
|
||||
|
||||
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.1.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw=="],
|
||||
|
||||
@@ -526,7 +540,7 @@
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
|
||||
"flatted": ["flatted@3.3.2", "", {}, "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA=="],
|
||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
@@ -538,7 +552,7 @@
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="],
|
||||
"globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
|
||||
|
||||
"goober": ["goober@2.1.16", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g=="],
|
||||
|
||||
@@ -586,7 +600,7 @@
|
||||
|
||||
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"lucide-react": ["lucide-react@0.475.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg=="],
|
||||
"lucide-react": ["lucide-react@0.476.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-x6cLTk8gahdUPje0hSgLN1/MgiJH+Xl90Xoxy9bkPAsMPOUiyRSKR4JCDPGVCEpyqnZXH3exFWNItcvra9WzUQ=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
@@ -608,7 +622,7 @@
|
||||
|
||||
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
||||
|
||||
"npm-check-updates": ["npm-check-updates@17.1.14", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-dr4bXIxETubLI1tFGeock5hN8yVjahvaVpx+lPO4/O2md3zJuxB7FgH3MIoTvQSCgsgkIRpe0skti01IEAA5tA=="],
|
||||
"npm-check-updates": ["npm-check-updates@17.1.15", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-miATvKu5rjec/1wxc5TGDjpsucgtCHwRVZorZpDkS6NzdWXfnUWlN4abZddWb7XSijAuBNzzYglIdTm9SbgMVg=="],
|
||||
|
||||
"npm-sort": ["npm-sort@0.0.4", "", { "bin": { "npm-sort": "./index.js" } }, "sha512-S5Id/3Jvr7Cf/QnWjRteprngERCBhhEFOM+wMhUrAYP060/HUBC1aL5GoXS3xITlgacJCWaSmP4HQaAt91nNYQ=="],
|
||||
|
||||
@@ -628,11 +642,11 @@
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"postcss": ["postcss@8.5.2", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA=="],
|
||||
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.5.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw=="],
|
||||
"prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
@@ -694,7 +708,7 @@
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tsx": ["tsx@4.19.2", "", { "dependencies": { "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g=="],
|
||||
"tsx": ["tsx@4.19.3", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
@@ -702,7 +716,7 @@
|
||||
|
||||
"typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
||||
|
||||
"typescript-eslint": ["typescript-eslint@8.24.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.24.1", "@typescript-eslint/parser": "8.24.1", "@typescript-eslint/utils": "8.24.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-cw3rEdzDqBs70TIcb0Gdzbt6h11BSs2pS0yaq7hDWDBtCCSei1pPSUXE9qUdQ/Wm9NgFg8mKtMt1b8fTHIl1jA=="],
|
||||
"typescript-eslint": ["typescript-eslint@8.25.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.25.0", "@typescript-eslint/parser": "8.25.0", "@typescript-eslint/utils": "8.25.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q=="],
|
||||
|
||||
"unplugin": ["unplugin@2.2.0", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw=="],
|
||||
|
||||
@@ -716,7 +730,7 @@
|
||||
|
||||
"use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="],
|
||||
|
||||
"vite": ["vite@6.1.0", "", { "dependencies": { "esbuild": "^0.24.2", "postcss": "^8.5.1", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ=="],
|
||||
"vite": ["vite@6.2.0", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ=="],
|
||||
|
||||
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
|
||||
|
||||
@@ -736,8 +750,6 @@
|
||||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.10.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw=="],
|
||||
|
||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
@@ -748,56 +760,6 @@
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"tsx/esbuild": ["esbuild@0.23.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.23.1", "@esbuild/android-arm": "0.23.1", "@esbuild/android-arm64": "0.23.1", "@esbuild/android-x64": "0.23.1", "@esbuild/darwin-arm64": "0.23.1", "@esbuild/darwin-x64": "0.23.1", "@esbuild/freebsd-arm64": "0.23.1", "@esbuild/freebsd-x64": "0.23.1", "@esbuild/linux-arm": "0.23.1", "@esbuild/linux-arm64": "0.23.1", "@esbuild/linux-ia32": "0.23.1", "@esbuild/linux-loong64": "0.23.1", "@esbuild/linux-mips64el": "0.23.1", "@esbuild/linux-ppc64": "0.23.1", "@esbuild/linux-riscv64": "0.23.1", "@esbuild/linux-s390x": "0.23.1", "@esbuild/linux-x64": "0.23.1", "@esbuild/netbsd-x64": "0.23.1", "@esbuild/openbsd-arm64": "0.23.1", "@esbuild/openbsd-x64": "0.23.1", "@esbuild/sunos-x64": "0.23.1", "@esbuild/win32-arm64": "0.23.1", "@esbuild/win32-ia32": "0.23.1", "@esbuild/win32-x64": "0.23.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.23.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.23.1", "", { "os": "android", "cpu": "arm" }, "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.23.1", "", { "os": "android", "cpu": "arm64" }, "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.23.1", "", { "os": "android", "cpu": "x64" }, "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.23.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.23.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.23.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.23.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.23.1", "", { "os": "linux", "cpu": "arm" }, "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.23.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.23.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.23.1", "", { "os": "linux", "cpu": "none" }, "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.23.1", "", { "os": "linux", "cpu": "none" }, "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.23.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.23.1", "", { "os": "linux", "cpu": "none" }, "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.23.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.23.1", "", { "os": "linux", "cpu": "x64" }, "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.23.1", "", { "os": "none", "cpu": "x64" }, "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.23.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.23.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.23.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.23.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.23.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.23.1", "", { "os": "win32", "cpu": "x64" }, "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,35 +11,36 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.20.0",
|
||||
"@tanstack/react-router": "^1.105.0",
|
||||
"@tanstack/router-devtools": "^1.105.0",
|
||||
"@tanstack/router-plugin": "^1.105.0",
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@tanstack/react-router": "^1.111.7",
|
||||
"@tanstack/router-devtools": "^1.111.7",
|
||||
"@tanstack/router-plugin": "^1.111.7",
|
||||
"@thilawyn/thilaschema": "^0.1.4",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"globals": "^15.15.0",
|
||||
"globals": "^16.0.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"typescript-eslint": "^8.24.1",
|
||||
"vite": "^6.1.0"
|
||||
"typescript-eslint": "^8.25.0",
|
||||
"vite": "^6.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@effect/platform": "~0.77.1",
|
||||
"@effect/platform-browser": "~0.56.1",
|
||||
"@effect/platform": "^0.77.2",
|
||||
"@effect/platform-browser": "^0.56.2",
|
||||
"@radix-ui/themes": "^3.2.0",
|
||||
"@reffuse/extension-lazyref": "workspace:*",
|
||||
"@typed/id": "^0.17.1",
|
||||
"@typed/lazy-ref": "^0.3.3",
|
||||
"effect": "~3.13.1",
|
||||
"lucide-react": "^0.475.0",
|
||||
"effect": "^3.13.2",
|
||||
"lucide-react": "^0.476.0",
|
||||
"mobx": "^6.13.6",
|
||||
"reffuse": "workspace:*"
|
||||
},
|
||||
"overrides": {
|
||||
"effect": "~3.13.1"
|
||||
"effect": "^3.13.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { HttpClient } from "@effect/platform"
|
||||
import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser"
|
||||
import { LazyRefExtension } from "@reffuse/extension-lazyref"
|
||||
import { Reffuse, ReffuseContext } from "reffuse"
|
||||
|
||||
|
||||
@@ -10,4 +11,9 @@ export const GlobalContext = ReffuseContext.make<
|
||||
| HttpClient.HttpClient
|
||||
>()
|
||||
|
||||
export const R = Reffuse.make(GlobalContext)
|
||||
export class GlobalReffuse extends Reffuse.Reffuse.pipe(
|
||||
Reffuse.withExtension(LazyRefExtension),
|
||||
Reffuse.withContexts(GlobalContext),
|
||||
) {}
|
||||
|
||||
export const R = new GlobalReffuse()
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Route as rootRoute } from './routes/__root'
|
||||
import { Route as TimeImport } from './routes/time'
|
||||
import { Route as TestsImport } from './routes/tests'
|
||||
import { Route as PromiseImport } from './routes/promise'
|
||||
import { Route as LazyrefImport } from './routes/lazyref'
|
||||
import { Route as CountImport } from './routes/count'
|
||||
import { Route as BlankImport } from './routes/blank'
|
||||
import { Route as IndexImport } from './routes/index'
|
||||
@@ -38,6 +39,12 @@ const PromiseRoute = PromiseImport.update({
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const LazyrefRoute = LazyrefImport.update({
|
||||
id: '/lazyref',
|
||||
path: '/lazyref',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const CountRoute = CountImport.update({
|
||||
id: '/count',
|
||||
path: '/count',
|
||||
@@ -81,6 +88,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof CountImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/lazyref': {
|
||||
id: '/lazyref'
|
||||
path: '/lazyref'
|
||||
fullPath: '/lazyref'
|
||||
preLoaderRoute: typeof LazyrefImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/promise': {
|
||||
id: '/promise'
|
||||
path: '/promise'
|
||||
@@ -111,6 +125,7 @@ export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/blank': typeof BlankRoute
|
||||
'/count': typeof CountRoute
|
||||
'/lazyref': typeof LazyrefRoute
|
||||
'/promise': typeof PromiseRoute
|
||||
'/tests': typeof TestsRoute
|
||||
'/time': typeof TimeRoute
|
||||
@@ -120,6 +135,7 @@ export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/blank': typeof BlankRoute
|
||||
'/count': typeof CountRoute
|
||||
'/lazyref': typeof LazyrefRoute
|
||||
'/promise': typeof PromiseRoute
|
||||
'/tests': typeof TestsRoute
|
||||
'/time': typeof TimeRoute
|
||||
@@ -130,6 +146,7 @@ export interface FileRoutesById {
|
||||
'/': typeof IndexRoute
|
||||
'/blank': typeof BlankRoute
|
||||
'/count': typeof CountRoute
|
||||
'/lazyref': typeof LazyrefRoute
|
||||
'/promise': typeof PromiseRoute
|
||||
'/tests': typeof TestsRoute
|
||||
'/time': typeof TimeRoute
|
||||
@@ -137,10 +154,25 @@ export interface FileRoutesById {
|
||||
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/' | '/blank' | '/count' | '/promise' | '/tests' | '/time'
|
||||
fullPaths:
|
||||
| '/'
|
||||
| '/blank'
|
||||
| '/count'
|
||||
| '/lazyref'
|
||||
| '/promise'
|
||||
| '/tests'
|
||||
| '/time'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/blank' | '/count' | '/promise' | '/tests' | '/time'
|
||||
id: '__root__' | '/' | '/blank' | '/count' | '/promise' | '/tests' | '/time'
|
||||
to: '/' | '/blank' | '/count' | '/lazyref' | '/promise' | '/tests' | '/time'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/blank'
|
||||
| '/count'
|
||||
| '/lazyref'
|
||||
| '/promise'
|
||||
| '/tests'
|
||||
| '/time'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
|
||||
@@ -148,6 +180,7 @@ export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
BlankRoute: typeof BlankRoute
|
||||
CountRoute: typeof CountRoute
|
||||
LazyrefRoute: typeof LazyrefRoute
|
||||
PromiseRoute: typeof PromiseRoute
|
||||
TestsRoute: typeof TestsRoute
|
||||
TimeRoute: typeof TimeRoute
|
||||
@@ -157,6 +190,7 @@ const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
BlankRoute: BlankRoute,
|
||||
CountRoute: CountRoute,
|
||||
LazyrefRoute: LazyrefRoute,
|
||||
PromiseRoute: PromiseRoute,
|
||||
TestsRoute: TestsRoute,
|
||||
TimeRoute: TimeRoute,
|
||||
@@ -175,6 +209,7 @@ export const routeTree = rootRoute
|
||||
"/",
|
||||
"/blank",
|
||||
"/count",
|
||||
"/lazyref",
|
||||
"/promise",
|
||||
"/tests",
|
||||
"/time"
|
||||
@@ -189,6 +224,9 @@ export const routeTree = rootRoute
|
||||
"/count": {
|
||||
"filePath": "count.tsx"
|
||||
},
|
||||
"/lazyref": {
|
||||
"filePath": "lazyref.tsx"
|
||||
},
|
||||
"/promise": {
|
||||
"filePath": "promise.tsx"
|
||||
},
|
||||
|
||||
31
packages/example/src/routes/lazyref.tsx
Normal file
31
packages/example/src/routes/lazyref.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { R } from "@/reffuse"
|
||||
import { Button, Text } from "@radix-ui/themes"
|
||||
import { createFileRoute } from "@tanstack/react-router"
|
||||
import * as LazyRef from "@typed/lazy-ref"
|
||||
import { Suspense, use } from "react"
|
||||
|
||||
|
||||
export const Route = createFileRoute("/lazyref")({
|
||||
component: RouteComponent
|
||||
})
|
||||
|
||||
function RouteComponent() {
|
||||
const promise = R.usePromise(() => LazyRef.of(0))
|
||||
|
||||
return (
|
||||
<Suspense fallback={<Text>Loading...</Text>}>
|
||||
<LazyRefComponent promise={promise} />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
function LazyRefComponent({ promise }: { readonly promise: Promise<LazyRef.LazyRef<number>> }) {
|
||||
const ref = use(promise)
|
||||
const [value, setValue] = R.useLazyRefState(ref)
|
||||
|
||||
return (
|
||||
<Button onClick={() => setValue(prev => prev + 1)}>
|
||||
{value}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -15,7 +15,7 @@ const Result = Schema.Tuple(Schema.String)
|
||||
type Result = typeof Result.Type
|
||||
|
||||
function RouteComponent() {
|
||||
const promise = R.usePromise(Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
const promise = R.usePromise(() => Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
Effect.andThen(HttpClient.get("https://www.uuidtools.com/api/generate/v4")),
|
||||
HttpClient.withTracerPropagation(false),
|
||||
Effect.flatMap(res => res.json),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { R } from "@/reffuse"
|
||||
import { Button } from "@radix-ui/themes"
|
||||
import { createFileRoute } from "@tanstack/react-router"
|
||||
import { Console, Effect } from "effect"
|
||||
|
||||
@@ -14,11 +15,17 @@ function RouteComponent() {
|
||||
// ), [])
|
||||
// console.log(value)
|
||||
|
||||
R.useFork(Effect.addFinalizer(() => Console.log("cleanup")).pipe(
|
||||
R.useFork(() => Effect.addFinalizer(() => Console.log("cleanup")).pipe(
|
||||
Effect.andThen(Console.log("ouient")),
|
||||
Effect.delay("1 second"),
|
||||
))
|
||||
|
||||
const logValue = R.useCallbackSync(Effect.fn(function*(value: string) {
|
||||
yield* Effect.log(value)
|
||||
}))
|
||||
|
||||
return <div>Hello "/tests"!</div>
|
||||
|
||||
return (
|
||||
<Button onClick={() => logValue("test")}>Log value</Button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ export const Route = createFileRoute("/time")({
|
||||
|
||||
function Time() {
|
||||
|
||||
const timeRef = R.useMemo(DateTime.now.pipe(Effect.flatMap(SubscriptionRef.make)))
|
||||
const timeRef = R.useMemo(() => DateTime.now.pipe(Effect.flatMap(SubscriptionRef.make)))
|
||||
|
||||
R.useFork(Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
R.useFork(() => Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
Effect.andThen(Stream.runForEach(timeEverySecond, v => Ref.set(timeRef, v)))
|
||||
), [timeRef])
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { GlobalContext } from "@/reffuse"
|
||||
import { GlobalReffuse } from "@/reffuse"
|
||||
import { Reffuse, ReffuseContext } from "reffuse"
|
||||
import { TodosState } from "./services"
|
||||
|
||||
|
||||
export const TodosContext = ReffuseContext.make<TodosState.TodosState>()
|
||||
export const R = Reffuse.make(GlobalContext, TodosContext)
|
||||
|
||||
export const R = new class TodosReffuse extends GlobalReffuse.pipe(
|
||||
Reffuse.withContexts(TodosContext)
|
||||
) {}
|
||||
|
||||
@@ -18,7 +18,7 @@ export function VNewTodo() {
|
||||
|
||||
const runSync = R.useRunSync()
|
||||
|
||||
const todoRef = R.useMemo(createEmptyTodo.pipe(Effect.flatMap(SubscriptionRef.make)))
|
||||
const todoRef = R.useMemo(() => createEmptyTodo.pipe(Effect.flatMap(SubscriptionRef.make)))
|
||||
const [todo, setTodo] = R.useRefState(todoRef)
|
||||
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ import { VTodo } from "./VTodo"
|
||||
export function VTodos() {
|
||||
|
||||
// Sync changes to the todos with the local storage
|
||||
R.useFork(TodosState.TodosState.pipe(
|
||||
R.useFork(() => TodosState.TodosState.pipe(
|
||||
Effect.flatMap(state =>
|
||||
Stream.runForEach(state.todos.changes, () => state.saveToLocalStorage)
|
||||
)
|
||||
))
|
||||
|
||||
const todosRef = R.useMemo(TodosState.TodosState.pipe(Effect.map(state => state.todos)))
|
||||
const todosRef = R.useMemo(() => TodosState.TodosState.pipe(Effect.map(state => state.todos)))
|
||||
const [todos] = R.useRefState(todosRef)
|
||||
|
||||
|
||||
|
||||
12
packages/extension-lazyref/README.md
Normal file
12
packages/extension-lazyref/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Reffuse
|
||||
|
||||
[Effect-TS](https://effect.website/) integration for React 19+ with the aim of integrating the Effect context system within React's component hierarchy, while avoiding touching React's internals.
|
||||
|
||||
This library is in early development. While it is (almost) feature complete and mostly usable, expect bugs and quirks. Things are still being ironed out, so ideas and criticisms are more than welcome.
|
||||
|
||||
Documentation is currently being written. In the meantime, you can take a look at the `packages/example` directory.
|
||||
|
||||
## Dependencies
|
||||
(needs to be manually installed)
|
||||
- `effect`
|
||||
- `react` 19+
|
||||
38
packages/extension-lazyref/package.json
Normal file
38
packages/extension-lazyref/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@reffuse/extension-lazyref",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"./README.md",
|
||||
"./dist"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"url": "git+https://github.com/Thiladev/reffuse.git"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./*": {
|
||||
"types": "./dist/*.d.ts",
|
||||
"default": "./dist/*.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"lint:tsc": "tsc --noEmit",
|
||||
"clean:cache": "rm -f tsconfig.tsbuildinfo",
|
||||
"clean:dist": "rm -rf dist",
|
||||
"clean:node": "rm -rf node_modules"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typed/lazy-ref": "^0.3.3",
|
||||
"@types/react": "^19.0.0",
|
||||
"effect": "^3.13.0",
|
||||
"react": "^19.0.0",
|
||||
"reffuse": "^0.1.1"
|
||||
}
|
||||
}
|
||||
29
packages/extension-lazyref/src/index.ts
Normal file
29
packages/extension-lazyref/src/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import * as LazyRef from "@typed/lazy-ref"
|
||||
import { Effect, Stream } from "effect"
|
||||
import * as React from "react"
|
||||
import { ReffuseExtension, type ReffuseHelpers, SetStateAction } from "reffuse"
|
||||
|
||||
|
||||
export const LazyRefExtension = ReffuseExtension.make(() => ({
|
||||
useLazyRefState<A, E, R>(
|
||||
this: ReffuseHelpers.ReffuseHelpers<R>,
|
||||
ref: LazyRef.LazyRef<A, E, R>,
|
||||
): [A, React.Dispatch<React.SetStateAction<A>>] {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
const initialState = React.useMemo(() => runSync(ref), [])
|
||||
const [reactStateValue, setReactStateValue] = React.useState(initialState)
|
||||
|
||||
this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() =>
|
||||
setReactStateValue(v)
|
||||
)), [ref])
|
||||
|
||||
const setValue = React.useCallback((setStateAction: React.SetStateAction<A>) =>
|
||||
runSync(LazyRef.update(ref, prevState =>
|
||||
SetStateAction.value(setStateAction, prevState)
|
||||
)),
|
||||
[ref])
|
||||
|
||||
return [reactStateValue, setValue]
|
||||
},
|
||||
}))
|
||||
33
packages/extension-lazyref/tsconfig.json
Normal file
33
packages/extension-lazyref/tsconfig.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"target": "ESNext",
|
||||
"module": "NodeNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
// "allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "NodeNext",
|
||||
// "allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
// "noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
|
||||
// Build
|
||||
"outDir": "./dist",
|
||||
"declaration": true
|
||||
},
|
||||
|
||||
"include": ["./src"]
|
||||
}
|
||||
@@ -28,9 +28,9 @@
|
||||
"clean:dist": "rm -rf dist",
|
||||
"clean:node": "rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.0.10",
|
||||
"effect": "~3.13.1",
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0",
|
||||
"effect": "^3.13.0",
|
||||
"react": "^19.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,399 +1,47 @@
|
||||
import { Context, Effect, ExecutionStrategy, Exit, Fiber, Pipeable, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect"
|
||||
import * as React from "react"
|
||||
import * as ReffuseContext from "./ReffuseContext.js"
|
||||
import * as ReffuseRuntime from "./ReffuseRuntime.js"
|
||||
import * as SetStateAction from "./SetStateAction.js"
|
||||
import type * as ReffuseContext from "./ReffuseContext.js"
|
||||
import type * as ReffuseExtension from "./ReffuseExtension.js"
|
||||
import * as ReffuseHelpers from "./ReffuseHelpers.js"
|
||||
import type { Merge, StaticType } from "./types.js"
|
||||
|
||||
|
||||
export class Reffuse<R> {
|
||||
|
||||
constructor(
|
||||
readonly contexts: readonly ReffuseContext.ReffuseContext<R>[]
|
||||
) {}
|
||||
export class Reffuse extends ReffuseHelpers.make() {}
|
||||
|
||||
|
||||
useContext(): Context.Context<R> {
|
||||
return ReffuseContext.useMergeAll(...this.contexts)
|
||||
export const withContexts = <R2 extends Array<unknown>>(
|
||||
...contexts: [...{ [K in keyof R2]: ReffuseContext.ReffuseContext<R2[K]> }]
|
||||
) =>
|
||||
<
|
||||
BaseClass extends ReffuseHelpers.ReffuseHelpersClass<R1>,
|
||||
R1
|
||||
>(
|
||||
self: BaseClass & ReffuseHelpers.ReffuseHelpersClass<R1>
|
||||
): (
|
||||
{
|
||||
new(): Merge<
|
||||
InstanceType<BaseClass>,
|
||||
{ constructor: ReffuseHelpers.ReffuseHelpersClass<R1 | R2[number]> }
|
||||
>
|
||||
} &
|
||||
Merge<
|
||||
StaticType<BaseClass>,
|
||||
StaticType<ReffuseHelpers.ReffuseHelpersClass<R1 | R2[number]>>
|
||||
>
|
||||
) => class extends self {
|
||||
static readonly contexts = [...self.contexts, ...contexts]
|
||||
} as any
|
||||
|
||||
|
||||
export const withExtension = <A extends object>(extension: ReffuseExtension.ReffuseExtension<A>) =>
|
||||
<
|
||||
BaseClass extends ReffuseHelpers.ReffuseHelpersClass<R>,
|
||||
R
|
||||
>(
|
||||
self: BaseClass & ReffuseHelpers.ReffuseHelpersClass<R>
|
||||
): (
|
||||
{ new(): Merge<InstanceType<BaseClass>, A> } &
|
||||
StaticType<BaseClass>
|
||||
) => {
|
||||
const class_ = class extends self {}
|
||||
Object.assign(class_.prototype, extension())
|
||||
return class_ as any
|
||||
}
|
||||
|
||||
|
||||
useRunSync() {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback(<A, E>(
|
||||
effect: Effect.Effect<A, E, R>
|
||||
): A => effect.pipe(
|
||||
Effect.provide(context),
|
||||
Runtime.runSync(runtime),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunPromise() {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback(<A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: { readonly signal?: AbortSignal },
|
||||
): Promise<A> => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runPromise(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunFork() {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback(<A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: Runtime.RunForkOptions,
|
||||
): Fiber.RuntimeFiber<A, E> => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runFork(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunCallback() {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback(<A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: Runtime.RunCallbackOptions<A, E>,
|
||||
): Runtime.Cancel<A, E> => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runCallback(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useMemo`.
|
||||
*
|
||||
* `useMemo` will only recompute the memoized value by running the given synchronous effect when one of the deps has changed. \
|
||||
* Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will recompute the value in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*/
|
||||
useMemo<A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions,
|
||||
): A {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useMemo(() => runSync(effect), [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
useMemoScoped<A, E>(
|
||||
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): A {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
// Calculate an initial version of the value so that it can be accessed during the first render
|
||||
const [initialScope, initialValue] = React.useMemo(() => Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.flatMap(scope => effect.pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.map(value => [scope, value] as const),
|
||||
)),
|
||||
|
||||
runSync,
|
||||
), [])
|
||||
|
||||
// Keep track of the state of the initial scope
|
||||
const initialScopeClosed = React.useRef(false)
|
||||
|
||||
const [value, setValue] = React.useState(initialValue)
|
||||
|
||||
React.useEffect(() => {
|
||||
const closeInitialScopeIfNeeded = Scope.close(initialScope, Exit.void).pipe(
|
||||
Effect.andThen(Effect.sync(() => { initialScopeClosed.current = true })),
|
||||
Effect.when(() => !initialScopeClosed.current),
|
||||
)
|
||||
|
||||
const [scope, value] = closeInitialScopeIfNeeded.pipe(
|
||||
Effect.andThen(Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.flatMap(scope => effect.pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.map(value => [scope, value] as const),
|
||||
))
|
||||
)),
|
||||
|
||||
runSync,
|
||||
)
|
||||
|
||||
setValue(value)
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useEffect`.
|
||||
*
|
||||
* Executes a synchronous effect wrapped into a Scope when one of the deps has changed. Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* useEffect(Effect.addFinalizer(() => Console.log("Component unmounted")).pipe(
|
||||
* Effect.flatMap(() => Console.log("Component mounted"))
|
||||
* ))
|
||||
* ```
|
||||
*
|
||||
* Plain React equivalent:
|
||||
* ```
|
||||
* React.useEffect(() => {
|
||||
* console.log("Component mounted")
|
||||
* return () => { console.log("Component unmounted") }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
useEffect<A, E>(
|
||||
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useEffect(() => {
|
||||
const scope = Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.tap(scope => Effect.provideService(effect, Scope.Scope, scope)),
|
||||
runSync,
|
||||
)
|
||||
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useLayoutEffect`.
|
||||
*
|
||||
* Executes a synchronous effect wrapped into a Scope when one of the deps has changed. Fires synchronously after all DOM mutations. \
|
||||
* Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* useLayoutEffect(Effect.addFinalizer(() => Console.log("Component unmounted")).pipe(
|
||||
* Effect.flatMap(() => Console.log("Component mounted"))
|
||||
* ))
|
||||
* ```
|
||||
*
|
||||
* Plain React equivalent:
|
||||
* ```
|
||||
* React.useLayoutEffect(() => {
|
||||
* console.log("Component mounted")
|
||||
* return () => { console.log("Component unmounted") }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
useLayoutEffect<A, E>(
|
||||
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useLayoutEffect(() => {
|
||||
const scope = Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.tap(scope => Effect.provideService(effect, Scope.Scope, scope)),
|
||||
runSync,
|
||||
)
|
||||
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* An asynchronous and non-blocking alternative to `React.useEffect`.
|
||||
*
|
||||
* Forks an effect wrapped into a Scope in the background when one of the deps has changed.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* const timeRef = useRefFromEffect(DateTime.now)
|
||||
*
|
||||
* useFork(Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
* Effect.map(() => Stream.repeatEffectWithSchedule(
|
||||
* DateTime.now,
|
||||
* Schedule.intersect(Schedule.forever, Schedule.spaced("1 second")),
|
||||
* )),
|
||||
*
|
||||
* Effect.flatMap(Stream.runForEach(time => Ref.set(timeRef, time)),
|
||||
* )), [timeRef])
|
||||
*
|
||||
* const [time] = useRefState(timeRef)
|
||||
* ```
|
||||
*/
|
||||
useFork<A, E>(
|
||||
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: Runtime.RunForkOptions & RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
const runFork = this.useRunFork()
|
||||
|
||||
return React.useEffect(() => {
|
||||
const scope = runSync(options?.scope
|
||||
? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential)
|
||||
: Scope.make(options?.finalizerExecutionStrategy)
|
||||
)
|
||||
runFork(Effect.provideService(effect, Scope.Scope, scope), { ...options, scope })
|
||||
|
||||
return () => { runFork(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
usePromise<A, E>(
|
||||
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: { readonly signal?: AbortSignal } & Runtime.RunForkOptions & RenderOptions & ScopeOptions,
|
||||
): Promise<A> {
|
||||
const runSync = this.useRunSync()
|
||||
const runFork = this.useRunFork()
|
||||
|
||||
const [value, setValue] = React.useState(Promise.withResolvers<A>().promise)
|
||||
|
||||
React.useEffect(() => {
|
||||
const { promise, resolve, reject } = Promise.withResolvers<A>()
|
||||
setValue(promise)
|
||||
|
||||
const scope = runSync(options?.scope
|
||||
? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential)
|
||||
: Scope.make(options?.finalizerExecutionStrategy)
|
||||
)
|
||||
|
||||
const cleanup = () => { runFork(Scope.close(scope, Exit.void)) }
|
||||
if (options?.signal)
|
||||
options.signal.addEventListener("abort", cleanup)
|
||||
|
||||
effect.pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.match({
|
||||
onSuccess: resolve,
|
||||
onFailure: reject,
|
||||
}),
|
||||
effect => runFork(effect, { ...options, scope }),
|
||||
)
|
||||
|
||||
return () => {
|
||||
if (options?.signal)
|
||||
options.signal.removeEventListener("abort", cleanup)
|
||||
|
||||
cleanup()
|
||||
}
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork],
|
||||
...(deps ?? []),
|
||||
])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
useRef<A>(value: A): SubscriptionRef.SubscriptionRef<A> {
|
||||
return this.useMemo(
|
||||
SubscriptionRef.make(value),
|
||||
[],
|
||||
{ doNotReExecuteOnRuntimeOrContextChange: true }, // Do not recreate the ref when the context changes
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the state of a `SubscriptionRef` to the state of the React component.
|
||||
*
|
||||
* Returns a [value, setter] tuple just like `React.useState` and triggers a re-render everytime the value held by the ref changes.
|
||||
*
|
||||
* Note that the rules of React's immutable state still apply: updating a ref with the same value will not trigger a re-render.
|
||||
*/
|
||||
useRefState<A>(ref: SubscriptionRef.SubscriptionRef<A>): [A, React.Dispatch<React.SetStateAction<A>>] {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
const initialState = React.useMemo(() => runSync(ref), [])
|
||||
const [reactStateValue, setReactStateValue] = React.useState(initialState)
|
||||
|
||||
this.useFork(Stream.runForEach(ref.changes, v => Effect.sync(() =>
|
||||
setReactStateValue(v)
|
||||
)), [ref])
|
||||
|
||||
const setValue = React.useCallback((setStateAction: React.SetStateAction<A>) =>
|
||||
runSync(Ref.update(ref, prevState =>
|
||||
SetStateAction.value(setStateAction, prevState)
|
||||
)),
|
||||
[ref])
|
||||
|
||||
return [reactStateValue, setValue]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export interface Reffuse<R> extends Pipeable.Pipeable {}
|
||||
|
||||
Reffuse.prototype.pipe = function pipe() {
|
||||
return Pipeable.pipeArguments(this, arguments)
|
||||
}
|
||||
|
||||
|
||||
export interface RenderOptions {
|
||||
/** Prevents re-executing the effect when the Effect runtime or context changes. Defaults to `false`. */
|
||||
readonly doNotReExecuteOnRuntimeOrContextChange?: boolean
|
||||
}
|
||||
|
||||
export interface ScopeOptions {
|
||||
readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy
|
||||
}
|
||||
|
||||
|
||||
export const make = <T extends Array<unknown>>(
|
||||
...contexts: [...{ [K in keyof T]: ReffuseContext.ReffuseContext<T[K]> }]
|
||||
): Reffuse<T[number]> =>
|
||||
new Reffuse(contexts)
|
||||
|
||||
// export const make = (): Reffuse<never> => new Reffuse([])
|
||||
|
||||
// export const withContexts = <R2 extends Array<unknown>>(
|
||||
// ...contexts: [...{ [K in keyof R2]: ReffuseContext.ReffuseContext<R2[K]> }]
|
||||
// ) =>
|
||||
// <T extends Reffuse<R1>, R1>(self: T & Reffuse<R1>): (
|
||||
// Reffuse<R1 | R2[number]> & Exclude<T, Reffuse<R1>>
|
||||
// ) =>
|
||||
// new Reffuse([...self.contexts, ...contexts as any]) as any
|
||||
|
||||
@@ -3,7 +3,6 @@ import * as React from "react"
|
||||
import * as ReffuseRuntime from "./ReffuseRuntime.js"
|
||||
|
||||
|
||||
// TODO: merge this with the Provider, just like React 19 contexts
|
||||
export class ReffuseContext<R> {
|
||||
|
||||
readonly Context = React.createContext<Context.Context<R>>(null!)
|
||||
@@ -11,7 +10,7 @@ export class ReffuseContext<R> {
|
||||
|
||||
constructor() {
|
||||
// TODO: scope the layer creation
|
||||
this.Provider = (props) => {
|
||||
this.Provider = props => {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
|
||||
const value = React.useMemo(() => Effect.context<R>().pipe(
|
||||
|
||||
7
packages/reffuse/src/ReffuseExtension.ts
Normal file
7
packages/reffuse/src/ReffuseExtension.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface ReffuseExtension<A extends object> {
|
||||
(): A
|
||||
readonly Type: A
|
||||
}
|
||||
|
||||
export const make = <A extends object>(extension: () => A): ReffuseExtension<A> =>
|
||||
extension as ReffuseExtension<A>
|
||||
431
packages/reffuse/src/ReffuseHelpers.ts
Normal file
431
packages/reffuse/src/ReffuseHelpers.ts
Normal file
@@ -0,0 +1,431 @@
|
||||
import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, Pipeable, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect"
|
||||
import * as React from "react"
|
||||
import * as ReffuseContext from "./ReffuseContext.js"
|
||||
import * as ReffuseRuntime from "./ReffuseRuntime.js"
|
||||
import * as SetStateAction from "./SetStateAction.js"
|
||||
|
||||
|
||||
export interface RenderOptions {
|
||||
/** Prevents re-executing the effect when the Effect runtime or context changes. Defaults to `false`. */
|
||||
readonly doNotReExecuteOnRuntimeOrContextChange?: boolean
|
||||
}
|
||||
|
||||
export interface ScopeOptions {
|
||||
readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy
|
||||
}
|
||||
|
||||
|
||||
export abstract class ReffuseHelpers<R> {
|
||||
declare ["constructor"]: ReffuseHelpersClass<R>
|
||||
|
||||
|
||||
useContext<R>(this: ReffuseHelpers<R>): Context.Context<R> {
|
||||
return ReffuseContext.useMergeAll(...this.constructor.contexts)
|
||||
}
|
||||
|
||||
|
||||
useRunSync<R>(this: ReffuseHelpers<R>): <A, E>(effect: Effect.Effect<A, E, R>) => A {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback(effect => effect.pipe(
|
||||
Effect.provide(context),
|
||||
Runtime.runSync(runtime),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunPromise<R>(this: ReffuseHelpers<R>): <A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: { readonly signal?: AbortSignal },
|
||||
) => Promise<A> {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback((effect, options) => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runPromise(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunFork<R>(this: ReffuseHelpers<R>): <A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: Runtime.RunForkOptions,
|
||||
) => Fiber.RuntimeFiber<A, E> {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback((effect, options) => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runFork(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
useRunCallback<R>(this: ReffuseHelpers<R>): <A, E>(
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: Runtime.RunCallbackOptions<A, E>,
|
||||
) => Runtime.Cancel<A, E> {
|
||||
const runtime = ReffuseRuntime.useRuntime()
|
||||
const context = this.useContext()
|
||||
|
||||
return React.useCallback((effect, options) => effect.pipe(
|
||||
Effect.provide(context),
|
||||
effect => Runtime.runCallback(runtime)(effect, options),
|
||||
), [runtime, context])
|
||||
}
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useMemo`.
|
||||
*
|
||||
* `useMemo` will only recompute the memoized value by running the given synchronous effect when one of the deps has changed. \
|
||||
* Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will recompute the value in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*/
|
||||
useMemo<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions,
|
||||
): A {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useMemo(() => runSync(effect()), [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
useMemoScoped<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): A {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
// Calculate an initial version of the value so that it can be accessed during the first render
|
||||
const [initialScope, initialValue] = React.useMemo(() => Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.flatMap(scope => effect().pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.map(value => [scope, value] as const),
|
||||
)),
|
||||
|
||||
runSync,
|
||||
), [])
|
||||
|
||||
// Keep track of the state of the initial scope
|
||||
const initialScopeClosed = React.useRef(false)
|
||||
|
||||
const [value, setValue] = React.useState(initialValue)
|
||||
|
||||
React.useEffect(() => {
|
||||
const closeInitialScopeIfNeeded = Scope.close(initialScope, Exit.void).pipe(
|
||||
Effect.andThen(Effect.sync(() => { initialScopeClosed.current = true })),
|
||||
Effect.when(() => !initialScopeClosed.current),
|
||||
)
|
||||
|
||||
const [scope, value] = closeInitialScopeIfNeeded.pipe(
|
||||
Effect.andThen(Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.flatMap(scope => effect().pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.map(value => [scope, value] as const),
|
||||
))
|
||||
)),
|
||||
|
||||
runSync,
|
||||
)
|
||||
|
||||
setValue(value)
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useEffect`.
|
||||
*
|
||||
* Executes a synchronous effect wrapped into a Scope when one of the deps has changed. Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* useEffect(() => Effect.addFinalizer(() => Console.log("Component unmounted")).pipe(
|
||||
* Effect.flatMap(() => Console.log("Component mounted"))
|
||||
* ))
|
||||
* ```
|
||||
*
|
||||
* Plain React equivalent:
|
||||
* ```
|
||||
* React.useEffect(() => {
|
||||
* console.log("Component mounted")
|
||||
* return () => { console.log("Component unmounted") }
|
||||
* }, [])
|
||||
* ```
|
||||
*/
|
||||
useEffect<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
React.useEffect(() => {
|
||||
const scope = Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.tap(scope => Effect.provideService(effect(), Scope.Scope, scope)),
|
||||
runSync,
|
||||
)
|
||||
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Reffuse equivalent to `React.useLayoutEffect`.
|
||||
*
|
||||
* Executes a synchronous effect wrapped into a Scope when one of the deps has changed. Fires synchronously after all DOM mutations. \
|
||||
* Trying to run an asynchronous effect will throw.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* useLayoutEffect(() => Effect.addFinalizer(() => Console.log("Component unmounted")).pipe(
|
||||
* Effect.flatMap(() => Console.log("Component mounted"))
|
||||
* ))
|
||||
* ```
|
||||
*
|
||||
* Plain React equivalent:
|
||||
* ```
|
||||
* React.useLayoutEffect(() => {
|
||||
* console.log("Component mounted")
|
||||
* return () => { console.log("Component unmounted") }
|
||||
* }, [])
|
||||
* ```
|
||||
*/
|
||||
useLayoutEffect<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useLayoutEffect(() => {
|
||||
const scope = Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||
Effect.tap(scope => Effect.provideService(effect(), Scope.Scope, scope)),
|
||||
runSync,
|
||||
)
|
||||
|
||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* An asynchronous and non-blocking alternative to `React.useEffect`.
|
||||
*
|
||||
* Forks an effect wrapped into a Scope in the background when one of the deps has changed.
|
||||
*
|
||||
* The Scope is closed on every cleanup, i.e. when one of the deps has changed and the effect needs to be re-executed. \
|
||||
* Add finalizers to the Scope to handle cleanup logic.
|
||||
*
|
||||
* Changes to the Reffuse runtime or context will re-execute the effect in addition to the deps.
|
||||
* You can disable this behavior by setting `doNotReExecuteOnRuntimeOrContextChange` to `true` in `options`.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* const timeRef = useRefFromEffect(DateTime.now)
|
||||
*
|
||||
* useFork(() => Effect.addFinalizer(() => Console.log("Cleanup")).pipe(
|
||||
* Effect.map(() => Stream.repeatEffectWithSchedule(
|
||||
* DateTime.now,
|
||||
* Schedule.intersect(Schedule.forever, Schedule.spaced("1 second")),
|
||||
* )),
|
||||
*
|
||||
* Effect.flatMap(Stream.runForEach(time => Ref.set(timeRef, time)),
|
||||
* )), [timeRef])
|
||||
*
|
||||
* const [time] = useRefState(timeRef)
|
||||
* ```
|
||||
*/
|
||||
useFork<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: Runtime.RunForkOptions & RenderOptions & ScopeOptions,
|
||||
): void {
|
||||
const runSync = this.useRunSync()
|
||||
const runFork = this.useRunFork()
|
||||
|
||||
return React.useEffect(() => {
|
||||
const scope = runSync(options?.scope
|
||||
? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential)
|
||||
: Scope.make(options?.finalizerExecutionStrategy)
|
||||
)
|
||||
runFork(Effect.provideService(effect(), Scope.Scope, scope), { ...options, scope })
|
||||
|
||||
return () => { runFork(Scope.close(scope, Exit.void)) }
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
usePromise<A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
effect: () => Effect.Effect<A, E, R | Scope.Scope>,
|
||||
deps?: React.DependencyList,
|
||||
options?: { readonly signal?: AbortSignal } & Runtime.RunForkOptions & RenderOptions & ScopeOptions,
|
||||
): Promise<A> {
|
||||
const runSync = this.useRunSync()
|
||||
const runFork = this.useRunFork()
|
||||
|
||||
const [value, setValue] = React.useState(Promise.withResolvers<A>().promise)
|
||||
|
||||
React.useEffect(() => {
|
||||
const { promise, resolve, reject } = Promise.withResolvers<A>()
|
||||
setValue(promise)
|
||||
|
||||
const scope = runSync(options?.scope
|
||||
? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential)
|
||||
: Scope.make(options?.finalizerExecutionStrategy)
|
||||
)
|
||||
|
||||
const cleanup = () => { runFork(Scope.close(scope, Exit.void)) }
|
||||
if (options?.signal)
|
||||
options.signal.addEventListener("abort", cleanup)
|
||||
|
||||
effect().pipe(
|
||||
Effect.provideService(Scope.Scope, scope),
|
||||
Effect.match({
|
||||
onSuccess: resolve,
|
||||
onFailure: reject,
|
||||
}),
|
||||
effect => runFork(effect, { ...options, scope }),
|
||||
)
|
||||
|
||||
return () => {
|
||||
if (options?.signal)
|
||||
options.signal.removeEventListener("abort", cleanup)
|
||||
|
||||
cleanup()
|
||||
}
|
||||
}, [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork],
|
||||
...(deps ?? []),
|
||||
])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
useCallbackSync<Args extends unknown[], A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
callback: (...args: Args) => Effect.Effect<A, E, R>,
|
||||
deps?: React.DependencyList,
|
||||
options?: RenderOptions,
|
||||
): (...args: Args) => A {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
return React.useCallback((...args) => runSync(callback(...args)), [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
useCallbackPromise<Args extends unknown[], A, E, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
callback: (...args: Args) => Effect.Effect<A, E, R>,
|
||||
deps?: React.DependencyList,
|
||||
options?: { readonly signal?: AbortSignal } & RenderOptions,
|
||||
): (...args: Args) => Promise<A> {
|
||||
const runPromise = this.useRunPromise()
|
||||
|
||||
return React.useCallback((...args) => runPromise(callback(...args), options), [
|
||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runPromise],
|
||||
...(deps ?? []),
|
||||
])
|
||||
}
|
||||
|
||||
useRef<A, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
value: A,
|
||||
): SubscriptionRef.SubscriptionRef<A> {
|
||||
return this.useMemo(
|
||||
() => SubscriptionRef.make(value),
|
||||
[],
|
||||
{ doNotReExecuteOnRuntimeOrContextChange: true }, // Do not recreate the ref when the context changes
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the state of a `SubscriptionRef` to the state of the React component.
|
||||
*
|
||||
* Returns a [value, setter] tuple just like `React.useState` and triggers a re-render everytime the value held by the ref changes.
|
||||
*
|
||||
* Note that the rules of React's immutable state still apply: updating a ref with the same value will not trigger a re-render.
|
||||
*/
|
||||
useRefState<A, R>(
|
||||
this: ReffuseHelpers<R>,
|
||||
ref: SubscriptionRef.SubscriptionRef<A>,
|
||||
): [A, React.Dispatch<React.SetStateAction<A>>] {
|
||||
const runSync = this.useRunSync()
|
||||
|
||||
const initialState = React.useMemo(() => runSync(ref), [])
|
||||
const [reactStateValue, setReactStateValue] = React.useState(initialState)
|
||||
|
||||
this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() =>
|
||||
setReactStateValue(v)
|
||||
)), [ref])
|
||||
|
||||
const setValue = React.useCallback((setStateAction: React.SetStateAction<A>) =>
|
||||
runSync(Ref.update(ref, prevState =>
|
||||
SetStateAction.value(setStateAction, prevState)
|
||||
)),
|
||||
[ref])
|
||||
|
||||
return [reactStateValue, setValue]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface ReffuseHelpers<R> extends Pipeable.Pipeable {}
|
||||
|
||||
ReffuseHelpers.prototype.pipe = function pipe() {
|
||||
return Pipeable.pipeArguments(this, arguments)
|
||||
}
|
||||
|
||||
|
||||
export interface ReffuseHelpersClass<R> extends Pipeable.Pipeable {
|
||||
new(): ReffuseHelpers<R>
|
||||
readonly contexts: readonly ReffuseContext.ReffuseContext<R>[]
|
||||
}
|
||||
|
||||
(ReffuseHelpers as ReffuseHelpersClass<any>).pipe = function pipe() {
|
||||
return Pipeable.pipeArguments(this, arguments)
|
||||
}
|
||||
|
||||
|
||||
export const make = (): ReffuseHelpersClass<never> =>
|
||||
class extends (ReffuseHelpers<never> as ReffuseHelpersClass<never>) {
|
||||
static readonly contexts = []
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export * as Reffuse from "./Reffuse.js"
|
||||
export * as ReffuseContext from "./ReffuseContext.js"
|
||||
export * as ReffuseExtension from "./ReffuseExtension.js"
|
||||
export * as ReffuseHelpers from "./ReffuseHelpers.js"
|
||||
export * as ReffuseRuntime from "./ReffuseRuntime.js"
|
||||
export * as SetStateAction from "./SetStateAction.js"
|
||||
|
||||
21
packages/reffuse/src/types.ts
Normal file
21
packages/reffuse/src/types.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Extracts the common keys between two types
|
||||
*/
|
||||
export type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||
|
||||
/**
|
||||
* Obtain the static members type of a constructor function type
|
||||
*/
|
||||
export type StaticType<T extends abstract new (...args: any) => any> = Omit<T, "prototype">
|
||||
|
||||
export type Extend<Super, Self> =
|
||||
Extendable<Super, Self> extends true
|
||||
? Omit<Super, CommonKeys<Self, Super>> & Self
|
||||
: never
|
||||
|
||||
export type Extendable<Super, Self> =
|
||||
Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? true
|
||||
: false
|
||||
|
||||
export type Merge<Super, Self> = Omit<Super, CommonKeys<Self, Super>> & Self
|
||||
Reference in New Issue
Block a user