jskelet 0.5.4 → 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 +387 -385
  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 +53 -25
  11. package/docs/08-build.md +40 -18
  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 +55 -27
  23. package/docs/en/08-build.md +43 -21
  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 +152 -18
  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 +31 -3
  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
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * `next/link`, `next/image` ve `@phosphor-icons/react` karşılıkları.
3
- * Hepsi HTML string döndürür; EJS içinden `<%- %>` ile basılır.
3
+ * Hepsi HTML string döndürür; şablonlarda PascalCase etiket veya
4
+ * (legacy EJS) `<%- %>` ile basılır.
4
5
  */
5
- import { attrs, esc, cn } from "./html.js";
6
- import { asset, getSpriteIds, optimizedImage } from "../../server/assets.js";
6
+ import { attrs, esc, cn, jsonScript } from "./html.js";
7
+ import {
8
+ asset,
9
+ hasAsset,
10
+ getSpriteIds,
11
+ optimizedImage,
12
+ } from "../../server/assets.js";
7
13
  import {
8
14
  parseAllowedRemoteUrl,
9
15
  remoteImageUrl,
@@ -290,3 +296,80 @@ export function toKebab(name) {
290
296
  .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
291
297
  .toLowerCase();
292
298
  }
299
+
300
+ /**
301
+ * Layout `<head>` stylesheet'leri. `hasAsset` false olanları basmaz —
302
+ * build yokken 404 link'i istememek için. `.jsk` ifade dilinde `asset()` /
303
+ * `hasAsset()` çağrılamadığı için layout bu etiketi kullanır.
304
+ *
305
+ * @param {{ styles?: string[] }} [props]
306
+ * @returns {string}
307
+ */
308
+ export function stylesheets(props = {}) {
309
+ const styles = Array.isArray(props.styles) ? props.styles : [];
310
+ /** @type {string[]} */
311
+ const parts = [];
312
+
313
+ if (hasAsset("app.css")) {
314
+ parts.push(
315
+ `<link rel="stylesheet" href="${esc(asset("app.css"))}" data-jskelet-css="app.css">`,
316
+ );
317
+ }
318
+
319
+ for (const sheet of styles) {
320
+ if (!sheet || !hasAsset(sheet)) continue;
321
+ parts.push(
322
+ `<link rel="stylesheet" href="${esc(asset(sheet))}" data-jskelet-css="${esc(sheet)}">`,
323
+ );
324
+ }
325
+
326
+ return parts.join("\n ");
327
+ }
328
+
329
+ /**
330
+ * Layout gövde sonu script'leri: `main.js`, controller `entries`, isteğe
331
+ * bağlı dev overlay.
332
+ *
333
+ * @param {{ entries?: string[], devtools?: boolean, devBasePath?: string }} [props]
334
+ * @returns {string}
335
+ */
336
+ export function bodyScripts(props = {}) {
337
+ const entries = Array.isArray(props.entries) ? props.entries : [];
338
+ const devBasePath = props.devBasePath ?? "/__jskelet/dev";
339
+ /** @type {string[]} */
340
+ const parts = [];
341
+
342
+ if (hasAsset("main.js")) {
343
+ parts.push(`<script type="module" src="${esc(asset("main.js"))}"></script>`);
344
+ }
345
+
346
+ for (const entry of entries) {
347
+ if (!entry) continue;
348
+ parts.push(`<script type="module" src="${esc(asset(entry))}"></script>`);
349
+ }
350
+
351
+ if (props.devtools) {
352
+ parts.push(
353
+ `<script type="module" src="${esc(devBasePath)}/overlay.js"></script>`,
354
+ );
355
+ }
356
+
357
+ return parts.join("\n ");
358
+ }
359
+
360
+ /**
361
+ * JSON-LD script etiketleri. `structuredData` dizisindeki her öğe için bir
362
+ * `<script type="application/ld+json">`.
363
+ *
364
+ * @param {{ items?: unknown[] }} [props]
365
+ * @returns {string}
366
+ */
367
+ export function jsonLd(props = {}) {
368
+ const items = Array.isArray(props.items) ? props.items : [];
369
+ return items
370
+ .map(
371
+ (item) =>
372
+ `<script type="application/ld+json">${jsonScript(item)}</script>`,
373
+ )
374
+ .join("\n ");
375
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @param {string} root Uygulama kökü.
3
+ * @param {string} specifier
4
+ * @returns {Promise<any>}
5
+ * @throws Paket bulunamazsa; zorunlu bağımlılıklar için.
6
+ */
7
+ export declare function importFromApp(root: string, specifier: string): Promise<any>;
8
+ /**
9
+ * @param {string} root
10
+ * @param {string} specifier
11
+ * @returns {Promise<any | null>} Paket yoksa `null`; adım atlanabilsin diye.
12
+ */
13
+ export declare function tryImportFromApp(root: string, specifier: string): Promise<any | null>;
@@ -0,0 +1,55 @@
1
+ /** Island'ların paylaştığı küçük DOM yardımcıları. */
2
+ /**
3
+ * @param {ParentNode} root
4
+ * @param {string} selector
5
+ * @returns {HTMLElement | null}
6
+ */
7
+ export declare function qs(root: ParentNode, selector: string): HTMLElement | null;
8
+ /**
9
+ * @param {ParentNode} root
10
+ * @param {string} selector
11
+ * @returns {HTMLElement[]}
12
+ */
13
+ export declare function qsa(root: ParentNode, selector: string): HTMLElement[];
14
+ /**
15
+ * Otomatik temizlenebilir listener.
16
+ * @param {EventTarget} target
17
+ * @param {string} type
18
+ * @param {EventListenerOrEventListenerObject} handler
19
+ * @param {AddEventListenerOptions | boolean} [options]
20
+ * @returns {() => void}
21
+ */
22
+ export declare function on(target: EventTarget, type: string, handler: EventListenerOrEventListenerObject, options?: AddEventListenerOptions | boolean): () => void;
23
+ /**
24
+ * `data-*` üzerinden delege edilmiş click.
25
+ * @param {HTMLElement} root
26
+ * @param {string} selector
27
+ * @param {(event: MouseEvent, target: HTMLElement) => void} handler
28
+ * @returns {() => void}
29
+ */
30
+ export declare function onClick(root: HTMLElement, selector: string, handler: (event: MouseEvent, target: HTMLElement) => void): () => void;
31
+ /**
32
+ * @param {number} ms
33
+ * @param {(...args: any[]) => void} fn
34
+ * @returns {(...args: any[]) => void}
35
+ */
36
+ export declare function debounce(ms: number, fn: (...args: any[]) => void): (...args: any[]) => void;
37
+ /**
38
+ * requestAnimationFrame ile birleştirilmiş çağrı.
39
+ * @param {() => void} fn
40
+ * @returns {() => void}
41
+ */
42
+ export declare function raf(fn: () => void): () => void;
43
+ /**
44
+ * @param {HTMLElement} element
45
+ * @param {string} name
46
+ * @param {boolean} active
47
+ */
48
+ export declare function toggleClass(element: HTMLElement, name: string, active: boolean): void;
49
+ /**
50
+ * Overlay portal hedefi: layout'ta `<div id="jskelet-overlays">` varsa
51
+ * modal/drawer içeriği oraya taşınır, yoksa `body`ye. Portal, `overflow`
52
+ * ya da `transform` taşıyan bir ata elementin `position: fixed` overlay'i
53
+ * kırpmasını engeller.
54
+ */
55
+ export declare function getOverlayRoot(): HTMLElement;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Tek bir formu bağlar.
3
+ *
4
+ * `data-target` verilirse başarılı yanıtın gövdesi o bölgeye takılır; yoksa
5
+ * yanıt formun kendisini değiştirir (doğrulama hatalarının geldiği yol).
6
+ *
7
+ * @param {HTMLFormElement} form
8
+ * @returns {() => void} Dinleyiciyi söken fonksiyon.
9
+ */
10
+ export declare function enhanceForm(form: HTMLFormElement): () => void;
11
+ /**
12
+ * `data-enhance` taşıyan formları tek bir delege dinleyiciyle bağlar.
13
+ * `submit` olayı köpürdüğü için sonradan DOM'a giren (fragment ile gelen)
14
+ * formlar da kapsanır ve her takastan sonra yeniden bağlama gerekmez.
15
+ *
16
+ * @param {ParentNode} [root]
17
+ * @returns {() => void}
18
+ */
19
+ export declare function startForms(root?: ParentNode): () => void;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * JSkelet island runtime'ının tarayıcı tarafı API'si.
3
+ *
4
+ * `client/entries/main.js` (veya `main.ts`) içinde:
5
+ *
6
+ * import { registerAll, start } from "jskelet/client";
7
+ *
8
+ * registerAll({
9
+ * counter: () => import("../islands/counter.ts"),
10
+ * });
11
+ *
12
+ * start();
13
+ */
14
+ export { register, registerAll, hydrate, unmount, observeDocument, start, } from "./registry.js";
15
+ export { swap, startSwapLinks } from "./swap.js";
16
+ export { enhanceForm, startForms } from "./form.js";
17
+ export { createStore } from "./store.js";
18
+ export { debounce, on, onClick, qs, qsa, raf, toggleClass, getOverlayRoot, } from "./dom.js";
19
+ export { startSafeImages } from "./safe-image.js";
20
+ export { clearSharedCookie, consumeWindowNameHandoff, createHandoffUrl, handoffViaWindowName, readCookie, resolveSharedCookieDomain, SHARED_COOKIE_WARN_BYTES, writeSharedCookie, } from "./shared-cookie.js";
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Island registry.
3
+ *
4
+ * Sunucu HTML'i tamdır; JS yalnızca davranış ekler. Bir element
5
+ * `data-island="ad"` taşıdığında ilgili modül dinamik import edilir ve
6
+ * `mount(element, props)` çağrılır.
7
+ *
8
+ * Hidrasyon **varsayılan olarak görünürlüğe bağlıdır**: her island bir
9
+ * IntersectionObserver'a verilir, ekranda olanlar zaten ilk gözlemde tetiklenir,
10
+ * ekran dışındakiler kaydırılana kadar hiç indirilmez. Ana sayfadaki grafik
11
+ * kütüphanesi gibi ağır modüller böylece ilk yükten tamamen çıkar.
12
+ *
13
+ * `data-island-eager` görünürlükten bağımsız, hemen bağlanmayı zorlar
14
+ * (header, çerez bandı gibi global davranışlar için).
15
+ *
16
+ * `data-island-idle` görünür olsa bile sayfa sakinleşene (load + boş zaman)
17
+ * kadar bekletir. İlk ekranda görünen ama kritik olmayan ağır modüller
18
+ * (ör. grafik kütüphanesi çeken mini grafik) LCP ile yarışmasın diye.
19
+ *
20
+ * `data-island-props` JSON ise parse edilip props olarak geçer.
21
+ */
22
+ export type MountFn = (element: HTMLElement, props: object) => void | (() => void);
23
+ /**
24
+ * @param {string} name
25
+ * @param {() => Promise<{ mount: MountFn }>} loader
26
+ */
27
+ export declare function register(name: string, loader: () => Promise<{
28
+ mount: MountFn;
29
+ }>): void;
30
+ /** @param {Record<string, () => Promise<{ mount: MountFn }>>} entries */
31
+ export declare function registerAll(entries: Record<string, () => Promise<{
32
+ mount: MountFn;
33
+ }>>): void;
34
+ /**
35
+ * Bir alt ağaçtaki island'ları söker.
36
+ *
37
+ * Fragment takasında çağrılması zorunlu: `innerHTML` ile değiştirilen bir
38
+ * bölgenin island'ları DOM'dan çıkar ama `document`/`window` üzerine
39
+ * kurdukları dinleyiciler ve `setInterval`'ları yaşamaya devam eder. Birkaç
40
+ * takastan sonra aynı olay birden fazla kez işlenmeye başlar.
41
+ *
42
+ * Sökülen element yeniden bağlanabilir hâle gelir: `mounted` kaydı da
43
+ * temizlenir, böylece aynı düğüm tekrar DOM'a girerse `hydrate()` onu
44
+ * yeniden görür.
45
+ *
46
+ * @param {ParentNode} [root] Kökün kendisi de island olabilir.
47
+ */
48
+ export declare function unmount(root?: ParentNode): void;
49
+ /** @param {ParentNode} [root] */
50
+ export declare function hydrate(root?: ParentNode): void;
51
+ /** Sonradan DOM'a eklenen island'ları da yakalar (infinite scroll, portal). */
52
+ export declare function observeDocument(): MutationObserver;
53
+ export declare function start(): void;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Yüklenemeyen görseller için tek bir belge dinleyicisi.
3
+ *
4
+ * Bu iş bilinçli olarak **island değil**. Görsel ağırlıklı bir sayfada 80+
5
+ * `<img>` olabiliyor ve her birine ayrı island bağlamak (gözlemci + dinamik
6
+ * import + mount) sırf hata ihtimali için ciddi bir hidrasyon yükü. `error`
7
+ * olayı kabarmaz ama yakalama fazında görülebilir, bu yüzden tek dinleyici
8
+ * hepsini karşılar ve sonradan DOM'a eklenen görseller de kendiliğinden
9
+ * kapsanır.
10
+ *
11
+ * Kullanım: görsele `data-safe-image` ekleyin. Kendi hata görünümünüzü
12
+ * vermek için görseli `data-safe-image-host` taşıyan bir sarmalayıcıya alın
13
+ * ve içine `<template data-safe-image-fallback>` koyun — framework hiçbir
14
+ * stil dayatmaz, yalnızca değiştirme işini yapar.
15
+ */
16
+ /**
17
+ * @returns {void}
18
+ */
19
+ export declare function startSafeImages(): void;
@@ -0,0 +1,82 @@
1
+ export { SHARED_COOKIE_WARN_BYTES, resolveSharedCookieDomain, stripHostPort, } from "../shared/cookie-domain.js";
2
+ /**
3
+ * @param {string} name
4
+ * @returns {string | null}
5
+ */
6
+ export declare function readCookie(name: string): string | null;
7
+ export type ClientSharedCookieResult = {
8
+ ok: boolean;
9
+ domain: string | null;
10
+ handoff: boolean;
11
+ reason?: string;
12
+ };
13
+ /**
14
+ * @typedef {object} ClientSharedCookieResult
15
+ * @property {boolean} ok
16
+ * @property {string | null} domain
17
+ * @property {boolean} handoff
18
+ * @property {string} [reason]
19
+ */
20
+ /**
21
+ * @param {string} name
22
+ * @param {string} value
23
+ * @param {{ roots?: string[], maxAge?: number, path?: string, sameSite?: string,
24
+ * secure?: boolean }} [options]
25
+ * @returns {ClientSharedCookieResult}
26
+ */
27
+ export declare function writeSharedCookie(name: string, value: string, options?: {
28
+ roots?: string[];
29
+ maxAge?: number;
30
+ path?: string;
31
+ sameSite?: string;
32
+ secure?: boolean;
33
+ }): ClientSharedCookieResult;
34
+ /**
35
+ * @param {string} name
36
+ * @param {{ roots?: string[], path?: string, secure?: boolean, sameSite?: string }} [options]
37
+ * @returns {ClientSharedCookieResult}
38
+ */
39
+ export declare function clearSharedCookie(name: string, options?: {
40
+ roots?: string[];
41
+ path?: string;
42
+ secure?: boolean;
43
+ sameSite?: string;
44
+ }): ClientSharedCookieResult;
45
+ /**
46
+ * Handoff bileti ister; dönen URL'ye gidilir (`?handoff=` taşır).
47
+ *
48
+ * @param {{ name: string, value: string, next: string }} body
49
+ * @param {{ path?: string }} [options]
50
+ * @returns {Promise<string | null>}
51
+ */
52
+ export declare function createHandoffUrl(body: {
53
+ name: string;
54
+ value: string;
55
+ next: string;
56
+ }, options?: {
57
+ path?: string;
58
+ }): Promise<string | null>;
59
+ /**
60
+ * first-party `window.name` köprüsü — cookie Domain reddedilince yedek.
61
+ * Kaynak sayfada hedefe gitmeden önce çağırın; hedefte
62
+ * `consumeWindowNameHandoff` okur.
63
+ *
64
+ * @param {string} targetUrl
65
+ * @param {{ name: string, value: string, maxAge?: number }} cookie
66
+ * @returns {void}
67
+ */
68
+ export declare function handoffViaWindowName(targetUrl: string, cookie: {
69
+ name: string;
70
+ value: string;
71
+ maxAge?: number;
72
+ }): void;
73
+ /**
74
+ * Hedef host'ta `window.name` içindeki handoff'u host-only cookie olarak yazar.
75
+ *
76
+ * @param {{ write?: typeof writeSharedCookie }} [options]
77
+ * Varsayılan: Domain denemeden host-only `document.cookie`.
78
+ * @returns {boolean} Bir şey yazıldı mı.
79
+ */
80
+ export declare function consumeWindowNameHandoff(options?: {
81
+ write?: typeof writeSharedCookie;
82
+ }): boolean;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * React Context yerine kullanılan minimal pub/sub store.
3
+ * `useSyncExternalStore` köprüsünün yerini alır: doğrudan `subscribe`.
4
+ */
5
+ /**
6
+ * @param {T} initial
7
+ * @returns {{
8
+ * get: () => T,
9
+ * set: (next: T | ((prev: T) => T)) => void,
10
+ * subscribe: (listener: (value: T) => void) => () => void,
11
+ * }}
12
+ * @template T
13
+ */
14
+ export declare function createStore<T>(initial: T): {
15
+ get: () => T;
16
+ set: (next: T | ((prev: T) => T)) => void;
17
+ subscribe: (listener: (value: T) => void) => () => void;
18
+ };
@@ -0,0 +1,46 @@
1
+ export type SwapOptions = {
2
+ /**
3
+ * Varsayılan `GET`.
4
+ */
5
+ method?: string;
6
+ body?: BodyInit | null;
7
+ headers?: Record<string, string>;
8
+ signal?: AbortSignal;
9
+ /**
10
+ * `true` → adres çubuğu `url` ile güncellenir.
11
+ */
12
+ history?: boolean;
13
+ /**
14
+ * Varsayılan `replace`.
15
+ */
16
+ mode?: "replace" | "append";
17
+ };
18
+ /**
19
+ * @typedef {object} SwapOptions
20
+ * @property {string} [method] Varsayılan `GET`.
21
+ * @property {BodyInit | null} [body]
22
+ * @property {Record<string, string>} [headers]
23
+ * @property {AbortSignal} [signal]
24
+ * @property {boolean} [history] `true` → adres çubuğu `url` ile güncellenir.
25
+ * @property {"replace" | "append"} [mode] Varsayılan `replace`.
26
+ */
27
+ /**
28
+ * @param {Element | string} target Takas edilecek bölge.
29
+ * @param {string} url Parçayı döndüren uç.
30
+ * @param {SwapOptions} [options]
31
+ * @returns {Promise<boolean>} Başarılıysa `true`; hata durumunda mevcut
32
+ * içerik korunur ve `false` döner.
33
+ */
34
+ export declare function swap(target: Element | string, url: string, options?: SwapOptions): Promise<boolean>;
35
+ /**
36
+ * `data-swap` taşıyan bağlantı ve butonları otomatik bağlar.
37
+ *
38
+ * <a href="/_fragment/rows?page=2" data-swap="#rows" data-swap-history>…</a>
39
+ *
40
+ * Tek bir delege dinleyici: sonradan DOM'a giren bağlantılar da çalışır ve
41
+ * her takastan sonra yeniden bağlama gerekmez.
42
+ *
43
+ * @param {ParentNode} [root]
44
+ * @returns {() => void} Dinleyiciyi söken fonksiyon.
45
+ */
46
+ export declare function startSwapLinks(root?: ParentNode): () => void;
@@ -0,0 +1,32 @@
1
+ export type AstNode = import('./parse.js').AstNode;
2
+ export type AttrNode = import('./parse.js').AttrNode;
3
+ /**
4
+ * @typedef {import('./parse.js').AstNode} AstNode
5
+ * @typedef {import('./parse.js').AttrNode} AttrNode
6
+ */
7
+ /**
8
+ * @param {AstNode[]} ast
9
+ * @param {{ viewId: string, file?: string, knownComponents?: Set<string> }} options
10
+ * @returns {{ code: string, includes: string[], components: string[] }}
11
+ */
12
+ export declare function codegen(ast: AstNode[], options: {
13
+ viewId: string;
14
+ file?: string;
15
+ knownComponents?: Set<string>;
16
+ }): {
17
+ code: string;
18
+ includes: string[];
19
+ components: string[];
20
+ };
21
+ /**
22
+ * Include yolunu view id'ye çevir (uzantısız, `/` ayırıcılı).
23
+ * @param {string} includePath
24
+ * @returns {string}
25
+ */
26
+ export declare function normalizeIncludeId(includePath: string): string;
27
+ /**
28
+ * `market-hero` / `MarketHero` → `MarketHero`
29
+ * @param {string} name
30
+ * @returns {string}
31
+ */
32
+ export declare function toPascalCase(name: string): string;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @param {{ root: string, dirs: Record<string, string> }} config
3
+ * @param {{ quiet?: boolean }} [options]
4
+ * @returns {Promise<{ count: number, manifest: Record<string, string>, outDir: string }>}
5
+ */
6
+ export declare function compileAll(config: {
7
+ root: string;
8
+ dirs: Record<string, string>;
9
+ }, _options?: {}): Promise<{
10
+ count: number;
11
+ manifest: Record<string, string>;
12
+ outDir: string;
13
+ }>;
14
+ /**
15
+ * Manifest yoksa veya herhangi bir `.jsk` daha yeniyse yeniden derler.
16
+ * Dev sunucu restart'ında build watch kaçırmış olsa bile şablonlar güncel kalır.
17
+ *
18
+ * @param {{ root: string, dirs: Record<string, string> }} config
19
+ * @returns {Promise<{ count: number, rebuilt: boolean }>}
20
+ */
21
+ export declare function ensureTemplatesCompiled(config: {
22
+ root: string;
23
+ dirs: Record<string, string>;
24
+ }): Promise<{
25
+ count: number;
26
+ rebuilt: boolean;
27
+ }>;
28
+ /**
29
+ * Tek kaynak dizgisini derler (birim testleri).
30
+ * @param {string} source
31
+ * @param {{ viewId?: string, file?: string, knownComponents?: Set<string> }} [options]
32
+ * @returns {{ code: string, includes: string[], components: string[] }}
33
+ */
34
+ export declare function compileSource(source: string, options?: {
35
+ viewId?: string;
36
+ file?: string;
37
+ knownComponents?: Set<string>;
38
+ }): {
39
+ code: string;
40
+ includes: string[];
41
+ components: string[];
42
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Şablon derleme hataları. Satır/sütun korunur ki DX overlay ve CLI
3
+ * çıktısı kaynağa işaret edebilsin.
4
+ */
5
+ /**
6
+ * @param {string} source
7
+ * @param {number} index
8
+ * @returns {{ line: number, column: number }}
9
+ */
10
+ export declare function indexToLocation(source: string, index: number): {
11
+ line: number;
12
+ column: number;
13
+ };
14
+ export declare class CompileError extends Error {
15
+ file: string | undefined;
16
+ line: number | undefined;
17
+ column: number | undefined;
18
+ /**
19
+ * @param {string} message
20
+ * @param {{ file?: string, source?: string, index?: number,
21
+ * line?: number, column?: number }} [opts]
22
+ */
23
+ constructor(message: string, opts?: {
24
+ file?: string;
25
+ source?: string;
26
+ index?: number;
27
+ line?: number;
28
+ column?: number;
29
+ });
30
+ }
@@ -0,0 +1,67 @@
1
+ export type LiteralNode = {
2
+ type: 'Literal';
3
+ value: string | number | boolean | null;
4
+ raw: string;
5
+ };
6
+ export type IdentNode = {
7
+ type: 'Ident';
8
+ name: string;
9
+ };
10
+ export type MemberNode = {
11
+ type: 'Member';
12
+ object: ExprNode;
13
+ property: string;
14
+ optional: boolean;
15
+ };
16
+ export type IndexNode = {
17
+ type: 'Index';
18
+ object: ExprNode;
19
+ index: ExprNode;
20
+ optional: boolean;
21
+ };
22
+ export type UnaryNode = {
23
+ type: 'Unary';
24
+ op: '!' | '-';
25
+ argument: ExprNode;
26
+ };
27
+ export type BinaryNode = {
28
+ type: 'Binary';
29
+ op: string;
30
+ left: ExprNode;
31
+ right: ExprNode;
32
+ };
33
+ export type CondNode = {
34
+ type: 'Cond';
35
+ test: ExprNode;
36
+ consequent: ExprNode;
37
+ alternate: ExprNode;
38
+ };
39
+ export type ExprNode = LiteralNode | IdentNode | MemberNode | IndexNode | UnaryNode | BinaryNode | CondNode;
40
+ /**
41
+ * @param {string} source
42
+ * @param {number} start
43
+ * @param {number} end
44
+ * @param {{ file?: string, templateSource?: string, templateIndex?: number }} [meta]
45
+ * @returns {ExprNode}
46
+ */
47
+ export declare function parseExpr(source: string, start?: number, end?: number, meta?: {
48
+ file?: string;
49
+ templateSource?: string;
50
+ templateIndex?: number;
51
+ }): ExprNode;
52
+ /**
53
+ * İfadeyi JS kaynak metnine çevirir. `locals` içindeki isimler çıplak kalır;
54
+ * diğerleri `data.` öneki alır.
55
+ *
56
+ * @param {ExprNode} node
57
+ * @param {Set<string>} [locals]
58
+ * @returns {string}
59
+ */
60
+ export declare function codegenExpr(node: ExprNode, locals?: Set<string>): string;
61
+ /**
62
+ * İfadede geçen kök tanımlayıcılar (data alanları / local adayları).
63
+ * @param {ExprNode} node
64
+ * @param {Set<string>} [out]
65
+ * @returns {Set<string>}
66
+ */
67
+ export declare function collectIdents(node: ExprNode, out?: Set<string>): Set<string>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Build-time `.jsk` derleyici yüzeyi.
3
+ */
4
+ export { CompileError, indexToLocation } from "./errors.js";
5
+ export { parseExpr, codegenExpr } from "./expr.js";
6
+ export { parseTemplate, isComponentTag } from "./parse.js";
7
+ export { codegen, toPascalCase, normalizeIncludeId } from "./codegen.js";
8
+ export { getViewRoots, getComponentDirs, discoverJskFiles, componentNameFromViewId, collectKnownComponents, toComponentTag, } from "./resolve.js";
9
+ export { scanNamedExports } from "./scan-exports.js";
10
+ export { compileAll, compileSource, ensureTemplatesCompiled } from "./compile-all.js";