atproto user agency toolkit for individuals and groups
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 221 lines 6.1 kB view raw
1/** 2 * Built-in policy presets for common replication scenarios. 3 * 4 * Each preset is a factory that accepts minimal configuration and returns 5 * a full Policy object. Presets are convenience helpers — users can always 6 * write policies from scratch. 7 */ 8 9import type { Policy, StoredPolicy } from "./types.js"; 10import { 11 DEFAULT_REPLICATION, 12 DEFAULT_SYNC, 13 DEFAULT_RETENTION, 14 DEFAULT_PRIORITY, 15 toStoredPolicy, 16} from "./types.js"; 17 18// ============================================ 19// mutual-aid: N-of-M redundancy among a peer group 20// ============================================ 21 22export interface MutualAidOptions { 23 /** Unique policy ID. Defaults to "mutual-aid". */ 24 id?: string; 25 /** Human-readable name. */ 26 name?: string; 27 /** The DIDs of all peers in the mutual-aid group. */ 28 peerDids: string[]; 29 /** Minimum copies across the group. Default: 2. */ 30 minCopies?: number; 31 /** Sync interval in seconds. Default: 600 (10 minutes). */ 32 intervalSec?: number; 33 /** Priority. Default: 50. */ 34 priority?: number; 35} 36 37/** 38 * Create a mutual-aid policy. Each peer in the group stores copies of 39 * the others' data for collective resilience. 40 */ 41export function mutualAid(options: MutualAidOptions): Policy { 42 return { 43 id: options.id ?? "mutual-aid", 44 name: options.name ?? "Mutual Aid", 45 target: { 46 type: "list", 47 dids: options.peerDids, 48 }, 49 replication: { 50 minCopies: options.minCopies ?? 2, 51 preferredPeers: options.peerDids, 52 }, 53 sync: { 54 intervalSec: options.intervalSec ?? 600, 55 }, 56 retention: { 57 maxAgeSec: 0, // keep forever 58 keepHistory: false, 59 }, 60 priority: options.priority ?? DEFAULT_PRIORITY, 61 enabled: true, 62 }; 63} 64 65// ============================================ 66// saas: SLA compliance 67// ============================================ 68 69export interface SaasOptions { 70 /** Unique policy ID. Defaults to "saas". */ 71 id?: string; 72 /** Human-readable name. */ 73 name?: string; 74 /** The DIDs of serviced accounts. */ 75 accountDids: string[]; 76 /** Minimum copies for SLA guarantees. Default: 3. */ 77 minCopies?: number; 78 /** Sync interval in seconds. Default: 60 (1 minute). */ 79 intervalSec?: number; 80 /** Retention max age in seconds. Default: 0 (forever). */ 81 maxAgeSec?: number; 82 /** Whether to keep history. Default: true. */ 83 keepHistory?: boolean; 84 /** Priority. Default: 80 (high). */ 85 priority?: number; 86} 87 88/** 89 * Create a SaaS SLA policy. Guarantees fast sync, high redundancy, 90 * and defined retention for paying accounts. 91 */ 92export function saas(options: SaasOptions): Policy { 93 return { 94 id: options.id ?? "saas", 95 name: options.name ?? "SaaS SLA", 96 target: { 97 type: "list", 98 dids: options.accountDids, 99 }, 100 replication: { 101 minCopies: options.minCopies ?? 3, 102 }, 103 sync: { 104 intervalSec: options.intervalSec ?? 60, 105 }, 106 retention: { 107 maxAgeSec: options.maxAgeSec ?? 0, 108 keepHistory: options.keepHistory ?? true, 109 }, 110 priority: options.priority ?? 80, 111 enabled: true, 112 }; 113} 114 115// ============================================ 116// group-governance: quorum-based replication decisions 117// ============================================ 118 119export interface GroupGovernanceOptions { 120 /** Unique policy ID. Defaults to "group-governance". */ 121 id?: string; 122 /** Human-readable name. */ 123 name?: string; 124 /** The DIDs that the group has decided to replicate. */ 125 approvedDids: string[]; 126 /** Members of the governance group (for preferred peers). */ 127 memberDids?: string[]; 128 /** Minimum copies. Default: 2. */ 129 minCopies?: number; 130 /** Sync interval in seconds. Default: 300 (5 minutes). */ 131 intervalSec?: number; 132 /** Priority. Default: 60. */ 133 priority?: number; 134} 135 136/** 137 * Create a group-governance policy. The group collectively decides 138 * which accounts to replicate. The approved list is the outcome of 139 * that governance process (quorum, vote, etc.) — the policy engine 140 * simply enforces the result. 141 */ 142export function groupGovernance(options: GroupGovernanceOptions): Policy { 143 return { 144 id: options.id ?? "group-governance", 145 name: options.name ?? "Group Governance", 146 target: { 147 type: "list", 148 dids: options.approvedDids, 149 }, 150 replication: { 151 minCopies: options.minCopies ?? 2, 152 preferredPeers: options.memberDids, 153 }, 154 sync: { 155 intervalSec: options.intervalSec ?? 300, 156 }, 157 retention: { 158 maxAgeSec: 0, 159 keepHistory: false, 160 }, 161 priority: options.priority ?? 60, 162 enabled: true, 163 }; 164} 165 166// ============================================ 167// configArchive: policy for a config-origin DID 168// ============================================ 169 170/** 171 * Create a StoredPolicy for a DID originating from REPLICATE_DIDS config. 172 * ID: `config:{did}`, type: config, priority 30. 173 */ 174export function configArchive(did: string): StoredPolicy { 175 const base: Policy = { 176 id: `config:${did}`, 177 name: `Config: ${did}`, 178 target: { type: "list", dids: [did] }, 179 replication: { ...DEFAULT_REPLICATION }, 180 sync: { ...DEFAULT_SYNC }, 181 retention: { ...DEFAULT_RETENTION }, 182 priority: 30, 183 enabled: true, 184 }; 185 return toStoredPolicy(base, "config", { source: "config", consent: "unconsented" }); 186} 187 188// ============================================ 189// archive: policy for a user-added DID 190// ============================================ 191 192export interface ArchiveOptions { 193 /** Priority. Default: 40. */ 194 priority?: number; 195 /** Sync interval in seconds. Default: 300. */ 196 intervalSec?: number; 197 /** Who created the policy. Default: "user". */ 198 createdBy?: string; 199} 200 201/** 202 * Create a StoredPolicy for a user-added (archive) DID. 203 * ID: `archive:{did}`, type: archive, priority 40. 204 */ 205export function archive(did: string, opts?: ArchiveOptions): StoredPolicy { 206 const base: Policy = { 207 id: `archive:${did}`, 208 name: `Archive: ${did}`, 209 target: { type: "list", dids: [did] }, 210 replication: { ...DEFAULT_REPLICATION }, 211 sync: { intervalSec: opts?.intervalSec ?? DEFAULT_SYNC.intervalSec }, 212 retention: { ...DEFAULT_RETENTION }, 213 priority: opts?.priority ?? 40, 214 enabled: true, 215 }; 216 return toStoredPolicy(base, "archive", { 217 source: "manual", 218 consent: "unconsented", 219 createdBy: opts?.createdBy ?? "user", 220 }); 221}