@perspective-dev/viewer 4.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 (394) hide show
  1. package/LICENSE.md +193 -0
  2. package/README.md +4 -0
  3. package/dist/cdn/perspective-viewer.js +3 -0
  4. package/dist/cdn/perspective-viewer.js.map +7 -0
  5. package/dist/css/dracula.css +1 -0
  6. package/dist/css/gruvbox-dark.css +1 -0
  7. package/dist/css/gruvbox.css +1 -0
  8. package/dist/css/icons.css +1 -0
  9. package/dist/css/intl/de.css +1 -0
  10. package/dist/css/intl/es.css +1 -0
  11. package/dist/css/intl/fr.css +1 -0
  12. package/dist/css/intl/ja.css +1 -0
  13. package/dist/css/intl/pt.css +1 -0
  14. package/dist/css/intl/zh.css +1 -0
  15. package/dist/css/intl.css +1 -0
  16. package/dist/css/monokai.css +1 -0
  17. package/dist/css/pro-dark.css +1 -0
  18. package/dist/css/pro.css +1 -0
  19. package/dist/css/solarized-dark.css +1 -0
  20. package/dist/css/solarized.css +1 -0
  21. package/dist/css/themes.css +1 -0
  22. package/dist/css/vaporwave.css +1 -0
  23. package/dist/css/variables.css +0 -0
  24. package/dist/esm/bootstrap.d.ts +1 -0
  25. package/dist/esm/extensions.d.ts +70 -0
  26. package/dist/esm/perspective-viewer.d.ts +39 -0
  27. package/dist/esm/perspective-viewer.inline.js +3 -0
  28. package/dist/esm/perspective-viewer.inline.js.map +7 -0
  29. package/dist/esm/perspective-viewer.js +3 -0
  30. package/dist/esm/perspective-viewer.js.map +7 -0
  31. package/dist/esm/plugin.d.ts +195 -0
  32. package/dist/esm/ts-rs/Aggregate.d.ts +1 -0
  33. package/dist/esm/ts-rs/ColumnConfigValues.d.ts +31 -0
  34. package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +1 -0
  35. package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +15 -0
  36. package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +18 -0
  37. package/dist/esm/ts-rs/DatetimeColorMode.d.ts +1 -0
  38. package/dist/esm/ts-rs/DatetimeFormatType.d.ts +6 -0
  39. package/dist/esm/ts-rs/Expressions.d.ts +3 -0
  40. package/dist/esm/ts-rs/Filter.d.ts +2 -0
  41. package/dist/esm/ts-rs/FilterReducer.d.ts +1 -0
  42. package/dist/esm/ts-rs/FilterTerm.d.ts +2 -0
  43. package/dist/esm/ts-rs/FormatMode.d.ts +1 -0
  44. package/dist/esm/ts-rs/FormatUnit.d.ts +1 -0
  45. package/dist/esm/ts-rs/NumberBackgroundMode.d.ts +1 -0
  46. package/dist/esm/ts-rs/NumberForegroundMode.d.ts +1 -0
  47. package/dist/esm/ts-rs/OptionalUpdate.d.ts +1 -0
  48. package/dist/esm/ts-rs/PluginConfig.d.ts +2 -0
  49. package/dist/esm/ts-rs/RoundingMode.d.ts +1 -0
  50. package/dist/esm/ts-rs/RoundingPriority.d.ts +1 -0
  51. package/dist/esm/ts-rs/Scalar.d.ts +5 -0
  52. package/dist/esm/ts-rs/SignDisplay.d.ts +1 -0
  53. package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +1 -0
  54. package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +6 -0
  55. package/dist/esm/ts-rs/Sort.d.ts +2 -0
  56. package/dist/esm/ts-rs/SortDir.d.ts +1 -0
  57. package/dist/esm/ts-rs/StringColorMode.d.ts +1 -0
  58. package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +1 -0
  59. package/dist/esm/ts-rs/UseGrouping.d.ts +1 -0
  60. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +102 -0
  61. package/dist/esm/ts-rs/serde_json/JsonValue.d.ts +3 -0
  62. package/dist/wasm/perspective-viewer.d.ts +1291 -0
  63. package/dist/wasm/perspective-viewer.js +3883 -0
  64. package/dist/wasm/perspective-viewer.wasm +0 -0
  65. package/dist/wasm/perspective-viewer.wasm.d.ts +142 -0
  66. package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline0.js +1 -0
  67. package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline1.js +1 -0
  68. package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline2.js +1 -0
  69. package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline3.js +44 -0
  70. package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline4.js +1 -0
  71. package/package.json +55 -0
  72. package/src/less/aggregate-selector.less +72 -0
  73. package/src/less/column-dropdown.less +95 -0
  74. package/src/less/column-selector.less +551 -0
  75. package/src/less/column-settings-panel.less +255 -0
  76. package/src/less/column-style.less +319 -0
  77. package/src/less/column-symbol-attributes.less +73 -0
  78. package/src/less/config-selector.less +363 -0
  79. package/src/less/containers/dropdown-menu.less +94 -0
  80. package/src/less/containers/pairs-list.less +46 -0
  81. package/src/less/containers/radio-list.less +29 -0
  82. package/src/less/containers/scroll-panel.less +27 -0
  83. package/src/less/containers/split-panel.less +80 -0
  84. package/src/less/containers/tabs.less +90 -0
  85. package/src/less/dom/checkbox.less +100 -0
  86. package/src/less/dom/scrollbar.less +35 -0
  87. package/src/less/dom/select.less +63 -0
  88. package/src/less/empty-column.less +72 -0
  89. package/src/less/expression-editor.less +152 -0
  90. package/src/less/filter-dropdown.less +53 -0
  91. package/src/less/filter-item.less +126 -0
  92. package/src/less/form/code-editor.less +137 -0
  93. package/src/less/form/debug.less +88 -0
  94. package/src/less/function-dropdown.less +45 -0
  95. package/src/less/plugin-selector.less +173 -0
  96. package/src/less/render-warning.less +81 -0
  97. package/src/less/status-bar.less +551 -0
  98. package/src/less/type-icon.less +68 -0
  99. package/src/less/viewer.less +368 -0
  100. package/src/rust/components/column_dropdown.rs +162 -0
  101. package/src/rust/components/column_selector/active_column.rs +462 -0
  102. package/src/rust/components/column_selector/add_expression_button.rs +59 -0
  103. package/src/rust/components/column_selector/aggregate_selector.rs +186 -0
  104. package/src/rust/components/column_selector/config_selector.rs +674 -0
  105. package/src/rust/components/column_selector/empty_column.rs +134 -0
  106. package/src/rust/components/column_selector/expression_toolbar.rs +45 -0
  107. package/src/rust/components/column_selector/filter_column.rs +530 -0
  108. package/src/rust/components/column_selector/inactive_column.rs +221 -0
  109. package/src/rust/components/column_selector/invalid_column.rs +37 -0
  110. package/src/rust/components/column_selector/pivot_column.rs +93 -0
  111. package/src/rust/components/column_selector/sort_column.rs +135 -0
  112. package/src/rust/components/column_selector.rs +426 -0
  113. package/src/rust/components/column_settings_sidebar/attributes_tab.rs +34 -0
  114. package/src/rust/components/column_settings_sidebar/mod.rs +17 -0
  115. package/src/rust/components/column_settings_sidebar/save_settings.rs +68 -0
  116. package/src/rust/components/column_settings_sidebar/sidebar.rs +396 -0
  117. package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +177 -0
  118. package/src/rust/components/column_settings_sidebar/style_tab/stub.rs +34 -0
  119. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +101 -0
  120. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_config.rs +24 -0
  121. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +185 -0
  122. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +55 -0
  123. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +131 -0
  124. package/src/rust/components/column_settings_sidebar/style_tab.rs +231 -0
  125. package/src/rust/components/containers/dragdrop_list.rs +325 -0
  126. package/src/rust/components/containers/dropdown_menu.rs +104 -0
  127. package/src/rust/components/containers/kvpair.rs +47 -0
  128. package/src/rust/components/containers/mod.rs +28 -0
  129. package/src/rust/components/containers/scroll_panel.rs +311 -0
  130. package/src/rust/components/containers/scroll_panel_item.rs +111 -0
  131. package/src/rust/components/containers/select.rs +269 -0
  132. package/src/rust/components/containers/sidebar.rs +89 -0
  133. package/src/rust/components/containers/split_panel.rs +483 -0
  134. package/src/rust/components/containers/tab_list.rs +104 -0
  135. package/src/rust/components/containers/tests/mod.rs +11 -0
  136. package/src/rust/components/containers/tests/split_panel.rs +91 -0
  137. package/src/rust/components/containers/trap_door_panel.rs +50 -0
  138. package/src/rust/components/copy_dropdown.rs +136 -0
  139. package/src/rust/components/datetime_column_style/custom.rs +222 -0
  140. package/src/rust/components/datetime_column_style/simple.rs +122 -0
  141. package/src/rust/components/datetime_column_style.rs +284 -0
  142. package/src/rust/components/editable_header.rs +183 -0
  143. package/src/rust/components/empty_row.rs +169 -0
  144. package/src/rust/components/error_message.rs +56 -0
  145. package/src/rust/components/export_dropdown.rs +153 -0
  146. package/src/rust/components/expression_editor.rs +153 -0
  147. package/src/rust/components/filter_dropdown.rs +144 -0
  148. package/src/rust/components/font_loader.rs +254 -0
  149. package/src/rust/components/form/code_editor.rs +286 -0
  150. package/src/rust/components/form/color_range_selector.rs +115 -0
  151. package/src/rust/components/form/color_selector.rs +54 -0
  152. package/src/rust/components/form/debug.rs +253 -0
  153. package/src/rust/components/form/highlight.rs +50 -0
  154. package/src/rust/components/form/mod.rs +29 -0
  155. package/src/rust/components/form/number_field.rs +72 -0
  156. package/src/rust/components/form/number_input.rs +45 -0
  157. package/src/rust/components/form/number_range_field.rs +77 -0
  158. package/src/rust/components/form/optional_field.rs +53 -0
  159. package/src/rust/components/form/select_field.rs +104 -0
  160. package/src/rust/components/function_dropdown.rs +151 -0
  161. package/src/rust/components/mod.rs +45 -0
  162. package/src/rust/components/modal.rs +171 -0
  163. package/src/rust/components/number_column_style.rs +522 -0
  164. package/src/rust/components/plugin_selector.rs +196 -0
  165. package/src/rust/components/render_warning.rs +178 -0
  166. package/src/rust/components/status_bar.rs +315 -0
  167. package/src/rust/components/status_bar_counter.rs +229 -0
  168. package/src/rust/components/status_indicator.rs +164 -0
  169. package/src/rust/components/string_column_style.rs +186 -0
  170. package/src/rust/components/style/local_style.rs +35 -0
  171. package/src/rust/components/style/mod.rs +52 -0
  172. package/src/rust/components/style/style_cache.rs +132 -0
  173. package/src/rust/components/style/style_provider.rs +65 -0
  174. package/src/rust/components/style_controls/number_string_format/digits_section.rs +140 -0
  175. package/src/rust/components/style_controls/number_string_format/misc_section.rs +56 -0
  176. package/src/rust/components/style_controls/number_string_format/style_section.rs +69 -0
  177. package/src/rust/components/style_controls/number_string_format/types.rs +31 -0
  178. package/src/rust/components/style_controls/number_string_format.rs +259 -0
  179. package/src/rust/components/style_controls.rs +15 -0
  180. package/src/rust/components/type_icon.rs +53 -0
  181. package/src/rust/components/viewer.rs +668 -0
  182. package/src/rust/config/columns_config.rs +132 -0
  183. package/src/rust/config/datetime_column_style/color_mode.rs +62 -0
  184. package/src/rust/config/datetime_column_style/custom.rs +121 -0
  185. package/src/rust/config/datetime_column_style/custom_format.rs +90 -0
  186. package/src/rust/config/datetime_column_style/simple.rs +55 -0
  187. package/src/rust/config/datetime_column_style/simple_format.rs +86 -0
  188. package/src/rust/config/datetime_column_style.rs +104 -0
  189. package/src/rust/config/mod.rs +30 -0
  190. package/src/rust/config/number_column_style.rs +138 -0
  191. package/src/rust/config/number_string_format/enums.rs +298 -0
  192. package/src/rust/config/number_string_format.rs +269 -0
  193. package/src/rust/config/string_column_style.rs +140 -0
  194. package/src/rust/config/view_config.rs +24 -0
  195. package/src/rust/config/viewer_config.rs +337 -0
  196. package/src/rust/custom_elements/column_dropdown.rs +123 -0
  197. package/src/rust/custom_elements/copy_dropdown.rs +112 -0
  198. package/src/rust/custom_elements/debug_plugin.rs +114 -0
  199. package/src/rust/custom_elements/export_dropdown.rs +112 -0
  200. package/src/rust/custom_elements/filter_dropdown.rs +179 -0
  201. package/src/rust/custom_elements/function_dropdown.rs +115 -0
  202. package/src/rust/custom_elements/mod.rs +24 -0
  203. package/src/rust/custom_elements/modal.rs +395 -0
  204. package/src/rust/custom_elements/viewer.rs +880 -0
  205. package/src/rust/custom_events.rs +214 -0
  206. package/src/rust/dragdrop.rs +362 -0
  207. package/src/rust/exprtk/cursor.rs +81 -0
  208. package/src/rust/exprtk/mod.rs +17 -0
  209. package/src/rust/exprtk/tokenize/comment.rs +21 -0
  210. package/src/rust/exprtk/tokenize/number.rs +44 -0
  211. package/src/rust/exprtk/tokenize/string.rs +98 -0
  212. package/src/rust/exprtk/tokenize/symbol.rs +26 -0
  213. package/src/rust/exprtk/tokenize.rs +190 -0
  214. package/src/rust/js/clipboard.rs +77 -0
  215. package/src/rust/js/clipboard_item.rs +21 -0
  216. package/src/rust/js/intersection_observer.rs +32 -0
  217. package/src/rust/js/mimetype.rs +42 -0
  218. package/src/rust/js/mod.rs +29 -0
  219. package/src/rust/js/plugin.rs +167 -0
  220. package/src/rust/js/resize_observer.rs +37 -0
  221. package/src/rust/js/testing.rs +149 -0
  222. package/src/rust/lib.rs +116 -0
  223. package/src/rust/model/columns_iter_set.rs +340 -0
  224. package/src/rust/model/copy_export.rs +157 -0
  225. package/src/rust/model/create_col.rs +59 -0
  226. package/src/rust/model/edit_expression.rs +95 -0
  227. package/src/rust/model/export_app.rs +58 -0
  228. package/src/rust/model/export_method.rs +151 -0
  229. package/src/rust/model/get_viewer_config.rs +85 -0
  230. package/src/rust/model/intersection_observer.rs +81 -0
  231. package/src/rust/model/is_invalid_drop.rs +36 -0
  232. package/src/rust/model/mod.rs +93 -0
  233. package/src/rust/model/plugin_column_styles.rs +106 -0
  234. package/src/rust/model/resize_observer.rs +98 -0
  235. package/src/rust/model/restore_and_render.rs +113 -0
  236. package/src/rust/model/structural.rs +73 -0
  237. package/src/rust/model/update_and_render.rs +74 -0
  238. package/src/rust/presentation.rs +370 -0
  239. package/src/rust/renderer/activate.rs +49 -0
  240. package/src/rust/renderer/limits.rs +200 -0
  241. package/src/rust/renderer/plugin_store.rs +45 -0
  242. package/src/rust/renderer/registry.rs +135 -0
  243. package/src/rust/renderer/render_timer.rs +185 -0
  244. package/src/rust/renderer.rs +463 -0
  245. package/src/rust/session/column_defaults_update.rs +141 -0
  246. package/src/rust/session/drag_drop_update.rs +179 -0
  247. package/src/rust/session/metadata.rs +308 -0
  248. package/src/rust/session/replace_expression_update.rs +131 -0
  249. package/src/rust/session/view_subscription.rs +189 -0
  250. package/src/rust/session.rs +794 -0
  251. package/src/rust/utils/browser/blob.rs +49 -0
  252. package/src/rust/utils/browser/download.rs +26 -0
  253. package/src/rust/utils/browser/mod.rs +24 -0
  254. package/src/rust/utils/browser/request_animation_frame.rs +76 -0
  255. package/src/rust/utils/browser/selection.rs +79 -0
  256. package/src/rust/utils/browser/tests/debounce.rs +114 -0
  257. package/src/rust/utils/browser/tests/mod.rs +13 -0
  258. package/src/rust/utils/custom_element.rs +85 -0
  259. package/src/rust/utils/datetime.rs +49 -0
  260. package/src/rust/utils/debounce.rs +54 -0
  261. package/src/rust/utils/hooks/mod.rs +15 -0
  262. package/src/rust/utils/hooks/use_async_callback.rs +53 -0
  263. package/src/rust/utils/mod.rs +114 -0
  264. package/src/rust/utils/number_format.rs +48 -0
  265. package/src/rust/utils/pubsub.rs +222 -0
  266. package/src/rust/utils/scope.rs +54 -0
  267. package/src/rust/utils/tee.rs +88 -0
  268. package/src/rust/utils/tests/mod.rs +14 -0
  269. package/src/rust/utils/tests/pubsub.rs +95 -0
  270. package/src/rust/utils/tests/request_animation_frame.rs +42 -0
  271. package/src/rust/utils/wasm_abi.rs +61 -0
  272. package/src/rust/utils/weak_scope.rs +39 -0
  273. package/src/svg/align-scroll-icon.svg +7 -0
  274. package/src/svg/bg-pattern.png +0 -0
  275. package/src/svg/boolean-type.svg +3 -0
  276. package/src/svg/checkbox-checked-icon.svg +7 -0
  277. package/src/svg/checkbox-hover.svg +4 -0
  278. package/src/svg/checkbox-off.svg +4 -0
  279. package/src/svg/checkbox-on.svg +4 -0
  280. package/src/svg/checkbox-unchecked-icon.svg +3 -0
  281. package/src/svg/close-icon.svg +6 -0
  282. package/src/svg/column-settings-icon.svg +6 -0
  283. package/src/svg/datagrid-select-column.svg +15 -0
  284. package/src/svg/datagrid-select-region.svg +15 -0
  285. package/src/svg/datagrid-select-row.svg +13 -0
  286. package/src/svg/datagrid.svg +13 -0
  287. package/src/svg/date-type.svg +23 -0
  288. package/src/svg/downloading.gif +0 -0
  289. package/src/svg/drag-handle.svg +10 -0
  290. package/src/svg/drawer-bg-pattern-hidpi.png +0 -0
  291. package/src/svg/drawer-tab-hover.svg +8 -0
  292. package/src/svg/drawer-tab-invert-hover.svg +9 -0
  293. package/src/svg/drawer-tab-invert.svg +8 -0
  294. package/src/svg/drawer-tab.svg +7 -0
  295. package/src/svg/dropdown-selector-light.svg +3 -0
  296. package/src/svg/dropdown-selector.svg +3 -0
  297. package/src/svg/duplicate-icon.svg +4 -0
  298. package/src/svg/editable-icon.svg +5 -0
  299. package/src/svg/export-icon.svg +4 -0
  300. package/src/svg/expression.svg +10 -0
  301. package/src/svg/free-scroll-icon.svg +5 -0
  302. package/src/svg/inactive-mouseover.svg +4 -0
  303. package/src/svg/mega-menu-icons-candlestick.svg +38 -0
  304. package/src/svg/mega-menu-icons-datagrid.svg +38 -0
  305. package/src/svg/mega-menu-icons-heatmap.svg +60 -0
  306. package/src/svg/mega-menu-icons-map-scatter.svg +43 -0
  307. package/src/svg/mega-menu-icons-ohlc.svg +40 -0
  308. package/src/svg/mega-menu-icons-sunburst.svg +39 -0
  309. package/src/svg/mega-menu-icons-treemap.svg +44 -0
  310. package/src/svg/mega-menu-icons-x-bar.svg +36 -0
  311. package/src/svg/mega-menu-icons-x-y-line.svg +38 -0
  312. package/src/svg/mega-menu-icons-x-y-scatter.svg +72 -0
  313. package/src/svg/mega-menu-icons-y-area.svg +73 -0
  314. package/src/svg/mega-menu-icons-y-bar.svg +36 -0
  315. package/src/svg/mega-menu-icons-y-line.svg +36 -0
  316. package/src/svg/mega-menu-icons-y-scatter.svg +72 -0
  317. package/src/svg/number-type.svg +4 -0
  318. package/src/svg/radio-hover.svg +4 -0
  319. package/src/svg/radio-off.svg +3 -0
  320. package/src/svg/radio-on.svg +4 -0
  321. package/src/svg/read-only-icon.svg +6 -0
  322. package/src/svg/revert-icon.svg +4 -0
  323. package/src/svg/sort-abs-asc-icon.svg +3 -0
  324. package/src/svg/sort-abs-col-asc-icon.svg +3 -0
  325. package/src/svg/sort-abs-col-desc-icon.svg +3 -0
  326. package/src/svg/sort-abs-desc-icon.svg +3 -0
  327. package/src/svg/sort-asc-icon.svg +4 -0
  328. package/src/svg/sort-col-asc-icon.svg +4 -0
  329. package/src/svg/sort-col-desc-icon.svg +4 -0
  330. package/src/svg/sort-desc-icon.svg +4 -0
  331. package/src/svg/sort-none-icon.svg +3 -0
  332. package/src/svg/status_error.svg +70 -0
  333. package/src/svg/status_ok.svg +26 -0
  334. package/src/svg/string-type.svg +8 -0
  335. package/src/svg/theme-icon.svg +5 -0
  336. package/src/svg/updating.gif +0 -0
  337. package/src/themes/dracula.less +101 -0
  338. package/src/themes/gruvbox-dark.less +116 -0
  339. package/src/themes/gruvbox.less +152 -0
  340. package/src/themes/icons.less +130 -0
  341. package/src/themes/intl/de.less +102 -0
  342. package/src/themes/intl/es.less +102 -0
  343. package/src/themes/intl/fr.less +102 -0
  344. package/src/themes/intl/ja.less +102 -0
  345. package/src/themes/intl/pt.less +102 -0
  346. package/src/themes/intl/zh.less +102 -0
  347. package/src/themes/intl.less +102 -0
  348. package/src/themes/monokai.less +107 -0
  349. package/src/themes/pro-dark.less +147 -0
  350. package/src/themes/pro.less +186 -0
  351. package/src/themes/solarized-dark.less +78 -0
  352. package/src/themes/solarized.less +102 -0
  353. package/src/themes/themes.less +21 -0
  354. package/src/themes/vaporwave.less +145 -0
  355. package/src/themes/variables.less +24 -0
  356. package/src/ts/bootstrap.ts +26 -0
  357. package/src/ts/extensions.ts +124 -0
  358. package/src/ts/perspective-viewer.cdn.ts +19 -0
  359. package/src/ts/perspective-viewer.inline.ts +23 -0
  360. package/src/ts/perspective-viewer.ts +59 -0
  361. package/src/ts/plugin.ts +279 -0
  362. package/src/ts/ts-rs/Aggregate.ts +3 -0
  363. package/src/ts/ts-rs/ColumnConfigValues.ts +14 -0
  364. package/src/ts/ts-rs/CustomDatetimeFormat.ts +3 -0
  365. package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +5 -0
  366. package/src/ts/ts-rs/CustomNumberFormatConfig.ts +8 -0
  367. package/src/ts/ts-rs/DatetimeColorMode.ts +3 -0
  368. package/src/ts/ts-rs/DatetimeFormatType.ts +8 -0
  369. package/src/ts/ts-rs/Expressions.ts +3 -0
  370. package/src/ts/ts-rs/Filter.ts +4 -0
  371. package/src/ts/ts-rs/FilterReducer.ts +3 -0
  372. package/src/ts/ts-rs/FilterTerm.ts +4 -0
  373. package/src/ts/ts-rs/FormatMode.ts +3 -0
  374. package/src/ts/ts-rs/FormatUnit.ts +3 -0
  375. package/src/ts/ts-rs/NumberBackgroundMode.ts +3 -0
  376. package/src/ts/ts-rs/NumberForegroundMode.ts +3 -0
  377. package/src/ts/ts-rs/OnUpdateData.ts +8 -0
  378. package/src/ts/ts-rs/OptionalUpdate.ts +3 -0
  379. package/src/ts/ts-rs/PluginConfig.ts +4 -0
  380. package/src/ts/ts-rs/RoundingMode.ts +3 -0
  381. package/src/ts/ts-rs/RoundingPriority.ts +3 -0
  382. package/src/ts/ts-rs/Scalar.ts +7 -0
  383. package/src/ts/ts-rs/SignDisplay.ts +3 -0
  384. package/src/ts/ts-rs/SimpleDatetimeFormat.ts +3 -0
  385. package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +4 -0
  386. package/src/ts/ts-rs/Sort.ts +4 -0
  387. package/src/ts/ts-rs/SortDir.ts +3 -0
  388. package/src/ts/ts-rs/StringColorMode.ts +3 -0
  389. package/src/ts/ts-rs/TrailingZeroDisplay.ts +3 -0
  390. package/src/ts/ts-rs/UseGrouping.ts +3 -0
  391. package/src/ts/ts-rs/ViewOnUpdateResp.ts +3 -0
  392. package/src/ts/ts-rs/ViewerConfigUpdate.ts +90 -0
  393. package/src/ts/ts-rs/serde_json/JsonValue.ts +3 -0
  394. package/tsconfig.json +15 -0
@@ -0,0 +1,53 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use wasm_bindgen::__rt::IntoJsResult;
14
+ use wasm_bindgen_futures::future_to_promise;
15
+ use yew::prelude::*;
16
+
17
+ use crate::renderer::*;
18
+ use crate::session::*;
19
+ use crate::*;
20
+
21
+ #[derive(Clone, Properties, PartialEq)]
22
+ pub struct StatusIndicatorProps {
23
+ pub session: Session,
24
+ pub renderer: Renderer,
25
+ pub children: Children,
26
+ }
27
+
28
+ /// Just like `use_callback`, except convenient for an async cresult body.
29
+ #[hook]
30
+ pub fn use_async_callback<IN, OUT, F, D>(deps: D, f: F) -> Callback<IN, ()>
31
+ where
32
+ IN: Clone + 'static,
33
+ OUT: IntoJsResult + 'static,
34
+ F: AsyncFn(IN, &D) -> OUT + 'static,
35
+ D: Clone + PartialEq + 'static,
36
+ {
37
+ let deps = std::rc::Rc::new(deps);
38
+ let f = std::rc::Rc::new(f);
39
+ (*use_memo(deps, move |deps| {
40
+ let deps = deps.clone();
41
+ let ff = move |value: IN| {
42
+ let value = value.clone();
43
+ let f = f.clone();
44
+ let deps = deps.clone();
45
+ let _ = future_to_promise(async move {
46
+ f(value, &deps).await.into_js_result()?;
47
+ Ok(JsValue::UNDEFINED)
48
+ });
49
+ };
50
+ Callback::from(ff)
51
+ }))
52
+ .clone()
53
+ }
@@ -0,0 +1,114 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ //! A catch all for project-wide macros and general-purpose functions that are
14
+ //! not directly related to Perspective.
15
+ //!
16
+ //! Modules below `crate::utils` strive to be single-responsibility, but some
17
+ //! reference other `crate::utils` modules when it helps reduce boiler-plate.
18
+
19
+ mod browser;
20
+
21
+ mod custom_element;
22
+ mod datetime;
23
+ mod debounce;
24
+ mod hooks;
25
+ mod number_format;
26
+ mod pubsub;
27
+ mod scope;
28
+ mod tee;
29
+ mod wasm_abi;
30
+ mod weak_scope;
31
+
32
+ #[cfg(test)]
33
+ mod tests;
34
+
35
+ pub use browser::*;
36
+ pub use custom_element::*;
37
+ pub use datetime::*;
38
+ pub use debounce::*;
39
+ pub use hooks::*;
40
+ pub use number_format::*;
41
+ pub use perspective_client::clone;
42
+ pub use pubsub::*;
43
+ pub use scope::*;
44
+ pub use tee::*;
45
+ pub use weak_scope::*;
46
+
47
+ #[macro_export]
48
+ macro_rules! maybe {
49
+ ($($exp:stmt);*) => {{
50
+ let x = ({
51
+ #[inline(always)]
52
+ || {
53
+ $($exp)*
54
+ }
55
+ })();
56
+ x
57
+ }};
58
+ }
59
+
60
+ #[macro_export]
61
+ macro_rules! js_log_maybe {
62
+ ($($exp:tt)+) => {{
63
+ let x = ({
64
+ #[inline(always)]
65
+ || {
66
+ {
67
+ $($exp)+
68
+ };
69
+ Ok(())
70
+ }
71
+ })();
72
+ x.unwrap_or_else(|e| web_sys::console::warn_1(&e))
73
+ }};
74
+ }
75
+
76
+ #[macro_export]
77
+ macro_rules! max {
78
+ ($x:expr) => ($x);
79
+ ($x:expr, $($z:expr),+ $(,)?) => {{
80
+ let x = $x;
81
+ let y = max!($($z),*);
82
+ if x > y {
83
+ x
84
+ } else {
85
+ y
86
+ }
87
+ }}
88
+ }
89
+
90
+ #[macro_export]
91
+ macro_rules! min {
92
+ ($x:expr) => ($x);
93
+ ($x:expr, $($z:expr),+ $(,)?) => {{
94
+ let x = $x;
95
+ let y = min!($($z),*);
96
+ if x < y {
97
+ x
98
+ } else {
99
+ y
100
+ }
101
+ }}
102
+ }
103
+
104
+ #[macro_export]
105
+ macro_rules! js_log {
106
+ ($x:expr) => {{
107
+ const DEBUG_ONLY_WARNING: &str = $x;
108
+ web_sys::console::log_1(&wasm_bindgen::JsValue::from($x));
109
+ }};
110
+ ($x:expr $(, $y:expr)*) => {{
111
+ const DEBUG_ONLY_WARNING: &str = $x;
112
+ web_sys::console::log_1(&format!($x, $($y),*).into());
113
+ }};
114
+ }
@@ -0,0 +1,48 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use std::sync::LazyLock;
14
+
15
+ use js_sys::Intl;
16
+ use perspective_js::json;
17
+ use perspective_js::utils::global::navigator;
18
+ use wasm_bindgen::JsValue;
19
+
20
+ pub trait ToFormattedString {
21
+ fn to_formatted_string(&self) -> String;
22
+ }
23
+
24
+ struct UnsafeNumberFormat(Intl::NumberFormat);
25
+
26
+ unsafe impl Send for UnsafeNumberFormat {}
27
+ unsafe impl Sync for UnsafeNumberFormat {}
28
+
29
+ static NUMBER_FORMAT: LazyLock<UnsafeNumberFormat> = LazyLock::new(|| {
30
+ let locale = navigator().languages();
31
+ let opts = json!({});
32
+ let number_format = Intl::NumberFormat::new(&locale, &opts);
33
+ UnsafeNumberFormat(number_format)
34
+ });
35
+
36
+ impl UnsafeNumberFormat {}
37
+
38
+ impl ToFormattedString for u32 {
39
+ fn to_formatted_string(&self) -> String {
40
+ NUMBER_FORMAT
41
+ .0
42
+ .format()
43
+ .call1(&NUMBER_FORMAT.0, &JsValue::from_f64(*self as f64))
44
+ .unwrap()
45
+ .as_string()
46
+ .unwrap()
47
+ }
48
+ }
@@ -0,0 +1,222 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use std::cell::{Cell, RefCell};
14
+ use std::collections::HashMap;
15
+ use std::rc::{Rc, Weak};
16
+
17
+ use derivative::Derivative;
18
+ use futures::channel::oneshot::*;
19
+ use yew::prelude::*;
20
+
21
+ /// An internal `HashSet` variant which supports unconstrained `T` e.g.
22
+ /// without `Hash`, via returning a unique `usize` index for each insert
23
+ /// which can be used for a reciprocal `remove(x: usize)`.
24
+ #[derive(Derivative)]
25
+ #[derivative(Default(bound = ""))]
26
+ struct IndexedSet<T> {
27
+ set: HashMap<usize, T>,
28
+ gen_: usize,
29
+ }
30
+
31
+ impl<T> IndexedSet<T> {
32
+ fn insert(&mut self, v: T) -> usize {
33
+ let key = self.gen_;
34
+ self.set.insert(key, v);
35
+ self.gen_ += 1;
36
+ key
37
+ }
38
+
39
+ fn remove(&mut self, key: usize) {
40
+ self.set.remove(&key);
41
+ }
42
+
43
+ fn iter(&self) -> impl Iterator<Item = &T> {
44
+ self.set.values()
45
+ }
46
+
47
+ fn drain(&mut self) -> impl Iterator<Item = T> {
48
+ let mut x = Box::default();
49
+ std::mem::swap(&mut self.set, &mut x);
50
+ x.into_values()
51
+ }
52
+ }
53
+
54
+ type ListenerSet<T> = IndexedSet<Box<dyn Fn(T) + 'static>>;
55
+ type ListenerOnceSet<T> = IndexedSet<Box<dyn FnOnce(T) + 'static>>;
56
+
57
+ #[derive(Derivative)]
58
+ #[derivative(Default(bound = ""))]
59
+ pub struct PubSubInternal<T: Clone> {
60
+ deleted: Cell<bool>,
61
+ listeners: RefCell<ListenerSet<T>>,
62
+ once_listeners: RefCell<ListenerOnceSet<T>>,
63
+ }
64
+
65
+ impl<T: Clone> PubSubInternal<T> {
66
+ fn emit(&self, val: T) {
67
+ if self.deleted.get() {
68
+ tracing::warn!("`Callback` invoked after `PubSub` dropped");
69
+ }
70
+
71
+ for listener in self.listeners.borrow().iter() {
72
+ listener(val.clone());
73
+ }
74
+
75
+ for listener in self.once_listeners.borrow_mut().drain() {
76
+ listener(val.clone());
77
+ }
78
+ }
79
+ }
80
+
81
+ /// A pub/sub struct which allows many listeners to subscribe to many
82
+ /// publishers, without leaking callbacks as listeners are dropped.
83
+ ///
84
+ /// Unlike `mpsc` etc., `PubSub` has no internal queue and is completely
85
+ /// synchronous.
86
+ #[derive(Derivative)]
87
+ #[derivative(Default(bound = ""))]
88
+ pub struct PubSub<T: Clone>(Rc<PubSubInternal<T>>);
89
+
90
+ unsafe impl<T: Clone> Send for PubSub<T> {}
91
+ unsafe impl<T: Clone> Sync for PubSub<T> {}
92
+
93
+ pub trait AddListener<T> {
94
+ /// Register a listener to this `PubSub<_>`, which will be automatically
95
+ /// deregistered when the return `Subscription` is dropped.
96
+ ///
97
+ /// # Arguments
98
+ /// - `f` The callback, presumably a function-like type.
99
+ fn add_listener(&self, f: T) -> Subscription;
100
+ }
101
+
102
+ impl<T: Clone + 'static> PubSub<T> {
103
+ /// Emit a value to all listeners.
104
+ ///
105
+ /// # Arguments
106
+ /// - `val` The value to emit.
107
+ pub fn emit(&self, val: T) {
108
+ self.0.emit(val);
109
+ }
110
+
111
+ /// Get this `PubSub<_>`'s `.emit_all()` method as a `Callback<T>`.
112
+ pub fn callback(&self) -> Callback<T> {
113
+ let internal = self.0.clone();
114
+ Callback::from(move |val: T| internal.emit(val))
115
+ }
116
+
117
+ pub fn as_boxfn(&self) -> Box<dyn Fn(T) + Send + Sync + 'static> {
118
+ let internal = PubSub(self.0.clone());
119
+ Box::new(move |val: T| internal.emit(val))
120
+ }
121
+
122
+ /// Await this `PubSub<_>`'s next call to `emit_all()`, once.
123
+ pub async fn listen_once(&self) -> Result<T, Canceled> {
124
+ let (sender, receiver) = channel::<T>();
125
+ let f = move |x| sender.send(x).unwrap_or(());
126
+ self.0.once_listeners.borrow_mut().insert(Box::new(f));
127
+ receiver.await
128
+ }
129
+
130
+ /// Create a `Subscriber` from this `PubSub`, which is the reciprocal of
131
+ /// `PubSub::callback` (a struct which only allows sending), a struct which
132
+ /// only allows receiving via `Subscriber::add_listener`.
133
+ pub fn subscriber(&self) -> Subscriber<T> {
134
+ Subscriber(Rc::<PubSubInternal<T>>::downgrade(&self.0))
135
+ }
136
+ }
137
+
138
+ impl<T: Clone> Drop for PubSub<T> {
139
+ fn drop(&mut self) {
140
+ self.0.deleted.set(true);
141
+ }
142
+ }
143
+
144
+ impl<T: Clone + 'static> AddListener<Callback<T>> for PubSub<T> {
145
+ fn add_listener(&self, f: Callback<T>) -> Subscription {
146
+ let internal = self.0.clone();
147
+ let cb = Box::new(move |x| f.emit(x));
148
+ let key = self.0.listeners.borrow_mut().insert(cb);
149
+ Subscription(Box::new(move || {
150
+ internal.listeners.borrow_mut().remove(key)
151
+ }))
152
+ }
153
+ }
154
+
155
+ impl<T, U> AddListener<U> for PubSub<T>
156
+ where
157
+ T: Clone + 'static,
158
+ U: Fn(T) + 'static,
159
+ {
160
+ fn add_listener(&self, f: U) -> Subscription {
161
+ let internal = self.0.clone();
162
+ let key = self.0.listeners.borrow_mut().insert(Box::new(f));
163
+ Subscription(Box::new(move || {
164
+ internal.listeners.borrow_mut().remove(key)
165
+ }))
166
+ }
167
+ }
168
+
169
+ /// Like a `PubSub` without `PubSub::emit`; the reciprocal of
170
+ /// `PubSub::callback`. `Subscriber` does not keep the parent `PubSub` alive.
171
+ #[derive(Clone)]
172
+ pub struct Subscriber<T: Clone>(Weak<PubSubInternal<T>>);
173
+
174
+ impl<T, U> AddListener<U> for Subscriber<T>
175
+ where
176
+ T: Clone + 'static,
177
+ U: Fn(T) + 'static,
178
+ {
179
+ fn add_listener(&self, f: U) -> Subscription {
180
+ if let Some(internal) = self.0.upgrade() {
181
+ let key = internal.listeners.borrow_mut().insert(Box::new(f));
182
+ Subscription(Box::new(move || {
183
+ internal.listeners.borrow_mut().remove(key)
184
+ }))
185
+ } else {
186
+ Subscription(Box::new(|| {}))
187
+ }
188
+ }
189
+ }
190
+
191
+ impl<T: Clone> Default for Subscriber<T> {
192
+ fn default() -> Self {
193
+ Self(Weak::new())
194
+ }
195
+ }
196
+
197
+ impl<T: Clone> PartialEq for Subscriber<T> {
198
+ fn eq(&self, other: &Self) -> bool {
199
+ match (self.0.upgrade(), other.0.upgrade()) {
200
+ (Some(x), Some(y)) => std::ptr::eq(
201
+ &*x as *const PubSubInternal<T>,
202
+ &*y as *const PubSubInternal<T>,
203
+ ),
204
+ (None, None) => true,
205
+ _ => false,
206
+ }
207
+ }
208
+ }
209
+
210
+ /// Manages the lifetime of a listener registered to a `PubSub<T>` by
211
+ /// deregistering the associated listener when dropped.
212
+ ///
213
+ /// The wrapped `Fn` of `Subscriptions` is the deregister closure provided by
214
+ /// the issuing `PubSub<T>`.
215
+ #[must_use]
216
+ pub struct Subscription(Box<dyn Fn()>);
217
+
218
+ impl Drop for Subscription {
219
+ fn drop(&mut self) {
220
+ (*self.0)();
221
+ }
222
+ }
@@ -0,0 +1,54 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use extend::ext;
14
+ use futures::channel::oneshot::*;
15
+ use perspective_js::utils::ApiResult;
16
+ use yew::html::Scope;
17
+ use yew::prelude::*;
18
+
19
+ #[ext]
20
+ pub impl<T> Scope<T>
21
+ where
22
+ T: Component,
23
+ {
24
+ /// Send a message with a callback, then suspend until the callback is
25
+ /// invoked.
26
+ fn send_message_async<F, U>(&self, f: F) -> Receiver<U>
27
+ where
28
+ F: FnOnce(Sender<U>) -> T::Message,
29
+ {
30
+ let (sender, receiver) = channel::<U>();
31
+ self.send_message(f(sender));
32
+ receiver
33
+ }
34
+ }
35
+
36
+ #[ext]
37
+ pub(crate) impl<T> Callback<Sender<T>>
38
+ where
39
+ T: 'static,
40
+ {
41
+ /// This is "safe" because `emit()` is not called synchronously. Normally
42
+ /// we want this to minimize the async by doing as much work synchronous
43
+ /// as possible (see `send_message_async()` e.g.), but this method calls
44
+ /// `Yew` which _never_ wants to be called synchronously.
45
+ ///
46
+ /// TODO Need test coverage for this - error behavior is that presize/render
47
+ /// blocking calls are out-of-order, e.g. toggle config `presize()` call.
48
+ /// Engineering the test to capture this faulty behavior may be difficult
49
+ async fn emit_async_safe(&self) -> ApiResult<T> {
50
+ let (sender, receiver) = channel::<T>();
51
+ self.emit(sender);
52
+ Ok(receiver.await?)
53
+ }
54
+ }
@@ -0,0 +1,88 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ /// Trait for polymorphic return value via turbofish-const-generic syntax.
14
+ ///
15
+ /// The associated type `Output` is a functional dependency of the const generic
16
+ /// parameter `N`, so there's typically no need to specify this parameter when
17
+ /// invoking, which is what we want - this parameter is quite verbose and
18
+ /// repetitive (see below), vs `N` which is a single character.
19
+ pub trait TeeInternal<const N: usize> {
20
+ type Output: Clone;
21
+ fn tee_internal(self) -> Self::Output;
22
+ }
23
+
24
+ pub trait Tee {
25
+ /// Extension method to add `tee()` method to all `T: Clone`.
26
+ ///
27
+ /// This can't be done directly as part of `TeeInternal` because it makes
28
+ /// specifying the const param at the `tee()` invocation site
29
+ /// cumbersome: `TeeInternal::<N>::tee(&obj)` as opposed to
30
+ /// `obj.tee::<N>()`. The constraint `Self: TeeInternal<N>` collapses
31
+ /// the potential `impl` matches to exactly 1, which makes the call to
32
+ /// `tee_internal()` unambiguous. This constraint is also allowed to
33
+ /// contain the generic parameter `N` because it is specified as a
34
+ /// constraint to the method (as opposed to a constraint on the trait).
35
+ /// I'm honestly quite surprised this works ...
36
+ ///
37
+ /// # Examples
38
+ ///
39
+ /// ```
40
+ /// let x = "test".tee::<2>();
41
+ /// assert_eq!(x.0, x.1);
42
+ /// assert_eq!(x.0, "test");
43
+ /// ```
44
+ fn tee<const N: usize>(self) -> <Self as TeeInternal<N>>::Output
45
+ where
46
+ Self: TeeInternal<N>;
47
+ }
48
+
49
+ impl<T: Clone> Tee for T {
50
+ fn tee<const N: usize>(self) -> <Self as TeeInternal<N>>::Output
51
+ where
52
+ Self: TeeInternal<N>,
53
+ {
54
+ self.tee_internal()
55
+ }
56
+ }
57
+
58
+ macro_rules! gen_tee {
59
+ ($($x:ty),*) => {
60
+ impl<T: Clone> TeeInternal<{${count($x)} + 1}> for T {
61
+ type Output = ($($x),*, T);
62
+ fn tee_internal(self) -> Self::Output {
63
+ ($( ${ignore($x)} self.clone() ),*, self)
64
+ }
65
+ }
66
+ };
67
+ }
68
+
69
+ gen_tee!(T);
70
+ gen_tee!(T, T);
71
+ gen_tee!(T, T, T);
72
+ gen_tee!(T, T, T, T);
73
+ gen_tee!(T, T, T, T, T);
74
+ gen_tee!(T, T, T, T, T, T);
75
+ gen_tee!(T, T, T, T, T, T, T);
76
+ gen_tee!(T, T, T, T, T, T, T, T);
77
+
78
+ #[cfg(test)]
79
+ mod tests {
80
+ use super::*;
81
+
82
+ #[test]
83
+ fn test_test1() {
84
+ let x = "test".tee::<2>();
85
+ assert_eq!(x.0, x.1);
86
+ assert_eq!(x.0, "test");
87
+ }
88
+ }
@@ -0,0 +1,14 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ mod pubsub;
14
+ mod request_animation_frame;