@askrjs/askr 0.0.43 → 0.0.44
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/benchmark.js +2 -2
- package/dist/common/ssr.d.ts +22 -1
- package/dist/common/ssr.d.ts.map +1 -1
- package/dist/common/ssr.js +9 -1
- package/dist/common/ssr.js.map +1 -1
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js.map +1 -1
- package/dist/router/match.js.map +1 -1
- package/dist/router/route.d.ts +4 -0
- package/dist/router/route.d.ts.map +1 -1
- package/dist/router/route.js +4 -1
- package/dist/router/route.js.map +1 -1
- package/dist/ssg/batch-render.js +27 -5
- package/dist/ssg/batch-render.js.map +1 -1
- package/dist/ssg/create-static-gen.d.ts.map +1 -1
- package/dist/ssg/create-static-gen.js +6 -4
- package/dist/ssg/create-static-gen.js.map +1 -1
- package/dist/ssg/index.d.ts +2 -1
- package/dist/ssg/resolve-ssg-data.js +18 -1
- package/dist/ssg/resolve-ssg-data.js.map +1 -1
- package/dist/ssg/types.d.ts +3 -0
- package/dist/ssg/types.d.ts.map +1 -1
- package/dist/ssr/context.d.ts +1 -2
- package/dist/ssr/context.d.ts.map +1 -1
- package/dist/ssr/index.d.ts +10 -11
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/index.js +104 -68
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/render-resolved.d.ts +1 -1
- package/package.json +2 -2
package/dist/ssg/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DocumentRenderArgs, DocumentRenderContext, DocumentRenderer } from "../common/ssr.js";
|
|
1
2
|
import { DiscoveredResources, RouteConfig, RouteRenderReason, RouteRenderResult, RouteRenderStatus, SSGGenerateOptions, SSGMetadata, SSGMode, SSGOptions, SSGResult } from "./types.js";
|
|
2
3
|
import { createStaticGen } from "./create-static-gen.js";
|
|
3
|
-
export { type DiscoveredResources, type RouteConfig, type RouteRenderReason, type RouteRenderResult, type RouteRenderStatus, type SSGGenerateOptions, type SSGMetadata, type SSGMode, type SSGOptions, type SSGResult, createStaticGen };
|
|
4
|
+
export { type DiscoveredResources, type DocumentRenderArgs, type DocumentRenderContext, type DocumentRenderer, type RouteConfig, type RouteRenderReason, type RouteRenderResult, type RouteRenderStatus, type SSGGenerateOptions, type SSGMetadata, type SSGMode, type SSGOptions, type SSGResult, createStaticGen };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { interpolateRoutePath } from "./route-utils.js";
|
|
2
2
|
//#region src/ssg/resolve-ssg-data.ts
|
|
3
|
+
function hasOwnRouteData(dataMap, path) {
|
|
4
|
+
return Object.prototype.hasOwnProperty.call(dataMap, path);
|
|
5
|
+
}
|
|
3
6
|
/**
|
|
4
7
|
* Resolve and validate data for SSG routes
|
|
5
8
|
* Returns a map of route path -> SSRData
|
|
@@ -21,6 +24,20 @@ function resolveSsgData(routes, options = {}) {
|
|
|
21
24
|
}
|
|
22
25
|
return dataMap;
|
|
23
26
|
}
|
|
27
|
+
function resolveSsgRouteData(dataMap, routePath, concretePath) {
|
|
28
|
+
if (hasOwnRouteData(dataMap, concretePath)) return {
|
|
29
|
+
hasData: true,
|
|
30
|
+
data: dataMap[concretePath]
|
|
31
|
+
};
|
|
32
|
+
if (hasOwnRouteData(dataMap, routePath)) return {
|
|
33
|
+
hasData: true,
|
|
34
|
+
data: dataMap[routePath]
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
hasData: false,
|
|
38
|
+
data: void 0
|
|
39
|
+
};
|
|
40
|
+
}
|
|
24
41
|
function isStringRecord(value) {
|
|
25
42
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
26
43
|
for (const recordValue of Object.values(value)) if (typeof recordValue !== "string") return false;
|
|
@@ -83,6 +100,6 @@ function validateRoutes(routes) {
|
|
|
83
100
|
}
|
|
84
101
|
}
|
|
85
102
|
//#endregion
|
|
86
|
-
export { expandRoutes, resolveSsgData, validateRoutes };
|
|
103
|
+
export { expandRoutes, resolveSsgData, resolveSsgRouteData, validateRoutes };
|
|
87
104
|
|
|
88
105
|
//# sourceMappingURL=resolve-ssg-data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-ssg-data.js","names":[],"sources":["../../src/ssg/resolve-ssg-data.ts"],"sourcesContent":["/**\n * Data resolution for SSG\n *\n * Merges user-supplied data overrides with any auto-discovered resources.\n * In phase 1, primarily handles user-supplied data.\n */\n\nimport type { SSRData } from '../common/ssr';\nimport type { RouteConfig } from './types';\nimport { interpolateRoutePath } from './route-utils';\n\ninterface DataResolutionOptions {\n /** User-supplied data overrides per route path */\n dataOverrides?: Record<string, unknown>;\n}\n\n/**\n * Resolve and validate data for SSG routes\n * Returns a map of route path -> SSRData\n *\n * In phase 1: accepts user-supplied dataOverrides\n * In phase 2: can be extended to auto-discover resources\n */\nexport function resolveSsgData(\n routes: RouteConfig[],\n options: DataResolutionOptions = {}\n): Record<string, SSRData> {\n const { dataOverrides = {} } = options;\n const dataMap: Record<string, SSRData> = {};\n\n for (const route of routes) {\n const concretePath = interpolateRoutePath(route.path, route.params);\n const overridePath =\n concretePath in dataOverrides\n ? concretePath\n : route.path in dataOverrides\n ? route.path\n : null;\n\n // Check if user provided data for this route\n if (overridePath) {\n const data = dataOverrides[overridePath];\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n throw new Error(\n `data for route \"${overridePath}\" must be an object, got ${typeof data}`\n );\n }\n dataMap[overridePath] = data as SSRData;\n }\n // In phase 1, routes without data are rendered with no SSR data\n // Phase 2 can add auto-discovery here\n }\n\n return dataMap;\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n\n for (const recordValue of Object.values(value)) {\n if (typeof recordValue !== 'string') {\n return false;\n }\n }\n\n return true;\n}\n\nfunction validateRouteShape(route: RouteConfig): void {\n if (typeof route.path !== 'string' || !route.path.startsWith('/')) {\n throw new Error(\n `route path must be a string starting with \"/\", got \"${route.path}\"`\n );\n }\n\n const handler = route.handler ?? route.component;\n if (typeof handler !== 'function') {\n throw new Error(\n `route handler must be a function for path \"${route.path}\"`\n );\n }\n\n if (route.params !== undefined && !isStringRecord(route.params)) {\n throw new Error(\n `route \"${route.path}\" params must be an object containing only string values`\n );\n }\n\n if (route.invalidationKeys !== undefined) {\n if (!Array.isArray(route.invalidationKeys)) {\n throw new Error(\n `route \"${route.path}\" invalidationKeys must be an array of strings`\n );\n }\n for (const key of route.invalidationKeys) {\n if (typeof key !== 'string' || key.length === 0) {\n throw new Error(\n `route \"${route.path}\" invalidationKeys must contain only non-empty strings`\n );\n }\n }\n }\n}\n\nfunction validateEntriesResult(\n route: RouteConfig,\n entries: unknown\n): Array<Record<string, string>> {\n if (!Array.isArray(entries)) {\n throw new Error(\n `route \"${route.path}\" entries must return an array of param maps`\n );\n }\n\n return entries.map((entry, index) => {\n if (!isStringRecord(entry)) {\n throw new Error(\n `route \"${route.path}\" entries[${index}] must be an object containing only string values`\n );\n }\n\n return entry;\n });\n}\n\nexport async function expandRoutes(\n routes: RouteConfig[]\n): Promise<RouteConfig[]> {\n if (!Array.isArray(routes)) {\n throw new Error('routes must be an array');\n }\n\n const expanded: RouteConfig[] = [];\n\n for (const route of routes) {\n validateRouteShape(route);\n\n if (route.params) {\n expanded.push({ ...route, entries: undefined });\n }\n\n if (!route.entries) {\n if (!route.params) {\n expanded.push(route);\n }\n continue;\n }\n\n const entries = validateEntriesResult(route, await route.entries());\n for (const params of entries) {\n expanded.push({ ...route, params, entries: undefined });\n }\n }\n\n return expanded;\n}\n\n/**\n * Validate routes are properly configured\n */\nexport function validateRoutes(routes: RouteConfig[]): void {\n if (!Array.isArray(routes)) {\n throw new Error('routes must be an array');\n }\n\n const seen = new Set<string>();\n\n for (const route of routes) {\n validateRouteShape(route);\n\n const key = `${route.path}::${JSON.stringify(route.params || {})}`;\n if (seen.has(key)) {\n throw new Error(\n `duplicate route entry detected for path \"${route.path}\"`\n );\n }\n seen.add(key);\n\n if (route.path.includes('{')) {\n const paramNames = Array.from(route.path.matchAll(/\\{([^}]+)\\}/g)).map(\n (m) => m[1]\n );\n if (!route.params) {\n throw new Error(\n `route \"${route.path}\" uses path parameters and requires params`\n );\n }\n for (const name of paramNames) {\n if (!(name in route.params)) {\n throw new Error(\n `route \"${route.path}\" missing required param \"${name}\"`\n );\n }\n }\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-ssg-data.js","names":[],"sources":["../../src/ssg/resolve-ssg-data.ts"],"sourcesContent":["/**\n * Data resolution for SSG\n *\n * Merges user-supplied data overrides with any auto-discovered resources.\n * In phase 1, primarily handles user-supplied data.\n */\n\nimport type { SSRData } from '../common/ssr';\nimport type { RouteConfig } from './types';\nimport { interpolateRoutePath } from './route-utils';\n\ninterface DataResolutionOptions {\n /** User-supplied data overrides per route path */\n dataOverrides?: Record<string, unknown>;\n}\n\nexport interface ResolvedSsgRouteData {\n hasData: boolean;\n data?: SSRData;\n}\n\nfunction hasOwnRouteData(\n dataMap: Record<string, SSRData>,\n path: string\n): boolean {\n return Object.prototype.hasOwnProperty.call(dataMap, path);\n}\n\n/**\n * Resolve and validate data for SSG routes\n * Returns a map of route path -> SSRData\n *\n * In phase 1: accepts user-supplied dataOverrides\n * In phase 2: can be extended to auto-discover resources\n */\nexport function resolveSsgData(\n routes: RouteConfig[],\n options: DataResolutionOptions = {}\n): Record<string, SSRData> {\n const { dataOverrides = {} } = options;\n const dataMap: Record<string, SSRData> = {};\n\n for (const route of routes) {\n const concretePath = interpolateRoutePath(route.path, route.params);\n const overridePath =\n concretePath in dataOverrides\n ? concretePath\n : route.path in dataOverrides\n ? route.path\n : null;\n\n // Check if user provided data for this route\n if (overridePath) {\n const data = dataOverrides[overridePath];\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n throw new Error(\n `data for route \"${overridePath}\" must be an object, got ${typeof data}`\n );\n }\n dataMap[overridePath] = data as SSRData;\n }\n // In phase 1, routes without data are rendered with no SSR data\n // Phase 2 can add auto-discovery here\n }\n\n return dataMap;\n}\n\nexport function resolveSsgRouteData(\n dataMap: Record<string, SSRData>,\n routePath: string,\n concretePath: string\n): ResolvedSsgRouteData {\n if (hasOwnRouteData(dataMap, concretePath)) {\n return {\n hasData: true,\n data: dataMap[concretePath],\n };\n }\n\n if (hasOwnRouteData(dataMap, routePath)) {\n return {\n hasData: true,\n data: dataMap[routePath],\n };\n }\n\n return {\n hasData: false,\n data: undefined,\n };\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n\n for (const recordValue of Object.values(value)) {\n if (typeof recordValue !== 'string') {\n return false;\n }\n }\n\n return true;\n}\n\nfunction validateRouteShape(route: RouteConfig): void {\n if (typeof route.path !== 'string' || !route.path.startsWith('/')) {\n throw new Error(\n `route path must be a string starting with \"/\", got \"${route.path}\"`\n );\n }\n\n const handler = route.handler ?? route.component;\n if (typeof handler !== 'function') {\n throw new Error(\n `route handler must be a function for path \"${route.path}\"`\n );\n }\n\n if (route.params !== undefined && !isStringRecord(route.params)) {\n throw new Error(\n `route \"${route.path}\" params must be an object containing only string values`\n );\n }\n\n if (route.invalidationKeys !== undefined) {\n if (!Array.isArray(route.invalidationKeys)) {\n throw new Error(\n `route \"${route.path}\" invalidationKeys must be an array of strings`\n );\n }\n for (const key of route.invalidationKeys) {\n if (typeof key !== 'string' || key.length === 0) {\n throw new Error(\n `route \"${route.path}\" invalidationKeys must contain only non-empty strings`\n );\n }\n }\n }\n}\n\nfunction validateEntriesResult(\n route: RouteConfig,\n entries: unknown\n): Array<Record<string, string>> {\n if (!Array.isArray(entries)) {\n throw new Error(\n `route \"${route.path}\" entries must return an array of param maps`\n );\n }\n\n return entries.map((entry, index) => {\n if (!isStringRecord(entry)) {\n throw new Error(\n `route \"${route.path}\" entries[${index}] must be an object containing only string values`\n );\n }\n\n return entry;\n });\n}\n\nexport async function expandRoutes(\n routes: RouteConfig[]\n): Promise<RouteConfig[]> {\n if (!Array.isArray(routes)) {\n throw new Error('routes must be an array');\n }\n\n const expanded: RouteConfig[] = [];\n\n for (const route of routes) {\n validateRouteShape(route);\n\n if (route.params) {\n expanded.push({ ...route, entries: undefined });\n }\n\n if (!route.entries) {\n if (!route.params) {\n expanded.push(route);\n }\n continue;\n }\n\n const entries = validateEntriesResult(route, await route.entries());\n for (const params of entries) {\n expanded.push({ ...route, params, entries: undefined });\n }\n }\n\n return expanded;\n}\n\n/**\n * Validate routes are properly configured\n */\nexport function validateRoutes(routes: RouteConfig[]): void {\n if (!Array.isArray(routes)) {\n throw new Error('routes must be an array');\n }\n\n const seen = new Set<string>();\n\n for (const route of routes) {\n validateRouteShape(route);\n\n const key = `${route.path}::${JSON.stringify(route.params || {})}`;\n if (seen.has(key)) {\n throw new Error(\n `duplicate route entry detected for path \"${route.path}\"`\n );\n }\n seen.add(key);\n\n if (route.path.includes('{')) {\n const paramNames = Array.from(route.path.matchAll(/\\{([^}]+)\\}/g)).map(\n (m) => m[1]\n );\n if (!route.params) {\n throw new Error(\n `route \"${route.path}\" uses path parameters and requires params`\n );\n }\n for (const name of paramNames) {\n if (!(name in route.params)) {\n throw new Error(\n `route \"${route.path}\" missing required param \"${name}\"`\n );\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/ssg/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentFunction } from "../common/component.js";
|
|
2
|
+
import { DocumentRenderer } from "../common/ssr.js";
|
|
2
3
|
import { RouteAuthMode, RouteHandler, RoutePathParams, RoutePolicy } from "../common/router.js";
|
|
3
4
|
|
|
4
5
|
//#region src/ssg/types.d.ts
|
|
@@ -59,6 +60,8 @@ interface SSGOptions<TRoutes extends readonly RouteConfig[] = RouteConfig[]> {
|
|
|
59
60
|
seed?: number;
|
|
60
61
|
/** Optional override data for resources (route-keyed) */
|
|
61
62
|
dataOverrides?: Record<string, unknown>;
|
|
63
|
+
/** Optional document wrapper for full HTML output */
|
|
64
|
+
document?: DocumentRenderer;
|
|
62
65
|
/** Optional concurrency limit for rendering (default: 10) */
|
|
63
66
|
concurrency?: number;
|
|
64
67
|
/** Preferred render parallelism. `'auto'` resolves from the host machine. */
|
package/dist/ssg/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/ssg/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/ssg/types.ts"],"mappings":";;;;;KAaY,OAAA;AAAA,KAEA,iBAAA;AAAA,KAEA,iBAAA;AAAA,KAUP,iBAAA,uCAAwD,IAAA,GACzD,MAAA,mBACA,eAAA,CAAgB,IAAA;AAdpB;;;;AAA6B;AAE7B;AAFA,UAsBiB,WAAA;;EAEf,IAAA,EAAM,IAAA;EAtBqB;EAwB3B,OAAA,GAAU,YAAA;EAdU;EAgBpB,SAAA,GAAY,iBAAA;EAhB+C;EAkB3D,KAAA,GAAQ,MAAA;EAhBU;EAkBlB,SAAA;EAlBiB;EAoBjB,IAAA,GAAO,aAAA;EAtBc;EAwBrB,IAAA;EAvBE;EAyBF,UAAA;EAxBkB;EA0BlB,QAAA,YAAoB,WAAA;EA1BE;EA4BtB,MAAA,GAAS,iBAAA,CAAkB,IAAA;EApBD;EAsB1B,gBAAA;EApBM;;;;;;;;;;;;EAiCN,OAAA,SACI,KAAA,CAAM,iBAAA,CAAkB,IAAA,KACxB,OAAA,CAAQ,KAAA,CAAM,iBAAA,CAAkB,IAAA;AAAA;;UAIrB,UAAA,0BACU,WAAA,KAAgB,WAAA;EAL9B;EAQX,MAAA,EAAQ,OAAA;EA3CR;EA6CA,SAAA;EA3CA;EA6CA,IAAA;EA3CA;EA6CA,aAAA,GAAgB,MAAA;EA3ChB;EA6CA,QAAA,GAAW,gBAAA;EA3CX;EA6CA,WAAA;EA3CO;EA6CP,WAAA;AAAA;;UAIe,kBAAA;EAzCf;EA2CA,IAAA,GAAO,OAAO;EA3Ca;EA6C3B,WAAA;EA9BA;EAgCA,aAAA;EA/BU;EAiCV,SAAA;AAAA;;UAIe,iBAAA;EApCqB;EAsCpC,IAAA;EAtCwC;EAwCxC,QAAA;EApCyB;EAsCzB,IAAA;EArCyB;EAuCzB,QAAA;EApCQ;EAsCR,cAAA;EA9BW;EAgCX,aAAA;EAhC2B;EAkC3B,MAAA,EAAQ,iBAAA;EA7CiB;EA+CzB,MAAA,EAAQ,iBAAiB;EA5CzB;EA8CA,OAAA;EA5CA;EA8CA,KAAA;AAAA;;UAIe,SAAA;EA5CJ;EA8CX,WAAA;EA1CA;EA4CA,WAAA;EA5CW;EA8CX,UAAA;EA1CiC;EA4CjC,MAAA;EA1Cc;EA4Cd,aAAA;EA5CO;EA8CP,IAAA,EAAM,OAAA;EA1CN;EA4CA,OAAA;EA1CS;EA4CT,OAAA;EAxCe;EA0Cf,OAAA;;EAEA,SAAA;EA1CA;EA4CA,eAAA;EAxCA;EA0CA,iBAAA;EAtCA;EAwCA,MAAA,EAAQ,iBAAiB;AAAA;;UAIV,WAAA,SAAoB,MAAA;EAtC3B;EAwCR,WAAA;EApCA;EAsCA,WAAA;EAtCK;EAwCL,UAAA;EApCwB;EAsCxB,MAAA;EAZyB;EAczB,aAAA;EApCA;EAsCA,IAAA,EAAM,OAAA;EAlCN;EAoCA,OAAA;EAhCA;EAkCA,OAAA;EAhCA;EAkCA,OAAA;EA9BA;EAgCA,SAAA;EA5BA;EA8BA,eAAA;EA1BA;EA4BA,iBAAA;EA5ByB;EA8BzB,MAAA,EAAQ,KAAA;IA1BO,eA4Bb,IAAA,UA5ByB;IA8BzB,QAAA,UAQQ;IANR,QAAA,UANM;IAQN,cAAA,UAlCuC;IAoCvC,aAAA,UApCiC;IAsCjC,MAAA,EAAQ,iBAAA,EAlCV;IAoCE,MAAA,EAAQ,iBAAA,EAhCV;IAkCE,OAAA,WA9BF;IAgCE,KAAA;EAAA;AAAA;;UAKa,mBAAA;EAAA,CACd,GAAA;IACC,KAAA;IACA,YAAA;EAAA;AAAA"}
|
package/dist/ssr/context.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { SSRData } from "../common/ssr.js";
|
|
1
2
|
import { Route, RouteAuthOptions } from "../common/router.js";
|
|
2
3
|
import { SSRDataMissingError } from "../common/ssr-errors.js";
|
|
3
|
-
import { SSRData } from "../common/ssr.js";
|
|
4
|
-
|
|
5
4
|
//#region src/ssr/context.d.ts
|
|
6
5
|
interface RenderContext {
|
|
7
6
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","names":[],"sources":["../../src/ssr/context.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","names":[],"sources":["../../src/ssr/context.ts"],"mappings":";;;;UAgBiB,aAAA;EACf,GAAA;EACA,IAAA;EACA,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,MAAA;EACT,MAAA,YAAkB,KAAA;EAClB,SAAA,GAAY,gBAAA;EACZ,MAAA,GAAS,WAAA;EACT,UAAA,GAAa,GAAA;EACb,aAAA,EAAe,KAAA;EAEf,UAAA;EACA,UAAA,EAAY,MAAA;AAAA;AAAA,KAIF,UAAA,GAAa,aAAa;AAAA,iBAoDtB,mBAAA,CACd,IAAA,WACA,IAAA;EACE,GAAA;EACA,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,MAAA;EACT,MAAA,YAAkB,KAAA;EAClB,SAAA,GAAY,gBAAA;EACZ,MAAA,GAAS,WAAA;AAAA,IAEV,aAAA;;;;;iBAsBa,iBAAA,IAAqB,GAAA,EAAK,aAAA,EAAe,EAAA,QAAU,CAAA,GAAI,CAAA;;AAxFnD;AAIpB;;iBAuGgB,gBAAA,IAAoB,aAAa;AAAA,cASpC,aAAA,SAAa,gBAAmB;AAAA,cAChC,cAAA,SAAc,iBAAoB;AAAA,cAClC,oBAAA,SAAoB,gBAAmB;AAAA,iBAEpC,iBAAA,IAAqB,GAAA,EAAK,aAAA,EAAe,EAAA,QAAU,CAAA,GAAI,CAAA;;;;;iBASvD,mBAAA"}
|
package/dist/ssr/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSXElement } from "../common/jsx.js";
|
|
2
|
+
import { DocumentRenderArgs, DocumentRenderContext, DocumentRenderer, SSRData } from "../common/ssr.js";
|
|
2
3
|
import { RouteAuthOptions, RouteHandler, RouteManifest, RouteRequestResult } from "../common/router.js";
|
|
3
4
|
import { SSRDataMissingError } from "../common/ssr-errors.js";
|
|
4
|
-
import { SSRData } from "../common/ssr.js";
|
|
5
5
|
import { SSRComponent, VNode } from "./types.js";
|
|
6
6
|
import { renderResolvedToStringSync } from "./render-resolved.js";
|
|
7
7
|
|
|
@@ -41,21 +41,20 @@ type SSRRoute = {
|
|
|
41
41
|
handler: RouteHandler;
|
|
42
42
|
namespace?: string;
|
|
43
43
|
};
|
|
44
|
-
|
|
45
|
-
declare function renderToString(opts: {
|
|
46
|
-
url: string;
|
|
47
|
-
routes: SSRRoute[];
|
|
48
|
-
seed?: number;
|
|
49
|
-
data?: SSRData;
|
|
50
|
-
}): string;
|
|
51
|
-
declare function renderToStream(opts: {
|
|
44
|
+
type RouteRenderOptions = {
|
|
52
45
|
url: string;
|
|
53
46
|
routes: SSRRoute[];
|
|
54
47
|
seed?: number;
|
|
55
48
|
data?: SSRData;
|
|
49
|
+
document?: DocumentRenderer;
|
|
50
|
+
};
|
|
51
|
+
type RouteStreamOptions = RouteRenderOptions & {
|
|
56
52
|
onChunk(html: string): void;
|
|
57
53
|
onComplete(): void;
|
|
58
|
-
}
|
|
54
|
+
};
|
|
55
|
+
declare function renderToString(component: (props?: Record<string, unknown>) => VNode | JSXElement | string | number | null): string;
|
|
56
|
+
declare function renderToString(opts: RouteRenderOptions): string;
|
|
57
|
+
declare function renderToStream(opts: RouteStreamOptions): void;
|
|
59
58
|
//#endregion
|
|
60
|
-
export { type SSRComponent, SSRDataMissingError, SSRRoute, type VNode, renderResolvedToStringSync, renderToStream, renderToString, renderToStringSync, resolveRequest };
|
|
59
|
+
export { type DocumentRenderArgs, type DocumentRenderContext, type DocumentRenderer, type SSRComponent, SSRDataMissingError, SSRRoute, type VNode, renderResolvedToStringSync, renderToStream, renderToString, renderToStringSync, resolveRequest };
|
|
61
60
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ssr/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/ssr/index.ts"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/ssr/index.ts"],"mappings":";;;;;;;;;;;;;iBAosCgB,kBAAA,CACd,SAAA,GACE,KAAA,GAAQ,MAAA,sBACL,KAAA,GAAQ,UAAA,iDACb,KAAA,GAAQ,MAAA,mBACR,OAAA;EAAY,IAAA;EAAe,IAAA,GAAO,OAAA;AAAA;AAAA,iBAgCd,cAAA,CACpB,IAAA;EAEM,GAAA;EACA,QAAA,EAAU,aAAA;EACV,MAAA,GAAS,KAAA;IACP,IAAA;IACA,OAAA,EAAS,YAAA;IACT,SAAA;EAAA;EAEF,IAAA,GAAO,gBAAA;EACP,MAAA,GAAS,WAAA;AAAA;EAGT,GAAA;EACA,QAAA,GAAW,aAAA;EACX,MAAA,EAAQ,KAAA;IACN,IAAA;IACA,OAAA,EAAS,YAAA;IACT,SAAA;EAAA;EAEF,IAAA,GAAO,gBAAA;EACP,MAAA,GAAS,WAAA;AAAA,IAEd,OAAA,CAAQ,kBAAA;AAAA,KAsCC,QAAA;EACV,IAAA;EACA,OAAA,EAAS,YAAY;EACrB,SAAA;AAAA;AAAA,KAGG,kBAAA;EACH,GAAA;EACA,MAAA,EAAQ,QAAA;EACR,IAAA;EACA,IAAA,GAAO,OAAA;EACP,QAAA,GAAW,gBAAA;AAAA;AAAA,KAGR,kBAAA,GAAqB,kBAAkB;EAC1C,OAAA,CAAQ,IAAA;EACR,UAAA;AAAA;AAAA,iBAiGc,cAAA,CACd,SAAA,GACE,KAAA,GAAQ,MAAA,sBACL,KAAA,GAAQ,UAAA;AAAA,iBAEC,cAAA,CAAe,IAAwB,EAAlB,kBAAkB;AAAA,iBAiBvC,cAAA,CAAe,IAAwB,EAAlB,kBAAkB"}
|
package/dist/ssr/index.js
CHANGED
|
@@ -10,10 +10,10 @@ import { evaluateCaseState, evaluateShowState } from "../runtime/control.js";
|
|
|
10
10
|
import { SSRDataMissingError } from "../common/ssr-errors.js";
|
|
11
11
|
import { VOID_ELEMENTS, escapeText, styleObjToCss } from "./escape.js";
|
|
12
12
|
import { createRenderContext, getRenderContext, throwSSRDataMissing, withRenderContext } from "./context.js";
|
|
13
|
-
import { resolveRouteFromRoutes, resolveRouteRequest } from "../router/route.js";
|
|
13
|
+
import { _resolveRouteMatchFromRoutes, resolveRouteFromRoutes, resolveRouteRequest } from "../router/route.js";
|
|
14
14
|
import "../jsx/index.js";
|
|
15
15
|
import { DefaultPortal, disposeDefaultPortalScope } from "../foundations/structures/portal.js";
|
|
16
|
-
import { SSR_RENDER_DATA_ATTR } from "../common/ssr.js";
|
|
16
|
+
import { SSR_RENDER_DATA_ATTR, renderDocument } from "../common/ssr.js";
|
|
17
17
|
import { getCurrentRenderData, getNextKey, startRenderPhase, stopRenderPhase } from "./render-keys.js";
|
|
18
18
|
import { installSSRBridge } from "../runtime/ssr-bridge.js";
|
|
19
19
|
import { renderAttrs, renderAttrsDirect } from "./attrs.js";
|
|
@@ -65,24 +65,35 @@ function popSSRStrictPurityGuard() {
|
|
|
65
65
|
/**
|
|
66
66
|
* Synchronous rendering helpers (used for strictly synchronous SSR)
|
|
67
67
|
*/
|
|
68
|
-
function
|
|
69
|
-
if (typeof
|
|
70
|
-
if (typeof
|
|
71
|
-
if (
|
|
72
|
-
if (
|
|
68
|
+
function renderRenderableSync(value, ctx) {
|
|
69
|
+
if (typeof value === "string") return escapeText(value);
|
|
70
|
+
if (typeof value === "number") return escapeText(String(value));
|
|
71
|
+
if (value === null || value === void 0 || value === false) return "";
|
|
72
|
+
if (Array.isArray(value)) return renderChildrenSync(value, ctx);
|
|
73
|
+
if (value && typeof value === "object" && "type" in value) return renderNodeSync(value, ctx);
|
|
73
74
|
return "";
|
|
74
75
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
function renderChildSync(child, ctx) {
|
|
77
|
+
return renderRenderableSync(child, ctx);
|
|
78
|
+
}
|
|
79
|
+
function renderRenderableSyncToSink(value, sink, ctx) {
|
|
80
|
+
if (value === null || value === void 0 || value === false) return;
|
|
81
|
+
if (typeof value === "string") {
|
|
82
|
+
sink.write(escapeText(value));
|
|
79
83
|
return;
|
|
80
84
|
}
|
|
81
|
-
if (typeof
|
|
82
|
-
sink.write(escapeText(String(
|
|
85
|
+
if (typeof value === "number") {
|
|
86
|
+
sink.write(escapeText(String(value)));
|
|
83
87
|
return;
|
|
84
88
|
}
|
|
85
|
-
if (
|
|
89
|
+
if (Array.isArray(value)) {
|
|
90
|
+
renderChildrenSyncToSink(value, sink, ctx);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (value && typeof value === "object" && "type" in value) renderNodeSyncToSink(value, sink, ctx);
|
|
94
|
+
}
|
|
95
|
+
function renderChildSyncToSink(child, sink, ctx) {
|
|
96
|
+
renderRenderableSyncToSink(child, sink, ctx);
|
|
86
97
|
}
|
|
87
98
|
function serializeHydrationRenderData(data) {
|
|
88
99
|
if (!data || Object.keys(data).length === 0) return "";
|
|
@@ -195,19 +206,7 @@ function evaluateControlBoundaryChildren(node) {
|
|
|
195
206
|
function renderChildrenSyncToSink(children, sink, ctx) {
|
|
196
207
|
if (!children || !Array.isArray(children) || children.length === 0) return;
|
|
197
208
|
if (children.length >= 32) {
|
|
198
|
-
for (let i = 0; i < children.length; i++)
|
|
199
|
-
const child = children[i];
|
|
200
|
-
if (child === null || child === void 0 || child === false) continue;
|
|
201
|
-
if (typeof child === "string") {
|
|
202
|
-
sink.write(escapeText(child));
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
if (typeof child === "number") {
|
|
206
|
-
sink.write(escapeText(String(child)));
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
if (child && typeof child === "object" && "type" in child) renderNodeSyncToSink(child, sink, ctx);
|
|
210
|
-
}
|
|
209
|
+
for (let i = 0; i < children.length; i++) renderRenderableSyncToSink(children[i], sink, ctx);
|
|
211
210
|
return;
|
|
212
211
|
}
|
|
213
212
|
for (let i = 0; i < children.length; i++) renderChildSyncToSink(children[i], sink, ctx);
|
|
@@ -238,14 +237,10 @@ function renderNodeSync(node, ctx) {
|
|
|
238
237
|
if (__SSR_DEBUG) try {
|
|
239
238
|
logger.warn("[SSR] renderNodeSync type:", typeof type, type);
|
|
240
239
|
} catch {}
|
|
241
|
-
if (typeof type === "function")
|
|
242
|
-
const result = executeComponentSync(type, props, ctx);
|
|
243
|
-
if (isPromiseLike(result)) throwSSRDataMissing();
|
|
244
|
-
return renderNodeSync(result, ctx);
|
|
245
|
-
}
|
|
240
|
+
if (typeof type === "function") return renderRenderableSync(inheritRenderableKey(node, executeComponentSync(type, props, ctx)), ctx);
|
|
246
241
|
if (typeof type === "symbol") {
|
|
247
242
|
if (type === Fragment) {
|
|
248
|
-
const childrenArr =
|
|
243
|
+
const childrenArr = getRenderableChildren(node);
|
|
249
244
|
/* istanbul ignore if - dev-only debug */
|
|
250
245
|
if (__SSR_DEBUG) try {
|
|
251
246
|
logger.warn("[SSR] fragment children length:", childrenArr?.length);
|
|
@@ -283,19 +278,19 @@ function renderNodeSync(node, ctx) {
|
|
|
283
278
|
if (maybeDangerous !== void 0 && maybeDangerous !== null) {
|
|
284
279
|
const { attrs, dangerousHtml } = renderAttrs(props, { returnDangerousHtml: true });
|
|
285
280
|
if (dangerousHtml !== void 0) return `<${typeStr}${attrs}>${dangerousHtml}</${typeStr}>`;
|
|
286
|
-
return `<${typeStr}${attrs}>${renderChildrenSync(node
|
|
281
|
+
return `<${typeStr}${attrs}>${renderChildrenSync(getRenderableChildren(node), ctx)}</${typeStr}>`;
|
|
287
282
|
}
|
|
288
|
-
return `<${typeStr}${renderAttrs(props)}>${renderChildrenSync(node
|
|
283
|
+
return `<${typeStr}${renderAttrs(props)}>${renderChildrenSync(getRenderableChildren(node), ctx)}</${typeStr}>`;
|
|
289
284
|
}
|
|
290
285
|
function renderNodeSyncToSink(node, sink, ctx) {
|
|
291
286
|
const { type, props } = node;
|
|
292
287
|
if (typeof type === "function") {
|
|
293
|
-
|
|
288
|
+
renderRenderableSyncToSink(inheritRenderableKey(node, executeComponentSync(type, props, ctx)), sink, ctx);
|
|
294
289
|
return;
|
|
295
290
|
}
|
|
296
291
|
if (typeof type === "symbol") {
|
|
297
292
|
if (type === Fragment) {
|
|
298
|
-
renderChildrenSyncToSink(
|
|
293
|
+
renderChildrenSyncToSink(getRenderableChildren(node), sink, ctx);
|
|
299
294
|
return;
|
|
300
295
|
}
|
|
301
296
|
if (type === __CONTROL_BOUNDARY__) {
|
|
@@ -344,16 +339,11 @@ function renderNodeSyncToSink(node, sink, ctx) {
|
|
|
344
339
|
renderAttrsDirect(props, sink);
|
|
345
340
|
sink.write(">");
|
|
346
341
|
if (dangerousHtml !== void 0) sink.write(dangerousHtml);
|
|
347
|
-
else renderChildrenSyncToSink(node
|
|
342
|
+
else renderChildrenSyncToSink(getRenderableChildren(node), sink, ctx);
|
|
348
343
|
sinkWrite3(sink, "</", typeStr, ">");
|
|
349
344
|
return;
|
|
350
345
|
}
|
|
351
|
-
|
|
352
|
-
if (children === void 0 && props?.children !== void 0) {
|
|
353
|
-
const propsChildren = props.children;
|
|
354
|
-
if (Array.isArray(propsChildren)) children = propsChildren;
|
|
355
|
-
else if (propsChildren !== null && propsChildren !== false) children = [propsChildren];
|
|
356
|
-
}
|
|
346
|
+
const children = getRenderableChildren(node);
|
|
357
347
|
if (!children || Array.isArray(children) && children.length === 0) {
|
|
358
348
|
sinkWrite2(sink, "<", typeStr);
|
|
359
349
|
renderAttrsDirect(props, sink);
|
|
@@ -532,10 +522,11 @@ function verifyExpectedNode(node, state, ctx) {
|
|
|
532
522
|
state.pendingText += String(node);
|
|
533
523
|
return true;
|
|
534
524
|
}
|
|
525
|
+
if (Array.isArray(node)) return verifyExpectedChildren(node, state, ctx);
|
|
535
526
|
if (!node || typeof node !== "object" || !("type" in node)) return true;
|
|
536
527
|
const vnode = node;
|
|
537
528
|
const { type, props } = vnode;
|
|
538
|
-
if (typeof type === "function") return
|
|
529
|
+
if (typeof type === "function") return verifyRenderableNode(inheritRenderableKey(vnode, executeComponentSync(type, props, ctx)), state, ctx);
|
|
539
530
|
if (typeof type === "symbol") {
|
|
540
531
|
if (type === __CONTROL_BOUNDARY__) {
|
|
541
532
|
const children = evaluateControlBoundaryChildren(vnode);
|
|
@@ -655,6 +646,64 @@ async function resolveRequest(opts) {
|
|
|
655
646
|
params: resolved.params
|
|
656
647
|
};
|
|
657
648
|
}
|
|
649
|
+
function resolveSSRRouteRender(opts) {
|
|
650
|
+
const { url, routes, seed = 12345, data, document } = opts;
|
|
651
|
+
const routeTable = routes.map((route) => ({ ...route }));
|
|
652
|
+
const requestUrl = new URL(url, "http://localhost");
|
|
653
|
+
const matched = _resolveRouteMatchFromRoutes(requestUrl.pathname, routeTable);
|
|
654
|
+
if (!matched) throw new Error(`SSR: no route found for url: ${url}`);
|
|
655
|
+
const ctx = createRenderContext(seed, {
|
|
656
|
+
url,
|
|
657
|
+
data,
|
|
658
|
+
params: matched.params,
|
|
659
|
+
routes: routeTable
|
|
660
|
+
});
|
|
661
|
+
return {
|
|
662
|
+
url,
|
|
663
|
+
requestUrl,
|
|
664
|
+
route: matched.route,
|
|
665
|
+
params: matched.params,
|
|
666
|
+
seed,
|
|
667
|
+
data,
|
|
668
|
+
ctx,
|
|
669
|
+
document
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
function buildDocumentRenderArgs(resolved, appHtml) {
|
|
673
|
+
return {
|
|
674
|
+
appHtml,
|
|
675
|
+
context: {
|
|
676
|
+
mode: "ssr",
|
|
677
|
+
url: resolved.url,
|
|
678
|
+
pathname: resolved.requestUrl.pathname,
|
|
679
|
+
search: resolved.requestUrl.search,
|
|
680
|
+
hash: resolved.requestUrl.hash,
|
|
681
|
+
params: resolved.params,
|
|
682
|
+
data: resolved.data,
|
|
683
|
+
seed: resolved.seed,
|
|
684
|
+
route: {
|
|
685
|
+
path: resolved.route.path,
|
|
686
|
+
namespace: resolved.route.namespace
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
function renderResolvedRouteAppToSink(resolved, sink) {
|
|
692
|
+
const { ctx, data, route, params } = resolved;
|
|
693
|
+
withRenderContext(ctx, () => {
|
|
694
|
+
startRenderPhase(data || null);
|
|
695
|
+
try {
|
|
696
|
+
renderRenderableSyncToSink(executeComponentSync(route.handler, params, ctx), sink, ctx);
|
|
697
|
+
sink.write(serializeHydrationRenderData(data));
|
|
698
|
+
} finally {
|
|
699
|
+
try {
|
|
700
|
+
stopRenderPhase();
|
|
701
|
+
} finally {
|
|
702
|
+
disposeSSRTemporaryOwners(ctx);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
}
|
|
658
707
|
function renderToString(arg) {
|
|
659
708
|
if (typeof arg === "function") return renderToStringSync(arg);
|
|
660
709
|
const opts = arg;
|
|
@@ -675,29 +724,16 @@ function renderToStream(opts) {
|
|
|
675
724
|
sink.end();
|
|
676
725
|
}
|
|
677
726
|
function renderToSinkInternal(opts) {
|
|
678
|
-
const {
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
withRenderContext(ctx, () => {
|
|
689
|
-
startRenderPhase(data || null);
|
|
690
|
-
try {
|
|
691
|
-
renderNodeSyncToSink(executeComponentSync(resolved.handler, resolved.params, ctx), sink, ctx);
|
|
692
|
-
sink.write(serializeHydrationRenderData(data));
|
|
693
|
-
} finally {
|
|
694
|
-
try {
|
|
695
|
-
stopRenderPhase();
|
|
696
|
-
} finally {
|
|
697
|
-
disposeSSRTemporaryOwners(ctx);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
});
|
|
727
|
+
const { sink, ...renderOptions } = opts;
|
|
728
|
+
const resolved = resolveSSRRouteRender(renderOptions);
|
|
729
|
+
if (!resolved.document) {
|
|
730
|
+
renderResolvedRouteAppToSink(resolved, sink);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
const appSink = new StringSink();
|
|
734
|
+
renderResolvedRouteAppToSink(resolved, appSink);
|
|
735
|
+
appSink.end();
|
|
736
|
+
sink.write(renderDocument(resolved.document, buildDocumentRenderArgs(resolved, appSink.toString()), "renderToString()/renderToStream()"));
|
|
701
737
|
}
|
|
702
738
|
//#endregion
|
|
703
739
|
export { SSRDataMissingError, renderResolvedToStringSync, renderToStream, renderToString, renderToStringSync, resolveRequest };
|