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

@gospace-ai/floorplan

v2.14.0

Published

JavaScript SDK for embedding gospace floorplan

Readme

@gospace-ai/floorplan

A lightweight JavaScript/TypeScript SDK for embedding the gospace Floorplan (hosted at https://floorplan.gospace.app) inside your app.
It handles secure messaging to the hosted floorplan, passes configuration (location/layer/space selections), and emits events (e.g., when a user clicks a space).


Features

  • Framework‑agnostic — Works with Nuxt, Vue, React, Next, Svelte, or plain HTML/JS.
  • Hosted UI — Renders an interactive floorplan from https://floorplan.gospace.app.
  • Typed API — First‑class TypeScript types.
  • Secure messaging — Uses postMessage to exchange only the data the iframe needs.
  • Event API — Subscribe to floorplan events (e.g., SPACE_CLICKED).

Installation

npm (recommended)

npm install @gospace-ai/floorplan
# or
yarn add @gospace-ai/floorplan
pnpm add @gospace-ai/floorplan

CDN (UMD)

Use a public npm CDN such as jsDelivr or unpkg:

<!-- Latest (auto-updates to the newest version) -->
<script src="https://cdn.jsdelivr.net/npm/@gospace-ai/floorplan@latest/dist/floorplan.umd.js"></script>

<!-- Or pin a specific version -->
<script src="https://cdn.jsdelivr.net/npm/@gospace-ai/[email protected]/dist/floorplan.umd.js"></script>

<!-- unpkg alternative -->
<script src="https://unpkg.com/@gospace-ai/floorplan/dist/floorplan.umd.js"></script>

The UMD build exposes a global: gospaceFloorplan.FloorplanSDK.


Security & Tokens

  • The SDK requires a short‑lived access_token (not an API key).
  • Generate tokens server‑side (e.g., via the gospace API SDK/back end) and pass them to your frontend.
  • Do not embed API keys in client code or expose them to the browser.

Content Security Policy (CSP)

Allow the floorplan host to be framed by your app. You can add either an HTTP header or a meta tag:

HTTP header (recommended):

Content-Security-Policy: frame-ancestors 'self' https://floorplan.gospace.app;

Meta tag (fallback):

<meta
  http-equiv="Content-Security-Policy"
  content="frame-ancestors 'self' https://floorplan.gospace.app"
/>

Quick Start

1) Vanilla HTML/JS (UMD)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>gospace Floorplan – Demo</title>
    <meta
      http-equiv="Content-Security-Policy"
      content="frame-ancestors 'self' https://floorplan.gospace.app"
    />
    <style>
      /* Ensure your container has a height */
      #floorplan-container {
        width: 100%;
        height: 640px;
        max-width: 1200px;
        margin: 0 auto;
        border: 0;
      }
    </style>
  </head>
  <body>
    <div id="floorplan-container"></div>

    <!-- UMD build -->
    <script src="https://cdn.jsdelivr.net/npm/@gospace-ai/floorplan@latest/dist/floorplan.umd.js"></script>

    <script>
      // Obtain a short-lived access token from your server (not shown here)
      const ACCESS_TOKEN = "<your_token_from_server>";
      const { FloorplanSDK } = window['gospace AI'];

      const customLoader = `
        <div style="display: flex; justify-content: center; align-items: center; padding: 2rem; flex-direction: column;">
          <div style="display: flex; gap: 8px;">
            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #3498db; animation: bounce 1.4s infinite ease-in-out both; animation-delay: -0.32s;"></div>
            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #3498db; animation: bounce 1.4s infinite ease-in-out both; animation-delay: -0.16s;"></div>
            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #3498db; animation: bounce 1.4s infinite ease-in-out both;"></div>
          </div>
          <div style="margin-top: 1rem; color: #333; font-family: Arial, sans-serif;">Loading...</div>
        </div>
        <style>
          @keyframes bounce {
            0%, 80%, 100% { 
              transform: scale(0);
            }
            40% { 
              transform: scale(1);
            }
          }
        </style>
      `;

      const sdk = new FloorplanSDK({
        key: "floorplan-container",
        access_token: ACCESS_TOKEN,
        location_id: "location_123",
        events: ['click', 'hover'],
        entity_events: ['ROOM', 'SPACE'],
        custom_loader: customLoader,
        // Optional filters:
        // layer_id: "layer_abc",
        // zone_id: "zone_1234",
        // room_id: "room_5678",
        // spaces: ["space_1", "space_2"],
        // url: "https://floorplan.gospace.app", // default
        // class_name: "my-iframe",
        // title: "Office floorplan",
        // dark_mode: true
      });


      /**
       * if `events` is not provided
       */
      sdk.on("SPACE_CLICKED", ({ space_id }) => {
        console.log("Space clicked:", space_id);
      });
      
      sdk.on("FLOOR_PLAN_ENTITY", ({ event, id, metadata, center }) => {
        console.log("event type:", event);
        console.log("event entity id:", id);
        console.log("event entity type:", metadata.type);
        /**
         * If apply like SPACE, ROOM, etc
         * for instance AREA does NOT have center
         */
        console.log("event entity center:", center);
      });

      sdk.init();
    </script>
  </body>
</html>

2) TypeScript / ESM

import { FloorplanSDK } from "@gospace-ai/floorplan";

const ACCESS_TOKEN = "<your_token_from_server>";

const sdk = new FloorplanSDK({
  key: "floorplan-container", // id of a DOM element you control
  access_token: ACCESS_TOKEN, // short-lived token from your server
  location_id: "location_123",
  // Optional:
  // layer_id: "layer_abc",
  // zone_id: "zone_1234",
  // room_id: "room_5678",
  // spaces: ["space_1", "space_2"],
  // url: "https://floorplan.gospace.app",
  // class_name: "my-iframe",
  // title: "Office floorplan",
  // dark_mode: true
});

sdk.on("SPACE_CLICKED", ({ space_id }) => {
  // Handle the user clicking a specific space on the floorplan
  console.log("Space clicked:", space_id);
});

sdk.init();

CommonJS:

const { FloorplanSDK } = require("@gospace-ai/floorplan");

const sdk = new FloorplanSDK({
  /* ...options... */
});
sdk.on("SPACE_CLICKED", ({ space_id }) => console.log(space_id));
sdk.init();

3) React Example

import { useEffect, useRef } from "react";
import { FloorplanSDK } from "@gospace-ai/floorplan";

export default function FloorplanEmbed() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!ref.current) return;

    const sdk = new FloorplanSDK({
      key: "floorplan-container",
      access_token: "<token from your server>",
      location_id: "location_123",
    });

    sdk.on("SPACE_CLICKED", ({ space_id }) => {
      console.log("Space clicked:", space_id);
    });

    sdk.init();

    // If the SDK exposes a cleanup method in future, call it here.
    // return () => sdk.destroy?.();
  }, []);

  return (
    <div
      id="floorplan-container"
      ref={ref}
      style={{ width: "100%", height: 640 }}
    />
  );
}

4) Vue 3 Example

<template>
  <div id="floorplan-container" style="width: 100%; height: 640px;" />
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import { FloorplanSDK } from "@gospace-ai/floorplan";

onMounted(() => {
  const sdk = new FloorplanSDK({
    key: "floorplan-container",
    access_token: "<token from your server>",
    location_id: "location_123",
  });

  sdk.on("SPACE_CLICKED", ({ space_id }) => {
    console.log("Space clicked:", space_id);
  });

  sdk.init();
});
</script>

Configuration

| Property | Type | Description | Required | | -------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------| -------- | | url | string | Full iframe URL (default: https://floorplan.gospace.app) | No | | key | string | ID of the container element that will host the iframe | Yes | | access_token | string | Short‑lived access token for authentication (generate server‑side) | Yes | | location_id | string | Location ID for the floorplan | Yes | | layer_id | string | Optional layer ID | No | | zone_id | string | Optional zone ID, allows to highlight and zoom into the given zone 🚧 (beta) | No | | room_id | string | Optional room ID, allows to zoom into the given room 🚧 (beta) | No | | spaces | (string \| SpaceCustomization)[] | Optional array of space IDs or customization objects to highlight | No | | class_name | string | Optional CSS class for the iframe | No | | title | string | Optional accessibility title (applied to the iframe) | No | | dark_mode | boolean | Optional dark mode flag | No | | events | FloorPlanEvents[] | Optional allows to receive floorplan events for an entity, if not provides only SPACE_CLICKED will be received 🚧 (beta) | No | | entity_events| FloorPlanEntityType[] | Optional allows to receive floorplan events for provided entity (depends on existence of events) 🚧 (beta) | No | | custom_loader| string | Optional allows inject custom HTML loader | No | | zoom | string | Optional allows to auto zoom into painted spaces | No | | primary_color| string | Optional allows to provide line color (hex color) | No |

Note: The container element referenced by key must exist and have a visible height/width; otherwise, the iframe may appear collapsed.


Types

type SpaceCustomization = {
  id: string;           // Space identifier
  color?: string;       // Optional fill color (hex)
  opacity?: number;     // Optional opacity value (0-1)
  border?: {
    color: string;      // Border color (hex)
    lineWidth?: number; // Optional border width in pixels
  };
};

type FloorPlanEvents =
  | 'click'
  | 'right-click'
  | 'double-click'
  | 'hover'
  | 'blur'
  | 'plan-right-click'
  | 'outside-click'


/**
 * Can be used to place custom tooltips, context menus etc., values are relative to the iframe position and window position
 */
export type Center = {
  x: number;
  y: number;
  relativeX?: number;
  relativeY?: number;
};

/**
 * Floor Plan events (advanced)
 */
type FloorPlanEntityType = 'SPACE' | 'WALL_PERIMETER' | 'ROOM' | 'AREA';

interface FloorPlanEntity<T extends Record<string, any> = {}> {
  id: string;
  type: FloorPlanEntityType;
  center?: Center;
  properties?: T & { locationId: string; layerId: string };
}

/**
 * @important Metadata is on build progress to provide only useful information
 */
type SpaceMetadata = unknown;
type RoomMetadata = unknown;
type WallPerimeterMetadata = unknown;

type FloorPlanEntityMetadata = SpaceMetadata | RoomMetadata | WallPerimeterMetadata;

type FloorPlanEvent = {
  event: FloorPlanEvents;
  id: string; // This is entity event ID could be Space, Room etc
  metadata: FloorPlanEntity<FloorPlanEntityMetadata>
}

type SpaceClickedEvent = {
  space_id: string;
};

Events

The SDK emits events via sdk.on(event, handler).

Currently documented:

// Usage
sdk.on("SPACE_CLICKED", ({ space_id }: SpaceClickedEvent) => {
  console.log("Space clicked:", space_id);
});

// or

sdk.on('FLOOR_PLAN_ENTITY', (event: FloorPlanEvent) => {
  console.log('Event type:', event.type);
  console.log('Event entity id:', event.id);
  console.log('Event entity type:', event.metadata.type);
})

sdk

Additional events may be introduced over time. Check the SDK release notes/changelog for newly available events.


Styling & Layout Tips

  • The SDK injects an <iframe> into your container.

  • Give your container a fixed height (e.g., height: 640px) or make it responsive with CSS.

  • You can pass a custom CSS class via class_name, then style the iframe:

    .my-iframe {
      border-radius: 12px;
      border: none;
      width: 100%;
      height: 100%;
    }

Troubleshooting

  • Blank or blocked iframe Ensure your app’s CSP allows https://floorplan.gospace.app as a frame-ancestor.

  • 401/403 errors Verify the access_token is valid and not expired. Tokens must be created server‑side and scoped correctly.

  • No click events Confirm you’ve registered the event handler before calling sdk.init() (recommended), and that the floorplan data contains clickable spaces.

  • No iframe rendered Ensure the container exists (document.getElementById(key)) and has a non‑zero size.


Versioning

We recommend pinning a specific version when using a CDN to avoid unintentional breaking changes:

<script src="https://cdn.jsdelivr.net/npm/@gospace-ai/[email protected]/dist/floorplan.umd.js"></script>

License

gospace AI Floorplan SDK License Agreement

Copyright (c) 2025 gospace AI

The @gospace-ai/floorplan SDK is proprietary software provided by gospace AI. This software is licensed solely to pre‑registered paying clients who have an active subscription or agreement with gospace AI. Usage of this software is strictly limited to authorized clients who have obtained a valid access token from gospace AI.

Terms of Use

  1. Restricted Access — This SDK may only be used by pre‑registered paying clients with a valid subscription or agreement with gospace AI. Unauthorized use, distribution, or modification of this software is strictly prohibited.
  2. Access Token — A valid access token, provided by the gospace API, is required to use the SDK and access the floorplan iframe at https://floorplan.gospace.app.
  3. No Redistribution — You may not redistribute, sublicense, or share the SDK or its source code without explicit written permission from gospace AI.
  4. No Warranty — The SDK is provided “as is,” without warranty of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, or non‑infringement.
  5. Termination — gospace AI reserves the right to terminate access to the SDK for any client who violates this agreement or fails to maintain an active subscription.

To obtain a license or access token, contact gospace AI at [email protected] or visit:

All rights not expressly granted herein are reserved by gospace AI.