@variance-authority/storybook-collector 0.11.0 → 0.13.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/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/dist/execution.js +6 -0
- package/dist/execution.js.map +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @variance-authority/storybook-collector
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
6
|
+
|
|
7
|
+
## 0.12.0
|
|
8
|
+
|
|
9
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
10
|
+
|
|
3
11
|
## 0.11.0
|
|
4
12
|
|
|
5
13
|
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
package/README.md
CHANGED
|
@@ -129,8 +129,8 @@ renderer, engine, platform, device scale factor and fonts that an approved image
|
|
|
129
129
|
is stored under. It exits `2` when no browser opens or when the root has no
|
|
130
130
|
images this machine could compare against.
|
|
131
131
|
|
|
132
|
-
The first durable run exits `
|
|
133
|
-
approved is not a pass. Promote the candidates the run already produced:
|
|
132
|
+
The first durable run exits `0` and reports every story `new`. Nothing moved,
|
|
133
|
+
and an image nobody approved is not a pass either. Promote the candidates the run already produced:
|
|
134
134
|
|
|
135
135
|
```bash
|
|
136
136
|
npx variance accept --config variance.config.json --all
|
package/dist/execution.js
CHANGED
|
@@ -50,6 +50,12 @@ export async function createStoryRecorder(index, options) {
|
|
|
50
50
|
// touches. A story the driving index does not know — a subject named on
|
|
51
51
|
// the command line, a preview rebuilt since — has no file to be a case
|
|
52
52
|
// in, and contributes to the file-level record only.
|
|
53
|
+
//
|
|
54
|
+
// FIXME: the row is owned by `story:<id>` and the case by `story.file`,
|
|
55
|
+
// and the case index retires the cases of a file a run finished, read off
|
|
56
|
+
// the rows. No row names a story file, so no case is ever retired by a
|
|
57
|
+
// run: a story removed or renamed keeps its case until its file is
|
|
58
|
+
// deleted.
|
|
53
59
|
if (story !== undefined) {
|
|
54
60
|
cases.push({
|
|
55
61
|
subject: subjectId,
|
package/dist/execution.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What each story executed, recorded for the next run's selection.\n *\n * The instrument is the one `@variance-authority/sense` already uses; only the\n * transport differs, which is the rule\n * [spec 0028](../../../docs/specs/0028-the-instrument.md) states. The preview is\n * built with `testSelectionProbes()`, the page counts block crossings, and this\n * closes one window per story and joins them at the end of the run.\n *\n * A story is its own owner. Storybook is an execution surface this tool drives\n * one subject at a time, so — unlike a test runner, where the file is the\n * smallest thing a runner can be asked to execute — the crossings of one story\n * belong to that story and to nothing else.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve, sep } from 'node:path';\nimport {\n drainExecution,\n preconditionOf,\n recordExecution,\n type EvaluatingPage,\n type InstrumentMode,\n type ObservedCase,\n type ObservedSubject,\n} from '@variance-authority/sense/journal';\nimport { parseStoryIndex } from '@variance-authority/storybook';\nimport { repositoryRoot } from '@variance-authority/sense/test-selection';\nimport { storyIdOf } from './parameters.js';\n\n/** Where a story run's execution evidence is joined, read and kept. */\nexport interface StoryExecutionOptions {\n /**\n * A directory inside the repository; defaults to the cwd. Recorded paths are\n * relative to the checkout it sits in, never to it. A story's `importPath` is\n * read from here, because it is relative to the directory Storybook ran in.\n */\n readonly root?: string;\n /** Matches the `label` the build's `testSelectionProbes()` used. Defaults to `build`. */\n readonly label?: string;\n /** Where the build wrote its block records. Defaults to the repository's cache. */\n readonly cacheRoot?: string;\n /** Coverage index. Defaults to the repository-keyed cache the runner seams share. */\n readonly coverageFile?: string;\n /** The suite this run is, as the root `variance.config.json` declares it under `suites`. */\n readonly suite?: string;\n /**\n * Where the execution index — which individual story entered which region —\n * goes. Defaults beside the snapshot, as the Vitest seam's does.\n *\n * A story is the case this costs nothing to name: the driver shows one at a\n * time, so the per-case grain a unit runner needs a custom runner for is\n * already here.\n */\n readonly executionFile?: string;\n /**\n * The probe recipe the preview was built with, matching\n * `testSelectionProbes()`'s `mode`. `presence` when absent, as it is there.\n *\n * Both sides answer the same or neither works: a journal cut by one recipe\n * and folded as another is refused, and a snapshot a runner seam also writes\n * under a different recipe has each run retire the other's evidence.\n */\n readonly mode?: InstrumentMode;\n /**\n * Files whose contents are preconditions of every story this run recorded.\n *\n * A `.storybook/preview` file, a theme module every decorator reads — a\n * story *file* is already a precondition of its own stories, and this is for\n * the ones no story declares and nothing enters.\n */\n readonly preconditions?: readonly string[];\n /**\n * Other builds this same run drove, by the label each instrumented under.\n *\n * A preview and the application behind it are two builds of overlapping\n * source, and a story that reaches both is one observation. Their stores\n * join this recording rather than getting one of their own.\n */\n readonly heads?: readonly string[];\n /**\n * Where this recording stands. Defaults to the checkout's `HEAD`, which is\n * the answer in every case except a caller that already knows better.\n */\n readonly commit?: string;\n}\n\n/** One run's accumulation: a window per story, written once at the end. */\nexport interface StoryRecorder {\n /**\n * Close one story's window.\n *\n * `complete` is false for a story this run refused. A refused story still\n * executed code, so its crossings are kept — what it may never do is justify\n * excluding itself from a later run.\n */\n readonly note: (page: EvaluatingPage, subjectId: string, complete: boolean) => Promise<void>;\n /**\n * Merge the run into the index, or say on stderr why it could not.\n *\n * `costs` is the run's own time for each story, by subject id: first\n * collection to decision, the figure `variance ask costs` answers and the\n * next run shards on. It is recorded as the story's duration, on its row and\n * on its case, rather than timed a second time here. A story the run did not\n * time is recorded without one.\n */\n readonly close: (costs?: ReadonlyMap<string, number>) => Promise<void>;\n}\n\nexport async function createStoryRecorder(\n index: string,\n options: StoryExecutionOptions,\n): Promise<StoryRecorder> {\n const ran = resolve(options.root ?? process.cwd());\n const root = repositoryRoot(ran);\n const storyFiles = await storyFilesFrom(index, ran, root);\n const observed: ObservedSubject[] = [];\n // Each case with the subject it was noted for, so the run's time finds it.\n const cases: { readonly subject: string; readonly observed: ObservedCase }[] = [];\n let seen = false;\n\n return {\n note: async (page, subjectId, complete) => {\n const journal = await drainExecution(page);\n if (journal === undefined) return;\n seen = true;\n // A story read at several widths is one declaration and several cases:\n // each width executed the story on its own, and a hook that reads the\n // width took a different branch at each.\n const widened = subjectId.replace(/^story:/, '');\n const storyId = storyIdOf(subjectId);\n const story = storyFiles.get(storyId);\n const precondition =\n story === undefined ? undefined : await preconditionOf(root, story.file);\n observed.push({\n owner: subjectId,\n journal,\n complete,\n ...(precondition === undefined ? {} : { preconditions: [precondition] }),\n });\n // The index names a story by where it is declared, which is the same\n // coordinate a person reads in the sidebar and the same one a diff\n // touches. A story the driving index does not know — a subject named on\n // the command line, a preview rebuilt since — has no file to be a case\n // in, and contributes to the file-level record only.\n if (story !== undefined) {\n cases.push({\n subject: subjectId,\n observed: {\n file: story.file,\n name: `${story.title}/${story.name}${widened.slice(storyId.length)}`,\n id: widened,\n stopped: !complete,\n journal,\n },\n });\n }\n },\n\n close: async (costs) => {\n if (!seen) {\n process.stderr.write(\n 'variance-authority: `tests` is on and the Storybook preview has no execution ' +\n 'collector in it — build it with `testSelectionProbes()` from ' +\n '`@variance-authority/sense/journal`, or the next `--since` will run ' +\n 'everything\\n',\n );\n return;\n }\n // A refusal is written and the run continues. Recording is an addition to\n // a visual run: losing it costs the *next* selection its narrowing, which\n // is a full suite — the safe direction — while failing the run over it\n // would cost this one its baselines, which is not.\n //\n // That holds for a throw as much as for a refusal. The recorder reports\n // what it declined in `because`, but it is a file format, a lock and a\n // filesystem underneath, and any of them can raise something it has no\n // sentence for. Letting that escape ends the run *after* every subject\n // has been rendered and compared — the most expensive possible moment to\n // lose a set of baselines, and over the half of the work that was only\n // ever an addition.\n let record: Awaited<ReturnType<typeof recordExecution>>;\n try {\n record = await recordExecution({\n root,\n subjects: zip(observed, timedOnce(observed.map((one) => one.owner), costs)),\n ...(options.label === undefined ? {} : { label: options.label }),\n ...(options.cacheRoot === undefined ? {} : { cacheRoot: options.cacheRoot }),\n // Against `root`, as the runner seams resolve them, never the checkout.\n ...(options.coverageFile === undefined\n ? {}\n : { coverageFile: resolve(ran, options.coverageFile) }),\n ...(options.suite === undefined ? {} : { suite: options.suite }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.preconditions === undefined\n ? {}\n : { preconditions: options.preconditions }),\n ...(options.heads === undefined || options.heads.length === 0\n ? {}\n : { heads: options.heads }),\n ...(options.commit === undefined ? {} : { commit: options.commit }),\n ...(cases.length === 0\n ? {}\n : { cases: zip(cases.map((one) => one.observed), timedOnce(cases.map((one) => one.subject), costs)) }),\n ...(options.executionFile === undefined\n ? {}\n : { executionFile: resolve(ran, options.executionFile) }),\n });\n } catch (error) {\n process.stderr.write(\n 'variance-authority: recorded no story execution — the recorder failed with ' +\n `${error instanceof Error ? error.message : String(error)}; this run is ` +\n 'unaffected and the next `--since` will run everything\\n',\n );\n return;\n }\n if (!record.recorded) {\n process.stderr.write(\n `variance-authority: recorded no story execution — ${record.because}\\n`,\n );\n }\n },\n };\n}\n\n/**\n * The run's time for each noted subject, given to the first note of that\n * subject only.\n *\n * A subject read again — once more in the same world, once alone — is noted\n * each time, and the record sums what its entries carry; the run's time\n * already covers every reading, from the first collection to the decision.\n */\nfunction timedOnce(\n subjects: readonly string[],\n costs: ReadonlyMap<string, number> | undefined,\n): { readonly duration?: number }[] {\n const given = new Set<string>();\n return subjects.map((subject) => {\n const duration = costs?.get(subject);\n if (duration === undefined || given.has(subject)) return {};\n given.add(subject);\n return { duration };\n });\n}\n\nfunction zip<T>(entries: readonly T[], timed: readonly { readonly duration?: number }[]): T[] {\n return entries.map((entry, index) => ({ ...entry, ...timed[index] }));\n}\n\n/**\n * Story id to where it is declared, from the index the run is driving.\n *\n * The one route from a subject back to a file, and the reason a story's own\n * `.stories` file can select it: nothing *enters* a story file the way execution\n * enters a module, so without this a commit that edits one selects nothing. The\n * title and the name come along because the execution index names a case by its\n * declaration rather than by the id Storybook slugged from it.\n *\n * Storybook writes `importPath` from the directory it ran in, `./` and all. A\n * diff names files from the checkout, so the path is resolved from `ran` and\n * named from `root`; in a workspace the two are a package apart.\n */\nasync function storyFilesFrom(\n index: string,\n ran: string,\n root: string,\n): Promise<Map<string, StoryCoordinate>> {\n const parsed = parseStoryIndex(JSON.parse(await readFile(index, 'utf8')), index);\n return new Map(\n parsed.stories.map((story) => [\n story.id,\n {\n file: relative(root, resolve(ran, story.importPath)).split(sep).join('/'),\n title: story.title,\n name: story.name,\n },\n ]),\n );\n}\n\n/** Where a story is declared and what it is called there. */\ninterface StoryCoordinate {\n readonly file: string;\n readonly title: string;\n readonly name: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What each story executed, recorded for the next run's selection.\n *\n * The instrument is the one `@variance-authority/sense` already uses; only the\n * transport differs, which is the rule\n * [spec 0028](../../../docs/specs/0028-the-instrument.md) states. The preview is\n * built with `testSelectionProbes()`, the page counts block crossings, and this\n * closes one window per story and joins them at the end of the run.\n *\n * A story is its own owner. Storybook is an execution surface this tool drives\n * one subject at a time, so — unlike a test runner, where the file is the\n * smallest thing a runner can be asked to execute — the crossings of one story\n * belong to that story and to nothing else.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve, sep } from 'node:path';\nimport {\n drainExecution,\n preconditionOf,\n recordExecution,\n type EvaluatingPage,\n type InstrumentMode,\n type ObservedCase,\n type ObservedSubject,\n} from '@variance-authority/sense/journal';\nimport { parseStoryIndex } from '@variance-authority/storybook';\nimport { repositoryRoot } from '@variance-authority/sense/test-selection';\nimport { storyIdOf } from './parameters.js';\n\n/** Where a story run's execution evidence is joined, read and kept. */\nexport interface StoryExecutionOptions {\n /**\n * A directory inside the repository; defaults to the cwd. Recorded paths are\n * relative to the checkout it sits in, never to it. A story's `importPath` is\n * read from here, because it is relative to the directory Storybook ran in.\n */\n readonly root?: string;\n /** Matches the `label` the build's `testSelectionProbes()` used. Defaults to `build`. */\n readonly label?: string;\n /** Where the build wrote its block records. Defaults to the repository's cache. */\n readonly cacheRoot?: string;\n /** Coverage index. Defaults to the repository-keyed cache the runner seams share. */\n readonly coverageFile?: string;\n /** The suite this run is, as the root `variance.config.json` declares it under `suites`. */\n readonly suite?: string;\n /**\n * Where the execution index — which individual story entered which region —\n * goes. Defaults beside the snapshot, as the Vitest seam's does.\n *\n * A story is the case this costs nothing to name: the driver shows one at a\n * time, so the per-case grain a unit runner needs a custom runner for is\n * already here.\n */\n readonly executionFile?: string;\n /**\n * The probe recipe the preview was built with, matching\n * `testSelectionProbes()`'s `mode`. `presence` when absent, as it is there.\n *\n * Both sides answer the same or neither works: a journal cut by one recipe\n * and folded as another is refused, and a snapshot a runner seam also writes\n * under a different recipe has each run retire the other's evidence.\n */\n readonly mode?: InstrumentMode;\n /**\n * Files whose contents are preconditions of every story this run recorded.\n *\n * A `.storybook/preview` file, a theme module every decorator reads — a\n * story *file* is already a precondition of its own stories, and this is for\n * the ones no story declares and nothing enters.\n */\n readonly preconditions?: readonly string[];\n /**\n * Other builds this same run drove, by the label each instrumented under.\n *\n * A preview and the application behind it are two builds of overlapping\n * source, and a story that reaches both is one observation. Their stores\n * join this recording rather than getting one of their own.\n */\n readonly heads?: readonly string[];\n /**\n * Where this recording stands. Defaults to the checkout's `HEAD`, which is\n * the answer in every case except a caller that already knows better.\n */\n readonly commit?: string;\n}\n\n/** One run's accumulation: a window per story, written once at the end. */\nexport interface StoryRecorder {\n /**\n * Close one story's window.\n *\n * `complete` is false for a story this run refused. A refused story still\n * executed code, so its crossings are kept — what it may never do is justify\n * excluding itself from a later run.\n */\n readonly note: (page: EvaluatingPage, subjectId: string, complete: boolean) => Promise<void>;\n /**\n * Merge the run into the index, or say on stderr why it could not.\n *\n * `costs` is the run's own time for each story, by subject id: first\n * collection to decision, the figure `variance ask costs` answers and the\n * next run shards on. It is recorded as the story's duration, on its row and\n * on its case, rather than timed a second time here. A story the run did not\n * time is recorded without one.\n */\n readonly close: (costs?: ReadonlyMap<string, number>) => Promise<void>;\n}\n\nexport async function createStoryRecorder(\n index: string,\n options: StoryExecutionOptions,\n): Promise<StoryRecorder> {\n const ran = resolve(options.root ?? process.cwd());\n const root = repositoryRoot(ran);\n const storyFiles = await storyFilesFrom(index, ran, root);\n const observed: ObservedSubject[] = [];\n // Each case with the subject it was noted for, so the run's time finds it.\n const cases: { readonly subject: string; readonly observed: ObservedCase }[] = [];\n let seen = false;\n\n return {\n note: async (page, subjectId, complete) => {\n const journal = await drainExecution(page);\n if (journal === undefined) return;\n seen = true;\n // A story read at several widths is one declaration and several cases:\n // each width executed the story on its own, and a hook that reads the\n // width took a different branch at each.\n const widened = subjectId.replace(/^story:/, '');\n const storyId = storyIdOf(subjectId);\n const story = storyFiles.get(storyId);\n const precondition =\n story === undefined ? undefined : await preconditionOf(root, story.file);\n observed.push({\n owner: subjectId,\n journal,\n complete,\n ...(precondition === undefined ? {} : { preconditions: [precondition] }),\n });\n // The index names a story by where it is declared, which is the same\n // coordinate a person reads in the sidebar and the same one a diff\n // touches. A story the driving index does not know — a subject named on\n // the command line, a preview rebuilt since — has no file to be a case\n // in, and contributes to the file-level record only.\n //\n // FIXME: the row is owned by `story:<id>` and the case by `story.file`,\n // and the case index retires the cases of a file a run finished, read off\n // the rows. No row names a story file, so no case is ever retired by a\n // run: a story removed or renamed keeps its case until its file is\n // deleted.\n if (story !== undefined) {\n cases.push({\n subject: subjectId,\n observed: {\n file: story.file,\n name: `${story.title}/${story.name}${widened.slice(storyId.length)}`,\n id: widened,\n stopped: !complete,\n journal,\n },\n });\n }\n },\n\n close: async (costs) => {\n if (!seen) {\n process.stderr.write(\n 'variance-authority: `tests` is on and the Storybook preview has no execution ' +\n 'collector in it — build it with `testSelectionProbes()` from ' +\n '`@variance-authority/sense/journal`, or the next `--since` will run ' +\n 'everything\\n',\n );\n return;\n }\n // A refusal is written and the run continues. Recording is an addition to\n // a visual run: losing it costs the *next* selection its narrowing, which\n // is a full suite — the safe direction — while failing the run over it\n // would cost this one its baselines, which is not.\n //\n // That holds for a throw as much as for a refusal. The recorder reports\n // what it declined in `because`, but it is a file format, a lock and a\n // filesystem underneath, and any of them can raise something it has no\n // sentence for. Letting that escape ends the run *after* every subject\n // has been rendered and compared — the most expensive possible moment to\n // lose a set of baselines, and over the half of the work that was only\n // ever an addition.\n let record: Awaited<ReturnType<typeof recordExecution>>;\n try {\n record = await recordExecution({\n root,\n subjects: zip(observed, timedOnce(observed.map((one) => one.owner), costs)),\n ...(options.label === undefined ? {} : { label: options.label }),\n ...(options.cacheRoot === undefined ? {} : { cacheRoot: options.cacheRoot }),\n // Against `root`, as the runner seams resolve them, never the checkout.\n ...(options.coverageFile === undefined\n ? {}\n : { coverageFile: resolve(ran, options.coverageFile) }),\n ...(options.suite === undefined ? {} : { suite: options.suite }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n ...(options.preconditions === undefined\n ? {}\n : { preconditions: options.preconditions }),\n ...(options.heads === undefined || options.heads.length === 0\n ? {}\n : { heads: options.heads }),\n ...(options.commit === undefined ? {} : { commit: options.commit }),\n ...(cases.length === 0\n ? {}\n : { cases: zip(cases.map((one) => one.observed), timedOnce(cases.map((one) => one.subject), costs)) }),\n ...(options.executionFile === undefined\n ? {}\n : { executionFile: resolve(ran, options.executionFile) }),\n });\n } catch (error) {\n process.stderr.write(\n 'variance-authority: recorded no story execution — the recorder failed with ' +\n `${error instanceof Error ? error.message : String(error)}; this run is ` +\n 'unaffected and the next `--since` will run everything\\n',\n );\n return;\n }\n if (!record.recorded) {\n process.stderr.write(\n `variance-authority: recorded no story execution — ${record.because}\\n`,\n );\n }\n },\n };\n}\n\n/**\n * The run's time for each noted subject, given to the first note of that\n * subject only.\n *\n * A subject read again — once more in the same world, once alone — is noted\n * each time, and the record sums what its entries carry; the run's time\n * already covers every reading, from the first collection to the decision.\n */\nfunction timedOnce(\n subjects: readonly string[],\n costs: ReadonlyMap<string, number> | undefined,\n): { readonly duration?: number }[] {\n const given = new Set<string>();\n return subjects.map((subject) => {\n const duration = costs?.get(subject);\n if (duration === undefined || given.has(subject)) return {};\n given.add(subject);\n return { duration };\n });\n}\n\nfunction zip<T>(entries: readonly T[], timed: readonly { readonly duration?: number }[]): T[] {\n return entries.map((entry, index) => ({ ...entry, ...timed[index] }));\n}\n\n/**\n * Story id to where it is declared, from the index the run is driving.\n *\n * The one route from a subject back to a file, and the reason a story's own\n * `.stories` file can select it: nothing *enters* a story file the way execution\n * enters a module, so without this a commit that edits one selects nothing. The\n * title and the name come along because the execution index names a case by its\n * declaration rather than by the id Storybook slugged from it.\n *\n * Storybook writes `importPath` from the directory it ran in, `./` and all. A\n * diff names files from the checkout, so the path is resolved from `ran` and\n * named from `root`; in a workspace the two are a package apart.\n */\nasync function storyFilesFrom(\n index: string,\n ran: string,\n root: string,\n): Promise<Map<string, StoryCoordinate>> {\n const parsed = parseStoryIndex(JSON.parse(await readFile(index, 'utf8')), index);\n return new Map(\n parsed.stories.map((story) => [\n story.id,\n {\n file: relative(root, resolve(ran, story.importPath)).split(sep).join('/'),\n title: story.title,\n name: story.name,\n },\n ]),\n );\n}\n\n/** Where a story is declared and what it is called there. */\ninterface StoryCoordinate {\n readonly file: string;\n readonly title: string;\n readonly name: string;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@variance-authority/storybook-collector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Turn a built or already-served Storybook into Variance Authority subjects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"variance-authority",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"build": "tsc --build"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@variance-authority/core": "^0.
|
|
44
|
-
"@variance-authority/dom": "^0.
|
|
45
|
-
"@variance-authority/playwright": "^0.
|
|
46
|
-
"@variance-authority/react": "^0.
|
|
47
|
-
"@variance-authority/sense": "^0.
|
|
48
|
-
"@variance-authority/storybook": "^0.
|
|
43
|
+
"@variance-authority/core": "^0.13.0",
|
|
44
|
+
"@variance-authority/dom": "^0.13.0",
|
|
45
|
+
"@variance-authority/playwright": "^0.13.0",
|
|
46
|
+
"@variance-authority/react": "^0.13.0",
|
|
47
|
+
"@variance-authority/sense": "^0.13.0",
|
|
48
|
+
"@variance-authority/storybook": "^0.13.0"
|
|
49
49
|
}
|
|
50
50
|
}
|