@chromatic-com/storybook 1.2.11 → 1.2.12
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/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.map +1 -1
- package/dist/manager.mjs +26 -26
- package/dist/manager.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,12 +6,12 @@ var node = require('chromatic/node');
|
|
|
6
6
|
var filesize = require('filesize');
|
|
7
7
|
var jsonfile = require('jsonfile');
|
|
8
8
|
|
|
9
|
-
var
|
|
10
|
-
${
|
|
9
|
+
var v=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(r,e)=>(typeof require<"u"?require:r)[e]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var {CHROMATIC_INDEX_URL:Z,CHROMATIC_BASE_URL:E=Z||"https://www.chromatic.com",CHROMATIC_API_URL:le=`${E}/api`}=process.env,w="@chromatic-com/storybook",a="chromaui/addon-visual-tests",R=`${a}/configInfo`,B=`${a}/gitInfo`,k=`${a}/gitInfoError`,L=`${a}/projectInfo`,A=`${a}/startBuild`,N=`${a}/stopBuild`,x=`${a}/localBuildProgress`,U=`${a}/removeAddon`,F={autoAcceptChanges:!1,exitOnceUploaded:!1,exitZeroOnChanges:!0,forceRebuild:!0,fromCI:!1,isLocalBuild:!0,skip:!1,interactive:!1};var h=t=>I.includes(t),j=t=>["upload","snapshot"].includes(t),I=["initialize","build","upload","verify","snapshot"],y={initialize:{key:"initialize",emoji:"\u{1F680}",renderName:()=>"Initialize build",renderProgress:()=>"Initializing build...",renderComplete:()=>"Initialized",estimateDuration:2e3},build:{key:"build",emoji:"\u{1F3D7}",renderName:()=>"Build Storybook",renderProgress:()=>"Building your Storybook...",renderComplete:()=>"Storybook built",estimateDuration:2e4},upload:{key:"upload",emoji:"\u{1F4E1}",renderName:()=>"Publish your Storybook",renderProgress:({stepProgress:t})=>{let{numerator:r,denominator:e}=t.upload;if(!e||!r)return "Uploading files...";let{value:o,exponent:n}=filesize.filesize(e,{output:"object",round:1}),{value:s,symbol:i}=filesize.filesize(r,{exponent:n,output:"object",round:1});return `Uploading files (${s}/${o} ${i})...`},renderComplete:()=>"Publish complete",estimateDuration:2e4},verify:{key:"verify",emoji:"\u{1F50D}",renderName:()=>"Verify your Storybook",renderProgress:()=>"Verifying contents...",renderComplete:()=>"Storybook verified",estimateDuration:2e4},snapshot:{key:"snapshot",emoji:"\u{1F4F8}",renderName:()=>"Run visual tests",renderProgress:({stepProgress:t})=>{let{numerator:r,denominator:e}=t.snapshot;return e?`Running visual tests (${r}/${e})...`:"Running visual tests..."},renderComplete:()=>"Tested your stories",estimateDuration:9e4},aborted:{key:"aborted",emoji:"\u270B",renderName:()=>"Build canceled",renderProgress:()=>"Build canceled",renderComplete:()=>"Build canceled",estimateDuration:0},complete:{key:"complete",emoji:"\u{1F389}",renderName:()=>"Visual tests completed!",renderProgress:()=>"Visual tests completed!",renderComplete:()=>"Visual tests completed!",estimateDuration:0},error:{key:"error",emoji:"\u{1F6A8}",renderName:()=>"Build failed",renderProgress:()=>"Build failed",renderComplete:()=>"Build failed",estimateDuration:0},limited:{key:"error",emoji:"\u{1F6A8}",renderName:()=>"Build limited",renderProgress:()=>"Build limited",renderComplete:()=>"Build limited",estimateDuration:0}},G={buildProgressPercentage:0,currentStep:I[0],stepProgress:Object.fromEntries(I.map(t=>[t,{}]))};var M=2e3,b,ee=(t,r)=>{if(!h(t))throw new Error(`Unknown step: ${t}`);let e=I.map(p=>{let{startedAt:l,completedAt:f}=r?.[p]||{};return l&&f?f-l:y[p].estimateDuration}),o=e.reduce((p,l)=>p+l,0),n=I.indexOf(t),s=e.slice(0,n).reduce((p,l)=>p+l,0),i=s+e[n],c=s/o*100,d=i/o*100;return {...y[t],startPercentage:c,endPercentage:d,stepPercentage:d-c}},S=(t,r)=>(e,{progress:o,total:n}={})=>{if(clearTimeout(r),!h(e.task))return;if(!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{buildProgressPercentage:s,stepProgress:i,previousBuildProgress:c}=t.value;if(i[e.task]?.completedAt)return;let{startPercentage:d,endPercentage:p,stepPercentage:l}=ee(e.task,c),f=d;if(o&&n&&(f+=l*(o/n)),!j(e.task)){let{estimateDuration:u}=y[e.task],C=I.indexOf(e.task);f=Math.max(f,s)+M/u*l,r=setTimeout(()=>{if(!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{currentStep:g}=t.value;h(g)&&I.indexOf(g)<=C&&S(t,r)(e);},M);}i[e.task]={startedAt:Date.now(),...i[e.task],...o&&n&&{numerator:o,denominator:n}},t.value={buildId:e.announcedBuild?.id,branch:e.git?.branch,buildProgressPercentage:Math.min(f,p),currentStep:e.task,stepProgress:i};},V=(t,r)=>(e,o)=>{if(clearTimeout(r),!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{buildProgressPercentage:n,stepProgress:s}=t.value,i={buildId:e.announcedBuild?.id,branch:e.git?.branch,buildProgressPercentage:n,stepProgress:s,previousBuildProgress:s};if(o){t.value={...i,currentStep:b?.signal.aborted?"aborted":"error",formattedError:o.formattedError,originalError:o.originalError};return}e.task&&h(e.task)&&(s[e.task]={...s[e.task],completedAt:Date.now()}),e.task==="verify"&&e.build?.wasLimited&&(t.value={...i,currentStep:"limited",stepProgress:s,errorDetailsUrl:e.build?.app.account?.billingUrl}),e.build&&e.task==="snapshot"&&(t.value={...i,buildProgressPercentage:100,currentStep:"complete",stepProgress:s,changeCount:e.build.changeCount,errorCount:e.build.errorCount});},K=async(t,r)=>{if(!r.projectId)throw new Error("Missing projectId");if(!r.userToken)throw new Error("Missing userToken");t.value=G;let e;b?.abort(),b=new AbortController,process.env.SB_TESTBUILD="true",await node.run({flags:{interactive:!1},options:{...r,...F,experimental_onTaskStart:S(t,e),experimental_onTaskProgress:S(t,e),experimental_onTaskComplete:V(t,e),experimental_onTaskError:V(t,e),experimental_abortSignal:b?.signal}});},z=()=>{b?.abort(new Error("Build canceled from Storybook"));};var H="experimental_useSharedState_getValue",T="experimental_useSharedState_setValue",D=new Map,m=class{constructor(r){this.channel=r,this.listeners=[],this.state={},this.channel.on(T,(e,o,n)=>{this.state?.[e]?.index>=n||(this.state[e]={index:n,value:o});}),this.channel.on(H,e=>{let o=this.state[e]?.index??0,n=this.state[e]?.value;this.channel.emit(T,e,n,o);});}get(r){return this.state[r]||this.channel.emit(H,r),this.state[r]?.value}set(r,e){let o=(this.state[r]?.index??0)+1;this.state[r]={index:o,value:e},this.channel.emit(T,r,e,o);}static subscribe(r,e){let o=D.get(r)||new m(e);return D.has(r)||(D.set(r,o),o.channel.on(T,(n,s)=>{n===r&&o.listeners.forEach(i=>i(s));})),{get value(){return o.get(r)},set value(n){o.set(r,n);},on(n,s){if(n!=="change")throw new Error("unsupported event");o.listeners.push(s);},off(n,s){if(n!=="change")throw new Error("unsupported event");let i=o.listeners.indexOf(s);i>=0&&o.listeners.splice(i,1);}}}};async function Y(t,r){await jsonfile.writeFile(t,r,{spaces:2});}function oe(t=[]){return [...t,v.resolve("./manager.mjs")]}var q=(t,r,e)=>Object.fromEntries(Object.entries(e).map(([o,n])=>[o,n===r[o]?null:n]).filter(([o,n])=>n!==null||t[o]!==void 0)),ne=async(t,{configDir:r})=>{let e={storybookBaseDir:".",storybookConfigDir:".storybook"},o={},n={},{repositoryRootDir:s}=await node.getGitInfo(),i=s&&path.normalize(path.relative(s,process.cwd()));return i!==path.normalize(t.storybookBaseDir??"")&&(o.storybookBaseDir=i),r!==path.normalize(t.storybookConfigDir??"")&&(o.storybookConfigDir=path.normalize(path.relative(process.cwd(),r))),t.zip||(n.zip=!0),{configuration:t,problems:q(t,e,o),suggestions:q(t,e,n)}},ie=async(t,r,e,o)=>{let n,s,i,c=async()=>{try{let d=await node.getGitInfo();Object.entries(d).some(([p,l])=>n?.[p]!==l)&&r(d,n),n=d,s=void 0,i=setTimeout(c,t);}catch(d){e(d),o&&s?.message!==d.message&&(console.error(`Failed to fetch git info, with error:
|
|
10
|
+
${d}`),n=void 0,s=d),i=setTimeout(c,t);}};return c(),()=>clearTimeout(i)},se=async(t,r)=>{let e=await node.getConfiguration(t);await r(e),e.configFile&&fs.watch(e.configFile,async(o,n)=>{n&&await r(await node.getConfiguration(n));});};async function ae(t,r){let{configFile:e,presets:o}=r,n=o.apply("experimental_serverAPI"),{projectId:s}=await node.getConfiguration(e),i=m.subscribe(L,t);i.value=s?{projectId:s}:{};let c=s;i.on("change",async({projectId:u}={})=>{if(!u||u===c)return;c=u;let C=e;try{let{configFile:g,...X}=await node.getConfiguration(C),O=g||C||"chromatic.config.json";await Y(O,{...X,projectId:u}),i.value={...i.value,written:!0,configFile:O};}catch(g){console.warn(`Failed to update your main configuration:
|
|
11
11
|
|
|
12
|
-
${g}`),i.value={...i.value,written:!1,configFile:C};}});let
|
|
13
|
-
${g}`);}}),t.on(N,z),t.on(U,()=>n.then(
|
|
12
|
+
${g}`),i.value={...i.value,written:!1,configFile:C};}});let d=m.subscribe(x,t);t.on(A,async({accessToken:u})=>{let{projectId:C}=i.value||{};try{await K(d,{configFile:e,projectId:C,userToken:u});}catch(g){console.error(`Failed to run Chromatic build, with error:
|
|
13
|
+
${g}`);}}),t.on(N,z),t.on(U,()=>n.then(u=>u.removeAddon(w)).catch(u=>console.error(u)));let p=m.subscribe(R,t),l=m.subscribe(B,t),f=m.subscribe(k,t);return ie(5e3,u=>{f.value=void 0,l.value=u;},u=>{f.value=u;}),se(e,async u=>{c&&(p.value=await ne(u,r));}),setInterval(()=>t.emit(`${a}/heartbeat`),1e3),t}var ue={managerEntries:oe,experimental_serverChannel:ae,env:async(t,{configType:r})=>r==="PRODUCTION"?t:{...t,CHROMATIC_BASE_URL:E}},Ge=ue;
|
|
14
14
|
|
|
15
|
-
module.exports =
|
|
15
|
+
module.exports = Ge;
|
|
16
16
|
//# sourceMappingURL=out.js.map
|
|
17
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/runChromaticBuild.ts","../src/buildSteps.ts","../src/utils/SharedState.ts","../src/utils/updateChromaticConfig.ts"],"names":["watch","normalize","relative","getConfiguration","getGitInfo","CHROMATIC_INDEX_URL","CHROMATIC_BASE_URL","CHROMATIC_API_URL","PACKAGE_NAME","ADDON_ID","PANEL_ID","SIDEBAR_TOP_ID","SIDEBAR_BOTTOM_ID","ACCESS_TOKEN_KEY","DEV_BUILD_ID_KEY","CONFIG_INFO","CONFIG_INFO_DISMISSED","GIT_INFO","GIT_INFO_ERROR","PROJECT_INFO","IS_OUTDATED","START_BUILD","STOP_BUILD","LOCAL_BUILD_PROGRESS","REMOVE_ADDON","CONFIG_OVERRIDES","run","filesize","isKnownStep","taskOrStep","BUILD_STEP_ORDER","hasProgressEvent","task","BUILD_STEP_CONFIG","stepProgress","numerator","denominator","total","exponent","progress","symbol","INITIAL_BUILD_PAYLOAD","step","ESTIMATED_PROGRESS_INTERVAL","abortController","getBuildStepData","previousBuildProgress","stepDurations","startedAt","completedAt","totalDuration","sum","duration","stepIndex","startTime","endTime","startPercentage","endPercentage","onStartOrProgress","localBuildProgress","timeout","ctx","buildProgressPercentage","stepPercentage","newPercentage","estimateDuration","currentStep","onCompleteOrError","error","update","runChromaticBuild","options","stopChromaticBuild","GET_VALUE","SET_VALUE","instances","SharedState","channel","key","value","index","sharedState","k","v","listener","newValue","event","callback","writeFile","updateChromaticConfig","configFile","configuration","managerEntries","entry","__require","suggestRemovals","config","defaults","getConfigInfo","configDir","problems","suggestions","repositoryRootDir","baseDir","observeGitInfo","interval","errorCallback","projectId","prev","prevError","timer","act","gitInfo","e","watchConfigFile","onChange","eventType","filename","serverChannel","presets","apiPromise","initialProjectId","projectInfoState","lastProjectId","writtenConfigFile","foundConfigFile","targetConfigFile","err","userToken","api","configInfoState","gitInfoState","gitInfoError","info","env","configType","src_default"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { watch } from \"node:fs\";\nimport { normalize, relative } from \"node:path\";\n\nimport type { Channel } from \"@storybook/channels\";\nimport type { Options } from \"@storybook/types\";\n// eslint-disable-next-line import/no-unresolved\nimport { type Configuration, getConfiguration, getGitInfo, type GitInfo } from \"chromatic/node\";\n\nimport {\n ADDON_ID,\n CHROMATIC_BASE_URL,\n CONFIG_INFO,\n GIT_INFO,\n GIT_INFO_ERROR,\n LOCAL_BUILD_PROGRESS,\n PACKAGE_NAME,\n PROJECT_INFO,\n REMOVE_ADDON,\n START_BUILD,\n STOP_BUILD,\n} from \"./constants\";\nimport { runChromaticBuild, stopChromaticBuild } from \"./runChromaticBuild\";\nimport {\n ConfigInfoPayload,\n ConfigurationUpdate,\n GitInfoPayload,\n LocalBuildProgress,\n ProjectInfoPayload,\n} from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\nimport { updateChromaticConfig } from \"./utils/updateChromaticConfig\";\n\n/**\n * to load the built addon in this test Storybook\n */\nfunction managerEntries(entry: string[] = []) {\n return [...entry, require.resolve(\"./manager.mjs\")];\n}\n\n// Nullify any suggestions that are the same as the defaults, to suggest removal.\n// Drop suggestions for removal that don't actually appear in the current config.\nconst suggestRemovals = (\n config: Configuration,\n defaults: Configuration,\n update: ConfigurationUpdate\n) =>\n Object.fromEntries(\n (Object.entries(update) as [keyof Configuration, Configuration[keyof Configuration]][])\n .map(([key, value]) => [key, value === defaults[key] ? null : value])\n .filter(([key, value]) => value !== null || config[key as keyof Configuration] !== undefined)\n );\n\n// Detect problems in the current configuration and suggest updates.\nconst getConfigInfo = async (\n configuration: Awaited<ReturnType<typeof getConfiguration>>,\n { configDir }: Options\n) => {\n const defaults: Configuration = {\n storybookBaseDir: \".\",\n storybookConfigDir: \".storybook\",\n } as const;\n\n const problems: ConfigurationUpdate = {};\n const suggestions: ConfigurationUpdate = {};\n\n const { repositoryRootDir } = await getGitInfo();\n const baseDir = repositoryRootDir && normalize(relative(repositoryRootDir, process.cwd()));\n if (baseDir !== normalize(configuration.storybookBaseDir ?? \"\")) {\n problems.storybookBaseDir = baseDir;\n }\n\n if (configDir !== normalize(configuration.storybookConfigDir ?? \"\")) {\n problems.storybookConfigDir = normalize(relative(process.cwd(), configDir));\n }\n\n if (!configuration.zip) {\n suggestions.zip = true;\n }\n\n return {\n configuration,\n problems: suggestRemovals(configuration, defaults, problems),\n suggestions: suggestRemovals(configuration, defaults, suggestions),\n };\n};\n\n// Polls for changes to the Git state and invokes the callback when it changes.\n// Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls.\nconst observeGitInfo = async (\n interval: number,\n callback: (info: GitInfo, prevInfo?: GitInfo) => void,\n errorCallback: (e: Error) => void,\n projectId?: string\n) => {\n let prev: GitInfo | undefined;\n let prevError: Error | undefined;\n let timer: NodeJS.Timeout | undefined;\n const act = async () => {\n try {\n const gitInfo = await getGitInfo();\n if (Object.entries(gitInfo).some(([key, value]) => prev?.[key as keyof GitInfo] !== value)) {\n callback(gitInfo, prev);\n }\n prev = gitInfo;\n prevError = undefined;\n timer = setTimeout(act, interval);\n } catch (e: any) {\n errorCallback(e);\n if (projectId && prevError?.message !== e.message) {\n console.error(`Failed to fetch git info, with error:\\n${e}`);\n prev = undefined;\n prevError = e;\n }\n timer = setTimeout(act, interval);\n }\n };\n act();\n\n return () => clearTimeout(timer);\n};\n\nconst watchConfigFile = async (\n configFile: string | undefined,\n onChange: (configuration: Awaited<ReturnType<typeof getConfiguration>>) => Promise<void>\n) => {\n const configuration = await getConfiguration(configFile);\n await onChange(configuration);\n\n if (configuration.configFile) {\n watch(configuration.configFile, async (eventType: string, filename: string | null) => {\n if (filename) await onChange(await getConfiguration(filename));\n });\n }\n};\n\nasync function serverChannel(channel: Channel, options: Options & { configFile?: string }) {\n const { configFile, presets } = options;\n\n // Lazy load the API since we don't need it right away\n const apiPromise = presets.apply<any>(\"experimental_serverAPI\");\n\n // This yields an empty object if the file doesn't exist and no explicit configFile is specified\n const { projectId: initialProjectId } = await getConfiguration(configFile);\n\n const projectInfoState = SharedState.subscribe<ProjectInfoPayload>(PROJECT_INFO, channel);\n projectInfoState.value = initialProjectId ? { projectId: initialProjectId } : {};\n\n let lastProjectId = initialProjectId;\n projectInfoState.on(\"change\", async ({ projectId } = {}) => {\n if (!projectId || projectId === lastProjectId) return;\n lastProjectId = projectId;\n\n const writtenConfigFile = configFile;\n try {\n // No config file may be found (file is about to be created)\n const { configFile: foundConfigFile, ...config } = await getConfiguration(writtenConfigFile);\n const targetConfigFile = foundConfigFile || writtenConfigFile || \"chromatic.config.json\";\n await updateChromaticConfig(targetConfigFile, { ...config, projectId });\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: true,\n configFile: targetConfigFile,\n };\n } catch (err) {\n console.warn(`Failed to update your main configuration:\\n\\n ${err}`);\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: false,\n configFile: writtenConfigFile,\n };\n }\n });\n\n const localBuildProgress = SharedState.subscribe<LocalBuildProgress>(\n LOCAL_BUILD_PROGRESS,\n channel\n );\n\n channel.on(START_BUILD, async ({ accessToken: userToken }) => {\n const { projectId } = projectInfoState.value || {};\n try {\n await runChromaticBuild(localBuildProgress, { configFile, projectId, userToken });\n } catch (e) {\n console.error(`Failed to run Chromatic build, with error:\\n${e}`);\n }\n });\n\n channel.on(STOP_BUILD, stopChromaticBuild);\n channel.on(REMOVE_ADDON, () =>\n apiPromise.then((api) => api.removeAddon(PACKAGE_NAME)).catch((e) => console.error(e))\n );\n\n const configInfoState = SharedState.subscribe<ConfigInfoPayload>(CONFIG_INFO, channel);\n const gitInfoState = SharedState.subscribe<GitInfoPayload>(GIT_INFO, channel);\n const gitInfoError = SharedState.subscribe<Error>(GIT_INFO_ERROR, channel);\n\n observeGitInfo(\n 5000,\n (info) => {\n gitInfoError.value = undefined;\n gitInfoState.value = info;\n },\n (error: Error) => {\n gitInfoError.value = error;\n }\n );\n\n watchConfigFile(configFile, async (configuration) => {\n if (!lastProjectId) return;\n configInfoState.value = await getConfigInfo(configuration, options);\n });\n\n setInterval(() => channel.emit(`${ADDON_ID}/heartbeat`), 1000);\n\n return channel;\n}\n\nconst config = {\n managerEntries,\n experimental_serverChannel: serverChannel,\n env: async (\n env: Record<string, string>,\n { configType }: { configType: \"DEVELOPMENT\" | \"PRODUCTION\" }\n ) => {\n if (configType === \"PRODUCTION\") return env;\n\n return {\n ...env,\n CHROMATIC_BASE_URL,\n };\n },\n};\n\nexport default config;\n","export const {\n CHROMATIC_INDEX_URL,\n CHROMATIC_BASE_URL = CHROMATIC_INDEX_URL || \"https://www.chromatic.com\",\n CHROMATIC_API_URL = `${CHROMATIC_BASE_URL}/api`,\n} = process.env;\n\nexport const PACKAGE_NAME = \"@chromatic-com/storybook\";\n\nexport const ADDON_ID = \"chromaui/addon-visual-tests\";\nexport const PANEL_ID = `${ADDON_ID}/panel`;\nexport const SIDEBAR_TOP_ID = `${ADDON_ID}/sidebarTop`;\nexport const SIDEBAR_BOTTOM_ID = `${ADDON_ID}/sidebarBottom`;\nexport const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`;\nexport const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`;\nexport const CONFIG_INFO = `${ADDON_ID}/configInfo`;\nexport const CONFIG_INFO_DISMISSED = `${ADDON_ID}/configInfoDismissed`;\nexport const GIT_INFO = `${ADDON_ID}/gitInfo`;\nexport const GIT_INFO_ERROR = `${ADDON_ID}/gitInfoError`;\nexport const PROJECT_INFO = `${ADDON_ID}/projectInfo`;\nexport const IS_OUTDATED = `${ADDON_ID}/isOutdated`;\nexport const START_BUILD = `${ADDON_ID}/startBuild`;\nexport const STOP_BUILD = `${ADDON_ID}/stopBuild`;\nexport const LOCAL_BUILD_PROGRESS = `${ADDON_ID}/localBuildProgress`;\n\nexport const REMOVE_ADDON = `${ADDON_ID}/removeAddon`;\n\nexport const CONFIG_OVERRIDES = {\n // Local changes should never be auto-accepted\n autoAcceptChanges: false,\n // Test results must be awaited to get progress updates\n exitOnceUploaded: false,\n // Don't raise any alarms when changes are found\n exitZeroOnChanges: true,\n // We might want to drop this later and instead record \"uncommitted hashes\" on builds\n forceRebuild: true,\n // This should never be set for local builds\n fromCI: false,\n // Builds initiated from the addon are always considered local\n isLocalBuild: true,\n // Never skip local builds\n skip: false,\n // No prompts from the Build proces\n interactive: false,\n};\n\nexport const DOCS_URL = \"https://www.chromatic.com/docs/visual-tests-addon\";\n","/* eslint-disable no-param-reassign */\n// eslint-disable-next-line import/no-unresolved\nimport { Context, InitialContext, Options, run, TaskName } from \"chromatic/node\";\n\nimport {\n BUILD_STEP_CONFIG,\n BUILD_STEP_ORDER,\n hasProgressEvent,\n INITIAL_BUILD_PAYLOAD,\n isKnownStep,\n} from \"./buildSteps\";\nimport { CONFIG_OVERRIDES } from \"./constants\";\nimport { LocalBuildProgress } from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\n\nconst ESTIMATED_PROGRESS_INTERVAL = 2000;\n\nlet abortController: AbortController | undefined;\n\nconst getBuildStepData = (\n task: TaskName,\n previousBuildProgress?: LocalBuildProgress[\"previousBuildProgress\"]\n) => {\n if (!isKnownStep(task)) throw new Error(`Unknown step: ${task}`);\n\n const stepDurations = BUILD_STEP_ORDER.map((step) => {\n const { startedAt, completedAt } = previousBuildProgress?.[step] || {};\n return startedAt && completedAt\n ? completedAt - startedAt\n : BUILD_STEP_CONFIG[step].estimateDuration;\n });\n const totalDuration = stepDurations.reduce((sum, duration) => sum + duration, 0);\n\n const stepIndex = BUILD_STEP_ORDER.indexOf(task);\n const startTime = stepDurations.slice(0, stepIndex).reduce((sum, duration) => sum + duration, 0);\n const endTime = startTime + stepDurations[stepIndex];\n\n const startPercentage = (startTime / totalDuration) * 100;\n const endPercentage = (endTime / totalDuration) * 100;\n return {\n ...BUILD_STEP_CONFIG[task],\n startPercentage,\n endPercentage,\n stepPercentage: endPercentage - startPercentage,\n };\n};\n\nexport const onStartOrProgress =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (ctx: Context, { progress, total }: { progress?: number; total?: number } = {}) => {\n clearTimeout(timeout);\n\n if (!isKnownStep(ctx.task)) return;\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress, previousBuildProgress } =\n localBuildProgress.value;\n\n // Ignore progress events for steps that have already completed\n if (stepProgress[ctx.task]?.completedAt) return;\n\n const { startPercentage, endPercentage, stepPercentage } = getBuildStepData(\n ctx.task,\n previousBuildProgress\n );\n\n let newPercentage = startPercentage;\n if (progress && total) {\n newPercentage += stepPercentage * (progress / total);\n }\n\n // If the step doesn't have a progress event, simulate one by synthetically updating progress\n if (!hasProgressEvent(ctx.task)) {\n const { estimateDuration } = BUILD_STEP_CONFIG[ctx.task];\n const stepIndex = BUILD_STEP_ORDER.indexOf(ctx.task);\n newPercentage =\n Math.max(newPercentage, buildProgressPercentage) +\n (ESTIMATED_PROGRESS_INTERVAL / estimateDuration) * stepPercentage;\n\n timeout = setTimeout(() => {\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n // Intentionally reference the present value here (after timeout)\n const { currentStep } = localBuildProgress.value;\n // Only update if we haven't moved on to a later step\n if (isKnownStep(currentStep) && BUILD_STEP_ORDER.indexOf(currentStep) <= stepIndex) {\n onStartOrProgress(localBuildProgress, timeout)(ctx);\n }\n }, ESTIMATED_PROGRESS_INTERVAL);\n }\n\n stepProgress[ctx.task] = {\n startedAt: Date.now(),\n ...stepProgress[ctx.task],\n ...(progress && total && { numerator: progress, denominator: total }),\n };\n\n localBuildProgress.value = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage: Math.min(newPercentage, endPercentage),\n currentStep: ctx.task,\n stepProgress,\n };\n };\n\nexport const onCompleteOrError =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (\n ctx: Context | InitialContext,\n error?: { formattedError: string; originalError: Error | Error[] }\n ) => {\n clearTimeout(timeout);\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress } = localBuildProgress.value;\n const update = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage,\n stepProgress,\n previousBuildProgress: stepProgress,\n };\n\n if (error) {\n localBuildProgress.value = {\n ...update,\n currentStep: abortController?.signal.aborted ? \"aborted\" : \"error\",\n formattedError: error.formattedError,\n originalError: error.originalError,\n };\n return;\n }\n\n if (ctx.task && isKnownStep(ctx.task)) {\n stepProgress[ctx.task] = {\n ...stepProgress[ctx.task],\n completedAt: Date.now(),\n };\n }\n\n if (ctx.task === \"verify\" && ctx.build?.wasLimited) {\n localBuildProgress.value = {\n ...update,\n currentStep: \"limited\",\n stepProgress,\n errorDetailsUrl: ctx.build?.app.account?.billingUrl,\n };\n }\n\n if (ctx.build && ctx.task === \"snapshot\") {\n localBuildProgress.value = {\n ...update,\n buildProgressPercentage: 100,\n currentStep: \"complete\",\n stepProgress,\n changeCount: ctx.build.changeCount,\n errorCount: ctx.build.errorCount,\n };\n }\n };\n\nexport const runChromaticBuild = async (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n options: Partial<Options>\n) => {\n if (!options.projectId) throw new Error(\"Missing projectId\");\n if (!options.userToken) throw new Error(\"Missing userToken\");\n\n localBuildProgress.value = INITIAL_BUILD_PAYLOAD;\n\n // Timeout is defined here so it's shared between all handlers\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n abortController?.abort();\n abortController = new AbortController();\n\n process.env.SB_TESTBUILD = \"true\";\n\n await run({\n flags: {\n interactive: false,\n },\n options: {\n ...options,\n ...CONFIG_OVERRIDES,\n experimental_onTaskStart: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskProgress: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskComplete: onCompleteOrError(localBuildProgress, timeout),\n experimental_onTaskError: onCompleteOrError(localBuildProgress, timeout),\n experimental_abortSignal: abortController?.signal,\n },\n });\n};\n\nexport const stopChromaticBuild = () => {\n abortController?.abort(new Error(\"Build canceled from Storybook\"));\n};\n","// eslint-disable-next-line import/no-unresolved\nimport { TaskName } from \"chromatic/node\";\nimport { filesize } from \"filesize\";\n\nimport { KnownStep, LocalBuildProgress, StepProgressPayload } from \"./types\";\n\nexport const isKnownStep = (\n taskOrStep: TaskName | LocalBuildProgress[\"currentStep\"]\n): taskOrStep is KnownStep => BUILD_STEP_ORDER.includes(taskOrStep as KnownStep);\n\nexport const hasProgressEvent = (task: TaskName) => [\"upload\", \"snapshot\"].includes(task);\n\n// Note this does not include the \"aborted\", \"complete\" and \"error\" steps\nexport const BUILD_STEP_ORDER: KnownStep[] = [\n \"initialize\",\n \"build\",\n \"upload\",\n \"verify\",\n \"snapshot\",\n];\n\nexport const BUILD_STEP_CONFIG: Record<\n LocalBuildProgress[\"currentStep\"],\n {\n key: LocalBuildProgress[\"currentStep\"];\n emoji: string;\n renderName: () => string;\n renderProgress: (payload: LocalBuildProgress) => string;\n renderComplete: () => string;\n estimateDuration: number;\n }\n> = {\n initialize: {\n key: \"initialize\",\n emoji: \"🚀\",\n renderName: () => `Initialize build`,\n renderProgress: () => `Initializing build...`,\n renderComplete: () => `Initialized`,\n estimateDuration: 2000,\n },\n build: {\n key: \"build\",\n emoji: \"🏗\",\n renderName: () => `Build Storybook`,\n renderProgress: () => `Building your Storybook...`,\n renderComplete: () => `Storybook built`,\n estimateDuration: 20_000,\n },\n upload: {\n key: \"upload\",\n emoji: \"📡\",\n renderName: () => `Publish your Storybook`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.upload;\n if (!denominator || !numerator) return `Uploading files...`;\n const { value: total, exponent } = filesize(denominator, {\n output: \"object\",\n round: 1,\n });\n const { value: progress, symbol } = filesize(numerator, {\n exponent,\n output: \"object\",\n round: 1,\n });\n return `Uploading files (${progress}/${total} ${symbol})...`;\n },\n renderComplete: () => `Publish complete`,\n estimateDuration: 20_000,\n },\n verify: {\n key: \"verify\",\n emoji: \"🔍\",\n renderName: () => `Verify your Storybook`,\n renderProgress: () => `Verifying contents...`,\n renderComplete: () => `Storybook verified`,\n estimateDuration: 20_000,\n },\n snapshot: {\n key: \"snapshot\",\n emoji: \"📸\",\n renderName: () => `Run visual tests`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.snapshot;\n return denominator\n ? `Running visual tests (${numerator}/${denominator})...`\n : `Running visual tests...`;\n },\n renderComplete: () => `Tested your stories`,\n estimateDuration: 90_000,\n },\n\n // These are special steps that are not part of the build process\n aborted: {\n key: \"aborted\",\n emoji: \"✋\",\n renderName: () => `Build canceled`,\n renderProgress: () => `Build canceled`,\n renderComplete: () => `Build canceled`,\n estimateDuration: 0,\n },\n complete: {\n key: \"complete\",\n emoji: \"🎉\",\n renderName: () => `Visual tests completed!`,\n renderProgress: () => `Visual tests completed!`,\n renderComplete: () => `Visual tests completed!`,\n estimateDuration: 0,\n },\n error: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build failed`,\n renderProgress: () => `Build failed`,\n renderComplete: () => `Build failed`,\n estimateDuration: 0,\n },\n limited: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build limited`,\n renderProgress: () => `Build limited`,\n renderComplete: () => `Build limited`,\n estimateDuration: 0,\n },\n};\n\nexport const INITIAL_BUILD_PAYLOAD = {\n buildProgressPercentage: 0,\n currentStep: BUILD_STEP_ORDER[0],\n stepProgress: Object.fromEntries(BUILD_STEP_ORDER.map((step) => [step, {}])) as Record<\n KnownStep,\n StepProgressPayload\n >,\n};\n","import type { Channel } from \"@storybook/channels\";\n\nexport const GET_VALUE = `experimental_useSharedState_getValue`;\nexport const SET_VALUE = `experimental_useSharedState_setValue`;\n\ntype ChannelLike = Pick<Channel, \"emit\" | \"on\" | \"off\">;\n\nconst instances = new Map<string, SharedState>();\n\nexport class SharedState<T = any> {\n channel: ChannelLike;\n\n listeners: ((value: T | undefined) => void)[];\n\n state: { [key: string]: { index: number; value: T | undefined } };\n\n constructor(channel: ChannelLike) {\n this.channel = channel;\n this.listeners = [];\n this.state = {};\n\n this.channel.on(SET_VALUE, (key: string, value: T | undefined, index: number) => {\n if (this.state?.[key]?.index >= index) return;\n this.state[key] = { index, value };\n });\n\n this.channel.on(GET_VALUE, (key: string) => {\n const index = this.state[key]?.index ?? 0;\n const value = this.state[key]?.value;\n this.channel.emit(SET_VALUE, key, value, index);\n });\n }\n\n get(key: string) {\n if (!this.state[key]) this.channel.emit(GET_VALUE, key);\n return this.state[key]?.value;\n }\n\n set(key: string, value: T | undefined) {\n const index = (this.state[key]?.index ?? 0) + 1;\n this.state[key] = { index, value };\n this.channel.emit(SET_VALUE, key, value, index);\n }\n\n static subscribe<T>(key: string, channel: ChannelLike) {\n const sharedState = instances.get(key) || new SharedState(channel);\n\n if (!instances.has(key)) {\n instances.set(key, sharedState);\n sharedState.channel.on(SET_VALUE, (k: string, v: T | undefined) => {\n if (k !== key) return;\n sharedState.listeners.forEach((listener) => listener(v));\n });\n }\n\n return {\n get value(): T | undefined {\n return sharedState.get(key);\n },\n\n set value(newValue: T | undefined) {\n sharedState.set(key, newValue);\n },\n\n on(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n sharedState.listeners.push(callback);\n },\n\n off(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n const index = sharedState.listeners.indexOf(callback);\n if (index >= 0) sharedState.listeners.splice(index, 1);\n },\n };\n }\n}\n","import type { Configuration } from \"chromatic/node\";\nimport { writeFile } from \"jsonfile\";\n\nexport async function updateChromaticConfig(configFile: string, configuration: Configuration) {\n await writeFile(configFile, configuration, { spaces: 2 });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/runChromaticBuild.ts","../src/buildSteps.ts","../src/utils/SharedState.ts","../src/utils/updateChromaticConfig.ts"],"names":["watch","normalize","relative","getConfiguration","getGitInfo","CHROMATIC_INDEX_URL","CHROMATIC_BASE_URL","CHROMATIC_API_URL","PACKAGE_NAME","ADDON_ID","PANEL_ID","SIDEBAR_TOP_ID","SIDEBAR_BOTTOM_ID","ACCESS_TOKEN_KEY","DEV_BUILD_ID_KEY","CONFIG_INFO","CONFIG_INFO_DISMISSED","GIT_INFO","GIT_INFO_ERROR","PROJECT_INFO","IS_OUTDATED","START_BUILD","STOP_BUILD","LOCAL_BUILD_PROGRESS","SELECTED_MODE_NAME","SELECTED_BROWSER_ID","REMOVE_ADDON","CONFIG_OVERRIDES","run","filesize","isKnownStep","taskOrStep","BUILD_STEP_ORDER","hasProgressEvent","task","BUILD_STEP_CONFIG","stepProgress","numerator","denominator","total","exponent","progress","symbol","INITIAL_BUILD_PAYLOAD","step","ESTIMATED_PROGRESS_INTERVAL","abortController","getBuildStepData","previousBuildProgress","stepDurations","startedAt","completedAt","totalDuration","sum","duration","stepIndex","startTime","endTime","startPercentage","endPercentage","onStartOrProgress","localBuildProgress","timeout","ctx","buildProgressPercentage","stepPercentage","newPercentage","estimateDuration","currentStep","onCompleteOrError","error","update","runChromaticBuild","options","stopChromaticBuild","GET_VALUE","SET_VALUE","instances","SharedState","channel","key","value","index","sharedState","k","v","listener","newValue","event","callback","writeFile","updateChromaticConfig","configFile","configuration","managerEntries","entry","__require","suggestRemovals","config","defaults","getConfigInfo","configDir","problems","suggestions","repositoryRootDir","baseDir","observeGitInfo","interval","errorCallback","projectId","prev","prevError","timer","act","gitInfo","e","watchConfigFile","onChange","eventType","filename","serverChannel","presets","apiPromise","initialProjectId","projectInfoState","lastProjectId","writtenConfigFile","foundConfigFile","targetConfigFile","err","userToken","api","configInfoState","gitInfoState","gitInfoError","info","env","configType","src_default"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { watch } from \"node:fs\";\nimport { normalize, relative } from \"node:path\";\n\nimport type { Channel } from \"@storybook/channels\";\nimport type { Options } from \"@storybook/types\";\n// eslint-disable-next-line import/no-unresolved\nimport { type Configuration, getConfiguration, getGitInfo, type GitInfo } from \"chromatic/node\";\n\nimport {\n ADDON_ID,\n CHROMATIC_BASE_URL,\n CONFIG_INFO,\n GIT_INFO,\n GIT_INFO_ERROR,\n LOCAL_BUILD_PROGRESS,\n PACKAGE_NAME,\n PROJECT_INFO,\n REMOVE_ADDON,\n START_BUILD,\n STOP_BUILD,\n} from \"./constants\";\nimport { runChromaticBuild, stopChromaticBuild } from \"./runChromaticBuild\";\nimport {\n ConfigInfoPayload,\n ConfigurationUpdate,\n GitInfoPayload,\n LocalBuildProgress,\n ProjectInfoPayload,\n} from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\nimport { updateChromaticConfig } from \"./utils/updateChromaticConfig\";\n\n/**\n * to load the built addon in this test Storybook\n */\nfunction managerEntries(entry: string[] = []) {\n return [...entry, require.resolve(\"./manager.mjs\")];\n}\n\n// Nullify any suggestions that are the same as the defaults, to suggest removal.\n// Drop suggestions for removal that don't actually appear in the current config.\nconst suggestRemovals = (\n config: Configuration,\n defaults: Configuration,\n update: ConfigurationUpdate\n) =>\n Object.fromEntries(\n (Object.entries(update) as [keyof Configuration, Configuration[keyof Configuration]][])\n .map(([key, value]) => [key, value === defaults[key] ? null : value])\n .filter(([key, value]) => value !== null || config[key as keyof Configuration] !== undefined)\n );\n\n// Detect problems in the current configuration and suggest updates.\nconst getConfigInfo = async (\n configuration: Awaited<ReturnType<typeof getConfiguration>>,\n { configDir }: Options\n) => {\n const defaults: Configuration = {\n storybookBaseDir: \".\",\n storybookConfigDir: \".storybook\",\n } as const;\n\n const problems: ConfigurationUpdate = {};\n const suggestions: ConfigurationUpdate = {};\n\n const { repositoryRootDir } = await getGitInfo();\n const baseDir = repositoryRootDir && normalize(relative(repositoryRootDir, process.cwd()));\n if (baseDir !== normalize(configuration.storybookBaseDir ?? \"\")) {\n problems.storybookBaseDir = baseDir;\n }\n\n if (configDir !== normalize(configuration.storybookConfigDir ?? \"\")) {\n problems.storybookConfigDir = normalize(relative(process.cwd(), configDir));\n }\n\n if (!configuration.zip) {\n suggestions.zip = true;\n }\n\n return {\n configuration,\n problems: suggestRemovals(configuration, defaults, problems),\n suggestions: suggestRemovals(configuration, defaults, suggestions),\n };\n};\n\n// Polls for changes to the Git state and invokes the callback when it changes.\n// Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls.\nconst observeGitInfo = async (\n interval: number,\n callback: (info: GitInfo, prevInfo?: GitInfo) => void,\n errorCallback: (e: Error) => void,\n projectId?: string\n) => {\n let prev: GitInfo | undefined;\n let prevError: Error | undefined;\n let timer: NodeJS.Timeout | undefined;\n const act = async () => {\n try {\n const gitInfo = await getGitInfo();\n if (Object.entries(gitInfo).some(([key, value]) => prev?.[key as keyof GitInfo] !== value)) {\n callback(gitInfo, prev);\n }\n prev = gitInfo;\n prevError = undefined;\n timer = setTimeout(act, interval);\n } catch (e: any) {\n errorCallback(e);\n if (projectId && prevError?.message !== e.message) {\n console.error(`Failed to fetch git info, with error:\\n${e}`);\n prev = undefined;\n prevError = e;\n }\n timer = setTimeout(act, interval);\n }\n };\n act();\n\n return () => clearTimeout(timer);\n};\n\nconst watchConfigFile = async (\n configFile: string | undefined,\n onChange: (configuration: Awaited<ReturnType<typeof getConfiguration>>) => Promise<void>\n) => {\n const configuration = await getConfiguration(configFile);\n await onChange(configuration);\n\n if (configuration.configFile) {\n watch(configuration.configFile, async (eventType: string, filename: string | null) => {\n if (filename) await onChange(await getConfiguration(filename));\n });\n }\n};\n\nasync function serverChannel(channel: Channel, options: Options & { configFile?: string }) {\n const { configFile, presets } = options;\n\n // Lazy load the API since we don't need it right away\n const apiPromise = presets.apply<any>(\"experimental_serverAPI\");\n\n // This yields an empty object if the file doesn't exist and no explicit configFile is specified\n const { projectId: initialProjectId } = await getConfiguration(configFile);\n\n const projectInfoState = SharedState.subscribe<ProjectInfoPayload>(PROJECT_INFO, channel);\n projectInfoState.value = initialProjectId ? { projectId: initialProjectId } : {};\n\n let lastProjectId = initialProjectId;\n projectInfoState.on(\"change\", async ({ projectId } = {}) => {\n if (!projectId || projectId === lastProjectId) return;\n lastProjectId = projectId;\n\n const writtenConfigFile = configFile;\n try {\n // No config file may be found (file is about to be created)\n const { configFile: foundConfigFile, ...config } = await getConfiguration(writtenConfigFile);\n const targetConfigFile = foundConfigFile || writtenConfigFile || \"chromatic.config.json\";\n await updateChromaticConfig(targetConfigFile, { ...config, projectId });\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: true,\n configFile: targetConfigFile,\n };\n } catch (err) {\n console.warn(`Failed to update your main configuration:\\n\\n ${err}`);\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: false,\n configFile: writtenConfigFile,\n };\n }\n });\n\n const localBuildProgress = SharedState.subscribe<LocalBuildProgress>(\n LOCAL_BUILD_PROGRESS,\n channel\n );\n\n channel.on(START_BUILD, async ({ accessToken: userToken }) => {\n const { projectId } = projectInfoState.value || {};\n try {\n await runChromaticBuild(localBuildProgress, { configFile, projectId, userToken });\n } catch (e) {\n console.error(`Failed to run Chromatic build, with error:\\n${e}`);\n }\n });\n\n channel.on(STOP_BUILD, stopChromaticBuild);\n channel.on(REMOVE_ADDON, () =>\n apiPromise.then((api) => api.removeAddon(PACKAGE_NAME)).catch((e) => console.error(e))\n );\n\n const configInfoState = SharedState.subscribe<ConfigInfoPayload>(CONFIG_INFO, channel);\n const gitInfoState = SharedState.subscribe<GitInfoPayload>(GIT_INFO, channel);\n const gitInfoError = SharedState.subscribe<Error>(GIT_INFO_ERROR, channel);\n\n observeGitInfo(\n 5000,\n (info) => {\n gitInfoError.value = undefined;\n gitInfoState.value = info;\n },\n (error: Error) => {\n gitInfoError.value = error;\n }\n );\n\n watchConfigFile(configFile, async (configuration) => {\n if (!lastProjectId) return;\n configInfoState.value = await getConfigInfo(configuration, options);\n });\n\n setInterval(() => channel.emit(`${ADDON_ID}/heartbeat`), 1000);\n\n return channel;\n}\n\nconst config = {\n managerEntries,\n experimental_serverChannel: serverChannel,\n env: async (\n env: Record<string, string>,\n { configType }: { configType: \"DEVELOPMENT\" | \"PRODUCTION\" }\n ) => {\n if (configType === \"PRODUCTION\") return env;\n\n return {\n ...env,\n CHROMATIC_BASE_URL,\n };\n },\n};\n\nexport default config;\n","export const {\n CHROMATIC_INDEX_URL,\n CHROMATIC_BASE_URL = CHROMATIC_INDEX_URL || \"https://www.chromatic.com\",\n CHROMATIC_API_URL = `${CHROMATIC_BASE_URL}/api`,\n} = process.env;\n\nexport const PACKAGE_NAME = \"@chromatic-com/storybook\";\n\nexport const ADDON_ID = \"chromaui/addon-visual-tests\";\nexport const PANEL_ID = `${ADDON_ID}/panel`;\nexport const SIDEBAR_TOP_ID = `${ADDON_ID}/sidebarTop`;\nexport const SIDEBAR_BOTTOM_ID = `${ADDON_ID}/sidebarBottom`;\nexport const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`;\nexport const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`;\nexport const CONFIG_INFO = `${ADDON_ID}/configInfo`;\nexport const CONFIG_INFO_DISMISSED = `${ADDON_ID}/configInfoDismissed`;\nexport const GIT_INFO = `${ADDON_ID}/gitInfo`;\nexport const GIT_INFO_ERROR = `${ADDON_ID}/gitInfoError`;\nexport const PROJECT_INFO = `${ADDON_ID}/projectInfo`;\nexport const IS_OUTDATED = `${ADDON_ID}/isOutdated`;\nexport const START_BUILD = `${ADDON_ID}/startBuild`;\nexport const STOP_BUILD = `${ADDON_ID}/stopBuild`;\nexport const LOCAL_BUILD_PROGRESS = `${ADDON_ID}/localBuildProgress`;\nexport const SELECTED_MODE_NAME = `${ADDON_ID}/selectedModeName`;\nexport const SELECTED_BROWSER_ID = `${ADDON_ID}/selectedBrowserId`;\n\nexport const REMOVE_ADDON = `${ADDON_ID}/removeAddon`;\n\nexport const CONFIG_OVERRIDES = {\n // Local changes should never be auto-accepted\n autoAcceptChanges: false,\n // Test results must be awaited to get progress updates\n exitOnceUploaded: false,\n // Don't raise any alarms when changes are found\n exitZeroOnChanges: true,\n // We might want to drop this later and instead record \"uncommitted hashes\" on builds\n forceRebuild: true,\n // This should never be set for local builds\n fromCI: false,\n // Builds initiated from the addon are always considered local\n isLocalBuild: true,\n // Never skip local builds\n skip: false,\n // No prompts from the Build proces\n interactive: false,\n};\n\nexport const DOCS_URL = \"https://www.chromatic.com/docs/visual-tests-addon\";\n","/* eslint-disable no-param-reassign */\n// eslint-disable-next-line import/no-unresolved\nimport { Context, InitialContext, Options, run, TaskName } from \"chromatic/node\";\n\nimport {\n BUILD_STEP_CONFIG,\n BUILD_STEP_ORDER,\n hasProgressEvent,\n INITIAL_BUILD_PAYLOAD,\n isKnownStep,\n} from \"./buildSteps\";\nimport { CONFIG_OVERRIDES } from \"./constants\";\nimport { LocalBuildProgress } from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\n\nconst ESTIMATED_PROGRESS_INTERVAL = 2000;\n\nlet abortController: AbortController | undefined;\n\nconst getBuildStepData = (\n task: TaskName,\n previousBuildProgress?: LocalBuildProgress[\"previousBuildProgress\"]\n) => {\n if (!isKnownStep(task)) throw new Error(`Unknown step: ${task}`);\n\n const stepDurations = BUILD_STEP_ORDER.map((step) => {\n const { startedAt, completedAt } = previousBuildProgress?.[step] || {};\n return startedAt && completedAt\n ? completedAt - startedAt\n : BUILD_STEP_CONFIG[step].estimateDuration;\n });\n const totalDuration = stepDurations.reduce((sum, duration) => sum + duration, 0);\n\n const stepIndex = BUILD_STEP_ORDER.indexOf(task);\n const startTime = stepDurations.slice(0, stepIndex).reduce((sum, duration) => sum + duration, 0);\n const endTime = startTime + stepDurations[stepIndex];\n\n const startPercentage = (startTime / totalDuration) * 100;\n const endPercentage = (endTime / totalDuration) * 100;\n return {\n ...BUILD_STEP_CONFIG[task],\n startPercentage,\n endPercentage,\n stepPercentage: endPercentage - startPercentage,\n };\n};\n\nexport const onStartOrProgress =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (ctx: Context, { progress, total }: { progress?: number; total?: number } = {}) => {\n clearTimeout(timeout);\n\n if (!isKnownStep(ctx.task)) return;\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress, previousBuildProgress } =\n localBuildProgress.value;\n\n // Ignore progress events for steps that have already completed\n if (stepProgress[ctx.task]?.completedAt) return;\n\n const { startPercentage, endPercentage, stepPercentage } = getBuildStepData(\n ctx.task,\n previousBuildProgress\n );\n\n let newPercentage = startPercentage;\n if (progress && total) {\n newPercentage += stepPercentage * (progress / total);\n }\n\n // If the step doesn't have a progress event, simulate one by synthetically updating progress\n if (!hasProgressEvent(ctx.task)) {\n const { estimateDuration } = BUILD_STEP_CONFIG[ctx.task];\n const stepIndex = BUILD_STEP_ORDER.indexOf(ctx.task);\n newPercentage =\n Math.max(newPercentage, buildProgressPercentage) +\n (ESTIMATED_PROGRESS_INTERVAL / estimateDuration) * stepPercentage;\n\n timeout = setTimeout(() => {\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n // Intentionally reference the present value here (after timeout)\n const { currentStep } = localBuildProgress.value;\n // Only update if we haven't moved on to a later step\n if (isKnownStep(currentStep) && BUILD_STEP_ORDER.indexOf(currentStep) <= stepIndex) {\n onStartOrProgress(localBuildProgress, timeout)(ctx);\n }\n }, ESTIMATED_PROGRESS_INTERVAL);\n }\n\n stepProgress[ctx.task] = {\n startedAt: Date.now(),\n ...stepProgress[ctx.task],\n ...(progress && total && { numerator: progress, denominator: total }),\n };\n\n localBuildProgress.value = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage: Math.min(newPercentage, endPercentage),\n currentStep: ctx.task,\n stepProgress,\n };\n };\n\nexport const onCompleteOrError =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (\n ctx: Context | InitialContext,\n error?: { formattedError: string; originalError: Error | Error[] }\n ) => {\n clearTimeout(timeout);\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress } = localBuildProgress.value;\n const update = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage,\n stepProgress,\n previousBuildProgress: stepProgress,\n };\n\n if (error) {\n localBuildProgress.value = {\n ...update,\n currentStep: abortController?.signal.aborted ? \"aborted\" : \"error\",\n formattedError: error.formattedError,\n originalError: error.originalError,\n };\n return;\n }\n\n if (ctx.task && isKnownStep(ctx.task)) {\n stepProgress[ctx.task] = {\n ...stepProgress[ctx.task],\n completedAt: Date.now(),\n };\n }\n\n if (ctx.task === \"verify\" && ctx.build?.wasLimited) {\n localBuildProgress.value = {\n ...update,\n currentStep: \"limited\",\n stepProgress,\n errorDetailsUrl: ctx.build?.app.account?.billingUrl,\n };\n }\n\n if (ctx.build && ctx.task === \"snapshot\") {\n localBuildProgress.value = {\n ...update,\n buildProgressPercentage: 100,\n currentStep: \"complete\",\n stepProgress,\n changeCount: ctx.build.changeCount,\n errorCount: ctx.build.errorCount,\n };\n }\n };\n\nexport const runChromaticBuild = async (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n options: Partial<Options>\n) => {\n if (!options.projectId) throw new Error(\"Missing projectId\");\n if (!options.userToken) throw new Error(\"Missing userToken\");\n\n localBuildProgress.value = INITIAL_BUILD_PAYLOAD;\n\n // Timeout is defined here so it's shared between all handlers\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n abortController?.abort();\n abortController = new AbortController();\n\n process.env.SB_TESTBUILD = \"true\";\n\n await run({\n flags: {\n interactive: false,\n },\n options: {\n ...options,\n ...CONFIG_OVERRIDES,\n experimental_onTaskStart: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskProgress: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskComplete: onCompleteOrError(localBuildProgress, timeout),\n experimental_onTaskError: onCompleteOrError(localBuildProgress, timeout),\n experimental_abortSignal: abortController?.signal,\n },\n });\n};\n\nexport const stopChromaticBuild = () => {\n abortController?.abort(new Error(\"Build canceled from Storybook\"));\n};\n","// eslint-disable-next-line import/no-unresolved\nimport { TaskName } from \"chromatic/node\";\nimport { filesize } from \"filesize\";\n\nimport { KnownStep, LocalBuildProgress, StepProgressPayload } from \"./types\";\n\nexport const isKnownStep = (\n taskOrStep: TaskName | LocalBuildProgress[\"currentStep\"]\n): taskOrStep is KnownStep => BUILD_STEP_ORDER.includes(taskOrStep as KnownStep);\n\nexport const hasProgressEvent = (task: TaskName) => [\"upload\", \"snapshot\"].includes(task);\n\n// Note this does not include the \"aborted\", \"complete\" and \"error\" steps\nexport const BUILD_STEP_ORDER: KnownStep[] = [\n \"initialize\",\n \"build\",\n \"upload\",\n \"verify\",\n \"snapshot\",\n];\n\nexport const BUILD_STEP_CONFIG: Record<\n LocalBuildProgress[\"currentStep\"],\n {\n key: LocalBuildProgress[\"currentStep\"];\n emoji: string;\n renderName: () => string;\n renderProgress: (payload: LocalBuildProgress) => string;\n renderComplete: () => string;\n estimateDuration: number;\n }\n> = {\n initialize: {\n key: \"initialize\",\n emoji: \"🚀\",\n renderName: () => `Initialize build`,\n renderProgress: () => `Initializing build...`,\n renderComplete: () => `Initialized`,\n estimateDuration: 2000,\n },\n build: {\n key: \"build\",\n emoji: \"🏗\",\n renderName: () => `Build Storybook`,\n renderProgress: () => `Building your Storybook...`,\n renderComplete: () => `Storybook built`,\n estimateDuration: 20_000,\n },\n upload: {\n key: \"upload\",\n emoji: \"📡\",\n renderName: () => `Publish your Storybook`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.upload;\n if (!denominator || !numerator) return `Uploading files...`;\n const { value: total, exponent } = filesize(denominator, {\n output: \"object\",\n round: 1,\n });\n const { value: progress, symbol } = filesize(numerator, {\n exponent,\n output: \"object\",\n round: 1,\n });\n return `Uploading files (${progress}/${total} ${symbol})...`;\n },\n renderComplete: () => `Publish complete`,\n estimateDuration: 20_000,\n },\n verify: {\n key: \"verify\",\n emoji: \"🔍\",\n renderName: () => `Verify your Storybook`,\n renderProgress: () => `Verifying contents...`,\n renderComplete: () => `Storybook verified`,\n estimateDuration: 20_000,\n },\n snapshot: {\n key: \"snapshot\",\n emoji: \"📸\",\n renderName: () => `Run visual tests`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.snapshot;\n return denominator\n ? `Running visual tests (${numerator}/${denominator})...`\n : `Running visual tests...`;\n },\n renderComplete: () => `Tested your stories`,\n estimateDuration: 90_000,\n },\n\n // These are special steps that are not part of the build process\n aborted: {\n key: \"aborted\",\n emoji: \"✋\",\n renderName: () => `Build canceled`,\n renderProgress: () => `Build canceled`,\n renderComplete: () => `Build canceled`,\n estimateDuration: 0,\n },\n complete: {\n key: \"complete\",\n emoji: \"🎉\",\n renderName: () => `Visual tests completed!`,\n renderProgress: () => `Visual tests completed!`,\n renderComplete: () => `Visual tests completed!`,\n estimateDuration: 0,\n },\n error: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build failed`,\n renderProgress: () => `Build failed`,\n renderComplete: () => `Build failed`,\n estimateDuration: 0,\n },\n limited: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build limited`,\n renderProgress: () => `Build limited`,\n renderComplete: () => `Build limited`,\n estimateDuration: 0,\n },\n};\n\nexport const INITIAL_BUILD_PAYLOAD = {\n buildProgressPercentage: 0,\n currentStep: BUILD_STEP_ORDER[0],\n stepProgress: Object.fromEntries(BUILD_STEP_ORDER.map((step) => [step, {}])) as Record<\n KnownStep,\n StepProgressPayload\n >,\n};\n","import type { Channel } from \"@storybook/channels\";\n\nexport const GET_VALUE = `experimental_useSharedState_getValue`;\nexport const SET_VALUE = `experimental_useSharedState_setValue`;\n\ntype ChannelLike = Pick<Channel, \"emit\" | \"on\" | \"off\">;\n\nconst instances = new Map<string, SharedState>();\n\nexport class SharedState<T = any> {\n channel: ChannelLike;\n\n listeners: ((value: T | undefined) => void)[];\n\n state: { [key: string]: { index: number; value: T | undefined } };\n\n constructor(channel: ChannelLike) {\n this.channel = channel;\n this.listeners = [];\n this.state = {};\n\n this.channel.on(SET_VALUE, (key: string, value: T | undefined, index: number) => {\n if (this.state?.[key]?.index >= index) return;\n this.state[key] = { index, value };\n });\n\n this.channel.on(GET_VALUE, (key: string) => {\n const index = this.state[key]?.index ?? 0;\n const value = this.state[key]?.value;\n this.channel.emit(SET_VALUE, key, value, index);\n });\n }\n\n get(key: string) {\n if (!this.state[key]) this.channel.emit(GET_VALUE, key);\n return this.state[key]?.value;\n }\n\n set(key: string, value: T | undefined) {\n const index = (this.state[key]?.index ?? 0) + 1;\n this.state[key] = { index, value };\n this.channel.emit(SET_VALUE, key, value, index);\n }\n\n static subscribe<T>(key: string, channel: ChannelLike) {\n const sharedState = instances.get(key) || new SharedState(channel);\n\n if (!instances.has(key)) {\n instances.set(key, sharedState);\n sharedState.channel.on(SET_VALUE, (k: string, v: T | undefined) => {\n if (k !== key) return;\n sharedState.listeners.forEach((listener) => listener(v));\n });\n }\n\n return {\n get value(): T | undefined {\n return sharedState.get(key);\n },\n\n set value(newValue: T | undefined) {\n sharedState.set(key, newValue);\n },\n\n on(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n sharedState.listeners.push(callback);\n },\n\n off(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n const index = sharedState.listeners.indexOf(callback);\n if (index >= 0) sharedState.listeners.splice(index, 1);\n },\n };\n }\n}\n","import type { Configuration } from \"chromatic/node\";\nimport { writeFile } from \"jsonfile\";\n\nexport async function updateChromaticConfig(configFile: string, configuration: Configuration) {\n await writeFile(configFile, configuration, { spaces: 2 });\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -4,12 +4,12 @@ import { getConfiguration, run, getGitInfo } from 'chromatic/node';
|
|
|
4
4
|
import { filesize } from 'filesize';
|
|
5
5
|
import { writeFile } from 'jsonfile';
|
|
6
6
|
|
|
7
|
-
var
|
|
8
|
-
${
|
|
7
|
+
var v=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(r,e)=>(typeof require<"u"?require:r)[e]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var {CHROMATIC_INDEX_URL:Z,CHROMATIC_BASE_URL:E=Z||"https://www.chromatic.com",CHROMATIC_API_URL:le=`${E}/api`}=process.env,w="@chromatic-com/storybook",a="chromaui/addon-visual-tests",R=`${a}/configInfo`,B=`${a}/gitInfo`,k=`${a}/gitInfoError`,L=`${a}/projectInfo`,A=`${a}/startBuild`,N=`${a}/stopBuild`,x=`${a}/localBuildProgress`,U=`${a}/removeAddon`,F={autoAcceptChanges:!1,exitOnceUploaded:!1,exitZeroOnChanges:!0,forceRebuild:!0,fromCI:!1,isLocalBuild:!0,skip:!1,interactive:!1};var h=t=>I.includes(t),j=t=>["upload","snapshot"].includes(t),I=["initialize","build","upload","verify","snapshot"],y={initialize:{key:"initialize",emoji:"\u{1F680}",renderName:()=>"Initialize build",renderProgress:()=>"Initializing build...",renderComplete:()=>"Initialized",estimateDuration:2e3},build:{key:"build",emoji:"\u{1F3D7}",renderName:()=>"Build Storybook",renderProgress:()=>"Building your Storybook...",renderComplete:()=>"Storybook built",estimateDuration:2e4},upload:{key:"upload",emoji:"\u{1F4E1}",renderName:()=>"Publish your Storybook",renderProgress:({stepProgress:t})=>{let{numerator:r,denominator:e}=t.upload;if(!e||!r)return "Uploading files...";let{value:o,exponent:n}=filesize(e,{output:"object",round:1}),{value:s,symbol:i}=filesize(r,{exponent:n,output:"object",round:1});return `Uploading files (${s}/${o} ${i})...`},renderComplete:()=>"Publish complete",estimateDuration:2e4},verify:{key:"verify",emoji:"\u{1F50D}",renderName:()=>"Verify your Storybook",renderProgress:()=>"Verifying contents...",renderComplete:()=>"Storybook verified",estimateDuration:2e4},snapshot:{key:"snapshot",emoji:"\u{1F4F8}",renderName:()=>"Run visual tests",renderProgress:({stepProgress:t})=>{let{numerator:r,denominator:e}=t.snapshot;return e?`Running visual tests (${r}/${e})...`:"Running visual tests..."},renderComplete:()=>"Tested your stories",estimateDuration:9e4},aborted:{key:"aborted",emoji:"\u270B",renderName:()=>"Build canceled",renderProgress:()=>"Build canceled",renderComplete:()=>"Build canceled",estimateDuration:0},complete:{key:"complete",emoji:"\u{1F389}",renderName:()=>"Visual tests completed!",renderProgress:()=>"Visual tests completed!",renderComplete:()=>"Visual tests completed!",estimateDuration:0},error:{key:"error",emoji:"\u{1F6A8}",renderName:()=>"Build failed",renderProgress:()=>"Build failed",renderComplete:()=>"Build failed",estimateDuration:0},limited:{key:"error",emoji:"\u{1F6A8}",renderName:()=>"Build limited",renderProgress:()=>"Build limited",renderComplete:()=>"Build limited",estimateDuration:0}},G={buildProgressPercentage:0,currentStep:I[0],stepProgress:Object.fromEntries(I.map(t=>[t,{}]))};var M=2e3,b,ee=(t,r)=>{if(!h(t))throw new Error(`Unknown step: ${t}`);let e=I.map(p=>{let{startedAt:l,completedAt:f}=r?.[p]||{};return l&&f?f-l:y[p].estimateDuration}),o=e.reduce((p,l)=>p+l,0),n=I.indexOf(t),s=e.slice(0,n).reduce((p,l)=>p+l,0),i=s+e[n],c=s/o*100,d=i/o*100;return {...y[t],startPercentage:c,endPercentage:d,stepPercentage:d-c}},S=(t,r)=>(e,{progress:o,total:n}={})=>{if(clearTimeout(r),!h(e.task))return;if(!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{buildProgressPercentage:s,stepProgress:i,previousBuildProgress:c}=t.value;if(i[e.task]?.completedAt)return;let{startPercentage:d,endPercentage:p,stepPercentage:l}=ee(e.task,c),f=d;if(o&&n&&(f+=l*(o/n)),!j(e.task)){let{estimateDuration:u}=y[e.task],C=I.indexOf(e.task);f=Math.max(f,s)+M/u*l,r=setTimeout(()=>{if(!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{currentStep:g}=t.value;h(g)&&I.indexOf(g)<=C&&S(t,r)(e);},M);}i[e.task]={startedAt:Date.now(),...i[e.task],...o&&n&&{numerator:o,denominator:n}},t.value={buildId:e.announcedBuild?.id,branch:e.git?.branch,buildProgressPercentage:Math.min(f,p),currentStep:e.task,stepProgress:i};},V=(t,r)=>(e,o)=>{if(clearTimeout(r),!t.value)throw new Error("Unexpected missing value for localBuildProgress");let{buildProgressPercentage:n,stepProgress:s}=t.value,i={buildId:e.announcedBuild?.id,branch:e.git?.branch,buildProgressPercentage:n,stepProgress:s,previousBuildProgress:s};if(o){t.value={...i,currentStep:b?.signal.aborted?"aborted":"error",formattedError:o.formattedError,originalError:o.originalError};return}e.task&&h(e.task)&&(s[e.task]={...s[e.task],completedAt:Date.now()}),e.task==="verify"&&e.build?.wasLimited&&(t.value={...i,currentStep:"limited",stepProgress:s,errorDetailsUrl:e.build?.app.account?.billingUrl}),e.build&&e.task==="snapshot"&&(t.value={...i,buildProgressPercentage:100,currentStep:"complete",stepProgress:s,changeCount:e.build.changeCount,errorCount:e.build.errorCount});},K=async(t,r)=>{if(!r.projectId)throw new Error("Missing projectId");if(!r.userToken)throw new Error("Missing userToken");t.value=G;let e;b?.abort(),b=new AbortController,process.env.SB_TESTBUILD="true",await run({flags:{interactive:!1},options:{...r,...F,experimental_onTaskStart:S(t,e),experimental_onTaskProgress:S(t,e),experimental_onTaskComplete:V(t,e),experimental_onTaskError:V(t,e),experimental_abortSignal:b?.signal}});},z=()=>{b?.abort(new Error("Build canceled from Storybook"));};var H="experimental_useSharedState_getValue",T="experimental_useSharedState_setValue",D=new Map,m=class{constructor(r){this.channel=r,this.listeners=[],this.state={},this.channel.on(T,(e,o,n)=>{this.state?.[e]?.index>=n||(this.state[e]={index:n,value:o});}),this.channel.on(H,e=>{let o=this.state[e]?.index??0,n=this.state[e]?.value;this.channel.emit(T,e,n,o);});}get(r){return this.state[r]||this.channel.emit(H,r),this.state[r]?.value}set(r,e){let o=(this.state[r]?.index??0)+1;this.state[r]={index:o,value:e},this.channel.emit(T,r,e,o);}static subscribe(r,e){let o=D.get(r)||new m(e);return D.has(r)||(D.set(r,o),o.channel.on(T,(n,s)=>{n===r&&o.listeners.forEach(i=>i(s));})),{get value(){return o.get(r)},set value(n){o.set(r,n);},on(n,s){if(n!=="change")throw new Error("unsupported event");o.listeners.push(s);},off(n,s){if(n!=="change")throw new Error("unsupported event");let i=o.listeners.indexOf(s);i>=0&&o.listeners.splice(i,1);}}}};async function Y(t,r){await writeFile(t,r,{spaces:2});}function oe(t=[]){return [...t,v.resolve("./manager.mjs")]}var q=(t,r,e)=>Object.fromEntries(Object.entries(e).map(([o,n])=>[o,n===r[o]?null:n]).filter(([o,n])=>n!==null||t[o]!==void 0)),ne=async(t,{configDir:r})=>{let e={storybookBaseDir:".",storybookConfigDir:".storybook"},o={},n={},{repositoryRootDir:s}=await getGitInfo(),i=s&&normalize(relative(s,process.cwd()));return i!==normalize(t.storybookBaseDir??"")&&(o.storybookBaseDir=i),r!==normalize(t.storybookConfigDir??"")&&(o.storybookConfigDir=normalize(relative(process.cwd(),r))),t.zip||(n.zip=!0),{configuration:t,problems:q(t,e,o),suggestions:q(t,e,n)}},ie=async(t,r,e,o)=>{let n,s,i,c=async()=>{try{let d=await getGitInfo();Object.entries(d).some(([p,l])=>n?.[p]!==l)&&r(d,n),n=d,s=void 0,i=setTimeout(c,t);}catch(d){e(d),o&&s?.message!==d.message&&(console.error(`Failed to fetch git info, with error:
|
|
8
|
+
${d}`),n=void 0,s=d),i=setTimeout(c,t);}};return c(),()=>clearTimeout(i)},se=async(t,r)=>{let e=await getConfiguration(t);await r(e),e.configFile&&watch(e.configFile,async(o,n)=>{n&&await r(await getConfiguration(n));});};async function ae(t,r){let{configFile:e,presets:o}=r,n=o.apply("experimental_serverAPI"),{projectId:s}=await getConfiguration(e),i=m.subscribe(L,t);i.value=s?{projectId:s}:{};let c=s;i.on("change",async({projectId:u}={})=>{if(!u||u===c)return;c=u;let C=e;try{let{configFile:g,...X}=await getConfiguration(C),O=g||C||"chromatic.config.json";await Y(O,{...X,projectId:u}),i.value={...i.value,written:!0,configFile:O};}catch(g){console.warn(`Failed to update your main configuration:
|
|
9
9
|
|
|
10
|
-
${g}`),i.value={...i.value,written:!1,configFile:C};}});let
|
|
11
|
-
${g}`);}}),t.on(N,z),t.on(U,()=>n.then(
|
|
10
|
+
${g}`),i.value={...i.value,written:!1,configFile:C};}});let d=m.subscribe(x,t);t.on(A,async({accessToken:u})=>{let{projectId:C}=i.value||{};try{await K(d,{configFile:e,projectId:C,userToken:u});}catch(g){console.error(`Failed to run Chromatic build, with error:
|
|
11
|
+
${g}`);}}),t.on(N,z),t.on(U,()=>n.then(u=>u.removeAddon(w)).catch(u=>console.error(u)));let p=m.subscribe(R,t),l=m.subscribe(B,t),f=m.subscribe(k,t);return ie(5e3,u=>{f.value=void 0,l.value=u;},u=>{f.value=u;}),se(e,async u=>{c&&(p.value=await ne(u,r));}),setInterval(()=>t.emit(`${a}/heartbeat`),1e3),t}var ue={managerEntries:oe,experimental_serverChannel:ae,env:async(t,{configType:r})=>r==="PRODUCTION"?t:{...t,CHROMATIC_BASE_URL:E}},Ge=ue;
|
|
12
12
|
|
|
13
|
-
export {
|
|
13
|
+
export { Ge as default };
|
|
14
14
|
//# sourceMappingURL=out.js.map
|
|
15
15
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/runChromaticBuild.ts","../src/buildSteps.ts","../src/utils/SharedState.ts","../src/utils/updateChromaticConfig.ts"],"names":["watch","normalize","relative","getConfiguration","getGitInfo","CHROMATIC_INDEX_URL","CHROMATIC_BASE_URL","CHROMATIC_API_URL","PACKAGE_NAME","ADDON_ID","PANEL_ID","SIDEBAR_TOP_ID","SIDEBAR_BOTTOM_ID","ACCESS_TOKEN_KEY","DEV_BUILD_ID_KEY","CONFIG_INFO","CONFIG_INFO_DISMISSED","GIT_INFO","GIT_INFO_ERROR","PROJECT_INFO","IS_OUTDATED","START_BUILD","STOP_BUILD","LOCAL_BUILD_PROGRESS","REMOVE_ADDON","CONFIG_OVERRIDES","run","filesize","isKnownStep","taskOrStep","BUILD_STEP_ORDER","hasProgressEvent","task","BUILD_STEP_CONFIG","stepProgress","numerator","denominator","total","exponent","progress","symbol","INITIAL_BUILD_PAYLOAD","step","ESTIMATED_PROGRESS_INTERVAL","abortController","getBuildStepData","previousBuildProgress","stepDurations","startedAt","completedAt","totalDuration","sum","duration","stepIndex","startTime","endTime","startPercentage","endPercentage","onStartOrProgress","localBuildProgress","timeout","ctx","buildProgressPercentage","stepPercentage","newPercentage","estimateDuration","currentStep","onCompleteOrError","error","update","runChromaticBuild","options","stopChromaticBuild","GET_VALUE","SET_VALUE","instances","SharedState","channel","key","value","index","sharedState","k","v","listener","newValue","event","callback","writeFile","updateChromaticConfig","configFile","configuration","managerEntries","entry","__require","suggestRemovals","config","defaults","getConfigInfo","configDir","problems","suggestions","repositoryRootDir","baseDir","observeGitInfo","interval","errorCallback","projectId","prev","prevError","timer","act","gitInfo","e","watchConfigFile","onChange","eventType","filename","serverChannel","presets","apiPromise","initialProjectId","projectInfoState","lastProjectId","writtenConfigFile","foundConfigFile","targetConfigFile","err","userToken","api","configInfoState","gitInfoState","gitInfoError","info","env","configType","src_default"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { watch } from \"node:fs\";\nimport { normalize, relative } from \"node:path\";\n\nimport type { Channel } from \"@storybook/channels\";\nimport type { Options } from \"@storybook/types\";\n// eslint-disable-next-line import/no-unresolved\nimport { type Configuration, getConfiguration, getGitInfo, type GitInfo } from \"chromatic/node\";\n\nimport {\n ADDON_ID,\n CHROMATIC_BASE_URL,\n CONFIG_INFO,\n GIT_INFO,\n GIT_INFO_ERROR,\n LOCAL_BUILD_PROGRESS,\n PACKAGE_NAME,\n PROJECT_INFO,\n REMOVE_ADDON,\n START_BUILD,\n STOP_BUILD,\n} from \"./constants\";\nimport { runChromaticBuild, stopChromaticBuild } from \"./runChromaticBuild\";\nimport {\n ConfigInfoPayload,\n ConfigurationUpdate,\n GitInfoPayload,\n LocalBuildProgress,\n ProjectInfoPayload,\n} from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\nimport { updateChromaticConfig } from \"./utils/updateChromaticConfig\";\n\n/**\n * to load the built addon in this test Storybook\n */\nfunction managerEntries(entry: string[] = []) {\n return [...entry, require.resolve(\"./manager.mjs\")];\n}\n\n// Nullify any suggestions that are the same as the defaults, to suggest removal.\n// Drop suggestions for removal that don't actually appear in the current config.\nconst suggestRemovals = (\n config: Configuration,\n defaults: Configuration,\n update: ConfigurationUpdate\n) =>\n Object.fromEntries(\n (Object.entries(update) as [keyof Configuration, Configuration[keyof Configuration]][])\n .map(([key, value]) => [key, value === defaults[key] ? null : value])\n .filter(([key, value]) => value !== null || config[key as keyof Configuration] !== undefined)\n );\n\n// Detect problems in the current configuration and suggest updates.\nconst getConfigInfo = async (\n configuration: Awaited<ReturnType<typeof getConfiguration>>,\n { configDir }: Options\n) => {\n const defaults: Configuration = {\n storybookBaseDir: \".\",\n storybookConfigDir: \".storybook\",\n } as const;\n\n const problems: ConfigurationUpdate = {};\n const suggestions: ConfigurationUpdate = {};\n\n const { repositoryRootDir } = await getGitInfo();\n const baseDir = repositoryRootDir && normalize(relative(repositoryRootDir, process.cwd()));\n if (baseDir !== normalize(configuration.storybookBaseDir ?? \"\")) {\n problems.storybookBaseDir = baseDir;\n }\n\n if (configDir !== normalize(configuration.storybookConfigDir ?? \"\")) {\n problems.storybookConfigDir = normalize(relative(process.cwd(), configDir));\n }\n\n if (!configuration.zip) {\n suggestions.zip = true;\n }\n\n return {\n configuration,\n problems: suggestRemovals(configuration, defaults, problems),\n suggestions: suggestRemovals(configuration, defaults, suggestions),\n };\n};\n\n// Polls for changes to the Git state and invokes the callback when it changes.\n// Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls.\nconst observeGitInfo = async (\n interval: number,\n callback: (info: GitInfo, prevInfo?: GitInfo) => void,\n errorCallback: (e: Error) => void,\n projectId?: string\n) => {\n let prev: GitInfo | undefined;\n let prevError: Error | undefined;\n let timer: NodeJS.Timeout | undefined;\n const act = async () => {\n try {\n const gitInfo = await getGitInfo();\n if (Object.entries(gitInfo).some(([key, value]) => prev?.[key as keyof GitInfo] !== value)) {\n callback(gitInfo, prev);\n }\n prev = gitInfo;\n prevError = undefined;\n timer = setTimeout(act, interval);\n } catch (e: any) {\n errorCallback(e);\n if (projectId && prevError?.message !== e.message) {\n console.error(`Failed to fetch git info, with error:\\n${e}`);\n prev = undefined;\n prevError = e;\n }\n timer = setTimeout(act, interval);\n }\n };\n act();\n\n return () => clearTimeout(timer);\n};\n\nconst watchConfigFile = async (\n configFile: string | undefined,\n onChange: (configuration: Awaited<ReturnType<typeof getConfiguration>>) => Promise<void>\n) => {\n const configuration = await getConfiguration(configFile);\n await onChange(configuration);\n\n if (configuration.configFile) {\n watch(configuration.configFile, async (eventType: string, filename: string | null) => {\n if (filename) await onChange(await getConfiguration(filename));\n });\n }\n};\n\nasync function serverChannel(channel: Channel, options: Options & { configFile?: string }) {\n const { configFile, presets } = options;\n\n // Lazy load the API since we don't need it right away\n const apiPromise = presets.apply<any>(\"experimental_serverAPI\");\n\n // This yields an empty object if the file doesn't exist and no explicit configFile is specified\n const { projectId: initialProjectId } = await getConfiguration(configFile);\n\n const projectInfoState = SharedState.subscribe<ProjectInfoPayload>(PROJECT_INFO, channel);\n projectInfoState.value = initialProjectId ? { projectId: initialProjectId } : {};\n\n let lastProjectId = initialProjectId;\n projectInfoState.on(\"change\", async ({ projectId } = {}) => {\n if (!projectId || projectId === lastProjectId) return;\n lastProjectId = projectId;\n\n const writtenConfigFile = configFile;\n try {\n // No config file may be found (file is about to be created)\n const { configFile: foundConfigFile, ...config } = await getConfiguration(writtenConfigFile);\n const targetConfigFile = foundConfigFile || writtenConfigFile || \"chromatic.config.json\";\n await updateChromaticConfig(targetConfigFile, { ...config, projectId });\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: true,\n configFile: targetConfigFile,\n };\n } catch (err) {\n console.warn(`Failed to update your main configuration:\\n\\n ${err}`);\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: false,\n configFile: writtenConfigFile,\n };\n }\n });\n\n const localBuildProgress = SharedState.subscribe<LocalBuildProgress>(\n LOCAL_BUILD_PROGRESS,\n channel\n );\n\n channel.on(START_BUILD, async ({ accessToken: userToken }) => {\n const { projectId } = projectInfoState.value || {};\n try {\n await runChromaticBuild(localBuildProgress, { configFile, projectId, userToken });\n } catch (e) {\n console.error(`Failed to run Chromatic build, with error:\\n${e}`);\n }\n });\n\n channel.on(STOP_BUILD, stopChromaticBuild);\n channel.on(REMOVE_ADDON, () =>\n apiPromise.then((api) => api.removeAddon(PACKAGE_NAME)).catch((e) => console.error(e))\n );\n\n const configInfoState = SharedState.subscribe<ConfigInfoPayload>(CONFIG_INFO, channel);\n const gitInfoState = SharedState.subscribe<GitInfoPayload>(GIT_INFO, channel);\n const gitInfoError = SharedState.subscribe<Error>(GIT_INFO_ERROR, channel);\n\n observeGitInfo(\n 5000,\n (info) => {\n gitInfoError.value = undefined;\n gitInfoState.value = info;\n },\n (error: Error) => {\n gitInfoError.value = error;\n }\n );\n\n watchConfigFile(configFile, async (configuration) => {\n if (!lastProjectId) return;\n configInfoState.value = await getConfigInfo(configuration, options);\n });\n\n setInterval(() => channel.emit(`${ADDON_ID}/heartbeat`), 1000);\n\n return channel;\n}\n\nconst config = {\n managerEntries,\n experimental_serverChannel: serverChannel,\n env: async (\n env: Record<string, string>,\n { configType }: { configType: \"DEVELOPMENT\" | \"PRODUCTION\" }\n ) => {\n if (configType === \"PRODUCTION\") return env;\n\n return {\n ...env,\n CHROMATIC_BASE_URL,\n };\n },\n};\n\nexport default config;\n","export const {\n CHROMATIC_INDEX_URL,\n CHROMATIC_BASE_URL = CHROMATIC_INDEX_URL || \"https://www.chromatic.com\",\n CHROMATIC_API_URL = `${CHROMATIC_BASE_URL}/api`,\n} = process.env;\n\nexport const PACKAGE_NAME = \"@chromatic-com/storybook\";\n\nexport const ADDON_ID = \"chromaui/addon-visual-tests\";\nexport const PANEL_ID = `${ADDON_ID}/panel`;\nexport const SIDEBAR_TOP_ID = `${ADDON_ID}/sidebarTop`;\nexport const SIDEBAR_BOTTOM_ID = `${ADDON_ID}/sidebarBottom`;\nexport const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`;\nexport const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`;\nexport const CONFIG_INFO = `${ADDON_ID}/configInfo`;\nexport const CONFIG_INFO_DISMISSED = `${ADDON_ID}/configInfoDismissed`;\nexport const GIT_INFO = `${ADDON_ID}/gitInfo`;\nexport const GIT_INFO_ERROR = `${ADDON_ID}/gitInfoError`;\nexport const PROJECT_INFO = `${ADDON_ID}/projectInfo`;\nexport const IS_OUTDATED = `${ADDON_ID}/isOutdated`;\nexport const START_BUILD = `${ADDON_ID}/startBuild`;\nexport const STOP_BUILD = `${ADDON_ID}/stopBuild`;\nexport const LOCAL_BUILD_PROGRESS = `${ADDON_ID}/localBuildProgress`;\n\nexport const REMOVE_ADDON = `${ADDON_ID}/removeAddon`;\n\nexport const CONFIG_OVERRIDES = {\n // Local changes should never be auto-accepted\n autoAcceptChanges: false,\n // Test results must be awaited to get progress updates\n exitOnceUploaded: false,\n // Don't raise any alarms when changes are found\n exitZeroOnChanges: true,\n // We might want to drop this later and instead record \"uncommitted hashes\" on builds\n forceRebuild: true,\n // This should never be set for local builds\n fromCI: false,\n // Builds initiated from the addon are always considered local\n isLocalBuild: true,\n // Never skip local builds\n skip: false,\n // No prompts from the Build proces\n interactive: false,\n};\n\nexport const DOCS_URL = \"https://www.chromatic.com/docs/visual-tests-addon\";\n","/* eslint-disable no-param-reassign */\n// eslint-disable-next-line import/no-unresolved\nimport { Context, InitialContext, Options, run, TaskName } from \"chromatic/node\";\n\nimport {\n BUILD_STEP_CONFIG,\n BUILD_STEP_ORDER,\n hasProgressEvent,\n INITIAL_BUILD_PAYLOAD,\n isKnownStep,\n} from \"./buildSteps\";\nimport { CONFIG_OVERRIDES } from \"./constants\";\nimport { LocalBuildProgress } from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\n\nconst ESTIMATED_PROGRESS_INTERVAL = 2000;\n\nlet abortController: AbortController | undefined;\n\nconst getBuildStepData = (\n task: TaskName,\n previousBuildProgress?: LocalBuildProgress[\"previousBuildProgress\"]\n) => {\n if (!isKnownStep(task)) throw new Error(`Unknown step: ${task}`);\n\n const stepDurations = BUILD_STEP_ORDER.map((step) => {\n const { startedAt, completedAt } = previousBuildProgress?.[step] || {};\n return startedAt && completedAt\n ? completedAt - startedAt\n : BUILD_STEP_CONFIG[step].estimateDuration;\n });\n const totalDuration = stepDurations.reduce((sum, duration) => sum + duration, 0);\n\n const stepIndex = BUILD_STEP_ORDER.indexOf(task);\n const startTime = stepDurations.slice(0, stepIndex).reduce((sum, duration) => sum + duration, 0);\n const endTime = startTime + stepDurations[stepIndex];\n\n const startPercentage = (startTime / totalDuration) * 100;\n const endPercentage = (endTime / totalDuration) * 100;\n return {\n ...BUILD_STEP_CONFIG[task],\n startPercentage,\n endPercentage,\n stepPercentage: endPercentage - startPercentage,\n };\n};\n\nexport const onStartOrProgress =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (ctx: Context, { progress, total }: { progress?: number; total?: number } = {}) => {\n clearTimeout(timeout);\n\n if (!isKnownStep(ctx.task)) return;\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress, previousBuildProgress } =\n localBuildProgress.value;\n\n // Ignore progress events for steps that have already completed\n if (stepProgress[ctx.task]?.completedAt) return;\n\n const { startPercentage, endPercentage, stepPercentage } = getBuildStepData(\n ctx.task,\n previousBuildProgress\n );\n\n let newPercentage = startPercentage;\n if (progress && total) {\n newPercentage += stepPercentage * (progress / total);\n }\n\n // If the step doesn't have a progress event, simulate one by synthetically updating progress\n if (!hasProgressEvent(ctx.task)) {\n const { estimateDuration } = BUILD_STEP_CONFIG[ctx.task];\n const stepIndex = BUILD_STEP_ORDER.indexOf(ctx.task);\n newPercentage =\n Math.max(newPercentage, buildProgressPercentage) +\n (ESTIMATED_PROGRESS_INTERVAL / estimateDuration) * stepPercentage;\n\n timeout = setTimeout(() => {\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n // Intentionally reference the present value here (after timeout)\n const { currentStep } = localBuildProgress.value;\n // Only update if we haven't moved on to a later step\n if (isKnownStep(currentStep) && BUILD_STEP_ORDER.indexOf(currentStep) <= stepIndex) {\n onStartOrProgress(localBuildProgress, timeout)(ctx);\n }\n }, ESTIMATED_PROGRESS_INTERVAL);\n }\n\n stepProgress[ctx.task] = {\n startedAt: Date.now(),\n ...stepProgress[ctx.task],\n ...(progress && total && { numerator: progress, denominator: total }),\n };\n\n localBuildProgress.value = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage: Math.min(newPercentage, endPercentage),\n currentStep: ctx.task,\n stepProgress,\n };\n };\n\nexport const onCompleteOrError =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (\n ctx: Context | InitialContext,\n error?: { formattedError: string; originalError: Error | Error[] }\n ) => {\n clearTimeout(timeout);\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress } = localBuildProgress.value;\n const update = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage,\n stepProgress,\n previousBuildProgress: stepProgress,\n };\n\n if (error) {\n localBuildProgress.value = {\n ...update,\n currentStep: abortController?.signal.aborted ? \"aborted\" : \"error\",\n formattedError: error.formattedError,\n originalError: error.originalError,\n };\n return;\n }\n\n if (ctx.task && isKnownStep(ctx.task)) {\n stepProgress[ctx.task] = {\n ...stepProgress[ctx.task],\n completedAt: Date.now(),\n };\n }\n\n if (ctx.task === \"verify\" && ctx.build?.wasLimited) {\n localBuildProgress.value = {\n ...update,\n currentStep: \"limited\",\n stepProgress,\n errorDetailsUrl: ctx.build?.app.account?.billingUrl,\n };\n }\n\n if (ctx.build && ctx.task === \"snapshot\") {\n localBuildProgress.value = {\n ...update,\n buildProgressPercentage: 100,\n currentStep: \"complete\",\n stepProgress,\n changeCount: ctx.build.changeCount,\n errorCount: ctx.build.errorCount,\n };\n }\n };\n\nexport const runChromaticBuild = async (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n options: Partial<Options>\n) => {\n if (!options.projectId) throw new Error(\"Missing projectId\");\n if (!options.userToken) throw new Error(\"Missing userToken\");\n\n localBuildProgress.value = INITIAL_BUILD_PAYLOAD;\n\n // Timeout is defined here so it's shared between all handlers\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n abortController?.abort();\n abortController = new AbortController();\n\n process.env.SB_TESTBUILD = \"true\";\n\n await run({\n flags: {\n interactive: false,\n },\n options: {\n ...options,\n ...CONFIG_OVERRIDES,\n experimental_onTaskStart: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskProgress: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskComplete: onCompleteOrError(localBuildProgress, timeout),\n experimental_onTaskError: onCompleteOrError(localBuildProgress, timeout),\n experimental_abortSignal: abortController?.signal,\n },\n });\n};\n\nexport const stopChromaticBuild = () => {\n abortController?.abort(new Error(\"Build canceled from Storybook\"));\n};\n","// eslint-disable-next-line import/no-unresolved\nimport { TaskName } from \"chromatic/node\";\nimport { filesize } from \"filesize\";\n\nimport { KnownStep, LocalBuildProgress, StepProgressPayload } from \"./types\";\n\nexport const isKnownStep = (\n taskOrStep: TaskName | LocalBuildProgress[\"currentStep\"]\n): taskOrStep is KnownStep => BUILD_STEP_ORDER.includes(taskOrStep as KnownStep);\n\nexport const hasProgressEvent = (task: TaskName) => [\"upload\", \"snapshot\"].includes(task);\n\n// Note this does not include the \"aborted\", \"complete\" and \"error\" steps\nexport const BUILD_STEP_ORDER: KnownStep[] = [\n \"initialize\",\n \"build\",\n \"upload\",\n \"verify\",\n \"snapshot\",\n];\n\nexport const BUILD_STEP_CONFIG: Record<\n LocalBuildProgress[\"currentStep\"],\n {\n key: LocalBuildProgress[\"currentStep\"];\n emoji: string;\n renderName: () => string;\n renderProgress: (payload: LocalBuildProgress) => string;\n renderComplete: () => string;\n estimateDuration: number;\n }\n> = {\n initialize: {\n key: \"initialize\",\n emoji: \"🚀\",\n renderName: () => `Initialize build`,\n renderProgress: () => `Initializing build...`,\n renderComplete: () => `Initialized`,\n estimateDuration: 2000,\n },\n build: {\n key: \"build\",\n emoji: \"🏗\",\n renderName: () => `Build Storybook`,\n renderProgress: () => `Building your Storybook...`,\n renderComplete: () => `Storybook built`,\n estimateDuration: 20_000,\n },\n upload: {\n key: \"upload\",\n emoji: \"📡\",\n renderName: () => `Publish your Storybook`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.upload;\n if (!denominator || !numerator) return `Uploading files...`;\n const { value: total, exponent } = filesize(denominator, {\n output: \"object\",\n round: 1,\n });\n const { value: progress, symbol } = filesize(numerator, {\n exponent,\n output: \"object\",\n round: 1,\n });\n return `Uploading files (${progress}/${total} ${symbol})...`;\n },\n renderComplete: () => `Publish complete`,\n estimateDuration: 20_000,\n },\n verify: {\n key: \"verify\",\n emoji: \"🔍\",\n renderName: () => `Verify your Storybook`,\n renderProgress: () => `Verifying contents...`,\n renderComplete: () => `Storybook verified`,\n estimateDuration: 20_000,\n },\n snapshot: {\n key: \"snapshot\",\n emoji: \"📸\",\n renderName: () => `Run visual tests`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.snapshot;\n return denominator\n ? `Running visual tests (${numerator}/${denominator})...`\n : `Running visual tests...`;\n },\n renderComplete: () => `Tested your stories`,\n estimateDuration: 90_000,\n },\n\n // These are special steps that are not part of the build process\n aborted: {\n key: \"aborted\",\n emoji: \"✋\",\n renderName: () => `Build canceled`,\n renderProgress: () => `Build canceled`,\n renderComplete: () => `Build canceled`,\n estimateDuration: 0,\n },\n complete: {\n key: \"complete\",\n emoji: \"🎉\",\n renderName: () => `Visual tests completed!`,\n renderProgress: () => `Visual tests completed!`,\n renderComplete: () => `Visual tests completed!`,\n estimateDuration: 0,\n },\n error: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build failed`,\n renderProgress: () => `Build failed`,\n renderComplete: () => `Build failed`,\n estimateDuration: 0,\n },\n limited: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build limited`,\n renderProgress: () => `Build limited`,\n renderComplete: () => `Build limited`,\n estimateDuration: 0,\n },\n};\n\nexport const INITIAL_BUILD_PAYLOAD = {\n buildProgressPercentage: 0,\n currentStep: BUILD_STEP_ORDER[0],\n stepProgress: Object.fromEntries(BUILD_STEP_ORDER.map((step) => [step, {}])) as Record<\n KnownStep,\n StepProgressPayload\n >,\n};\n","import type { Channel } from \"@storybook/channels\";\n\nexport const GET_VALUE = `experimental_useSharedState_getValue`;\nexport const SET_VALUE = `experimental_useSharedState_setValue`;\n\ntype ChannelLike = Pick<Channel, \"emit\" | \"on\" | \"off\">;\n\nconst instances = new Map<string, SharedState>();\n\nexport class SharedState<T = any> {\n channel: ChannelLike;\n\n listeners: ((value: T | undefined) => void)[];\n\n state: { [key: string]: { index: number; value: T | undefined } };\n\n constructor(channel: ChannelLike) {\n this.channel = channel;\n this.listeners = [];\n this.state = {};\n\n this.channel.on(SET_VALUE, (key: string, value: T | undefined, index: number) => {\n if (this.state?.[key]?.index >= index) return;\n this.state[key] = { index, value };\n });\n\n this.channel.on(GET_VALUE, (key: string) => {\n const index = this.state[key]?.index ?? 0;\n const value = this.state[key]?.value;\n this.channel.emit(SET_VALUE, key, value, index);\n });\n }\n\n get(key: string) {\n if (!this.state[key]) this.channel.emit(GET_VALUE, key);\n return this.state[key]?.value;\n }\n\n set(key: string, value: T | undefined) {\n const index = (this.state[key]?.index ?? 0) + 1;\n this.state[key] = { index, value };\n this.channel.emit(SET_VALUE, key, value, index);\n }\n\n static subscribe<T>(key: string, channel: ChannelLike) {\n const sharedState = instances.get(key) || new SharedState(channel);\n\n if (!instances.has(key)) {\n instances.set(key, sharedState);\n sharedState.channel.on(SET_VALUE, (k: string, v: T | undefined) => {\n if (k !== key) return;\n sharedState.listeners.forEach((listener) => listener(v));\n });\n }\n\n return {\n get value(): T | undefined {\n return sharedState.get(key);\n },\n\n set value(newValue: T | undefined) {\n sharedState.set(key, newValue);\n },\n\n on(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n sharedState.listeners.push(callback);\n },\n\n off(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n const index = sharedState.listeners.indexOf(callback);\n if (index >= 0) sharedState.listeners.splice(index, 1);\n },\n };\n }\n}\n","import type { Configuration } from \"chromatic/node\";\nimport { writeFile } from \"jsonfile\";\n\nexport async function updateChromaticConfig(configFile: string, configuration: Configuration) {\n await writeFile(configFile, configuration, { spaces: 2 });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/runChromaticBuild.ts","../src/buildSteps.ts","../src/utils/SharedState.ts","../src/utils/updateChromaticConfig.ts"],"names":["watch","normalize","relative","getConfiguration","getGitInfo","CHROMATIC_INDEX_URL","CHROMATIC_BASE_URL","CHROMATIC_API_URL","PACKAGE_NAME","ADDON_ID","PANEL_ID","SIDEBAR_TOP_ID","SIDEBAR_BOTTOM_ID","ACCESS_TOKEN_KEY","DEV_BUILD_ID_KEY","CONFIG_INFO","CONFIG_INFO_DISMISSED","GIT_INFO","GIT_INFO_ERROR","PROJECT_INFO","IS_OUTDATED","START_BUILD","STOP_BUILD","LOCAL_BUILD_PROGRESS","SELECTED_MODE_NAME","SELECTED_BROWSER_ID","REMOVE_ADDON","CONFIG_OVERRIDES","run","filesize","isKnownStep","taskOrStep","BUILD_STEP_ORDER","hasProgressEvent","task","BUILD_STEP_CONFIG","stepProgress","numerator","denominator","total","exponent","progress","symbol","INITIAL_BUILD_PAYLOAD","step","ESTIMATED_PROGRESS_INTERVAL","abortController","getBuildStepData","previousBuildProgress","stepDurations","startedAt","completedAt","totalDuration","sum","duration","stepIndex","startTime","endTime","startPercentage","endPercentage","onStartOrProgress","localBuildProgress","timeout","ctx","buildProgressPercentage","stepPercentage","newPercentage","estimateDuration","currentStep","onCompleteOrError","error","update","runChromaticBuild","options","stopChromaticBuild","GET_VALUE","SET_VALUE","instances","SharedState","channel","key","value","index","sharedState","k","v","listener","newValue","event","callback","writeFile","updateChromaticConfig","configFile","configuration","managerEntries","entry","__require","suggestRemovals","config","defaults","getConfigInfo","configDir","problems","suggestions","repositoryRootDir","baseDir","observeGitInfo","interval","errorCallback","projectId","prev","prevError","timer","act","gitInfo","e","watchConfigFile","onChange","eventType","filename","serverChannel","presets","apiPromise","initialProjectId","projectInfoState","lastProjectId","writtenConfigFile","foundConfigFile","targetConfigFile","err","userToken","api","configInfoState","gitInfoState","gitInfoError","info","env","configType","src_default"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { watch } from \"node:fs\";\nimport { normalize, relative } from \"node:path\";\n\nimport type { Channel } from \"@storybook/channels\";\nimport type { Options } from \"@storybook/types\";\n// eslint-disable-next-line import/no-unresolved\nimport { type Configuration, getConfiguration, getGitInfo, type GitInfo } from \"chromatic/node\";\n\nimport {\n ADDON_ID,\n CHROMATIC_BASE_URL,\n CONFIG_INFO,\n GIT_INFO,\n GIT_INFO_ERROR,\n LOCAL_BUILD_PROGRESS,\n PACKAGE_NAME,\n PROJECT_INFO,\n REMOVE_ADDON,\n START_BUILD,\n STOP_BUILD,\n} from \"./constants\";\nimport { runChromaticBuild, stopChromaticBuild } from \"./runChromaticBuild\";\nimport {\n ConfigInfoPayload,\n ConfigurationUpdate,\n GitInfoPayload,\n LocalBuildProgress,\n ProjectInfoPayload,\n} from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\nimport { updateChromaticConfig } from \"./utils/updateChromaticConfig\";\n\n/**\n * to load the built addon in this test Storybook\n */\nfunction managerEntries(entry: string[] = []) {\n return [...entry, require.resolve(\"./manager.mjs\")];\n}\n\n// Nullify any suggestions that are the same as the defaults, to suggest removal.\n// Drop suggestions for removal that don't actually appear in the current config.\nconst suggestRemovals = (\n config: Configuration,\n defaults: Configuration,\n update: ConfigurationUpdate\n) =>\n Object.fromEntries(\n (Object.entries(update) as [keyof Configuration, Configuration[keyof Configuration]][])\n .map(([key, value]) => [key, value === defaults[key] ? null : value])\n .filter(([key, value]) => value !== null || config[key as keyof Configuration] !== undefined)\n );\n\n// Detect problems in the current configuration and suggest updates.\nconst getConfigInfo = async (\n configuration: Awaited<ReturnType<typeof getConfiguration>>,\n { configDir }: Options\n) => {\n const defaults: Configuration = {\n storybookBaseDir: \".\",\n storybookConfigDir: \".storybook\",\n } as const;\n\n const problems: ConfigurationUpdate = {};\n const suggestions: ConfigurationUpdate = {};\n\n const { repositoryRootDir } = await getGitInfo();\n const baseDir = repositoryRootDir && normalize(relative(repositoryRootDir, process.cwd()));\n if (baseDir !== normalize(configuration.storybookBaseDir ?? \"\")) {\n problems.storybookBaseDir = baseDir;\n }\n\n if (configDir !== normalize(configuration.storybookConfigDir ?? \"\")) {\n problems.storybookConfigDir = normalize(relative(process.cwd(), configDir));\n }\n\n if (!configuration.zip) {\n suggestions.zip = true;\n }\n\n return {\n configuration,\n problems: suggestRemovals(configuration, defaults, problems),\n suggestions: suggestRemovals(configuration, defaults, suggestions),\n };\n};\n\n// Polls for changes to the Git state and invokes the callback when it changes.\n// Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls.\nconst observeGitInfo = async (\n interval: number,\n callback: (info: GitInfo, prevInfo?: GitInfo) => void,\n errorCallback: (e: Error) => void,\n projectId?: string\n) => {\n let prev: GitInfo | undefined;\n let prevError: Error | undefined;\n let timer: NodeJS.Timeout | undefined;\n const act = async () => {\n try {\n const gitInfo = await getGitInfo();\n if (Object.entries(gitInfo).some(([key, value]) => prev?.[key as keyof GitInfo] !== value)) {\n callback(gitInfo, prev);\n }\n prev = gitInfo;\n prevError = undefined;\n timer = setTimeout(act, interval);\n } catch (e: any) {\n errorCallback(e);\n if (projectId && prevError?.message !== e.message) {\n console.error(`Failed to fetch git info, with error:\\n${e}`);\n prev = undefined;\n prevError = e;\n }\n timer = setTimeout(act, interval);\n }\n };\n act();\n\n return () => clearTimeout(timer);\n};\n\nconst watchConfigFile = async (\n configFile: string | undefined,\n onChange: (configuration: Awaited<ReturnType<typeof getConfiguration>>) => Promise<void>\n) => {\n const configuration = await getConfiguration(configFile);\n await onChange(configuration);\n\n if (configuration.configFile) {\n watch(configuration.configFile, async (eventType: string, filename: string | null) => {\n if (filename) await onChange(await getConfiguration(filename));\n });\n }\n};\n\nasync function serverChannel(channel: Channel, options: Options & { configFile?: string }) {\n const { configFile, presets } = options;\n\n // Lazy load the API since we don't need it right away\n const apiPromise = presets.apply<any>(\"experimental_serverAPI\");\n\n // This yields an empty object if the file doesn't exist and no explicit configFile is specified\n const { projectId: initialProjectId } = await getConfiguration(configFile);\n\n const projectInfoState = SharedState.subscribe<ProjectInfoPayload>(PROJECT_INFO, channel);\n projectInfoState.value = initialProjectId ? { projectId: initialProjectId } : {};\n\n let lastProjectId = initialProjectId;\n projectInfoState.on(\"change\", async ({ projectId } = {}) => {\n if (!projectId || projectId === lastProjectId) return;\n lastProjectId = projectId;\n\n const writtenConfigFile = configFile;\n try {\n // No config file may be found (file is about to be created)\n const { configFile: foundConfigFile, ...config } = await getConfiguration(writtenConfigFile);\n const targetConfigFile = foundConfigFile || writtenConfigFile || \"chromatic.config.json\";\n await updateChromaticConfig(targetConfigFile, { ...config, projectId });\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: true,\n configFile: targetConfigFile,\n };\n } catch (err) {\n console.warn(`Failed to update your main configuration:\\n\\n ${err}`);\n\n projectInfoState.value = {\n ...projectInfoState.value,\n written: false,\n configFile: writtenConfigFile,\n };\n }\n });\n\n const localBuildProgress = SharedState.subscribe<LocalBuildProgress>(\n LOCAL_BUILD_PROGRESS,\n channel\n );\n\n channel.on(START_BUILD, async ({ accessToken: userToken }) => {\n const { projectId } = projectInfoState.value || {};\n try {\n await runChromaticBuild(localBuildProgress, { configFile, projectId, userToken });\n } catch (e) {\n console.error(`Failed to run Chromatic build, with error:\\n${e}`);\n }\n });\n\n channel.on(STOP_BUILD, stopChromaticBuild);\n channel.on(REMOVE_ADDON, () =>\n apiPromise.then((api) => api.removeAddon(PACKAGE_NAME)).catch((e) => console.error(e))\n );\n\n const configInfoState = SharedState.subscribe<ConfigInfoPayload>(CONFIG_INFO, channel);\n const gitInfoState = SharedState.subscribe<GitInfoPayload>(GIT_INFO, channel);\n const gitInfoError = SharedState.subscribe<Error>(GIT_INFO_ERROR, channel);\n\n observeGitInfo(\n 5000,\n (info) => {\n gitInfoError.value = undefined;\n gitInfoState.value = info;\n },\n (error: Error) => {\n gitInfoError.value = error;\n }\n );\n\n watchConfigFile(configFile, async (configuration) => {\n if (!lastProjectId) return;\n configInfoState.value = await getConfigInfo(configuration, options);\n });\n\n setInterval(() => channel.emit(`${ADDON_ID}/heartbeat`), 1000);\n\n return channel;\n}\n\nconst config = {\n managerEntries,\n experimental_serverChannel: serverChannel,\n env: async (\n env: Record<string, string>,\n { configType }: { configType: \"DEVELOPMENT\" | \"PRODUCTION\" }\n ) => {\n if (configType === \"PRODUCTION\") return env;\n\n return {\n ...env,\n CHROMATIC_BASE_URL,\n };\n },\n};\n\nexport default config;\n","export const {\n CHROMATIC_INDEX_URL,\n CHROMATIC_BASE_URL = CHROMATIC_INDEX_URL || \"https://www.chromatic.com\",\n CHROMATIC_API_URL = `${CHROMATIC_BASE_URL}/api`,\n} = process.env;\n\nexport const PACKAGE_NAME = \"@chromatic-com/storybook\";\n\nexport const ADDON_ID = \"chromaui/addon-visual-tests\";\nexport const PANEL_ID = `${ADDON_ID}/panel`;\nexport const SIDEBAR_TOP_ID = `${ADDON_ID}/sidebarTop`;\nexport const SIDEBAR_BOTTOM_ID = `${ADDON_ID}/sidebarBottom`;\nexport const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`;\nexport const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`;\nexport const CONFIG_INFO = `${ADDON_ID}/configInfo`;\nexport const CONFIG_INFO_DISMISSED = `${ADDON_ID}/configInfoDismissed`;\nexport const GIT_INFO = `${ADDON_ID}/gitInfo`;\nexport const GIT_INFO_ERROR = `${ADDON_ID}/gitInfoError`;\nexport const PROJECT_INFO = `${ADDON_ID}/projectInfo`;\nexport const IS_OUTDATED = `${ADDON_ID}/isOutdated`;\nexport const START_BUILD = `${ADDON_ID}/startBuild`;\nexport const STOP_BUILD = `${ADDON_ID}/stopBuild`;\nexport const LOCAL_BUILD_PROGRESS = `${ADDON_ID}/localBuildProgress`;\nexport const SELECTED_MODE_NAME = `${ADDON_ID}/selectedModeName`;\nexport const SELECTED_BROWSER_ID = `${ADDON_ID}/selectedBrowserId`;\n\nexport const REMOVE_ADDON = `${ADDON_ID}/removeAddon`;\n\nexport const CONFIG_OVERRIDES = {\n // Local changes should never be auto-accepted\n autoAcceptChanges: false,\n // Test results must be awaited to get progress updates\n exitOnceUploaded: false,\n // Don't raise any alarms when changes are found\n exitZeroOnChanges: true,\n // We might want to drop this later and instead record \"uncommitted hashes\" on builds\n forceRebuild: true,\n // This should never be set for local builds\n fromCI: false,\n // Builds initiated from the addon are always considered local\n isLocalBuild: true,\n // Never skip local builds\n skip: false,\n // No prompts from the Build proces\n interactive: false,\n};\n\nexport const DOCS_URL = \"https://www.chromatic.com/docs/visual-tests-addon\";\n","/* eslint-disable no-param-reassign */\n// eslint-disable-next-line import/no-unresolved\nimport { Context, InitialContext, Options, run, TaskName } from \"chromatic/node\";\n\nimport {\n BUILD_STEP_CONFIG,\n BUILD_STEP_ORDER,\n hasProgressEvent,\n INITIAL_BUILD_PAYLOAD,\n isKnownStep,\n} from \"./buildSteps\";\nimport { CONFIG_OVERRIDES } from \"./constants\";\nimport { LocalBuildProgress } from \"./types\";\nimport { SharedState } from \"./utils/SharedState\";\n\nconst ESTIMATED_PROGRESS_INTERVAL = 2000;\n\nlet abortController: AbortController | undefined;\n\nconst getBuildStepData = (\n task: TaskName,\n previousBuildProgress?: LocalBuildProgress[\"previousBuildProgress\"]\n) => {\n if (!isKnownStep(task)) throw new Error(`Unknown step: ${task}`);\n\n const stepDurations = BUILD_STEP_ORDER.map((step) => {\n const { startedAt, completedAt } = previousBuildProgress?.[step] || {};\n return startedAt && completedAt\n ? completedAt - startedAt\n : BUILD_STEP_CONFIG[step].estimateDuration;\n });\n const totalDuration = stepDurations.reduce((sum, duration) => sum + duration, 0);\n\n const stepIndex = BUILD_STEP_ORDER.indexOf(task);\n const startTime = stepDurations.slice(0, stepIndex).reduce((sum, duration) => sum + duration, 0);\n const endTime = startTime + stepDurations[stepIndex];\n\n const startPercentage = (startTime / totalDuration) * 100;\n const endPercentage = (endTime / totalDuration) * 100;\n return {\n ...BUILD_STEP_CONFIG[task],\n startPercentage,\n endPercentage,\n stepPercentage: endPercentage - startPercentage,\n };\n};\n\nexport const onStartOrProgress =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (ctx: Context, { progress, total }: { progress?: number; total?: number } = {}) => {\n clearTimeout(timeout);\n\n if (!isKnownStep(ctx.task)) return;\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress, previousBuildProgress } =\n localBuildProgress.value;\n\n // Ignore progress events for steps that have already completed\n if (stepProgress[ctx.task]?.completedAt) return;\n\n const { startPercentage, endPercentage, stepPercentage } = getBuildStepData(\n ctx.task,\n previousBuildProgress\n );\n\n let newPercentage = startPercentage;\n if (progress && total) {\n newPercentage += stepPercentage * (progress / total);\n }\n\n // If the step doesn't have a progress event, simulate one by synthetically updating progress\n if (!hasProgressEvent(ctx.task)) {\n const { estimateDuration } = BUILD_STEP_CONFIG[ctx.task];\n const stepIndex = BUILD_STEP_ORDER.indexOf(ctx.task);\n newPercentage =\n Math.max(newPercentage, buildProgressPercentage) +\n (ESTIMATED_PROGRESS_INTERVAL / estimateDuration) * stepPercentage;\n\n timeout = setTimeout(() => {\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n // Intentionally reference the present value here (after timeout)\n const { currentStep } = localBuildProgress.value;\n // Only update if we haven't moved on to a later step\n if (isKnownStep(currentStep) && BUILD_STEP_ORDER.indexOf(currentStep) <= stepIndex) {\n onStartOrProgress(localBuildProgress, timeout)(ctx);\n }\n }, ESTIMATED_PROGRESS_INTERVAL);\n }\n\n stepProgress[ctx.task] = {\n startedAt: Date.now(),\n ...stepProgress[ctx.task],\n ...(progress && total && { numerator: progress, denominator: total }),\n };\n\n localBuildProgress.value = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage: Math.min(newPercentage, endPercentage),\n currentStep: ctx.task,\n stepProgress,\n };\n };\n\nexport const onCompleteOrError =\n (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n timeout?: ReturnType<typeof setTimeout>\n ) =>\n (\n ctx: Context | InitialContext,\n error?: { formattedError: string; originalError: Error | Error[] }\n ) => {\n clearTimeout(timeout);\n\n // We should set this right before starting so it should never be unset during a build.\n if (!localBuildProgress.value) {\n throw new Error(\"Unexpected missing value for localBuildProgress\");\n }\n\n const { buildProgressPercentage, stepProgress } = localBuildProgress.value;\n const update = {\n buildId: ctx.announcedBuild?.id,\n branch: ctx.git?.branch,\n buildProgressPercentage,\n stepProgress,\n previousBuildProgress: stepProgress,\n };\n\n if (error) {\n localBuildProgress.value = {\n ...update,\n currentStep: abortController?.signal.aborted ? \"aborted\" : \"error\",\n formattedError: error.formattedError,\n originalError: error.originalError,\n };\n return;\n }\n\n if (ctx.task && isKnownStep(ctx.task)) {\n stepProgress[ctx.task] = {\n ...stepProgress[ctx.task],\n completedAt: Date.now(),\n };\n }\n\n if (ctx.task === \"verify\" && ctx.build?.wasLimited) {\n localBuildProgress.value = {\n ...update,\n currentStep: \"limited\",\n stepProgress,\n errorDetailsUrl: ctx.build?.app.account?.billingUrl,\n };\n }\n\n if (ctx.build && ctx.task === \"snapshot\") {\n localBuildProgress.value = {\n ...update,\n buildProgressPercentage: 100,\n currentStep: \"complete\",\n stepProgress,\n changeCount: ctx.build.changeCount,\n errorCount: ctx.build.errorCount,\n };\n }\n };\n\nexport const runChromaticBuild = async (\n localBuildProgress: ReturnType<typeof SharedState.subscribe<LocalBuildProgress>>,\n options: Partial<Options>\n) => {\n if (!options.projectId) throw new Error(\"Missing projectId\");\n if (!options.userToken) throw new Error(\"Missing userToken\");\n\n localBuildProgress.value = INITIAL_BUILD_PAYLOAD;\n\n // Timeout is defined here so it's shared between all handlers\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n abortController?.abort();\n abortController = new AbortController();\n\n process.env.SB_TESTBUILD = \"true\";\n\n await run({\n flags: {\n interactive: false,\n },\n options: {\n ...options,\n ...CONFIG_OVERRIDES,\n experimental_onTaskStart: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskProgress: onStartOrProgress(localBuildProgress, timeout),\n experimental_onTaskComplete: onCompleteOrError(localBuildProgress, timeout),\n experimental_onTaskError: onCompleteOrError(localBuildProgress, timeout),\n experimental_abortSignal: abortController?.signal,\n },\n });\n};\n\nexport const stopChromaticBuild = () => {\n abortController?.abort(new Error(\"Build canceled from Storybook\"));\n};\n","// eslint-disable-next-line import/no-unresolved\nimport { TaskName } from \"chromatic/node\";\nimport { filesize } from \"filesize\";\n\nimport { KnownStep, LocalBuildProgress, StepProgressPayload } from \"./types\";\n\nexport const isKnownStep = (\n taskOrStep: TaskName | LocalBuildProgress[\"currentStep\"]\n): taskOrStep is KnownStep => BUILD_STEP_ORDER.includes(taskOrStep as KnownStep);\n\nexport const hasProgressEvent = (task: TaskName) => [\"upload\", \"snapshot\"].includes(task);\n\n// Note this does not include the \"aborted\", \"complete\" and \"error\" steps\nexport const BUILD_STEP_ORDER: KnownStep[] = [\n \"initialize\",\n \"build\",\n \"upload\",\n \"verify\",\n \"snapshot\",\n];\n\nexport const BUILD_STEP_CONFIG: Record<\n LocalBuildProgress[\"currentStep\"],\n {\n key: LocalBuildProgress[\"currentStep\"];\n emoji: string;\n renderName: () => string;\n renderProgress: (payload: LocalBuildProgress) => string;\n renderComplete: () => string;\n estimateDuration: number;\n }\n> = {\n initialize: {\n key: \"initialize\",\n emoji: \"🚀\",\n renderName: () => `Initialize build`,\n renderProgress: () => `Initializing build...`,\n renderComplete: () => `Initialized`,\n estimateDuration: 2000,\n },\n build: {\n key: \"build\",\n emoji: \"🏗\",\n renderName: () => `Build Storybook`,\n renderProgress: () => `Building your Storybook...`,\n renderComplete: () => `Storybook built`,\n estimateDuration: 20_000,\n },\n upload: {\n key: \"upload\",\n emoji: \"📡\",\n renderName: () => `Publish your Storybook`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.upload;\n if (!denominator || !numerator) return `Uploading files...`;\n const { value: total, exponent } = filesize(denominator, {\n output: \"object\",\n round: 1,\n });\n const { value: progress, symbol } = filesize(numerator, {\n exponent,\n output: \"object\",\n round: 1,\n });\n return `Uploading files (${progress}/${total} ${symbol})...`;\n },\n renderComplete: () => `Publish complete`,\n estimateDuration: 20_000,\n },\n verify: {\n key: \"verify\",\n emoji: \"🔍\",\n renderName: () => `Verify your Storybook`,\n renderProgress: () => `Verifying contents...`,\n renderComplete: () => `Storybook verified`,\n estimateDuration: 20_000,\n },\n snapshot: {\n key: \"snapshot\",\n emoji: \"📸\",\n renderName: () => `Run visual tests`,\n renderProgress: ({ stepProgress }) => {\n const { numerator, denominator } = stepProgress.snapshot;\n return denominator\n ? `Running visual tests (${numerator}/${denominator})...`\n : `Running visual tests...`;\n },\n renderComplete: () => `Tested your stories`,\n estimateDuration: 90_000,\n },\n\n // These are special steps that are not part of the build process\n aborted: {\n key: \"aborted\",\n emoji: \"✋\",\n renderName: () => `Build canceled`,\n renderProgress: () => `Build canceled`,\n renderComplete: () => `Build canceled`,\n estimateDuration: 0,\n },\n complete: {\n key: \"complete\",\n emoji: \"🎉\",\n renderName: () => `Visual tests completed!`,\n renderProgress: () => `Visual tests completed!`,\n renderComplete: () => `Visual tests completed!`,\n estimateDuration: 0,\n },\n error: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build failed`,\n renderProgress: () => `Build failed`,\n renderComplete: () => `Build failed`,\n estimateDuration: 0,\n },\n limited: {\n key: \"error\",\n emoji: \"🚨\",\n renderName: () => `Build limited`,\n renderProgress: () => `Build limited`,\n renderComplete: () => `Build limited`,\n estimateDuration: 0,\n },\n};\n\nexport const INITIAL_BUILD_PAYLOAD = {\n buildProgressPercentage: 0,\n currentStep: BUILD_STEP_ORDER[0],\n stepProgress: Object.fromEntries(BUILD_STEP_ORDER.map((step) => [step, {}])) as Record<\n KnownStep,\n StepProgressPayload\n >,\n};\n","import type { Channel } from \"@storybook/channels\";\n\nexport const GET_VALUE = `experimental_useSharedState_getValue`;\nexport const SET_VALUE = `experimental_useSharedState_setValue`;\n\ntype ChannelLike = Pick<Channel, \"emit\" | \"on\" | \"off\">;\n\nconst instances = new Map<string, SharedState>();\n\nexport class SharedState<T = any> {\n channel: ChannelLike;\n\n listeners: ((value: T | undefined) => void)[];\n\n state: { [key: string]: { index: number; value: T | undefined } };\n\n constructor(channel: ChannelLike) {\n this.channel = channel;\n this.listeners = [];\n this.state = {};\n\n this.channel.on(SET_VALUE, (key: string, value: T | undefined, index: number) => {\n if (this.state?.[key]?.index >= index) return;\n this.state[key] = { index, value };\n });\n\n this.channel.on(GET_VALUE, (key: string) => {\n const index = this.state[key]?.index ?? 0;\n const value = this.state[key]?.value;\n this.channel.emit(SET_VALUE, key, value, index);\n });\n }\n\n get(key: string) {\n if (!this.state[key]) this.channel.emit(GET_VALUE, key);\n return this.state[key]?.value;\n }\n\n set(key: string, value: T | undefined) {\n const index = (this.state[key]?.index ?? 0) + 1;\n this.state[key] = { index, value };\n this.channel.emit(SET_VALUE, key, value, index);\n }\n\n static subscribe<T>(key: string, channel: ChannelLike) {\n const sharedState = instances.get(key) || new SharedState(channel);\n\n if (!instances.has(key)) {\n instances.set(key, sharedState);\n sharedState.channel.on(SET_VALUE, (k: string, v: T | undefined) => {\n if (k !== key) return;\n sharedState.listeners.forEach((listener) => listener(v));\n });\n }\n\n return {\n get value(): T | undefined {\n return sharedState.get(key);\n },\n\n set value(newValue: T | undefined) {\n sharedState.set(key, newValue);\n },\n\n on(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n sharedState.listeners.push(callback);\n },\n\n off(event: \"change\", callback: (value: T | undefined) => void) {\n if (event !== \"change\") throw new Error(\"unsupported event\");\n const index = sharedState.listeners.indexOf(callback);\n if (index >= 0) sharedState.listeners.splice(index, 1);\n },\n };\n }\n}\n","import type { Configuration } from \"chromatic/node\";\nimport { writeFile } from \"jsonfile\";\n\nexport async function updateChromaticConfig(configFile: string, configuration: Configuration) {\n await writeFile(configFile, configuration, { spaces: 2 });\n}\n"]}
|