@poveste/plugin-svelte 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,8 +53,8 @@ and your content reads it from the snippet:
53
53
  > preview — Poveste owns the state instead. A story with controls but no `initState` logs an
54
54
  > error explaining this.
55
55
  >
56
- > [How, and why](https://poveste.dev/guide/migration-from-histoire.html#svelte-story-state-moves-to-initstate)
56
+ > [How, and why](https://poveste.dev/guide/migration-from-histoire#svelte-story-state-moves-to-initstate)
57
57
 
58
- [Svelte guide](https://poveste.dev/guide/svelte/getting-started.html) ·
59
- [SvelteKit](https://poveste.dev/guide/svelte/getting-started.html#sveltekit) ·
58
+ [Svelte guide](https://poveste.dev/guide/svelte/getting-started) ·
59
+ [SvelteKit](https://poveste.dev/guide/sveltekit/getting-started) ·
60
60
  [Documentation](https://poveste.dev)
@@ -1 +1 @@
1
- import e from"./MountVariant.svelte";import{omitInheritStoryProps as t}from"@poveste/shared";import{getContext as n,setContext as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";function a(a,o){let s=i.sanitize_slots(o),c=i.legacy_rest_props(o,[`children`,`$$slots`,`$$events`,`$$legacy`]),l=i.legacy_rest_props(c,[]);i.push(o,!1);let u=n(`__pvtStory`);r(`__pvtIndex`,{value:0}),r(`__pvtSlots`,s);let d=Object.keys(u).filter(e=>!t.includes(e)).reduce((e,t)=>(e[t]=u[t],e),{});i.init();var f=i.comment(),p=i.first_child(f),m=t=>{e(t,i.spread_props(()=>d,()=>l,{implicit:!0,children:(e,t)=>{var n=i.comment(),r=i.first_child(n);i.slot(r,o,`default`,{},null),i.append(e,n)},$$slots:{default:!0,controls:(e,t)=>{var n=i.comment(),r=i.first_child(n);i.slot(r,o,`controls`,{},null),i.append(e,n)}}}))},h=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,o,`default`,{},null),i.append(e,t)};i.if(p,e=>{i.untrack(()=>u.variants.length===1&&u.variants[0].id===`_default`)?e(m):e(h,-1)}),i.append(a,f),i.pop()}export{a as default};
1
+ import e from"./MountVariant.svelte";import{omitInheritStoryProps as t}from"@poveste/shared";import{getContext as n,setContext as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";function a(a,o){let s=i.sanitize_slots(o),c=i.legacy_rest_props(o,[`children`,`$$slots`,`$$events`,`$$legacy`]),l=i.legacy_rest_props(c,[]);i.push(o,!1);let u=n(`__pvtStory`);r(`__pvtIndex`,{value:0}),r(`__pvtSlots`,s),r(`__pvtStoryProps`,l);let d=Object.keys(u).filter(e=>!t.includes(e)).reduce((e,t)=>(e[t]=u[t],e),{});i.init();var f=i.comment(),p=i.first_child(f),m=t=>{e(t,i.spread_props(()=>d,()=>l,{implicit:!0,children:(e,t)=>{var n=i.comment(),r=i.first_child(n);i.slot(r,o,`default`,{},null),i.append(e,n)},$$slots:{default:!0,controls:(e,t)=>{var n=i.comment(),r=i.first_child(n);i.slot(r,o,`controls`,{},null),i.append(e,n)}}}))},h=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,o,`default`,{},null),i.append(e,t)};i.if(p,e=>{i.untrack(()=>u.variants.length===1&&u.variants[0].id===`_default`)?e(m):e(h,-1)}),i.append(a,f),i.pop()}export{a as default};
@@ -7,6 +7,10 @@
7
7
  const index = { value: 0 }
8
8
  setContext('__pvtIndex', index)
9
9
  setContext('__pvtSlots', $$slots)
10
+ // Slots were given this treatment and props never were, so a story-level prop
11
+ // reached an implicit variant and was dropped the moment a story declared
12
+ // explicit ones — `$$restProps` is only spread in the branch below (#466).
13
+ setContext('__pvtStoryProps', $$restProps)
10
14
 
11
15
  // Not `$:`: Svelte invalidates a reactive statement when a variable it
12
16
  // references is reassigned, and `story` is a const read from context that
@@ -1 +1 @@
1
- import{afterUpdate as e,getContext as t,onDestroy as n}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as r from"svelte/internal/client";r.from_html(`<!> <!>`,1);function i(i,a){let o=r.sanitize_slots(a);r.push(a,!1);let s=r.prop(a,`source`,8,null),c=r.prop(a,`responsiveDisabled`,8,!1),l=r.prop(a,`autoPropsDisabled`,8,!1),u=r.prop(a,`setupApp`,8,null),d=r.prop(a,`implicit`,8,!1),f=t(`__pvtStory`),p=t(`__pvtIndex`),m=t(`__pvtSlots`),h=t(`__pvtTargetVariantId`)??null,g=f.variants[p.value];p.value++;let _=!1;function v(){Object.assign(g,{slots:()=>({default:!0,controls:o.controls??m.controls}),source:s(),responsiveDisabled:c(),autoPropsDisabled:l(),setupApp:u(),configReady:!0}),!d()&&!f.meta?.hasVariantChildComponents&&(f.meta=f.meta||{},Object.assign(f.meta,{hasVariantChildComponents:!0}))}function y(){_||(_=!0,v())}if(h===null)y();else{let e=h.subscribe(e=>{(e===null||g?.id===e)&&y()});n(e)}e(()=>{_&&v()}),r.init();var b=r.comment(),x=r.first_child(b);r.if(x,e=>{}),r.append(i,b),r.pop()}export{i as default};
1
+ import{afterUpdate as e,getContext as t,onDestroy as n}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as r from"svelte/internal/client";r.from_html(`<!> <!>`,1);function i(i,a){let o=r.sanitize_slots(a);r.push(a,!1);let s=r.prop(a,`source`,8,null),c=r.prop(a,`responsiveDisabled`,8,null),l=r.prop(a,`autoPropsDisabled`,8,!1),u=r.prop(a,`setupApp`,8,null),d=r.prop(a,`implicit`,8,!1),f=t(`__pvtStory`),p=t(`__pvtIndex`),m=t(`__pvtSlots`),h=t(`__pvtStoryProps`)??{},g=t(`__pvtTargetVariantId`)??null,_=f.variants[p.value];p.value++;let v=!1;function y(){Object.assign(_,{slots:()=>({default:!0,controls:o.controls??m.controls}),source:s(),responsiveDisabled:c()??h.responsiveDisabled??!1,autoPropsDisabled:l(),setupApp:u()??h.setupApp??null,configReady:!0}),!d()&&!f.meta?.hasVariantChildComponents&&(f.meta=f.meta||{},Object.assign(f.meta,{hasVariantChildComponents:!0}))}function b(){v||(v=!0,y())}if(g===null)b();else{let e=g.subscribe(e=>{(e===null||_?.id===e)&&b()});n(e)}e(()=>{v&&y()}),r.init();var x=r.comment(),S=r.first_child(x);r.if(S,e=>{}),r.append(i,x),r.pop()}export{i as default};
@@ -2,7 +2,11 @@
2
2
  import { afterUpdate, getContext, onDestroy } from 'svelte'
3
3
 
4
4
  export let source = null
5
- export let responsiveDisabled = false
5
+ // `null` rather than `false`/a handler: these two inherit from the story, and
6
+ // a literal default is indistinguishable from a variant that set it — so a
7
+ // variant could not opt out of what the story declared. `??` falls through on
8
+ // null only, so an explicit `responsiveDisabled={false}` still wins (#466).
9
+ export let responsiveDisabled = null
6
10
  export let autoPropsDisabled = false
7
11
  export let setupApp = null
8
12
  export let implicit = false
@@ -10,6 +14,7 @@
10
14
  const story = getContext('__pvtStory')
11
15
  const index = getContext('__pvtIndex')
12
16
  const storySlots = getContext('__pvtSlots')
17
+ const storyProps = getContext('__pvtStoryProps') ?? {}
13
18
  // A store: a sandbox sets it to the one variant this realm serves and changes
14
19
  // it when the realm is retargeted (#240). Null in the app realm, which keeps
15
20
  // every variant's bookkeeping.
@@ -30,9 +35,9 @@
30
35
  controls: $$slots.controls ?? storySlots.controls,
31
36
  }),
32
37
  source,
33
- responsiveDisabled,
38
+ responsiveDisabled: responsiveDisabled ?? storyProps.responsiveDisabled ?? false,
34
39
  autoPropsDisabled,
35
- setupApp,
40
+ setupApp: setupApp ?? storyProps.setupApp ?? null,
36
41
  configReady: true,
37
42
  })
38
43
 
@@ -1 +1 @@
1
- import{watch as e}from"@poveste/vendors/vue";import{getContext as t,onDestroy as n,setContext as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";var a=i.from_html(`<!> <!>`,1);function o(o,s){let c=i.sanitize_slots(s);i.push(s,!1);let l=t(`__pvtStory`),u=i.mutable_source(t(`__pvtVariant`)),d=t(`__pvtSlot`);r(`__pvtIndex`,{value:0});let f=i.prop(s,`source`,8,null),p=i.prop(s,`initState`,8,null);p()&&i.get(u)&&!i.get(u).__pvtStateSeeded&&(i.mutate(u,i.get(u).__pvtStateSeeded=!0),i.mutate(u,i.get(u).state={...i.get(u).state,...p()()})),!p()&&d===`controls`&&c.controls&&i.get(u)&&!i.get(u).__pvtStateWarned&&(i.mutate(u,i.get(u).__pvtStateWarned=!0),console.error([`[poveste] Story "${l?.title??l?.id}" has a controls slot but no \`initState\`.`,`Controls will render and appear to work, but their edits cannot reach the story:`,`the story is mounted separately for each slot, so a component-local variable is not shared.`,"Pass `initState` and read state from the snippet —",`https://poveste.dev/guide/migration-from-histoire.html#svelte-story-state-moves-to-initstate`].join(` `)));let m=i.mutable_source(i.get(u)?.state),h=e(()=>i.get(u)?.state,()=>{i.set(m,i.get(u)?.state)},{deep:!0});n(h),i.legacy_pre_effect(()=>(i.deep_read_state(f()),i.get(m),i.get(u)),()=>{let e=typeof f()==`function`?f()(i.get(m)):f();e!=null&&Object.assign(i.get(u),{source:e})}),i.legacy_pre_effect_reset(),i.init();var g=a(),_=i.first_child(g),v=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`controls`,{get state(){return i.get(m)}},null),i.append(e,t)};i.if(_,e=>{d===`controls`&&e(v)});var y=i.sibling(_,2),b=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`default`,{get state(){return i.get(m)}},null),i.append(e,t)};i.if(y,e=>{i.untrack(()=>d==="default"||l.meta?.hasVariantChildComponents)&&e(b)}),i.append(o,g),i.pop()}export{o as default};
1
+ import{watch as e}from"@poveste/vendors/vue";import{getContext as t,onDestroy as n,setContext as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";var a=i.from_html(`<!> <!>`,1);function o(o,s){let c=i.sanitize_slots(s),l=i.legacy_rest_props(s,[`children`,`$$slots`,`$$events`,`$$legacy`]),u=i.legacy_rest_props(l,[`source`,`initState`]);i.push(s,!1);let d=t(`__pvtStory`),f=i.mutable_source(t(`__pvtVariant`)),p=t(`__pvtSlot`);r(`__pvtIndex`,{value:0}),r(`__pvtStoryProps`,u),i.get(f)&&d.variants.length===1&&d.variants[0].id===`_default`&&Object.assign(i.get(f),{setupApp:u.setupApp??null});let m=i.prop(s,`source`,8,null),h=i.prop(s,`initState`,8,null);h()&&i.get(f)&&!i.get(f).__pvtStateSeeded&&(i.mutate(f,i.get(f).__pvtStateSeeded=!0),i.mutate(f,i.get(f).state={...i.get(f).state,...h()()})),!h()&&p===`controls`&&c.controls&&i.get(f)&&!i.get(f).__pvtStateWarned&&(i.mutate(f,i.get(f).__pvtStateWarned=!0),console.error([`[poveste] Story "${d?.title??d?.id}" has a controls slot but no \`initState\`.`,`Controls will render and appear to work, but their edits cannot reach the story:`,`the story is mounted separately for each slot, so a component-local variable is not shared.`,"Pass `initState` and read state from the snippet —",`https://poveste.dev/guide/migration-from-histoire#svelte-story-state-moves-to-initstate`].join(` `)));let g=i.mutable_source(i.get(f)?.state),_=e(()=>i.get(f)?.state,()=>{i.set(g,i.get(f)?.state)},{deep:!0});n(_),i.legacy_pre_effect(()=>(i.deep_read_state(m()),i.get(g),i.get(f)),()=>{let e=typeof m()==`function`?m()(i.get(g)):m();e!=null&&Object.assign(i.get(f),{source:e})}),i.legacy_pre_effect_reset(),i.init();var v=a(),y=i.first_child(v),b=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`controls`,{get state(){return i.get(g)}},null),i.append(e,t)};i.if(y,e=>{p===`controls`&&e(b)});var x=i.sibling(y,2),S=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`default`,{get state(){return i.get(g)}},null),i.append(e,t)};i.if(x,e=>{i.untrack(()=>p==="default"||d.meta?.hasVariantChildComponents)&&e(S)}),i.append(o,v),i.pop()}export{o as default};
@@ -8,6 +8,22 @@
8
8
 
9
9
  const index = { value: 0 }
10
10
  setContext('__pvtIndex', index)
11
+ // The sandbox realm's half of story-prop inheritance. `MountStory` does this
12
+ // for the app realm, and the bridge carries only `variant.state` across the
13
+ // iframe — so without it a story-level prop reaches the sandbox by accident,
14
+ // when a grid cell happens to render in the same realm (#466).
15
+ setContext('__pvtStoryProps', $$restProps)
16
+
17
+ // A story with no `<Hst.Variant>` children has no `RenderVariant` to write the
18
+ // handler, so the story is the only place it can come from — and without this
19
+ // it too reached `render.ts` only by accident, passing one run in three. At
20
+ // init for the same reason `RenderVariant` writes at init: the handler is read
21
+ // as soon as the component has mounted. The condition is `MountStory`'s own.
22
+ if (currentVariant && story.variants.length === 1 && story.variants[0].id === '_default') {
23
+ Object.assign(currentVariant, {
24
+ setupApp: $$restProps.setupApp ?? null,
25
+ })
26
+ }
11
27
 
12
28
  export let source = null
13
29
  export let initState = null
@@ -39,7 +55,7 @@
39
55
  'Controls will render and appear to work, but their edits cannot reach the story:',
40
56
  'the story is mounted separately for each slot, so a component-local variable is not shared.',
41
57
  'Pass `initState` and read state from the snippet —',
42
- 'https://poveste.dev/guide/migration-from-histoire.html#svelte-story-state-moves-to-initstate',
58
+ 'https://poveste.dev/guide/migration-from-histoire#svelte-story-state-moves-to-initstate',
43
59
  ].join(' '))
44
60
  }
45
61
 
@@ -1 +1 @@
1
- import{shouldWarnAboutMissingInitState as e}from"../util/init-state-warning.js";import{watch as t}from"@poveste/vendors/vue";import{getContext as n,onDestroy as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";var a=i.from_html(`<!> <!>`,1);function o(o,s){let c=i.sanitize_slots(s);i.push(s,!1);let l=n(`__pvtStory`),u=i.mutable_source(n(`__pvtVariant`)),d=n(`__pvtSlot`),f=n(`__pvtIndex`),p=l.variants[f.value];f.value++;let m=i.get(u).id===p.id,h=i.prop(s,`source`,8,null),g=i.prop(s,`initState`,8,null);g()&&m&&!i.get(u).__pvtStateSeeded&&(i.mutate(u,i.get(u).__pvtStateSeeded=!0),i.mutate(u,i.get(u).state={...i.get(u).state,...g()()})),m&&e({hasInitState:!!g(),seeded:!!i.get(u).__pvtStateSeeded,slotName:d,hasControlsSlot:!!c.controls,alreadyWarned:!!i.get(u).__pvtStateWarned})&&(i.mutate(u,i.get(u).__pvtStateWarned=!0),console.error([`[poveste] Variant "${p?.title??p?.id}" has a controls slot but no \`initState\`.`,`Controls will render and appear to work, but their edits cannot reach the story:`,`the story is mounted separately for each slot, so a component-local variable is not shared.`,"Pass `initState` and read state from the snippet —",`https://poveste.dev/guide/migration-from-histoire.html#svelte-story-state-moves-to-initstate`].join(` `)));let _=i.mutable_source(i.get(u)?.state),v=()=>{};m&&(v=t(()=>i.get(u)?.state,()=>{i.set(_,i.get(u)?.state)},{deep:!0})),r(()=>v()),i.legacy_pre_effect(()=>(i.deep_read_state(h()),i.get(_),i.get(u)),()=>{if(m){let e=typeof h()==`function`?h()(i.get(_)):h();e!=null&&Object.assign(i.get(u),{source:e})}}),i.legacy_pre_effect_reset(),i.init();var y=i.comment(),b=i.first_child(y),x=e=>{var t=a(),n=i.first_child(t),r=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`default`,{get state(){return i.get(_)}},null),i.append(e,t)};i.if(n,e=>{d==="default"&&e(r)});var o=i.sibling(n,2),c=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`controls`,{get state(){return i.get(_)}},null),i.append(e,t)};i.if(o,e=>{d===`controls`&&e(c)}),i.append(e,t)};i.if(b,e=>{m&&e(x)}),i.append(o,y),i.pop()}export{o as default};
1
+ import{shouldWarnAboutMissingInitState as e}from"../util/init-state-warning.js";import{watch as t}from"@poveste/vendors/vue";import{getContext as n,onDestroy as r}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as i from"svelte/internal/client";var a=i.from_html(`<!> <!>`,1);function o(o,s){let c=i.sanitize_slots(s);i.push(s,!1);let l=n(`__pvtStory`),u=i.mutable_source(n(`__pvtVariant`)),d=n(`__pvtSlot`),f=n(`__pvtIndex`),p=n(`__pvtStoryProps`)??{},m=l.variants[f.value];f.value++;let h=i.get(u).id===m.id,g=i.prop(s,`source`,8,null),_=i.prop(s,`initState`,8,null),v=i.prop(s,`setupApp`,8,null);h&&Object.assign(i.get(u),{setupApp:v()??p.setupApp??null}),_()&&h&&!i.get(u).__pvtStateSeeded&&(i.mutate(u,i.get(u).__pvtStateSeeded=!0),i.mutate(u,i.get(u).state={...i.get(u).state,..._()()})),h&&e({hasInitState:!!_(),seeded:!!i.get(u).__pvtStateSeeded,slotName:d,hasControlsSlot:!!c.controls,alreadyWarned:!!i.get(u).__pvtStateWarned})&&(i.mutate(u,i.get(u).__pvtStateWarned=!0),console.error([`[poveste] Variant "${m?.title??m?.id}" has a controls slot but no \`initState\`.`,`Controls will render and appear to work, but their edits cannot reach the story:`,`the story is mounted separately for each slot, so a component-local variable is not shared.`,"Pass `initState` and read state from the snippet —",`https://poveste.dev/guide/migration-from-histoire#svelte-story-state-moves-to-initstate`].join(` `)));let y=i.mutable_source(i.get(u)?.state),b=()=>{};h&&(b=t(()=>i.get(u)?.state,()=>{i.set(y,i.get(u)?.state)},{deep:!0})),r(()=>b()),i.legacy_pre_effect(()=>(i.deep_read_state(g()),i.get(y),i.get(u)),()=>{if(h){let e=typeof g()==`function`?g()(i.get(y)):g();e!=null&&Object.assign(i.get(u),{source:e})}}),i.legacy_pre_effect_reset(),i.init();var x=i.comment(),S=i.first_child(x),C=e=>{var t=a(),n=i.first_child(t),r=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`default`,{get state(){return i.get(y)}},null),i.append(e,t)};i.if(n,e=>{d==="default"&&e(r)});var o=i.sibling(n,2),c=e=>{var t=i.comment(),n=i.first_child(t);i.slot(n,s,`controls`,{get state(){return i.get(y)}},null),i.append(e,t)};i.if(o,e=>{d===`controls`&&e(c)}),i.append(e,t)};i.if(S,e=>{h&&e(C)}),i.append(o,x),i.pop()}export{o as default};
@@ -7,6 +7,7 @@
7
7
  const currentVariant = getContext('__pvtVariant')
8
8
  const slotName = getContext('__pvtSlot')
9
9
  const index = getContext('__pvtIndex')
10
+ const storyProps = getContext('__pvtStoryProps') ?? {}
10
11
 
11
12
  const variant = story.variants[index.value]
12
13
  index.value++
@@ -18,6 +19,17 @@
18
19
 
19
20
  export let source = null
20
21
  export let initState = null
22
+ export let setupApp = null
23
+
24
+ // Written at init, not in a reactive block: `render.ts` reads
25
+ // `variant.setupApp` as soon as the story component has mounted, so anything
26
+ // deferred is missed for that render and never runs. Guarded like `source`
27
+ // below — this is *this* variant's handler, on the shared `currentVariant`.
28
+ if (shouldRender) {
29
+ Object.assign(currentVariant, {
30
+ setupApp: setupApp ?? storyProps.setupApp ?? null,
31
+ })
32
+ }
21
33
 
22
34
  // Same contract as `RenderStory`: poveste owns the state because the story is
23
35
  // mounted once per slot, so a component-local variable cannot be shared (#81).
@@ -41,7 +53,7 @@
41
53
  'Controls will render and appear to work, but their edits cannot reach the story:',
42
54
  'the story is mounted separately for each slot, so a component-local variable is not shared.',
43
55
  'Pass `initState` and read state from the snippet —',
44
- 'https://poveste.dev/guide/migration-from-histoire.html#svelte-story-state-moves-to-initstate',
56
+ 'https://poveste.dev/guide/migration-from-histoire#svelte-story-state-moves-to-initstate',
45
57
  ].join(' '))
46
58
  }
47
59
 
@@ -7,10 +7,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
7
7
  };
8
8
  targetVariantId: {
9
9
  type: StringConstructor;
10
- default: any;
10
+ default: null;
11
11
  };
12
12
  }>, {
13
- el: import("vue").Ref<HTMLDivElement, HTMLDivElement>;
13
+ el: import("vue").Ref<HTMLDivElement | undefined, HTMLDivElement | undefined>;
14
14
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
15
15
  story: {
16
16
  type: _PropType<Story>;
@@ -18,7 +18,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
18
18
  };
19
19
  targetVariantId: {
20
20
  type: StringConstructor;
21
- default: any;
21
+ default: null;
22
22
  };
23
23
  }>> & Readonly<{}>, {
24
24
  targetVariantId: string;
@@ -1 +1 @@
1
- import{callSetupFunctions as e,mountSvelteComponent as t}from"../util/svelte.js";import n from"./MountVariant.svelte";import r from"./MountStory.svelte";import i from"./Stub.svelte";import{components as a}from"@poveste/controls";import{defineComponent as o,h as s,onMounted as c,onUnmounted as l,ref as u,watch as d}from"@poveste/vendors/vue";import{writable as f}from"svelte/store";import*as p from"virtual:$poveste-generated-global-setup";import*as m from"virtual:$poveste-setup";var h=o({name:`MountStory`,props:{story:{type:Object,required:!0},targetVariantId:{type:String,default:null}},setup(i){let a=u(),o,s,h=null,_=f(i.targetVariantId);d(()=>i.targetVariantId,e=>{_.set(e)});async function v(){s=document.createElement(`div`),a.value.appendChild(s);let c=await t(i.story.file.component,{target:s,props:{Hst:{Story:r,Variant:n,...g()}},context:new Map(Object.entries({__pvtStory:i.story,__pvtTargetVariantId:_}))},`client`,{storyId:i.story.id,variantId:i.targetVariantId??void 0});o=c.app,h=c.destroy;let l={app:o,story:i.story,variant:null};await e(p,m,l)}function y(){h?.(),h=null,s&&=(s.parentNode?.removeChild(s),null),o=null}return d(()=>i.story.id,async()=>{y(),await v()}),c(async()=>{await v()}),l(()=>{y()}),{el:a}},render(){return s(`div`,{ref:`el`})}});function g(){let e={};for(let t in a)e[t.substring(3)]=i;return e}export{h as default};
1
+ import{callSetupFunctions as e,mountSvelteComponent as t}from"../util/svelte.js";import n from"./MountVariant.svelte";import r from"./MountStory.svelte";import i from"./Stub.svelte";import{components as a}from"@poveste/controls";import{defineComponent as o,h as s,onMounted as c,onUnmounted as l,ref as u,watch as d}from"@poveste/vendors/vue";import{writable as f}from"svelte/store";import*as p from"virtual:$poveste-generated-global-setup";import*as m from"virtual:$poveste-setup";var h=o({name:`MountStory`,props:{story:{type:Object,required:!0},targetVariantId:{type:String,default:null}},setup(i){let a=u(),o,s=null,h=null,_=f(i.targetVariantId);d(()=>i.targetVariantId,e=>{_.set(e)});async function v(){if(!a.value||!i.story.file)return;s=document.createElement(`div`),a.value.appendChild(s);let c=await t(i.story.file.component,{target:s,props:{Hst:{Story:r,Variant:n,...g()}},context:new Map(Object.entries({__pvtStory:i.story,__pvtTargetVariantId:_}))},`client`,{storyId:i.story.id,variantId:i.targetVariantId??void 0});o=c.app,h=c.destroy;let l={app:o,story:i.story,variant:void 0};await e(p,m,l)}function y(){h?.(),h=null,s&&=(s.parentNode?.removeChild(s),null),o=null}return d(()=>i.story.id,async()=>{y(),await v()}),c(async()=>{await v()}),l(()=>{y()}),{el:a}},render(){return s(`div`,{ref:`el`})}});function g(){let e={};for(let t in a)e[t.substring(3)]=i;return e}export{h as default};
@@ -0,0 +1,16 @@
1
+ import type { Story, Variant } from '@poveste/shared';
2
+ type SvelteComponentFunction = (anchor: any, props: any) => any;
3
+ /**
4
+ * `Hst.Story` and `Hst.Variant` for a render of `story` that shows `variant`.
5
+ *
6
+ * The story's `{#each}` calls `Hst.Variant` once per variant, and a sandbox mounts
7
+ * the story again on every retarget. A `RenderVariant` for another variant renders
8
+ * nothing and changes nothing, yet creating them was most of a retarget: 3ms of 7ms
9
+ * at 1000 variants (#888). So only the shown one is created, and the rest are
10
+ * counted, which is all they did.
11
+ */
12
+ export declare function renderStoryComponents(story: Story, variant: Variant): {
13
+ Story: SvelteComponentFunction;
14
+ Variant: SvelteComponentFunction;
15
+ };
16
+ export {};
@@ -0,0 +1 @@
1
+ import e from"./RenderStory.svelte";import t from"./RenderVariant.svelte";import{toRaw as n}from"@poveste/vendors/vue";import{getContext as r}from"svelte";function i(i,a){let o=n(i).variants.findIndex(({id:e})=>e===a.id),s=0;return{Story:(t,n)=>(s=0,e(t,n)),Variant:(e,n)=>{if(s++===o)return r(`__pvtIndex`).value=o,t(e,n)}}}export{i as renderStoryComponents};
@@ -14,7 +14,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
14
14
  default: string;
15
15
  };
16
16
  }>, {
17
- el: import("vue").Ref<HTMLDivElement, HTMLDivElement>;
17
+ el: import("vue").Ref<HTMLDivElement | undefined, HTMLDivElement | undefined>;
18
18
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
19
19
  variant: {
20
20
  type: _PropType<Variant>;
@@ -1 +1 @@
1
- import{callSetupFunctions as e,createWrappedComponent as t,getLegacyStateApi as n,mountSvelteComponent as r}from"../util/svelte.js";import i from"./RenderStory.svelte";import a from"./RenderVariant.svelte";import{syncState as o}from"./util.js";import s from"./Wrap.svelte";import{components as c}from"@poveste/controls";import{defineComponent as l,h as u,onMounted as d,onUnmounted as f,ref as p,watch as m}from"@poveste/vendors/vue";import*as h from"virtual:$poveste-generated-global-setup";import*as g from"virtual:$poveste-setup";var _=l({name:`RenderStory`,props:{variant:{type:Object,required:!0},story:{type:Object,required:!0},slotName:{type:String,default:`default`}},setup(t,{emit:s}){let c=p(),l,u,_=[];function y(e,t){document.addEventListener(e,t);let n=()=>document.removeEventListener(e,t);return _.push(n),{off:n}}async function b(){u=document.createElement(`div`),c.value.appendChild(u);let d=[],{off:f}=y(`SvelteRegisterComponent`,e=>{let{component:t}=e.detail;d.push(t)}),p=await r(t.story.file.component,{target:u,props:{Hst:{Story:i,Variant:a,...v()}},context:new Map(Object.entries({__pvtStory:t.story,__pvtVariant:t.variant,__pvtSlot:t.slotName}))},`client`,{storyId:t.story.id,variantId:t.variant?.id});l=p.app,_.push(()=>{p.destroy()});let m=d.find(e=>e.$$&&l?.$$&&e.$$===l.$$)??l;f(),d=[];function b(){let e=m?.$replace;e&&(m.$replace=(...t)=>{let n=e.apply(m,t);return m=n??m,n})}b();let x=n(m);if(x){let{apply:e,stop:n}=o(t.variant.state,e=>{x.injectState(e)});_.push(n);let r,i=()=>{e(x.captureState()),r=requestAnimationFrame(i)};r=requestAnimationFrame(i),_.push(()=>{cancelAnimationFrame(r)}),e(x.captureState())}let S={app:l,story:t.story,variant:t.variant};await e(h,g,S,t.variant.setupApp),s(`ready`)}function x(){_.forEach(e=>e()),_=[],u&&=(u.parentNode?.removeChild(u),null),l=null}return m(()=>t.story.id,async()=>{x(),await b()}),d(async()=>{await b()}),f(()=>{x()}),{el:c}},render(){return u(`div`,{ref:`el`})}});function v(){let e={};for(let t in c)e[t.substring(3)]=y(c[t]);return e}function y(e){return t(s,e)}export{_ as default};
1
+ import{callSetupFunctions as e,createWrappedComponent as t,getLegacyStateApi as n,mountSvelteComponent as r}from"../util/svelte.js";import{renderStoryComponents as i}from"./render-story-components.js";import{syncState as a}from"./util.js";import o from"./Wrap.svelte";import{components as s}from"@poveste/controls";import{defineComponent as c,h as l,onMounted as u,onUnmounted as d,ref as f,watch as p}from"@poveste/vendors/vue";import*as m from"virtual:$poveste-generated-global-setup";import*as h from"virtual:$poveste-setup";var g=c({name:`RenderStory`,props:{variant:{type:Object,required:!0},story:{type:Object,required:!0},slotName:{type:String,default:`default`}},setup(t,{emit:o}){let s=f(),c,l=null,g=[];function v(e,t){document.addEventListener(e,t);let n=()=>document.removeEventListener(e,t);return g.push(n),{off:n}}async function y(){if(!s.value||!t.story.file)return;l=document.createElement(`div`),s.value.appendChild(l);let u=[],{off:d}=v(`SvelteRegisterComponent`,e=>{let{component:t}=e.detail;u.push(t)}),f=await r(t.story.file.component,{target:l,props:{Hst:{...i(t.story,t.variant),..._()}},context:new Map(Object.entries({__pvtStory:t.story,__pvtVariant:t.variant,__pvtSlot:t.slotName}))},`client`,{storyId:t.story.id,variantId:t.variant?.id});c=f.app,g.push(()=>{f.destroy()});let p=u.find(e=>e.$$&&c?.$$&&e.$$===c.$$)??c;d(),u=[];function y(){let e=p?.$replace;e&&(p.$replace=(...t)=>{let n=e.apply(p,t);return p=n??p,n})}y();let b=n(p);if(b){let{apply:e,stop:n}=a(t.variant.state,e=>{b.injectState(e)});g.push(n);let r,i=()=>{e(b.captureState()),r=requestAnimationFrame(i)};r=requestAnimationFrame(i),g.push(()=>{cancelAnimationFrame(r)}),e(b.captureState())}let x={app:c,story:t.story,variant:t.variant};await e(m,h,x,t.variant.setupApp),o(`ready`)}function b(){g.forEach(e=>e()),g=[],l&&=(l.parentNode?.removeChild(l),null),c=null}return p(()=>t.story.id,async()=>{b(),await y()}),u(async()=>{await y()}),d(()=>{b()}),{el:s}},render(){return l(`div`,{ref:`el`})}});function _(){let e={};for(let[t,n]of Object.entries(s))e[t.substring(3)]=v(n);return e}function v(e){return t(o,e)}export{g as default};
@@ -1,4 +1,4 @@
1
- export declare function syncState(variantState: any, onChange: (state: any) => unknown): {
2
- apply: (value: any) => void;
1
+ export declare function syncState(variantState: Record<string, any>, onChange: (state: Record<string, any>) => unknown): {
2
+ apply: (value: Record<string, any> | null | undefined) => void;
3
3
  stop(): void;
4
4
  };
@@ -1 +1 @@
1
- import{getContext as e}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as t from"svelte/internal/client";function n(n,r){t.push(r,!1);let i=t.prop(r,`title`,8,`untitled`),a=t.prop(r,`id`,8,null),o=t.prop(r,`icon`,8,null),s=t.prop(r,`iconColor`,8,null);t.prop(r,`initState`,8,null);let c=e(`__pvtStory`),l=e(`__pvtAddVariant`);function u(){return`${c.id}-${c.variants.length}`}l({id:a()??u(),title:i(),icon:o(),iconColor:s()}),t.init(),t.pop()}export{n as default};
1
+ import{getContext as e}from"svelte";import"svelte/internal/disclose-version";import"svelte/internal/flags/legacy";import*as t from"svelte/internal/client";function n(n,r){t.push(r,!1);let i=t.prop(r,`title`,8,`untitled`),a=t.prop(r,`id`,8,null),o=t.prop(r,`icon`,8,null),s=t.prop(r,`iconColor`,8,null),c=t.prop(r,`autoPropsDisabled`,8,!1);t.prop(r,`initState`,8,null);let l=e(`__pvtStory`),u=e(`__pvtAddVariant`);function d(){return`${l.id}-${l.variants.length}`}u({id:a()??d(),title:i(),icon:o(),iconColor:s(),autoPropsDisabled:c()}),t.init(),t.pop()}export{n as default};
@@ -5,6 +5,10 @@
5
5
  export let id = null
6
6
  export let icon = null
7
7
  export let iconColor = null
8
+ // Collected rather than left to `MountVariant`, which sets it when the mount
9
+ // realm runs — and the realm that reads it renders in parallel, so whether a
10
+ // variant's auto-props were off came down to which mount finished first (#890).
11
+ export let autoPropsDisabled = false
8
12
  // Absorbs the prop; collection never renders variant children. `export const`
9
13
  // (the compiler's suggestion) would make passing one an error.
10
14
  // svelte-ignore export_let_unused
@@ -22,6 +26,7 @@
22
26
  title,
23
27
  icon,
24
28
  iconColor,
29
+ autoPropsDisabled,
25
30
  }
26
31
 
27
32
  addVariant(variant)
@@ -1 +1 @@
1
- import{callSetupFunctions as e,mountSvelteComponent as t}from"../util/svelte.js";import n from"./Story.svelte";import r from"./Variant.svelte";import*as i from"virtual:$poveste-generated-global-setup";import*as a from"virtual:$poveste-setup";import{tick as o}from"svelte";async function s({file:s,el:c,storyData:l}){let{default:u}=await import(/* @vite-ignore */s.moduleId),d=await t(u,{target:c,props:{Hst:{Story:n,Variant:r}},context:new Map(Object.entries({__pvtAddStory(e){l.push(e)},__pvtStoryFile:s}))},`client`),f={app:d.app,story:null,variant:null};if(await e(i,a,f),await o(),!l[0]){d.destroy();return}l[0].variants.length||l[0].variants.push({id:`_default`,title:`default`}),d.destroy()}export{s as run};
1
+ import{callSetupFunctions as e,mountSvelteComponent as t}from"../util/svelte.js";import n from"./Story.svelte";import r from"./Variant.svelte";import*as i from"virtual:$poveste-generated-global-setup";import*as a from"virtual:$poveste-setup";import{tick as o}from"svelte";async function s({file:s,el:c,storyData:l}){let{default:u}=await import(/* @vite-ignore */s.moduleId),d=await t(u,{target:c,props:{Hst:{Story:n,Variant:r}},context:new Map(Object.entries({__pvtAddStory(e){l.push(e)},__pvtStoryFile:s}))},`client`),f={app:d.app,story:void 0,variant:void 0};if(await e(i,a,f),await o(),!l[0]){d.destroy();return}l[0].variants.length||l[0].variants.push({id:`_default`,title:`default`}),d.destroy()}export{s as run};
@@ -14,13 +14,13 @@ export default {
14
14
  label: 'File name',
15
15
  type: 'text',
16
16
  required: true,
17
- defaultValue: answers => answers.component?.replace(/[^/]+\/([^/]+)\.svelte$/, '$1.story.svelte'),
17
+ defaultValue: answers => answers['component']?.replace(/[^/]+\/([^/]+)\.svelte$/, '$1.story.svelte'),
18
18
  },
19
19
  ],
20
20
  clientAction: (params) => {
21
- const index = params.component.lastIndexOf('/');
22
- const dirname = params.component.substring(0, index + 1);
23
- const file = `${dirname}${params.fileName}`;
21
+ const index = params['component'].lastIndexOf('/');
22
+ const dirname = params['component'].substring(0, index + 1);
23
+ const file = `${dirname}${params['fileName']}`;
24
24
  const storyId = kebabCase(file.toLowerCase());
25
25
  openStory(storyId);
26
26
  },
@@ -7,11 +7,11 @@ export default {
7
7
  icon: 'https://svelte.dev/favicon.png',
8
8
  searchText: 'generate create',
9
9
  async serverAction(params) {
10
- const targetFile = path.join(path.dirname(params.component), params.fileName);
10
+ const targetFile = path.join(path.dirname(params['component']), params['fileName']);
11
11
  if (fs.existsSync(targetFile)) {
12
12
  throw new Error(`File ${targetFile} already exists`);
13
13
  }
14
- const { component, componentName, isTs } = await getComponentInfo(params.component);
14
+ const { component, componentName, isTs } = await getComponentInfo(params['component']);
15
15
  const content = `<script${isTs ? ' lang="ts"' : ''}>
16
16
  ${isTs
17
17
  ? `import type { Hst } from '@poveste/plugin-svelte'\n
package/dist/helpers.d.ts CHANGED
@@ -3,8 +3,8 @@ import type { Story, StoryProps, Variant, VariantProps } from '@poveste/shared';
3
3
  import type { Component, Snippet } from 'svelte';
4
4
  export interface SvelteStorySetupApi {
5
5
  app: any;
6
- story?: Story;
7
- variant?: Variant;
6
+ story?: Story | undefined;
7
+ variant?: Variant | undefined;
8
8
  }
9
9
  export type SvelteStorySetupHandler = (api: SvelteStorySetupApi) => Promise<void> | void;
10
10
  export declare function defineSetupSvelte(handler: SvelteStorySetupHandler): SvelteStorySetupHandler;
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module';
3
3
  import { dirname, join } from 'pathe';
4
4
  import { defaultColors } from 'poveste';
5
5
  import generateStoryCommand from './commands/generate-story.server.js';
6
+ import { SVELTE_SETUP_HOOK_NAMES } from './setup-hooks.js';
6
7
  import { svelteAutoProps } from './util/auto-props-vite.js';
7
8
  import { svelteKitAssetsDir } from './util/kit-assets.js';
8
9
  import { listComponentFiles } from './util/list-components.js';
@@ -47,7 +48,7 @@ export function HstSvelte() {
47
48
  supportPlugin: {
48
49
  id: 'svelte4',
49
50
  moduleName: '@poveste/plugin-svelte',
50
- setupFn: ['setupSvelte3', 'setupSvelte4', 'setupSvelte5'],
51
+ setupFn: SVELTE_SETUP_HOOK_NAMES,
51
52
  importStoryComponent: (file, index) => `import Comp${index} from ${JSON.stringify(file.moduleId)}`,
52
53
  },
53
54
  commands: [
@@ -59,6 +60,7 @@ export function HstSvelte() {
59
60
  return listComponentFiles(api.payload.search, api.getConfig().storyMatch);
60
61
  }
61
62
  }
63
+ return undefined;
62
64
  },
63
65
  };
64
66
  }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The names a Svelte setup file may export, most established first.
3
+ *
4
+ * The numbers are historical. `@poveste/plugin-svelte` supports Svelte 5 only,
5
+ * so `setupSvelte3` and `setupSvelte4` name majors it cannot run — they are
6
+ * accepted because histoire users wrote them, not because they select anything.
7
+ * `setupSvelte` is the unnumbered name, added as an alias rather than a rename,
8
+ * which is the only way to introduce it without breaking every existing setup
9
+ * file (#157).
10
+ *
11
+ * Order is load-bearing: `getSetupHook` runs the first one present, so a file
12
+ * that already exports `setupSvelte5` behaves exactly as before and the new name
13
+ * is the one that yields.
14
+ */
15
+ export declare const SVELTE_SETUP_HOOK_NAMES: string[];
16
+ /**
17
+ * Names this plugin has stopped reading.
18
+ *
19
+ * Empty, and meant to stay empty until 1.0 retires the numbered names. It is
20
+ * here so that doing so is a string moving from the list above to this one,
21
+ * with the warning already written and already tested.
22
+ */
23
+ export declare const SVELTE_RETIRED_SETUP_HOOK_NAMES: string[];
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The names a Svelte setup file may export, most established first.
3
+ *
4
+ * The numbers are historical. `@poveste/plugin-svelte` supports Svelte 5 only,
5
+ * so `setupSvelte3` and `setupSvelte4` name majors it cannot run — they are
6
+ * accepted because histoire users wrote them, not because they select anything.
7
+ * `setupSvelte` is the unnumbered name, added as an alias rather than a rename,
8
+ * which is the only way to introduce it without breaking every existing setup
9
+ * file (#157).
10
+ *
11
+ * Order is load-bearing: `getSetupHook` runs the first one present, so a file
12
+ * that already exports `setupSvelte5` behaves exactly as before and the new name
13
+ * is the one that yields.
14
+ */
15
+ export const SVELTE_SETUP_HOOK_NAMES = ['setupSvelte3', 'setupSvelte4', 'setupSvelte5', 'setupSvelte'];
16
+ /**
17
+ * Names this plugin has stopped reading.
18
+ *
19
+ * Empty, and meant to stay empty until 1.0 retires the numbered names. It is
20
+ * here so that doing so is a string moving from the list above to this one,
21
+ * with the warning already written and already tested.
22
+ */
23
+ export const SVELTE_RETIRED_SETUP_HOOK_NAMES = [];
@@ -4,6 +4,6 @@ export declare function svelteAutoProps(): {
4
4
  enforce: "pre";
5
5
  transform(this: any, code: string, id: string): Promise<{
6
6
  code: string;
7
- map: any;
8
- }>;
7
+ map: null;
8
+ } | undefined>;
9
9
  };
@@ -11,7 +11,7 @@ export function svelteAutoProps() {
11
11
  name: 'poveste:svelte-auto-props',
12
12
  enforce: 'pre',
13
13
  async transform(code, id) {
14
- if (!id.split('?')[0].endsWith('.svelte') || !code.includes(RENDERS_A_STORY) || !IMPORTS_A_COMPONENT.test(code)) {
14
+ if (!id.replace(/\?.*$/s, '').endsWith('.svelte') || !code.includes(RENDERS_A_STORY) || !IMPORTS_A_COMPONENT.test(code)) {
15
15
  return undefined;
16
16
  }
17
17
  const result = await transformStoryAutoProps(code, async (specifier) => {
@@ -57,12 +57,12 @@ export async function transformStoryAutoProps(code, propsOf) {
57
57
  function importedComponents(body) {
58
58
  const found = new Map();
59
59
  for (const node of body) {
60
- if (node.type !== 'ImportDeclaration' || !/\.svelte$/.test(node.source?.value ?? '')) {
60
+ if (node.type !== 'ImportDeclaration' || !/\.svelte$/.test(node['source']?.value ?? '')) {
61
61
  continue;
62
62
  }
63
- for (const specifier of node.specifiers ?? []) {
63
+ for (const specifier of node['specifiers'] ?? []) {
64
64
  if (specifier.type === 'ImportDefaultSpecifier') {
65
- found.set(specifier.local.name, node.source.value);
65
+ found.set(specifier.local.name, node['source'].value);
66
66
  }
67
67
  }
68
68
  }
@@ -75,13 +75,13 @@ function importedComponents(body) {
75
75
  */
76
76
  function collectTargets(fragment, imported) {
77
77
  const story = findStory(fragment);
78
- if (!story || blockWrapsAVariant(story.fragment)) {
78
+ if (!story || blockWrapsAVariant(story['fragment'])) {
79
79
  return undefined;
80
80
  }
81
81
  // At any depth and in document order, matching how `collect/Variant.svelte`
82
82
  // registers them. A story with none renders its children as variant zero.
83
83
  const variants = [];
84
- walk(story.fragment, (node) => {
84
+ walk(story['fragment'], (node) => {
85
85
  if (isHst(node, 'Variant')) {
86
86
  variants.push(node);
87
87
  }
@@ -90,7 +90,7 @@ function collectTargets(fragment, imported) {
90
90
  const targets = [];
91
91
  scopes.forEach((scope, variant) => {
92
92
  let index = 0;
93
- walk(scope.fragment, (node, ancestors) => {
93
+ walk(scope['fragment'], (node, ancestors) => {
94
94
  // The controls snippet builds the panel, not the preview. A component in
95
95
  // a block is skipped on its own.
96
96
  if (isControls(node)) {
@@ -99,7 +99,7 @@ function collectTargets(fragment, imported) {
99
99
  if (node.type !== 'Component' || insideBlock(ancestors)) {
100
100
  return undefined;
101
101
  }
102
- const specifier = imported.get(node.name);
102
+ const specifier = imported.get(node['name']);
103
103
  if (specifier) {
104
104
  targets.push({ node, variant, index: index++, specifier });
105
105
  }
@@ -131,12 +131,12 @@ function insideBlock(ancestors) {
131
131
  }
132
132
  function isControls(node) {
133
133
  if (node.type === 'SnippetBlock') {
134
- return node.expression?.name === 'controls';
134
+ return node['expression']?.name === 'controls';
135
135
  }
136
- return (node.attributes ?? []).some((attribute) => attribute.name === 'slot' && attribute.value?.[0]?.data === 'controls');
136
+ return (node['attributes'] ?? []).some((attribute) => attribute['name'] === 'slot' && attribute['value']?.[0]?.data === 'controls');
137
137
  }
138
138
  function isHst(node, member) {
139
- return node.type === 'Component' && (member ? node.name === `${HST}.${member}` : node.name?.startsWith(`${HST}.`));
139
+ return node.type === 'Component' && (member ? node['name'] === `${HST}.${member}` : node['name']?.startsWith(`${HST}.`));
140
140
  }
141
141
  // `then`/`catch`/`pending` and `fallback` are branches a variant can hide in.
142
142
  const CHILD_KEYS = ['fragment', 'nodes', 'children', 'body', 'consequent', 'alternate', 'pending', 'then', 'catch', 'fallback'];
@@ -172,7 +172,7 @@ async function describe(targets, propsOf) {
172
172
  for (const target of targets) {
173
173
  const props = await sources.get(target.specifier);
174
174
  if (props?.length) {
175
- defs[target.variant].push({ name: target.node.name, index: target.index, props });
175
+ defs[target.variant]?.push({ name: target.node['name'], index: target.index, props });
176
176
  }
177
177
  }
178
178
  return defs;
@@ -222,9 +222,9 @@ function literal(value) {
222
222
  .replace(/\u2029/g, '\\u2029');
223
223
  }
224
224
  function attributesEnd(code, node) {
225
- const attributes = node.attributes ?? [];
225
+ const attributes = node['attributes'] ?? [];
226
226
  if (attributes.length > 0) {
227
227
  return Math.max(...attributes.map((attribute) => attribute.end));
228
228
  }
229
- return code.indexOf(node.name, node.start) + node.name.length;
229
+ return code.indexOf(node['name'], node.start) + node['name'].length;
230
230
  }
@@ -1 +1 @@
1
- export declare function listComponentFiles(search?: string, ignore?: string[], limit?: number): Promise<string[]>;
1
+ export declare function listComponentFiles(search?: string, ignoredPatterns?: string[], limit?: number, cwd?: string): Promise<string[]>;
@@ -1,12 +1,69 @@
1
- import { globby } from 'globby';
2
- export async function listComponentFiles(search = '', ignore = [], limit = 10) {
3
- let files = await globby('**/*.svelte', {
4
- gitignore: true,
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join, relative, resolve, sep } from 'node:path';
3
+ import ignore from 'ignore';
4
+ import { glob } from 'tinyglobby';
5
+ function toPosix(path) {
6
+ return path.split(sep).join('/');
7
+ }
8
+ /**
9
+ * Whether a file under `cwd` is git-ignored, the way globby's `gitignore: true`
10
+ * decided it: every `.gitignore` from the repository root down, each pattern
11
+ * relative to its own file. tinyglobby reads none of them (#839).
12
+ */
13
+ async function gitIgnoredFilter(cwd) {
14
+ let root = cwd;
15
+ while (!existsSync(join(root, '.git'))) {
16
+ const parent = dirname(root);
17
+ if (parent === root) {
18
+ root = cwd;
19
+ break;
20
+ }
21
+ root = parent;
22
+ }
23
+ const ancestors = [];
24
+ for (let dir = cwd; dir !== root;) {
25
+ dir = dirname(dir);
26
+ ancestors.unshift(join(dir, '.gitignore'));
27
+ }
28
+ // Shallow files first, so a nested `.gitignore` can override its parent.
29
+ const nested = (await glob('**/.gitignore', { cwd, absolute: true, dot: true, ignore: ['**/node_modules/**', '**/.git/**'] }))
30
+ .sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b));
31
+ const rules = ignore();
32
+ for (const file of [...ancestors, ...nested]) {
33
+ if (!existsSync(file)) {
34
+ continue;
35
+ }
36
+ const base = toPosix(relative(root, dirname(file)));
37
+ for (const raw of readFileSync(file, 'utf8').split(/\r?\n/)) {
38
+ const line = raw.trimEnd();
39
+ if (!line || line.startsWith('#')) {
40
+ continue;
41
+ }
42
+ const negated = line.startsWith('!');
43
+ let pattern = negated ? line.slice(1) : line;
44
+ if (base) {
45
+ // A pattern with a slash before its end is anchored to its own directory;
46
+ // one without matches at any depth below it.
47
+ const anchored = pattern.replace(/\/$/, '').includes('/');
48
+ pattern = anchored ? `${base}/${pattern.replace(/^\//, '')}` : `${base}/**/${pattern}`;
49
+ }
50
+ rules.add(negated ? `!${pattern}` : pattern);
51
+ }
52
+ }
53
+ return (file) => {
54
+ const path = toPosix(relative(root, resolve(cwd, file)));
55
+ return !path.startsWith('..') && rules.ignores(path);
56
+ };
57
+ }
58
+ export async function listComponentFiles(search = '', ignoredPatterns = [], limit = 10, cwd = process.cwd()) {
59
+ const isIgnored = await gitIgnoredFilter(cwd);
60
+ let files = (await glob('**/*.svelte', {
61
+ cwd,
5
62
  ignore: [
6
63
  'node_modules',
7
- ...ignore,
64
+ ...ignoredPatterns,
8
65
  ],
9
- });
66
+ })).filter(file => !isIgnored(file));
10
67
  if (search) {
11
68
  const searchText = search.toLowerCase();
12
69
  files = files.filter(file => file.toLowerCase().includes(searchText));
@@ -1,10 +1,6 @@
1
- import { reportStoryError } from '@poveste/shared';
1
+ import { getSetupHook, reportStoryError } from '@poveste/shared';
2
2
  import * as svelte from 'svelte';
3
- const setupHookNames = [
4
- 'setupSvelte3',
5
- 'setupSvelte4',
6
- 'setupSvelte5',
7
- ];
3
+ import { SVELTE_RETIRED_SETUP_HOOK_NAMES, SVELTE_SETUP_HOOK_NAMES } from '../setup-hooks.js';
8
4
  function loadSvelteModule(moduleId) {
9
5
  return import(/* @vite-ignore */ moduleId);
10
6
  }
@@ -81,15 +77,17 @@ export function getLegacyStateApi(app) {
81
77
  };
82
78
  }
83
79
  export async function callSetupFunctions(generatedSetup, setup, setupApi, variantSetupApp) {
84
- for (const hookName of setupHookNames) {
85
- const generatedHook = generatedSetup[hookName];
86
- if (typeof generatedHook === 'function') {
87
- await generatedHook(setupApi);
88
- }
89
- const setupHook = setup[hookName];
90
- if (typeof setupHook === 'function') {
91
- await setupHook(setupApi);
92
- }
80
+ // One hook per module, not every name present. The loop this replaces ran all
81
+ // of them, so a file part-way through the migration — exporting `setupSvelte5`
82
+ // and `setupSvelte` at once — had its setup applied twice, silently. That is
83
+ // the failure the Vue pair has always been shaped to prevent (#157).
84
+ const generatedHook = getSetupHook(generatedSetup, SVELTE_SETUP_HOOK_NAMES, SVELTE_RETIRED_SETUP_HOOK_NAMES);
85
+ if (generatedHook) {
86
+ await generatedHook(setupApi);
87
+ }
88
+ const setupHook = getSetupHook(setup, SVELTE_SETUP_HOOK_NAMES, SVELTE_RETIRED_SETUP_HOOK_NAMES);
89
+ if (setupHook) {
90
+ await setupHook(setupApi);
93
91
  }
94
92
  if (typeof variantSetupApp === 'function') {
95
93
  await variantSetupApp(setupApi);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@poveste/plugin-svelte",
3
3
  "type": "module",
4
- "version": "0.13.1",
4
+ "version": "0.15.0",
5
5
  "description": "Poveste plugin for Svelte 5 and SvelteKit support",
6
6
  "author": {
7
7
  "name": "Sorin Gitlan",
@@ -65,7 +65,7 @@
65
65
  "peerDependencies": {
66
66
  "@sveltejs/kit": "^2.53.0",
67
67
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
68
- "poveste": "^0.13.1",
68
+ "poveste": "^0.15.0",
69
69
  "svelte": "^5.46.4"
70
70
  },
71
71
  "peerDependenciesMeta": {
@@ -74,26 +74,26 @@
74
74
  }
75
75
  },
76
76
  "dependencies": {
77
- "@poveste/controls": "^0.13.1",
78
- "@poveste/shared": "^0.13.1",
79
- "@poveste/vendors": "^0.13.1",
77
+ "@poveste/controls": "^0.15.0",
78
+ "@poveste/shared": "^0.15.0",
79
+ "@poveste/vendors": "^0.15.0",
80
80
  "change-case": "^5.4.4",
81
- "globby": "^14.0.2",
81
+ "ignore": "^7.0.6",
82
82
  "launch-editor": "^2.9.1",
83
- "pathe": "^1.1.2"
83
+ "pathe": "^2.0.3",
84
+ "tinyglobby": "^0.2.17"
84
85
  },
85
86
  "devDependencies": {
86
87
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
87
88
  "@types/node": "^22.10.1",
88
- "concurrently": "^9.1.0",
89
+ "concurrently": "^10.0.5",
89
90
  "fs-extra": "^11.2.0",
90
- "globby": "^14.0.2",
91
- "poveste": "0.13.1",
91
+ "poveste": "0.15.0",
92
92
  "svelte": "5.55.0",
93
93
  "svelte-preprocess": "^6.0.3",
94
- "typescript": "5.6.3",
94
+ "typescript": "6.0.3",
95
95
  "vite": "^8.0.0",
96
- "vitest": "^4.1.10"
96
+ "vitest": "^5.0.0"
97
97
  },
98
98
  "scripts": {
99
99
  "build": "rimraf dist && vite build && tsc -d -P tsconfig.build.json && pnpm run build:types",