Formalizing the many undeclared interface contracts throughout the codebase.
STRVCT has a protocol system for declaring interfaces and verifying conformance at class-registration time. In practice, only a handful of protocols have been formally declared (audio clip, audio clip delegate, drag source, drag destination). The rest of the codebase relies on informal duck-typing -- checking for a method's existence before calling it, or simply assuming it exists based on context.
This means there are many implicit protocols scattered throughout the framework: sets of methods that classes are expected to implement but that have no formal declaration, no early verification, and no central documentation.
These are recurring interface patterns in the codebase that are currently enforced by convention rather than by protocol declarations:
Used by tile views to ask a node whether it accepts a dropped item:
nodeAcceptsDrop(node) -- returns whether the drop is allowednodeDropped(node) -- handles the actual dropCurrently checked with if (node && node.nodeAcceptsDrop) at call sites. A formal SvNodeDropProtocol would make the contract explicit.
The framework uses a delegation pattern in many places beyond audio. Any class that accepts delegates and calls methods on them defines an implicit protocol. Formalizing these as SvThingDelegateProtocol classes would:
Classes that participate in persistence implement methods like recordForStore(), loadFromRecord(), and referencedBlobHashesSet(). Classes that participate in JSON exchange implement serializeToJson() and deserializeFromJson(). These are currently expected by convention -- a formal protocol would verify that a class claiming to be storable actually implements all the required methods.
Node views implement a set of methods for synchronization (syncToNode(), syncFromNode()), lifecycle (prepareToRetire()), and display (postNeedsDisplay()). These expectations are implicit -- a formal protocol would clarify the minimal interface a view must provide.
The work is incremental and non-breaking. Each undeclared protocol can be formalized independently:
Protocol subclass.addProtocol() calls to classes that implement the interface.No existing behavior changes -- the methods already exist on the classes. The protocol declaration simply makes the contract explicit and verifiable.
Protocol.allProtocols() and protocol.implementers() provide runtime introspection of which classes implement which interfaces.This is an ongoing improvement, not a single task. The codebase has dozens of implicit protocols. Formalizing them should happen organically -- when working in an area of the code, identify the implicit contracts and declare them as protocols. Priority should go to contracts that:
Specific informal protocols identified in the codebase, grouped by priority. Each entry lists a suggested protocol name, the methods it would declare, and where the duck-typing checks currently live.
These are core framework contracts implemented by many classes.
SvStorableProtocol -- persistence serialization
recordForStore(store), loadFromRecord(record, store)SvObjectPool.js (lines 1133, 1453, 1477)Array_store, Map_store, ProtoClass_store, Object_store, and 10+ primitive type storesSvJsonSerializableProtocol -- JSON exchange for AI and data transfer
serializeToJson(), deserializeFromJson(json)SvJsonGroup.js (lines 429, 445) via if (value && value.serializeToJson)SvJsonGroup, SvJsonArrayNode, SvJsonDictionaryNode, SvField, SvBooleanField, SvImageNodeSvViewSyncProtocol -- bidirectional model-view synchronization
syncToNode(), syncFromNode()SvSyncScheduler.js (scheduled batch calls)SvNodeView, SvStackView, SvNavView, SvTile, SvTilesView, and 15+ view classesSvFieldRenderingProtocol -- field display and completion state
keyIsComplete(), valueIsComplete(), keyWhiteSpace(), valueCanUserSelect()SvFieldTile.js (lines 397--470) via if (node && node.keyIsComplete)SvField, SvAiResponseMessage, SvConversationMessageImportant contracts with more specialized scope.
SvNodeDropTargetProtocol -- node-level drop acceptance
nodeAcceptsDrop(node), nodeDropped(node)SvTile_dragging.js (lines 99, 116)SvLinkNodeSvBrowserDropHandlerProtocol -- browser drag-and-drop data handling
onBrowserDropChunk(chunk)SvTilesView.js (line 469)SvViewableNode, SvJsonArrayNodeSvBlobTrackableProtocol -- blob reference tracking for garbage collection
referencedBlobHashesSet()SvObjectPool.js (line 1846)SvBlobNode, SvField, SvPointerFieldSvNodeVisibilityProtocol -- visibility lifecycle notification
nodeBecameVisible()SvNodeView.js (line 483)SvNode, SvViewableNodeSvNavSelectionProtocol -- navigation selection changes
didChangeNavSelection()SvTile.js (lines 414, 437)SvStackView, SvTilesViewNarrower contracts or single-implementer interfaces worth formalizing for documentation.
SvTileLinkableProtocol -- tile navigation target
nodeTileLink()SvJsonIdNode.js (lines 185, 232)SvPointerField, SvJsonArrayNode, SvOptionsNode, SvField, SvLinkNodeSvCssVariableProviderProtocol -- node-defined CSS custom properties
cssVariableDict()SvNodeView.js (line 290)SvActivatableProtocol -- tile activation on keyboard/gesture
activate()SvTilesView_keyboard.js (line 185)