@perspective-dev/viewer 5.5.1 → 5.6.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 (194) hide show
  1. package/README.md +82 -3
  2. package/dist/cdn/perspective-viewer.js +9 -9
  3. package/dist/cdn/perspective-viewer.js.map +3 -3
  4. package/dist/css/blueprint.css +1 -1
  5. package/dist/css/botanical.css +1 -1
  6. package/dist/css/dracula.css +1 -1
  7. package/dist/css/eggplant.css +1 -1
  8. package/dist/css/gruvbox-dark.css +1 -1
  9. package/dist/css/gruvbox.css +1 -1
  10. package/dist/css/icons.css +1 -1
  11. package/dist/css/intl/ar.css +1 -1
  12. package/dist/css/intl/de.css +1 -1
  13. package/dist/css/intl/es.css +1 -1
  14. package/dist/css/intl/fr.css +1 -1
  15. package/dist/css/intl/ja.css +1 -1
  16. package/dist/css/intl/pt.css +1 -1
  17. package/dist/css/intl/zh.css +1 -1
  18. package/dist/css/intl.css +1 -1
  19. package/dist/css/ledger.css +1 -1
  20. package/dist/css/monokai.css +1 -1
  21. package/dist/css/nord.css +1 -1
  22. package/dist/css/phosphor.css +1 -1
  23. package/dist/css/pro-dark.css +1 -1
  24. package/dist/css/pro.css +1 -1
  25. package/dist/css/solarized-dark.css +1 -1
  26. package/dist/css/solarized.css +1 -1
  27. package/dist/css/themes.css +1 -1
  28. package/dist/css/vaporwave.css +1 -1
  29. package/dist/css/velvet.css +1 -1
  30. package/dist/docs/perspective-docs.json +1 -1
  31. package/dist/esm/column-format.js +2 -0
  32. package/dist/esm/column-format.js.map +7 -0
  33. package/dist/esm/extensions.d.ts +3 -13
  34. package/dist/esm/perspective-viewer.d.ts +1 -1
  35. package/dist/esm/perspective-viewer.js +9 -9
  36. package/dist/esm/perspective-viewer.js.map +3 -3
  37. package/dist/esm/plugin.d.ts +4 -1
  38. package/dist/esm/select-detail.d.ts +15 -0
  39. package/dist/esm/select-detail.js +2 -0
  40. package/dist/esm/select-detail.js.map +7 -0
  41. package/dist/esm/ts-rs/DerivedTableConfig.d.ts +35 -0
  42. package/dist/esm/ts-rs/PanelViewerConfig.d.ts +7 -6
  43. package/dist/esm/ts-rs/RestoreOptions.d.ts +3 -7
  44. package/dist/esm/ts-rs/TableRef.d.ts +9 -0
  45. package/dist/esm/ts-rs/ViewerConfig.d.ts +7 -6
  46. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -5
  47. package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
  48. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +9 -0
  49. package/dist/wasm/perspective-viewer.d.ts +115 -35
  50. package/dist/wasm/perspective-viewer.js +314 -190
  51. package/dist/wasm/perspective-viewer.wasm +0 -0
  52. package/dist/wasm/perspective-viewer.wasm.d.ts +21 -17
  53. package/package.json +31 -18
  54. package/src/css/column-selector.css +205 -50
  55. package/src/css/ui/containers/context-menu.css +12 -1
  56. package/src/css/ui/containers/dropdown-menu-items.css +29 -0
  57. package/src/css/ui/containers/scroll-panel.css +4 -1
  58. package/src/rust/agent/client/protocol.rs +0 -89
  59. package/src/rust/agent/markdown/mod.rs +0 -238
  60. package/src/rust/agent/preamble.md +1 -0
  61. package/src/rust/agent/tools.rs +2 -16
  62. package/src/rust/components/column_selector/active_column.rs +15 -5
  63. package/src/rust/components/column_selector/add_expression_button.rs +9 -26
  64. package/src/rust/components/column_selector/config_selector.rs +34 -6
  65. package/src/rust/components/column_selector/derived_control.rs +229 -0
  66. package/src/rust/components/column_selector/expr_edit_button.rs +3 -2
  67. package/src/rust/components/column_selector/filter_column.rs +0 -2
  68. package/src/rust/components/column_selector/inactive_column.rs +4 -5
  69. package/src/rust/components/column_selector/pivot_column.rs +21 -1
  70. package/src/rust/components/column_selector/sort_column.rs +4 -3
  71. package/src/rust/components/column_selector.rs +21 -1
  72. package/src/rust/components/column_settings_sidebar/save_settings.rs +5 -3
  73. package/src/rust/components/column_settings_sidebar/style_tab.rs +1 -0
  74. package/src/rust/components/column_settings_sidebar.rs +25 -19
  75. package/src/rust/components/debug_panel.rs +38 -29
  76. package/src/rust/components/dragdrop_list.rs +8 -9
  77. package/src/rust/components/main_panel/msg.rs +6 -4
  78. package/src/rust/components/main_panel/reconcile.rs +6 -1
  79. package/src/rust/components/main_panel/render.rs +70 -51
  80. package/src/rust/components/main_panel/update.rs +39 -1
  81. package/src/rust/components/main_panel.rs +97 -59
  82. package/src/rust/components/new_panel_menu.rs +69 -1
  83. package/src/rust/components/panel_menu.rs +63 -12
  84. package/src/rust/components/plugin_tab.rs +3 -2
  85. package/src/rust/components/render_warning.rs +2 -1
  86. package/src/rust/components/settings_panel.rs +4 -4
  87. package/src/rust/components/status_bar.rs +74 -24
  88. package/src/rust/components/status_indicator.rs +8 -1
  89. package/src/rust/components/viewer/filters.rs +13 -1
  90. package/src/rust/components/viewer/msg.rs +4 -0
  91. package/src/rust/components/viewer/panels.rs +41 -1
  92. package/src/rust/components/viewer/render.rs +1 -0
  93. package/src/rust/components/viewer/settings.rs +0 -22
  94. package/src/rust/components/viewer/snapshots.rs +2 -2
  95. package/src/rust/components/viewer/wiring.rs +14 -0
  96. package/src/rust/components/viewer.rs +45 -25
  97. package/src/rust/components/window_editor.rs +5 -4
  98. package/src/rust/config/column_config_schema.rs +38 -377
  99. package/src/rust/config/number_string_format.rs +0 -94
  100. package/src/rust/config/options.rs +3 -7
  101. package/src/rust/config/plugin_static_config.rs +0 -42
  102. package/src/rust/config/viewer_config.rs +47 -17
  103. package/src/rust/config/workspace_config.rs +158 -128
  104. package/src/rust/custom_elements/viewer.rs +187 -131
  105. package/src/rust/custom_events.rs +33 -18
  106. package/src/rust/derived.rs +266 -0
  107. package/src/rust/exprtk/tokenize.rs +0 -54
  108. package/src/rust/js/plugin.rs +1 -1
  109. package/src/rust/lib.rs +3 -0
  110. package/src/rust/presentation.rs +23 -4
  111. package/src/rust/queries/column_locator.rs +55 -48
  112. package/src/rust/queries/get_viewer_config.rs +1 -1
  113. package/src/rust/queries/plugin_column_styles.rs +22 -23
  114. package/src/rust/renderer/dispatch.rs +2 -0
  115. package/src/rust/renderer/plugin_config.rs +652 -487
  116. package/src/rust/renderer/props.rs +4 -0
  117. package/src/rust/renderer/registry.rs +2 -6
  118. package/src/rust/renderer/state.rs +205 -0
  119. package/src/rust/renderer.rs +201 -59
  120. package/src/rust/session/metadata.rs +30 -9
  121. package/src/rust/session/op_queue.rs +430 -0
  122. package/src/rust/session/panel_state.rs +327 -0
  123. package/src/rust/session/view_subscription.rs +42 -3
  124. package/src/rust/session.rs +900 -395
  125. package/src/rust/tasks/apply_global_filters.rs +49 -35
  126. package/src/rust/tasks/auto_pause.rs +22 -12
  127. package/src/rust/tasks/copy_export.rs +5 -0
  128. package/src/rust/tasks/create_panel.rs +34 -9
  129. package/src/rust/tasks/derive.rs +312 -0
  130. package/src/rust/tasks/mod.rs +6 -2
  131. package/src/rust/tasks/pipeline.rs +145 -89
  132. package/src/rust/tasks/reset_all.rs +31 -20
  133. package/src/rust/tasks/restore_derived.rs +200 -0
  134. package/src/rust/tasks/restore_panel.rs +153 -141
  135. package/src/rust/tasks/send_column_config.rs +56 -29
  136. package/src/rust/tasks/send_plugin_config.rs +52 -23
  137. package/src/rust/tasks/set_edit_mode.rs +33 -25
  138. package/src/rust/tasks/sync_update_panels.rs +39 -12
  139. package/src/rust/tasks/table_lifecycle.rs +70 -34
  140. package/src/rust/tasks/transactional_restore.rs +387 -0
  141. package/src/rust/tasks/update_theme.rs +45 -6
  142. package/src/rust/ui/containers/scroll_panel.rs +17 -10
  143. package/src/rust/ui/containers/split_panel.rs +0 -41
  144. package/src/rust/ui/context_menu.rs +157 -18
  145. package/src/rust/ui/font_loader.rs +23 -35
  146. package/src/rust/ui/form/mirrored_textarea.rs +0 -12
  147. package/src/rust/ui/form/multi_stop_gradient_selector.rs +0 -89
  148. package/src/rust/ui/form/palette_selector.rs +0 -51
  149. package/src/rust/ui/portal.rs +4 -10
  150. package/src/rust/utils/browser/mod.rs +2 -3
  151. package/src/{ts/perspective-viewer.inline.ts → rust/utils/browser/mouse.rs} +11 -10
  152. package/src/rust/utils/browser/request_animation_frame.rs +27 -8
  153. package/src/rust/utils/css.rs +0 -360
  154. package/src/rust/utils/local_fonts.rs +0 -36
  155. package/src/rust/utils/mod.rs +2 -3
  156. package/src/rust/utils/modal_position.rs +15 -21
  157. package/src/rust/utils/{browser/tests/mod.rs → plugin_host_state.rs} +31 -1
  158. package/src/rust/utils/pubsub.rs +0 -1
  159. package/src/rust/workspace.rs +187 -140
  160. package/src/svg/derived.svg +6 -0
  161. package/src/themes/icons.css +1 -0
  162. package/src/themes/intl/ar.css +10 -0
  163. package/src/themes/intl/de.css +10 -0
  164. package/src/themes/intl/es.css +10 -0
  165. package/src/themes/intl/fr.css +10 -0
  166. package/src/themes/intl/ja.css +10 -0
  167. package/src/themes/intl/pt.css +10 -0
  168. package/src/themes/intl/zh.css +10 -0
  169. package/src/themes/intl.css +10 -0
  170. package/src/ts/extensions.ts +3 -36
  171. package/src/ts/perspective-viewer.ts +1 -1
  172. package/src/ts/plugin.ts +4 -1
  173. package/src/{rust/utils/tests/request_animation_frame.rs → ts/select-detail.ts} +32 -26
  174. package/src/ts/ts-rs/DerivedTableConfig.ts +22 -0
  175. package/src/ts/ts-rs/PanelViewerConfig.ts +7 -6
  176. package/src/ts/ts-rs/RestoreOptions.ts +3 -7
  177. package/src/ts/ts-rs/TableRef.ts +9 -0
  178. package/src/ts/ts-rs/ViewerConfig.ts +7 -6
  179. package/src/ts/ts-rs/ViewerConfigUpdate.ts +7 -5
  180. package/src/ts/ts-rs/WorkspaceConfig.ts +7 -1
  181. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +7 -0
  182. package/dist/esm/perspective-viewer.inline.d.ts +0 -3
  183. package/dist/esm/perspective-viewer.inline.js +0 -21
  184. package/dist/esm/perspective-viewer.inline.js.map +0 -7
  185. package/src/rust/tasks/restore_and_render.rs +0 -107
  186. package/src/rust/utils/browser/tests/debounce.rs +0 -163
  187. package/src/rust/utils/tests/mod.rs +0 -14
  188. package/src/rust/utils/tests/pubsub.rs +0 -95
  189. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline0.js +0 -0
  190. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline1.js +0 -0
  191. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline2.js +0 -0
  192. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline3.js +0 -0
  193. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline4.js +0 -0
  194. /package/dist/wasm/snippets/{perspective-viewer-6813b568219c6763 → perspective-viewer-d0d525977a1acba2}/inline5.js +0 -0
@@ -14,43 +14,10 @@ import type { HTMLPerspectiveViewerPluginElement } from "./plugin";
14
14
  import type { PerspectiveViewerElement } from "../../dist/wasm/perspective-viewer.js";
15
15
  import type React from "react";
16
16
  import type { ViewerConfigUpdate } from "./ts-rs/ViewerConfigUpdate.js";
17
- import type {
18
- ViewWindow,
19
- ViewConfigUpdate,
20
- Filter,
21
- } from "@perspective-dev/client";
22
-
23
- export class PerspectiveSelectDetail {
24
- selected: boolean;
25
- row: Record<string, unknown>;
26
- column_names?: string[];
27
- removeConfigs: ViewConfigUpdate[];
28
- insertConfigs: ViewConfigUpdate[];
29
- panel?: string;
30
- constructor(
31
- selected: boolean,
32
- row: Record<string, unknown>,
33
- column_names: string[],
34
- removeConfigs: ViewConfigUpdate[],
35
- insertConfigs: ViewConfigUpdate[],
36
- panel?: string,
37
- ) {
38
- this.selected = selected;
39
- this.row = row;
40
- this.column_names = column_names;
41
- this.removeConfigs = removeConfigs;
42
- this.insertConfigs = insertConfigs;
43
- this.panel = panel;
44
- }
45
-
46
- get removeFilters(): Filter[] {
47
- return this.removeConfigs.flatMap((x) => x.filter ?? []);
48
- }
17
+ import type { ViewWindow, Filter } from "@perspective-dev/client";
18
+ import type { PerspectiveSelectDetail } from "./select-detail.ts";
49
19
 
50
- get insertFilters(): Filter[] {
51
- return this.insertConfigs.flatMap((x) => x.filter ?? []);
52
- }
53
- }
20
+ export { PerspectiveSelectDetail } from "./select-detail.ts";
54
21
 
55
22
  // DOM extensions
56
23
 
@@ -47,7 +47,7 @@ export {
47
47
  export type { NumberFormatConfig, DateFormatConfig } from "./column-format";
48
48
 
49
49
  export type * from "./extensions.ts";
50
- export { PerspectiveSelectDetail } from "./extensions.ts";
50
+ export { PerspectiveSelectDetail } from "./select-detail.ts";
51
51
  export type * from "./ts-rs/ViewerConfigUpdate.d.ts";
52
52
  export type * from "./ts-rs/ViewerConfig.d.ts";
53
53
  export type * from "./ts-rs/WorkspaceConfigUpdate.d.ts";
package/src/ts/plugin.ts CHANGED
@@ -97,6 +97,9 @@ export interface IPerspectiveViewerPlugin {
97
97
  * The per-column Style-tab schema: the controls the viewer renders
98
98
  * for one column, re-queried on every field edit so the field set
99
99
  * may depend on `current_value`.
100
+ *
101
+ * Must be a function of its arguments alone, never of what this element
102
+ * last drew or was last `restore`d with.
100
103
  */
101
104
  column_config_schema?(
102
105
  view_type: string,
@@ -104,7 +107,7 @@ export interface IPerspectiveViewerPlugin {
104
107
  column_name: string,
105
108
  current_value: Record<string, unknown> | null,
106
109
  viewer_config?: Record<string, unknown>,
107
- column_stats?: Record<string, unknown>,
110
+ plugin_config?: Record<string, unknown> | null,
108
111
  ): { fields: Array<Record<string, unknown> & { kind: string }> };
109
112
 
110
113
  /**
@@ -10,33 +10,39 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- use std::cell::*;
14
- use std::rc::*;
13
+ import type { ViewConfigUpdate, Filter } from "@perspective-dev/client";
15
14
 
16
- use wasm_bindgen_futures::spawn_local;
17
- use wasm_bindgen_test::*;
15
+ /**
16
+ * The `detail` of a `perspective-global-filter` event.
17
+ */
18
+ export class PerspectiveSelectDetail {
19
+ selected: boolean;
20
+ row: Record<string, unknown>;
21
+ column_names?: string[];
22
+ removeConfigs: ViewConfigUpdate[];
23
+ insertConfigs: ViewConfigUpdate[];
24
+ panel?: string;
25
+ constructor(
26
+ selected: boolean,
27
+ row: Record<string, unknown>,
28
+ column_names: string[],
29
+ removeConfigs: ViewConfigUpdate[],
30
+ insertConfigs: ViewConfigUpdate[],
31
+ panel?: string,
32
+ ) {
33
+ this.selected = selected;
34
+ this.row = row;
35
+ this.column_names = column_names;
36
+ this.removeConfigs = removeConfigs;
37
+ this.insertConfigs = insertConfigs;
38
+ this.panel = panel;
39
+ }
18
40
 
19
- use crate::utils::*;
41
+ get removeFilters(): Filter[] {
42
+ return this.removeConfigs.flatMap((x) => x.filter ?? []);
43
+ }
20
44
 
21
- #[wasm_bindgen_test]
22
- async fn test_request_animation_frame_async() {
23
- // Merely test that this Promise resolves at all ..
24
- request_animation_frame().await;
25
- }
26
-
27
- #[wasm_bindgen_test]
28
- async fn test_async_in_correct_order() {
29
- let cell = Rc::new(RefCell::new(vec![]));
30
- spawn_local({
31
- clone!(cell);
32
- async move {
33
- request_animation_frame().await;
34
- cell.borrow_mut().push("1");
35
- }
36
- });
37
-
38
- request_animation_frame().await;
39
- cell.borrow_mut().push("2");
40
- request_animation_frame().await;
41
- assert_eq!(vec!["2", "1"], *cell.borrow());
45
+ get insertFilters(): Filter[] {
46
+ return this.insertConfigs.flatMap((x) => x.filter ?? []);
47
+ }
42
48
  }
@@ -0,0 +1,22 @@
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 { SplitRollupMode } from "./SplitRollupMode.js";
9
+ import type { Windows } from "./Windows.js";
10
+
11
+ /**
12
+ * A derived `Table`'s definition: the `Table` its source `View` reads, and
13
+ * the config of that `View`; generic over the `table` slot, which is a name
14
+ * in the workspace `derived_tables` map and a recursive [`TableRef`] when
15
+ * inlined in a single-panel config.
16
+ */
17
+ export type DerivedTableConfig<T = string> = {
18
+ /**
19
+ * The `Table` this derivation reads, which may itself be another
20
+ * derived `Table`.
21
+ */
22
+ table: T, group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, group_rollup_mode: GroupRollupMode, split_rollup_mode: SplitRollupMode, filter_op?: FilterReducer, expressions: Expressions, windows?: Windows, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
@@ -6,6 +6,7 @@ import type { FilterReducer } from "./FilterReducer.js";
6
6
  import type { GroupRollupMode } from "./GroupRollupMode.js";
7
7
  import type { Sort } from "./Sort.js";
8
8
  import type { SplitRollupMode } from "./SplitRollupMode.js";
9
+ import type { TableRef } from "./TableRef.js";
9
10
  import type { Windows } from "./Windows.js";
10
11
  import type { JsonValue } from "./serde_json/JsonValue.js";
11
12
 
@@ -14,7 +15,7 @@ import type { JsonValue } from "./serde_json/JsonValue.js";
14
15
  * element-level `settings` flag. This is the `panels` entry type of the
15
16
  * workspace config format.
16
17
  */
17
- export type PanelViewerConfig<V = string> = {
18
+ export type PanelViewerConfig<V = string, T = TableRef> = {
18
19
  /**
19
20
  * The `@perspective-dev/viewer` version that wrote this config,
20
21
  * stamped on save and used to migrate older tokens. Callers do not
@@ -44,12 +45,12 @@ plugin: string,
44
45
  */
45
46
  plugin_config: { [key in string]?: JsonValue },
46
47
  /**
47
- * Name of the `Table` this panel renders, as hosted on the panel's
48
- * `Client`. Every placed panel has a table binding (creation
49
- * requires one by type — [`ViewerConfigInitial`]), so the saved
50
- * config carries it unconditionally.
48
+ * The `Table` this panel renders: its hosted name in a
49
+ * [`WorkspaceConfig`] `panels` entry (`T = String`), and a
50
+ * [`TableRef`] — a name, or a recursively inlined derived-table
51
+ * definition — in the single-panel `save()` format.
51
52
  */
52
- table: string,
53
+ table: T,
53
54
  /**
54
55
  * Selected theme NAME (e.g. `"Pro Dark"`) — not a CSS value. Valid
55
56
  * names are the Perspective themes loaded on the page, which
@@ -9,13 +9,9 @@ export type RestoreOptions = {
9
9
  */
10
10
  panel?: string,
11
11
  /**
12
- * When `true`, a failed restore only REJECTS the returned `Promise` —
13
- * the error is not committed to the viewer's visible error state, and
14
- * the session remains usable for subsequent calls. For programmatic
15
- * callers (e.g. the LLM agent's `set_view_config` tool) for whom a
16
- * failed config patch is feedback rather than a user-facing fault.
17
- * The config may be partially applied on failure; restore a
18
- * known-good config to recover exactly.
12
+ * When `true`, a config that was applied and then failed to render only
13
+ * rejects the returned `Promise`, without raising the panel's visible
14
+ * error state.
19
15
  */
20
16
  suppress_errors?: boolean,
21
17
  /**
@@ -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 { DerivedTableConfig } from "./DerivedTableConfig.js";
3
+
4
+ /**
5
+ * What may occupy a `table` position in a single-panel config: a hosted
6
+ * `Table`'s name, or an inline derived-table definition recursing through
7
+ * its own `table` field until a concrete name.
8
+ */
9
+ export type TableRef = string | (Omit<DerivedTableConfig, "table"> & { table: TableRef });
@@ -6,6 +6,7 @@ import type { FilterReducer } from "./FilterReducer.js";
6
6
  import type { GroupRollupMode } from "./GroupRollupMode.js";
7
7
  import type { Sort } from "./Sort.js";
8
8
  import type { SplitRollupMode } from "./SplitRollupMode.js";
9
+ import type { TableRef } from "./TableRef.js";
9
10
  import type { Windows } from "./Windows.js";
10
11
  import type { JsonValue } from "./serde_json/JsonValue.js";
11
12
 
@@ -17,7 +18,7 @@ import type { JsonValue } from "./serde_json/JsonValue.js";
17
18
  * state there, carried by the top-level `active` field instead), while the
18
19
  * single-panel format flattens back to the legacy shape.
19
20
  */
20
- export type ViewerConfig<V = string> = { settings: boolean,
21
+ export type ViewerConfig<V = string, T = TableRef> = { settings: boolean,
21
22
  /**
22
23
  * The `@perspective-dev/viewer` version that wrote this config,
23
24
  * stamped on save and used to migrate older tokens. Callers do not
@@ -47,12 +48,12 @@ plugin: string,
47
48
  */
48
49
  plugin_config: { [key in string]?: JsonValue },
49
50
  /**
50
- * Name of the `Table` this panel renders, as hosted on the panel's
51
- * `Client`. Every placed panel has a table binding (creation
52
- * requires one by type — [`ViewerConfigInitial`]), so the saved
53
- * config carries it unconditionally.
51
+ * The `Table` this panel renders: its hosted name in a
52
+ * [`WorkspaceConfig`] `panels` entry (`T = String`), and a
53
+ * [`TableRef`] — a name, or a recursively inlined derived-table
54
+ * definition — in the single-panel `save()` format.
54
55
  */
55
- table: string,
56
+ table: T,
56
57
  /**
57
58
  * Selected theme NAME (e.g. `"Pro Dark"`) — not a CSS value. Valid
58
59
  * names are the Perspective themes loaded on the page, which
@@ -7,6 +7,7 @@ import type { GroupRollupMode } from "./GroupRollupMode.js";
7
7
  import type { OptionalUpdate } from "./OptionalUpdate.js";
8
8
  import type { Sort } from "./Sort.js";
9
9
  import type { SplitRollupMode } from "./SplitRollupMode.js";
10
+ import type { TableRef } from "./TableRef.js";
10
11
  import type { Windows } from "./Windows.js";
11
12
  import type { JsonValue } from "./serde_json/JsonValue.js";
12
13
 
@@ -33,12 +34,13 @@ plugin?: OptionalUpdate<string>,
33
34
  */
34
35
  title?: OptionalUpdate<string>,
35
36
  /**
36
- * Name of the `Table` to render, as hosted on this panel's
37
- * `Client`. Rebinding an existing panel to another table keeps the
38
- * rest of the config, so column names that do not exist in the new
39
- * table will fail validation.
37
+ * The `Table` to render: a name as hosted on this panel's `Client`,
38
+ * or an inline derived-table definition to materialize (reusing a
39
+ * structurally identical derived `Table` when one exists). Rebinding
40
+ * an existing panel keeps the rest of the config, so column names
41
+ * that do not exist in the new table will fail validation.
40
42
  */
41
- table?: OptionalUpdate<string>,
43
+ table?: OptionalUpdate<TableRef>,
42
44
  /**
43
45
  * Theme NAME (e.g. `"Pro Dark"`) — not a CSS value. Valid names are
44
46
  * the Perspective themes loaded on the page, re-scanned by
@@ -1,4 +1,5 @@
1
1
  // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { DerivedTableConfig } from "./DerivedTableConfig.js";
2
3
  import type { Filter } from "./Filter.js";
3
4
  import type { Layout } from "./Layout.js";
4
5
  import type { PanelViewerConfig } from "./PanelViewerConfig.js";
@@ -20,7 +21,12 @@ export type WorkspaceConfig = { version: string, active?: string, layout: Layout
20
21
  * iterates in a per-instance random order, which made consecutive
21
22
  * `save()` outputs byte-unstable.
22
23
  */
23
- panels: { [key in string]?: PanelViewerConfig<string> },
24
+ panels: { [key in string]?: PanelViewerConfig<string, string> },
25
+ /**
26
+ * Named derived `Table`s, each a `View` of its `parent` promoted to a
27
+ * `Table`. A `BTreeMap` for the same determinism reason as `panels`.
28
+ */
29
+ derived_tables?: { [key in string]?: DerivedTableConfig<string> },
24
30
  /**
25
31
  * The element-level global (master/detail cross-) filters. A transient
26
32
  * overlay on every detail panel's view — persisted here, never in a
@@ -1,4 +1,5 @@
1
1
  // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ import type { DerivedTableConfig } from "./DerivedTableConfig.js";
2
3
  import type { Filter } from "./Filter.js";
3
4
  import type { Layout } from "./Layout.js";
4
5
  import type { OptionalUpdate } from "./OptionalUpdate.js";
@@ -26,6 +27,12 @@ layout?: Layout,
26
27
  * existing panels.
27
28
  */
28
29
  panels?: { [key in string]?: ViewerConfigInitial },
30
+ /**
31
+ * The complete replacement set of derived `Table`s, in any order (they
32
+ * are built parent-first); absent keeps the current ones, `{}` deletes
33
+ * them all.
34
+ */
35
+ derived_tables?: { [key in string]?: DerivedTableConfig<string> },
29
36
  /**
30
37
  * The element-level cross-filter set applied to every detail panel as
31
38
  * one unattributed bucket, replacing the current set; `null` clears it.
@@ -1,3 +0,0 @@
1
- import perspective_viewer from "./perspective-viewer.ts";
2
- export * from "./perspective-viewer.ts";
3
- export default perspective_viewer;