@molecule/app-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +115 -0
- package/README.md +2645 -0
- package/dist/agent-identity.d.ts +40 -0
- package/dist/agent-identity.d.ts.map +1 -0
- package/dist/agent-identity.js +31 -0
- package/dist/agent-identity.js.map +1 -0
- package/dist/contexts.d.ts +69 -0
- package/dist/contexts.d.ts.map +1 -0
- package/dist/contexts.js +70 -0
- package/dist/contexts.js.map +1 -0
- package/dist/hooks/index.d.ts +32 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +32 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useAIModels.d.ts +48 -0
- package/dist/hooks/useAIModels.d.ts.map +1 -0
- package/dist/hooks/useAIModels.js +145 -0
- package/dist/hooks/useAIModels.js.map +1 -0
- package/dist/hooks/useAsyncState.d.ts +41 -0
- package/dist/hooks/useAsyncState.d.ts.map +1 -0
- package/dist/hooks/useAsyncState.js +77 -0
- package/dist/hooks/useAsyncState.js.map +1 -0
- package/dist/hooks/useAuth.d.ts +43 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useAuth.js +106 -0
- package/dist/hooks/useAuth.js.map +1 -0
- package/dist/hooks/useCapacitorApp.d.ts +35 -0
- package/dist/hooks/useCapacitorApp.d.ts.map +1 -0
- package/dist/hooks/useCapacitorApp.js +61 -0
- package/dist/hooks/useCapacitorApp.js.map +1 -0
- package/dist/hooks/useChangePassword.d.ts +34 -0
- package/dist/hooks/useChangePassword.d.ts.map +1 -0
- package/dist/hooks/useChangePassword.js +37 -0
- package/dist/hooks/useChangePassword.js.map +1 -0
- package/dist/hooks/useChat.d.ts +30 -0
- package/dist/hooks/useChat.d.ts.map +1 -0
- package/dist/hooks/useChat.js +1510 -0
- package/dist/hooks/useChat.js.map +1 -0
- package/dist/hooks/useDevice.d.ts +39 -0
- package/dist/hooks/useDevice.d.ts.map +1 -0
- package/dist/hooks/useDevice.js +41 -0
- package/dist/hooks/useDevice.js.map +1 -0
- package/dist/hooks/useEditor.d.ts +20 -0
- package/dist/hooks/useEditor.d.ts.map +1 -0
- package/dist/hooks/useEditor.js +98 -0
- package/dist/hooks/useEditor.js.map +1 -0
- package/dist/hooks/useForm.d.ts +87 -0
- package/dist/hooks/useForm.d.ts.map +1 -0
- package/dist/hooks/useForm.js +148 -0
- package/dist/hooks/useForm.js.map +1 -0
- package/dist/hooks/useHttp.d.ts +103 -0
- package/dist/hooks/useHttp.d.ts.map +1 -0
- package/dist/hooks/useHttp.js +161 -0
- package/dist/hooks/useHttp.js.map +1 -0
- package/dist/hooks/useLogger.d.ts +68 -0
- package/dist/hooks/useLogger.d.ts.map +1 -0
- package/dist/hooks/useLogger.js +95 -0
- package/dist/hooks/useLogger.js.map +1 -0
- package/dist/hooks/useLogin.d.ts +35 -0
- package/dist/hooks/useLogin.d.ts.map +1 -0
- package/dist/hooks/useLogin.js +37 -0
- package/dist/hooks/useLogin.js.map +1 -0
- package/dist/hooks/useOAuth.d.ts +83 -0
- package/dist/hooks/useOAuth.d.ts.map +1 -0
- package/dist/hooks/useOAuth.js +348 -0
- package/dist/hooks/useOAuth.js.map +1 -0
- package/dist/hooks/usePasswordReset.d.ts +43 -0
- package/dist/hooks/usePasswordReset.d.ts.map +1 -0
- package/dist/hooks/usePasswordReset.js +50 -0
- package/dist/hooks/usePasswordReset.js.map +1 -0
- package/dist/hooks/usePlatform.d.ts +38 -0
- package/dist/hooks/usePlatform.d.ts.map +1 -0
- package/dist/hooks/usePlatform.js +40 -0
- package/dist/hooks/usePlatform.js.map +1 -0
- package/dist/hooks/usePreview.d.ts +20 -0
- package/dist/hooks/usePreview.d.ts.map +1 -0
- package/dist/hooks/usePreview.js +62 -0
- package/dist/hooks/usePreview.js.map +1 -0
- package/dist/hooks/usePromise.d.ts +39 -0
- package/dist/hooks/usePromise.d.ts.map +1 -0
- package/dist/hooks/usePromise.js +92 -0
- package/dist/hooks/usePromise.js.map +1 -0
- package/dist/hooks/usePush.d.ts +50 -0
- package/dist/hooks/usePush.d.ts.map +1 -0
- package/dist/hooks/usePush.js +89 -0
- package/dist/hooks/usePush.js.map +1 -0
- package/dist/hooks/useRouter.d.ts +65 -0
- package/dist/hooks/useRouter.d.ts.map +1 -0
- package/dist/hooks/useRouter.js +120 -0
- package/dist/hooks/useRouter.js.map +1 -0
- package/dist/hooks/useSignup.d.ts +35 -0
- package/dist/hooks/useSignup.d.ts.map +1 -0
- package/dist/hooks/useSignup.js +37 -0
- package/dist/hooks/useSignup.js.map +1 -0
- package/dist/hooks/useStorage.d.ts +72 -0
- package/dist/hooks/useStorage.d.ts.map +1 -0
- package/dist/hooks/useStorage.js +144 -0
- package/dist/hooks/useStorage.js.map +1 -0
- package/dist/hooks/useStore.d.ts +51 -0
- package/dist/hooks/useStore.d.ts.map +1 -0
- package/dist/hooks/useStore.js +86 -0
- package/dist/hooks/useStore.js.map +1 -0
- package/dist/hooks/useTheme.d.ts +50 -0
- package/dist/hooks/useTheme.d.ts.map +1 -0
- package/dist/hooks/useTheme.js +135 -0
- package/dist/hooks/useTheme.js.map +1 -0
- package/dist/hooks/useTranslation.d.ts +69 -0
- package/dist/hooks/useTranslation.d.ts.map +1 -0
- package/dist/hooks/useTranslation.js +131 -0
- package/dist/hooks/useTranslation.js.map +1 -0
- package/dist/hooks/useVersion.d.ts +41 -0
- package/dist/hooks/useVersion.d.ts.map +1 -0
- package/dist/hooks/useVersion.js +73 -0
- package/dist/hooks/useVersion.js.map +1 -0
- package/dist/hooks/useWorkspace.d.ts +18 -0
- package/dist/hooks/useWorkspace.d.ts.map +1 -0
- package/dist/hooks/useWorkspace.js +67 -0
- package/dist/hooks/useWorkspace.js.map +1 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/providers.d.ts +189 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +248 -0
- package/dist/providers.js.map +1 -0
- package/dist/types.d.ts +381 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for internationalization.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { useCallback, useContext, useEffect, useState } from 'react';
|
|
7
|
+
import { I18nError, t } from '@molecule/app-i18n';
|
|
8
|
+
import { I18nContext } from '../contexts.js';
|
|
9
|
+
/**
|
|
10
|
+
* Hook to access the i18n provider from context.
|
|
11
|
+
*
|
|
12
|
+
* @returns The i18n provider from context
|
|
13
|
+
* @throws {Error} Error if used outside of I18nProvider
|
|
14
|
+
*/
|
|
15
|
+
export function useI18nProvider() {
|
|
16
|
+
const provider = useContext(I18nContext);
|
|
17
|
+
if (!provider) {
|
|
18
|
+
throw new Error(t('react.error.useI18nOutsideProvider', undefined, {
|
|
19
|
+
defaultValue: 'useI18nProvider must be used within an I18nProvider',
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
return provider;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Hook for internationalization.
|
|
26
|
+
*
|
|
27
|
+
* @returns Translation function and locale management
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const { t, locale, setLocale, formatNumber } = useTranslation()
|
|
32
|
+
*
|
|
33
|
+
* return (
|
|
34
|
+
* <div>
|
|
35
|
+
* <h1>{t('welcome.title', { name: 'User' })}</h1>
|
|
36
|
+
* <p>{formatNumber(1234.56, { style: 'currency', currency: 'USD' })}</p>
|
|
37
|
+
* <select value={locale} onChange={(e) => setLocale(e.target.value)}>
|
|
38
|
+
* <option value="en">English</option>
|
|
39
|
+
* <option value="es">Spanish</option>
|
|
40
|
+
* </select>
|
|
41
|
+
* </div>
|
|
42
|
+
* )
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function useTranslation() {
|
|
46
|
+
const provider = useI18nProvider();
|
|
47
|
+
const [locale, setLocaleState] = useState(() => provider.getLocale());
|
|
48
|
+
const [direction, setDirection] = useState(() => provider.getDirection());
|
|
49
|
+
const [locales, setLocales] = useState(() => provider.getLocales());
|
|
50
|
+
const [, forceUpdate] = useState({});
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const unsubscribe = provider.onLocaleChange(() => {
|
|
53
|
+
setLocaleState(provider.getLocale());
|
|
54
|
+
setDirection(provider.getDirection());
|
|
55
|
+
setLocales(provider.getLocales());
|
|
56
|
+
// Force re-render even when locale string is unchanged (e.g. when
|
|
57
|
+
// addTranslations adds new keys for the current locale).
|
|
58
|
+
forceUpdate({});
|
|
59
|
+
});
|
|
60
|
+
return unsubscribe;
|
|
61
|
+
}, [provider]);
|
|
62
|
+
// Memoized translation function
|
|
63
|
+
const t = useCallback((key, values, options) => provider.t(key, values, options), [provider, locale]);
|
|
64
|
+
// Memoized action wrappers
|
|
65
|
+
const setLocale = useCallback((code) => provider.setLocale(code), [provider]);
|
|
66
|
+
const formatNumber = useCallback((value, options) => provider.formatNumber(value, options), [provider]);
|
|
67
|
+
const formatDate = useCallback((value, options) => provider.formatDate(value, options), [provider]);
|
|
68
|
+
return {
|
|
69
|
+
t,
|
|
70
|
+
locale,
|
|
71
|
+
setLocale,
|
|
72
|
+
locales,
|
|
73
|
+
formatNumber,
|
|
74
|
+
formatDate,
|
|
75
|
+
direction,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Hook to get just the translation function.
|
|
80
|
+
*
|
|
81
|
+
* @returns The translation function
|
|
82
|
+
*/
|
|
83
|
+
export function useT() {
|
|
84
|
+
const provider = useI18nProvider();
|
|
85
|
+
return useCallback((key, values, options) => provider.t(key, values, options), [provider]);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Hook to get the current locale.
|
|
89
|
+
*
|
|
90
|
+
* @returns The current locale code
|
|
91
|
+
*/
|
|
92
|
+
export function useLocale() {
|
|
93
|
+
const { locale } = useTranslation();
|
|
94
|
+
return locale;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Hook to get the text direction.
|
|
98
|
+
*
|
|
99
|
+
* @returns The text direction ('ltr' or 'rtl')
|
|
100
|
+
*/
|
|
101
|
+
export function useDirection() {
|
|
102
|
+
const { direction } = useTranslation();
|
|
103
|
+
return direction;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Translates an error at render time so the displayed message updates automatically
|
|
107
|
+
* when the locale changes.
|
|
108
|
+
*
|
|
109
|
+
* **Always use this hook to display errors in React components** — accessing
|
|
110
|
+
* `error.message` directly bypasses re-translation and leaves stale text after a
|
|
111
|
+
* locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
|
|
112
|
+
* its key is translated using the current locale. For plain `Error` instances,
|
|
113
|
+
* `error.message` is returned unchanged.
|
|
114
|
+
*
|
|
115
|
+
* @param error - The error to translate, or `null`/`undefined`.
|
|
116
|
+
* @returns The translated error string, or `null` if no error.
|
|
117
|
+
*/
|
|
118
|
+
export function useI18nError(error) {
|
|
119
|
+
const { t } = useTranslation();
|
|
120
|
+
if (!error)
|
|
121
|
+
return null;
|
|
122
|
+
// defaultValue is the I18nError's own message — the fallback text its throw
|
|
123
|
+
// site provided (for a server error: the server's already-translated
|
|
124
|
+
// message). Without it, a key the CLIENT dictionary happens to lack renders
|
|
125
|
+
// as the raw key ("user.error.passwordTooShort") instead of a message.
|
|
126
|
+
if (error instanceof I18nError) {
|
|
127
|
+
return t(error.i18nKey, error.i18nValues, { defaultValue: error.message });
|
|
128
|
+
}
|
|
129
|
+
return error.message;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=useTranslation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTranslation.js","sourceRoot":"","sources":["../../src/hooks/useTranslation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAQpE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,CAAC,CAAC,oCAAoC,EAAE,SAAS,EAAE;YACjD,YAAY,EAAE,qDAAqD;SACpE,CAAC,CACH,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAA;IAElC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;IACrE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;IACzE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,EAAE;YAC/C,cAAc,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;YACpC,YAAY,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;YACrC,UAAU,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACjC,kEAAkE;YAClE,yDAAyD;YACzD,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;QACF,OAAO,WAAW,CAAA;IACpB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,gCAAgC;IAChC,MAAM,CAAC,GAAsB,WAAW,CACtC,CACE,GAAW,EACX,MAA4B,EAC5B,OAAmD,EACnD,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EACrC,CAAC,QAAQ,EAAE,MAAM,CAAC,CACnB,CAAA;IAED,2BAA2B;IAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAErF,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,KAAa,EAAE,OAA6B,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,EACvF,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,KAA6B,EAAE,OAA2B,EAAE,EAAE,CAC7D,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,EACrC,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,OAAO;QACL,CAAC;QACD,MAAM;QACN,SAAS;QACT,OAAO;QACP,YAAY;QACZ,UAAU;QACV,SAAS;KACV,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI;IAClB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAA;IAClC,OAAO,WAAW,CAChB,CACE,GAAW,EACX,MAA4B,EAC5B,OAAmD,EACnD,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EACrC,CAAC,QAAQ,CAAC,CACU,CAAA;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAA;IACnC,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,CAAA;IACtC,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,KAA+B;IAC1D,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,4EAA4E;IAC5E,qEAAqE;IACrE,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for version and update management.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { UpdateCheckOptions, VersionState } from '@molecule/app-version';
|
|
7
|
+
/**
|
|
8
|
+
* Hook return type.
|
|
9
|
+
*/
|
|
10
|
+
export interface UseVersionResult {
|
|
11
|
+
state: VersionState;
|
|
12
|
+
isUpdateAvailable: boolean;
|
|
13
|
+
isChecking: boolean;
|
|
14
|
+
isServiceWorkerWaiting: boolean;
|
|
15
|
+
newVersion: string | undefined;
|
|
16
|
+
checkForUpdates: () => Promise<boolean>;
|
|
17
|
+
applyUpdate: (options?: {
|
|
18
|
+
force?: boolean;
|
|
19
|
+
}) => void;
|
|
20
|
+
dismissUpdate: () => void;
|
|
21
|
+
startPeriodicChecks: (options?: UpdateCheckOptions) => void;
|
|
22
|
+
stopPeriodicChecks: () => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Hook for version state and update actions.
|
|
26
|
+
*
|
|
27
|
+
* Uses module-level `getProvider()` — version is a singleton, not context-provided.
|
|
28
|
+
*
|
|
29
|
+
* @returns Version state and action methods
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const { isUpdateAvailable, newVersion, applyUpdate, dismissUpdate } = useVersion()
|
|
34
|
+
*
|
|
35
|
+
* if (isUpdateAvailable) {
|
|
36
|
+
* return <div>Update to {newVersion} available! <button onClick={() => applyUpdate()}>Update</button></div>
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function useVersion(): UseVersionResult;
|
|
41
|
+
//# sourceMappingURL=useVersion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVersion.d.ts","sourceRoot":"","sources":["../../src/hooks/useVersion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAG7E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAA;IACnB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,sBAAsB,EAAE,OAAO,CAAA;IAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACvC,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACpD,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB,mBAAmB,EAAE,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAC3D,kBAAkB,EAAE,MAAM,IAAI,CAAA;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CAiE7C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for version and update management.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { useCallback, useRef, useSyncExternalStore } from 'react';
|
|
7
|
+
import { getProvider } from '@molecule/app-version';
|
|
8
|
+
/**
|
|
9
|
+
* Hook for version state and update actions.
|
|
10
|
+
*
|
|
11
|
+
* Uses module-level `getProvider()` — version is a singleton, not context-provided.
|
|
12
|
+
*
|
|
13
|
+
* @returns Version state and action methods
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const { isUpdateAvailable, newVersion, applyUpdate, dismissUpdate } = useVersion()
|
|
18
|
+
*
|
|
19
|
+
* if (isUpdateAvailable) {
|
|
20
|
+
* return <div>Update to {newVersion} available! <button onClick={() => applyUpdate()}>Update</button></div>
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function useVersion() {
|
|
25
|
+
const provider = getProvider();
|
|
26
|
+
// Cached ref for snapshot stability (prevents infinite re-renders with useSyncExternalStore)
|
|
27
|
+
const cachedStateRef = useRef(null);
|
|
28
|
+
const getSnapshot = useCallback(() => {
|
|
29
|
+
const next = provider.getState();
|
|
30
|
+
const prev = cachedStateRef.current;
|
|
31
|
+
if (prev !== null &&
|
|
32
|
+
prev.isUpdateAvailable === next.isUpdateAvailable &&
|
|
33
|
+
prev.isChecking === next.isChecking &&
|
|
34
|
+
prev.isServiceWorkerWaiting === next.isServiceWorkerWaiting &&
|
|
35
|
+
prev.newVersion === next.newVersion &&
|
|
36
|
+
prev.buildId === next.buildId &&
|
|
37
|
+
prev.version === next.version) {
|
|
38
|
+
return prev;
|
|
39
|
+
}
|
|
40
|
+
cachedStateRef.current = next;
|
|
41
|
+
return next;
|
|
42
|
+
}, [provider]);
|
|
43
|
+
const subscribe = useCallback((onStateChange) => {
|
|
44
|
+
const unsubs = [
|
|
45
|
+
provider.on('update-available', onStateChange),
|
|
46
|
+
provider.on('service-worker-waiting', onStateChange),
|
|
47
|
+
provider.on('service-worker-activated', onStateChange),
|
|
48
|
+
provider.on('check-start', onStateChange),
|
|
49
|
+
provider.on('check-complete', onStateChange),
|
|
50
|
+
provider.on('check-error', onStateChange),
|
|
51
|
+
];
|
|
52
|
+
return () => unsubs.forEach((unsub) => unsub());
|
|
53
|
+
}, [provider]);
|
|
54
|
+
const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
55
|
+
const checkForUpdates = useCallback(() => provider.checkForUpdates(), [provider]);
|
|
56
|
+
const applyUpdate = useCallback((options) => provider.applyUpdate(options), [provider]);
|
|
57
|
+
const dismissUpdate = useCallback(() => provider.dismissUpdate(), [provider]);
|
|
58
|
+
const startPeriodicChecks = useCallback((options) => provider.startPeriodicChecks(options), [provider]);
|
|
59
|
+
const stopPeriodicChecks = useCallback(() => provider.stopPeriodicChecks(), [provider]);
|
|
60
|
+
return {
|
|
61
|
+
state,
|
|
62
|
+
isUpdateAvailable: state.isUpdateAvailable,
|
|
63
|
+
isChecking: state.isChecking,
|
|
64
|
+
isServiceWorkerWaiting: state.isServiceWorkerWaiting,
|
|
65
|
+
newVersion: state.newVersion,
|
|
66
|
+
checkForUpdates,
|
|
67
|
+
applyUpdate,
|
|
68
|
+
dismissUpdate,
|
|
69
|
+
startPeriodicChecks,
|
|
70
|
+
stopPeriodicChecks,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=useVersion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVersion.js","sourceRoot":"","sources":["../../src/hooks/useVersion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAkBnD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAE9B,6FAA6F;IAC7F,MAAM,cAAc,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAA;IAExD,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;QAChC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAA;QACnC,IACE,IAAI,KAAK,IAAI;YACb,IAAI,CAAC,iBAAiB,KAAK,IAAI,CAAC,iBAAiB;YACjD,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU;YACnC,IAAI,CAAC,sBAAsB,KAAK,IAAI,CAAC,sBAAsB;YAC3D,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU;YACnC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;YAC7B,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAC7B,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QACD,cAAc,CAAC,OAAO,GAAG,IAAI,CAAA;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,aAAyB,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG;YACb,QAAQ,CAAC,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC;YAC9C,QAAQ,CAAC,EAAE,CAAC,wBAAwB,EAAE,aAAa,CAAC;YACpD,QAAQ,CAAC,EAAE,CAAC,0BAA0B,EAAE,aAAa,CAAC;YACtD,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;YACzC,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,aAAa,CAAC;YAC5C,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;SAC1C,CAAA;QACD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;IACjD,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;IAEvE,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IACjF,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,OAA6B,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,EAChE,CAAC,QAAQ,CAAC,CACX,CAAA;IACD,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC7E,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,OAA4B,EAAE,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,EACvE,CAAC,QAAQ,CAAC,CACX,CAAA;IACD,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEvF,OAAO;QACL,KAAK;QACL,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,eAAe;QACf,WAAW;QACX,aAAa;QACb,mBAAmB;QACnB,kBAAkB;KACnB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for IDE workspace provider.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { WorkspaceProvider } from '@molecule/app-ide';
|
|
7
|
+
import type { UseWorkspaceResult } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Access the workspace provider from context.
|
|
10
|
+
* @returns The result.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useWorkspaceProvider(): WorkspaceProvider;
|
|
13
|
+
/**
|
|
14
|
+
* Hook for IDE workspace layout management.
|
|
15
|
+
* @returns The workspace state and management methods.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useWorkspace(): UseWorkspaceResult;
|
|
18
|
+
//# sourceMappingURL=useWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspace.d.ts","sourceRoot":"","sources":["../../src/hooks/useWorkspace.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAW,iBAAiB,EAAkB,MAAM,mBAAmB,CAAA;AAGnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CAUxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAyDjD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for IDE workspace provider.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { useCallback, useContext, useRef, useSyncExternalStore } from 'react';
|
|
7
|
+
import { t } from '@molecule/app-i18n';
|
|
8
|
+
import { WorkspaceContext } from '../contexts.js';
|
|
9
|
+
/**
|
|
10
|
+
* Access the workspace provider from context.
|
|
11
|
+
* @returns The result.
|
|
12
|
+
*/
|
|
13
|
+
export function useWorkspaceProvider() {
|
|
14
|
+
const provider = useContext(WorkspaceContext);
|
|
15
|
+
if (!provider) {
|
|
16
|
+
throw new Error(t('react.error.useWorkspaceOutsideProvider', undefined, {
|
|
17
|
+
defaultValue: 'useWorkspaceProvider must be used within a WorkspaceProvider',
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
return provider;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Hook for IDE workspace layout management.
|
|
24
|
+
* @returns The workspace state and management methods.
|
|
25
|
+
*/
|
|
26
|
+
export function useWorkspace() {
|
|
27
|
+
const provider = useWorkspaceProvider();
|
|
28
|
+
const cachedRef = useRef(null);
|
|
29
|
+
const getSnapshot = useCallback(() => {
|
|
30
|
+
const layout = provider.getLayout();
|
|
31
|
+
// Create a state object — provider.subscribe gives us the full WorkspaceState
|
|
32
|
+
// but getLayout only gives us the layout. Use a lightweight cache comparison.
|
|
33
|
+
const prev = cachedRef.current;
|
|
34
|
+
if (prev && prev.layout === layout) {
|
|
35
|
+
return prev;
|
|
36
|
+
}
|
|
37
|
+
const next = {
|
|
38
|
+
layout,
|
|
39
|
+
activePanel: null,
|
|
40
|
+
collapsedPanels: new Set(),
|
|
41
|
+
isFullscreen: false,
|
|
42
|
+
};
|
|
43
|
+
cachedRef.current = next;
|
|
44
|
+
return next;
|
|
45
|
+
}, [provider]);
|
|
46
|
+
const subscribe = useCallback((onStoreChange) => {
|
|
47
|
+
return provider.subscribe((state) => {
|
|
48
|
+
cachedRef.current = state;
|
|
49
|
+
onStoreChange();
|
|
50
|
+
});
|
|
51
|
+
}, [provider]);
|
|
52
|
+
const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
53
|
+
const togglePanel = useCallback((panelId) => provider.togglePanel(panelId), [provider]);
|
|
54
|
+
const resizePanel = useCallback((panelId, size) => provider.resizePanel(panelId, size), [provider]);
|
|
55
|
+
const setActivePanel = useCallback((panelId) => provider.setActivePanel(panelId), [provider]);
|
|
56
|
+
const resetLayout = useCallback(() => provider.resetLayout(), [provider]);
|
|
57
|
+
return {
|
|
58
|
+
layout: state.layout,
|
|
59
|
+
activePanel: state.activePanel,
|
|
60
|
+
collapsedPanels: state.collapsedPanels,
|
|
61
|
+
togglePanel,
|
|
62
|
+
resizePanel,
|
|
63
|
+
setActivePanel,
|
|
64
|
+
resetLayout,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=useWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspace.js","sourceRoot":"","sources":["../../src/hooks/useWorkspace.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAE7E,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAGtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAGjD;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,CAAC,CAAC,yCAAyC,EAAE,SAAS,EAAE;YACtD,YAAY,EAAE,8DAA8D;SAC7E,CAAC,CACH,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAA;IACvC,MAAM,SAAS,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAA;IAErD,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;QACnC,8EAA8E;QAC9E,8EAA8E;QAC9E,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAA;QAC9B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACnC,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,IAAI,GAAmB;YAC3B,MAAM;YACN,WAAW,EAAE,IAAI;YACjB,eAAe,EAAE,IAAI,GAAG,EAAE;YAC1B,YAAY,EAAE,KAAK;SACpB,CAAA;QACD,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,aAAyB,EAAE,EAAE;QAC5B,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAClC,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;YACzB,aAAa,EAAE,CAAA;QACjB,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;IAEvE,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEhG,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,OAAgB,EAAE,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,EACvE,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EACtD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEzE,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,WAAW;QACX,WAAW;QACX,cAAc;QACd,WAAW;KACZ,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React framework bindings for the Molecule app stack.
|
|
3
|
+
*
|
|
4
|
+
* Provides React hooks, contexts, and provider components for all molecule
|
|
5
|
+
* core interfaces (auth, i18n, theme, routing, state, http, storage, logger,
|
|
6
|
+
* chat, workspace, editor, preview), so framework-agnostic providers plug
|
|
7
|
+
* into React idioms.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { MoleculeProvider, useAuth, useTheme, useTranslation } from '@molecule/app-react'
|
|
12
|
+
* import { provider as stateProvider } from '@molecule/app-state-zustand'
|
|
13
|
+
* import { provider as themeProvider } from '@molecule/app-theme-css-variables'
|
|
14
|
+
* import { provider as i18nProvider } from '@molecule/app-i18n-react-i18next'
|
|
15
|
+
* import { createJWTAuthClient } from '@molecule/app-auth'
|
|
16
|
+
*
|
|
17
|
+
* const authClient = createJWTAuthClient({ baseURL: '/api' })
|
|
18
|
+
*
|
|
19
|
+
* function Dashboard() {
|
|
20
|
+
* const { user, isAuthenticated, logout } = useAuth<{ name?: string }>()
|
|
21
|
+
* const { t } = useTranslation()
|
|
22
|
+
* const { theme, toggleTheme } = useTheme()
|
|
23
|
+
*
|
|
24
|
+
* if (!isAuthenticated) {
|
|
25
|
+
* return <p>{t('auth.required', undefined, { defaultValue: 'Please log in.' })}</p>
|
|
26
|
+
* }
|
|
27
|
+
* return (
|
|
28
|
+
* <div style={{ background: theme.colors.background }}>
|
|
29
|
+
* <h1>{t('greeting.welcome', { name: user?.name }, { defaultValue: 'Welcome, {{name}}!' })}</h1>
|
|
30
|
+
* <button onClick={toggleTheme}>{t('theme.toggle', undefined, { defaultValue: 'Toggle theme' })}</button>
|
|
31
|
+
* <button onClick={() => logout()}>{t('auth.logout', undefined, { defaultValue: 'Log out' })}</button>
|
|
32
|
+
* </div>
|
|
33
|
+
* )
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* function App() {
|
|
37
|
+
* return (
|
|
38
|
+
* <MoleculeProvider
|
|
39
|
+
* state={stateProvider}
|
|
40
|
+
* auth={authClient}
|
|
41
|
+
* theme={themeProvider}
|
|
42
|
+
* i18n={i18nProvider}
|
|
43
|
+
* >
|
|
44
|
+
* <Dashboard />
|
|
45
|
+
* </MoleculeProvider>
|
|
46
|
+
* )
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* - **Every hook throws when its provider is not mounted.** `MoleculeProvider` wires ONLY the
|
|
52
|
+
* services you pass as props — it is a convenience wrapper, not a default registry. The map:
|
|
53
|
+
* `useAuth`→`auth`, `useTranslation`/`useT`→`i18n`, `useTheme`→`theme`, `useRouter`→`router`,
|
|
54
|
+
* `useStore`→`state`, `useHttp`→`http`, `useStorage`→`storage`, `useLogger`→`logger`,
|
|
55
|
+
* `useChat`→`chat`, `useWorkspace`→`workspace`, `useEditor`→`editor`, `usePreview`→`preview`.
|
|
56
|
+
* "useXProvider must be used within an XProvider" means the matching prop (or individual
|
|
57
|
+
* provider component) is missing ABOVE the component that calls the hook — fix the wiring,
|
|
58
|
+
* never wrap the hook in try/catch.
|
|
59
|
+
* - **Locale-reactive text requires the hook.** Inside components always read `t` from
|
|
60
|
+
* `useTranslation()` (or `useT()`); it re-renders on `onLocaleChange` — even when
|
|
61
|
+
* `addTranslations()` only adds keys for the current locale. Calling the raw `t()` import from
|
|
62
|
+
* `@molecule/app-i18n` in render works once but leaves stale text after a locale switch.
|
|
63
|
+
* - **Exactly one React copy.** In workspace/symlinked dev setups a second React instance makes
|
|
64
|
+
* every hook fail ("Invalid hook call", or the provider errors above with the provider
|
|
65
|
+
* mounted). Scaffolded Vite configs ship
|
|
66
|
+
* `resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` — keep it, and
|
|
67
|
+
* add any new hook-bearing peer library there too.
|
|
68
|
+
* - `RouterProvider` carries a molecule `Router` (e.g. `createReactRouter()` from
|
|
69
|
+
* `@molecule/app-routing-react-router`). react-router's own `<BrowserRouter>` context is
|
|
70
|
+
* separate — components that render react-router `<Link>` (several in
|
|
71
|
+
* `@molecule/app-ui-react`) need it in addition to the molecule providers.
|
|
72
|
+
*
|
|
73
|
+
* @module
|
|
74
|
+
*/
|
|
75
|
+
export * from './agent-identity.js';
|
|
76
|
+
export * from './contexts.js';
|
|
77
|
+
export * from './hooks/index.js';
|
|
78
|
+
export * from './providers.js';
|
|
79
|
+
export * from './types.js';
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AAEH,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React framework bindings for the Molecule app stack.
|
|
3
|
+
*
|
|
4
|
+
* Provides React hooks, contexts, and provider components for all molecule
|
|
5
|
+
* core interfaces (auth, i18n, theme, routing, state, http, storage, logger,
|
|
6
|
+
* chat, workspace, editor, preview), so framework-agnostic providers plug
|
|
7
|
+
* into React idioms.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { MoleculeProvider, useAuth, useTheme, useTranslation } from '@molecule/app-react'
|
|
12
|
+
* import { provider as stateProvider } from '@molecule/app-state-zustand'
|
|
13
|
+
* import { provider as themeProvider } from '@molecule/app-theme-css-variables'
|
|
14
|
+
* import { provider as i18nProvider } from '@molecule/app-i18n-react-i18next'
|
|
15
|
+
* import { createJWTAuthClient } from '@molecule/app-auth'
|
|
16
|
+
*
|
|
17
|
+
* const authClient = createJWTAuthClient({ baseURL: '/api' })
|
|
18
|
+
*
|
|
19
|
+
* function Dashboard() {
|
|
20
|
+
* const { user, isAuthenticated, logout } = useAuth<{ name?: string }>()
|
|
21
|
+
* const { t } = useTranslation()
|
|
22
|
+
* const { theme, toggleTheme } = useTheme()
|
|
23
|
+
*
|
|
24
|
+
* if (!isAuthenticated) {
|
|
25
|
+
* return <p>{t('auth.required', undefined, { defaultValue: 'Please log in.' })}</p>
|
|
26
|
+
* }
|
|
27
|
+
* return (
|
|
28
|
+
* <div style={{ background: theme.colors.background }}>
|
|
29
|
+
* <h1>{t('greeting.welcome', { name: user?.name }, { defaultValue: 'Welcome, {{name}}!' })}</h1>
|
|
30
|
+
* <button onClick={toggleTheme}>{t('theme.toggle', undefined, { defaultValue: 'Toggle theme' })}</button>
|
|
31
|
+
* <button onClick={() => logout()}>{t('auth.logout', undefined, { defaultValue: 'Log out' })}</button>
|
|
32
|
+
* </div>
|
|
33
|
+
* )
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* function App() {
|
|
37
|
+
* return (
|
|
38
|
+
* <MoleculeProvider
|
|
39
|
+
* state={stateProvider}
|
|
40
|
+
* auth={authClient}
|
|
41
|
+
* theme={themeProvider}
|
|
42
|
+
* i18n={i18nProvider}
|
|
43
|
+
* >
|
|
44
|
+
* <Dashboard />
|
|
45
|
+
* </MoleculeProvider>
|
|
46
|
+
* )
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* - **Every hook throws when its provider is not mounted.** `MoleculeProvider` wires ONLY the
|
|
52
|
+
* services you pass as props — it is a convenience wrapper, not a default registry. The map:
|
|
53
|
+
* `useAuth`→`auth`, `useTranslation`/`useT`→`i18n`, `useTheme`→`theme`, `useRouter`→`router`,
|
|
54
|
+
* `useStore`→`state`, `useHttp`→`http`, `useStorage`→`storage`, `useLogger`→`logger`,
|
|
55
|
+
* `useChat`→`chat`, `useWorkspace`→`workspace`, `useEditor`→`editor`, `usePreview`→`preview`.
|
|
56
|
+
* "useXProvider must be used within an XProvider" means the matching prop (or individual
|
|
57
|
+
* provider component) is missing ABOVE the component that calls the hook — fix the wiring,
|
|
58
|
+
* never wrap the hook in try/catch.
|
|
59
|
+
* - **Locale-reactive text requires the hook.** Inside components always read `t` from
|
|
60
|
+
* `useTranslation()` (or `useT()`); it re-renders on `onLocaleChange` — even when
|
|
61
|
+
* `addTranslations()` only adds keys for the current locale. Calling the raw `t()` import from
|
|
62
|
+
* `@molecule/app-i18n` in render works once but leaves stale text after a locale switch.
|
|
63
|
+
* - **Exactly one React copy.** In workspace/symlinked dev setups a second React instance makes
|
|
64
|
+
* every hook fail ("Invalid hook call", or the provider errors above with the provider
|
|
65
|
+
* mounted). Scaffolded Vite configs ship
|
|
66
|
+
* `resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` — keep it, and
|
|
67
|
+
* add any new hook-bearing peer library there too.
|
|
68
|
+
* - `RouterProvider` carries a molecule `Router` (e.g. `createReactRouter()` from
|
|
69
|
+
* `@molecule/app-routing-react-router`). react-router's own `<BrowserRouter>` context is
|
|
70
|
+
* separate — components that render react-router `<Link>` (several in
|
|
71
|
+
* `@molecule/app-ui-react`) need it in addition to the molecule providers.
|
|
72
|
+
*
|
|
73
|
+
* @module
|
|
74
|
+
*/
|
|
75
|
+
export * from './agent-identity.js';
|
|
76
|
+
export * from './contexts.js';
|
|
77
|
+
export * from './hooks/index.js';
|
|
78
|
+
export * from './providers.js';
|
|
79
|
+
export * from './types.js';
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AAEH,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA"}
|