Branch: fix/loader-merge-window-wilco
Summary
loader.js uses if (!window.wilco) to guard initialization. If any script sets window.wilco before the loader runs, the entire public API is silently skipped, breaking the component system.
Goal
Provide a stable, well-defined API surface on window.wilco that is closed for modification, open for extension.
Solution
Immutable core API via Object.defineProperty
Core functions are defined as non-writable, non-configurable properties on window.wilco. This ensures the loader is always the source of truth for the component system, regardless of script loading order.
Core API functions (immutable):
renderComponent
loadComponent
updateComponentProps
useComponent
Extension mechanism
The window.wilco object remains extensible (not frozen). Users can add custom properties freely:
// Before or after loader.js — both work
window.wilco = window.wilco || {}
window.wilco.refreshAllPreviews = () => { /* custom logic */ }
User-defined extensions are preserved when the loader initializes. Only core API names are protected.
Error policy
Attempting to overwrite a core API function throws TypeError in strict mode (standard JS behavior for non-writable properties). In non-strict mode, the assignment is silently ignored.
Auto-initialization guard
A dedicated __wilcoInitialized flag prevents DOMContentLoaded / initialize() from firing more than once (handles duplicate <script> tags).
Key points
- Script loading order no longer matters
- Core API is always available and cannot be accidentally overwritten
- User extensions are preserved across initialization
Object.defineProperty with writable: false, configurable: false for core functions
Window.wilco type includes core API + index signature for extensions
- All public APIs documented
Testing scenarios
- No pre-existing
window.wilco: API created normally
- Pre-existing
window.wilco with user extensions: Extensions preserved, core API added
- Attempt to overwrite core API: TypeError in strict mode
- Core API is non-configurable:
Object.defineProperty on core function also throws
- Duplicate
<script> tags: Auto-init runs only once
- Extension added after loader: Works, object is extensible
Branch: fix/loader-merge-window-wilco
Summary
loader.jsusesif (!window.wilco)to guard initialization. If any script setswindow.wilcobefore the loader runs, the entire public API is silently skipped, breaking the component system.Goal
Provide a stable, well-defined API surface on
window.wilcothat is closed for modification, open for extension.Solution
Immutable core API via
Object.definePropertyCore functions are defined as non-writable, non-configurable properties on
window.wilco. This ensures the loader is always the source of truth for the component system, regardless of script loading order.Core API functions (immutable):
renderComponentloadComponentupdateComponentPropsuseComponentExtension mechanism
The
window.wilcoobject remains extensible (not frozen). Users can add custom properties freely:User-defined extensions are preserved when the loader initializes. Only core API names are protected.
Error policy
Attempting to overwrite a core API function throws
TypeErrorin strict mode (standard JS behavior for non-writable properties). In non-strict mode, the assignment is silently ignored.Auto-initialization guard
A dedicated
__wilcoInitializedflag preventsDOMContentLoaded/initialize()from firing more than once (handles duplicate<script>tags).Key points
Object.definePropertywithwritable: false, configurable: falsefor core functionsWindow.wilcotype includes core API + index signature for extensionsTesting scenarios
window.wilco: API created normallywindow.wilcowith user extensions: Extensions preserved, core API addedObject.definePropertyon core function also throws<script>tags: Auto-init runs only once