The property system: declaration, slot annotations, runtime type checks, lifecycle hooks, and metadata consumers.
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.
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());| Setter Method | Default | Purpose / Subsystem Consumer |
|---|---|---|
setSlotType("String") | "Object" | Controls type validation, form field input type, and LLM JSON schema generation. |
setIsWeak(true) | false | Holds value via WeakRef to prevent retain cycles in parent/owner back references. |
setIsLazy(true) | false | Defers initialization or loading until the first getter call. |
setShouldStoreSlot(true) | false | Instructs SvObjectPool to include property in serialized IndexedDB record rows. |
setIsInCloudRecord(true) | true | When set to false, retains property in local IndexedDB but strips it from cloud commits. |
setSyncsToView(true) | false | Emits "didChangeSlot" notification via SvNotificationCenter upon mutation. |
setCanEditInspection(true) | false | Exposes field for direct editing in the modifier-click (Option+Click) Property Inspector. |
setIsSubnode(true) | null | Adds slot value automatically to parent's subnodes array during finalInit(). |
setIsSubnodeField(true) | null | Generates a navigable field tile (SvField) in the UI inspector hierarchy. |
setFinalInitProto(ClassName) | null | Auto-instantiates default child objects during finalInit() if absent from storage. |
setIsBlobString(true) | false | Long text slot whose payload spills to a SHA-256 text blob in storage. |
setIsPromiseWrapped(true) | false | Auto-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]) | null | Restricts values to an allowed set, rendering dropdown options in the UI. |
setAllowsNullValue(true) | false | Relaxes runtime validation to permit null slot values. |
setTranslationContext("ui") | null | Declares i18n category for auto-translating string values. |
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.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());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.
SvNode domain abstraction.