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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@linkworld_ai/sdk-browser

v0.8.0

Published

Browser-side bridge + lw-ui CSS framework for Linkworld partner-app bundles. 0.8.0: bridge.kv.list now clamps the platform's 1000-row cap client-side (no more 500'd routes), and the build emits inline source maps so devtools resolves stack traces without

Downloads

790

Readme

@linkworld_ai/sdk-browser

Browser-side bridge for partner-app bundles running inside the Linkworld tenant shell (Phase 3 M2b).

Why this exists

Your bundle JS runs in a sandboxed iframe on apps-cdn.linkworld.ai with connect-src 'none' — it cannot fetch the Linkworld API directly. The bridge wraps window.parent.postMessage so you can make tool calls as if you were on the server side.

The parent (tenant shell on app.linkworld.ai) does the actual HTTP request using the user's session cookie and forwards the result back. Origin and install are verified on the parent before the call ever leaves the user's browser.

Usage

import { LinkworldBridge, ToolCallError } from '@linkworld_ai/sdk-browser'

const bridge = new LinkworldBridge({
  onInit: (info) => {
    document.querySelector('#hello')!.textContent =
      `Hi user ${info.userIdPrefix} on tenant ${info.tenantIdPrefix}`
  },
  // M3.12 — context bridge: react to platform-shell state.
  onLanguageChange: (lang) => {
    // bridge.language is also exposed as a getter
    console.log('user is on', lang)
  },
  onRouteChange: (route) => {
    // dim the bundle when the user navigates away from the app
    document.body.dataset.parentRoute = route
  },
})

document.querySelector('#send')!.addEventListener('click', async () => {
  try {
    const result = await bridge.tools.call('email_send', {
      to: '[email protected]',
      subject: 'Hello from the bundle',
      body: 'This was sent via the bridge.',
    })
    console.log('sent', result)
  } catch (err) {
    if (err instanceof ToolCallError) {
      if (err.decision === 'scope_denied') {
        alert(`Missing scope: ${err.neededScopes?.join(', ')}`)
      } else {
        alert(err.message)
      }
    } else {
      throw err
    }
  }
})

// Tell the parent to set the iframe height to fit content.
bridge.resize(document.documentElement.scrollHeight)

// Update the URL bar (deep-link friendly).
bridge.navigate('/settings')

API

new LinkworldBridge(options?: BridgeOptions)

Wires the postMessage listener. One instance per page; constructing a second is allowed but unusual.

BridgeOptions:

  • parentOrigin?: string — defense-in-depth target origin for outbound posts. Default '*' (the parent's own origin gate is what enforces trust).
  • toolCallTimeoutMs?: number — default 30000.
  • onInit?: (info) => void — fires once when the parent posts the init event.
  • onThemeChange?: (theme) => void — fires whenever the parent shell's color tokens change (light/dark toggle, design refresh).
  • onLanguageChange?: (lang) => void — fires when the parent's BCP-47 language tag changes. (M3.12)
  • onRouteChange?: (route) => void — fires when the parent shell's pathname changes (NOT when the bundle's own route changes). (M3.12)
  • injectThemeStyle?: boolean — default true. Writes theme tokens as --lw-bg, --lw-surface, … on <html>.
  • injectLanguage?: boolean — default true. Writes the language tag to <html lang> so :lang(de) selectors and screen-reader pronunciation just work. (M3.12)

bridge.tools.call<T>(tool, args?) => Promise<T>

Mirrors the server-side ctx.tools.call(...). Resolves with the tool result; rejects with ToolCallError if the platform refused (scope check, install missing, etc.) or with Error on timeout / internal failure.

bridge.resize(height: number) => void

Asks the parent to set the iframe height. Useful for content-driven sizing.

bridge.navigate(path: string) => void

Asks the parent to update the URL bar to /apps/<slug>${path}. Internal routing inside the bundle is up to you; this just keeps the user's URL in sync.

bridge.init: BridgeInit | null

Last received init payload, or null if the parent hasn't sent one yet. BridgeInit carries appId, tenantIdPrefix (8-char display only — NOT for auth), userIdPrefix, theme, language (BCP-47 tag), and routeName (parent pathname).

bridge.theme: BridgeTheme | null

Latest theme snapshot. colorScheme is 'light' | 'dark'; the rest are CSS color strings (already painted as CSS custom properties on <html> unless injectThemeStyle: false).

bridge.language: string | null (M3.12)

Latest BCP-47 language tag from the parent shell, e.g. 'en', 'de-DE'. null until the parent has pushed one. Already written to document.documentElement.lang unless injectLanguage: false.

bridge.routeName: string | null (M3.12)

Parent shell's current pathname (NO scheme/host/query/hash). Useful for bundles that want to react to the user navigating away. NOT auth-scoped — any user reading this iframe sees their own pathname.

What you cannot do

  • Read the user's cookie or localStorage of the tenant shell — the iframe is cross-origin to app.linkworld.ai.
  • Make outbound fetch() calls from the bundle. CSP connect-src 'none' blocks them. Use bridge.tools.call(...).
  • Call tools your app didn't declare in manifest.tools. The platform rejects with decision='scope_denied'.