jskelet 0.6.2 → 0.6.3

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 (155) hide show
  1. package/AGENTS.md +136 -136
  2. package/CHANGELOG.md +620 -596
  3. package/LICENSE +21 -21
  4. package/bin/jskelet.mjs +130 -130
  5. package/docs/01-baslangic.md +291 -291
  6. package/docs/02-mimari.md +310 -309
  7. package/docs/03-routing.md +515 -515
  8. package/docs/04-render-ve-sablonlar.md +661 -661
  9. package/docs/05-islands.md +486 -486
  10. package/docs/06-cache.md +1443 -1423
  11. package/docs/07-yapilandirma.md +12 -6
  12. package/docs/08-build.md +429 -428
  13. package/docs/09-dev-araclari.md +364 -364
  14. package/docs/10-dagitim.md +338 -338
  15. package/docs/12-panel-ve-oturum.md +478 -478
  16. package/docs/README.md +83 -83
  17. package/docs/en/01-getting-started.md +298 -298
  18. package/docs/en/02-architecture.md +329 -328
  19. package/docs/en/03-routing.md +531 -531
  20. package/docs/en/04-rendering.md +669 -669
  21. package/docs/en/05-islands.md +497 -497
  22. package/docs/en/06-caching.md +1453 -1431
  23. package/docs/en/07-configuration.md +1219 -1214
  24. package/docs/en/08-build.md +447 -446
  25. package/docs/en/09-dev-tools.md +373 -373
  26. package/docs/en/10-deployment.md +340 -340
  27. package/docs/en/11-migration.md +398 -398
  28. package/docs/en/12-dashboards-and-sessions.md +488 -488
  29. package/docs/en/README.md +87 -87
  30. package/package.json +137 -137
  31. package/src/build/ensure-build.mjs +19 -19
  32. package/src/build/paths.mjs +153 -153
  33. package/src/build/resolve-peer.mjs +36 -36
  34. package/src/build/tasks/client.mjs +349 -349
  35. package/src/build/tasks/css.mjs +235 -235
  36. package/src/build/tasks/fonts.mjs +146 -146
  37. package/src/build/tasks/icons.mjs +357 -357
  38. package/src/build/tasks/images.mjs +244 -244
  39. package/src/build/tasks/precompress.mjs +78 -78
  40. package/src/build/tasks/templates.mjs +20 -20
  41. package/src/client/admin/i18n.js +764 -764
  42. package/src/client/admin/login.html +74 -74
  43. package/src/client/admin/panel.css +809 -809
  44. package/src/client/admin/panel.html +495 -495
  45. package/src/client/admin/panel.js +1251 -1251
  46. package/src/client/devtools/report.html +185 -185
  47. package/src/client/devtools/report.js +745 -745
  48. package/src/client/devtools/seo.js +628 -628
  49. package/src/client/dom.js +95 -95
  50. package/src/client/form.js +192 -192
  51. package/src/client/index.js +45 -45
  52. package/src/client/registry.js +305 -305
  53. package/src/client/safe-image.js +91 -91
  54. package/src/client/shared-cookie.js +225 -225
  55. package/src/client/store.js +36 -36
  56. package/src/client/swap.js +188 -188
  57. package/src/compile/codegen.js +336 -336
  58. package/src/compile/compile-all.js +149 -149
  59. package/src/compile/errors.js +66 -66
  60. package/src/compile/expr.js +409 -409
  61. package/src/compile/index.js +17 -17
  62. package/src/compile/parse.js +541 -541
  63. package/src/compile/resolve.js +211 -211
  64. package/src/compile/scan-exports.js +51 -51
  65. package/src/config/defaults.js +17 -1
  66. package/src/config/index.js +13 -0
  67. package/src/config/pattern.js +107 -107
  68. package/src/generate.mjs +163 -163
  69. package/src/http/control-flow.js +71 -71
  70. package/src/http/cookies-entry.js +21 -21
  71. package/src/http/cookies.js +277 -277
  72. package/src/http/request-cache.js +46 -46
  73. package/src/http/request-context.js +165 -165
  74. package/src/http/shared-cookie.js +178 -178
  75. package/src/index.js +101 -101
  76. package/src/init.mjs +230 -230
  77. package/src/migrate/apply.mjs +262 -262
  78. package/src/migrate/babel.mjs +79 -79
  79. package/src/migrate/classify.mjs +155 -155
  80. package/src/migrate/config.mjs +126 -126
  81. package/src/migrate/fs-walk.mjs +191 -191
  82. package/src/migrate/parse.mjs +26 -26
  83. package/src/migrate/scan.mjs +177 -177
  84. package/src/migrate/transform/expr-source.mjs +168 -168
  85. package/src/migrate/transform/island.mjs +67 -67
  86. package/src/migrate/transform/jsx-to-component.mjs +302 -302
  87. package/src/migrate/transform/jsx-to-jsk.mjs +330 -330
  88. package/src/migrate/transform/page-split.mjs +435 -435
  89. package/src/migrate/write.mjs +81 -81
  90. package/src/migrate.mjs +171 -171
  91. package/src/runtime/alias-hooks.mjs +119 -119
  92. package/src/runtime/register.mjs +4 -4
  93. package/src/server/admin/actions.js +229 -229
  94. package/src/server/admin/auth.js +125 -125
  95. package/src/server/admin/event-log.js +151 -151
  96. package/src/server/admin/gate.js +209 -209
  97. package/src/server/admin/inventory.js +188 -188
  98. package/src/server/admin/mount.js +56 -56
  99. package/src/server/admin/router.js +216 -216
  100. package/src/server/admin/snapshot.js +241 -241
  101. package/src/server/assets.js +147 -147
  102. package/src/server/auth/handoff.js +309 -309
  103. package/src/server/cache-blob.js +70 -0
  104. package/src/server/cache-deps.js +42 -42
  105. package/src/server/cache-vary.js +113 -113
  106. package/src/server/cloudflare.js +607 -607
  107. package/src/server/create-app.js +366 -366
  108. package/src/server/data-cache.js +553 -462
  109. package/src/server/dev/report.js +485 -485
  110. package/src/server/dev/socket.js +170 -170
  111. package/src/server/dev/version-check.mjs +139 -139
  112. package/src/server/disk-cache.js +233 -0
  113. package/src/server/ejs-adapter.js +59 -59
  114. package/src/server/html-cache.js +1196 -1122
  115. package/src/server/image-optimizer.js +500 -407
  116. package/src/server/logs/access-middleware.js +66 -66
  117. package/src/server/logs/file-sink.js +193 -66
  118. package/src/server/logs/pipeline.js +165 -158
  119. package/src/server/logs/s3-put.js +214 -214
  120. package/src/server/logs/s3-sink.js +112 -112
  121. package/src/server/metadata.js +102 -102
  122. package/src/server/middleware/compression.js +205 -205
  123. package/src/server/middleware/csrf.js +134 -134
  124. package/src/server/middleware/dev-gate.js +75 -75
  125. package/src/server/middleware/headers.js +37 -37
  126. package/src/server/middleware/redirects.js +32 -32
  127. package/src/server/middleware/robots-txt.js +341 -341
  128. package/src/server/middleware/static-precompressed.js +121 -100
  129. package/src/server/middleware/trailing-slash.js +53 -53
  130. package/src/server/middleware/upstream-proxy.js +141 -141
  131. package/src/server/og-image.js +356 -356
  132. package/src/server/port-guard.js +255 -255
  133. package/src/server/prewarm.js +1082 -1058
  134. package/src/server/redis.js +588 -569
  135. package/src/server/render.js +4 -4
  136. package/src/server/router.js +157 -157
  137. package/src/server/status-page.js +265 -265
  138. package/src/server/upstream-limiter.js +376 -376
  139. package/src/server/upstream-tracking.js +166 -166
  140. package/src/shared/cookie-domain.js +66 -66
  141. package/src/start.mjs +22 -22
  142. package/src/templates/layout.ejs +30 -30
  143. package/src/templates/layout.jsk +30 -30
  144. package/src/version.mjs +31 -31
  145. package/src/views/components/loader.js +101 -101
  146. package/src/views/helpers/html.js +102 -102
  147. package/src/views/helpers/tags.js +375 -375
  148. package/types/config/defaults.d.ts +15 -1
  149. package/types/config/index.d.ts +8 -0
  150. package/types/server/cache-blob.d.ts +13 -0
  151. package/types/server/data-cache.d.ts +9 -0
  152. package/types/server/disk-cache.d.ts +36 -0
  153. package/types/server/html-cache.d.ts +26 -3
  154. package/types/server/logs/file-sink.d.ts +16 -5
  155. package/types/server/redis.d.ts +2 -1
package/AGENTS.md CHANGED
@@ -1,136 +1,136 @@
1
- # AGENTS.md
2
-
3
- Bu depo **JSkelet** framework'ünün kaynağıdır: Express 5 + build-time `.jsk`
4
- sunucu render (EJS opsiyonel legacy peer), vanilla JS island'lar, Tailwind v4
5
- ve süreç belleğinde yaşayan HTML TTL cache. React yok; framework kaynağı düz
6
- JavaScript + JSDoc. Uygulama client island/entry'leri `.ts` olabilir; paket
7
- `types/` altında `.d.ts` yayınlar. Sunucu route/hook/config hâlâ Node ESM
8
- `.js`/`.mjs`.
9
-
10
- Bir JSkelet **uygulamasında** çalışıyorsan (framework'ün kendisinde değil), aynı
11
- kuralların uygulama tarafı karşılıkları için [docs/](./docs/README.md) yeterli;
12
- özellikle 03, 05 ve 07.
13
-
14
- ## Değişiklik yapmadan önce
15
-
16
- Framework'ün davranışını değiştiren bir iş alıyorsan ilgili belgeyi oku. Bu
17
- dosyalar kararların **gerekçelerini** taşıyor ve çoğu "iyileştirme" fikri orada
18
- zaten tartışılmış:
19
-
20
- | Dokunacağın yer | Önce oku |
21
- | --- | --- |
22
- | `src/server/render.js`, şablonlar | [04-render-ve-sablonlar.md](./docs/04-render-ve-sablonlar.md) |
23
- | `src/server/html-cache.js`, `route()` | [06-cache.md](./docs/06-cache.md) |
24
- | `src/server/create-app.js`, middleware | [02-mimari.md](./docs/02-mimari.md) |
25
- | `src/client/**` | [05-islands.md](./docs/05-islands.md) |
26
- | `src/build/**` | [08-build.md](./docs/08-build.md) |
27
- | `src/config/**` | [07-yapilandirma.md](./docs/07-yapilandirma.md) |
28
- | `src/dev-server.mjs`, `src/server/dev/**` | [09-dev-araclari.md](./docs/09-dev-araclari.md) |
29
-
30
- Belgeler iki dilde: Türkçesi `docs/`, İngilizcesi `docs/en/` altında ve
31
- dosyalar birebir eşlenik. Bir belgeyi değiştirdiysen karşılığını da güncelle;
32
- eksik kalan çeviri kullanıcıya görünür.
33
-
34
- ## Doğrulama
35
-
36
- **Lint yeterli, tam build zorunlu değil.**
37
-
38
- ```bash
39
- npm run lint
40
- npm test # desen derleyicisi ve HTML cache için birim testler
41
- ```
42
-
43
- Davranış değiştiren bir iş yaptıysan örneklerden biriyle uçtan uca dene:
44
-
45
- ```bash
46
- npm --prefix examples/blog install # ilk seferde
47
- npm --prefix examples/blog run build
48
- npm --prefix examples/blog run start # ayrı terminalde
49
- node examples/blog/smoke.mjs
50
- ```
51
-
52
- `examples/blog` bilinçli olarak framework'ün her yüzeyini kullanır (dinamik
53
- route, tüm config bölümleri, fragment, form, prewarm, RSS/sitemap, dört island).
54
- Bir şeyi bozduysan smoke testi genelde yakalar.
55
-
56
- ## Mimari kurallar
57
-
58
- **Framework domain bilgisi taşımaz.** `src/` altında hiçbir yerde uygulamaya
59
- özel URL, marka adı, metin ya da veri şekli olmaz. Uygulamaya ait mantık
60
- `hooks` üzerinden gelir (`metadata`, `layoutContext`, `notFound`,
61
- `prewarmPaths`), görünen adlar `brand` üzerinden.
62
-
63
- **Yol hesabı tek yerde.** Hiçbir modül `../..` sayarak dizin bulmaz;
64
- `getConfig().dirs` kullanılır. Framework `node_modules/` içine girdiğinde
65
- göreli yol sayan her satır bozulur.
66
-
67
- **Yapılandırma hatası siteyi düşürmez.** Bozuk bir `jskelet.config.mjs`, hata
68
- veren bir `headers()` ya da fırlatan bir hook uyarı basar ve varsayılana döner.
69
-
70
- **Build çıktısı olmadan da ayağa kalkar.** `asset()` manifest yoksa hash'siz
71
- yola döner, `hasAsset()` false olur ve layout etiketi basmaz. `jskelet build`
72
- unutulduğunda hata değil, stilsiz ama çalışan bir sayfa görülür.
73
-
74
- **Opsiyonel bağımlılıklar sessizce atlanır.** `sharp`, `postcss`,
75
- `@phosphor-icons/core` yoksa ilgili build adımı çalışmaz. Peer bağımlılıklar
76
- **uygulamanın** `node_modules`'ünden çözülmeli: `src/build/resolve-peer.mjs`
77
- içindeki `importFromApp` / `tryImportFromApp` kullanılır, doğrudan `import
78
- "postcss"` yazılmaz.
79
-
80
- **Middleware sırası sözleşmedir.** `src/server/create-app.js` başındaki
81
- numaralı yorum sırayı ve her konumun gerekçesini anlatır. Sıra değiştirmek
82
- sessiz bozulmalara yol açar; değiştiriyorsan yorumu da güncelle.
83
-
84
- **Cache'lenen HTML herkese aynı gider.** Kişiye özel hiçbir şey `route()` ile
85
- render edilen sayfaya girmez. Tema gibi kararlar client'ta, kullanıcıya özel
86
- parçalar ayrı ve `no-store` işaretli fragment uçlarında.
87
-
88
- ## Kod stili
89
-
90
- - **JSDoc zorunlu**: dışa açık her fonksiyonda parametre ve dönüş tipleri.
91
- - **Yorumlar Türkçe** ve *neden*i anlatır. Kodun ne yaptığını tekrar eden yorum
92
- yazma; bir kararın gerekçesini, bir takası ya da bir tuzağı yaz.
93
- - Sunucu ve build tarafı `node:` önekli çekirdek modülleri kullanır.
94
- - `src/client/**` tarayıcıda çalışır: Node API'si, `process` (build sırasında
95
- değiştirilen `clientEnv` dışında) ve senkron ağ yok.
96
- - Yeni bir dışa açık yüzey ekliyorsan `package.json` → `exports` ve
97
- `src/index.js` / `src/client/index.js` barrel'larını güncelle; belgelerde
98
- yalnızca `exports` haritasındaki belirteçler kullanılır (`jskelet`,
99
- `jskelet/client`, `jskelet/html`, `jskelet/tags`).
100
-
101
- ## `.jsk` tuzakları
102
-
103
- - İfade dilinde fonksiyon çağrısı, object/array literal ve atama yok — mantık
104
- controller veya `views/components/*.js` içinde kalır. Layout’ta `asset()` /
105
- `hasAsset()` için yerleşik `<Stylesheets />` / `<BodyScripts />` /
106
- `<JsonLd />` kullan.
107
- - `{#include "partials/x"}` aynı `data` nesnesini geçer; EJS’teki ikinci-argüman
108
- locals yok — veriyi controller’da hazırla.
109
- - `views/components/**` named export’ları PascalCase etiket olur; import yok.
110
- - Kullanıcı verisi `{{ }}` ile kaçar; `{{{ }}}` yalnızca güvendiğin HTML için.
111
- - Legacy EJS hâlâ varsa: `include` async’tir (`forEach` içinde `await` yok);
112
- `<%= %>` / `<%- %>` ayrımına dikkat et; `ejs` opsiyonel peer olarak kurulmalı.
113
-
114
- ## Tailwind
115
-
116
- Sınıf taraması `styles/globals.css` içindeki `@source` direktiflerine bağlıdır
117
- ve otomatik tespit `source(none)` ile kapatılmıştır. Sınıf kullanmaya başladığın
118
- yeni bir dizin varsa oraya bir `@source` satırı eklemek gerekir; yoksa sınıflar
119
- sessizce çıktıdan düşer.
120
-
121
- ## Örnekleri güncel tut
122
-
123
- Framework'ün genel yüzeyini değiştirdiysen (`route()` imzası, hook adları,
124
- config alanları, client API'si) `examples/minimal`, `examples/blog` ve
125
- `examples/dashboard`'i de güncelle. Örnekler belgelerdeki kod parçalarının kaynağı; kaymaları en hızlı
126
- fark edilen yer orası.
127
-
128
- ## Windows notları
129
-
130
- Bu depo Windows üzerinde geliştiriliyor ve iki tuzak tekrar tekrar çıkıyor:
131
-
132
- - `--import` argümanı modül belirteci bekler. `H:\...` gibi mutlak bir yol `h:`
133
- şemalı URL sanılıp reddedilir; `pathToFileURL(...).href` kullan.
134
- - `fs.watch` bir dosya yazıldığında komşuları için de olay üretebiliyor. Dev
135
- sunucusu bu yüzden olayları `mtime` karşılaştırmasıyla eler; watcher mantığını
136
- değiştirirken bu elemeyi kaldırma.
1
+ # AGENTS.md
2
+
3
+ Bu depo **JSkelet** framework'ünün kaynağıdır: Express 5 + build-time `.jsk`
4
+ sunucu render (EJS opsiyonel legacy peer), vanilla JS island'lar, Tailwind v4
5
+ ve süreç belleğinde yaşayan HTML TTL cache. React yok; framework kaynağı düz
6
+ JavaScript + JSDoc. Uygulama client island/entry'leri `.ts` olabilir; paket
7
+ `types/` altında `.d.ts` yayınlar. Sunucu route/hook/config hâlâ Node ESM
8
+ `.js`/`.mjs`.
9
+
10
+ Bir JSkelet **uygulamasında** çalışıyorsan (framework'ün kendisinde değil), aynı
11
+ kuralların uygulama tarafı karşılıkları için [docs/](./docs/README.md) yeterli;
12
+ özellikle 03, 05 ve 07.
13
+
14
+ ## Değişiklik yapmadan önce
15
+
16
+ Framework'ün davranışını değiştiren bir iş alıyorsan ilgili belgeyi oku. Bu
17
+ dosyalar kararların **gerekçelerini** taşıyor ve çoğu "iyileştirme" fikri orada
18
+ zaten tartışılmış:
19
+
20
+ | Dokunacağın yer | Önce oku |
21
+ | --- | --- |
22
+ | `src/server/render.js`, şablonlar | [04-render-ve-sablonlar.md](./docs/04-render-ve-sablonlar.md) |
23
+ | `src/server/html-cache.js`, `route()` | [06-cache.md](./docs/06-cache.md) |
24
+ | `src/server/create-app.js`, middleware | [02-mimari.md](./docs/02-mimari.md) |
25
+ | `src/client/**` | [05-islands.md](./docs/05-islands.md) |
26
+ | `src/build/**` | [08-build.md](./docs/08-build.md) |
27
+ | `src/config/**` | [07-yapilandirma.md](./docs/07-yapilandirma.md) |
28
+ | `src/dev-server.mjs`, `src/server/dev/**` | [09-dev-araclari.md](./docs/09-dev-araclari.md) |
29
+
30
+ Belgeler iki dilde: Türkçesi `docs/`, İngilizcesi `docs/en/` altında ve
31
+ dosyalar birebir eşlenik. Bir belgeyi değiştirdiysen karşılığını da güncelle;
32
+ eksik kalan çeviri kullanıcıya görünür.
33
+
34
+ ## Doğrulama
35
+
36
+ **Lint yeterli, tam build zorunlu değil.**
37
+
38
+ ```bash
39
+ npm run lint
40
+ npm test # desen derleyicisi ve HTML cache için birim testler
41
+ ```
42
+
43
+ Davranış değiştiren bir iş yaptıysan örneklerden biriyle uçtan uca dene:
44
+
45
+ ```bash
46
+ npm --prefix examples/blog install # ilk seferde
47
+ npm --prefix examples/blog run build
48
+ npm --prefix examples/blog run start # ayrı terminalde
49
+ node examples/blog/smoke.mjs
50
+ ```
51
+
52
+ `examples/blog` bilinçli olarak framework'ün her yüzeyini kullanır (dinamik
53
+ route, tüm config bölümleri, fragment, form, prewarm, RSS/sitemap, dört island).
54
+ Bir şeyi bozduysan smoke testi genelde yakalar.
55
+
56
+ ## Mimari kurallar
57
+
58
+ **Framework domain bilgisi taşımaz.** `src/` altında hiçbir yerde uygulamaya
59
+ özel URL, marka adı, metin ya da veri şekli olmaz. Uygulamaya ait mantık
60
+ `hooks` üzerinden gelir (`metadata`, `layoutContext`, `notFound`,
61
+ `prewarmPaths`), görünen adlar `brand` üzerinden.
62
+
63
+ **Yol hesabı tek yerde.** Hiçbir modül `../..` sayarak dizin bulmaz;
64
+ `getConfig().dirs` kullanılır. Framework `node_modules/` içine girdiğinde
65
+ göreli yol sayan her satır bozulur.
66
+
67
+ **Yapılandırma hatası siteyi düşürmez.** Bozuk bir `jskelet.config.mjs`, hata
68
+ veren bir `headers()` ya da fırlatan bir hook uyarı basar ve varsayılana döner.
69
+
70
+ **Build çıktısı olmadan da ayağa kalkar.** `asset()` manifest yoksa hash'siz
71
+ yola döner, `hasAsset()` false olur ve layout etiketi basmaz. `jskelet build`
72
+ unutulduğunda hata değil, stilsiz ama çalışan bir sayfa görülür.
73
+
74
+ **Opsiyonel bağımlılıklar sessizce atlanır.** `sharp`, `postcss`,
75
+ `@phosphor-icons/core` yoksa ilgili build adımı çalışmaz. Peer bağımlılıklar
76
+ **uygulamanın** `node_modules`'ünden çözülmeli: `src/build/resolve-peer.mjs`
77
+ içindeki `importFromApp` / `tryImportFromApp` kullanılır, doğrudan `import
78
+ "postcss"` yazılmaz.
79
+
80
+ **Middleware sırası sözleşmedir.** `src/server/create-app.js` başındaki
81
+ numaralı yorum sırayı ve her konumun gerekçesini anlatır. Sıra değiştirmek
82
+ sessiz bozulmalara yol açar; değiştiriyorsan yorumu da güncelle.
83
+
84
+ **Cache'lenen HTML herkese aynı gider.** Kişiye özel hiçbir şey `route()` ile
85
+ render edilen sayfaya girmez. Tema gibi kararlar client'ta, kullanıcıya özel
86
+ parçalar ayrı ve `no-store` işaretli fragment uçlarında.
87
+
88
+ ## Kod stili
89
+
90
+ - **JSDoc zorunlu**: dışa açık her fonksiyonda parametre ve dönüş tipleri.
91
+ - **Yorumlar Türkçe** ve *neden*i anlatır. Kodun ne yaptığını tekrar eden yorum
92
+ yazma; bir kararın gerekçesini, bir takası ya da bir tuzağı yaz.
93
+ - Sunucu ve build tarafı `node:` önekli çekirdek modülleri kullanır.
94
+ - `src/client/**` tarayıcıda çalışır: Node API'si, `process` (build sırasında
95
+ değiştirilen `clientEnv` dışında) ve senkron ağ yok.
96
+ - Yeni bir dışa açık yüzey ekliyorsan `package.json` → `exports` ve
97
+ `src/index.js` / `src/client/index.js` barrel'larını güncelle; belgelerde
98
+ yalnızca `exports` haritasındaki belirteçler kullanılır (`jskelet`,
99
+ `jskelet/client`, `jskelet/html`, `jskelet/tags`).
100
+
101
+ ## `.jsk` tuzakları
102
+
103
+ - İfade dilinde fonksiyon çağrısı, object/array literal ve atama yok — mantık
104
+ controller veya `views/components/*.js` içinde kalır. Layout’ta `asset()` /
105
+ `hasAsset()` için yerleşik `<Stylesheets />` / `<BodyScripts />` /
106
+ `<JsonLd />` kullan.
107
+ - `{#include "partials/x"}` aynı `data` nesnesini geçer; EJS’teki ikinci-argüman
108
+ locals yok — veriyi controller’da hazırla.
109
+ - `views/components/**` named export’ları PascalCase etiket olur; import yok.
110
+ - Kullanıcı verisi `{{ }}` ile kaçar; `{{{ }}}` yalnızca güvendiğin HTML için.
111
+ - Legacy EJS hâlâ varsa: `include` async’tir (`forEach` içinde `await` yok);
112
+ `<%= %>` / `<%- %>` ayrımına dikkat et; `ejs` opsiyonel peer olarak kurulmalı.
113
+
114
+ ## Tailwind
115
+
116
+ Sınıf taraması `styles/globals.css` içindeki `@source` direktiflerine bağlıdır
117
+ ve otomatik tespit `source(none)` ile kapatılmıştır. Sınıf kullanmaya başladığın
118
+ yeni bir dizin varsa oraya bir `@source` satırı eklemek gerekir; yoksa sınıflar
119
+ sessizce çıktıdan düşer.
120
+
121
+ ## Örnekleri güncel tut
122
+
123
+ Framework'ün genel yüzeyini değiştirdiysen (`route()` imzası, hook adları,
124
+ config alanları, client API'si) `examples/minimal`, `examples/blog` ve
125
+ `examples/dashboard`'i de güncelle. Örnekler belgelerdeki kod parçalarının kaynağı; kaymaları en hızlı
126
+ fark edilen yer orası.
127
+
128
+ ## Windows notları
129
+
130
+ Bu depo Windows üzerinde geliştiriliyor ve iki tuzak tekrar tekrar çıkıyor:
131
+
132
+ - `--import` argümanı modül belirteci bekler. `H:\...` gibi mutlak bir yol `h:`
133
+ şemalı URL sanılıp reddedilir; `pathToFileURL(...).href` kullan.
134
+ - `fs.watch` bir dosya yazıldığında komşuları için de olay üretebiliyor. Dev
135
+ sunucusu bu yüzden olayları `mtime` karşılaştırmasıyla eler; watcher mantığını
136
+ değiştirirken bu elemeyi kaldırma.