@superapp_men/content-provider
v1.4.0
Published
Offline content provider for SuperApp partner applications via iframe/Capacitor
Maintainers
Readme
@superapp_men/content-provider
Bridge package for Bewize / SuperApp partner applications to request offline assets from the SuperApp host via postMessage.
Partner apps run inside an iframe managed by the SuperApp. This package provides typed clients for four categories of assets:
| Client | Function | What it returns |
|--------|----------|-----------------|
| ContentProviderClient | getContent() | The student's grade-specific content.json |
| MediaProviderClient | getMedia(path) / getMediaObjectUrl(path) | Downloaded audio / video / image files |
| BackgroundProviderClient | getBackground(name) | Shared SVG background images |
| RiveProviderClient | getRive(path) / getRiveBuffer(path) / getRiveUrl(path) | Rive animation files (.riv) |
Installation
npm install @superapp_men/content-providerContentProviderClient
Retrieves the pre-downloaded content.json for the authenticated student's grade.
import { ContentProviderClient } from "@superapp_men/content-provider";
const client = new ContentProviderClient({ partnerCode: "bewize" });
try {
const content = await client.getContent();
console.log(content); // parsed content.json object
} finally {
client.destroy();
}Config
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| partnerCode | string | required | Your partner code (e.g. "bewize") |
| timeout | number | 15000 | Request timeout in ms |
| debug | boolean | false | Enable console logs |
MediaProviderClient
Retrieves downloaded media files (audio, video, images) stored in the SuperApp's data directory at partner-apps/{partnerCode}/media/.
import { MediaProviderClient } from "@superapp_men/content-provider";
const media = new MediaProviderClient({ partnerCode: "bewize" });
// Option A — get base64 data + MIME type
const { data, mimeType, encoding } = await media.getMedia("consignes/00e5b2a4-98c8-409e-9b68-d8eb397d4c78.mp3");
// Option B — get a ready-to-use object URL (recommended for <audio> / <video> / <img>)
const { url, mimeType, revoke } = await media.getMediaObjectUrl("consignes/00e5b2a4-98c8-409e-9b68-d8eb397d4c78.mp3");
const audio = new Audio(url);
audio.play();
// Release the object URL when no longer needed
audio.addEventListener("ended", revoke);
media.destroy();mediaPath format
Pass the relative path exactly as listed in the manifest media.audio.files[] array:
"consignes/00e5b2a4-98c8-409e-9b68-d8eb397d4c78.mp3"
"questions/159903a1-803d-46ee-9f34-365010d378f3.mp3"The same function works for future video and image files — the MIME type is auto-detected from the extension.
Supported MIME types
| Extension | MIME type |
|-----------|-----------|
| .mp3 | audio/mpeg |
| .m4a | audio/mp4 |
| .ogg | audio/ogg |
| .wav | audio/wav |
| .mp4 | video/mp4 |
| .webm | video/webm |
| .png | image/png |
| .jpg / .jpeg | image/jpeg |
| .gif | image/gif |
| .webp | image/webp |
| .svg | image/svg+xml |
Config
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| partnerCode | string | required | Your partner code |
| timeout | number | 30000 | Request timeout in ms (files can be large) |
| debug | boolean | false | Enable console logs |
BackgroundProviderClient
Retrieves shared SVG background images hosted by the SuperApp. Returns a ready-to-use base64 data URL.
import { BackgroundProviderClient } from "@superapp_men/content-provider";
import type { BackgroundName } from "@superapp_men/content-provider";
const bg = new BackgroundProviderClient();
const { url } = await bg.getBackground("champs");
// Use as CSS background
element.style.backgroundImage = `url(${url})`;
// Or as <img> src
imgElement.src = url;
bg.destroy();Available backgrounds
| Name | Preview |
|------|---------|
| "champs" | Green countryside fields |
| "decor_souk" | Traditional souk decoration |
| "douar" | Rural village scene |
| "puis" | Well / water scene |
Config
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| timeout | number | 10000 | Request timeout in ms |
| debug | boolean | false | Enable console logs |
RiveProviderClient
Retrieves Rive animation files (.riv) stored in the partner app's bundle. The SuperApp reads the pre-downloaded file from partner-apps/{partnerCode}/rive/{rivPath} and returns its binary content as base64.
import { RiveProviderClient } from "@superapp_men/content-provider";
import { Rive, EventType } from "@rive-app/canvas";
const riveProvider = new RiveProviderClient({ partnerCode: "bewize" });
// Option A — ArrayBuffer (recommended, for Rive's `buffer` prop)
const buffer = await riveProvider.getRiveBuffer("animations/intro.riv");
const r = new Rive({ buffer, canvas, autoplay: true });
// Option B — temporary object URL (for Rive's `src` prop)
const { url, revoke } = await riveProvider.getRiveUrl("animations/intro.riv");
const r2 = new Rive({ src: url, canvas, autoplay: true });
r2.on(EventType.Load, revoke); // free memory after load
// Option C — raw base64 data
const { data, mimeType, encoding } = await riveProvider.getRive("animations/intro.riv");
riveProvider.destroy();rivPath format
Pass the relative path within the partner app's rive/ directory (as stored in the downloaded bundle):
"animations/intro.riv"
"characters/hero.riv"
"ui/button.riv"Config
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| partnerCode | string | required | Your partner code (e.g. "bewize") |
| timeout | number | 30000 | Request timeout in ms |
| debug | boolean | false | Enable console logs |
SuperApp host path
The SuperApp reads the file from:
partner-apps/{partnerCode}/rive/{rivPath}Make sure your bundle extraction puts .riv files under this path in the app's data directory.
SuperApp integration
If you are implementing the SuperApp host side, import from the /superapp subpath to get the handler types:
import {
ContentMessageType,
MediaMessageType,
BackgroundMessageType,
RiveMessageType,
} from "@superapp_men/content-provider/superapp";
import type {
ContentRequestMessage,
MediaRequestMessage,
BackgroundRequestMessage,
RiveRequestMessage,
} from "@superapp_men/content-provider/superapp";The SuperApp's IframeCommunicationHandler handles all four message types:
| Message type | Handler | Filesystem path |
|-------------|---------|-----------------|
| content:request | Reads content.json | partner-apps/{code}/content/current/content.json |
| media:request | Reads media file as base64 | partner-apps/{code}/media/{path} |
| background:request | Fetches SVG from static assets | /shared_backgrounds/{name}.svg |
| rive:request | Reads .riv file as base64 | partner-apps/{code}/rive/{path} |
Message protocol
All messages follow the same pattern:
Request (partner → SuperApp):
{
"type": "content:request",
"requestId": "1751234567890-abc123",
"payload": { "partnerCode": "bewize" },
"timestamp": 1751234567890
}Response (SuperApp → partner):
{
"type": "content:response",
"requestId": "1751234567890-abc123",
"statusCode": 200,
"body": { "content": { ... } },
"timestamp": 1751234567891
}Rive request (partner → SuperApp):
{
"type": "rive:request",
"requestId": "1751234567890-abc123",
"payload": { "partnerCode": "bewize", "rivPath": "animations/intro.riv" },
"timestamp": 1751234567890
}Rive response (SuperApp → partner):
{
"type": "rive:response",
"requestId": "1751234567890-abc123",
"statusCode": 200,
"body": { "data": "<base64>", "mimeType": "application/octet-stream", "encoding": "base64" },
"timestamp": 1751234567891
}Error responses use statusCode 400 / 404 / 500 and body: { "error": "...", "detail": "..." }.
License
MIT — SuperApp Team
