@onlook/storybook-plugin 0.4.0-beta.17 → 0.4.0-beta.19

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.
@@ -151,50 +151,6 @@ async function closeBrowser() {
151
151
  var ONLOOK_RENDER_STATE_ATTR = "data-onlook-render-state";
152
152
  var ONLOOK_CONTAINED_CARD_ATTR = "data-onlook-contained-card";
153
153
 
154
- // src/screenshot-service/utils/capture-semaphore/capture-semaphore.ts
155
- function createSemaphore(limit) {
156
- const max = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 1;
157
- let active = 0;
158
- const waiters = [];
159
- const acquire = () => {
160
- if (active < max) {
161
- active += 1;
162
- return Promise.resolve();
163
- }
164
- return new Promise((resolve) => {
165
- waiters.push(() => {
166
- active += 1;
167
- resolve();
168
- });
169
- });
170
- };
171
- const release = () => {
172
- active -= 1;
173
- const next = waiters.shift();
174
- if (next) next();
175
- };
176
- return {
177
- async run(fn) {
178
- await acquire();
179
- try {
180
- return await fn();
181
- } finally {
182
- release();
183
- }
184
- }
185
- };
186
- }
187
- var DEFAULT_CAPTURE_CONCURRENCY = 3;
188
- function resolveConcurrency(raw) {
189
- if (!raw) return DEFAULT_CAPTURE_CONCURRENCY;
190
- const parsed = Number.parseInt(raw, 10);
191
- if (!Number.isInteger(parsed) || parsed < 1) return DEFAULT_CAPTURE_CONCURRENCY;
192
- return parsed;
193
- }
194
- var captureSemaphore = createSemaphore(
195
- resolveConcurrency(process.env.ONLOOK_CAPTURE_CONCURRENCY)
196
- );
197
-
198
154
  // src/screenshot-service/utils/screenshot/screenshot.ts
199
155
  function classifyPreviewSnapshot(s) {
200
156
  if (s.text.includes("Sorry, something went wrong")) return "errored";
@@ -270,89 +226,87 @@ function screenshotExists(storyId, theme) {
270
226
  return fs.existsSync(screenshotPath);
271
227
  }
272
228
  async function captureScreenshotBuffer(storyId, theme, width = VIEWPORT_WIDTH, height = VIEWPORT_HEIGHT, storybookUrl = "http://localhost:6006", loadTimeoutMs = 9e4, renderTimeoutMs = 2e4) {
273
- return captureSemaphore.run(async () => {
274
- const browser = await getBrowser();
275
- const context = await browser.newContext({
276
- viewport: { width, height },
277
- deviceScaleFactor: 2
278
- });
279
- const page = await context.newPage();
229
+ const browser = await getBrowser();
230
+ const context = await browser.newContext({
231
+ viewport: { width, height },
232
+ deviceScaleFactor: 2
233
+ });
234
+ const page = await context.newPage();
235
+ try {
236
+ const url = `${storybookUrl}/iframe.html?id=${storyId}&viewMode=story&globals=theme:${theme}`;
237
+ await page.goto(url, { timeout: loadTimeoutMs });
238
+ await page.waitForLoadState("domcontentloaded", { timeout: loadTimeoutMs });
239
+ await page.waitForLoadState("load", { timeout: loadTimeoutMs });
280
240
  try {
281
- const url = `${storybookUrl}/iframe.html?id=${storyId}&viewMode=story&globals=theme:${theme}`;
282
- await page.goto(url, { timeout: loadTimeoutMs });
283
- await page.waitForLoadState("domcontentloaded", { timeout: loadTimeoutMs });
284
- await page.waitForLoadState("load", { timeout: loadTimeoutMs });
285
- try {
286
- await page.waitForLoadState("networkidle", { timeout: 5e3 });
287
- } catch {
288
- }
289
- const renderState = await detectRenderState(page, { hardCapMs: renderTimeoutMs });
290
- await page.evaluate(() => document.fonts.ready);
291
- try {
292
- await page.evaluate(async () => {
293
- const images = document.querySelectorAll("img");
294
- await Promise.all(
295
- Array.from(images).map((img) => {
296
- if (img.complete) return Promise.resolve();
297
- return new Promise((resolve) => {
298
- img.addEventListener("load", resolve);
299
- img.addEventListener("error", resolve);
300
- setTimeout(resolve, 3e3);
301
- });
302
- })
303
- );
304
- });
305
- } catch {
306
- }
307
- const contentBounds = await page.evaluate(() => {
308
- const root = document.querySelector("#storybook-root");
309
- if (!root) return null;
310
- const children = root.querySelectorAll("*");
311
- if (children.length === 0) return null;
312
- let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
313
- children.forEach((child) => {
314
- const rect = child.getBoundingClientRect();
315
- if (rect.width === 0 || rect.height === 0) return;
316
- minX = Math.min(minX, rect.left);
317
- minY = Math.min(minY, rect.top);
318
- maxX = Math.max(maxX, rect.right);
319
- maxY = Math.max(maxY, rect.bottom);
320
- });
321
- if (minX === Infinity) return null;
322
- return {
323
- x: minX,
324
- y: minY,
325
- width: maxX - minX,
326
- height: maxY - minY
327
- };
241
+ await page.waitForLoadState("networkidle", { timeout: 5e3 });
242
+ } catch {
243
+ }
244
+ const renderState = await detectRenderState(page, { hardCapMs: renderTimeoutMs });
245
+ await page.evaluate(() => document.fonts.ready);
246
+ try {
247
+ await page.evaluate(async () => {
248
+ const images = document.querySelectorAll("img");
249
+ await Promise.all(
250
+ Array.from(images).map((img) => {
251
+ if (img.complete) return Promise.resolve();
252
+ return new Promise((resolve) => {
253
+ img.addEventListener("load", resolve);
254
+ img.addEventListener("error", resolve);
255
+ setTimeout(resolve, 3e3);
256
+ });
257
+ })
258
+ );
328
259
  });
329
- let screenshotBuffer;
330
- let resultBoundingBox = null;
331
- if (contentBounds && contentBounds.width > 0 && contentBounds.height > 0) {
332
- const PADDING = 20;
333
- const clippedWidth = Math.min(width, contentBounds.width + PADDING);
334
- const clippedHeight = Math.min(height, contentBounds.height + PADDING);
335
- resultBoundingBox = {
336
- width: Math.max(MIN_COMPONENT_WIDTH, Math.round(clippedWidth)),
337
- height: Math.max(MIN_COMPONENT_HEIGHT, Math.round(clippedHeight))
338
- };
339
- screenshotBuffer = await page.screenshot({
340
- type: "png",
341
- clip: {
342
- x: Math.max(0, contentBounds.x - 10),
343
- y: Math.max(0, contentBounds.y - 10),
344
- width: clippedWidth,
345
- height: clippedHeight
346
- }
347
- });
348
- } else {
349
- screenshotBuffer = await page.screenshot({ type: "png" });
350
- }
351
- return { buffer: screenshotBuffer, boundingBox: resultBoundingBox, renderState };
352
- } finally {
353
- await context.close();
260
+ } catch {
354
261
  }
355
- });
262
+ const contentBounds = await page.evaluate(() => {
263
+ const root = document.querySelector("#storybook-root");
264
+ if (!root) return null;
265
+ const children = root.querySelectorAll("*");
266
+ if (children.length === 0) return null;
267
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
268
+ children.forEach((child) => {
269
+ const rect = child.getBoundingClientRect();
270
+ if (rect.width === 0 || rect.height === 0) return;
271
+ minX = Math.min(minX, rect.left);
272
+ minY = Math.min(minY, rect.top);
273
+ maxX = Math.max(maxX, rect.right);
274
+ maxY = Math.max(maxY, rect.bottom);
275
+ });
276
+ if (minX === Infinity) return null;
277
+ return {
278
+ x: minX,
279
+ y: minY,
280
+ width: maxX - minX,
281
+ height: maxY - minY
282
+ };
283
+ });
284
+ let screenshotBuffer;
285
+ let resultBoundingBox = null;
286
+ if (contentBounds && contentBounds.width > 0 && contentBounds.height > 0) {
287
+ const PADDING = 20;
288
+ const clippedWidth = Math.min(width, contentBounds.width + PADDING);
289
+ const clippedHeight = Math.min(height, contentBounds.height + PADDING);
290
+ resultBoundingBox = {
291
+ width: Math.max(MIN_COMPONENT_WIDTH, Math.round(clippedWidth)),
292
+ height: Math.max(MIN_COMPONENT_HEIGHT, Math.round(clippedHeight))
293
+ };
294
+ screenshotBuffer = await page.screenshot({
295
+ type: "png",
296
+ clip: {
297
+ x: Math.max(0, contentBounds.x - 10),
298
+ y: Math.max(0, contentBounds.y - 10),
299
+ width: clippedWidth,
300
+ height: clippedHeight
301
+ }
302
+ });
303
+ } else {
304
+ screenshotBuffer = await page.screenshot({ type: "png" });
305
+ }
306
+ return { buffer: screenshotBuffer, boundingBox: resultBoundingBox, renderState };
307
+ } finally {
308
+ await context.close();
309
+ }
356
310
  }
357
311
  async function generateScreenshot(storyId, theme, storybookUrl = "http://localhost:6006", timeoutMs = 3e4) {
358
312
  try {
@@ -49,16 +49,16 @@ interface PackageMockEntry {
49
49
  /**
50
50
  * Named exports the customer actually imports from the package (the union
51
51
  * across story-reachable component sources). The generated mock provides a
52
- * stand-in for each so no `import { X } from '@clerk/nextjs'` produces a Vite
53
- * "no matching export" build error.
52
+ * stand-in for each so no `import { X } from '@clerk/nextjs'` produces a
53
+ * Vite "no matching export" build error. Optional on the wire — the plugin
54
+ * treats an absent list as empty (a customer-edited config may omit it).
54
55
  */
55
- usedExports: string[];
56
+ usedExports?: string[];
56
57
  }
57
58
  /**
58
- * The `packageMock` plugin-options surface. Written by the preflight engine into
59
- * `.storybook/main.*` (`storybookOnlookPlugin({ packageMock })`). Mirrored
60
- * structurally as `PackageMockValue` in
61
- * `packages/preflight/src/checks/storybook/patch.ts` — keep the shapes in sync.
59
+ * The `packageMock` plugin-options surface. Written by the preflight engine
60
+ * into `.storybook/main.*` (`storybookOnlookPlugin({ packageMock })`) and read
61
+ * by the plugin's package-mock Vite plugin factory.
62
62
  */
63
63
  interface PackageMockOptions {
64
64
  packages?: PackageMockEntry[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlook/storybook-plugin",
3
- "version": "0.4.0-beta.17",
3
+ "version": "0.4.0-beta.19",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "onlook-storybook": "./dist/cli/index.js"
@@ -35,7 +35,6 @@
35
35
  "scripts": {
36
36
  "build": "rm -rf dist && tsup",
37
37
  "clean": "git clean -xdf .cache .turbo dist node_modules",
38
- "test": "bun test",
39
38
  "typecheck": "tsc --noEmit",
40
39
  "prepublishOnly": "bun run build && bun scripts/prepublish.ts",
41
40
  "postpublish": "bun scripts/postpublish.ts",
@@ -53,6 +52,7 @@
53
52
  "storybook": "^10.1.11"
54
53
  },
55
54
  "devDependencies": {
55
+ "@onbook/shared": "0.1.0",
56
56
  "@onbook/tsconfig": "0.1.0",
57
57
  "@types/babel__generator": "^7.6.8",
58
58
  "@types/babel__traverse": "^7.20.6",