Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@heroiclabs/nakama-js

heroiclabs5.1kApache-2.02.8.0TypeScript support: included

JavaScript client for Nakama server written in TypeScript.

app server, client library, game server, nakama, realtime, realtime chat

readme

Nakama JavaScript client

JavaScript client for Nakama server written in TypeScript. For browser and React Native projects.

Nakama is an open-source server designed to power modern games and apps. Features include user accounts, chat, social, matchmaker, realtime multiplayer, and much more.

This client implements the full API and socket options with the server. It's written in TypeScript with minimal dependencies to be compatible with all modern browsers and React Native.

Full documentation is online - https://heroiclabs.com/docs/nakama/client-libraries/javascript/

Getting Started

You'll need to setup the server and database before you can connect with the client. The simplest way is to use Docker but have a look at the server documentation for other options.

  1. Install and run the servers. Follow these instructions.

  2. Import the client into your project. It's available on NPM and can be also be added to a project with Bower or other package managers.

     npm install @heroiclabs/nakama-js

    You'll now see the code in the "node_modules" folder and package listed in your "package.json".

    Optionally, if you would like to use the Protocol Buffers wire format with your sockets, you can import the adapter found in this package:

     npm install @heroiclabs/nakama-js-protobuf
  3. Use the connection credentials to build a client object.

     import {Client} from "@heroiclabs/nakama-js";
    
     var useSSL = false; // Enable if server is run with an SSL certificate.
     var client = new Client("defaultkey", "127.0.0.1", "7350", useSSL);

Usage

The client object has many methods to execute various features in the server or open realtime socket connections with the server.

Authenticate

There's a variety of ways to authenticate with the server. Authentication can create a user if they don't already exist with those credentials. It's also easy to authenticate with a social profile from Google Play Games, Facebook, Game Center, etc.

var email = "super@heroes.com";
var password = "batsignal";
const session = await client.authenticateEmail(email, password);
console.info(session);

Sessions

When authenticated the server responds with an auth token (JWT) which contains useful properties and gets deserialized into a Session object.

console.info(session.token); // raw JWT token
console.info(session.refreshToken); // refresh token
console.info(session.userId);
console.info(session.username);
console.info("Session has expired?", session.isexpired(Date.now() / 1000));
const expiresat = session.expires_at;
console.warn("Session will expire at", new Date(expiresat * 1000).toISOString());

It is recommended to store the auth token from the session and check at startup if it has expired. If the token has expired you must reauthenticate. The expiry time of the token can be changed as a setting in the server.

// Assume we've stored the auth token in browser Web Storage.
const authtoken = window.localStorage.getItem("nkauthtoken");
const refreshtoken = window.localStorage.getItem("nkrefreshtoken");

let session = nakamajs.Session.restore(authtoken, refreshtoken);

// Check whether a session is close to expiry.

const unixTimeInFuture = Date.now() + 8.64e+7; // one day from now

if (session.isexpired(unixTimeInFuture / 1000)) {
    try
    {
        session = await client.sessionRefresh(session);
    }
    catch (e)
    {
        console.info("Session can no longer be refreshed. Must reauthenticate!");
    }
}

Requests

The client includes lots of builtin APIs for various features of the game server. These can be accessed with the methods which return Promise objects. It can also call custom logic as RPC functions on the server. These can also be executed with a socket object.

All requests are sent with a session object which authorizes the client.

const account = await client.getAccount(session);
console.info(account.user.id);
console.info(account.user.username);
console.info(account.wallet);

Socket

The client can create one or more sockets with the server. Each socket can have it's own event listeners registered for responses received from the server.

const secure = false; // Enable if server is run with an SSL certificate
const trace = false;
const socket = client.createSocket(secure, trace);
socket.ondisconnect = (evt) => {
    console.info("Disconnected", evt);
};

const session = await socket.connect(session);
// Socket is open.

If you are using the optional protocol buffer adapter, pass the adapter to the Socket object during construction:

import {WebSocketAdapterPb} from "@heroiclabs/nakama-js-protobuf"

const secure = false; // Enable if server is run with an SSL certificate
const trace = false;
const socket = client.createSocket(secure, trace, new WebSocketAdapterPb());

There's many messages for chat, realtime, status events, notifications, etc. which can be sent or received from the socket.

socket.onchannelmessage = (message) => {
    console.info("Message received from channel", message.channel_id);
    console.info("Received message", message);
};


// 1 = room, 2 = Direct Message, 3 = Group
const roomname = "mychannel";
const type: number = 1;
const persistence: boolean = false;
const hidden: boolean = false;

const channel = await socket.joinChat(roomname, type, persistence, hidden);

const message = { hello: "world" };
socket.writeChatMessage(channel.id, message);

Handling errors

For any errors in client requests, we return the original error objects from the Fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

In order to capture the Nakama server response associated with the error, when you wrap your client requests in a try...catch statement you can invoke await error.json() on the error object in the catch block:

try {
    const account = await client.getAccount(session);
    console.info(account.user.id);
    console.info(account.user.username);
    console.info(account.wallet);
} catch (error) {
    console.info("Inner Nakama error", await error.json());
}

Contribute

The development roadmap is managed as GitHub issues and pull requests are welcome. If you're interested in enhancing the code please open an issue to discuss the changes or drop in and discuss it in the community forum.

Source Builds

Ensure you are using Node v18>.

The codebase is multi-package monorepo written in TypeScript and can be built with esbuild. All dependencies are managed with NPM.

To build from source, first install all workspace dependencies from the repository root with npm install.

Then to build a specific workspace, pass the --workspace flag to your build command, for example:

npm run build --workspace=@heroiclabs/nakama-js

Run Tests

To run tests you will need to run the server and database. Most tests are written as integration tests which execute against the server. A quick approach we use with our test workflow is to use the Docker compose file described in the documentation.

Tests are run against each workspace bundle; if you have made source code changes, you should npm run build --workspace=<workspace> prior to running tests.

docker-compose -f ./docker-compose.yml up
npm run test --workspace=@heroiclabs/nakama-js-test

Protocol Buffer Web Socket Adapter

To update the generated Typescript required for using the protocol buffer adapter, cd into packages/nakama-js-protobuf and run the following:

npx protoc \
--plugin="./node_modules/.bin/protoc-gen-ts_proto" \
--proto_path=$GOPATH/src/github.com/heroiclabs/nakama-common \
--ts_proto_out=. \
--ts_proto_opt=snakeToCamel=false \
--ts_proto_opt=esModuleInterop=true \
$GOPATH/src/github.com/heroiclabs/nakama-common/rtapi/realtime.proto \
$GOPATH/src/github.com/heroiclabs/nakama-common/api/api.proto

Release Process

To release onto NPM if you have access to the "@heroiclabs" organization you can use NPM.

npm run build --workspace=<workspace> && npm publish --access=public --workspace=<workspace>

Generate Docs

API docs are generated with typedoc and deployed to GitHub pages.

To run typedoc:

npm install && npm run docs

License

This project is licensed under the Apache-2 License.

changelog

Change Log

All notable changes to this project are documented below.

The format is based on keep a changelog and this project uses semantic versioning.

Unreleased

[2.8.0]

Added

  • Nakama: Added ability to invoke listFriendsOfFriends on the client which returns a list of friends of the user's friends.
  • Nakama: Added a rank_count to LeaderboardRecordList.
  • Nakama: Added ability to invoke listSubscriptions on the client which lists all the user's validated subscriptions.
  • Nakama: Added ability to invoke getSubscription on the client which gets a subscription by product ID.
  • Nakama: Added ability to invoke deleteAccount on the client which deletes the user's account.
  • Nakama: Added ability to invoke validatePurchaseFacebookInstant on the client which validates a FB Instant IAP receipt.
  • Nakama: Added ability to invoke deleteTournamentRecord on the client which deletes a tournament record.
  • Nakama: Added ability to invoke validateSubscriptionApple and validateSubscriptionGoogle on the client which validates Apple and Google subscription receipts.
  • Nakama: Added cursor parameter to listTournamentRecordsAroundOwner and listLeaderboardRecordsAroundOwner.
  • Nakama: Added authoritative field to Tournament.
  • Nakama: Added ability to specify whether to persist purchases and subscriptions when validating their receipts.
  • Nakama: Added create_time and update_time to ApiStorageObjectAck.
  • Nakama: Added refund_time, update_time and user_id to ApiValidatedPurchase.

Changed

  • Nakama: Changed StreamId.descriptor to StreamId.subcontext.

[2.7.0]

Added

  • Satori: Added ability to schedule, update and delete outgoing messages for Live Events.
  • Satori: Added ability to add custom and default properties for a user at the point of authentication.
  • Satori: Add 'recompute' param to Satori's update-properties.
  • Satori: Added ability to delete identity.
  • Nakama: Added ability to create match by name.

Changed

  • Nakama: Improves how outgoing messages are logged in verbose mode.
  • Nakama: Updated signature for Authenticate Game Center.

Fixed

  • Nakama: Fixed typings distribution location for protobuf-js.
  • Nakama: Fixed how newer bundlers (such as those used by ViteJs) discover Nakama's type definitions.
  • Satori: Return live event ID when getting all live events.

[2.6.1]

Added

  • You can now pass a onheartbeattimeout to the socket which will be called directly when a heartbeat timeout occurs. It will also still call ondisconnect once the socket is closed (which can take a few seconds for some browsers).

Fixed

  • Fixed a NodeJS compatibility issue by no longer depending on XMLHttpRequest.

[2.6.0]

Added

  • The socket will now automatically heartbeat with the server from within nakama-js. If the server doesn't reply after a heartbeat timeout has elapsed, ondisconnect will be called. This should resolve issues with the socket detecting lack of internet connectivity in Chrome. You can configure the heartbeat tiemout with setHeartbeatTimeoutMs(ms : number) : void.

  • You can now pass a connectTimeoutMs to the socket connect call in order to set a connect timeout.

  • You can now pass a sendTimeoutMs to the socket constructor to detect timeouts for socket calls that expect a response.

The connect, send, and heartbeat timeouts are set to sensible default values.

Fixed

  • Fixed dispatching of onpartyclose.

[2.5.3]

Fixed

  • Nakama and Satori ESM module files now correctly end in the .mjs extension.

[2.5.1]

Added

  • Added Satori client package (satori-js)

Changed

  • Remove Yarn in favour of NPM and updates dependencies to support Node 18 LTS

[2.4.1]

Fixed

  • This release is a republish of 2.4.0 but with the cjs distribution provided.

[2.4.0]

Added

  • Added more details comments and documentation on objects and methods.

Changed

  • Changed data structure used to pass session variables to authentication methods. The old structure used was a Map<string, string>. We now use the Record<string, string> for serialization support.
  • Changed StreamData.stream_presence to StreamData.sender. This field should be populated correctly now.
  • Changed MatchData.presences to a singular MatchData.presence. This presence represents the sender. This field should be populated correctly now.
  • Match and party data payloads are now serialized as protobuf when using the protobuf adapter.
    • Because of this change, sendMatchState and sendPartyData can now receive bytes as input. If bytes are sent using the default text adapter, they are base64 encoded to a string.
      • These functions can no longer receive data payloads of type any. Any object previously passed in must be serialized to a string or bytes. This change is enforced at compile time.
    • Also due to this change, MatchData and PartyData have their data fields typed as a Uint8Array. This breaks backwards compatibility. Users who send a string as their match or party data will need to use a utility such as TextDecoder to deserialize the string. This change is enforced at compile time.

Fixed

  • Fixed an issue with our base64 dependency in React Native.

[2.3.0]

Fixed

  • Fixed 401 Unauthorized Responses from the server in response to rpcHttpKey.

Changed

  • Changed parameter list optionals and sequencing in rpcHttpKey.

    • The signature is now listed as follows: rpcHttpKey(httpKey: string, id: string, input?: object);
  • Renamed ApiOverrideOperator to ApiOperator.

  • Query params are now formatted with snake case rather than camel case internally by client.

[2.2.0]

Added

  • Added purchase validation for Apple, Google and Huawei.
  • Added an ApiOverrideOperator to leaderboard writes.
  • Added ability to logout of a session with sessionLogout.
  • Added realtime party support.
  • Added ability to import steam friends through importSteamFriends.

Changed

  • Removes the deprecated generalist socket.Send function for sending data. Use the other exported Socket methods such as socket.addMatchmaker for better type checking.
  • Changed the return type from socket.addMatchmaker to a MatchmakerTicket rather than a MatchmakerMatched.
  • Changed signature of authenticateSteam and linkSteam to allow for a sync option.
  • Upgraded ts-proto dependency and shipped type definitions with the protobuf adapter.
  • Sessions that are close to expiration will now be automatically refreshed. You can configure this behavior via the autoRefreshSession parameter in the Client constructor and the expiredTimespanMs expiration buffer value on the client.
  • Removed session parameter from rpcGet and renamed it to rpcHttpKey. This function should be used with an http key rather than a session.

Fixed

  • 401 Unauthorized errors while renewing sessions.

[2.1.7]

Fixed

  • Fixed cacheable cursor parsing in ChannelMessageList.

[2.1.6]

Added

  • Added a cachable cursor to ChannelMessageList.

[2.1.5]

Fixed

  • Fixed issue where rollup.js was not bundling in js-base64 library to UMD distribution.

[2.1.4]

Added

  • Added React Native integration example to packages/ folder. The example builds for iOS and Android.
  • More tests for group chat, social profile ids.

Fixed

  • Fixed base64 imports for React Native
  • Rollup not finding tslib due to Yarn workspace inconsistency.
  • Authenticate methods now properly accept "create" and "username" parameters for email, Gamecenter, device, and Steam methods.

Changed

  • Base64 library to base64-js (for Typescript support.)

[2.1.3]

Added

  • Added Webpack and Create React App integration examples to packages/ folder.

Changed

  • Canonical import examples no longer reference a single exported object.
  • Moved tests to their own workspace and upgraded Jest dependencies.

Fixed

  • Fixed browser imports by removing the browser IIFE distribution entry in package.json. The IIFE distribution is still available in the repository but is no longer chosen as an option by bundlers following conventional package.json load entries.

[2.1.2]

Fixed

  • Paths to distribution files in package.json

[2.1.1]

Added

  • Support for Session Vars.
  • Added interface for Session object.
  • Support for Tournaments.
  • Support for events.
  • Update to support features through Nakama 2.14.0
  • Implemented base64 encoder and decoder for unicode characters
  • Added support for protocol buffer payloads via Web Sockets.
  • Added support for Facebook Instant Game Authentication.
  • Added support for Apple authentication.

Changed

  • Simplified the way callback IDs are generated. (Thanks @dimon4eg).
  • Small improvements to TypeScript typings. (Thanks @Blaizer).
  • Updated minimum TypeScript language to 3.5 version. (Thanks @Blaizer).
  • Migrated test suite to Typescript
  • Migrated build system to esbuild
  • Update rollup.js which is still used for Cocos support.
  • Updated Yarn version to 2.0
  • Signatures for all Client.ts methods have been flattened to take primitives rather than composite objects.

Fixed

  • Typo fix in Match interface to use Presences.
  • Add missing MatchmakerUser typescript interface definition.
  • Authentication functions no longer check for session tokens.
  • Fix for Cocos Creator support that allows the setting of XmlHttpRequest.withCredentials to be bypassed if the property does not have a setter.
  • Internal type-checking for the generated client methods.

[2.0.1] - 2018-05-19

Added

  • Authenticate functions for Steam and Game Center.

Fixed

  • Usernames can be passed into account create with register.

[2.0.0] - 2018-05-14

Added

  • New browser headless test suite with Puppeteer.

Changed

  • All source code now written in TypeScript.
  • Rewrite client and socket model for Nakama 2.0.

[0.4.0] - 2018-02-02

Changed

  • Re-structure project for wider browser compatibility.
  • Use a polyfill for window.fetch support.

Fixed

  • Fix bug in MatchDataSendRequest message.

[0.3.0] - 2017-11-27

Added

  • Add support for Leaderboards.

[0.2.0] - 2017-11-24

Added

  • Matchmaking and multiplayer support.

Changed

  • Build system now bundles a Base64 codec.

Fixed

  • Use Base64 library to enhance React Native compatibility.

[0.1.0] - 2017-11-08

Added

  • Initial public release.