@weasel-js/forge 1.5.2 → 1.6.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.
- package/README.md +72 -10
- package/dist/{FrameController-eZM3hlcE.d.ts → FrameController-BspC9Zr5.d.ts} +61 -4
- package/dist/chunk-A4JOEGYQ.js +325 -0
- package/dist/chunk-A4JOEGYQ.js.map +1 -0
- package/dist/{chunk-5YHEO26U.js → chunk-FWPBKKYB.js} +58 -240
- package/dist/chunk-FWPBKKYB.js.map +1 -0
- package/dist/{chunk-6SRQIHJQ.js → chunk-HRGPFQBW.js} +3 -3
- package/dist/{chunk-6SRQIHJQ.js.map → chunk-HRGPFQBW.js.map} +1 -1
- package/dist/chunk-PO5JLVYT.js +318 -0
- package/dist/chunk-PO5JLVYT.js.map +1 -0
- package/dist/{chunk-TLO6UHF2.js → chunk-VEKEBILL.js} +17 -4
- package/dist/chunk-VEKEBILL.js.map +1 -0
- package/dist/{config-CSVP6duU.d.ts → config-DU_WuORS.d.ts} +7 -1
- package/dist/csf/preview-api.js +1 -2
- package/dist/csf/preview-api.js.map +1 -1
- package/dist/frame/index.css +102 -0
- package/dist/frame/index.css.map +1 -1
- package/dist/frame/index.d.ts +11 -3
- package/dist/frame/index.js +365 -5
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js.map +1 -1
- package/dist/shell/index.css +96 -19
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +75 -15
- package/dist/shell/index.js +762 -214
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.d.ts +3 -3
- package/dist/test/index.js +67 -72
- package/dist/test/index.js.map +1 -1
- package/dist/vite/index.js +43 -5
- package/dist/vite/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/chunk-2JDYOBWM.js +0 -118
- package/dist/chunk-2JDYOBWM.js.map +0 -1
- package/dist/chunk-5YHEO26U.js.map +0 -1
- package/dist/chunk-FTFR2YPM.js +0 -13
- package/dist/chunk-FTFR2YPM.js.map +0 -1
- package/dist/chunk-TLO6UHF2.js.map +0 -1
package/dist/frame/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FrameSetup, L as LoadedStory } from '../FrameController-
|
|
2
|
-
export {
|
|
1
|
+
import { F as FrameSetup, L as LoadedStory } from '../FrameController-BspC9Zr5.js';
|
|
2
|
+
export { k as StartFrameOptions, r as reportImportFault, s as startFrame } from '../FrameController-BspC9Zr5.js';
|
|
3
3
|
import '@weasel-js/labkit/config';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
@@ -12,6 +12,10 @@ interface FrameIndexEntry {
|
|
|
12
12
|
title: string;
|
|
13
13
|
file: string;
|
|
14
14
|
exportName: string;
|
|
15
|
+
/** The JSDoc above the story's export, which its index page shows. */
|
|
16
|
+
description?: string;
|
|
17
|
+
/** The JSDoc above the file's meta, which heads the index page. */
|
|
18
|
+
componentDescription?: string;
|
|
15
19
|
}
|
|
16
20
|
interface MountFrameOptions {
|
|
17
21
|
index: readonly FrameIndexEntry[];
|
|
@@ -19,7 +23,11 @@ interface MountFrameOptions {
|
|
|
19
23
|
setup?: FrameSetup;
|
|
20
24
|
load?: (mod: Record<string, unknown>, autoTitle: string, parameters?: Record<string, unknown>) => LoadedStory[];
|
|
21
25
|
}
|
|
22
|
-
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The frame document's entry: asks its parent for a port and shows what the handoff names, or, from a shell that
|
|
29
|
+
* names nothing, what the hash does. The hash is read at once, so its module loads during the handshake.
|
|
30
|
+
*/
|
|
23
31
|
declare function mountFrame(options: MountFrameOptions): Promise<void>;
|
|
24
32
|
|
|
25
33
|
export { type FrameImporters, type FrameIndexEntry, FrameSetup, type MountFrameOptions, mountFrame };
|
package/dist/frame/index.js
CHANGED
|
@@ -1,8 +1,368 @@
|
|
|
1
|
-
|
|
1
|
+
import { describeSchema, openChannel, isIndexId, indexId, answerSchema, IndexPage } from '../chunk-PO5JLVYT.js';
|
|
2
|
+
import { createOverrides, createGlobalsTarget, loadStories, indexRenderOf, scanCssVars, runAxe, captureElement, StoryHost, resolveCssVar } from '../chunk-FWPBKKYB.js';
|
|
2
3
|
import '../chunk-2GXKNXTJ.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '
|
|
6
|
-
import '
|
|
4
|
+
import '../chunk-HRGPFQBW.js';
|
|
5
|
+
import { FRAME_HELLO, stableStringify, PORT_HANDOFF } from '../chunk-VEKEBILL.js';
|
|
6
|
+
import { flushSync } from 'react-dom';
|
|
7
|
+
import { createRoot } from 'react-dom/client';
|
|
8
|
+
import { jsx } from 'react/jsx-runtime';
|
|
9
|
+
import { f } from '@weasel-js/labkit/config';
|
|
10
|
+
import { Component } from 'react';
|
|
11
|
+
|
|
12
|
+
var VARS_SETTLE_MS = 100;
|
|
13
|
+
function fault(phase, error, seq) {
|
|
14
|
+
return {
|
|
15
|
+
type: "fault",
|
|
16
|
+
phase,
|
|
17
|
+
message: error instanceof Error ? error.message : String(error),
|
|
18
|
+
...error instanceof Error && error.stack ? { stack: error.stack } : {},
|
|
19
|
+
...seq === void 0 ? {} : { seq }
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function startFrame({ story, channel, container, setup = {} }) {
|
|
23
|
+
const { send } = channel;
|
|
24
|
+
send({ type: "ready", schema: describeSchema(story.config), layout: story.layout, viewport: story.viewport });
|
|
25
|
+
const wrapper = document.createElement("div");
|
|
26
|
+
wrapper.className = `fg-frame fg-frame--${story.layout}`;
|
|
27
|
+
container.append(wrapper);
|
|
28
|
+
const root = createRoot(wrapper);
|
|
29
|
+
const decorators = setup.decorators ?? [];
|
|
30
|
+
let initialized = false;
|
|
31
|
+
let rendered = false;
|
|
32
|
+
let config;
|
|
33
|
+
let state = null;
|
|
34
|
+
let globals = {};
|
|
35
|
+
let answeredKey = null;
|
|
36
|
+
let resetKey = 0;
|
|
37
|
+
let seq = 0;
|
|
38
|
+
const overrides = createOverrides(document, setup.cssVarsScope);
|
|
39
|
+
const globalsTarget = createGlobalsTarget(document.documentElement, ":root");
|
|
40
|
+
let lastVars = null;
|
|
41
|
+
let reported = null;
|
|
42
|
+
const publishVars = (vars) => {
|
|
43
|
+
lastVars = vars;
|
|
44
|
+
const key = JSON.stringify(vars);
|
|
45
|
+
if (key === reported) return;
|
|
46
|
+
reported = key;
|
|
47
|
+
send({ type: "vars", vars });
|
|
48
|
+
};
|
|
49
|
+
const reportVars = () => publishVars(scanCssVars(document, overrides.has));
|
|
50
|
+
const ownMutation = (record) => overrides.owns(record.target) || record.type === "childList" && [...record.addedNodes, ...record.removedNodes].length > 0 && [...record.addedNodes, ...record.removedNodes].every(overrides.owns);
|
|
51
|
+
let settleTimer;
|
|
52
|
+
const mutations = typeof MutationObserver === "undefined" ? null : new MutationObserver((records) => {
|
|
53
|
+
if (records.every(ownMutation)) return;
|
|
54
|
+
clearTimeout(settleTimer);
|
|
55
|
+
settleTimer = setTimeout(reportVars, VARS_SETTLE_MS);
|
|
56
|
+
});
|
|
57
|
+
mutations?.observe(document.documentElement, { subtree: true, childList: true, characterData: true, attributes: true });
|
|
58
|
+
const setConfig = (path, value) => send({ type: "setConfig", path, value });
|
|
59
|
+
const setState = (next) => {
|
|
60
|
+
state = typeof next === "function" ? next(state) : next;
|
|
61
|
+
send({ type: "setState", state });
|
|
62
|
+
render();
|
|
63
|
+
};
|
|
64
|
+
const render = () => {
|
|
65
|
+
const ctx = { config, setConfig, state, setState, globals, title: story.title, name: story.name };
|
|
66
|
+
const at = seq;
|
|
67
|
+
root.render(
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
StoryHost,
|
|
70
|
+
{
|
|
71
|
+
story,
|
|
72
|
+
ctx,
|
|
73
|
+
decorators,
|
|
74
|
+
resetKey,
|
|
75
|
+
onError: (error) => send(fault("render", error, at))
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
const key = stableStringify(config);
|
|
80
|
+
if (key !== answeredKey) {
|
|
81
|
+
answeredKey = key;
|
|
82
|
+
send({ type: "answers", answers: { configKey: key, ...answerSchema(story.config, config) } });
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const input = (apply) => {
|
|
86
|
+
seq += 1;
|
|
87
|
+
try {
|
|
88
|
+
apply();
|
|
89
|
+
if (!initialized) return;
|
|
90
|
+
resetKey += 1;
|
|
91
|
+
flushSync(render);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
send(fault("render", error, seq));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!rendered) {
|
|
97
|
+
rendered = true;
|
|
98
|
+
announceRendered();
|
|
99
|
+
}
|
|
100
|
+
reportVars();
|
|
101
|
+
};
|
|
102
|
+
const announceRendered = () => {
|
|
103
|
+
const { fonts } = document;
|
|
104
|
+
if (!fonts) {
|
|
105
|
+
send({ type: "rendered" });
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const afterPaint = () => requestAnimationFrame(() => send({ type: "rendered" }));
|
|
109
|
+
void fonts.ready.then(afterPaint, afterPaint);
|
|
110
|
+
};
|
|
111
|
+
const play = async () => {
|
|
112
|
+
try {
|
|
113
|
+
await story.play?.({ canvasElement: wrapper, config, globals });
|
|
114
|
+
send({ type: "played", ok: true });
|
|
115
|
+
} catch (error) {
|
|
116
|
+
send({ type: "played", ok: false, message: error instanceof Error ? error.message : String(error) });
|
|
117
|
+
send(fault("play", error));
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const audit = async (id) => {
|
|
121
|
+
try {
|
|
122
|
+
send({ type: "a11y", id, ok: true, report: await runAxe(wrapper) });
|
|
123
|
+
} catch (error) {
|
|
124
|
+
send({ type: "a11y", id, ok: false, message: error instanceof Error ? error.message : String(error) });
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const picture = (id) => {
|
|
128
|
+
try {
|
|
129
|
+
send({ type: "capture", id, ok: true, picture: captureElement(wrapper) });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
send({ type: "capture", id, ok: false, message: error instanceof Error ? error.message : String(error) });
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const off = channel.on((msg) => {
|
|
135
|
+
switch (msg.type) {
|
|
136
|
+
case "init":
|
|
137
|
+
input(() => {
|
|
138
|
+
initialized = true;
|
|
139
|
+
config = msg.config;
|
|
140
|
+
globals = msg.globals;
|
|
141
|
+
state = msg.state;
|
|
142
|
+
if (state === null && story.initialState) {
|
|
143
|
+
state = story.initialState(config);
|
|
144
|
+
send({ type: "setState", state });
|
|
145
|
+
}
|
|
146
|
+
setup.applyGlobals?.(globals, globalsTarget);
|
|
147
|
+
});
|
|
148
|
+
break;
|
|
149
|
+
case "config":
|
|
150
|
+
input(() => {
|
|
151
|
+
config = msg.config;
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
case "state":
|
|
155
|
+
input(() => {
|
|
156
|
+
state = msg.state;
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
159
|
+
case "globals":
|
|
160
|
+
input(() => {
|
|
161
|
+
globals = msg.globals;
|
|
162
|
+
setup.applyGlobals?.(globals, globalsTarget);
|
|
163
|
+
});
|
|
164
|
+
break;
|
|
165
|
+
case "vars.set": {
|
|
166
|
+
overrides.set(msg.name, msg.value);
|
|
167
|
+
const at = lastVars?.findIndex((v) => v.name === msg.name) ?? -1;
|
|
168
|
+
if (!lastVars || at < 0) break;
|
|
169
|
+
const vars = lastVars.slice();
|
|
170
|
+
vars[at] = { name: msg.name, value: resolveCssVar(document, msg.name), overridden: overrides.has(msg.name) };
|
|
171
|
+
publishVars(vars);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case "play":
|
|
175
|
+
void play();
|
|
176
|
+
break;
|
|
177
|
+
case "a11y.run":
|
|
178
|
+
void audit(msg.id);
|
|
179
|
+
break;
|
|
180
|
+
case "capture.run":
|
|
181
|
+
picture(msg.id);
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => {
|
|
186
|
+
const { width, height } = wrapper.getBoundingClientRect();
|
|
187
|
+
send({ type: "size", width: Math.ceil(width), height: Math.ceil(height) });
|
|
188
|
+
});
|
|
189
|
+
observer?.observe(wrapper);
|
|
190
|
+
return () => {
|
|
191
|
+
off();
|
|
192
|
+
observer?.disconnect();
|
|
193
|
+
mutations?.disconnect();
|
|
194
|
+
clearTimeout(settleTimer);
|
|
195
|
+
overrides.dispose();
|
|
196
|
+
globalsTarget.dispose();
|
|
197
|
+
root.unmount();
|
|
198
|
+
wrapper.remove();
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function reportImportFault(channel, error) {
|
|
202
|
+
channel.send(fault("import", error));
|
|
203
|
+
}
|
|
204
|
+
var message = (error) => error instanceof Error ? error.message : String(error);
|
|
205
|
+
var PageBoundary = class extends Component {
|
|
206
|
+
state = { failed: null };
|
|
207
|
+
static getDerivedStateFromError(error) {
|
|
208
|
+
return { failed: error ?? new Error("Index page failed") };
|
|
209
|
+
}
|
|
210
|
+
componentDidCatch(error) {
|
|
211
|
+
this.props.onError(error);
|
|
212
|
+
}
|
|
213
|
+
render() {
|
|
214
|
+
return this.state.failed ? null : this.props.children;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
function startIndex(options) {
|
|
218
|
+
const { channel, container, setup = {} } = options;
|
|
219
|
+
const { send } = channel;
|
|
220
|
+
send({ type: "ready", schema: describeSchema(f.schema({})), layout: "fullscreen", viewport: null });
|
|
221
|
+
const wrapper = document.createElement("div");
|
|
222
|
+
wrapper.className = "fg-frame fg-frame--fullscreen";
|
|
223
|
+
container.append(wrapper);
|
|
224
|
+
const root = createRoot(wrapper);
|
|
225
|
+
const globalsTarget = createGlobalsTarget(document.documentElement, ":root");
|
|
226
|
+
let globals = null;
|
|
227
|
+
let announced = false;
|
|
228
|
+
const render = () => {
|
|
229
|
+
if (!globals) return;
|
|
230
|
+
const env = {
|
|
231
|
+
title: options.title,
|
|
232
|
+
...options.description === void 0 ? {} : { description: options.description },
|
|
233
|
+
stories: options.stories,
|
|
234
|
+
descriptions: options.descriptions,
|
|
235
|
+
globals,
|
|
236
|
+
decorators: setup.decorators ?? [],
|
|
237
|
+
open: (id) => send({ type: "open", id }),
|
|
238
|
+
// A story that throws shows its error in its own cell; the rest of the page is still worth reading.
|
|
239
|
+
onError: (error) => console.error(error)
|
|
240
|
+
};
|
|
241
|
+
root.render(
|
|
242
|
+
/* @__PURE__ */ jsx(PageBoundary, { onError: (error) => send({ type: "fault", phase: "render", message: message(error) }), children: /* @__PURE__ */ jsx(IndexPage, { env, render: options.render }) })
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
const announce = () => {
|
|
246
|
+
if (announced) return;
|
|
247
|
+
announced = true;
|
|
248
|
+
const { fonts } = document;
|
|
249
|
+
if (!fonts) {
|
|
250
|
+
send({ type: "rendered" });
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const afterPaint = () => requestAnimationFrame(() => send({ type: "rendered" }));
|
|
254
|
+
void fonts.ready.then(afterPaint, afterPaint);
|
|
255
|
+
};
|
|
256
|
+
const off = channel.on((msg) => {
|
|
257
|
+
switch (msg.type) {
|
|
258
|
+
case "init":
|
|
259
|
+
case "globals":
|
|
260
|
+
globals = msg.globals;
|
|
261
|
+
setup.applyGlobals?.(globals, globalsTarget);
|
|
262
|
+
flushSync(render);
|
|
263
|
+
announce();
|
|
264
|
+
break;
|
|
265
|
+
case "a11y.run":
|
|
266
|
+
runAxe(wrapper).then(
|
|
267
|
+
(report) => send({ type: "a11y", id: msg.id, ok: true, report }),
|
|
268
|
+
(error) => send({ type: "a11y", id: msg.id, ok: false, message: message(error) })
|
|
269
|
+
);
|
|
270
|
+
break;
|
|
271
|
+
case "capture.run":
|
|
272
|
+
try {
|
|
273
|
+
send({ type: "capture", id: msg.id, ok: true, picture: captureElement(wrapper) });
|
|
274
|
+
} catch (error) {
|
|
275
|
+
send({ type: "capture", id: msg.id, ok: false, message: message(error) });
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
return () => {
|
|
281
|
+
off();
|
|
282
|
+
globalsTarget.dispose();
|
|
283
|
+
root.unmount();
|
|
284
|
+
wrapper.remove();
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/frame/mountFrame.tsx
|
|
289
|
+
function waitForHandoff() {
|
|
290
|
+
return new Promise((resolve) => {
|
|
291
|
+
const onMessage = (event) => {
|
|
292
|
+
const data = event.data;
|
|
293
|
+
const port = event.ports[0];
|
|
294
|
+
if (event.origin !== location.origin || event.source !== window.parent) return;
|
|
295
|
+
if (typeof data !== "object" || data === null || data.type !== PORT_HANDOFF || !port) return;
|
|
296
|
+
window.removeEventListener("message", onMessage);
|
|
297
|
+
resolve({ port, id: typeof data.id === "string" ? data.id : null });
|
|
298
|
+
};
|
|
299
|
+
window.addEventListener("message", onMessage);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async function mountFrame(options) {
|
|
303
|
+
const imports = /* @__PURE__ */ new Map();
|
|
304
|
+
const importOf = (file) => {
|
|
305
|
+
let loading = imports.get(file);
|
|
306
|
+
if (!loading) {
|
|
307
|
+
const importer = options.importers[file];
|
|
308
|
+
if (!importer) throw new Error(`No importer for ${file}`);
|
|
309
|
+
loading = importer();
|
|
310
|
+
imports.set(file, loading);
|
|
311
|
+
}
|
|
312
|
+
return loading;
|
|
313
|
+
};
|
|
314
|
+
const entriesOf = (id2) => isIndexId(id2) ? options.index.filter((e) => indexId(e.title) === id2) : options.index.filter((e) => e.id === id2);
|
|
315
|
+
const early = location.hash.slice(1) || null;
|
|
316
|
+
for (const file of new Set(early === null ? [] : entriesOf(early).map((e) => e.file))) {
|
|
317
|
+
if (options.importers[file]) importOf(file).catch(() => {
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const handoff = waitForHandoff();
|
|
321
|
+
window.parent.postMessage({ type: FRAME_HELLO }, location.origin);
|
|
322
|
+
const { port, id: handed } = await handoff;
|
|
323
|
+
const channel = openChannel(port);
|
|
324
|
+
const id = handed ?? early ?? "";
|
|
325
|
+
const container = document.getElementById("root") ?? document.body;
|
|
326
|
+
try {
|
|
327
|
+
if (isIndexId(id)) {
|
|
328
|
+
const entries = entriesOf(id);
|
|
329
|
+
const title = entries[0]?.title;
|
|
330
|
+
if (title === void 0) throw new Error(`No component with index "${id}"`);
|
|
331
|
+
const files = [...new Set(entries.map((e) => e.file))];
|
|
332
|
+
const mods = await Promise.all(files.map(importOf));
|
|
333
|
+
const loaded = files.map((file, i) => ({
|
|
334
|
+
file,
|
|
335
|
+
stories: (options.load ?? loadStories)(mods[i] ?? {}, title, options.setup?.parameters)
|
|
336
|
+
}));
|
|
337
|
+
const stories2 = entries.flatMap(
|
|
338
|
+
(e) => loaded.find((l) => l.file === e.file)?.stories.find((s) => s.exportName === e.exportName) ?? []
|
|
339
|
+
);
|
|
340
|
+
for (const story2 of stories2) await options.setup?.prepare?.(story2);
|
|
341
|
+
startIndex({
|
|
342
|
+
title,
|
|
343
|
+
...entries[0]?.componentDescription === void 0 ? {} : { description: entries[0].componentDescription },
|
|
344
|
+
stories: stories2,
|
|
345
|
+
descriptions: Object.fromEntries(entries.flatMap((e) => e.description ? [[e.id, e.description]] : [])),
|
|
346
|
+
render: mods.map(indexRenderOf).find((render) => render !== null) ?? null,
|
|
347
|
+
channel,
|
|
348
|
+
container,
|
|
349
|
+
...options.setup ? { setup: options.setup } : {}
|
|
350
|
+
});
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const entry = options.index.find((e) => e.id === id);
|
|
354
|
+
if (!entry) throw new Error(`No story with id "${id}"`);
|
|
355
|
+
const mod = await importOf(entry.file);
|
|
356
|
+
const stories = (options.load ?? loadStories)(mod, entry.title, options.setup?.parameters);
|
|
357
|
+
const story = stories.find((s) => s.exportName === entry.exportName);
|
|
358
|
+
if (!story) throw new Error(`${entry.file} has no story export "${entry.exportName}"`);
|
|
359
|
+
await options.setup?.prepare?.(story);
|
|
360
|
+
startFrame({ story, channel, container, setup: options.setup });
|
|
361
|
+
} catch (error) {
|
|
362
|
+
reportImportFault(channel, error);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export { mountFrame, reportImportFault, startFrame };
|
|
7
367
|
//# sourceMappingURL=index.js.map
|
|
8
368
|
//# sourceMappingURL=index.js.map
|
package/dist/frame/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/frame/FrameController.tsx","../../src/frame/index/startIndex.tsx","../../src/frame/mountFrame.tsx"],"names":["createRoot","jsx","flushSync","id","stories","story"],"mappings":"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","file":"index.js","sourcesContent":["import { flushSync } from 'react-dom';\nimport { createRoot } from 'react-dom/client';\nimport type { Channel } from '../protocol/channel';\nimport {\n type CssVarReport,\n type FaultPhase,\n type FromFrame,\n type Globals,\n stableStringify,\n type ToFrame,\n} from '../protocol/messages';\nimport { answerSchema, describeSchema } from '../protocol/schema';\nimport type { Decorator, LoadedStory, StoryContext } from '../story/types';\nimport { runAxe } from './a11y';\nimport { captureElement } from './capture';\nimport { createOverrides, resolveCssVar, scanCssVars } from './cssVars';\nimport { createGlobalsTarget, type GlobalsTarget } from './globalsTarget';\nimport { StoryHost } from './StoryHost';\n\nexport interface FrameSetup {\n /** Wraps every story, outermost; receives the globals. From the frame config (`frameConfig`). */\n decorators?: Decorator[];\n /** Applies globals to a target: theme mode, fonts. The target is a frame document's root, or one story's host in\n * the workshop document, so a rule the setup writes goes through `target.style` under `target.scope`. */\n applyGlobals?: (globals: Globals, target: GlobalsTarget) => void;\n /**\n * The elements a CSS variable override is declared on; `:root` by default. An override has to be declared on\n * whichever element declares the token itself — a theme wrapper, say — or that element's own value wins.\n */\n cssVarsScope?: string;\n /** Project-wide CSF parameters, Storybook's preview `parameters`: under each meta's and story's. */\n parameters?: Record<string, unknown>;\n /**\n * Awaited once a story is loaded and before it first renders — the place to import what only some stories\n * need, so the rest never load it.\n */\n prepare?: (story: LoadedStory) => void | Promise<void>;\n}\n\nexport interface StartFrameOptions {\n story: LoadedStory;\n channel: Channel<ToFrame, FromFrame>;\n container: HTMLElement;\n setup?: FrameSetup;\n}\n\nconst VARS_SETTLE_MS = 100;\n\nfunction fault(phase: FaultPhase, error: unknown, seq?: number): FromFrame {\n return {\n type: 'fault',\n phase,\n message: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),\n ...(seq === undefined ? {} : { seq }),\n };\n}\n\n/** Sends `ready`, then renders the story on `init` and keeps it in step. Returns a stop function. */\nexport function startFrame({ story, channel, container, setup = {} }: StartFrameOptions): () => void {\n const { send } = channel;\n send({ type: 'ready', schema: describeSchema(story.config), layout: story.layout, viewport: story.viewport });\n\n const wrapper = document.createElement('div');\n wrapper.className = `fg-frame fg-frame--${story.layout}`;\n container.append(wrapper);\n const root = createRoot(wrapper);\n const decorators = setup.decorators ?? [];\n\n let initialized = false;\n let rendered = false;\n let config: unknown;\n let state: unknown = null;\n let globals: Globals = {};\n let answeredKey: string | null = null;\n let resetKey = 0;\n let seq = 0;\n\n const overrides = createOverrides(document, setup.cssVarsScope);\n const globalsTarget = createGlobalsTarget(document.documentElement, ':root');\n let lastVars: CssVarReport[] | null = null;\n let reported: string | null = null;\n const publishVars = (vars: CssVarReport[]) => {\n lastVars = vars;\n const key = JSON.stringify(vars);\n if (key === reported) return;\n reported = key;\n send({ type: 'vars', vars });\n };\n const reportVars = () => publishVars(scanCssVars(document, overrides.has));\n const ownMutation = (record: MutationRecord) =>\n overrides.owns(record.target) ||\n (record.type === 'childList' &&\n [...record.addedNodes, ...record.removedNodes].length > 0 &&\n [...record.addedNodes, ...record.removedNodes].every(overrides.owns));\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n const mutations =\n typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver((records) => {\n if (records.every(ownMutation)) return;\n clearTimeout(settleTimer);\n settleTimer = setTimeout(reportVars, VARS_SETTLE_MS);\n });\n // Every attribute, not just style and class: a stylesheet can select on any of them, `[data-wzl-mode]` included.\n mutations?.observe(document.documentElement, { subtree: true, childList: true, characterData: true, attributes: true });\n\n const setConfig = (path: string, value: unknown) => send({ type: 'setConfig', path, value });\n const setState = (next: unknown) => {\n state = typeof next === 'function' ? (next as (prev: unknown) => unknown)(state) : next;\n send({ type: 'setState', state });\n render();\n };\n\n const render = () => {\n const ctx: StoryContext = { config, setConfig, state, setState, globals, title: story.title, name: story.name };\n const at = seq;\n root.render(\n <StoryHost\n story={story}\n ctx={ctx}\n decorators={decorators}\n resetKey={resetKey}\n onError={(error) => send(fault('render', error, at))}\n />,\n );\n const key = stableStringify(config);\n if (key !== answeredKey) {\n answeredKey = key;\n send({ type: 'answers', answers: { configKey: key, ...answerSchema(story.config, config) } });\n }\n };\n\n // Input from the trial commits synchronously, so a `play` that follows sees the rendered story. A throw while\n // applying it faults like a render would; otherwise the trial would wait on a frame that never answers.\n const input = (apply: () => void) => {\n seq += 1;\n try {\n apply();\n if (!initialized) return;\n resetKey += 1;\n flushSync(render);\n } catch (error) {\n send(fault('render', error, seq));\n return;\n }\n if (!rendered) {\n rendered = true;\n announceRendered();\n }\n reportVars();\n };\n\n /**\n * The shell unhides the frame on `rendered` and fades it in, so whatever\n * reflows after that message reads as a glide rather than a jump. A webfont\n * swapping in is the reflow that does it: a `layout: 'padded'` story is\n * top-anchored, so the line-height change walks the whole story upward.\n * Waiting for the fonts and then one painted frame means the story the\n * shell reveals is the settled one.\n *\n * `document.fonts` is absent in jsdom, where there is no paint to wait for\n * and no font to swap — the message stays synchronous there, which is also\n * what `FrameController.test.tsx` observes. The deferral itself is only\n * exercised in a browser.\n */\n const announceRendered = () => {\n const { fonts } = document;\n if (!fonts) {\n send({ type: 'rendered' });\n return;\n }\n const afterPaint = () => requestAnimationFrame(() => send({ type: 'rendered' }));\n void fonts.ready.then(afterPaint, afterPaint);\n };\n\n const play = async () => {\n try {\n await story.play?.({ canvasElement: wrapper, config, globals });\n send({ type: 'played', ok: true });\n } catch (error) {\n send({ type: 'played', ok: false, message: error instanceof Error ? error.message : String(error) });\n send(fault('play', error));\n }\n };\n\n const audit = async (id: string) => {\n try {\n send({ type: 'a11y', id, ok: true, report: await runAxe(wrapper) });\n } catch (error) {\n send({ type: 'a11y', id, ok: false, message: error instanceof Error ? error.message : String(error) });\n }\n };\n\n const picture = (id: string) => {\n try {\n send({ type: 'capture', id, ok: true, picture: captureElement(wrapper) });\n } catch (error) {\n send({ type: 'capture', id, ok: false, message: error instanceof Error ? error.message : String(error) });\n }\n };\n\n const off = channel.on((msg) => {\n switch (msg.type) {\n case 'init':\n input(() => {\n initialized = true;\n config = msg.config;\n globals = msg.globals;\n state = msg.state;\n if (state === null && story.initialState) {\n state = story.initialState(config);\n send({ type: 'setState', state });\n }\n setup.applyGlobals?.(globals, globalsTarget);\n });\n break;\n case 'config':\n input(() => {\n config = msg.config;\n });\n break;\n case 'state':\n input(() => {\n state = msg.state;\n });\n break;\n case 'globals':\n input(() => {\n globals = msg.globals;\n setup.applyGlobals?.(globals, globalsTarget);\n });\n break;\n case 'vars.set': {\n overrides.set(msg.name, msg.value);\n const at = lastVars?.findIndex((v) => v.name === msg.name) ?? -1;\n if (!lastVars || at < 0) break;\n const vars = lastVars.slice();\n vars[at] = { name: msg.name, value: resolveCssVar(document, msg.name), overridden: overrides.has(msg.name) };\n publishVars(vars);\n break;\n }\n case 'play':\n void play();\n break;\n case 'a11y.run':\n void audit(msg.id);\n break;\n case 'capture.run':\n picture(msg.id);\n break;\n }\n });\n\n const observer =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => {\n const { width, height } = wrapper.getBoundingClientRect();\n send({ type: 'size', width: Math.ceil(width), height: Math.ceil(height) });\n });\n observer?.observe(wrapper);\n\n return () => {\n off();\n observer?.disconnect();\n mutations?.disconnect();\n clearTimeout(settleTimer);\n overrides.dispose();\n globalsTarget.dispose();\n root.unmount();\n wrapper.remove();\n };\n}\n\n/** Reports an import failure — there is no story to start. */\nexport function reportImportFault(channel: Channel<ToFrame, FromFrame>, error: unknown): void {\n channel.send(fault('import', error));\n}\n","import { f } from '@weasel-js/labkit/config';\nimport { Component, type ReactNode } from 'react';\nimport { flushSync } from 'react-dom';\nimport { createRoot } from 'react-dom/client';\nimport type { Channel } from '../../protocol/channel';\nimport type { FromFrame, Globals, ToFrame } from '../../protocol/messages';\nimport { describeSchema } from '../../protocol/schema';\nimport type { IndexRender, LoadedStory } from '../../story/types';\nimport { runAxe } from '../a11y';\nimport { captureElement } from '../capture';\nimport type { FrameSetup } from '../FrameController';\nimport { createGlobalsTarget } from '../globalsTarget';\nimport { type IndexEnv, IndexPage } from './IndexPage';\nimport './index.css';\n\nexport interface StartIndexOptions {\n title: string;\n description?: string;\n /** In file order. */\n stories: readonly LoadedStory[];\n descriptions: Readonly<Record<string, string>>;\n /** The component's own page; null for the generated one. */\n render: IndexRender | null;\n channel: Channel<ToFrame, FromFrame>;\n container: HTMLElement;\n setup?: FrameSetup;\n}\n\nconst message = (error: unknown): string => (error instanceof Error ? error.message : String(error));\n\n/** Faults the frame when the page itself throws. A single story's throw stays in its own cell. */\nclass PageBoundary extends Component<{ onError: (error: unknown) => void; children: ReactNode }, { failed: unknown }> {\n override state = { failed: null as unknown };\n\n static getDerivedStateFromError(error: unknown) {\n return { failed: error ?? new Error('Index page failed') };\n }\n\n override componentDidCatch(error: unknown): void {\n this.props.onError(error);\n }\n\n override render(): ReactNode {\n return this.state.failed ? null : this.props.children;\n }\n}\n\n/**\n * Sends `ready` for a page with no controls, then renders the component's index on `init` and follows the lab's\n * globals. Returns a stop function.\n */\nexport function startIndex(options: StartIndexOptions): () => void {\n const { channel, container, setup = {} } = options;\n const { send } = channel;\n send({ type: 'ready', schema: describeSchema(f.schema({})), layout: 'fullscreen', viewport: null });\n\n const wrapper = document.createElement('div');\n wrapper.className = 'fg-frame fg-frame--fullscreen';\n container.append(wrapper);\n const root = createRoot(wrapper);\n const globalsTarget = createGlobalsTarget(document.documentElement, ':root');\n let globals: Globals | null = null;\n let announced = false;\n\n const render = (): void => {\n if (!globals) return;\n const env: IndexEnv = {\n title: options.title,\n ...(options.description === undefined ? {} : { description: options.description }),\n stories: options.stories,\n descriptions: options.descriptions,\n globals,\n decorators: setup.decorators ?? [],\n open: (id) => send({ type: 'open', id }),\n // A story that throws shows its error in its own cell; the rest of the page is still worth reading.\n onError: (error) => console.error(error),\n };\n root.render(\n <PageBoundary onError={(error) => send({ type: 'fault', phase: 'render', message: message(error) })}>\n <IndexPage env={env} render={options.render} />\n </PageBoundary>,\n );\n };\n\n const announce = (): void => {\n if (announced) return;\n announced = true;\n const { fonts } = document;\n if (!fonts) {\n send({ type: 'rendered' });\n return;\n }\n const afterPaint = () => requestAnimationFrame(() => send({ type: 'rendered' }));\n void fonts.ready.then(afterPaint, afterPaint);\n };\n\n const off = channel.on((msg) => {\n switch (msg.type) {\n case 'init':\n case 'globals':\n globals = msg.globals;\n setup.applyGlobals?.(globals, globalsTarget);\n flushSync(render);\n announce();\n break;\n case 'a11y.run':\n runAxe(wrapper).then(\n (report) => send({ type: 'a11y', id: msg.id, ok: true, report }),\n (error: unknown) => send({ type: 'a11y', id: msg.id, ok: false, message: message(error) }),\n );\n break;\n case 'capture.run':\n try {\n send({ type: 'capture', id: msg.id, ok: true, picture: captureElement(wrapper) });\n } catch (error) {\n send({ type: 'capture', id: msg.id, ok: false, message: message(error) });\n }\n break;\n default:\n break;\n }\n });\n\n return () => {\n off();\n globalsTarget.dispose();\n root.unmount();\n wrapper.remove();\n };\n}\n","import { openChannel } from '../protocol/channel';\nimport { FRAME_HELLO, type FromFrame, PORT_HANDOFF, type ToFrame } from '../protocol/messages';\nimport { indexId, isIndexId } from '../story/indexPages';\nimport { indexRenderOf, loadStories } from '../story/load';\nimport type { LoadedStory } from '../story/types';\nimport { type FrameSetup, reportImportFault, startFrame } from './FrameController';\nimport { startIndex } from './index/startIndex';\n\nexport interface FrameImporters {\n [file: string]: () => Promise<Record<string, unknown>>;\n}\n\nexport interface FrameIndexEntry {\n id: string;\n /** The story's title as indexed, which titles the file's stories when its meta names none. */\n title: string;\n file: string;\n exportName: string;\n /** The JSDoc above the story's export, which its index page shows. */\n description?: string;\n /** The JSDoc above the file's meta, which heads the index page. */\n componentDescription?: string;\n}\n\nexport interface MountFrameOptions {\n index: readonly FrameIndexEntry[];\n importers: FrameImporters;\n setup?: FrameSetup;\n load?: (mod: Record<string, unknown>, autoTitle: string, parameters?: Record<string, unknown>) => LoadedStory[];\n}\n\nexport { indexRenderOf, loadStories } from '../story/load';\n\nfunction waitForHandoff():Promise<{ port: MessagePort; id: string | null }> {\n return new Promise((resolve) => {\n const onMessage = (event: MessageEvent) => {\n const data = event.data as { type?: unknown; id?: unknown } | null;\n const port = event.ports[0];\n if (event.origin !== location.origin || event.source !== window.parent) return;\n if (typeof data !== 'object' || data === null || data.type !== PORT_HANDOFF || !port) return;\n window.removeEventListener('message', onMessage);\n resolve({ port, id: typeof data.id === 'string' ? data.id : null });\n };\n window.addEventListener('message', onMessage);\n });\n}\n\n/**\n * The frame document's entry: asks its parent for a port and shows what the handoff names, or, from a shell that\n * names nothing, what the hash does. The hash is read at once, so its module loads during the handshake.\n */\nexport async function mountFrame(options: MountFrameOptions): Promise<void> {\n const imports = new Map<string, Promise<Record<string, unknown>>>();\n const importOf = (file: string): Promise<Record<string, unknown>> => {\n let loading = imports.get(file);\n if (!loading) {\n const importer = options.importers[file];\n if (!importer) throw new Error(`No importer for ${file}`);\n loading = importer();\n imports.set(file, loading);\n }\n return loading;\n };\n /** The entries `id` shows: one story, or every story of the component an index id names. */\n const entriesOf = (id: string): FrameIndexEntry[] =>\n isIndexId(id)\n ? options.index.filter((e) => indexId(e.title) === id)\n : options.index.filter((e) => e.id === id);\n const early = location.hash.slice(1) || null;\n // Only starts the fetch; whoever awaits the import later sees its outcome.\n for (const file of new Set(early === null ? [] : entriesOf(early).map((e) => e.file))) {\n if (options.importers[file]) importOf(file).catch(() => {});\n }\n\n const handoff = waitForHandoff();\n window.parent.postMessage({ type: FRAME_HELLO }, location.origin);\n const { port, id: handed } = await handoff;\n const channel = openChannel<ToFrame, FromFrame>(port);\n const id = handed ?? early ?? '';\n const container = document.getElementById('root') ?? document.body;\n try {\n if (isIndexId(id)) {\n const entries = entriesOf(id);\n const title = entries[0]?.title;\n if (title === undefined) throw new Error(`No component with index \"${id}\"`);\n const files = [...new Set(entries.map((e) => e.file))];\n const mods = await Promise.all(files.map(importOf));\n const loaded = files.map((file, i) => ({\n file,\n stories: (options.load ?? loadStories)(mods[i] ?? {}, title, options.setup?.parameters),\n }));\n const stories = entries.flatMap(\n (e) => loaded.find((l) => l.file === e.file)?.stories.find((s) => s.exportName === e.exportName) ?? [],\n );\n for (const story of stories) await options.setup?.prepare?.(story);\n startIndex({\n title,\n ...(entries[0]?.componentDescription === undefined ? {} : { description: entries[0].componentDescription }),\n stories,\n descriptions: Object.fromEntries(entries.flatMap((e) => (e.description ? [[e.id, e.description]] : []))),\n render: mods.map(indexRenderOf).find((render) => render !== null) ?? null,\n channel,\n container,\n ...(options.setup ? { setup: options.setup } : {}),\n });\n return;\n }\n const entry = options.index.find((e) => e.id === id);\n if (!entry) throw new Error(`No story with id \"${id}\"`);\n const mod = await importOf(entry.file);\n const stories = (options.load ?? loadStories)(mod, entry.title, options.setup?.parameters);\n const story = stories.find((s) => s.exportName === entry.exportName);\n if (!story) throw new Error(`${entry.file} has no story export \"${entry.exportName}\"`);\n await options.setup?.prepare?.(story);\n startFrame({ story, channel, container, setup: options.setup });\n } catch (error) {\n reportImportFault(channel, error);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export { f } from '@weasel-js/labkit/config';
|
|
2
|
-
export { G as GlobalDeclaration, a as GlobalDeclarations, S as ShellConfig, d as defineFrameConfig, b as defineShellConfig } from './config-
|
|
2
|
+
export { G as GlobalDeclaration, a as GlobalDeclarations, S as ShellConfig, d as defineFrameConfig, b as defineShellConfig } from './config-DU_WuORS.js';
|
|
3
3
|
import { ComponentType, ReactNode } from 'react';
|
|
4
|
-
import { G as Globals, M as MetaSpec, S as StorySpec } from './FrameController-
|
|
5
|
-
export { A as A11yFinding, a as A11yNode, b as A11yReport, D as Decorator, F as FrameSetup, L as LoadedStory, P as PlayContext,
|
|
4
|
+
import { G as Globals, M as MetaSpec, S as StorySpec } from './FrameController-BspC9Zr5.js';
|
|
5
|
+
export { A as A11yFinding, a as A11yNode, b as A11yReport, D as Decorator, F as FrameSetup, c as GlobalsTarget, I as IndexContext, d as IndexRender, e as IndexStoryProps, L as LoadedStory, P as PlayContext, f as StoryContext } from './FrameController-BspC9Zr5.js';
|
|
6
6
|
import '@weasel-js/labkit';
|
|
7
|
+
import '@weasel-js/theme';
|
|
7
8
|
|
|
8
9
|
/** Storybook's conditional control: shown only while an arg, or a global, meets the test. */
|
|
9
10
|
type ArgCondition = ({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"names":[],"mappings":";;;;AAuBO,SAAS,kBAAkB,MAAA,EAAgC;AAChE,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,kBAAkB,MAAA,EAAkC;AAClE,EAAA,OAAO,MAAA;AACT","file":"index.js","sourcesContent":["import type { LabContribution, LabPage } from '@weasel-js/labkit';\nimport type { Theme } from '@weasel-js/theme';\nimport type { ControlRenderer } from '@weasel-js/labkit/config';\nimport type { FrameSetup } from './frame/FrameController';\nimport type { Globals } from './protocol/messages';\nimport type { GlobalDeclarations } from './shell/globals';\n\n/** A shell config module: what the workshop adds to the lab. Only the workshop page imports it. */\nexport interface ShellConfig {\n labChrome?: readonly LabContribution[];\n controls?: Record<string, ControlRenderer>;\n /** Globals the lab's header sets for every story, each pinnable per trial. Frames apply them with `applyGlobals`. */\n globals?: GlobalDeclarations;\n /** The theme the workshop's own chrome takes at the lab's current globals, so a global can restyle the workshop\n * as well as the stories. Default: labkit's. */\n labTheme?: (globals: Globals) => Theme;\n /** The project's other labs, offered in the workshop's title menu. */\n pages?: readonly LabPage[];\n /** Which of `pages` the workshop is, when the URL alone cannot say, as across dev servers on different ports. */\n path?: string;\n}\n\n/** A frame config module's default export. Only frame documents import it, so its CSS stays out of the workshop. */\nexport function defineFrameConfig(config: FrameSetup): FrameSetup {\n return config;\n}\n\n/** A shell config module's default export. */\nexport function defineShellConfig(config: ShellConfig): ShellConfig {\n return config;\n}\n"]}
|