ember-storybook 0.3.0 → 0.3.1

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.
@@ -40,16 +40,10 @@ export interface RouteStoryInput {
40
40
  /** The booted app instance the route renders under. */
41
41
  owner: object;
42
42
  }
43
- /**
44
- * Name of the Storybook global that decides how `{{outlet}}` is rendered
45
- * (`hole` | `placeholder`). Declared here so the toolbar item and the renderer
46
- * read and write the same key.
47
- */
48
- export declare const OUTLET_GLOBAL_KEY = "outlet";
49
43
  export interface OutletResolveInput {
50
44
  /** `parameters.ember.route` of the story being rendered. */
51
45
  route: RouteParameters;
52
- /** Value of the {@link OUTLET_GLOBAL_KEY} global, if any. */
46
+ /** Value of the `outlet` global (see `src/outlet-key.ts`), if any. */
53
47
  mode?: OutletMode;
54
48
  /**
55
49
  * Produces the stub rendered when the global asks for a visible placeholder.
@@ -1 +1 @@
1
- {"version":3,"file":"outlet.d.ts","sourceRoot":"","sources":["../../src/client/outlet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,GAAG,SAAS,CAAA;KAAE,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,KAAK,EAAE,eAAe,CAAC;IACvB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,WAAW,EAAE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACrD;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,KAAK,EACL,IAAI,EACJ,WAAW,EACZ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAMtD;AAsBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,KAAK,EACL,MAAM,EACN,IAAI,EACJ,SAAS,EACT,KAAK,EACN,EAAE,eAAe,GAAG,WAAW,CAa/B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1C;AAyDD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1F"}
1
+ {"version":3,"file":"outlet.d.ts","sourceRoot":"","sources":["../../src/client/outlet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,GAAG,SAAS,CAAA;KAAE,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;CACf;AAID,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,KAAK,EAAE,eAAe,CAAC;IACvB,sEAAsE;IACtE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,WAAW,EAAE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACrD;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,KAAK,EACL,IAAI,EACJ,WAAW,EACZ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAMtD;AAsBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,KAAK,EACL,MAAM,EACN,IAAI,EACJ,SAAS,EACT,KAAK,EACN,EAAE,eAAe,GAAG,WAAW,CAa/B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1C;AAyDD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1F"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Name of the Storybook global that decides how `{{outlet}}` is rendered
3
+ * (`hole` | `placeholder`).
4
+ *
5
+ * Lives in its own dependency-free module: the manager toolbar and the client
6
+ * renderer must read and write the same key, but importing it from the client
7
+ * outlet module would pull Ember-only imports (`@ember/*`) into the manager
8
+ * bundle, which Storybook builds with esbuild and cannot resolve them.
9
+ */
10
+ export declare const OUTLET_GLOBAL_KEY = "outlet";
11
+ //# sourceMappingURL=outlet-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlet-key.d.ts","sourceRoot":"","sources":["../src/outlet-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAC"}
@@ -1,5 +1,5 @@
1
- import { n as renderToCanvas, t as render } from "../render-jYhDmzLM.mjs";
2
- import { t as OUTLET_GLOBAL_KEY } from "../outlet-Dc5ySBso.mjs";
1
+ import { n as renderToCanvas, t as render } from "../render-DzZ1vCNM.mjs";
2
+ import { t as OUTLET_GLOBAL_KEY } from "../outlet-key-Dhm2WHYN.mjs";
3
3
  import { enhanceArgTypes } from "storybook/internal/docs-tools";
4
4
  //#region src/client/config.ts
5
5
  const parameters = {
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":["enhanceArgTypes","OUTLET_GLOBAL_KEY","render","renderToCanvas","parameters","renderer","docs","story","inline","globalTypes","description","defaultValue","argTypesEnhancers"],"sources":["../../src/client/config.ts"],"sourcesContent":["import { enhanceArgTypes } from 'storybook/internal/docs-tools';\n\nimport { OUTLET_GLOBAL_KEY } from './outlet';\n\nimport type { ArgTypesEnhancer, GlobalTypes, Parameters } from 'storybook/internal/types';\n\nexport { render, renderToCanvas } from './render';\n\nexport const parameters: Parameters = {\n renderer: 'ember',\n docs: {\n story: { inline: true }\n }\n};\n\n/**\n * The \"Ember\" toolbar menu: how a route story should render `{{outlet}}`.\n *\n * `defaultValue` seeds the global (Storybook merges global-type defaults under\n * any project `initialGlobals`), so a project can still change the starting\n * value with `initialGlobals: { outlet: 'placeholder' }`.\n *\n * No `toolbar` here: the menu UI (with the Ember brand icon) is a custom tool\n * in `src/manager`, because Storybook 10 only resolves toolbar icons against\n * its fixed built-in icon map.\n */\nexport const globalTypes: GlobalTypes = {\n [OUTLET_GLOBAL_KEY]: {\n description: 'How a route story renders {{outlet}}',\n defaultValue: 'hole'\n }\n};\n\nexport const argTypesEnhancers: ArgTypesEnhancer[] = [enhanceArgTypes];\n"],"mappings":";;;;AAQA,MAAaI,aAAyB;CACpCC,UAAU;CACVC,MAAM,EACJC,OAAO,EAAEC,QAAQ,KAAK,EACxB;AACF;;;;;;;;;;;;AAaA,MAAaC,cAA2B,GACrCR,oBAAoB;CACnBS,aAAa;CACbC,cAAc;AAChB,EACF;AAEA,MAAaC,oBAAwC,CAACZ,eAAe"}
1
+ {"version":3,"file":"config.mjs","names":["enhanceArgTypes","OUTLET_GLOBAL_KEY","render","renderToCanvas","parameters","renderer","docs","story","inline","globalTypes","description","defaultValue","argTypesEnhancers"],"sources":["../../src/client/config.ts"],"sourcesContent":["import { enhanceArgTypes } from 'storybook/internal/docs-tools';\n\nimport { OUTLET_GLOBAL_KEY } from '../outlet-key';\n\nimport type { ArgTypesEnhancer, GlobalTypes, Parameters } from 'storybook/internal/types';\n\nexport { render, renderToCanvas } from './render';\n\nexport const parameters: Parameters = {\n renderer: 'ember',\n docs: {\n story: { inline: true }\n }\n};\n\n/**\n * The \"Ember\" toolbar menu: how a route story should render `{{outlet}}`.\n *\n * `defaultValue` seeds the global (Storybook merges global-type defaults under\n * any project `initialGlobals`), so a project can still change the starting\n * value with `initialGlobals: { outlet: 'placeholder' }`.\n *\n * No `toolbar` here: the menu UI (with the Ember brand icon) is a custom tool\n * in `src/manager`, because Storybook 10 only resolves toolbar icons against\n * its fixed built-in icon map.\n */\nexport const globalTypes: GlobalTypes = {\n [OUTLET_GLOBAL_KEY]: {\n description: 'How a route story renders {{outlet}}',\n defaultValue: 'hole'\n }\n};\n\nexport const argTypesEnhancers: ArgTypesEnhancer[] = [enhanceArgTypes];\n"],"mappings":";;;;AAQA,MAAaI,aAAyB;CACpCC,UAAU;CACVC,MAAM,EACJC,OAAO,EAAEC,QAAQ,KAAK,EACxB;AACF;;;;;;;;;;;;AAaA,MAAaC,cAA2B,GACrCR,oBAAoB;CACnBS,aAAa;CACbC,cAAc;AAChB,EACF;AAEA,MAAaC,oBAAwC,CAACZ,eAAe"}
@@ -1,4 +1,4 @@
1
- import { n as renderToCanvas } from "../render-jYhDmzLM.mjs";
2
- import { n as setProjectAnnotations, t as RenderStory } from "../client-DMN9EyIc.mjs";
3
- import { t as OutletPlaceholder } from "../outlet-placeholder-DZpXQLIa.mjs";
1
+ import { n as renderToCanvas } from "../render-DzZ1vCNM.mjs";
2
+ import { n as setProjectAnnotations, t as RenderStory } from "../client-BN1WZuKz.mjs";
3
+ import { t as OutletPlaceholder } from "../outlet-placeholder-BL2iFDVf.mjs";
4
4
  export { OutletPlaceholder, RenderStory, renderToCanvas, setProjectAnnotations };
@@ -1,5 +1,5 @@
1
- import { r as render_exports } from "./render-jYhDmzLM.mjs";
2
- import "./outlet-placeholder-DZpXQLIa.mjs";
1
+ import { r as render_exports } from "./render-DzZ1vCNM.mjs";
2
+ import "./outlet-placeholder-BL2iFDVf.mjs";
3
3
  import { r as normalizeStoryResult } from "./story-result-D9erht0M.mjs";
4
4
  import { template } from "@ember/template-compiler";
5
5
  import { setDefaultProjectAnnotations, setProjectAnnotations } from "storybook/preview-api";
@@ -62,4 +62,4 @@ var RenderStory = class extends Component {
62
62
  //#endregion
63
63
  export { setProjectAnnotations$1 as n, RenderStory as t };
64
64
 
65
- //# sourceMappingURL=client-DMN9EyIc.mjs.map
65
+ //# sourceMappingURL=client-BN1WZuKz.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-DMN9EyIc.mjs","names":["globalThis","STORYBOOK_ENV","setDefaultProjectAnnotations","setProjectAnnotations","originalSetProjectAnnotations","INTERNAL_DEFAULT_PROJECT_ANNOTATIONS","projectAnnotations"],"sources":["../src/client/globals.ts","../src/client/portable-stories.ts","../src/client/render-story.gts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\n// eslint-disable-next-line unicorn/no-global-object-property-assignment\nglobalThis.STORYBOOK_ENV = 'ember';\n","import {\n setDefaultProjectAnnotations,\n setProjectAnnotations as originalSetProjectAnnotations\n} from 'storybook/preview-api';\n\nimport * as INTERNAL_DEFAULT_PROJECT_ANNOTATIONS from './render';\n\nimport type { EmberRenderer } from './types';\nimport type {\n NamedOrDefaultProjectAnnotations,\n NormalizedProjectAnnotations\n} from 'storybook/internal/types';\n\n/**\n * Function that sets the globalConfig of your storybook. The global config is the preview module of\n * your .storybook folder.\n *\n * It should be run a single time, so that your global config (e.g. decorators) is applied to your\n * stories when using `composeStories` or `composeStory`.\n *\n * Example:\n *\n * ```jsx\n * // setup-file.js\n * import { setProjectAnnotations } from '@storybook/preact';\n * import projectAnnotations from './.storybook/preview';\n *\n * setProjectAnnotations(projectAnnotations);\n * ```\n *\n * @param projectAnnotations - E.g. (import projectAnnotations from '../.storybook/preview')\n */\nexport function setProjectAnnotations(\n projectAnnotations:\n | NamedOrDefaultProjectAnnotations<EmberRenderer>\n | NamedOrDefaultProjectAnnotations<EmberRenderer>[]\n): NormalizedProjectAnnotations<EmberRenderer> {\n setDefaultProjectAnnotations(INTERNAL_DEFAULT_PROJECT_ANNOTATIONS);\n\n return originalSetProjectAnnotations(projectAnnotations);\n}\n","import Component from '@glimmer/component';\nimport { getOwner } from '@ember/owner';\nimport { renderComponent } from '@ember/renderer';\n\nimport { modifier } from 'ember-modifier';\n\nimport { normalizeStoryResult } from './story-result';\n\ninterface RenderStorySignature {\n Args: {\n story: () => object;\n args: Record<string, unknown>;\n };\n Element: HTMLDivElement;\n}\n\nexport class RenderStory extends Component<RenderStorySignature> {\n render = modifier((element: HTMLDivElement) => {\n const story = this.args.story();\n const { component, args, route } = normalizeStoryResult(story, this.args.args);\n const owner = getOwner(this);\n\n if (route) {\n // `{{outlet}}` is resolved from Glimmer's dynamic scope, which only a root\n // render can seed. Rendering it in here would nest a second outlet root\n // inside an already-rendering tree, so route stories are canvas-only.\n throw new Error(\n 'ember-storybook: this story sets `parameters.ember.route`, but route stories ' +\n 'can only be rendered by `renderToCanvas`, not through <RenderStory> ' +\n '(portable stories).'\n );\n }\n\n const result = renderComponent(component, {\n args,\n into: element,\n owner\n });\n\n return () => {\n result.destroy();\n };\n });\n\n <template>\n <div {{this.render}}></div>\n </template>\n}\n"],"mappings":";;;;;;;;;;AAGAA,WAAWC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;AC6B3B,SAAgBE,wBACdG,oBAG6C;CAC7CJ,6BAA6BG,cAAoC;CAEjE,OAAOD,sBAA8BE,kBAAkB;AACzD;;;ACxBA,IAAa,cAAb,cAAiC,UAAU;CACzC,SAAS,UAAU,YAAS;EAE1B,MAAM,EAAE,WAAW,MAAM,UAAU,qBADrB,KAAK,KAAK,MACgC,GAAO,KAAK,KAAK,IAAI;EAC7E,MAAM,QAAQ,SAAS,IAAI;EAE3B,IAAI,OAIF,MAAM,IAAI,MACR,sKAEE;EAIN,MAAM,SAAS,gBAAgB,WAAW;GACxC;GACA,MAAM;GACN;EACF,CAAA;EAEA,aAAO;GACL,OAAO,QAAO;EAChB;CACF,CAAA;CAEA;EAAA,SAAU,+BAEV;GAAA,WAAA;GAAA,OAAA;IAAA,OAAA,KAAA,UAAA,EAAW;GAAD;EAAA,CAAA;CAAA;AACZ"}
1
+ {"version":3,"file":"client-BN1WZuKz.mjs","names":["globalThis","STORYBOOK_ENV","setDefaultProjectAnnotations","setProjectAnnotations","originalSetProjectAnnotations","INTERNAL_DEFAULT_PROJECT_ANNOTATIONS","projectAnnotations"],"sources":["../src/client/globals.ts","../src/client/portable-stories.ts","../src/client/render-story.gts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\n// eslint-disable-next-line unicorn/no-global-object-property-assignment\nglobalThis.STORYBOOK_ENV = 'ember';\n","import {\n setDefaultProjectAnnotations,\n setProjectAnnotations as originalSetProjectAnnotations\n} from 'storybook/preview-api';\n\nimport * as INTERNAL_DEFAULT_PROJECT_ANNOTATIONS from './render';\n\nimport type { EmberRenderer } from './types';\nimport type {\n NamedOrDefaultProjectAnnotations,\n NormalizedProjectAnnotations\n} from 'storybook/internal/types';\n\n/**\n * Function that sets the globalConfig of your storybook. The global config is the preview module of\n * your .storybook folder.\n *\n * It should be run a single time, so that your global config (e.g. decorators) is applied to your\n * stories when using `composeStories` or `composeStory`.\n *\n * Example:\n *\n * ```jsx\n * // setup-file.js\n * import { setProjectAnnotations } from '@storybook/preact';\n * import projectAnnotations from './.storybook/preview';\n *\n * setProjectAnnotations(projectAnnotations);\n * ```\n *\n * @param projectAnnotations - E.g. (import projectAnnotations from '../.storybook/preview')\n */\nexport function setProjectAnnotations(\n projectAnnotations:\n | NamedOrDefaultProjectAnnotations<EmberRenderer>\n | NamedOrDefaultProjectAnnotations<EmberRenderer>[]\n): NormalizedProjectAnnotations<EmberRenderer> {\n setDefaultProjectAnnotations(INTERNAL_DEFAULT_PROJECT_ANNOTATIONS);\n\n return originalSetProjectAnnotations(projectAnnotations);\n}\n","import Component from '@glimmer/component';\nimport { getOwner } from '@ember/owner';\nimport { renderComponent } from '@ember/renderer';\n\nimport { modifier } from 'ember-modifier';\n\nimport { normalizeStoryResult } from './story-result';\n\ninterface RenderStorySignature {\n Args: {\n story: () => object;\n args: Record<string, unknown>;\n };\n Element: HTMLDivElement;\n}\n\nexport class RenderStory extends Component<RenderStorySignature> {\n render = modifier((element: HTMLDivElement) => {\n const story = this.args.story();\n const { component, args, route } = normalizeStoryResult(story, this.args.args);\n const owner = getOwner(this);\n\n if (route) {\n // `{{outlet}}` is resolved from Glimmer's dynamic scope, which only a root\n // render can seed. Rendering it in here would nest a second outlet root\n // inside an already-rendering tree, so route stories are canvas-only.\n throw new Error(\n 'ember-storybook: this story sets `parameters.ember.route`, but route stories ' +\n 'can only be rendered by `renderToCanvas`, not through <RenderStory> ' +\n '(portable stories).'\n );\n }\n\n const result = renderComponent(component, {\n args,\n into: element,\n owner\n });\n\n return () => {\n result.destroy();\n };\n });\n\n <template>\n <div {{this.render}}></div>\n </template>\n}\n"],"mappings":";;;;;;;;;;AAGAA,WAAWC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;AC6B3B,SAAgBE,wBACdG,oBAG6C;CAC7CJ,6BAA6BG,cAAoC;CAEjE,OAAOD,sBAA8BE,kBAAkB;AACzD;;;ACxBA,IAAa,cAAb,cAAiC,UAAU;CACzC,SAAS,UAAU,YAAS;EAE1B,MAAM,EAAE,WAAW,MAAM,UAAU,qBADrB,KAAK,KAAK,MACgC,GAAO,KAAK,KAAK,IAAI;EAC7E,MAAM,QAAQ,SAAS,IAAI;EAE3B,IAAI,OAIF,MAAM,IAAI,MACR,sKAEE;EAIN,MAAM,SAAS,gBAAgB,WAAW;GACxC;GACA,MAAM;GACN;EACF,CAAA;EAEA,aAAO;GACL,OAAO,QAAO;EAChB;CACF,CAAA;CAEA;EAAA,SAAU,+BAEV;GAAA,WAAA;GAAA,OAAA;IAAA,OAAA,KAAA,UAAA,EAAW;GAAD;EAAA,CAAA;CAAA;AACZ"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as renderToCanvas } from "./render-jYhDmzLM.mjs";
2
- import { n as setProjectAnnotations, t as RenderStory } from "./client-DMN9EyIc.mjs";
3
- import { t as OutletPlaceholder } from "./outlet-placeholder-DZpXQLIa.mjs";
1
+ import { n as renderToCanvas } from "./render-DzZ1vCNM.mjs";
2
+ import { n as setProjectAnnotations, t as RenderStory } from "./client-BN1WZuKz.mjs";
3
+ import { t as OutletPlaceholder } from "./outlet-placeholder-BL2iFDVf.mjs";
4
4
  export { OutletPlaceholder, RenderStory, renderToCanvas, setProjectAnnotations };
@@ -1,4 +1,4 @@
1
- import { t as OUTLET_GLOBAL_KEY } from "../outlet-Dc5ySBso.mjs";
1
+ import { t as OUTLET_GLOBAL_KEY } from "../outlet-key-Dhm2WHYN.mjs";
2
2
  import { createElement } from "react";
3
3
  import { Select } from "storybook/internal/components";
4
4
  import { addons, types, useGlobals } from "storybook/manager-api";
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["createElement","EMBER_ICON_MARKUP","EmberIcon","props","width","height","viewBox","xmlns","style","display","verticalAlign","dangerouslySetInnerHTML","__html","createElement","Select","addons","types","useGlobals","OUTLET_GLOBAL_KEY","EmberIcon","ADDON_ID","TITLE","DESCRIPTION","OUTLET_ITEMS","value","title","OutletToolbar","globals","updateGlobals","storyGlobals","defaultOptions","options","disabled","undefined","ariaLabel","tooltip","onSelect","selected","icon","showSelectedOptionTitle","register","add","type","TOOL","render"],"sources":["../../src/manager/ember-icon.ts","../../src/manager/index.ts"],"sourcesContent":["import { createElement } from 'react';\n\nimport type { SVGProps } from 'react';\n\n/**\n * The Ember \"e-circle\" brand icon, embedding the markup from\n * https://github.com/ember-learn/ember-website/blob/main/public/images/brand/Ember%20Logos/Icon/e-circle-icon-4c.svg\n *\n * Storybook 10 resolves toolbar `icon` strings against a fixed manager-side\n * map, so a custom brand icon has to be a React element rendered by our own\n * toolbar tool. The fills are hardcoded brand colors on purpose: unlike\n * Storybook's monochrome icons this one must keep its red/white identity.\n */\nconst EMBER_ICON_MARKUP = `\n <g fill=\"none\" fill-rule=\"evenodd\">\n <path d=\"M64 0c35.346 0 64 28.654 64 64 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64C0 28.654 28.654 0 64 0z\" fill=\"#E05C43\" fill-rule=\"nonzero\"/>\n <path d=\"M65.265 24.128c8.246-.163 14.073 2.073 19.087 9.19 10.934 27.109-28.147 41.1-29.714 41.65l-.049.016s-1.18 7.363 10.028 7.08c13.793 0 28.294-10.691 33.81-15.21a3.293 3.293 0 0 1 4.468.265l4.13 4.29a3.291 3.291 0 0 1 .085 4.491c-3.59 3.997-12.014 12.203-24.696 17.504 0 0-21.16 9.798-35.42.52-8.503-5.53-10.842-12.151-11.793-19.038.005 0-10.324-.524-16.957-3.114-6.635-2.592.049-10.411.049-10.411s2.04-3.233 5.92 0c3.883 3.228 11.13 1.772 11.13 1.772.646-5.099 1.72-11.828 4.884-18.93 6.632-14.885 16.789-19.915 25.038-20.075zm4.853 14.915c-4.369-4.21-16.984 4.202-17.471 23.45 0 0 3.724 1.134 11.97-4.53 8.25-5.661 9.87-14.718 5.501-18.92z\" fill=\"#FFFFFF\"/>\n </g>\n`;\n\nexport function EmberIcon(props: SVGProps<SVGSVGElement>) {\n return createElement('svg', {\n width: 14,\n height: 14,\n viewBox: '0 0 128 128',\n xmlns: 'http://www.w3.org/2000/svg',\n style: { display: 'inline-block', verticalAlign: 'middle' },\n 'aria-hidden': true,\n ...props,\n // The markup mirrors the upstream brand asset; static, first-party content.\n dangerouslySetInnerHTML: { __html: EMBER_ICON_MARKUP }\n });\n}\n","import { createElement } from 'react';\nimport { Select } from 'storybook/internal/components';\nimport { addons, types, useGlobals } from 'storybook/manager-api';\n\nimport { OUTLET_GLOBAL_KEY } from '../client/outlet';\nimport { EmberIcon } from './ember-icon';\n\nimport type { OutletMode } from '../client/types';\n\n/**\n * The \"Ember\" toolbar menu: how a route story should render `{{outlet}}`.\n *\n * Registered as a custom tool (not `globalTypes.toolbar`) because Storybook 10\n * resolves toolbar `icon` strings against a fixed manager-side icon map — the\n * Ember brand icon can only be supplied through a tool's own `render`. The\n * value still lives in globals (see `globalTypes` in `client/config.ts`), so\n * the renderer and `initialGlobals` keep working unchanged.\n */\nconst ADDON_ID = 'ember-storybook';\n\nconst TITLE = 'Ember';\nconst DESCRIPTION = 'How a route story renders {{outlet}}';\n\nconst OUTLET_ITEMS: { value: OutletMode; title: string }[] = [\n { value: 'hole', title: 'Hole' },\n { value: 'placeholder', title: 'Placeholder' }\n];\n\nfunction OutletToolbar() {\n const [globals, updateGlobals, storyGlobals] = useGlobals();\n\n return createElement(Select, {\n defaultOptions: [globals[OUTLET_GLOBAL_KEY]],\n options: OUTLET_ITEMS,\n // A story-level global override wins; don't let the toolbar fight it.\n disabled: storyGlobals[OUTLET_GLOBAL_KEY] !== undefined,\n ariaLabel: TITLE,\n tooltip: DESCRIPTION,\n onSelect: (selected: unknown) => {\n updateGlobals({ [OUTLET_GLOBAL_KEY]: selected });\n },\n icon: createElement(EmberIcon),\n // Icon-only trigger, like Storybook's own toolbar items (backgrounds,\n // viewport, …): never swap in the selected item's title (\"Hole\").\n showSelectedOptionTitle: false\n });\n}\n\naddons.register(ADDON_ID, () => {\n addons.add(`${ADDON_ID}/outlet-toolbar`, {\n type: types.TOOL,\n title: TITLE,\n render: () => createElement(OutletToolbar)\n });\n});\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAMC,oBAAoB;;;;;;AAO1B,SAAgBC,UAAUC,OAAgC;CACxD,OAAOH,cAAc,OAAO;EAC1BI,OAAO;EACPC,QAAQ;EACRC,SAAS;EACTC,OAAO;EACPC,OAAO;GAAEC,SAAS;GAAgBC,eAAe;EAAS;EAC1D,eAAe;EACf,GAAGP;EAEHQ,yBAAyB,EAAEC,QAAQX,kBAAkB;CACvD,CAAC;AACH;;;;;;;;;;;;ACdA,MAAMmB,WAAW;AAEjB,MAAMC,QAAQ;AACd,MAAMC,cAAc;AAEpB,MAAMC,eAAuD,CAC3D;CAAEC,OAAO;CAAQC,OAAO;AAAO,GAC/B;CAAED,OAAO;CAAeC,OAAO;AAAc,CAAC;AAGhD,SAASC,gBAAgB;CACvB,MAAM,CAACC,SAASC,eAAeC,gBAAgBZ,WAAW;CAE1D,OAAOJ,cAAcC,QAAQ;EAC3BgB,gBAAgB,CAACH,QAAQT,kBAAkB;EAC3Ca,SAASR;EAETS,UAAUH,aAAaX,uBAAuBe,KAAAA;EAC9CC,WAAWb;EACXc,SAASb;EACTc,WAAWC,aAAsB;GAC/BT,cAAc,GAAGV,oBAAoBmB,SAAS,CAAC;EACjD;EACAC,MAAMzB,cAAcM,SAAS;EAG7BoB,yBAAyB;CAC3B,CAAC;AACH;AAEAxB,OAAOyB,SAASpB,gBAAgB;CAC9BL,OAAO0B,IAAI,GAAGrB,SAAQ,kBAAmB;EACvCsB,MAAM1B,MAAM2B;EACZlB,OAAOJ;EACPuB,cAAc/B,cAAca,aAAa;CAC3C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["createElement","EMBER_ICON_MARKUP","EmberIcon","props","width","height","viewBox","xmlns","style","display","verticalAlign","dangerouslySetInnerHTML","__html","createElement","Select","addons","types","useGlobals","OUTLET_GLOBAL_KEY","EmberIcon","ADDON_ID","TITLE","DESCRIPTION","OUTLET_ITEMS","value","title","OutletToolbar","globals","updateGlobals","storyGlobals","defaultOptions","options","disabled","undefined","ariaLabel","tooltip","onSelect","selected","icon","showSelectedOptionTitle","register","add","type","TOOL","render"],"sources":["../../src/manager/ember-icon.ts","../../src/manager/index.ts"],"sourcesContent":["import { createElement } from 'react';\n\nimport type { SVGProps } from 'react';\n\n/**\n * The Ember \"e-circle\" brand icon, embedding the markup from\n * https://github.com/ember-learn/ember-website/blob/main/public/images/brand/Ember%20Logos/Icon/e-circle-icon-4c.svg\n *\n * Storybook 10 resolves toolbar `icon` strings against a fixed manager-side\n * map, so a custom brand icon has to be a React element rendered by our own\n * toolbar tool. The fills are hardcoded brand colors on purpose: unlike\n * Storybook's monochrome icons this one must keep its red/white identity.\n */\nconst EMBER_ICON_MARKUP = `\n <g fill=\"none\" fill-rule=\"evenodd\">\n <path d=\"M64 0c35.346 0 64 28.654 64 64 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64C0 28.654 28.654 0 64 0z\" fill=\"#E05C43\" fill-rule=\"nonzero\"/>\n <path d=\"M65.265 24.128c8.246-.163 14.073 2.073 19.087 9.19 10.934 27.109-28.147 41.1-29.714 41.65l-.049.016s-1.18 7.363 10.028 7.08c13.793 0 28.294-10.691 33.81-15.21a3.293 3.293 0 0 1 4.468.265l4.13 4.29a3.291 3.291 0 0 1 .085 4.491c-3.59 3.997-12.014 12.203-24.696 17.504 0 0-21.16 9.798-35.42.52-8.503-5.53-10.842-12.151-11.793-19.038.005 0-10.324-.524-16.957-3.114-6.635-2.592.049-10.411.049-10.411s2.04-3.233 5.92 0c3.883 3.228 11.13 1.772 11.13 1.772.646-5.099 1.72-11.828 4.884-18.93 6.632-14.885 16.789-19.915 25.038-20.075zm4.853 14.915c-4.369-4.21-16.984 4.202-17.471 23.45 0 0 3.724 1.134 11.97-4.53 8.25-5.661 9.87-14.718 5.501-18.92z\" fill=\"#FFFFFF\"/>\n </g>\n`;\n\nexport function EmberIcon(props: SVGProps<SVGSVGElement>) {\n return createElement('svg', {\n width: 14,\n height: 14,\n viewBox: '0 0 128 128',\n xmlns: 'http://www.w3.org/2000/svg',\n style: { display: 'inline-block', verticalAlign: 'middle' },\n 'aria-hidden': true,\n ...props,\n // The markup mirrors the upstream brand asset; static, first-party content.\n dangerouslySetInnerHTML: { __html: EMBER_ICON_MARKUP }\n });\n}\n","import { createElement } from 'react';\nimport { Select } from 'storybook/internal/components';\nimport { addons, types, useGlobals } from 'storybook/manager-api';\n\nimport { OUTLET_GLOBAL_KEY } from '../outlet-key';\nimport { EmberIcon } from './ember-icon';\n\nimport type { OutletMode } from '../client/types';\n\n/**\n * The \"Ember\" toolbar menu: how a route story should render `{{outlet}}`.\n *\n * Registered as a custom tool (not `globalTypes.toolbar`) because Storybook 10\n * resolves toolbar `icon` strings against a fixed manager-side icon map — the\n * Ember brand icon can only be supplied through a tool's own `render`. The\n * value still lives in globals (see `globalTypes` in `client/config.ts`), so\n * the renderer and `initialGlobals` keep working unchanged.\n */\nconst ADDON_ID = 'ember-storybook';\n\nconst TITLE = 'Ember';\nconst DESCRIPTION = 'How a route story renders {{outlet}}';\n\nconst OUTLET_ITEMS: { value: OutletMode; title: string }[] = [\n { value: 'hole', title: 'Hole' },\n { value: 'placeholder', title: 'Placeholder' }\n];\n\nfunction OutletToolbar() {\n const [globals, updateGlobals, storyGlobals] = useGlobals();\n\n return createElement(Select, {\n defaultOptions: [globals[OUTLET_GLOBAL_KEY]],\n options: OUTLET_ITEMS,\n // A story-level global override wins; don't let the toolbar fight it.\n disabled: storyGlobals[OUTLET_GLOBAL_KEY] !== undefined,\n ariaLabel: TITLE,\n tooltip: DESCRIPTION,\n onSelect: (selected: unknown) => {\n updateGlobals({ [OUTLET_GLOBAL_KEY]: selected });\n },\n icon: createElement(EmberIcon),\n // Icon-only trigger, like Storybook's own toolbar items (backgrounds,\n // viewport, …): never swap in the selected item's title (\"Hole\").\n showSelectedOptionTitle: false\n });\n}\n\naddons.register(ADDON_ID, () => {\n addons.add(`${ADDON_ID}/outlet-toolbar`, {\n type: types.TOOL,\n title: TITLE,\n render: () => createElement(OutletToolbar)\n });\n});\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAMC,oBAAoB;;;;;;AAO1B,SAAgBC,UAAUC,OAAgC;CACxD,OAAOH,cAAc,OAAO;EAC1BI,OAAO;EACPC,QAAQ;EACRC,SAAS;EACTC,OAAO;EACPC,OAAO;GAAEC,SAAS;GAAgBC,eAAe;EAAS;EAC1D,eAAe;EACf,GAAGP;EAEHQ,yBAAyB,EAAEC,QAAQX,kBAAkB;CACvD,CAAC;AACH;;;;;;;;;;;;ACdA,MAAMmB,WAAW;AAEjB,MAAMC,QAAQ;AACd,MAAMC,cAAc;AAEpB,MAAMC,eAAuD,CAC3D;CAAEC,OAAO;CAAQC,OAAO;AAAO,GAC/B;CAAED,OAAO;CAAeC,OAAO;AAAc,CAAC;AAGhD,SAASC,gBAAgB;CACvB,MAAM,CAACC,SAASC,eAAeC,gBAAgBZ,WAAW;CAE1D,OAAOJ,cAAcC,QAAQ;EAC3BgB,gBAAgB,CAACH,QAAQT,kBAAkB;EAC3Ca,SAASR;EAETS,UAAUH,aAAaX,uBAAuBe,KAAAA;EAC9CC,WAAWb;EACXc,SAASb;EACTc,WAAWC,aAAsB;GAC/BT,cAAc,GAAGV,oBAAoBmB,SAAS,CAAC;EACjD;EACAC,MAAMzB,cAAcM,SAAS;EAG7BoB,yBAAyB;CAC3B,CAAC;AACH;AAEAxB,OAAOyB,SAASpB,gBAAgB;CAC9BL,OAAO0B,IAAI,GAAGrB,SAAQ,kBAAmB;EACvCsB,MAAM1B,MAAM2B;EACZlB,OAAOJ;EACPuB,cAAc/B,cAAca,aAAa;CAC3C,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ //#region src/outlet-key.ts
2
+ /**
3
+ * Name of the Storybook global that decides how `{{outlet}}` is rendered
4
+ * (`hole` | `placeholder`).
5
+ *
6
+ * Lives in its own dependency-free module: the manager toolbar and the client
7
+ * renderer must read and write the same key, but importing it from the client
8
+ * outlet module would pull Ember-only imports (`@ember/*`) into the manager
9
+ * bundle, which Storybook builds with esbuild and cannot resolve them.
10
+ */
11
+ const OUTLET_GLOBAL_KEY = "outlet";
12
+ //#endregion
13
+ export { OUTLET_GLOBAL_KEY as t };
14
+
15
+ //# sourceMappingURL=outlet-key-Dhm2WHYN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlet-key-Dhm2WHYN.mjs","names":["OUTLET_GLOBAL_KEY"],"sources":["../src/outlet-key.ts"],"sourcesContent":["/**\n * Name of the Storybook global that decides how `{{outlet}}` is rendered\n * (`hole` | `placeholder`).\n *\n * Lives in its own dependency-free module: the manager toolbar and the client\n * renderer must read and write the same key, but importing it from the client\n * outlet module would pull Ember-only imports (`@ember/*`) into the manager\n * bundle, which Storybook builds with esbuild and cannot resolve them.\n */\nexport const OUTLET_GLOBAL_KEY = 'outlet';\n"],"mappings":";;;;;;;;;;AASA,MAAaA,oBAAoB"}
@@ -1,4 +1,4 @@
1
- import { i as __exportAll } from "./render-jYhDmzLM.mjs";
1
+ import { i as __exportAll } from "./render-DzZ1vCNM.mjs";
2
2
  import { template } from "@ember/template-compiler";
3
3
  //#region src/client/outlet-placeholder.gts
4
4
  var outlet_placeholder_exports = /* @__PURE__ */ __exportAll({ OutletPlaceholder: () => OutletPlaceholder });
@@ -28,4 +28,4 @@ const OutletPlaceholder = template(`<div
28
28
  //#endregion
29
29
  export { outlet_placeholder_exports as n, OutletPlaceholder as t };
30
30
 
31
- //# sourceMappingURL=outlet-placeholder-DZpXQLIa.mjs.map
31
+ //# sourceMappingURL=outlet-placeholder-BL2iFDVf.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"outlet-placeholder-DZpXQLIa.mjs","names":[],"sources":["../src/client/outlet-placeholder.gts"],"sourcesContent":["import type { TOC } from '@ember/component/template-only';\n\ninterface OutletPlaceholderSignature {\n Element: HTMLDivElement;\n Args: {\n /** Shown inside the box. A route template only receives `@model`. */\n model?: string;\n };\n}\n\n/**\n * A visible stand-in for `{{outlet}}`, for route stories where an empty hole is\n * hard to see (e.g. on the docs page).\n *\n * It is rendered *as a route template*, so it must be template-only (the outlet\n * only accepts a raw template or an internal-manager component) and the only\n * value it can receive is `@model` — pass a string to label the box:\n *\n * ```js\n * parameters: {\n * ember: { route: { outlet: { template: OutletPlaceholder, model: 'settings' } } }\n * }\n * ```\n */\nexport const OutletPlaceholder: TOC<OutletPlaceholderSignature> = <template>\n <div\n class=\"ember-storybook-outlet-placeholder\"\n style=\"border: 1px dashed #999; padding: 0.5rem; color: #666; font: italic 0.8rem/1.4 monospace;\"\n data-storybook-outlet\n >\n {{if @model @model \"outlet\"}}\n </div>\n</template>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAwBA,MAAa,oBAAqD,SAAU;;;;;;SAQ5E,EAAA,OAAA;CAAA,OAAA,KAAA,UAAA,EAAW;AAAD,EAAA,CAAA"}
1
+ {"version":3,"file":"outlet-placeholder-BL2iFDVf.mjs","names":[],"sources":["../src/client/outlet-placeholder.gts"],"sourcesContent":["import type { TOC } from '@ember/component/template-only';\n\ninterface OutletPlaceholderSignature {\n Element: HTMLDivElement;\n Args: {\n /** Shown inside the box. A route template only receives `@model`. */\n model?: string;\n };\n}\n\n/**\n * A visible stand-in for `{{outlet}}`, for route stories where an empty hole is\n * hard to see (e.g. on the docs page).\n *\n * It is rendered *as a route template*, so it must be template-only (the outlet\n * only accepts a raw template or an internal-manager component) and the only\n * value it can receive is `@model` — pass a string to label the box:\n *\n * ```js\n * parameters: {\n * ember: { route: { outlet: { template: OutletPlaceholder, model: 'settings' } } }\n * }\n * ```\n */\nexport const OutletPlaceholder: TOC<OutletPlaceholderSignature> = <template>\n <div\n class=\"ember-storybook-outlet-placeholder\"\n style=\"border: 1px dashed #999; padding: 0.5rem; color: #666; font: italic 0.8rem/1.4 monospace;\"\n data-storybook-outlet\n >\n {{if @model @model \"outlet\"}}\n </div>\n</template>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAwBA,MAAa,oBAAqD,SAAU;;;;;;SAQ5E,EAAA,OAAA;CAAA,OAAA,KAAA,UAAA,EAAW;AAAD,EAAA,CAAA"}
@@ -1,11 +1,12 @@
1
- import { a as updateOutletView, i as resolveOutletStub, n as buildRouteOutletState, r as mountOutletView, t as OUTLET_GLOBAL_KEY } from "./outlet-Dc5ySBso.mjs";
1
+ import { t as OUTLET_GLOBAL_KEY } from "./outlet-key-Dhm2WHYN.mjs";
2
2
  import { r as normalizeStoryResult, t as createAppResolver } from "./story-result-D9erht0M.mjs";
3
3
  import "node:module";
4
4
  import Application from "@ember/application";
5
5
  import ApplicationInstance from "@ember/application/instance";
6
6
  import { destroy } from "@ember/destroyable";
7
- import { renderComponent } from "@ember/renderer";
7
+ import { renderComponent, renderSettled } from "@ember/renderer";
8
8
  import { VERSION } from "@ember/version";
9
+ import { run } from "@ember/runloop";
9
10
  //#region \0rolldown/runtime.js
10
11
  var __defProp = Object.defineProperty;
11
12
  var __exportAll = (all, no_symbols) => {
@@ -18,6 +19,114 @@ var __exportAll = (all, no_symbols) => {
18
19
  return target;
19
20
  };
20
21
  //#endregion
22
+ //#region src/client/outlet.ts
23
+ /**
24
+ * What Ember's outlet hands a route template. A route template is *not* a
25
+ * component story: it receives exactly `@model` and `@controller`, because that
26
+ * is all `{{outlet}}` passes down (`OUTLET_COMPONENT_TEMPLATE` in ember-source).
27
+ */
28
+ /**
29
+ * Mirrors ember-source's internal `OutletState`. The shape is structural, not
30
+ * nominal, so a plain object is accepted by `setOutletState`; the leaf's
31
+ * `outlets.main` is what a nested `{{outlet}}` reads.
32
+ */
33
+ const DEFAULT_OUTLET_NAME = "outlet";
34
+ /**
35
+ * Decides what `{{outlet}}` renders.
36
+ *
37
+ * An explicit `route.outlet` is author intent and always wins, so a story stays
38
+ * deterministic no matter how the toolbar is set. Otherwise the global decides:
39
+ * `placeholder` renders the injected marker, anything else leaves a hole.
40
+ */
41
+ async function resolveOutletStub({ route, mode, placeholder }) {
42
+ if (route.outlet?.template) return route.outlet;
43
+ return mode === "placeholder" ? await placeholder() : void 0;
44
+ }
45
+ function mainOutlet(child) {
46
+ return { main: child };
47
+ }
48
+ function buildChildRenderState(stub, owner) {
49
+ return {
50
+ render: {
51
+ owner,
52
+ name: stub.name ?? DEFAULT_OUTLET_NAME,
53
+ template: stub.template,
54
+ model: stub.model,
55
+ controller: stub.controller
56
+ },
57
+ outlets: mainOutlet(void 0)
58
+ };
59
+ }
60
+ /**
61
+ * Builds the `OutletState` for a route story.
62
+ *
63
+ * `{{outlet}}` reads its child from Glimmer's *dynamic scope*, which
64
+ * `renderComponent` never populates — so route templates are rendered through
65
+ * Ember's own outlet root instead, and this is the state handed to it. Leaving
66
+ * `outlets.main` undefined is what makes `{{outlet}}` render a hole.
67
+ */
68
+ function buildRouteOutletState({ template, route, outlet, args, storyName, owner }) {
69
+ const child = outlet?.template ? buildChildRenderState(outlet, owner) : void 0;
70
+ return {
71
+ render: {
72
+ owner,
73
+ name: route.name ?? storyName,
74
+ template,
75
+ model: route.model ?? args.model,
76
+ controller: route.controller ?? args.controller
77
+ },
78
+ outlets: mainOutlet(child)
79
+ };
80
+ }
81
+ /**
82
+ * Ember's `OutletView` (the router's top-level view), reduced to the surface
83
+ * this module drives. It is only reachable through the container, so the type is
84
+ * declared here rather than imported from `@ember/-internals`.
85
+ */
86
+ /**
87
+ * The private container entries backing Ember's outlet root — the very full
88
+ * names `Router._setOutlets()` uses. Casting through this interface keeps the
89
+ * unsound lookups in one place instead of spread across the renderer.
90
+ */
91
+ /**
92
+ * `{{outlet}}` compiles to Ember's built-in `-outlet` keyword helper, which reads
93
+ * its child from Glimmer's *dynamic scope*. `renderComponent` starts that scope
94
+ * empty, so a route template rendered as a plain component crashes. Route stories
95
+ * are therefore rendered through the same outlet root `Router._setOutlets()` uses
96
+ * — reached by container name, never imported.
97
+ */
98
+ function createOutletView(container, state, element) {
99
+ const factory = container.factoryFor("view:-outlet");
100
+ if (!factory) throw new Error("ember-storybook: this story sets `parameters.ember.route`, but `view:-outlet` is not registered on this Ember build, so {{outlet}} cannot be rendered. Route stories render through Ember's own outlet root, which the router (`Router._setOutlets()`) uses as well.");
101
+ const view = factory.create({
102
+ environment: container.lookup("-environment:main"),
103
+ application: container.lookup("application:main"),
104
+ template: container.lookup("template:-outlet")
105
+ });
106
+ view.setOutletState(state);
107
+ run(() => {
108
+ view.appendTo(element);
109
+ });
110
+ return view;
111
+ }
112
+ /**
113
+ * Renders `state` into `element` through Ember's outlet root and waits for the
114
+ * render to settle.
115
+ */
116
+ async function mountOutletView(application, state, element) {
117
+ const view = createOutletView(application, state, element);
118
+ await renderSettled();
119
+ return view;
120
+ }
121
+ /**
122
+ * Swaps what the outlet renders, in place. This is how the router updates a live
123
+ * route tree, so arg changes do not tear the route's components down.
124
+ */
125
+ async function updateOutletView(view, state) {
126
+ view.setOutletState(state);
127
+ await renderSettled();
128
+ }
129
+ //#endregion
21
130
  //#region src/client/render.ts
22
131
  var render_exports = /* @__PURE__ */ __exportAll({
23
132
  render: () => render,
@@ -78,7 +187,7 @@ function teardownMount(context) {
78
187
  * story — down with it.
79
188
  */
80
189
  async function loadPlaceholderStub() {
81
- const { OutletPlaceholder } = await import("./outlet-placeholder-DZpXQLIa.mjs").then((n) => n.n);
190
+ const { OutletPlaceholder } = await import("./outlet-placeholder-BL2iFDVf.mjs").then((n) => n.n);
82
191
  return {
83
192
  name: "outlet",
84
193
  template: OutletPlaceholder
@@ -217,4 +326,4 @@ async function renderToCanvas({ storyFn, showMain, storyContext, forceRemount },
217
326
  //#endregion
218
327
  export { __exportAll as i, renderToCanvas as n, render_exports as r, render as t };
219
328
 
220
- //# sourceMappingURL=render-jYhDmzLM.mjs.map
329
+ //# sourceMappingURL=render-DzZ1vCNM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-DzZ1vCNM.mjs","names":["renderSettled","run","DEFAULT_OUTLET_NAME","resolveOutletStub","route","mode","placeholder","outlet","template","undefined","mainOutlet","child","main","buildChildRenderState","stub","owner","render","name","model","controller","outlets","buildRouteOutletState","args","storyName","createOutletView","container","state","element","factory","factoryFor","Error","view","create","environment","lookup","application","setOutletState","appendTo","mountOutletView","updateOutletView","Application","ApplicationInstance","destroy","renderComponent","VERSION","OUTLET_GLOBAL_KEY","buildRouteOutletState","mountOutletView","resolveOutletStub","updateOutletView","createAppResolver","normalizeStoryResult","isEmberBelow","major","minor","maj","min","split","map","Number","render","args","context","id","component","ember","parameters","route","Error","shallowEqual","a","b","aKeys","Object","keys","bKeys","length","every","key","hasOwn","is","withoutOutletGlobal","globals","fromEntries","entries","filter","relevantGlobals","contexts","Map","teardownMount","renderer","mount","remove","loadPlaceholderStub","OutletPlaceholder","name","template","routeOutletState","storyName","application","outlet","mode","placeholder","owner","mountStory","into","outletView","resolveAppOption","applicationInstance","initApp","appOption","opts","bootApp","storyContext","canvasElement","app","options","toLowerCase","includes","join","rootElement","obj","unregister","register","configure","boot","updateGlobals","renderToCanvas","storyFn","showMain","forceRemount","element","get","delete","storyResult","routeFromStory","existing","previousGlobals","currentGlobals","globalsChanged","undefined","set","canReuseApp","Boolean","document","createElement","append","mounted"],"sources":["../src/client/outlet.ts","../src/client/render.ts"],"sourcesContent":["import { renderSettled } from '@ember/renderer';\nimport { run } from '@ember/runloop';\n\nimport type { OutletMode, OutletStub, RouteParameters } from './types';\nimport type ApplicationInstance from '@ember/application/instance';\n\n/**\n * What Ember's outlet hands a route template. A route template is *not* a\n * component story: it receives exactly `@model` and `@controller`, because that\n * is all `{{outlet}}` passes down (`OUTLET_COMPONENT_TEMPLATE` in ember-source).\n */\nexport interface OutletRenderState {\n owner: object;\n name: string;\n controller: unknown;\n model: unknown;\n template: object;\n}\n\n/**\n * Mirrors ember-source's internal `OutletState`. The shape is structural, not\n * nominal, so a plain object is accepted by `setOutletState`; the leaf's\n * `outlets.main` is what a nested `{{outlet}}` reads.\n */\nexport interface OutletState {\n render: OutletRenderState;\n outlets: { main: OutletState | undefined };\n}\n\nexport interface RouteStoryInput {\n /** The route template — the story's `component`. */\n template: object;\n /** `parameters.ember.route`. */\n route: RouteParameters;\n /**\n * The resolved stub for `{{outlet}}` — see {@link resolveOutletStub}.\n * `undefined` leaves the outlet as a hole.\n */\n outlet?: OutletStub;\n /** Final (decorated) story args; `model`/`controller` feed the route. */\n args: Record<string, unknown>;\n /** Story name, used when `route.name` is not given. */\n storyName: string;\n /** The booted app instance the route renders under. */\n owner: object;\n}\n\nconst DEFAULT_OUTLET_NAME = 'outlet';\n\nexport interface OutletResolveInput {\n /** `parameters.ember.route` of the story being rendered. */\n route: RouteParameters;\n /** Value of the `outlet` global (see `src/outlet-key.ts`), if any. */\n mode?: OutletMode;\n /**\n * Produces the stub rendered when the global asks for a visible placeholder.\n * Called lazily (and so may be an async chunk load) and only when needed;\n * injected so this module stays free of Ember-owned template components.\n */\n placeholder: () => OutletStub | Promise<OutletStub>;\n}\n\n/**\n * Decides what `{{outlet}}` renders.\n *\n * An explicit `route.outlet` is author intent and always wins, so a story stays\n * deterministic no matter how the toolbar is set. Otherwise the global decides:\n * `placeholder` renders the injected marker, anything else leaves a hole.\n */\nexport async function resolveOutletStub({\n route,\n mode,\n placeholder\n}: OutletResolveInput): Promise<OutletStub | undefined> {\n if (route.outlet?.template) {\n return route.outlet;\n }\n\n return mode === 'placeholder' ? await placeholder() : undefined;\n}\n\n// Ember has no named outlets any more: every `{{outlet}}` is the \"main\" one.\nfunction mainOutlet(child: OutletState | undefined): OutletState['outlets'] {\n return { main: child };\n}\n\nfunction buildChildRenderState(stub: OutletStub, owner: object): OutletState {\n return {\n render: {\n owner,\n name: stub.name ?? DEFAULT_OUTLET_NAME,\n template: stub.template as object,\n model: stub.model,\n controller: stub.controller\n },\n // One level only: a stubbed child route is a leaf, so a `{{outlet}}` inside\n // it renders a hole as well.\n outlets: mainOutlet(undefined)\n };\n}\n\n/**\n * Builds the `OutletState` for a route story.\n *\n * `{{outlet}}` reads its child from Glimmer's *dynamic scope*, which\n * `renderComponent` never populates — so route templates are rendered through\n * Ember's own outlet root instead, and this is the state handed to it. Leaving\n * `outlets.main` undefined is what makes `{{outlet}}` render a hole.\n */\nexport function buildRouteOutletState({\n template,\n route,\n outlet,\n args,\n storyName,\n owner\n}: RouteStoryInput): OutletState {\n const child = outlet?.template ? buildChildRenderState(outlet, owner) : undefined;\n\n return {\n render: {\n owner,\n name: route.name ?? storyName,\n template,\n model: route.model ?? args.model,\n controller: route.controller ?? args.controller\n },\n outlets: mainOutlet(child)\n };\n}\n\n/**\n * Ember's `OutletView` (the router's top-level view), reduced to the surface\n * this module drives. It is only reachable through the container, so the type is\n * declared here rather than imported from `@ember/-internals`.\n */\nexport interface OutletView {\n appendTo(target: HTMLElement): void;\n setOutletState(state: OutletState): void;\n}\n\ninterface OutletViewFactory {\n create(options: Record<string, unknown>): OutletView;\n}\n\n/**\n * The private container entries backing Ember's outlet root — the very full\n * names `Router._setOutlets()` uses. Casting through this interface keeps the\n * unsound lookups in one place instead of spread across the renderer.\n */\ninterface OutletContainer {\n factoryFor(fullName: string): OutletViewFactory | undefined;\n lookup(fullName: string): unknown;\n}\n\n/**\n * `{{outlet}}` compiles to Ember's built-in `-outlet` keyword helper, which reads\n * its child from Glimmer's *dynamic scope*. `renderComponent` starts that scope\n * empty, so a route template rendered as a plain component crashes. Route stories\n * are therefore rendered through the same outlet root `Router._setOutlets()` uses\n * — reached by container name, never imported.\n */\nfunction createOutletView(\n container: OutletContainer,\n state: OutletState,\n element: HTMLElement\n): OutletView {\n const factory = container.factoryFor('view:-outlet');\n\n if (!factory) {\n throw new Error(\n 'ember-storybook: this story sets `parameters.ember.route`, but `view:-outlet` ' +\n 'is not registered on this Ember build, so {{outlet}} cannot be rendered. ' +\n \"Route stories render through Ember's own outlet root, which the router \" +\n '(`Router._setOutlets()`) uses as well.'\n );\n }\n\n const view = factory.create({\n environment: container.lookup('-environment:main'),\n application: container.lookup('application:main'),\n // The outlet root renders `{{outlet}}` itself; the story's route template\n // arrives through the state below, as `outlets.main`.\n template: container.lookup('template:-outlet')\n });\n\n view.setOutletState(state);\n\n // `appendTo` schedules on the `render` queue, so flush the run loop to render.\n run(() => {\n view.appendTo(element);\n });\n\n return view;\n}\n\n/**\n * Renders `state` into `element` through Ember's outlet root and waits for the\n * render to settle.\n */\nexport async function mountOutletView(\n application: ApplicationInstance,\n state: OutletState,\n element: HTMLElement\n): Promise<OutletView> {\n const view = createOutletView(application as unknown as OutletContainer, state, element);\n\n await renderSettled();\n\n return view;\n}\n\n/**\n * Swaps what the outlet renders, in place. This is how the router updates a live\n * route tree, so arg changes do not tear the route's components down.\n */\nexport async function updateOutletView(view: OutletView, state: OutletState): Promise<void> {\n view.setOutletState(state);\n await renderSettled();\n}\n","import Application from '@ember/application';\nimport ApplicationInstance from '@ember/application/instance';\nimport { destroy } from '@ember/destroyable';\nimport { renderComponent } from '@ember/renderer';\nimport { VERSION } from '@ember/version';\n\nimport { OUTLET_GLOBAL_KEY } from '../outlet-key';\nimport {\n buildRouteOutletState,\n mountOutletView,\n resolveOutletStub,\n updateOutletView\n} from './outlet';\nimport { createAppResolver, type EmberStoryResult, normalizeStoryResult } from './story-result';\n\nimport type { OutletView } from './outlet';\nimport type {\n AppParamater,\n EmberGlobals,\n EmberRenderer,\n OutletStub,\n RouteParameters,\n StoryContext\n} from './types';\nimport type { RenderResult } from '@ember/-internals/glimmer/lib/renderer';\nimport type { ArgsStoryFn, RenderContext } from 'storybook/internal/types';\n\ntype Args = Record<string, unknown>;\n\n// ember-source < 6.12 built a brand-new `BaseRenderer` (EvaluationContext) on\n// every `renderComponent` call and had no per-owner renderer cache. Re-rendering\n// an already-rendered owner therefore produced multiple live EvaluationContexts\n// that corrupted glimmer's shared opcode table, crashing with\n// \"Cannot read properties of null (reading 'syscall')\". 6.12+ added that cache\n// (`RENDERER_CACHE` keyed by owner), so reusing an app across renders is only\n// safe from 6.12 onward.\nfunction isEmberBelow(major: number, minor: number): boolean {\n const [maj, min] = VERSION.split('.').map(Number);\n\n return maj < major || (maj === major && min < minor);\n}\n\nexport const render: ArgsStoryFn<EmberRenderer> = (args, context): EmberStoryResult => {\n const { id, component } = context;\n // `ArgsStoryFn`'s context types `parameters` loosely; the framework's own\n // `StoryContext` carries the typed `ember` bag.\n const { ember } = context.parameters as StoryContext['parameters'];\n const route = ember?.route;\n\n if (typeof component === 'function' || typeof component === 'object') {\n // `route` is reported back like `args` are: `<RenderStory>` gets nothing but\n // the story result, and it needs to know a story is a route story.\n return { component, args, route };\n }\n\n throw new Error(\n `Unable to render story ${id} as the component annotation is missing from the default export`\n );\n};\n\nfunction shallowEqual(a: Record<string, unknown>, b: Record<string, unknown>) {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n return (\n aKeys.length === bKeys.length &&\n aKeys.every((key) => Object.hasOwn(b, key) && Object.is(a[key], b[key]))\n );\n}\n\nconst withoutOutletGlobal = (globals: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(globals).filter(([key]) => key !== OUTLET_GLOBAL_KEY));\n\n/**\n * Globals the renderer actually reacts to.\n *\n * The outlet menu only concerns route stories, so for a plain component story its\n * value is stripped: toggling \"Ember\" would otherwise count as a globals change\n * and needlessly remount (throwing away the component's state).\n */\nfunction relevantGlobals(\n route: RouteParameters | undefined,\n globals: Record<string, unknown>\n): Record<string, unknown> {\n return route ? globals : withoutOutletGlobal(globals);\n}\n\ntype RenderContextCache = {\n application: ApplicationInstance;\n mount: HTMLElement;\n args: Args;\n globals: Record<string, unknown>;\n // A story is mounted either as a plain component (`renderer`) or, for route\n // templates, through Ember's outlet root (`outletView`) — never both.\n renderer?: RenderResult;\n outletView?: OutletView;\n};\n\nconst contexts = new Map<EmberRenderer['canvasElement'], RenderContextCache>();\n\n/**\n * Tears the mounted story down, leaving the booted app alone so it can be\n * reused.\n *\n * Route stories are deliberately not cleaned up here: the outlet root is dropped\n * by destroying the app (which clears *and deregisters* its roots), and\n * `Renderer.cleanupRootFor()` would empty the root list without deregistering —\n * leaving the renderer in the global set so the next append would assert \"Cannot\n * register the same renderer twice\".\n */\nfunction teardownMount(context: RenderContextCache) {\n context.renderer?.destroy();\n context.mount.remove();\n}\n\n/**\n * The stub rendered when the toolbar asks for a visible placeholder.\n *\n * Loaded on demand rather than imported: folding the compiled template into the\n * boot chunk makes the bundler emit a `node:module` `createRequire` shim into it,\n * which throws in the browser and takes `renderToCanvas` — and with it every\n * story — down with it.\n */\nasync function loadPlaceholderStub(): Promise<OutletStub> {\n // Typed explicitly: the `.gts` module has no declaration reachable from here.\n const { OutletPlaceholder } = (await import('./outlet-placeholder.gts')) as {\n OutletPlaceholder: object;\n };\n\n // A route template receives only @model/@controller, so the marker renders its\n // own \"outlet\" label when the author did not supply one.\n return { name: 'outlet', template: OutletPlaceholder };\n}\n\nasync function routeOutletState({\n component,\n args,\n route,\n globals,\n storyName,\n application\n}: {\n component: object;\n args: Args;\n route: RouteParameters;\n globals: EmberGlobals;\n storyName: string;\n application: ApplicationInstance;\n}) {\n return buildRouteOutletState({\n template: component,\n route,\n outlet: await resolveOutletStub({\n route,\n mode: globals[OUTLET_GLOBAL_KEY],\n placeholder: loadPlaceholderStub\n }),\n args,\n storyName,\n owner: application\n });\n}\n\nasync function mountStory({\n application,\n component,\n args,\n route,\n globals,\n storyName,\n mount\n}: {\n application: ApplicationInstance;\n component: object;\n args: Args;\n route?: RouteParameters;\n globals: EmberGlobals;\n storyName: string;\n mount: HTMLElement;\n}): Promise<Pick<RenderContextCache, 'renderer' | 'outletView'>> {\n if (!route) {\n return {\n renderer: renderComponent(component, { args, into: mount, owner: application })\n };\n }\n\n // `{{outlet}}` reads its child from Glimmer's dynamic scope, which\n // `renderComponent` never populates — so a route template rendered as a plain\n // component throws instead of rendering. Route stories go through Ember's own\n // outlet root; the toolbar global decides whether `{{outlet}}` is a hole or a\n // placeholder (an explicit `route.outlet` overrides it).\n const outletView = await mountOutletView(\n application,\n await routeOutletState({ component, args, route, globals, storyName, application }),\n mount\n );\n\n return { outletView };\n}\n\nconst resolveAppOption = createAppResolver({\n application: Application,\n applicationInstance: ApplicationInstance\n});\n\nfunction initApp(appOption: AppParamater, opts: { rootElement: HTMLElement }) {\n return resolveAppOption(appOption, opts) as ApplicationInstance;\n}\n\nasync function bootApp(\n storyContext: StoryContext,\n canvasElement: EmberRenderer['canvasElement']\n): Promise<ApplicationInstance> {\n const ember = storyContext.parameters.ember;\n\n if (!ember?.app) {\n const options = Object.keys(storyContext.parameters)\n .filter((key) => key.toLowerCase().includes('ember'))\n .join(', ');\n\n throw new Error(\n [\n 'ember-storybook: no Ember application configured for this story.',\n 'Set `parameters.ember.app` in your preview (e.g. `.storybook/preview.ts`) to a function',\n 'returning an Application or ApplicationInstance. When not provided, every render would',\n `boot a bare Application without any resolver, failing with an obscure error. Found \\`parameters\\` keys: ${options || '(none)'}.`\n ].join(' ')\n );\n }\n\n const application: ApplicationInstance = initApp(ember.app, { rootElement: canvasElement });\n\n // modify the owner for the story\n if (ember.owner) {\n for (const [key, obj] of Object.entries(ember.owner) as [`${string}:${string}`, object][]) {\n application.unregister(key);\n application.register(key, obj);\n }\n }\n\n // configure and boot the instance so ember registers necessary environments\n ember.configure?.(application);\n await application.boot();\n ember.updateGlobals?.(storyContext.globals, application);\n\n return application;\n}\n\nexport async function renderToCanvas(\n {\n storyFn,\n showMain,\n storyContext,\n forceRemount\n }: RenderContext<EmberRenderer> & { storyContext: StoryContext },\n canvasElement: EmberRenderer['canvasElement']\n) {\n function unregister(element: EmberRenderer['canvasElement']) {\n const context = contexts.get(element);\n\n if (!context) {\n return;\n }\n\n contexts.delete(element);\n teardownMount(context);\n destroy(context.application);\n }\n\n // The story function carries the decorator pipeline; the framework's `render`\n // reports the final (possibly decorator-transformed) args back in its result.\n const storyResult = storyFn();\n const {\n component,\n args,\n route: routeFromStory\n } = normalizeStoryResult(storyResult, storyContext.args);\n // Stories that define their own `render` never report a route back, so the\n // parameter is the fallback.\n const route = routeFromStory ?? storyContext.parameters.ember?.route;\n\n const existing = contexts.get(canvasElement);\n const previousGlobals = relevantGlobals(route, existing?.globals ?? {});\n const currentGlobals = relevantGlobals(route, storyContext.globals);\n const globalsChanged =\n existing !== undefined && !forceRemount && !shallowEqual(previousGlobals, currentGlobals);\n\n // Nothing to do: a globals-only change (or a no-op call) must not tear down the\n // mounted component.\n if (existing && !forceRemount && !globalsChanged && shallowEqual(existing.args, args)) {\n return () => {\n unregister(canvasElement);\n };\n }\n\n // An outlet root is not tracked by the mount cache that broke component re-renders\n // (#27, #33), so it can be updated in place exactly the way the router swaps route\n // state. That preserves the route tree's component state and avoids re-appending.\n if (route && existing?.outletView && !forceRemount) {\n if (globalsChanged) {\n storyContext.parameters.ember?.updateGlobals?.(storyContext.globals, existing.application);\n }\n\n await updateOutletView(\n existing.outletView,\n await routeOutletState({\n component,\n args,\n route,\n globals: storyContext.globals,\n storyName: storyContext.name,\n application: existing.application\n })\n );\n\n contexts.set(canvasElement, { ...existing, args, globals: { ...storyContext.globals } });\n\n showMain();\n\n return () => {\n unregister(canvasElement);\n };\n }\n\n // Reuse the booted app across arg/globals updates, but always render into a\n // fresh mount: reusing the same mount makes Ember's render cache serve a stale\n // entry, which destroyed renders with obscure node errors (#27, #33).\n //\n // A route story and a component story cannot share an app: the outlet root can\n // only be dropped by destroying the app, so switching modes remounts.\n const canReuseApp =\n existing !== undefined && !forceRemount && Boolean(existing.outletView) === Boolean(route);\n\n let application: ApplicationInstance;\n\n if (isEmberBelow(6, 12)) {\n // Exception: ember-source < 6.12 has no per-owner renderer cache, so every\n // `renderComponent` call builds a new renderer (EvaluationContext) and\n // re-rendering an already-rendered owner corrupts the shared opcode table,\n // crashing with \"reading 'syscall'\". Boot a fresh app on every render instead,\n // so each owner is only ever rendered once (at the cost of app state + perf).\n if (existing) {\n unregister(canvasElement);\n }\n\n application = await bootApp(storyContext, canvasElement);\n } else if (canReuseApp) {\n // ember-source >= 6.12 caches one renderer per owner, so we can keep the same\n // app instance across re-renders. This preserves component/app state (@tracked\n // fields, services) and avoids re-booting on every control/global change.\n if (globalsChanged) {\n storyContext.parameters.ember?.updateGlobals?.(storyContext.globals, existing.application);\n }\n\n application = existing.application;\n teardownMount(existing);\n } else {\n if (existing) {\n unregister(canvasElement);\n }\n\n application = await bootApp(storyContext, canvasElement);\n }\n\n const mount = document.createElement('div');\n\n canvasElement.append(mount);\n\n const mounted = await mountStory({\n application,\n component,\n args,\n route,\n globals: storyContext.globals,\n storyName: storyContext.name,\n mount\n });\n\n contexts.set(canvasElement, {\n application,\n mount,\n args,\n globals: { ...storyContext.globals },\n ...mounted\n });\n\n showMain();\n\n return () => {\n unregister(canvasElement);\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-storybook",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "license": "MIT",
5
5
  "description": "Storybook for Ember: Develop, document, and test UI components in isolation",
6
6
  "keywords": [
@@ -1,119 +0,0 @@
1
- import { renderSettled } from "@ember/renderer";
2
- import { run } from "@ember/runloop";
3
- //#region src/client/outlet.ts
4
- /**
5
- * What Ember's outlet hands a route template. A route template is *not* a
6
- * component story: it receives exactly `@model` and `@controller`, because that
7
- * is all `{{outlet}}` passes down (`OUTLET_COMPONENT_TEMPLATE` in ember-source).
8
- */
9
- /**
10
- * Mirrors ember-source's internal `OutletState`. The shape is structural, not
11
- * nominal, so a plain object is accepted by `setOutletState`; the leaf's
12
- * `outlets.main` is what a nested `{{outlet}}` reads.
13
- */
14
- const DEFAULT_OUTLET_NAME = "outlet";
15
- /**
16
- * Name of the Storybook global that decides how `{{outlet}}` is rendered
17
- * (`hole` | `placeholder`). Declared here so the toolbar item and the renderer
18
- * read and write the same key.
19
- */
20
- const OUTLET_GLOBAL_KEY = "outlet";
21
- /**
22
- * Decides what `{{outlet}}` renders.
23
- *
24
- * An explicit `route.outlet` is author intent and always wins, so a story stays
25
- * deterministic no matter how the toolbar is set. Otherwise the global decides:
26
- * `placeholder` renders the injected marker, anything else leaves a hole.
27
- */
28
- async function resolveOutletStub({ route, mode, placeholder }) {
29
- if (route.outlet?.template) return route.outlet;
30
- return mode === "placeholder" ? await placeholder() : void 0;
31
- }
32
- function mainOutlet(child) {
33
- return { main: child };
34
- }
35
- function buildChildRenderState(stub, owner) {
36
- return {
37
- render: {
38
- owner,
39
- name: stub.name ?? DEFAULT_OUTLET_NAME,
40
- template: stub.template,
41
- model: stub.model,
42
- controller: stub.controller
43
- },
44
- outlets: mainOutlet(void 0)
45
- };
46
- }
47
- /**
48
- * Builds the `OutletState` for a route story.
49
- *
50
- * `{{outlet}}` reads its child from Glimmer's *dynamic scope*, which
51
- * `renderComponent` never populates — so route templates are rendered through
52
- * Ember's own outlet root instead, and this is the state handed to it. Leaving
53
- * `outlets.main` undefined is what makes `{{outlet}}` render a hole.
54
- */
55
- function buildRouteOutletState({ template, route, outlet, args, storyName, owner }) {
56
- const child = outlet?.template ? buildChildRenderState(outlet, owner) : void 0;
57
- return {
58
- render: {
59
- owner,
60
- name: route.name ?? storyName,
61
- template,
62
- model: route.model ?? args.model,
63
- controller: route.controller ?? args.controller
64
- },
65
- outlets: mainOutlet(child)
66
- };
67
- }
68
- /**
69
- * Ember's `OutletView` (the router's top-level view), reduced to the surface
70
- * this module drives. It is only reachable through the container, so the type is
71
- * declared here rather than imported from `@ember/-internals`.
72
- */
73
- /**
74
- * The private container entries backing Ember's outlet root — the very full
75
- * names `Router._setOutlets()` uses. Casting through this interface keeps the
76
- * unsound lookups in one place instead of spread across the renderer.
77
- */
78
- /**
79
- * `{{outlet}}` compiles to Ember's built-in `-outlet` keyword helper, which reads
80
- * its child from Glimmer's *dynamic scope*. `renderComponent` starts that scope
81
- * empty, so a route template rendered as a plain component crashes. Route stories
82
- * are therefore rendered through the same outlet root `Router._setOutlets()` uses
83
- * — reached by container name, never imported.
84
- */
85
- function createOutletView(container, state, element) {
86
- const factory = container.factoryFor("view:-outlet");
87
- if (!factory) throw new Error("ember-storybook: this story sets `parameters.ember.route`, but `view:-outlet` is not registered on this Ember build, so {{outlet}} cannot be rendered. Route stories render through Ember's own outlet root, which the router (`Router._setOutlets()`) uses as well.");
88
- const view = factory.create({
89
- environment: container.lookup("-environment:main"),
90
- application: container.lookup("application:main"),
91
- template: container.lookup("template:-outlet")
92
- });
93
- view.setOutletState(state);
94
- run(() => {
95
- view.appendTo(element);
96
- });
97
- return view;
98
- }
99
- /**
100
- * Renders `state` into `element` through Ember's outlet root and waits for the
101
- * render to settle.
102
- */
103
- async function mountOutletView(application, state, element) {
104
- const view = createOutletView(application, state, element);
105
- await renderSettled();
106
- return view;
107
- }
108
- /**
109
- * Swaps what the outlet renders, in place. This is how the router updates a live
110
- * route tree, so arg changes do not tear the route's components down.
111
- */
112
- async function updateOutletView(view, state) {
113
- view.setOutletState(state);
114
- await renderSettled();
115
- }
116
- //#endregion
117
- export { updateOutletView as a, resolveOutletStub as i, buildRouteOutletState as n, mountOutletView as r, OUTLET_GLOBAL_KEY as t };
118
-
119
- //# sourceMappingURL=outlet-Dc5ySBso.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"outlet-Dc5ySBso.mjs","names":["renderSettled","run","DEFAULT_OUTLET_NAME","OUTLET_GLOBAL_KEY","resolveOutletStub","route","mode","placeholder","outlet","template","undefined","mainOutlet","child","main","buildChildRenderState","stub","owner","render","name","model","controller","outlets","buildRouteOutletState","args","storyName","createOutletView","container","state","element","factory","factoryFor","Error","view","create","environment","lookup","application","setOutletState","appendTo","mountOutletView","updateOutletView"],"sources":["../src/client/outlet.ts"],"sourcesContent":["import { renderSettled } from '@ember/renderer';\nimport { run } from '@ember/runloop';\n\nimport type { OutletMode, OutletStub, RouteParameters } from './types';\nimport type ApplicationInstance from '@ember/application/instance';\n\n/**\n * What Ember's outlet hands a route template. A route template is *not* a\n * component story: it receives exactly `@model` and `@controller`, because that\n * is all `{{outlet}}` passes down (`OUTLET_COMPONENT_TEMPLATE` in ember-source).\n */\nexport interface OutletRenderState {\n owner: object;\n name: string;\n controller: unknown;\n model: unknown;\n template: object;\n}\n\n/**\n * Mirrors ember-source's internal `OutletState`. The shape is structural, not\n * nominal, so a plain object is accepted by `setOutletState`; the leaf's\n * `outlets.main` is what a nested `{{outlet}}` reads.\n */\nexport interface OutletState {\n render: OutletRenderState;\n outlets: { main: OutletState | undefined };\n}\n\nexport interface RouteStoryInput {\n /** The route template — the story's `component`. */\n template: object;\n /** `parameters.ember.route`. */\n route: RouteParameters;\n /**\n * The resolved stub for `{{outlet}}` — see {@link resolveOutletStub}.\n * `undefined` leaves the outlet as a hole.\n */\n outlet?: OutletStub;\n /** Final (decorated) story args; `model`/`controller` feed the route. */\n args: Record<string, unknown>;\n /** Story name, used when `route.name` is not given. */\n storyName: string;\n /** The booted app instance the route renders under. */\n owner: object;\n}\n\nconst DEFAULT_OUTLET_NAME = 'outlet';\n\n/**\n * Name of the Storybook global that decides how `{{outlet}}` is rendered\n * (`hole` | `placeholder`). Declared here so the toolbar item and the renderer\n * read and write the same key.\n */\nexport const OUTLET_GLOBAL_KEY = 'outlet';\n\nexport interface OutletResolveInput {\n /** `parameters.ember.route` of the story being rendered. */\n route: RouteParameters;\n /** Value of the {@link OUTLET_GLOBAL_KEY} global, if any. */\n mode?: OutletMode;\n /**\n * Produces the stub rendered when the global asks for a visible placeholder.\n * Called lazily (and so may be an async chunk load) and only when needed;\n * injected so this module stays free of Ember-owned template components.\n */\n placeholder: () => OutletStub | Promise<OutletStub>;\n}\n\n/**\n * Decides what `{{outlet}}` renders.\n *\n * An explicit `route.outlet` is author intent and always wins, so a story stays\n * deterministic no matter how the toolbar is set. Otherwise the global decides:\n * `placeholder` renders the injected marker, anything else leaves a hole.\n */\nexport async function resolveOutletStub({\n route,\n mode,\n placeholder\n}: OutletResolveInput): Promise<OutletStub | undefined> {\n if (route.outlet?.template) {\n return route.outlet;\n }\n\n return mode === 'placeholder' ? await placeholder() : undefined;\n}\n\n// Ember has no named outlets any more: every `{{outlet}}` is the \"main\" one.\nfunction mainOutlet(child: OutletState | undefined): OutletState['outlets'] {\n return { main: child };\n}\n\nfunction buildChildRenderState(stub: OutletStub, owner: object): OutletState {\n return {\n render: {\n owner,\n name: stub.name ?? DEFAULT_OUTLET_NAME,\n template: stub.template as object,\n model: stub.model,\n controller: stub.controller\n },\n // One level only: a stubbed child route is a leaf, so a `{{outlet}}` inside\n // it renders a hole as well.\n outlets: mainOutlet(undefined)\n };\n}\n\n/**\n * Builds the `OutletState` for a route story.\n *\n * `{{outlet}}` reads its child from Glimmer's *dynamic scope*, which\n * `renderComponent` never populates — so route templates are rendered through\n * Ember's own outlet root instead, and this is the state handed to it. Leaving\n * `outlets.main` undefined is what makes `{{outlet}}` render a hole.\n */\nexport function buildRouteOutletState({\n template,\n route,\n outlet,\n args,\n storyName,\n owner\n}: RouteStoryInput): OutletState {\n const child = outlet?.template ? buildChildRenderState(outlet, owner) : undefined;\n\n return {\n render: {\n owner,\n name: route.name ?? storyName,\n template,\n model: route.model ?? args.model,\n controller: route.controller ?? args.controller\n },\n outlets: mainOutlet(child)\n };\n}\n\n/**\n * Ember's `OutletView` (the router's top-level view), reduced to the surface\n * this module drives. It is only reachable through the container, so the type is\n * declared here rather than imported from `@ember/-internals`.\n */\nexport interface OutletView {\n appendTo(target: HTMLElement): void;\n setOutletState(state: OutletState): void;\n}\n\ninterface OutletViewFactory {\n create(options: Record<string, unknown>): OutletView;\n}\n\n/**\n * The private container entries backing Ember's outlet root — the very full\n * names `Router._setOutlets()` uses. Casting through this interface keeps the\n * unsound lookups in one place instead of spread across the renderer.\n */\ninterface OutletContainer {\n factoryFor(fullName: string): OutletViewFactory | undefined;\n lookup(fullName: string): unknown;\n}\n\n/**\n * `{{outlet}}` compiles to Ember's built-in `-outlet` keyword helper, which reads\n * its child from Glimmer's *dynamic scope*. `renderComponent` starts that scope\n * empty, so a route template rendered as a plain component crashes. Route stories\n * are therefore rendered through the same outlet root `Router._setOutlets()` uses\n * — reached by container name, never imported.\n */\nfunction createOutletView(\n container: OutletContainer,\n state: OutletState,\n element: HTMLElement\n): OutletView {\n const factory = container.factoryFor('view:-outlet');\n\n if (!factory) {\n throw new Error(\n 'ember-storybook: this story sets `parameters.ember.route`, but `view:-outlet` ' +\n 'is not registered on this Ember build, so {{outlet}} cannot be rendered. ' +\n \"Route stories render through Ember's own outlet root, which the router \" +\n '(`Router._setOutlets()`) uses as well.'\n );\n }\n\n const view = factory.create({\n environment: container.lookup('-environment:main'),\n application: container.lookup('application:main'),\n // The outlet root renders `{{outlet}}` itself; the story's route template\n // arrives through the state below, as `outlets.main`.\n template: container.lookup('template:-outlet')\n });\n\n view.setOutletState(state);\n\n // `appendTo` schedules on the `render` queue, so flush the run loop to render.\n run(() => {\n view.appendTo(element);\n });\n\n return view;\n}\n\n/**\n * Renders `state` into `element` through Ember's outlet root and waits for the\n * render to settle.\n */\nexport async function mountOutletView(\n application: ApplicationInstance,\n state: OutletState,\n element: HTMLElement\n): Promise<OutletView> {\n const view = createOutletView(application as unknown as OutletContainer, state, element);\n\n await renderSettled();\n\n return view;\n}\n\n/**\n * Swaps what the outlet renders, in place. This is how the router updates a live\n * route tree, so arg changes do not tear the route's components down.\n */\nexport async function updateOutletView(view: OutletView, state: OutletState): Promise<void> {\n view.setOutletState(state);\n await renderSettled();\n}\n"],"mappings":";;;;;;;;;;;;;AA+CA,MAAME,sBAAsB;;;;;;AAO5B,MAAaC,oBAAoB;;;;;;;;AAsBjC,eAAsBC,kBAAkB,EACtCC,OACAC,MACAC,eACsD;CACtD,IAAIF,MAAMG,QAAQC,UAChB,OAAOJ,MAAMG;CAGf,OAAOF,SAAS,gBAAgB,MAAMC,YAAY,IAAIG,KAAAA;AACxD;AAGA,SAASC,WAAWC,OAAwD;CAC1E,OAAO,EAAEC,MAAMD,MAAM;AACvB;AAEA,SAASE,sBAAsBC,MAAkBC,OAA4B;CAC3E,OAAO;EACLC,QAAQ;GACND;GACAE,MAAMH,KAAKG,QAAQhB;GACnBO,UAAUM,KAAKN;GACfU,OAAOJ,KAAKI;GACZC,YAAYL,KAAKK;EACnB;EAGAC,SAASV,WAAWD,KAAAA,CAAS;CAC/B;AACF;;;;;;;;;AAUA,SAAgBY,sBAAsB,EACpCb,UACAJ,OACAG,QACAe,MACAC,WACAR,SAC+B;CAC/B,MAAMJ,QAAQJ,QAAQC,WAAWK,sBAAsBN,QAAQQ,KAAK,IAAIN,KAAAA;CAExE,OAAO;EACLO,QAAQ;GACND;GACAE,MAAMb,MAAMa,QAAQM;GACpBf;GACAU,OAAOd,MAAMc,SAASI,KAAKJ;GAC3BC,YAAYf,MAAMe,cAAcG,KAAKH;EACvC;EACAC,SAASV,WAAWC,KAAK;CAC3B;AACF;;;;;;;;;;;;;;;;;;AAiCA,SAASa,iBACPC,WACAC,OACAC,SACY;CACZ,MAAMC,UAAUH,UAAUI,WAAW,cAAc;CAEnD,IAAI,CAACD,SACH,MAAM,IAAIE,MACR,sQAIF;CAGF,MAAMC,OAAOH,QAAQI,OAAO;EAC1BC,aAAaR,UAAUS,OAAO,mBAAmB;EACjDC,aAAaV,UAAUS,OAAO,kBAAkB;EAGhD1B,UAAUiB,UAAUS,OAAO,kBAAkB;CAC/C,CAAC;CAEDH,KAAKK,eAAeV,KAAK;CAGzB1B,UAAU;EACR+B,KAAKM,SAASV,OAAO;CACvB,CAAC;CAED,OAAOI;AACT;;;;;AAMA,eAAsBO,gBACpBH,aACAT,OACAC,SACqB;CACrB,MAAMI,OAAOP,iBAAiBW,aAA2CT,OAAOC,OAAO;CAEvF,MAAM5B,cAAc;CAEpB,OAAOgC;AACT;;;;;AAMA,eAAsBQ,iBAAiBR,MAAkBL,OAAmC;CAC1FK,KAAKK,eAAeV,KAAK;CACzB,MAAM3B,cAAc;AACtB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"render-jYhDmzLM.mjs","names":["Application","ApplicationInstance","destroy","renderComponent","VERSION","buildRouteOutletState","mountOutletView","OUTLET_GLOBAL_KEY","resolveOutletStub","updateOutletView","createAppResolver","normalizeStoryResult","isEmberBelow","major","minor","maj","min","split","map","Number","render","args","context","id","component","ember","parameters","route","Error","shallowEqual","a","b","aKeys","Object","keys","bKeys","length","every","key","hasOwn","is","withoutOutletGlobal","globals","fromEntries","entries","filter","relevantGlobals","contexts","Map","teardownMount","renderer","mount","remove","loadPlaceholderStub","OutletPlaceholder","name","template","routeOutletState","storyName","application","outlet","mode","placeholder","owner","mountStory","into","outletView","resolveAppOption","applicationInstance","initApp","appOption","opts","bootApp","storyContext","canvasElement","app","options","toLowerCase","includes","join","rootElement","obj","unregister","register","configure","boot","updateGlobals","renderToCanvas","storyFn","showMain","forceRemount","element","get","delete","storyResult","routeFromStory","existing","previousGlobals","currentGlobals","globalsChanged","undefined","set","canReuseApp","Boolean","document","createElement","append","mounted"],"sources":["../src/client/render.ts"],"sourcesContent":["import Application from '@ember/application';\nimport ApplicationInstance from '@ember/application/instance';\nimport { destroy } from '@ember/destroyable';\nimport { renderComponent } from '@ember/renderer';\nimport { VERSION } from '@ember/version';\n\nimport {\n buildRouteOutletState,\n mountOutletView,\n OUTLET_GLOBAL_KEY,\n resolveOutletStub,\n updateOutletView\n} from './outlet';\nimport { createAppResolver, type EmberStoryResult, normalizeStoryResult } from './story-result';\n\nimport type { OutletView } from './outlet';\nimport type {\n AppParamater,\n EmberGlobals,\n EmberRenderer,\n OutletStub,\n RouteParameters,\n StoryContext\n} from './types';\nimport type { RenderResult } from '@ember/-internals/glimmer/lib/renderer';\nimport type { ArgsStoryFn, RenderContext } from 'storybook/internal/types';\n\ntype Args = Record<string, unknown>;\n\n// ember-source < 6.12 built a brand-new `BaseRenderer` (EvaluationContext) on\n// every `renderComponent` call and had no per-owner renderer cache. Re-rendering\n// an already-rendered owner therefore produced multiple live EvaluationContexts\n// that corrupted glimmer's shared opcode table, crashing with\n// \"Cannot read properties of null (reading 'syscall')\". 6.12+ added that cache\n// (`RENDERER_CACHE` keyed by owner), so reusing an app across renders is only\n// safe from 6.12 onward.\nfunction isEmberBelow(major: number, minor: number): boolean {\n const [maj, min] = VERSION.split('.').map(Number);\n\n return maj < major || (maj === major && min < minor);\n}\n\nexport const render: ArgsStoryFn<EmberRenderer> = (args, context): EmberStoryResult => {\n const { id, component } = context;\n // `ArgsStoryFn`'s context types `parameters` loosely; the framework's own\n // `StoryContext` carries the typed `ember` bag.\n const { ember } = context.parameters as StoryContext['parameters'];\n const route = ember?.route;\n\n if (typeof component === 'function' || typeof component === 'object') {\n // `route` is reported back like `args` are: `<RenderStory>` gets nothing but\n // the story result, and it needs to know a story is a route story.\n return { component, args, route };\n }\n\n throw new Error(\n `Unable to render story ${id} as the component annotation is missing from the default export`\n );\n};\n\nfunction shallowEqual(a: Record<string, unknown>, b: Record<string, unknown>) {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n return (\n aKeys.length === bKeys.length &&\n aKeys.every((key) => Object.hasOwn(b, key) && Object.is(a[key], b[key]))\n );\n}\n\nconst withoutOutletGlobal = (globals: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(globals).filter(([key]) => key !== OUTLET_GLOBAL_KEY));\n\n/**\n * Globals the renderer actually reacts to.\n *\n * The outlet menu only concerns route stories, so for a plain component story its\n * value is stripped: toggling \"Ember\" would otherwise count as a globals change\n * and needlessly remount (throwing away the component's state).\n */\nfunction relevantGlobals(\n route: RouteParameters | undefined,\n globals: Record<string, unknown>\n): Record<string, unknown> {\n return route ? globals : withoutOutletGlobal(globals);\n}\n\ntype RenderContextCache = {\n application: ApplicationInstance;\n mount: HTMLElement;\n args: Args;\n globals: Record<string, unknown>;\n // A story is mounted either as a plain component (`renderer`) or, for route\n // templates, through Ember's outlet root (`outletView`) — never both.\n renderer?: RenderResult;\n outletView?: OutletView;\n};\n\nconst contexts = new Map<EmberRenderer['canvasElement'], RenderContextCache>();\n\n/**\n * Tears the mounted story down, leaving the booted app alone so it can be\n * reused.\n *\n * Route stories are deliberately not cleaned up here: the outlet root is dropped\n * by destroying the app (which clears *and deregisters* its roots), and\n * `Renderer.cleanupRootFor()` would empty the root list without deregistering —\n * leaving the renderer in the global set so the next append would assert \"Cannot\n * register the same renderer twice\".\n */\nfunction teardownMount(context: RenderContextCache) {\n context.renderer?.destroy();\n context.mount.remove();\n}\n\n/**\n * The stub rendered when the toolbar asks for a visible placeholder.\n *\n * Loaded on demand rather than imported: folding the compiled template into the\n * boot chunk makes the bundler emit a `node:module` `createRequire` shim into it,\n * which throws in the browser and takes `renderToCanvas` — and with it every\n * story — down with it.\n */\nasync function loadPlaceholderStub(): Promise<OutletStub> {\n // Typed explicitly: the `.gts` module has no declaration reachable from here.\n const { OutletPlaceholder } = (await import('./outlet-placeholder.gts')) as {\n OutletPlaceholder: object;\n };\n\n // A route template receives only @model/@controller, so the marker renders its\n // own \"outlet\" label when the author did not supply one.\n return { name: 'outlet', template: OutletPlaceholder };\n}\n\nasync function routeOutletState({\n component,\n args,\n route,\n globals,\n storyName,\n application\n}: {\n component: object;\n args: Args;\n route: RouteParameters;\n globals: EmberGlobals;\n storyName: string;\n application: ApplicationInstance;\n}) {\n return buildRouteOutletState({\n template: component,\n route,\n outlet: await resolveOutletStub({\n route,\n mode: globals[OUTLET_GLOBAL_KEY],\n placeholder: loadPlaceholderStub\n }),\n args,\n storyName,\n owner: application\n });\n}\n\nasync function mountStory({\n application,\n component,\n args,\n route,\n globals,\n storyName,\n mount\n}: {\n application: ApplicationInstance;\n component: object;\n args: Args;\n route?: RouteParameters;\n globals: EmberGlobals;\n storyName: string;\n mount: HTMLElement;\n}): Promise<Pick<RenderContextCache, 'renderer' | 'outletView'>> {\n if (!route) {\n return {\n renderer: renderComponent(component, { args, into: mount, owner: application })\n };\n }\n\n // `{{outlet}}` reads its child from Glimmer's dynamic scope, which\n // `renderComponent` never populates — so a route template rendered as a plain\n // component throws instead of rendering. Route stories go through Ember's own\n // outlet root; the toolbar global decides whether `{{outlet}}` is a hole or a\n // placeholder (an explicit `route.outlet` overrides it).\n const outletView = await mountOutletView(\n application,\n await routeOutletState({ component, args, route, globals, storyName, application }),\n mount\n );\n\n return { outletView };\n}\n\nconst resolveAppOption = createAppResolver({\n application: Application,\n applicationInstance: ApplicationInstance\n});\n\nfunction initApp(appOption: AppParamater, opts: { rootElement: HTMLElement }) {\n return resolveAppOption(appOption, opts) as ApplicationInstance;\n}\n\nasync function bootApp(\n storyContext: StoryContext,\n canvasElement: EmberRenderer['canvasElement']\n): Promise<ApplicationInstance> {\n const ember = storyContext.parameters.ember;\n\n if (!ember?.app) {\n const options = Object.keys(storyContext.parameters)\n .filter((key) => key.toLowerCase().includes('ember'))\n .join(', ');\n\n throw new Error(\n [\n 'ember-storybook: no Ember application configured for this story.',\n 'Set `parameters.ember.app` in your preview (e.g. `.storybook/preview.ts`) to a function',\n 'returning an Application or ApplicationInstance. When not provided, every render would',\n `boot a bare Application without any resolver, failing with an obscure error. Found \\`parameters\\` keys: ${options || '(none)'}.`\n ].join(' ')\n );\n }\n\n const application: ApplicationInstance = initApp(ember.app, { rootElement: canvasElement });\n\n // modify the owner for the story\n if (ember.owner) {\n for (const [key, obj] of Object.entries(ember.owner) as [`${string}:${string}`, object][]) {\n application.unregister(key);\n application.register(key, obj);\n }\n }\n\n // configure and boot the instance so ember registers necessary environments\n ember.configure?.(application);\n await application.boot();\n ember.updateGlobals?.(storyContext.globals, application);\n\n return application;\n}\n\nexport async function renderToCanvas(\n {\n storyFn,\n showMain,\n storyContext,\n forceRemount\n }: RenderContext<EmberRenderer> & { storyContext: StoryContext },\n canvasElement: EmberRenderer['canvasElement']\n) {\n function unregister(element: EmberRenderer['canvasElement']) {\n const context = contexts.get(element);\n\n if (!context) {\n return;\n }\n\n contexts.delete(element);\n teardownMount(context);\n destroy(context.application);\n }\n\n // The story function carries the decorator pipeline; the framework's `render`\n // reports the final (possibly decorator-transformed) args back in its result.\n const storyResult = storyFn();\n const {\n component,\n args,\n route: routeFromStory\n } = normalizeStoryResult(storyResult, storyContext.args);\n // Stories that define their own `render` never report a route back, so the\n // parameter is the fallback.\n const route = routeFromStory ?? storyContext.parameters.ember?.route;\n\n const existing = contexts.get(canvasElement);\n const previousGlobals = relevantGlobals(route, existing?.globals ?? {});\n const currentGlobals = relevantGlobals(route, storyContext.globals);\n const globalsChanged =\n existing !== undefined && !forceRemount && !shallowEqual(previousGlobals, currentGlobals);\n\n // Nothing to do: a globals-only change (or a no-op call) must not tear down the\n // mounted component.\n if (existing && !forceRemount && !globalsChanged && shallowEqual(existing.args, args)) {\n return () => {\n unregister(canvasElement);\n };\n }\n\n // An outlet root is not tracked by the mount cache that broke component re-renders\n // (#27, #33), so it can be updated in place exactly the way the router swaps route\n // state. That preserves the route tree's component state and avoids re-appending.\n if (route && existing?.outletView && !forceRemount) {\n if (globalsChanged) {\n storyContext.parameters.ember?.updateGlobals?.(storyContext.globals, existing.application);\n }\n\n await updateOutletView(\n existing.outletView,\n await routeOutletState({\n component,\n args,\n route,\n globals: storyContext.globals,\n storyName: storyContext.name,\n application: existing.application\n })\n );\n\n contexts.set(canvasElement, { ...existing, args, globals: { ...storyContext.globals } });\n\n showMain();\n\n return () => {\n unregister(canvasElement);\n };\n }\n\n // Reuse the booted app across arg/globals updates, but always render into a\n // fresh mount: reusing the same mount makes Ember's render cache serve a stale\n // entry, which destroyed renders with obscure node errors (#27, #33).\n //\n // A route story and a component story cannot share an app: the outlet root can\n // only be dropped by destroying the app, so switching modes remounts.\n const canReuseApp =\n existing !== undefined && !forceRemount && Boolean(existing.outletView) === Boolean(route);\n\n let application: ApplicationInstance;\n\n if (isEmberBelow(6, 12)) {\n // Exception: ember-source < 6.12 has no per-owner renderer cache, so every\n // `renderComponent` call builds a new renderer (EvaluationContext) and\n // re-rendering an already-rendered owner corrupts the shared opcode table,\n // crashing with \"reading 'syscall'\". Boot a fresh app on every render instead,\n // so each owner is only ever rendered once (at the cost of app state + perf).\n if (existing) {\n unregister(canvasElement);\n }\n\n application = await bootApp(storyContext, canvasElement);\n } else if (canReuseApp) {\n // ember-source >= 6.12 caches one renderer per owner, so we can keep the same\n // app instance across re-renders. This preserves component/app state (@tracked\n // fields, services) and avoids re-booting on every control/global change.\n if (globalsChanged) {\n storyContext.parameters.ember?.updateGlobals?.(storyContext.globals, existing.application);\n }\n\n application = existing.application;\n teardownMount(existing);\n } else {\n if (existing) {\n unregister(canvasElement);\n }\n\n application = await bootApp(storyContext, canvasElement);\n }\n\n const mount = document.createElement('div');\n\n canvasElement.append(mount);\n\n const mounted = await mountStory({\n application,\n component,\n args,\n route,\n globals: storyContext.globals,\n storyName: storyContext.name,\n mount\n });\n\n contexts.set(canvasElement, {\n application,\n mount,\n args,\n globals: { ...storyContext.globals },\n ...mounted\n });\n\n showMain();\n\n return () => {\n unregister(canvasElement);\n };\n}\n"],"mappings":"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"}