You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 92eee4d
Browse filesBrowse the repository at this point in the historyBrowse files
`collectFlowGraphs` no longer hands out a `FlowGraph` whose `edges` can hold a non-record — the sibling list #16752's repair did not reach (#18102).
6
+
7
+
`FlowGraph.edges` is declared `readonly FlowEdgeParsed[]`. The walk forwarded it untouched, four lines from the node-side member filter the same walk has carried since #16752, and a nested region's edge list is admitted on `Array.isArray` alone — which proves the LIST and never its MEMBERS. A YAML `edges:` list item left empty deserialises to `null`, and a region its own schema refused is left RAW for `validateControlFlow` to name, so the producer handed out an array holding a member its own declared element type excludes. Measured on `main`:
-**The junk member is DROPPED, per list**, through the same one predicate the node side uses (`isRegionDict`), so the two lists the walk hands out cannot drift from each other. Copy-on-write per list: a well-formed flow is handed back the very same arrays.
15
+
- ⭐ **The real edge beside it is still HANDED OUT**, and so is the node list. "No non-record members" is half a contract — a filter that emptied `edges`, or reached into `nodes`, would satisfy it. Both are pinned.
16
+
-**This is a drop in the producer, not a refusal.** No authoring door's accept set moves: `FlowSchema.safeParse` still returns an envelope rather than throwing, the region `safeParse` refusal in `validateControlFlow` still owns and still reports the malformed region, and `FlowGraph.path` still indexes the RAW node list so a Zod issue stays anchored where the author wrote it. ⛔ Not a looser signature either — the declared element type is unchanged and is now true.
17
+
-**Latent, not live — measured, and not for the reason the filing gave.** There are THREE `graph.edges` consumers on the tree, not two. The two in `packages/lint` coerce through `recordsOf` (#16910). The third is `packages/services/service-automation`'s registration pass, which reads `.id` / `.source` / `.target` straight off each member with no guard, and is shielded only by call ORDER — `validateControlFlow` refuses the malformed region a few frames earlier in `registerFlow`. So no throw is reachable today, by one belt more than was counted. After this change the declared type carries it, and the next consumer needs neither a coercion nor a call-order argument.
18
+
-**`analyzeRegion` is not one of those consumers.** It throws a `TypeError` on a `null` / `undefined` edge member (measured), but nothing routes producer output into it: its in-repo callers hand it post-`safeParse` region data. It reads an edge list, it does not read `FlowGraph.edges`.
19
+
-**No behaviour changes on well-formed metadata.** The only input whose handling moves is input whose declared type already said it could not exist.
`ListMapConfigSchema` now declares `style` — optional `z.string()`, the map style URL the renderer already reads and the schema refused by name (#18406). In the same stroke `object-map`'s `map` prop points at `ListMapConfigSchema` again, retracting the `z.unknown()` that the missing key had forced.
6
+
7
+
`ListMapConfigSchema` is a `strictObject`, and `style` was the one member of the renderer's own documented config surface it omitted. Measured at the `.objectui-sha` pin `53ded82b`: objectui's `ObjectMapConfigSchema` (`packages/types/src/zod/objectql.zod.ts:562`) declares all eight keys, `getMapConfig` reads `schema.mapStyle || schema.map?.style` (`packages/plugin-map/src/ObjectMap.tsx:365`), and objectui's own `content/docs/plugins/plugin-map.mdx:131` documents `style` inside the block. `ListMapConfigSchema.safeParse({ style: 'https://tiles.example/style.json' })` answered `success: false`, so a map style could not be declared through the spec's list-view face at all. Declared here under the director seat's decision batch #153 item 4 letter 1, confirmed by the maintainer verbatim 「其他同意」.
8
+
9
+
**Clause-②: yes (widening)** — one new declared key on a published, strict accept set, so the set a consumer writes against grows. Nothing previously admitted is refused, and nothing is retired. Contract-review tier.
10
+
11
+
-**`style`, not `mapStyle`, and not both.** Mapbox and MapLibre both call a style URL `style`, and that is the name the renderer reads inside the config block. The competing spelling — objectui#5017's dev warning teaching `map: { mapStyle }` — is corrected on the objectui side rather than learned here, and no alias is declared: an alias would be a permanent obligation for a key nobody has written yet.
12
+
-**Not the node-level `style`.** A component node's `style` is `BaseSchema.style`, an inline CSS record; the renderer stopped reading a top-level `style` as a map style at objectui#5017. The component-level `mapStyle` prop is unchanged and still wins when both are present.
13
+
-**`object-map.map` stops being `z.unknown()`.** That posture existed only because pointing the door at a schema missing `style` would have refused a value the renderer honours. With the gap closed, the door takes the spec's own block — so a misspelling inside an authored `map` block is now refused at `map`, by name, instead of passing through an open value. The two pins that recorded the divergence are inverted in the same change.
14
+
-**The generated projections move with it** — `authorable-surface/ui.json` gains `ui/ListMapConfig:style`, and `content/docs/references/ui/view.mdx` plus `content/docs/references/ui/component.mdx` gain the key; the `object-map.map` row in the component reference changes from `any` to the block's real shape and gains a nested-shape table.
Copy file name to clipboardExpand all lines: content/docs/references/ui/component.mdx
+14-1Lines changed: 14 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -640,7 +640,7 @@ View filter rule
640
640
|**staticData**|`any[]`| optional | Inline records — read SECOND by `getDataConfig`, wrapped into a `{ provider: 'value' }` config |
641
641
|**filter**|`{ field: string; operator: Enum<'equals' \| 'not_equals' \| 'contains' \| 'not_contains' \| 'icontains' \| …>; value?: string \| number \| boolean \| null \| (string \| number)[] }[]`| optional | Base query filter — the ViewFilterRule array form `[{ field, operator, value }, ...]`, the one filter orthography every `filter` door in this map shares; lowered to the wire `$filter`. The MongoDB-style record form is refused — see migration `element-data-source-and-object-block-filter-rule-array`|
642
642
|**sort**|`{ field: string; order: Enum<'asc' \| 'desc'> }[]`| optional | Marker order for the fetched records — the SortItem array form `[{ field, order }, ...]`, the one sort orthography every declared `sort` door on this platform shares; lowered to the wire `$orderby`. The legacy string clause (`name desc`) is refused — see migration `object-block-sort-item-array`|
643
-
|**map**|`any`| optional | Map field config, the author face: `{ latitudeField, longitudeField, locationField?, titleField?, descriptionField?, zoom?, center?, style? }`. Taken WHOLE when present — the flat top-level spelling beside it is ignored |
643
+
|**map**|`{ latitudeField?: string; longitudeField?: string; locationField?: string; titleField?: string; … }`| optional | Map field config, the author face — the same block `ListViewSchema.map` declares, and the one the renderer validates this node against. Taken WHOLE when present: the flat top-level spelling beside it is ignored |
644
644
|**mapStyle**|`string`| optional | MapLibre style URL or spec, overriding the public demo tiles. Read before `map.style`; NOT the base node `style`, which is an inline CSS record |
|**enableClustering**|`boolean`| optional | Group nearby markers into clusters. Absent, the renderer clusters only above 100 markers |
@@ -694,6 +694,19 @@ Sort field and direction pair
694
694
|**field**|`string`| ✅ | Field name to sort by |
695
695
|**order**|`Enum<'asc' \| 'desc'>`| ✅ | Sort direction |
696
696
697
+
### Nested Shape: `ObjectMapProps.map`
698
+
699
+
| Property | Type | Required | Description |
700
+
| :--- | :--- | :--- | :--- |
701
+
|**latitudeField**|`string`| optional | Field providing the marker latitude (used with longitudeField) |
702
+
|**longitudeField**|`string`| optional | Field providing the marker longitude (used with latitudeField) |
703
+
|**locationField**|`string`| optional | Field providing a combined location — a "lat,lng" string or a `{ lat, lng }` object — as the alternative to the latitudeField/longitudeField pair |
704
+
|**titleField**|`string`| optional | Field displayed as the marker title (popup heading, mobile record card, and what the map search box matches on) |
705
+
|**descriptionField**|`string`| optional | Field displayed as the marker description |
706
+
|**zoom**|`number`| optional | Initial zoom level (1-20). Omit to let the renderer fit the camera to the queried records |
707
+
|**center**|`[number, number]`| optional | Initial camera center as [latitude, longitude]. Omit to let the renderer fit the camera to the queried records |
708
+
|**style**|`string`| optional | Map style URL — the MapLibre style document the renderer loads in place of the public demo tiles. The component-level `mapStyle` is read FIRST and wins when both are present; this is NOT the inline CSS `style` record a component node carries |
Copy file name to clipboardExpand all lines: content/docs/references/ui/view.mdx
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -775,6 +775,7 @@ Map view configuration
775
775
|**descriptionField**|`string`| optional | Field displayed as the marker description |
776
776
|**zoom**|`number`| optional | Initial zoom level (1-20). Omit to let the renderer fit the camera to the queried records |
777
777
|**center**|`[number, number]`| optional | Initial camera center as [latitude, longitude]. Omit to let the renderer fit the camera to the queried records |
778
+
|**style**|`string`| optional | Map style URL — the MapLibre style document the renderer loads in place of the public demo tiles. The component-level `mapStyle` is read FIRST and wins when both are present; this is NOT the inline CSS `style` record a component node carries |
778
779
779
780
780
781
---
@@ -1023,6 +1024,7 @@ View filter rule
1023
1024
|**descriptionField**|`string`| optional | Field displayed as the marker description |
1024
1025
|**zoom**|`number`| optional | Initial zoom level (1-20). Omit to let the renderer fit the camera to the queried records |
1025
1026
|**center**|`[number, number]`| optional | Initial camera center as [latitude, longitude]. Omit to let the renderer fit the camera to the queried records |
1027
+
|**style**|`string`| optional | Map style URL — the MapLibre style document the renderer loads in place of the public demo tiles. The component-level `mapStyle` is read FIRST and wins when both are present; this is NOT the inline CSS `style` record a component node carries |
1026
1028
1027
1029
### Nested Shape: `ListView.tree`
1028
1030
@@ -1421,6 +1423,7 @@ View filter rule
1421
1423
|**descriptionField**|`string`| optional | Field displayed as the marker description |
1422
1424
|**zoom**|`number`| optional | Initial zoom level (1-20). Omit to let the renderer fit the camera to the queried records |
1423
1425
|**center**|`[number, number]`| optional | Initial camera center as [latitude, longitude]. Omit to let the renderer fit the camera to the queried records |
1426
+
|**style**|`string`| optional | Map style URL — the MapLibre style document the renderer loads in place of the public demo tiles. The component-level `mapStyle` is read FIRST and wins when both are present; this is NOT the inline CSS `style` record a component node carries |
0 commit comments