API Reference
Every function in store.js, html.js, and shell.js.
store.js
createStore(jsonLd, options)
Create a reactive store from a JSON-LD object.
import { createStore } from './losos/store.js'
var store = createStore(data, {
url: 'https://pod.example/data.jsonld', // PUT target
authFetch: window.xlogin.authFetch, // authenticated fetch
debounce: 800 // ms before auto-save
})
| Method | Description |
|---|---|
store.get(id) | Retrieve a node by @id |
store.prop(node, key) | Read a property (fuzzy key match) |
store.propAll(node, key) | Read array property (always returns array) |
store.type(node) | Get @type |
store.set(node, key, value) | Write → dirty → auto-save |
store.unset(node, key) | Delete property → auto-save |
store.push(node, key, value) | Array append → auto-save |
store.remove(node, key, fn) | Array filter → auto-save |
store.reorder(node, key, from, to) | Array move → auto-save |
store.save() | Force immediate PUT |
store.reload() | Re-fetch from URL, notify listeners |
store.onChange(fn) | Subscribe to changes (returns unsubscribe) |
store.toJSON() | Serialize to JSON-LD string |
store.data | The raw JSON-LD root object |
store.dirty | Whether there are unsaved changes |
Fuzzy key resolution
store.prop(node, 'title') matches node['title'], node['dct:title'], or any key ending in :title, /title, or #title. This lets panes work with both short context aliases and full URIs.
html.js
html`...`
Tagged template literal that creates a template object. Use ${} for dynamic values:
import { html, render } from './losos/html.js'
render(container, html`
<h1>${title}</h1>
<button onclick="${function() { alert('clicked') }}">Click</button>
${condition ? html`<p>Shown</p>` : null}
${items.map(function(i) { return html`<div>${i.name}</div>` })}
`)
Supported value types in ${}:
- Strings, numbers → text content
null,false→ renders nothing- Arrays → renders each item
- Nested
html`...`→ nested template - Functions in
on*attributes → event handlers
render(container, template)
First call builds DOM. Subsequent calls with the same template shape patch only the changed ${} values.
keyed(items, keyFn, templateFn)
Efficient list rendering. Matches items by key, reuses DOM, skips unchanged items:
import { keyed } from './losos/html.js'
html`${keyed(
items,
function(i) { return i['@id'] },
function(i) { return html`<div>${i.name}</div>` }
)}`
Items whose template values haven't changed are not re-rendered — their DOM nodes are reused as-is.
ref()
Grab a DOM element after render:
import { ref } from './losos/html.js'
var inputRef = ref()
render(el, html`<input ref="${inputRef}" />`)
inputRef.el.focus()
onUnmount(container, fn)
Call a function when the container is removed from the DOM (e.g., tab switch):
onUnmount(container, function() {
unsub() // unsubscribe from store
audio.pause() // clean up resources
})
innerHTML attribute
Set innerHTML directly in templates:
html`<div innerHTML="${htmlString}"></div>`
shell.js
boot(el, options)
Boot the shell. Called automatically if a #losos element exists.
import { boot } from './losos/shell.js'
boot('#app', {
maxWidth: '100%', // default: '960px'
accentColor: '#e63946' // default: '#7c3aed'
})
Options:
maxWidth— controls tab bar and content container widthaccentColor— active tab underline color
The shell provides built-in tab persistence (namespaced by pathname) and passes parsed JSON-LD as the 4th argument to pane.render().
Pane interface
export default {
label: 'My Pane',
icon: '📋',
canHandle(subject, store) {
// Return true if this pane should show for the data
var node = store.get(subject.value)
return store.type(node)?.includes('MyType')
},
render(subject, store, container, rawData) {
// subject.value = the @id of the primary node
// store = LION store (read-only, for canHandle)
// container = DOM element to render into
// rawData = parsed JSON-LD (use for createStore)
}
}