@perspective-dev/viewer 4.0.0 → 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 (184) 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 +1251 -762
  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/export_app.rs +3 -2
  126. package/src/rust/model/get_viewer_config.rs +4 -28
  127. package/src/rust/model/intersection_observer.rs +20 -8
  128. package/src/rust/model/mod.rs +11 -4
  129. package/src/rust/model/plugin_column_styles.rs +0 -31
  130. package/src/rust/model/reset_all.rs +38 -0
  131. package/src/rust/model/resize_observer.rs +34 -7
  132. package/src/rust/model/restore_and_render.rs +12 -7
  133. package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
  134. package/src/rust/model/structural.rs +194 -23
  135. package/src/rust/model/update_and_render.rs +14 -4
  136. package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
  137. package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
  138. package/src/rust/presentation.rs +60 -119
  139. package/src/rust/renderer/activate.rs +20 -5
  140. package/src/rust/renderer/limits.rs +0 -149
  141. package/src/rust/renderer/render_timer.rs +1 -1
  142. package/src/rust/renderer.rs +34 -18
  143. package/src/rust/root.rs +50 -0
  144. package/src/rust/session/column_defaults_update.rs +4 -4
  145. package/src/rust/session/drag_drop_update.rs +1 -1
  146. package/src/rust/session/metadata.rs +3 -17
  147. package/src/rust/session/replace_expression_update.rs +1 -2
  148. package/src/rust/session.rs +162 -82
  149. package/src/rust/utils/browser/blob.rs +16 -2
  150. package/src/rust/utils/browser/download.rs +1 -0
  151. package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
  152. package/src/rust/utils/browser/mod.rs +8 -4
  153. package/src/rust/utils/browser/selection.rs +5 -0
  154. package/src/rust/utils/custom_element.rs +28 -13
  155. package/src/rust/utils/datetime.rs +5 -0
  156. package/src/rust/utils/debounce.rs +7 -1
  157. package/src/rust/utils/hooks/use_async_callback.rs +7 -17
  158. package/src/rust/utils/mod.rs +28 -40
  159. package/src/rust/utils/number_format.rs +6 -5
  160. package/src/rust/utils/pubsub.rs +15 -10
  161. package/src/rust/utils/weak_scope.rs +11 -1
  162. package/src/svg/bookmark-icon.svg +4 -0
  163. package/src/svg/drag-handle copy.svg +10 -0
  164. package/src/svg/drawer-tab-hover.svg +5 -7
  165. package/src/svg/drawer-tab-invert-hover.svg +4 -8
  166. package/src/svg/drawer-tab-invert.svg +4 -7
  167. package/src/svg/drawer-tab.svg +4 -6
  168. package/src/svg/status_ok.svg +24 -24
  169. package/src/ts/extensions.ts +51 -3
  170. package/src/ts/perspective-viewer.ts +2 -14
  171. package/src/ts/plugin.ts +1 -1
  172. package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
  173. package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
  174. package/src/rust/components/containers/tests/mod.rs +0 -11
  175. package/src/rust/components/containers/tests/split_panel.rs +0 -91
  176. package/src/rust/js/testing.rs +0 -149
  177. package/src/rust/utils/tee.rs +0 -88
  178. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
  179. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
  180. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
  181. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
  182. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
  183. /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
  184. /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
@@ -13,7 +13,6 @@
13
13
  use std::collections::HashMap;
14
14
 
15
15
  use serde::{Deserialize, Serialize};
16
- use serde_with::skip_serializing_none;
17
16
  use ts_rs::TS;
18
17
 
19
18
  use super::{
@@ -28,7 +27,6 @@ fn is_zero(x: &u32) -> bool {
28
27
 
29
28
  /// The value de/serialized and stored in the viewer config.
30
29
  /// Also passed to the plugin via `plugin.save()`.
31
- #[skip_serializing_none]
32
30
  #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, TS)]
33
31
  pub struct ColumnConfigValues {
34
32
  #[serde(default)]
@@ -130,3 +128,5 @@ pub struct KeyValueOpts {
130
128
  pub keys: KvPairKeys,
131
129
  pub values: Vec<String>,
132
130
  }
131
+
132
+ pub type SymbolKVPair = super::kvpair::KVPair<Option<String>, String>;
@@ -24,8 +24,6 @@ pub use simple::*;
24
24
  pub use simple_format::*;
25
25
  use ts_rs::TS;
26
26
 
27
- use crate::*;
28
-
29
27
  /// `Simple` case has all default-able keys and must be last!
30
28
  #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, TS)]
31
29
  // #[serde(tag = "format", content = "date_format")]
@@ -65,6 +63,7 @@ impl DatetimeFormatType {
65
63
  /// A model for the JSON serialized style configuration for a column of type
66
64
  /// `datetime`.
67
65
  #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, TS)]
66
+ // #[derive(WasmDescribe!, FromWasmAbi!)]
68
67
  pub struct DatetimeColumnStyleConfig {
69
68
  #[serde(default)]
70
69
  #[serde(skip_serializing_if = "DatetimeFormatType::is_simple")]
@@ -94,11 +93,7 @@ impl Default for DatetimeColumnStyleConfig {
94
93
  }
95
94
  }
96
95
 
97
- derive_wasm_abi!(DatetimeColumnStyleConfig, FromWasmAbi, IntoWasmAbi);
98
-
99
96
  #[derive(Clone, Default, Deserialize, Eq, PartialEq, Serialize, Debug)]
100
97
  pub struct DatetimeColumnStyleDefaultConfig {
101
98
  pub color: String,
102
99
  }
103
-
104
- derive_wasm_abi!(DatetimeColumnStyleDefaultConfig, FromWasmAbi);
@@ -15,6 +15,7 @@
15
15
 
16
16
  mod columns_config;
17
17
  mod datetime_column_style;
18
+ mod kvpair;
18
19
  mod number_column_style;
19
20
  mod number_string_format;
20
21
  mod string_column_style;
@@ -16,8 +16,6 @@ use serde::{Deserialize, Serialize};
16
16
  use strum::{Display, EnumIter};
17
17
  use ts_rs::TS;
18
18
 
19
- use crate::*;
20
-
21
19
  #[derive(
22
20
  Clone, Copy, Debug, Default, Deserialize, Display, EnumIter, Eq, PartialEq, Serialize, TS,
23
21
  )]
@@ -116,8 +114,6 @@ pub struct NumberColumnStyleConfig {
116
114
  pub bg_gradient: Option<f64>,
117
115
  }
118
116
 
119
- derive_wasm_abi!(NumberColumnStyleConfig, FromWasmAbi, IntoWasmAbi);
120
-
121
117
  /// Exactly like a `ColumnStyleConfig`, except without `Option<>` fields.
122
118
  ///
123
119
  /// Necessary because this struct represents the default values we should use in
@@ -134,5 +130,3 @@ pub struct NumberColumnStyleDefaultConfig {
134
130
  pub number_fg_mode: NumberForegroundMode,
135
131
  pub number_bg_mode: NumberBackgroundMode,
136
132
  }
137
-
138
- derive_wasm_abi!(NumberColumnStyleDefaultConfig, FromWasmAbi);
@@ -13,7 +13,6 @@
13
13
  mod enums;
14
14
  pub use enums::*;
15
15
  use serde::{Deserialize, Serialize};
16
- use serde_with::skip_serializing_none;
17
16
  use strum::{Display, EnumIter};
18
17
  use ts_rs::TS;
19
18
 
@@ -45,13 +44,16 @@ pub enum CurrencySign {
45
44
  Accounting,
46
45
  }
47
46
 
48
- #[skip_serializing_none]
49
47
  #[derive(Default, Serialize, Deserialize, Debug, PartialEq, Clone, TS)]
50
48
  #[serde(rename_all = "camelCase")]
51
49
  pub struct CurrencyNumberFormatStyle {
52
50
  #[serde(default)]
53
51
  pub currency: CurrencyCode,
52
+
53
+ #[serde(skip_serializing_if = "Option::is_none")]
54
54
  pub currency_display: Option<CurrencyDisplay>,
55
+
56
+ #[serde(skip_serializing_if = "Option::is_none")]
55
57
  pub currency_sign: Option<CurrencySign>,
56
58
  }
57
59
 
@@ -64,12 +66,13 @@ pub enum UnitDisplay {
64
66
  Long,
65
67
  }
66
68
 
67
- #[skip_serializing_none]
68
69
  #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, TS)]
69
70
  #[serde(rename_all = "camelCase")]
70
71
  pub struct UnitNumberFormatStyle {
71
72
  #[serde(default)]
72
73
  pub unit: Unit,
74
+
75
+ #[serde(skip_serializing_if = "Option::is_none")]
73
76
  pub unit_display: Option<UnitDisplay>,
74
77
  }
75
78
 
@@ -166,7 +169,6 @@ pub enum SignDisplay {
166
169
  Never,
167
170
  }
168
171
 
169
- #[skip_serializing_none]
170
172
  #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, TS)]
171
173
  #[serde(rename_all = "camelCase")]
172
174
  pub struct CustomNumberFormatConfig {
@@ -178,24 +180,45 @@ pub struct CustomNumberFormatConfig {
178
180
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#minimumintegerdigits
179
181
  // these min/max props can all be specified but it results in possible conflicts
180
182
  // may consider making them distinct options
183
+ #[serde(skip_serializing_if = "Option::is_none")]
181
184
  pub minimum_integer_digits: Option<f64>,
185
+
186
+ #[serde(skip_serializing_if = "Option::is_none")]
182
187
  pub minimum_fraction_digits: Option<f64>,
188
+
189
+ #[serde(skip_serializing_if = "Option::is_none")]
183
190
  pub maximum_fraction_digits: Option<f64>,
191
+
192
+ #[serde(skip_serializing_if = "Option::is_none")]
184
193
  pub minimum_significant_digits: Option<f64>,
194
+
195
+ #[serde(skip_serializing_if = "Option::is_none")]
185
196
  pub maximum_significant_digits: Option<f64>,
197
+
198
+ #[serde(skip_serializing_if = "Option::is_none")]
186
199
  pub rounding_priority: Option<RoundingPriority>,
187
200
 
188
201
  // specific values https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#roundingincrement
189
202
  // Only available with automatic rounding priority
190
203
  // Cannot be mixed with sigfig rounding. (Does this mean max/min sigfig must be unset?)
204
+ #[serde(skip_serializing_if = "Option::is_none")]
191
205
  pub rounding_increment: Option<f64>,
206
+
207
+ #[serde(skip_serializing_if = "Option::is_none")]
192
208
  pub rounding_mode: Option<RoundingMode>,
209
+
210
+ #[serde(skip_serializing_if = "Option::is_none")]
193
211
  pub trailing_zero_display: Option<TrailingZeroDisplay>,
194
212
 
195
213
  #[serde(flatten)]
196
214
  #[ts(skip)]
215
+ #[serde(skip_serializing_if = "Option::is_none")]
197
216
  pub _notation: Option<Notation>,
217
+
218
+ #[serde(skip_serializing_if = "Option::is_none")]
198
219
  pub use_grouping: Option<UseGrouping>,
220
+
221
+ #[serde(skip_serializing_if = "Option::is_none")]
199
222
  pub sign_display: Option<SignDisplay>,
200
223
  }
201
224
 
@@ -11,55 +11,30 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  use std::collections::HashMap;
14
- use std::io::{Read, Write};
15
14
  use std::ops::Deref;
16
- use std::str::FromStr;
17
15
  use std::sync::LazyLock;
18
16
 
19
- use flate2::Compression;
20
- use flate2::read::ZlibDecoder;
21
- use flate2::write::ZlibEncoder;
22
17
  use perspective_client::config::*;
23
18
  use perspective_js::utils::*;
24
19
  use serde::{Deserialize, Deserializer, Serialize};
25
20
  use serde_json::Value;
26
21
  use ts_rs::TS;
27
- use wasm_bindgen::JsCast;
28
22
  use wasm_bindgen::prelude::*;
29
23
 
30
24
  use super::ColumnConfigValues;
31
25
  use crate::presentation::ColumnConfigMap;
32
26
 
33
- pub enum ViewerConfigEncoding {
34
- Json,
35
- String,
36
- ArrayBuffer,
37
- JSONString,
38
- }
39
-
40
- impl FromStr for ViewerConfigEncoding {
41
- type Err = JsValue;
42
-
43
- fn from_str(s: &str) -> Result<Self, Self::Err> {
44
- match s {
45
- "json" => Ok(Self::Json),
46
- "string" => Ok(Self::String),
47
- "arraybuffer" => Ok(Self::ArrayBuffer),
48
- x => Err(format!("Unknown format \"{x}\"").into()),
49
- }
50
- }
51
- }
52
-
53
27
  /// The state of an entire `custom_elements::PerspectiveViewerElement` component
54
28
  /// and its `Plugin`.
55
- #[derive(Serialize, PartialEq)]
29
+ #[derive(Debug, Default, Serialize, PartialEq)]
56
30
  #[serde(deny_unknown_fields)]
57
- pub struct ViewerConfig {
58
- pub version: String,
31
+ pub struct ViewerConfig<V = String> {
32
+ pub version: V,
33
+ pub columns_config: ColumnConfigMap,
59
34
  pub plugin: String,
60
35
  pub plugin_config: Value,
61
- pub columns_config: ColumnConfigMap,
62
36
  pub settings: bool,
37
+ pub table: Option<String>,
63
38
  pub theme: Option<String>,
64
39
  pub title: Option<String>,
65
40
 
@@ -67,30 +42,6 @@ pub struct ViewerConfig {
67
42
  pub view_config: ViewConfig,
68
43
  }
69
44
 
70
- // `#[serde(flatten)]` makes messagepack 2x as big as they can no longer be
71
- // struct fields, so make a tuple alternative for serialization in binary.
72
- type ViewerConfigBinarySerialFormat<'a> = (
73
- &'a String,
74
- &'a ColumnConfigMap,
75
- &'a String,
76
- &'a Value,
77
- bool,
78
- &'a Option<String>,
79
- &'a Option<String>,
80
- &'a ViewConfig,
81
- );
82
-
83
- type ViewerConfigBinaryDeserialFormat = (
84
- VersionUpdate,
85
- ColumnConfigUpdate,
86
- PluginUpdate,
87
- Option<Value>,
88
- SettingsUpdate,
89
- ThemeUpdate,
90
- TitleUpdate,
91
- ViewConfigUpdate,
92
- );
93
-
94
45
  pub static API_VERSION: LazyLock<&'static str> = LazyLock::new(|| {
95
46
  #[derive(Deserialize)]
96
47
  struct Package {
@@ -102,76 +53,16 @@ pub static API_VERSION: LazyLock<&'static str> = LazyLock::new(|| {
102
53
  });
103
54
 
104
55
  impl ViewerConfig {
105
- fn token(&self) -> ViewerConfigBinarySerialFormat<'_> {
106
- (
107
- &self.version,
108
- &self.columns_config,
109
- &self.plugin,
110
- &self.plugin_config,
111
- self.settings,
112
- &self.theme,
113
- &self.title,
114
- &self.view_config,
115
- )
116
- }
117
-
118
56
  /// Encode a `ViewerConfig` to a `JsValue` in a supported type.
119
- pub fn encode(&self, format: &Option<ViewerConfigEncoding>) -> ApiResult<JsValue> {
120
- match format {
121
- Some(ViewerConfigEncoding::String) => {
122
- let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
123
- let bytes = rmp_serde::to_vec_named(&self.token())?;
124
- encoder.write_all(&bytes)?;
125
- let encoded = encoder.finish()?;
126
- Ok(JsValue::from(base64::encode(encoded)))
127
- },
128
- Some(ViewerConfigEncoding::ArrayBuffer) => {
129
- let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
130
- let bytes = rmp_serde::to_vec_named(&self.token())?;
131
- encoder.write_all(&bytes)?;
132
- let encoded = encoder.finish()?;
133
- let array = js_sys::Uint8Array::from(&encoded[..]);
134
- let start = array.byte_offset();
135
- let len = array.byte_length();
136
- Ok(array
137
- .buffer()
138
- .slice_with_end(start, start + len)
139
- .unchecked_into())
140
- },
141
- Some(ViewerConfigEncoding::JSONString) => {
142
- Ok(JsValue::from(serde_json::to_string(self)?))
143
- },
144
- None | Some(ViewerConfigEncoding::Json) => Ok(JsValue::from_serde_ext(self)?),
145
- }
57
+ pub fn encode(&self) -> ApiResult<JsValue> {
58
+ Ok(JsValue::from_serde_ext(self)?)
146
59
  }
147
60
  }
148
61
 
149
- #[derive(Clone, TS, Deserialize)]
62
+ #[derive(Clone, Debug, TS, Deserialize, PartialEq, Serialize)]
150
63
  #[serde(transparent)]
151
64
  pub struct PluginConfig(serde_json::Value);
152
65
 
153
- // impl Type for PluginConfig {
154
- // fn inline(type_map: &mut specta::TypeMap, generics: specta::Generics) ->
155
- // specta::DataType { specta::Map::from(());
156
- // // specta::Map {
157
- // // key_ty:
158
- // // specta::DataType::Primitive(specta::PrimitiveType::String),
159
- // // value_ty: specta::DataType::Any,
160
- // // }
161
-
162
- // // specta::DataType::Map(specta::Map { Box::new((
163
- // // specta::DataType::Primitive(specta::PrimitiveType::String),
164
- // // specta::DataType::Any,
165
- // // )))
166
- // }
167
- // // fn inline(_type_map: &mut specta::TypeMap, _generics:
168
- // &[specta::DataType]) -> // specta::DataType {
169
- // specta::DataType::Map(Box::new(( //
170
- // specta::DataType::Primitive(specta::PrimitiveType::String), //
171
- // specta::DataType::Any, // )))
172
- // // }
173
- // }
174
-
175
66
  impl Deref for PluginConfig {
176
67
  type Target = Value;
177
68
 
@@ -180,8 +71,7 @@ impl Deref for PluginConfig {
180
71
  }
181
72
  }
182
73
 
183
- #[derive(Clone, Deserialize, TS)]
184
- // #[serde(deny_unknown_fields)]
74
+ #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, TS)]
185
75
  pub struct ViewerConfigUpdate {
186
76
  #[serde(default)]
187
77
  #[ts(as = "Option<_>")]
@@ -198,6 +88,11 @@ pub struct ViewerConfigUpdate {
198
88
  #[ts(optional)]
199
89
  pub title: TitleUpdate,
200
90
 
91
+ #[serde(default)]
92
+ #[ts(as = "Option<_>")]
93
+ #[ts(optional)]
94
+ pub table: TableUpdate,
95
+
201
96
  #[serde(default)]
202
97
  #[ts(as = "Option<_>")]
203
98
  #[ts(optional)]
@@ -223,44 +118,10 @@ pub struct ViewerConfigUpdate {
223
118
  }
224
119
 
225
120
  impl ViewerConfigUpdate {
226
- fn from_token(
227
- (version, columns_config, plugin, plugin_config, settings, theme, title, view_config): ViewerConfigBinaryDeserialFormat,
228
- ) -> ViewerConfigUpdate {
229
- ViewerConfigUpdate {
230
- version,
231
- columns_config,
232
- plugin,
233
- plugin_config: plugin_config.map(PluginConfig),
234
- settings,
235
- theme,
236
- title,
237
- view_config,
238
- }
239
- }
240
-
241
121
  /// Decode a `JsValue` into a `ViewerConfigUpdate` by auto-detecting format
242
122
  /// from JavaScript type.
243
123
  pub fn decode(update: &JsValue) -> ApiResult<Self> {
244
- if update.is_string() {
245
- let js_str = update.as_string().into_apierror()?;
246
- let bytes = base64::decode(js_str)?;
247
- let mut decoder = ZlibDecoder::new(&*bytes);
248
- let mut decoded = vec![];
249
- decoder.read_to_end(&mut decoded)?;
250
- let token = rmp_serde::from_slice(&decoded[..])?;
251
- Ok(ViewerConfigUpdate::from_token(token))
252
- } else if update.is_instance_of::<js_sys::ArrayBuffer>() {
253
- let uint8array = js_sys::Uint8Array::new(update);
254
- let mut slice = vec![0; uint8array.length() as usize];
255
- uint8array.copy_to(&mut slice[..]);
256
- let mut decoder = ZlibDecoder::new(&*slice);
257
- let mut decoded = vec![];
258
- decoder.read_to_end(&mut decoded)?;
259
- let token = rmp_serde::from_slice(&decoded[..])?;
260
- Ok(ViewerConfigUpdate::from_token(token))
261
- } else {
262
- Ok(update.into_serde_ext()?)
263
- }
124
+ Ok(update.into_serde_ext()?)
264
125
  }
265
126
 
266
127
  pub fn migrate(&self) -> ApiResult<Self> {
@@ -269,7 +130,17 @@ impl ViewerConfigUpdate {
269
130
  }
270
131
  }
271
132
 
272
- #[derive(Clone, Debug, Serialize, TS)]
133
+ impl std::fmt::Display for ViewerConfigUpdate {
134
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135
+ write!(
136
+ f,
137
+ "{}",
138
+ serde_json::to_string(self).map_err(|_| std::fmt::Error)?
139
+ )
140
+ }
141
+ }
142
+
143
+ #[derive(Clone, Debug, Serialize, PartialEq, TS)]
273
144
  #[serde(untagged)]
274
145
  // #[ts(untagged)]
275
146
  pub enum OptionalUpdate<T: Clone> {
@@ -285,22 +156,11 @@ pub enum OptionalUpdate<T: Clone> {
285
156
  Update(T),
286
157
  }
287
158
 
288
- // #[derive(Clone, Debug, Serialize, TS)]
289
- // #[serde(flatten)]
290
- // pub struct OptionalUpdate<T: Clone> {
291
- // #[ts(optional)]
292
- // inner: Option<OptionalUpdateInner<T>>,
293
- // }
294
-
295
- // // #[ts(optional = nullable)]
296
-
297
- // #[derive(Clone, Debug, Serialize, TS)]
298
- // pub struct OptionalUpdateInner<T: Clone>(Option<T>);
299
-
300
159
  pub type PluginUpdate = OptionalUpdate<String>;
301
160
  pub type SettingsUpdate = OptionalUpdate<bool>;
302
161
  pub type ThemeUpdate = OptionalUpdate<String>;
303
162
  pub type TitleUpdate = OptionalUpdate<String>;
163
+ pub type TableUpdate = OptionalUpdate<String>;
304
164
  pub type VersionUpdate = OptionalUpdate<String>;
305
165
  pub type ColumnConfigUpdate = OptionalUpdate<HashMap<String, ColumnConfigValues>>;
306
166
 
@@ -61,7 +61,7 @@ impl CopyDropDownMenuElement {
61
61
  /// Internal Only.
62
62
  ///
63
63
  /// Set this custom element model's raw pointer.
64
- pub fn set_model(&self, parent: &PerspectiveViewerElement) {
64
+ pub fn __set_model(&self, parent: &PerspectiveViewerElement) {
65
65
  self.set_config_model(parent)
66
66
  }
67
67
 
@@ -69,7 +69,11 @@ impl CopyDropDownMenuElement {
69
69
  }
70
70
 
71
71
  impl CopyDropDownMenuElement {
72
- pub fn new_from_model<A: GetViewerConfigModel>(model: &A) -> Self {
72
+ pub fn new_from_model<A>(model: &A) -> Self
73
+ where
74
+ A: GetViewerConfigModel + StateProvider,
75
+ <A as StateProvider>::State: HasPresentation + HasRenderer + HasSession,
76
+ {
73
77
  let dropdown = global::document()
74
78
  .create_element("perspective-copy-menu")
75
79
  .unwrap()
@@ -80,18 +84,22 @@ impl CopyDropDownMenuElement {
80
84
  elem
81
85
  }
82
86
 
83
- pub fn set_config_model<A: GetViewerConfigModel>(&self, model: &A) {
87
+ pub fn set_config_model<A>(&self, model: &A)
88
+ where
89
+ A: GetViewerConfigModel + StateProvider,
90
+ <A as StateProvider>::State: HasPresentation + HasRenderer + HasSession,
91
+ {
84
92
  let callback = Callback::from({
85
- let model = model.cloned();
93
+ let model = model.clone_state();
86
94
  let modal_rc = self.modal.clone();
87
95
  move |x: ExportFile| {
88
96
  let model = model.clone();
89
97
  let modal = modal_rc.borrow().clone().unwrap();
90
98
  spawn_local(async move {
91
99
  let mime = x.method.mimetype(x.is_chart);
92
- let task = model.export_method_to_jsvalue(x.method);
100
+ let task = model.export_method_to_blob(x.method);
93
101
  let result = copy_to_clipboard(task, mime).await;
94
- crate::js_log_maybe!({
102
+ crate::maybe_log!({
95
103
  result?;
96
104
  modal.hide()?;
97
105
  })
@@ -61,7 +61,7 @@ impl ExportDropDownMenuElement {
61
61
  /// Internal Only.
62
62
  ///
63
63
  /// Set this custom element model's raw pointer.
64
- pub fn set_model(&self, parent: &PerspectiveViewerElement) {
64
+ pub fn __set_model(&self, parent: &PerspectiveViewerElement) {
65
65
  self.set_config_model(parent)
66
66
  }
67
67
 
@@ -69,7 +69,11 @@ impl ExportDropDownMenuElement {
69
69
  }
70
70
 
71
71
  impl ExportDropDownMenuElement {
72
- pub fn new_from_model<A: GetViewerConfigModel>(model: &A) -> Self {
72
+ pub fn new_from_model<A>(model: &A) -> Self
73
+ where
74
+ A: GetViewerConfigModel + StateProvider,
75
+ <A as StateProvider>::State: HasPresentation + HasRenderer + HasSession,
76
+ {
73
77
  let dropdown = global::document()
74
78
  .create_element("perspective-export-menu")
75
79
  .unwrap()
@@ -80,15 +84,19 @@ impl ExportDropDownMenuElement {
80
84
  elem
81
85
  }
82
86
 
83
- fn set_config_model<A: GetViewerConfigModel>(&self, model: &A) {
87
+ fn set_config_model<A>(&self, model: &A)
88
+ where
89
+ A: GetViewerConfigModel + StateProvider,
90
+ <A as StateProvider>::State: HasPresentation + HasRenderer + HasSession,
91
+ {
84
92
  let callback = Callback::from({
85
- let model = model.cloned();
93
+ let model = model.clone_state();
86
94
  let modal_rc = self.modal.clone();
87
95
  move |x: ExportFile| {
88
96
  if !x.name.is_empty() {
89
97
  clone!(modal_rc, model);
90
98
  spawn_local(async move {
91
- let val = model.export_method_to_jsvalue(x.method).await.unwrap();
99
+ let val = model.export_method_to_blob(x.method).await.unwrap();
92
100
  let is_chart = model.renderer().is_chart();
93
101
  download(&x.as_filename(is_chart), &val).unwrap();
94
102
  modal_rc.borrow().clone().unwrap().hide().unwrap();
@@ -98,10 +106,10 @@ impl ExportDropDownMenuElement {
98
106
  });
99
107
 
100
108
  let renderer = model.renderer().clone();
101
- let presentation = model.presentation().clone();
109
+ let session = model.session().clone();
102
110
  let props = props!(ExportDropDownMenuProps {
103
111
  renderer,
104
- presentation,
112
+ session,
105
113
  callback,
106
114
  root: self.elem.clone()
107
115
  });
@@ -93,10 +93,10 @@ impl FilterDropDownElement {
93
93
  FilterDropDownMsg::SetValues(values),
94
94
  ]);
95
95
 
96
- if let Some(x) = self.target.borrow().clone()
97
- && !self.modal.is_open()
98
- {
99
- ApiFuture::spawn(self.modal.clone().open(x, None))
96
+ if let Some(x) = self.target.borrow().clone() {
97
+ if !self.modal.is_open() {
98
+ ApiFuture::spawn(self.modal.clone().open(x, None))
99
+ }
100
100
  }
101
101
  }
102
102
  },
@@ -10,6 +10,9 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
+ //! Each file in `custom_elements` exports a single struct which will be the
14
+ //! public [`wasm_bindgen`] API to a JavaScript Custom Element.
15
+
13
16
  mod column_dropdown;
14
17
  pub mod copy_dropdown;
15
18
  pub mod debug_plugin;