@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,76 @@
1
+ import { $DATA } from "./directories.js";
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import * as yaml from 'yaml';
5
+ import { FullCharacter, RawCharacter } from "./models/Character.js";
6
+ import { processImageFastcache } from "./imageprocess.js";
7
+ import { cacheVersion, getCache, fullPath, relPath } from "./util.js";
8
+ import { flushFastCache, readFastCache } from "./fastcache.js";
9
+ import { galleries } from "./gallery.js";
10
+ import { normalizeCharacter } from "../util/art.js";
11
+ const CHARACTER_PATH = path.join('characters', 'characters.yaml');
12
+ async function doResolveImage(filename, character, fc) {
13
+ const full = processImageFastcache(fc, fullPath(filename, character.picture.image), relPath(filename, character.picture.image));
14
+ const thumb = character.thumbnail
15
+ ? processImageFastcache(fc, fullPath(filename, character.thumbnail.image), relPath(filename, character.thumbnail.image))
16
+ : undefined;
17
+ return {
18
+ ...character,
19
+ picture: { ...(await full), alt: character.picture.alt },
20
+ thumbnail: thumb
21
+ ? {
22
+ ...(await thumb),
23
+ alt: character.thumbnail.alt
24
+ }
25
+ : undefined
26
+ };
27
+ }
28
+ export async function rawCharacters() {
29
+ const cached = getCache().rawCharacterCache;
30
+ const nextVersion = await cacheVersion();
31
+ if (cached.cache && cached.version === nextVersion) {
32
+ return cached.cache;
33
+ }
34
+ const document = yaml.parse(await fs.readFile(path.join($DATA(), CHARACTER_PATH), { encoding: 'utf-8' }));
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ const characters = document
37
+ .flatMap((obj, idx) => {
38
+ const ch = RawCharacter.parse({ ...obj, index: idx++ });
39
+ return ch;
40
+ })
41
+ .reduce((acc, cur) => ({ ...acc, [cur.name]: cur }), {});
42
+ getCache().rawCharacterCache.cache = characters;
43
+ getCache().rawCharacterCache.version = nextVersion;
44
+ return characters;
45
+ }
46
+ export async function characters() {
47
+ const cached = getCache().characterCache;
48
+ const nextVersion = await cacheVersion();
49
+ if (cached.cache && cached.version === nextVersion) {
50
+ return cached.cache;
51
+ }
52
+ const characters = await rawCharacters();
53
+ const fc = await readFastCache();
54
+ const resolved = Object.fromEntries(await Promise.all(Object.entries(characters).map(async ([k, v]) => {
55
+ const resolved = await doResolveImage(CHARACTER_PATH, v, fc);
56
+ return [k, resolved];
57
+ })));
58
+ await flushFastCache(fc);
59
+ getCache().characterCache.cache = resolved;
60
+ getCache().characterCache.version = nextVersion;
61
+ return resolved;
62
+ }
63
+ export async function getAllCharacters() {
64
+ const all = await characters();
65
+ const mapped = Object.values(await galleries())
66
+ .flatMap((g) => g.pieces)
67
+ .flatMap((p) => p.characters)
68
+ .flatMap((ch) => normalizeCharacter(ch, all))
69
+ .concat(Object.values(all).map((ch) => normalizeCharacter(ch.name, all)));
70
+ // Collapse by name, from pair
71
+ const record = {};
72
+ for (const m of mapped) {
73
+ record[`${m.name}\x00${m.from}`] = m;
74
+ }
75
+ return Object.values(record);
76
+ }
@@ -0,0 +1,4 @@
1
+ export declare const $ROOT: () => string;
2
+ export declare const $DATA: () => string;
3
+ export declare const $PUBLIC: () => string;
4
+ //# sourceMappingURL=directories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directories.d.ts","sourceRoot":"","sources":["../../src/lib/server/directories.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,KAAK,cAAgC,CAAC;AACnD,eAAO,MAAM,KAAK,cAA8B,CAAC;AACjD,eAAO,MAAM,OAAO,cAA2C,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { join, dirname } from 'node:path';
2
+ import * as fs from 'node:fs';
3
+ function tryFindRoot(start) {
4
+ let cur = dirname(start);
5
+ while (cur.length > 1) {
6
+ if (cur.includes('node_modules')) {
7
+ cur = join(cur, '..');
8
+ continue;
9
+ }
10
+ try {
11
+ // If package.json parses correctly...
12
+ JSON.parse(fs.readFileSync(join(cur, 'package.json'), { encoding: 'utf-8' }));
13
+ return cur;
14
+ }
15
+ catch {
16
+ cur = join(cur, '..');
17
+ }
18
+ }
19
+ return null;
20
+ }
21
+ let cachedRoot = null;
22
+ function findRoot() {
23
+ if (cachedRoot) {
24
+ return cachedRoot;
25
+ }
26
+ let root = null;
27
+ if (process.env.PROJECT_ROOT) {
28
+ root = tryFindRoot(process.env.PROJECT_ROOT);
29
+ }
30
+ root = root ?? tryFindRoot(process.argv[1]) ?? tryFindRoot(process.cwd());
31
+ if (!root) {
32
+ throw new Error('Failed to find root');
33
+ }
34
+ cachedRoot = root;
35
+ return root;
36
+ }
37
+ export const $ROOT = () => join(findRoot(), 'src');
38
+ export const $DATA = () => join($ROOT(), 'data');
39
+ export const $PUBLIC = () => join($ROOT(), '..', 'static', '_');
@@ -0,0 +1,11 @@
1
+ export interface FastCache {
2
+ [relpath: string]: {
3
+ mtime: number;
4
+ hash: string;
5
+ };
6
+ }
7
+ export declare function getFastHash(fc: FastCache, fullpath: string, relpath: string): Promise<[string | null, number | null]>;
8
+ export declare function updateFastCache(fc: FastCache, fullpath: string, relpath: string, hash: string, premtime?: number | null): Promise<void>;
9
+ export declare function flushFastCache(fc: FastCache): Promise<void>;
10
+ export declare function readFastCache(): Promise<FastCache>;
11
+ //# sourceMappingURL=fastcache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastcache.d.ts","sourceRoot":"","sources":["../../src/lib/server/fastcache.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,SAAS;IACzB,CAAC,OAAO,EAAE,MAAM,GAAG;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF;AAED,wBAAsB,WAAW,CAChC,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAYzC;AAED,wBAAsB,eAAe,CACpC,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,iBAQxB;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,SAAS,iBAMjD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAOxD"}
@@ -0,0 +1,43 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import { $DATA } from "./directories.js";
3
+ import path from 'node:path';
4
+ import { Logger } from 'tslog';
5
+ import { getLogLevel } from "./util.js";
6
+ import { readPack, writePack } from "./pack.js";
7
+ const FastcacheLogger = new Logger({ minLevel: getLogLevel() });
8
+ const $FASTCACHEPATH = () => path.join($DATA(), '.fastcache.pack.gz');
9
+ export async function getFastHash(fc, fullpath, relpath) {
10
+ const cacheinfo = fc[relpath];
11
+ if (!cacheinfo)
12
+ return [null, null];
13
+ const fstat = await stat(fullpath);
14
+ const mtime = fstat.mtimeMs;
15
+ if (mtime !== cacheinfo.mtime) {
16
+ return [null, mtime];
17
+ }
18
+ return [cacheinfo.hash, mtime];
19
+ }
20
+ export async function updateFastCache(fc, fullpath, relpath, hash, premtime) {
21
+ const mtime = premtime ?? (await stat(fullpath)).mtimeMs;
22
+ fc[relpath] = {
23
+ mtime,
24
+ hash
25
+ };
26
+ }
27
+ export async function flushFastCache(fc) {
28
+ try {
29
+ await writePack($FASTCACHEPATH(), fc);
30
+ }
31
+ catch (err) {
32
+ FastcacheLogger.warn('Failed to write fastcache', err);
33
+ }
34
+ }
35
+ export async function readFastCache() {
36
+ try {
37
+ return await readPack($FASTCACHEPATH());
38
+ }
39
+ catch (err) {
40
+ FastcacheLogger.warn('Failed to read fastcache', err);
41
+ return {};
42
+ }
43
+ }
@@ -0,0 +1,6 @@
1
+ import { type ArtPiece, type ResourceRef } from '../util/art.ts';
2
+ export declare function filter(gallery: ArtPiece[] | Record<string, ArtPiece>, by?: ResourceRef, { negated, sorted }?: {
3
+ negated?: boolean;
4
+ sorted?: boolean;
5
+ }): ArtPiece[];
6
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/lib/server/filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,MAAM,gBAAgB,CAAC;AAgDxB,wBAAgB,MAAM,CACrB,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC9C,EAAE,CAAC,EAAE,WAAW,EAChB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/D,QAAQ,EAAE,CAaZ"}
@@ -0,0 +1,53 @@
1
+ import { normalizeArtist, normalizeCharacter } from "../util/art.js";
2
+ function filterOne(piece, by, negated) {
3
+ if (!by.type || !by.resource) {
4
+ return false;
5
+ }
6
+ switch (by.type) {
7
+ case 'artist': {
8
+ const artists = normalizeArtist(piece.artist);
9
+ let hasArtist = artists.some((artist) => artist.name.toLowerCase() === by.resource.name.toLowerCase());
10
+ if (negated) {
11
+ hasArtist = !hasArtist;
12
+ }
13
+ return hasArtist;
14
+ }
15
+ case 'character': {
16
+ const characters = normalizeCharacter(piece.characters);
17
+ let hasCharacter = characters.some((ch) => ch.name.toLowerCase() === by.resource.name.toLowerCase() &&
18
+ (ch.from?.toLowerCase() === by.resource.from?.toLowerCase() ||
19
+ (!ch.from && !by.resource.from)));
20
+ if (negated) {
21
+ hasCharacter = !hasCharacter;
22
+ }
23
+ return hasCharacter;
24
+ }
25
+ case 'piece': {
26
+ let isPiece = by.resource.slug === piece.slug;
27
+ if (negated) {
28
+ isPiece = !isPiece;
29
+ }
30
+ return isPiece;
31
+ }
32
+ case 'tag': {
33
+ let hasTag = piece.tags.map((t) => t.toLowerCase()).includes(by.resource.toLowerCase());
34
+ if (negated) {
35
+ hasTag = !hasTag;
36
+ }
37
+ return hasTag;
38
+ }
39
+ }
40
+ }
41
+ export function filter(gallery, by, { negated, sorted } = {}) {
42
+ if (!Array.isArray(gallery))
43
+ gallery = Object.values(gallery);
44
+ const results = by
45
+ ? gallery.filter((piece) => {
46
+ return filterOne(piece, by, negated ?? false);
47
+ })
48
+ : gallery;
49
+ if (!sorted) {
50
+ return results;
51
+ }
52
+ return results.sort((a, b) => b.date.getTime() - a.date.getTime());
53
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ import { FullGallery, RawGallery } from './models/Gallery.ts';
3
+ import type { ArtPiece } from '../util/art.ts';
4
+ type FileName = string;
5
+ type RawGalleryT = z.infer<typeof RawGallery>;
6
+ type FullGalleryT = z.infer<typeof FullGallery>;
7
+ type GalleryListing<T> = Record<FileName, T>;
8
+ export type GalleryCache = GalleryListing<FullGalleryT>;
9
+ export type RawGalleryCache = GalleryListing<RawGalleryT>;
10
+ export declare function rawGalleries(): Promise<RawGalleryCache>;
11
+ export declare function galleries(doRetry?: boolean): Promise<GalleryCache>;
12
+ export declare function allPieces(): Promise<Record<string, ArtPiece>>;
13
+ export declare function getPieceBySlug(slug: string): Promise<ArtPiece | null>;
14
+ export declare function hasNsfw(gallery: ArtPiece[]): boolean;
15
+ export {};
16
+ //# sourceMappingURL=gallery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gallery.d.ts","sourceRoot":"","sources":["../../src/lib/server/gallery.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAIN,WAAW,EACX,UAAU,EACV,MAAM,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI/C,KAAK,QAAQ,GAAG,MAAM,CAAC;AAEvB,KAAK,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,KAAK,cAAc,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;AACxD,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;AAmH1D,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CAgC7D;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,OAAc,yBAsDtD;AAMD,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAKnE;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAE3E;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAEpD"}
@@ -0,0 +1,162 @@
1
+ import { glob } from 'glob';
2
+ import * as yaml from 'yaml';
3
+ import * as path from 'node:path';
4
+ import * as fs from 'node:fs/promises';
5
+ import { z } from 'zod';
6
+ import { Logger } from 'tslog';
7
+ import { BaseArtPiece, BaseGallery, FullArtPiece, FullGallery, RawGallery } from "./models/Gallery.js";
8
+ import { $DATA } from "./directories.js";
9
+ import { processImageFastcache, processVideoFastcache } from "./imageprocess.js";
10
+ import { cacheVersion, clearCache, getCache, hash, fullPath, relPath, getLogLevel } from "./util.js";
11
+ import { flushFastCache, readFastCache } from "./fastcache.js";
12
+ import { asRecord } from "../util/util.js";
13
+ const GalleryLogger = new Logger({ minLevel: getLogLevel() });
14
+ async function resolveExtendsRec(fname, gallery, rec, fc) {
15
+ if (!('$extends' in gallery)) {
16
+ return await resolveReferences(gallery, fname, fc);
17
+ }
18
+ const full = { pieces: [] };
19
+ for (const relative of gallery.$extends) {
20
+ const base = path.dirname(fname);
21
+ const target = path.join(base, relative);
22
+ if (rec[target]) {
23
+ const result = await resolveExtendsRec(target, rec[target], rec, fc);
24
+ if ('$extends' in result) {
25
+ throw new Error('Impossible');
26
+ }
27
+ full.pieces.push(...result.pieces);
28
+ }
29
+ else {
30
+ GalleryLogger.warn('[GALLERY] Could not find target for', target, 'when parsing', fname);
31
+ }
32
+ }
33
+ return full;
34
+ }
35
+ async function resolveExtends(rec, fc) {
36
+ const listing = {};
37
+ for (const [fname, gallery] of Object.entries(rec)) {
38
+ if ('$extends' in gallery) {
39
+ listing[fname] = await resolveExtendsRec(fname, gallery, rec, fc);
40
+ }
41
+ else {
42
+ listing[fname] = await resolveReferences(gallery, fname, fc);
43
+ }
44
+ }
45
+ return listing;
46
+ }
47
+ async function resolvePieceReferences(piece, filename, fc) {
48
+ const relpath = relPath(filename, piece.image);
49
+ const fullpath = fullPath(filename, piece.image);
50
+ const image = await processImageFastcache(fc, fullpath, relpath, { position: piece.position });
51
+ const alts = await Promise.all(piece.alts?.map(async (alt) => ({
52
+ ...alt,
53
+ image: await processImageFastcache(fc, fullPath(filename, alt.image), relPath(filename, alt.image), { position: piece.position }),
54
+ video: alt.video
55
+ ? {
56
+ full: await processVideoFastcache(fc, fullPath(filename, alt.video.full), relPath(filename, alt.video.full), 'full'),
57
+ thumb: await processVideoFastcache(fc, fullPath(filename, alt.video.thumb), relPath(filename, alt.video.thumb), 'thumb')
58
+ }
59
+ : undefined
60
+ })) ?? []);
61
+ const video = piece.video
62
+ ? {
63
+ full: await processVideoFastcache(fc, fullPath(filename, piece.video.full), relPath(filename, piece.video.full), 'full'),
64
+ thumb: await processVideoFastcache(fc, fullPath(filename, piece.video.thumb), relPath(filename, piece.video.thumb), 'thumb')
65
+ }
66
+ : undefined;
67
+ return { ...piece, image, alts, video };
68
+ }
69
+ async function resolveReferences(gallery, fname, fc) {
70
+ return {
71
+ pieces: await Promise.all(gallery.pieces.map((piece) => resolvePieceReferences(piece, fname, fc)))
72
+ };
73
+ }
74
+ export async function rawGalleries() {
75
+ const cached = getCache().rawGalleryCache;
76
+ const nextVersion = await cacheVersion();
77
+ if (cached.cache && cached.version === nextVersion) {
78
+ return cached.cache;
79
+ }
80
+ const allGalleries = await glob('./**/*.gallery', { cwd: $DATA() });
81
+ const documents = (await Promise.all(allGalleries.map((fn) => fs
82
+ .readFile(path.join($DATA(), fn), { encoding: 'utf-8' })
83
+ .then((text) => ({ filename: fn, text })))))
84
+ .map(({ filename, text }) => ({ filename, obj: yaml.parse(text) }))
85
+ .map(({ filename, obj }) => {
86
+ GalleryLogger.silly('[GALLERY] Parsing', filename);
87
+ obj.pieces = obj.pieces
88
+ ? obj.pieces.map((p) => ({ ...p, slug: p.id ?? hash(p) }))
89
+ : undefined;
90
+ return { filename, obj: RawGallery.parse(obj) };
91
+ })
92
+ .reduce((rec, { filename, obj }) => ({ ...rec, [filename.replaceAll(path.sep, '/')]: obj }), {});
93
+ getCache().rawGalleryCache.cache = documents;
94
+ getCache().rawGalleryCache.version = nextVersion;
95
+ return documents;
96
+ }
97
+ export async function galleries(doRetry = true) {
98
+ const cached = getCache().galleryCache;
99
+ const nextVersion = await cacheVersion();
100
+ if (cached.cache && cached.version === nextVersion) {
101
+ return cached.cache;
102
+ }
103
+ const documents = Object.fromEntries(Object.entries(await rawGalleries())
104
+ .map(([path, g]) => {
105
+ if ('pieces' in g) {
106
+ g = {
107
+ pieces: g.pieces
108
+ .map((p) => {
109
+ if (p.deindexed) {
110
+ return null;
111
+ }
112
+ if (p.alts) {
113
+ p = { ...p, alts: p.alts.filter((a) => !a.deindexed) };
114
+ }
115
+ return p;
116
+ })
117
+ .filter(truthy)
118
+ };
119
+ if (g.pieces.length === 0) {
120
+ return null;
121
+ }
122
+ return [path, g];
123
+ }
124
+ else {
125
+ if (g.$extends.length === 0) {
126
+ return null;
127
+ }
128
+ return [path, g];
129
+ }
130
+ })
131
+ .filter(truthy));
132
+ try {
133
+ const fc = await readFastCache();
134
+ const out = await resolveExtends(documents, fc);
135
+ await flushFastCache(fc);
136
+ getCache().galleryCache.cache = out;
137
+ getCache().galleryCache.version = nextVersion;
138
+ return out;
139
+ }
140
+ catch (e) {
141
+ if (doRetry) {
142
+ GalleryLogger.warn('Encountered error, clearing cache and trying again', e);
143
+ clearCache();
144
+ return await galleries(/* doRetry = */ false);
145
+ }
146
+ else {
147
+ throw e;
148
+ }
149
+ }
150
+ }
151
+ function truthy(t) {
152
+ return !!t;
153
+ }
154
+ export async function allPieces() {
155
+ return asRecord(Object.values(await galleries()).flatMap((p) => p.pieces), (p) => p.slug);
156
+ }
157
+ export async function getPieceBySlug(slug) {
158
+ return (await allPieces())[slug] ?? null;
159
+ }
160
+ export function hasNsfw(gallery) {
161
+ return gallery.some((p) => p.nsfw);
162
+ }
@@ -0,0 +1,18 @@
1
+ import type { z } from 'zod';
2
+ import type { Picture } from './models/image.ts';
3
+ import { type FastCache } from './fastcache.ts';
4
+ interface ProcessOptions {
5
+ forceKeep?: boolean;
6
+ position?: string;
7
+ }
8
+ export declare function getProcessedHashes(): ReadonlySet<string>;
9
+ export declare function clearProcessedHashes(): void;
10
+ export declare function getUnusedHashes(): Promise<ReadonlySet<string>>;
11
+ export declare function deleteHashes(unused: ReadonlySet<string>): Promise<void>;
12
+ export declare function cleanUnusedHashes(): Promise<void>;
13
+ export declare function processVideoFastcache(fc: FastCache, fullpath: string, relpath: string, name: string, processOptions?: ProcessOptions): Promise<string>;
14
+ export declare function processVideo(url: string, name: string): Promise<string>;
15
+ export declare function processImageFastcache(fc: FastCache, fullpath: string, relpath: string, processOptions?: ProcessOptions): Promise<z.infer<typeof Picture>>;
16
+ export declare function processImage(url: string, processOptions?: ProcessOptions): Promise<z.infer<typeof Picture>>;
17
+ export {};
18
+ //# sourceMappingURL=imageprocess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageprocess.d.ts","sourceRoot":"","sources":["../../src/lib/server/imageprocess.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0B9E,UAAU,cAAc;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,wBAAgB,kBAAkB,IAAI,WAAW,CAAC,MAAM,CAAC,CAExD;AACD,wBAAgB,oBAAoB,SAEnC;AACD,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAiBpE;AACD,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,iBAsB7D;AACD,wBAAsB,iBAAiB,kBAEtC;AAYD,wBAAsB,qBAAqB,CAC1C,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,cAAc,GAAE,cAAmB,GACjC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAsBD,wBAAsB,qBAAqB,CAC1C,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,cAAmB,GACjC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC,CAQlC;AAED,wBAAsB,YAAY,CACjC,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,cAAmB,GACjC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC,CAElC"}