Slots

← Documentation
STRVCT

The property system: declaration, slot annotations, runtime type checks, lifecycle hooks, and metadata consumers.

Overview

Slots are Strvct's property system. In traditional JavaScript objects, instance fields are simple key-value pairs without metadata. In Strvct, declaring a property as a slot transforms it into a rich metadata carrier that each framework layer reads independently.

Slot Declaration newSlot("name", "Thorin") UI Layer Auto-generates Property Tiles Storage Layer Serializes shouldStoreSlot AI Agent Surface Generates JSON tool schemas Slots decouple business logic from UI, persistence, and AI tools; declare metadata once, every layer benefits automatically.

Declaration Syntax & Slot Maps

Slots are declared inside initPrototypeSlots() during class registration. Declaring a slot installs a private variable (_slotName), an auto-generated getter (slotName()), and an auto-generated setter (setSlotName(value)) on the class prototype.

Each class prototype maintains two slot maps:

  • slotsMap(): Map of slots defined directly on this specific class.
  • allSlotsMap(): Map of all slots from this class and every ancestor class, accumulated down the prototype chain.
(class Character extends SvStorableNode {

    initPrototypeSlots () {
        {
            const slot = this.newSlot("name", "");
            slot.setSlotType("String");
            slot.setShouldStoreSlot(true);   // Included in IndexedDB record rows
            slot.setSyncsToView(true);       // Posts didChangeSlot notification
            slot.setCanEditInspection(true); // Editable field in Property Inspector
        }
        {
            const slot = this.newSlot("ownerNode", null);
            slot.setIsWeak(true);            // WeakRef memory safety
            slot.setSyncsToView(true);
        }
    }

}.initThisClass());

Complete Annotation Setters Table

Setter MethodDefaultPurpose / Subsystem Consumer
setSlotType("String")"Object"Controls type validation, form field input type, and LLM JSON schema generation.
setIsWeak(true)falseHolds value via WeakRef to prevent retain cycles in parent/owner back references.
setIsLazy(true)falseDefers initialization or loading until the first getter call.
setShouldStoreSlot(true)falseInstructs SvObjectPool to include property in serialized IndexedDB record rows.
setIsInCloudRecord(true)trueWhen set to false, retains property in local IndexedDB but strips it from cloud commits.
setSyncsToView(true)falseEmits "didChangeSlot" notification via SvNotificationCenter upon mutation.
setCanEditInspection(true)falseExposes field for direct editing in the modifier-click (Option+Click) Property Inspector.
setIsSubnode(true)nullAdds slot value automatically to parent's subnodes array during finalInit().
setIsSubnodeField(true)nullGenerates a navigable field tile (SvField) in the UI inspector hierarchy.
setFinalInitProto(ClassName)nullAuto-instantiates default child objects during finalInit() if absent from storage.
setIsBlobString(true)falseLong text slot whose payload spills to a SHA-256 text blob in storage.
setIsPromiseWrapped(true)falseAuto-wraps getter return values in a Promise for async interface operations.
setDuplicateOp("duplicate")"nop"Cloning policy when duplicating nodes ("nop", "copyValue", "duplicate").
setValidValues([a, b])nullRestricts values to an allowed set, rendering dropdown options in the UI.
setAllowsNullValue(true)falseRelaxes runtime validation to permit null slot values.
setTranslationContext("ui")nullDeclares i18n category for auto-translating string values.

Slot Constructor Variants

  • newSlot(name, defaultValue): Standard slot constructor with auto getter and setter.
  • newWeakSlot(name, defaultValue): Creates a slot holding a WeakRef. The getter unwraps the weak reference automatically; the setter wraps new values in WeakRef. Prevents retain cycles in parent-child back references.
  • newSubnodeFieldSlot(name, Class): Convenience constructor for navigable subnode field properties.
  • overrideSlot(name, defaultValue): Overrides a slot inherited from a superclass, preserving metadata while changing the default value.

Slot Change & Getter Hooks

Auto-generated getters and setters execute optional lifecycle hooks on the owning object if defined:

(class Character extends SvStorableNode {

    initPrototypeSlots () {
        {
            const slot = this.newSlot("inventory", null);
            slot.setSlotType("Inventory");
        }
    }

    // Optional lazy initialization hook called BEFORE getter returns value
    willGetSlotInventory () {
        if (!this._inventory) {
            this.setInventory(Inventory.clone());
        }
    }

    // Optional hook called BEFORE setter updates value
    willUpdateSlotInventory (oldVal, newVal) {
        console.log("Inventory changing from", oldVal, "to", newVal);
    }

    // Optional hook called AFTER setter updates value
    didUpdateSlotInventory (oldVal, newVal) {
        this.recalculateTotalWeight();
    }

}.initThisClass());

Runtime Type Checking

Auto-generated setters enforce runtime type checks against setSlotType(). When a type mismatch occurs (e.g. attempting to pass a string to a Number slot), the setter logs a warning and attempts safe type coercion (e.g. Number("12")), protecting object graph state from corrupt data.