hub-list-sort.mjs
88 lines 3.0 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago
1 /**
2 * Pure list sort helpers for Hub notes and proposals (used by hub.js + tests).
3 */
4
5 export function noteTimestampForSort(n) {
6 if (!n || typeof n !== 'object') return 0;
7 const tryParse = (s) => {
8 if (s == null || s === '') return 0;
9 const t = Date.parse(String(s));
10 return Number.isNaN(t) ? 0 : t;
11 };
12 const t1 = tryParse(n.updated);
13 if (t1) return t1;
14 const t2 = tryParse(n.date);
15 return t2 || 0;
16 }
17
18 /** @param {string} dayKey - e.g. YYYY-MM-DD from calendar display */
19 export function yearFromDayKey(dayKey) {
20 if (!dayKey || typeof dayKey !== 'string') return 0;
21 const m = dayKey.match(/^(\d{4})/);
22 return m ? parseInt(m[1], 10) : 0;
23 }
24
25 /**
26 * @param {(a: object, b: object) => number} noteSortOrCalendarDayCmp - (a,b) => string compare of day keys
27 */
28 export function sortNotesList(notes, mode, noteSortOrCalendarDay) {
29 const out = Array.isArray(notes) ? notes.slice() : [];
30 const dayKey = (n) => (typeof noteSortOrCalendarDay === 'function' ? noteSortOrCalendarDay(n) : '') || '';
31 const cmpPath = (a, b) => String(a.path || '').localeCompare(String(b.path || ''));
32 const cmpTitle = (a, b) =>
33 String(a.title || a.path || '').localeCompare(String(b.title || b.path || ''));
34 switch (mode) {
35 case 'date_asc':
36 return out.sort(
37 (a, b) => noteTimestampForSort(a) - noteTimestampForSort(b) || cmpPath(a, b),
38 );
39 case 'year_desc':
40 return out.sort((a, b) => {
41 const yd = yearFromDayKey(dayKey(b)) - yearFromDayKey(dayKey(a));
42 if (yd !== 0) return yd;
43 return noteTimestampForSort(b) - noteTimestampForSort(a) || cmpPath(a, b);
44 });
45 case 'year_asc':
46 return out.sort((a, b) => {
47 const ya = yearFromDayKey(dayKey(a)) - yearFromDayKey(dayKey(b));
48 if (ya !== 0) return ya;
49 return noteTimestampForSort(a) - noteTimestampForSort(b) || cmpPath(a, b);
50 });
51 case 'path_asc':
52 return out.sort(cmpPath);
53 case 'title_asc':
54 return out.sort(cmpTitle);
55 case 'date_desc':
56 default:
57 return out.sort(
58 (a, b) => noteTimestampForSort(b) - noteTimestampForSort(a) || cmpPath(a, b),
59 );
60 }
61 }
62
63 export function proposalTimestamp(p) {
64 if (!p || typeof p !== 'object') return 0;
65 const t = Date.parse(String(p.updated_at || p.created_at || ''));
66 return Number.isNaN(t) ? 0 : t;
67 }
68
69 export function sortProposalsList(list, mode) {
70 const out = Array.isArray(list) ? list.slice() : [];
71 const cmpPath = (a, b) => String(a.path || '').localeCompare(String(b.path || ''));
72 const cmpStatus = (a, b) => String(a.status || '').localeCompare(String(b.status || ''));
73 switch (mode) {
74 case 'updated_asc':
75 return out.sort(
76 (a, b) => proposalTimestamp(a) - proposalTimestamp(b) || cmpPath(a, b),
77 );
78 case 'path_asc':
79 return out.sort(cmpPath);
80 case 'status_asc':
81 return out.sort((a, b) => cmpStatus(a, b) || proposalTimestamp(b) - proposalTimestamp(a));
82 case 'updated_desc':
83 default:
84 return out.sort(
85 (a, b) => proposalTimestamp(b) - proposalTimestamp(a) || cmpPath(a, b),
86 );
87 }
88 }
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 1 day ago