jskelet 0.5.5 → 0.6.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 (149) hide show
  1. package/AGENTS.md +18 -13
  2. package/CHANGELOG.md +95 -0
  3. package/README.md +9 -7
  4. package/bin/jskelet.mjs +24 -10
  5. package/docs/01-baslangic.md +4 -3
  6. package/docs/02-mimari.md +4 -3
  7. package/docs/03-routing.md +11 -6
  8. package/docs/04-render-ve-sablonlar.md +35 -43
  9. package/docs/05-islands.md +12 -8
  10. package/docs/07-yapilandirma.md +40 -18
  11. package/docs/08-build.md +15 -9
  12. package/docs/09-dev-araclari.md +5 -1
  13. package/docs/10-dagitim.md +6 -1
  14. package/docs/11-tasima.md +51 -17
  15. package/docs/12-panel-ve-oturum.md +10 -4
  16. package/docs/README.md +7 -5
  17. package/docs/en/01-getting-started.md +4 -3
  18. package/docs/en/02-architecture.md +5 -5
  19. package/docs/en/03-routing.md +12 -7
  20. package/docs/en/04-rendering.md +47 -59
  21. package/docs/en/05-islands.md +13 -8
  22. package/docs/en/07-configuration.md +40 -20
  23. package/docs/en/08-build.md +16 -10
  24. package/docs/en/09-dev-tools.md +6 -1
  25. package/docs/en/10-deployment.md +6 -1
  26. package/docs/en/11-migration.md +51 -16
  27. package/docs/en/12-dashboards-and-sessions.md +9 -4
  28. package/docs/en/README.md +7 -5
  29. package/package.json +49 -14
  30. package/src/build/tasks/client.mjs +91 -10
  31. package/src/build/tasks/icons.mjs +11 -1
  32. package/src/client/index.js +2 -2
  33. package/src/compile/codegen.js +4 -0
  34. package/src/compile/compile-all.js +12 -21
  35. package/src/compile/expr.js +5 -0
  36. package/src/compile/parse.js +64 -8
  37. package/src/compile/resolve.js +3 -0
  38. package/src/config/defaults.js +12 -2
  39. package/src/config/index.js +1 -1
  40. package/src/dev-server.mjs +26 -3
  41. package/src/http/cookies-entry.js +1 -0
  42. package/src/http/cookies.js +18 -0
  43. package/src/logo.png +0 -0
  44. package/src/migrate/apply.mjs +262 -0
  45. package/src/migrate/babel.mjs +79 -0
  46. package/src/migrate/classify.mjs +155 -0
  47. package/src/migrate/config.mjs +126 -0
  48. package/src/migrate/fs-walk.mjs +191 -0
  49. package/src/migrate/parse.mjs +26 -0
  50. package/src/migrate/scan.mjs +177 -0
  51. package/src/migrate/transform/expr-source.mjs +168 -0
  52. package/src/migrate/transform/island.mjs +67 -0
  53. package/src/migrate/transform/jsx-to-component.mjs +302 -0
  54. package/src/migrate/transform/jsx-to-jsk.mjs +330 -0
  55. package/src/migrate/transform/page-split.mjs +435 -0
  56. package/src/migrate/write.mjs +81 -0
  57. package/src/migrate.mjs +171 -0
  58. package/src/server/auth/handoff.js +94 -11
  59. package/src/server/create-app.js +28 -10
  60. package/src/server/ejs-adapter.js +59 -0
  61. package/src/server/image-optimizer.js +94 -26
  62. package/src/server/port-guard.js +255 -0
  63. package/src/server/render.js +27 -9
  64. package/src/server/status-page.js +105 -4
  65. package/src/start.mjs +18 -3
  66. package/src/templates/layout.ejs +8 -28
  67. package/src/templates/layout.jsk +30 -0
  68. package/src/templates/layout.render.js +41 -0
  69. package/src/views/helpers/tags.js +86 -3
  70. package/types/build/resolve-peer.d.mts +13 -0
  71. package/types/client/dom.d.ts +55 -0
  72. package/types/client/form.d.ts +19 -0
  73. package/types/client/index.d.ts +20 -0
  74. package/types/client/registry.d.ts +53 -0
  75. package/types/client/safe-image.d.ts +19 -0
  76. package/types/client/shared-cookie.d.ts +82 -0
  77. package/types/client/store.d.ts +18 -0
  78. package/types/client/swap.d.ts +46 -0
  79. package/types/compile/codegen.d.ts +32 -0
  80. package/types/compile/compile-all.d.ts +42 -0
  81. package/types/compile/errors.d.ts +30 -0
  82. package/types/compile/expr.d.ts +67 -0
  83. package/types/compile/index.d.ts +10 -0
  84. package/types/compile/parse.d.ts +82 -0
  85. package/types/compile/resolve.d.ts +46 -0
  86. package/types/compile/scan-exports.d.ts +9 -0
  87. package/types/config/defaults.d.ts +449 -0
  88. package/types/config/index.d.ts +299 -0
  89. package/types/config/pattern.d.ts +38 -0
  90. package/types/http/control-flow.d.ts +45 -0
  91. package/types/http/cookies-entry.d.ts +5 -0
  92. package/types/http/cookies.d.ts +113 -0
  93. package/types/http/request-cache.d.ts +13 -0
  94. package/types/http/request-context.d.ts +67 -0
  95. package/types/http/shared-cookie.d.ts +73 -0
  96. package/types/index.d.ts +30 -0
  97. package/types/log.d.mts +153 -0
  98. package/types/server/admin/actions.d.ts +16 -0
  99. package/types/server/admin/auth.d.ts +52 -0
  100. package/types/server/admin/event-log.d.ts +38 -0
  101. package/types/server/admin/gate.d.ts +43 -0
  102. package/types/server/admin/inventory.d.ts +40 -0
  103. package/types/server/admin/mount.d.ts +6 -0
  104. package/types/server/admin/router.d.ts +6 -0
  105. package/types/server/admin/snapshot.d.ts +6 -0
  106. package/types/server/assets.d.ts +47 -0
  107. package/types/server/auth/handoff.d.ts +12 -0
  108. package/types/server/cache-deps.d.ts +16 -0
  109. package/types/server/cache-vary.d.ts +30 -0
  110. package/types/server/cloudflare.d.ts +163 -0
  111. package/types/server/create-app.d.ts +25 -0
  112. package/types/server/data-cache.d.ts +116 -0
  113. package/types/server/dev/devtools.d.ts +44 -0
  114. package/types/server/dev/report.d.ts +229 -0
  115. package/types/server/dev/socket.d.ts +17 -0
  116. package/types/server/dev/version-check.d.mts +15 -0
  117. package/types/server/ejs-adapter.d.ts +11 -0
  118. package/types/server/head-hints.d.ts +40 -0
  119. package/types/server/html-cache.d.ts +173 -0
  120. package/types/server/image-optimizer.d.ts +68 -0
  121. package/types/server/logs/access-middleware.d.ts +7 -0
  122. package/types/server/logs/file-sink.d.ts +17 -0
  123. package/types/server/logs/pipeline.d.ts +37 -0
  124. package/types/server/logs/s3-put.d.ts +85 -0
  125. package/types/server/logs/s3-sink.d.ts +26 -0
  126. package/types/server/metadata.d.ts +38 -0
  127. package/types/server/middleware/compression.d.ts +17 -0
  128. package/types/server/middleware/csrf.d.ts +4 -0
  129. package/types/server/middleware/dev-gate.d.ts +2 -0
  130. package/types/server/middleware/headers.d.ts +2 -0
  131. package/types/server/middleware/redirects.d.ts +2 -0
  132. package/types/server/middleware/static-precompressed.d.ts +5 -0
  133. package/types/server/middleware/trailing-slash.d.ts +11 -0
  134. package/types/server/middleware/upstream-proxy.d.ts +21 -0
  135. package/types/server/og-image.d.ts +149 -0
  136. package/types/server/port-guard.d.ts +50 -0
  137. package/types/server/prewarm.d.ts +128 -0
  138. package/types/server/redis.d.ts +163 -0
  139. package/types/server/render.d.ts +101 -0
  140. package/types/server/router.d.ts +5 -0
  141. package/types/server/status-page.d.ts +24 -0
  142. package/types/server/upstream-limiter.d.ts +123 -0
  143. package/types/server/upstream-tracking.d.ts +42 -0
  144. package/types/shared/cookie-domain.d.ts +29 -0
  145. package/types/templates/layout.render.d.ts +7 -0
  146. package/types/version.d.mts +10 -0
  147. package/types/views/components/loader.d.ts +5 -0
  148. package/types/views/helpers/html.d.ts +39 -0
  149. package/types/views/helpers/tags.d.ts +127 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Isıtmanın canlı durumu. Dev araçları bunu okuyup ilerlemeyi gösterir;
3
+ * üretimde kimse okumazsa da maliyeti bir nesnedir.
4
+ */
5
+ export declare const prewarmProgress: {
6
+ active: boolean;
7
+ done: number;
8
+ total: number;
9
+ ok: number;
10
+ failed: number;
11
+ /** @type {number | null} */
12
+ startedAt: number | null;
13
+ /** @type {number | null} */
14
+ finishedAt: number | null;
15
+ /**
16
+ * Denenen her yolun sonucu; dev panelindeki Prewarming sekmesi bunu listeler.
17
+ * @type {{ path: string, status: number, ms: number, bytes: number,
18
+ * cache: string | null, error: string | null }[]}
19
+ */
20
+ entries: {
21
+ path: string;
22
+ status: number;
23
+ ms: number;
24
+ bytes: number;
25
+ cache: string | null;
26
+ error: string | null;
27
+ }[];
28
+ };
29
+ /**
30
+ * İstek ısıtma turunun kendi isteği mi? Yalnızca tur çalışırken ve istek
31
+ * ısıtmanın user-agent'ıyla geldiğinde doğru; gerçek trafiğin hataları her
32
+ * zaman loglanmaya devam eder.
33
+ *
34
+ * @param {{ get?: (name: string) => string | undefined } | null | undefined} req
35
+ * @returns {boolean}
36
+ */
37
+ export declare function isPrewarmRequest(req: {
38
+ get?: (name: string) => string | undefined;
39
+ } | null | undefined): boolean;
40
+ /**
41
+ * Isıtma turuna ait bir uyarıyı loglamak yerine sayar.
42
+ *
43
+ * @param {string} message Gruplama anahtarı; yol adı içermemeli.
44
+ * @returns {boolean} `true` ise sayıldı, çağıran taraf loglamamalı.
45
+ */
46
+ export declare function suppressForPrewarm(message: string): boolean;
47
+ /**
48
+ * Bastırılan bir istek hatasını sayaca ekler. Yığın izi saklanmaz: özet
49
+ * satırının amacı "neyin bozulduğunu" göstermek, hatayı ayıklamak değil.
50
+ *
51
+ * @param {number} status
52
+ * @param {unknown} error
53
+ * @returns {void}
54
+ */
55
+ export declare function notePrewarmError(status: number, error: unknown): void;
56
+ /**
57
+ * Bir turda ısıtılacak dilimi seçer: önce `priority` eşleşenler, sonra
58
+ * kuyruğun sırası gelen parçası. Dışa açık olması bilinçli — sıralama ve
59
+ * rotasyon, tur çalışmadan doğrulanabilen tek davranış.
60
+ *
61
+ * @param {string[]} all
62
+ * @param {number} limit
63
+ * @param {boolean} rotate
64
+ * @returns {string[]}
65
+ */
66
+ export declare function selectPrewarmPaths(all: string[], limit: number, rotate?: boolean): string[];
67
+ /**
68
+ * @param {{ origin: string, quiet?: boolean, paths?: string[] }} options
69
+ * `paths` verilirse hook çağrılmaz, yalnızca o yollar ısıtılır (dev
70
+ * panelindeki "tekrar dene" bunu kullanır).
71
+ * @returns {Promise<{ ok: number, failed: number, total: number, elapsed: number }>}
72
+ */
73
+ export declare function prewarm({ origin, quiet, paths: only }: {
74
+ origin: string;
75
+ quiet?: boolean;
76
+ paths?: string[];
77
+ }): Promise<{
78
+ ok: number;
79
+ failed: number;
80
+ total: number;
81
+ elapsed: number;
82
+ }>;
83
+ /**
84
+ * HTML içindeki aynı-origin `<a href>` yollarını DOM sırasıyla (üstten alta)
85
+ * toplar. Speculation Rules ile aynı muafiyetler: `nofollow`, `_blank`,
86
+ * `data-no-prefetch`, `prewarmSkip`, `navigation.exclude`.
87
+ *
88
+ * @param {string} html
89
+ * @param {{ limit?: number, basePath?: string }} [options]
90
+ * @returns {string[]}
91
+ */
92
+ export declare function extractSameOriginLinks(html: string, options?: {
93
+ limit?: number;
94
+ basePath?: string;
95
+ }): string[];
96
+ /**
97
+ * Ziyaret ısıtması açık mı? `PREWARM=0` her iki modu da keser.
98
+ *
99
+ * @returns {boolean}
100
+ */
101
+ export declare function isOnVisitPrewarm(): boolean;
102
+ /**
103
+ * Yanıt gövdesindeki linkleri soğuksa kuyruğa alır. İstek yolunu bloklamamak
104
+ * için `route()` bunu `queueMicrotask` ile çağırır.
105
+ *
106
+ * @param {string} html
107
+ * @param {{ path: string, req?: { get?: (name: string) => string | undefined,
108
+ * headers?: Record<string, unknown> } }} context
109
+ * @returns {void}
110
+ */
111
+ export declare function noteVisitWarm(html: string, context: {
112
+ path: string;
113
+ req?: {
114
+ get?: (name: string) => string | undefined;
115
+ headers?: Record<string, unknown>;
116
+ };
117
+ }): void;
118
+ /**
119
+ * Açılışta ısıtmayı tetikler. `listen` geri çağrısından çağrılır.
120
+ * `onVisit` modunda klasik zamanlayıcı yok; yine de erken-TTL invalidation
121
+ * drain'i çalışır — soft-bayatlayan sweeper'ın kuyruğu boşalmasın.
122
+ *
123
+ * @param {{ port: number }} options
124
+ * @returns {void}
125
+ */
126
+ export declare function startPrewarm({ port }: {
127
+ port: number;
128
+ }): void;
@@ -0,0 +1,163 @@
1
+ export type RedisConfig = import('../config/index.js').RedisConfig;
2
+ export type CacheEvent = {
3
+ type: string;
4
+ [key: string]: unknown;
5
+ };
6
+ /**
7
+ * Bağlantıyı kurar. `createApp()` config yüklendikten sonra bir kez çağırır.
8
+ *
9
+ * `ioredis` opsiyonel peer bağımlılık ve **uygulamanın** node_modules'ünden
10
+ * çözülür: framework `file:`/workspace bağlantısıyla kuruluysa düz bir
11
+ * `import "ioredis"` framework'ün kendi ağacına bakar.
12
+ *
13
+ * @param {import('../config/index.js').ResolvedConfig} config
14
+ * @returns {Promise<boolean>} Bağlantı kuruldu mu.
15
+ */
16
+ export declare function connectRedis(config: import('../config/index.js').ResolvedConfig): Promise<boolean>;
17
+ /**
18
+ * Önbellek olaylarına abone olur. Önbellek modülleri yükleme anında çağırır;
19
+ * bağlantı sonradan kurulsa da kayıt geçerli kalır.
20
+ *
21
+ * Dinleyici **yalnızca yerel** işi yapmalı: yeniden yayın yapan bir dinleyici
22
+ * iki node arasında sonsuz mesaj döngüsü üretir.
23
+ *
24
+ * @param {(event: CacheEvent) => void} listener
25
+ */
26
+ export declare function onCacheEvent(listener: (event: CacheEvent) => void): void;
27
+ /**
28
+ * Olayı diğer node'lara duyurur. Ateşle-unut: yayın hatası çağıranı
29
+ * etkilemez, yerel invalidation zaten yapıldı.
30
+ *
31
+ * @param {CacheEvent} event
32
+ */
33
+ export declare function publishCacheEvent(event: CacheEvent): void;
34
+ /**
35
+ * Bu tür için paylaşım açık mı. `html`/`data` ayrı ayrı kapatılabiliyor:
36
+ * veri önbelleğini paylaşmak neredeyse her zaman kazançlı, HTML gövdelerini
37
+ * paylaşmak girdi başına yüz kilobayt trafik demek.
38
+ *
39
+ * @param {"html" | "data"} kind
40
+ * @returns {boolean}
41
+ */
42
+ export declare function redisShares(kind: "html" | "data"): boolean;
43
+ /** @returns {boolean} */
44
+ export declare function redisSharesEncoded(): boolean;
45
+ /**
46
+ * @param {"html" | "data"} kind
47
+ * @param {string} key
48
+ * @returns {string}
49
+ */
50
+ export declare function cacheKey(kind: "html" | "data", key: string): string;
51
+ /**
52
+ * @param {string} key
53
+ * @returns {Promise<any | null>} Girdi yoksa, ayrıştırılamıyorsa ya da Redis
54
+ * hata verirse `null` — hepsi "miss" sayılır.
55
+ */
56
+ export declare function redisGetJson(key: string): Promise<any | null>;
57
+ /**
58
+ * Ateşle-unut yazma. İsteğin yanıt yolunda beklenmez: HTML zaten L1'e
59
+ * yazıldı, Redis kopyası yalnızca diğer node'lar için.
60
+ *
61
+ * @param {string} key
62
+ * @param {unknown} value
63
+ * @param {number} ttlMs
64
+ */
65
+ export declare function redisSetJson(key: string, value: unknown, ttlMs: number): void;
66
+ /**
67
+ * @param {string[]} keys
68
+ */
69
+ export declare function redisDrop(keys: string[]): void;
70
+ /**
71
+ * Bir isim alanını tarar ve eşleşen anahtarları düşürür.
72
+ *
73
+ * `KEYS` **kullanılmaz**: tek komutta tüm keyspace'i tarayıp sunucuyu bloklar.
74
+ * `SCAN` kursoru parça parça döner; bu yüzden işlem atomik değil, ama
75
+ * invalidation'ın atomik olması gerekmiyor.
76
+ *
77
+ * @param {"html" | "data"} kind
78
+ * @param {(key: string) => boolean} [match] Anahtarın **önek sonrası** kısmına
79
+ * uygulanır; verilmezse tür altındaki her şey düşer.
80
+ * @returns {Promise<number>} Düşürülen anahtar sayısı.
81
+ */
82
+ export declare function redisDropMatching(kind: "html" | "data", match?: (key: string) => boolean): Promise<number>;
83
+ /**
84
+ * Dev raporu için durum özeti. Bağlantı yoksa da güvenle çağrılabilir.
85
+ *
86
+ * @returns {{ enabled: boolean, connected: boolean, keyPrefix: string,
87
+ * buildId: string, errors: number, bypassed: boolean }}
88
+ */
89
+ export declare function getRedisStatus(): {
90
+ enabled: boolean;
91
+ connected: boolean;
92
+ keyPrefix: string;
93
+ buildId: string;
94
+ errors: number;
95
+ bypassed: boolean;
96
+ };
97
+ /**
98
+ * Bağlantının **nereye** kurulduğu ve hangi ayarlarla çalıştığı.
99
+ *
100
+ * Şifre asla dönmez: bağlantı URL'i `redis://user:pass@host` biçiminde
101
+ * olabiliyor ve panelin işi adresi göstermek, sırrı değil. Ayrıştırılamayan
102
+ * bir URL için adres `"custom"` olur — bozuk bir değer teşhis ucunu
103
+ * düşürmemeli.
104
+ *
105
+ * @returns {{ address: string, secure: boolean, db: string | null,
106
+ * namespace: string, keyPrefix: string, html: boolean, data: boolean,
107
+ * storeEncoded: boolean, events: boolean, commandTimeoutMs: number,
108
+ * subscribed: boolean }}
109
+ */
110
+ export declare function getRedisDetails(): {
111
+ address: string;
112
+ secure: boolean;
113
+ db: string | null;
114
+ namespace: string;
115
+ keyPrefix: string;
116
+ html: boolean;
117
+ data: boolean;
118
+ storeEncoded: boolean;
119
+ events: boolean;
120
+ commandTimeoutMs: number;
121
+ subscribed: boolean;
122
+ };
123
+ /**
124
+ * Paylaşımlı kademede gerçekten **ne durduğunu** sayar: tür başına anahtar
125
+ * sayısı ve sunucunun bildirdiği bellek kullanımı.
126
+ *
127
+ * Ayrı bir çağrı olması gerekiyor. Sayım `SCAN` turu demek ve panelin döküm
128
+ * ucu birkaç saniyede bir yenileniyor; her turda tüm keyspace'i taramak
129
+ * Redis'i teşhis uğruna yormak olurdu. Panel bunu düğmeye basınca çağırır.
130
+ *
131
+ * @returns {Promise<{ ok: boolean, html: number, data: number,
132
+ * usedMemory: string | null, totalKeys: number | null }>}
133
+ */
134
+ export declare function inspectRedis(): Promise<{
135
+ ok: boolean;
136
+ html: number;
137
+ data: number;
138
+ usedMemory: string | null;
139
+ totalKeys: number | null;
140
+ }>;
141
+ /**
142
+ * Bağlantıları kapatır. `SIGTERM` sonrası uçuştaki komutların bitmesi
143
+ * beklenir (`quit`), zorla kesilmez.
144
+ *
145
+ * @returns {Promise<void>}
146
+ */
147
+ export declare function disconnectRedis(): Promise<void>;
148
+ /**
149
+ * Testler için: sahte bir istemci enjekte eder. Gerçek bir Redis'e bağlanmadan
150
+ * serileştirme ve olay yollarının doğrulanabilmesi gerekiyor.
151
+ *
152
+ * @param {any} fake `null` → katman kapatılır.
153
+ * @param {Partial<RedisConfig>} [overrides]
154
+ */
155
+ export declare function setRedisClientForTests(fake: any, overrides?: Partial<RedisConfig>): void;
156
+ /**
157
+ * Testler için: abone kanalından gelmiş gibi olay besler. `originId`
158
+ * verilmezse uzak bir node varsayılır; kendi kimliğini taşıyan bir yayını
159
+ * olduğu gibi geri vermek de mümkün olmalı — eleme testi buna dayanıyor.
160
+ *
161
+ * @param {CacheEvent} event
162
+ */
163
+ export declare function emitRemoteCacheEventForTests(event: CacheEvent): void;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Uygulama geliştirirken bileşen dosyaları değişince kayıt yenilenmeli.
3
+ * Dev sunucusu süreci yeniden başlattığı için normalde gerekmez; gömülü
4
+ * kullanımlar (test, script) için dışa açık.
5
+ *
6
+ * @returns {void}
7
+ */
8
+ export declare function resetRenderEngine(): void;
9
+ /**
10
+ * Layout kullanmadan tek bir şablon render eder. Fragment/partial uçları
11
+ * ve e-posta şablonları bunu kullanır.
12
+ *
13
+ * Öncelik: derlenmiş `.jsk` → `.ejs`. İstek anında şablon derlenmez.
14
+ *
15
+ * @param {string} view `views/` altındaki yol, uzantısız (örn. "pages/home")
16
+ * @param {object} [data]
17
+ * @returns {Promise<string>}
18
+ */
19
+ export declare function renderView(view: string, data?: object): Promise<string>;
20
+ /**
21
+ * Sayfayı layout içinde render eder.
22
+ *
23
+ * @param {{ view: string, data?: object, metadata?: object, head?: string,
24
+ * bodyClass?: string, entries?: string[], styles?: string[],
25
+ * pathname?: string }} page
26
+ * @returns {Promise<string>}
27
+ */
28
+ export declare function renderPage(page: {
29
+ view: string;
30
+ data?: object;
31
+ metadata?: object;
32
+ head?: string;
33
+ bodyClass?: string;
34
+ entries?: string[];
35
+ styles?: string[];
36
+ pathname?: string;
37
+ }): Promise<string>;
38
+ /**
39
+ * Controller'ı çalıştırıp yanıtı yazar; notFound/redirect kontrol akışını,
40
+ * HTML cache'ini ve hata yönetimini üstlenir.
41
+ *
42
+ * `private: true` kişiye özel sayfaları public cache yolundan tamamen ayırır:
43
+ * HTML cache devre dışı kalır, config'in `cache.html` deseni bu kararı
44
+ * ezemez, yanıt `no-store` ile ve ETag'siz gider. Dashboard tipi sayfalarda
45
+ * bu bayrak olmadan çalışmak, bir kullanıcının HTML'inin bir başkasına
46
+ * servis edilmesi anlamına gelir.
47
+ *
48
+ * @param {(ctx: { params: object, query: object, pathname: string,
49
+ * req: import('express').Request }) => Promise<object>} controller
50
+ * @param {{ revalidate?: number, private?: boolean }} [options]
51
+ * @returns {import('express').RequestHandler}
52
+ */
53
+ export declare function route(controller: (ctx: {
54
+ params: object;
55
+ query: object;
56
+ pathname: string;
57
+ req: import('express').Request;
58
+ }) => Promise<object>, options?: {
59
+ revalidate?: number;
60
+ private?: boolean;
61
+ }): import('express').RequestHandler;
62
+ /**
63
+ * Layout'suz, asla cache'lenmeyen parça yanıtı.
64
+ *
65
+ * Fragment uçları (tablo sayfası, sekme paneli, canlı tazelenen kart) her
66
+ * projede elle yazılıyor ve `no-store` yazmayı unutmak sessiz bir sızıntıya
67
+ * dönüşüyor. Burada politika sabit: HTML cache'e hiç uğramaz, `no-store` ile
68
+ * ve ETag'siz gider.
69
+ *
70
+ * Hata durumunda tüm sayfa yerine küçük bir hata parçası döner: takas edilen
71
+ * bölge bir hata sayfasının tamamını içine almasın.
72
+ *
73
+ * @param {(ctx: { params: object, query: object, pathname: string,
74
+ * req: import('express').Request }) => Promise<{ view: string, data?: object,
75
+ * status?: number } | string>} controller
76
+ * @returns {import('express').RequestHandler}
77
+ */
78
+ export declare function fragment(controller: (ctx: {
79
+ params: object;
80
+ query: object;
81
+ pathname: string;
82
+ req: import('express').Request;
83
+ }) => Promise<{
84
+ view: string;
85
+ data?: object;
86
+ status?: number;
87
+ } | string>): import('express').RequestHandler;
88
+ export type Produced = {
89
+ html: string;
90
+ status: number;
91
+ degraded?: boolean;
92
+ storable?: boolean;
93
+ retryAfter?: number;
94
+ };
95
+ /**
96
+ * 404 sayfası. `renderStatusPage(404)` için kısayol; route dosyalarında en sık
97
+ * ihtiyaç duyulan durum bu olduğu için ayrı bir ad taşımaya devam ediyor.
98
+ *
99
+ * @returns {Promise<string>}
100
+ */
101
+ export declare function renderNotFound(): Promise<string>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @param {import('express').Express} app
3
+ * @returns {Promise<number>} Bağlanan modül sayısı.
4
+ */
5
+ export declare function registerRoutes(app: import('express').Express): Promise<number>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Durum koduna karşılık gelen sayfayı üretir. Hiçbir koşulda fırlatmaz:
3
+ * hata sayfasının kendisi patlarsa ziyaretçi boş yanıt görür, bu yüzden her
4
+ * başarısızlık gömülü HTML'e düşer.
5
+ *
6
+ * Development'ta 5xx yanıtları `hooks.error` ve gömülü 500 sayfasını atlar;
7
+ * yığın izini içeren bir teşhis sayfası döner. Production'da ayrıntı
8
+ * gösterilmez — sunucu içi ziyaretçiye açılmaz.
9
+ *
10
+ * @param {number} status
11
+ * @param {{ error?: unknown }} [options]
12
+ * @returns {Promise<string>}
13
+ */
14
+ export declare function renderStatusPage(status: number, options?: {
15
+ error?: unknown;
16
+ }): Promise<string>;
17
+ /**
18
+ * Bir hatadan HTTP durum kodu çıkarır. Uygulama kodu `error.statusCode` ya da
19
+ * `error.status` ile kendi kodunu bildirebilir; tanınmayan her şey 500'dür.
20
+ *
21
+ * @param {unknown} error
22
+ * @returns {number}
23
+ */
24
+ export declare function statusFromError(error: unknown): number;
@@ -0,0 +1,123 @@
1
+ export type HostState = {
2
+ host: string;
3
+ /**
4
+ * Config'te verilen tavan; AIMD bunun üstüne çıkmaz.
5
+ */
6
+ maxRate: number;
7
+ /**
8
+ * Azalmanın dibi; 0'a inip tamamen kilitlenmesin.
9
+ */
10
+ minRate: number;
11
+ /**
12
+ * Saniyedeki izin — AIMD bunu oynatır.
13
+ */
14
+ rate: number;
15
+ /**
16
+ * Kovanın boyu: kısa patlamalara verilen tolerans.
17
+ */
18
+ burst: number;
19
+ /**
20
+ * Aynı anda uçabilecek çağrı sayısı.
21
+ */
22
+ concurrency: number;
23
+ tokens: number;
24
+ refilledAt: number;
25
+ /**
26
+ * Uçuştaki çağrı.
27
+ */
28
+ active: number;
29
+ /**
30
+ * Boş yuva bekleyenler.
31
+ */
32
+ waiters: (() => void)[];
33
+ /**
34
+ * Admission sırası (FIFO).
35
+ */
36
+ chain: Promise<void>;
37
+ /**
38
+ * `Retry-After` boyunca kova tamamen durur.
39
+ */
40
+ blockedUntil: number;
41
+ consecutiveFailures: number;
42
+ /**
43
+ * Devre kesicinin açık kaldığı an.
44
+ */
45
+ bypassUntil: number;
46
+ /**
47
+ * Son AIMD kararının zamanı.
48
+ */
49
+ adjustedAt: number;
50
+ /**
51
+ * Kaç kez 429/503 görüldü (teşhis için).
52
+ */
53
+ throttled: number;
54
+ /**
55
+ * Devre kesici kaç çağrıyı hiç göndermedi.
56
+ */
57
+ rejected: number;
58
+ };
59
+ /**
60
+ * `createApp()` config yüklendikten sonra bir kez çağırır. Ayar değiştiğinde
61
+ * host durumları sıfırlanır: eski `maxRate`'e göre ayarlanmış bir `rate`
62
+ * yeni tavanın üstünde kalabilir.
63
+ *
64
+ * @param {Record<string, unknown> | undefined} config `cache().upstream`
65
+ * @returns {void}
66
+ */
67
+ export declare function configureUpstreamLimiter(config: Record<string, unknown> | undefined): void;
68
+ /**
69
+ * Çağrı için izin alır. `null` dönerse fren kapalı ya da host çözülemedi;
70
+ * `blocked` dönerse devre kesici açık ve çağrı hiç yapılmamalı.
71
+ *
72
+ * @param {string} url
73
+ * @returns {Promise<{ blocked: boolean, host: string, release: () => void } | null>}
74
+ */
75
+ export declare function limitUpstream(url: string): Promise<{
76
+ blocked: boolean;
77
+ host: string;
78
+ release: () => void;
79
+ } | null>;
80
+ /**
81
+ * Yanıtın hıza etkisini işler. 429/503 hızı yarıya indirir ve `Retry-After`
82
+ * varsa kovayı o süre boyunca tamamen durdurur; başarı sayaçları sıfırlar.
83
+ *
84
+ * @param {string} host
85
+ * @param {number} status `0` → ağ hatası (yanıt gelmedi).
86
+ * @param {string | null} [retryAfter] `Retry-After` başlığı.
87
+ * @returns {void}
88
+ */
89
+ export declare function noteUpstreamResponse(host: string, status: number, retryAfter?: string | null): void;
90
+ /**
91
+ * Dev paneli ve teşhis için host başına durum. Fren kapalıysa boş dizi.
92
+ *
93
+ * @returns {{ host: string, rate: number, maxRate: number, concurrency: number,
94
+ * active: number, throttled: number, rejected: number, bypassed: boolean,
95
+ * blockedMs: number, bypassedMs: number }[]}
96
+ */
97
+ export declare function getUpstreamLimiterStatus(): {
98
+ host: string;
99
+ rate: number;
100
+ maxRate: number;
101
+ concurrency: number;
102
+ active: number;
103
+ throttled: number;
104
+ rejected: number;
105
+ bypassed: boolean;
106
+ blockedMs: number;
107
+ bypassedMs: number;
108
+ }[];
109
+ /**
110
+ * Freni bekleten en uzun süre. Isıtma turunun tekrar denemesi bunu kullanıyor:
111
+ * sabit bir bekleme, kesici 10 saniye açıkken 2 saniye sonra tekrar denemek
112
+ * demekti — yani aynı 429'u peşin peşin almak.
113
+ *
114
+ * @returns {number} ms; fren kapalıysa ya da bekleyen bir şey yoksa 0.
115
+ */
116
+ export declare function upstreamCooldownMs(): number;
117
+ /**
118
+ * Testler için: ayarları verip tüm host durumlarını sıfırlar.
119
+ *
120
+ * @param {Record<string, unknown>} [config]
121
+ * @returns {void}
122
+ */
123
+ export declare function resetUpstreamLimiterForTests(config?: Record<string, unknown>): void;
@@ -0,0 +1,42 @@
1
+ export type UpstreamFailure = {
2
+ status: number;
3
+ path: string;
4
+ };
5
+ /**
6
+ * @param {UpstreamFailure} failure
7
+ * @returns {void}
8
+ */
9
+ export declare function reportUpstreamFailure(failure: UpstreamFailure): void;
10
+ /**
11
+ * @param {number} status
12
+ * @returns {boolean}
13
+ */
14
+ export declare function isTransientStatus(status: number): boolean;
15
+ /**
16
+ * `globalThis.fetch`i sarıp **geçici** upstream hatalarını kendiliğinden
17
+ * bildirir.
18
+ *
19
+ * Gerekçesi pratik: `reportUpstreamFailure()` sözleşmesi uygulamanın HTTP
20
+ * istemcisine bir satır eklemeyi gerektiriyor ve o satır yazılmadığında
21
+ * framework rate limit'i hiç göremiyor — veri gelmediği için `notFound()`
22
+ * çağıran sayfa 404 olarak servis ediliyordu. Otomatik izleme bu bilgiyi
23
+ * varsayılan hâle getirir; elle çağrı hâlâ geçerli ve tekilleştirilir.
24
+ *
25
+ * Yalnızca geçici durumlar bildirilir. `404`/`403` gibi deterministik
26
+ * cevaplar birçok API'de "böyle bir kayıt yok" anlamına geliyor ve onları
27
+ * otomatik olarak "eksik veri" saymak her sayfada yanlış uyarı üretirdi.
28
+ *
29
+ * Kendi sunucumuza yapılan istekler atlanır: ısıtma turu ve sağlık kontrolü
30
+ * upstream değil.
31
+ *
32
+ * @returns {void}
33
+ */
34
+ export declare function trackUpstreamFetch(): void;
35
+ /**
36
+ * @param {() => T} run
37
+ * @returns {T}
38
+ * @template T
39
+ */
40
+ export declare function withUpstreamTracking<T>(run: () => T): T;
41
+ /** @returns {UpstreamFailure[]} */
42
+ export declare function getUpstreamFailures(): UpstreamFailure[];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Paylaşımlı cookie Domain seçimi — sunucu ve istemci aynı kuralları kullanır.
3
+ *
4
+ * `brand.sharedCookieRoots` örn. `[".investvio.com", ".localhost"]`.
5
+ * Host bu köklerden birine uyuyorsa Domain olarak o kök yazılır.
6
+ */
7
+ /**
8
+ * @param {string} host Host veya Host:port.
9
+ * @returns {string} Lowercase, portsuz.
10
+ */
11
+ export declare function stripHostPort(host: string): string;
12
+ /**
13
+ * Kökü `Domain=` biçimine getirir (başında nokta).
14
+ *
15
+ * @param {unknown} root
16
+ * @returns {string | null}
17
+ */
18
+ export declare function normalizeCookieRoot(root: unknown): string | null;
19
+ /**
20
+ * @param {string} hostname Portsuz hostname.
21
+ * @param {Iterable<string>} roots `brand.sharedCookieRoots`.
22
+ * @returns {string | null} `Domain` değeri (başında nokta) ya da eşleşme yoksa null.
23
+ */
24
+ export declare function resolveSharedCookieDomain(hostname: string, roots: Iterable<string>): string | null;
25
+ /**
26
+ * Paylaşımlı cookie için önerilen üst sınır. JWT / büyük token buraya
27
+ * sığmaz — kısa session id koyun; aksi halde handoff veya host-only cookie.
28
+ */
29
+ export declare const SHARED_COOKIE_WARN_BYTES = 512;
@@ -0,0 +1,7 @@
1
+ /** @generated by scripts/compile-framework-layout.mjs — do not edit */
2
+ /**
3
+ * @param {Record<string, unknown>} data
4
+ * @param {Record<string, any>} helpers
5
+ * @returns {string}
6
+ */
7
+ export declare function render(data: Record<string, unknown>, helpers: Record<string, any>): string;
@@ -0,0 +1,10 @@
1
+ /** @type {string} */
2
+ export declare const FRAMEWORK_VERSION: string;
3
+ /** Paket adı: sürüm kontrolü hangi kayıt defteri girdisine bakacağını buradan bilir. */
4
+ export declare const FRAMEWORK_PACKAGE: any;
5
+ /** Künye alanları: yönetim panelinin footer'ı bunları basıyor. */
6
+ export declare const FRAMEWORK_LICENSE: any;
7
+ /** @type {string} */
8
+ export declare const FRAMEWORK_NODE_RANGE: string;
9
+ /** @type {string} */
10
+ export declare const FRAMEWORK_HOMEPAGE: string;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @param {string | string[]} dirs Tek dizin veya çoklu kök (feature/shared).
3
+ * @returns {Promise<Record<string, unknown>>}
4
+ */
5
+ export declare function loadComponents(dirs: string | string[]): Promise<Record<string, unknown>>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Metin içeriği ve attribute değerleri için kaçış.
3
+ * @param {unknown} value
4
+ * @returns {string}
5
+ */
6
+ export declare function esc(value: unknown): string;
7
+ /**
8
+ * `<script type="application/ld+json">` gövdesi için güvenli JSON.
9
+ * `</script`, `<!--` ve U+2028/2029 kaçırılır.
10
+ * @param {unknown} value
11
+ * @returns {string}
12
+ */
13
+ export declare function jsonScript(value: unknown): string;
14
+ /**
15
+ * Attribute nesnesini string'e çevirir. `false`/`null`/`undefined` atlanır,
16
+ * `true` boolean attribute olarak yazılır.
17
+ * @param {Record<string, unknown>} attrs
18
+ * @returns {string}
19
+ */
20
+ export declare function attrs(attrs: Record<string, unknown>): string;
21
+ /**
22
+ * `clsx` karşılığı — koşullu sınıf birleştirme, çakışma çözümü yok.
23
+ * @param {...unknown} inputs
24
+ * @returns {string}
25
+ */
26
+ export declare function cx(...inputs: unknown[]): string;
27
+ /**
28
+ * `lib/ui/cn.js` ile aynı davranış: birleştir, sonra Tailwind çakışmalarını çöz.
29
+ *
30
+ * `tailwind-merge` çalışma zamanı bağımlılığı olarak korunur çünkü sınıf
31
+ * hesabı **yalnızca sunucuda** yapılır — client bundle'a hiç girmez, dolayısıyla
32
+ * sayfa ağırlığına etkisi yoktur. Elle yazılmış bir grup tablosu ise
33
+ * `border-2` + `border-transparent` gibi genişlik/renk çiftlerini birbirine
34
+ * karıştırıp sınıf düşürdüğü için görsel regresyon üretiyordu.
35
+ *
36
+ * @param {...unknown} inputs
37
+ * @returns {string}
38
+ */
39
+ export declare function cn(...inputs: unknown[]): string;