code-node-graph 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

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.
code_node/__init__.py CHANGED
@@ -13,7 +13,7 @@ from .libraries import Library, register_library
13
13
  from .platforms import Platform, get_platform, register_platform
14
14
  from .project import EntryPoint, Project, entry_points, read_project
15
15
 
16
- __version__ = "0.2.0"
16
+ __version__ = "0.3.0"
17
17
 
18
18
  __all__ = [
19
19
  "CodeGraph",
code_node/report/style.py CHANGED
@@ -298,13 +298,27 @@ _EXTRA_CSS = """\
298
298
  .cnd .walk .ws{border-left:1px solid rgba(127,127,127,.2)}
299
299
  .cnd .walk .wch{position:sticky;top:0;z-index:2;padding:12px 16px 9px;font-size:12.5px;font-weight:650;background:var(--bg);border-bottom:1px solid rgba(127,127,127,.14)}
300
300
  .cnd .walk .wr{display:block;width:0;height:0;margin:0;border:0;padding:0;opacity:0;appearance:none;-webkit-appearance:none;pointer-events:none}
301
- .cnd .walk .wil{display:flex;align-items:center;gap:10px;min-height:30px;padding:0 14px 0 4px;cursor:pointer;white-space:nowrap;user-select:none;-webkit-user-select:none;transition:background-color .15s}
301
+ .cnd .walk .wil{display:flex;align-items:center;gap:10px;min-height:30px;padding:0 14px 0 4px;cursor:pointer;white-space:nowrap;user-select:none;-webkit-user-select:none;transition:background-color .2s,box-shadow .2s;animation:cnd-row .22s ease-out}
302
+ @keyframes cnd-row{from{opacity:0;transform:translateY(-3px)}}
303
+ .cnd .walk .wcx{position:absolute;width:0;height:0;margin:0;opacity:0;pointer-events:none}
304
+ .cnd .walk .wtg{position:relative;z-index:1;display:block;height:0}
305
+ .cnd .walk .wtg i{position:absolute;top:0;left:calc(40px + var(--d)*16px);width:16px;height:30px;border-radius:4px;cursor:pointer;opacity:.45;transition:opacity .15s,background-color .15s}
306
+ .cnd .walk .wtg i::before{content:"";position:absolute;left:5px;top:12px;width:5px;height:5px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg);transition:transform .2s cubic-bezier(.3,.7,.3,1)}
307
+ .cnd .walk .wtg:hover i{opacity:1;background:rgba(127,127,127,.14)}
308
+ .cnd .walk .wcx:checked+.wtg i{opacity:.8}
309
+ .cnd .walk .wcx:checked+.wtg i::before{transform:translate(-1px,1px) rotate(-45deg)}
310
+ .cnd .walk .wcnt{display:none;flex:none;font-size:11px;padding:0 7px;border-radius:9px;line-height:17px;background:rgba(127,127,127,.14);opacity:.75;animation:cnd-in .2s ease}
311
+ .cnd .walk .wcx:checked+.wtg+.wr+.wil .wcnt{display:inline-block}
302
312
  .cnd .walk .wil:hover{background-color:rgba(127,127,127,.08)}
303
313
  .cnd .walk .wr:checked+.wil{background-color:rgba(245,158,11,.16);box-shadow:inset 3px 0 #f59e0b}
304
314
  .cnd .walk .wr:focus-visible+.wil{outline:2px solid var(--blue);outline-offset:-2px}
305
315
  .cnd .walk .wno{flex:0 0 26px;text-align:right;font:11px var(--mono);opacity:.4;font-variant-numeric:tabular-nums}
306
- .cnd .walk .wr:checked+.wil .wno{opacity:.8}
307
- .cnd .walk .wx{display:flex;align-items:center;align-self:stretch;gap:8px;min-width:0;flex:1;padding-left:calc(var(--d)*16px);background:repeating-linear-gradient(90deg,rgba(127,127,127,.18) 0 1px,transparent 1px 16px) 5px 0/calc(var(--d)*16px) 100% no-repeat}
316
+ .cnd .walk .wr:checked+.wil .wno{opacity:.9;color:#d97706;font-weight:600}
317
+ .cnd .walk .wtx{transition:transform .2s ease}
318
+ .cnd .walk .wr:checked+.wil .wtx{transform:translateX(2px)}
319
+ .cnd .walk .wr:checked+.wil .wdot{animation:cnd-ping 1s ease-out 2}
320
+ @keyframes cnd-ping{from{box-shadow:0 0 0 0 var(--c,rgba(127,127,127,.6))}to{box-shadow:0 0 0 6px transparent}}
321
+ .cnd .walk .wx{display:flex;align-items:center;align-self:stretch;gap:8px;min-width:0;flex:1;padding-left:calc(var(--d)*16px + 18px);background:repeating-linear-gradient(90deg,rgba(127,127,127,.18) 0 1px,transparent 1px 16px) 8px 0/calc(var(--d)*16px) 100% no-repeat}
308
322
  .cnd .walk .wtx{min-width:0;overflow:hidden;text-overflow:ellipsis}
309
323
  .cnd .walk .wtx code{font:12px var(--mono);background:none;padding:0}
310
324
  .cnd .walk :is(.k-def,.k-module) .wtx b{font:650 12.5px var(--mono)}
@@ -312,7 +326,10 @@ _EXTRA_CSS = """\
312
326
  .cnd .walk .wdot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--c,rgba(127,127,127,.6))}
313
327
  .cnd .walk :is(.d-aws-reads,.d-lib-reads){--c:#3b82f6}.cnd .walk :is(.d-aws-writes,.d-lib-writes){--c:#ea580c}
314
328
  .cnd .walk :is(.d-aws-sends,.d-lib-sends,.d-http){--c:#db2777}.cnd .walk :is(.d-aws-runs,.d-lib-runs){--c:#9333ea}.cnd .walk .d-aws-signs{--c:#64748b}
315
- .cnd .walk .wc{display:none;position:absolute;left:var(--lw);right:0;top:0;height:var(--ch);box-sizing:border-box;overflow:auto;padding:14px 22px 12px;white-space:normal;cursor:auto;border-left:1px solid rgba(127,127,127,.2);border-bottom:1px solid rgba(127,127,127,.18);background:var(--bg);animation:cnd-in .18s ease}
329
+ .cnd .walk .wc{display:none;position:absolute;left:var(--lw);right:0;top:0;height:var(--ch);box-sizing:border-box;overflow:auto;padding:14px 22px 12px;white-space:normal;cursor:auto;border-left:1px solid rgba(127,127,127,.2);border-bottom:1px solid rgba(127,127,127,.18);background:var(--bg)}
330
+ .cnd .walk .wc>*{animation:cnd-in .24s ease both}
331
+ .cnd .walk .wc>.whead{animation-delay:.03s}.cnd .walk .wc>.wstk{animation-delay:.06s}.cnd .walk .wc>.wsay{animation-delay:.09s}.cnd .walk .wc>.wthen{animation-delay:.12s}
332
+ .cnd .walk .wfacts li{animation:cnd-in .24s ease both;animation-delay:.12s}.cnd .walk .wfacts li:nth-child(2){animation-delay:.15s}.cnd .walk .wfacts li:nth-child(n+3){animation-delay:.18s}
316
333
  .cnd .walk .wr:checked+.wil+.wc{display:block}
317
334
  .cnd .walk .wnav{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
318
335
  .cnd .walk .wbt{display:inline-flex;align-items:center;gap:5px;padding:4px 14px;border:1px solid rgba(127,127,127,.32);border-radius:8px;font-size:13px;font-weight:600;line-height:20px;cursor:pointer;user-select:none;-webkit-user-select:none;transition:background-color .12s,transform .06s}
@@ -348,7 +365,9 @@ _EXTRA_CSS = """\
348
365
  .cnd .walk :is(.wfm,.wfv){opacity:.6}
349
366
  .cnd .walk .wthen{margin-top:10px;font-size:12px;opacity:.6}
350
367
  .cnd .walk .wf{display:none;position:absolute;left:var(--lw);right:0;top:var(--ch);bottom:0;flex-direction:column;border-left:1px solid rgba(127,127,127,.2);background:var(--bg)}
351
- .cnd .walk .wfn>.wr:checked~.wf{display:flex}
368
+ .cnd .walk .wfn>.wr:checked~.wf{display:flex;animation:cnd-fade .25s ease}
369
+ .cnd .walk .wfh{animation:cnd-in .25s ease}
370
+ @keyframes cnd-fade{from{opacity:0}}
352
371
  .cnd .walk .wfh{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:8px 22px;font-size:12px;border-bottom:1px solid rgba(127,127,127,.12)}
353
372
  .cnd .walk .wfh b{font:650 12.5px var(--mono)}
354
373
  .cnd .walk .wfh span{opacity:.62}
@@ -356,15 +375,16 @@ _EXTRA_CSS = """\
356
375
  .cnd .walk .wfw{position:relative;flex:1;min-height:0;overflow-x:auto;overflow-y:hidden;container-type:size;background:rgba(127,127,127,.03)}
357
376
  .cnd .walk .wfp{position:relative;box-sizing:border-box;width:max-content;min-width:100%;padding:var(--pad) 0;font:12.5px/var(--lh) var(--mono);
358
377
  translate:0 min(0px,max(calc(100cqh - var(--n)*var(--lh) - 2*var(--pad)),calc(36cqh - var(--k,0)*var(--lh))));transition:translate .32s cubic-bezier(.25,.8,.25,1)}
359
- .cnd .walk .wbar{position:absolute;left:0;right:0;top:calc(var(--pad) + var(--k,-9)*var(--lh));height:var(--lh);background:rgba(245,158,11,.2);box-shadow:inset 3px 0 #f59e0b;transition:top .32s cubic-bezier(.25,.8,.25,1)}
378
+ .cnd .walk .wbar{position:absolute;left:0;right:0;top:calc(var(--pad) + var(--k,-9)*var(--lh));height:var(--lh);background:rgba(245,158,11,.2);box-shadow:inset 3px 0 #f59e0b;transition:top .32s cubic-bezier(.25,.8,.25,1);animation:cnd-glow 1.2s ease-in-out 2}
379
+ @keyframes cnd-glow{50%{background:rgba(245,158,11,.3)}}
360
380
  .cnd .walk .sl{position:relative;display:block;padding-right:16px;white-space:pre}
361
381
  .cnd .walk span.sl{opacity:.6}
362
- .cnd .walk label.sl{cursor:pointer}
382
+ .cnd .walk label.sl{cursor:pointer;transition:background-color .15s}
363
383
  .cnd .walk label.sl:hover{background:rgba(127,127,127,.1)}
364
384
  .cnd .walk .sn{display:inline-block;width:3.2em;padding-right:14px;text-align:right;opacity:.42;user-select:none;-webkit-user-select:none}
365
385
  .cnd .walk label.sl .sn{opacity:.8}
366
386
  @media (max-width:860px){.cnd .walk{--lt:40vh;grid-template-columns:minmax(0,1fr);grid-template-rows:var(--lt) 1fr;height:calc(var(--lt) + var(--ch) + 380px)}.cnd .walk .wl{max-height:none}.cnd .walk :is(.wc,.wf){left:0;border-left:0}.cnd .walk .wc{top:var(--lt);border-top:1px solid rgba(127,127,127,.2);padding:12px 16px}.cnd .walk .wf{top:calc(var(--lt) + var(--ch))}.cnd .walk .ws{border-left:0}}
367
- @media (prefers-reduced-motion:reduce){.cnd .walk .wfp,.cnd .walk .wbar,.cnd .walk .wc,.cnd .tabs>.tp{transition:none;animation:none}}"""
387
+ @media (prefers-reduced-motion:reduce){.cnd .walk :is(.wfp,.wbar,.wc,.wc>*,.wfacts li,.wil,.wtx,.wdot,.wcnt,.wf,.wfh,.wtg i,.wtg i::before),.cnd .tabs>.tp{transition:none;animation:none}}"""
368
388
 
369
389
  _CSS = _base_css(_ROOT, _EXTRA_CSS)
370
390
 
code_node/report/walk.py CHANGED
@@ -7,6 +7,11 @@ No JavaScript: each step is a radio button (one group, so once one has focus the
7
7
  Each function's steps sit in a box of their own, with the function's code drawn once at the end of it; the CSS shows
8
8
  the card after the checked button and the code of its box with sibling selectors, so the light slides from line to
9
9
  line as you step, and a step costs the same however many there are.
10
+
11
+ The list folds like a tree: a step with steps under it has a checkbox before it, and its arrow folds them away. Each
12
+ step under it carries the class `wu<step>`, so one rule per fold hides them, whether they sit beside it or inside the
13
+ box of a function it calls (`#cx5:checked ~ .wu5, #cx5:checked ~ * .wu5`). Only the steps' rows are hidden: the
14
+ current one's card and code still show when it's folded away.
10
15
  """
11
16
 
12
17
  from __future__ import annotations
@@ -523,11 +528,29 @@ def _frame_html(index: int, frame: _Frame, rows: list[tuple[int, str]]) -> str:
523
528
  )
524
529
 
525
530
 
526
- def _item_html(stops: list[_Stop], i: int, card: str) -> str:
531
+ def _folds(stops: list[_Stop]) -> tuple[list[int], list[list[int]]]:
532
+ """
533
+ How many steps sit under each stop in the list, and the stops each one sits under, outermost first.
534
+ """
535
+ under = [0] * len(stops)
536
+ above: list[list[int]] = []
537
+ opened: list[int] = []
538
+ for i, stop in enumerate(stops):
539
+ while opened and (stops[opened[-1]].depth >= stop.depth or stops[opened[-1]].chapter != stop.chapter):
540
+ opened.pop()
541
+ for j in opened:
542
+ under[j] += 1
543
+ above.append(list(opened))
544
+ opened.append(i)
545
+ return under, above
546
+
547
+
548
+ def _item_html(stops: list[_Stop], i: int, card: str, under: int = 0, above: tuple[int, ...] = ()) -> str:
527
549
  """
528
550
  A step in the list: its radio button, then its number and what it does in a few words (or, for a function it goes
529
551
  into, the function's name and file, as a heading over its steps) as the button's label, then its card, which shows
530
- (beside the list) while the button is checked.
552
+ (beside the list) while the button is checked. under: how many steps sit under it, folded away by the checkbox and
553
+ arrow before it; above: the steps it sits under, whose folds hide it.
531
554
  """
532
555
  stop = stops[i]
533
556
  step = stop.step
@@ -543,10 +566,18 @@ def _item_html(stops: list[_Stop], i: int, card: str) -> str:
543
566
  dot = f'<span class="wdot d-{said}" title="{_esc(_NOTE_TIPS.get(said, ""))}"></span>' if said in _DOTS else ""
544
567
  text = f'<span class="wtx">{headline}</span>{dot}'
545
568
  checked = " checked" if i == 0 else ""
569
+ hidden_by = "".join(f" wu{j}" for j in above)
570
+ fold = ""
571
+ if under:
572
+ fold = (
573
+ f'<input type="checkbox" class="wcx" id="cx{i}" tabindex="-1"><label class="wtg{hidden_by}" for="cx{i}" '
574
+ f'style="--d:{stop.depth}" title="Fold or unfold the {_plural(under, "step")} under it"><i></i></label>'
575
+ )
576
+ text += f'<span class="wcnt">{_plural(under, "step")}</span>'
546
577
  return (
547
- f'<input type="radio" class="wr" name="{_GROUP}" id="cw{i}"{checked}><label class="wil k-{_esc(step.kind)}" '
548
- f'for="cw{i}" style="--d:{stop.depth}"><span class="wno">{i + 1}</span><span class="wx">{text}</span>'
549
- f"</label>{card}"
578
+ f'{fold}<input type="radio" class="wr" name="{_GROUP}" id="cw{i}"{checked}><label class="wil '
579
+ f'k-{_esc(step.kind)}{hidden_by}" for="cw{i}" style="--d:{stop.depth}"><span class="wno">{i + 1}</span>'
580
+ f'<span class="wx">{text}</span></label>{card}'
550
581
  )
551
582
 
552
583
 
@@ -576,6 +607,7 @@ def _walk_html(block: _Walk, report: _Report) -> str:
576
607
  rows = _frame_rows(frame, highlighted.get(frame.file, []), stops)
577
608
  rows_of.append({number: n for n, (number, _) in enumerate(rows) if number})
578
609
  drawn.append(_frame_html(k, frame, rows))
610
+ under, above = _folds(stops)
579
611
  out: list[str] = []
580
612
  opened: list[int] = [] # the frames whose boxes are open, innermost last
581
613
  chapter = -1
@@ -593,7 +625,9 @@ def _walk_html(block: _Walk, report: _Report) -> str:
593
625
  if not opened or opened[-1] != stop.frame: # into a call
594
626
  out.append('<div class="wfn">')
595
627
  opened.append(stop.frame)
596
- out.append(_item_html(stops, i, _card_html(stops, i, first, docs, block.editor)))
628
+ out.append(_item_html(stops, i, _card_html(stops, i, first, docs, block.editor), under[i], tuple(above[i])))
629
+ if under[i]: # its fold hides the steps under it, beside it or in the boxes of what it calls
630
+ report.rules.add(f".{root} #cx{i}:checked~.wu{i},.{root} #cx{i}:checked~* .wu{i}{{display:none}}")
597
631
  at = rows_of[stop.frame].get(stop.lit)
598
632
  if at is not None: # the line its code lights
599
633
  report.rules.add(f".{root} #cw{i}:checked~.wf{stop.frame}{{--k:{at}}}")
@@ -601,7 +635,8 @@ def _walk_html(block: _Walk, report: _Report) -> str:
601
635
  out.append(drawn[opened.pop()] + "</div>")
602
636
  sub = (
603
637
  f'<div class="wsub">{_plural(len(stops), "step")}, in the order the code runs. Press Next or click a step to '
604
- "light its line in the code; after a click, <kbd>↑</kbd> <kbd>↓</kbd> move through them.</div>"
638
+ "light its line in the code; after a click, <kbd>↑</kbd> <kbd>↓</kbd> move through them. The arrow beside a "
639
+ "step folds the steps under it away.</div>"
605
640
  )
606
641
  return (
607
642
  f'{title}{sub}<div class="walk"><div class="wl" role="radiogroup" aria-label="The steps">{"".join(out)}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code-node-graph
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: See how Python code works without running it: a graph of who calls whom from an entry point, and what each path reaches.
5
5
  Project-URL: Homepage, https://github.com/utkarsh5026/code-node
6
6
  Project-URL: Documentation, https://utkarsh5026.github.io/code-node/
@@ -1,4 +1,4 @@
1
- code_node/__init__.py,sha256=sfJ6RjFtxsJMr0-zronmOKVpmXZECgEUsWBV3BKfHrA,1106
1
+ code_node/__init__.py,sha256=RGdvFZ4nq5pe5UXLWQMZaZvneTOwgLS-aGK6TqTBTG4,1106
2
2
  code_node/__main__.py,sha256=0W2bmerF1S96rjlTNJZKVzO4FvVhN6ENzAl451A08sQ,101
3
3
  code_node/cli.py,sha256=GI0vZY1t4Pf7qtZI2coTpWZi-ulQEWNREDJPkTtmxG0,12302
4
4
  code_node/pages.py,sha256=2UOrHUz3G_vAjPO89phJxhF4652FysVLgrLtJ-Iw6p4,3234
@@ -36,9 +36,9 @@ code_node/report/build.py,sha256=F0wdC0ibu3WSAenUsovUWuKwLC0vVxnNYKJVXtU5jRk,464
36
36
  code_node/report/editor.py,sha256=TRUX6BTB-oe-m5Vf3xM9PppnC99sCLL4PObXkYAGKoU,1466
37
37
  code_node/report/graph.py,sha256=YbrVWbymYUL8-KOdsDSRhD2RxCMWbGVEhHD0-MSjX1I,66832
38
38
  code_node/report/outline.py,sha256=3RRxU4FMUZKBVjFDsscKZkvDlj_W4ZeW4DwUztg4wd0,8539
39
- code_node/report/style.py,sha256=zTOZ552sasyRASnm8-P8XNzashtxHe38RkvOZTMDm24,33743
39
+ code_node/report/style.py,sha256=a5JesVQaDnqLqmqnuh-ZeayA-VZKTlUoDCPDcoUrK3M,35883
40
40
  code_node/report/tabs.py,sha256=K2XR16owfgEL1kfux61PI9nBcRsgjQurTx1ptMM5Mac,3016
41
- code_node/report/walk.py,sha256=jumSV-x1X0D614V7K0zECCSWk69OkHNR7IuDt8K4ggg,27516
41
+ code_node/report/walk.py,sha256=LWJDGJ3efF0fPWlMO4G4HBQqnNVn2RHXgLeuLrC-WnA,29466
42
42
  code_node/report/logos/README.md,sha256=8Evw8eApl_56QJrwY7LAtGgJMZE0mp0-HIpRz9bu1ME,613
43
43
  code_node/report/logos/anthropic-icon.svg,sha256=-_25zx86lfDTm-ksVXkLE4uQ_ldzLbTd3U0z-wjT-JA,302
44
44
  code_node/report/logos/aws-amplify.svg,sha256=62WXM0XCn4WrQYWcVZFz4ln62xidiqF8eO4ELlgO8hg,531
@@ -171,8 +171,8 @@ code_node/report/logos/small/aws-systems-manager.svg,sha256=9VzzFdTjaRZO9ulR8Ulp
171
171
  code_node/report/logos/small/aws-timestream.svg,sha256=yKdKIj7pbooFqDKClEQxW9h7dYV5mnDn0RCHnLUDf8Q,639
172
172
  code_node/report/logos/small/aws-waf.svg,sha256=l9ZzBZAl2g8bK1-m6A50ga37l5g1t-9Mj70bxWDykWE,591
173
173
  code_node/report/logos/small/aws-xray.svg,sha256=VKg_QtKGZKDCbZvKBRDn7eReuNVbJpduBUVV8MQrZZU,591
174
- code_node_graph-0.2.0.dist-info/METADATA,sha256=BkbfZl6ViABwgsSH4QAJoGIkbbTNyfAp6FuPyo9JJuA,7619
175
- code_node_graph-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
176
- code_node_graph-0.2.0.dist-info/entry_points.txt,sha256=eEArp-uk7ZzODIWr6l62rI0-mIA0-mLDaqJEyKikPJw,49
177
- code_node_graph-0.2.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
178
- code_node_graph-0.2.0.dist-info/RECORD,,
174
+ code_node_graph-0.3.0.dist-info/METADATA,sha256=N1ODeR5ZEpH4roWDSuYXxMNjQu_q31V2uCuYsQQyTig,7619
175
+ code_node_graph-0.3.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
176
+ code_node_graph-0.3.0.dist-info/entry_points.txt,sha256=eEArp-uk7ZzODIWr6l62rI0-mIA0-mLDaqJEyKikPJw,49
177
+ code_node_graph-0.3.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
178
+ code_node_graph-0.3.0.dist-info/RECORD,,