Instances

Internal instance anatomy and orchestration boundaries.

Anatomy at a glance

createInstance({ map, document? }) first validates the consumer-injected map, then normalises input via normaliseInstanceDocument(...), then delegates the resulting canonical InstanceDocument to createInstanceCore(map, ...), which assembles one runtime core for one injected map.

Key components:

ComponentResponsibility
src/entry.jsFactory entry: map duck-type validation, document normalisation, deep-clone, runtime creation.
src/document/instanceDocument.jsCanonical InstanceDocument shape, normalisation, serialisation, and validation.
src/runtime/createInstanceCore.jsRuntime core orchestration, lifecycle, public API assembly, registry behaviour, destroy flow.
src/runtime/runtimeRegistry.jsInternal WeakMap runtime storage keyed by the consumer map (get/set/delete).
src/runtime/createInstanceEvents.jsContainer event bus (on/off/once/emit); events are dispatched on map.getContainer().
src/runtime/state/createInstanceState.jsCanonical runtime-state store (getSnapshot, dispatch, subscribe) and scoped/global state-event emission.
src/config/resolveConfig.jsRuntime config resolution (debug) over defaultConfig.
src/geojson/*GeoJSON overlay internals — type-based render plans (createGeoJSONModule.js), feature interaction events (createFeatureInteractionModule.js). Documented in docs/5.data.md.

Internal orchestration boundaries

Map injection details are documented separately:

core.modules boundary

core.modules in createInstanceCore(...) groups teardown-capable internals:

This grouping is internal lifecycle wiring, not part of the consumer API.

Module state boundaries

Lifecycle order

Create flow:

  1. Validate the injected map (src/entry.js) and normalise the incoming document.
  2. Check the WeakMap registry in src/runtime/runtimeRegistry.js; if the map already has a runtime, throw.
  3. Resolve config (debug) and install the event bus on map.getContainer().
  4. Create the GeoJSON module: build render plans, register load/style.load mount handlers, and wire the feature interaction module (click/mousemove/mouseout).
  5. Create runtime state (createInstanceState(...)) with initial debug and type-visibility state.
  6. Build the InstanceDocument adapter and public API.
  7. Register the runtime against the map in the WeakMap and emit waymark:instance.created on the map container.

Destroy flow:

  1. Mark lifecycle destroyed and emit waymark:instance.destroyed.
  2. Run geoJSON.destroy() (remove Waymark-owned layers/sources, detach load/style.load, destroy the feature interaction module and detach its click/mousemove/mouseout handlers) and debug.destroy().
  3. Delete the runtime registry entry for the map.

The consumer's map and container are never removed or modified by Waymark.

Extension notes

When adding internals to createInstanceCore(...):

For module-level behaviour, update these docs alongside runtime changes: