Utilities/Resolve-PathGraphForJsonArray.ps1
|
# ============================================================================= # 🔁 Resolve-PathGraphForJsonArray (Declarative Signal Graph Builder) # License: MIT License • Copyright (c) 2025 Silicon Dream Artists / BDDB # Authors: Shadow PhanTom ☠️🧁👾️/🤖 • Neural Alchemist ⚗️☣️🐲 • Last Generated: 05/20/2025 # ============================================================================= # This function generates a sovereign Signal graph from a JSON array, using # declarative wire path references embedded in a scoped Signal Jacket. # # It is designed to be called within a GraphCondenser flow, where each # plan signal contains: # - A SourceWirePath: path to the array of objects to convert to signals # - A SourcesWirePath: key or path in each item that declares its linked nodes # # Each item becomes a Signal node with a `.Pointer` chain constructed from # cross-references defined in the SourcesWirePath. The graph is returned as a # result pointer in a finalized Grid structure. # # This function adheres to the SDA Doctrine of nested sovereign memory: # - Inputs are read from `%.@.Plan.*` # - Source data is accessed via `%.%` # - Output is returned in `.Result` # # All memory is recursively encapsulated, sovereign, and lineage-safe. function Resolve-PathGraphForJsonArray { param ( [Parameter(Mandatory)] [Signal]$ConductionSignal ) $opSignal = [Signal]::Start("Resolve-PathGraphForJsonArray", $ConductionSignal) | Select-Object -Last 1 ## TODO: Replace with a path discovery and cache mechanism. $plan = Resolve-PathFromDictionary -Dictionary $ConductionSignal -Path "%.%.%.@.Plan" -SignalLevel "Warning" -SignalTags @("Verbose") | Select-Object -Last 1 if (-Not $plan.HasResult()) { $plan = Resolve-PathFromDictionary -Dictionary $ConductionSignal -Path "%.@.Plan" -SignalLevel "Warning" -SignalTags @("Verbose") | Select-Object -Last 1 } if (-Not $plan.HasResult()) { $plan = Resolve-PathFromDictionary -Dictionary $ConductionSignal -Path "%.%.@.Plan" -SignalLevel "Warning" -SignalTags @("Verbose") | Select-Object -Last 1 } # Pull plan fields $sourcesKey = $plan.GetResult().SourcesWirePath $idPath = $plan.GetResult().SourcesIdentifierWirePath # Normalize template (default to '{0}') $template = $plan.GetResult().SourcesWirePathTemplate $template = if ([string]::IsNullOrWhiteSpace($template)) { '{0}' } else { $template } $isDefault = ($template -eq '{0}') # Enforce token if ($template -notmatch '\{0\}') { $opSignal.LogCritical("SourcesWirePathTemplate must contain '{0}'. Template: '$template'") return $opSignal } # Build path from template $path = [string]::Format($template, $sourcesKey) # Resolve the array at the computed path $arraySignal = Resolve-PathFromDictionary -Dictionary $ConductionSignal -Path $path | Select-Object -Last 1 if ($opSignal.MergeSignalAndVerifyFailure(@($arraySignal))) { $opSignal.LogCritical("Failed to resolve object array via SourcesWirePathTemplate. For SourcesWirePath='$sourcesKey' → '$path'") return $opSignal } # Log with tidy messaging when default template is used if ($isDefault) { $opSignal.LogInformation("✅ Sources resolved: '$path'") } else { $opSignal.LogInformation("✅ Sources resolved: '$path' (template: '$template')") } $flatArray = $arraySignal.GetResult() # Build a graph and map items by identifier $graphSignal = [Graph]::Start("Graph:$sourcesKey", $opSignal, $true) | Select-Object -Last 1 $graph = $graphSignal.GetResult() $signalMap = @{} foreach ($item in $flatArray) { $id = $item.Name if ($idPath) { $idSignal = Resolve-PathFromDictionary -Dictionary $item -Path $idPath | Select-Object -Last 1 if ($opSignal.MergeSignalAndVerifyFailure(@($idSignal))) { $opSignal.LogCritical("Failed to resolve identifier path '$idPath' for item: $($item.Name)") return $opSignal } $id = $idSignal.GetResult() } $jacketSig = [Signal]::Start("Node:$($id):Jacket", $item) $jacketSig.SetResult($item) $nodeSignal = [Signal]::Start("Node:$id", $item) | Select-Object -Last 1 $nodeSignal.SetJacket($jacketSig) $signalMap[$id] = $nodeSignal $graph.RegisterSignal($id, $nodeSignal) | Out-Null } # Link nodes using the same sources key path on each jacket # Turned off because sourcesKey doesn't find anything in jacket that matches the sources if ($sourcesKey) { foreach ($node in $signalMap.Values) { $jacket = $node.GetJacket() #$sourceSignal = Resolve-PathFromDictionary -Dictionary $jacket -Path $sourcesKey | Select-Object -Last 1 <# if ($opSignal.MergeSignalAndVerifyFailure(@($sourceSignal))) { return $opSignal.LogCritical("Could not resolve sources from key: $sourcesKey") } $sourceIds = $sourceSignal.GetResult() \ $linked = @() foreach ($srcId in $sourceIds) { if ($signalMap.ContainsKey($srcId)) { $linked += $signalMap[$srcId] } } if ($linked.Count -eq 1) { $node.SetPointer($linked[0]) } elseif ($linked.Count -gt 1) { $node.SetPointer($linked) } #> } } $graph.Finalize() $opSignal.SetResult($graph) $opSignal.LogInformation("✅ Signal graph constructed from JSON array.") return $opSignal } |