bookcover-core 0.13.0 → 0.15.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 (109) hide show
  1. package/dist/barcode.d.ts +7 -1
  2. package/dist/barcode.js +10 -4
  3. package/dist/colors.d.ts +2 -1
  4. package/dist/colors.js +9 -4
  5. package/dist/design.js +12 -7
  6. package/dist/form_state.d.ts +13 -0
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +6 -3
  9. package/dist/patterns.d.ts +4 -1
  10. package/dist/patterns.js +90 -262
  11. package/dist/patterns_svg.d.ts +6 -0
  12. package/dist/patterns_svg.js +275 -0
  13. package/dist/split.js +19 -5
  14. package/package.json +21 -5
  15. package/dist/assets.d.ts.map +0 -1
  16. package/dist/assets.js.map +0 -1
  17. package/dist/barcode.d.ts.map +0 -1
  18. package/dist/barcode.js.map +0 -1
  19. package/dist/build_files.d.ts.map +0 -1
  20. package/dist/build_files.js.map +0 -1
  21. package/dist/builtin_bg_regions.d.ts +0 -15
  22. package/dist/builtin_bg_regions.d.ts.map +0 -1
  23. package/dist/builtin_bg_regions.js +0 -73
  24. package/dist/builtin_bg_regions.js.map +0 -1
  25. package/dist/builtin_icons.d.ts.map +0 -1
  26. package/dist/builtin_icons.js.map +0 -1
  27. package/dist/colors.d.ts.map +0 -1
  28. package/dist/colors.js.map +0 -1
  29. package/dist/data_file.d.ts.map +0 -1
  30. package/dist/data_file.js.map +0 -1
  31. package/dist/defaults.d.ts.map +0 -1
  32. package/dist/defaults.js.map +0 -1
  33. package/dist/design.d.ts.map +0 -1
  34. package/dist/design.js.map +0 -1
  35. package/dist/dimensions.d.ts.map +0 -1
  36. package/dist/dimensions.js.map +0 -1
  37. package/dist/font_manifest.d.ts +0 -3
  38. package/dist/font_manifest.d.ts.map +0 -1
  39. package/dist/font_manifest.js +0 -18
  40. package/dist/font_manifest.js.map +0 -1
  41. package/dist/font_sizes.d.ts.map +0 -1
  42. package/dist/font_sizes.js.map +0 -1
  43. package/dist/fonts.d.ts.map +0 -1
  44. package/dist/fonts.js.map +0 -1
  45. package/dist/form_schema.d.ts.map +0 -1
  46. package/dist/form_schema.js.map +0 -1
  47. package/dist/form_state.d.ts.map +0 -1
  48. package/dist/form_state.js.map +0 -1
  49. package/dist/frame.d.ts.map +0 -1
  50. package/dist/frame.js.map +0 -1
  51. package/dist/frame_assets.d.ts +0 -3
  52. package/dist/frame_assets.d.ts.map +0 -1
  53. package/dist/frame_assets.js +0 -4
  54. package/dist/frame_assets.js.map +0 -1
  55. package/dist/generated/builtin_bg_regions.d.ts.map +0 -1
  56. package/dist/generated/builtin_bg_regions.js.map +0 -1
  57. package/dist/generated/font_manifest.json +0 -147
  58. package/dist/generated/han_hints.json +0 -7
  59. package/dist/generated/icon_svgs_data.d.ts.map +0 -1
  60. package/dist/generated/icon_svgs_data.js.map +0 -1
  61. package/dist/generated/noto_manifest.json +0 -2775
  62. package/dist/generated/templates_data.d.ts.map +0 -1
  63. package/dist/generated/templates_data.js.map +0 -1
  64. package/dist/generated/vector_bg_images_data.d.ts.map +0 -1
  65. package/dist/generated/vector_bg_images_data.js.map +0 -1
  66. package/dist/generated/vector_patterns_data.d.ts +0 -4
  67. package/dist/generated/vector_patterns_data.d.ts.map +0 -1
  68. package/dist/generated/vector_patterns_data.js +0 -33
  69. package/dist/generated/vector_patterns_data.js.map +0 -1
  70. package/dist/icon_cache.d.ts.map +0 -1
  71. package/dist/icon_cache.js.map +0 -1
  72. package/dist/image_regions.d.ts.map +0 -1
  73. package/dist/image_regions.js.map +0 -1
  74. package/dist/index.d.ts.map +0 -1
  75. package/dist/index.js.map +0 -1
  76. package/dist/noto_fonts.d.ts +0 -21
  77. package/dist/noto_fonts.d.ts.map +0 -1
  78. package/dist/noto_fonts.js +0 -208
  79. package/dist/noto_fonts.js.map +0 -1
  80. package/dist/patterns.d.ts.map +0 -1
  81. package/dist/patterns.js.map +0 -1
  82. package/dist/printers.d.ts +0 -17
  83. package/dist/printers.d.ts.map +0 -1
  84. package/dist/printers.js +0 -52
  85. package/dist/printers.js.map +0 -1
  86. package/dist/schema.d.ts.map +0 -1
  87. package/dist/schema.js.map +0 -1
  88. package/dist/split.d.ts.map +0 -1
  89. package/dist/split.js.map +0 -1
  90. package/dist/template_content.d.ts +0 -3
  91. package/dist/template_content.d.ts.map +0 -1
  92. package/dist/template_content.js +0 -4
  93. package/dist/template_content.js.map +0 -1
  94. package/dist/templates_data.d.ts +0 -4
  95. package/dist/templates_data.d.ts.map +0 -1
  96. package/dist/templates_data.js +0 -8
  97. package/dist/templates_data.js.map +0 -1
  98. package/dist/themes.d.ts +0 -12
  99. package/dist/themes.d.ts.map +0 -1
  100. package/dist/themes.js +0 -49
  101. package/dist/themes.js.map +0 -1
  102. package/dist/utils.d.ts.map +0 -1
  103. package/dist/utils.js.map +0 -1
  104. package/dist/vector_backgrounds.d.ts.map +0 -1
  105. package/dist/vector_backgrounds.js.map +0 -1
  106. package/dist/vector_patterns_data.d.ts +0 -4
  107. package/dist/vector_patterns_data.d.ts.map +0 -1
  108. package/dist/vector_patterns_data.js +0 -66
  109. package/dist/vector_patterns_data.js.map +0 -1
package/dist/barcode.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  /**
2
2
  * Generate an ISBN-13 barcode as SVG bytes sized to the given region.
3
- * Uses toSVG() which is platform-independent (no canvas / Node Buffer required).
4
3
  * width_mm/height_mm are from printing-services cover_region_barcode (mm).
4
+ *
5
+ * Calls the isbn encoder directly rather than bwip-js's toSVG(). toSVG() dispatches on the
6
+ * bcid string, and that lookup table references all ~110 symbologies, so none of them can be
7
+ * dropped — the dispatch alone costs ~1.5MB of encoders we never use. Naming the encoder
8
+ * leaves only its own code reachable. The 'generic' entry point also avoids the canvas/DOM
9
+ * path, which is dead weight here on both platforms. Output is unchanged: this is the same
10
+ * encoder and the same SVG drawing backend toSVG() would have reached.
5
11
  */
6
12
  export declare function generate_isbn_barcode(isbn: string, width_mm: number, height_mm: number): Uint8Array;
7
13
  //# sourceMappingURL=barcode.d.ts.map
package/dist/barcode.js CHANGED
@@ -1,16 +1,22 @@
1
1
  // ISBN barcode generation using bwip-js (SVG output — works in both Node and browser)
2
- import * as bwipjs from 'bwip-js';
2
+ import { isbn as bwipp_isbn, drawingSVG } from 'bwip-js/generic';
3
3
  const encoder = new TextEncoder();
4
4
  /**
5
5
  * Generate an ISBN-13 barcode as SVG bytes sized to the given region.
6
- * Uses toSVG() which is platform-independent (no canvas / Node Buffer required).
7
6
  * width_mm/height_mm are from printing-services cover_region_barcode (mm).
7
+ *
8
+ * Calls the isbn encoder directly rather than bwip-js's toSVG(). toSVG() dispatches on the
9
+ * bcid string, and that lookup table references all ~110 symbologies, so none of them can be
10
+ * dropped — the dispatch alone costs ~1.5MB of encoders we never use. Naming the encoder
11
+ * leaves only its own code reachable. The 'generic' entry point also avoids the canvas/DOM
12
+ * path, which is dead weight here on both platforms. Output is unchanged: this is the same
13
+ * encoder and the same SVG drawing backend toSVG() would have reached.
8
14
  */
9
15
  export function generate_isbn_barcode(isbn, width_mm, height_mm) {
10
16
  // Trim surrounding whitespace but preserve internal dashes —
11
17
  // bwip-js requires dashes for ISBN grouping validation
12
18
  // bwip-js width/height are in mm
13
- const svg = bwipjs.toSVG({
19
+ const svg = bwipp_isbn({
14
20
  bcid: 'isbn',
15
21
  text: isbn.trim(),
16
22
  includetext: true,
@@ -19,7 +25,7 @@ export function generate_isbn_barcode(isbn, width_mm, height_mm) {
19
25
  paddingwidth: 10, // 1cm seems reasonable (not set according to any spec though)
20
26
  paddingheight: 10, // 1cm seems reasonable (not set according to any spec though)
21
27
  backgroundcolor: 'ffffff', // KDP and others are picky and insist on black/white
22
- });
28
+ }, drawingSVG());
23
29
  return encoder.encode(svg);
24
30
  }
25
31
  //# sourceMappingURL=barcode.js.map
package/dist/colors.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /** Convert a hex color string to an HSL tuple [h, s, l] */
2
2
  export declare function hex_to_hsl(hex: string): [number, number, number];
3
- /** Return true when white text has better contrast than black text against this color (WCAG) */
3
+ /** Return true when white text has better contrast against this color than the near-black
4
+ * text it pairs with (see DARK_TEXT_LUMINANCE) */
4
5
  export declare function is_dark_color(hex: string): boolean;
5
6
  /** Color values derived from the form's bg_color and spine_color */
6
7
  export interface DerivedColors {
package/dist/colors.js CHANGED
@@ -27,13 +27,18 @@ function relative_luminance(hex) {
27
27
  const b = to_linear(parseInt(hex.slice(5, 7), 16) / 255);
28
28
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
29
29
  }
30
- /** Return true when white text has better contrast than black text against this color (WCAG) */
30
+ // Luminance of the near-black (#1a1a1a = hsl(0deg, 0%, 10%)) that pairs with white as this
31
+ // module's auto text color — a printable K90 gray rather than pure black. The choice below is
32
+ // made against THIS, not pure black: near-black has less contrast than black does, so
33
+ // comparing against black picks it on mid-gray backgrounds where white actually reads better
34
+ const DARK_TEXT_LUMINANCE = relative_luminance('#1a1a1a');
35
+ /** Return true when white text has better contrast against this color than the near-black
36
+ * text it pairs with (see DARK_TEXT_LUMINANCE) */
31
37
  export function is_dark_color(hex) {
32
38
  const L = relative_luminance(hex);
33
- // Contrast ratio with white (L=1) vs black (L=0)
34
39
  const contrast_white = 1.05 / (L + 0.05);
35
- const contrast_black = (L + 0.05) / 0.05;
36
- return contrast_white > contrast_black;
40
+ const contrast_dark = (L + 0.05) / (DARK_TEXT_LUMINANCE + 0.05);
41
+ return contrast_white > contrast_dark;
37
42
  }
38
43
  /** Format HSL components as hsl(Hdeg, S%, L%) — compatible with CSS4 and Typst's color.hsl() */
39
44
  function fmt_hsl(h, s, l) {
package/dist/design.js CHANGED
@@ -108,18 +108,23 @@ export function generate_palette(base, count, scheme) {
108
108
  }
109
109
  return colors;
110
110
  }
111
- /** True when white text has more WCAG contrast than black against this color */
111
+ // The two colors auto text falls back to. The dark one is a near-black (K90% for print, see
112
+ // COLOR_DEFAULTS) rather than pure black, and its luminance is what the choice below is made
113
+ // against — comparing against PURE black instead picks it on mid-gray backgrounds where white
114
+ // actually reads better, since near-black's own contrast is lower than black's
115
+ const AUTO_TEXT_LIGHT = 'hsl(0deg, 0%, 100%)';
116
+ const AUTO_TEXT_DARK = 'hsl(0deg, 0%, 10%)';
117
+ const AUTO_TEXT_DARK_LUMINANCE = chroma.hsl(0, 0, 0.1).luminance();
118
+ /** True when the light auto text reads better than the dark one against this color */
112
119
  function is_dark(c) {
113
120
  const L = c.luminance();
114
- const contrast_white = 1.05 / (L + 0.05);
115
- const contrast_black = (L + 0.05) / 0.05;
116
- return contrast_white >= contrast_black;
121
+ const contrast_light = 1.05 / (L + 0.05);
122
+ const contrast_dark = (L + 0.05) / (AUTO_TEXT_DARK_LUMINANCE + 0.05);
123
+ return contrast_light >= contrast_dark;
117
124
  }
118
125
  /** Return white or near-black, whichever has more WCAG contrast against the given background */
119
126
  function auto_contrast_text(bg) {
120
- return is_dark(from_hsl(bg))
121
- ? 'hsl(0deg, 0%, 100%)' // white — better on dark backgrounds
122
- : 'hsl(0deg, 0%, 10%)'; // near-black (K90% for print)
127
+ return is_dark(from_hsl(bg)) ? AUTO_TEXT_LIGHT : AUTO_TEXT_DARK;
123
128
  }
124
129
  /** Same contrast choice as auto_contrast_text, but hex-in/hex-out — for callers (pick_vivid_tint)
125
130
  * that need to stay in hex rather than the hsl(Hdeg, S%, L%) string format */
@@ -112,6 +112,19 @@ export interface EmbedFormState {
112
112
  /** Live form values — adds the background image File, which is held only in the browser and
113
113
  * never serialized with the rest of the form */
114
114
  export interface FormState extends EmbedFormState {
115
+ /** The background image, held byte-for-byte.
116
+ *
117
+ * BYTES ROUND-TRIP UNMODIFIED. A File put in this slot — whether the user uploaded it, a
118
+ * host handed it over the embed protocol, or it was fetched from the built-in backgrounds
119
+ * — is the exact File handed back out again: never re-encoded, resized, recompressed or
120
+ * stripped of metadata. So any host may use the bytes themselves as the image's identity
121
+ * (hashing them to recognise an image it already stores), and that identity survives a
122
+ * round trip through the editor.
123
+ *
124
+ * Everything the editor derives FROM the pixels — crop/coverage choices, sampled colors,
125
+ * region analysis — lives in the form values or is recomputed at render time, never by
126
+ * rewriting this file. Downscaling for preview rendering is fine, but the result is a
127
+ * separate Blob that must not be written back here. */
115
128
  bg_image: File | null;
116
129
  }
117
130
  /** Plain object with blank/empty values — no demo content, white background, no icon or
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { collect_fonts, collect_all_fonts, collect_fallback_fonts, all_fonts_bun
12
12
  export { asset_path, FRAMES_DIR, BACKGROUNDS_DIR } from './assets.js';
13
13
  export { DEFAULT_TEMPLATES } from './generated/templates_data.js';
14
14
  export { list_patterns, find_pattern } from './patterns.js';
15
- export type { PatternDef } from './patterns.js';
15
+ export type { PatternDef, PatternId } from './patterns.js';
16
16
  export { list_vector_backgrounds, find_vector_background } from './vector_backgrounds.js';
17
17
  export { list_builtin_icons, find_builtin_icon } from './builtin_icons.js';
18
18
  export type { VectorBackgroundDef } from './vector_backgrounds.js';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { resolve_colors, resolve_font_configs, darken_hsl, mix_hsl, generate_pal
7
7
  import { build_cover_files } from './build_files.js';
8
8
  import { DEFAULT_TEMPLATES } from './generated/templates_data.js';
9
9
  import { resolve_icon } from './icon_cache.js';
10
- import { find_pattern } from './patterns.js';
10
+ import { find_pattern_svg } from './patterns_svg.js';
11
11
  import { find_vector_background } from './vector_backgrounds.js';
12
12
  import { resolve_fallback_chain, cjk_segments, cjk_family, font_style } from 'typst-fonts';
13
13
  import { resolve_field_cjk_variant, collect_fallback_fonts } from './fonts.js';
@@ -16,6 +16,9 @@ export { default_spine_title } from './utils.js';
16
16
  export { collect_fonts, collect_all_fonts, collect_fallback_fonts, all_fonts_bundled, resolve_cjk_variant, resolve_field_cjk_variant } from './fonts.js';
17
17
  export { asset_path, FRAMES_DIR, BACKGROUNDS_DIR } from './assets.js';
18
18
  export { DEFAULT_TEMPLATES } from './generated/templates_data.js';
19
+ // Pattern metadata only — the SVG payload is deliberately NOT re-exported here, so importing
20
+ // this barrel (as the widget's main thread does) never pulls it in. Reach it via the
21
+ // 'bookcover-core/patterns-svg' subpath instead
19
22
  export { list_patterns, find_pattern } from './patterns.js';
20
23
  export { list_vector_backgrounds, find_vector_background } from './vector_backgrounds.js';
21
24
  export { list_builtin_icons, find_builtin_icon } from './builtin_icons.js';
@@ -158,8 +161,8 @@ export async function build(schema, image, frame_fn, frame_data, templates = DEF
158
161
  ?? (schema_resolved.bg_color_gradient
159
162
  ? colors.front_background
160
163
  : darken_hsl(colors.front_background, 0.05));
161
- const pat = find_pattern(schema_resolved.pattern);
162
- const svg = await resolve_icon(pat ? pat.svg : schema_resolved.pattern, color_pattern);
164
+ const pat_svg = find_pattern_svg(schema_resolved.pattern);
165
+ const svg = await resolve_icon(pat_svg ?? schema_resolved.pattern, color_pattern);
163
166
  // Parse natural SVG dimensions to preserve aspect ratio when tiling
164
167
  const svg_w = parseFloat(svg.match(/\bwidth="([0-9.]+)"/)?.[1] ?? '1');
165
168
  const svg_h = parseFloat(svg.match(/\bheight="([0-9.]+)"/)?.[1] ?? '1');
@@ -1,8 +1,11 @@
1
+ /** Union of every built-in pattern ID — keeps PATTERN_SVGS in patterns_svg.ts exhaustive,
2
+ * so adding a pattern here without its SVG (or vice versa) is a type error */
3
+ export type PatternId = 'anchors-away' | 'architect' | 'autumn' | 'aztec' | 'bamboo' | 'bank-note' | 'bathroom-floor' | 'bevel-circle' | 'boxes' | 'brick-wall' | 'bubbles' | 'cage' | 'charlie-brown' | 'church-on-sunday' | 'circles-and-squares' | 'circuit-board' | 'connections' | 'cork-screw' | 'current' | 'curtain' | 'cutout' | 'death-star' | 'diagonal-lines' | 'diagonal-stripes' | 'dominos' | 'endless-clouds' | 'eyes' | 'falling-triangles' | 'fancy-rectangles' | 'flipped-diamonds' | 'floating-cogs' | 'floor-tile' | 'formal-invitation' | 'four-point-stars' | 'glamorous' | 'graph-paper' | 'groovy' | 'happy-intersection' | 'heavy-rain' | 'hexagons' | 'hideout' | 'houndstooth' | 'i-like-food' | 'intersecting-circles' | 'jigsaw' | 'jupiter' | 'kiwi' | 'leaf' | 'lines-in-motion' | 'lips' | 'lisbon' | 'melt' | 'moroccan' | 'morphing-diamonds' | 'overcast' | 'overlapping-circles' | 'overlapping-diamonds' | 'overlapping-hexagons' | 'parkay-floor' | 'piano-man' | 'pie-factory' | 'pixel-dots' | 'plus' | 'polka-dots' | 'rails' | 'rain' | 'random-shapes' | 'rounded-plus-connected' | 'signal' | 'skulls' | 'slanted-stars' | 'squares-in-squares' | 'squares' | 'stamp-collection' | 'steel-beams' | 'stripes' | 'temple' | 'texture' | 'tic-tac-toe' | 'tiny-checkers' | 'topography' | 'volcano-lamp' | 'wallpaper' | 'wiggle' | 'x-equals' | 'yyy' | 'zig-zag';
1
4
  export interface PatternDef {
2
5
  id: string;
3
6
  name: string;
4
- svg: string;
5
7
  tile_mm: number;
8
+ aspect_ratio: number;
6
9
  }
7
10
  /** Look up a pattern by ID — internal use only */
8
11
  export declare function find_pattern(id: string): PatternDef | undefined;