Documentation
Parcourir la documentation

DocumentationRéférence

Référence du SDK

@overcrow/sdk 1.0 est l’API de la logique d’un widget PlayerVox OverCrow : l’état, les données de l’hôte, les services, les minuteurs, le dessin, le menu d’options, les messages, les journaux et le formatage. Cette page liste tous les exports du paquet. La logique et Services et permissions expliquent comment s’en servir.

Le SDK est sur npm, et la commande ci-dessous l’ajoute à un projet. Un projet créé par overcrow-widget init le liste déjà : lancez-y npm install.

SH
npm install --save-dev --save-exact @overcrow/sdk@1.0.0
TSwidgets/clock/logic.ts
import {
  formatDate,
  formatTime,
  initState,
  onHost,
  option,
  t,
  timers,
  type DateOrder,
  type Timer,
} from "@overcrow/sdk";

Le SDK est assemblé dans le logic.js du widget à l’empaquetage et s’exécute dans la VM du widget ; le charger ailleurs lève une erreur. Les parties inutilisées sont retirées du script assemblé. C’est une commodité, pas une barrière de sécurité : PlayerVox OverCrow vérifie chaque appel, chaque paramètre et chaque valeur qui sort de la VM.

ExportNatureRésumé
SDK_VERSIONconstante"1.0.0".
RUNTIME_SURFACEconstante"0.1", la version de l’interface intégrée de la VM dont ce SDK a besoin.

État et vue

ExportNatureRésumé
stateconstanteL’objet d’état du widget. Modifiez-le ; après chaque tour, la VM réévalue la vue et n’envoie que les différences.
WidgetStateinterfaceType de state ; déclarez ses membres par augmentation de module. Les membres non déclarés sont unknown.
initState(initial)fonctionCopie initial dans state et renvoie state avec le type de initial. Appelez-la une seule fois, pendant le chargement du module.
registerView(table)fonctionEnregistre les expressions et les gestionnaires compilés de la vue. L’outil en ligne de commande génère cet appel : un widget ne l’écrit jamais.
ViewTabletypeLa table que prend registerView.
Expressiontype(state, scope) => value : une expression compilée de la vue.
Handlertype(state, scope, event) => void : un gestionnaire compilé de la vue.
NodeEvent<E>interface{ type, detail } d’un événement ; detail vaut EventDetailMap[E].
ScopeinterfaceLes noms à la portée d’une expression : entrées d’un for, propriétés d’un composant.
TStemplates/chart/logic.ts
declare module "@overcrow/sdk" {
  interface WidgetState {
    values: number[];
  }
}

const state = initState({ values: [50] as number[] });

Données de l’hôte

ExportNatureRésumé
hostconstanteObjet figé dont les membres donnent toujours les dernières valeurs envoyées par PlayerVox OverCrow.
HostDatainterfaceType de host : locale, messages, theme, region, scale (en millièmes), viewport, mode, visible, options, grants.
onHost(listener)fonctionAppelle listener avec les noms des membres de host que PlayerVox OverCrow vient d’envoyer (options après un changement dans le menu, visible quand le widget est affiché ou masqué, region…), avant la réévaluation de la vue. Renvoie { cancel() }.
HostKeytypeLe nom d’un membre de HostData.
HostListenertypeUn écouteur de onHost.
Viewportinterface{ width, height }, en pixels logiques.
hasGrant(capability)fonctionIndique si l’utilisateur a accordé une capability.
option(id, fallback)fonctionLa valeur enregistrée d’une ligne du menu d’options, ou fallback quand il n’y en a pas ou qu’elle est d’un autre type.
MenuValuetypeboolean | number | string.
Widened<T>typeLe type du résultat de option : une valeur de repli false donne boolean.
TSwidgets/clock/logic.ts
onHost((changed) => {
  if (changed.includes("options")) {
    const values = menuValues();
    const unitChanged = values.seconds !== state.seconds;
    Object.assign(state, values);
    if (unitChanged) {
      start();
    }
  }
  // A new UTC offset (time zone or summer time) shows at once.
  if (changed.includes("region")) {
    tick();
  }
});

Services

Chaque service répond par l’intermédiaire de PlayerVox OverCrow, qui vérifie à chaque appel sa permission ou sa capability, ses paramètres et l’action de l’utilisateur.

ExportNatureRésumé
storageespace de nomsget({ key }), set({ key, value }), remove({ key }), keys(). Permission storage.
httpespace de nomsfetch(url, { as, method?, body?, contentType? }). Permission network.
clipboardespace de nomswriteText({ text }), pendant une action de l’utilisateur. Permission clipboardWrite.
gameEventsespace de nomssubscribe(listener). Permission gameEvents.
sessionespace de nomssubscribe(listener). Capability session.read.
telemetryespace de nomssubscribe(listener). Capability telemetry.read.
fpsespace de nomssubscribe(listener). Capability fps.read.
mediaespace de nomssubscribe({ cover? }, listener) ; previous, playPause, next({ player? }) pendant une action de l’utilisateur.
stopwatchespace de nomssubscribe(listener) ; toggle(), reset() pendant une action de l’utilisateur.
notesespace de nomssubscribe(listener) ; create(), select({ note }), setItem({ note, item, checked }), delete({ note }) pendant une action de l’utilisateur.
playervoxespace de nomsscore.subscribe, rating.subscribe, reviews.subscribe, reviews.page({ page?, followedOnly? }).
journalespace de nomssubscribe(listener) ; page({ cursor? }) ; delete({ session }) pendant une action de l’utilisateur, après confirmation de celui-ci.
twitchespace de nomschat.subscribe(listener) ; chat.join({ channel }), chat.leave(), chat.favorite({ channel, favorite }) pendant une action de l’utilisateur.
call(service, params?)fonctionAppelle par son nom n’importe quel service qui répond une seule fois.
subscribe(service, params, listener)fonctionS’abonne par son nom à n’importe quel service d’abonnement.
ServiceErrorclasseLe rejet d’un appel en échec : code est un ServiceErrorCode.
Listener<T>type(update: SubscriptionUpdate<T>) => void.
SubscriptionUpdate<T>type{ ok: true, value, final } ou { ok: false, error, final: true }.
Subscriptioninterfacecancel() ; un nouvel appel ne fait rien.
ServiceParams<N>typeLes paramètres du service N.
ServiceResult<N>typeLe résultat, ou la mise à jour, du service N.
FetchOptions<A>interfaceLes options de http.fetch.
FetchResponse<A>type{ status, contentType, body }, ou { status, asset } pour as: "image".
BodyTypetype"json" | "text" | "bytes" | "image".
BodyTypesinterfaceLe corps décodé de chaque type de corps.
HttpMethodtypeLes méthodes des règles réseau.
HttpServicesinterfaceType de http.

L’écouteur vient toujours en dernier, et un service sans paramètres n’en prend aucun :

TSwidgets/fps/logic.ts
  fps.subscribe((update) => {
    Object.assign(state, reading(update));
  });
TSwidgets/media/logic.ts
  const current = media.subscribe({ cover: state.showCover }, (update) => {
    if (update.ok) {
      state.media = update.value;
      state.unavailable = false;
      return;
    }
    // The subscription ended: the host's source failed. Show it and ask
    // again later; hidden, the timer waits until the widget shows.
    if (subscription === current) {
      subscription = null;
      state.media = null;
      state.unavailable = true;
      retry = timers.after(RETRY_MS, subscribe);
    }
  });

http.fetch envoie un corps de type chaîne en text/plain et tout autre corps en JSON, sauf si contentType en dit autrement, et décode la réponse comme le demande as. Une réponse sans corps donne null, "" ou un ArrayBuffer vide.

Les types des autres espaces de noms sont générés à partir du schéma : ClipboardServices, FpsServices, GameEventsServices, JournalServices, MediaServices, NotesServices, PlayervoxServices, SessionServices, StopwatchServices, StorageServices, TelemetryServices et TwitchServices. Chaque service est décrit dans la référence des services.

Minuteurs

ExportNatureRésumé
timersespace de nomsafter(ms, callback), every(ms, callback), atEach(unit, callback).
Timerinterfacecancel() ; un nouvel appel ne fait rien.
  • 16 minuteurs au plus, jamais plus courts que 100 ms : un intervalle plus court est porté à cette valeur.
  • Aucun minuteur ne se déclenche tant que le widget est masqué. Un minuteur répétitif saute les déclenchements manqués ; un minuteur à usage unique arrivé à échéance pendant ce temps se déclenche une fois quand le widget réapparaît.
  • atEach("second" | "minute" | "hour" | "day", callback) appelle callback à chaque changement d’unité de l’heure locale de l’utilisateur, et une fois quand le widget réapparaît. Il se réveille aussi quand le décalage UTC de l’utilisateur change.
TSwidgets/media/logic.ts
      retry = timers.after(RETRY_MS, subscribe);

Dessin, menu, messages et journal

ExportNatureRésumé
draw(ref, commands)fonctionRemplace les commandes du canvas dont le ref est donné.
onMenu(handler)fonctionReçoit l’identifiant de chaque ligne action du menu d’options que l’utilisateur choisit.
t(key, params?)fonctionLe message de la langue active, où chaque {name} est remplacé par params.name ; la clé elle-même quand il n’y a pas de message.
MessageParamstypeRecord<string, string | number>.
logespace de nomsdebug, info, warn, error(text) : affichés par overcrow-widget dev, ignorés pour un widget installé.

Les commandes de dessin sont des tuples typés, listés dans Dessin.

TSdocs/content/examples/countdown/logic.ts
    dots.push(["circle", 6 + index * 14, 6, 4], ["fill", "var(--color-accent)"]);

Heure, dates et nombres

La VM n’a pas d’Intl, et son heure locale est UTC : Date ne donne jamais l’heure de l’utilisateur. Ces fonctions formatent à partir de host.region. Les nombres suivent le format de nombre de l’utilisateur (1,234.5, 1 234,5 ou 1.234,5), quelle que soit la langue de l’interface ; les dates sont numériques, dans l’ordre de date de l’utilisateur ; les heures s’affichent sur 24 heures. Chaque fonction accepte aussi ses valeurs régionales en options : elle peut ainsi tourner dans un test unitaire, hors de la VM.

ExportNatureRésumé
localTime(ms, offsetMinutes?)fonctionLes champs LocalTime d’un instant dans le décalage UTC de l’utilisateur, ou dans l’offsetMinutes d’un horodatage de service.
formatTime(ms, options?)fonction14:08, ou 14:08:42 avec seconds: true.
formatDate(ms, options?)fonction17/07/2026 (dmy), 07/17/2026 (mdy), 2026-07-17 (ymd).
formatNumber(value, options?)fonctionLes séparateurs du format de nombre de l’utilisateur ; minimumFractionDigits, maximumFractionDigits (3 par défaut), grouping.
formatDuration(ms, options?)fonction04:05, 1:02:03, 04:05.67 avec hundredths: true ; tronquée, comme l’affiche un chronomètre.
delayToNext(unit, nowMs, region?)fonctionLes millisecondes jusqu’au prochain changement d’unité de l’heure locale, jamais au-delà du prochain changement de décalage UTC.
LocalTimeinterfaceyear, month (1 à 12), day, weekday (0 pour dimanche), hour, minute, second, millisecond.
TimeUnittype"second" | "minute" | "hour" | "day".
TimeOptionsinterfaceoffsetMinutes.
DateOptionsinterfaceoffsetMinutes, order.
ClockOptionsinterfaceoffsetMinutes, seconds.
NumberOptionsinterfaceLes options de formatNumber.
DurationOptionsinterfacehours, hundredths, format.
TSwidgets/clock/logic.ts
export function clockDate(now: number, order: DateOrder): string {
  return formatDate(now, { order });
}

Les noms de mois et de jours de la semaine, l’affichage sur 12 heures et les règles de pluriel ne font pas partie de la version 1.0.

Types générés

Ces types sont générés à partir du schéma des widgets : ils correspondent donc toujours à ce que PlayerVox OverCrow accepte.

ExportRésumé
ServiceName, CallServiceName, SubscribeServiceName, GestureServiceNameLes noms de service : tous, ceux qui répondent une seule fois, les abonnements, et ceux qui demandent une action de l’utilisateur.
ServiceParamsMap, ServiceResultMapLes paramètres et le résultat de chaque service.
ServiceErrorCode, ServiceErrorPayloadLes codes d’erreur, et la valeur { code } qui en porte un.
Session, Telemetry, Fps, Stopwatch, Media, Notes, Note, NoteItem, CreatedNote, Score, Rating, RatingState, Review, ReviewsState, ReviewsPage, JournalState, JournalPage, JournalSession, TwitchChat, ChatMessage, ChatFragment, GameEvent, HttpResponseLes formes de résultat.
Permission, Capability, SensitiveCapability, CapabilityServices, PermissionServicesLes permissions et les capabilities du manifeste, et les services que chacune autorise.
Locale, Theme, Mode, Region, NumberFormat, DateOrderLes valeurs de host.
EventName, GestureEventName, EventDetailMap, NamedKeyLes événements de la vue, ceux qui sont des actions de l’utilisateur, leurs détails, et les touches nommées de keydown.
DrawCommand, DrawCommandName, ColorLes commandes et les couleurs du canvas.
TokenName, ColorToken, LengthToken, FontSizeToken, FontFamilyToken, TimeToken, ShadowTokenLes tokens du design system.
IconNameLes noms des icônes.
MenuRowType, HostFeatureLes types de ligne du menu d’options, et les sources de données de requires.
JsonValue, AssetHandle, ImageSourceToute valeur JSON ; un identifiant d’image donné par un service ; une image du paquet ou un tel identifiant.

Constantes de limites

Les limites que la logique d’un widget doit respecter sont exportées sous forme de constantes, pour que le code ne répète jamais un nombre : MAX_TIMERS, MIN_TIMER_INTERVAL_MS, MAX_SERVICE_CALLS_IN_FLIGHT, MAX_SUBSCRIPTIONS, MAX_STORAGE_KEYS, MAX_STORAGE_KEY_BYTES, MAX_STORAGE_VALUE_BYTES, STORAGE_QUOTA_BYTES, MAX_REQUEST_URL_BYTES, MAX_HTTP_REQUEST_BYTES, MAX_HTTP_RESPONSE_BYTES, MAX_HTTP_DECLARED_RESPONSE_BYTES, MAX_CLIPBOARD_BYTES, MAX_OBJECT_ID_BYTES, MAX_NOTES, MAX_NOTE_ITEMS, MAX_NOTE_TITLE_BYTES, MAX_NOTE_BODY_BYTES, MAX_NOTE_ITEM_BYTES, MAX_REVIEW_CHARS, MAX_CHAT_CHANNEL_BYTES, MAX_CHAT_MESSAGE_CHARS, MAX_CHAT_FRAGMENTS, MAX_CHAT_FAVORITES, MAX_DRAW_COMMANDS, MAX_DRAW_STATE_DEPTH, MAX_PATH_POINTS, MAX_PATCH_BYTES, MAX_SCENE_NODES, MAX_CHILDREN, MAX_NODE_TEXT_BYTES, MAX_ATTRIBUTE_TEXT_BYTES, MAX_LABEL_BYTES, MAX_FIELD_TEXT_BYTES, MAX_LOCALE_ENTRIES, MAX_LOG_BYTES, VM_HEAP_BYTES, VM_MAX_HEAP_BYTES, VM_TURN_BUDGET_MS, VM_JOBS_PER_TURN et VM_MESSAGES_PER_TURN.

Tests unitaires : @overcrow/sdk/testing

Un second point d’entrée, jamais assemblé dans un widget, remplace PlayerVox OverCrow dans un test unitaire de la logique : installRuntime() fournit un temps virtuel, fait aboutir les appels de service et pousse les valeurs des abonnements. Voir les tests unitaires.