@unbrained/pm-web 2026.8.7 → 2026.8.14
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/CHANGELOG.md +16 -0
- package/dist/app.d.ts +16 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -1
- package/dist/auth.d.ts +5 -0
- package/dist/auth.js.map +1 -1
- package/dist/board.d.ts +53 -0
- package/dist/board.js +48 -0
- package/dist/board.js.map +1 -1
- package/dist/crypto.d.ts +23 -0
- package/dist/crypto.js +32 -0
- package/dist/crypto.js.map +1 -1
- package/dist/db.d.ts +19 -0
- package/dist/db.js +19 -0
- package/dist/db.js.map +1 -1
- package/dist/ical.d.ts +72 -0
- package/dist/ical.js +73 -0
- package/dist/ical.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +52 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/auth.d.ts +8 -0
- package/dist/middleware/auth.js.map +1 -1
- package/dist/oidc.d.ts +87 -0
- package/dist/oidc.js +113 -0
- package/dist/oidc.js.map +1 -1
- package/dist/routes/admin.js +15 -0
- package/dist/routes/admin.js.map +1 -1
- package/dist/routes/github.js +13 -0
- package/dist/routes/github.js.map +1 -1
- package/dist/routes/oidc.d.ts +10 -0
- package/dist/routes/oidc.js +51 -0
- package/dist/routes/oidc.js.map +1 -1
- package/dist/routes/pm.js +132 -1
- package/dist/routes/pm.js.map +1 -1
- package/dist/routes/sharing.js +8 -0
- package/dist/routes/sharing.js.map +1 -1
- package/dist/services/mutation-event-watcher.js +13 -0
- package/dist/services/mutation-event-watcher.js.map +1 -1
- package/dist/services/pm-runner.d.ts +82 -0
- package/dist/services/pm-runner.js +121 -0
- package/dist/services/pm-runner.js.map +1 -1
- package/dist/services/project-watcher.d.ts +22 -0
- package/dist/services/project-watcher.js +51 -0
- package/dist/services/project-watcher.js.map +1 -1
- package/dist/services/realtime-bus.d.ts +46 -0
- package/dist/services/realtime-bus.js +59 -0
- package/dist/services/realtime-bus.js.map +1 -1
- package/dist/services/sse.d.ts +134 -0
- package/dist/services/sse.js +145 -0
- package/dist/services/sse.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +5 -3
- package/public/src/app.js +44 -1
- package/public/src/app.js.map +1 -1
- package/public/src/app.ts +44 -1
- package/public/src/components/modals.js +11 -0
- package/public/src/components/modals.js.map +1 -1
- package/public/src/components/modals.ts +11 -0
- package/public/src/components/toast.js +2 -0
- package/public/src/components/toast.js.map +1 -1
- package/public/src/components/toast.ts +2 -0
- package/public/src/constants.js +21 -4
- package/public/src/constants.js.map +1 -1
- package/public/src/constants.ts +21 -4
- package/public/src/filters.js +10 -7
- package/public/src/filters.js.map +1 -1
- package/public/src/filters.ts +10 -7
- package/public/src/i18n.js +11 -1
- package/public/src/i18n.js.map +1 -1
- package/public/src/i18n.ts +13 -1
- package/public/src/state.js +3 -0
- package/public/src/state.js.map +1 -1
- package/public/src/state.ts +3 -0
- package/public/src/sw.ts +71 -7
- package/public/src/theme.js +13 -1
- package/public/src/theme.js.map +1 -1
- package/public/src/theme.ts +15 -1
- package/public/src/types.ts +2 -0
- package/public/src/utils.js +26 -1
- package/public/src/utils.js.map +1 -1
- package/public/src/utils.ts +26 -1
- package/public/src/views/activity.js +1 -0
- package/public/src/views/activity.js.map +1 -1
- package/public/src/views/activity.ts +1 -0
- package/public/src/views/admin.js +134 -0
- package/public/src/views/admin.js.map +1 -1
- package/public/src/views/admin.ts +134 -0
- package/public/src/views/auth.js +31 -0
- package/public/src/views/auth.js.map +1 -1
- package/public/src/views/auth.ts +31 -0
- package/public/src/views/calendar.js +3 -0
- package/public/src/views/calendar.js.map +1 -1
- package/public/src/views/calendar.ts +3 -0
- package/public/src/views/comments-audit.js +1 -0
- package/public/src/views/comments-audit.js.map +1 -1
- package/public/src/views/comments-audit.ts +1 -0
- package/public/src/views/config.js +67 -0
- package/public/src/views/config.js.map +1 -1
- package/public/src/views/config.ts +67 -0
- package/public/src/views/context.js +2 -0
- package/public/src/views/context.js.map +1 -1
- package/public/src/views/context.ts +2 -0
- package/public/src/views/create.js +3 -0
- package/public/src/views/create.js.map +1 -1
- package/public/src/views/create.ts +3 -0
- package/public/src/views/dedupe.js +1 -0
- package/public/src/views/dedupe.js.map +1 -1
- package/public/src/views/dedupe.ts +1 -0
- package/public/src/views/export.js +6 -0
- package/public/src/views/export.js.map +1 -1
- package/public/src/views/export.ts +6 -0
- package/public/src/views/github.js +58 -0
- package/public/src/views/github.js.map +1 -1
- package/public/src/views/github.ts +58 -0
- package/public/src/views/graph-canvas.js +18 -0
- package/public/src/views/graph-canvas.js.map +1 -1
- package/public/src/views/graph-canvas.ts +20 -0
- package/public/src/views/graph.js +41 -0
- package/public/src/views/graph.js.map +1 -1
- package/public/src/views/graph.ts +42 -1
- package/public/src/views/groups.js +45 -0
- package/public/src/views/groups.js.map +1 -1
- package/public/src/views/groups.ts +45 -0
- package/public/src/views/guide.js +3 -0
- package/public/src/views/guide.js.map +1 -1
- package/public/src/views/guide.ts +3 -0
- package/public/src/views/health.js +3 -0
- package/public/src/views/health.js.map +1 -1
- package/public/src/views/health.ts +3 -0
- package/public/src/views/items.js +196 -6
- package/public/src/views/items.js.map +1 -1
- package/public/src/views/items.ts +196 -6
- package/public/src/views/normalize.js +2 -0
- package/public/src/views/normalize.js.map +1 -1
- package/public/src/views/normalize.ts +2 -0
- package/public/src/views/packages.js +41 -0
- package/public/src/views/packages.js.map +1 -1
- package/public/src/views/packages.ts +41 -0
- package/public/src/views/plan-execution.js +6 -0
- package/public/src/views/plan-execution.js.map +1 -1
- package/public/src/views/plan-execution.ts +8 -0
- package/public/src/views/plan.js +145 -0
- package/public/src/views/plan.js.map +1 -1
- package/public/src/views/plan.ts +146 -1
- package/public/src/views/projects.js +60 -0
- package/public/src/views/projects.js.map +1 -1
- package/public/src/views/projects.ts +60 -0
- package/public/src/views/router.js +43 -0
- package/public/src/views/router.js.map +1 -1
- package/public/src/views/router.ts +43 -0
- package/public/src/views/search.js +5 -0
- package/public/src/views/search.js.map +1 -1
- package/public/src/views/search.ts +5 -0
- package/public/src/views/settings.js +36 -0
- package/public/src/views/settings.js.map +1 -1
- package/public/src/views/settings.ts +36 -0
- package/public/src/views/shared.js +1 -0
- package/public/src/views/shared.js.map +1 -1
- package/public/src/views/shared.ts +1 -0
- package/public/src/views/sharing.js +32 -0
- package/public/src/views/sharing.js.map +1 -1
- package/public/src/views/sharing.ts +32 -0
- package/public/src/views/stats.js +1 -0
- package/public/src/views/stats.js.map +1 -1
- package/public/src/views/stats.ts +1 -0
- package/public/src/views/templates.js +4 -0
- package/public/src/views/templates.js.map +1 -1
- package/public/src/views/templates.ts +4 -0
- package/public/src/views/validate.js +1 -0
- package/public/src/views/validate.js.map +1 -1
- package/public/src/views/validate.ts +1 -0
- package/public/sw.js +60 -5
|
@@ -6,6 +6,14 @@ import { api } from '../api.js';
|
|
|
6
6
|
import { escHtml } from '../utils.js';
|
|
7
7
|
import { showModal, hideModal, createModal, confirmDialog } from '../components/modals.js';
|
|
8
8
|
import { toast } from '../components/toast.js';
|
|
9
|
+
/**
|
|
10
|
+
* Derives a display record (name, detail line, two-letter avatar, and group
|
|
11
|
+
* flag) for a single share row, preferring group fields when the row
|
|
12
|
+
* references a group and falling back through user fields otherwise.
|
|
13
|
+
*
|
|
14
|
+
* @param share - the share row to summarize.
|
|
15
|
+
* @returns display fields for rendering a member row.
|
|
16
|
+
*/
|
|
9
17
|
function shareDisplay(share) {
|
|
10
18
|
const isGroup = Boolean(share.group_id || share.groupId);
|
|
11
19
|
const name = isGroup
|
|
@@ -16,6 +24,10 @@ function shareDisplay(share) {
|
|
|
16
24
|
: (share.user_email || share.email || '');
|
|
17
25
|
return { name, detail, avatar: name.slice(0, 2).toUpperCase(), isGroup };
|
|
18
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Renders the project sharing page header and a placeholder, then loads the
|
|
29
|
+
* current list of shares. Shows an empty state when no project is selected.
|
|
30
|
+
*/
|
|
19
31
|
export async function renderSharingView() {
|
|
20
32
|
const el = document.getElementById('content-sharing');
|
|
21
33
|
if (!el)
|
|
@@ -38,6 +50,11 @@ export async function renderSharingView() {
|
|
|
38
50
|
<div id="shares-list"><div class="loading-state"><div class="loading-spinner"></div></div></div>`;
|
|
39
51
|
await loadShares();
|
|
40
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Fetches the shares for the current project and renders each one as a
|
|
55
|
+
* member row with its permission and a remove control, or an empty state
|
|
56
|
+
* when nobody has been invited yet.
|
|
57
|
+
*/
|
|
41
58
|
async function loadShares() {
|
|
42
59
|
const el = document.getElementById('shares-list');
|
|
43
60
|
if (!el)
|
|
@@ -84,6 +101,10 @@ async function loadShares() {
|
|
|
84
101
|
el.innerHTML = `<div class="empty-state"><div class="empty-state-text">Error: ${escHtml(err instanceof Error ? err.message : String(err))}</div></div>`;
|
|
85
102
|
}
|
|
86
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Builds and displays the invite dialog for sharing the current project,
|
|
106
|
+
* collecting an email or group id and a permission level.
|
|
107
|
+
*/
|
|
87
108
|
export function openShareModal() {
|
|
88
109
|
createModal('share-modal', 'Invite to Project', `
|
|
89
110
|
<div class="form-group">
|
|
@@ -105,6 +126,11 @@ export function openShareModal() {
|
|
|
105
126
|
<button class="btn btn-primary" onclick="window.__app.submitShare()"><span>Send Invite</span></button>`);
|
|
106
127
|
showModal('share-modal');
|
|
107
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Reads the invite form fields and posts a new share for the current project
|
|
131
|
+
* using the entered email or group id and selected permission. Surfaces
|
|
132
|
+
* validation and server errors inline and refreshes the list on success.
|
|
133
|
+
*/
|
|
108
134
|
export async function submitShare() {
|
|
109
135
|
const email = document.getElementById('share-email')?.value?.trim() || '';
|
|
110
136
|
const groupId = document.getElementById('share-group-id')?.value?.trim() || '';
|
|
@@ -137,6 +163,12 @@ export async function submitShare() {
|
|
|
137
163
|
}
|
|
138
164
|
}
|
|
139
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Asks for confirmation then deletes the given share from the current
|
|
168
|
+
* project, refreshing the list and showing errors as toasts.
|
|
169
|
+
*
|
|
170
|
+
* @param shareId - identifier of the share to revoke.
|
|
171
|
+
*/
|
|
140
172
|
export function removeShare(shareId) {
|
|
141
173
|
confirmDialog('Remove Access?', 'The user will lose access to this project.', async () => {
|
|
142
174
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharing.js","sourceRoot":"","sources":["sharing.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sharing.js","sourceRoot":"","sources":["sharing.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,14 @@ import { showModal, hideModal, createModal, confirmDialog } from '../components/
|
|
|
8
8
|
import { toast } from '../components/toast.js';
|
|
9
9
|
import type { ShareRow, SharesResponse } from '../api-types.js';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Derives a display record (name, detail line, two-letter avatar, and group
|
|
13
|
+
* flag) for a single share row, preferring group fields when the row
|
|
14
|
+
* references a group and falling back through user fields otherwise.
|
|
15
|
+
*
|
|
16
|
+
* @param share - the share row to summarize.
|
|
17
|
+
* @returns display fields for rendering a member row.
|
|
18
|
+
*/
|
|
11
19
|
function shareDisplay(share: ShareRow): { name: string; detail: string; avatar: string; isGroup: boolean } {
|
|
12
20
|
const isGroup = Boolean(share.group_id || share.groupId);
|
|
13
21
|
const name = isGroup
|
|
@@ -19,6 +27,10 @@ function shareDisplay(share: ShareRow): { name: string; detail: string; avatar:
|
|
|
19
27
|
return { name, detail, avatar: name.slice(0, 2).toUpperCase(), isGroup };
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Renders the project sharing page header and a placeholder, then loads the
|
|
32
|
+
* current list of shares. Shows an empty state when no project is selected.
|
|
33
|
+
*/
|
|
22
34
|
export async function renderSharingView(): Promise<void> {
|
|
23
35
|
const el = document.getElementById('content-sharing');
|
|
24
36
|
if (!el) return;
|
|
@@ -38,6 +50,11 @@ export async function renderSharingView(): Promise<void> {
|
|
|
38
50
|
await loadShares();
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Fetches the shares for the current project and renders each one as a
|
|
55
|
+
* member row with its permission and a remove control, or an empty state
|
|
56
|
+
* when nobody has been invited yet.
|
|
57
|
+
*/
|
|
41
58
|
async function loadShares(): Promise<void> {
|
|
42
59
|
const el = document.getElementById('shares-list');
|
|
43
60
|
if (!el) return;
|
|
@@ -82,6 +99,10 @@ async function loadShares(): Promise<void> {
|
|
|
82
99
|
}
|
|
83
100
|
}
|
|
84
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Builds and displays the invite dialog for sharing the current project,
|
|
104
|
+
* collecting an email or group id and a permission level.
|
|
105
|
+
*/
|
|
85
106
|
export function openShareModal(): void {
|
|
86
107
|
createModal('share-modal','Invite to Project',`
|
|
87
108
|
<div class="form-group">
|
|
@@ -106,6 +127,11 @@ export function openShareModal(): void {
|
|
|
106
127
|
showModal('share-modal');
|
|
107
128
|
}
|
|
108
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Reads the invite form fields and posts a new share for the current project
|
|
132
|
+
* using the entered email or group id and selected permission. Surfaces
|
|
133
|
+
* validation and server errors inline and refreshes the list on success.
|
|
134
|
+
*/
|
|
109
135
|
export async function submitShare(): Promise<void> {
|
|
110
136
|
const email = (document.getElementById('share-email') as HTMLInputElement | null)?.value?.trim() || '';
|
|
111
137
|
const groupId = (document.getElementById('share-group-id') as HTMLInputElement | null)?.value?.trim() || '';
|
|
@@ -129,6 +155,12 @@ export async function submitShare(): Promise<void> {
|
|
|
129
155
|
}
|
|
130
156
|
}
|
|
131
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Asks for confirmation then deletes the given share from the current
|
|
160
|
+
* project, refreshing the list and showing errors as toasts.
|
|
161
|
+
*
|
|
162
|
+
* @param shareId - identifier of the share to revoke.
|
|
163
|
+
*/
|
|
132
164
|
export function removeShare(shareId: string): void {
|
|
133
165
|
confirmDialog('Remove Access?', 'The user will lose access to this project.', async () => {
|
|
134
166
|
try {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { state } from '../state.js';
|
|
5
5
|
import { api } from '../api.js';
|
|
6
6
|
import { escHtml, statusBadge, typeIcon } from '../utils.js';
|
|
7
|
+
/** Renders project statistics — total, open, closed, blocked, and completion cards, plus by-status and by-type breakdown bars and any project health issues — fetched in parallel from the stats, aggregate, and health endpoints. */
|
|
7
8
|
export async function renderStatsView() {
|
|
8
9
|
const el = document.getElementById('content-stats');
|
|
9
10
|
if (!el)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.js","sourceRoot":"","sources":["stats.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { api } from '../api.js';
|
|
|
6
6
|
import { escHtml, statusBadge, typeIcon } from '../utils.js';
|
|
7
7
|
import type { HealthResponse, StatsResponse } from '../api-types.js';
|
|
8
8
|
|
|
9
|
+
/** Renders project statistics — total, open, closed, blocked, and completion cards, plus by-status and by-type breakdown bars and any project health issues — fetched in parallel from the stats, aggregate, and health endpoints. */
|
|
9
10
|
export async function renderStatsView(): Promise<void> {
|
|
10
11
|
const el = document.getElementById('content-stats');
|
|
11
12
|
if (!el) return;
|
|
@@ -6,6 +6,7 @@ import { api } from '../api.js';
|
|
|
6
6
|
import { escHtml, typeIcon } from '../utils.js';
|
|
7
7
|
import { toast } from '../components/toast.js';
|
|
8
8
|
import { showView } from './router.js';
|
|
9
|
+
/** Renders the templates view header for the current project, then fetches and renders the available item templates. */
|
|
9
10
|
export async function renderTemplatesView() {
|
|
10
11
|
const el = document.getElementById('content-templates');
|
|
11
12
|
if (!el)
|
|
@@ -27,6 +28,7 @@ export async function renderTemplatesView() {
|
|
|
27
28
|
<div id="templates-content"><div class="loading-state"><div class="loading-spinner"></div></div></div>`;
|
|
28
29
|
await fetchAndRenderTemplates();
|
|
29
30
|
}
|
|
31
|
+
/** Loads item templates for the current project from the templates endpoint and renders either an empty-state hint or a responsive grid of template cards. */
|
|
30
32
|
async function fetchAndRenderTemplates() {
|
|
31
33
|
const pid = state.currentProject?.id;
|
|
32
34
|
if (!pid)
|
|
@@ -62,6 +64,7 @@ async function fetchAndRenderTemplates() {
|
|
|
62
64
|
el.innerHTML = `<div class="empty-state"><div class="empty-state-text">Failed to load templates: ${escHtml(err instanceof Error ? err.message : String(err))}</div></div>`;
|
|
63
65
|
}
|
|
64
66
|
}
|
|
67
|
+
/** Renders a single template card showing its name, type icon, priority badge, tags, and description, with a button to create a new item from it. */
|
|
65
68
|
function renderTemplateCard(t) {
|
|
66
69
|
const name = t.name || t.id || 'Unnamed';
|
|
67
70
|
const type = t.type || t.defaults?.type || '';
|
|
@@ -87,6 +90,7 @@ function renderTemplateCard(t) {
|
|
|
87
90
|
</div>
|
|
88
91
|
</div>`;
|
|
89
92
|
}
|
|
93
|
+
/** Navigates to the create-item view and pre-fills its fields (type, priority, tags, description, sprint, release, assignee, acceptance criteria) from the selected template. */
|
|
90
94
|
export function createFromTemplate(name, template) {
|
|
91
95
|
// Navigate to create view and pre-fill from template
|
|
92
96
|
showView('create');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["templates.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { toast } from '../components/toast.js';
|
|
|
8
8
|
import { showView } from './router.js';
|
|
9
9
|
import type { TemplateEntry, TemplatesResponse } from '../api-types.js';
|
|
10
10
|
|
|
11
|
+
/** Renders the templates view header for the current project, then fetches and renders the available item templates. */
|
|
11
12
|
export async function renderTemplatesView(): Promise<void> {
|
|
12
13
|
const el = document.getElementById('content-templates');
|
|
13
14
|
if (!el) return;
|
|
@@ -29,6 +30,7 @@ export async function renderTemplatesView(): Promise<void> {
|
|
|
29
30
|
await fetchAndRenderTemplates();
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/** Loads item templates for the current project from the templates endpoint and renders either an empty-state hint or a responsive grid of template cards. */
|
|
32
34
|
async function fetchAndRenderTemplates(): Promise<void> {
|
|
33
35
|
const pid = state.currentProject?.id;
|
|
34
36
|
if (!pid) return;
|
|
@@ -61,6 +63,7 @@ async function fetchAndRenderTemplates(): Promise<void> {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
/** Renders a single template card showing its name, type icon, priority badge, tags, and description, with a button to create a new item from it. */
|
|
64
67
|
function renderTemplateCard(t: TemplateEntry): string {
|
|
65
68
|
const name = t.name || t.id || 'Unnamed';
|
|
66
69
|
const type = t.type || t.defaults?.type || '';
|
|
@@ -87,6 +90,7 @@ function renderTemplateCard(t: TemplateEntry): string {
|
|
|
87
90
|
</div>`;
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
/** Navigates to the create-item view and pre-fills its fields (type, priority, tags, description, sprint, release, assignee, acceptance criteria) from the selected template. */
|
|
90
94
|
export function createFromTemplate(name: string, template: TemplateEntry): void {
|
|
91
95
|
// Navigate to create view and pre-fill from template
|
|
92
96
|
showView('create');
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { state } from '../state.js';
|
|
5
5
|
import { api } from '../api.js';
|
|
6
6
|
import { escHtml } from '../utils.js';
|
|
7
|
+
/** Renders metadata and lifecycle validation results for the current project: a combined list of error and warning issues with item links, an optional summary, and an overall pass/fail status. */
|
|
7
8
|
export async function renderValidateView() {
|
|
8
9
|
const el = document.getElementById('content-validate');
|
|
9
10
|
if (!el)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { api } from '../api.js';
|
|
|
6
6
|
import { escHtml } from '../utils.js';
|
|
7
7
|
import type { ValidateIssue, ValidateResponse } from '../api-types.js';
|
|
8
8
|
|
|
9
|
+
/** Renders metadata and lifecycle validation results for the current project: a combined list of error and warning issues with item links, an optional summary, and an overall pass/fail status. */
|
|
9
10
|
export async function renderValidateView(): Promise<void> {
|
|
10
11
|
const el = document.getElementById('content-validate');
|
|
11
12
|
if (!el) return;
|
package/public/sw.js
CHANGED
|
@@ -100,6 +100,9 @@ const OFFLINE_HTML = `<!DOCTYPE html>
|
|
|
100
100
|
</div>
|
|
101
101
|
</body>
|
|
102
102
|
</html>`;
|
|
103
|
+
/** Open (creating on first run) the IndexedDB database backing the offline
|
|
104
|
+
* mutation queue, ensuring the `mutations` object store and its timestamp
|
|
105
|
+
* index exist. Resolves with the ready database handle. */
|
|
103
106
|
function openMutationDB() {
|
|
104
107
|
return new Promise((resolve, reject) => {
|
|
105
108
|
const request = indexedDB.open(MUTATION_DB, 1);
|
|
@@ -156,19 +159,25 @@ async function queueMutation(method, path, body) {
|
|
|
156
159
|
return false;
|
|
157
160
|
}
|
|
158
161
|
}
|
|
162
|
+
/** Read every queued mutation out of IndexedDB in insertion order. Returns
|
|
163
|
+
* `{ ok: true, mutations }` on success (including an empty array when the
|
|
164
|
+
* queue is genuinely empty) or `{ ok: false, error }` on storage failure so
|
|
165
|
+
* callers can distinguish an empty queue from an unreadable one instead of
|
|
166
|
+
* treating both as drained. */
|
|
159
167
|
async function getQueuedMutations() {
|
|
160
168
|
try {
|
|
161
169
|
const db = await openMutationDB();
|
|
162
170
|
const tx = db.transaction(MUTATION_STORE, 'readonly');
|
|
163
171
|
const store = tx.objectStore(MUTATION_STORE);
|
|
164
|
-
|
|
172
|
+
const mutations = await new Promise((resolve, reject) => {
|
|
165
173
|
const request = store.getAll();
|
|
166
174
|
request.onsuccess = () => resolve(request.result);
|
|
167
175
|
request.onerror = () => reject(request.error);
|
|
168
176
|
});
|
|
177
|
+
return { ok: true, mutations };
|
|
169
178
|
}
|
|
170
|
-
catch {
|
|
171
|
-
return
|
|
179
|
+
catch (error) {
|
|
180
|
+
return { ok: false, error };
|
|
172
181
|
}
|
|
173
182
|
}
|
|
174
183
|
/**
|
|
@@ -189,10 +198,22 @@ async function clearMutation(id) {
|
|
|
189
198
|
return false;
|
|
190
199
|
}
|
|
191
200
|
}
|
|
201
|
+
/** Replay queued mutations to the API in order, removing each on success and
|
|
202
|
+
* stopping at the first failure so it can retry later, then post-message the
|
|
203
|
+
* connected clients with how many were replayed or remain. A storage read
|
|
204
|
+
* failure is never treated as a drained queue: the initial read failure
|
|
205
|
+
* aborts the flush, and a final read failure reports a partial result rather
|
|
206
|
+
* than claiming all mutations were replayed. */
|
|
192
207
|
async function flushMutationQueue() {
|
|
193
|
-
const
|
|
208
|
+
const read = await getQueuedMutations();
|
|
209
|
+
if (!read.ok) {
|
|
210
|
+
console.warn('Failed to read mutation queue:', read.error);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const mutations = read.mutations;
|
|
194
214
|
if (mutations.length === 0)
|
|
195
215
|
return;
|
|
216
|
+
let replayed = 0;
|
|
196
217
|
for (const mut of mutations) {
|
|
197
218
|
try {
|
|
198
219
|
const opts = {
|
|
@@ -210,6 +231,7 @@ async function flushMutationQueue() {
|
|
|
210
231
|
// avoid duplicate replays on the next flush; it will retry later.
|
|
211
232
|
break;
|
|
212
233
|
}
|
|
234
|
+
replayed++;
|
|
213
235
|
}
|
|
214
236
|
else {
|
|
215
237
|
console.warn('Offline mutation failed:', mut.method, mut.path, res.status);
|
|
@@ -223,8 +245,25 @@ async function flushMutationQueue() {
|
|
|
223
245
|
}
|
|
224
246
|
}
|
|
225
247
|
// Notify clients about replayed mutations
|
|
226
|
-
const
|
|
248
|
+
const remainingRead = await getQueuedMutations();
|
|
227
249
|
const clients = await sw.clients.matchAll();
|
|
250
|
+
if (!remainingRead.ok) {
|
|
251
|
+
// Could not re-read the queue — do NOT claim all mutations were replayed.
|
|
252
|
+
// Report a partial result with the known replayed count so unreplayed
|
|
253
|
+
// mutations are not treated as drained.
|
|
254
|
+
console.warn('Failed to re-read mutation queue after replay:', remainingRead.error);
|
|
255
|
+
if (mutations.length > 0) {
|
|
256
|
+
clients.forEach((client) => {
|
|
257
|
+
client.postMessage({
|
|
258
|
+
type: 'MUTATIONS_PARTIAL',
|
|
259
|
+
replayed,
|
|
260
|
+
remaining: mutations.length - replayed,
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const remaining = remainingRead.mutations;
|
|
228
267
|
if (remaining.length === 0 && mutations.length > 0) {
|
|
229
268
|
clients.forEach((client) => {
|
|
230
269
|
client.postMessage({ type: 'MUTATIONS_REPLAYED', count: mutations.length });
|
|
@@ -385,3 +424,19 @@ sw.addEventListener('sync', (event) => {
|
|
|
385
424
|
sw.addEventListener('online', () => {
|
|
386
425
|
void flushMutationQueue();
|
|
387
426
|
});
|
|
427
|
+
// ── Test-only: expose queue internals ──
|
|
428
|
+
// app.ts registers this file as a CLASSIC worker (`register('/sw.js', ...)`
|
|
429
|
+
// with no `type: 'module'`), so it cannot use `export` — a module-mode script
|
|
430
|
+
// fails to load under a classic registration, which would take offline support
|
|
431
|
+
// down. That leaves a global as the only seam a test can reach.
|
|
432
|
+
//
|
|
433
|
+
// It is inert in the browser because a classic service worker is the only
|
|
434
|
+
// script that ever runs in its own global scope: no page script, extension or
|
|
435
|
+
// import shares it, so nothing exists that could set the flag before this line
|
|
436
|
+
// executes. That invariant is the registration mode, not the flag name — if
|
|
437
|
+
// app.ts ever registers with `type: 'module'`, replace this with real exports
|
|
438
|
+
// rather than keeping both.
|
|
439
|
+
const __testGlobals = globalThis;
|
|
440
|
+
if (__testGlobals.__swTestHarness) {
|
|
441
|
+
__testGlobals.__swInternals = { getQueuedMutations, flushMutationQueue, queueMutation, clearMutation };
|
|
442
|
+
}
|