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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@seedprotocol/sdk

v0.1.114

Published

The SDK for Seed Protocol

Downloads

3,850

Readme

Seed Protocol SDK

The official SDK for Seed Protocol.

The SDK is a heavily opinionated ORM that saves its database (SQLite) and files (OPFS) within the user's browser. All user data is fetched from, or written to, the Ethereum Attestation Service (EAS) and Arweave (More attestation services and decentralized storage providers will be supported in the future).

With all the remote storage on decentralized, public infrastructure, there's no server component to manage or rely on.

The hope is that this local-first and distributed approach will make it easier for developers to build apps with Seed Protocol without ever custodying user data on their own infrastructure.

The SDK is currently used and developed by PermaPress, the first client for Seed Protocol. PermaPress is a product developed by JournoLabs (formerly JournoDAO).

Installing

yarn add @seedprotocol/sdk

Getting Started

The first thing to do when integrating Seed SDK is define your data model by placing a schema.ts file in the root of your project.

As an example, here's the actual data model for PermaPress:

import { ImageSrc, List, Model, Relation, Text } from '@/browser/schema'

@Model
class Image {
  @Text() storageTransactionId!: string
  @Text() uri!: string
  @Text() alt!: string
  @ImageSrc() src!: string
}

@Model
class Post {
  @Text() title!: string
  @Text() summary!: string
  @Relation('Image', 'ImageSrc') featureImage!: string
  @Text('ItemStorage', '/html', '.html') html!: string
  @Text('ItemStorage', '/json', '.json') json!: string
  @Text() storageTransactionId!: string
  @List('Identity') authors!: string[]
  @Text() importUrl!: string
}

@Model
class Identity {
  @Text() name!: string
  @Text() profile!: string
  @Text() displayName!: string
  @Relation('Image', 'ImageSrc') avatarImage!: string
  @Relation('Image', 'ImageSrc') coverImage!: string
}

@Model
class Link {
  @Text() url!: string
  @Text() text!: string
}

const models = {
  Identity,
  Image,
  Link,
  Post,
}

const endpoints = {
  filePaths: '/api/seed/migrations',
  files: '/app-files',
}

export { models, endpoints }

export default { models, endpoints }

This will create a database locally in the browser with all the tables and fields necessary to support your Models.

[!NOTE] The database is a SQLite file stored in OPFS. We recommend using the OPFS Explorer browser extension to see the files managed by the SDK.

Notice that we create relationships by defining a Property that takes its related Model as its type. For one-to-many relationships, we use the List type and pass in the Model type we want.

So creating a Post would look like this:

import { Post, Image, Identity } from './seed/models'
import html                      from './index.html'

const image = await Image.create({
  src: 'https://imgr.com/image.jpg',
})

const author = await Identity.create({
  name: 'Keith Axline',
  profile: 'Developer for Seed Protocol',
})

const authors = [
  author
]

const post = await Post.create({
  title: 'Some title',
  summary: 'My summary',
  featureImage: image,
  authors,
})

await post.publish()

// And later when we want to update the post
post.title = 'Something else'

await post.publish()

Usage

Item

Create

Files

Subscribe to events:

import { SeedFile } from '@seedprotocol/sdk'

const fileFromUrl = new SeedFile('https://example.com/file.txt')

fileFromUrl.subscribe(( event, status ) => {
  console.log(`Event: ${event}, Status: ${status}`)
})

await fileFromUrl.save()

Create files from various sources:

const fileFromPath = new SeedFile('path/to/file.txt')

const fileFromBlob = new SeedFile(new Blob([ 'Hello, World!' ]))

const fileFromBuffer = new SeedFile(Buffer.from('Hello, World!'))

const fileFromFile = new SeedFile(new File([ 'Hello, World!' ], 'file.txt'))

if ( fileFromPath.isSaved ) {
  console.log('File is saved to Arweave and EAS')
}

Use the SeedFileSystem

import { SeedFileSystem } from '@seedprotocol/sdk'

const fs = new SeedFileSystem()

fs.subscribe(( event, status ) => {
  console.log(`Event: ${event}, Status: ${status}`)
  if ( event === 'connection.success' && status === 'connected' ) {
    console.log('Connected to user\'s file system')
  }

  if ( event === 'connection.error' ) {
    console.error('Error connecting to user\'s file system', event.error)
  }
})

await fs.connect() // User prompted to connect browser wallet

const files = await fs.listFiles('/')

files.forEach(file => {
  console.log(file.name)
  console.log(file.size)
  console.log(file.seedPath) // Each wallet address has a virtual root directory with directories and file system paths
})

Images


import { SeedImage } from '@seedprotocol/sdk'

const imgFromUrl = new SeedImage('https://example.com/image.png')

const imgFromDataUrl = new SeedImage('data:image/png;base64,iVB....')

await imgFromUrl.save()

const imgBlob    = imgFromUrl.blob()
const imgBuffer  = imgFromUrl.buffer()
const imgDataUrl = imgFromUrl.dataUrl()
---
Title: Seed Protocol SDK
---
%%{
  init: {
    'theme': 'base',
    'themeVariables': {
      'primaryColor': '#e0f2fe',
      'primaryTextColor': '#0c4a6e',
      'primaryBorderColor': '#38bdf8',
      'lineColor': '#475569',
      'secondaryColor': '#d9f99d',
      'tertiaryColor': '#fff',
      'tertiaryBorderColor': '#7e22ce',
      'tertiaryTextColor': '#7e22ce',
      'clusterBkg': '#fff'
    }
  }
}%%
flowchart TD
    A{Developer}
    B{User}
    C{Seed Dev}
    N{SDK}
    Q[App Code]
    D[(sdk_config_db)]
    E[(app_db)]
    L[(seeds_db)]
    G[Schema/Migration files
    browser/db/seedSchema]
H[Schema/Migration files
.seed/app/schema]
R[Schema/Migration files
node/db/sdkSchema]

I[browser.seed.db.config.mjs]
J[sdk.db.config.mjs]
K[browser.app.db.config.mjs]

O[files.json
seed/endpoint/list]
P[Files
seed/endpoint/files]

S[$> seed init]
T[scripts/bin]

subgraph SDK Code
C--changes Seeds or Versions --> I
C-- changes Models or Properties --> J
J-- generates -->R
I-- generates --> G
subgraph Package Bundle
R
G
end
end



subgraph App Code
A-- adds Models and Properties --> K
subgraph SDK
D
H
end
A-- runs --> S
S-- calls --> T
T-- reads--> K
T-- generates --> D
T-- generates --> H
end

subgraph App Server
H-- served at endpoint --> O
H-- served at endpoint --> P
end



subgraph Browser
B-- adds data--> Q
subgraph App
Q-- calls SDK--> N
subgraph SDK
E-- notifies -->N
N<-- files . json --> O
N<-- files --> P
N-- updates -->E
N-- updates --> L

end
end
end

A[Versions From EAS] B[Seeds From EAS] C[List of Items] D[List of Properties] E{Property Machine} F{Item Machine} G{Items Machine}

sequenceDiagram
    Items Service ->>+ EAS: Seeds Request
    EAS -->>+ Items Service: Seed Attestations
    loop Each Seed Attestation
        Items Service ->>+ Items Service: Extract Seed Uid
    end
    Note over Items Service: Now we have SeedUid[]
    Items Service ->>+ EAS: Versions Request w/ SeedUid[]
    EAS -->>+ Items Service: Version Attestations
    loop Each SeedUid
        Items Service ->>+ Items Service: Sort Version Uids DESC
    end
    loop Each most recent Version for Seed
        Items Service ->>+ Item Service: Create Item
    end
    Note over Items Service: Now we have VersionUid[] for each SeedUid<br />sorted by `createdAt` DESC
    Item Service ->>+ EAS: Properties Request w/ VersionUid[]
    EAS -->>+ Item Service: Properties Attestations
    loop Each Property Attestation
        Item Service ->>+ Property Service: Create Property Service
    end
    Note over Item Service: Now has all Property Services<br />under this._services