katanakit-js 2.2.1 → 2.12.9

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 (148) hide show
  1. package/README.md +72 -437
  2. package/dist/adapters/astro/astro.service.d.ts +103 -15
  3. package/dist/adapters/astro/astro.service.d.ts.map +1 -1
  4. package/dist/adapters/astro/astro.service.js +145 -75
  5. package/dist/adapters/astro/astro.service.js.map +1 -1
  6. package/dist/adapters/astro/index.d.ts +1 -1
  7. package/dist/adapters/astro/index.d.ts.map +1 -1
  8. package/dist/adapters/astro/index.js +1 -1
  9. package/dist/adapters/astro/index.js.map +1 -1
  10. package/dist/adapters/astro/rss.service.d.ts +85 -105
  11. package/dist/adapters/astro/rss.service.d.ts.map +1 -1
  12. package/dist/adapters/astro/rss.service.js +172 -168
  13. package/dist/adapters/astro/rss.service.js.map +1 -1
  14. package/dist/adapters/astro/seo.service.d.ts +10 -0
  15. package/dist/adapters/astro/seo.service.d.ts.map +1 -0
  16. package/dist/adapters/astro/seo.service.js +3 -0
  17. package/dist/adapters/astro/seo.service.js.map +1 -0
  18. package/dist/adapters/express/app.d.ts +30 -1
  19. package/dist/adapters/express/app.d.ts.map +1 -1
  20. package/dist/adapters/express/app.js +31 -3
  21. package/dist/adapters/express/app.js.map +1 -1
  22. package/dist/adapters/express/index.d.ts +2 -2
  23. package/dist/adapters/express/index.d.ts.map +1 -1
  24. package/dist/adapters/express/index.js +2 -2
  25. package/dist/adapters/express/index.js.map +1 -1
  26. package/dist/adapters/express/main.js +2 -2
  27. package/dist/adapters/express/main.js.map +1 -1
  28. package/dist/adapters/express/products.controller.d.ts +67 -8
  29. package/dist/adapters/express/products.controller.d.ts.map +1 -1
  30. package/dist/adapters/express/products.controller.js +105 -49
  31. package/dist/adapters/express/products.controller.js.map +1 -1
  32. package/dist/adapters/express/server.d.ts +37 -13
  33. package/dist/adapters/express/server.d.ts.map +1 -1
  34. package/dist/adapters/express/server.js +118 -53
  35. package/dist/adapters/express/server.js.map +1 -1
  36. package/dist/adapters/nuxt/nuxt.service.d.ts +8 -6
  37. package/dist/adapters/nuxt/nuxt.service.d.ts.map +1 -1
  38. package/dist/adapters/nuxt/nuxt.service.js +34 -10
  39. package/dist/adapters/nuxt/nuxt.service.js.map +1 -1
  40. package/dist/adapters/vue/vue.service.d.ts +5 -2
  41. package/dist/adapters/vue/vue.service.d.ts.map +1 -1
  42. package/dist/adapters/vue/vue.service.js +41 -7
  43. package/dist/adapters/vue/vue.service.js.map +1 -1
  44. package/dist/config/index.d.ts +2 -1
  45. package/dist/config/index.d.ts.map +1 -1
  46. package/dist/config/index.js +1 -1
  47. package/dist/config/index.js.map +1 -1
  48. package/dist/config/seo-meta.types.d.ts +177 -0
  49. package/dist/config/seo-meta.types.d.ts.map +1 -0
  50. package/dist/config/seo-meta.types.js +11 -0
  51. package/dist/config/seo-meta.types.js.map +1 -0
  52. package/dist/config/seo.service.d.ts +41 -58
  53. package/dist/config/seo.service.d.ts.map +1 -1
  54. package/dist/config/seo.service.js +468 -136
  55. package/dist/config/seo.service.js.map +1 -1
  56. package/dist/config/site.config.d.ts +10 -50
  57. package/dist/config/site.config.d.ts.map +1 -1
  58. package/dist/config/site.config.js +8 -36
  59. package/dist/config/site.config.js.map +1 -1
  60. package/dist/core/index.d.ts +1 -3
  61. package/dist/core/index.d.ts.map +1 -1
  62. package/dist/core/index.js +1 -3
  63. package/dist/core/index.js.map +1 -1
  64. package/dist/core/services/dates.service.d.ts +149 -22
  65. package/dist/core/services/dates.service.d.ts.map +1 -1
  66. package/dist/core/services/dates.service.js +201 -54
  67. package/dist/core/services/dates.service.js.map +1 -1
  68. package/dist/core/services/error.service.d.ts +32 -20
  69. package/dist/core/services/error.service.d.ts.map +1 -1
  70. package/dist/core/services/error.service.js +44 -32
  71. package/dist/core/services/error.service.js.map +1 -1
  72. package/dist/core/services/formatter.service.d.ts +245 -35
  73. package/dist/core/services/formatter.service.d.ts.map +1 -1
  74. package/dist/core/services/formatter.service.js +281 -57
  75. package/dist/core/services/formatter.service.js.map +1 -1
  76. package/dist/core/services/generator.service.d.ts +115 -26
  77. package/dist/core/services/generator.service.d.ts.map +1 -1
  78. package/dist/core/services/generator.service.js +191 -56
  79. package/dist/core/services/generator.service.js.map +1 -1
  80. package/dist/core/services/geometry.service.d.ts +369 -39
  81. package/dist/core/services/geometry.service.d.ts.map +1 -1
  82. package/dist/core/services/geometry.service.js +424 -66
  83. package/dist/core/services/geometry.service.js.map +1 -1
  84. package/dist/core/services/http.service.d.ts +244 -21
  85. package/dist/core/services/http.service.d.ts.map +1 -1
  86. package/dist/core/services/http.service.js +419 -98
  87. package/dist/core/services/http.service.js.map +1 -1
  88. package/dist/core/services/logger.service.d.ts +95 -29
  89. package/dist/core/services/logger.service.d.ts.map +1 -1
  90. package/dist/core/services/logger.service.js +167 -41
  91. package/dist/core/services/logger.service.js.map +1 -1
  92. package/dist/core/services/reactive.service.d.ts +146 -19
  93. package/dist/core/services/reactive.service.d.ts.map +1 -1
  94. package/dist/core/services/reactive.service.js +278 -137
  95. package/dist/core/services/reactive.service.js.map +1 -1
  96. package/dist/core/services/timing.service.d.ts +142 -20
  97. package/dist/core/services/timing.service.d.ts.map +1 -1
  98. package/dist/core/services/timing.service.js +324 -185
  99. package/dist/core/services/timing.service.js.map +1 -1
  100. package/dist/core/services/utils.service.d.ts +228 -43
  101. package/dist/core/services/utils.service.d.ts.map +1 -1
  102. package/dist/core/services/utils.service.js +305 -125
  103. package/dist/core/services/utils.service.js.map +1 -1
  104. package/dist/infrastructure/dom/dom.service.d.ts +307 -44
  105. package/dist/infrastructure/dom/dom.service.d.ts.map +1 -1
  106. package/dist/infrastructure/dom/dom.service.js +408 -129
  107. package/dist/infrastructure/dom/dom.service.js.map +1 -1
  108. package/dist/infrastructure/index.d.ts +0 -3
  109. package/dist/infrastructure/index.d.ts.map +1 -1
  110. package/dist/infrastructure/index.js +0 -3
  111. package/dist/infrastructure/index.js.map +1 -1
  112. package/dist/infrastructure/observer/observer.service.d.ts +124 -31
  113. package/dist/infrastructure/observer/observer.service.d.ts.map +1 -1
  114. package/dist/infrastructure/observer/observer.service.js +227 -131
  115. package/dist/infrastructure/observer/observer.service.js.map +1 -1
  116. package/dist/infrastructure/sensors/sensors.service.d.ts +154 -22
  117. package/dist/infrastructure/sensors/sensors.service.d.ts.map +1 -1
  118. package/dist/infrastructure/sensors/sensors.service.js +264 -112
  119. package/dist/infrastructure/sensors/sensors.service.js.map +1 -1
  120. package/dist/infrastructure/storage/storage.service.d.ts +123 -45
  121. package/dist/infrastructure/storage/storage.service.d.ts.map +1 -1
  122. package/dist/infrastructure/storage/storage.service.js +236 -66
  123. package/dist/infrastructure/storage/storage.service.js.map +1 -1
  124. package/dist/infrastructure/theme/theme.service.d.ts +93 -29
  125. package/dist/infrastructure/theme/theme.service.d.ts.map +1 -1
  126. package/dist/infrastructure/theme/theme.service.js +198 -96
  127. package/dist/infrastructure/theme/theme.service.js.map +1 -1
  128. package/dist/infrastructure/viewport/viewport.service.d.ts +233 -35
  129. package/dist/infrastructure/viewport/viewport.service.d.ts.map +1 -1
  130. package/dist/infrastructure/viewport/viewport.service.js +358 -139
  131. package/dist/infrastructure/viewport/viewport.service.js.map +1 -1
  132. package/dist/infrastructure/worker/worker.service.d.ts +84 -38
  133. package/dist/infrastructure/worker/worker.service.d.ts.map +1 -1
  134. package/dist/infrastructure/worker/worker.service.js +234 -133
  135. package/dist/infrastructure/worker/worker.service.js.map +1 -1
  136. package/dist/prisma/index.d.ts +2 -0
  137. package/dist/prisma/index.d.ts.map +1 -0
  138. package/dist/prisma/index.js +2 -0
  139. package/dist/prisma/index.js.map +1 -0
  140. package/dist/prisma/schema.json +11 -33
  141. package/dist/prisma/use-prisma.d.ts +68 -0
  142. package/dist/prisma/use-prisma.d.ts.map +1 -0
  143. package/dist/prisma/use-prisma.js +82 -0
  144. package/dist/prisma/use-prisma.js.map +1 -0
  145. package/dist/types/index.d.ts +20 -12
  146. package/dist/types/index.d.ts.map +1 -1
  147. package/package.json +124 -125
  148. package/CHANGELOG.md +0 -101
package/README.md CHANGED
@@ -1,61 +1,6 @@
1
- # KatanaKit (`katanakit-js`)
2
-
3
- KatanaKit is a sharp, framework-agnostic **TypeScript service toolkit** organized
4
- with **hexagonal architecture** and built on proven design patterns (Singleton,
5
- Observer, Factory, Strategy, Facade and Adapter).
6
-
7
- It runs in the browser, in Node.js (>= 22.18) and in Bun, ships with an Astro
8
- `getStaticPaths` adapter, an RSS 2.0 generator, a site-config/SEO module, an
9
- optional Express server reference, a Nuxt (Nitro/H3) adapter and a Vue 3
10
- composable. Importing a module never triggers side effects, and every async
11
- operation returns a **Safe Result** instead of throwing.
12
-
13
- - **Version:** 2.1.4
14
- - **npm package:** `katanakit-js`
15
- - **Repository:** [senseikatana/katanakit](https://github.com/senseikatana/katanakit)
16
- (development happens on the `dev` branch)
17
- - **License:** MIT
18
-
19
- ## Why
20
-
21
- Modern frontend and full-stack apps keep reimplementing the same plumbing:
22
- fetching an API safely, logging, persisting to storage, querying the DOM,
23
- reacting to state changes, generating slugs, formatting dates and money,
24
- building RSS/SEO output. KatanaKit provides all of that as a single, typed and
25
- tree-shakeable set of `use*` services with a consistent API: one `useInit` for
26
- your APIs, one `useFetch` that returns a Safe Result, one way to do logging,
27
- storage and DOM across every framework.
1
+ # `katanakit-js`
28
2
 
29
- ## Features
30
-
31
- - **Safe URL construction** — builds URLs from a JSON-defined API registry using
32
- the native `URL` API and `encodeURIComponent`; only `http:`/`https:` schemes
33
- are allowed (prevents `javascript:` URLs and SSRF).
34
- - **Safe Result** — every `useFetch` returns a discriminated union
35
- `{ data, error, url, status, ok }` (Astro Actions style) instead of throwing
36
- on HTTP errors.
37
- - **Hexagonal architecture** — a pure `core` layer (services), an
38
- `infrastructure` layer (browser/runtime adapters), an `adapters` layer
39
- (Astro, Express, Nuxt, Vue), a `config` layer (site config + SEO) and a
40
- single source of truth for contracts and types in `src/types/`.
41
- - **Design patterns** — Singleton facades, Strategy (logger, storage,
42
- crypto/UUID), Factory (errors, debounce/throttle), Observer (signals,
43
- IntersectionObserver, media queries), Facade and Adapter, all exposed as
44
- `use*` methods (like React hooks) with safe destructured exports.
45
- - **Consistent `use*` API** — every public method is prefixed with `use`
46
- (`useInit`, `useFetch`, `useLog`, `useCreateSignal`, ...); the only exception
47
- is `getInstance()`.
48
- - **Pure ESM** — relative imports use explicit `.js` extensions and
49
- `module: nodenext`; bundlers and Node resolve the package cleanly.
50
- - **Zero side effects on import** — importing a module never triggers network
51
- calls, timers, storage writes or DOM mutations.
52
- - **SSR-safe** — browser-only adapters guard or fall back gracefully
53
- (in-memory storage, main-thread worker execution) when `window` is
54
- unavailable.
55
- - **Optional heavy dependencies** — only `@js-temporal/polyfill` is a runtime
56
- dependency; `express`, `cors`, `dotenv` and `@prisma/orm-postgres` are
57
- optional peer dependencies.
58
- - **Fully typed** — strict TypeScript with generated `.d.ts` declarations.
3
+ A sharp, framework-agnostic TypeScript service toolkit organized with hexagonal architecture.
59
4
 
60
5
  ## Installation
61
6
 
@@ -63,437 +8,127 @@ storage and DOM across every framework.
63
8
  npm install katanakit-js
64
9
  # or
65
10
  bun add katanakit-js
11
+ # or
12
+ yarn add katanakit-js
66
13
  ```
67
14
 
68
- Requirements: **Node.js >= 22.18.0** (pure ESM package). TypeScript consumers
69
- should use `moduleResolution: "nodenext"` (or `"bundler"`).
70
-
71
- ### Framework adapters
72
-
73
- The root import is framework-agnostic. Framework-specific entry points are
74
- published as package **subpaths** of the same `katanakit-js` package:
75
-
76
- ```ts
77
- // Nuxt / Nitro adapter helpers (no extra dependency; h3 ships with Nuxt)
78
- import { useUnwrap } from "katanakit-js/adapters/nuxt";
15
+ ### CDN (ESM)
79
16
 
80
- // Vue 3 composable (requires vue as a peer dependency)
81
- import { useKatanaFetch } from "katanakit-js/adapters/vue";
17
+ In the browser, use jsDelivr **`/+esm`** so named exports and dependencies resolve:
82
18
 
83
- // Express reference server (requires express as a peer dependency)
84
- import { ServerExpress } from "katanakit-js/adapters/express";
19
+ ```html
20
+ <script type="module">
21
+ import { useLogger, useGetApi, useInitApis } from "https://cdn.jsdelivr.net/npm/katanakit-js/+esm";
22
+ useLogger("ready");
23
+ </script>
85
24
  ```
86
25
 
87
- `express`, `cors`, `dotenv` and `@prisma/orm-postgres` are **optional peer
88
- dependencies** — install them only if you use the Express adapter or the Prisma
89
- layer.
90
-
91
- ### Building from source
26
+ | CDN | URL |
27
+ |-----|-----|
28
+ | **jsDelivr `/+esm`** (recommended) | `https://cdn.jsdelivr.net/npm/katanakit-js/+esm` |
29
+ | **esm.sh** | `https://esm.sh/katanakit-js` |
30
+ | **Raw ESM file** | `https://cdn.jsdelivr.net/npm/katanakit-js/dist/index.js` (needs bundler or import map) |
92
31
 
93
- ```bash
94
- git clone https://github.com/senseikatana/katanakit.git
95
- cd katanakit
96
- bun install
97
- bun run build # outputs to dist/
98
- ```
32
+ Pin a version in production (e.g. `@2.8.0/+esm`). There is no IIFE/UMD build.
99
33
 
100
34
  ## Quick Start
101
35
 
102
- Everything below is importable from the main barrel `katanakit-js`.
103
-
104
- ### HTTP client
105
-
106
36
  ```ts
107
- import { useInit, useGet, usePost, useBuildUrl } from "katanakit-js";
37
+ import { useInitApis, useGetApi, useLogger } from "katanakit-js";
38
+
39
+ useLogger("boot");
108
40
 
109
- // 1. Register your APIs once.
110
- useInit({
41
+ // Register your APIs once
42
+ useInitApis({
111
43
  pokeapi: {
112
44
  baseUri: "https://pokeapi.co/api/v2",
113
- endpoints: {
114
- pokemonById: "/pokemon/:id/",
115
- pokemons: "/pokemons/",
116
- },
45
+ endpoints: { pokemonById: "/pokemon/:id/" },
117
46
  },
118
47
  });
119
48
 
120
- // 2. Build a safe URL (path params encoded, query params merged).
121
- const url = useBuildUrl("pokeapi", "pokemonById", {
122
- params: { id: "pikachu" },
123
- });
124
- // => "https://pokeapi.co/api/v2/pokemon/pikachu/"
125
-
126
- // 3. Fetch with a Safe Result (no throwing on HTTP errors).
127
- const result = await useGet<{ name: string }>("pokeapi", "pokemonById", {
49
+ // Fetch with Safe Result no try/catch needed for HTTP failures
50
+ const result = await useGetApi<{ name: string }>("pokeapi", "pokemonById", {
128
51
  params: { id: 25 },
129
52
  });
130
53
 
131
54
  if (result.ok) {
132
- console.log(result.data.name);
55
+ console.log(result.data.name); // "pikachu"
133
56
  } else {
134
- console.error(result.error.message, result.error.status);
135
- }
136
-
137
- // 4. POST JSON.
138
- await usePost("pokeapi", "pokemons", { name: "charmander" });
139
- ```
140
-
141
- ### Logger, storage and DOM
142
-
143
- ```ts
144
- import {
145
- useLog,
146
- useSetStorage,
147
- useGetStorage,
148
- useRemoveStorage,
149
- useAddClass,
150
- useGetRoot,
151
- } from "katanakit-js";
152
-
153
- useLog("Hello", { user: "John" }); // info level
154
- useLog("error", "Something failed", { code: 500 }); // error level
155
-
156
- useSetStorage("theme", "dark");
157
- const theme = useGetStorage<string>("theme"); // "dark"
158
- useRemoveStorage("theme");
159
-
160
- useAddClass(useGetRoot()!, "dark-mode");
161
- ```
162
-
163
- Storage is SSR-safe: when `window` is unavailable an in-memory fallback is used
164
- automatically, so imports never crash in Node/Bun.
165
-
166
- ## Astro adapter
167
-
168
- KatanaKit converts arbitrary collections into the payload Astro's
169
- `getStaticPaths` expects, wrapped in a Safe Result.
170
-
171
- ```ts
172
- // src/pages/blog/[slug].astro
173
- import { AstroService } from "katanakit-js";
174
-
175
- export async function getStaticPaths() {
176
- const { useGetStaticPaths } = AstroService.getInstance();
177
-
178
- return useGetStaticPaths(getCollection, "blog", {
179
- param: "slug",
180
- valueFrom: (entry) => entry.slug ?? entry.id,
181
- propsFrom: (entry) => entry.data,
182
- });
57
+ console.error(result.error.message);
183
58
  }
184
59
  ```
185
60
 
186
- Also available: `usePathsFrom`, `useFindEntry`, `useGeneratePagination`,
187
- `usePathsFromValues` and `useExtractUniqueValues`. See the
188
- [API Reference](docs/API-Reference.md#astro--astroservice).
61
+ ## Features
189
62
 
190
- ## RSS feeds for Astro
63
+ - **Safe Results** HTTP (and other fallible) operations return `{ data, error, ok }` instead of throwing
64
+ - **Zero side effects** — importing any module is safe. No `fetch` calls, no `console.log`, no storage writes
65
+ - **Hexagonal architecture** — pure core, infrastructure adapters, framework adapters
66
+ - **Tree-shakeable** — destructured re-exports from Singleton facades
67
+ - **SSR-safe** — all infrastructure adapters guard or fall back gracefully in server environments
191
68
 
192
- `RssService` generates pure RSS 2.0 XML with **no external dependencies**
193
- (`@astrojs/rss` is not required).
69
+ ## Framework usage
194
70
 
195
- ```ts
196
- // src/pages/rss.xml.ts
197
- import { RssService } from "katanakit-js";
198
- import { getCollection } from "astro:content";
199
-
200
- const { useCreateRssEndpoint } = RssService.getInstance();
201
-
202
- export const GET = useCreateRssEndpoint({
203
- title: "My Blog",
204
- description: "Posts about TypeScript",
205
- site: "https://example.com",
206
- items: async () => {
207
- const posts = await getCollection("blog");
208
- return posts.map((post) => ({
209
- title: post.data.title,
210
- pubDate: post.data.date,
211
- link: `/blog/${post.slug}/`,
212
- description: post.data.description,
213
- }));
214
- },
215
- });
216
- ```
71
+ All common `use*` helpers (`useLogger`, `useInitApis`, `useGetApi`, formatter, dates, utils, theme, …) are on the **main barrel** `katanakit-js`.
217
72
 
218
- Add the feed `<link>` tag to your layout's `<head>`:
73
+ ### Astro (npm)
219
74
 
220
75
  ```astro
221
76
  ---
222
- import { useRssLinkTag } from "katanakit-js";
77
+ // Frontmatter = server
78
+ import { useLogger, useGetApi, useInitApis } from "katanakit-js";
79
+ useInitApis({ /* ... */ });
80
+ const result = await useGetApi("pokeapi", "pokemonById", { params: { id: 25 } });
223
81
  ---
224
- <head>
225
- <Fragment set:html={useRssLinkTag({ title: "My Blog" })} />
226
- </head>
227
- ```
228
-
229
- `useCreateRssEndpointFromConfig(siteConfig, items)` builds the same endpoint
230
- from your `SiteConfig`. See the [API Reference](docs/API-Reference.md#rss--rssservice).
231
-
232
- ## Site config and SEO
233
-
234
- Centralize your site metadata in a typed `SiteConfig` and derive every `<head>`
235
- tag from it.
236
-
237
- ```ts
238
- // src/config/site.config.ts
239
- import { type SiteConfig } from "katanakit-js";
240
-
241
- export const siteConfig: SiteConfig = {
242
- site: "https://myblog.com",
243
- title: "My Blog",
244
- description: "A blog about TypeScript and Astro",
245
- lang: "en",
246
- author: "John Doe",
247
- ogImage: "/og-default.png",
248
- twitter: "johndoe",
249
- rss: { enabled: true, path: "/rss.xml", limit: 20 },
250
- seo: { noindex: false, canonical: true, openGraph: true, twitterCard: true, jsonLd: true },
251
- nav: [
252
- { label: "Home", href: "/" },
253
- { label: "Blog", href: "/blog" },
254
- { label: "GitHub", href: "https://github.com/senseikatana/katanakit", external: true },
255
- ],
256
- };
82
+ <script>
83
+ // Client script Vite bundles the same package
84
+ import { useLogger } from "katanakit-js";
85
+ useLogger("client");
86
+ </script>
257
87
  ```
258
88
 
259
- Then inject complete meta tags (title, description, canonical, Open Graph,
260
- Twitter Card and JSON-LD) in your layout:
89
+ ### Astro (CDN client)
261
90
 
262
91
  ```astro
263
- ---
264
- // src/layouts/BaseLayout.astro
265
- import { siteConfig } from "@/config/site.config";
266
- import { useHeadTags } from "katanakit-js";
267
-
268
- interface Props {
269
- title: string;
270
- description?: string;
271
- ogType?: "website" | "article";
272
- publishedTime?: string;
273
- }
274
-
275
- const { title, description, ogType, publishedTime } = Astro.props;
276
- const headTags = useHeadTags(siteConfig, {
277
- title,
278
- description,
279
- url: new URL(Astro.url.pathname, siteConfig.site).href,
280
- ogType,
281
- publishedTime,
282
- });
283
- ---
284
- <html lang={siteConfig.lang}>
285
- <head>
286
- <meta charset="utf-8" />
287
- <meta name="viewport" content="width=device-width, initial-scale=1" />
288
- <Fragment set:html={headTags} />
289
- </head>
290
- <body>
291
- <slot />
292
- </body>
293
- </html>
294
- ```
295
-
296
- The RSS endpoint consumes the same config:
297
-
298
- ```ts
299
- // src/pages/rss.xml.ts
300
- import { RssService } from "katanakit-js";
301
- import { siteConfig } from "@/config/site.config";
302
- import { getCollection } from "astro:content";
303
-
304
- const { useCreateRssEndpointFromConfig } = RssService.getInstance();
305
-
306
- export const GET = useCreateRssEndpointFromConfig(siteConfig, async () => {
307
- const posts = await getCollection("blog");
308
- return posts.map((post) => ({
309
- title: post.data.title,
310
- pubDate: post.data.date,
311
- link: `/blog/${post.slug}/`,
312
- description: post.data.description,
313
- }));
314
- });
315
- ```
316
-
317
- ## Nuxt adapter
318
-
319
- New in 2.1.4. Three pure helper functions bridge KatanaKit's Safe Results to
320
- Nuxt/Nitro server routes. They are **not** singleton services — just exported
321
- functions — and they avoid a hard dependency on `h3` (it ships with Nuxt).
322
-
323
- ```ts
324
- import { useInit, useGet } from "katanakit-js";
325
- import { useUnwrap } from "katanakit-js/adapters/nuxt";
326
-
327
- // server/plugins/api.ts — register your APIs once
328
- useInit({
329
- pokeapi: {
330
- baseUri: "https://pokeapi.co/api/v2",
331
- endpoints: { pokemonById: "/pokemon/:id/" },
332
- },
333
- });
334
- ```
335
-
336
- ```ts
337
- // server/api/pokemon/[id].ts
338
- import { useGet } from "katanakit-js";
339
- import { useUnwrap } from "katanakit-js/adapters/nuxt";
340
-
341
- export default defineEventHandler(async (event) => {
342
- const id = getRouterParam(event, "id");
343
- const result = await useGet("pokeapi", "pokemonById", { params: { id } });
344
- return useUnwrap(result, `Pokemon ${id}`); // returns data, or throws an H3-compatible error
345
- });
346
- ```
347
-
348
- The other helpers are `useSafeResponse(result)` (shape the result as a clean
349
- JSON response object) and `useEventResponse(event, result)` (set the H3 event
350
- status code and return data/error). See the
351
- [API Reference](docs/API-Reference.md#nuxt-adapter--katanakit-jsadaptersnuxt).
352
-
353
- ## Vue adapter
354
-
355
- `useKatanaFetch` is a Vue 3 composable that bridges KatanaKit's Safe Results to
356
- Vue's reactivity system. It exposes `data`, `error`, `loading` and a `refetch`
357
- function, and it never throws on HTTP errors.
358
-
359
- ```ts
360
- import { useInit } from "katanakit-js";
361
- import { useKatanaFetch } from "katanakit-js/adapters/vue";
362
-
363
- useInit({
364
- pokeapi: {
365
- baseUri: "https://pokeapi.co/api/v2",
366
- endpoints: { pokemonById: "/pokemon/:id/" },
367
- },
368
- });
369
- ```
370
-
371
- ```vue
372
- <script setup lang="ts">
373
- import { useKatanaFetch } from "katanakit-js/adapters/vue";
374
-
375
- interface Pokemon { name: string; id: number; }
376
-
377
- const { data: pokemon, error, loading } = useKatanaFetch<Pokemon>(
378
- "pokeapi",
379
- "pokemonById",
380
- { params: { id: 25 } },
381
- );
92
+ <script is:inline type="module">
93
+ import { useLogger } from "https://cdn.jsdelivr.net/npm/katanakit-js/+esm";
94
+ useLogger("cdn");
382
95
  </script>
383
-
384
- <template>
385
- <div v-if="loading">Loading…</div>
386
- <div v-else-if="error">{{ error.message }}</div>
387
- <div v-else>{{ pokemon?.name }}</div>
388
- </template>
389
96
  ```
390
97
 
391
- Pass a `Ref` as the options argument to refetch automatically when it changes:
98
+ ### Vue / Nuxt / vanilla
392
99
 
393
100
  ```ts
394
- const id = ref(25);
395
- const { data } = useKatanaFetch("pokeapi", "pokemonById", computed(() => ({ params: { id: id.value } })));
101
+ import { useLogger, useInitApis, useGetApi } from "katanakit-js";
102
+ import { useKatanaFetch } from "katanakit-js/adapters/vue"; // Vue only
103
+ import { useUnwrap } from "katanakit-js/adapters/nuxt"; // Nuxt only
396
104
  ```
397
105
 
398
- `vue` is an optional peer dependency — install it only if you use this adapter.
399
- See the [API Reference](docs/API-Reference.md#vue-adapter--katanakit-jsadaptersvue).
400
-
401
- ## Express server (optional)
402
-
403
- The Express reference adapter is exposed only through its own subpath so it
404
- never bloats the main bundle:
405
-
406
- ```ts
407
- import { ServerExpress } from "katanakit-js/adapters/express";
408
-
409
- ServerExpress.getInstance().useStart(); // http://localhost:3000
106
+ ```html
107
+ <!-- vanilla -->
108
+ <script type="module">
109
+ import { useLogger } from "https://cdn.jsdelivr.net/npm/katanakit-js/+esm";
110
+ </script>
410
111
  ```
411
112
 
412
- It expects `express` (and `cors`/`dotenv` if used) to be installed in your
413
- project. A `ProductController` and a demo `router` are also exported.
414
-
415
- ## Services at a glance
416
-
417
- | Area | Service / module | Highlights |
418
- | --------- | --------------------------- | ------------------------------------------------------------------- |
419
- | HTTP | `FetchApiManager` | `useInit`, `useGetApis`, `useBuildUrl`, `useFetch`, `useGet`, `usePost`, `usePut`, `useDelete` |
420
- | Logging | `LoggerService` | `useLog`, `useError`, `useClear`, `useTable`, pluggable `LogStrategy` |
421
- | Storage | `StorageService` | `useGetStorage`, `useSetStorage`, `useRemoveStorage`, `useClearStorage` (SSR-safe) |
422
- | DOM | `DomService` | `useQuerySelector`, `useAddClass`, `useOn`, `useSetText`, ... |
423
- | Reactive | `ReactiveService` | `useCreateSignal`, `useCreateEffect`, `useCreateMemo`, `useCreateToggle`, `useCreateStorageSignal`, `useCreateDebouncedSignal`, `useCreateBatch` |
424
- | Format | `FormatterService` | `useFormatNumber`, `useFormatCurrency`, `useJsonStringify`, `useUpperCase`, `useCapitalize`, ... |
425
- | Convert | `ConverterService` | `useToCelsius`, `useToFahrenheit`, `useToMiles`, `useToKilos`, ... |
426
- | Errors | `ErrorFactoryService` | `useBadRequest`, `useUnauthorized`, `useForbidden`, `useNotFound`, `useInternal`, `useCustom` |
427
- | Generate | `GeneratorService` | `useUuid`, `useSlugify`, `useNumericId`, `useToken`, `useEncrypt` |
428
- | Dates | `DatesService` | `useFormat`, `useNow`, `useAddDays`, `useIsBefore`, `useLastDayOfMonth`, ... (Temporal) |
429
- | Geometry | `GeometryUtils` | `area`, `perimeter`, `volume` static helpers (`useCircle`, `useSphere`, ...) |
430
- | Timing | `TimingService` | `useDelay`, `useSetTimeout`, `useInterval`, `useDebounce`, `useThrottle`, `useRepeat`, `useRace` |
431
- | Utils | `DataUtils` / `SystemUtils` | `useUnique`, `useGroupBy`, `useDeepClone`, `useSleep`, `useRetry`, `useRound`, ... |
432
- | Viewport | `ViewportService` | scroll, fullscreen, visibility, `usePrefersReducedMotion` |
433
- | Sensors | `SensorsUtils` | `useGetGeolocation`, `useGetMediaStream`, `useVibrate`, `useGetBattery`, ... |
434
- | Observer | `ObserverService` | `useCreate`, `useObserve`, `useObserveAll`, `useDisconnect` |
435
- | LazyLoad | `LazyLoaderService` | `useInit`, `useStop`, `useStopAll` for `img[data-src]` |
436
- | Worker | `WorkerService` | `useRun`, `useCreatePool`, `useRunPool`, `useTerminate` |
437
- | Theme | `ThemeService` | `useInitTheme`, `useSetThemeMode`, `useToggleTheme`, `useResetTheme` |
438
- | Astro | `AstroService` | `useGetStaticPaths`, `usePathsFrom`, `useGeneratePagination`, ... |
439
- | RSS | `RssService` | `useGenerateRss`, `useRssLinkTag`, `useCreateRssEndpoint`, `useCreateRssEndpointFromConfig` |
440
- | SEO | `useHeadTags` and friends | `useGenerateMetaTags`, `useTitle`, `useRssHeadLink` + typed `SiteConfig` |
441
- | Config | `siteConfig` / `SiteConfig` | single source for site metadata, RSS and SEO defaults |
442
- | Nuxt | `katanakit-js/adapters/nuxt`| `useUnwrap`, `useSafeResponse`, `useEventResponse` (pure functions) |
443
- | Vue | `katanakit-js/adapters/vue` | `useKatanaFetch` composable (`data`, `error`, `loading`, `refetch`) |
444
- | Server | `katanakit-js/adapters/express` | `ServerExpress`, `router`, `ProductController` (optional reference) |
445
-
446
- The Astro, RSS, SEO and config modules plus all core/infrastructure services
447
- are re-exported from the main barrel. The Nuxt, Vue and Express adapters are
448
- only available through their subpaths.
449
-
450
- ## Project structure (hexagonal)
113
+ See [Getting Started](https://senseikatana.github.io/katanakit-js/docs/guides/getting-started) for full recipes.
451
114
 
452
- ```
453
- katanakit/
454
- ├── package.json # name: katanakit-js, ESM, exports map
455
- ├── prisma.config.ts # Prisma ORM config (contract + connection)
456
- ├── src/
457
- │ ├── index.ts # main barrel (public API)
458
- │ ├── types/ # single source of truth: contracts & types
459
- │ ├── core/
460
- │ │ └── services/ # pure services (no I/O): logger, http, ...
461
- │ ├── infrastructure/ # browser/runtime adapters
462
- │ │ ├── dom/ storage/ viewport/ sensors/
463
- │ │ └── observer/ worker/ theme/
464
- │ ├── adapters/ # framework adapters
465
- │ │ ├── astro/ # AstroService + RssService
466
- │ │ ├── express/ # ServerExpress reference (subpath export)
467
- │ │ ├── nuxt/ # Nuxt helpers (subpath export)
468
- │ │ └── vue/ # Vue composable (subpath export)
469
- │ ├── config/ # siteConfig (SiteConfig) + SEO helpers
470
- │ └── prisma/ # Prisma schema, contract types and db client
471
- ├── tests/ # Vitest suite (60 tests across 8 files)
472
- ├── examples/ # runnable demos
473
- ├── docs/ # Getting Started, Architecture, API Reference, Roadmap
474
- ├── CONTRIBUTING.md
475
- └── SECURITY.md
476
- ```
115
+ ## Framework Adapters
477
116
 
478
- All internal source imports are relative and carry an explicit `.js` extension
479
- (pure ESM, `module: nodenext`). The `@/` alias (mapped to `src/`) is configured
480
- for the test suite and the examples.
117
+ | Adapter | Import | Description |
118
+ |---------|--------|-------------|
119
+ | **Express** | `katanakit-js/adapters/express` | Reference server with CORS and hardened headers |
120
+ | **Nuxt** | `katanakit-js/adapters/nuxt` | `useUnwrap`, `useSafeResponse`, `useEventResponse` |
121
+ | **Vue** | `katanakit-js/adapters/vue` | `useKatanaFetch` composable with reactivity |
122
+ | **Astro** | `katanakit-js` or `katanakit-js/adapters/astro` | `AstroService`, `RssService` |
481
123
 
482
124
  ## Documentation
483
125
 
484
- - [Getting Started](docs/Getting-Started.md)
485
- - [Architecture](docs/Architecture.md)
486
- - [API Reference](docs/API-Reference.md)
487
- - [Roadmap](docs/Roadmap.md)
488
- - [Security](SECURITY.md)
489
- - [Changelog](CHANGELOG.md)
490
-
491
- ## Contributing
492
-
493
- Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for
494
- the development contract (hexagonal layering, `use*` convention, `.js` ESM
495
- imports, tests, scripts) before opening a pull request.
126
+ - [Getting Started](https://senseikatana.github.io/katanakit-js/docs/guides/getting-started)
127
+ - [Architecture](https://senseikatana.github.io/katanakit-js/docs/guides/architecture)
128
+ - [API Reference](https://senseikatana.github.io/katanakit-js/docs/api)
129
+ - [Roadmap](https://senseikatana.github.io/katanakit-js/docs/guides/roadmap)
130
+ - [Changelog](https://senseikatana.github.io/katanakit-js/docs/changelog)
496
131
 
497
132
  ## License
498
133
 
499
- [MIT](LICENSE)
134
+ MIT