LiaDevelopers

Packages

Build your app in a desktop browser with mockLia(), a pretend Lia that answers every call with a test player. Change its answers, send events, and debug every message.

Outside the Lia app there's no frame bridge, so every call fails with not_in_lia. mockLia() puts a pretend Lia in its place: it answers every call the way Lia would, with a test player in test mode, so your whole app runs in a desktop browser or in tests.

#Turn it on

Call it before your first SDK call, and only outside Lia:

TypeScript
import { init, isLia, mockLia } from '@lia-labs/sdk';

if (!isLia()) mockLia();

const me = await init(); // { player: { name: 'tester' }, mode: 'test', ... }

With a framework package it's the same import, from that package. Keep it out of production builds with your bundler's dev flag if you like (if (import.meta.env.DEV && !isLia())).

#What it answers

CallThe mock answers
initA test player (tester), test mode, English, light, a sheet, notifications available
payA paid charge, ch_mock0001 and up
showAd and its shortcutsA watched video (ad_mock), or a shown interstitial
confirm, showPopupYes, and the first button
requestNotifications, inviteFriendAllowed, invited
submitScore, leaderboardKeeps your best score and ranks you first
StorageKept in memory for the page's life
biometricAvailable Face ID, authenticated
Everything elseWhat Lia answers when it works

#Change its answers

Pass init to change who and how, and onMethod to decide any answer yourself. Return a value to answer, throw { code } to fail, or call next() for the mock's own answer:

TypeScript
mockLia({
  init: { language: 'ar', rtl: true, theme: 'dark', startParam: 'room-k3x9' },
  latency: 300, // ms before each answer, to see your loading states
  onMethod: (call, next) => {
    if (call.method === 'pay' && call.params.productId === 'gold-pack') throw { code: 'cancelled' };
    if (call.method === 'showAd') return { watched: false, shown: false, reason: 'no_ad' };
    return next();
  },
});

#Send events

The mock can send any of Lia's events, to try how your app reacts:

TypeScript
const mock = mockLia();
mock.event('theme', { colorScheme: 'dark', theme: { bg_color: '#09090B', text_color: '#F5F5F7' } });
mock.event('soundChanged', { on: false });
mock.event('startParam', { startParam: 'room-a81c' });
mock.event('mainButtonClicked');
mock.event('pause');

mock.calls lists every call your page made, and mock.restore() removes the mock.

#In tests

The same mock makes tests simple (here with Vitest and jsdom):

TypeScript
import { afterEach, expect, it } from 'vitest';
import { init, mainButton, mockLia, resetForTests, resetStateForTests } from '@lia-labs/sdk';

afterEach(() => {
  resetForTests();
  resetStateForTests();
});

it('shows Buy once the player is in', async () => {
  const mock = mockLia();
  await init();
  mainButton.setParams({ text: 'Buy', isVisible: true });
  await Promise.resolve();
  expect(mock.calls.at(-1)).toMatchObject({ method: 'bottomButton', params: { text: 'Buy', visible: true } });
  mock.restore();
});

#See every message

setDebug(true) logs every call, answer and event to the console, inside Lia too:

TypeScript
import { setDebug } from '@lia-labs/sdk';
setDebug(true);
// [lia] call pay { productId: 'extra-lives' }
// [lia] event pause undefined
// [lia] answer pay { id: 7, ok: true, result: { chargeId: 'ch_…', productId: 'extra-lives' } }

Pass a second argument to send them to your own logger, which helps inside Lia where there's no web inspector: setDebug(true, { log: send, warn: send, error: send }).

#Your server

The mock's session (lias_mock) isn't one Lia signed, so /session/verify says it isn't valid. Give your server a development path, or try server flows inside Lia as a tester. See Testing your app.

Type to search every page, method and endpoint.