@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.
- package/bin/vista.js +98 -0
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.js +16 -0
- package/dist/bin/build-rsc.d.ts +17 -0
- package/dist/bin/build-rsc.js +320 -0
- package/dist/bin/build.d.ts +4 -0
- package/dist/bin/build.js +336 -0
- package/dist/bin/file-scanner.d.ts +66 -0
- package/dist/bin/file-scanner.js +399 -0
- package/dist/bin/server-component-plugin.d.ts +17 -0
- package/dist/bin/server-component-plugin.js +133 -0
- package/dist/bin/webpack.config.d.ts +6 -0
- package/dist/bin/webpack.config.js +138 -0
- package/dist/build/manifest.d.ts +95 -0
- package/dist/build/manifest.js +168 -0
- package/dist/build/rsc/client-manifest.d.ts +48 -0
- package/dist/build/rsc/client-manifest.js +191 -0
- package/dist/build/rsc/client-reference-plugin.d.ts +37 -0
- package/dist/build/rsc/client-reference-plugin.js +185 -0
- package/dist/build/rsc/compiler.d.ts +36 -0
- package/dist/build/rsc/compiler.js +311 -0
- package/dist/build/rsc/index.d.ts +16 -0
- package/dist/build/rsc/index.js +32 -0
- package/dist/build/rsc/native-scanner.d.ts +123 -0
- package/dist/build/rsc/native-scanner.js +165 -0
- package/dist/build/rsc/rsc-renderer.d.ts +99 -0
- package/dist/build/rsc/rsc-renderer.js +269 -0
- package/dist/build/rsc/server-component-loader.d.ts +19 -0
- package/dist/build/rsc/server-component-loader.js +147 -0
- package/dist/build/rsc/server-manifest.d.ts +63 -0
- package/dist/build/rsc/server-manifest.js +268 -0
- package/dist/build/webpack/loaders/vista-flight-loader.d.ts +17 -0
- package/dist/build/webpack/loaders/vista-flight-loader.js +93 -0
- package/dist/build/webpack/plugins/vista-flight-plugin.d.ts +36 -0
- package/dist/build/webpack/plugins/vista-flight-plugin.js +133 -0
- package/dist/client/dynamic.d.ts +25 -0
- package/dist/client/dynamic.js +68 -0
- package/dist/client/font.d.ts +98 -0
- package/dist/client/font.js +109 -0
- package/dist/client/head.d.ts +79 -0
- package/dist/client/head.js +261 -0
- package/dist/client/hydration.d.ts +45 -0
- package/dist/client/hydration.js +291 -0
- package/dist/client/link.d.ts +30 -0
- package/dist/client/link.js +188 -0
- package/dist/client/navigation.d.ts +28 -0
- package/dist/client/navigation.js +116 -0
- package/dist/client/router.d.ts +41 -0
- package/dist/client/router.js +190 -0
- package/dist/client/script.d.ts +51 -0
- package/dist/client/script.js +118 -0
- package/dist/components/client-island.d.ts +34 -0
- package/dist/components/client-island.js +75 -0
- package/dist/components/client.d.ts +29 -0
- package/dist/components/client.js +102 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +8 -0
- package/dist/components/link.d.ts +6 -0
- package/dist/components/link.js +13 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +31 -0
- package/dist/dev-error.d.ts +35 -0
- package/dist/dev-error.js +310 -0
- package/dist/image/get-img-props.d.ts +28 -0
- package/dist/image/get-img-props.js +49 -0
- package/dist/image/image-config.d.ts +20 -0
- package/dist/image/image-config.js +20 -0
- package/dist/image/image-loader.d.ts +7 -0
- package/dist/image/image-loader.js +14 -0
- package/dist/image/index.d.ts +6 -0
- package/dist/image/index.js +110 -0
- package/dist/image.d.ts +10 -0
- package/dist/image.js +7 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +53 -0
- package/dist/metadata/generate.d.ts +22 -0
- package/dist/metadata/generate.js +324 -0
- package/dist/metadata/index.d.ts +7 -0
- package/dist/metadata/index.js +26 -0
- package/dist/metadata/types.d.ts +325 -0
- package/dist/metadata/types.js +15 -0
- package/dist/router/context.d.ts +8 -0
- package/dist/router/context.js +13 -0
- package/dist/router/index.d.ts +2 -0
- package/dist/router/index.js +18 -0
- package/dist/router/provider.d.ts +5 -0
- package/dist/router/provider.js +31 -0
- package/dist/server/client-boundary.d.ts +48 -0
- package/dist/server/client-boundary.js +133 -0
- package/dist/server/engine.d.ts +4 -0
- package/dist/server/engine.js +651 -0
- package/dist/server/index.d.ts +95 -0
- package/dist/server/index.js +177 -0
- package/dist/server/rsc-engine.d.ts +20 -0
- package/dist/server/rsc-engine.js +588 -0
- package/dist/server/rsc-module-system.d.ts +33 -0
- package/dist/server/rsc-module-system.js +119 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +2 -0
- 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;
|