A JavaScript module that helps anyone build recent searches functionality.
Building recent searches experience can be trickier than you think, recent-searches module helps you easily build that experience and handle the edge cases while also giving you flexibility on how to rank those suggestions. Since I couldn't find a good existing solution I decided to build one.
recent-searches is a module that handles storing, retrieving and ranking of recent searches. If available, it uses localStorage to store suggestions cross sessions and in the rare cases where it might not be available uses a fallback memory storage, thus loosing it's cross session functionality.
The module handles expiry of searches, ranking of results and degrading their ranking through their lifecycle as well as a simple prefix search.
recent-searches is published on npm's public registry, you can install it as a dependancy of your project with the following command.
npm install --save recent-searches
Initializing the module
import RecentSearches from 'recent-searches'
const searches = new RecentSearches({
ttl: number, // Optional: ttl of searches in milliseconds, default to 1h (1000 * 60 * 60)
limit: number, // Optional: max number of entries that will be persisted, defaults is 10
namespace: string, // Optional: custom localStorage namespace
rankBy: string // Optional: ranking strategy of recent searches, "PROXIMITY" | "TIME" | "PROXIMITY_AND_TIME", default is "PROXIMITY_AND_TIME"
})
Setting and retrieving relevant searches.
// To retrieve searches for a given query
const previousSearchesForJohn = searches.getRecentSearches("John")
// [{query: "John", timestamp: ...}, {query: "Marc John", timestamp: ...}]
// To set a recent search
searches.setRecentSearch("John", resultData)
This is the list of props that you should probably know about. There are some advanced props below as well.
function({})
| required
This is called with an object. Read more about the properties of this object in the section "Children Function".
function(item: any)
| defaults to:i => (i == null ? '' : String(i))
Used to determine the string value for the selected item (which is used to
compute the inputValue
).
function(selectedItem: any, stateAndHelpers: object)
| optional, no useful default
Called when the user selects an item and the selected item has changed. Called
with the item that was selected and the new state of recent-searches
. (see
onStateChange
for more info on stateAndHelpers
).
selectedItem
: The item that was just selectedstateAndHelpers
: This is the same thing your children
function is
called with (see Children Function)
function(state: object, changes: object)
| optional
🚨 This is a really handy power feature 🚨
This function will be called each time recent-searches
sets its internal state
(or calls your onStateChange
handler for control props). It allows you to
modify the state change that will take place which can give you fine grain
control over how the component interacts with user updates without having to
use Control Props. It gives you the current state and the
state that will be set, and you return the state that you want to set.
state
: The full current state of recent-searches.changes
: These are the properties that are about to change. This also has a
type
property which you can learn more about in the
stateChangeTypes
section.const ui = (
<recent-searches stateReducer={stateReducer}>{/* your callback */}</recent-searches>
)
function stateReducer(state, changes) {
// this prevents the menu from being closed when the user
// selects an item with a keyboard or mouse
switch (changes.type) {
case recent-searches.stateChangeTypes.keyDownEnter:
case recent-searches.stateChangeTypes.clickItem:
return {
...changes,
isOpen: state.isOpen,
highlightedIndex: state.highlightedIndex,
}
default:
return changes
}
}
NOTE: This is only called when state actually changes. You should not attempt to use this to handle events. If you wish to handle events, put your event handlers directly on the elements (make sure to use the prop getters though! For example:
<input onBlur={handleBlur} />
should be<input {...getInputProps({onBlur: handleBlur})} />
). Also, your reducer function should be "pure." This means it should do nothing other than return the state changes you want to have happen.
any
| defaults tonull
Pass an item or an array of items that should be selected when recent-searches is initialized.
string
| defaults to''
This is the initial input value when recent-searches is initialized.
number
/null
| defaults todefaultHighlightedIndex
This is the initial value to set the highlighted index to when recent-searches is initialized.
boolean
| defaults todefaultIsOpen
This is the initial isOpen
value when recent-searches is initialized.
number
/null
| defaults tonull
This is the value to set the highlightedIndex
to anytime recent-searches is reset,
when the the selection is cleared, when an item is selected or when the inputValue is changed.
boolean
| defaults tofalse
This is the value to set the isOpen
to anytime recent-searches is reset, when the
the selection is cleared, or when an item is selected.
function(prevItem: any, item: any)
| defaults to:(prevItem, item) => (prevItem !== item)
Used to determine if the new selectedItem
has changed compared to the previous
selectedItem
and properly update recent-searches's internal state.
function({/* see below */})
| default messages provided in English
This function is passed as props to a Status
component nested within and
allows you to create your own assertive ARIA statuses.
A default getA11yStatusMessage
function is provided that will check
resultCount
and return "No results." or if there are results but no item is
highlighted, "resultCount
results are available, use up and down arrow keys to
navigate." If an item is highlighted it will run itemToString(highlightedItem)
and display the value of the highlightedItem
.
The object you are passed to generate your status message has the following properties:
| property | type | description |
|---|---|---|
highlightedIndex |
number /null |
The currently highlighted index |
highlightedItem |
any |
The value of the highlighted item |
inputValue |
string |
The current input value |
isOpen |
boolean |
The isOpen state |
itemToString |
function(any) |
The itemToString function (see props) for getting the string value from one of the options |
previousResultCount |
number |
The total items showing in the dropdown the last time the status was updated |
resultCount |
number |
The total items showing in the dropdown |
selectedItem |
any |
The value of the currently selected item |
function(selectedItem: any, stateAndHelpers: object)
| optional, no useful default
Called when the user selects an item, regardless of the previous selected item.
Called with the item that was selected and the new state of recent-searches
. (see
onStateChange
for more info on stateAndHelpers
).
selectedItem
: The item that was just selectedstateAndHelpers
: This is the same thing your children
function is
called with (see Children Function)
function(changes: object, stateAndHelpers: object)
| optional, no useful default
This function is called anytime the internal state changes. This can be useful
if you're using recent-searches as a "controlled" component, where you manage some or
all of the state (e.g. isOpen, selectedItem, highlightedIndex, etc) and then
pass it as props, rather than letting recent-searches control all its state itself.
The parameters both take the shape of internal state ({highlightedIndex: number, inputValue: string, isOpen: boolean, selectedItem: any}
) but differ
slightly.
changes
: These are the properties that actually have changed since the last
state change. This also has a type
property which you can learn more about
in the stateChangeTypes
section.stateAndHelpers
: This is the exact same thing your children
function is
called with (see Children Function)Tip: This function will be called any time any state is changed. The best way to determine whether any particular state was changed, you can use
changes.hasOwnProperty('propName')
.
NOTE: This is only called when state actually changes. You should not attempt to use this to handle events. If you wish to handle events, put your event handlers directly on the elements (make sure to use the prop getters though! For example:
<input onBlur={handleBlur} />
should be<input {...getInputProps({onBlur: handleBlur})} />
).
function(inputValue: string, stateAndHelpers: object)
| optional, no useful default
Called whenever the input value changes. Useful to use instead or in combination
of onStateChange
when inputValue
is a controlled prop to
avoid issues with cursor positions.
inputValue
: The current value of the inputstateAndHelpers
: This is the same thing your children
function is
called with (see Children Function)
number
| optional, defaults the number of times you call getItemProps
This is useful if you're using some kind of virtual listing component for
"windowing" (like
react-virtualized
).
number
| control prop (read more about this in the Control Props section)
The index that should be highlighted
string
| control prop (read more about this in the Control Props section)
The value the input should have
boolean
| control prop (read more about this in the Control Props section)
Whether the menu should be considered open or closed. Some aspects of the
recent-searches component respond differently based on this value (for example, if
isOpen
is true when the user hits "Enter" on the input field, then the item at
the highlightedIndex
item is selected).
any
/Array(any)
| control prop (read more about this in the Control Props section)
The currently selected item.
string
| defaults to a generated ID
You should not normally need to set this prop. It's only useful if you're server
rendering items (which each have an id
prop generated based on the recent-searches
id
). For more information see the FAQ
below.
string
| defaults to a generated ID
Used for aria
attributes and the id
prop of the element (input
) you use
getInputProps
with.
string
| defaults to a generated ID
Used for aria
attributes and the id
prop of the element (label
) you use
getLabelProps
with.
string
| defaults to a generated ID
Used for aria
attributes and the id
prop of the element (ul
) you use
getMenuProps
with.
function(index)
| defaults to a function that generates an ID based on the index
Used for aria
attributes and the id
prop of the element (li
) you use
getInputProps
with.
window
| defaults towindow
This prop is only useful if you're rendering recent-searches within a different window
context from where your JavaScript is running; for example, an iframe or a shadow-root. If the given context is lacking document
and/or add|removeEventListener
on its prototype (as is the case for a shadow-root) then you will need to pass in a custom object that is able to provide access to these properties for recent-searches.
function(stateAndHelpers: object)
| optional
A helper callback to help control internal state of recent-searches like isOpen
as
mentioned in this issue. The
same behavior can be achieved using onStateChange
, but this prop is provided
as a helper because it's a fairly common use-case if you're controlling the
isOpen
state:
const ui = (
<recent-searches
isOpen={this.state.menuIsOpen}
onOuterClick={() => this.setState({menuIsOpen: false})}
>
{/* your callback */}
</recent-searches>
)
This callback will only be called if isOpen
is true
.
function(node: HTMLElement, menuNode: HTMLElement)
| defaults to internal implementation
This allows you to customize how the scrolling works when the highlighted index
changes. It receives the node to be scrolled to and the root node (the root
node you render in recent-searches). Internally we use
compute-scroll-into-view
so if you use that package then you wont be adding any additional bytes to your
bundle :)
There are a few props that expose changes to state
(onStateChange
and stateReducer
).
For you to make the most of these APIs, it's important for you to understand
why state is being changed. To accomplish this, there's a type
property on the
changes
object you get. This type
corresponds to a
recent-searches.stateChangeTypes
property.
The list of all possible values this type
property can take is defined in
this file
and is as follows:
recent-searches.stateChangeTypes.unknown
recent-searches.stateChangeTypes.mouseUp
recent-searches.stateChangeTypes.itemMouseEnter
recent-searches.stateChangeTypes.keyDownArrowUp
recent-searches.stateChangeTypes.keyDownArrowDown
recent-searches.stateChangeTypes.keyDownEscape
recent-searches.stateChangeTypes.keyDownEnter
recent-searches.stateChangeTypes.clickItem
recent-searches.stateChangeTypes.blurInput
recent-searches.stateChangeTypes.changeInput
recent-searches.stateChangeTypes.keyDownSpaceButton
recent-searches.stateChangeTypes.clickButton
recent-searches.stateChangeTypes.blurButton
recent-searches.stateChangeTypes.controlledPropUpdatedSelectedItem
recent-searches.stateChangeTypes.touchEnd
See stateReducer
for a concrete example on how to use the
type
property.
recent-searches manages its own state internally and calls your onChange
and
onStateChange
handlers with any relevant changes. The state that recent-searches
manages includes: isOpen
, selectedItem
, inputValue
, and
highlightedIndex
. Your Children function (read more below) can be used to
manipulate this state and can likely support many of your use cases.
However, if more control is needed, you can pass any of these pieces of state as
a prop (as indicated above) and that state becomes controlled. As soon as
this.props[statePropKey] !== undefined
, internally, recent-searches
will determine
its state based on your prop's value rather than its own internal state. You
will be required to keep the state up to date (this is where onStateChange
comes in really handy), but you can also control the state from anywhere, be
that state from other components, redux
, react-router
, or anywhere else.
Note: This is very similar to how normal controlled components work elsewhere in react (like
<input />
). If you want to learn more about this concept, you can learn about that from this the Advanced React Component Patterns course
This is where you render whatever you want to based on the state of recent-searches
.
You use it like so:
const ui = (
<recent-searches>
{recent-searches => (
// use recent-searches utilities and state here, like recent-searches.isOpen,
// recent-searches.getInputProps, etc.

{/* more jsx here */}

)}
</recent-searches>
)
The properties of this recent-searches
object can be split into three categories as
indicated below:
NOTE: These prop-getters provide important
aria-
attributes which are very important to your component being accessible. It's recommended that you utilize these functions and apply the props they give you to your components.
These functions are used to apply props to the elements that you render. This
gives you maximum flexibility to render what, when, and wherever you like. You
call these on the element in question (for example: <input {...getInputProps()}
)). It's advisable to pass all your props to that function
rather than applying them on the element yourself to avoid your props being
overridden (or overriding the props returned). For example:
getInputProps({onKeyUp(event) {console.log(event)}})
.
| property | type | description |
|---|---|---|
getToggleButtonProps |
function({}) |
returns the props you should apply to any menu toggle button element you render. |
getInputProps |
function({}) |
returns the props you should apply to the input element that you render. |
getItemProps |
function({}) |
returns the props you should apply to any menu item elements you render. |
getLabelProps |
function({}) |
returns the props you should apply to the label element that you render. |
getMenuProps |
function({},{}) |
returns the props you should apply to the ul element (or root of your menu) that you render. |
getRootProps |
function({},{}) |
returns the props you should apply to the root element that you render. It can be optional. |
getRootProps
Most of the time, you can just render a div
yourself and recent-searches
will
apply the props it needs to do its job (and you don't need to call this
function). However, if you're rendering a composite component (custom component)
as the root element, then you'll need to call getRootProps
and apply that to
your root element (recent-searches will throw an error otherwise).
There are no required properties for this method.
Optional properties:
refKey
: if you're rendering a composite component, that component will need
to accept a prop which it forwards to the root DOM element. Commonly, folks
call this innerRef
. So you'd call: getRootProps({refKey: 'innerRef'})
and
your composite component would forward like:

If you're rendering a composite component, recent-searches
checks that
getRootProps
is called and that refKey
is a prop of the returned composite
component. This is done to catch common causes of errors but, in some cases, the
check could fail even if the ref is correctly forwarded to the root DOM
component. In these cases, you can provide the object {suppressRefError : true}
as the second argument to getRootProps
to completely bypass the check.\
Please use it with extreme care and only if you are absolutely sure that the ref
is correctly forwarded otherwise recent-searches
will unexpectedly fail.\
See #235 for the discussion that lead to this.
getInputProps
This method should be applied to the input
you render. It is recommended that
you pass all props as an object to this method which will compose together any
of the event handlers you need to apply to the input
while preserving the ones
that recent-searches
needs to apply to make the input
behave.
There are no required properties for this method.
Optional properties:
disabled
: If this is set to true, then no event handlers will be returned
from getInputProps
and a disabled
prop will be returned (effectively
disabling the input).getLabelProps
This method should be applied to the label
you render. It is useful for
ensuring that the for
attribute on the
(htmlFor
as a react prop)
is the same as the id
that appears on the input
. If no htmlFor
is provided
(the normal case) then an ID will be generated and used for the input
and the
label
for
attribute.
There are no required properties for this method.
Note: For accessibility purposes, calling this method is highly recommended.
getMenuProps
This method should be applied to the element which contains your list of items.
Typically, this will be a

or a

that surrounds a map
expression.
This handles the proper ARIA roles and attributes.
Optional properties:
refKey
: if you're rendering a composite component, that component will need
to accept a prop which it forwards to the root DOM element. Commonly, folks
call this innerRef
. So you'd call: getMenuProps({refKey: 'innerRef'})
and
your composite component would forward like:

.
However, if you are just rendering a primitive component like

, there
is no need to specify this property.
Please keep in mind that menus, for accessiblity purposes, should always be
rendered, regardless of whether you hide it or not. Otherwise, getMenuProps
may throw error if you unmount and remount the menu.
aria-label
: By default the menu will add an aria-labelledby
that refers
to the
rendered with getLabelProps
. However, if you provide
aria-label
to give a more specific label that describes the options
available, then aria-labelledby
will not be provided and screen readers
can use your aria-label
instead.
In some cases, you might want to completely bypass the refKey
check. Then you
can provide the object {suppressRefError : true}
as the second argument to
getMenuProps
.
Please use it with extreme care and only if you are absolutely sure that the ref
is correctly forwarded otherwise recent-searches
will unexpectedly fail.

{!isOpen
? null
: items.map((item, index) => (

{item.name}

))}

Note that for accessibility reasons it's best if you always render this element whether or not recent-searches is in an
isOpen
state.
getItemProps
The props returned from calling this function should be applied to any menu items you render.
This is an impure function, so it should only be called when you will actually be applying the props to an item.
Basically just don't do this:
items.map(item => {
const props = getItemProps({item}) // we're calling it here
if (!shouldRenderItem(item)) {
return null // but we're not using props, and recent-searches thinks we are...
}
return

})
Instead, you could do this:
items.filter(shouldRenderItem).map(item =>
)
Required properties:
item
: this is the item data that will be selected when the user selects a
particular item.Optional properties:
index
: This is how recent-searches
keeps track of your item when updating the
highlightedIndex
as the user keys around. By default, recent-searches
will
assume the index
is the order in which you're calling getItemProps
. This
is often good enough, but if you find odd behavior, try setting this
explicitly. It's probably best to be explicit about index
when using a
windowing library like react-virtualized
.disabled
: If this is set to true
, then all of the recent-searches item event
handlers will be omitted. Items will not be highlighted when hovered,
and items will not be selected when clicked.getToggleButtonProps
Call this and apply the returned props to a button
. It allows you to toggle
the Menu
component. You can definitely build something like this yourself (all
of the available APIs are exposed to you), but this is nice because it will also
apply all of the proper ARIA attributes.
Optional properties:
disabled
: If this is set to true
, then all of the recent-searches button event
handlers will be omitted (it wont toggle the menu when clicked).aria-label
: The aria-label
prop is in English. You should probably override
this yourself so you can provide translations:const myButton = (
<button
{...getToggleButtonProps({
'aria-label': translateWithId(isOpen ? 'close.menu' : 'open.menu'),
})}
/>
)
These are functions you can call to change the state of the recent-searches component.
| property | type | description |
|---|---|---|
clearSelection |
function(cb: Function) |
clears the selection |
clearItems |
function() |
Clears recent-searches's record of all the items. Only really useful if you render your items asynchronously within recent-searches. See #186 |
closeMenu |
function(cb: Function) |
closes the menu |
openMenu |
function(cb: Function) |
opens the menu |
selectHighlightedItem |
function(otherStateToSet: object, cb: Function) |
selects the item that is currently highlighted |
selectItem |
function(item: any, otherStateToSet: object, cb: Function) |
selects the given item |
selectItemAtIndex |
function(index: number, otherStateToSet: object, cb: Function) |
selects the item at the given index |
setHighlightedIndex |
function(index: number, otherStateToSet: object, cb: Function) |
call to set a new highlighted index |
toggleMenu |
function(otherStateToSet: object, cb: Function) |
toggle the menu open state |
reset |
function(otherStateToSet: object, cb: Function) |
this resets recent-searches's state to a reasonable default |
setItemCount |
function(count: number) |
this sets the itemCount . Handy in situations where you're using windowing and the items are loaded asynchronously from within recent-searches (so you can't use the itemCount prop. |
unsetItemCount |
function() |
this unsets the itemCount which means the item count will be calculated instead by the itemCount prop or based on how many times you call getItemProps . |
setState |
function(stateToSet: object, cb: Function) |
This is a general setState function. It uses recent-searches's internalSetState function which works with control props and calls your onSelect , onChange , etc. (Note, you can specify a type which you can reference in some other APIs like the stateReducer ). |
otherStateToSet
refers to an object to set other internal state. It is recommended to avoid abusing this, but is available if you need it.
These are values that represent the current state of the recent-searches component.
| property | type | description |
|---|---|---|
highlightedIndex |
number / null |
the currently highlighted item |
inputValue |
string / null |
the current value of the getInputProps input |
isOpen |
boolean |
the menu open state |
selectedItem |
any |
the currently selected item input |
As a convenience, the id
and itemToString
props which you pass to
<recent-searches />
are available here as well.
recent-searches has a few events for which it provides implicit handlers. Several of
these handlers call event.preventDefault()
. Their additional functionality is
described below.
ArrowDown
: if menu is closed, opens it and moves the highlighted index to
defaultHighlightedIndex + 1
, if defaultHighlightedIndex
is provided, or
to the top-most item, if not. If menu is open, it moves the highlighted index
down by 1. If the shift key is held when this event fires, the highlighted
index will jump down 5 indices instead of 1. NOTE: if the current highlighed
index is within the bottom 5 indices, the top-most index will be highlighted.)
ArrowUp
: if menu is closed, opens it and moves the highlighted index to
defaultHighlightedIndex - 1
, if defaultHighlightedIndex
is provided, or
to the bottom-most item, if not. If menu is open, moves the highlighted index
up by 1. If the shift key is held when this event fires, the highlighted
index will jump up 5 indices instead of 1. NOTE: if the current highlighed
index is within the top 5 indices, the bottom-most index will be highlighted.)
Home
: if menu is closed, it will not add any other behavior. If menu is open,
the top-most index will get highlighted.
End
: if menu is closed, it will not add any other behavior. If menu is open,
the bottom-most index will get highlighted.
Enter
: if the menu is open, selects the currently highlighted item. If the menu
is open, the usual 'Enter' event is prevented by recent-searches's default implicit enter
handler; so, for example, a form submission event will not work as one might expect
(though if the menu is closed the form submission will work normally). See below
for customizing the handlers.
Escape
: will reset recent-searches's state. This means that highlightedIndex
will be
set to the defaultHighlightedIndex
, the inputValue
will be set to the itemToString
value of the selectedItem
, and the isOpen
state will be set to the defaultIsOpen
.
You can provide your own event handlers to recent-searches which will be called before the default handlers:
const ui = (
<recent-searches>
{({getInputProps}) => (
<input
{...getInputProps({
onKeyDown: event => {
// your handler code
},
})}
/>
)}
</recent-searches>
)
If you would like to prevent the default handler behavior in some cases, you can set the event's preventrecent-searchesDefault
property to true
:
const ui = (
<recent-searches>
{({getInputProps}) => (
<input
{...getInputProps({
onKeyDown: event => {
if (event.key === 'Enter') {
// Prevent recent-searches's default 'Enter' behavior.
event.nativeEvent.preventrecent-searchesDefault = true
// your handler code
}
},
})}
/>
)}
</recent-searches>
)
If you would like to completely override recent-searches's behavior for a handler, in favor of your own, you can bypass prop getters:
const ui = (
<recent-searches>
{({getInputProps}) => (
<input
{...getInputProps()}
onKeyDown={event => {
// your handler code
}}
/>
)}
</recent-searches>
)
Allows reseting the internal id counter which is used to generate unique ids for recent-searches component.
You should never need to use this in the browser. Only if you are running an universal React app that is rendered on the server you should call resetIdCounter before every render so that the ids that get generated on the server match the ids generated in the browser.
import {resetIdCounter} from 'recent-searches';
resetIdCounter()
ReactDOMServer.renderToString(...);
Since recent-searches renders it's UI using render props, recent-searches supports rendering on React Native with ease. Use components like <View>
, <Text>
, <TouchableOpacity>
and others inside of your render method to generate awesome autocomplete, dropdown, or selection components.
getRootProps
or call getRootProps
with { suppressRefError: true }
. This ref is used to catch a common set of errors around composite components. Learn more in getRootProps
.<FlatList>
or <ScrollView>
, be sure to supply the keyboardShouldPersistTaps
prop to ensure that your text input stays focus, while allowing for taps on the touchables rendered for your items.Kent C. Dodds has created learning material based on the patterns implemented in this component. You can find it on various platforms:
🚨 We're in the process of moving all examples to the recent-searches-examples repo (which you can open, interact with, and contribute back to live on codesandbox)
Ordered Examples:
If you're just learning recent-searches, review these in order:
selectedItem
so the selected item can be one of your items or whatever the user types.Other Examples:
Check out these examples of more advanced use/edge cases:
React.createContext
and a recent-searches higher order component. This is generally not recommended because the render prop API exported by recent-searches is generally good enough for everyone, but there's nothing technically wrong with doing something like this.Old Examples exist on codesandbox.io:
🚨 This is a great contribution opportunity! These are examples that have not yet been migrated to recent-searches-examples. You're more than welcome to make PRs to the examples repository to move these examples over there. Watch this to learn how to contribute completely in the browser
react-instantsearch
from AlgoliaGenieJS
(learn more about genie
here)react-tiny-virtual-list
fuzzaldrin-plus
(Fuzzy matching)withrecent-searches
higher order component which you can use to get at
the state, actions, prop getters in a rendered recent-searches tree).redux-form
react-final-form
The checksum error you're seeing is most likely due to the automatically
generated id
and/or htmlFor
prop you get from getInputProps
and
getLabelProps
(respectively). It could also be from the automatically
generated id
prop you get from getItemProps
(though this is not likely as
you're probably not rendering any items when rendering a recent-searches component on
the server).
To avoid these problems, simply call resetIdCounter before
ReactDOM.renderToString
.
Alternatively you could provide your own ids via the id props where you render
<recent-searches />
:
const ui = (
<recent-searches
id="autocomplete"
labelId="autocomplete-label"
inputId="autocomplete-input"
menuId="autocomplete-menu"
>
{({getInputProps, getLabelProps}) =>
{/* your UI */}
}
</recent-searches>
)
I was heavily inspired by Ryan Florence. Watch his (free) lesson about "Compound Components". Initially recent-searches was a group of compound components using context to communicate. But then Jared Forsyth suggested I expose functions (the prop getters) to get props to apply to the elements rendered. That bit of inspiration made a big impact on the flexibility and simplicity of this API.
I also took a few ideas from the code in
react-autocomplete
and jQuery UI's
Autocomplete.
You can watch me build the first iteration of recent-searches
on YouTube:
You'll find more recordings of me working on recent-searches
on my livestream
YouTube playlist.
You can implement these other solutions using recent-searches
, but if you'd prefer
to use these out of the box solutions, then that's fine too:
If you're developing some React in ReasonML, check out the recent-searches
bindings for that.
Thanks goes to these people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
MIT
Generated using TypeDoc


Bok captain in remarkable rags to riches rise
South Africa captain Siya Kolisi did not have a television at home the last time the Springboks played in the Rugby World Cup final but 12 years on leads his team out in Saturday's decider against England in a remarkable rags to riches story.
CAPE TOWN: South Africa captain Siya Kolisi did not have a television at home the last time the Springboks played in the Rugby World Cup final but 12 years on leads his team out in Saturday's decider against England in a remarkable rags to riches story.
From growing up in a dusty, poverty-stricken township on the eastern coast of South Africa to the Yokohama International Stadium caps a remarkable journey for Kolisi, the first black man to captain the Springboks and now increasingly a new symbol for South African unity.
"For a young kid from Zwide township in Port Elizabeth to rise above circumstances and become Springbok captain and lead the way‚ he has just been inspirational to South Africans from all walks of life‚” teammate Tendai Mtawarira said in the build-up to Saturday's final in Japan.
Kolisi grew up in one of the few black areas where rugby is as popular as soccer, raised by his paternal grandmother, but did not pick up a rugby ball until he was seven.
His talent was quickly recognised, though for Kolisi rugby was no more than a distraction from life’s daily toil.
“It’s tough to stay on the right path because sometimes hunger makes you do things that you never thought you would do,” he explained before the kick-off of the World Cup last month.
“Some of my friends would steal and some died because they got into bad things.”
But Kolisi’s talent gave him an opportunity to get away from temptation as he won a bursary to Port Elizabeth’s top boys school Grey High, but even then going onto be a Springbok and play in a World Cup was furthest from his mind.
DREAM
"You don't dream about that where I am from," he said.
“He adapted well to the posh school but it was on the rugby field where he excelled. Siya was rewarded with a call-up to the South African Schools team and a contract to join Western Province,” added his biographer Jeremy Daniel.
Kolisi was 16 when South Africa edged England in the 2007 final in Paris.
“I was watching it in a tavern, because I didn’t have a TV at home."
Saturday’s final marks a 50th cap for Kolisi, who made his debut for his country in 2013 and participated at the 2015 World Cup where South Africa finished third.
“I’m very happy that I have reached 50 – not a lot of Springboks have achieved that – but the most important thing is that I do my bit for the team and everything else will fall into place,” he told a news conference in Tokyo on Friday.
“It would be huge to show our country that no matter where we come from, if we can bind to one plan, we can achieve our goals," Kolisi added.
(Editing by Giles Elgood)


August 28, 2019
The Unum Pattern
Warning: absurd technical geekery ahead — even compared to the kinds of things I normally talk about. Seriously. But things will be back to my normal level of still-pretty-geeky-but-basically-approachable soon enough.
[Historical note: This post has been a long time in the making — the roots of the fundamental idea being described here go back to the original Habitat system (although we didn’t realize it at the time). It describes a software design pattern for distributed objects — which we call the “unum” — that I and some of my co-conspirators at various companies have used to good effect in many different systems, but which is still obscure even among the people who do the kinds of things I do. In particular, I’ve described this stuff in conversation with lots of people over the years and a few of them have published descriptions of what they understood, but their writeups haven’t, to my sensibilities at least, quite captured the idea as I conceive of it. But I’ve only got myself to blame for this as I’ve been lax in actually writing down my own understanding of the idea, for all the usual reasons one has for not getting around to doing things one should be doing.]
Consider a distributed, multi-participant virtual world such as Habitat or one of its myriad descendants. This world is by its nature very object oriented, but not in quite the same way that we mean when we talk about, for example, object oriented programming. This is confusing because the implementation is, itself, very object oriented, in exactly the object oriented programming sense.
Imagine being in this virtual world somewhere, say, in a room in a building in downtown Populopolis. And there is a table in the room and sitting on the table is a teacup. Well, I said you were in the virtual world, but you’re not really in it, your avatar is in it, and you are just interacting with it through the mediation of some kind of client software running on your local computer (or perhaps these days on your phone), which is in turn communicating over a network connection to a server somewhere. So the question arises, where is the teacup, really? Certainly there is a representation of the teacup inside your local computer, but there is also a representation of the teacup inside the server. And if I am in the room with you (well, my avatar, but that’s not important right now), then there’s also a representation of the teacup inside my local computer. So is the teacup in your computer or in my computer or in the server? One reasonable answer is “all of the above”, but in my experience a lot of technical people will say that it’s “really” in the server, since they regard the server as the source of truth. But the correct answer is that the teacup is on a table in a room inside a building in Populopolis. The teacup occupies a different plane of existence from the software objects that are used to realize it. It has an objective identity of its own — if you and I each refer to it, we are talking about the same teacup — but this identity is entirely distinct from the identities of any of those software objects. And it has such an identity, because even though it’s on a different plane there still needs to be some kind of actual identifier that can be used in the communications protocols that the clients and the server use to talk to each other, so that they can refer to the teacup when they describe their manipulations of it and the things that happen to it.
You might distinguish between these two senses of “object” by using phrases with modifiers; for example, you might say “world object” versus “OOP object”, and in fact that is what we did for several years. However, this terminology made it easy to fall back on the shorthand of just talking about “objects” when it was clear from context which of these two meanings of “object” you meant. Of course, it often turned out that this context wasn’t actually clear to somebody in the conversation, with confusion and misunderstanding as the common result. So after a few false starts at crafting alternative jargon we settled on using the term “object” to always refer to an OOP object in an implementation and the term “unum”, from the latin meaning a single thing, to refer to a world object. This term has worked well for us, aside from endless debates about whether the plural is properly “una” or “unums” (my opinion is: take your pick; people will know what you mean either way).
Of course, we still have to explain the relationship between the unum and its implementation. The objects (using that word from now on according to our revised terminology) that realize the unum do live at particular memory addresses in particular computers. We think of the unum, in contrast, as having a distributed existence. We speak of the portion of the unum that resides in a particular machine as a “presence”. So to go back to the example I started with, the teacup unum has a presence on the server and presences on each of our client machines.
(As an aside, for the first few years of trying to explain to people how Habitat worked, I would sometimes find myself in confused discussions about “distributed objects”, by which the people with whom I was talking meant individual objects that were located at different places on the network, whereas I meant objects that were themselves distributed entities. I didn’t at first realize these conversations were at cross purposes because the model we had developed for Habitat seemed natural and obvious to me at the time — how else could it possibly work, after all? — and it took me a while to twig to the fact that other people conceived of things in a very different way. Another reason for introducing a new word.)
In the teacup example, we have a server presence and some number of client presences. The client presences are concerned with presenting the unum to their local users while the server presence is concerned with keeping track of that portion of the unum’s state which all the users share. Phrased this way, many people find the presence abstraction very natural, but it sometimes leads them to jump to conclusions about what is going on, resulting in still more confusion and conversation at cross purposes. People who implement distributed systems often build on top of frameworks that provide services like data replication, and so it is easy to fall into thinking of the server presence as the “real” version of the unum and the client presences as shadow copies that maintain a (perhaps slightly out of date) cached representation of the true state. Or thinking of the client presences as proxies of some kind. This is not exactly wrong, in the sense that you can certainly build systems that work this way, as many distributed applications — possibly including most commercially successful MMOs — actually do. However, it’s not the model I’m describing here.
One problem with data replication based schemes is that they don’t gracefully accommodate use cases that require some information be withheld from some participants (it’s not that you absolutely can’t do this, but it’s awkward and cuts against the grain). It’s not just that the server is authoritative about shared state, but also that the server is allowed to take into account private state that the clients don’t have, in order to determine how the shared state changes over time and in response to events.
A server presence and a client presence are not doing the same job. The fundamental underlying concept that presences embody is not some notion of master vs. replica, but division of labor. Each has distinct responsibilities in the joint work of being the unum. Each is authoritative about different aspects of the unum’s existence (and typically each will maintain private state of their own that they do not share with the other). In the case of the client-server model in our example, the client presence manages client-side concerns such as the state of the display. It worries about things like 3D rendering, animation sequencing, and presenting controls to the human user to manipulate the teacup with. The server keeps track of things like the physical model of the teacup within the virtual world. It worries about the interactions between the teacup and the table, for example. Each presence knows things that are none of the other presence’s business, either because that information is simply outside the scope of what the other presence does (such as the current animation frame or the force being applied to the table) or because it’s something the other presence is not supposed to know (such as the server knowing that this particular teacup has a hidden flaw that will cause it to break into several pieces if you pour hot water into it, revealing a secret message inscribed on the edges where it comes apart). The various different client presences may also have information they do not share with each other for reasons of function or privacy. For example, one client might do 3D rendering in a GUI window while another presents only a textual description with a command line interface. Perhaps the server has revealed the secret message hidden in the teacup to my client (and to none of the others) because I possess a magic amulet that lets me see such things.
We can loosely talk about “sending a message to an unum”, but the sending of messages is an OOP concept rather than a world model concept. Sending a message to an unum (which is not an object) is really sending a message to some presence of that unum (since a presence is an object). This means that to designate the target of such a message, the address needs two components: (1) the identity of the unum and (2) an indicator of which presences of that unum you want to talk to.
In the systems I’ve implemented (including Habitat, but also, perhaps more usefully for anyone who wants to play with these ideas, its Nth generation descendant, the Elko server framework), the objects on a machine within a given application all run inside a common execution environment — what we now call a “vat”. Cross-machine messages are transported over communications channels established between vats. In such a system, from a vat’s perspective the external presences of a given unum (that is, presences other than the local one) are thus in one-to-one correspondence with the message channels to the other vats that host those presences, so you can designate a presence by indicating the channel that leads to its vat. (For those presences you can talk to, anyway: the unum model does not require that a presence be able to directly communicate with all the other presences. For example, in the case of a Habitat or Elko-style system such as I am describing here, clients don’t talk to other clients, but only to the server.)
Here we encounter an asymmetry between client and server that is another frequent source of confusion. From the client’s perspective, there is only one open message channel — the one that talks to the server — and so the only other unum presence a client knows about is the server presence. In this situation, the identifier of the unum is sufficient to determine where a message should be sent, since there is only one possibility. Developers working on client-side code don’t have to distinguish between “send a message to the unum” and “send a message to the server presence of the unum”. Consequently, they can program to the conventional model of “send messages to objects on the other end of the connection” and everything works more or less the way they are used to. On the server side, however, things get more interesting. Here we encounter something that people accustomed to developing in the web world have usually never experienced: server code that is simultaneously in communication with multiple clients. This is where working with the unum pattern suddenly becomes very different, and also where it acquires much of its power and usefulness.
In the client-server unum model, the server can communicate with all
of an unum’s client presences. Although a given message could be sent
to any of them, or to all of them, or to any arbitrary subset of them,
in practice we’ve found that a small number of messaging patterns
suffice to capture everything we’ve wanted to do. More specifically,
there are four patterns that in our experience are repeatedly useful, to
the point where we’ve codified these in the messaging libraries we use
to implement distributed applications. We call these four messaging
patterns Reply
, Neighbor
, Broadcast
, and Point
,
all framed in the context of processing some message that has been
received by the server presence from one of the clients; among other
things, this context identifies which client it was who sent it. A Reply
message is directed back to the client presence that sent the message the server is processing. A Point
message is directed to a specific client presence chosen by the server; this is similar to a Reply
message except that the recipient is explicit rather than implied and could be any client regardless of context. A Broadcast
message is sent to all the client presences, while a Neighbor
message is directed to all the client presences except
the sender of the message that the server is processing. The latter
pattern is the one that people coming to the unum model for the first
time tend to find weird; I’ll explain its use in a moment.
(Some people jump to the idea these four are all generalizations of the Point
message, thinking it a good primitive to actually implement the other
three, but in the systems we’ve built the messaging primitive is a lower
level construct that handles fanout and routing for one or many
recipients with a single, common mechanism so that we don’t have to
multiply buffer the message if it has more than one target. In
practice, we use Point messages rather rarely; in fact, using a Point
message usually indicates that you’re doing something odd.)
The reason for there being multiple client presences in the first place is that the presences all share a common context in which the actions of one client can affect the others. This is in contrast to the classic web model in which each client is engaged in its own one-on-one dialog with the server, pretty much unrelated to any simultaneous dialogs the server might be having with other clients that just happen to be connected to it at the same time. However, the multiple-clients-in-a-shared-context model is a very good match for the kinds of online game and virtual world applications for which it was originated (it’s not that you can’t realize those kinds of applications using the web model, but, like the comment I made above about data replication, it’s cutting against the grain — it’s not a natural thing for web servers to do).
Actions initiated by a client typically take the form of a request
message from that client to an unum’s server presence. The server’s
handler for this message takes whatever actions are appropriate, then
sends a Reply
message back informing the requestor of the results of the action, along with a Neighbor
message to the other client presences informing them of what just happened. The Reply
and Neighbor
messages generally have different payloads since the requestor
typically already knows what’s going on and often merely needs a status
result, whereas the other clients need to be informed of the action de
novo. It is also common for the requestor to be a client that is in
some privileged role with respect to the unum (perhaps the sending
client is associated with the unum’s owner or holder, for example), and
thus entitled to be given additional information in the Reply
that is not shared with the other clients.
Actions initiated by the server, on the other hand, typically will be communicated to all the clients using the Broadcast
pattern, since in this case none of the clients start out knowing
what’s going on and thus all require the same information. The fact
that the server can autonomously initiate actions is another
difference between these kinds of systems and traditional web
applications (server initiated actions are now supported by HTTP/2,
albeit in a strange, inside out kind of way, but as far as I can tell
they have yet to become part of the typical web application developer’s
toolkit).
A direction that some people immediately want to go is to attempt to reduce the variety of messaging patterns by treating the coordination among presences as a data replication problem, which I’ve already said is not what we’re doing here. At the heart of this idea is a sense that you might make the development of presences simpler by reducing the differences between them — that rather than developing a client presence and a server presence as separate pieces of code, you could have a single implementation that will serve both ends of the connection (I can’t count the number of times I’ve seen game companies try to turn single player games into multiplayer games this way, and the results are usually pretty awful). Alternatively, one could implement one end and have the other be some kind of standardized one-side-fits-all thing that has no type-specific logic of its own. One issue with either of these approaches is how you handle the asymmetric information patterns inherent in the world model, but another is the division of labor itself. Systems built on the unum pattern tend to have message interfaces that are fundamentally about behavior rather than about data. That is, what is important about an unum is what it does. Habitat’s design was driven to a very large degree by the need for it to work effectively over 300 and 1200 baud connections. Behavioral protocols are vastly more effective at economizing on bandwidth than data based protocols. One way to think of this is as a form of highly optimized, knowledge-based data compression: if you already know what the possible actions are that can transform the state of something, a parameterized operation can often be represented much more compactly than can all state that is changed as a consequence of the action’s execution. In some sense, the unum pattern is about as anti-REST as you can be.
One idea that I think merits a lot more exploration is this: given the fundamental idea that an unum’s presences are factored according to a division of labor, are there other divisions of labor besides client-server that might be useful? I have a strong intuition that the answer is yes, but I don’t as yet have a lot of justification for that intuition. One obvious pattern to look into is a pure peer-to-peer model, where all presences are equally authoritative and the “true” state of reality is determined by some kind of distributed consensus mechanism. This is a notion we tinkered with a little bit at Electric Communities, but not to any particular conclusion. For the moment, this remains a research question.
One of the things we did do at Electric Communities was build a system where the client-server distinction was on a per-unum basis, rather than “client” and “server” being roles assigned to the two ends of a network connection. To return to our example of a teacup on a table in a room, you might have the server presence of the teacup be on machine A, with machines B and C acting as clients, while machine B is the server for the table and machine C is the server for the room. Obviously, this can only happen if there is N-way connectivity among all the participants, in contrast to the traditional two-way connectivity we use in the web, though whether this is realized via pairwise connections to a central routing hub or as a true crossbar is left as an implementation detail. This kind of per-unum relationship typing was one of the keys to our strategy for making our framework support a world that was both decentralized and openly extensible. (Continuing with the question raised in the last paragraph, an obvious generalization would be to allow the division of labor scheme itself vary from one unum to another. This suggests that a system whose unums are all initially structured according to the client-server model could still potentially act as a test bed for different schemes for dividing up functionality over the network.)
Having the locus of authoritativeness with respect to shared state vary from one unum to another opens up lots of interesting questions about the semantics of inter-unum relationships. In particular, there is a fairly broad set of issues that at Electric Communities we came to refer to as “the containership problem”, concerning how to model one unum containing another when the una are hosted on separate machines, and especially how to deal with changes in the containership relation. For example, let’s say we want to take our teacup that’s sitting on the table and put it into a box that’s on the table next to it. Is that an operation on the teacup or on the box? If we have the teacup be authoritative about what its container is, it could conceivably teleport itself from one place to another, or insert itself into places it doesn’t belong. On the other hand, if we have the box be authoritative about what it contains, then it could claim to contain (or not contain) anything it decides it wants. Obviously there needs to be some kind of handshake between the two (or between the three, if what we’re doing is moving an unum from one container to another, since both containers may have an interest — or among the two or three and whatever entity is initiating the change of containership, since that entity too may have something to say about things), but what form that handshake takes leads to a research program probably worthy of being somebody’s PhD thesis project.
Setting aside some of these more exotic possibilities for a moment, we have found the unum pattern to be a powerful and effective tool for implementing virtual worlds and lots of other applications that have some kind of world-like flavor, which, once you start looking at things through a world builder’s lens, is a fairly diverse lot, including smart contracts, multi-party negotiations, auctions, chat systems, presentation and conferencing systems, and, of course, all kinds of multiplayer games. And if you dig into some of the weirder things that we never had the chance to get into in too much depth, I think you have a rich universe of possibilities that is still ripe for exploration.
Very cool! I appreciate this detailed explanation.
As far as Web compatibility, WebSocket closes most of the gap for the transport layer. Now all that’s needed is the object framework (which should be a Simple Matter of Programming).
Posted by: Michael FIG | August 29, 2019, 12:01 pm
Very interesting, thank you.
Posted by: Simon Michael | August 29, 2019, 2:10 pm
It strikes me that unums are the inverse of an Avatar. Whilst the Avatar is your presence in the Populopolis tea room, the unum is the teacup’s presence(s) in our world.
Of course, that makes it’s really hard to model relativistic physics in these virtual worlds because there are lots of “shortcuts” in our physical world!
Anyway, modern so-called “distributed systems” seems awash with people who mean “individual objects that were located at different places on the network” (i.e. “sharded” systems) rather than the more traditional “objects that were themselves distributed entities” (i.e. “(multi-master) replicated”; one “thing” appears in lots of places in potentially different states).
Systems sharded by data are often useful to run code that is “replicated” (i.e. “duplicated” you run the same piece of code on lots of different, data). Systems replicated by data are often useful to run code that is sharded (i.e. “division of labour”. You run slightly different code on the same (or a subset of, or a restructuring of) data in different places for different purposes). Most of the current narrative seems to be about solving the former problem because “big data”.
I think your date replication / behavioural communication distinction is similar to a the code / data distinction in data driven programming, but somewhat in reverse: it’s possible to get good communication efficiencies by describing some transitions in code and referring to them symbolically rather than programming more generally and driving it with replicated data.
When extending the division of labour concept to the server side I think it’s important to know why you’re dividing the labour. Different servers could be responsible for different rooms whilst teacups might be so important that they have their own server. All the room servers could have a teacup presence but the server specific aspects of the teacup could be dealt with on the teacup server. If that’s because I provide teacups for your game then that’s a very different problem than if you just have a lot of teacups that need their own resources. In many ways it becomes similar to the containership problem:
The containership problem seems like it’s to do with the trust of the different servers and the trust of the code they run. At the moment your trust boundary seems like it’s between the client and the servers. If they’re all run by the same entity then it’s “just” a problem of managing that cross-cutting concern in the wider codebase.
Posted by: andyjpb | August 29, 2019, 2:48 pm
unum here sounds very similar to the idea of an “entity” described here: https://martinfowler.com/bliki/EvansClassification.html
Posted by: Douglas | August 30, 2019, 3:13 pm


Manage GitHub labels from the command line
Rather than managing GitHub issue labels with the web interface, use this script to do so from the command line. This script makes it easier to delete default labels and add new ones from a standard list. It’s especially useful for organizations or users who want consistent issue labels across a large number of repositories.
Requirements
- Python 3
- Python modules:
json
,argparse
, andrequests
- GitHub authorization token
Set up
Get and store authorization token in file
If you don’t have one already, set up an authorization token with
appropriate permissions using these
instructions. Once
created, save your token in a file on your computer. For example, you
might create ~/.gh_token
in your home directory that simply
contains the token.
Label files
New labels should be stored in a JSON file. For example:
[
{
"name": "Priority: Critical",
"description": "",
"color": "e11d21"
},
{
"name": "Priority: High",
"description": "",
"color": "eb6420"
},
{
"name": "Priority: Medium",
"description": "",
"color": "fbca04"
},
{
"name": "Priority: Low",
"description": "",
"color": "009800"
}
]
Usage
Use the -h
or --help
flags to see the scripts arguments (arguments
in square brackets are optional).
[~] $ ./manage_repo_labels.py -h
usage: manage_repo_labels.py [-h] -i ID -t TOKEN -r REPO [-o ORG] [-l LABELS]
[-c] [-d]
optional arguments:
-h, --help show this help message and exit
-i ID, --id ID GitHub ID
-t TOKEN, --token TOKEN
GitHub authorization token in file
-r REPO, --repo REPO Repository name
-o ORG, --org ORG Organization name
-l LABELS, --labels LABELS
Labels in JSON file
-c, --check_existing Flag to check existing labels
-d, --drop_existing Flag to drop existing labels
Users must supply their GitHub ID, path to authorization token file, and the repository name. If the repository is owned by an organization, then the the organization name must be included. The script assumes the repository is owned by the user otherwise.
Check existing
./manage_repo_labels.py -i ID -t ~/.github_token -r my_repo -c
Delete existing
./manage_repo_labels.py -i ID -t ~/.github_token -r my_repo -d
Add new labels
./manage_repo_labels.py -i ID -t ~/.github_token -r my_repo -l new_repo_labels.json


The easiest way of starting a new project using ABP and module-zero is to create a template on templates page. Remember to check "Include module zero".
After creating and downloading your project,
Be sure you have installed Typescript 2.0+ for your Visual Studio because Abp.Web.Resources nuget package comes with d.ts and it requires Typescript 2.0+.
In this template, multi-tenancy is enabled by default. You can disable it in Core project's module class if you don't need.
Startup template uses cookie based authentication for browsers. However, if you want to consume Web APIs or application services (those are exposed via dynamic web api) from a mobile application, you probably want a token based authentication mechanism. Startup template includes bearer token authentication infrastructure. AccountController in .WebApi project contains Authenticate action to get the token. Then we can use the token for next requests.
Here, Postman (chrome extension) will be used to demonstrate requests and responses.
Just send a POST request to http://localhost:6334/api/Account/Authenticate with Context-Type="application/json" header as shown below:
We sent a JSON request body includes userNameOrEmailAddress and password. Also, tenancyName should be sent for tenant users. As seen above, result property of returning JSON contains the token. We can save it and use for next requests.
After authenticate and get the token, we can use it to call any authorized action. All application services are available to be used remotely. For example, we can use the Tenant service to get a list of tenants:
Just made a POST request to http://localhost:6334/api/services/app/tenant/GetTenants with Content-Type="application/json" and Authorization="Bearer your- auth-token ". Request body was just empty {}. Surely, request and response body will be different for different APIs.
Almost all operations available on UI are also available as Web API (since UI uses the same Web API) and can be consumed easily.
Startup template includes a tool, Migrator.exe, to easily migrate your databases. You can run this application to create/migrate host and tenant databases.
This application gets host connection string from it's own .config file. It will be same in the web.config at the beggining. Be sure that the connection string in config file is the database you want. After getting host connection sring, it first creates the host database or apply migrations if it does already exists. Then it gets connection strings of tenant databases and runs migrations for those databases. It skips a tenant if it has not a dedicated database or it's database is already migrated for another tenant (for shared databases between multiple tenants).
You can use this tool on development or on product environment to migrate databases on deployment, instead of EntityFramework's own Migrate.exe (which requires some configuration and can work for single database in one run).
Startup template includes test infrastructure setup and a few tests under the .Test project. You can check them and write similar tests easily. Actually, they are integration tests rather than unit tests since they tests your code with all ASP.NET Boilerplate infrastructure (including validation, authorization, unit of work...).


localhost:9099 (copy to clipboard)
No iOS apps detected.
1. Ensure a simulator is online, and the inspector is initialized via-code with the default values.
{{device.validIp ? device.ip : device.id}} (copy to clipboard)
No devices detected.
1. Ensure ADB is in your environment's path and a device is online.
2. Otherwise, connect to a device using the Manual Connection tab.


There is not a single one of us who have not seen Tom & Jerry, or don’t recollect the cat & mouse chase. This adorable duo forms an important part of our growing up years. But over a period of time, they too have evolved. Let’s travel back in time with this classic pair.
Hanna-Barbera (1940-1958)
Yes, they are that old!
The original creators of the cat & the mouse, William Hanna & Joseph Barbera worked for the MGM cartoon studio. Burdened with the task of directing profit-generating films for the studio, the pair came up with the idea. But it was met with opposition. After all, there had been enough cat & mouse cartoons. However, Hanna-Barbera stood their ground, and Tom & Jerry made their debut in February 1940 in the short Puss Gets the Boot. But they were yet to become Tom and Jerry. On their introduction, they were Jasper and Jinx. The short was an instant hit but the names were not. Hanna-Barbera offered studio employees a US$ 50 prize to come up with the best name. And Tom & Jerry were born.
While Jerry’s physical appearance has changed very little, Tom has transformed over the years. During this period Tom had a very round face and an unruly fur. Although changes were made to the characters over the years, these initial years are considered to the golden era for Tom & Jerry. Under Hanna-Barbera’s supervision, MGM produced 114 animated shorts, and won seven Academy Awards.
Gene Deitch (1961-1962)
When the franchise was revived by MGM in 1961, they hired Rembrandt Films to produce 13 shorts. Gene Deitch headed this project. These 13 differed from Hanna-Barbera’s original in their settings. Unlike the originals that were set inside or outside a house, these 13 shorts moved to more exotic locations including a whaling ship, jungles of Nairobi, Ancient Greek acropolis, and the Wild West. They also changed Tom’s owner Mammy Two-Shoes, a heavy-set, middle-aged, black woman, to Clint Cobbler, a bald, overweight, short-tempered, middle-aged white man.
Although none of these films were nominated for the Academy Awards, they were a huge commercial success, becoming the highest-grossing animated short film series of the time, breaking the record of Looney Tunes.
Chuck Jones (1963-1967)
The man behind Looney Tunes’ Wile E Coyote and Roadrunner started his own studio with 34 shorts of Tom & Jerry made between 1963 & 1967. Jones brought his characteristic style to the characters. Tom got Wile E-style bushy, knitted eyebrows, a gray fur, sharper ears, longer tail, and fuller cheeks like Sylvester, while Jerry was given bigger ears and cuter facial characteristics on the lines of Porky Pig. Jones’s Tom & Jerry series also introduced the iconic theme tune that is used to this day, and the timeless title sequence with a hissing Tom replacing MGM’s trademark roaring lion.
Hanna-Barbera’s The Tom and Jerry Show (1975-1977)
Tom & Jerry returned home with their own TV series – The Tom and Jerry Show. But there were some visible differences. The series had 48 new seven-minute adventures. But there were strict new rules against violence in kids’ television. This meant that the amount and form of violence had to be toned down, and often the sworn enemies had to become best friends or at least help each other. To keep in line with this new kid-friendly series, Jerry was given a new accessory – a red bow-tie.
Filmation Studios (1980-1982)
When Filmation Studios took over production, the cat & mouse duo returned to television with a new series but with their original tricks. The Tom and Jerry Comedy Show also brought back other animated characters from the original series, including Droopy, Barney the Bear and Spike, giving them more material to play with.
Tom and Jerry Kids (1990-1994)
Weekend television cartoon in the 1980s & 90s saw the emerging trend of ‘babyfication’ or popular cartoon characters. Tom & Jerry also joined the bandwagon, and the series featured a bow-tie wearing Jerry and a red cap-wearing Tom chasing each other. Spike and his son Tyke (with dialogues), and Droopy and his son Dripple also made cameo appearances.
Warner Bros.’ Tom and Jerry (2006-2008)
Warner Bros. produced the Tom and Jerry Tales. This was a 13-part series of half-hour shows, each featuring three adventures that utilised the slapstick chase style of the original.
Warner Bros.’ The Tom and Jerry Show (2014-present day)
Barring the occasional reruns on Cartoon Network, there was nothing happening with this iconic duo. Tom and Jerry were resurrected for television in 2014. And a second season was launched in 2015, just before their 75th birthday. Not much has changed in Tom & Jerry themselves, but the Flash animation used by Warner Bros. gives the series a more contemporary 2D style.
The series retains the feel of the original, but little things like the digital read-out on the cooker, remind us that the cat & mouse are now in the 21st century. Occasionally, modern gadgets also make an appearance.
We look forward to more cat & mouse adventures.


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/.22let.22.20destroys.20tags.html ---
When you do induction, Lean tags the different cases. You can see these tags in the Goal window in VScode. However, let
destroys those tags.
example (n : ℕ) : n > 0 := begin induction n, { let k : ℤ := 3, -- the tag is gone :sad: sorry }, sorry end
Would you rather the tags were there forever? I always think it's a bit weird that the tags are there at all, and never pay any attention to them. A general "idea" I have in a proof isn't tagged, how come "I happen to be doing a case split" is so important?
Well, if they are there, they shouldn't be destroyed by a simple let
statement.
Also, I think they can be used in a nice way.
You can try wrapping your let
with propagate_tags
Aha :bulb:
Still... this defeats the purpose of tags a bit, in my eyes.
Because users will not do the wrapping... and so they lose their tags
Two solutions: you create a let'
tactic or you make a pull request to the Lean community fork for let
I see... thanks for teaching me about propagate_tags
!
PR to core
oh wait it isn't in core
You could PR this as a change to the set
tactic in mathlib, which is just a wrapper around let
.
Well, in general you would want all tactics to reasonably preserve tags. (Unless they have a good reason not to.)
I didn't test which tactics are bad actors. But I guess let
is not the only one.
Look into init/meta/interactive.lean
and see which ones do not use propagate_tags
and try to find a good reason for them.
Last updated: Apr 24 2020 at 19:02 UTC


2 Samuel 5:14
And these be the names of those that were born unto him in Jerusalem; Shammuah, and Shobab, and Nathan, and Solomon,


public class PrimeCounter
extends java.lang.Object
| Modifier and Type | Class and Description |
|---|---|
private static class |
PrimeCounter.Lock |
| Modifier and Type | Field and Description |
|---|---|
int |
HIGH_LIM
Some necessary (and unnecessary) constants.
|
private static java.lang.Object |
LOCK
A constant object of
PrimeCounter.Lock , used for multithreading purposes. |
int |
LOW_LIM
Some necessary (and unnecessary) constants.
|
int |
NUM_THREADS
Some necessary (and unnecessary) constants.
|
static java.lang.String |
PROMPT
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
int |
REDUCE_FACTOR
Some necessary (and unnecessary) constants.
|
int |
SPLIT_LIM
Some necessary (and unnecessary) constants.
|
static java.lang.String |
START_CODE
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
static java.lang.String |
TEST_FORMAT
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
static java.lang.String |
TOTAL_OUTPUT_FORMAT
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
static java.lang.String |
WAIT
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
static java.lang.String |
WARNING
Some Strings used for I/O purposes, factored out of code for i18n purposes.
|
| Constructor and Description |
|---|
PrimeCounter()
Default constructor.
|
PrimeCounter(int NUM_THREADS,
int LOW_LIM,
int SPLIT_LIM,
int HIGH_LIM,
int REDUCE_FACTOR)
Parameterized Constructor - configures calculation parameters
|
| Modifier and Type | Method and Description |
|---|---|
long |
bitPrimeSieve(long MAX)
Calculates primes using bitmasked Sieve of Eratosthenes.
|
private static boolean |
completed(long[] array)
Checks for completion of threads
|
private static boolean |
isPrime(long n)
Checks if the parameter is prime or not.
|
static void |
main(java.lang.String[] args)
Main method: accepts user input and shows total execution time taken
|
long |
primeCount(long MAX)
Generates and counts primes using an optimized but naive iterative algorithm.
|
long |
primeSieve(long MAX)
Calculates primes using the atandard Sieve of Eratosthenes.
|
private static long |
sieveTest(long MAX)
Private testing and timer function
|
public static final java.lang.String START_CODE
public static final java.lang.String TEST_FORMAT
public static final java.lang.String PROMPT
public static final java.lang.String WAIT
public static final java.lang.String WARNING
public static final java.lang.String TOTAL_OUTPUT_FORMAT
private static final java.lang.Object LOCK
PrimeCounter.Lock
, used for multithreading purposes.PrimeCounter.Lock
public final int NUM_THREADS
PrimeCounter(int, int, int, int, int)
public final int LOW_LIM
PrimeCounter(int, int, int, int, int)
public final int SPLIT_LIM
PrimeCounter(int, int, int, int, int)
public final int HIGH_LIM
PrimeCounter(int, int, int, int, int)
public final int REDUCE_FACTOR
PrimeCounter(int, int, int, int, int)
public PrimeCounter()
public PrimeCounter(int NUM_THREADS, int LOW_LIM, int SPLIT_LIM, int HIGH_LIM, int REDUCE_FACTOR)
NUM_THREADS
- : The number of threads to be used in multithreaded trial division.LOW_LIM
- : The minimum value of 'x' for which trial division will be used.SPLIT_LIM
- : The value which determines how many threads will be used. NUM_THREADS
HIGH_LIM
- : The value of 'x' for which the bitPrimeSieve(long)
will be used.REDUCE_FACTOR
- : The value which determines the packing density bitPrimeSieve(long)
will use.public static void main(java.lang.String[] args)
args
- : The command-line argumentsprivate static long sieveTest(long MAX)
MAX
- : input to be passed on to primeSieve(long)
private static boolean completed(@NotNull long[] array)
array
- : The array containing the completion dataprivate static boolean isPrime(long n)
n
- : the number to check for primalitypublic long primeSieve(long MAX)
MAX
- : argument x for pi(x)
Will delegate to primeCount(long)
for MAX<LOW_LIM,
and to bitPrimeSieve(long)
for MAX>HIGH_LIM, for performance reasons.primeCount(long)
,
bitPrimeSieve(long)
public long primeCount(long MAX)
MAX
- : Argument x for pi(x), the limit to which to generate numbers.public long bitPrimeSieve(long MAX)
MAX
- : argument x for pi(x)


baseNet
helps provide users with clear, concise visualizations of
their standard network graphs so that they can perform an effective analysis of the network.
baseNet(data, nodes = NULL, layout = "lgl", label, label_color, directed = F, node_color, node_size, edge_color, edge_size)
| data | A network object that can be converted to a tidygraph tbl_graph (acceptable classes include 'data.frame', 'igraph', 'list', 'matrix', and 'network'). See ?tbl_graph for more information about accepted classes of networks. |
|---|---|
| nodes | A data.frame containing information about the nodes in the graph. Default: NULL |
| layout | The type of layout used to plot the network using ggraph. Either a valid string, a function, a matrix, or a data.frame. See ?ggraph for more information. Default: "lgl" |
| label | The variable from the nodes table that should be used to label the nodes in the plotted network. Default: first column of the nodes table |
| label_color | The color of the label. Default: "navy" |
| directed | Indicates if the constructed graph should be directed. Default: F |
| node_color | The color of the nodes of the network. Accepted inputs are either a character vector that notes a specific color (ex."red") or the name of a variable from the nodes table. Default: "cornflowerblue" |
| node_size | The size of the nodes of the network. Accepted inputs are either a numeric vector that notes a specific size (ex. 6) or the name of a variable from the nodes table. Default: 8 |
| edge_color | The color of the edges of the network. Accepted inputs are either a character vector that notes a specific color (ex."red") or the name of a variable from the edges table. Default: "slategrey" |
| edge_size | The size/width of the edges of the network. Accepted inputs are either a numeric vector that notes a specific size (ex. 0.5) or the name of a variable from the nodes table. Default: 0.6 |
A list, k, containing the network data in the form of a tidygraph, k$data, and a ggmap object of the plotted network, k$network.
The baseNet
function converts the user's network into a tidygraph
class
object, returning the both the tidygraph object and plotting the network using ggmap
. This
allows for the user to futher edit the network object as needed as well as allowing them to
add further modifications to the ggmap plot, such as editing the title. In order to customize the nodes
of the network using a measure of centrality, the user must input one of the values featured bellow into the
node_color/node_size aruguments, which correspond with following tidygraph centrality measurement functions:
betweenness: centrality_betweenness()
closeness: centrality_closeness()
degree: centrality_degree()
eigen: centrality_eigen()
Users also have the option of customizing the edges of their network using the variable edge_weight, which notes the weight between two edges.


1) JP Morgan Chase:
Location: India Position: Assistant Vice President Team: Treasury Technology: Python, Kafka, Hadoop and Tableau Role: At JP morgan, I was developing analytical tools for Treasury. JP Morgan vital role is managing liquidity and investing in profitable assets. The analytics team plays an important role in assitanting business in making critical decisions about where to invest and find the AAA bonds - Not just by the ratings but also by their past performance. My project was a core module and it was deployed pan JP Morgan Chase. We not only assesed external business but also profitable entities within the bank.2) Barclays Bank
Location: Singapore Position: Assistant Vice President Team: FX and Derivatives Technology: C++, Oracle Cache, IBM Message queues, .NET Role: At Barclays Bank, I was developing front end software for FX trading Desk. I was involved in EM migration for the business. I was also involved in design related discussions for the software. FX Derivatives is one of the profitable arm of the bank and it is very competitive. Only change is the constant. We were evolving system towards real time Risk and Pnl calculation. We already optimized software for End of the day report generation.
I am student at UNCC. This summer I took Knowledge Discovery in Data Graduate course. I learnt about CRISP-DM technique for Data Minning. As a part of the course, I learnt R and did courses from DataCamp. In past I have worked on Data Analytics projects with JP Morgan Chase and Barclays Bank. I have been writing code in Python for past 3 years and have used Scikit Learn and Scipy for analysis.
I am Data Analysis enthusiast learning R and Python programming languages as well as Visualization techniques. Based on my past Industrial experiences and my current Graduation course, I believe I have a perfect toolset to be adept in field of Data Analysis!
I took KDD as my summer course and took part in Kaggle competition as a project.
Link to Competition: Home Credit Default
Home Credit is a consumer finance provider which focus on lending to people with little or no credit history. To make use of the data to enable Home Credit to make predictions on client's repayment abilities. This will help Home Credit to ensure that clients who can repay are not rejected, but are given a loan with a principle, maturity, and repayment calendar that the loan proves empowering to both Home Credit and the client.
Along with my team, I applied CRISP-DM process to the Kaggle dataset.
1) Understanding Business Problem: As a first step we defined the goal for the project and translated it to data analytic problem.
2) Exploratory data analysis: Since the data was huge we had to write our own wrapper libraries to perform EDA, for ex. we added library to plot barplots, histograms and boxplots based on frequency binning.
3) Data Preparation: The kaggle data had lot of imbalance between majority and minority target classes. We used ROSE library and SMOTE to reduce imbalances. After that we performed Z-score standardization for linear regression and Min-Max for XGBoost. We also reduced the dimensions of the train data from 121 to 49. After this we also joined Credit and Bureau files to train data. We also did imputation of missing data using HMISC and MICE.
4) Modelling We performed two modelling techniques:
a) Linear Regression Model - To find variables which has linear correlation with target class
b) Ensemble XGBoost - Decision tree was run 100 fold and we achieved RMSE .30
I took topics of Intelligent Systems as my Spring 2018 course.
Predicting successful clicks for an advertisment are critical for any organization. With rise in Social Networks it is important to know factors leading to successful click on advertisments.
Using Python NLTK package, I did text analysis - TF-IDF vectorization and Sentiment Analysis
1) Data scrapping: Using Beautiful Soup, I scrapped data from the youtube channel.
2) Preprocessing: Removing tags, frequent words and creation of POS tagging tree.
3) Analytics: Using Wordnet to get words with weights on Sentiments. Profanity words and Synonymns. We created chain of words often used together. We also tried Bigram and Trigram.
4) Modelling We performed followin modelling techniques:
a) Support Vector Machine
b) Random Forest
c) Bigram and Trigram Decision Trees.


Wrong Artwork
-
MrG5UK
Hi,
I'm a very happy user of Synergy for many years now. I have one little thing that's bugging me... Can Synergy be made to get it's artwork from iTunes rather than the internet? Now that iTunes gets it's own artwork Synergy to oftern comes up with different artwork. There appears to be no way to change the artwork in Synergy once it's downloaded something. How do I change/delete it? I tend to mostly copy artwork from Amazon into iPhoto then paste into iTunes as iTunes doesn't come up with the right artwork as it gets it from the US iTunes store.
Your thoughts appreciated,
Yours
Chris
-
Greg Hurrell
https://wincent.com/a/products/synergy-classic/album-covers/
-
MrG5UK
Thanks for the links. Most helpful.
Reply
This topic is now closed.


Chapter 10. Security
Keeping
MySQL secure is critical to maintaining the integrity and privacy of
your data. Just as you have to protect Unix or Windows login
accounts, you need to ensure that MySQL accounts have good passwords
and only the privileges they need. Because MySQL is often used on a
network, you also need to consider the security of the host that runs
MySQL, who has access to it, and what someone could learn by sniffing
traffic on your network.
In this chapter we'll look at how
MySQL's permissions work and how you can keep
control of who has access to the data. We'll also
consider some of the basic operating system and network security
measures you can employ to keep the bad guys out of your databases.
Finally, we'll discuss encryption and running MySQL
in a highly restricted environment.
|


{% extends "admin/base_site.html" %} {% load i18n static %} {% block content %}
{% blocktrans trimmed with username=user.username %} The following link can be used to reset the password of user {{ username }}: {% endblocktrans %}
{% blocktrans trimmed with username=user.username %} This link can be sent directly to the user (e.g. by email). It's only usable once, and it expires in {{ timeout_days }} days. {% endblocktrans %} {% endblock %}


|
Maybe you want your system to behave differently at specific periods in the application's execution.
You can define different states the application may be in. You would have to define the conditions
that change the system from one state into the next. These systems have a predefined number of states
and hence are called Finite State Machines.
A system may have multiple Finite State Machines. Finite State Machines may be nested. If a state
is entered, it may mean you enter an initial state of the inner state machine as well.
The State defines the way the system acts at a certain time.
The State Transition defines when the system may change from one state into the next and what
immediate actions are taken at the time of the transition. A state transition must be defined for
every allowable transition between any two states.
Examples
- A coffee machine is the archetypal state machine.
- Games.
When should you use it?
Use a Finite State Machine architecture when your system should not perform the same behaviour all the time,
and there are a finite number of states the system can be in.
How does it work?
The state machine starts in some initial state. Every execution cycle or control cycle the following two
steps are executed:
- The state-specific code of the current state is executed.
- For every state transition starting from this state, the conditions are checked.
If all conditions match, the system changes to the new state.
When the system changes state, three types of code may be executed (in this order):
- Exit code, code belonging to the state that is exited.
- Transition code, code that belongs to a specific transition.
- Enter code, code that belongs to the state that is entered.
Remarks:
- If multiple transitions are possible in a single cycle, only one (the first encountered) should be chosen.
- The transition code, enter code, and exit code,
should be very short pieces of code. They should
be executed in the same execution cycle. It may not be possible that this code takes so long that
the state machine changes to a different state while this code is executed. If it does, a new state
should be created for it.
In a hierarchical state machine a state B may itself be described by an entire state machine.
A hierarchical state machine allows for three kinds of state transitions not found in simple
state machines:
- Entering a state machine.
E.g. State A -> State B1. State B has become the active state
in the outer state machine. If a state machine becomes active, it automatically places itself
in its initial state, which is B1 in this picture.
The exit code of A is executed,
followed by the transition code of the transition A->B,
followed by the enter code of B,
followed by the enter code of B1.
- The outer state machine leaves the state containing the inner state machine.
E.g. State B -> State C.
The conditions for the transition B->C match, so the outer state machine changes state. Any state
the inner state machine might have had is lost.
The exit code of the inner state is executed,
followed by the exit code of B,
followed by the transition code of the transition B->C,
followed by the enter code of C.
- The inner state machine's state changes to the outer state machine's state.
E.g. State B5 -> State D.
The conditions for the transition B5->C match, so state B is left and state C is entered.
The exit code of B5 is executed,
followed by the exit code of B,
followed by the transition code of the transition B->D,
followed by the enter code of D.
It is even possible to have more than one Finite State Machine in a single state. These all become
active whenever the super state becomes active. This creates the problem of what should happen when
a state transition of an inner state to a new outer state becomes possible.
The outer state is only really left (execution of transition code) when all inner state machines
can transfer into the same outer state in the same cycle.
Special state transitions:
- Conditionless transitions. A conditionless transition is always performed immediately.
In the previous picture the transition B5->D would likely be conditionless. It is the endstate
of the inner state machine, so there's no use remaining in this state.
- Timeouts. A transition may occur after some predefined time has elapsed.
Your system may also have a number of Finite State Machines, each used for a different job.
It is entirely possible that transition code of one FSM sends an event to another FSM,
which changes its state.
Advanced state machines may keep track of how much time was spent in each state, if a state is entered
for the first time, log changes for debugging, etc.
Common implementation techniques
- The identifier of the state can be an enumeration type or the name of the state.
Links
|
|


Sodium Hexametaphosphate [SHMP] (E452i) is a sequestrant, which allows gelling agents to be hydrated at much lower temperatures. It is the highest performing sequestrant available. And unlike sodium citrate, it has no taste at the concentrations used for gel hydration.
To start, sodium hexametaphosphate (SHMP) is a hexamer of composition (NaPO3)6.Sodium hexametaphosphate of commerce is typically a mixture of polymeric metaphosphates, of which the hexamer is one, and is usually the compound referred to by this name. It is more correctly termed sodium polymetaphosphate. It is prepared by melting monosodium orthophosphate, followed by rapid cooling.
Sodium hexametaphosphate (SHMP) is used as a sequestrant and has applications in a wide variety of industries, including as a food additive in which it is used under the E number E452i. Sodium carbonate is sometimes added to SHMP to raise the pH to 8.0-8.6, which produces a number of SHMP products used for water softening and detergents. Also used as a dispersing agent to break down clay and other soil types.
Sodium Hexametaphosphate is widely used as Water softener, emusifier and viscosity regulator in various other industries.
Shipping items: Shipping items will be delivered by international express like EMS, TNT, UPS, FedEx or DHL after receiving received. Every item will be shipped out in 1-2working days after the payment is done. The product usually arrives in 1-4 days based on the different destination, and online track is provided. Please kindly supply the shipping address, contact and tel number for successful shipment.
Price: Please let us know the quantity you required, because for small order and bulk purchase, the price will be difference.
Payment: Western Union, MoneyGram We will supply the receiver's information or the bank account information for payment use.


Sage
Black Flash
Nonstandard
Jujutsu Koshien
The Origin of Blind Obedience
The Origin of Blind Obedience - 2
Accomplices