Skip to content
Alex Mercado edited this page Oct 16, 2024 · 15 revisions

Platform API (PAPI) is a set of TypeScript APIs that you can use in your extension.

Each workspace contains a set of functions and variables provided to extensions for communicating across the PAPI and performing various tasks.

You can call these workspaces in your extension like:

papi.<workspace_name>.<member_name>

Explore the automatically generated documentation of the PAPI on Github Pages or look at the PAPI's TypeScript type declaration file (papi.d.ts) for the latest details about the PAPI.

Services

The services are unified modules that make importing the tools of the PAPI easy. There are frontend, backend, and a shared service. An extension file should either use papi-frontend or papi-backend, but not both.

Shared Service

src/shared/services/papi.service.ts

Link to File in GitHub

This is a unified module for accessing API features in extensions. The classes, functions, and workspaces exported from this module are shared between the frontend and backend. That means you can access all of these through the frontend and backend services, and you should not access it directly. This service exports the following:

const papi = {
	//Classes
	EventEmitter: papiEventEmitter,

	//Functions
	fetch: internetService.fetch,

	//Services/Workspaces
	commands: commandService,
	utils: papiUtil,
	webViews: papiWebViewService,
	network: papiNetworkService,
	logger,
	internet: internetService,
	dataProviders: dataProviderService,
	dialogs: dialogService,
};

A few small functions and workspaces here are described below, and the rest of the functions and workspaces are described in following sections on this page.

fetch

provides a way to get anything from the Internet

logger

provides a general logging system. The items that you log appear in the Platform.Bible console and go to file.

Location of log file

  • macOS: ~/Library/Logs/{app name}/main.log
  • Linux: ~/.config/{app name}/logs/main.log
  • Windows: %USERPROFILE%\AppData\Roaming\ {app name}\logs\main.log

internet

Currently, this module only has fetch making it a longer way to get to fetch.

Frontend

src/renderer/services/papi-frontend.service.ts

Link to File in GitHub

This is a unified module for accessing PAPI features in the web view. This module exports all of the shared services as well as the PAPI React-related APIs like hooks. These two features are for use inside of React web views.

You can import the papi-frontend into your extension like:

import papi from "papi-frontend";

You can import papi-related React hooks via papi-frontend/react:

import { useData, useDataProvider, ... } from "papi-frontend/react";

Backend

/src/extension-host/services/papi-backend.service.ts

Link to File in GitHub

This is a unified module for accessing API features in the extension backend. This module exports all of the shared services as well as the storage service. The ExtensionStorageService provides extensions in the extension host the ability to read/write data based on the extension identity and current user. This service does not work in the renderer process.

You can import the papi-backend into your extension like:

import papi from "papi-backend";

Events

/src/shared/models/papi-event-emitter.model.ts

Link to File in GitHub

This file contains the interfaces, classes, and functions related to events and event emitters. The PapiEventEmitter is an event manager that accepts subscriptions to an event and runs the subscription callbacks when the event is emitted.

EventEmitter is a class that allows you to create events and subscribe to them. This class is local which means that it cannot cross or go between the four processes (main, renderer, extension-host, c#). There are no predefined events for extensions, they are unique to the design of your extension.

/src/shared/models/papi-event.model.ts

Link to File in GitHub

This file contains declarations for PapiEvent, PapiEventHandler, and PapiEventAsync.

/src/shared/models/papi-network-event-emitter.model.ts

Link to File in GitHub

This file contains the networked version of EventEmitter.

Commands

/src/shared/services/command.service.ts

Link to File in GitHub

The command service handles registering, sending, and receiving commands with the Platform.Bible backend in a unified format. The command service is exposed on the PAPI so that extensions can initialize their own commands and extensions can use commands from other extensions.

Commands allow you to register a command that tells you to do something and then you would emit an event saying you did that thing. Commands are one to one whereas events are one to many. Commands follow a request-response pattern. The examples below are from paranext-extension-template.

How to register a command:

papi.commands.registerCommand(
	"extensionTemplate.doStuff",
	(message: string) => {
		return `The template did stuff! ${message}`;
	}
);

How to send a command:

papi.commands.sendCommand(
	"extensionTemplate.doStuff",
	"Extension Template React Component"
);

sendCommand

This function sends a command to the backend.

export const sendCommand = async <CommandName extends CommandNames>(
	commandName: CommandName,
	...args: Parameters<CommandHandlers[CommandName]>
): Promise<Awaited<ReturnType<CommandHandlers[CommandName]>>> => {};
```

Parameter

Description
commandName Command name for command function
…args Arguments of command to send with function
Return Description
sendCommandUnsafe(commandName, …args) Function to call with arguments of command that sends the command and resolves with the result of the command.

registerCommand

This function registers a command on the PAPI to be handled here.

export const registerCommand: <CommandName extends CommandNames>(
   commandName: CommandName,
   handler: CommandHandlers[CommandName],
) => Promise<UnsubscriberAsync> = createSafeRegisterFn( ... );

Parameter

Description
commandName Command name for command function
handler Handler function to run when the command is invoked
Return Description
True If successfully registered
Error If unsuccessful

Dialogs

Link to File in GitHub

The dialog service (accessed via papi.dialogs) exposes methods with which an extension can prompt the user for responses with dialogs.

showDialog

showDialog<DialogTabType extends DialogTabTypes>(
    dialogType: DialogTabType,
    options?: DialogTypes[DialogTabType]['options'],
  ): Promise<DialogTypes[DialogTabType]['responseType'] | null>;

Parameter

Description
dialogType the type of dialog to show the user
options various options for configuring the dialog that shows
Return Description
DialogTypes[DialogTabType]['responseType'] Returns the user's response. The type is dependent on which dialog is used
null If the user cancels
Error If unsuccessful

selectProject

selectProject(options?: DialogOptions): Promise<string | null>;

Parameter

Description
options various options for configuring the dialog that shows
Return Description
string Returns the user's selected project id
null If the user cancels
Error If unsuccessful

Utils

/src/shared/utils/papi-util.ts

Link to File in GitHub

This file contains functions to handle subscribe and unsubscribe actions. These functions are exposed on the PAPI for use in your extension, and specifically cleanup in the activate function of the entry file.

Utility Functions

/src/shared/utils/util.ts

Link to File in GitHub

This file contains a mismatch of utility functions. Currently, the functions included are not expected to be of much use to extension developers.

Hooks

/src/renderer/hooks/papi-hooks/index.ts

Link to File in GitHub

React hooks let you use state and other React features without writing a class. There are built-in hooks that come with React or you may build your own. You can read more about React hooks in the React docs. The PAPI has exposed hooks for you to use in your React web views. You can import papi-related React hooks via papi-frontend/react:

import { useData, useDataProvider, ... } from "papi-frontend/react";

useDataProvider

Gets a data provider with specified provider name

useProjectDataProvider

Gets a project data provider with specified provider name

useData

Subscribes to run a callback on a data provider’s data with specified selector on any data type that data provider serves

useProjectData

Subscribes to run a callback on a project data provider’s project data with specified selector on any project data type that project data provider serves

useDialogCallback

Provides a callback to run to get a response from a dialog as well as states that indicate the dialog's response and whether the dialog is open.

Data Provider

src/shared/services/data-provider.service.ts

Link to File in GitHub

Data providers allow you to interact with PAPI data and hold resources to manage. It outlines what data you are sending, and what to expect back. The Data Provider service handles registering data providers and serving data around the PAPI. A data provider can provide multiple types of data, but they should be closely associated. Data is generally associated to a project, but it doesn’t have to be.

Data Provider model

/src/shared/models/data-provider.model.ts

Link to File in GitHub

Data Provider interface

src/shared/models/data-provider.interface.ts

Link to File in GitHub

Data Provider Engine model

/src/shared/models/data-provider-engine.model.ts

Link to File in GitHub

Network

shared/services/network.service.ts

Link to file in Github

The network service handles requests, responses, subscriptions, etc. to the backend. It serves as a connection between extensions. An example of this connection would be an extension using the c# process to access usfm data provider. The parts of this service that are exposed on the PAPI are included in papiNetworkService, and listed below.

onDidClientConnect

Event that emits with clientId when a client connects

onDidClientDisconnect

Event that emits with clientId when a client disconnects

createNetworkEventEmitter

Creates an event emitter that works properly over the network. Other connections receive this event when it is emitted.

getNetworkEvent

Gets the network event with the specified type. Creates the emitter if it does not exist.

Web View

Service

shared/services/web-view.service.ts

Link to file in GitHub

Handles registering web view providers and serving web views around the papi. The parts of this service that are exposed on the PAPI are included in PapiWebViewService, and listed below.

onDidAddWebView

Event that emits with webView info when a webView is added

getWebView

Creates a new web view or gets an existing one depending on if you request an existing one and if the web view provider decides to give that existing one to you.

initialize

This function sets up the WebViewService.

Provider Service

shared/services/web-view-provider.service.ts

Link to file in GitHub

Service that handles webview-related operations. The parts of this service that are exposed on the PAPI are included in PapiWebViewProviderService, and listed below.

register

Register a web view provider to serve webViews for a specified type of webViews