@perspective-dev/viewer 4.0.1 → 4.1.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 (183) hide show
  1. package/dist/cdn/perspective-viewer.js +2 -2
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/dracula.css +1 -1
  4. package/dist/css/gruvbox-dark.css +1 -1
  5. package/dist/css/gruvbox.css +1 -1
  6. package/dist/css/icons.css +1 -1
  7. package/dist/css/monokai.css +1 -1
  8. package/dist/css/pro-dark.css +1 -1
  9. package/dist/css/pro.css +1 -1
  10. package/dist/css/solarized-dark.css +1 -1
  11. package/dist/css/solarized.css +1 -1
  12. package/dist/css/themes.css +1 -1
  13. package/dist/css/vaporwave.css +1 -1
  14. package/dist/esm/extensions.d.ts +23 -2
  15. package/dist/esm/perspective-viewer.d.ts +2 -7
  16. package/dist/esm/perspective-viewer.inline.js +2 -2
  17. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  18. package/dist/esm/perspective-viewer.js +2 -2
  19. package/dist/esm/perspective-viewer.js.map +4 -4
  20. package/dist/esm/plugin.d.ts +1 -1
  21. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +1 -0
  22. package/dist/wasm/perspective-viewer.d.ts +218 -46
  23. package/dist/wasm/perspective-viewer.js +1250 -761
  24. package/dist/wasm/perspective-viewer.wasm +0 -0
  25. package/dist/wasm/perspective-viewer.wasm.d.ts +38 -19
  26. package/package.json +1 -1
  27. package/src/less/containers/scroll-panel.less +0 -1
  28. package/src/less/plugin-selector.less +15 -5
  29. package/src/less/status-bar.less +75 -27
  30. package/src/less/viewer.less +140 -58
  31. package/src/rust/components/column_dropdown.rs +21 -21
  32. package/src/rust/components/column_selector/active_column.rs +131 -120
  33. package/src/rust/components/column_selector/add_expression_button.rs +5 -0
  34. package/src/rust/components/column_selector/aggregate_selector.rs +8 -4
  35. package/src/rust/components/column_selector/config_selector.rs +170 -161
  36. package/src/rust/components/column_selector/empty_column.rs +16 -11
  37. package/src/rust/components/column_selector/{expression_toolbar.rs → expr_edit_button.rs} +7 -0
  38. package/src/rust/components/column_selector/filter_column.rs +195 -194
  39. package/src/rust/components/column_selector/inactive_column.rs +82 -67
  40. package/src/rust/components/column_selector/pivot_column.rs +16 -11
  41. package/src/rust/components/column_selector/sort_column.rs +9 -7
  42. package/src/rust/components/column_selector.rs +42 -37
  43. package/src/rust/components/column_settings_sidebar/save_settings.rs +3 -1
  44. package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +58 -0
  45. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +6 -6
  46. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +2 -94
  47. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +111 -0
  48. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +3 -3
  49. package/src/rust/components/column_settings_sidebar/style_tab.rs +23 -83
  50. package/src/rust/components/{column_settings_sidebar/sidebar.rs → column_settings_sidebar.rs} +198 -171
  51. package/src/rust/components/containers/dragdrop_list.rs +20 -20
  52. package/src/rust/components/containers/dropdown_menu.rs +4 -6
  53. package/src/rust/components/containers/mod.rs +1 -4
  54. package/src/rust/components/containers/scroll_panel.rs +80 -80
  55. package/src/rust/components/containers/scroll_panel_item.rs +36 -36
  56. package/src/rust/components/containers/select.rs +46 -44
  57. package/src/rust/components/containers/sidebar.rs +3 -19
  58. package/src/rust/components/{column_settings_sidebar/style_tab/symbol/symbol_config.rs → containers/sidebar_close_button.rs} +15 -9
  59. package/src/rust/components/containers/split_panel.rs +212 -200
  60. package/src/rust/components/containers/tab_list.rs +11 -11
  61. package/src/rust/components/copy_dropdown.rs +22 -25
  62. package/src/rust/components/datetime_column_style/custom.rs +19 -19
  63. package/src/rust/components/datetime_column_style/simple.rs +13 -14
  64. package/src/rust/components/datetime_column_style.rs +75 -76
  65. package/src/rust/components/editable_header.rs +18 -14
  66. package/src/rust/components/empty_row.rs +5 -5
  67. package/src/rust/components/export_dropdown.rs +42 -42
  68. package/src/rust/components/expression_editor.rs +25 -19
  69. package/src/rust/components/filter_dropdown.rs +22 -22
  70. package/src/rust/components/font_loader.rs +11 -9
  71. package/src/rust/components/form/code_editor.rs +106 -105
  72. package/src/rust/components/form/color_range_selector.rs +14 -12
  73. package/src/rust/components/form/color_selector.rs +3 -1
  74. package/src/rust/components/form/debug.rs +95 -94
  75. package/src/rust/components/form/highlight.rs +5 -3
  76. package/src/rust/components/form/mod.rs +3 -2
  77. package/src/rust/components/form/optional_field.rs +2 -2
  78. package/src/rust/components/form/{select_field.rs → select_enum_field.rs} +1 -46
  79. package/src/rust/components/form/select_value_field.rs +64 -0
  80. package/src/rust/components/function_dropdown.rs +21 -21
  81. package/src/rust/components/main_panel.rs +219 -0
  82. package/src/rust/components/mod.rs +6 -6
  83. package/src/rust/components/modal.rs +42 -42
  84. package/src/rust/components/number_column_style.rs +34 -88
  85. package/src/rust/components/plugin_selector.rs +22 -25
  86. package/src/rust/components/render_warning.rs +9 -6
  87. package/src/rust/components/settings_panel.rs +82 -0
  88. package/src/rust/components/status_bar.rs +250 -146
  89. package/src/rust/components/status_bar_counter.rs +26 -119
  90. package/src/rust/components/status_indicator.rs +95 -79
  91. package/src/rust/components/string_column_style.rs +45 -45
  92. package/src/rust/components/style/style_provider.rs +1 -15
  93. package/src/rust/components/style_controls/number_string_format/digits_section.rs +1 -1
  94. package/src/rust/components/style_controls/number_string_format/misc_section.rs +1 -1
  95. package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -1
  96. package/src/rust/components/style_controls/number_string_format.rs +45 -46
  97. package/src/rust/components/type_icon.rs +14 -11
  98. package/src/rust/components/viewer.rs +241 -384
  99. package/src/rust/config/columns_config.rs +2 -2
  100. package/src/rust/config/datetime_column_style.rs +1 -6
  101. package/src/rust/config/mod.rs +1 -0
  102. package/src/rust/config/number_column_style.rs +0 -6
  103. package/src/rust/config/number_string_format.rs +27 -4
  104. package/src/rust/config/viewer_config.rs +27 -167
  105. package/src/rust/custom_elements/copy_dropdown.rs +14 -6
  106. package/src/rust/custom_elements/export_dropdown.rs +15 -7
  107. package/src/rust/custom_elements/filter_dropdown.rs +4 -4
  108. package/src/rust/custom_elements/mod.rs +3 -0
  109. package/src/rust/custom_elements/viewer.rs +353 -161
  110. package/src/rust/custom_events.rs +55 -32
  111. package/src/rust/dragdrop.rs +4 -24
  112. package/src/rust/exprtk/cursor.rs +10 -1
  113. package/src/rust/exprtk/mod.rs +2 -0
  114. package/src/rust/exprtk/tokenize.rs +20 -3
  115. package/src/rust/js/clipboard.rs +2 -2
  116. package/src/rust/js/mimetype.rs +2 -7
  117. package/src/rust/js/mod.rs +0 -1
  118. package/src/rust/js/plugin.rs +7 -0
  119. package/src/rust/lib.rs +18 -5
  120. package/src/rust/model/column_locator.rs +82 -0
  121. package/src/rust/model/columns_iter_set.rs +1 -0
  122. package/src/rust/model/copy_export.rs +50 -14
  123. package/src/rust/model/edit_expression.rs +2 -5
  124. package/src/rust/model/eject.rs +41 -0
  125. package/src/rust/model/get_viewer_config.rs +4 -28
  126. package/src/rust/model/intersection_observer.rs +20 -8
  127. package/src/rust/model/mod.rs +11 -4
  128. package/src/rust/model/plugin_column_styles.rs +0 -31
  129. package/src/rust/model/reset_all.rs +38 -0
  130. package/src/rust/model/resize_observer.rs +34 -7
  131. package/src/rust/model/restore_and_render.rs +12 -7
  132. package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
  133. package/src/rust/model/structural.rs +194 -23
  134. package/src/rust/model/update_and_render.rs +14 -4
  135. package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
  136. package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
  137. package/src/rust/presentation.rs +60 -119
  138. package/src/rust/renderer/activate.rs +20 -5
  139. package/src/rust/renderer/limits.rs +0 -149
  140. package/src/rust/renderer/render_timer.rs +1 -1
  141. package/src/rust/renderer.rs +34 -18
  142. package/src/rust/root.rs +50 -0
  143. package/src/rust/session/column_defaults_update.rs +4 -4
  144. package/src/rust/session/drag_drop_update.rs +1 -1
  145. package/src/rust/session/metadata.rs +3 -17
  146. package/src/rust/session/replace_expression_update.rs +1 -2
  147. package/src/rust/session.rs +162 -82
  148. package/src/rust/utils/browser/blob.rs +16 -2
  149. package/src/rust/utils/browser/download.rs +1 -0
  150. package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
  151. package/src/rust/utils/browser/mod.rs +8 -4
  152. package/src/rust/utils/browser/selection.rs +5 -0
  153. package/src/rust/utils/custom_element.rs +28 -13
  154. package/src/rust/utils/datetime.rs +5 -0
  155. package/src/rust/utils/debounce.rs +7 -1
  156. package/src/rust/utils/hooks/use_async_callback.rs +7 -17
  157. package/src/rust/utils/mod.rs +28 -40
  158. package/src/rust/utils/number_format.rs +6 -5
  159. package/src/rust/utils/pubsub.rs +15 -10
  160. package/src/rust/utils/weak_scope.rs +11 -1
  161. package/src/svg/bookmark-icon.svg +4 -0
  162. package/src/svg/drag-handle copy.svg +10 -0
  163. package/src/svg/drawer-tab-hover.svg +5 -7
  164. package/src/svg/drawer-tab-invert-hover.svg +4 -8
  165. package/src/svg/drawer-tab-invert.svg +4 -7
  166. package/src/svg/drawer-tab.svg +4 -6
  167. package/src/svg/status_ok.svg +24 -24
  168. package/src/ts/extensions.ts +51 -3
  169. package/src/ts/perspective-viewer.ts +2 -14
  170. package/src/ts/plugin.ts +1 -1
  171. package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
  172. package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
  173. package/src/rust/components/containers/tests/mod.rs +0 -11
  174. package/src/rust/components/containers/tests/split_panel.rs +0 -91
  175. package/src/rust/js/testing.rs +0 -149
  176. package/src/rust/utils/tee.rs +0 -88
  177. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
  178. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
  179. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
  180. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
  181. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
  182. /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
  183. /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
@@ -18,15 +18,20 @@ use async_lock::Mutex;
18
18
  use perspective_js::utils::ApiResult;
19
19
 
20
20
  #[derive(Default)]
21
- pub struct DebounceMutexData {
21
+ struct DebounceMutexData {
22
22
  id: Cell<u64>,
23
23
  mutex: Mutex<u64>,
24
24
  }
25
25
 
26
+ /// An async `Mutex` type specialized for Perspective's rendering, which
27
+ /// debounces calls in addition to providing exclusivity. Calling `debounce`
28
+ /// with a _cancellable_ [`Future`] will resolve only after at least one
29
+ /// _complete_ evaluation of a call awaiting the lock.
26
30
  #[derive(Clone, Default)]
27
31
  pub struct DebounceMutex(Rc<DebounceMutexData>);
28
32
 
29
33
  impl DebounceMutex {
34
+ /// Lock like a normal `Mutex`.
30
35
  pub async fn lock<T>(&self, f: impl Future<Output = T>) -> T {
31
36
  let mut last = self.0.mutex.lock().await;
32
37
  let next = self.0.id.get();
@@ -35,6 +40,7 @@ impl DebounceMutex {
35
40
  result
36
41
  }
37
42
 
43
+ /// Lock and also debounce `f`, which should be cancellable.
38
44
  pub async fn debounce(&self, f: impl Future<Output = ApiResult<()>>) -> ApiResult<()> {
39
45
  let next = self.0.id.get() + 1;
40
46
  let mut last = self.0.mutex.lock().await;
@@ -11,21 +11,11 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  use wasm_bindgen::__rt::IntoJsResult;
14
+ use wasm_bindgen::JsValue;
14
15
  use wasm_bindgen_futures::future_to_promise;
15
16
  use yew::prelude::*;
16
17
 
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.
18
+ /// Just like `use_callback`, except convenient for an async result body.
29
19
  #[hook]
30
20
  pub fn use_async_callback<IN, OUT, F, D>(deps: D, f: F) -> Callback<IN, ()>
31
21
  where
@@ -34,14 +24,14 @@ where
34
24
  F: AsyncFn(IN, &D) -> OUT + 'static,
35
25
  D: Clone + PartialEq + 'static,
36
26
  {
37
- let deps = std::rc::Rc::new(deps);
38
- let f = std::rc::Rc::new(f);
27
+ use std::rc::Rc;
28
+
29
+ let deps = Rc::new(deps);
30
+ let f = Rc::new(f);
39
31
  (*use_memo(deps, move |deps| {
40
32
  let deps = deps.clone();
41
33
  let ff = move |value: IN| {
42
- let value = value.clone();
43
- let f = f.clone();
44
- let deps = deps.clone();
34
+ perspective_client::clone!(value, f, deps);
45
35
  let _ = future_to_promise(async move {
46
36
  f(value, &deps).await.into_js_result()?;
47
37
  Ok(JsValue::UNDEFINED)
@@ -17,16 +17,12 @@
17
17
  //! reference other `crate::utils` modules when it helps reduce boiler-plate.
18
18
 
19
19
  mod browser;
20
-
21
20
  mod custom_element;
22
21
  mod datetime;
23
22
  mod debounce;
24
23
  mod hooks;
25
24
  mod number_format;
26
25
  mod pubsub;
27
- mod scope;
28
- mod tee;
29
- mod wasm_abi;
30
26
  mod weak_scope;
31
27
 
32
28
  #[cfg(test)]
@@ -40,10 +36,9 @@ pub use hooks::*;
40
36
  pub use number_format::*;
41
37
  pub use perspective_client::clone;
42
38
  pub use pubsub::*;
43
- pub use scope::*;
44
- pub use tee::*;
45
39
  pub use weak_scope::*;
46
40
 
41
+ /// An implementaiton of `try_blocks` feature in a non-nightly macro.
47
42
  #[macro_export]
48
43
  macro_rules! maybe {
49
44
  ($($exp:stmt);*) => {{
@@ -57,8 +52,9 @@ macro_rules! maybe {
57
52
  }};
58
53
  }
59
54
 
55
+ /// As `maybe!`, but returns `()` and just logs errors.
60
56
  #[macro_export]
61
- macro_rules! js_log_maybe {
57
+ macro_rules! maybe_log {
62
58
  ($($exp:tt)+) => {{
63
59
  let x = ({
64
60
  #[inline(always)]
@@ -74,41 +70,33 @@ macro_rules! js_log_maybe {
74
70
  }
75
71
 
76
72
  #[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
- }}
73
+ macro_rules! maybe_log_or_default {
74
+ ($($exp:tt)+) => {{
75
+ let x = ({
76
+ #[inline(always)]
77
+ || {
78
+ $($exp)+
79
+ }
80
+ })();
81
+ x.unwrap_or_else(|e| {
82
+ web_sys::console::warn_1(&e);
83
+ Default::default()
84
+ })
85
+ }};
102
86
  }
103
87
 
104
88
  #[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());
89
+ macro_rules! maybe_or_default {
90
+ ($($exp:tt)+) => {{
91
+ let x = ({
92
+ #[inline(always)]
93
+ || {
94
+ $($exp)+
95
+ }
96
+ })();
97
+ x.unwrap_or_else(|| {
98
+ web_sys::console::warn_1("Unwrap on Noner");
99
+ Default::default()
100
+ })
113
101
  }};
114
102
  }
@@ -17,12 +17,10 @@ use perspective_js::json;
17
17
  use perspective_js::utils::global::navigator;
18
18
  use wasm_bindgen::JsValue;
19
19
 
20
- pub trait ToFormattedString {
21
- fn to_formatted_string(&self) -> String;
22
- }
23
-
24
20
  struct UnsafeNumberFormat(Intl::NumberFormat);
25
21
 
22
+ // JavaScript does not allow threading, but we do not have a non-threadsafe
23
+ // way to conveniently make lazy static caches of JavaScript ref values.
26
24
  unsafe impl Send for UnsafeNumberFormat {}
27
25
  unsafe impl Sync for UnsafeNumberFormat {}
28
26
 
@@ -35,7 +33,10 @@ static NUMBER_FORMAT: LazyLock<UnsafeNumberFormat> = LazyLock::new(|| {
35
33
 
36
34
  impl UnsafeNumberFormat {}
37
35
 
38
- impl ToFormattedString for u32 {
36
+ /// Trait for the [`u32::to_formatted_string`] method.
37
+ #[extend::ext]
38
+ pub impl u32 {
39
+ /// Format integers consistenly using the Browser's native `NumberFormat`.
39
40
  fn to_formatted_string(&self) -> String {
40
41
  NUMBER_FORMAT
41
42
  .0
@@ -18,9 +18,8 @@ use derivative::Derivative;
18
18
  use futures::channel::oneshot::*;
19
19
  use yew::prelude::*;
20
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)`.
21
+ /// A simple collection with lookup and remove with stable indices, for
22
+ /// collecting `Box<dyn Fn()>` which do not implement [`Hash`].
24
23
  #[derive(Derivative)]
25
24
  #[derivative(Default(bound = ""))]
26
25
  struct IndexedSet<T> {
@@ -31,7 +30,10 @@ struct IndexedSet<T> {
31
30
  impl<T> IndexedSet<T> {
32
31
  fn insert(&mut self, v: T) -> usize {
33
32
  let key = self.gen_;
34
- self.set.insert(key, v);
33
+ if self.set.insert(key, v).is_some() {
34
+ tracing::warn!("Collision");
35
+ };
36
+
35
37
  self.gen_ += 1;
36
38
  key
37
39
  }
@@ -56,7 +58,7 @@ type ListenerOnceSet<T> = IndexedSet<Box<dyn FnOnce(T) + 'static>>;
56
58
 
57
59
  #[derive(Derivative)]
58
60
  #[derivative(Default(bound = ""))]
59
- pub struct PubSubInternal<T: Clone> {
61
+ struct PubSubInternal<T: Clone> {
60
62
  deleted: Cell<bool>,
61
63
  listeners: RefCell<ListenerSet<T>>,
62
64
  once_listeners: RefCell<ListenerOnceSet<T>>,
@@ -87,9 +89,8 @@ impl<T: Clone> PubSubInternal<T> {
87
89
  #[derivative(Default(bound = ""))]
88
90
  pub struct PubSub<T: Clone>(Rc<PubSubInternal<T>>);
89
91
 
90
- unsafe impl<T: Clone> Send for PubSub<T> {}
91
- unsafe impl<T: Clone> Sync for PubSub<T> {}
92
-
92
+ /// An extension trait for [`AddListener::add_listener`], which we want to
93
+ /// take a variety of function-like arguments for readability.
93
94
  pub trait AddListener<T> {
94
95
  /// Register a listener to this `PubSub<_>`, which will be automatically
95
96
  /// deregistered when the return `Subscription` is dropped.
@@ -109,18 +110,21 @@ impl<T: Clone + 'static> PubSub<T> {
109
110
  }
110
111
 
111
112
  /// Get this `PubSub<_>`'s `.emit_all()` method as a `Callback<T>`.
113
+ #[must_use]
112
114
  pub fn callback(&self) -> Callback<T> {
113
115
  let internal = self.0.clone();
114
116
  Callback::from(move |val: T| internal.emit(val))
115
117
  }
116
118
 
117
- pub fn as_boxfn(&self) -> Box<dyn Fn(T) + Send + Sync + 'static> {
119
+ /// Convert [`PubSub::emit`] to a `Box<dyn Fn(T)>`.
120
+ #[must_use]
121
+ pub fn as_boxfn(&self) -> Box<dyn Fn(T) + 'static> {
118
122
  let internal = PubSub(self.0.clone());
119
123
  Box::new(move |val: T| internal.emit(val))
120
124
  }
121
125
 
122
126
  /// Await this `PubSub<_>`'s next call to `emit_all()`, once.
123
- pub async fn listen_once(&self) -> Result<T, Canceled> {
127
+ pub async fn read_next(&self) -> Result<T, Canceled> {
124
128
  let (sender, receiver) = channel::<T>();
125
129
  let f = move |x| sender.send(x).unwrap_or(());
126
130
  self.0.once_listeners.borrow_mut().insert(Box::new(f));
@@ -130,6 +134,7 @@ impl<T: Clone + 'static> PubSub<T> {
130
134
  /// Create a `Subscriber` from this `PubSub`, which is the reciprocal of
131
135
  /// `PubSub::callback` (a struct which only allows sending), a struct which
132
136
  /// only allows receiving via `Subscriber::add_listener`.
137
+ #[must_use]
133
138
  pub fn subscriber(&self) -> Subscriber<T> {
134
139
  Subscriber(Rc::<PubSubInternal<T>>::downgrade(&self.0))
135
140
  }
@@ -18,7 +18,7 @@ use derivative::Derivative;
18
18
  use yew::html::Scope;
19
19
  use yew::prelude::*;
20
20
 
21
- /// A mutable reference for capturing the `Scope<_>` props arguments, a useful
21
+ /// A mutable reference for capturing the [`Scope`] props arguments, a useful
22
22
  /// function for tests.
23
23
  #[derive(Derivative)]
24
24
  #[derivative(Clone(bound = ""), Default(bound = ""))]
@@ -37,3 +37,13 @@ impl<C: Component> PartialEq for WeakScope<C> {
37
37
  Rc::ptr_eq(&self.0, &other.0)
38
38
  }
39
39
  }
40
+
41
+ // #[extend::ext]
42
+ // pub impl<T: Component> Context<T> {
43
+ // fn context<U: Clone + PartialEq + 'static>(&self) -> U {
44
+ // self.link()
45
+ // .context::<U>(Callback::from(|_| {}))
46
+ // .map(|(c, _)| c)
47
+ // .unwrap()
48
+ // }
49
+ // }
@@ -0,0 +1,4 @@
1
+ <svg width="20" height="11" viewBox="0 0 20 11" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M3.66214 6.96476L0.5 9.86338V0.5H7.5V9.86338L4.33786 6.96476L4 6.65505L3.66214 6.96476Z" stroke="#042121"/>
3
+ <path d="M15 4L17 6L19 4" stroke="#042121" stroke-linecap="round"/>
4
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg width="5" height="12" viewBox="0 0 5 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="3.49996" cy="11.0001" r="0.833333" fill="#6E6E6E"/>
3
+ <circle cx="0.833333" cy="11.0001" r="0.833333" fill="#6E6E6E"/>
4
+ <circle cx="3.49996" cy="7.66683" r="0.833333" fill="#6E6E6E"/>
5
+ <circle cx="0.833333" cy="7.66683" r="0.833333" fill="#6E6E6E"/>
6
+ <circle cx="3.49996" cy="4.33333" r="0.833333" fill="#6E6E6E"/>
7
+ <circle cx="0.833333" cy="4.33333" r="0.833333" fill="#6E6E6E"/>
8
+ <circle cx="3.49996" cy="1.00008" r="0.833333" fill="#6E6E6E"/>
9
+ <circle cx="0.833333" cy="1.00008" r="0.833333" fill="#6E6E6E"/>
10
+ </svg>
@@ -1,8 +1,6 @@
1
- <svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g transform="translate(0.5, 0.5)">
3
- <path d="M 0 4 C 0 1 1 0 4 0 L 26 0 L 26 17 L 4 17 C 1.791 17 0 15.209 0 13 Z" stroke="#042121"></path>
4
- <path
5
- d="M 5.646 5.52 L 8.626 8.5 L 5.646 11.48 C 5.451 11.675 5.451 11.992 5.646 12.187 C 5.842 12.382 6.158 12.382 6.353 12.187 L 9.687 8.854 L 10.04 8.5 L 6.353 4.813 C 6.158 4.618 5.842 4.618 5.646 4.813 C 5.451 5.008 5.451 5.325 5.646 5.52 Z M 9.98 5.52 L 12.96 8.5 L 9.98 11.48 C 9.785 11.675 9.785 11.992 9.98 12.187 C 10.175 12.382 10.492 12.382 10.687 12.187 L 14.374 8.5 L 10.687 4.813 C 10.492 4.618 10.175 4.618 9.98 4.813 C 9.785 5.008 9.785 5.325 9.98 5.52 Z"
6
- fill="#042121"></path>
7
- </g>
1
+ <svg width="20px" height="20px" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0.5, 0.5)">
3
+ <path d="M 0 4.471 C 0 1.118 1.118 0 4.471 0 L 29.059 0 L 29.059 19 L 4.471 19 C 2.002 19 0 16.998 0 14.529 L 0 4.471 Z" stroke="#042121"></path>
4
+ <path d="M 5.209 6.52 L 8.189 9.5 L 5.209 12.48 C 5.014 12.675 5.014 12.992 5.209 13.187 C 5.405 13.382 5.721 13.382 5.916 13.187 L 9.25 9.854 L 9.603 9.5 L 5.916 5.813 C 5.721 5.618 5.405 5.618 5.209 5.813 C 5.014 6.008 5.014 6.325 5.209 6.52 Z M 9.543 6.52 L 12.523 9.5 L 9.543 12.48 C 9.348 12.675 9.348 12.992 9.543 13.187 C 9.738 13.382 10.055 13.382 10.25 13.187 L 13.937 9.5 L 10.25 5.813 C 10.055 5.618 9.738 5.618 9.543 5.813 C 9.348 6.008 9.348 6.325 9.543 6.52 Z" fill="#042121"></path>
5
+ </g>
8
6
  </svg>
@@ -1,9 +1,5 @@
1
- <svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g transform="translate(0.5, 0.5)">
3
- <path d="
4
- M 0 4 C 0 1.791 1.791 0 4 0 L 26 0 L 26 17 L 4 17 C 1.791 17 0 15.209 0 13 Z
5
- M 14.228 11.48 L 11.248 8.5 L 14.228 5.52 C 14.423 5.325 14.423 5.008 14.228 4.813 C 14.033 4.618 13.716 4.618 13.521 4.813 L 9.834 8.5 L 13.521 12.187 C 13.716 12.382 14.033 12.382 14.228 12.187 C 14.423 11.992 14.423 11.675 14.228 11.48 Z
6
- M 9.894 11.48 L 6.914 8.5 L 9.894 5.52 C 10.089 5.325 10.089 5.008 9.894 4.813 C 9.698 4.618 9.382 4.618 9.187 4.813 L 5.853 8.146 L 5.5 8.5 L 9.187 12.187 C 9.382 12.382 9.698 12.382 9.894 12.187 C 10.089 11.992 10.089 11.675 9.894 11.48 Z
7
- " fill="#042121"></path>
8
- </g>
1
+ <svg width="20px" height="20px" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0.5, 0.5)">
3
+ <path d="M 9.457 12.48 L 6.477 9.5 L 9.457 6.52 C 9.652 6.325 9.652 6.008 9.457 5.813 C 9.261 5.618 8.945 5.618 8.75 5.813 L 5.416 9.146 L 5.063 9.5 L 8.75 13.187 C 8.945 13.382 9.261 13.382 9.457 13.187 C 9.652 12.992 9.652 12.675 9.457 12.48 Z M 13.791 12.48 L 10.811 9.5 L 13.791 6.52 C 13.986 6.325 13.986 6.008 13.791 5.813 C 13.596 5.618 13.279 5.618 13.084 5.813 L 9.397 9.5 L 13.084 13.187 C 13.279 13.382 13.596 13.382 13.791 13.187 C 13.986 12.992 13.986 12.675 13.791 12.48 Z M -0.5 4.206 C -0.5 1.608 1.608 -0.5 4.206 -0.5 L 30.088 -0.5 L 30.088 19.5 L 4.206 19.5 C 1.608 19.5 -0.5 17.392 -0.5 14.794 L -0.5 4.206 Z" fill="#042121"></path>
4
+ </g>
9
5
  </svg>
@@ -1,8 +1,5 @@
1
- <svg width="26" height="18" viewBox="0 0 25 18" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g transform="translate(0.5, 0.5)">
3
- <path d="
4
- M 14.228 11.48 L 11.248 8.5 L 14.228 5.52 C 14.423 5.325 14.423 5.008 14.228 4.813 C 14.033 4.618 13.716 4.618 13.521 4.813 L 9.834 8.5 L 13.521 12.187 C 13.716 12.382 14.033 12.382 14.228 12.187 C 14.423 11.992 14.423 11.675 14.228 11.48 Z
5
- M 9.894 11.48 L 6.914 8.5 L 9.894 5.52 C 10.089 5.325 10.089 5.008 9.894 4.813 C 9.698 4.618 9.382 4.618 9.187 4.813 L 5.853 8.146 L 5.5 8.5 L 9.187 12.187 C 9.382 12.382 9.698 12.382 9.894 12.187 C 10.089 11.992 10.089 11.675 9.894 11.48 Z
6
- " fill="#042121"></path>
7
- </g>
1
+ <svg width="20px" height="20px" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g>
3
+ <path d="M 14.291 12.98 L 11.311 10 L 14.291 7.02 C 14.486 6.825 14.486 6.508 14.291 6.313 C 14.096 6.118 13.779 6.118 13.584 6.313 L 9.897 10 L 13.584 13.687 C 13.779 13.882 14.096 13.882 14.291 13.687 C 14.486 13.492 14.486 13.175 14.291 12.98 Z M 9.957 12.98 L 6.977 10 L 9.957 7.02 C 10.152 6.825 10.152 6.508 9.957 6.313 C 9.761 6.118 9.445 6.118 9.25 6.313 L 5.916 9.646 L 5.563 10 L 9.25 13.687 C 9.445 13.882 9.761 13.882 9.957 13.687 C 10.152 13.492 10.152 13.175 9.957 12.98 Z" fill="#042121"></path>
4
+ </g>
8
5
  </svg>
@@ -1,7 +1,5 @@
1
- <svg width="26" height="18" viewBox="0 0 25 18" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g transform="translate(0.5, 0.5)">
3
- <path
4
- d="M 0 4 C 0 1.791 1.791 0 4 0 L 26 0 L 26 17 L 4 17 C 1.791 17 0 15.209 0 13 Z M 5.646 5.52 L 8.626 8.5 L 5.646 11.48 C 5.451 11.675 5.451 11.992 5.646 12.187 C 5.842 12.382 6.158 12.382 6.353 12.187 L 9.687 8.854 L 10.04 8.5 L 6.353 4.813 C 6.158 4.618 5.842 4.618 5.646 4.813 C 5.451 5.008 5.451 5.325 5.646 5.52 Z M 9.98 5.52 L 12.96 8.5 L 9.98 11.48 C 9.785 11.675 9.785 11.992 9.98 12.187 C 10.175 12.382 10.492 12.382 10.687 12.187 L 14.374 8.5 L 10.687 4.813 C 10.492 4.618 10.175 4.618 9.98 4.813 C 9.785 5.008 9.785 5.325 9.98 5.52 Z"
5
- fill="#042121"></path>
6
- </g>
1
+ <svg width="20px" height="20px" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0.5, 0.5)">
3
+ <path d="M -0.5 4.206 C -0.5 1.607 1.607 -0.5 4.206 -0.5 L 30.088 -0.5 L 30.088 19.5 L 4.206 19.5 C 1.607 19.5 -0.5 17.393 -0.5 14.794 L -0.5 4.206 Z M 9.543 6.52 L 12.523 9.5 L 9.543 12.48 C 9.348 12.675 9.348 12.992 9.543 13.187 C 9.738 13.382 10.055 13.382 10.25 13.187 L 13.937 9.5 L 10.25 5.813 C 10.055 5.618 9.738 5.618 9.543 5.813 C 9.348 6.008 9.348 6.325 9.543 6.52 Z M 5.209 6.52 L 8.189 9.5 L 5.209 12.48 C 5.014 12.675 5.014 12.992 5.209 13.187 C 5.405 13.382 5.721 13.382 5.916 13.187 L 9.25 9.854 L 9.603 9.5 L 5.916 5.813 C 5.721 5.618 5.405 5.618 5.209 5.813 C 5.014 6.008 5.014 6.325 5.209 6.52 Z" fill="#042121"></path>
4
+ </g>
7
5
  </svg>
@@ -1,26 +1,26 @@
1
1
  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M10 14V15" stroke="#042121" />
3
- <path d="M9 14V15" stroke="#042121" />
4
- <path d="M11 14V15" stroke="#042121" />
5
- <path d="M12 14V15" stroke="#042121" />
6
- <path d="M13 13V14" stroke="#042121" />
7
- <path d="M14 12V13" stroke="#042121" />
8
- <path d="M14 11V12" stroke="#042121" />
9
- <path d="M14 10V11" stroke="#042121" />
10
- <path d="M14 9V10" stroke="#042121" />
11
- <path d="M14 8V9" stroke="#042121" />
12
- <path d="M13 7V8" stroke="#042121" />
13
- <path d="M12 6V7" stroke="#042121" />
14
- <path d="M11 6V7" stroke="#042121" />
15
- <path d="M10 6V7" stroke="#042121" />
16
- <path d="M9 6V7" stroke="#042121" />
17
- <path d="M8 6V7" stroke="#042121" />
18
- <path d="M7 7V8" stroke="#042121" />
19
- <path d="M6 8V9" stroke="#042121" />
20
- <path d="M6 9V10" stroke="#042121" />
21
- <path d="M6 10V11" stroke="#042121" />
22
- <path d="M6 11V12" stroke="#042121" />
23
- <path d="M6 12V13" stroke="#042121" />
24
- <path d="M7 13V14" stroke="#042121" />
25
- <path d="M8 14V15" stroke="#042121" />
2
+ <path d="M10 13.5V14.5" stroke="#042121" />
3
+ <path d="M9 13.5V14.5" stroke="#042121" />
4
+ <path d="M11 13.5V14.5" stroke="#042121" />
5
+ <path d="M12 13.5V14.5" stroke="#042121" />
6
+ <path d="M13 12.5V13.5" stroke="#042121" />
7
+ <path d="M14 11.5V12.5" stroke="#042121" />
8
+ <path d="M14 10.5V11.5" stroke="#042121" />
9
+ <path d="M14 9.5V10.5" stroke="#042121" />
10
+ <path d="M14 8.5V9.5" stroke="#042121" />
11
+ <path d="M14 7.5V8.5" stroke="#042121" />
12
+ <path d="M13 6.5V7.5" stroke="#042121" />
13
+ <path d="M12 5.5V6.5" stroke="#042121" />
14
+ <path d="M11 5.5V6.5" stroke="#042121" />
15
+ <path d="M10 5.5V6.5" stroke="#042121" />
16
+ <path d="M9 5.5V6.5" stroke="#042121" />
17
+ <path d="M8 5.5V6.5" stroke="#042121" />
18
+ <path d="M7 6.5V7.5" stroke="#042121" />
19
+ <path d="M6 7.5V8.5" stroke="#042121" />
20
+ <path d="M6 8.5V9.5" stroke="#042121" />
21
+ <path d="M6 9.5V10.5" stroke="#042121" />
22
+ <path d="M6 10.5V11.5" stroke="#042121" />
23
+ <path d="M6 11.5V12.5" stroke="#042121" />
24
+ <path d="M7 12.5V13.5" stroke="#042121" />
25
+ <path d="M8 13.5V14.5" stroke="#042121" />
26
26
  </svg>
@@ -11,17 +11,29 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  import type { HTMLPerspectiveViewerPluginElement } from "./plugin";
14
- import { PerspectiveViewerElement } from "../../dist/wasm/perspective-viewer.js";
14
+ import type { PerspectiveViewerElement } from "../../dist/wasm/perspective-viewer.js";
15
15
  import type React from "react";
16
- import { ViewerConfigUpdate } from "./ts-rs/ViewerConfigUpdate.js";
16
+ import type { ViewerConfigUpdate } from "./ts-rs/ViewerConfigUpdate.js";
17
17
  import type { ViewWindow } from "@perspective-dev/client";
18
+ import type {
19
+ ExportDropDownMenuElement,
20
+ CopyDropDownMenuElement,
21
+ } from "../../dist/wasm/perspective-viewer.d.ts";
18
22
 
19
- // JSX / React extensions
23
+ // DOM extensions
20
24
 
21
25
  export type HTMLPerspectiveViewerElement = PerspectiveViewerElement &
22
26
  PerspectiveViewerElementExt &
23
27
  HTMLElement;
24
28
 
29
+ export interface HTMLPerspectiveViewerExportMenuElement
30
+ extends HTMLElement,
31
+ ExportDropDownMenuElement {}
32
+
33
+ export interface HTMLPerspectiveViewerCopyMenuElement
34
+ extends HTMLElement,
35
+ CopyDropDownMenuElement {}
36
+
25
37
  export type PerspectiveClickEventDetail = {
26
38
  config: ViewerConfigUpdate;
27
39
  row: Record<string, any>;
@@ -32,6 +44,8 @@ export type PerspectiveSelectEventDetail = {
32
44
  view_window: ViewWindow;
33
45
  };
34
46
 
47
+ // JSX / React extensions
48
+
35
49
  type ReactPerspectiveViewerAttributes<T> = React.HTMLAttributes<T>;
36
50
 
37
51
  type JsxPerspectiveViewerElement = { class?: string } & React.DetailedHTMLProps<
@@ -111,14 +125,48 @@ export interface PerspectiveViewerElementExt {
111
125
  options?: { signal: AbortSignal },
112
126
  ): void;
113
127
 
128
+ addEventListener(
129
+ name: "perspective-toggle-settings-before",
130
+ cb: (e: CustomEvent) => void,
131
+ options?: { signal: AbortSignal },
132
+ ): void;
133
+
114
134
  addEventListener(
115
135
  name: "perspective-config-update",
116
136
  cb: (e: CustomEvent) => void,
117
137
  options?: { signal: AbortSignal },
118
138
  ): void;
119
139
 
140
+ addEventListener(
141
+ name: "perspective-statusbar-pointerdown",
142
+ cb: (e: CustomEvent) => void,
143
+ options?: { signal: AbortSignal },
144
+ ): void;
145
+
146
+ addEventListener(
147
+ name: "perspective-table-delete",
148
+ cb: (e: CustomEvent) => void,
149
+ options?: { signal: AbortSignal },
150
+ ): void;
151
+
152
+ addEventListener(
153
+ name: "perspective-table-delete-before",
154
+ cb: (e: CustomEvent) => void,
155
+ options?: { signal: AbortSignal },
156
+ ): void;
157
+
120
158
  removeEventListener(name: "perspective-click", cb: any): void;
121
159
  removeEventListener(name: "perspective-select", cb: any): void;
122
160
  removeEventListener(name: "perspective-toggle-settings", cb: any): void;
161
+ removeEventListener(
162
+ name: "perspective-toggle-settings-before",
163
+ cb: any,
164
+ ): void;
123
165
  removeEventListener(name: "perspective-config-update", cb: any): void;
166
+ removeEventListener(
167
+ name: "perspective-statusbar-pointerdown",
168
+ cb: any,
169
+ ): void;
170
+ removeEventListener(name: "perspective-table-delete", cb: any): void;
171
+ removeEventListener(name: "perspective-table-delete-before", cb: any): void;
124
172
  }
@@ -13,7 +13,7 @@
13
13
  /**
14
14
  * Module for the `<perspective-viewer>` custom element. This module has no
15
15
  * (real) exports, but importing it has a side effect: the
16
- * `PerspectiveViewerElement`class is registered as a custom element, after
16
+ * `PerspectiveViewerElement` class is registered as a custom element, after
17
17
  * which it can be used as a standard DOM element.
18
18
  *
19
19
  * Though `<perspective-viewer>` is written mostly in Rust, the nature
@@ -33,20 +33,8 @@
33
33
 
34
34
  export { IPerspectiveViewerPlugin } from "./plugin";
35
35
  export { HTMLPerspectiveViewerPluginElement } from "./plugin";
36
- import {
37
- ExportDropDownMenuElement,
38
- CopyDropDownMenuElement,
39
- } from "../../dist/wasm/perspective-viewer";
40
36
 
41
- export interface HTMLPerspectiveViewerExportMenu
42
- extends HTMLElement,
43
- ExportDropDownMenuElement {}
44
-
45
- export interface HTMLPerspectiveViewerCopyMenu
46
- extends HTMLElement,
47
- CopyDropDownMenuElement {}
48
-
49
- export * from "./extensions";
37
+ export type * from "./extensions.ts";
50
38
  export type * from "./ts-rs/ViewerConfigUpdate.d.ts";
51
39
  export type * from "./ts-rs/ColumnConfigValues.d.ts";
52
40
  export type * from "./ts-rs/Filter.d.ts";
package/src/ts/plugin.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- import { View } from "@perspective-dev/client";
13
+ import type { View } from "@perspective-dev/client";
14
14
 
15
15
  // import type * as perspective from "@perspective-dev/client";
16
16
 
@@ -8,7 +8,7 @@ import type { OptionalUpdate } from "./OptionalUpdate.js";
8
8
  import type { PluginConfig } from "./PluginConfig.js";
9
9
  import type { Sort } from "./Sort.js";
10
10
 
11
- export type ViewerConfigUpdate = { version?: OptionalUpdate<string>, plugin?: OptionalUpdate<string>, title?: OptionalUpdate<string>, theme?: OptionalUpdate<string>, settings?: OptionalUpdate<boolean>, plugin_config?: PluginConfig | null, columns_config?: OptionalUpdate<{ [key in string]?: ColumnConfigValues }>,
11
+ export type ViewerConfigUpdate = { version?: OptionalUpdate<string>, plugin?: OptionalUpdate<string>, title?: OptionalUpdate<string>, table?: OptionalUpdate<string>, theme?: OptionalUpdate<string>, settings?: OptionalUpdate<boolean>, plugin_config?: PluginConfig | null, columns_config?: OptionalUpdate<{ [key in string]?: ColumnConfigValues }>,
12
12
  /**
13
13
  * A group by _groups_ the dataset by the unique values of each column used
14
14
  * as a group by - a close analogue in SQL to the `GROUP BY` statement.