@cossistant/react 0.0.19 → 0.0.22

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 (101) hide show
  1. package/conversation.d.ts +28 -0
  2. package/conversation.d.ts.map +1 -1
  3. package/hooks/index.d.ts +4 -1
  4. package/hooks/index.js +4 -1
  5. package/hooks/private/use-default-messages.js +1 -1
  6. package/hooks/private/use-default-messages.js.map +1 -1
  7. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  8. package/hooks/private/use-grouped-messages.js +4 -18
  9. package/hooks/private/use-grouped-messages.js.map +1 -1
  10. package/hooks/private/use-rest-client.js +1 -1
  11. package/hooks/private/use-rest-client.js.map +1 -1
  12. package/hooks/private/use-visitor-typing-reporter.js +3 -3
  13. package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
  14. package/hooks/use-conversation-auto-seen.d.ts +1 -1
  15. package/hooks/use-conversation-auto-seen.js +30 -46
  16. package/hooks/use-conversation-auto-seen.js.map +1 -1
  17. package/hooks/use-conversation-page.js +1 -1
  18. package/hooks/use-conversation-page.js.map +1 -1
  19. package/hooks/use-conversation-seen.d.ts.map +1 -1
  20. package/hooks/use-conversation-seen.js +7 -3
  21. package/hooks/use-conversation-seen.js.map +1 -1
  22. package/hooks/use-new-message-sound.d.ts +23 -0
  23. package/hooks/use-new-message-sound.d.ts.map +1 -0
  24. package/hooks/use-new-message-sound.js +34 -0
  25. package/hooks/use-new-message-sound.js.map +1 -0
  26. package/hooks/use-send-message.js +1 -1
  27. package/hooks/use-send-message.js.map +1 -1
  28. package/hooks/use-sound-effect.d.ts +30 -0
  29. package/hooks/use-sound-effect.d.ts.map +1 -0
  30. package/hooks/use-sound-effect.js +104 -0
  31. package/hooks/use-sound-effect.js.map +1 -0
  32. package/hooks/use-typing-sound.d.ts +18 -0
  33. package/hooks/use-typing-sound.d.ts.map +1 -0
  34. package/hooks/use-typing-sound.js +38 -0
  35. package/hooks/use-typing-sound.js.map +1 -0
  36. package/index.d.ts +5 -2
  37. package/index.js +8 -6
  38. package/package.json +3 -3
  39. package/primitives/avatar/image.d.ts +1 -1
  40. package/primitives/bubble.js +1 -1
  41. package/primitives/index.d.ts +3 -5
  42. package/primitives/index.js +3 -9
  43. package/primitives/index.parts.d.ts +2 -4
  44. package/primitives/index.parts.js +2 -4
  45. package/primitives/router.d.ts +19 -20
  46. package/primitives/router.d.ts.map +1 -1
  47. package/primitives/router.js +17 -11
  48. package/primitives/router.js.map +1 -1
  49. package/realtime/index.js +1 -1
  50. package/realtime/provider.d.ts +1 -0
  51. package/realtime/provider.d.ts.map +1 -1
  52. package/realtime/provider.js +59 -10
  53. package/realtime/provider.js.map +1 -1
  54. package/realtime-events.d.ts +14 -0
  55. package/realtime-events.d.ts.map +1 -1
  56. package/schemas3.d.ts +7 -0
  57. package/schemas3.d.ts.map +1 -1
  58. package/support/components/bubble.d.ts.map +1 -1
  59. package/support/components/bubble.js +27 -4
  60. package/support/components/bubble.js.map +1 -1
  61. package/support/components/conversation-event.js +1 -1
  62. package/support/components/conversation-event.js.map +1 -1
  63. package/support/components/conversation-timeline.d.ts.map +1 -1
  64. package/support/components/conversation-timeline.js +5 -0
  65. package/support/components/conversation-timeline.js.map +1 -1
  66. package/support/components/support-content.d.ts +2 -0
  67. package/support/components/support-content.d.ts.map +1 -1
  68. package/support/components/support-content.js +5 -2
  69. package/support/components/support-content.js.map +1 -1
  70. package/support/components/timeline-message-group.js +2 -2
  71. package/support/components/timeline-message-group.js.map +1 -1
  72. package/support/components/timeline-message-item.js +2 -2
  73. package/support/components/timeline-message-item.js.map +1 -1
  74. package/support/components/typing-indicator.d.ts.map +1 -1
  75. package/support/index.d.ts +12 -7
  76. package/support/index.d.ts.map +1 -1
  77. package/support/index.js +28 -29
  78. package/support/index.js.map +1 -1
  79. package/support/pages/conversation.d.ts.map +1 -1
  80. package/support/pages/conversation.js +19 -1
  81. package/support/pages/conversation.js.map +1 -1
  82. package/support/router.d.ts +19 -9
  83. package/support/router.d.ts.map +1 -1
  84. package/support/router.js +31 -30
  85. package/support/router.js.map +1 -1
  86. package/support/text/runtime.js +1 -1
  87. package/support/text/runtime.js.map +1 -1
  88. package/support/utils/time.d.ts +1 -0
  89. package/support/utils/time.d.ts.map +1 -1
  90. package/support/utils/time.js +2 -0
  91. package/support/utils/time.js.map +1 -1
  92. package/timeline-item.d.ts +14 -0
  93. package/timeline-item.d.ts.map +1 -1
  94. package/primitives/page-registry.d.ts +0 -30
  95. package/primitives/page-registry.d.ts.map +0 -1
  96. package/primitives/page-registry.js +0 -45
  97. package/primitives/page-registry.js.map +0 -1
  98. package/primitives/page.d.ts +0 -21
  99. package/primitives/page.d.ts.map +0 -1
  100. package/primitives/page.js +0 -18
  101. package/primitives/page.js.map +0 -1
package/support/router.js CHANGED
@@ -1,4 +1,3 @@
1
- import { Page } from "../primitives/page.js";
2
1
  import { Router } from "../primitives/router.js";
3
2
  import { useSupportNavigation } from "./store/support-store.js";
4
3
  import { ArticlesPage } from "./pages/articles.js";
@@ -10,39 +9,41 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
9
  //#region src/support/router.tsx
11
10
  /**
12
11
  * Router with default support pages (HOME, ARTICLES, CONVERSATION, CONVERSATION_HISTORY).
13
- * Add custom pages as children.
12
+ * Add custom pages via customPages prop.
14
13
  *
15
14
  * @example
16
- * <SupportRouter>
17
- * <Page name="SETTINGS" component={SettingsPage} />
18
- * </SupportRouter>
15
+ * <SupportRouter
16
+ * customPages={[
17
+ * { name: "SETTINGS", component: SettingsPage }
18
+ * ]}
19
+ * />
19
20
  */
20
- const SupportRouter = ({ children }) => {
21
+ const SupportRouter = ({ customPages = [], children }) => {
21
22
  const { current } = useSupportNavigation();
22
- return /* @__PURE__ */ jsxs(Fragment, { children: [
23
- /* @__PURE__ */ jsx(Page, {
24
- component: HomePage,
25
- name: "HOME"
26
- }),
27
- /* @__PURE__ */ jsx(Page, {
28
- component: ArticlesPage,
29
- name: "ARTICLES"
30
- }),
31
- /* @__PURE__ */ jsx(Page, {
32
- component: ConversationPage,
33
- name: "CONVERSATION"
34
- }),
35
- /* @__PURE__ */ jsx(Page, {
36
- component: ConversationHistoryPage,
37
- name: "CONVERSATION_HISTORY"
38
- }),
39
- children,
40
- /* @__PURE__ */ jsx(Router, {
41
- fallback: HomePage,
42
- page: current.page,
43
- params: current.params
44
- })
45
- ] });
23
+ const allPages = [...[
24
+ {
25
+ name: "HOME",
26
+ component: HomePage
27
+ },
28
+ {
29
+ name: "ARTICLES",
30
+ component: ArticlesPage
31
+ },
32
+ {
33
+ name: "CONVERSATION",
34
+ component: ConversationPage
35
+ },
36
+ {
37
+ name: "CONVERSATION_HISTORY",
38
+ component: ConversationHistoryPage
39
+ }
40
+ ], ...customPages];
41
+ return /* @__PURE__ */ jsxs(Fragment, { children: [children, /* @__PURE__ */ jsx(Router, {
42
+ fallback: HomePage,
43
+ page: current.page,
44
+ pages: allPages,
45
+ params: current.params
46
+ })] });
46
47
  };
47
48
 
48
49
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","names":["SupportRouter: React.FC<{ children?: React.ReactNode }>","Primitive.Page","Primitive.Router"],"sources":["../../src/support/router.tsx"],"sourcesContent":["import type React from \"react\";\nimport * as Primitive from \"../primitives\";\nimport { ArticlesPage } from \"./pages/articles\";\nimport { ConversationPage } from \"./pages/conversation\";\nimport { ConversationHistoryPage } from \"./pages/conversation-history\";\nimport { HomePage } from \"./pages/home\";\nimport { useSupportNavigation } from \"./store/support-store\";\n\n/**\n * Router with default support pages (HOME, ARTICLES, CONVERSATION, CONVERSATION_HISTORY).\n * Add custom pages as children.\n *\n * @example\n * <SupportRouter>\n * <Page name=\"SETTINGS\" component={SettingsPage} />\n * </SupportRouter>\n */\nexport const SupportRouter: React.FC<{ children?: React.ReactNode }> = ({\n\tchildren,\n}) => {\n\tconst { current } = useSupportNavigation();\n\n\treturn (\n\t\t<>\n\t\t\t{/* Register default pages */}\n\t\t\t<Primitive.Page\n\t\t\t\tcomponent={HomePage as React.ComponentType<{ params?: unknown }>}\n\t\t\t\tname=\"HOME\"\n\t\t\t/>\n\t\t\t<Primitive.Page\n\t\t\t\tcomponent={ArticlesPage as React.ComponentType<{ params?: unknown }>}\n\t\t\t\tname=\"ARTICLES\"\n\t\t\t/>\n\t\t\t<Primitive.Page\n\t\t\t\tcomponent={\n\t\t\t\t\tConversationPage as React.ComponentType<{ params?: unknown }>\n\t\t\t\t}\n\t\t\t\tname=\"CONVERSATION\"\n\t\t\t/>\n\t\t\t<Primitive.Page\n\t\t\t\tcomponent={\n\t\t\t\t\tConversationHistoryPage as React.ComponentType<{ params?: unknown }>\n\t\t\t\t}\n\t\t\t\tname=\"CONVERSATION_HISTORY\"\n\t\t\t/>\n\n\t\t\t{/* Allow custom pages via children */}\n\t\t\t{children}\n\n\t\t\t{/* Render using primitive router */}\n\t\t\t<Primitive.Router\n\t\t\t\tfallback={HomePage as React.ComponentType<{ params?: unknown }>}\n\t\t\t\tpage={current.page as string}\n\t\t\t\tparams={current.params}\n\t\t\t/>\n\t\t</>\n\t);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,MAAaA,iBAA2D,EACvE,eACK;CACL,MAAM,EAAE,YAAY,sBAAsB;AAE1C,QACC;EAEC,oBAACC;GACA,WAAW;GACX,MAAK;IACJ;EACF,oBAACA;GACA,WAAW;GACX,MAAK;IACJ;EACF,oBAACA;GACA,WACC;GAED,MAAK;IACJ;EACF,oBAACA;GACA,WACC;GAED,MAAK;IACJ;EAGD;EAGD,oBAACC;GACA,UAAU;GACV,MAAM,QAAQ;GACd,QAAQ,QAAQ;IACf;KACA"}
1
+ {"version":3,"file":"router.js","names":["SupportRouter: React.FC<SupportRouterProps>","Primitive.Router"],"sources":["../../src/support/router.tsx"],"sourcesContent":["import type { RouteRegistry } from \"@cossistant/core\";\nimport type React from \"react\";\nimport type { PageDefinition } from \"../primitives\";\nimport * as Primitive from \"../primitives\";\nimport { ArticlesPage } from \"./pages/articles\";\nimport { ConversationPage } from \"./pages/conversation\";\nimport { ConversationHistoryPage } from \"./pages/conversation-history\";\nimport { HomePage } from \"./pages/home\";\nimport { useSupportNavigation } from \"./store/support-store\";\n\n// Type for custom pages that ensures they match RouteRegistry\nexport type CustomPage<K extends keyof RouteRegistry = keyof RouteRegistry> = {\n\tname: K;\n\tcomponent: React.ComponentType<{ params?: RouteRegistry[K] }>;\n};\n\nexport type SupportRouterProps = {\n\tcustomPages?: CustomPage[];\n\tchildren?: React.ReactNode;\n};\n\n/**\n * Router with default support pages (HOME, ARTICLES, CONVERSATION, CONVERSATION_HISTORY).\n * Add custom pages via customPages prop.\n *\n * @example\n * <SupportRouter\n * customPages={[\n * { name: \"SETTINGS\", component: SettingsPage }\n * ]}\n * />\n */\nexport const SupportRouter: React.FC<SupportRouterProps> = ({\n\tcustomPages = [],\n\tchildren,\n}) => {\n\tconst { current } = useSupportNavigation();\n\n\t// Define all pages with proper typing\n\tconst builtInPages = [\n\t\t{\n\t\t\tname: \"HOME\",\n\t\t\tcomponent: HomePage,\n\t\t},\n\t\t{\n\t\t\tname: \"ARTICLES\",\n\t\t\tcomponent: ArticlesPage,\n\t\t},\n\t\t{\n\t\t\tname: \"CONVERSATION\",\n\t\t\tcomponent: ConversationPage,\n\t\t},\n\t\t{\n\t\t\tname: \"CONVERSATION_HISTORY\",\n\t\t\tcomponent: ConversationHistoryPage,\n\t\t},\n\t] as PageDefinition<keyof RouteRegistry>[];\n\n\t// Combine built-in and custom pages\n\tconst allPages = [...builtInPages, ...customPages] as PageDefinition<\n\t\tkeyof RouteRegistry\n\t>[];\n\n\treturn (\n\t\t<>\n\t\t\t{children}\n\t\t\t<Primitive.Router\n\t\t\t\tfallback={HomePage as React.ComponentType<{ params?: unknown }>}\n\t\t\t\tpage={current.page}\n\t\t\t\tpages={allPages}\n\t\t\t\tparams={current.params}\n\t\t\t/>\n\t\t</>\n\t);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,MAAaA,iBAA+C,EAC3D,cAAc,EAAE,EAChB,eACK;CACL,MAAM,EAAE,YAAY,sBAAsB;CAuB1C,MAAM,WAAW,CAAC,GApBG;EACpB;GACC,MAAM;GACN,WAAW;GACX;EACD;GACC,MAAM;GACN,WAAW;GACX;EACD;GACC,MAAM;GACN,WAAW;GACX;EACD;GACC,MAAM;GACN,WAAW;GACX;EACD,EAGkC,GAAG,YAAY;AAIlD,QACC,4CACE,UACD,oBAACC;EACA,UAAU;EACV,MAAM,QAAQ;EACd,OAAO;EACP,QAAQ,QAAQ;GACf,IACA"}
@@ -70,7 +70,7 @@ function createTextUtils(locale, isHydrated = false) {
70
70
  return value.charAt(0).toUpperCase() + value.slice(1);
71
71
  },
72
72
  timeOfDay: () => {
73
- if (!isHydrated) return {
73
+ if (!isHydrated || typeof window === "undefined") return {
74
74
  token: "morning",
75
75
  label: dayPeriodLabels.morning
76
76
  };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","names":["BUILTIN_LOCALES: Record<SupportLocale, SupportLocaleMessages>","TIME_OF_DAY_THRESHOLDS: Array<{\n\ttoken: SupportTimeOfDayToken;\n\thour: number;\n}>","fallback: Record<SupportTimeOfDayToken, string>","labels: Partial<Record<SupportTimeOfDayToken, string>>","token: SupportTimeOfDayToken","chain: string[]","map: NormalizedOverrides"],"sources":["../../../src/support/text/runtime.ts"],"sourcesContent":["/** biome-ignore-all lint/nursery/useMaxParams: ok here */\nimport en from \"./locales/en\";\nimport es from \"./locales/es\";\nimport fr from \"./locales/fr\";\nimport type {\n\tSupportLocale,\n\tSupportLocaleMessages,\n\tSupportTextContentOverrides,\n\tSupportTextContext,\n\tSupportTextKey,\n\tSupportTextUtils,\n\tSupportTextVariables,\n\tSupportTimeOfDayToken,\n} from \"./locales/keys\";\n\nexport type NormalizedOverride<K extends SupportTextKey> = {\n\tanyLocale?: SupportLocaleMessages[K];\n\tbyLocale: Map<string, SupportLocaleMessages[K]>;\n};\n\nexport type NormalizedOverrides = Map<\n\tSupportTextKey,\n\tNormalizedOverride<SupportTextKey>\n>;\n\nexport const BUILTIN_LOCALES: Record<SupportLocale, SupportLocaleMessages> = {\n\ten,\n\tfr,\n\tes,\n};\n\nconst TIME_OF_DAY_THRESHOLDS: Array<{\n\ttoken: SupportTimeOfDayToken;\n\thour: number;\n}> = [\n\t{ token: \"morning\", hour: 9 },\n\t{ token: \"afternoon\", hour: 15 },\n\t{ token: \"evening\", hour: 20 },\n];\n\nfunction buildDayPeriodLabels(\n\tlocale: string\n): Record<SupportTimeOfDayToken, string> {\n\tconst fallback: Record<SupportTimeOfDayToken, string> = {\n\t\tmorning: \"morning\",\n\t\tafternoon: \"afternoon\",\n\t\tevening: \"evening\",\n\t};\n\n\ttry {\n\t\tconst formatter = new Intl.DateTimeFormat(locale, {\n\t\t\thour: \"numeric\",\n\t\t\thour12: true,\n\t\t});\n\n\t\tconst labels: Partial<Record<SupportTimeOfDayToken, string>> = {};\n\t\tfor (const { token, hour } of TIME_OF_DAY_THRESHOLDS) {\n\t\t\tconst parts = formatter.formatToParts(new Date(2020, 0, 1, hour));\n\t\t\tconst part = parts.find((segment) => segment.type === \"dayPeriod\");\n\t\t\tif (part?.value) {\n\t\t\t\tconst normalized = part.value.trim();\n\t\t\t\tif (normalized) {\n\t\t\t\t\tlabels[token] = normalized;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmorning: labels.morning ?? fallback.morning,\n\t\t\tafternoon: labels.afternoon ?? fallback.afternoon,\n\t\t\tevening: labels.evening ?? fallback.evening,\n\t\t};\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\n/**\n * Builds formatting helpers tailored for the visitor locale. The utilities are\n * memoized by callers and include number formatting, pluralization, title\n * casing and dynamic time-of-day descriptions.\n */\nexport function createTextUtils(\n\tlocale: string,\n\tisHydrated = false\n): SupportTextUtils {\n\tconst numberFormatter = new Intl.NumberFormat(locale);\n\tconst pluralRules = new Intl.PluralRules(locale);\n\tconst dayPeriodLabels = buildDayPeriodLabels(locale);\n\n\treturn {\n\t\tformatNumber: (value: number, options?: Intl.NumberFormatOptions) =>\n\t\t\toptions\n\t\t\t\t? new Intl.NumberFormat(locale, options).format(value)\n\t\t\t\t: numberFormatter.format(value),\n\t\tpluralize: (count: number, options: { one: string; other: string }) => {\n\t\t\tconst rule = pluralRules.select(count);\n\t\t\treturn rule === \"one\" ? options.one : options.other;\n\t\t},\n\t\ttitleCase: (value: string) => {\n\t\t\tif (!value) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\treturn value.charAt(0).toUpperCase() + value.slice(1);\n\t\t},\n\t\ttimeOfDay: () => {\n\t\t\t// Return a stable default during SSR to avoid hydration mismatches\n\t\t\tif (!isHydrated) {\n\t\t\t\treturn {\n\t\t\t\t\ttoken: \"morning\" as SupportTimeOfDayToken,\n\t\t\t\t\tlabel: dayPeriodLabels.morning,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst hour = new Date().getHours();\n\t\t\tlet token: SupportTimeOfDayToken;\n\t\t\tif (hour < 12) {\n\t\t\t\ttoken = \"morning\";\n\t\t\t} else if (hour < 18) {\n\t\t\t\ttoken = \"afternoon\";\n\t\t\t} else {\n\t\t\t\ttoken = \"evening\";\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttoken,\n\t\t\t\tlabel: dayPeriodLabels[token],\n\t\t\t};\n\t\t},\n\t};\n}\n\n/**\n * Normalize a locale string to its base language code\n * Examples:\n * - \"en-US\" -> \"en\"\n * - \"en-GB\" -> \"en\"\n * - \"fr-FR\" -> \"fr\"\n */\nfunction normalizeLocaleString(locale: string): string {\n\tconst [base] = locale.toLowerCase().split(\"-\");\n\treturn base || locale.toLowerCase();\n}\n\n/**\n * Derives the locale preference order from visitor/provider hints while\n * guaranteeing an English fallback.\n */\nexport function buildLocaleChain(\n\tpreferences: Array<string | null | undefined>\n): string[] {\n\tconst seen = new Set<string>();\n\tconst chain: string[] = [];\n\n\tconst pushLocale = (value: string) => {\n\t\t// Always normalize to base language (en-US -> en, en-GB -> en)\n\t\tconst normalized = normalizeLocaleString(value);\n\t\tif (!seen.has(normalized)) {\n\t\t\tseen.add(normalized);\n\t\t\tchain.push(normalized);\n\t\t}\n\t};\n\n\tfor (const candidate of preferences) {\n\t\tif (!candidate) {\n\t\t\tcontinue;\n\t\t}\n\t\tpushLocale(candidate);\n\t}\n\n\t// Always fallback to English\n\tif (!seen.has(\"en\")) {\n\t\tchain.push(\"en\");\n\t}\n\n\treturn chain;\n}\n\n/**\n * Canonicalizes text override definitions into a lookup map that can be\n * consumed efficiently at runtime.\n */\nexport function normalizeOverrides(\n\toverrides?: SupportTextContentOverrides<string>\n): NormalizedOverrides {\n\tconst map: NormalizedOverrides = new Map();\n\n\tif (!overrides) {\n\t\treturn map;\n\t}\n\n\tfor (const key of Object.keys(overrides) as SupportTextKey[]) {\n\t\tconst value = overrides[key];\n\t\tif (!value) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof value === \"string\" || typeof value === \"function\") {\n\t\t\tmap.set(key, {\n\t\t\t\tanyLocale: value as SupportLocaleMessages[typeof key],\n\t\t\t\tbyLocale: new Map(),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst byLocale = new Map<string, SupportLocaleMessages[typeof key]>();\n\t\tfor (const [locale, localizedValue] of Object.entries(value)) {\n\t\t\tif (!localizedValue) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbyLocale.set(\n\t\t\t\tlocale.toLowerCase(),\n\t\t\t\tlocalizedValue as SupportLocaleMessages[typeof key]\n\t\t\t);\n\t\t}\n\n\t\tmap.set(key, { byLocale });\n\t}\n\n\treturn map;\n}\n\n/**\n * Finds the best matching localized string for a key, consulting overrides\n * before bundled locale dictionaries.\n */\nexport function resolveMessage<K extends SupportTextKey>(\n\tkey: K,\n\tlocaleChain: string[],\n\toverrides: NormalizedOverrides\n): SupportLocaleMessages[K] {\n\tconst override = overrides.get(key) as NormalizedOverride<K> | undefined;\n\tif (override) {\n\t\tfor (const locale of localeChain) {\n\t\t\tconst localized = override.byLocale.get(locale);\n\t\t\tif (localized) {\n\t\t\t\treturn localized;\n\t\t\t}\n\t\t}\n\t\tif (override.anyLocale) {\n\t\t\treturn override.anyLocale;\n\t\t}\n\t}\n\n\tfor (const locale of localeChain) {\n\t\tif (locale in BUILTIN_LOCALES) {\n\t\t\treturn BUILTIN_LOCALES[locale as SupportLocale][key];\n\t\t}\n\t}\n\n\treturn BUILTIN_LOCALES.en[key];\n}\n\n/**\n * Produces the final rendered string by executing function overrides or\n * interpolating variables into template literals.\n */\nexport function evaluateMessage<K extends SupportTextKey>(\n\tkey: K,\n\tmessage: SupportLocaleMessages[K],\n\tvariables: SupportTextVariables<K> | undefined,\n\tcontext: SupportTextContext,\n\tutils: SupportTextUtils\n): string {\n\tif (typeof message === \"function\") {\n\t\treturn message({\n\t\t\tvariables: variables as never,\n\t\t\tcontext,\n\t\t\tutils,\n\t\t});\n\t}\n\n\treturn message;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","names":["BUILTIN_LOCALES: Record<SupportLocale, SupportLocaleMessages>","TIME_OF_DAY_THRESHOLDS: Array<{\n\ttoken: SupportTimeOfDayToken;\n\thour: number;\n}>","fallback: Record<SupportTimeOfDayToken, string>","labels: Partial<Record<SupportTimeOfDayToken, string>>","token: SupportTimeOfDayToken","chain: string[]","map: NormalizedOverrides"],"sources":["../../../src/support/text/runtime.ts"],"sourcesContent":["/** biome-ignore-all lint/nursery/useMaxParams: ok here */\nimport en from \"./locales/en\";\nimport es from \"./locales/es\";\nimport fr from \"./locales/fr\";\nimport type {\n\tSupportLocale,\n\tSupportLocaleMessages,\n\tSupportTextContentOverrides,\n\tSupportTextContext,\n\tSupportTextKey,\n\tSupportTextUtils,\n\tSupportTextVariables,\n\tSupportTimeOfDayToken,\n} from \"./locales/keys\";\n\nexport type NormalizedOverride<K extends SupportTextKey> = {\n\tanyLocale?: SupportLocaleMessages[K];\n\tbyLocale: Map<string, SupportLocaleMessages[K]>;\n};\n\nexport type NormalizedOverrides = Map<\n\tSupportTextKey,\n\tNormalizedOverride<SupportTextKey>\n>;\n\nexport const BUILTIN_LOCALES: Record<SupportLocale, SupportLocaleMessages> = {\n\ten,\n\tfr,\n\tes,\n};\n\nconst TIME_OF_DAY_THRESHOLDS: Array<{\n\ttoken: SupportTimeOfDayToken;\n\thour: number;\n}> = [\n\t{ token: \"morning\", hour: 9 },\n\t{ token: \"afternoon\", hour: 15 },\n\t{ token: \"evening\", hour: 20 },\n];\n\nfunction buildDayPeriodLabels(\n\tlocale: string\n): Record<SupportTimeOfDayToken, string> {\n\tconst fallback: Record<SupportTimeOfDayToken, string> = {\n\t\tmorning: \"morning\",\n\t\tafternoon: \"afternoon\",\n\t\tevening: \"evening\",\n\t};\n\n\ttry {\n\t\tconst formatter = new Intl.DateTimeFormat(locale, {\n\t\t\thour: \"numeric\",\n\t\t\thour12: true,\n\t\t});\n\n\t\tconst labels: Partial<Record<SupportTimeOfDayToken, string>> = {};\n\t\tfor (const { token, hour } of TIME_OF_DAY_THRESHOLDS) {\n\t\t\tconst parts = formatter.formatToParts(new Date(2020, 0, 1, hour));\n\t\t\tconst part = parts.find((segment) => segment.type === \"dayPeriod\");\n\t\t\tif (part?.value) {\n\t\t\t\tconst normalized = part.value.trim();\n\t\t\t\tif (normalized) {\n\t\t\t\t\tlabels[token] = normalized;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmorning: labels.morning ?? fallback.morning,\n\t\t\tafternoon: labels.afternoon ?? fallback.afternoon,\n\t\t\tevening: labels.evening ?? fallback.evening,\n\t\t};\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\n/**\n * Builds formatting helpers tailored for the visitor locale. The utilities are\n * memoized by callers and include number formatting, pluralization, title\n * casing and dynamic time-of-day descriptions.\n */\nexport function createTextUtils(\n\tlocale: string,\n\tisHydrated = false\n): SupportTextUtils {\n\tconst numberFormatter = new Intl.NumberFormat(locale);\n\tconst pluralRules = new Intl.PluralRules(locale);\n\tconst dayPeriodLabels = buildDayPeriodLabels(locale);\n\n\treturn {\n\t\tformatNumber: (value: number, options?: Intl.NumberFormatOptions) =>\n\t\t\toptions\n\t\t\t\t? new Intl.NumberFormat(locale, options).format(value)\n\t\t\t\t: numberFormatter.format(value),\n\t\tpluralize: (count: number, options: { one: string; other: string }) => {\n\t\t\tconst rule = pluralRules.select(count);\n\t\t\treturn rule === \"one\" ? options.one : options.other;\n\t\t},\n\t\ttitleCase: (value: string) => {\n\t\t\tif (!value) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\treturn value.charAt(0).toUpperCase() + value.slice(1);\n\t\t},\n\t\ttimeOfDay: () => {\n\t\t\t// Return a stable default during SSR to avoid hydration mismatches\n\t\t\tif (!isHydrated || typeof window === \"undefined\") {\n\t\t\t\treturn {\n\t\t\t\t\ttoken: \"morning\" as SupportTimeOfDayToken,\n\t\t\t\t\tlabel: dayPeriodLabels.morning,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst hour = new Date().getHours();\n\t\t\tlet token: SupportTimeOfDayToken;\n\t\t\tif (hour < 12) {\n\t\t\t\ttoken = \"morning\";\n\t\t\t} else if (hour < 18) {\n\t\t\t\ttoken = \"afternoon\";\n\t\t\t} else {\n\t\t\t\ttoken = \"evening\";\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttoken,\n\t\t\t\tlabel: dayPeriodLabels[token],\n\t\t\t};\n\t\t},\n\t};\n}\n\n/**\n * Normalize a locale string to its base language code\n * Examples:\n * - \"en-US\" -> \"en\"\n * - \"en-GB\" -> \"en\"\n * - \"fr-FR\" -> \"fr\"\n */\nfunction normalizeLocaleString(locale: string): string {\n\tconst [base] = locale.toLowerCase().split(\"-\");\n\treturn base || locale.toLowerCase();\n}\n\n/**\n * Derives the locale preference order from visitor/provider hints while\n * guaranteeing an English fallback.\n */\nexport function buildLocaleChain(\n\tpreferences: Array<string | null | undefined>\n): string[] {\n\tconst seen = new Set<string>();\n\tconst chain: string[] = [];\n\n\tconst pushLocale = (value: string) => {\n\t\t// Always normalize to base language (en-US -> en, en-GB -> en)\n\t\tconst normalized = normalizeLocaleString(value);\n\t\tif (!seen.has(normalized)) {\n\t\t\tseen.add(normalized);\n\t\t\tchain.push(normalized);\n\t\t}\n\t};\n\n\tfor (const candidate of preferences) {\n\t\tif (!candidate) {\n\t\t\tcontinue;\n\t\t}\n\t\tpushLocale(candidate);\n\t}\n\n\t// Always fallback to English\n\tif (!seen.has(\"en\")) {\n\t\tchain.push(\"en\");\n\t}\n\n\treturn chain;\n}\n\n/**\n * Canonicalizes text override definitions into a lookup map that can be\n * consumed efficiently at runtime.\n */\nexport function normalizeOverrides(\n\toverrides?: SupportTextContentOverrides<string>\n): NormalizedOverrides {\n\tconst map: NormalizedOverrides = new Map();\n\n\tif (!overrides) {\n\t\treturn map;\n\t}\n\n\tfor (const key of Object.keys(overrides) as SupportTextKey[]) {\n\t\tconst value = overrides[key];\n\t\tif (!value) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof value === \"string\" || typeof value === \"function\") {\n\t\t\tmap.set(key, {\n\t\t\t\tanyLocale: value as SupportLocaleMessages[typeof key],\n\t\t\t\tbyLocale: new Map(),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst byLocale = new Map<string, SupportLocaleMessages[typeof key]>();\n\t\tfor (const [locale, localizedValue] of Object.entries(value)) {\n\t\t\tif (!localizedValue) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbyLocale.set(\n\t\t\t\tlocale.toLowerCase(),\n\t\t\t\tlocalizedValue as SupportLocaleMessages[typeof key]\n\t\t\t);\n\t\t}\n\n\t\tmap.set(key, { byLocale });\n\t}\n\n\treturn map;\n}\n\n/**\n * Finds the best matching localized string for a key, consulting overrides\n * before bundled locale dictionaries.\n */\nexport function resolveMessage<K extends SupportTextKey>(\n\tkey: K,\n\tlocaleChain: string[],\n\toverrides: NormalizedOverrides\n): SupportLocaleMessages[K] {\n\tconst override = overrides.get(key) as NormalizedOverride<K> | undefined;\n\tif (override) {\n\t\tfor (const locale of localeChain) {\n\t\t\tconst localized = override.byLocale.get(locale);\n\t\t\tif (localized) {\n\t\t\t\treturn localized;\n\t\t\t}\n\t\t}\n\t\tif (override.anyLocale) {\n\t\t\treturn override.anyLocale;\n\t\t}\n\t}\n\n\tfor (const locale of localeChain) {\n\t\tif (locale in BUILTIN_LOCALES) {\n\t\t\treturn BUILTIN_LOCALES[locale as SupportLocale][key];\n\t\t}\n\t}\n\n\treturn BUILTIN_LOCALES.en[key];\n}\n\n/**\n * Produces the final rendered string by executing function overrides or\n * interpolating variables into template literals.\n */\nexport function evaluateMessage<K extends SupportTextKey>(\n\tkey: K,\n\tmessage: SupportLocaleMessages[K],\n\tvariables: SupportTextVariables<K> | undefined,\n\tcontext: SupportTextContext,\n\tutils: SupportTextUtils\n): string {\n\tif (typeof message === \"function\") {\n\t\treturn message({\n\t\t\tvariables: variables as never,\n\t\t\tcontext,\n\t\t\tutils,\n\t\t});\n\t}\n\n\treturn message;\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  //#region src/support/utils/time.d.ts
2
2
  /**
3
3
  * Friendly relative time formatter used throughout the support widget.
4
+ * Only use this in browser context (components with effects, not during SSR).
4
5
  */
5
6
  declare function formatTimeAgo(date: Date | string): string;
6
7
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","names":[],"sources":["../../../src/support/utils/time.ts"],"sourcesContent":[],"mappings":";;AAGA;;iBAAgB,aAAA,OAAoB"}
1
+ {"version":3,"file":"time.d.ts","names":[],"sources":["../../../src/support/utils/time.ts"],"sourcesContent":[],"mappings":";;AAIA;;;iBAAgB,aAAA,OAAoB"}
@@ -1,8 +1,10 @@
1
1
  //#region src/support/utils/time.ts
2
2
  /**
3
3
  * Friendly relative time formatter used throughout the support widget.
4
+ * Only use this in browser context (components with effects, not during SSR).
4
5
  */
5
6
  function formatTimeAgo(date) {
7
+ if (typeof window === "undefined") return "";
6
8
  const now = /* @__PURE__ */ new Date();
7
9
  const messageDate = typeof date === "string" ? new Date(date) : date;
8
10
  const diffMs = now.getTime() - messageDate.getTime();
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","names":[],"sources":["../../../src/support/utils/time.ts"],"sourcesContent":["/**\n * Friendly relative time formatter used throughout the support widget.\n */\nexport function formatTimeAgo(date: Date | string): string {\n\tconst now = new Date();\n\tconst messageDate = typeof date === \"string\" ? new Date(date) : date;\n\tconst diffMs = now.getTime() - messageDate.getTime();\n\tconst diffMins = Math.floor(diffMs / (1000 * 60));\n\tconst diffHours = Math.floor(diffMs / (1000 * 60 * 60));\n\tconst diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n\tif (diffMins < 1) {\n\t\treturn \"now\";\n\t}\n\tif (diffMins < 60) {\n\t\treturn `${diffMins}m ago`;\n\t}\n\tif (diffHours < 24) {\n\t\treturn `${diffHours}h ago`;\n\t}\n\tif (diffDays === 1) {\n\t\treturn \"Yesterday\";\n\t}\n\tif (diffDays < 7) {\n\t\treturn `${diffDays} days ago`;\n\t}\n\tif (diffDays < 30) {\n\t\tconst weeks = Math.floor(diffDays / 7);\n\t\treturn `${weeks} ${weeks === 1 ? \"week\" : \"weeks\"} ago`;\n\t}\n\tif (diffDays < 365) {\n\t\tconst months = Math.floor(diffDays / 30);\n\t\treturn `${months} ${months === 1 ? \"month\" : \"months\"} ago`;\n\t}\n\tconst years = Math.floor(diffDays / 365);\n\treturn `${years} ${years === 1 ? \"year\" : \"years\"} ago`;\n}\n"],"mappings":";;;;AAGA,SAAgB,cAAc,MAA6B;CAC1D,MAAM,sBAAM,IAAI,MAAM;CACtB,MAAM,cAAc,OAAO,SAAS,WAAW,IAAI,KAAK,KAAK,GAAG;CAChE,MAAM,SAAS,IAAI,SAAS,GAAG,YAAY,SAAS;CACpD,MAAM,WAAW,KAAK,MAAM,UAAU,MAAO,IAAI;CACjD,MAAM,YAAY,KAAK,MAAM,UAAU,MAAO,KAAK,IAAI;CACvD,MAAM,WAAW,KAAK,MAAM,UAAU,MAAO,KAAK,KAAK,IAAI;AAE3D,KAAI,WAAW,EACd,QAAO;AAER,KAAI,WAAW,GACd,QAAO,GAAG,SAAS;AAEpB,KAAI,YAAY,GACf,QAAO,GAAG,UAAU;AAErB,KAAI,aAAa,EAChB,QAAO;AAER,KAAI,WAAW,EACd,QAAO,GAAG,SAAS;AAEpB,KAAI,WAAW,IAAI;EAClB,MAAM,QAAQ,KAAK,MAAM,WAAW,EAAE;AACtC,SAAO,GAAG,MAAM,GAAG,UAAU,IAAI,SAAS,QAAQ;;AAEnD,KAAI,WAAW,KAAK;EACnB,MAAM,SAAS,KAAK,MAAM,WAAW,GAAG;AACxC,SAAO,GAAG,OAAO,GAAG,WAAW,IAAI,UAAU,SAAS;;CAEvD,MAAM,QAAQ,KAAK,MAAM,WAAW,IAAI;AACxC,QAAO,GAAG,MAAM,GAAG,UAAU,IAAI,SAAS,QAAQ"}
1
+ {"version":3,"file":"time.js","names":[],"sources":["../../../src/support/utils/time.ts"],"sourcesContent":["/**\n * Friendly relative time formatter used throughout the support widget.\n * Only use this in browser context (components with effects, not during SSR).\n */\nexport function formatTimeAgo(date: Date | string): string {\n\t// Guard against SSR - return empty string or static fallback\n\tif (typeof window === \"undefined\") {\n\t\treturn \"\";\n\t}\n\n\tconst now = new Date();\n\tconst messageDate = typeof date === \"string\" ? new Date(date) : date;\n\tconst diffMs = now.getTime() - messageDate.getTime();\n\tconst diffMins = Math.floor(diffMs / (1000 * 60));\n\tconst diffHours = Math.floor(diffMs / (1000 * 60 * 60));\n\tconst diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n\tif (diffMins < 1) {\n\t\treturn \"now\";\n\t}\n\tif (diffMins < 60) {\n\t\treturn `${diffMins}m ago`;\n\t}\n\tif (diffHours < 24) {\n\t\treturn `${diffHours}h ago`;\n\t}\n\tif (diffDays === 1) {\n\t\treturn \"Yesterday\";\n\t}\n\tif (diffDays < 7) {\n\t\treturn `${diffDays} days ago`;\n\t}\n\tif (diffDays < 30) {\n\t\tconst weeks = Math.floor(diffDays / 7);\n\t\treturn `${weeks} ${weeks === 1 ? \"week\" : \"weeks\"} ago`;\n\t}\n\tif (diffDays < 365) {\n\t\tconst months = Math.floor(diffDays / 30);\n\t\treturn `${months} ${months === 1 ? \"month\" : \"months\"} ago`;\n\t}\n\tconst years = Math.floor(diffDays / 365);\n\treturn `${years} ${years === 1 ? \"year\" : \"years\"} ago`;\n}\n"],"mappings":";;;;;AAIA,SAAgB,cAAc,MAA6B;AAE1D,KAAI,OAAO,WAAW,YACrB,QAAO;CAGR,MAAM,sBAAM,IAAI,MAAM;CACtB,MAAM,cAAc,OAAO,SAAS,WAAW,IAAI,KAAK,KAAK,GAAG;CAChE,MAAM,SAAS,IAAI,SAAS,GAAG,YAAY,SAAS;CACpD,MAAM,WAAW,KAAK,MAAM,UAAU,MAAO,IAAI;CACjD,MAAM,YAAY,KAAK,MAAM,UAAU,MAAO,KAAK,IAAI;CACvD,MAAM,WAAW,KAAK,MAAM,UAAU,MAAO,KAAK,KAAK,IAAI;AAE3D,KAAI,WAAW,EACd,QAAO;AAER,KAAI,WAAW,GACd,QAAO,GAAG,SAAS;AAEpB,KAAI,YAAY,GACf,QAAO,GAAG,UAAU;AAErB,KAAI,aAAa,EAChB,QAAO;AAER,KAAI,WAAW,EACd,QAAO,GAAG,SAAS;AAEpB,KAAI,WAAW,IAAI;EAClB,MAAM,QAAQ,KAAK,MAAM,WAAW,EAAE;AACtC,SAAO,GAAG,MAAM,GAAG,UAAU,IAAI,SAAS,QAAQ;;AAEnD,KAAI,WAAW,KAAK;EACnB,MAAM,SAAS,KAAK,MAAM,WAAW,GAAG;AACxC,SAAO,GAAG,OAAO,GAAG,WAAW,IAAI,UAAU,SAAS;;CAEvD,MAAM,QAAQ,KAAK,MAAM,WAAW,IAAI;AACxC,QAAO,GAAG,MAAM,GAAG,UAAU,IAAI,SAAS,QAAQ"}
@@ -61,6 +61,13 @@ declare const timelineItemSchema: ZodObject<{
61
61
  mediaType: ZodString;
62
62
  fileName: ZodOptional<ZodString>;
63
63
  size: ZodOptional<ZodNumber>;
64
+ }, $strip>, ZodObject<{
65
+ type: ZodLiteral<"metadata">;
66
+ source: ZodEnum<{
67
+ email: "email";
68
+ widget: "widget";
69
+ api: "api";
70
+ }>;
64
71
  }, $strip>]>>;
65
72
  userId: ZodNullable<ZodString>;
66
73
  aiAgentId: ZodNullable<ZodString>;
@@ -131,6 +138,13 @@ declare const getConversationTimelineItemsResponseSchema: ZodObject<{
131
138
  mediaType: ZodString;
132
139
  fileName: ZodOptional<ZodString>;
133
140
  size: ZodOptional<ZodNumber>;
141
+ }, $strip>, ZodObject<{
142
+ type: ZodLiteral<"metadata">;
143
+ source: ZodEnum<{
144
+ email: "email";
145
+ widget: "widget";
146
+ api: "api";
147
+ }>;
134
148
  }, $strip>]>>;
135
149
  userId: ZodNullable<ZodString>;
136
150
  aiAgentId: ZodNullable<ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-item.d.ts","names":[],"sources":["../../types/src/api/timeline-item.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAgMY,cA9EC,kBA8ED,EA9EmB,SA8EgB,CAAA;EAIlC,EAAA,aAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA9BD,kBAAA,GAAqB,cAAe;KAEpC,YAAA,GAAe,cAAe;cAS7B,2CAAyC;;;;AAmBC,KAJ3C,mCAAA,GAAsC,MAIK,CAAA,OAH/C,yCAG+C,CAAA;AAAA,cAA1C,0CAA0C,EAAA,SAAA,CAAA;EAiB3C,KAAA,UAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAAA,oCAAA,GAAuC,cAC3C"}
1
+ {"version":3,"file":"timeline-item.d.ts","names":[],"sources":["../../types/src/api/timeline-item.ts"],"sourcesContent":[],"mappings":";;;;;;;;cA4Ha,oBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmFwB,SAAA,WAAA;EAAA,SAAA,aAAA,YAAA,UAAA,CAAA,CAAA;AAiBvD,CAAA,QAAY,CAAA;KAhDA,kBAAA,GAAqB,cAAe;KAEpC,YAAA,GAAe,cAAe;cAU7B,2CAAyC;;;;KAe1C,mCAAA,GAAsC,cAC1C;cAGK,4CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiB3C,oCAAA,GAAuC,cAC3C"}
@@ -1,30 +0,0 @@
1
- import React from "react";
2
-
3
- //#region src/primitives/page-registry.d.ts
4
- type PageComponent<P = unknown> = React.ComponentType<{
5
- params?: P;
6
- }>;
7
- type PageRegistry = Map<string, PageComponent>;
8
- /**
9
- * Context provider for declarative page registration.
10
- *
11
- * @example
12
- * <PageRegistryProvider>
13
- * <Page name="HOME" component={HomePage} />
14
- * <Router page={currentPage} />
15
- * </PageRegistryProvider>
16
- */
17
- declare const PageRegistryProvider: React.FC<{
18
- children: React.ReactNode;
19
- }>;
20
- /**
21
- * Access the page registry (used internally by Router and Page).
22
- */
23
- declare const usePageRegistry: () => PageRegistry;
24
- /**
25
- * Register a page in the registry (used internally by Page component).
26
- */
27
- declare const useRegisterPage: (name: string, component: PageComponent) => void;
28
- //#endregion
29
- export { PageRegistryProvider, usePageRegistry, useRegisterPage };
30
- //# sourceMappingURL=page-registry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page-registry.d.ts","names":[],"sources":["../../src/primitives/page-registry.tsx"],"sourcesContent":[],"mappings":";;;KAEK,6BAA6B,KAAA,CAAM;WAAyB;AAFC,CAAA,CAAA;AAEb,KAEhD,YAAA,GAAe,GAAH,CAAA,MAAA,EAAe,aAAA,CAAA;AAahC;AAeA;AAKA;;;;;;;cApBa,sBAAsB,KAAA,CAAM;YAAe,KAAA,CAAM;;;;;cAejD,uBAAe;;;;cAKf,2CAA4C"}
@@ -1,45 +0,0 @@
1
- import React, { createContext, useContext, useMemo } from "react";
2
- import { jsx } from "react/jsx-runtime";
3
-
4
- //#region src/primitives/page-registry.tsx
5
- const PageRegistryContext = createContext(/* @__PURE__ */ new Map());
6
- /**
7
- * Context provider for declarative page registration.
8
- *
9
- * @example
10
- * <PageRegistryProvider>
11
- * <Page name="HOME" component={HomePage} />
12
- * <Router page={currentPage} />
13
- * </PageRegistryProvider>
14
- */
15
- const PageRegistryProvider = ({ children }) => {
16
- const registry = useMemo(() => /* @__PURE__ */ new Map(), []);
17
- return /* @__PURE__ */ jsx(PageRegistryContext.Provider, {
18
- value: registry,
19
- children
20
- });
21
- };
22
- /**
23
- * Access the page registry (used internally by Router and Page).
24
- */
25
- const usePageRegistry = () => useContext(PageRegistryContext);
26
- /**
27
- * Register a page in the registry (used internally by Page component).
28
- */
29
- const useRegisterPage = (name, component) => {
30
- const registry = usePageRegistry();
31
- React.useEffect(() => {
32
- registry.set(name, component);
33
- return () => {
34
- registry.delete(name);
35
- };
36
- }, [
37
- name,
38
- component,
39
- registry
40
- ]);
41
- };
42
-
43
- //#endregion
44
- export { PageRegistryProvider, usePageRegistry, useRegisterPage };
45
- //# sourceMappingURL=page-registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page-registry.js","names":["PageRegistryProvider: React.FC<{ children: React.ReactNode }>"],"sources":["../../src/primitives/page-registry.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\n\ntype PageComponent<P = unknown> = React.ComponentType<{ params?: P }>;\n\ntype PageRegistry = Map<string, PageComponent>;\n\nconst PageRegistryContext = createContext<PageRegistry>(new Map());\n\n/**\n * Context provider for declarative page registration.\n *\n * @example\n * <PageRegistryProvider>\n * <Page name=\"HOME\" component={HomePage} />\n * <Router page={currentPage} />\n * </PageRegistryProvider>\n */\nexport const PageRegistryProvider: React.FC<{ children: React.ReactNode }> = ({\n\tchildren,\n}) => {\n\tconst registry = useMemo(() => new Map<string, PageComponent>(), []);\n\n\treturn (\n\t\t<PageRegistryContext.Provider value={registry}>\n\t\t\t{children}\n\t\t</PageRegistryContext.Provider>\n\t);\n};\n\n/**\n * Access the page registry (used internally by Router and Page).\n */\nexport const usePageRegistry = () => useContext(PageRegistryContext);\n\n/**\n * Register a page in the registry (used internally by Page component).\n */\nexport const useRegisterPage = (name: string, component: PageComponent) => {\n\tconst registry = usePageRegistry();\n\n\tReact.useEffect(() => {\n\t\tregistry.set(name, component);\n\t\treturn () => {\n\t\t\tregistry.delete(name);\n\t\t};\n\t}, [name, component, registry]);\n};\n"],"mappings":";;;;AAMA,MAAM,sBAAsB,8BAA4B,IAAI,KAAK,CAAC;;;;;;;;;;AAWlE,MAAaA,wBAAiE,EAC7E,eACK;CACL,MAAM,WAAW,8BAAc,IAAI,KAA4B,EAAE,EAAE,CAAC;AAEpE,QACC,oBAAC,oBAAoB;EAAS,OAAO;EACnC;GAC6B;;;;;AAOjC,MAAa,wBAAwB,WAAW,oBAAoB;;;;AAKpE,MAAa,mBAAmB,MAAc,cAA6B;CAC1E,MAAM,WAAW,iBAAiB;AAElC,OAAM,gBAAgB;AACrB,WAAS,IAAI,MAAM,UAAU;AAC7B,eAAa;AACZ,YAAS,OAAO,KAAK;;IAEpB;EAAC;EAAM;EAAW;EAAS,CAAC"}
@@ -1,21 +0,0 @@
1
- //#region src/primitives/page.d.ts
2
- type PageProps<Params = unknown> = {
3
- name: string;
4
- component: React.ComponentType<{
5
- params?: Params;
6
- }>;
7
- };
8
- /**
9
- * Declaratively register a page component.
10
- *
11
- * @example
12
- * <Page name="HOME" component={HomePage} />
13
- * <Page name="SETTINGS" component={SettingsPage} />
14
- */
15
- declare function Page<Params = unknown>({
16
- name,
17
- component
18
- }: PageProps<Params>): null;
19
- //#endregion
20
- export { Page, PageProps };
21
- //# sourceMappingURL=page.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page.d.ts","names":[],"sources":["../../src/primitives/page.tsx"],"sourcesContent":[],"mappings":";KAEY;EAAA,IAAA,EAAA,MAAS;EAYL,SAAI,EAVR,KAAA,CAAM,aAUE,CAAA;IACnB,MAAA,CAAA,EAX0C,MAW1C;EACA,CAAA,CAAA;CACY;;;;;;;;iBAHG;;;GAGb,UAAU"}
@@ -1,18 +0,0 @@
1
- import { useRegisterPage } from "./page-registry.js";
2
-
3
- //#region src/primitives/page.tsx
4
- /**
5
- * Declaratively register a page component.
6
- *
7
- * @example
8
- * <Page name="HOME" component={HomePage} />
9
- * <Page name="SETTINGS" component={SettingsPage} />
10
- */
11
- function Page({ name, component }) {
12
- useRegisterPage(name, component);
13
- return null;
14
- }
15
-
16
- //#endregion
17
- export { Page };
18
- //# sourceMappingURL=page.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"page.js","names":[],"sources":["../../src/primitives/page.tsx"],"sourcesContent":["import { useRegisterPage } from \"./page-registry\";\n\nexport type PageProps<Params = unknown> = {\n\tname: string;\n\tcomponent: React.ComponentType<{ params?: Params }>;\n};\n\n/**\n * Declaratively register a page component.\n *\n * @example\n * <Page name=\"HOME\" component={HomePage} />\n * <Page name=\"SETTINGS\" component={SettingsPage} />\n */\nexport function Page<Params = unknown>({\n\tname,\n\tcomponent,\n}: PageProps<Params>): null {\n\tuseRegisterPage(name, component as React.ComponentType<{ params?: unknown }>);\n\treturn null;\n}\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,KAAuB,EACtC,MACA,aAC2B;AAC3B,iBAAgB,MAAM,UAAuD;AAC7E,QAAO"}