@treenity/mods 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/board/board.test.ts +212 -0
  2. package/board/client.ts +1 -0
  3. package/board/seed.ts +26 -0
  4. package/board/server.ts +5 -0
  5. package/board/types.ts +87 -0
  6. package/board/view.tsx +574 -0
  7. package/brahman/CLAUDE.md +18 -0
  8. package/brahman/brahman.test.ts +855 -0
  9. package/brahman/client.ts +2 -0
  10. package/brahman/helpers.ts +374 -0
  11. package/brahman/server.ts +2 -0
  12. package/brahman/service.ts +328 -0
  13. package/brahman/types.ts +727 -0
  14. package/brahman/view.tsx +73 -0
  15. package/brahman/views/action-cards.tsx +615 -0
  16. package/brahman/views/bot-view.tsx +76 -0
  17. package/brahman/views/chat-editor.tsx +782 -0
  18. package/brahman/views/chat-preview.tsx +266 -0
  19. package/brahman/views/menu-editor.tsx +451 -0
  20. package/brahman/views/page-layout.tsx +285 -0
  21. package/brahman/views/tstring-input.tsx +84 -0
  22. package/cafe/CLAUDE.md +7 -0
  23. package/cafe/seed.ts +8 -0
  24. package/cafe/server.ts +2 -0
  25. package/cafe/types.ts +32 -0
  26. package/canary/seed.ts +8 -0
  27. package/canary/server.ts +3 -0
  28. package/canary/service.ts +101 -0
  29. package/canary/types.ts +16 -0
  30. package/dist/board/client.d.ts +2 -0
  31. package/dist/board/client.d.ts.map +1 -0
  32. package/dist/board/client.js +2 -0
  33. package/dist/board/client.js.map +1 -0
  34. package/dist/board/seed.d.ts +2 -0
  35. package/dist/board/seed.d.ts.map +1 -0
  36. package/dist/board/seed.js +23 -0
  37. package/dist/board/seed.js.map +1 -0
  38. package/dist/board/server.d.ts +3 -0
  39. package/dist/board/server.d.ts.map +1 -0
  40. package/dist/board/server.js +5 -0
  41. package/dist/board/server.js.map +1 -0
  42. package/dist/board/types.d.ts +45 -0
  43. package/dist/board/types.d.ts.map +1 -0
  44. package/dist/board/types.js +82 -0
  45. package/dist/board/types.js.map +1 -0
  46. package/dist/board/view.d.ts +2 -0
  47. package/dist/board/view.d.ts.map +1 -0
  48. package/dist/board/view.js +254 -0
  49. package/dist/board/view.js.map +1 -0
  50. package/dist/brahman/client.d.ts +3 -0
  51. package/dist/brahman/client.d.ts.map +1 -0
  52. package/dist/brahman/client.js +3 -0
  53. package/dist/brahman/client.js.map +1 -0
  54. package/dist/brahman/helpers.d.ts +51 -0
  55. package/dist/brahman/helpers.d.ts.map +1 -0
  56. package/dist/brahman/helpers.js +321 -0
  57. package/dist/brahman/helpers.js.map +1 -0
  58. package/dist/brahman/server.d.ts +3 -0
  59. package/dist/brahman/server.d.ts.map +1 -0
  60. package/dist/brahman/server.js +3 -0
  61. package/dist/brahman/server.js.map +1 -0
  62. package/dist/brahman/service.d.ts +2 -0
  63. package/dist/brahman/service.d.ts.map +1 -0
  64. package/dist/brahman/service.js +310 -0
  65. package/dist/brahman/service.js.map +1 -0
  66. package/dist/brahman/types.d.ts +335 -0
  67. package/dist/brahman/types.d.ts.map +1 -0
  68. package/dist/brahman/types.js +633 -0
  69. package/dist/brahman/types.js.map +1 -0
  70. package/dist/brahman/view.d.ts +2 -0
  71. package/dist/brahman/view.d.ts.map +1 -0
  72. package/dist/brahman/view.js +47 -0
  73. package/dist/brahman/view.js.map +1 -0
  74. package/dist/brahman/views/action-cards.d.ts +60 -0
  75. package/dist/brahman/views/action-cards.d.ts.map +1 -0
  76. package/dist/brahman/views/action-cards.js +283 -0
  77. package/dist/brahman/views/action-cards.js.map +1 -0
  78. package/dist/brahman/views/bot-view.d.ts +5 -0
  79. package/dist/brahman/views/bot-view.d.ts.map +1 -0
  80. package/dist/brahman/views/bot-view.js +14 -0
  81. package/dist/brahman/views/bot-view.js.map +1 -0
  82. package/dist/brahman/views/chat-editor.d.ts +5 -0
  83. package/dist/brahman/views/chat-editor.d.ts.map +1 -0
  84. package/dist/brahman/views/chat-editor.js +306 -0
  85. package/dist/brahman/views/chat-editor.js.map +1 -0
  86. package/dist/brahman/views/chat-preview.d.ts +5 -0
  87. package/dist/brahman/views/chat-preview.d.ts.map +1 -0
  88. package/dist/brahman/views/chat-preview.js +145 -0
  89. package/dist/brahman/views/chat-preview.js.map +1 -0
  90. package/dist/brahman/views/menu-editor.d.ts +11 -0
  91. package/dist/brahman/views/menu-editor.d.ts.map +1 -0
  92. package/dist/brahman/views/menu-editor.js +171 -0
  93. package/dist/brahman/views/menu-editor.js.map +1 -0
  94. package/dist/brahman/views/page-layout.d.ts +5 -0
  95. package/dist/brahman/views/page-layout.d.ts.map +1 -0
  96. package/dist/brahman/views/page-layout.js +114 -0
  97. package/dist/brahman/views/page-layout.js.map +1 -0
  98. package/dist/brahman/views/tstring-input.d.ts +15 -0
  99. package/dist/brahman/views/tstring-input.d.ts.map +1 -0
  100. package/dist/brahman/views/tstring-input.js +23 -0
  101. package/dist/brahman/views/tstring-input.js.map +1 -0
  102. package/dist/cafe/seed.d.ts +2 -0
  103. package/dist/cafe/seed.d.ts.map +1 -0
  104. package/dist/cafe/seed.js +7 -0
  105. package/dist/cafe/seed.js.map +1 -0
  106. package/dist/cafe/server.d.ts +3 -0
  107. package/dist/cafe/server.d.ts.map +1 -0
  108. package/dist/cafe/server.js +3 -0
  109. package/dist/cafe/server.js.map +1 -0
  110. package/dist/cafe/types.d.ts +2 -0
  111. package/dist/cafe/types.d.ts.map +1 -0
  112. package/dist/cafe/types.js +31 -0
  113. package/dist/cafe/types.js.map +1 -0
  114. package/dist/canary/seed.d.ts +2 -0
  115. package/dist/canary/seed.d.ts.map +1 -0
  116. package/dist/canary/seed.js +7 -0
  117. package/dist/canary/seed.js.map +1 -0
  118. package/dist/canary/server.d.ts +4 -0
  119. package/dist/canary/server.d.ts.map +1 -0
  120. package/dist/canary/server.js +4 -0
  121. package/dist/canary/server.js.map +1 -0
  122. package/dist/canary/service.d.ts +2 -0
  123. package/dist/canary/service.d.ts.map +1 -0
  124. package/dist/canary/service.js +101 -0
  125. package/dist/canary/service.js.map +1 -0
  126. package/dist/canary/types.d.ts +9 -0
  127. package/dist/canary/types.d.ts.map +1 -0
  128. package/dist/canary/types.js +13 -0
  129. package/dist/canary/types.js.map +1 -0
  130. package/dist/doc/client.d.ts +3 -0
  131. package/dist/doc/client.d.ts.map +1 -0
  132. package/dist/doc/client.js +5 -0
  133. package/dist/doc/client.js.map +1 -0
  134. package/dist/doc/fs-codec.d.ts +2 -0
  135. package/dist/doc/fs-codec.d.ts.map +1 -0
  136. package/dist/doc/fs-codec.js +44 -0
  137. package/dist/doc/fs-codec.js.map +1 -0
  138. package/dist/doc/markdown.d.ts +13 -0
  139. package/dist/doc/markdown.d.ts.map +1 -0
  140. package/dist/doc/markdown.js +250 -0
  141. package/dist/doc/markdown.js.map +1 -0
  142. package/dist/doc/prefab.d.ts +2 -0
  143. package/dist/doc/prefab.d.ts.map +1 -0
  144. package/dist/doc/prefab.js +23 -0
  145. package/dist/doc/prefab.js.map +1 -0
  146. package/dist/doc/renderers.d.ts +2 -0
  147. package/dist/doc/renderers.d.ts.map +1 -0
  148. package/dist/doc/renderers.js +94 -0
  149. package/dist/doc/renderers.js.map +1 -0
  150. package/dist/doc/seed.d.ts +2 -0
  151. package/dist/doc/seed.d.ts.map +1 -0
  152. package/dist/doc/seed.js +9 -0
  153. package/dist/doc/seed.js.map +1 -0
  154. package/dist/doc/server.d.ts +6 -0
  155. package/dist/doc/server.d.ts.map +1 -0
  156. package/dist/doc/server.js +6 -0
  157. package/dist/doc/server.js.map +1 -0
  158. package/dist/doc/slash-command.d.ts +3 -0
  159. package/dist/doc/slash-command.d.ts.map +1 -0
  160. package/dist/doc/slash-command.js +123 -0
  161. package/dist/doc/slash-command.js.map +1 -0
  162. package/dist/doc/slash-menu.d.ts +15 -0
  163. package/dist/doc/slash-menu.d.ts.map +1 -0
  164. package/dist/doc/slash-menu.js +54 -0
  165. package/dist/doc/slash-menu.js.map +1 -0
  166. package/dist/doc/text.d.ts +2 -0
  167. package/dist/doc/text.d.ts.map +1 -0
  168. package/dist/doc/text.js +22 -0
  169. package/dist/doc/text.js.map +1 -0
  170. package/dist/doc/toolbar.d.ts +5 -0
  171. package/dist/doc/toolbar.d.ts.map +1 -0
  172. package/dist/doc/toolbar.js +15 -0
  173. package/dist/doc/toolbar.js.map +1 -0
  174. package/dist/doc/treenity-block-view.d.ts +2 -0
  175. package/dist/doc/treenity-block-view.d.ts.map +1 -0
  176. package/dist/doc/treenity-block-view.js +37 -0
  177. package/dist/doc/treenity-block-view.js.map +1 -0
  178. package/dist/doc/treenity-block.d.ts +3 -0
  179. package/dist/doc/treenity-block.d.ts.map +1 -0
  180. package/dist/doc/treenity-block.js +27 -0
  181. package/dist/doc/treenity-block.js.map +1 -0
  182. package/dist/doc/types.d.ts +2 -0
  183. package/dist/doc/types.d.ts.map +1 -0
  184. package/dist/doc/types.js +10 -0
  185. package/dist/doc/types.js.map +1 -0
  186. package/dist/launcher/client.d.ts +5 -0
  187. package/dist/launcher/client.d.ts.map +1 -0
  188. package/dist/launcher/client.js +5 -0
  189. package/dist/launcher/client.js.map +1 -0
  190. package/dist/launcher/icons.d.ts +2 -0
  191. package/dist/launcher/icons.d.ts.map +1 -0
  192. package/dist/launcher/icons.js +57 -0
  193. package/dist/launcher/icons.js.map +1 -0
  194. package/dist/launcher/seed.d.ts +2 -0
  195. package/dist/launcher/seed.d.ts.map +1 -0
  196. package/dist/launcher/seed.js +36 -0
  197. package/dist/launcher/seed.js.map +1 -0
  198. package/dist/launcher/server.d.ts +3 -0
  199. package/dist/launcher/server.d.ts.map +1 -0
  200. package/dist/launcher/server.js +3 -0
  201. package/dist/launcher/server.js.map +1 -0
  202. package/dist/launcher/types.d.ts +21 -0
  203. package/dist/launcher/types.d.ts.map +1 -0
  204. package/dist/launcher/types.js +47 -0
  205. package/dist/launcher/types.js.map +1 -0
  206. package/dist/launcher/view.d.ts +2 -0
  207. package/dist/launcher/view.d.ts.map +1 -0
  208. package/dist/launcher/view.js +187 -0
  209. package/dist/launcher/view.js.map +1 -0
  210. package/dist/launcher/widgets.d.ts +2 -0
  211. package/dist/launcher/widgets.d.ts.map +1 -0
  212. package/dist/launcher/widgets.js +73 -0
  213. package/dist/launcher/widgets.js.map +1 -0
  214. package/dist/mindmap/branch.d.ts +17 -0
  215. package/dist/mindmap/branch.d.ts.map +1 -0
  216. package/dist/mindmap/branch.js +47 -0
  217. package/dist/mindmap/branch.js.map +1 -0
  218. package/dist/mindmap/client.d.ts +3 -0
  219. package/dist/mindmap/client.d.ts.map +1 -0
  220. package/dist/mindmap/client.js +3 -0
  221. package/dist/mindmap/client.js.map +1 -0
  222. package/dist/mindmap/radial-tree.d.ts +14 -0
  223. package/dist/mindmap/radial-tree.d.ts.map +1 -0
  224. package/dist/mindmap/radial-tree.js +184 -0
  225. package/dist/mindmap/radial-tree.js.map +1 -0
  226. package/dist/mindmap/sidebar.d.ts +8 -0
  227. package/dist/mindmap/sidebar.d.ts.map +1 -0
  228. package/dist/mindmap/sidebar.js +24 -0
  229. package/dist/mindmap/sidebar.js.map +1 -0
  230. package/dist/mindmap/types.d.ts +8 -0
  231. package/dist/mindmap/types.d.ts.map +1 -0
  232. package/dist/mindmap/types.js +10 -0
  233. package/dist/mindmap/types.js.map +1 -0
  234. package/dist/mindmap/use-tree-data.d.ts +14 -0
  235. package/dist/mindmap/use-tree-data.d.ts.map +1 -0
  236. package/dist/mindmap/use-tree-data.js +95 -0
  237. package/dist/mindmap/use-tree-data.js.map +1 -0
  238. package/dist/mindmap/view.d.ts +3 -0
  239. package/dist/mindmap/view.d.ts.map +1 -0
  240. package/dist/mindmap/view.js +141 -0
  241. package/dist/mindmap/view.js.map +1 -0
  242. package/dist/sensor-demo/client.d.ts +2 -0
  243. package/dist/sensor-demo/client.d.ts.map +1 -0
  244. package/dist/sensor-demo/client.js +2 -0
  245. package/dist/sensor-demo/client.js.map +1 -0
  246. package/dist/sensor-demo/server.d.ts +2 -0
  247. package/dist/sensor-demo/server.d.ts.map +1 -0
  248. package/dist/sensor-demo/server.js +2 -0
  249. package/dist/sensor-demo/server.js.map +1 -0
  250. package/dist/sensor-demo/service.d.ts +2 -0
  251. package/dist/sensor-demo/service.d.ts.map +1 -0
  252. package/dist/sensor-demo/service.js +27 -0
  253. package/dist/sensor-demo/service.js.map +1 -0
  254. package/dist/sensor-demo/types.d.ts +15 -0
  255. package/dist/sensor-demo/types.d.ts.map +1 -0
  256. package/dist/sensor-demo/types.js +18 -0
  257. package/dist/sensor-demo/types.js.map +1 -0
  258. package/dist/sensor-demo/view.d.ts +2 -0
  259. package/dist/sensor-demo/view.d.ts.map +1 -0
  260. package/dist/sensor-demo/view.js +33 -0
  261. package/dist/sensor-demo/view.js.map +1 -0
  262. package/dist/sensor-generator/action.d.ts +2 -0
  263. package/dist/sensor-generator/action.d.ts.map +1 -0
  264. package/dist/sensor-generator/action.js +23 -0
  265. package/dist/sensor-generator/action.js.map +1 -0
  266. package/dist/sensor-generator/client.d.ts +2 -0
  267. package/dist/sensor-generator/client.d.ts.map +1 -0
  268. package/dist/sensor-generator/client.js +2 -0
  269. package/dist/sensor-generator/client.js.map +1 -0
  270. package/dist/sensor-generator/server.d.ts +2 -0
  271. package/dist/sensor-generator/server.d.ts.map +1 -0
  272. package/dist/sensor-generator/server.js +2 -0
  273. package/dist/sensor-generator/server.js.map +1 -0
  274. package/dist/sensor-generator/view.d.ts +2 -0
  275. package/dist/sensor-generator/view.d.ts.map +1 -0
  276. package/dist/sensor-generator/view.js +64 -0
  277. package/dist/sensor-generator/view.js.map +1 -0
  278. package/dist/sim/client.d.ts +2 -0
  279. package/dist/sim/client.d.ts.map +1 -0
  280. package/dist/sim/client.js +2 -0
  281. package/dist/sim/client.js.map +1 -0
  282. package/dist/sim/seed.d.ts +2 -0
  283. package/dist/sim/seed.d.ts.map +1 -0
  284. package/dist/sim/seed.js +50 -0
  285. package/dist/sim/seed.js.map +1 -0
  286. package/dist/sim/server.d.ts +3 -0
  287. package/dist/sim/server.d.ts.map +1 -0
  288. package/dist/sim/server.js +3 -0
  289. package/dist/sim/server.js.map +1 -0
  290. package/dist/sim/service.d.ts +4 -0
  291. package/dist/sim/service.d.ts.map +1 -0
  292. package/dist/sim/service.js +528 -0
  293. package/dist/sim/service.js.map +1 -0
  294. package/dist/sim/types.d.ts +63 -0
  295. package/dist/sim/types.d.ts.map +1 -0
  296. package/dist/sim/types.js +57 -0
  297. package/dist/sim/types.js.map +1 -0
  298. package/dist/sim/view.d.ts +2 -0
  299. package/dist/sim/view.d.ts.map +1 -0
  300. package/dist/sim/view.js +205 -0
  301. package/dist/sim/view.js.map +1 -0
  302. package/dist/table/client.d.ts +4 -0
  303. package/dist/table/client.d.ts.map +1 -0
  304. package/dist/table/client.js +4 -0
  305. package/dist/table/client.js.map +1 -0
  306. package/dist/table/edit.d.ts +2 -0
  307. package/dist/table/edit.d.ts.map +1 -0
  308. package/dist/table/edit.js +115 -0
  309. package/dist/table/edit.js.map +1 -0
  310. package/dist/table/server.d.ts +2 -0
  311. package/dist/table/server.d.ts.map +1 -0
  312. package/dist/table/server.js +2 -0
  313. package/dist/table/server.js.map +1 -0
  314. package/dist/table/types.d.ts +18 -0
  315. package/dist/table/types.d.ts.map +1 -0
  316. package/dist/table/types.js +13 -0
  317. package/dist/table/types.js.map +1 -0
  318. package/dist/table/use-debounced-sync.d.ts +8 -0
  319. package/dist/table/use-debounced-sync.d.ts.map +1 -0
  320. package/dist/table/use-debounced-sync.js +56 -0
  321. package/dist/table/use-debounced-sync.js.map +1 -0
  322. package/dist/table/view.d.ts +2 -0
  323. package/dist/table/view.d.ts.map +1 -0
  324. package/dist/table/view.js +199 -0
  325. package/dist/table/view.js.map +1 -0
  326. package/dist/tasks/server.d.ts +2 -0
  327. package/dist/tasks/server.d.ts.map +1 -0
  328. package/dist/tasks/server.js +2 -0
  329. package/dist/tasks/server.js.map +1 -0
  330. package/dist/tasks/types.d.ts +22 -0
  331. package/dist/tasks/types.d.ts.map +1 -0
  332. package/dist/tasks/types.js +34 -0
  333. package/dist/tasks/types.js.map +1 -0
  334. package/dist/three/client.d.ts +2 -0
  335. package/dist/three/client.d.ts.map +1 -0
  336. package/dist/three/client.js +2 -0
  337. package/dist/three/client.js.map +1 -0
  338. package/dist/three/seed.d.ts +2 -0
  339. package/dist/three/seed.d.ts.map +1 -0
  340. package/dist/three/seed.js +45 -0
  341. package/dist/three/seed.js.map +1 -0
  342. package/dist/three/server.d.ts +3 -0
  343. package/dist/three/server.d.ts.map +1 -0
  344. package/dist/three/server.js +3 -0
  345. package/dist/three/server.js.map +1 -0
  346. package/dist/three/types.d.ts +178 -0
  347. package/dist/three/types.d.ts.map +1 -0
  348. package/dist/three/types.js +209 -0
  349. package/dist/three/types.js.map +1 -0
  350. package/dist/three/view.d.ts +2 -0
  351. package/dist/three/view.d.ts.map +1 -0
  352. package/dist/three/view.js +307 -0
  353. package/dist/three/view.js.map +1 -0
  354. package/dist/todo/client.d.ts +3 -0
  355. package/dist/todo/client.d.ts.map +1 -0
  356. package/dist/todo/client.js +3 -0
  357. package/dist/todo/client.js.map +1 -0
  358. package/dist/todo/seed.d.ts +2 -0
  359. package/dist/todo/seed.d.ts.map +1 -0
  360. package/dist/todo/seed.js +8 -0
  361. package/dist/todo/seed.js.map +1 -0
  362. package/dist/todo/server.d.ts +3 -0
  363. package/dist/todo/server.d.ts.map +1 -0
  364. package/dist/todo/server.js +3 -0
  365. package/dist/todo/server.js.map +1 -0
  366. package/dist/todo/types.d.ts +15 -0
  367. package/dist/todo/types.d.ts.map +1 -0
  368. package/dist/todo/types.js +29 -0
  369. package/dist/todo/types.js.map +1 -0
  370. package/dist/todo/view.d.ts +2 -0
  371. package/dist/todo/view.d.ts.map +1 -0
  372. package/dist/todo/view.js +27 -0
  373. package/dist/todo/view.js.map +1 -0
  374. package/dist/whisper/client.d.ts +2 -0
  375. package/dist/whisper/client.d.ts.map +1 -0
  376. package/dist/whisper/client.js +2 -0
  377. package/dist/whisper/client.js.map +1 -0
  378. package/dist/whisper/inbox.d.ts +2 -0
  379. package/dist/whisper/inbox.d.ts.map +1 -0
  380. package/dist/whisper/inbox.js +50 -0
  381. package/dist/whisper/inbox.js.map +1 -0
  382. package/dist/whisper/route.d.ts +10 -0
  383. package/dist/whisper/route.d.ts.map +1 -0
  384. package/dist/whisper/route.js +154 -0
  385. package/dist/whisper/route.js.map +1 -0
  386. package/dist/whisper/seed.d.ts +2 -0
  387. package/dist/whisper/seed.d.ts.map +1 -0
  388. package/dist/whisper/seed.js +14 -0
  389. package/dist/whisper/seed.js.map +1 -0
  390. package/dist/whisper/server.d.ts +5 -0
  391. package/dist/whisper/server.d.ts.map +1 -0
  392. package/dist/whisper/server.js +5 -0
  393. package/dist/whisper/server.js.map +1 -0
  394. package/dist/whisper/service.d.ts +2 -0
  395. package/dist/whisper/service.d.ts.map +1 -0
  396. package/dist/whisper/service.js +26 -0
  397. package/dist/whisper/service.js.map +1 -0
  398. package/dist/whisper/types.d.ts +38 -0
  399. package/dist/whisper/types.d.ts.map +1 -0
  400. package/dist/whisper/types.js +45 -0
  401. package/dist/whisper/types.js.map +1 -0
  402. package/dist/whisper/view.d.ts +2 -0
  403. package/dist/whisper/view.d.ts.map +1 -0
  404. package/dist/whisper/view.js +40 -0
  405. package/dist/whisper/view.js.map +1 -0
  406. package/doc/CLAUDE.md +49 -0
  407. package/doc/client.ts +5 -0
  408. package/doc/editor.css +283 -0
  409. package/doc/fs-codec.test.ts +119 -0
  410. package/doc/fs-codec.ts +50 -0
  411. package/doc/markdown.test.ts +152 -0
  412. package/doc/markdown.ts +284 -0
  413. package/doc/prefab.ts +26 -0
  414. package/doc/renderers.tsx +126 -0
  415. package/doc/seed.ts +10 -0
  416. package/doc/server.ts +5 -0
  417. package/doc/slash-command.ts +136 -0
  418. package/doc/slash-menu.tsx +91 -0
  419. package/doc/text.ts +20 -0
  420. package/doc/toolbar.tsx +86 -0
  421. package/doc/treenity-block-view.tsx +116 -0
  422. package/doc/treenity-block.ts +31 -0
  423. package/doc/types.ts +10 -0
  424. package/launcher/client.ts +4 -0
  425. package/launcher/icons.tsx +234 -0
  426. package/launcher/launcher.css +64 -0
  427. package/launcher/seed.ts +41 -0
  428. package/launcher/server.ts +2 -0
  429. package/launcher/types.ts +53 -0
  430. package/launcher/view.tsx +401 -0
  431. package/launcher/widgets.tsx +171 -0
  432. package/mindmap/branch.tsx +163 -0
  433. package/mindmap/client.ts +2 -0
  434. package/mindmap/mindmap.css +243 -0
  435. package/mindmap/sidebar.tsx +127 -0
  436. package/mindmap/types.ts +10 -0
  437. package/mindmap/view.tsx +247 -0
  438. package/package.json +75 -0
  439. package/sensor-demo/CLAUDE.md +3 -0
  440. package/sensor-demo/client.ts +1 -0
  441. package/sensor-demo/server.ts +1 -0
  442. package/sensor-demo/service.ts +27 -0
  443. package/sensor-demo/types.ts +20 -0
  444. package/sensor-demo/view.tsx +64 -0
  445. package/sensor-generator/CLAUDE.md +3 -0
  446. package/sensor-generator/action.ts +28 -0
  447. package/sensor-generator/client.ts +1 -0
  448. package/sensor-generator/server.ts +1 -0
  449. package/sensor-generator/view.tsx +107 -0
  450. package/sim/CLAUDE.md +16 -0
  451. package/sim/client.ts +1 -0
  452. package/sim/seed.ts +55 -0
  453. package/sim/server.ts +2 -0
  454. package/sim/service.ts +594 -0
  455. package/sim/sim.test.ts +282 -0
  456. package/sim/types.ts +87 -0
  457. package/sim/view.tsx +446 -0
  458. package/table/client.ts +3 -0
  459. package/table/edit.tsx +241 -0
  460. package/table/server.ts +1 -0
  461. package/table/types.ts +22 -0
  462. package/table/use-debounced-sync.ts +67 -0
  463. package/table/view.tsx +339 -0
  464. package/tasks/CLAUDE.md +6 -0
  465. package/tasks/server.ts +1 -0
  466. package/tasks/types.ts +36 -0
  467. package/three/CLAUDE.md +6 -0
  468. package/three/client.ts +1 -0
  469. package/three/seed.ts +54 -0
  470. package/three/server.ts +2 -0
  471. package/three/types.ts +238 -0
  472. package/three/view.tsx +453 -0
  473. package/todo/client.ts +2 -0
  474. package/todo/seed.ts +9 -0
  475. package/todo/server.ts +2 -0
  476. package/todo/types.ts +32 -0
  477. package/todo/view.tsx +67 -0
  478. package/whisper/CLAUDE.md +16 -0
  479. package/whisper/client.ts +1 -0
  480. package/whisper/inbox.ts +54 -0
  481. package/whisper/route.ts +182 -0
  482. package/whisper/seed.ts +15 -0
  483. package/whisper/server.ts +4 -0
  484. package/whisper/service.ts +29 -0
  485. package/whisper/types.ts +51 -0
  486. package/whisper/view.tsx +81 -0
package/three/types.ts ADDED
@@ -0,0 +1,238 @@
1
+ import { registerType } from '@treenity/core/comp';
2
+
3
+ /** @title 3D Scene — root container for the Three.js viewport */
4
+ export class T3dScene {}
5
+
6
+ /** @title 3D Object — spatial entity in the scene graph */
7
+ export class T3dObject {
8
+ /** @title Position X */ px = 0;
9
+ /** @title Position Y */ py = 0;
10
+ /** @title Position Z */ pz = 0;
11
+ /** @title Rotation X (rad) */ rx = 0;
12
+ /** @title Rotation Y (rad) */ ry = 0;
13
+ /** @title Rotation Z (rad) */ rz = 0;
14
+ /** @title Scale X */ sx = 1;
15
+ /** @title Scale Y */ sy = 1;
16
+ /** @title Scale Z */ sz = 1;
17
+ }
18
+
19
+ // --- Geometry ---
20
+
21
+ /** @title 3D Mesh — geometry shape */
22
+ export class T3dMesh {
23
+ /** @title Geometry */ geometry: 'box' | 'sphere' | 'plane' | 'cylinder' | 'torus' | 'cone' | 'capsule' | 'ring' | 'dodecahedron' | 'icosahedron' | 'octahedron' = 'box';
24
+ /** @title Width / Radius */ width = 1;
25
+ /** @title Height */ height = 1;
26
+ /** @title Depth */ depth = 1;
27
+ /** @title Segments */ segments = 32;
28
+ /** @title Cast Shadow */ castShadow = true;
29
+ /** @title Receive Shadow */ receiveShadow = true;
30
+ }
31
+
32
+ // --- Material ---
33
+
34
+ /** @title 3D Material — surface appearance */
35
+ export class T3dMaterial {
36
+ /** @title Type */ kind: 'standard' | 'physical' | 'basic' | 'phong' | 'toon' | 'lambert' = 'standard';
37
+ /** @title Color */ color = '#6366f1';
38
+ /** @title Emissive Color */ emissive = '#000000';
39
+ /** @title Emissive Intensity */ emissiveIntensity = 0;
40
+ /** @title Metalness */ metalness = 0;
41
+ /** @title Roughness */ roughness = 0.5;
42
+ /** @title Opacity */ opacity = 1;
43
+ /** @title Transparent */ transparent = false;
44
+ /** @title Wireframe */ wireframe = false;
45
+ /** @title Side */ side: 'front' | 'back' | 'double' = 'front';
46
+ /** @title Flat Shading */ flatShading = false;
47
+ /** @title Texture URL */ map = '';
48
+ /** @title Normal Map URL */ normalMap = '';
49
+ /** @title Roughness Map URL */ roughnessMap = '';
50
+ /** @title Metalness Map URL */ metalnessMap = '';
51
+ /** @title Emissive Map URL */ emissiveMap = '';
52
+ /** @title AO Map URL */ aoMap = '';
53
+ /** @title Env Map Intensity */ envMapIntensity = 1;
54
+ }
55
+
56
+ // --- Lighting ---
57
+
58
+ /** @title 3D Light — light source */
59
+ export class T3dLight {
60
+ /** @title Kind */ kind: 'point' | 'directional' | 'spot' | 'ambient' | 'hemisphere' | 'rect-area' = 'point';
61
+ /** @title Color */ color = '#ffffff';
62
+ /** @title Ground Color (hemisphere) */ groundColor = '#444444';
63
+ /** @title Intensity */ intensity = 1;
64
+ /** @title Distance (0=infinite) */ distance = 0;
65
+ /** @title Decay */ decay = 2;
66
+ /** @title Cast Shadow */ castShadow = true;
67
+ /** @title Spot Angle */ angle = 0.5;
68
+ /** @title Spot Penumbra */ penumbra = 0.5;
69
+ /** @title Shadow Map Size */ shadowMapSize = 1024;
70
+ /** @title Rect Width */ rectWidth = 1;
71
+ /** @title Rect Height */ rectHeight = 1;
72
+ }
73
+
74
+ // --- Camera ---
75
+
76
+ /** @title 3D Camera */
77
+ export class T3dCamera {
78
+ /** @title Kind */ kind: 'perspective' | 'orthographic' = 'perspective';
79
+ /** @title FOV */ fov = 75;
80
+ /** @title Near Clip */ near = 0.1;
81
+ /** @title Far Clip */ far = 1000;
82
+ /** @title Ortho Size */ orthoSize = 10;
83
+ /** @title Active */ active = true;
84
+ }
85
+
86
+ // --- Physics ---
87
+
88
+ /** @title 3D Rigidbody — physics body */
89
+ export class T3dRigidbody {
90
+ /** @title Kind */ kind: 'dynamic' | 'static' | 'kinematic' = 'dynamic';
91
+ /** @title Mass */ mass = 1;
92
+ /** @title Linear Drag */ linearDamping = 0;
93
+ /** @title Angular Drag */ angularDamping = 0.05;
94
+ /** @title Use Gravity */ useGravity = true;
95
+ /** @title Freeze Position X */ freezePx = false;
96
+ /** @title Freeze Position Y */ freezePy = false;
97
+ /** @title Freeze Position Z */ freezePz = false;
98
+ /** @title Freeze Rotation X */ freezeRx = false;
99
+ /** @title Freeze Rotation Y */ freezeRy = false;
100
+ /** @title Freeze Rotation Z */ freezeRz = false;
101
+ }
102
+
103
+ /** @title 3D Collider — collision shape */
104
+ export class T3dCollider {
105
+ /** @title Shape */ shape: 'box' | 'sphere' | 'capsule' | 'cylinder' | 'mesh' | 'convex' = 'box';
106
+ /** @title Is Trigger */ isTrigger = false;
107
+ /** @title Size X */ sizeX = 1;
108
+ /** @title Size Y */ sizeY = 1;
109
+ /** @title Size Z */ sizeZ = 1;
110
+ /** @title Radius */ radius = 0.5;
111
+ /** @title Offset X */ offsetX = 0;
112
+ /** @title Offset Y */ offsetY = 0;
113
+ /** @title Offset Z */ offsetZ = 0;
114
+ /** @title Friction */ friction = 0.5;
115
+ /** @title Restitution (bounce) */ restitution = 0;
116
+ }
117
+
118
+ // --- Audio ---
119
+
120
+ /** @title 3D Audio — positional sound */
121
+ export class T3dAudio {
122
+ /** @title Source URL */ src = '';
123
+ /** @title Volume */ volume = 1;
124
+ /** @title Loop */ loop = false;
125
+ /** @title Autoplay */ autoplay = false;
126
+ /** @title Spatial */ spatial = true;
127
+ /** @title Ref Distance */ refDistance = 1;
128
+ /** @title Max Distance */ maxDistance = 100;
129
+ /** @title Rolloff Factor */ rolloffFactor = 1;
130
+ }
131
+
132
+ // --- Particles ---
133
+
134
+ /** @title 3D Particles — particle emitter */
135
+ export class T3dParticles {
136
+ /** @title Count */ count = 100;
137
+ /** @title Size */ size = 0.1;
138
+ /** @title Color */ color = '#ffffff';
139
+ /** @title Lifetime (s) */ lifetime = 2;
140
+ /** @title Speed */ speed = 1;
141
+ /** @title Spread */ spread = 1;
142
+ /** @title Shape */ shape: 'sphere' | 'cone' | 'box' | 'point' = 'sphere';
143
+ /** @title Emitter */ emitter: 'point' | 'volume' = 'point';
144
+ /** @title Particle Shape */ particleShape: 'sphere' | 'triangle' | 'plane' = 'sphere';
145
+ /** @title Gravity */ gravity = 0;
146
+ /** @title Size Over Lifetime */ sizeOverLifetime = false;
147
+ /** @title Opacity Over Lifetime */ opacityOverLifetime = true;
148
+ /** @title Emissive */ emissive = false;
149
+ /** @title Loop */ loop = true;
150
+ }
151
+
152
+ // --- Text ---
153
+
154
+ /** @title 3D Text — floating text in scene */
155
+ export class T3dText {
156
+ /** @title Text @format textarea */ text = 'Hello';
157
+ /** @title Font Size */ fontSize = 1;
158
+ /** @title Color */ color = '#ffffff';
159
+ /** @title Max Width */ maxWidth = 10;
160
+ /** @title Align */ align: 'left' | 'center' | 'right' = 'center';
161
+ /** @title Anchor X */ anchorX: 'left' | 'center' | 'right' = 'center';
162
+ /** @title Anchor Y */ anchorY: 'top' | 'middle' | 'bottom' = 'middle';
163
+ /** @title Billboard (face camera) */ billboard = false;
164
+ /** @title Outline Width */ outlineWidth = 0;
165
+ /** @title Outline Color */ outlineColor = '#000000';
166
+ }
167
+
168
+ // --- Animation ---
169
+
170
+ /** @title 3D Animator — animation state */
171
+ export class T3dAnimator {
172
+ /** @title GLTF URL */ src = '';
173
+ /** @title Current Clip */ clip = '';
174
+ /** @title Playing */ playing = true;
175
+ /** @title Loop */ loop = true;
176
+ /** @title Speed */ speed = 1;
177
+ /** @title Crossfade Duration (s) */ crossfadeDuration = 0.3;
178
+ }
179
+
180
+ // --- LOD ---
181
+
182
+ /** @title 3D LOD — level of detail */
183
+ export class T3dLod {
184
+ /** @title Distance 0 (high) */ d0 = 0;
185
+ /** @title Distance 1 (mid) */ d1 = 10;
186
+ /** @title Distance 2 (low) */ d2 = 25;
187
+ }
188
+
189
+ // --- Trail ---
190
+
191
+ /** @title 3D Trail — trail renderer behind moving objects */
192
+ export class T3dTrail {
193
+ /** @title Width */ width = 0.2;
194
+ /** @title Length (s) */ length = 1;
195
+ /** @title Color Start */ colorStart = '#ffffff';
196
+ /** @title Color End */ colorEnd = '#ffffff00';
197
+ /** @title Attenuation */ attenuation: 'linear' | 'squared' | 'none' = 'linear';
198
+ }
199
+
200
+ // --- Line ---
201
+
202
+ /** @title 3D Line Renderer */
203
+ export class T3dLine {
204
+ /** @title Color */ color = '#ffffff';
205
+ /** @title Line Width */ lineWidth = 1;
206
+ /** @title Dashed */ dashed = false;
207
+ /** @title Dash Size */ dashSize = 0.1;
208
+ /** @title Gap Size */ gapSize = 0.05;
209
+ /** @title Points (JSON array of [x,y,z]) @format textarea */ points = '[[0,0,0],[1,1,0],[2,0,0]]';
210
+ }
211
+
212
+ // --- Script ---
213
+
214
+ /** @title 3D Script — client-side update loop */
215
+ export class T3dScript {
216
+ /** @title Code @format textarea */
217
+ code = '';
218
+ /** @title Active */ active = true;
219
+ }
220
+
221
+ // --- Register all ---
222
+
223
+ registerType('t3d.scene', T3dScene);
224
+ registerType('t3d.object', T3dObject);
225
+ registerType('t3d.mesh', T3dMesh);
226
+ registerType('t3d.material', T3dMaterial);
227
+ registerType('t3d.light', T3dLight);
228
+ registerType('t3d.camera', T3dCamera);
229
+ registerType('t3d.rigidbody', T3dRigidbody);
230
+ registerType('t3d.collider', T3dCollider);
231
+ registerType('t3d.audio', T3dAudio);
232
+ registerType('t3d.particles', T3dParticles);
233
+ registerType('t3d.text', T3dText);
234
+ registerType('t3d.animator', T3dAnimator);
235
+ registerType('t3d.lod', T3dLod);
236
+ registerType('t3d.trail', T3dTrail);
237
+ registerType('t3d.line', T3dLine);
238
+ registerType('t3d.script', T3dScript);
package/three/view.tsx ADDED
@@ -0,0 +1,453 @@
1
+ // Three.js scene view — renders Treenity node tree as a 3D scene graph
2
+ // SceneView registered for t3d.scene in "react" context
3
+
4
+ import { Billboard, OrbitControls, Text, Trail } from '@react-three/drei';
5
+ import { Canvas, useFrame } from '@react-three/fiber';
6
+ import { getComponent, type NodeData, register } from '@treenity/core';
7
+ import { useResolvedNode } from '@treenity/react/bind/hook';
8
+ import * as cache from '@treenity/react/cache';
9
+ import { useCurrentNode } from '@treenity/react/context';
10
+ import { execute, useChildren, usePath } from '@treenity/react/hooks';
11
+ import { useEffect, useMemo, useRef, useState } from 'react';
12
+ import * as THREE from 'three';
13
+ import {
14
+ T3dCamera,
15
+ T3dLight,
16
+ T3dLine,
17
+ T3dMaterial,
18
+ T3dMesh,
19
+ T3dObject,
20
+ T3dParticles,
21
+ T3dScript,
22
+ T3dText,
23
+ T3dTrail,
24
+ } from './types';
25
+
26
+ // --- Texture loader helper ---
27
+
28
+ function useOptionalTexture(url: string | undefined): THREE.Texture | undefined {
29
+ const [tex, setTex] = useState<THREE.Texture | undefined>();
30
+ useEffect(() => {
31
+ if (!url) { setTex(undefined); return; }
32
+ new THREE.TextureLoader().load(url, setTex, undefined, () => setTex(undefined));
33
+ }, [url]);
34
+ return tex;
35
+ }
36
+
37
+ // --- Geometry ---
38
+
39
+ function Geometry({ mesh }: { mesh: T3dMesh }) {
40
+ const s = mesh.segments;
41
+ switch (mesh.geometry) {
42
+ case 'sphere':
43
+ return <sphereGeometry args={[mesh.width, s, s]} />;
44
+ case 'plane':
45
+ return <planeGeometry args={[mesh.width, mesh.depth]} />;
46
+ case 'cylinder':
47
+ return <cylinderGeometry args={[mesh.width, mesh.width, mesh.height, s]} />;
48
+ case 'torus':
49
+ return <torusGeometry args={[mesh.width, mesh.width * 0.4, 16, s]} />;
50
+ case 'cone':
51
+ return <coneGeometry args={[mesh.width, mesh.height, s]} />;
52
+ case 'capsule':
53
+ return <capsuleGeometry args={[mesh.width, mesh.height, 16, s]} />;
54
+ case 'ring':
55
+ return <ringGeometry args={[mesh.width * 0.5, mesh.width, s]} />;
56
+ case 'dodecahedron':
57
+ return <dodecahedronGeometry args={[mesh.width]} />;
58
+ case 'icosahedron':
59
+ return <icosahedronGeometry args={[mesh.width]} />;
60
+ case 'octahedron':
61
+ return <octahedronGeometry args={[mesh.width]} />;
62
+ default: // box
63
+ return <boxGeometry args={[mesh.width, mesh.height, mesh.depth]} />;
64
+ }
65
+ }
66
+
67
+ // --- Material ---
68
+
69
+ const SIDE_MAP = { front: THREE.FrontSide, back: THREE.BackSide, double: THREE.DoubleSide } as const;
70
+
71
+ function MaterialElement({ data }: { data: T3dMaterial }) {
72
+ const map = useOptionalTexture(data.map || undefined);
73
+ const normalMap = useOptionalTexture(data.normalMap || undefined);
74
+ const roughnessMap = useOptionalTexture(data.roughnessMap || undefined);
75
+ const metalnessMap = useOptionalTexture(data.metalnessMap || undefined);
76
+ const emissiveMap = useOptionalTexture(data.emissiveMap || undefined);
77
+ const aoMap = useOptionalTexture(data.aoMap || undefined);
78
+
79
+ const side = SIDE_MAP[data.side] ?? THREE.FrontSide;
80
+
81
+ switch (data.kind) {
82
+ case 'basic':
83
+ return <meshBasicMaterial color={data.color} map={map} wireframe={data.wireframe} transparent={data.transparent} opacity={data.opacity} side={side} />;
84
+ case 'phong':
85
+ return <meshPhongMaterial color={data.color} emissive={data.emissive} map={map} normalMap={normalMap} wireframe={data.wireframe} flatShading={data.flatShading} transparent={data.transparent} opacity={data.opacity} side={side} />;
86
+ case 'toon':
87
+ return <meshToonMaterial color={data.color} map={map} wireframe={data.wireframe} transparent={data.transparent} opacity={data.opacity} side={side} />;
88
+ case 'lambert':
89
+ return <meshLambertMaterial color={data.color} emissive={data.emissive} map={map} wireframe={data.wireframe} transparent={data.transparent} opacity={data.opacity} side={side} />;
90
+ case 'physical':
91
+ return (
92
+ <meshPhysicalMaterial
93
+ color={data.color} emissive={data.emissive} emissiveIntensity={data.emissiveIntensity}
94
+ metalness={data.metalness} roughness={data.roughness}
95
+ map={map} normalMap={normalMap} roughnessMap={roughnessMap} metalnessMap={metalnessMap} emissiveMap={emissiveMap} aoMap={aoMap}
96
+ wireframe={data.wireframe} flatShading={data.flatShading} transparent={data.transparent} opacity={data.opacity} side={side}
97
+ envMapIntensity={data.envMapIntensity}
98
+ />
99
+ );
100
+ default: // standard
101
+ return (
102
+ <meshStandardMaterial
103
+ color={data.color} emissive={data.emissive} emissiveIntensity={data.emissiveIntensity}
104
+ metalness={data.metalness} roughness={data.roughness}
105
+ map={map} normalMap={normalMap} roughnessMap={roughnessMap} metalnessMap={metalnessMap} emissiveMap={emissiveMap} aoMap={aoMap}
106
+ wireframe={data.wireframe} flatShading={data.flatShading} transparent={data.transparent} opacity={data.opacity} side={side}
107
+ envMapIntensity={data.envMapIntensity}
108
+ />
109
+ );
110
+ }
111
+ }
112
+
113
+ function MeshElement({ mesh, material }: { mesh: T3dMesh; material: T3dMaterial | null }) {
114
+ return (
115
+ <mesh castShadow={mesh.castShadow} receiveShadow={mesh.receiveShadow}>
116
+ <Geometry mesh={mesh} />
117
+ {material
118
+ ? <MaterialElement data={material} />
119
+ : <meshStandardMaterial color="#6366f1" roughness={0.5} />
120
+ }
121
+ </mesh>
122
+ );
123
+ }
124
+
125
+ // --- Light ---
126
+
127
+ function LightElement({ data }: { data: T3dLight }) {
128
+ switch (data.kind) {
129
+ case 'directional':
130
+ return <directionalLight color={data.color} intensity={data.intensity} castShadow={data.castShadow} />;
131
+ case 'spot':
132
+ return (
133
+ <spotLight
134
+ color={data.color} intensity={data.intensity}
135
+ angle={data.angle} penumbra={data.penumbra} distance={data.distance} decay={data.decay}
136
+ castShadow={data.castShadow}
137
+ />
138
+ );
139
+ case 'ambient':
140
+ return <ambientLight color={data.color} intensity={data.intensity} />;
141
+ case 'hemisphere':
142
+ return <hemisphereLight color={data.color} groundColor={data.groundColor} intensity={data.intensity} />;
143
+ case 'rect-area':
144
+ return <rectAreaLight color={data.color} intensity={data.intensity} width={data.rectWidth} height={data.rectHeight} />;
145
+ default: // point
146
+ return <pointLight color={data.color} intensity={data.intensity} distance={data.distance} decay={data.decay} castShadow={data.castShadow} />;
147
+ }
148
+ }
149
+
150
+ // --- Text ---
151
+
152
+ function TextElement({ data }: { data: T3dText }) {
153
+ const inner = (
154
+ <Text
155
+ fontSize={data.fontSize}
156
+ color={data.color}
157
+ maxWidth={data.maxWidth}
158
+ textAlign={data.align}
159
+ anchorX={data.anchorX}
160
+ anchorY={data.anchorY}
161
+ outlineWidth={data.outlineWidth}
162
+ outlineColor={data.outlineColor}
163
+ >
164
+ {data.text}
165
+ </Text>
166
+ );
167
+
168
+ return data.billboard ? <Billboard>{inner}</Billboard> : inner;
169
+ }
170
+
171
+ // --- Particles ---
172
+
173
+ function ParticlesElement({ data }: { data: T3dParticles }) {
174
+ const meshRef = useRef<THREE.InstancedMesh>(null);
175
+ const dummy = useMemo(() => new THREE.Object3D(), []);
176
+ const isVolume = data.emitter === 'volume';
177
+
178
+ // Per-particle state: position, drift velocity, rotation speed
179
+ const state = useMemo(() => {
180
+ const pos = new Float32Array(data.count * 3);
181
+ const vel = new Float32Array(data.count * 3);
182
+ const rot = new Float32Array(data.count * 3);
183
+
184
+ for (let i = 0; i < data.count; i++) {
185
+ const i3 = i * 3;
186
+ if (isVolume) {
187
+ pos[i3] = (Math.random() - 0.5) * data.spread * 2;
188
+ pos[i3 + 1] = Math.random() * data.spread;
189
+ pos[i3 + 2] = (Math.random() - 0.5) * data.spread * 2;
190
+ vel[i3] = (Math.random() - 0.5) * 0.3;
191
+ vel[i3 + 1] = 0;
192
+ vel[i3 + 2] = (Math.random() - 0.5) * 0.3;
193
+ } else {
194
+ const theta = Math.random() * Math.PI * 2;
195
+ const phi = Math.acos(2 * Math.random() - 1);
196
+ vel[i3] = Math.sin(phi) * Math.cos(theta) * data.spread;
197
+ vel[i3 + 1] = Math.sin(phi) * Math.sin(theta) * data.spread;
198
+ vel[i3 + 2] = Math.cos(phi) * data.spread;
199
+ }
200
+ rot[i3] = (Math.random() - 0.5) * 4;
201
+ rot[i3 + 1] = (Math.random() - 0.5) * 4;
202
+ rot[i3 + 2] = (Math.random() - 0.5) * 4;
203
+ }
204
+ return { pos, vel, rot };
205
+ }, [data.count, data.spread, isVolume]);
206
+
207
+ const ages = useMemo(() => {
208
+ const a = new Float32Array(data.count);
209
+ for (let i = 0; i < data.count; i++) a[i] = Math.random() * data.lifetime;
210
+ return a;
211
+ }, [data.count, data.lifetime]);
212
+
213
+ useFrame((_, dt) => {
214
+ if (!meshRef.current) return;
215
+ const { pos, vel, rot } = state;
216
+
217
+ for (let i = 0; i < data.count; i++) {
218
+ ages[i] += dt;
219
+ const i3 = i * 3;
220
+
221
+ if (ages[i] > data.lifetime) {
222
+ ages[i] = 0;
223
+ if (isVolume) {
224
+ pos[i3] = (Math.random() - 0.5) * data.spread * 2;
225
+ pos[i3 + 1] = Math.random() * data.spread;
226
+ pos[i3 + 2] = (Math.random() - 0.5) * data.spread * 2;
227
+ vel[i3] = (Math.random() - 0.5) * 0.3;
228
+ vel[i3 + 2] = (Math.random() - 0.5) * 0.3;
229
+ } else {
230
+ dummy.position.set(0, 0, 0);
231
+ }
232
+ }
233
+
234
+ const t = ages[i];
235
+
236
+ if (isVolume) {
237
+ // Gentle fall with horizontal wobble
238
+ dummy.position.set(
239
+ pos[i3] + vel[i3] * t + Math.sin(t * 2 + i) * 0.2,
240
+ pos[i3 + 1] - data.gravity * t * data.speed,
241
+ pos[i3 + 2] + vel[i3 + 2] * t + Math.cos(t * 1.5 + i * 0.7) * 0.15,
242
+ );
243
+ dummy.rotation.set(rot[i3] * t, rot[i3 + 1] * t, rot[i3 + 2] * t);
244
+ } else {
245
+ dummy.position.set(
246
+ vel[i3] * t * data.speed,
247
+ vel[i3 + 1] * t * data.speed - data.gravity * t * t * 0.5,
248
+ vel[i3 + 2] * t * data.speed,
249
+ );
250
+ }
251
+
252
+ const lifeRatio = ages[i] / data.lifetime;
253
+ const s = data.sizeOverLifetime ? data.size * (1 - lifeRatio) : data.size;
254
+ dummy.scale.setScalar(s);
255
+ dummy.updateMatrix();
256
+ meshRef.current.setMatrixAt(i, dummy.matrix);
257
+ }
258
+ meshRef.current.instanceMatrix.needsUpdate = true;
259
+ });
260
+
261
+ // circleGeometry(r, 3) = equilateral triangle
262
+ const geometry = data.particleShape === 'triangle'
263
+ ? <circleGeometry args={[1, 3]} />
264
+ : data.particleShape === 'plane'
265
+ ? <planeGeometry args={[1, 1]} />
266
+ : <sphereGeometry args={[1, 8, 8]} />;
267
+
268
+ const side = data.particleShape !== 'sphere' ? THREE.DoubleSide : undefined;
269
+
270
+ return (
271
+ <instancedMesh ref={meshRef} args={[undefined, undefined, data.count]}>
272
+ {geometry}
273
+ {data.emissive
274
+ ? <meshBasicMaterial color={data.color} transparent opacity={data.opacityOverLifetime ? 0.8 : 1} side={side} />
275
+ : <meshStandardMaterial color={data.color} transparent opacity={data.opacityOverLifetime ? 0.8 : 1} side={side} />
276
+ }
277
+ </instancedMesh>
278
+ );
279
+ }
280
+
281
+ // --- Line ---
282
+
283
+ function LineElement({ data }: { data: T3dLine }) {
284
+ const points = useMemo(() => {
285
+ try {
286
+ const arr = JSON.parse(data.points) as number[][];
287
+ return arr.map(([x, y, z]) => new THREE.Vector3(x, y, z));
288
+ } catch { return [new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 0, 0)]; }
289
+ }, [data.points]);
290
+
291
+ const geometry = useMemo(() => new THREE.BufferGeometry().setFromPoints(points), [points]);
292
+
293
+ if (data.dashed) {
294
+ return (
295
+ // @ts-expect-error R3F <line> is THREE.Line, not SVG <line>
296
+ <line geometry={geometry}>
297
+ <lineDashedMaterial color={data.color} dashSize={data.dashSize} gapSize={data.gapSize} />
298
+ </line>
299
+ );
300
+ }
301
+
302
+ return (
303
+ // @ts-expect-error R3F <line> is THREE.Line, not SVG <line>
304
+ <line geometry={geometry}>
305
+ <lineBasicMaterial color={data.color} />
306
+ </line>
307
+ );
308
+ }
309
+
310
+ // --- Trail ---
311
+
312
+ function TrailElement({ data, children }: { data: T3dTrail; children: React.ReactNode }) {
313
+ return (
314
+ <Trail
315
+ width={data.width}
316
+ length={data.length}
317
+ color={data.colorStart}
318
+ attenuation={(t: number) => data.attenuation === 'none' ? 1 : data.attenuation === 'squared' ? t * t : t}
319
+ >
320
+ {children}
321
+ </Trail>
322
+ );
323
+ }
324
+
325
+ // --- Script runner (client-side useFrame update loop) ---
326
+
327
+ function ScriptRunner({ path, code, groupRef }: {
328
+ path: string;
329
+ code: string;
330
+ groupRef: React.RefObject<THREE.Group | null>;
331
+ }) {
332
+ const fnRef = useRef<((ctx: unknown) => void) | null>(null);
333
+ const node = usePath(path);
334
+
335
+ useEffect(() => {
336
+ try {
337
+ fnRef.current = new Function('ctx', code) as (ctx: unknown) => void;
338
+ } catch (e) {
339
+ console.error(`[t3d.script] compile error at ${path}:`, e);
340
+ fnRef.current = null;
341
+ }
342
+ }, [code, path]);
343
+
344
+ const throttledExecute = useMemo(() => {
345
+ let last = 0;
346
+ return (action: string, data?: unknown) => {
347
+ const now = Date.now();
348
+ if (now - last < 100) return;
349
+ last = now;
350
+ execute(path, action, data);
351
+ };
352
+ }, [path, execute]);
353
+
354
+ useFrame((state, dt) => {
355
+ if (!fnRef.current || !node) return;
356
+ try {
357
+ fnRef.current({
358
+ node, dt,
359
+ time: state.clock.elapsedTime,
360
+ ref: groupRef.current,
361
+ execute: throttledExecute,
362
+ getNode: (p: string) => cache.get(p),
363
+ getChildren: (p: string) => cache.getChildren(p),
364
+ });
365
+ } catch (e) {
366
+ console.error(`[t3d.script] runtime error at ${path}:`, e);
367
+ fnRef.current = null;
368
+ }
369
+ });
370
+
371
+ return null;
372
+ }
373
+
374
+ // --- Recursive tree node renderer ---
375
+
376
+ function TreeNode({ path }: { path: string }) {
377
+ const [node] = useResolvedNode(path);
378
+ const children = useChildren(path);
379
+ const groupRef = useRef<THREE.Group>(null);
380
+
381
+ if (!node) return null;
382
+
383
+ const obj = getComponent(node, T3dObject);
384
+ const mesh = getComponent(node, T3dMesh);
385
+ const material = getComponent(node, T3dMaterial);
386
+ const light = getComponent(node, T3dLight);
387
+ const camera = getComponent(node, T3dCamera);
388
+ const text = getComponent(node, T3dText);
389
+ const particles = getComponent(node, T3dParticles);
390
+ const line = getComponent(node, T3dLine);
391
+ const trail = getComponent(node, T3dTrail);
392
+ const script = getComponent(node, T3dScript);
393
+
394
+ // Build inner visual content
395
+ let visual: React.ReactNode = null;
396
+ if (mesh) visual = <MeshElement mesh={mesh} material={material ?? null} />;
397
+ else if (light) visual = <LightElement data={light} />;
398
+ else if (text) visual = <TextElement data={text} />;
399
+ else if (particles) visual = <ParticlesElement data={particles} />;
400
+ else if (line) visual = <LineElement data={line} />;
401
+
402
+ // Wrap in trail if present
403
+ if (trail && visual) visual = <TrailElement data={trail}>{visual}</TrailElement>;
404
+
405
+ return (
406
+ <group
407
+ ref={groupRef}
408
+ position={obj ? [obj.px, obj.py, obj.pz] : undefined}
409
+ rotation={obj ? [obj.rx, obj.ry, obj.rz] : undefined}
410
+ scale={obj ? [obj.sx, obj.sy, obj.sz] : undefined}
411
+ >
412
+ {visual}
413
+ {script?.active && script.code && (
414
+ <ScriptRunner path={path} code={script.code} groupRef={groupRef} />
415
+ )}
416
+ {children.map((c) => (
417
+ <TreeNode key={c.$path} path={c.$path} />
418
+ ))}
419
+ </group>
420
+ );
421
+ }
422
+
423
+ // --- Scene root (inside Canvas) ---
424
+
425
+ function SceneRoot({ path }: { path: string }) {
426
+ const children = useChildren(path, { watch: true, watchNew: true });
427
+
428
+ return (
429
+ <>
430
+ {children.map((c) => (
431
+ <TreeNode key={c.$path} path={c.$path} />
432
+ ))}
433
+ </>
434
+ );
435
+ }
436
+
437
+ // --- Top-level view registered for t3d.scene ---
438
+
439
+ function SceneView({ value }: { value: NodeData }) {
440
+ const node = useCurrentNode();
441
+ const path = node?.$path ?? value.$path;
442
+
443
+ return (
444
+ <div className="w-full h-[600px] rounded-lg overflow-hidden bg-black/90">
445
+ <Canvas shadows camera={{ position: [5, 5, 5], fov: 60 }}>
446
+ <OrbitControls />
447
+ <SceneRoot path={path} />
448
+ </Canvas>
449
+ </div>
450
+ );
451
+ }
452
+
453
+ register('t3d.scene', 'react', SceneView as never);
package/todo/client.ts ADDED
@@ -0,0 +1,2 @@
1
+ import './types';
2
+ import './view';