🦄 Pubky App Specs (WASM) · pubky-app-specs
A WASM library for building and validating structured JSON models compatible with Pubky.App social powered by @synonymdev/pubky
. It handles domain objects like Users, Posts, Feeds, Bookmarks, Tags, and more. Each object is:
- Sanitized and Validated via Rust logic.
- Auto-ID’ed and Auto-Pathed according to your domain rules.
- Exported to JavaScript/TypeScript with minimal overhead.
🤔 Why Use This Crate Instead of Manual JSONs?
- Validation Consistency: Ensures your app uses the same sanitization and validation rules as Pubky indexers, avoiding errors.
- Schema Versioning: Automatically stay up-to-date with schema changes, reducing maintenance overhead.
- Auto IDs & Paths: Generates unique IDs, paths, and URLs according to Pubky standards.
- Rust-to-JavaScript Compatibility: Type-safe models that work seamlessly across Rust and JavaScript/TypeScript.
- Future-Proof: Easily adapt to new Pubky object types without rewriting JSON manually.
⚙️ Installation
npm install pubky-app-specs
yarn add pubky-app-specs
Note: This package uses WASM. Ensure your bundler or environment supports loading WASM modules (e.g. Next.js, Vite, etc.).
🚀 Quick Start
- Initialize the WASM module.
- Construct a
PubkySpecsBuilder(pubkyId)
object. - Create validated domain objects (User, Post, Tag, etc.).
- Store them on the PubKy homeserver or any distributed storage solution you prefer.
Import & Initialize
import init, { PubkySpecsBuilder } from "pubky-app-specs";
async function loadSpecs(pubkyId) {
await init();
const specs = new PubkySpecsBuilder(pubkyId);
return specs;
}
🎨 Example Usage
Below are succinct examples to illustrate how to create or update data using pubky-app-specs
and then store it with @synonymdev/pubky
.
1) Creating a New User
import { Client, PublicKey } from "@synonymdev/pubky";
import { PubkySpecsBuilder } from "pubky-app-specs";
async function createUser(pubkyId) {
const client = new Client();
const specs = new PubkySpecsBuilder(pubkyId);
const userResult = specs.createUser(
"Alice",
"Hello from WASM",
null,
null,
"active"
);
const userJson = userResult.user.toJson();
const response = await client.fetch(userResult.meta.url, {
method: "PUT",
body: JSON.stringify(userJson),
credentials: "include",
});
if (!response.ok) {
throw new Error(`Failed to store user: ${response.statusText}`);
}
console.log("User stored at:", userResult.meta.url);
return userResult;
}
2) Creating a Post
import { Client } from "@synonymdev/pubky";
import { PubkySpecsBuilder, PubkyAppPostKind } from "pubky-app-specs";
async function createPost(pubkyId, content) {
const client = new Client();
const specs = new PubkySpecsBuilder(pubkyId);
const postResult = specs.createPost(
content,
PubkyAppPostKind.Short,
null,
null,
null
);
const postJson = postResult.post.toJson();
await client.fetch(postResult.meta.url, {
method: "PUT",
body: JSON.stringify(postJson),
});
console.log("Post stored at:", postResult.meta.url);
return postResult;
}
3) Following a User
import { Client } from "@synonymdev/pubky";
import { PubkySpecsBuilder } from "pubky-app-specs";
async function followUser(myPubkyId, userToFollow) {
const client = new Client();
const specs = new PubkySpecsBuilder(myPubkyId);
const followResult = specs.createFollow(userToFollow);
await client.fetch(followResult.meta.url, {
method: "PUT",
body: JSON.stringify(followResult.follow.toJson()),
});
console.log(`Successfully followed: ${userToFollow}`);
}
📁 Additional Models
This library supports many more domain objects beyond User
and Post
. Here are a few more you can explore:
- Feeds:
createFeed(...)
- Bookmarks:
createBookmark(...)
- Tags:
createTag(...)
- Mutes:
createMute(...)
- Follows:
createFollow(...)
- LastRead:
createLastRead(...)
Each has a meta
field for storing relevant IDs/paths and a typed data object.