@graphlearning/shell 0.3.0 → 0.5.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.md CHANGED
@@ -50,9 +50,10 @@ import { SiteHeader } from '@graphlearning/shell'
50
50
  <SiteHeader kind="labs" actions={<ThemeToggle />} />
51
51
  ```
52
52
 
53
- `ui-graphl` is buildless vanilla and this is a React package, so the bar exists twice by necessity.
54
- One design, two implementations — **when you change one, change the other**, or they drift and the
55
- seam shows on every crossing.
53
+ The bar exists **three times** by necessity — `ui-graphl` (buildless vanilla), this package, and
54
+ `python-lab` (which hand-ports it rather than take this package as a dependency; see the invariant
55
+ in CLAUDE.md). One design, three implementations — **when you change one, change all three**, or
56
+ they drift and the seam shows on every crossing.
56
57
 
57
58
  ## The three contracts
58
59
 
@@ -118,6 +119,23 @@ They are `bin` entries, wired through each repo's `npm run`:
118
119
  | `npm run gen:desc` | video descriptions + chapters |
119
120
  | `npm run gen:audio` | the narration manifest |
120
121
 
122
+ **Capture is not realtime.** `record` and `record:reels` screencast one short window per section and
123
+ loop it over the narration (`-stream_loop`), because the only moving thing in a frame is the engine's
124
+ edge pulse and that pulse has a 2.4s period — and a pulse crosses its whole edge in exactly one
125
+ period, so one period is the whole picture. A 90-second section is captured in ~3.4s; the output's
126
+ timing is unchanged.
127
+
128
+ | env | default | what it does |
129
+ |---|---|---|
130
+ | `LOOP_CYCLES` | `1` | window length, in pulse periods → 2.4s |
131
+ | `LOOP_MS` | — | window length in ms, snapped to a whole period |
132
+ | `PULSE_S` | `2.4` | the engine's `animateMotion dur` — must match `ui-flow`'s `FlowEdge` |
133
+ | `LOOP_LEAD_S` | `0.5` | discarded screencast ramp-up before the window |
134
+ | `NO_LOOP` | — | set to hold for the whole wav, as before |
135
+
136
+ The window **must** be a whole multiple of `PULSE_S` or the loop join shows a jump — which is why
137
+ `LOOP_MS` is snapped rather than taken literally.
138
+
121
139
  **Where things live.** Scripts resolve two roots explicitly (`scripts/_paths.mjs`), because from
122
140
  `node_modules` they can no longer use their own directory:
123
141
 
@@ -1,9 +1,11 @@
1
+ import { type ThemeKey } from '@graphlearning/flow';
1
2
  import type { Course, SceneLookup } from './types';
2
- export declare function ConceptApp({ subject, eyebrow, courses: COURSES, getScene, audioBase, kind, }: {
3
+ export declare function ConceptApp({ subject, eyebrow, courses: COURSES, getScene, audioBase, kind, theme, }: {
3
4
  subject: string;
4
5
  courses: Record<string, Course>;
5
6
  eyebrow?: string;
6
7
  getScene: SceneLookup;
7
8
  audioBase?: string;
8
9
  kind?: string;
10
+ theme?: ThemeKey;
9
11
  }): import("react").JSX.Element;
@@ -1,6 +1,8 @@
1
1
  import type { Course } from './types';
2
- export declare function CourseIndex({ courses, subject, kind, }: {
2
+ import type { ReactNode } from 'react';
3
+ export declare function CourseIndex({ courses, subject, kind, actions, }: {
3
4
  courses: Course[];
4
5
  subject: string;
5
6
  kind?: string;
7
+ actions?: ReactNode;
6
8
  }): import("react").JSX.Element;
@@ -1,5 +1,6 @@
1
+ import { type ThemeKey } from '@graphlearning/flow';
1
2
  import type { Section, SceneLookup } from './types';
2
- export declare function SectionView({ section, getScene, capture, eyebrow, index, total, onHome, onPrev, onNext, narrating, onToggleNarration, }: {
3
+ export declare function SectionView({ section, getScene, capture, eyebrow, index, total, onHome, onPrev, onNext, narrating, onToggleNarration, theme, onToggleTheme, }: {
3
4
  section: Section;
4
5
  getScene: SceneLookup;
5
6
  capture?: boolean;
@@ -11,4 +12,6 @@ export declare function SectionView({ section, getScene, capture, eyebrow, index
11
12
  onNext?: () => void;
12
13
  narrating?: boolean;
13
14
  onToggleNarration?: () => void;
15
+ theme?: ThemeKey;
16
+ onToggleTheme?: () => void;
14
17
  }): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { ThemeKey } from '@graphlearning/flow';
2
+ export declare function ThemeToggle({ theme, onToggle }: {
3
+ theme: ThemeKey;
4
+ onToggle: () => void;
5
+ }): import("react").JSX.Element;