@pyreon/zero 0.24.4 → 0.24.6

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 (54) hide show
  1. package/package.json +10 -39
  2. package/src/actions.ts +0 -196
  3. package/src/adapters/bun.ts +0 -114
  4. package/src/adapters/cloudflare.ts +0 -166
  5. package/src/adapters/index.ts +0 -61
  6. package/src/adapters/netlify.ts +0 -154
  7. package/src/adapters/node.ts +0 -163
  8. package/src/adapters/static.ts +0 -42
  9. package/src/adapters/validate.ts +0 -23
  10. package/src/adapters/vercel.ts +0 -182
  11. package/src/adapters/warn-missing-env.ts +0 -49
  12. package/src/ai.ts +0 -623
  13. package/src/api-routes.ts +0 -219
  14. package/src/app.ts +0 -92
  15. package/src/cache.ts +0 -136
  16. package/src/client.ts +0 -143
  17. package/src/compression.ts +0 -116
  18. package/src/config.ts +0 -35
  19. package/src/cors.ts +0 -94
  20. package/src/csp.ts +0 -226
  21. package/src/entry-server.ts +0 -224
  22. package/src/env.ts +0 -344
  23. package/src/error-overlay.ts +0 -118
  24. package/src/favicon.ts +0 -841
  25. package/src/font.ts +0 -511
  26. package/src/fs-router.ts +0 -1519
  27. package/src/i18n-routing.ts +0 -533
  28. package/src/icon.tsx +0 -182
  29. package/src/icons-plugin.ts +0 -296
  30. package/src/image-plugin.ts +0 -751
  31. package/src/image-types.ts +0 -60
  32. package/src/image.tsx +0 -340
  33. package/src/index.ts +0 -92
  34. package/src/isr.ts +0 -394
  35. package/src/link.tsx +0 -304
  36. package/src/logger.ts +0 -144
  37. package/src/manifest.ts +0 -787
  38. package/src/meta.tsx +0 -354
  39. package/src/middleware.ts +0 -65
  40. package/src/not-found.ts +0 -44
  41. package/src/og-image.ts +0 -378
  42. package/src/rate-limit.ts +0 -140
  43. package/src/script.tsx +0 -260
  44. package/src/seo.ts +0 -617
  45. package/src/server.ts +0 -89
  46. package/src/sharp.d.ts +0 -22
  47. package/src/ssg-plugin.ts +0 -1582
  48. package/src/testing.ts +0 -146
  49. package/src/theme.tsx +0 -257
  50. package/src/types.ts +0 -624
  51. package/src/utils/use-intersection-observer.ts +0 -36
  52. package/src/utils/with-headers.ts +0 -13
  53. package/src/vercel-revalidate-handler.ts +0 -204
  54. package/src/vite-plugin.ts +0 -848
@@ -1,60 +0,0 @@
1
- /**
2
- * Ambient type declarations for the custom image-import queries that
3
- * `@pyreon/zero`'s `imagePlugin` introduces (`?optimize` / `?component`
4
- * / `?raw`). Shipped + exported so the documented usage type-checks out
5
- * of the box — no consumer hand-authoring required.
6
- *
7
- * Add ONE line to any tsconfig-covered `.d.ts` (e.g. `src/env.d.ts`):
8
- * /// <reference types="@pyreon/zero/image-types" />
9
- *
10
- * Or via tsconfig.json:
11
- * "types": ["@pyreon/zero/image-types"]
12
- *
13
- * This is an ambient-only **script** (no top-level import/export) so
14
- * every `declare module` below is a global module augmentation. The
15
- * `ProcessedImage` shape is referenced via the package self-ref
16
- * `import('@pyreon/zero/image-plugin')` (resolution-stable in the
17
- * published layout, and re-uses the plugin's own type so it can never
18
- * drift out of sync).
19
- */
20
-
21
- declare module '*.jpg?optimize' {
22
- const image: import('@pyreon/zero/image-plugin').ProcessedImage
23
- export default image
24
- }
25
-
26
- declare module '*.jpeg?optimize' {
27
- const image: import('@pyreon/zero/image-plugin').ProcessedImage
28
- export default image
29
- }
30
-
31
- declare module '*.png?optimize' {
32
- const image: import('@pyreon/zero/image-plugin').ProcessedImage
33
- export default image
34
- }
35
-
36
- declare module '*.webp?optimize' {
37
- const image: import('@pyreon/zero/image-plugin').ProcessedImage
38
- export default image
39
- }
40
-
41
- declare module '*.avif?optimize' {
42
- const image: import('@pyreon/zero/image-plugin').ProcessedImage
43
- export default image
44
- }
45
-
46
- declare module '*.svg?component' {
47
- const component: import('@pyreon/core').ComponentFn<{
48
- width?: number
49
- height?: number
50
- class?: string
51
- style?: string
52
- [key: string]: unknown
53
- }>
54
- export default component
55
- }
56
-
57
- declare module '*.svg?raw' {
58
- const svg: string
59
- export default svg
60
- }
package/src/image.tsx DELETED
@@ -1,340 +0,0 @@
1
- import type { Ref, VNodeChild } from '@pyreon/core'
2
- import { createRef } from '@pyreon/core'
3
- import { signal } from '@pyreon/reactivity'
4
- import type { FormatSource } from './image-plugin'
5
- import { useIntersectionObserver } from './utils/use-intersection-observer'
6
-
7
- // ─── Image optimization component ───────────────────────────────────────────
8
- //
9
- // <Image> provides:
10
- // - Lazy loading via IntersectionObserver (loads when near viewport)
11
- // - Automatic width/height to prevent CLS (Cumulative Layout Shift)
12
- // - Responsive srcset generation from width descriptors
13
- // - Multi-format support via <picture> (WebP/AVIF with fallback)
14
- // - Blur-up placeholder while loading
15
- // - Priority loading for above-the-fold images
16
- //
17
- // Three levels of API (mirrors @pyreon/zero/link):
18
- //
19
- // 1. useImage(props) — composable returning resolved attributes + signals
20
- // 2. createImage(Comp) — HOC wrapping any component with image optimization
21
- // 3. Image — default <div><img/></div> wrapper (built on createImage)
22
-
23
- export interface ImageProps {
24
- /** Image source URL. */
25
- src: string
26
- /** Alt text (required for accessibility). */
27
- alt: string
28
- /** Intrinsic width of the image. */
29
- width: number
30
- /** Intrinsic height of the image. */
31
- height: number
32
- /** Responsive sizes attribute. Default: "100vw" */
33
- sizes?: string
34
- /** Responsive srcset string or source array. */
35
- srcset?: string | ImageSource[]
36
- /** Per-format source sets for <picture>. Provided automatically by imagePlugin. */
37
- formats?: FormatSource[]
38
- /** Loading strategy. "lazy" uses IntersectionObserver, "eager" loads immediately. Default: "lazy" */
39
- loading?: 'lazy' | 'eager'
40
- /** Mark as priority (LCP image). Disables lazy loading, adds fetchPriority="high". */
41
- priority?: boolean
42
- /** Low-quality placeholder image URL or base64 data URI for blur-up effect. */
43
- placeholder?: string
44
- /** CSS class name. */
45
- class?: string
46
- /** Inline styles. */
47
- style?: string
48
- /** CSS object-fit. Default: "cover" */
49
- fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'
50
- /** Decode async. Default: true */
51
- decoding?: 'sync' | 'async' | 'auto'
52
- /**
53
- * Raw mode — renders a plain `<img>` without the container div,
54
- * aspect-ratio, max-width, or lazy loading wrapper.
55
- * Use when the Image is inside a custom layout (absolute positioning, etc.).
56
- *
57
- * Note: `raw` skips the three-layer API entirely. `useImage` / `createImage`
58
- * do not apply when `raw: true` — the component returns a bare `<img>`.
59
- */
60
- raw?: boolean
61
- }
62
-
63
- export interface ImageSource {
64
- src: string
65
- width: number
66
- }
67
-
68
- /** Return type of {@link useImage}. */
69
- export interface UseImageReturn {
70
- /** Ref — attach to the container element for IntersectionObserver. */
71
- containerRef: Ref<HTMLElement>
72
- /** Whether the image has entered the viewport (and started loading). */
73
- inView: () => boolean
74
- /** Whether the `<img>` onLoad has fired. */
75
- loaded: () => boolean
76
- /** Resolved `src` accessor — empty string until inView, then `props.src`. */
77
- src: () => string
78
- /** Resolved srcSet accessor — empty until inView; empty when `formats` is set (srcset moves to `<source>` elements). */
79
- srcSet: () => string
80
- /** `sizes` attribute or undefined when no srcset. */
81
- sizes: string | undefined
82
- /** `aspect-ratio` CSS value (`"${width} / ${height}"`). */
83
- aspectRatio: string
84
- /** Resolved CSS for the container — position + overflow + aspect-ratio + max-width + caller's `style`. */
85
- containerStyle: string
86
- /** Resolved CSS accessor for the `<img>` — fit + transition + opacity (placeholder fade). */
87
- imageStyle: () => string
88
- /** Resolved CSS accessor for the placeholder `<img>` (only meaningful when `placeholder` is set). */
89
- placeholderStyle: () => string
90
- /** `loading` attribute — eager when priority/eager, else lazy. */
91
- loading: 'lazy' | 'eager'
92
- /** `fetchPriority` — 'high' when priority, else undefined. */
93
- fetchPriority: 'high' | undefined
94
- /** onLoad handler — sets the loaded signal. Wire into the rendered `<img>`. */
95
- handleLoad: () => void
96
- /** Resolved per-format <source> descriptors (or undefined when no formats). */
97
- formats: FormatSource[] | undefined
98
- /** Whether `formats` is non-empty (i.e. consumer should render a `<picture>` wrapper). */
99
- hasFormats: boolean
100
- }
101
-
102
- /** Props passed to a custom component via {@link createImage}. */
103
- export interface ImageRenderProps {
104
- /** Container ref. */
105
- containerRef: Ref<HTMLElement>
106
- /** CSS class for the container. */
107
- class: string | undefined
108
- /** Resolved container `style` string. */
109
- containerStyle: string
110
- /** Pre-rendered placeholder `<img>` (or `null` when `placeholder` is unset). */
111
- placeholder: VNodeChild
112
- /** Pre-rendered image — either a bare `<img>` or a `<picture>` tree when `formats` is set. */
113
- image: VNodeChild
114
- }
115
-
116
- /**
117
- * Composable that provides all image optimization behavior — lazy loading,
118
- * srcset/sizes resolution, format selection, blur-placeholder state,
119
- * load tracking.
120
- *
121
- * Use this for full control when `createImage` is too opinionated about
122
- * the surrounding markup (e.g. custom container layouts, non-`<div>`
123
- * wrappers, additional overlay elements).
124
- *
125
- * @example
126
- * function MyImage(props: ImageProps) {
127
- * const img = useImage(props)
128
- * return (
129
- * <figure ref={img.containerRef} style={img.containerStyle}>
130
- * <img
131
- * src={img.src}
132
- * srcSet={img.srcSet}
133
- * sizes={img.sizes}
134
- * alt={props.alt}
135
- * loading={img.loading}
136
- * onLoad={img.handleLoad}
137
- * style={img.imageStyle}
138
- * />
139
- * <figcaption>{props.alt}</figcaption>
140
- * </figure>
141
- * )
142
- * }
143
- */
144
- export function useImage(props: ImageProps): UseImageReturn {
145
- const isEager = props.priority || props.loading === 'eager'
146
- const loaded = signal(isEager)
147
- const inView = signal(isEager)
148
- const containerRef = createRef<HTMLElement>()
149
-
150
- // Resolve srcset from string or array
151
- const resolvedSrcset =
152
- typeof props.srcset === 'string'
153
- ? props.srcset
154
- : props.srcset?.map((s) => `${s.src} ${s.width}w`).join(', ')
155
-
156
- const sizes = props.sizes ?? '100vw'
157
- const fit = props.fit ?? 'cover'
158
- const hasFormats = !!(props.formats && props.formats.length > 0)
159
- const aspectRatio = `${props.width} / ${props.height}`
160
-
161
- if (!isEager) {
162
- useIntersectionObserver(
163
- () => containerRef.current ?? undefined,
164
- () => inView.set(true),
165
- )
166
- }
167
-
168
- const containerStyle = [
169
- 'position: relative',
170
- 'overflow: hidden',
171
- `aspect-ratio: ${aspectRatio}`,
172
- `max-width: ${props.width}px`,
173
- 'width: 100%',
174
- props.style,
175
- ]
176
- .filter(Boolean)
177
- .join('; ')
178
-
179
- const imageStyle = () =>
180
- [
181
- 'display: block',
182
- 'width: 100%',
183
- 'height: 100%',
184
- `object-fit: ${fit}`,
185
- 'transition: opacity 0.3s ease',
186
- props.placeholder && !loaded() ? 'opacity: 0' : 'opacity: 1',
187
- ].join('; ')
188
-
189
- const placeholderStyle = () =>
190
- [
191
- 'position: absolute',
192
- 'inset: 0',
193
- 'width: 100%',
194
- 'height: 100%',
195
- 'object-fit: cover',
196
- 'filter: blur(20px)',
197
- 'transform: scale(1.1)',
198
- 'transition: opacity 0.4s ease',
199
- loaded() ? 'opacity: 0; pointer-events: none' : 'opacity: 1',
200
- ].join('; ')
201
-
202
- return {
203
- containerRef,
204
- inView,
205
- loaded,
206
- src: () => (inView() ? props.src : ''),
207
- srcSet: () => (!hasFormats && inView() && resolvedSrcset ? resolvedSrcset : ''),
208
- sizes: resolvedSrcset ? sizes : undefined,
209
- aspectRatio,
210
- containerStyle,
211
- imageStyle,
212
- placeholderStyle,
213
- loading: isEager ? 'eager' : 'lazy',
214
- fetchPriority: props.priority ? 'high' : undefined,
215
- handleLoad: () => loaded.set(true),
216
- formats: props.formats,
217
- hasFormats,
218
- }
219
- }
220
-
221
- /**
222
- * Higher-order component that wraps any component with image optimization.
223
- *
224
- * The wrapped component receives {@link ImageRenderProps} with the pre-rendered
225
- * `image` JSX (bare `<img>` OR `<picture>` tree depending on formats), the
226
- * pre-rendered `placeholder` JSX, and the container ref + styles. Consumers
227
- * compose those pieces with whatever wrapper element / layout they want.
228
- *
229
- * @example
230
- * // Custom figure-based image with caption
231
- * const FigureImage = createImage((props) => (
232
- * <figure ref={props.containerRef} class={props.class} style={props.containerStyle}>
233
- * {props.placeholder}
234
- * {props.image}
235
- * <figcaption>Caption goes here</figcaption>
236
- * </figure>
237
- * ))
238
- *
239
- * // Usage — identical to default <Image>
240
- * <FigureImage src="/hero.jpg" alt="Hero" width={1200} height={630} />
241
- */
242
- export function createImage(
243
- Component: (p: ImageRenderProps) => any,
244
- ): (props: ImageProps) => any {
245
- return function WrappedImage(props: ImageProps) {
246
- // `raw` mode short-circuits — returns a bare <img> with no optimization
247
- // wrapper, no container, no createImage composition. Documented as the
248
- // no-optimization escape hatch.
249
- if (props.raw) {
250
- return (
251
- <img
252
- src={props.src}
253
- alt={props.alt}
254
- width={props.width}
255
- height={props.height}
256
- class={props.class}
257
- style={props.style}
258
- decoding={props.decoding ?? 'async'}
259
- loading={props.loading ?? 'lazy'}
260
- fetchPriority={props.priority ? 'high' : undefined}
261
- />
262
- )
263
- }
264
-
265
- const img = useImage(props)
266
-
267
- const imgEl = (
268
- <img
269
- src={img.src}
270
- srcSet={img.srcSet}
271
- sizes={img.sizes}
272
- alt={props.alt}
273
- width={props.width}
274
- height={props.height}
275
- loading={img.loading}
276
- decoding={props.decoding ?? 'async'}
277
- fetchPriority={img.fetchPriority}
278
- onLoad={img.handleLoad}
279
- style={img.imageStyle}
280
- />
281
- )
282
-
283
- const placeholderEl = props.placeholder
284
- ? (
285
- <img
286
- src={props.placeholder}
287
- alt=""
288
- aria-hidden="true"
289
- loading="eager"
290
- style={img.placeholderStyle}
291
- />
292
- )
293
- : null
294
-
295
- const imageEl = img.hasFormats
296
- ? (
297
- <picture>
298
- {img.formats?.map((fmt) => (
299
- <source
300
- type={fmt.type}
301
- srcSet={() => (img.inView() ? (fmt.srcset ?? '') : '')}
302
- sizes={img.sizes}
303
- />
304
- ))}
305
- {imgEl}
306
- </picture>
307
- )
308
- : imgEl
309
-
310
- return (
311
- <Component
312
- containerRef={img.containerRef}
313
- class={props.class}
314
- containerStyle={img.containerStyle}
315
- placeholder={placeholderEl}
316
- image={imageEl}
317
- />
318
- )
319
- }
320
- }
321
-
322
- /**
323
- * Default optimized image component with lazy loading, responsive srcset,
324
- * `<picture>` multi-format support, and blur-up placeholders.
325
- *
326
- * @example
327
- * // With imagePlugin — spread the import directly
328
- * import hero from "./hero.jpg?optimize"
329
- * <Image {...hero} alt="Hero" priority />
330
- *
331
- * @example
332
- * // Manual usage
333
- * <Image src="/hero.jpg" alt="Hero" width={1200} height={630} />
334
- */
335
- export const Image: (props: ImageProps) => any = createImage((props) => (
336
- <div ref={props.containerRef} class={props.class} style={props.containerStyle}>
337
- {props.placeholder}
338
- {props.image}
339
- </div>
340
- ))
package/src/index.ts DELETED
@@ -1,92 +0,0 @@
1
- /**
2
- * @pyreon/zero — client-safe exports.
3
- *
4
- * This entry contains only browser-safe components and hooks.
5
- * No node:fs, node:path, or other server-only imports.
6
- *
7
- * For server/build-time features, use subpath imports:
8
- * import { faviconPlugin } from "@pyreon/zero/favicon"
9
- * import { createServer } from "@pyreon/zero/server"
10
- * import { defineConfig } from "@pyreon/zero/config"
11
- * import { validateEnv } from "@pyreon/zero/env"
12
- */
13
-
14
- // ─── Components (browser-safe) ──────────────────────────────────────────────
15
-
16
- export type { IconMode, IconProps, NamedIconProps, SvgComponent } from "./icon";
17
- export { createIcon, createNamedIcon, Icon } from "./icon";
18
- export type { ImageProps, ImageRenderProps, ImageSource, UseImageReturn } from "./image";
19
- export { createImage, Image, useImage } from "./image";
20
- export type { LinkProps, LinkRenderProps, UseLinkReturn } from "./link";
21
- export { createLink, Link, prefetchRoute, useLink } from "./link";
22
- export type { ScriptProps, ScriptRenderProps, ScriptStrategy, UseScriptReturn } from "./script";
23
- export { createScript, Script, useScript } from "./script";
24
- export type { MetaProps } from "./meta";
25
- export { buildMetaTags, Meta } from "./meta";
26
-
27
- // ─── Theme (browser-safe) ───────────────────────────────────────────────────
28
-
29
- export type { Theme } from "./theme";
30
- export {
31
- initTheme,
32
- resolvedTheme,
33
- setSSRThemeDefault,
34
- setTheme,
35
- ThemeToggle,
36
- theme,
37
- themeScript,
38
- toggleTheme,
39
- } from "./theme";
40
-
41
- // ─── I18n hooks (browser-safe) ──────────────────────────────────────────────
42
-
43
- export type { I18nRoutingConfig, LocaleContext } from "./i18n-routing";
44
- export {
45
- buildLocalePath,
46
- extractLocaleFromPath,
47
- setLocale,
48
- useLocale,
49
- } from "./i18n-routing";
50
-
51
- // ─── Server-only stubs ──────────────────────────────────────────────────────
52
- // Throw clear error messages when developers accidentally import server-only
53
- // APIs from the main entry. These are tree-shaken if not imported.
54
-
55
- function serverOnly(name: string, subpath: string): never {
56
- throw new Error(
57
- `[Pyreon] "${name}" is server-only and cannot be imported from "@pyreon/zero".\n` +
58
- `Import from the subpath instead:\n\n` +
59
- ` import { ${name} } from "@pyreon/zero/${subpath}"\n`,
60
- )
61
- }
62
-
63
- /* eslint-disable @typescript-eslint/no-unused-vars */
64
- /** @deprecated Import from `@pyreon/zero/favicon` instead */
65
- export function faviconPlugin(..._: unknown[]): never { return serverOnly('faviconPlugin', 'favicon') }
66
- /** @deprecated Import from `@pyreon/zero/seo` instead */
67
- export function seoPlugin(..._: unknown[]): never { return serverOnly('seoPlugin', 'seo') }
68
- /** @deprecated Import from `@pyreon/zero/server` instead */
69
- export function createServer(..._: unknown[]): never { return serverOnly('createServer', 'server') }
70
- /** @deprecated Import from `@pyreon/zero/config` instead */
71
- export function defineConfig(..._: unknown[]): never { return serverOnly('defineConfig', 'config') }
72
- /** @deprecated Import from `@pyreon/zero/env` instead */
73
- export function validateEnv(..._: unknown[]): never { return serverOnly('validateEnv', 'env') }
74
- /** @deprecated Import from `@pyreon/zero/og-image` instead */
75
- export function ogImagePlugin(..._: unknown[]): never { return serverOnly('ogImagePlugin', 'og-image') }
76
- /** @deprecated Import from `@pyreon/zero/ai` instead */
77
- export function aiPlugin(..._: unknown[]): never { return serverOnly('aiPlugin', 'ai') }
78
-
79
- // ─── Types (no runtime, safe everywhere) ────────────────────────────────────
80
-
81
- export type {
82
- Adapter,
83
- AdapterBuildOptions,
84
- FileRoute,
85
- ISRConfig,
86
- LoaderContext,
87
- RenderMode,
88
- RouteMeta,
89
- RouteMiddlewareEntry,
90
- RouteModule,
91
- ZeroConfig,
92
- } from "./types";