@blinkk/root 1.4.11 → 1.4.13

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/render.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  htmlMinify,
10
10
  htmlPretty,
11
11
  parseTagNames
12
- } from "./chunk-5YDJSEDK.js";
12
+ } from "./chunk-3KGEENDW.js";
13
13
 
14
14
  // src/render/render.tsx
15
15
  import crypto from "node:crypto";
@@ -12886,6 +12886,9 @@ var Router = class {
12886
12886
  get(url) {
12887
12887
  return this.routeTrie.get(url);
12888
12888
  }
12889
+ matchAll(url) {
12890
+ return this.routeTrie.matchAll(url);
12891
+ }
12889
12892
  async walk(cb) {
12890
12893
  await this.routeTrie.walk(cb);
12891
12894
  }
@@ -13056,29 +13059,29 @@ function toSquareBrackets(str) {
13056
13059
  // src/render/render.tsx
13057
13060
  import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
13058
13061
  var CONTENT_TYPES = {
13059
- "html": "text/html",
13060
- "htm": "text/html",
13061
- "css": "text/css",
13062
- "js": "application/javascript",
13063
- "json": "application/json",
13064
- "png": "image/png",
13065
- "jpg": "image/jpeg",
13066
- "jpeg": "image/jpeg",
13067
- "gif": "image/gif",
13068
- "svg": "image/svg+xml",
13069
- "txt": "text/plain",
13070
- "xml": "application/xml",
13071
- "pdf": "application/pdf",
13072
- "zip": "application/zip",
13073
- "mp4": "video/mp4",
13074
- "webm": "video/webm",
13075
- "mp3": "audio/mpeg",
13076
- "wav": "audio/wav",
13077
- "woff": "font/woff",
13078
- "woff2": "font/woff2",
13079
- "ttf": "font/ttf",
13080
- "otf": "font/otf",
13081
- "wasm": "application/wasm"
13062
+ html: "text/html",
13063
+ htm: "text/html",
13064
+ css: "text/css",
13065
+ js: "application/javascript",
13066
+ json: "application/json",
13067
+ png: "image/png",
13068
+ jpg: "image/jpeg",
13069
+ jpeg: "image/jpeg",
13070
+ gif: "image/gif",
13071
+ svg: "image/svg+xml",
13072
+ txt: "text/plain",
13073
+ xml: "application/xml",
13074
+ pdf: "application/pdf",
13075
+ zip: "application/zip",
13076
+ mp4: "video/mp4",
13077
+ webm: "video/webm",
13078
+ mp3: "audio/mpeg",
13079
+ wav: "audio/wav",
13080
+ woff: "font/woff",
13081
+ woff2: "font/woff2",
13082
+ ttf: "font/ttf",
13083
+ otf: "font/otf",
13084
+ wasm: "application/wasm"
13082
13085
  };
13083
13086
  var Renderer = class {
13084
13087
  rootConfig;
@@ -13100,140 +13103,155 @@ var Renderer = class {
13100
13103
  } catch (e) {
13101
13104
  }
13102
13105
  }
13103
- const [route, routeParams] = this.router.get(url);
13104
- if (!route) {
13105
- next();
13106
- return;
13107
- }
13108
- if (route.locale) {
13109
- routeParams.$locale = route.locale;
13110
- }
13111
- const fallbackLocales = route.isDefaultLocale ? getFallbackLocales(req) : [route.locale];
13112
- const getPreferredLocale = (availableLocales) => {
13113
- const lowerLocales = availableLocales.map((l) => l.toLowerCase());
13114
- for (const fallbackLocale of fallbackLocales) {
13115
- if (lowerLocales.includes(fallbackLocale.toLowerCase())) {
13116
- return fallbackLocale;
13117
- }
13118
- }
13119
- return req.rootConfig?.i18n?.defaultLocale || "en";
13120
- };
13121
- const render404 = async () => {
13122
- next();
13123
- };
13124
- const render = async (props2, options) => {
13125
- if (!route.module.default) {
13126
- console.error(`no default component exported in route: ${route.src}`);
13127
- render404();
13106
+ const matches = this.router.matchAll(url);
13107
+ let matchIndex = 0;
13108
+ const processNextMatch = async () => {
13109
+ const match = matches[matchIndex++];
13110
+ if (!match) {
13111
+ next();
13128
13112
  return;
13129
13113
  }
13130
- const securityConfig = this.getSecurityConfig();
13131
- const cspEnabled = !!securityConfig.contentSecurityPolicy;
13132
- const currentPath = req.path;
13133
- const locale = options?.locale || route.locale;
13134
- const translations = options?.translations;
13135
- const nonce = cspEnabled ? this.generateNonce() : void 0;
13136
- const output = await this.renderComponent(route.module.default, props2, {
13137
- currentPath,
13138
- route,
13139
- routeParams,
13140
- locale,
13141
- translations,
13142
- nonce
13143
- });
13144
- let html = output.html;
13145
- if (this.rootConfig.prettyHtml) {
13146
- html = await htmlPretty(html, this.rootConfig.prettyHtmlOptions);
13147
- } else if (this.rootConfig.minifyHtml !== false) {
13148
- html = await htmlMinify(html, this.rootConfig.minifyHtmlOptions);
13114
+ const [route, routeParams] = match;
13115
+ if (route.locale) {
13116
+ routeParams.$locale = route.locale;
13149
13117
  }
13150
- if (req.viteServer) {
13151
- html = await req.viteServer.transformIndexHtml(currentPath, html);
13152
- if (nonce) {
13153
- html = html.replace(
13154
- '<script type="module" src="/@vite/client"></script>',
13155
- `<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
13156
- );
13118
+ const fallbackLocales = route.isDefaultLocale ? getFallbackLocales(req) : [route.locale];
13119
+ const getPreferredLocale = (availableLocales) => {
13120
+ const lowerLocales = availableLocales.map((l) => l.toLowerCase());
13121
+ for (const fallbackLocale of fallbackLocales) {
13122
+ if (lowerLocales.includes(fallbackLocale.toLowerCase())) {
13123
+ return fallbackLocale;
13124
+ }
13157
13125
  }
13158
- }
13159
- let statusCode = 200;
13160
- if (route.src === "routes/404.tsx") {
13161
- statusCode = 404;
13162
- } else if (route.src === "routes/500.tsx") {
13163
- statusCode = 500;
13164
- }
13165
- req.hooks.trigger("preRender");
13166
- const plugins = this.rootConfig.plugins || [];
13167
- for (const plugin of plugins) {
13168
- if (plugin.hooks?.preRender) {
13169
- const newHtml = await plugin.hooks.preRender(html);
13170
- if (newHtml && typeof newHtml === "string") {
13171
- html = newHtml;
13126
+ return req.rootConfig?.i18n?.defaultLocale || "en";
13127
+ };
13128
+ const render404 = async (options) => {
13129
+ if (options?.nextRoute) {
13130
+ await processNextMatch();
13131
+ return;
13132
+ }
13133
+ next();
13134
+ };
13135
+ const render = async (props2, options) => {
13136
+ if (!route.module.default) {
13137
+ console.error(`no default component exported in route: ${route.src}`);
13138
+ render404();
13139
+ return;
13140
+ }
13141
+ const securityConfig = this.getSecurityConfig();
13142
+ const cspEnabled = !!securityConfig.contentSecurityPolicy;
13143
+ const currentPath = req.path;
13144
+ const locale = options?.locale || route.locale;
13145
+ const translations = options?.translations;
13146
+ const nonce = cspEnabled ? this.generateNonce() : void 0;
13147
+ const output = await this.renderComponent(route.module.default, props2, {
13148
+ currentPath,
13149
+ route,
13150
+ routeParams,
13151
+ locale,
13152
+ translations,
13153
+ nonce
13154
+ });
13155
+ let html = output.html;
13156
+ if (this.rootConfig.prettyHtml) {
13157
+ html = await htmlPretty(html, this.rootConfig.prettyHtmlOptions);
13158
+ } else if (this.rootConfig.minifyHtml !== false) {
13159
+ html = await htmlMinify(html, this.rootConfig.minifyHtmlOptions);
13160
+ }
13161
+ if (req.viteServer) {
13162
+ html = await req.viteServer.transformIndexHtml(currentPath, html);
13163
+ if (nonce) {
13164
+ html = html.replace(
13165
+ '<script type="module" src="/@vite/client"></script>',
13166
+ `<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
13167
+ );
13168
+ }
13169
+ }
13170
+ let statusCode = 200;
13171
+ if (route.src === "routes/404.tsx") {
13172
+ statusCode = 404;
13173
+ } else if (route.src === "routes/500.tsx") {
13174
+ statusCode = 500;
13175
+ }
13176
+ req.hooks.trigger("preRender");
13177
+ const plugins = this.rootConfig.plugins || [];
13178
+ for (const plugin of plugins) {
13179
+ if (plugin.hooks?.preRender) {
13180
+ const newHtml = await plugin.hooks.preRender(html);
13181
+ if (newHtml && typeof newHtml === "string") {
13182
+ html = newHtml;
13183
+ }
13172
13184
  }
13173
13185
  }
13186
+ res.status(statusCode);
13187
+ res.set({ "Content-Type": "text/html" });
13188
+ this.setSecurityHeaders(res, {
13189
+ securityConfig,
13190
+ nonce
13191
+ });
13192
+ res.end(html);
13193
+ };
13194
+ if (route.module.getStaticContent) {
13195
+ let props2;
13196
+ if (route.module.getStaticProps) {
13197
+ props2 = await route.module.getStaticProps({
13198
+ rootConfig: this.rootConfig,
13199
+ params: routeParams
13200
+ });
13201
+ if (props2?.notFound) {
13202
+ return render404();
13203
+ }
13204
+ } else {
13205
+ props2 = { rootConfig: this.rootConfig, params: routeParams };
13206
+ }
13207
+ const result = await route.module.getStaticContent(props2);
13208
+ let body;
13209
+ let contentType;
13210
+ if (typeof result === "string" || Buffer.isBuffer(result)) {
13211
+ body = result;
13212
+ } else if (result && typeof result === "object") {
13213
+ body = result.body;
13214
+ contentType = result.contentType;
13215
+ } else {
13216
+ body = "";
13217
+ }
13218
+ res.status(200);
13219
+ const ext = path2.extname(route.routePath);
13220
+ res.set({
13221
+ "Content-Type": contentType || guessContentType(ext)
13222
+ });
13223
+ res.end(body);
13224
+ return;
13174
13225
  }
13175
- res.status(statusCode);
13176
- res.set({ "Content-Type": "text/html" });
13177
- this.setSecurityHeaders(res, {
13178
- securityConfig,
13179
- nonce
13180
- });
13181
- res.end(html);
13182
- };
13183
- if (route.module.getStaticContent) {
13184
- let props2;
13226
+ if (route.module.handle) {
13227
+ const handlerContext = {
13228
+ route,
13229
+ params: routeParams,
13230
+ i18nFallbackLocales: fallbackLocales,
13231
+ getPreferredLocale,
13232
+ render,
13233
+ render404
13234
+ };
13235
+ req.handlerContext = handlerContext;
13236
+ return route.module.handle(req, res, next);
13237
+ }
13238
+ let props = {};
13185
13239
  if (route.module.getStaticProps) {
13186
- props2 = await route.module.getStaticProps({
13240
+ const propsData = await route.module.getStaticProps({
13187
13241
  rootConfig: this.rootConfig,
13188
13242
  params: routeParams
13189
13243
  });
13190
- } else {
13191
- props2 = { rootConfig: this.rootConfig, params: routeParams };
13192
- }
13193
- const result = await route.module.getStaticContent(props2);
13194
- let body;
13195
- let contentType;
13196
- if (typeof result === "string" || Buffer.isBuffer(result)) {
13197
- body = result;
13198
- } else if (result && typeof result === "object") {
13199
- body = result.body;
13200
- contentType = result.contentType;
13201
- } else {
13202
- body = "";
13203
- }
13204
- res.status(200);
13205
- const ext = path2.extname(route.routePath);
13206
- res.set({
13207
- "Content-Type": contentType || guessContentType(ext)
13208
- });
13209
- return res.end(body);
13210
- }
13211
- if (route.module.handle) {
13212
- const handlerContext = {
13213
- route,
13214
- params: routeParams,
13215
- i18nFallbackLocales: fallbackLocales,
13216
- getPreferredLocale,
13217
- render,
13218
- render404
13219
- };
13220
- req.handlerContext = handlerContext;
13221
- return route.module.handle(req, res, next);
13222
- }
13223
- let props = {};
13224
- if (route.module.getStaticProps) {
13225
- const propsData = await route.module.getStaticProps({
13226
- rootConfig: this.rootConfig,
13227
- params: routeParams
13228
- });
13229
- if (propsData.notFound) {
13230
- return render404();
13231
- }
13232
- if (propsData.props) {
13233
- props = propsData.props;
13244
+ if (propsData.notFound) {
13245
+ return render404();
13246
+ }
13247
+ if (propsData.props) {
13248
+ props = propsData.props;
13249
+ }
13234
13250
  }
13235
- }
13236
- await render(props);
13251
+ await render(props);
13252
+ return;
13253
+ };
13254
+ await processNextMatch();
13237
13255
  }
13238
13256
  async renderComponent(Component, props, options) {
13239
13257
  const { currentPath, route, routeParams, nonce } = options;