Files
source-presences/README.md
T
2026-04-25 23:58:58 +03:00

109 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Source Presences
Public registry of Source Presence extensions, served from
[`gits.hibna.com.tr/hibna/source-presences`](https://gits.hibna.com.tr/hibna/source-presences).
The Source Presence browser extension reads:
- `index.json` — list of presences and their current versions.
- `presences/<id>/metadata.json` — presence manifest.
- `presences/<id>/dist/presence.js` — built CJS module (produced by `npm run build`).
- `presences/<id>/<icon>` — optional 128×128 PNG.
Both `index.json` and each presence's `dist/presence.js` are committed by the
Gitea Actions workflow at [`.gitea/workflows/build.yml`](.gitea/workflows/build.yml)
on every push to `main`.
## Add a new presence
```bash
mkdir -p presences/<id>/src
cat > presences/<id>/metadata.json <<'JSON'
{
"id": "<id>",
"name": "<Display Name>",
"description": "<short description>",
"version": "1.0.0",
"author": "<your name>",
"match": ["https://example.com/*"],
"tickInterval": 1000,
"sdkVersion": "^0.1.0"
}
JSON
```
Write your TypeScript entry at `presences/<id>/src/presence.ts`:
```ts
import { ActivityType, definePresence } from "@source/presence-sdk";
export default definePresence({
match: ["https://example.com/*"],
tick(ctx) {
ctx.setActivity({
type: ActivityType.WATCHING,
name: "Example",
details: document.title,
});
},
});
```
Push to `main`. Gitea Actions builds the presence, regenerates `index.json`,
and commits the artifacts back. The extension picks up the new version on its
next 6-hour refresh, or immediately when users hit "Refresh" / "Update all".
## Local build
```bash
npm install
npm run build # builds every presence under presences/*
npm run index # regenerates index.json
npm run release # both
```
## Presence API
`PresenceDefinition` shape (also defined in [`types/presence-sdk.d.ts`](types/presence-sdk.d.ts)):
| Field | Required | Description |
|----------------|----------|--------------------------------------------------------------------|
| `match` | yes | Array of [match patterns](https://developer.chrome.com/docs/extensions/reference/match_patterns). |
| `tickInterval` | no | Override default 1000ms tick. |
| `onLoad(ctx)` | no | Runs once when a matching tab loads the presence. |
| `tick(ctx)` | no | Runs every `tickInterval`; call `ctx.setActivity(...)` to publish. |
| `onUnload(ctx)`| no | Runs when the presence is torn down (tab nav / disable). |
`PresenceContext`:
- `ctx.url` / `ctx.tabActive` — read-only state.
- `ctx.setActivity(activity)` / `ctx.clear()` — publish or clear.
- `ctx.storage` — namespaced async storage (`get` / `set` / `delete` / `clear`).
- `ctx.log` / `warn` / `error` — surfaced in the extension's background console.
## Activity payload
```ts
{
type: ActivityType.PLAYING | LISTENING | WATCHING,
name: string,
details?: string,
state?: string,
url?: string,
largeImage?: string,
largeText?: string,
smallImage?: string,
smallText?: string,
startedAt?: number, // unix ms — Source renders an elapsed timer
endsAt?: number, // unix ms — Source renders a remaining timer
}
```
## Notes
- Presences run in the **content script's isolated world** with full DOM read
access. They cannot access page JS globals.
- The extension debounces identical payloads; calling `setActivity` with the
same data on every tick is fine.
- Keep presence builds small (< 100 KB). They're shipped with every install.