@leadertechie/personal-site-kit 0.1.0-alpha.15 → 0.1.0-alpha.16

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.
@@ -1 +1 @@
1
- {"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3E,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiC;IAEhD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IAIzD,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,UAAU;IAqBL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CA+FlE"}
1
+ {"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3E,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiC;IAEhD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IAIzD,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,UAAU;IAqBL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAgGlE"}
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { W as WebsiteAPI } from "./chunks/website-api-CE2q2nt7.js";
2
- import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-CE2q2nt7.js";
1
+ import { W as WebsiteAPI } from "./chunks/website-api-C3lGjXdD.js";
2
+ import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-C3lGjXdD.js";
3
3
  const defaultAPI = new WebsiteAPI();
4
4
  export {
5
5
  A as AUTH_KV,
@@ -798,16 +798,20 @@ class WebsiteAPI {
798
798
  this.customHandlers.set(route, handler);
799
799
  }
800
800
  addCORSHeaders(response) {
801
- response.headers.set("Access-Control-Allow-Origin", "*");
801
+ if (!response.headers.has("Access-Control-Allow-Origin")) {
802
+ response.headers.set("Access-Control-Allow-Origin", "*");
803
+ }
802
804
  response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
803
805
  response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Session-Token");
804
806
  return response;
805
807
  }
806
808
  addAdminCORSHeaders(response, origin) {
807
809
  const isLocal = origin && (origin.includes("localhost") || origin.includes("127.0.0.1"));
808
- if (isLocal) {
809
- response.headers.set("Access-Control-Allow-Origin", origin);
810
- response.headers.set("Access-Control-Allow-Credentials", "true");
810
+ if (!response.headers.has("Access-Control-Allow-Origin")) {
811
+ if (isLocal) {
812
+ response.headers.set("Access-Control-Allow-Origin", origin);
813
+ response.headers.set("Access-Control-Allow-Credentials", "true");
814
+ }
811
815
  }
812
816
  response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
813
817
  response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Session-Token");
@@ -871,7 +875,7 @@ class WebsiteAPI {
871
875
  return this.addAdminCORSHeaders(createErrorResponse("Unauthorized", 401), origin);
872
876
  }
873
877
  clearContentCache$1();
874
- return this.addAdminCORSHeaders(new Response(JSON.stringify({ success: true, message: "Cache cleared" }), { status: 200 }), origin);
878
+ return this.addAdminCORSHeaders(new Response(JSON.stringify({ success: true, message: "Cache cleared" }), { status: 200, headers: { "Content-Type": "application/json" } }), origin);
875
879
  case "aboutme":
876
880
  return this.addAdminCORSHeaders(await handleAboutMe(env), origin);
877
881
  case "logo":
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-CE2q2nt7.js";
1
+ import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-C3lGjXdD.js";
2
2
  import { WebsitePrerender } from "./prerender.js";
3
3
  import { A as A2, a as a2, b as b2, c as c2, d as d2, e as e2, f, g as g2, h as h2, i, B as B2, F, M as M2, j, S, k } from "./chunks/index-B2jGIzSi.js";
4
4
  import { S as S2, g as g3, i as i2, r as r2 } from "./chunks/site-store-CGV9c2DI.js";
@@ -5,6 +5,8 @@ export interface TemplateProps {
5
5
  content: string;
6
6
  hydrationData?: string;
7
7
  baseSiteUrl?: string;
8
+ jsAsset?: string;
9
+ cssAsset?: string;
8
10
  }
9
- export declare const createHtmlTemplate: ({ title, description, canonicalUrl, content, hydrationData, baseSiteUrl }: TemplateProps) => Promise<string>;
11
+ export declare const createHtmlTemplate: ({ title, description, canonicalUrl, content, hydrationData, baseSiteUrl, jsAsset, cssAsset }: TemplateProps) => Promise<string>;
10
12
  //# sourceMappingURL=template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/prerender/template.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAuCD,eAAO,MAAM,kBAAkB,GAAU,2EAOtC,aAAa,KAAG,OAAO,CAAC,MAAM,CA4BhC,CAAC"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/prerender/template.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsDD,eAAO,MAAM,kBAAkB,GAAU,8FAStC,aAAa,KAAG,OAAO,CAAC,MAAM,CAmChC,CAAC"}
@@ -18,7 +18,9 @@ export declare class WebsitePrerender {
18
18
  private copyright;
19
19
  private templateRenderer;
20
20
  private apiHandler?;
21
+ private cachedAssets;
21
22
  constructor(options?: PrerenderOptions);
23
+ private discoverAssets;
22
24
  private fetchStaticDetails;
23
25
  private fetchAboutMeData;
24
26
  fetch(request: Request, env: any, ctx: any): Promise<Response>;
@@ -1 +1 @@
1
- {"version":3,"file":"website-prerender.d.ts","sourceRoot":"","sources":["../../src/prerender/website-prerender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAuB,MAAM,gBAAgB,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,WAAW,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACtE,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;KAAE,CAAC;CAChG;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAqD;IAC7E,OAAO,CAAC,UAAU,CAAC,CAAoF;gBAE3F,OAAO,GAAE,gBAAqB;YAmB5B,kBAAkB;YAiClB,gBAAgB;IAajB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAoH5E"}
1
+ {"version":3,"file":"website-prerender.d.ts","sourceRoot":"","sources":["../../src/prerender/website-prerender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAuB,MAAM,gBAAgB,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,WAAW,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACtE,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;KAAE,CAAC;CAChG;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAqD;IAC7E,OAAO,CAAC,UAAU,CAAC,CAAoF;IACvG,OAAO,CAAC,YAAY,CAA4C;gBAEpD,OAAO,GAAE,gBAAqB;YAmB5B,cAAc;YAuCd,kBAAkB;YAgClB,gBAAgB;IAajB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAiI5E"}
package/dist/prerender.js CHANGED
@@ -1,27 +1,42 @@
1
1
  import { R2ContentLoader } from "@leadertechie/r2tohtml";
2
+ let cachedAssets = null;
3
+ let isDiscovering = false;
2
4
  async function getAssetPaths(baseSiteUrl) {
3
- if (baseSiteUrl.includes("localhost") || baseSiteUrl.includes("127.0.0.1")) ;
4
- const assetsUrl = `${baseSiteUrl}/cdn-assets.json`;
5
+ if (cachedAssets) return cachedAssets;
6
+ if (isDiscovering) {
7
+ return { js: "/assets/index.js", css: "/assets/index.css" };
8
+ }
9
+ isDiscovering = true;
5
10
  try {
11
+ const assetsUrl = `${baseSiteUrl}/cdn-assets.json`;
6
12
  const res = await fetch(assetsUrl);
7
13
  if (res.ok) {
8
14
  const data = await res.json();
9
- return { js: data.js, css: data.css };
15
+ cachedAssets = { js: data.js, css: data.css };
16
+ isDiscovering = false;
17
+ return cachedAssets;
10
18
  }
11
19
  } catch (e) {
12
20
  }
13
21
  try {
14
- const res = await fetch(`${baseSiteUrl}/?t=${Date.now()}`);
15
- const html = await res.text();
16
- const jsMatch = html.match(/src="(\/assets\/index-[^"]+\.js)"/);
17
- const cssMatch = html.match(/href="(\/assets\/index-[^"]+\.css)"/);
18
- if (jsMatch || cssMatch) {
19
- return {
20
- js: jsMatch ? jsMatch[1] : "/assets/index.js",
21
- css: cssMatch ? cssMatch[1] : "/assets/index.css"
22
- };
22
+ const res = await fetch(`${baseSiteUrl}/index.html`);
23
+ if (res.ok) {
24
+ const html = await res.text();
25
+ const jsMatch = html.match(/src="([^"]*assets\/index-[^"]+\.js)"/);
26
+ const cssMatch = html.match(/href="([^"]*assets\/index-[^"]+\.css)"/);
27
+ if (jsMatch || cssMatch) {
28
+ cachedAssets = {
29
+ js: jsMatch ? jsMatch[1].startsWith("/") ? jsMatch[1] : "/" + jsMatch[1] : "/assets/index.js",
30
+ css: cssMatch ? cssMatch[1].startsWith("/") ? cssMatch[1] : "/" + cssMatch[1] : "/assets/index.css"
31
+ };
32
+ isDiscovering = false;
33
+ return cachedAssets;
34
+ }
23
35
  }
24
36
  } catch (e) {
37
+ console.warn("Asset discovery failed:", e);
38
+ } finally {
39
+ isDiscovering = false;
25
40
  }
26
41
  return { js: "/assets/index.js", css: "/assets/index.css" };
27
42
  }
@@ -31,10 +46,18 @@ const createHtmlTemplate = async ({
31
46
  canonicalUrl,
32
47
  content,
33
48
  hydrationData = "",
34
- baseSiteUrl = ""
49
+ baseSiteUrl = "",
50
+ jsAsset,
51
+ cssAsset
35
52
  }) => {
36
- const effectiveBaseUrl = baseSiteUrl || new URL(canonicalUrl).origin;
37
- const { js: jsAsset, css: cssAsset } = await getAssetPaths(effectiveBaseUrl);
53
+ let js = jsAsset;
54
+ let css = cssAsset;
55
+ if (!js || !css) {
56
+ const effectiveBaseUrl = baseSiteUrl || new URL(canonicalUrl).origin;
57
+ const discovered = await getAssetPaths(effectiveBaseUrl);
58
+ js = js || discovered.js;
59
+ css = css || discovered.css;
60
+ }
38
61
  return `<!doctype html>
39
62
  <html lang="en" data-theme="light">
40
63
  <head>
@@ -48,8 +71,8 @@ const createHtmlTemplate = async ({
48
71
  <meta property="og:description" content="${description}" />
49
72
  <meta property="og:url" content="${canonicalUrl}" />
50
73
  <link rel="canonical" href="${canonicalUrl}" />
51
- <link rel="stylesheet" crossorigin href="${cssAsset}" />
52
- <script type="module" crossorigin src="${jsAsset}"><\/script>
74
+ <link rel="stylesheet" crossorigin href="${css}" />
75
+ <script type="module" crossorigin src="${js}"><\/script>
53
76
  </head>
54
77
  <body>
55
78
  ${hydrationData}
@@ -290,6 +313,7 @@ const generatePageContent = async (pathname, routes, footerLinks, env) => {
290
313
  };
291
314
  class WebsitePrerender {
292
315
  constructor(options = {}) {
316
+ this.cachedAssets = null;
293
317
  this.routes = options.routes || [
294
318
  { link: "/", text: "Home" },
295
319
  { link: "/blogs", text: "Blogs" },
@@ -307,11 +331,41 @@ class WebsitePrerender {
307
331
  this.templateRenderer = options.templateRenderer || createHtmlTemplate;
308
332
  this.apiHandler = options.apiHandler;
309
333
  }
334
+ async discoverAssets(env, baseSiteUrl) {
335
+ if (this.cachedAssets) return this.cachedAssets;
336
+ try {
337
+ let html = "";
338
+ if (env.ASSETS) {
339
+ const res = await env.ASSETS.fetch(new Request("http://localhost/index.html"));
340
+ if (res.ok) html = await res.text();
341
+ }
342
+ if (!html) {
343
+ const res = await fetch(`${baseSiteUrl}/index.html`, {
344
+ headers: { "X-Asset-Discovery": "true" }
345
+ });
346
+ if (res.ok) html = await res.text();
347
+ }
348
+ if (html) {
349
+ const jsMatch = html.match(/src="([^"]*assets\/index-[^"]+\.js)"/);
350
+ const cssMatch = html.match(/href="([^"]*assets\/index-[^"]+\.css)"/);
351
+ if (jsMatch || cssMatch) {
352
+ this.cachedAssets = {
353
+ js: jsMatch ? jsMatch[1].startsWith("/") ? jsMatch[1] : "/" + jsMatch[1] : "/assets/index.js",
354
+ css: cssMatch ? cssMatch[1].startsWith("/") ? cssMatch[1] : "/" + cssMatch[1] : "/assets/index.css"
355
+ };
356
+ return this.cachedAssets;
357
+ }
358
+ }
359
+ } catch (e) {
360
+ console.warn("Asset discovery failed:", e);
361
+ }
362
+ return { js: "/assets/index.js", css: "/assets/index.css" };
363
+ }
310
364
  async fetchStaticDetails(apiUrl, env) {
311
365
  try {
312
366
  let data;
313
367
  if (this.apiHandler) {
314
- const res = await this.apiHandler.fetch(new Request(`${apiUrl}/api/static`), env, {});
368
+ const res = await this.apiHandler.fetch(new Request("http://localhost/api/static"), env, {});
315
369
  if (res.ok) data = await res.json();
316
370
  } else {
317
371
  const res = await fetch(`${apiUrl}/api/static`);
@@ -338,7 +392,7 @@ class WebsitePrerender {
338
392
  async fetchAboutMeData(apiUrl, env) {
339
393
  try {
340
394
  if (this.apiHandler) {
341
- const res = await this.apiHandler.fetch(new Request(`${apiUrl}/api/aboutme`), env, {});
395
+ const res = await this.apiHandler.fetch(new Request("http://localhost/api/aboutme"), env, {});
342
396
  if (res.ok) return await res.json();
343
397
  } else {
344
398
  const res = await fetch(`${apiUrl}/api/aboutme`);
@@ -353,6 +407,10 @@ class WebsitePrerender {
353
407
  const apiUrl = env?.API_URL || `${url.origin}/api`;
354
408
  const baseSiteUrl = env?.BASE_SITE_URL || url.origin;
355
409
  if (url.pathname === "/admin" || url.pathname.startsWith("/admin/")) {
410
+ if (env.ASSETS) {
411
+ const assetRes = await env.ASSETS.fetch(new Request("http://localhost/index.html"));
412
+ if (assetRes.ok) return assetRes;
413
+ }
356
414
  const templateResponse = await fetch(`${baseSiteUrl}/index.html`);
357
415
  if (templateResponse.ok) {
358
416
  return new Response(templateResponse.body, {
@@ -360,6 +418,11 @@ class WebsitePrerender {
360
418
  });
361
419
  }
362
420
  }
421
+ if (request.headers.get("X-Asset-Discovery") === "true") {
422
+ if (env.ASSETS) {
423
+ return env.ASSETS.fetch(new Request("http://localhost/index.html"));
424
+ }
425
+ }
363
426
  await this.fetchStaticDetails(apiUrl, env);
364
427
  if (url.pathname.startsWith("/api/")) {
365
428
  if (this.apiHandler) {
@@ -409,7 +472,7 @@ class WebsitePrerender {
409
472
  ico: "image/x-icon"
410
473
  };
411
474
  const contentType = contentTypes[ext || ""] || "application/octet-stream";
412
- if (baseSiteUrl === url.origin) {
475
+ if (baseSiteUrl === url.origin && !env.ASSETS) {
413
476
  return new Response("Asset not found", { status: 404 });
414
477
  }
415
478
  const response = await fetch(`${baseSiteUrl}${path}`);
@@ -436,8 +499,15 @@ class WebsitePrerender {
436
499
  hydrationScript = `<script>window.__HYDRATION_DATA__ = ${JSON.stringify(aboutMeData)};<\/script>`;
437
500
  }
438
501
  }
502
+ const assets = await this.discoverAssets(env, baseSiteUrl);
439
503
  const pageContent = await generatePageContent(url.pathname, this.routes, this.footerLinks, { ...env, apiUrl, siteTitle: this.siteTitle, copyright: this.copyright });
440
- const html = await this.templateRenderer({ ...pageContent, hydrationData: hydrationScript });
504
+ const html = await this.templateRenderer({
505
+ ...pageContent,
506
+ hydrationData: hydrationScript,
507
+ baseSiteUrl,
508
+ jsAsset: assets.js,
509
+ cssAsset: assets.css
510
+ });
441
511
  return new Response(html, {
442
512
  headers: {
443
513
  "content-type": "text/html",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leadertechie/personal-site-kit",
3
- "version": "0.1.0-alpha.15",
3
+ "version": "0.1.0-alpha.16",
4
4
  "type": "module",
5
5
  "description": "A high-performance personal website engine for Cloudflare Workers and R2",
6
6
  "repository": {