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

trimbledesktopclient

v2.0.10

Published

Trimble Desktop Web Client

Downloads

61

Readme

Trimble Desktop is a local service that allows communication between a local browser page and desktop product. It consists for a client that runs on the browser and a windows service that should exist/be installed in the local machine.

Npm package

Run "npm run package"

bundle.js

Requisites: have browsify installed: npm install -g browserify browserify -r ./index.js:tbonewebclient > bundle.js

Available npm targets

npm run "target"

test => run jest unit tests : be sure a service is launched
build => build the client
lint => fixes/checks codes for format. Run always before commit    
version => creates a new version. U need to append the version number: ex npm run version 1.2.3
bundle => creates a bundle.js with all client side libraries...
package => creates a npm package    

Run Jest Tests

To run tests against debug session in VS. Run the server in debug F5 Run tests in VS code

Run backend Unit tests

Use visual studio.

Service Ports

Tests will connect to port 44325, in Visual studio when pressing debug, before, set additonal command arguments on you debug to --urls=http://localhost:44325/ Alternatively you can run from command line in "dotnet run --urls=http://localhost:44325/" in the TeklaTBone folder

TeklaTBone Components

Backend Service

Asp.net core .net 6 + sqlite db (entity framework) + rest api Runs as admin in system account TrimbleDesktopConsole => .net full framework component to access windows 32 apis

TBone Client

Typescript: npm or bundle.js library that runs on users browser and communicate to service via rest api

The next examples show some of the components for the client and some examples how to use them

Service Manager

Singleton service, that is interacts with backed service. Following supported features are available

  1. Management of the service, download and check versions
  2. Install module - Creation of install jobs on the backed
  3. Discovery module - Checking what products are installed

In your app, initialization is required before accessing further functionality. Service manager is a sigleton to avoid multiple queries

Examples Initialization

Using Azure Blob Storage

<script>
 var tBoneWebClient = require('tbonewebclient');
 tBoneWebClient.ServiceManager.InitInstance(new tBoneWebClient.TBoneRestHelpers("http://localhost:5000/"), new tBoneWebClient.AzureBlobBackedRestHelpers())
</script>

Using Tekla Downloads

<script>
 var tBoneWebClient = require('tbonewebclient');
 tBoneWebClient.ServiceManager.InitInstance(new tBoneWebClient.TBoneRestHelpers("http://localhost:5000/"), ew TeklaDownloadsRestHelpers('https://download.dev.tekla.com/'))
</script>

Using TypeScript and npm packges - vue.js

<script lang="ts">
import { AzureBlobBackedRestHelpers, ServiceManager, TBoneRestHelpers } from 'tbonewebclient';
export default class App extends Vue {
    private tboneService : ServiceManager = ServiceManager.InitService(new TBoneRestHelpers('http://localhost:5000/'), new AzureBlobBackedRestHelpers())
}
</script>    

Example Monitor Service Status

Assumes Initialization is done

<script lang="ts">
import { AzureBlobBackedRestHelpers, ServiceManager, TBoneRestHelpers } from 'tbonewebclient';
export default class App extends Vue {
    private tboneService : ServiceManager = ServiceManager.InitService(new TBoneRestHelpers('http://localhost:5000/'), new AzureBlobBackedRestHelpers());
    private async created() {
        this.serviceManager.RegisterOnServiceHandler(async () => this.HandleServiceOnEvent());
        this.serviceManager.RegisterOffServiceHandler(async () => this.HandleServiceOffEvent());
    }
    private async HandleServiceOnEvent(){
      console.log("Service off");
    }    
    private async HandleServiceOffEvent(){
      console.log("Service on");
    }
}
</script> 

Examples Download Service/Check Service

Assumes Initialization is done

<script>
 var tBoneWebClient = require('tbonewebclient');
 console.log("Latest Version", tBoneWebClient.ServiceManager.Instance().LastVersion())
 console.log("Installed Version", tBoneWebClient.ServiceManager.Instance().CurrentInstalledVersion())
</script>

Product Manager

Helper class that allows management of installs/execution/discovery at higher level. Extendable, clients using the library can create new products by inheriting GenericProduct interface

Available features

  1. Discovery - searchs for a product in local machine
  2. Installation - installs a product
  3. Execution - Runs a product

At the moment the client ships with the following product definitions, TrimbleConnectDesktop, TeklaStructuresMsi and TeklaStructuresDailyMsi

Discovery

Discovery responsibility is from the product definition itself. This approachs allow more easily support different products that have different ways of install.

Example
<script lang="ts">
import { AzureBlobBackedRestHelpers, ServiceManager, TBoneRestHelpers } from 'tbonewebclient';
export default class App extends Vue {
    private TEKLADOWNLOADURLDEV = 'https://download.dev.tekla.com/';
    // creates manager
    private productManager: ProductManager = new ProductManager(new TeklaDownloadsRestHelpers(this.TEKLADOWNLOADURLDEV));
    // define a product
    private tcdProduct: GenericProduct = new TrimbleConnectDesktopMsi();
    private async created() {
        if (ServiceManager.Instance().IsLocalServiceRunning()) {
            await this.productManager.DiscoverProduct(this.tcdProduct);
            console.log("Last Version", this.tcdProduct.ProductLastVersion);
            console.log("Installed Version", this.tcdProduct.ProductInstalledVersion);
        }
    }
}
</script> 

Typically discovery for example means checking some registries on local machines. However registry might not be involved at all if the product itself doesnt have a registry to check.

Install Instructions and Install

The manager expects a certain set of install instructions to be sent to the ServiceManager, again the instructions should be defined by the product to allow more flexibily. Typical instructions for example involve run a installer.

Example
<script lang="ts">
import { AzureBlobBackedRestHelpers, ServiceManager, TBoneRestHelpers } from 'tbonewebclient';
export default class App extends Vue {
    private TEKLADOWNLOADURLDEV = 'https://download.dev.tekla.com/';
    // creates manager
    private productManager: ProductManager = new ProductManager(new TeklaDownloadsRestHelpers(this.TEKLADOWNLOADURLDEV));
    // define a product
    private tcdProduct: GenericProduct = new TrimbleConnectDesktopMsi();
    private async InstallJob() {
        if (ServiceManager.Instance().IsLocalServiceRunning()) {
            const installId = await this.productManager.InstallProduct(
                this.tcdProduct.ProductName,
                this.LatestVersion,
                async (_: any, job: InstallJob | undefined) => {
                    console.log("Job Completed Ok");
                },
                async (_: any, job: InstallJob | undefined) => {
                    console.log("Job Completed Failed");
                },
                false,
            );
        }
    }
}
</script> 

Product Start

Client use custom protocol, it requires the product the provide the app path. and the protocol will be created in the local machine. Should be possible to pass arguments to the product when execution

Example
<script lang="ts">
import { AzureBlobBackedRestHelpers, ServiceManager, TBoneRestHelpers } from 'tbonewebclient';
export default class App extends Vue {
    private TEKLADOWNLOADURLDEV = 'https://download.dev.tekla.com/';
    // creates manager
    private productManager: ProductManager = new ProductManager(new TeklaDownloadsRestHelpers(this.TEKLADOWNLOADURLDEV));
    // define a product
    private tcdProduct: GenericProduct = new TrimbleConnectDesktopMsi();
    private async StartApplication() {
        if (ServiceManager.Instance().IsLocalServiceRunning()) {
            await this.productManager.RunProduct(this.tcdProduct.ProductName);
        }
    }
}
</script> 

Products Definition

Clients can construct products based on GenericProduct.

export interface GenericProduct {
  DiscoverProduct(): Promise<void>;
  RunProduct(): Promise<void>;
  InstallInstructions(
    backendService: TBoneBackedRestHelpersI,
    versionToInstall: string,
    autoUpdate: boolean,
  ): Promise<InstallJob>;
  ProductState: ProductInstallState;
  ProductLastVersion: string;
  ProductInstalledVersion: string;
  ProductId: string;
  ProductName: string;
}

Discovery Examples

In the next example we use GetRegistryValues and GetAppPath to check if a version has registry settings and exist on disk.

It also figures out whats the version from the registry.

async DiscoverProduct(): Promise<void> {
    const handlers = new LocalMachineRegistryDiscoveryHandler();
    handlers.searchRegistries = [];
    handlers.searchRegistries.push(
      new RegistryKeyPair('SOFTWARE\\Trimble\\Trimble Connect\\Installer', 'InstallDir', ''),
    );
    handlers.searchRegistries.push(
      new RegistryKeyPair('SOFTWARE\\Trimble\\Trimble Connect\\Installer', 'ProductVersion', ''),
    );

    const registryKeysToCheck = (await ServiceManager.Instance().GetRegistryValues(handlers)) as LocalMachineRegistryDiscoveryHandler;

    if (registryKeysToCheck !== undefined && registryKeysToCheck.searchRegistries !== undefined) {
      if (registryKeysToCheck.searchRegistries[0].value !== '') {
        const folderSearchPath = new FolderDiscoveryHandler();
        folderSearchPath.pathsToSearch = [];
        folderSearchPath.pathsToSearch.push(registryKeysToCheck.searchRegistries[0].value! + '\\TrimbleConnect.exe');
        this.appPath = await ServiceManager.Instance().GetAppPath(folderSearchPath);
        if (this.appPath !== '') {
          this.productState = ProductInstallState.INSTALLED;
          this.productInstalledVersion = registryKeysToCheck.searchRegistries[1].value!;

          const elems = this.productInstalledVersion.split(".");
          if (elems.length === 4) { // 123.23.2.23
            // we support only sem version
            this.productInstalledVersion = elems[0] + "." + elems[1] + "." + elems[2];
          }
        } else {
          this.productState = ProductInstallState.INVALID;
        }
      } else {
        // check if installation is running
        const jobState = await ServiceManager.Instance().GetJobState(this.productName);
        if (jobState === InstallInstructionState.Processing) {
          this.productState = ProductInstallState.INSTALLING;
        } else {
          this.productState = ProductInstallState.NOTAVAILABLE;
        }
      }
    }
  }

Install Instructions Examples

In the next example we set the type of installer, how binaries are retrieved and additional command line argumets the installer will perform.

  async InstallInstructions(
    backendService: TBoneBackedRestHelpersI,
    versionToInstall: string,
    autoUpdateSet: boolean,
  ): Promise<InstallJob> {
    // define install instructions
    const installInstruction = new InstallJob(this.productName);
    installInstruction.downloadType = ProductDownloadType.Download;
    installInstruction.productType = ProductInstallType.Msi;
    installInstruction.versionToInstall = versionToInstall;
    installInstruction.installOrder = 0;
    installInstruction.installState = InstallInstructionState.Planned;
    installInstruction.automaticUpgradeSet = autoUpdateSet;
    installInstruction.additionalCommandLineArguments = '/s /debuglog"%LOGFOLDER%\\SetupLogExe.log" /v"/qnb REBOOT=ReallySuppress" /V"/lv %LOGFOLDER%\\SetupLogMis.log"';
    installInstruction.downloadLocation = await backendService.GetDownloadLinkForProduct(
      this.productName,
      versionToInstall,
      GetOsInfo(),
    );

    return installInstruction;
  }

Product bundles

Should be possible to define a set of product bundles. Each install job can have sub jobs or dependent jobs that are installed at given order provided by user.

TBone Service

Reseting Database

Remove all migrations, then

Drop-Database -Verbose Add-Migration Initial Update-Database