WakaPAC Integration
WakaSync integrates with WakaPAC as a plugin, delivering HTTP responses as messages through msgProc. This gives components a unified event-driven architecture for UI events, network events, and timers — all handled in the same dispatch table.
Plugin Registration
Register WakaSync with WakaPAC once, before creating any components. This gives every component automatic access to a scoped HTTP handle via this.http and automatic request cancellation when the component is destroyed.
<script src="wakapac.js"></script>
<script src="wakasync.js"></script>
<script>
wakaPAC.use(wakaSync);
</script>
The Basics
Once registered, every component has a this.http handle. Initiate requests with it; responses arrive in msgProc as messages. No promises, no try/catch — everything flows through the same dispatch table as clicks, keypresses, and timers.
wakaPAC('#app', {
user: null,
loading: false,
error: null,
init() {
this.loading = true;
this.http.get('/api/user');
},
msgProc(event) {
switch (event.message) {
case wakaPAC.MSG_HTTP_SUCCESS:
this.user = event.detail.data;
this.loading = false;
break;
case wakaPAC.MSG_HTTP_ERROR:
this.error = event.detail.error.message;
this.loading = false;
break;
case wakaPAC.MSG_HTTP_ABORT:
this.loading = false;
break;
}
}
});
Message Contract
The plugin delivers three message types to msgProc. Use event.wParam to correlate responses to requests when a component has multiple requests in flight.
| Message | wParam | lParam | detail |
|---|---|---|---|
MSG_HTTP_SUCCESS |
Request ID | 0 | { data, url, method, timing } |
MSG_HTTP_ERROR |
Request ID | HTTP status (or 0) | { error, url, method, status, code } |
MSG_HTTP_ABORT |
Request ID | 0 | { error, url, method } |
For HEAD requests and responses with status 204, 205, or 304, event.detail.data is undefined.
Error Handling via lParam
On MSG_HTTP_ERROR, event.lParam carries the HTTP status code (or 0 for network errors). This allows quick filtering without inspecting the detail object:
case wakaPAC.MSG_HTTP_ERROR:
switch (event.lParam) {
case 401:
window.location = '/login';
break;
case 404:
this.error = 'Not found';
break;
case 0:
this.error = 'Network error — check your connection';
break;
default:
this.error = event.detail.error.message;
break;
}
break;
Error Codes
The event.detail.code property on MSG_HTTP_ERROR provides more granular error classification:
HTTP_404,HTTP_500, etc. — HTTP status code errorsPARSE_ERROR— Failed to parse response bodyINTERCEPTOR_ERROR— Request or response interceptor failedINVALID_URL— Malformed URL provided
Cancellations — including timeouts, groupKey/latestOnly superseding, explicit this.http.cancel(), and component destruction — are all delivered as MSG_HTTP_ABORT. The cancellation reason is available via event.detail.error.code:
CANCEL_TIMEOUT— Request timed outCANCEL_CANCELLED— Manually cancelled or component destroyed- No code (raw AbortError) — Superseded by a newer request in the same group
Request Correlation
Every call to this.http.get(), this.http.post(), etc. returns a request ID. When the response arrives, event.wParam carries the same ID. This lets components distinguish which response belongs to which request:
init() {
this._ordersReq = this.http.get('/api/orders');
this._usersReq = this.http.get('/api/users');
},
msgProc(event) {
if (event.message === wakaPAC.MSG_HTTP_SUCCESS) {
if (event.wParam === this._ordersReq) {
this.orders = event.detail.data;
} else if (event.wParam === this._usersReq) {
this.users = event.detail.data;
}
}
}
HTTP Methods
The this.http handle provides convenience methods for all standard HTTP verbs. Each returns a request ID for correlation.
this.http.get('/api/users');
this.http.post('/api/users', { name: 'Alice' });
this.http.put('/api/users/123', { name: 'Alice Smith' });
this.http.patch('/api/users/123', { lastLogin: new Date().toISOString() });
this.http.delete('/api/users/123');
this.http.head('/api/users/123');
WakaSync sets Content-Type automatically based on the body type: objects are serialized as application/json, strings as text/plain, and Blob/ArrayBuffer as application/octet-stream. For FormData, Content-Type is left to the browser so it can set the correct multipart boundary.
Request Cancellation
Each component's requests are automatically grouped by its pacId. Call this.http.cancel() to cancel all in-flight requests for the component. Requests are also cancelled automatically when the component is destroyed.
For more granular control, pass an explicit groupKey to tag specific requests. When a new request is made with the same groupKey, all previous requests in that group are automatically cancelled:
watch: {
searchQuery(query) {
if (!query) {
this.results = [];
return;
}
// Previous requests with the same groupKey are
// cancelled automatically when a new one starts.
this.http.get('/api/search?q=' + encodeURIComponent(query), {
groupKey: 'search'
});
this.searching = true;
}
}
groupKey vs latestOnly
Both groupKey and latestOnly auto-cancel previous requests, but they work differently. Use groupKey when requests to different URLs should cancel each other — such as search queries where the URL changes with each keystroke. Use latestOnly when repeated requests hit the same URL and only the most recent response matters, such as polling or refreshing. If both are set, groupKey takes precedence.
// groupKey: cancels any previous request tagged 'search', regardless of URL
this.http.get('/api/search?q=' + query, { groupKey: 'search' });
// latestOnly: cancels previous requests to this exact URL
this.http.get('/api/dashboard/stats', { latestOnly: true });
Configuration
HTTP options are resolved in three layers, each overriding the previous:
- Global defaults — WakaSync's built-in configuration
- Component defaults — per-component options via the
httpkey in wakaPAC's third argument - Per-request options — passed directly to
this.http.get(),this.http.post(), etc.
Global Defaults
These apply to all requests unless overridden at the component or request level:
| Option | Default | Description |
|---|---|---|
timeout |
30000 | Request timeout in milliseconds (0 = no timeout) |
retries |
0 | Number of retry attempts on failure |
retryDelay |
1000 | Base delay between retries in milliseconds (scaled by backoff strategy) |
retryBackoff |
'exponential' | Backoff strategy: 'exponential' (with jitter), 'linear', or 'fixed' |
retryBackoffMax |
30000 | Maximum backoff delay in milliseconds (caps exponential/linear growth) |
headers |
{} | Default headers applied to all requests |
responseType |
'auto' | Response parsing: 'json', 'text', 'blob', 'response', 'auto' |
validateStatus |
response.ok | Function(response) that determines whether a response is treated as success or error. Default accepts 200–299. |
WakaSync retries requests that fail due to network errors, 5xx server errors, or 429 (rate limiting). It does not retry 4xx client errors (like 404, 403) since these indicate the request itself is wrong. Retries use exponential backoff with jitter by default, and respect Retry-After headers on 429 responses. Retries are aborted if the request is cancelled during the delay.
To change global defaults, configure the wakaSync instance before registering:
wakaSync.config.timeout = 10000;
wakaSync.config.retries = 2;
wakaPAC.use(wakaSync);
Component Defaults
Set per-component defaults via the http key in wakaPAC's options argument. These override global defaults for all requests made by that component:
wakaPAC('#quick-lookup', {
init() { this.http.get('/api/autocomplete?q=test'); },
msgProc(event) { /* ... */ }
}, { http: { timeout: 5000 } });
wakaPAC('#resilient-dashboard', {
init() { this.http.get('/api/metrics'); },
msgProc(event) { /* ... */ }
}, { http: { retries: 3, retryDelay: 2000 } });
Per-Request Options
Override any option on individual requests. These take highest precedence:
| Option | Description |
|---|---|
groupKey |
Group identifier for batch cancellation (defaults to component's pacId) |
latestOnly |
Auto-cancel previous requests to the same URL (ignored if groupKey is set) |
headers |
Request-specific headers (merged with defaults) |
timeout |
Override timeout for this request |
retries |
Override retry count for this request |
retryDelay |
Override base retry delay for this request |
retryBackoff |
Override backoff strategy for this request |
retryBackoffMax |
Override maximum backoff delay for this request |
shouldRetry |
Custom function(error, attempt, maxAttempts) to control retry logic |
responseType |
Override response parsing for this request |
validateStatus |
Override status validation for this request |
credentials, mode, cache, redirect, referrer, referrerPolicy, integrity, keepalive, priority |
Passed through directly to the underlying fetch() call |
// Long timeout for a large export
this.http.get('/api/export/full', { timeout: 60000 });
// Aggressive retries for an unreliable endpoint
this.http.get('/api/unstable', { retries: 3, retryDelay: 1000 });
// Include cookies for cross-origin request
this.http.get('/api/external', { credentials: 'include' });
Advanced Features
Response Type Control
By default, WakaSync auto-detects response type from the Content-Type header. Override this when you need specific handling:
this.http.get('/api/download', { responseType: 'blob' });
this.http.get('/api/page', { responseType: 'text' });
The parsed result arrives in event.detail.data, regardless of response type.
Timing Information
Successful responses include timing metadata in event.detail.timing:
case wakaPAC.MSG_HTTP_SUCCESS:
console.log('Request took', event.detail.timing.duration, 'ms');
// timing.startTime, timing.endTime also available
break;
Request and Response Interceptors
Interceptors transform requests before they're sent and responses after they're received. They apply globally to all requests made through the wakaSync instance. Each returns an unsubscribe function.
// Add auth token to every request
wakaSync.addRequestInterceptor(function(config) {
config.headers.set('Authorization', 'Bearer ' + getToken());
return config;
});
// Log all response timing
wakaSync.addResponseInterceptor(function(data, config, timing) {
console.log(config.method + ' ' + config.url + ' took ' + timing.duration + 'ms');
return data;
});
// Unsubscribe when no longer needed
const unsub = wakaSync.addRequestInterceptor(fn);
unsub();
Request interceptors may be async — useful for refreshing expired tokens before a request is sent. Interceptors should return the modified config or data. If nothing is returned (undefined), the original value is preserved. Returning any other value — including falsy values like 0, "", false, or null — will be used as the new value.
Request Headers
WakaSync adds X-WakaSync-Request: true and X-WakaSync-Version headers to every request, along with a default Accept: application/json, text/plain, */* header. User-provided headers override these defaults.
Best Practices
- Register once: Call
wakaPAC.use(wakaSync)once before creating components. - Use component defaults for shared behavior: Set
{ http: { retries: 3 } }on components that talk to unreliable endpoints rather than repeating options on every request. - Use groupKey for searches: Prevents race conditions — previous requests with the same groupKey are cancelled when a new one starts.
- Handle all three message types: Always account for
MSG_HTTP_SUCCESS,MSG_HTTP_ERROR, andMSG_HTTP_ABORTto keep loading states consistent. - Ignore aborts gracefully: Cancelled requests are expected during rapid typing or navigation — don't show error messages for
MSG_HTTP_ABORT. - Use lParam for HTTP status: Quick status checks via
event.lParamare cleaner than digging intoevent.detailfor common cases like 401 or 404. - No manual cleanup needed: The plugin automatically cancels in-flight requests when a component is destroyed.
- Request IDs are optional: Store the return value of
this.http.get()only when you need to distinguish between multiple concurrent requests.