@treenity/core 1.0.48 → 3.0.0

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 (696) hide show
  1. package/dist/chain.d.ts +20 -0
  2. package/dist/chain.d.ts.map +1 -0
  3. package/dist/chain.js +59 -0
  4. package/dist/chain.js.map +1 -0
  5. package/dist/client/handle.d.ts +13 -0
  6. package/dist/client/handle.d.ts.map +1 -0
  7. package/dist/client/handle.js +46 -0
  8. package/dist/client/handle.js.map +1 -0
  9. package/dist/client/index.d.ts +21 -0
  10. package/dist/client/index.d.ts.map +1 -0
  11. package/dist/client/index.js +5 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/client/trpc.d.ts +13 -0
  14. package/dist/client/trpc.d.ts.map +1 -0
  15. package/dist/client/trpc.js +78 -0
  16. package/dist/client/trpc.js.map +1 -0
  17. package/dist/client.d.ts +2 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +2 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/comp/handle.d.ts +14 -0
  22. package/dist/comp/handle.d.ts.map +1 -0
  23. package/dist/comp/handle.js +21 -0
  24. package/dist/comp/handle.js.map +1 -0
  25. package/dist/comp/index.d.ts +42 -0
  26. package/dist/comp/index.d.ts.map +1 -0
  27. package/dist/comp/index.js +126 -0
  28. package/dist/comp/index.js.map +1 -0
  29. package/dist/comp/needs.d.ts +26 -0
  30. package/dist/comp/needs.d.ts.map +1 -0
  31. package/dist/comp/needs.js +101 -0
  32. package/dist/comp/needs.js.map +1 -0
  33. package/dist/comp/validate.d.ts +13 -0
  34. package/dist/comp/validate.d.ts.map +1 -0
  35. package/dist/comp/validate.js +117 -0
  36. package/dist/comp/validate.js.map +1 -0
  37. package/dist/comp.d.ts +2 -0
  38. package/dist/comp.d.ts.map +1 -0
  39. package/dist/comp.js +2 -0
  40. package/dist/comp.js.map +1 -0
  41. package/dist/contexts/schema/index.d.ts +7 -0
  42. package/dist/contexts/schema/index.d.ts.map +1 -0
  43. package/dist/contexts/schema/index.js +2 -0
  44. package/dist/contexts/schema/index.js.map +1 -0
  45. package/dist/contexts/schema.d.ts +2 -0
  46. package/dist/contexts/schema.d.ts.map +1 -0
  47. package/dist/contexts/schema.js +2 -0
  48. package/dist/contexts/schema.js.map +1 -0
  49. package/dist/contexts/service/index.d.ts +31 -0
  50. package/dist/contexts/service/index.d.ts.map +1 -0
  51. package/dist/contexts/service/index.js +16 -0
  52. package/dist/contexts/service/index.js.map +1 -0
  53. package/dist/contexts/service.d.ts +1 -14
  54. package/dist/contexts/service.d.ts.map +1 -1
  55. package/dist/contexts/service.js +2 -0
  56. package/dist/contexts/service.js.map +1 -0
  57. package/dist/contexts/telegram/index.d.ts +19 -0
  58. package/dist/contexts/telegram/index.d.ts.map +1 -0
  59. package/dist/contexts/telegram/index.js +89 -0
  60. package/dist/contexts/telegram/index.js.map +1 -0
  61. package/dist/contexts/text/index.d.ts +7 -0
  62. package/dist/contexts/text/index.d.ts.map +1 -0
  63. package/dist/contexts/text/index.js +9 -0
  64. package/dist/contexts/text/index.js.map +1 -0
  65. package/dist/contexts/text.d.ts +2 -0
  66. package/dist/contexts/text.d.ts.map +1 -0
  67. package/dist/contexts/text.js +2 -0
  68. package/dist/contexts/text.js.map +1 -0
  69. package/dist/core/component.d.ts +41 -0
  70. package/dist/core/component.d.ts.map +1 -0
  71. package/dist/core/component.js +105 -0
  72. package/dist/core/component.js.map +1 -0
  73. package/dist/core/context.d.ts +5 -0
  74. package/dist/core/context.d.ts.map +1 -0
  75. package/dist/core/context.js +3 -0
  76. package/dist/core/context.js.map +1 -0
  77. package/dist/core/index.d.ts +5 -0
  78. package/dist/core/index.d.ts.map +1 -0
  79. package/dist/core/index.js +8 -0
  80. package/dist/core/index.js.map +1 -0
  81. package/dist/core/path.d.ts +7 -0
  82. package/dist/core/path.d.ts.map +1 -0
  83. package/dist/core/path.js +37 -0
  84. package/dist/core/path.js.map +1 -0
  85. package/dist/core/registry.d.ts +16 -0
  86. package/dist/core/registry.d.ts.map +1 -0
  87. package/dist/core/registry.js +100 -0
  88. package/dist/core/registry.js.map +1 -0
  89. package/dist/core.d.ts +2 -0
  90. package/dist/core.d.ts.map +1 -0
  91. package/dist/core.js +2 -0
  92. package/dist/core.js.map +1 -0
  93. package/dist/log.d.ts +8 -0
  94. package/dist/log.d.ts.map +1 -0
  95. package/dist/log.js +31 -0
  96. package/dist/log.js.map +1 -0
  97. package/dist/mod/discover.d.ts +4 -0
  98. package/dist/mod/discover.d.ts.map +1 -0
  99. package/dist/mod/discover.js +103 -0
  100. package/dist/mod/discover.js.map +1 -0
  101. package/dist/mod/examples/ticker/seed.d.ts +3 -0
  102. package/dist/mod/examples/ticker/seed.d.ts.map +1 -0
  103. package/dist/mod/examples/ticker/seed.js +16 -0
  104. package/dist/mod/examples/ticker/seed.js.map +1 -0
  105. package/dist/mod/examples/ticker/service.d.ts +2 -0
  106. package/dist/mod/examples/ticker/service.d.ts.map +1 -0
  107. package/dist/mod/examples/ticker/service.js +18 -0
  108. package/dist/mod/examples/ticker/service.js.map +1 -0
  109. package/dist/mod/examples/ticker/types.d.ts +16 -0
  110. package/dist/mod/examples/ticker/types.d.ts.map +1 -0
  111. package/dist/mod/examples/ticker/types.js +20 -0
  112. package/dist/mod/examples/ticker/types.js.map +1 -0
  113. package/dist/mod/examples/ticker/view.d.ts +2 -0
  114. package/dist/mod/examples/ticker/view.d.ts.map +1 -0
  115. package/dist/mod/examples/ticker/view.js +10 -0
  116. package/dist/mod/examples/ticker/view.js.map +1 -0
  117. package/dist/mod/index.d.ts +11 -0
  118. package/dist/mod/index.d.ts.map +1 -0
  119. package/dist/mod/index.js +8 -0
  120. package/dist/mod/index.js.map +1 -0
  121. package/dist/mod/loader.d.ts +18 -0
  122. package/dist/mod/loader.d.ts.map +1 -0
  123. package/dist/mod/loader.js +154 -0
  124. package/dist/mod/loader.js.map +1 -0
  125. package/dist/mod/optimistic.d.ts +34 -0
  126. package/dist/mod/optimistic.d.ts.map +1 -0
  127. package/dist/mod/optimistic.js +176 -0
  128. package/dist/mod/optimistic.js.map +1 -0
  129. package/dist/mod/prefab.d.ts +18 -0
  130. package/dist/mod/prefab.d.ts.map +1 -0
  131. package/dist/mod/prefab.js +42 -0
  132. package/dist/mod/prefab.js.map +1 -0
  133. package/dist/mod/tracking.d.ts +8 -0
  134. package/dist/mod/tracking.d.ts.map +1 -0
  135. package/dist/mod/tracking.js +44 -0
  136. package/dist/mod/tracking.js.map +1 -0
  137. package/dist/mod/types.d.ts +31 -0
  138. package/dist/mod/types.d.ts.map +1 -0
  139. package/dist/mod/types.js +5 -0
  140. package/dist/mod/types.js.map +1 -0
  141. package/dist/mod.d.ts +2 -0
  142. package/dist/mod.d.ts.map +1 -0
  143. package/dist/mod.js +2 -0
  144. package/dist/mod.js.map +1 -0
  145. package/dist/mods/autostart/server.d.ts +2 -0
  146. package/dist/mods/autostart/server.d.ts.map +1 -0
  147. package/dist/mods/autostart/server.js +2 -0
  148. package/dist/mods/autostart/server.js.map +1 -0
  149. package/dist/mods/autostart/service.d.ts +14 -0
  150. package/dist/mods/autostart/service.d.ts.map +1 -0
  151. package/dist/mods/autostart/service.js +88 -0
  152. package/dist/mods/autostart/service.js.map +1 -0
  153. package/dist/mods/llm/index.d.ts +13 -0
  154. package/dist/mods/llm/index.d.ts.map +1 -0
  155. package/dist/mods/llm/index.js +43 -0
  156. package/dist/mods/llm/index.js.map +1 -0
  157. package/dist/mods/llm/server.d.ts +2 -0
  158. package/dist/mods/llm/server.d.ts.map +1 -0
  159. package/dist/mods/llm/server.js +2 -0
  160. package/dist/mods/llm/server.js.map +1 -0
  161. package/dist/mods/mcp/server.d.ts +3 -0
  162. package/dist/mods/mcp/server.d.ts.map +1 -0
  163. package/dist/mods/mcp/server.js +3 -0
  164. package/dist/mods/mcp/server.js.map +1 -0
  165. package/dist/mods/mcp/service.d.ts +2 -0
  166. package/dist/mods/mcp/service.d.ts.map +1 -0
  167. package/dist/mods/mcp/service.js +17 -0
  168. package/dist/mods/mcp/service.js.map +1 -0
  169. package/dist/mods/mcp/types.d.ts +5 -0
  170. package/dist/mods/mcp/types.d.ts.map +1 -0
  171. package/dist/mods/mcp/types.js +7 -0
  172. package/dist/mods/mcp/types.js.map +1 -0
  173. package/dist/mods/treenity/agent-port.d.ts +2 -0
  174. package/dist/mods/treenity/agent-port.d.ts.map +1 -0
  175. package/dist/mods/treenity/agent-port.js +76 -0
  176. package/dist/mods/treenity/agent-port.js.map +1 -0
  177. package/dist/mods/treenity/groups.d.ts +2 -0
  178. package/dist/mods/treenity/groups.d.ts.map +1 -0
  179. package/dist/mods/treenity/groups.js +18 -0
  180. package/dist/mods/treenity/groups.js.map +1 -0
  181. package/dist/mods/treenity/mod-type.d.ts +2 -0
  182. package/dist/mods/treenity/mod-type.d.ts.map +1 -0
  183. package/dist/mods/treenity/mod-type.js +9 -0
  184. package/dist/mods/treenity/mod-type.js.map +1 -0
  185. package/dist/mods/treenity/seed.d.ts +2 -0
  186. package/dist/mods/treenity/seed.d.ts.map +1 -0
  187. package/dist/mods/treenity/seed.js +53 -0
  188. package/dist/mods/treenity/seed.js.map +1 -0
  189. package/dist/mods/treenity/server.d.ts +5 -0
  190. package/dist/mods/treenity/server.d.ts.map +1 -0
  191. package/dist/mods/treenity/server.js +5 -0
  192. package/dist/mods/treenity/server.js.map +1 -0
  193. package/dist/mods/treenity/system.d.ts +36 -0
  194. package/dist/mods/treenity/system.d.ts.map +1 -0
  195. package/dist/mods/treenity/system.js +61 -0
  196. package/dist/mods/treenity/system.js.map +1 -0
  197. package/dist/mods/uix/client.d.ts +3 -0
  198. package/dist/mods/uix/client.d.ts.map +1 -0
  199. package/dist/mods/uix/client.js +96 -0
  200. package/dist/mods/uix/client.js.map +1 -0
  201. package/dist/mods/uix/compile.d.ts +7 -0
  202. package/dist/mods/uix/compile.d.ts.map +1 -0
  203. package/dist/mods/uix/compile.js +94 -0
  204. package/dist/mods/uix/compile.js.map +1 -0
  205. package/dist/mods/uix/jsx-parser.d.ts +2 -0
  206. package/dist/mods/uix/jsx-parser.d.ts.map +1 -0
  207. package/dist/mods/uix/jsx-parser.js +565 -0
  208. package/dist/mods/uix/jsx-parser.js.map +1 -0
  209. package/dist/mods/uix/verify.d.ts +7 -0
  210. package/dist/mods/uix/verify.d.ts.map +1 -0
  211. package/dist/mods/uix/verify.js +59 -0
  212. package/dist/mods/uix/verify.js.map +1 -0
  213. package/dist/schema/catalog.d.ts +23 -0
  214. package/dist/schema/catalog.d.ts.map +1 -0
  215. package/dist/schema/catalog.js +82 -0
  216. package/dist/schema/catalog.js.map +1 -0
  217. package/dist/schema/extract-schemas.d.ts +5 -0
  218. package/dist/schema/extract-schemas.d.ts.map +1 -0
  219. package/dist/schema/extract-schemas.js +444 -0
  220. package/dist/schema/extract-schemas.js.map +1 -0
  221. package/dist/schema/load.d.ts +2 -0
  222. package/dist/schema/load.d.ts.map +1 -0
  223. package/dist/schema/load.js +23 -0
  224. package/dist/schema/load.js.map +1 -0
  225. package/dist/schema/test-fixture.types.d.ts +2 -0
  226. package/dist/schema/test-fixture.types.d.ts.map +1 -0
  227. package/dist/schema/test-fixture.types.js +19 -0
  228. package/dist/schema/test-fixture.types.js.map +1 -0
  229. package/dist/schema/test-opaque.d.ts +3 -0
  230. package/dist/schema/test-opaque.d.ts.map +1 -0
  231. package/dist/schema/test-opaque.js +43 -0
  232. package/dist/schema/test-opaque.js.map +1 -0
  233. package/dist/schema/types.d.ts +37 -0
  234. package/dist/schema/types.d.ts.map +1 -0
  235. package/dist/schema/types.js +3 -0
  236. package/dist/schema/types.js.map +1 -0
  237. package/dist/server/actions.d.ts +35 -0
  238. package/dist/server/actions.d.ts.map +1 -0
  239. package/dist/server/actions.js +170 -0
  240. package/dist/server/actions.js.map +1 -0
  241. package/dist/server/agent.d.ts +6 -0
  242. package/dist/server/agent.d.ts.map +1 -0
  243. package/dist/server/agent.js +15 -0
  244. package/dist/server/agent.js.map +1 -0
  245. package/dist/server/auth.d.ts +39 -0
  246. package/dist/server/auth.d.ts.map +1 -0
  247. package/dist/server/auth.js +335 -0
  248. package/dist/server/auth.js.map +1 -0
  249. package/dist/server/client.d.ts +183 -0
  250. package/dist/server/client.d.ts.map +1 -0
  251. package/dist/server/client.js +22 -0
  252. package/dist/server/client.js.map +1 -0
  253. package/dist/server/cookies.d.ts +5 -0
  254. package/dist/server/cookies.d.ts.map +1 -0
  255. package/dist/server/cookies.js +24 -0
  256. package/dist/server/cookies.js.map +1 -0
  257. package/dist/server/doc-index.d.ts +38 -0
  258. package/dist/server/doc-index.d.ts.map +1 -0
  259. package/dist/server/doc-index.js +244 -0
  260. package/dist/server/doc-index.js.map +1 -0
  261. package/dist/server/errors.d.ts +7 -0
  262. package/dist/server/errors.d.ts.map +1 -0
  263. package/dist/server/errors.js +11 -0
  264. package/dist/server/errors.js.map +1 -0
  265. package/dist/server/factory.d.ts +23 -0
  266. package/dist/server/factory.d.ts.map +1 -0
  267. package/dist/server/factory.js +70 -0
  268. package/dist/server/factory.js.map +1 -0
  269. package/dist/server/main.d.ts +6 -0
  270. package/dist/server/main.d.ts.map +1 -0
  271. package/dist/server/main.js +45 -0
  272. package/dist/server/main.js.map +1 -0
  273. package/dist/server/mcp.d.ts +5 -0
  274. package/dist/server/mcp.d.ts.map +1 -0
  275. package/dist/server/mcp.js +280 -0
  276. package/dist/server/mcp.js.map +1 -0
  277. package/dist/server/migrate.d.ts +3 -0
  278. package/dist/server/migrate.d.ts.map +1 -0
  279. package/dist/server/migrate.js +56 -0
  280. package/dist/server/migrate.js.map +1 -0
  281. package/dist/server/mod-catalog.d.ts +14 -0
  282. package/dist/server/mod-catalog.d.ts.map +1 -0
  283. package/dist/server/mod-catalog.js +40 -0
  284. package/dist/server/mod-catalog.js.map +1 -0
  285. package/dist/server/mods-mount.d.ts +4 -0
  286. package/dist/server/mods-mount.d.ts.map +1 -0
  287. package/dist/server/mods-mount.js +169 -0
  288. package/dist/server/mods-mount.js.map +1 -0
  289. package/dist/server/mount-adapters.d.ts +9 -0
  290. package/dist/server/mount-adapters.d.ts.map +1 -0
  291. package/dist/server/mount-adapters.js +75 -0
  292. package/dist/server/mount-adapters.js.map +1 -0
  293. package/dist/server/mount.d.ts +3 -0
  294. package/dist/server/mount.d.ts.map +1 -0
  295. package/dist/server/mount.js +195 -0
  296. package/dist/server/mount.js.map +1 -0
  297. package/dist/server/prefab.d.ts +18 -0
  298. package/dist/server/prefab.d.ts.map +1 -0
  299. package/dist/server/prefab.js +70 -0
  300. package/dist/server/prefab.js.map +1 -0
  301. package/dist/server/seed/index.d.ts +6 -0
  302. package/dist/server/seed/index.d.ts.map +1 -0
  303. package/dist/server/seed/index.js +16 -0
  304. package/dist/server/seed/index.js.map +1 -0
  305. package/dist/server/server.d.ts +28 -0
  306. package/dist/server/server.d.ts.map +1 -0
  307. package/dist/server/server.js +117 -0
  308. package/dist/server/server.js.map +1 -0
  309. package/dist/server/sub.d.ts +34 -0
  310. package/dist/server/sub.d.ts.map +1 -0
  311. package/dist/server/sub.js +174 -0
  312. package/dist/server/sub.js.map +1 -0
  313. package/dist/server/trpc.d.ts +192 -0
  314. package/dist/server/trpc.d.ts.map +1 -0
  315. package/dist/server/trpc.js +319 -0
  316. package/dist/server/trpc.js.map +1 -0
  317. package/dist/server/types-mount.d.ts +3 -0
  318. package/dist/server/types-mount.d.ts.map +1 -0
  319. package/dist/server/types-mount.js +144 -0
  320. package/dist/server/types-mount.js.map +1 -0
  321. package/dist/server/validate.d.ts +3 -0
  322. package/dist/server/validate.d.ts.map +1 -0
  323. package/dist/server/validate.js +20 -0
  324. package/dist/server/validate.js.map +1 -0
  325. package/dist/server/volatile.d.ts +11 -0
  326. package/dist/server/volatile.d.ts.map +1 -0
  327. package/dist/server/volatile.js +26 -0
  328. package/dist/server/volatile.js.map +1 -0
  329. package/dist/server/watch.d.ts +23 -0
  330. package/dist/server/watch.d.ts.map +1 -0
  331. package/dist/server/watch.js +178 -0
  332. package/dist/server/watch.js.map +1 -0
  333. package/dist/tree/cache.d.ts +3 -0
  334. package/dist/tree/cache.d.ts.map +1 -0
  335. package/dist/tree/cache.js +48 -0
  336. package/dist/tree/cache.js.map +1 -0
  337. package/dist/tree/fs.d.ts +3 -0
  338. package/dist/tree/fs.d.ts.map +1 -0
  339. package/dist/tree/fs.js +274 -0
  340. package/dist/tree/fs.js.map +1 -0
  341. package/dist/tree/index.d.ts +38 -0
  342. package/dist/tree/index.d.ts.map +1 -0
  343. package/dist/tree/index.js +182 -0
  344. package/dist/tree/index.js.map +1 -0
  345. package/dist/tree/inflight.d.ts +2 -0
  346. package/dist/tree/inflight.d.ts.map +1 -0
  347. package/dist/tree/inflight.js +15 -0
  348. package/dist/tree/inflight.js.map +1 -0
  349. package/dist/tree/json-codec.d.ts +2 -0
  350. package/dist/tree/json-codec.d.ts.map +1 -0
  351. package/dist/tree/json-codec.js +13 -0
  352. package/dist/tree/json-codec.js.map +1 -0
  353. package/dist/tree/mimefs.d.ts +13 -0
  354. package/dist/tree/mimefs.d.ts.map +1 -0
  355. package/dist/tree/mimefs.js +124 -0
  356. package/dist/tree/mimefs.js.map +1 -0
  357. package/dist/tree/mongo.d.ts +5 -0
  358. package/dist/tree/mongo.d.ts.map +1 -0
  359. package/dist/tree/mongo.js +110 -0
  360. package/dist/tree/mongo.js.map +1 -0
  361. package/dist/tree/patch.d.ts +30 -0
  362. package/dist/tree/patch.d.ts.map +1 -0
  363. package/dist/tree/patch.js +112 -0
  364. package/dist/tree/patch.js.map +1 -0
  365. package/dist/tree/query.d.ts +12 -0
  366. package/dist/tree/query.d.ts.map +1 -0
  367. package/dist/tree/query.js +61 -0
  368. package/dist/tree/query.js.map +1 -0
  369. package/dist/tree/repath.d.ts +3 -0
  370. package/dist/tree/repath.d.ts.map +1 -0
  371. package/dist/tree/repath.js +38 -0
  372. package/dist/tree/repath.js.map +1 -0
  373. package/dist/tree-chain.d.ts +18 -0
  374. package/dist/tree-chain.d.ts.map +1 -0
  375. package/dist/tree-chain.js +109 -0
  376. package/dist/tree-chain.js.map +1 -0
  377. package/dist/tree.d.ts +2 -0
  378. package/dist/tree.d.ts.map +1 -0
  379. package/dist/tree.js +2 -0
  380. package/dist/tree.js.map +1 -0
  381. package/dist/uri.d.ts +11 -0
  382. package/dist/uri.d.ts.map +1 -0
  383. package/dist/uri.js +79 -0
  384. package/dist/uri.js.map +1 -0
  385. package/package.json +39 -40
  386. package/src/chain.test.ts +190 -0
  387. package/src/chain.ts +82 -0
  388. package/src/client/client.test.ts +192 -0
  389. package/src/client/handle.ts +53 -0
  390. package/src/client/index.ts +18 -0
  391. package/src/client/trpc.ts +91 -0
  392. package/src/client.ts +1 -0
  393. package/src/comp/CLAUDE.md +14 -0
  394. package/src/comp/handle.ts +36 -0
  395. package/src/comp/index.test.ts +129 -0
  396. package/src/comp/index.ts +175 -0
  397. package/src/comp/needs.test.ts +499 -0
  398. package/src/comp/needs.ts +113 -0
  399. package/src/comp/validate.test.ts +304 -0
  400. package/src/comp/validate.ts +125 -0
  401. package/src/comp.ts +1 -0
  402. package/src/contexts/schema/index.ts +7 -0
  403. package/src/contexts/schema.ts +1 -0
  404. package/src/contexts/service/index.test.ts +323 -0
  405. package/src/contexts/service/index.ts +43 -0
  406. package/src/contexts/service.ts +1 -0
  407. package/src/contexts/telegram/index.ts +115 -0
  408. package/src/contexts/text/index.test.ts +31 -0
  409. package/src/contexts/text/index.ts +18 -0
  410. package/src/contexts/text.ts +1 -0
  411. package/src/core/component.ts +151 -0
  412. package/src/core/context.ts +14 -0
  413. package/src/core/index.test.ts +203 -0
  414. package/src/core/index.ts +9 -0
  415. package/src/core/path.ts +35 -0
  416. package/src/core/registry.ts +115 -0
  417. package/src/core.ts +1 -0
  418. package/src/log.test.ts +70 -0
  419. package/src/log.ts +28 -0
  420. package/src/mod/discover.test.ts +133 -0
  421. package/src/mod/discover.ts +100 -0
  422. package/src/mod/docs/00-index.md +19 -0
  423. package/src/mod/docs/01-primitives.md +38 -0
  424. package/src/mod/docs/02-core-api.md +68 -0
  425. package/src/mod/docs/03-registry.md +30 -0
  426. package/src/mod/docs/04-store.md +62 -0
  427. package/src/mod/docs/05-comp.md +111 -0
  428. package/src/mod/docs/06-actions.md +193 -0
  429. package/src/mod/docs/07-realtime.md +100 -0
  430. package/src/mod/docs/08-services.md +33 -0
  431. package/src/mod/docs/09-mounts.md +43 -0
  432. package/src/mod/docs/10-acl.md +60 -0
  433. package/src/mod/docs/11-server.md +62 -0
  434. package/src/mod/docs/12-conventions.md +65 -0
  435. package/src/mod/docs/13-example.md +132 -0
  436. package/src/mod/docs/14-mod-format.md +304 -0
  437. package/src/mod/docs/15-documenting-types.md +156 -0
  438. package/src/mod/examples/ticker/seed.ts +19 -0
  439. package/src/mod/examples/ticker/service.ts +20 -0
  440. package/src/mod/examples/ticker/ticker.test.ts +18 -0
  441. package/src/mod/examples/ticker/types.ts +22 -0
  442. package/src/mod/examples/ticker/view.tsx +19 -0
  443. package/src/mod/index.ts +12 -0
  444. package/src/mod/loader.test.ts +168 -0
  445. package/src/mod/loader.ts +174 -0
  446. package/src/mod/optimistic.test.ts +446 -0
  447. package/src/mod/optimistic.ts +210 -0
  448. package/src/mod/prefab.ts +62 -0
  449. package/src/mod/tracking.test.ts +59 -0
  450. package/src/mod/tracking.ts +51 -0
  451. package/src/mod/types.ts +40 -0
  452. package/src/mod.ts +1 -0
  453. package/src/mods/autostart/CLAUDE.md +6 -0
  454. package/src/mods/autostart/autostart.test.ts +85 -0
  455. package/src/mods/autostart/server.ts +1 -0
  456. package/src/mods/autostart/service.ts +98 -0
  457. package/src/mods/llm/CLAUDE.md +6 -0
  458. package/src/mods/llm/index.ts +57 -0
  459. package/src/mods/llm/llm.test.ts +109 -0
  460. package/src/mods/llm/server.ts +1 -0
  461. package/src/mods/mcp/CLAUDE.md +6 -0
  462. package/src/mods/mcp/server.ts +2 -0
  463. package/src/mods/mcp/service.ts +19 -0
  464. package/src/mods/mcp/types.ts +7 -0
  465. package/src/mods/treenity/agent-port.ts +93 -0
  466. package/src/mods/treenity/groups.ts +19 -0
  467. package/src/mods/treenity/mod-type.ts +10 -0
  468. package/src/mods/treenity/seed.ts +56 -0
  469. package/src/mods/treenity/server.ts +4 -0
  470. package/src/mods/treenity/system.ts +70 -0
  471. package/src/mods/uix/CLAUDE.md +7 -0
  472. package/src/mods/uix/client.ts +117 -0
  473. package/src/mods/uix/compile.test.ts +228 -0
  474. package/src/mods/uix/compile.ts +110 -0
  475. package/src/mods/uix/jsx-parser.test.ts +554 -0
  476. package/src/mods/uix/jsx-parser.ts +489 -0
  477. package/src/mods/uix/lazy-load.test.ts +261 -0
  478. package/src/mods/uix/uix-repomix.md +3509 -0
  479. package/src/mods/uix/verify.ts +68 -0
  480. package/src/schema/CLAUDE.md +13 -0
  481. package/src/schema/catalog.ts +101 -0
  482. package/src/schema/extract-schemas.test.ts +84 -0
  483. package/src/schema/extract-schemas.ts +462 -0
  484. package/src/schema/generated/autostart.json +44 -0
  485. package/src/schema/generated/board.column.json +25 -0
  486. package/src/schema/generated/board.task.json +147 -0
  487. package/src/schema/generated/brahman.action.back.json +12 -0
  488. package/src/schema/generated/brahman.action.broadcast.json +31 -0
  489. package/src/schema/generated/brahman.action.call.json +57 -0
  490. package/src/schema/generated/brahman.action.emittext.json +23 -0
  491. package/src/schema/generated/brahman.action.eval.json +23 -0
  492. package/src/schema/generated/brahman.action.file.json +28 -0
  493. package/src/schema/generated/brahman.action.forward.json +29 -0
  494. package/src/schema/generated/brahman.action.getvalue.json +28 -0
  495. package/src/schema/generated/brahman.action.ifelse.json +42 -0
  496. package/src/schema/generated/brahman.action.keywordselect.json +46 -0
  497. package/src/schema/generated/brahman.action.message.json +127 -0
  498. package/src/schema/generated/brahman.action.onerror.json +29 -0
  499. package/src/schema/generated/brahman.action.page.json +22 -0
  500. package/src/schema/generated/brahman.action.params.json +36 -0
  501. package/src/schema/generated/brahman.action.question.json +43 -0
  502. package/src/schema/generated/brahman.action.remove.json +12 -0
  503. package/src/schema/generated/brahman.action.resethistory.json +12 -0
  504. package/src/schema/generated/brahman.action.resetsession.json +12 -0
  505. package/src/schema/generated/brahman.action.selectlang.json +20 -0
  506. package/src/schema/generated/brahman.action.setvalue.json +27 -0
  507. package/src/schema/generated/brahman.action.tag.json +27 -0
  508. package/src/schema/generated/brahman.bot.json +68 -0
  509. package/src/schema/generated/brahman.page.json +25 -0
  510. package/src/schema/generated/brahman.session.json +29 -0
  511. package/src/schema/generated/brahman.user.json +58 -0
  512. package/src/schema/generated/cafe.contact.json +56 -0
  513. package/src/schema/generated/cafe.mail.json +29 -0
  514. package/src/schema/generated/default.json +15 -0
  515. package/src/schema/generated/doc.page.json +23 -0
  516. package/src/schema/generated/examples.demo.generator.json +16 -0
  517. package/src/schema/generated/examples.demo.sensor.json +35 -0
  518. package/src/schema/generated/groups.json +20 -0
  519. package/src/schema/generated/launcher.json +91 -0
  520. package/src/schema/generated/mcp.server.json +15 -0
  521. package/src/schema/generated/mindmap.map.json +22 -0
  522. package/src/schema/generated/sim.agent.json +24 -0
  523. package/src/schema/generated/sim.ai.json +24 -0
  524. package/src/schema/generated/sim.config.json +38 -0
  525. package/src/schema/generated/sim.descriptive.json +26 -0
  526. package/src/schema/generated/sim.events.json +47 -0
  527. package/src/schema/generated/sim.item.json +20 -0
  528. package/src/schema/generated/sim.memory.json +17 -0
  529. package/src/schema/generated/sim.nearby.json +17 -0
  530. package/src/schema/generated/sim.position.json +25 -0
  531. package/src/schema/generated/sim.round.json +64 -0
  532. package/src/schema/generated/sim.world.json +32 -0
  533. package/src/schema/generated/t.agent.port.json +74 -0
  534. package/src/schema/generated/t.llm.json +20 -0
  535. package/src/schema/generated/t.mod.json +27 -0
  536. package/src/schema/generated/t3d.animator.json +46 -0
  537. package/src/schema/generated/t3d.audio.json +58 -0
  538. package/src/schema/generated/t3d.camera.json +50 -0
  539. package/src/schema/generated/t3d.collider.json +84 -0
  540. package/src/schema/generated/t3d.light.json +90 -0
  541. package/src/schema/generated/t3d.line.json +47 -0
  542. package/src/schema/generated/t3d.lod.json +28 -0
  543. package/src/schema/generated/t3d.material.json +131 -0
  544. package/src/schema/generated/t3d.mesh.json +65 -0
  545. package/src/schema/generated/t3d.object.json +64 -0
  546. package/src/schema/generated/t3d.particles.json +109 -0
  547. package/src/schema/generated/t3d.rigidbody.json +81 -0
  548. package/src/schema/generated/t3d.scene.json +7 -0
  549. package/src/schema/generated/t3d.script.json +23 -0
  550. package/src/schema/generated/t3d.text.json +86 -0
  551. package/src/schema/generated/t3d.trail.json +45 -0
  552. package/src/schema/generated/task.json +96 -0
  553. package/src/schema/generated/test.fixture.json +43 -0
  554. package/src/schema/generated/ticker.config.json +43 -0
  555. package/src/schema/generated/ticker.price.json +20 -0
  556. package/src/schema/generated/todo.item.json +25 -0
  557. package/src/schema/generated/todo.list.json +33 -0
  558. package/src/schema/generated/treenity.system.json +259 -0
  559. package/src/schema/generated/whisper.audio.json +25 -0
  560. package/src/schema/generated/whisper.checklist.json +17 -0
  561. package/src/schema/generated/whisper.config.json +30 -0
  562. package/src/schema/generated/whisper.inbox.json +24 -0
  563. package/src/schema/generated/whisper.meta.json +35 -0
  564. package/src/schema/generated/whisper.text.json +16 -0
  565. package/src/schema/load.ts +24 -0
  566. package/src/schema/schema.test.ts +86 -0
  567. package/src/schema/test-fixture.types.ts +21 -0
  568. package/src/schema/test-opaque.ts +42 -0
  569. package/src/schema/types.ts +33 -0
  570. package/src/server/CLAUDE.md +26 -0
  571. package/src/server/actions.test.ts +272 -0
  572. package/src/server/actions.ts +274 -0
  573. package/src/server/agent-sub.test.ts +90 -0
  574. package/src/server/agent.test.ts +305 -0
  575. package/src/server/agent.ts +17 -0
  576. package/src/server/api.test.ts +454 -0
  577. package/src/server/auth.test.ts +441 -0
  578. package/src/server/auth.ts +386 -0
  579. package/src/server/client.ts +24 -0
  580. package/src/server/conditions.test.ts +128 -0
  581. package/src/server/cookies.ts +25 -0
  582. package/src/server/coverage.test.ts +827 -0
  583. package/src/server/doc-index.ts +286 -0
  584. package/src/server/e2e.test.ts +966 -0
  585. package/src/server/errors.ts +11 -0
  586. package/src/server/factory.ts +99 -0
  587. package/src/server/main.ts +56 -0
  588. package/src/server/mcp.ts +326 -0
  589. package/src/server/migrate.test.ts +123 -0
  590. package/src/server/migrate.ts +62 -0
  591. package/src/server/mod-catalog.ts +59 -0
  592. package/src/server/mods-mount.ts +179 -0
  593. package/src/server/mount-adapters.ts +82 -0
  594. package/src/server/mount.parametrized.test.ts +52 -0
  595. package/src/server/mount.query.test.ts +127 -0
  596. package/src/server/mount.test.ts +497 -0
  597. package/src/server/mount.ts +208 -0
  598. package/src/server/prefab.test.ts +415 -0
  599. package/src/server/prefab.ts +104 -0
  600. package/src/server/seed/index.ts +24 -0
  601. package/src/server/server.ts +153 -0
  602. package/src/server/stress.test.ts +844 -0
  603. package/src/server/sub.test.ts +55 -0
  604. package/src/server/sub.ts +224 -0
  605. package/src/server/trpc.ts +369 -0
  606. package/src/server/types-mount.ts +142 -0
  607. package/src/server/validate.test.ts +91 -0
  608. package/src/server/validate.ts +22 -0
  609. package/src/server/volatile.test.ts +140 -0
  610. package/src/server/volatile.ts +32 -0
  611. package/src/server/watch.test.ts +594 -0
  612. package/src/server/watch.ts +202 -0
  613. package/src/server/workflow.test.ts +82 -0
  614. package/src/tree/CLAUDE.md +13 -0
  615. package/src/tree/cache.test.ts +213 -0
  616. package/src/tree/cache.ts +51 -0
  617. package/src/tree/fs.test.ts +247 -0
  618. package/src/tree/fs.ts +251 -0
  619. package/src/tree/index.test.ts +164 -0
  620. package/src/tree/index.ts +216 -0
  621. package/src/tree/inflight.ts +15 -0
  622. package/src/tree/json-codec.ts +16 -0
  623. package/src/tree/mimefs.test.ts +289 -0
  624. package/src/tree/mimefs.ts +142 -0
  625. package/src/tree/mongo.ts +125 -0
  626. package/src/tree/patch.test.ts +192 -0
  627. package/src/tree/patch.ts +133 -0
  628. package/src/tree/query.test.ts +110 -0
  629. package/src/tree/query.ts +70 -0
  630. package/src/tree/repath.test.ts +86 -0
  631. package/src/tree/repath.ts +53 -0
  632. package/src/tree-chain.test.ts +723 -0
  633. package/src/tree-chain.ts +144 -0
  634. package/src/tree.ts +1 -0
  635. package/src/uri.test.ts +86 -0
  636. package/src/uri.ts +82 -0
  637. package/CHANGELOG.md +0 -314
  638. package/README.md +0 -18
  639. package/dist/context.d.ts +0 -41
  640. package/dist/context.d.ts.map +0 -1
  641. package/dist/context.mjs +0 -81
  642. package/dist/context.mjs.map +0 -1
  643. package/dist/contexts/node-engine.d.ts +0 -12
  644. package/dist/contexts/node-engine.d.ts.map +0 -1
  645. package/dist/contexts/node-engine.mjs +0 -7
  646. package/dist/contexts/node-engine.mjs.map +0 -1
  647. package/dist/contexts/noflo/types.d.ts +0 -20
  648. package/dist/contexts/noflo/types.d.ts.map +0 -1
  649. package/dist/contexts/object.d.ts +0 -11
  650. package/dist/contexts/object.d.ts.map +0 -1
  651. package/dist/contexts/object.mjs +0 -15
  652. package/dist/contexts/object.mjs.map +0 -1
  653. package/dist/contexts/proto.d.ts +0 -11
  654. package/dist/contexts/proto.d.ts.map +0 -1
  655. package/dist/contexts/proto.mjs +0 -7
  656. package/dist/contexts/proto.mjs.map +0 -1
  657. package/dist/contexts/react-context.d.ts +0 -21
  658. package/dist/contexts/react-context.d.ts.map +0 -1
  659. package/dist/contexts/react-context.mjs +0 -24
  660. package/dist/contexts/react-context.mjs.map +0 -1
  661. package/dist/contexts/service.mjs +0 -7
  662. package/dist/contexts/service.mjs.map +0 -1
  663. package/dist/get-type-cache.d.ts +0 -2
  664. package/dist/get-type-cache.d.ts.map +0 -1
  665. package/dist/get-type-cache.mjs +0 -7
  666. package/dist/get-type-cache.mjs.map +0 -1
  667. package/dist/index.d.ts +0 -13
  668. package/dist/index.d.ts.map +0 -1
  669. package/dist/index.mjs +0 -10
  670. package/dist/index.mjs.map +0 -1
  671. package/dist/link/link.d.ts +0 -25
  672. package/dist/link/link.d.ts.map +0 -1
  673. package/dist/link/link.mjs +0 -72
  674. package/dist/link/link.mjs.map +0 -1
  675. package/dist/link/link.test.d.ts +0 -2
  676. package/dist/link/link.test.d.ts.map +0 -1
  677. package/dist/loading.d.ts +0 -9
  678. package/dist/loading.d.ts.map +0 -1
  679. package/dist/meta-type.d.ts +0 -58
  680. package/dist/meta-type.d.ts.map +0 -1
  681. package/dist/meta-type.mjs +0 -104
  682. package/dist/meta-type.mjs.map +0 -1
  683. package/dist/meta.d.ts +0 -20
  684. package/dist/meta.d.ts.map +0 -1
  685. package/dist/meta.mjs +0 -16
  686. package/dist/meta.mjs.map +0 -1
  687. package/dist/node/index.d.ts +0 -2
  688. package/dist/node/index.d.ts.map +0 -1
  689. package/dist/node/types.d.ts +0 -37
  690. package/dist/node/types.d.ts.map +0 -1
  691. package/dist/test/context.test.d.ts +0 -2
  692. package/dist/test/context.test.d.ts.map +0 -1
  693. package/dist/types.d.ts +0 -14
  694. package/dist/types.d.ts.map +0 -1
  695. package/dist/types.mjs +0 -16
  696. package/dist/types.mjs.map +0 -1
@@ -0,0 +1,190 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { chain, refVal, runPathWithRefs, TypedRef } from './chain';
4
+
5
+ // ── basic ──
6
+
7
+ test('sync field', async () => {
8
+ assert.equal(await chain({ name: 'Alice' }).name, 'Alice')
9
+ })
10
+
11
+ test('sync method', async () => {
12
+ assert.equal(await chain({ greet: (n: string) => `hello ${n}` }).greet('Bob'), 'hello Bob')
13
+ })
14
+
15
+ test('async field', async () => {
16
+ assert.equal(await chain({ fetch: async () => 42 }).fetch(), 42)
17
+ })
18
+
19
+ test('deep sync chain', async () => {
20
+ const obj = { user: { profile: { name: 'Alice' } } }
21
+ assert.equal(await chain(obj).user.profile.name, 'Alice')
22
+ })
23
+
24
+ test('deep async chain', async () => {
25
+ const obj = {
26
+ user: async (id: string) => ({
27
+ id,
28
+ posts: async () => [{ title: 'Hello' }, { title: 'World' }],
29
+ }),
30
+ }
31
+ const posts = await chain(obj).user('123').posts()
32
+ assert.deepEqual(posts, [{ title: 'Hello' }, { title: 'World' }])
33
+ })
34
+
35
+ test('method chaining returns new chain', async () => {
36
+ const obj = {
37
+ add: (n: number) => ({
38
+ multiply: (m: number) => n * m,
39
+ }),
40
+ }
41
+ assert.equal(await chain(obj).add(3).multiply(4), 12)
42
+ })
43
+
44
+ test('this binding preserved', async () => {
45
+ const obj = { value: 42, get() { return this.value } }
46
+ assert.equal(await chain(obj).get(), 42)
47
+ })
48
+
49
+ test('null in chain throws', async () => {
50
+ await assert.rejects(
51
+ async () => { await chain({ user: null } as any).user.name },
52
+ )
53
+ })
54
+
55
+ test('same chain reusable', async () => {
56
+ let callCount = 0
57
+ const obj = { fetch: async () => { callCount++; return callCount } }
58
+ const c = chain(obj).fetch()
59
+ assert.equal(await c, 1)
60
+ assert.equal(await c, 2) // no caching — executes again
61
+ })
62
+
63
+ test('async error propagates', async () => {
64
+ const obj = { fail: async () => { throw new Error('boom') } }
65
+ await assert.rejects(async () => { await chain(obj).fail() })
66
+ })
67
+
68
+ // ── demo tracker component types ──
69
+
70
+ class LivePrices {
71
+ static $type = 'demo.live-prices'
72
+ feederUrl = 'ws://localhost:8090'
73
+ async subscribe({ slugs }: { slugs: string[] }) {
74
+ return slugs.map(s => ({ slug: s, bid: 0.6, ask: 0.65 }))
75
+ }
76
+ }
77
+
78
+ class Scanner {
79
+ static $type = 'demo.scanner'
80
+ intervalMs = 900_000
81
+ livePrices: TypedRef<LivePrices> = refVal(LivePrices, '/demo/live-prices')
82
+ depositTracker: TypedRef<DepositTracker> = refVal(DepositTracker, '/demo/deposits')
83
+ }
84
+
85
+ class DepositTracker {
86
+ static $type = 'demo.deposit-tracker'
87
+ async run() { return { added: 12, ts: Date.now() } }
88
+ }
89
+
90
+ class Profile {
91
+ static $type = 'demo.profile'
92
+ address = ''
93
+ async fetch({ address }: { address: string }) {
94
+ return { address, name: 'whale.eth', totalPnl: 50_000 }
95
+ }
96
+ async trades({ page = 1 } = {}) {
97
+ return { page, items: [{ hash: '0xabc', amount: 1000 }] }
98
+ }
99
+ }
100
+
101
+ // ── refVal ──
102
+
103
+ test('refVal stores $type and $ref', () => {
104
+ const ref = refVal(LivePrices, '/demo/live-prices')
105
+ assert.equal(ref.$type, 'ref')
106
+ assert.equal(ref.$ref, '/demo/live-prices')
107
+ })
108
+
109
+ test('refVal default path is empty', () => {
110
+ const ref = refVal(LivePrices)
111
+ assert.equal(ref.$ref, '')
112
+ })
113
+
114
+ // ── server executor: auto-resolves refs ──
115
+
116
+ function makeStore(entries: [string, any][]) {
117
+ const m = new Map(entries)
118
+ return (ref: { $ref: string }) => {
119
+ const node = m.get(ref.$ref)
120
+ if (!node) throw new Error(`Ref not found: ${ref.$ref}`)
121
+ return Promise.resolve(node)
122
+ }
123
+ }
124
+
125
+ test('runPathWithRefs: follows ref to node', async () => {
126
+ const live = new LivePrices()
127
+ const scanner = new Scanner()
128
+
129
+ const result = await runPathWithRefs(
130
+ scanner,
131
+ ['livePrices', 'subscribe', [{ slugs: ['btc-win'] }]],
132
+ makeStore([['/demo/live-prices', live]]),
133
+ )
134
+
135
+ assert.deepEqual(result, [{ slug: 'btc-win', bid: 0.6, ask: 0.65 }])
136
+ })
137
+
138
+ test('runPathWithRefs: multiple refs in one session', async () => {
139
+ const live = new LivePrices()
140
+ const deposits = new DepositTracker()
141
+ const scanner = new Scanner()
142
+ const resolve = makeStore([
143
+ ['/demo/live-prices', live],
144
+ ['/demo/deposits', deposits],
145
+ ])
146
+
147
+ const prices = await runPathWithRefs(scanner, ['livePrices', 'subscribe', [{ slugs: ['x'] }]], resolve)
148
+ const run = await runPathWithRefs(scanner, ['depositTracker', 'run', []], resolve)
149
+
150
+ assert.ok(Array.isArray(prices))
151
+ assert.equal(run.added, 12)
152
+ })
153
+
154
+ test('runPathWithRefs: nested refs (ref → node → ref → node)', async () => {
155
+ const profile = new Profile()
156
+ // live node has a nested ref to profile
157
+ const liveNode = { profile: { $type: 'ref', $ref: '/demo/profiles/0xabc' } }
158
+ const scanner = { live: { $type: 'ref', $ref: '/demo/live' } }
159
+
160
+ const result = await runPathWithRefs(
161
+ scanner,
162
+ ['live', 'profile', 'fetch', [{ address: '0xabc' }]],
163
+ makeStore([
164
+ ['/demo/live', liveNode],
165
+ ['/demo/profiles/0xabc', profile],
166
+ ]),
167
+ )
168
+
169
+ assert.deepEqual(result, { address: '0xabc', name: 'whale.eth', totalPnl: 50_000 })
170
+ })
171
+
172
+ test('runPathWithRefs: missing ref throws', async () => {
173
+ const scanner = new Scanner()
174
+ await assert.rejects(
175
+ () => runPathWithRefs(scanner, ['livePrices', 'subscribe', [{ slugs: [] }]], makeStore([])),
176
+ )
177
+ })
178
+
179
+ test('runPathWithRefs: profile trades pagination', async () => {
180
+ const profile = new Profile()
181
+ const node = { target: { $type: 'ref', $ref: '/profile' } }
182
+
183
+ const result = await runPathWithRefs(
184
+ node,
185
+ ['target', 'trades', [{ page: 2 }]],
186
+ makeStore([['/profile', profile]]),
187
+ )
188
+
189
+ assert.deepEqual(result, { page: 2, items: [{ hash: '0xabc', amount: 1000 }] })
190
+ })
package/src/chain.ts ADDED
@@ -0,0 +1,82 @@
1
+ // Minimal call-chain: records property/call path, resolves lazily on await.
2
+ // Ref resolution is opt-in via runPathWithRefs — chain itself is pure.
3
+
4
+ import { isRef } from '#core';
5
+
6
+ export type PathSection = string | unknown[]
7
+
8
+ // ── Types (mirrors call-chain library, no dep needed) ──
9
+
10
+ type Primitive = undefined | null | boolean | string | number | symbol | bigint | void
11
+
12
+ type ValuePromise<T> = T extends Primitive
13
+ ? Promise<T>
14
+ : T extends Promise<any>
15
+ ? T
16
+ : Chain<T>
17
+
18
+ export type Chain<T> = Promise<T> & {
19
+ [K in keyof T]: T[K] extends (...args: infer A) => infer R
20
+ ? (...args: A) => ValuePromise<Awaited<NonNullable<R>>>
21
+ : ValuePromise<Awaited<NonNullable<T[K]>>>
22
+ }
23
+
24
+ // TypedRef: runtime $ref + phantom type T for call-chain to follow
25
+ // _T is a phantom type — exists only for TypeScript inference, erased at runtime
26
+ export interface TypedRef<_T> {
27
+ readonly $type: 'ref'
28
+ $ref: string
29
+ }
30
+
31
+ // Pass registered class (has .$type stamped by registerType) for TypeScript type inference.
32
+ // Runtime only stores $ref — no class reference kept.
33
+ export function refVal<T>(Comp: (new () => T) & { $type?: string }, defaultPath = ''): TypedRef<T> {
34
+ void Comp // type-only at runtime; $type from registerType could be stored if needed
35
+ return { $type: 'ref', $ref: defaultPath }
36
+ }
37
+
38
+ // ── Core ──
39
+
40
+ export async function runPath(target: any, path: PathSection[]): Promise<any> {
41
+ let cur = target, prev = target
42
+ for (const step of path) {
43
+ if (cur == null) throw new Error(`null at step: ${JSON.stringify(step)}`)
44
+ if (typeof step === 'string') { prev = cur; cur = cur[step] }
45
+ else { cur = cur.apply(prev, step as any[]) }
46
+ if (cur?.then) cur = await cur
47
+ }
48
+ return cur
49
+ }
50
+
51
+ // Server executor: same as runPath but auto-follows TypedRef fields
52
+ export async function runPathWithRefs(
53
+ target: any,
54
+ path: PathSection[],
55
+ resolveRef: (ref: { $ref: string }) => Promise<any>,
56
+ ): Promise<any> {
57
+ let cur = target, prev = target
58
+ for (const step of path) {
59
+ if (cur == null) throw new Error(`null at step: ${JSON.stringify(step)}`)
60
+ if (typeof step === 'string') {
61
+ prev = cur
62
+ cur = cur[step]
63
+ if (isRef(cur)) cur = await resolveRef(cur)
64
+ } else {
65
+ cur = cur.apply(prev, step as any[])
66
+ }
67
+ if (cur?.then) cur = await cur
68
+ }
69
+ return cur
70
+ }
71
+
72
+ const make = (target: any, path: PathSection[]): any =>
73
+ new Proxy((() => {}) as any, {
74
+ get: (_, p: string | symbol) => {
75
+ if (p === 'then') return (res: any, rej: any) => runPath(target, path).then(res, rej)
76
+ if (typeof p === 'symbol') return undefined
77
+ return make(target, [...path, p as string])
78
+ },
79
+ apply: (_, __, args) => make(target, [...path, args]),
80
+ })
81
+
82
+ export const chain = <T>(target: T): Chain<T> => make(target, []) as Chain<T>
@@ -0,0 +1,192 @@
1
+ // Treenity Client SDK — e2e tests
2
+ // Tests createTrpcTransport + createRepathTree + t.mount.tree.trpc
3
+
4
+ import { registerType } from '#comp';
5
+ import { createNode, R, S, W } from '#core';
6
+ import { withMounts } from '#server/mount';
7
+ import '#server/mount-adapters';
8
+ import { createTreenityServer } from '#server/server';
9
+ import { createMemoryTree } from '#tree';
10
+ import { createRepathTree } from '#tree/repath';
11
+ import assert from 'node:assert/strict';
12
+ import type { Socket } from 'node:net';
13
+ import { afterEach, before, beforeEach, describe, it } from 'node:test';
14
+ import { createTrpcTransport } from './trpc';
15
+
16
+ // ── Helpers ──
17
+
18
+ function listen(server: import('node:http').Server): Promise<number> {
19
+ return new Promise((resolve) => {
20
+ server.listen(0, '127.0.0.1', () => {
21
+ resolve((server.address() as { port: number }).port);
22
+ });
23
+ });
24
+ }
25
+
26
+ // ── Test type ──
27
+
28
+ class Counter {
29
+ count = 0;
30
+ increment() { this.count++; }
31
+ }
32
+
33
+ describe('Treenity Client SDK', () => {
34
+ let ts: ReturnType<typeof createTreenityServer>;
35
+ let url: string;
36
+ const sockets = new Set<Socket>();
37
+
38
+ before(() => {
39
+ registerType('counter', Counter);
40
+ });
41
+
42
+ beforeEach(async () => {
43
+ const bootstrap = createMemoryTree();
44
+ await bootstrap.set({
45
+ ...createNode('/', 'root'),
46
+ $acl: [{ g: 'public', p: R | W | S }],
47
+ });
48
+
49
+ ts = createTreenityServer(bootstrap);
50
+ ts.server.on('connection', (s: Socket) => {
51
+ sockets.add(s);
52
+ s.on('close', () => sockets.delete(s));
53
+ });
54
+ const port = await listen(ts.server);
55
+ url = `http://127.0.0.1:${port}`;
56
+ });
57
+
58
+ afterEach(async () => {
59
+ for (const s of sockets) s.destroy();
60
+ sockets.clear();
61
+ await new Promise<void>((r) => ts.server.close(() => r()));
62
+ });
63
+
64
+ // ── createTrpcTransport ──
65
+
66
+ describe('createTrpcTransport', () => {
67
+ it('tree.get + tree.set roundtrip', async () => {
68
+ const { tree } = createTrpcTransport({ url });
69
+ await tree.set(createNode('/hello', 'doc', { title: 'World' }));
70
+ const node = await tree.get('/hello');
71
+
72
+ assert.ok(node);
73
+ assert.equal(node.$type, 't.doc');
74
+ assert.equal((node as any).title, 'World');
75
+ });
76
+
77
+ it('tree.getChildren returns children', async () => {
78
+ const { tree } = createTrpcTransport({ url });
79
+ await tree.set(createNode('/items', 'dir'));
80
+ await tree.set(createNode('/items/a', 'doc'));
81
+ await tree.set(createNode('/items/b', 'doc'));
82
+
83
+ const { items } = await tree.getChildren('/items');
84
+ assert.equal(items.length, 2);
85
+ });
86
+
87
+ it('tree.remove deletes node', async () => {
88
+ const { tree } = createTrpcTransport({ url });
89
+ await tree.set(createNode('/tmp', 'doc'));
90
+ await tree.remove('/tmp');
91
+
92
+ assert.equal(await tree.get('/tmp'), undefined);
93
+ });
94
+
95
+ it('execute calls action', async () => {
96
+ const { tree, execute } = createTrpcTransport({ url });
97
+ await tree.set(createNode('/c', 'counter', { count: 0 }));
98
+
99
+ await execute('/c', 'increment');
100
+
101
+ const node = await tree.get('/c');
102
+ assert.equal((node as any).count, 1);
103
+ });
104
+ });
105
+
106
+ // ── createRepathTree over tRPC ──
107
+
108
+ describe('createRepathTree + tRPC', () => {
109
+ it('translates paths over the wire', async () => {
110
+ const { tree: remote } = createTrpcTransport({ url });
111
+
112
+ // Write via server at absolute path
113
+ await remote.set(createNode('/data/item', 'doc', { v: 42 }));
114
+
115
+ // Mount remote's /data at local /mnt
116
+ const mounted = createRepathTree(remote, '/mnt', '/data');
117
+ const node = await mounted.get('/mnt/item');
118
+
119
+ assert.ok(node);
120
+ assert.equal(node.$path, '/mnt/item');
121
+ assert.equal((node as any).v, 42);
122
+ });
123
+
124
+ it('set through repath writes to correct remote path', async () => {
125
+ const { tree: remote } = createTrpcTransport({ url });
126
+ const mounted = createRepathTree(remote, '/mnt', '/store');
127
+
128
+ await mounted.set(createNode('/mnt/new', 'doc', { x: 1 }));
129
+
130
+ // Verify via direct remote access
131
+ const node = await remote.get('/store/new');
132
+ assert.ok(node);
133
+ assert.equal(node.$path, '/store/new');
134
+ });
135
+ });
136
+
137
+ // ── t.mount.tree.trpc ──
138
+
139
+ describe('t.mount.tree.trpc', () => {
140
+ it('mounts remote tree with path translation', async () => {
141
+ // Set up content on the remote server
142
+ const { tree: remote } = createTrpcTransport({ url });
143
+ await remote.set(createNode('/strategies/alpha', 'doc', { score: 99 }));
144
+
145
+ // Create a local bootstrap with mount pointing to remote
146
+ const local = createMemoryTree();
147
+ await local.set({
148
+ ...createNode('/', 'root'),
149
+ $acl: [{ g: 'public', p: R | W | S }],
150
+ });
151
+ await local.set({
152
+ $path: '/remote',
153
+ $type: 'dir',
154
+ mount: { $type: 't.mount.tree.trpc' },
155
+ connection: { $type: 'connection', url, path: '/strategies' },
156
+ });
157
+
158
+ const store = withMounts(local);
159
+ const node = await store.get('/remote/alpha');
160
+
161
+ assert.ok(node);
162
+ assert.equal(node.$path, '/remote/alpha');
163
+ assert.equal((node as any).score, 99);
164
+ });
165
+
166
+ it('getChildren through mount', async () => {
167
+ const { tree: remote } = createTrpcTransport({ url });
168
+ await remote.set(createNode('/items', 'dir'));
169
+ await remote.set(createNode('/items/x', 'doc'));
170
+ await remote.set(createNode('/items/y', 'doc'));
171
+
172
+ const local = createMemoryTree();
173
+ await local.set({
174
+ ...createNode('/', 'root'),
175
+ $acl: [{ g: 'public', p: R | W | S }],
176
+ });
177
+ await local.set({
178
+ $path: '/fed',
179
+ $type: 'dir',
180
+ mount: { $type: 't.mount.tree.trpc' },
181
+ connection: { $type: 'connection', url, path: '/items' },
182
+ });
183
+
184
+ const store = withMounts(local);
185
+ const { items } = await store.getChildren('/fed');
186
+
187
+ assert.equal(items.length, 2);
188
+ const paths = items.map(n => n.$path).sort();
189
+ assert.deepEqual(paths, ['/fed/x', '/fed/y']);
190
+ });
191
+ });
192
+ });
@@ -0,0 +1,53 @@
1
+ // Client node handle — typed access to remote nodes.
2
+ // nc(path).get(Type).method() — actions, no fetch needed.
3
+ // nc(path).fetch(Type) — async fetch + typed proxy.
4
+ // nc(path).sub(Type, cb) — reactive subscription with typed data.
5
+
6
+ import { type Class, type TypeProxy } from '#comp';
7
+ import { makeTypedProxy, type ExecuteFn } from '#comp/handle';
8
+ import type { NodeData } from '#core';
9
+ import type { TreenityClient } from './index';
10
+
11
+ export function createNodeClient(client: TreenityClient) {
12
+ const execute: ExecuteFn = (input) =>
13
+ client.execute(input.path, input.action, input.data, { type: input.type, key: input.key });
14
+
15
+ return (path: string) => ({
16
+ /** Typed actions proxy — calls execute over network, no fetch needed */
17
+ get<T extends object>(cls: Class<T>, key?: string): TypeProxy<T> {
18
+ return makeTypedProxy<T>(undefined, cls, path, execute, undefined, key);
19
+ },
20
+
21
+ /** Fetch node + typed proxy (data fields + action methods) */
22
+ async fetch<T extends object>(cls: Class<T>, key?: string): Promise<TypeProxy<T>> {
23
+ const node = await client.tree.get(path);
24
+ return makeTypedProxy<T>(node, cls, path, execute, undefined, key);
25
+ },
26
+
27
+ /** Subscribe — callback with typed proxy on each change */
28
+ async sub<T extends object>(cls: Class<T>, cb: (data: TypeProxy<T>) => void, key?: string) {
29
+ let cached: NodeData | undefined;
30
+
31
+ function notify() {
32
+ cb(makeTypedProxy<T>(cached, cls, path, execute, undefined, key));
33
+ }
34
+
35
+ const { node, unsubscribe } = await client.watchPath(path, (event) => {
36
+ if (event.type === 'set') {
37
+ cached = { $path: event.path, ...event.node } as NodeData;
38
+ notify();
39
+ }
40
+ if (event.type === 'patch' && cached) {
41
+ // Re-fetch on patch (optimize with applyPatch later)
42
+ client.tree.get(path).then(fresh => {
43
+ if (fresh) { cached = fresh; notify(); }
44
+ });
45
+ }
46
+ });
47
+
48
+ cached = node as NodeData | undefined;
49
+ if (cached) notify();
50
+ return { unsubscribe };
51
+ },
52
+ });
53
+ }
@@ -0,0 +1,18 @@
1
+ // Treenity Client SDK — transport-agnostic tree client interface.
2
+ // Transports: trpc (now), ws (future), http (future).
3
+
4
+ import type { Tree } from '#tree';
5
+
6
+ export type WatchSub = { unsubscribe(): void };
7
+
8
+ export type TreenityClient = {
9
+ tree: Tree;
10
+ execute(path: string, action: string, data?: unknown, opts?: { type?: string; key?: string }): Promise<unknown>;
11
+ /** Global SSE stream — all events for this user */
12
+ watch(onEvent: (e: any) => void): WatchSub;
13
+ /** Watch specific path — registers watch + filters events. Returns initial node + subscription. */
14
+ watchPath(path: string, onEvent: (e: any) => void): Promise<{ node: any; unsubscribe(): void }>;
15
+ };
16
+
17
+ export { createTrpcTransport } from './trpc';
18
+ export { createNodeClient } from './handle';
@@ -0,0 +1,91 @@
1
+ // tRPC transport for Treenity Client.
2
+ // HTTP batch for queries/mutations, SSE for subscriptions.
3
+
4
+ import type { NodeData } from '#core';
5
+ import type { TreeRouter } from '#server/trpc';
6
+ import { defaultPatch } from '#tree/patch';
7
+ import { createTRPCClient, httpBatchLink, httpSubscriptionLink, splitLink } from '@trpc/client';
8
+ import type { TreenityClient, WatchSub } from './index';
9
+
10
+ export type TrpcTransportOpts = {
11
+ url: string;
12
+ getToken?: () => string | null;
13
+ token?: string;
14
+ fetch?: (input: any, init?: any) => Promise<Response>;
15
+ };
16
+
17
+ export function createTrpcTransport(opts: TrpcTransportOpts): TreenityClient & { trpc: ReturnType<typeof createTRPCClient<TreeRouter>> } {
18
+ const getToken = opts.getToken ?? (() => opts.token ?? null);
19
+
20
+ const trpc = createTRPCClient<TreeRouter>({
21
+ links: [
22
+ splitLink({
23
+ condition: (op) => op.type === 'subscription',
24
+ true: httpSubscriptionLink({
25
+ url: `${opts.url}/trpc/`,
26
+ connectionParams: () => {
27
+ const t = getToken();
28
+ return t ? { token: t } : {};
29
+ },
30
+ }),
31
+ false: httpBatchLink({
32
+ url: `${opts.url}/trpc/`,
33
+ headers: () => {
34
+ const t = getToken();
35
+ return t ? { Authorization: `Bearer ${t}` } : {};
36
+ },
37
+ ...(opts.fetch && { fetch: opts.fetch }),
38
+ }),
39
+ }),
40
+ ],
41
+ });
42
+
43
+ // Shared SSE connection for watchPath — lazy, one per transport
44
+ let eventSub: WatchSub | null = null;
45
+ const pathCbs = new Map<string, Set<(e: any) => void>>();
46
+
47
+ function ensureSSE() {
48
+ if (eventSub) return;
49
+ eventSub = trpc.events.subscribe(undefined as void, {
50
+ onData: (event: any) => {
51
+ if ('path' in event) pathCbs.get(event.path)?.forEach(cb => cb(event));
52
+ },
53
+ });
54
+ }
55
+
56
+ return {
57
+ tree: {
58
+ get: (path) => trpc.get.query({ path }) as Promise<NodeData | undefined>,
59
+ getChildren: (path, opts) => trpc.getChildren.query({ path, ...opts }),
60
+ set: (node) => trpc.set.mutate({ node: node as Record<string, unknown> }),
61
+ remove: (path) => trpc.remove.mutate({ path }).then(() => true),
62
+ // TODO: add tRPC patch endpoint for single-RPC atomic patch
63
+ patch: (path, ops) => defaultPatch(
64
+ (p) => trpc.get.query({ path: p }) as Promise<NodeData | undefined>,
65
+ (n) => trpc.set.mutate({ node: n as Record<string, unknown> }).then(() => {}),
66
+ path, ops,
67
+ ),
68
+ },
69
+ execute: (path, action, data, o) =>
70
+ trpc.execute.mutate({ path, action, data, type: o?.type, key: o?.key }),
71
+ watch: (onEvent) =>
72
+ trpc.events.subscribe(undefined as void, { onData: onEvent }),
73
+
74
+ watchPath: async (path, onEvent) => {
75
+ const node = await trpc.get.query({ path, watch: true });
76
+ ensureSSE();
77
+ if (!pathCbs.has(path)) pathCbs.set(path, new Set());
78
+ pathCbs.get(path)!.add(onEvent);
79
+ return {
80
+ node,
81
+ unsubscribe() {
82
+ const set = pathCbs.get(path);
83
+ if (set) { set.delete(onEvent); if (!set.size) pathCbs.delete(path); }
84
+ if (!pathCbs.size && eventSub) { eventSub.unsubscribe(); eventSub = null; }
85
+ },
86
+ };
87
+ },
88
+
89
+ trpc,
90
+ };
91
+ }
package/src/client.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './client/index.ts';
@@ -0,0 +1,14 @@
1
+ ## comp
2
+ Component registration layer (L2). Bridges core primitives and server.
3
+
4
+ ### Файлы
5
+ - index.ts — registerType, findCompByType, Actions<T>, TypeProxy<T> = Raw<T> & Actions<T>
6
+ - needs.ts — sibling dependency injection: registerNeeds/resolveNeeds
7
+ - ports.ts — action port graph: pre/post conditions as queryable edges
8
+ - planner.ts — backward+forward chaining planner on the port graph
9
+
10
+ ### Конвенции
11
+ - registerType auto-registers all public methods as action:{name}
12
+ - Components never access siblings directly — use `needs` for injection
13
+ - Ports declared via static metadata, planner resolves execution order
14
+ - ExecCtx = {node, tree, signal, nc, deps} — context during action execution
@@ -0,0 +1,36 @@
1
+ // Shared typed proxy factory — L0, no server deps.
2
+ // Used by: server (serverNodeHandle), client (createNodeClient), React (hooks).
3
+
4
+ import { type Class, type TypeProxy } from './index';
5
+ import { getComponent, type NodeData, normalizeType } from '#core';
6
+
7
+ export type ExecuteInput = { path: string; type?: string; key?: string; action: string; data?: unknown };
8
+ export type ExecuteFn = (input: ExecuteInput) => Promise<unknown>;
9
+ export type StreamFn = (input: ExecuteInput) => AsyncIterable<unknown>;
10
+
11
+ const AsyncGenFn = Object.getPrototypeOf(async function* () {}).constructor;
12
+
13
+ /** Create TypeProxy from node data + class. Actions call execute/stream, fields read from comp. */
14
+ export function makeTypedProxy<T extends object>(
15
+ node: NodeData | undefined,
16
+ cls: Class<T>,
17
+ path: string,
18
+ execute: ExecuteFn,
19
+ stream?: StreamFn,
20
+ key?: string,
21
+ ): TypeProxy<T> {
22
+ const type = normalizeType(cls);
23
+ const comp = node ? getComponent(node, cls, key) : undefined;
24
+
25
+ return new Proxy(comp ?? {} as T, {
26
+ get: (_t, prop: string) => {
27
+ const fn = (cls.prototype as any)[prop];
28
+ if (typeof fn === 'function') {
29
+ if (stream && fn instanceof AsyncGenFn)
30
+ return (data?: unknown) => stream({ path, type, key, action: prop, data });
31
+ return (data?: unknown) => execute({ path, type, key, action: prop, data });
32
+ }
33
+ return (comp as any)?.[prop];
34
+ },
35
+ }) as TypeProxy<T>;
36
+ }