isthmus-cli 0.6.0 → 0.7.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 +135 -31
- package/README.md +134 -16
- package/Skills/isthmus/SKILL.md +17 -7
- package/compatibility.json +10 -0
- package/dist/cli/check-command.d.ts +2 -2
- package/dist/cli/check-command.js +22 -9
- package/dist/cli/check-command.js.map +1 -1
- package/dist/cli/command-support.d.ts +19 -1
- package/dist/cli/command-support.js +37 -8
- package/dist/cli/command-support.js.map +1 -1
- package/dist/cli/diff-command.js +4 -3
- package/dist/cli/diff-command.js.map +1 -1
- package/dist/cli/doctor-command.d.ts +11 -0
- package/dist/cli/doctor-command.js +128 -0
- package/dist/cli/doctor-command.js.map +1 -0
- package/dist/cli/extract-js-command.d.ts +33 -0
- package/dist/cli/extract-js-command.js +233 -0
- package/dist/cli/extract-js-command.js.map +1 -0
- package/dist/cli/graph-command.js +13 -6
- package/dist/cli/graph-command.js.map +1 -1
- package/dist/cli/init-command.d.ts +11 -0
- package/dist/cli/init-command.js +115 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/main.js +52 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp-server.d.ts +16 -0
- package/dist/cli/mcp-server.js +534 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/query-command.js +13 -6
- package/dist/cli/query-command.js.map +1 -1
- package/dist/cli/retentions-command.js +14 -7
- package/dist/cli/retentions-command.js.map +1 -1
- package/dist/cli/serve-command.d.ts +13 -0
- package/dist/cli/serve-command.js +43 -0
- package/dist/cli/serve-command.js.map +1 -0
- package/dist/exchange/capture-config.d.ts +18 -0
- package/dist/exchange/capture-config.js +100 -0
- package/dist/exchange/capture-config.js.map +1 -0
- package/dist/exchange/messages.d.ts +9 -24
- package/dist/exchange/messages.js +25 -55
- package/dist/exchange/messages.js.map +1 -1
- package/dist/exchange/parse.d.ts +61 -0
- package/dist/exchange/parse.js +115 -12
- package/dist/exchange/parse.js.map +1 -1
- package/dist/extract/js-document.d.ts +22 -0
- package/dist/extract/js-document.js +230 -0
- package/dist/extract/js-document.js.map +1 -0
- package/dist/extract/js-scan.d.ts +93 -0
- package/dist/extract/js-scan.js +1205 -0
- package/dist/extract/js-scan.js.map +1 -0
- package/dist/extract/lexer.d.ts +26 -0
- package/dist/extract/lexer.js +316 -0
- package/dist/extract/lexer.js.map +1 -0
- package/dist/join/join.d.ts +66 -1
- package/dist/join/join.js +171 -1
- package/dist/join/join.js.map +1 -1
- package/dist/join/messages.d.ts +7 -4
- package/dist/join/messages.js +15 -8
- package/dist/join/messages.js.map +1 -1
- package/dist/report/check-report.d.ts +20 -3
- package/dist/report/check-report.js +240 -8
- package/dist/report/check-report.js.map +1 -1
- package/dist/report/codequality.d.ts +45 -0
- package/dist/report/codequality.js +74 -0
- package/dist/report/codequality.js.map +1 -0
- package/dist/report/diff.d.ts +25 -3
- package/dist/report/diff.js +91 -11
- package/dist/report/diff.js.map +1 -1
- package/dist/report/graph.d.ts +10 -4
- package/dist/report/graph.js +60 -6
- package/dist/report/graph.js.map +1 -1
- package/dist/report/preflight-view.js +28 -1
- package/dist/report/preflight-view.js.map +1 -1
- package/dist/report/preflight.d.ts +4 -4
- package/dist/report/preflight.js +81 -46
- package/dist/report/preflight.js.map +1 -1
- package/dist/report/query.d.ts +11 -4
- package/dist/report/query.js +84 -17
- package/dist/report/query.js.map +1 -1
- package/dist/report/retentions.d.ts +17 -5
- package/dist/report/retentions.js +85 -8
- package/dist/report/retentions.js.map +1 -1
- package/dist/report/rules.d.ts +16 -0
- package/dist/report/rules.js +30 -0
- package/dist/report/rules.js.map +1 -0
- package/dist/report/sarif.d.ts +2 -8
- package/dist/report/sarif.js +2 -10
- package/dist/report/sarif.js.map +1 -1
- package/docs/BRIDGE-EVENTS.md +87 -0
- package/docs/BRIDGE-MESSAGES.md +23 -8
- package/docs/GRAPH-EXCHANGE.md +141 -14
- package/docs/IMPACT.md +1 -1
- package/docs/MCP.md +62 -0
- package/docs/PREFLIGHT.md +24 -8
- package/docs/RUNTIME.md +2 -2
- package/docs/TOOLCHAIN.md +5 -5
- package/package.json +5 -2
- package/scripts/capture-preflight.mjs +32 -44
- package/scripts/run-child.mjs +1 -0
package/dist/report/graph.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/report/graph.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BridgeLocation,\n BridgePlatform,\n BridgeSymbol,\n BridgeSourceLanguage,\n BridgeTarget,\n} from '../exchange/parse.ts';\nimport type {\n BridgeEndpoint,\n BridgeJoinResult,\n JoinLimitation,\n} from '../join/join.ts';\nimport { isBridgeJoinDeferred } from '../join/join.ts';\nimport { compareStrings } from '../compare.ts';\nimport { encodeSortedJson } from './sorted-json.ts';\n\n/** 소스 위치 하나를 나타내는 경계 그래프 노드다. */\nexport interface BridgeGraphNode {\n readonly id: string;\n readonly platform: BridgePlatform;\n readonly location: BridgeLocation;\n readonly symbol?: BridgeSymbol;\n readonly sourceLanguage?: BridgeSourceLanguage;\n}\n\n/** 호출 측 위치에서 수신 측 위치로 향하는 경계 간선이다. */\nexport interface BridgeGraphEdge {\n readonly from: string;\n readonly to: string;\n readonly kind: 'channel' | 'method';\n readonly target: BridgeTarget;\n readonly channel: string;\n readonly method?: string;\n}\n\n/** 매치된 경계 간선만 담는 그래프 문서다. */\nexport interface BridgeGraphDocument {\n readonly format: 'isthmus-graph';\n readonly version: 1;\n readonly nodes: readonly BridgeGraphNode[];\n readonly edges: readonly BridgeGraphEdge[];\n readonly limitations: readonly JoinLimitation[];\n}\n\n/** 한 번에 생성할 수 있는 경계 그래프 간선 수다. */\nexport const MAX_GRAPH_EDGES = 100_000;\n\n/** 입력 증거의 곱이 안전한 그래프 크기를 넘었음을 나타낸다. */\nexport class BridgeGraphLimitError extends Error {\n constructor() {\n super(`Bridge graph exceeds the ${MAX_GRAPH_EDGES} edge limit.`);\n this.name = 'BridgeGraphLimitError';\n }\n}\n\n/** 같은 위치 노드가 서로 모순된 심볼을 가졌음을 나타낸다. */\nexport class BridgeGraphValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'BridgeGraphValidationError';\n }\n}\n\n/** 경계 그래프를 요청한 출력 형식으로 렌더링한다. */\nexport function renderBridgeGraph(\n graph: BridgeGraphDocument,\n format: 'json' | 'dot' | 'mermaid',\n): string {\n if (format === 'json') return encodeSortedJson(graph);\n if (format === 'dot') return renderDot(graph);\n return renderMermaid(graph);\n}\n\n/** Mermaid flowchart 문법으로 경계 그래프를 렌더링한다. */\nfunction renderMermaid(graph: BridgeGraphDocument): string {\n const identifiers = new Map(\n graph.nodes.map((node, index) => [node.id, `n${index}`]),\n );\n const lines = ['flowchart LR'];\n for (const limitation of graph.limitations) {\n lines.push(` %% limitation: ${limitationComment(limitation)}`);\n }\n for (const node of graph.nodes) {\n const label = `${mermaidText(node.sourceLanguage ?? node.platform)}<br/>${mermaidText(locationLabel(node.location))}`;\n lines.push(` ${identifiers.get(node.id)}[\"${label}\"]`);\n }\n for (const edge of graph.edges) {\n const from = identifiers.get(edge.from);\n const to = identifiers.get(edge.to);\n lines.push(` ${from} -->|\"${mermaidText(edgeLabel(edge))}\"| ${to}`);\n }\n return `${lines.join('\\n')}\\n`;\n}\n\n/** Mermaid 인용 라벨에서 제어 문자를 HTML 엔터티로 바꾼다. */\nfunction mermaidText(value: string): string {\n return value\n .replaceAll('&', '&')\n .replaceAll('\"', '"')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('|', '|')\n .replaceAll('\\r', ' ')\n .replaceAll('\\n', ' ');\n}\n\n/** Graphviz DOT 문법으로 경계 그래프를 렌더링한다. */\nfunction renderDot(graph: BridgeGraphDocument): string {\n const lines = ['digraph isthmus {', ' rankdir=LR;'];\n for (const limitation of graph.limitations) {\n lines.push(` // limitation: ${limitationComment(limitation)}`);\n }\n for (const node of graph.nodes) {\n const label = `${node.sourceLanguage ?? node.platform}\\n${locationLabel(node.location)}`;\n lines.push(` ${dotString(node.id)} [label=${dotString(label)}];`);\n }\n for (const edge of graph.edges) {\n lines.push(\n ` ${dotString(edge.from)} -> ${dotString(edge.to)} `\n + `[label=${dotString(edgeLabel(edge))}];`,\n );\n }\n lines.push('}');\n return `${lines.join('\\n')}\\n`;\n}\n\n/** 분석 한계를 텍스트 그래프의 한 줄 주석으로 안전하게 만든다. */\nfunction limitationComment(limitation: JoinLimitation): string {\n const text =\n `${limitation.platform}/${limitation.target}/${limitation.tool}: `\n + limitation.message\n + (limitation.origin === undefined ? '' : ' [origin: consumer]')\n + (limitation.channels === undefined ? '' : ` [channels: ${JSON.stringify(limitation.channels)}]`);\n return text.replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]+/gu, ' ');\n}\n\n/** DOT 문자열 리터럴로 안전하게 이스케이프한다. */\nfunction dotString(value: string): string {\n return JSON.stringify(value);\n}\n\n/** 위치를 사람이 읽을 수 있는 경로:줄:열로 만든다. */\nfunction locationLabel(location: BridgeLocation): string {\n return `${location.path}:${location.line}:${location.column}`;\n}\n\n/** 간선 종류와 문자열 키를 한 줄 라벨로 만든다. */\nfunction edgeLabel(edge: BridgeGraphEdge): string {\n const key = edge.method === undefined\n ? edge.channel\n : `${edge.channel}#${edge.method}`;\n return `${edge.kind} ${key}`;\n}\n\n/** 조인 결과의 매치만 경계 그래프로 바꾼다. */\nexport function createBridgeGraph(joined: BridgeJoinResult): BridgeGraphDocument {\n if (isBridgeJoinDeferred(joined)) {\n throw new Error('Cannot create a graph from a deferred bridge join.');\n }\n assertBridgeGraphSize(joined);\n const nodes = new Map<string, BridgeGraphNode>();\n const edges: BridgeGraphEdge[] = [];\n addChannelEdges(joined, nodes, edges);\n addMethodEdges(joined, nodes, edges);\n return {\n format: 'isthmus-graph',\n version: 1,\n nodes: [...nodes.values()].sort((left, right) => compareStrings(left.id, right.id)),\n edges: edges.sort(compareEdges),\n limitations: joined.limitations,\n };\n}\n\n/** 모든 Cartesian 간선 수를 할당 전에 계산해 메모리 폭증을 막는다. */\nexport function assertBridgeGraphSize(joined: BridgeJoinResult): void {\n let edgeCount = 0;\n const endpointCounts = [\n ...joined.matchedChannels.map(({ creations, registrations }) =>\n [creations.length, registrations.length] as const,\n ),\n ...joined.matchedMethods.map(({ invocations, handlers }) =>\n [invocations.length, handlers.length] as const,\n ),\n ];\n for (const [fromCount, toCount] of endpointCounts) {\n if (\n toCount > 0 &&\n fromCount > Math.floor((MAX_GRAPH_EDGES - edgeCount) / toCount)\n ) {\n throw new BridgeGraphLimitError();\n }\n edgeCount += fromCount * toCount;\n }\n}\n\n/** 매치된 채널의 생성→등록 간선을 추가한다. */\nfunction addChannelEdges(\n joined: BridgeJoinResult,\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const match of joined.matchedChannels) {\n for (const creation of match.creations) {\n for (const registration of match.registrations) {\n const from = addNode(nodes, creation);\n const to = addNode(nodes, registration);\n edges.push({\n from,\n to,\n kind: 'channel',\n target: match.target,\n channel: match.channel,\n });\n }\n }\n }\n}\n\n/** 매치된 메서드의 호출→핸들러 간선을 추가한다. */\nfunction addMethodEdges(\n joined: BridgeJoinResult,\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const match of joined.matchedMethods) {\n for (const invocation of match.invocations) {\n for (const handler of match.handlers) {\n const from = addNode(nodes, invocation);\n const to = addNode(nodes, handler);\n edges.push({\n from,\n to,\n kind: 'method',\n target: match.target,\n channel: match.channel,\n method: match.method,\n });\n }\n }\n }\n}\n\n/** 증거 위치를 그래프 노드로 추가하고 안정 ID를 돌려준다. */\nfunction addNode(\n nodes: Map<string, BridgeGraphNode>,\n endpoint: BridgeEndpoint,\n): string {\n const id = endpointId(endpoint);\n const existing = nodes.get(id);\n if (existing === undefined) {\n nodes.set(id, { id, ...endpoint });\n } else if (endpoint.symbol !== undefined) {\n const symbol = mergeSymbols(existing.symbol, endpoint.symbol);\n if (symbol === undefined) {\n throw new BridgeGraphValidationError(\n 'Bridge graph node has conflicting symbols.',\n );\n }\n nodes.set(id, { ...existing, symbol });\n }\n return id;\n}\n\n/** 호환되는 두 심볼을 더 구체적인 선언 식별자로 병합한다. */\nfunction mergeSymbols(\n left: BridgeSymbol | undefined,\n right: BridgeSymbol,\n): BridgeSymbol | undefined {\n if (left === undefined) return right;\n if (left.qualifiedName !== right.qualifiedName) return undefined;\n if (left.usr !== undefined && right.usr !== undefined && left.usr !== right.usr) {\n return undefined;\n }\n const usr = left.usr ?? right.usr;\n return usr === undefined\n ? { qualifiedName: left.qualifiedName }\n : { qualifiedName: left.qualifiedName, usr };\n}\n\n/** 플랫폼과 소스 위치로 실행 간 안정적인 노드 ID를 만든다. */\nfunction endpointId(endpoint: BridgeEndpoint): string {\n const { path, line, column } = endpoint.location;\n const suffix = endpoint.sourceLanguage === undefined ? '' : `:${endpoint.sourceLanguage}`;\n return `${endpoint.platform}:${path}:${line}:${column}${suffix}`;\n}\n\n/** 간선을 종류·from·to 순으로 고정한다. */\nfunction compareEdges(left: BridgeGraphEdge, right: BridgeGraphEdge): number {\n return (\n compareStrings(left.kind, right.kind) ||\n compareStrings(left.from, right.from) ||\n compareStrings(left.to, right.to)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/report/graph.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BridgeLocation,\n BridgePlatform,\n BridgeSymbol,\n BridgeSourceLanguage,\n BridgeTarget,\n} from '../exchange/parse.ts';\nimport type {\n BridgeEndpoint,\n BridgeJoinResult,\n JoinLimitation,\n MatchedBoundaryName,\n} from '../join/join.ts';\nimport { compareLimitations, isBridgeJoinDeferred } from '../join/join.ts';\nimport type { MessageBridgeJoin } from '../join/messages.ts';\nimport { compareStrings } from '../compare.ts';\nimport { encodeSortedJson } from './sorted-json.ts';\n\n/** 소스 위치 하나를 나타내는 경계 그래프 노드다. */\nexport interface BridgeGraphNode {\n readonly id: string;\n readonly platform: BridgePlatform;\n readonly location: BridgeLocation;\n readonly symbol?: BridgeSymbol;\n readonly sourceLanguage?: BridgeSourceLanguage;\n}\n\n/** 호출 측 위치에서 수신 측 위치로 향하는 경계 간선이다. */\nexport interface BridgeGraphEdge {\n readonly from: string;\n readonly to: string;\n readonly kind: 'channel' | 'method' | 'module' | 'component' | 'message' | 'stream';\n readonly target: BridgeTarget;\n readonly channel: string;\n readonly method?: string;\n}\n\n/** 매치된 경계 간선만 담는 그래프 문서다. */\nexport interface BridgeGraphDocument {\n readonly format: 'isthmus-graph';\n readonly version: 1;\n readonly nodes: readonly BridgeGraphNode[];\n readonly edges: readonly BridgeGraphEdge[];\n readonly limitations: readonly JoinLimitation[];\n}\n\n/** 한 번에 생성할 수 있는 경계 그래프 간선 수다. */\nexport const MAX_GRAPH_EDGES = 100_000;\n\n/** 입력 증거의 곱이 안전한 그래프 크기를 넘었음을 나타낸다. */\nexport class BridgeGraphLimitError extends Error {\n constructor() {\n super(`Bridge graph exceeds the ${MAX_GRAPH_EDGES} edge limit.`);\n this.name = 'BridgeGraphLimitError';\n }\n}\n\n/** 같은 위치 노드가 서로 모순된 심볼을 가졌음을 나타낸다. */\nexport class BridgeGraphValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'BridgeGraphValidationError';\n }\n}\n\n/** 경계 그래프를 요청한 출력 형식으로 렌더링한다. */\nexport function renderBridgeGraph(\n graph: BridgeGraphDocument,\n format: 'json' | 'dot' | 'mermaid',\n): string {\n if (format === 'json') return encodeSortedJson(graph);\n if (format === 'dot') return renderDot(graph);\n return renderMermaid(graph);\n}\n\n/** Mermaid flowchart 문법으로 경계 그래프를 렌더링한다. */\nfunction renderMermaid(graph: BridgeGraphDocument): string {\n const identifiers = new Map(\n graph.nodes.map((node, index) => [node.id, `n${index}`]),\n );\n const lines = ['flowchart LR'];\n for (const limitation of graph.limitations) {\n lines.push(` %% limitation: ${limitationComment(limitation)}`);\n }\n for (const node of graph.nodes) {\n const label = `${mermaidText(node.sourceLanguage ?? node.platform)}<br/>${mermaidText(locationLabel(node.location))}`;\n lines.push(` ${identifiers.get(node.id)}[\"${label}\"]`);\n }\n for (const edge of graph.edges) {\n const from = identifiers.get(edge.from);\n const to = identifiers.get(edge.to);\n lines.push(` ${from} -->|\"${mermaidText(edgeLabel(edge))}\"| ${to}`);\n }\n return `${lines.join('\\n')}\\n`;\n}\n\n/** Mermaid 인용 라벨에서 제어 문자를 HTML 엔터티로 바꾼다. */\nfunction mermaidText(value: string): string {\n return value\n .replaceAll('&', '&')\n .replaceAll('\"', '"')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('|', '|')\n .replaceAll('\\r', ' ')\n .replaceAll('\\n', ' ');\n}\n\n/** Graphviz DOT 문법으로 경계 그래프를 렌더링한다. */\nfunction renderDot(graph: BridgeGraphDocument): string {\n const lines = ['digraph isthmus {', ' rankdir=LR;'];\n for (const limitation of graph.limitations) {\n lines.push(` // limitation: ${limitationComment(limitation)}`);\n }\n for (const node of graph.nodes) {\n const label = `${node.sourceLanguage ?? node.platform}\\n${locationLabel(node.location)}`;\n lines.push(` ${dotString(node.id)} [label=${dotString(label)}];`);\n }\n for (const edge of graph.edges) {\n lines.push(\n ` ${dotString(edge.from)} -> ${dotString(edge.to)} `\n + `[label=${dotString(edgeLabel(edge))}];`,\n );\n }\n lines.push('}');\n return `${lines.join('\\n')}\\n`;\n}\n\n/** 분석 한계를 텍스트 그래프의 한 줄 주석으로 안전하게 만든다. */\nfunction limitationComment(limitation: JoinLimitation): string {\n const text =\n `${limitation.platform}/${limitation.target}/${limitation.tool}: `\n + limitation.message\n + (limitation.origin === undefined ? '' : ' [origin: consumer]')\n + (limitation.channels === undefined ? '' : ` [channels: ${JSON.stringify(limitation.channels)}]`);\n return text.replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]+/gu, ' ');\n}\n\n/** DOT 문자열 리터럴로 안전하게 이스케이프한다. */\nfunction dotString(value: string): string {\n return JSON.stringify(value);\n}\n\n/** 위치를 사람이 읽을 수 있는 경로:줄:열로 만든다. */\nfunction locationLabel(location: BridgeLocation): string {\n return `${location.path}:${location.line}:${location.column}`;\n}\n\n/** 간선 종류와 문자열 키를 한 줄 라벨로 만든다. */\nfunction edgeLabel(edge: BridgeGraphEdge): string {\n const key = edge.method === undefined\n ? edge.channel\n : `${edge.channel}#${edge.method}`;\n return `${edge.kind} ${key}`;\n}\n\n/**\n * 조인 결과의 매치만 경계 그래프로 만든다.\n *\n * `messages`를 주면 literal로 확정된 Basic·Event 경계가 `message`·`stream`\n * 간선으로 더해진다. dynamic prefix 후보는 확정 매치가 아니므로 담지 않는다.\n */\nexport function createBridgeGraph(\n joined: BridgeJoinResult,\n messages?: MessageBridgeJoin,\n): BridgeGraphDocument {\n if (isBridgeJoinDeferred(joined)) {\n throw new Error('Cannot create a graph from a deferred bridge join.');\n }\n assertBridgeGraphSize(joined, messages);\n const nodes = new Map<string, BridgeGraphNode>();\n const edges: BridgeGraphEdge[] = [];\n addChannelEdges(joined, nodes, edges);\n addMethodEdges(joined, nodes, edges);\n addNameEdges(joined.matchedModules, 'module', nodes, edges);\n addNameEdges(joined.matchedComponents, 'component', nodes, edges);\n if (messages !== undefined) addMessageEdges(messages, nodes, edges);\n return {\n format: 'isthmus-graph',\n version: 1,\n nodes: [...nodes.values()].sort((left, right) => compareStrings(left.id, right.id)),\n edges: edges.sort(compareEdges),\n limitations: messages === undefined\n ? joined.limitations\n : [...joined.limitations, ...messages.limitations].sort(compareLimitations),\n };\n}\n\n/** literal로 확정된 Basic·Event 경계의 발신→수신 간선을 추가한다. */\nfunction addMessageEdges(\n messages: MessageBridgeJoin,\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const route of messages.routes) {\n if (route.matching !== 'literal') continue;\n for (const sender of route.senders) {\n for (const handler of route.handlers) {\n const from = addNode(nodes, sender);\n const to = addNode(nodes, handler);\n edges.push({\n from,\n to,\n kind: route.transport === 'event-channel' ? 'stream' : 'message',\n target: 'flutter',\n channel: route.channel,\n });\n }\n }\n }\n}\n\n/** 모든 Cartesian 간선 수를 할당 전에 계산해 메모리 폭증을 막는다. */\nexport function assertBridgeGraphSize(\n joined: BridgeJoinResult,\n messages?: MessageBridgeJoin,\n): void {\n let edgeCount = 0;\n const endpointCounts = [\n ...joined.matchedChannels.map(({ creations, registrations }) =>\n [creations.length, registrations.length] as const,\n ),\n ...joined.matchedMethods.map(({ invocations, handlers }) =>\n [invocations.length, handlers.length] as const,\n ),\n ...joined.matchedModules.map(({ callers, receivers }) =>\n [callers.length, receivers.length] as const,\n ),\n ...joined.matchedComponents.map(({ callers, receivers }) =>\n [callers.length, receivers.length] as const,\n ),\n ...(messages?.routes ?? [])\n .filter((route) => route.matching === 'literal')\n .map(({ senders, handlers }) =>\n [senders.length, handlers.length] as const,\n ),\n ];\n for (const [fromCount, toCount] of endpointCounts) {\n if (\n toCount > 0 &&\n fromCount > Math.floor((MAX_GRAPH_EDGES - edgeCount) / toCount)\n ) {\n throw new BridgeGraphLimitError();\n }\n edgeCount += fromCount * toCount;\n }\n}\n\n/** 매치된 채널의 생성→등록 간선을 추가한다. */\nfunction addChannelEdges(\n joined: BridgeJoinResult,\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const match of joined.matchedChannels) {\n for (const creation of match.creations) {\n for (const registration of match.registrations) {\n const from = addNode(nodes, creation);\n const to = addNode(nodes, registration);\n edges.push({\n from,\n to,\n kind: 'channel',\n target: match.target,\n channel: match.channel,\n });\n }\n }\n }\n}\n\n/** 매치된 메서드의 호출→핸들러 간선을 추가한다. */\nfunction addMethodEdges(\n joined: BridgeJoinResult,\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const match of joined.matchedMethods) {\n for (const invocation of match.invocations) {\n for (const handler of match.handlers) {\n const from = addNode(nodes, invocation);\n const to = addNode(nodes, handler);\n edges.push({\n from,\n to,\n kind: 'method',\n target: match.target,\n channel: match.channel,\n method: match.method,\n });\n }\n }\n }\n}\n\n/** 매치된 모듈·컴포넌트 이름의 호출→export 간선을 추가한다. */\nfunction addNameEdges(\n matches: readonly MatchedBoundaryName[],\n kind: 'module' | 'component',\n nodes: Map<string, BridgeGraphNode>,\n edges: BridgeGraphEdge[],\n): void {\n for (const match of matches) {\n for (const caller of match.callers) {\n for (const receiver of match.receivers) {\n const from = addNode(nodes, caller);\n const to = addNode(nodes, receiver);\n edges.push({\n from,\n to,\n kind,\n target: match.target,\n channel: match.channel,\n });\n }\n }\n }\n}\n\n/** 증거 위치를 그래프 노드로 추가하고 안정 ID를 돌려준다. */\nfunction addNode(\n nodes: Map<string, BridgeGraphNode>,\n endpoint: BridgeEndpoint,\n): string {\n const id = endpointId(endpoint);\n const existing = nodes.get(id);\n if (existing === undefined) {\n nodes.set(id, { id, ...endpoint });\n } else if (endpoint.symbol !== undefined) {\n const symbol = mergeSymbols(existing.symbol, endpoint.symbol);\n if (symbol === undefined) {\n throw new BridgeGraphValidationError(\n 'Bridge graph node has conflicting symbols.',\n );\n }\n nodes.set(id, { ...existing, symbol });\n }\n return id;\n}\n\n/** 호환되는 두 심볼을 더 구체적인 선언 식별자로 병합한다. */\nfunction mergeSymbols(\n left: BridgeSymbol | undefined,\n right: BridgeSymbol,\n): BridgeSymbol | undefined {\n if (left === undefined) return right;\n if (left.qualifiedName !== right.qualifiedName) return undefined;\n if (left.usr !== undefined && right.usr !== undefined && left.usr !== right.usr) {\n return undefined;\n }\n const usr = left.usr ?? right.usr;\n return usr === undefined\n ? { qualifiedName: left.qualifiedName }\n : { qualifiedName: left.qualifiedName, usr };\n}\n\n/** 플랫폼과 소스 위치로 실행 간 안정적인 노드 ID를 만든다. */\nfunction endpointId(endpoint: BridgeEndpoint): string {\n const { path, line, column } = endpoint.location;\n const suffix = endpoint.sourceLanguage === undefined ? '' : `:${endpoint.sourceLanguage}`;\n return `${endpoint.platform}:${path}:${line}:${column}${suffix}`;\n}\n\n/** 간선을 종류·from·to 순으로 고정한다. */\nfunction compareEdges(left: BridgeGraphEdge, right: BridgeGraphEdge): number {\n return (\n compareStrings(left.kind, right.kind) ||\n compareStrings(left.from, right.from) ||\n compareStrings(left.to, right.to)\n );\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { compareStrings } from "../compare.js";
|
|
2
|
+
import { isReceiverPlatform } from "../exchange/parse.js";
|
|
2
3
|
import { hasPreflightBlockers, PreflightGraphError } from "./preflight.js";
|
|
3
4
|
const VIEW_LIMIT = 20;
|
|
4
5
|
/** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */
|
|
@@ -96,6 +97,10 @@ function runtimeRoutePreview(route) {
|
|
|
96
97
|
...(route.candidateKey === undefined ? {} : { candidateKey: route.candidateKey }),
|
|
97
98
|
};
|
|
98
99
|
}
|
|
100
|
+
/** 증거 위치가 수신 측(네이티브) 플랫폼에서 온 것인지 구분한다. */
|
|
101
|
+
function isReceiverEndpoint(endpoint) {
|
|
102
|
+
return isReceiverPlatform(endpoint.platform);
|
|
103
|
+
}
|
|
99
104
|
function issuePreview(issue) {
|
|
100
105
|
const route = issue.method === undefined ? issue.channel : `${issue.channel}.${issue.method}`;
|
|
101
106
|
const message = issue.code === 'unhandled-invocation' || issue.code === 'unhandled-invocation-unverified'
|
|
@@ -104,7 +109,29 @@ function issuePreview(issue) {
|
|
|
104
109
|
? `No native registration was verified for ${route}.`
|
|
105
110
|
: issue.code === 'registration-without-creation'
|
|
106
111
|
? `Native registration has no verified channel creation for ${route}.`
|
|
107
|
-
:
|
|
112
|
+
: issue.code === 'module-import-without-export' || issue.code === 'module-import-without-export-unverified'
|
|
113
|
+
? `No native module export was verified for ${route}.`
|
|
114
|
+
: issue.code === 'module-import-without-export-optional'
|
|
115
|
+
? `No native module export was verified for ${route}, but every caller tolerates absence.`
|
|
116
|
+
: issue.code === 'module-import-mechanism-mismatch'
|
|
117
|
+
? `Observed module exports for ${route} resolve through a different bridge mechanism.`
|
|
118
|
+
: issue.code === 'component-require-without-export' || issue.code === 'component-require-without-export-unverified'
|
|
119
|
+
// Expo require가 코어 export만 관찰된 경우 error 코드지만
|
|
120
|
+
// 원인은 mechanism 불일치다 — 없다는 문구는 틀리다.
|
|
121
|
+
? issue.evidence.some(isReceiverEndpoint)
|
|
122
|
+
? `Observed component exports for ${route} resolve through a different bridge mechanism.`
|
|
123
|
+
: `No native component export was verified for ${route}.`
|
|
124
|
+
: issue.code === 'component-require-mechanism-mismatch'
|
|
125
|
+
? `Observed component exports for ${route} resolve through a different bridge mechanism.`
|
|
126
|
+
: issue.code === 'module-export-without-import'
|
|
127
|
+
? `Native module export has no verified import for ${route}.`
|
|
128
|
+
: issue.code === 'module-export-mechanism-mismatch'
|
|
129
|
+
? `Observed module imports for ${route} resolve through a different bridge mechanism.`
|
|
130
|
+
: issue.code === 'component-export-without-require'
|
|
131
|
+
? `Native component export has no verified require for ${route}.`
|
|
132
|
+
: issue.code === 'component-export-mechanism-mismatch'
|
|
133
|
+
? `Observed component requires for ${route} resolve through a different bridge mechanism.`
|
|
134
|
+
: `Native handler has no verified invocation for ${route}.`;
|
|
108
135
|
return {
|
|
109
136
|
code: issue.code, severity: issue.severity, channel: issue.channel,
|
|
110
137
|
...(issue.method === undefined ? {} : { method: issue.method }), message,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight-view.js","sourceRoot":"","sources":["../../src/report/preflight-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { compareStrings } from '../compare.ts';\nimport type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';\nimport { hasPreflightBlockers, PreflightGraphError, type PreflightAffected, type PreflightRelation, type PreflightReport, type PreflightSubject } from './preflight.ts';\nimport type { RuntimeCheckResult } from './runtime.ts';\nimport type { RuntimeVerificationReport } from './runtime.ts';\n\n/** 모든 항목 수를 보존하면서 표시 항목만 제한하는 컬렉션이다. */\nexport interface PreflightBounded<T> {\n readonly total: number;\n readonly items: readonly T[];\n readonly omitted: number;\n}\n\n/** 목록 소비자가 사용할 수 있는 작은 심볼 투영이다. */\nexport type PreflightSubjectPreview = PreflightSubject;\n\nexport interface PreflightIssuePreview {\n readonly code: string;\n readonly severity: 'error' | 'warning';\n readonly channel: string;\n readonly method?: string;\n readonly message: string;\n}\n\nexport interface PreflightLimitationPreview {\n readonly code: string;\n readonly message: string;\n readonly analysis?: string;\n}\n\nexport interface PreflightBridgeLimitationPreview {\n readonly platform: JoinLimitation['platform'];\n readonly target: JoinLimitation['target'];\n readonly tool: string;\n readonly message: string;\n readonly channels?: PreflightBounded<string>;\n}\n\nexport interface PreflightRuntimeRoutePreview {\n readonly runId: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly observedCalls: number;\n readonly staticStatus: string;\n readonly candidateKey?: string;\n}\n\nexport interface PreflightRuntimeCandidatePreview {\n readonly key: string;\n readonly channel: string;\n readonly method?: string;\n readonly transport?: 'basic-message-channel';\n readonly matching?: 'literal' | 'prefix';\n readonly handlerCount: number;\n readonly handlersOmitted: number;\n readonly handlers: PreflightBounded<BridgeEndpoint>;\n}\n\nexport interface PreflightRuntimeView {\n readonly aligned: boolean;\n readonly verification: {\n readonly status: string;\n readonly scope: string;\n readonly summary: RuntimeVerificationReport['summary'];\n readonly declaredScenarioPlatforms: number;\n readonly nonpassedChecks: PreflightBounded<PreflightRuntimeCheckPreview>;\n };\n readonly unobservedBoundaries: PreflightBounded<string>;\n readonly uncoveredBoundaries: PreflightBounded<string>;\n readonly routes: PreflightBounded<PreflightRuntimeRoutePreview>;\n readonly candidates: PreflightBounded<PreflightRuntimeCandidatePreview>;\n}\n\nexport interface PreflightRuntimeCheckPreview {\n readonly id: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly status: string;\n readonly observedCalls: number;\n}\n\n/** 원본 보고서를 변경하지 않고 정적·runtime 정보를 압축한 뷰다. */\nexport interface PreflightSummaryView {\n readonly format: 'isthmus-preflight-summary';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: PreflightReport['status'];\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly roots: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: 0 }>;\n readonly affected: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: number }>;\n readonly reviewFiles: PreflightBounded<string>;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly producers: PreflightBounded<PreflightReport['producers'][number]>;\n readonly runtime?: PreflightRuntimeView;\n}\n\ninterface PreflightPathStep {\n readonly subject: PreflightSubjectPreview;\n readonly depth: number;\n readonly relations: PreflightBounded<PreflightRelationPreview>;\n}\n\ntype PreflightRelationPreview =\n | { readonly kind: 'language'; readonly analysis: string; readonly relationships: PreflightBounded<string> }\n | Exclude<PreflightRelation, { readonly kind: 'language' }>;\n\nexport interface PreflightExplanationView {\n readonly format: 'isthmus-preflight-explanation';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: 'found' | 'notFound' | 'ambiguous';\n readonly selector: string;\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly runtime?: PreflightRuntimeView;\n readonly result?: { readonly subject: PreflightSubjectPreview; readonly path: readonly PreflightPathStep[] };\n readonly candidates?: PreflightBounded<{ readonly key: string; readonly subject: PreflightSubjectPreview }>;\n}\n\nconst VIEW_LIMIT = 20;\n\n/** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */\nexport function createPreflightSummary(report: PreflightReport, limit = VIEW_LIMIT): PreflightSummaryView {\n assertLimit(limit);\n const view = commonView(report, limit);\n return {\n format: 'isthmus-preflight-summary', version: 1,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false, status: report.status, summary: report.summary,\n requiresReview: requiresReview(report),\n roots: bounded(sortedRoots(report.roots).map((subject) => ({ subject, depth: 0 as const })), limit),\n affected: bounded(sortedAffected(report.affected).map(({ subject, depth }) => ({ subject, depth })), limit),\n ...view,\n };\n}\n\n/** 정확히 일치하는 심볼을 설명하고, 찾으면 root부터의 전체 경로를 제공한다. */\nexport function createPreflightExplanation(report: PreflightReport, selector: string): PreflightExplanationView {\n const limit = VIEW_LIMIT;\n const view = commonView(report, limit);\n const subjects = allSubjects(report);\n const matches = matchingSubjects(subjects, selector);\n const base = {\n format: 'isthmus-preflight-explanation' as const, version: 1 as const,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false as const, selector, summary: report.summary,\n requiresReview: requiresReview(report), ...view,\n };\n if (matches.length === 0) return { ...base, status: 'notFound' };\n const candidates = bounded(matches.map(({ subject }) => ({ key: subject.key, subject })), limit);\n if (matches.length !== 1) return { ...base, status: 'ambiguous', candidates };\n const target = matches[0]!.subject;\n return { ...base, status: 'found', result: { subject: target, path: pathFor(report, target.key) } };\n}\n\nfunction commonView(report: PreflightReport, limit: number): Pick<PreflightSummaryView, 'reviewFiles' | 'issues' | 'limitations' | 'bridgeLimitations' | 'messageLimitations' | 'producers' | 'runtime'> {\n return {\n reviewFiles: bounded([...report.reviewFiles].sort(compareStrings), limit),\n issues: bounded([...report.issues].sort(compareIssues).map(issuePreview), limit),\n limitations: bounded([...report.limitations].sort(compareLimitations).map(({ code, message, analysis }) => ({\n code, message, ...(analysis === undefined ? {} : { analysis }),\n })), limit),\n bridgeLimitations: bounded([...report.bridgeLimitations].sort(compareBridgeLimitations).map((limitation) => ({\n platform: limitation.platform, target: limitation.target, tool: limitation.tool, message: limitation.message,\n ...(limitation.channels === undefined ? {} : { channels: bounded([...limitation.channels].sort(compareStrings), limit) }),\n })), limit),\n ...(report.messageLimitations === undefined ? {} : { messageLimitations: bounded([...report.messageLimitations]\n .sort(compareBridgeLimitations).map(({ platform, target, tool, message }) => ({ platform, target, tool, message })), limit) }),\n producers: bounded([...report.producers].sort((a, b) => compareStrings(a.analysis, b.analysis) || compareStrings(a.platform, b.platform)), limit),\n ...(report.runtime === undefined ? {} : { runtime: runtimeView(report, limit) }),\n };\n}\n\nfunction runtimeView(report: PreflightReport, limit: number): PreflightRuntimeView {\n const runtime = report.runtime!;\n const checks = runtime.verification.checks.filter(({ status }) => status !== 'passed');\n const pairs = new Set(runtime.verification.checks.map(({ expected }) => JSON.stringify([expected.scenario, expected.platform])));\n return {\n aligned: runtime.aligned,\n verification: {\n status: runtime.verification.status, scope: runtime.verification.scope,\n summary: runtime.verification.summary,\n declaredScenarioPlatforms: pairs.size,\n nonpassedChecks: bounded(checks.map(runtimeCheckPreview).sort(compareRuntimeChecks), limit),\n },\n unobservedBoundaries: bounded([...runtime.unobservedBoundaries].sort(compareStrings), limit),\n uncoveredBoundaries: bounded([...runtime.uncoveredBoundaries].sort(compareStrings), limit),\n routes: bounded(runtime.routes.map(runtimeRoutePreview).sort(compareRuntimeRoutes), limit),\n candidates: bounded(runtime.candidates.map((candidate) => ({\n key: candidate.key, channel: candidate.channel, ...(candidate.method === undefined ? {} : { method: candidate.method }),\n ...(candidate.transport === undefined ? {} : { transport: candidate.transport, matching: candidate.matching! }),\n handlerCount: candidate.handlers.length + candidate.handlersOmitted, handlersOmitted: candidate.handlersOmitted,\n handlers: { total: candidate.handlers.length + candidate.handlersOmitted,\n items: candidate.handlers.slice(0, limit),\n omitted: candidate.handlers.length + candidate.handlersOmitted - Math.min(candidate.handlers.length, limit) },\n })).sort((a, b) => compareStrings(a.key, b.key)), limit),\n };\n}\n\nfunction runtimeCheckPreview(check: RuntimeCheckResult): PreflightRuntimeCheckPreview {\n const expected = check.expected;\n return {\n id: expected.id, scenario: expected.scenario, platform: expected.platform,\n transport: expected.transport, channel: expected.channel,\n ...(expected.method === undefined ? {} : { method: expected.method }),\n ...(expected.instance === undefined ? {} : { instance: expected.instance }),\n status: check.status, observedCalls: check.observedCalls,\n };\n}\n\nfunction runtimeRoutePreview(route: NonNullable<PreflightReport['runtime']>['routes'][number]): PreflightRuntimeRoutePreview {\n return {\n runId: route.runId, scenario: route.scenario, platform: route.platform, transport: route.transport,\n channel: route.channel, ...(route.method === undefined ? {} : { method: route.method }),\n ...(route.instance === undefined ? {} : { instance: route.instance }),\n observedCalls: route.observedCalls, staticStatus: route.staticStatus,\n ...(route.candidateKey === undefined ? {} : { candidateKey: route.candidateKey }),\n };\n}\n\nfunction issuePreview(issue: PreflightReport['issues'][number]): PreflightIssuePreview {\n const route = issue.method === undefined ? issue.channel : `${issue.channel}.${issue.method}`;\n const message = issue.code === 'unhandled-invocation' || issue.code === 'unhandled-invocation-unverified'\n ? `No native handler was verified for ${route}.`\n : issue.code === 'unregistered-channel-creation' || issue.code === 'unregistered-channel-creation-unverified'\n ? `No native registration was verified for ${route}.`\n : issue.code === 'registration-without-creation'\n ? `Native registration has no verified channel creation for ${route}.`\n : `Native handler has no verified invocation for ${route}.`;\n return {\n code: issue.code, severity: issue.severity, channel: issue.channel,\n ...(issue.method === undefined ? {} : { method: issue.method }), message,\n };\n}\n\nfunction pathFor(report: PreflightReport, targetKey: string): PreflightPathStep[] {\n const roots = new Map(report.roots.map((subject) => [subject.key, subject]));\n const affected = new Map(report.affected.map((item) => [item.subject.key, item]));\n const steps: PreflightPathStep[] = [];\n const seen = new Set<string>();\n let reachedRoot = false;\n let key: string | undefined = targetKey;\n while (key !== undefined) {\n if (seen.has(key)) throw new PreflightGraphError('Preflight explanation encountered a cyclic path.');\n seen.add(key);\n const root = roots.get(key);\n if (root !== undefined) {\n steps.push({ subject: root, depth: 0, relations: bounded([], VIEW_LIMIT) });\n reachedRoot = true;\n break;\n }\n const item = affected.get(key);\n if (item === undefined) throw new PreflightGraphError('Preflight explanation refers to an unknown path node.');\n steps.push({ subject: item.subject, depth: item.depth, relations: relationPreview(item.relations, VIEW_LIMIT) });\n key = item.via;\n }\n if (!reachedRoot) {\n throw new PreflightGraphError('Preflight explanation could not find a root path.');\n }\n return steps.reverse();\n}\n\nfunction relationPreview(relations: readonly PreflightRelation[], limit: number): PreflightBounded<PreflightRelationPreview> {\n return bounded(relations.map((relation) => relation.kind === 'language'\n ? { kind: 'language' as const, analysis: relation.analysis, relationships: bounded([...relation.relationships].sort(compareStrings), limit) }\n : relation), limit);\n}\n\nfunction allSubjects(report: PreflightReport): Array<{ subject: PreflightSubject; index: number }> {\n const values = [...report.roots, ...report.affected.map(({ subject }) => subject)];\n const unique = new Map<string, { subject: PreflightSubject; index: number }>();\n values.forEach((subject, index) => { if (!unique.has(subject.key)) unique.set(subject.key, { subject, index }); });\n return [...unique.values()].sort((a, b) => compareStrings(a.subject.key, b.subject.key) || a.index - b.index);\n}\n\nfunction matchingSubjects(subjects: readonly { subject: PreflightSubject; index: number }[], selector: string): Array<{ subject: PreflightSubject; index: number }> {\n const keys = subjects.filter(({ subject }) => subject.key === selector);\n if (keys.length > 0) return keys;\n const ids = subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.id === selector);\n if (ids.length > 0) return ids;\n return subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.qualifiedName === selector);\n}\n\nfunction sortedRoots(subjects: readonly PreflightSubject[]): PreflightSubject[] { return [...subjects].sort((a, b) => compareStrings(a.key, b.key)); }\nfunction sortedAffected(affected: readonly PreflightAffected[]): PreflightAffected[] {\n return [...affected].sort((a, b) => a.depth - b.depth || compareStrings(a.subject.key, b.subject.key));\n}\n\nfunction bounded<T>(items: readonly T[], limit: number): PreflightBounded<T> {\n return { total: items.length, items: items.slice(0, limit), omitted: Math.max(0, items.length - limit) };\n}\n\nfunction assertLimit(limit: number): asserts limit is number {\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new RangeError('Preflight view limit must be an integer from 1 to 100.');\n}\n\nfunction requiresReview(report: PreflightReport): boolean {\n return hasPreflightBlockers(report);\n}\n\nfunction compareIssues(a: PreflightReport['issues'][number], b: PreflightReport['issues'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.severity, b.severity);\n}\nfunction compareLimitations(a: PreflightReport['limitations'][number], b: PreflightReport['limitations'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.analysis ?? '', b.analysis ?? '') || compareStrings(a.message, b.message);\n}\nfunction compareBridgeLimitations(a: JoinLimitation, b: JoinLimitation): number {\n return compareStrings(a.platform, b.platform) || compareStrings(a.target ?? '', b.target ?? '') || compareStrings(a.tool, b.tool) || compareStrings(a.message, b.message);\n}\nfunction compareRuntimeChecks(a: PreflightRuntimeCheckPreview, b: PreflightRuntimeCheckPreview): number { return compareStrings(a.id, b.id); }\nfunction compareRuntimeRoutes(a: PreflightRuntimeRoutePreview, b: PreflightRuntimeRoutePreview): number {\n return compareStrings(a.runId, b.runId) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.instance ?? '', b.instance ?? '');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"preflight-view.js","sourceRoot":"","sources":["../../src/report/preflight-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { compareStrings } from '../compare.ts';\nimport { isReceiverPlatform } from '../exchange/parse.ts';\nimport type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';\nimport { hasPreflightBlockers, PreflightGraphError, type PreflightAffected, type PreflightRelation, type PreflightReport, type PreflightSubject } from './preflight.ts';\nimport type { RuntimeCheckResult } from './runtime.ts';\nimport type { RuntimeVerificationReport } from './runtime.ts';\n\n/** 모든 항목 수를 보존하면서 표시 항목만 제한하는 컬렉션이다. */\nexport interface PreflightBounded<T> {\n readonly total: number;\n readonly items: readonly T[];\n readonly omitted: number;\n}\n\n/** 목록 소비자가 사용할 수 있는 작은 심볼 투영이다. */\nexport type PreflightSubjectPreview = PreflightSubject;\n\nexport interface PreflightIssuePreview {\n readonly code: string;\n readonly severity: 'error' | 'warning';\n readonly channel: string;\n readonly method?: string;\n readonly message: string;\n}\n\nexport interface PreflightLimitationPreview {\n readonly code: string;\n readonly message: string;\n readonly analysis?: string;\n}\n\nexport interface PreflightBridgeLimitationPreview {\n readonly platform: JoinLimitation['platform'];\n readonly target: JoinLimitation['target'];\n readonly tool: string;\n readonly message: string;\n readonly channels?: PreflightBounded<string>;\n}\n\nexport interface PreflightRuntimeRoutePreview {\n readonly runId: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly observedCalls: number;\n readonly staticStatus: string;\n readonly candidateKey?: string;\n}\n\nexport interface PreflightRuntimeCandidatePreview {\n readonly key: string;\n readonly channel: string;\n readonly method?: string;\n readonly transport?: 'basic-message-channel';\n readonly matching?: 'literal' | 'prefix';\n readonly handlerCount: number;\n readonly handlersOmitted: number;\n readonly handlers: PreflightBounded<BridgeEndpoint>;\n}\n\nexport interface PreflightRuntimeView {\n readonly aligned: boolean;\n readonly verification: {\n readonly status: string;\n readonly scope: string;\n readonly summary: RuntimeVerificationReport['summary'];\n readonly declaredScenarioPlatforms: number;\n readonly nonpassedChecks: PreflightBounded<PreflightRuntimeCheckPreview>;\n };\n readonly unobservedBoundaries: PreflightBounded<string>;\n readonly uncoveredBoundaries: PreflightBounded<string>;\n readonly routes: PreflightBounded<PreflightRuntimeRoutePreview>;\n readonly candidates: PreflightBounded<PreflightRuntimeCandidatePreview>;\n}\n\nexport interface PreflightRuntimeCheckPreview {\n readonly id: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly status: string;\n readonly observedCalls: number;\n}\n\n/** 원본 보고서를 변경하지 않고 정적·runtime 정보를 압축한 뷰다. */\nexport interface PreflightSummaryView {\n readonly format: 'isthmus-preflight-summary';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: PreflightReport['status'];\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly roots: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: 0 }>;\n readonly affected: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: number }>;\n readonly reviewFiles: PreflightBounded<string>;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly producers: PreflightBounded<PreflightReport['producers'][number]>;\n readonly runtime?: PreflightRuntimeView;\n}\n\ninterface PreflightPathStep {\n readonly subject: PreflightSubjectPreview;\n readonly depth: number;\n readonly relations: PreflightBounded<PreflightRelationPreview>;\n}\n\ntype PreflightRelationPreview =\n | { readonly kind: 'language'; readonly analysis: string; readonly relationships: PreflightBounded<string> }\n | Exclude<PreflightRelation, { readonly kind: 'language' }>;\n\nexport interface PreflightExplanationView {\n readonly format: 'isthmus-preflight-explanation';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: 'found' | 'notFound' | 'ambiguous';\n readonly selector: string;\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly runtime?: PreflightRuntimeView;\n readonly result?: { readonly subject: PreflightSubjectPreview; readonly path: readonly PreflightPathStep[] };\n readonly candidates?: PreflightBounded<{ readonly key: string; readonly subject: PreflightSubjectPreview }>;\n}\n\nconst VIEW_LIMIT = 20;\n\n/** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */\nexport function createPreflightSummary(report: PreflightReport, limit = VIEW_LIMIT): PreflightSummaryView {\n assertLimit(limit);\n const view = commonView(report, limit);\n return {\n format: 'isthmus-preflight-summary', version: 1,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false, status: report.status, summary: report.summary,\n requiresReview: requiresReview(report),\n roots: bounded(sortedRoots(report.roots).map((subject) => ({ subject, depth: 0 as const })), limit),\n affected: bounded(sortedAffected(report.affected).map(({ subject, depth }) => ({ subject, depth })), limit),\n ...view,\n };\n}\n\n/** 정확히 일치하는 심볼을 설명하고, 찾으면 root부터의 전체 경로를 제공한다. */\nexport function createPreflightExplanation(report: PreflightReport, selector: string): PreflightExplanationView {\n const limit = VIEW_LIMIT;\n const view = commonView(report, limit);\n const subjects = allSubjects(report);\n const matches = matchingSubjects(subjects, selector);\n const base = {\n format: 'isthmus-preflight-explanation' as const, version: 1 as const,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false as const, selector, summary: report.summary,\n requiresReview: requiresReview(report), ...view,\n };\n if (matches.length === 0) return { ...base, status: 'notFound' };\n const candidates = bounded(matches.map(({ subject }) => ({ key: subject.key, subject })), limit);\n if (matches.length !== 1) return { ...base, status: 'ambiguous', candidates };\n const target = matches[0]!.subject;\n return { ...base, status: 'found', result: { subject: target, path: pathFor(report, target.key) } };\n}\n\nfunction commonView(report: PreflightReport, limit: number): Pick<PreflightSummaryView, 'reviewFiles' | 'issues' | 'limitations' | 'bridgeLimitations' | 'messageLimitations' | 'producers' | 'runtime'> {\n return {\n reviewFiles: bounded([...report.reviewFiles].sort(compareStrings), limit),\n issues: bounded([...report.issues].sort(compareIssues).map(issuePreview), limit),\n limitations: bounded([...report.limitations].sort(compareLimitations).map(({ code, message, analysis }) => ({\n code, message, ...(analysis === undefined ? {} : { analysis }),\n })), limit),\n bridgeLimitations: bounded([...report.bridgeLimitations].sort(compareBridgeLimitations).map((limitation) => ({\n platform: limitation.platform, target: limitation.target, tool: limitation.tool, message: limitation.message,\n ...(limitation.channels === undefined ? {} : { channels: bounded([...limitation.channels].sort(compareStrings), limit) }),\n })), limit),\n ...(report.messageLimitations === undefined ? {} : { messageLimitations: bounded([...report.messageLimitations]\n .sort(compareBridgeLimitations).map(({ platform, target, tool, message }) => ({ platform, target, tool, message })), limit) }),\n producers: bounded([...report.producers].sort((a, b) => compareStrings(a.analysis, b.analysis) || compareStrings(a.platform, b.platform)), limit),\n ...(report.runtime === undefined ? {} : { runtime: runtimeView(report, limit) }),\n };\n}\n\nfunction runtimeView(report: PreflightReport, limit: number): PreflightRuntimeView {\n const runtime = report.runtime!;\n const checks = runtime.verification.checks.filter(({ status }) => status !== 'passed');\n const pairs = new Set(runtime.verification.checks.map(({ expected }) => JSON.stringify([expected.scenario, expected.platform])));\n return {\n aligned: runtime.aligned,\n verification: {\n status: runtime.verification.status, scope: runtime.verification.scope,\n summary: runtime.verification.summary,\n declaredScenarioPlatforms: pairs.size,\n nonpassedChecks: bounded(checks.map(runtimeCheckPreview).sort(compareRuntimeChecks), limit),\n },\n unobservedBoundaries: bounded([...runtime.unobservedBoundaries].sort(compareStrings), limit),\n uncoveredBoundaries: bounded([...runtime.uncoveredBoundaries].sort(compareStrings), limit),\n routes: bounded(runtime.routes.map(runtimeRoutePreview).sort(compareRuntimeRoutes), limit),\n candidates: bounded(runtime.candidates.map((candidate) => ({\n key: candidate.key, channel: candidate.channel, ...(candidate.method === undefined ? {} : { method: candidate.method }),\n ...(candidate.transport === undefined ? {} : { transport: candidate.transport, matching: candidate.matching! }),\n handlerCount: candidate.handlers.length + candidate.handlersOmitted, handlersOmitted: candidate.handlersOmitted,\n handlers: { total: candidate.handlers.length + candidate.handlersOmitted,\n items: candidate.handlers.slice(0, limit),\n omitted: candidate.handlers.length + candidate.handlersOmitted - Math.min(candidate.handlers.length, limit) },\n })).sort((a, b) => compareStrings(a.key, b.key)), limit),\n };\n}\n\nfunction runtimeCheckPreview(check: RuntimeCheckResult): PreflightRuntimeCheckPreview {\n const expected = check.expected;\n return {\n id: expected.id, scenario: expected.scenario, platform: expected.platform,\n transport: expected.transport, channel: expected.channel,\n ...(expected.method === undefined ? {} : { method: expected.method }),\n ...(expected.instance === undefined ? {} : { instance: expected.instance }),\n status: check.status, observedCalls: check.observedCalls,\n };\n}\n\nfunction runtimeRoutePreview(route: NonNullable<PreflightReport['runtime']>['routes'][number]): PreflightRuntimeRoutePreview {\n return {\n runId: route.runId, scenario: route.scenario, platform: route.platform, transport: route.transport,\n channel: route.channel, ...(route.method === undefined ? {} : { method: route.method }),\n ...(route.instance === undefined ? {} : { instance: route.instance }),\n observedCalls: route.observedCalls, staticStatus: route.staticStatus,\n ...(route.candidateKey === undefined ? {} : { candidateKey: route.candidateKey }),\n };\n}\n\n/** 증거 위치가 수신 측(네이티브) 플랫폼에서 온 것인지 구분한다. */\nfunction isReceiverEndpoint(endpoint: BridgeEndpoint): boolean {\n return isReceiverPlatform(endpoint.platform);\n}\n\nfunction issuePreview(issue: PreflightReport['issues'][number]): PreflightIssuePreview {\n const route = issue.method === undefined ? issue.channel : `${issue.channel}.${issue.method}`;\n const message = issue.code === 'unhandled-invocation' || issue.code === 'unhandled-invocation-unverified'\n ? `No native handler was verified for ${route}.`\n : issue.code === 'unregistered-channel-creation' || issue.code === 'unregistered-channel-creation-unverified'\n ? `No native registration was verified for ${route}.`\n : issue.code === 'registration-without-creation'\n ? `Native registration has no verified channel creation for ${route}.`\n : issue.code === 'module-import-without-export' || issue.code === 'module-import-without-export-unverified'\n ? `No native module export was verified for ${route}.`\n : issue.code === 'module-import-without-export-optional'\n ? `No native module export was verified for ${route}, but every caller tolerates absence.`\n : issue.code === 'module-import-mechanism-mismatch'\n ? `Observed module exports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'component-require-without-export' || issue.code === 'component-require-without-export-unverified'\n // Expo require가 코어 export만 관찰된 경우 error 코드지만\n // 원인은 mechanism 불일치다 — 없다는 문구는 틀리다.\n ? issue.evidence.some(isReceiverEndpoint)\n ? `Observed component exports for ${route} resolve through a different bridge mechanism.`\n : `No native component export was verified for ${route}.`\n : issue.code === 'component-require-mechanism-mismatch'\n ? `Observed component exports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'module-export-without-import'\n ? `Native module export has no verified import for ${route}.`\n : issue.code === 'module-export-mechanism-mismatch'\n ? `Observed module imports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'component-export-without-require'\n ? `Native component export has no verified require for ${route}.`\n : issue.code === 'component-export-mechanism-mismatch'\n ? `Observed component requires for ${route} resolve through a different bridge mechanism.`\n : `Native handler has no verified invocation for ${route}.`;\n return {\n code: issue.code, severity: issue.severity, channel: issue.channel,\n ...(issue.method === undefined ? {} : { method: issue.method }), message,\n };\n}\n\nfunction pathFor(report: PreflightReport, targetKey: string): PreflightPathStep[] {\n const roots = new Map(report.roots.map((subject) => [subject.key, subject]));\n const affected = new Map(report.affected.map((item) => [item.subject.key, item]));\n const steps: PreflightPathStep[] = [];\n const seen = new Set<string>();\n let reachedRoot = false;\n let key: string | undefined = targetKey;\n while (key !== undefined) {\n if (seen.has(key)) throw new PreflightGraphError('Preflight explanation encountered a cyclic path.');\n seen.add(key);\n const root = roots.get(key);\n if (root !== undefined) {\n steps.push({ subject: root, depth: 0, relations: bounded([], VIEW_LIMIT) });\n reachedRoot = true;\n break;\n }\n const item = affected.get(key);\n if (item === undefined) throw new PreflightGraphError('Preflight explanation refers to an unknown path node.');\n steps.push({ subject: item.subject, depth: item.depth, relations: relationPreview(item.relations, VIEW_LIMIT) });\n key = item.via;\n }\n if (!reachedRoot) {\n throw new PreflightGraphError('Preflight explanation could not find a root path.');\n }\n return steps.reverse();\n}\n\nfunction relationPreview(relations: readonly PreflightRelation[], limit: number): PreflightBounded<PreflightRelationPreview> {\n return bounded(relations.map((relation) => relation.kind === 'language'\n ? { kind: 'language' as const, analysis: relation.analysis, relationships: bounded([...relation.relationships].sort(compareStrings), limit) }\n : relation), limit);\n}\n\nfunction allSubjects(report: PreflightReport): Array<{ subject: PreflightSubject; index: number }> {\n const values = [...report.roots, ...report.affected.map(({ subject }) => subject)];\n const unique = new Map<string, { subject: PreflightSubject; index: number }>();\n values.forEach((subject, index) => { if (!unique.has(subject.key)) unique.set(subject.key, { subject, index }); });\n return [...unique.values()].sort((a, b) => compareStrings(a.subject.key, b.subject.key) || a.index - b.index);\n}\n\nfunction matchingSubjects(subjects: readonly { subject: PreflightSubject; index: number }[], selector: string): Array<{ subject: PreflightSubject; index: number }> {\n const keys = subjects.filter(({ subject }) => subject.key === selector);\n if (keys.length > 0) return keys;\n const ids = subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.id === selector);\n if (ids.length > 0) return ids;\n return subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.qualifiedName === selector);\n}\n\nfunction sortedRoots(subjects: readonly PreflightSubject[]): PreflightSubject[] { return [...subjects].sort((a, b) => compareStrings(a.key, b.key)); }\nfunction sortedAffected(affected: readonly PreflightAffected[]): PreflightAffected[] {\n return [...affected].sort((a, b) => a.depth - b.depth || compareStrings(a.subject.key, b.subject.key));\n}\n\nfunction bounded<T>(items: readonly T[], limit: number): PreflightBounded<T> {\n return { total: items.length, items: items.slice(0, limit), omitted: Math.max(0, items.length - limit) };\n}\n\nfunction assertLimit(limit: number): asserts limit is number {\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new RangeError('Preflight view limit must be an integer from 1 to 100.');\n}\n\nfunction requiresReview(report: PreflightReport): boolean {\n return hasPreflightBlockers(report);\n}\n\nfunction compareIssues(a: PreflightReport['issues'][number], b: PreflightReport['issues'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.severity, b.severity);\n}\nfunction compareLimitations(a: PreflightReport['limitations'][number], b: PreflightReport['limitations'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.analysis ?? '', b.analysis ?? '') || compareStrings(a.message, b.message);\n}\nfunction compareBridgeLimitations(a: JoinLimitation, b: JoinLimitation): number {\n return compareStrings(a.platform, b.platform) || compareStrings(a.target ?? '', b.target ?? '') || compareStrings(a.tool, b.tool) || compareStrings(a.message, b.message);\n}\nfunction compareRuntimeChecks(a: PreflightRuntimeCheckPreview, b: PreflightRuntimeCheckPreview): number { return compareStrings(a.id, b.id); }\nfunction compareRuntimeRoutes(a: PreflightRuntimeRoutePreview, b: PreflightRuntimeRoutePreview): number {\n return compareStrings(a.runId, b.runId) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.instance ?? '', b.instance ?? '');\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';
|
|
|
3
3
|
import type { BridgeTarget } from '../exchange/parse.ts';
|
|
4
4
|
import type { CheckIssue } from './check-report.ts';
|
|
5
5
|
import type { PreflightRuntimeReport } from './preflight-runtime.ts';
|
|
6
|
-
import type { BridgeHandlerDependency } from '../exchange/messages.ts';
|
|
6
|
+
import type { BridgeHandlerDependency, BridgeMessageTransport } from '../exchange/messages.ts';
|
|
7
7
|
import type { BridgeSymbol } from '../exchange/parse.ts';
|
|
8
8
|
type Language = 'dart' | 'swift' | 'kotlin';
|
|
9
9
|
/** 언어 심볼과 경계의 키 공간을 분리한다. 원래 producer ID는 symbol.id에 보존한다. */
|
|
@@ -18,7 +18,7 @@ export type PreflightSubject = {
|
|
|
18
18
|
readonly target: BridgeTarget;
|
|
19
19
|
readonly channel: string;
|
|
20
20
|
readonly method?: string;
|
|
21
|
-
readonly transport?:
|
|
21
|
+
readonly transport?: BridgeMessageTransport;
|
|
22
22
|
readonly matching?: 'literal' | 'prefix';
|
|
23
23
|
};
|
|
24
24
|
/** 실제 producer 사용 관계와 문자열 브리지 관계를 서로 다른 근거로 표시한다. */
|
|
@@ -27,12 +27,12 @@ export type PreflightRelation = {
|
|
|
27
27
|
readonly analysis: string;
|
|
28
28
|
readonly relationships: readonly string[];
|
|
29
29
|
} | {
|
|
30
|
-
readonly kind: 'bridge-message-dependency';
|
|
30
|
+
readonly kind: 'bridge-message-dependency' | 'bridge-stream-dependency' | 'bridge-method-dependency';
|
|
31
31
|
readonly evidence: BridgeEndpoint;
|
|
32
32
|
readonly dependency: Omit<BridgeHandlerDependency, 'dispatchTargets'>;
|
|
33
33
|
readonly dispatchTarget?: BridgeSymbol;
|
|
34
34
|
} | {
|
|
35
|
-
readonly kind: 'bridge-handler' | 'bridge-registration' | 'bridge-invocation' | 'bridge-creation' | 'bridge-message-send' | 'bridge-message-handler';
|
|
35
|
+
readonly kind: 'bridge-handler' | 'bridge-registration' | 'bridge-invocation' | 'bridge-creation' | 'bridge-message-send' | 'bridge-message-handler' | 'bridge-stream-listen' | 'bridge-stream-handler';
|
|
36
36
|
readonly evidence: BridgeEndpoint;
|
|
37
37
|
};
|
|
38
38
|
/** 가장 가까운 변경 씨앗까지의 선행 정점을 공유해 긴 경로 복사를 피한다. */
|
package/dist/report/preflight.js
CHANGED
|
@@ -105,51 +105,74 @@ export function createPreflightReport(context) {
|
|
|
105
105
|
];
|
|
106
106
|
const registrations = new Map(channelRecords.map((item) => [JSON.stringify([item.target, item.channel]), item.registrations]));
|
|
107
107
|
const routes = [];
|
|
108
|
-
function boundary(target, channel, method, callers, handlers, wire,
|
|
109
|
-
const key =
|
|
110
|
-
: JSON.stringify(['bridge', target,
|
|
108
|
+
function boundary(target, channel, method, callers, handlers, wire, transport) {
|
|
109
|
+
const key = transport === undefined ? JSON.stringify(['bridge', target, channel, method ?? null])
|
|
110
|
+
: JSON.stringify(['bridge', target, transport.kind, transport.matching, channel]);
|
|
111
111
|
const subject = { key, kind: 'bridge', target, channel, ...(method === undefined ? {} : { method }),
|
|
112
|
-
...(
|
|
112
|
+
...(transport === undefined ? {} : { transport: transport.kind, matching: transport.matching }) };
|
|
113
113
|
nodes.set(key, subject);
|
|
114
114
|
const route = { subject, callers, receivers: [...handlers, ...wire], callerKeys: [], receiverKeys: [],
|
|
115
115
|
missing: [], imprecise: [] };
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
const handlerKind = transport === undefined ? 'bridge-handler'
|
|
117
|
+
: transport.kind === 'event-channel' ? 'bridge-stream-handler' : 'bridge-message-handler';
|
|
118
|
+
const dependencyKind = transport === undefined ? 'bridge-method-dependency'
|
|
119
|
+
: transport.kind === 'event-channel' ? 'bridge-stream-dependency' : 'bridge-message-dependency';
|
|
120
|
+
const receiverOf = new Map();
|
|
121
|
+
for (const endpoint of [...handlers, ...wire]) {
|
|
122
|
+
const receiver = endpointKey(endpoint);
|
|
123
|
+
if (receiver === undefined)
|
|
124
|
+
route.missing.push(endpoint);
|
|
125
|
+
else
|
|
126
|
+
receiverOf.set(endpoint, receiver);
|
|
127
|
+
}
|
|
128
|
+
// 언어 심볼로 귀속 가능한 수신 사실이 전부 완전한 분기 근거를 가질 때만
|
|
129
|
+
// 등록 배선을 직접 선택 게이트로 좁힌다. Objective-C처럼 귀속 불가능한
|
|
130
|
+
// 끝점은 근거를 가질 수 없으므로 판정에서 제외하고 공백 증거로 남는다.
|
|
131
|
+
const scopedHandlers = handlers.filter((endpoint) => receiverOf.has(endpoint) && endpoint.sourceLanguage === undefined);
|
|
132
|
+
const routeScoped = scopedHandlers.length > 0 && scopedHandlers.every((endpoint) => endpoint.handlerScope?.complete === true && endpoint.dependencies !== undefined);
|
|
133
|
+
// 근거 필드를 아예 싣지 않는 예전 생산자는 분기 한계를 신고하지 않는다 —
|
|
134
|
+
// 분기 근거를 지원하는 생산자가 일부만 채웠을 때만 정밀도 공백을 알린다.
|
|
135
|
+
const anyScopeEvidence = handlers.some((endpoint) => endpoint.handlerScope !== undefined);
|
|
136
|
+
for (const endpoint of handlers) {
|
|
137
|
+
const receiver = receiverOf.get(endpoint);
|
|
138
|
+
if (receiver === undefined)
|
|
139
|
+
continue;
|
|
140
|
+
const { handlerScope, dependencies, ...evidence } = endpoint;
|
|
141
|
+
if (handlerScope?.complete === true && dependencies !== undefined) {
|
|
142
|
+
// 공통 등록·디스패치 선언은 직접 선택했을 때 전체 배선을 검토한다. 다른 분기의
|
|
143
|
+
// 호출로 선언에 도달한 경우에는 발생 위치로 구분한 사용 관계만 해당 boundary로 전파한다.
|
|
144
|
+
if (roots.has(receiver)) {
|
|
145
|
+
route.receiverKeys.push(receiver);
|
|
146
|
+
link(receiver, key, { kind: handlerKind, evidence });
|
|
122
147
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
for (const { dispatchTargets, ...dependency } of dependencies) {
|
|
135
|
-
for (const target of [dependency.symbol, ...(dispatchTargets ?? [])]) {
|
|
136
|
-
if (endpoint.platform !== 'swift' && endpoint.platform !== 'kotlin')
|
|
137
|
-
continue;
|
|
138
|
-
const dependencyKey = symbolKey(endpoint.platform, target.usr);
|
|
139
|
-
if (!nodes.has(dependencyKey))
|
|
140
|
-
continue;
|
|
141
|
-
route.receiverKeys.push(dependencyKey);
|
|
142
|
-
link(dependencyKey, key, { kind: 'bridge-message-dependency', evidence, dependency,
|
|
143
|
-
...(target === dependency.symbol ? {} : { dispatchTarget: target }) });
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
continue;
|
|
148
|
+
for (const { dispatchTargets, ...dependency } of dependencies) {
|
|
149
|
+
for (const target of [dependency.symbol, ...(dispatchTargets ?? [])]) {
|
|
150
|
+
if (endpoint.platform !== 'swift' && endpoint.platform !== 'kotlin')
|
|
151
|
+
continue;
|
|
152
|
+
const dependencyKey = symbolKey(endpoint.platform, target.usr);
|
|
153
|
+
if (!nodes.has(dependencyKey))
|
|
154
|
+
continue;
|
|
155
|
+
route.receiverKeys.push(dependencyKey);
|
|
156
|
+
link(dependencyKey, key, { kind: dependencyKind, evidence, dependency,
|
|
157
|
+
...(target === dependency.symbol ? {} : { dispatchTarget: target }) });
|
|
147
158
|
}
|
|
148
|
-
route.imprecise.push(evidence);
|
|
149
159
|
}
|
|
150
|
-
|
|
151
|
-
link(receiver, key, { kind: matching === undefined ? kind : 'bridge-message-handler', evidence: linkEvidence });
|
|
160
|
+
continue;
|
|
152
161
|
}
|
|
162
|
+
if (transport !== undefined || anyScopeEvidence)
|
|
163
|
+
route.imprecise.push(evidence);
|
|
164
|
+
route.receiverKeys.push(receiver);
|
|
165
|
+
link(receiver, key, { kind: handlerKind, evidence });
|
|
166
|
+
}
|
|
167
|
+
for (const endpoint of wire) {
|
|
168
|
+
const receiver = receiverOf.get(endpoint);
|
|
169
|
+
if (receiver === undefined)
|
|
170
|
+
continue;
|
|
171
|
+
// 분기 근거가 완전한 경로의 등록 배선은 직접 선택했을 때만 경계를 연다.
|
|
172
|
+
if (routeScoped && !roots.has(receiver))
|
|
173
|
+
continue;
|
|
174
|
+
route.receiverKeys.push(receiver);
|
|
175
|
+
link(receiver, key, { kind: 'bridge-registration', evidence: endpoint });
|
|
153
176
|
}
|
|
154
177
|
for (const endpoint of callers) {
|
|
155
178
|
const caller = endpointKey(endpoint);
|
|
@@ -158,7 +181,9 @@ export function createPreflightReport(context) {
|
|
|
158
181
|
continue;
|
|
159
182
|
}
|
|
160
183
|
route.callerKeys.push(caller);
|
|
161
|
-
link(key, caller, { kind:
|
|
184
|
+
link(key, caller, { kind: transport === undefined
|
|
185
|
+
? (method === undefined ? 'bridge-creation' : 'bridge-invocation')
|
|
186
|
+
: transport.kind === 'event-channel' ? 'bridge-stream-listen' : 'bridge-message-send', evidence: endpoint });
|
|
162
187
|
}
|
|
163
188
|
routes.push(route);
|
|
164
189
|
}
|
|
@@ -171,7 +196,7 @@ export function createPreflightReport(context) {
|
|
|
171
196
|
])
|
|
172
197
|
boundary(item.target, item.channel, item.method, item.invocations, item.handlers, registrations.get(JSON.stringify([item.target, item.channel])) ?? []);
|
|
173
198
|
for (const route of messages.routes)
|
|
174
|
-
boundary('flutter', route.channel, undefined, route.senders, route.handlers, [], route.matching);
|
|
199
|
+
boundary('flutter', route.channel, undefined, route.senders, route.handlers, [], { kind: route.transport, matching: route.matching });
|
|
175
200
|
const depths = new Map([...roots].map((key) => [key, 0]));
|
|
176
201
|
const visits = new Map();
|
|
177
202
|
const queue = [...roots].sort(compareStrings);
|
|
@@ -200,16 +225,26 @@ export function createPreflightReport(context) {
|
|
|
200
225
|
const relevant = routes.filter((route) => depths.has(route.subject.key) || route.callerKeys.some((key) => depths.has(key)) ||
|
|
201
226
|
route.receiverKeys.some((key) => depths.has(key)) || route.missing.some(({ location }) => reachedFiles.has(location.path)));
|
|
202
227
|
for (const route of relevant) {
|
|
203
|
-
if (route.subject.transport === 'basic-message-channel') {
|
|
228
|
+
if (route.subject.transport === 'basic-message-channel' || route.subject.transport === 'event-channel') {
|
|
229
|
+
const stream = route.subject.transport === 'event-channel';
|
|
204
230
|
for (const evidence of route.imprecise)
|
|
205
|
-
limits.push({ code: 'unresolved-message-handler-scope',
|
|
231
|
+
limits.push({ code: stream ? 'unresolved-stream-handler-scope' : 'unresolved-message-handler-scope',
|
|
206
232
|
message: 'Handler dependencies could not be fully attributed in the observed index; enclosing declaration impact remains conservative.', evidence });
|
|
207
233
|
if (route.subject.matching === 'prefix')
|
|
208
|
-
limits.push({ code: 'dynamic-message-address',
|
|
209
|
-
message:
|
|
234
|
+
limits.push({ code: stream ? 'dynamic-stream-address' : 'dynamic-message-address',
|
|
235
|
+
message: stream
|
|
236
|
+
? 'Event channel prefixes describe possible routes; suffix and instance wiring are not resolved.'
|
|
237
|
+
: 'Message channel prefixes describe possible routes; suffix and instance wiring are not resolved.' });
|
|
210
238
|
if (route.callers.length === 0 || route.receivers.length === 0)
|
|
211
|
-
limits.push({ code: 'unmatched-message-boundary',
|
|
212
|
-
message:
|
|
239
|
+
limits.push({ code: stream ? 'unmatched-stream-boundary' : 'unmatched-message-boundary',
|
|
240
|
+
message: stream
|
|
241
|
+
? 'A related stream boundary has no observed counterpart in the EventChannel extraction scope.'
|
|
242
|
+
: 'A related message boundary has no observed counterpart in the Basic extraction scope.' });
|
|
243
|
+
}
|
|
244
|
+
else if (route.subject.method !== undefined) {
|
|
245
|
+
for (const evidence of route.imprecise)
|
|
246
|
+
limits.push({ code: 'unresolved-method-handler-scope',
|
|
247
|
+
message: 'Method handler branches could not be fully attributed in the observed index; enclosing declaration impact remains conservative.', evidence });
|
|
213
248
|
}
|
|
214
249
|
for (const evidence of route.missing)
|
|
215
250
|
limits.push({ code: 'unresolved-bridge-binding',
|
|
@@ -253,7 +288,7 @@ export function createPreflightReport(context) {
|
|
|
253
288
|
for (const limit of joined.limitations)
|
|
254
289
|
limits.push({ code: 'bridge-limitation', message: limit.message });
|
|
255
290
|
}
|
|
256
|
-
if (relevant.some(({ subject }) => subject.transport === 'basic-message-channel')) {
|
|
291
|
+
if (relevant.some(({ subject }) => subject.transport === 'basic-message-channel' || subject.transport === 'event-channel')) {
|
|
257
292
|
for (const limit of messages.limitations)
|
|
258
293
|
limits.push({ code: 'message-producer-limitation', message: limit.message });
|
|
259
294
|
}
|