npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@cosmik.network/semble-pds-client

v0.0.6

Published

A lightweight PDS client and AtpAgent wrapper for creating and reading Semble records (Cards, Collections, CollectionLinks) directly to your PDS

Readme

@cosmik.network/semble-pds-client

A lightweight PDS client and AtpAgent wrapper for creating Semble records (Cards, Collections, CollectionLinks) directly to your PDS.

Installation

npm install @cosmik.network/semble-pds-client

Usage

import { SemblePDSClient } from '@cosmik.network/semble-pds-client';

const client = new SemblePDSClient({
  service: 'https://bsky.social', // or your PDS URL
  env: 'dev', // optional: appends to NSID (e.g. network.cosmik.dev.*), usually only used for testing purposes
});

// Login with app password
await client.login('your-handle.bsky.social', 'your-app-password');

// Create a URL card
const card = await client.createCard({
  url: 'https://example.com',
  note: 'Optional note about this URL',
  viaCard: someOtherCard, // Optional: reference to the card that led to this one
});

// Add a note to an existing card
const noteCard = await client.addNoteToCard(card, 'This is my note');

// Create a collection
const collection = await client.createCollection({
  name: 'My Collection',
  description: 'Optional description',
});

// Add card to collection
const collectionLink = await client.addCardToCollection(card, collection);

// Add card to collection with provenance tracking
const collectionLinkWithProvenance = await client.addCardToCollection(
  card,
  collection,
  viaCard, // Optional: reference to the card that led to this addition
);

// Update a note
await client.updateNote(noteCard, 'Updated note text');

// Delete a card
await client.deleteCard(card);

// Update collection
await client.updateCollection(collection, 'New Name', 'New description');

// Delete collection
await client.deleteCollection(collection);

// Remove card from collection
await client.removeCardFromCollection(collectionLink);

// Get a specific card
const cardRecord = await client.getCard(card);

// Get a specific collection
const collectionRecord = await client.getCollection(collection);

// List your own cards with pagination
const myCardsResult = await client.getMyCards({
  limit: 50,
  cursor: 'optional-cursor',
  reverse: false,
});

// List your own collections with pagination
const myCollectionsResult = await client.getMyCollections({
  limit: 20,
});

// List cards for a specific user
const userCardsResult = await client.getCards('did:plc:example123', {
  limit: 50,
});

// List collections for a specific user
const userCollectionsResult = await client.getCollections(
  'did:plc:example123',
  {
    limit: 20,
  },
);

// Batch create multiple cards
const cardsResult = await client.createCards({
  cards: [
    { url: 'https://example1.com', note: 'First card' },
    { url: 'https://example2.com' },
    { url: 'https://example3.com', viaCard: someCard },
  ],
});

// Batch create multiple collections
const collectionsResult = await client.createCollections({
  collections: [
    { name: 'Collection 1', description: 'First collection' },
    { name: 'Collection 2' },
  ],
});

// Batch add multiple cards to a collection
const linksResult = await client.addCardsToCollection({
  collection: myCollection,
  cards: [card1, card2, card3],
  viaCard: someCard, // Optional: applies to all cards being added
});

API

SemblePDSClient

Constructor

  • new SemblePDSClient(options) - Create a new client instance
    • options.service - PDS service URL
    • options.env - Optional environment string that gets appended to the NSID (e.g. network.cosmik.{env}.*)

Methods

  • login(identifier, password) - Authenticate with app password
  • createCard(options) - Create a URL card with automatic metadata fetching and optional provenance tracking
  • addNoteToCard(parentCard, noteText) - Add a note card to an existing card
  • createCollection(options) - Create a new collection (defaults to CLOSED access)
  • addCardToCollection(card, collection, viaCard?) - Link a card to a collection with optional provenance tracking
  • updateNote(noteRef, updatedText) - Update an existing note card
  • deleteCard(cardRef) - Delete a card
  • updateCollection(collectionRef, name, description?) - Update collection details
  • deleteCollection(collectionRef) - Delete a collection
  • removeCardFromCollection(collectionLinkRef) - Remove a card from a collection
  • getCard(cardRef) - Get a specific card record
  • getCollection(collectionRef) - Get a specific collection record
  • getMyCards(params?) - List your own cards with optional pagination parameters
  • getMyCollections(params?) - List your own collections with optional pagination parameters
  • getCards(did, params?) - List cards for a specific user with optional pagination parameters
  • getCollections(did, params?) - List collections for a specific user with optional pagination parameters
  • createCards(options) - Batch create multiple cards using applyWrites
  • createCollections(options) - Batch create multiple collections using applyWrites
  • addCardsToCollection(options) - Batch add multiple cards to a collection using applyWrites

Types

StrongRef

interface StrongRef {
  uri: string;
  cid: string;
}

CreateCardOptions

interface CreateCardOptions {
  url: string;
  note?: string;
  viaCard?: StrongRef; // Optional reference to the card that led to this one
}

CreateCollectionOptions

interface CreateCollectionOptions {
  name: string;
  description?: string;
}

ListQueryParams

interface ListQueryParams {
  limit?: number;
  cursor?: string;
  reverse?: boolean;
}

CardRecord

interface CardRecord {
  uri: string;
  cid: string;
  value: {
    $type: string;
    type: 'URL' | 'NOTE';
    content: any;
    url?: string;
    parentCard?: StrongRef;
    createdAt: string;
    originalCard?: StrongRef;
    provenance?: {
      $type: string;
      via?: StrongRef;
    };
  };
}

CollectionRecord

interface CollectionRecord {
  uri: string;
  cid: string;
  value: {
    $type: string;
    name: string;
    description?: string;
    accessType: 'OPEN' | 'CLOSED';
    collaborators?: string[];
    createdAt: string;
    updatedAt: string;
  };
}

GetCardsResult / GetCollectionsResult

interface GetCardsResult {
  cursor?: string;
  records: CardRecord[];
}

interface GetCollectionsResult {
  cursor?: string;
  records: CollectionRecord[];
}

CreateCardsOptions

interface CreateCardsOptions {
  cards: CreateCardOptions[];
}

CreateCollectionsOptions

interface CreateCollectionsOptions {
  collections: CreateCollectionOptions[];
}

AddCardsToCollectionOptions

interface AddCardsToCollectionOptions {
  collection: StrongRef;
  cards: StrongRef[];
  viaCard?: StrongRef;
}

BatchCreateResult

interface BatchCreateResult {
  results: StrongRef[];
}

Provenance Tracking

The client supports provenance tracking through the optional viaCard parameter in createCard() and addCardToCollection(). When provided, this creates a provenance record that tracks which card led to the creation of a new card or the addition of a card to a collection.

This is useful for tracking how content spreads through the network - for example, if someone discovers a URL through another person's card and saves it themselves, or adds it to their own collection.

The provenance information is stored in the record's provenance.via field as a strong reference to the originating card.

License

MIT