@maplibre-yaml/core 0.2.2 → 0.3.0-alpha.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.
@@ -1,6 +1,7 @@
1
- import { R as RootSchema, M as MapBlockSchema, S as ScrollytellingBlockSchema, L as LayerSchema, a as LegendConfigSchema, b as MapConfigSchema, c as LayerSourceSchema, C as ControlsConfigSchema } from './page.schema-Cad2FFqh.js';
1
+ import { R as RootSchema, M as MapBlockSchema, S as ScrollytellingBlockSchema, L as LayerSchema, a as LegendConfigSchema, b as MapConfigSchema, C as ControlsConfigSchema, c as LayerSourceSchema } from './page.schema-Cad2FFqh.js';
2
2
  import { z } from 'zod';
3
- import { Map, LngLat } from 'maplibre-gl';
3
+ import * as maplibre from 'maplibre-gl';
4
+ import { LngLat } from 'maplibre-gl';
4
5
 
5
6
  /**
6
7
  * @file YAML parser for MapLibre configuration files
@@ -122,6 +123,33 @@ interface ParseResult<T = RootConfig> {
122
123
  data?: T;
123
124
  errors: ParseError[];
124
125
  }
126
+ /**
127
+ * Discriminated result returned by {@link YAMLParser.safeParseAny}
128
+ *
129
+ * @remarks
130
+ * The `blockType` field identifies which schema the document was validated
131
+ * against, and `result` carries the corresponding safeParse result:
132
+ *
133
+ * - `'map'` — document had `type: map`, validated with {@link YAMLParser.safeParseMapBlock}
134
+ * - `'scrollytelling'` — document had `type: scrollytelling`, validated with {@link YAMLParser.safeParseScrollytellingBlock}
135
+ * - `'root'` — document had no `type:` but a `pages:` array, validated with {@link YAMLParser.safeParse}
136
+ * - `'unknown'` — the document type could not be determined (unrecognized
137
+ * `type:` value, YAML syntax error, or a document that is neither a block
138
+ * nor a root config); `result` is always a failure with a descriptive error
139
+ */
140
+ type SafeParseAnyResult = {
141
+ blockType: "map";
142
+ result: ParseResult<MapBlock>;
143
+ } | {
144
+ blockType: "scrollytelling";
145
+ result: ParseResult<ScrollytellingBlock>;
146
+ } | {
147
+ blockType: "root";
148
+ result: ParseResult<RootConfig>;
149
+ } | {
150
+ blockType: "unknown";
151
+ result: ParseResult<never>;
152
+ };
125
153
  /**
126
154
  * YAML parser with schema validation and reference resolution
127
155
  *
@@ -334,6 +362,35 @@ declare class YAMLParser {
334
362
  * ```
335
363
  */
336
364
  static safeParseScrollytellingBlock(yaml: string): ParseResult<ScrollytellingBlock>;
365
+ /**
366
+ * Detect the document type of a YAML string and validate it against the
367
+ * matching schema
368
+ *
369
+ * @param yaml - YAML string to parse (a map block, a scrollytelling block, or a root document)
370
+ * @returns Discriminated result with the detected block type and the corresponding safeParse result
371
+ *
372
+ * @remarks
373
+ * Dispatches on the document's top-level `type:` field:
374
+ *
375
+ * - `type: map` → {@link safeParseMapBlock}
376
+ * - `type: scrollytelling` → {@link safeParseScrollytellingBlock}
377
+ * - no `type:` but a `pages:` key → {@link safeParse} (root document)
378
+ *
379
+ * Any other `type:` value produces a failure result listing the valid
380
+ * values, as does a document that has neither `type:` nor `pages:`.
381
+ * This method never throws.
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const { blockType, result } = YAMLParser.safeParseAny(yamlString);
386
+ * if (!result.success) {
387
+ * result.errors.forEach(err => console.error(`${err.path}: ${err.message}`));
388
+ * } else if (blockType === 'map') {
389
+ * renderMap(result.data);
390
+ * }
391
+ * ```
392
+ */
393
+ static safeParseAny(yaml: string): SafeParseAnyResult;
337
394
  /**
338
395
  * Resolve $ref references to global layers and sources
339
396
  *
@@ -444,6 +501,54 @@ declare const parseYAMLConfig: typeof YAMLParser.parse;
444
501
  * ```
445
502
  */
446
503
  declare const safeParseYAMLConfig: typeof YAMLParser.safeParse;
504
+ /**
505
+ * Convenience function to detect and validate any supported document type
506
+ *
507
+ * @param yaml - YAML string to parse (map block, scrollytelling block, or root document)
508
+ * @returns Discriminated result with the detected block type and safeParse result
509
+ *
510
+ * @remarks
511
+ * This is an alias for {@link YAMLParser.safeParseAny} for convenient imports.
512
+ *
513
+ * @example
514
+ * ```typescript
515
+ * import { safeParseAny } from '@maplibre-yaml/core/parser';
516
+ * const { blockType, result } = safeParseAny(yamlString);
517
+ * ```
518
+ */
519
+ declare const safeParseAny: typeof YAMLParser.safeParseAny;
520
+
521
+ /**
522
+ * @file maplibre-gl named-export interop
523
+ * @module @maplibre-yaml/core/renderer
524
+ *
525
+ * @description
526
+ * Single place where maplibre-gl runtime values enter this package.
527
+ *
528
+ * maplibre-gl (v3–v5) ships a CJS bundle with no `exports` map, which makes
529
+ * its bindings environment-dependent:
530
+ *
531
+ * - **Node ESM**: cjs-module-lexer cannot statically detect the bundle's
532
+ * named exports, so `import { Map } from "maplibre-gl"` throws at import
533
+ * time ("Named export not found") — only the `default` binding
534
+ * (`module.exports`) is populated. This is why a straight named-import
535
+ * conversion was reverted once before: it broke every Node consumer of
536
+ * this package (the CLI's `validate`, Astro's content loader).
537
+ * - **Bundlers** (Vite/esbuild/webpack): CJS interop populates both named
538
+ * and default bindings.
539
+ * - **Real ESM builds** (esm.sh via the documented CDN import map, or a
540
+ * future ESM-only maplibre-gl): named exports exist; `default` may not.
541
+ * maplibre-gl v5's type declarations already dropped the default export.
542
+ *
543
+ * Importing the namespace and preferring `default` when present yields
544
+ * working constructors in every environment, while the exported types stay
545
+ * the named ones that v5 declares. Do not import maplibre-gl runtime values
546
+ * directly anywhere else in src/ — route them through this module.
547
+ * (Type-only imports from "maplibre-gl" are fine; they're erased.)
548
+ */
549
+
550
+ declare const Map: typeof maplibre.Map;
551
+ type Map = maplibre.Map;
447
552
 
448
553
  /**
449
554
  * @file Legend builder for map layers
@@ -490,6 +595,10 @@ type LegendConfig = z.infer<typeof LegendConfigSchema>;
490
595
  interface MapRendererOptions {
491
596
  onLoad?: () => void;
492
597
  onError?: (error: Error) => void;
598
+ /** Controls declared in the YAML `controls:` block — added automatically on map load */
599
+ controls?: ControlsConfig;
600
+ /** Legend declared in the YAML `legend:` block — built automatically on map load */
601
+ legend?: LegendConfig;
493
602
  }
494
603
  /**
495
604
  * Events emitted by MapRenderer
@@ -535,6 +644,10 @@ declare class MapRenderer {
535
644
  private controlsManager;
536
645
  private eventListeners;
537
646
  private isLoaded;
647
+ private containerEl;
648
+ private controlsAdded;
649
+ private legendBuilt;
650
+ private autoLegendContainer;
538
651
  constructor(container: string | HTMLElement, config: MapConfig, layers?: Layer[], options?: MapRendererOptions, sources?: Record<string, LayerSource>);
539
652
  /**
540
653
  * Get the underlying MapLibre map instance
@@ -562,12 +675,26 @@ declare class MapRenderer {
562
675
  updateLayerData(layerId: string, data: GeoJSON.GeoJSON): void;
563
676
  /**
564
677
  * Add controls to the map
678
+ *
679
+ * @remarks
680
+ * Called automatically on map load when a `controls:` config was passed via
681
+ * {@link MapRendererOptions}. Calling it manually marks controls as added so
682
+ * the automatic invocation is skipped (no double-add).
565
683
  */
566
684
  addControls(config: ControlsConfig): void;
567
685
  /**
568
686
  * Build legend in container
687
+ *
688
+ * @remarks
689
+ * Called automatically on map load when a `legend:` config was passed via
690
+ * {@link MapRendererOptions}. Calling it manually marks the legend as built
691
+ * so the automatic invocation is skipped (no double-build).
569
692
  */
570
693
  buildLegend(container: string | HTMLElement, layers: Layer[], config?: LegendConfig): void;
694
+ /**
695
+ * Create a positioned container inside the map element for the auto legend
696
+ */
697
+ private createLegendContainer;
571
698
  /**
572
699
  * Get the legend builder instance
573
700
  */
@@ -590,4 +717,4 @@ declare class MapRenderer {
590
717
  destroy(): void;
591
718
  }
592
719
 
593
- export { LegendBuilder as L, MapRenderer as M, type ParseError as P, YAMLParser as Y, type ParseResult as a, type MapRendererOptions as b, type MapRendererEvents as c, type MapBlock as d, parseYAMLConfig as p, safeParseYAMLConfig as s };
720
+ export { LegendBuilder as L, MapRenderer as M, type ParseError as P, type SafeParseAnyResult as S, YAMLParser as Y, safeParseAny as a, type ParseResult as b, type MapRendererOptions as c, type MapRendererEvents as d, type MapBlock as e, parseYAMLConfig as p, safeParseYAMLConfig as s };