@singi-labs/sifa-sdk 0.19.74 → 0.19.76
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/dist/format/index.js +2 -0
- package/dist/format/index.js.map +1 -1
- package/dist/format/openalex.js +10 -0
- package/dist/format/openalex.js.map +1 -0
- package/dist/{index-BFdNI6jA.d.ts → index-DAiJZvPg.d.ts} +8 -0
- package/dist/{index-BzkaABDb.d.cts → index-k6tBrbEU.d.cts} +8 -0
- package/dist/index.cjs +71 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -6
- package/dist/index.d.ts +14 -6
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/dist/jsonld/index.d.cts +1 -1
- package/dist/jsonld/index.d.ts +1 -1
- package/dist/logic/index.js +26 -0
- package/dist/logic/index.js.map +1 -1
- package/dist/logic/site-activity-preset.js +68 -0
- package/dist/logic/site-activity-preset.js.map +1 -0
- package/dist/{network-map-BRBzAHrT.d.cts → network-map-DInAc_DB.d.cts} +3 -3
- package/dist/{network-map-DIUQSB0r.d.ts → network-map-DvALufF9.d.ts} +3 -3
- package/dist/{profile-summary-X4MGExfS.d.cts → profile-summary-BcbJrph1.d.cts} +1 -1
- package/dist/{profile-summary-6GySSJvO.d.ts → profile-summary-PRDqxAQT.d.ts} +1 -1
- package/dist/query/fetchers/activity-preferences.js +43 -0
- package/dist/query/fetchers/activity-preferences.js.map +1 -0
- package/dist/query/fetchers/activity.js +3 -0
- package/dist/query/fetchers/activity.js.map +1 -1
- package/dist/query/fetchers/index.cjs +88 -1
- package/dist/query/fetchers/index.cjs.map +1 -1
- package/dist/query/fetchers/index.d.cts +6 -6
- package/dist/query/fetchers/index.d.ts +6 -6
- package/dist/query/fetchers/index.js +16 -0
- package/dist/query/fetchers/index.js.map +1 -1
- package/dist/query/fetchers/user-settings.js +48 -0
- package/dist/query/fetchers/user-settings.js.map +1 -0
- package/dist/query/hooks/index.cjs +141 -1
- package/dist/query/hooks/index.cjs.map +1 -1
- package/dist/query/hooks/index.d.cts +4 -4
- package/dist/query/hooks/index.d.ts +4 -4
- package/dist/query/hooks/index.js +11 -0
- package/dist/query/hooks/index.js.map +1 -1
- package/dist/query/hooks/use-activity-preferences.js +53 -0
- package/dist/query/hooks/use-activity-preferences.js.map +1 -0
- package/dist/query/hooks/use-activity.js.map +1 -1
- package/dist/query/hooks/use-user-settings.js +34 -0
- package/dist/query/hooks/use-user-settings.js.map +1 -0
- package/dist/query/index.cjs +143 -1
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +9 -9
- package/dist/query/index.d.ts +9 -9
- package/dist/query/index.js +27 -0
- package/dist/query/index.js.map +1 -1
- package/dist/query/keys.js +7 -1
- package/dist/query/keys.js.map +1 -1
- package/dist/resume/index.d.cts +1 -1
- package/dist/resume/index.d.ts +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/{types-DxMMqOJo.d.ts → types-CI24asgo.d.ts} +72 -2
- package/dist/{types-DXep6553.d.cts → types-qw55KvoV.d.cts} +72 -2
- package/dist/{use-org-notification-emails-CfDfHwBl.d.ts → use-user-settings-B1rJmjQR.d.ts} +32 -5
- package/dist/{use-org-notification-emails-5V3ZAlRd.d.cts → use-user-settings-CYDXJNmI.d.cts} +32 -5
- package/dist/{org-Spq8yU-B.d.ts → user-settings-Qwi6wSnK.d.ts} +89 -4
- package/dist/{org-A9Tz-Uv9.d.cts → user-settings-lenJHz19.d.cts} +89 -4
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/query/fetchers/activity-preferences.ts
|
|
2
|
+
import {
|
|
3
|
+
apiFetch,
|
|
4
|
+
apiWrite,
|
|
5
|
+
encodeIdentifier
|
|
6
|
+
} from "../client.js";
|
|
7
|
+
async function fetchActivityPreferences(config, options = {}) {
|
|
8
|
+
const headers = { ...options.headers ?? {} };
|
|
9
|
+
if (options.cookieHeader) headers.cookie = options.cookieHeader;
|
|
10
|
+
try {
|
|
11
|
+
return await apiFetch(config, "/api/activity-preferences", {
|
|
12
|
+
credentials: "include",
|
|
13
|
+
cache: "no-store",
|
|
14
|
+
...options,
|
|
15
|
+
headers
|
|
16
|
+
});
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function updateActivityPreferences(config, input, options = {}) {
|
|
22
|
+
return apiWrite(config, "/api/activity-preferences", "PUT", {
|
|
23
|
+
...options,
|
|
24
|
+
body: input
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function fetchSiteActivityPreset(config, handleOrDid, options = {}) {
|
|
28
|
+
try {
|
|
29
|
+
return await apiFetch(
|
|
30
|
+
config,
|
|
31
|
+
`/api/activity-preferences/site-preset/${encodeIdentifier(handleOrDid)}`,
|
|
32
|
+
options
|
|
33
|
+
);
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
fetchActivityPreferences,
|
|
40
|
+
fetchSiteActivityPreset,
|
|
41
|
+
updateActivityPreferences
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=activity-preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/query/fetchers/activity-preferences.ts"],"sourcesContent":["import type { SiteActivityPreset } from '../../logic/site-activity-preset.js';\nimport {\n apiFetch,\n apiWrite,\n encodeIdentifier,\n type ApiFetchOptions,\n type SifaApiConfig,\n type WriteResult,\n} from '../client.js';\n\n/**\n * The authenticated user's activity preferences, resolved to an answer for\n * every known key. `sitePreset` is the personal-site \"show only\" filter; both\n * lists empty means no preset.\n */\nexport interface ActivityPreferences {\n streamCategories: Record<string, boolean>;\n digestItemTypes: Record<string, boolean>;\n sitePreset: SiteActivityPreset;\n}\n\n/**\n * Partial update. Only the keys present change. `sitePreset`, when present,\n * replaces the whole stored preset; send empty lists to clear it.\n */\nexport interface UpdateActivityPreferencesInput {\n streamCategories?: Record<string, boolean>;\n digestItemTypes?: Record<string, boolean>;\n sitePreset?: SiteActivityPreset;\n}\n\n/** A user's personal-site preset as anyone can read it. */\nexport interface SiteActivityPresetResponse extends SiteActivityPreset {\n did: string;\n /** False when both lists are empty, i.e. the site shows all activity. */\n active: boolean;\n}\n\nexport interface FetchActivityPreferencesOptions extends ApiFetchOptions {\n /**\n * Pass the caller's `Cookie` header on Next.js RSC server-side calls.\n * `credentials: 'include'` does NOT propagate browser cookies in RSC.\n */\n cookieHeader?: string;\n}\n\n/** The caller's own preferences. Returns `null` on any error. */\nexport async function fetchActivityPreferences(\n config: SifaApiConfig,\n options: FetchActivityPreferencesOptions = {},\n): Promise<ActivityPreferences | null> {\n const headers: Record<string, string> = { ...(options.headers ?? {}) };\n if (options.cookieHeader) headers.cookie = options.cookieHeader;\n\n try {\n return await apiFetch<ActivityPreferences>(config, '/api/activity-preferences', {\n credentials: 'include',\n cache: 'no-store',\n ...options,\n headers,\n });\n } catch {\n return null;\n }\n}\n\n/** Update the caller's own preferences. */\nexport function updateActivityPreferences(\n config: SifaApiConfig,\n input: UpdateActivityPreferencesInput,\n options: ApiFetchOptions = {},\n): Promise<WriteResult<Partial<ActivityPreferences>>> {\n return apiWrite<Partial<ActivityPreferences>>(config, '/api/activity-preferences', 'PUT', {\n ...options,\n body: input,\n });\n}\n\n/**\n * Public read of a user's personal-site preset, by handle or DID. Site\n * builders use it to show the same activity page.sifa.id shows. Returns\n * `null` on any error.\n */\nexport async function fetchSiteActivityPreset(\n config: SifaApiConfig,\n handleOrDid: string,\n options: ApiFetchOptions = {},\n): Promise<SiteActivityPresetResponse | null> {\n try {\n return await apiFetch<SiteActivityPresetResponse>(\n config,\n `/api/activity-preferences/site-preset/${encodeIdentifier(handleOrDid)}`,\n options,\n );\n } catch {\n return null;\n }\n}\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAuCP,eAAsB,yBACpB,QACA,UAA2C,CAAC,GACP;AACrC,QAAM,UAAkC,EAAE,GAAI,QAAQ,WAAW,CAAC,EAAG;AACrE,MAAI,QAAQ,aAAc,SAAQ,SAAS,QAAQ;AAEnD,MAAI;AACF,WAAO,MAAM,SAA8B,QAAQ,6BAA6B;AAAA,MAC9E,aAAa;AAAA,MACb,OAAO;AAAA,MACP,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,0BACd,QACA,OACA,UAA2B,CAAC,GACwB;AACpD,SAAO,SAAuC,QAAQ,6BAA6B,OAAO;AAAA,IACxF,GAAG;AAAA,IACH,MAAM;AAAA,EACR,CAAC;AACH;AAOA,eAAsB,wBACpB,QACA,aACA,UAA2B,CAAC,GACgB;AAC5C,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA,yCAAyC,iBAAiB,WAAW,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -33,6 +33,9 @@ async function fetchActivityTeaser(config, handleOrDid, options = {}) {
|
|
|
33
33
|
async function fetchActivityFeed(config, handleOrDid, options = {}) {
|
|
34
34
|
const params = new URLSearchParams();
|
|
35
35
|
if (options.category) params.set("category", options.category);
|
|
36
|
+
if (options.categories?.length) params.set("categories", options.categories.join(","));
|
|
37
|
+
if (options.tags?.length) params.set("tags", options.tags.join(","));
|
|
38
|
+
if (options.preset) params.set("preset", options.preset);
|
|
36
39
|
if (options.limit) params.set("limit", String(options.limit));
|
|
37
40
|
if (options.cursor) params.set("cursor", options.cursor);
|
|
38
41
|
const qs = params.toString();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/query/fetchers/activity.ts"],"sourcesContent":["import type { ActivityLabel } from '../../cards/adult-content.js';\nimport { encodeIdentifier, apiFetch, type ApiFetchOptions, type SifaApiConfig } from '../client.js';\nimport type { QuotedPostResult } from './quoted-posts.js';\n\n/**\n * Liveness of an activity card's destination, as reported by sifa-api's\n * `/api/activity` enrichment (see sifa-api `url-health-checker`). How liveness\n * is measured depends on the card's health strategy (see `resolveCardHealth`):\n * first-party permalinks (`record`) are checked by record existence on the PDS;\n * foreign/derived targets (`url`) by HTTP reachability (HEAD, then GET).\n *\n * ok -- record exists, or the URL returned 2xx/3xx\n * broken -- confirmed dead (record deleted, or >=2 consecutive 4xx / >=5 consecutive 5xx)\n * unverifiable -- 403/429, PDS unreachable, or network error; NOT dead\n * unknown -- newly seen, not yet checked\n *\n * Consumers should only suppress UI on `'broken'`. All other values\n * (including missing) mean \"render normally\".\n */\nexport type ActivityItemLinkHealth = 'ok' | 'broken' | 'unverifiable' | 'unknown';\n\nexport interface HeatmapDay {\n date: string;\n total: number;\n apps: { appId: string; count: number }[];\n}\n\nexport interface HeatmapResponse {\n days: HeatmapDay[];\n appTotals: { appId: string; appName: string; total: number }[];\n thresholds: [number, number, number, number];\n}\n\nexport interface ActivityItem {\n uri: string;\n cid: string;\n collection: string;\n rkey: string;\n record: Record<string, unknown>;\n appId: string;\n appName: string;\n category: string;\n indexedAt: string;\n /**\n * The record author's handle / display name / avatar, injected by the server\n * on MULTI-author feeds (the following feed) so a card can show whose activity\n * it is. Unset on the per-author activity feed (all one author). Mirrors the\n * stream `ActivityItem`'s author fields the view-model transform reads.\n */\n authorHandle?: string;\n authorDisplayName?: string;\n authorAvatar?: string;\n /**\n * Set by the server when an `app.bsky.embed.record` quote was already\n * resolved upstream (AppView path). Mutually exclusive with `quotedPostUri`.\n */\n quotedPost?: QuotedPostResult;\n /**\n * Set by the server when an `app.bsky.embed.record` quote needs client-side\n * resolution (PDS path). Pass batches to {@link resolveQuotedPosts}.\n * Mutually exclusive with `quotedPost`.\n */\n quotedPostUri?: string;\n /**\n * Reachability of the card's external destination as last checked by\n * sifa-api. Undefined for legacy responses; treat as 'unknown'.\n * See {@link ActivityItemLinkHealth}.\n */\n linkHealth?: ActivityItemLinkHealth;\n /**\n * Content labels from `app.bsky.feed.defs#postView.labels`. Set by\n * sifa-api for Bluesky posts; undefined for other sources and legacy\n * responses. Pass items to {@link hasAdultContent} to decide whether to\n * gate media. See {@link ActivityLabel}.\n */\n labels?: ActivityLabel[];\n /**\n * The owner has hidden this item from their profile. Only ever set on the\n * owner's own view of their feed -- every other surface omits hidden items\n * rather than flagging them -- so a card can offer an unhide in place.\n */\n hidden?: boolean;\n}\n\nexport interface ActivityTeaserResponse {\n items: ActivityItem[];\n blueskyGated?: boolean;\n backfillPending?: boolean;\n failedApps?: string[];\n}\n\nexport interface ActivityFeedResponse {\n items: ActivityItem[];\n cursor: string | null;\n hasMore: boolean;\n availableCategories?: string[];\n blueskyGated?: boolean;\n failedApps?: string[];\n}\n\n/**\n * Per-day activity counts for a profile across all ATproto apps. Returns\n * `null` on any error so callers can render a graceful empty state.\n */\nexport async function fetchHeatmapData(\n config: SifaApiConfig,\n handleOrDid: string,\n days: number,\n options: ApiFetchOptions = {},\n): Promise<HeatmapResponse | null> {\n const path = `/api/activity/${encodeIdentifier(handleOrDid)}/heatmap?days=${days}`;\n try {\n return await apiFetch<HeatmapResponse>(config, path, {\n next: { revalidate: 900, tags: [`heatmap-${handleOrDid}`] },\n ...options,\n });\n } catch {\n return null;\n }\n}\n\nexport interface FetchActivityTeaserOptions extends ApiFetchOptions {\n /**\n * Pass the caller's `Cookie` header on Next.js RSC server-side calls.\n * Required for authenticated server fetches because `credentials: 'include'`\n * does not propagate browser cookies in RSC.\n */\n cookieHeader?: string;\n}\n\n/**\n * Recent activity teaser for a profile (homepage-sized slice). Caps the\n * upstream wait so the SSR path cannot hang. Returns `null` on any error.\n */\nexport async function fetchActivityTeaser(\n config: SifaApiConfig,\n handleOrDid: string,\n options: FetchActivityTeaserOptions = {},\n): Promise<ActivityTeaserResponse | null> {\n const headers: Record<string, string> = { ...(options.headers ?? {}) };\n if (options.cookieHeader) headers.cookie = options.cookieHeader;\n\n try {\n return await apiFetch<ActivityTeaserResponse>(\n config,\n `/api/activity/${encodeIdentifier(handleOrDid)}/teaser`,\n {\n credentials: 'include',\n timeoutMs: 8000,\n next: { revalidate: 300, tags: [`activity-teaser-${handleOrDid}`] },\n ...options,\n headers,\n },\n );\n } catch {\n return null;\n }\n}\n\nexport interface FetchActivityFeedOptions extends ApiFetchOptions {\n category?: string;\n limit?: number;\n cursor?: string;\n cookieHeader?: string;\n}\n\n/**\n * Paginated activity feed for a profile. Always fresh (`cache: 'no-store'`).\n * Returns `null` on any error.\n */\nexport async function fetchActivityFeed(\n config: SifaApiConfig,\n handleOrDid: string,\n options: FetchActivityFeedOptions = {},\n): Promise<ActivityFeedResponse | null> {\n const params = new URLSearchParams();\n if (options.category) params.set('category', options.category);\n if (options.limit) params.set('limit', String(options.limit));\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n\n const headers: Record<string, string> = { ...(options.headers ?? {}) };\n if (options.cookieHeader) headers.cookie = options.cookieHeader;\n\n try {\n return await apiFetch<ActivityFeedResponse>(\n config,\n `/api/activity/${encodeIdentifier(handleOrDid)}${qs ? `?${qs}` : ''}`,\n {\n credentials: 'include',\n cache: 'no-store',\n ...options,\n headers,\n },\n );\n } catch {\n return null;\n }\n}\n"],"mappings":";AACA,SAAS,kBAAkB,gBAA0D;AAuGrF,eAAsB,iBACpB,QACA,aACA,MACA,UAA2B,CAAC,GACK;AACjC,QAAM,OAAO,iBAAiB,iBAAiB,WAAW,CAAC,iBAAiB,IAAI;AAChF,MAAI;AACF,WAAO,MAAM,SAA0B,QAAQ,MAAM;AAAA,MACnD,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC,WAAW,WAAW,EAAE,EAAE;AAAA,MAC1D,GAAG;AAAA,IACL,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeA,eAAsB,oBACpB,QACA,aACA,UAAsC,CAAC,GACC;AACxC,QAAM,UAAkC,EAAE,GAAI,QAAQ,WAAW,CAAC,EAAG;AACrE,MAAI,QAAQ,aAAc,SAAQ,SAAS,QAAQ;AAEnD,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA,iBAAiB,iBAAiB,WAAW,CAAC;AAAA,MAC9C;AAAA,QACE,aAAa;AAAA,QACb,WAAW;AAAA,QACX,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC,mBAAmB,WAAW,EAAE,EAAE;AAAA,QAClE,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;
|
|
1
|
+
{"version":3,"sources":["../../../src/query/fetchers/activity.ts"],"sourcesContent":["import type { ActivityLabel } from '../../cards/adult-content.js';\nimport { encodeIdentifier, apiFetch, type ApiFetchOptions, type SifaApiConfig } from '../client.js';\nimport type { QuotedPostResult } from './quoted-posts.js';\n\n/**\n * Liveness of an activity card's destination, as reported by sifa-api's\n * `/api/activity` enrichment (see sifa-api `url-health-checker`). How liveness\n * is measured depends on the card's health strategy (see `resolveCardHealth`):\n * first-party permalinks (`record`) are checked by record existence on the PDS;\n * foreign/derived targets (`url`) by HTTP reachability (HEAD, then GET).\n *\n * ok -- record exists, or the URL returned 2xx/3xx\n * broken -- confirmed dead (record deleted, or >=2 consecutive 4xx / >=5 consecutive 5xx)\n * unverifiable -- 403/429, PDS unreachable, or network error; NOT dead\n * unknown -- newly seen, not yet checked\n *\n * Consumers should only suppress UI on `'broken'`. All other values\n * (including missing) mean \"render normally\".\n */\nexport type ActivityItemLinkHealth = 'ok' | 'broken' | 'unverifiable' | 'unknown';\n\nexport interface HeatmapDay {\n date: string;\n total: number;\n apps: { appId: string; count: number }[];\n}\n\nexport interface HeatmapResponse {\n days: HeatmapDay[];\n appTotals: { appId: string; appName: string; total: number }[];\n thresholds: [number, number, number, number];\n}\n\nexport interface ActivityItem {\n uri: string;\n cid: string;\n collection: string;\n rkey: string;\n record: Record<string, unknown>;\n appId: string;\n appName: string;\n category: string;\n indexedAt: string;\n /**\n * The record author's handle / display name / avatar, injected by the server\n * on MULTI-author feeds (the following feed) so a card can show whose activity\n * it is. Unset on the per-author activity feed (all one author). Mirrors the\n * stream `ActivityItem`'s author fields the view-model transform reads.\n */\n authorHandle?: string;\n authorDisplayName?: string;\n authorAvatar?: string;\n /**\n * Set by the server when an `app.bsky.embed.record` quote was already\n * resolved upstream (AppView path). Mutually exclusive with `quotedPostUri`.\n */\n quotedPost?: QuotedPostResult;\n /**\n * Set by the server when an `app.bsky.embed.record` quote needs client-side\n * resolution (PDS path). Pass batches to {@link resolveQuotedPosts}.\n * Mutually exclusive with `quotedPost`.\n */\n quotedPostUri?: string;\n /**\n * Reachability of the card's external destination as last checked by\n * sifa-api. Undefined for legacy responses; treat as 'unknown'.\n * See {@link ActivityItemLinkHealth}.\n */\n linkHealth?: ActivityItemLinkHealth;\n /**\n * Content labels from `app.bsky.feed.defs#postView.labels`. Set by\n * sifa-api for Bluesky posts; undefined for other sources and legacy\n * responses. Pass items to {@link hasAdultContent} to decide whether to\n * gate media. See {@link ActivityLabel}.\n */\n labels?: ActivityLabel[];\n /**\n * The owner has hidden this item from their profile. Only ever set on the\n * owner's own view of their feed -- every other surface omits hidden items\n * rather than flagging them -- so a card can offer an unhide in place.\n */\n hidden?: boolean;\n}\n\nexport interface ActivityTeaserResponse {\n items: ActivityItem[];\n blueskyGated?: boolean;\n backfillPending?: boolean;\n failedApps?: string[];\n}\n\nexport interface ActivityFeedResponse {\n items: ActivityItem[];\n cursor: string | null;\n hasMore: boolean;\n availableCategories?: string[];\n blueskyGated?: boolean;\n failedApps?: string[];\n}\n\n/**\n * Per-day activity counts for a profile across all ATproto apps. Returns\n * `null` on any error so callers can render a graceful empty state.\n */\nexport async function fetchHeatmapData(\n config: SifaApiConfig,\n handleOrDid: string,\n days: number,\n options: ApiFetchOptions = {},\n): Promise<HeatmapResponse | null> {\n const path = `/api/activity/${encodeIdentifier(handleOrDid)}/heatmap?days=${days}`;\n try {\n return await apiFetch<HeatmapResponse>(config, path, {\n next: { revalidate: 900, tags: [`heatmap-${handleOrDid}`] },\n ...options,\n });\n } catch {\n return null;\n }\n}\n\nexport interface FetchActivityTeaserOptions extends ApiFetchOptions {\n /**\n * Pass the caller's `Cookie` header on Next.js RSC server-side calls.\n * Required for authenticated server fetches because `credentials: 'include'`\n * does not propagate browser cookies in RSC.\n */\n cookieHeader?: string;\n}\n\n/**\n * Recent activity teaser for a profile (homepage-sized slice). Caps the\n * upstream wait so the SSR path cannot hang. Returns `null` on any error.\n */\nexport async function fetchActivityTeaser(\n config: SifaApiConfig,\n handleOrDid: string,\n options: FetchActivityTeaserOptions = {},\n): Promise<ActivityTeaserResponse | null> {\n const headers: Record<string, string> = { ...(options.headers ?? {}) };\n if (options.cookieHeader) headers.cookie = options.cookieHeader;\n\n try {\n return await apiFetch<ActivityTeaserResponse>(\n config,\n `/api/activity/${encodeIdentifier(handleOrDid)}/teaser`,\n {\n credentials: 'include',\n timeoutMs: 8000,\n next: { revalidate: 300, tags: [`activity-teaser-${handleOrDid}`] },\n ...options,\n headers,\n },\n );\n } catch {\n return null;\n }\n}\n\nexport interface FetchActivityFeedOptions extends ApiFetchOptions {\n category?: string;\n /**\n * Show only these app categories. Applies when `category` is unset (the\n * \"all\" view).\n */\n categories?: string[];\n /**\n * Show only long-form posts carrying one of these tags. Other activity is\n * not filtered on tags. See `SiteActivityPreset`.\n */\n tags?: string[];\n /**\n * Apply the profile owner's saved preset for this surface. Explicit\n * `categories` / `tags` override the matching half of the preset.\n */\n preset?: 'site';\n limit?: number;\n cursor?: string;\n cookieHeader?: string;\n}\n\n/**\n * Paginated activity feed for a profile. Always fresh (`cache: 'no-store'`).\n * Returns `null` on any error.\n */\nexport async function fetchActivityFeed(\n config: SifaApiConfig,\n handleOrDid: string,\n options: FetchActivityFeedOptions = {},\n): Promise<ActivityFeedResponse | null> {\n const params = new URLSearchParams();\n if (options.category) params.set('category', options.category);\n if (options.categories?.length) params.set('categories', options.categories.join(','));\n if (options.tags?.length) params.set('tags', options.tags.join(','));\n if (options.preset) params.set('preset', options.preset);\n if (options.limit) params.set('limit', String(options.limit));\n if (options.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n\n const headers: Record<string, string> = { ...(options.headers ?? {}) };\n if (options.cookieHeader) headers.cookie = options.cookieHeader;\n\n try {\n return await apiFetch<ActivityFeedResponse>(\n config,\n `/api/activity/${encodeIdentifier(handleOrDid)}${qs ? `?${qs}` : ''}`,\n {\n credentials: 'include',\n cache: 'no-store',\n ...options,\n headers,\n },\n );\n } catch {\n return null;\n }\n}\n"],"mappings":";AACA,SAAS,kBAAkB,gBAA0D;AAuGrF,eAAsB,iBACpB,QACA,aACA,MACA,UAA2B,CAAC,GACK;AACjC,QAAM,OAAO,iBAAiB,iBAAiB,WAAW,CAAC,iBAAiB,IAAI;AAChF,MAAI;AACF,WAAO,MAAM,SAA0B,QAAQ,MAAM;AAAA,MACnD,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC,WAAW,WAAW,EAAE,EAAE;AAAA,MAC1D,GAAG;AAAA,IACL,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeA,eAAsB,oBACpB,QACA,aACA,UAAsC,CAAC,GACC;AACxC,QAAM,UAAkC,EAAE,GAAI,QAAQ,WAAW,CAAC,EAAG;AACrE,MAAI,QAAQ,aAAc,SAAQ,SAAS,QAAQ;AAEnD,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA,iBAAiB,iBAAiB,WAAW,CAAC;AAAA,MAC9C;AAAA,QACE,aAAa;AAAA,QACb,WAAW;AAAA,QACX,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC,mBAAmB,WAAW,EAAE,EAAE;AAAA,QAClE,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA4BA,eAAsB,kBACpB,QACA,aACA,UAAoC,CAAC,GACC;AACtC,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,QAAQ,SAAU,QAAO,IAAI,YAAY,QAAQ,QAAQ;AAC7D,MAAI,QAAQ,YAAY,OAAQ,QAAO,IAAI,cAAc,QAAQ,WAAW,KAAK,GAAG,CAAC;AACrF,MAAI,QAAQ,MAAM,OAAQ,QAAO,IAAI,QAAQ,QAAQ,KAAK,KAAK,GAAG,CAAC;AACnE,MAAI,QAAQ,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACvD,MAAI,QAAQ,MAAO,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC5D,MAAI,QAAQ,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACvD,QAAM,KAAK,OAAO,SAAS;AAE3B,QAAM,UAAkC,EAAE,GAAI,QAAQ,WAAW,CAAC,EAAG;AACrE,MAAI,QAAQ,aAAc,SAAQ,SAAS,QAAQ;AAEnD,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA,iBAAiB,iBAAiB,WAAW,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,MACnE;AAAA,QACE,aAAa;AAAA,QACb,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -801,6 +801,39 @@ async function fetchHiddenActivityItems(config, options = {}) {
|
|
|
801
801
|
}
|
|
802
802
|
}
|
|
803
803
|
|
|
804
|
+
// src/query/fetchers/activity-preferences.ts
|
|
805
|
+
async function fetchActivityPreferences(config, options = {}) {
|
|
806
|
+
const headers = { ...options.headers ?? {} };
|
|
807
|
+
if (options.cookieHeader) headers.cookie = options.cookieHeader;
|
|
808
|
+
try {
|
|
809
|
+
return await apiFetch(config, "/api/activity-preferences", {
|
|
810
|
+
credentials: "include",
|
|
811
|
+
cache: "no-store",
|
|
812
|
+
...options,
|
|
813
|
+
headers
|
|
814
|
+
});
|
|
815
|
+
} catch {
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
function updateActivityPreferences(config, input, options = {}) {
|
|
820
|
+
return apiWrite(config, "/api/activity-preferences", "PUT", {
|
|
821
|
+
...options,
|
|
822
|
+
body: input
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
async function fetchSiteActivityPreset(config, handleOrDid, options = {}) {
|
|
826
|
+
try {
|
|
827
|
+
return await apiFetch(
|
|
828
|
+
config,
|
|
829
|
+
`/api/activity-preferences/site-preset/${encodeIdentifier(handleOrDid)}`,
|
|
830
|
+
options
|
|
831
|
+
);
|
|
832
|
+
} catch {
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
804
837
|
// src/query/fetchers/stats.ts
|
|
805
838
|
async function fetchStats(config, options = {}) {
|
|
806
839
|
try {
|
|
@@ -1282,6 +1315,9 @@ async function fetchActivityTeaser(config, handleOrDid, options = {}) {
|
|
|
1282
1315
|
async function fetchActivityFeed(config, handleOrDid, options = {}) {
|
|
1283
1316
|
const params = new URLSearchParams();
|
|
1284
1317
|
if (options.category) params.set("category", options.category);
|
|
1318
|
+
if (options.categories?.length) params.set("categories", options.categories.join(","));
|
|
1319
|
+
if (options.tags?.length) params.set("tags", options.tags.join(","));
|
|
1320
|
+
if (options.preset) params.set("preset", options.preset);
|
|
1285
1321
|
if (options.limit) params.set("limit", String(options.limit));
|
|
1286
1322
|
if (options.cursor) params.set("cursor", options.cursor);
|
|
1287
1323
|
const qs = params.toString();
|
|
@@ -1843,6 +1879,45 @@ async function fetchProfileSummary(config, actor, options = {}) {
|
|
|
1843
1879
|
const view = await fetchGetProfileView(config, actor, fetchOptions);
|
|
1844
1880
|
return view ? summarizeProfileView(view, { maxSkills }) : null;
|
|
1845
1881
|
}
|
|
1882
|
+
var UserSettingsSchema = zod.z.object({
|
|
1883
|
+
respectBskyBlocks: zod.z.boolean(),
|
|
1884
|
+
autoLinkCompanies: zod.z.boolean(),
|
|
1885
|
+
/**
|
|
1886
|
+
* Show per-publication citation counts from OpenAlex on the profile.
|
|
1887
|
+
* Off by default; an API that predates the setting reads as off.
|
|
1888
|
+
*/
|
|
1889
|
+
showCitationCounts: zod.z.boolean().default(false)
|
|
1890
|
+
});
|
|
1891
|
+
async function fetchUserSettings(config, options = {}) {
|
|
1892
|
+
const { cookieHeader, ...rest } = options;
|
|
1893
|
+
const headers = { ...rest.headers ?? {} };
|
|
1894
|
+
if (cookieHeader) headers.cookie = cookieHeader;
|
|
1895
|
+
try {
|
|
1896
|
+
const data = await apiFetch(config, "/api/settings", {
|
|
1897
|
+
cache: "no-store",
|
|
1898
|
+
credentials: "include",
|
|
1899
|
+
...rest,
|
|
1900
|
+
headers
|
|
1901
|
+
});
|
|
1902
|
+
const parsed = UserSettingsSchema.safeParse(data);
|
|
1903
|
+
return parsed.success ? parsed.data : null;
|
|
1904
|
+
} catch {
|
|
1905
|
+
return null;
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
async function updateUserSettings(config, patch) {
|
|
1909
|
+
try {
|
|
1910
|
+
const data = await apiFetch(config, "/api/settings", {
|
|
1911
|
+
method: "PATCH",
|
|
1912
|
+
credentials: "include",
|
|
1913
|
+
body: patch
|
|
1914
|
+
});
|
|
1915
|
+
const parsed = UserSettingsSchema.safeParse(data);
|
|
1916
|
+
return parsed.success ? parsed.data : null;
|
|
1917
|
+
} catch {
|
|
1918
|
+
return null;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1846
1921
|
|
|
1847
1922
|
// src/query/keys.ts
|
|
1848
1923
|
var sifaQueryKeys = {
|
|
@@ -1926,7 +2001,10 @@ var sifaQueryKeys = {
|
|
|
1926
2001
|
feed: (handleOrDid, opts) => ["sifa", "activity", "feed", handleOrDid, opts],
|
|
1927
2002
|
// Session-scoped: the AppView reads the caller's own hides from their
|
|
1928
2003
|
// cookie, so there is only ever one list per client.
|
|
1929
|
-
hiddenItems: () => ["sifa", "activity", "hidden-items"]
|
|
2004
|
+
hiddenItems: () => ["sifa", "activity", "hidden-items"],
|
|
2005
|
+
// Session-scoped, like hiddenItems: the caller's own preferences.
|
|
2006
|
+
preferences: () => ["sifa", "activity", "preferences"],
|
|
2007
|
+
sitePreset: (handleOrDid) => ["sifa", "activity", "site-preset", handleOrDid]
|
|
1930
2008
|
},
|
|
1931
2009
|
github: {
|
|
1932
2010
|
all: () => ["sifa", "github"],
|
|
@@ -1982,6 +2060,9 @@ var sifaQueryKeys = {
|
|
|
1982
2060
|
all: () => ["sifa", "bsky-preferences"],
|
|
1983
2061
|
contentLabels: () => ["sifa", "bsky-preferences", "content-labels"]
|
|
1984
2062
|
},
|
|
2063
|
+
userSettings: {
|
|
2064
|
+
all: () => ["sifa", "user-settings"]
|
|
2065
|
+
},
|
|
1985
2066
|
repoInventory: {
|
|
1986
2067
|
all: () => ["sifa", "repo-inventory"],
|
|
1987
2068
|
list: () => ["sifa", "repo-inventory", "list"]
|
|
@@ -2143,6 +2224,7 @@ exports.PROFILE_COMPLETENESS_SIGNALS = PROFILE_COMPLETENESS_SIGNALS;
|
|
|
2143
2224
|
exports.QUOTED_POSTS_BATCH_MAX = QUOTED_POSTS_BATCH_MAX;
|
|
2144
2225
|
exports.RpgItemStatusSchema = RpgItemStatusSchema;
|
|
2145
2226
|
exports.RpgStatusResponseSchema = RpgStatusResponseSchema;
|
|
2227
|
+
exports.UserSettingsSchema = UserSettingsSchema;
|
|
2146
2228
|
exports.addFeatureAllowlist = addFeatureAllowlist;
|
|
2147
2229
|
exports.addOrgNotificationEmail = addOrgNotificationEmail;
|
|
2148
2230
|
exports.apiFetch = apiFetch;
|
|
@@ -2184,6 +2266,7 @@ exports.dismissEndorsement = dismissEndorsement;
|
|
|
2184
2266
|
exports.dismissUnlinkedPosition = dismissUnlinkedPosition;
|
|
2185
2267
|
exports.fetchAccounts = fetchAccounts;
|
|
2186
2268
|
exports.fetchActivityFeed = fetchActivityFeed;
|
|
2269
|
+
exports.fetchActivityPreferences = fetchActivityPreferences;
|
|
2187
2270
|
exports.fetchActivityTeaser = fetchActivityTeaser;
|
|
2188
2271
|
exports.fetchAppsRegistry = fetchAppsRegistry;
|
|
2189
2272
|
exports.fetchAtFundLink = fetchAtFundLink;
|
|
@@ -2219,6 +2302,7 @@ exports.fetchSearchCompanies = fetchSearchCompanies;
|
|
|
2219
2302
|
exports.fetchSearchFilters = fetchSearchFilters;
|
|
2220
2303
|
exports.fetchSearchProfiles = fetchSearchProfiles;
|
|
2221
2304
|
exports.fetchSimilarProfiles = fetchSimilarProfiles;
|
|
2305
|
+
exports.fetchSiteActivityPreset = fetchSiteActivityPreset;
|
|
2222
2306
|
exports.fetchSkillSuggestions = fetchSkillSuggestions;
|
|
2223
2307
|
exports.fetchSpeakers = fetchSpeakers;
|
|
2224
2308
|
exports.fetchStats = fetchStats;
|
|
@@ -2226,6 +2310,7 @@ exports.fetchSuggestionCount = fetchSuggestionCount;
|
|
|
2226
2310
|
exports.fetchSuggestions = fetchSuggestions;
|
|
2227
2311
|
exports.fetchTalks = fetchTalks;
|
|
2228
2312
|
exports.fetchUnlinkedPositions = fetchUnlinkedPositions;
|
|
2313
|
+
exports.fetchUserSettings = fetchUserSettings;
|
|
2229
2314
|
exports.fetchViewerPositionConfirmations = fetchViewerPositionConfirmations;
|
|
2230
2315
|
exports.fetchWipePreview = fetchWipePreview;
|
|
2231
2316
|
exports.followUser = followUser;
|
|
@@ -2277,6 +2362,7 @@ exports.unrevealMarqueDomain = unrevealMarqueDomain;
|
|
|
2277
2362
|
exports.unsetExternalAccountPrimary = unsetExternalAccountPrimary;
|
|
2278
2363
|
exports.unsetPositionPrimary = unsetPositionPrimary;
|
|
2279
2364
|
exports.unsetSectionPrimary = unsetSectionPrimary;
|
|
2365
|
+
exports.updateActivityPreferences = updateActivityPreferences;
|
|
2280
2366
|
exports.updateEducation = updateEducation;
|
|
2281
2367
|
exports.updateExternalAccount = updateExternalAccount;
|
|
2282
2368
|
exports.updateInvestment = updateInvestment;
|
|
@@ -2287,6 +2373,7 @@ exports.updateProfileOverride = updateProfileOverride;
|
|
|
2287
2373
|
exports.updateProfileSelf = updateProfileSelf;
|
|
2288
2374
|
exports.updateRecord = updateRecord;
|
|
2289
2375
|
exports.updateSkill = updateSkill;
|
|
2376
|
+
exports.updateUserSettings = updateUserSettings;
|
|
2290
2377
|
exports.uploadAvatar = uploadAvatar;
|
|
2291
2378
|
exports.uploadNamePronunciationAudio = uploadNamePronunciationAudio;
|
|
2292
2379
|
exports.verifyExternalAccount = verifyExternalAccount;
|