@vistagenic/vista 0.1.0-alpha.1

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 (100) hide show
  1. package/bin/vista.js +98 -0
  2. package/dist/auth/index.d.ts +8 -0
  3. package/dist/auth/index.js +16 -0
  4. package/dist/bin/build-rsc.d.ts +17 -0
  5. package/dist/bin/build-rsc.js +320 -0
  6. package/dist/bin/build.d.ts +4 -0
  7. package/dist/bin/build.js +336 -0
  8. package/dist/bin/file-scanner.d.ts +66 -0
  9. package/dist/bin/file-scanner.js +399 -0
  10. package/dist/bin/server-component-plugin.d.ts +17 -0
  11. package/dist/bin/server-component-plugin.js +133 -0
  12. package/dist/bin/webpack.config.d.ts +6 -0
  13. package/dist/bin/webpack.config.js +138 -0
  14. package/dist/build/manifest.d.ts +95 -0
  15. package/dist/build/manifest.js +168 -0
  16. package/dist/build/rsc/client-manifest.d.ts +48 -0
  17. package/dist/build/rsc/client-manifest.js +191 -0
  18. package/dist/build/rsc/client-reference-plugin.d.ts +37 -0
  19. package/dist/build/rsc/client-reference-plugin.js +185 -0
  20. package/dist/build/rsc/compiler.d.ts +36 -0
  21. package/dist/build/rsc/compiler.js +311 -0
  22. package/dist/build/rsc/index.d.ts +16 -0
  23. package/dist/build/rsc/index.js +32 -0
  24. package/dist/build/rsc/native-scanner.d.ts +123 -0
  25. package/dist/build/rsc/native-scanner.js +165 -0
  26. package/dist/build/rsc/rsc-renderer.d.ts +99 -0
  27. package/dist/build/rsc/rsc-renderer.js +269 -0
  28. package/dist/build/rsc/server-component-loader.d.ts +19 -0
  29. package/dist/build/rsc/server-component-loader.js +147 -0
  30. package/dist/build/rsc/server-manifest.d.ts +63 -0
  31. package/dist/build/rsc/server-manifest.js +268 -0
  32. package/dist/build/webpack/loaders/vista-flight-loader.d.ts +17 -0
  33. package/dist/build/webpack/loaders/vista-flight-loader.js +93 -0
  34. package/dist/build/webpack/plugins/vista-flight-plugin.d.ts +36 -0
  35. package/dist/build/webpack/plugins/vista-flight-plugin.js +133 -0
  36. package/dist/client/dynamic.d.ts +25 -0
  37. package/dist/client/dynamic.js +68 -0
  38. package/dist/client/font.d.ts +98 -0
  39. package/dist/client/font.js +109 -0
  40. package/dist/client/head.d.ts +79 -0
  41. package/dist/client/head.js +261 -0
  42. package/dist/client/hydration.d.ts +45 -0
  43. package/dist/client/hydration.js +291 -0
  44. package/dist/client/link.d.ts +30 -0
  45. package/dist/client/link.js +188 -0
  46. package/dist/client/navigation.d.ts +28 -0
  47. package/dist/client/navigation.js +116 -0
  48. package/dist/client/router.d.ts +41 -0
  49. package/dist/client/router.js +190 -0
  50. package/dist/client/script.d.ts +51 -0
  51. package/dist/client/script.js +118 -0
  52. package/dist/components/client-island.d.ts +34 -0
  53. package/dist/components/client-island.js +75 -0
  54. package/dist/components/client.d.ts +29 -0
  55. package/dist/components/client.js +102 -0
  56. package/dist/components/index.d.ts +1 -0
  57. package/dist/components/index.js +8 -0
  58. package/dist/components/link.d.ts +6 -0
  59. package/dist/components/link.js +13 -0
  60. package/dist/config.d.ts +10 -0
  61. package/dist/config.js +31 -0
  62. package/dist/dev-error.d.ts +35 -0
  63. package/dist/dev-error.js +310 -0
  64. package/dist/image/get-img-props.d.ts +28 -0
  65. package/dist/image/get-img-props.js +49 -0
  66. package/dist/image/image-config.d.ts +20 -0
  67. package/dist/image/image-config.js +20 -0
  68. package/dist/image/image-loader.d.ts +7 -0
  69. package/dist/image/image-loader.js +14 -0
  70. package/dist/image/index.d.ts +6 -0
  71. package/dist/image/index.js +110 -0
  72. package/dist/image.d.ts +10 -0
  73. package/dist/image.js +7 -0
  74. package/dist/index.d.ts +20 -0
  75. package/dist/index.js +53 -0
  76. package/dist/metadata/generate.d.ts +22 -0
  77. package/dist/metadata/generate.js +324 -0
  78. package/dist/metadata/index.d.ts +7 -0
  79. package/dist/metadata/index.js +26 -0
  80. package/dist/metadata/types.d.ts +325 -0
  81. package/dist/metadata/types.js +15 -0
  82. package/dist/router/context.d.ts +8 -0
  83. package/dist/router/context.js +13 -0
  84. package/dist/router/index.d.ts +2 -0
  85. package/dist/router/index.js +18 -0
  86. package/dist/router/provider.d.ts +5 -0
  87. package/dist/router/provider.js +31 -0
  88. package/dist/server/client-boundary.d.ts +48 -0
  89. package/dist/server/client-boundary.js +133 -0
  90. package/dist/server/engine.d.ts +4 -0
  91. package/dist/server/engine.js +651 -0
  92. package/dist/server/index.d.ts +95 -0
  93. package/dist/server/index.js +177 -0
  94. package/dist/server/rsc-engine.d.ts +20 -0
  95. package/dist/server/rsc-engine.js +588 -0
  96. package/dist/server/rsc-module-system.d.ts +33 -0
  97. package/dist/server/rsc-module-system.js +119 -0
  98. package/dist/types/index.d.ts +4 -0
  99. package/dist/types/index.js +2 -0
  100. package/package.json +103 -0
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Head = Head;
37
+ exports.generateMetadataHead = generateMetadataHead;
38
+ const jsx_runtime_1 = require("react/jsx-runtime");
39
+ /**
40
+ * Vista Head Component
41
+ *
42
+ * Allows injection of elements into the document <head>.
43
+ * Similar to Next.js Head component.
44
+ */
45
+ const React = __importStar(require("react"));
46
+ // Store for head elements (for SSR)
47
+ const headElements = [];
48
+ /**
49
+ * Head component - injects children into document head
50
+ */
51
+ function Head({ children }) {
52
+ React.useEffect(() => {
53
+ if (typeof document === 'undefined')
54
+ return;
55
+ const head = document.head;
56
+ const fragment = document.createDocumentFragment();
57
+ const elements = [];
58
+ // Process children
59
+ React.Children.forEach(children, (child) => {
60
+ if (!React.isValidElement(child))
61
+ return;
62
+ const { type, props } = child;
63
+ let element = null;
64
+ if (type === 'title') {
65
+ // Update existing title or create new
66
+ const existingTitle = head.querySelector('title');
67
+ if (existingTitle) {
68
+ existingTitle.textContent = props.children;
69
+ return;
70
+ }
71
+ element = document.createElement('title');
72
+ element.textContent = props.children;
73
+ }
74
+ else if (type === 'meta') {
75
+ // Check for existing meta with same name/property
76
+ const name = (props.name || props.property);
77
+ if (name) {
78
+ const selector = props.name
79
+ ? `meta[name="${props.name}"]`
80
+ : `meta[property="${props.property}"]`;
81
+ const existing = head.querySelector(selector);
82
+ if (existing) {
83
+ existing.setAttribute('content', props.content);
84
+ return;
85
+ }
86
+ }
87
+ element = document.createElement('meta');
88
+ Object.entries(props).forEach(([key, value]) => {
89
+ if (key !== 'children' && value !== undefined) {
90
+ element.setAttribute(key, String(value));
91
+ }
92
+ });
93
+ }
94
+ else if (type === 'link') {
95
+ // Check for existing link with same href
96
+ if (props.rel === 'canonical') {
97
+ const existing = head.querySelector('link[rel="canonical"]');
98
+ if (existing) {
99
+ existing.setAttribute('href', props.href);
100
+ return;
101
+ }
102
+ }
103
+ element = document.createElement('link');
104
+ Object.entries(props).forEach(([key, value]) => {
105
+ if (key !== 'children' && value !== undefined) {
106
+ element.setAttribute(key, String(value));
107
+ }
108
+ });
109
+ }
110
+ else if (type === 'style') {
111
+ element = document.createElement('style');
112
+ if (props.dangerouslySetInnerHTML) {
113
+ element.innerHTML = props.dangerouslySetInnerHTML.__html;
114
+ }
115
+ else if (props.children) {
116
+ element.textContent = props.children;
117
+ }
118
+ if (props.id)
119
+ element.id = props.id;
120
+ }
121
+ else if (type === 'script') {
122
+ element = document.createElement('script');
123
+ Object.entries(props).forEach(([key, value]) => {
124
+ if (key === 'dangerouslySetInnerHTML') {
125
+ element.innerHTML = value.__html;
126
+ }
127
+ else if (key !== 'children' && value !== undefined) {
128
+ element.setAttribute(key, String(value));
129
+ }
130
+ });
131
+ if (props.children) {
132
+ element.textContent = props.children;
133
+ }
134
+ }
135
+ if (element) {
136
+ elements.push(element);
137
+ fragment.appendChild(element);
138
+ }
139
+ });
140
+ // Append all elements
141
+ head.appendChild(fragment);
142
+ // Cleanup on unmount
143
+ return () => {
144
+ elements.forEach((el) => {
145
+ if (el.parentNode === head) {
146
+ head.removeChild(el);
147
+ }
148
+ });
149
+ };
150
+ }, [children]);
151
+ return null;
152
+ }
153
+ /**
154
+ * Generate head elements from metadata object
155
+ */
156
+ function generateMetadataHead(metadata) {
157
+ const elements = [];
158
+ // Title
159
+ if (metadata.title) {
160
+ const titleStr = typeof metadata.title === 'string'
161
+ ? metadata.title
162
+ : metadata.title.default;
163
+ elements.push((0, jsx_runtime_1.jsx)("title", { children: titleStr }, "title"));
164
+ }
165
+ // Description
166
+ if (metadata.description) {
167
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "description", content: metadata.description }, "description"));
168
+ }
169
+ // Keywords
170
+ if (metadata.keywords) {
171
+ const keywordsStr = Array.isArray(metadata.keywords)
172
+ ? metadata.keywords.join(', ')
173
+ : metadata.keywords;
174
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "keywords", content: keywordsStr }, "keywords"));
175
+ }
176
+ // Viewport
177
+ if (metadata.viewport) {
178
+ const viewportStr = typeof metadata.viewport === 'string'
179
+ ? metadata.viewport
180
+ : `width=${metadata.viewport.width || 'device-width'}, initial-scale=${metadata.viewport.initialScale || 1}`;
181
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "viewport", content: viewportStr }, "viewport"));
182
+ }
183
+ // Theme color
184
+ if (metadata.themeColor) {
185
+ if (typeof metadata.themeColor === 'string') {
186
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "theme-color", content: metadata.themeColor }, "themeColor"));
187
+ }
188
+ }
189
+ // Robots
190
+ if (metadata.robots) {
191
+ const robotsStr = typeof metadata.robots === 'string'
192
+ ? metadata.robots
193
+ : `${metadata.robots.index !== false ? 'index' : 'noindex'}, ${metadata.robots.follow !== false ? 'follow' : 'nofollow'}`;
194
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "robots", content: robotsStr }, "robots"));
195
+ }
196
+ // Open Graph
197
+ if (metadata.openGraph) {
198
+ const og = metadata.openGraph;
199
+ if (og.title)
200
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:title", content: og.title }, "og:title"));
201
+ if (og.description)
202
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:description", content: og.description }, "og:description"));
203
+ if (og.url)
204
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:url", content: og.url }, "og:url"));
205
+ if (og.siteName)
206
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:site_name", content: og.siteName }, "og:site_name"));
207
+ if (og.type)
208
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:type", content: og.type }, "og:type"));
209
+ if (og.locale)
210
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:locale", content: og.locale }, "og:locale"));
211
+ if (og.images) {
212
+ og.images.forEach((img, i) => {
213
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image", content: img.url }, `og:image:${i}`));
214
+ if (img.width)
215
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image:width", content: String(img.width) }, `og:image:width:${i}`));
216
+ if (img.height)
217
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image:height", content: String(img.height) }, `og:image:height:${i}`));
218
+ if (img.alt)
219
+ elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image:alt", content: img.alt }, `og:image:alt:${i}`));
220
+ });
221
+ }
222
+ }
223
+ // Twitter
224
+ if (metadata.twitter) {
225
+ const tw = metadata.twitter;
226
+ if (tw.card)
227
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:card", content: tw.card }, "twitter:card"));
228
+ if (tw.site)
229
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:site", content: tw.site }, "twitter:site"));
230
+ if (tw.creator)
231
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:creator", content: tw.creator }, "twitter:creator"));
232
+ if (tw.title)
233
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:title", content: tw.title }, "twitter:title"));
234
+ if (tw.description)
235
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:description", content: tw.description }, "twitter:description"));
236
+ if (tw.images) {
237
+ tw.images.forEach((img, i) => {
238
+ elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:image", content: img }, `twitter:image:${i}`));
239
+ });
240
+ }
241
+ }
242
+ // Canonical
243
+ if (metadata.alternates?.canonical) {
244
+ elements.push((0, jsx_runtime_1.jsx)("link", { rel: "canonical", href: metadata.alternates.canonical }, "canonical"));
245
+ }
246
+ // Manifest
247
+ if (metadata.manifest) {
248
+ elements.push((0, jsx_runtime_1.jsx)("link", { rel: "manifest", href: metadata.manifest }, "manifest"));
249
+ }
250
+ // Icons
251
+ if (metadata.icons) {
252
+ if (metadata.icons.icon) {
253
+ elements.push((0, jsx_runtime_1.jsx)("link", { rel: "icon", href: metadata.icons.icon }, "icon"));
254
+ }
255
+ if (metadata.icons.apple) {
256
+ elements.push((0, jsx_runtime_1.jsx)("link", { rel: "apple-touch-icon", href: metadata.icons.apple }, "apple-touch-icon"));
257
+ }
258
+ }
259
+ return (0, jsx_runtime_1.jsx)(Head, { children: elements });
260
+ }
261
+ exports.default = Head;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Vista Selective Hydration
3
+ *
4
+ * This module provides selective hydration for RSC (React Server Components).
5
+ *
6
+ * Key Features:
7
+ * - Only hydrates client component "islands"
8
+ * - Server components are rendered as static HTML
9
+ * - Progressive hydration based on priority and visibility
10
+ * - Minimal JavaScript for maximum performance
11
+ */
12
+ export interface ClientReference {
13
+ id: string;
14
+ mountId: string;
15
+ props: Record<string, any>;
16
+ chunkUrl: string;
17
+ exportName: string;
18
+ }
19
+ export interface HydrationOptions {
20
+ /** Whether to use progressive hydration based on visibility */
21
+ progressive?: boolean;
22
+ /** Hydration priority (higher = sooner) */
23
+ priority?: 'high' | 'normal' | 'low';
24
+ /** Whether to use requestIdleCallback for low priority */
25
+ useIdleCallback?: boolean;
26
+ }
27
+ /**
28
+ * Hydrate a single client component
29
+ */
30
+ declare function hydrateComponent(reference: ClientReference): Promise<void>;
31
+ /**
32
+ * Hydrate all client components on the page
33
+ */
34
+ export declare function hydrateClientComponents(options?: HydrationOptions): Promise<void>;
35
+ /**
36
+ * Initialize Vista hydration
37
+ * Call this after the page loads
38
+ */
39
+ export declare function initializeHydration(): void;
40
+ declare const _default: {
41
+ hydrateClientComponents: typeof hydrateClientComponents;
42
+ hydrateComponent: typeof hydrateComponent;
43
+ initializeHydration: typeof initializeHydration;
44
+ };
45
+ export default _default;
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ /**
3
+ * Vista Selective Hydration
4
+ *
5
+ * This module provides selective hydration for RSC (React Server Components).
6
+ *
7
+ * Key Features:
8
+ * - Only hydrates client component "islands"
9
+ * - Server components are rendered as static HTML
10
+ * - Progressive hydration based on priority and visibility
11
+ * - Minimal JavaScript for maximum performance
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.hydrateClientComponents = hydrateClientComponents;
48
+ exports.initializeHydration = initializeHydration;
49
+ const React = __importStar(require("react"));
50
+ const client_1 = require("react-dom/client");
51
+ // Track hydrated components
52
+ const hydratedComponents = new Set();
53
+ const loadedChunks = new Map();
54
+ const pendingHydrations = new Map();
55
+ /**
56
+ * Deserialize props that were serialized on the server
57
+ */
58
+ function deserializeProps(props) {
59
+ const result = {};
60
+ for (const [key, value] of Object.entries(props)) {
61
+ if (value && typeof value === 'object' && value.__type) {
62
+ switch (value.__type) {
63
+ case 'Date':
64
+ result[key] = new Date(value.value);
65
+ break;
66
+ case 'undefined':
67
+ result[key] = undefined;
68
+ break;
69
+ case 'ReactElement':
70
+ // React elements rendered on server - keep as is
71
+ result[key] = null;
72
+ break;
73
+ default:
74
+ result[key] = value;
75
+ }
76
+ }
77
+ else {
78
+ result[key] = value;
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+ /**
84
+ * Load a chunk dynamically
85
+ * Uses indirect eval to bypass webpack's static analysis
86
+ */
87
+ async function loadChunk(chunkUrl) {
88
+ if (loadedChunks.has(chunkUrl)) {
89
+ return loadedChunks.get(chunkUrl);
90
+ }
91
+ try {
92
+ // Use Function constructor to create dynamic import that webpack won't analyze
93
+ // This prevents the "Critical dependency" warning
94
+ const dynamicImport = new Function('url', 'return import(url)');
95
+ const module = await dynamicImport(chunkUrl);
96
+ loadedChunks.set(chunkUrl, module);
97
+ return module;
98
+ }
99
+ catch (error) {
100
+ console.error(`[Vista] Failed to load chunk: ${chunkUrl}`, error);
101
+ throw error;
102
+ }
103
+ }
104
+ /**
105
+ * Hydrate a single client component
106
+ */
107
+ async function hydrateComponent(reference) {
108
+ // Skip if already hydrated
109
+ if (hydratedComponents.has(reference.mountId)) {
110
+ return;
111
+ }
112
+ // Check if already pending
113
+ if (pendingHydrations.has(reference.mountId)) {
114
+ return pendingHydrations.get(reference.mountId);
115
+ }
116
+ const hydrationPromise = (async () => {
117
+ try {
118
+ // Find mount point
119
+ const mountPoint = document.getElementById(reference.mountId);
120
+ if (!mountPoint) {
121
+ console.warn(`[Vista] Mount point not found: ${reference.mountId}`);
122
+ return;
123
+ }
124
+ // Load the component chunk
125
+ const module = await loadChunk(reference.chunkUrl);
126
+ const Component = module[reference.exportName] || module.default;
127
+ if (!Component) {
128
+ console.error(`[Vista] Component not found in chunk: ${reference.exportName}`);
129
+ return;
130
+ }
131
+ // Deserialize props
132
+ const props = deserializeProps(reference.props);
133
+ // Check if there's existing content to hydrate
134
+ const hasContent = mountPoint.innerHTML.trim().length > 0;
135
+ if (hasContent) {
136
+ // Hydrate existing SSR content
137
+ (0, client_1.hydrateRoot)(mountPoint, React.createElement(Component, props));
138
+ }
139
+ else {
140
+ // No SSR content - create new root
141
+ const root = (0, client_1.createRoot)(mountPoint);
142
+ root.render(React.createElement(Component, props));
143
+ }
144
+ // Mark as hydrated
145
+ hydratedComponents.add(reference.mountId);
146
+ mountPoint.removeAttribute('data-vista-cc');
147
+ mountPoint.setAttribute('data-hydrated', 'true');
148
+ }
149
+ catch (error) {
150
+ console.error(`[Vista] Hydration error for ${reference.id}:`, error);
151
+ // In development, show error in the mount point
152
+ if (process.env.NODE_ENV === 'development') {
153
+ const mountPoint = document.getElementById(reference.mountId);
154
+ if (mountPoint) {
155
+ mountPoint.innerHTML = `
156
+ <div style="padding: 20px; background: #fee2e2; border: 2px solid #ef4444; border-radius: 8px; color: #991b1b; font-family: monospace;">
157
+ <h3 style="margin: 0 0 10px 0;">⚠️ Hydration Error</h3>
158
+ <p style="margin: 0 0 10px 0;">${error.message}</p>
159
+ <p style="margin: 0; font-size: 12px;">Component: ${reference.id}</p>
160
+ </div>
161
+ `;
162
+ }
163
+ }
164
+ }
165
+ finally {
166
+ pendingHydrations.delete(reference.mountId);
167
+ }
168
+ })();
169
+ pendingHydrations.set(reference.mountId, hydrationPromise);
170
+ return hydrationPromise;
171
+ }
172
+ /**
173
+ * Hydrate all client components on the page
174
+ */
175
+ async function hydrateClientComponents(options = {}) {
176
+ const { progressive = false, priority = 'normal', useIdleCallback = false } = options;
177
+ // Get references from window
178
+ const references = window.__VISTA_CLIENT_REFERENCES__ || [];
179
+ if (references.length === 0) {
180
+ console.log('[Vista] No client components to hydrate');
181
+ return;
182
+ }
183
+ console.log(`[Vista] Hydrating ${references.length} client component(s)`);
184
+ if (progressive) {
185
+ // Progressive hydration - hydrate visible components first
186
+ await hydrateProgressively(references);
187
+ }
188
+ else if (useIdleCallback && priority === 'low') {
189
+ // Use idle callback for low priority hydration
190
+ await hydrateOnIdle(references);
191
+ }
192
+ else {
193
+ // Hydrate all at once
194
+ await Promise.all(references.map(hydrateComponent));
195
+ }
196
+ }
197
+ /**
198
+ * Progressive hydration based on visibility
199
+ */
200
+ async function hydrateProgressively(references) {
201
+ // First, hydrate above-the-fold components
202
+ const aboveTheFold = [];
203
+ const belowTheFold = [];
204
+ for (const ref of references) {
205
+ const element = document.getElementById(ref.mountId);
206
+ if (element && isInViewport(element)) {
207
+ aboveTheFold.push(ref);
208
+ }
209
+ else {
210
+ belowTheFold.push(ref);
211
+ }
212
+ }
213
+ // Hydrate above-the-fold immediately
214
+ await Promise.all(aboveTheFold.map(hydrateComponent));
215
+ // Set up intersection observer for below-the-fold
216
+ if (belowTheFold.length > 0 && 'IntersectionObserver' in window) {
217
+ const observer = new IntersectionObserver((entries) => {
218
+ for (const entry of entries) {
219
+ if (entry.isIntersecting) {
220
+ const mountId = entry.target.id;
221
+ const ref = belowTheFold.find((r) => r.mountId === mountId);
222
+ if (ref) {
223
+ hydrateComponent(ref);
224
+ observer.unobserve(entry.target);
225
+ }
226
+ }
227
+ }
228
+ }, {
229
+ rootMargin: '50px', // Start loading slightly before visible
230
+ });
231
+ for (const ref of belowTheFold) {
232
+ const element = document.getElementById(ref.mountId);
233
+ if (element) {
234
+ observer.observe(element);
235
+ }
236
+ }
237
+ }
238
+ else {
239
+ // Fallback: hydrate after a delay
240
+ setTimeout(() => {
241
+ Promise.all(belowTheFold.map(hydrateComponent));
242
+ }, 1000);
243
+ }
244
+ }
245
+ /**
246
+ * Hydrate during browser idle time
247
+ */
248
+ async function hydrateOnIdle(references) {
249
+ const requestIdleCallback = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
250
+ for (const ref of references) {
251
+ await new Promise((resolve) => {
252
+ requestIdleCallback(() => {
253
+ hydrateComponent(ref).then(resolve);
254
+ });
255
+ });
256
+ }
257
+ }
258
+ /**
259
+ * Check if an element is in the viewport
260
+ */
261
+ function isInViewport(element) {
262
+ const rect = element.getBoundingClientRect();
263
+ return (rect.top < window.innerHeight + 100 &&
264
+ rect.bottom > -100 &&
265
+ rect.left < window.innerWidth + 100 &&
266
+ rect.right > -100);
267
+ }
268
+ /**
269
+ * Initialize Vista hydration
270
+ * Call this after the page loads
271
+ */
272
+ function initializeHydration() {
273
+ // Wait for DOM to be ready
274
+ if (document.readyState === 'loading') {
275
+ document.addEventListener('DOMContentLoaded', () => {
276
+ hydrateClientComponents({ progressive: true });
277
+ });
278
+ }
279
+ else {
280
+ hydrateClientComponents({ progressive: true });
281
+ }
282
+ }
283
+ // Auto-initialize if this module is loaded
284
+ if (typeof window !== 'undefined') {
285
+ initializeHydration();
286
+ }
287
+ exports.default = {
288
+ hydrateClientComponents,
289
+ hydrateComponent,
290
+ initializeHydration,
291
+ };
@@ -0,0 +1,30 @@
1
+ import React, { AnchorHTMLAttributes } from 'react';
2
+ type Url = string | {
3
+ href: string;
4
+ query?: Record<string, string>;
5
+ hash?: string;
6
+ };
7
+ export interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
8
+ href: Url;
9
+ as?: Url;
10
+ replace?: boolean;
11
+ scroll?: boolean;
12
+ shallow?: boolean;
13
+ passHref?: boolean;
14
+ prefetch?: boolean | 'auto' | null;
15
+ locale?: string | false;
16
+ legacyBehavior?: boolean;
17
+ onNavigate?: () => void;
18
+ }
19
+ export declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
20
+ /**
21
+ * Hook to check link navigation status
22
+ */
23
+ export declare const useLinkStatus: () => {
24
+ pending: boolean;
25
+ };
26
+ /**
27
+ * Hook to check if a path is active
28
+ */
29
+ export declare const useIsActive: (path: string) => boolean;
30
+ export default Link;