@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.
- package/README.md +153 -0
- package/dist/ai-bridge/css.d.ts +2 -0
- package/dist/ai-bridge/css.js +366 -0
- package/dist/ai-bridge/index.d.ts +44 -0
- package/dist/ai-bridge/index.js +132 -0
- package/dist/ai-bridge/panel.d.ts +27 -0
- package/dist/ai-bridge/panel.js +715 -0
- package/dist/ascii-view/css.d.ts +4 -0
- package/dist/ascii-view/css.js +83 -0
- package/dist/ascii-view/index.d.ts +25 -0
- package/dist/ascii-view/index.js +92 -0
- package/dist/command-palette/css.d.ts +4 -0
- package/dist/command-palette/css.js +157 -0
- package/dist/command-palette/index.d.ts +53 -0
- package/dist/command-palette/index.js +378 -0
- package/dist/command-palette-editor/index.d.ts +35 -0
- package/dist/command-palette-editor/index.js +60 -0
- package/dist/config-panel/css.d.ts +4 -0
- package/dist/config-panel/css.js +719 -0
- package/dist/config-panel/index.d.ts +36 -0
- package/dist/config-panel/index.js +73 -0
- package/dist/config-panel/renderer.d.ts +127 -0
- package/dist/config-panel/renderer.js +1162 -0
- package/dist/config-panel/types.d.ts +118 -0
- package/dist/config-panel/types.js +2 -0
- package/dist/config-panel-bpmn/index.d.ts +58 -0
- package/dist/config-panel-bpmn/index.js +1320 -0
- package/dist/config-panel-bpmn/template-engine.d.ts +17 -0
- package/dist/config-panel-bpmn/template-engine.js +307 -0
- package/dist/config-panel-bpmn/template-to-service-task.d.ts +30 -0
- package/dist/config-panel-bpmn/template-to-service-task.js +92 -0
- package/dist/config-panel-bpmn/template-types.d.ts +126 -0
- package/dist/config-panel-bpmn/template-types.js +6 -0
- package/dist/config-panel-bpmn/templates/generated.d.ts +3 -0
- package/dist/config-panel-bpmn/templates/generated.js +57865 -0
- package/dist/config-panel-bpmn/util.d.ts +46 -0
- package/dist/config-panel-bpmn/util.js +195 -0
- package/dist/dmn-editor/css.d.ts +3 -0
- package/dist/dmn-editor/css.js +667 -0
- package/dist/dmn-editor/dmn-editor.d.ts +34 -0
- package/dist/dmn-editor/dmn-editor.js +646 -0
- package/dist/dmn-editor/drd-canvas.d.ts +85 -0
- package/dist/dmn-editor/drd-canvas.js +1087 -0
- package/dist/dmn-editor/index.d.ts +3 -0
- package/dist/dmn-editor/index.js +2 -0
- package/dist/dmn-viewer/css.d.ts +3 -0
- package/dist/dmn-viewer/css.js +151 -0
- package/dist/dmn-viewer/dmn-viewer.d.ts +30 -0
- package/dist/dmn-viewer/dmn-viewer.js +160 -0
- package/dist/dmn-viewer/feel.d.ts +3 -0
- package/dist/dmn-viewer/feel.js +2 -0
- package/dist/dmn-viewer/index.d.ts +14 -0
- package/dist/dmn-viewer/index.js +12 -0
- package/dist/element-docs/content.d.ts +20 -0
- package/dist/element-docs/content.js +1032 -0
- package/dist/element-docs/index.d.ts +7 -0
- package/dist/element-docs/index.js +643 -0
- package/dist/feel-playground/css.d.ts +4 -0
- package/dist/feel-playground/css.js +292 -0
- package/dist/feel-playground/index.d.ts +4 -0
- package/dist/feel-playground/index.js +3 -0
- package/dist/feel-playground/playground-plugin.d.ts +14 -0
- package/dist/feel-playground/playground-plugin.js +292 -0
- package/dist/form-editor/css.d.ts +3 -0
- package/dist/form-editor/css.js +703 -0
- package/dist/form-editor/form-editor.d.ts +48 -0
- package/dist/form-editor/form-editor.js +1039 -0
- package/dist/form-editor/index.d.ts +3 -0
- package/dist/form-editor/index.js +2 -0
- package/dist/form-viewer/css.d.ts +3 -0
- package/dist/form-viewer/css.js +303 -0
- package/dist/form-viewer/form-viewer.d.ts +29 -0
- package/dist/form-viewer/form-viewer.js +376 -0
- package/dist/form-viewer/index.d.ts +12 -0
- package/dist/form-viewer/index.js +11 -0
- package/dist/history/checkpoint.d.ts +10 -0
- package/dist/history/checkpoint.js +92 -0
- package/dist/history/css.d.ts +2 -0
- package/dist/history/css.js +130 -0
- package/dist/history/history-panel.d.ts +12 -0
- package/dist/history/history-panel.js +142 -0
- package/dist/history/index.d.ts +5 -0
- package/dist/history/index.js +3 -0
- package/dist/main-menu/css.d.ts +4 -0
- package/dist/main-menu/css.js +272 -0
- package/dist/main-menu/index.d.ts +59 -0
- package/dist/main-menu/index.js +285 -0
- package/dist/minimap/css.d.ts +10 -0
- package/dist/minimap/css.js +54 -0
- package/dist/minimap/index.d.ts +38 -0
- package/dist/minimap/index.js +69 -0
- package/dist/minimap/minimap.d.ts +35 -0
- package/dist/minimap/minimap.js +166 -0
- package/dist/optimize/index.d.ts +21 -0
- package/dist/optimize/index.js +304 -0
- package/dist/process-runner/css.d.ts +2 -0
- package/dist/process-runner/css.js +467 -0
- package/dist/process-runner/index.d.ts +56 -0
- package/dist/process-runner/index.js +549 -0
- package/dist/storage/auto-save.d.ts +11 -0
- package/dist/storage/auto-save.js +44 -0
- package/dist/storage/css.d.ts +2 -0
- package/dist/storage/css.js +2 -0
- package/dist/storage/db.d.ts +99 -0
- package/dist/storage/db.js +116 -0
- package/dist/storage/dialog.d.ts +15 -0
- package/dist/storage/dialog.js +201 -0
- package/dist/storage/export.d.ts +3 -0
- package/dist/storage/export.js +137 -0
- package/dist/storage/index.d.ts +44 -0
- package/dist/storage/index.js +201 -0
- package/dist/storage/sidebar.d.ts +2 -0
- package/dist/storage/sidebar.js +2 -0
- package/dist/storage/storage-api.d.ts +76 -0
- package/dist/storage/storage-api.js +342 -0
- package/dist/storage/types.d.ts +44 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage-tabs-bridge/index.d.ts +96 -0
- package/dist/storage-tabs-bridge/index.js +502 -0
- package/dist/tabs/css.d.ts +3 -0
- package/dist/tabs/css.js +642 -0
- package/dist/tabs/file-resolver.d.ts +71 -0
- package/dist/tabs/file-resolver.js +46 -0
- package/dist/tabs/index.d.ts +15 -0
- package/dist/tabs/index.js +13 -0
- package/dist/tabs/tabs-plugin.d.ts +250 -0
- package/dist/tabs/tabs-plugin.js +1119 -0
- package/dist/token-highlight/css.d.ts +2 -0
- package/dist/token-highlight/css.js +81 -0
- package/dist/token-highlight/index.d.ts +44 -0
- package/dist/token-highlight/index.js +164 -0
- package/dist/watermark/css.d.ts +10 -0
- package/dist/watermark/css.js +54 -0
- package/dist/watermark/index.d.ts +48 -0
- package/dist/watermark/index.js +64 -0
- package/dist/zoom-controls/css.d.ts +4 -0
- package/dist/zoom-controls/css.js +48 -0
- package/dist/zoom-controls/index.d.ts +36 -0
- package/dist/zoom-controls/index.js +111 -0
- package/package.json +121 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { FileContentRecord, FileRecord, ProjectMruRecord, ProjectRecord, WorkspaceRecord } from "./types.js";
|
|
2
|
+
export declare const db: {
|
|
3
|
+
workspaces: {
|
|
4
|
+
get(key: string): Promise<WorkspaceRecord | undefined>;
|
|
5
|
+
add(record: WorkspaceRecord): Promise<void>;
|
|
6
|
+
update(key: string, changes: Partial<WorkspaceRecord>): Promise<void>;
|
|
7
|
+
delete(key: string): Promise<void>;
|
|
8
|
+
orderBy(field: string): {
|
|
9
|
+
toArray: () => Promise<WorkspaceRecord[]>;
|
|
10
|
+
};
|
|
11
|
+
where(index: string): {
|
|
12
|
+
equals: (value: string) => {
|
|
13
|
+
toArray: () => Promise<WorkspaceRecord[]>;
|
|
14
|
+
sortBy: (field: string) => Promise<WorkspaceRecord[]>;
|
|
15
|
+
delete: () => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
filter: (pred: (item: WorkspaceRecord) => boolean) => {
|
|
19
|
+
toArray: () => Promise<WorkspaceRecord[]>;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
projects: {
|
|
23
|
+
get(key: string): Promise<ProjectRecord | undefined>;
|
|
24
|
+
add(record: ProjectRecord): Promise<void>;
|
|
25
|
+
update(key: string, changes: Partial<ProjectRecord>): Promise<void>;
|
|
26
|
+
delete(key: string): Promise<void>;
|
|
27
|
+
orderBy(field: string): {
|
|
28
|
+
toArray: () => Promise<ProjectRecord[]>;
|
|
29
|
+
};
|
|
30
|
+
where(index: string): {
|
|
31
|
+
equals: (value: string) => {
|
|
32
|
+
toArray: () => Promise<ProjectRecord[]>;
|
|
33
|
+
sortBy: (field: string) => Promise<ProjectRecord[]>;
|
|
34
|
+
delete: () => Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
filter: (pred: (item: ProjectRecord) => boolean) => {
|
|
38
|
+
toArray: () => Promise<ProjectRecord[]>;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
files: {
|
|
42
|
+
get(key: string): Promise<FileRecord | undefined>;
|
|
43
|
+
add(record: FileRecord): Promise<void>;
|
|
44
|
+
update(key: string, changes: Partial<FileRecord>): Promise<void>;
|
|
45
|
+
delete(key: string): Promise<void>;
|
|
46
|
+
orderBy(field: string): {
|
|
47
|
+
toArray: () => Promise<FileRecord[]>;
|
|
48
|
+
};
|
|
49
|
+
where(index: string): {
|
|
50
|
+
equals: (value: string) => {
|
|
51
|
+
toArray: () => Promise<FileRecord[]>;
|
|
52
|
+
sortBy: (field: string) => Promise<FileRecord[]>;
|
|
53
|
+
delete: () => Promise<void>;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
filter: (pred: (item: FileRecord) => boolean) => {
|
|
57
|
+
toArray: () => Promise<FileRecord[]>;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
fileContents: {
|
|
61
|
+
get(key: string): Promise<FileContentRecord | undefined>;
|
|
62
|
+
add(record: FileContentRecord): Promise<void>;
|
|
63
|
+
update(key: string, changes: Partial<FileContentRecord>): Promise<void>;
|
|
64
|
+
delete(key: string): Promise<void>;
|
|
65
|
+
orderBy(field: string): {
|
|
66
|
+
toArray: () => Promise<FileContentRecord[]>;
|
|
67
|
+
};
|
|
68
|
+
where(index: string): {
|
|
69
|
+
equals: (value: string) => {
|
|
70
|
+
toArray: () => Promise<FileContentRecord[]>;
|
|
71
|
+
sortBy: (field: string) => Promise<FileContentRecord[]>;
|
|
72
|
+
delete: () => Promise<void>;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
filter: (pred: (item: FileContentRecord) => boolean) => {
|
|
76
|
+
toArray: () => Promise<FileContentRecord[]>;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
projectMru: {
|
|
80
|
+
get(key: string): Promise<ProjectMruRecord | undefined>;
|
|
81
|
+
add(record: ProjectMruRecord): Promise<void>;
|
|
82
|
+
update(key: string, changes: Partial<ProjectMruRecord>): Promise<void>;
|
|
83
|
+
delete(key: string): Promise<void>;
|
|
84
|
+
orderBy(field: string): {
|
|
85
|
+
toArray: () => Promise<ProjectMruRecord[]>;
|
|
86
|
+
};
|
|
87
|
+
where(index: string): {
|
|
88
|
+
equals: (value: string) => {
|
|
89
|
+
toArray: () => Promise<ProjectMruRecord[]>;
|
|
90
|
+
sortBy: (field: string) => Promise<ProjectMruRecord[]>;
|
|
91
|
+
delete: () => Promise<void>;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
filter: (pred: (item: ProjectMruRecord) => boolean) => {
|
|
95
|
+
toArray: () => Promise<ProjectMruRecord[]>;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const DB_NAME = "bpmn-sdk-storage";
|
|
2
|
+
// Dexie 4.x internally stored version 10 for user-space version 1.
|
|
3
|
+
// Use 12 to add the projectMru object store.
|
|
4
|
+
const DB_VERSION = 12;
|
|
5
|
+
let _db = null;
|
|
6
|
+
function openDb() {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const r = indexedDB.open(DB_NAME, DB_VERSION);
|
|
9
|
+
r.onupgradeneeded = () => {
|
|
10
|
+
const d = r.result;
|
|
11
|
+
// Guard each store: Dexie may have already created them at version 10.
|
|
12
|
+
if (!d.objectStoreNames.contains("workspaces")) {
|
|
13
|
+
const ws = d.createObjectStore("workspaces", { keyPath: "id" });
|
|
14
|
+
ws.createIndex("name", "name");
|
|
15
|
+
}
|
|
16
|
+
if (!d.objectStoreNames.contains("projects")) {
|
|
17
|
+
const prj = d.createObjectStore("projects", { keyPath: "id" });
|
|
18
|
+
prj.createIndex("workspaceId", "workspaceId");
|
|
19
|
+
}
|
|
20
|
+
if (!d.objectStoreNames.contains("files")) {
|
|
21
|
+
const fl = d.createObjectStore("files", { keyPath: "id" });
|
|
22
|
+
fl.createIndex("projectId", "projectId");
|
|
23
|
+
fl.createIndex("workspaceId", "workspaceId");
|
|
24
|
+
}
|
|
25
|
+
if (!d.objectStoreNames.contains("fileContents")) {
|
|
26
|
+
d.createObjectStore("fileContents", { keyPath: "fileId" });
|
|
27
|
+
}
|
|
28
|
+
if (!d.objectStoreNames.contains("projectMru")) {
|
|
29
|
+
d.createObjectStore("projectMru", { keyPath: "projectId" });
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
r.onsuccess = () => {
|
|
33
|
+
_db = r.result;
|
|
34
|
+
resolve(_db);
|
|
35
|
+
};
|
|
36
|
+
r.onerror = () => reject(r.error);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function getDb() {
|
|
40
|
+
return _db !== null ? Promise.resolve(_db) : openDb();
|
|
41
|
+
}
|
|
42
|
+
function wrap(r) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
r.onsuccess = () => resolve(r.result);
|
|
45
|
+
r.onerror = () => reject(r.error);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function sorted(items, field) {
|
|
49
|
+
return [...items].sort((a, b) => {
|
|
50
|
+
const av = String(a[field] ?? "");
|
|
51
|
+
const bv = String(b[field] ?? "");
|
|
52
|
+
return av.localeCompare(bv);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function makeTable(name) {
|
|
56
|
+
async function fetchAll(index, value) {
|
|
57
|
+
const d = await getDb();
|
|
58
|
+
const os = d.transaction(name, "readonly").objectStore(name);
|
|
59
|
+
const r = index !== undefined && value !== undefined ? os.index(index).getAll(value) : os.getAll();
|
|
60
|
+
return wrap(r);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
async get(key) {
|
|
64
|
+
const d = await getDb();
|
|
65
|
+
return wrap(d.transaction(name, "readonly").objectStore(name).get(key));
|
|
66
|
+
},
|
|
67
|
+
async add(record) {
|
|
68
|
+
const d = await getDb();
|
|
69
|
+
await wrap(d.transaction(name, "readwrite").objectStore(name).add(record));
|
|
70
|
+
},
|
|
71
|
+
async update(key, changes) {
|
|
72
|
+
const d = await getDb();
|
|
73
|
+
const tx = d.transaction(name, "readwrite");
|
|
74
|
+
const os = tx.objectStore(name);
|
|
75
|
+
const current = await wrap(os.get(key));
|
|
76
|
+
if (current !== undefined) {
|
|
77
|
+
await wrap(os.put(Object.assign({}, current, changes)));
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
async delete(key) {
|
|
81
|
+
const d = await getDb();
|
|
82
|
+
await wrap(d.transaction(name, "readwrite").objectStore(name).delete(key));
|
|
83
|
+
},
|
|
84
|
+
orderBy(field) {
|
|
85
|
+
return {
|
|
86
|
+
toArray: () => fetchAll().then((items) => sorted(items, field)),
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
where(index) {
|
|
90
|
+
return {
|
|
91
|
+
equals: (value) => ({
|
|
92
|
+
toArray: () => fetchAll(index, value),
|
|
93
|
+
sortBy: (field) => fetchAll(index, value).then((items) => sorted(items, field)),
|
|
94
|
+
delete: async () => {
|
|
95
|
+
const d = await getDb();
|
|
96
|
+
const tx = d.transaction(name, "readwrite");
|
|
97
|
+
const os = tx.objectStore(name);
|
|
98
|
+
const keys = await wrap(os.index(index).getAllKeys(value));
|
|
99
|
+
await Promise.all(keys.map((k) => wrap(os.delete(k))));
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
filter: (pred) => ({
|
|
105
|
+
toArray: () => fetchAll().then((items) => items.filter(pred)),
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export const db = {
|
|
110
|
+
workspaces: makeTable("workspaces"),
|
|
111
|
+
projects: makeTable("projects"),
|
|
112
|
+
files: makeTable("files"),
|
|
113
|
+
fileContents: makeTable("fileContents"),
|
|
114
|
+
projectMru: makeTable("projectMru"),
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Shows a modal input dialog. Returns the trimmed value or null if cancelled. */
|
|
2
|
+
export declare function showInputDialog(opts: {
|
|
3
|
+
title: string;
|
|
4
|
+
defaultValue?: string;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
confirmLabel?: string;
|
|
7
|
+
}): Promise<string | null>;
|
|
8
|
+
/** Shows a modal confirmation dialog. Returns true if confirmed, false if cancelled. */
|
|
9
|
+
export declare function showConfirmDialog(opts: {
|
|
10
|
+
title: string;
|
|
11
|
+
message: string;
|
|
12
|
+
confirmLabel?: string;
|
|
13
|
+
danger?: boolean;
|
|
14
|
+
}): Promise<boolean>;
|
|
15
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const STYLE_ID = "stor-dialog-styles";
|
|
2
|
+
function injectStyles() {
|
|
3
|
+
if (document.getElementById(STYLE_ID))
|
|
4
|
+
return;
|
|
5
|
+
const style = document.createElement("style");
|
|
6
|
+
style.id = STYLE_ID;
|
|
7
|
+
style.textContent = `
|
|
8
|
+
.stor-dialog-overlay {
|
|
9
|
+
position: fixed; inset: 0; z-index: 500;
|
|
10
|
+
background: rgba(0,0,0,0.5);
|
|
11
|
+
display: flex; align-items: center; justify-content: center;
|
|
12
|
+
}
|
|
13
|
+
.stor-dialog {
|
|
14
|
+
background: rgba(22, 22, 30, 0.97);
|
|
15
|
+
border: 1px solid rgba(255,255,255,0.12);
|
|
16
|
+
border-radius: 10px;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
min-width: 300px; max-width: 90vw;
|
|
19
|
+
color: rgba(255,255,255,0.85);
|
|
20
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
21
|
+
box-shadow: 0 16px 48px rgba(0,0,0,0.6);
|
|
22
|
+
display: flex; flex-direction: column; gap: 12px;
|
|
23
|
+
}
|
|
24
|
+
.stor-dialog-title {
|
|
25
|
+
font-size: 14px; font-weight: 600;
|
|
26
|
+
color: rgba(255,255,255,0.95);
|
|
27
|
+
}
|
|
28
|
+
.stor-dialog-msg {
|
|
29
|
+
font-size: 13px; color: rgba(255,255,255,0.65); line-height: 1.4;
|
|
30
|
+
}
|
|
31
|
+
.stor-dialog-input {
|
|
32
|
+
width: 100%; padding: 6px 10px;
|
|
33
|
+
background: rgba(255,255,255,0.08);
|
|
34
|
+
border: 1px solid rgba(255,255,255,0.15);
|
|
35
|
+
border-radius: 6px;
|
|
36
|
+
color: rgba(255,255,255,0.9);
|
|
37
|
+
font-size: 13px;
|
|
38
|
+
outline: none;
|
|
39
|
+
box-sizing: border-box;
|
|
40
|
+
}
|
|
41
|
+
.stor-dialog-input:focus { border-color: rgba(60,120,220,0.6); }
|
|
42
|
+
.stor-dialog-actions { display: flex; gap: 8px; justify-content: flex-end; }
|
|
43
|
+
.stor-dialog-btn {
|
|
44
|
+
font-size: 13px; padding: 6px 14px; border-radius: 6px;
|
|
45
|
+
cursor: pointer; font-weight: 500;
|
|
46
|
+
border: 1px solid rgba(255,255,255,0.12);
|
|
47
|
+
background: rgba(255,255,255,0.06);
|
|
48
|
+
color: rgba(255,255,255,0.8);
|
|
49
|
+
}
|
|
50
|
+
.stor-dialog-btn:hover { background: rgba(255,255,255,0.1); }
|
|
51
|
+
.stor-dialog-btn--primary {
|
|
52
|
+
background: rgba(60,120,220,0.5);
|
|
53
|
+
border-color: rgba(60,120,220,0.7);
|
|
54
|
+
color: #fff;
|
|
55
|
+
}
|
|
56
|
+
.stor-dialog-btn--primary:hover { background: rgba(60,120,220,0.65); }
|
|
57
|
+
.stor-dialog-btn--danger {
|
|
58
|
+
background: rgba(200,40,40,0.5);
|
|
59
|
+
border-color: rgba(200,40,40,0.7);
|
|
60
|
+
color: #fff;
|
|
61
|
+
}
|
|
62
|
+
.stor-dialog-btn--danger:hover { background: rgba(200,40,40,0.65); }
|
|
63
|
+
/* Light theme */
|
|
64
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog {
|
|
65
|
+
background: rgba(252,252,254,0.98);
|
|
66
|
+
border-color: rgba(0,0,0,0.1);
|
|
67
|
+
color: rgba(0,0,0,0.8);
|
|
68
|
+
box-shadow: 0 8px 32px rgba(0,0,0,0.15);
|
|
69
|
+
}
|
|
70
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-title { color: rgba(0,0,0,0.88); }
|
|
71
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-msg { color: rgba(0,0,0,0.55); }
|
|
72
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-input {
|
|
73
|
+
background: rgba(0,0,0,0.04);
|
|
74
|
+
border-color: rgba(0,0,0,0.15);
|
|
75
|
+
color: rgba(0,0,0,0.9);
|
|
76
|
+
}
|
|
77
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-input:focus { border-color: rgba(0,80,200,0.4); }
|
|
78
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn {
|
|
79
|
+
border-color: rgba(0,0,0,0.12);
|
|
80
|
+
background: rgba(0,0,0,0.04);
|
|
81
|
+
color: rgba(0,0,0,0.7);
|
|
82
|
+
}
|
|
83
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn:hover { background: rgba(0,0,0,0.08); }
|
|
84
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn--primary {
|
|
85
|
+
background: rgba(0,80,200,0.85);
|
|
86
|
+
border-color: rgba(0,80,200,0.9);
|
|
87
|
+
color: #fff;
|
|
88
|
+
}
|
|
89
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn--primary:hover { background: rgba(0,80,200,1); }
|
|
90
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn--danger {
|
|
91
|
+
background: rgba(180,30,30,0.85);
|
|
92
|
+
border-color: rgba(180,30,30,0.9);
|
|
93
|
+
color: #fff;
|
|
94
|
+
}
|
|
95
|
+
[data-bpmnkit-hud-theme="light"] .stor-dialog-btn--danger:hover { background: rgba(180,30,30,1); }
|
|
96
|
+
`;
|
|
97
|
+
document.head.appendChild(style);
|
|
98
|
+
}
|
|
99
|
+
/** Shows a modal input dialog. Returns the trimmed value or null if cancelled. */
|
|
100
|
+
export function showInputDialog(opts) {
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
injectStyles();
|
|
103
|
+
const overlay = document.createElement("div");
|
|
104
|
+
overlay.className = "stor-dialog-overlay";
|
|
105
|
+
const dialog = document.createElement("div");
|
|
106
|
+
dialog.className = "stor-dialog";
|
|
107
|
+
const titleEl = document.createElement("div");
|
|
108
|
+
titleEl.className = "stor-dialog-title";
|
|
109
|
+
titleEl.textContent = opts.title;
|
|
110
|
+
const input = document.createElement("input");
|
|
111
|
+
input.type = "text";
|
|
112
|
+
input.className = "stor-dialog-input";
|
|
113
|
+
input.value = opts.defaultValue ?? "";
|
|
114
|
+
if (opts.placeholder)
|
|
115
|
+
input.placeholder = opts.placeholder;
|
|
116
|
+
const actions = document.createElement("div");
|
|
117
|
+
actions.className = "stor-dialog-actions";
|
|
118
|
+
const cancelBtn = document.createElement("button");
|
|
119
|
+
cancelBtn.className = "stor-dialog-btn";
|
|
120
|
+
cancelBtn.textContent = "Cancel";
|
|
121
|
+
const confirmBtn = document.createElement("button");
|
|
122
|
+
confirmBtn.className = "stor-dialog-btn stor-dialog-btn--primary";
|
|
123
|
+
confirmBtn.textContent = opts.confirmLabel ?? "OK";
|
|
124
|
+
function close(value) {
|
|
125
|
+
overlay.remove();
|
|
126
|
+
document.removeEventListener("keydown", handleKey);
|
|
127
|
+
resolve(value);
|
|
128
|
+
}
|
|
129
|
+
cancelBtn.addEventListener("click", () => close(null));
|
|
130
|
+
confirmBtn.addEventListener("click", () => close(input.value.trim() || null));
|
|
131
|
+
function handleKey(e) {
|
|
132
|
+
if (e.key === "Escape")
|
|
133
|
+
close(null);
|
|
134
|
+
else if (e.key === "Enter")
|
|
135
|
+
close(input.value.trim() || null);
|
|
136
|
+
}
|
|
137
|
+
document.addEventListener("keydown", handleKey);
|
|
138
|
+
overlay.addEventListener("click", (e) => {
|
|
139
|
+
if (e.target === overlay)
|
|
140
|
+
close(null);
|
|
141
|
+
});
|
|
142
|
+
actions.append(cancelBtn, confirmBtn);
|
|
143
|
+
dialog.append(titleEl, input, actions);
|
|
144
|
+
overlay.append(dialog);
|
|
145
|
+
document.body.append(overlay);
|
|
146
|
+
requestAnimationFrame(() => {
|
|
147
|
+
input.select();
|
|
148
|
+
input.focus();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** Shows a modal confirmation dialog. Returns true if confirmed, false if cancelled. */
|
|
153
|
+
export function showConfirmDialog(opts) {
|
|
154
|
+
return new Promise((resolve) => {
|
|
155
|
+
injectStyles();
|
|
156
|
+
const overlay = document.createElement("div");
|
|
157
|
+
overlay.className = "stor-dialog-overlay";
|
|
158
|
+
const dialog = document.createElement("div");
|
|
159
|
+
dialog.className = "stor-dialog";
|
|
160
|
+
const titleEl = document.createElement("div");
|
|
161
|
+
titleEl.className = "stor-dialog-title";
|
|
162
|
+
titleEl.textContent = opts.title;
|
|
163
|
+
const msgEl = document.createElement("div");
|
|
164
|
+
msgEl.className = "stor-dialog-msg";
|
|
165
|
+
msgEl.textContent = opts.message;
|
|
166
|
+
const actions = document.createElement("div");
|
|
167
|
+
actions.className = "stor-dialog-actions";
|
|
168
|
+
const cancelBtn = document.createElement("button");
|
|
169
|
+
cancelBtn.className = "stor-dialog-btn";
|
|
170
|
+
cancelBtn.textContent = "Cancel";
|
|
171
|
+
const confirmBtn = document.createElement("button");
|
|
172
|
+
confirmBtn.className = opts.danger
|
|
173
|
+
? "stor-dialog-btn stor-dialog-btn--danger"
|
|
174
|
+
: "stor-dialog-btn stor-dialog-btn--primary";
|
|
175
|
+
confirmBtn.textContent = opts.confirmLabel ?? "Confirm";
|
|
176
|
+
function close(result) {
|
|
177
|
+
overlay.remove();
|
|
178
|
+
document.removeEventListener("keydown", handleKey);
|
|
179
|
+
resolve(result);
|
|
180
|
+
}
|
|
181
|
+
cancelBtn.addEventListener("click", () => close(false));
|
|
182
|
+
confirmBtn.addEventListener("click", () => close(true));
|
|
183
|
+
function handleKey(e) {
|
|
184
|
+
if (e.key === "Escape")
|
|
185
|
+
close(false);
|
|
186
|
+
else if (e.key === "Enter")
|
|
187
|
+
close(true);
|
|
188
|
+
}
|
|
189
|
+
document.addEventListener("keydown", handleKey);
|
|
190
|
+
overlay.addEventListener("click", (e) => {
|
|
191
|
+
if (e.target === overlay)
|
|
192
|
+
close(false);
|
|
193
|
+
});
|
|
194
|
+
actions.append(cancelBtn, confirmBtn);
|
|
195
|
+
dialog.append(titleEl, msgEl, actions);
|
|
196
|
+
overlay.append(dialog);
|
|
197
|
+
document.body.append(overlay);
|
|
198
|
+
requestAnimationFrame(() => confirmBtn.focus());
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=dialog.js.map
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// ─── CRC-32 ───────────────────────────────────────────────────────────────────
|
|
2
|
+
const CRC_TABLE = (() => {
|
|
3
|
+
const t = new Uint32Array(256);
|
|
4
|
+
for (let i = 0; i < 256; i++) {
|
|
5
|
+
let c = i;
|
|
6
|
+
for (let j = 0; j < 8; j++) {
|
|
7
|
+
c = c & 1 ? (c >>> 1) ^ 0xedb88320 : c >>> 1;
|
|
8
|
+
}
|
|
9
|
+
t[i] = c;
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
})();
|
|
13
|
+
function crc32(data) {
|
|
14
|
+
let crc = 0xffffffff;
|
|
15
|
+
for (const byte of data) {
|
|
16
|
+
crc = (crc >>> 8) ^ (CRC_TABLE[(crc ^ byte) & 0xff] ?? 0);
|
|
17
|
+
}
|
|
18
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
19
|
+
}
|
|
20
|
+
function u16(view, off, v) {
|
|
21
|
+
view.setUint16(off, v, true);
|
|
22
|
+
}
|
|
23
|
+
function u32(view, off, v) {
|
|
24
|
+
view.setUint32(off, v, true);
|
|
25
|
+
}
|
|
26
|
+
function buildZip(files) {
|
|
27
|
+
const enc = new TextEncoder();
|
|
28
|
+
const entries = [];
|
|
29
|
+
const localParts = [];
|
|
30
|
+
let dataOffset = 0;
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const nameBytes = enc.encode(file.name);
|
|
33
|
+
const crc = crc32(file.data);
|
|
34
|
+
const headerLen = 30 + nameBytes.length;
|
|
35
|
+
const header = new Uint8Array(headerLen);
|
|
36
|
+
const v = new DataView(header.buffer);
|
|
37
|
+
u32(v, 0, 0x04034b50); // local file signature
|
|
38
|
+
u16(v, 4, 10); // version needed: 1.0
|
|
39
|
+
u16(v, 6, 0); // flags
|
|
40
|
+
u16(v, 8, 0); // STORE
|
|
41
|
+
u16(v, 10, 0); // last mod time
|
|
42
|
+
u16(v, 12, 0); // last mod date
|
|
43
|
+
u32(v, 14, crc);
|
|
44
|
+
u32(v, 18, file.data.length); // compressed size
|
|
45
|
+
u32(v, 22, file.data.length); // uncompressed size
|
|
46
|
+
u16(v, 26, nameBytes.length);
|
|
47
|
+
u16(v, 28, 0); // extra field length
|
|
48
|
+
header.set(nameBytes, 30);
|
|
49
|
+
entries.push({ nameBytes, data: file.data, crc, offset: dataOffset });
|
|
50
|
+
localParts.push(header, file.data);
|
|
51
|
+
dataOffset += headerLen + file.data.length;
|
|
52
|
+
}
|
|
53
|
+
// Central directory
|
|
54
|
+
const centralParts = [];
|
|
55
|
+
let centralSize = 0;
|
|
56
|
+
for (const e of entries) {
|
|
57
|
+
const len = 46 + e.nameBytes.length;
|
|
58
|
+
const cd = new Uint8Array(len);
|
|
59
|
+
const v = new DataView(cd.buffer);
|
|
60
|
+
u32(v, 0, 0x02014b50); // central dir signature
|
|
61
|
+
u16(v, 4, 20); // version made by
|
|
62
|
+
u16(v, 6, 10); // version needed
|
|
63
|
+
u16(v, 8, 0); // flags
|
|
64
|
+
u16(v, 10, 0); // STORE
|
|
65
|
+
u16(v, 12, 0); // last mod time
|
|
66
|
+
u16(v, 14, 0); // last mod date
|
|
67
|
+
u32(v, 16, e.crc);
|
|
68
|
+
u32(v, 20, e.data.length); // compressed size
|
|
69
|
+
u32(v, 24, e.data.length); // uncompressed size
|
|
70
|
+
u16(v, 28, e.nameBytes.length);
|
|
71
|
+
u16(v, 30, 0); // extra field length
|
|
72
|
+
u16(v, 32, 0); // file comment length
|
|
73
|
+
u16(v, 34, 0); // disk number start
|
|
74
|
+
u16(v, 36, 0); // internal file attributes
|
|
75
|
+
u32(v, 38, 0); // external file attributes
|
|
76
|
+
u32(v, 42, e.offset); // relative offset of local header
|
|
77
|
+
cd.set(e.nameBytes, 46);
|
|
78
|
+
centralParts.push(cd);
|
|
79
|
+
centralSize += len;
|
|
80
|
+
}
|
|
81
|
+
// End of central directory record
|
|
82
|
+
const eocd = new Uint8Array(22);
|
|
83
|
+
const ev = new DataView(eocd.buffer);
|
|
84
|
+
u32(ev, 0, 0x06054b50);
|
|
85
|
+
u16(ev, 4, 0);
|
|
86
|
+
u16(ev, 6, 0);
|
|
87
|
+
u16(ev, 8, entries.length);
|
|
88
|
+
u16(ev, 10, entries.length);
|
|
89
|
+
u32(ev, 12, centralSize);
|
|
90
|
+
u32(ev, 16, dataOffset);
|
|
91
|
+
u16(ev, 20, 0);
|
|
92
|
+
const totalSize = dataOffset + centralSize + 22;
|
|
93
|
+
const out = new Uint8Array(totalSize);
|
|
94
|
+
let pos = 0;
|
|
95
|
+
for (const part of [...localParts, ...centralParts, eocd]) {
|
|
96
|
+
out.set(part, pos);
|
|
97
|
+
pos += part.length;
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
// ─── File extension helper ────────────────────────────────────────────────────
|
|
102
|
+
function fileExt(type) {
|
|
103
|
+
if (type === "bpmn")
|
|
104
|
+
return ".bpmn";
|
|
105
|
+
if (type === "dmn")
|
|
106
|
+
return ".dmn";
|
|
107
|
+
return ".form";
|
|
108
|
+
}
|
|
109
|
+
// ─── Public ───────────────────────────────────────────────────────────────────
|
|
110
|
+
export async function exportProjectAsZip(api) {
|
|
111
|
+
const projectId = api.getCurrentProjectId();
|
|
112
|
+
if (!projectId)
|
|
113
|
+
return;
|
|
114
|
+
const projectName = api.getProjectName(projectId) ?? "project";
|
|
115
|
+
const files = await api.getFiles(projectId);
|
|
116
|
+
const enc = new TextEncoder();
|
|
117
|
+
const entries = [];
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const content = await api.getFileContent(file.id);
|
|
120
|
+
if (content === null)
|
|
121
|
+
continue;
|
|
122
|
+
const suffix = fileExt(file.type);
|
|
123
|
+
const filename = file.name.toLowerCase().endsWith(suffix) ? file.name : `${file.name}${suffix}`;
|
|
124
|
+
entries.push({ name: filename, data: enc.encode(content) });
|
|
125
|
+
}
|
|
126
|
+
if (entries.length === 0)
|
|
127
|
+
return;
|
|
128
|
+
const zip = buildZip(entries);
|
|
129
|
+
const blob = new Blob([zip.buffer], { type: "application/zip" });
|
|
130
|
+
const url = URL.createObjectURL(blob);
|
|
131
|
+
const a = document.createElement("a");
|
|
132
|
+
a.href = url;
|
|
133
|
+
a.download = `${projectName}.zip`;
|
|
134
|
+
a.click();
|
|
135
|
+
URL.revokeObjectURL(url);
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
2
|
+
import type { MainMenuApi } from "../main-menu/index.js";
|
|
3
|
+
import { StorageApi, type StorageApiOptions } from "./storage-api.js";
|
|
4
|
+
import type { FileType } from "./types.js";
|
|
5
|
+
export type { FileType, WorkspaceRecord, ProjectRecord, FileRecord, FileContentRecord, } from "./types.js";
|
|
6
|
+
export { StorageApi } from "./storage-api.js";
|
|
7
|
+
export type { StorageApiOptions } from "./storage-api.js";
|
|
8
|
+
export { showInputDialog, showConfirmDialog } from "./dialog.js";
|
|
9
|
+
/** Options for {@link createStoragePlugin}. */
|
|
10
|
+
export interface StoragePluginOptions extends StorageApiOptions {
|
|
11
|
+
/** The main menu plugin instance (must have an `api` property). */
|
|
12
|
+
mainMenu: CanvasPlugin & {
|
|
13
|
+
api: MainMenuApi;
|
|
14
|
+
};
|
|
15
|
+
/** Returns the currently open tabs with their latest content. */
|
|
16
|
+
getOpenTabs(): Array<{
|
|
17
|
+
tabId: string;
|
|
18
|
+
name: string;
|
|
19
|
+
type: FileType;
|
|
20
|
+
content: string;
|
|
21
|
+
}>;
|
|
22
|
+
/** Title to restore when leaving a project. Defaults to "". */
|
|
23
|
+
initialTitle?: string;
|
|
24
|
+
/** Called when the user clicks "Leave" in the project info bar. */
|
|
25
|
+
onLeaveProject?: () => void;
|
|
26
|
+
/** Called after the IndexedDB caches have finished loading. Use this to refresh any UI that depends on storage data (e.g. the recent-projects dropdown). */
|
|
27
|
+
onReady?: () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Called when the user renames the current file via the main menu.
|
|
30
|
+
* Update the corresponding tab's display name from this callback.
|
|
31
|
+
*/
|
|
32
|
+
onRenameCurrentFile?: (fileId: string, name: string) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates an IndexedDB-backed storage plugin.
|
|
36
|
+
*
|
|
37
|
+
* Integrates with the main menu plugin to provide workspace/project navigation
|
|
38
|
+
* via drill-down menus. Auto-saves BPMN changes with a 500 ms debounce.
|
|
39
|
+
* Persists the last-opened project across page refreshes.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createStoragePlugin(options: StoragePluginOptions): CanvasPlugin & {
|
|
42
|
+
api: StorageApi;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|