Compare commits

49 Commits
master ... next

Author SHA1 Message Date
Julien Valverdé
1e8f7d888e Add components
Some checks failed
Lint / lint (push) Failing after 11s
2026-01-04 23:27:25 +01:00
Julien Valverdé
cc87f79974 Add Tween tests
Some checks failed
Lint / lint (push) Failing after 11s
2026-01-04 23:15:21 +01:00
Julien Valverdé
a571bc8163 Test
Some checks failed
Lint / lint (push) Failing after 10s
2026-01-04 18:17:22 +01:00
Julien Valverdé
eae6647b7e Add signal support
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-04 18:13:09 +01:00
Julien Valverdé
7f1be2cd1d Tests
Some checks failed
Lint / lint (push) Failing after 39s
2026-01-03 02:53:17 +01:00
Julien Valverdé
9fb5468ec2 Example work
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 23:46:16 +01:00
Julien Valverdé
c6683f4905 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 23:23:45 +01:00
Julien Valverdé
ff2d92d743 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 23:08:27 +01:00
Julien Valverdé
d02864b873 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 21:31:15 +01:00
Julien Valverdé
a02f63f90d Tests
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 21:25:27 +01:00
Julien Valverdé
703b0f13d4 Add Component.useSignalValues
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 21:17:30 +01:00
Julien Valverdé
dc2f4d81d6 Add Component.fromClassUnsafe
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 19:18:44 +01:00
Julien Valverdé
a97afa5dd9 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 12:40:15 +01:00
Julien Valverdé
a4508fb053 Test Component.fromScene
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 12:33:07 +01:00
Julien Valverdé
76b19de46a Fix
Some checks failed
Lint / lint (push) Failing after 10s
2026-01-02 03:38:32 +01:00
Julien Valverdé
54c6466127 Add Component.fromScene
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 03:24:30 +01:00
Julien Valverdé
99007ec462 Add gen files
Some checks failed
Lint / lint (push) Failing after 38s
2026-01-02 03:01:07 +01:00
Julien Valverdé
2471299089 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 00:48:20 +01:00
Julien Valverdé
f245b61ab3 Handle React cleanup
Some checks failed
Lint / lint (push) Failing after 10s
2026-01-02 00:43:28 +01:00
Julien Valverdé
3b2961e557 Tests
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-02 00:14:54 +01:00
Julien Valverdé
78c3051342 Fix destruction
Some checks failed
Lint / lint (push) Failing after 8s
2026-01-02 00:06:41 +01:00
Julien Valverdé
fae11b2024 Add useSignal
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-01 23:25:05 +01:00
Julien Valverdé
d37c5e1405 Test controlled TextEdit
Some checks failed
Lint / lint (push) Failing after 9s
2026-01-01 20:26:11 +01:00
Julien Valverdé
84c83c1bef Fix
Some checks failed
Lint / lint (push) Failing after 10s
2026-01-01 20:18:09 +01:00
Julien Valverdé
45f84810b5 Fix
Some checks failed
Lint / lint (push) Failing after 38s
2026-01-01 17:47:59 +01:00
Julien Valverdé
93fabb16ba Fix
Some checks failed
Lint / lint (push) Failing after 8s
2025-12-31 01:53:40 +01:00
Julien Valverdé
2ac13c15aa Fix
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-31 01:42:38 +01:00
Julien Valverdé
0b636828b3 Fix
Some checks failed
Lint / lint (push) Failing after 38s
2025-12-31 01:35:20 +01:00
Julien Valverdé
7eceb4e20e Fix
Some checks failed
Lint / lint (push) Failing after 10s
2025-12-30 23:40:19 +01:00
Julien Valverdé
a19746d3ab Fix
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-30 13:22:48 +01:00
Julien Valverdé
04eb98bc3f Fix
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-30 13:20:31 +01:00
Julien Valverdé
5dd051ce71 Fix
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 23:52:39 +01:00
Julien Valverdé
bd31fd5ea4 Add Node component
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 19:35:31 +01:00
Julien Valverdé
fba9ca6193 Work
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 18:57:25 +01:00
Julien Valverdé
7032432e74 Fix renderComponent
Some checks failed
Lint / lint (push) Failing after 8s
2025-12-29 18:33:38 +01:00
Julien Valverdé
2398118105 Fix JSX types
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 00:42:53 +01:00
Julien Valverdé
19c5b91b6b Fix dependencies
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 00:33:16 +01:00
Julien Valverdé
6778925a3a Fix
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 00:26:49 +01:00
Julien Valverdé
cfdcae0892 Example work
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-29 00:04:53 +01:00
Julien Valverdé
945ef34829 Fix JSX types
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-28 23:53:22 +01:00
Julien Valverdé
0c642b655e Library work
Some checks failed
Lint / lint (push) Failing after 10s
2025-12-28 22:04:37 +01:00
Julien Valverdé
446dbc1cc7 Add reconciler
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-28 17:39:05 +01:00
Julien Valverdé
1552de4a27 Fix
Some checks failed
Lint / lint (push) Failing after 8s
2025-12-28 16:42:31 +01:00
Julien Valverdé
193f92f7ab Setup lib
Some checks failed
Lint / lint (push) Failing after 8s
2025-12-28 16:36:12 +01:00
Julien Valverdé
185912ceae Fix example project
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-28 16:12:38 +01:00
Julien Valverdé
dd446da61c Fix
Some checks failed
Lint / lint (push) Failing after 11s
2025-12-28 15:54:12 +01:00
Julien Valverdé
e9a34a2152 Setup Godot example project
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-28 15:37:58 +01:00
Julien Valverdé
30cc8a857c Fix package.json
Some checks failed
Lint / lint (push) Failing after 9s
2025-12-28 14:40:54 +01:00
Julien Valverdé
b792924733 Cleanup
Some checks failed
Lint / lint (push) Failing after 8s
2025-12-28 14:39:45 +01:00
85 changed files with 185375 additions and 36 deletions

349
bun.lock Normal file
View File

@@ -0,0 +1,349 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "@react-godot-renderer/monorepo",
"devDependencies": {
"@biomejs/biome": "^2.3.8",
"npm-check-updates": "^19.1.2",
"npm-sort": "^0.0.4",
"turbo": "^2.6.1",
"typescript": "^5.9.3",
},
},
"packages/example": {
"name": "@react-godot-renderer/example",
"version": "0.0.0",
"dependencies": {
"@nberlette/utf8": "^0.4.0",
"fast-text-encoding": "^1.0.6",
"react": "^19.2.0",
"react-godot-renderer": "workspace:*",
"url-shim": "^1.0.1",
},
"devDependencies": {
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-inject": "^5.0.5",
"@rollup/plugin-node-resolve": "^16.0.3",
"@types/react": "^19.2.7",
"glob": "^13.0.0",
"rollup": "^4.54.0",
"rollup-plugin-delete": "^3.0.2",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-polyfill-node": "^0.13.0",
},
},
"packages/react-godot-renderer": {
"name": "react-godot-renderer",
"version": "0.1.0",
"dependencies": {
"react-reconciler": "~0.33.0",
},
"devDependencies": {
"@types/react-reconciler": "~0.32.0",
},
"peerDependencies": {
"@types/react": "^19.2.0",
"react": "^19.2.0",
},
},
},
"packages": {
"@biomejs/biome": ["@biomejs/biome@2.3.10", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.10", "@biomejs/cli-darwin-x64": "2.3.10", "@biomejs/cli-linux-arm64": "2.3.10", "@biomejs/cli-linux-arm64-musl": "2.3.10", "@biomejs/cli-linux-x64": "2.3.10", "@biomejs/cli-linux-x64-musl": "2.3.10", "@biomejs/cli-win32-arm64": "2.3.10", "@biomejs/cli-win32-x64": "2.3.10" }, "bin": { "biome": "bin/biome" } }, "sha512-/uWSUd1MHX2fjqNLHNL6zLYWBbrJeG412/8H7ESuK8ewoRoMPUgHDebqKrPTx/5n6f17Xzqc9hdg3MEqA5hXnQ=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-M6xUjtCVnNGFfK7HMNKa593nb7fwNm43fq1Mt71kpLpb+4mE7odO8W/oWVDyBVO4ackhresy1ZYO7OJcVo/B7w=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vae7+V6t/Avr8tVbFNjnFSTKZogZHFYl7MMH62P/J1kZtr0tyRQ9Fe0onjqjS2Ek9lmNLmZc/VR5uSekh+p1fg=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-hhPw2V3/EpHKsileVOFynuWiKRgFEV48cLe0eA+G2wO4SzlwEhLEB9LhlSrVeu2mtSn205W283LkX7Fh48CaxA=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-B9DszIHkuKtOH2IFeeVkQmSMVUjss9KtHaNXquYYWCjH8IstNgXgx5B0aSBQNr6mn4RcKKRQZXn9Zu1rM3O0/A=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-wwAkWD1MR95u+J4LkWP74/vGz+tRrIQvr8kfMMJY8KOQ8+HMVleREOcPYsQX82S7uueco60L58Wc6M1I9WA9Dw=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-QTfHZQh62SDFdYc2nfmZFuTm5yYb4eO1zwfB+90YxUumRCR171tS1GoTX5OD0wrv4UsziMPmrePMtkTnNyYG3g=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-o7lYc9n+CfRbHvkjPhm8s9FgbKdYZu5HCcGVMItLjz93EhgJ8AM44W+QckDqLA9MKDNFrR8nPbO4b73VC5kGGQ=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.10", "", { "os": "win32", "cpu": "x64" }, "sha512-pHEFgq7dUEsKnqG9mx9bXihxGI49X+ar+UBrEIj3Wqj3UCZp1rNgV+OoyjFgcXsjCWpuEAF4VJdkZr3TrWdCbQ=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="],
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="],
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="],
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@nberlette/utf8": ["@nberlette/utf8@0.4.0", "", {}, "sha512-1JtHVkmTYntzPWw7mAzXeQ2pPAh6fnDlByPiK+73dhAnSaScj3QOkKXC80PlfWZFdLC+HaIkLyl7lX0AE3DDgA=="],
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"@react-godot-renderer/example": ["@react-godot-renderer/example@workspace:packages/example"],
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@29.0.0", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ=="],
"@rollup/plugin-inject": ["@rollup/plugin-inject@5.0.5", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "estree-walker": "^2.0.2", "magic-string": "^0.30.3" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg=="],
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.3", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.54.0", "", { "os": "android", "cpu": "arm" }, "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.54.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.54.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.54.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.54.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.54.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg=="],
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw=="],
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.54.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.54.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw=="],
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.54.0", "", { "os": "none", "cpu": "arm64" }, "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.54.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.54.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ=="],
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg=="],
"@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
"@types/react-reconciler": ["@types/react-reconciler@0.32.3", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-cMi5ZrLG7UtbL7LTK6hq9w/EZIRk4Mf1Z5qHoI+qBh7/WkYkFXQ7gOto2yfUvPzF5ERMAhaXS5eTQ2SAnHjLzA=="],
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
"commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
"del": ["del@8.0.1", "", { "dependencies": { "globby": "^14.0.2", "is-glob": "^4.0.3", "is-path-cwd": "^3.0.0", "is-path-inside": "^4.0.0", "p-map": "^7.0.2", "presentable-error": "^0.0.1", "slash": "^5.1.0" } }, "sha512-gPqh0mKTPvaUZGAuHbrBUYKZWBNAeHG7TU3QH5EhVwPMyKvmfJaNXhcD2jTcXsJRRcffuho4vaYweu80dRrMGA=="],
"es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
"esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
"fast-text-encoding": ["fast-text-encoding@1.0.6", "", {}, "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w=="],
"fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
"glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"globby": ["globby@14.1.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.3", "ignore": "^7.0.3", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-path-cwd": ["is-path-cwd@3.0.0", "", {}, "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA=="],
"is-path-inside": ["is-path-inside@4.0.0", "", {}, "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA=="],
"is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
"lru-cache": ["lru-cache@11.2.4", "", {}, "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg=="],
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"npm-check-updates": ["npm-check-updates@19.2.0", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-XSIuL0FNgzXPDZa4lje7+OwHjiyEt84qQm6QMsQRbixNY5EHEM9nhgOjxjlK9jIbN+ysvSqOV8DKNS0zydwbdg=="],
"npm-sort": ["npm-sort@0.0.4", "", { "bin": { "npm-sort": "./index.js" } }, "sha512-S5Id/3Jvr7Cf/QnWjRteprngERCBhhEFOM+wMhUrAYP060/HUBC1aL5GoXS3xITlgacJCWaSmP4HQaAt91nNYQ=="],
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
"path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="],
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
"presentable-error": ["presentable-error@0.0.1", "", {}, "sha512-E6rsNU1QNJgB3sjj7OANinGncFKuK+164sLXw1/CqBjj/EkXSoSdHCtWQGBNlREIGLnL7IEUEGa08YFVUbrhVg=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
"react-godot-renderer": ["react-godot-renderer@workspace:packages/react-godot-renderer"],
"react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="],
"resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
"rollup": ["rollup@4.54.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.54.0", "@rollup/rollup-android-arm64": "4.54.0", "@rollup/rollup-darwin-arm64": "4.54.0", "@rollup/rollup-darwin-x64": "4.54.0", "@rollup/rollup-freebsd-arm64": "4.54.0", "@rollup/rollup-freebsd-x64": "4.54.0", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", "@rollup/rollup-linux-arm-musleabihf": "4.54.0", "@rollup/rollup-linux-arm64-gnu": "4.54.0", "@rollup/rollup-linux-arm64-musl": "4.54.0", "@rollup/rollup-linux-loong64-gnu": "4.54.0", "@rollup/rollup-linux-ppc64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-musl": "4.54.0", "@rollup/rollup-linux-s390x-gnu": "4.54.0", "@rollup/rollup-linux-x64-gnu": "4.54.0", "@rollup/rollup-linux-x64-musl": "4.54.0", "@rollup/rollup-openharmony-arm64": "4.54.0", "@rollup/rollup-win32-arm64-msvc": "4.54.0", "@rollup/rollup-win32-ia32-msvc": "4.54.0", "@rollup/rollup-win32-x64-gnu": "4.54.0", "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw=="],
"rollup-plugin-delete": ["rollup-plugin-delete@3.0.2", "", { "dependencies": { "del": "^8.0.1" }, "peerDependencies": { "rollup": "*" } }, "sha512-26GSi/aeYQ/hEBdG1rjEMeh+WUhiPZ3hGmSr9Ucj7mhLQ1P9j8KEgtYoybDp7OlIMj3eQjHHB9fnqhxNuVgfzA=="],
"rollup-plugin-esbuild": ["rollup-plugin-esbuild@6.2.1", "", { "dependencies": { "debug": "^4.4.0", "es-module-lexer": "^1.6.0", "get-tsconfig": "^4.10.0", "unplugin-utils": "^0.2.4" }, "peerDependencies": { "esbuild": ">=0.18.0", "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" } }, "sha512-jTNOMGoMRhs0JuueJrJqbW8tOwxumaWYq+V5i+PD+8ecSCVkuX27tGW7BXqDgoULQ55rO7IdNxPcnsWtshz3AA=="],
"rollup-plugin-polyfill-node": ["rollup-plugin-polyfill-node@0.13.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.4" }, "peerDependencies": { "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" } }, "sha512-FYEvpCaD5jGtyBuBFcQImEGmTxDTPbiHjJdrYIp+mFIwgXiXabxvKUK7ZT9P31ozu2Tqm9llYQMRWsfvTMTAOw=="],
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
"slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
"turbo": ["turbo@2.7.2", "", { "optionalDependencies": { "turbo-darwin-64": "2.7.2", "turbo-darwin-arm64": "2.7.2", "turbo-linux-64": "2.7.2", "turbo-linux-arm64": "2.7.2", "turbo-windows-64": "2.7.2", "turbo-windows-arm64": "2.7.2" }, "bin": { "turbo": "bin/turbo" } }, "sha512-5JIA5aYBAJSAhrhbyag1ZuMSgUZnHtI+Sq3H8D3an4fL8PeF+L1yYvbEJg47akP1PFfATMf5ehkqFnxfkmuwZQ=="],
"turbo-darwin-64": ["turbo-darwin-64@2.7.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-dxY3X6ezcT5vm3coK6VGixbrhplbQMwgNsCsvZamS/+/6JiebqW9DKt4NwpgYXhDY2HdH00I7FWs3wkVuan4rA=="],
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.7.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1bXmuwPLqNFt3mzrtYcVx1sdJ8UYb124Bf48nIgcpMCGZy3kDhgxNv1503kmuK/37OGOZbsWSQFU4I08feIuSg=="],
"turbo-linux-64": ["turbo-linux-64@2.7.2", "", { "os": "linux", "cpu": "x64" }, "sha512-kP+TiiMaiPugbRlv57VGLfcjFNsFbo8H64wMBCPV2270Or2TpDCBULMzZrvEsvWFjT3pBFvToYbdp8/Kw0jAQg=="],
"turbo-linux-arm64": ["turbo-linux-arm64@2.7.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-VDJwQ0+8zjAfbyY6boNaWfP6RIez4ypKHxwkuB6SrWbOSk+vxTyW5/hEjytTwK8w/TsbKVcMDyvpora8tEsRFw=="],
"turbo-windows-64": ["turbo-windows-64@2.7.2", "", { "os": "win32", "cpu": "x64" }, "sha512-rPjqQXVnI6A6oxgzNEE8DNb6Vdj2Wwyhfv3oDc+YM3U9P7CAcBIlKv/868mKl4vsBtz4ouWpTQNXG8vljgJO+w=="],
"turbo-windows-arm64": ["turbo-windows-arm64@2.7.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-tcnHvBhO515OheIFWdxA+qUvZzNqqcHbLVFc1+n+TJ1rrp8prYicQtbtmsiKgMvr/54jb9jOabU62URAobnB7g=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
"unplugin-utils": ["unplugin-utils@0.2.5", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg=="],
"url-shim": ["url-shim@1.0.1", "", {}, "sha512-8nwZkCP7pbI8ifcifTZSLRO3W+CWuh/mafPvc7utPRqgxAORnsZIzQ5K8LUsHiQ4mTtJrKRAJmW2ZHxQk0rKUA=="],
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
}
}

View File

@@ -16,8 +16,6 @@
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.3.8", "@biomejs/biome": "^2.3.8",
"@effect/language-service": "^0.60.0",
"@types/bun": "^1.3.3",
"npm-check-updates": "^19.1.2", "npm-check-updates": "^19.1.2",
"npm-sort": "^0.0.4", "npm-sort": "^0.0.4",
"turbo": "^2.6.1", "turbo": "^2.6.1",

View File

@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
packages/example/.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

7
packages/example/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
# Godot 4+ specific ignores
.godot/
/android/
!node_modules/
node_modules/**/*
!node_modules/.gdignore

View File

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface ResourceTypes {
"res://biome.json": JSON;
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface ResourceTypes {
"res://icon.svg": CompressedTexture2D;
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface SceneNodes {
"src/TestUi1.tscn": {};
}
}

View File

@@ -0,0 +1,6 @@
import TestUi1 from "../../../src/TestUi1";
declare module "godot" {
interface ResourceTypes {
"res://src/TestUi1.tscn": PackedScene<TestUi1>;
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface SceneNodes {
"src/TestUi2.tscn": {};
}
}

View File

@@ -0,0 +1,6 @@
import TestUi2 from "../../../src/TestUi2";
declare module "godot" {
interface ResourceTypes {
"res://src/TestUi2.tscn": PackedScene<TestUi2>;
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface SceneNodes {
"src/form/ControlledForm.tscn": {};
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface ResourceTypes {
"res://src/form/ControlledForm.tscn": PackedScene<Control<SceneNodes["src/form/ControlledForm.tscn"]>>;
}
}

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface SceneNodes {
"src/tween/Tween.tscn": {};
}
}

View File

@@ -0,0 +1,6 @@
import Tween from "../../../../src/tween/Tween";
declare module "godot" {
interface ResourceTypes {
"res://src/tween/Tween.tscn": PackedScene<Tween>;
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 995 B

View File

@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bn14p8nl4khp"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

0
packages/example/node_modules/.gdignore generated vendored Normal file
View File

View File

@@ -4,39 +4,29 @@
"type": "module", "type": "module",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "watch": "npx rollup -c --watch",
"build": "npx rollup -c",
"lint:tsc": "tsc --noEmit", "lint:tsc": "tsc --noEmit",
"lint:biome": "biome lint", "lint:biome": "biome lint",
"preview": "vite preview", "clean:cache": "rm -rf .turbo",
"clean:cache": "rm -rf .turbo node_modules/.tmp node_modules/.vite* .tanstack", "clean:modules": "rm -rf node_modules/* && touch node_modules/.gdignore"
"clean:dist": "rm -rf dist",
"clean:modules": "rm -rf node_modules"
}, },
"devDependencies": { "devDependencies": {
"@tanstack/react-router": "^1.139.12", "@rollup/plugin-commonjs": "^29.0.0",
"@tanstack/react-router-devtools": "^1.139.12", "@rollup/plugin-inject": "^5.0.5",
"@tanstack/router-plugin": "^1.139.12", "@rollup/plugin-node-resolve": "^16.0.3",
"@types/react": "^19.2.7", "@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3", "glob": "^13.0.0",
"@vitejs/plugin-react": "^5.1.1", "rollup": "^4.54.0",
"globals": "^16.5.0", "rollup-plugin-delete": "^3.0.2",
"react": "^19.2.0", "rollup-plugin-esbuild": "^6.2.1",
"react-dom": "^19.2.0", "rollup-plugin-polyfill-node": "^0.13.0"
"type-fest": "^5.2.0",
"vite": "^7.2.6"
}, },
"dependencies": { "dependencies": {
"@effect/platform": "^0.93.6", "@nberlette/utf8": "^0.4.0",
"@effect/platform-browser": "^0.73.0", "fast-text-encoding": "^1.0.6",
"@radix-ui/themes": "^3.2.1", "react": "^19.2.0",
"@typed/id": "^0.17.2", "react-godot-renderer": "workspace:*",
"effect": "^3.19.8", "url-shim": "^1.0.1"
"effect-fc": "workspace:*",
"react-icons": "^5.5.0"
},
"overrides": {
"@types/react": "^19.2.7",
"effect": "^3.19.8",
"react": "^19.2.0"
} }
} }

View File

@@ -0,0 +1,16 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="example"
run/main_scene="uid://ckb5ke2llfynx"
config/features=PackedStringArray("4.5", "Forward Plus")
config/icon="res://icon.svg"

View File

@@ -0,0 +1,49 @@
import commonjs from "@rollup/plugin-commonjs"
import inject from "@rollup/plugin-inject"
import { nodeResolve } from "@rollup/plugin-node-resolve"
import { globSync } from "glob"
import path from "node:path"
import url from "node:url"
import { defineConfig } from "rollup"
import del from "rollup-plugin-delete"
import esbuild from "rollup-plugin-esbuild"
import nodePolyfills from "rollup-plugin-polyfill-node"
export default defineConfig({
input: Object.fromEntries(
globSync(["./src/**/*.ts"]).map(file => [
path.relative(".", file.slice(0, file.length - path.extname(file).length)),
url.fileURLToPath(new URL(file, import.meta.url)),
])
),
external: [/^godot/, /^jsb/],
output: {
dir: "./.godot/GodotJS",
format: "cjs",
exports: "named",
esModule: true,
preserveModules: true,
},
treeshake: true,
plugins: [
esbuild(),
nodeResolve(),
commonjs(),
nodePolyfills({ include: null }),
inject({
TextEncoder: ["@nberlette/utf8", "TextEncoder"],
TextDecoder: ["@nberlette/utf8", "TextDecoder"],
TextEncoderStream: ["@nberlette/utf8", "TextEncoderStream"],
TextDecoderStream: ["@nberlette/utf8", "TextDecoderStream"],
URL: ["url-shim", "URL"],
URLSearchParams: ["url-shim", "URLSearchParams"],
React: ["react", "*"],
}),
del({ targets: "./.godot/GodotJS/*" }),
],
})

View File

@@ -0,0 +1 @@
uid://djsi7p0f1jx6f

View File

@@ -0,0 +1,6 @@
import { Control } from "godot"
import { Class } from "react-godot-renderer"
import { TestUi1Component } from "./TestUi1Component"
export default class TestUi1 extends Class.make(Control, TestUi1Component) {}

View File

@@ -0,0 +1 @@
uid://ibm3smonxuoh

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://ckb5ke2llfynx"]
[ext_resource type="Script" uid="uid://ibm3smonxuoh" path="res://src/TestUi1.ts" id="1_nkte1"]
[node name="TestUi1" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_nkte1")

View File

@@ -0,0 +1,47 @@
import Godot, { Vector2 } from "godot"
import { useState } from "react"
import { Component } from "react-godot-renderer"
const VFlowContainer = Component.fromClass(Godot.VFlowContainer)
const Label = Component.fromClass(Godot.Label)
const TextEdit = Component.fromClass(Godot.TextEdit)
const Button = Component.fromClass(Godot.Button)
export function TestUi1Component() {
const [text, setText] = useState("Default text")
const buttonRef = Button.useRef()
Component.useSignal(buttonRef, "pressed", () => {
console.log("Pressed!")
})
const [buttonPressed] = Component.useSignalValues(buttonRef, "toggled", [false])
return (
<VFlowContainer
name="Root"
>
<Label
name="Label"
text={buttonPressed ? "The button is pressed" : "The button is not pressed"}
/>
<TextEdit
name="TextEdit"
text={text}
custom_minimum_size={new Vector2(200, 35)}
text_changed={function(this) {
setText(this.text)
}}
/>
<Button
ref={buttonRef}
name="Button"
toggle_mode
text="Ok"
/>
</VFlowContainer>
)
}

View File

@@ -0,0 +1,6 @@
import { Control } from "godot"
import { Class } from "react-godot-renderer"
import { TestUi2Component } from "./TestUi2Component"
export default class TestUi2 extends Class.make(Control, TestUi2Component) {}

View File

@@ -0,0 +1 @@
uid://bm1qao8uj6b1f

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://b17syqj60kwx1"]
[ext_resource type="Script" uid="uid://bm1qao8uj6b1f" path="res://src/TestUi2.ts" id="1_1lkkw"]
[node name="TestUi2" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_1lkkw")

View File

@@ -0,0 +1,32 @@
import Godot from "godot"
import { useState } from "react"
import { Component } from "react-godot-renderer"
const HFlowContainer = Component.fromClass(Godot.HFlowContainer)
const VFlowContainer = Component.fromClass(Godot.VFlowContainer)
const Label = Component.fromClass(Godot.Label)
const CheckBox = Component.fromClass(Godot.CheckBox)
const TestUi1FC = Component.fromScene("res://src/TestUi1.tscn")
export function TestUi2Component() {
const [show, setShow] = useState(false)
const checkBoxRef = CheckBox.useRef()
Component.useSignal(checkBoxRef, "toggled", setShow)
return (
<HFlowContainer>
<VFlowContainer>
<Label text="Show" />
<CheckBox
ref={checkBoxRef}
button_pressed={show}
/>
</VFlowContainer>
{show && <TestUi1FC />}
</HFlowContainer>
)
}

View File

@@ -0,0 +1,12 @@
import Godot from "godot"
import { Component } from "react-godot-renderer"
export const Control = Component.fromClass(Godot.Control)
export const CenterContainer = Component.fromClass(Godot.CenterContainer)
export const HBoxContainer = Component.fromClass(Godot.HBoxContainer)
export const VBoxContainer = Component.fromClass(Godot.VBoxContainer)
export const Label = Component.fromClass(Godot.Label)
export const CheckBox = Component.fromClass(Godot.CheckBox)
export const TextEdit = Component.fromClass(Godot.TextEdit)
export const Button = Component.fromClass(Godot.Button)

View File

@@ -0,0 +1 @@
uid://c4p5ioay76skq

View File

@@ -0,0 +1,6 @@
import { Control } from "godot"
import { Class } from "react-godot-renderer"
import { ControlledFormRoot } from "./ControlledFormRoot"
export default class ControlledForm extends Class.make(Control, ControlledFormRoot) {}

View File

@@ -0,0 +1 @@
uid://c7c43wpsjchhs

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://dmvgc7era5i4e"]
[ext_resource type="Script" uid="uid://c7c43wpsjchhs" path="res://src/form/ControlledForm.ts" id="1_4ihd3"]
[node name="ControlledForm" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_4ihd3")

View File

@@ -0,0 +1,44 @@
import Godot, { Vector2 } from "godot"
import { Component } from "react-godot-renderer"
const CenterContainer = Component.fromClass(Godot.CenterContainer)
const PanelContainer = Component.fromClass(Godot.PanelContainer)
const MarginContainer = Component.fromClass(Godot.MarginContainer)
const VBoxContainer = Component.fromClass(Godot.VBoxContainer)
const Label = Component.fromClass(Godot.Label)
const TextEdit = Component.fromClass(Godot.TextEdit)
/**
* A form UI where React controls the state
*/
export function ControlledFormRoot() {
return (
<CenterContainer
anchors_preset={Godot.Control.LayoutPreset.PRESET_FULL_RECT}
ready={function(this) {
console.log("ready")
}}
>
<PanelContainer>
<MarginContainer>
<VBoxContainer>
<CenterContainer
anchors_preset={Godot.Control.LayoutPreset.PRESET_FULL_RECT}
>
<Label text="Register" />
</CenterContainer>
<TextEdit
custom_minimum_size={new Vector2(250, 40)}
/>
<TextEdit
custom_minimum_size={new Vector2(250, 40)}
/>
</VBoxContainer>
</MarginContainer>
</PanelContainer>
</CenterContainer>
)
}

View File

@@ -0,0 +1,6 @@
import { Control } from "godot"
import { Class } from "react-godot-renderer"
import { TweenRoot } from "./TweenRoot"
export default class Tween extends Class.make(Control, TweenRoot) {}

View File

@@ -0,0 +1 @@
uid://cau87pj31qgqr

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://cc4bbuq05f7us"]
[ext_resource type="Script" uid="uid://cau87pj31qgqr" path="res://src/tween/Tween.ts" id="1_cpsg0"]
[node name="Tween" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_cpsg0")

View File

@@ -0,0 +1,45 @@
import Godot, { Vector2 } from "godot"
import { useState } from "react"
import { CenterContainer, CheckBox, HBoxContainer, Label, VBoxContainer } from "../components"
export function TweenRoot() {
const [show, setShow] = useState(false)
return (
<CenterContainer
anchors_preset={Godot.Control.LayoutPreset.PRESET_FULL_RECT}
>
<VBoxContainer>
<HBoxContainer>
<CheckBox
button_pressed={show}
toggled={setShow}
/>
<Label text="Show" />
</HBoxContainer>
{show &&
<Label
anchors_preset={Godot.Control.LayoutPreset.PRESET_CENTER}
text="Hello World!"
ready={async function(this) {
// If the Control node is a child of a [Container] node, the scale will be reset to Vector2(1, 1) when the scene is instantiated.
// To set the Control's scale when it's instantiated, wait for one frame using await get_tree().process_frame then set its [member scale] property.
await this.get_tree().process_frame.as_promise()
this.scale = new Vector2(0, 0)
const tween = this.create_tween()
tween.tween_property(this, "scale", new Godot.Vector2(1, 1), 2)
tween.tween_callback(Godot.Callable.create(() => console.log("Tween done!")))
// await tween.finished.as_promise()
// console.log("Tween done!")
}}
/>
}
</VBoxContainer>
</CenterContainer>
)
}

View File

@@ -0,0 +1,111 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
"incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
"tsBuildInfoFile": ".godot/.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "esnext", /* Specify what module code is generated. */
"rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
"typeRoots": [ /* Specify multiple folders that act like './node_modules/@types'. */
"./node_modules/@types", "./typings"
],
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": ".godot/GodotJS", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
"noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
"sourceRoot": "./src", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
"noEmitOnError": false, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

View File

@@ -0,0 +1,368 @@
declare module "godot-jsb" {
import {
Callable,
MethodFlags,
MultiplayerAPI,
MultiplayerPeer,
Object as GObject,
PackedByteArray,
PropertyInfo,
Signal,
StringName,
Variant,
} from "godot";
const CAMEL_CASE_BINDINGS_ENABLED: boolean;
const DEV_ENABLED: boolean;
const TOOLS_ENABLED: boolean;
/** version of GodotJS */
const version: string;
/** impl currently used */
const impl: string;
/**
* Create godot Callable without a bound object.
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
*/
function callable<F extends Function>(fn: F): Callable<F>;
/**
* Create godot Callable with a bound object `self`.
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
*/
function callable<S extends GObject, F extends (this: S, ...args: any[]) => any>(self: S, fn: F): Callable<F>;
/**
* Explicitly convert a `PackedByteArray`(aka `Vector<uint8_t>`) into a javascript `ArrayBuffer`
* @deprecated [WARNING] This free function '_to_array_buffer' is deprecated and will be removed in a future version, use 'PackedByteArray.to_array_buffer()' instead.
*/
function to_array_buffer(packed: PackedByteArray): ArrayBuffer;
type AsyncModuleSourceLoaderResolveFunc = (source: string) => void;
type AsyncModuleSourceLoaderRejectFunc = (error: string) => void;
/**
* Set a callback function to handle the load of source code of asynchronous modules.
* Only use this function if it's not set in C++.
*/
function set_async_module_loader(
fn: (
module_id: string,
resolve: AsyncModuleSourceLoaderResolveFunc,
reject: AsyncModuleSourceLoaderRejectFunc,
) => void,
): void;
interface MinimalCommonJSModule {
exports: any;
loaded: boolean;
id: string;
}
/**
* Import a CommonJS module asynchronously.
*
* NOTE: Only the source code is loaded asynchronously, the module is still evaluated on the script thread.
* NOTE: Calling the $import() function without a async module loader set in advance will return undefined.
* @param module_id the module id to import
* @example
* ```js
* // [init.js]
* import * as jsb from "godot-jsb";
* jsb.set_async_module_loader((id, resolve, reject) => {
* console.log("[test] async module loader start", id);
* // here should be the actual async loading of the module, HTTP request, etc.
* // we just simulate it with a timeout
* setTimeout(() => {
* console.log("[test] async module loader resolve", id);
* resolve("exports.foo = function () { console.log('hello, module imported'); }");
* }, 3000);
* });
* // [somescript.js]
* jsb.$import("http://localhost/async_loaded.js").then(mod => {
* console.log("[test] async module loader", mod);
* mod.exports.foo();
* });
* ```
*/
function $import(module_id: string): Promise<MinimalCommonJSModule>;
interface ScriptPropertyInfo {
name: string;
type: Variant.Type;
class_?: Function;
hint?: number;
hint_string?: string;
usage?: number;
cache?: boolean;
}
export namespace internal {
type OnReadyEvaluatorFunc = (self: any) => any;
type GObjectConstructor = abstract new (...args: any[]) => GObject;
function add_script_signal(prototype: GObject, name: string): void;
function add_script_property(prototype: GObject, details: ScriptPropertyInfo): void;
function add_script_ready(
prototype: GObject,
details: {
name: string;
evaluator: string | OnReadyEvaluatorFunc;
},
): void;
function add_script_tool(constructor: GObjectConstructor): void;
function add_script_icon(constructor: GObjectConstructor, path: string): void;
function add_script_rpc(
prototype: GObject,
property_key: string,
config: {
rpc_mode?: MultiplayerAPI.RPCMode;
call_local?: boolean;
transfer_mode?: MultiplayerPeer.TransferMode;
channel?: number;
},
): void;
function create_script_signal_getter(name: string): (this: GObject) => Signal;
function create_script_cached_property_updater(name: string): (this: GObject, value?: unknown) => void;
// 0: deprecated, 1: experimental, 2: help
function set_script_doc(
target: GObjectConstructor,
property_key: undefined,
field: 0 | 1 | 2,
message: string,
): void;
function set_script_doc(target: GObject, property_key: string, field: 0 | 1 | 2, message: string): void;
function add_module(id: string, obj: any): void;
function find_module(id: string): any;
function notify_microtasks_run(): void;
namespace names {
/**
* Get the transformed name of a Godot class
*/
function get_class<T extends string>(godot_class: T): T;
/**
* Get the transformed name of a Godot enum
*/
function get_enum<T extends string>(godot_enum: T): T;
/**
* Get the transformed name of a Godot enum
*/
function get_enum_value<T extends string>(godot_enum_value: T): T;
/**
* Get the transformed name of a Godot class member
*/
function get_member<T extends string>(godot_member: T): T;
/**
* Get the internal Godot name/identifier from a transformed name i.e. the inverse of the other accessors.
*/
function get_internal_mapping(name: string): string;
/**
* Get the transformed name of a Godot function parameter
*/
function get_parameter<T extends string>(parameter: T): T;
/**
* Get the transformed type name of a Variant.Type
*/
function get_variant_type<T extends string>(type: Variant.Type): StringName;
}
}
namespace editor {
interface PrimitiveConstantInfo {
name: string;
type: Variant.Type;
value: number /* only if type is literal */;
}
interface ConstantInfo {
name: string;
value: number /** int64_t */;
}
interface EnumInfo {
name: string;
literals: Record<string, number>;
is_bitfield: boolean;
}
interface DefaultArgumentInfo {
type: Variant.Type;
value: any;
}
// we treat godot MethodInfo/MethodBind as the same thing here for simplicity
//NOTE some fields will not be set if it's actually a MethodInfo struct
interface MethodBind {
internal_name: string;
id: number;
name: string;
hint_flags: MethodFlags;
is_static: boolean;
is_const: boolean;
is_vararg: boolean;
argument_count: number /** int32_t */;
args_: Array<PropertyInfo>;
default_arguments?: Array<DefaultArgumentInfo>;
return_: PropertyInfo | undefined;
}
interface PropertySetGetInfo {
internal_name: string;
name: string;
type: Variant.Type;
index: number;
setter: string;
getter: string;
info: PropertyInfo;
}
interface PrimitiveGetSetInfo {
name: string;
type: Variant.Type;
}
interface SignalInfo {
internal_name: string;
name: string;
method_: MethodBind;
}
interface ArgumentInfo {
name: string;
type: Variant.Type;
}
interface ConstructorInfo {
arguments: Array<ArgumentInfo>;
}
interface OperatorInfo {
name: string;
return_type: Variant.Type;
left_type: Variant.Type;
right_type: Variant.Type;
}
interface BasicClassInfo {
name: string;
methods: Array<MethodBind>;
enums?: Array<EnumInfo>;
}
// godot class
interface ClassInfo extends BasicClassInfo {
internal_name: string;
super: string;
properties: Array<PropertySetGetInfo>;
virtual_methods: Array<MethodBind>;
signals: Array<SignalInfo>;
constants?: Array<ConstantInfo>;
}
// variant class
interface PrimitiveClassInfo extends BasicClassInfo {
// self type
type: Variant.Type;
// valid only if has_indexing
element_type?: Variant.Type;
// true only if is_keyed
is_keyed: boolean;
constructors?: Array<ConstructorInfo>;
operators?: Array<OperatorInfo>;
properties?: Array<PrimitiveGetSetInfo>;
constants?: Array<PrimitiveConstantInfo>;
}
interface SingletonInfo {
name: string;
class_name: string;
user_created: boolean;
editor_only: boolean;
}
interface GlobalConstantInfo {
name: string;
values: { [name: string]: number /** int64_t */ };
}
interface ClassDoc {
brief_description: string;
constants: { [name: string]: { description: string } };
methods: { [name: string]: { description: string } };
properties: { [name: string]: { description: string } };
signals: { [name: string]: { description: string } };
}
function get_class_doc(class_name: string): ClassDoc | undefined;
/**
* get a list of all classes registered in ClassDB
*/
function get_classes(): Array<ClassInfo>;
function get_primitive_types(): Array<PrimitiveClassInfo>;
function get_singletons(): Array<SingletonInfo>;
function get_global_constants(): Array<GlobalConstantInfo>;
function get_utility_functions(): Array<MethodBind>;
function get_input_actions(): Array<string>;
function delete_file(filepath: string): void;
const VERSION_DOCS_URL: string;
}
}
// Globals
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */
interface Console {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/assert_static) */
assert(condition?: boolean, ...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug_static) */
debug(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static) */
error(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info_static) */
info(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) */
log(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time_static) */
time(label?: string): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd_static) */
timeEnd(label?: string): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace_static) */
trace(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn_static) */
warn(...data: any[]): void;
}
declare const console: Console;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearInterval) */
declare function clearInterval(id: number | undefined): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearTimeout) */
declare function clearTimeout(id: number | undefined): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setInterval) */
declare function setInterval(handler: () => void, timeout?: number, ...arguments: any[]): number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout) */
declare function setTimeout(handler: () => void, timeout?: number, ...arguments: any[]): number;

418
packages/example/typings/godot.mix.d.ts vendored Normal file
View File

@@ -0,0 +1,418 @@
declare module "godot" {
const IntegerType: unique symbol;
const FloatType: unique symbol;
/**
* Proxy objects are typically transparent by design, allowing a proxy to impersonate a type. However, GodotJS also
* makes use of proxies to wrap existing objects in order to provide a more convenient API. In such cases, it is
* convenient to be able to unwrap the object i.e. obtain access to the target object. In order to achieve this,
* GodotJS exposes a property with the key ProxyTarget. You can access this to, for example, obtain direct access
* to the original GDictionary wrapped via a call to .proxy(). Additionally, GodotJS uses this property internally
* to unwrap proxies, thus allowing you to pass a proxy wrapped GArray/GDictionary as an argument to any function
* expecting a GArray/GDictionary parameter.
*/
const ProxyTarget: unique symbol;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable/Callable<T>.
*/
type AnyCallable = Callable;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal/Signal<T>.
*/
type AnySignal = Signal;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable0<R = void> = Callable<() => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable1<T1, R = void> = Callable<(v1: T1) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable2<T1, T2, R = void> = Callable<(v1: T1, v2: T2) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable3<T1, T2, T3, R = void> = Callable<(v1: T1, v2: T2, v3: T3) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable4<T1, T2, T3, T4, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable5<T1, T2, T3, T4, T5, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal0 = Signal<() => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal1<T1> = Signal<(v1: T1) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal2<T1, T2> = Signal<(v1: T1, v2: T2) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal3<T1, T2, T3> = Signal<(v1: T1, v2: T2, v3: T3) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal4<T1, T2, T3, T4> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal5<T1, T2, T3, T4, T5> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => void>;
type ExtractValueKeys<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
type UndefinedToNull<T> = T extends undefined ? null : T;
// A bit convoluted, but written this way to mitigate type definitions circularly depending on themselves.
type GodotNames<T> = "__godotNameMap" extends keyof T
? keyof T["__godotNameMap"] | Exclude<keyof T, T["__godotNameMap"][keyof T["__godotNameMap"]]>
: keyof T;
type ResolveGodotName<T, Name> = Name extends keyof T
? Name
: "__godotNameMap" extends keyof T
? Name extends keyof T["__godotNameMap"]
? T["__godotNameMap"][Name]
: never
: never;
type ResolveGodotNameValue<T, Name> = Name extends keyof T
? T[Name]
: "__godotNameMap" extends keyof T
? Name extends keyof T["__godotNameMap"]
? T["__godotNameMap"][Name] extends keyof T
? T[T["__godotNameMap"][Name]]
: never
: never
: never;
type ResolveGodotNameParameters<T, Name> = Name extends GodotDynamicDispatchName
? GAny[]
: ResolveGodotName<T, Name> extends keyof T
? T[ResolveGodotName<T, Name>] extends {
bivarianceHack(...args: infer P extends GAny[]): void | GAny;
}["bivarianceHack"]
? P
: never
: never;
type ResolveGodotReturnType<T, Name> = Name extends GodotDynamicDispatchName
? void | GAny
: ResolveGodotName<T, Name> extends keyof T
? T[ResolveGodotName<T, Name>] extends (...args: any[]) => infer R
? R
: never
: never;
/**
* Godot has many APIs that are a form of dynamic dispatch, i.e., they take the name of a function or property and
* then operate on the value matching the name. TypeScript is powerful enough to allow us to type these APIs.
* However, since these APIs can be used to call each other, the type checker can get hung up trying to infinitely
* recurse on these types. What follows is an interface with the built-in dynamic dispatch names. GodotJS' types
* will not recurse through methods matching these names. If you want to build your own dynamic dispatch APIs, you
* can use interface merging to insert additional method names.
*/
interface GodotDynamicDispatchNames {
call: "call";
callv: "callv";
call_deferred: "call_deferred";
add_do_method: "add_do_method";
add_undo_method: "add_undo_method";
}
type GodotDynamicDispatchName = GodotDynamicDispatchNames[keyof GodotDynamicDispatchNames];
/**
* This namespace and the values within do not exist at runtime. They're declared here, for internal use only, as a
* work-around for limitations of TypeScript's type system.
*/
namespace __PathMappableDummyKeys {}
type PathMappable<DummyKey extends symbol, Map extends PathMap = PathMap> = {
[K in DummyKey]: Map;
};
type PathMap<T = unknown> = Record<string, T>;
type StaticPath<
Map extends PathMap,
Permitted = any,
DefaultKey extends string = never,
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
> = IfAny<
Map,
string,
| (ExtractValueKeys<Map, Permitted> & string)
| (DummyKey extends any
?
| (Map[DefaultKey] extends never
? never
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
? StaticPath<ChildMap, Permitted, DefaultKey>
: never)
| {
[K in Exclude<keyof Map, DefaultKey> & string]: Map[K] extends PathMappable<
DummyKey,
infer ChildMap
>
? `${K}/${StaticPath<ChildMap, Permitted, DefaultKey>}`
: never;
}[Exclude<keyof Map, DefaultKey> & string]
: never)
>;
type ResolvePath<
Map extends PathMap,
Path extends string,
Default,
Permitted,
DefaultKey extends string = never,
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
> = IfAny<
Map,
Permitted,
DummyKey extends any
? Path extends keyof Map
? [Map[Path]] extends [Permitted]
? [undefined] extends [Map[Path]]
? null | Exclude<Map[Path], undefined>
: Map[Path]
: Default
: Path extends `${infer Key extends Exclude<keyof Map, DefaultKey> & string}/${infer SubPath}`
? Map[Key] extends PathMappable<DummyKey, infer ChildMap>
? ResolvePath<ChildMap, SubPath, Default, Permitted>
: Default
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
? ResolvePath<ChildMap, Path, Default, Permitted>
: never
: never
>;
type PathMapChild<Map extends NodePathMap, Permitted, Default> = IfAny<
Map,
Permitted,
Map[keyof Map] extends undefined | Permitted ? Exclude<Map[keyof Map], undefined> : Default
>;
type NodePathMap = PathMap<undefined | Node>;
type StaticNodePath<Map extends NodePathMap, Permitted = Node> = StaticPath<
Map,
Permitted,
never,
typeof __PathMappableDummyKeys.Node
>;
type ResolveNodePath<Map extends NodePathMap, Path extends string, Default = never, Permitted = Node> = ResolvePath<
Map,
Path,
Default,
Permitted,
never,
typeof __PathMappableDummyKeys.Node
>;
type ResolveNodePathMap<Map extends NodePathMap, Path extends string, Default = never> = Path extends keyof Map
? Map[Path] extends Node<infer ChildMap>
? ChildMap
: Default
: Path extends `${infer Key extends keyof Map & string}/${infer SubPath}`
? Map[Key] extends Node<infer ChildMap>
? ResolveNodePathMap<ChildMap, SubPath, Default>
: Default
: Default;
type NodePathMapChild<Map extends NodePathMap> = PathMapChild<Map, Node, Node>;
type AnimationMixerPathMap = PathMap<AnimationLibrary>;
type StaticAnimationMixerPath<Map extends AnimationMixerPathMap> = StaticPath<
Map,
Animation,
"",
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
>;
type ResolveAnimationMixerPath<
Map extends AnimationMixerPathMap,
Path extends string,
Default = never,
> = ResolvePath<
Map,
Path,
Default,
Animation,
"",
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
>;
type GArrayElement<T extends GAny | GAny[], I extends int64 = int64> = T extends any[] ? T[I] : T;
/**
* GArray elements are exposed with a subset of JavaScript's standard Array API. Array indexes are exposed as
* enumerable properties, thus if you want to perform more complex operations you can convert to a regular
* JavaScript array with [...g_array.proxy()].
*/
class GArrayProxy<T> {
[Symbol.iterator](): IteratorObject<GProxyValueWrap<T>>;
/**
* Gets the length of the array. This is a number one higher than the highest index in the array.
*/
get length(): number;
/**
* Performs the specified action for each element in an array.
* @param callback A function that accepts up to three arguments. forEach calls the callback function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callback function. If thisArg is omitted, undefined is used as the this value.
*/
forEach<S = GArrayProxy<T>>(
callback: (this: GArrayProxy<T>, value: GProxyValueWrap<T>, index: number) => void,
thisArg?: S,
): void;
/**
* Removes the last element from an array and returns it.
* If the array is empty, undefined is returned and the array is not modified.
*/
pop(): GProxyValueWrap<T> | undefined;
/**
* Appends new elements to the end of an array, and returns the new length of the array.
* @param item New element to add to the array.
* @param additionalItems Additional new elements to add to the array.
*/
push(item: T | GProxyValueWrap<T>, ...additionalItems: Array<T | GProxyValueWrap<T>>): number;
/**
* Returns the index of the first occurrence of a value in an array, or -1 if it is not present.
* @param searchElement The value to locate in the array.
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
*/
indexOf(searchElement: T | GProxyValueWrap<T>, fromIndex?: number): number;
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
*/
includes(searchElement: T | GProxyValueWrap<T>): boolean;
toJSON(key?: any): any;
toString(): string;
[n: number]: T | GProxyValueWrap<T>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
}
// Ideally this would be a class, but TS currently doesn't provide a way to type a class with mapped properties.
/**
* GObject entries are exposed as enumerable properties, so Object.keys(), GObject.entries() etc. will work.
*/
type GDictionaryProxy<T> = {
[K in keyof T]: T[K] | GProxyValueWrap<T[K]>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
};
type GProxyValueWrap<V> =
V extends GArray<infer T>
? GArrayProxy<GArrayElement<T>>
: V extends GDictionary<infer T>
? GDictionaryProxy<T>
: V;
type GProxyValueUnwrap<V> = V extends GArrayProxy<infer E> ? E : V extends GDictionaryProxy<infer T> ? T : V;
type GWrappableValue = GAny | GWrappableValue[] | { [key: number | string]: GWrappableValue };
type GValueWrapUnchecked<V> = V extends any[]
? number extends V["length"]
? GArray<GValueWrapUnchecked<V[number]>>
: GArray<{ [I in keyof V]: GValueWrapUnchecked<V[I]> }>
: V extends GAny
? V
: GDictionary<{ [K in keyof V]: GValueWrapUnchecked<V[K]> }>;
type GValueWrap<V> = [keyof V] extends [never]
? GDictionary<{}>
: [V] extends [GWrappableValue]
? GValueWrapUnchecked<V>
: never;
type GValueUnwrap<V> =
V extends GArray<infer T>
? T extends any[]
? { [I in keyof T]: GValueUnwrap<T[I]> }
: Array<GValueUnwrap<T>>
: V extends GDictionary<infer T>
? { [K in keyof T]: GValueUnwrap<T[K]> }
: V;
/**
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
* @see GReadProxyValueWrap
*/
type GArrayReadProxy<T> = Omit<GArrayProxy<T>, "forEach"> & {
[Symbol.iterator](): IteratorObject<GReadProxyValueWrap<T>>;
forEach<S = GArrayReadProxy<T>>(
callback: (this: GArrayReadProxy<T>, value: GReadProxyValueWrap<T>, index: number) => void,
thisArg?: S,
): void;
[n: number]: GReadProxyValueWrap<T>;
};
/**
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
* @see GReadProxyValueWrap
*/
type GDictionaryReadProxy<T> = {
[K in keyof T]: GReadProxyValueWrap<T[K]>;
};
// At runtime we only have the one kind of dictionary proxy and one kind of array proxy. The read interfaces have
// indexers typed correctly for access i.e. return proxied types. The non-read interfaces have indexers accurate for
// assignment and will accept both GArray/GDictionary and proxies. The read interfaces exist for convenience only,
// you can safely cast between the two interfaces types as desired.
type GReadProxyValueWrap<V> =
V extends GArray<infer E> ? GArrayReadProxy<E> : V extends GDictionary<infer T> ? GDictionaryReadProxy<T> : V;
interface PropertyInfo {
name: string;
type: Variant.Type;
class_name: string;
hint: PropertyHint;
hint_string: string;
usage: PropertyUsageFlags;
}
type BindRight<F extends Function, B extends any[]> = F extends (
this: infer T,
...args: [...infer A, ...B]
) => infer R
? (this: T, ...args: A) => R
: never;
}

View File

@@ -0,0 +1,39 @@
declare module "godot.worker" {
import { GAny, GArray, Object as GObject } from "godot";
class JSWorker {
constructor(path: string);
postMessage(message: any, transfer?: GArray | ReadonlyArray<NonNullable<GAny>>): void;
terminate(): void;
onready?: () => void;
onmessage?: (message: any) => void;
//TODO not implemented yet
onerror?: (error: any) => void;
/**
* @deprecated Use onmessage to receive messages sent from postMessage() with transfers included.
* @param obj
*/
ontransfer?: (obj: GObject) => void;
}
// only available in worker scripts
const JSWorkerParent:
| {
onmessage?: (message: any) => void;
close(): void;
/**
* @deprecated Use the transfer parameter of postMessage instead.
* @param obj
*/
transfer(obj: GObject): void;
postMessage(message: any, transfer?: GArray | ReadonlyArray<NonNullable<GAny>>): void;
}
| undefined;
}

10147
packages/example/typings/godot0.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9534
packages/example/typings/godot1.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9252
packages/example/typings/godot2.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9206
packages/example/typings/godot3.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9217
packages/example/typings/godot4.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9222
packages/example/typings/godot5.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9236
packages/example/typings/godot6.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9271
packages/example/typings/godot7.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

9267
packages/example/typings/godot8.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

6202
packages/example/typings/godot9.gen.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
declare module "jsb.editor.codegen" {
import type { ExtractValueKeys, GArray, GDictionary, Node, PropertyInfo, Resource, ResourceTypes, Script } from "godot";
import type * as GodotJsb from "godot-jsb";
export enum DescriptorType {
Godot = 0,
User = 1,
FunctionLiteral = 2,
ObjectLiteral = 3,
StringLiteral = 4,
NumericLiteral = 5,
BooleanLiteral = 6,
Union = 7,
Intersection = 8,
Conditional = 9,
Tuple = 10,
Infer = 11,
Mapped = 12,
Indexed = 13
}
/**
* Reference to a built-in type, either declared in the 'godot' namespace, or available as part of the standard library.
*/
export type GodotTypeDescriptor = GDictionary<{
type: DescriptorType.Godot;
name: string;
/**
* Generic arguments.
*/
arguments?: GArray<TypeDescriptor>;
}>;
/**
* Reference to a user defined type. A path must be specified so that the generated code is able to import the file
* where the type is declared/exported.
*/
export type UserTypeDescriptor = GDictionary<{
type: DescriptorType.User;
/**
* res:// style path to the TypeScript module where this type is exported.
*/
resource: ExtractValueKeys<ResourceTypes, Script>;
/**
* Preferred type name to use when importing.
*/
name: string;
/**
* Named module export that is being imported. When omitted, the default export is imported.
*/
export?: string;
/**
* Generic arguments.
*/
arguments?: GArray<TypeDescriptor>;
}>;
export type GenericParameterDescriptor = GDictionary<{
name: string;
extends?: TypeDescriptor;
default?: TypeDescriptor;
}>;
export type ParameterDescriptor = GDictionary<{
name: string;
type: TypeDescriptor;
optional?: boolean;
}>;
export type FunctionLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.FunctionLiteral;
generics?: GArray<GenericParameterDescriptor>;
parameters?: GArray<ParameterDescriptor>;
returns?: TypeDescriptor;
}>;
export type OptionalTypeDescriptor<Descriptor extends GDictionary> = Descriptor extends GDictionary<infer T> ? GDictionary<T & {
optional?: boolean;
}> : never;
export type ObjectLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.ObjectLiteral;
properties?: GDictionary<Partial<Record<string, OptionalTypeDescriptor<TypeDescriptor>>>>;
index?: GDictionary<{
key: TypeDescriptor;
value: TypeDescriptor;
}>;
}>;
export type StringLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.StringLiteral;
value: string;
template?: boolean;
}>;
export type NumberLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.NumericLiteral;
value: number;
}>;
export type BooleanLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.BooleanLiteral;
value: boolean;
}>;
export type TupleElementDescriptor = GDictionary<{
name?: string;
type: TypeDescriptor;
}>;
export type TupleTypeDescriptor = GDictionary<{
type: DescriptorType.Tuple;
elements: GArray<TupleElementDescriptor>;
}>;
export type UnionTypeDescriptor = GDictionary<{
type: DescriptorType.Union;
types: GArray<TypeDescriptor>;
}>;
export type IntersectionTypeDescriptor = GDictionary<{
type: DescriptorType.Intersection;
types: GArray<TypeDescriptor>;
}>;
export type InferTypeDescriptor = GDictionary<{
type: DescriptorType.Infer;
name: string;
}>;
export type ConditionalTypeDescriptor = GDictionary<{
type: DescriptorType.Conditional;
check: TypeDescriptor;
extends: TypeDescriptor;
true: TypeDescriptor;
false: TypeDescriptor;
}>;
export type MappedTypeDescriptor = GDictionary<{
type: DescriptorType.Mapped;
key: string;
in: TypeDescriptor;
as?: TypeDescriptor;
value: TypeDescriptor;
}>;
export type IndexedTypeDescriptor = GDictionary<{
type: DescriptorType.Indexed;
base: TypeDescriptor;
index: TypeDescriptor;
}>;
export type TypeDescriptor = GodotTypeDescriptor | UserTypeDescriptor | FunctionLiteralTypeDescriptor | ObjectLiteralTypeDescriptor | StringLiteralTypeDescriptor | NumberLiteralTypeDescriptor | BooleanLiteralTypeDescriptor | TupleTypeDescriptor | UnionTypeDescriptor | IntersectionTypeDescriptor | InferTypeDescriptor | ConditionalTypeDescriptor | MappedTypeDescriptor | IndexedTypeDescriptor;
/**
* Codegen analogue of NodePathMap.
*/
export type NodeTypeDescriptorPathMap = GDictionary<Partial<Record<string, TypeDescriptor>>>;
export enum CodeGenType {
ScriptNodeTypeDescriptor = 0,
ScriptResourceTypeDescriptor = 1
}
/**
* Handle a NodeTypeDescriptorCodeGenRequest to overwrite the generated type for nodes using this script.
*/
export type ScriptNodeTypeDescriptorCodeGenRequest = GDictionary<{
type: CodeGenType.ScriptNodeTypeDescriptor;
node: Node;
children: NodeTypeDescriptorPathMap;
}>;
/**
* Handle a ScriptResourceTypeDescriptorCodeGenRequest to overwrite the generated type for resources using this script.
*/
export type ScriptResourceTypeDescriptorCodeGenRequest = GDictionary<{
type: CodeGenType.ScriptResourceTypeDescriptor;
resource: Resource;
}>;
export type CodeGenRequest = ScriptNodeTypeDescriptorCodeGenRequest | ScriptResourceTypeDescriptorCodeGenRequest;
/**
* You can manipulate GodotJS' codegen by exporting a function from your script/module called `codegen`.
*/
export type CodeGenHandler = (request: CodeGenRequest) => undefined | TypeDescriptor;
export class TypeDB {
singletons: {
[name: string]: GodotJsb.editor.SingletonInfo;
};
classes: {
[name: string]: GodotJsb.editor.ClassInfo;
};
primitive_types: {
[name: string]: GodotJsb.editor.PrimitiveClassInfo;
};
globals: {
[name: string]: GodotJsb.editor.GlobalConstantInfo;
};
utilities: {
[name: string]: GodotJsb.editor.MethodBind;
};
class_docs: {
[name: string]: GodotJsb.editor.ClassDoc | false;
};
constructor();
find_doc(class_name: string): GodotJsb.editor.ClassDoc | undefined;
is_primitive_type(name: string): boolean;
is_valid_method_name(name: string): boolean;
make_classname(class_name: string, internal?: boolean): string;
make_typename(info: PropertyInfo, used_as_input: boolean, non_nullable: boolean): string;
make_arg(info: PropertyInfo, optional?: boolean): string;
make_literal_value(value: GodotJsb.editor.DefaultArgumentInfo): string;
make_arg_default_value(method_info: GodotJsb.editor.MethodBind, index: number): string;
make_args(method_info: GodotJsb.editor.MethodBind): string;
make_return(method_info: GodotJsb.editor.MethodBind): string;
make_signal_type(method_info: GodotJsb.editor.MethodBind): string;
}
export class TSDCodeGen {
private _split_index;
private _out_dir;
private _splitter;
private _types;
private _use_project_settings;
constructor(outDir: string, use_project_settings: boolean);
private make_path;
private new_splitter;
private split;
private cleanup;
has_class(name?: string): boolean;
emit(): Promise<void>;
private emit_utility;
private emit_global;
private emit_aliases;
private emit_singleton;
private emit_godot_primitive;
private emit_godot_class;
}
export class SceneTSDCodeGen {
private _out_dir;
private _scene_paths;
private _types;
constructor(out_dir: string, scene_paths: string[]);
private make_scene_path;
emit(): Promise<void>;
private emit_children_node_types;
private emit_scene_node_types;
}
export class ResourceTSDCodeGen {
private _out_dir;
private _resource_paths;
private _types;
constructor(out_dir: string, resource_paths: string[]);
private make_resource_path;
emit(): Promise<void>;
private emit_resource_type;
}
}
declare module "jsb.editor.main" {
import { PackedStringArray } from "godot";
export function auto_complete(pattern: string): PackedStringArray;
export function run_npm_install(): void;
}

View File

@@ -0,0 +1,209 @@
declare module "godot.lib.api" {
import type * as Godot from "godot";
import type * as GodotJsb from "godot-jsb";
function proxy_unwrap_value<T>(value: T): T;
function proxy_wrap_value<T>(value: T): T;
function array_proxy<T extends any[]>(arr: T): T;
function object_proxy<T extends object>(obj: T, remap_properties?: boolean): T;
function key_only_proxy<T extends object | ((...args: any[]) => any)>(target: T): any;
function instance_proxy<T extends object>(target_instance: T): T;
function class_proxy<T extends object>(target_class: T): T;
function function_proxy<T extends (...args: any[]) => any>(fn: T): T;
function enum_proxy<T extends object>(target_enum: T): T;
const proxy: {
array_proxy: typeof array_proxy;
class_proxy: typeof class_proxy;
enum_proxy: typeof enum_proxy;
function_proxy: typeof function_proxy;
instance_proxy: typeof instance_proxy;
key_only_proxy: typeof key_only_proxy;
object_proxy: typeof object_proxy;
proxy_unwrap_value: typeof proxy_unwrap_value;
proxy_wrap_value: typeof proxy_wrap_value;
};
type GodotLibApi = typeof Godot & {
jsb: typeof GodotJsb;
proxy: typeof proxy;
};
const api: GodotLibApi;
/**
* This is a starting point for writing GodotJS code that is camel-case binding agnostic at runtime.
*
* Library code must consume this API rather than "godot", and be built with camel case bindings disabled. This is to
* ensure that the library will function at runtime for all projects irrespective of whether they have camel-case
* bindings enabled.
*/
export = api;
}
declare module "godot.annotations" {
import type * as Godot from "godot";
import type { ClassBinder, RPCConfig } from "godot.annotations";
type VariantConstructor = abstract new (...args: any[]) => NonNullable<Godot.GAny> | Number | String | Boolean;
type GObjectConstructor = abstract new (...args: any[]) => Godot.Object;
type ClassSpecifier = VariantConstructor | Symbol | EnumPlaceholder | TypePairPlaceholder;
interface EnumPlaceholder {
target: Record<string, string | number>;
}
interface TypePairPlaceholder {
key: VariantConstructor;
value: VariantConstructor;
}
export function EnumType(type: Record<string, string | number>): EnumPlaceholder;
export function TypePair(key: VariantConstructor, value: VariantConstructor): TypePairPlaceholder;
/** @deprecated Use createClassBinder() instead. */
export function signal(): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportSignal: typeof signal;
/** @deprecated Use createClassBinder() instead. */
export function export_multiline(): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportMultiline: typeof export_multiline;
/** @deprecated Use createClassBinder() instead. */
export function export_range(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportRange: typeof export_range;
/** @deprecated Use createClassBinder() instead. */
export function export_range_i(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportIntRange: typeof export_range_i;
/** String as a path to a file, custom filter provided as hint. */
/** @deprecated Use createClassBinder() instead. */
export function export_file(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportFile: typeof export_file;
/** @deprecated Use createClassBinder() instead. */
export function export_dir(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export function export_global_file(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportGlobalFile: typeof export_global_file;
/** @deprecated Use createClassBinder() instead. */
export function export_global_dir(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportGlobalDir: typeof export_global_dir;
/** @deprecated Use createClassBinder() instead. */
export function export_exp_easing(hint?: "" | "attenuation" | "positive_only" | "attenuation,positive_only"): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportExpEasing: typeof export_exp_easing;
/**
* A Shortcut for `export_(Variant.Type.TYPE_ARRAY, { class_: clazz })`
*/
/** @deprecated Use createClassBinder() instead. */
export function export_array(clazz: ClassSpecifier): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportArray: typeof export_array;
/**
* A Shortcut for exporting a dictionary { class_: [key_class, value_class] })`
*/
/** @deprecated Use createClassBinder() instead. */
export function export_dictionary(key_class: VariantConstructor, value_class: VariantConstructor): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportDictionary: typeof export_dictionary;
/** @deprecated Use createClassBinder() instead. */
export function export_object(clazz: GObjectConstructor): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportObject: typeof export_object;
/**
* [low level export]
* @deprecated Use createClassBinder() instead.
* */
export function export_(type: Godot.Variant.Type, details?: {
class_?: ClassSpecifier;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export function Export(type: Godot.Variant.Type, details?: {
class?: ClassSpecifier;
hint?: Godot.PropertyHint;
hintString?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/**
* In Godot, class members can be exported.
* This means their value gets saved along with the resource (such as the scene) they're attached to.
* They will also be available for editing in the property editor.
* Exporting is done by using the `@export_var` (or `@export_`) annotation.
*/
/** @deprecated Use createClassBinder() instead. */
export function export_var(type: Godot.Variant.Type, details?: {
class_?: ClassSpecifier;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportVar: typeof export_var;
/**
* NOTE only int value enums are allowed
*/
/** @deprecated Use createClassBinder() instead. */
export function export_enum(enum_type: Record<string, string | number>): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportEnum: typeof export_enum;
/**
* NOTE only int value enums are allowed
*/
/** @deprecated Use createClassBinder() instead. */
export function export_flags(enum_type: Record<string, string | number>): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportFlags: typeof export_flags;
/** @deprecated Use createClassBinder() instead. */
export function rpc(config?: RPCConfig): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Rpc: typeof rpc;
/**
* auto initialized on ready (before _ready called)
*
* @deprecated Use createClassBinder() instead.
*/
export function onready(evaluator: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const OnReady: typeof onready;
/** @deprecated Use createClassBinder() instead. */
export function tool(): (target: any, name: undefined) => void;
/** @deprecated Use createClassBinder() instead. */
export const Tool: typeof tool;
/** @deprecated Use createClassBinder() instead. */
export function icon(path: string): (target: any, name: undefined) => void;
/** @deprecated Use createClassBinder() instead. */
export const Icon: typeof icon;
/** @deprecated Use createClassBinder() instead. */
export function deprecated(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Deprecated: typeof deprecated;
/** @deprecated Use createClassBinder() instead. */
export function experimental(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Experimental: typeof experimental;
/** @deprecated Use createClassBinder() instead. */
export function help(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Help: typeof help;
export type ClassMemberDecorator<RestrictedContext extends ClassMemberDecoratorContext = ClassMemberDecoratorContext> = <Context extends RestrictedContext>(target: ClassMemberDecoratorTarget<Context>, context: Context) => void | ClassMemberDecoratorReturn<Context>;
export type ClassMemberDecoratorTarget<Context extends ClassMemberDecoratorContext> = Context extends ClassMethodDecoratorContext<infer _, infer Value> ? (...args: unknown[]) => Value : Context extends ClassGetterDecoratorContext<infer _, infer Value> ? () => Value : Context extends ClassSetterDecoratorContext<infer _, infer Value> ? (value: Value) => void : Context extends ClassFieldDecoratorContext ? undefined : Context extends ClassAccessorDecoratorContext<infer _, infer Value> ? {
get: () => Value;
set: (value: Value) => void;
} : never;
export type ClassMemberDecoratorReturn<Context extends ClassMemberDecoratorContext> = Context extends ClassMethodDecoratorContext<infer This, infer Value> ? (this: This, ...args: unknown[]) => Value : Context extends ClassGetterDecoratorContext<infer This, infer Value> ? (this: This) => Value : Context extends ClassSetterDecoratorContext<infer This, infer Value> ? (this: This, value: Value) => void : Context extends ClassFieldDecoratorContext<infer This, infer Value> ? (this: This, initialValue: Value) => Value : Context extends ClassAccessorDecoratorContext<infer This, infer Value> ? {
get?(this: This): Value;
set?(this: This, value: Value): void;
init?(this: This, initialValue: Value): Value;
} : never;
export type ClassDecorator<This extends abstract new (...args: any) => any = abstract new (...args: any) => any> = (target: This, context: ClassDecoratorContext<This>) => void;
export type ClassDecoratorClass<Context extends ClassDecoratorContext> = Context extends ClassDecoratorContext<infer Class> ? Class : never;
export type Decorator<RestrictedContext extends DecoratorContext = DecoratorContext> = RestrictedContext extends ClassDecoratorContext ? <Context extends RestrictedContext>(target: ClassDecoratorClass<Context>, context: Context) => void : RestrictedContext extends ClassMemberDecoratorContext ? <Context extends RestrictedContext>(target: ClassMemberDecoratorTarget<Context>, context: Context) => void | ClassMemberDecoratorReturn<Context> : never;
export type AnyDecorator = (value: unknown, context: DecoratorContext) => unknown;
export type ClassValueMemberDecoratorContext<This = unknown, Value = unknown> = ClassGetterDecoratorContext<This, Value> | ClassSetterDecoratorContext<This, Value> | ClassFieldDecoratorContext<This, Value> | ClassAccessorDecoratorContext<This, Value>;
export function createClassBinder(): ClassBinder;
}
declare module "godot.typeloader" {
/**
* @param type the loaded type or function in godot module
*/
export type TypeLoadedCallback = (type: any) => void;
export function on_type_loaded(type_name: string | string[], callback: TypeLoadedCallback): void;
}
declare module "jsb.core" { }
declare module "jsb.inject" { }

View File

@@ -0,0 +1,144 @@
declare module "godot.annotations" {
import * as Godot from "godot";
import * as GodotJsb from "godot-jsb";
type ClassBinder = (() =>
((
target: GObjectConstructor,
context: ClassDecoratorContext
) => void))
& {
tool: () =>
((
target: GObjectConstructor,
_context: ClassDecoratorContext
) => void);
icon: (path: string) =>
((
target: GObjectConstructor,
_context: ClassDecoratorContext
) => void);
export: ((
type: Godot.Variant.Type,
options?: ExportOptions
) => ClassMemberDecorator)
& {
multiline: () => ClassMemberDecorator;
range: (
min: number,
max: number,
step: number,
...extra_hints: string[]
) => ClassMemberDecorator;
range_int: (
min: number,
max: number,
step: number,
...extra_hints: string[]
) => ClassMemberDecorator;
file: (filter: string) => ClassMemberDecorator;
dir: (filter: string) => ClassMemberDecorator;
global_file: (filter: string) => ClassMemberDecorator;
global_dir: (filter: string) => ClassMemberDecorator;
exp_easing: (
hint?: ""
| "attenuation"
| "positive_only"
| "attenuation,positive_only"
) => ClassMemberDecorator;
array: (clazz: ClassSpecifier) => ClassMemberDecorator;
dictionary: (
key_class: VariantConstructor,
value_class: VariantConstructor
) => ClassMemberDecorator;
object: <
Constructor extends GObjectConstructor>(clazz: Constructor
) =>
ClassMemberDecorator<
ClassValueMemberDecoratorContext<
unknown,
null
| InstanceType<Constructor>
>
>;
"enum": (
enum_type: Record<
string,
string
| number
>
) => ClassMemberDecorator;
flags: (
enum_type: Record<
string,
string
| number
>
) => ClassMemberDecorator;
cache: () =>
ClassMemberDecorator<
ClassAccessorDecoratorContext<Godot.Object>
| ClassSetterDecoratorContext<Godot.Object>
>;
};
signal: () =>
(<
Context extends ClassAccessorDecoratorContext<
Godot.Object,
Godot.Signal
>
| ClassGetterDecoratorContext<
Godot.Object,
Godot.Signal
>
| ClassFieldDecoratorContext<
Godot.Object,
Godot.Signal
>>(
_target: unknown,
context: Context
) => ClassMemberDecoratorReturn<Context>);
rpc: (config?: RPCConfig) =>
((
_target: Function,
context: string
| ClassMethodDecoratorContext
) => void);
onready: (
evaluator: string
| GodotJsb.internal.OnReadyEvaluatorFunc
) =>
((
_target: undefined,
context: string
| ClassMethodDecoratorContext
) => void);
deprecated: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
experimental: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
help: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
}
type ExportOptions = {
"class"?: any;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}
type RPCConfig = {
mode?: Godot.MultiplayerAPI.RPCMode;
sync?: "call_remote"
| "call_local";
transfer_mode?: Godot.MultiplayerPeer.TransferMode;
transfer_channel?: number;
}
}

View File

@@ -37,6 +37,12 @@
"clean:dist": "rm -rf dist", "clean:dist": "rm -rf dist",
"clean:modules": "rm -rf node_modules" "clean:modules": "rm -rf node_modules"
}, },
"devDependencies": {
"@types/react-reconciler": "~0.32.0"
},
"dependencies": {
"react-reconciler": "~0.33.0"
},
"peerDependencies": { "peerDependencies": {
"@types/react": "^19.2.0", "@types/react": "^19.2.0",
"react": "^19.2.0" "react": "^19.2.0"

View File

@@ -0,0 +1,16 @@
/** biome-ignore-all lint/complexity/noBannedTypes: {} is the "empty props" type in React */
import type * as Godot from "godot"
import type * as React from "react"
import * as Renderer from "./Renderer.js"
export const make = <C extends new (...args: any[]) => Godot.Node<Godot.NodePathMap>>(
parent: C,
component: React.FC<{}>,
): C => class extends parent {
_ready(): void {
// @ts-expect-error
if (super._ready) super._ready()
Renderer.renderComponent(this, component)
}
}

View File

@@ -0,0 +1,109 @@
import Godot from "godot"
import * as React from "react"
export interface Component<T extends Godot.Node<Godot.NodePathMap>>
extends React.FunctionComponent<Props<T>>, Prototype<T> {}
export type Props<T extends Godot.Node<Godot.NodePathMap>> = {
readonly ref?: React.RefObject<T | null>
} & {
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
[K in keyof T as T[K] extends Function | Godot.Signal ? never : K]?: T[K]
} & {
[K in keyof T as T[K] extends Godot.Signal ? K : never]?: T[K] extends Godot.Signal<infer F>
? ((this: T, ...args: Parameters<F>) => ReturnType<F>) | ((this: T, ...args: Parameters<F>) => Promise<ReturnType<F>>)
: never
}
export interface Prototype<T extends Godot.Node<Godot.NodePathMap>> {
useRef(): React.RefObject<T | null>
useUnsafeRef(): React.RefObject<T>
}
export interface InstrinsicAttributes extends React.Attributes {
readonly children?: React.ReactNode
readonly name?: string
}
export const Prototype: Prototype<any> = {
useRef() { return React.useRef(null) },
useUnsafeRef() { return React.useRef(null) },
}
export const fromClass = <T extends Godot.Node<Godot.NodePathMap>>(
class_: new (...args: any[]) => T
): Component<T> => Object.setPrototypeOf(
Object.assign(
(props: Props<T>) => React.createElement("node", { ...props, class: class_ }),
{ displayName: class_.name },
),
Prototype,
)
export const fromSceneUnsafe = <T extends Godot.Node<Godot.NodePathMap> = Godot.Node<Godot.NodePathMap>>(
path: string
): Component<T> => Object.setPrototypeOf(
Object.assign(
(props: Props<T>) => React.createElement("scene", { ...props, path }),
{ displayName: path },
),
Prototype,
)
export declare namespace fromScene {
export type SceneNames = {
[K in keyof Godot.ResourceTypes]: Godot.ResourceTypes[K] extends Godot.PackedScene ? K : never
}[keyof Godot.ResourceTypes]
}
export const fromScene = <A extends fromScene.SceneNames>(
path: A
): Component<Godot.ResourceTypes[A] extends Godot.PackedScene<infer T> ? T : never> => fromSceneUnsafe(path)
export declare namespace useSignal {
export type SignalNames<T extends Godot.Node<Godot.NodePathMap>> = {
[K in keyof T & string]: T[K] extends Godot.Signal ? K : never
}[keyof T & string]
export type Function<T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>> = (
T[N] extends Godot.Signal<infer F>
? ((this: T, ...args: Parameters<F>) => ReturnType<F>) | ((this: T, ...args: Parameters<F>) => Promise<ReturnType<F>>)
: never
)
}
export const useSignal = <T extends Godot.Node<Godot.NodePathMap>, A extends useSignal.SignalNames<T>>(
ref: React.RefObject<T | null>,
name: A,
f: useSignal.Function<T, A>,
// biome-ignore lint/correctness/useExhaustiveDependencies: "f" is non-reactive
): void => React.useEffect(() => {
if (!ref.current) return
const signal = ref.current[name] as Godot.Signal
const callable = Godot.Callable.create(ref.current, f)
signal.connect(callable)
return () => { signal.disconnect(callable) }
}, [ref.current, name])
export declare namespace useSignalValues {
export type SignalNames<T extends Godot.Node<Godot.NodePathMap>> = useSignal.SignalNames<T>
export type SignalValues<T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>> = (
T[N] extends Godot.Signal<infer F>
? Parameters<F>
: never
)
}
export const useSignalValues = <T extends Godot.Node<Godot.NodePathMap>, A extends useSignal.SignalNames<T>>(
ref: React.RefObject<T | null>,
name: A,
initialValue:
| useSignalValues.SignalValues<NoInfer<T>, NoInfer<A>>
| (() => useSignalValues.SignalValues<NoInfer<T>, NoInfer<A>>),
): useSignalValues.SignalValues<T, A> => {
const [values, setValues] = React.useState(initialValue)
useSignal(ref, name, ((...args: any) => setValues(args)) as any)
return values
}

View File

@@ -0,0 +1,25 @@
import type * as Component from "./Component.js"
// export type NodeClass = {
// [K in keyof typeof Godot]: typeof Godot[K] extends new (...args: any[]) => Godot.Node
// ? K
// : never
// }[keyof typeof Godot]
// export type GodotIntrinsicElements = {
// [K in NodeClass as PascalToCamel<K>]: Component.Props<InstanceType<(typeof Godot)[K]>>
// } & {
// element: {
// class: new (...args: any[]) => Godot.Node
// }
// }
declare global {
namespace React {
namespace JSX {
// interface IntrinsicElements extends GodotIntrinsicElements {}
interface IntrinsicAttributes extends Component.InstrinsicAttributes {}
}
}
}

View File

@@ -0,0 +1,280 @@
/** biome-ignore-all lint/complexity/noBannedTypes: "Function" is used as a type in GodotJS, keeping it for consistency */
import { Callable, Control, Node, type NodePathMap, PackedScene, ResourceLoader, Signal } from "godot"
import ReactReconciler, { type HostConfig } from "react-reconciler"
import { hasProperty } from "./utils.js"
const DefaultEventPriority = 32
export const make = () => {
let eventTime = 0
let currentPriority = DefaultEventPriority
return ReactReconciler<
string,
Record<string, unknown>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
unknown,
unknown,
unknown,
unknown,
unknown
>({
supportsMutation: true,
createInstance(type, props) {
let instance: Node
if (type === "node") {
if (!hasProperty(props, "class"))
throw new Error("Property 'class' required when using the 'node' intrinsic type")
instance = new (props.class as any)()
}
else if (type === "scene") {
if (!hasProperty(props, "path"))
throw new Error("Property 'path' required when using the 'scene' intrinsic type")
if (typeof props.path !== "string")
throw new Error("Property 'path' is not a string")
const res = ResourceLoader.load(props.path)
if (!(res instanceof PackedScene))
throw new Error(`Resource at 'path' is not a PackedScene`)
instance = res.instantiate()
}
else {
// const className = snakeToPascal(camelToSnake(type))
// if (!ClassDB.class_exists(className))
// throw new Error(`Class is invalid: '${className}' (declared as '${type}') is not a valid engine or GDExtension class`)
// instance = ClassDB.instantiate(className)
throw new Error(`Unsupported JSX type: '${ type }'`)
}
if (!(instance instanceof Node))
throw new Error("Class is not a subclass of 'Node'")
applyNextProps(instance, props)
return instance
},
createTextInstance(_text) {
throw new Error("createTextInstance not supported")
},
appendInitialChild(parent, child) {
parent.add_child(child)
},
appendChild(parent, child) {
parent.add_child(child)
},
appendChildToContainer(container, child) {
container.add_child(child)
},
removeChild(parent, child) {
parent.remove_child(child)
},
removeChildFromContainer(container, child) {
container.remove_child(child)
},
insertBefore(_parent, child, before) {
before.add_sibling(child)
},
finalizeInitialChildren() {
return false
},
prepareForCommit() { return null },
resetAfterCommit() {},
getRootHostContext() {
return {}
},
getChildHostContext(parentHostContext, _type, _rootContainer) {
return parentHostContext
},
shouldSetTextContent() {
return false
},
commitUpdate(instance, _type, _prevProps, nextProps, _internalHandle) {
applyNextProps(instance, nextProps)
},
commitTextUpdate(_textInstance, _oldText, _newText) {
throw new Error("commitTextUpdate not supported")
},
getPublicInstance(instance) {
return instance
},
resolveUpdatePriority() {
return DefaultEventPriority
},
resolveEventTimeStamp() {
return ++eventTime
},
trackSchedulerEvent() {},
resolveEventType() {
return null
},
getCurrentUpdatePriority() {
return currentPriority
},
setCurrentUpdatePriority(newPriority) {
currentPriority = newPriority
},
clearContainer(container) {
for (const child of container.get_children()) {
container.remove_child(child)
}
},
scheduleTimeout: setTimeout,
cancelTimeout: clearTimeout,
noTimeout: -1,
// isPrimaryRenderer: true,
// supportsPersistence: false,
// preparePortalMount(_containerInfo) {
// throw new Error("Function not implemented.")
// },
// getInstanceFromNode(_node) {
// throw new Error("Function not implemented.")
// },
// beforeActiveInstanceBlur() {
// throw new Error("Function not implemented.")
// },
// afterActiveInstanceBlur() {
// throw new Error("Function not implemented.")
// },
// prepareScopeUpdate(_scopeInstance, _instance) {
// throw new Error("Function not implemented.")
// },
// getInstanceFromScope(_scopeInstance) {
// throw new Error("Function not implemented.")
// },
detachDeletedInstance(node) {
node.queue_free()
},
// supportsHydration: false,
// NotPendingTransition: undefined,
// HostTransitionContext: undefined as any,
// resetFormInstance(_form) {
// throw new Error("Function not implemented.")
// },
// requestPostPaintCallback(_callback: (time: number) => void) {
// throw new Error("Function not implemented.")
// },
// shouldAttemptEagerTransition: (): boolean => {
// throw new Error("Function not implemented.")
// },
// maySuspendCommit(_type, _props) {
// throw new Error("Function not implemented.")
// },
// preloadInstance(_type, _props) {
// throw new Error("Function not implemented.")
// },
// startSuspendingCommit() {
// throw new Error("Function not implemented.")
// },
// suspendInstance(_type, _props) {
// throw new Error("Function not implemented.")
// },
// waitForCommitToBeReady() {
// throw new Error("Function not implemented.")
// },
} as Partial<
HostConfig<
string,
Record<string, unknown>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
Node<NodePathMap>,
unknown,
unknown,
unknown,
unknown,
unknown
>
> as any)
}
const applyNextProps = (instance: Node<NodePathMap>, nextProps: Record<string, unknown>) => {
Object.keys(nextProps).forEach(name => {
if (!hasProperty(instance, name)) return
if (name === "name") {
if (typeof nextProps[name] !== "string")
throw new Error("Prop 'name' should be a string")
instance.set_name(nextProps[name])
return
}
if (instance[name] instanceof Signal) {
if ((typeof nextProps[name] !== "function") || nextProps[name] === undefined)
throw new Error(`Prop '${ name }' should be a function or undefined`)
instance[`${ name }_event`] = nextProps[name]
if (!isNodeSignalRegistered(instance, name)) {
const callable = Callable.create(instance, function(this, ...args) {
if (this[`${ name }_event`])
(this[`${ name }_event`] as Function)(...args)
})
instance[`${ name }_callable`] = callable
instance.connect(name, callable)
}
return
}
if (instance instanceof Control) {
if (name === "anchors_preset") {
if (typeof nextProps[name] !== "number")
throw new Error("Prop 'anchors_preset' should be a number")
instance.set_anchors_preset(nextProps[name])
return
}
}
instance[name] = nextProps[name]
})
}
type NodeWithSignalMetadata<A extends string> = Node<NodePathMap> & {
[K in `${ A }_callable`]: Callable
} & {
[K in `${ A }_event`]?: Function
}
const isNodeSignalRegistered = <A extends string>(
u: Node<NodePathMap>,
name: A,
): u is NodeWithSignalMetadata<A> => (
hasProperty(u, `${ name }_callable`) &&
u[`${ name }_callable`] instanceof Callable
)

View File

@@ -0,0 +1,57 @@
/** biome-ignore-all lint/complexity/noBannedTypes: {} is the "empty props" type in React */
import { Callable, type Node, type NodePathMap } from "godot"
import * as React from "react"
import * as Reconciler from "./Reconciler.js"
const ConcurrentRoot = 1
export const renderComponent: {
(
container: Node<NodePathMap>,
component: React.FC<{}>,
): void
<P>(
container: Node<NodePathMap>,
component: React.FC<P>,
props: NoInfer<P>,
): void
} = (
container: Node<NodePathMap>,
component: React.FC<{}>,
props?: Record<string, unknown>,
): void => {
if (!(container as any)._reactReconciler)
(container as any)._reactReconciler = Reconciler.make()
if (!(container as any)._reactContainer) {
(container as any)._reactContainer = (container as any)._reactReconciler.createContainer(
container,
ConcurrentRoot,
null,
false,
false,
"",
console.error,
)
const cleanup = Callable.create(container, function(this) {
(container as any)._reactReconciler.updateContainer(
null,
(container as any)._reactContainer,
null,
)
delete (container as any)._reactReconciler
delete (container as any)._reactContainer
container.tree_exiting.disconnect(cleanup)
})
container.tree_exiting.connect(cleanup)
}
(container as any)._reactReconciler.updateContainer(
React.createElement(component, props),
(container as any)._reactContainer,
null,
)
}

View File

@@ -0,0 +1,5 @@
export * as Class from "./Class.js"
export * as Component from "./Component.js"
export * as JSX from "./JSX.js"
export * as Reconciler from "./Reconciler.js"
export * as Renderer from "./Renderer.js"

View File

@@ -0,0 +1,18 @@
export type PascalToCamel<S extends string> = S extends `${infer F}${infer R}` ? `${Lowercase<F>}${R}` : S
export const isRecordOrArray = (input: unknown): input is { [x: PropertyKey]: unknown } =>
typeof input === "object" && input !== null
// biome-ignore lint/complexity/noBannedTypes: it's completely fine
export const isFunction = (input: unknown): input is Function => typeof input === "function"
export const isObject = (input: unknown): input is object => isRecordOrArray(input) || isFunction(input)
export const hasProperty = <P extends PropertyKey>(self: unknown, property: P): self is { [K in P]: unknown } =>
isObject(self) && (property in self)
export const camelToSnake = (self: string): string => self.replace(/([A-Z])/g, "_$1").toLowerCase()
export const snakeToPascal = (self: string): string => {
let str = self[0].toUpperCase()
for (let i = 1; i < self.length; i++) {
str += self[i] === "_" ? self[++i].toUpperCase() : self[i]
}
return str
}

View File

@@ -1,7 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
// Enable latest features // Enable latest features
"lib": ["ESNext", "DOM"], "lib": ["ESNext"],
"target": "ESNext", "target": "ESNext",
"module": "NodeNext", "module": "NodeNext",
"moduleDetection": "force", "moduleDetection": "force",
@@ -13,6 +13,7 @@
// "allowImportingTsExtensions": true, // "allowImportingTsExtensions": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
// "noEmit": true, // "noEmit": true,
"typeRoots": ["./node_modules/@types", "./typings"],
// Best practices // Best practices
"strict": true, "strict": true,
@@ -27,12 +28,8 @@
// Build // Build
"outDir": "./dist", "outDir": "./dist",
"declaration": true, "declaration": true,
"sourceMap": true, "sourceMap": true
"plugins": [
{ "name": "@effect/language-service" }
]
}, },
"include": ["./src"] "include": ["./src", "./typings"]
} }

View File

@@ -0,0 +1,5 @@
declare module "godot" {
interface ResourceTypes {
"res://biome.json": JSON;
}
}

View File

@@ -0,0 +1,368 @@
declare module "godot-jsb" {
import {
Callable,
MethodFlags,
MultiplayerAPI,
MultiplayerPeer,
Object as GObject,
PackedByteArray,
PropertyInfo,
Signal,
StringName,
Variant,
} from "godot";
const CAMEL_CASE_BINDINGS_ENABLED: boolean;
const DEV_ENABLED: boolean;
const TOOLS_ENABLED: boolean;
/** version of GodotJS */
const version: string;
/** impl currently used */
const impl: string;
/**
* Create godot Callable without a bound object.
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
*/
function callable<F extends Function>(fn: F): Callable<F>;
/**
* Create godot Callable with a bound object `self`.
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
*/
function callable<S extends GObject, F extends (this: S, ...args: any[]) => any>(self: S, fn: F): Callable<F>;
/**
* Explicitly convert a `PackedByteArray`(aka `Vector<uint8_t>`) into a javascript `ArrayBuffer`
* @deprecated [WARNING] This free function '_to_array_buffer' is deprecated and will be removed in a future version, use 'PackedByteArray.to_array_buffer()' instead.
*/
function to_array_buffer(packed: PackedByteArray): ArrayBuffer;
type AsyncModuleSourceLoaderResolveFunc = (source: string) => void;
type AsyncModuleSourceLoaderRejectFunc = (error: string) => void;
/**
* Set a callback function to handle the load of source code of asynchronous modules.
* Only use this function if it's not set in C++.
*/
function set_async_module_loader(
fn: (
module_id: string,
resolve: AsyncModuleSourceLoaderResolveFunc,
reject: AsyncModuleSourceLoaderRejectFunc,
) => void,
): void;
interface MinimalCommonJSModule {
exports: any;
loaded: boolean;
id: string;
}
/**
* Import a CommonJS module asynchronously.
*
* NOTE: Only the source code is loaded asynchronously, the module is still evaluated on the script thread.
* NOTE: Calling the $import() function without a async module loader set in advance will return undefined.
* @param module_id the module id to import
* @example
* ```js
* // [init.js]
* import * as jsb from "godot-jsb";
* jsb.set_async_module_loader((id, resolve, reject) => {
* console.log("[test] async module loader start", id);
* // here should be the actual async loading of the module, HTTP request, etc.
* // we just simulate it with a timeout
* setTimeout(() => {
* console.log("[test] async module loader resolve", id);
* resolve("exports.foo = function () { console.log('hello, module imported'); }");
* }, 3000);
* });
* // [somescript.js]
* jsb.$import("http://localhost/async_loaded.js").then(mod => {
* console.log("[test] async module loader", mod);
* mod.exports.foo();
* });
* ```
*/
function $import(module_id: string): Promise<MinimalCommonJSModule>;
interface ScriptPropertyInfo {
name: string;
type: Variant.Type;
class_?: Function;
hint?: number;
hint_string?: string;
usage?: number;
cache?: boolean;
}
export namespace internal {
type OnReadyEvaluatorFunc = (self: any) => any;
type GObjectConstructor = abstract new (...args: any[]) => GObject;
function add_script_signal(prototype: GObject, name: string): void;
function add_script_property(prototype: GObject, details: ScriptPropertyInfo): void;
function add_script_ready(
prototype: GObject,
details: {
name: string;
evaluator: string | OnReadyEvaluatorFunc;
},
): void;
function add_script_tool(constructor: GObjectConstructor): void;
function add_script_icon(constructor: GObjectConstructor, path: string): void;
function add_script_rpc(
prototype: GObject,
property_key: string,
config: {
rpc_mode?: MultiplayerAPI.RPCMode;
call_local?: boolean;
transfer_mode?: MultiplayerPeer.TransferMode;
channel?: number;
},
): void;
function create_script_signal_getter(name: string): (this: GObject) => Signal;
function create_script_cached_property_updater(name: string): (this: GObject, value?: unknown) => void;
// 0: deprecated, 1: experimental, 2: help
function set_script_doc(
target: GObjectConstructor,
property_key: undefined,
field: 0 | 1 | 2,
message: string,
): void;
function set_script_doc(target: GObject, property_key: string, field: 0 | 1 | 2, message: string): void;
function add_module(id: string, obj: any): void;
function find_module(id: string): any;
function notify_microtasks_run(): void;
namespace names {
/**
* Get the transformed name of a Godot class
*/
function get_class<T extends string>(godot_class: T): T;
/**
* Get the transformed name of a Godot enum
*/
function get_enum<T extends string>(godot_enum: T): T;
/**
* Get the transformed name of a Godot enum
*/
function get_enum_value<T extends string>(godot_enum_value: T): T;
/**
* Get the transformed name of a Godot class member
*/
function get_member<T extends string>(godot_member: T): T;
/**
* Get the internal Godot name/identifier from a transformed name i.e. the inverse of the other accessors.
*/
function get_internal_mapping(name: string): string;
/**
* Get the transformed name of a Godot function parameter
*/
function get_parameter<T extends string>(parameter: T): T;
/**
* Get the transformed type name of a Variant.Type
*/
function get_variant_type<T extends string>(type: Variant.Type): StringName;
}
}
namespace editor {
interface PrimitiveConstantInfo {
name: string;
type: Variant.Type;
value: number /* only if type is literal */;
}
interface ConstantInfo {
name: string;
value: number /** int64_t */;
}
interface EnumInfo {
name: string;
literals: Record<string, number>;
is_bitfield: boolean;
}
interface DefaultArgumentInfo {
type: Variant.Type;
value: any;
}
// we treat godot MethodInfo/MethodBind as the same thing here for simplicity
//NOTE some fields will not be set if it's actually a MethodInfo struct
interface MethodBind {
internal_name: string;
id: number;
name: string;
hint_flags: MethodFlags;
is_static: boolean;
is_const: boolean;
is_vararg: boolean;
argument_count: number /** int32_t */;
args_: Array<PropertyInfo>;
default_arguments?: Array<DefaultArgumentInfo>;
return_: PropertyInfo | undefined;
}
interface PropertySetGetInfo {
internal_name: string;
name: string;
type: Variant.Type;
index: number;
setter: string;
getter: string;
info: PropertyInfo;
}
interface PrimitiveGetSetInfo {
name: string;
type: Variant.Type;
}
interface SignalInfo {
internal_name: string;
name: string;
method_: MethodBind;
}
interface ArgumentInfo {
name: string;
type: Variant.Type;
}
interface ConstructorInfo {
arguments: Array<ArgumentInfo>;
}
interface OperatorInfo {
name: string;
return_type: Variant.Type;
left_type: Variant.Type;
right_type: Variant.Type;
}
interface BasicClassInfo {
name: string;
methods: Array<MethodBind>;
enums?: Array<EnumInfo>;
}
// godot class
interface ClassInfo extends BasicClassInfo {
internal_name: string;
super: string;
properties: Array<PropertySetGetInfo>;
virtual_methods: Array<MethodBind>;
signals: Array<SignalInfo>;
constants?: Array<ConstantInfo>;
}
// variant class
interface PrimitiveClassInfo extends BasicClassInfo {
// self type
type: Variant.Type;
// valid only if has_indexing
element_type?: Variant.Type;
// true only if is_keyed
is_keyed: boolean;
constructors?: Array<ConstructorInfo>;
operators?: Array<OperatorInfo>;
properties?: Array<PrimitiveGetSetInfo>;
constants?: Array<PrimitiveConstantInfo>;
}
interface SingletonInfo {
name: string;
class_name: string;
user_created: boolean;
editor_only: boolean;
}
interface GlobalConstantInfo {
name: string;
values: { [name: string]: number /** int64_t */ };
}
interface ClassDoc {
brief_description: string;
constants: { [name: string]: { description: string } };
methods: { [name: string]: { description: string } };
properties: { [name: string]: { description: string } };
signals: { [name: string]: { description: string } };
}
function get_class_doc(class_name: string): ClassDoc | undefined;
/**
* get a list of all classes registered in ClassDB
*/
function get_classes(): Array<ClassInfo>;
function get_primitive_types(): Array<PrimitiveClassInfo>;
function get_singletons(): Array<SingletonInfo>;
function get_global_constants(): Array<GlobalConstantInfo>;
function get_utility_functions(): Array<MethodBind>;
function get_input_actions(): Array<string>;
function delete_file(filepath: string): void;
const VERSION_DOCS_URL: string;
}
}
// Globals
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */
interface Console {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/assert_static) */
assert(condition?: boolean, ...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug_static) */
debug(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static) */
error(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info_static) */
info(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) */
log(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time_static) */
time(label?: string): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd_static) */
timeEnd(label?: string): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace_static) */
trace(...data: any[]): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn_static) */
warn(...data: any[]): void;
}
declare const console: Console;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearInterval) */
declare function clearInterval(id: number | undefined): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearTimeout) */
declare function clearTimeout(id: number | undefined): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setInterval) */
declare function setInterval(handler: () => void, timeout?: number, ...arguments: any[]): number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout) */
declare function setTimeout(handler: () => void, timeout?: number, ...arguments: any[]): number;

View File

@@ -0,0 +1,418 @@
declare module "godot" {
const IntegerType: unique symbol;
const FloatType: unique symbol;
/**
* Proxy objects are typically transparent by design, allowing a proxy to impersonate a type. However, GodotJS also
* makes use of proxies to wrap existing objects in order to provide a more convenient API. In such cases, it is
* convenient to be able to unwrap the object i.e. obtain access to the target object. In order to achieve this,
* GodotJS exposes a property with the key ProxyTarget. You can access this to, for example, obtain direct access
* to the original GDictionary wrapped via a call to .proxy(). Additionally, GodotJS uses this property internally
* to unwrap proxies, thus allowing you to pass a proxy wrapped GArray/GDictionary as an argument to any function
* expecting a GArray/GDictionary parameter.
*/
const ProxyTarget: unique symbol;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable/Callable<T>.
*/
type AnyCallable = Callable;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal/Signal<T>.
*/
type AnySignal = Signal;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable0<R = void> = Callable<() => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable1<T1, R = void> = Callable<(v1: T1) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable2<T1, T2, R = void> = Callable<(v1: T1, v2: T2) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable3<T1, T2, T3, R = void> = Callable<(v1: T1, v2: T2, v3: T3) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable4<T1, T2, T3, T4, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Callable<T>.
*/
type Callable5<T1, T2, T3, T4, T5, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => R>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal0 = Signal<() => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal1<T1> = Signal<(v1: T1) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal2<T1, T2> = Signal<(v1: T1, v2: T2) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal3<T1, T2, T3> = Signal<(v1: T1, v2: T2, v3: T3) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal4<T1, T2, T3, T4> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4) => void>;
/**
* FOR BACKWARD COMPATIBILITY ONLY
* @deprecated [WARNING] Use Signal<T>.
*/
type Signal5<T1, T2, T3, T4, T5> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => void>;
type ExtractValueKeys<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
type UndefinedToNull<T> = T extends undefined ? null : T;
// A bit convoluted, but written this way to mitigate type definitions circularly depending on themselves.
type GodotNames<T> = "__godotNameMap" extends keyof T
? keyof T["__godotNameMap"] | Exclude<keyof T, T["__godotNameMap"][keyof T["__godotNameMap"]]>
: keyof T;
type ResolveGodotName<T, Name> = Name extends keyof T
? Name
: "__godotNameMap" extends keyof T
? Name extends keyof T["__godotNameMap"]
? T["__godotNameMap"][Name]
: never
: never;
type ResolveGodotNameValue<T, Name> = Name extends keyof T
? T[Name]
: "__godotNameMap" extends keyof T
? Name extends keyof T["__godotNameMap"]
? T["__godotNameMap"][Name] extends keyof T
? T[T["__godotNameMap"][Name]]
: never
: never
: never;
type ResolveGodotNameParameters<T, Name> = Name extends GodotDynamicDispatchName
? GAny[]
: ResolveGodotName<T, Name> extends keyof T
? T[ResolveGodotName<T, Name>] extends {
bivarianceHack(...args: infer P extends GAny[]): void | GAny;
}["bivarianceHack"]
? P
: never
: never;
type ResolveGodotReturnType<T, Name> = Name extends GodotDynamicDispatchName
? void | GAny
: ResolveGodotName<T, Name> extends keyof T
? T[ResolveGodotName<T, Name>] extends (...args: any[]) => infer R
? R
: never
: never;
/**
* Godot has many APIs that are a form of dynamic dispatch, i.e., they take the name of a function or property and
* then operate on the value matching the name. TypeScript is powerful enough to allow us to type these APIs.
* However, since these APIs can be used to call each other, the type checker can get hung up trying to infinitely
* recurse on these types. What follows is an interface with the built-in dynamic dispatch names. GodotJS' types
* will not recurse through methods matching these names. If you want to build your own dynamic dispatch APIs, you
* can use interface merging to insert additional method names.
*/
interface GodotDynamicDispatchNames {
call: "call";
callv: "callv";
call_deferred: "call_deferred";
add_do_method: "add_do_method";
add_undo_method: "add_undo_method";
}
type GodotDynamicDispatchName = GodotDynamicDispatchNames[keyof GodotDynamicDispatchNames];
/**
* This namespace and the values within do not exist at runtime. They're declared here, for internal use only, as a
* work-around for limitations of TypeScript's type system.
*/
namespace __PathMappableDummyKeys {}
type PathMappable<DummyKey extends symbol, Map extends PathMap = PathMap> = {
[K in DummyKey]: Map;
};
type PathMap<T = unknown> = Record<string, T>;
type StaticPath<
Map extends PathMap,
Permitted = any,
DefaultKey extends string = never,
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
> = IfAny<
Map,
string,
| (ExtractValueKeys<Map, Permitted> & string)
| (DummyKey extends any
?
| (Map[DefaultKey] extends never
? never
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
? StaticPath<ChildMap, Permitted, DefaultKey>
: never)
| {
[K in Exclude<keyof Map, DefaultKey> & string]: Map[K] extends PathMappable<
DummyKey,
infer ChildMap
>
? `${K}/${StaticPath<ChildMap, Permitted, DefaultKey>}`
: never;
}[Exclude<keyof Map, DefaultKey> & string]
: never)
>;
type ResolvePath<
Map extends PathMap,
Path extends string,
Default,
Permitted,
DefaultKey extends string = never,
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
> = IfAny<
Map,
Permitted,
DummyKey extends any
? Path extends keyof Map
? [Map[Path]] extends [Permitted]
? [undefined] extends [Map[Path]]
? null | Exclude<Map[Path], undefined>
: Map[Path]
: Default
: Path extends `${infer Key extends Exclude<keyof Map, DefaultKey> & string}/${infer SubPath}`
? Map[Key] extends PathMappable<DummyKey, infer ChildMap>
? ResolvePath<ChildMap, SubPath, Default, Permitted>
: Default
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
? ResolvePath<ChildMap, Path, Default, Permitted>
: never
: never
>;
type PathMapChild<Map extends NodePathMap, Permitted, Default> = IfAny<
Map,
Permitted,
Map[keyof Map] extends undefined | Permitted ? Exclude<Map[keyof Map], undefined> : Default
>;
type NodePathMap = PathMap<undefined | Node>;
type StaticNodePath<Map extends NodePathMap, Permitted = Node> = StaticPath<
Map,
Permitted,
never,
typeof __PathMappableDummyKeys.Node
>;
type ResolveNodePath<Map extends NodePathMap, Path extends string, Default = never, Permitted = Node> = ResolvePath<
Map,
Path,
Default,
Permitted,
never,
typeof __PathMappableDummyKeys.Node
>;
type ResolveNodePathMap<Map extends NodePathMap, Path extends string, Default = never> = Path extends keyof Map
? Map[Path] extends Node<infer ChildMap>
? ChildMap
: Default
: Path extends `${infer Key extends keyof Map & string}/${infer SubPath}`
? Map[Key] extends Node<infer ChildMap>
? ResolveNodePathMap<ChildMap, SubPath, Default>
: Default
: Default;
type NodePathMapChild<Map extends NodePathMap> = PathMapChild<Map, Node, Node>;
type AnimationMixerPathMap = PathMap<AnimationLibrary>;
type StaticAnimationMixerPath<Map extends AnimationMixerPathMap> = StaticPath<
Map,
Animation,
"",
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
>;
type ResolveAnimationMixerPath<
Map extends AnimationMixerPathMap,
Path extends string,
Default = never,
> = ResolvePath<
Map,
Path,
Default,
Animation,
"",
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
>;
type GArrayElement<T extends GAny | GAny[], I extends int64 = int64> = T extends any[] ? T[I] : T;
/**
* GArray elements are exposed with a subset of JavaScript's standard Array API. Array indexes are exposed as
* enumerable properties, thus if you want to perform more complex operations you can convert to a regular
* JavaScript array with [...g_array.proxy()].
*/
class GArrayProxy<T> {
[Symbol.iterator](): IteratorObject<GProxyValueWrap<T>>;
/**
* Gets the length of the array. This is a number one higher than the highest index in the array.
*/
get length(): number;
/**
* Performs the specified action for each element in an array.
* @param callback A function that accepts up to three arguments. forEach calls the callback function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callback function. If thisArg is omitted, undefined is used as the this value.
*/
forEach<S = GArrayProxy<T>>(
callback: (this: GArrayProxy<T>, value: GProxyValueWrap<T>, index: number) => void,
thisArg?: S,
): void;
/**
* Removes the last element from an array and returns it.
* If the array is empty, undefined is returned and the array is not modified.
*/
pop(): GProxyValueWrap<T> | undefined;
/**
* Appends new elements to the end of an array, and returns the new length of the array.
* @param item New element to add to the array.
* @param additionalItems Additional new elements to add to the array.
*/
push(item: T | GProxyValueWrap<T>, ...additionalItems: Array<T | GProxyValueWrap<T>>): number;
/**
* Returns the index of the first occurrence of a value in an array, or -1 if it is not present.
* @param searchElement The value to locate in the array.
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
*/
indexOf(searchElement: T | GProxyValueWrap<T>, fromIndex?: number): number;
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
*/
includes(searchElement: T | GProxyValueWrap<T>): boolean;
toJSON(key?: any): any;
toString(): string;
[n: number]: T | GProxyValueWrap<T>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
}
// Ideally this would be a class, but TS currently doesn't provide a way to type a class with mapped properties.
/**
* GObject entries are exposed as enumerable properties, so Object.keys(), GObject.entries() etc. will work.
*/
type GDictionaryProxy<T> = {
[K in keyof T]: T[K] | GProxyValueWrap<T[K]>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
};
type GProxyValueWrap<V> =
V extends GArray<infer T>
? GArrayProxy<GArrayElement<T>>
: V extends GDictionary<infer T>
? GDictionaryProxy<T>
: V;
type GProxyValueUnwrap<V> = V extends GArrayProxy<infer E> ? E : V extends GDictionaryProxy<infer T> ? T : V;
type GWrappableValue = GAny | GWrappableValue[] | { [key: number | string]: GWrappableValue };
type GValueWrapUnchecked<V> = V extends any[]
? number extends V["length"]
? GArray<GValueWrapUnchecked<V[number]>>
: GArray<{ [I in keyof V]: GValueWrapUnchecked<V[I]> }>
: V extends GAny
? V
: GDictionary<{ [K in keyof V]: GValueWrapUnchecked<V[K]> }>;
type GValueWrap<V> = [keyof V] extends [never]
? GDictionary<{}>
: [V] extends [GWrappableValue]
? GValueWrapUnchecked<V>
: never;
type GValueUnwrap<V> =
V extends GArray<infer T>
? T extends any[]
? { [I in keyof T]: GValueUnwrap<T[I]> }
: Array<GValueUnwrap<T>>
: V extends GDictionary<infer T>
? { [K in keyof T]: GValueUnwrap<T[K]> }
: V;
/**
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
* @see GReadProxyValueWrap
*/
type GArrayReadProxy<T> = Omit<GArrayProxy<T>, "forEach"> & {
[Symbol.iterator](): IteratorObject<GReadProxyValueWrap<T>>;
forEach<S = GArrayReadProxy<T>>(
callback: (this: GArrayReadProxy<T>, value: GReadProxyValueWrap<T>, index: number) => void,
thisArg?: S,
): void;
[n: number]: GReadProxyValueWrap<T>;
};
/**
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
* @see GReadProxyValueWrap
*/
type GDictionaryReadProxy<T> = {
[K in keyof T]: GReadProxyValueWrap<T[K]>;
};
// At runtime we only have the one kind of dictionary proxy and one kind of array proxy. The read interfaces have
// indexers typed correctly for access i.e. return proxied types. The non-read interfaces have indexers accurate for
// assignment and will accept both GArray/GDictionary and proxies. The read interfaces exist for convenience only,
// you can safely cast between the two interfaces types as desired.
type GReadProxyValueWrap<V> =
V extends GArray<infer E> ? GArrayReadProxy<E> : V extends GDictionary<infer T> ? GDictionaryReadProxy<T> : V;
interface PropertyInfo {
name: string;
type: Variant.Type;
class_name: string;
hint: PropertyHint;
hint_string: string;
usage: PropertyUsageFlags;
}
type BindRight<F extends Function, B extends any[]> = F extends (
this: infer T,
...args: [...infer A, ...B]
) => infer R
? (this: T, ...args: A) => R
: never;
}

View File

@@ -0,0 +1,39 @@
declare module "godot.worker" {
import { GAny, GArray, Object as GObject } from "godot";
class JSWorker {
constructor(path: string);
postMessage(message: any, transfer?: GArray | ReadonlyArray<NonNullable<GAny>>): void;
terminate(): void;
onready?: () => void;
onmessage?: (message: any) => void;
//TODO not implemented yet
onerror?: (error: any) => void;
/**
* @deprecated Use onmessage to receive messages sent from postMessage() with transfers included.
* @param obj
*/
ontransfer?: (obj: GObject) => void;
}
// only available in worker scripts
const JSWorkerParent:
| {
onmessage?: (message: any) => void;
close(): void;
/**
* @deprecated Use the transfer parameter of postMessage instead.
* @param obj
*/
transfer(obj: GObject): void;
postMessage(message: any, transfer?: GArray | ReadonlyArray<NonNullable<GAny>>): void;
}
| undefined;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
declare module "jsb.editor.codegen" {
import type { ExtractValueKeys, GArray, GDictionary, Node, PropertyInfo, Resource, ResourceTypes, Script } from "godot";
import type * as GodotJsb from "godot-jsb";
export enum DescriptorType {
Godot = 0,
User = 1,
FunctionLiteral = 2,
ObjectLiteral = 3,
StringLiteral = 4,
NumericLiteral = 5,
BooleanLiteral = 6,
Union = 7,
Intersection = 8,
Conditional = 9,
Tuple = 10,
Infer = 11,
Mapped = 12,
Indexed = 13
}
/**
* Reference to a built-in type, either declared in the 'godot' namespace, or available as part of the standard library.
*/
export type GodotTypeDescriptor = GDictionary<{
type: DescriptorType.Godot;
name: string;
/**
* Generic arguments.
*/
arguments?: GArray<TypeDescriptor>;
}>;
/**
* Reference to a user defined type. A path must be specified so that the generated code is able to import the file
* where the type is declared/exported.
*/
export type UserTypeDescriptor = GDictionary<{
type: DescriptorType.User;
/**
* res:// style path to the TypeScript module where this type is exported.
*/
resource: ExtractValueKeys<ResourceTypes, Script>;
/**
* Preferred type name to use when importing.
*/
name: string;
/**
* Named module export that is being imported. When omitted, the default export is imported.
*/
export?: string;
/**
* Generic arguments.
*/
arguments?: GArray<TypeDescriptor>;
}>;
export type GenericParameterDescriptor = GDictionary<{
name: string;
extends?: TypeDescriptor;
default?: TypeDescriptor;
}>;
export type ParameterDescriptor = GDictionary<{
name: string;
type: TypeDescriptor;
optional?: boolean;
}>;
export type FunctionLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.FunctionLiteral;
generics?: GArray<GenericParameterDescriptor>;
parameters?: GArray<ParameterDescriptor>;
returns?: TypeDescriptor;
}>;
export type OptionalTypeDescriptor<Descriptor extends GDictionary> = Descriptor extends GDictionary<infer T> ? GDictionary<T & {
optional?: boolean;
}> : never;
export type ObjectLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.ObjectLiteral;
properties?: GDictionary<Partial<Record<string, OptionalTypeDescriptor<TypeDescriptor>>>>;
index?: GDictionary<{
key: TypeDescriptor;
value: TypeDescriptor;
}>;
}>;
export type StringLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.StringLiteral;
value: string;
template?: boolean;
}>;
export type NumberLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.NumericLiteral;
value: number;
}>;
export type BooleanLiteralTypeDescriptor = GDictionary<{
type: DescriptorType.BooleanLiteral;
value: boolean;
}>;
export type TupleElementDescriptor = GDictionary<{
name?: string;
type: TypeDescriptor;
}>;
export type TupleTypeDescriptor = GDictionary<{
type: DescriptorType.Tuple;
elements: GArray<TupleElementDescriptor>;
}>;
export type UnionTypeDescriptor = GDictionary<{
type: DescriptorType.Union;
types: GArray<TypeDescriptor>;
}>;
export type IntersectionTypeDescriptor = GDictionary<{
type: DescriptorType.Intersection;
types: GArray<TypeDescriptor>;
}>;
export type InferTypeDescriptor = GDictionary<{
type: DescriptorType.Infer;
name: string;
}>;
export type ConditionalTypeDescriptor = GDictionary<{
type: DescriptorType.Conditional;
check: TypeDescriptor;
extends: TypeDescriptor;
true: TypeDescriptor;
false: TypeDescriptor;
}>;
export type MappedTypeDescriptor = GDictionary<{
type: DescriptorType.Mapped;
key: string;
in: TypeDescriptor;
as?: TypeDescriptor;
value: TypeDescriptor;
}>;
export type IndexedTypeDescriptor = GDictionary<{
type: DescriptorType.Indexed;
base: TypeDescriptor;
index: TypeDescriptor;
}>;
export type TypeDescriptor = GodotTypeDescriptor | UserTypeDescriptor | FunctionLiteralTypeDescriptor | ObjectLiteralTypeDescriptor | StringLiteralTypeDescriptor | NumberLiteralTypeDescriptor | BooleanLiteralTypeDescriptor | TupleTypeDescriptor | UnionTypeDescriptor | IntersectionTypeDescriptor | InferTypeDescriptor | ConditionalTypeDescriptor | MappedTypeDescriptor | IndexedTypeDescriptor;
/**
* Codegen analogue of NodePathMap.
*/
export type NodeTypeDescriptorPathMap = GDictionary<Partial<Record<string, TypeDescriptor>>>;
export enum CodeGenType {
ScriptNodeTypeDescriptor = 0,
ScriptResourceTypeDescriptor = 1
}
/**
* Handle a NodeTypeDescriptorCodeGenRequest to overwrite the generated type for nodes using this script.
*/
export type ScriptNodeTypeDescriptorCodeGenRequest = GDictionary<{
type: CodeGenType.ScriptNodeTypeDescriptor;
node: Node;
children: NodeTypeDescriptorPathMap;
}>;
/**
* Handle a ScriptResourceTypeDescriptorCodeGenRequest to overwrite the generated type for resources using this script.
*/
export type ScriptResourceTypeDescriptorCodeGenRequest = GDictionary<{
type: CodeGenType.ScriptResourceTypeDescriptor;
resource: Resource;
}>;
export type CodeGenRequest = ScriptNodeTypeDescriptorCodeGenRequest | ScriptResourceTypeDescriptorCodeGenRequest;
/**
* You can manipulate GodotJS' codegen by exporting a function from your script/module called `codegen`.
*/
export type CodeGenHandler = (request: CodeGenRequest) => undefined | TypeDescriptor;
export class TypeDB {
singletons: {
[name: string]: GodotJsb.editor.SingletonInfo;
};
classes: {
[name: string]: GodotJsb.editor.ClassInfo;
};
primitive_types: {
[name: string]: GodotJsb.editor.PrimitiveClassInfo;
};
globals: {
[name: string]: GodotJsb.editor.GlobalConstantInfo;
};
utilities: {
[name: string]: GodotJsb.editor.MethodBind;
};
class_docs: {
[name: string]: GodotJsb.editor.ClassDoc | false;
};
constructor();
find_doc(class_name: string): GodotJsb.editor.ClassDoc | undefined;
is_primitive_type(name: string): boolean;
is_valid_method_name(name: string): boolean;
make_classname(class_name: string, internal?: boolean): string;
make_typename(info: PropertyInfo, used_as_input: boolean, non_nullable: boolean): string;
make_arg(info: PropertyInfo, optional?: boolean): string;
make_literal_value(value: GodotJsb.editor.DefaultArgumentInfo): string;
make_arg_default_value(method_info: GodotJsb.editor.MethodBind, index: number): string;
make_args(method_info: GodotJsb.editor.MethodBind): string;
make_return(method_info: GodotJsb.editor.MethodBind): string;
make_signal_type(method_info: GodotJsb.editor.MethodBind): string;
}
export class TSDCodeGen {
private _split_index;
private _out_dir;
private _splitter;
private _types;
private _use_project_settings;
constructor(outDir: string, use_project_settings: boolean);
private make_path;
private new_splitter;
private split;
private cleanup;
has_class(name?: string): boolean;
emit(): Promise<void>;
private emit_utility;
private emit_global;
private emit_aliases;
private emit_singleton;
private emit_godot_primitive;
private emit_godot_class;
}
export class SceneTSDCodeGen {
private _out_dir;
private _scene_paths;
private _types;
constructor(out_dir: string, scene_paths: string[]);
private make_scene_path;
emit(): Promise<void>;
private emit_children_node_types;
private emit_scene_node_types;
}
export class ResourceTSDCodeGen {
private _out_dir;
private _resource_paths;
private _types;
constructor(out_dir: string, resource_paths: string[]);
private make_resource_path;
emit(): Promise<void>;
private emit_resource_type;
}
}
declare module "jsb.editor.main" {
import { PackedStringArray } from "godot";
export function auto_complete(pattern: string): PackedStringArray;
export function run_npm_install(): void;
}

View File

@@ -0,0 +1,209 @@
declare module "godot.lib.api" {
import type * as Godot from "godot";
import type * as GodotJsb from "godot-jsb";
function proxy_unwrap_value<T>(value: T): T;
function proxy_wrap_value<T>(value: T): T;
function array_proxy<T extends any[]>(arr: T): T;
function object_proxy<T extends object>(obj: T, remap_properties?: boolean): T;
function key_only_proxy<T extends object | ((...args: any[]) => any)>(target: T): any;
function instance_proxy<T extends object>(target_instance: T): T;
function class_proxy<T extends object>(target_class: T): T;
function function_proxy<T extends (...args: any[]) => any>(fn: T): T;
function enum_proxy<T extends object>(target_enum: T): T;
const proxy: {
array_proxy: typeof array_proxy;
class_proxy: typeof class_proxy;
enum_proxy: typeof enum_proxy;
function_proxy: typeof function_proxy;
instance_proxy: typeof instance_proxy;
key_only_proxy: typeof key_only_proxy;
object_proxy: typeof object_proxy;
proxy_unwrap_value: typeof proxy_unwrap_value;
proxy_wrap_value: typeof proxy_wrap_value;
};
type GodotLibApi = typeof Godot & {
jsb: typeof GodotJsb;
proxy: typeof proxy;
};
const api: GodotLibApi;
/**
* This is a starting point for writing GodotJS code that is camel-case binding agnostic at runtime.
*
* Library code must consume this API rather than "godot", and be built with camel case bindings disabled. This is to
* ensure that the library will function at runtime for all projects irrespective of whether they have camel-case
* bindings enabled.
*/
export = api;
}
declare module "godot.annotations" {
import type * as Godot from "godot";
import type { ClassBinder, RPCConfig } from "godot.annotations";
type VariantConstructor = abstract new (...args: any[]) => NonNullable<Godot.GAny> | Number | String | Boolean;
type GObjectConstructor = abstract new (...args: any[]) => Godot.Object;
type ClassSpecifier = VariantConstructor | Symbol | EnumPlaceholder | TypePairPlaceholder;
interface EnumPlaceholder {
target: Record<string, string | number>;
}
interface TypePairPlaceholder {
key: VariantConstructor;
value: VariantConstructor;
}
export function EnumType(type: Record<string, string | number>): EnumPlaceholder;
export function TypePair(key: VariantConstructor, value: VariantConstructor): TypePairPlaceholder;
/** @deprecated Use createClassBinder() instead. */
export function signal(): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportSignal: typeof signal;
/** @deprecated Use createClassBinder() instead. */
export function export_multiline(): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportMultiline: typeof export_multiline;
/** @deprecated Use createClassBinder() instead. */
export function export_range(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportRange: typeof export_range;
/** @deprecated Use createClassBinder() instead. */
export function export_range_i(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportIntRange: typeof export_range_i;
/** String as a path to a file, custom filter provided as hint. */
/** @deprecated Use createClassBinder() instead. */
export function export_file(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportFile: typeof export_file;
/** @deprecated Use createClassBinder() instead. */
export function export_dir(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export function export_global_file(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportGlobalFile: typeof export_global_file;
/** @deprecated Use createClassBinder() instead. */
export function export_global_dir(filter: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportGlobalDir: typeof export_global_dir;
/** @deprecated Use createClassBinder() instead. */
export function export_exp_easing(hint?: "" | "attenuation" | "positive_only" | "attenuation,positive_only"): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportExpEasing: typeof export_exp_easing;
/**
* A Shortcut for `export_(Variant.Type.TYPE_ARRAY, { class_: clazz })`
*/
/** @deprecated Use createClassBinder() instead. */
export function export_array(clazz: ClassSpecifier): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportArray: typeof export_array;
/**
* A Shortcut for exporting a dictionary { class_: [key_class, value_class] })`
*/
/** @deprecated Use createClassBinder() instead. */
export function export_dictionary(key_class: VariantConstructor, value_class: VariantConstructor): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportDictionary: typeof export_dictionary;
/** @deprecated Use createClassBinder() instead. */
export function export_object(clazz: GObjectConstructor): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportObject: typeof export_object;
/**
* [low level export]
* @deprecated Use createClassBinder() instead.
* */
export function export_(type: Godot.Variant.Type, details?: {
class_?: ClassSpecifier;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export function Export(type: Godot.Variant.Type, details?: {
class?: ClassSpecifier;
hint?: Godot.PropertyHint;
hintString?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/**
* In Godot, class members can be exported.
* This means their value gets saved along with the resource (such as the scene) they're attached to.
* They will also be available for editing in the property editor.
* Exporting is done by using the `@export_var` (or `@export_`) annotation.
*/
/** @deprecated Use createClassBinder() instead. */
export function export_var(type: Godot.Variant.Type, details?: {
class_?: ClassSpecifier;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportVar: typeof export_var;
/**
* NOTE only int value enums are allowed
*/
/** @deprecated Use createClassBinder() instead. */
export function export_enum(enum_type: Record<string, string | number>): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportEnum: typeof export_enum;
/**
* NOTE only int value enums are allowed
*/
/** @deprecated Use createClassBinder() instead. */
export function export_flags(enum_type: Record<string, string | number>): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const ExportFlags: typeof export_flags;
/** @deprecated Use createClassBinder() instead. */
export function rpc(config?: RPCConfig): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Rpc: typeof rpc;
/**
* auto initialized on ready (before _ready called)
*
* @deprecated Use createClassBinder() instead.
*/
export function onready(evaluator: string): (target: any, name: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const OnReady: typeof onready;
/** @deprecated Use createClassBinder() instead. */
export function tool(): (target: any, name: undefined) => void;
/** @deprecated Use createClassBinder() instead. */
export const Tool: typeof tool;
/** @deprecated Use createClassBinder() instead. */
export function icon(path: string): (target: any, name: undefined) => void;
/** @deprecated Use createClassBinder() instead. */
export const Icon: typeof icon;
/** @deprecated Use createClassBinder() instead. */
export function deprecated(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Deprecated: typeof deprecated;
/** @deprecated Use createClassBinder() instead. */
export function experimental(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Experimental: typeof experimental;
/** @deprecated Use createClassBinder() instead. */
export function help(message?: string): (target: any, name?: string) => void;
/** @deprecated Use createClassBinder() instead. */
export const Help: typeof help;
export type ClassMemberDecorator<RestrictedContext extends ClassMemberDecoratorContext = ClassMemberDecoratorContext> = <Context extends RestrictedContext>(target: ClassMemberDecoratorTarget<Context>, context: Context) => void | ClassMemberDecoratorReturn<Context>;
export type ClassMemberDecoratorTarget<Context extends ClassMemberDecoratorContext> = Context extends ClassMethodDecoratorContext<infer _, infer Value> ? (...args: unknown[]) => Value : Context extends ClassGetterDecoratorContext<infer _, infer Value> ? () => Value : Context extends ClassSetterDecoratorContext<infer _, infer Value> ? (value: Value) => void : Context extends ClassFieldDecoratorContext ? undefined : Context extends ClassAccessorDecoratorContext<infer _, infer Value> ? {
get: () => Value;
set: (value: Value) => void;
} : never;
export type ClassMemberDecoratorReturn<Context extends ClassMemberDecoratorContext> = Context extends ClassMethodDecoratorContext<infer This, infer Value> ? (this: This, ...args: unknown[]) => Value : Context extends ClassGetterDecoratorContext<infer This, infer Value> ? (this: This) => Value : Context extends ClassSetterDecoratorContext<infer This, infer Value> ? (this: This, value: Value) => void : Context extends ClassFieldDecoratorContext<infer This, infer Value> ? (this: This, initialValue: Value) => Value : Context extends ClassAccessorDecoratorContext<infer This, infer Value> ? {
get?(this: This): Value;
set?(this: This, value: Value): void;
init?(this: This, initialValue: Value): Value;
} : never;
export type ClassDecorator<This extends abstract new (...args: any) => any = abstract new (...args: any) => any> = (target: This, context: ClassDecoratorContext<This>) => void;
export type ClassDecoratorClass<Context extends ClassDecoratorContext> = Context extends ClassDecoratorContext<infer Class> ? Class : never;
export type Decorator<RestrictedContext extends DecoratorContext = DecoratorContext> = RestrictedContext extends ClassDecoratorContext ? <Context extends RestrictedContext>(target: ClassDecoratorClass<Context>, context: Context) => void : RestrictedContext extends ClassMemberDecoratorContext ? <Context extends RestrictedContext>(target: ClassMemberDecoratorTarget<Context>, context: Context) => void | ClassMemberDecoratorReturn<Context> : never;
export type AnyDecorator = (value: unknown, context: DecoratorContext) => unknown;
export type ClassValueMemberDecoratorContext<This = unknown, Value = unknown> = ClassGetterDecoratorContext<This, Value> | ClassSetterDecoratorContext<This, Value> | ClassFieldDecoratorContext<This, Value> | ClassAccessorDecoratorContext<This, Value>;
export function createClassBinder(): ClassBinder;
}
declare module "godot.typeloader" {
/**
* @param type the loaded type or function in godot module
*/
export type TypeLoadedCallback = (type: any) => void;
export function on_type_loaded(type_name: string | string[], callback: TypeLoadedCallback): void;
}
declare module "jsb.core" { }
declare module "jsb.inject" { }

View File

@@ -0,0 +1,144 @@
declare module "godot.annotations" {
import * as Godot from "godot";
import * as GodotJsb from "godot-jsb";
type ClassBinder = (() =>
((
target: GObjectConstructor,
context: ClassDecoratorContext
) => void))
& {
tool: () =>
((
target: GObjectConstructor,
_context: ClassDecoratorContext
) => void);
icon: (path: string) =>
((
target: GObjectConstructor,
_context: ClassDecoratorContext
) => void);
export: ((
type: Godot.Variant.Type,
options?: ExportOptions
) => ClassMemberDecorator)
& {
multiline: () => ClassMemberDecorator;
range: (
min: number,
max: number,
step: number,
...extra_hints: string[]
) => ClassMemberDecorator;
range_int: (
min: number,
max: number,
step: number,
...extra_hints: string[]
) => ClassMemberDecorator;
file: (filter: string) => ClassMemberDecorator;
dir: (filter: string) => ClassMemberDecorator;
global_file: (filter: string) => ClassMemberDecorator;
global_dir: (filter: string) => ClassMemberDecorator;
exp_easing: (
hint?: ""
| "attenuation"
| "positive_only"
| "attenuation,positive_only"
) => ClassMemberDecorator;
array: (clazz: ClassSpecifier) => ClassMemberDecorator;
dictionary: (
key_class: VariantConstructor,
value_class: VariantConstructor
) => ClassMemberDecorator;
object: <
Constructor extends GObjectConstructor>(clazz: Constructor
) =>
ClassMemberDecorator<
ClassValueMemberDecoratorContext<
unknown,
null
| InstanceType<Constructor>
>
>;
"enum": (
enum_type: Record<
string,
string
| number
>
) => ClassMemberDecorator;
flags: (
enum_type: Record<
string,
string
| number
>
) => ClassMemberDecorator;
cache: () =>
ClassMemberDecorator<
ClassAccessorDecoratorContext<Godot.Object>
| ClassSetterDecoratorContext<Godot.Object>
>;
};
signal: () =>
(<
Context extends ClassAccessorDecoratorContext<
Godot.Object,
Godot.Signal
>
| ClassGetterDecoratorContext<
Godot.Object,
Godot.Signal
>
| ClassFieldDecoratorContext<
Godot.Object,
Godot.Signal
>>(
_target: unknown,
context: Context
) => ClassMemberDecoratorReturn<Context>);
rpc: (config?: RPCConfig) =>
((
_target: Function,
context: string
| ClassMethodDecoratorContext
) => void);
onready: (
evaluator: string
| GodotJsb.internal.OnReadyEvaluatorFunc
) =>
((
_target: undefined,
context: string
| ClassMethodDecoratorContext
) => void);
deprecated: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
experimental: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
help: (message?: string) =>
Decorator<
ClassDecoratorContext<GObjectConstructor>
| ClassValueMemberDecoratorContext<GObjectConstructor>
>;
}
type ExportOptions = {
"class"?: any;
hint?: Godot.PropertyHint;
hint_string?: string;
usage?: Godot.PropertyUsageFlags;
}
type RPCConfig = {
mode?: Godot.MultiplayerAPI.RPCMode;
sync?: "call_remote"
| "call_local";
transfer_mode?: Godot.MultiplayerPeer.TransferMode;
transfer_channel?: number;
}
}