@rsconcept/domain 2.0.2 → 2.1.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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/dist/cctext/language-api.js.map +1 -1
  3. package/dist/cctext/language.d.ts +7 -4
  4. package/dist/cctext/language.js.map +1 -1
  5. package/dist/{diagnostics-D7SiHAwW.js → diagnostics-BSryP66e.js} +116 -11
  6. package/dist/diagnostics-BSryP66e.js.map +1 -0
  7. package/dist/{diagnostics-Clo3mkba.d.ts → diagnostics-Dtzgj5Q9.d.ts} +14 -5
  8. package/dist/graph/graph.d.ts +1 -1
  9. package/dist/graph/graph.js +88 -1
  10. package/dist/graph/graph.js.map +1 -1
  11. package/dist/graph/index.d.ts +1 -1
  12. package/dist/{graph-DR8rL2o3.d.ts → graph-DPOvglEm.d.ts} +10 -2
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +2 -2
  15. package/dist/library/diagnostics.d.ts +2 -2
  16. package/dist/library/diagnostics.js +2 -2
  17. package/dist/library/index.d.ts +2 -2
  18. package/dist/library/index.js +2 -2
  19. package/dist/library/oss-api.d.ts +1 -1
  20. package/dist/library/oss.d.ts +1 -1
  21. package/dist/library/rsengine.d.ts +1 -1
  22. package/dist/library/rsengine.js +1 -1
  23. package/dist/library/rsform-api.d.ts +13 -2
  24. package/dist/library/rsform-api.js +2 -2
  25. package/dist/library/rsform.d.ts +1 -1
  26. package/dist/library/rsmodel-api.d.ts +1 -1
  27. package/dist/library/rsmodel-api.js +1 -1
  28. package/dist/library/rsmodel.d.ts +1 -1
  29. package/dist/library/structure-planner.d.ts +1 -1
  30. package/dist/library/structure-planner.js +1 -1
  31. package/package.json +14 -13
  32. package/src/cctext/language-api.test.ts +5 -0
  33. package/src/cctext/language-api.ts +6 -6
  34. package/src/cctext/language.ts +3 -4
  35. package/src/graph/graph.test.ts +22 -0
  36. package/src/graph/graph.ts +105 -1
  37. package/src/index.ts +2 -0
  38. package/src/library/diagnostics.test.ts +30 -0
  39. package/src/library/diagnostics.ts +43 -2
  40. package/src/library/index.ts +2 -0
  41. package/src/library/rsform-api.test.ts +99 -3
  42. package/src/library/rsform-api.ts +147 -6
  43. package/dist/diagnostics-D7SiHAwW.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","names":[],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/**\n * Module: Custom graph data structure.\n */\n\n/** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */\nexport class GraphNode<NodeID> {\n /** Unique identifier of the node. */\n id: NodeID;\n /** List of outgoing nodes. */\n outputs: NodeID[];\n /** List of incoming nodes. */\n inputs: NodeID[];\n\n constructor(id: NodeID) {\n this.id = id;\n this.outputs = [];\n this.inputs = [];\n }\n\n clone(): GraphNode<NodeID> {\n const result = new GraphNode(this.id);\n result.outputs = [...this.outputs];\n result.inputs = [...this.inputs];\n return result;\n }\n\n addOutput(node: NodeID): void {\n this.outputs.push(node);\n }\n\n addInput(node: NodeID): void {\n this.inputs.push(node);\n }\n\n removeInput(target: NodeID): NodeID | null {\n const index = this.inputs.findIndex(node => node === target);\n return index > -1 ? this.inputs.splice(index, 1)[0] : null;\n }\n\n removeOutput(target: NodeID): NodeID | null {\n const index = this.outputs.findIndex(node => node === target);\n return index > -1 ? this.outputs.splice(index, 1)[0] : null;\n }\n}\n\n/**\n * Represents a Graph.\n *\n * This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.\n */\nexport class Graph<NodeID = number> {\n /** Map of nodes. */\n nodes = new Map<NodeID, GraphNode<NodeID>>();\n\n constructor(arr?: NodeID[][]) {\n if (!arr) {\n return;\n }\n arr.forEach(edge => {\n if (edge.length === 1) {\n this.addNode(edge[0]);\n } else {\n this.addEdge(edge[0], edge[1]);\n }\n });\n }\n\n clone(): Graph<NodeID> {\n const result = new Graph<NodeID>();\n this.nodes.forEach(node => result.nodes.set(node.id, node.clone()));\n return result;\n }\n\n at(target: NodeID): GraphNode<NodeID> | undefined {\n return this.nodes.get(target);\n }\n\n addNode(target: NodeID): GraphNode<NodeID> {\n let node = this.nodes.get(target);\n if (!node) {\n node = new GraphNode(target);\n this.nodes.set(target, node);\n }\n return node;\n }\n\n hasNode(target: NodeID): boolean {\n return !!this.nodes.get(target);\n }\n\n removeNode(target: NodeID): void {\n this.nodes.forEach(node => {\n node.removeInput(target);\n node.removeOutput(target);\n });\n this.nodes.delete(target);\n }\n\n foldNode(target: NodeID): void {\n const nodeToRemove = this.nodes.get(target);\n if (!nodeToRemove) {\n return;\n }\n nodeToRemove.inputs.forEach(input => {\n nodeToRemove.outputs.forEach(output => {\n this.addEdge(input, output);\n });\n });\n this.removeNode(target);\n }\n\n removeIsolated(): GraphNode<NodeID>[] {\n const result: GraphNode<NodeID>[] = [];\n this.nodes.forEach(node => {\n if (node.outputs.length === 0 && node.inputs.length === 0) {\n result.push(node);\n this.nodes.delete(node.id);\n }\n });\n return result;\n }\n\n addEdge(source: NodeID, destination: NodeID): void {\n if (this.hasEdge(source, destination)) {\n return;\n }\n const sourceNode = this.addNode(source);\n const destinationNode = this.addNode(destination);\n sourceNode.addOutput(destinationNode.id);\n destinationNode.addInput(sourceNode.id);\n }\n\n removeEdge(source: NodeID, destination: NodeID): void {\n const sourceNode = this.nodes.get(source);\n const destinationNode = this.nodes.get(destination);\n if (sourceNode && destinationNode) {\n sourceNode.removeOutput(destination);\n destinationNode.removeInput(source);\n }\n }\n\n hasEdge(source: NodeID, destination: NodeID): boolean {\n const sourceNode = this.nodes.get(source);\n if (!sourceNode) {\n return false;\n }\n return !!sourceNode.outputs.find(id => id === destination);\n }\n\n isReachable(source: NodeID, destination: NodeID): boolean {\n return this.expandAllOutputs([source]).includes(destination);\n }\n\n rootNodes(): NodeID[] {\n return [...this.nodes.keys()].filter(id => !this.nodes.get(id)?.inputs.length);\n }\n\n expandOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.outputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.inputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandAllOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandOutputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.outputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n expandAllInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandInputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.inputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n maximizePart(origin: NodeID[]): NodeID[] {\n const outputs: NodeID[] = this.expandAllOutputs(origin);\n const result = [...origin];\n this.topologicalOrder()\n .filter(id => outputs.includes(id))\n .forEach(id => {\n const node = this.nodes.get(id);\n if (node?.inputs.every(parent => result.includes(parent))) {\n result.push(id);\n }\n });\n return result;\n }\n\n topologicalOrder(): NodeID[] {\n const result: NodeID[] = [];\n const marked = new Set<NodeID>();\n const nodeStack: NodeID[] = [];\n this.nodes.forEach(node => {\n if (marked.has(node.id)) {\n return;\n }\n nodeStack.push(node.id);\n while (nodeStack.length > 0) {\n const item = nodeStack[nodeStack.length - 1];\n if (marked.has(item)) {\n if (!result.find(id => id === item)) {\n result.push(item);\n }\n nodeStack.pop();\n } else {\n marked.add(item);\n const itemNode = this.nodes.get(item);\n if (itemNode && itemNode.outputs.length > 0) {\n itemNode.outputs.forEach(child => {\n if (!marked.has(child)) {\n nodeStack.push(child);\n }\n });\n }\n }\n }\n });\n return result.reverse();\n }\n\n /**\n * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive\n * successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).\n */\n sortStable(target: NodeID[]): NodeID[] {\n if (target.length <= 1) {\n return [...target];\n }\n\n const reachable = this.buildTransitiveClosureForSort();\n const testSet = new Set<NodeID>();\n const result: NodeID[] = [];\n\n for (const nodeId of [...target].reverse()) {\n const nodeReachable = reachable.get(nodeId) ?? new Set<NodeID>();\n const needMove = testSet.has(nodeId);\n for (const childId of nodeReachable) {\n testSet.add(childId);\n }\n\n if (!needMove) {\n result.push(nodeId);\n continue;\n }\n\n let inserted = false;\n for (let index = 0; index < result.length; index++) {\n const parent = result[index];\n const parentReachable = reachable.get(parent) ?? new Set<NodeID>();\n if (nodeReachable.has(parent)) {\n if (parentReachable.has(nodeId)) {\n result.push(nodeId);\n } else {\n result.splice(index, 0, nodeId);\n }\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n result.push(nodeId);\n }\n }\n\n result.reverse();\n return result;\n }\n\n private buildTransitiveClosureForSort(): Map<NodeID, Set<NodeID>> {\n const closure = new Map<NodeID, Set<NodeID>>();\n for (const node of this.nodes.values()) {\n closure.set(node.id, new Set(node.outputs));\n }\n\n const order = this.topologicalOrder();\n for (const nodeId of [...order].reverse()) {\n const node = this.at(nodeId);\n if (!node) {\n continue;\n }\n const nodeClosure = closure.get(nodeId) ?? new Set<NodeID>();\n for (const parentId of node.inputs) {\n const parentClosure = closure.get(parentId) ?? new Set<NodeID>();\n for (const childId of nodeClosure) {\n parentClosure.add(childId);\n }\n closure.set(parentId, parentClosure);\n }\n }\n\n return closure;\n }\n\n transitiveReduction() {\n const order = this.topologicalOrder();\n const marked = new Map<NodeID, boolean>();\n order.forEach(nodeID => {\n if (marked.get(nodeID)) {\n return;\n }\n const stack: { id: NodeID; parents: NodeID[] }[] = [];\n stack.push({ id: nodeID, parents: [] });\n while (stack.length > 0) {\n const item = stack.splice(0, 1)[0];\n const node = this.nodes.get(item.id);\n if (node) {\n node.outputs.forEach(child => {\n item.parents.forEach(parent => this.removeEdge(parent, child));\n stack.push({ id: child, parents: [item.id, ...item.parents] });\n });\n }\n marked.set(item.id, true);\n }\n });\n }\n\n /**\n * Finds a cycle in the graph.\n *\n * @returns {NodeID[] | null} The cycle if found, otherwise `null`.\n * Uses non-recursive DFS.\n */\n findCycle(): NodeID[] | null {\n const visited = new Set<NodeID>();\n const nodeStack = new Set<NodeID>();\n const parents = new Map<NodeID, NodeID>();\n\n for (const nodeId of this.nodes.keys()) {\n if (visited.has(nodeId)) {\n continue;\n }\n\n const callStack: { nodeId: NodeID; parentId: NodeID | null }[] = [];\n callStack.push({ nodeId: nodeId, parentId: null });\n while (callStack.length > 0) {\n const { nodeId, parentId } = callStack[callStack.length - 1];\n if (visited.has(nodeId)) {\n nodeStack.delete(nodeId);\n callStack.pop();\n continue;\n }\n visited.add(nodeId);\n nodeStack.add(nodeId);\n if (parentId !== null) {\n parents.set(nodeId, parentId);\n }\n\n const currentNode = this.nodes.get(nodeId)!;\n for (const child of currentNode.outputs) {\n if (!visited.has(child)) {\n callStack.push({ nodeId: child, parentId: nodeId });\n continue;\n }\n if (!nodeStack.has(child)) {\n continue;\n }\n const cycle: NodeID[] = [];\n let current = nodeId;\n cycle.push(child);\n while (current !== child) {\n cycle.push(current);\n current = parents.get(current)!;\n }\n cycle.push(child);\n cycle.reverse();\n return cycle;\n }\n }\n }\n return null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","names":[],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/**\n * Module: Custom graph data structure.\n */\n\n/** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */\nexport class GraphNode<NodeID> {\n /** Unique identifier of the node. */\n id: NodeID;\n /** List of outgoing nodes. */\n outputs: NodeID[];\n /** List of incoming nodes. */\n inputs: NodeID[];\n\n constructor(id: NodeID) {\n this.id = id;\n this.outputs = [];\n this.inputs = [];\n }\n\n clone(): GraphNode<NodeID> {\n const result = new GraphNode(this.id);\n result.outputs = [...this.outputs];\n result.inputs = [...this.inputs];\n return result;\n }\n\n addOutput(node: NodeID): void {\n this.outputs.push(node);\n }\n\n addInput(node: NodeID): void {\n this.inputs.push(node);\n }\n\n removeInput(target: NodeID): NodeID | null {\n const index = this.inputs.findIndex(node => node === target);\n return index > -1 ? this.inputs.splice(index, 1)[0] : null;\n }\n\n removeOutput(target: NodeID): NodeID | null {\n const index = this.outputs.findIndex(node => node === target);\n return index > -1 ? this.outputs.splice(index, 1)[0] : null;\n }\n}\n\n/**\n * Represents a Graph.\n *\n * This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.\n */\nexport class Graph<NodeID = number> {\n /** Map of nodes. */\n nodes = new Map<NodeID, GraphNode<NodeID>>();\n\n constructor(arr?: NodeID[][]) {\n if (!arr) {\n return;\n }\n arr.forEach(edge => {\n if (edge.length === 1) {\n this.addNode(edge[0]);\n } else {\n this.addEdge(edge[0], edge[1]);\n }\n });\n }\n\n clone(): Graph<NodeID> {\n const result = new Graph<NodeID>();\n this.nodes.forEach(node => result.nodes.set(node.id, node.clone()));\n return result;\n }\n\n at(target: NodeID): GraphNode<NodeID> | undefined {\n return this.nodes.get(target);\n }\n\n addNode(target: NodeID): GraphNode<NodeID> {\n let node = this.nodes.get(target);\n if (!node) {\n node = new GraphNode(target);\n this.nodes.set(target, node);\n }\n return node;\n }\n\n hasNode(target: NodeID): boolean {\n return !!this.nodes.get(target);\n }\n\n removeNode(target: NodeID): void {\n this.nodes.forEach(node => {\n node.removeInput(target);\n node.removeOutput(target);\n });\n this.nodes.delete(target);\n }\n\n foldNode(target: NodeID): void {\n const nodeToRemove = this.nodes.get(target);\n if (!nodeToRemove) {\n return;\n }\n nodeToRemove.inputs.forEach(input => {\n nodeToRemove.outputs.forEach(output => {\n this.addEdge(input, output);\n });\n });\n this.removeNode(target);\n }\n\n removeIsolated(): GraphNode<NodeID>[] {\n const result: GraphNode<NodeID>[] = [];\n this.nodes.forEach(node => {\n if (node.outputs.length === 0 && node.inputs.length === 0) {\n result.push(node);\n this.nodes.delete(node.id);\n }\n });\n return result;\n }\n\n addEdge(source: NodeID, destination: NodeID): void {\n if (this.hasEdge(source, destination)) {\n return;\n }\n const sourceNode = this.addNode(source);\n const destinationNode = this.addNode(destination);\n sourceNode.addOutput(destinationNode.id);\n destinationNode.addInput(sourceNode.id);\n }\n\n removeEdge(source: NodeID, destination: NodeID): void {\n const sourceNode = this.nodes.get(source);\n const destinationNode = this.nodes.get(destination);\n if (sourceNode && destinationNode) {\n sourceNode.removeOutput(destination);\n destinationNode.removeInput(source);\n }\n }\n\n hasEdge(source: NodeID, destination: NodeID): boolean {\n const sourceNode = this.nodes.get(source);\n if (!sourceNode) {\n return false;\n }\n return !!sourceNode.outputs.find(id => id === destination);\n }\n\n isReachable(source: NodeID, destination: NodeID): boolean {\n return this.expandAllOutputs([source]).includes(destination);\n }\n\n rootNodes(): NodeID[] {\n return [...this.nodes.keys()].filter(id => !this.nodes.get(id)?.inputs.length);\n }\n\n expandOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.outputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.inputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandAllOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandOutputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.outputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n expandAllInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandInputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.inputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n maximizePart(origin: NodeID[]): NodeID[] {\n const outputs: NodeID[] = this.expandAllOutputs(origin);\n const result = [...origin];\n this.topologicalOrder()\n .filter(id => outputs.includes(id))\n .forEach(id => {\n const node = this.nodes.get(id);\n if (node?.inputs.every(parent => result.includes(parent))) {\n result.push(id);\n }\n });\n return result;\n }\n\n topologicalOrder(): NodeID[] {\n const result: NodeID[] = [];\n const marked = new Set<NodeID>();\n const nodeStack: NodeID[] = [];\n this.nodes.forEach(node => {\n if (marked.has(node.id)) {\n return;\n }\n nodeStack.push(node.id);\n while (nodeStack.length > 0) {\n const item = nodeStack[nodeStack.length - 1];\n if (marked.has(item)) {\n if (!result.find(id => id === item)) {\n result.push(item);\n }\n nodeStack.pop();\n } else {\n marked.add(item);\n const itemNode = this.nodes.get(item);\n if (itemNode && itemNode.outputs.length > 0) {\n itemNode.outputs.forEach(child => {\n if (!marked.has(child)) {\n nodeStack.push(child);\n }\n });\n }\n }\n }\n });\n return result.reverse();\n }\n\n /**\n * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive\n * successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).\n */\n sortStable(target: NodeID[]): NodeID[] {\n if (target.length <= 1) {\n return [...target];\n }\n\n const reachable = this.buildTransitiveClosureForSort();\n const testSet = new Set<NodeID>();\n const result: NodeID[] = [];\n\n for (const nodeId of [...target].reverse()) {\n const nodeReachable = reachable.get(nodeId) ?? new Set<NodeID>();\n const needMove = testSet.has(nodeId);\n for (const childId of nodeReachable) {\n testSet.add(childId);\n }\n\n if (!needMove) {\n result.push(nodeId);\n continue;\n }\n\n let inserted = false;\n for (let index = 0; index < result.length; index++) {\n const parent = result[index];\n const parentReachable = reachable.get(parent) ?? new Set<NodeID>();\n if (nodeReachable.has(parent)) {\n if (parentReachable.has(nodeId)) {\n result.push(nodeId);\n } else {\n result.splice(index, 0, nodeId);\n }\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n result.push(nodeId);\n }\n }\n\n result.reverse();\n return result;\n }\n\n private buildTransitiveClosureForSort(): Map<NodeID, Set<NodeID>> {\n const closure = new Map<NodeID, Set<NodeID>>();\n for (const node of this.nodes.values()) {\n closure.set(node.id, new Set(node.outputs));\n }\n\n const order = this.topologicalOrder();\n for (const nodeId of [...order].reverse()) {\n const node = this.at(nodeId);\n if (!node) {\n continue;\n }\n const nodeClosure = closure.get(nodeId) ?? new Set<NodeID>();\n for (const parentId of node.inputs) {\n const parentClosure = closure.get(parentId) ?? new Set<NodeID>();\n for (const childId of nodeClosure) {\n parentClosure.add(childId);\n }\n closure.set(parentId, parentClosure);\n }\n }\n\n return closure;\n }\n\n transitiveReduction() {\n const order = this.topologicalOrder();\n const marked = new Map<NodeID, boolean>();\n order.forEach(nodeID => {\n if (marked.get(nodeID)) {\n return;\n }\n const stack: { id: NodeID; parents: NodeID[] }[] = [];\n stack.push({ id: nodeID, parents: [] });\n while (stack.length > 0) {\n const item = stack.splice(0, 1)[0];\n const node = this.nodes.get(item.id);\n if (node) {\n node.outputs.forEach(child => {\n item.parents.forEach(parent => this.removeEdge(parent, child));\n stack.push({ id: child, parents: [item.id, ...item.parents] });\n });\n }\n marked.set(item.id, true);\n }\n });\n }\n\n /**\n * Finds a cycle in the graph.\n *\n * @returns {NodeID[] | null} The cycle if found, otherwise `null`.\n * Uses non-recursive DFS. The returned path is closed (first id equals last).\n */\n findCycle(): NodeID[] | null {\n const visited = new Set<NodeID>();\n const nodeStack = new Set<NodeID>();\n const parents = new Map<NodeID, NodeID>();\n\n for (const nodeId of this.nodes.keys()) {\n if (visited.has(nodeId)) {\n continue;\n }\n\n const callStack: { nodeId: NodeID; parentId: NodeID | null }[] = [];\n callStack.push({ nodeId: nodeId, parentId: null });\n while (callStack.length > 0) {\n const { nodeId, parentId } = callStack[callStack.length - 1];\n if (visited.has(nodeId)) {\n nodeStack.delete(nodeId);\n callStack.pop();\n continue;\n }\n visited.add(nodeId);\n nodeStack.add(nodeId);\n if (parentId !== null) {\n parents.set(nodeId, parentId);\n }\n\n const currentNode = this.nodes.get(nodeId)!;\n for (const child of currentNode.outputs) {\n if (!visited.has(child)) {\n callStack.push({ nodeId: child, parentId: nodeId });\n continue;\n }\n if (!nodeStack.has(child)) {\n continue;\n }\n const cycle: NodeID[] = [];\n let current = nodeId;\n cycle.push(child);\n while (current !== child) {\n cycle.push(current);\n current = parents.get(current)!;\n }\n cycle.push(child);\n cycle.reverse();\n return cycle;\n }\n }\n }\n return null;\n }\n\n /**\n * Finds one closed cycle path per cyclic strongly connected component.\n *\n * @returns Closed paths (first id equals last). Empty when the graph is acyclic.\n */\n findCycles(): NodeID[][] {\n const components = this.stronglyConnectedComponents();\n const result: NodeID[][] = [];\n for (const component of components) {\n if (component.length === 1) {\n const id = component[0];\n if (this.hasEdge(id, id)) {\n result.push([id, id]);\n }\n continue;\n }\n const subgraph = new Graph<NodeID>();\n const memberIds = new Set(component);\n for (const id of component) {\n subgraph.addNode(id);\n const node = this.nodes.get(id);\n if (!node) {\n continue;\n }\n for (const child of node.outputs) {\n if (memberIds.has(child)) {\n subgraph.addEdge(id, child);\n }\n }\n }\n const cycle = subgraph.findCycle();\n if (cycle) {\n result.push(cycle);\n }\n }\n return result;\n }\n\n /** Tarjan strongly connected components (non-recursive). */\n stronglyConnectedComponents(): NodeID[][] {\n let index = 0;\n const indices = new Map<NodeID, number>();\n const lowlink = new Map<NodeID, number>();\n const onStack = new Set<NodeID>();\n const stack: NodeID[] = [];\n const components: NodeID[][] = [];\n\n type Frame = { nodeId: NodeID; edgeIndex: number; entered: boolean };\n for (const startId of this.nodes.keys()) {\n if (indices.has(startId)) {\n continue;\n }\n const callStack: Frame[] = [{ nodeId: startId, edgeIndex: 0, entered: false }];\n while (callStack.length > 0) {\n const frame = callStack[callStack.length - 1];\n const node = this.nodes.get(frame.nodeId);\n if (!node) {\n callStack.pop();\n continue;\n }\n\n if (!frame.entered) {\n frame.entered = true;\n indices.set(frame.nodeId, index);\n lowlink.set(frame.nodeId, index);\n index += 1;\n stack.push(frame.nodeId);\n onStack.add(frame.nodeId);\n }\n\n if (frame.edgeIndex < node.outputs.length) {\n const child = node.outputs[frame.edgeIndex];\n frame.edgeIndex += 1;\n if (!indices.has(child)) {\n callStack.push({ nodeId: child, edgeIndex: 0, entered: false });\n } else if (onStack.has(child)) {\n lowlink.set(frame.nodeId, Math.min(lowlink.get(frame.nodeId)!, indices.get(child)!));\n }\n continue;\n }\n\n callStack.pop();\n if (callStack.length > 0) {\n const parentId = callStack[callStack.length - 1].nodeId;\n lowlink.set(parentId, Math.min(lowlink.get(parentId)!, lowlink.get(frame.nodeId)!));\n }\n\n if (lowlink.get(frame.nodeId) === indices.get(frame.nodeId)) {\n const component: NodeID[] = [];\n while (stack.length > 0) {\n const id = stack.pop()!;\n onStack.delete(id);\n component.push(id);\n if (id === frame.nodeId) {\n break;\n }\n }\n components.push(component);\n }\n }\n }\n return components;\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as Graph } from "../graph-DR8rL2o3.js";
1
+ import { t as Graph } from "../graph-DPOvglEm.js";
2
2
  export { Graph };
@@ -55,10 +55,18 @@ declare class Graph<NodeID = number> {
55
55
  * Finds a cycle in the graph.
56
56
  *
57
57
  * @returns {NodeID[] | null} The cycle if found, otherwise `null`.
58
- * Uses non-recursive DFS.
58
+ * Uses non-recursive DFS. The returned path is closed (first id equals last).
59
59
  */
60
60
  findCycle(): NodeID[] | null;
61
+ /**
62
+ * Finds one closed cycle path per cyclic strongly connected component.
63
+ *
64
+ * @returns Closed paths (first id equals last). Empty when the graph is acyclic.
65
+ */
66
+ findCycles(): NodeID[][];
67
+ /** Tarjan strongly connected components (non-recursive). */
68
+ stronglyConnectedComponents(): NodeID[][];
61
69
  }
62
70
  //#endregion
63
71
  export { GraphNode as n, Graph as t };
64
- //# sourceMappingURL=graph-DR8rL2o3.d.ts.map
72
+ //# sourceMappingURL=graph-DPOvglEm.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EntityReference, Grammeme, ReferenceType, SyntacticReference, TermContext, WordForm, supportedGrammemes } from "./cctext/language.js";
2
- import { t as Graph } from "./graph-DR8rL2o3.js";
2
+ import { t as Graph } from "./graph-DPOvglEm.js";
3
3
  import { r as printTree, t as CMSyntaxNode } from "./lezer-tree-iS7LpLBJ.js";
4
4
  import { a as TOKEN_ERROR, c as flattenAst, d as printAst, f as visitAstDFS, i as FlatAstNode, l as getNodeIndices, n as AstNodeBase, o as buildTree, r as FlatAST, s as findByUid, t as AstNode, u as getNodeText } from "./ast-C8sIpKdL.js";
5
5
  import { t as Branded } from "./branded-ZlzIcxzu.js";
@@ -18,9 +18,9 @@ import { n as ArgumentsType } from "./arguments-extractor-ngatANBI.js";
18
18
  import { n as applyAsciiTypeSubstitutions, r as parseTypeText } from "./typification-parser-Dytsv9CI.js";
19
19
  import { n as TypificationNodeData, t as TypificationGraph } from "./typification-graph-BY_oGT82.js";
20
20
  import { a as LibraryItemType, i as LibraryItemReference, n as CurrentVersion, o as LocationHead, r as LibraryItem, s as VersionInfo, t as AccessPolicy } from "./library-CYun28Xz.js";
21
- import { C as TypeInfo, S as Substitution, _ as CstClass, a as hasCstDiagnostic, b as RSForm, c as BasicsContext, d as RSModel, f as RSModelStats, g as Constituenta, h as Attribution, i as assignSchemaDiagnostics, l as DEFAULT_VALUE_TEXT, m as ArgumentValue, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, s as BasicBinding, t as CstDiagnostic, u as EvalStatus, v as CstStatus, x as RSFormStats, y as CstType } from "./diagnostics-Clo3mkba.js";
21
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, a as detectDependencyCycleDiagnostics, b as CstStatus, c as modelStatusCstDiagnostic, d as DEFAULT_VALUE_TEXT, f as EvalStatus, g as ArgumentValue, i as assignSchemaDiagnostics, l as BasicBinding, m as RSModelStats, n as DiagnosticKind, o as formatDependencyCycle, p as RSModel, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic, u as BasicsContext, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "./diagnostics-Dtzgj5Q9.js";
22
22
  import { FolderNode, FolderTree } from "./library/folder-tree.js";
23
23
  import { n as OssLayout, r as Position2D } from "./oss-layout-3glgAqfn.js";
24
24
  import { Block, CstSubstituteInfo, NodeType, Operation, OperationInput, OperationSchema, OperationSchemaStats, OperationSynthesis, OperationType, OssItem, SubstitutionErrorDescription, SubstitutionErrorType } from "./library/oss.js";
25
25
  import { RSEngine } from "./library/rsengine.js";
26
- export { AccessPolicy, type AnalysisBase, type AnalysisFast, type AnalysisFull, AnyTypificationT, type ArgumentValue, type ArgumentsType, type AstNode, type AstNodeBase, type Attribution, type BasicBinding, type BasicsContext, type Block, type Branded, type CMSyntaxNode, type CalculatorEvaluateOptions, type CalculatorResult, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, type EntityReference, EvalStatus, type ExpressionType, type FlatAST, type FlatAstNode, FolderNode, FolderTree, Grammeme, Graph, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, LogicT, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, type RSErrorDescription, type RSForm, type RSFormStats, RSLangAnalyzer, type RSModel, type RSModelStats, ReferenceType, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type SyntacticReference, TOKEN_ERROR, TUPLE_ID, type TermContext, TokenID, TypeClass, TypeID, type TypeInfo, type TypePath, type Typification, TypificationGraph, type TypificationNodeData, type Value, ValueClass, type ValuePath, type VersionInfo, type WordForm, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, findByUid, flattenAst, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
26
+ export { AccessPolicy, type AnalysisBase, type AnalysisFast, type AnalysisFull, AnyTypificationT, type ArgumentValue, type ArgumentsType, type AstNode, type AstNodeBase, type Attribution, type BasicBinding, type BasicsContext, type Block, type Branded, type CMSyntaxNode, type CalculatorEvaluateOptions, type CalculatorResult, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, type EntityReference, EvalStatus, type ExpressionType, type FlatAST, type FlatAstNode, FolderNode, FolderTree, Grammeme, Graph, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, LogicT, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, type RSErrorDescription, type RSForm, type RSFormStats, RSLangAnalyzer, type RSModel, type RSModelStats, ReferenceType, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type SyntacticReference, TOKEN_ERROR, TUPLE_ID, type TermContext, TokenID, TypeClass, TypeID, type TypeInfo, type TypePath, type Typification, TypificationGraph, type TypificationNodeData, type Value, ValueClass, type ValuePath, type VersionInfo, type WordForm, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, detectDependencyCycleDiagnostics, findByUid, flattenAst, formatDependencyCycle, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
package/dist/index.js CHANGED
@@ -15,10 +15,10 @@ import { RSLangAnalyzer } from "./rslang/semantic/analyzer.js";
15
15
  import { applyAsciiTypeSubstitutions, parseTypeText } from "./rslang/semantic/typification-parser.js";
16
16
  import { TypificationGraph } from "./rslang/typification-graph.js";
17
17
  import { CstClass, CstStatus, CstType } from "./library/rsform.js";
18
- import { a as modelStatusCstDiagnostic, i as hasCstDiagnostic, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind } from "./diagnostics-D7SiHAwW.js";
18
+ import { a as formatDependencyCycle, i as detectDependencyCycleDiagnostics, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind } from "./diagnostics-BSryP66e.js";
19
19
  import { DEFAULT_VALUE_TEXT, EvalStatus } from "./library/rsmodel.js";
20
20
  import { FolderNode, FolderTree } from "./library/folder-tree.js";
21
21
  import { AccessPolicy, LibraryItemType, LocationHead } from "./library/library.js";
22
22
  import { NodeType, OperationType, SubstitutionErrorType } from "./library/oss.js";
23
23
  import { RSEngine } from "./library/rsengine.js";
24
- export { AccessPolicy, AnyTypificationT, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, EvalStatus, FolderNode, FolderTree, Grammeme, Graph, LibraryItemType, LocationHead, LogicT, NodeType, OperationType, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, RSLangAnalyzer, ReferenceType, SubstitutionErrorType, TOKEN_ERROR, TUPLE_ID, TokenID, TypeClass, TypeID, TypificationGraph, ValueClass, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, findByUid, flattenAst, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
24
+ export { AccessPolicy, AnyTypificationT, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, EvalStatus, FolderNode, FolderTree, Grammeme, Graph, LibraryItemType, LocationHead, LogicT, NodeType, OperationType, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, RSLangAnalyzer, ReferenceType, SubstitutionErrorType, TOKEN_ERROR, TUPLE_ID, TokenID, TypeClass, TypeID, TypificationGraph, ValueClass, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, detectDependencyCycleDiagnostics, findByUid, flattenAst, formatDependencyCycle, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
@@ -1,2 +1,2 @@
1
- import { a as hasCstDiagnostic, i as assignSchemaDiagnostics, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, t as CstDiagnostic } from "../diagnostics-Clo3mkba.js";
2
- export { CstDiagnostic, DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic };
1
+ import { a as detectDependencyCycleDiagnostics, c as modelStatusCstDiagnostic, i as assignSchemaDiagnostics, n as DiagnosticKind, o as formatDependencyCycle, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic } from "../diagnostics-Dtzgj5Q9.js";
2
+ export { CstDiagnostic, DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic };
@@ -1,2 +1,2 @@
1
- import { a as modelStatusCstDiagnostic, i as hasCstDiagnostic, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind } from "../diagnostics-D7SiHAwW.js";
2
- export { DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic };
1
+ import { a as formatDependencyCycle, i as detectDependencyCycleDiagnostics, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind } from "../diagnostics-BSryP66e.js";
2
+ export { DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic };
@@ -1,5 +1,5 @@
1
1
  import { a as LibraryItemType, i as LibraryItemReference, n as CurrentVersion, o as LocationHead, r as LibraryItem, s as VersionInfo, t as AccessPolicy } from "../library-CYun28Xz.js";
2
- import { C as TypeInfo, S as Substitution, _ as CstClass, a as hasCstDiagnostic, b as RSForm, c as BasicsContext, d as RSModel, f as RSModelStats, g as Constituenta, h as Attribution, i as assignSchemaDiagnostics, l as DEFAULT_VALUE_TEXT, m as ArgumentValue, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, s as BasicBinding, t as CstDiagnostic, u as EvalStatus, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
2
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, a as detectDependencyCycleDiagnostics, b as CstStatus, c as modelStatusCstDiagnostic, d as DEFAULT_VALUE_TEXT, f as EvalStatus, g as ArgumentValue, i as assignSchemaDiagnostics, l as BasicBinding, m as RSModelStats, n as DiagnosticKind, o as formatDependencyCycle, p as RSModel, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic, u as BasicsContext, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "../diagnostics-Dtzgj5Q9.js";
3
3
  import { FolderNode, FolderTree } from "./folder-tree.js";
4
4
  import { n as OssLayout, r as Position2D } from "../oss-layout-3glgAqfn.js";
5
5
  import { Block, CstSubstituteInfo, NodeType, Operation, OperationInput, OperationSchema, OperationSchemaStats, OperationSynthesis, OperationType, OssItem, SubstitutionErrorDescription, SubstitutionErrorType } from "./oss.js";
@@ -99,5 +99,5 @@ declare class TemplateInstantiationPlanner {
99
99
  private collectDependencies;
100
100
  }
101
101
  //#endregion
102
- export { AccessPolicy, type ArgumentValue, type Attribution, type BasicBinding, type BasicsContext, type Block, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSDiagnosticCode, RSEngine, type RSForm, type RSFormStats, type RSModel, type RSModelStats, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type TemplateBindingConflict, type TemplateInstantiationInput, type TemplateInstantiationItem, type TemplateInstantiationPlan, TemplateInstantiationPlanner, type TypeInfo, type VersionInfo, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
102
+ export { AccessPolicy, type ArgumentValue, type Attribution, type BasicBinding, type BasicsContext, type Block, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSDiagnosticCode, RSEngine, type RSForm, type RSFormStats, type RSModel, type RSModelStats, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type TemplateBindingConflict, type TemplateInstantiationInput, type TemplateInstantiationItem, type TemplateInstantiationPlan, TemplateInstantiationPlanner, type TypeInfo, type VersionInfo, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
103
103
  //# sourceMappingURL=index.d.ts.map
@@ -5,7 +5,7 @@ import { TypeID } from "../rslang/semantic/typification.js";
5
5
  import { labelType } from "../rslang/labels.js";
6
6
  import { applyAliasMapping, isGlobalAlias, parseRSLangExpression, splitTemplateDefinition, substituteLocalAliases, substituteTemplateArgs } from "../rslang/api.js";
7
7
  import { CstClass, CstStatus, CstType } from "./rsform.js";
8
- import { D as isFunctional, a as modelStatusCstDiagnostic, c as applyMappingToConstituents, h as generateAlias, i as hasCstDiagnostic, j as normalizeExpression, l as argumentValuesToMapping, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind, w as inferTemplatedType } from "../diagnostics-D7SiHAwW.js";
8
+ import { E as inferTemplatedType, N as normalizeExpression, _ as generateAlias, a as formatDependencyCycle, d as argumentValuesToMapping, i as detectDependencyCycleDiagnostics, k as isFunctional, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind, u as applyMappingToConstituents } from "../diagnostics-BSryP66e.js";
9
9
  import { DEFAULT_VALUE_TEXT, EvalStatus } from "./rsmodel.js";
10
10
  import { FolderNode, FolderTree } from "./folder-tree.js";
11
11
  import { AccessPolicy, LibraryItemType, LocationHead } from "./library.js";
@@ -284,6 +284,6 @@ function topologicalSort(aliases, refs) {
284
284
  return sorted;
285
285
  }
286
286
  //#endregion
287
- export { AccessPolicy, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, LibraryItemType, LocationHead, NodeType, OperationType, RSDiagnosticCode, RSEngine, SubstitutionErrorType, TemplateInstantiationPlanner, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
287
+ export { AccessPolicy, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, LibraryItemType, LocationHead, NodeType, OperationType, RSDiagnosticCode, RSEngine, SubstitutionErrorType, TemplateInstantiationPlanner, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
288
288
 
289
289
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { r as LibraryItem } from "../library-CYun28Xz.js";
2
- import { S as Substitution, b as RSForm, g as Constituenta } from "../diagnostics-Clo3mkba.js";
2
+ import { S as RSForm, v as Constituenta, w as Substitution } from "../diagnostics-Dtzgj5Q9.js";
3
3
  import { NodeType, OperationSchema, SubstitutionErrorDescription } from "./oss.js";
4
4
 
5
5
  //#region src/library/oss-api.d.ts
@@ -1,4 +1,4 @@
1
- import { t as Graph } from "../graph-DR8rL2o3.js";
1
+ import { t as Graph } from "../graph-DPOvglEm.js";
2
2
  import { r as LibraryItem } from "../library-CYun28Xz.js";
3
3
  import { n as OssLayout, t as NodePosition } from "../oss-layout-3glgAqfn.js";
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { t as AstNode } from "../ast-C8sIpKdL.js";
2
2
  import { l as Value } from "../value-BduA_ZGp.js";
3
3
  import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../calculator-k8BGIKmj.js";
4
- import { b as RSForm, c as BasicsContext, d as RSModel, s as BasicBinding, u as EvalStatus, y as CstType } from "../diagnostics-Clo3mkba.js";
4
+ import { S as RSForm, f as EvalStatus, l as BasicBinding, p as RSModel, u as BasicsContext, x as CstType } from "../diagnostics-Dtzgj5Q9.js";
5
5
 
6
6
  //#region src/library/rsengine.d.ts
7
7
  /** Services for {@link RSEngine}. */
@@ -4,7 +4,7 @@ import { l as compare } from "../value-COprb2Je.js";
4
4
  import { RSCalculator } from "../rslang/eval/calculator.js";
5
5
  import "../rslang/index.js";
6
6
  import { CstType } from "./rsform.js";
7
- import { D as isFunctional, E as isBasicConcept, T as isBaseSet, g as getAnalysisFor } from "../diagnostics-D7SiHAwW.js";
7
+ import { D as isBaseSet, O as isBasicConcept, k as isFunctional, v as getAnalysisFor } from "../diagnostics-BSryP66e.js";
8
8
  import { TYPE_BASIC } from "./rsmodel.js";
9
9
  import { inferEvalStatus, isInferrable, tryFixValue } from "./rsmodel-api.js";
10
10
  //#region src/library/rsengine.ts
@@ -3,7 +3,7 @@ import { g as TypeClass, y as TypePath } from "../typification-9lNu9R4k.js";
3
3
  import { t as ValueClass } from "../value-class-CNI-lqXJ.js";
4
4
  import { r as AnalysisFull } from "../analyzer-iqAXyROE.js";
5
5
  import { r as LibraryItem } from "../library-CYun28Xz.js";
6
- import { _ as CstClass, b as RSForm, g as Constituenta, m as ArgumentValue, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
6
+ import { C as RSFormStats, S as RSForm, b as CstStatus, g as ArgumentValue, v as Constituenta, x as CstType, y as CstClass } from "../diagnostics-Dtzgj5Q9.js";
7
7
  import { AliasMapping } from "../rslang/api.js";
8
8
 
9
9
  //#region src/library/rsform-api.d.ts
@@ -82,6 +82,17 @@ declare function typeClassForCstType(cstType: CstType): TypeClass;
82
82
  declare function canHaveFormalDefinition(cstType: CstType): boolean;
83
83
  /** Analyze expression for {@link RSForm}. */
84
84
  declare function getAnalysisFor(expression: string, cstType: CstType, schema: RSForm, alias?: string): AnalysisFull;
85
+ /**
86
+ * When an untyped / bare F·P reference names a constituent on a definition cycle with the
87
+ * current expression, replace that error with {@link RSDiagnosticCode.schemaDependencyCycle}.
88
+ *
89
+ * Covers both semantic `globalNotTyped` (e.g. `F3[σ]`) and parser `globalFuncWithoutArgs`
90
+ * (bare `P1` / `F1` treated as a call without arguments).
91
+ *
92
+ * Uses a draft dependency graph: incoming edges of the edited constituent are taken from
93
+ * `expression`, so Check works before Save.
94
+ */
95
+ declare function refineAnalysisForDependencyCycles(analysis: AnalysisFull, expression: string, schema: RSForm, alias?: string): AnalysisFull;
85
96
  /** Calculate statistics for {@link RSForm}. */
86
97
  declare function calculateSchemaStats(target: RSForm): RSFormStats;
87
98
  /** Finds {@link Constituenta} by structure path. */
@@ -89,5 +100,5 @@ declare function findCstByStructure(schema: RSForm, target: Constituenta, path:
89
100
  /** Retrieves name for piece of target {@link Constituenta} structure. */
90
101
  declare function getStructureName(schema: RSForm, target: Constituenta, path: TypePath): string;
91
102
  //#endregion
92
- export { ConstituentaMappableFields, addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
103
+ export { ConstituentaMappableFields, addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, refineAnalysisForDependencyCycles, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
93
104
  //# sourceMappingURL=rsform-api.d.ts.map
@@ -1,2 +1,2 @@
1
- import { A as isTemplateCst, C as inferTemplate, D as isFunctional, E as isBasicConcept, F as validateAliasFormat, I as validateNewAlias, M as removeAliasReference, N as sortItemsForInlineSynthesis, O as isLogical, P as typeClassForCstType, S as inferStatus, T as isBaseSet, _ as getCstTypePrefix, b as inferClass, c as applyMappingToConstituents, d as canHaveFormalDefinition, f as canHaveManualTypification, g as getAnalysisFor, h as generateAlias, j as normalizeExpression, k as isSchemaIssue, l as argumentValuesToMapping, m as findCstByStructure, o as addAliasReference, p as canProduceStructure, s as applyFilterCategory, u as calculateSchemaStats, v as getStructureName, w as inferTemplatedType, x as inferNewSpawnPosition, y as guessCstType } from "../diagnostics-D7SiHAwW.js";
2
- export { addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
1
+ import { A as isLogical, C as inferNewSpawnPosition, D as isBaseSet, E as inferTemplatedType, F as removeAliasReference, I as sortItemsForInlineSynthesis, L as typeClassForCstType, M as isTemplateCst, N as normalizeExpression, O as isBasicConcept, P as refineAnalysisForDependencyCycles, R as validateAliasFormat, S as inferClass, T as inferTemplate, _ as generateAlias, b as getStructureName, c as addAliasReference, d as argumentValuesToMapping, f as calculateSchemaStats, g as findCstByStructure, h as canProduceStructure, j as isSchemaIssue, k as isFunctional, l as applyFilterCategory, m as canHaveManualTypification, p as canHaveFormalDefinition, u as applyMappingToConstituents, v as getAnalysisFor, w as inferStatus, x as guessCstType, y as getCstTypePrefix, z as validateNewAlias } from "../diagnostics-BSryP66e.js";
2
+ export { addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, refineAnalysisForDependencyCycles, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
@@ -1,2 +1,2 @@
1
- import { C as TypeInfo, S as Substitution, _ as CstClass, b as RSForm, g as Constituenta, h as Attribution, m as ArgumentValue, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
1
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, b as CstStatus, g as ArgumentValue, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "../diagnostics-Dtzgj5Q9.js";
2
2
  export { ArgumentValue, Attribution, Constituenta, CstClass, CstStatus, CstType, RSForm, RSFormStats, Substitution, TypeInfo };
@@ -1,6 +1,6 @@
1
1
  import { b as Typification, f as ExpressionType } from "../typification-9lNu9R4k.js";
2
2
  import { d as ValuePath, l as Value } from "../value-BduA_ZGp.js";
3
- import { b as RSForm, f as RSModelStats, g as Constituenta, s as BasicBinding, u as EvalStatus, y as CstType } from "../diagnostics-Clo3mkba.js";
3
+ import { S as RSForm, f as EvalStatus, l as BasicBinding, m as RSModelStats, v as Constituenta, x as CstType } from "../diagnostics-Dtzgj5Q9.js";
4
4
  import { RSEngine } from "./rsengine.js";
5
5
 
6
6
  //#region src/library/rsmodel-api.d.ts
@@ -2,7 +2,7 @@ import { TypeID } from "../rslang/semantic/typification.js";
2
2
  import { O as setNestedValue, _ as extractValue, b as isTupleValue, f as tuple, l as compare, x as makeDefaultValue } from "../value-COprb2Je.js";
3
3
  import "../rslang/index.js";
4
4
  import { CstType } from "./rsform.js";
5
- import { E as isBasicConcept, T as isBaseSet, a as modelStatusCstDiagnostic, u as calculateSchemaStats } from "../diagnostics-D7SiHAwW.js";
5
+ import { D as isBaseSet, O as isBasicConcept, f as calculateSchemaStats, s as modelStatusCstDiagnostic } from "../diagnostics-BSryP66e.js";
6
6
  import { EvalStatus } from "./rsmodel.js";
7
7
  //#region src/library/rsmodel-api.ts
8
8
  const RANDOM_INTEGER_MIN = -100;
@@ -1,2 +1,2 @@
1
- import { c as BasicsContext, d as RSModel, f as RSModelStats, l as DEFAULT_VALUE_TEXT, p as TYPE_BASIC, s as BasicBinding, u as EvalStatus } from "../diagnostics-Clo3mkba.js";
1
+ import { d as DEFAULT_VALUE_TEXT, f as EvalStatus, h as TYPE_BASIC, l as BasicBinding, m as RSModelStats, p as RSModel, u as BasicsContext } from "../diagnostics-Dtzgj5Q9.js";
2
2
  export { BasicBinding, BasicsContext, DEFAULT_VALUE_TEXT, EvalStatus, RSModel, RSModelStats, TYPE_BASIC };
@@ -1,5 +1,5 @@
1
1
  import { b as Typification, y as TypePath } from "../typification-9lNu9R4k.js";
2
- import { b as RSForm, g as Constituenta } from "../diagnostics-Clo3mkba.js";
2
+ import { S as RSForm, v as Constituenta } from "../diagnostics-Dtzgj5Q9.js";
3
3
 
4
4
  //#region src/library/structure-planner.d.ts
5
5
  /** Represents a node in the structure planner. */
@@ -3,7 +3,7 @@ import { labelType } from "../rslang/labels.js";
3
3
  import { splitTemplateDefinition } from "../rslang/api.js";
4
4
  import "../rslang/index.js";
5
5
  import { CstType } from "./rsform.js";
6
- import { m as findCstByStructure } from "../diagnostics-D7SiHAwW.js";
6
+ import { g as findCstByStructure } from "../diagnostics-BSryP66e.js";
7
7
  //#region src/library/structure-planner.ts
8
8
  /** Structure planner for {@link Constituenta}. */
9
9
  var StructurePlanner = class {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsconcept/domain",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "Shared TypeScript domain for RS language, RSForm, RSModel, RSEngine, OSS, and concept-text helpers.",
5
5
  "license": "MIT",
6
6
  "author": "IRBorisov",
@@ -154,6 +154,18 @@
154
154
  "README.md",
155
155
  "LICENSE"
156
156
  ],
157
+ "scripts": {
158
+ "generate": "lezer-generator src/rslang/parser/rslang.grammar -o src/rslang/parser/parser.ts",
159
+ "build": "tsdown",
160
+ "dev": "tsdown --watch",
161
+ "typecheck": "tsc -p tsconfig.json --noEmit",
162
+ "test": "vitest run",
163
+ "lint": "eslint . --report-unused-disable-directives --max-warnings 0",
164
+ "lintFix": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
165
+ "format": "prettier --write \"src/**/*.ts\" \"*.{ts,js}\"",
166
+ "format:check": "prettier --check \"src/**/*.ts\" \"*.{ts,js}\"",
167
+ "prepublishOnly": "pnpm run build"
168
+ },
157
169
  "dependencies": {
158
170
  "@lezer/common": "^1.5.2",
159
171
  "@lezer/lr": "^1.4.10"
@@ -174,16 +186,5 @@
174
186
  },
175
187
  "publishConfig": {
176
188
  "access": "public"
177
- },
178
- "scripts": {
179
- "generate": "lezer-generator src/rslang/parser/rslang.grammar -o src/rslang/parser/parser.ts",
180
- "build": "tsdown",
181
- "dev": "tsdown --watch",
182
- "typecheck": "tsc -p tsconfig.json --noEmit",
183
- "test": "vitest run",
184
- "lint": "eslint . --report-unused-disable-directives --max-warnings 0",
185
- "lintFix": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
186
- "format": "prettier --write \"src/**/*.ts\" \"*.{ts,js}\"",
187
- "format:check": "prettier --check \"src/**/*.ts\" \"*.{ts,js}\""
188
189
  }
189
- }
190
+ }
@@ -112,6 +112,11 @@ describe('Testing reference parsing', () => {
112
112
  expect(parseReference('@{0|derived term}')).toBeNull();
113
113
  expect(parseReference('@{-0|derived term}')).toBeNull();
114
114
  expect(parseReference('@{1|}')).toBeNull();
115
+ // Cyrillic А (U+0410) is not a syntactic offset; treat as entity alias
116
+ expect(parseReference('@{А55|sing,datv}')).toStrictEqual({
117
+ type: 'entity',
118
+ data: { entity: 'А55', tags: ['sing', 'datv'] }
119
+ });
115
120
  });
116
121
  });
117
122
 
@@ -81,7 +81,7 @@ export function parseEntityReference(text: string): EntityReference {
81
81
  if (ref?.type !== ReferenceType.ENTITY) {
82
82
  throw new Error(`Invalid entity reference: ${text}`);
83
83
  }
84
- return ref.data as EntityReference;
84
+ return ref.data;
85
85
  }
86
86
 
87
87
  /**
@@ -94,7 +94,7 @@ export function parseSyntacticReference(text: string): SyntacticReference {
94
94
  if (ref?.type !== ReferenceType.SYNTACTIC) {
95
95
  throw new Error(`Invalid syntactic reference: ${text}`);
96
96
  }
97
- return ref.data as SyntacticReference;
97
+ return ref.data;
98
98
  }
99
99
 
100
100
  /** Extracts a validated reference from string representation. */
@@ -172,12 +172,12 @@ export function resolveTextReferences(text: string, context: TermContext): strin
172
172
 
173
173
  for (const ref of references) {
174
174
  if (ref.ref.type === ReferenceType.ENTITY) {
175
- ref.resolved = resolveEntity(ref.ref.data as EntityReference, context);
175
+ ref.resolved = resolveEntity(ref.ref.data, context);
176
176
  }
177
177
  }
178
178
  references.forEach((ref, index) => {
179
179
  if (ref.ref.type === ReferenceType.SYNTACTIC) {
180
- ref.resolved = resolveSyntactic(ref.ref.data as SyntacticReference, index, references);
180
+ ref.resolved = resolveSyntactic(ref.ref.data, index, references);
181
181
  }
182
182
  });
183
183
 
@@ -196,11 +196,11 @@ export function resolveTextReferences(text: string, context: TermContext): strin
196
196
  export function referenceToString(ref: IReference): string {
197
197
  switch (ref.type) {
198
198
  case ReferenceType.ENTITY: {
199
- const entity = ref.data as EntityReference;
199
+ const entity = ref.data;
200
200
  return `@{${entity.entity}|${entity.tags.join(',')}}`;
201
201
  }
202
202
  case ReferenceType.SYNTACTIC: {
203
- const syntactic = ref.data as SyntacticReference;
203
+ const syntactic = ref.data;
204
204
  return `@{${syntactic.offset}|${syntactic.nominal}}`;
205
205
  }
206
206
  }
@@ -74,7 +74,6 @@ export interface SyntacticReference {
74
74
  }
75
75
 
76
76
  /** Represents abstract reference data. */
77
- export interface IReference {
78
- type: ReferenceType;
79
- data: EntityReference | SyntacticReference;
80
- }
77
+ export type IReference =
78
+ | { type: typeof ReferenceType.ENTITY; data: EntityReference }
79
+ | { type: typeof ReferenceType.SYNTACTIC; data: SyntacticReference };
@@ -374,6 +374,28 @@ describe('Testing Graph queries', () => {
374
374
  expect(graph.findCycle()).toStrictEqual(null);
375
375
  });
376
376
 
377
+ it('findCycles returns one closed path per cyclic SCC', () => {
378
+ const graph = new Graph([[1, 2], [2, 1], [3, 4], [4, 3], [5]]);
379
+ const cycles = graph.findCycles();
380
+ expect(cycles).toHaveLength(2);
381
+ expect(cycles.some(cycle => cycle[0] === cycle[cycle.length - 1] && cycle.includes(1) && cycle.includes(2))).toBe(
382
+ true
383
+ );
384
+ expect(cycles.some(cycle => cycle[0] === cycle[cycle.length - 1] && cycle.includes(3) && cycle.includes(4))).toBe(
385
+ true
386
+ );
387
+ });
388
+
389
+ it('findCycles reports self-loop', () => {
390
+ const graph = new Graph([[1, 1], [2]]);
391
+ expect(graph.findCycles()).toStrictEqual([[1, 1]]);
392
+ });
393
+
394
+ it('findCycles returns empty for acyclic graph', () => {
395
+ const graph = new Graph([[1, 2], [2, 3], [3]]);
396
+ expect(graph.findCycles()).toStrictEqual([]);
397
+ });
398
+
377
399
  it('sortStable should stably reorder node ids according to topological order', () => {
378
400
  const graph = new Graph([
379
401
  [1, 2],