AbstractOptionaloptions: DestinationConstructorOptionalcacheWhether this destination supports a real-time live data stream. Parks with WebSocket or database sync feeds set this to true. The collector checks this to decide whether to run a stream loop.
ReadonlyhttpDefault language for localized strings Can be overridden by subclasses or via {PREFIX}_LANGUAGE env var with
Timezone for this destination. Subclasses should override this with the park's local timezone. Used by virtual queue helpers to format dates in the park's timezone.
Protected_ProtectedInternal initialization hook for subclasses
Override this method to provide custom initialization logic.
Called once per instance by init().
Inject proxy settings into HTTP requests. Runs last (priority 999) so all auth/header injectors fire before the URL is rewritten to point at the proxy service.
Unwrap proxy responses (e.g., Scrapfly wraps responses in JSON). Runs first (priority -999) so downstream response handlers see the unwrapped response, not the proxy envelope.
Add a prefix to use when looking up config values from environment variables or config object. This allows multiple destinations to co-exist in the same environment without clashing on config keys.
Prefix to add to config lookups (e.g. 'UNIVERSAL' to check UNIVERSAL_
ProtectedbuildHelper to build boarding group queue data
Constructs a BOARDING_GROUP queue object with allocation information. Automatically formats dates in the destination's timezone.
Boarding group status (AVAILABLE, PAUSED, or CLOSED)
Optionaloptions: {Additional boarding group information
Boarding group queue object
State of boarding group availability
Current boarding group end number
Current boarding group start number
Estimated wait time in minutes
Next boarding group allocation time
ProtectedbuildBuild the list of entities for this destination
Subclasses should override this method to return their entities. The returned entities will automatically have their parkId and destinationId resolved based on the parent hierarchy.
List of entities (hierarchy will be resolved automatically)
ProtectedbuildBuild live data for all entities in this destination
Subclasses should override this method to return live data (wait times, operating status, showtimes, etc.) for their entities.
List of live data for entities
ProtectedbuildBuild a real-time stream of live data updates
Override this method in parks that have a WebSocket or database sync feed. The default implementation is an empty generator (returns immediately, never yields).
The connection to the live data source should be opened in _init(), not here. This method subscribes to the already-open connection and yields updates as they arrive.
Async generator yielding LiveData[] per update
ProtectedbuildHelper to build paid return time queue data
Constructs a PAID_RETURN_TIME queue object with pricing information. Automatically formats dates in the destination's timezone.
Queue state (AVAILABLE, TEMP_FULL, or FINISHED)
Start time of return window (Date or ISO string)
End time of return window (Date or ISO string)
Currency code (e.g., 'USD', 'EUR')
Price in cents (e.g., 1500 for $15.00)
Paid return time queue object
Price information for paid return time
End time of return window
Start time of return window
State of return time availability
ProtectedbuildHelper to build return time queue data
Constructs a RETURN_TIME queue object with proper formatting. Automatically formats dates in the destination's timezone.
Queue state (AVAILABLE, TEMP_FULL, or FINISHED)
Start time of return window (Date or ISO string)
End time of return window (Date or ISO string)
Return time queue object
End time of return window
Start time of return window
State of return time availability
ProtectedbuildBuild schedules for all entities in this destination
Subclasses should override this method to return operating hours, show times, and other schedule information for their entities.
List of schedules for entities
ProtectedcalculateCalculate return window based on current wait time
Common pattern for parks like Efteling where virtual queue window is calculated as: now + waitTime to now + waitTime + windowDuration
Wait time in minutes to add to base time
Optionaloptions: { baseTime?: Date; windowMinutes?: number }Optional configuration
Object with formatted start and end times
OptionalgetGet all entities (parks, attractions, dining, shows, hotels) for this destination
⚠️ DO NOT OVERRIDE THIS METHOD ⚠️
This method automatically calls init() before fetching entities, and calls resolveEntityHierarchy() on the returned entities to set parkId and destinationId based on parent relationships.
To provide entities, implement buildEntityList() instead.
List of entities with resolved hierarchy
Get live data for all entities in this destination
⚠️ DO NOT OVERRIDE THIS METHOD ⚠️
This method automatically calls init() before fetching live data. If you need to provide post-processing or validation of live data, consider using the transform pattern in buildLiveData() instead.
To provide live data, implement buildLiveData() instead.
List of live data for entities
ProtectedgetGet localized string value with fallback logic
Handles both simple strings and multi-language objects. For multi-language objects, uses intelligent fallback: tries exact match, then base language (en-gb -> en), then fallback language, then first available.
LocalisedString (string or multi-language object)
Optionallanguage: "en" | "en-gb" | "en-us" | "de" | "fr" | "es" | "it" | "nl" | "ja" | "ko" | "zh"Preferred language code (defaults to instance language config)
Fallback language if preferred unavailable (defaults to 'en')
Localized string value
// Simple string - returns as-is
this.getLocalizedString("Space Mountain") // => "Space Mountain"
// Multi-language object with exact match
this.getLocalizedString({ en: "Space Mountain", fr: "Space Mountain" }, "fr")
// => "Space Mountain"
// Multi-language with base language fallback
this.getLocalizedString({ en: "Space Mountain" }, "en-gb")
// => "Space Mountain" (falls back to 'en')
Get schedules for all entities in this destination
⚠️ DO NOT OVERRIDE THIS METHOD ⚠️
This method automatically calls init() before fetching schedules. If you need to provide post-processing or validation of schedules, consider using the transform pattern in buildSchedules() instead.
To provide schedules, implement buildSchedules() instead.
List of schedules for entities
ProtectedinitInitialize the destination
This method is called automatically before any data retrieval methods (getEntities, getLiveData, getSchedules). It runs only once per instance, even if called multiple times, thanks to @reusable({forever: true}).
Subclasses should override _init() instead of this method.
ProtectedmapMap array of source items to Entity objects
Helper method to reduce boilerplate when converting API responses to Entity objects. Provides declarative mapping configuration instead of manual object construction.
Note: This method does NOT set parkId automatically. Use resolveEntityHierarchy() after mapping all entities to correctly populate parkId and destinationId based on the parent chain.
const entities = this.mapEntities(apiRides, {
idField: 'Id',
nameField: 'MblDisplayName',
entityType: 'ATTRACTION',
parentIdField: 'VenueId',
locationFields: { lat: 'Latitude', lng: 'Longitude' },
destinationId: 'universalorlando',
timezone: 'America/New_York',
filter: (ride) => ride.IsActive === true,
});
ProtectedresolveResolve entity hierarchy relationships (parkId and destinationId)
Walks the parent chain for each entity to correctly set parkId and destinationId based on ancestor types. This handles edge cases like:
Rules:
Validation:
Array of entities to resolve
Same array with parkId and destinationId correctly set
Stream live data updates in real time
Returns an async generator that yields LiveData[] arrays as updates arrive from the upstream feed. Each yield contains only the item(s) that changed — a single-element array for per-document sources (e.g. Couchbase Lite), or a full snapshot for sources that send all data at once (e.g. WebSocket).
For parks without a live feed (hasLiveStream = false), the generator returns immediately without yielding.
The generator ends when the upstream connection closes. The caller is responsible for reconnecting by calling streamLiveData() again in a loop.
Optional cache key prefix for all cached methods. When set, this prefix is prepended to all cache keys, preventing cache collisions when multiple instances of the same base class exist (e.g., multiple parks using the same framework).
Can be set directly as a string property, or implement getCacheKeyPrefix() method for dynamic prefixes.