@gjsify/storybook 0.18.0 → 0.20.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.
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{storybookDevtoolsExtension as e}from"./devtools-extension.js";import{STORYBOOK_CSS as t}from"./styles.js";import{StorybookWindow as n}from"./window.js";import r from"@girs/adw-1";import i from"@girs/gdk-4.0";import a from"@girs/gio-2.0";import o from"@girs/gobject-2.0";import s from"@girs/gtk-4.0";import{installDevtools as c}from"@gjsify/devtools";var l=class StorybookApplication extends r.Application{static{o.registerClass({GTypeName:`StorybookApplication`},StorybookApplication)}constructor(e){super({application_id:e.applicationId,flags:a.ApplicationFlags.DEFAULT_FLAGS}),this._window=null,this._options=e,this.connect(`startup`,()=>this._initStyles()),this.connect(`activate`,()=>this._onActivate())}_initStyles(){let e=new s.CssProvider;e.load_from_string(`${t}\n${this._options.css??``}`);let n=i.Display.get_default();if(!n){console.error(`No display found`);return}s.StyleContext.add_provider_for_display(n,e,s.STYLE_PROVIDER_PRIORITY_APPLICATION)}_onActivate(){if(!this._window){this._window=new n({application:this}),this._options.title&&this._window.set_title(this._options.title);try{this._window.populateSidebar(this._options.stories)}catch(e){console.error(`Failed to create story instances:`,e)}c(this,{enabled:this._options.devtools||void 0,extend:[e(this._window)]})}this._window.present()}};o.type_ensure(l.$gtype);export{l as StorybookApplication};
1
+ import"./_virtual/_rolldown/runtime.js";import{storybookDevtoolsExtension as e}from"./devtools-extension.js";import{installStorybookProbe as t,probeEnabled as n}from"./probe.js";import{STORYBOOK_CSS as r}from"./styles.js";import{StorybookWindow as i}from"./window.js";import a from"@girs/adw-1";import o from"@girs/gdk-4.0";import s from"@girs/gio-2.0";import c from"@girs/gobject-2.0";import l from"@girs/gtk-4.0";import{installDevtools as u}from"@gjsify/devtools";var d=class StorybookApplication extends a.Application{static{c.registerClass({GTypeName:`StorybookApplication`},StorybookApplication)}constructor(e){super({application_id:e.applicationId,flags:s.ApplicationFlags.DEFAULT_FLAGS}),this._window=null,this._options=e,this.connect(`startup`,()=>this._initStyles()),this.connect(`activate`,()=>this._onActivate())}_initStyles(){let e=new l.CssProvider;e.load_from_string(`${r}\n${this._options.css??``}`);let t=o.Display.get_default();if(!t){console.error(`No display found`);return}l.StyleContext.add_provider_for_display(t,e,l.STYLE_PROVIDER_PRIORITY_APPLICATION)}_onActivate(){if(!this._window){this._window=new i({application:this}),this._options.title&&this._window.set_title(this._options.title);try{this._window.populateSidebar(this._options.stories)}catch(e){console.error(`Failed to create story instances:`,e)}u(this,{enabled:this._options.devtools||void 0,extend:[e(this._window)]}),n()&&t(this,this._window,this._options.probe)}this._window.present()}};c.type_ensure(d.$gtype);export{d as StorybookApplication};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{storybookDevtoolsExtension as e}from"./devtools-extension.js";import{StorybookWindow as t}from"./window.js";import{StorybookApplication as n}from"./application.js";import{installActionGroup as r,withActionGroup as i}from"./decorators.js";import{collectStoryModules as a}from"./discover.js";import{StoryWidget as o}from"./story-widget.js";import{StoryRegistryService as s}from"./registry.js";import{runStorybook as c}from"./run.js";import{ControlType as l,argsFromControls as u,isStoryModule as d}from"@gjsify/stories";export{l as ControlType,s as StoryRegistryService,o as StoryWidget,n as StorybookApplication,t as StorybookWindow,u as argsFromControls,a as collectStoryModules,r as installActionGroup,d as isStoryModule,c as runStorybook,e as storybookDevtoolsExtension,i as withActionGroup};
1
+ import{storybookDevtoolsExtension as e}from"./devtools-extension.js";import{installStorybookProbe as t,probeEnabled as n}from"./probe.js";import{StorybookWindow as r}from"./window.js";import{StorybookApplication as i}from"./application.js";import{installActionGroup as a,withActionGroup as o}from"./decorators.js";import{collectStoryModules as s}from"./discover.js";import{StoryWidget as c}from"./story-widget.js";import{StoryRegistryService as l}from"./registry.js";import{runStorybook as u}from"./run.js";import{ControlType as d,argsFromControls as f,isStoryModule as p}from"@gjsify/stories";export{d as ControlType,l as StoryRegistryService,c as StoryWidget,i as StorybookApplication,r as StorybookWindow,f as argsFromControls,s as collectStoryModules,a as installActionGroup,t as installStorybookProbe,p as isStoryModule,n as probeEnabled,u as runStorybook,e as storybookDevtoolsExtension,o as withActionGroup};
@@ -0,0 +1 @@
1
+ import"./_virtual/_rolldown/runtime.js";import{captureWidgetPng as e,dumpTree as t}from"@gjsify/devtools";import n from"@girs/glib-2.0";const r=[`AdwNavigationSplitView`,`GtkListBox`,`AdwOverlaySplitView`];function probeEnabled(){let e=n.getenv(`GJSIFY_STORYBOOK_PROBE`);if(e==null)return!1;let t=e.toLowerCase();return t!==``&&t!==`0`&&t!==`false`}function collectTypes(e,t){t.add(e.type);for(let n of e.children)collectTypes(n,t)}function installStorybookProbe(i,a,o={}){let s=o.requireChrome??r,c=o.out??n.getenv(`GJSIFY_STORYBOOK_PROBE_OUT`)??void 0,l=o.timeoutMs??8e3,u=o.storyWidget??n.getenv(`GJSIFY_STORYBOOK_PROBE_STORY_WIDGET`)??void 0,d=a.controller.listStories(),f=[...new Set(d.map(e=>e.category))],p=o.story??n.getenv(`GJSIFY_STORYBOOK_PROBE_STORY`)??d[0]?.title,m=p?a.openStoryByTitle(p):!1,h=a.activeStory,g=new Set;collectTypes(t(a,60,`toplevel:0`),g);let _=s.filter(e=>!g.has(e)),v=new Set;h&&collectTypes(t(h,60,`story`),v);let y=v.size,b=u?v.has(u):null,finish=e=>{let t=JSON.stringify(e);if(e.ok)console.log(`STORYBOOK PROBE: PASS ${t}`);else{console.error(`STORYBOOK PROBE: FAIL ${t}`);try{typeof process<`u`&&(process.exitCode=1)}catch{}}if(c)try{n.file_set_contents(c,JSON.stringify(e,null,2))}catch{}i.quit()},x=0;n.timeout_add(n.PRIORITY_DEFAULT,100,()=>{x+=100;let t=e(a),r=a.get_width()>0&&a.get_height()>0;if(!t&&!(x>=l))return n.SOURCE_CONTINUE;let i=h?e(h):null,o=d.length>=1&&f.length>=1&&_.length===0&&m&&h!=null&&y>1,c;return d.length<1?c=`no stories registered`:f.length<1?c=`no categories`:_.length>0?c=`chrome missing: ${_.join(`, `)}`:!m||h==null?c=`could not open story: ${p??`(none)`}`:y<=1&&(c=`opened story rendered an empty subtree`),o&&u&&!v.has(u)&&(o=!1,c=`story widget ${u} not found in the opened story subtree`),o&&r&&(!t||t.length===0)&&(o=!1,c=`window realized (${a.get_width()}x${a.get_height()}) but the GSK capture was empty`),finish({ok:o,reason:c,stories:d.length,categories:f,opened:m,activeStory:h?h.meta.title:null,requiredChrome:s,missingChrome:_,storySubtreeWidgets:y,storyWidgetPresent:b,windowRealized:r,windowPngBytes:t?t.length:0,storyPngBytes:i?i.length:0}),n.SOURCE_REMOVE})}export{installStorybookProbe,probeEnabled};
@@ -1,4 +1,5 @@
1
1
  import Adw from '@girs/adw-1';
2
+ import { type StorybookProbeOptions } from './probe.js';
2
3
  import type { StoryModule } from './story-widget.js';
3
4
  /** Options that adapt the generic storybook to a host project. */
4
5
  export interface StorybookOptions {
@@ -12,6 +13,8 @@ export interface StorybookOptions {
12
13
  css?: string;
13
14
  /** Force-enable the devtools control plane (otherwise gated on `GJSIFY_DEVTOOLS`). */
14
15
  devtools?: boolean;
16
+ /** Self-verification probe options (only used when `GJSIFY_STORYBOOK_PROBE` is set). */
17
+ probe?: StorybookProbeOptions;
15
18
  }
16
19
  /**
17
20
  * Hosts the storybook: loads styles on startup, builds the window and populates
@@ -7,5 +7,7 @@ export { StorybookWindow } from './window.js';
7
7
  export { storybookDevtoolsExtension } from './devtools-extension.js';
8
8
  export { StorybookApplication, type StorybookOptions } from './application.js';
9
9
  export { runStorybook } from './run.js';
10
+ export { installStorybookProbe, probeEnabled } from './probe.js';
11
+ export type { StorybookProbeOptions, StorybookProbeResult } from './probe.js';
10
12
  export { collectStoryModules } from './discover.js';
11
13
  export type { StoryRow } from './types.js';
@@ -0,0 +1,40 @@
1
+ import type Adw from '@girs/adw-1';
2
+ import type { StorybookWindow } from './window.js';
3
+ /** Options for {@link installStorybookProbe} (env vars supply the CI-side defaults). */
4
+ export interface StorybookProbeOptions {
5
+ /** Story `Category/Name` title to open as the representative render. Default: `GJSIFY_STORYBOOK_PROBE_STORY`, else the first story. */
6
+ story?: string;
7
+ /** A widget type (e.g. `AdwSwitchRow`) that MUST appear in the opened story's subtree. Default: `GJSIFY_STORYBOOK_PROBE_STORY_WIDGET`. */
8
+ storyWidget?: string;
9
+ /** Chrome widget types required in the DumpTree. Default: NavigationSplitView + sidebar ListBox + controls OverlaySplitView. */
10
+ requireChrome?: string[];
11
+ /** Path to write the JSON result. Default: `GJSIFY_STORYBOOK_PROBE_OUT`. */
12
+ out?: string;
13
+ /** Max ms to wait for the surface to realize before capturing. Default 8000. */
14
+ timeoutMs?: number;
15
+ }
16
+ /** The result the probe logs + writes — the machine-readable proof record. */
17
+ export interface StorybookProbeResult {
18
+ ok: boolean;
19
+ reason?: string;
20
+ stories: number;
21
+ categories: string[];
22
+ opened: boolean;
23
+ activeStory: string | null;
24
+ requiredChrome: string[];
25
+ missingChrome: string[];
26
+ storySubtreeWidgets: number;
27
+ storyWidgetPresent: boolean | null;
28
+ windowRealized: boolean;
29
+ windowPngBytes: number;
30
+ storyPngBytes: number;
31
+ }
32
+ /** Truthy-env check, matching `@gjsify/devtools`' `GJSIFY_DEVTOOLS` gate semantics. */
33
+ export declare function probeEnabled(): boolean;
34
+ /**
35
+ * Install the storybook self-verification probe. A no-op unless it is called
36
+ * (the caller gates on {@link probeEnabled}). Opens a representative story, then
37
+ * polls for the GSK render, asserts the chrome + story subtree + a non-empty PNG,
38
+ * logs `STORYBOOK PROBE: PASS|FAIL`, writes the JSON result, and quits the app.
39
+ */
40
+ export declare function installStorybookProbe(app: Adw.Application, window: StorybookWindow, options?: StorybookProbeOptions): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/storybook",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Reusable GTK/Adwaita storybook for GJS — author *.story.ts and browse them in a generic component explorer",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -41,13 +41,13 @@
41
41
  "@girs/glib-2.0": "^4.1.0",
42
42
  "@girs/gobject-2.0": "^4.1.0",
43
43
  "@girs/gtk-4.0": "^4.1.0",
44
- "@gjsify/devtools": "^0.18.0",
45
- "@gjsify/stories": "^0.18.0",
46
- "@gjsify/storybook-core": "^0.18.0"
44
+ "@gjsify/devtools": "^0.20.0",
45
+ "@gjsify/stories": "^0.20.0",
46
+ "@gjsify/storybook-core": "^0.20.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@gjsify/cli": "^0.18.0",
50
- "@gjsify/unit": "^0.18.0",
49
+ "@gjsify/cli": "^0.20.0",
50
+ "@gjsify/unit": "^0.20.0",
51
51
  "@types/node": "^25.9.2",
52
52
  "typescript": "^6.0.3"
53
53
  },