Deep technical specifications for class lifecycle, slots, views, persistence, notifications, and build infrastructure.
This document provides a detailed engineering specification of the Strvct framework implementation. It builds directly on the high-level concepts described in the Technical Overview and the architectural foundations in Naked Objects.
Strvct applications are composed of three primary layers: Model, UI, and Storage. The framework eliminates manual "glue" code by embedding structural metadata directly into model objects via Slots and Slot Annotations.
Strvct implements a structured class initialization pattern built on top of standard ES6 class syntax.
Classes are defined inside an IIFE (Immediately Invoked Function Expression) and self-register using .initThisClass():
(class Character extends SvStorableNode {
initPrototypeSlots () {
// Declare instance slots (properties + metadata)
}
initPrototype () {
// Configure class-wide prototype settings
}
init () {
super.init();
// Basic instance initialization
}
finalInit () {
super.finalInit();
// Relationship resolution & post-deserialization setup
}
}.initThisClass());initPrototypeSlots(): Invoked automatically during class registration. Defines slots and annotations on the class prototype. Must never call super.initPrototype(): Sets up prototype-wide default properties (e.g., this.setShouldStore(true)). Must never call super.init(): Called when an object is instantiated (new Class()). Performs basic property initialization. Always calls super.init().finalInit(): Called after an object is fully instantiated or deserialized from IndexedDB. Sets up complex object references and child subnodes. Always calls super.finalInit().Slots are Strvct's property system. Instead of raw instance fields, properties are declared in initPrototypeSlots():
initPrototypeSlots () {
{
const slot = this.newSlot("name", "Default Name");
slot.setSlotType("String");
slot.setShouldStoreSlot(true); // Persists to IndexedDB
slot.setSyncsToView(true); // Emits view update notifications
slot.setCanEditInspection(true); // Editable in Property Inspector
}
{
const slot = this.newSlot("inventory", null);
slot.setFinalInitProto(InventoryNode); // Auto-creates default instance
slot.setIsSubnodeField(true); // Navigable tile in inspector
}
}setSlotType(typeName): Declares expected type (String, Number, Boolean, Array, Object, ClassName). Enforces runtime type checks on setters.setShouldStoreSlot(boolean): Controls whether the slot value is included in serialized JSON records.setSyncsToView(boolean): Triggers change notifications to observing views upon mutation.setCanEditInspection(boolean): Exposes property in the modifier-click (Option+Click) live Property Inspector.setIsSubnode(boolean): Adds slot value directly to the parent's subnodes array.setIsSubnodeField(boolean): Generates a navigable field tile in the inspector hierarchy.setFinalInitProto(Class): Auto-instantiates default child objects during finalInit() if no record was loaded from storage.initThisCategory()): Extend existing classes across multiple files without modifying the base definition file (e.g., SvJsonGroup_patches.js adding applyJsonPatches() to SvJsonGroup).NameProtocol): Define required interface method stubs inheriting from Protocol to enable runtime interface compliance checks.The domain model is an object graph inheriting from SvNode. Every node contains:
subnodes: An ordered, unique collection of child SvNode objects.parentNode: Reference to the parent SvNode.title / subtitle: String properties displayed in summary tiles.puuid: Persistent unique identifier string.setIsSubnode(true)): Permanent parent-child ownership relationships where child nodes are stored directly inside the parent's subnodes array and persisted together.setIsSubnodeField(true)): Properties where value state remains in a slot on the parent node, but a navigable field tile (SvField) is generated in the UI for inspecting child subnodes.The view system uses a deep, single-inheritance hierarchy where each layer adds a isolated capability:
SvElementDomView (Wraps DOM element, enables alternative render backends)
└─ SvCssDomView (Manages inline CSS styles and class list)
└─ SvSubviewsDomView (Manages child view hierarchy)
└─ SvListenerDomView (Event listener attachment)
└─ SvVisibleDomView (Viewport visibility tracking)
└─ SvGesturableDomView (Gesture recognizers: tap, pan, swipe, long-press)
└─ SvResponderDomView (Focus management & keyboard navigation)
└─ SvControlDomView (Target/Action pattern for control triggers)
└─ SvStyledDomView (State-based style states: selected, active, disabled)
└─ SvNodeView (Binds model SvNode to DOM presentation)The UI is rendered using nested Miller Column container views:
SvStackView: Core navigation container. Contains a SvNavView (master column) and otherView (detail area). Automatically collapses on mobile viewports into a push/pop stack with breadcrumbs.SvBrowserView: Top-level application shell extending SvStackView with header breadcrumb navigation.SvNavView: Single navigation column containing header, scrollable SvTilesView, and footer.SvTilesView: Scrollable container for SvTile items. Handles keyboard cursor selection, drag-and-drop, and reordering gestures.SvTile: Visual presentation of a single model node or property slot.SvPersistentObjectPool)Application data is stored locally in IndexedDB as object pools (one pool per document):
poolId + puuid (Persistent UUID).{ "*": puuid } (near references within the same document pool).{ "**": poolId } (far references to external document roots, loaded asynchronously).setShouldStoreSlot(true) invokes didMutate(), marking the node dirty.instanceFromRecordInStore() instantiates a blank object, invokes init(), populates slot state via loadFromRecord(), and executes finalInit() to reconnect object references.SvBlobPool): Large binary assets (images, audio, files) are stored in a content-addressable store keyed by SHA-256 hash. Records store hash references rather than binary payloads.Strvct provides loose coupling across layers using three notification utilities:
SvNotificationCenter: Asynchronous notification dispatch. Nodes post named notifications; observing views register to handle them.SvSyncScheduler: Coalesces multiple notification method invocations in one event loop into a single UI sync pass.SvBroadcaster: Immediate, synchronous event broadcast for high-frequency internal events.Strvct avoids standard ES module imports and Webpack/Vite bundlers, using a custom Content-Addressable Memory (CAM) build system:
ImportsIndexer (Build Time): Recursively walks _imports.json files to discover source files and dependency order. Outputs:_index.json: Metadata catalog mapping resource paths to SHA-256 content hashes._cam.json.zip: Zip-compressed content bundle keyed by SHA-256 hash.SvResourceManager & SvHashCache (Runtime):_index.json on app boot.SvHashCache._cam.json.zip in one HTTP request.eval() with embedded sourceURL comments for complete DevTools debugging support.