@trebco/treb 32.14.0 → 36.1.2

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 (266) hide show
  1. package/api-generator/api-generator-types.ts +3 -0
  2. package/api-generator/api-generator.ts +15 -1
  3. package/bun.lock +145 -99
  4. package/dist/chunk-43DLP2OX.mjs +11 -0
  5. package/dist/chunk-4CKS56PE.mjs +11 -0
  6. package/dist/chunk-75PARUQE.mjs +11 -0
  7. package/dist/chunk-7QD63AZS.mjs +24601 -0
  8. package/dist/chunk-A55ARVRD.mjs +11 -0
  9. package/dist/chunk-DESAKYW4.mjs +11 -0
  10. package/dist/chunk-EQ2R5W6P.mjs +24565 -0
  11. package/dist/chunk-IYJU2J6D.mjs +24601 -0
  12. package/dist/chunk-KSJFPGXT.mjs +11 -0
  13. package/dist/chunk-ORQFKLXM.mjs +24601 -0
  14. package/dist/chunk-SFDNNDHY.mjs +11 -0
  15. package/dist/chunk-T47DX5MI.mjs +11 -0
  16. package/dist/chunk-T6ILBVEX.mjs +11 -0
  17. package/dist/chunk-TPRCDYYG.mjs +11 -0
  18. package/dist/chunk-YAHNOOHO.mjs +11 -0
  19. package/dist/treb-export-worker.mjs +9 -2
  20. package/dist/treb-spreadsheet.mjs +7 -19
  21. package/dist/treb.d.ts +20 -4
  22. package/esbuild-composite.mjs +18 -6
  23. package/esbuild-utils.mjs +62 -3
  24. package/i18n/languages/treb-i18n-da.mjs +1 -1
  25. package/i18n/languages/treb-i18n-de.mjs +1 -1
  26. package/i18n/languages/treb-i18n-es.mjs +1 -1
  27. package/i18n/languages/treb-i18n-fr.mjs +1 -1
  28. package/i18n/languages/treb-i18n-it.mjs +1 -1
  29. package/i18n/languages/treb-i18n-nl.mjs +1 -1
  30. package/i18n/languages/treb-i18n-no.mjs +1 -1
  31. package/i18n/languages/treb-i18n-pl.mjs +1 -1
  32. package/i18n/languages/treb-i18n-pt.mjs +1 -1
  33. package/i18n/languages/treb-i18n-sv.mjs +1 -1
  34. package/ooxml-types/README.md +141 -0
  35. package/ooxml-types/package.json +5 -0
  36. package/ooxml-types/src/types/drawingml/chart.ts +327 -0
  37. package/ooxml-types/src/types/drawingml/index.ts +63 -0
  38. package/ooxml-types/src/types/drawingml/spreadsheetDrawing.ts +105 -0
  39. package/ooxml-types/src/types/drawingml/theme.ts +104 -0
  40. package/ooxml-types/src/types/index.ts +3 -0
  41. package/ooxml-types/src/types/package/contentTypes.ts +49 -0
  42. package/ooxml-types/src/types/package/docProps.ts +46 -0
  43. package/ooxml-types/src/types/package/index.ts +17 -0
  44. package/ooxml-types/src/types/package/relationships.ts +37 -0
  45. package/ooxml-types/src/types/spreadsheetml/columns.ts +20 -0
  46. package/ooxml-types/src/types/spreadsheetml/comments.ts +30 -0
  47. package/ooxml-types/src/types/spreadsheetml/dataFeatures.ts +261 -0
  48. package/ooxml-types/src/types/spreadsheetml/enums.ts +175 -0
  49. package/ooxml-types/src/types/spreadsheetml/index.ts +186 -0
  50. package/ooxml-types/src/types/spreadsheetml/metadata.ts +90 -0
  51. package/ooxml-types/src/types/spreadsheetml/misc.ts +35 -0
  52. package/ooxml-types/src/types/spreadsheetml/pageLayout.ts +83 -0
  53. package/ooxml-types/src/types/spreadsheetml/sharedStrings.ts +33 -0
  54. package/ooxml-types/src/types/spreadsheetml/sheetData.ts +70 -0
  55. package/ooxml-types/src/types/spreadsheetml/sheetProperties.ts +86 -0
  56. package/ooxml-types/src/types/spreadsheetml/sheetViews.ts +51 -0
  57. package/ooxml-types/src/types/spreadsheetml/sparkline.ts +46 -0
  58. package/ooxml-types/src/types/spreadsheetml/styles.ts +274 -0
  59. package/ooxml-types/src/types/spreadsheetml/table.ts +106 -0
  60. package/ooxml-types/src/types/spreadsheetml/util.ts +15 -0
  61. package/ooxml-types/src/types/spreadsheetml/workbook.ts +165 -0
  62. package/ooxml-types/src/types/spreadsheetml/worksheet.ts +60 -0
  63. package/package.json +13 -11
  64. package/treb-base-types/src/api_types.ts +1 -1
  65. package/treb-base-types/src/area-utils.ts +1 -1
  66. package/treb-base-types/src/area.ts +1 -1
  67. package/treb-base-types/src/basic_types.ts +1 -1
  68. package/treb-base-types/src/cell.ts +1 -1
  69. package/treb-base-types/src/cells.ts +1 -1
  70. package/treb-base-types/src/color.ts +1 -1
  71. package/treb-base-types/src/dom-utilities.ts +1 -1
  72. package/treb-base-types/src/evaluate-options.ts +1 -1
  73. package/treb-base-types/src/font-stack.ts +1 -1
  74. package/treb-base-types/src/gradient.ts +1 -1
  75. package/treb-base-types/src/import.ts +1 -1
  76. package/treb-base-types/src/index-standalone.ts +1 -1
  77. package/treb-base-types/src/index.ts +2 -1
  78. package/treb-base-types/src/layout.ts +1 -1
  79. package/treb-base-types/src/localization.ts +1 -1
  80. package/treb-base-types/src/rectangle.ts +1 -1
  81. package/treb-base-types/src/render_text.ts +7 -1
  82. package/treb-base-types/src/style.ts +1 -1
  83. package/treb-base-types/src/table.ts +1 -1
  84. package/treb-base-types/src/text_part.ts +1 -1
  85. package/treb-base-types/src/theme.ts +1 -1
  86. package/treb-base-types/src/union.ts +4 -1
  87. package/treb-base-types/src/value-type.ts +1 -1
  88. package/treb-base-types/src/worker-proxy.ts +294 -0
  89. package/treb-base-types/style/resizable.css +1 -1
  90. package/treb-calculator/src/calculator.ts +133 -14
  91. package/treb-calculator/src/complex-math.ts +1 -1
  92. package/treb-calculator/src/dag/array-vertex.ts +1 -1
  93. package/treb-calculator/src/dag/calculation_leaf_vertex.ts +1 -1
  94. package/treb-calculator/src/dag/graph.ts +1 -1
  95. package/treb-calculator/src/dag/spreadsheet_vertex.ts +1 -1
  96. package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +1 -1
  97. package/treb-calculator/src/dag/state_leaf_vertex.ts +1 -1
  98. package/treb-calculator/src/dag/vertex.ts +1 -1
  99. package/treb-calculator/src/descriptors.ts +9 -1
  100. package/treb-calculator/src/expression-calculator.ts +1 -1
  101. package/treb-calculator/src/function-error.ts +1 -1
  102. package/treb-calculator/src/function-library.ts +1 -1
  103. package/treb-calculator/src/functions/base-functions.ts +8 -4
  104. package/treb-calculator/src/functions/beta.ts +1 -1
  105. package/treb-calculator/src/functions/checkbox.ts +1 -1
  106. package/treb-calculator/src/functions/complex-functions.ts +1 -1
  107. package/treb-calculator/src/functions/date-utils.ts +1 -1
  108. package/treb-calculator/src/functions/finance-functions.ts +2 -4
  109. package/treb-calculator/src/functions/fp.ts +1 -1
  110. package/treb-calculator/src/functions/function-utilities.ts +1 -1
  111. package/treb-calculator/src/functions/gamma.ts +1 -1
  112. package/treb-calculator/src/functions/information-functions.ts +1 -1
  113. package/treb-calculator/src/functions/lambda-functions.ts +4 -1
  114. package/treb-calculator/src/functions/matrix-functions.ts +1 -1
  115. package/treb-calculator/src/functions/normal.ts +1 -1
  116. package/treb-calculator/src/functions/regex-functions.ts +13 -4
  117. package/treb-calculator/src/functions/sparkline.ts +1 -1
  118. package/treb-calculator/src/functions/statistics-functions.ts +1 -1
  119. package/treb-calculator/src/functions/students-t.ts +1 -1
  120. package/treb-calculator/src/functions/text-functions.ts +5 -1
  121. package/treb-calculator/src/index.ts +1 -1
  122. package/treb-calculator/src/notifier-types.ts +1 -1
  123. package/treb-calculator/src/primitives.ts +1 -1
  124. package/treb-calculator/src/utilities.ts +1 -1
  125. package/treb-charts/src/chart-functions.ts +1 -1
  126. package/treb-charts/src/chart-types.ts +1 -1
  127. package/treb-charts/src/chart-utils.ts +1 -1
  128. package/treb-charts/src/chart.ts +1 -1
  129. package/treb-charts/src/default-chart-renderer.ts +1 -1
  130. package/treb-charts/src/index.ts +1 -1
  131. package/treb-charts/src/main.ts +1 -1
  132. package/treb-charts/src/quicksort.ts +1 -1
  133. package/treb-charts/src/rectangle.ts +1 -1
  134. package/treb-charts/src/renderer-type.ts +1 -1
  135. package/treb-charts/src/renderer.ts +1 -1
  136. package/treb-charts/src/util.ts +1 -1
  137. package/treb-charts/style/charts.scss +1 -1
  138. package/treb-data-model/src/annotation.ts +1 -1
  139. package/treb-data-model/src/conditional_format.ts +1 -1
  140. package/treb-data-model/src/data-validation.ts +1 -1
  141. package/treb-data-model/src/data_model.ts +32 -5
  142. package/treb-data-model/src/index.ts +1 -1
  143. package/treb-data-model/src/language-model.ts +1 -1
  144. package/treb-data-model/src/named.ts +1 -1
  145. package/treb-data-model/src/serialize_options.ts +1 -1
  146. package/treb-data-model/src/sheet.ts +1 -1
  147. package/treb-data-model/src/sheet_collection.ts +1 -1
  148. package/treb-data-model/src/sheet_selection.ts +1 -1
  149. package/treb-data-model/src/sheet_types.ts +1 -1
  150. package/treb-data-model/src/types.ts +1 -1
  151. package/treb-embed/src/content-types.d.ts +1 -1
  152. package/treb-embed/src/custom-element/global.d.ts +1 -1
  153. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1 -1
  154. package/treb-embed/src/custom-element/treb-global.ts +1 -1
  155. package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +1 -1
  156. package/treb-embed/src/embedded-spreadsheet.ts +342 -149
  157. package/treb-embed/src/index.ts +1 -1
  158. package/treb-embed/src/options.ts +4 -2
  159. package/treb-embed/src/plugin.ts +1 -1
  160. package/treb-embed/src/progress-dialog.ts +1 -1
  161. package/treb-embed/src/selection-state.ts +1 -1
  162. package/treb-embed/src/spinner.ts +1 -1
  163. package/treb-embed/src/toolbar-message.ts +6 -1
  164. package/treb-embed/src/types.ts +13 -1
  165. package/treb-embed/style/autocomplete.scss +1 -1
  166. package/treb-embed/style/dark-theme.scss +1 -1
  167. package/treb-embed/style/defaults.scss +1 -1
  168. package/treb-embed/style/dialog.scss +1 -1
  169. package/treb-embed/style/dropdown-select.scss +1 -1
  170. package/treb-embed/style/font-stacks.scss +1 -1
  171. package/treb-embed/style/formula-bar.scss +1 -1
  172. package/treb-embed/style/grid.scss +1 -1
  173. package/treb-embed/style/layout.scss +1 -1
  174. package/treb-embed/style/mouse-mask.scss +1 -1
  175. package/treb-embed/style/note.scss +1 -1
  176. package/treb-embed/style/overlay-editor.scss +1 -1
  177. package/treb-embed/style/spinner.scss +1 -1
  178. package/treb-embed/style/tab-bar.scss +1 -1
  179. package/treb-embed/style/table.scss +1 -1
  180. package/treb-embed/style/theme-defaults.scss +1 -1
  181. package/treb-embed/style/toolbar.scss +1 -1
  182. package/treb-embed/style/tooltip.scss +1 -1
  183. package/treb-embed/style/treb-icons.scss +1 -1
  184. package/treb-embed/style/treb-spreadsheet-element.scss +1 -1
  185. package/treb-embed/style/z-index.scss +1 -1
  186. package/treb-export/src/address-type.ts +1 -1
  187. package/treb-export/src/base-template.ts +1 -1
  188. package/treb-export/src/column-width.ts +1 -1
  189. package/treb-export/src/drawing/bubble-chart-template.ts +1 -1
  190. package/treb-export/src/drawing/chart-template-components2.ts +1 -1
  191. package/treb-export/src/drawing/chart.ts +1 -1
  192. package/treb-export/src/drawing/column-chart-template2.ts +1 -1
  193. package/treb-export/src/drawing/donut-chart-template2.ts +1 -1
  194. package/treb-export/src/drawing/drawing.ts +1 -1
  195. package/treb-export/src/drawing/embedded-image.ts +1 -1
  196. package/treb-export/src/drawing/scatter-chart-template2.ts +1 -1
  197. package/treb-export/src/export.ts +10 -6
  198. package/treb-export/src/import-export-messages.ts +61 -0
  199. package/treb-export/src/import.ts +318 -301
  200. package/treb-export/src/index.worker.ts +85 -53
  201. package/treb-export/src/metadata.ts +71 -3
  202. package/treb-export/src/ooxml.ts +47 -0
  203. package/treb-export/src/relationship.ts +1 -1
  204. package/treb-export/src/shared-strings.ts +19 -15
  205. package/treb-export/src/template-2.ts +1 -1
  206. package/treb-export/src/unescape_xml.ts +1 -1
  207. package/treb-export/src/workbook-sheet.ts +11 -6
  208. package/treb-export/src/workbook-style.ts +137 -25
  209. package/treb-export/src/workbook-theme.ts +20 -4
  210. package/treb-export/src/workbook.ts +85 -88
  211. package/treb-export/src/xml-test.ts +1 -1
  212. package/treb-export/src/xml-utils.ts +1 -1
  213. package/treb-export/src/zip-wrapper.ts +1 -1
  214. package/treb-export/tsconfig.json +2 -1
  215. package/treb-format/src/format.test.ts +1 -1
  216. package/treb-format/src/format.ts +12 -5
  217. package/treb-format/src/format_cache.ts +3 -3
  218. package/treb-format/src/format_parser.ts +1 -1
  219. package/treb-format/src/index.ts +1 -1
  220. package/treb-format/src/number_format_section.ts +1 -1
  221. package/treb-format/src/value_parser.ts +1 -1
  222. package/treb-grid/src/editors/autocomplete.ts +1 -1
  223. package/treb-grid/src/editors/autocomplete_matcher.ts +1 -1
  224. package/treb-grid/src/editors/editor.ts +15 -6
  225. package/treb-grid/src/editors/external_editor.ts +33 -8
  226. package/treb-grid/src/editors/formula_bar.ts +12 -1
  227. package/treb-grid/src/editors/overlay_editor.ts +4 -1
  228. package/treb-grid/src/index.ts +1 -1
  229. package/treb-grid/src/layout/base_layout.ts +1 -1
  230. package/treb-grid/src/layout/grid_layout.ts +1 -1
  231. package/treb-grid/src/layout/mock-layout.ts +1 -1
  232. package/treb-grid/src/render/selection-renderer.ts +1 -1
  233. package/treb-grid/src/render/svg_header_overlay.ts +1 -1
  234. package/treb-grid/src/render/svg_selection_block.ts +1 -1
  235. package/treb-grid/src/render/tile_renderer.ts +36 -7
  236. package/treb-grid/src/types/border_constants.ts +1 -1
  237. package/treb-grid/src/types/clipboard_data.ts +1 -1
  238. package/treb-grid/src/types/clipboard_data2.ts +1 -1
  239. package/treb-grid/src/types/drag_mask.ts +1 -1
  240. package/treb-grid/src/types/external_editor_config.ts +1 -1
  241. package/treb-grid/src/types/grid.ts +181 -40
  242. package/treb-grid/src/types/grid_base.ts +7 -4
  243. package/treb-grid/src/types/grid_command.ts +7 -1
  244. package/treb-grid/src/types/grid_events.ts +2 -1
  245. package/treb-grid/src/types/grid_options.ts +1 -1
  246. package/treb-grid/src/types/scale-control.ts +1 -1
  247. package/treb-grid/src/types/set_range_options.ts +1 -1
  248. package/treb-grid/src/types/tab_bar.ts +1 -1
  249. package/treb-grid/src/types/tile.ts +1 -1
  250. package/treb-grid/src/types/update_flags.ts +1 -1
  251. package/treb-grid/src/util/fontmetrics.ts +1 -1
  252. package/treb-grid/src/util/ua.ts +1 -1
  253. package/treb-parser/src/csv-parser.ts +1 -1
  254. package/treb-parser/src/index.ts +1 -1
  255. package/treb-parser/src/md-parser.ts +1 -1
  256. package/treb-parser/src/parser-types.ts +1 -1
  257. package/treb-parser/src/parser.ts +1 -1
  258. package/treb-utils/src/event_source.ts +1 -1
  259. package/treb-utils/src/ievent_source.ts +1 -1
  260. package/treb-utils/src/index.ts +1 -1
  261. package/treb-utils/src/measurement.ts +1 -1
  262. package/treb-utils/src/scale.ts +1 -1
  263. package/treb-utils/src/serialize_html.ts +1 -1
  264. package/treb-utils/src/validate_uri.ts +1 -1
  265. package/tsproject.json +2 -3
  266. package/treb-embed/src/export-worker.ts +0 -44
@@ -14,7 +14,7 @@
14
14
  * You should have received a copy of the GNU General Public License along
15
15
  * with TREB. If not, see <https://www.gnu.org/licenses/>.
16
16
  *
17
- * Copyright 2022-2025 trebco, llc.
17
+ * Copyright 2022-2026 trebco, llc.
18
18
  * info@treb.app
19
19
  *
20
20
  */
@@ -26,6 +26,7 @@ import type {
26
26
  SheetChangeEvent, GridOptions,
27
27
  CellEvent, FunctionDescriptor,
28
28
  ExternalEditorConfig,
29
+ GridSelectionEvent,
29
30
  } from 'treb-grid';
30
31
 
31
32
  import { DataModel, Sheet, StandardGradientsList } from 'treb-data-model';
@@ -74,6 +75,7 @@ import type {
74
75
  IArea, CellValue, Point,
75
76
  Complex, ExtendedUnion, IRectangle,
76
77
  AddressReference, RangeReference, TableSortOptions, Table, TableTheme,
78
+ Theme,
77
79
  } from 'treb-base-types';
78
80
 
79
81
  import {
@@ -92,7 +94,7 @@ import { NumberFormatCache, ValueParser, NumberFormat, LotusDate, UnlotusDate }
92
94
  import { Dialog, DialogType } from './progress-dialog';
93
95
  import { Spinner } from './spinner';
94
96
  import { type EmbeddedSpreadsheetOptions, DefaultOptions, type ExportOptions } from './options';
95
- import { type TREBDocument, SaveFileType, LoadSource, type EmbeddedSheetEvent, type InsertTableOptions } from './types';
97
+ import { type TREBDocument, SaveFileType, LoadSource, type EmbeddedSheetEvent, type InsertTableOptions, type SelectionEvent } from './types';
96
98
 
97
99
  import type { SelectionState } from './selection-state';
98
100
  import type { BorderToolbarMessage, ToolbarMessage } from './toolbar-message';
@@ -102,6 +104,7 @@ import type { SetRangeOptions, ClipboardData, PasteOptions } from 'treb-grid';
102
104
 
103
105
  import type { StateLeafVertex } from 'treb-calculator';
104
106
 
107
+ import * as ImportExportMessages from 'treb-export/src/import-export-messages';
105
108
 
106
109
  // --- worker ------------------------------------------------------------------
107
110
 
@@ -109,9 +112,20 @@ import type { StateLeafVertex } from 'treb-calculator';
109
112
  * import type for our worker, plus markup files
110
113
  */
111
114
  import './content-types.d.ts';
115
+ import { CreateWorker, type WorkerProxy } from 'treb-base-types';
112
116
 
113
117
  // --- types -------------------------------------------------------------------
114
118
 
119
+ /** new, intended for tui support but keeping it as generic as possible */
120
+ export type CustomGridFactory = (
121
+ options: GridOptions,
122
+ model: DataModel,
123
+ theme: Theme|undefined,
124
+ initialze_dom: boolean,
125
+ DOM: DOMContext,
126
+ ) => Grid;
127
+
128
+
115
129
  /**
116
130
  * options for saving files. we add the option for JSON formatting.
117
131
  */
@@ -243,6 +257,18 @@ export type TableFilterFunction = (value: CellValue, calculated_value: CellValue
243
257
  */
244
258
  export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
245
259
 
260
+ /**
261
+ * this is temporary. we need a better way to handle this, perhaps
262
+ * making the factory method (createSpreadsheet) async.
263
+ *
264
+ * for now, you can test on this set of promises to see when the
265
+ * app is ready
266
+ */
267
+ protected _ready_state: Promise<void>[] = [];
268
+ public get ready () {
269
+ return Promise.all(this._ready_state);
270
+ }
271
+
246
272
  /** @internal */
247
273
  public static treb_base_path = '';
248
274
 
@@ -463,8 +489,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
463
489
  /**
464
490
  * export worker (no longer using worker-loader).
465
491
  * export worker is loaded on demand, not by default.
492
+ *
493
+ * FIXME: type
466
494
  */
467
- protected export_worker?: Worker;
495
+ protected export_worker?: WorkerProxy<ImportExportMessages.RXMessages, ImportExportMessages.TXMessages>;
468
496
 
469
497
  /**
470
498
  * undo pointer points to the next insert spot. that means that when
@@ -651,7 +679,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
651
679
  *
652
680
  * @internal
653
681
  */
654
- constructor(options: EmbeddedSpreadsheetOptions & { model?: EmbeddedSpreadsheet }) {
682
+ constructor(options: EmbeddedSpreadsheetOptions & { model?: EmbeddedSpreadsheet, custom_grid?: CustomGridFactory }) {
655
683
 
656
684
  // we renamed this option, default to the new name
657
685
 
@@ -832,8 +860,12 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
832
860
 
833
861
  }
834
862
 
835
- //this.extra_calculator = //new Calculator(this.model);
836
- // this.CreateCalculator(this.model);
863
+ // FIXME: we should start figuring out what can happen before
864
+ // this async init, and what has to wait. then we can split the
865
+ // ctor into two parts, and move stuff that has to wait to part 2
866
+
867
+ const calculator_init = this.calculator.InitResources();
868
+ this._ready_state.push(calculator_init);
837
869
 
838
870
  if (container) {
839
871
  this.DOM = DOMContext.GetInstance(container.ownerDocument);
@@ -847,12 +879,30 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
847
879
  // it when we don't have a container? or was it built for something
848
880
  // else? (A: it was)
849
881
 
850
- this.grid = new Grid(
851
- grid_options,
852
- this.model,
853
- undefined,
854
- !!container,
855
- this.DOM);
882
+ if (options.custom_grid) {
883
+ this.grid = options.custom_grid(
884
+ grid_options,
885
+ this.model,
886
+ undefined,
887
+ !!container,
888
+ this.DOM);
889
+
890
+ // we're going to need to create some sort of capabilities map
891
+ // for custom grids. for the time being, let's subscribe to events
892
+ // and see what happens.
893
+
894
+ // UPDATE: do that a little later...
895
+
896
+
897
+ }
898
+ else {
899
+ this.grid = new Grid(
900
+ grid_options,
901
+ this.model,
902
+ undefined,
903
+ !!container,
904
+ this.DOM);
905
+ }
856
906
 
857
907
  if (this.options.headless) {
858
908
  this.grid.headless = true; // FIXME: move into grid options
@@ -970,7 +1020,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
970
1020
 
971
1021
  case 'selection':
972
1022
  // console.info('selection event');
973
- this.UpdateSelection(event.selection);
1023
+ this.UpdateSelection(event.selection, event.reason);
974
1024
  this.UpdateSelectionStyle(event.selection);
975
1025
  break;
976
1026
 
@@ -1133,11 +1183,204 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1133
1183
 
1134
1184
  }
1135
1185
  else {
1186
+
1187
+ if (options.custom_grid) {
1188
+ console.info("creating subscription for custom grid (TODO: capabilities)")
1189
+
1190
+ ////
1191
+
1192
+
1193
+ this.grid.grid_events.Subscribe((event) => {
1194
+
1195
+ // console.info({event});
1196
+
1197
+ switch (event.type) {
1198
+
1199
+ // these messages can stack, they don't have undo effect
1200
+
1201
+ case 'error':
1202
+ /*
1203
+ this.dialog?.ShowDialog({
1204
+ type: DialogType.error,
1205
+ ...this.TranslateGridError(event.code),
1206
+ timeout: 3000,
1207
+ close_box: true,
1208
+ });
1209
+ */
1210
+
1211
+ // ??
1212
+
1213
+ break;
1214
+
1215
+ case 'selection':
1216
+ // console.info('selection event');
1217
+ this.UpdateSelection(event.selection, event.reason);
1218
+ this.UpdateSelectionStyle(event.selection);
1219
+ break;
1220
+
1221
+ case 'sheet-change':
1222
+ this.OnSheetChange(event);
1223
+ this.UpdateSelectionStyle();
1224
+ break;
1225
+
1226
+ case 'scale':
1227
+ this.RebuildAllAnnotations();
1228
+ this.Publish({ type: 'view-change' });
1229
+ break;
1230
+
1231
+ case 'cell-event':
1232
+ this.HandleCellEvent(event);
1233
+ break;
1234
+
1235
+ // messages that trigger undo need some special handling,
1236
+ // because we don't want to stack a sequence of messages
1237
+ // and push multiple undo events. that applies to data,
1238
+ // style, structure, and (maybe?) annotations
1239
+
1240
+ // OK, temp we have a composite event for data+style
1241
+
1242
+ case 'composite':
1243
+ {
1244
+ const cached_selection = this.last_selection;
1245
+ if (this.calculation === CalculationOptions.automatic) {
1246
+ this.Recalculate(event);
1247
+ }
1248
+ this.DocumentChange(cached_selection);
1249
+ this.UpdateDocumentStyles();
1250
+ this.UpdateSelectionStyle();
1251
+ }
1252
+ break;
1253
+
1254
+ case 'data':
1255
+ {
1256
+ // because this is async (more than once), we can't expect the
1257
+ // selection event to happen after the PushUndo call. we need
1258
+ // to preserve the current selection and pass it through.
1259
+
1260
+ const cached_selection = this.last_selection;
1261
+
1262
+ // recalc is no longer async
1263
+
1264
+ if (this.calculation === CalculationOptions.automatic) {
1265
+ this.Recalculate(event);
1266
+ }
1267
+
1268
+ this.DocumentChange(cached_selection);
1269
+
1270
+ }
1271
+ break;
1272
+
1273
+ case 'style':
1274
+ this.DocumentChange();
1275
+ this.UpdateDocumentStyles();
1276
+ this.UpdateSelectionStyle();
1277
+ break;
1278
+
1279
+ case 'annotation':
1280
+
1281
+ /*
1282
+ // FIXME: maybe need to update vertices (on create, update, delete,
1283
+ // not on move or resize)
1284
+
1285
+ if (event.annotation) {
1286
+ const view: AnnotationViewData = event.annotation.view[this.grid.view_index] || {};
1287
+
1288
+ let update_toolbar = false;
1289
+
1290
+ if (event.event === 'select') {
1291
+ update_toolbar = true;
1292
+ }
1293
+ else {
1294
+ this.DocumentChange();
1295
+ switch (event.event) {
1296
+ case 'create':
1297
+ this.InflateAnnotation(event.annotation);
1298
+ this.calculator.UpdateAnnotations(event.annotation, this.grid.active_sheet);
1299
+ this.grid.AnnotationUpdated(event.annotation);
1300
+ update_toolbar = (event.annotation === this.grid.selected_annotation);
1301
+ break;
1302
+ case 'delete':
1303
+ this.calculator.RemoveAnnotation(event.annotation); // clean up vertex
1304
+ break;
1305
+ case 'update':
1306
+ if (view.update_callback) {
1307
+ view.update_callback();
1308
+ this.grid.AnnotationUpdated(event.annotation);
1309
+ }
1310
+ else {
1311
+ console.info('annotation update event without update callback');
1312
+ }
1313
+ this.calculator.UpdateAnnotations(event.annotation, this.grid.active_sheet);
1314
+ update_toolbar = (event.annotation === this.grid.selected_annotation);
1315
+ break;
1316
+ case 'resize':
1317
+ if (view.resize_callback) {
1318
+ view.resize_callback();
1319
+ this.grid.AnnotationUpdated(event.annotation);
1320
+ }
1321
+ break;
1322
+ }
1323
+
1324
+ }
1325
+
1326
+ if (update_toolbar) {
1327
+ this.UpdateSelectionStyleAnnotation(event.annotation);
1328
+ this.Publish({ type: 'annotation-selection' });
1329
+ break;
1330
+ }
1331
+
1332
+ }
1333
+ else {
1334
+ console.info('annotation event without annotation');
1335
+ }
1336
+ */
1337
+ break;
1338
+
1339
+ case 'structure':
1340
+ {
1341
+ // console.info("S event", event);
1342
+
1343
+ const cached_selection = this.last_selection;
1344
+ if (event.conditional_format) {
1345
+ this.calculator.UpdateConditionals();
1346
+ this.ApplyConditionalFormats(this.grid.active_sheet, false);
1347
+ }
1348
+
1349
+ if (event.rebuild_required) {
1350
+ this.calculator.Reset();
1351
+
1352
+ // recalculate is no longer async
1353
+
1354
+ if (this.calculation === CalculationOptions.automatic) {
1355
+ this.Recalculate(event);
1356
+ }
1357
+ this.DocumentChange(cached_selection);
1358
+
1359
+ }
1360
+ else {
1361
+ this.DocumentChange(cached_selection);
1362
+ }
1363
+ }
1364
+ this.UpdateSelectionStyle();
1365
+ break;
1366
+
1367
+ }
1368
+ });
1369
+
1370
+ ////
1371
+
1372
+
1373
+ }
1374
+
1136
1375
  if (!EmbeddedSpreadsheet.one_time_warnings.headless) {
1137
- EmbeddedSpreadsheet.one_time_warnings.headless = true;
1138
- console.info('not initializing layout; don\'t call UI functions');
1376
+
1377
+ // suppress this warning if you explicitly set headless mode
1378
+
1379
+ if (!options.headless) {
1380
+ EmbeddedSpreadsheet.one_time_warnings.headless = true;
1381
+ console.info('not initializing layout; don\'t call UI functions');
1382
+ }
1139
1383
  }
1140
- // this.grid.headless = true; // ensure
1141
1384
  }
1142
1385
 
1143
1386
  if (options.preload) {
@@ -1151,7 +1394,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1151
1394
  data = JSON.parse(data);
1152
1395
  }
1153
1396
  if (data) {
1154
- this.LoadDocument(data as TREBDocument, { recalculate: !!this.options.recalculate, source});
1397
+ calculator_init.then(() => {
1398
+ this.LoadDocument(data as TREBDocument, { recalculate: !!this.options.recalculate, source});
1399
+ });
1155
1400
  }
1156
1401
  else {
1157
1402
  this.UpdateDocumentStyles();
@@ -1206,13 +1451,16 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1206
1451
  this.spinner = new Spinner(container);
1207
1452
  }
1208
1453
 
1454
+
1209
1455
  // don't load if we are a split view
1210
1456
  // UPDATE: don't load if we have a local_storage document. this is taking
1211
1457
  // over the old alternate_document flow, because it doesn't make any sense
1212
1458
  // otherwise. what would local_storage with document_name mean otherwise?
1213
1459
 
1214
1460
  if (network_document && !options.model && !data) {
1215
- this.LoadNetworkDocument(network_document, this.options);
1461
+ calculator_init.then(() => {
1462
+ this.LoadNetworkDocument(network_document, this.options);
1463
+ });
1216
1464
  }
1217
1465
 
1218
1466
  // create mask dialog
@@ -1286,6 +1534,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1286
1534
  return new Calculator(model, {
1287
1535
  complex_numbers: options.complex,
1288
1536
  spill: options.spill,
1537
+ headless: options.headless,
1289
1538
  });
1290
1539
  }
1291
1540
 
@@ -1881,6 +2130,17 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1881
2130
  case 'insert-scatter-plot': insert_annotation('Scatter.Plot'); break;
1882
2131
  case 'insert-box-plot': insert_annotation('Box.Plot'); break;
1883
2132
 
2133
+ case 'toggle-grouping':
2134
+ if (this.selection_state?.style) {
2135
+ const format = NumberFormatCache.Get(this.selection_state.style.number_format || 'General');
2136
+ if (format.date_format) { break; }
2137
+ const clone = new NumberFormat(format.pattern);
2138
+ clone.ToggleGrouping();
2139
+ const rendered = clone.toString();
2140
+ updated_style.number_format = NumberFormatCache.SymbolicName(rendered) || rendered;
2141
+ }
2142
+ break;
2143
+
1884
2144
  case 'increase-precision':
1885
2145
  case 'decrease-precision':
1886
2146
  if (this.selection_state?.style) {
@@ -1890,78 +2150,18 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1890
2150
 
1891
2151
  const clone = new NumberFormat(format.pattern);
1892
2152
 
1893
- // special case: from general, we want to go to a relative number...
1894
- // for that to work, we need a (the first) value... then go from there.
1895
-
1896
- // NOTE: this isn't really the way to identify this, we only want
1897
- // to do this if the style === 'General'.
1898
-
1899
- if (format.magic_decimal) {
1900
-
1901
- // but what we're doing here, if there's a magic decimal, is
1902
- // measuring the decimal part of the first number we find. then
1903
- // we increase/decrease from that.
1904
-
1905
- let len = 0;
1906
- let rng = this.GetRange();
1907
-
1908
- // find the first number...
1909
-
1910
- if (!Array.isArray(rng)) {
1911
- rng = [[rng]];
1912
- }
1913
-
1914
- find_number:
1915
- for (let i = 0; i < rng.length; i++) {
1916
- for (let j = 0; j < rng[i].length; j++) {
1917
- const value = rng[i][j];
1918
-
1919
- if (typeof value !== 'undefined' && IsComplex(value)) {
1920
-
1921
- // find the longer of the two, use that as base
1922
-
1923
- //const f2 = NumberFormatCache.Get(this.active_selection_style.number_format || 'General', true);
1924
- const f2 = NumberFormatCache.Get(this.selection_state.style.number_format || 'General', true);
1925
- const real_parts = f2.BaseFormat(value.real);
1926
- const imaginary_parts = f2.BaseFormat(value.imaginary);
1927
-
1928
- if (real_parts.parts && typeof real_parts.parts[1] === 'string') {
1929
- len = real_parts.parts[1].length;
1930
- }
1931
- if (imaginary_parts.parts && typeof imaginary_parts.parts[1] === 'string') {
1932
- len = Math.max(len, imaginary_parts.parts[1].length);
1933
- }
1934
-
1935
- break find_number;
1936
-
1937
- }
1938
- else if (typeof value === 'number') {
1939
- const parts = format.BaseFormat(value);
1940
- if (parts.parts && typeof parts.parts[1] === 'string') {
1941
- len = parts.parts[1].length;
1942
- }
1943
- break find_number;
1944
- }
1945
- }
1946
- }
1947
-
1948
- if (event.command === 'increase-precision') {
1949
- clone.SetDecimal(len + 1);
1950
- }
1951
- else {
1952
- clone.SetDecimal(Math.max(0, len - 1));
1953
- }
1954
-
2153
+ if (event.command === 'increase-precision' ) {
2154
+ clone.IncreaseDecimal();
1955
2155
  }
1956
2156
  else {
1957
- if (event.command === 'increase-precision' ) {
1958
- clone.IncreaseDecimal();
1959
- }
1960
- else {
1961
- clone.DecreaseDecimal();
1962
- }
2157
+ clone.DecreaseDecimal();
1963
2158
  }
1964
- updated_style.number_format = clone.toString();
2159
+
2160
+ // try to resolve this to a standard format, if possible
2161
+
2162
+ const rendered = clone.toString();
2163
+ updated_style.number_format = NumberFormatCache.SymbolicName(rendered) || rendered;
2164
+
1965
2165
  }
1966
2166
  break;
1967
2167
 
@@ -2203,7 +2403,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2203
2403
  // comments
2204
2404
 
2205
2405
  try {
2206
- mod = await import(`esbuild-ignore-import:./languages/treb-i18n-${language}.mjs`);
2406
+ const path = `./languages/treb-i18n-${language}.mjs`;
2407
+ mod = await import(path);
2207
2408
  }
2208
2409
  catch (err) {
2209
2410
  console.error(err);
@@ -2222,6 +2423,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2222
2423
  this.grid.Update(true);
2223
2424
  this.UpdateAC();
2224
2425
 
2426
+ this.Publish({
2427
+ type: 'language-change',
2428
+ });
2429
+
2225
2430
  }
2226
2431
 
2227
2432
  /**
@@ -2870,6 +3075,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2870
3075
  *
2871
3076
  * @param column - column, or columns (array), or undefined means all columns
2872
3077
  * @param width - desired width (can be 0) or undefined means 'auto-size'
3078
+ * @param allow_shrinking - for auto-size, allow shrinking. defaults to true.
2873
3079
  *
2874
3080
  * @privateRemarks
2875
3081
  *
@@ -2878,9 +3084,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
2878
3084
  *
2879
3085
  * @public
2880
3086
  */
2881
- public SetColumnWidth(column?: number | number[], width?: number): void {
2882
-
2883
- this.grid.SetColumnWidth(column, width);
3087
+ public SetColumnWidth(column?: number | number[], width?: number, allow_shrinking?: boolean): void {
3088
+ this.grid.SetColumnWidth(column, width, allow_shrinking);
2884
3089
  }
2885
3090
 
2886
3091
  /**
@@ -3084,14 +3289,16 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
3084
3289
  return new Promise<Blob>((resolve, reject) => {
3085
3290
 
3086
3291
  if (this.export_worker) {
3087
- this.export_worker.onmessage = (event) => {
3088
- resolve(event.data ? event.data.blob : undefined);
3089
- };
3090
- this.export_worker.onerror = (event) => {
3292
+ this.export_worker.OnMessage((event) => {
3293
+ if (event.data.type === 'export-complete') {
3294
+ resolve(event.data.blob);
3295
+ }
3296
+ });
3297
+ this.export_worker.OnError((event) => {
3091
3298
  console.error('export worker error');
3092
3299
  console.info(event);
3093
3300
  reject(event);
3094
- };
3301
+ });
3095
3302
 
3096
3303
  if (!serialized) {
3097
3304
  serialized = this.Serialize({
@@ -3109,8 +3316,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
3109
3316
  // why do _we_ put this in, instead of the grid method?
3110
3317
  serialized.decimal_mark = Localization.decimal_separator;
3111
3318
 
3112
- this.export_worker.postMessage({
3113
- command: 'export',
3319
+ this.export_worker.PostMessage({
3320
+ type: 'export',
3114
3321
  sheet: serialized,
3115
3322
  decorated: this.calculator.DecoratedFunctionList(),
3116
3323
  });
@@ -4041,7 +4248,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
4041
4248
 
4042
4249
  this.calculator.Calculate(area);
4043
4250
 
4044
- if (this.calculator.grid_expanded) {
4251
+ if (this.calculator.grid_expanded && !this.grid.headless) {
4045
4252
  // console.info("GRID EXPANDED");
4046
4253
  this.grid.UpdateLayout();
4047
4254
  }
@@ -5061,7 +5268,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5061
5268
  *
5062
5269
  */
5063
5270
  protected async ImportXLSX( // data: string, source: LoadSource): Promise<Blob | void> {
5064
- data: ArrayBuffer, source: LoadSource): Promise<Blob | void> {
5271
+ data: ArrayBuffer, source: LoadSource, path?: string): Promise<Blob | void> {
5065
5272
 
5066
5273
  // this is inlined to ensure the code will be tree-shaken properly
5067
5274
  if (!process.env.XLSX_SUPPORT) {
@@ -5089,12 +5296,15 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5089
5296
  message: 'Importing XLSX...'
5090
5297
  });
5091
5298
 
5092
- this.export_worker.onmessage = (event) => {
5299
+ this.export_worker.OnMessage((event) => {
5093
5300
  if (event.data) {
5094
5301
 
5095
- if (event.data.status === 'error') {
5302
+ if (event.data.type === 'import-error') {
5096
5303
  return reject(event.data.error || 'unknown error');
5097
5304
  }
5305
+ if (event.data.type !== 'import-complete') {
5306
+ return reject('unknown error (invalid message)');
5307
+ }
5098
5308
 
5099
5309
  if (this.parser.decimal_mark !== DecimalMarkType.Period) {
5100
5310
 
@@ -5118,15 +5328,15 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5118
5328
  });
5119
5329
  };
5120
5330
 
5121
- for (const named of event.data.results) {
5122
- named.expression = translate(named.expression);
5331
+ for (const named of event.data.results.named || []) {
5332
+ named.expression = translate(named.expression) || '';
5123
5333
  }
5124
5334
 
5125
5335
  for (const sheet of event.data.results.sheets || []) {
5126
5336
 
5127
5337
  for (const cell of sheet.cells || []) {
5128
5338
  if (cell.type === 'formula' && cell.value) {
5129
- cell.value = translate(cell.value);
5339
+ cell.value = translate(cell.value as string);
5130
5340
  }
5131
5341
  }
5132
5342
 
@@ -5152,7 +5362,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5152
5362
  // this one _is_ the grid cells
5153
5363
 
5154
5364
  // this.calculator.AttachModel();
5155
- this.Publish({ type: 'load', source, });
5365
+ this.Publish({ type: 'load', source, path });
5156
5366
  this.UpdateDocumentStyles();
5157
5367
 
5158
5368
  // add to support import charts
@@ -5171,15 +5381,18 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5171
5381
 
5172
5382
  this.dialog?.HideDialog();
5173
5383
  resolve();
5174
- };
5175
- this.export_worker.onerror = (event) => {
5384
+ });
5385
+
5386
+ this.export_worker.OnError((event) => {
5176
5387
  console.error('import worker error');
5177
5388
  console.info(event);
5178
5389
  reject(event);
5179
- };
5180
- this.export_worker.postMessage({
5181
- command: 'import', data,
5182
5390
  });
5391
+
5392
+ this.export_worker.PostMessage({
5393
+ type: 'import', data,
5394
+ });
5395
+
5183
5396
  }
5184
5397
  else {
5185
5398
  reject('worker failed');
@@ -5630,21 +5843,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5630
5843
  }
5631
5844
  }
5632
5845
 
5633
- /*
5634
- public SetHeadless(headless = true): void {
5635
- if (this.grid.headless === headless) {
5636
- return;
5637
- }
5638
-
5639
- this.grid.headless = headless;
5640
- if (!headless) {
5641
- this.grid.Update(true);
5642
- this.RebuildAllAnnotations();
5643
- // this.InflateAnnotations();
5644
- }
5645
- }
5646
- */
5647
-
5648
5846
  /**
5649
5847
  * this method should be called after changing the headless flag
5650
5848
  */
@@ -6119,14 +6317,19 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6119
6317
  * we can also use this to better manage selection in the undo system...
6120
6318
  *
6121
6319
  */
6122
- protected UpdateSelection(selection: GridSelection): void {
6320
+ protected UpdateSelection(selection: GridSelection, reason?: GridSelectionEvent['reason']): void {
6123
6321
 
6124
6322
  // console.info("US", JSON.stringify(selection));
6125
6323
 
6126
6324
  // cache for undo
6127
6325
  this.last_selection = JSON.stringify(selection);
6128
6326
 
6129
- this.Publish({ type: 'selection' });
6327
+ const event: SelectionEvent = { type: 'selection' };
6328
+ if (reason === 'sheet-change') {
6329
+ event.reason = reason;
6330
+ }
6331
+
6332
+ this.Publish(event);
6130
6333
  }
6131
6334
 
6132
6335
  /** update selection style for the toolbar, when an annotation is selected. */
@@ -6240,12 +6443,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6240
6443
 
6241
6444
  }
6242
6445
 
6243
- /* * overloadable for subclasses * /
6244
- protected InitCalculator(): CalcType {
6245
- return new Calculator();
6246
- }
6247
- */
6248
-
6249
6446
  /**
6250
6447
  * this function is called when the file locale (as indicated by the
6251
6448
  * decimal separator) is different than the current active locale.
@@ -6577,21 +6774,17 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
6577
6774
  }
6578
6775
 
6579
6776
  /**
6580
- * worker now uses a dynamic import with a module built separately.
6581
- * see `export-worker.ts` (in this directory) for more detail.
6582
- */
6583
- protected async LoadWorker(): Promise<Worker> {
6584
- try {
6585
- const worker = `export`;
6586
- const mod = await import(`esbuild-ignore-import:./treb-${worker}-worker.mjs`) as {
6587
- CreateWorker: () => Promise<Worker>;
6588
- };
6589
- return await mod.CreateWorker();
6590
- }
6591
- catch (err) {
6592
- console.error(err);
6593
- throw(err);
6594
- }
6777
+ * switching to worker proxy so we can support node
6778
+ * FIXME: type
6779
+ */
6780
+ protected async LoadWorker(): Promise<WorkerProxy<ImportExportMessages.RXMessages, ImportExportMessages.TXMessages>> {
6781
+ const worker = CreateWorker<ImportExportMessages.RXMessages, ImportExportMessages.TXMessages>(!!this.options.in_process_workers);
6782
+ await worker.Init('./treb-export-worker.mjs', () => {
6783
+ return new Worker(new URL('./treb-export-worker.mjs', import.meta.url), {
6784
+ type: 'module'
6785
+ }) as Worker;
6786
+ });
6787
+ return worker;
6595
6788
  }
6596
6789
 
6597
6790
  /**