@perspective-dev/viewer 4.5.2 → 5.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 (178) hide show
  1. package/dist/cdn/perspective-viewer.js +20 -1
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/botanical.css +1 -1
  4. package/dist/css/dracula.css +1 -1
  5. package/dist/css/gruvbox-dark.css +1 -1
  6. package/dist/css/gruvbox.css +1 -1
  7. package/dist/css/icons.css +1 -1
  8. package/dist/css/monokai.css +1 -1
  9. package/dist/css/phosphor.css +1 -1
  10. package/dist/css/pro-dark.css +1 -1
  11. package/dist/css/pro.css +1 -1
  12. package/dist/css/solarized-dark.css +1 -1
  13. package/dist/css/solarized.css +1 -1
  14. package/dist/css/themes.css +1 -1
  15. package/dist/css/vaporwave.css +1 -1
  16. package/dist/esm/extensions.d.ts +22 -3
  17. package/dist/esm/perspective-viewer.d.ts +9 -0
  18. package/dist/esm/perspective-viewer.inline.js +20 -1
  19. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  20. package/dist/esm/perspective-viewer.js +20 -1
  21. package/dist/esm/perspective-viewer.js.map +4 -4
  22. package/dist/esm/plugin.d.ts +71 -5
  23. package/dist/esm/ts-rs/ClientOptions.d.ts +7 -0
  24. package/dist/esm/ts-rs/ExportMethod.d.ts +1 -0
  25. package/dist/esm/ts-rs/ExportOptions.d.ts +9 -0
  26. package/dist/esm/ts-rs/GetClientOptions.d.ts +8 -0
  27. package/dist/esm/ts-rs/GetTableOptions.d.ts +8 -0
  28. package/dist/esm/ts-rs/Layout.d.ts +11 -0
  29. package/dist/esm/ts-rs/Orientation.d.ts +4 -0
  30. package/dist/esm/ts-rs/PanelOptions.d.ts +7 -0
  31. package/dist/esm/ts-rs/PanelViewerConfig.d.ts +39 -0
  32. package/dist/esm/ts-rs/SplitLayout.d.ts +7 -0
  33. package/dist/esm/ts-rs/TabLayout.d.ts +10 -0
  34. package/dist/esm/ts-rs/ViewerConfig.d.ts +6 -2
  35. package/dist/esm/ts-rs/WorkspaceConfig.d.ts +40 -0
  36. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +28 -0
  37. package/dist/wasm/perspective-viewer.d.ts +211 -77
  38. package/dist/wasm/perspective-viewer.js +528 -180
  39. package/dist/wasm/perspective-viewer.wasm +0 -0
  40. package/dist/wasm/perspective-viewer.wasm.d.ts +34 -26
  41. package/dist/wasm/snippets/perspective-viewer-daeef4ceb066e6c7/inline0.js +6 -0
  42. package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline3.js → perspective-viewer-daeef4ceb066e6c7/inline4.js} +5 -0
  43. package/package.json +3 -2
  44. package/src/css/_context_menu.css +14 -0
  45. package/src/css/column-settings-panel.css +1 -1
  46. package/src/css/containers/context-menu.css +101 -0
  47. package/src/css/panel-tab.css +193 -0
  48. package/src/css/plugin-selector.css +7 -10
  49. package/src/css/status-bar.css +75 -81
  50. package/src/css/viewer.css +180 -70
  51. package/src/rust/components/column_dropdown.rs +40 -30
  52. package/src/rust/components/column_selector/active_column.rs +7 -18
  53. package/src/rust/components/column_selector/aggregate_selector.rs +4 -7
  54. package/src/rust/components/column_selector/config_selector.rs +33 -81
  55. package/src/rust/components/column_selector/filter_column.rs +5 -15
  56. package/src/rust/components/column_selector/inactive_column.rs +3 -8
  57. package/src/rust/components/column_selector/sort_column.rs +3 -6
  58. package/src/rust/components/column_selector.rs +5 -11
  59. package/src/rust/components/containers/split_panel.rs +175 -62
  60. package/src/rust/components/context_menu.rs +130 -0
  61. package/src/rust/components/form/debug.rs +3 -0
  62. package/src/rust/components/global_filter_bar.rs +76 -0
  63. package/src/rust/components/main_panel/frame_theme.rs +186 -0
  64. package/src/rust/components/main_panel/msg.rs +62 -0
  65. package/src/rust/components/main_panel/presize.rs +220 -0
  66. package/src/rust/components/main_panel/reconcile.rs +224 -0
  67. package/src/rust/components/main_panel/render.rs +385 -0
  68. package/src/rust/components/main_panel/update.rs +184 -0
  69. package/src/rust/components/main_panel.rs +311 -71
  70. package/src/rust/components/mod.rs +4 -0
  71. package/src/rust/components/panel_menu.rs +486 -0
  72. package/src/rust/components/panel_tab.rs +505 -0
  73. package/src/rust/components/plugin_tab.rs +1 -1
  74. package/src/rust/components/settings_panel.rs +13 -5
  75. package/src/rust/components/status_bar.rs +110 -178
  76. package/src/rust/components/status_indicator.rs +6 -9
  77. package/src/rust/components/style/mod.rs +5 -0
  78. package/src/rust/components/style/style_provider.rs +2 -0
  79. package/src/rust/components/viewer/filters.rs +133 -0
  80. package/src/rust/components/viewer/msg.rs +180 -0
  81. package/src/rust/components/viewer/panels.rs +326 -0
  82. package/src/rust/components/viewer/render.rs +243 -0
  83. package/src/rust/components/viewer/settings.rs +402 -0
  84. package/src/rust/components/viewer/snapshots.rs +134 -0
  85. package/src/rust/components/viewer/wiring.rs +505 -0
  86. package/src/rust/components/viewer.rs +243 -756
  87. package/src/rust/config/export_method.rs +1 -1
  88. package/src/rust/config/mod.rs +4 -0
  89. package/src/rust/config/options.rs +71 -0
  90. package/src/rust/config/viewer_config.rs +24 -2
  91. package/src/rust/config/workspace_config.rs +92 -0
  92. package/src/rust/custom_elements/copy_dropdown.rs +3 -1
  93. package/src/rust/custom_elements/debug_plugin.rs +20 -1
  94. package/src/rust/custom_elements/export_dropdown.rs +3 -1
  95. package/src/rust/custom_elements/viewer.rs +1015 -286
  96. package/src/rust/custom_events.rs +212 -61
  97. package/src/rust/js/mod.rs +2 -0
  98. package/src/rust/js/plugin.rs +297 -10
  99. package/src/rust/js/regular_layout.rs +258 -0
  100. package/src/rust/lib.rs +20 -1
  101. package/src/rust/presentation.rs +66 -33
  102. package/src/rust/queries/get_viewer_config.rs +29 -11
  103. package/src/rust/queries/plugin_column_styles.rs +2 -2
  104. package/src/rust/renderer/activate.rs +41 -14
  105. package/src/rust/renderer/dispatch.rs +436 -0
  106. package/src/rust/renderer/plugin_config.rs +495 -0
  107. package/src/rust/renderer/registry.rs +18 -6
  108. package/src/rust/renderer/render_timer.rs +29 -10
  109. package/src/rust/renderer.rs +350 -837
  110. package/src/rust/session/column_defaults_update.rs +26 -8
  111. package/src/rust/session/view_subscription.rs +30 -15
  112. package/src/rust/session.rs +753 -264
  113. package/src/rust/tasks/apply_global_filters.rs +89 -0
  114. package/src/rust/tasks/auto_pause.rs +171 -0
  115. package/src/rust/tasks/copy_export.rs +29 -19
  116. package/src/rust/tasks/create_panel.rs +243 -0
  117. package/src/rust/tasks/dismiss_render_warning.rs +3 -1
  118. package/src/rust/tasks/edit_expression.rs +4 -4
  119. package/src/rust/tasks/eject.rs +64 -23
  120. package/src/rust/tasks/mod.rs +28 -4
  121. package/src/rust/tasks/pipeline.rs +411 -0
  122. package/src/rust/tasks/presize_panels.rs +324 -0
  123. package/src/rust/tasks/reset_all.rs +22 -12
  124. package/src/rust/tasks/resize_observer.rs +124 -87
  125. package/src/rust/tasks/restore_and_render.rs +80 -86
  126. package/src/rust/tasks/restore_panel.rs +145 -0
  127. package/src/rust/tasks/send_column_config.rs +5 -2
  128. package/src/rust/tasks/send_plugin_config.rs +5 -2
  129. package/src/rust/tasks/set_edit_mode.rs +59 -0
  130. package/src/rust/tasks/sync_update_panels.rs +152 -0
  131. package/src/rust/tasks/table_lifecycle.rs +158 -0
  132. package/src/rust/tasks/update_theme.rs +56 -12
  133. package/src/rust/utils/completion.rs +56 -0
  134. package/src/rust/utils/custom_element.rs +5 -0
  135. package/src/rust/utils/debounce.rs +130 -7
  136. package/src/rust/utils/mod.rs +6 -0
  137. package/src/rust/utils/pending_effects.rs +62 -0
  138. package/src/rust/utils/spawn.rs +33 -0
  139. package/src/rust/utils/weak_scope.rs +0 -10
  140. package/src/rust/workspace.rs +846 -0
  141. package/src/svg/active-indicator.svg +3 -0
  142. package/src/themes/botanical.css +5 -2
  143. package/src/themes/defaults.css +54 -2
  144. package/src/themes/dracula.css +6 -3
  145. package/src/themes/gruvbox-dark.css +5 -2
  146. package/src/themes/gruvbox.css +5 -2
  147. package/src/themes/icons.css +4 -2
  148. package/src/themes/monokai.css +5 -2
  149. package/src/themes/phosphor.css +5 -2
  150. package/src/themes/pro-dark.css +5 -2
  151. package/src/themes/pro.css +2 -1
  152. package/src/themes/solarized-dark.css +5 -2
  153. package/src/themes/solarized.css +5 -2
  154. package/src/themes/vaporwave.css +5 -2
  155. package/src/ts/bootstrap.ts +8 -7
  156. package/src/ts/extensions.ts +30 -2
  157. package/src/ts/perspective-viewer.ts +10 -0
  158. package/src/ts/plugin.ts +72 -5
  159. package/src/ts/ts-rs/ClientOptions.ts +7 -0
  160. package/src/ts/ts-rs/ExportMethod.ts +3 -0
  161. package/src/ts/ts-rs/ExportOptions.ts +8 -0
  162. package/src/ts/ts-rs/GetClientOptions.ts +7 -0
  163. package/src/ts/ts-rs/GetTableOptions.ts +7 -0
  164. package/src/ts/ts-rs/Layout.ts +9 -0
  165. package/src/ts/ts-rs/Orientation.ts +6 -0
  166. package/src/ts/ts-rs/PanelOptions.ts +7 -0
  167. package/src/ts/ts-rs/PanelViewerConfig.ts +15 -0
  168. package/src/ts/ts-rs/SplitLayout.ts +5 -0
  169. package/src/ts/ts-rs/TabLayout.ts +11 -0
  170. package/src/ts/ts-rs/ViewerConfig.ts +6 -2
  171. package/src/ts/ts-rs/WorkspaceConfig.ts +36 -0
  172. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +24 -0
  173. package/src/rust/tasks/intersection_observer.rs +0 -98
  174. package/src/rust/tasks/update_and_render.rs +0 -110
  175. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline0.js → perspective-viewer-daeef4ceb066e6c7/inline1.js} +0 -0
  176. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline1.js → perspective-viewer-daeef4ceb066e6c7/inline2.js} +0 -0
  177. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline2.js → perspective-viewer-daeef4ceb066e6c7/inline3.js} +0 -0
  178. /package/dist/wasm/snippets/{perspective-viewer-93064d0d79855d97/inline4.js → perspective-viewer-daeef4ceb066e6c7/inline5.js} +0 -0
@@ -0,0 +1,7 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+
3
+ /**
4
+ * The `getTable` argument: whether to `wait` for a `Table`, and the target
5
+ * panel.
6
+ */
7
+ export type GetTableOptions = { wait?: boolean, panel?: string, };
@@ -0,0 +1,9 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { SplitLayout } from "./SplitLayout.js";
3
+ import type { TabLayout } from "./TabLayout.js";
4
+
5
+ /**
6
+ * A serde mirror of `regular-layout`'s serialized layout tree, as returned by
7
+ * [`RegularLayout::save`] and accepted by [`RegularLayout::restore`].
8
+ */
9
+ export type Layout = { "type": "split-layout" } & SplitLayout | { "type": "tab-layout" } & TabLayout;
@@ -0,0 +1,6 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+
3
+ /**
4
+ * The orientation of a [`SplitLayout`].
5
+ */
6
+ export type Orientation = "horizontal" | "vertical";
@@ -0,0 +1,7 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+
3
+ /**
4
+ * Selects the target panel of a panel-scoped `<perspective-viewer>` method;
5
+ * the active panel when `panel` is omitted.
6
+ */
7
+ export type PanelOptions = { panel?: string, };
@@ -0,0 +1,15 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { Aggregate } from "./Aggregate.js";
3
+ import type { Expressions } from "./Expressions.js";
4
+ import type { Filter } from "./Filter.js";
5
+ import type { FilterReducer } from "./FilterReducer.js";
6
+ import type { GroupRollupMode } from "./GroupRollupMode.js";
7
+ import type { Sort } from "./Sort.js";
8
+ import type { JsonValue } from "./serde_json/JsonValue.js";
9
+
10
+ /**
11
+ * The per-panel state of a [`ViewerConfig`] — everything except the
12
+ * element-level `settings` flag. This is the `panels` entry type of the
13
+ * whole-element config format.
14
+ */
15
+ export type PanelViewerConfig<V = string> = { version: V, columns_config: { [key in string]?: { [key in string]?: JsonValue } }, plugin: string, plugin_config: { [key in string]?: JsonValue }, table: string | null, theme: string | null, title: string | null, group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, group_rollup_mode: GroupRollupMode, filter_op?: FilterReducer, expressions: Expressions, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
@@ -0,0 +1,5 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { Layout } from "./Layout.js";
3
+ import type { Orientation } from "./Orientation.js";
4
+
5
+ export type SplitLayout = { children: Array<Layout>, sizes: Array<number>, orientation: Orientation, };
@@ -0,0 +1,11 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+
3
+ export type TabLayout = {
4
+ /**
5
+ * Panel ids (slot names) in this stack.
6
+ */
7
+ tabs: Array<string>,
8
+ /**
9
+ * Index of the selected tab within `tabs`.
10
+ */
11
+ selected?: number, };
@@ -9,6 +9,10 @@ import type { JsonValue } from "./serde_json/JsonValue.js";
9
9
 
10
10
  /**
11
11
  * The state of an entire `custom_elements::PerspectiveViewerElement` component
12
- * and its `Plugin`.
12
+ * and its `Plugin`: the element-level `settings` flag plus the per-panel
13
+ * [`PanelViewerConfig`]. The split exists so the whole-element config format
14
+ * can serialize panel entries *without* a `settings` key (it is element-level
15
+ * state there, carried by the top-level `active` field instead), while the
16
+ * single-panel format flattens back to the legacy shape.
13
17
  */
14
- export type ViewerConfig<V = string> = { version: V, columns_config: { [key in string]?: { [key in string]?: JsonValue } }, plugin: string, plugin_config: { [key in string]?: JsonValue }, settings: boolean, table: string | null, theme: string | null, title: string | null, group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, group_rollup_mode: GroupRollupMode, filter_op?: FilterReducer, expressions: Expressions, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
18
+ export type ViewerConfig<V = string> = { settings: boolean, version: V, columns_config: { [key in string]?: { [key in string]?: JsonValue } }, plugin: string, plugin_config: { [key in string]?: JsonValue }, table: string | null, theme: string | null, title: string | null, group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, group_rollup_mode: GroupRollupMode, filter_op?: FilterReducer, expressions: Expressions, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
@@ -0,0 +1,36 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { Filter } from "./Filter.js";
3
+ import type { Layout } from "./Layout.js";
4
+ import type { PanelViewerConfig } from "./PanelViewerConfig.js";
5
+
6
+ /**
7
+ * The whole-element config format (`{version, active?, layout, panels}`) —
8
+ * the multi-panel counterpart of the single-panel [`ViewerConfig`] — as
9
+ * emitted by [`PerspectiveViewerElement::save`].
10
+ *
11
+ * - `panels` entries are [`PanelViewerConfig`]s: per-panel state only, no
12
+ * `settings` key (element-level state).
13
+ * - `active` names the panel targeted by the *open* settings sidebar; it is
14
+ * omitted when the sidebar is closed.
15
+ */
16
+ export type WorkspaceConfig = { version: string, active?: string, layout: Layout | null,
17
+ /**
18
+ * `BTreeMap` (not `HashMap`) so `save()` serializes panels in a
19
+ * DETERMINISTIC (sorted) key order — a fresh `HashMap` per call
20
+ * iterates in a per-instance random order, which made consecutive
21
+ * `save()` outputs byte-unstable.
22
+ */
23
+ panels: { [key in string]?: PanelViewerConfig<string> },
24
+ /**
25
+ * The element-level global (master/detail cross-) filters. A transient
26
+ * overlay on every detail panel's view — persisted here, never in a
27
+ * per-panel entry. Omitted when empty.
28
+ */
29
+ global_filters?: Array<Filter>,
30
+ /**
31
+ * The MASTER (filter-source) panels' ids, referencing `panels` keys.
32
+ * Roles are layout state (like the panel arrangement), so they persist;
33
+ * which master contributed which clause does not — restored
34
+ * `global_filters` are one unattributed bucket. Omitted when empty.
35
+ */
36
+ masters?: Array<string>, };
@@ -0,0 +1,24 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { Filter } from "./Filter.js";
3
+ import type { Layout } from "./Layout.js";
4
+ import type { ViewerConfigUpdate } from "./ViewerConfigUpdate.js";
5
+
6
+ /**
7
+ * The parse target of a whole-element config in
8
+ * [`PerspectiveViewerElement::restore`]. Mirrors [`WorkspaceConfig`],
9
+ * but `panels` entries are full [`ViewerConfigUpdate`]s so a stray per-panel
10
+ * `settings` can be detected (warned, then ignored — `create_panel` strips
11
+ * it).
12
+ */
13
+ export type WorkspaceConfigUpdate = { active?: string, layout?: Layout, panels: { [key in string]?: ViewerConfigUpdate },
14
+ /**
15
+ * The element-level global (master/detail cross-) filters to re-apply as
16
+ * a transient overlay on every DETAIL panel. Restored as one
17
+ * unattributed bucket: the next selection on any master replaces it.
18
+ */
19
+ global_filters?: Array<Filter>,
20
+ /**
21
+ * The master (filter-source) panels, by saved `panels` key. An id not in
22
+ * `panels` warns and is dropped.
23
+ */
24
+ masters?: Array<string>, };
@@ -1,98 +0,0 @@
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::JsCast;
14
- use wasm_bindgen::prelude::*;
15
- use web_sys::*;
16
-
17
- use crate::config::ViewerConfigUpdate;
18
- use crate::js::*;
19
- use crate::presentation::Presentation;
20
- use crate::renderer::*;
21
- use crate::session::Session;
22
- use crate::utils::*;
23
- use crate::*;
24
-
25
- pub struct IntersectionObserverHandle {
26
- elem: HtmlElement,
27
- observer: IntersectionObserver,
28
- _callback: Closure<dyn FnMut(js_sys::Array)>,
29
- }
30
-
31
- impl IntersectionObserverHandle {
32
- pub fn new(
33
- elem: &HtmlElement,
34
- presentation: &Presentation,
35
- session: &Session,
36
- renderer: &Renderer,
37
- ) -> Self {
38
- clone!(session, renderer, presentation);
39
- let _callback = Closure::new(move |xs: js_sys::Array| {
40
- // https://stackoverflow.com/questions/53862160/intersectionobserver-multiple-entries
41
- let intersect = xs
42
- .pop()
43
- .unchecked_into::<IntersectionObserverEntry>()
44
- .is_intersecting();
45
-
46
- clone!(session, renderer, presentation);
47
- let state = IntersectionObserverState {
48
- presentation,
49
- session,
50
- renderer,
51
- };
52
-
53
- ApiFuture::spawn(state.set_pause(intersect));
54
- });
55
-
56
- let func = _callback.as_ref().unchecked_ref::<js_sys::Function>();
57
- let observer = IntersectionObserver::new(func);
58
- observer.observe(elem);
59
- Self {
60
- elem: elem.clone(),
61
- _callback,
62
- observer,
63
- }
64
- }
65
- }
66
-
67
- impl Drop for IntersectionObserverHandle {
68
- fn drop(&mut self) {
69
- self.observer.unobserve(&self.elem);
70
- }
71
- }
72
-
73
- struct IntersectionObserverState {
74
- session: Session,
75
- renderer: Renderer,
76
- presentation: Presentation,
77
- }
78
-
79
- impl IntersectionObserverState {
80
- async fn set_pause(self, intersect: bool) -> ApiResult<()> {
81
- if intersect {
82
- if self.session.set_pause(false) {
83
- super::restore_and_render(
84
- &self.session,
85
- &self.renderer,
86
- &self.presentation,
87
- ViewerConfigUpdate::default(),
88
- async move { Ok(()) },
89
- )
90
- .await?;
91
- }
92
- } else {
93
- self.session.set_pause(true);
94
- };
95
-
96
- Ok(())
97
- }
98
- }
@@ -1,110 +0,0 @@
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
- //! Apply a [`ViewConfigUpdate`] to the active [`Session`], validate it, then
14
- //! draw with the active [`Renderer`]. The companion `*_callback` helpers
15
- //! return [`yew::Callback`]s suitable for wiring as Yew child-component
16
- //! props.
17
-
18
- use perspective_client::config::ViewConfigUpdate;
19
- use yew::prelude::*;
20
-
21
- use crate::renderer::Renderer;
22
- use crate::session::Session;
23
- use crate::utils::*;
24
- use crate::*;
25
-
26
- /// Create a [`Callback`] that renders from the current `View` and `Plugin`.
27
- pub fn render_callback(session: &Session, renderer: &Renderer) -> Callback<()> {
28
- clone!(session, renderer);
29
- Callback::from(move |_| {
30
- clone!(session, renderer);
31
- ApiFuture::spawn(async move {
32
- renderer.draw(async { Ok(session.get_view()) }).await?;
33
- Ok(())
34
- })
35
- })
36
- }
37
-
38
- /// Create a [`Callback`] that resizes from the current `View` and `Plugin`.
39
- pub fn resize_callback(session: &Session, renderer: &Renderer) -> Callback<()> {
40
- clone!(session, renderer);
41
- Callback::from(move |_| {
42
- clone!(renderer, session);
43
- ApiFuture::spawn(async move {
44
- if !renderer.is_plugin_activated()? {
45
- update_and_render_inner(session, renderer).await?
46
- } else {
47
- renderer.resize().await?;
48
- }
49
-
50
- Ok(())
51
- })
52
- })
53
- }
54
-
55
- /// Apply a `ViewConfigUpdate` to the current `View` and render.
56
- pub fn update_and_render(
57
- session: &Session,
58
- renderer: &Renderer,
59
- update: ViewConfigUpdate,
60
- ) -> ApiResult<ApiFuture<()>> {
61
- session.update_view_config(update)?;
62
- clone!(session, renderer);
63
- Ok(ApiFuture::new(update_and_render_inner(session, renderer)))
64
- }
65
-
66
- /// Re-render the current `View` and `Plugin` without applying a new
67
- /// `ViewConfigUpdate`.
68
- pub fn just_render(session: &Session, renderer: &Renderer) -> ApiResult<ApiFuture<()>> {
69
- clone!(session, renderer);
70
- Ok(ApiFuture::new(update_and_render_inner(session, renderer)))
71
- }
72
-
73
- #[tracing::instrument(level = "debug", skip(session, renderer))]
74
- async fn update_and_render_inner(session: Session, renderer: Renderer) -> ApiResult<()> {
75
- // The previous call which acquired the lock errored, so skip this render
76
- if session.get_error().is_some() {
77
- return Ok(());
78
- }
79
-
80
- let plugin_swapped = renderer.apply_pending_plugin()?;
81
-
82
- // Validate + create the view BEFORE the plugin-swap materialize
83
- // so the schema query sees fresh `expression_schema` /
84
- // `view_schema` and `resolve_abs_max` has a bound view that
85
- // knows about any new expression columns.
86
- let view = session.validate().await?.create_view().await?;
87
-
88
- if plugin_swapped {
89
- // `commit_plugin_idx` already restored the new plugin from its
90
- // raw bucket; re-run with the materialized snapshot so any
91
- // `include: true` schema defaults (e.g. Datagrid's
92
- // `fg_gradient` when `number_fg_mode = "bar"`) make it into
93
- // the plugin's state before the first draw. The Session is in
94
- // scope here but not at `commit_plugin_idx`'s call sites in
95
- // the column-selector tree, so we do the second restore at
96
- // the caller instead of plumbing `&Session` through every
97
- // `apply_pending_plugin` site.
98
- let view_config_snapshot = session.get_view_config().clone();
99
- let plugin_token = wasm_bindgen::JsValue::from_serde_ext(&renderer.get_plugin_config())
100
- .unwrap_or(wasm_bindgen::JsValue::NULL);
101
- let columns_config = renderer
102
- .all_columns_configs_materialized(&view_config_snapshot, &session)
103
- .await;
104
- renderer
105
- .get_active_plugin()?
106
- .restore(&plugin_token, Some(&columns_config))?;
107
- }
108
-
109
- renderer.draw(async { Ok(view) }).await
110
- }