Skip to content

Commit

Permalink
Completed type definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
ItalyPaleAle committed Oct 22, 2020
1 parent b462265 commit 1a2ce29
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 57 deletions.
190 changes: 183 additions & 7 deletions Router.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,184 @@
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 */
export interface RouteDetail {
route: string | RegExp;
location: string;
querystring: string;
userData?: {};
component?: {};
name?: string;
}
/** Route matched as defined in the route definition (could be a string or a reguar expression object) */
route: string | RegExp

/** Location path */
location: string

/** Querystring from the hash */
querystring: string

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

/** Svelte component (only in `routeLoaded` events) */
component?: SvelteComponent

/** Name of the Svelte component (only in `routeLoaded` events) */
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>

/**
* 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.
* The function must return a boolean indicating whether the route can be loaded. If the function returns `false`, the route is not loaded, and no other pre-condition function is executed.
*
* The pre-condition function can be asynchronous too, returning a boolean asynchronously.
*
* @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>)

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

/** Route pre-conditions to validate */
conditions?: RoutePrecondition[]

/** Optional dictionary of static props */
props?: object

/** Optional user data dictionary */
userData?: object

/**
* Internal flag used by the router to identify wrapped routes
* @internal
*/
_sveltesparouter?: boolean
}

/**
* Wraps a component to add route pre-conditions.
*
* @deprecated Use `wrap` from `svelte-spa-router/wrap` instead. This function will be removed in a later version.
*
* @param component Svelte component for the route
* @param userData Optional object that will be passed to each `conditionsFailed` event
* @param conditions Route pre-conditions to add, which will be executed in order
* @returns Wrapped component
*/
export function wrap(
component: SvelteComponent,
userData?: object,
...conditions: RoutePrecondition[]
): WrappedComponent

/**
* Navigates to a new page programmatically.
*
* @param location Path to navigate to (must start with `/` or '#/')
* @returns Promise that resolves after the page navigation has completed
*/
export function push(location: string): Promise<void>

/**
* Navigates back in history (equivalent to pressing the browser's back button).
*
* @returns Promise that resolves after the page navigation has completed
*/
export function pop(): Promise<void>

/**
* Replaces the current page but without modifying the history stack.
*
* @param location - Path to navigate to (must start with `/` or '#/')
* @returns Promise that resolves after the page navigation has completed
*/
export function replace(location: string): Promise<void>

/**
* Svelte Action that enables a link element (`<a>`) to use our history management.
*
* For example:
*
* ````html
* <a href="/books" use:link>View books</a>
* ````
*
* @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

/**
* @typedef {Object} Location
* @property {string} location - Location (page/view), for example `/book`
* @property {string} [querystring] - Querystring from the hash, as a string not parsed
*/
/** Full location from the hash: page and querystring */
interface Location {
/** Location (page/view), for example `/book` */
location: string

/** Querystring from the hash, as a string not parsed */
querystring?: string
}

/**
* Readable store that returns the current full location (incl. querystring)
*/
export const loc: Readable<Location>

/**
* Readable store that returns the current location
*/
export const location: Readable<string>

/**
* Readable store that returns the current querystring
*/
export const querystring: Readable<string|undefined>

/**
* Router component
*/
export default class Router extends SvelteComponent {
routes: RouteDefinition
prefix: string | RegExp | undefined
restoreScrollState: boolean | undefined
}
4 changes: 2 additions & 2 deletions Router.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {wrap as _wrap} from './wrap'
* @deprecated Use `wrap` from `svelte-spa-router/wrap` instead. This function will be removed in a later version.
*
* @param {SvelteComponent} component - Svelte component for the route
* @param {Object} [userData] - Optional object that will be passed to each `conditionsFailed` event
* @param {object} [userData] - Optional object that will be passed to each `conditionsFailed` event
* @param {...function(RouteDetail): boolean} conditions - Route pre-conditions to add, which will be executed in order
* @returns {WrappedComponent} Wrapped component
*/
Expand Down Expand Up @@ -345,7 +345,7 @@ class RouteItem {
* @property {string|RegExp} route - Route matched as defined in the route definition (could be a string or a reguar expression object)
* @property {string} location - Location path
* @property {string} querystring - Querystring from the hash
* @property {Object} [userData] - Custom data passed by the user
* @property {object} [userData] - Custom data passed by the user
* @property {SvelteComponent} [component] - Svelte component (only in `routeLoaded` events)
* @property {string} [name] - Name of the Svelte component (only in `routeLoaded` events)
*/
Expand Down
15 changes: 11 additions & 4 deletions active.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/** Options for the `active` action */
interface ActiveOptions {
path: string | RegExp;
className: string;
/** Path to match; if empty, will default to the link's target */
path?: string | RegExp

/** Name of the CSS class to add when the route is active; default is "active" */
className?: string
}

/**
* Svelte Action for automatically adding the "active" class to elements (links, or any other DOM element) when the current location matches a certain path.
*
* @param node - The target node (automatically set by Svelte)
* @param opts - Can be an object of type ActiveOptions, or a string (or regular expressions) representing ActiveOptions.path.
* @param opts - Can be an object of type `ActiveOptions`, or a string (or regular expressions) representing `ActiveOptions.path`.
* @returns Destroy function
*/
export declare function active(node: HTMLElement,opt?: ActiveOptions | string | RegExp): {destroy: () => void};
export declare function active(
node: HTMLElement,
opt?: ActiveOptions | string | RegExp
): {destroy: () => void}
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Router for SPAs using Svelte 3",
"main": "Router.svelte",
"svelte": "Router.svelte",
"types": "Router.d.ts",
"scripts": {
"build-test-app": "(cd test/app && npx rollup -c)",
"start-test-app": "npx serve -n -l 5000 test/app/dist",
Expand Down Expand Up @@ -44,8 +45,5 @@
"rollup-plugin-svelte": "^6.0.1",
"serve": "^11.3.2",
"svelte": "^3.25.1"
},
"peerDependencies": {
"svelte": "^3.5.0"
}
}
34 changes: 0 additions & 34 deletions warp.d.ts

This file was deleted.

40 changes: 40 additions & 0 deletions wrap.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {SvelteComponent} from 'svelte'
import {AsyncSvelteComponent, RoutePrecondition, WrappedComponent} from './Router'

/** Options object for the call to `wrap` */
interface WrapOptions {
/** Svelte component to load (this is incompatible with `asyncComponent`) */
component?: 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

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

/** Optional object that will be passed to events such as `routeLoading`, `routeLoaded`, `conditionsFailed` */
userData?: object

/** Optional key-value dictionary of static props that will be passed to the component. The props are expanded with {...props}, so the key in the dictionary becomes the name of the prop. */
props?: object

/** Route pre-conditions to add, which will be executed in order */
conditions?: RoutePrecondition[] | RoutePrecondition
}

/**
* Wraps a component to enable multiple capabilities:
*
* 1. Using dynamically-imported component, with (e.g. `{asyncComponent: () => import('Foo.svelte')}`), which also allows bundlers to do code-splitting.
* 2. Adding route pre-conditions (e.g. `{conditions: [...]}`)
* 3. Adding static props that are passed to the component
* 4. Adding custom userData, which is passed to route events (e.g. route loaded events) or to route pre-conditions (e.g. `{userData: {foo: 'bar}}`)
*
* @param args Arguments object
* @returns Wrapped component
*/
export function wrap(args: WrapOptions): WrappedComponent
export default wrap
19 changes: 12 additions & 7 deletions wrap.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
/**
* @typedef {Object} WrappedComponent
* @typedef {Object} WrappedComponent Object returned by the `wrap` method
* @property {SvelteComponent} component - Component to load (this is always asynchronous)
* @property {RoutePrecondition[]} [conditions] - Route pre-conditions to validate
* @property {Object} [props] - Optional dictionary of static props
* @property {Object} [userData] - Optional user data dictionary
* @property {bool} _sveltesparouter - Internal flag; always set to true
*/

/**
* @callback AsyncSvelteComponent
* @returns {Promise<SvelteComponent>} Returns a Promise that resolves with a Svelte component
*/

/**
* @callback RoutePrecondition
* @param {RouteDetail} detail - Route detail object
* @returns {boolean} 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)
* @returns {boolean|Promise<boolean>} 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)
*/

/**
* @typedef {Object} WrapOptions
* @typedef {Object} WrapOptions Options object for the call to `wrap`
* @property {SvelteComponent} [component] - Svelte component to load (this is incompatible with `asyncComponent`)
* @property {function(): Promise<SvelteComponent>} [asyncComponent] - Function that returns a Promise that fulfills with a Svelte component (e.g. `{asyncComponent: () => import('Foo.svelte')}`)
* @property {AsyncSvelteComponent} [asyncComponent] - Function that returns a Promise that fulfills with a Svelte component (e.g. `{asyncComponent: () => import('Foo.svelte')}`)
* @property {SvelteComponent} [loadingComponent] - 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
* @property {Object} [loadingParams] - Optional dictionary passed to the `loadingComponent` component as params (for an exported prop called `params`)
* @property {Object} [userData] - Optional object that will be passed to events such as `routeLoading`, `routeLoaded`, `conditionsFailed`
* @property {Object} [props] - Optional key-value dictionary of static props that will be passed to the component. The props are expanded with {...props}, so the key in the dictionary becomes the name of the prop.
* @property {object} [loadingParams] - Optional dictionary passed to the `loadingComponent` component as params (for an exported prop called `params`)
* @property {object} [userData] - Optional object that will be passed to events such as `routeLoading`, `routeLoaded`, `conditionsFailed`
* @property {object} [props] - Optional key-value dictionary of static props that will be passed to the component. The props are expanded with {...props}, so the key in the dictionary becomes the name of the prop.
* @property {RoutePrecondition[]|RoutePrecondition} [conditions] - Route pre-conditions to add, which will be executed in order
*/

Expand Down

0 comments on commit 1a2ce29

Please sign in to comment.