@fluojs/react 0.1.0 → 0.2.0
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/README.ko.md +629 -16
- package/README.md +644 -25
- package/dist/decorators.d.ts +3 -3
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +10 -4
- package/dist/diagnostics.d.ts +110 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +180 -0
- package/dist/error-representation.d.ts +28 -0
- package/dist/error-representation.d.ts.map +1 -0
- package/dist/error-representation.js +28 -0
- package/dist/experimental/rsc-flight-response.d.ts.map +1 -1
- package/dist/experimental/rsc-flight-response.js +2 -6
- package/dist/experimental/server-functions-server.js +1 -1
- package/dist/experimental/server-functions-types.d.ts +1 -1
- package/dist/experimental/server-functions-types.d.ts.map +1 -1
- package/dist/index.d.ts +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/module.d.ts +8 -2
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +31 -8
- package/dist/page-catalog.d.ts +29 -0
- package/dist/page-catalog.d.ts.map +1 -0
- package/dist/page-catalog.js +46 -0
- package/dist/page-metadata.d.ts +58 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +139 -0
- package/dist/page-renderer.d.ts +24 -0
- package/dist/page-renderer.d.ts.map +1 -0
- package/dist/page-renderer.js +18 -0
- package/dist/page-result.d.ts +16 -0
- package/dist/page-result.d.ts.map +1 -0
- package/dist/page-result.js +101 -0
- package/dist/render-diagnostics.d.ts +25 -0
- package/dist/render-diagnostics.d.ts.map +1 -0
- package/dist/render-diagnostics.js +94 -0
- package/dist/render-policy-metadata.d.ts +40 -0
- package/dist/render-policy-metadata.d.ts.map +1 -0
- package/dist/render-policy-metadata.js +136 -0
- package/dist/render-policy.d.ts +87 -0
- package/dist/render-policy.d.ts.map +1 -0
- package/dist/render-policy.js +203 -0
- package/dist/render-stream.d.ts +1 -1
- package/dist/render-stream.d.ts.map +1 -1
- package/dist/render-stream.js +80 -15
- package/dist/render.d.ts +12 -3
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +70 -76
- package/dist/server-entry.d.ts +13 -1
- package/dist/server-entry.d.ts.map +1 -1
- package/dist/server-entry.js +21 -11
- package/dist/typegen-artifact.d.ts +9 -0
- package/dist/typegen-artifact.d.ts.map +1 -0
- package/dist/typegen-artifact.js +116 -0
- package/dist/typegen.d.ts +41 -0
- package/dist/typegen.d.ts.map +1 -0
- package/dist/typegen.js +162 -0
- package/package.json +11 -6
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HandlerDescriptor, HttpMethod } from '@fluojs/http/portable';
|
|
2
|
+
/**
|
|
3
|
+
* Immutable bootstrap-resolved description of one React page handler.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The catalog is a one-way projection from authoritative compiled HTTP descriptors.
|
|
7
|
+
* Effective path, method, version, and params come from HTTP compilation rather than
|
|
8
|
+
* the static values passed to `@Router(...)` and `@Path(...)`. Catalog entries never
|
|
9
|
+
* participate in route matching, conflict detection, or dispatch.
|
|
10
|
+
*/
|
|
11
|
+
export interface ReactPageCatalogEntry {
|
|
12
|
+
readonly handler: string;
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly kind: 'react-page';
|
|
15
|
+
readonly method: HttpMethod;
|
|
16
|
+
readonly module?: string;
|
|
17
|
+
readonly params: readonly string[];
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly router: string;
|
|
20
|
+
readonly version?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates an immutable React page catalog from compiled HTTP handler descriptors.
|
|
24
|
+
*
|
|
25
|
+
* @param descriptors Authoritative descriptors produced by `createHandlerMapping(...)`.
|
|
26
|
+
* @returns Frozen React page entries in descriptor registration order; ordinary HTTP handlers are omitted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createReactPageCatalog(descriptors: readonly HandlerDescriptor[]): readonly ReactPageCatalogEntry[];
|
|
29
|
+
//# sourceMappingURL=page-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-catalog.d.ts","sourceRoot":"","sources":["../src/page-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAK3E;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,iBAAiB,EAAE,GACxC,SAAS,qBAAqB,EAAE,CA0BlC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createRuntimeRouteInspection } from '@fluojs/runtime/internal';
|
|
2
|
+
import { getReactPathMetadata, getReactRouterMetadata } from './decorators.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Immutable bootstrap-resolved description of one React page handler.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The catalog is a one-way projection from authoritative compiled HTTP descriptors.
|
|
9
|
+
* Effective path, method, version, and params come from HTTP compilation rather than
|
|
10
|
+
* the static values passed to `@Router(...)` and `@Path(...)`. Catalog entries never
|
|
11
|
+
* participate in route matching, conflict detection, or dispatch.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates an immutable React page catalog from compiled HTTP handler descriptors.
|
|
16
|
+
*
|
|
17
|
+
* @param descriptors Authoritative descriptors produced by `createHandlerMapping(...)`.
|
|
18
|
+
* @returns Frozen React page entries in descriptor registration order; ordinary HTTP handlers are omitted.
|
|
19
|
+
*/
|
|
20
|
+
export function createReactPageCatalog(descriptors) {
|
|
21
|
+
const pages = [];
|
|
22
|
+
for (const descriptor of descriptors) {
|
|
23
|
+
const routerMetadata = getReactRouterMetadata(descriptor.controllerToken);
|
|
24
|
+
const pathMetadata = getReactPathMetadata(descriptor.controllerToken, descriptor.methodName);
|
|
25
|
+
if (!routerMetadata || !pathMetadata) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const route = createRuntimeRouteInspection(descriptor);
|
|
29
|
+
pages.push(Object.freeze({
|
|
30
|
+
handler: route.handler,
|
|
31
|
+
id: route.id,
|
|
32
|
+
kind: 'react-page',
|
|
33
|
+
method: route.method,
|
|
34
|
+
...(route.module ? {
|
|
35
|
+
module: route.module
|
|
36
|
+
} : {}),
|
|
37
|
+
params: route.params,
|
|
38
|
+
path: route.path,
|
|
39
|
+
router: route.controller,
|
|
40
|
+
...(route.version ? {
|
|
41
|
+
version: route.version
|
|
42
|
+
} : {})
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze(pages);
|
|
46
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import type { ReactRenderContext } from './render.js';
|
|
3
|
+
import type { ReactRenderPolicies } from './render-policy.js';
|
|
4
|
+
import { type ReactRenderPolicyDecorator } from './render-policy-metadata.js';
|
|
5
|
+
/** Request-scoped, response-free context supplied to page metadata factories. */
|
|
6
|
+
export type ReactPageMetadataContext = {
|
|
7
|
+
readonly container: ReactRenderContext['container'];
|
|
8
|
+
readonly request: ReactRenderContext['request'];
|
|
9
|
+
readonly requestId?: ReactRenderContext['requestId'];
|
|
10
|
+
};
|
|
11
|
+
/** One name- or property-addressed React document meta descriptor. */
|
|
12
|
+
export type ReactPageMeta = {
|
|
13
|
+
readonly content: string;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly property?: never;
|
|
16
|
+
} | {
|
|
17
|
+
readonly content: string;
|
|
18
|
+
readonly name?: never;
|
|
19
|
+
readonly property: string;
|
|
20
|
+
};
|
|
21
|
+
/** One bounded React document link descriptor. */
|
|
22
|
+
export type ReactPageLink = {
|
|
23
|
+
readonly href: string;
|
|
24
|
+
readonly media?: string;
|
|
25
|
+
readonly rel: string;
|
|
26
|
+
readonly type?: string;
|
|
27
|
+
};
|
|
28
|
+
/** Composed document-head metadata for one matched React page request. */
|
|
29
|
+
export type ReactPageMetadata = {
|
|
30
|
+
readonly links?: readonly ReactPageLink[];
|
|
31
|
+
readonly meta?: readonly ReactPageMeta[];
|
|
32
|
+
readonly title?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Synchronous request-aware factory for one React page metadata declaration. */
|
|
35
|
+
export type ReactPageMetadataFactory = (context: ReactPageMetadataContext) => ReactPageMetadata;
|
|
36
|
+
/**
|
|
37
|
+
* Marks a React router class or `@Path(...)` method with one page metadata factory.
|
|
38
|
+
*
|
|
39
|
+
* @param factory Synchronous request-aware factory consumed by the application page renderer.
|
|
40
|
+
* @returns A class-or-method decorator that records render-only metadata without changing HTTP matching.
|
|
41
|
+
*/
|
|
42
|
+
export declare function PageMetadata(factory: ReactPageMetadataFactory): ReactRenderPolicyDecorator;
|
|
43
|
+
/**
|
|
44
|
+
* Resolves ordered page metadata factories for one active request.
|
|
45
|
+
*
|
|
46
|
+
* @param policies Matched page policies supplied to the application renderer.
|
|
47
|
+
* @param context Active request-scoped React render context.
|
|
48
|
+
* @returns A frozen metadata snapshot with deterministic nearest-title and descriptor replacement semantics.
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveReactPageMetadata(policies: ReactRenderPolicies, context: ReactRenderContext): ReactPageMetadata;
|
|
51
|
+
/**
|
|
52
|
+
* Creates escaped ordinary React head elements from resolved page metadata.
|
|
53
|
+
*
|
|
54
|
+
* @param metadata Resolved metadata snapshot for one matched page request.
|
|
55
|
+
* @returns Frozen title, meta, and link elements in deterministic composition order.
|
|
56
|
+
*/
|
|
57
|
+
export declare function createReactPageMetadataElements(metadata: ReactPageMetadata): readonly ReactElement[];
|
|
58
|
+
//# sourceMappingURL=page-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-metadata.d.ts","sourceRoot":"","sources":["../src/page-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,6BAA6B,CAAC;AAErC,iFAAiF;AACjF,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CACtD,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,aAAa,GACrB;IACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,kDAAkD;AAClD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,wBAAwB,KAC9B,iBAAiB,CAAC;AAgCvB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,0BAA0B,CAE1F;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,kBAAkB,GAC1B,iBAAiB,CA8BnB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,iBAAiB,GAC1B,SAAS,YAAY,EAAE,CAgCzB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { createReactRenderPolicyDecorator } from './render-policy-metadata.js';
|
|
3
|
+
|
|
4
|
+
/** Request-scoped, response-free context supplied to page metadata factories. */
|
|
5
|
+
|
|
6
|
+
/** One name- or property-addressed React document meta descriptor. */
|
|
7
|
+
|
|
8
|
+
/** One bounded React document link descriptor. */
|
|
9
|
+
|
|
10
|
+
/** Composed document-head metadata for one matched React page request. */
|
|
11
|
+
|
|
12
|
+
/** Synchronous request-aware factory for one React page metadata declaration. */
|
|
13
|
+
|
|
14
|
+
function replaceEntry(entries, key, value) {
|
|
15
|
+
entries.delete(key);
|
|
16
|
+
entries.set(key, value);
|
|
17
|
+
}
|
|
18
|
+
function metaIdentity(meta) {
|
|
19
|
+
return meta.name !== undefined ? JSON.stringify(['name', meta.name]) : JSON.stringify(['property', meta.property]);
|
|
20
|
+
}
|
|
21
|
+
function linkIdentity(link) {
|
|
22
|
+
return JSON.stringify([link.rel, link.href]);
|
|
23
|
+
}
|
|
24
|
+
function cloneMeta(meta) {
|
|
25
|
+
return meta.name !== undefined ? Object.freeze({
|
|
26
|
+
content: meta.content,
|
|
27
|
+
name: meta.name
|
|
28
|
+
}) : Object.freeze({
|
|
29
|
+
content: meta.content,
|
|
30
|
+
property: meta.property
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function cloneLink(link) {
|
|
34
|
+
return Object.freeze({
|
|
35
|
+
href: link.href,
|
|
36
|
+
...(link.media === undefined ? {} : {
|
|
37
|
+
media: link.media
|
|
38
|
+
}),
|
|
39
|
+
rel: link.rel,
|
|
40
|
+
...(link.type === undefined ? {} : {
|
|
41
|
+
type: link.type
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Marks a React router class or `@Path(...)` method with one page metadata factory.
|
|
48
|
+
*
|
|
49
|
+
* @param factory Synchronous request-aware factory consumed by the application page renderer.
|
|
50
|
+
* @returns A class-or-method decorator that records render-only metadata without changing HTTP matching.
|
|
51
|
+
*/
|
|
52
|
+
export function PageMetadata(factory) {
|
|
53
|
+
return createReactRenderPolicyDecorator('page-metadata', factory);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolves ordered page metadata factories for one active request.
|
|
58
|
+
*
|
|
59
|
+
* @param policies Matched page policies supplied to the application renderer.
|
|
60
|
+
* @param context Active request-scoped React render context.
|
|
61
|
+
* @returns A frozen metadata snapshot with deterministic nearest-title and descriptor replacement semantics.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveReactPageMetadata(policies, context) {
|
|
64
|
+
const metadataContext = Object.freeze({
|
|
65
|
+
container: context.container,
|
|
66
|
+
request: context.request,
|
|
67
|
+
...(context.requestId === undefined ? {} : {
|
|
68
|
+
requestId: context.requestId
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
const meta = new Map();
|
|
72
|
+
const links = new Map();
|
|
73
|
+
let title;
|
|
74
|
+
for (const factory of policies.pageMetadata ?? []) {
|
|
75
|
+
const declaration = factory(metadataContext);
|
|
76
|
+
if (declaration.title !== undefined) {
|
|
77
|
+
title = declaration.title;
|
|
78
|
+
}
|
|
79
|
+
for (const descriptor of declaration.meta ?? []) {
|
|
80
|
+
const cloned = cloneMeta(descriptor);
|
|
81
|
+
replaceEntry(meta, metaIdentity(cloned), cloned);
|
|
82
|
+
}
|
|
83
|
+
for (const descriptor of declaration.links ?? []) {
|
|
84
|
+
const cloned = cloneLink(descriptor);
|
|
85
|
+
replaceEntry(links, linkIdentity(cloned), cloned);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return Object.freeze({
|
|
89
|
+
...(links.size === 0 ? {} : {
|
|
90
|
+
links: Object.freeze([...links.values()])
|
|
91
|
+
}),
|
|
92
|
+
...(meta.size === 0 ? {} : {
|
|
93
|
+
meta: Object.freeze([...meta.values()])
|
|
94
|
+
}),
|
|
95
|
+
...(title === undefined ? {} : {
|
|
96
|
+
title
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates escaped ordinary React head elements from resolved page metadata.
|
|
103
|
+
*
|
|
104
|
+
* @param metadata Resolved metadata snapshot for one matched page request.
|
|
105
|
+
* @returns Frozen title, meta, and link elements in deterministic composition order.
|
|
106
|
+
*/
|
|
107
|
+
export function createReactPageMetadataElements(metadata) {
|
|
108
|
+
const elements = [];
|
|
109
|
+
if (metadata.title !== undefined) {
|
|
110
|
+
elements.push(createElement('title', {
|
|
111
|
+
key: 'title'
|
|
112
|
+
}, metadata.title));
|
|
113
|
+
}
|
|
114
|
+
for (const meta of metadata.meta ?? []) {
|
|
115
|
+
elements.push(meta.name !== undefined ? createElement('meta', {
|
|
116
|
+
content: meta.content,
|
|
117
|
+
key: `meta:${metaIdentity(meta)}`,
|
|
118
|
+
name: meta.name
|
|
119
|
+
}) : createElement('meta', {
|
|
120
|
+
content: meta.content,
|
|
121
|
+
key: `meta:${metaIdentity(meta)}`,
|
|
122
|
+
property: meta.property
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
for (const link of metadata.links ?? []) {
|
|
126
|
+
elements.push(createElement('link', {
|
|
127
|
+
href: link.href,
|
|
128
|
+
key: `link:${linkIdentity(link)}`,
|
|
129
|
+
...(link.media === undefined ? {} : {
|
|
130
|
+
media: link.media
|
|
131
|
+
}),
|
|
132
|
+
rel: link.rel,
|
|
133
|
+
...(link.type === undefined ? {} : {
|
|
134
|
+
type: link.type
|
|
135
|
+
})
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
return Object.freeze(elements);
|
|
139
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Token } from '@fluojs/core';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import type { ReactRenderContext } from './render.js';
|
|
4
|
+
import type { ReactRenderPolicies } from './render-policy.js';
|
|
5
|
+
import type { ReactServerEntry } from './server-entry.js';
|
|
6
|
+
/**
|
|
7
|
+
* Application-owned page composition callback registered through `ReactModule.forRoot(...)`.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The callback can wrap one page element with an application document, shared providers,
|
|
11
|
+
* request-derived client route state, hydration assets, and recoverable-error policy. It must
|
|
12
|
+
* return `ReactServerEntry` so the existing HTTP response-writer lifecycle remains authoritative.
|
|
13
|
+
* Browser and Vite helpers stay application-owned and may be composed without widening the
|
|
14
|
+
* runtime-neutral root import boundary.
|
|
15
|
+
*
|
|
16
|
+
* @param page React page element produced by an application handler.
|
|
17
|
+
* @param context Active render context containing the matched request URL, params, and response.
|
|
18
|
+
* @param policies Resolved class and method render policy component references for this page.
|
|
19
|
+
* @returns An existing React server entry finalized by the fluo HTTP dispatcher.
|
|
20
|
+
*/
|
|
21
|
+
export type ReactPageRenderer = (page: ReactElement, context: ReactRenderContext, policies: ReactRenderPolicies) => ReactServerEntry;
|
|
22
|
+
/** Dependency-injection token for the application `ReactPageRenderer`. */
|
|
23
|
+
export declare const REACT_PAGE_RENDERER: Token<ReactPageRenderer>;
|
|
24
|
+
//# sourceMappingURL=page-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-renderer.d.ts","sourceRoot":"","sources":["../src/page-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,mBAAmB,KAC1B,gBAAgB,CAAC;AAEtB,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,iBAAiB,CAA0C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application-owned page composition callback registered through `ReactModule.forRoot(...)`.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* The callback can wrap one page element with an application document, shared providers,
|
|
6
|
+
* request-derived client route state, hydration assets, and recoverable-error policy. It must
|
|
7
|
+
* return `ReactServerEntry` so the existing HTTP response-writer lifecycle remains authoritative.
|
|
8
|
+
* Browser and Vite helpers stay application-owned and may be composed without widening the
|
|
9
|
+
* runtime-neutral root import boundary.
|
|
10
|
+
*
|
|
11
|
+
* @param page React page element produced by an application handler.
|
|
12
|
+
* @param context Active render context containing the matched request URL, params, and response.
|
|
13
|
+
* @param policies Resolved class and method render policy component references for this page.
|
|
14
|
+
* @returns An existing React server entry finalized by the fluo HTTP dispatcher.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Dependency-injection token for the application `ReactPageRenderer`. */
|
|
18
|
+
export const REACT_PAGE_RENDERER = Symbol.for('fluo.react.page-renderer');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Middleware } from '@fluojs/http/portable';
|
|
2
|
+
import { type ReactSsrDiagnosticHandler } from './diagnostics.js';
|
|
3
|
+
import type { ReactPageRenderer } from './page-renderer.js';
|
|
4
|
+
type ReactPageResultRuntime = {
|
|
5
|
+
readonly onDiagnostic?: ReactSsrDiagnosticHandler;
|
|
6
|
+
readonly renderPage?: ReactPageRenderer;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Creates module middleware that finalizes React page values through the HTTP response lifecycle.
|
|
10
|
+
*
|
|
11
|
+
* @param runtime Module-level renderer and diagnostic configuration.
|
|
12
|
+
* @returns Middleware that installs request-local React response state.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createReactPageResultMiddleware(runtime: ReactPageResultRuntime): Middleware;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=page-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-result.d.ts","sourceRoot":"","sources":["../src/page-result.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAKhB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAML,KAAK,yBAAyB,EAG/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CACzC,CAAC;AAuGF;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,sBAAsB,GAAG,UAAU,CAgB3F"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { RequestAbortedError } from '@fluojs/http/portable';
|
|
2
|
+
import { registerFrameworkResponseValueFinalizer } from '@fluojs/http/internal';
|
|
3
|
+
import { isValidElement } from 'react';
|
|
4
|
+
import { getReactPathMetadata } from './decorators.js';
|
|
5
|
+
import { bindReactSsrDiagnosticHandler, createReactSsrDiagnostic, REACT_SSR_DIAGNOSTIC_CODES, REACT_SSR_DIAGNOSTIC_PHASES, ReactSsrDiagnosticError, readReactSsrDiagnosticMarker, reportReactSsrDiagnostic } from './diagnostics.js';
|
|
6
|
+
import { getReactRenderPolicies } from './render-policy.js';
|
|
7
|
+
import { isReactServerEntry } from './server-entry.js';
|
|
8
|
+
function isRequestAborted(context) {
|
|
9
|
+
return context.request.signal?.aborted === true || context.request.isAborted?.() === true;
|
|
10
|
+
}
|
|
11
|
+
function reportReactPageFailure(runtime, error, context) {
|
|
12
|
+
const marker = readReactSsrDiagnosticMarker(context, error);
|
|
13
|
+
if (marker !== undefined) {
|
|
14
|
+
reportReactSsrDiagnostic(runtime.onDiagnostic, createReactSsrDiagnostic({
|
|
15
|
+
code: marker.code,
|
|
16
|
+
error,
|
|
17
|
+
phase: marker.phase,
|
|
18
|
+
request: context.request,
|
|
19
|
+
...(context.requestId === undefined ? {} : {
|
|
20
|
+
requestId: context.requestId
|
|
21
|
+
})
|
|
22
|
+
}));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (error instanceof ReactSsrDiagnosticError) {
|
|
26
|
+
reportReactSsrDiagnostic(runtime.onDiagnostic, createReactSsrDiagnostic({
|
|
27
|
+
code: error.code,
|
|
28
|
+
error,
|
|
29
|
+
phase: error.phase,
|
|
30
|
+
request: context.request,
|
|
31
|
+
...(context.requestId === undefined ? {} : {
|
|
32
|
+
requestId: context.requestId
|
|
33
|
+
})
|
|
34
|
+
}));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (error instanceof RequestAbortedError || isRequestAborted(context)) {
|
|
38
|
+
reportReactSsrDiagnostic(runtime.onDiagnostic, createReactSsrDiagnostic({
|
|
39
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.requestAbort,
|
|
40
|
+
error,
|
|
41
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.requestAbort,
|
|
42
|
+
request: context.request,
|
|
43
|
+
...(context.requestId === undefined ? {} : {
|
|
44
|
+
requestId: context.requestId
|
|
45
|
+
})
|
|
46
|
+
}));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!context.response.committed) {
|
|
50
|
+
reportReactSsrDiagnostic(runtime.onDiagnostic, createReactSsrDiagnostic({
|
|
51
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.httpPipelineFailure,
|
|
52
|
+
error,
|
|
53
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.httpPipeline,
|
|
54
|
+
request: context.request,
|
|
55
|
+
...(context.requestId === undefined ? {} : {
|
|
56
|
+
requestId: context.requestId
|
|
57
|
+
})
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function finalizeReactPageResult(runtime, context) {
|
|
62
|
+
if (getReactPathMetadata(context.handler.controllerToken, context.handler.methodName) === undefined) {
|
|
63
|
+
return context.value;
|
|
64
|
+
}
|
|
65
|
+
if (isReactServerEntry(context.value)) {
|
|
66
|
+
return context.value;
|
|
67
|
+
}
|
|
68
|
+
if (!isValidElement(context.value)) {
|
|
69
|
+
return context.value;
|
|
70
|
+
}
|
|
71
|
+
if (runtime.renderPage === undefined) {
|
|
72
|
+
throw new ReactSsrDiagnosticError('A @Path handler returned a ReactElement, but ReactModule.forRoot(...) has no renderPage callback. ' + 'Configure renderPage or return createReactServerEntry(...) explicitly.', {
|
|
73
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.missingPageRenderer,
|
|
74
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.httpPipeline
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const policies = getReactRenderPolicies(context.handler.controllerToken, context.handler.methodName);
|
|
78
|
+
const entry = runtime.renderPage(context.value, context.requestContext, policies);
|
|
79
|
+
return entry;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates module middleware that finalizes React page values through the HTTP response lifecycle.
|
|
84
|
+
*
|
|
85
|
+
* @param runtime Module-level renderer and diagnostic configuration.
|
|
86
|
+
* @returns Middleware that installs request-local React response state.
|
|
87
|
+
*/
|
|
88
|
+
export function createReactPageResultMiddleware(runtime) {
|
|
89
|
+
return {
|
|
90
|
+
async handle(context, next) {
|
|
91
|
+
bindReactSsrDiagnosticHandler(context.requestContext, runtime.onDiagnostic);
|
|
92
|
+
registerFrameworkResponseValueFinalizer(context.requestContext, finalizerContext => finalizeReactPageResult(runtime, finalizerContext));
|
|
93
|
+
try {
|
|
94
|
+
await next();
|
|
95
|
+
} catch (error) {
|
|
96
|
+
reportReactPageFailure(runtime, error, context.requestContext);
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactRenderContext } from './render.js';
|
|
2
|
+
import type { ReactServerEntry } from './server-entry.js';
|
|
3
|
+
/** Recoverable React render error retained until the response shell can commit. */
|
|
4
|
+
export type PendingReactRecoverableError = {
|
|
5
|
+
/** Original recoverable render failure. */
|
|
6
|
+
readonly error: unknown;
|
|
7
|
+
/** React-provided metadata, when available. */
|
|
8
|
+
readonly errorInfo?: unknown;
|
|
9
|
+
};
|
|
10
|
+
type ReactRenderDiagnostics = {
|
|
11
|
+
readonly preservePreCommitShellError: (error: unknown) => unknown;
|
|
12
|
+
readonly reportRequestAbort: () => void;
|
|
13
|
+
readonly reportRecoverableError: (event: PendingReactRecoverableError) => void;
|
|
14
|
+
readonly reportRecoverableErrors: (events: readonly PendingReactRecoverableError[]) => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Creates request-local reporting helpers for one React server entry render.
|
|
18
|
+
*
|
|
19
|
+
* @param entry React server entry whose callbacks receive recoverable errors.
|
|
20
|
+
* @param requestContext Active request and response lifecycle context.
|
|
21
|
+
* @returns Helpers that classify pre-commit failures and report recoverable errors.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createReactRenderDiagnostics(entry: ReactServerEntry, requestContext: ReactRenderContext): ReactRenderDiagnostics;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=render-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-diagnostics.d.ts","sourceRoot":"","sources":["../src/render-diagnostics.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAgC,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExF,mFAAmF;AACnF,MAAM,MAAM,4BAA4B,GAAG;IACzC,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,CAAC,2BAA2B,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAClE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IACxC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,CAAC;IAC/E,QAAQ,CAAC,uBAAuB,EAAE,CAAC,MAAM,EAAE,SAAS,4BAA4B,EAAE,KAAK,IAAI,CAAC;CAC7F,CAAC;AAmBF;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,gBAAgB,EACvB,cAAc,EAAE,kBAAkB,GACjC,sBAAsB,CAkFxB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { RequestAbortedError } from '@fluojs/http/portable';
|
|
2
|
+
import { createReactSsrDiagnostic, markReactSsrDiagnostic, REACT_SSR_DIAGNOSTIC_CODES, REACT_SSR_DIAGNOSTIC_PHASES, ReactSsrDiagnosticError, readReactSsrDiagnosticHandler, reportReactSsrDiagnostic } from './diagnostics.js';
|
|
3
|
+
|
|
4
|
+
/** Recoverable React render error retained until the response shell can commit. */
|
|
5
|
+
|
|
6
|
+
function createRecoverableErrorContext(errorInfo, requestContext) {
|
|
7
|
+
return {
|
|
8
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.postShellRecoverableError,
|
|
9
|
+
...(errorInfo !== undefined ? {
|
|
10
|
+
errorInfo
|
|
11
|
+
} : {}),
|
|
12
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.postShellRecoverable,
|
|
13
|
+
request: requestContext.request,
|
|
14
|
+
...(requestContext.requestId !== undefined ? {
|
|
15
|
+
requestId: requestContext.requestId
|
|
16
|
+
} : {})
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function isDiagnosticMarkerKey(value) {
|
|
20
|
+
return typeof value === 'object' && value !== null || typeof value === 'function';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates request-local reporting helpers for one React server entry render.
|
|
25
|
+
*
|
|
26
|
+
* @param entry React server entry whose callbacks receive recoverable errors.
|
|
27
|
+
* @param requestContext Active request and response lifecycle context.
|
|
28
|
+
* @returns Helpers that classify pre-commit failures and report recoverable errors.
|
|
29
|
+
*/
|
|
30
|
+
export function createReactRenderDiagnostics(entry, requestContext) {
|
|
31
|
+
const reportRecoverableError = event => {
|
|
32
|
+
const recoverableContext = createRecoverableErrorContext(event.errorInfo, requestContext);
|
|
33
|
+
reportReactSsrDiagnostic(readReactSsrDiagnosticHandler(requestContext), createReactSsrDiagnostic({
|
|
34
|
+
code: recoverableContext.code,
|
|
35
|
+
error: event.error,
|
|
36
|
+
phase: recoverableContext.phase,
|
|
37
|
+
request: requestContext.request,
|
|
38
|
+
...(requestContext.requestId === undefined ? {} : {
|
|
39
|
+
requestId: requestContext.requestId
|
|
40
|
+
})
|
|
41
|
+
}));
|
|
42
|
+
const hook = entry.onRecoverableError;
|
|
43
|
+
if (!hook) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
hook(event.error, recoverableContext);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof Error) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
preservePreCommitShellError(error) {
|
|
56
|
+
if (error instanceof RequestAbortedError || error instanceof ReactSsrDiagnosticError || requestContext.response.committed) {
|
|
57
|
+
return error;
|
|
58
|
+
}
|
|
59
|
+
if (!isDiagnosticMarkerKey(error)) {
|
|
60
|
+
return new ReactSsrDiagnosticError('React SSR failed before the response shell committed.', {
|
|
61
|
+
cause: error,
|
|
62
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.preCommitShellFailure,
|
|
63
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.preCommitShell
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
markReactSsrDiagnostic(requestContext, error, {
|
|
67
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.preCommitShellFailure,
|
|
68
|
+
error,
|
|
69
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.preCommitShell
|
|
70
|
+
});
|
|
71
|
+
return error;
|
|
72
|
+
},
|
|
73
|
+
reportRequestAbort() {
|
|
74
|
+
if (requestContext.request.signal?.aborted !== true && requestContext.request.isAborted?.() !== true) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
reportReactSsrDiagnostic(readReactSsrDiagnosticHandler(requestContext), createReactSsrDiagnostic({
|
|
78
|
+
code: REACT_SSR_DIAGNOSTIC_CODES.requestAbort,
|
|
79
|
+
error: new RequestAbortedError(),
|
|
80
|
+
phase: REACT_SSR_DIAGNOSTIC_PHASES.requestAbort,
|
|
81
|
+
request: requestContext.request,
|
|
82
|
+
...(requestContext.requestId === undefined ? {} : {
|
|
83
|
+
requestId: requestContext.requestId
|
|
84
|
+
})
|
|
85
|
+
}));
|
|
86
|
+
},
|
|
87
|
+
reportRecoverableError,
|
|
88
|
+
reportRecoverableErrors(events) {
|
|
89
|
+
for (const event of events) {
|
|
90
|
+
reportRecoverableError(event);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { MetadataPropertyKey } from '@fluojs/core';
|
|
2
|
+
/** Class-or-method decorator shape used by React render policy declarations. */
|
|
3
|
+
export type ReactRenderPolicyDecorator = {
|
|
4
|
+
(value: Function, context: ClassDecoratorContext): void;
|
|
5
|
+
(value: Function, context: ClassMethodDecoratorContext): void;
|
|
6
|
+
(target: Function): void;
|
|
7
|
+
(target: object, propertyKey: MetadataPropertyKey, descriptor?: PropertyDescriptor): void;
|
|
8
|
+
};
|
|
9
|
+
/** Internal render policy record retained until bootstrap validation. */
|
|
10
|
+
export type ReactRenderPolicyRecord = {
|
|
11
|
+
readonly kind: 'layout' | 'page-metadata' | 'suspense-fallback';
|
|
12
|
+
readonly reference: unknown;
|
|
13
|
+
};
|
|
14
|
+
/** One class or method decoration site in a router inheritance chain. */
|
|
15
|
+
export type ReactRenderPolicySite = {
|
|
16
|
+
readonly kind: 'class';
|
|
17
|
+
readonly owner: Function;
|
|
18
|
+
readonly records: readonly ReactRenderPolicyRecord[];
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'method';
|
|
21
|
+
readonly owner: Function;
|
|
22
|
+
readonly propertyKey: MetadataPropertyKey;
|
|
23
|
+
readonly records: readonly ReactRenderPolicyRecord[];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Creates a render policy decorator that records one component reference at a class or method site.
|
|
27
|
+
*
|
|
28
|
+
* @param kind Render policy kind being recorded.
|
|
29
|
+
* @param reference Component reference retained for bootstrap validation and renderer consumption.
|
|
30
|
+
* @returns A standard/legacy-compatible class-or-method decorator.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createReactRenderPolicyDecorator(kind: ReactRenderPolicyRecord['kind'], reference: unknown): ReactRenderPolicyDecorator;
|
|
33
|
+
/**
|
|
34
|
+
* Collects own class and method policy sites across a router inheritance chain.
|
|
35
|
+
*
|
|
36
|
+
* @param routerToken Router constructor whose inherited policy declarations should be collected.
|
|
37
|
+
* @returns Class sites followed by method sites, each ordered base-to-derived.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getReactRenderPolicySites(routerToken: Function): readonly ReactRenderPolicySite[];
|
|
40
|
+
//# sourceMappingURL=render-policy-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-policy-metadata.d.ts","sourceRoot":"","sources":["../src/render-policy-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKxD,gFAAgF;AAChF,MAAM,MAAM,0BAA0B,GAAG;IACvC,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACxD,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC9D,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC3F,CAAC;AAEF,yEAAyE;AACzE,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,eAAe,GAAG,mBAAmB,CAAC;IAChE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,yEAAyE;AACzE,MAAM,MAAM,qBAAqB,GAC7B;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACtD,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACtD,CAAC;AAiGN;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,uBAAuB,CAAC,MAAM,CAAC,EACrC,SAAS,EAAE,OAAO,GACjB,0BAA0B,CAoC5B;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS,qBAAqB,EAAE,CAgCjG"}
|