@krak-stack/registry 0.1.6 → 0.1.8

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.
@@ -387,6 +387,14 @@ var routeStrategies = [
387
387
  {
388
388
  match: "/api/:path(.*)?",
389
389
  exclude: true
390
+ },
391
+ {
392
+ match: "/sitemap.xml",
393
+ exclude: true
394
+ },
395
+ {
396
+ match: "/llms.txt",
397
+ exclude: true
390
398
  }
391
399
  ];
392
400
  var urlPatterns = [
@@ -1594,6 +1602,107 @@ function SidebarLayout({
1594
1602
  });
1595
1603
  }
1596
1604
 
1605
+ // ../../src/lib/seo.ts
1606
+ var localizedUrl = (origin, locale, path) => `${origin.replace(/\/$/, "")}/${locale}${path === "/" ? "/" : path}`;
1607
+ var seo = ({
1608
+ title,
1609
+ description,
1610
+ image,
1611
+ keywords,
1612
+ url,
1613
+ origin,
1614
+ path = "/",
1615
+ locale,
1616
+ locales: locales2,
1617
+ defaultLocale,
1618
+ robots = "index, follow",
1619
+ siteName = "KrakStack",
1620
+ twitterCreator = "@krak",
1621
+ twitterSite = "@krak",
1622
+ type = "website",
1623
+ sameAs
1624
+ }) => {
1625
+ const canonical = url ?? (origin && locale ? localizedUrl(origin, locale, path) : undefined);
1626
+ const tags = [
1627
+ { title },
1628
+ { name: "description", content: description },
1629
+ { name: "keywords", content: keywords },
1630
+ { name: "robots", content: robots },
1631
+ { name: "twitter:title", content: title },
1632
+ { name: "twitter:description", content: description },
1633
+ { name: "twitter:creator", content: twitterCreator },
1634
+ { name: "twitter:site", content: twitterSite },
1635
+ {
1636
+ name: "twitter:card",
1637
+ content: image ? "summary_large_image" : "summary"
1638
+ },
1639
+ { property: "og:type", content: type },
1640
+ { property: "og:title", content: title },
1641
+ { property: "og:description", content: description },
1642
+ { property: "og:site_name", content: siteName },
1643
+ { property: "og:url", content: canonical },
1644
+ {
1645
+ property: "og:locale",
1646
+ content: locale === "fr" ? "fr_FR" : locale ? "en_US" : undefined
1647
+ },
1648
+ ...image ? [
1649
+ { name: "twitter:image", content: image },
1650
+ { property: "og:image", content: image }
1651
+ ] : []
1652
+ ].filter((tag) => !Object.hasOwn(tag, "content") || tag.content);
1653
+ const alternateLocales = locales2 ?? [];
1654
+ const links = canonical ? [
1655
+ { rel: "canonical", href: canonical },
1656
+ ...origin && alternateLocales.length > 0 ? alternateLocales.map((alternateLocale) => ({
1657
+ rel: "alternate",
1658
+ hrefLang: alternateLocale,
1659
+ href: localizedUrl(origin, alternateLocale, path)
1660
+ })) : [],
1661
+ ...origin && alternateLocales.length > 0 ? [
1662
+ {
1663
+ rel: "alternate",
1664
+ hrefLang: "x-default",
1665
+ href: localizedUrl(origin, defaultLocale ?? alternateLocales[0] ?? "en", path)
1666
+ }
1667
+ ] : []
1668
+ ] : [];
1669
+ const siteUrl = origin?.replace(/\/$/, "") ?? canonical;
1670
+ const publisher = {
1671
+ "@type": "Organization",
1672
+ name: siteName,
1673
+ ...siteUrl ? { url: siteUrl } : {},
1674
+ ...sameAs?.length ? { sameAs } : {}
1675
+ };
1676
+ const structuredData = type === "article" ? {
1677
+ "@type": "Article",
1678
+ headline: title,
1679
+ description,
1680
+ ...canonical ? { url: canonical } : {},
1681
+ ...locale ? { inLanguage: locale } : {},
1682
+ ...image ? { image } : {},
1683
+ publisher
1684
+ } : {
1685
+ "@type": "WebSite",
1686
+ name: siteName,
1687
+ ...siteUrl ? { url: siteUrl } : {},
1688
+ publisher
1689
+ };
1690
+ const scripts = [
1691
+ {
1692
+ type: "application/ld+json",
1693
+ children: JSON.stringify({
1694
+ "@context": "https://schema.org",
1695
+ ...structuredData
1696
+ })
1697
+ }
1698
+ ];
1699
+ return { meta: tags, links, scripts };
1700
+ };
1701
+ var createSeo = (defaults) => (options) => seo({
1702
+ ...defaults,
1703
+ ...options
1704
+ });
1705
+
1597
1706
  // ../../src/lib/docs-core.tsx
1598
1707
  import { jsx as jsx14, jsxs as jsxs9, Fragment as Fragment3 } from "react/jsx-runtime";
1599
1708
  addCollection(lucideIcons);
@@ -1612,7 +1721,7 @@ var DocsFrontmatter = Schema2.Struct({
1612
1721
  path: Schema2.String,
1613
1722
  title: Schema2.String,
1614
1723
  description: Schema2.String,
1615
- icon: Schema2.String,
1724
+ icon: Schema2.optional(Schema2.String),
1616
1725
  order: Schema2.Number,
1617
1726
  locale: Schema2.String,
1618
1727
  section: DocsSection,
@@ -1701,7 +1810,7 @@ var validateDocsPages = (pages, config) => {
1701
1810
  const orders = new Set;
1702
1811
  const routeSlugs = new Set;
1703
1812
  for (const page of localized) {
1704
- if (!/^[a-z0-9-]+:[a-z0-9-]+$/.test(page.icon)) {
1813
+ if (page.icon && !/^[a-z0-9-]+:[a-z0-9-]+$/.test(page.icon)) {
1705
1814
  throw new Error(`${page.sourceFile} must use an Iconify icon name`);
1706
1815
  }
1707
1816
  if (config.matchesLocale && !config.matchesLocale(page.sourceFile, locale)) {
@@ -1795,6 +1904,12 @@ var makeDocs = (config) => {
1795
1904
  icon: "lucide:book-open",
1796
1905
  href: "/"
1797
1906
  };
1907
+ const docsSeo = createSeo({
1908
+ origin,
1909
+ locales: source.locales,
1910
+ ...config.defaultLocale ? { defaultLocale: config.defaultLocale } : {},
1911
+ siteName: config.siteName
1912
+ });
1798
1913
  const getMessages = (locale) => getDocsMessages(locale, config.messages?.(locale));
1799
1914
  const normalizeSearchText = (value) => value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
1800
1915
  const searchIndex = source.pages.flatMap((page) => {
@@ -1879,7 +1994,7 @@ var makeDocs = (config) => {
1879
1994
  }));
1880
1995
  };
1881
1996
  const url = (page, locale) => `${origin}/${locale}${page.path}`;
1882
- const editUrl = (page) => githubUrl ? `${githubUrl}/edit/${config.github?.branch ?? "main"}/${page.sourceFile}` : undefined;
1997
+ const editUrl = (page) => githubUrl && (config.editable?.(page) ?? true) ? `${githubUrl}/edit/${config.github?.branch ?? "main"}/${page.sourceFile}` : undefined;
1883
1998
  const getHead = ({
1884
1999
  locale,
1885
2000
  page
@@ -1888,32 +2003,13 @@ var makeDocs = (config) => {
1888
2003
  const path = page?.path ?? basePath;
1889
2004
  const title = `${page?.title ?? resolvedMessages.title} | ${config.siteName}`;
1890
2005
  const description = page?.description ?? resolvedMessages.description;
1891
- const canonical = page ? url(page, locale) : `${origin}/${locale}${path}`;
1892
- const defaultLocale = config.defaultLocale ?? source.locales[0] ?? locale;
1893
- return {
1894
- meta: [
1895
- { title },
1896
- { name: "description", content: description },
1897
- { property: "og:title", content: title },
1898
- { property: "og:description", content: description },
1899
- { property: "og:type", content: "article" },
1900
- { property: "og:url", content: canonical },
1901
- { property: "og:site_name", content: config.siteName }
1902
- ],
1903
- links: [
1904
- { rel: "canonical", href: canonical },
1905
- ...source.locales.map((alternateLocale) => ({
1906
- rel: "alternate",
1907
- hrefLang: alternateLocale,
1908
- href: `${origin}/${alternateLocale}${path}`
1909
- })),
1910
- {
1911
- rel: "alternate",
1912
- hrefLang: "x-default",
1913
- href: `${origin}/${defaultLocale}${path}`
1914
- }
1915
- ]
1916
- };
2006
+ return docsSeo({
2007
+ title,
2008
+ description,
2009
+ path,
2010
+ locale,
2011
+ type: "article"
2012
+ });
1917
2013
  };
1918
2014
  return {
1919
2015
  basePath,
@@ -2031,6 +2127,7 @@ var getDocsMessages = (locale, overrides) => ({
2031
2127
  ...overrides
2032
2128
  });
2033
2129
  var iconComponents = new Map;
2130
+ var EmptyIcon = forwardRef(() => null);
2034
2131
  var iconFor = (name) => {
2035
2132
  const existing = iconComponents.get(name);
2036
2133
  if (existing)
@@ -2255,11 +2352,13 @@ var DocsSearch = ({
2255
2352
  id: page.path,
2256
2353
  label: page.title,
2257
2354
  description: page.description,
2258
- icon: /* @__PURE__ */ jsx14(Icon, {
2259
- className: "size-4",
2260
- icon: page.icon,
2261
- ssr: true
2262
- }),
2355
+ ...page.icon ? {
2356
+ icon: /* @__PURE__ */ jsx14(Icon, {
2357
+ className: "size-4",
2358
+ icon: page.icon,
2359
+ ssr: true
2360
+ })
2361
+ } : {},
2263
2362
  onSelect: () => navigate({ to: page.path })
2264
2363
  })
2265
2364
  };
@@ -2291,7 +2390,7 @@ var DocsLayout = ({
2291
2390
  items: section.pages.map((item) => ({
2292
2391
  label: () => item.title,
2293
2392
  href: item.path,
2294
- icon: iconFor(item.icon)
2393
+ icon: item.icon ? iconFor(item.icon) : EmptyIcon
2295
2394
  }))
2296
2395
  }));
2297
2396
  if (resources) {
@@ -0,0 +1,88 @@
1
+ export type SeoOptions = {
2
+ title: string;
3
+ description?: string;
4
+ image?: string;
5
+ keywords?: string;
6
+ url?: string;
7
+ origin?: string;
8
+ path?: string;
9
+ locale?: string;
10
+ locales?: readonly string[];
11
+ defaultLocale?: string;
12
+ robots?: string;
13
+ siteName?: string;
14
+ twitterCreator?: string;
15
+ twitterSite?: string;
16
+ type?: "website" | "article";
17
+ sameAs?: readonly string[];
18
+ };
19
+ export type SeoDefaults = {
20
+ origin: string;
21
+ locales?: readonly string[];
22
+ defaultLocale?: string;
23
+ siteName?: string;
24
+ twitterCreator?: string;
25
+ twitterSite?: string;
26
+ sameAs?: readonly string[];
27
+ };
28
+ export type SeoPageOptions = Omit<SeoOptions, keyof SeoDefaults>;
29
+ export declare const seo: ({ title, description, image, keywords, url, origin, path, locale, locales, defaultLocale, robots, siteName, twitterCreator, twitterSite, type, sameAs, }: SeoOptions) => {
30
+ meta: ({
31
+ title: string;
32
+ name?: undefined;
33
+ property?: undefined;
34
+ content?: undefined;
35
+ } | {
36
+ title?: undefined;
37
+ name: string;
38
+ content: string | undefined;
39
+ property?: undefined;
40
+ } | {
41
+ title?: undefined;
42
+ name?: undefined;
43
+ property: string;
44
+ content: string | undefined;
45
+ })[];
46
+ links: ({
47
+ rel: string;
48
+ href: string;
49
+ } | {
50
+ rel: string;
51
+ hrefLang: string;
52
+ href: string;
53
+ })[];
54
+ scripts: {
55
+ type: string;
56
+ children: string;
57
+ }[];
58
+ };
59
+ export declare const createSeo: (defaults: SeoDefaults) => (options: SeoPageOptions) => {
60
+ meta: ({
61
+ title: string;
62
+ name?: undefined;
63
+ property?: undefined;
64
+ content?: undefined;
65
+ } | {
66
+ title?: undefined;
67
+ name: string;
68
+ content: string | undefined;
69
+ property?: undefined;
70
+ } | {
71
+ title?: undefined;
72
+ name?: undefined;
73
+ property: string;
74
+ content: string | undefined;
75
+ })[];
76
+ links: ({
77
+ rel: string;
78
+ href: string;
79
+ } | {
80
+ rel: string;
81
+ hrefLang: string;
82
+ href: string;
83
+ })[];
84
+ scripts: {
85
+ type: string;
86
+ children: string;
87
+ }[];
88
+ };
@@ -0,0 +1,104 @@
1
+ // ../../src/lib/seo.ts
2
+ var localizedUrl = (origin, locale, path) => `${origin.replace(/\/$/, "")}/${locale}${path === "/" ? "/" : path}`;
3
+ var seo = ({
4
+ title,
5
+ description,
6
+ image,
7
+ keywords,
8
+ url,
9
+ origin,
10
+ path = "/",
11
+ locale,
12
+ locales,
13
+ defaultLocale,
14
+ robots = "index, follow",
15
+ siteName = "KrakStack",
16
+ twitterCreator = "@krak",
17
+ twitterSite = "@krak",
18
+ type = "website",
19
+ sameAs
20
+ }) => {
21
+ const canonical = url ?? (origin && locale ? localizedUrl(origin, locale, path) : undefined);
22
+ const tags = [
23
+ { title },
24
+ { name: "description", content: description },
25
+ { name: "keywords", content: keywords },
26
+ { name: "robots", content: robots },
27
+ { name: "twitter:title", content: title },
28
+ { name: "twitter:description", content: description },
29
+ { name: "twitter:creator", content: twitterCreator },
30
+ { name: "twitter:site", content: twitterSite },
31
+ {
32
+ name: "twitter:card",
33
+ content: image ? "summary_large_image" : "summary"
34
+ },
35
+ { property: "og:type", content: type },
36
+ { property: "og:title", content: title },
37
+ { property: "og:description", content: description },
38
+ { property: "og:site_name", content: siteName },
39
+ { property: "og:url", content: canonical },
40
+ {
41
+ property: "og:locale",
42
+ content: locale === "fr" ? "fr_FR" : locale ? "en_US" : undefined
43
+ },
44
+ ...image ? [
45
+ { name: "twitter:image", content: image },
46
+ { property: "og:image", content: image }
47
+ ] : []
48
+ ].filter((tag) => !Object.hasOwn(tag, "content") || tag.content);
49
+ const alternateLocales = locales ?? [];
50
+ const links = canonical ? [
51
+ { rel: "canonical", href: canonical },
52
+ ...origin && alternateLocales.length > 0 ? alternateLocales.map((alternateLocale) => ({
53
+ rel: "alternate",
54
+ hrefLang: alternateLocale,
55
+ href: localizedUrl(origin, alternateLocale, path)
56
+ })) : [],
57
+ ...origin && alternateLocales.length > 0 ? [
58
+ {
59
+ rel: "alternate",
60
+ hrefLang: "x-default",
61
+ href: localizedUrl(origin, defaultLocale ?? alternateLocales[0] ?? "en", path)
62
+ }
63
+ ] : []
64
+ ] : [];
65
+ const siteUrl = origin?.replace(/\/$/, "") ?? canonical;
66
+ const publisher = {
67
+ "@type": "Organization",
68
+ name: siteName,
69
+ ...siteUrl ? { url: siteUrl } : {},
70
+ ...sameAs?.length ? { sameAs } : {}
71
+ };
72
+ const structuredData = type === "article" ? {
73
+ "@type": "Article",
74
+ headline: title,
75
+ description,
76
+ ...canonical ? { url: canonical } : {},
77
+ ...locale ? { inLanguage: locale } : {},
78
+ ...image ? { image } : {},
79
+ publisher
80
+ } : {
81
+ "@type": "WebSite",
82
+ name: siteName,
83
+ ...siteUrl ? { url: siteUrl } : {},
84
+ publisher
85
+ };
86
+ const scripts = [
87
+ {
88
+ type: "application/ld+json",
89
+ children: JSON.stringify({
90
+ "@context": "https://schema.org",
91
+ ...structuredData
92
+ })
93
+ }
94
+ ];
95
+ return { meta: tags, links, scripts };
96
+ };
97
+ var createSeo = (defaults) => (options) => seo({
98
+ ...defaults,
99
+ ...options
100
+ });
101
+ export {
102
+ seo,
103
+ createSeo
104
+ };
@@ -927,6 +927,14 @@ var routeStrategies = [
927
927
  {
928
928
  match: "/api/:path(.*)?",
929
929
  exclude: true
930
+ },
931
+ {
932
+ match: "/sitemap.xml",
933
+ exclude: true
934
+ },
935
+ {
936
+ match: "/llms.txt",
937
+ exclude: true
930
938
  }
931
939
  ];
932
940
  var urlPatterns = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krak-stack/registry",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Tree-shakable KrakStack components and Effect services.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -60,6 +60,10 @@
60
60
  "types": "./dist/lib/query.d.ts",
61
61
  "import": "./dist/lib/query.js"
62
62
  },
63
+ "./seo": {
64
+ "types": "./dist/lib/seo.d.ts",
65
+ "import": "./dist/lib/seo.js"
66
+ },
63
67
  "./app-brand": {
64
68
  "types": "./dist/components/ui/app-brand.d.ts",
65
69
  "import": "./dist/components/ui/app-brand.js"
@@ -160,14 +164,6 @@
160
164
  "types": "./dist/services/s3/schema.d.ts",
161
165
  "import": "./dist/services/s3/schema.js"
162
166
  },
163
- "./service-opentelemetry": {
164
- "types": "./dist/services/opentelemetry.d.ts",
165
- "import": "./dist/services/opentelemetry.js"
166
- },
167
- "./embedding-layer": {
168
- "types": "./dist/services/embedding.d.ts",
169
- "import": "./dist/services/embedding.js"
170
- },
171
167
  "./tailwind.css": "./tailwind.css",
172
168
  "./package.json": "./package.json"
173
169
  },
@@ -184,7 +180,6 @@
184
180
  "@dnd-kit/core": "^6.3.1",
185
181
  "@dnd-kit/sortable": "^10.0.0",
186
182
  "@dnd-kit/utilities": "^3.2.2",
187
- "@effect/ai-openai-compat": "4.0.0-beta.85",
188
183
  "@effect/atom-react": "4.0.0-beta.85",
189
184
  "@effect/platform-browser": "4.0.0-beta.85",
190
185
  "@iconify-json/lucide": "^1.2.83",
@@ -222,9 +217,6 @@
222
217
  "@dnd-kit/utilities": {
223
218
  "optional": true
224
219
  },
225
- "@effect/ai-openai-compat": {
226
- "optional": true
227
- },
228
220
  "@effect/atom-react": {
229
221
  "optional": true
230
222
  },
@@ -1,2 +0,0 @@
1
- import { Config, Layer } from "effect";
2
- export declare const EmbeddingLayer: Layer.Layer<import("effect/unstable/ai/EmbeddingModel").EmbeddingModel, Config.ConfigError, never>;
@@ -1,23 +0,0 @@
1
- // ../../src/services/embedding.ts
2
- import { OpenAiClient, OpenAiEmbeddingModel } from "@effect/ai-openai-compat";
3
- import { Config, Effect, Layer, Redacted } from "effect";
4
- import { FetchHttpClient } from "effect/unstable/http";
5
- var EmbeddingLayer = Layer.unwrap(Effect.gen(function* () {
6
- const apiUrl = yield* Config.string("EMBEDDINGS_URL");
7
- const embeddingModel = yield* Config.string("EMBEDDINGS_MODEL");
8
- const embeddingDimensions = yield* Config.number("EMBEDDINGS_DIMENSIONS");
9
- const embeddingClientLayer = OpenAiClient.layer({
10
- apiKey: Redacted.make("embedding"),
11
- apiUrl
12
- });
13
- return OpenAiEmbeddingModel.layer({
14
- model: embeddingModel,
15
- config: {
16
- dimensions: embeddingDimensions,
17
- encoding_format: "float"
18
- }
19
- }).pipe(Layer.provide(embeddingClientLayer), Layer.provide(FetchHttpClient.layer));
20
- }));
21
- export {
22
- EmbeddingLayer
23
- };
@@ -1,8 +0,0 @@
1
- import { Config, Effect, Layer, Context } from "effect";
2
- declare const OpenTelemetry_base: Context.ServiceClass<OpenTelemetry, "OpenTelemetry", void> & {
3
- readonly make: Effect.Effect<void, never, never>;
4
- };
5
- export declare class OpenTelemetry extends OpenTelemetry_base {
6
- static readonly layer: Layer.Layer<OpenTelemetry, Config.ConfigError, never>;
7
- }
8
- export {};
@@ -1,23 +0,0 @@
1
- // ../../src/services/opentelemetry.ts
2
- import { FetchHttpClient } from "effect/unstable/http";
3
- import { Otlp, OtlpSerialization } from "effect/unstable/observability";
4
- import { Config, Effect, Layer, Context } from "effect";
5
- var OtelLive = Layer.unwrap(Effect.gen(function* () {
6
- const serviceName = yield* Config.string("OTEL_SERVICE_NAME").pipe(Config.withDefault("app"));
7
- const otlpEndpoint = yield* Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.withDefault("http://localhost:4318"));
8
- return Otlp.layer({
9
- baseUrl: otlpEndpoint,
10
- resource: {
11
- serviceName
12
- }
13
- }).pipe(Layer.provide(OtlpSerialization.layerJson), Layer.provide(FetchHttpClient.layer));
14
- }));
15
-
16
- class OpenTelemetry extends Context.Service()("OpenTelemetry", {
17
- make: Effect.log("OpenTelemetry initialized")
18
- }) {
19
- static layer = Layer.effect(this, this.make).pipe(Layer.provideMerge(OtelLive));
20
- }
21
- export {
22
- OpenTelemetry
23
- };