Skip to content

Commit

Permalink
Actually delivering proper typings for TS
Browse files Browse the repository at this point in the history
  • Loading branch information
ItalyPaleAle committed Oct 24, 2020
1 parent eacb377 commit 9613048
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 49 deletions.
105 changes: 58 additions & 47 deletions Router.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
///<reference types="svelte" />

import {SvelteComponent} from 'svelte'
import {Readable} from 'svelte/store'

/** Dictionary with route details passed to the pre-conditions functions, as well as the `routeLoading`, `routeLoaded` and `conditionsFailed` events */
/** Dictionary with route details passed to the pre-conditions functions, as well as the `routeLoading` and `conditionsFailed` events */
export interface RouteDetail {
/** Route matched as defined in the route definition (could be a string or a reguar expression object) */
route: string | RegExp
Expand All @@ -14,19 +16,22 @@ export interface RouteDetail {

/** Custom data passed by the user */
userData?: object
}

/** Svelte component (only in `routeLoaded` events) */
component?: SvelteComponent
/** Detail object for the `routeLoaded` event */
export interface RouteDetailLoaded extends RouteDetail {
/** Svelte component */
component: typeof SvelteComponent

/** Name of the Svelte component (only in `routeLoaded` events) */
name?: string
/** Name of the Svelte component that was loaded (note: might be minified in production) */
name: string
}

/**
* This is a Svelte component loaded asynchronously.
* It's meant to be used with the `import()` function, such as `() => import('Foo.svelte')}`
*/
export type AsyncSvelteComponent = () => Promise<SvelteComponent>
export type AsyncSvelteComponent = () => Promise<{default: typeof SvelteComponent}>

/**
* Route pre-condition function. This is a callback that receives a RouteDetail object as argument containing information on the route that we're trying to load.
Expand All @@ -37,12 +42,12 @@ export type AsyncSvelteComponent = () => Promise<SvelteComponent>
* @param detail Route detail object
* @returns If the callback returns a false-y value, it's interpreted as the precondition failed, so it aborts loading the component (and won't process other pre-condition callbacks)
*/
export type RoutePrecondition = (detail: RouteDetail) => (boolean|Promise<boolean>)
export type RoutePrecondition = (detail: RouteDetail) => (boolean | Promise<boolean>)

/** Object returned by the `wrap` method */
export interface WrappedComponent {
/** Component to load (this is always asynchronous) */
component: SvelteComponent
component: typeof SvelteComponent

/** Route pre-conditions to validate */
conditions?: RoutePrecondition[]
Expand All @@ -57,7 +62,7 @@ export interface WrappedComponent {
* Internal flag used by the router to identify wrapped routes
* @internal
*/
_sveltesparouter?: boolean
//_sveltesparouter?: boolean
}

/**
Expand All @@ -71,7 +76,7 @@ export interface WrappedComponent {
* @returns Wrapped component
*/
export function wrap(
component: SvelteComponent,
component: typeof SvelteComponent,
userData?: object,
...conditions: RoutePrecondition[]
): WrappedComponent
Expand Down Expand Up @@ -111,39 +116,7 @@ export function replace(location: string): Promise<void>
* @param node - The target node (automatically set by Svelte). Must be an anchor tag (`<a>`) with a href attribute starting in `/`
* @param hrefVar - A string to use in place of the link's href attribute. Using this allows for updating link's targets reactively.
*/
export function link(node: HTMLElement, hrefVar: string): void

/** List of routes */
export type RouteDefinition = {[key: string]: (SvelteComponent|WrappedComponent)} |
Map<string|RegExp, SvelteComponent|WrappedComponent>

/**
* Dictionary of all routes, in the format `'/path': component`.
*
* For example:
* ````js
* import HomeRoute from './routes/HomeRoute.svelte'
* import BooksRoute from './routes/BooksRoute.svelte'
* import NotFoundRoute from './routes/NotFoundRoute.svelte'
* routes = {
* '/': HomeRoute,
* '/books': BooksRoute,
* '*': NotFoundRoute
* }
* ````
*/
export let routes: RouteDefinition

/**
* Optional prefix for the routes in this router. This is useful for example in the case of nested routers.
*/
export let prefix: string | RegExp | undefined

/**
* If set to true, the router will restore scroll positions on back navigation
* and scroll to top on forward navigation.
*/
export let restoreScrollState: boolean | undefined
export function link(node: HTMLElement, hrefVar?: string): {update: (hrefVar?: string) => void}

/**
* @typedef {Object} Location
Expand Down Expand Up @@ -172,13 +145,51 @@ export const location: Readable<string>
/**
* Readable store that returns the current querystring
*/
export const querystring: Readable<string|undefined>
export const querystring: Readable<string | undefined>

/** List of routes */
export type RouteDefinition = Record<string, typeof SvelteComponent | WrappedComponent> |
Map<string | RegExp, typeof SvelteComponent | WrappedComponent>

/** Generic interface for events from the router */
interface RouterEvent<T> {
detail: T
}

/**
* Router component
*/
export default class Router extends SvelteComponent {
routes: RouteDefinition
prefix: string | RegExp | undefined
restoreScrollState: boolean | undefined
// Props
$$prop_def: {
/**
* Dictionary of all routes, in the format `'/path': component`.
*
* For example:
* ````js
* import HomeRoute from './routes/HomeRoute.svelte'
* import BooksRoute from './routes/BooksRoute.svelte'
* import NotFoundRoute from './routes/NotFoundRoute.svelte'
* routes = {
* '/': HomeRoute,
* '/books': BooksRoute,
* '*': NotFoundRoute
* }
* ````
*/
routes: RouteDefinition,
/**
* Optional prefix for the routes in this router. This is useful for example in the case of nested routers.
*/
prefix?: string | RegExp,
/**
* If set to true, the router will restore scroll positions on back navigation
* and scroll to top on forward navigation.
*/
restoreScrollState?: boolean
}

$on(event: 'routeEvent', callback: (event: CustomEvent) => void): () => void
$on(event: 'routeLoading' | 'conditionsFailed', callback: (event: RouterEvent<RouteDetail>) => void): () => void
$on(event: 'routeLoaded', callback: (event: RouterEvent<RouteDetailLoaded>) => void): () => void
}
4 changes: 2 additions & 2 deletions wrap.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {AsyncSvelteComponent, RoutePrecondition, WrappedComponent} from './Route
/** Options object for the call to `wrap` */
interface WrapOptions {
/** Svelte component to load (this is incompatible with `asyncComponent`) */
component?: SvelteComponent
component?: typeof SvelteComponent

/** Function that returns a Promise that fulfills with a Svelte component (e.g. `{asyncComponent: () => import('Foo.svelte')}`) */
asyncComponent?: AsyncSvelteComponent

/** Svelte component to be displayed while the async route is loading (as a placeholder); when unset or false-y, no component is shown while component */
loadingComponent?: SvelteComponent
loadingComponent?: typeof SvelteComponent

/** Optional dictionary passed to the `loadingComponent` component as params (for an exported prop called `params`) */
loadingParams?: object
Expand Down

0 comments on commit 9613048

Please sign in to comment.