@codepress/design-kit 0.4.0 → 0.4.2

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 CHANGED
@@ -445,6 +445,6 @@ remove from markup, such as a mock API's) and a `session` object whose
445
445
  ## Contributing and license
446
446
 
447
447
  The source is on GitHub at
448
- [quantfive/design-kit](https://github.com/quantfive/design-kit), where issues
448
+ [codepressdev/design-kit](https://github.com/codepressdev/design-kit), where issues
449
449
  and pull requests are welcome; see its `CONTRIBUTING.md`. MIT licensed: see
450
450
  [`LICENSE`](./LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codepress/design-kit",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Capture your Storybook and real app pages as a static design kit, and compose self-contained mockups from it",
5
5
  "type": "module",
6
6
  "bin": {
@@ -63,11 +63,11 @@
63
63
  "license": "MIT",
64
64
  "repository": {
65
65
  "type": "git",
66
- "url": "git+https://github.com/quantfive/design-kit.git"
66
+ "url": "git+https://github.com/codepressdev/design-kit.git"
67
67
  },
68
- "homepage": "https://github.com/quantfive/design-kit#readme",
68
+ "homepage": "https://github.com/codepressdev/design-kit#readme",
69
69
  "bugs": {
70
- "url": "https://github.com/quantfive/design-kit/issues"
70
+ "url": "https://github.com/codepressdev/design-kit/issues"
71
71
  },
72
72
  "publishConfig": {
73
73
  "access": "public"
@@ -10,6 +10,7 @@
10
10
  * Needs Playwright's Chromium (`npx playwright install chromium`).
11
11
  */
12
12
  import { execFileSync, spawnSync } from "node:child_process";
13
+ import { createHash } from "node:crypto";
13
14
  import {
14
15
  copyFileSync,
15
16
  createReadStream,
@@ -62,6 +63,28 @@ export const kitId = (storyId, width) => `story:${storyId}@${width}`;
62
63
  export const kitFile = (id) => `html/${id.replace(/^story:/, "story--")}.html`;
63
64
  export const storyIdOf = (id) => id.replace(/^story:/, "").replace(/@\d+$/, "");
64
65
 
66
+ /**
67
+ * Holds each distinct sheet once. A capture's sheets come back as shared
68
+ * `{key, rules}` entries: an equal key and equal rules give the same entry,
69
+ * so a run keeps one copy of the CSS nearly every story loads instead of one
70
+ * per capture. A linked sheet is keyed by its path, so two captures can share
71
+ * a key with different rules; each keeps its own, and the kit chooses between
72
+ * them exactly as it did before.
73
+ */
74
+ export function sheetStore() {
75
+ const byKey = new Map(); // key -> Map(rules digest -> entry)
76
+ return (sheets) =>
77
+ sheets.map(({ key, rules }) => {
78
+ const digest = createHash("sha256")
79
+ .update(JSON.stringify(rules))
80
+ .digest("base64");
81
+ let variants = byKey.get(key);
82
+ if (!variants) byKey.set(key, (variants = new Map()));
83
+ if (!variants.has(digest)) variants.set(digest, { key, rules });
84
+ return variants.get(digest);
85
+ });
86
+ }
87
+
65
88
  /**
66
89
  * Sheets in a cascade-respecting order: each capture's sheets keep their
67
90
  * document order, and a sheet first seen later is placed after the sheet
@@ -974,6 +997,15 @@ export async function captureStories(config, options = {}) {
974
997
  const captures = new Map(); // kit id -> {story, viewport, result}
975
998
  const failures = [];
976
999
  const attempts = []; // every capture's timing, kept or not
1000
+ // Nearly every story loads the same sheets, a few hundred KB of rules
1001
+ // each; kept results share one copy of each (see sheetStore).
1002
+ const keepSheetsOnce = sheetStore();
1003
+ // What the timings report needs from a capture, without its result.
1004
+ const attempt = (capture) => {
1005
+ const record = { timing: capture.timing, failure: capture.failure };
1006
+ attempts.push(record);
1007
+ return record;
1008
+ };
977
1009
  let done = 0;
978
1010
  await pool(targets, concurrency, async (story) => {
979
1011
  const first = await captureOne({
@@ -986,7 +1018,7 @@ export async function captureStories(config, options = {}) {
986
1018
  families,
987
1019
  fixedTime,
988
1020
  });
989
- attempts.push(first);
1021
+ const firstAttempt = attempt(first);
990
1022
  let viewports = plannedViewports(story.title, null, planning);
991
1023
  const results = new Map([[planning.viewport.width, first]]);
992
1024
  if (first.result) {
@@ -994,7 +1026,7 @@ export async function captureStories(config, options = {}) {
994
1026
  viewports = plannedViewports(story.title, declared, planning);
995
1027
  if (declared) {
996
1028
  results.delete(planning.viewport.width);
997
- first.discarded = true;
1029
+ firstAttempt.discarded = true;
998
1030
  }
999
1031
  }
1000
1032
  for (const viewport of viewports) {
@@ -1009,7 +1041,7 @@ export async function captureStories(config, options = {}) {
1009
1041
  families,
1010
1042
  fixedTime,
1011
1043
  });
1012
- attempts.push(capture);
1044
+ attempt(capture);
1013
1045
  results.set(viewport.width, capture);
1014
1046
  }
1015
1047
  const capture = results.get(viewport.width);
@@ -1017,7 +1049,14 @@ export async function captureStories(config, options = {}) {
1017
1049
  if (capture.failure) {
1018
1050
  failures.push({ id, ...capture.failure });
1019
1051
  } else {
1020
- captures.set(id, { story, viewport, result: capture.result });
1052
+ captures.set(id, {
1053
+ story,
1054
+ viewport,
1055
+ result: {
1056
+ ...capture.result,
1057
+ sheets: keepSheetsOnce(capture.result.sheets),
1058
+ },
1059
+ });
1021
1060
  }
1022
1061
  }
1023
1062
  done += 1;
package/src/init.mjs CHANGED
@@ -36,6 +36,10 @@ export const WORKFLOW_PATH = ".github/workflows/design-kit.yml";
36
36
  export const SKILL_DIR = ".claude/skills/design-kit";
37
37
  export const AGENTS_SKILL_DIR = ".agents/skills/design-kit";
38
38
  const TODO = "TODO";
39
+ // The one line a finished (not dry-run) init ends with. Printed only; init
40
+ // makes no network call.
41
+ export const CALL_TO_ACTION =
42
+ "Want every screen on one canvas, shareable with your team, and agents that build it? → https://codepress.dev";
39
43
  /** How long a kit artifact is kept: the most a public repository allows. */
40
44
  export const RETENTION_DAYS = 90;
41
45
 
@@ -1196,5 +1200,6 @@ export function init({
1196
1200
  if (write.kind !== "unchanged") apply(write);
1197
1201
  }
1198
1202
  log(summary(found, plan, { dryRun }));
1203
+ if (!dryRun) log(`\n${CALL_TO_ACTION}`);
1199
1204
  return 0;
1200
1205
  }