fimo 0.8.0 → 0.9.0-experimental.10

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 (218) hide show
  1. package/assets/agent-templates/content-translator/scripts/write-locale-files.ts +66 -0
  2. package/assets/agents-starter/claude/settings.json +19 -0
  3. package/assets/content-templates/hooks-template.eta +4 -2
  4. package/assets/content-templates/types-template.eta +67 -1
  5. package/assets/skills/fimo/SKILL.md +1 -1
  6. package/assets/skills/fimo/references/content.md +86 -15
  7. package/assets/skills/fimo/references/translations.md +75 -0
  8. package/assets/skills/fimo-cli/SKILL.md +6 -2
  9. package/assets/skills/fimo-cli/references/content.md +61 -2
  10. package/assets/skills/fimo-cli/references/integrations/firecrawl.md +20 -4
  11. package/assets/skills/fimo-cli/references/integrations.md +5 -1
  12. package/assets/skills/fimo-cli/references/webhooks.md +162 -0
  13. package/assets/skills/fimo-migration/SKILL.md +24 -2
  14. package/assets/skills/fimo-migration/references/content.md +24 -0
  15. package/assets/skills/fimo-migration/references/manifest.md +46 -0
  16. package/assets/skills/fimo-migration/references/pages.md +234 -0
  17. package/assets/skills/fimo-migration/references/qa.md +24 -2
  18. package/assets/skills/fimo-migration/references/workflow.md +12 -1
  19. package/assets/skills/fimo-migration/references/wrap.md +662 -0
  20. package/assets/skills/fimo-studio/SKILL.md +5 -3
  21. package/assets/skills/fimo-studio/references/cms.md +9 -1
  22. package/assets/skills/fimo-studio/references/visual-editing.md +5 -3
  23. package/assets/skills/fimo-studio/references/webhooks.md +42 -0
  24. package/dist/build/vite/plugins/translations.d.ts +2 -8
  25. package/dist/build/vite/plugins/translations.js +31 -131
  26. package/dist/cli/bundle.json +1 -1
  27. package/dist/cli/index.js +1337 -189
  28. package/dist/runtime/app/FimoProviders.d.ts +1 -11
  29. package/dist/runtime/app/FimoProviders.js +31 -30
  30. package/dist/runtime/astro/index.d.ts +2 -0
  31. package/dist/runtime/astro/index.js +3 -0
  32. package/dist/runtime/astro/server.d.ts +3 -0
  33. package/dist/runtime/astro/server.js +6 -0
  34. package/dist/runtime/content/client/internal.js +1 -0
  35. package/dist/runtime/content/client/types.d.ts +16 -0
  36. package/dist/runtime/core/BuiltWithBadge.d.ts +2 -0
  37. package/dist/runtime/core/BuiltWithBadge.js +68 -0
  38. package/dist/runtime/i18n/FimoLocaleContext.js +1 -0
  39. package/dist/runtime/next/FimoNextProviders.d.ts +24 -0
  40. package/dist/runtime/next/FimoNextProviders.js +20 -0
  41. package/dist/runtime/next/FimoNextScripts.d.ts +10 -0
  42. package/dist/runtime/next/FimoNextScripts.js +19 -0
  43. package/dist/runtime/next/index.d.ts +14 -0
  44. package/dist/runtime/next/index.js +14 -0
  45. package/dist/runtime/next/server.d.ts +2 -0
  46. package/dist/runtime/next/server.js +4 -0
  47. package/dist/runtime/nuxt/composables.d.ts +9 -0
  48. package/dist/runtime/nuxt/composables.js +57 -0
  49. package/dist/runtime/nuxt/index.d.ts +3 -0
  50. package/dist/runtime/nuxt/index.js +6 -0
  51. package/dist/runtime/nuxt/server.d.ts +3 -0
  52. package/dist/runtime/nuxt/server.js +6 -0
  53. package/dist/runtime/primitives/components/RichText.d.ts +5 -1
  54. package/dist/runtime/primitives/components/RichText.js +2 -2
  55. package/dist/runtime/primitives/labels-hook.d.ts +33 -0
  56. package/dist/runtime/primitives/labels-hook.js +41 -0
  57. package/dist/runtime/primitives/labels-store.d.ts +12 -0
  58. package/dist/runtime/primitives/labels-store.js +60 -0
  59. package/dist/runtime/primitives/lib/useFimoLiveValue.d.ts +5 -3
  60. package/dist/runtime/primitives/lib/useFimoLiveValue.js +11 -4
  61. package/dist/runtime/primitives/translations.d.ts +1 -27
  62. package/dist/runtime/primitives/translations.js +7 -85
  63. package/dist/runtime/react/FimoSpaProviders.d.ts +36 -0
  64. package/dist/runtime/react/FimoSpaProviders.js +122 -0
  65. package/dist/runtime/react/index.d.ts +35 -0
  66. package/dist/runtime/react/index.js +40 -0
  67. package/dist/runtime/react/spa-content-cache.d.ts +38 -0
  68. package/dist/runtime/react/spa-content-cache.js +64 -0
  69. package/dist/runtime/remix/FimoRemixProviders.d.ts +16 -0
  70. package/dist/runtime/remix/FimoRemixProviders.js +12 -0
  71. package/dist/runtime/remix/FimoRemixScripts.d.ts +10 -0
  72. package/dist/runtime/remix/FimoRemixScripts.js +19 -0
  73. package/dist/runtime/remix/index.d.ts +12 -0
  74. package/dist/runtime/remix/index.js +11 -0
  75. package/dist/runtime/remix/server.d.ts +2 -0
  76. package/dist/runtime/remix/server.js +2 -0
  77. package/dist/runtime/seo/neutral.d.ts +22 -0
  78. package/dist/runtime/seo/neutral.js +17 -0
  79. package/dist/runtime/shared/display-routes.d.ts +14 -0
  80. package/dist/runtime/shared/display-routes.js +25 -0
  81. package/dist/runtime/shared/fimo-config.server.d.ts +0 -1
  82. package/dist/runtime/shared/fimo-config.server.js +1 -13
  83. package/dist/runtime/shared/fimo-config.types.d.ts +2 -0
  84. package/dist/runtime/shared/i18n-messages.d.ts +29 -0
  85. package/dist/runtime/shared/i18n-messages.js +79 -0
  86. package/dist/runtime/shared/labels-fetch.pure.d.ts +17 -0
  87. package/dist/runtime/shared/labels-fetch.pure.js +71 -0
  88. package/dist/runtime/shared/labels-fetch.server.d.ts +7 -0
  89. package/dist/runtime/shared/labels-fetch.server.js +97 -0
  90. package/dist/runtime/shared/labels-t.pure.d.ts +2 -0
  91. package/dist/runtime/shared/labels-t.pure.js +10 -0
  92. package/dist/runtime/strapi/client.d.ts +30 -0
  93. package/dist/runtime/strapi/client.js +132 -0
  94. package/dist/runtime/strapi/index.d.ts +5 -0
  95. package/dist/runtime/strapi/index.js +6 -0
  96. package/dist/runtime/strapi/reshape.d.ts +50 -0
  97. package/dist/runtime/strapi/reshape.js +121 -0
  98. package/dist/runtime/svelte/index.d.ts +3 -0
  99. package/dist/runtime/svelte/index.js +7 -0
  100. package/dist/runtime/svelte/server.d.ts +3 -0
  101. package/dist/runtime/svelte/server.js +6 -0
  102. package/dist/runtime/vue/index.d.ts +3 -0
  103. package/dist/runtime/vue/index.js +5 -0
  104. package/dist/runtime/vue/server.d.ts +3 -0
  105. package/dist/runtime/vue/server.js +6 -0
  106. package/dist/runtime/wrapped/FimoFileLink.d.ts +17 -0
  107. package/dist/runtime/wrapped/FimoFileLink.js +19 -0
  108. package/dist/runtime/wrapped/FimoMediaImage.d.ts +14 -0
  109. package/dist/runtime/wrapped/FimoMediaImage.js +20 -0
  110. package/dist/runtime/wrapped/FimoMediaVideo.d.ts +14 -0
  111. package/dist/runtime/wrapped/FimoMediaVideo.js +20 -0
  112. package/dist/runtime/wrapped/FimoRichTextBlock.d.ts +26 -0
  113. package/dist/runtime/wrapped/FimoRichTextBlock.js +22 -0
  114. package/dist/runtime/wrapped/FimoText.d.ts +22 -0
  115. package/dist/runtime/wrapped/FimoText.js +20 -0
  116. package/dist/runtime/wrapped/WrappedContentContext.d.ts +28 -0
  117. package/dist/runtime/wrapped/WrappedContentContext.js +30 -0
  118. package/dist/runtime/wrapped/WrappedProviders.d.ts +33 -0
  119. package/dist/runtime/wrapped/WrappedProviders.js +101 -0
  120. package/dist/runtime/wrapped/content-fetch.pure.d.ts +20 -0
  121. package/dist/runtime/wrapped/content-fetch.pure.js +106 -0
  122. package/dist/runtime/wrapped/dom.d.ts +4 -0
  123. package/dist/runtime/wrapped/dom.js +23 -0
  124. package/dist/runtime/wrapped/server.d.ts +80 -0
  125. package/dist/runtime/wrapped/server.js +207 -0
  126. package/dist/scripts/apply-wrap-templates.d.ts +61 -0
  127. package/dist/scripts/apply-wrap-templates.js +137 -0
  128. package/dist/scripts/apply-wrap.d.ts +73 -0
  129. package/dist/scripts/apply-wrap.js +340 -0
  130. package/dist/scripts/cms/discover.d.ts +2 -0
  131. package/dist/scripts/cms/discover.js +17 -0
  132. package/dist/scripts/cms/example-content.d.ts +33 -0
  133. package/dist/scripts/cms/example-content.js +165 -0
  134. package/dist/scripts/cms/strapi/detect.d.ts +2 -0
  135. package/dist/scripts/cms/strapi/detect.js +186 -0
  136. package/dist/scripts/cms/strapi/index.d.ts +3 -0
  137. package/dist/scripts/cms/strapi/index.js +25 -0
  138. package/dist/scripts/cms/strapi/list-source.d.ts +17 -0
  139. package/dist/scripts/cms/strapi/list-source.js +90 -0
  140. package/dist/scripts/cms/strapi/schema-map.d.ts +9 -0
  141. package/dist/scripts/cms/strapi/schema-map.js +289 -0
  142. package/dist/scripts/cms/strapi/shapes.d.ts +25 -0
  143. package/dist/scripts/cms/strapi/shapes.js +48 -0
  144. package/dist/scripts/cms/strapi/touchpoints.d.ts +31 -0
  145. package/dist/scripts/cms/strapi/touchpoints.js +145 -0
  146. package/dist/scripts/cms/strapi/wire-client.d.ts +15 -0
  147. package/dist/scripts/cms/strapi/wire-client.js +107 -0
  148. package/dist/scripts/cms/strapi/wiring.d.ts +17 -0
  149. package/dist/scripts/cms/strapi/wiring.js +46 -0
  150. package/dist/scripts/cms/types.d.ts +145 -0
  151. package/dist/scripts/cms/types.js +11 -0
  152. package/dist/scripts/detect-framework.d.ts +39 -0
  153. package/dist/scripts/detect-framework.js +139 -0
  154. package/dist/scripts/draft-rows.d.ts +19 -0
  155. package/dist/scripts/draft-rows.js +178 -0
  156. package/dist/scripts/draft-schemas.d.ts +27 -0
  157. package/dist/scripts/draft-schemas.js +247 -0
  158. package/dist/scripts/extract-translations.js +16 -11
  159. package/dist/scripts/frameworks/astro/routes.d.ts +3 -0
  160. package/dist/scripts/frameworks/astro/routes.js +44 -0
  161. package/dist/scripts/frameworks/astro/template-style.d.ts +7 -0
  162. package/dist/scripts/frameworks/astro/template-style.js +19 -0
  163. package/dist/scripts/frameworks/discover.d.ts +83 -0
  164. package/dist/scripts/frameworks/discover.js +288 -0
  165. package/dist/scripts/frameworks/discovered-route.d.ts +9 -0
  166. package/dist/scripts/frameworks/discovered-route.js +17 -0
  167. package/dist/scripts/frameworks/next/rewire.d.ts +43 -0
  168. package/dist/scripts/frameworks/next/rewire.js +282 -0
  169. package/dist/scripts/frameworks/next/routes.d.ts +30 -0
  170. package/dist/scripts/frameworks/next/routes.js +176 -0
  171. package/dist/scripts/frameworks/next/wiring.d.ts +33 -0
  172. package/dist/scripts/frameworks/next/wiring.js +186 -0
  173. package/dist/scripts/frameworks/nuxt/routes.d.ts +3 -0
  174. package/dist/scripts/frameworks/nuxt/routes.js +38 -0
  175. package/dist/scripts/frameworks/nuxt/template-style.d.ts +9 -0
  176. package/dist/scripts/frameworks/nuxt/template-style.js +27 -0
  177. package/dist/scripts/frameworks/remix/routes.d.ts +3 -0
  178. package/dist/scripts/frameworks/remix/routes.js +36 -0
  179. package/dist/scripts/frameworks/support.d.ts +75 -0
  180. package/dist/scripts/frameworks/support.js +165 -0
  181. package/dist/scripts/frameworks/sveltekit/routes.d.ts +3 -0
  182. package/dist/scripts/frameworks/sveltekit/routes.js +35 -0
  183. package/dist/scripts/frameworks/sveltekit/template-style.d.ts +9 -0
  184. package/dist/scripts/frameworks/sveltekit/template-style.js +54 -0
  185. package/dist/scripts/frameworks/vite/routes.d.ts +20 -0
  186. package/dist/scripts/frameworks/vite/routes.js +143 -0
  187. package/dist/scripts/frameworks/vite/wiring.d.ts +22 -0
  188. package/dist/scripts/frameworks/vite/wiring.js +144 -0
  189. package/dist/scripts/i18n-namespace.d.ts +27 -0
  190. package/dist/scripts/i18n-namespace.js +155 -0
  191. package/dist/scripts/lib/humanize.d.ts +14 -0
  192. package/dist/scripts/lib/humanize.js +54 -0
  193. package/dist/scripts/lib/validation-report.d.ts +1 -3
  194. package/dist/scripts/lib/validation-report.js +3 -9
  195. package/dist/scripts/render-parity/capture.d.ts +64 -0
  196. package/dist/scripts/render-parity/capture.js +436 -0
  197. package/dist/scripts/render-parity/compare.d.ts +59 -0
  198. package/dist/scripts/render-parity/compare.js +0 -0
  199. package/dist/scripts/render-parity/normalize-html.d.ts +13 -0
  200. package/dist/scripts/render-parity/normalize-html.js +223 -0
  201. package/dist/scripts/render-parity/types.d.ts +41 -0
  202. package/dist/scripts/render-parity/types.js +1 -0
  203. package/dist/scripts/routes/bindings.d.ts +93 -0
  204. package/dist/scripts/routes/bindings.js +117 -0
  205. package/dist/scripts/routes/label-prefixes.d.ts +49 -0
  206. package/dist/scripts/routes/label-prefixes.js +136 -0
  207. package/dist/scripts/routes/module-resolve.d.ts +20 -0
  208. package/dist/scripts/routes/module-resolve.js +78 -0
  209. package/dist/scripts/routes/page-structure.d.ts +72 -0
  210. package/dist/scripts/routes/page-structure.js +234 -0
  211. package/dist/scripts/scan-wrappable.d.ts +200 -0
  212. package/dist/scripts/scan-wrappable.js +1355 -0
  213. package/dist/scripts/validate-route-metadata.js +11 -0
  214. package/dist/scripts/validate-schemas.js +42 -1
  215. package/package.json +88 -4
  216. package/release.json +2 -2
  217. package/templates/react-router/package.json +1 -1
  218. package/templates/react-router/translations/en.json +1 -0
@@ -9,9 +9,11 @@ import { type RefObject } from 'react';
9
9
  * preview knows to dispatch events instead of falling back to raw DOM writes,
10
10
  * and updates internal state when a mutation arrives.
11
11
  *
12
- * In prod (published app): Vite statically inlines `import.meta.env.DEV`, so
13
- * `useFimoLiveValueProd` is the only implementation linked and the listener
14
- * machinery is dead-code-eliminated.
12
+ * In prod (published app): only `useFimoLiveValueProd` is linked. The dev
13
+ * check must work under any bundler (Vite, webpack, Turbopack) and plain
14
+ * Node SSR: `import.meta.env.DEV` only exists under Vite, and
15
+ * `process.env.NODE_ENV` is statically replaced by Next/webpack — checking
16
+ * both keeps the hook correct across adapters.
15
17
  */
16
18
  declare function useFimoLiveValueDev<T, E extends HTMLElement = HTMLElement>(external: T): {
17
19
  value: T;
@@ -10,9 +10,11 @@ import { useEffect, useRef, useState } from 'react';
10
10
  * preview knows to dispatch events instead of falling back to raw DOM writes,
11
11
  * and updates internal state when a mutation arrives.
12
12
  *
13
- * In prod (published app): Vite statically inlines `import.meta.env.DEV`, so
14
- * `useFimoLiveValueProd` is the only implementation linked and the listener
15
- * machinery is dead-code-eliminated.
13
+ * In prod (published app): only `useFimoLiveValueProd` is linked. The dev
14
+ * check must work under any bundler (Vite, webpack, Turbopack) and plain
15
+ * Node SSR: `import.meta.env.DEV` only exists under Vite, and
16
+ * `process.env.NODE_ENV` is statically replaced by Next/webpack — checking
17
+ * both keeps the hook correct across adapters.
16
18
  */
17
19
  function useFimoLiveValueDev(external) {
18
20
  const ref = useRef(null);
@@ -46,4 +48,9 @@ function useFimoLiveValueProd(external) {
46
48
  const ref = useRef(null);
47
49
  return { value: external, ref };
48
50
  }
49
- export const useFimoLiveValue = (import.meta.env.DEV ? useFimoLiveValueDev : useFimoLiveValueProd);
51
+ // globalThis lookup, not a bare `process` reference: this file is part of the
52
+ // browser-facing runtime surface, which must typecheck without node types
53
+ // (the generated-types gate enforces it).
54
+ const isDevRuntime = import.meta.env?.DEV === true ||
55
+ globalThis.process?.env?.NODE_ENV === 'development';
56
+ export const useFimoLiveValue = (isDevRuntime ? useFimoLiveValueDev : useFimoLiveValueProd);
@@ -1,28 +1,2 @@
1
- import { FimoString } from './lib/index.js';
2
- /**
3
- * Hook to provide a label function (`t`).
4
- *
5
- * Returns FimoString with source tracking for inline editing.
6
- * Use with <Text> component for rendering, or String() for escape hatch.
7
- *
8
- * @example
9
- * const { t } = useLabels();
10
- *
11
- * // With Text component (recommended)
12
- * <Text value={t('welcome')} />
13
- *
14
- * // Escape hatch for attributes
15
- * <input placeholder={String(t('email.placeholder'))} />
16
- */
17
- export declare function useLabels(): {
18
- t: (fullKey: string) => FimoString;
19
- locale: string;
20
- };
21
- /**
22
- * Legacy alias for older projects. Prefer useLabels() in new code.
23
- */
24
- export declare function useTranslations(): {
25
- t: (fullKey: string) => FimoString;
26
- locale: string;
27
- };
1
+ export { useLabels, useTranslations } from './labels-hook.js';
28
2
  //# sourceMappingURL=translations.d.ts.map
@@ -1,61 +1,14 @@
1
- import { useSyncExternalStore } from 'react';
1
+ // Vite flavor of the label layer: hydrates the framework-neutral store from
2
+ // the `virtual:translations` module (fimo/vite labels plugin) and wires HMR.
3
+ // Framework-agnostic consumers use ./labels-store.ts + ./labels-hook.ts.
2
4
  import { defaultLocale as bundledDefaultLocale, dictionaries as bundledDictionaries, signature as translationSignature, updatedAt as bundledUpdatedAt, } from 'virtual:translations';
3
- import { useLocale } from '../i18n/FimoLocaleContext.js';
4
- import { FimoString } from './lib/index.js';
5
- const labelListeners = new Set();
6
- let labelState = {
5
+ import { applyLabelUpdate, hydrateLabels } from './labels-store.js';
6
+ hydrateLabels({
7
7
  dictionaries: bundledDictionaries ?? {},
8
8
  defaultLocale: bundledDefaultLocale || 'en',
9
9
  signature: translationSignature,
10
10
  updatedAt: bundledUpdatedAt ?? null,
11
- };
12
- function subscribeLabels(listener) {
13
- labelListeners.add(listener);
14
- return () => {
15
- labelListeners.delete(listener);
16
- };
17
- }
18
- function getLabelSnapshot() {
19
- return labelState;
20
- }
21
- function setLabelState(next) {
22
- if (next.signature === labelState.signature) {
23
- return;
24
- }
25
- labelState = next;
26
- for (const listener of labelListeners) {
27
- listener();
28
- }
29
- }
30
- function isRecord(value) {
31
- return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
32
- }
33
- function normalizeDictionaries(value) {
34
- if (!isRecord(value)) {
35
- return null;
36
- }
37
- const dictionaries = {};
38
- for (const [locale, labels] of Object.entries(value)) {
39
- if (!isRecord(labels)) {
40
- continue;
41
- }
42
- dictionaries[locale] = Object.fromEntries(Object.entries(labels).filter((entry) => typeof entry[1] === 'string'));
43
- }
44
- return dictionaries;
45
- }
46
- function applyLabelUpdate(payload) {
47
- if (!isRecord(payload)) {
48
- return;
49
- }
50
- const dictionaries = normalizeDictionaries(payload.dictionaries);
51
- if (!dictionaries) {
52
- return;
53
- }
54
- const defaultLocale = typeof payload.defaultLocale === 'string' ? payload.defaultLocale : labelState.defaultLocale;
55
- const signature = typeof payload.signature === 'string' ? payload.signature : JSON.stringify({ dictionaries, defaultLocale });
56
- const updatedAt = typeof payload.updatedAt === 'string' ? payload.updatedAt : null;
57
- setLabelState({ dictionaries, defaultLocale, signature, updatedAt });
58
- }
11
+ });
59
12
  // @ts-ignore - import.meta.hot is provided by Vite during development.
60
13
  if (import.meta.hot) {
61
14
  const onLabelsUpdated = (payload) => {
@@ -69,35 +22,4 @@ if (import.meta.hot) {
69
22
  import.meta.hot.off('fimo:labels-updated', onLabelsUpdated);
70
23
  });
71
24
  }
72
- /**
73
- * Hook to provide a label function (`t`).
74
- *
75
- * Returns FimoString with source tracking for inline editing.
76
- * Use with <Text> component for rendering, or String() for escape hatch.
77
- *
78
- * @example
79
- * const { t } = useLabels();
80
- *
81
- * // With Text component (recommended)
82
- * <Text value={t('welcome')} />
83
- *
84
- * // Escape hatch for attributes
85
- * <input placeholder={String(t('email.placeholder'))} />
86
- */
87
- export function useLabels() {
88
- const localeContext = useLocale();
89
- const labels = useSyncExternalStore(subscribeLabels, getLabelSnapshot, getLabelSnapshot);
90
- const t = (fullKey) => {
91
- const locale = localeContext.locale || labels.defaultLocale || 'en';
92
- const dictionary = labels.dictionaries[locale] ?? labels.dictionaries[labels.defaultLocale] ?? {};
93
- const text = dictionary[fullKey] ?? '';
94
- return new FimoString(text, `__labels.${locale}.${fullKey}.value`);
95
- };
96
- return { t, locale: localeContext.locale };
97
- }
98
- /**
99
- * Legacy alias for older projects. Prefer useLabels() in new code.
100
- */
101
- export function useTranslations() {
102
- return useLabels();
103
- }
25
+ export { useLabels, useTranslations } from './labels-hook.js';
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import type { FimoConfig } from '../shared/fimo-config.types.js';
3
+ import type { WrappedMediaEntry, WrappedRichTextEntry } from '../wrapped/WrappedContentContext.js';
4
+ export interface FimoSpaProvidersProps {
5
+ /** The project's fimo-config.json — import it directly: `import config from '../fimo-config.json'`. */
6
+ config: FimoConfig;
7
+ /** Tenant API base URL, e.g. `import.meta.env.VITE_API_URL`. Without it, wrapped values render their inline fallbacks. */
8
+ apiUrl?: string;
9
+ /** Preview client script for Fimo Studio edit mode. Pass only in dev, e.g. `import.meta.env.DEV ? import.meta.env.VITE_FIMO_PREVIEW_SCRIPT_URL : undefined`. */
10
+ previewScriptUrl?: string;
11
+ media?: Record<string, WrappedMediaEntry>;
12
+ richText?: Record<string, WrappedRichTextEntry>;
13
+ locale?: string;
14
+ children?: React.ReactNode;
15
+ }
16
+ /**
17
+ * Fimo providers for wrapped CLIENT-RENDERED React apps (Vite SPAs). There is
18
+ * no server pass to load labels in, so this adapter fetches the dictionary in
19
+ * the browser and hydrates the framework-neutral WrappedProviders; until the
20
+ * fetch resolves (or when it fails), every wrapped value renders its inline
21
+ * fallback — the original hardcoded string. Mount once around the app root:
22
+ *
23
+ * import config from '../fimo-config.json';
24
+ * <FimoSpaProviders
25
+ * config={config}
26
+ * apiUrl={import.meta.env.VITE_API_URL}
27
+ * previewScriptUrl={import.meta.env.DEV ? import.meta.env.VITE_FIMO_PREVIEW_SCRIPT_URL : undefined}
28
+ * >
29
+ * <App />
30
+ * </FimoSpaProviders>
31
+ *
32
+ * Navigation is History-API based (full page load): correct for any SPA
33
+ * router without depending on one.
34
+ */
35
+ export declare function FimoSpaProviders({ config, apiUrl, previewScriptUrl, media, richText, locale, children, }: FimoSpaProvidersProps): import("react/jsx-runtime").JSX.Element;
36
+ //# sourceMappingURL=FimoSpaProviders.d.ts.map
@@ -0,0 +1,122 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useRef, useState } from 'react';
4
+ import { getFimoDefaultLocale, getFimoLocales } from '../i18n/locale.js';
5
+ import { fetchLabelBundle } from '../shared/labels-fetch.pure.js';
6
+ import { fetchWrappedContent } from '../wrapped/content-fetch.pure.js';
7
+ import { WrappedProviders } from '../wrapped/WrappedProviders.js';
8
+ import { readInitialSpaContent, spaBundleSignature, writeSpaContentCache } from './spa-content-cache.js';
9
+ /**
10
+ * Fimo providers for wrapped CLIENT-RENDERED React apps (Vite SPAs). There is
11
+ * no server pass to load labels in, so this adapter fetches the dictionary in
12
+ * the browser and hydrates the framework-neutral WrappedProviders; until the
13
+ * fetch resolves (or when it fails), every wrapped value renders its inline
14
+ * fallback — the original hardcoded string. Mount once around the app root:
15
+ *
16
+ * import config from '../fimo-config.json';
17
+ * <FimoSpaProviders
18
+ * config={config}
19
+ * apiUrl={import.meta.env.VITE_API_URL}
20
+ * previewScriptUrl={import.meta.env.DEV ? import.meta.env.VITE_FIMO_PREVIEW_SCRIPT_URL : undefined}
21
+ * >
22
+ * <App />
23
+ * </FimoSpaProviders>
24
+ *
25
+ * Navigation is History-API based (full page load): correct for any SPA
26
+ * router without depending on one.
27
+ */
28
+ export function FimoSpaProviders({ config, apiUrl, previewScriptUrl, media, richText, locale, children, }) {
29
+ // Synchronous first paint: baked SSG payload or the last visit's cached
30
+ // one renders IMMEDIATELY (the SDK owns rendering — no fallback flash
31
+ // while the network round-trips); the fetches below revalidate it.
32
+ const initial = useMemo(() => readInitialSpaContent(apiUrl), [apiUrl]);
33
+ const [labels, setLabels] = useState(initial?.labels ?? undefined);
34
+ const [content, setContent] = useState(initial?.content ?? undefined);
35
+ const latestRef = useRef({
36
+ labels: initial?.labels ?? undefined,
37
+ content: initial?.content ?? undefined,
38
+ });
39
+ useEffect(() => {
40
+ if (!apiUrl) {
41
+ return;
42
+ }
43
+ let disposed = false;
44
+ const persist = () => {
45
+ writeSpaContentCache(apiUrl, { labels: latestRef.current.labels, content: latestRef.current.content });
46
+ };
47
+ const revalidate = () => {
48
+ const defaultLocale = getFimoDefaultLocale(config);
49
+ fetchLabelBundle(apiUrl, getFimoLocales(config), defaultLocale)
50
+ .then((bundle) => {
51
+ if (!disposed) {
52
+ const next = { ...bundle, signature: spaBundleSignature(bundle) };
53
+ latestRef.current.labels = next;
54
+ setLabels(next);
55
+ persist();
56
+ }
57
+ })
58
+ .catch(() => {
59
+ // Unreachable API: keep rendering the cached/baked values or fallbacks.
60
+ });
61
+ // Wrapped rich text and media live in the plumbing types — without this
62
+ // fetch a client-rendered app only ever shows their inline fallbacks
63
+ // and Studio edits to them render nowhere.
64
+ fetchWrappedContent(apiUrl)
65
+ .then((fetched) => {
66
+ if (!disposed) {
67
+ latestRef.current.content = fetched;
68
+ setContent(fetched);
69
+ persist();
70
+ }
71
+ })
72
+ .catch(() => {
73
+ // Unreachable API: keep rendering the cached/baked values or fallbacks.
74
+ });
75
+ };
76
+ revalidate();
77
+ // Live updates, no refresh needed:
78
+ // 1. Inside the Fimo Studio preview, every save posts
79
+ // `{ type: 'content/refresh' }` into the iframe — refetch on the spot
80
+ // (same contract the template runtime's RefreshContentProvider uses).
81
+ // 2. In a plain tab, coming back to the site (alt-tab from the Studio)
82
+ // revalidates on focus/visibility — edits appear without a reload.
83
+ let lastRun = Date.now();
84
+ const throttledRevalidate = () => {
85
+ if (Date.now() - lastRun < 1500) {
86
+ return;
87
+ }
88
+ lastRun = Date.now();
89
+ revalidate();
90
+ };
91
+ const onMessage = (event) => {
92
+ if (event.data?.type === 'content/refresh') {
93
+ lastRun = Date.now();
94
+ revalidate();
95
+ }
96
+ };
97
+ const onVisibility = () => {
98
+ if (document.visibilityState === 'visible') {
99
+ throttledRevalidate();
100
+ }
101
+ };
102
+ window.addEventListener('message', onMessage);
103
+ window.addEventListener('focus', throttledRevalidate);
104
+ document.addEventListener('visibilitychange', onVisibility);
105
+ return () => {
106
+ disposed = true;
107
+ window.removeEventListener('message', onMessage);
108
+ window.removeEventListener('focus', throttledRevalidate);
109
+ document.removeEventListener('visibilitychange', onVisibility);
110
+ };
111
+ }, [apiUrl, config]);
112
+ // Explicitly-passed maps win over the fetched ones (caller override).
113
+ const mergedMedia = useMemo(() => (content?.media || media ? { ...(content?.media ?? {}), ...(media ?? {}) } : undefined), [content?.media, media]);
114
+ const mergedRichText = useMemo(() => (content?.richText || richText ? { ...(content?.richText ?? {}), ...(richText ?? {}) } : undefined), [content?.richText, richText]);
115
+ const navigation = useMemo(() => ({
116
+ pathname: typeof window !== 'undefined' ? window.location.pathname : null,
117
+ navigate: (to) => {
118
+ window.location.assign(to);
119
+ },
120
+ }), []);
121
+ return (_jsxs(WrappedProviders, { config: config, labels: labels, media: mergedMedia, richText: mergedRichText, locale: locale, navigation: navigation, children: [previewScriptUrl ? _jsx("script", { type: "module", src: previewScriptUrl }) : null, children] }));
122
+ }
@@ -0,0 +1,35 @@
1
+ export { Text } from '../primitives/components/Text.js';
2
+ export { Image } from '../primitives/components/Image.js';
3
+ export { StaticImage } from '../primitives/components/StaticImage.js';
4
+ export { Video } from '../primitives/components/Video.js';
5
+ export { Date } from '../primitives/components/Date.js';
6
+ export { Boolean } from '../primitives/components/Boolean.js';
7
+ export { RichText } from '../primitives/components/RichText.js';
8
+ export { useLabels, useTranslations } from '../primitives/labels-hook.js';
9
+ export { applyLabelUpdate, getLabelSnapshot, hydrateLabels, subscribeLabels } from '../primitives/labels-store.js';
10
+ export type { LabelState } from '../primitives/labels-store.js';
11
+ export { FimoText } from '../wrapped/FimoText.js';
12
+ export { FimoRichTextBlock } from '../wrapped/FimoRichTextBlock.js';
13
+ export { FimoMediaImage } from '../wrapped/FimoMediaImage.js';
14
+ export { FimoMediaVideo } from '../wrapped/FimoMediaVideo.js';
15
+ export { FimoFileLink } from '../wrapped/FimoFileLink.js';
16
+ export { useWrappedMedia, useWrappedRichText } from '../wrapped/WrappedContentContext.js';
17
+ export type { WrappedMediaEntry, WrappedRichTextEntry } from '../wrapped/WrappedContentContext.js';
18
+ export { FimoSpaProviders } from './FimoSpaProviders.js';
19
+ export type { FimoSpaProvidersProps } from './FimoSpaProviders.js';
20
+ export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, type FimoSource, type FimoPart, type FimoRichTextContent, type FimoRichTextNodeProps, type FimoRichTextMarkProps, type FimoRichTextComponents, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, } from '../primitives/lib/index.js';
21
+ export { fimo } from '../primitives/lib/template.js';
22
+ export { useFimoLiveValue } from '../primitives/lib/useFimoLiveValue.js';
23
+ export { DataSourcesProvider } from '../content/DataSourcesProvider.js';
24
+ export { ConsoleErrorProvider } from '../iframe/ConsoleErrorProvider.js';
25
+ export { ScreenshotProvider } from '../iframe/ScreenshotProvider.js';
26
+ export { FimoLocaleProvider, useLocale } from '../i18n/FimoLocaleContext.js';
27
+ export type { FimoLocaleContextValue } from '../i18n/FimoLocaleContext.js';
28
+ export { getFimoDefaultLocale, getFimoLocales, getFimoTextDirection, localizeFimoPath, resolveFimoLocale, toHtmlLang, } from '../i18n/locale.js';
29
+ export type { FimoLocaleResolution } from '../i18n/locale.js';
30
+ export { getDisplayRoutes } from '../shared/display-routes.js';
31
+ export type { DisplayRoute, ParamInfo } from '../shared/display-routes.js';
32
+ export type { FimoConfig, FimoRouteConfig, FimoSEO } from '../shared/fimo-config.types.js';
33
+ export { fetchFimoSpaContent, serializeFimoSpaContent } from './spa-content-cache.js';
34
+ export type { SpaContentPayload } from './spa-content-cache.js';
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,40 @@
1
+ // fimo/react — the framework-agnostic React core of the Fimo runtime.
2
+ // No Vite virtual modules, no react-router, no bundler assumptions:
3
+ // per-framework adapters (fimo/react-router via fimo/ui, fimo/next, ...)
4
+ // build on this surface.
5
+ // Inline-editing components
6
+ export { Text } from '../primitives/components/Text.js';
7
+ export { Image } from '../primitives/components/Image.js';
8
+ export { StaticImage } from '../primitives/components/StaticImage.js';
9
+ export { Video } from '../primitives/components/Video.js';
10
+ export { Date } from '../primitives/components/Date.js';
11
+ export { Boolean } from '../primitives/components/Boolean.js';
12
+ export { RichText } from '../primitives/components/RichText.js';
13
+ // Labels (framework-neutral store + hook; adapters hydrate the store)
14
+ export { useLabels, useTranslations } from '../primitives/labels-hook.js';
15
+ export { applyLabelUpdate, getLabelSnapshot, hydrateLabels, subscribeLabels } from '../primitives/labels-store.js';
16
+ // Wrapped-site primitives (the --apply codemod imports these from fimo/react
17
+ // in Vite React SPAs) + the client-side providers that hydrate them. All are
18
+ // fallback-safe without a provider: FimoText renders its children, media
19
+ // elements render their original src.
20
+ export { FimoText } from '../wrapped/FimoText.js';
21
+ export { FimoRichTextBlock } from '../wrapped/FimoRichTextBlock.js';
22
+ export { FimoMediaImage } from '../wrapped/FimoMediaImage.js';
23
+ export { FimoMediaVideo } from '../wrapped/FimoMediaVideo.js';
24
+ export { FimoFileLink } from '../wrapped/FimoFileLink.js';
25
+ export { useWrappedMedia, useWrappedRichText } from '../wrapped/WrappedContentContext.js';
26
+ export { FimoSpaProviders } from './FimoSpaProviders.js';
27
+ // Source-tracking primitives & utilities
28
+ export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, } from '../primitives/lib/index.js';
29
+ export { fimo } from '../primitives/lib/template.js';
30
+ export { useFimoLiveValue } from '../primitives/lib/useFimoLiveValue.js';
31
+ // Preview/editor bridge providers (postMessage-based, framework-free)
32
+ export { DataSourcesProvider } from '../content/DataSourcesProvider.js';
33
+ export { ConsoleErrorProvider } from '../iframe/ConsoleErrorProvider.js';
34
+ export { ScreenshotProvider } from '../iframe/ScreenshotProvider.js';
35
+ // Locale
36
+ export { FimoLocaleProvider, useLocale } from '../i18n/FimoLocaleContext.js';
37
+ export { getFimoDefaultLocale, getFimoLocales, getFimoTextDirection, localizeFimoPath, resolveFimoLocale, toHtmlLang, } from '../i18n/locale.js';
38
+ // Config + routes
39
+ export { getDisplayRoutes } from '../shared/display-routes.js';
40
+ export { fetchFimoSpaContent, serializeFimoSpaContent } from './spa-content-cache.js';
@@ -0,0 +1,38 @@
1
+ import type { FimoConfig } from '../shared/fimo-config.types.js';
2
+ import { type LabelBundle } from '../shared/labels-fetch.pure.js';
3
+ import { type WrappedContent } from '../wrapped/content-fetch.pure.js';
4
+ import type { WrappedLabels } from '../wrapped/WrappedProviders.js';
5
+ /**
6
+ * Instant first paint for client-rendered wrapped apps: the SDK controls
7
+ * rendering, so it never has to flash fallbacks while the network round
8
+ * trips. Two synchronous sources, in priority order:
9
+ *
10
+ * 1. `window.__FIMO_CONTENT__` — baked by the site's SSG/prerender step
11
+ * (`serializeFimoSpaContent`), zero flash even on the first ever visit;
12
+ * 2. the last fetched payload cached in localStorage — instant from the
13
+ * second visit on, revalidated in the background (stale-while-revalidate).
14
+ */
15
+ export interface SpaContentPayload {
16
+ labels?: WrappedLabels;
17
+ content?: WrappedContent;
18
+ }
19
+ declare global {
20
+ interface Window {
21
+ __FIMO_CONTENT__?: SpaContentPayload;
22
+ }
23
+ }
24
+ export declare function readInitialSpaContent(apiUrl: string | undefined): SpaContentPayload | null;
25
+ export declare function writeSpaContentCache(apiUrl: string, payload: SpaContentPayload): void;
26
+ /** Browser-safe stable signature (labelSignature uses Buffer, server-only). */
27
+ export declare function spaBundleSignature(bundle: LabelBundle): string;
28
+ /**
29
+ * Build-time half of the bake: fetch the exact payload the provider's
30
+ * background revalidation produces (labels with the same signature shape,
31
+ * wrapped rich text + media), ready for `serializeFimoSpaContent`. Runs
32
+ * anywhere `fetch` exists — an SSG/prerender node script included.
33
+ */
34
+ export declare function fetchFimoSpaContent(apiUrl: string, config: FimoConfig): Promise<SpaContentPayload>;
35
+ /** SSG helper: a script tag baking the payload into prerendered HTML so the
36
+ * provider hydrates it synchronously — zero content flash. */
37
+ export declare function serializeFimoSpaContent(payload: SpaContentPayload): string;
38
+ //# sourceMappingURL=spa-content-cache.d.ts.map
@@ -0,0 +1,64 @@
1
+ import { getFimoDefaultLocale, getFimoLocales } from '../i18n/locale.js';
2
+ import { fetchLabelBundle, serializeBundle } from '../shared/labels-fetch.pure.js';
3
+ import { fetchWrappedContent } from '../wrapped/content-fetch.pure.js';
4
+ const CACHE_PREFIX = 'fimo:spa-content:';
5
+ export function readInitialSpaContent(apiUrl) {
6
+ if (typeof window === 'undefined') {
7
+ return null;
8
+ }
9
+ if (window.__FIMO_CONTENT__ && typeof window.__FIMO_CONTENT__ === 'object') {
10
+ return window.__FIMO_CONTENT__;
11
+ }
12
+ if (!apiUrl) {
13
+ return null;
14
+ }
15
+ try {
16
+ const raw = window.localStorage.getItem(CACHE_PREFIX + apiUrl);
17
+ return raw ? JSON.parse(raw) : null;
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ export function writeSpaContentCache(apiUrl, payload) {
24
+ if (typeof window === 'undefined') {
25
+ return;
26
+ }
27
+ try {
28
+ window.localStorage.setItem(CACHE_PREFIX + apiUrl, JSON.stringify(payload));
29
+ }
30
+ catch {
31
+ // Quota/private mode: the cache is an optimization, never a requirement.
32
+ }
33
+ }
34
+ /** Browser-safe stable signature (labelSignature uses Buffer, server-only). */
35
+ export function spaBundleSignature(bundle) {
36
+ const serialized = serializeBundle(bundle);
37
+ let hash = 5381;
38
+ for (let i = 0; i < serialized.length; i++) {
39
+ hash = ((hash << 5) + hash + serialized.charCodeAt(i)) | 0;
40
+ }
41
+ return `spa-${hash}`;
42
+ }
43
+ /**
44
+ * Build-time half of the bake: fetch the exact payload the provider's
45
+ * background revalidation produces (labels with the same signature shape,
46
+ * wrapped rich text + media), ready for `serializeFimoSpaContent`. Runs
47
+ * anywhere `fetch` exists — an SSG/prerender node script included.
48
+ */
49
+ export async function fetchFimoSpaContent(apiUrl, config) {
50
+ const [labels, content] = await Promise.all([
51
+ fetchLabelBundle(apiUrl, getFimoLocales(config), getFimoDefaultLocale(config)).then((bundle) => ({
52
+ ...bundle,
53
+ signature: spaBundleSignature(bundle),
54
+ })),
55
+ fetchWrappedContent(apiUrl),
56
+ ]);
57
+ return { labels, content };
58
+ }
59
+ /** SSG helper: a script tag baking the payload into prerendered HTML so the
60
+ * provider hydrates it synchronously — zero content flash. */
61
+ export function serializeFimoSpaContent(payload) {
62
+ const json = JSON.stringify(payload).replace(/</g, '\\u003c');
63
+ return `<script>window.__FIMO_CONTENT__=${json}</script>`;
64
+ }
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import type { FimoConfig } from '../shared/fimo-config.types.js';
3
+ import type { WrappedMediaEntry, WrappedRichTextEntry } from '../wrapped/WrappedContentContext.js';
4
+ import { type WrappedLabels } from '../wrapped/WrappedProviders.js';
5
+ export type FimoRemixLabels = WrappedLabels;
6
+ export interface FimoRemixProvidersProps {
7
+ config: FimoConfig;
8
+ labels?: FimoRemixLabels;
9
+ media?: Record<string, WrappedMediaEntry>;
10
+ richText?: Record<string, WrappedRichTextEntry>;
11
+ locale?: string;
12
+ children?: React.ReactNode;
13
+ }
14
+ /** Fimo providers for wrapped Remix apps — mount once in app/root.tsx. */
15
+ export declare function FimoRemixProviders(props: FimoRemixProvidersProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=FimoRemixProviders.d.ts.map
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useLocation, useNavigate } from '@remix-run/react';
4
+ import { useMemo } from 'react';
5
+ import { WrappedProviders } from '../wrapped/WrappedProviders.js';
6
+ /** Fimo providers for wrapped Remix apps — mount once in app/root.tsx. */
7
+ export function FimoRemixProviders(props) {
8
+ const location = useLocation();
9
+ const navigate = useNavigate();
10
+ const navigation = useMemo(() => ({ pathname: location.pathname, navigate: (to) => navigate(to) }), [location.pathname, navigate]);
11
+ return _jsx(WrappedProviders, { ...props, navigation: navigation });
12
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Renders the Fimo preview client script in development so the Fimo Studio
3
+ * preview can select/edit elements. Mount inside <head> in the root layout.
4
+ *
5
+ * The script URL comes from FIMO_PREVIEW_SCRIPT_URL (written by
6
+ * `fimo init` for wrapped projects, pointing at `<apiUrl>/preview.js`).
7
+ * Renders nothing in production builds.
8
+ */
9
+ export declare function FimoRemixScripts(): import("react/jsx-runtime").JSX.Element | null;
10
+ //# sourceMappingURL=FimoRemixScripts.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Renders the Fimo preview client script in development so the Fimo Studio
4
+ * preview can select/edit elements. Mount inside <head> in the root layout.
5
+ *
6
+ * The script URL comes from FIMO_PREVIEW_SCRIPT_URL (written by
7
+ * `fimo init` for wrapped projects, pointing at `<apiUrl>/preview.js`).
8
+ * Renders nothing in production builds.
9
+ */
10
+ export function FimoRemixScripts() {
11
+ if (process.env.NODE_ENV !== 'development') {
12
+ return null;
13
+ }
14
+ const previewScriptUrl = process.env.FIMO_PREVIEW_SCRIPT_URL;
15
+ if (!previewScriptUrl) {
16
+ return null;
17
+ }
18
+ return _jsx("script", { type: "module", src: previewScriptUrl });
19
+ }
@@ -0,0 +1,12 @@
1
+ export { FimoRemixProviders } from './FimoRemixProviders.js';
2
+ export type { FimoRemixLabels, FimoRemixProvidersProps } from './FimoRemixProviders.js';
3
+ export { FimoRemixScripts } from './FimoRemixScripts.js';
4
+ export { FimoText } from '../wrapped/FimoText.js';
5
+ export { FimoRichTextBlock } from '../wrapped/FimoRichTextBlock.js';
6
+ export { FimoMediaImage } from '../wrapped/FimoMediaImage.js';
7
+ export { FimoMediaVideo } from '../wrapped/FimoMediaVideo.js';
8
+ export { FimoFileLink } from '../wrapped/FimoFileLink.js';
9
+ export { useWrappedMedia, useWrappedRichText } from '../wrapped/WrappedContentContext.js';
10
+ export type { WrappedMediaEntry, WrappedRichTextEntry } from '../wrapped/WrappedContentContext.js';
11
+ export { useLabels } from '../primitives/labels-hook.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ // fimo/remix — the Remix adapter. Framework-neutral pieces live in
2
+ // ../wrapped and are re-exported; this module only adds the Remix wiring.
3
+ export { FimoRemixProviders } from './FimoRemixProviders.js';
4
+ export { FimoRemixScripts } from './FimoRemixScripts.js';
5
+ export { FimoText } from '../wrapped/FimoText.js';
6
+ export { FimoRichTextBlock } from '../wrapped/FimoRichTextBlock.js';
7
+ export { FimoMediaImage } from '../wrapped/FimoMediaImage.js';
8
+ export { FimoMediaVideo } from '../wrapped/FimoMediaVideo.js';
9
+ export { FimoFileLink } from '../wrapped/FimoFileLink.js';
10
+ export { useWrappedMedia, useWrappedRichText } from '../wrapped/WrappedContentContext.js';
11
+ export { useLabels } from '../primitives/labels-hook.js';
@@ -0,0 +1,2 @@
1
+ export * from '../wrapped/server.js';
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1,2 @@
1
+ // fimo/remix/server — same framework-neutral loaders as every adapter.
2
+ export * from '../wrapped/server.js';
@@ -0,0 +1,22 @@
1
+ import type { FimoSEO } from '../shared/fimo-config.types.js';
2
+ /**
3
+ * The framework-neutral `fimo/seo` surface: pure per-page SEO resolution over
4
+ * the page registry (`fimo-config.json#routes`), with no framework adapter,
5
+ * no vite virtual module, and no React. Every framework's injection recipe
6
+ * (Next `generateMetadata`, an Astro head component, a SvelteKit load) calls
7
+ * `getFimoSeoForPath` server-side and maps the result to its own head API.
8
+ * SEO stays wired only when the project owner explicitly opted into
9
+ * Fimo-managed SEO — the migration never wires it by default.
10
+ */
11
+ export { resolveSeoForPath } from './resolver.js';
12
+ export type { FimoSEO, RouteSEO } from '../shared/fimo-config.types.js';
13
+ export interface GetFimoSeoOptions {
14
+ /** Project root holding fimo-config.json (default: process.cwd()). */
15
+ rootDir?: string;
16
+ /** Instance data for `{{variable}}` templates in route-level SEO (e.g. the
17
+ * entry rendered by a dynamic page: `{ "blog-post": entry }`). */
18
+ routeData?: Record<string, unknown>;
19
+ }
20
+ /** Resolve the SEO values for one page path from the page registry on disk. */
21
+ export declare function getFimoSeoForPath(pathname: string, options?: GetFimoSeoOptions): FimoSEO | undefined;
22
+ //# sourceMappingURL=neutral.d.ts.map