@tileflow/core 0.1.0-alpha.3 → 0.1.0-alpha.30

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.
Files changed (37) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +270 -26
  3. package/THIRD_PARTY_NOTICES.md +327 -0
  4. package/dist/browser.d.ts +334 -0
  5. package/dist/browser.js +5694 -0
  6. package/dist/build.d.ts +574 -0
  7. package/dist/build.js +25405 -0
  8. package/dist/capture-scene-D6soWztE.d.ts +161 -0
  9. package/dist/capture.d.ts +9 -0
  10. package/dist/capture.js +276 -0
  11. package/dist/config-reference.json +32261 -0
  12. package/dist/icon-composition-BiOTwrvD.d.ts +1331 -0
  13. package/dist/index.d.ts +1112 -162
  14. package/dist/index.js +18690 -3479
  15. package/dist/manifest-types-CTT2eLbp.d.ts +790 -0
  16. package/dist/manifest.d.ts +9 -0
  17. package/dist/manifest.js +368 -0
  18. package/dist/native-profile.d.ts +188 -0
  19. package/dist/native-profile.js +9316 -0
  20. package/dist/native.d.ts +222 -0
  21. package/dist/native.js +4862 -0
  22. package/dist/runtime.d.ts +1 -0
  23. package/dist/runtime.js +1317 -0
  24. package/docs/authoring-model.md +226 -0
  25. package/docs/capture-scenes.md +36 -0
  26. package/docs/compiled-style-performance.md +263 -0
  27. package/docs/data-is-separate-from-design.md +345 -0
  28. package/docs/globe-atmosphere.md +83 -0
  29. package/docs/hosted-session-authorization.md +108 -0
  30. package/docs/map-and-terrain-examples.md +149 -0
  31. package/docs/native-artifact-profile.md +145 -0
  32. package/docs/native-resource-urls.md +367 -0
  33. package/docs/public-api-and-browser-subpath.md +93 -0
  34. package/docs/shared-visual-primitives.md +81 -0
  35. package/docs/theme-transitions-and-blends.md +165 -0
  36. package/docs/themes-and-module-styles.md +83 -0
  37. package/package.json +58 -8
@@ -0,0 +1,93 @@
1
+ # Public API and browser subpath
2
+
3
+ Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
4
+
5
+ Config, data, modules, compilation, validation, runtime resolution, and capture-scene APIs remain
6
+ available from the package root. Capture scenes, manifests, and browser-runtime surfaces also have
7
+ explicit `@tileflow/core/capture`, `@tileflow/core/manifest`, and `@tileflow/core/runtime`
8
+ subpaths. Node build integrations import the small deterministic map-identity contract from
9
+ `@tileflow/core/build`: `collectTileflowMapBuildLineage`, `createTileflowMapBuildManifest`,
10
+ `hashTileflowMapRevision`, `hashTileflowAssetSet`, and `hashTileflowAssetSetIdentities`. The latter
11
+ reproduces the same asset-set v1 hash from exact per-file identities after another system has
12
+ independently confirmed the immutable bytes; package or bundle hashes are not substitutes. The
13
+ previous aggregate-wrapper and recipe-selector APIs, `renderer`, top-level `tiles`/`tileset`, module
14
+ arrays, and top-level raw `layers` are not part of this API. Raw MapLibre layers are accepted only
15
+ inside a named `maplibreOverlay()` bound to a named Team source.
16
+
17
+ Advanced cartography remains in the same public language: `withRenderStack()`, `renderPass()`, and
18
+ `refineRenderTarget()` address owner-local semantic targets without exposing physical layer IDs,
19
+ sources, source layers, raw filters, or before/after anchors. Typed `field()` references and
20
+ `expr.*` builders stay semantic until the compiler's single lowering boundary. There is no recipe
21
+ subpath or alternate compiler integration API.
22
+
23
+ `mapRevisionSha256` hashes only resolved cartography: the effective design after `extends`, the
24
+ semantic language, compiler-owned effective contributions, and exact source icon/font identities.
25
+ Leaf `id`, `name`, editorial `mapVersion`, default `view`, capture `scenes`, and `delivery` policy do
26
+ not change that content identity. They remain explicit on the map, manifest, Style, capture receipt,
27
+ or Hosted deployment fingerprint that owns them. Compiler ABI, package versions, generated assets,
28
+ and the concrete release selected by World `current` likewise have separate identities.
29
+
30
+ Runtime manifest version 1 has one shape for local and Hosted delivery. Every map entry owns
31
+ `defaultTheme`, optional `systemThemes`, and a `themes` record whose leaves contain
32
+ `colorScheme`, `styleUrl`, and optional font/deployment identity. Hosted-only identity is additive
33
+ metadata on the same map entry; there is no delivery discriminator or parallel `styles` alias.
34
+ `parseTileflowRuntimeManifest()` accepts only this canonical shape. The strict bounded schema uses
35
+ the same portable map and theme IDs as authoring, rejects `system` as a published name, duplicate
36
+ font identities, unsafe owner-relative URLs, prototype-bearing input, unknown fields, and JSON
37
+ larger than 1 MiB.
38
+
39
+ ```json
40
+ {
41
+ "version": 1,
42
+ "maps": {
43
+ "madrid": {
44
+ "defaultTheme": "light",
45
+ "systemThemes": {"light": "light", "dark": "dark"},
46
+ "themes": {
47
+ "light": {"colorScheme": "light", "styleUrl": "/styles/madrid/light.json"},
48
+ "dark": {"colorScheme": "dark", "styleUrl": "/styles/madrid/dark.json"}
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ Runtime fetches share a successful result for 30 seconds, never cache failures, use
56
+ `cache: 'no-store'`, enforce a 10-second timeout (configurable up to 60 seconds), compose an
57
+ external abort signal, and can be invalidated with `clearTileflowManifestCache()`.
58
+
59
+ Named map `view` values travel in the manifest. `resolveTileflowRuntimeTheme()` turns an omitted,
60
+ explicit, or `system` request with a supplied color scheme into one concrete published entry;
61
+ unknown names fail closed. `resolveTileflowRuntimeView()` defines the shared precedence as explicit
62
+ runtime values, then the manifest view, then the single exported `defaultTileflowRuntimeView`
63
+ (`[0, 20]`, zoom 2, bearing/pitch 0).
64
+
65
+ `TileflowRuntimeSource` is one object, `{map, manifestUrl?}`, selecting a named Tileflow map only
66
+ through its published manifest. React, Vue and Svelte share that source contract. Omitting the URL
67
+ means exactly `/tileflow/manifest.json`; other locations must be explicit. The native Core contract
68
+ uses `{map, manifestUrl}` with a required absolute URL and no discovery, as described in the
69
+ [native guide](native-resource-urls.md). The React Native type contract preserves that requirement.
70
+ No public framework Map source exposes a renderer discriminator or direct-style branch. The obsolete
71
+ `kind` and `style` fields are rejected; completely unmanaged maps use upstream MapLibre directly.
72
+ The runtime subpath does not import the config compiler, invent a localhost style URL, or change
73
+ image mode by environment.
74
+
75
+ Framework adapters import the browser-only lifecycle kernel explicitly:
76
+
77
+ ```ts
78
+ import {
79
+ attachTileflowAtmosphere,
80
+ attachTileflowFairUseNotice,
81
+ attachTileflowMapLifecycle,
82
+ createTileflowSessionStarter,
83
+ createTileflowTransformRequest,
84
+ registerTileflowWorldRequestBridge,
85
+ } from '@tileflow/core/browser';
86
+ ```
87
+
88
+ The browser entry is not re-exported from the root. It is SSR-safe to import, has no MapLibre
89
+ runtime dependency, and reads no browser global during module evaluation. See the
90
+ [framework browser runtime contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/framework-browser-runtime.md) and the
91
+ [cartographic authoring contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/cartographic-authoring.md). Exact field
92
+ resolution and asset rules live in the
93
+ [map inheritance contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/map-inheritance.md).
@@ -0,0 +1,81 @@
1
+ # Shared visual primitives
2
+
3
+ Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
4
+
5
+ The same small visual language is reused across every geographic domain. This keeps an agent from
6
+ having to learn different spellings for the same MapLibre behavior:
7
+
8
+ - `BackgroundStyle`: color, opacity, pattern, visibility, and zoom range.
9
+ - `FillStyle`: color, opacity, pattern, antialiasing, visibility, and zoom range.
10
+ - `LineStyle`: color, width, opacity, dash, blur, gap, offset, pattern, caps, joins, and zoom range.
11
+ - `LineHatchStyle`: repeated diagonal detail with color, opacity, spacing, size, angle, and zoom
12
+ range for a road structure.
13
+ - `TextStyle`: field, exact font face, exact fallback faces, size, color, halo, line-fitted
14
+ background, spacing metrics, transform, collision policy, rotation, fixed/variable anchoring, line
15
+ constraints, and zoom range.
16
+ - `IconStyle`: image, size, color, halo, rotation/alignment, collision policy, and zoom range.
17
+ - `CircleStyle`: radius, fill/stroke appearance, blur, opacity, pitch behavior, and zoom range.
18
+ - `ExtrusionStyle`: color, height, base, opacity, pattern, vertical gradient, and zoom range.
19
+
20
+ Compounds express common cartographic structures: `AreaStyle` has `fill` and `outline`,
21
+ `LineStackStyle` has `shadow`, `casing`, and `fill`, and `SymbolStyle` combines placement with
22
+ optional `text`, `icon`, and `marker`. Geographic selection remains owned by semantic modules;
23
+ ordinary visual styles intentionally do not accept raw source filters.
24
+
25
+ ## Line-fitted text backgrounds
26
+
27
+ `text.background` draws one opaque strip behind each shaped line of a label, fitted to that line's
28
+ own width. Use it for captions whose lines differ in length, where a stretched icon plate
29
+ (`icon.textFit`) would cover the whole block.
30
+
31
+ <!-- docs:check -->
32
+
33
+ ```ts
34
+ import {fixed, poi, zoom} from '@tileflow/core';
35
+
36
+ export const captions = poi({
37
+ categories: ['arts-entertainment'],
38
+ styles: {
39
+ 'arts-entertainment': {
40
+ text: {
41
+ background: {
42
+ color: fixed('#080E11', {reason: 'Caption strip'}),
43
+ fit: 'lines',
44
+ padding: 0.33,
45
+ },
46
+ color: fixed('#ECEEE9', {reason: 'Caption text'}),
47
+ font: fixed('Noto Sans Bold', {reason: 'Caption face'}),
48
+ letterSpacing: fixed(0.08, {reason: 'Caption tracking'}),
49
+ lineHeight: fixed(1.2, {reason: 'Caption leading'}),
50
+ size: zoom.linear([
51
+ [14, 11],
52
+ [18, 14],
53
+ ]),
54
+ },
55
+ },
56
+ },
57
+ });
58
+ ```
59
+
60
+ Tileflow lowers the background to MapLibre properties only. `text-font` becomes a derived stack,
61
+ such as `Noto Sans Bold lines-v1-t80-l1200-p330`. Its glyphs keep the source advances and shapes and
62
+ add a rectangular cell, which the text halo paints. The halo width tracks `text-size / 6`, including
63
+ zoom curves. Shaping, wrapping, collision, variable anchors, fading and right-to-left text therefore
64
+ stay native, and the compiled style needs no runtime extension.
65
+
66
+ - The colour must be opaque. Neighbouring cells overlap where they join.
67
+ - `font` must name one stack served by the map's `glyphs` provider, without `fallbacks`. Maps that
68
+ use browser-rendered `fonts` reject backgrounds.
69
+ - `letterSpacing` and `lineHeight` must be constants. The derived stack encodes them in thousandths
70
+ of an em, and the layer uses those rounded values. Tracking runs from 0 to 0.5em, leading from 0.8
71
+ to 3 and padding from 0 to 1em.
72
+ - The background replaces the text halo. While a background is active, `haloWidth` and `haloBlur`
73
+ are derived, and `haloColor` is the strip colour. Later refinements of size, tracking, leading or
74
+ font re-derive the stack and halo.
75
+ - Collision still reserves the shaped block. Padding beyond it is drawn outside that box, so keep
76
+ `padding` (text padding) at least as large as the strip padding in pixels.
77
+
78
+ The map's `glyphs` provider must serve derived stacks. `deriveTileflowLineBackgroundGlyphs`
79
+ computes any range from the source stack's range, and `parseTileflowLineBackgroundFontStack`
80
+ recognises derived requests. Local previews and captures derive ranges themselves; hosted and
81
+ self-hosted providers must do the same.
@@ -0,0 +1,165 @@
1
+ # Theme transitions and blends
2
+
3
+ Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
4
+
5
+ A Tileflow map can change theme with a cross-fade, or show any point between two or more of its
6
+ themes. Use a transition when people switch between appearances, such as light and dark. Use a
7
+ blend when the application controls the appearance continuously, such as a slider or a day that
8
+ passes from night to day.
9
+
10
+ Both work on the one MapLibre map the application already has. They create no second map, add no
11
+ map views, and request the same tiles as a map that does not change theme. They need a browser
12
+ document and MapLibre GL JS; the React Native package does not offer them.
13
+
14
+ ## Cross-fade a theme change
15
+
16
+ Pass `themeTransition` to the React, Vue, or Svelte map. This React example assumes a map named
17
+ `city` with `light` and `dark` themes in the published manifest:
18
+
19
+ ```tsx
20
+ import {Map} from '@tileflow/react';
21
+ import {useState} from 'react';
22
+
23
+ export function CityMap() {
24
+ const [theme, setTheme] = useState<'dark' | 'light'>('light');
25
+ return (
26
+ <>
27
+ <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Switch theme</button>
28
+ <Map source={{map: 'city'}} theme={theme} themeTransition={{duration: 450}} />
29
+ </>
30
+ );
31
+ }
32
+ ```
33
+
34
+ When the theme changes, a snapshot of the current frame covers the map. The snapshot follows the
35
+ camera while people pan, zoom, rotate, or tilt, and fades out once the new theme is drawn. The map
36
+ stays interactive throughout. `onThemeChange` reports `preloading`, `applying`, and finally `ready`
37
+ after the fade. A `theme="system"` change, entering a blend, and leaving one use the same
38
+ transition.
39
+
40
+ `duration` is in milliseconds, from 0 to 5000. It defaults to 0, which changes the theme at once.
41
+ When the browser asks for reduced motion, every change happens at once.
42
+
43
+ ## Blend themes
44
+
45
+ Pass `themeBlend` with the themes to blend, in order, and a `position` between them. Position 0
46
+ shows the first theme, 1 the second, and 1.25 a quarter of the way from the second to the third:
47
+
48
+ ```tsx
49
+ import {Map} from '@tileflow/react';
50
+ import {useState} from 'react';
51
+
52
+ export function DayMap() {
53
+ const [position, setPosition] = useState(0);
54
+ return (
55
+ <>
56
+ <input
57
+ aria-label="Time of day"
58
+ max={2}
59
+ min={0}
60
+ onChange={(event) => setPosition(Number(event.target.value))}
61
+ step={0.01}
62
+ type="range"
63
+ value={position}
64
+ />
65
+ <Map source={{map: 'city'}} themeBlend={{position, themes: ['night', 'dusk', 'day']}} />
66
+ </>
67
+ );
68
+ }
69
+ ```
70
+
71
+ The first blend of a set of themes loads each theme's style and fonts, prepares one style that
72
+ holds every theme, and replaces the map's style once, with `themeTransition` if set. Until then the
73
+ map shows the theme nearest to the position. After that, changing `position` updates the map at
74
+ once without loading anything, so it can follow a slider, a clock, or an animation frame by frame.
75
+ Changing `themes` prepares a new blend. Removing `themeBlend` returns to `theme`.
76
+
77
+ While a blend is shown, `data-tileflow-theme` names the theme nearest to the position.
78
+ `onThemeChange` reports the preparation of a blend; moving its position reports nothing.
79
+
80
+ ### What follows the position
81
+
82
+ - Colours and numbers of the ground, such as land, water, roads, buildings, and their widths and
83
+ opacities, follow the position continuously. Colours mix in the OKLab colour space, so halfway
84
+ between two themes looks halfway to the eye.
85
+ - Patterns, the sky, and light follow the position too. Pattern artwork is mixed in its pixels.
86
+ - Labels, icons, and other symbols change when the nearest theme changes, with a short cross-fade.
87
+ Light lettering on a dark plate and dark lettering on a light plate would meet in the same grey
88
+ halfway, so symbols do not follow the position.
89
+ - A value that depends on feature state, such as a caption that changes colour when highlighted,
90
+ changes with the nearest theme. MapLibre lays its source out again for that change; a cross-fade
91
+ covers it.
92
+
93
+ ### Which themes can be blended
94
+
95
+ Blend themes of the same map. Every theme of a map exposes the same token keys, so its compiled
96
+ styles share sources, layers, filters, and expressions, and differ only in colours, numbers, and
97
+ image names. Up to eight themes can be blended. A blend fails, and the map keeps its current
98
+ appearance, when the styles differ in structure, sources, sprite, or glyphs.
99
+
100
+ Icon and pattern artwork is mixed in place of the first theme's image when every theme's version
101
+ has the same size. Otherwise that image changes with the nearest theme instead.
102
+
103
+ ### Cost
104
+
105
+ The prepared style holds every theme. A value that depends on feature data, such as a land-use
106
+ colour chosen by class, becomes one layer per class while the blend is shown, so the prepared
107
+ style has more layers than one theme. Physical layer IDs are diagnostic, not stable; semantic
108
+ interactions are not affected.
109
+
110
+ Entering a blend replaces the map's style once. MapLibre then takes about as long as it takes to
111
+ load the map: for a detailed city map, around half a second on a desktop computer and longer on a
112
+ phone, while the transition snapshot, if any, covers the map. Start a blend before people need it
113
+ to move, for example when the map loads.
114
+
115
+ Each position change after that sets the map's themed values directly, without expression parsing.
116
+ For a detailed city map this takes a few milliseconds on a mid-range phone. Positions closer than a
117
+ four-hundredth of a theme are not applied, so a slowly moving position leaves the map at rest
118
+ between changes.
119
+
120
+ ## Use the core controller
121
+
122
+ Framework adapters use `createTileflowThemeController` from `@tileflow/core/browser`. A direct
123
+ MapLibre integration can use it too. Resolve runtime styles from the published manifest with
124
+ `resolveTileflowRuntimeStyle` and `resolveTileflowRuntimeThemeBlend` from `@tileflow/core/runtime`:
125
+
126
+ ```ts
127
+ import {createTileflowThemeController} from '@tileflow/core/browser';
128
+ import {
129
+ resolveTileflowRuntimeStyle,
130
+ resolveTileflowRuntimeThemeBlend,
131
+ } from '@tileflow/core/runtime';
132
+ import type {Map as MapLibreMap} from 'maplibre-gl';
133
+ import type {TileflowRuntimeManifestMap} from '@tileflow/core/runtime';
134
+
135
+ export async function moveThroughTheDay(map: MapLibreMap, manifestMap: TileflowRuntimeManifestMap) {
136
+ const source = {map: 'city'};
137
+ const styleOf = (theme: string) => {
138
+ const style = resolveTileflowRuntimeStyle({manifestMap, source, theme});
139
+ if (!style) throw new Error(`The manifest has no ${theme} theme for ${source.map}.`);
140
+ return style;
141
+ };
142
+ // `initial` is the runtime style the map was created with.
143
+ const controller = createTileflowThemeController({initial: styleOf('day'), map});
144
+
145
+ await controller.setTheme(styleOf('night'), {transition: {duration: 450}});
146
+
147
+ const themes = resolveTileflowRuntimeThemeBlend({
148
+ blend: {position: 0, themes: ['night', 'dusk', 'day']},
149
+ manifestMap,
150
+ source,
151
+ });
152
+ await controller.setBlend({position: 0.5, themes});
153
+ // The same themes: the position applies at once.
154
+ await controller.setBlend({position: 0.6, themes});
155
+ return controller.getBlend(); // {position: 0.6, themes: ['night', 'dusk', 'day']}
156
+ }
157
+ ```
158
+
159
+ `setTheme` and `setBlend` accept `{transition: {duration}}`;
160
+ `createTileflowThemeController({transition})` sets a default. Requests are serialized and the
161
+ latest wins. A failed change restores the previous appearance and reports `failed` with its error.
162
+
163
+ The controller loads blended themes' style documents with the same request policy it uses for
164
+ style font metadata: same-origin credentials, no redirects, and a bounded size. Pass `loadStyle`
165
+ when styles need another loader.
@@ -0,0 +1,83 @@
1
+ # Themes and module styles
2
+
3
+ Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
4
+
5
+ A map declares complete named appearances in `themes`, chooses one deterministic
6
+ `defaultTheme`, and may map the browser's light/dark preference through `systemThemes`. `system` is
7
+ never a compiled theme name: it is a runtime request that resolves immediately to one concrete
8
+ name. Disk builds write `styles/<map>/<theme>.json` beneath their output root. Public and
9
+ content-addressed Style URLs belong to the runtime manifest and may include a deployment prefix;
10
+ capture scenes and receipts store the concrete name rather than `system`.
11
+
12
+ Themes are flat, JSON-safe documents with `colorScheme`, identity, typography, lighting, and four
13
+ typed token catalogs: `color`, `font`, `image`, and `number`. Every theme on one map must expose the
14
+ same token keys, so changing a theme can never change map structure or silently lose a semantic
15
+ role. `defineTheme(base, definition)` is an authoring convenience that returns a fully materialized
16
+ document; it does not leave an inheritance edge in the resolved config.
17
+
18
+ The key in the `themes` record is its concrete runtime selector and output-path segment. The
19
+ theme's own `id` and `version` are its editorial identity and build provenance, so they need not
20
+ equal that key. Concrete keys may be names such as `day` and `night`; every `systemThemes.light` or
21
+ `systemThemes.dark` value must name an existing theme whose `colorScheme` matches that branch.
22
+
23
+ ```ts
24
+ import {color, defineMap, defineTheme, fixed, roads, token} from '@tileflow/core';
25
+ import {streets, streetsThemes} from '@tileflow/maps';
26
+
27
+ const dark = defineTheme(streetsThemes.dark, {
28
+ id: 'company-dark',
29
+ version: 1,
30
+ colorScheme: 'dark',
31
+ tokens: {
32
+ color: {
33
+ 'surface.land': '#101722',
34
+ 'labels.primary': color.mix('#eef3fb', token.color('surface.background'), {amount: 0.08}),
35
+ },
36
+ },
37
+ });
38
+
39
+ export default defineMap({
40
+ id: 'company',
41
+ version: 1,
42
+ extends: streets,
43
+ themes: {light: streetsThemes.light, dark},
44
+ defaultTheme: 'light',
45
+ systemThemes: {light: 'light', dark: 'dark'},
46
+ modules: {
47
+ roads: roads({
48
+ classes: {
49
+ primary: {
50
+ surface: {
51
+ fill: {
52
+ color: fixed('#ff2d78', {reason: 'Regulatory primary-road ink is invariant'}),
53
+ },
54
+ },
55
+ },
56
+ secondary: {
57
+ surface: {
58
+ fill: {
59
+ color: token.color('roads.secondary'),
60
+ },
61
+ },
62
+ },
63
+ },
64
+ }),
65
+ },
66
+ });
67
+ ```
68
+
69
+ Semantic modules own structure and behavior; visual fields accept typed token references.
70
+ Use a visual literal only inside a theme. If a module value intentionally must not vary, wrap it in
71
+ `fixed(value, {reason})`. `tileflow inspect --json` reports stable `THEME_IMPLICIT_FIXED`
72
+ diagnostics: implicit color, font, and image literals block Style compilation, while direct visual
73
+ number literals are warnings so an agent can document their invariance deliberately. Structural
74
+ numbers such as zoom bounds and ranks are not visual-theme diagnostics. `color.alpha()` and
75
+ deterministic OKLCH `color.mix()` keep derived palette logic inspectable. Unknown refs, cycles,
76
+ cross-category refs, token-schema drift, and unresolved visual nodes fail before Style JSON is
77
+ emitted.
78
+
79
+ There is no physical-layer override for the Tileflow basemap or separate official-map authoring
80
+ surface. Basemap behavior belongs to a typed control or owner-local render stack. Every
81
+ official and application map therefore follows the same schema, inheritance rules, diagnostics,
82
+ and lowering path. `createStyle()` validates the final planned Style JSON with the MapLibre style
83
+ spec and never returns an invalid style.
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "@tileflow/core",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.0-alpha.30",
4
+ "license": "Apache-2.0",
4
5
  "description": "Typed Tileflow config and MapLibre style compiler.",
5
6
  "type": "module",
7
+ "sideEffects": false,
6
8
  "homepage": "https://tileflow.dev",
7
9
  "repository": {
8
10
  "type": "git",
9
- "url": "git+https://github.com/tileflow/tileflow.git",
11
+ "url": "git+https://github.com/tileflow/tileflow-sdk.git",
10
12
  "directory": "packages/core"
11
13
  },
12
14
  "bugs": {
13
- "url": "https://github.com/tileflow/tileflow/issues"
15
+ "url": "https://github.com/tileflow/tileflow-sdk/issues"
14
16
  },
15
17
  "keywords": [
16
18
  "tileflow",
@@ -22,25 +24,73 @@
22
24
  "main": "./dist/index.js",
23
25
  "types": "./dist/index.d.ts",
24
26
  "files": [
25
- "dist"
27
+ "dist",
28
+ "docs",
29
+ "LICENSE",
30
+ "THIRD_PARTY_NOTICES.md"
26
31
  ],
27
32
  "exports": {
28
33
  ".": {
29
34
  "types": "./dist/index.d.ts",
30
35
  "import": "./dist/index.js",
31
36
  "default": "./dist/index.js"
32
- }
37
+ },
38
+ "./browser": {
39
+ "types": "./dist/browser.d.ts",
40
+ "import": "./dist/browser.js",
41
+ "default": "./dist/browser.js"
42
+ },
43
+ "./build": {
44
+ "types": "./dist/build.d.ts",
45
+ "import": "./dist/build.js",
46
+ "default": "./dist/build.js"
47
+ },
48
+ "./capture": {
49
+ "types": "./dist/capture.d.ts",
50
+ "import": "./dist/capture.js",
51
+ "default": "./dist/capture.js"
52
+ },
53
+ "./config-reference.json": "./dist/config-reference.json",
54
+ "./manifest": {
55
+ "types": "./dist/manifest.d.ts",
56
+ "import": "./dist/manifest.js",
57
+ "default": "./dist/manifest.js"
58
+ },
59
+ "./native": {
60
+ "types": "./dist/native.d.ts",
61
+ "import": "./dist/native.js",
62
+ "default": "./dist/native.js"
63
+ },
64
+ "./native-profile": {
65
+ "types": "./dist/native-profile.d.ts",
66
+ "import": "./dist/native-profile.js",
67
+ "default": "./dist/native-profile.js"
68
+ },
69
+ "./runtime": {
70
+ "types": "./dist/runtime.d.ts",
71
+ "import": "./dist/runtime.js",
72
+ "default": "./dist/runtime.js"
73
+ },
74
+ "./package.json": "./package.json"
33
75
  },
34
76
  "publishConfig": {
35
77
  "access": "public"
36
78
  },
37
79
  "dependencies": {
80
+ "@maplibre/maplibre-gl-style-spec": "24.8.5",
38
81
  "zod": "^4.4.3"
39
82
  },
83
+ "devDependencies": {
84
+ "maplibre-contour": "0.1.0",
85
+ "pmtiles": "4.4.0",
86
+ "whatwg-url": "15.1.0"
87
+ },
40
88
  "scripts": {
41
- "build": "tsup src/index.ts --format esm --dts --clean",
42
- "verify": "tsx scripts/verify.ts",
43
- "typecheck": "tsc -p tsconfig.json --noEmit",
89
+ "build": "tsup --config tsup.build.config.ts && tsup --config tsup.native-profile.config.ts && tsup src/browser.ts --format esm --dts --no-splitting --platform browser && tsup --config tsup.native.config.ts && cp ../../docs/modules-api-reference.json dist/config-reference.json",
90
+ "reference:check": "tsx scripts/generate-config-reference.ts --check",
91
+ "reference:generate": "tsx scripts/generate-config-reference.ts --write",
92
+ "verify": "pnpm run build && tsx --test test/*.test.ts",
93
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.contract.json",
44
94
  "lint": "tsc -p tsconfig.json --noEmit"
45
95
  }
46
96
  }