@absolutejs/absolute 0.20.0-beta.174 → 0.20.0-beta.175

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 (84) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/changelog.json +60 -0
  3. package/dist/angular/browser.js +13 -2
  4. package/dist/angular/browser.js.map +3 -3
  5. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  6. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  7. package/dist/angular/index.js +67 -8
  8. package/dist/angular/index.js.map +10 -8
  9. package/dist/angular/server.js +67 -8
  10. package/dist/angular/server.js.map +10 -8
  11. package/dist/build.js +312 -119
  12. package/dist/build.js.map +20 -18
  13. package/dist/cli/{compile-n6fs2vmx.js → compile-w2z6c9vt.js} +1 -1
  14. package/dist/cli/{dev-6h1f0mzq.js → dev-8br5mr7t.js} +16 -2
  15. package/dist/cli/{index-mqevg32w.js → index-6522t968.js} +21 -2
  16. package/dist/cli/{index-bhyd3ejc.js → index-7z1hh3fg.js} +1 -1
  17. package/dist/cli/index.js +6 -6
  18. package/dist/cli/{islands-vk05sj6v.js → islands-bx67g15t.js} +4 -4
  19. package/dist/cli/{mobile-62b6j3j7.js → mobile-we5q51ey.js} +2 -2
  20. package/dist/cli/{start-jh6kyp92.js → start-srs11bm8.js} +2 -2
  21. package/dist/client/chunks/index-4j1snyh2.js +18 -0
  22. package/dist/client/chunks/index-4j1snyh2.js.map +10 -0
  23. package/dist/client/chunks/{index-6b66nzyf.js → index-a3rpg5kw.js} +6 -16
  24. package/dist/client/chunks/{index-6b66nzyf.js.map → index-a3rpg5kw.js.map} +3 -4
  25. package/dist/client/chunks/{islands-s2ta5ajb.js → islands-mfjmdwnb.js} +11 -4
  26. package/dist/client/chunks/{islands-s2ta5ajb.js.map → islands-mfjmdwnb.js.map} +3 -3
  27. package/dist/client/chunks/{react-dcvkaba2.js → react-sprprqzs.js} +20 -4
  28. package/dist/client/chunks/react-sprprqzs.js.map +10 -0
  29. package/dist/client/chunks/svelte-6ewphsvj.js +30 -0
  30. package/dist/client/chunks/svelte-6ewphsvj.js.map +10 -0
  31. package/dist/client/chunks/{vue-a84fzp3v.js → vue-db6ppn1f.js} +14 -4
  32. package/dist/client/chunks/vue-db6ppn1f.js.map +10 -0
  33. package/dist/client/index.js +65 -8
  34. package/dist/client/index.js.map +4 -4
  35. package/dist/client/navigation.js +5 -3
  36. package/dist/client/navigation.js.map +2 -2
  37. package/dist/client/prefetch.js +1 -1
  38. package/dist/dev/client/handlers/islands.ts +85 -0
  39. package/dist/dev/client/hmrClient.ts +6 -0
  40. package/dist/index.js +448 -242
  41. package/dist/index.js.map +21 -19
  42. package/dist/islands/index.js +57 -10
  43. package/dist/islands/index.js.map +9 -7
  44. package/dist/react/browser.js +15 -4
  45. package/dist/react/browser.js.map +5 -5
  46. package/dist/react/components/client.js +506 -0
  47. package/dist/react/components/index.js +14 -15
  48. package/dist/react/components/index.js.map +4 -4
  49. package/dist/react/components/server/index.js +728 -0
  50. package/dist/react/hooks/index.js +14 -15
  51. package/dist/react/hooks/index.js.map +4 -4
  52. package/dist/react/index.js +66 -6
  53. package/dist/react/index.js.map +11 -9
  54. package/dist/react/router/browser.js +7 -8
  55. package/dist/react/router/browser.js.map +4 -4
  56. package/dist/react/router/index.js +7 -8
  57. package/dist/react/router/index.js.map +4 -4
  58. package/dist/react/server.js +14 -1
  59. package/dist/react/server.js.map +4 -4
  60. package/dist/src/build/buildReactServerComponents.d.ts +4 -0
  61. package/dist/src/build/islandEntries.d.ts +5 -0
  62. package/dist/src/client/hydrators/react.d.ts +7 -0
  63. package/dist/src/client/hydrators/svelte.d.ts +3 -0
  64. package/dist/src/client/hydrators/vue.d.ts +3 -0
  65. package/dist/src/client/preserveIslandMarkup.d.ts +5 -0
  66. package/dist/src/core/islandServerGeneration.d.ts +3 -0
  67. package/dist/src/react/components/client.d.ts +4 -0
  68. package/dist/src/react/components/server/index.d.ts +8 -0
  69. package/dist/src/react/serverComponents/constants.d.ts +2 -1
  70. package/dist/svelte/index.js +66 -6
  71. package/dist/svelte/index.js.map +10 -8
  72. package/dist/svelte/server.js +38 -3
  73. package/dist/svelte/server.js.map +6 -5
  74. package/dist/types/build.d.ts +3 -2
  75. package/dist/types/globals.d.ts +15 -0
  76. package/dist/vue/browser.js +26 -16
  77. package/dist/vue/browser.js.map +5 -5
  78. package/dist/vue/index.js +65 -21
  79. package/dist/vue/index.js.map +10 -9
  80. package/package.json +1 -1
  81. package/dist/client/chunks/react-dcvkaba2.js.map +0 -10
  82. package/dist/client/chunks/svelte-4yfa5bxa.js +0 -17
  83. package/dist/client/chunks/svelte-4yfa5bxa.js.map +0 -10
  84. package/dist/client/chunks/vue-a84fzp3v.js.map +0 -10
@@ -0,0 +1,728 @@
1
+ // @bun
2
+ // src/utils/cspNonceRef.ts
3
+ var GETTER_KEY = Symbol.for("absolutejs.cspNonceGetter");
4
+ var readCspNonce = () => {
5
+ const getter = Reflect.get(globalThis, GETTER_KEY);
6
+ if (typeof getter !== "function")
7
+ return;
8
+ const nonce = getter();
9
+ return typeof nonce === "string" ? nonce : undefined;
10
+ };
11
+
12
+ // src/utils/fontAssets.ts
13
+ var MIME_BY_EXTENSION = {
14
+ otf: "font/otf",
15
+ ttf: "font/ttf",
16
+ woff: "font/woff",
17
+ woff2: "font/woff2"
18
+ };
19
+ var fontMimeType = (href) => {
20
+ const extension = /\.([a-z0-9]+)(?:[?#].*)?$/i.exec(href)?.[1]?.toLowerCase();
21
+ return (extension && MIME_BY_EXTENSION[extension]) ?? "font/woff2";
22
+ };
23
+ var isRemote = (href) => /^https?:\/\//i.test(href);
24
+ var fontPreconnectOrigins = (fonts) => fonts.stylesheets.some(isRemote) ? ["https://fonts.googleapis.com", "https://fonts.gstatic.com"] : [];
25
+
26
+ // src/utils/iconVersion.ts
27
+ var iconMimeType = (icon) => {
28
+ if (icon.endsWith(".svg"))
29
+ return "image/svg+xml";
30
+ if (icon.endsWith(".png"))
31
+ return "image/png";
32
+ return "image/x-icon";
33
+ };
34
+ var resolver;
35
+ var applyIconVersion = (href) => resolver ? resolver(href) : href;
36
+
37
+ // src/utils/escapeScriptContent.ts
38
+ var ESCAPE_LOOKUP = {
39
+ "\u2028": "\\u2028",
40
+ "\u2029": "\\u2029",
41
+ "<": "\\u003C"
42
+ };
43
+ var ESCAPE_REGEX = /[<\u2028\u2029]/g;
44
+ var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
45
+ const escaped = ESCAPE_LOOKUP[char];
46
+ return escaped !== undefined ? escaped : char;
47
+ });
48
+
49
+ // src/utils/jsonLd.ts
50
+ var serializeJsonLd = (schema) => {
51
+ const schemaOrgContext = "https://schema.org";
52
+ const data = Array.isArray(schema) ? { "@context": schemaOrgContext, "@graph": schema } : { "@context": schemaOrgContext, ...schema };
53
+ return escapeScriptContent(JSON.stringify(data));
54
+ };
55
+
56
+ // src/utils/generateHeadElement.ts
57
+ var serializeSpeculationRules = (rules) => {
58
+ const body = {};
59
+ if (rules.prerender && rules.prerender.length > 0) {
60
+ body.prerender = [{ urls: rules.prerender }];
61
+ }
62
+ if (rules.prefetch && rules.prefetch.length > 0) {
63
+ body.prefetch = [{ urls: rules.prefetch }];
64
+ }
65
+ if (Object.keys(body).length === 0)
66
+ return;
67
+ return JSON.stringify(body).replace(/</g, "\\u003c");
68
+ };
69
+
70
+ // src/react/components/Head.tsx
71
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
72
+ var RobotsContent = ({ robots }) => {
73
+ const directives = [];
74
+ if (robots.index === false)
75
+ directives.push("noindex");
76
+ if (robots.index === true)
77
+ directives.push("index");
78
+ if (robots.follow === false)
79
+ directives.push("nofollow");
80
+ if (robots.follow === true)
81
+ directives.push("follow");
82
+ if (robots.noarchive)
83
+ directives.push("noarchive");
84
+ if (robots.nosnippet)
85
+ directives.push("nosnippet");
86
+ if (robots.noimageindex)
87
+ directives.push("noimageindex");
88
+ if (robots.maxSnippet !== undefined)
89
+ directives.push(`max-snippet:${robots.maxSnippet}`);
90
+ if (robots.maxImagePreview)
91
+ directives.push(`max-image-preview:${robots.maxImagePreview}`);
92
+ if (robots.maxVideoPreview !== undefined)
93
+ directives.push(`max-video-preview:${robots.maxVideoPreview}`);
94
+ const content = directives.join(", ");
95
+ return content ? /* @__PURE__ */ jsx("meta", {
96
+ content,
97
+ name: "robots"
98
+ }) : null;
99
+ };
100
+ var OpenGraphTags = ({
101
+ openGraph,
102
+ title,
103
+ description
104
+ }) => /* @__PURE__ */ jsxs(Fragment, {
105
+ children: [
106
+ /* @__PURE__ */ jsx("meta", {
107
+ content: openGraph.title ?? title,
108
+ property: "og:title"
109
+ }),
110
+ /* @__PURE__ */ jsx("meta", {
111
+ content: openGraph.description ?? description,
112
+ property: "og:description"
113
+ }),
114
+ openGraph.url && /* @__PURE__ */ jsx("meta", {
115
+ content: openGraph.url,
116
+ property: "og:url"
117
+ }),
118
+ openGraph.image && /* @__PURE__ */ jsx("meta", {
119
+ content: openGraph.image,
120
+ property: "og:image"
121
+ }),
122
+ openGraph.imageAlt && /* @__PURE__ */ jsx("meta", {
123
+ content: openGraph.imageAlt,
124
+ property: "og:image:alt"
125
+ }),
126
+ openGraph.imageWidth && /* @__PURE__ */ jsx("meta", {
127
+ content: String(openGraph.imageWidth),
128
+ property: "og:image:width"
129
+ }),
130
+ openGraph.imageHeight && /* @__PURE__ */ jsx("meta", {
131
+ content: String(openGraph.imageHeight),
132
+ property: "og:image:height"
133
+ }),
134
+ openGraph.type && /* @__PURE__ */ jsx("meta", {
135
+ content: openGraph.type,
136
+ property: "og:type"
137
+ }),
138
+ openGraph.siteName && /* @__PURE__ */ jsx("meta", {
139
+ content: openGraph.siteName,
140
+ property: "og:site_name"
141
+ }),
142
+ openGraph.locale && /* @__PURE__ */ jsx("meta", {
143
+ content: openGraph.locale,
144
+ property: "og:locale"
145
+ })
146
+ ]
147
+ });
148
+ var TwitterTags = ({
149
+ twitter,
150
+ title,
151
+ description
152
+ }) => /* @__PURE__ */ jsxs(Fragment, {
153
+ children: [
154
+ twitter.card && /* @__PURE__ */ jsx("meta", {
155
+ content: twitter.card,
156
+ name: "twitter:card"
157
+ }),
158
+ /* @__PURE__ */ jsx("meta", {
159
+ content: twitter.title ?? title,
160
+ name: "twitter:title"
161
+ }),
162
+ /* @__PURE__ */ jsx("meta", {
163
+ content: twitter.description ?? description,
164
+ name: "twitter:description"
165
+ }),
166
+ twitter.image && /* @__PURE__ */ jsx("meta", {
167
+ content: twitter.image,
168
+ name: "twitter:image"
169
+ }),
170
+ twitter.imageAlt && /* @__PURE__ */ jsx("meta", {
171
+ content: twitter.imageAlt,
172
+ name: "twitter:image:alt"
173
+ }),
174
+ twitter.site && /* @__PURE__ */ jsx("meta", {
175
+ content: twitter.site,
176
+ name: "twitter:site"
177
+ }),
178
+ twitter.creator && /* @__PURE__ */ jsx("meta", {
179
+ content: twitter.creator,
180
+ name: "twitter:creator"
181
+ })
182
+ ]
183
+ });
184
+ var CustomMetaTag = ({ tag }) => {
185
+ if (tag.property)
186
+ return /* @__PURE__ */ jsx("meta", {
187
+ content: tag.content,
188
+ property: tag.property
189
+ });
190
+ if (tag.httpEquiv)
191
+ return /* @__PURE__ */ jsx("meta", {
192
+ content: tag.content,
193
+ httpEquiv: tag.httpEquiv
194
+ });
195
+ return /* @__PURE__ */ jsx("meta", {
196
+ content: tag.content,
197
+ name: tag.name
198
+ });
199
+ };
200
+ var toCrossOrigin = (value) => {
201
+ if (value === undefined)
202
+ return;
203
+ if (value === "" || value === "use-credentials")
204
+ return value;
205
+ return "anonymous";
206
+ };
207
+ var FontLinks = ({ fonts }) => /* @__PURE__ */ jsxs(Fragment, {
208
+ children: [
209
+ fontPreconnectOrigins(fonts).map((origin) => /* @__PURE__ */ jsx("link", {
210
+ crossOrigin: origin.includes("gstatic") ? "anonymous" : undefined,
211
+ href: origin,
212
+ rel: "preconnect"
213
+ }, `preconnect:${origin}`)),
214
+ fonts.preload.map((href) => /* @__PURE__ */ jsx("link", {
215
+ as: "font",
216
+ crossOrigin: "anonymous",
217
+ href,
218
+ rel: "preload",
219
+ suppressHydrationWarning: true,
220
+ type: fontMimeType(href)
221
+ }, `preload:${href}`)),
222
+ fonts.stylesheets.map((href) => /* @__PURE__ */ jsx("link", {
223
+ "data-absolute-fonts": "",
224
+ href,
225
+ rel: "stylesheet",
226
+ suppressHydrationWarning: true
227
+ }, `stylesheet:${href}`))
228
+ ]
229
+ });
230
+ var SpeculationRulesScript = ({
231
+ rules
232
+ }) => {
233
+ const body = serializeSpeculationRules(rules);
234
+ if (!body)
235
+ return null;
236
+ return /* @__PURE__ */ jsx("script", {
237
+ dangerouslySetInnerHTML: { __html: body },
238
+ nonce: readCspNonce(),
239
+ suppressHydrationWarning: true,
240
+ type: "speculationrules"
241
+ });
242
+ };
243
+ var Head = ({
244
+ title = "AbsoluteJS",
245
+ description = "A page created using AbsoluteJS",
246
+ icon = "/assets/ico/favicon.ico",
247
+ font,
248
+ fonts,
249
+ cssPath,
250
+ canonical,
251
+ alternates,
252
+ openGraph,
253
+ twitter,
254
+ robots,
255
+ meta,
256
+ jsonLd,
257
+ preload,
258
+ speculationRules
259
+ } = {}) => /* @__PURE__ */ jsxs("head", {
260
+ suppressHydrationWarning: true,
261
+ children: [
262
+ /* @__PURE__ */ jsx("meta", {
263
+ charSet: "utf-8"
264
+ }),
265
+ /* @__PURE__ */ jsx("title", {
266
+ children: title
267
+ }),
268
+ /* @__PURE__ */ jsx("meta", {
269
+ content: description,
270
+ name: "description"
271
+ }),
272
+ /* @__PURE__ */ jsx("meta", {
273
+ content: "width=device-width, initial-scale=1",
274
+ name: "viewport"
275
+ }),
276
+ /* @__PURE__ */ jsx("link", {
277
+ href: applyIconVersion(icon),
278
+ rel: "icon",
279
+ type: iconMimeType(icon)
280
+ }),
281
+ canonical && /* @__PURE__ */ jsx("link", {
282
+ href: canonical,
283
+ rel: "canonical"
284
+ }),
285
+ alternates?.map(({ href, hreflang }) => /* @__PURE__ */ jsx("link", {
286
+ href,
287
+ hrefLang: hreflang,
288
+ rel: "alternate"
289
+ }, `alternate:${hreflang}`)),
290
+ openGraph && /* @__PURE__ */ jsx(OpenGraphTags, {
291
+ description,
292
+ openGraph,
293
+ title
294
+ }),
295
+ twitter && /* @__PURE__ */ jsx(TwitterTags, {
296
+ description,
297
+ title,
298
+ twitter
299
+ }),
300
+ robots && /* @__PURE__ */ jsx(RobotsContent, {
301
+ robots
302
+ }),
303
+ meta?.map((tag, i) => /* @__PURE__ */ jsx(CustomMetaTag, {
304
+ tag
305
+ }, i)),
306
+ font && /* @__PURE__ */ jsxs(Fragment, {
307
+ children: [
308
+ /* @__PURE__ */ jsx("link", {
309
+ href: "https://fonts.googleapis.com",
310
+ rel: "preconnect"
311
+ }),
312
+ /* @__PURE__ */ jsx("link", {
313
+ crossOrigin: "anonymous",
314
+ href: "https://fonts.gstatic.com",
315
+ rel: "preconnect",
316
+ suppressHydrationWarning: true
317
+ }),
318
+ /* @__PURE__ */ jsx("link", {
319
+ href: `https://fonts.googleapis.com/css2?family=${font}:wght@100..900&display=swap`,
320
+ rel: "stylesheet",
321
+ suppressHydrationWarning: true
322
+ })
323
+ ]
324
+ }),
325
+ fonts && /* @__PURE__ */ jsx(FontLinks, {
326
+ fonts
327
+ }),
328
+ preload?.map((link) => /* @__PURE__ */ jsx("link", {
329
+ as: link.module ? undefined : link.as,
330
+ crossOrigin: toCrossOrigin(link.crossorigin),
331
+ href: link.href,
332
+ rel: link.module ? "modulepreload" : "preload"
333
+ }, `${link.module ? "modulepreload" : "preload"}:${link.href}`)),
334
+ speculationRules && /* @__PURE__ */ jsx(SpeculationRulesScript, {
335
+ rules: speculationRules
336
+ }),
337
+ cssPath && [cssPath].flat().map((path) => /* @__PURE__ */ jsx("link", {
338
+ href: path,
339
+ rel: "stylesheet",
340
+ suppressHydrationWarning: true,
341
+ type: "text/css"
342
+ }, path)),
343
+ jsonLd && /* @__PURE__ */ jsx("script", {
344
+ dangerouslySetInnerHTML: { __html: serializeJsonLd(jsonLd) },
345
+ nonce: readCspNonce(),
346
+ suppressHydrationWarning: true,
347
+ type: "application/ld+json"
348
+ })
349
+ ]
350
+ });
351
+ // src/constants.ts
352
+ var HOURS_IN_DAY = 24;
353
+ var IMAGE_DEFAULT_DEVICE_SIZES = [
354
+ 640,
355
+ 750,
356
+ 828,
357
+ 1080,
358
+ 1200,
359
+ 1920,
360
+ 2048,
361
+ 3840
362
+ ];
363
+ var IMAGE_DEFAULT_IMAGE_SIZES = [16, 32, 48, 64, 96, 128, 256, 384];
364
+ var IMAGE_DEFAULT_QUALITY = 75;
365
+ var MILLISECONDS_IN_A_SECOND = 1000;
366
+ var MINUTES_IN_AN_HOUR = 60;
367
+ var SECONDS_IN_A_MINUTE = 60;
368
+ var MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
369
+ var MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
370
+ var TWO_THIRDS = 2 / 3;
371
+
372
+ // src/utils/imageClient.ts
373
+ var DEFAULT_DEVICE_SIZES = IMAGE_DEFAULT_DEVICE_SIZES;
374
+ var DEFAULT_IMAGE_SIZES = IMAGE_DEFAULT_IMAGE_SIZES;
375
+ var DEFAULT_QUALITY = IMAGE_DEFAULT_QUALITY;
376
+ var OPTIMIZATION_ENDPOINT = "/_absolute/image";
377
+ var buildOptimizedUrl = (src, width, quality, basePath = OPTIMIZATION_ENDPOINT) => `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`;
378
+ var getAllSizes = (deviceSizes, imageSizes) => {
379
+ const device = deviceSizes ?? DEFAULT_DEVICE_SIZES;
380
+ const image = imageSizes ?? DEFAULT_IMAGE_SIZES;
381
+ return [...device, ...image].sort((left, right) => left - right);
382
+ };
383
+ var snapToSize = (target, sizes) => {
384
+ for (const size of sizes) {
385
+ if (size >= target)
386
+ return size;
387
+ }
388
+ return sizes[sizes.length - 1] ?? target;
389
+ };
390
+ var generateBlurSvg = (base64Thumbnail) => {
391
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 320"><filter id="b" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="20"/><feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1"/></filter><image filter="url(#b)" x="0" y="0" width="100%" height="100%" href="${base64Thumbnail}"/></svg>`;
392
+ const encoded = encodeURIComponent(svg);
393
+ return `url("data:image/svg+xml,${encoded}")`;
394
+ };
395
+ var generateSrcSet = (src, width, sizes, deviceSizes, imageSizes) => {
396
+ const quality = DEFAULT_QUALITY;
397
+ if (sizes) {
398
+ const allSizes = getAllSizes(deviceSizes, imageSizes);
399
+ return allSizes.map((sizeWidth) => `${buildOptimizedUrl(src, sizeWidth, quality)} ${sizeWidth}w`).join(", ");
400
+ }
401
+ if (width) {
402
+ const allSizes = getAllSizes(deviceSizes, imageSizes);
403
+ const w1x = snapToSize(width, allSizes);
404
+ const w2x = snapToSize(width * 2, allSizes);
405
+ return `${buildOptimizedUrl(src, w1x, quality)} 1x, ${buildOptimizedUrl(src, w2x, quality)} 2x`;
406
+ }
407
+ const devSizes = deviceSizes ?? DEFAULT_DEVICE_SIZES;
408
+ return devSizes.map((sizeWidth) => `${buildOptimizedUrl(src, sizeWidth, quality)} ${sizeWidth}w`).join(", ");
409
+ };
410
+
411
+ // src/react/components/Image.tsx
412
+ import { jsx as jsx2, jsxs as jsxs2, Fragment as Fragment2 } from "react/jsx-runtime";
413
+ var resolveSource = (src, overrideSrc, unoptimized, loader, width, quality) => {
414
+ if (overrideSrc)
415
+ return overrideSrc;
416
+ if (unoptimized)
417
+ return src;
418
+ if (loader)
419
+ return loader({ quality, src, width: width ?? 0 });
420
+ if (!width)
421
+ return buildOptimizedUrl(src, 0, quality);
422
+ return buildOptimizedUrl(src, width, quality);
423
+ };
424
+ var resolveBlurBackground = (hasBlur, placeholder, blurDataURL) => {
425
+ if (!hasBlur)
426
+ return;
427
+ if (typeof placeholder === "string" && placeholder !== "blur" && placeholder.startsWith("data:")) {
428
+ return generateBlurSvg(placeholder);
429
+ }
430
+ if (blurDataURL)
431
+ return generateBlurSvg(blurDataURL);
432
+ return;
433
+ };
434
+ var Image = ({
435
+ alt,
436
+ blurDataURL,
437
+ className,
438
+ crossOrigin,
439
+ fetchPriority,
440
+ fill,
441
+ height,
442
+ loader,
443
+ loading,
444
+ onError,
445
+ onLoad,
446
+ overrideSrc,
447
+ placeholder,
448
+ priority,
449
+ quality = DEFAULT_QUALITY,
450
+ referrerPolicy,
451
+ sizes,
452
+ src,
453
+ style,
454
+ unoptimized,
455
+ width
456
+ }) => {
457
+ const resolvedSrc = resolveSource(src, overrideSrc, unoptimized, loader, width, quality);
458
+ const srcSet = unoptimized ? undefined : generateSrcSet(src, width, sizes);
459
+ const resolvedSizes = sizes ?? (fill ? "100vw" : undefined);
460
+ const resolvedLoading = priority ? "eager" : loading ?? "lazy";
461
+ const resolvedFetchPriority = priority ? "high" : fetchPriority;
462
+ const hasBlur = placeholder === "blur" || typeof placeholder === "string" && placeholder !== "empty" && placeholder.startsWith("data:");
463
+ const blurBackground = resolveBlurBackground(hasBlur, placeholder, blurDataURL);
464
+ const imgStyle = {
465
+ ...style ?? {},
466
+ ...blurBackground ? {
467
+ backgroundImage: blurBackground,
468
+ backgroundPosition: "center",
469
+ backgroundRepeat: "no-repeat",
470
+ backgroundSize: "cover"
471
+ } : {},
472
+ ...fill ? {
473
+ color: "transparent",
474
+ height: "100%",
475
+ inset: 0,
476
+ objectFit: "cover",
477
+ position: "absolute",
478
+ width: "100%"
479
+ } : { color: "transparent" }
480
+ };
481
+ const fillWrapperStyle = {
482
+ display: "block",
483
+ height: "100%",
484
+ overflow: "hidden",
485
+ position: "relative",
486
+ width: "100%"
487
+ };
488
+ const preloadLink = priority ? /* @__PURE__ */ jsx2("link", {
489
+ as: "image",
490
+ crossOrigin,
491
+ href: resolvedSrc,
492
+ imageSizes: resolvedSizes,
493
+ imageSrcSet: srcSet,
494
+ rel: "preload"
495
+ }) : null;
496
+ const imgElement = /* @__PURE__ */ jsx2("img", {
497
+ alt,
498
+ className,
499
+ crossOrigin,
500
+ decoding: "async",
501
+ fetchPriority: resolvedFetchPriority,
502
+ height: fill ? undefined : height,
503
+ loading: resolvedLoading,
504
+ onError: onError ? (event) => onError(event.nativeEvent) : undefined,
505
+ onLoad: (event) => {
506
+ const { target } = event;
507
+ if (blurBackground && target instanceof HTMLImageElement) {
508
+ target.style.backgroundImage = "none";
509
+ }
510
+ if (onLoad)
511
+ onLoad(event.nativeEvent);
512
+ },
513
+ referrerPolicy,
514
+ sizes: resolvedSizes,
515
+ src: resolvedSrc,
516
+ srcSet,
517
+ style: imgStyle,
518
+ width: fill ? undefined : width
519
+ });
520
+ if (fill) {
521
+ return /* @__PURE__ */ jsxs2(Fragment2, {
522
+ children: [
523
+ preloadLink,
524
+ /* @__PURE__ */ jsx2("span", {
525
+ style: fillWrapperStyle,
526
+ children: imgElement
527
+ })
528
+ ]
529
+ });
530
+ }
531
+ return /* @__PURE__ */ jsxs2(Fragment2, {
532
+ children: [
533
+ preloadLink,
534
+ imgElement
535
+ ]
536
+ });
537
+ };
538
+ // src/react/components/JsonLd.tsx
539
+ import { jsx as jsx3 } from "react/jsx-runtime";
540
+ var JsonLd = ({
541
+ schema
542
+ }) => {
543
+ const schemaOrgContext = "https://schema.org";
544
+ const data = Array.isArray(schema) ? schema.map((s) => ({
545
+ "@context": schemaOrgContext,
546
+ ...s
547
+ })) : { "@context": schemaOrgContext, ...schema };
548
+ return /* @__PURE__ */ jsx3("script", {
549
+ dangerouslySetInnerHTML: { __html: JSON.stringify(data) },
550
+ type: "application/ld+json"
551
+ });
552
+ };
553
+ // src/core/streamingSlotRegistrar.ts
554
+ var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
555
+ var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
556
+ var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
557
+ var getRegisteredStreamingSlotRegistrar = () => {
558
+ const value = Reflect.get(globalThis, STREAMING_SLOT_REGISTRAR_KEY);
559
+ if (typeof value === "function" || value === null) {
560
+ return value;
561
+ }
562
+ return;
563
+ };
564
+ var isObjectRecord = (value) => Boolean(value) && typeof value === "object";
565
+ var isStreamingSlotWarningController = (value) => isObjectRecord(value) && ("maybeWarn" in value) && typeof value.maybeWarn === "function";
566
+ var isStreamingSlotCollectionController = (value) => isObjectRecord(value) && ("isCollecting" in value) && typeof value.isCollecting === "function";
567
+ var getWarningController = () => {
568
+ const value = Reflect.get(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY);
569
+ if (value === null || typeof value === "undefined")
570
+ return;
571
+ return isStreamingSlotWarningController(value) ? value : undefined;
572
+ };
573
+ var getCollectionController = () => {
574
+ const value = Reflect.get(globalThis, STREAMING_SLOT_COLLECTION_STORAGE_KEY);
575
+ if (value === null || typeof value === "undefined")
576
+ return;
577
+ return isStreamingSlotCollectionController(value) ? value : undefined;
578
+ };
579
+ var isStreamingSlotCollectionActive = () => getCollectionController()?.isCollecting() === true;
580
+ var registerStreamingSlot = (slot) => {
581
+ getRegisteredStreamingSlotRegistrar()?.(slot);
582
+ };
583
+ var warnMissingStreamingSlotCollector = (primitiveName) => {
584
+ if (isStreamingSlotCollectionActive()) {
585
+ return;
586
+ }
587
+ getWarningController()?.maybeWarn(primitiveName);
588
+ };
589
+
590
+ // src/react/components/SuspenseSlot.tsx
591
+ import { jsx as jsx4 } from "react/jsx-runtime";
592
+ var isLegacyProps = (props) => ("fallbackHtml" in props) || ("errorHtml" in props);
593
+ var renderReactNodeToHtml = async (node) => {
594
+ const { Fragment } = await import("react");
595
+ const { renderToReadableStream } = await import("react-dom/server");
596
+ const stream = await renderToReadableStream(/* @__PURE__ */ jsx4(Fragment, {
597
+ children: node
598
+ }));
599
+ await stream.allReady;
600
+ return new Response(stream).text();
601
+ };
602
+ var hasRenderChildren = (props) => typeof props.children === "function";
603
+ async function resolveRenderSuspenseValue(props) {
604
+ if ("resolve" in props && props.resolve !== undefined) {
605
+ return props.resolve();
606
+ }
607
+ if ("promise" in props && props.promise !== undefined) {
608
+ return props.promise;
609
+ }
610
+ return;
611
+ }
612
+ async function resolveNodeSuspenseValue(props) {
613
+ if (props.resolve !== undefined) {
614
+ return props.resolve();
615
+ }
616
+ if (props.promise !== undefined) {
617
+ return props.promise;
618
+ }
619
+ return;
620
+ }
621
+ var renderErrorFallback = async (props, error) => {
622
+ if (typeof props.errorFallback === "function") {
623
+ return renderReactNodeToHtml(props.errorFallback(error));
624
+ }
625
+ if (props.errorFallback !== undefined) {
626
+ return renderReactNodeToHtml(props.errorFallback);
627
+ }
628
+ throw error;
629
+ };
630
+ var registerLegacySuspenseSlot = (props) => {
631
+ registerStreamingSlot({
632
+ dynamic: props.dynamic,
633
+ errorHtml: props.errorHtml,
634
+ fallbackHtml: props.fallbackHtml,
635
+ id: props.id,
636
+ resolve: props.resolve,
637
+ timeoutMs: props.timeoutMs
638
+ });
639
+ };
640
+ var registerFrameworkSuspenseSlot = (props) => {
641
+ registerStreamingSlot({
642
+ dynamic: props.dynamic,
643
+ id: props.id,
644
+ timeoutMs: props.timeoutMs,
645
+ resolve: async () => {
646
+ try {
647
+ const content = hasRenderChildren(props) ? props.children(await resolveRenderSuspenseValue(props)) : props.children ?? await resolveNodeSuspenseValue(props) ?? null;
648
+ return renderReactNodeToHtml(content);
649
+ } catch (error) {
650
+ return renderErrorFallback(props, error);
651
+ }
652
+ }
653
+ });
654
+ };
655
+ var renderLegacySuspenseSlot = (props) => /* @__PURE__ */ jsx4("div", {
656
+ className: props.className,
657
+ dangerouslySetInnerHTML: { __html: props.fallbackHtml ?? "" },
658
+ "data-absolute-slot": "true",
659
+ id: props.id,
660
+ suppressHydrationWarning: true
661
+ });
662
+ var renderFrameworkSuspenseSlot = (props) => /* @__PURE__ */ jsx4("div", {
663
+ className: props.className,
664
+ "data-absolute-slot": "true",
665
+ id: props.id,
666
+ suppressHydrationWarning: true,
667
+ children: props.fallback ?? null
668
+ });
669
+ var renderServerSuspenseSlot = (props) => {
670
+ if (isLegacyProps(props)) {
671
+ registerLegacySuspenseSlot(props);
672
+ return renderLegacySuspenseSlot(props);
673
+ }
674
+ registerFrameworkSuspenseSlot(props);
675
+ return renderFrameworkSuspenseSlot(props);
676
+ };
677
+ var SuspenseSlot = (props) => {
678
+ if (isStreamingSlotCollectionActive()) {
679
+ return renderServerSuspenseSlot(props);
680
+ }
681
+ warnMissingStreamingSlotCollector("SuspenseSlot");
682
+ if (isLegacyProps(props))
683
+ return renderLegacySuspenseSlot(props);
684
+ return renderFrameworkSuspenseSlot(props);
685
+ };
686
+ // src/react/components/StreamSlot.tsx
687
+ import { jsx as jsx5 } from "react/jsx-runtime";
688
+ var StreamSlot = ({
689
+ className,
690
+ dynamic,
691
+ errorHtml,
692
+ fallbackHtml = "",
693
+ id,
694
+ resolve,
695
+ timeoutMs
696
+ }) => {
697
+ if (isStreamingSlotCollectionActive()) {
698
+ registerStreamingSlot({
699
+ dynamic,
700
+ errorHtml,
701
+ fallbackHtml,
702
+ id,
703
+ resolve,
704
+ timeoutMs
705
+ });
706
+ } else {
707
+ warnMissingStreamingSlotCollector("StreamSlot");
708
+ }
709
+ return /* @__PURE__ */ jsx5("div", {
710
+ className,
711
+ dangerouslySetInnerHTML: { __html: fallbackHtml },
712
+ "data-absolute-slot": "true",
713
+ id,
714
+ suppressHydrationWarning: true
715
+ });
716
+ };
717
+
718
+ // src/react/components/server/index.ts
719
+ import { Link, usePrefetch } from "../client.js";
720
+ export {
721
+ Head,
722
+ Image,
723
+ JsonLd,
724
+ Link,
725
+ StreamSlot,
726
+ SuspenseSlot,
727
+ usePrefetch
728
+ };