Skip to content

Layer time can be open-ended ("now") and granularity-aware - #337

Open
BhattaraiSijan wants to merge 5 commits into
developmentfrom
feat/open-ended-layer-time
Open

Layer time can be open-ended ("now") and granularity-aware#337
BhattaraiSijan wants to merge 5 commits into
developmentfrom
feat/open-ended-layer-time

Conversation

@BhattaraiSijan

@BhattaraiSijan BhattaraiSijan commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Closes #332 (part of epic #331)

Summary

Time-enabled layers could only declare fixed data start/end timestamps — but for growing collections the end is unknowable at authoring time, so every config went stale the day after it was written. A layer's dataStartTime/dataEndTime may now be a policy re-evaluated on demand: now, or now ± <ISO-8601 duration> (now - P1D, now + P5D). Concrete datetimes behave exactly as before.

Per veda-ui (our semantics standard), now resolves to the raw current moment — never rounded.

Core owns this vocabulary. The config keeps what the author wrote; core resolves it behind one provider, layers:getTemporalExtent, which answers { start, end } as plain ISO datetimes (or null) — for one layer by id, or for all layers keyed by UUID, in the same call shapes as layers:getCogCapabilities and layers:getBounds. It resolves at the moment of asking, so an open-ended now is always fresh. A plugin never sees a policy string and never imports a resolver.

Granularity (interval) and periodicity (isPeriodic) were originally declared on the bus contract here as carried facts. Nothing in this PR writes or reads them, so they land with #338's VEDA source instead, which is what actually produces them. The time block's index signature already allows both, so no consumer is blocked in the meantime.

Commits

  1. The resolver — one pure function: policy string in, resolved ISO datetime out, null for anything unparseable so consumers keep their fallbacks and a bad value can never break the UI. Calendar-safe offset math (months/years via UTC date components, not milliseconds).
  2. The Timeline consumes it — the per-layer bar previously hand-parsed dates with an inline 'now' special case on the end only; both ends now resolve.
  3. Resolution moves into core — the resolver relocates to Basics/TimeControl_/layerTimePolicy.ts, beside the mission-level time parser; Layers_ registers layers:getTemporalExtent; the Timeline reads extents from it instead of resolving; _shared/time/ is removed with no re-export. The Layers tool's "set global time to layer extent" action goes through the same path — it previously did new Date("now") and produced NaN for a policy value.

Testing

  • 15 unit specs with an injected clock: all three policy forms, sub-day and calendar-unit offsets, pass-through, every failure mode degrading to null. Full suite green (92 files, 1425 tests); typecheck clean.
  • Verified live: an ongoing layer configured with end now draws its timeline bar reaching the current date (screenshot in Layer time can be open-ended ("now") and granularity-aware #332), while a closed-extent layer's bar correctly stops at its real end — and the now config needs no edits, ever.

Mission-level time (initialstart/initialend) keeps its existing seconds-offset syntax; unifying it with ISO durations is possible future work.

🤖 Generated with Claude Code

…uration offsets)

A layer's dataStartTime/dataEndTime may now be a policy re-evaluated at load instead of a fixed timestamp, so configs for growing collections never go stale. One pure resolver evaluates 'now' and 'now +/- <ISO duration>'; per veda-ui the result is the raw current moment, never rounded. Unparseable values resolve to null so consumers keep their fallbacks. Spec'd with an injected clock. Mechanism half of #332.
The per-layer timeline bar previously hand-parsed data times with an inline 'now' special case for the end only. It now resolves both ends through the time-policy resolver, so open-ended and offset policies render correctly on either end and reach the current moment on every load. The bus layer-config type documents the policy vocabulary plus the carried granularity/periodicity facts (interval, isPeriodic). Completes #332's visible half.
@BhattaraiSijan
BhattaraiSijan marked this pull request as ready for review August 26, 2026 20:14
The Data Start/End Time field descriptions said ISO 8601 datetime only, so an admin had no way to discover that now, or now offset by an ISO 8601 duration, is a legal value. The tile and vector layer forms both say so now. Description text only; no behaviour change. Completes #332's documentation criterion.
Comment thread src/essence/Tools/_shared/adapters/mmgisAPI.ts Outdated
Nothing in this PR writes or reads either field;
The now / now ± duration vocabulary is a core-owned meaning of dataStartTime/dataEndTime. Core resolves it at call time behind one provider; the Timeline plugin reads dates and no longer imports a resolver. The Layers tool's set-to-extent action goes through the same path, which it previously did not (a 'now' produced NaN there).
@BhattaraiSijan
BhattaraiSijan force-pushed the feat/open-ended-layer-time branch from e7760a4 to 111be6a Compare August 28, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layer time can be open-ended ("now") and granularity-aware

2 participants