Adapter implementation is a function that accepts requestName, arguments for individual request, and a callback function that should be executed whenever data for the request changes. Adapter implementation needs to be registered to widgets framework with
function onRequest(requestName, args, callback) {
// adapter implementation
}
SIR('registerAdapter', onRequest);
Register call needs to be made before adding widgets that will use the adapter on the page. If adapter implementation is loaded at a later time, the registration call can be made with a promise that will resolve to adapter implementation later.
const adapterPromise = new Promise((resolve, reject) => {
// resolve(onRequest) when loaded
});
SIR('registerAdapter', adapterPromise);
When request to adapter triggers a subscription and adapter will continue providing new data over time, adapter should return unsubscribe function that widgets will call when this particular subscription is no longer needed. Request for new subscription will happen before unsubscribe of old subscription, so that overlapping data can be safely reused between subscriptions.
Here's a minimum example of how adapter implementation could look like:
type Adapter = (requestName: string, args: Record<string, any>, callback: OnRequestCallback) => UnsubscribeFunction;
type Callback = (error: Error | undefined, data: Record<string, any>) => void;
type UnsubscribeFunction = (() => void) | undefined;
const onRequest: Adapter = function onRequest(requestName, args, callback) {
switch (requestName) {
case 'events': {
let timeout = 0;
const controller = new AbortController();
function iteration() {
fetch(`/api/${args.eventIds.join(',')}`, { signal: controller.signal })
.then((response) => response.json())
.then((data) => {
callback(undefined, data);
})
.catch((error) => {
if (!controller.signal.aborted) {
callback(error);
}
})
.then(() => {
if (!controller.signal.aborted) {
timeout = setTimeout(iteration, 3000);
}
});
}
iteration();
return function unsubscribe() {
clearTimeout(timeout);
controller.abort();
};
}
default:
callback(new Error('unknown request'));
}
};
SIR('registerAdapter', onRequest);