bytecut 0.2.1 → 0.3.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.
Files changed (27) hide show
  1. package/README.md +18 -4
  2. package/dist/{audit-EBKL6L65.js → audit-RKJNHNDZ.js} +11 -11
  3. package/dist/{check-XTTU5SCZ.js → check-MN7R7XOM.js} +10 -10
  4. package/dist/{chunk-IZ4JEL3Q.js → chunk-4AM2CCML.js} +1 -1
  5. package/dist/{chunk-4FIB6VNC.js → chunk-7RHHOWQT.js} +1 -1
  6. package/dist/{chunk-KN5QOB7R.js → chunk-ABHEWNYQ.js} +4 -4
  7. package/dist/{chunk-TCQFQ354.js → chunk-CSDZGNUN.js} +14 -3
  8. package/dist/{chunk-WI4ZO7GP.js → chunk-DZLFVN4G.js} +14 -11
  9. package/dist/{chunk-PQRBLHCC.js → chunk-EM7JMQND.js} +1 -1
  10. package/dist/{chunk-HLBNRB3S.js → chunk-GNW3OK5U.js} +198 -44
  11. package/dist/{chunk-RZ2V4PCS.js → chunk-JMMXC5UA.js} +3 -3
  12. package/dist/{chunk-FY53B4NB.js → chunk-KJK7XGWA.js} +24 -13
  13. package/dist/{chunk-QOG2F4SF.js → chunk-L5HLKZDW.js} +2 -2
  14. package/dist/{chunk-MV6J66AP.js → chunk-MUE3L5XT.js} +1 -1
  15. package/dist/{chunk-SKANYRVT.js → chunk-NOTYXNMY.js} +1 -1
  16. package/dist/{chunk-3PF6BBFK.js → chunk-PE5NKZCH.js} +18 -8
  17. package/dist/{chunk-S3FQYUTI.js → chunk-SMR2764T.js} +1 -1
  18. package/dist/{chunk-7DHE25UE.js → chunk-UZ3Z2T5I.js} +1 -1
  19. package/dist/cli.js +22 -22
  20. package/dist/{compare-MPPGTUC5.js → compare-XRMDMCZL.js} +8 -8
  21. package/dist/{doctor-PWCUEBD5.js → doctor-YYTLIOVG.js} +5 -5
  22. package/dist/{explain-LKOB7FRT.js → explain-GZWGHYRY.js} +12 -7
  23. package/dist/{init-CWDWVJ55.js → init-3IQAWWBW.js} +4 -4
  24. package/dist/{optimize-TLJG7UYF.js → optimize-BDPL4Y2Z.js} +11 -11
  25. package/dist/{snippet-IIPVF6PS.js → snippet-6P7CMROL.js} +7 -7
  26. package/dist/{tui-6WSMCHZS.js → tui-ETSPQFXB.js} +29 -17
  27. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BytecutError
4
- } from "./chunk-FY53B4NB.js";
4
+ } from "./chunk-KJK7XGWA.js";
5
5
 
6
6
  // src/cli/system.ts
7
7
  import { execFile } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BytecutError
4
- } from "./chunk-FY53B4NB.js";
4
+ } from "./chunk-KJK7XGWA.js";
5
5
 
6
6
  // src/core/compare/server.ts
7
7
  import { randomBytes } from "crypto";
package/dist/cli.js CHANGED
@@ -2,25 +2,25 @@
2
2
  import {
3
3
  collectDoctorReport,
4
4
  formatDoctorReport
5
- } from "./chunk-PQRBLHCC.js";
5
+ } from "./chunk-EM7JMQND.js";
6
6
  import {
7
7
  svgoEngine
8
8
  } from "./chunk-LTWUPQDT.js";
9
9
  import {
10
10
  audit
11
- } from "./chunk-WI4ZO7GP.js";
11
+ } from "./chunk-DZLFVN4G.js";
12
12
  import {
13
13
  package_default
14
- } from "./chunk-SKANYRVT.js";
14
+ } from "./chunk-NOTYXNMY.js";
15
15
  import {
16
16
  formatAuditReport
17
- } from "./chunk-HLBNRB3S.js";
17
+ } from "./chunk-GNW3OK5U.js";
18
18
  import "./chunk-3DBJKHOD.js";
19
- import "./chunk-TCQFQ354.js";
19
+ import "./chunk-CSDZGNUN.js";
20
20
  import {
21
21
  sharpImageEngine
22
22
  } from "./chunk-CSFBJ3UH.js";
23
- import "./chunk-RZ2V4PCS.js";
23
+ import "./chunk-JMMXC5UA.js";
24
24
  import {
25
25
  createVideoEngine,
26
26
  discover,
@@ -28,17 +28,17 @@ import {
28
28
  ffmpegStatus,
29
29
  makeScorerFactory,
30
30
  noAssetsMessage
31
- } from "./chunk-KN5QOB7R.js";
31
+ } from "./chunk-ABHEWNYQ.js";
32
32
  import {
33
33
  doctorDeps
34
- } from "./chunk-S3FQYUTI.js";
35
- import "./chunk-QOG2F4SF.js";
36
- import "./chunk-3PF6BBFK.js";
37
- import "./chunk-IZ4JEL3Q.js";
34
+ } from "./chunk-SMR2764T.js";
35
+ import "./chunk-L5HLKZDW.js";
36
+ import "./chunk-PE5NKZCH.js";
37
+ import "./chunk-4AM2CCML.js";
38
38
  import {
39
39
  guarded
40
- } from "./chunk-MV6J66AP.js";
41
- import "./chunk-FY53B4NB.js";
40
+ } from "./chunk-MUE3L5XT.js";
41
+ import "./chunk-KJK7XGWA.js";
42
42
 
43
43
  // src/cli/index.ts
44
44
  import { defineCommand, runMain } from "citty";
@@ -57,7 +57,7 @@ async function runDefault() {
57
57
  return;
58
58
  }
59
59
  if (isInteractive()) {
60
- const { runTui } = await import("./tui-6WSMCHZS.js");
60
+ const { runTui } = await import("./tui-ETSPQFXB.js");
61
61
  await runTui({
62
62
  projectRoot: found.projectRoot,
63
63
  project: found.project,
@@ -125,14 +125,14 @@ var main = defineCommand({
125
125
  await runDefault();
126
126
  }),
127
127
  subCommands: {
128
- audit: () => import("./audit-EBKL6L65.js").then((m) => m.default),
129
- optimize: () => import("./optimize-TLJG7UYF.js").then((m) => m.default),
130
- snippet: () => import("./snippet-IIPVF6PS.js").then((m) => m.default),
131
- compare: () => import("./compare-MPPGTUC5.js").then((m) => m.default),
132
- explain: () => import("./explain-LKOB7FRT.js").then((m) => m.default),
133
- init: () => import("./init-CWDWVJ55.js").then((m) => m.default),
134
- check: () => import("./check-XTTU5SCZ.js").then((m) => m.default),
135
- doctor: () => import("./doctor-PWCUEBD5.js").then((m) => m.default)
128
+ audit: () => import("./audit-RKJNHNDZ.js").then((m) => m.default),
129
+ optimize: () => import("./optimize-BDPL4Y2Z.js").then((m) => m.default),
130
+ snippet: () => import("./snippet-6P7CMROL.js").then((m) => m.default),
131
+ compare: () => import("./compare-XRMDMCZL.js").then((m) => m.default),
132
+ explain: () => import("./explain-GZWGHYRY.js").then((m) => m.default),
133
+ init: () => import("./init-3IQAWWBW.js").then((m) => m.default),
134
+ check: () => import("./check-MN7R7XOM.js").then((m) => m.default),
135
+ doctor: () => import("./doctor-YYTLIOVG.js").then((m) => m.default)
136
136
  }
137
137
  });
138
138
  await runMain(main);
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startCompareServer
4
- } from "./chunk-7DHE25UE.js";
4
+ } from "./chunk-UZ3Z2T5I.js";
5
5
  import {
6
6
  MANIFEST_FILE,
7
7
  parseManifest
8
- } from "./chunk-TCQFQ354.js";
8
+ } from "./chunk-CSDZGNUN.js";
9
9
  import {
10
10
  configArg,
11
11
  discover
12
- } from "./chunk-KN5QOB7R.js";
13
- import "./chunk-S3FQYUTI.js";
12
+ } from "./chunk-ABHEWNYQ.js";
13
+ import "./chunk-SMR2764T.js";
14
14
  import {
15
15
  toPosix
16
- } from "./chunk-QOG2F4SF.js";
17
- import "./chunk-3PF6BBFK.js";
16
+ } from "./chunk-L5HLKZDW.js";
17
+ import "./chunk-PE5NKZCH.js";
18
18
  import {
19
19
  guarded
20
- } from "./chunk-MV6J66AP.js";
20
+ } from "./chunk-MUE3L5XT.js";
21
21
  import {
22
22
  BytecutError
23
- } from "./chunk-FY53B4NB.js";
23
+ } from "./chunk-KJK7XGWA.js";
24
24
 
25
25
  // src/cli/commands/compare.ts
26
26
  import { readFile } from "fs/promises";
@@ -2,24 +2,24 @@
2
2
  import {
3
3
  collectDoctorReport,
4
4
  formatDoctorReport
5
- } from "./chunk-PQRBLHCC.js";
5
+ } from "./chunk-EM7JMQND.js";
6
6
  import {
7
7
  doctorDeps
8
- } from "./chunk-S3FQYUTI.js";
8
+ } from "./chunk-SMR2764T.js";
9
9
  import {
10
10
  resolveConfig
11
- } from "./chunk-3PF6BBFK.js";
11
+ } from "./chunk-PE5NKZCH.js";
12
12
  import {
13
13
  isGitIgnored
14
14
  } from "./chunk-DJ45NQZD.js";
15
15
  import {
16
16
  guarded
17
- } from "./chunk-MV6J66AP.js";
17
+ } from "./chunk-MUE3L5XT.js";
18
18
  import {
19
19
  BytecutError,
20
20
  detectProject,
21
21
  loadConfig
22
- } from "./chunk-FY53B4NB.js";
22
+ } from "./chunk-KJK7XGWA.js";
23
23
 
24
24
  // src/cli/commands/doctor.ts
25
25
  import { defineCommand } from "citty";
@@ -8,27 +8,27 @@ import {
8
8
  mirroredDir,
9
9
  outputWidths,
10
10
  plannedVideoOutputs
11
- } from "./chunk-RZ2V4PCS.js";
11
+ } from "./chunk-JMMXC5UA.js";
12
12
  import {
13
13
  configArg,
14
14
  createVideoEngine,
15
15
  discover
16
- } from "./chunk-KN5QOB7R.js";
17
- import "./chunk-S3FQYUTI.js";
16
+ } from "./chunk-ABHEWNYQ.js";
17
+ import "./chunk-SMR2764T.js";
18
18
  import {
19
19
  toPosix
20
- } from "./chunk-QOG2F4SF.js";
20
+ } from "./chunk-L5HLKZDW.js";
21
21
  import {
22
22
  getVideoPreset
23
- } from "./chunk-3PF6BBFK.js";
23
+ } from "./chunk-PE5NKZCH.js";
24
24
  import {
25
25
  guarded
26
- } from "./chunk-MV6J66AP.js";
26
+ } from "./chunk-MUE3L5XT.js";
27
27
  import {
28
28
  BytecutError,
29
29
  formatBytes,
30
30
  matchesGlob
31
- } from "./chunk-FY53B4NB.js";
31
+ } from "./chunk-KJK7XGWA.js";
32
32
 
33
33
  // src/cli/commands/explain.ts
34
34
  import { stat } from "fs/promises";
@@ -201,6 +201,11 @@ function formatExplanation(e) {
201
201
  lines.push(
202
202
  ` search: ${r.search.metric} >= ${r.search.target} on the worst of 3 sampled clips (crf above is the starting point)`
203
203
  );
204
+ if (r.search.maxBytes !== void 0) {
205
+ lines.push(
206
+ ` size cap: at most ${formatBytes(r.search.maxBytes)} per file; quality may fall to ${r.search.metric} ${r.search.floor}, then the width steps down (never below half)`
207
+ );
208
+ }
204
209
  }
205
210
  }
206
211
  if (e.outputs.length > 0) {
@@ -6,20 +6,20 @@ import {
6
6
  applyChoices,
7
7
  isEmpty,
8
8
  renderConfig
9
- } from "./chunk-4FIB6VNC.js";
9
+ } from "./chunk-7RHHOWQT.js";
10
10
  import {
11
11
  writeConfigFile
12
- } from "./chunk-IZ4JEL3Q.js";
12
+ } from "./chunk-4AM2CCML.js";
13
13
  import {
14
14
  guarded
15
- } from "./chunk-MV6J66AP.js";
15
+ } from "./chunk-MUE3L5XT.js";
16
16
  import {
17
17
  BytecutError,
18
18
  FRAMEWORKS,
19
19
  PLACEHOLDERS,
20
20
  detectProject,
21
21
  findConfigFiles
22
- } from "./chunk-FY53B4NB.js";
22
+ } from "./chunk-KJK7XGWA.js";
23
23
 
24
24
  // src/cli/commands/init.ts
25
25
  import { relative } from "path";
@@ -1,42 +1,42 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  package_default
4
- } from "./chunk-SKANYRVT.js";
4
+ } from "./chunk-NOTYXNMY.js";
5
5
  import {
6
6
  formatFindings,
7
7
  formatPlan,
8
8
  formatSummary,
9
9
  optimize
10
- } from "./chunk-HLBNRB3S.js";
10
+ } from "./chunk-GNW3OK5U.js";
11
11
  import "./chunk-3DBJKHOD.js";
12
12
  import {
13
13
  isPlaceholderKind,
14
14
  parsePlan,
15
15
  serializePlan
16
- } from "./chunk-TCQFQ354.js";
16
+ } from "./chunk-CSDZGNUN.js";
17
17
  import {
18
18
  sharpImageEngine
19
19
  } from "./chunk-CSFBJ3UH.js";
20
- import "./chunk-RZ2V4PCS.js";
20
+ import "./chunk-JMMXC5UA.js";
21
21
  import {
22
22
  configArg,
23
23
  createVideoEngine,
24
24
  ffmpegInstallText,
25
25
  makeScorerFactory
26
- } from "./chunk-KN5QOB7R.js";
27
- import "./chunk-S3FQYUTI.js";
28
- import "./chunk-QOG2F4SF.js";
26
+ } from "./chunk-ABHEWNYQ.js";
27
+ import "./chunk-SMR2764T.js";
28
+ import "./chunk-L5HLKZDW.js";
29
29
  import {
30
30
  resolveConfig
31
- } from "./chunk-3PF6BBFK.js";
32
- import "./chunk-IZ4JEL3Q.js";
31
+ } from "./chunk-PE5NKZCH.js";
32
+ import "./chunk-4AM2CCML.js";
33
33
  import {
34
34
  guarded
35
- } from "./chunk-MV6J66AP.js";
35
+ } from "./chunk-MUE3L5XT.js";
36
36
  import {
37
37
  BytecutError,
38
38
  loadConfig
39
- } from "./chunk-FY53B4NB.js";
39
+ } from "./chunk-KJK7XGWA.js";
40
40
 
41
41
  // src/cli/commands/optimize.ts
42
42
  import { existsSync } from "fs";
@@ -8,22 +8,22 @@ import "./chunk-3DBJKHOD.js";
8
8
  import {
9
9
  MANIFEST_FILE,
10
10
  parseManifest
11
- } from "./chunk-TCQFQ354.js";
11
+ } from "./chunk-CSDZGNUN.js";
12
12
  import {
13
13
  configArg,
14
14
  discover
15
- } from "./chunk-KN5QOB7R.js";
16
- import "./chunk-S3FQYUTI.js";
15
+ } from "./chunk-ABHEWNYQ.js";
16
+ import "./chunk-SMR2764T.js";
17
17
  import {
18
18
  toPosix
19
- } from "./chunk-QOG2F4SF.js";
20
- import "./chunk-3PF6BBFK.js";
19
+ } from "./chunk-L5HLKZDW.js";
20
+ import "./chunk-PE5NKZCH.js";
21
21
  import {
22
22
  guarded
23
- } from "./chunk-MV6J66AP.js";
23
+ } from "./chunk-MUE3L5XT.js";
24
24
  import {
25
25
  BytecutError
26
- } from "./chunk-FY53B4NB.js";
26
+ } from "./chunk-KJK7XGWA.js";
27
27
 
28
28
  // src/cli/commands/snippet.ts
29
29
  import { readFile } from "fs/promises";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  audit
4
- } from "./chunk-WI4ZO7GP.js";
4
+ } from "./chunk-DZLFVN4G.js";
5
5
  import {
6
6
  formatSummary,
7
7
  optimize
8
- } from "./chunk-HLBNRB3S.js";
8
+ } from "./chunk-GNW3OK5U.js";
9
9
  import {
10
10
  buildSnippet,
11
11
  originalUrl,
@@ -14,30 +14,30 @@ import {
14
14
  import "./chunk-3DBJKHOD.js";
15
15
  import {
16
16
  startCompareServer
17
- } from "./chunk-7DHE25UE.js";
17
+ } from "./chunk-UZ3Z2T5I.js";
18
18
  import {
19
19
  MANIFEST_FILE,
20
20
  parseManifest
21
- } from "./chunk-TCQFQ354.js";
22
- import "./chunk-RZ2V4PCS.js";
21
+ } from "./chunk-CSDZGNUN.js";
22
+ import "./chunk-JMMXC5UA.js";
23
23
  import {
24
24
  toPosix
25
- } from "./chunk-QOG2F4SF.js";
25
+ } from "./chunk-L5HLKZDW.js";
26
26
  import {
27
27
  resolveConfig,
28
28
  resolveConfigData
29
- } from "./chunk-3PF6BBFK.js";
29
+ } from "./chunk-PE5NKZCH.js";
30
30
  import {
31
31
  applyChoices,
32
32
  canRewrite,
33
33
  isEmpty,
34
34
  renderChoicesSnippet,
35
35
  renderConfig
36
- } from "./chunk-4FIB6VNC.js";
36
+ } from "./chunk-7RHHOWQT.js";
37
37
  import {
38
38
  SafeFs,
39
39
  writeConfigFile
40
- } from "./chunk-IZ4JEL3Q.js";
40
+ } from "./chunk-4AM2CCML.js";
41
41
  import {
42
42
  ALL_RULES,
43
43
  BytecutError,
@@ -46,7 +46,7 @@ import {
46
46
  parseConfig,
47
47
  percentChange,
48
48
  plural
49
- } from "./chunk-FY53B4NB.js";
49
+ } from "./chunk-KJK7XGWA.js";
50
50
 
51
51
  // src/tui/index.tsx
52
52
  import { render } from "ink";
@@ -72,7 +72,7 @@ var COMMANDS = [
72
72
  },
73
73
  {
74
74
  name: "preset",
75
- usage: "/preset <photo|hero|icon> [@file\u2026]",
75
+ usage: "/preset <preset> [@file\u2026]",
76
76
  description: "Set the preset for the highlighted (or mentioned) files"
77
77
  },
78
78
  {
@@ -306,6 +306,7 @@ function buildModel(report) {
306
306
  );
307
307
  rows.push({
308
308
  source,
309
+ kind: file.kind ?? "image",
309
310
  bytes: file.bytes,
310
311
  width: file.width,
311
312
  height: file.height,
@@ -405,11 +406,13 @@ import { Box as Box3, Text as Text3 } from "ink";
405
406
 
406
407
  // src/tui/state.ts
407
408
  var PRESET_CYCLE = ["photo", "hero", "icon"];
409
+ var VIDEO_PRESET_CYCLE = ["background-video", "content-video", "gif-to-video"];
408
410
  var EMPTY_MODEL = { rows: [], reportOnly: [], covered: 0, skipped: [], notes: [] };
409
- function initialState(outDir, presetNames = PRESET_CYCLE) {
411
+ function initialState(outDir, presetNames = PRESET_CYCLE, videoPresetNames = VIDEO_PRESET_CYCLE) {
410
412
  return {
411
413
  view: "scanning",
412
414
  presetNames: [...presetNames],
415
+ videoPresetNames: [...videoPresetNames],
413
416
  baseline: { presets: {}, outDir },
414
417
  save: null,
415
418
  snippet: null,
@@ -522,7 +525,8 @@ function reducer(state, action) {
522
525
  const row = state.model.rows.find((r) => r.source === source);
523
526
  if (!row) continue;
524
527
  const current = presets[source] ?? row.preset;
525
- const names = state.presetNames;
528
+ const names = row.kind === "video" ? state.videoPresetNames : state.presetNames;
529
+ if (action.to !== void 0 && !names.includes(action.to)) continue;
526
530
  const next = action.to ?? names[(names.indexOf(current) + 1) % names.length];
527
531
  if (next === row.preset) delete presets[source];
528
532
  else presets[source] = next;
@@ -1194,7 +1198,7 @@ function App(props) {
1194
1198
  const [state, dispatch] = useReducer(
1195
1199
  reducer,
1196
1200
  props.outDir,
1197
- (outDir) => initialState(outDir, props.presetNames)
1201
+ (outDir) => initialState(outDir, props.presetNames, props.videoPresetNames)
1198
1202
  );
1199
1203
  const [doctor, setDoctor] = useState(null);
1200
1204
  const stateRef = useRef(state);
@@ -1383,14 +1387,21 @@ function App(props) {
1383
1387
  return;
1384
1388
  case "preset": {
1385
1389
  const name = parsed.args[0];
1386
- if (!name || !s.presetNames.includes(name)) {
1390
+ const sources = targets.length > 0 ? targets : rowAt(s) ? [rowAt(s).source] : [];
1391
+ const kinds = new Set(
1392
+ sources.map((src) => s.model.rows.find((r) => r.source === src)?.kind ?? "image")
1393
+ );
1394
+ const valid = [
1395
+ ...kinds.has("image") || kinds.size === 0 ? s.presetNames : [],
1396
+ ...kinds.has("video") ? s.videoPresetNames : []
1397
+ ];
1398
+ if (!name || !valid.includes(name)) {
1387
1399
  dispatch({
1388
1400
  type: "status",
1389
- message: `Usage: /preset <${s.presetNames.join("|")}> [@file\u2026]`
1401
+ message: `Usage: /preset <${valid.join("|")}> [@file\u2026]`
1390
1402
  });
1391
1403
  return;
1392
1404
  }
1393
- const sources = targets.length > 0 ? targets : rowAt(s) ? [rowAt(s).source] : [];
1394
1405
  dispatch({ type: "cycle-preset", sources, to: name });
1395
1406
  return;
1396
1407
  }
@@ -1692,6 +1703,7 @@ async function runTui(options) {
1692
1703
  inputs: options.inputs,
1693
1704
  outDir: options.outDir,
1694
1705
  presetNames: options.config ? Object.keys(options.config.catalog.image) : void 0,
1706
+ videoPresetNames: options.config ? Object.keys(options.config.catalog.video) : void 0,
1695
1707
  loadDoctor: options.loadDoctor
1696
1708
  }
1697
1709
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bytecut",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Audit and optimize images and videos in web projects.",
5
5
  "type": "module",
6
6
  "license": "MIT",