@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.
Files changed (173) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/app.d.ts +16 -0
  3. package/dist/app.js +16 -0
  4. package/dist/app.js.map +1 -1
  5. package/dist/auth.d.ts +5 -0
  6. package/dist/auth.js.map +1 -1
  7. package/dist/board.d.ts +53 -0
  8. package/dist/board.js +48 -0
  9. package/dist/board.js.map +1 -1
  10. package/dist/crypto.d.ts +23 -0
  11. package/dist/crypto.js +32 -0
  12. package/dist/crypto.js.map +1 -1
  13. package/dist/db.d.ts +19 -0
  14. package/dist/db.js +19 -0
  15. package/dist/db.js.map +1 -1
  16. package/dist/ical.d.ts +72 -0
  17. package/dist/ical.js +73 -0
  18. package/dist/ical.js.map +1 -1
  19. package/dist/index.d.ts +11 -0
  20. package/dist/index.js +52 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/middleware/auth.d.ts +8 -0
  23. package/dist/middleware/auth.js.map +1 -1
  24. package/dist/oidc.d.ts +87 -0
  25. package/dist/oidc.js +113 -0
  26. package/dist/oidc.js.map +1 -1
  27. package/dist/routes/admin.js +15 -0
  28. package/dist/routes/admin.js.map +1 -1
  29. package/dist/routes/github.js +13 -0
  30. package/dist/routes/github.js.map +1 -1
  31. package/dist/routes/oidc.d.ts +10 -0
  32. package/dist/routes/oidc.js +51 -0
  33. package/dist/routes/oidc.js.map +1 -1
  34. package/dist/routes/pm.js +132 -1
  35. package/dist/routes/pm.js.map +1 -1
  36. package/dist/routes/sharing.js +8 -0
  37. package/dist/routes/sharing.js.map +1 -1
  38. package/dist/services/mutation-event-watcher.js +13 -0
  39. package/dist/services/mutation-event-watcher.js.map +1 -1
  40. package/dist/services/pm-runner.d.ts +82 -0
  41. package/dist/services/pm-runner.js +121 -0
  42. package/dist/services/pm-runner.js.map +1 -1
  43. package/dist/services/project-watcher.d.ts +22 -0
  44. package/dist/services/project-watcher.js +51 -0
  45. package/dist/services/project-watcher.js.map +1 -1
  46. package/dist/services/realtime-bus.d.ts +46 -0
  47. package/dist/services/realtime-bus.js +59 -0
  48. package/dist/services/realtime-bus.js.map +1 -1
  49. package/dist/services/sse.d.ts +134 -0
  50. package/dist/services/sse.js +145 -0
  51. package/dist/services/sse.js.map +1 -1
  52. package/manifest.json +1 -1
  53. package/package.json +5 -3
  54. package/public/src/app.js +44 -1
  55. package/public/src/app.js.map +1 -1
  56. package/public/src/app.ts +44 -1
  57. package/public/src/components/modals.js +11 -0
  58. package/public/src/components/modals.js.map +1 -1
  59. package/public/src/components/modals.ts +11 -0
  60. package/public/src/components/toast.js +2 -0
  61. package/public/src/components/toast.js.map +1 -1
  62. package/public/src/components/toast.ts +2 -0
  63. package/public/src/constants.js +21 -4
  64. package/public/src/constants.js.map +1 -1
  65. package/public/src/constants.ts +21 -4
  66. package/public/src/filters.js +10 -7
  67. package/public/src/filters.js.map +1 -1
  68. package/public/src/filters.ts +10 -7
  69. package/public/src/i18n.js +11 -1
  70. package/public/src/i18n.js.map +1 -1
  71. package/public/src/i18n.ts +13 -1
  72. package/public/src/state.js +3 -0
  73. package/public/src/state.js.map +1 -1
  74. package/public/src/state.ts +3 -0
  75. package/public/src/sw.ts +71 -7
  76. package/public/src/theme.js +13 -1
  77. package/public/src/theme.js.map +1 -1
  78. package/public/src/theme.ts +15 -1
  79. package/public/src/types.ts +2 -0
  80. package/public/src/utils.js +26 -1
  81. package/public/src/utils.js.map +1 -1
  82. package/public/src/utils.ts +26 -1
  83. package/public/src/views/activity.js +1 -0
  84. package/public/src/views/activity.js.map +1 -1
  85. package/public/src/views/activity.ts +1 -0
  86. package/public/src/views/admin.js +134 -0
  87. package/public/src/views/admin.js.map +1 -1
  88. package/public/src/views/admin.ts +134 -0
  89. package/public/src/views/auth.js +31 -0
  90. package/public/src/views/auth.js.map +1 -1
  91. package/public/src/views/auth.ts +31 -0
  92. package/public/src/views/calendar.js +3 -0
  93. package/public/src/views/calendar.js.map +1 -1
  94. package/public/src/views/calendar.ts +3 -0
  95. package/public/src/views/comments-audit.js +1 -0
  96. package/public/src/views/comments-audit.js.map +1 -1
  97. package/public/src/views/comments-audit.ts +1 -0
  98. package/public/src/views/config.js +67 -0
  99. package/public/src/views/config.js.map +1 -1
  100. package/public/src/views/config.ts +67 -0
  101. package/public/src/views/context.js +2 -0
  102. package/public/src/views/context.js.map +1 -1
  103. package/public/src/views/context.ts +2 -0
  104. package/public/src/views/create.js +3 -0
  105. package/public/src/views/create.js.map +1 -1
  106. package/public/src/views/create.ts +3 -0
  107. package/public/src/views/dedupe.js +1 -0
  108. package/public/src/views/dedupe.js.map +1 -1
  109. package/public/src/views/dedupe.ts +1 -0
  110. package/public/src/views/export.js +6 -0
  111. package/public/src/views/export.js.map +1 -1
  112. package/public/src/views/export.ts +6 -0
  113. package/public/src/views/github.js +58 -0
  114. package/public/src/views/github.js.map +1 -1
  115. package/public/src/views/github.ts +58 -0
  116. package/public/src/views/graph-canvas.js +18 -0
  117. package/public/src/views/graph-canvas.js.map +1 -1
  118. package/public/src/views/graph-canvas.ts +20 -0
  119. package/public/src/views/graph.js +41 -0
  120. package/public/src/views/graph.js.map +1 -1
  121. package/public/src/views/graph.ts +42 -1
  122. package/public/src/views/groups.js +45 -0
  123. package/public/src/views/groups.js.map +1 -1
  124. package/public/src/views/groups.ts +45 -0
  125. package/public/src/views/guide.js +3 -0
  126. package/public/src/views/guide.js.map +1 -1
  127. package/public/src/views/guide.ts +3 -0
  128. package/public/src/views/health.js +3 -0
  129. package/public/src/views/health.js.map +1 -1
  130. package/public/src/views/health.ts +3 -0
  131. package/public/src/views/items.js +196 -6
  132. package/public/src/views/items.js.map +1 -1
  133. package/public/src/views/items.ts +196 -6
  134. package/public/src/views/normalize.js +2 -0
  135. package/public/src/views/normalize.js.map +1 -1
  136. package/public/src/views/normalize.ts +2 -0
  137. package/public/src/views/packages.js +41 -0
  138. package/public/src/views/packages.js.map +1 -1
  139. package/public/src/views/packages.ts +41 -0
  140. package/public/src/views/plan-execution.js +6 -0
  141. package/public/src/views/plan-execution.js.map +1 -1
  142. package/public/src/views/plan-execution.ts +8 -0
  143. package/public/src/views/plan.js +145 -0
  144. package/public/src/views/plan.js.map +1 -1
  145. package/public/src/views/plan.ts +146 -1
  146. package/public/src/views/projects.js +60 -0
  147. package/public/src/views/projects.js.map +1 -1
  148. package/public/src/views/projects.ts +60 -0
  149. package/public/src/views/router.js +43 -0
  150. package/public/src/views/router.js.map +1 -1
  151. package/public/src/views/router.ts +43 -0
  152. package/public/src/views/search.js +5 -0
  153. package/public/src/views/search.js.map +1 -1
  154. package/public/src/views/search.ts +5 -0
  155. package/public/src/views/settings.js +36 -0
  156. package/public/src/views/settings.js.map +1 -1
  157. package/public/src/views/settings.ts +36 -0
  158. package/public/src/views/shared.js +1 -0
  159. package/public/src/views/shared.js.map +1 -1
  160. package/public/src/views/shared.ts +1 -0
  161. package/public/src/views/sharing.js +32 -0
  162. package/public/src/views/sharing.js.map +1 -1
  163. package/public/src/views/sharing.ts +32 -0
  164. package/public/src/views/stats.js +1 -0
  165. package/public/src/views/stats.js.map +1 -1
  166. package/public/src/views/stats.ts +1 -0
  167. package/public/src/views/templates.js +4 -0
  168. package/public/src/views/templates.js.map +1 -1
  169. package/public/src/views/templates.ts +4 -0
  170. package/public/src/views/validate.js +1 -0
  171. package/public/src/views/validate.js.map +1 -1
  172. package/public/src/views/validate.ts +1 -0
  173. package/public/sw.js +60 -5
@@ -3,22 +3,29 @@
3
3
  // ═══════════════════════════════════════════════════════════════
4
4
  import { escHtml } from '../utils.js';
5
5
 
6
+ /** Display the modal with the given id by setting its display style to flex. */
6
7
  export function showModal(id: string): void {
7
8
  const modal = document.getElementById(id);
8
9
  if (modal) modal.style.display = 'flex';
9
10
  }
10
11
 
12
+ /** Hide the modal with the given id by setting its display style to none. */
11
13
  export function hideModal(id: string): void {
12
14
  const modal = document.getElementById(id);
13
15
  if (modal) modal.style.display = 'none';
14
16
  }
15
17
 
18
+ /** Hide every modal backdrop element in the document by setting each to
19
+ * display none. */
16
20
  export function closeAllModals(): void {
17
21
  document.querySelectorAll('.modal-backdrop').forEach(m => {
18
22
  (m as HTMLElement).style.display = 'none';
19
23
  });
20
24
  }
21
25
 
26
+ /** Build (or rebuild) a modal element with the given id, title, body, and
27
+ * optional footer markup, append it under `#modal-container`, and wire its
28
+ * backdrop-click-to-close behavior. Returns the created modal element. */
22
29
  export function createModal(
23
30
  id: string,
24
31
  title: string,
@@ -47,6 +54,10 @@ export function createModal(
47
54
  return el;
48
55
  }
49
56
 
57
+ /** Open a confirmation modal with a title and description; when the user
58
+ * clicks the confirm button the modal closes and `onConfirm` runs. The
59
+ * `danger` flag switches the styling and default labels to a destructive
60
+ * action, and `labels` overrides the button text. */
50
61
  export function confirmDialog(
51
62
  title: string,
52
63
  desc: string,
@@ -1,3 +1,5 @@
1
+ /** Show a transient toast notification of the given type, appending it to the
2
+ * toast container and removing it after 3.5 seconds. */
1
3
  export function toast(msg, type = 'info') {
2
4
  const el = document.createElement('div');
3
5
  el.className = `toast toast-${type}`;
@@ -1 +1 @@
1
- {"version":3,"file":"toast.js","sourceRoot":"","sources":["toast.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,IAAI,GAAc,MAAM;IACzD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,GAAG,eAAe,IAAI,EAAE,CAAC;IACrC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC7D,IAAI,SAAS;QAAE,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACzC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["toast.ts"],"names":[],"mappings":"AAKA;wDACwD;AACxD,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,IAAI,GAAc,MAAM;IACzD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,GAAG,eAAe,IAAI,EAAE,CAAC;IACrC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC7D,IAAI,SAAS;QAAE,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACzC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
@@ -3,6 +3,8 @@
3
3
  // ═══════════════════════════════════════════════════════════════
4
4
  import type { ToastType } from '../types.js';
5
5
 
6
+ /** Show a transient toast notification of the given type, appending it to the
7
+ * toast container and removing it after 3.5 seconds. */
6
8
  export function toast(msg: string, type: ToastType = 'info'): void {
7
9
  const el = document.createElement('div');
8
10
  el.className = `toast toast-${type}`;
@@ -1,26 +1,43 @@
1
- // Fallback values kept in sync with pm CLI builtins for offline resilience.
2
- // The live schema is fetched from /api/projects/:id/pm/schema per project
3
- // and injected via state.schema; use getTypes()/getStatuses() everywhere.
1
+ /** Item-type names kept in sync with the pm CLI builtins, used as the
2
+ * offline fallback when the live project schema is unavailable. Prefer
3
+ * `getTypes()` everywhere so the fetched schema wins when present. */
4
4
  export const FALLBACK_TYPES = [
5
5
  'Task', 'Feature', 'Issue', 'Epic', 'Milestone', 'Decision', 'Chore', 'Event', 'Meeting', 'Reminder', 'Plan'
6
6
  ];
7
+ /** Lifecycle status names kept in sync with the pm CLI builtins, used as the
8
+ * offline fallback when the live project schema is unavailable. Prefer
9
+ * `getStatuses()` everywhere so the fetched schema wins when present. */
7
10
  export const FALLBACK_STATUSES = ['draft', 'open', 'in_progress', 'blocked', 'closed', 'canceled'];
8
- // Back-compat aliases (avoid widespread refactors, prefer getTypes/getStatuses)
11
+ /** Back-compat alias for `FALLBACK_TYPES`, retained to avoid a widespread
12
+ * refactor; new code should call `getTypes()` instead. */
9
13
  export const TYPES = FALLBACK_TYPES;
14
+ /** Back-compat alias for `FALLBACK_STATUSES`, retained to avoid a widespread
15
+ * refactor; new code should call `getStatuses()` instead. */
10
16
  export const STATUSES = FALLBACK_STATUSES;
17
+ /** Return the item types for a project, preferring the live `schema.types`
18
+ * when non-empty and falling back to the built-in `FALLBACK_TYPES`. */
11
19
  export function getTypes(schema) {
12
20
  return schema?.types?.length ? schema.types : [...FALLBACK_TYPES];
13
21
  }
22
+ /** Return the lifecycle statuses for a project, preferring the live
23
+ * `schema.statuses` when non-empty and falling back to the built-in
24
+ * `FALLBACK_STATUSES`. */
14
25
  export function getStatuses(schema) {
15
26
  return schema?.statuses?.length ? schema.statuses : [...FALLBACK_STATUSES];
16
27
  }
28
+ /** Map of item-type name to the single-character glyph shown in the UI for
29
+ * that type. */
17
30
  export const TYPE_ICONS = {
18
31
  Task: '✓', Feature: '★', Issue: '⚠', Epic: '◈',
19
32
  Milestone: '⚑', Decision: '⚖', Chore: '⚙', Event: '◷', Meeting: '◉', Reminder: '◉', Plan: '◧'
20
33
  };
34
+ /** Map of numeric priority (0–4) to its human-readable label, used for
35
+ * tooltips and accessibility text on priority indicators. */
21
36
  export const PRIORITY_LABELS = {
22
37
  0: 'Critical', 1: 'High', 2: 'Medium', 3: 'Low', 4: 'Minimal'
23
38
  };
39
+ /** Fixed list of navigation view identifiers in display order; mirrors the
40
+ * routing keys accepted by the SPA router. */
24
41
  export const VIEW_NAMES = [
25
42
  'projects', 'items', 'create', 'activity', 'search', 'stats', 'calendar',
26
43
  'context', 'graph', 'sharing', 'groups', 'health', 'dedupe', 'validate', 'settings',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAKA,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,WAAW,EAAC,UAAU,EAAC,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,EAAC,MAAM;CAC1F,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAC,MAAM,EAAC,aAAa,EAAC,SAAS,EAAC,QAAQ,EAAC,UAAU,CAAU,CAAC;AAEvG,gFAAgF;AAChF,MAAM,CAAC,MAAM,KAAK,GAAG,cAAc,CAAC;AACpC,MAAM,CAAC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAE1C,MAAM,UAAU,QAAQ,CAAC,MAA6B;IACpD,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAA6B;IACvD,OAAO,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAA2B;IAChD,IAAI,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;IAC1C,SAAS,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;CACvF,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,CAAC,EAAC,UAAU,EAAE,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,QAAQ,EAAE,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,SAAS;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU,EAAC,OAAO,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAC,UAAU;IAClE,SAAS,EAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,EAAC,UAAU,EAAC,UAAU;IAC5E,QAAQ,EAAC,QAAQ,EAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAC,UAAU,EAAC,gBAAgB,EAAC,QAAQ,EAAC,OAAO;IAC/F,OAAO,EAAC,MAAM;CACN,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAKA;;sEAEsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,WAAW,EAAC,UAAU,EAAC,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,EAAC,MAAM;CAC1F,CAAC;AAEX;;yEAEyE;AACzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAC,MAAM,EAAC,aAAa,EAAC,SAAS,EAAC,QAAQ,EAAC,UAAU,CAAU,CAAC;AAEvG;0DAC0D;AAC1D,MAAM,CAAC,MAAM,KAAK,GAAG,cAAc,CAAC;AACpC;6DAC6D;AAC7D,MAAM,CAAC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAE1C;uEACuE;AACvE,MAAM,UAAU,QAAQ,CAAC,MAA6B;IACpD,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;AACpE,CAAC;AAED;;0BAE0B;AAC1B,MAAM,UAAU,WAAW,CAAC,MAA6B;IACvD,OAAO,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAC7E,CAAC;AAED;gBACgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAA2B;IAChD,IAAI,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;IAC1C,SAAS,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,EAAE,IAAI,EAAC,GAAG;CACvF,CAAC;AAEF;6DAC6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,CAAC,EAAC,UAAU,EAAE,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,QAAQ,EAAE,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,SAAS;CACzD,CAAC;AAEF;8CAC8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU,EAAC,OAAO,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAC,UAAU;IAClE,SAAS,EAAC,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,EAAC,UAAU,EAAC,UAAU;IAC5E,QAAQ,EAAC,QAAQ,EAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAC,UAAU,EAAC,gBAAgB,EAAC,QAAQ,EAAC,OAAO;IAC/F,OAAO,EAAC,MAAM;CACN,CAAC"}
@@ -3,36 +3,53 @@
3
3
  // ═══════════════════════════════════════════════════════════════
4
4
  import type { ProjectSchema } from './types.js';
5
5
 
6
- // Fallback values kept in sync with pm CLI builtins for offline resilience.
7
- // The live schema is fetched from /api/projects/:id/pm/schema per project
8
- // and injected via state.schema; use getTypes()/getStatuses() everywhere.
6
+ /** Item-type names kept in sync with the pm CLI builtins, used as the
7
+ * offline fallback when the live project schema is unavailable. Prefer
8
+ * `getTypes()` everywhere so the fetched schema wins when present. */
9
9
  export const FALLBACK_TYPES = [
10
10
  'Task','Feature','Issue','Epic','Milestone','Decision','Chore','Event','Meeting','Reminder','Plan'
11
11
  ] as const;
12
12
 
13
+ /** Lifecycle status names kept in sync with the pm CLI builtins, used as the
14
+ * offline fallback when the live project schema is unavailable. Prefer
15
+ * `getStatuses()` everywhere so the fetched schema wins when present. */
13
16
  export const FALLBACK_STATUSES = ['draft','open','in_progress','blocked','closed','canceled'] as const;
14
17
 
15
- // Back-compat aliases (avoid widespread refactors, prefer getTypes/getStatuses)
18
+ /** Back-compat alias for `FALLBACK_TYPES`, retained to avoid a widespread
19
+ * refactor; new code should call `getTypes()` instead. */
16
20
  export const TYPES = FALLBACK_TYPES;
21
+ /** Back-compat alias for `FALLBACK_STATUSES`, retained to avoid a widespread
22
+ * refactor; new code should call `getStatuses()` instead. */
17
23
  export const STATUSES = FALLBACK_STATUSES;
18
24
 
25
+ /** Return the item types for a project, preferring the live `schema.types`
26
+ * when non-empty and falling back to the built-in `FALLBACK_TYPES`. */
19
27
  export function getTypes(schema?: ProjectSchema | null): string[] {
20
28
  return schema?.types?.length ? schema.types : [...FALLBACK_TYPES];
21
29
  }
22
30
 
31
+ /** Return the lifecycle statuses for a project, preferring the live
32
+ * `schema.statuses` when non-empty and falling back to the built-in
33
+ * `FALLBACK_STATUSES`. */
23
34
  export function getStatuses(schema?: ProjectSchema | null): string[] {
24
35
  return schema?.statuses?.length ? schema.statuses : [...FALLBACK_STATUSES];
25
36
  }
26
37
 
38
+ /** Map of item-type name to the single-character glyph shown in the UI for
39
+ * that type. */
27
40
  export const TYPE_ICONS: Record<string, string> = {
28
41
  Task:'✓', Feature:'★', Issue:'⚠', Epic:'◈',
29
42
  Milestone:'⚑', Decision:'⚖', Chore:'⚙', Event:'◷', Meeting:'◉', Reminder:'◉', Plan:'◧'
30
43
  };
31
44
 
45
+ /** Map of numeric priority (0–4) to its human-readable label, used for
46
+ * tooltips and accessibility text on priority indicators. */
32
47
  export const PRIORITY_LABELS: Record<number, string> = {
33
48
  0:'Critical', 1:'High', 2:'Medium', 3:'Low', 4:'Minimal'
34
49
  };
35
50
 
51
+ /** Fixed list of navigation view identifiers in display order; mirrors the
52
+ * routing keys accepted by the SPA router. */
36
53
  export const VIEW_NAMES = [
37
54
  'projects','items','create','activity','search','stats','calendar',
38
55
  'context','graph','sharing','groups','health','dedupe','validate','settings',
@@ -1,3 +1,5 @@
1
+ /** Item filter state with every dimension empty, used as the base value when
2
+ * resetting or parsing filters. */
1
3
  export const EMPTY_FILTERS = {
2
4
  status: '', type: '', priority: '', sprint: '', release: '', assignee: '', tag: '',
3
5
  };
@@ -5,8 +7,8 @@ export const EMPTY_FILTERS = {
5
7
  const FILTER_KEYS = [
6
8
  'status', 'type', 'priority', 'sprint', 'release', 'assignee', 'tag',
7
9
  ];
8
- // Serialize active (non-empty) filters into a URLSearchParams. Empty values are
9
- // omitted so the URL stays clean.
10
+ /** Serialize the active (non-empty) filter dimensions into a `URLSearchParams`
11
+ * in a stable key order, omitting empty values so generated URLs stay clean. */
10
12
  export function filtersToSearchParams(f) {
11
13
  const params = new URLSearchParams();
12
14
  for (const key of FILTER_KEYS) {
@@ -16,13 +18,13 @@ export function filtersToSearchParams(f) {
16
18
  }
17
19
  return params;
18
20
  }
19
- // Serialize filters to a query string (without the leading "?"), or "" when no
20
- // filters are active.
21
+ /** Serialize filters to a URL query string without the leading `?`, returning
22
+ * an empty string when no dimensions are active. */
21
23
  export function filtersToQueryString(f) {
22
24
  return filtersToSearchParams(f).toString();
23
25
  }
24
- // Parse filters back out of a URLSearchParams (or query string). Unknown keys
25
- // are ignored; missing keys default to empty.
26
+ /** Parse filter dimensions back out of a `URLSearchParams` or query string,
27
+ * defaulting missing known keys to empty strings and ignoring unknown keys. */
26
28
  export function filtersFromSearchParams(input) {
27
29
  const params = typeof input === 'string' ? new URLSearchParams(input) : input;
28
30
  const result = { ...EMPTY_FILTERS };
@@ -33,7 +35,8 @@ export function filtersFromSearchParams(input) {
33
35
  }
34
36
  return result;
35
37
  }
36
- // True when at least one dimension is set.
38
+ /** Return true when at least one filter dimension has a non-empty trimmed
39
+ * value. */
37
40
  export function hasActiveFilters(f) {
38
41
  return FILTER_KEYS.some((key) => (f[key] ?? '').trim() !== '');
39
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"filters.js","sourceRoot":"","sources":["filters.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CACnF,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,GAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK;CACrE,CAAC;AAEF,gFAAgF;AAChF,kCAAkC;AAClC,MAAM,UAAU,qBAAqB,CAAC,CAAc;IAClD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,sBAAsB;AACtB,MAAM,UAAU,oBAAoB,CAAC,CAAc;IACjD,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC7C,CAAC;AAED,8EAA8E;AAC9E,8CAA8C;AAC9C,MAAM,UAAU,uBAAuB,CAAC,KAA+B;IACrE,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9E,MAAM,MAAM,GAAgB,EAAE,GAAG,aAAa,EAAE,CAAC;IACjD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,gBAAgB,CAAC,CAAc;IAC7C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjE,CAAC"}
1
+ {"version":3,"file":"filters.js","sourceRoot":"","sources":["filters.ts"],"names":[],"mappings":"AAUA;mCACmC;AACnC,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CACnF,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,GAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK;CACrE,CAAC;AAEF;gFACgF;AAChF,MAAM,UAAU,qBAAqB,CAAC,CAAc;IAClD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;oDACoD;AACpD,MAAM,UAAU,oBAAoB,CAAC,CAAc;IACjD,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC7C,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,uBAAuB,CAAC,KAA+B;IACrE,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9E,MAAM,MAAM,GAAgB,EAAE,GAAG,aAAa,EAAE,CAAC;IACjD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;YACY;AACZ,MAAM,UAAU,gBAAgB,CAAC,CAAc;IAC7C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjE,CAAC"}
@@ -8,6 +8,8 @@
8
8
  // free so they can be unit-tested without a DOM.
9
9
  import type { ItemFilters } from './types.js';
10
10
 
11
+ /** Item filter state with every dimension empty, used as the base value when
12
+ * resetting or parsing filters. */
11
13
  export const EMPTY_FILTERS: ItemFilters = {
12
14
  status: '', type: '', priority: '', sprint: '', release: '', assignee: '', tag: '',
13
15
  };
@@ -17,8 +19,8 @@ const FILTER_KEYS: (keyof ItemFilters)[] = [
17
19
  'status', 'type', 'priority', 'sprint', 'release', 'assignee', 'tag',
18
20
  ];
19
21
 
20
- // Serialize active (non-empty) filters into a URLSearchParams. Empty values are
21
- // omitted so the URL stays clean.
22
+ /** Serialize the active (non-empty) filter dimensions into a `URLSearchParams`
23
+ * in a stable key order, omitting empty values so generated URLs stay clean. */
22
24
  export function filtersToSearchParams(f: ItemFilters): URLSearchParams {
23
25
  const params = new URLSearchParams();
24
26
  for (const key of FILTER_KEYS) {
@@ -28,14 +30,14 @@ export function filtersToSearchParams(f: ItemFilters): URLSearchParams {
28
30
  return params;
29
31
  }
30
32
 
31
- // Serialize filters to a query string (without the leading "?"), or "" when no
32
- // filters are active.
33
+ /** Serialize filters to a URL query string without the leading `?`, returning
34
+ * an empty string when no dimensions are active. */
33
35
  export function filtersToQueryString(f: ItemFilters): string {
34
36
  return filtersToSearchParams(f).toString();
35
37
  }
36
38
 
37
- // Parse filters back out of a URLSearchParams (or query string). Unknown keys
38
- // are ignored; missing keys default to empty.
39
+ /** Parse filter dimensions back out of a `URLSearchParams` or query string,
40
+ * defaulting missing known keys to empty strings and ignoring unknown keys. */
39
41
  export function filtersFromSearchParams(input: URLSearchParams | string): ItemFilters {
40
42
  const params = typeof input === 'string' ? new URLSearchParams(input) : input;
41
43
  const result: ItemFilters = { ...EMPTY_FILTERS };
@@ -46,7 +48,8 @@ export function filtersFromSearchParams(input: URLSearchParams | string): ItemFi
46
48
  return result;
47
49
  }
48
50
 
49
- // True when at least one dimension is set.
51
+ /** Return true when at least one filter dimension has a non-empty trimmed
52
+ * value. */
50
53
  export function hasActiveFilters(f: ItemFilters): boolean {
51
54
  return FILTER_KEYS.some((key) => (f[key] ?? '').trim() !== '');
52
55
  }
@@ -153,7 +153,8 @@ export async function initI18n() {
153
153
  syncHtmlLang(currentLocale);
154
154
  applyTranslations();
155
155
  }
156
- /** Current active locale. */
156
+ /** Return the locale currently selected for the session, set by `initI18n` or
157
+ * `setLocale`. Defaults to the English fallback before initialization. */
157
158
  export function getLocale() {
158
159
  return currentLocale;
159
160
  }
@@ -220,6 +221,10 @@ export function applyTranslations(root) {
220
221
  bindAttr(scope, '[data-i18n-placeholder]', 'data-i18n-placeholder', (el, v) => { el.setAttribute('placeholder', v); });
221
222
  bindAttr(scope, '[data-i18n-aria]', 'data-i18n-aria', (el, v) => { el.setAttribute('aria-label', v); });
222
223
  }
224
+ /** For every element in `scope` matching `selector`, read its `attr` data
225
+ * key, resolve the translation (with optional `data-i18n-params`
226
+ * substitutions), and pass the result to `setter`. Used to bind each
227
+ * `data-i18n*` flavor. */
223
228
  function bindAttr(scope, selector, attr, setter) {
224
229
  scope.querySelectorAll(selector).forEach((el) => {
225
230
  const key = el.getAttribute(attr);
@@ -230,6 +235,8 @@ function bindAttr(scope, selector, attr, setter) {
230
235
  setter(el, t(key, params));
231
236
  });
232
237
  }
238
+ /** Parse a `data-i18n-params` JSON string into a parameter object, returning
239
+ * `undefined` when the JSON is missing, malformed, or not a plain object. */
233
240
  function safeParseParams(json) {
234
241
  try {
235
242
  const parsed = JSON.parse(json);
@@ -257,6 +264,9 @@ export function translateError(message) {
257
264
  // Lazy reverse map: English error text → catalog key. Built from enCatalog
258
265
  // so it tracks the catalog without a hand-maintained second table.
259
266
  let cachedErrorReverse = null;
267
+ /** Build and cache a reverse lookup from English error text to its catalog
268
+ * key (covering only `error.*` entries), so server error strings can be
269
+ * mapped back to translatable keys at the display layer. */
260
270
  function errorReverseMap() {
261
271
  if (cachedErrorReverse)
262
272
  return cachedErrorReverse;
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["i18n.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["i18n.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,8 @@ export const LOCALE_STORAGE_KEY = 'pmLocale';
24
24
 
25
25
  /** Locales shipped by this package. The first entry is the default/fallback. */
26
26
  export const SUPPORTED_LOCALES = ['en', 'de', 'es', 'zh'] as const;
27
+ /** String literal union of every locale code this package ships a catalog
28
+ * for, derived from `SUPPORTED_LOCALES`. */
27
29
  export type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
28
30
 
29
31
  const DEFAULT_LOCALE: SupportedLocale = 'en';
@@ -166,7 +168,8 @@ export async function initI18n(): Promise<void> {
166
168
  applyTranslations();
167
169
  }
168
170
 
169
- /** Current active locale. */
171
+ /** Return the locale currently selected for the session, set by `initI18n` or
172
+ * `setLocale`. Defaults to the English fallback before initialization. */
170
173
  export function getLocale(): SupportedLocale {
171
174
  return currentLocale;
172
175
  }
@@ -232,6 +235,10 @@ export function applyTranslations(root?: ParentNode): void {
232
235
  bindAttr(scope, '[data-i18n-aria]', 'data-i18n-aria', (el, v) => { el.setAttribute('aria-label', v); });
233
236
  }
234
237
 
238
+ /** For every element in `scope` matching `selector`, read its `attr` data
239
+ * key, resolve the translation (with optional `data-i18n-params`
240
+ * substitutions), and pass the result to `setter`. Used to bind each
241
+ * `data-i18n*` flavor. */
235
242
  function bindAttr(
236
243
  scope: ParentNode,
237
244
  selector: string,
@@ -247,6 +254,8 @@ function bindAttr(
247
254
  });
248
255
  }
249
256
 
257
+ /** Parse a `data-i18n-params` JSON string into a parameter object, returning
258
+ * `undefined` when the JSON is missing, malformed, or not a plain object. */
250
259
  function safeParseParams(json: string): Record<string, string | number> | undefined {
251
260
  try {
252
261
  const parsed = JSON.parse(json) as unknown;
@@ -274,6 +283,9 @@ export function translateError(message: string): string {
274
283
  // Lazy reverse map: English error text → catalog key. Built from enCatalog
275
284
  // so it tracks the catalog without a hand-maintained second table.
276
285
  let cachedErrorReverse: Map<string, string> | null = null;
286
+ /** Build and cache a reverse lookup from English error text to its catalog
287
+ * key (covering only `error.*` entries), so server error strings can be
288
+ * mapped back to translatable keys at the display layer. */
277
289
  function errorReverseMap(): Map<string, string> {
278
290
  if (cachedErrorReverse) return cachedErrorReverse;
279
291
  const map = new Map<string, string>();
@@ -1,3 +1,6 @@
1
+ /** Mutable singleton holding the SPA's global application state: the signed-in
2
+ * user, loaded projects, the active project and view, item list and filters,
3
+ * and search state. Views read and mutate this directly. */
1
4
  export const state = {
2
5
  user: null,
3
6
  projects: [],
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["state.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,KAAK,GAAa;IAC7B,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,EAAE;IACZ,cAAc,EAAE,IAAI;IACpB,WAAW,EAAE,UAAU;IACvB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,EAAE;IACT,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACnG,WAAW,EAAE,EAAE;IACf,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,IAAI;CACb,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["state.ts"],"names":[],"mappings":"AAKA;;4DAE4D;AAC5D,MAAM,CAAC,MAAM,KAAK,GAAa;IAC7B,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,EAAE;IACZ,cAAc,EAAE,IAAI;IACpB,WAAW,EAAE,UAAU;IACvB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,EAAE;IACT,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACnG,WAAW,EAAE,EAAE;IACf,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,IAAI;CACb,CAAC"}
@@ -3,6 +3,9 @@
3
3
  // ═══════════════════════════════════════════════════════════════
4
4
  import type { AppState } from './types.js';
5
5
 
6
+ /** Mutable singleton holding the SPA's global application state: the signed-in
7
+ * user, loaded projects, the active project and view, item list and filters,
8
+ * and search state. Views read and mutate this directly. */
6
9
  export const state: AppState = {
7
10
  user: null,
8
11
  projects: [],
package/public/src/sw.ts CHANGED
@@ -127,6 +127,9 @@ interface SyncEvent extends ExtendableEvent {
127
127
  readonly tag: string;
128
128
  }
129
129
 
130
+ /** Open (creating on first run) the IndexedDB database backing the offline
131
+ * mutation queue, ensuring the `mutations` object store and its timestamp
132
+ * index exist. Resolves with the ready database handle. */
130
133
  function openMutationDB(): Promise<IDBDatabase> {
131
134
  return new Promise((resolve, reject) => {
132
135
  const request = indexedDB.open(MUTATION_DB, 1);
@@ -185,18 +188,32 @@ async function queueMutation(method: string, path: string, body: unknown): Promi
185
188
  }
186
189
  }
187
190
 
188
- async function getQueuedMutations(): Promise<QueuedMutation[]> {
191
+ /** The outcome of reading the mutation queue: either the mutations were read
192
+ * successfully, or the read failed and the queue state is unknown. The
193
+ * discriminator lets callers distinguish an empty queue from an unreadable
194
+ * one instead of collapsing both into `[]`. */
195
+ type QueueReadResult =
196
+ | { ok: true; mutations: QueuedMutation[] }
197
+ | { ok: false; error: unknown };
198
+
199
+ /** Read every queued mutation out of IndexedDB in insertion order. Returns
200
+ * `{ ok: true, mutations }` on success (including an empty array when the
201
+ * queue is genuinely empty) or `{ ok: false, error }` on storage failure so
202
+ * callers can distinguish an empty queue from an unreadable one instead of
203
+ * treating both as drained. */
204
+ async function getQueuedMutations(): Promise<QueueReadResult> {
189
205
  try {
190
206
  const db = await openMutationDB();
191
207
  const tx = db.transaction(MUTATION_STORE, 'readonly');
192
208
  const store = tx.objectStore(MUTATION_STORE);
193
- return await new Promise<QueuedMutation[]>((resolve, reject) => {
209
+ const mutations = await new Promise<QueuedMutation[]>((resolve, reject) => {
194
210
  const request = store.getAll();
195
211
  request.onsuccess = () => resolve(request.result as QueuedMutation[]);
196
212
  request.onerror = () => reject(request.error);
197
213
  });
198
- } catch {
199
- return [];
214
+ return { ok: true, mutations };
215
+ } catch (error) {
216
+ return { ok: false, error };
200
217
  }
201
218
  }
202
219
 
@@ -218,10 +235,22 @@ async function clearMutation(id: number): Promise<boolean> {
218
235
  }
219
236
  }
220
237
 
238
+ /** Replay queued mutations to the API in order, removing each on success and
239
+ * stopping at the first failure so it can retry later, then post-message the
240
+ * connected clients with how many were replayed or remain. A storage read
241
+ * failure is never treated as a drained queue: the initial read failure
242
+ * aborts the flush, and a final read failure reports a partial result rather
243
+ * than claiming all mutations were replayed. */
221
244
  async function flushMutationQueue(): Promise<void> {
222
- const mutations = await getQueuedMutations();
245
+ const read = await getQueuedMutations();
246
+ if (!read.ok) {
247
+ console.warn('Failed to read mutation queue:', read.error);
248
+ return;
249
+ }
250
+ const mutations = read.mutations;
223
251
  if (mutations.length === 0) return;
224
252
 
253
+ let replayed = 0;
225
254
  for (const mut of mutations) {
226
255
  try {
227
256
  const opts: RequestInit = {
@@ -238,6 +267,7 @@ async function flushMutationQueue(): Promise<void> {
238
267
  // avoid duplicate replays on the next flush; it will retry later.
239
268
  break;
240
269
  }
270
+ replayed++;
241
271
  } else {
242
272
  console.warn('Offline mutation failed:', mut.method, mut.path, res.status);
243
273
  // Stop processing on first failure — try again later
@@ -250,8 +280,25 @@ async function flushMutationQueue(): Promise<void> {
250
280
  }
251
281
 
252
282
  // Notify clients about replayed mutations
253
- const remaining = await getQueuedMutations();
283
+ const remainingRead = await getQueuedMutations();
254
284
  const clients = await sw.clients.matchAll();
285
+ if (!remainingRead.ok) {
286
+ // Could not re-read the queue — do NOT claim all mutations were replayed.
287
+ // Report a partial result with the known replayed count so unreplayed
288
+ // mutations are not treated as drained.
289
+ console.warn('Failed to re-read mutation queue after replay:', remainingRead.error);
290
+ if (mutations.length > 0) {
291
+ clients.forEach((client) => {
292
+ client.postMessage({
293
+ type: 'MUTATIONS_PARTIAL',
294
+ replayed,
295
+ remaining: mutations.length - replayed,
296
+ });
297
+ });
298
+ }
299
+ return;
300
+ }
301
+ const remaining = remainingRead.mutations;
255
302
  if (remaining.length === 0 && mutations.length > 0) {
256
303
  clients.forEach((client) => {
257
304
  client.postMessage({ type: 'MUTATIONS_REPLAYED', count: mutations.length });
@@ -445,4 +492,21 @@ sw.addEventListener('sync', (event: Event) => {
445
492
  // ── Online event: flush queue when connectivity returns ──
446
493
  sw.addEventListener('online', () => {
447
494
  void flushMutationQueue();
448
- });
495
+ });
496
+
497
+ // ── Test-only: expose queue internals ──
498
+ // app.ts registers this file as a CLASSIC worker (`register('/sw.js', ...)`
499
+ // with no `type: 'module'`), so it cannot use `export` — a module-mode script
500
+ // fails to load under a classic registration, which would take offline support
501
+ // down. That leaves a global as the only seam a test can reach.
502
+ //
503
+ // It is inert in the browser because a classic service worker is the only
504
+ // script that ever runs in its own global scope: no page script, extension or
505
+ // import shares it, so nothing exists that could set the flag before this line
506
+ // executes. That invariant is the registration mode, not the flag name — if
507
+ // app.ts ever registers with `type: 'module'`, replace this with real exports
508
+ // rather than keeping both.
509
+ const __testGlobals = globalThis as unknown as Record<string, unknown>;
510
+ if (__testGlobals.__swTestHarness) {
511
+ __testGlobals.__swInternals = { getQueuedMutations, flushMutationQueue, queueMutation, clearMutation };
512
+ }
@@ -20,6 +20,9 @@ const LABEL = {
20
20
  light: 'Theme: light',
21
21
  dark: 'Theme: dark',
22
22
  };
23
+ /** Read the persisted theme choice from localStorage, defaulting to `auto`
24
+ * when no preference is stored or when localStorage is unavailable (e.g.
25
+ * private browsing). */
23
26
  export function getStoredTheme() {
24
27
  try {
25
28
  const v = localStorage.getItem(STORAGE_KEY);
@@ -29,6 +32,9 @@ export function getStoredTheme() {
29
32
  catch { /* localStorage may be unavailable (private mode) */ }
30
33
  return 'auto';
31
34
  }
35
+ /** Apply a theme to the page: set `data-theme` on `<html>`, update the toggle
36
+ * button's glyph/title, and sync the `<meta name="theme-color">` tag so the
37
+ * mobile browser chrome matches the chosen palette. */
32
38
  export function applyTheme(theme) {
33
39
  document.documentElement.setAttribute('data-theme', theme);
34
40
  const btn = document.getElementById('theme-toggle');
@@ -50,6 +56,8 @@ export function applyTheme(theme) {
50
56
  meta.setAttribute('content', color);
51
57
  }
52
58
  }
59
+ /** Persist a theme choice to localStorage and immediately apply it to the
60
+ * document. */
53
61
  export function setTheme(theme) {
54
62
  try {
55
63
  localStorage.setItem(STORAGE_KEY, theme);
@@ -57,12 +65,16 @@ export function setTheme(theme) {
57
65
  catch { /* ignore */ }
58
66
  applyTheme(theme);
59
67
  }
68
+ /** Advance to the next theme in the auto → light → dark order (wrapping
69
+ * around) and persist plus apply the new selection. */
60
70
  export function cycleTheme() {
61
71
  const current = getStoredTheme();
62
72
  const next = ORDER[(ORDER.indexOf(current) + 1) % ORDER.length];
63
73
  setTheme(next);
64
74
  }
65
- // Apply the persisted (or default) theme as early as possible.
75
+ /** Apply the persisted (or default) theme early to avoid a flash of the wrong
76
+ * palette, then register a listener so `auto` mode tracks live OS theme
77
+ * changes. */
66
78
  export function initTheme() {
67
79
  applyTheme(getStoredTheme());
68
80
  // When in auto mode, react to live OS theme changes.
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["theme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["theme.ts"],"names":[],"mappings":"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"}