Socket
Book a DemoInstallSign in
Socket

@lightningrodlabs/we-applet

Package Overview
Dependencies
Maintainers
0
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lightningrodlabs/we-applet

This package contains the interfaces and contracts that a Holochain app UI needs to implement in order to run as a Tool in a Weave Frame like [Moss](theweave.social#tryit).

0.17.2
latest
Source
npmnpm
Version published
Weekly downloads
7
-36.36%
Maintainers
0
Weekly downloads
 
Created
Source

@lightningrodlabs/we-applet

This package contains the interfaces and contracts that a Holochain app UI needs to implement in order to run as a Tool in a Weave Frame like Moss.

The differences between a Weave Tool and a normal Holochain App are:

  • A Weave Tool can make use of the profiles zome provided by the Frame instead of using its own profiles module
  • A Weave Tool can provide more than just the default "main" UI. It can additionally provide:
    • UI elements to display single "assets"
    • UI widgets/blocks of any kind
    • UI elements ("main" view or "blocks") that render information across all instances of that same Tool type
  • A Weave Tool can provide AppletServices for the Frame or other Applets to use, including:
    • search: Searching in the Tool that returns Holochain Resource Locators (HRLs) with context pointing to an asset
    • creatables: Assets that can be created on-the-fly by a user.
    • getAssetInfo(): A function that returns info for the asset associated to the WAL if it exists in the Tool and the method is implemented.
    • blockTypes: Types of UI widgets/blocks that this Tool can render if requested by the Frame.

Definition: An "Asset" is anything that a) can be identified with an HRL plus arbitrary context and b) has an associated "asset-view", i.e. it can be displayed by the applet if requested.

Implementing a most basic applet UI

import { WeaveClient, isWeContext } from '@lightningrodlabs/we-applet';

if (!isWeContext) {
  // do non-the Frame related rendering logic (launcher, kangaroo, electron, ...)
}

const weaveClient = await WeaveClient.connect();

if (
  (weaveClient.renderInfo.type !== "applet-view")
  || (weaveClient.renderInfo.view.type !== "main")
) throw new Error("This Tool only implements the applet main view.");

const appAgentClient = weaveClient.renderInfo.appletClient;
const profilesClient = weaveClient.renderInfo.profilesClient;

// Your normal rendering logic here...

Implementing an (almost) full-fletched Weave Tool

import { WeaveClient, AppletServices, WAL, AssetInfo } from '@lightningrodlabs/we-applet';

// First define your AppletServices that the Frame can call on your applet
// to do things like search your applet or get information
// about the available block views etc.
const appletServices: Appletservices = {
    // Types of attachment that this Tool offers for other Applets to attach
    creatables: {
        'post': {
            label: 'post',
            icon_src: 'data:image/png;base64,iVBORasdwsfvawe',
          }
        },
        'comment': {
            ...
        }

    },
    // Types of UI widgets/blocks that this Tool supports
    blockTypes: {
        'most_recent_posts': {
            label: 'most_recent_posts',
            icon_src: 'data:image/png;base64,KJNjknAKJkajsn',
            view: "applet-view",
        },
        'bookmarked_posts': {
            label: 'bookmarked_posts',
            icon_src: 'data:image/png;base64,LKlkJElkjJnlksja',
            view: "cross-applet-view",
        }
    },
    getAssetInfo: async (
        appletClient: AppClient,
        roleName: RoleName,
        integrityZomeName: ZomeName,
        entryType: string,
        wal: WAL,
    ): Promise<AssetInfo | undefined> => {
        // your logic here...
        // for example
        const post = appletClient.callZome({
            'get_post',
            ...
        });
        return {
            title: post.title,
            icon_src: 'data:image/png;base64,iVBORasdwsfvawe'
        };
    },
    search: async (appletClient: AppClient, appletHash: AppletHash, weaveServices: WeaveServices, searchFilter: string): Promise<Array<WAL>> => {
        // Your search logic here. For example
        let searchResults: Array<Record> = await appletClient.callZome({
            zome_name: 'search_posts',
            ...
        });
        const appInfo = await appletClient.appInfo();
        const dnaHash = (appInfo.cell_info.notebooks[0] as any)[
          CellType.Provisioned
        ].cell_id[0];

        return searchResults.map((record) => {
                hrl: [
                    dnaHash,
                    record.signed_action.hashed.hash
                ],
                context: {}
            }
        );
    },
}


// Now connect to the WeaveClient by passing your appletServices
const weaveClient = await WeaveClient.connect(appletServices);

// Then handle all the different types of views that you offer
switch (weaveClient.renderInfo.type) {
  case "applet-view":
    switch (weaveClient.renderInfo.view.type) {
      case "main":
        // here comes your rendering logic for the main view
      case "block":
        switch(weaveClient.renderInfo.view.block) {
          case "most_recent_posts":
            // your rendering logic to display this block type
          case "bookmarked_posts":
            // Your rendering logic to display this block type
          default:
             throw new Error("Unknown applet-view block type");
        }
      case "asset":
        switch (weaveClient.renderInfo.view.roleName) {
          case "forum":
            switch (weaveClient.renderInfo.view.integrityZomeName) {
              case "posts_integrity":
                switch (weaveClient.renderInfo.view.entryType) {
                  case "post":
                        // here comes your rendering logic for that specific entry type
                  default:
                    throw new Error("Unknown entry type");
                }
              default:
                throw new Error("Unknown integrity zome");
            }
          default:
            throw new Error("Unknown role name");
        }

      case "creatable":
        switch (weaveClient.renderInfo.view.creatableName) {
          case "post":
            // here comes your rendering logic to create this creatable type.
            // Once created, you need to call
            // weaveClient.renderInfo.view.resolve(${WAL of your created creatable here});
            // or if there's an error:
            // weaveClient.renderInfo.view.reject("Failed to create asset.");
            // or if the user cancelled the creation:
            // weaveClient.renderInfo.view.cancel();
        }

      default:
        throw new Error("Unknown applet-view type");
    }

  case "cross-applet-view":
    switch (this.weaveClient.renderInfo.view.type) {
      case "main":
        // here comes your rendering logic for the cross-applet main view
      case "block":
        //
      default:
        throw new Error("Unknown cross-applet-view render type.")

    `;
    }

  default:
    throw new Error("Unknown render view type");

}


Keywords

holochain

FAQs

Package last updated on 26 Aug 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.