@bpmnkit/plugins 0.0.8

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 (140) hide show
  1. package/README.md +153 -0
  2. package/dist/ai-bridge/css.d.ts +2 -0
  3. package/dist/ai-bridge/css.js +366 -0
  4. package/dist/ai-bridge/index.d.ts +44 -0
  5. package/dist/ai-bridge/index.js +132 -0
  6. package/dist/ai-bridge/panel.d.ts +27 -0
  7. package/dist/ai-bridge/panel.js +715 -0
  8. package/dist/ascii-view/css.d.ts +4 -0
  9. package/dist/ascii-view/css.js +83 -0
  10. package/dist/ascii-view/index.d.ts +25 -0
  11. package/dist/ascii-view/index.js +92 -0
  12. package/dist/command-palette/css.d.ts +4 -0
  13. package/dist/command-palette/css.js +157 -0
  14. package/dist/command-palette/index.d.ts +53 -0
  15. package/dist/command-palette/index.js +378 -0
  16. package/dist/command-palette-editor/index.d.ts +35 -0
  17. package/dist/command-palette-editor/index.js +60 -0
  18. package/dist/config-panel/css.d.ts +4 -0
  19. package/dist/config-panel/css.js +719 -0
  20. package/dist/config-panel/index.d.ts +36 -0
  21. package/dist/config-panel/index.js +73 -0
  22. package/dist/config-panel/renderer.d.ts +127 -0
  23. package/dist/config-panel/renderer.js +1162 -0
  24. package/dist/config-panel/types.d.ts +118 -0
  25. package/dist/config-panel/types.js +2 -0
  26. package/dist/config-panel-bpmn/index.d.ts +58 -0
  27. package/dist/config-panel-bpmn/index.js +1320 -0
  28. package/dist/config-panel-bpmn/template-engine.d.ts +17 -0
  29. package/dist/config-panel-bpmn/template-engine.js +307 -0
  30. package/dist/config-panel-bpmn/template-to-service-task.d.ts +30 -0
  31. package/dist/config-panel-bpmn/template-to-service-task.js +92 -0
  32. package/dist/config-panel-bpmn/template-types.d.ts +126 -0
  33. package/dist/config-panel-bpmn/template-types.js +6 -0
  34. package/dist/config-panel-bpmn/templates/generated.d.ts +3 -0
  35. package/dist/config-panel-bpmn/templates/generated.js +57865 -0
  36. package/dist/config-panel-bpmn/util.d.ts +46 -0
  37. package/dist/config-panel-bpmn/util.js +195 -0
  38. package/dist/dmn-editor/css.d.ts +3 -0
  39. package/dist/dmn-editor/css.js +667 -0
  40. package/dist/dmn-editor/dmn-editor.d.ts +34 -0
  41. package/dist/dmn-editor/dmn-editor.js +646 -0
  42. package/dist/dmn-editor/drd-canvas.d.ts +85 -0
  43. package/dist/dmn-editor/drd-canvas.js +1087 -0
  44. package/dist/dmn-editor/index.d.ts +3 -0
  45. package/dist/dmn-editor/index.js +2 -0
  46. package/dist/dmn-viewer/css.d.ts +3 -0
  47. package/dist/dmn-viewer/css.js +151 -0
  48. package/dist/dmn-viewer/dmn-viewer.d.ts +30 -0
  49. package/dist/dmn-viewer/dmn-viewer.js +160 -0
  50. package/dist/dmn-viewer/feel.d.ts +3 -0
  51. package/dist/dmn-viewer/feel.js +2 -0
  52. package/dist/dmn-viewer/index.d.ts +14 -0
  53. package/dist/dmn-viewer/index.js +12 -0
  54. package/dist/element-docs/content.d.ts +20 -0
  55. package/dist/element-docs/content.js +1032 -0
  56. package/dist/element-docs/index.d.ts +7 -0
  57. package/dist/element-docs/index.js +643 -0
  58. package/dist/feel-playground/css.d.ts +4 -0
  59. package/dist/feel-playground/css.js +292 -0
  60. package/dist/feel-playground/index.d.ts +4 -0
  61. package/dist/feel-playground/index.js +3 -0
  62. package/dist/feel-playground/playground-plugin.d.ts +14 -0
  63. package/dist/feel-playground/playground-plugin.js +292 -0
  64. package/dist/form-editor/css.d.ts +3 -0
  65. package/dist/form-editor/css.js +703 -0
  66. package/dist/form-editor/form-editor.d.ts +48 -0
  67. package/dist/form-editor/form-editor.js +1039 -0
  68. package/dist/form-editor/index.d.ts +3 -0
  69. package/dist/form-editor/index.js +2 -0
  70. package/dist/form-viewer/css.d.ts +3 -0
  71. package/dist/form-viewer/css.js +303 -0
  72. package/dist/form-viewer/form-viewer.d.ts +29 -0
  73. package/dist/form-viewer/form-viewer.js +376 -0
  74. package/dist/form-viewer/index.d.ts +12 -0
  75. package/dist/form-viewer/index.js +11 -0
  76. package/dist/history/checkpoint.d.ts +10 -0
  77. package/dist/history/checkpoint.js +92 -0
  78. package/dist/history/css.d.ts +2 -0
  79. package/dist/history/css.js +130 -0
  80. package/dist/history/history-panel.d.ts +12 -0
  81. package/dist/history/history-panel.js +142 -0
  82. package/dist/history/index.d.ts +5 -0
  83. package/dist/history/index.js +3 -0
  84. package/dist/main-menu/css.d.ts +4 -0
  85. package/dist/main-menu/css.js +272 -0
  86. package/dist/main-menu/index.d.ts +59 -0
  87. package/dist/main-menu/index.js +285 -0
  88. package/dist/minimap/css.d.ts +10 -0
  89. package/dist/minimap/css.js +54 -0
  90. package/dist/minimap/index.d.ts +38 -0
  91. package/dist/minimap/index.js +69 -0
  92. package/dist/minimap/minimap.d.ts +35 -0
  93. package/dist/minimap/minimap.js +166 -0
  94. package/dist/optimize/index.d.ts +21 -0
  95. package/dist/optimize/index.js +304 -0
  96. package/dist/process-runner/css.d.ts +2 -0
  97. package/dist/process-runner/css.js +467 -0
  98. package/dist/process-runner/index.d.ts +56 -0
  99. package/dist/process-runner/index.js +549 -0
  100. package/dist/storage/auto-save.d.ts +11 -0
  101. package/dist/storage/auto-save.js +44 -0
  102. package/dist/storage/css.d.ts +2 -0
  103. package/dist/storage/css.js +2 -0
  104. package/dist/storage/db.d.ts +99 -0
  105. package/dist/storage/db.js +116 -0
  106. package/dist/storage/dialog.d.ts +15 -0
  107. package/dist/storage/dialog.js +201 -0
  108. package/dist/storage/export.d.ts +3 -0
  109. package/dist/storage/export.js +137 -0
  110. package/dist/storage/index.d.ts +44 -0
  111. package/dist/storage/index.js +201 -0
  112. package/dist/storage/sidebar.d.ts +2 -0
  113. package/dist/storage/sidebar.js +2 -0
  114. package/dist/storage/storage-api.d.ts +76 -0
  115. package/dist/storage/storage-api.js +342 -0
  116. package/dist/storage/types.d.ts +44 -0
  117. package/dist/storage/types.js +2 -0
  118. package/dist/storage-tabs-bridge/index.d.ts +96 -0
  119. package/dist/storage-tabs-bridge/index.js +502 -0
  120. package/dist/tabs/css.d.ts +3 -0
  121. package/dist/tabs/css.js +642 -0
  122. package/dist/tabs/file-resolver.d.ts +71 -0
  123. package/dist/tabs/file-resolver.js +46 -0
  124. package/dist/tabs/index.d.ts +15 -0
  125. package/dist/tabs/index.js +13 -0
  126. package/dist/tabs/tabs-plugin.d.ts +250 -0
  127. package/dist/tabs/tabs-plugin.js +1119 -0
  128. package/dist/token-highlight/css.d.ts +2 -0
  129. package/dist/token-highlight/css.js +81 -0
  130. package/dist/token-highlight/index.d.ts +44 -0
  131. package/dist/token-highlight/index.js +164 -0
  132. package/dist/watermark/css.d.ts +10 -0
  133. package/dist/watermark/css.js +54 -0
  134. package/dist/watermark/index.d.ts +48 -0
  135. package/dist/watermark/index.js +64 -0
  136. package/dist/zoom-controls/css.d.ts +4 -0
  137. package/dist/zoom-controls/css.js +48 -0
  138. package/dist/zoom-controls/index.d.ts +36 -0
  139. package/dist/zoom-controls/index.js +111 -0
  140. package/package.json +121 -0
@@ -0,0 +1,376 @@
1
+ import { injectFormViewerStyles } from "./css.js";
2
+ /**
3
+ * Standalone read-only Camunda Form viewer.
4
+ *
5
+ * Renders a `FormDefinition` as a static HTML preview of all component types.
6
+ * Does not depend on `@bpmnkit/canvas`.
7
+ */
8
+ export class FormViewer {
9
+ _container;
10
+ _root;
11
+ _theme;
12
+ _form = null;
13
+ constructor(options) {
14
+ this._container = options.container;
15
+ this._theme = options.theme ?? "dark";
16
+ injectFormViewerStyles();
17
+ this._root = document.createElement("div");
18
+ this._root.className = `form-viewer ${this._theme}`;
19
+ this._container.appendChild(this._root);
20
+ }
21
+ /** Load and render a FormDefinition. */
22
+ load(form) {
23
+ this._form = form;
24
+ this._render();
25
+ }
26
+ /** Clear the view. */
27
+ clear() {
28
+ this._form = null;
29
+ this._root.innerHTML = "";
30
+ }
31
+ /** Set the theme. */
32
+ setTheme(theme) {
33
+ this._root.classList.remove(this._theme);
34
+ this._theme = theme;
35
+ this._root.classList.add(theme);
36
+ }
37
+ /** Remove the viewer from the DOM. */
38
+ destroy() {
39
+ this._root.remove();
40
+ }
41
+ _render() {
42
+ if (!this._form)
43
+ return;
44
+ this._root.innerHTML = "";
45
+ const body = document.createElement("div");
46
+ body.className = "form-viewer-body";
47
+ renderComponents(this._form.components, body);
48
+ this._root.appendChild(body);
49
+ }
50
+ }
51
+ /** Group components by their layout.row, preserving order. */
52
+ function groupByRow(components) {
53
+ const rows = [];
54
+ const rowMap = new Map();
55
+ for (const c of components) {
56
+ const rowKey = c.layout?.row ?? `__solo_${c.id}`;
57
+ let row = rowMap.get(rowKey);
58
+ if (!row) {
59
+ row = [];
60
+ rowMap.set(rowKey, row);
61
+ rows.push(row);
62
+ }
63
+ row.push(c);
64
+ }
65
+ return rows;
66
+ }
67
+ function renderComponents(components, parent) {
68
+ const rows = groupByRow(components);
69
+ for (const row of rows) {
70
+ const rowEl = document.createElement("div");
71
+ rowEl.className = "fv-row";
72
+ for (const c of row) {
73
+ const wrapper = document.createElement("div");
74
+ wrapper.className = "fv-field";
75
+ if (c.layout?.columns !== null && c.layout?.columns !== undefined) {
76
+ wrapper.style.flex = `0 0 calc(${c.layout.columns} / 12 * 100% - 6px)`;
77
+ }
78
+ renderComponent(c, wrapper);
79
+ rowEl.appendChild(wrapper);
80
+ }
81
+ parent.appendChild(rowEl);
82
+ }
83
+ }
84
+ function renderComponent(c, parent) {
85
+ // Cast to specific type in each case because FormUnknownComponent's index signature
86
+ // prevents TypeScript from narrowing properties via the discriminant alone.
87
+ const type = c.type;
88
+ switch (type) {
89
+ case "text":
90
+ renderText(c, parent);
91
+ break;
92
+ case "textfield":
93
+ renderTextField(c.label, "Text…", parent);
94
+ break;
95
+ case "textarea":
96
+ renderTextarea(c.label, "Text…", parent);
97
+ break;
98
+ case "number":
99
+ renderTextField(c.label, "0", parent);
100
+ break;
101
+ case "datetime":
102
+ renderDatetime(c, parent);
103
+ break;
104
+ case "select": {
105
+ const s = c;
106
+ renderSelect(s.label, s.values ?? [], parent);
107
+ break;
108
+ }
109
+ case "radio": {
110
+ const r = c;
111
+ renderChoices(r.label, r.values ?? [], "radio", parent);
112
+ break;
113
+ }
114
+ case "checkbox":
115
+ renderCheckbox(c.label, parent);
116
+ break;
117
+ case "checklist": {
118
+ const cl = c;
119
+ renderChoices(cl.label, cl.values ?? [], "checklist", parent);
120
+ break;
121
+ }
122
+ case "taglist": {
123
+ const tl = c;
124
+ renderTaglist(tl.label, tl.values ?? [], parent);
125
+ break;
126
+ }
127
+ case "button":
128
+ renderButton(c.label, parent);
129
+ break;
130
+ case "group": {
131
+ const g = c;
132
+ renderGroup(g.label, g.components, parent);
133
+ break;
134
+ }
135
+ case "dynamiclist": {
136
+ const dl = c;
137
+ renderDynamicList(dl.label, dl.components, parent);
138
+ break;
139
+ }
140
+ case "table": {
141
+ const t = c;
142
+ renderTable(t.label, t.columns ?? [], parent);
143
+ break;
144
+ }
145
+ case "image":
146
+ renderImage(c.alt, parent);
147
+ break;
148
+ case "iframe": {
149
+ const iframe = c;
150
+ renderIframe(iframe.label, iframe.url, parent);
151
+ break;
152
+ }
153
+ case "separator":
154
+ parent.appendChild(document.createElement("hr")).className = "fv-separator";
155
+ break;
156
+ case "spacer": {
157
+ const spacer = document.createElement("div");
158
+ spacer.className = "fv-spacer";
159
+ spacer.style.height = `${c.height ?? 20}px`;
160
+ parent.appendChild(spacer);
161
+ break;
162
+ }
163
+ case "documentPreview":
164
+ renderDocumentPreview(c.label, parent);
165
+ break;
166
+ case "html":
167
+ renderHtml(c.content, parent);
168
+ break;
169
+ case "expression":
170
+ renderExpression(c.expression, parent);
171
+ break;
172
+ case "filepicker":
173
+ renderFilepicker(c.label, parent);
174
+ break;
175
+ default:
176
+ renderUnknown(type, parent);
177
+ }
178
+ }
179
+ function label(text) {
180
+ const el = document.createElement("label");
181
+ el.className = "fv-label";
182
+ el.textContent = text;
183
+ return el;
184
+ }
185
+ function renderTextField(labelText, placeholder, parent) {
186
+ parent.appendChild(label(labelText));
187
+ const input = document.createElement("div");
188
+ input.className = "fv-input";
189
+ input.textContent = placeholder;
190
+ parent.appendChild(input);
191
+ }
192
+ function renderTextarea(labelText, placeholder, parent) {
193
+ parent.appendChild(label(labelText));
194
+ const input = document.createElement("div");
195
+ input.className = "fv-input fv-textarea";
196
+ input.textContent = placeholder;
197
+ parent.appendChild(input);
198
+ }
199
+ function renderDatetime(c, parent) {
200
+ parent.appendChild(label("Date / Time"));
201
+ const wrapper = document.createElement("div");
202
+ wrapper.className = "fv-datetime-inputs";
203
+ if (!c.subtype || c.subtype === "date" || c.subtype === "datetime") {
204
+ const d = document.createElement("div");
205
+ d.className = "fv-input";
206
+ d.textContent = c.dateLabel ?? "Date…";
207
+ wrapper.appendChild(d);
208
+ }
209
+ if (c.subtype === "time" || c.subtype === "datetime") {
210
+ const t = document.createElement("div");
211
+ t.className = "fv-input";
212
+ t.textContent = c.timeLabel ?? "Time…";
213
+ wrapper.appendChild(t);
214
+ }
215
+ parent.appendChild(wrapper);
216
+ }
217
+ function renderSelect(labelText, values, parent) {
218
+ parent.appendChild(label(labelText));
219
+ const input = document.createElement("div");
220
+ input.className = "fv-input";
221
+ const first = values[0];
222
+ input.textContent = first ? first.label : "Select…";
223
+ parent.appendChild(input);
224
+ }
225
+ function renderChoices(labelText, values, type, parent) {
226
+ parent.appendChild(label(labelText));
227
+ for (const v of values) {
228
+ const row = document.createElement("div");
229
+ row.className = "fv-option-row";
230
+ const dot = document.createElement("div");
231
+ dot.className = type === "radio" ? "fv-option-dot" : "fv-option-square";
232
+ row.appendChild(dot);
233
+ row.appendChild(document.createTextNode(v.label));
234
+ parent.appendChild(row);
235
+ }
236
+ }
237
+ function renderCheckbox(labelText, parent) {
238
+ const row = document.createElement("div");
239
+ row.className = "fv-option-row";
240
+ const box = document.createElement("div");
241
+ box.className = "fv-option-square";
242
+ row.appendChild(box);
243
+ row.appendChild(document.createTextNode(labelText));
244
+ parent.appendChild(row);
245
+ }
246
+ function renderTaglist(labelText, values, parent) {
247
+ parent.appendChild(label(labelText));
248
+ const tags = document.createElement("div");
249
+ tags.className = "fv-tags";
250
+ for (const v of values.slice(0, 3)) {
251
+ const tag = document.createElement("span");
252
+ tag.className = "fv-tag";
253
+ tag.textContent = v.label;
254
+ tags.appendChild(tag);
255
+ }
256
+ parent.appendChild(tags);
257
+ }
258
+ function renderButton(labelText, parent) {
259
+ const btn = document.createElement("div");
260
+ btn.className = "fv-btn";
261
+ btn.textContent = labelText;
262
+ parent.appendChild(btn);
263
+ }
264
+ function renderGroup(labelText, components, parent) {
265
+ const group = document.createElement("div");
266
+ group.className = "fv-group";
267
+ const groupLabel = document.createElement("div");
268
+ groupLabel.className = "fv-group-label";
269
+ groupLabel.textContent = labelText;
270
+ group.appendChild(groupLabel);
271
+ renderComponents(components, group);
272
+ parent.appendChild(group);
273
+ }
274
+ function renderDynamicList(labelText, components, parent) {
275
+ const dl = document.createElement("div");
276
+ dl.className = "fv-dynamic-list";
277
+ if (labelText) {
278
+ const dlLabel = document.createElement("div");
279
+ dlLabel.className = "fv-dynamic-list-label";
280
+ dlLabel.textContent = labelText;
281
+ dl.appendChild(dlLabel);
282
+ }
283
+ renderComponents(components, dl);
284
+ parent.appendChild(dl);
285
+ }
286
+ function renderTable(labelText, columns, parent) {
287
+ if (labelText)
288
+ parent.appendChild(label(labelText));
289
+ const table = document.createElement("table");
290
+ table.className = "fv-table";
291
+ const thead = document.createElement("thead");
292
+ const tr = document.createElement("tr");
293
+ for (const col of columns) {
294
+ const th = document.createElement("th");
295
+ th.textContent = col.label;
296
+ tr.appendChild(th);
297
+ }
298
+ thead.appendChild(tr);
299
+ table.appendChild(thead);
300
+ // One empty data row as placeholder
301
+ const tbody = document.createElement("tbody");
302
+ const dataRow = document.createElement("tr");
303
+ for (const _ of columns) {
304
+ const td = document.createElement("td");
305
+ td.innerHTML = " ";
306
+ dataRow.appendChild(td);
307
+ }
308
+ tbody.appendChild(dataRow);
309
+ table.appendChild(tbody);
310
+ parent.appendChild(table);
311
+ }
312
+ function renderImage(alt, parent) {
313
+ const el = document.createElement("div");
314
+ el.className = "fv-image";
315
+ el.textContent = alt ? `[Image: ${alt}]` : "[Image]";
316
+ parent.appendChild(el);
317
+ }
318
+ function renderIframe(labelText, url, parent) {
319
+ const el = document.createElement("div");
320
+ el.className = "fv-iframe";
321
+ el.textContent = labelText ? `[iFrame: ${labelText}]` : url ? `[iFrame: ${url}]` : "[iFrame]";
322
+ parent.appendChild(el);
323
+ }
324
+ function renderDocumentPreview(labelText, parent) {
325
+ const el = document.createElement("div");
326
+ el.className = "fv-document-preview";
327
+ el.textContent = labelText ? `[Document: ${labelText}]` : "[Document Preview]";
328
+ parent.appendChild(el);
329
+ }
330
+ function renderHtml(content, parent) {
331
+ const el = document.createElement("div");
332
+ el.className = "fv-html";
333
+ // Safe: we trust the form definition content (designer-authored, not user input)
334
+ el.innerHTML = content ?? "";
335
+ parent.appendChild(el);
336
+ }
337
+ function renderExpression(expression, parent) {
338
+ const el = document.createElement("div");
339
+ el.className = "fv-expression";
340
+ el.textContent = expression ? `= ${expression}` : "= …";
341
+ parent.appendChild(el);
342
+ }
343
+ function renderFilepicker(labelText, parent) {
344
+ if (labelText)
345
+ parent.appendChild(label(labelText));
346
+ const input = document.createElement("div");
347
+ input.className = "fv-input";
348
+ input.textContent = "Choose file…";
349
+ parent.appendChild(input);
350
+ }
351
+ function renderText(c, parent) {
352
+ const el = document.createElement("div");
353
+ el.className = "fv-text";
354
+ // Convert minimal markdown: # headings, **bold**, *italic*
355
+ el.innerHTML = minimalMarkdown(c.text ?? "");
356
+ parent.appendChild(el);
357
+ }
358
+ function renderUnknown(type, parent) {
359
+ const el = document.createElement("div");
360
+ el.className = "fv-input";
361
+ el.textContent = `[${type}]`;
362
+ parent.appendChild(el);
363
+ }
364
+ /** Very minimal markdown: headers, bold, italic. */
365
+ function minimalMarkdown(md) {
366
+ return md
367
+ .replace(/&/g, "&")
368
+ .replace(/</g, "&lt;")
369
+ .replace(/^### (.+)$/gm, "<h3>$1</h3>")
370
+ .replace(/^## (.+)$/gm, "<h2>$1</h2>")
371
+ .replace(/^# (.+)$/gm, "<h1>$1</h1>")
372
+ .replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
373
+ .replace(/\*(.+?)\*/g, "<em>$1</em>")
374
+ .replace(/\n/g, "<br>");
375
+ }
376
+ //# sourceMappingURL=form-viewer.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @bpmnkit/canvas-plugin-form-viewer — read-only Camunda Form viewer.
3
+ *
4
+ * Renders all Camunda Form component types as a static HTML preview.
5
+ * Built entirely in-repo — no dependency on @bpmnkit-io/form-js.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { FormViewer } from "./form-viewer.js";
10
+ export type { FormViewerOptions } from "./form-viewer.js";
11
+ export { FORM_VIEWER_CSS, injectFormViewerStyles } from "./css.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @bpmnkit/canvas-plugin-form-viewer — read-only Camunda Form viewer.
3
+ *
4
+ * Renders all Camunda Form component types as a static HTML preview.
5
+ * Built entirely in-repo — no dependency on @bpmnkit-io/form-js.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { FormViewer } from "./form-viewer.js";
10
+ export { FORM_VIEWER_CSS, injectFormViewerStyles } from "./css.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ export interface Checkpoint {
2
+ id: string;
3
+ projectId: string;
4
+ fileId: string;
5
+ timestamp: number;
6
+ xml: string;
7
+ }
8
+ export declare function saveCheckpoint(projectId: string, fileId: string, xml: string): Promise<void>;
9
+ export declare function listCheckpoints(projectId: string, fileId: string): Promise<Checkpoint[]>;
10
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1,92 @@
1
+ const DB_NAME = "bpmnkit-ai";
2
+ const STORE = "checkpoints";
3
+ const MAX_TODAY = 50;
4
+ const HISTORICAL_DAYS = 10;
5
+ function openDb() {
6
+ return new Promise((resolve, reject) => {
7
+ const req = indexedDB.open(DB_NAME, 1);
8
+ req.onupgradeneeded = () => {
9
+ const db = req.result;
10
+ if (!db.objectStoreNames.contains(STORE)) {
11
+ const store = db.createObjectStore(STORE, { keyPath: "id" });
12
+ store.createIndex("byFile", ["projectId", "fileId"], { unique: false });
13
+ store.createIndex("byTimestamp", "timestamp", { unique: false });
14
+ }
15
+ };
16
+ req.onsuccess = () => resolve(req.result);
17
+ req.onerror = () => reject(req.error);
18
+ });
19
+ }
20
+ export async function saveCheckpoint(projectId, fileId, xml) {
21
+ const db = await openDb();
22
+ return new Promise((resolve, reject) => {
23
+ const tx = db.transaction(STORE, "readwrite");
24
+ const store = tx.objectStore(STORE);
25
+ const getReq = store.index("byFile").getAll(IDBKeyRange.only([projectId, fileId]));
26
+ getReq.onsuccess = () => {
27
+ const existing = getReq.result;
28
+ const todayStart = new Date();
29
+ todayStart.setHours(0, 0, 0, 0);
30
+ const todayMs = todayStart.getTime();
31
+ const cutoffMs = todayMs - HISTORICAL_DAYS * 24 * 60 * 60 * 1000;
32
+ // Today's checkpoints — keep MAX_TODAY - 1 (oldest pruned first)
33
+ const todayOnes = existing
34
+ .filter((cp) => cp.timestamp >= todayMs)
35
+ .sort((a, b) => a.timestamp - b.timestamp);
36
+ for (const cp of todayOnes.slice(0, Math.max(0, todayOnes.length - (MAX_TODAY - 1)))) {
37
+ store.delete(cp.id);
38
+ }
39
+ // Historical checkpoints — keep 1 (latest) per day, prune older than cutoff
40
+ const historical = existing.filter((cp) => cp.timestamp >= cutoffMs && cp.timestamp < todayMs);
41
+ const byDay = new Map();
42
+ for (const cp of historical) {
43
+ const d = new Date(cp.timestamp);
44
+ const key = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
45
+ const arr = byDay.get(key) ?? [];
46
+ arr.push(cp);
47
+ byDay.set(key, arr);
48
+ }
49
+ for (const [, cps] of byDay) {
50
+ const sorted = cps.sort((a, b) => b.timestamp - a.timestamp);
51
+ for (const cp of sorted.slice(1))
52
+ store.delete(cp.id);
53
+ }
54
+ // Delete anything beyond the historical window
55
+ for (const cp of existing.filter((c) => c.timestamp < cutoffMs)) {
56
+ store.delete(cp.id);
57
+ }
58
+ store.add({
59
+ id: crypto.randomUUID(),
60
+ projectId,
61
+ fileId,
62
+ timestamp: Date.now(),
63
+ xml,
64
+ });
65
+ };
66
+ tx.oncomplete = () => {
67
+ db.close();
68
+ resolve();
69
+ };
70
+ tx.onerror = () => {
71
+ db.close();
72
+ reject(tx.error);
73
+ };
74
+ });
75
+ }
76
+ export async function listCheckpoints(projectId, fileId) {
77
+ const db = await openDb();
78
+ return new Promise((resolve, reject) => {
79
+ const tx = db.transaction(STORE, "readonly");
80
+ const store = tx.objectStore(STORE);
81
+ const req = store.index("byFile").getAll(IDBKeyRange.only([projectId, fileId]));
82
+ req.onsuccess = () => {
83
+ db.close();
84
+ resolve(req.result.sort((a, b) => b.timestamp - a.timestamp));
85
+ };
86
+ req.onerror = () => {
87
+ db.close();
88
+ reject(req.error);
89
+ };
90
+ });
91
+ }
92
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1,2 @@
1
+ export declare function injectHistoryStyles(): void;
2
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,130 @@
1
+ const STYLE_ID = "bpmnkit-history-styles";
2
+ export function injectHistoryStyles() {
3
+ if (document.getElementById(STYLE_ID))
4
+ return;
5
+ const style = document.createElement("style");
6
+ style.id = STYLE_ID;
7
+ style.textContent = `
8
+ /* ── History pane ────────────────────────────────────────────────────────── */
9
+ .bpmnkit-hist-pane {
10
+ display: flex; flex-direction: column; height: 100%; overflow: hidden;
11
+ font-family: system-ui, -apple-system, sans-serif;
12
+ }
13
+ .bpmnkit-hist-header {
14
+ display: flex; align-items: center; justify-content: space-between;
15
+ padding: 10px 14px 9px; flex-shrink: 0;
16
+ border-bottom: 1px solid rgba(255,255,255,0.08);
17
+ }
18
+ .bpmnkit-hist-header-title {
19
+ font-size: 10px; font-weight: 700; text-transform: uppercase;
20
+ letter-spacing: 0.08em; color: rgba(255,255,255,0.3);
21
+ }
22
+ .bpmnkit-hist-refresh {
23
+ width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
24
+ background: transparent; border: none; border-radius: 4px;
25
+ color: rgba(255,255,255,0.35); cursor: pointer; font-size: 14px; line-height: 1;
26
+ transition: color 0.1s, background 0.1s;
27
+ }
28
+ .bpmnkit-hist-refresh:hover { color: rgba(255,255,255,0.8); background: rgba(255,255,255,0.07); }
29
+ .bpmnkit-hist-list {
30
+ flex: 1; overflow-y: auto; padding: 4px 0 8px;
31
+ }
32
+ .bpmnkit-hist-list::-webkit-scrollbar { width: 4px; }
33
+ .bpmnkit-hist-list::-webkit-scrollbar-track { background: transparent; }
34
+ .bpmnkit-hist-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 2px; }
35
+ .bpmnkit-hist-group-label {
36
+ padding: 10px 14px 3px;
37
+ font-size: 10px; font-weight: 700; text-transform: uppercase;
38
+ letter-spacing: 0.07em; color: rgba(255,255,255,0.28);
39
+ }
40
+ .bpmnkit-hist-item {
41
+ display: flex; align-items: center; justify-content: space-between;
42
+ padding: 5px 14px; gap: 10px;
43
+ transition: background 0.1s;
44
+ }
45
+ .bpmnkit-hist-item:hover { background: rgba(255,255,255,0.04); }
46
+ .bpmnkit-hist-item-time {
47
+ font-size: 12.5px; color: rgba(255,255,255,0.65);
48
+ font-variant-numeric: tabular-nums; flex: 1;
49
+ }
50
+ .bpmnkit-hist-restore {
51
+ flex-shrink: 0; font-size: 11px; padding: 3px 9px;
52
+ background: var(--bpmnkit-accent-subtle, rgba(107,157,247,0.15)); border: 1px solid rgba(76,142,247,0.3);
53
+ border-radius: 4px; color: rgba(140,185,255,0.85);
54
+ cursor: pointer; font-family: inherit;
55
+ transition: background 0.1s, border-color 0.1s, color 0.1s;
56
+ }
57
+ .bpmnkit-hist-restore:hover {
58
+ background: rgba(76,142,247,0.26); border-color: rgba(76,142,247,0.52);
59
+ color: rgba(180,210,255,0.95);
60
+ }
61
+ .bpmnkit-hist-empty {
62
+ padding: 32px 20px; text-align: center;
63
+ color: rgba(255,255,255,0.28); font-size: 12px; line-height: 1.65;
64
+ }
65
+ /* ── Confirm dialog ──────────────────────────────────────────────────────── */
66
+ .bpmnkit-hist-confirm-overlay {
67
+ position: fixed; inset: 0; z-index: 10100;
68
+ background: rgba(0,0,0,0.55);
69
+ display: flex; align-items: center; justify-content: center;
70
+ }
71
+ .bpmnkit-hist-confirm-panel {
72
+ background: var(--bpmnkit-panel-bg, rgba(13,13,22,0.92)); border: 1px solid rgba(255,255,255,0.12);
73
+ border-radius: 10px; padding: 20px 22px; width: 300px;
74
+ box-shadow: 0 20px 60px rgba(0,0,0,0.7);
75
+ font-family: system-ui, -apple-system, sans-serif;
76
+ }
77
+ .bpmnkit-hist-confirm-title {
78
+ font-size: 13.5px; font-weight: 600; color: rgba(255,255,255,0.9); margin-bottom: 7px;
79
+ }
80
+ .bpmnkit-hist-confirm-body {
81
+ font-size: 12px; color: rgba(255,255,255,0.5); line-height: 1.55; margin-bottom: 18px;
82
+ }
83
+ .bpmnkit-hist-confirm-actions { display: flex; justify-content: flex-end; gap: 7px; }
84
+ .bpmnkit-hist-confirm-cancel {
85
+ padding: 5px 13px; background: transparent;
86
+ border: 1px solid rgba(255,255,255,0.14); border-radius: 6px;
87
+ color: rgba(255,255,255,0.55); font-size: 12px; cursor: pointer; font-family: inherit;
88
+ transition: background 0.1s, color 0.1s;
89
+ }
90
+ .bpmnkit-hist-confirm-cancel:hover { background: rgba(255,255,255,0.07); color: rgba(255,255,255,0.85); }
91
+ .bpmnkit-hist-confirm-ok {
92
+ padding: 5px 13px; background: var(--bpmnkit-accent, #6b9df7);
93
+ border: 1px solid var(--bpmnkit-accent, #6b9df7); border-radius: 6px;
94
+ color: #fff; font-size: 12px; font-weight: 500; cursor: pointer; font-family: inherit;
95
+ transition: background 0.1s;
96
+ }
97
+ .bpmnkit-hist-confirm-ok:hover { background: var(--bpmnkit-accent, #6b9df7); }
98
+ /* ── Light theme ─────────────────────────────────────────────────────────── */
99
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-header { border-bottom-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08)); }
100
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-header-title { color: rgba(0,0,0,0.3); }
101
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-refresh { color: rgba(0,0,0,0.35); }
102
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-refresh:hover { color: rgba(0,0,0,0.75); background: rgba(0,0,0,0.06); }
103
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-group-label { color: rgba(0,0,0,0.3); }
104
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-item:hover { background: rgba(0,0,0,0.035); }
105
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-item-time { color: rgba(0,0,0,0.65); }
106
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-restore {
107
+ background: var(--bpmnkit-accent-subtle, rgba(26,86,219,0.12)); border-color: rgba(26,86,219,0.25); color: rgba(26,86,219,0.9);
108
+ }
109
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-restore:hover {
110
+ background: rgba(26,86,219,0.16); border-color: rgba(26,86,219,0.45); color: rgba(26,86,219,1);
111
+ }
112
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-empty { color: rgba(0,0,0,0.3); }
113
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-panel {
114
+ background: rgba(252,252,255,0.99); border-color: rgba(0,0,0,0.1);
115
+ box-shadow: 0 20px 60px rgba(0,0,0,0.18);
116
+ }
117
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-title { color: rgba(0,0,0,0.88); }
118
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-body { color: rgba(0,0,0,0.5); }
119
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-cancel {
120
+ border-color: rgba(0,0,0,0.14); color: rgba(0,0,0,0.55);
121
+ }
122
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-cancel:hover {
123
+ background: rgba(0,0,0,0.05); color: rgba(0,0,0,0.8);
124
+ }
125
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-ok { background: var(--bpmnkit-accent, #1a56db); border-color: var(--bpmnkit-accent, #1a56db); }
126
+ [data-bpmnkit-hud-theme="light"] .bpmnkit-hist-confirm-ok:hover { background: #1648c2; }
127
+ `;
128
+ document.head.appendChild(style);
129
+ }
130
+ //# sourceMappingURL=css.js.map
@@ -0,0 +1,12 @@
1
+ export interface HistoryPanelOptions {
2
+ getCurrentContext?(): {
3
+ projectId: string;
4
+ fileId: string;
5
+ } | null;
6
+ loadXml(xml: string): void;
7
+ }
8
+ export declare function createHistoryPanel(options: HistoryPanelOptions): {
9
+ el: HTMLElement;
10
+ refresh(): Promise<void>;
11
+ };
12
+ //# sourceMappingURL=history-panel.d.ts.map