{"id":17419650,"url":"https://github.com/bendrucker/sour","last_synced_at":"2025-04-15T00:02:04.969Z","repository":{"id":35332239,"uuid":"39594327","full_name":"bendrucker/sour","owner":"bendrucker","description":"Router for functional rendering UIs","archived":false,"fork":false,"pushed_at":"2019-08-19T21:45:43.000Z","size":85,"stargazers_count":6,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T08:14:06.042Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bendrucker.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-23T21:35:00.000Z","updated_at":"2019-07-12T17:15:51.000Z","dependencies_parsed_at":"2022-09-17T09:11:32.932Z","dependency_job_id":null,"html_url":"https://github.com/bendrucker/sour","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendrucker%2Fsour","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendrucker%2Fsour/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendrucker%2Fsour/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bendrucker%2Fsour/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bendrucker","download_url":"https://codeload.github.com/bendrucker/sour/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248981263,"owners_count":21193145,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-17T02:28:38.921Z","updated_at":"2025-04-15T00:02:04.925Z","avatar_url":"https://github.com/bendrucker.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sour [![Build Status](https://travis-ci.org/bendrucker/sour.svg?branch=master)](https://travis-ci.org/bendrucker/sour) [![Greenkeeper badge](https://badges.greenkeeper.io/bendrucker/sour.svg)](https://greenkeeper.io/)\n\n\u003e Router for functional rendering UIs\n\nsour is a standalone functional router that works in Node and the browser. It provides the state management and lifecycle hooks you'll use in your application. Sour is designed for composition. You should build your own application-specific routing layer that uses sour internally. Routing is handled by [routington](https://github.com/pillarjs/routington).\n\n\n## Install\n\n```\n$ npm install --save sour\n```\n\n\n## Usage\n\n```js\nvar Sour = require('sour')\nvar state = Sour()\n\nconsole.log(state.path())\n//=\u003e /the/current/path\n\nvar hello = Sour.route(state, {\n  path: '/the/route/path',\n  render: function () {\n    return 'Hello world!'\n  }\n})\n\nSour.beforeEnter(state, hello, function (params, callback) {\n  //=\u003e I run before the \"hello\" route is rendered\n  callback(null)\n})\n\nSour.watch(state)\n//=\u003e Observe path changes and update the active route\n\nstate(function (state) {\n  console.log(Sour.render(state))  \n})\n```\n\n## API\n\n### Initialization\n\n#### `Sour([data])` -\u003e `state`\n\nReturns an [observable](https://github.com/raynos/observ) representation of the state.\n\n##### data.path\n\nType: `string`  \nDefault: `document.location.pathname`\n\nThe initial path to use. In the browser, this defaults to the current page path. In Node, it defaults to `''`. Passing `data.hash = true` will synchronize the path with `location.hash` instead of `location.pathname`.\n\n#### `Sour.watch(state, [done])` -\u003e `function`\n\nWatches for path changes to update the active route. Returns an unwatch function.\n\n##### done\n\nType: `function`  \nArguments: none\n\nAn optional callback that will be called when the router is ready, meanin either:\n\n* No matching route was found\n* A match was located and the route transition was successful\n\n### Routing\n\n#### `Sour.route(state, options)` -\u003e `object`\n\nDefines a new route, returning the route key that can later be referenced to create hooks or change routes.\n\n##### options\n\n###### path\n\n*Required*  \nType: `string`\n\nA path string provided to [routington](https://github.com/pillarjs/routington).\n\n###### render\n\n*Required*  \nType: `function`\n\nThe render function for the route.\n\n#### `Sour.transition(state, route, params, callback)` -\u003e `undefined`\n\nTransitions the router to the specified route returned by `Sour.route`. \n\n##### state\n\n*Required*\n\nThe router state.\n\n##### route\n\n*Required*  \nType: `object`\n\nA route returned from `Sour.route`.\n\n##### params\n\n*Required*  \nType: `object`\n\nParameters for the route. These are passed to any registered route hooks.\n\n##### callback\n\nType: `function`  \nDefault: `noop`  \nArguments: `err`\n\nA callback that will be called after the transition completes. A route transition is complete when:\n\n* `beforeLeave` hooks finish\n* `afterLeave` hooks finish\n* `beforeEnter` hooks finish\n* the active route is updated\n\nThe `afterEnter` hook for the destination route will be run after the transition completes.\n\n### Rendering\n\n#### `Sour.render(state, [args...])` -\u003e `any`\n\nRuns the `render` function defined via `Sour.route` for the active route and returns its result. \n\n##### state\n\n*Required*  \nType: `object`\n\nThe current state of the router. If no active route is found, `undefined` is returned.\n\n##### args...\n\nA variadic set of arguments. These arguments are passed to your active `render` function.\n\n### Hooks\n\nHooks provide a way to add custom behavior that runs at different points in the routing lifecycle. \n\n#### `Sour.beforeEnter(state, [route], callback)` -\u003e `function`\n#### `Sour.afterEnter(state, [route], callback)` -\u003e `function`\n#### `Sour.beforeLeave(state, [route], callback)` -\u003e `function`\n#### `Sour.afterLeave(state, [route], callback)` -\u003e `function`\n\nEnter and leave hooks run asynchronously when moving between valid routes. Each hook method returns an unlisten function that will unregister the hook.\n\n##### state\n\nThe router state.\n\n##### route\n\nThe route key object returned by `Sour.route`. If no route is provided, the hook will run for every route.\n\n##### callback\n\n*Required*  \nType: `function`  \nArguments: `params, callback`\n\nA callback that will be called when the specified route is activated. Hooks are called in the order in which they were registered with the arguments `params, callback`, where:\n\n* `params` are path parameters defined by the path definition string.\n* `callback`: a function of `err` that can halt the route transition and must be called to continue route activation.\n\n#### `Sour.onNotFound(state, listener)` -\u003e `function`\n\n##### listener\n\n*Required*  \nType: `function`  \nArguments: `{path}`\n\nCalled when the current path does not match any routes. Returns an unlisten function.\n\n#### `Sour.onError(state, listener)` -\u003e `function`\n\n##### listener\n\n*Required*  \nType: `function`  \nArguments: `err`\n\nCalled when any hook errors during a transition. Returns an unlisten function.\n\n\n#### `Sour.path(state, route, [params])` -\u003e `string`\n\nGiven a route and its path params, return a string representing the route's path.\n\n#### route\n\n*Required*\nType: `object`\n\nA route returned from `Sour.route`\n\n#### params\n\n*Optional*\nType: `object`\n\nParams to match against the params in the path of the given route.\n\n## License\n\nMIT © [Ben Drucker](http://bendrucker.me)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbendrucker%2Fsour","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbendrucker%2Fsour","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbendrucker%2Fsour/lists"}