@dashkite/compass
v0.7.37
Published
Accessors for hypermedia graphs
Downloads
115
Readme
Compass
Accessors for hypermedia application
Compass provides Scout-like accessors for navigating hypermedia applications. For example, if we want the link to an application state, we simply ask for it.
Example: Navigating to a new state
Neon.event "success", Fn.pipe [
Obj.get "detail"
Compass.link
item: target
state: "success"
browse
]Key Concepts
Compass accessors generally take a specifier for one of the following:
- An application state
- An application state space
- A managed resource
- A managed resource space
| Type / Property | Name | Target | Bindings | | ----------------------: | :--: | :----: | :------: | | application state | ✓ | ✓ | ✓ | | application state space | ✓ | ✓ | | | managed resource space | | ✓ | | | managed resource | | ✓ | ✓ |
These are described further below.
Application State
An application state consists of:
- A name
- A target, which is an application alias for the name of a managed R-space
- Bindings, a dictionary of values which are applied to the R-space to construct a locator
Application State Space
An application state space is a partially specified application state, without bindings. An application spaces references all possible application states for a given name and target.
Managed Resource Space
An managed resource space, or application R-space, is a just the state space without a state name, which represents all the possible states corresponding to the application target.
Managed Resource
When an application resource has bindings, it becomes a managed resource.
API
| Function | Description | | ---------------------: | ------------------------------------------------------------ | | install | Configure Compass with an oracle. | | make | A constructor function take takes an application target or an object shorthand for an item or collection resource and returns a virtual application space | | managed | An accessor that resolves the R-space for a target. | | title | Return the title for the corresponding R-space. | | status | Return a description of a given state (ex: empty) for the corresponding R-space. | | item | Navigate to the item of a collection R-space. | | collection | Navigate to the collection of an item R-space. | | states | Enumerates the state states that are (directly) accessible from a given state. | | state | Describes a specific application state. | | prompt | Return the prompt corresponding to the transition to a given state. | | link | Generate a link corresponding to the transition to a given state. | | supported, unsupported | Is a given state supported by the corresponding managed resource. | | visible, hidden | Is the given state hidden by the application definition. | | allowed, disallowed | Determine whether a given transition is accessible to the current session. |
Application Oracle
The application oracle provides an interface to the client environment. It must implement four functions.
| Function | Description | | ----------: | ------------------------------------------------------------ | | managed | Returns the R-space for a given A-name. | | application | Returns the application state definition for a given A-name. | | link | Given a state name, an A-name, and a bindings object, constructs a link path. | | allowed | Given a locator and a list of methods, returns a promise resolving to true if the methods are allowed and false otherwise. |
The install function takes an oracle object as a configuration option:
Compass.install oracle: { managed, application, link, allowed }Item And Collection Shorthand
The object form is a shorthand for accessing the collection or item edges by providing an object with the corresponding property whose value is an A-name. For example, to construct the item navigator for a given collection, we’d write:
Compass.make collection: anameImportant: The create action is accessible via the item edge. That’s because we’re creating items, not collections.
Object Currying
The high-level accessors are object-curried over the bindings property. Object-currying is a term I just made up to describe currying properties instead of arguments. In effect, it treats an object as a set of keyword arguments. Object-currying over a property means we’re only currying that property. Which is also a thing I just made up.
In this case, Compass can provide generator functions without expandng its interface. Consider again our success handler above: we’re object-currying the link function.
State And States
Perhaps surprisingly, we don’t seem to need accessors to describe a state or states. The application already knows which actions it’s interested in (because it must render the necessary controls), so we just need to know if they’re available. However, the state and states functions are provided in case they’re needed.
Examples
Let’s consider a few examples of how we might use this interface. Here’s a function to a render a link to a state:
link = ( state ) ->
if await Compass.available state
HTML.p [
HTML.a href: ( Compass.link state ),
Compass.prompt state
]Let’s consider another example, where we have to generate the component tags for items in a collection. Here we assume a Render.component helper exists, similar to the link helper above.
if items.length > 0
HTML.ul Arr.compact do ->
for item in items
element = await Render.component {
name: "summarize"
item: target
bindings
}
if element?
HTML.li [ element ]
else
HTML.p Compass.status "empty", {state: "view", target }