@phosart/common 0.4.22

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 (178) hide show
  1. package/README.md +58 -0
  2. package/dist/FullGallery.svelte +51 -0
  3. package/dist/FullGallery.svelte.d.ts +17 -0
  4. package/dist/FullGallery.svelte.d.ts.map +1 -0
  5. package/dist/Gallery.svelte +30 -0
  6. package/dist/Gallery.svelte.d.ts +14 -0
  7. package/dist/Gallery.svelte.d.ts.map +1 -0
  8. package/dist/GalleryPreview.svelte +60 -0
  9. package/dist/GalleryPreview.svelte.d.ts +9 -0
  10. package/dist/GalleryPreview.svelte.d.ts.map +1 -0
  11. package/dist/HighResContext.svelte +21 -0
  12. package/dist/HighResContext.svelte.d.ts +8 -0
  13. package/dist/HighResContext.svelte.d.ts.map +1 -0
  14. package/dist/Image.svelte +171 -0
  15. package/dist/Image.svelte.d.ts +14 -0
  16. package/dist/Image.svelte.d.ts.map +1 -0
  17. package/dist/Modal.svelte +87 -0
  18. package/dist/Modal.svelte.d.ts +9 -0
  19. package/dist/Modal.svelte.d.ts.map +1 -0
  20. package/dist/ModalGallery/Carousel.svelte +76 -0
  21. package/dist/ModalGallery/Carousel.svelte.d.ts +10 -0
  22. package/dist/ModalGallery/Carousel.svelte.d.ts.map +1 -0
  23. package/dist/ModalGallery/ImageSection.svelte +156 -0
  24. package/dist/ModalGallery/ImageSection.svelte.d.ts +11 -0
  25. package/dist/ModalGallery/ImageSection.svelte.d.ts.map +1 -0
  26. package/dist/ModalGallery/ImageView.svelte +92 -0
  27. package/dist/ModalGallery/ImageView.svelte.d.ts +9 -0
  28. package/dist/ModalGallery/ImageView.svelte.d.ts.map +1 -0
  29. package/dist/ModalGallery/Spinner.svelte +71 -0
  30. package/dist/ModalGallery/Spinner.svelte.d.ts +7 -0
  31. package/dist/ModalGallery/Spinner.svelte.d.ts.map +1 -0
  32. package/dist/ModalGallery.svelte +165 -0
  33. package/dist/ModalGallery.svelte.d.ts +16 -0
  34. package/dist/ModalGallery.svelte.d.ts.map +1 -0
  35. package/dist/OpengraphMeta.svelte +125 -0
  36. package/dist/OpengraphMeta.svelte.d.ts +15 -0
  37. package/dist/OpengraphMeta.svelte.d.ts.map +1 -0
  38. package/dist/Postcard/ArtistLink.svelte +46 -0
  39. package/dist/Postcard/ArtistLink.svelte.d.ts +9 -0
  40. package/dist/Postcard/ArtistLink.svelte.d.ts.map +1 -0
  41. package/dist/Postcard/Chip.svelte +100 -0
  42. package/dist/Postcard/Chip.svelte.d.ts +12 -0
  43. package/dist/Postcard/Chip.svelte.d.ts.map +1 -0
  44. package/dist/Postcard/Description/Character.svelte +79 -0
  45. package/dist/Postcard/Description/Character.svelte.d.ts +9 -0
  46. package/dist/Postcard/Description/Character.svelte.d.ts.map +1 -0
  47. package/dist/Postcard/Description.svelte +146 -0
  48. package/dist/Postcard/Description.svelte.d.ts +13 -0
  49. package/dist/Postcard/Description.svelte.d.ts.map +1 -0
  50. package/dist/Postcard/Headline.svelte +70 -0
  51. package/dist/Postcard/Headline.svelte.d.ts +10 -0
  52. package/dist/Postcard/Headline.svelte.d.ts.map +1 -0
  53. package/dist/index.d.ts +17 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +17 -0
  56. package/dist/server/artist.d.ts +7 -0
  57. package/dist/server/artist.d.ts.map +1 -0
  58. package/dist/server/artist.js +40 -0
  59. package/dist/server/character.d.ts +9 -0
  60. package/dist/server/character.d.ts.map +1 -0
  61. package/dist/server/character.js +76 -0
  62. package/dist/server/directories.d.ts +4 -0
  63. package/dist/server/directories.d.ts.map +1 -0
  64. package/dist/server/directories.js +39 -0
  65. package/dist/server/fastcache.d.ts +11 -0
  66. package/dist/server/fastcache.d.ts.map +1 -0
  67. package/dist/server/fastcache.js +43 -0
  68. package/dist/server/filter.d.ts +6 -0
  69. package/dist/server/filter.d.ts.map +1 -0
  70. package/dist/server/filter.js +53 -0
  71. package/dist/server/gallery.d.ts +16 -0
  72. package/dist/server/gallery.d.ts.map +1 -0
  73. package/dist/server/gallery.js +162 -0
  74. package/dist/server/imageprocess.d.ts +18 -0
  75. package/dist/server/imageprocess.d.ts.map +1 -0
  76. package/dist/server/imageprocess.js +243 -0
  77. package/dist/server/index.d.ts +15 -0
  78. package/dist/server/index.d.ts.map +1 -0
  79. package/dist/server/index.js +15 -0
  80. package/dist/server/models/Artist.d.ts +7 -0
  81. package/dist/server/models/Artist.d.ts.map +1 -0
  82. package/dist/server/models/Artist.js +15 -0
  83. package/dist/server/models/Character.d.ts +108 -0
  84. package/dist/server/models/Character.d.ts.map +1 -0
  85. package/dist/server/models/Character.js +21 -0
  86. package/dist/server/models/Gallery.d.ts +373 -0
  87. package/dist/server/models/Gallery.d.ts.map +1 -0
  88. package/dist/server/models/Gallery.js +60 -0
  89. package/dist/server/models/image.d.ts +64 -0
  90. package/dist/server/models/image.d.ts.map +1 -0
  91. package/dist/server/models/image.js +17 -0
  92. package/dist/server/pack.d.ts +3 -0
  93. package/dist/server/pack.d.ts.map +1 -0
  94. package/dist/server/pack.js +26 -0
  95. package/dist/server/theme/schema.d.ts +57 -0
  96. package/dist/server/theme/schema.d.ts.map +1 -0
  97. package/dist/server/theme/schema.js +217 -0
  98. package/dist/server/util.d.ts +24 -0
  99. package/dist/server/util.d.ts.map +1 -0
  100. package/dist/server/util.js +71 -0
  101. package/dist/util/art.d.ts +52 -0
  102. package/dist/util/art.d.ts.map +1 -0
  103. package/dist/util/art.js +57 -0
  104. package/dist/util/artistcontext.svelte.d.ts +8 -0
  105. package/dist/util/artistcontext.svelte.d.ts.map +1 -0
  106. package/dist/util/artistcontext.svelte.js +18 -0
  107. package/dist/util/charactercontext.svelte.d.ts +4 -0
  108. package/dist/util/charactercontext.svelte.d.ts.map +1 -0
  109. package/dist/util/charactercontext.svelte.js +11 -0
  110. package/dist/util/date.d.ts +2 -0
  111. package/dist/util/date.d.ts.map +1 -0
  112. package/dist/util/date.js +6 -0
  113. package/dist/util/index.d.ts +13 -0
  114. package/dist/util/index.d.ts.map +1 -0
  115. package/dist/util/index.js +10 -0
  116. package/dist/util/markdown.d.ts +2 -0
  117. package/dist/util/markdown.d.ts.map +1 -0
  118. package/dist/util/markdown.js +16 -0
  119. package/dist/util/phosart_config.svelte.d.ts +44 -0
  120. package/dist/util/phosart_config.svelte.d.ts.map +1 -0
  121. package/dist/util/phosart_config.svelte.js +51 -0
  122. package/dist/util/search.d.ts +3 -0
  123. package/dist/util/search.d.ts.map +1 -0
  124. package/dist/util/search.js +24 -0
  125. package/dist/util/smoothscroll.d.ts +4 -0
  126. package/dist/util/smoothscroll.d.ts.map +1 -0
  127. package/dist/util/smoothscroll.js +21 -0
  128. package/dist/util/tree.d.ts +19 -0
  129. package/dist/util/tree.d.ts.map +1 -0
  130. package/dist/util/tree.js +58 -0
  131. package/dist/util/util.d.ts +4 -0
  132. package/dist/util/util.d.ts.map +1 -0
  133. package/dist/util/util.js +22 -0
  134. package/package.json +102 -0
  135. package/src/lib/FullGallery.svelte +51 -0
  136. package/src/lib/Gallery.svelte +30 -0
  137. package/src/lib/GalleryPreview.svelte +60 -0
  138. package/src/lib/HighResContext.svelte +21 -0
  139. package/src/lib/Image.svelte +171 -0
  140. package/src/lib/Modal.svelte +87 -0
  141. package/src/lib/ModalGallery/Carousel.svelte +76 -0
  142. package/src/lib/ModalGallery/ImageSection.svelte +156 -0
  143. package/src/lib/ModalGallery/ImageView.svelte +92 -0
  144. package/src/lib/ModalGallery/Spinner.svelte +71 -0
  145. package/src/lib/ModalGallery.svelte +165 -0
  146. package/src/lib/OpengraphMeta.svelte +125 -0
  147. package/src/lib/Postcard/ArtistLink.svelte +46 -0
  148. package/src/lib/Postcard/Chip.svelte +100 -0
  149. package/src/lib/Postcard/Description/Character.svelte +79 -0
  150. package/src/lib/Postcard/Description.svelte +146 -0
  151. package/src/lib/Postcard/Headline.svelte +70 -0
  152. package/src/lib/index.ts +20 -0
  153. package/src/lib/server/artist.ts +50 -0
  154. package/src/lib/server/character.ts +113 -0
  155. package/src/lib/server/directories.ts +45 -0
  156. package/src/lib/server/fastcache.ts +66 -0
  157. package/src/lib/server/filter.ts +71 -0
  158. package/src/lib/server/gallery.ts +259 -0
  159. package/src/lib/server/imageprocess.ts +382 -0
  160. package/src/lib/server/index.ts +57 -0
  161. package/src/lib/server/models/Artist.ts +19 -0
  162. package/src/lib/server/models/Character.ts +24 -0
  163. package/src/lib/server/models/Gallery.ts +70 -0
  164. package/src/lib/server/models/image.ts +20 -0
  165. package/src/lib/server/pack.ts +31 -0
  166. package/src/lib/server/theme/schema.ts +286 -0
  167. package/src/lib/server/util.ts +102 -0
  168. package/src/lib/util/art.ts +136 -0
  169. package/src/lib/util/artistcontext.svelte.ts +25 -0
  170. package/src/lib/util/charactercontext.svelte.ts +15 -0
  171. package/src/lib/util/date.ts +7 -0
  172. package/src/lib/util/index.ts +29 -0
  173. package/src/lib/util/markdown.ts +17 -0
  174. package/src/lib/util/phosart_config.svelte.ts +101 -0
  175. package/src/lib/util/search.ts +28 -0
  176. package/src/lib/util/smoothscroll.ts +21 -0
  177. package/src/lib/util/tree.ts +75 -0
  178. package/src/lib/util/util.ts +37 -0
@@ -0,0 +1,101 @@
1
+ import type Gallery from '../Gallery.svelte';
2
+ import type FullGallery from '../FullGallery.svelte';
3
+ import { createContext, type ComponentProps } from 'svelte';
4
+ import type { ArtPiece, NormalizedArtist, NormalizedCharacter } from './art.ts';
5
+
6
+ const [get, set] = createContext<LibraryConfig | undefined>();
7
+
8
+ export type ChipAction<T> =
9
+ | {
10
+ onclick: (data: T) => void;
11
+ makeHref?: never;
12
+ }
13
+ | {
14
+ makeHref: (data: T) => string;
15
+ onclick?: never;
16
+ };
17
+
18
+ type ChipOptionBase<T> =
19
+ | { action?: ChipAction<T> | null; hidden?: never }
20
+ | { hidden?: true; action?: never };
21
+
22
+ type ChipOptionTypes = {
23
+ tag: string;
24
+ artist: NormalizedArtist;
25
+ character: NormalizedCharacter;
26
+ permalink: ArtPiece;
27
+ };
28
+
29
+ export type ChipOptions<T> = ChipOptionBase<T>;
30
+ export type DataType<Type extends keyof ChipOptionTypes> = ChipOptionTypes[Type];
31
+
32
+ export type ChipOptionsByType = {
33
+ [K in keyof ChipOptionTypes]?: ChipOptions<DataType<K>>;
34
+ };
35
+
36
+ export interface LibraryConfig {
37
+ siteName: string;
38
+ gallery?: {
39
+ DefaultCardComponent?: NonNullable<ComponentProps<typeof FullGallery>['CardComponent']> | null;
40
+ DefaultPieceComponent?: NonNullable<ComponentProps<typeof Gallery>['PieceComponent']> | null;
41
+ };
42
+ modal?: { chipOptionsByType?: ChipOptionsByType | null };
43
+ }
44
+
45
+ const DEFAULT_CONFIG: LibraryConfig = {
46
+ siteName: '',
47
+ gallery: {
48
+ DefaultCardComponent: undefined, // TODO
49
+ DefaultPieceComponent: undefined // TODO
50
+ },
51
+ modal: {
52
+ chipOptionsByType: {
53
+ artist: {
54
+ action: { makeHref: (artist) => `/artist/${artist.name}` }
55
+ },
56
+ tag: { action: { makeHref: (tag) => `/tag/${tag}` } },
57
+ character: { action: { makeHref: (ch) => `/characters/${ch.name}` } },
58
+ permalink: { action: { makeHref: (pl) => `/piece/${pl.slug}` } }
59
+ }
60
+ }
61
+ };
62
+
63
+ function spread(cfg: LibraryConfig): LibraryConfig {
64
+ const modalBase = DEFAULT_CONFIG.modal;
65
+ let gallery = DEFAULT_CONFIG.gallery;
66
+ let modal = modalBase;
67
+ let chipOptionsByType = modalBase?.chipOptionsByType;
68
+
69
+ if (cfg.gallery) {
70
+ gallery = { ...DEFAULT_CONFIG.gallery, ...cfg.gallery };
71
+ }
72
+ if (cfg.modal) {
73
+ if (cfg.modal.chipOptionsByType) {
74
+ chipOptionsByType = { ...modalBase?.chipOptionsByType, ...cfg.modal.chipOptionsByType };
75
+ }
76
+ modal = { ...modalBase, ...cfg.modal, chipOptionsByType };
77
+ }
78
+
79
+ return { ...cfg, gallery, modal };
80
+ }
81
+
82
+ export function useChipConfig<Type extends keyof ChipOptionsByType>(
83
+ type: Type
84
+ ): ChipOptions<DataType<Type>> | null {
85
+ const config = useLibraryConfig();
86
+ if (!config.modal) {
87
+ return null;
88
+ }
89
+ return config.modal.chipOptionsByType?.[type] ?? null;
90
+ }
91
+
92
+ export function setLibraryConfig(config: LibraryConfig) {
93
+ set(spread(config));
94
+ $effect(() => {
95
+ set(spread(config));
96
+ });
97
+ }
98
+
99
+ export function useLibraryConfig(): LibraryConfig {
100
+ return get() ?? DEFAULT_CONFIG;
101
+ }
@@ -0,0 +1,28 @@
1
+ import fz from 'fuzzysort';
2
+ import { normalizeArtist, normalizeCharacter, type ArtPiece } from './art.ts';
3
+ import { asRecord } from './util.ts';
4
+
5
+ export function executeSearch(query: string, pieces: ArtPiece[]): ArtPiece[] {
6
+ const allPieces = asRecord(pieces, (p) => p.slug);
7
+
8
+ const searchObj = Object.values(allPieces).map((p) => ({
9
+ name: p.name,
10
+ description: p.description,
11
+ alt: p.alt,
12
+ tags: p.tags.join(', '),
13
+ characters: p.characters
14
+ .map((ch) => normalizeCharacter(ch))
15
+ .map((ch) => `${ch.name} ${ch.from}`),
16
+ artists: normalizeArtist(p.artist)
17
+ .map((a) => a.name)
18
+ .join(', '),
19
+ slug: p.slug
20
+ }));
21
+
22
+ const results = fz.go(query, searchObj, {
23
+ keys: ['name', 'characters', 'artists', 'tags', 'alt', 'description'],
24
+ threshold: 0.3
25
+ });
26
+
27
+ return results.map((res) => allPieces[res.obj.slug]);
28
+ }
@@ -0,0 +1,21 @@
1
+ export const smoothScroll = (anchor: HTMLAnchorElement) => {
2
+ const cb = (e: Event) => {
3
+ e.preventDefault();
4
+ const href = anchor.getAttribute('href');
5
+ if (!href || !href.startsWith('#')) return;
6
+ const target = document.getElementById(href.replace(/^#/g, ''));
7
+ if (!target) return;
8
+
9
+ window.scrollTo({
10
+ top: target.offsetTop,
11
+ behavior: 'smooth'
12
+ });
13
+ };
14
+
15
+ anchor.addEventListener('click', cb);
16
+ return {
17
+ destroy() {
18
+ anchor.removeEventListener('click', cb);
19
+ }
20
+ };
21
+ };
@@ -0,0 +1,75 @@
1
+ import type { GalleryCache } from '../server/gallery.ts';
2
+ import type { ArtPiece, Gallery } from './art.ts';
3
+
4
+ export type FolderElement = { $type: 'folder'; data: GalleryTree; items: number };
5
+ export type GalleryElement = { $type: 'gallery'; data: Gallery; fullpath: string };
6
+ export type TreeElement = FolderElement | GalleryElement;
7
+
8
+ export type GalleryTree = {
9
+ [element: string]: TreeElement;
10
+ };
11
+
12
+ export function asTree(
13
+ cache: GalleryCache,
14
+ transformPieces?: (pieces: Array<ArtPiece>) => Array<ArtPiece>
15
+ ): FolderElement {
16
+ const paths: [string, Gallery][] = Object.entries(cache);
17
+ const tree: TreeElement = { $type: 'folder', data: {}, items: 0 };
18
+ for (const [path, gallery] of paths) {
19
+ let cur = tree;
20
+ tree.items += gallery.pieces.length;
21
+ const segments = path.split('/');
22
+ const dir = segments.slice(0, -1);
23
+ for (const segment of dir) {
24
+ let next = cur.data[segment];
25
+ if (!next) {
26
+ cur.data[segment] = { $type: 'folder', data: {}, items: 0 };
27
+ next = cur.data[segment];
28
+ }
29
+ if (next.$type !== 'folder') {
30
+ throw new Error('Somehow found gallery + folder with same name??');
31
+ }
32
+ next.items += gallery.pieces.length;
33
+ cur = next;
34
+ }
35
+ cur.data[segments.at(-1)!] = {
36
+ $type: 'gallery',
37
+ data: {
38
+ pieces: transformPieces?.(gallery.pieces) ?? gallery.pieces
39
+ },
40
+ fullpath: path
41
+ };
42
+ }
43
+
44
+ return tree;
45
+ }
46
+
47
+ export function pathView(tree: FolderElement, path: string[]): GalleryTree {
48
+ let cur: TreeElement = tree;
49
+ // Go to path
50
+ for (let i = 0; i < path.length; i++) {
51
+ const el = path[i];
52
+ const next: TreeElement = cur.data[el];
53
+ if (!next) {
54
+ return {};
55
+ }
56
+ if (next.$type !== 'folder') {
57
+ return {};
58
+ }
59
+ cur = next;
60
+ }
61
+
62
+ cur = { ...cur, data: { ...cur.data } };
63
+
64
+ // Prune deeper levels
65
+ for (const [k, el] of Object.entries(cur.data)) {
66
+ if (el.$type === 'folder') {
67
+ if (el.items === 0) {
68
+ delete cur.data[k];
69
+ } else {
70
+ cur.data[k] = { $type: 'folder', data: {}, items: el.items };
71
+ }
72
+ }
73
+ }
74
+ return cur.data;
75
+ }
@@ -0,0 +1,37 @@
1
+ function defaultCombine<T>(a: T): T {
2
+ return a;
3
+ }
4
+
5
+ export function asRecord<T>(
6
+ arr: T[],
7
+ key: (el: T) => string,
8
+ combine?: (a: T, b: T) => T
9
+ ): Record<string, T> {
10
+ const record: Record<string, T> = {};
11
+ for (const val of arr) {
12
+ const k = key(val);
13
+ if (k in record) {
14
+ record[k] = (combine ?? defaultCombine)(record[k], val);
15
+ } else {
16
+ record[k] = val;
17
+ }
18
+ }
19
+
20
+ return record;
21
+ }
22
+
23
+ export function multiRecordBy<T>(arr: T[], key: (el: T) => string): Record<string, T[]> {
24
+ return asRecord(
25
+ arr.map((v) => [v]),
26
+ (arr) => key(arr[0]),
27
+ (a1, a2) => [...a1, ...a2]
28
+ );
29
+ }
30
+
31
+ export function deduplicateBy<T>(
32
+ arr: T[],
33
+ key: (el: T) => string,
34
+ combine?: (a: T, b: T) => T
35
+ ): T[] {
36
+ return Object.values(asRecord(arr, key, combine));
37
+ }