@perspective-dev/viewer 5.5.0 → 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 (201) 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/ExportMethod.d.ts +1 -1
  43. package/dist/esm/ts-rs/PanelViewerConfig.d.ts +7 -6
  44. package/dist/esm/ts-rs/RestoreOptions.d.ts +3 -7
  45. package/dist/esm/ts-rs/TableRef.d.ts +9 -0
  46. package/dist/esm/ts-rs/ViewerConfig.d.ts +7 -6
  47. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -5
  48. package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
  49. package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +9 -0
  50. package/dist/wasm/perspective-viewer.d.ts +126 -35
  51. package/dist/wasm/perspective-viewer.js +320 -185
  52. package/dist/wasm/perspective-viewer.wasm +0 -0
  53. package/dist/wasm/perspective-viewer.wasm.d.ts +21 -17
  54. package/package.json +33 -20
  55. package/src/css/column-selector.css +205 -50
  56. package/src/css/ui/containers/context-menu.css +12 -1
  57. package/src/css/ui/containers/dropdown-menu-items.css +29 -0
  58. package/src/css/ui/containers/scroll-panel.css +4 -1
  59. package/src/rust/agent/client/protocol.rs +0 -89
  60. package/src/rust/agent/markdown/mod.rs +0 -238
  61. package/src/rust/agent/preamble.md +1 -0
  62. package/src/rust/agent/tools.rs +2 -16
  63. package/src/rust/components/column_selector/active_column.rs +15 -5
  64. package/src/rust/components/column_selector/add_expression_button.rs +9 -26
  65. package/src/rust/components/column_selector/config_selector.rs +34 -6
  66. package/src/rust/components/column_selector/derived_control.rs +229 -0
  67. package/src/rust/components/column_selector/expr_edit_button.rs +3 -2
  68. package/src/rust/components/column_selector/filter_column.rs +0 -2
  69. package/src/rust/components/column_selector/inactive_column.rs +4 -5
  70. package/src/rust/components/column_selector/pivot_column.rs +21 -1
  71. package/src/rust/components/column_selector/sort_column.rs +4 -3
  72. package/src/rust/components/column_selector.rs +21 -1
  73. package/src/rust/components/column_settings_sidebar/save_settings.rs +5 -3
  74. package/src/rust/components/column_settings_sidebar/style_tab.rs +1 -0
  75. package/src/rust/components/column_settings_sidebar.rs +25 -19
  76. package/src/rust/components/debug_panel.rs +38 -29
  77. package/src/rust/components/dragdrop_list.rs +8 -9
  78. package/src/rust/components/export_dropdown.rs +6 -0
  79. package/src/rust/components/main_panel/msg.rs +6 -4
  80. package/src/rust/components/main_panel/reconcile.rs +6 -1
  81. package/src/rust/components/main_panel/render.rs +70 -51
  82. package/src/rust/components/main_panel/update.rs +39 -1
  83. package/src/rust/components/main_panel.rs +97 -59
  84. package/src/rust/components/new_panel_menu.rs +69 -1
  85. package/src/rust/components/panel_menu.rs +63 -12
  86. package/src/rust/components/plugin_tab.rs +3 -2
  87. package/src/rust/components/render_warning.rs +2 -1
  88. package/src/rust/components/settings_panel.rs +4 -4
  89. package/src/rust/components/status_bar.rs +80 -21
  90. package/src/rust/components/status_indicator.rs +8 -1
  91. package/src/rust/components/viewer/filters.rs +15 -3
  92. package/src/rust/components/viewer/msg.rs +8 -0
  93. package/src/rust/components/viewer/panels.rs +44 -4
  94. package/src/rust/components/viewer/render.rs +1 -0
  95. package/src/rust/components/viewer/settings.rs +0 -22
  96. package/src/rust/components/viewer/snapshots.rs +2 -2
  97. package/src/rust/components/viewer/wiring.rs +18 -1
  98. package/src/rust/components/viewer.rs +47 -27
  99. package/src/rust/components/window_editor.rs +5 -4
  100. package/src/rust/config/column_config_schema.rs +38 -377
  101. package/src/rust/config/export_method.rs +24 -0
  102. package/src/rust/config/number_string_format.rs +0 -94
  103. package/src/rust/config/options.rs +3 -7
  104. package/src/rust/config/plugin_static_config.rs +0 -42
  105. package/src/rust/config/viewer_config.rs +47 -17
  106. package/src/rust/config/workspace_config.rs +158 -128
  107. package/src/rust/custom_elements/viewer.rs +189 -129
  108. package/src/rust/custom_events.rs +33 -18
  109. package/src/rust/derived.rs +266 -0
  110. package/src/rust/exprtk/tokenize.rs +0 -54
  111. package/src/rust/js/plugin.rs +1 -1
  112. package/src/rust/lib.rs +3 -0
  113. package/src/rust/presentation.rs +23 -4
  114. package/src/rust/queries/column_locator.rs +55 -48
  115. package/src/rust/queries/get_viewer_config.rs +1 -1
  116. package/src/rust/queries/plugin_column_styles.rs +22 -23
  117. package/src/rust/renderer/dispatch.rs +2 -0
  118. package/src/rust/renderer/plugin_config.rs +652 -487
  119. package/src/rust/renderer/props.rs +4 -0
  120. package/src/rust/renderer/registry.rs +2 -6
  121. package/src/rust/renderer/state.rs +205 -0
  122. package/src/rust/renderer.rs +201 -59
  123. package/src/rust/session/metadata.rs +35 -19
  124. package/src/rust/session/op_queue.rs +430 -0
  125. package/src/rust/session/panel_state.rs +327 -0
  126. package/src/rust/session/view_subscription.rs +42 -3
  127. package/src/rust/session.rs +931 -419
  128. package/src/rust/tasks/apply_global_filters.rs +49 -35
  129. package/src/rust/tasks/auto_pause.rs +22 -12
  130. package/src/rust/tasks/copy_export.rs +72 -0
  131. package/src/rust/tasks/create_panel.rs +46 -21
  132. package/src/rust/tasks/derive.rs +312 -0
  133. package/src/rust/tasks/mod.rs +6 -2
  134. package/src/rust/tasks/pipeline.rs +152 -89
  135. package/src/rust/tasks/reset_all.rs +31 -20
  136. package/src/rust/tasks/restore_derived.rs +200 -0
  137. package/src/rust/tasks/restore_panel.rs +153 -141
  138. package/src/rust/tasks/send_column_config.rs +56 -29
  139. package/src/rust/tasks/send_plugin_config.rs +52 -23
  140. package/src/rust/tasks/set_edit_mode.rs +33 -25
  141. package/src/rust/tasks/sync_update_panels.rs +40 -13
  142. package/src/rust/tasks/table_lifecycle.rs +70 -34
  143. package/src/rust/tasks/transactional_restore.rs +387 -0
  144. package/src/rust/tasks/update_theme.rs +45 -6
  145. package/src/rust/ui/containers/scroll_panel.rs +17 -10
  146. package/src/rust/ui/containers/split_panel.rs +0 -41
  147. package/src/rust/ui/context_menu.rs +157 -18
  148. package/src/rust/ui/font_loader.rs +23 -35
  149. package/src/rust/ui/form/mirrored_textarea.rs +0 -12
  150. package/src/rust/ui/form/multi_stop_gradient_selector.rs +0 -89
  151. package/src/rust/ui/form/palette_selector.rs +0 -51
  152. package/src/rust/ui/portal.rs +4 -10
  153. package/src/rust/utils/browser/mod.rs +2 -3
  154. package/src/{ts/perspective-viewer.inline.ts → rust/utils/browser/mouse.rs} +11 -10
  155. package/src/rust/utils/browser/request_animation_frame.rs +27 -8
  156. package/src/rust/utils/css.rs +0 -360
  157. package/src/rust/utils/{tests/mod.rs → in_flight.rs} +62 -2
  158. package/src/rust/utils/local_fonts.rs +0 -36
  159. package/src/rust/utils/mod.rs +4 -3
  160. package/src/rust/utils/modal_position.rs +15 -21
  161. package/src/rust/utils/pending_effects.rs +6 -30
  162. package/src/rust/utils/{browser/tests/mod.rs → plugin_host_state.rs} +31 -1
  163. package/src/rust/utils/pubsub.rs +0 -1
  164. package/src/rust/workspace.rs +187 -140
  165. package/src/svg/derived.svg +6 -0
  166. package/src/themes/icons.css +1 -0
  167. package/src/themes/intl/ar.css +10 -0
  168. package/src/themes/intl/de.css +10 -0
  169. package/src/themes/intl/es.css +10 -0
  170. package/src/themes/intl/fr.css +10 -0
  171. package/src/themes/intl/ja.css +10 -0
  172. package/src/themes/intl/pt.css +10 -0
  173. package/src/themes/intl/zh.css +10 -0
  174. package/src/themes/intl.css +10 -0
  175. package/src/themes/monokai.css +1 -1
  176. package/src/themes/vaporwave.css +1 -1
  177. package/src/ts/extensions.ts +3 -36
  178. package/src/ts/perspective-viewer.ts +1 -1
  179. package/src/ts/plugin.ts +4 -1
  180. package/src/{rust/utils/tests/request_animation_frame.rs → ts/select-detail.ts} +32 -26
  181. package/src/ts/ts-rs/DerivedTableConfig.ts +22 -0
  182. package/src/ts/ts-rs/ExportMethod.ts +1 -1
  183. package/src/ts/ts-rs/PanelViewerConfig.ts +7 -6
  184. package/src/ts/ts-rs/RestoreOptions.ts +3 -7
  185. package/src/ts/ts-rs/TableRef.ts +9 -0
  186. package/src/ts/ts-rs/ViewerConfig.ts +7 -6
  187. package/src/ts/ts-rs/ViewerConfigUpdate.ts +7 -5
  188. package/src/ts/ts-rs/WorkspaceConfig.ts +7 -1
  189. package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +7 -0
  190. package/dist/esm/perspective-viewer.inline.d.ts +0 -3
  191. package/dist/esm/perspective-viewer.inline.js +0 -21
  192. package/dist/esm/perspective-viewer.inline.js.map +0 -7
  193. package/src/rust/tasks/restore_and_render.rs +0 -107
  194. package/src/rust/utils/browser/tests/debounce.rs +0 -163
  195. package/src/rust/utils/tests/pubsub.rs +0 -95
  196. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline0.js +0 -0
  197. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline1.js +0 -0
  198. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline2.js +0 -0
  199. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline3.js +0 -0
  200. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline4.js +0 -0
  201. /package/dist/wasm/snippets/{perspective-viewer-ea71a3990cad35d7 → perspective-viewer-d0d525977a1acba2}/inline5.js +0 -0
@@ -75,6 +75,8 @@ perspective-viewer {
75
75
 
76
76
  /* Column Settings */
77
77
  --psp-label--color--content: "色";
78
+ --psp-label--palette--content: "パレット";
79
+ --psp-label--gradient--content: "グラデーション";
78
80
  --psp-label--timezone--content: "タイムゾーン";
79
81
  --psp-label--date-style--content: "日付スタイル";
80
82
  --psp-label--time-style--content: "時間スタイル";
@@ -204,4 +206,12 @@ perspective-viewer {
204
206
  --psp-label--group-column--content: "列";
205
207
  --psp-label--group-format--content: "書式";
206
208
  --psp-label--column-size-override--content: "列の幅";
209
+
210
+ /* Derived tables */
211
+ --psp-label--derive-table--content: "テーブルを派生";
212
+ --psp-label--derive-table-title--content: "このビューから新しいテーブルを派生します";
213
+ --psp-label--derived-snapshot--content: "スナップショット";
214
+ --psp-label--derived-snapshot-title--content: "このデータソースはストリーミングしません - このテーブルのデータは派生した時点で固定されます。";
215
+ --psp-label--derived-release-title--content: "親テーブルに戻る";
216
+ --psp-label--derived-release-delete-title--content: "親テーブルに戻る - Shiftクリックで削除";
207
217
  }
@@ -74,6 +74,8 @@ perspective-viewer {
74
74
 
75
75
  /* Column Settings */
76
76
  --psp-label--color--content: "Cor";
77
+ --psp-label--palette--content: "Paleta";
78
+ --psp-label--gradient--content: "Gradiente";
77
79
  --psp-label--timezone--content: "Fuso horário";
78
80
  --psp-label--date-style--content: "Estilo de data";
79
81
  --psp-label--time-style--content: "Estilo de tempo";
@@ -204,4 +206,12 @@ perspective-viewer {
204
206
  --psp-label--group-column--content: "Coluna";
205
207
  --psp-label--group-format--content: "Formato";
206
208
  --psp-label--column-size-override--content: "Largura da coluna";
209
+
210
+ /* Derived tables */
211
+ --psp-label--derive-table--content: "Derivar tabela";
212
+ --psp-label--derive-table-title--content: "Derivar uma nova tabela a partir desta visualização";
213
+ --psp-label--derived-snapshot--content: "instantâneo";
214
+ --psp-label--derived-snapshot-title--content: "Esta fonte de dados não transmite em contínuo - os dados desta tabela ficam fixados no momento da derivação.";
215
+ --psp-label--derived-release-title--content: "Voltar à tabela pai";
216
+ --psp-label--derived-release-delete-title--content: "Voltar à tabela pai - shift+clique para excluí-la";
207
217
  }
@@ -74,6 +74,8 @@ perspective-viewer {
74
74
 
75
75
  /* Column Settings */
76
76
  --psp-label--color--content: "颜色";
77
+ --psp-label--palette--content: "调色板";
78
+ --psp-label--gradient--content: "渐变";
77
79
  --psp-label--timezone--content: "时区";
78
80
  --psp-label--date-style--content: "日期样式";
79
81
  --psp-label--time-style--content: "时间风格";
@@ -204,4 +206,12 @@ perspective-viewer {
204
206
  --psp-label--group-column--content: "列";
205
207
  --psp-label--group-format--content: "格式";
206
208
  --psp-label--column-size-override--content: "列宽";
209
+
210
+ /* Derived tables */
211
+ --psp-label--derive-table--content: "派生表";
212
+ --psp-label--derive-table-title--content: "从此视图派生新表";
213
+ --psp-label--derived-snapshot--content: "快照";
214
+ --psp-label--derived-snapshot-title--content: "此数据源不支持流式更新 - 该表的数据固定在派生时的状态。";
215
+ --psp-label--derived-release-title--content: "返回父表";
216
+ --psp-label--derived-release-delete-title--content: "返回父表 - Shift+点击可将其删除";
207
217
  }
@@ -74,6 +74,8 @@ perspective-viewer {
74
74
 
75
75
  /* Column Settings */
76
76
  --psp-label--color--content: "Color";
77
+ --psp-label--palette--content: "Palette";
78
+ --psp-label--gradient--content: "Gradient";
77
79
  --psp-label--timezone--content: "Timezone";
78
80
  --psp-label--date-style--content: "Date Style";
79
81
  --psp-label--time-style--content: "Time Style";
@@ -206,4 +208,12 @@ perspective-viewer {
206
208
  --psp-label--legend-opacity--content: "Opacity";
207
209
  --psp-label--tooltip-max-column-px--content: "Max column width";
208
210
  --psp-label--tooltip-opacity--content: "Opacity";
211
+
212
+ /* Derived tables */
213
+ --psp-label--derive-table--content: "Derive table";
214
+ --psp-label--derive-table-title--content: "Derive a new table from this view";
215
+ --psp-label--derived-snapshot--content: "snapshot";
216
+ --psp-label--derived-snapshot-title--content: "This data source does not stream - this table's data is fixed at the point it was derived.";
217
+ --psp-label--derived-release-title--content: "Back to the parent table";
218
+ --psp-label--derived-release-delete-title--content: "Back to the parent table - shift-click to delete this one";
209
219
  }
@@ -131,7 +131,7 @@ perspective-viewer [theme="Monokai"] {
131
131
  --psp-datagrid--border-color: #444444;
132
132
 
133
133
  /* FIXME: broken in shadow DOM */
134
- regular-table table tbody th:empty {
134
+ regular-table table tbody th.psp-tree-spacer {
135
135
  background: linear-gradient(
136
136
  to right,
137
137
  transparent 9px,
@@ -130,7 +130,7 @@ perspective-viewer [theme="Vaporwave"] {
130
130
  --psp-datagrid--hover--border-color: var(--pp-color-1) !important;
131
131
 
132
132
  /* FIXME: broken in shadow DOM */
133
- regular-table table tbody th:empty {
133
+ regular-table table tbody th.psp-tree-spacer {
134
134
  background: linear-gradient(
135
135
  to right,
136
136
  transparent 9px,
@@ -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, };
@@ -1,3 +1,3 @@
1
1
  // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
2
 
3
- export type ExportMethod = "csv" | "csv-all" | "csv-selected" | "json" | "json-all" | "json-selected" | "ndjson" | "ndjson-all" | "ndjson-selected" | "html" | "plugin" | "arrow" | "arrow-selected" | "arrow-all" | "json-config";
3
+ export type ExportMethod = "csv" | "csv-all" | "csv-selected" | "json" | "json-all" | "json-selected" | "ndjson" | "ndjson-all" | "ndjson-selected" | "html" | "plugin" | "arrow" | "arrow-selected" | "arrow-all" | "arrow-lz4" | "arrow-lz4-selected" | "arrow-lz4-all" | "arrow-zstd" | "arrow-zstd-selected" | "arrow-zstd-all" | "json-config";
@@ -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;