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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@enertrag/p2pconnect

v6.0.1

Published

Capacitor Peer to Peer connectivity plugin

Downloads

3

Readme

@enertrag/p2pconnect

This Capacitor plugin enables file exchange between two devices. They do not need to be connected to the Internet and do not need to be on the same network.

The plugin uses peer-to-peer technologies of the respective platforms. Devices with iOS use MultipeerConnectivity, devices with Android use Google Nearby.

The plugin does not allow data exchange between devices of different systems (iOS vs. Android).

Install

npm install @enertrag/p2pconnect
npx cap sync

Examples

Send

// use Capacitor Filesystem plugin to get file uri
const fileUri = await Filesystem.getUri({
  directory: Directory.Data,
  path: 'foo/bar/example.json',
});

// define ids
const serviceId = 'p2p-test';
const transferId = 'share.json';

// creating resource descriptor
const resource: ResourceDescriptor = {
  id: 'example.json', // we use the filename here
  uri: fileUri,
};

// call plugin: method will return after the resource was
// sent to client or the user cancelled the process.
const result = await P2pConnect.send({
  serviceId,
  transferId,
  resources: [resource],
});

Retrieve

// on completion a callback will be called
P2pConnect.addListener('transferComplete', async result => {
  // We only handle a single file here.
  // It is also valid to send multiple files.
  // They always arrive in the same order in
  // which they were sent.
  const resource = result.resources[0];

  // The resource uri is a random temp file.
  // Especially the file name differs from the sender!

  // We use the resource id as the filename
  const fileTargetPath = '/target/foobar/' + resource.id;

  // We move(!) the file to the final target,
  // for we are responsible for cleaning up the temp file.
  await Filesystem.rename({
    from: resource.uri,
    toDirectory: Directory.Data,
    to: fileTargetPath,
  });
});

// must be equal for sender and receiver,
// otherwise the devices can't see each other
const serviceId = 'p2p-test';

// the method returns immediatly,
// we must call stopReceive() to stop accepting connections.
const result = await P2pConnect.startReceive({
  serviceId,
});

Accepting transfer (receiver)

// register callback
P2pConnect.addListener('acceptTransfer', request => {
  const transferId: string = request.transferId;
  let result = false;

  if (transferId.startsWith('share.')) {
    // decide on the basis of the data provided
    // result = customCheck();

    result = true;
  }

  // The method must be executed within 30 seconds,
  // otherwise the process terminates.
  // The sender is blocked during this time.
  P2pConnect.acceptTransfer({
    transferId,
    accept: result,
  });
});

Sequence

The following flowchart describes the communication between sender and receiver.

sequenceDiagram
    actor Sender
    participant Plugin/Sender
    participant Plugin/Receiver
    actor Receiver
    Sender->>Plugin/Sender: send
    activate Sender

    activate Plugin/Sender
    Receiver->>Plugin/Receiver: start receive

    activate Receiver
    activate Plugin/Receiver
    Plugin/Sender-->>Plugin/Sender: browse
    Plugin/Receiver-->>Plugin/Receiver: advertise
    Plugin/Receiver-->>Receiver: ok
    deactivate Receiver

    Plugin/Sender-->>Plugin/Receiver: connect
    deactivate Plugin/Sender

    Plugin/Receiver-->>Plugin/Sender: accept
    activate Plugin/Sender

    Plugin/Sender->>Plugin/Receiver: check version
    deactivate Plugin/Sender
    Plugin/Receiver->>Plugin/Sender: accept version
    activate Plugin/Sender
    deactivate Plugin/Receiver

    Plugin/Sender->>Plugin/Receiver: check transfer id
    deactivate Plugin/Sender
    activate Plugin/Receiver

    Plugin/Receiver-->>Receiver: notify transfer id
    deactivate Plugin/Receiver
    activate Receiver
    Receiver->>Plugin/Receiver: accept transfer
    deactivate Receiver
    activate Plugin/Receiver

    Plugin/Receiver->>Plugin/Sender: accept transfer
    activate Plugin/Sender

    Plugin/Sender-->>Plugin/Receiver: transfer resource count
    Plugin/Sender-->>Plugin/Receiver: transfer ids (android only)
    deactivate Plugin/Receiver

    Plugin/Sender->>Plugin/Receiver: send resources
    activate Plugin/Receiver
    Plugin/Sender->>Plugin/Sender: send
    Plugin/Sender-->>Sender: done (iOS)
    activate Receiver
    Plugin/Receiver->>Receiver: transfer complete
    deactivate Plugin/Sender

    Plugin/Receiver-->>Plugin/Sender: ok (android)
    activate Plugin/Sender
    deactivate Plugin/Receiver
    Plugin/Sender-->>Sender: done (android)
    deactivate Plugin/Sender

    deactivate Sender
    Receiver-->>Receiver: move files
    deactivate Receiver

API

The methods of the peer-to-peer interface are described below.

isAvailable()

isAvailable() => Promise<{ available: boolean; }>

Indicates whether the Peer to Peer function is available on the device.

Returns: Promise<{ available: boolean; }>

Since: 1.0.0


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all native listeners for this plugin.

Since: 1.0.0


addListener(...)

addListener(eventName: 'acceptTransfer', listenerFunc: (request: AcceptTransferRequest) => void) => Promise<PluginListenerHandle>

The notification is triggered on the recipient's side when a new transfer is received that needs to be confirmed.

| Param | Type | | ------------------ | --------------------------------------------------------------------------------------------- | | eventName | "acceptTransfer" | | listenerFunc | (request: AcceptTransferRequest) => void |

Returns: Promise<PluginListenerHandle>


addListener(...)

addListener(eventName: 'transferComplete', listenerFunc: (result: TransferResult) => void) => Promise<PluginListenerHandle>

Notification is triggered on the recipient's side when a transfer is complete.

| Param | Type | | ------------------ | ------------------------------------------------------------------------------ | | eventName | "transferComplete" | | listenerFunc | (result: TransferResult) => void |

Returns: Promise<PluginListenerHandle>


send(...)

send(options: SendOptions) => Promise<{ success: boolean; error: SendError | null; }>

Starts a transfer on the sender's side.

| Param | Type | | ------------- | --------------------------------------------------- | | options | SendOptions |

Returns: Promise<{ success: boolean; error: SendError | null; }>


startReceive(...)

startReceive(options: ReceiveOptions) => Promise<{ success: boolean; }>

Activates the reception of a transfer on the recipient's side.

| Param | Type | | ------------- | --------------------------------------------------------- | | options | ReceiveOptions |

Returns: Promise<{ success: boolean; }>


stopReceive()

stopReceive() => Promise<{ success: boolean; }>

Cancels the reception on the receiver's side.

Returns: Promise<{ success: boolean; }>


acceptTransfer(...)

acceptTransfer(options: AcceptTransferOptions) => Promise<void>

Must be called in response to the 'acceptTransfer' notification and determines on the recipient's side whether the transfer should be accepted or rejected.

| Param | Type | | ------------- | ----------------------------------------------------------------------- | | options | AcceptTransferOptions |


Interfaces

PluginListenerHandle

| Prop | Type | | ------------ | ----------------------------------------- | | remove | () => Promise<void> |

AcceptTransferRequest

Describes a request to the recipient to confirm or decline acceptance of the transfer.

| Prop | Type | Description | | ---------------- | ------------------- | ------------------------------------------------------- | | transferId | string | The ID of the transfer whose status is to be confirmed. |

TransferResult

The result of a transmission process for the receiver.

| Prop | Type | Description | | ---------------- | --------------------------------- | -------------------------------------- | | transferId | string | The ID for the transfer process. | | resources | ResourceDescriptor[] | The list of the transferred resources. |

ResourceDescriptor

Describes a resource to be transferred.

| Prop | Type | Description | | --------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | string | An identifier for the resource. This will be the same for sender and receiver. | | uri | string | The resource URI. This must be an absolute URI. It will include a schema, depending of the target system. The path (especially the last part) will vary between sender and receiver. |

SendOptions

Defines the parameters of the sender to transfer files.

| Prop | Type | Description | | ---------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | serviceId | string | The identifier for the P2P process. Only devices that use the same identifier can be found. To remain compatible with iOS devices, the identifier must meet the following criteria: <ul> <li>Must be 1–15 characters long</li> <li>Can contain only ASCII lowercase letters, numbers, and hyphens</li> <li>Must contain at least one ASCII letter</li> <li>Must not begin or end with a hyphen</li> <li>Must not contain hyphens adjacent to other hyphens.</li> </ul> | | transferId | string | The ID for the transfer process. | | resources | ResourceDescriptor[] | The list of the resources to be transferred. |

ReceiveOptions

Defines the parameters for receiving a transfer.

| Prop | Type | Description | | --------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | serviceId | string | The identifier for the P2P process. Only devices that use the same identifier can be found. To remain compatible with iOS devices, the identifier must meet the following criteria: <ul> <li>Must be 1–15 characters long</li> <li>Can contain only ASCII lowercase letters, numbers, and hyphens</li> <li>Must contain at least one ASCII letter</li> <li>Must not begin or end with a hyphen</li> <li>Must not contain hyphens adjacent to other hyphens.</li> </ul> |

AcceptTransferOptions

Accepts or rejects a transfer.

| Prop | Type | Description | | ---------------- | -------------------- | --------------------------------------------------------------------------------------------- | | transferId | string | The ID for the transfer process. | | accept | boolean | <code>true<code> to accept the transfer, <code>fale</code> otherwise. |

Enums

SendError

| Members | Value | Description | | ------------------------- | ---------------------------------- | ---------------------------------------------------------- | | transferInterrupted | 'transferInterrupted' | The transfer was interrupted by either sender or receiver. | | versionMismatch | 'versionMismatch' | The plugin version differs between sender and receiver. | | transferDenied | 'transferDenied' | The recipient has refused to receive the transfer. | | cancelled | 'cancelled' | The sending process was cancelled. | | permissionDenied | 'permissionDenied' | The user has not granted the requested permissions. | | internalError | 'internalError' | An internal error occured. Something went terribly wrong. | | connectionFailed | 'connectionFailed' | The connection between the peers could not be established. |