@gradial/aci 0.1.1 → 0.1.3

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 (57) hide show
  1. package/README.md +65 -1
  2. package/bin/aci +0 -0
  3. package/bin/aci.js +139 -27
  4. package/dist/assets/index.d.ts +2 -0
  5. package/dist/assets/index.js +2 -0
  6. package/dist/astro/index.js +4 -4
  7. package/dist/block-ref.d.ts +34 -0
  8. package/dist/block-ref.js +34 -0
  9. package/dist/define-component.d.ts +1 -0
  10. package/dist/define-component.js +1 -0
  11. package/dist/define-layout.d.ts +1 -0
  12. package/dist/define-layout.js +1 -0
  13. package/dist/dev/index.d.ts +6 -0
  14. package/dist/dev/index.js +66 -0
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +4 -1
  17. package/dist/next/asset-route.d.ts +9 -0
  18. package/dist/next/asset-route.js +15 -0
  19. package/dist/next/config.d.ts +2 -10
  20. package/dist/next/config.js +5 -2
  21. package/dist/next/server.d.ts +4 -0
  22. package/dist/next/server.js +53 -0
  23. package/dist/providers/s3.d.ts +2 -0
  24. package/dist/providers/s3.js +13 -1
  25. package/dist/react/GradialMedia.d.ts +24 -0
  26. package/dist/react/GradialMedia.js +31 -0
  27. package/dist/react/GradialPicture.d.ts +14 -0
  28. package/dist/react/GradialPicture.js +30 -0
  29. package/dist/react/GradialVideoPlayer.d.ts +13 -0
  30. package/dist/react/GradialVideoPlayer.js +28 -0
  31. package/dist/react/index.d.ts +3 -0
  32. package/dist/react/index.js +3 -0
  33. package/dist/sveltekit/index.js +6 -1
  34. package/dist/types/component.d.ts +8 -3
  35. package/dist/types/image.d.ts +2 -2
  36. package/dist/types/image.js +1 -1
  37. package/dist/types/index.d.ts +2 -0
  38. package/dist/types/index.js +2 -0
  39. package/dist/types/media.d.ts +69 -0
  40. package/dist/types/media.js +86 -0
  41. package/dist/types/video.d.ts +70 -0
  42. package/dist/types/video.js +22 -0
  43. package/package.json +14 -9
  44. package/src/cli/compile-registry.mjs +142 -1
  45. package/src/cli/validate-content.mjs +98 -0
  46. package/src/types/component.ts +59 -0
  47. package/src/types/config.ts +36 -0
  48. package/src/types/image.ts +100 -0
  49. package/src/types/index.ts +9 -0
  50. package/src/types/layout.ts +29 -0
  51. package/src/types/media.ts +125 -0
  52. package/src/types/page.ts +48 -0
  53. package/src/types/render-mode.ts +18 -0
  54. package/src/types/renderer.ts +83 -0
  55. package/src/types/video.ts +66 -0
  56. package/src/cli/css-stub-loader.mjs +0 -27
  57. package/src/cli/generate-registry.mjs +0 -72
@@ -0,0 +1,48 @@
1
+ import type { RenderMode, VaryDimension } from './render-mode.js';
2
+
3
+ export interface PageDocument {
4
+ path: string;
5
+ layout: string;
6
+ locale: string;
7
+ metadata: PageMetadata;
8
+ regions: Record<string, RegionNode>;
9
+ renderMode: RenderMode;
10
+ }
11
+
12
+ export interface PageMetadata {
13
+ title: string;
14
+ description?: string;
15
+ openGraph?: Record<string, string>;
16
+ canonicalUrl?: string;
17
+ alternateLocales?: { locale: string; path: string }[];
18
+ customHead?: string[];
19
+ }
20
+
21
+ export interface RegionNode {
22
+ kind: 'region';
23
+ name: string;
24
+ children: Array<BlockNode | FragmentRefNode>;
25
+ }
26
+
27
+ export interface BlockNode {
28
+ kind: 'block';
29
+ id: string;
30
+ component: string;
31
+ props: Record<string, unknown>;
32
+ renderHints: BlockRenderHints;
33
+ contentRef?: string;
34
+ }
35
+
36
+ export interface BlockRenderHints {
37
+ canStatic: boolean;
38
+ needsSSR: boolean;
39
+ isIsland: boolean;
40
+ islandMode?: 'ssr' | 'client';
41
+ varyDimensions?: VaryDimension[];
42
+ }
43
+
44
+ export interface FragmentRefNode {
45
+ kind: 'fragment-ref';
46
+ fragmentId: string;
47
+ inline: boolean;
48
+ }
@@ -0,0 +1,18 @@
1
+ export type RenderMode =
2
+ | 'static'
3
+ | 'static-with-fragments'
4
+ | 'prerender-on-demand'
5
+ | 'ssr-page'
6
+ | 'ssr-island'
7
+ | 'client-island';
8
+
9
+ export type IslandMode = 'ssr' | 'client';
10
+
11
+ export type VaryDimension =
12
+ | 'geo:country'
13
+ | 'geo:region'
14
+ | 'geo:city'
15
+ | `cookie:${string}`
16
+ | `header:${string}`
17
+ | 'locale'
18
+ | `query:${string}`;
@@ -0,0 +1,83 @@
1
+ import type { PageDocument } from './page.js';
2
+ import type { VaryDimension } from './render-mode.js';
3
+
4
+ export interface RenderCapabilities {
5
+ staticRender: boolean;
6
+ ssr: boolean;
7
+ ssrIslands: boolean;
8
+ clientIslands: boolean;
9
+ fragmentRender: boolean;
10
+ }
11
+
12
+ export interface GradialRenderer {
13
+ renderPage(request: RenderPageRequest): Promise<RenderPageResult>;
14
+ renderFragment?(request: RenderFragmentRequest): Promise<RenderResult>;
15
+ renderIsland?(request: RenderIslandRequest): Promise<RenderResult>;
16
+ }
17
+
18
+ export interface RenderPageRequest {
19
+ page: PageDocument;
20
+ requestContext?: RequestContext;
21
+ release: ReleaseContext;
22
+ }
23
+
24
+ export interface RequestContext {
25
+ url: string;
26
+ method: string;
27
+ headers: Record<string, string>;
28
+ cookies: Record<string, string>;
29
+ geo?: GeoContext;
30
+ }
31
+
32
+ export interface GeoContext {
33
+ country?: string;
34
+ region?: string;
35
+ city?: string;
36
+ }
37
+
38
+ export interface ReleaseContext {
39
+ releaseId: string;
40
+ codeDigest: string;
41
+ contentSnapshotId: string;
42
+ assetUrl(logicalPath: string): string;
43
+ }
44
+
45
+ export interface RenderFragmentRequest {
46
+ fragmentId: string;
47
+ content: unknown;
48
+ release: ReleaseContext;
49
+ }
50
+
51
+ export interface RenderIslandRequest {
52
+ islandId: string;
53
+ component: string;
54
+ props: Record<string, unknown>;
55
+ requestContext: RequestContext;
56
+ release: ReleaseContext;
57
+ }
58
+
59
+ export interface RenderResult {
60
+ html: string;
61
+ status?: number;
62
+ headers?: Record<string, string>;
63
+ cachePolicy?: CachePolicy;
64
+ }
65
+
66
+ export interface RenderPageResult extends RenderResult {
67
+ islands?: IslandDescriptor[];
68
+ }
69
+
70
+ export interface IslandDescriptor {
71
+ islandId: string;
72
+ component: string;
73
+ props: Record<string, unknown>;
74
+ mode: 'ssr' | 'client';
75
+ varyDimensions?: VaryDimension[];
76
+ }
77
+
78
+ export interface CachePolicy {
79
+ scope: 'public' | 'private' | 'no-store';
80
+ ttl?: number;
81
+ staleWhileRevalidate?: number;
82
+ tags?: string[];
83
+ }
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { GradialImageSchema, type GradialImage } from './image.js';
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Video source variant (format alternatives)
6
+ // ---------------------------------------------------------------------------
7
+
8
+ export interface VideoSource {
9
+ src: string;
10
+ type: string; // MIME type: video/mp4, video/webm
11
+ }
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // GradialVideo — DAM-backed video asset with compiler-resolved derivatives
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface GradialVideo {
18
+ /** Discriminator — always 'gradial.video'. */
19
+ $type: 'gradial.video';
20
+ /** DAM asset identifier. */
21
+ assetId: string;
22
+ /** DAM version identifier. */
23
+ versionId: string;
24
+ /** Accessible description of the video content. */
25
+ alt: string;
26
+ /** Primary video URL (compiler-resolved). */
27
+ src: string;
28
+ /** Primary video MIME type (e.g. 'video/mp4'). */
29
+ type: string;
30
+ /** Intrinsic width in pixels. */
31
+ width: number;
32
+ /** Intrinsic height in pixels. */
33
+ height: number;
34
+ /**
35
+ * Poster frame — a full GradialImage with responsive srcset.
36
+ * The compiler extracts or generates this from the video asset.
37
+ */
38
+ poster?: GradialImage;
39
+ /** Format variants (e.g. mp4 + webm). Maps to <video><source> elements. */
40
+ sources?: VideoSource[];
41
+ /** Duration in seconds (if known). */
42
+ duration?: number;
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Zod schema
47
+ // ---------------------------------------------------------------------------
48
+
49
+ export const VideoSourceSchema = z.object({
50
+ src: z.string().min(1),
51
+ type: z.string().min(1),
52
+ });
53
+
54
+ export const GradialVideoSchema = z.object({
55
+ $type: z.literal('gradial.video'),
56
+ assetId: z.string().min(1),
57
+ versionId: z.string().min(1),
58
+ alt: z.string(),
59
+ src: z.string().min(1),
60
+ type: z.string().min(1),
61
+ width: z.number().int().nonnegative(),
62
+ height: z.number().int().nonnegative(),
63
+ poster: GradialImageSchema.optional(),
64
+ sources: z.array(VideoSourceSchema).optional(),
65
+ duration: z.number().nonnegative().optional(),
66
+ });
@@ -1,27 +0,0 @@
1
- /**
2
- * Node.js custom loader that stubs CSS module imports.
3
- * Used by CLI tools (compile-registry, validate-content) that need to import
4
- * component files without actually loading CSS.
5
- *
6
- * Usage: node --import tsx --loader ./css-stub-loader.mjs <script>
7
- */
8
-
9
- const CSS_EXTENSIONS = ['.css', '.module.css', '.scss', '.module.scss', '.less'];
10
-
11
- export function resolve(specifier, context, nextResolve) {
12
- if (CSS_EXTENSIONS.some((ext) => specifier.endsWith(ext))) {
13
- return { url: `css-stub:${specifier}`, shortCircuit: true };
14
- }
15
- return nextResolve(specifier, context);
16
- }
17
-
18
- export function load(url, context, nextLoad) {
19
- if (url.startsWith('css-stub:')) {
20
- return {
21
- format: 'module',
22
- source: 'export default {};',
23
- shortCircuit: true,
24
- };
25
- }
26
- return nextLoad(url, context);
27
- }
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * generate-registry — Derives a runtime registry from co-located component contracts.
4
- *
5
- * Usage:
6
- * baremetal generate-registry --contracts <path> --output <path>
7
- *
8
- * --contracts Path to the aggregation module (default-exports an array of ComponentContract).
9
- * --output Path to the generated TypeScript file.
10
- *
11
- * The generated file imports the contracts module and derives:
12
- * - `registry`: a flat map of component name -> component function (for the renderer)
13
- * - `contractMap`: a flat map of component name -> full contract (for tooling/validation)
14
- */
15
- import { writeFile, mkdir } from 'node:fs/promises';
16
- import path from 'node:path';
17
-
18
- const args = parseArgs(process.argv.slice(2));
19
-
20
- if (!args.contracts) {
21
- console.error('Error: --contracts <path> is required');
22
- process.exitCode = 1;
23
- } else if (!args.output) {
24
- console.error('Error: --output <path> is required');
25
- process.exitCode = 1;
26
- } else {
27
- try {
28
- await generateRegistry(args);
29
- console.log(`Registry generated at ${args.output}`);
30
- } catch (error) {
31
- console.error(`Error: ${error?.message ?? error}`);
32
- process.exitCode = 1;
33
- }
34
- }
35
-
36
- async function generateRegistry({ contracts, output }) {
37
- const contractsPath = contracts.replace(/\.(ts|tsx|js|mjs)$/, '');
38
- const outputPath = path.resolve(output);
39
-
40
- await mkdir(path.dirname(outputPath), { recursive: true });
41
-
42
- const content = `// AUTO-GENERATED — do not edit. Run \`baremetal generate-registry\` to regenerate.
43
- import type { ComponentContract } from '@baremetal/sdk';
44
- import contracts from '${contractsPath}';
45
-
46
- export const registry = Object.fromEntries(
47
- contracts.filter((c) => c.component != null).map((c) => [c.name, c.component]),
48
- );
49
-
50
- export const contractMap: Record<string, ComponentContract> = Object.fromEntries(
51
- contracts.map((c) => [c.name, c]),
52
- );
53
- `;
54
-
55
- await writeFile(outputPath, content, 'utf-8');
56
- }
57
-
58
- function parseArgs(argv) {
59
- const out = {};
60
- for (let i = 0; i < argv.length; i++) {
61
- const arg = argv[i];
62
- if (!arg.startsWith('--')) continue;
63
- const body = arg.slice(2);
64
- const equals = body.indexOf('=');
65
- if (equals >= 0) {
66
- out[body.slice(0, equals)] = body.slice(equals + 1);
67
- continue;
68
- }
69
- out[body] = argv[++i];
70
- }
71
- return out;
72
- }