astroidjs 0.14.0 → 0.15.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/bin/astroid.mjs CHANGED
@@ -148,7 +148,7 @@ async function cmdDoctor(cwd, flags) {
148
148
  // and are a pure function of the config, so "stale" means the project on
149
149
  // disk is not the project the config describes—which is the single
150
150
  // condition doctor exists to catch. As a warning it printed "healthy" and
151
- // exited 0, so `pnpm doctor` could not gate CI on it.
151
+ // exited 0, so `pnpm run doctor` could not gate CI on it.
152
152
  err(`${file.path} is stale (out of sync with your config) — run \`astroid generate\`.`);
153
153
  } else {
154
154
  ok(`${file.path} is up to date`);
@@ -24,6 +24,6 @@ export declare function generateMapTileRoute(config: AstroidConfig): string | nu
24
24
  export declare function generateMapEmbedComponent(config: AstroidConfig): string | null;
25
25
  /** The npm dependencies the map module needs in the scaffold. */
26
26
  export declare const ASTROID_MAP_DEPENDENCIES: {
27
- readonly "maplibre-gl": "^5.9.0";
27
+ readonly "maplibre-gl": "^6.11.2";
28
28
  readonly pmtiles: "^4.4.0";
29
29
  };
@@ -149,14 +149,19 @@ export function generateMapEmbedComponent(config) {
149
149
  " const load = () =>",
150
150
  " (loader ??= Promise.all([",
151
151
  ' import("maplibre-gl"),',
152
+ " // MapLibre 6 looks for its worker next to its own module, which a",
153
+ " // bundle moves, so hand it the worker. `?worker&url` sends the file",
154
+ " // through Vite's worker pipeline, which emits one self-contained",
155
+ " // chunk; a plain `?url` copies it without the shared module it",
156
+ " // imports, and then no tiles load. The worker is same-origin, so",
157
+ " // `worker-src 'self'` covers it with no `blob:`.",
158
+ ' import("maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url"),',
152
159
  ' import("pmtiles"),',
153
160
  ' import("maplibre-gl/dist/maplibre-gl.css"),',
154
- " ]).then(([maplibre, pmtiles]) => ({",
155
- " // maplibre-gl ships as CJS: under ESM interop the API may be on",
156
- " // `.default` or be the namespace itself. Accept either.",
157
- " maplibregl: (maplibre as any).default ?? maplibre,",
158
- " Protocol: (pmtiles as any).Protocol,",
159
- " })));",
161
+ " ]).then(([maplibregl, worker, pmtiles]) => {",
162
+ " maplibregl.setWorkerUrl(worker.default);",
163
+ " return { maplibregl, Protocol: pmtiles.Protocol };",
164
+ " }));",
160
165
  "",
161
166
  " const init = async (el: HTMLElement) => {",
162
167
  " const lat = Number(el.dataset.lat);",
@@ -168,18 +173,26 @@ export function generateMapEmbedComponent(config) {
168
173
  " // archive instead of requesting tile URLs.",
169
174
  ' maplibregl.addProtocol("pmtiles", new Protocol().tile);',
170
175
  "",
171
- " const map = new maplibregl.Map({",
172
- " container: el,",
173
- ' style: JSON.parse(el.dataset.style ?? "{}"),',
174
- " center: [lng, lat],",
175
- " zoom: Number(el.dataset.zoom ?? 15),",
176
- " // A map that swallows page scroll is a trap on mobile; cooperative",
177
- " // gestures require an explicit modifier/two fingers to pan.",
178
- " cooperativeGestures: true,",
179
- " dragRotate: false,",
180
- " pitchWithRotate: false,",
181
- " touchPitch: false,",
182
- " });",
176
+ " let map;",
177
+ " try {",
178
+ " map = new maplibregl.Map({",
179
+ " container: el,",
180
+ ' style: JSON.parse(el.dataset.style ?? "{}"),',
181
+ " center: [lng, lat],",
182
+ " zoom: Number(el.dataset.zoom ?? 15),",
183
+ " // A map that swallows page scroll is a trap on mobile; cooperative",
184
+ " // gestures require an explicit modifier/two fingers to pan.",
185
+ " cooperativeGestures: true,",
186
+ " dragRotate: false,",
187
+ " pitchWithRotate: false,",
188
+ " touchPitch: false,",
189
+ " });",
190
+ " } catch (err) {",
191
+ " // MapLibre 6 needs WebGL2 and throws `GPUInitializationError` without",
192
+ " // it. Leave the tinted container in place rather than a broken canvas.",
193
+ " if (err instanceof maplibregl.GPUInitializationError) return;",
194
+ " throw err;",
195
+ " }",
183
196
  ' map.addControl(new maplibregl.NavigationControl({ showCompass: false }), "top-right");',
184
197
  "",
185
198
  ' const pin = document.createElement("div");',
@@ -213,6 +226,6 @@ export function generateMapEmbedComponent(config) {
213
226
  }
214
227
  /** The npm dependencies the map module needs in the scaffold. */
215
228
  export const ASTROID_MAP_DEPENDENCIES = {
216
- "maplibre-gl": "^5.9.0",
229
+ "maplibre-gl": "^6.11.2",
217
230
  pmtiles: "^4.4.0",
218
231
  };
@@ -34,14 +34,13 @@ const COMMERCE_ORIGINS = {
34
34
  // convention) and it must not need a rebuild to switch on—CSP is baked at
35
35
  // build time, the secret is a runtime value.
36
36
  const TURNSTILE = turnstileCsp();
37
- // The map module. MapLibre spins its tile-decoding workers up from blob: URLs,
38
- // so `worker-src blob:` is not optional—without it the map renders an empty
39
- // canvas and the console fills with worker-construction errors.
40
- //
41
- // Nothing else is needed, and that's the whole argument for the self-hosted
42
- // basemap: the PMTiles archive is served same-origin, so `connect-src` stays
43
- // `'self'` with no tile host and no API key to allow.
44
- const MAP = { worker: ["blob:"] };
37
+ // The map module adds nothing, and that's the whole argument for the
38
+ // self-hosted basemap: the PMTiles archive is served same-origin, so
39
+ // `connect-src` stays `'self'` with no tile host and no API key to allow. The
40
+ // generated `<MapEmbed>` hands MapLibre 6 a same-origin worker URL, which it
41
+ // constructs directly, so `worker-src 'self'` covers it with no `blob:`.
42
+ // (MapLibre 5 built its workers from blob: URLs; a site still on 5 adds
43
+ // `worker: ["blob:"]` to its own `security.cspOrigins`.)
45
44
  const DIRECTIVE_KEYS = ["script", "style", "frame", "connect", "font", "img", "worker"];
46
45
  /** Merge origin lists, de-duplicated, order preserved. */
47
46
  function mergeOrigins(...sets) {
@@ -57,7 +56,7 @@ function mergeOrigins(...sets) {
57
56
  * what a config implies without rebuilding the whole policy.
58
57
  */
59
58
  export function astroidCspOrigins(config) {
60
- return mergeOrigins(TURNSTILE, ...((config.modules ?? []).includes("map") ? [MAP] : []),
59
+ return mergeOrigins(TURNSTILE,
61
60
  // EVERY provider in play, not "the" provider: a site can run Stripe for
62
61
  // invoicing beside Fourthwall for the storefront, and a policy that allowed
63
62
  // only one of them blocks the other's SDK at runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astroidjs",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Astroid — an opinionated meta-framework over Louise Toolkit and Astro for building editable, multi-editor sites on Cloudflare Workers.",
5
5
  "keywords": [
6
6
  "astro",
@@ -64,14 +64,14 @@
64
64
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
65
65
  "@vitest/coverage-v8": "4.1.11",
66
66
  "astro": "^7.2.9",
67
- "louise-toolkit": "^0.31.1",
67
+ "louise-toolkit": "^0.33.0",
68
68
  "solid-js": "^1.9.15",
69
- "typescript": "^5.9.3",
69
+ "typescript": "^6.0.3",
70
70
  "vitest": "^4.1.11"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "astro": "^7.0.9",
74
- "louise-toolkit": "^0.31.1",
74
+ "louise-toolkit": "^0.33.0",
75
75
  "solid-js": "^1.9.0"
76
76
  },
77
77
  "peerDependenciesMeta": {