source for getorbyt.com getorbyt.com/
client bsky orbytapp app orbyt bluesky getorbyt orbytvideo atproto video
0
fork

Configure Feed

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

refactor: update AltStore ADP handling by removing static source.json; implement dynamic serving via site Worker and adjust related documentation for clarity

+38 -91
+1 -1
README.md
··· 55 55 - **Config:** [wrangler.jsonc](wrangler.jsonc) — assets binding, ORBYT_API service, R2 bucket binding 56 56 - **Deploy Command:** `npm run build && npx wrangler deploy` 57 57 - **Pages cleanup:** If you previously created a Pages project, see [docs/CLOUDFLARE_PAGES_CLEANUP.md](docs/CLOUDFLARE_PAGES_CLEANUP.md) 58 - - **AltStore ADP:** hosted in Cloudflare R2; only `public/altstore/source.json` and `public/altstore/orbyt-icon.png` stay in site assets 58 + - **AltStore ADP:** hosted in Cloudflare R2; source JSON is served dynamically at `/altstore/source.json` via `src/pages/altstore/source.json.ts`, and `public/altstore/orbyt-icon.png` remains static 59 59 - **AltStore Runbook:** see [docs/ALTSTORE_FINISH_SETUP.md](docs/ALTSTORE_FINISH_SETUP.md) → "Quick Release Checklist" 60 60 61 61 ## Project Structure
+9 -7
docs/ALTSTORE_FINISH_SETUP.md
··· 4 4 5 5 **Prerequisites:** These instructions assume `orbyt-app` and `orbyt-site` are sibling directories (e.g. both under `orbyt-master`). Run commands from the parent directory, or adjust paths to your layout. 6 6 7 - **Cloudflare note:** Do not deploy the ADP folder from `public/`. The IPA files are larger than Cloudflare Workers static asset limits. Use R2 for the ADP payload and keep only `source.json` and the icon on the website. 7 + **Cloudflare note:** Do not deploy the ADP folder from `public/`. The IPA files are larger than Cloudflare Workers static asset limits. Use R2 for the ADP payload. The public source URL (`https://getorbyt.com/altstore/source.json`) is served dynamically by the site Worker and should be managed via `orbyt-api` admin. 8 8 9 9 **Routing note:** `getorbyt.com/*` is served by the Cloudflare Worker route configured in `wrangler.jsonc`, so deploy production with `wrangler deploy`. 10 10 ··· 91 91 1. create the R2 bucket if needed 92 92 2. enable the public `r2.dev` URL (fallback) 93 93 3. upload `manifest.json`, `signature`, and `variant/*.ipa` 94 - 4. update `public/altstore/source.json` so `downloadURL` points to `https://downloads.getorbyt.com/manifest.json` when available, otherwise it falls back to `r2.dev` 94 + 4. print the preferred manifest URL (`https://downloads.getorbyt.com/manifest.json` when available, otherwise `r2.dev`) for use in `orbyt-api` admin publish flow 95 95 96 96 If you want to use a different bucket name, replace `orbyt-altstore-adp` with your preferred name. 97 97 ··· 124 124 125 125 https://getorbyt.com/altstore/source.json 126 126 127 - 3. Verify the ADP manifest URL stored inside `source.json` returns `200`. 127 + 3. Verify the ADP manifest URL referenced by published source JSON returns `200`. 128 128 129 129 --- 130 130 ··· 177 177 rm -rf .altstore/adp 178 178 mv ../orbyt-app/adp-extracted .altstore/adp 179 179 180 - # 4) Upload ADP to R2 and update public/altstore/source.json downloadURL 180 + # 4) Upload ADP to R2 and note printed manifest URL 181 181 npm run altstore:r2 -- setup orbyt-altstore-adp 182 182 183 - # 5) Deploy production route (getorbyt.com/*) 183 + # 5) In orbyt-api admin, update source downloadURL to printed manifest URL, then publish 184 + 185 + # 6) Deploy production route (getorbyt.com/*) 184 186 npm run build 185 187 npx wrangler deploy 186 188 187 - # 6) Verify live URLs 189 + # 7) Verify live URLs 188 190 curl -sS -o /dev/null -w 'source %{http_code}\n' https://getorbyt.com/altstore/source.json 189 191 curl -sS -o /dev/null -w 'manifest %{http_code}\n' https://downloads.getorbyt.com/manifest.json 190 192 191 - # 7) Federate source 193 + # 8) Federate source 192 194 curl -X POST -H "Content-Type: application/json" -d '{"source":"https://getorbyt.com/altstore/source.json"}' https://api.altstore.io/federate 193 195 ``` 194 196
+1 -1
public/altstore/README.md
··· 1 1 # AltStore PAL assets 2 2 3 3 - `orbyt-icon.png` — App icon (1024×1024), already added 4 - - `source.json` — Hosted from this site at `https://getorbyt.com/altstore/source.json` 4 + - `source.json` — Served dynamically at `https://getorbyt.com/altstore/source.json` via the site Worker route (`src/pages/altstore/source.json.ts`) 5 5 - `.altstore/adp/` — Keep extracted ADP contents here locally, then upload them to R2 6 6 7 7 Default manifest host is `https://downloads.getorbyt.com/manifest.json`.
-47
public/altstore/source.json
··· 1 - { 2 - "name": "Orbyt", 3 - "subtitle": "Video app for Bluesky", 4 - "description": "Orbyt is a video-first social app for the Bluesky network, built on the AT Protocol. Available for EU and Japan via AltStore PAL.", 5 - "iconURL": "https://getorbyt.com/altstore/orbyt-icon.png", 6 - "headerURL": "https://getorbyt.com/images/orbyt-logotype.png", 7 - "website": "https://getorbyt.com", 8 - "tintColor": "#9B59B6", 9 - "fediUsername": "orbyt", 10 - "featuredApps": [ 11 - "com.getorbyt.app" 12 - ], 13 - "apps": [ 14 - { 15 - "name": "Orbyt", 16 - "bundleIdentifier": "com.getorbyt.app", 17 - "marketplaceID": "6751679299", 18 - "developerName": "Orbyt", 19 - "subtitle": "Video app for Bluesky", 20 - "localizedDescription": "Orbyt is a video-first social app for the Bluesky network.\n\n• Browse video feeds from Bluesky\n• Create and share short-form videos\n• Connect with the AT Protocol community\n• Built with React Native and Expo", 21 - "iconURL": "https://getorbyt.com/altstore/orbyt-icon.png", 22 - "tintColor": "#9B59B6", 23 - "category": "social", 24 - "screenshots": [], 25 - "versions": [ 26 - { 27 - "version": "1.1.2", 28 - "buildVersion": "62", 29 - "date": "2026-03-12", 30 - "localizedDescription": "Latest release.", 31 - "downloadURL": "https://downloads.getorbyt.com/manifest.json", 32 - "size": 70307293, 33 - "minOSVersion": "16.4" 34 - } 35 - ], 36 - "appPermissions": { 37 - "privacy": { 38 - "NSCameraUsageDescription": "We need camera access to record videos for posts and take profile photos.", 39 - "NSMicrophoneUsageDescription": "We need microphone access to record audio with your videos.", 40 - "NSPhotoLibraryUsageDescription": "We need access to your photo library to select videos for posts and photos for your profile.", 41 - "NSPhotoLibraryAddUsageDescription": "We need permission to save your videos to the camera roll." 42 - } 43 - } 44 - } 45 - ], 46 - "news": [] 47 - }
+4 -34
scripts/altstore-r2.sh
··· 3 3 4 4 ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 5 5 DEFAULT_ADP_DIR="${ALTSTORE_ADP_DIR:-$ROOT_DIR/.altstore/adp}" 6 - SOURCE_JSON="$ROOT_DIR/public/altstore/source.json" 7 6 DEFAULT_BUCKET_LOCATION="${R2_BUCKET_LOCATION:-weur}" 8 7 DEFAULT_CUSTOM_MANIFEST_URL="${ALTSTORE_CUSTOM_MANIFEST_URL:-https://downloads.getorbyt.com/manifest.json}" 9 8 ··· 12 11 Usage: 13 12 ./scripts/altstore-r2.sh setup <bucket> [adp_dir] 14 13 ./scripts/altstore-r2.sh upload <bucket> [adp_dir] 15 - ./scripts/altstore-r2.sh set-source-url <manifest_url> 16 14 ./scripts/altstore-r2.sh check <manifest_url> 17 15 18 16 Commands: 19 17 setup Create the R2 bucket if needed, enable the public r2.dev URL, 20 - upload the ADP directory, and update public/altstore/source.json. 18 + and upload the ADP directory. 21 19 upload Upload the ADP directory to an existing R2 bucket. 22 - set-source-url Update public/altstore/source.json to point at a manifest URL. 23 20 check Fetch a manifest URL and print the HTTP status. 24 21 25 22 Environment: ··· 47 44 } 48 45 49 46 ensure_prereqs() { 50 - require_file "$SOURCE_JSON" 47 + : 51 48 } 52 49 53 50 ensure_adp_dir() { ··· 133 130 done < <(find "$adp_dir" -type f | sort) 134 131 } 135 132 136 - set_source_url() { 137 - local manifest_url="$1" 138 - 139 - require_file "$SOURCE_JSON" 140 - 141 - node --input-type=commonjs - "$SOURCE_JSON" "$manifest_url" <<'NODE' 142 - const fs = require('node:fs'); 143 - const [filePath, manifestUrl] = process.argv.slice(2); 144 - const raw = fs.readFileSync(filePath, 'utf8'); 145 - const json = JSON.parse(raw); 146 - if (!Array.isArray(json.apps) || json.apps.length === 0) { 147 - throw new Error('source.json has no apps array'); 148 - } 149 - if (!Array.isArray(json.apps[0].versions) || json.apps[0].versions.length === 0) { 150 - throw new Error('source.json has no versions array'); 151 - } 152 - json.apps[0].versions[0].downloadURL = manifestUrl; 153 - fs.writeFileSync(filePath, `${JSON.stringify(json, null, 2)}\n`); 154 - NODE 155 - 156 - echo "Updated source download URL to: $manifest_url" 157 - } 158 - 159 133 check_url() { 160 134 local url="$1" 161 135 curl -sS -o /dev/null -w '%{http_code} %{url_effective}\n' "$url" ··· 191 165 [[ -n "$dev_url" ]] || fail "Unable to determine r2.dev URL for bucket '$bucket'" 192 166 193 167 manifest_url="$(pick_manifest_url "$dev_url")" 194 - set_source_url "$manifest_url" 195 168 196 169 echo 197 170 echo "R2 setup complete." 198 171 echo "Manifest URL: $manifest_url" 199 - echo "Next: deploy the site so https://getorbyt.com/altstore/source.json serves the updated metadata." 172 + echo "Next: update source JSON in orbyt-api admin (downloadURL=$manifest_url), publish, then verify:" 173 + echo " https://getorbyt.com/altstore/source.json" 200 174 } 201 175 202 176 main() { ··· 211 185 [[ $# -ge 2 ]] || fail "upload requires a bucket name" 212 186 ensure_adp_dir "${3:-$DEFAULT_ADP_DIR}" 213 187 upload_adp "$2" "${3:-$DEFAULT_ADP_DIR}" 214 - ;; 215 - set-source-url) 216 - [[ $# -eq 2 ]] || fail "set-source-url requires a manifest URL" 217 - set_source_url "$2" 218 188 ;; 219 189 check) 220 190 [[ $# -eq 2 ]] || fail "check requires a manifest URL"
+22
src/pages/altstore/source.json.ts
··· 1 + import { env } from 'cloudflare:workers'; 2 + 3 + export const prerender = false; 4 + 5 + export async function GET(): Promise<Response> { 6 + const upstream = await env.ORBYT_API.fetch('https://orbyt-api/v1/altstore/source.json', { 7 + method: 'GET', 8 + headers: { 9 + Accept: 'application/json', 10 + }, 11 + }); 12 + 13 + const body = await upstream.text(); 14 + const responseHeaders = new Headers(); 15 + responseHeaders.set('Content-Type', 'application/json; charset=utf-8'); 16 + responseHeaders.set('Cache-Control', 'public, max-age=60, stale-while-revalidate=300'); 17 + 18 + return new Response(body, { 19 + status: upstream.status, 20 + headers: responseHeaders, 21 + }); 22 + }
+1 -1
src/utils/ios-distribution.ts
··· 58 58 }>; 59 59 60 60 const DEFAULT_ALTSTORE_SOURCE = 'https://getorbyt.com/altstore/source.json'; 61 - /** Same marketplace ID as `public/altstore/source.json` */ 61 + /** Same marketplace ID as the canonical source served at `/altstore/source.json` */ 62 62 const DEFAULT_APP_STORE = 'https://apps.apple.com/app/id6751679299'; 63 63 64 64 /** Builds iOS download options based on the visitor's country; AltStore PAL is primary for EU and Japan. */