Skip to content

Commit

Permalink
chore: add jsdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
wazolab committed Jan 9, 2025
1 parent d8be9c3 commit 6577428
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 13 deletions.
55 changes: 45 additions & 10 deletions src/composables/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,54 @@ import type { Error } from '@/types'
import type { Reactive, Ref } from 'vue'
import { reactive, ref } from 'vue'

/**
* Interface representing the reactive state and methods for handling API interactions.
* Provides error handling, data fetching, and loading state management.
*/
interface ApiComposable {
/**
* A reactive error object that holds the current error state.
* When an error occurs during the API interaction, this object is updated.
* @example { message: 'Error message', type: 'error' }
*/
error: Reactive<Error>

/**
* Fetches data from the API. This function can accept query parameters via the `params` argument.
* @param params - Optional URLSearchParams object that can be used to append query parameters to the API request.
* @returns A Promise resolving to an `ApiResponse` or `undefined` if there was an issue.
*/
fetchData: (params?: URLSearchParams) => Promise<ApiResponse | undefined>

/**
* A reactive reference indicating whether the API request is currently loading.
* This state is useful for showing loading indicators while the request is in progress.
* @example `true` if loading, `false` if finished.
*/
loading: Ref<boolean>

/**
* Sets the error state.
* This function updates the `error` reactive state with the given error object.
* @param err - The error object to be set.
*/
setError: (err: Error) => void
}

/**
* Interface representing a link in the API metadata.
* A link typically points to a feature.
*/
export interface ApiLink {
id: string
before?: string
after?: string
}

/**
* Interface representing the API response.
* Extends `GeoJSON.FeatureCollection` to represent geographic data and includes additional metadata.
*/
export interface ApiResponse extends GeoJSON.FeatureCollection {
metadata: {
links: ApiLink[]
Expand All @@ -33,7 +68,7 @@ const API_BASE_URL_PROD = 'https://osm-logical-history-dev.teritorio.xyz'
/**
* Provides a composable for API configuration and interaction.
*
* @returns {ApiComposable} The API composable object with error state and fetch functionality.
* @returns The API composable object with error state and fetch functionality.
*/
export function useApiConfig(): ApiComposable {
const apiBaseUrl = import.meta.env.MODE === 'development'
Expand All @@ -51,8 +86,8 @@ export function useApiConfig(): ApiComposable {
/**
* Constructs the full API URL with optional query parameters.
*
* @param {URLSearchParams} [params] - Optional query parameters to append to the API endpoint.
* @returns {string} The constructed API URL.
* @param params - Optional query parameters to append to the API endpoint.
* @returns The constructed API URL.
*/
function buildApiUrl(params?: URLSearchParams): string {
const endpoint = '/api/0.1/overpass_logical_history'
Expand All @@ -62,8 +97,8 @@ export function useApiConfig(): ApiComposable {
/**
* Fetches data from the API and processes the response.
*
* @param {URLSearchParams} [params] - Optional query parameters to include in the API request.
* @returns {Promise<ApiResponse | undefined>} The API response with transformed features, or undefined if an error occurred.
* @param params - Optional query parameters to include in the API request.
* @returns The API response with transformed features, or undefined if an error occurred.
*/
async function fetchData(params?: URLSearchParams): Promise<ApiResponse | undefined> {
resetError()
Expand Down Expand Up @@ -98,8 +133,8 @@ export function useApiConfig(): ApiComposable {
/**
* Transforms the metadata of an API response by adding a unique `id` field to each link.
*
* @param {ApiResponse['metadata']} metadata - The metadata object containing links to be transformed.
* @returns {ApiResponse['metadata']} The transformed metadata with an `id` field added to each link.
* @param metadata - The metadata object containing links to be transformed.
* @returns The transformed metadata with an `id` field added to each link.
*/
function transformMetadata(metadata: ApiResponse['metadata']): ApiResponse['metadata'] {
return {
Expand All @@ -113,9 +148,9 @@ export function useApiConfig(): ApiComposable {
/**
* Transforms the features of the API response to include additional metadata.
*
* @param {ApiResponse} data - The API response containing features and metadata.
* @returns {Array<GeoJSON.Feature>} The transformed features with additional properties.
* @throws {Error} If a feature is missing a link in the metadata.
* @param data - The API response containing features and metadata.
* @returns The transformed features with additional properties.
* @throws If a feature is missing a link in the metadata.
*/
function transformFeatures(data: ApiResponse): Array<GeoJSON.Feature> {
return data.features.map((feature) => {
Expand Down
51 changes: 51 additions & 0 deletions src/composables/useLoCha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@ import type { ApiResponse } from '@/composables/useApi'
import type { ComputedRef, Ref } from 'vue'
import { computed, ref } from 'vue'

/**
* The possible statuses for features in the system.
* - 'create': New features.
* - 'delete': Deleted features.
* - 'update': Updated features.
*/
export type Status = 'create' | 'delete' | 'update'

/**
* The Color type defines colors based on feature status.
* - 'create' maps to '#52c41a'
* - 'delete' maps to '#FF0000'
* - 'update' maps to '#E6A23C'
*/
export type Color = {
[key in Status]: key extends 'create'
? '#52c41a'
Expand All @@ -12,16 +24,27 @@ export type Color = {
: '#E6A23C';
}

/**
* A predefined object that maps status types to corresponding color codes.
*/
export const loChaColors = {
create: '#52c41a',
delete: '#FF0000',
update: '#E6A23C',
} satisfies Color

/**
* Creates a mapping of status keys to themselves (i.e., 'create' -> 'create', 'delete' -> 'delete', etc.).
* This is useful for status-based filtering or logic.
*/
export const loChaStatus = Object.fromEntries(
['create', 'delete', 'update'].map(key => [key, key]),
) as Record<Status, Status>

/**
* The LoCha interface defines the structure of the LoCha state,
* which includes various references and computed values to track the features and metadata.
*/
export interface LoCha {
afterFeatures: Ref<GeoJSON.Feature[]>
beforeFeatures: Ref<GeoJSON.Feature[]>
Expand All @@ -31,15 +54,36 @@ export interface LoCha {
setLoCha: (loCha: ApiResponse) => void
}

// Internal state variables
const loCha = ref<ApiResponse>()
const afterFeatures = ref<GeoJSON.Feature[]>([])
const beforeFeatures = ref<GeoJSON.Feature[]>([])

/**
* The `useLoCha` composable provides reactive state and functions for managing and manipulating LoCha data.
* This includes tracking features, metadata, and updating state based on new data.
* @returns An object containing reactive references and functions for working with LoCha data.
*/
export function useLoCha(): LoCha {
/**
* A computed reference to count the number of features in the LoCha response.
* @returns The number of features in the LoCha response, or undefined if no data is available.
*/
const featureCount = computed(() => loCha.value?.features.length)

/**
* A computed reference to count the number of links in the LoCha metadata.
* @returns The number of links in the metadata, or undefined if no data is available.
*/
const linkCount = computed(() => loCha.value?.metadata.links.length)

/**
* Populates the `beforeFeatures` and `afterFeatures` arrays based on the properties of the features.
* - Features marked as 'is_before' are added to `beforeFeatures`.
* - Features marked as 'is_deleted' are also added to `beforeFeatures`.
* - Features marked as 'is_after' are added to `afterFeatures`.
* - Features marked as 'is_created' are added to `afterFeatures`.
*/
function populateBeforeAfterFeatures(): void {
if (!featureCount.value)
return
Expand All @@ -59,12 +103,19 @@ export function useLoCha(): LoCha {
})
}

/**
* Sets the LoCha data and populates the before and after features.
* @param data - The LoCha API response data to set.
*/
function setLoCha(data: ApiResponse): void {
resetLoCha()
loCha.value = data
populateBeforeAfterFeatures()
}

/**
* Resets the LoCha state by clearing the LoCha data and resetting the feature arrays.
*/
function resetLoCha(): void {
loCha.value = undefined
afterFeatures.value = []
Expand Down
49 changes: 46 additions & 3 deletions src/composables/useMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,51 @@ export interface MapEmits {
(e: 'update-bbox', bbox: string): void
}

/**
* The ID used for the map data source.
* @constant {string} SOURCE_ID
*/
const SOURCE_ID = 'lochas'

/**
* The URL of the map style used by MapLibre.
* @constant {string} MAP_STYLE_URL
*/
const MAP_STYLE_URL = 'https://vecto-dev.teritorio.xyz/styles/positron/style.json?key=teritorio-demo-1-eTuhasohVahquais0giuth7i'

/**
* An object defining the layer types used in the map. Each layer corresponds to a specific feature type
* in the map's configuration (e.g., polygons, lines, or points).
* @constant {object} LAYERS
* @property {string} Polygon - The layer ID for rendering polygons.
* @property {string} Line - The layer ID for rendering lines.
* @property {string} Point - The layer ID for rendering points.
*/
const LAYERS = {
Polygon: 'feature-polygons',
Line: 'feature-lines',
Point: 'feature-points',
}

/**
* A variable that holds the `MapEmits` function, which is used to emit custom events in the map component.
* This is typically used to communicate state changes or errors back to the parent component.
* @type {MapEmits}
*/
let emit: MapEmits

/**
* A reactive reference to the `Map` object. This holds the MapLibre map instance that is used to interact
* with the map, add layers, and listen for map events.
* @constant {ShallowRef<Map>} map
*/
const map = shallowRef<Map>()

/**
* A reactive reference to the map data source of type `GeoJSONSource`. This holds the map's data source,
* which contains the geoJSON data that is visualized on the map.
* @constant {Ref<GeoJSONSource>}
*/
const source = ref<GeoJSONSource>()

/**
Expand Down Expand Up @@ -170,11 +205,15 @@ export function useMap(): IMap {
.addTo(map.value)
}

/**
* Configures the map layers for different geometry types (Polygon, LineString, Point).
* Each layer is styled based on feature properties.
*/
function _setupMapLayers(): void {
if (!map.value)
throw new Error('Call useMap.init() function first.')

// Polygon type
// Polygon layer configuration
map.value.addLayer({
id: LAYERS.Polygon,
type: 'fill',
Expand All @@ -195,7 +234,7 @@ export function useMap(): IMap {
filter: ['in', ['geometry-type'], ['literal', ['Polygon', 'MultiPolygon']]],
})

// LineString type
// LineString layer configuration
map.value.addLayer({
id: LAYERS.Line,
type: 'line',
Expand Down Expand Up @@ -226,7 +265,7 @@ export function useMap(): IMap {
filter: ['in', ['geometry-type'], ['literal', ['LineString', 'MultiLineString']]],
})

// Point type
// Point layer configuration
map.value.addLayer({
id: LAYERS.Point,
type: 'circle',
Expand All @@ -251,6 +290,10 @@ export function useMap(): IMap {
})
}

/**
* Updates the bounding box based on the map's current view.
* Emits the updated bounding box coordinates.
*/
function _updateBoundingBox(): void {
if (!map.value)
throw new Error('Call useMap.init() function first.')
Expand Down

0 comments on commit 6577428

Please sign in to comment.