@reckona/mreact-router 0.0.80 → 0.0.82

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server-action-inference.d.ts","sourceRoot":"","sources":["../src/server-action-inference.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uCACf,SAAQ,6BAA6B;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,OAAO,8BAA8B,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnF;AAED,eAAO,MAAM,8BAA8B,mDACO,CAAC;AAKnD,wBAAsB,mCAAmC,CAAC,OAAO,EAAE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,sCAAsC,CAAC;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IACV,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/C,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;CACxD,CAAC,CAqED;AAED,wBAAsB,iCAAiC,CAAC,OAAO,EAAE;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/C,UAAU,EAAE,uCAAuC,EAAE,CAAC;CACvD,CAAC,CAgED;AAujBD,wBAAgB,mDAAmD,IAAI,OAAO,CAE7E;AAED,wBAAgB,8CAA8C,IAAI,IAAI,CAGrE;AAsBD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAMV"}
1
+ {"version":3,"file":"server-action-inference.d.ts","sourceRoot":"","sources":["../src/server-action-inference.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uCACf,SAAQ,6BAA6B;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,OAAO,8BAA8B,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnF;AAED,eAAO,MAAM,8BAA8B,mDACO,CAAC;AAKnD,wBAAsB,mCAAmC,CAAC,OAAO,EAAE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,sCAAsC,CAAC;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IACV,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/C,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;CACxD,CAAC,CAqED;AAED,wBAAsB,iCAAiC,CAAC,OAAO,EAAE;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/C,UAAU,EAAE,uCAAuC,EAAE,CAAC;CACvD,CAAC,CA+ED;AAwlBD,wBAAgB,mDAAmD,IAAI,OAAO,CAE7E;AAED,wBAAgB,8CAA8C,IAAI,IAAI,CAGrE;AAsBD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAMV"}
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { dirname, relative, sep } from "node:path";
3
- import { collectFormActionExpressionReferences, hasModuleDirective, } from "@reckona/mreact-compiler";
3
+ import { analyzeBoundaryGraph, collectFormActionExpressionReferences, hasModuleDirective, } from "@reckona/mreact-compiler";
4
4
  let ts = undefined;
5
5
  let typescriptLoaded = false;
6
6
  export const dynamicFormActionInferenceCode = "MR_SERVER_ACTION_INFERENCE_DYNAMIC_FORM_ACTION";
@@ -83,6 +83,14 @@ export async function collectBuildInferredServerActions(options) {
83
83
  const diagnostics = [];
84
84
  const references = [];
85
85
  const sourceHash = formActionSourceHash(options.source);
86
+ const graphReferences = await collectBuildBoundaryGraphServerActions({
87
+ file: options.file,
88
+ files: options.files,
89
+ relativeRoutesDir: options.relativeRoutesDir,
90
+ resolveSourceImport: options.resolveSourceImport,
91
+ source: options.source,
92
+ sourceHash,
93
+ });
86
94
  for (const formReference of formReferences) {
87
95
  const expression = findExpressionAt(sourceFile, formReference);
88
96
  if (expression === undefined) {
@@ -109,6 +117,11 @@ export async function collectBuildInferredServerActions(options) {
109
117
  });
110
118
  continue;
111
119
  }
120
+ const graphReference = graphReferences.get(formActionOccurrenceKey(formReference));
121
+ if (graphReference !== undefined) {
122
+ references.push(graphReference);
123
+ continue;
124
+ }
112
125
  if (resolved.kind === "dynamic") {
113
126
  diagnostics.push({
114
127
  code: dynamicFormActionInferenceCode,
@@ -120,6 +133,29 @@ export async function collectBuildInferredServerActions(options) {
120
133
  }
121
134
  return { diagnostics, references };
122
135
  }
136
+ async function collectBuildBoundaryGraphServerActions(options) {
137
+ const graph = await analyzeBoundaryGraph({
138
+ entries: [{ file: options.file, kind: "route-page" }],
139
+ readModule: (file) => (file === options.file ? options.source : options.files[file]),
140
+ resolveModule: ({ importer, source }) => options.resolveSourceImport(importer, source),
141
+ });
142
+ const references = new Map();
143
+ for (const action of graph.serverActions) {
144
+ const reference = {
145
+ end: action.end,
146
+ exportName: action.exportName,
147
+ expression: action.expression,
148
+ expressionEnd: action.expressionEnd,
149
+ expressionStart: action.expressionStart,
150
+ inferred: action.inferred,
151
+ moduleId: moduleIdForBuildFile(action.moduleFile, options.relativeRoutesDir),
152
+ sourceHash: options.sourceHash,
153
+ start: action.start,
154
+ };
155
+ references.set(formActionOccurrenceKey(reference), reference);
156
+ }
157
+ return references;
158
+ }
123
159
  async function resolveRuntimeActionExpression(options) {
124
160
  const expression = unwrapExpression(options.expression);
125
161
  if (options.seen.has(expression)) {
@@ -1 +1 @@
1
- {"version":3,"file":"server-action-inference.js","sourceRoot":"","sources":["../src/server-action-inference.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { dirname, relative, sep } from \"node:path\";\nimport {\n collectFormActionExpressionReferences,\n hasModuleDirective,\n type FormActionExpressionReference,\n} from \"@reckona/mreact-compiler\";\nimport type * as Ts from \"typescript\";\n\nlet ts = undefined as unknown as typeof Ts;\nlet typescriptLoaded = false;\n\nexport interface InferredServerActionReference {\n exportName: string;\n inferred: boolean;\n moduleId: string;\n}\n\nexport interface InferredServerActionExpressionReference\n extends InferredServerActionReference {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n sourceHash: string;\n start: number;\n}\n\nexport interface ServerActionInferenceDiagnostic {\n code: typeof dynamicFormActionInferenceCode;\n filename: string;\n level: \"warn\";\n message: string;\n}\n\nexport interface RuntimeServerActionInferenceFileSystem {\n isUseServerFile(file: string): Promise<boolean>;\n resolveSourceFile(directory: string, source: string): Promise<string | undefined>;\n}\n\nexport const dynamicFormActionInferenceCode =\n \"MR_SERVER_ACTION_INFERENCE_DYNAMIC_FORM_ACTION\";\n\nconst dynamicFormActionInferenceMessage =\n \"mreact could not infer a single server action from this form action expression. Pass the action function directly or use an explicit escape hatch.\";\n\nexport async function collectRuntimeInferredServerActions(options: {\n appDir: string;\n code: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: Map<string, InferredServerActionReference>;\n}> {\n const formReferences = collectFormActionExpressionReferences({\n code: options.code,\n filename: options.pageFile,\n });\n\n if (formReferences.length === 0) {\n return { diagnostics: [], references: new Map() };\n }\n\n await loadTypeScript();\n const program = ts.createProgram({\n host: createRuntimeProgramHost({\n code: options.code,\n compilerOptions: defaultCompilerOptions(),\n pageFile: options.pageFile,\n }),\n options: {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n noEmit: true,\n target: ts.ScriptTarget.ES2022,\n },\n rootNames: [options.pageFile],\n });\n const checker = program.getTypeChecker();\n const sourceFile = program.getSourceFile(options.pageFile);\n\n if (sourceFile === undefined) {\n return { diagnostics: [], references: new Map() };\n }\n\n const diagnostics: ServerActionInferenceDiagnostic[] = [];\n const references = new Map<string, InferredServerActionReference>();\n\n for (const formReference of formReferences) {\n const expression = findExpressionAt(sourceFile, formReference);\n\n if (expression === undefined) {\n continue;\n }\n\n const resolved = await resolveRuntimeActionExpression({\n appDir: options.appDir,\n checker,\n expression,\n fileSystem: options.fileSystem,\n pageFile: options.pageFile,\n seen: new Set(),\n });\n\n if (resolved.kind === \"resolved\") {\n references.set(formActionOccurrenceKey(formReference), resolved.reference);\n continue;\n }\n\n if (resolved.kind === \"dynamic\") {\n diagnostics.push({\n code: dynamicFormActionInferenceCode,\n filename: options.pageFile,\n level: \"warn\",\n message: dynamicFormActionInferenceMessage,\n });\n }\n }\n\n return { diagnostics, references };\n}\n\nexport async function collectBuildInferredServerActions(options: {\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n source: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: InferredServerActionExpressionReference[];\n}> {\n const formReferences = collectFormActionExpressionReferences({\n code: options.source,\n filename: options.file,\n });\n\n if (formReferences.length === 0) {\n return { diagnostics: [], references: [] };\n }\n\n await loadTypeScript();\n const program = createBuildProgram(options.file, options.files, options.source);\n const checker = program.getTypeChecker();\n const sourceFile = program.getSourceFile(options.file);\n\n if (sourceFile === undefined) {\n return { diagnostics: [], references: [] };\n }\n\n const diagnostics: ServerActionInferenceDiagnostic[] = [];\n const references: InferredServerActionExpressionReference[] = [];\n const sourceHash = formActionSourceHash(options.source);\n\n for (const formReference of formReferences) {\n const expression = findExpressionAt(sourceFile, formReference);\n\n if (expression === undefined) {\n continue;\n }\n\n const resolved = resolveBuildActionExpression({\n checker,\n expression,\n file: options.file,\n files: options.files,\n relativeRoutesDir: options.relativeRoutesDir,\n resolveSourceImport: options.resolveSourceImport,\n seen: new Set(),\n });\n\n if (resolved.kind === \"resolved\") {\n references.push({\n ...resolved.reference,\n end: formReference.end,\n expression: formReference.expression,\n expressionEnd: formReference.expressionEnd,\n expressionStart: formReference.expressionStart,\n sourceHash,\n start: formReference.start,\n });\n continue;\n }\n\n if (resolved.kind === \"dynamic\") {\n diagnostics.push({\n code: dynamicFormActionInferenceCode,\n filename: options.file,\n level: \"warn\",\n message: dynamicFormActionInferenceMessage,\n });\n }\n }\n\n return { diagnostics, references };\n}\n\ntype RuntimeResolveResult =\n | { kind: \"dynamic\" }\n | { kind: \"resolved\"; reference: InferredServerActionReference }\n | { kind: \"unresolved\" };\n\ntype BuildResolveResult =\n | { kind: \"dynamic\" }\n | { kind: \"resolved\"; reference: InferredServerActionReference }\n | { kind: \"unresolved\" };\n\nasync function resolveRuntimeActionExpression(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.Expression;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const expression = unwrapExpression(options.expression);\n\n if (options.seen.has(expression)) {\n return { kind: \"unresolved\" };\n }\n\n options.seen.add(expression);\n\n if (ts.isIdentifier(expression)) {\n return await resolveRuntimeIdentifier({ ...options, expression });\n }\n\n if (ts.isPropertyAccessExpression(expression)) {\n return await resolveRuntimePropertyAccess({ ...options, expression });\n }\n\n if (ts.isConditionalExpression(expression)) {\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimeIdentifier(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.Identifier;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const symbol = options.checker.getSymbolAtLocation(options.expression);\n\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return await referenceFromRuntimeImportSpecifier(options, declaration);\n }\n\n if (ts.isVariableDeclaration(declaration)) {\n if (declaration.initializer === undefined) {\n continue;\n }\n\n return await resolveRuntimeActionExpression({\n ...options,\n expression: declaration.initializer,\n });\n }\n }\n\n const aliased = aliasTargetSymbol(options.checker, symbol);\n\n if (aliased !== undefined) {\n const reference = await referenceFromRuntimeSymbolDeclaration(options, aliased);\n\n if (reference !== undefined) {\n return { kind: \"resolved\", reference };\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimePropertyAccess(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.PropertyAccessExpression;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const object = unwrapExpression(options.expression.expression);\n\n if (!ts.isIdentifier(object)) {\n return { kind: \"unresolved\" };\n }\n\n const symbol = options.checker.getSymbolAtLocation(object);\n\n for (const declaration of symbol?.declarations ?? []) {\n if (!ts.isVariableDeclaration(declaration) || declaration.initializer === undefined) {\n continue;\n }\n\n const initializer = unwrapExpression(declaration.initializer);\n\n if (!ts.isObjectLiteralExpression(initializer)) {\n continue;\n }\n\n const property = initializer.properties.find((candidate) =>\n objectLiteralPropertyName(candidate) === options.expression.name.text,\n );\n\n if (property === undefined) {\n continue;\n }\n\n if (ts.isShorthandPropertyAssignment(property)) {\n return await resolveRuntimeSymbol(\n options,\n options.checker.getShorthandAssignmentValueSymbol(property),\n );\n }\n\n if (ts.isPropertyAssignment(property)) {\n return await resolveRuntimeActionExpression({\n ...options,\n expression: property.initializer,\n });\n }\n\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimeSymbol(\n options: {\n appDir: string;\n checker: Ts.TypeChecker;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n symbol: Ts.Symbol | undefined,\n): Promise<RuntimeResolveResult> {\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return await referenceFromRuntimeImportSpecifier(options, declaration);\n }\n }\n\n const aliased = aliasTargetSymbol(options.checker, symbol);\n\n if (aliased === undefined) {\n return { kind: \"unresolved\" };\n }\n\n const reference = await referenceFromRuntimeSymbolDeclaration(options, aliased);\n\n return reference === undefined ? { kind: \"unresolved\" } : { kind: \"resolved\", reference };\n}\n\nasync function referenceFromRuntimeImportSpecifier(\n options: {\n appDir: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n declaration: Ts.ImportSpecifier,\n): Promise<RuntimeResolveResult> {\n const importDeclaration = declaration.parent.parent.parent;\n const source = importDeclaration.moduleSpecifier;\n\n if (!ts.isStringLiteral(source) || !source.text.startsWith(\".\")) {\n return { kind: \"unresolved\" };\n }\n\n const file = await options.fileSystem.resolveSourceFile(dirname(options.pageFile), source.text);\n\n if (file === undefined) {\n return { kind: \"unresolved\" };\n }\n\n return {\n kind: \"resolved\",\n reference: {\n exportName: declaration.propertyName?.text ?? declaration.name.text,\n inferred: !(await options.fileSystem.isUseServerFile(file)),\n moduleId: moduleIdForFile(options.appDir, file),\n },\n };\n}\n\nasync function referenceFromRuntimeSymbolDeclaration(\n options: {\n appDir: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n symbol: Ts.Symbol,\n): Promise<InferredServerActionReference | undefined> {\n const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];\n\n if (declaration === undefined) {\n return undefined;\n }\n\n const file = declaration.getSourceFile().fileName;\n\n if (file === options.pageFile || !isInsideAppDir(options.appDir, file)) {\n return undefined;\n }\n\n return {\n exportName: symbol.getName(),\n inferred: !(await options.fileSystem.isUseServerFile(file)),\n moduleId: moduleIdForFile(options.appDir, file),\n };\n}\n\nfunction resolveBuildActionExpression(options: {\n checker: Ts.TypeChecker;\n expression: Ts.Expression;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const expression = unwrapExpression(options.expression);\n\n if (options.seen.has(expression)) {\n return { kind: \"unresolved\" };\n }\n\n options.seen.add(expression);\n\n if (ts.isIdentifier(expression)) {\n return resolveBuildIdentifier({ ...options, expression });\n }\n\n if (ts.isPropertyAccessExpression(expression)) {\n return resolveBuildPropertyAccess({ ...options, expression });\n }\n\n if (ts.isConditionalExpression(expression)) {\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildIdentifier(options: {\n checker: Ts.TypeChecker;\n expression: Ts.Identifier;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const symbol = options.checker.getSymbolAtLocation(options.expression);\n\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return referenceFromBuildImportSpecifier(options, declaration);\n }\n\n if (ts.isVariableDeclaration(declaration)) {\n if (declaration.initializer === undefined) {\n continue;\n }\n\n return resolveBuildActionExpression({\n ...options,\n expression: declaration.initializer,\n });\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildPropertyAccess(options: {\n checker: Ts.TypeChecker;\n expression: Ts.PropertyAccessExpression;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const object = unwrapExpression(options.expression.expression);\n\n if (!ts.isIdentifier(object)) {\n return { kind: \"unresolved\" };\n }\n\n const symbol = options.checker.getSymbolAtLocation(object);\n\n for (const declaration of symbol?.declarations ?? []) {\n if (!ts.isVariableDeclaration(declaration) || declaration.initializer === undefined) {\n continue;\n }\n\n const initializer = unwrapExpression(declaration.initializer);\n\n if (!ts.isObjectLiteralExpression(initializer)) {\n continue;\n }\n\n const property = initializer.properties.find((candidate) =>\n objectLiteralPropertyName(candidate) === options.expression.name.text,\n );\n\n if (property === undefined) {\n continue;\n }\n\n if (ts.isShorthandPropertyAssignment(property)) {\n return resolveBuildSymbol(options, options.checker.getShorthandAssignmentValueSymbol(property));\n }\n\n if (ts.isPropertyAssignment(property)) {\n return resolveBuildActionExpression({\n ...options,\n expression: property.initializer,\n });\n }\n\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildSymbol(\n options: {\n checker: Ts.TypeChecker;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n },\n symbol: Ts.Symbol | undefined,\n): BuildResolveResult {\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return referenceFromBuildImportSpecifier(options, declaration);\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction referenceFromBuildImportSpecifier(\n options: {\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n },\n declaration: Ts.ImportSpecifier,\n): BuildResolveResult {\n const importDeclaration = declaration.parent.parent.parent;\n const source = importDeclaration.moduleSpecifier;\n\n if (!ts.isStringLiteral(source) || !source.text.startsWith(\".\")) {\n return { kind: \"unresolved\" };\n }\n\n const localFile = options.resolveSourceImport(options.file, source.text);\n\n if (localFile === undefined) {\n return { kind: \"unresolved\" };\n }\n\n const sourceCode = options.files[localFile];\n\n if (sourceCode === undefined) {\n return { kind: \"unresolved\" };\n }\n\n return {\n kind: \"resolved\",\n reference: {\n exportName: declaration.propertyName?.text ?? declaration.name.text,\n inferred: !hasUseServerDirectiveInSource({ code: sourceCode, filename: localFile }),\n moduleId: moduleIdForBuildFile(localFile, options.relativeRoutesDir),\n },\n };\n}\n\nfunction aliasTargetSymbol(checker: Ts.TypeChecker, symbol: Ts.Symbol): Ts.Symbol | undefined {\n if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {\n return undefined;\n }\n\n return checker.getAliasedSymbol(symbol);\n}\n\nfunction findExpressionAt(\n sourceFile: Ts.SourceFile,\n reference: FormActionExpressionReference,\n): Ts.Expression | undefined {\n let found: Ts.Expression | undefined;\n\n const visit = (node: Ts.Node): void => {\n if (found !== undefined) {\n return;\n }\n\n if (\n ts.isExpression(node) &&\n node.getStart(sourceFile) === reference.expressionStart &&\n node.getEnd() === reference.expressionEnd\n ) {\n found = node;\n return;\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return found;\n}\n\nfunction objectLiteralPropertyName(property: Ts.ObjectLiteralElementLike): string | undefined {\n if (\n ts.isShorthandPropertyAssignment(property) ||\n ts.isPropertyAssignment(property) ||\n ts.isMethodDeclaration(property)\n ) {\n return propertyNameText(property.name);\n }\n\n return undefined;\n}\n\nfunction propertyNameText(name: Ts.PropertyName): string | undefined {\n if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {\n return name.text;\n }\n\n return undefined;\n}\n\nfunction unwrapExpression(expression: Ts.Expression): Ts.Expression {\n let current = expression;\n\n while (\n ts.isParenthesizedExpression(current) ||\n ts.isAsExpression(current) ||\n ts.isSatisfiesExpression(current) ||\n ts.isTypeAssertionExpression(current) ||\n ts.isNonNullExpression(current)\n ) {\n current = current.expression;\n }\n\n return current;\n}\n\nfunction moduleIdForFile(appDir: string, file: string): string {\n return relative(appDir, file).split(sep).join(\"/\");\n}\n\nfunction isInsideAppDir(appDir: string, file: string): boolean {\n const relativePath = relative(appDir, file);\n\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !relativePath.startsWith(\"/\"));\n}\n\nfunction moduleIdForBuildFile(file: string, relativeRoutesDir: string): string {\n return relativeRoutesDir === \"\" ? file : file.slice(relativeRoutesDir.length + 1);\n}\n\nfunction createBuildProgram(\n file: string,\n files: Record<string, string>,\n source: string,\n): Ts.Program {\n const compilerOptions = defaultCompilerOptions();\n const defaultHost = ts.createCompilerHost(compilerOptions, true);\n const host: Ts.CompilerHost = {\n ...defaultHost,\n fileExists: (filename) => filename === file || files[filename] !== undefined,\n getSourceFile: (filename, languageVersion) => {\n const fileSource = filename === file ? source : files[filename];\n\n if (fileSource !== undefined) {\n return ts.createSourceFile(filename, fileSource, languageVersion, true);\n }\n\n return defaultHost.getSourceFile(filename, languageVersion);\n },\n readFile: (filename) => (filename === file ? source : files[filename]),\n };\n\n return ts.createProgram({\n host,\n options: compilerOptions,\n rootNames: [file],\n });\n}\n\nfunction createRuntimeProgramHost(options: {\n code: string;\n compilerOptions: Ts.CompilerOptions;\n pageFile: string;\n}): Ts.CompilerHost {\n const defaultHost = ts.createCompilerHost(options.compilerOptions, true);\n\n return {\n ...defaultHost,\n fileExists: (filename) => filename === options.pageFile || defaultHost.fileExists(filename),\n getSourceFile: (filename, languageVersion) => {\n if (filename === options.pageFile) {\n return ts.createSourceFile(filename, options.code, languageVersion, true);\n }\n\n return defaultHost.getSourceFile(filename, languageVersion);\n },\n readFile: (filename) =>\n filename === options.pageFile ? options.code : defaultHost.readFile(filename),\n };\n}\n\nfunction defaultCompilerOptions(): Ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n noEmit: true,\n target: ts.ScriptTarget.ES2022,\n };\n}\n\nasync function loadTypeScript(): Promise<void> {\n if (typescriptLoaded) {\n return;\n }\n\n ts = await import(\"typescript\");\n typescriptLoaded = true;\n}\n\nexport function __readServerActionInferenceTypeScriptLoadedForTests(): boolean {\n return typescriptLoaded;\n}\n\nexport function __resetServerActionInferenceTypeScriptForTests(): void {\n ts = undefined as unknown as typeof Ts;\n typescriptLoaded = false;\n}\n\nfunction formActionOccurrenceKey(reference: {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n start: number;\n}): string {\n return [\n reference.start,\n reference.end,\n reference.expressionStart,\n reference.expressionEnd,\n reference.expression,\n ].join(\":\");\n}\n\nfunction formActionSourceHash(code: string): string {\n return createHash(\"sha256\").update(code).digest(\"base64url\");\n}\n\nexport function hasUseServerDirectiveInSource(input: {\n code: string;\n filename: string;\n}): boolean {\n return hasModuleDirective({\n code: input.code,\n directive: \"use server\",\n filename: input.filename,\n });\n}\n"]}
1
+ {"version":3,"file":"server-action-inference.js","sourceRoot":"","sources":["../src/server-action-inference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,oBAAoB,EACpB,qCAAqC,EACrC,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAGlC,IAAI,EAAE,GAAG,SAAiC,CAAC;AAC3C,IAAI,gBAAgB,GAAG,KAAK,CAAC;AA8B7B,MAAM,CAAC,MAAM,8BAA8B,GACzC,gDAAgD,CAAC;AAEnD,MAAM,iCAAiC,GACrC,oJAAoJ,CAAC;AAEvJ,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,OAKzD;IAIC,MAAM,cAAc,GAAG,qCAAqC,CAAC;QAC3D,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACpD,CAAC;IAED,MAAM,cAAc,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC;QAC/B,IAAI,EAAE,wBAAwB,CAAC;YAC7B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,eAAe,EAAE,sBAAsB,EAAE;YACzC,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC;QACF,OAAO,EAAE;YACP,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;YACxB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ;YAC9B,gBAAgB,EAAE,EAAE,CAAC,oBAAoB,CAAC,QAAQ;YAClD,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;SAC/B;QACD,SAAS,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;KAC9B,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE3D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACpD,CAAC;IAED,MAAM,WAAW,GAAsC,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEpE,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE/D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,8BAA8B,CAAC;YACpD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO;YACP,UAAU;YACV,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,IAAI,GAAG,EAAE;SAChB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACjC,UAAU,CAAC,GAAG,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC3E,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,8BAA8B;gBACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,iCAAiC;aAC3C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,OAMvD;IAIC,MAAM,cAAc,GAAG,qCAAqC,CAAC;QAC3D,IAAI,EAAE,OAAO,CAAC,MAAM;QACpB,QAAQ,EAAE,OAAO,CAAC,IAAI;KACvB,CAAC,CAAC;IAEH,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,cAAc,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,WAAW,GAAsC,EAAE,CAAC;IAC1D,MAAM,UAAU,GAA8C,EAAE,CAAC;IACjE,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,MAAM,sCAAsC,CAAC;QACnE,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU;KACX,CAAC,CAAC;IAEH,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE/D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,4BAA4B,CAAC;YAC5C,OAAO;YACP,UAAU;YACV,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,IAAI,EAAE,IAAI,GAAG,EAAE;SAChB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC;gBACd,GAAG,QAAQ,CAAC,SAAS;gBACrB,GAAG,EAAE,aAAa,CAAC,GAAG;gBACtB,UAAU,EAAE,aAAa,CAAC,UAAU;gBACpC,aAAa,EAAE,aAAa,CAAC,aAAa;gBAC1C,eAAe,EAAE,aAAa,CAAC,eAAe;gBAC9C,UAAU;gBACV,KAAK,EAAE,aAAa,CAAC,KAAK;aAC3B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAC;QAEnF,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAChC,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,8BAA8B;gBACpC,QAAQ,EAAE,OAAO,CAAC,IAAI;gBACtB,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,iCAAiC;aAC3C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,sCAAsC,CAAC,OAOrD;IACC,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC;QACvC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QACrD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpF,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC;KACvF,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmD,CAAC;IAE9E,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG;YAChB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC;YAC5E,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC;QACF,UAAU,CAAC,GAAG,CAAC,uBAAuB,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAYD,KAAK,UAAU,8BAA8B,CAAC,OAO7C;IACC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAExD,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7B,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,wBAAwB,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,EAAE,CAAC,0BAA0B,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,OAAO,MAAM,4BAA4B,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,OAOvC;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,MAAM,mCAAmC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC1C,SAAS;YACX,CAAC;YAED,OAAO,MAAM,8BAA8B,CAAC;gBAC1C,GAAG,OAAO;gBACV,UAAU,EAAE,WAAW,CAAC,WAAW;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE3D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,MAAM,qCAAqC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEhF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,OAO3C;IACC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAE/D,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE3D,KAAK,MAAM,WAAW,IAAI,MAAM,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpF,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAE9D,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CACzD,yBAAyB,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CACtE,CAAC;QAEF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,IAAI,EAAE,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/C,OAAO,MAAM,oBAAoB,CAC/B,OAAO,EACP,OAAO,CAAC,OAAO,CAAC,iCAAiC,CAAC,QAAQ,CAAC,CAC5D,CAAC;QACJ,CAAC;QAED,IAAI,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,OAAO,MAAM,8BAA8B,CAAC;gBAC1C,GAAG,OAAO;gBACV,UAAU,EAAE,QAAQ,CAAC,WAAW;aACjC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAKC,EACD,MAA6B;IAE7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,MAAM,mCAAmC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE3D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,qCAAqC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhF,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAC5F,CAAC;AAED,KAAK,UAAU,mCAAmC,CAChD,OAIC,EACD,WAA+B;IAE/B,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3D,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAEjD,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhG,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE;YACT,UAAU,EAAE,WAAW,CAAC,YAAY,EAAE,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI;YACnE,QAAQ,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC3D,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;SAChD;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qCAAqC,CAClD,OAIC,EACD,MAAiB;IAEjB,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAExE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC;IAElD,IAAI,IAAI,KAAK,OAAO,CAAC,QAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE;QAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC3D,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,OAQrC;IACC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAExD,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7B,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,sBAAsB,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,EAAE,CAAC,0BAA0B,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,OAAO,0BAA0B,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,sBAAsB,CAAC,OAQ/B;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,iCAAiC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC1C,SAAS;YACX,CAAC;YAED,OAAO,4BAA4B,CAAC;gBAClC,GAAG,OAAO;gBACV,UAAU,EAAE,WAAW,CAAC,WAAW;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,0BAA0B,CAAC,OAQnC;IACC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAE/D,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE3D,KAAK,MAAM,WAAW,IAAI,MAAM,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpF,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAE9D,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CACzD,yBAAyB,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CACtE,CAAC;QAEF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,IAAI,EAAE,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/C,OAAO,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,iCAAiC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClG,CAAC;QAED,IAAI,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,OAAO,4BAA4B,CAAC;gBAClC,GAAG,OAAO;gBACV,UAAU,EAAE,QAAQ,CAAC,WAAW;aACjC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,kBAAkB,CACzB,OAMC,EACD,MAA6B;IAE7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,iCAAiC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,iCAAiC,CACxC,OAKC,EACD,WAA+B;IAE/B,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3D,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,CAAC;IAEjD,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEzE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE;YACT,UAAU,EAAE,WAAW,CAAC,YAAY,EAAE,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI;YACnE,QAAQ,EAAE,CAAC,6BAA6B,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;YACnF,QAAQ,EAAE,oBAAoB,CAAC,SAAS,EAAE,OAAO,CAAC,iBAAiB,CAAC;SACrE;KACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAuB,EAAE,MAAiB;IACnE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,gBAAgB,CACvB,UAAyB,EACzB,SAAwC;IAExC,IAAI,KAAgC,CAAC;IAErC,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IACE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,eAAe;YACvD,IAAI,CAAC,MAAM,EAAE,KAAK,SAAS,CAAC,aAAa,EACzC,CAAC;YACD,KAAK,GAAG,IAAI,CAAC;YACb,OAAO;QACT,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,yBAAyB,CAAC,QAAqC;IACtE,IACE,EAAE,CAAC,6BAA6B,CAAC,QAAQ,CAAC;QAC1C,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;QACjC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAChC,CAAC;QACD,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAqB;IAC7C,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QACnF,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAyB;IACjD,IAAI,OAAO,GAAG,UAAU,CAAC;IAEzB,OACE,EAAE,CAAC,yBAAyB,CAAC,OAAO,CAAC;QACrC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC;QAC1B,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC;QACjC,EAAE,CAAC,yBAAyB,CAAC,OAAO,CAAC;QACrC,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAC/B,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,MAAc,EAAE,IAAY;IACnD,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,IAAY;IAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE5C,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,iBAAyB;IACnE,OAAO,iBAAiB,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAY,EACZ,KAA6B,EAC7B,MAAc;IAEd,MAAM,eAAe,GAAG,sBAAsB,EAAE,CAAC;IACjD,MAAM,WAAW,GAAG,EAAE,CAAC,kBAAkB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,IAAI,GAAoB;QAC5B,GAAG,WAAW;QACd,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,SAAS;QAC5E,aAAa,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE;YAC3C,MAAM,UAAU,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEhE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;YAC1E,CAAC;YAED,OAAO,WAAW,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC9D,CAAC;QACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;KACvE,CAAC;IAEF,OAAO,EAAE,CAAC,aAAa,CAAC;QACtB,IAAI;QACJ,OAAO,EAAE,eAAe;QACxB,SAAS,EAAE,CAAC,IAAI,CAAC;KAClB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,wBAAwB,CAAC,OAIjC;IACC,MAAM,WAAW,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAEzE,OAAO;QACL,GAAG,WAAW;QACd,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC3F,aAAa,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE;YAC3C,IAAI,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAClC,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;YAC5E,CAAC;YAED,OAAO,WAAW,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC9D,CAAC;QACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CACrB,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;KAChF,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB;IAC7B,OAAO;QACL,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;QACxB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ;QAC9B,gBAAgB,EAAE,EAAE,CAAC,oBAAoB,CAAC,QAAQ;QAClD,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;KAC/B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAChC,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mDAAmD;IACjE,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,8CAA8C;IAC5D,EAAE,GAAG,SAAiC,CAAC;IACvC,gBAAgB,GAAG,KAAK,CAAC;AAC3B,CAAC;AAED,SAAS,uBAAuB,CAAC,SAMhC;IACC,OAAO;QACL,SAAS,CAAC,KAAK;QACf,SAAS,CAAC,GAAG;QACb,SAAS,CAAC,eAAe;QACzB,SAAS,CAAC,aAAa;QACvB,SAAS,CAAC,UAAU;KACrB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAG7C;IACC,OAAO,kBAAkB,CAAC;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,YAAY;QACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { dirname, relative, sep } from \"node:path\";\nimport {\n analyzeBoundaryGraph,\n collectFormActionExpressionReferences,\n hasModuleDirective,\n type FormActionExpressionReference,\n} from \"@reckona/mreact-compiler\";\nimport type * as Ts from \"typescript\";\n\nlet ts = undefined as unknown as typeof Ts;\nlet typescriptLoaded = false;\n\nexport interface InferredServerActionReference {\n exportName: string;\n inferred: boolean;\n moduleId: string;\n}\n\nexport interface InferredServerActionExpressionReference\n extends InferredServerActionReference {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n sourceHash: string;\n start: number;\n}\n\nexport interface ServerActionInferenceDiagnostic {\n code: typeof dynamicFormActionInferenceCode;\n filename: string;\n level: \"warn\";\n message: string;\n}\n\nexport interface RuntimeServerActionInferenceFileSystem {\n isUseServerFile(file: string): Promise<boolean>;\n resolveSourceFile(directory: string, source: string): Promise<string | undefined>;\n}\n\nexport const dynamicFormActionInferenceCode =\n \"MR_SERVER_ACTION_INFERENCE_DYNAMIC_FORM_ACTION\";\n\nconst dynamicFormActionInferenceMessage =\n \"mreact could not infer a single server action from this form action expression. Pass the action function directly or use an explicit escape hatch.\";\n\nexport async function collectRuntimeInferredServerActions(options: {\n appDir: string;\n code: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: Map<string, InferredServerActionReference>;\n}> {\n const formReferences = collectFormActionExpressionReferences({\n code: options.code,\n filename: options.pageFile,\n });\n\n if (formReferences.length === 0) {\n return { diagnostics: [], references: new Map() };\n }\n\n await loadTypeScript();\n const program = ts.createProgram({\n host: createRuntimeProgramHost({\n code: options.code,\n compilerOptions: defaultCompilerOptions(),\n pageFile: options.pageFile,\n }),\n options: {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n noEmit: true,\n target: ts.ScriptTarget.ES2022,\n },\n rootNames: [options.pageFile],\n });\n const checker = program.getTypeChecker();\n const sourceFile = program.getSourceFile(options.pageFile);\n\n if (sourceFile === undefined) {\n return { diagnostics: [], references: new Map() };\n }\n\n const diagnostics: ServerActionInferenceDiagnostic[] = [];\n const references = new Map<string, InferredServerActionReference>();\n\n for (const formReference of formReferences) {\n const expression = findExpressionAt(sourceFile, formReference);\n\n if (expression === undefined) {\n continue;\n }\n\n const resolved = await resolveRuntimeActionExpression({\n appDir: options.appDir,\n checker,\n expression,\n fileSystem: options.fileSystem,\n pageFile: options.pageFile,\n seen: new Set(),\n });\n\n if (resolved.kind === \"resolved\") {\n references.set(formActionOccurrenceKey(formReference), resolved.reference);\n continue;\n }\n\n if (resolved.kind === \"dynamic\") {\n diagnostics.push({\n code: dynamicFormActionInferenceCode,\n filename: options.pageFile,\n level: \"warn\",\n message: dynamicFormActionInferenceMessage,\n });\n }\n }\n\n return { diagnostics, references };\n}\n\nexport async function collectBuildInferredServerActions(options: {\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n source: string;\n}): Promise<{\n diagnostics: ServerActionInferenceDiagnostic[];\n references: InferredServerActionExpressionReference[];\n}> {\n const formReferences = collectFormActionExpressionReferences({\n code: options.source,\n filename: options.file,\n });\n\n if (formReferences.length === 0) {\n return { diagnostics: [], references: [] };\n }\n\n await loadTypeScript();\n const program = createBuildProgram(options.file, options.files, options.source);\n const checker = program.getTypeChecker();\n const sourceFile = program.getSourceFile(options.file);\n\n if (sourceFile === undefined) {\n return { diagnostics: [], references: [] };\n }\n\n const diagnostics: ServerActionInferenceDiagnostic[] = [];\n const references: InferredServerActionExpressionReference[] = [];\n const sourceHash = formActionSourceHash(options.source);\n const graphReferences = await collectBuildBoundaryGraphServerActions({\n file: options.file,\n files: options.files,\n relativeRoutesDir: options.relativeRoutesDir,\n resolveSourceImport: options.resolveSourceImport,\n source: options.source,\n sourceHash,\n });\n\n for (const formReference of formReferences) {\n const expression = findExpressionAt(sourceFile, formReference);\n\n if (expression === undefined) {\n continue;\n }\n\n const resolved = resolveBuildActionExpression({\n checker,\n expression,\n file: options.file,\n files: options.files,\n relativeRoutesDir: options.relativeRoutesDir,\n resolveSourceImport: options.resolveSourceImport,\n seen: new Set(),\n });\n\n if (resolved.kind === \"resolved\") {\n references.push({\n ...resolved.reference,\n end: formReference.end,\n expression: formReference.expression,\n expressionEnd: formReference.expressionEnd,\n expressionStart: formReference.expressionStart,\n sourceHash,\n start: formReference.start,\n });\n continue;\n }\n\n const graphReference = graphReferences.get(formActionOccurrenceKey(formReference));\n\n if (graphReference !== undefined) {\n references.push(graphReference);\n continue;\n }\n\n if (resolved.kind === \"dynamic\") {\n diagnostics.push({\n code: dynamicFormActionInferenceCode,\n filename: options.file,\n level: \"warn\",\n message: dynamicFormActionInferenceMessage,\n });\n }\n }\n\n return { diagnostics, references };\n}\n\nasync function collectBuildBoundaryGraphServerActions(options: {\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n source: string;\n sourceHash: string;\n}): Promise<Map<string, InferredServerActionExpressionReference>> {\n const graph = await analyzeBoundaryGraph({\n entries: [{ file: options.file, kind: \"route-page\" }],\n readModule: (file) => (file === options.file ? options.source : options.files[file]),\n resolveModule: ({ importer, source }) => options.resolveSourceImport(importer, source),\n });\n const references = new Map<string, InferredServerActionExpressionReference>();\n\n for (const action of graph.serverActions) {\n const reference = {\n end: action.end,\n exportName: action.exportName,\n expression: action.expression,\n expressionEnd: action.expressionEnd,\n expressionStart: action.expressionStart,\n inferred: action.inferred,\n moduleId: moduleIdForBuildFile(action.moduleFile, options.relativeRoutesDir),\n sourceHash: options.sourceHash,\n start: action.start,\n };\n references.set(formActionOccurrenceKey(reference), reference);\n }\n\n return references;\n}\n\ntype RuntimeResolveResult =\n | { kind: \"dynamic\" }\n | { kind: \"resolved\"; reference: InferredServerActionReference }\n | { kind: \"unresolved\" };\n\ntype BuildResolveResult =\n | { kind: \"dynamic\" }\n | { kind: \"resolved\"; reference: InferredServerActionReference }\n | { kind: \"unresolved\" };\n\nasync function resolveRuntimeActionExpression(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.Expression;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const expression = unwrapExpression(options.expression);\n\n if (options.seen.has(expression)) {\n return { kind: \"unresolved\" };\n }\n\n options.seen.add(expression);\n\n if (ts.isIdentifier(expression)) {\n return await resolveRuntimeIdentifier({ ...options, expression });\n }\n\n if (ts.isPropertyAccessExpression(expression)) {\n return await resolveRuntimePropertyAccess({ ...options, expression });\n }\n\n if (ts.isConditionalExpression(expression)) {\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimeIdentifier(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.Identifier;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const symbol = options.checker.getSymbolAtLocation(options.expression);\n\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return await referenceFromRuntimeImportSpecifier(options, declaration);\n }\n\n if (ts.isVariableDeclaration(declaration)) {\n if (declaration.initializer === undefined) {\n continue;\n }\n\n return await resolveRuntimeActionExpression({\n ...options,\n expression: declaration.initializer,\n });\n }\n }\n\n const aliased = aliasTargetSymbol(options.checker, symbol);\n\n if (aliased !== undefined) {\n const reference = await referenceFromRuntimeSymbolDeclaration(options, aliased);\n\n if (reference !== undefined) {\n return { kind: \"resolved\", reference };\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimePropertyAccess(options: {\n appDir: string;\n checker: Ts.TypeChecker;\n expression: Ts.PropertyAccessExpression;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n seen: Set<Ts.Node>;\n}): Promise<RuntimeResolveResult> {\n const object = unwrapExpression(options.expression.expression);\n\n if (!ts.isIdentifier(object)) {\n return { kind: \"unresolved\" };\n }\n\n const symbol = options.checker.getSymbolAtLocation(object);\n\n for (const declaration of symbol?.declarations ?? []) {\n if (!ts.isVariableDeclaration(declaration) || declaration.initializer === undefined) {\n continue;\n }\n\n const initializer = unwrapExpression(declaration.initializer);\n\n if (!ts.isObjectLiteralExpression(initializer)) {\n continue;\n }\n\n const property = initializer.properties.find((candidate) =>\n objectLiteralPropertyName(candidate) === options.expression.name.text,\n );\n\n if (property === undefined) {\n continue;\n }\n\n if (ts.isShorthandPropertyAssignment(property)) {\n return await resolveRuntimeSymbol(\n options,\n options.checker.getShorthandAssignmentValueSymbol(property),\n );\n }\n\n if (ts.isPropertyAssignment(property)) {\n return await resolveRuntimeActionExpression({\n ...options,\n expression: property.initializer,\n });\n }\n\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nasync function resolveRuntimeSymbol(\n options: {\n appDir: string;\n checker: Ts.TypeChecker;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n symbol: Ts.Symbol | undefined,\n): Promise<RuntimeResolveResult> {\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return await referenceFromRuntimeImportSpecifier(options, declaration);\n }\n }\n\n const aliased = aliasTargetSymbol(options.checker, symbol);\n\n if (aliased === undefined) {\n return { kind: \"unresolved\" };\n }\n\n const reference = await referenceFromRuntimeSymbolDeclaration(options, aliased);\n\n return reference === undefined ? { kind: \"unresolved\" } : { kind: \"resolved\", reference };\n}\n\nasync function referenceFromRuntimeImportSpecifier(\n options: {\n appDir: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n declaration: Ts.ImportSpecifier,\n): Promise<RuntimeResolveResult> {\n const importDeclaration = declaration.parent.parent.parent;\n const source = importDeclaration.moduleSpecifier;\n\n if (!ts.isStringLiteral(source) || !source.text.startsWith(\".\")) {\n return { kind: \"unresolved\" };\n }\n\n const file = await options.fileSystem.resolveSourceFile(dirname(options.pageFile), source.text);\n\n if (file === undefined) {\n return { kind: \"unresolved\" };\n }\n\n return {\n kind: \"resolved\",\n reference: {\n exportName: declaration.propertyName?.text ?? declaration.name.text,\n inferred: !(await options.fileSystem.isUseServerFile(file)),\n moduleId: moduleIdForFile(options.appDir, file),\n },\n };\n}\n\nasync function referenceFromRuntimeSymbolDeclaration(\n options: {\n appDir: string;\n fileSystem: RuntimeServerActionInferenceFileSystem;\n pageFile: string;\n },\n symbol: Ts.Symbol,\n): Promise<InferredServerActionReference | undefined> {\n const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];\n\n if (declaration === undefined) {\n return undefined;\n }\n\n const file = declaration.getSourceFile().fileName;\n\n if (file === options.pageFile || !isInsideAppDir(options.appDir, file)) {\n return undefined;\n }\n\n return {\n exportName: symbol.getName(),\n inferred: !(await options.fileSystem.isUseServerFile(file)),\n moduleId: moduleIdForFile(options.appDir, file),\n };\n}\n\nfunction resolveBuildActionExpression(options: {\n checker: Ts.TypeChecker;\n expression: Ts.Expression;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const expression = unwrapExpression(options.expression);\n\n if (options.seen.has(expression)) {\n return { kind: \"unresolved\" };\n }\n\n options.seen.add(expression);\n\n if (ts.isIdentifier(expression)) {\n return resolveBuildIdentifier({ ...options, expression });\n }\n\n if (ts.isPropertyAccessExpression(expression)) {\n return resolveBuildPropertyAccess({ ...options, expression });\n }\n\n if (ts.isConditionalExpression(expression)) {\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildIdentifier(options: {\n checker: Ts.TypeChecker;\n expression: Ts.Identifier;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const symbol = options.checker.getSymbolAtLocation(options.expression);\n\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return referenceFromBuildImportSpecifier(options, declaration);\n }\n\n if (ts.isVariableDeclaration(declaration)) {\n if (declaration.initializer === undefined) {\n continue;\n }\n\n return resolveBuildActionExpression({\n ...options,\n expression: declaration.initializer,\n });\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildPropertyAccess(options: {\n checker: Ts.TypeChecker;\n expression: Ts.PropertyAccessExpression;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n seen: Set<Ts.Node>;\n}): BuildResolveResult {\n const object = unwrapExpression(options.expression.expression);\n\n if (!ts.isIdentifier(object)) {\n return { kind: \"unresolved\" };\n }\n\n const symbol = options.checker.getSymbolAtLocation(object);\n\n for (const declaration of symbol?.declarations ?? []) {\n if (!ts.isVariableDeclaration(declaration) || declaration.initializer === undefined) {\n continue;\n }\n\n const initializer = unwrapExpression(declaration.initializer);\n\n if (!ts.isObjectLiteralExpression(initializer)) {\n continue;\n }\n\n const property = initializer.properties.find((candidate) =>\n objectLiteralPropertyName(candidate) === options.expression.name.text,\n );\n\n if (property === undefined) {\n continue;\n }\n\n if (ts.isShorthandPropertyAssignment(property)) {\n return resolveBuildSymbol(options, options.checker.getShorthandAssignmentValueSymbol(property));\n }\n\n if (ts.isPropertyAssignment(property)) {\n return resolveBuildActionExpression({\n ...options,\n expression: property.initializer,\n });\n }\n\n return { kind: \"dynamic\" };\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction resolveBuildSymbol(\n options: {\n checker: Ts.TypeChecker;\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n },\n symbol: Ts.Symbol | undefined,\n): BuildResolveResult {\n if (symbol === undefined) {\n return { kind: \"unresolved\" };\n }\n\n for (const declaration of symbol.declarations ?? []) {\n if (ts.isImportSpecifier(declaration)) {\n return referenceFromBuildImportSpecifier(options, declaration);\n }\n }\n\n return { kind: \"unresolved\" };\n}\n\nfunction referenceFromBuildImportSpecifier(\n options: {\n file: string;\n files: Record<string, string>;\n relativeRoutesDir: string;\n resolveSourceImport: (importer: string, source: string) => string | undefined;\n },\n declaration: Ts.ImportSpecifier,\n): BuildResolveResult {\n const importDeclaration = declaration.parent.parent.parent;\n const source = importDeclaration.moduleSpecifier;\n\n if (!ts.isStringLiteral(source) || !source.text.startsWith(\".\")) {\n return { kind: \"unresolved\" };\n }\n\n const localFile = options.resolveSourceImport(options.file, source.text);\n\n if (localFile === undefined) {\n return { kind: \"unresolved\" };\n }\n\n const sourceCode = options.files[localFile];\n\n if (sourceCode === undefined) {\n return { kind: \"unresolved\" };\n }\n\n return {\n kind: \"resolved\",\n reference: {\n exportName: declaration.propertyName?.text ?? declaration.name.text,\n inferred: !hasUseServerDirectiveInSource({ code: sourceCode, filename: localFile }),\n moduleId: moduleIdForBuildFile(localFile, options.relativeRoutesDir),\n },\n };\n}\n\nfunction aliasTargetSymbol(checker: Ts.TypeChecker, symbol: Ts.Symbol): Ts.Symbol | undefined {\n if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {\n return undefined;\n }\n\n return checker.getAliasedSymbol(symbol);\n}\n\nfunction findExpressionAt(\n sourceFile: Ts.SourceFile,\n reference: FormActionExpressionReference,\n): Ts.Expression | undefined {\n let found: Ts.Expression | undefined;\n\n const visit = (node: Ts.Node): void => {\n if (found !== undefined) {\n return;\n }\n\n if (\n ts.isExpression(node) &&\n node.getStart(sourceFile) === reference.expressionStart &&\n node.getEnd() === reference.expressionEnd\n ) {\n found = node;\n return;\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return found;\n}\n\nfunction objectLiteralPropertyName(property: Ts.ObjectLiteralElementLike): string | undefined {\n if (\n ts.isShorthandPropertyAssignment(property) ||\n ts.isPropertyAssignment(property) ||\n ts.isMethodDeclaration(property)\n ) {\n return propertyNameText(property.name);\n }\n\n return undefined;\n}\n\nfunction propertyNameText(name: Ts.PropertyName): string | undefined {\n if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {\n return name.text;\n }\n\n return undefined;\n}\n\nfunction unwrapExpression(expression: Ts.Expression): Ts.Expression {\n let current = expression;\n\n while (\n ts.isParenthesizedExpression(current) ||\n ts.isAsExpression(current) ||\n ts.isSatisfiesExpression(current) ||\n ts.isTypeAssertionExpression(current) ||\n ts.isNonNullExpression(current)\n ) {\n current = current.expression;\n }\n\n return current;\n}\n\nfunction moduleIdForFile(appDir: string, file: string): string {\n return relative(appDir, file).split(sep).join(\"/\");\n}\n\nfunction isInsideAppDir(appDir: string, file: string): boolean {\n const relativePath = relative(appDir, file);\n\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !relativePath.startsWith(\"/\"));\n}\n\nfunction moduleIdForBuildFile(file: string, relativeRoutesDir: string): string {\n return relativeRoutesDir === \"\" ? file : file.slice(relativeRoutesDir.length + 1);\n}\n\nfunction createBuildProgram(\n file: string,\n files: Record<string, string>,\n source: string,\n): Ts.Program {\n const compilerOptions = defaultCompilerOptions();\n const defaultHost = ts.createCompilerHost(compilerOptions, true);\n const host: Ts.CompilerHost = {\n ...defaultHost,\n fileExists: (filename) => filename === file || files[filename] !== undefined,\n getSourceFile: (filename, languageVersion) => {\n const fileSource = filename === file ? source : files[filename];\n\n if (fileSource !== undefined) {\n return ts.createSourceFile(filename, fileSource, languageVersion, true);\n }\n\n return defaultHost.getSourceFile(filename, languageVersion);\n },\n readFile: (filename) => (filename === file ? source : files[filename]),\n };\n\n return ts.createProgram({\n host,\n options: compilerOptions,\n rootNames: [file],\n });\n}\n\nfunction createRuntimeProgramHost(options: {\n code: string;\n compilerOptions: Ts.CompilerOptions;\n pageFile: string;\n}): Ts.CompilerHost {\n const defaultHost = ts.createCompilerHost(options.compilerOptions, true);\n\n return {\n ...defaultHost,\n fileExists: (filename) => filename === options.pageFile || defaultHost.fileExists(filename),\n getSourceFile: (filename, languageVersion) => {\n if (filename === options.pageFile) {\n return ts.createSourceFile(filename, options.code, languageVersion, true);\n }\n\n return defaultHost.getSourceFile(filename, languageVersion);\n },\n readFile: (filename) =>\n filename === options.pageFile ? options.code : defaultHost.readFile(filename),\n };\n}\n\nfunction defaultCompilerOptions(): Ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n noEmit: true,\n target: ts.ScriptTarget.ES2022,\n };\n}\n\nasync function loadTypeScript(): Promise<void> {\n if (typescriptLoaded) {\n return;\n }\n\n ts = await import(\"typescript\");\n typescriptLoaded = true;\n}\n\nexport function __readServerActionInferenceTypeScriptLoadedForTests(): boolean {\n return typescriptLoaded;\n}\n\nexport function __resetServerActionInferenceTypeScriptForTests(): void {\n ts = undefined as unknown as typeof Ts;\n typescriptLoaded = false;\n}\n\nfunction formActionOccurrenceKey(reference: {\n end: number;\n expression: string;\n expressionEnd: number;\n expressionStart: number;\n start: number;\n}): string {\n return [\n reference.start,\n reference.end,\n reference.expressionStart,\n reference.expressionEnd,\n reference.expression,\n ].join(\":\");\n}\n\nfunction formActionSourceHash(code: string): string {\n return createHash(\"sha256\").update(code).digest(\"base64url\");\n}\n\nexport function hasUseServerDirectiveInSource(input: {\n code: string;\n filename: string;\n}): boolean {\n return hasModuleDirective({\n code: input.code,\n directive: \"use server\",\n filename: input.filename,\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-router",
3
- "version": "0.0.80",
3
+ "version": "0.0.82",
4
4
  "description": "File-system app router, SSR, actions, and deployment adapters for mreact.",
5
5
  "keywords": [
6
6
  "jsx",
@@ -105,20 +105,20 @@
105
105
  },
106
106
  "dependencies": {
107
107
  "typescript": "^6.0.3",
108
- "@reckona/mreact": "0.0.80",
109
- "@reckona/mreact-devtools": "0.0.80",
110
- "@reckona/mreact-query": "0.0.80",
111
- "@reckona/mreact-compiler": "0.0.80",
112
- "@reckona/mreact-compat": "0.0.80",
113
- "@reckona/mreact-reactive-core": "0.0.80",
114
- "@reckona/mreact-reactive-dom": "0.0.80",
115
- "@reckona/mreact-server": "0.0.80",
116
- "@reckona/mreact-shared": "0.0.80"
108
+ "@reckona/mreact-compiler": "0.0.82",
109
+ "@reckona/mreact-query": "0.0.82",
110
+ "@reckona/mreact-reactive-core": "0.0.82",
111
+ "@reckona/mreact-compat": "0.0.82",
112
+ "@reckona/mreact-devtools": "0.0.82",
113
+ "@reckona/mreact": "0.0.82",
114
+ "@reckona/mreact-reactive-dom": "0.0.82",
115
+ "@reckona/mreact-server": "0.0.82",
116
+ "@reckona/mreact-shared": "0.0.82"
117
117
  },
118
118
  "peerDependencies": {
119
119
  "vite": ">=8 <9"
120
120
  },
121
121
  "optionalDependencies": {
122
- "@reckona/mreact-router-native": "0.0.80"
122
+ "@reckona/mreact-router-native": "0.0.82"
123
123
  }
124
124
  }
package/src/client.ts CHANGED
@@ -3,9 +3,11 @@ import { readFile, stat } from "node:fs/promises";
3
3
  import { builtinModules } from "node:module";
4
4
  import { dirname, extname, join, relative, sep } from "node:path";
5
5
  import {
6
+ analyzeBoundaryGraph,
6
7
  collectClientRouteModuleAnalysis,
7
8
  formatDiagnostic,
8
9
  type ComponentMetadata,
10
+ type BoundaryGraphResult,
9
11
  type ClientRouteModuleAnalysis,
10
12
  type ClientRouteStaticImportReference,
11
13
  type ClientReferenceMetadata,
@@ -103,6 +105,8 @@ export interface ClientRouteInferenceResult {
103
105
  }
104
106
 
105
107
  interface ClientRouteModuleInferenceResult extends ClientRouteInferenceResult {
108
+ boundaryGraphFallbackCandidate: boolean;
109
+ boundaryGraphFallbackRequired: boolean;
106
110
  clientBoundaryExportNames: string[];
107
111
  clientBoundaryModule: boolean;
108
112
  nestedClientExportNames: string[];
@@ -211,9 +215,20 @@ export async function inferClientRouteModule(options: {
211
215
  seen: new Set(),
212
216
  sourceTransform,
213
217
  });
218
+ const mergedRouteInference = routeInference.boundaryGraphFallbackRequired
219
+ ? mergeClientRouteInference(
220
+ routeInference,
221
+ await inferClientRouteModuleBoundaryGraph({
222
+ cache,
223
+ code,
224
+ filename: options.filename,
225
+ sourceTransform,
226
+ }),
227
+ )
228
+ : routeInference;
214
229
 
215
230
  if (options.appDir === undefined) {
216
- return routeInference;
231
+ return mergedRouteInference;
217
232
  }
218
233
 
219
234
  const shellInferences = await inferClientRouteShellModules({
@@ -224,10 +239,10 @@ export async function inferClientRouteModule(options: {
224
239
  });
225
240
 
226
241
  return {
227
- client: routeInference.client || shellInferences.some((inference) => inference.client),
228
- clientBoundaryImports: routeInference.clientBoundaryImports,
242
+ client: mergedRouteInference.client || shellInferences.some((inference) => inference.client),
243
+ clientBoundaryImports: mergedRouteInference.clientBoundaryImports,
229
244
  diagnostics: [
230
- ...routeInference.diagnostics,
245
+ ...mergedRouteInference.diagnostics,
231
246
  ...shellInferences.flatMap((inference) => inference.diagnostics),
232
247
  ],
233
248
  };
@@ -239,6 +254,68 @@ export async function inferClientRouteModule(options: {
239
254
  }
240
255
  }
241
256
 
257
+ async function inferClientRouteModuleBoundaryGraph(options: {
258
+ cache: ClientRouteInferenceCache;
259
+ code: string;
260
+ filename: string;
261
+ sourceTransform?: ClientRouteSourceTransform | undefined;
262
+ }): Promise<ClientRouteInferenceResult> {
263
+ const graph = await analyzeBoundaryGraph({
264
+ entries: [{ file: options.filename, kind: "route-page" }],
265
+ readModule: async (file) => {
266
+ if (file === options.filename) {
267
+ return options.code;
268
+ }
269
+
270
+ return await readClientRouteSource({
271
+ cache: options.cache,
272
+ filename: file,
273
+ sourceTransform: options.sourceTransform,
274
+ });
275
+ },
276
+ resolveModule: async ({ importer, source }) =>
277
+ await resolveAppLocalModule({
278
+ allowExplicitNonSource: options.sourceTransform !== undefined,
279
+ cache: options.cache,
280
+ importer,
281
+ specifier: source,
282
+ }),
283
+ });
284
+
285
+ return clientRouteInferenceFromBoundaryGraph(graph, options.filename);
286
+ }
287
+
288
+ function clientRouteInferenceFromBoundaryGraph(
289
+ graph: BoundaryGraphResult,
290
+ filename: string,
291
+ ): ClientRouteInferenceResult {
292
+ const clientBoundaryImports = graph.clientBoundaries
293
+ .filter((boundary) => boundary.importerFile === filename)
294
+ .map((boundary) => boundary.source);
295
+ const clientRoute = graph.modules.some(
296
+ (module) => module.file === filename && module.classification === "client-route",
297
+ );
298
+
299
+ return {
300
+ client: clientRoute || clientBoundaryImports.length > 0,
301
+ clientBoundaryImports,
302
+ diagnostics: [],
303
+ };
304
+ }
305
+
306
+ function mergeClientRouteInference(
307
+ left: ClientRouteInferenceResult,
308
+ right: ClientRouteInferenceResult,
309
+ ): ClientRouteInferenceResult {
310
+ return {
311
+ client: left.client || right.client,
312
+ clientBoundaryImports: Array.from(
313
+ new Set([...left.clientBoundaryImports, ...right.clientBoundaryImports]),
314
+ ),
315
+ diagnostics: [...left.diagnostics, ...right.diagnostics],
316
+ };
317
+ }
318
+
242
319
  export async function collectClientRouteReferences(options: {
243
320
  appDir?: string | undefined;
244
321
  cache?: ClientRouteInferenceCache | undefined;
@@ -534,6 +611,7 @@ async function inferClientRouteModuleSource(options: {
534
611
  const nestedClientExportNames = new Set<string>();
535
612
  const clientReferenceSourceFiles: string[] = [];
536
613
  const diagnostics: ClientRouteInferenceDiagnostic[] = [];
614
+ let boundaryGraphFallbackRequired = false;
537
615
  let clientProxy = false;
538
616
  let nestedClient = false;
539
617
  const exportInfo = analysis.topLevelExportRenderInfo;
@@ -605,6 +683,9 @@ async function inferClientRouteModuleSource(options: {
605
683
  diagnostics.push(...imported.diagnostics);
606
684
 
607
685
  if (!imported.client) {
686
+ if (rendered && imported.boundaryGraphFallbackCandidate) {
687
+ boundaryGraphFallbackRequired = true;
688
+ }
608
689
  if (imported.serverOnlyClientRuntime && rendered) {
609
690
  diagnostics.push(
610
691
  serverOnlyClientImportReferenceDiagnostic({
@@ -706,11 +787,16 @@ async function inferClientRouteModuleSource(options: {
706
787
  } else if (exported.client) {
707
788
  nestedClient = true;
708
789
  clientReferenceSourceFiles.push(resolved);
790
+ } else if (exported.boundaryGraphFallbackCandidate) {
791
+ boundaryGraphFallbackRequired = true;
709
792
  }
710
793
  }
711
794
  }
712
795
 
713
796
  return {
797
+ boundaryGraphFallbackCandidate:
798
+ analysis.staticExports.length > 0 || boundaryGraphFallbackRequired,
799
+ boundaryGraphFallbackRequired,
714
800
  client:
715
801
  clientBoundaryImports.length > 0 ||
716
802
  clientBoundaryExportNames.size > 0 ||
@@ -735,6 +821,8 @@ function emptyClientRouteModuleInferenceResult(
735
821
  overrides: Partial<ClientRouteModuleInferenceResult> = {},
736
822
  ): ClientRouteModuleInferenceResult {
737
823
  return {
824
+ boundaryGraphFallbackCandidate: false,
825
+ boundaryGraphFallbackRequired: false,
738
826
  client: false,
739
827
  clientBoundaryImports: [],
740
828
  clientBoundaryExportNames: [],
@@ -1442,6 +1530,7 @@ export async function buildClientRouteEntrySource(
1442
1530
  code: options.code,
1443
1531
  filename: options.filename,
1444
1532
  });
1533
+ const routeSourceAnalysis = collectClientRouteModuleAnalysisFromContext(moduleContext);
1445
1534
  const compiled = transformCompilerModuleContext({
1446
1535
  code: options.code,
1447
1536
  clientBoundaryImports: options.clientBoundaryImports ?? [],
@@ -1479,10 +1568,17 @@ export async function buildClientRouteEntrySource(
1479
1568
  const routeUsesCells = detectRouteCellStateHint(compiled.code);
1480
1569
  const routeUsesReactiveEffect = detectRouteReactiveEffectHint(compiled.code);
1481
1570
  const routeUsesCleanupScope = routeUsesCells || routeUsesReactiveEffect;
1571
+ const routeExplicitlyRequiresHydration = isExplicitClientRouteSource(
1572
+ routeSourceAnalysis,
1573
+ options.filename,
1574
+ );
1482
1575
  const routeHasEventBindings =
1483
1576
  (compiled.metadata.eventHydrationManifest?.events.length ?? 0) > 0;
1484
1577
  const routeRequiresFullHydration =
1485
- routeUsesCells || routeUsesReactiveEffect || routeHasEventBindings;
1578
+ routeExplicitlyRequiresHydration ||
1579
+ routeUsesCells ||
1580
+ routeUsesReactiveEffect ||
1581
+ routeHasEventBindings;
1486
1582
  const routeUsesOnlyClientReferenceBoundaries =
1487
1583
  !routeRequiresFullHydration &&
1488
1584
  clientReferenceManifest.length > 0 &&
@@ -1702,7 +1798,7 @@ export function __mreactHydrateRoute() {
1702
1798
  }
1703
1799
  ${routeCellHydrationStart}${routeCleanupHydrationStart}${boundaryOnlyHydrationBlock}${routeComponentGuard}${routeCellHydrationIndent}const __mreactNode = ${routeNodeExpression};
1704
1800
  ${routeCellHydrationIndent}__mreactResumeRoute(__mreactMarker, __mreactNode);
1705
- ${routeCellHydrationIndent}__mreactHydrateClientBoundaries(__mreactMarker, __mreactClientReferences, __mreactClientReferenceComponents);
1801
+ ${routeCellHydrationIndent}__mreactHydrateClientBoundaries(document, __mreactClientReferences, __mreactClientReferenceComponents);
1706
1802
  ${routeCellHydrationIndent}__mreactMarker.setAttribute("data-mreact-hydrated", "true");
1707
1803
  ${routeCellHydrationEnd}}
1708
1804
  ${routeCellDropFunction}
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { dirname, relative, sep } from "node:path";
3
3
  import {
4
+ analyzeBoundaryGraph,
4
5
  collectFormActionExpressionReferences,
5
6
  hasModuleDirective,
6
7
  type FormActionExpressionReference,
@@ -154,6 +155,14 @@ export async function collectBuildInferredServerActions(options: {
154
155
  const diagnostics: ServerActionInferenceDiagnostic[] = [];
155
156
  const references: InferredServerActionExpressionReference[] = [];
156
157
  const sourceHash = formActionSourceHash(options.source);
158
+ const graphReferences = await collectBuildBoundaryGraphServerActions({
159
+ file: options.file,
160
+ files: options.files,
161
+ relativeRoutesDir: options.relativeRoutesDir,
162
+ resolveSourceImport: options.resolveSourceImport,
163
+ source: options.source,
164
+ sourceHash,
165
+ });
157
166
 
158
167
  for (const formReference of formReferences) {
159
168
  const expression = findExpressionAt(sourceFile, formReference);
@@ -185,6 +194,13 @@ export async function collectBuildInferredServerActions(options: {
185
194
  continue;
186
195
  }
187
196
 
197
+ const graphReference = graphReferences.get(formActionOccurrenceKey(formReference));
198
+
199
+ if (graphReference !== undefined) {
200
+ references.push(graphReference);
201
+ continue;
202
+ }
203
+
188
204
  if (resolved.kind === "dynamic") {
189
205
  diagnostics.push({
190
206
  code: dynamicFormActionInferenceCode,
@@ -198,6 +214,39 @@ export async function collectBuildInferredServerActions(options: {
198
214
  return { diagnostics, references };
199
215
  }
200
216
 
217
+ async function collectBuildBoundaryGraphServerActions(options: {
218
+ file: string;
219
+ files: Record<string, string>;
220
+ relativeRoutesDir: string;
221
+ resolveSourceImport: (importer: string, source: string) => string | undefined;
222
+ source: string;
223
+ sourceHash: string;
224
+ }): Promise<Map<string, InferredServerActionExpressionReference>> {
225
+ const graph = await analyzeBoundaryGraph({
226
+ entries: [{ file: options.file, kind: "route-page" }],
227
+ readModule: (file) => (file === options.file ? options.source : options.files[file]),
228
+ resolveModule: ({ importer, source }) => options.resolveSourceImport(importer, source),
229
+ });
230
+ const references = new Map<string, InferredServerActionExpressionReference>();
231
+
232
+ for (const action of graph.serverActions) {
233
+ const reference = {
234
+ end: action.end,
235
+ exportName: action.exportName,
236
+ expression: action.expression,
237
+ expressionEnd: action.expressionEnd,
238
+ expressionStart: action.expressionStart,
239
+ inferred: action.inferred,
240
+ moduleId: moduleIdForBuildFile(action.moduleFile, options.relativeRoutesDir),
241
+ sourceHash: options.sourceHash,
242
+ start: action.start,
243
+ };
244
+ references.set(formActionOccurrenceKey(reference), reference);
245
+ }
246
+
247
+ return references;
248
+ }
249
+
201
250
  type RuntimeResolveResult =
202
251
  | { kind: "dynamic" }
203
252
  | { kind: "resolved"; reference: InferredServerActionReference }