gazetta 0.4.0 → 0.5.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 (58) hide show
  1. package/admin-dist/assets/{index-DjGNi6yy.js → index-BZAFKsUp.js} +22 -22
  2. package/admin-dist/assets/index-BpRotMuK.css +1 -0
  3. package/admin-dist/index.html +2 -2
  4. package/dist/admin-api/index.d.ts +8 -2
  5. package/dist/admin-api/index.d.ts.map +1 -1
  6. package/dist/admin-api/index.js +31 -5
  7. package/dist/admin-api/index.js.map +1 -1
  8. package/dist/admin-api/routes/compare.d.ts +2 -1
  9. package/dist/admin-api/routes/compare.d.ts.map +1 -1
  10. package/dist/admin-api/routes/compare.js +2 -1
  11. package/dist/admin-api/routes/compare.js.map +1 -1
  12. package/dist/admin-api/routes/fragments.d.ts +2 -1
  13. package/dist/admin-api/routes/fragments.d.ts.map +1 -1
  14. package/dist/admin-api/routes/fragments.js +3 -1
  15. package/dist/admin-api/routes/fragments.js.map +1 -1
  16. package/dist/admin-api/routes/pages.d.ts +2 -1
  17. package/dist/admin-api/routes/pages.d.ts.map +1 -1
  18. package/dist/admin-api/routes/pages.js +3 -1
  19. package/dist/admin-api/routes/pages.js.map +1 -1
  20. package/dist/admin-api/routes/publish.d.ts +2 -1
  21. package/dist/admin-api/routes/publish.d.ts.map +1 -1
  22. package/dist/admin-api/routes/publish.js +121 -27
  23. package/dist/admin-api/routes/publish.js.map +1 -1
  24. package/dist/cli/index.js +75 -12
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/compare.d.ts +7 -0
  27. package/dist/compare.d.ts.map +1 -1
  28. package/dist/compare.js +39 -40
  29. package/dist/compare.js.map +1 -1
  30. package/dist/concurrency.d.ts +63 -0
  31. package/dist/concurrency.d.ts.map +1 -0
  32. package/dist/concurrency.js +134 -0
  33. package/dist/concurrency.js.map +1 -0
  34. package/dist/hash.d.ts +15 -0
  35. package/dist/hash.d.ts.map +1 -1
  36. package/dist/hash.js +47 -7
  37. package/dist/hash.js.map +1 -1
  38. package/dist/publish-rendered.d.ts +6 -5
  39. package/dist/publish-rendered.d.ts.map +1 -1
  40. package/dist/publish-rendered.js +39 -44
  41. package/dist/publish-rendered.js.map +1 -1
  42. package/dist/publish.d.ts +38 -0
  43. package/dist/publish.d.ts.map +1 -1
  44. package/dist/publish.js +154 -14
  45. package/dist/publish.js.map +1 -1
  46. package/dist/sidecars.d.ts +56 -0
  47. package/dist/sidecars.d.ts.map +1 -0
  48. package/dist/sidecars.js +141 -0
  49. package/dist/sidecars.js.map +1 -0
  50. package/dist/site-loader.d.ts.map +1 -1
  51. package/dist/site-loader.js +13 -10
  52. package/dist/site-loader.js.map +1 -1
  53. package/dist/source-sidecars.d.ts +13 -0
  54. package/dist/source-sidecars.d.ts.map +1 -0
  55. package/dist/source-sidecars.js +52 -0
  56. package/dist/source-sidecars.js.map +1 -0
  57. package/package.json +1 -1
  58. package/admin-dist/assets/index-Bh_y1d_l.css +0 -1
package/dist/compare.js CHANGED
@@ -1,6 +1,8 @@
1
+ import { join } from 'node:path';
1
2
  import { loadSite } from './site-loader.js';
2
- import { hashManifest, parseSidecarName } from './hash.js';
3
+ import { hashManifest } from './hash.js';
3
4
  import { scanTemplates, templateHashesFrom } from './templates-scan.js';
5
+ import { listSidecars } from './sidecars.js';
4
6
  /**
5
7
  * Compare local source state against a published target.
6
8
  *
@@ -13,30 +15,56 @@ import { scanTemplates, templateHashesFrom } from './templates-scan.js';
13
15
  */
14
16
  export async function compareTargets(opts) {
15
17
  // 1. Validate + hash templates
16
- const templateInfos = await scanTemplates(opts.templatesDir, opts.projectRoot);
18
+ const scan = opts.scanTemplates ?? scanTemplates;
19
+ const templateInfos = await scan(opts.templatesDir, opts.projectRoot);
17
20
  const invalidTemplates = templateInfos.filter(t => !t.valid)
18
21
  .map(t => ({ name: t.name, errors: t.errors }));
19
22
  const templateHashes = templateHashesFrom(templateInfos);
20
- // 2. Load local site, compute manifest hashes
23
+ // 2. Load local site, compute manifest hashes.
24
+ // Source-side sidecars (written on save) let us skip re-hashing for items
25
+ // whose manifest + templates haven't changed since the last save. Fall
26
+ // back to hashManifest for items without a source sidecar.
21
27
  const site = await loadSite({ siteDir: opts.siteDir, storage: opts.source, templatesDir: opts.templatesDir });
28
+ const [sourcePagesSidecars, sourceFragmentsSidecars] = await Promise.all([
29
+ listSidecars(opts.source, join(opts.siteDir, 'pages')),
30
+ listSidecars(opts.source, join(opts.siteDir, 'fragments')),
31
+ ]);
32
+ // Hash fragments first (they don't depend on page hashes). Static-mode
33
+ // page hashes include fragment hashes so a fragment content change
34
+ // invalidates every page that bakes it in.
35
+ const fragmentHashes = new Map();
36
+ for (const [name, frag] of site.fragments) {
37
+ const cached = sourceFragmentsSidecars.get(name)?.hash;
38
+ fragmentHashes.set(name, cached ?? hashManifest(frag, { templateHashes }));
39
+ }
22
40
  const local = new Map();
41
+ const pageHashOpts = opts.publishMode === 'static'
42
+ ? { templateHashes, fragmentHashes }
43
+ : { templateHashes };
23
44
  for (const [name, page] of site.pages) {
24
- local.set(`pages/${name}`, hashManifest(page, { templateHashes }));
45
+ // Source sidecars are written without fragmentHashes (source doesn't
46
+ // know target's publish mode). For static targets we must re-hash.
47
+ const cached = opts.publishMode === 'static' ? null : sourcePagesSidecars.get(name)?.hash;
48
+ local.set(`pages/${name}`, cached ?? hashManifest(page, pageHashOpts));
25
49
  }
26
50
  // Static-mode targets bake fragments into pages — no fragment sidecars exist
27
51
  // on the target, and publishing @header/@footer is a no-op server-side. Omit
28
52
  // them from local so they don't appear as perpetually "added".
29
53
  if (opts.publishMode !== 'static') {
30
- for (const [name, frag] of site.fragments) {
31
- local.set(`fragments/${name}`, hashManifest(frag, { templateHashes }));
54
+ for (const [name, hash] of fragmentHashes) {
55
+ local.set(`fragments/${name}`, hash);
32
56
  }
33
57
  }
34
- // 3. List target sidecars
58
+ // 3. List target sidecars — one pass per root, parallel inside.
35
59
  const target = new Map();
36
- await collectSidecars(opts.target, 'pages', target);
37
- if (opts.publishMode !== 'static') {
38
- await collectSidecars(opts.target, 'fragments', target);
39
- }
60
+ const [pagesSidecars, fragmentsSidecars] = await Promise.all([
61
+ listSidecars(opts.target, 'pages'),
62
+ opts.publishMode !== 'static' ? listSidecars(opts.target, 'fragments') : Promise.resolve(new Map()),
63
+ ]);
64
+ for (const [k, s] of pagesSidecars)
65
+ target.set(`pages/${k}`, s.hash);
66
+ for (const [k, s] of fragmentsSidecars)
67
+ target.set(`fragments/${k}`, s.hash);
40
68
  // 4. Diff
41
69
  const result = {
42
70
  added: [],
@@ -61,33 +89,4 @@ export async function compareTargets(opts) {
61
89
  }
62
90
  return result;
63
91
  }
64
- /**
65
- * Walk `pages/` or `fragments/` looking for `.{8hex}.hash` sidecar files.
66
- * Records `pages/home` → `abc12345` for each found.
67
- */
68
- async function collectSidecars(storage, rootDir, out, prefix = rootDir) {
69
- let entries;
70
- try {
71
- entries = await storage.readDir(rootDir);
72
- }
73
- catch {
74
- return;
75
- }
76
- let foundSidecar = null;
77
- for (const e of entries) {
78
- if (!e.isDirectory) {
79
- const hash = parseSidecarName(e.name);
80
- if (hash)
81
- foundSidecar = hash;
82
- }
83
- }
84
- if (foundSidecar) {
85
- out.set(prefix, foundSidecar);
86
- }
87
- for (const e of entries) {
88
- if (e.isDirectory) {
89
- await collectSidecars(storage, `${rootDir}/${e.name}`, out, `${prefix}/${e.name}`);
90
- }
91
- }
92
- }
93
92
  //# sourceMappingURL=compare.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Bounded-concurrency helpers. Use these instead of `Promise.all` when the
3
+ * input list can be large (site walks, sidecar listings, per-item publish
4
+ * renders). Unbounded Promise.all hits three real limits at 10k items:
5
+ *
6
+ * 1. File-descriptor limits (macOS 256, Linux 1024) → EMFILE
7
+ * 2. Cloud-storage rate limits (S3 3500 PUT/s, R2 Class A throttles)
8
+ * 3. Memory — thousands of live promise chains + closures
9
+ *
10
+ * Default concurrency 20 balances throughput against those limits for both
11
+ * local filesystem and cloud storage. Tune per-call via the second arg.
12
+ */
13
+ export declare const DEFAULT_CONCURRENCY = 20;
14
+ /**
15
+ * Memoize a zero-arg async function until invalidate() is called. Concurrent
16
+ * callers share a single in-flight promise (no thundering herd on cold
17
+ * start). A failed call is NOT cached — the next call retries.
18
+ *
19
+ * Typical shape: a server owns the cache and exposes invalidate() to its
20
+ * file watcher. Keeps the underlying scanner pure — no module-level state,
21
+ * no surprise caching semantics when called from tests or the CLI.
22
+ */
23
+ export interface Memoized<T> {
24
+ get(): Promise<T>;
25
+ invalidate(): void;
26
+ }
27
+ export declare function memoizeAsync<T>(fn: () => Promise<T>): Memoized<T>;
28
+ /**
29
+ * Run `fn` on every item with at most `limit` in flight at once. Results
30
+ * are returned in input order. Errors reject immediately (like Promise.all)
31
+ * but in-flight work still completes in the background.
32
+ *
33
+ * Preserves order even though completion order varies.
34
+ */
35
+ export declare function mapLimit<T, U>(items: readonly T[], fn: (item: T, index: number) => Promise<U>, limit?: number): Promise<U[]>;
36
+ /**
37
+ * Run `fn` on every item with at most `limit` in flight, yielding each
38
+ * result as it completes — in completion order, not input order. Use when
39
+ * the caller wants to react to each completion as it happens (e.g. emit
40
+ * a progress event mid-stream). For collect-all-then-return semantics,
41
+ * mapLimit is simpler.
42
+ *
43
+ * Each yield includes the original `index` so the consumer can reconstruct
44
+ * input order if needed.
45
+ */
46
+ export declare function mapLimitStream<T, U>(items: readonly T[], fn: (item: T, index: number) => Promise<U>, limit?: number): AsyncGenerator<{
47
+ item: T;
48
+ result: U;
49
+ index: number;
50
+ }>;
51
+ /**
52
+ * Like mapLimit but doesn't throw on individual failures — returns a parallel
53
+ * array of { ok: true, value } or { ok: false, error } per input. Useful
54
+ * when a single bad manifest shouldn't abort a whole site walk.
55
+ */
56
+ export declare function mapLimitSettled<T, U>(items: readonly T[], fn: (item: T, index: number) => Promise<U>, limit?: number): Promise<Array<{
57
+ ok: true;
58
+ value: U;
59
+ } | {
60
+ ok: false;
61
+ error: unknown;
62
+ }>>;
63
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAA;IACjB,UAAU,IAAI,IAAI,CAAA;CACnB;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CA0BjE;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,KAAK,SAAsB,GAC1B,OAAO,CAAC,CAAC,EAAE,CAAC,CAqBd;AAED;;;;;;;;;GASG;AACH,wBAAuB,cAAc,CAAC,CAAC,EAAE,CAAC,EACxC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,KAAK,SAAsB,GAC1B,cAAc,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BvD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,CAAC,EACxC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,KAAK,SAAsB,GAC1B,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAmBxE"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Bounded-concurrency helpers. Use these instead of `Promise.all` when the
3
+ * input list can be large (site walks, sidecar listings, per-item publish
4
+ * renders). Unbounded Promise.all hits three real limits at 10k items:
5
+ *
6
+ * 1. File-descriptor limits (macOS 256, Linux 1024) → EMFILE
7
+ * 2. Cloud-storage rate limits (S3 3500 PUT/s, R2 Class A throttles)
8
+ * 3. Memory — thousands of live promise chains + closures
9
+ *
10
+ * Default concurrency 20 balances throughput against those limits for both
11
+ * local filesystem and cloud storage. Tune per-call via the second arg.
12
+ */
13
+ export const DEFAULT_CONCURRENCY = 20;
14
+ export function memoizeAsync(fn) {
15
+ let pending = null;
16
+ let result = null;
17
+ let hasResult = false;
18
+ return {
19
+ async get() {
20
+ if (hasResult)
21
+ return result;
22
+ if (pending)
23
+ return pending;
24
+ pending = (async () => {
25
+ try {
26
+ const v = await fn();
27
+ result = v;
28
+ hasResult = true;
29
+ return v;
30
+ }
31
+ finally {
32
+ pending = null;
33
+ }
34
+ })();
35
+ return pending;
36
+ },
37
+ invalidate() {
38
+ hasResult = false;
39
+ result = null;
40
+ pending = null;
41
+ },
42
+ };
43
+ }
44
+ /**
45
+ * Run `fn` on every item with at most `limit` in flight at once. Results
46
+ * are returned in input order. Errors reject immediately (like Promise.all)
47
+ * but in-flight work still completes in the background.
48
+ *
49
+ * Preserves order even though completion order varies.
50
+ */
51
+ export async function mapLimit(items, fn, limit = DEFAULT_CONCURRENCY) {
52
+ const results = new Array(items.length);
53
+ let cursor = 0;
54
+ let firstError = null;
55
+ async function worker() {
56
+ while (cursor < items.length && firstError === null) {
57
+ const i = cursor++;
58
+ try {
59
+ results[i] = await fn(items[i], i);
60
+ }
61
+ catch (err) {
62
+ if (firstError === null)
63
+ firstError = err;
64
+ return;
65
+ }
66
+ }
67
+ }
68
+ const workerCount = Math.min(limit, items.length);
69
+ await Promise.all(Array.from({ length: workerCount }, worker));
70
+ if (firstError !== null)
71
+ throw firstError;
72
+ return results;
73
+ }
74
+ /**
75
+ * Run `fn` on every item with at most `limit` in flight, yielding each
76
+ * result as it completes — in completion order, not input order. Use when
77
+ * the caller wants to react to each completion as it happens (e.g. emit
78
+ * a progress event mid-stream). For collect-all-then-return semantics,
79
+ * mapLimit is simpler.
80
+ *
81
+ * Each yield includes the original `index` so the consumer can reconstruct
82
+ * input order if needed.
83
+ */
84
+ export async function* mapLimitStream(items, fn, limit = DEFAULT_CONCURRENCY) {
85
+ // Each task gets a unique id — lets us remove from `active` by lookup
86
+ // without relying on Promise identity (which Promise.race doesn't give
87
+ // us directly).
88
+ const active = new Map();
89
+ let next = 0;
90
+ function start() {
91
+ if (next >= items.length)
92
+ return;
93
+ const i = next++;
94
+ const item = items[i];
95
+ const self = Symbol();
96
+ const p = fn(item, i).then((result) => ({ item, result, index: i, self }));
97
+ active.set(self, p);
98
+ }
99
+ for (let i = 0; i < Math.min(limit, items.length); i++)
100
+ start();
101
+ while (active.size > 0) {
102
+ // Promise.race resolves with the first settled value (and rejects on
103
+ // the first rejection — so errors propagate naturally).
104
+ const settled = await Promise.race(active.values());
105
+ active.delete(settled.self);
106
+ yield { item: settled.item, result: settled.result, index: settled.index };
107
+ start();
108
+ }
109
+ }
110
+ /**
111
+ * Like mapLimit but doesn't throw on individual failures — returns a parallel
112
+ * array of { ok: true, value } or { ok: false, error } per input. Useful
113
+ * when a single bad manifest shouldn't abort a whole site walk.
114
+ */
115
+ export async function mapLimitSettled(items, fn, limit = DEFAULT_CONCURRENCY) {
116
+ const results = new Array(items.length);
117
+ let cursor = 0;
118
+ async function worker() {
119
+ while (cursor < items.length) {
120
+ const i = cursor++;
121
+ try {
122
+ const value = await fn(items[i], i);
123
+ results[i] = { ok: true, value };
124
+ }
125
+ catch (error) {
126
+ results[i] = { ok: false, error };
127
+ }
128
+ }
129
+ }
130
+ const workerCount = Math.min(limit, items.length);
131
+ await Promise.all(Array.from({ length: workerCount }, worker));
132
+ return results;
133
+ }
134
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":"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"}
package/dist/hash.d.ts CHANGED
@@ -1,8 +1,23 @@
1
1
  import type { FragmentManifest, PageManifest } from './types.js';
2
2
  export declare function sidecarNameFor(hash: string): string;
3
3
  export declare function parseSidecarName(entryName: string): string | null;
4
+ /**
5
+ * Filename-safe encoding for fragment/template names. Fragments can be
6
+ * subfolder-qualified (e.g. "buttons/primary"); we replace / with __ so the
7
+ * name works as a filename component and stays readable in listings.
8
+ */
9
+ export declare function encodeRefName(name: string): string;
10
+ export declare function decodeRefName(name: string): string;
11
+ /** `.uses-header` for a page/fragment that references @header. */
12
+ export declare function usesSidecarNameFor(fragmentName: string): string;
13
+ export declare function parseUsesSidecarName(entryName: string): string | null;
14
+ /** `.tpl-page-default` for a page/fragment rendered with that template. */
15
+ export declare function templateSidecarNameFor(templateName: string): string;
16
+ export declare function parseTemplateSidecarName(entryName: string): string | null;
4
17
  export interface HashManifestOptions {
5
18
  templateHashes: Map<string, string>;
19
+ /** Fragment content hashes — include only for static-mode page hashing. */
20
+ fragmentHashes?: Map<string, string>;
6
21
  }
7
22
  /**
8
23
  * Compute the content hash for a page or fragment manifest.
@@ -1 +1 @@
1
- {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAIhF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE;AAuBD,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,GAAG,gBAAgB,EACzC,IAAI,EAAE,mBAAmB,GACxB,MAAM,CASR"}
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAMhF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE/D;AACD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnE;AACD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzE;AAmCD,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,GAAG,gBAAgB,EACzC,IAAI,EAAE,mBAAmB,GACxB,MAAM,CASR"}
package/dist/hash.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  const SIDECAR_RE = /^\.([0-9a-f]{8})\.hash$/;
3
+ const USES_SIDECAR_RE = /^\.uses-(.+)$/;
4
+ const TPL_SIDECAR_RE = /^\.tpl-(.+)$/;
3
5
  export function sidecarNameFor(hash) {
4
6
  return `.${hash}.hash`;
5
7
  }
@@ -8,21 +10,59 @@ export function parseSidecarName(entryName) {
8
10
  return m ? m[1] : null;
9
11
  }
10
12
  /**
11
- * Walk the component tree and substitute `template: "name"` with `template: "name#hash"`
12
- * using the provided template hashes. Returns a new normalized structure input is not mutated.
13
+ * Filename-safe encoding for fragment/template names. Fragments can be
14
+ * subfolder-qualified (e.g. "buttons/primary"); we replace / with __ so the
15
+ * name works as a filename component and stays readable in listings.
13
16
  */
14
- function substituteTemplateHashes(components, templateHashes) {
17
+ export function encodeRefName(name) {
18
+ return name.replace(/\//g, '__');
19
+ }
20
+ export function decodeRefName(name) {
21
+ return name.replace(/__/g, '/');
22
+ }
23
+ /** `.uses-header` for a page/fragment that references @header. */
24
+ export function usesSidecarNameFor(fragmentName) {
25
+ return `.uses-${encodeRefName(fragmentName)}`;
26
+ }
27
+ export function parseUsesSidecarName(entryName) {
28
+ const m = USES_SIDECAR_RE.exec(entryName);
29
+ return m ? decodeRefName(m[1]) : null;
30
+ }
31
+ /** `.tpl-page-default` for a page/fragment rendered with that template. */
32
+ export function templateSidecarNameFor(templateName) {
33
+ return `.tpl-${encodeRefName(templateName)}`;
34
+ }
35
+ export function parseTemplateSidecarName(entryName) {
36
+ const m = TPL_SIDECAR_RE.exec(entryName);
37
+ return m ? decodeRefName(m[1]) : null;
38
+ }
39
+ /**
40
+ * Walk the component tree and substitute template/fragment refs with their
41
+ * hashed forms (`"name#hash"`) using the provided maps. Returns a new
42
+ * normalized structure — input is not mutated.
43
+ *
44
+ * `fragmentHashes` is only provided for static-mode targets where fragments
45
+ * are baked into pages at publish time — a fragment content change must
46
+ * invalidate every page that uses it. In ESI mode fragments are published
47
+ * separately, so pages don't need fragment hashes in their own hash.
48
+ */
49
+ function substituteHashes(components, templateHashes, fragmentHashes) {
15
50
  if (!components)
16
51
  return undefined;
17
52
  return components.map(entry => {
18
- if (typeof entry === 'string')
19
- return entry;
53
+ if (typeof entry === 'string') {
54
+ if (!fragmentHashes || !entry.startsWith('@'))
55
+ return entry;
56
+ const name = entry.slice(1);
57
+ const h = fragmentHashes.get(name);
58
+ return h ? `@${name}#${h}` : entry;
59
+ }
20
60
  const hash = templateHashes.get(entry.template);
21
61
  return {
22
62
  name: entry.name,
23
63
  template: hash ? `${entry.template}#${hash}` : entry.template,
24
64
  content: entry.content,
25
- components: substituteTemplateHashes(entry.components, templateHashes),
65
+ components: substituteHashes(entry.components, templateHashes, fragmentHashes),
26
66
  };
27
67
  });
28
68
  }
@@ -39,7 +79,7 @@ export function hashManifest(manifest, opts) {
39
79
  const normalized = {
40
80
  template: rootHash ? `${manifest.template}#${rootHash}` : manifest.template,
41
81
  content: manifest.content ?? null,
42
- components: substituteTemplateHashes(manifest.components, opts.templateHashes) ?? null,
82
+ components: substituteHashes(manifest.components, opts.templateHashes, opts.fragmentHashes) ?? null,
43
83
  };
44
84
  const json = JSON.stringify(normalized, sortedReplacer);
45
85
  return createHash('md5').update(json).digest('hex').slice(0, 8);
package/dist/hash.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxC,MAAM,UAAU,GAAG,yBAAyB,CAAA;AAE5C,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,IAAI,OAAO,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACpC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACxB,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAC/B,UAAwC,EACxC,cAAmC;IAEnC,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAA;IACjC,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC/C,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ;YAC7D,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,UAAU,EAAE,wBAAwB,CAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC;SACvE,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAMD;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAyC,EACzC,IAAyB;IAEzB,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC3D,MAAM,UAAU,GAAG;QACjB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ;QAC3E,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI;QACjC,UAAU,EAAE,wBAAwB,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI;KACvF,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IACvD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACjE,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAc;IAClD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACrE,GAAG,CAAC,CAAC,CAAC,GAAI,KAAiC,CAAC,CAAC,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import type { StorageProvider, PurgeStrategy, CacheConfig } from './types.js';
2
+ import type { Site } from './site-loader.js';
2
3
  /**
3
4
  * Publish a page as HTML with ESI placeholders for fragments.
4
5
  * Local components are baked in. Fragment markup is replaced at request time by the worker.
5
6
  * CSS is stored as separate hashed files for immutable caching.
6
7
  */
7
- export declare function publishPageRendered(pageName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, targetCache?: CacheConfig, templatesDir?: string, manifestHash?: string): Promise<{
8
+ export declare function publishPageRendered(pageName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, targetCache?: CacheConfig, templatesDir?: string, manifestHash?: string, preloadedSite?: Site): Promise<{
8
9
  files: number;
9
10
  removed: number;
10
11
  }>;
@@ -13,26 +14,26 @@ export declare function publishPageRendered(pageName: string, sourceStorage: Sto
13
14
  * All components (including fragments) are baked in. CSS/JS inline.
14
15
  * For static hosting: GitHub Pages, Netlify, Vercel, any file server.
15
16
  */
16
- export declare function publishPageStatic(pageName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, templatesDir?: string, manifestHash?: string): Promise<{
17
+ export declare function publishPageStatic(pageName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, templatesDir?: string, manifestHash?: string, preloadedSite?: Site): Promise<{
17
18
  files: number;
18
19
  }>;
19
20
  /**
20
21
  * Publish a fragment as HTML with a <head> section for CSS/JS.
21
22
  * The worker injects <head> content before </head> and body content at the ESI placeholder.
22
23
  */
23
- export declare function publishFragmentRendered(fragmentName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, templatesDir?: string, manifestHash?: string): Promise<{
24
+ export declare function publishFragmentRendered(fragmentName: string, sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, templatesDir?: string, manifestHash?: string, preloadedSite?: Site): Promise<{
24
25
  files: number;
25
26
  removed: number;
26
27
  }>;
27
28
  /**
28
29
  * Publish site manifest (stripped of targets config).
29
30
  */
30
- export declare function publishSiteManifest(sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider): Promise<void>;
31
+ export declare function publishSiteManifest(sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, preloadedSite?: Site): Promise<void>;
31
32
  /**
32
33
  * Build and store reverse fragment index.
33
34
  * Maps each fragment to the list of page routes that use it.
34
35
  */
35
- export declare function publishFragmentIndex(sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider): Promise<Record<string, string[]>>;
36
+ export declare function publishFragmentIndex(sourceStorage: StorageProvider, sourceDir: string, targetStorage: StorageProvider, preloadedSite?: Site): Promise<Record<string, string[]>>;
36
37
  /** Purge via Cloudflare zone cache API */
37
38
  export declare function createCloudflarePurge(zoneId: string, apiToken: string): PurgeStrategy;
38
39
  /** Look up Cloudflare zone ID from a site URL */
@@ -1 +1 @@
1
- {"version":3,"file":"publish-rendered.d.ts","sourceRoot":"","sources":["../src/publish-rendered.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAqD7E;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,WAAW,CAAC,EAAE,WAAW,EACzB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA8G7C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5B;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA0D7C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,GAC7B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAiBnC;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAcrF;AAED,iDAAiD;AACjD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQtG;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,KAAK,EAAE,aAAa,EACpB,SAAS,GAAE,KAAK,GAAG,KAAa,GAC/B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkBlD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAUlD"}
1
+ {"version":3,"file":"publish-rendered.d.ts","sourceRoot":"","sources":["../src/publish-rendered.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAmC5C;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,WAAW,CAAC,EAAE,WAAW,EACzB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,IAAI,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsH7C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,IAAI,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B5B;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,IAAI,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAgE7C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,aAAa,CAAC,EAAE,IAAI,GACnB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,aAAa,CAAC,EAAE,IAAI,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAiBnC;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAcrF;AAED,iDAAiD;AACjD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQtG;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,KAAK,EAAE,aAAa,EACpB,SAAS,GAAE,KAAK,GAAG,KAAa,GAC/B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkBlD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,eAAe,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,eAAe,EAC9B,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAUlD"}