wiki-formant 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -1
- package/dist/blocks.d.ts +34 -0
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +42 -0
- package/dist/blocks.js.map +1 -1
- package/dist/combobox.d.ts +11 -1
- package/dist/combobox.d.ts.map +1 -1
- package/dist/combobox.js +4 -4
- package/dist/combobox.js.map +1 -1
- package/dist/feed.d.ts +50 -0
- package/dist/feed.d.ts.map +1 -0
- package/dist/feed.js +94 -0
- package/dist/feed.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts +39 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +50 -0
- package/dist/license.js.map +1 -0
- package/dist/react.d.ts +71 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +100 -2
- package/dist/react.js.map +1 -1
- package/dist/revisions.d.ts +99 -0
- package/dist/revisions.d.ts.map +1 -0
- package/dist/revisions.js +175 -0
- package/dist/revisions.js.map +1 -0
- package/dist/well-known.d.ts +27 -0
- package/dist/well-known.d.ts.map +1 -1
- package/dist/well-known.js +30 -0
- package/dist/well-known.js.map +1 -1
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -242,6 +242,62 @@ and a crawler obeys only its most-specific matching group, so an agent with no
|
|
|
242
242
|
group of its own falls through to `*`. Three wikis were measuring five crawlers
|
|
243
243
|
they had never addressed.
|
|
244
244
|
|
|
245
|
+
## Revisions
|
|
246
|
+
|
|
247
|
+
What changed between two versions of a page, and therefore which semver bump to
|
|
248
|
+
ask for. Both wikis had written it and `extractBlocks` was byte-identical
|
|
249
|
+
between the copies; they differed only in what each had learned since.
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const diff = computeRevisionDiff({
|
|
253
|
+
currentVersion: page.version,
|
|
254
|
+
oldContent, newContent, oldTitle, newTitle,
|
|
255
|
+
containers: b =>
|
|
256
|
+
b.type === 'infobox' ? [{ path: 'blocks', blocks: b.blocks }]
|
|
257
|
+
: b.type === 'columns' ? b.columns.map((c, i) => ({ path: `columns.${i}.blocks`, blocks: c.blocks }))
|
|
258
|
+
: null,
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
- **Blocks match by id**, so a block that moved is one `moved` and not a removal
|
|
263
|
+
plus an addition.
|
|
264
|
+
- **Container keys are never diffed as attributes.** They are walked as their own
|
|
265
|
+
entries, and comparing them here would report an infobox as edited every time
|
|
266
|
+
anything inside it changed — turning a prose edit into a structural bump.
|
|
267
|
+
- **The path segment is a parameter**, because `root.1.columns.0.blocks.2` is
|
|
268
|
+
what a reviewing UI anchors on and only the consumer knows how its containers
|
|
269
|
+
are addressed.
|
|
270
|
+
|
|
271
|
+
One copy also built two Maps keyed by a recursive `JSON.stringify` of every
|
|
272
|
+
block, on every save, and never read either one. Matching is by id and always
|
|
273
|
+
was. That half is not here.
|
|
274
|
+
|
|
275
|
+
## Feeds
|
|
276
|
+
|
|
277
|
+
Three repos, four feeds, 47 of 64 significant lines identical — including,
|
|
278
|
+
verbatim in two of them, the comment explaining why the apostrophe escapes
|
|
279
|
+
numerically. `renderFeed` is the union.
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
return new Response(renderFeed(channel, items), { headers: FEED_HEADERS });
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**`lastBuildDate` comes from the newest item, not the clock.** One copy stamped
|
|
286
|
+
`new Date()` on every request, telling every poller the feed had changed when it
|
|
287
|
+
had not — the recrawl the conditional-GET helpers exist to prevent. An empty feed
|
|
288
|
+
carries no build date rather than a fictional one.
|
|
289
|
+
|
|
290
|
+
## Licence declarations
|
|
291
|
+
|
|
292
|
+
S10 wants a licence on every surface, and each repo satisfied that by writing the
|
|
293
|
+
same block again. What is genuinely per-project is the *scope* — which half of a
|
|
294
|
+
site the grant covers and what it excludes — so that is the parameter.
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
const license = ccBy40({ siteName: 'AcuiQ', siteUrl: SITE_URL });
|
|
298
|
+
const block = licenseBlock({ license, scope: 'The protocol compilation and prose', excludes });
|
|
299
|
+
```
|
|
300
|
+
|
|
245
301
|
## Rendered-article passes
|
|
246
302
|
|
|
247
303
|
`wiki-formant/dom` holds what runs against an article element after it is in the document. Not React, so not in `react.tsx`.
|
|
@@ -308,11 +364,15 @@ they name a gap in the corpus in the reader's own words.
|
|
|
308
364
|
| `htmlToMarkdown`, `inlineToMarkdown`, `tableToMarkdown`, `frontmatter`, `markdownDocument`, `decodeEntities` | `wiki-formant/markdown` |
|
|
309
365
|
| `corpusEtag`, `notModified`, `textHeaders`, `markdownHeaders`, `cleanSnippet`, `pageLine` | `wiki-formant/http` |
|
|
310
366
|
| `parsePagination`, `paginatedResponse`, `toOffset` | `wiki-formant/pagination` |
|
|
367
|
+
| `mapBlockTree`, `mapBlockTreeAsync`, `someBlock`, `renderBlockTree` | `wiki-formant/blocks` |
|
|
311
368
|
| `parseVersion`, `formatVersion`, `incrementVersion`, `bump`, `compareVersions` | `wiki-formant/versioning` |
|
|
312
369
|
| `plausibleEvent`, `mcpCallProps`, `searchQueryProps`, `plausibleDomain` | `wiki-formant/analytics` |
|
|
313
370
|
| `comboboxAria`, `listId`, `optionId` | `wiki-formant/combobox` |
|
|
371
|
+
| `computeRevisionDiff`, `diffBlocks`, `extractBlocks`, `classifyChanges`, `changeSummary` | `wiki-formant/revisions` |
|
|
372
|
+
| `renderFeed`, `renderItem`, `escXml`, `cdata`, `clampWords`, `absolutise`, `FEED_HEADERS` | `wiki-formant/feed` |
|
|
373
|
+
| `ccBy40`, `licenseBlock`, `licenseLines`, `licenseNote` | `wiki-formant/license` |
|
|
314
374
|
| `AI_CRAWLERS`, `detectAiBot`, `aiCrawlerTokens`, `aiCrawlerRules` | `wiki-formant/crawlers` |
|
|
315
|
-
| `useCollapsibleSidebar`, `SidebarProvider`, `useSidebar`, `TableOfContents`, `useTypeahead`, `useLinkPreview`, `useClickOutside` | `wiki-formant/react` |
|
|
375
|
+
| `useCollapsibleSidebar`, `SidebarProvider`, `useSidebar`, `TableOfContents`, `useTypeahead`, `useLinkPreview`, `useClickOutside`, `useTableSort`, `useCopy`, `ErrorBoundary` | `wiki-formant/react` |
|
|
316
376
|
| `resolveSidebarOpen`, `sidebarBootScript`, `SIDEBAR_ATTRIBUTE` | `wiki-formant/sidebar` |
|
|
317
377
|
| `addCopyButtons`, `activateTabGroups`, `tweetEmbedSrc`, `onTweetResize`, `hydrateTweetEmbeds`, `sizeTweetEmbeds`, `TWITTER_ORIGIN` | `wiki-formant/dom` |
|
|
318
378
|
| `Iframe`, `YouTube`, `TwitterEmbed`, `createMapEmbed`, `createCodeBlock`, `createTabs` | `wiki-formant/tiptap` |
|
package/dist/blocks.d.ts
CHANGED
|
@@ -42,6 +42,40 @@ export interface BlockTreeOptions<B> {
|
|
|
42
42
|
* needs the sentences adjacent, not interleaved.
|
|
43
43
|
*/
|
|
44
44
|
export declare function renderBlockTree<B>(blocks: readonly B[], opts: BlockTreeOptions<B>): string;
|
|
45
|
+
/**
|
|
46
|
+
* How a container exposes and rebuilds its nested groups.
|
|
47
|
+
*
|
|
48
|
+
* `renderBlockTree` only ever reads groups, so it takes `containers` alone.
|
|
49
|
+
* A transform has to put the mapped blocks back where it found them, which is
|
|
50
|
+
* the second half — and the half every hand-rolled copy of this walk wrote out
|
|
51
|
+
* per block type, at six call sites across two repos.
|
|
52
|
+
*/
|
|
53
|
+
export interface BlockTreeShape<B> {
|
|
54
|
+
/** Nested groups in document order, or `null` for a leaf. */
|
|
55
|
+
containers: (block: B) => B[][] | null;
|
|
56
|
+
/** Rebuild a container from its mapped groups. */
|
|
57
|
+
rebuild: (block: B, groups: B[][]) => B;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Every block in the tree, transformed, with the tree's shape preserved.
|
|
61
|
+
*
|
|
62
|
+
* The three-branch walk this replaces — columns to `columns[].blocks`, infobox
|
|
63
|
+
* to `.blocks`, everything else atomic — was written by hand for heading
|
|
64
|
+
* injection, syntax highlighting, server-side data resolution, feed rendering
|
|
65
|
+
* and twice more besides. Each copy was correct and each had to be found again
|
|
66
|
+
* whenever a container type was added.
|
|
67
|
+
*/
|
|
68
|
+
export declare function mapBlockTree<B>(blocks: readonly B[], map: (block: B) => B, shape: BlockTreeShape<B>): B[];
|
|
69
|
+
/** The async twin. Highlighting and data resolution both await per leaf. */
|
|
70
|
+
export declare function mapBlockTreeAsync<B>(blocks: readonly B[], map: (block: B) => Promise<B>, shape: BlockTreeShape<B>): Promise<B[]>;
|
|
71
|
+
/**
|
|
72
|
+
* Whether any leaf satisfies `predicate`, containers included.
|
|
73
|
+
*
|
|
74
|
+
* The copy this replaces asked "does this page hold a code block?" to decide
|
|
75
|
+
* whether to ship a highlighter, and answered by checking the top level only —
|
|
76
|
+
* so a code block inside an infobox shipped unhighlighted.
|
|
77
|
+
*/
|
|
78
|
+
export declare function someBlock<B>(blocks: readonly B[], predicate: (block: B) => boolean, containers: (block: B) => B[][] | null): boolean;
|
|
45
79
|
/**
|
|
46
80
|
* Fenced blocks, one per tab, each under its label.
|
|
47
81
|
*
|
package/dist/blocks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CAChC;AAID,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,uEAAuE;IACvE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,MAAM,CAe1F;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAOnE;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5E;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,KAAK,SAAe,GACnB,MAAM,CAMR;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAGlE;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAWR;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAE/D"}
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
|
package/dist/blocks.js
CHANGED
|
@@ -34,6 +34,48 @@ export function renderBlockTree(blocks, opts) {
|
|
|
34
34
|
.replace(/\n{3,}/g, '\n\n')
|
|
35
35
|
.trim();
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Every block in the tree, transformed, with the tree's shape preserved.
|
|
39
|
+
*
|
|
40
|
+
* The three-branch walk this replaces — columns to `columns[].blocks`, infobox
|
|
41
|
+
* to `.blocks`, everything else atomic — was written by hand for heading
|
|
42
|
+
* injection, syntax highlighting, server-side data resolution, feed rendering
|
|
43
|
+
* and twice more besides. Each copy was correct and each had to be found again
|
|
44
|
+
* whenever a container type was added.
|
|
45
|
+
*/
|
|
46
|
+
export function mapBlockTree(blocks, map, shape) {
|
|
47
|
+
return blocks.map(block => {
|
|
48
|
+
const groups = shape.containers(block);
|
|
49
|
+
if (!groups)
|
|
50
|
+
return map(block);
|
|
51
|
+
return shape.rebuild(block, groups.map(group => group.map(map)));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** The async twin. Highlighting and data resolution both await per leaf. */
|
|
55
|
+
export async function mapBlockTreeAsync(blocks, map, shape) {
|
|
56
|
+
return Promise.all(blocks.map(async (block) => {
|
|
57
|
+
const groups = shape.containers(block);
|
|
58
|
+
if (!groups)
|
|
59
|
+
return map(block);
|
|
60
|
+
const mapped = await Promise.all(groups.map(group => Promise.all(group.map(map))));
|
|
61
|
+
return shape.rebuild(block, mapped);
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Whether any leaf satisfies `predicate`, containers included.
|
|
66
|
+
*
|
|
67
|
+
* The copy this replaces asked "does this page hold a code block?" to decide
|
|
68
|
+
* whether to ship a highlighter, and answered by checking the top level only —
|
|
69
|
+
* so a code block inside an infobox shipped unhighlighted.
|
|
70
|
+
*/
|
|
71
|
+
export function someBlock(blocks, predicate, containers) {
|
|
72
|
+
return blocks.some(block => {
|
|
73
|
+
const groups = containers(block);
|
|
74
|
+
if (!groups)
|
|
75
|
+
return predicate(block);
|
|
76
|
+
return groups.some(group => someBlock(group, predicate, containers));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
37
79
|
// ---- the shared leaf renderers ----------------------------------------------
|
|
38
80
|
/**
|
|
39
81
|
* Fenced blocks, one per tab, each under its label.
|
package/dist/blocks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,qEAAqE;AACrE,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,qDAAqD;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAkDjE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAI,MAAoB,EAAE,IAAyB;IAChF,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7D,OAAO,MAAM;SACV,GAAG,CAAC,KAAK,CAAC,EAAE;QACX,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,MAAM;aACV,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;aACpE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1B,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,MAAM,CAAC;SACZ,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;SAC1B,IAAI,EAAE,CAAC;AACZ,CAAC;AAmBD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAoB,EACpB,GAAoB,EACpB,KAAwB;IAExB,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,GAA6B,EAC7B,KAAwB;IAExB,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACvB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,MAAoB,EACpB,SAAgC,EAChC,UAAsC;IAEtC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAwB;IACzD,OAAO,IAAI;SACR,GAAG,CACF,CAAC,CAAC,EAAE,CACF,KAAK,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,QAAQ,IAAI,EAAE,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAClH;SACA,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,IAAoB;IAClE,OAAO,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACvE,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAClC,KAA+B,EAC/B,KAAK,GAAG,YAAY;IAEpB,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CACrB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/E,CAAC;IACF,OAAO,OAAO,KAAK,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC7B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAChC,MAAgC,EAChC,KAAqB;IAErB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAC9B;QACE,OAAO,CAAC,CAAC,OAAO,EAAE;QAClB,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,EAAE;QACF,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;KACjD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,QAAQ,CAAC,KAA8B;IACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC"}
|
package/dist/combobox.d.ts
CHANGED
|
@@ -11,6 +11,16 @@ export interface ComboboxInput {
|
|
|
11
11
|
count: number;
|
|
12
12
|
/** Index of the highlighted row. */
|
|
13
13
|
highlight: number;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the surface is actually showing its list. Defaults to `count > 0`.
|
|
16
|
+
*
|
|
17
|
+
* The hook knows how many results it holds; only the surface knows whether it
|
|
18
|
+
* is rendering them. A header that hides its dropdown on blur while the hook
|
|
19
|
+
* still holds items would otherwise claim `aria-expanded` for a list that is
|
|
20
|
+
* not in the document, and point `aria-activedescendant` at a row that is not
|
|
21
|
+
* there — which is the dangling reference this module exists to prevent.
|
|
22
|
+
*/
|
|
23
|
+
open?: boolean;
|
|
14
24
|
}
|
|
15
25
|
export interface ComboboxInputProps {
|
|
16
26
|
role: 'combobox';
|
|
@@ -46,5 +56,5 @@ export declare function listId(baseId: string, listKey?: string): string;
|
|
|
46
56
|
* than no attribute: the reader announces nothing and the field still claims to
|
|
47
57
|
* have an active option.
|
|
48
58
|
*/
|
|
49
|
-
export declare function comboboxAria({ baseId, listKey, count, highlight }: ComboboxInput): ComboboxAria;
|
|
59
|
+
export declare function comboboxAria({ baseId, listKey, count, highlight, open }: ComboboxInput): ComboboxAria;
|
|
50
60
|
//# sourceMappingURL=combobox.d.ts.map
|
package/dist/combobox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../src/combobox.ts"],"names":[],"mappings":"AAsBA,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf;;;+DAG2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../src/combobox.ts"],"names":[],"mappings":"AAsBA,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf;;;+DAG2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAAC;CACrD;AAED;mFACmF;AACnF,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3F;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,aAAa,GAAG,YAAY,CAmBrG"}
|
package/dist/combobox.js
CHANGED
|
@@ -36,14 +36,14 @@ export function listId(baseId, listKey) {
|
|
|
36
36
|
* than no attribute: the reader announces nothing and the field still claims to
|
|
37
37
|
* have an active option.
|
|
38
38
|
*/
|
|
39
|
-
export function comboboxAria({ baseId, listKey, count, highlight }) {
|
|
39
|
+
export function comboboxAria({ baseId, listKey, count, highlight, open }) {
|
|
40
40
|
const list = listId(baseId, listKey);
|
|
41
|
-
const
|
|
42
|
-
const active =
|
|
41
|
+
const expanded = (open ?? true) && count > 0;
|
|
42
|
+
const active = expanded && highlight >= 0 && highlight < count;
|
|
43
43
|
return {
|
|
44
44
|
inputProps: {
|
|
45
45
|
role: 'combobox',
|
|
46
|
-
'aria-expanded':
|
|
46
|
+
'aria-expanded': expanded,
|
|
47
47
|
'aria-controls': list,
|
|
48
48
|
'aria-autocomplete': 'list',
|
|
49
49
|
'aria-activedescendant': active ? optionId(baseId, listKey, highlight) : undefined,
|
package/dist/combobox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.js","sourceRoot":"","sources":["../src/combobox.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,0BAA0B;AAC1B,EAAE;AACF,gFAAgF;AAChF,wEAAwE;AACxE,uBAAuB;AACvB,EAAE;AACF,8EAA8E;AAC9E,mEAAmE;AACnE,6EAA6E;AAC7E,oBAAoB;AACpB,mCAAmC;AACnC,6EAA6E;AAC7E,aAAa;AACb,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;
|
|
1
|
+
{"version":3,"file":"combobox.js","sourceRoot":"","sources":["../src/combobox.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,0BAA0B;AAC1B,EAAE;AACF,gFAAgF;AAChF,wEAAwE;AACxE,uBAAuB;AACvB,EAAE;AACF,8EAA8E;AAC9E,mEAAmE;AACnE,6EAA6E;AAC7E,oBAAoB;AACpB,mCAAmC;AACnC,6EAA6E;AAC7E,aAAa;AACb,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAoD7E;mFACmF;AACnF,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,OAA2B,EAAE,KAAa;IACjF,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,OAAgB;IACrD,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAiB;IACrF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,QAAQ,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC;IAC/D,OAAO;QACL,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,eAAe,EAAE,QAAQ;YACzB,eAAe,EAAE,IAAI;YACrB,mBAAmB,EAAE,MAAM;YAC3B,uBAAuB,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;SACnF;QACD,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE;QACxC,WAAW,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC;YAC/B,EAAE,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;YACpC,IAAI,EAAE,QAAQ;YACd,eAAe,EAAE,KAAK,KAAK,SAAS;SACrC,CAAC;KACH,CAAC;AACJ,CAAC"}
|
package/dist/feed.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export declare const escXml: (s: string) => string;
|
|
2
|
+
/**
|
|
3
|
+
* `content:encoded` carries raw HTML, so it travels inside CDATA. A literal
|
|
4
|
+
* `]]>` in the body would close the section early and corrupt every item after
|
|
5
|
+
* it — not just the one that contained it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const cdata: (html: string) => string;
|
|
8
|
+
/**
|
|
9
|
+
* Aggregators hard-truncate a description around 150 characters. Trimming on a
|
|
10
|
+
* word boundary first means the cut lands between words rather than inside one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function clampWords(s: string, max?: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Relative hrefs and srcs are meaningless once an item is syndicated, so every
|
|
15
|
+
* internal link is absolutised on the way out. Protocol-relative and anchor-only
|
|
16
|
+
* targets are left alone.
|
|
17
|
+
*/
|
|
18
|
+
export declare function absolutise(html: string, baseUrl: string): string;
|
|
19
|
+
export interface FeedItem {
|
|
20
|
+
title: string;
|
|
21
|
+
url: string;
|
|
22
|
+
description: string;
|
|
23
|
+
date: Date;
|
|
24
|
+
/** Becomes an `<enclosure>`. */
|
|
25
|
+
image?: string;
|
|
26
|
+
/** Becomes `content:encoded`. Full-text RSS is what lets a feed be mirrored. */
|
|
27
|
+
html?: string;
|
|
28
|
+
categories?: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare function renderItem(item: FeedItem): string;
|
|
31
|
+
export interface FeedChannel {
|
|
32
|
+
title: string;
|
|
33
|
+
link: string;
|
|
34
|
+
description: string;
|
|
35
|
+
/** The feed's own URL, for `atom:link rel="self"`. */
|
|
36
|
+
self: string;
|
|
37
|
+
language?: string;
|
|
38
|
+
/** Channel-level licence, so the grant travels with the feed. */
|
|
39
|
+
copyright?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `lastBuildDate` comes from the newest item, not from the clock.
|
|
43
|
+
*
|
|
44
|
+
* A feed whose build date moves on every request tells every poller it changed
|
|
45
|
+
* when it did not, which is exactly the recrawl the conditional-GET helpers
|
|
46
|
+
* exist to prevent. An empty feed has no build date rather than a fictional one.
|
|
47
|
+
*/
|
|
48
|
+
export declare function renderFeed(channel: FeedChannel, items: readonly FeedItem[]): string;
|
|
49
|
+
export declare const FEED_HEADERS: Record<string, string>;
|
|
50
|
+
//# sourceMappingURL=feed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,MAAM,GAAI,GAAG,MAAM,KAAG,MAAyD,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,KAAG,MAAyD,CAAC;AAE/F;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAM,GAAG,MAAM,CAKvD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAajD;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAoBnF;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG/C,CAAC"}
|
package/dist/feed.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// feed.ts — an RSS 2.0 channel, assembled.
|
|
2
|
+
//
|
|
3
|
+
// Three repos, four feeds, and the same 47 of 64 significant lines in each —
|
|
4
|
+
// including, verbatim in two of them, the four-line comment explaining why the
|
|
5
|
+
// apostrophe uses a numeric reference rather than `'`. That comment
|
|
6
|
+
// travelling by copy-paste is what made this worth lifting.
|
|
7
|
+
//
|
|
8
|
+
// The union, because each copy had something the others lacked: one had
|
|
9
|
+
// `content:encoded`, `<enclosure>`, `<category>` and a word-boundary clamp; two
|
|
10
|
+
// had a `lastBuildDate` derived from the newest item, where the third stamped
|
|
11
|
+
// `new Date()` on every request — a validator that changes when nothing has,
|
|
12
|
+
// which is the same waste the ETag helpers exist to avoid.
|
|
13
|
+
//
|
|
14
|
+
// What stays with the caller is the channel's identity and the block walk that
|
|
15
|
+
// turns a page into HTML. Every project owns its own type set.
|
|
16
|
+
// Numeric reference for the apostrophe: `'` is an XML entity that older
|
|
17
|
+
// readers parsing the feed as HTML do not carry in their entity table.
|
|
18
|
+
const XML_ESCAPES = {
|
|
19
|
+
'&': '&',
|
|
20
|
+
'<': '<',
|
|
21
|
+
'>': '>',
|
|
22
|
+
'"': '"',
|
|
23
|
+
"'": ''',
|
|
24
|
+
};
|
|
25
|
+
export const escXml = (s) => s.replace(/[&<>"']/g, c => XML_ESCAPES[c] ?? c);
|
|
26
|
+
/**
|
|
27
|
+
* `content:encoded` carries raw HTML, so it travels inside CDATA. A literal
|
|
28
|
+
* `]]>` in the body would close the section early and corrupt every item after
|
|
29
|
+
* it — not just the one that contained it.
|
|
30
|
+
*/
|
|
31
|
+
export const cdata = (html) => `<![CDATA[${html.replace(/]]>/g, ']]>')}]]>`;
|
|
32
|
+
/**
|
|
33
|
+
* Aggregators hard-truncate a description around 150 characters. Trimming on a
|
|
34
|
+
* word boundary first means the cut lands between words rather than inside one.
|
|
35
|
+
*/
|
|
36
|
+
export function clampWords(s, max = 150) {
|
|
37
|
+
if (s.length <= max)
|
|
38
|
+
return s;
|
|
39
|
+
const cut = s.slice(0, max);
|
|
40
|
+
const lastSpace = cut.lastIndexOf(' ');
|
|
41
|
+
return (lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[.,;:–-]$/, '');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Relative hrefs and srcs are meaningless once an item is syndicated, so every
|
|
45
|
+
* internal link is absolutised on the way out. Protocol-relative and anchor-only
|
|
46
|
+
* targets are left alone.
|
|
47
|
+
*/
|
|
48
|
+
export function absolutise(html, baseUrl) {
|
|
49
|
+
return html.replace(/\s(href|src)="\/(?!\/)([^"]*)"/gi, (_m, attr, path) => ` ${attr}="${baseUrl}/${path}"`);
|
|
50
|
+
}
|
|
51
|
+
export function renderItem(item) {
|
|
52
|
+
return [
|
|
53
|
+
' <item>',
|
|
54
|
+
` <title>${escXml(item.title)}</title>`,
|
|
55
|
+
` <link>${escXml(item.url)}</link>`,
|
|
56
|
+
` <guid isPermaLink="true">${escXml(item.url)}</guid>`,
|
|
57
|
+
` <description>${escXml(item.description)}</description>`,
|
|
58
|
+
...(item.categories ?? []).map(c => ` <category>${escXml(c)}</category>`),
|
|
59
|
+
` <pubDate>${item.date.toUTCString()}</pubDate>`,
|
|
60
|
+
...(item.image ? [` <enclosure url="${escXml(item.image)}" type="image/png" />`] : []),
|
|
61
|
+
...(item.html ? [` <content:encoded>${cdata(item.html)}</content:encoded>`] : []),
|
|
62
|
+
' </item>',
|
|
63
|
+
].join('\n');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `lastBuildDate` comes from the newest item, not from the clock.
|
|
67
|
+
*
|
|
68
|
+
* A feed whose build date moves on every request tells every poller it changed
|
|
69
|
+
* when it did not, which is exactly the recrawl the conditional-GET helpers
|
|
70
|
+
* exist to prevent. An empty feed has no build date rather than a fictional one.
|
|
71
|
+
*/
|
|
72
|
+
export function renderFeed(channel, items) {
|
|
73
|
+
const newest = items.reduce((max, item) => (!max || item.date > max ? item.date : max), null);
|
|
74
|
+
return [
|
|
75
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
76
|
+
'<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">',
|
|
77
|
+
' <channel>',
|
|
78
|
+
` <title>${escXml(channel.title)}</title>`,
|
|
79
|
+
` <link>${escXml(channel.link)}</link>`,
|
|
80
|
+
` <description>${escXml(channel.description)}</description>`,
|
|
81
|
+
` <language>${escXml(channel.language ?? 'en')}</language>`,
|
|
82
|
+
...(channel.copyright ? [` <copyright>${escXml(channel.copyright)}</copyright>`] : []),
|
|
83
|
+
` <atom:link href="${escXml(channel.self)}" rel="self" type="application/rss+xml" />`,
|
|
84
|
+
...(newest ? [` <lastBuildDate>${newest.toUTCString()}</lastBuildDate>`] : []),
|
|
85
|
+
...items.map(renderItem),
|
|
86
|
+
' </channel>',
|
|
87
|
+
'</rss>',
|
|
88
|
+
].join('\n');
|
|
89
|
+
}
|
|
90
|
+
export const FEED_HEADERS = {
|
|
91
|
+
'Content-Type': 'application/rss+xml; charset=utf-8',
|
|
92
|
+
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=feed.js.map
|
package/dist/feed.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,4 +15,7 @@ export * from './maps.js';
|
|
|
15
15
|
export * from './freshness.js';
|
|
16
16
|
export * from './combobox.js';
|
|
17
17
|
export * from './crawlers.js';
|
|
18
|
+
export * from './revisions.js';
|
|
19
|
+
export * from './feed.js';
|
|
20
|
+
export * from './license.js';
|
|
18
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,4 +20,7 @@ export * from './maps.js';
|
|
|
20
20
|
export * from './freshness.js';
|
|
21
21
|
export * from './combobox.js';
|
|
22
22
|
export * from './crawlers.js';
|
|
23
|
+
export * from './revisions.js';
|
|
24
|
+
export * from './feed.js';
|
|
25
|
+
export * from './license.js';
|
|
23
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,mBAAmB;AAEnB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,mBAAmB;AAEnB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface License {
|
|
2
|
+
/** SPDX identifier, e.g. `CC-BY-4.0`. */
|
|
3
|
+
spdx: string;
|
|
4
|
+
/** Human name, e.g. `Creative Commons Attribution 4.0 International`. */
|
|
5
|
+
name: string;
|
|
6
|
+
url: string;
|
|
7
|
+
/** The credit line a dataset should carry. */
|
|
8
|
+
attribution: string;
|
|
9
|
+
}
|
|
10
|
+
/** The grant every one of these wikis makes, parameterised by who is making it. */
|
|
11
|
+
export declare function ccBy40(opts: {
|
|
12
|
+
siteName: string;
|
|
13
|
+
siteUrl: string;
|
|
14
|
+
}): License;
|
|
15
|
+
export interface LicenseBlockOptions {
|
|
16
|
+
license: License;
|
|
17
|
+
/**
|
|
18
|
+
* What the grant covers, as a sentence fragment completing "… is licensed
|
|
19
|
+
* under". Defaults to naming the whole site, which is the rarer case: every
|
|
20
|
+
* consumer of this so far grants over some of what it serves and not all.
|
|
21
|
+
*/
|
|
22
|
+
scope?: string;
|
|
23
|
+
/** Sentences appended after the identifiers — carve-outs, caveats, terms. */
|
|
24
|
+
excludes?: readonly string[];
|
|
25
|
+
/** `Licence` where the site's prose says so. Defaults to `License`. */
|
|
26
|
+
heading?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The block, as lines, ready to join into any text export.
|
|
30
|
+
*
|
|
31
|
+
* Returned as an array rather than a string because every caller splices it
|
|
32
|
+
* into a document it is already building line by line, and a caller that wants
|
|
33
|
+
* the string can join it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function licenseLines({ license, scope, excludes, heading, }: LicenseBlockOptions): string[];
|
|
36
|
+
export declare function licenseBlock(opts: LicenseBlockOptions): string;
|
|
37
|
+
/** The one-line form, for a frontmatter field or a feed's `<copyright>`. */
|
|
38
|
+
export declare function licenseNote(license: License): string;
|
|
39
|
+
//# sourceMappingURL=license.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAO3E;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,KAAsB,EACtB,QAAa,EACb,OAAiC,GAClC,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAchC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAE9D;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEpD"}
|
package/dist/license.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// license.ts — the licence declaration every agent surface has to carry.
|
|
2
|
+
//
|
|
3
|
+
// S10 requires a licence on every export — llms.txt, the agent card, the
|
|
4
|
+
// OpenAPI info block, the JSON-LD, the feed's `<copyright>` — and each repo
|
|
5
|
+
// satisfied that requirement by writing the same block again. The shape was
|
|
6
|
+
// identical in all three, and the sentence beginning "You may ingest, embed,
|
|
7
|
+
// and redistribute" was verbatim in all three.
|
|
8
|
+
//
|
|
9
|
+
// What is genuinely per-project is the scope: which half of a site the grant
|
|
10
|
+
// covers, and what it deliberately excludes. That is the `scope` and `excludes`
|
|
11
|
+
// below, and it is the only part a consumer should be writing by hand.
|
|
12
|
+
/** The grant every one of these wikis makes, parameterised by who is making it. */
|
|
13
|
+
export function ccBy40(opts) {
|
|
14
|
+
return {
|
|
15
|
+
spdx: 'CC-BY-4.0',
|
|
16
|
+
name: 'Creative Commons Attribution 4.0 International',
|
|
17
|
+
url: 'https://creativecommons.org/licenses/by/4.0/',
|
|
18
|
+
attribution: `Source: ${opts.siteName} (${opts.siteUrl}), CC BY 4.0`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The block, as lines, ready to join into any text export.
|
|
23
|
+
*
|
|
24
|
+
* Returned as an array rather than a string because every caller splices it
|
|
25
|
+
* into a document it is already building line by line, and a caller that wants
|
|
26
|
+
* the string can join it.
|
|
27
|
+
*/
|
|
28
|
+
export function licenseLines({ license, scope = 'This content', excludes = [], heading = 'License & Attribution', }) {
|
|
29
|
+
return [
|
|
30
|
+
`## ${heading}`,
|
|
31
|
+
'',
|
|
32
|
+
`${scope} is licensed under the ${license.name} (${license.spdx}): ${license.url}`,
|
|
33
|
+
'',
|
|
34
|
+
'You may ingest, embed, and redistribute this content in RAG systems, fine-tuning',
|
|
35
|
+
'datasets, or other derivative works, including commercially. Attribution at the',
|
|
36
|
+
'dataset or system level is sufficient.',
|
|
37
|
+
'',
|
|
38
|
+
`- Recommended attribution: "${license.attribution}"`,
|
|
39
|
+
`- SPDX identifier: ${license.spdx}`,
|
|
40
|
+
...(excludes.length ? ['', ...excludes] : []),
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
export function licenseBlock(opts) {
|
|
44
|
+
return licenseLines(opts).join('\n');
|
|
45
|
+
}
|
|
46
|
+
/** The one-line form, for a frontmatter field or a feed's `<copyright>`. */
|
|
47
|
+
export function licenseNote(license) {
|
|
48
|
+
return `${license.name} (${license.spdx}): ${license.url}`;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=license.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,+CAA+C;AAC/C,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,uEAAuE;AAYvE,mFAAmF;AACnF,MAAM,UAAU,MAAM,CAAC,IAA2C;IAChE,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,gDAAgD;QACtD,GAAG,EAAE,8CAA8C;QACnD,WAAW,EAAE,WAAW,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,cAAc;KACrE,CAAC;AACJ,CAAC;AAgBD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,OAAO,EACP,KAAK,GAAG,cAAc,EACtB,QAAQ,GAAG,EAAE,EACb,OAAO,GAAG,uBAAuB,GACb;IACpB,OAAO;QACL,MAAM,OAAO,EAAE;QACf,EAAE;QACF,GAAG,KAAK,0BAA0B,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE;QAClF,EAAE;QACF,kFAAkF;QAClF,iFAAiF;QACjF,wCAAwC;QACxC,EAAE;QACF,+BAA+B,OAAO,CAAC,WAAW,GAAG;QACrD,sBAAsB,OAAO,CAAC,IAAI,EAAE;QACpC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC;AAC7D,CAAC"}
|