qlara 0.1.7 → 0.1.9
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/dist/aws.cjs +6 -4
- package/dist/aws.d.cts +1 -1
- package/dist/aws.d.ts +1 -1
- package/dist/aws.js +6 -4
- package/dist/cli.js +6 -4
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/plugin/next.cjs +2 -1
- package/dist/plugin/next.d.cts +1 -1
- package/dist/plugin/next.d.ts +1 -1
- package/dist/plugin/next.js +2 -1
- package/dist/{types-gl2xFqEX.d.cts → types--KPPgCtc.d.cts} +11 -0
- package/dist/{types-gl2xFqEX.d.ts → types--KPPgCtc.d.ts} +11 -0
- package/package.json +1 -1
- package/src/provider/aws/renderer.ts +50 -1
- package/src/types.ts +11 -0
package/dist/aws.cjs
CHANGED
|
@@ -562,7 +562,7 @@ async function bundleEdgeHandler(config) {
|
|
|
562
562
|
});
|
|
563
563
|
return createZip(outfile, "edge-handler.js");
|
|
564
564
|
}
|
|
565
|
-
async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
565
|
+
async function bundleRenderer(routeFile, cacheTtl = 3600, framework) {
|
|
566
566
|
(0, import_node_fs2.mkdirSync)(BUNDLE_DIR, { recursive: true });
|
|
567
567
|
const outfile = (0, import_node_path2.join)(BUNDLE_DIR, "renderer.js");
|
|
568
568
|
const alias = {};
|
|
@@ -584,7 +584,8 @@ async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
|
584
584
|
minify: true,
|
|
585
585
|
alias,
|
|
586
586
|
define: {
|
|
587
|
-
__QLARA_CACHE_TTL__: String(cacheTtl)
|
|
587
|
+
__QLARA_CACHE_TTL__: String(cacheTtl),
|
|
588
|
+
__QLARA_FRAMEWORK__: JSON.stringify(framework || "")
|
|
588
589
|
},
|
|
589
590
|
external: []
|
|
590
591
|
});
|
|
@@ -764,8 +765,9 @@ async function updateCloudFrontEdgeVersion(cf, distributionId, newVersionArn) {
|
|
|
764
765
|
const lambdaAssociations = config.DefaultCacheBehavior?.LambdaFunctionAssociations;
|
|
765
766
|
if (lambdaAssociations?.Items) {
|
|
766
767
|
for (const assoc of lambdaAssociations.Items) {
|
|
767
|
-
if (assoc.EventType === "origin-request") {
|
|
768
|
+
if (assoc.EventType === "origin-request" || assoc.EventType === "origin-response") {
|
|
768
769
|
assoc.LambdaFunctionARN = newVersionArn;
|
|
770
|
+
assoc.EventType = "origin-request";
|
|
769
771
|
}
|
|
770
772
|
}
|
|
771
773
|
}
|
|
@@ -963,7 +965,7 @@ function aws(awsConfig = {}) {
|
|
|
963
965
|
const cf = new import_client_cloudfront.CloudFrontClient({ region: res.region });
|
|
964
966
|
await updateCloudFrontEdgeVersion(cf, res.distributionId, newVersionArn);
|
|
965
967
|
console.log("[qlara/aws] Bundling renderer...");
|
|
966
|
-
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl);
|
|
968
|
+
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl, config.framework);
|
|
967
969
|
await (0, import_client_lambda.waitUntilFunctionUpdatedV2)(
|
|
968
970
|
{ client: lambda, maxWaitTime: 120 },
|
|
969
971
|
{ FunctionName: res.rendererFunctionArn }
|
package/dist/aws.d.cts
CHANGED
package/dist/aws.d.ts
CHANGED
package/dist/aws.js
CHANGED
|
@@ -558,7 +558,7 @@ async function bundleEdgeHandler(config) {
|
|
|
558
558
|
});
|
|
559
559
|
return createZip(outfile, "edge-handler.js");
|
|
560
560
|
}
|
|
561
|
-
async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
561
|
+
async function bundleRenderer(routeFile, cacheTtl = 3600, framework) {
|
|
562
562
|
mkdirSync(BUNDLE_DIR, { recursive: true });
|
|
563
563
|
const outfile = join2(BUNDLE_DIR, "renderer.js");
|
|
564
564
|
const alias = {};
|
|
@@ -580,7 +580,8 @@ async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
|
580
580
|
minify: true,
|
|
581
581
|
alias,
|
|
582
582
|
define: {
|
|
583
|
-
__QLARA_CACHE_TTL__: String(cacheTtl)
|
|
583
|
+
__QLARA_CACHE_TTL__: String(cacheTtl),
|
|
584
|
+
__QLARA_FRAMEWORK__: JSON.stringify(framework || "")
|
|
584
585
|
},
|
|
585
586
|
external: []
|
|
586
587
|
});
|
|
@@ -760,8 +761,9 @@ async function updateCloudFrontEdgeVersion(cf, distributionId, newVersionArn) {
|
|
|
760
761
|
const lambdaAssociations = config.DefaultCacheBehavior?.LambdaFunctionAssociations;
|
|
761
762
|
if (lambdaAssociations?.Items) {
|
|
762
763
|
for (const assoc of lambdaAssociations.Items) {
|
|
763
|
-
if (assoc.EventType === "origin-request") {
|
|
764
|
+
if (assoc.EventType === "origin-request" || assoc.EventType === "origin-response") {
|
|
764
765
|
assoc.LambdaFunctionARN = newVersionArn;
|
|
766
|
+
assoc.EventType = "origin-request";
|
|
765
767
|
}
|
|
766
768
|
}
|
|
767
769
|
}
|
|
@@ -959,7 +961,7 @@ function aws(awsConfig = {}) {
|
|
|
959
961
|
const cf = new CloudFrontClient({ region: res.region });
|
|
960
962
|
await updateCloudFrontEdgeVersion(cf, res.distributionId, newVersionArn);
|
|
961
963
|
console.log("[qlara/aws] Bundling renderer...");
|
|
962
|
-
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl);
|
|
964
|
+
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl, config.framework);
|
|
963
965
|
await waitUntilFunctionUpdatedV2(
|
|
964
966
|
{ client: lambda, maxWaitTime: 120 },
|
|
965
967
|
{ FunctionName: res.rendererFunctionArn }
|
package/dist/cli.js
CHANGED
|
@@ -569,7 +569,7 @@ async function bundleEdgeHandler(config) {
|
|
|
569
569
|
});
|
|
570
570
|
return createZip(outfile, "edge-handler.js");
|
|
571
571
|
}
|
|
572
|
-
async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
572
|
+
async function bundleRenderer(routeFile, cacheTtl = 3600, framework) {
|
|
573
573
|
mkdirSync(BUNDLE_DIR, { recursive: true });
|
|
574
574
|
const outfile = join2(BUNDLE_DIR, "renderer.js");
|
|
575
575
|
const alias = {};
|
|
@@ -591,7 +591,8 @@ async function bundleRenderer(routeFile, cacheTtl = 3600) {
|
|
|
591
591
|
minify: true,
|
|
592
592
|
alias,
|
|
593
593
|
define: {
|
|
594
|
-
__QLARA_CACHE_TTL__: String(cacheTtl)
|
|
594
|
+
__QLARA_CACHE_TTL__: String(cacheTtl),
|
|
595
|
+
__QLARA_FRAMEWORK__: JSON.stringify(framework || "")
|
|
595
596
|
},
|
|
596
597
|
external: []
|
|
597
598
|
});
|
|
@@ -768,8 +769,9 @@ async function updateCloudFrontEdgeVersion(cf, distributionId, newVersionArn) {
|
|
|
768
769
|
const lambdaAssociations = config.DefaultCacheBehavior?.LambdaFunctionAssociations;
|
|
769
770
|
if (lambdaAssociations?.Items) {
|
|
770
771
|
for (const assoc of lambdaAssociations.Items) {
|
|
771
|
-
if (assoc.EventType === "origin-request") {
|
|
772
|
+
if (assoc.EventType === "origin-request" || assoc.EventType === "origin-response") {
|
|
772
773
|
assoc.LambdaFunctionARN = newVersionArn;
|
|
774
|
+
assoc.EventType = "origin-request";
|
|
773
775
|
}
|
|
774
776
|
}
|
|
775
777
|
}
|
|
@@ -967,7 +969,7 @@ function aws(awsConfig = {}) {
|
|
|
967
969
|
const cf = new CloudFrontClient({ region: res.region });
|
|
968
970
|
await updateCloudFrontEdgeVersion(cf, res.distributionId, newVersionArn);
|
|
969
971
|
console.log("[qlara/aws] Bundling renderer...");
|
|
970
|
-
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl);
|
|
972
|
+
const rendererZip = await bundleRenderer(config.routeFile, cacheTtl, config.framework);
|
|
971
973
|
await waitUntilFunctionUpdatedV2(
|
|
972
974
|
{ client: lambda, maxWaitTime: 120 },
|
|
973
975
|
{ FunctionName: res.rendererFunctionArn }
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as QlaraPluginConfig, b as QlaraRoute, c as QlaraManifest, M as ManifestRoute, R as RouteMatch } from './types
|
|
2
|
-
export { P as ProviderResources, d as QlaraAlternateLinkDescriptor, e as QlaraAlternateURLs, f as QlaraAppLinks, g as QlaraAppLinksAndroid, h as QlaraAppLinksApple, i as QlaraAppLinksWeb, j as QlaraAppLinksWindows, k as QlaraAppleImage, l as QlaraAppleImageDescriptor, m as QlaraAppleWebApp, n as QlaraAuthor, o as QlaraDeployConfig, p as QlaraFacebook, q as QlaraFormatDetection, r as QlaraIcon, s as QlaraIconDescriptor, t as QlaraIcons, u as QlaraItunesApp, v as QlaraMetaDataGenerator, w as QlaraMetadata, x as QlaraOGAudio, y as QlaraOGAudioDescriptor, z as QlaraOGImage, A as QlaraOGImageDescriptor, B as QlaraOGVideo, C as QlaraOGVideoDescriptor, D as QlaraOpenGraph, E as QlaraOpenGraphArticle, F as QlaraOpenGraphBase, G as QlaraOpenGraphBook, H as QlaraOpenGraphMusicAlbum, I as QlaraOpenGraphMusicPlaylist, J as QlaraOpenGraphMusicRadioStation, K as QlaraOpenGraphMusicSong, L as QlaraOpenGraphProfile, N as QlaraOpenGraphVideoEpisode, O as QlaraOpenGraphVideoMovie, S as QlaraOpenGraphVideoOther, T as QlaraOpenGraphVideoTVShow, U as QlaraOpenGraphWebsite, V as QlaraPinterest, Q as QlaraProvider, W as QlaraReferrer, X as QlaraRobots, Y as QlaraRobotsInfo, Z as QlaraRouteDefinition, _ as QlaraRoutes, $ as QlaraTwitter, a0 as QlaraTwitterApp, a1 as QlaraTwitterAppDescriptor, a2 as QlaraTwitterBase, a3 as QlaraTwitterImage, a4 as QlaraTwitterImageDescriptor, a5 as QlaraTwitterPlayer, a6 as QlaraTwitterPlayerDescriptor, a7 as QlaraTwitterSummary, a8 as QlaraTwitterSummaryLargeImage, a9 as QlaraVerification } from './types
|
|
1
|
+
import { a as QlaraPluginConfig, b as QlaraRoute, c as QlaraManifest, M as ManifestRoute, R as RouteMatch } from './types--KPPgCtc.cjs';
|
|
2
|
+
export { P as ProviderResources, d as QlaraAlternateLinkDescriptor, e as QlaraAlternateURLs, f as QlaraAppLinks, g as QlaraAppLinksAndroid, h as QlaraAppLinksApple, i as QlaraAppLinksWeb, j as QlaraAppLinksWindows, k as QlaraAppleImage, l as QlaraAppleImageDescriptor, m as QlaraAppleWebApp, n as QlaraAuthor, o as QlaraDeployConfig, p as QlaraFacebook, q as QlaraFormatDetection, r as QlaraIcon, s as QlaraIconDescriptor, t as QlaraIcons, u as QlaraItunesApp, v as QlaraMetaDataGenerator, w as QlaraMetadata, x as QlaraOGAudio, y as QlaraOGAudioDescriptor, z as QlaraOGImage, A as QlaraOGImageDescriptor, B as QlaraOGVideo, C as QlaraOGVideoDescriptor, D as QlaraOpenGraph, E as QlaraOpenGraphArticle, F as QlaraOpenGraphBase, G as QlaraOpenGraphBook, H as QlaraOpenGraphMusicAlbum, I as QlaraOpenGraphMusicPlaylist, J as QlaraOpenGraphMusicRadioStation, K as QlaraOpenGraphMusicSong, L as QlaraOpenGraphProfile, N as QlaraOpenGraphVideoEpisode, O as QlaraOpenGraphVideoMovie, S as QlaraOpenGraphVideoOther, T as QlaraOpenGraphVideoTVShow, U as QlaraOpenGraphWebsite, V as QlaraPinterest, Q as QlaraProvider, W as QlaraReferrer, X as QlaraRobots, Y as QlaraRobotsInfo, Z as QlaraRouteDefinition, _ as QlaraRoutes, $ as QlaraTwitter, a0 as QlaraTwitterApp, a1 as QlaraTwitterAppDescriptor, a2 as QlaraTwitterBase, a3 as QlaraTwitterImage, a4 as QlaraTwitterImageDescriptor, a5 as QlaraTwitterPlayer, a6 as QlaraTwitterPlayerDescriptor, a7 as QlaraTwitterSummary, a8 as QlaraTwitterSummaryLargeImage, a9 as QlaraVerification } from './types--KPPgCtc.cjs';
|
|
3
3
|
|
|
4
4
|
declare function validateConfig(config: QlaraPluginConfig, routes: QlaraRoute[]): void;
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as QlaraPluginConfig, b as QlaraRoute, c as QlaraManifest, M as ManifestRoute, R as RouteMatch } from './types
|
|
2
|
-
export { P as ProviderResources, d as QlaraAlternateLinkDescriptor, e as QlaraAlternateURLs, f as QlaraAppLinks, g as QlaraAppLinksAndroid, h as QlaraAppLinksApple, i as QlaraAppLinksWeb, j as QlaraAppLinksWindows, k as QlaraAppleImage, l as QlaraAppleImageDescriptor, m as QlaraAppleWebApp, n as QlaraAuthor, o as QlaraDeployConfig, p as QlaraFacebook, q as QlaraFormatDetection, r as QlaraIcon, s as QlaraIconDescriptor, t as QlaraIcons, u as QlaraItunesApp, v as QlaraMetaDataGenerator, w as QlaraMetadata, x as QlaraOGAudio, y as QlaraOGAudioDescriptor, z as QlaraOGImage, A as QlaraOGImageDescriptor, B as QlaraOGVideo, C as QlaraOGVideoDescriptor, D as QlaraOpenGraph, E as QlaraOpenGraphArticle, F as QlaraOpenGraphBase, G as QlaraOpenGraphBook, H as QlaraOpenGraphMusicAlbum, I as QlaraOpenGraphMusicPlaylist, J as QlaraOpenGraphMusicRadioStation, K as QlaraOpenGraphMusicSong, L as QlaraOpenGraphProfile, N as QlaraOpenGraphVideoEpisode, O as QlaraOpenGraphVideoMovie, S as QlaraOpenGraphVideoOther, T as QlaraOpenGraphVideoTVShow, U as QlaraOpenGraphWebsite, V as QlaraPinterest, Q as QlaraProvider, W as QlaraReferrer, X as QlaraRobots, Y as QlaraRobotsInfo, Z as QlaraRouteDefinition, _ as QlaraRoutes, $ as QlaraTwitter, a0 as QlaraTwitterApp, a1 as QlaraTwitterAppDescriptor, a2 as QlaraTwitterBase, a3 as QlaraTwitterImage, a4 as QlaraTwitterImageDescriptor, a5 as QlaraTwitterPlayer, a6 as QlaraTwitterPlayerDescriptor, a7 as QlaraTwitterSummary, a8 as QlaraTwitterSummaryLargeImage, a9 as QlaraVerification } from './types
|
|
1
|
+
import { a as QlaraPluginConfig, b as QlaraRoute, c as QlaraManifest, M as ManifestRoute, R as RouteMatch } from './types--KPPgCtc.js';
|
|
2
|
+
export { P as ProviderResources, d as QlaraAlternateLinkDescriptor, e as QlaraAlternateURLs, f as QlaraAppLinks, g as QlaraAppLinksAndroid, h as QlaraAppLinksApple, i as QlaraAppLinksWeb, j as QlaraAppLinksWindows, k as QlaraAppleImage, l as QlaraAppleImageDescriptor, m as QlaraAppleWebApp, n as QlaraAuthor, o as QlaraDeployConfig, p as QlaraFacebook, q as QlaraFormatDetection, r as QlaraIcon, s as QlaraIconDescriptor, t as QlaraIcons, u as QlaraItunesApp, v as QlaraMetaDataGenerator, w as QlaraMetadata, x as QlaraOGAudio, y as QlaraOGAudioDescriptor, z as QlaraOGImage, A as QlaraOGImageDescriptor, B as QlaraOGVideo, C as QlaraOGVideoDescriptor, D as QlaraOpenGraph, E as QlaraOpenGraphArticle, F as QlaraOpenGraphBase, G as QlaraOpenGraphBook, H as QlaraOpenGraphMusicAlbum, I as QlaraOpenGraphMusicPlaylist, J as QlaraOpenGraphMusicRadioStation, K as QlaraOpenGraphMusicSong, L as QlaraOpenGraphProfile, N as QlaraOpenGraphVideoEpisode, O as QlaraOpenGraphVideoMovie, S as QlaraOpenGraphVideoOther, T as QlaraOpenGraphVideoTVShow, U as QlaraOpenGraphWebsite, V as QlaraPinterest, Q as QlaraProvider, W as QlaraReferrer, X as QlaraRobots, Y as QlaraRobotsInfo, Z as QlaraRouteDefinition, _ as QlaraRoutes, $ as QlaraTwitter, a0 as QlaraTwitterApp, a1 as QlaraTwitterAppDescriptor, a2 as QlaraTwitterBase, a3 as QlaraTwitterImage, a4 as QlaraTwitterImageDescriptor, a5 as QlaraTwitterPlayer, a6 as QlaraTwitterPlayerDescriptor, a7 as QlaraTwitterSummary, a8 as QlaraTwitterSummaryLargeImage, a9 as QlaraVerification } from './types--KPPgCtc.js';
|
|
3
3
|
|
|
4
4
|
declare function validateConfig(config: QlaraPluginConfig, routes: QlaraRoute[]): void;
|
|
5
5
|
|
package/dist/plugin/next.cjs
CHANGED
|
@@ -153,7 +153,8 @@ function withQlara(qlaraConfig) {
|
|
|
153
153
|
},
|
|
154
154
|
outputDir,
|
|
155
155
|
routeFile: (0, import_node_path.resolve)(qlaraConfig.routeFile),
|
|
156
|
-
env
|
|
156
|
+
env,
|
|
157
|
+
framework: "next"
|
|
157
158
|
};
|
|
158
159
|
(0, import_node_fs.mkdirSync)(QLARA_DIR, { recursive: true });
|
|
159
160
|
(0, import_node_fs.writeFileSync)(
|
package/dist/plugin/next.d.cts
CHANGED
package/dist/plugin/next.d.ts
CHANGED
package/dist/plugin/next.js
CHANGED
|
@@ -368,6 +368,12 @@ interface QlaraPluginConfig {
|
|
|
368
368
|
provider: QlaraProvider;
|
|
369
369
|
/** Env var names to forward to the renderer Lambda (values read from process.env at build time) */
|
|
370
370
|
env?: string[];
|
|
371
|
+
/**
|
|
372
|
+
* The framework identifier. Set automatically by framework plugins (e.g. 'next' by withQlara).
|
|
373
|
+
* Used by the renderer to enable framework-specific post-render behavior
|
|
374
|
+
* (e.g. generating .txt RSC flight data files for Next.js client-side navigation).
|
|
375
|
+
*/
|
|
376
|
+
framework?: string;
|
|
371
377
|
}
|
|
372
378
|
interface QlaraProvider {
|
|
373
379
|
name: string;
|
|
@@ -394,6 +400,11 @@ interface QlaraDeployConfig {
|
|
|
394
400
|
routeFile: string;
|
|
395
401
|
/** Environment variables for the renderer Lambda (key-value pairs resolved at build time) */
|
|
396
402
|
env?: Record<string, string>;
|
|
403
|
+
/**
|
|
404
|
+
* The framework identifier (e.g. 'next'). Set by framework plugins.
|
|
405
|
+
* Passed to the renderer to enable framework-specific post-render behavior.
|
|
406
|
+
*/
|
|
407
|
+
framework?: string;
|
|
397
408
|
}
|
|
398
409
|
interface QlaraManifest {
|
|
399
410
|
version: 1;
|
|
@@ -368,6 +368,12 @@ interface QlaraPluginConfig {
|
|
|
368
368
|
provider: QlaraProvider;
|
|
369
369
|
/** Env var names to forward to the renderer Lambda (values read from process.env at build time) */
|
|
370
370
|
env?: string[];
|
|
371
|
+
/**
|
|
372
|
+
* The framework identifier. Set automatically by framework plugins (e.g. 'next' by withQlara).
|
|
373
|
+
* Used by the renderer to enable framework-specific post-render behavior
|
|
374
|
+
* (e.g. generating .txt RSC flight data files for Next.js client-side navigation).
|
|
375
|
+
*/
|
|
376
|
+
framework?: string;
|
|
371
377
|
}
|
|
372
378
|
interface QlaraProvider {
|
|
373
379
|
name: string;
|
|
@@ -394,6 +400,11 @@ interface QlaraDeployConfig {
|
|
|
394
400
|
routeFile: string;
|
|
395
401
|
/** Environment variables for the renderer Lambda (key-value pairs resolved at build time) */
|
|
396
402
|
env?: Record<string, string>;
|
|
403
|
+
/**
|
|
404
|
+
* The framework identifier (e.g. 'next'). Set by framework plugins.
|
|
405
|
+
* Passed to the renderer to enable framework-specific post-render behavior.
|
|
406
|
+
*/
|
|
407
|
+
framework?: string;
|
|
397
408
|
}
|
|
398
409
|
interface QlaraManifest {
|
|
399
410
|
version: 1;
|
package/package.json
CHANGED
|
@@ -54,6 +54,7 @@ import type {
|
|
|
54
54
|
// At bundle time: '__qlara_routes__' → './qlara.routes.ts' (or wherever the dev put it)
|
|
55
55
|
// Injected at bundle time by esbuild define
|
|
56
56
|
declare const __QLARA_CACHE_TTL__: number;
|
|
57
|
+
declare const __QLARA_FRAMEWORK__: string;
|
|
57
58
|
|
|
58
59
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
59
60
|
// @ts-ignore — resolved at bundle time by esbuild alias
|
|
@@ -759,6 +760,34 @@ function metadataToRscEntries(metadata: QlaraMetadata): string {
|
|
|
759
760
|
return entries.join('');
|
|
760
761
|
}
|
|
761
762
|
|
|
763
|
+
/**
|
|
764
|
+
* Extract RSC flight data from rendered HTML (Next.js-specific).
|
|
765
|
+
*
|
|
766
|
+
* Next.js embeds RSC data inside <script>self.__next_f.push([1,"..."])</script> blocks.
|
|
767
|
+
* The .txt file is these payloads concatenated with JSON string escapes resolved.
|
|
768
|
+
* Next.js's client-side router fetches the .txt file for client-side navigation
|
|
769
|
+
* instead of the full .html — so we must generate it for renderer-created pages.
|
|
770
|
+
*
|
|
771
|
+
* Only called when __QLARA_FRAMEWORK__ === 'next'.
|
|
772
|
+
*/
|
|
773
|
+
function extractRscFlightData(html: string): string | null {
|
|
774
|
+
const chunks: string[] = [];
|
|
775
|
+
const regex = /self\.__next_f\.push\(\[1,"((?:[^"\\]|\\.)*)"\]\)/g;
|
|
776
|
+
let match;
|
|
777
|
+
|
|
778
|
+
while ((match = regex.exec(html)) !== null) {
|
|
779
|
+
// Unescape the JSON string: \" → ", \\ → \, \n → newline
|
|
780
|
+
const unescaped = match[1]
|
|
781
|
+
.replace(/\\n/g, '\n')
|
|
782
|
+
.replace(/\\"/g, '"')
|
|
783
|
+
.replace(/\\\\/g, '\\');
|
|
784
|
+
chunks.push(unescaped);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if (chunks.length === 0) return null;
|
|
788
|
+
return chunks.join('');
|
|
789
|
+
}
|
|
790
|
+
|
|
762
791
|
export async function handler(event: RendererEvent & { warmup?: boolean }): Promise<RendererResult> {
|
|
763
792
|
// Warmup invocation — just initialize the runtime and return
|
|
764
793
|
if (event.warmup) {
|
|
@@ -825,7 +854,7 @@ export async function handler(event: RendererEvent & { warmup?: boolean }): Prom
|
|
|
825
854
|
}
|
|
826
855
|
}
|
|
827
856
|
|
|
828
|
-
// 5. Upload to S3
|
|
857
|
+
// 5. Upload HTML to S3
|
|
829
858
|
await s3.send(
|
|
830
859
|
new PutObjectCommand({
|
|
831
860
|
Bucket: bucket,
|
|
@@ -836,6 +865,26 @@ export async function handler(event: RendererEvent & { warmup?: boolean }): Prom
|
|
|
836
865
|
})
|
|
837
866
|
);
|
|
838
867
|
|
|
868
|
+
// 6. Framework-specific post-render uploads
|
|
869
|
+
// Next.js: extract RSC flight data and upload as .txt for client-side navigation.
|
|
870
|
+
// Next.js fetches .txt instead of .html when using <Link> / client-side nav.
|
|
871
|
+
// Without this, client-side nav falls back to a full page reload (slow).
|
|
872
|
+
if (__QLARA_FRAMEWORK__ === 'next') {
|
|
873
|
+
const rscData = extractRscFlightData(html);
|
|
874
|
+
if (rscData) {
|
|
875
|
+
const txtKey = s3Key.replace(/\.html$/, '.txt');
|
|
876
|
+
await s3.send(
|
|
877
|
+
new PutObjectCommand({
|
|
878
|
+
Bucket: bucket,
|
|
879
|
+
Key: txtKey,
|
|
880
|
+
Body: rscData,
|
|
881
|
+
ContentType: 'text/plain; charset=utf-8',
|
|
882
|
+
CacheControl: `public, max-age=0, s-maxage=${__QLARA_CACHE_TTL__}, stale-while-revalidate=60`,
|
|
883
|
+
})
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
839
888
|
return {
|
|
840
889
|
statusCode: 200,
|
|
841
890
|
body: JSON.stringify({
|
package/src/types.ts
CHANGED
|
@@ -513,6 +513,12 @@ export interface QlaraPluginConfig {
|
|
|
513
513
|
provider: QlaraProvider;
|
|
514
514
|
/** Env var names to forward to the renderer Lambda (values read from process.env at build time) */
|
|
515
515
|
env?: string[];
|
|
516
|
+
/**
|
|
517
|
+
* The framework identifier. Set automatically by framework plugins (e.g. 'next' by withQlara).
|
|
518
|
+
* Used by the renderer to enable framework-specific post-render behavior
|
|
519
|
+
* (e.g. generating .txt RSC flight data files for Next.js client-side navigation).
|
|
520
|
+
*/
|
|
521
|
+
framework?: string;
|
|
516
522
|
}
|
|
517
523
|
|
|
518
524
|
export interface QlaraProvider {
|
|
@@ -542,6 +548,11 @@ export interface QlaraDeployConfig {
|
|
|
542
548
|
routeFile: string;
|
|
543
549
|
/** Environment variables for the renderer Lambda (key-value pairs resolved at build time) */
|
|
544
550
|
env?: Record<string, string>;
|
|
551
|
+
/**
|
|
552
|
+
* The framework identifier (e.g. 'next'). Set by framework plugins.
|
|
553
|
+
* Passed to the renderer to enable framework-specific post-render behavior.
|
|
554
|
+
*/
|
|
555
|
+
framework?: string;
|
|
545
556
|
}
|
|
546
557
|
|
|
547
558
|
export interface QlaraManifest {
|