atproto blogging
1#!/usr/bin/env bash
2set -euo pipefail
3
4SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5cd "$SCRIPT_DIR"
6
7PKG_NAME="@weaver.sh/renderer"
8PKG_VERSION="0.1.1"
9
10# Targets to build
11TARGETS=(bundler web nodejs deno)
12
13COMMAND="${1:-build}"
14shift || true
15
16# Feature variants
17declare -A VARIANTS=(
18 ["core"]=""
19 ["full"]="syntax-highlighting"
20)
21
22build() {
23 local target="$1"
24 local variant="$2"
25 local features="$3"
26 local out_dir="pkg/${variant}/${target}"
27
28 echo "Building ${variant}/${target}..."
29
30 local feature_args=""
31 if [[ -n "$features" ]]; then
32 feature_args="--features $features"
33 fi
34
35 wasm-pack build \
36 --out-name weaver_renderer \
37 --out-dir "$out_dir" \
38 --target "$target" \
39 --no-default-features \
40 $feature_args
41
42 # Report size
43 local wasm_file="${out_dir}/weaver_renderer_bg.wasm"
44 if [[ -f "$wasm_file" ]]; then
45 local size=$(ls -lh "$wasm_file" | awk '{print $5}')
46 echo " → ${size}"
47 fi
48}
49
50generate_package_json() {
51 local variant="$1"
52 local out_dir="pkg/${variant}"
53 local description="AT Protocol record renderer (${variant})"
54
55 if [[ "$variant" == "full" ]]; then
56 description="AT Protocol record renderer with syntax highlighting"
57 else
58 description="AT Protocol record renderer (lightweight, no syntax highlighting)"
59 fi
60
61 cat > "${out_dir}/package.json" << EOF
62{
63 "name": "${PKG_NAME}-${variant}",
64 "version": "${PKG_VERSION}",
65 "description": "${description}",
66 "license": "MPL-2.0",
67 "repository": {
68 "type": "git",
69 "url": "https://tangled.org/nonbinary.computer/weaver"
70 },
71 "keywords": ["atproto", "bluesky", "markdown", "renderer", "wasm"],
72 "main": "nodejs/weaver_renderer.js",
73 "module": "bundler/weaver_renderer.js",
74 "browser": "web/weaver_renderer.js",
75 "types": "bundler/weaver_renderer.d.ts",
76 "exports": {
77 ".": {
78 "deno": "./deno/weaver_renderer.js",
79 "node": {
80 "import": "./nodejs/weaver_renderer.js",
81 "require": "./nodejs/weaver_renderer.js"
82 },
83 "browser": {
84 "import": "./web/weaver_renderer.js"
85 },
86 "default": "./bundler/weaver_renderer.js"
87 },
88 "./bundler": {
89 "import": "./bundler/weaver_renderer.js",
90 "types": "./bundler/weaver_renderer.d.ts"
91 },
92 "./web": {
93 "import": "./web/weaver_renderer.js",
94 "types": "./web/weaver_renderer.d.ts"
95 },
96 "./nodejs": {
97 "import": "./nodejs/weaver_renderer.js",
98 "require": "./nodejs/weaver_renderer.js",
99 "types": "./nodejs/weaver_renderer.d.ts"
100 },
101 "./deno": {
102 "import": "./deno/weaver_renderer.js",
103 "types": "./deno/weaver_renderer.d.ts"
104 }
105 },
106 "files": [
107 "bundler/",
108 "web/",
109 "nodejs/",
110 "deno/",
111 "README.md"
112 ]
113}
114EOF
115}
116
117generate_readme() {
118 local variant="$1"
119 local out_dir="pkg/${variant}"
120
121 cat > "${out_dir}/README.md" << 'EOF'
122# @weaver.sh/renderer
123
124WASM bindings for rendering AT Protocol records (Bluesky posts, etc.) to HTML.
125
126## Installation
127
128```bash
129npm install @weaver.sh/renderer-full # With syntax highlighting
130npm install @weaver.sh/renderer-core # Light(er) weight
131```
132
133## Usage
134
135### With a bundler (webpack, vite, etc.)
136
137```javascript
138import init, { render_record, render_markdown } from '@weaver.sh/renderer-full';
139
140await init();
141
142const html = render_record(atUri, recordJson);
143```
144
145### Direct browser usage (no bundler)
146
147```html
148<script type="module">
149 import init, { render_record } from '@weaver.sh/renderer-full/web';
150 await init();
151 // ...
152</script>
153```
154
155### Node.js
156
157```javascript
158const { render_record } = require('@weaver.sh/renderer-full/nodejs');
159```
160
161## API
162
163- `render_record(at_uri, record_json, fallback_author?, resolved_content?)` - Render an AT Protocol record
164- `render_markdown(markdown, resolved_content?)` - Render markdown to HTML
165- `render_math(latex, display_mode)` - Render LaTeX math to MathML
166- `render_faceted_text(text, facets_json)` - Render rich text with facets
167EOF
168}
169
170do_build() {
171# Clean previous builds
172rm -rf pkg
173
174# Build all combinations
175for variant in "${!VARIANTS[@]}"; do
176 features="${VARIANTS[$variant]}"
177
178 for target in "${TARGETS[@]}"; do
179 build "$target" "$variant" "$features"
180 done
181
182 generate_package_json "$variant"
183 generate_readme "$variant"
184
185 # Clean up wasm-pack artifacts we don't need
186 find "pkg/${variant}" -name ".gitignore" -delete
187 find "pkg/${variant}" -name "package.json" -path "*/bundler/*" -delete
188 find "pkg/${variant}" -name "package.json" -path "*/web/*" -delete
189 find "pkg/${variant}" -name "package.json" -path "*/nodejs/*" -delete
190 find "pkg/${variant}" -name "package.json" -path "*/deno/*" -delete
191done
192
193echo ""
194echo "Build complete!"
195echo ""
196ls -lh pkg/core/web/*.wasm pkg/full/web/*.wasm 2>/dev/null || true
197echo ""
198echo "Packages:"
199echo " pkg/core/ - @weaver.sh/renderer-core (no syntax highlighting)"
200echo " pkg/full/ - @weaver.sh/renderer-full (with syntax highlighting)"
201}
202
203do_pack() {
204 echo "Packing..."
205 for variant in "${!VARIANTS[@]}"; do
206 echo " ${variant}..."
207 (cd "pkg/${variant}" && npm pack)
208 done
209 echo ""
210 echo "Tarballs created:"
211 ls -lh pkg/*/*.tgz 2>/dev/null || true
212}
213
214do_publish() {
215 local tag="${1:-}"
216 local tag_arg=""
217 if [[ -n "$tag" ]]; then
218 tag_arg="--tag $tag"
219 fi
220
221 echo "Publishing..."
222 for variant in "${!VARIANTS[@]}"; do
223 echo " ${variant}..."
224 (cd "pkg/${variant}" && npm publish --access public $tag_arg)
225 done
226 echo ""
227 echo "Published!"
228}
229
230usage() {
231 echo "Usage: $0 [command]"
232 echo ""
233 echo "Commands:"
234 echo " build Build all variants and targets (default)"
235 echo " pack Create npm tarballs"
236 echo " publish Publish to npm registry"
237 echo " all Build, pack, and publish"
238 echo ""
239 echo "Options for publish:"
240 echo " --tag <tag> Publish with a specific tag (e.g., 'next', 'beta')"
241}
242
243case "$COMMAND" in
244 build)
245 do_build
246 ;;
247 pack)
248 do_pack
249 ;;
250 publish)
251 do_publish "$@"
252 ;;
253 all)
254 do_build
255 do_pack
256 do_publish "$@"
257 ;;
258 -h|--help|help)
259 usage
260 ;;
261 *)
262 echo "Unknown command: $COMMAND"
263 usage
264 exit 1
265 ;;
266esac