@grove-dev/astro 0.3.1 → 0.3.4

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 (163) hide show
  1. package/README.md +9 -75
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +11 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/display.d.ts +1 -26
  6. package/dist/lib/display.d.ts.map +1 -1
  7. package/dist/lib/display.js +1 -103
  8. package/dist/lib/display.js.map +1 -1
  9. package/dist/lib/format.d.ts +1 -28
  10. package/dist/lib/format.d.ts.map +1 -1
  11. package/dist/lib/format.js +1 -71
  12. package/dist/lib/format.js.map +1 -1
  13. package/dist/lib/lenses.d.ts +1 -57
  14. package/dist/lib/lenses.d.ts.map +1 -1
  15. package/dist/lib/lenses.js +1 -198
  16. package/dist/lib/lenses.js.map +1 -1
  17. package/dist/lib/repo.d.ts +1 -19
  18. package/dist/lib/repo.d.ts.map +1 -1
  19. package/dist/lib/repo.js +1 -30
  20. package/dist/lib/repo.js.map +1 -1
  21. package/dist/lib/scores.d.ts +1 -36
  22. package/dist/lib/scores.d.ts.map +1 -1
  23. package/dist/lib/scores.js +1 -75
  24. package/dist/lib/scores.js.map +1 -1
  25. package/dist/lib/search.d.ts +1 -113
  26. package/dist/lib/search.d.ts.map +1 -1
  27. package/dist/lib/search.js +1 -379
  28. package/dist/lib/search.js.map +1 -1
  29. package/dist/lib/taxonomy-counts.d.ts +1 -10
  30. package/dist/lib/taxonomy-counts.d.ts.map +1 -1
  31. package/dist/lib/taxonomy-counts.js +1 -21
  32. package/dist/lib/taxonomy-counts.js.map +1 -1
  33. package/package.json +23 -11
  34. package/src/components/ContributorsGrid.astro +3 -3
  35. package/src/components/CurationGrid.astro +2 -2
  36. package/src/components/DirectoryIndexClient.astro +240 -0
  37. package/src/components/FilterGroupMenu.astro +8 -4
  38. package/src/components/FinalCta.astro +41 -0
  39. package/src/components/Hero.astro +15 -18
  40. package/src/components/Icon.astro +35 -7
  41. package/src/components/IndexRow.astro +2 -2
  42. package/src/components/ItemCard.astro +2 -7
  43. package/src/components/RefinePanel.astro +7 -7
  44. package/src/components/SmartLensTabs.astro +9 -5
  45. package/src/components/StackGrid.astro +1 -1
  46. package/src/components/SubmissionClient.astro +133 -0
  47. package/src/index.ts +11 -1
  48. package/src/layouts/BaseLayout.astro +30 -8
  49. package/src/layouts/Footer.astro +25 -56
  50. package/src/layouts/Header.astro +33 -15
  51. package/src/layouts/ThemeToggle.astro +7 -3
  52. package/src/lib/display.ts +1 -111
  53. package/src/lib/format.ts +1 -64
  54. package/src/lib/lenses.ts +1 -220
  55. package/src/lib/repo.ts +1 -32
  56. package/src/lib/scores.ts +1 -90
  57. package/src/lib/search.ts +1 -418
  58. package/src/lib/taxonomy-counts.ts +1 -26
  59. package/{templates/default/src/data/records.ts → src/server/directory.ts} +12 -8
  60. package/src/server/index.ts +2 -0
  61. package/src/server/models.ts +436 -0
  62. package/dist/template-routes.test.d.ts +0 -2
  63. package/dist/template-routes.test.d.ts.map +0 -1
  64. package/dist/template-routes.test.js +0 -63
  65. package/dist/template-routes.test.js.map +0 -1
  66. package/dist/theme.test.d.ts +0 -2
  67. package/dist/theme.test.d.ts.map +0 -1
  68. package/dist/theme.test.js +0 -60
  69. package/dist/theme.test.js.map +0 -1
  70. package/src/template-routes.test.ts +0 -103
  71. package/src/theme.test.ts +0 -76
  72. package/templates/default/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
  73. package/templates/default/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  74. package/templates/default/.github/ISSUE_TEMPLATE/record_submission.md +0 -48
  75. package/templates/default/.github/pull_request_template.md +0 -27
  76. package/templates/default/.github/workflows/build.yml +0 -53
  77. package/templates/default/.github/workflows/cleanup-stale-records.yml +0 -46
  78. package/templates/default/.github/workflows/daily-refresh.yml +0 -51
  79. package/templates/default/.github/workflows/sync-contributors.yml +0 -51
  80. package/templates/default/.github/workflows/sync-github-metadata.yml +0 -56
  81. package/templates/default/.github/workflows/validate-data.yml +0 -33
  82. package/templates/default/astro.config.mjs +0 -25
  83. package/templates/default/content/pages/about.md +0 -66
  84. package/templates/default/content/pages/methodology.md +0 -103
  85. package/templates/default/data/records/.gitkeep +0 -0
  86. package/templates/default/data/records/coolify.yml +0 -46
  87. package/templates/default/data/records/gitea.yml +0 -46
  88. package/templates/default/data/records/hoppscotch.yml +0 -47
  89. package/templates/default/data/records/inventree.yml +0 -47
  90. package/templates/default/data/records/label-studio.yml +0 -46
  91. package/templates/default/data/records/logseq.yml +0 -48
  92. package/templates/default/data/records/private-gpt.yml +0 -47
  93. package/templates/default/data/records/wakapi.yml +0 -44
  94. package/templates/default/data/taxonomy/categories.yml +0 -47
  95. package/templates/default/data/taxonomy/distribution-channels.yml +0 -43
  96. package/templates/default/data/taxonomy/platforms.yml +0 -27
  97. package/templates/default/data/taxonomy/stacks.yml +0 -41
  98. package/templates/default/grove.config.ts +0 -36
  99. package/templates/default/package.json +0 -43
  100. package/templates/default/public/icons/platforms/android.svg +0 -1
  101. package/templates/default/public/icons/platforms/apple-dark.svg +0 -1
  102. package/templates/default/public/icons/platforms/apple-light.svg +0 -1
  103. package/templates/default/public/icons/platforms/chrome.svg +0 -1
  104. package/templates/default/public/icons/platforms/chromeos.svg +0 -5
  105. package/templates/default/public/icons/platforms/desktop.svg +0 -4
  106. package/templates/default/public/icons/platforms/embedded.svg +0 -5
  107. package/templates/default/public/icons/platforms/ios.svg +0 -1
  108. package/templates/default/public/icons/platforms/linux.svg +0 -1
  109. package/templates/default/public/icons/platforms/macos.svg +0 -1
  110. package/templates/default/public/icons/platforms/ubuntu.svg +0 -1
  111. package/templates/default/public/icons/platforms/web.svg +0 -5
  112. package/templates/default/public/icons/platforms/windows.svg +0 -6
  113. package/templates/default/public/icons/stacks/android.svg +0 -1
  114. package/templates/default/public/icons/stacks/apple-dark.svg +0 -1
  115. package/templates/default/public/icons/stacks/apple-light.svg +0 -1
  116. package/templates/default/public/icons/stacks/bun.svg +0 -1
  117. package/templates/default/public/icons/stacks/capacitor.svg +0 -14
  118. package/templates/default/public/icons/stacks/clojure.svg +0 -1
  119. package/templates/default/public/icons/stacks/clojurescript.svg +0 -1
  120. package/templates/default/public/icons/stacks/dart.svg +0 -1
  121. package/templates/default/public/icons/stacks/deno.svg +0 -1
  122. package/templates/default/public/icons/stacks/django.svg +0 -1
  123. package/templates/default/public/icons/stacks/docker.svg +0 -1
  124. package/templates/default/public/icons/stacks/firebase.svg +0 -1
  125. package/templates/default/public/icons/stacks/flutter.svg +0 -1
  126. package/templates/default/public/icons/stacks/go.svg +0 -1
  127. package/templates/default/public/icons/stacks/graphql.svg +0 -1
  128. package/templates/default/public/icons/stacks/ionic.svg +0 -4
  129. package/templates/default/public/icons/stacks/java.svg +0 -1
  130. package/templates/default/public/icons/stacks/javascript.svg +0 -1
  131. package/templates/default/public/icons/stacks/kotlin.svg +0 -1
  132. package/templates/default/public/icons/stacks/llm.svg +0 -1
  133. package/templates/default/public/icons/stacks/mongodb.svg +0 -1
  134. package/templates/default/public/icons/stacks/node.js.svg +0 -1
  135. package/templates/default/public/icons/stacks/nodejs.svg +0 -1
  136. package/templates/default/public/icons/stacks/python.svg +0 -1
  137. package/templates/default/public/icons/stacks/rag.svg +0 -7
  138. package/templates/default/public/icons/stacks/react-native.svg +0 -1
  139. package/templates/default/public/icons/stacks/react.svg +0 -1
  140. package/templates/default/public/icons/stacks/rust.svg +0 -1
  141. package/templates/default/public/icons/stacks/solidity.svg +0 -1
  142. package/templates/default/public/icons/stacks/sveltekit.svg +0 -1
  143. package/templates/default/public/icons/stacks/swift.svg +0 -1
  144. package/templates/default/public/icons/stacks/tensorflow.svg +0 -1
  145. package/templates/default/public/icons/stacks/typescript.svg +0 -1
  146. package/templates/default/public/icons/stacks/vue.svg +0 -1
  147. package/templates/default/public/llms-full.txt +0 -83
  148. package/templates/default/public/llms.txt +0 -11
  149. package/templates/default/public/og-image.svg +0 -48
  150. package/templates/default/public/robots.txt +0 -53
  151. package/templates/default/public/sitemap.xml +0 -63
  152. package/templates/default/src/pages/404.astro +0 -64
  153. package/templates/default/src/pages/[slug]/[recordSlug].astro +0 -691
  154. package/templates/default/src/pages/[slug]/index.astro +0 -482
  155. package/templates/default/src/pages/about.astro +0 -189
  156. package/templates/default/src/pages/apps/[recordSlug].astro +0 -34
  157. package/templates/default/src/pages/contributors.astro +0 -175
  158. package/templates/default/src/pages/index.astro +0 -233
  159. package/templates/default/src/pages/sitemap.xml.ts +0 -89
  160. package/templates/default/src/pages/submit.astro +0 -281
  161. package/templates/default/src/styles/global.css +0 -33
  162. package/templates/default/tsconfig.json +0 -9
  163. package/templates/default/wrangler.jsonc +0 -28
@@ -1,380 +1,2 @@
1
- import { labelDisplay, lensDisplay, statusDisplay } from "./display.js";
2
- /** Available sort orders, in UI order. */
3
- export const SORT_OPTIONS = [
4
- { value: "recently-updated", label: "Recently updated" },
5
- { value: "most-starred", label: "Most starred" },
6
- { value: "recently-added", label: "Recently added" },
7
- { value: "best-overall", label: "Best overall" },
8
- { value: "alphabetical", label: "Alphabetical" },
9
- ];
10
- const DEFAULT_SORT = "recently-updated";
11
- const DEFAULT_PAGE = 1;
12
- const DEFAULT_PAGE_SIZE = 20;
13
- const KEYS = {
14
- q: "q",
15
- stacks: "stack",
16
- platforms: "platform",
17
- categories: "category",
18
- labels: "label",
19
- licenses: "license",
20
- statuses: "status",
21
- lens: "lens",
22
- sort: "sort",
23
- page: "page",
24
- };
25
- /**
26
- * Read filters from a URLSearchParams (or anything URLSearchParams-shaped,
27
- * e.g. the result of `new URL(req.url).searchParams`).
28
- */
29
- export function filtersFromSearchParams(sp) {
30
- const rawSort = sp.get(KEYS.sort);
31
- // Backwards-compat: old "most-mature" sort now maps to "best-overall".
32
- const normalizedSort = rawSort === "most-mature" ? "best-overall" : rawSort;
33
- const sort = normalizedSort && SORT_OPTIONS.some((o) => o.value === normalizedSort)
34
- ? normalizedSort
35
- : undefined;
36
- const rawPage = Number(sp.get(KEYS.page));
37
- const page = Number.isFinite(rawPage) && rawPage >= 1 ? Math.floor(rawPage) : undefined;
38
- const q = sp.get(KEYS.q);
39
- const lens = sp.get(KEYS.lens);
40
- return {
41
- ...(q !== null ? { q } : {}),
42
- stacks: sp.getAll(KEYS.stacks).filter(Boolean),
43
- platforms: sp.getAll(KEYS.platforms).filter(Boolean),
44
- categories: sp.getAll(KEYS.categories).filter(Boolean),
45
- labels: sp.getAll(KEYS.labels).filter(Boolean),
46
- licenses: sp.getAll(KEYS.licenses).filter(Boolean),
47
- statuses: sp.getAll(KEYS.statuses).flatMap((s) => s.split(",")).filter(Boolean),
48
- ...(lens !== null ? { lens } : {}),
49
- ...(sort !== undefined ? { sort } : {}),
50
- ...(page !== undefined ? { page } : {}),
51
- };
52
- }
53
- /**
54
- * Serialize a filters object back to URLSearchParams.
55
- * Undefined / empty values are dropped. Defaults (sort, page 1, comfortable
56
- * density) are also dropped to keep URLs short and canonical.
57
- */
58
- export function searchParamsFromFilters(f) {
59
- const sp = new URLSearchParams();
60
- if (f.q)
61
- sp.set(KEYS.q, f.q);
62
- for (const v of f.stacks ?? [])
63
- sp.append(KEYS.stacks, v);
64
- for (const v of f.platforms ?? [])
65
- sp.append(KEYS.platforms, v);
66
- for (const v of f.categories ?? [])
67
- sp.append(KEYS.categories, v);
68
- for (const v of f.labels ?? [])
69
- sp.append(KEYS.labels, v);
70
- for (const v of f.licenses ?? [])
71
- sp.append(KEYS.licenses, v);
72
- if (f.statuses?.length)
73
- sp.set(KEYS.statuses, f.statuses.join(","));
74
- if (f.lens)
75
- sp.set(KEYS.lens, f.lens);
76
- if (f.sort && f.sort !== DEFAULT_SORT)
77
- sp.set(KEYS.sort, f.sort);
78
- if (f.page && f.page !== DEFAULT_PAGE)
79
- sp.set(KEYS.page, String(f.page));
80
- return sp;
81
- }
82
- /** True if any filter is active (i.e. the result list isn't "all items"). */
83
- export function hasAnyFilter(f) {
84
- if (f.q && f.q.trim())
85
- return true;
86
- if (f.lens)
87
- return true;
88
- return Boolean((f.stacks?.length ?? 0) +
89
- (f.platforms?.length ?? 0) +
90
- (f.categories?.length ?? 0) +
91
- (f.labels?.length ?? 0) +
92
- (f.licenses?.length ?? 0) +
93
- (f.statuses?.length ?? 0));
94
- }
95
- /** How many items per page. Constant for now; future versions may vary. */
96
- export const PAGE_SIZE = DEFAULT_PAGE_SIZE;
97
- /**
98
- * Sort items in-place-free: returns a new array. Stable for ties.
99
- * Apps missing the sort key (e.g. no stars) sink to the bottom rather
100
- * than vanishing.
101
- */
102
- function recordName(record) {
103
- return record.kind === "resource" ? record.title : record.name;
104
- }
105
- function projectStars(record) {
106
- return record.kind === "project" ? record.github?.stars ?? 0 : 0;
107
- }
108
- function recordUpdatedAt(record) {
109
- if (record.kind === "project")
110
- return record.github?.pushedAt ?? null;
111
- if (record.kind === "resource")
112
- return record.publishedAt ?? null;
113
- return null;
114
- }
115
- function recordAddedAt(record) {
116
- return record.curation?.reviewedAt ?? null;
117
- }
118
- export function applySort(items, sort) {
119
- const arr = items.slice();
120
- const ts = (s) => (s ? new Date(s).valueOf() : 0);
121
- switch (sort) {
122
- case "most-starred":
123
- arr.sort((a, b) => projectStars(b) - projectStars(a));
124
- break;
125
- case "recently-updated":
126
- arr.sort((a, b) => ts(recordUpdatedAt(b)) - ts(recordUpdatedAt(a)));
127
- break;
128
- case "recently-added":
129
- arr.sort((a, b) => ts(recordAddedAt(b)) - ts(recordAddedAt(a)));
130
- break;
131
- case "best-overall": {
132
- const reviewed = (a) => (a.curation?.reviewed ? 1 : 0);
133
- const visible = (a) => (a.visibility === "keep" ? 1 : 0);
134
- arr.sort((a, b) => {
135
- const reviewedDelta = reviewed(b) - reviewed(a);
136
- if (reviewedDelta !== 0)
137
- return reviewedDelta;
138
- const visibleDelta = visible(b) - visible(a);
139
- if (visibleDelta !== 0)
140
- return visibleDelta;
141
- return projectStars(b) - projectStars(a);
142
- });
143
- break;
144
- }
145
- case "alphabetical":
146
- arr.sort((a, b) => recordName(a).localeCompare(recordName(b)));
147
- break;
148
- }
149
- return arr;
150
- }
151
- /** Slice an array for a given page (1-based). */
152
- export function paginate(items, page, pageSize = PAGE_SIZE) {
153
- const start = (page - 1) * pageSize;
154
- return items.slice(start, start + pageSize);
155
- }
156
- /** Total number of pages given an item count. Always >= 1. */
157
- export function totalPages(itemCount, pageSize = PAGE_SIZE) {
158
- return Math.max(1, Math.ceil(itemCount / pageSize));
159
- }
160
- /** Resolve the effective sort from a filters object, applying default. */
161
- export function effectiveSort(f) {
162
- return f.sort ?? DEFAULT_SORT;
163
- }
164
- /** Resolve the effective page from a filters object, applying default. */
165
- export function effectivePage(f) {
166
- return f.page ?? DEFAULT_PAGE;
167
- }
168
- /**
169
- * Return the subset of items that match all active filters (AND across
170
- * dimensions, OR within a dimension).
171
- *
172
- * `q` is a case-insensitive substring search across name, owner,
173
- * description, and category. Other dimensions are exact match.
174
- */
175
- export function filterRecords(items, f) {
176
- const q = f.q?.trim().toLowerCase();
177
- const stacks = f.stacks?.length ? new Set(f.stacks) : null;
178
- const platforms = f.platforms?.length ? new Set(f.platforms) : null;
179
- const categories = f.categories?.length ? new Set(f.categories) : null;
180
- const labels = f.labels?.length ? new Set(f.labels) : null;
181
- const licenses = f.licenses?.length ? new Set(f.licenses) : null;
182
- const statuses = f.statuses?.length ? new Set(f.statuses) : null;
183
- return items.filter((a) => {
184
- // Text search — match name, owner, description, category, stack,
185
- // stacks, platforms, tags, backend, architecture, stateManagement,
186
- // bestFor, whyListed, license, status.
187
- if (q) {
188
- const repoUrl = a.kind === "project" ? a.repoUrl : a.links.github ?? "";
189
- const ownerMatch = /github\.com\/([^/]+)\//.exec(repoUrl ?? "")?.[1]?.toLowerCase() ?? "";
190
- const projectFields = a.kind === "project"
191
- ? [
192
- a.stack,
193
- ...a.stacks,
194
- ...a.platforms,
195
- a.projectType,
196
- a.difficulty ?? "",
197
- a.codebaseSize ?? "",
198
- ...a.bestFor,
199
- ...a.whyListed,
200
- a.github?.license ?? "",
201
- a.health?.status ? statusDisplay(a.health.status) : "",
202
- ]
203
- : [];
204
- const resourceFields = a.kind === "resource"
205
- ? [a.type, a.topic, a.author ?? ""]
206
- : [];
207
- const entityFields = a.kind === "entity"
208
- ? [a.type, a.location ?? "", a.parent ?? ""]
209
- : [];
210
- const haystack = [
211
- recordName(a),
212
- ownerMatch,
213
- a.description,
214
- a.category,
215
- ...a.tags,
216
- ...projectFields,
217
- ...resourceFields,
218
- ...entityFields,
219
- ]
220
- .join(" ")
221
- .toLowerCase();
222
- if (!haystack.includes(q))
223
- return false;
224
- }
225
- if (stacks) {
226
- if (a.kind !== "project")
227
- return false;
228
- const allStacks = [a.stack, ...a.stacks].filter((stack) => Boolean(stack));
229
- if (!allStacks.some((s) => stacks.has(s)))
230
- return false;
231
- }
232
- if (platforms) {
233
- if (a.kind !== "project")
234
- return false;
235
- if (!a.platforms.some((p) => platforms.has(p)))
236
- return false;
237
- }
238
- if (categories) {
239
- if (!categories.has(a.category))
240
- return false;
241
- }
242
- if (labels) {
243
- if (!a.curation?.labels?.some((l) => labels.has(l)))
244
- return false;
245
- }
246
- if (licenses) {
247
- if (a.kind !== "project")
248
- return false;
249
- const license = a.github?.license;
250
- if (!license || !licenses.has(license))
251
- return false;
252
- }
253
- if (statuses) {
254
- if (a.kind !== "project")
255
- return false;
256
- const status = a.health?.status;
257
- if (!status || !statuses.has(status))
258
- return false;
259
- }
260
- if (f.lens) {
261
- if (!a.curation?.lenses?.includes(f.lens))
262
- return false;
263
- }
264
- return true;
265
- });
266
- }
267
- /** Build a flat list of "active filter" chips for display + removal. */
268
- export function activeFilterChips(f) {
269
- const out = [];
270
- if (f.q && f.q.trim()) {
271
- out.push({ key: "q", value: "", label: `“${f.q}”` });
272
- }
273
- for (const v of f.stacks ?? []) {
274
- out.push({ key: "stacks", value: v, label: `Stack: ${v}` });
275
- }
276
- for (const v of f.platforms ?? []) {
277
- out.push({ key: "platforms", value: v, label: `Platform: ${v}` });
278
- }
279
- for (const v of f.categories ?? []) {
280
- out.push({ key: "categories", value: v, label: `Category: ${v}` });
281
- }
282
- for (const v of f.labels ?? []) {
283
- out.push({ key: "labels", value: v, label: labelDisplay(v) ?? v });
284
- }
285
- for (const v of f.licenses ?? []) {
286
- out.push({ key: "licenses", value: v, label: `License: ${v}` });
287
- }
288
- if (f.lens) {
289
- out.push({ key: "lens", value: f.lens, label: lensDisplay(f.lens) });
290
- }
291
- // Status: collapse the "stale,quiet" composite into a single chip.
292
- if (f.statuses && f.statuses.length) {
293
- const joined = f.statuses.join(",");
294
- if (joined === "stale,quiet") {
295
- out.push({ key: "statuses", value: "stale,quiet", label: statusDisplay("needs-maintainer") });
296
- }
297
- else {
298
- for (const v of f.statuses) {
299
- out.push({ key: "statuses", value: v, label: statusDisplay(v) });
300
- }
301
- }
302
- }
303
- return out;
304
- }
305
- /**
306
- * Return a new filters object with one (key, value) removed.
307
- * - key="q" → clears the search string
308
- * - multi-value keys → removes the single matching value
309
- * Used by the "x" button on each active filter chip.
310
- * Also resets page to 1 so the user doesn't get stranded on a high page
311
- * that no longer has results.
312
- */
313
- export function removeFilter(f, key, value) {
314
- let next;
315
- if (key === "q") {
316
- // `q` is `string | undefined` under exactOptionalPropertyTypes; the
317
- // cleanest way to drop it is to omit the key entirely (delete-style).
318
- const { q: _drop, ...rest } = f;
319
- next = rest;
320
- }
321
- else {
322
- const current = f[key];
323
- if (!current)
324
- return f;
325
- const filtered = current.filter((v) => v !== value);
326
- if (filtered.length === 0) {
327
- const { [key]: _drop, ...rest } = f;
328
- next = rest;
329
- }
330
- else {
331
- next = { ...f, [key]: filtered };
332
- }
333
- }
334
- next.page = 1;
335
- return next;
336
- }
337
- /**
338
- * Build the full list of facet values from the items array, preserving
339
- * a sensible order (frequency desc, then alphabetical for ties).
340
- */
341
- export function buildFacets(items) {
342
- const counts = {
343
- stack: new Map(),
344
- platform: new Map(),
345
- category: new Map(),
346
- label: new Map(),
347
- license: new Map(),
348
- };
349
- for (const a of items) {
350
- if (a.kind === "project") {
351
- const allStacks = new Set([a.stack, ...a.stacks].filter((stack) => Boolean(stack)));
352
- for (const s of allStacks)
353
- counts.stack.set(s, (counts.stack.get(s) ?? 0) + 1);
354
- for (const p of a.platforms)
355
- counts.platform.set(p, (counts.platform.get(p) ?? 0) + 1);
356
- const license = a.github?.license;
357
- if (license)
358
- counts.license.set(license, (counts.license.get(license) ?? 0) + 1);
359
- }
360
- counts.category.set(a.category, (counts.category.get(a.category) ?? 0) + 1);
361
- for (const l of a.curation?.labels ?? [])
362
- counts.label.set(l, (counts.label.get(l) ?? 0) + 1);
363
- }
364
- const sortByCountThenName = (m) => [...m.entries()]
365
- .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
366
- .map(([value, count]) => ({ value, count }));
367
- return {
368
- stacks: sortByCountThenName(counts.stack),
369
- platforms: sortByCountThenName(counts.platform),
370
- categories: sortByCountThenName(counts.category),
371
- labels: sortByCountThenName(counts.label),
372
- licenses: sortByCountThenName(counts.license),
373
- };
374
- }
375
- // ── V1-published API ─────────────────────────────────────────────────
376
- // `IndexFilters` / `IndexSort` are the canonical V1 names for the
377
- // filter-state type. The internal functions (filterRecords, applySort,
378
- // paginate, buildFacets, etc.) operate on the generic `IndexRecord`
379
- // shape and are intentionally framework-agnostic.
1
+ export * from "@grove-dev/core";
380
2
  //# sourceMappingURL=search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAwBxE,0CAA0C;AAC1C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACpD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;CACxC,CAAC;AAIX,MAAM,YAAY,GAAc,kBAAkB,CAAC;AACnD,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,MAAM,IAAI,GAAG;IACX,CAAC,EAAE,GAAG;IACN,MAAM,EAAE,OAAO;IACf,SAAS,EAAE,UAAU;IACrB,UAAU,EAAE,UAAU;IACtB,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAmB;IACzD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,uEAAuE;IACvE,MAAM,cAAc,GAAG,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5E,MAAM,IAAI,GACR,cAAc,IAAK,YAA6C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC;QACtG,CAAC,CAAE,cAA4B;QAC/B,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO;QACL,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACpD,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACtD,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAClD,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/E,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAe;IACrD,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,CAAC;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,IAAI;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,CAAe;IAC1C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,OAAO,CACZ,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAE3C;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAmB;IACrC,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,MAAmB;IACvC,OAAO,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,MAAmB;IAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;IACtE,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,MAAmB;IACxC,OAAO,MAAM,CAAC,QAAQ,EAAE,UAAU,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAoB,EAAE,IAAe;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC1B,MAAM,EAAE,GAAG,CAAC,CAAiB,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,cAAc;YACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,kBAAkB;YACrB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,gBAAgB;YACnB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,OAAO,GAAG,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAChB,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAChD,IAAI,aAAa,KAAK,CAAC;oBAAE,OAAO,aAAa,CAAC;gBAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC7C,IAAI,YAAY,KAAK,CAAC;oBAAE,OAAO,YAAY,CAAC;gBAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QACD,KAAK,cAAc;YACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,MAAM;IACV,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CAAI,KAAU,EAAE,IAAY,EAAE,QAAQ,GAAG,SAAS;IACxE,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;IACpC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,QAAQ,GAAG,SAAS;IAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,CAAe;IAC3C,OAAO,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC;AAChC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,CAAe;IAC3C,OAAO,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAoB,EAAE,CAAe;IACjE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,iEAAiE;QACjE,mEAAmE;QACnE,uCAAuC;QACvC,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;YACxE,MAAM,UAAU,GACd,wBAAwB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACzE,MAAM,aAAa,GACjB,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC;oBACE,CAAC,CAAC,KAAK;oBACP,GAAG,CAAC,CAAC,MAAM;oBACX,GAAG,CAAC,CAAC,SAAS;oBACd,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,UAAU,IAAI,EAAE;oBAClB,CAAC,CAAC,YAAY,IAAI,EAAE;oBACpB,GAAG,CAAC,CAAC,OAAO;oBACZ,GAAG,CAAC,CAAC,SAAS;oBACd,CAAC,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;oBACvB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;iBACvD;gBACH,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,KAAK,UAAU;gBACnB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBACnC,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,YAAY,GAChB,CAAC,CAAC,IAAI,KAAK,QAAQ;gBACjB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,QAAQ,GAAG;gBACf,UAAU,CAAC,CAAC,CAAC;gBACb,UAAU;gBACV,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,QAAQ;gBACV,GAAG,CAAC,CAAC,IAAI;gBACT,GAAG,aAAa;gBAChB,GAAG,cAAc;gBACjB,GAAG,YAAY;aAChB;iBACE,IAAI,CAAC,GAAG,CAAC;iBACT,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1C,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAC7C,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAC3C,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1D,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC/D,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChD,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QACpE,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;YAClC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;QACvD,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;YAChC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAC/B,CAAe;IAEf,MAAM,GAAG,GAAgE,EAAE,CAAC;IAE5E,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,mEAAmE;IACnE,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,CAAe,EACf,GAAuB,EACvB,KAAa;IAEb,IAAI,IAAkB,CAAC;IACvB,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QAChB,oEAAoE;QACpE,sEAAsE;QACtE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAyB,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;QACpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;YACpC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACd,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,IAAI,GAAG,EAAkB;QAChC,QAAQ,EAAE,IAAI,GAAG,EAAkB;QACnC,QAAQ,EAAE,IAAI,GAAG,EAAkB;QACnC,KAAK,EAAE,IAAI,GAAG,EAAkB;QAChC,OAAO,EAAE,IAAI,GAAG,EAAkB;KACnC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC1E,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,SAAS;gBAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS;gBAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;YAClC,IAAI,OAAO;gBAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,mBAAmB,GAAG,CAAC,CAAsB,EAAE,EAAE,CACrD,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;SACb,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvD,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACjD,OAAO;QACL,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/C,UAAU,EAAE,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChD,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,QAAQ,EAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,kEAAkE;AAClE,uEAAuE;AACvE,oEAAoE;AACpE,kDAAkD"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -1,11 +1,2 @@
1
- type TaxonomyRecord = {
2
- category?: string;
3
- stack?: string;
4
- stacks?: string[];
5
- };
6
- /** Number of items in the directory, per category name. */
7
- export declare function countByCategory(items?: TaxonomyRecord[]): Map<string, number>;
8
- /** Number of items in the directory, per primary stack. */
9
- export declare function countByStack(items?: TaxonomyRecord[]): Map<string, number>;
10
- export {};
1
+ export * from "@grove-dev/core";
11
2
  //# sourceMappingURL=taxonomy-counts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"taxonomy-counts.d.ts","sourceRoot":"","sources":["../../src/lib/taxonomy-counts.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,KAAK,GAAE,cAAc,EAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOjF;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,GAAE,cAAc,EAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ9E"}
1
+ {"version":3,"file":"taxonomy-counts.d.ts","sourceRoot":"","sources":["../../src/lib/taxonomy-counts.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -1,22 +1,2 @@
1
- /** Number of items in the directory, per category name. */
2
- export function countByCategory(items = []) {
3
- const m = new Map();
4
- for (const a of items) {
5
- const k = a.category || "Other";
6
- m.set(k, (m.get(k) ?? 0) + 1);
7
- }
8
- return m;
9
- }
10
- /** Number of items in the directory, per primary stack. */
11
- export function countByStack(items = []) {
12
- const m = new Map();
13
- for (const a of items) {
14
- const stacks = new Set([a.stack, ...(a.stacks ?? [])].filter(Boolean));
15
- if (stacks.size === 0)
16
- stacks.add("Other");
17
- for (const stack of stacks)
18
- m.set(stack, (m.get(stack) ?? 0) + 1);
19
- }
20
- return m;
21
- }
1
+ export * from "@grove-dev/core";
22
2
  //# sourceMappingURL=taxonomy-counts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"taxonomy-counts.js","sourceRoot":"","sources":["../../src/lib/taxonomy-counts.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,QAA0B,EAAE;IAC1D,MAAM,CAAC,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;QAChC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,QAA0B,EAAE;IACvD,MAAM,CAAC,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC,CAAC;QACnF,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"taxonomy-counts.js","sourceRoot":"","sources":["../../src/lib/taxonomy-counts.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "@grove-dev/astro",
3
- "version": "0.3.1",
3
+ "version": "0.3.4",
4
4
  "type": "module",
5
- "description": "Astro framework adapter for Grove. Components, layouts, design tokens, and a default template.",
5
+ "description": "Composable Astro UI, data adapters, and integration for Grove directories.",
6
6
  "license": "MIT",
7
+ "engines": {
8
+ "node": ">=22.12.0"
9
+ },
7
10
  "keywords": [
8
11
  "grove",
9
12
  "astro",
10
13
  "ui",
11
- "template",
14
+ "directory",
12
15
  "components",
13
16
  "static-site"
14
17
  ],
@@ -27,8 +30,12 @@
27
30
  },
28
31
  "files": [
29
32
  "dist",
30
- "src",
31
- "templates",
33
+ "src/components",
34
+ "src/layouts",
35
+ "src/lib",
36
+ "src/server",
37
+ "src/index.ts",
38
+ "src/styles.css",
32
39
  "README.md"
33
40
  ],
34
41
  "exports": {
@@ -40,18 +47,23 @@
40
47
  "./components/*.astro": "./src/components/*.astro",
41
48
  "./components/*": "./src/components/*.astro",
42
49
  "./layouts/*.astro": "./src/layouts/*.astro",
43
- "./layouts/*": "./src/layouts/*.astro"
50
+ "./layouts/*": "./src/layouts/*.astro",
51
+ "./server": "./src/server/index.ts"
44
52
  },
45
53
  "dependencies": {
46
- "astro": "^6.4.6",
47
- "@grove-dev/core": "0.3.1",
48
- "@grove-dev/ui": "1.1.1"
54
+ "astro": "^7.1.3",
55
+ "marked": "^18.0.0",
56
+ "sanitize-html": "^2.17.5",
57
+ "@grove-dev/core": "0.3.4"
49
58
  },
50
59
  "peerDependencies": {
51
- "astro": "^6.0.0"
60
+ "astro": "^6.0.0 || ^7.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/sanitize-html": "^2.16.0"
52
64
  },
53
65
  "scripts": {
54
- "build": "tsc -p tsconfig.json",
66
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
55
67
  "check": "tsc -p tsconfig.json --noEmit",
56
68
  "test": "echo \"No astro package tests yet\""
57
69
  }
@@ -36,8 +36,8 @@ const {
36
36
  total,
37
37
  viewAllHref,
38
38
  viewAllLabel = "View all",
39
- title = "Top contributors",
40
- description,
39
+ title = "Built by the community",
40
+ description = "The people improving this directory through code, curation, and review.",
41
41
  class: className = "",
42
42
  } = Astro.props;
43
43
 
@@ -91,7 +91,7 @@ const visible = contributors
91
91
 
92
92
  {visible.length === 0 ? (
93
93
  <p class="m-0 text-sm text-ink-500 dark:text-ink-400">
94
- No contributors yet.
94
+ Community profiles appear after the first repository metadata sync.
95
95
  </p>
96
96
  ) : (
97
97
  <ul
@@ -30,9 +30,9 @@ const columns = [
30
30
  <h3 class="m-0 text-sm font-semibold uppercase tracking-wider text-ink-500 dark:text-ink-400">
31
31
  {column.title}
32
32
  </h3>
33
- <ul class="mt-3 m-0 flex list-none flex-col gap-1.5 p-0">
33
+ <ul class="mt-3 mb-0 flex list-disc flex-col gap-1.5 pl-5">
34
34
  {column.items.map((item) => (
35
- <li class="text-sm text-ink-700 dark:text-ink-200">- {item}</li>
35
+ <li class="text-sm text-ink-700 dark:text-ink-200">{item}</li>
36
36
  ))}
37
37
  </ul>
38
38
  </div>