@onlook/storybook-plugin 0.3.6 → 0.3.7-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,6 @@
1
1
  export { closeBrowser } from './utils/browser/index.js';
2
2
  import 'playwright';
3
3
 
4
- /**
5
- * Generate screenshots for all stories (parallelized for speed)
6
- *
7
- * @param offset - Absolute index offset for logging (e.g. skip=200 → offset=200)
8
- * @param total - Total number of stories across all runs (for [n/total] logging)
9
- */
10
4
  declare function generateAllScreenshots(stories: Array<{
11
5
  id: string;
12
6
  importPath: string;
@@ -1,9 +1,10 @@
1
+ import { createRequire } from 'node:module';
1
2
  import crypto from 'crypto';
2
3
  import fs from 'fs';
3
4
  import path from 'path';
4
5
  import { chromium } from 'playwright';
5
6
 
6
- // src/utils/fileSystem/fileSystem.ts
7
+ globalThis.require = createRequire(import.meta.url);
7
8
  var CACHE_DIR = path.join(process.cwd(), ".storybook-cache");
8
9
  var SCREENSHOTS_DIR = path.join(CACHE_DIR, "screenshots");
9
10
  var MANIFEST_PATH = path.join(CACHE_DIR, "manifest.json");
@@ -188,6 +189,33 @@ async function generateScreenshot(storyId, theme, storybookUrl = "http://localho
188
189
  }
189
190
 
190
191
  // src/screenshot-service/screenshot-service.ts
192
+ var StoryTimeoutError = class extends Error {
193
+ constructor(storyId, timeoutMs) {
194
+ super(`Story ${storyId} timed out after ${timeoutMs / 1e3}s`);
195
+ this.storyId = storyId;
196
+ this.timeoutMs = timeoutMs;
197
+ this.name = "StoryTimeoutError";
198
+ }
199
+ };
200
+ async function captureBothThemes(storyId, storybookUrl, timeoutMs, storyTimeoutMs) {
201
+ let timer;
202
+ try {
203
+ return await Promise.race([
204
+ Promise.all([
205
+ generateScreenshot(storyId, "light", storybookUrl, timeoutMs),
206
+ generateScreenshot(storyId, "dark", storybookUrl, timeoutMs)
207
+ ]),
208
+ new Promise((_, reject) => {
209
+ timer = setTimeout(
210
+ () => reject(new StoryTimeoutError(storyId, storyTimeoutMs)),
211
+ storyTimeoutMs
212
+ );
213
+ })
214
+ ]);
215
+ } finally {
216
+ if (timer) clearTimeout(timer);
217
+ }
218
+ }
191
219
  async function generateAllScreenshots(stories, storybookUrl = "http://localhost:6006", concurrency = 10, offset = 0, total, skipExisting = false, timeoutMs = 3e4) {
192
220
  const displayTotal = total ?? offset + stories.length;
193
221
  console.log(
@@ -198,53 +226,74 @@ async function generateAllScreenshots(stories, storybookUrl = "http://localhost:
198
226
  for (let i = 0; i < stories.length; i += BATCH_SIZE) {
199
227
  batches.push(stories.slice(i, i + BATCH_SIZE));
200
228
  }
229
+ const storyTimeout = timeoutMs * 2 + 1e4;
201
230
  let completed = 0;
202
231
  for (const batch of batches) {
203
232
  await Promise.all(
204
233
  batch.map(async (story) => {
205
234
  if (skipExisting && screenshotExists(story.id, "light") && screenshotExists(story.id, "dark")) {
206
235
  completed++;
207
- const absoluteIndex = offset + completed;
208
- console.log(`[${absoluteIndex}/${displayTotal}] Skipped (exists) ${story.id}`);
236
+ const absoluteIndex2 = offset + completed;
237
+ console.log(`[${absoluteIndex2}/${displayTotal}] Skipped (exists) ${story.id}`);
209
238
  return;
210
239
  }
211
- const storyTimeout = timeoutMs * 2 + 1e4;
212
- let timer;
213
- try {
214
- const result = await Promise.race([
215
- Promise.all([
216
- generateScreenshot(story.id, "light", storybookUrl, timeoutMs),
217
- generateScreenshot(story.id, "dark", storybookUrl, timeoutMs)
218
- ]),
219
- new Promise((_, reject) => {
220
- timer = setTimeout(
221
- () => reject(
222
- new Error(
223
- `Story ${story.id} timed out after ${storyTimeout / 1e3}s`
224
- )
225
- ),
226
- storyTimeout
227
- );
228
- })
229
- ]);
230
- clearTimeout(timer);
231
- const [lightResult, darkResult] = result;
232
- if (lightResult && darkResult) {
233
- const fileHash = computeFileHash(story.importPath);
234
- updateManifest(story.id, story.importPath, fileHash, lightResult.boundingBox);
240
+ let lightResult = null;
241
+ let darkResult = null;
242
+ let lastError;
243
+ const startedAt = Date.now();
244
+ let attempts = 0;
245
+ const maxAttempts = 2;
246
+ while (attempts < maxAttempts) {
247
+ attempts++;
248
+ try {
249
+ [lightResult, darkResult] = await captureBothThemes(
250
+ story.id,
251
+ storybookUrl,
252
+ timeoutMs,
253
+ storyTimeout
254
+ );
255
+ lastError = void 0;
256
+ break;
257
+ } catch (error) {
258
+ lastError = error;
259
+ if (!(error instanceof StoryTimeoutError) || attempts >= maxAttempts) {
260
+ break;
261
+ }
262
+ console.warn(
263
+ `[screenshot] Retrying ${story.id} after timeout (attempt ${attempts + 1}/${maxAttempts})`
264
+ );
235
265
  }
236
- completed++;
237
- const absoluteIndex = offset + completed;
266
+ }
267
+ completed++;
268
+ const absoluteIndex = offset + completed;
269
+ const durationMs = Date.now() - startedAt;
270
+ if (lightResult && darkResult) {
271
+ const fileHash = computeFileHash(story.importPath);
272
+ updateManifest(story.id, story.importPath, fileHash, lightResult.boundingBox);
238
273
  console.log(
239
- `[${absoluteIndex}/${displayTotal}] Generated screenshots for ${story.id}`
274
+ `[${absoluteIndex}/${displayTotal}] Generated screenshots for ${story.id}`,
275
+ { storyId: story.id, attempts, durationMs, outcome: "ok" }
240
276
  );
241
- } catch (error) {
242
- completed++;
243
- const absoluteIndex = offset + completed;
277
+ } else if (lastError) {
244
278
  console.error(
245
279
  `[${absoluteIndex}/${displayTotal}] \u26A0\uFE0F Failed ${story.id}:`,
246
- error instanceof Error ? error.message : error
280
+ lastError instanceof Error ? lastError.message : lastError,
281
+ {
282
+ storyId: story.id,
283
+ attempts,
284
+ durationMs,
285
+ outcome: lastError instanceof StoryTimeoutError ? "timeout" : "error"
286
+ }
247
287
  );
288
+ } else {
289
+ console.warn(`[${absoluteIndex}/${displayTotal}] Partial result ${story.id}`, {
290
+ storyId: story.id,
291
+ attempts,
292
+ durationMs,
293
+ outcome: "partial",
294
+ hasLight: !!lightResult,
295
+ hasDark: !!darkResult
296
+ });
248
297
  }
249
298
  })
250
299
  );
@@ -1,6 +1,7 @@
1
+ import { createRequire } from 'node:module';
1
2
  import { chromium } from 'playwright';
2
3
 
3
- // src/screenshot-service/utils/browser/browser.ts
4
+ globalThis.require = createRequire(import.meta.url);
4
5
  var browser = null;
5
6
  async function getBrowser() {
6
7
  if (!browser) {
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@onlook/storybook-plugin",
3
- "version": "0.3.6",
3
+ "version": "0.3.7-beta.0",
4
4
  "type": "module",
5
5
  "bin": {
6
- "onlook-storybook": "dist/cli/index.js"
6
+ "onlook-storybook": "./dist/cli/index.js"
7
7
  },
8
8
  "exports": {
9
9
  ".": {
@@ -29,9 +29,8 @@
29
29
  "typecheck": "tsc --noEmit",
30
30
  "prepublishOnly": "bun run build && bun scripts/prepublish.ts",
31
31
  "postpublish": "bun scripts/postpublish.ts",
32
- "publish-pkg": "npm publish",
33
- "publish-pkg:next": "npm publish --tag next",
34
- "promote-latest": "npm dist-tag add @onlook/storybook-plugin@$(node -p \"require('./package.json').version\") latest"
32
+ "publish-pkg": "bun publish",
33
+ "publish-beta": "bun publish --tag beta"
35
34
  },
36
35
  "dependencies": {
37
36
  "@babel/generator": "^7.26.9",
@@ -39,15 +38,16 @@
39
38
  "@babel/traverse": "^7.26.9",
40
39
  "@babel/types": "^7.26.9",
41
40
  "@drizzle-team/brocli": "^0.11.0",
42
- "playwright": "^1.52.0"
41
+ "@liveblocks/client": "3.11.0",
42
+ "playwright": "^1.52.0",
43
+ "ws": "^8.18.0"
43
44
  },
44
45
  "devDependencies": {
45
- "@onbook/tsconfig": "workspace:*",
46
+ "@onbook/tsconfig": "0.1.0",
46
47
  "@types/babel__generator": "^7.6.8",
47
48
  "@types/babel__traverse": "^7.20.6",
48
49
  "@types/node": "^22.15.32",
49
50
  "bun-types": "^1.3.5",
50
- "storybook": "^10.1.11",
51
51
  "tsup": "^8.5.1",
52
52
  "typescript": "5.8.3",
53
53
  "vite": "^6.3.5"
@@ -56,7 +56,6 @@
56
56
  "access": "public"
57
57
  },
58
58
  "peerDependencies": {
59
- "storybook": "^10.0.0",
60
59
  "vite": "^5.0.0 || ^6.0.0"
61
60
  }
62
61
  }