@maplibre-yaml/core 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -104,6 +104,50 @@ layers:
104
104
  circle-color: "#ef4444"
105
105
  ```
106
106
 
107
+ ### Named Sources
108
+
109
+ Define sources at the block level and reference them by name across multiple layers:
110
+
111
+ ```yaml
112
+ type: map
113
+ id: neighborhood-map
114
+ config:
115
+ center: [-73.985, 40.674]
116
+ zoom: 14
117
+ mapStyle: https://basemaps.cartocdn.com/gl/positron-gl-style/style.json
118
+
119
+ sources:
120
+ boundary:
121
+ type: geojson
122
+ url: https://example.com/boundary.geojson
123
+ parcels:
124
+ type: vector
125
+ url: https://example.com/parcels.json
126
+
127
+ layers:
128
+ - id: boundary-fill
129
+ type: fill
130
+ source: boundary
131
+ paint:
132
+ fill-color: "#3388ff"
133
+ fill-opacity: 0.2
134
+ - id: boundary-outline
135
+ type: line
136
+ source: boundary
137
+ paint:
138
+ line-color: "#3388ff"
139
+ line-width: 2
140
+ - id: parcels-fill
141
+ type: fill
142
+ source: parcels
143
+ source-layer: parcels
144
+ paint:
145
+ fill-color: "#ccc"
146
+ fill-opacity: 0.5
147
+ ```
148
+
149
+ Sources defined at the block level are added to the map before layers, so any layer can reference them by name. This avoids duplicating source definitions when multiple layers use the same data. Inline sources on individual layers still work as before.
150
+
107
151
  ### Real-time Data with Polling
108
152
 
109
153
  ```yaml
@@ -1,7 +1,7 @@
1
1
  export { MLMap, registerMLMap } from '../register.js';
2
2
  import 'maplibre-gl';
3
- import '../map-renderer-Br4guic2.js';
4
- import '../page.schema-EBT_0Ojm.js';
3
+ import '../map-renderer-8-c51Ww7.js';
4
+ import '../page.schema-Cad2FFqh.js';
5
5
  import 'zod';
6
6
 
7
7
  /**
@@ -589,6 +589,7 @@ var MapBlockSchema = z.object({
589
589
  className: z.string().optional().describe("CSS class name for container"),
590
590
  style: z.string().optional().describe("Inline CSS styles for container"),
591
591
  config: MapConfigSchema.describe("Map configuration"),
592
+ sources: z.record(z.string(), LayerSourceSchema).optional().describe("Map sources"),
592
593
  layers: z.array(LayerOrReferenceSchema).default([]).describe("Map layers"),
593
594
  controls: ControlsConfigSchema.optional().describe("Map controls"),
594
595
  legend: LegendConfigSchema.optional().describe("Legend configuration")
@@ -599,6 +600,7 @@ var MapFullPageBlockSchema = z.object({
599
600
  className: z.string().optional().describe("CSS class name for container"),
600
601
  style: z.string().optional().describe("Inline CSS styles for container"),
601
602
  config: MapConfigSchema.describe("Map configuration"),
603
+ sources: z.record(z.string(), LayerSourceSchema).optional().describe("Map sources"),
602
604
  layers: z.array(LayerOrReferenceSchema).default([]).describe("Map layers"),
603
605
  controls: ControlsConfigSchema.optional().describe("Map controls"),
604
606
  legend: LegendConfigSchema.optional().describe("Legend configuration")
@@ -3568,9 +3570,16 @@ var LayerManager = class {
3568
3570
  this.abortControllers = /* @__PURE__ */ new Map();
3569
3571
  }
3570
3572
  async addLayer(layer) {
3571
- const sourceId = `${layer.id}-source`;
3573
+ const isSourceRef = typeof layer.source === "string";
3574
+ const sourceId = isSourceRef ? layer.source : `${layer.id}-source`;
3572
3575
  this.layerToSource.set(layer.id, sourceId);
3573
- await this.addSource(sourceId, layer);
3576
+ if (!isSourceRef) {
3577
+ await this.addSource(sourceId, layer);
3578
+ } else if (!this.map.getSource(sourceId)) {
3579
+ throw new Error(
3580
+ `Source '${sourceId}' referenced by layer '${layer.id}' not found. Ensure it is defined in the block-level 'sources' map.`
3581
+ );
3582
+ }
3574
3583
  const layerSpec = {
3575
3584
  id: layer.id,
3576
3585
  type: layer.type,
@@ -3598,12 +3607,6 @@ var LayerManager = class {
3598
3607
  }
3599
3608
  }
3600
3609
  async addSource(sourceId, layer) {
3601
- if (typeof layer.source === "string") {
3602
- if (!this.map.getSource(layer.source)) {
3603
- throw new Error(`Source reference '${layer.source}' not found`);
3604
- }
3605
- return;
3606
- }
3607
3610
  const source = layer.source;
3608
3611
  if (source.type === "geojson") {
3609
3612
  const geojsonSource = source;
@@ -3823,7 +3826,10 @@ var LayerManager = class {
3823
3826
  }
3824
3827
  if (this.map.getLayer(layerId)) this.map.removeLayer(layerId);
3825
3828
  const sourceId = this.layerToSource.get(layerId) || `${layerId}-source`;
3826
- if (this.map.getSource(sourceId)) this.map.removeSource(sourceId);
3829
+ const isInlineSource = sourceId === `${layerId}-source`;
3830
+ if (isInlineSource && this.map.getSource(sourceId)) {
3831
+ this.map.removeSource(sourceId);
3832
+ }
3827
3833
  this.sourceData.delete(sourceId);
3828
3834
  this.layerToSource.delete(layerId);
3829
3835
  }
@@ -4185,7 +4191,7 @@ var MapRenderer = class {
4185
4191
  controlsManager;
4186
4192
  eventListeners;
4187
4193
  isLoaded;
4188
- constructor(container, config, layers = [], options = {}) {
4194
+ constructor(container, config, layers = [], options = {}, sources) {
4189
4195
  this.eventListeners = /* @__PURE__ */ new Map();
4190
4196
  this.isLoaded = false;
4191
4197
  this.map = new maplibregl2.Map({
@@ -4213,6 +4219,13 @@ var MapRenderer = class {
4213
4219
  this.controlsManager = new ControlsManager(this.map);
4214
4220
  this.map.on("load", () => {
4215
4221
  this.isLoaded = true;
4222
+ if (sources) {
4223
+ for (const [id, sourceSpec] of Object.entries(sources)) {
4224
+ if (!this.map.getSource(id)) {
4225
+ this.map.addSource(id, sourceSpec);
4226
+ }
4227
+ }
4228
+ }
4216
4229
  Promise.all(layers.map((layer) => this.addLayer(layer))).then(() => {
4217
4230
  this.emit("load", void 0);
4218
4231
  options.onLoad?.();
@@ -4512,7 +4525,7 @@ var MLMap = class extends HTMLElement {
4512
4525
  }
4513
4526
  this.appendChild(this.mapContainer);
4514
4527
  try {
4515
- const { config, layers = [] } = mapBlock;
4528
+ const { config, sources, layers = [] } = mapBlock;
4516
4529
  this.renderer = new MapRenderer(this.mapContainer, config, layers, {
4517
4530
  onLoad: () => {
4518
4531
  },
@@ -4524,7 +4537,7 @@ var MLMap = class extends HTMLElement {
4524
4537
  })
4525
4538
  );
4526
4539
  }
4527
- });
4540
+ }, sources);
4528
4541
  this.setupEventForwarding();
4529
4542
  } catch (error) {
4530
4543
  this.handleError([