@trebco/treb 23.6.5 → 25.0.0-rc2

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 (217) hide show
  1. package/.eslintignore +8 -0
  2. package/.eslintrc.js +164 -0
  3. package/README-shadow-DOM.md +88 -0
  4. package/README.md +37 -130
  5. package/api-config.json +29 -0
  6. package/api-generator/api-generator-types.ts +82 -0
  7. package/api-generator/api-generator.ts +1172 -0
  8. package/api-generator/package.json +3 -0
  9. package/build/treb-spreadsheet.mjs +14 -0
  10. package/{treb.d.ts → build/treb.d.ts} +323 -271
  11. package/esbuild-custom-element.mjs +336 -0
  12. package/esbuild.js +305 -0
  13. package/package.json +49 -14
  14. package/treb-base-types/package.json +5 -0
  15. package/treb-base-types/src/api_types.ts +36 -0
  16. package/treb-base-types/src/area.ts +583 -0
  17. package/treb-base-types/src/basic_types.ts +45 -0
  18. package/treb-base-types/src/cell.ts +612 -0
  19. package/treb-base-types/src/cells.ts +1066 -0
  20. package/treb-base-types/src/color.ts +124 -0
  21. package/treb-base-types/src/import.ts +71 -0
  22. package/treb-base-types/src/index-standalone.ts +29 -0
  23. package/treb-base-types/src/index.ts +42 -0
  24. package/treb-base-types/src/layout.ts +47 -0
  25. package/treb-base-types/src/localization.ts +187 -0
  26. package/treb-base-types/src/rectangle.ts +145 -0
  27. package/treb-base-types/src/render_text.ts +72 -0
  28. package/treb-base-types/src/style.ts +545 -0
  29. package/treb-base-types/src/table.ts +109 -0
  30. package/treb-base-types/src/text_part.ts +54 -0
  31. package/treb-base-types/src/theme.ts +608 -0
  32. package/treb-base-types/src/union.ts +152 -0
  33. package/treb-base-types/src/value-type.ts +164 -0
  34. package/treb-base-types/style/resizable.css +59 -0
  35. package/treb-calculator/modern.tsconfig.json +11 -0
  36. package/treb-calculator/package.json +5 -0
  37. package/treb-calculator/src/calculator.ts +2546 -0
  38. package/treb-calculator/src/complex-math.ts +558 -0
  39. package/treb-calculator/src/dag/array-vertex.ts +198 -0
  40. package/treb-calculator/src/dag/graph.ts +951 -0
  41. package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
  42. package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
  43. package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
  44. package/treb-calculator/src/dag/vertex.ts +352 -0
  45. package/treb-calculator/src/descriptors.ts +162 -0
  46. package/treb-calculator/src/expression-calculator.ts +1069 -0
  47. package/treb-calculator/src/function-error.ts +103 -0
  48. package/treb-calculator/src/function-library.ts +103 -0
  49. package/treb-calculator/src/functions/base-functions.ts +1214 -0
  50. package/treb-calculator/src/functions/checkbox.ts +164 -0
  51. package/treb-calculator/src/functions/complex-functions.ts +253 -0
  52. package/treb-calculator/src/functions/finance-functions.ts +399 -0
  53. package/treb-calculator/src/functions/information-functions.ts +102 -0
  54. package/treb-calculator/src/functions/matrix-functions.ts +182 -0
  55. package/treb-calculator/src/functions/sparkline.ts +335 -0
  56. package/treb-calculator/src/functions/statistics-functions.ts +350 -0
  57. package/treb-calculator/src/functions/text-functions.ts +298 -0
  58. package/treb-calculator/src/index.ts +27 -0
  59. package/treb-calculator/src/notifier-types.ts +59 -0
  60. package/treb-calculator/src/primitives.ts +428 -0
  61. package/treb-calculator/src/utilities.ts +305 -0
  62. package/treb-charts/package.json +5 -0
  63. package/treb-charts/src/chart-functions.ts +156 -0
  64. package/treb-charts/src/chart-types.ts +230 -0
  65. package/treb-charts/src/chart.ts +1288 -0
  66. package/treb-charts/src/index.ts +24 -0
  67. package/treb-charts/src/main.ts +37 -0
  68. package/treb-charts/src/rectangle.ts +52 -0
  69. package/treb-charts/src/renderer.ts +1841 -0
  70. package/treb-charts/src/util.ts +122 -0
  71. package/treb-charts/style/charts.scss +221 -0
  72. package/treb-charts/style/old-charts.scss +250 -0
  73. package/treb-embed/markup/layout.html +137 -0
  74. package/treb-embed/markup/toolbar.html +175 -0
  75. package/treb-embed/modern.tsconfig.json +25 -0
  76. package/treb-embed/src/custom-element/content-types.d.ts +18 -0
  77. package/treb-embed/src/custom-element/global.d.ts +11 -0
  78. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1228 -0
  79. package/treb-embed/src/custom-element/treb-global.ts +44 -0
  80. package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
  81. package/treb-embed/src/embedded-spreadsheet.ts +5358 -0
  82. package/treb-embed/src/index.ts +16 -0
  83. package/treb-embed/src/language-model.ts +41 -0
  84. package/treb-embed/src/options.ts +298 -0
  85. package/treb-embed/src/progress-dialog.ts +228 -0
  86. package/treb-embed/src/selection-state.ts +16 -0
  87. package/treb-embed/src/spinner.ts +42 -0
  88. package/treb-embed/src/toolbar-message.ts +96 -0
  89. package/treb-embed/src/types.ts +167 -0
  90. package/treb-embed/style/autocomplete.scss +103 -0
  91. package/treb-embed/style/dark-theme.scss +114 -0
  92. package/treb-embed/style/defaults.scss +36 -0
  93. package/treb-embed/style/dialog.scss +181 -0
  94. package/treb-embed/style/dropdown-select.scss +101 -0
  95. package/treb-embed/style/formula-bar.scss +193 -0
  96. package/treb-embed/style/grid.scss +374 -0
  97. package/treb-embed/style/layout.scss +424 -0
  98. package/treb-embed/style/mouse-mask.scss +67 -0
  99. package/treb-embed/style/note.scss +92 -0
  100. package/treb-embed/style/overlay-editor.scss +102 -0
  101. package/treb-embed/style/spinner.scss +92 -0
  102. package/treb-embed/style/tab-bar.scss +228 -0
  103. package/treb-embed/style/table.scss +80 -0
  104. package/treb-embed/style/theme-defaults.scss +444 -0
  105. package/treb-embed/style/toolbar.scss +416 -0
  106. package/treb-embed/style/tooltip.scss +68 -0
  107. package/treb-embed/style/treb-icons.scss +130 -0
  108. package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
  109. package/treb-embed/style/z-index.scss +43 -0
  110. package/treb-export/docs/charts.md +68 -0
  111. package/treb-export/modern.tsconfig.json +19 -0
  112. package/treb-export/package.json +4 -0
  113. package/treb-export/src/address-type.ts +77 -0
  114. package/treb-export/src/base-template.ts +22 -0
  115. package/treb-export/src/column-width.ts +85 -0
  116. package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
  117. package/treb-export/src/drawing2/chart2.ts +282 -0
  118. package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
  119. package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
  120. package/treb-export/src/drawing2/drawing2.ts +355 -0
  121. package/treb-export/src/drawing2/embedded-image.ts +71 -0
  122. package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
  123. package/treb-export/src/export-worker/export-worker.ts +99 -0
  124. package/treb-export/src/export-worker/index-modern.ts +22 -0
  125. package/treb-export/src/export2.ts +2204 -0
  126. package/treb-export/src/import2.ts +882 -0
  127. package/treb-export/src/relationship.ts +36 -0
  128. package/treb-export/src/shared-strings2.ts +128 -0
  129. package/treb-export/src/template-2.ts +22 -0
  130. package/treb-export/src/unescape_xml.ts +47 -0
  131. package/treb-export/src/workbook-sheet2.ts +182 -0
  132. package/treb-export/src/workbook-style2.ts +1285 -0
  133. package/treb-export/src/workbook-theme2.ts +88 -0
  134. package/treb-export/src/workbook2.ts +491 -0
  135. package/treb-export/src/xml-utils.ts +201 -0
  136. package/treb-export/template/base/[Content_Types].xml +2 -0
  137. package/treb-export/template/base/_rels/.rels +2 -0
  138. package/treb-export/template/base/docProps/app.xml +2 -0
  139. package/treb-export/template/base/docProps/core.xml +12 -0
  140. package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
  141. package/treb-export/template/base/xl/sharedStrings.xml +2 -0
  142. package/treb-export/template/base/xl/styles.xml +2 -0
  143. package/treb-export/template/base/xl/theme/theme1.xml +2 -0
  144. package/treb-export/template/base/xl/workbook.xml +2 -0
  145. package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
  146. package/treb-export/template/base.xlsx +0 -0
  147. package/treb-format/package.json +8 -0
  148. package/treb-format/src/format.test.ts +213 -0
  149. package/treb-format/src/format.ts +942 -0
  150. package/treb-format/src/format_cache.ts +199 -0
  151. package/treb-format/src/format_parser.ts +723 -0
  152. package/treb-format/src/index.ts +25 -0
  153. package/treb-format/src/number_format_section.ts +100 -0
  154. package/treb-format/src/value_parser.ts +337 -0
  155. package/treb-grid/package.json +5 -0
  156. package/treb-grid/src/editors/autocomplete.ts +394 -0
  157. package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
  158. package/treb-grid/src/editors/formula_bar.ts +473 -0
  159. package/treb-grid/src/editors/formula_editor_base.ts +910 -0
  160. package/treb-grid/src/editors/overlay_editor.ts +511 -0
  161. package/treb-grid/src/index.ts +37 -0
  162. package/treb-grid/src/layout/base_layout.ts +2618 -0
  163. package/treb-grid/src/layout/grid_layout.ts +299 -0
  164. package/treb-grid/src/layout/rectangle_cache.ts +86 -0
  165. package/treb-grid/src/render/selection-renderer.ts +414 -0
  166. package/treb-grid/src/render/svg_header_overlay.ts +93 -0
  167. package/treb-grid/src/render/svg_selection_block.ts +187 -0
  168. package/treb-grid/src/render/tile_renderer.ts +2122 -0
  169. package/treb-grid/src/types/annotation.ts +216 -0
  170. package/treb-grid/src/types/border_constants.ts +34 -0
  171. package/treb-grid/src/types/clipboard_data.ts +31 -0
  172. package/treb-grid/src/types/data_model.ts +334 -0
  173. package/treb-grid/src/types/drag_mask.ts +81 -0
  174. package/treb-grid/src/types/grid.ts +7743 -0
  175. package/treb-grid/src/types/grid_base.ts +3644 -0
  176. package/treb-grid/src/types/grid_command.ts +470 -0
  177. package/treb-grid/src/types/grid_events.ts +124 -0
  178. package/treb-grid/src/types/grid_options.ts +97 -0
  179. package/treb-grid/src/types/grid_selection.ts +60 -0
  180. package/treb-grid/src/types/named_range.ts +369 -0
  181. package/treb-grid/src/types/scale-control.ts +202 -0
  182. package/treb-grid/src/types/serialize_options.ts +72 -0
  183. package/treb-grid/src/types/set_range_options.ts +52 -0
  184. package/treb-grid/src/types/sheet.ts +3099 -0
  185. package/treb-grid/src/types/sheet_types.ts +95 -0
  186. package/treb-grid/src/types/tab_bar.ts +464 -0
  187. package/treb-grid/src/types/tile.ts +59 -0
  188. package/treb-grid/src/types/update_flags.ts +75 -0
  189. package/treb-grid/src/util/dom_utilities.ts +44 -0
  190. package/treb-grid/src/util/fontmetrics2.ts +179 -0
  191. package/treb-grid/src/util/ua.ts +104 -0
  192. package/treb-logo.svg +18 -0
  193. package/treb-parser/package.json +5 -0
  194. package/treb-parser/src/csv-parser.ts +122 -0
  195. package/treb-parser/src/index.ts +25 -0
  196. package/treb-parser/src/md-parser.ts +526 -0
  197. package/treb-parser/src/parser-types.ts +397 -0
  198. package/treb-parser/src/parser.test.ts +298 -0
  199. package/treb-parser/src/parser.ts +2673 -0
  200. package/treb-utils/package.json +5 -0
  201. package/treb-utils/src/dispatch.ts +57 -0
  202. package/treb-utils/src/event_source.ts +147 -0
  203. package/treb-utils/src/ievent_source.ts +33 -0
  204. package/treb-utils/src/index.ts +31 -0
  205. package/treb-utils/src/measurement.ts +174 -0
  206. package/treb-utils/src/resizable.ts +160 -0
  207. package/treb-utils/src/scale.ts +137 -0
  208. package/treb-utils/src/serialize_html.ts +124 -0
  209. package/treb-utils/src/template.ts +70 -0
  210. package/treb-utils/src/validate_uri.ts +61 -0
  211. package/tsconfig.json +10 -0
  212. package/tsproject.json +30 -0
  213. package/util/license-plugin-esbuild.js +86 -0
  214. package/util/list-css-vars.sh +46 -0
  215. package/README-esm.md +0 -37
  216. package/treb-bundle.css +0 -2
  217. package/treb-bundle.mjs +0 -15
@@ -0,0 +1,336 @@
1
+ // @ts-check
2
+
3
+ import * as esbuild from 'esbuild';
4
+ import { promises as fs } from 'fs';
5
+ import { minify } from 'html-minifier';
6
+ import path from 'path';
7
+ import sass from 'sass';
8
+ import cssnano from 'cssnano';
9
+ import postcss from 'postcss';
10
+
11
+ import pkg from './package.json' assert { type: 'json' };
12
+
13
+ /** @type {import('html-minifier').Options} */
14
+ const html_minifier_options = {
15
+ removeComments: true,
16
+ collapseWhitespace: true,
17
+ };
18
+
19
+ /**
20
+ * @typedef {Object} Options
21
+ * @property {'dev'|'production'} version
22
+ * @property {boolean} watch
23
+ * @property {boolean} verbose - log all plugin inputs. helpful for dev/debug.
24
+ * @property {boolean} minify - separate from dev/production, in case we need to test
25
+ */
26
+
27
+ /**
28
+ * @type {Options}
29
+ *
30
+ * defaults to production, we will update from any options
31
+ * passed at command line.
32
+ */
33
+ const options = {
34
+ version: 'production',
35
+ watch: false,
36
+ minify: true,
37
+ verbose: false,
38
+ };
39
+
40
+ /**
41
+ * @function
42
+ * @param {string} [label] - optional label for build messages
43
+ * @returns {esbuild.Plugin}
44
+ *
45
+ * add notifications on build start/end. we also want to use this
46
+ * to notify worker sub-builds, so we can be sure they're working
47
+ * properly.
48
+ */
49
+ const NotifyPlugin = (label) => {
50
+ return {
51
+ name: 'notify',
52
+ setup(build) {
53
+ build.onStart(() => {
54
+ console.info(`${label ? `${label} ` : ''}build started @ ${new Date().toLocaleTimeString()}`);
55
+ });
56
+ build.onEnd(result => {
57
+ if (!result.errors.length) {
58
+ console.info(`${label ? `${label} ` : ''}build complete @ ${new Date().toLocaleTimeString()}`);
59
+ }
60
+ if (!label) {
61
+ console.info('');
62
+ }
63
+ });
64
+ },
65
+ };
66
+ };
67
+
68
+ /**
69
+ * @function
70
+ * @param {number} size - size in bytes
71
+ * @returns {string} - size as a human readable string
72
+ */
73
+ const FormatSize = (size) => {
74
+
75
+ const units = ['B', 'KB', 'MB'];
76
+ let index = 0;
77
+
78
+ for (let i = 0; i < units.length; i++) {
79
+ if (size > 1024) {
80
+ size = size / 1024;
81
+ index++;
82
+ }
83
+ }
84
+
85
+ return `${size.toFixed(1)} ${units[index]}`;
86
+
87
+ };
88
+
89
+ /**
90
+ * @type esbuild.Plugin
91
+ *
92
+ * inlining the worker build. this works out well with one limitation:
93
+ * at the moment, we're not caching the build for watching. OTOH esbuild
94
+ * is so fast it doesn't really matter at the moment.
95
+ *
96
+ * if you import a worker script like this
97
+ * ```
98
+ * import worker_script from 'worker:path/to/worker.ts';
99
+ * ```
100
+ * the plugin will compile the target (with esbuild) and then return the
101
+ * compiled script as a string. the child build inherits minify settings
102
+ * from the parent build.
103
+ *
104
+ * you can then use it in the containing script by creating a worker:
105
+ * ```
106
+ * const worker = new Worker(URL.createObjectURL(new Blob([worker_script], { type: 'application/javascript' })));
107
+ * ```
108
+ *
109
+ * this might cause problems with CSP. if so, we'll sort that out separately.
110
+ *
111
+ */
112
+ const worker_plugin = {
113
+ name: 'worker',
114
+ setup(build) {
115
+
116
+ build.onResolve({ filter: /^worker:/}, async (args) => {
117
+ args.path = args.path.substring(7);
118
+ const result = await build.resolve(args.path, {
119
+ kind: args.kind,
120
+ resolveDir: args.resolveDir,
121
+ });
122
+ return { path: result.path, namespace: 'worker', };
123
+ }),
124
+
125
+ // for some reason I can't get the filter to work here, but using
126
+ // namespace works. as long as we don't collide with anybody else.
127
+ //
128
+ // with the assumption that esbuild will eventually have a solution
129
+ // for inlining workers, we might want to use a more distinctive
130
+ // namespace that has less possibility of collision in the future.
131
+ // of course if that happens we will probably use the native version,
132
+ // so maybe it doesn't matter.
133
+
134
+ build.onLoad({ filter: /./, namespace: 'worker' }, async(args) => {
135
+
136
+ if (options.verbose) {
137
+ console.info('worker:', args.path);
138
+ }
139
+
140
+ try {
141
+
142
+ const result = await esbuild.build({
143
+
144
+ entryPoints: [ args.path ],
145
+
146
+ // we can use this as a key later
147
+ outfile: 'worker',
148
+
149
+ // inherit options
150
+ minify: options.minify,
151
+ bundle: true,
152
+ format: 'esm',
153
+
154
+ // don't write to filesystem
155
+ write: false,
156
+
157
+ // use the metafile to get deps
158
+ metafile: true,
159
+
160
+ // write to stdout
161
+ plugins: [
162
+ NotifyPlugin('- worker'),
163
+ ],
164
+
165
+ });
166
+
167
+ if (options.verbose) {
168
+ console.info(' worker build size: ' + FormatSize(result.outputFiles[0].text.length));
169
+ }
170
+
171
+ // here's where we use that name as a key
172
+
173
+ const inputs = result.metafile.outputs['worker'].inputs;
174
+ const watchFiles = Object.keys(inputs).map(relative => path.resolve(relative));
175
+
176
+ return {
177
+ errors: result.errors,
178
+ warnings: result.warnings,
179
+ loader: 'text',
180
+ contents: result.outputFiles[0].text,
181
+ watchFiles,
182
+ }
183
+
184
+ }
185
+ catch (err) {
186
+
187
+ // on error, we pass the file that threw as a dependency so we can
188
+ // watch updates and trigger a rebuild (nice that this works, btw)
189
+
190
+ const watchFiles = [];
191
+ for (const error of err.errors) {
192
+ if (error.location?.file) {
193
+ watchFiles.push(path.resolve(error.location.file));
194
+ }
195
+ }
196
+ return {
197
+ errors: err.errors,
198
+ watchFiles,
199
+ };
200
+
201
+ }
202
+
203
+ });
204
+ }
205
+ };
206
+
207
+ /**
208
+ * @type esbuild.Plugin
209
+ *
210
+ * html -> string, optionally minified
211
+ */
212
+ const html_plugin = {
213
+ name: 'html',
214
+ setup(build) {
215
+ build.onLoad({ filter: /\.html$/ }, async (args) => {
216
+
217
+ if (options.verbose) {
218
+ console.info('html:', args.path);
219
+ }
220
+
221
+ const text = await fs.readFile(args.path, 'utf8');
222
+ return {
223
+ contents: options.minify ? minify(text, html_minifier_options) : text,
224
+ loader: 'text',
225
+ };
226
+ });
227
+ },
228
+ };
229
+
230
+ /**
231
+ * @type esbuild.Plugin
232
+ *
233
+ * sass -> string, optionally minified
234
+ */
235
+ const sass_plugin = {
236
+ name: 'sass',
237
+ setup(build) {
238
+ build.onLoad({ filter: /\.scss$/ }, async (args) => {
239
+
240
+ if (options.verbose) {
241
+ console.info('sass:', args.path);
242
+ }
243
+
244
+ try {
245
+
246
+ const result = await sass.compile(args.path, {
247
+ loadPaths: ['.'],
248
+ // charset: false,
249
+ // style: 'compressed',
250
+ });
251
+ const files = (result.loadedUrls || []).map(url => url.pathname);
252
+
253
+ let contents = result.css;
254
+ if (options.minify) {
255
+ const minified = await postcss([cssnano]).process(result.css, { from: undefined });
256
+ contents = minified.css;
257
+ }
258
+
259
+ return {
260
+ contents,
261
+ loader: 'text',
262
+ watchFiles: files,
263
+ };
264
+
265
+ }
266
+ catch (err) {
267
+ const watchFiles = [];
268
+ if (err.span?.file?.url?.path) {
269
+ watchFiles.push(path.resolve(err.span.file.url.path));
270
+ }
271
+ return {
272
+ errors: [{
273
+ text: err.message,
274
+ // ...location...
275
+ }],
276
+ watchFiles,
277
+ }
278
+ }
279
+
280
+ });
281
+ },
282
+ };
283
+
284
+ //------------------------------------------------------------------------------
285
+ //
286
+ // runtime
287
+ //
288
+ //------------------------------------------------------------------------------
289
+
290
+ for (let i = 0; i < process.argv.length; i++) {
291
+ if (process.argv[i] === '--dev') {
292
+ options.version = 'dev';
293
+ options.minify = false;
294
+ }
295
+ if (process.argv[i] === '--watch') {
296
+ options.watch = true;
297
+ }
298
+ if (process.argv[i] === '--verbose') {
299
+ options.verbose = true;
300
+ }
301
+ }
302
+
303
+ /** @type esbuild.BuildOptions */
304
+ const build_options = {
305
+ entryPoints: [
306
+ 'treb-embed/src/index.ts',
307
+ ],
308
+ banner: {
309
+ js: `/*! TREB v${pkg.version}. Copyright 2018-${new Date().getFullYear()} trebco, llc. All rights reserved. LGPL: https://treb.app/license */`
310
+ },
311
+ bundle: true,
312
+ outfile: 'build/treb-spreadsheet.mjs',
313
+ outExtension: { '.js': '.mjs' },
314
+ minify: options.minify,
315
+ metafile: true,
316
+ format: 'esm',
317
+ define: {
318
+ 'process.env.NODE_ENV': `"${options.version}"`,
319
+ 'process.env.BUILD_VERSION': `"${pkg.version}"`,
320
+ 'process.env.BUILD_NAME': `"${pkg.name}"`,
321
+ },
322
+ plugins: [
323
+ NotifyPlugin(),
324
+ worker_plugin,
325
+ html_plugin,
326
+ sass_plugin,
327
+ ],
328
+ };
329
+
330
+ if (options.watch) {
331
+ const context = await esbuild.context(build_options);
332
+ await context.watch();
333
+ }
334
+ else {
335
+ await esbuild.build(build_options);
336
+ }
package/esbuild.js ADDED
@@ -0,0 +1,305 @@
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
+
3
+ const esbuild = require('esbuild');
4
+ const path = require('path');
5
+ const sass_plugin = require('esbuild-sass-plugin');
6
+ const package = require('./package.json');
7
+ const template_compressor = require('./util/template-compressor-esbuild');
8
+ const fs = require('fs');
9
+ const child_process = require('child_process');
10
+ const postcss = require('postcss');
11
+ const cssnano = require('cssnano');
12
+ const license_plugin = require('./util/license-plugin-esbuild');
13
+
14
+
15
+ // ---- command line -----------------------------------------------------------
16
+
17
+ /**
18
+ * versions. note that the module version (mjs) still needs worker files,
19
+ * but those should be compiled normally -- so we use the modern version,
20
+ * but we don't rebuild them. that means if you want to build and use the
21
+ * module version you will need to build the modern version to get the workers.
22
+ */
23
+ const version = {
24
+ modern: false,
25
+ module: false,
26
+ };
27
+
28
+
29
+ /** clean outdir, jic */
30
+ let clean = false;
31
+
32
+ /** prod: minify, generate license file (now default) */
33
+ let production = true;
34
+
35
+ /** watch and rebuild */
36
+ let watch = false;
37
+
38
+ /** write license file (usually only necessary for prod) */
39
+ let license = false;
40
+
41
+ /** write metafile (for dev) */
42
+ let metafile = false;
43
+
44
+ /** embed worker (for esm) */
45
+ let embed_worker = false;
46
+
47
+ for (let i = 0; i < process.argv.length; i++) {
48
+ if (process.argv[i] === '--dev') {
49
+ production = false;
50
+ // license = true; // implied
51
+ }
52
+ else if (process.argv[i] === '--license') {
53
+ license = true;
54
+ }
55
+ else if (process.argv[i] === '--watch') {
56
+ watch = true;
57
+ }
58
+ else if (process.argv[i] === '--clean') {
59
+ clean = true;
60
+ }
61
+ else if (process.argv[i] === '--embed-worker') {
62
+ embed_worker = true;
63
+ }
64
+ else if (process.argv[i] === '--modern') {
65
+ version.modern = true;
66
+ }
67
+ else if (process.argv[i] === '--module') {
68
+ version.module = true;
69
+ }
70
+ else if (process.argv[i] === '--metafile') {
71
+ metafile = true;
72
+ }
73
+ else if (/^-/.test(process.argv[i])){
74
+ console.warn('Unrecognized option: ' + process.argv[i]);
75
+ }
76
+ }
77
+
78
+ if (production) {
79
+ license = true; // implied
80
+ }
81
+
82
+ const version_str = production ? 'production' : 'dev';
83
+
84
+ // default to modern if nothing else is set
85
+ if (!version.modern && !version.module) {
86
+ version.modern = true;
87
+ }
88
+
89
+ // can only watch one at a time (why?)
90
+ if (watch) {
91
+ let count = 0;
92
+ if (version.modern) { count++; }
93
+ if (version.module) { count++; }
94
+ if (count > 1) {
95
+ throw new Error('can only watch one at a time');
96
+ }
97
+ }
98
+
99
+ // ---- setup/data -------------------------------------------------------------
100
+
101
+ /**
102
+ * banner will be prepended to any and all output files
103
+ */
104
+ const banner =
105
+ `/*! TREB v${package.version}. Copyright 2018-${new Date().getFullYear()} trebco, llc. All rights reserved. LGPL: https://treb.app/license */` ;
106
+
107
+ /**
108
+ * entry points for module build, keyed by output file name
109
+ */
110
+ const module_entry = {
111
+ [package['build-entry-points']['main']]: './treb-embed/src/index-module.ts',
112
+ };
113
+
114
+ /**
115
+ * entry points for regular build, keyed by output file name
116
+ */
117
+ const modern_entry = {
118
+ [package['build-entry-points']['main']]: './treb-embed/src/index-modern.ts',
119
+ [package['build-entry-points']['export-worker'] + '-' + package.version]: './treb-export/src/export-worker/index-modern.ts',
120
+ };
121
+
122
+ /**
123
+ * list of replacements, will be set via DEFINE (very handy)
124
+ */
125
+ const build_entry_replacements = {};
126
+
127
+ for (const key of Object.keys(package['build-entry-points'])) {
128
+ const text = `process.env.BUILD_ENTRY_${key.replace(/\W/g, '_').toUpperCase()}`;
129
+ build_entry_replacements[text] = `"${package['build-entry-points'][key]}"`;
130
+ }
131
+
132
+ /**
133
+ * configure the sass plugin. because minifying post-plugin does not work for
134
+ * some reason, we can use cssnano to do the same. only do that for prod.
135
+ */
136
+ const sass_style = sass_plugin.sassPlugin(production ? {
137
+ type: 'style',
138
+ async transform(source) {
139
+ const {css} = await postcss([cssnano]).process(source, { from: undefined });
140
+ return css;
141
+ }
142
+ } : {
143
+ type: 'style',
144
+ });
145
+
146
+ const sass_default = sass_plugin.sassPlugin();
147
+
148
+ /** outdir */
149
+ const outdir_parent = 'build';
150
+ let outdir = '';
151
+
152
+ // ----
153
+
154
+ const LoadPlugin = (options) => {
155
+
156
+ return {
157
+ name: 'load-plugin',
158
+ setup(build) {
159
+ build.onLoad({ filter: /\.ts$/ }, async (args) => {
160
+
161
+ let text = await fs.promises.readFile(args.path, 'utf8')
162
+ let contents = template_compressor.transform(options, text);
163
+
164
+ return {
165
+ contents,
166
+ loader: 'ts',
167
+ };
168
+
169
+ })
170
+ },
171
+ };
172
+
173
+ };
174
+
175
+ // ----
176
+
177
+ const GenerateConfig = (version) => {
178
+
179
+ let worker_text = '';
180
+ if (version === 'module' && embed_worker) {
181
+ try {
182
+ worker_text = fs.readFileSync(`build/current/treb-export-worker-${package.version}.js`, {encoding: 'utf-8'});
183
+ }
184
+ catch (err) {
185
+ console.error('\n** embedding worker failed. make sure the worker for this version exists before building module.\n');
186
+ throw err;
187
+ }
188
+ }
189
+
190
+ const config = {
191
+
192
+ metafile: metafile||license, // only if necessary
193
+ watch: watch ? {
194
+ onRebuild(error, result) {
195
+ if (error) console.error('watch build failed:', error)
196
+ else console.log('watch build succeeded:', result)
197
+ },
198
+ } : undefined,
199
+ minify: !!production,
200
+ banner: {
201
+ js: banner,
202
+ css: banner,
203
+ },
204
+ define: {
205
+ 'process.env.WORKER_TEXT': worker_text ? JSON.stringify(worker_text) :`""`,
206
+ 'process.env.NODE_ENV': `"${version_str}"`,
207
+ 'process.env.BUILD_VERSION': `"${package.version}"`,
208
+ 'process.env.BUILD_NAME': `"${package.name}"`,
209
+ ...build_entry_replacements,
210
+ },
211
+ bundle: true,
212
+ tsconfig: './treb-embed/modern.tsconfig.json',
213
+ plugins: [
214
+ LoadPlugin({
215
+ tags: [
216
+ { tag: 'tmpl',
217
+ trim_lines: true,
218
+ remove_html_comments: true,
219
+ icons: {
220
+ tag: 'icon',
221
+ dir: path.resolve(__dirname, 'treb-embed', 'icons', '4'),
222
+ },
223
+ },
224
+ { tag: 'composite', trim_lines: true, remove_tag: true, },
225
+ { tag: 'css', remove_whitespace: true, remove_tag: true, },
226
+ ],
227
+ version,
228
+ }),
229
+ ],
230
+ outdir : version === 'module' ? path.join(outdir, 'esm') : outdir,
231
+ };
232
+
233
+ switch (version) {
234
+ case 'modern':
235
+ config.entryPoints = modern_entry;
236
+ config.plugins.push(sass_style);
237
+ break;
238
+
239
+ case 'module':
240
+ config.entryPoints = module_entry;
241
+ config.format = 'esm';
242
+ config.outExtension = { '.js': '.mjs' };
243
+ config.plugins.push(sass_default);
244
+ break;
245
+
246
+ }
247
+
248
+
249
+ return config;
250
+
251
+ };
252
+
253
+ // ---- run builder ------------------------------------------------------------
254
+
255
+ const Run = async () => {
256
+
257
+ // writing to "current", and we will copy to versioned dir.
258
+
259
+ outdir = path.join(outdir_parent, 'current');
260
+ await fs.promises.mkdir(outdir, { recursive: true });
261
+
262
+ // FIXME: clean should -r ?
263
+
264
+ if (clean) {
265
+ await new Promise((resolve) => {
266
+ child_process.exec(`rm -r ${path.join(outdir, '*')}`, () => resolve());
267
+ });
268
+ }
269
+
270
+ // modern version includes all support files
271
+
272
+ if (version.modern) {
273
+ console.info(`building modern (${version_str})...`);
274
+ const result = await esbuild.build(GenerateConfig('modern'));
275
+ if (result.metafile) {
276
+ if (metafile) {
277
+ await fs.promises.writeFile(
278
+ path.join(outdir, 'metafile.json'),
279
+ JSON.stringify(result.metafile, undefined, 2), { encoding: 'utf8' });
280
+ }
281
+ if (license) {
282
+ const licenses = await license_plugin.GenerateLicenseFile(result.metafile);
283
+ await fs.promises.writeFile(path.join(outdir, '3d_party.txt'), licenses, { encoding: 'utf8' });
284
+ }
285
+ }
286
+ }
287
+
288
+ // module must be after modern, if we are embedding worker
289
+
290
+ if (version.module) {
291
+ console.info(`building module (${version_str})...`);
292
+ await esbuild.build(GenerateConfig('module'));
293
+ }
294
+
295
+ const versioned_dir = path.join(outdir_parent, package.version);
296
+ await fs.promises.mkdir(versioned_dir, { recursive: true });
297
+
298
+ await new Promise((resolve) => {
299
+ child_process.exec(`cp -r ${path.join(outdir, '*')} ${versioned_dir}`, () => resolve());
300
+ });
301
+
302
+ };
303
+
304
+ Run();
305
+
package/package.json CHANGED
@@ -1,14 +1,49 @@
1
- {
2
- "name": "@trebco/treb",
3
- "version": "23.6.5",
4
- "license": "LGPL-3.0-or-later",
5
- "homepage": "https://treb.app",
6
- "main": "treb-bundle.mjs",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/trebco/treb.git"
10
- },
11
- "type": "module",
12
- "types": "treb.d.ts",
13
- "stylesheet": "treb-bundle.css"
14
- }
1
+ {
2
+ "name": "@trebco/treb",
3
+ "version": "25.0.0-rc2",
4
+ "license": "LGPL-3.0-or-later",
5
+ "homepage": "https://treb.app",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/trebco/treb.git"
9
+ },
10
+ "main": "build/treb-spreadsheet.mjs",
11
+ "types": "build/treb.d.ts",
12
+ "type": "module",
13
+ "devDependencies": {
14
+ "@types/html-minifier": "^4.0.2",
15
+ "@types/node": "^18.15.3",
16
+ "@typescript-eslint/eslint-plugin": "^5.30.4",
17
+ "@typescript-eslint/parser": "^5.30.4",
18
+ "archiver": "^5.3.0",
19
+ "cssnano": "^5.1.5",
20
+ "esbuild": "^0.17.11",
21
+ "eslint": "^8.19.0",
22
+ "fast-xml-parser": "^4.0.7",
23
+ "html-minifier": "^4.0.0",
24
+ "jszip": "^3.6.0",
25
+ "sass": "^1.53.0",
26
+ "treb-base-types": "file:treb-base-types",
27
+ "treb-calculator": "file:treb-calculator",
28
+ "treb-charts": "file:treb-charts",
29
+ "treb-format": "file:treb-format",
30
+ "treb-grid": "file:treb-grid",
31
+ "treb-parser": "file:treb-parser",
32
+ "treb-utils": "file:treb-utils",
33
+ "ts-node-dev": "^2.0.0",
34
+ "tslib": "^2.2.0",
35
+ "typescript": "^4.6.4"
36
+ },
37
+ "scripts": {
38
+ "build": "node esbuild-custom-element.mjs",
39
+ "dev": "node esbuild-custom-element.mjs --dev",
40
+ "clean": "rm -fr build dist declaration",
41
+ "watch": "node --watch esbuild-custom-element.mjs --watch --dev",
42
+ "tsc": "tsc -b treb-embed/modern.tsconfig.json",
43
+ "rebuild-tsc": "tsc -b --force treb-embed/modern.tsconfig.json",
44
+ "watch-tsc": "tsc -b treb-embed/modern.tsconfig.json -w",
45
+ "watch-api": "ts-node-dev --respawn api-generator/api-generator.ts --config api-config.json",
46
+ "generate-api": "ts-node-dev api-generator/api-generator.ts --config api-config.json",
47
+ "release": "npm run rebuild-tsc && npm run build && npm run generate-api"
48
+ }
49
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "treb-base-types",
3
+ "version": "16.0.0",
4
+ "main": "src/index.ts"
5
+ }