jskelet 0.6.14 → 0.6.15

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.
package/CHANGELOG.md CHANGED
@@ -17,6 +17,10 @@ one is listed under a **Breaking** heading.
17
17
 
18
18
  ### Added
19
19
 
20
+ - `asset(name, { origin: "document" })` skips `build.assets.prefix` and
21
+ returns the site-origin `/assets/…` path. `icon()` always resolves the
22
+ sprite this way so SVG `<use href>` keeps working when other assets are
23
+ on a CDN (the origin still serves `public/assets/`).
20
24
  - Dev overlay **API** tab (between Performance and Server): outbound
21
25
  `fetch` calls for the current page — browser and SSR — with host
22
26
  rollup, duration, status, and a detail pane on click (component,
@@ -629,7 +629,7 @@ değişmez** — asset'ler origin'den servis edilir.
629
629
 
630
630
  | Alan | Tip | Varsayılan | Anlamı |
631
631
  | --- | --- | --- | --- |
632
- | `assets.prefix` | `string` | `""` | CDN origin; `asset()` URL öneki (sonunda `/` yok). Yalnızca config. Manifest diskte göreli kalır. |
632
+ | `assets.prefix` | `string` | `""` | CDN origin; `asset()` URL öneki (sonunda `/` yok). Yalnızca config. Manifest diskte göreli kalır. `asset(name, { origin: "document" })` ve `icon()` sprite'ı öneksiz kalır. |
633
633
  | `assets.upload.enabled` | `boolean` | `false` | `true` veya config'te `bucket` doluysa açılır; açık `false` ezer. |
634
634
  | `assets.upload.bucket` | `string \| null` | `null` | **S3 bucket adı** (`static.ornek.com` gibi noktalı adlar geçerli; PutObject path-style kullanır) veya `bucket/key/prefix`. `https://…` şeması kabul edilmez — o `prefix`. |
635
635
  | `assets.upload.keyPrefix` | `string` | `""` | Nesne anahtarı öneki; bucket yolunda verilmişse o kazanır (`prefix` takma adı da kabul). |
package/docs/08-build.md CHANGED
@@ -80,6 +80,10 @@ dosya adlarını okunur tutuyor. Hash'li olmaları sayesinde bu dosyalara
80
80
  - `asset(name)` manifest'te varsa hash'li URL'i, yoksa `/assets/<name>` döner.
81
81
  `build.assets.prefix` doluysa bu göreli yolun önüne CDN origin eklenir
82
82
  (manifest diskte göreli kalır).
83
+ - `asset(name, { origin: "document" })` prefix'i atlar; site origin'indeki
84
+ `/assets/…` yolunu döner. SVG `<use href>` çapraz origin sprite
85
+ yüklemediği için `icon()` sprite'ı her zaman böyle çözer — origin hâlâ
86
+ `public/assets/` servis eder.
83
87
  - `hasAsset(name)` manifest'te olup olmadığını söyler.
84
88
 
85
89
  ### CDN prefix ve S3 upload
@@ -91,7 +95,8 @@ env → ECS task role → EC2 IMDS zincirinden. Açılınca:
91
95
  altındaki dosyaları S3'e PutObject ile kopyalar.
92
96
  2. Çalışma anında `asset()` / optimize görseller `build.assets.prefix` ile
93
97
  absolute CDN URL basar. Entry CDN'deyse esbuild chunk'ları göreli yolla aynı
94
- host'a gider.
98
+ host'a gider. `icon()` sprite'ı ve `asset(name, { origin: "document" })`
99
+ site origin'inde kalır.
95
100
 
96
101
  Bucket adı noktalı olabilir (`static.ornek.com`); `https://…` şeması
97
102
  `prefix`'e yazılır. Config sözlüğü: [07-yapilandirma.md](./07-yapilandirma.md#build).
@@ -457,7 +462,9 @@ karşılaşmaması.
457
462
  - **Bazı Tailwind sınıfları çalışmıyor.** `@source` direktifi eksik olan bir
458
463
  dizinde yazılmışlar.
459
464
  - **İkon boş görünüyor.** Sprite'ta o sembol yok; dev'de `[icon] missing from sprite`
460
- uyarısına bakın.
465
+ uyarısına bakın. CDN prefix açıkken sprite bilerek site origin'inde kalır
466
+ (`asset("sprite.svg", { origin: "document" })`); origin `public/assets/`
467
+ servis etmiyorsa `<use>` boş kalır.
461
468
  - **Island'lar hiç açılmıyor.** `main.js` manifest'te yok (entry dizini boş ya
462
469
  da build atlanmış) veya bir build hatası var.
463
470
  - **Dev'de sayfa aniden stilsiz kaldı.** Manifest ile diskteki dosya
@@ -642,7 +642,7 @@ changes** — assets stay on the origin.
642
642
 
643
643
  | Field | Type | Default | Meaning |
644
644
  | --- | --- | --- | --- |
645
- | `assets.prefix` | `string` | `""` | CDN origin; prefix for `asset()` URLs (no trailing `/`). Config only. The on-disk manifest stays relative. |
645
+ | `assets.prefix` | `string` | `""` | CDN origin; prefix for `asset()` URLs (no trailing `/`). Config only. The on-disk manifest stays relative. `asset(name, { origin: "document" })` and the `icon()` sprite stay unprefixed. |
646
646
  | `assets.upload.enabled` | `boolean` | `false` | Turns on when `true` or when `bucket` is set in config; explicit `false` wins. |
647
647
  | `assets.upload.bucket` | `string \| null` | `null` | **S3 bucket name** (dotted names like `static.example.com` are fine; PutObject uses path-style) or `bucket/key/prefix`. A `https://…` scheme is rejected — that belongs in `prefix`. |
648
648
  | `assets.upload.keyPrefix` | `string` | `""` | Object key prefix; a path on the bucket wins (`prefix` is accepted as an alias). |
@@ -83,6 +83,10 @@ They are passed to templates automatically; in server code,
83
83
  - `asset(name)` returns the hashed URL if it is in the manifest, otherwise
84
84
  `/assets/<name>`. When `build.assets.prefix` is set, that relative path is
85
85
  prefixed with the CDN origin (the on-disk manifest stays relative).
86
+ - `asset(name, { origin: "document" })` skips the prefix and returns the
87
+ site-origin `/assets/…` path. SVG `<use href>` cannot load a cross-origin
88
+ sprite, so `icon()` always resolves the sprite this way — the origin still
89
+ serves `public/assets/`.
86
90
  - `hasAsset(name)` tells you whether it is in the manifest.
87
91
 
88
92
  ### CDN prefix and S3 upload
@@ -94,7 +98,8 @@ resolve from env → ECS task role → EC2 IMDS. When enabled:
94
98
  directories in `include`) to S3.
95
99
  2. At runtime `asset()` / optimised images emit absolute CDN URLs via
96
100
  `build.assets.prefix`. When the entry script is on the CDN, esbuild chunks
97
- resolve relatively on the same host.
101
+ resolve relatively on the same host. The `icon()` sprite and
102
+ `asset(name, { origin: "document" })` stay on the document origin.
98
103
 
99
104
  Bucket names may include dots (`static.example.com`); put `https://…` in
100
105
  `prefix`. Config reference: [07-configuration.md](./07-configuration.md#build).
@@ -473,7 +478,9 @@ directly does not end up facing an unstyled page.
473
478
  - **Some Tailwind classes do not work.** They were written in a directory whose
474
479
  `@source` directive is missing.
475
480
  - **An icon looks empty.** That symbol is not in the sprite; in dev, look for the
476
- `[icon] missing from sprite` warning.
481
+ `[icon] missing from sprite` warning. With a CDN prefix the sprite stays on
482
+ the document origin on purpose (`asset("sprite.svg", { origin: "document" })`);
483
+ if the origin does not serve `public/assets/`, `<use>` stays blank.
477
484
  - **The islands never open.** `main.js` is not in the manifest (the entry
478
485
  directory is empty or the build was skipped) or there is a build error.
479
486
  - **The page suddenly went unstyled in dev.** The manifest and the file on disk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jskelet",
3
- "version": "0.6.14",
3
+ "version": "0.6.15",
4
4
  "description": "A framework that feels like no framework: Express 5 + build-time .jsk SSR (optional EJS peer), vanilla JS islands, Tailwind v4 and an in-process HTML TTL cache.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,6 +9,11 @@
9
9
  * `build.assets.prefix` doluysa HTML'e basılan URL'lere CDN origin eklenir;
10
10
  * manifest diskte göreli kalır. Dosya sistemi okumaları (`getSpriteIds`)
11
11
  * göreli yolu kullanır.
12
+ *
13
+ * Bazı varlıklar bilinçli olarak site origin'inde kalır: SVG `<use href>`
14
+ * çapraz origin sprite yüklemez. `asset(name, { origin: "document" })`
15
+ * prefix'i atlar; `icon()` sprite için bunu kullanır. Origin hâlâ
16
+ * `public/assets/` servis eder.
12
17
  */
13
18
  import fs from "node:fs";
14
19
  import path from "node:path";
@@ -17,7 +22,7 @@ import { getConfig } from "../config/index.js";
17
22
 
18
23
  const isDev = process.env.NODE_ENV === "development";
19
24
 
20
- /** @type {{ manifest: Record<string, string> } | null} */
25
+ /** @type {{ manifest: Record<string, string>, generated: string } | null} */
21
26
  let cached = null;
22
27
  let warned = false;
23
28
 
@@ -38,13 +43,15 @@ function load() {
38
43
  }
39
44
  }
40
45
 
41
- return { manifest };
46
+ return { manifest, generated };
42
47
  }
43
48
 
44
49
  function state() {
45
50
  // Dev'de her istekte yeniden okunur (watch build hash'leri değiştirir);
46
- // prod'da bir kez.
47
- if (isDev || !cached) cached = load();
51
+ // prod'da bir kez. `generated` yolu değiştiyse (test / başka kök) de
52
+ // yenilenir — aksi hâlde eski manifest takılı kalır.
53
+ const generated = getConfig().dirs.generated;
54
+ if (isDev || !cached || cached.generated !== generated) cached = load();
48
55
  return cached;
49
56
  }
50
57
 
@@ -82,11 +89,22 @@ function assetPath(name) {
82
89
  }
83
90
 
84
91
  /**
92
+ * @typedef {{ origin?: "cdn" | "document" }} AssetOptions
93
+ */
94
+
95
+ /**
96
+ * Manifest'teki hash'li (veya yedek) URL.
97
+ *
85
98
  * @param {string} name Örn. "app.css", "main.js", "sprite.svg"
99
+ * @param {AssetOptions} [options]
100
+ * `origin: "document"` → `build.assets.prefix` uygulanmaz; site
101
+ * origin'indeki `/assets/…` yolu döner (varsayılan `"cdn"`).
86
102
  * @returns {string}
87
103
  */
88
- export function asset(name) {
89
- return applyAssetPrefix(assetPrefix(), assetPath(name));
104
+ export function asset(name, options = {}) {
105
+ const relative = assetPath(name);
106
+ if (options.origin === "document") return relative;
107
+ return applyAssetPrefix(assetPrefix(), relative);
90
108
  }
91
109
 
92
110
  /**
@@ -195,6 +195,11 @@ export function preloadImage({ href, imagesrcset, imagesizes }) {
195
195
  /**
196
196
  * Phosphor ikonları — build zamanı üretilen SVG sprite'tan `<use>`.
197
197
  * `weight` sprite id'sine dahildir (regular/bold/fill).
198
+ *
199
+ * Sprite URL'si her zaman site origin'indedir (`asset(..., { origin:
200
+ * "document" })`). `<use href>` çapraz origin SVG yüklemez; CDN prefix
201
+ * açıkken bile `public/assets/sprite.<hash>.svg` aynı host'tan gelir.
202
+ *
198
203
  * @param {{ name: string, size?: number | string, weight?: string,
199
204
  * class?: string, attrs?: Record<string, unknown> }} props
200
205
  * @returns {string}
@@ -208,7 +213,7 @@ export function icon(props) {
208
213
  attrs: extra = {},
209
214
  } = props;
210
215
 
211
- const spritePath = asset("sprite.svg");
216
+ const spritePath = asset("sprite.svg", { origin: "document" });
212
217
  const id = `${toKebab(name)}-${weight}`;
213
218
 
214
219
  if (isDev && !warnedIcons.has(id)) {
@@ -6,11 +6,22 @@
6
6
  * @returns {string}
7
7
  */
8
8
  export declare function applyAssetPrefix(prefix: string, url: string): string;
9
+ export type AssetOptions = {
10
+ origin?: "cdn" | "document";
11
+ };
12
+ /**
13
+ * @typedef {{ origin?: "cdn" | "document" }} AssetOptions
14
+ */
9
15
  /**
16
+ * Manifest'teki hash'li (veya yedek) URL.
17
+ *
10
18
  * @param {string} name Örn. "app.css", "main.js", "sprite.svg"
19
+ * @param {AssetOptions} [options]
20
+ * `origin: "document"` → `build.assets.prefix` uygulanmaz; site
21
+ * origin'indeki `/assets/…` yolu döner (varsayılan `"cdn"`).
11
22
  * @returns {string}
12
23
  */
13
- export declare function asset(name: string): string;
24
+ export declare function asset(name: string, options?: AssetOptions): string;
14
25
  /**
15
26
  * @param {string} name
16
27
  * @returns {boolean}
@@ -60,6 +60,11 @@ export declare function preloadImage({ href, imagesrcset, imagesizes }: {
60
60
  /**
61
61
  * Phosphor ikonları — build zamanı üretilen SVG sprite'tan `<use>`.
62
62
  * `weight` sprite id'sine dahildir (regular/bold/fill).
63
+ *
64
+ * Sprite URL'si her zaman site origin'indedir (`asset(..., { origin:
65
+ * "document" })`). `<use href>` çapraz origin SVG yüklemez; CDN prefix
66
+ * açıkken bile `public/assets/sprite.<hash>.svg` aynı host'tan gelir.
67
+ *
63
68
  * @param {{ name: string, size?: number | string, weight?: string,
64
69
  * class?: string, attrs?: Record<string, unknown> }} props
65
70
  * @returns {string}