diff --git a/MIGRATION.md b/MIGRATION.md
index b168c0931fcd..15b17681953b 100644
--- a/MIGRATION.md
+++ b/MIGRATION.md
@@ -28,6 +28,7 @@
- [Removed stories.json](#removed-storiesjson)
- [Removed `sb babelrc` command](#removed-sb-babelrc-command)
- [Changed interfaces for `@storybook/router` components](#changed-interfaces-for-storybookrouter-components)
+ - [Extract no longer batches](#extract-no-longer-batches)
- [Framework-specific changes](#framework-specific-changes)
- [React](#react)
- [`react-docgen` component analysis by default](#react-docgen-component-analysis-by-default)
@@ -712,6 +713,10 @@ The reasoning behind is to condense and provide some clarity to what's happened
The `hideOnly` prop has been removed from the `` component in `@storybook/router`. If needed this can be implemented manually with the `` component.
+#### Extract no longer batches
+
+`Preview.extract()` no longer loads CSF files in batches. This was a workaround for resource limitations that slowed down extract. This shouldn't affect behaviour.
+
### Framework-specific changes
#### React
diff --git a/code/lib/preview-api/src/modules/store/StoryStore.test.ts b/code/lib/preview-api/src/modules/store/StoryStore.test.ts
index 7d796970b560..65f225c8ef6e 100644
--- a/code/lib/preview-api/src/modules/store/StoryStore.test.ts
+++ b/code/lib/preview-api/src/modules/store/StoryStore.test.ts
@@ -28,14 +28,6 @@ vi.mock('@storybook/global', async (importOriginal) => ({
vi.mock('@storybook/client-logger');
-const createGate = (): [Promise, (_?: any) => void] => {
- let openGate = (_?: any) => {};
- const gate = new Promise((resolve) => {
- openGate = resolve;
- });
- return [gate, openGate];
-};
-
const componentOneExports = {
default: { title: 'Component One' },
a: { args: { foo: 'a' } },
@@ -435,22 +427,6 @@ describe('StoryStore', () => {
'./src/ComponentTwo.stories.js',
]);
});
-
- it('imports in batches', async () => {
- const [gate, openGate] = createGate();
- const blockedImportFn = vi.fn(async (file) => {
- await gate;
- return importFn(file);
- });
- const store = new StoryStore(storyIndex, blockedImportFn, projectAnnotations);
-
- const promise = store.loadAllCSFFiles({ batchSize: 1 });
- expect(blockedImportFn).toHaveBeenCalledTimes(1);
-
- openGate();
- await promise;
- expect(blockedImportFn).toHaveBeenCalledTimes(3);
- });
});
describe('extract', () => {
diff --git a/code/lib/preview-api/src/modules/store/StoryStore.ts b/code/lib/preview-api/src/modules/store/StoryStore.ts
index c779f13ddd2c..123ea5b984c8 100644
--- a/code/lib/preview-api/src/modules/store/StoryStore.ts
+++ b/code/lib/preview-api/src/modules/store/StoryStore.ts
@@ -41,9 +41,9 @@ import {
prepareContext,
} from './csf';
+// TODO -- what are reasonable values for these?
const CSF_CACHE_SIZE = 1000;
const STORY_CACHE_SIZE = 10000;
-const EXTRACT_BATCH_SIZE = 20;
export class StoryStore {
public storyIndex: StoryIndexStore;
@@ -127,32 +127,19 @@ export class StoryStore {
return this.processCSFFileWithCache(moduleExports, importPath, title);
}
- async loadAllCSFFiles({ batchSize = EXTRACT_BATCH_SIZE } = {}): Promise<
- StoryStore['cachedCSFFiles']
- > {
- const importPaths = Object.entries(this.storyIndex.entries).map(([storyId, { importPath }]) => [
- importPath,
- storyId,
- ]);
-
- const loadInBatches = async (
- remainingImportPaths: typeof importPaths
- ): Promise<{ importPath: Path; csfFile: CSFFile }[]> => {
- if (remainingImportPaths.length === 0) return Promise.resolve([]);
-
- const csfFilePromiseList = remainingImportPaths
- .slice(0, batchSize)
- .map(async ([importPath, storyId]) => ({
- importPath,
- csfFile: await this.loadCSFFileByStoryId(storyId),
- }));
-
- const firstResults = await Promise.all(csfFilePromiseList);
- const restResults = await loadInBatches(remainingImportPaths.slice(batchSize));
- return firstResults.concat(restResults);
- };
+ async loadAllCSFFiles(): Promise['cachedCSFFiles']> {
+ const importPaths: Record = {};
+ Object.entries(this.storyIndex.entries).forEach(([storyId, { importPath }]) => {
+ importPaths[importPath] = storyId;
+ });
+
+ const list = await Promise.all(
+ Object.entries(importPaths).map(async ([importPath, storyId]) => ({
+ importPath,
+ csfFile: await this.loadCSFFileByStoryId(storyId),
+ }))
+ );
- const list = await loadInBatches(importPaths);
return list.reduce(
(acc, { importPath, csfFile }) => {
acc[importPath] = csfFile;