@weasel-js/forge 1.11.0 → 1.11.1
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/README.md +2 -1
- package/dist/{FrameController-BRhShqut.d.ts → FrameController-Cj_i-Rdk.d.ts} +18 -10
- package/dist/{chunk-R5F44ECM.js → chunk-BKPDKUDN.js} +13 -12
- package/dist/chunk-BKPDKUDN.js.map +1 -0
- package/dist/{chunk-J3GYSNCK.js → chunk-FZNABWJC.js} +12 -15
- package/dist/chunk-FZNABWJC.js.map +1 -0
- package/dist/{chunk-2OJAV522.js → chunk-GH5RE5X5.js} +2 -2
- package/dist/chunk-GH5RE5X5.js.map +1 -0
- package/dist/{chunk-NVNTQ4AT.js → chunk-JTCUIJPZ.js} +87 -5
- package/dist/chunk-JTCUIJPZ.js.map +1 -0
- package/dist/{chunk-SQ4KCIEH.js → chunk-KEQBGDUZ.js} +3 -3
- package/dist/{chunk-SQ4KCIEH.js.map → chunk-KEQBGDUZ.js.map} +1 -1
- package/dist/{chunk-DPTECNYC.js → chunk-LTTEILXY.js} +3 -3
- package/dist/{chunk-DPTECNYC.js.map → chunk-LTTEILXY.js.map} +1 -1
- package/dist/{config-BwScQukB.d.ts → config-DN6IaNf6.d.ts} +3 -3
- package/dist/csf/preview-api.js +2 -2
- package/dist/frame/index.css +1 -0
- package/dist/frame/index.css.map +1 -1
- package/dist/frame/index.d.ts +2 -2
- package/dist/frame/index.js +10 -11
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/shell/index.css +15 -6
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +5 -13
- package/dist/shell/index.js +104 -32
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.d.ts +2 -4
- package/dist/test/index.js +9 -11
- package/dist/test/index.js.map +1 -1
- package/dist/vite/index.js +14 -5
- package/dist/vite/index.js.map +1 -1
- package/package.json +8 -8
- package/dist/chunk-2OJAV522.js.map +0 -1
- package/dist/chunk-J3GYSNCK.js.map +0 -1
- package/dist/chunk-NVNTQ4AT.js.map +0 -1
- package/dist/chunk-R5F44ECM.js.map +0 -1
package/dist/test/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FrameSetup } from '../FrameController-
|
|
1
|
+
import { F as FrameSetup } from '../FrameController-Cj_i-Rdk.js';
|
|
2
2
|
import '@weasel-js/icons';
|
|
3
3
|
import '@weasel-js/labkit/config';
|
|
4
4
|
import 'react';
|
|
@@ -7,8 +7,6 @@ import 'react';
|
|
|
7
7
|
interface RunStoryOptions {
|
|
8
8
|
/** The frame config (`frameConfig`). */
|
|
9
9
|
setup?: FrameSetup;
|
|
10
|
-
/** Resizes the page, for a story that names a viewport. Without it, stories run at whatever size the page is. */
|
|
11
|
-
viewport?: (width: number, height: number) => Promise<void>;
|
|
12
10
|
}
|
|
13
11
|
/**
|
|
14
12
|
* Renders one story in the test page the way the workshop does — defaults, no state, no globals — then plays it.
|
|
@@ -16,6 +14,6 @@ interface RunStoryOptions {
|
|
|
16
14
|
*/
|
|
17
15
|
declare function runStory(mod: Record<string, unknown>, exportName: string, file: string,
|
|
18
16
|
/** The file's index entry title. */
|
|
19
|
-
title: string, { setup
|
|
17
|
+
title: string, { setup }?: RunStoryOptions): Promise<void>;
|
|
20
18
|
|
|
21
19
|
export { type RunStoryOptions, runStory };
|
package/dist/test/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { StoryTrial } from '../chunk-
|
|
1
|
+
import { StoryTrial } from '../chunk-FZNABWJC.js';
|
|
2
2
|
import '../chunk-7BQPHMA2.js';
|
|
3
|
-
import { loadStories } from '../chunk-
|
|
3
|
+
import { loadStories } from '../chunk-JTCUIJPZ.js';
|
|
4
4
|
import '../chunk-L5XM5VKB.js';
|
|
5
5
|
import '../chunk-ZAWXMUGZ.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-KEQBGDUZ.js';
|
|
7
|
+
import '../chunk-GH5RE5X5.js';
|
|
8
8
|
import { withValueAtPath } from '@weasel-js/labkit/config';
|
|
9
9
|
import { useState, useEffect } from 'react';
|
|
10
10
|
import { createRoot } from 'react-dom/client';
|
|
@@ -32,8 +32,7 @@ function TestTrial({ story, setup, hostRef, onConfig, onRendered, onError }) {
|
|
|
32
32
|
return /* @__PURE__ */ jsx(StoryTrial, { story, setup, ctx, hostRef, onRendered, onError });
|
|
33
33
|
}
|
|
34
34
|
var leftover = null;
|
|
35
|
-
|
|
36
|
-
async function runStory(mod, exportName, file, title, { setup = {}, viewport } = {}) {
|
|
35
|
+
async function runStory(mod, exportName, file, title, { setup = {} } = {}) {
|
|
37
36
|
leftover?.();
|
|
38
37
|
let story;
|
|
39
38
|
try {
|
|
@@ -42,12 +41,11 @@ async function runStory(mod, exportName, file, title, { setup = {}, viewport } =
|
|
|
42
41
|
throw phased("load", error);
|
|
43
42
|
}
|
|
44
43
|
if (!story) throw new Error(`load fault: ${file} has no story export "${exportName}"`);
|
|
45
|
-
pageSize ??= { width: window.innerWidth, height: window.innerHeight };
|
|
46
|
-
const size = story.viewport ?? pageSize;
|
|
47
|
-
if (viewport && (window.innerWidth !== size.width || window.innerHeight !== size.height)) {
|
|
48
|
-
await viewport(size.width, size.height);
|
|
49
|
-
}
|
|
50
44
|
const container = document.createElement("div");
|
|
45
|
+
if (story.viewport) {
|
|
46
|
+
container.style.width = `${story.viewport.width}px`;
|
|
47
|
+
container.style.height = `${story.viewport.height}px`;
|
|
48
|
+
}
|
|
51
49
|
document.body.append(container);
|
|
52
50
|
let root;
|
|
53
51
|
const cleanup = () => {
|
package/dist/test/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/runStory.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { withValueAtPath } from '@weasel-js/labkit/config';\nimport { type RefObject, useEffect, useState } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { FrameSetup } from '../frame/FrameController';\nimport type { Viewport } from '../protocol/messages';\nimport { StoryTrial } from '../shell/StoryTrial';\nimport { loadStories } from '../story/load';\nimport type { LoadedStory } from '../story/types';\n\n/** Prefixes `error` with the phase it came from, keeping its stack. */\nfunction phased(phase: string, error: unknown): Error {\n const message = error instanceof Error ? error.message : String(error);\n const out = new Error(`${phase} fault: ${message}`, { cause: error });\n if (error instanceof Error && error.stack) out.stack = `${phase} fault: ${error.stack}`;\n return out;\n}\n\nconst settle = () =>\n new Promise<void>((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n\ninterface TestTrialProps {\n story: LoadedStory;\n setup: FrameSetup;\n hostRef: RefObject<HTMLElement | null>;\n /** The config in force after each commit, so `play` reads what the story last wrote. */\n onConfig: (config: unknown) => void;\n onRendered: () => void;\n onError: (error: unknown) => void;\n}\n\n/** The trial a story test runs in: its config and state, held the way a lab trial holds them. */\nfunction TestTrial({ story, setup, hostRef, onConfig, onRendered, onError }: TestTrialProps) {\n const [config, setConfigState] = useState<unknown>(() => story.config.defaults());\n const [state, setState] = useState<unknown>(null);\n useEffect(() => onConfig(config), [config, onConfig]);\n const ctx = {\n config,\n state,\n setConfig: (path: string, value: unknown) => setConfigState((prev: unknown) => withValueAtPath(prev, path, value)),\n setState,\n };\n return <StoryTrial story={story} setup={setup} ctx={ctx} hostRef={hostRef} onRendered={onRendered} onError={onError} />;\n}\n\n/** Options for `runStory`. */\nexport interface RunStoryOptions {\n /** The frame config (`frameConfig`). */\n setup?: FrameSetup;\n /** Resizes the page, for a story that names a viewport. Without it, stories run at whatever size the page is. */\n viewport?: (width: number, height: number) => Promise<void>;\n}\n\n/** Stops the story a timed-out test left mounted. */\nlet leftover: (() => unknown) | null = null;\n/** The page's size before any story resized it; a story with no viewport runs at this size. */\nlet pageSize: Viewport | null = null;\n\n/**\n * Renders one story in the test page the way the workshop does — defaults, no state, no globals — then plays it.\n * Throws on a render the story's boundary caught, or a play function that fails.\n */\nexport async function runStory(\n mod: Record<string, unknown>,\n exportName: string,\n file: string,\n /** The file's index entry title. */\n title: string,\n { setup = {}, viewport }: RunStoryOptions = {},\n): Promise<void> {\n leftover?.();\n let story: LoadedStory | undefined;\n try {\n story = loadStories(mod, title, setup.parameters).find((s) => s.exportName === exportName);\n } catch (error) {\n throw phased('load', error);\n }\n if (!story) throw new Error(`load fault: ${file} has no story export \"${exportName}\"`);\n\n pageSize ??= { width: window.innerWidth, height: window.innerHeight };\n const size = story.viewport ?? pageSize;\n if (viewport && (window.innerWidth !== size.width || window.innerHeight !== size.height)) {\n await viewport(size.width, size.height);\n }\n\n const container = document.createElement('div');\n document.body.append(container);\n let root: Root | undefined;\n /** Returns what unmounting threw, having released everything else regardless. */\n const cleanup = (): { error: unknown } | null => {\n if (leftover === cleanup) leftover = null;\n let thrown: { error: unknown } | null = null;\n try {\n root?.unmount();\n } catch (error) {\n thrown = { error };\n } finally {\n root = undefined;\n container.remove();\n }\n return thrown;\n };\n leftover = cleanup;\n\n const hostRef: RefObject<HTMLElement | null> = { current: null };\n let config: unknown;\n let renderError: { error: unknown } | null = null;\n let markRendered: () => void = () => {};\n const rendered = new Promise<void>((resolve) => {\n markRendered = resolve;\n });\n const fail = (error: unknown) => {\n renderError ??= { error };\n // An error the boundary could not catch leaves nothing to announce `rendered`; the check below throws instead.\n markRendered();\n };\n const checkRender = () => {\n if (renderError) throw phased('render', renderError.error);\n };\n\n let failure: { error: unknown } | null = null;\n try {\n try {\n await setup.prepare?.(story);\n root = createRoot(container, { onUncaughtError: fail });\n root.render(\n <TestTrial\n story={story}\n setup={setup}\n hostRef={hostRef}\n onConfig={(next) => {\n config = next;\n }}\n onRendered={markRendered}\n onError={fail}\n />,\n );\n } catch (error) {\n throw phased('mount', error);\n }\n await rendered;\n await settle();\n checkRender();\n const host = hostRef.current;\n if (!host) throw new Error('render fault: the story host never mounted');\n if (story.play) {\n try {\n await story.play({ canvasElement: host, config, globals: {} });\n } catch (error) {\n throw phased('play', error);\n }\n await settle();\n checkRender();\n }\n } catch (error) {\n failure = { error };\n }\n const cleanupError = cleanup();\n if (failure) throw failure.error;\n if (cleanupError) throw phased('cleanup', cleanupError.error);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/test/runStory.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { withValueAtPath } from '@weasel-js/labkit/config';\nimport { type RefObject, useEffect, useState } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { FrameSetup } from '../frame/FrameController';\nimport { StoryTrial } from '../shell/StoryTrial';\nimport { loadStories } from '../story/load';\nimport type { LoadedStory } from '../story/types';\n\n/** Prefixes `error` with the phase it came from, keeping its stack. */\nfunction phased(phase: string, error: unknown): Error {\n const message = error instanceof Error ? error.message : String(error);\n const out = new Error(`${phase} fault: ${message}`, { cause: error });\n if (error instanceof Error && error.stack) out.stack = `${phase} fault: ${error.stack}`;\n return out;\n}\n\nconst settle = () =>\n new Promise<void>((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n\ninterface TestTrialProps {\n story: LoadedStory;\n setup: FrameSetup;\n hostRef: RefObject<HTMLElement | null>;\n /** The config in force after each commit, so `play` reads what the story last wrote. */\n onConfig: (config: unknown) => void;\n onRendered: () => void;\n onError: (error: unknown) => void;\n}\n\n/** The trial a story test runs in: its config and state, held the way a lab trial holds them. */\nfunction TestTrial({ story, setup, hostRef, onConfig, onRendered, onError }: TestTrialProps) {\n const [config, setConfigState] = useState<unknown>(() => story.config.defaults());\n const [state, setState] = useState<unknown>(null);\n useEffect(() => onConfig(config), [config, onConfig]);\n const ctx = {\n config,\n state,\n setConfig: (path: string, value: unknown) => setConfigState((prev: unknown) => withValueAtPath(prev, path, value)),\n setState,\n };\n return <StoryTrial story={story} setup={setup} ctx={ctx} hostRef={hostRef} onRendered={onRendered} onError={onError} />;\n}\n\n/** Options for `runStory`. */\nexport interface RunStoryOptions {\n /** The frame config (`frameConfig`). */\n setup?: FrameSetup;\n}\n\n/** Stops the story a timed-out test left mounted. */\nlet leftover: (() => unknown) | null = null;\n\n/**\n * Renders one story in the test page the way the workshop does — defaults, no state, no globals — then plays it.\n * Throws on a render the story's boundary caught, or a play function that fails.\n */\nexport async function runStory(\n mod: Record<string, unknown>,\n exportName: string,\n file: string,\n /** The file's index entry title. */\n title: string,\n { setup = {} }: RunStoryOptions = {},\n): Promise<void> {\n leftover?.();\n let story: LoadedStory | undefined;\n try {\n story = loadStories(mod, title, setup.parameters).find((s) => s.exportName === exportName);\n } catch (error) {\n throw phased('load', error);\n }\n if (!story) throw new Error(`load fault: ${file} has no story export \"${exportName}\"`);\n\n const container = document.createElement('div');\n // The workshop gives a story's viewport to its stage, a box of that size, not to the window.\n if (story.viewport) {\n container.style.width = `${story.viewport.width}px`;\n container.style.height = `${story.viewport.height}px`;\n }\n document.body.append(container);\n let root: Root | undefined;\n /** Returns what unmounting threw, having released everything else regardless. */\n const cleanup = (): { error: unknown } | null => {\n if (leftover === cleanup) leftover = null;\n let thrown: { error: unknown } | null = null;\n try {\n root?.unmount();\n } catch (error) {\n thrown = { error };\n } finally {\n root = undefined;\n container.remove();\n }\n return thrown;\n };\n leftover = cleanup;\n\n const hostRef: RefObject<HTMLElement | null> = { current: null };\n let config: unknown;\n let renderError: { error: unknown } | null = null;\n let markRendered: () => void = () => {};\n const rendered = new Promise<void>((resolve) => {\n markRendered = resolve;\n });\n const fail = (error: unknown) => {\n renderError ??= { error };\n // An error the boundary could not catch leaves nothing to announce `rendered`; the check below throws instead.\n markRendered();\n };\n const checkRender = () => {\n if (renderError) throw phased('render', renderError.error);\n };\n\n let failure: { error: unknown } | null = null;\n try {\n try {\n await setup.prepare?.(story);\n root = createRoot(container, { onUncaughtError: fail });\n root.render(\n <TestTrial\n story={story}\n setup={setup}\n hostRef={hostRef}\n onConfig={(next) => {\n config = next;\n }}\n onRendered={markRendered}\n onError={fail}\n />,\n );\n } catch (error) {\n throw phased('mount', error);\n }\n await rendered;\n await settle();\n checkRender();\n const host = hostRef.current;\n if (!host) throw new Error('render fault: the story host never mounted');\n if (story.play) {\n try {\n await story.play({ canvasElement: host, config, globals: {} });\n } catch (error) {\n throw phased('play', error);\n }\n await settle();\n checkRender();\n }\n } catch (error) {\n failure = { error };\n }\n const cleanupError = cleanup();\n if (failure) throw failure.error;\n if (cleanupError) throw phased('cleanup', cleanupError.error);\n}\n"]}
|
package/dist/vite/index.js
CHANGED
|
@@ -344,7 +344,13 @@ function fileDates(log, paths) {
|
|
|
344
344
|
const name = files.at(-1);
|
|
345
345
|
const path = name === void 0 ? void 0 : names.get(name);
|
|
346
346
|
if (!status || name === void 0 || path === void 0) continue;
|
|
347
|
-
|
|
347
|
+
const newer = out.get(path);
|
|
348
|
+
out.set(path, {
|
|
349
|
+
created: date,
|
|
350
|
+
modified: newer?.modified ?? date,
|
|
351
|
+
createdBy: commit,
|
|
352
|
+
modifiedBy: newer?.modifiedBy ?? commit
|
|
353
|
+
});
|
|
348
354
|
const renamed = status.startsWith("R") ? files[0] : void 0;
|
|
349
355
|
if (status === "A" || renamed !== void 0) names.delete(name);
|
|
350
356
|
if (renamed !== void 0) names.set(renamed, path);
|
|
@@ -384,11 +390,16 @@ function createHistoryReader(root, git = runGit) {
|
|
|
384
390
|
const history = {};
|
|
385
391
|
for (const [name, paths] of byPackage) {
|
|
386
392
|
const refs = ["v[0-9]*", "[0-9]*", ...name === null ? [] : [`${name}@[0-9]*`]].map((ref) => `--refs=${ref}`);
|
|
387
|
-
const commits = paths.
|
|
393
|
+
const commits = paths.flatMap((path) => [dates.get(path).createdBy, dates.get(path).modifiedBy]);
|
|
388
394
|
const named = (await git(["name-rev", "--tags", "--name-only", ...refs, ...commits], top)).split("\n");
|
|
389
395
|
paths.forEach((path, i) => {
|
|
390
396
|
const { created, modified } = dates.get(path);
|
|
391
|
-
history[inRepo.get(path)] = {
|
|
397
|
+
history[inRepo.get(path)] = {
|
|
398
|
+
created,
|
|
399
|
+
modified,
|
|
400
|
+
introduced: versionOf(named[2 * i] ?? ""),
|
|
401
|
+
modifiedIn: versionOf(named[2 * i + 1] ?? "")
|
|
402
|
+
};
|
|
392
403
|
});
|
|
393
404
|
}
|
|
394
405
|
return history;
|
|
@@ -1540,7 +1551,6 @@ function forgeTest(options) {
|
|
|
1540
1551
|
const lines = [
|
|
1541
1552
|
"",
|
|
1542
1553
|
`import { test as __forge_test } from "vitest";`,
|
|
1543
|
-
`import { page as __forge_page } from "vitest/browser";`,
|
|
1544
1554
|
`import { runStory as __forge_runStory } from "@weasel-js/forge/test";`,
|
|
1545
1555
|
// shell.css draws the story host; frame.css still holds the boundary's fault rule.
|
|
1546
1556
|
`import "@weasel-js/forge/shell.css";`,
|
|
@@ -1551,7 +1561,6 @@ function forgeTest(options) {
|
|
|
1551
1561
|
`const __forge_timeout = ${TIMEOUT_MS};`,
|
|
1552
1562
|
"const __forge_options = {",
|
|
1553
1563
|
` setup: ${options.frameConfig ? "__forge_frame_config" : "undefined"},`,
|
|
1554
|
-
" viewport: (width, height) => __forge_page.viewport(width, height),",
|
|
1555
1564
|
"};",
|
|
1556
1565
|
"const __forge_run = async (exportName) => __forge_runStory(await import(/* @vite-ignore */ import.meta.url), exportName, __forge_file, __forge_title, __forge_options);",
|
|
1557
1566
|
// An isolated story asks for a document of its own, which the test page is not; its reason goes in the name.
|