-
Notifications
You must be signed in to change notification settings - Fork 1
PAPI
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.
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.
src/shared/services/papi.service.ts
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.
provides a way to get anything from the Internet
provides a general logging system. The items that you log appear in the Platform.Bible console and go to file.
- macOS: ~/Library/Logs/
{app name}
/main.log - Linux: ~/.config/
{app name}
/logs/main.log - Windows: %USERPROFILE%\AppData\Roaming\
{app name}
\logs\main.log
Currently, this module only has fetch
making it a longer way to get to fetch
.
src/renderer/services/papi-frontend.service.ts
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";
/src/extension-host/services/papi-backend.service.ts
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";
/src/shared/models/papi-event-emitter.model.ts
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
This file contains declarations for PapiEvent
, PapiEventHandler
, and PapiEventAsync
.
/src/shared/models/papi-network-event-emitter.model.ts
This file contains the networked version of EventEmitter
.
/src/shared/services/command.service.ts
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"
);
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. |
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 |
The dialog service (accessed via papi.dialogs
) exposes methods with which an extension can prompt the user for responses with dialogs.
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(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 |
/src/shared/utils/papi-util.ts
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.
/src/shared/utils/util.ts
This file contains a mismatch of utility functions. Currently, the functions included are not expected to be of much use to extension developers.
/src/renderer/hooks/papi-hooks/index.ts
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";
Gets a data provider with specified provider name
Gets a project data provider with specified provider name
Subscribes to run a callback on a data provider’s data with specified selector on any data type that data provider serves
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
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.
src/shared/services/data-provider.service.ts
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
Data Provider interface
src/shared/models/data-provider.interface.ts
Data Provider Engine model
/src/shared/models/data-provider-engine.model.ts
shared/services/network.service.ts
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.
Event that emits with clientId when a client connects
Event that emits with clientId when a client disconnects
Creates an event emitter that works properly over the network. Other connections receive this event when it is emitted.
Gets the network event with the specified type. Creates the emitter if it does not exist.
shared/services/web-view.service.ts
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.
Event that emits with webView info when a webView is added
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.
This function sets up the WebViewService
.
shared/services/web-view-provider.service.ts
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 a web view provider to serve webViews for a specified type of webViews
Note that code style and other such documentation is stored in the Paranext wiki and covers all Paranext repositories.