Type-safe global store
Your store is shaped by creating a Store Schema. This Schema specifies the types and default values of store entries.Base store components are created using this Schema. This is boilerplate that you do not need to change.import {type ComponentPropsBase, type ComponentStateConstraint,registerStore, BaseSimpleStoreComponent, BaseStatefulStoreComponent} from 'tungsten'// define a store schema, specifying entry types and default valuesclass StoreSchema {username: string = 'Bob'profilePicture: string = '/images/profile-picture.jpg'}
The registerStore call in the code above passes the Schema to Tungsten, which creates the store. Each entry in the schema becomes an object with 4 methods. A simplified version of an entry object looks like this (typed, but types not shown):import {type ComponentPropsBase, type ComponentStateConstraint,registerStore, BaseSimpleStoreComponent, BaseStatefulStoreComponent} from 'tungsten'import { StoreSchema } from './StoreSchema.js'const getStore = registerStore(StoreSchema)export abstract class SimpleStoreComponent<Props extends TungstenComponentPropsBase = object,RouteData = undefined> extends BaseSimpleStoreComponent<Props, RouteData, StoreSchema> {store = getStore(this)}export abstract class StatefulStoreComponent<Props extends TungstenComponentPropsBase = object,State extends TungstenComponentStateConstraint = object,RouteData = undefined> extends BaseStatefulStoreComponent<Props, State, RouteData, StoreSchema> {store = getStore(this)}
Once we have the store schema and base class defined, we can easily create a new component with store accessentry: {#value: initialValue,#subscribers: [],get = () => #value,set = (newValue) => {#value = newValuenotifySubscribers(subscribers)},subscribe = () => {#subscribers.push(callingComponent)},sync = () => {#subscribers.push(callingComponent)return #value}}
By usingimport { SimpleStoreComponent } from '../StoreComponents.js'export class Profile extends SimpleStoreComponent {content = () => <section><img src={this.store.profilePicture.sync()} /><br /><span>{this.store.username.sync()}</span></section>style = Sass`imgheight: 4em`}
we get the current values for those store entries, and also cause the Profile to update with the new values if they are changed. Here is a demo.this.store.profilePicture.sync()this.store.username.sync()
import { BindableInput } from 'tungsten'import { SimpleStoreComponent } from '../StoreComponents.js'export class UpdateProfile extends SimpleStoreComponent {username = this.store.username.get()update = () => this.store.username.set(this.username)content = () => <section><label htmlFor='username'>Update Username:</label> <BindableInput name="username" bind={[this as UpdateProfile, 'username']} /><br /><button onClick={this.update}>Update</button></section>}
<Profile /><br /><UpdateProfile /><br />

Bob