@scenar/cli 0.2.0 → 0.2.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.
- package/example-bundle/assets/index-BLQ14SEo.js +147 -0
- package/example-bundle/assets/logo-f-5LjVqJ.png +0 -0
- package/example-bundle/assets/style-Dnzx_jUO.css +1 -0
- package/example-bundle/index.html +13 -0
- package/example-bundle/pack-manifest.json +36 -0
- package/example-bundle/scenario.json +9 -0
- package/package.json +5 -5
- package/src/__tests__/pack-generate-embed-entry.test.ts +59 -6
- package/src/__tests__/try-command.test.ts +21 -0
- package/src/commands/try.d.ts +3 -0
- package/src/commands/try.d.ts.map +1 -0
- package/src/commands/try.js +99 -0
- package/src/commands/try.js.map +1 -0
- package/src/commands/try.ts +122 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +2 -0
- package/src/index.js.map +1 -1
- package/src/index.ts +2 -0
- package/src/pack/generate-embed-entry.d.ts +11 -0
- package/src/pack/generate-embed-entry.d.ts.map +1 -1
- package/src/pack/generate-embed-entry.js +81 -10
- package/src/pack/generate-embed-entry.js.map +1 -1
- package/src/pack/generate-embed-entry.ts +81 -10
- package/tsconfig.tsbuildinfo +1 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@source "./**/*.js";@layer scenar{.scenar{--scenar-surface: #ffffff;--scenar-border: #e5e7eb;--scenar-foreground: #0f172a;--scenar-muted-foreground: #64748b;--scenar-card: #ffffff;--scenar-accent: #f1f5f9;--scenar-primary: #0f172a;--scenar-ring: #0f172a}.scenar.dark{--scenar-surface: #0f172a;--scenar-border: #1e293b;--scenar-foreground: #f8fafc;--scenar-muted-foreground: #94a3b8;--scenar-card: #1e293b;--scenar-accent: #1e293b;--scenar-primary: #f8fafc;--scenar-ring: #f8fafc}}/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-neutral-900:oklch(20.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--drop-shadow-sm:0 1px 2px #00000026;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-foreground:var(--scenar-foreground);--color-border:var(--scenar-border)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-1{top:calc(var(--spacing) * 1)}.top-1\/2{top:50%}.top-3{top:calc(var(--spacing) * 3)}.-right-px{right:-1px}.right-0{right:calc(var(--spacing) * 0)}.-bottom-px{bottom:-1px}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-1{bottom:calc(var(--spacing) * 1)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.left-4{left:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-0\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mr-3{margin-right:calc(var(--spacing) * 3)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-\[7px\]{height:7px}.h-\[14px\]{height:14px}.h-\[15px\]{height:15px}.h-full{height:100%}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-0\.5{width:calc(var(--spacing) * .5)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-1\/3{width:33.3333%}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-\[3px\]{width:3px}.w-\[7px\]{width:7px}.w-\[14px\]{width:14px}.w-\[15px\]{width:15px}.w-\[42px\]{width:42px}.w-\[160px\]{width:160px}.w-full{width:100%}.w-px{width:1px}.max-w-4xl{max-width:var(--container-4xl)}.max-w-\[80\%\]{max-width:80%}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[2rem\]{min-width:2rem}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-2{--tw-translate-x:calc(var(--spacing) * -2);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-px{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-2{--tw-translate-y:calc(var(--spacing) * -2);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-px{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.flex-col{flex-direction:column}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-\[5px\]{gap:5px}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-\[\#1a1a1a\]{border-color:#1a1a1a}.border-\[\#1e1e1e\]{border-color:#1e1e1e}.border-\[\#2a2a2e\]{border-color:#2a2a2e}.border-\[\#2d2d2d\]{border-color:#2d2d2d}.border-\[\#3a3a3a\]{border-color:#3a3a3a}.border-\[\#3a3f47\]{border-color:#3a3f47}.border-\[\#3c4043\]{border-color:#3c4043}.border-\[\#007acc\]{border-color:#007acc}.border-\[\#ff6c37\]{border-color:#ff6c37}.border-\[var\(--scenar-border\)\],.border-border{border-color:var(--scenar-border)}.border-primary\/50{border-color:var(--scenar-primary)}@supports (color:color-mix(in lab,red,red)){.border-primary\/50{border-color:color-mix(in oklab,var(--scenar-primary) 50%,transparent)}}.border-transparent{border-color:#0000}.bg-\[\#0b93f6\]{background-color:#0b93f6}.bg-\[\#1a1a1a\]{background-color:#1a1a1a}.bg-\[\#1a73e8\]{background-color:#1a73e8}.bg-\[\#1c1c1c\]{background-color:#1c1c1c}.bg-\[\#1e1e1e\]{background-color:#1e1e1e}.bg-\[\#2a2a2e\]{background-color:#2a2a2e}.bg-\[\#2c2c2c\]{background-color:#2c2c2c}.bg-\[\#2d2d2d\]{background-color:#2d2d2d}.bg-\[\#3b82f6\]{background-color:#3b82f6}.bg-\[\#3b82f6\]\/10{background-color:#3b82f61a}.bg-\[\#3b82f6\]\/15{background-color:#3b82f626}.bg-\[\#5f6368\]{background-color:#5f6368}.bg-\[\#007acc\]{background-color:#007acc}.bg-\[\#007acc\]\/10{background-color:#007acc1a}.bg-\[\#22c55e\]{background-color:#22c55e}.bg-\[\#22c55e\]\/15{background-color:#22c55e26}.bg-\[\#28c840\]{background-color:#28c840}.bg-\[\#94a3b8\]\/15{background-color:#94a3b826}.bg-\[\#181b1f\]{background-color:#181b1f}.bg-\[\#999\]{background-color:#999}.bg-\[\#3274d9\]{background-color:#3274d9}.bg-\[\#04395e\]{background-color:#04395e}.bg-\[\#6366f1\]{background-color:#6366f1}.bg-\[\#35363a\]{background-color:#35363a}.bg-\[\#111217\]{background-color:#111217}.bg-\[\#202124\]{background-color:#202124}.bg-\[\#252526\]{background-color:#252526}.bg-\[\#323232\]{background-color:#323232}.bg-\[\#323233\]{background-color:#323233}.bg-\[\#333333\]{background-color:#333}.bg-\[\#404040\]{background-color:#404040}.bg-\[\#eab308\]\/15{background-color:#eab30826}.bg-\[\#ef4444\]\/15{background-color:#ef444426}.bg-\[\#febc2e\]{background-color:#febc2e}.bg-\[\#ff5f57\]{background-color:#ff5f57}.bg-\[var\(--scenar-accent\)\]{background-color:var(--scenar-accent)}.bg-\[var\(--scenar-card\)\]{background-color:var(--scenar-card)}.bg-\[var\(--scenar-surface\)\],.bg-background{background-color:var(--scenar-surface)}.bg-black{background-color:var(--color-black)}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black) 70%,transparent)}}.bg-card{background-color:var(--scenar-card)}.bg-foreground\/25{background-color:var(--scenar-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-foreground\/25{background-color:color-mix(in oklab,var(--scenar-foreground) 25%,transparent)}}.bg-foreground\/60{background-color:var(--scenar-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-foreground\/60{background-color:color-mix(in oklab,var(--scenar-foreground) 60%,transparent)}}.bg-foreground\/80{background-color:var(--scenar-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-foreground\/80{background-color:color-mix(in oklab,var(--scenar-foreground) 80%,transparent)}}.bg-white{background-color:var(--color-white)}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab,red,red)){.bg-white\/80{background-color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white) 90%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#6366f1\]{--tw-gradient-from:#6366f1;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#ff6600\]{--tw-gradient-from:#f60;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#8b5cf6\]{--tw-gradient-to:#8b5cf6;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#f5a623\]{--tw-gradient-to:#f5a623;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-\[2px\]{padding-block:2px}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-\[10px\]{padding-top:10px}.pt-\[14px\]{padding-top:14px}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-1{padding-left:calc(var(--spacing) * 1)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[16px\]{font-size:16px}.leading-\[1\.6\]{--tw-leading:1.6;line-height:1.6}.leading-\[18px\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#3b82f6\]{color:#3b82f6}.text-\[\#5f6368\]{color:#5f6368}.text-\[\#6e7681\]{color:#6e7681}.text-\[\#9aa0a6\]{color:#9aa0a6}.text-\[\#9d9d9d\]{color:#9d9d9d}.text-\[\#22c55e\]{color:#22c55e}.text-\[\#50fa7b\]{color:#50fa7b}.text-\[\#94a3b8\]{color:#94a3b8}.text-\[\#519aba\]{color:#519aba}.text-\[\#666\]{color:#666}.text-\[\#888\]{color:#888}.text-\[\#64748b\]{color:#64748b}.text-\[\#666666\]{color:#666}.text-\[\#858585\]{color:#858585}.text-\[\#a0a0a0\]{color:#a0a0a0}.text-\[\#bd93f9\]{color:#bd93f9}.text-\[\#bdc1c6\]{color:#bdc1c6}.text-\[\#c6c6c6\]{color:#c6c6c6}.text-\[\#cccccc\]{color:#ccc}.text-\[\#d4d4d4\]{color:#d4d4d4}.text-\[\#dcb67a\]{color:#dcb67a}.text-\[\#e8e8e8\]{color:#e8e8e8}.text-\[\#e8eaed\]{color:#e8eaed}.text-\[\#e6995b\]{color:#e6995b}.text-\[\#eab308\]{color:#eab308}.text-\[\#ef4444\]{color:#ef4444}.text-\[\#f8f8f2\]{color:#f8f8f2}.text-\[\#f8f8f2\]\/70{color:#f8f8f2b3}.text-\[\#ff5555\]{color:#f55}.text-\[\#ffffff\]{color:#fff}.text-\[var\(--scenar-foreground\)\]{color:var(--scenar-foreground)}.text-\[var\(--scenar-muted-foreground\)\]{color:var(--scenar-muted-foreground)}.text-foreground,.text-foreground\/70{color:var(--scenar-foreground)}@supports (color:color-mix(in lab,red,red)){.text-foreground\/70{color:color-mix(in oklab,var(--scenar-foreground) 70%,transparent)}}.text-muted-foreground{color:var(--scenar-muted-foreground)}.text-neutral-900{color:var(--color-neutral-900)}.text-primary{color:var(--scenar-primary)}.text-white{color:var(--color-white)}.text-white\/70{color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.text-white\/70{color:color-mix(in oklab,var(--color-white) 70%,transparent)}}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow-\[0_0_30px_rgba\(255\,255\,255\,0\.3\)\]{--tw-shadow:0 0 30px var(--tw-shadow-color,#ffffff4d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white\/30{--tw-ring-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.ring-white\/30{--tw-ring-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.drop-shadow-sm{--tw-drop-shadow-size:drop-shadow(0 1px 2px var(--tw-drop-shadow-color,#00000026));--tw-drop-shadow:drop-shadow(var(--drop-shadow-sm));filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[height\]{transition-property:height;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:h-1\.5:hover{height:calc(var(--spacing) * 1.5)}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:bg-accent:hover{background-color:var(--scenar-accent)}.hover\:text-foreground:hover{color:var(--scenar-foreground)}}}@layer scenar{.scenar{--scenar-surface:#fff;--scenar-border:#e5e7eb;--scenar-foreground:#0f172a;--scenar-muted-foreground:#64748b;--scenar-card:#fff;--scenar-accent:#f1f5f9;--scenar-primary:#0f172a;--scenar-ring:#0f172a}.scenar.dark{--scenar-surface:#0f172a;--scenar-border:#1e293b;--scenar-foreground:#f8fafc;--scenar-muted-foreground:#94a3b8;--scenar-card:#1e293b;--scenar-accent:#1e293b;--scenar-primary:#f8fafc;--scenar-ring:#f8fafc}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>welcome-tour</title>
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-BLQ14SEo.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/style-Dnzx_jUO.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"scenarioId": "welcome-tour",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"path": "assets/index-BLQ14SEo.js",
|
|
7
|
+
"sha256": "c92c12b731c1fbd2b1a52bab87ce7d0f4be9f527c76f16d40f399c6b3b786f0b",
|
|
8
|
+
"sizeBytes": 373572,
|
|
9
|
+
"contentType": "text/javascript"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"path": "assets/logo-f-5LjVqJ.png",
|
|
13
|
+
"sha256": "646d467684f319064ba97fa832ef53f641d2872ddc6d0821e267b75f9ac714aa",
|
|
14
|
+
"sizeBytes": 15394,
|
|
15
|
+
"contentType": "image/png"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"path": "assets/style-Dnzx_jUO.css",
|
|
19
|
+
"sha256": "1f3690453ddfa2eeb5ad686d941a2a258ad888b943f3b1e195b2d2c3765874d8",
|
|
20
|
+
"sizeBytes": 30458,
|
|
21
|
+
"contentType": "text/css"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "index.html",
|
|
25
|
+
"sha256": "242a0d2b71f1cc01a1c61a75fb605ae35997d0d943a9b4bd71fd982c7aef51e3",
|
|
26
|
+
"sizeBytes": 397,
|
|
27
|
+
"contentType": "text/html"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "scenario.json",
|
|
31
|
+
"sha256": "036d23cf0523958fc5b5b2da57318d9ad2ab8fb2f1eac0c264a52a7b15cbc001",
|
|
32
|
+
"sizeBytes": 148,
|
|
33
|
+
"contentType": "application/json"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scenar/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Scenar CLI — validate scenarios, generate narration, and render videos.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"@bufbuild/protobuf": "^2.2.2",
|
|
43
43
|
"@connectrpc/connect": "^2.0.0",
|
|
44
44
|
"@connectrpc/connect-node": "^2.0.0",
|
|
45
|
-
"@scenar/core": "0.2.
|
|
46
|
-
"@scenar/preview": "0.2.
|
|
47
|
-
"@scenar/sdk": "0.2.
|
|
48
|
-
"@scenar/stubs": "0.2.
|
|
45
|
+
"@scenar/core": "0.2.1",
|
|
46
|
+
"@scenar/preview": "0.2.1",
|
|
47
|
+
"@scenar/sdk": "0.2.1",
|
|
48
|
+
"@scenar/stubs": "0.2.1",
|
|
49
49
|
"commander": "^13.0.0",
|
|
50
50
|
"yaml": "^2.7.0"
|
|
51
51
|
},
|
|
@@ -16,13 +16,53 @@ describe("generateEmbedEntry", () => {
|
|
|
16
16
|
it("mounts ScenarioPlayer into #root with the renderStep contract", () => {
|
|
17
17
|
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
18
18
|
expect(src).toContain('import { createRoot } from "react-dom/client";');
|
|
19
|
-
expect(src).toContain('import { ScenarioPlayer, DemoViewport, SCENAR_CLASS } from "@scenar/react";');
|
|
20
19
|
expect(src).toContain('import { renderStep } from "/proj/scenarios/welcome-tour/index";');
|
|
21
|
-
expect(src).toContain("<ScenarioPlayer bundle={_bundle} embed>");
|
|
20
|
+
expect(src).toContain("<ScenarioPlayer bundle={_bundle} embed onStepChange={_handleStepChange}>");
|
|
22
21
|
expect(src).toContain("renderStep(data, stepIndex)");
|
|
23
22
|
expect(src).toContain('getElementById("root")');
|
|
24
23
|
});
|
|
25
24
|
|
|
25
|
+
it("imports the interaction primitives + React hooks the embed wiring needs", () => {
|
|
26
|
+
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
27
|
+
expect(src).toContain('import { useCallback, useRef, useState } from "react";');
|
|
28
|
+
// ScenarioPlayer/DemoViewport/SCENAR_CLASS plus Cursor, useStepInteractions,
|
|
29
|
+
// ViewportTransformLayer, VIEWPORT_TRANSFORM_IDENTITY all come from @scenar/react.
|
|
30
|
+
expect(src).toContain(
|
|
31
|
+
'import { ScenarioPlayer, DemoViewport, SCENAR_CLASS, Cursor, useStepInteractions, ViewportTransformLayer, VIEWPORT_TRANSFORM_IDENTITY } from "@scenar/react";',
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("wires the host-side interaction system so packed embeds run interactions", () => {
|
|
36
|
+
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
37
|
+
// A shared container ref flows to DemoViewport, useStepInteractions, and Cursor.
|
|
38
|
+
expect(src).toContain("const _containerRef = useRef<HTMLDivElement>(null);");
|
|
39
|
+
expect(src).toContain("<DemoViewport containerRef={_containerRef}");
|
|
40
|
+
// Step index is tracked from the player and fed to the interaction scheduler.
|
|
41
|
+
expect(src).toContain("onStepChange={_handleStepChange}");
|
|
42
|
+
expect(src).toContain("useStepInteractions({");
|
|
43
|
+
expect(src).toContain("setCursorTarget: _setCursorTarget,");
|
|
44
|
+
expect(src).toContain("setViewportTransform: _setViewport,");
|
|
45
|
+
expect(src).toContain("steps: _steps,");
|
|
46
|
+
// Cursor is a sibling of the transform layer (absolute-positioned against the
|
|
47
|
+
// shared container) — the documented invariant.
|
|
48
|
+
expect(src).toContain("<ViewportTransformLayer transform={_viewport}>");
|
|
49
|
+
expect(src).toContain(
|
|
50
|
+
"<Cursor target={_cursorTarget} containerRef={_containerRef} showRipple={_showRipple} isDragging={_dragging} />",
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("feeds the narration manifest into the interaction scheduler when present", () => {
|
|
55
|
+
const without = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
56
|
+
// No narration: interactions are timed by step delays only.
|
|
57
|
+
expect(without).toContain("narrationManifest: undefined,");
|
|
58
|
+
|
|
59
|
+
const withNarration = generateEmbedEntry({ ...BASE, hasNarration: true, providersPath: null });
|
|
60
|
+
// With narration: both the bundle and useStepInteractions receive _manifest,
|
|
61
|
+
// so interaction timing tracks the spoken-clip durations.
|
|
62
|
+
expect(withNarration).toContain("narrationManifest: _manifest,");
|
|
63
|
+
expect(withNarration).not.toContain("narrationManifest: undefined,");
|
|
64
|
+
});
|
|
65
|
+
|
|
26
66
|
it("imports the @scenar/react theme + styles so the bundle is self-contained", () => {
|
|
27
67
|
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
28
68
|
expect(src).toContain('import "@scenar/react/theme.css";');
|
|
@@ -31,11 +71,23 @@ describe("generateEmbedEntry", () => {
|
|
|
31
71
|
|
|
32
72
|
it("scopes the tree with SCENAR_CLASS + DemoViewport sizing", () => {
|
|
33
73
|
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
34
|
-
expect(src).toContain("className={SCENAR_CLASS}");
|
|
35
74
|
expect(src).toContain("canonicalWidth={896}");
|
|
36
75
|
expect(src).toContain("shellHeight={480}");
|
|
37
76
|
});
|
|
38
77
|
|
|
78
|
+
it("derives the root class from ?theme so dark is opt-in and the default stays light", () => {
|
|
79
|
+
const src = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
80
|
+
// The container class is theme-derived, not a hardcoded SCENAR_CLASS.
|
|
81
|
+
expect(src).toContain("className={_rootClass}");
|
|
82
|
+
expect(src).not.toContain("className={SCENAR_CLASS}");
|
|
83
|
+
// Reads the theme from the embed's own URL.
|
|
84
|
+
expect(src).toContain('new URLSearchParams(window.location.search).get("theme")');
|
|
85
|
+
// theme=dark adds the `dark` class (-> .scenar.dark tokens); else light.
|
|
86
|
+
expect(src).toContain(
|
|
87
|
+
'const _rootClass = _theme === "dark" ? SCENAR_CLASS + " dark" : SCENAR_CLASS;',
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
|
|
39
91
|
it("fetches the narration manifest at runtime only when present", () => {
|
|
40
92
|
const without = generateEmbedEntry({ ...BASE, hasNarration: false, providersPath: null });
|
|
41
93
|
expect(without).toContain("narrationManifest: undefined,");
|
|
@@ -45,10 +97,11 @@ describe("generateEmbedEntry", () => {
|
|
|
45
97
|
const withNarration = generateEmbedEntry({ ...BASE, hasNarration: true, providersPath: null });
|
|
46
98
|
// Never inlines the manifest as a build-time JSON import.
|
|
47
99
|
expect(withNarration).not.toContain("import _manifest");
|
|
48
|
-
// Imports the hook
|
|
49
|
-
// so clip src values resolve
|
|
100
|
+
// Imports the hook (appended after the interaction primitives) and fetches
|
|
101
|
+
// the manifest from its own relative location, so clip src values resolve
|
|
102
|
+
// against ./narration/ at runtime.
|
|
50
103
|
expect(withNarration).toContain(
|
|
51
|
-
'import { ScenarioPlayer, DemoViewport, SCENAR_CLASS, useNarrationManifest } from "@scenar/react";',
|
|
104
|
+
'import { ScenarioPlayer, DemoViewport, SCENAR_CLASS, Cursor, useStepInteractions, ViewportTransformLayer, VIEWPORT_TRANSFORM_IDENTITY, useNarrationManifest } from "@scenar/react";',
|
|
52
105
|
);
|
|
53
106
|
expect(withNarration).toContain('const _resolveManifestUrl = () => "./narration/manifest.json";');
|
|
54
107
|
expect(withNarration).toContain(
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { createProgram } from "../index.js";
|
|
3
|
+
|
|
4
|
+
describe("scenar try", () => {
|
|
5
|
+
it("registers the try command", () => {
|
|
6
|
+
const program = createProgram();
|
|
7
|
+
const cmd = program.commands.find((c) => c.name() === "try");
|
|
8
|
+
expect(cmd).toBeDefined();
|
|
9
|
+
expect(cmd!.description()).toContain("no app required");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("takes no positional arguments and exposes its options", () => {
|
|
13
|
+
const program = createProgram();
|
|
14
|
+
const cmd = program.commands.find((c) => c.name() === "try");
|
|
15
|
+
expect(cmd!.registeredArguments).toHaveLength(0);
|
|
16
|
+
const opts = cmd!.options.map((o) => o.long);
|
|
17
|
+
expect(opts).toContain("--port");
|
|
18
|
+
expect(opts).toContain("--host");
|
|
19
|
+
expect(opts).toContain("--open");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"try.d.ts","sourceRoot":"","sources":["../../../src/commands/try.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2DzD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { platform } from "node:process";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { stat } from "node:fs/promises";
|
|
6
|
+
import { runServe } from "../serve/run-serve.js";
|
|
7
|
+
/** Vite's preview port — the conventional "serve a built site" port. */
|
|
8
|
+
const DEFAULT_PORT = 4173;
|
|
9
|
+
/** Bind to loopback by default; a preview is a single-developer tool. */
|
|
10
|
+
const DEFAULT_HOST = "localhost";
|
|
11
|
+
/**
|
|
12
|
+
* The example bundle that ships with the CLI. It's generated at build time
|
|
13
|
+
* (`pack examples/welcome-tour --out dist/example-bundle`, see package.json) and
|
|
14
|
+
* published as part of dist/, so it's present for npx consumers. This module
|
|
15
|
+
* compiles to dist/src/commands/try.js, so the bundle sits two levels up.
|
|
16
|
+
*/
|
|
17
|
+
const EXAMPLE_BUNDLE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../../example-bundle");
|
|
18
|
+
export function registerTryCommand(program) {
|
|
19
|
+
program
|
|
20
|
+
.command("try")
|
|
21
|
+
.description("Serve the bundled welcome-tour example locally — no app required.\n\n" +
|
|
22
|
+
"Boots the example embed that ships with the CLI on\n" +
|
|
23
|
+
"http://localhost:4173 (override with --port/--host) and prints a\n" +
|
|
24
|
+
"ready-to-paste <iframe> snippet, then stays running until Ctrl+C.\n\n" +
|
|
25
|
+
"This is the fastest way to see what a Scenar embed looks like before\n" +
|
|
26
|
+
"wiring up your own app. To build a tour from your components, see\n" +
|
|
27
|
+
"`scenar preview`; to host one, see `scenar publish`.")
|
|
28
|
+
.option("--port <number>", `port to listen on (default: ${DEFAULT_PORT})`, String(DEFAULT_PORT))
|
|
29
|
+
.option("--host <host>", `host/interface to bind (default: ${DEFAULT_HOST})`, DEFAULT_HOST)
|
|
30
|
+
.option("--open", "open the embed in your default browser")
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
try {
|
|
33
|
+
const port = Number(options.port);
|
|
34
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
35
|
+
throw new Error(`invalid --port "${options.port}"; expected an integer between 0 and 65535.`);
|
|
36
|
+
}
|
|
37
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
38
|
+
const bundle = await stat(EXAMPLE_BUNDLE_DIR).catch(() => null);
|
|
39
|
+
if (!bundle || !bundle.isDirectory()) {
|
|
40
|
+
throw new Error("the bundled example is missing. If you installed @scenar/cli from npm, " +
|
|
41
|
+
"reinstall it; if you're running from source, run `pnpm build` first.");
|
|
42
|
+
}
|
|
43
|
+
let result;
|
|
44
|
+
try {
|
|
45
|
+
result = await runServe({ bundleDir: EXAMPLE_BUNDLE_DIR, port, host });
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (isAddrInUse(error)) {
|
|
49
|
+
throw new Error(`port ${port} is already in use. Stop the other process or pass --port <number>.`);
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
process.stderr.write(`\n\x1b[32m✓\x1b[0m Serving the welcome-tour example at ${result.url}\n`);
|
|
54
|
+
process.stderr.write("\n Embed snippet (paste into any page):\n\n");
|
|
55
|
+
process.stderr.write(`${indent(result.snippet)}\n`);
|
|
56
|
+
process.stderr.write("\n Press Ctrl+C to stop.\n");
|
|
57
|
+
if (options.open) {
|
|
58
|
+
openInBrowser(result.url);
|
|
59
|
+
}
|
|
60
|
+
await runUntilInterrupted(result.handle);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
64
|
+
process.stderr.write(`\x1b[31mError:\x1b[0m ${msg}\n`);
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Block until SIGINT/SIGTERM, then close the server cleanly. */
|
|
70
|
+
function runUntilInterrupted(handle) {
|
|
71
|
+
return new Promise((resolvePromise) => {
|
|
72
|
+
const shutdown = () => {
|
|
73
|
+
process.stderr.write("\nStopping...\n");
|
|
74
|
+
void handle.close().finally(() => resolvePromise());
|
|
75
|
+
};
|
|
76
|
+
process.once("SIGINT", shutdown);
|
|
77
|
+
process.once("SIGTERM", shutdown);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/** Best-effort: launch the OS default browser. Failures are silent (non-fatal). */
|
|
81
|
+
function openInBrowser(url) {
|
|
82
|
+
const command = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
83
|
+
try {
|
|
84
|
+
const child = spawn(command, [url], { stdio: "ignore", detached: true, shell: platform === "win32" });
|
|
85
|
+
child.on("error", () => { });
|
|
86
|
+
child.unref();
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Opening a browser is a convenience; never fail the command over it.
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function isAddrInUse(error) {
|
|
93
|
+
return typeof error === "object" && error !== null && error.code === "EADDRINUSE";
|
|
94
|
+
}
|
|
95
|
+
/** Indent every line by two spaces (for nesting a block under a heading). */
|
|
96
|
+
function indent(block) {
|
|
97
|
+
return block.replace(/^/gm, " ");
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=try.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"try.js","sourceRoot":"","sources":["../../../src/commands/try.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,wEAAwE;AACxE,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,yEAAyE;AACzE,MAAM,YAAY,GAAG,WAAW,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;AAQpG,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CACV,uEAAuE;QACrE,sDAAsD;QACtD,oEAAoE;QACpE,uEAAuE;QACvE,wEAAwE;QACxE,qEAAqE;QACrE,sDAAsD,CACzD;SACA,MAAM,CAAC,iBAAiB,EAAE,+BAA+B,YAAY,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;SAC/F,MAAM,CAAC,eAAe,EAAE,oCAAoC,YAAY,GAAG,EAAE,YAAY,CAAC;SAC1F,MAAM,CAAC,QAAQ,EAAE,wCAAwC,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAAmB,EAAE,EAAE;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBACxD,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,IAAI,6CAA6C,CAAC,CAAC;YAChG,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;YAE1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YAChE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,yEAAyE;oBACvE,sEAAsE,CACzE,CAAC;YACJ,CAAC;YAED,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,qEAAqE,CAClF,CAAC;gBACJ,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0DAA0D,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;YAC/F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YACrE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAEpD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YAED,MAAM,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;YACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,iEAAiE;AACjE,SAAS,mBAAmB,CAAC,MAA0B;IACrD,OAAO,IAAI,OAAO,CAAO,CAAC,cAAc,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACxC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,mFAAmF;AACnF,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,OAAO,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7F,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;QACtG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAA2B,CAAC,IAAI,KAAK,YAAY,CAAC;AAC3G,CAAC;AAED,6EAA6E;AAC7E,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { platform } from "node:process";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { stat } from "node:fs/promises";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { runServe } from "../serve/run-serve.js";
|
|
8
|
+
import type { BundleServerHandle } from "../serve/static-server.js";
|
|
9
|
+
|
|
10
|
+
/** Vite's preview port — the conventional "serve a built site" port. */
|
|
11
|
+
const DEFAULT_PORT = 4173;
|
|
12
|
+
|
|
13
|
+
/** Bind to loopback by default; a preview is a single-developer tool. */
|
|
14
|
+
const DEFAULT_HOST = "localhost";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The example bundle that ships with the CLI. It's generated at build time
|
|
18
|
+
* (`pack examples/welcome-tour --out dist/example-bundle`, see package.json) and
|
|
19
|
+
* published as part of dist/, so it's present for npx consumers. This module
|
|
20
|
+
* compiles to dist/src/commands/try.js, so the bundle sits two levels up.
|
|
21
|
+
*/
|
|
22
|
+
const EXAMPLE_BUNDLE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../../example-bundle");
|
|
23
|
+
|
|
24
|
+
interface TryOptions {
|
|
25
|
+
port?: string;
|
|
26
|
+
host?: string;
|
|
27
|
+
open?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function registerTryCommand(program: Command): void {
|
|
31
|
+
program
|
|
32
|
+
.command("try")
|
|
33
|
+
.description(
|
|
34
|
+
"Serve the bundled welcome-tour example locally — no app required.\n\n" +
|
|
35
|
+
"Boots the example embed that ships with the CLI on\n" +
|
|
36
|
+
"http://localhost:4173 (override with --port/--host) and prints a\n" +
|
|
37
|
+
"ready-to-paste <iframe> snippet, then stays running until Ctrl+C.\n\n" +
|
|
38
|
+
"This is the fastest way to see what a Scenar embed looks like before\n" +
|
|
39
|
+
"wiring up your own app. To build a tour from your components, see\n" +
|
|
40
|
+
"`scenar preview`; to host one, see `scenar publish`.",
|
|
41
|
+
)
|
|
42
|
+
.option("--port <number>", `port to listen on (default: ${DEFAULT_PORT})`, String(DEFAULT_PORT))
|
|
43
|
+
.option("--host <host>", `host/interface to bind (default: ${DEFAULT_HOST})`, DEFAULT_HOST)
|
|
44
|
+
.option("--open", "open the embed in your default browser")
|
|
45
|
+
.action(async (options: TryOptions) => {
|
|
46
|
+
try {
|
|
47
|
+
const port = Number(options.port);
|
|
48
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
49
|
+
throw new Error(`invalid --port "${options.port}"; expected an integer between 0 and 65535.`);
|
|
50
|
+
}
|
|
51
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
52
|
+
|
|
53
|
+
const bundle = await stat(EXAMPLE_BUNDLE_DIR).catch(() => null);
|
|
54
|
+
if (!bundle || !bundle.isDirectory()) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"the bundled example is missing. If you installed @scenar/cli from npm, " +
|
|
57
|
+
"reinstall it; if you're running from source, run `pnpm build` first.",
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let result;
|
|
62
|
+
try {
|
|
63
|
+
result = await runServe({ bundleDir: EXAMPLE_BUNDLE_DIR, port, host });
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (isAddrInUse(error)) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`port ${port} is already in use. Stop the other process or pass --port <number>.`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
process.stderr.write(`\n\x1b[32m✓\x1b[0m Serving the welcome-tour example at ${result.url}\n`);
|
|
74
|
+
process.stderr.write("\n Embed snippet (paste into any page):\n\n");
|
|
75
|
+
process.stderr.write(`${indent(result.snippet)}\n`);
|
|
76
|
+
process.stderr.write("\n Press Ctrl+C to stop.\n");
|
|
77
|
+
|
|
78
|
+
if (options.open) {
|
|
79
|
+
openInBrowser(result.url);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
await runUntilInterrupted(result.handle);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
85
|
+
process.stderr.write(`\x1b[31mError:\x1b[0m ${msg}\n`);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Block until SIGINT/SIGTERM, then close the server cleanly. */
|
|
92
|
+
function runUntilInterrupted(handle: BundleServerHandle): Promise<void> {
|
|
93
|
+
return new Promise<void>((resolvePromise) => {
|
|
94
|
+
const shutdown = () => {
|
|
95
|
+
process.stderr.write("\nStopping...\n");
|
|
96
|
+
void handle.close().finally(() => resolvePromise());
|
|
97
|
+
};
|
|
98
|
+
process.once("SIGINT", shutdown);
|
|
99
|
+
process.once("SIGTERM", shutdown);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Best-effort: launch the OS default browser. Failures are silent (non-fatal). */
|
|
104
|
+
function openInBrowser(url: string): void {
|
|
105
|
+
const command = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
106
|
+
try {
|
|
107
|
+
const child = spawn(command, [url], { stdio: "ignore", detached: true, shell: platform === "win32" });
|
|
108
|
+
child.on("error", () => {});
|
|
109
|
+
child.unref();
|
|
110
|
+
} catch {
|
|
111
|
+
// Opening a browser is a convenience; never fail the command over it.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isAddrInUse(error: unknown): boolean {
|
|
116
|
+
return typeof error === "object" && error !== null && (error as { code?: string }).code === "EADDRINUSE";
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Indent every line by two spaces (for nesting a block under a heading). */
|
|
120
|
+
function indent(block: string): string {
|
|
121
|
+
return block.replace(/^/gm, " ");
|
|
122
|
+
}
|
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,aAAa,IAAI,OAAO,CAmBvC;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAGxC"}
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { registerPreviewCommand } from "./commands/preview.js";
|
|
|
5
5
|
import { registerRenderCommand } from "./commands/render.js";
|
|
6
6
|
import { registerPackCommand } from "./commands/pack.js";
|
|
7
7
|
import { registerServeCommand } from "./commands/serve.js";
|
|
8
|
+
import { registerTryCommand } from "./commands/try.js";
|
|
8
9
|
import { registerPublishCommand } from "./commands/publish.js";
|
|
9
10
|
import { registerDeployCommand } from "./commands/deploy.js";
|
|
10
11
|
export function createProgram() {
|
|
@@ -19,6 +20,7 @@ export function createProgram() {
|
|
|
19
20
|
registerPreviewCommand(program);
|
|
20
21
|
registerPackCommand(program);
|
|
21
22
|
registerServeCommand(program);
|
|
23
|
+
registerTryCommand(program);
|
|
22
24
|
registerPublishCommand(program);
|
|
23
25
|
registerDeployCommand(program);
|
|
24
26
|
return program;
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,8FAA8F,CAAC;SAC3G,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,8FAA8F,CAAC;SAC3G,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { registerPreviewCommand } from "./commands/preview.js";
|
|
|
5
5
|
import { registerRenderCommand } from "./commands/render.js";
|
|
6
6
|
import { registerPackCommand } from "./commands/pack.js";
|
|
7
7
|
import { registerServeCommand } from "./commands/serve.js";
|
|
8
|
+
import { registerTryCommand } from "./commands/try.js";
|
|
8
9
|
import { registerPublishCommand } from "./commands/publish.js";
|
|
9
10
|
import { registerDeployCommand } from "./commands/deploy.js";
|
|
10
11
|
|
|
@@ -22,6 +23,7 @@ export function createProgram(): Command {
|
|
|
22
23
|
registerPreviewCommand(program);
|
|
23
24
|
registerPackCommand(program);
|
|
24
25
|
registerServeCommand(program);
|
|
26
|
+
registerTryCommand(program);
|
|
25
27
|
registerPublishCommand(program);
|
|
26
28
|
registerDeployCommand(program);
|
|
27
29
|
|
|
@@ -30,6 +30,17 @@ export interface EmbedEntryInput {
|
|
|
30
30
|
* @scenar/react theme + styles so the bundle is self-contained, and scopes the
|
|
31
31
|
* tree with `SCENAR_CLASS` + `DemoViewport` exactly as the authoring surfaces do.
|
|
32
32
|
*
|
|
33
|
+
* Interactions: the entry wires the full host-side interaction system —
|
|
34
|
+
* `useStepInteractions` + `<Cursor>` + `<ViewportTransformLayer>` — so packed
|
|
35
|
+
* embeds run the same narration-synced cursor moves, clicks, typing, hovers,
|
|
36
|
+
* drags, scrolls, and viewport transitions as the in-app player. (`ScenarioPlayer`
|
|
37
|
+
* itself owns none of this; the host must wire it, per DemoViewport's contract.)
|
|
38
|
+
*
|
|
39
|
+
* Theme: the embed reads `?theme` from its own URL and applies the `dark` class
|
|
40
|
+
* alongside `SCENAR_CLASS` when `theme=dark` (matching the `.scenar.dark` token
|
|
41
|
+
* selector). The default is light, so existing embeds are unaffected; a host can
|
|
42
|
+
* theme-sync simply by framing `…/?theme=dark`.
|
|
43
|
+
*
|
|
33
44
|
* Pure function, no side effects — the caller writes the result to disk.
|
|
34
45
|
*/
|
|
35
46
|
export declare function generateEmbedEntry(input: EmbedEntryInput): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-embed-entry.d.ts","sourceRoot":"","sources":["../../../src/pack/generate-embed-entry.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"generate-embed-entry.d.ts","sourceRoot":"","sources":["../../../src/pack/generate-embed-entry.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAiJjE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAgBnF"}
|