@neoloopy/cld-canvas 0.1.4 → 0.1.8

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.
@@ -206,6 +206,44 @@ export function emitExtra(lines, key, value, indent) {
206
206
  lines.push(`${pad}${key}: ${scalar(value)}`);
207
207
  }
208
208
  }
209
+ function emitFlowExtra(lines, value) {
210
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
211
+ emitExtra(lines, "flow", value, 0);
212
+ return;
213
+ }
214
+ const m = value;
215
+ lines.push("flow:");
216
+ if (m["from"] !== undefined)
217
+ lines.push(` from: ${scalar(m["from"])}`);
218
+ if (m["to"] !== undefined)
219
+ lines.push(` to: ${scalar(m["to"])}`);
220
+ for (const [k, v] of Object.entries(m)) {
221
+ if (k === "from" || k === "to")
222
+ continue;
223
+ emitExtra(lines, k, v, 1);
224
+ }
225
+ }
226
+ function emitSfdExtra(lines, value) {
227
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
228
+ emitExtra(lines, "sfd", value, 0);
229
+ return;
230
+ }
231
+ const m = value;
232
+ lines.push("sfd:");
233
+ if (m["x"] !== undefined) {
234
+ const x = m["x"];
235
+ lines.push(` x: ${typeof x === "number" ? numToYaml(x) : scalar(x)}`);
236
+ }
237
+ if (m["y"] !== undefined) {
238
+ const y = m["y"];
239
+ lines.push(` y: ${typeof y === "number" ? numToYaml(y) : scalar(y)}`);
240
+ }
241
+ for (const [k, v] of Object.entries(m)) {
242
+ if (k === "x" || k === "y")
243
+ continue;
244
+ emitExtra(lines, k, v, 1);
245
+ }
246
+ }
209
247
  export function serializeNote(v) {
210
248
  const lines = [FENCE];
211
249
  lines.push(`id: ${scalar(v.id)}`);
@@ -252,8 +290,14 @@ export function serializeNote(v) {
252
290
  }
253
291
  }
254
292
  }
255
- for (const [k, val] of Object.entries(v.extra))
256
- emitExtra(lines, k, val, 0);
293
+ for (const [k, val] of Object.entries(v.extra)) {
294
+ if (k === "flow")
295
+ emitFlowExtra(lines, val);
296
+ else if (k === "sfd")
297
+ emitSfdExtra(lines, val);
298
+ else
299
+ emitExtra(lines, k, val, 0);
300
+ }
257
301
  lines.push(FENCE);
258
302
  let out = lines.join("\n") + "\n";
259
303
  if (v.body.trim().length > 0)
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Conservative, renderer-facing resolution of qualitative and quantitative loops.
3
+ *
4
+ * This is deliberately not a simulation or dominance implementation. It only
5
+ * enriches a declared qualitative cycle independently when every authored leg
6
+ * maps to one exact visible connector or material pipe. It admits a synthesized
7
+ * static scalar cycle only when every equation dependency and material effect
8
+ * is equally exact. Incomplete quantitative analysis returns no synthesized
9
+ * prefix but never strips an independently resolved qualitative path.
10
+ */
11
+ import { DetectedLoop, ModelManifest, VariableFile } from "./types";
12
+ export interface CanvasLoopDiscoveryLimits {
13
+ readonly maxLoops: number;
14
+ readonly maxEdgeVisits: number;
15
+ readonly maxDepth: number;
16
+ }
17
+ export declare const USER_FACING_CANVAS_LOOP_LIMITS: CanvasLoopDiscoveryLimits;
18
+ export interface CanvasLoopDiscoveryOptions {
19
+ readonly manifest?: ModelManifest;
20
+ readonly limits?: CanvasLoopDiscoveryLimits;
21
+ }
22
+ export interface CanvasLoopDiscoveryResult {
23
+ readonly loops: DetectedLoop[];
24
+ readonly analysisError: string | null;
25
+ }
26
+ /** Stable first-class SFD pipe-leg identity. */
27
+ export declare function materialPipeLegId(flowId: string, stockId: string): string;
28
+ /** Stable base id for a non-persistent CLD projection of a material effect. */
29
+ export declare function materialProjectionEdgeId(flowId: string, stockId: string): string;
30
+ /**
31
+ * Discover complete canvas-resolvable quantitative cycles and merge them with
32
+ * exact qualitative counterparts. Declared loops are first resolved from their
33
+ * own authored topology, so a quantitative error never suppresses their honest
34
+ * CLD/SFD representation.
35
+ */
36
+ export declare function discoverCanvasLoops(nodes: readonly VariableFile[], qualitativeLoops: readonly DetectedLoop[], options?: CanvasLoopDiscoveryOptions): CanvasLoopDiscoveryResult;