@atmo-dev/kit 0.5.0 → 0.6.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 +84 -0
- package/dist/at-tags.d.ts +18 -0
- package/dist/at-tags.js +18 -0
- package/dist/components/AtTags.svelte +17 -0
- package/dist/components/AtTags.svelte.d.ts +7 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -9,6 +9,90 @@ Svelte 5 and Tailwind CSS 4 components for Atmo apps.
|
|
|
9
9
|
- Releases: `pnpm changeset`, then merge the generated release PR. [Details](.changeset/README.md).
|
|
10
10
|
- License: [MIT](LICENSE).
|
|
11
11
|
|
|
12
|
+
## AT record metadata (AT Tags)
|
|
13
|
+
|
|
14
|
+
Use `AtTags` to let other clients discover which AT Protocol records and identities
|
|
15
|
+
an HTML page represents. It renders server-side `<meta name="at:…" content="at://…">`
|
|
16
|
+
tags in the document head and updates/removes them when its props change. It needs
|
|
17
|
+
no theme, styles, network requests, or app state.
|
|
18
|
+
|
|
19
|
+
The [AT Tags proposal](https://tangled.org/chrisshank.com/at-tags) is a draft. Its four
|
|
20
|
+
standard relationships are:
|
|
21
|
+
|
|
22
|
+
| Property | Meaning | Content |
|
|
23
|
+
| ----------- | ------------------------------------------------------------------------ | --------------- |
|
|
24
|
+
| `canonical` | The record this page represents; deleting it would remove the page. | A record AT URI |
|
|
25
|
+
| `alternate` | Auxiliary records shown or referenced; the page survives their deletion. | A record AT URI |
|
|
26
|
+
| `author` | Account(s) who authored the page's content. | `at://<DID>` |
|
|
27
|
+
| `me` | Account(s) this site or section belongs to. | `at://<DID>` |
|
|
28
|
+
|
|
29
|
+
Each property accepts an array; multiple values produce separate tags, with exact
|
|
30
|
+
duplicates removed within each property. Use meta **names**, not Open Graph
|
|
31
|
+
`property` attributes or `<link href="at://…">`. These tags supplement—not
|
|
32
|
+
replace—your title, description, HTTPS canonical URL and Open Graph metadata.
|
|
33
|
+
|
|
34
|
+
For a page backed by one record authored by its repository owner, use the
|
|
35
|
+
framework-free `recordAtTags` helper in your server loader:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { recordAtTags } from '@atmo-dev/kit/at-tags';
|
|
39
|
+
|
|
40
|
+
// After app-owned loading, visibility/moderation checks and handle resolution:
|
|
41
|
+
return {
|
|
42
|
+
atTags: recordAtTags(record, relatedRecords)
|
|
43
|
+
};
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`record` and each optional `relatedRecords` entry only need `{ uri: string }`.
|
|
47
|
+
The helper sets `canonical`, derives `author` from the record's repository DID,
|
|
48
|
+
and lists related records as `alternate`, excluding the canonical URI. It throws
|
|
49
|
+
`SyntaxError` for non-record or handle-based URIs: pass resolved DID-based record
|
|
50
|
+
URIs, not a URL path or viewer parameter. It does not resolve or fetch anything.
|
|
51
|
+
|
|
52
|
+
Render the metadata once in a SvelteKit root layout (covering embeds too):
|
|
53
|
+
|
|
54
|
+
```svelte
|
|
55
|
+
<script lang="ts">
|
|
56
|
+
import { page } from '$app/state';
|
|
57
|
+
import { AtTags } from '@atmo-dev/kit';
|
|
58
|
+
|
|
59
|
+
let { children } = $props();
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<AtTags tags={page.error ? undefined : page.data.atTags} />
|
|
63
|
+
{@render children()}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Add `atTags?: import('@atmo-dev/kit/at-tags').AtTagMetadata` to `App.PageData`.
|
|
67
|
+
In other Svelte apps, pass the current page's metadata directly; set `tags` to
|
|
68
|
+
`undefined` on pages with no relationships. Do not mount competing tag owners.
|
|
69
|
+
|
|
70
|
+
You can supply `AtTagMetadata` directly for multiple canonical records, different
|
|
71
|
+
or additional authors, or an account section:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import type { AtTagMetadata } from '@atmo-dev/kit/at-tags';
|
|
75
|
+
|
|
76
|
+
const atTags: AtTagMetadata = {
|
|
77
|
+
me: [`at://${profile.did}`],
|
|
78
|
+
alternate: profile.uri ? [profile.uri] : []
|
|
79
|
+
};
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
An account's events page might survive deletion of its optional Bluesky profile,
|
|
83
|
+
so that profile record is an alternate, not necessarily canonical. Likewise,
|
|
84
|
+
embedded comments are alternate records, not the page's authors. `me` is not the
|
|
85
|
+
signed-in viewer or every record author; do not assign it site-wide unless the
|
|
86
|
+
site actually belongs to that account. Ordinary discovery and creation pages
|
|
87
|
+
usually have no canonical record.
|
|
88
|
+
|
|
89
|
+
Apps own these semantic choices, record loading, identity resolution, visibility,
|
|
90
|
+
and error-page suppression. The component escapes attributes but does not validate
|
|
91
|
+
raw metadata or verify record existence. Use record URIs with collection and rkey,
|
|
92
|
+
and bare `at://<DID>` identity URIs without a trailing slash. Only the four standard
|
|
93
|
+
properties are supported; parsing/scraping pages and draft custom namespaces are
|
|
94
|
+
outside this API.
|
|
95
|
+
|
|
12
96
|
## Events
|
|
13
97
|
|
|
14
98
|
The event UI formerly in `@atmo-dev/events-ui` lives in this package:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Standard AT Tags draft properties. Identity values are `at://<DID>` URIs. */
|
|
2
|
+
export interface AtTagMetadata {
|
|
3
|
+
canonical?: readonly string[];
|
|
4
|
+
alternate?: readonly string[];
|
|
5
|
+
author?: readonly string[];
|
|
6
|
+
me?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
/** A resolved record reference; no lexicon-specific fields are needed. */
|
|
9
|
+
export interface AtTagRecordRef {
|
|
10
|
+
uri: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Metadata for a page backed by one record, authored by its repository owner.
|
|
14
|
+
* Supply only auxiliary records represented on the page. Throws SyntaxError for
|
|
15
|
+
* non-record or non-DID-based URIs; resolve handles before calling this helper.
|
|
16
|
+
* For multiple canonical records or different authors, supply metadata directly.
|
|
17
|
+
*/
|
|
18
|
+
export declare function recordAtTags(record: AtTagRecordRef, alternates?: readonly AtTagRecordRef[]): AtTagMetadata;
|
package/dist/at-tags.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { parseCanonicalResourceUri } from '@atcute/lexicons/syntax';
|
|
2
|
+
/**
|
|
3
|
+
* Metadata for a page backed by one record, authored by its repository owner.
|
|
4
|
+
* Supply only auxiliary records represented on the page. Throws SyntaxError for
|
|
5
|
+
* non-record or non-DID-based URIs; resolve handles before calling this helper.
|
|
6
|
+
* For multiple canonical records or different authors, supply metadata directly.
|
|
7
|
+
*/
|
|
8
|
+
export function recordAtTags(record, alternates = []) {
|
|
9
|
+
const { repo } = parseCanonicalResourceUri(record.uri);
|
|
10
|
+
const alternate = [...new Set(alternates.map(({ uri }) => uri))].filter((uri) => uri !== record.uri);
|
|
11
|
+
for (const uri of alternate)
|
|
12
|
+
parseCanonicalResourceUri(uri);
|
|
13
|
+
return {
|
|
14
|
+
canonical: [record.uri],
|
|
15
|
+
author: [`at://${repo}`],
|
|
16
|
+
alternate
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AtTagMetadata } from '../at-tags.js';
|
|
3
|
+
|
|
4
|
+
export interface AtTagsProps {
|
|
5
|
+
tags?: AtTagMetadata;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let { tags }: AtTagsProps = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<svelte:head>
|
|
12
|
+
{#each ['canonical', 'alternate', 'author', 'me'] as property (property)}
|
|
13
|
+
{#each [...new Set(tags?.[property as keyof AtTagMetadata] ?? [])] as uri (uri)}
|
|
14
|
+
<meta name={`at:${property}`} content={uri} />
|
|
15
|
+
{/each}
|
|
16
|
+
{/each}
|
|
17
|
+
</svelte:head>
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ export * from './social.js';
|
|
|
11
11
|
export { default as Checkbox } from './components/Checkbox.svelte';
|
|
12
12
|
export { default as Label } from './components/Label.svelte';
|
|
13
13
|
export { default as PageTitle } from './components/PageTitle.svelte';
|
|
14
|
+
export { default as AtTags } from './components/AtTags.svelte';
|
|
15
|
+
export type { AtTagsProps } from './components/AtTags.svelte';
|
|
16
|
+
export * from './at-tags.js';
|
|
14
17
|
export { default as Heading } from './components/Heading.svelte';
|
|
15
18
|
export { default as Subheading } from './components/Subheading.svelte';
|
|
16
19
|
export { default as Surface } from './components/Surface.svelte';
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ export * from './social.js';
|
|
|
8
8
|
export { default as Checkbox } from './components/Checkbox.svelte';
|
|
9
9
|
export { default as Label } from './components/Label.svelte';
|
|
10
10
|
export { default as PageTitle } from './components/PageTitle.svelte';
|
|
11
|
+
export { default as AtTags } from './components/AtTags.svelte';
|
|
12
|
+
export * from './at-tags.js';
|
|
11
13
|
export { default as Heading } from './components/Heading.svelte';
|
|
12
14
|
export { default as Subheading } from './components/Subheading.svelte';
|
|
13
15
|
export { default as Surface } from './components/Surface.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atmo-dev/kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "The shared UI foundation for Atmo apps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"svelte": "./dist/index.js",
|
|
28
28
|
"default": "./dist/index.js"
|
|
29
29
|
},
|
|
30
|
+
"./at-tags": {
|
|
31
|
+
"types": "./dist/at-tags.d.ts",
|
|
32
|
+
"default": "./dist/at-tags.js"
|
|
33
|
+
},
|
|
30
34
|
"./events": {
|
|
31
35
|
"types": "./dist/events.d.ts",
|
|
32
36
|
"svelte": "./dist/events.js",
|
|
@@ -166,7 +170,7 @@
|
|
|
166
170
|
"test": "pnpm test:unit --run && pnpm test:e2e && pnpm test:package",
|
|
167
171
|
"test:ci": "pnpm test:unit --run --no-file-parallelism && pnpm test:e2e && pnpm test:package",
|
|
168
172
|
"test:e2e": "playwright test",
|
|
169
|
-
"test:package": "pnpm prepack && node --test scripts/test
|
|
173
|
+
"test:package": "pnpm prepack && node --test scripts/test-*-package.mjs",
|
|
170
174
|
"changeset": "changeset",
|
|
171
175
|
"version-packages": "changeset version && pnpm install --lockfile-only --no-frozen-lockfile --ignore-scripts",
|
|
172
176
|
"release": "pnpm prepack && changeset publish"
|