Skip to content

Commit

Permalink
More updates in preview-web
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeasday committed May 31, 2022
1 parent d42b8b7 commit fae35d3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 39 deletions.
33 changes: 22 additions & 11 deletions lib/preview-web/src/Preview.tsx
@@ -1,7 +1,18 @@
import dedent from 'ts-dedent';
import global from 'global';
import { SynchronousPromise } from 'synchronous-promise';
import Events from '@storybook/core-events';
import {
CONFIG_ERROR,
FORCE_REMOUNT,
FORCE_RE_RENDER,
GLOBALS_UPDATED,
RESET_STORY_ARGS,
SET_GLOBALS,
STORY_ARGS_UPDATED,
STORY_INDEX_INVALIDATED,
UPDATE_GLOBALS,
UPDATE_STORY_ARGS,
} from '@storybook/core-events';
import { logger } from '@storybook/client-logger';
import { addons, Channel } from '@storybook/addons';
import { AnyFramework, StoryId, ProjectAnnotations, Args, Globals } from '@storybook/csf';
Expand Down Expand Up @@ -80,13 +91,13 @@ export class Preview<TFramework extends AnyFramework> {
}

setupListeners() {
this.serverChannel?.on(Events.STORY_INDEX_INVALIDATED, this.onStoryIndexChanged.bind(this));
this.serverChannel?.on(STORY_INDEX_INVALIDATED, this.onStoryIndexChanged.bind(this));

this.channel.on(Events.UPDATE_GLOBALS, this.onUpdateGlobals.bind(this));
this.channel.on(Events.UPDATE_STORY_ARGS, this.onUpdateArgs.bind(this));
this.channel.on(Events.RESET_STORY_ARGS, this.onResetArgs.bind(this));
this.channel.on(Events.FORCE_RE_RENDER, this.onForceReRender.bind(this));
this.channel.on(Events.FORCE_REMOUNT, this.onForceRemount.bind(this));
this.channel.on(UPDATE_GLOBALS, this.onUpdateGlobals.bind(this));
this.channel.on(UPDATE_STORY_ARGS, this.onUpdateArgs.bind(this));
this.channel.on(RESET_STORY_ARGS, this.onResetArgs.bind(this));
this.channel.on(FORCE_RE_RENDER, this.onForceReRender.bind(this));
this.channel.on(FORCE_REMOUNT, this.onForceRemount.bind(this));
}

getProjectAnnotationsOrRenderError(
Expand Down Expand Up @@ -144,7 +155,7 @@ export class Preview<TFramework extends AnyFramework> {
}

emitGlobals() {
this.channel.emit(Events.SET_GLOBALS, {
this.channel.emit(SET_GLOBALS, {
globals: this.storyStore.globals.get() || {},
globalTypes: this.storyStore.projectAnnotations.globalTypes || {},
});
Expand Down Expand Up @@ -227,7 +238,7 @@ export class Preview<TFramework extends AnyFramework> {

await Promise.all(this.storyRenders.map((r) => r.rerender()));

this.channel.emit(Events.GLOBALS_UPDATED, {
this.channel.emit(GLOBALS_UPDATED, {
globals: this.storyStore.globals.get(),
initialGlobals: this.storyStore.globals.initialGlobals,
});
Expand All @@ -238,7 +249,7 @@ export class Preview<TFramework extends AnyFramework> {

await Promise.all(this.storyRenders.filter((r) => r.id === storyId).map((r) => r.rerender()));

this.channel.emit(Events.STORY_ARGS_UPDATED, {
this.channel.emit(STORY_ARGS_UPDATED, {
storyId,
args: this.storyStore.args.get(storyId),
});
Expand Down Expand Up @@ -344,6 +355,6 @@ export class Preview<TFramework extends AnyFramework> {
this.previewEntryError = err;
logger.error(reason);
logger.error(err);
this.channel.emit(Events.CONFIG_ERROR, err);
this.channel.emit(CONFIG_ERROR, err);
}
}
21 changes: 14 additions & 7 deletions lib/preview-web/src/PreviewWeb.mockdata.ts
@@ -1,5 +1,12 @@
import { EventEmitter } from 'events';
import Events from '@storybook/core-events';
import {
DOCS_RENDERED,
STORY_ERRORED,
STORY_MISSING,
STORY_RENDERED,
STORY_RENDER_PHASE_CHANGED,
STORY_THREW_EXCEPTION,
} from '@storybook/core-events';
import { StoryIndex } from '@storybook/store';
import { RenderPhase } from './PreviewWeb';

Expand Down Expand Up @@ -99,15 +106,15 @@ export const waitForEvents = (
// the async parts, so we need to listen for the "done" events
export const waitForRender = () =>
waitForEvents([
Events.STORY_RENDERED,
Events.DOCS_RENDERED,
Events.STORY_THREW_EXCEPTION,
Events.STORY_ERRORED,
Events.STORY_MISSING,
STORY_RENDERED,
DOCS_RENDERED,
STORY_THREW_EXCEPTION,
STORY_ERRORED,
STORY_MISSING,
]);

export const waitForRenderPhase = (phase: RenderPhase) =>
waitForEvents([Events.STORY_RENDER_PHASE_CHANGED], ({ newPhase }) => newPhase === phase);
waitForEvents([STORY_RENDER_PHASE_CHANGED], ({ newPhase }) => newPhase === phase);

// A little trick to ensure that we always call the real `setTimeout` even when timers are mocked
const realSetTimeout = setTimeout;
Expand Down
2 changes: 1 addition & 1 deletion lib/preview-web/src/PreviewWeb.test.ts
@@ -1,7 +1,7 @@
import global from 'global';
import * as ReactDOM from 'react-dom';
import merge from 'lodash/merge';
import Events, {
import {
CONFIG_ERROR,
CURRENT_STORY_WAS_SET,
DOCS_RENDERED,
Expand Down
57 changes: 37 additions & 20 deletions lib/preview-web/src/PreviewWeb.tsx
@@ -1,7 +1,24 @@
import deprecate from 'util-deprecate';
import dedent from 'ts-dedent';
import global from 'global';
import Events, { IGNORED_EXCEPTION } from '@storybook/core-events';
import {
CURRENT_STORY_WAS_SET,
IGNORED_EXCEPTION,
PRELOAD_STORIES,
PREVIEW_KEYDOWN,
SET_CURRENT_STORY,
SET_STORIES,
STORY_ARGS_UPDATED,
STORY_CHANGED,
STORY_ERRORED,
STORY_MISSING,
STORY_PREPARED,
STORY_RENDER_PHASE_CHANGED,
STORY_SPECIFIED,
STORY_THREW_EXCEPTION,
STORY_UNCHANGED,
UPDATE_QUERY_PARAMS,
} from '@storybook/core-events';
import { logger } from '@storybook/client-logger';
import { AnyFramework, StoryId, ProjectAnnotations, Args, Globals } from '@storybook/csf';
import type {
Expand Down Expand Up @@ -64,9 +81,9 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew

globalWindow.onkeydown = this.onKeydown.bind(this);

this.channel.on(Events.SET_CURRENT_STORY, this.onSetCurrentStory.bind(this));
this.channel.on(Events.UPDATE_QUERY_PARAMS, this.onUpdateQueryParams.bind(this));
this.channel.on(Events.PRELOAD_STORIES, this.onPreloadStories.bind(this));
this.channel.on(SET_CURRENT_STORY, this.onSetCurrentStory.bind(this));
this.channel.on(UPDATE_QUERY_PARAMS, this.onUpdateQueryParams.bind(this));
this.channel.on(PRELOAD_STORIES, this.onPreloadStories.bind(this));
}

initializeWithProjectAnnotations(projectAnnotations: WebProjectAnnotations<TFramework>) {
Expand All @@ -87,7 +104,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
initializeWithStoryIndex(storyIndex: StoryIndex): PromiseLike<void> {
return super.initializeWithStoryIndex(storyIndex).then(() => {
if (!global.FEATURES?.storyStoreV7) {
this.channel.emit(Events.SET_STORIES, this.storyStore.getSetStoriesPayload());
this.channel.emit(SET_STORIES, this.storyStore.getSetStoriesPayload());
}

return this.selectSpecifiedStory();
Expand Down Expand Up @@ -130,9 +147,9 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
}

this.urlStore.setSelection({ storyId, viewMode });
this.channel.emit(Events.STORY_SPECIFIED, this.urlStore.selection);
this.channel.emit(STORY_SPECIFIED, this.urlStore.selection);

this.channel.emit(Events.CURRENT_STORY_WAS_SET, this.urlStore.selection);
this.channel.emit(CURRENT_STORY_WAS_SET, this.urlStore.selection);

await this.renderSelection({ persistedArgs: args });
}
Expand Down Expand Up @@ -161,7 +178,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
super.onStoriesChanged({ importFn, storyIndex });

if (!global.FEATURES?.storyStoreV7) {
this.channel.emit(Events.SET_STORIES, await this.storyStore.getSetStoriesPayload());
this.channel.emit(SET_STORIES, await this.storyStore.getSetStoriesPayload());
}

if (this.urlStore.selection) {
Expand All @@ -176,15 +193,15 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
if (!this.currentRender?.disableKeyListeners && !focusInInput(event)) {
// We have to pick off the keys of the event that we need on the other side
const { altKey, ctrlKey, metaKey, shiftKey, key, code, keyCode } = event;
this.channel.emit(Events.PREVIEW_KEYDOWN, {
this.channel.emit(PREVIEW_KEYDOWN, {
event: { altKey, ctrlKey, metaKey, shiftKey, key, code, keyCode },
});
}
}

onSetCurrentStory(selection: Selection) {
this.urlStore.setSelection(selection);
this.channel.emit(Events.CURRENT_STORY_WAS_SET, this.urlStore.selection);
this.channel.emit(CURRENT_STORY_WAS_SET, this.urlStore.selection);
this.renderSelection();
}

Expand Down Expand Up @@ -290,7 +307,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
// Don't re-render the story if nothing has changed to justify it
if (lastRender && !storyIdChanged && !implementationChanged && !viewModeChanged) {
this.currentRender = lastRender;
this.channel.emit(Events.STORY_UNCHANGED, storyId);
this.channel.emit(STORY_UNCHANGED, storyId);
this.view.showMain();
return;
}
Expand All @@ -301,11 +318,11 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew

// If we are rendering something new (as opposed to re-rendering the same or first story), emit
if (lastSelection && (storyIdChanged || viewModeChanged)) {
this.channel.emit(Events.STORY_CHANGED, storyId);
this.channel.emit(STORY_CHANGED, storyId);
}

if (global.FEATURES?.storyStoreV7) {
this.channel.emit(Events.STORY_PREPARED, {
this.channel.emit(STORY_PREPARED, {
id: storyId,
parameters,
initialArgs,
Expand All @@ -318,7 +335,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
// If the implementation changed, or args were persisted, the args may have changed,
// and the STORY_PREPARED event above may not be respected.
if (implementationChanged || persistedArgs) {
this.channel.emit(Events.STORY_ARGS_UPDATED, { storyId, args });
this.channel.emit(STORY_ARGS_UPDATED, { storyId, args });
}

if (selection.viewMode === 'docs' || parameters.docsOnly) {
Expand Down Expand Up @@ -411,20 +428,20 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew

renderMissingStory() {
this.view.showNoPreview();
this.channel.emit(Events.STORY_MISSING);
this.channel.emit(STORY_MISSING);
}

renderStoryLoadingException(storySpecifier: StorySpecifier, err: Error) {
logger.error(`Unable to load story '${storySpecifier}':`);
logger.error(err);
this.view.showErrorDisplay(err);
this.channel.emit(Events.STORY_MISSING, storySpecifier);
this.channel.emit(STORY_MISSING, storySpecifier);
}

// renderException is used if we fail to render the story and it is uncaught by the app layer
renderException(storyId: StoryId, err: Error) {
this.channel.emit(Events.STORY_THREW_EXCEPTION, err);
this.channel.emit(Events.STORY_RENDER_PHASE_CHANGED, { newPhase: 'errored', storyId });
this.channel.emit(STORY_THREW_EXCEPTION, err);
this.channel.emit(STORY_RENDER_PHASE_CHANGED, { newPhase: 'errored', storyId });

// Ignored exceptions exist for control flow purposes, and are typically handled elsewhere.
if (err !== IGNORED_EXCEPTION) {
Expand All @@ -438,8 +455,8 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
// wrong -- for instance returned the wrong thing from a story
renderError(storyId: StoryId, { title, description }: { title: string; description: string }) {
logger.error(`Error rendering story ${title}: ${description}`);
this.channel.emit(Events.STORY_ERRORED, { title, description });
this.channel.emit(Events.STORY_RENDER_PHASE_CHANGED, { newPhase: 'errored', storyId });
this.channel.emit(STORY_ERRORED, { title, description });
this.channel.emit(STORY_RENDER_PHASE_CHANGED, { newPhase: 'errored', storyId });
this.view.showErrorDisplay({
message: title,
stack: description,
Expand Down

0 comments on commit fae35d3

Please sign in to comment.