Develop into master (v1.9.1)#656
Conversation
The JSON export from the map search wrote only `data.features`, but the Tina timeline/table/stacked-timeline upload inputs read `data.hits` (via buildTimelineData / buildTableData / buildStackedTimelineData). Uploading an exported file therefore produced an empty events/rows array. Expose `hits` on MapSearchContext and include it alongside `features` in the export payload. The map import still reads `data.features`, so the existing map workflow is unaffected. Also reset the hidden file input's value when the Upload button is clicked in JsonUpload — without this, re-selecting the same file does not fire `change` and subsequent uploads silently do nothing. Closes #645
The export-side fix (previous commit) made uploads round-trip non-empty data into TinaCMS rich-text components, which uncovered several latent render-side bugs that crashed the visual editor on upload. - All five visualization components (Map, Timeline, StackedTimeline, Table, EventsByYear) called hooks both before and after `if (!props.data) return null`. Hook count jumped on the empty-to-data transition, throwing "Rendered more hooks than during the previous render." Hoist hooks above the gate; the existing `data && (...)` render gate already handles the no-data case. - `src/visualizations/Map.tsx` rendered `<LocationMarkers>` without a `layerId`. Peripleo's `GeoJSONLayer` then built layer keys like `layer-undefined-point`, which couldn't be found or moved. Use a stable `useId()` per component instance. - `PlaceInsert` had the same hook-order bug between `useSelectionState` and `useMemo(parseFeature(...))`. Hoist the `useMemo`. - `src/components/Map.tsx` (BaseMap): Peripleo provides a single shared `MapContext` at the app root, so when a post body contains more than one map (e.g. a `<place>` block and a `<map>` block), each PeripleoMap mount overwrites the previous one's `setMap(...)` and `useLoadedMap()` returns the wrong instance for the earlier subtree. Wrap each BaseMap in its own `<MapProvider>` to isolate the context per instance. - BaseMap also defers rendering its layer-adding children behind a new `<WhenStyleLoaded>` gate. Peripleo flips `loaded=true` synchronously the moment a `style` prop is passed to `<PeripleoMap>`, even though MapLibre hasn't finished parsing the style. The first effect inside `<GeoJSONLayer>` then reads `map.getStyle().layers` against an undefined style and crashes. Wait for `isStyleLoaded()` or the `styledata`/`load` events before mounting the children.
Map exports include Algolia-style `_highlightResult` and `_snippetResult` fields on each hit, whose `value` strings contain HTML-pre-escaped snippets like `"`. TinaCMS's MDX attribute serializer encodes `"` as `"` but does not encode `&`, so any `"` in saved JSON round-trips to an unescaped `"` on read, terminating JSON strings mid-value and crashing `JSON.parse(props.data)` in the post iframe. - `buildMapData` now strips `_highlightResult`, `_snippetResult`, and `_rankingInfo` from each hit. These fields are not used by any visualization renderer; removing them eliminates the entity-encoded text from the saved payload and also shrinks stored map data by ~3x. - All five visualization components (Map, Timeline, Table, StackedTimeline, EventsByYear) now parse `props.data` through a shared `parseVisualizationData` helper that catches JSON.parse errors and returns null. The existing render gate then renders nothing instead of letting an uncaught SyntaxError crash the editor iframe — keeping any future encoding edge case (or legacy corrupted data) from taking down the visual editor. Posts saved before this fix retain the corrupted attribute data on disk and must be re-uploaded after redeploy.
`includeTimeline` controls two things: whether the schema registers the `<timeline>` block, and whether `TimelineInput` accepts an upload from a given search. Both need `buildTimelineData` to actually return events, which requires `search.timeline.event_path` to extract events from each hit. The old check (`!_.isEmpty(config.timeline)`) treated any non-empty `timeline` object as "supports the embed", including searches that only set `timeline.date_range_facet` for the search-UI timeline filter. Such searches would let users upload an export but render zero events, since `getNestedValue(hit, undefined)` returns undefined. Tighten the check to require a non-empty `event_path`. The search-UI timeline (gated on `date_range_facet` in `Header.tsx`/`TimelineView.tsx`) is unaffected.
…export-645 Fix JSON-embed round-trip in posts: search export → TinaCMS upload → rich-text render
Removing a <map> embed in the TinaCMS visual editor crashed the whole editor and lost unsaved edits. The post body renders every embed via TinaMarkdown in a client:only island with no error handling, so a MapLibre teardown throw during unmount (map.removeImage read against an already-removed style, in a passive-effect cleanup) propagated to the React root and unmounted it — blanking both the preview and the form. Wrap the body in a PostEmbedErrorBoundary. React routes commit-phase errors to the nearest mounted ancestor boundary, so the editor stays mounted, edits are preserved, and the body shows a fallback that recovers on the next edit (resetKeys). The boundary wraps the whole body because a boundary inside a removed block can't catch its own teardown. The underlying throw is in @peripleo/maplibre teardown and predates PR #646 (reproduces with and without the per-instance MapProvider); the permanent fix is an upstream guard on the layer/image cleanup. Closes #647
The error boundary kept the editor alive but left the post body on the fallback until the next edit, which reads as "did I break it?". Two follow-ups: - Auto-retry: on catch, schedule a single deferred retry (one per burst, capped) so the preview re-renders itself once the teardown throws settle. Removing a map throws several times in one synchronous burst (the removed map plus index-keyed siblings that remount), so the retry is deferred to a macrotask and de-duplicated; the cap counts bursts, so a genuine render-phase loop still stops instead of escalating to a root unmount. The retry only re-renders from current content and never touches form state, so edits are never lost. - Context-aware fallback copy: the fallback is only really hit inside the visual editor, so show a reassuring "your edits are safe" message there and a neutral one on a normally-loaded published page.
…-crash-647 Contain post-embed crashes so removing a map doesn't kill the editor
❌ Deploy Preview for atlas-project-staging failed. Why did it fail? →
|
❌ Deploy Preview for cabildo-de-regla failed. Why did it fail? →
|
✅ Deploy Preview for juel-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for pss-scavenger-hunt ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for juel-life ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for juel-ancestry ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
* WIP * keep consistent layer ID for full view * add interactive prop * WIP trying to fix Peripleo state race condition * working, but hacky * arc improvements * map styles * revert config * state management and a11y fixes * upgrade to production RC
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
* rename config file * add to gitignore * also remove tina-lock * actually put tina-lock back for now * use example config as source by default
* add overlay option to Tina for paths * much better way to fetch list of layers
Place.tsx read feature.properties.originalProperties.certainty_radius
without optional chaining. When a place's place_geometry.properties is
null (e.g. Nodegoat-migrated data, vs the {} other sites produce),
originalProperties is null and clicking the result threw an uncaught
TypeError that crashed the search map. Matches the optional-chaining
already used in BasePanel, PlaceMap, and the library's getFeatures.
…radius-null Guard null place_geometry.properties in place map panel
* WIP * custom map colors
* show all geometry on zoom paths * null check place UUID * update RC to prod
✅ Deploy Preview for relnet-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
* open and initial values config for timeline * fix field name
Repo had no Dependabot config, so it used GitHub defaults: one PR per advisory, unbatched. Group security updates into a single weekly PR per ecosystem and turn off version-bump PRs.
The map-based search renders result points but never moves the camera:
it doesn't zoom to the result set on load, and clicking a result doesn't
pan/highlight it. The map sits at world view, so selections look like
no-ops.
Root cause: `Map` wraps `PeripleoMap` in its own nested `MapProvider`
(added to isolate multiple maps in a post body). `MapView` and
`MapSearchContext` render above `Map` and read the map via
`useLoadedMap()` against the root `MapProvider` supplied by `Peripleo`.
After the nested provider was introduced, `PeripleoMap` registers the map
into the inner context, so those ancestors get `null` forever. As a
result `MapSearchContext.getBoundingBox()` early-returns without resolving
and `MapView`'s fit effect guard is never satisfied. Result layers still
render because they are children of `Map` and see the inner context.
Add an `isolate` prop to `Map` (default `true`, preserving the
multiple-maps-in-a-post behavior) and set `isolate={false}` for the search
map so it registers into the root provider that its ancestors read.
Removes [protobufjs](https://github.com/protobufjs/protobuf.js). It's no longer used after updating ancestor dependency [posthog-js](https://github.com/PostHog/posthog-js). These dependencies need to be updated together. Removes `protobufjs` Updates `posthog-js` from 1.360.2 to 1.388.2 - [Release notes](https://github.com/PostHog/posthog-js/releases) - [Changelog](https://github.com/PostHog/posthog-js/blob/main/CHANGELOG.md) - [Commits](https://github.com/PostHog/posthog-js/compare/posthog-js@1.360.2...posthog-js@1.388.2) --- updated-dependencies: - dependency-name: protobufjs dependency-version: dependency-type: indirect - dependency-name: posthog-js dependency-version: 1.388.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
✅ Deploy Preview for marronage-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
* add properties field to Tina * update tina lockfile
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 6.4.3. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.4.3/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.4.3 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [uuid](https://github.com/uuidjs/uuid) from 11.1.0 to 14.0.0. - [Release notes](https://github.com/uuidjs/uuid/releases) - [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md) - [Commits](uuidjs/uuid@v11.1.0...v14.0.0) --- updated-dependencies: - dependency-name: uuid dependency-version: 14.0.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [axios](https://github.com/axios/axios) from 1.12.2 to 1.17.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.12.2...v1.17.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.17.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.2 to 5.8.1. - [Release notes](https://github.com/sveltejs/devalue/releases) - [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md) - [Commits](sveltejs/devalue@v5.6.2...v5.8.1) --- updated-dependencies: - dependency-name: devalue dependency-version: 5.8.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.0.16 to 4.1.0. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.0/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.1.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [shell-quote](https://github.com/ljharb/shell-quote) from 1.8.3 to 1.8.4. - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](ljharb/shell-quote@v1.8.3...v1.8.4) --- updated-dependencies: - dependency-name: shell-quote dependency-version: 1.8.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to 4.0.6. - [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md) - [Commits](form-data/form-data@v4.0.5...v4.0.6) --- updated-dependencies: - dependency-name: form-data dependency-version: 4.0.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Add Dependabot config to batch security updates
- Node 20.x → 24.x (matches .node-version) - Replace the Keycloak SSO section with Clerk SSO (the only deployed-auth path as of v1.9.0; Keycloak + tinacms-authjs were removed) - Remove the content/users/index.json seeding step (native TinaCMS users were removed in v1.9.0)
* WIP cleanup * i18n cache * WIP * fixes * package cleanup * remove duplicate Tailwind dependency * bump Typescript * more dependency cleanup * remove uuid * fix env loading for deployed sites
* upgrade tina * try caching Tina responses * remove logging
* more upgrades * fix db-provider * revert abstract-layer upgrade * replace level thing with tina's own mongodb-level * fix import * fixes
* possible fix for Tina * debug logging in rebuild * set active org on Tina login * remove debug logging
✅ Deploy Preview for padp-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Bumps the npm-security group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@smithy/config-resolver](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/config-resolver) | `4.0.1` | `4.6.4` | | [rollup](https://github.com/rollup/rollup) | `3.29.5` | `3.30.0` | | [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `4.4.1` | `removed` | | [immutable](https://github.com/immutable-js/immutable-js) | `3.7.6` | `5.1.9` | | [protocol-buffers-schema](https://github.com/mafintosh/protocol-buffers-schema) | `3.6.0` | `3.6.1` | Updates `@smithy/config-resolver` from 4.0.1 to 4.6.4 - [Release notes](https://github.com/smithy-lang/smithy-typescript/releases) - [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/config-resolver/CHANGELOG.md) - [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/config-resolver@4.6.4/packages/config-resolver) Updates `rollup` from 3.29.5 to 3.30.0 - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/v3.30.0/CHANGELOG.md) - [Commits](rollup/rollup@v3.29.5...v3.30.0) Removes `fast-xml-parser` Updates `immutable` from 3.7.6 to 5.1.9 - [Release notes](https://github.com/immutable-js/immutable-js/releases) - [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md) - [Commits](immutable-js/immutable-js@3.7.6...v5.1.9) Updates `protocol-buffers-schema` from 3.6.0 to 3.6.1 - [Commits](mafintosh/protocol-buffers-schema@v3.6.0...v3.6.1) --- updated-dependencies: - dependency-name: "@smithy/config-resolver" dependency-version: 4.6.4 dependency-type: indirect dependency-group: npm-security - dependency-name: rollup dependency-version: 3.30.0 dependency-type: indirect dependency-group: npm-security - dependency-name: fast-xml-parser dependency-version: dependency-type: indirect dependency-group: npm-security - dependency-name: immutable dependency-version: 5.1.9 dependency-type: indirect dependency-group: npm-security - dependency-name: protocol-buffers-schema dependency-version: 3.6.1 dependency-type: indirect dependency-group: npm-security ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Release v1.9.1 — TinaCMS post-embed and map/timeline bug fixes. Non-breaking; no schema or config changes.
In-scope:
timeline.event_pathfor the<timeline>embed; fix MDX attribute round-trip and render-side crashes in map embedsAfter merge: tag
v1.9.1on master, branchreleases/v1.9.1on that commit; write the GitHub release.