@peers-app/peers-ui 0.14.0 → 0.15.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 (438) hide show
  1. package/.github/workflows/publish.yml +8 -5
  2. package/babel.config.js +4 -4
  3. package/biome.json +191 -0
  4. package/dist/command-palette/command-palette-ui.d.ts +1 -2
  5. package/dist/command-palette/command-palette-ui.js +175 -244
  6. package/dist/command-palette/command-palette.js +65 -64
  7. package/dist/components/chat-overlay.d.ts +2 -2
  8. package/dist/components/chat-overlay.js +160 -217
  9. package/dist/components/checkbox.d.ts +5 -4
  10. package/dist/components/checkbox.js +4 -7
  11. package/dist/components/group-switcher.d.ts +1 -2
  12. package/dist/components/group-switcher.js +119 -159
  13. package/dist/components/input-date.d.ts +3 -3
  14. package/dist/components/input-date.js +6 -6
  15. package/dist/components/input-number.d.ts +7 -6
  16. package/dist/components/input-number.js +25 -20
  17. package/dist/components/input.d.ts +5 -4
  18. package/dist/components/input.js +4 -7
  19. package/dist/components/inverse-lazy-list.d.ts +3 -3
  20. package/dist/components/inverse-lazy-list.js +13 -47
  21. package/dist/components/io-schema-values.d.ts +5 -6
  22. package/dist/components/io-schema-values.js +28 -65
  23. package/dist/components/io-schema.d.ts +4 -5
  24. package/dist/components/io-schema.js +42 -79
  25. package/dist/components/lazy-list.d.ts +3 -3
  26. package/dist/components/lazy-list.js +38 -58
  27. package/dist/components/list-screen.d.ts +3 -8
  28. package/dist/components/list-screen.js +28 -23
  29. package/dist/components/loading-indicator.d.ts +1 -2
  30. package/dist/components/loading-indicator.js +2 -6
  31. package/dist/components/markdown-editor/autolink-plugin.js +5 -8
  32. package/dist/components/markdown-editor/editor-inline.d.ts +2 -3
  33. package/dist/components/markdown-editor/editor-inline.js +2 -6
  34. package/dist/components/markdown-editor/editor.d.ts +6 -6
  35. package/dist/components/markdown-editor/editor.js +9 -19
  36. package/dist/components/markdown-editor/markdown-plugin.d.ts +1 -1
  37. package/dist/components/markdown-editor/markdown-plugin.js +20 -21
  38. package/dist/components/markdown-editor/mention-node.d.ts +2 -2
  39. package/dist/components/markdown-editor/mention-node.js +24 -24
  40. package/dist/components/markdown-editor/mentions-plugin.d.ts +2 -2
  41. package/dist/components/markdown-editor/mentions-plugin.js +61 -62
  42. package/dist/components/markdown-editor/theme.js +28 -28
  43. package/dist/components/markdown-editor/toolbar.d.ts +2 -3
  44. package/dist/components/markdown-editor/toolbar.js +32 -49
  45. package/dist/components/markdown-with-mentions.d.ts +1 -1
  46. package/dist/components/markdown-with-mentions.js +43 -43
  47. package/dist/components/message-logs/message-logs.d.ts +1 -2
  48. package/dist/components/message-logs/message-logs.js +91 -116
  49. package/dist/components/messages/avatar.d.ts +3 -4
  50. package/dist/components/messages/avatar.js +37 -46
  51. package/dist/components/messages/channel-message-list.d.ts +5 -6
  52. package/dist/components/messages/channel-message-list.js +34 -34
  53. package/dist/components/messages/channel-view.d.ts +1 -2
  54. package/dist/components/messages/channel-view.js +23 -57
  55. package/dist/components/messages/message-compose.d.ts +3 -4
  56. package/dist/components/messages/message-compose.js +27 -38
  57. package/dist/components/messages/message-display.d.ts +2 -3
  58. package/dist/components/messages/message-display.js +42 -95
  59. package/dist/components/messages/thread-message-list.d.ts +4 -5
  60. package/dist/components/messages/thread-message-list.js +29 -29
  61. package/dist/components/router.d.ts +1 -2
  62. package/dist/components/router.js +58 -66
  63. package/dist/components/save-button.d.ts +3 -3
  64. package/dist/components/save-button.js +23 -33
  65. package/dist/components/sortable-list.d.ts +11 -12
  66. package/dist/components/sortable-list.js +42 -22
  67. package/dist/components/tabs.d.ts +3 -3
  68. package/dist/components/tabs.js +16 -47
  69. package/dist/components/tooltip.d.ts +4 -4
  70. package/dist/components/tooltip.js +4 -9
  71. package/dist/components/trust-level-badge.d.ts +2 -3
  72. package/dist/components/trust-level-badge.js +16 -16
  73. package/dist/components/trust-level-dropdown.d.ts +3 -4
  74. package/dist/components/trust-level-dropdown.js +32 -55
  75. package/dist/components/typeahead.d.ts +3 -3
  76. package/dist/components/typeahead.js +48 -89
  77. package/dist/components/voice-indicator.d.ts +2 -2
  78. package/dist/components/voice-indicator.js +93 -106
  79. package/dist/components/voice-subscribe-events.d.ts +32 -0
  80. package/dist/components/voice-subscribe-events.js +2 -0
  81. package/dist/globals.d.ts +3 -5
  82. package/dist/globals.js +22 -33
  83. package/dist/hooks.d.ts +5 -5
  84. package/dist/hooks.js +22 -12
  85. package/dist/hooks.test.js +129 -145
  86. package/dist/index.d.ts +9 -8
  87. package/dist/index.js +13 -12
  88. package/dist/mention-configs.d.ts +2 -2
  89. package/dist/mention-configs.js +55 -42
  90. package/dist/screens/assistants/assistant-config.d.ts +2 -3
  91. package/dist/screens/assistants/assistant-config.js +9 -22
  92. package/dist/screens/assistants/assistant-details.d.ts +1 -2
  93. package/dist/screens/assistants/assistant-details.js +13 -28
  94. package/dist/screens/assistants/assistant-info.d.ts +2 -3
  95. package/dist/screens/assistants/assistant-info.js +3 -17
  96. package/dist/screens/assistants/assistant-list.d.ts +1 -2
  97. package/dist/screens/assistants/assistant-list.js +15 -56
  98. package/dist/screens/assistants/assistant-tools.d.ts +2 -3
  99. package/dist/screens/assistants/assistant-tools.js +10 -24
  100. package/dist/screens/console-logs/console-logs-list.d.ts +1 -2
  101. package/dist/screens/console-logs/console-logs-list.js +130 -134
  102. package/dist/screens/console-logs/log-display.d.ts +2 -3
  103. package/dist/screens/console-logs/log-display.js +40 -42
  104. package/dist/screens/console-logs/log-filters.d.ts +1 -2
  105. package/dist/screens/console-logs/log-filters.js +2 -24
  106. package/dist/screens/console-logs/mobile-log-card.d.ts +2 -3
  107. package/dist/screens/console-logs/mobile-log-card.js +64 -67
  108. package/dist/screens/console-logs/resizable-table-header.d.ts +1 -2
  109. package/dist/screens/console-logs/resizable-table-header.js +31 -67
  110. package/dist/screens/contacts/contact-details.d.ts +1 -2
  111. package/dist/screens/contacts/contact-details.js +16 -46
  112. package/dist/screens/contacts/contact-list.d.ts +1 -2
  113. package/dist/screens/contacts/contact-list.js +44 -103
  114. package/dist/screens/contacts/index.d.ts +4 -4
  115. package/dist/screens/contacts/index.js +1 -1
  116. package/dist/screens/contacts/user-connect.d.ts +1 -2
  117. package/dist/screens/contacts/user-connect.js +85 -186
  118. package/dist/screens/data-explorer/data-explorer.d.ts +1 -2
  119. package/dist/screens/data-explorer/data-explorer.js +61 -181
  120. package/dist/screens/data-explorer/index.d.ts +2 -2
  121. package/dist/screens/data-explorer/query-executor.d.ts +1 -2
  122. package/dist/screens/data-explorer/query-executor.js +56 -166
  123. package/dist/screens/groups/group-details.d.ts +1 -2
  124. package/dist/screens/groups/group-details.js +27 -122
  125. package/dist/screens/groups/group-invite-listener.d.ts +2 -3
  126. package/dist/screens/groups/group-invite-listener.js +8 -104
  127. package/dist/screens/groups/group-list.d.ts +1 -2
  128. package/dist/screens/groups/group-list.js +56 -133
  129. package/dist/screens/groups/group-members.d.ts +2 -3
  130. package/dist/screens/groups/group-members.js +62 -132
  131. package/dist/screens/groups/index.d.ts +4 -4
  132. package/dist/screens/groups/index.js +1 -1
  133. package/dist/screens/join-group/index.d.ts +2 -2
  134. package/dist/screens/join-group/join-group.d.ts +1 -2
  135. package/dist/screens/join-group/join-group.js +9 -109
  136. package/dist/screens/network-viewer/connection-troubleshooter.d.ts +2 -3
  137. package/dist/screens/network-viewer/connection-troubleshooter.js +89 -193
  138. package/dist/screens/network-viewer/cpu-usage-graph.d.ts +1 -2
  139. package/dist/screens/network-viewer/cpu-usage-graph.js +60 -99
  140. package/dist/screens/network-viewer/device-details-modal.d.ts +1 -2
  141. package/dist/screens/network-viewer/device-details-modal.js +25 -177
  142. package/dist/screens/network-viewer/group-details-modal.d.ts +1 -2
  143. package/dist/screens/network-viewer/group-details-modal.js +31 -142
  144. package/dist/screens/network-viewer/index.d.ts +4 -4
  145. package/dist/screens/network-viewer/index.js +3 -3
  146. package/dist/screens/network-viewer/network-viewer-ipc.d.ts +22 -0
  147. package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
  148. package/dist/screens/network-viewer/network-viewer.d.ts +1 -2
  149. package/dist/screens/network-viewer/network-viewer.js +91 -296
  150. package/dist/screens/network-viewer/usage-graph.d.ts +1 -2
  151. package/dist/screens/network-viewer/usage-graph.js +78 -110
  152. package/dist/screens/packages/package-details.d.ts +1 -2
  153. package/dist/screens/packages/package-details.js +35 -41
  154. package/dist/screens/packages/package-info.d.ts +2 -2
  155. package/dist/screens/packages/package-info.js +33 -86
  156. package/dist/screens/packages/package-list.d.ts +1 -2
  157. package/dist/screens/packages/package-list.js +42 -106
  158. package/dist/screens/packages/package-new-local.d.ts +1 -2
  159. package/dist/screens/packages/package-new-local.js +13 -19
  160. package/dist/screens/packages/package-versions.d.ts +2 -3
  161. package/dist/screens/packages/package-versions.js +29 -96
  162. package/dist/screens/peer-types/peer-type-details.d.ts +3 -4
  163. package/dist/screens/peer-types/peer-type-details.js +26 -78
  164. package/dist/screens/peer-types/peer-type-list.d.ts +1 -2
  165. package/dist/screens/peer-types/peer-type-list.js +13 -24
  166. package/dist/screens/search/global-search.d.ts +1 -2
  167. package/dist/screens/search/global-search.js +104 -182
  168. package/dist/screens/settings/color-mode-dropdown.d.ts +3 -4
  169. package/dist/screens/settings/color-mode-dropdown.js +18 -37
  170. package/dist/screens/settings/settings-page.d.ts +1 -1
  171. package/dist/screens/settings/settings-page.js +86 -213
  172. package/dist/screens/settings/voice-settings-agent.d.ts +1 -1
  173. package/dist/screens/settings/voice-settings-agent.js +7 -44
  174. package/dist/screens/settings/voice-settings-api-keys.d.ts +2 -2
  175. package/dist/screens/settings/voice-settings-api-keys.js +2 -29
  176. package/dist/screens/settings/voice-settings-output.d.ts +2 -2
  177. package/dist/screens/settings/voice-settings-output.js +2 -40
  178. package/dist/screens/settings/voice-settings-providers.d.ts +2 -2
  179. package/dist/screens/settings/voice-settings-providers.js +2 -19
  180. package/dist/screens/settings/voice-settings-types.d.ts +4 -4
  181. package/dist/screens/settings/voice-settings-types.js +31 -31
  182. package/dist/screens/settings/voice-settings-wake-word.d.ts +2 -2
  183. package/dist/screens/settings/voice-settings-wake-word.js +2 -33
  184. package/dist/screens/settings/voice-settings.d.ts +1 -1
  185. package/dist/screens/settings/voice-settings.js +35 -112
  186. package/dist/screens/setup-user.d.ts +1 -2
  187. package/dist/screens/setup-user.js +38 -116
  188. package/dist/screens/tools/tool-code.d.ts +2 -3
  189. package/dist/screens/tools/tool-code.js +9 -13
  190. package/dist/screens/tools/tool-details.d.ts +1 -2
  191. package/dist/screens/tools/tool-details.js +26 -39
  192. package/dist/screens/tools/tool-info.d.ts +2 -3
  193. package/dist/screens/tools/tool-info.js +9 -48
  194. package/dist/screens/tools/tool-list.d.ts +1 -2
  195. package/dist/screens/tools/tool-list.js +33 -65
  196. package/dist/screens/tools/tool-schema.d.ts +2 -3
  197. package/dist/screens/tools/tool-schema.js +2 -13
  198. package/dist/screens/tools/tool-test-details.d.ts +1 -2
  199. package/dist/screens/tools/tool-test-details.js +12 -28
  200. package/dist/screens/tools/tool-test-list.d.ts +1 -2
  201. package/dist/screens/tools/tool-test-list.js +17 -56
  202. package/dist/screens/variables/variable-details.d.ts +1 -2
  203. package/dist/screens/variables/variable-details.js +19 -86
  204. package/dist/screens/variables/variable-list.d.ts +1 -2
  205. package/dist/screens/variables/variable-list.js +16 -27
  206. package/dist/screens/welcome-modal.d.ts +1 -2
  207. package/dist/screens/welcome-modal.js +44 -111
  208. package/dist/screens/workflows/workflow-details.d.ts +1 -2
  209. package/dist/screens/workflows/workflow-details.js +17 -31
  210. package/dist/screens/workflows/workflow-info.d.ts +2 -3
  211. package/dist/screens/workflows/workflow-info.js +2 -9
  212. package/dist/screens/workflows/workflow-instructions.d.ts +2 -3
  213. package/dist/screens/workflows/workflow-instructions.js +23 -55
  214. package/dist/screens/workflows/workflow-list.d.ts +1 -2
  215. package/dist/screens/workflows/workflow-list.js +23 -62
  216. package/dist/setupTests.d.ts +1 -1
  217. package/dist/setupTests.js +10 -11
  218. package/dist/system-apps/assistants.app.d.ts +1 -1
  219. package/dist/system-apps/assistants.app.js +3 -3
  220. package/dist/system-apps/console-logs.app.d.ts +1 -1
  221. package/dist/system-apps/console-logs.app.js +3 -3
  222. package/dist/system-apps/contacts.app.d.ts +1 -1
  223. package/dist/system-apps/contacts.app.js +4 -4
  224. package/dist/system-apps/data-explorer.app.d.ts +1 -1
  225. package/dist/system-apps/data-explorer.app.js +4 -4
  226. package/dist/system-apps/groups.app.d.ts +1 -1
  227. package/dist/system-apps/groups.app.js +4 -4
  228. package/dist/system-apps/index.d.ts +17 -17
  229. package/dist/system-apps/index.js +52 -52
  230. package/dist/system-apps/join-group.app.d.ts +1 -1
  231. package/dist/system-apps/join-group.app.js +4 -4
  232. package/dist/system-apps/mobile-settings.app.d.ts +1 -1
  233. package/dist/system-apps/mobile-settings.app.js +3 -3
  234. package/dist/system-apps/network-viewer.app.d.ts +1 -1
  235. package/dist/system-apps/network-viewer.app.js +4 -4
  236. package/dist/system-apps/packages.app.d.ts +1 -1
  237. package/dist/system-apps/packages.app.js +3 -3
  238. package/dist/system-apps/search.app.d.ts +1 -1
  239. package/dist/system-apps/search.app.js +4 -4
  240. package/dist/system-apps/settings.app.d.ts +1 -1
  241. package/dist/system-apps/settings.app.js +3 -3
  242. package/dist/system-apps/threads.app.d.ts +1 -1
  243. package/dist/system-apps/threads.app.js +3 -3
  244. package/dist/system-apps/tools.app.d.ts +1 -1
  245. package/dist/system-apps/tools.app.js +3 -3
  246. package/dist/system-apps/types.app.d.ts +1 -1
  247. package/dist/system-apps/types.app.js +3 -3
  248. package/dist/system-apps/variables.app.d.ts +1 -1
  249. package/dist/system-apps/variables.app.js +3 -3
  250. package/dist/system-apps/workflows.app.d.ts +1 -1
  251. package/dist/system-apps/workflows.app.js +3 -3
  252. package/dist/tabs-layout/tabs-layout.d.ts +2 -3
  253. package/dist/tabs-layout/tabs-layout.js +215 -246
  254. package/dist/tabs-layout/tabs-state.d.ts +2 -2
  255. package/dist/tabs-layout/tabs-state.js +73 -61
  256. package/dist/ui-defaults/index.d.ts +2 -2
  257. package/dist/ui-defaults/list-screen.d.ts +2 -3
  258. package/dist/ui-defaults/list-screen.js +33 -37
  259. package/dist/ui-defaults/markdown-field.js +24 -56
  260. package/dist/ui-router/routes-loader.d.ts +1 -1
  261. package/dist/ui-router/routes-loader.js +17 -13
  262. package/dist/ui-router/ui-loader.d.ts +6 -6
  263. package/dist/ui-router/ui-loader.js +172 -268
  264. package/dist/utils.js +49 -39
  265. package/jest.config.js +16 -16
  266. package/package.json +16 -14
  267. package/src/command-palette/command-palette-ui.tsx +261 -237
  268. package/src/command-palette/command-palette.ts +81 -78
  269. package/src/components/chat-overlay.tsx +366 -261
  270. package/src/components/checkbox.tsx +15 -12
  271. package/src/components/group-switcher.tsx +150 -105
  272. package/src/components/input-date.tsx +17 -16
  273. package/src/components/input-number.tsx +47 -31
  274. package/src/components/input.tsx +15 -12
  275. package/src/components/inverse-lazy-list.tsx +14 -13
  276. package/src/components/io-schema-values.tsx +51 -69
  277. package/src/components/io-schema.tsx +94 -69
  278. package/src/components/lazy-list.tsx +51 -34
  279. package/src/components/list-screen.tsx +51 -35
  280. package/src/components/loading-indicator.tsx +2 -4
  281. package/src/components/markdown-editor/autolink-plugin.tsx +4 -11
  282. package/src/components/markdown-editor/editor-inline.tsx +3 -4
  283. package/src/components/markdown-editor/editor.tsx +53 -51
  284. package/src/components/markdown-editor/markdown-plugin.tsx +48 -40
  285. package/src/components/markdown-editor/mention-node.ts +39 -38
  286. package/src/components/markdown-editor/mentions-plugin.tsx +99 -101
  287. package/src/components/markdown-editor/theme.ts +28 -29
  288. package/src/components/markdown-editor/toolbar.tsx +53 -47
  289. package/src/components/markdown-with-mentions.tsx +56 -46
  290. package/src/components/message-logs/message-logs.tsx +225 -165
  291. package/src/components/messages/avatar.tsx +70 -52
  292. package/src/components/messages/channel-message-list.tsx +80 -68
  293. package/src/components/messages/channel-view.tsx +34 -33
  294. package/src/components/messages/message-compose.tsx +84 -67
  295. package/src/components/messages/message-display.tsx +103 -89
  296. package/src/components/messages/thread-message-list.tsx +53 -44
  297. package/src/components/router.tsx +42 -43
  298. package/src/components/save-button.tsx +43 -39
  299. package/src/components/sortable-list.tsx +77 -49
  300. package/src/components/tabs.tsx +31 -31
  301. package/src/components/tooltip.tsx +21 -28
  302. package/src/components/trust-level-badge.tsx +15 -11
  303. package/src/components/trust-level-dropdown.tsx +49 -19
  304. package/src/components/typeahead.tsx +57 -59
  305. package/src/components/voice-indicator.tsx +158 -141
  306. package/src/components/voice-subscribe-events.ts +20 -0
  307. package/src/globals.tsx +42 -40
  308. package/src/hooks.test.tsx +141 -134
  309. package/src/hooks.ts +80 -48
  310. package/src/index.tsx +17 -10
  311. package/src/mention-configs.ts +122 -68
  312. package/src/screens/assistants/assistant-config.tsx +28 -18
  313. package/src/screens/assistants/assistant-details.tsx +35 -36
  314. package/src/screens/assistants/assistant-info.tsx +16 -11
  315. package/src/screens/assistants/assistant-list.tsx +37 -34
  316. package/src/screens/assistants/assistant-tools.tsx +41 -20
  317. package/src/screens/console-logs/console-logs-list.tsx +173 -140
  318. package/src/screens/console-logs/log-display.tsx +65 -38
  319. package/src/screens/console-logs/log-filters.tsx +4 -3
  320. package/src/screens/console-logs/mobile-log-card.tsx +78 -71
  321. package/src/screens/console-logs/resizable-table-header.tsx +29 -21
  322. package/src/screens/contacts/contact-details.tsx +29 -30
  323. package/src/screens/contacts/contact-list.tsx +71 -60
  324. package/src/screens/contacts/index.ts +5 -5
  325. package/src/screens/contacts/user-connect.tsx +177 -171
  326. package/src/screens/data-explorer/data-explorer.tsx +134 -98
  327. package/src/screens/data-explorer/index.ts +2 -3
  328. package/src/screens/data-explorer/query-executor.tsx +90 -80
  329. package/src/screens/groups/group-details.tsx +120 -101
  330. package/src/screens/groups/group-invite-listener.tsx +34 -37
  331. package/src/screens/groups/group-list.tsx +119 -103
  332. package/src/screens/groups/group-members.tsx +225 -164
  333. package/src/screens/groups/index.ts +5 -6
  334. package/src/screens/join-group/index.ts +2 -2
  335. package/src/screens/join-group/join-group.tsx +41 -39
  336. package/src/screens/network-viewer/connection-troubleshooter.tsx +145 -104
  337. package/src/screens/network-viewer/cpu-usage-graph.tsx +39 -43
  338. package/src/screens/network-viewer/device-details-modal.tsx +46 -59
  339. package/src/screens/network-viewer/group-details-modal.tsx +68 -49
  340. package/src/screens/network-viewer/index.ts +4 -5
  341. package/src/screens/network-viewer/network-viewer-ipc.ts +23 -0
  342. package/src/screens/network-viewer/network-viewer.tsx +261 -236
  343. package/src/screens/network-viewer/usage-graph.tsx +57 -49
  344. package/src/screens/packages/package-details.tsx +43 -35
  345. package/src/screens/packages/package-info.tsx +107 -66
  346. package/src/screens/packages/package-list.tsx +175 -98
  347. package/src/screens/packages/package-new-local.tsx +28 -26
  348. package/src/screens/packages/package-versions.tsx +102 -77
  349. package/src/screens/peer-types/peer-type-details.tsx +60 -50
  350. package/src/screens/peer-types/peer-type-list.tsx +20 -30
  351. package/src/screens/search/global-search.tsx +153 -137
  352. package/src/screens/settings/color-mode-dropdown.tsx +52 -35
  353. package/src/screens/settings/settings-page.tsx +215 -141
  354. package/src/screens/settings/voice-settings-agent.tsx +13 -12
  355. package/src/screens/settings/voice-settings-api-keys.tsx +14 -12
  356. package/src/screens/settings/voice-settings-output.tsx +12 -11
  357. package/src/screens/settings/voice-settings-providers.tsx +7 -3
  358. package/src/screens/settings/voice-settings-types.ts +52 -49
  359. package/src/screens/settings/voice-settings-wake-word.tsx +25 -9
  360. package/src/screens/settings/voice-settings.tsx +66 -43
  361. package/src/screens/setup-user.tsx +88 -41
  362. package/src/screens/tools/tool-code.tsx +12 -17
  363. package/src/screens/tools/tool-details.tsx +28 -28
  364. package/src/screens/tools/tool-info.tsx +14 -19
  365. package/src/screens/tools/tool-list.tsx +58 -40
  366. package/src/screens/tools/tool-schema.tsx +16 -9
  367. package/src/screens/tools/tool-test-details.tsx +11 -22
  368. package/src/screens/tools/tool-test-list.tsx +29 -30
  369. package/src/screens/variables/variable-details.tsx +63 -51
  370. package/src/screens/variables/variable-list.tsx +29 -30
  371. package/src/screens/welcome-modal.tsx +68 -48
  372. package/src/screens/workflows/workflow-details.tsx +40 -30
  373. package/src/screens/workflows/workflow-info.tsx +4 -11
  374. package/src/screens/workflows/workflow-instructions.tsx +35 -28
  375. package/src/screens/workflows/workflow-list.tsx +50 -40
  376. package/src/setupTests.ts +14 -13
  377. package/src/system-apps/assistants.app.ts +5 -5
  378. package/src/system-apps/console-logs.app.ts +4 -4
  379. package/src/system-apps/contacts.app.ts +6 -6
  380. package/src/system-apps/data-explorer.app.ts +5 -5
  381. package/src/system-apps/groups.app.ts +6 -6
  382. package/src/system-apps/index.ts +49 -49
  383. package/src/system-apps/join-group.app.ts +5 -5
  384. package/src/system-apps/mobile-settings.app.ts +4 -5
  385. package/src/system-apps/network-viewer.app.ts +5 -5
  386. package/src/system-apps/packages.app.ts +5 -5
  387. package/src/system-apps/search.app.ts +6 -6
  388. package/src/system-apps/settings.app.ts +5 -5
  389. package/src/system-apps/threads.app.ts +5 -5
  390. package/src/system-apps/tools.app.ts +5 -5
  391. package/src/system-apps/types.app.ts +5 -5
  392. package/src/system-apps/variables.app.ts +5 -5
  393. package/src/system-apps/workflows.app.ts +5 -5
  394. package/src/tabs-layout/tabs-layout.tsx +345 -254
  395. package/src/tabs-layout/tabs-state.ts +100 -81
  396. package/src/ui-defaults/index.ts +2 -3
  397. package/src/ui-defaults/list-screen.tsx +45 -40
  398. package/src/ui-defaults/markdown-field.tsx +22 -26
  399. package/src/ui-router/routes-loader.ts +40 -24
  400. package/src/ui-router/ui-loader.tsx +312 -214
  401. package/src/utils.ts +68 -81
  402. package/tsconfig.json +5 -10
  403. package/dist/components/input-datetime.d.ts +0 -7
  404. package/dist/components/input-datetime.js +0 -35
  405. package/dist/components/lazy-sortable-list.d.ts +0 -29
  406. package/dist/components/lazy-sortable-list.js +0 -12
  407. package/dist/components/left-bar.d.ts +0 -5
  408. package/dist/components/left-bar.js +0 -207
  409. package/dist/components/main-content-container.d.ts +0 -2
  410. package/dist/components/main-content-container.js +0 -92
  411. package/dist/components/messages/thread-view.d.ts +0 -6
  412. package/dist/components/messages/thread-view.js +0 -174
  413. package/dist/components/off-canvas.d.ts +0 -13
  414. package/dist/components/off-canvas.js +0 -89
  415. package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +0 -6
  416. package/dist/components/text-list-editor.tsx/text-list-editor.js +0 -13
  417. package/dist/components/top-bar.d.ts +0 -2
  418. package/dist/components/top-bar.js +0 -51
  419. package/dist/components/typeahead/mentions-plugin.d.ts +0 -7
  420. package/dist/components/typeahead/mentions-plugin.js +0 -203
  421. package/dist/components/typeahead/typeahead-editor.d.ts +0 -15
  422. package/dist/components/typeahead/typeahead-editor.js +0 -134
  423. package/dist/components/typeahead/typeahead.d.ts +0 -12
  424. package/dist/components/typeahead/typeahead.js +0 -94
  425. package/dist/screens/profile.d.ts +0 -2
  426. package/dist/screens/profile.js +0 -76
  427. package/src/components/input-datetime.tsx +0 -41
  428. package/src/components/lazy-sortable-list.tsx +0 -51
  429. package/src/components/left-bar.tsx +0 -322
  430. package/src/components/main-content-container.tsx +0 -79
  431. package/src/components/messages/thread-view.tsx +0 -214
  432. package/src/components/off-canvas.tsx +0 -83
  433. package/src/components/text-list-editor.tsx/text-list-editor.tsx +0 -13
  434. package/src/components/top-bar.tsx +0 -119
  435. package/src/components/typeahead/mentions-plugin.tsx +0 -265
  436. package/src/components/typeahead/typeahead-editor.tsx +0 -140
  437. package/src/components/typeahead/typeahead.tsx +0 -77
  438. package/src/screens/profile.tsx +0 -75
package/dist/globals.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groups = exports.isDesktop = exports.windowHeight = exports.windowWidth = exports.me = exports.threadViewOpen = exports.openThreads = exports.mainContentPath = exports._mainContentPath = exports.packageReloaded = void 0;
3
+ exports.groups = exports.isDesktop = exports.windowHeight = exports.windowWidth = exports.me = exports.mainContentPath = exports._mainContentPath = exports.packageReloaded = void 0;
4
4
  exports.queryParam = queryParam;
5
5
  exports.openThread = openThread;
6
6
  exports.openThreadInTab = openThreadInTab;
@@ -9,7 +9,7 @@ const peers_sdk_1 = require("@peers-app/peers-sdk");
9
9
  const tabs_state_1 = require("./tabs-layout/tabs-state");
10
10
  const utils_1 = require("./utils");
11
11
  exports.packageReloaded = (0, peers_sdk_1.observable)(0);
12
- exports._mainContentPath = (0, peers_sdk_1.groupUserVar)('mainContentPath', { defaultValue: '' });
12
+ exports._mainContentPath = (0, peers_sdk_1.groupUserVar)("mainContentPath", { defaultValue: "" });
13
13
  exports.mainContentPath = (0, peers_sdk_1.computed)({
14
14
  read: () => {
15
15
  return (0, exports._mainContentPath)();
@@ -24,7 +24,7 @@ exports.mainContentPath = (0, peers_sdk_1.computed)({
24
24
  });
25
25
  const queryParams = (0, peers_sdk_1.computed)({
26
26
  read: () => {
27
- const queryStr = (0, exports.mainContentPath)()?.split('?')[1] || '';
27
+ const queryStr = (0, exports.mainContentPath)()?.split("?")[1] || "";
28
28
  const params = new URLSearchParams(queryStr);
29
29
  const obj = {};
30
30
  for (const [key, value] of params.entries()) {
@@ -33,12 +33,12 @@ const queryParams = (0, peers_sdk_1.computed)({
33
33
  return obj;
34
34
  },
35
35
  write: (value) => {
36
- const queryStr = (0, exports.mainContentPath)().split('?')[1] || '';
36
+ const queryStr = (0, exports.mainContentPath)().split("?")[1] || "";
37
37
  const params = new URLSearchParams(queryStr);
38
38
  for (const key in value) {
39
39
  params.set(key, value[key]);
40
40
  }
41
- (0, exports.mainContentPath)((0, exports.mainContentPath)().split('?')[0] + '?' + params.toString());
41
+ (0, exports.mainContentPath)(`${(0, exports.mainContentPath)().split("?")[0]}?${params.toString()}`);
42
42
  },
43
43
  });
44
44
  function queryParam(name, value) {
@@ -47,7 +47,7 @@ function queryParam(name, value) {
47
47
  if (params[name] === value) {
48
48
  return value;
49
49
  }
50
- if (value === null || value === '') {
50
+ if (value === null || value === "") {
51
51
  delete params[name];
52
52
  }
53
53
  else {
@@ -57,25 +57,14 @@ function queryParam(name, value) {
57
57
  }
58
58
  return params[name];
59
59
  }
60
- exports.openThreads = (0, peers_sdk_1.groupUserVar)('openThreads', { defaultValue: [] });
61
- exports.threadViewOpen = (0, peers_sdk_1.groupUserVar)('threadViewOpen', { defaultValue: false });
62
60
  async function openThread(thread) {
63
61
  openThreadInTab(thread);
64
- // let threadId = typeof thread === 'string' ? thread : thread.messageId;
65
- // const message = await Messages().get(threadId);
66
- // if (message) {
67
- // thread = message.messageParentId || message.messageId;
68
- // }
69
- // const threadsWithout = openThreads().filter(t => (typeof t === 'string' && t !== threadId) || (typeof t === 'object' && t.messageId !== threadId));
70
- // openThreads([thread, ...threadsWithout]);
71
- // threadViewOpen(true);
72
62
  }
73
- // Thread opening function for tabs system
74
63
  async function openThreadInTab(thread) {
75
- let threadId = typeof thread === 'string' ? thread : thread.messageId;
64
+ const threadId = typeof thread === "string" ? thread : thread.messageId;
76
65
  const message = await (0, peers_sdk_1.Messages)().get(threadId);
77
66
  if (!message) {
78
- console.warn('Thread message not found:', threadId);
67
+ console.warn("Thread message not found:", threadId);
79
68
  return;
80
69
  }
81
70
  // Use parent message ID if this is a reply, otherwise use the message itself
@@ -83,27 +72,27 @@ async function openThreadInTab(thread) {
83
72
  // Generate thread title from message content (strip mentions and clean formatting)
84
73
  const cleanMessage = (0, utils_1.stripMentions)(message.message);
85
74
  const messagePreview = cleanMessage.slice(0, 30);
86
- const threadTitle = `${messagePreview}${cleanMessage.length > 30 ? '...' : ''}` || `Thread`;
75
+ const threadTitle = `${messagePreview}${cleanMessage.length > 30 ? "..." : ""}` || `Thread`;
87
76
  // // Import openNewTab dynamically to avoid circular dependency
88
77
  // const { openNewTab } = await import('./tabs-layout/tabs-layout');
89
78
  (0, tabs_state_1.openNewTab)({
90
- packageId: 'system-apps',
79
+ packageId: "system-apps",
91
80
  path: `threads/${actualThreadId}`,
92
81
  title: threadTitle,
93
- iconClassName: 'bi-chat-dots',
82
+ iconClassName: "bi-chat-dots",
94
83
  });
95
84
  }
96
85
  peers_sdk_1.rpcClientCalls.setClientPath = async (url) => {
97
- (0, exports.mainContentPath)(url && String(url).trim() || '');
86
+ (0, exports.mainContentPath)((url && String(url).trim()) || "");
98
87
  };
99
88
  peers_sdk_1.rpcClientCalls.openThread = async (threadId) => {
100
- console.warn('Opening thread:', threadId);
89
+ console.warn("Opening thread:", threadId);
101
90
  openThread(threadId);
102
91
  };
103
92
  exports.me = null;
104
93
  exports.windowWidth = (0, peers_sdk_1.observable)(window.innerWidth); //.extend({ rateLimit: 500 });
105
94
  exports.windowHeight = (0, peers_sdk_1.observable)(window.innerHeight); //.extend({ rateLimit: 500 });
106
- window.addEventListener("resize", (ev) => {
95
+ window.addEventListener("resize", (_ev) => {
107
96
  (0, exports.windowWidth)(window.innerWidth);
108
97
  (0, exports.windowHeight)(window.innerHeight);
109
98
  });
@@ -121,18 +110,18 @@ async function loadGlobals() {
121
110
  exports.me = await (0, peers_sdk_1.getMe)();
122
111
  await peers_sdk_1.reloadPackagesOnPageRefresh.loadingPromise;
123
112
  if ((0, peers_sdk_1.reloadPackagesOnPageRefresh)()) {
124
- await peers_sdk_1.rpcServerCalls.addOrUpdatePackage('updateAll');
113
+ await peers_sdk_1.rpcServerCalls.addOrUpdatePackage("updateAll");
125
114
  }
126
115
  await Promise.all([
127
- (0, peers_sdk_1.Groups)().list().then(r => (0, exports.groups)(r)),
116
+ (0, peers_sdk_1.Groups)()
117
+ .list()
118
+ .then((r) => (0, exports.groups)(r)),
128
119
  exports._mainContentPath.loadingPromise,
129
- exports.openThreads.loadingPromise,
130
- exports.threadViewOpen.loadingPromise,
131
120
  (0, peers_sdk_1.sleep)(100),
132
121
  ]);
133
122
  function updateWindowHash() {
134
123
  const currentPath = window.location.hash.substring(1);
135
- const expectedPath = (0, exports.mainContentPath)() || '';
124
+ const expectedPath = (0, exports.mainContentPath)() || "";
136
125
  // console.log({ expectedPath, currentPath });
137
126
  if (currentPath !== expectedPath) {
138
127
  window.location.hash = expectedPath;
@@ -141,10 +130,10 @@ async function loadGlobals() {
141
130
  }
142
131
  exports.mainContentPath.subscribe(updateWindowHash);
143
132
  updateWindowHash();
144
- window.addEventListener('hashchange', () => (0, exports.mainContentPath)(window.location.hash.substring(1)));
133
+ window.addEventListener("hashchange", () => (0, exports.mainContentPath)(window.location.hash.substring(1)));
145
134
  return true;
146
135
  }
147
- if (typeof window !== 'undefined') {
148
- // @ts-ignore
136
+ if (typeof window !== "undefined") {
137
+ // @ts-expect-error
149
138
  window.globals = module.exports;
150
139
  }
package/dist/hooks.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Observable } from "@peers-app/peers-sdk";
2
- import React from 'react';
1
+ import { type Observable } from "@peers-app/peers-sdk";
2
+ import type React from "react";
3
3
  /**
4
4
  * Use this to subscribe to an observable or computed in a functional component.
5
5
  * Uses useSyncExternalStore for proper React 18 concurrent rendering support.
@@ -31,6 +31,6 @@ export declare function useObservableState<T = undefined>(initialValue?: T, doNo
31
31
  * The handler will be called immediately and whenever the subscribable changes.
32
32
  * @param subscribable The observable to subscribe to
33
33
  * @param onChange The function to call with the new value when the observable changes
34
- */
35
- export declare function useSubscription<T>(subscribable: Observable<T>, onChange: (value: T) => any, doNotCallOnChangeDuringSetup?: boolean): void;
36
- export declare function useOnScreen(ref: React.RefObject<any>): boolean;
34
+ */
35
+ export declare function useSubscription<T>(subscribable: Observable<T>, onChange: (value: T) => void, doNotCallOnChangeDuringSetup?: boolean): void;
36
+ export declare function useOnScreen(ref: React.RefObject<Element | null>): boolean;
package/dist/hooks.js CHANGED
@@ -47,12 +47,13 @@ function useObservable(sub, deps = []) {
47
47
  */
48
48
  function usePromise(p, initialValue, deps = []) {
49
49
  const [data, setData] = (0, react_1.useState)(initialValue);
50
+ // `deps` drives when the effect re-runs; callers include `p` when it changes. Omitting `p` avoids duplicate tracking with `[...deps]`.
50
51
  (0, react_1.useEffect)(() => {
51
52
  let disposed = false;
52
- if (typeof p === 'function') {
53
+ if (typeof p === "function") {
53
54
  p = p();
54
55
  }
55
- p.then(newData => {
56
+ p.then((newData) => {
56
57
  // if (!_.isEqual(newData, data) && !disposed) {
57
58
  if (!disposed) {
58
59
  setData(newData);
@@ -61,12 +62,13 @@ function usePromise(p, initialValue, deps = []) {
61
62
  return () => {
62
63
  disposed = true;
63
64
  };
64
- }, deps);
65
+ }, [...deps]);
65
66
  return data;
66
67
  }
67
68
  function useObservableState(initialValue, doNotSubscribe) {
68
69
  const [obs] = (0, react_1.useState)(() => initialValue !== undefined ? (0, peers_sdk_1.observable)(initialValue) : (0, peers_sdk_1.observable)());
69
70
  if (!doNotSubscribe) {
71
+ // biome-ignore lint/correctness/useHookAtTopLevel: when doNotSubscribe, caller keeps a stable observable without React-driven subscription (see docstring).
70
72
  useObservable(obs);
71
73
  }
72
74
  return obs;
@@ -76,23 +78,31 @@ function useObservableState(initialValue, doNotSubscribe) {
76
78
  * The handler will be called immediately and whenever the subscribable changes.
77
79
  * @param subscribable The observable to subscribe to
78
80
  * @param onChange The function to call with the new value when the observable changes
79
- */
81
+ */
80
82
  function useSubscription(subscribable, onChange, doNotCallOnChangeDuringSetup) {
81
- if (!doNotCallOnChangeDuringSetup) {
82
- (0, react_1.useEffect)(() => onChange(subscribable()), []);
83
- }
84
83
  (0, react_1.useEffect)(() => {
84
+ if (!doNotCallOnChangeDuringSetup) {
85
+ onChange(subscribable());
86
+ }
85
87
  const subscription = subscribable.subscribe(() => onChange(subscribable()));
86
88
  return () => subscription.dispose();
87
- }, [subscribable, onChange]);
89
+ }, [subscribable, onChange, doNotCallOnChangeDuringSetup]);
88
90
  }
89
91
  function useOnScreen(ref) {
90
92
  const [isIntersecting, setIntersecting] = (0, react_1.useState)(false);
91
- const observer = new IntersectionObserver(([entry]) => setIntersecting(entry.isIntersecting));
93
+ // Read ref.current once on mount (ref object identity is stable).
92
94
  (0, react_1.useEffect)(() => {
93
- observer.observe(ref.current);
94
- // Remove the observer as soon as the component is unmounted
95
- return () => { observer.disconnect(); };
95
+ const element = ref.current;
96
+ if (!element) {
97
+ return;
98
+ }
99
+ const observer = new IntersectionObserver(([entry]) => {
100
+ setIntersecting(entry.isIntersecting);
101
+ });
102
+ observer.observe(element);
103
+ return () => {
104
+ observer.disconnect();
105
+ };
96
106
  }, []);
97
107
  return isIntersecting;
98
108
  }
@@ -1,111 +1,102 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const react_1 = __importDefault(require("react"));
7
- const react_2 = require("@testing-library/react");
3
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
4
  const peers_sdk_1 = require("@peers-app/peers-sdk");
5
+ const react_1 = require("@testing-library/react");
9
6
  const hooks_1 = require("./hooks");
10
7
  // Helper component to test useObservable
11
- function TestComponent({ obs, testId = 'value' }) {
8
+ function TestComponent({ obs, testId = "value" }) {
12
9
  const [value, setValue] = (0, hooks_1.useObservable)(obs);
13
- return (react_1.default.createElement("div", null,
14
- react_1.default.createElement("span", { "data-testid": testId }, JSON.stringify(value)),
15
- react_1.default.createElement("button", { "data-testid": "setter", onClick: () => setValue('new-value') }, "Set")));
10
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { "data-testid": testId, children: JSON.stringify(value) }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "setter", onClick: () => setValue("new-value"), children: "Set" })] }));
16
11
  }
17
12
  // Helper component to test array behavior
18
13
  function ArrayTestComponent({ obs }) {
19
14
  const [value] = (0, hooks_1.useObservable)(obs);
20
- return (react_1.default.createElement("div", null,
21
- react_1.default.createElement("span", { "data-testid": "array-value" }, JSON.stringify(value)),
22
- react_1.default.createElement("span", { "data-testid": "array-length" }, value.length)));
15
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { "data-testid": "array-value", children: JSON.stringify(value) }), (0, jsx_runtime_1.jsx)("span", { "data-testid": "array-length", children: value.length })] }));
23
16
  }
24
17
  // Helper component to test useObservableState
25
18
  function ObservableStateTestComponent({ initialValue }) {
26
19
  const obs = (0, hooks_1.useObservableState)(initialValue);
27
20
  const [value] = (0, hooks_1.useObservable)(obs);
28
- return (react_1.default.createElement("div", null,
29
- react_1.default.createElement("span", { "data-testid": "state-value" }, value),
30
- react_1.default.createElement("button", { "data-testid": "increment", onClick: () => obs(obs() + 1) }, "Increment")));
21
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { "data-testid": "state-value", children: value }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "increment", onClick: () => obs(obs() + 1), children: "Increment" })] }));
31
22
  }
32
- describe('useObservable', () => {
33
- describe('basic functionality', () => {
34
- it('should return the current value of an observable', () => {
35
- const obs = (0, peers_sdk_1.observable)('hello');
36
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
37
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('"hello"');
38
- });
39
- it('should return the value when passed a plain value (non-observable)', () => {
40
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: "plain-value" }));
41
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('"plain-value"');
42
- });
43
- it('should re-render when observable value changes', async () => {
44
- const obs = (0, peers_sdk_1.observable)('initial');
45
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
46
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('"initial"');
47
- (0, react_2.act)(() => {
48
- obs('updated');
23
+ describe("useObservable", () => {
24
+ describe("basic functionality", () => {
25
+ it("should return the current value of an observable", () => {
26
+ const obs = (0, peers_sdk_1.observable)("hello");
27
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
28
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('"hello"');
29
+ });
30
+ it("should return the value when passed a plain value (non-observable)", () => {
31
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: "plain-value" }));
32
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('"plain-value"');
33
+ });
34
+ it("should re-render when observable value changes", async () => {
35
+ const obs = (0, peers_sdk_1.observable)("initial");
36
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
37
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('"initial"');
38
+ (0, react_1.act)(() => {
39
+ obs("updated");
49
40
  });
50
- await (0, react_2.waitFor)(() => {
51
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('"updated"');
41
+ await (0, react_1.waitFor)(() => {
42
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('"updated"');
52
43
  });
53
44
  });
54
- it('should update the observable when setter is called', async () => {
55
- const obs = (0, peers_sdk_1.observable)('initial');
56
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
57
- (0, react_2.act)(() => {
58
- react_2.screen.getByTestId('setter').click();
45
+ it("should update the observable when setter is called", async () => {
46
+ const obs = (0, peers_sdk_1.observable)("initial");
47
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
48
+ (0, react_1.act)(() => {
49
+ react_1.screen.getByTestId("setter").click();
59
50
  });
60
- await (0, react_2.waitFor)(() => {
61
- expect(obs()).toBe('new-value');
62
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('"new-value"');
51
+ await (0, react_1.waitFor)(() => {
52
+ expect(obs()).toBe("new-value");
53
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('"new-value"');
63
54
  });
64
55
  });
65
- it('should handle undefined values', () => {
56
+ it("should handle undefined values", () => {
66
57
  const obs = (0, peers_sdk_1.observable)(undefined);
67
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
58
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
68
59
  // undefined serializes to empty string in JSON.stringify, but actually shows as nothing
69
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('');
70
- });
71
- it('should handle object values', async () => {
72
- const obs = (0, peers_sdk_1.observable)({ name: 'test', count: 5 });
73
- (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
74
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('{"name":"test","count":5}');
75
- (0, react_2.act)(() => {
76
- obs({ name: 'updated', count: 10 });
60
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent("");
61
+ });
62
+ it("should handle object values", async () => {
63
+ const obs = (0, peers_sdk_1.observable)({ name: "test", count: 5 });
64
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
65
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('{"name":"test","count":5}');
66
+ (0, react_1.act)(() => {
67
+ obs({ name: "updated", count: 10 });
77
68
  });
78
- await (0, react_2.waitFor)(() => {
79
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('{"name":"updated","count":10}');
69
+ await (0, react_1.waitFor)(() => {
70
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent('{"name":"updated","count":10}');
80
71
  });
81
72
  });
82
73
  });
83
- describe('array handling', () => {
84
- it('should handle array values', () => {
85
- const obs = (0, peers_sdk_1.observable)(['a', 'b', 'c']);
86
- (0, react_2.render)(react_1.default.createElement(ArrayTestComponent, { obs: obs }));
87
- expect(react_2.screen.getByTestId('array-value')).toHaveTextContent('["a","b","c"]');
88
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('3');
89
- });
90
- it('should re-render when array is replaced with new reference', async () => {
91
- const obs = (0, peers_sdk_1.observable)(['a', 'b']);
92
- (0, react_2.render)(react_1.default.createElement(ArrayTestComponent, { obs: obs }));
93
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('2');
94
- (0, react_2.act)(() => {
95
- obs(['a', 'b', 'c']); // New array reference
74
+ describe("array handling", () => {
75
+ it("should handle array values", () => {
76
+ const obs = (0, peers_sdk_1.observable)(["a", "b", "c"]);
77
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ArrayTestComponent, { obs: obs }));
78
+ expect(react_1.screen.getByTestId("array-value")).toHaveTextContent('["a","b","c"]');
79
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("3");
80
+ });
81
+ it("should re-render when array is replaced with new reference", async () => {
82
+ const obs = (0, peers_sdk_1.observable)(["a", "b"]);
83
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ArrayTestComponent, { obs: obs }));
84
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("2");
85
+ (0, react_1.act)(() => {
86
+ obs(["a", "b", "c"]); // New array reference
96
87
  });
97
- await (0, react_2.waitFor)(() => {
98
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('3');
88
+ await (0, react_1.waitFor)(() => {
89
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("3");
99
90
  });
100
91
  });
101
- it('should NOT re-render when array is mutated in place (requires immutable updates)', async () => {
92
+ it("should NOT re-render when array is mutated in place (requires immutable updates)", async () => {
102
93
  // This tests the case where an array is mutated in place and notifySubscribers is called.
103
- //
94
+ //
104
95
  // IMPORTANT BEHAVIORAL NOTE:
105
- // The OLD implementation (useState + useEffect) had special handling that would
106
- // spread the array when it detected same-reference mutation:
96
+ // The OLD implementation (useState + useEffect) had special handling that would
97
+ // spread the array when it detected same-reference mutation:
107
98
  // if (isArray(newData) && newData === data) setData([...newData])
108
- //
99
+ //
109
100
  // The NEW implementation (useSyncExternalStore) does NOT do this.
110
101
  // useSyncExternalStore uses Object.is() comparison on getSnapshot results.
111
102
  // If the reference is the same, React won't re-render.
@@ -113,97 +104,95 @@ describe('useObservable', () => {
113
104
  // This is actually the CORRECT behavior - it encourages immutable data patterns
114
105
  // which are required for React 18 concurrent rendering to work correctly.
115
106
  // Mutating data in place can cause tearing in concurrent mode.
116
- const obs = (0, peers_sdk_1.observable)(['a', 'b']);
117
- (0, react_2.render)(react_1.default.createElement(ArrayTestComponent, { obs: obs }));
118
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('2');
119
- (0, react_2.act)(() => {
107
+ const obs = (0, peers_sdk_1.observable)(["a", "b"]);
108
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ArrayTestComponent, { obs: obs }));
109
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("2");
110
+ (0, react_1.act)(() => {
120
111
  // Mutate the array in place (BAD PRACTICE - don't do this!)
121
112
  const arr = obs();
122
- arr.push('c');
113
+ arr.push("c");
123
114
  obs.notifySubscribers();
124
115
  });
125
116
  // The observable itself has the mutated value
126
- expect(obs()).toEqual(['a', 'b', 'c']);
117
+ expect(obs()).toEqual(["a", "b", "c"]);
127
118
  // But the component did NOT re-render because the reference didn't change
128
119
  // This is expected with useSyncExternalStore - it requires immutable updates
129
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('2');
120
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("2");
130
121
  });
131
- it('should re-render when array is properly updated with spread', async () => {
122
+ it("should re-render when array is properly updated with spread", async () => {
132
123
  // This is the recommended pattern for updating arrays
133
- const obs = (0, peers_sdk_1.observable)(['a', 'b']);
134
- (0, react_2.render)(react_1.default.createElement(ArrayTestComponent, { obs: obs }));
135
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('2');
136
- (0, react_2.act)(() => {
137
- obs([...obs(), 'c']); // Proper immutable update
124
+ const obs = (0, peers_sdk_1.observable)(["a", "b"]);
125
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ArrayTestComponent, { obs: obs }));
126
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("2");
127
+ (0, react_1.act)(() => {
128
+ obs([...obs(), "c"]); // Proper immutable update
138
129
  });
139
- await (0, react_2.waitFor)(() => {
140
- expect(react_2.screen.getByTestId('array-length')).toHaveTextContent('3');
141
- expect(react_2.screen.getByTestId('array-value')).toHaveTextContent('["a","b","c"]');
130
+ await (0, react_1.waitFor)(() => {
131
+ expect(react_1.screen.getByTestId("array-length")).toHaveTextContent("3");
132
+ expect(react_1.screen.getByTestId("array-value")).toHaveTextContent('["a","b","c"]');
142
133
  });
143
134
  });
144
135
  });
145
- describe('subscription management', () => {
146
- it('should unsubscribe when component unmounts', () => {
147
- const obs = (0, peers_sdk_1.observable)('test');
136
+ describe("subscription management", () => {
137
+ it("should unsubscribe when component unmounts", () => {
138
+ const obs = (0, peers_sdk_1.observable)("test");
148
139
  const initialSubscriberCount = obs.subscriberCount();
149
- const { unmount } = (0, react_2.render)(react_1.default.createElement(TestComponent, { obs: obs }));
140
+ const { unmount } = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { obs: obs }));
150
141
  // Should have subscribed
151
142
  expect(obs.subscriberCount()).toBeGreaterThan(initialSubscriberCount);
152
143
  unmount();
153
144
  // Should have unsubscribed
154
145
  expect(obs.subscriberCount()).toBe(initialSubscriberCount);
155
146
  });
156
- it('should handle multiple components subscribing to same observable', async () => {
157
- const obs = (0, peers_sdk_1.observable)('shared');
158
- (0, react_2.render)(react_1.default.createElement("div", null,
159
- react_1.default.createElement(TestComponent, { obs: obs, testId: "value1" }),
160
- react_1.default.createElement(TestComponent, { obs: obs, testId: "value2" })));
161
- expect(react_2.screen.getByTestId('value1')).toHaveTextContent('"shared"');
162
- expect(react_2.screen.getByTestId('value2')).toHaveTextContent('"shared"');
163
- (0, react_2.act)(() => {
164
- obs('updated');
147
+ it("should handle multiple components subscribing to same observable", async () => {
148
+ const obs = (0, peers_sdk_1.observable)("shared");
149
+ (0, react_1.render)((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(TestComponent, { obs: obs, testId: "value1" }), (0, jsx_runtime_1.jsx)(TestComponent, { obs: obs, testId: "value2" })] }));
150
+ expect(react_1.screen.getByTestId("value1")).toHaveTextContent('"shared"');
151
+ expect(react_1.screen.getByTestId("value2")).toHaveTextContent('"shared"');
152
+ (0, react_1.act)(() => {
153
+ obs("updated");
165
154
  });
166
- await (0, react_2.waitFor)(() => {
167
- expect(react_2.screen.getByTestId('value1')).toHaveTextContent('"updated"');
168
- expect(react_2.screen.getByTestId('value2')).toHaveTextContent('"updated"');
155
+ await (0, react_1.waitFor)(() => {
156
+ expect(react_1.screen.getByTestId("value1")).toHaveTextContent('"updated"');
157
+ expect(react_1.screen.getByTestId("value2")).toHaveTextContent('"updated"');
169
158
  });
170
159
  });
171
160
  });
172
- describe('rapid updates', () => {
173
- it('should handle rapid sequential updates correctly', async () => {
161
+ describe("rapid updates", () => {
162
+ it("should handle rapid sequential updates correctly", async () => {
174
163
  const obs = (0, peers_sdk_1.observable)(0);
175
164
  function CounterComponent() {
176
165
  const [value] = (0, hooks_1.useObservable)(obs);
177
- return react_1.default.createElement("span", { "data-testid": "counter" }, value);
166
+ return (0, jsx_runtime_1.jsx)("span", { "data-testid": "counter", children: value });
178
167
  }
179
- (0, react_2.render)(react_1.default.createElement(CounterComponent, null));
180
- (0, react_2.act)(() => {
168
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(CounterComponent, {}));
169
+ (0, react_1.act)(() => {
181
170
  for (let i = 1; i <= 10; i++) {
182
171
  obs(i);
183
172
  }
184
173
  });
185
- await (0, react_2.waitFor)(() => {
186
- expect(react_2.screen.getByTestId('counter')).toHaveTextContent('10');
174
+ await (0, react_1.waitFor)(() => {
175
+ expect(react_1.screen.getByTestId("counter")).toHaveTextContent("10");
187
176
  });
188
177
  });
189
178
  });
190
179
  });
191
- describe('useObservableState', () => {
192
- it('should create an observable with the initial value', () => {
193
- (0, react_2.render)(react_1.default.createElement(ObservableStateTestComponent, { initialValue: 42 }));
194
- expect(react_2.screen.getByTestId('state-value')).toHaveTextContent('42');
180
+ describe("useObservableState", () => {
181
+ it("should create an observable with the initial value", () => {
182
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ObservableStateTestComponent, { initialValue: 42 }));
183
+ expect(react_1.screen.getByTestId("state-value")).toHaveTextContent("42");
195
184
  });
196
- it('should re-render when the observable is updated', async () => {
197
- (0, react_2.render)(react_1.default.createElement(ObservableStateTestComponent, { initialValue: 0 }));
198
- expect(react_2.screen.getByTestId('state-value')).toHaveTextContent('0');
199
- (0, react_2.act)(() => {
200
- react_2.screen.getByTestId('increment').click();
185
+ it("should re-render when the observable is updated", async () => {
186
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ObservableStateTestComponent, { initialValue: 0 }));
187
+ expect(react_1.screen.getByTestId("state-value")).toHaveTextContent("0");
188
+ (0, react_1.act)(() => {
189
+ react_1.screen.getByTestId("increment").click();
201
190
  });
202
- await (0, react_2.waitFor)(() => {
203
- expect(react_2.screen.getByTestId('state-value')).toHaveTextContent('1');
191
+ await (0, react_1.waitFor)(() => {
192
+ expect(react_1.screen.getByTestId("state-value")).toHaveTextContent("1");
204
193
  });
205
194
  });
206
- it('should maintain the same observable instance across re-renders', async () => {
195
+ it("should maintain the same observable instance across re-renders", async () => {
207
196
  let capturedObs = null;
208
197
  function CaptureObsComponent() {
209
198
  const obs = (0, hooks_1.useObservableState)(0);
@@ -211,37 +200,32 @@ describe('useObservableState', () => {
211
200
  capturedObs = obs;
212
201
  }
213
202
  const [value] = (0, hooks_1.useObservable)(obs);
214
- return (react_1.default.createElement("div", null,
215
- react_1.default.createElement("span", { "data-testid": "value" }, value),
216
- react_1.default.createElement("span", { "data-testid": "same-obs" }, obs === capturedObs ? 'same' : 'different'),
217
- react_1.default.createElement("button", { "data-testid": "update", onClick: () => obs(obs() + 1) }, "Update")));
203
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { "data-testid": "value", children: value }), (0, jsx_runtime_1.jsx)("span", { "data-testid": "same-obs", children: obs === capturedObs ? "same" : "different" }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "update", onClick: () => obs(obs() + 1), children: "Update" })] }));
218
204
  }
219
- (0, react_2.render)(react_1.default.createElement(CaptureObsComponent, null));
220
- expect(react_2.screen.getByTestId('same-obs')).toHaveTextContent('same');
205
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(CaptureObsComponent, {}));
206
+ expect(react_1.screen.getByTestId("same-obs")).toHaveTextContent("same");
221
207
  // Trigger a re-render by updating the observable
222
- (0, react_2.act)(() => {
223
- react_2.screen.getByTestId('update').click();
208
+ (0, react_1.act)(() => {
209
+ react_1.screen.getByTestId("update").click();
224
210
  });
225
- await (0, react_2.waitFor)(() => {
226
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('1');
227
- expect(react_2.screen.getByTestId('same-obs')).toHaveTextContent('same');
211
+ await (0, react_1.waitFor)(() => {
212
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent("1");
213
+ expect(react_1.screen.getByTestId("same-obs")).toHaveTextContent("same");
228
214
  });
229
215
  });
230
- it('should not subscribe when doNotSubscribe is true', () => {
216
+ it("should not subscribe when doNotSubscribe is true", () => {
231
217
  function NoSubscribeComponent() {
232
218
  const obs = (0, hooks_1.useObservableState)(0, true); // doNotSubscribe = true
233
- return (react_1.default.createElement("div", null,
234
- react_1.default.createElement("span", { "data-testid": "value" }, obs()),
235
- react_1.default.createElement("button", { "data-testid": "update", onClick: () => obs(obs() + 1) }, "Update")));
219
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { "data-testid": "value", children: obs() }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "update", onClick: () => obs(obs() + 1), children: "Update" })] }));
236
220
  }
237
- (0, react_2.render)(react_1.default.createElement(NoSubscribeComponent, null));
238
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('0');
221
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(NoSubscribeComponent, {}));
222
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent("0");
239
223
  // Update won't cause re-render since we're not subscribed
240
- (0, react_2.act)(() => {
241
- react_2.screen.getByTestId('update').click();
224
+ (0, react_1.act)(() => {
225
+ react_1.screen.getByTestId("update").click();
242
226
  });
243
227
  // Value in DOM should still show 0 since component didn't re-render
244
228
  // But the observable itself has been updated
245
- expect(react_2.screen.getByTestId('value')).toHaveTextContent('0');
229
+ expect(react_1.screen.getByTestId("value")).toHaveTextContent("0");
246
230
  });
247
231
  });