@multiplatform.one/core 6.1.0 → 6.3.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/README.md +57 -0
- package/package.json +28 -32
- package/src/app/CreateApp.tsx +41 -10
- package/src/app/CreateRootLayout.web.tsx +36 -0
- package/src/app/TanstackDevtools.tsx +8 -1
- package/src/app/rootLayoutShared.ts +11 -0
- package/types/app/CreateApp.d.ts +132 -0
- package/types/app/CreateApp.d.ts.map +1 -0
- package/types/app/CreateRootLayout.d.ts +13 -0
- package/types/app/CreateRootLayout.d.ts.map +1 -0
- package/types/app/CreateRootLayout.native.d.ts +14 -0
- package/types/app/CreateRootLayout.native.d.ts.map +1 -0
- package/types/app/CreateRootLayout.web.d.ts +21 -0
- package/types/app/CreateRootLayout.web.d.ts.map +1 -0
- package/types/app/TanstackDevtools.d.ts +7 -0
- package/types/app/TanstackDevtools.d.ts.map +1 -0
- package/types/app/TanstackProvider.d.ts +3 -0
- package/types/app/TanstackProvider.d.ts.map +1 -0
- package/types/app/index.d.ts +28 -0
- package/types/app/index.d.ts.map +1 -0
- package/types/app/loadWalletProvider.native.d.ts +3 -0
- package/types/app/loadWalletProvider.native.d.ts.map +1 -0
- package/types/app/loadWalletProvider.web.d.ts +4 -0
- package/types/app/loadWalletProvider.web.d.ts.map +1 -0
- package/types/app/rootLayoutShared.d.ts +67 -0
- package/types/app/rootLayoutShared.d.ts.map +1 -0
- package/types/app/tanstackProvider.native.d.ts +3 -0
- package/types/app/tanstackProvider.native.d.ts.map +1 -0
- package/types/healthz.d.ts +3 -0
- package/types/healthz.d.ts.map +1 -0
- package/types/index.d.ts +3 -0
- package/types/index.d.ts.map +1 -0
- package/types/layouts/CreateDefaultLayout.d.ts +57 -0
- package/types/layouts/CreateDefaultLayout.d.ts.map +1 -0
- package/types/layouts/index.d.ts +3 -0
- package/types/layouts/index.d.ts.map +1 -0
- package/CHANGELOG.md +0 -125
- package/tsconfig.json +0 -11
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @multiplatform.one/core
|
|
2
|
+
|
|
3
|
+
App shell for multiplatform.one: provider composition (`createApp`), root
|
|
4
|
+
layout factories, and default screen layouts — so an app wires TanStack Query,
|
|
5
|
+
Keycloak, Frappe, Web3, and theming in one declaration.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @multiplatform.one/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Heavy integrations (`@multiplatform.one/keycloak`, `frappe`, `frappe-ui`,
|
|
14
|
+
`web3`, `@tanstack/react-query`, `one`, `tamagui`, …) are **peer dependencies**
|
|
15
|
+
and lazy-loaded — install only the ones your app enables.
|
|
16
|
+
|
|
17
|
+
## What it owns
|
|
18
|
+
|
|
19
|
+
- **`createApp(config)`** — returns `{ AppProvider, withApp, useAppConfig }`;
|
|
20
|
+
composes providers outermost → innermost:
|
|
21
|
+
config → TanStack → Web3 → Keycloak → Frappe → custom providers → Theme
|
|
22
|
+
- **`createRootLayout(config)`** — platform-split root layout (web/native) with
|
|
23
|
+
head, Sentry, and loader-data handling
|
|
24
|
+
- **`createDefaultLayout(options)`** / `createTanstackProvider` — screen layout
|
|
25
|
+
and query-client factories
|
|
26
|
+
|
|
27
|
+
## What it must not do
|
|
28
|
+
|
|
29
|
+
- No screens and no UI catalog — this package is wiring, not widgets
|
|
30
|
+
- No direct Frappe/Keycloak/Web3 implementations — it composes the dedicated
|
|
31
|
+
packages behind lazy provider boundaries
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { createApp } from "@multiplatform.one/core";
|
|
37
|
+
import { themeConfig } from "@package/config";
|
|
38
|
+
|
|
39
|
+
const { AppProvider } = createApp({
|
|
40
|
+
theme: themeConfig,
|
|
41
|
+
tanstack: true, // TanStack Query with defaults (devtools in dev)
|
|
42
|
+
keycloak: true, // read settings from env config
|
|
43
|
+
frappe: true,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export function App({ children }) {
|
|
47
|
+
return <AppProvider>{children}</AppProvider>;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Pass `true` to a provider slot to read all settings from env config, or an
|
|
52
|
+
object (`TanstackConfig`, `KeycloakConfig`, `FrappeConfig`, `Web3AppConfig`)
|
|
53
|
+
to configure explicitly. Disabled slots add zero bundle weight.
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
Apache-2.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/core",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Core framework shell, provider composition, and layout factories for multiplatform.one",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app",
|
|
@@ -9,21 +9,31 @@
|
|
|
9
9
|
],
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"author": "BitSpur",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://gitlab.com/bitspur/frappe/multiplatform.one.git",
|
|
15
|
+
"directory": "public/core"
|
|
16
|
+
},
|
|
12
17
|
"source": "src/index.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"src",
|
|
20
|
+
"types",
|
|
21
|
+
"!types/.tsbuildinfo"
|
|
22
|
+
],
|
|
13
23
|
"sideEffects": true,
|
|
14
24
|
"main": "src/index.ts",
|
|
15
25
|
"module": "src/index.ts",
|
|
16
|
-
"types": "
|
|
26
|
+
"types": "types/index.d.ts",
|
|
17
27
|
"exports": {
|
|
18
28
|
"./package.json": "./package.json",
|
|
19
29
|
"./healthz": {
|
|
20
|
-
"types": "./
|
|
30
|
+
"types": "./types/healthz.d.ts",
|
|
21
31
|
"source": "./src/healthz.ts",
|
|
22
32
|
"default": "./src/healthz.ts"
|
|
23
33
|
},
|
|
24
34
|
".": {
|
|
25
35
|
"source": "./src/index.ts",
|
|
26
|
-
"types": "./
|
|
36
|
+
"types": "./types/index.d.ts",
|
|
27
37
|
"default": "./src/index.ts"
|
|
28
38
|
}
|
|
29
39
|
},
|
|
@@ -36,12 +46,12 @@
|
|
|
36
46
|
"@tanstack/react-form-devtools": "0.2.22",
|
|
37
47
|
"@tanstack/react-pacer-devtools": "^0.7.0",
|
|
38
48
|
"react-cookie": "^8.1.2",
|
|
39
|
-
"@multiplatform.one/i18n": "6.
|
|
40
|
-
"@multiplatform.one/
|
|
41
|
-
"@multiplatform.one/platform": "6.
|
|
42
|
-
"@multiplatform.one/
|
|
43
|
-
"@multiplatform.one/
|
|
44
|
-
"@multiplatform.one/web3": "6.
|
|
49
|
+
"@multiplatform.one/i18n": "6.3.0",
|
|
50
|
+
"@multiplatform.one/logger": "6.3.0",
|
|
51
|
+
"@multiplatform.one/platform": "6.3.0",
|
|
52
|
+
"@multiplatform.one/theme": "6.3.0",
|
|
53
|
+
"@multiplatform.one/store": "6.3.0",
|
|
54
|
+
"@multiplatform.one/web3": "6.3.0"
|
|
45
55
|
},
|
|
46
56
|
"devDependencies": {
|
|
47
57
|
"@sentry/react": "^10.51.0",
|
|
@@ -57,8 +67,8 @@
|
|
|
57
67
|
"react-native-safe-area-context": "~5.7.0",
|
|
58
68
|
"tamagui": "2.0.0-rc.41",
|
|
59
69
|
"typescript": "~5.9.3",
|
|
60
|
-
"@multiplatform.one/web3": "6.
|
|
61
|
-
"@multiplatform.one/frappe": "6.
|
|
70
|
+
"@multiplatform.one/web3": "6.3.0",
|
|
71
|
+
"@multiplatform.one/frappe": "6.3.0"
|
|
62
72
|
},
|
|
63
73
|
"peerDependencies": {
|
|
64
74
|
"@sentry/react": "^9.0.0",
|
|
@@ -74,33 +84,18 @@
|
|
|
74
84
|
"react-native-gesture-handler": ">=2.0.0",
|
|
75
85
|
"react-native-safe-area-context": ">=4.0.0",
|
|
76
86
|
"tamagui": "^2.0.0-rc",
|
|
77
|
-
"@multiplatform.one/
|
|
78
|
-
"@multiplatform.one/
|
|
79
|
-
"@multiplatform.one/
|
|
80
|
-
"@multiplatform.one/
|
|
87
|
+
"@multiplatform.one/web3": "^6.3.0",
|
|
88
|
+
"@multiplatform.one/frappe-ui": "^6.3.0",
|
|
89
|
+
"@multiplatform.one/frappe": "^6.3.0",
|
|
90
|
+
"@multiplatform.one/keycloak": "^6.3.0"
|
|
81
91
|
},
|
|
82
92
|
"peerDependenciesMeta": {
|
|
83
|
-
"@multiplatform.one/frappe": {
|
|
84
|
-
"optional": true
|
|
85
|
-
},
|
|
86
|
-
"@multiplatform.one/frappe-ui": {
|
|
87
|
-
"optional": true
|
|
88
|
-
},
|
|
89
|
-
"@multiplatform.one/keycloak": {
|
|
90
|
-
"optional": true
|
|
91
|
-
},
|
|
92
93
|
"@multiplatform.one/web3": {
|
|
93
94
|
"optional": true
|
|
94
95
|
},
|
|
95
96
|
"@sentry/react": {
|
|
96
97
|
"optional": true
|
|
97
98
|
},
|
|
98
|
-
"@tanstack/react-query": {
|
|
99
|
-
"optional": true
|
|
100
|
-
},
|
|
101
|
-
"@tanstack/react-query-devtools": {
|
|
102
|
-
"optional": true
|
|
103
|
-
},
|
|
104
99
|
"@vxrn/color-scheme": {
|
|
105
100
|
"optional": true
|
|
106
101
|
},
|
|
@@ -121,6 +116,7 @@
|
|
|
121
116
|
}
|
|
122
117
|
},
|
|
123
118
|
"scripts": {
|
|
124
|
-
"typecheck": "tsc --noEmit"
|
|
119
|
+
"typecheck": "tsc --noEmit",
|
|
120
|
+
"build": "rm -rf types 2>/dev/null && tsc -p tsconfig.build.json"
|
|
125
121
|
}
|
|
126
122
|
}
|
package/src/app/CreateApp.tsx
CHANGED
|
@@ -20,6 +20,31 @@ import LazyWalletProvider from "./loadWalletProvider";
|
|
|
20
20
|
|
|
21
21
|
export type ProviderComponent = ComponentType<PropsWithChildren>;
|
|
22
22
|
|
|
23
|
+
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Follow the page origin when a loopback-configured backend is opened from a
|
|
27
|
+
* non-loopback host. Dev configs point at `http://localhost:8000`, which is
|
|
28
|
+
* correct on the dev machine but breaks the moment the app is opened via a
|
|
29
|
+
* LAN IP (`http://10.x.x.x:3456` → the API and the Socket.IO handshake would
|
|
30
|
+
* target the *visitor's* machine, and Chromium's Local Network Access policy
|
|
31
|
+
* flags the cross-origin loopback fetch). Rewriting only the hostname keeps
|
|
32
|
+
* the configured scheme and port, and only ever triggers in a browser whose
|
|
33
|
+
* page host is itself not loopback — SSR and same-machine dev are untouched.
|
|
34
|
+
*/
|
|
35
|
+
export function followPageOriginForLoopback(configured: string): string {
|
|
36
|
+
if (typeof window === "undefined" || !window.location?.hostname) return configured;
|
|
37
|
+
try {
|
|
38
|
+
const url = new URL(configured);
|
|
39
|
+
const pageHost = window.location.hostname;
|
|
40
|
+
if (!LOOPBACK_HOSTS.has(url.hostname) || LOOPBACK_HOSTS.has(pageHost)) return configured;
|
|
41
|
+
url.hostname = pageHost;
|
|
42
|
+
return url.toString().replace(/\/$/, "");
|
|
43
|
+
} catch {
|
|
44
|
+
return configured;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
// ---------------------------------------------------------------------------
|
|
24
49
|
// Provider config types
|
|
25
50
|
// ---------------------------------------------------------------------------
|
|
@@ -287,21 +312,27 @@ export function createApp(appConfig: CreateAppConfig) {
|
|
|
287
312
|
const enabled = cfg.enabled ?? config.get("FRAPPE_ENABLED") === "1";
|
|
288
313
|
if (!enabled) return children;
|
|
289
314
|
|
|
290
|
-
|
|
315
|
+
// LAN dev: a loopback-configured bench follows the page origin's host
|
|
316
|
+
// (the Socket.IO URL derives from baseURL too, so realtime follows).
|
|
317
|
+
const baseURL = followPageOriginForLoopback(
|
|
318
|
+
cfg.baseURL || config.get("BASE_URL") || "http://localhost:8000",
|
|
319
|
+
);
|
|
291
320
|
const socketPort =
|
|
292
321
|
cfg.socketPort ?? (Number(config.get("FRAPPE_SOCKETIO_PORT")) || undefined);
|
|
293
322
|
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
//
|
|
323
|
+
// Keycloak auth uses ONE transport on every platform: the HttpClient
|
|
324
|
+
// and the Socket.IO handshake send `Authorization: Bearer <keycloak
|
|
325
|
+
// access token>`, fetched lazily from better-auth's /get-access-token
|
|
326
|
+
// (which refreshes server-side; SecureStore jar on native, session
|
|
327
|
+
// cookie on web). The bench's frappe_keycloak auth hook validates the
|
|
328
|
+
// JWT. Cookies alone can't cover realtime: frappe's socketio middleware
|
|
329
|
+
// only accepts a frappe `sid` cookie or an Authorization header, so the
|
|
330
|
+
// better-auth account cookie never authenticated the socket on web.
|
|
331
|
+
// When signed out the getter resolves undefined and requests fall back
|
|
332
|
+
// to guest.
|
|
302
333
|
const auth =
|
|
303
334
|
cfg.auth ??
|
|
304
|
-
(
|
|
335
|
+
(appConfig.keycloak
|
|
305
336
|
? {
|
|
306
337
|
useToken: true,
|
|
307
338
|
type: "Bearer",
|
|
@@ -123,10 +123,46 @@ export function createRootLayout(cfg: CreateRootLayoutConfig): ComponentType {
|
|
|
123
123
|
i18n.changeLanguage(rootLoaderData.detectedLanguage);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
// LC-33 FONT-STABLE-MOUNT (DF-17 / Axiom 8 STABLE GROUND): Inter must be
|
|
127
|
+
// usable at first paint. The Tamagui font CSS is injected as a JS side
|
|
128
|
+
// effect (theme's createFontLoader.web), so without a head declaration
|
|
129
|
+
// the fallback→Inter swap reflows settled text (H1 width jumped 74px in
|
|
130
|
+
// the dogfood axiom review). Preloading the same Inter binaries the app
|
|
131
|
+
// serves from /fonts (extracted from @tamagui/font-inter — identical
|
|
132
|
+
// metrics to the late-injected face) and declaring the face in the head
|
|
133
|
+
// means first paint already renders Inter; `font-display: optional`
|
|
134
|
+
// guarantees the head face itself never swaps after first paint.
|
|
135
|
+
const interFonts = cfg.head?.interFonts !== false;
|
|
136
|
+
const interFontCss = [
|
|
137
|
+
'@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:optional;src:url("/fonts/inter-400.woff2") format("woff2")}',
|
|
138
|
+
'@font-face{font-family:"Inter";font-style:normal;font-weight:700;font-display:optional;src:url("/fonts/inter-700.woff2") format("woff2")}',
|
|
139
|
+
].join("");
|
|
140
|
+
|
|
126
141
|
return (
|
|
127
142
|
<html lang={htmlLang}>
|
|
128
143
|
<head>
|
|
129
144
|
<meta charSet="utf-8" />
|
|
145
|
+
{interFonts && (
|
|
146
|
+
<>
|
|
147
|
+
<link
|
|
148
|
+
rel="preload"
|
|
149
|
+
href="/fonts/inter-400.woff2"
|
|
150
|
+
as="font"
|
|
151
|
+
type="font/woff2"
|
|
152
|
+
crossOrigin=""
|
|
153
|
+
/>
|
|
154
|
+
<link
|
|
155
|
+
rel="preload"
|
|
156
|
+
href="/fonts/inter-700.woff2"
|
|
157
|
+
as="font"
|
|
158
|
+
type="font/woff2"
|
|
159
|
+
crossOrigin=""
|
|
160
|
+
/>
|
|
161
|
+
<style precedence="reset" href="__font_inter">
|
|
162
|
+
{interFontCss}
|
|
163
|
+
</style>
|
|
164
|
+
</>
|
|
165
|
+
)}
|
|
130
166
|
{/* Critical reset CSS with data-precedence so React 19 hoists it
|
|
131
167
|
to the very top of <head> – BEFORE the Tamagui atomic CSS.
|
|
132
168
|
This eliminates FOUC during streaming SSR. */}
|
|
@@ -61,7 +61,14 @@ function useFrappePlugin() {
|
|
|
61
61
|
]);
|
|
62
62
|
const sync = __getActiveSyncModule();
|
|
63
63
|
if (sync && !cancelled) {
|
|
64
|
-
|
|
64
|
+
// SyncModule is a class (nominal typing); when this file is
|
|
65
|
+
// typechecked through nested node_modules symlinks with
|
|
66
|
+
// preserveSymlinks, the two dynamic imports above can resolve to
|
|
67
|
+
// distinct copies of the same source file, making the identical
|
|
68
|
+
// class types mutually unassignable. Same runtime object either way.
|
|
69
|
+
setPlugin(
|
|
70
|
+
frappeDevtoolsPlugin(sync as unknown as Parameters<typeof frappeDevtoolsPlugin>[0]),
|
|
71
|
+
);
|
|
65
72
|
return true;
|
|
66
73
|
}
|
|
67
74
|
} catch {
|
|
@@ -5,6 +5,17 @@ import type { AppProviderProps } from "./CreateApp";
|
|
|
5
5
|
export interface HeadConfig {
|
|
6
6
|
/** Path to favicon (e.g. "/favicon.svg"). */
|
|
7
7
|
favicon?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Preload + declare the default Inter faces (400/700) in the document
|
|
10
|
+
* head with `font-display: optional` so first paint is font-stable
|
|
11
|
+
* (LC-33 FONT-STABLE-MOUNT / DF-17): without a head declaration the
|
|
12
|
+
* Tamagui font CSS arrives as a JS side effect and the fallback→Inter
|
|
13
|
+
* swap reflows settled text. Defaults to true; requires the app to
|
|
14
|
+
* serve `/fonts/inter-400.woff2` + `/fonts/inter-700.woff2` from its
|
|
15
|
+
* public directory. Set false for apps that don't use Inter or ship
|
|
16
|
+
* their own head declaration.
|
|
17
|
+
*/
|
|
18
|
+
interFonts?: boolean;
|
|
8
19
|
}
|
|
9
20
|
|
|
10
21
|
export interface SentryConfig {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { type ComponentType, type PropsWithChildren } from "react";
|
|
2
|
+
import type { ThemeConfig } from "@multiplatform.one/theme";
|
|
3
|
+
export type ProviderComponent = ComponentType<PropsWithChildren>;
|
|
4
|
+
/**
|
|
5
|
+
* Follow the page origin when a loopback-configured backend is opened from a
|
|
6
|
+
* non-loopback host. Dev configs point at `http://localhost:8000`, which is
|
|
7
|
+
* correct on the dev machine but breaks the moment the app is opened via a
|
|
8
|
+
* LAN IP (`http://10.x.x.x:3456` → the API and the Socket.IO handshake would
|
|
9
|
+
* target the *visitor's* machine, and Chromium's Local Network Access policy
|
|
10
|
+
* flags the cross-origin loopback fetch). Rewriting only the hostname keeps
|
|
11
|
+
* the configured scheme and port, and only ever triggers in a browser whose
|
|
12
|
+
* page host is itself not loopback — SSR and same-machine dev are untouched.
|
|
13
|
+
*/
|
|
14
|
+
export declare function followPageOriginForLoopback(configured: string): string;
|
|
15
|
+
export interface TanstackConfig {
|
|
16
|
+
/** Show React Query devtools (web only, ignored on native and in Storybook). */
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
/** Options forwarded to the QueryClient constructor. */
|
|
19
|
+
queryClientOptions?: Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Pass `useUserScheme` from `one` / `@vxrn/color-scheme` so the theme
|
|
22
|
+
* devtools panel can control the color scheme (light / dark / system).
|
|
23
|
+
*/
|
|
24
|
+
useUserScheme?: () => {
|
|
25
|
+
setting: "system" | "light" | "dark";
|
|
26
|
+
value: "light" | "dark";
|
|
27
|
+
set: (s: "system" | "light" | "dark") => void;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Tamagui config object (from `createTamagui()`). When provided, the
|
|
31
|
+
* TanStack Devtools theme panel extracts `$color1`–`$color12` directly
|
|
32
|
+
* from the config's themes for the color line visualizer.
|
|
33
|
+
* Passed automatically by `createApp()` from the theme config.
|
|
34
|
+
*/
|
|
35
|
+
tamaguiConfig?: unknown;
|
|
36
|
+
}
|
|
37
|
+
export interface KeycloakConfig {
|
|
38
|
+
/** Force-enable or disable. When omitted, reads KEYCLOAK_ENABLED from env config. */
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
baseUrl?: string;
|
|
41
|
+
clientId?: string;
|
|
42
|
+
publicClientId?: string;
|
|
43
|
+
realm?: string;
|
|
44
|
+
debug?: boolean;
|
|
45
|
+
iframeSso?: boolean;
|
|
46
|
+
loginRedirectUri?: string;
|
|
47
|
+
messageHandlerKeys?: string[];
|
|
48
|
+
/** Better Auth server base URL (native sign-in). When omitted, reads
|
|
49
|
+
* BETTER_AUTH_BASE_URL, then falls back to BASE_URL (the app server proxies
|
|
50
|
+
* /api/auth). */
|
|
51
|
+
betterAuthBaseUrl?: string;
|
|
52
|
+
/** App scheme for the Expo auth-session redirect (native). */
|
|
53
|
+
expoScheme?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface FrappeConfig {
|
|
56
|
+
/** Force-enable or disable. When omitted, reads FRAPPE_ENABLED from env config. */
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
baseURL?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Override port for Socket.IO realtime connection (e.g. 9000 in dev).
|
|
61
|
+
* Omit in production behind a reverse proxy.
|
|
62
|
+
*/
|
|
63
|
+
socketPort?: number;
|
|
64
|
+
auth?: {
|
|
65
|
+
useToken?: boolean;
|
|
66
|
+
token?: string | (() => string | Promise<string>);
|
|
67
|
+
type?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface Web3AppConfig {
|
|
71
|
+
/** Force-enable or disable. When omitted, reads WEB3_ENABLED from env config. */
|
|
72
|
+
enabled?: boolean;
|
|
73
|
+
walletConnectProjectId?: string;
|
|
74
|
+
appName?: string;
|
|
75
|
+
appDescription?: string;
|
|
76
|
+
appUrl?: string;
|
|
77
|
+
appIcon?: string;
|
|
78
|
+
enableTestnets?: boolean;
|
|
79
|
+
/** Add the local dev chain (`make localnet`). When omitted, reads WEB3_LOCALNET_ENABLED. */
|
|
80
|
+
localnet?: boolean;
|
|
81
|
+
/** Local EVM JSON-RPC endpoint for localnet. When omitted, reads WEB3_EVM_RPC. */
|
|
82
|
+
localnetRpcUrl?: string;
|
|
83
|
+
/** Solana JSON-RPC endpoint. When omitted, reads WEB3_SOLANA_RPC. */
|
|
84
|
+
solanaRpcUrl?: string;
|
|
85
|
+
/** Sui JSON-RPC endpoint. When omitted, reads WEB3_SUI_RPC. */
|
|
86
|
+
suiRpcUrl?: string;
|
|
87
|
+
/** Native: URL serving the wallet WebView HTML. When omitted, reads WEB3_WEBVIEW_URL. */
|
|
88
|
+
webViewUrl?: string;
|
|
89
|
+
/** E2E only (native): route connect through the in-WebView mock wallet. When omitted, reads WEB3_MOCK_WALLET. */
|
|
90
|
+
mockWallet?: boolean;
|
|
91
|
+
}
|
|
92
|
+
export interface CreateAppConfig {
|
|
93
|
+
/** ThemeConfig to pass to the built-in ThemeProvider. */
|
|
94
|
+
theme?: ThemeConfig;
|
|
95
|
+
/**
|
|
96
|
+
* Additional providers composed outermost-to-innermost order.
|
|
97
|
+
* Each component receives `{ children }` and must render them.
|
|
98
|
+
* The first provider in the array becomes the outermost wrapper.
|
|
99
|
+
*/
|
|
100
|
+
providers?: ProviderComponent[];
|
|
101
|
+
/** TanStack Query provider with optional devtools. Pass `true` for defaults. */
|
|
102
|
+
tanstack?: TanstackConfig | boolean;
|
|
103
|
+
/** Keycloak auth provider (lazy-loaded). Pass `true` to read all settings from env config. */
|
|
104
|
+
keycloak?: KeycloakConfig | boolean;
|
|
105
|
+
/** Frappe provider (lazy-loaded). Pass `true` to read all settings from env config. */
|
|
106
|
+
frappe?: FrappeConfig | boolean;
|
|
107
|
+
/** Web3 wallet provider (lazy-loaded). Pass `true` to read all settings from env config. */
|
|
108
|
+
web3?: Web3AppConfig | boolean;
|
|
109
|
+
}
|
|
110
|
+
export interface AppProviderProps extends PropsWithChildren {
|
|
111
|
+
/** System color scheme for theme resolution. */
|
|
112
|
+
systemTheme?: "light" | "dark";
|
|
113
|
+
/** Override the theme config set at createApp() time (useful for Storybook). */
|
|
114
|
+
themeConfig?: ThemeConfig;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Creates a pre-configured app shell with composable providers.
|
|
118
|
+
*
|
|
119
|
+
* Returns `{ AppProvider, withApp, useAppConfig }`.
|
|
120
|
+
*
|
|
121
|
+
* Provider composition order (outermost → innermost):
|
|
122
|
+
* config context → TanStack → Web3 → Keycloak → Frappe → custom providers → ThemeProvider → children
|
|
123
|
+
*/
|
|
124
|
+
export declare function createApp(appConfig: CreateAppConfig): {
|
|
125
|
+
AppProvider: {
|
|
126
|
+
({ children, systemTheme, themeConfig }: AppProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
127
|
+
displayName: string;
|
|
128
|
+
};
|
|
129
|
+
withApp: <P extends Record<string, unknown>>(Screen: ComponentType<P>) => ComponentType<P>;
|
|
130
|
+
useAppConfig: () => CreateAppConfig;
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=CreateApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateApp.d.ts","sourceRoot":"","sources":["../../src/app/CreateApp.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ComponentType } from "react";
|
|
2
|
+
import type { CreateRootLayoutConfig } from "./rootLayoutShared";
|
|
3
|
+
export type { CreateRootLayoutConfig, HeadConfig, RootLayoutProps, RootLoaderData, SentryConfig, } from "./rootLayoutShared";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a root layout component (universal fallback for Tauri / desktop).
|
|
6
|
+
*
|
|
7
|
+
* Handles i18n initialization, color-scheme detection via `matchMedia`,
|
|
8
|
+
* and wraps content in `LoadProgressBar` → `AppProvider` → `RootLayout` → `<Slot />`.
|
|
9
|
+
*
|
|
10
|
+
* `head` and `sentry` config options are ignored in the universal fallback.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createRootLayout(cfg: CreateRootLayoutConfig): ComponentType;
|
|
13
|
+
//# sourceMappingURL=CreateRootLayout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateRootLayout.d.ts","sourceRoot":"","sources":["../../src/app/CreateRootLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKhF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,YAAY,EACV,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,sBAAsB,GAAG,aAAa,CAwC3E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
import type { CreateRootLayoutConfig } from "./rootLayoutShared";
|
|
3
|
+
export type { CreateRootLayoutConfig, HeadConfig, RootLayoutProps, RootLoaderData, SentryConfig, } from "./rootLayoutShared";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a root layout component for **React Native** (iOS + Android).
|
|
6
|
+
*
|
|
7
|
+
* Handles i18n initialization, color-scheme detection via `@vxrn/color-scheme`,
|
|
8
|
+
* and wraps content in `GestureHandlerRootView` → `SafeAreaProvider` →
|
|
9
|
+
* `SchemeProvider` → `AppProvider` → `RootLayout` → `<Slot />`.
|
|
10
|
+
*
|
|
11
|
+
* `head` and `sentry` config options are ignored on native.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createRootLayout(cfg: CreateRootLayoutConfig): ComponentType;
|
|
14
|
+
//# sourceMappingURL=CreateRootLayout.native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateRootLayout.native.d.ts","sourceRoot":"","sources":["../../src/app/CreateRootLayout.native.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,OAAO,CAAC;AAQtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,YAAY,EACV,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,sBAAsB,GAAG,aAAa,CAsC3E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
import type { CreateRootLayoutConfig } from "./rootLayoutShared";
|
|
3
|
+
export type { CreateRootLayoutConfig, HeadConfig, RootLayoutProps, RootLoaderData, SentryConfig, } from "./rootLayoutShared";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a root layout component for **web** (browser + SSR).
|
|
6
|
+
*
|
|
7
|
+
* Handles i18n initialization, Sentry setup, color-scheme detection via
|
|
8
|
+
* `SchemeProvider` (blocking script + localStorage – no cookie needed),
|
|
9
|
+
* `<Head>` meta tags, `<LoadProgressBar>`, and wraps content in
|
|
10
|
+
* `SchemeProvider` → `CookiesProvider` → `AppProvider` → `RootLayout` → `<Slot />`.
|
|
11
|
+
*
|
|
12
|
+
* Light/dark scheme: handled by `@vxrn/color-scheme` `SchemeProvider` which
|
|
13
|
+
* injects a blocking `<script>` that reads `localStorage` / `matchMedia`
|
|
14
|
+
* before the first paint. Works even when cookies are disabled.
|
|
15
|
+
*
|
|
16
|
+
* Theme properties (color theme, padding, borderRadius, …): synced via
|
|
17
|
+
* `mp.preset` + `mp.overrides` cookies so SSR can render with the user's full
|
|
18
|
+
* theme. The cookies are populated by `useTheme` in `@multiplatform.one/theme`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createRootLayout(cfg: CreateRootLayoutConfig): ComponentType;
|
|
21
|
+
//# sourceMappingURL=CreateRootLayout.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateRootLayout.web.d.ts","sourceRoot":"","sources":["../../src/app/CreateRootLayout.web.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,OAAO,CAAC;AAOtD,OAAO,KAAK,EAAE,sBAAsB,EAAkB,MAAM,oBAAoB,CAAC;AAEjF,YAAY,EACV,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,sBAAsB,GAAG,aAAa,CAoL3E"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TanstackConfig } from "./CreateApp";
|
|
2
|
+
export interface TanstackDevtoolsProps {
|
|
3
|
+
resolvedScheme: "light" | "dark";
|
|
4
|
+
tanstackConfig: TanstackConfig;
|
|
5
|
+
}
|
|
6
|
+
export default function TanstackDevtoolsWrapper({ resolvedScheme, tanstackConfig, }: TanstackDevtoolsProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=TanstackDevtools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TanstackDevtools.d.ts","sourceRoot":"","sources":["../../src/app/TanstackDevtools.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsBlD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;CAChC;AAkED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC9C,cAAc,EACd,cAAc,GACf,EAAE,qBAAqB,2CA0CvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TanstackProvider.d.ts","sourceRoot":"","sources":["../../src/app/TanstackProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIrE,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,cAAc,GAAG,iBAAiB,CAiCxF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## Platform File Extension Conventions
|
|
3
|
+
*
|
|
4
|
+
* The framework uses platform-specific file extensions for automatic
|
|
5
|
+
* bundler resolution. When multiple variants exist for a module, the
|
|
6
|
+
* bundler picks the most specific match for the current target:
|
|
7
|
+
*
|
|
8
|
+
* | Extension | Target |
|
|
9
|
+
* | ---------------- | --------------------------------------- |
|
|
10
|
+
* | `.web.tsx` | Web (browser + SSR) |
|
|
11
|
+
* | `.native.tsx` | React Native (iOS + Android) |
|
|
12
|
+
* | `.ios.tsx` | iOS only |
|
|
13
|
+
* | `.android.tsx` | Android only |
|
|
14
|
+
* | `.tauri.tsx` | Tauri desktop (macOS, Windows, Linux) |
|
|
15
|
+
* | `.storybook-expo.ts` | Storybook running in Expo |
|
|
16
|
+
* | (no suffix) | Universal fallback / shared code |
|
|
17
|
+
*
|
|
18
|
+
* Resolution priority (most → least specific):
|
|
19
|
+
* `.ios.tsx` > `.native.tsx` > `.tsx` (on iOS)
|
|
20
|
+
* `.web.tsx` > `.tsx` (on web)
|
|
21
|
+
* `.tauri.tsx` > `.tsx` (on Tauri)
|
|
22
|
+
*
|
|
23
|
+
* When creating platform-specific variants, always keep a universal
|
|
24
|
+
* fallback file (e.g. `index.ts`) that exports the default API.
|
|
25
|
+
*/
|
|
26
|
+
export * from "./CreateApp";
|
|
27
|
+
export * from "./CreateRootLayout";
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadWalletProvider.native.d.ts","sourceRoot":"","sources":["../../src/app/loadWalletProvider.native.ts"],"names":[],"mappings":";AAWA,wBAEE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadWalletProvider.web.d.ts","sourceRoot":"","sources":["../../src/app/loadWalletProvider.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAO5F,QAAA,MAAM,cAAc,EAAE,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CACrC,CAAC;AAC1C,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ComponentType, PropsWithChildren } from "react";
|
|
2
|
+
import type { I18nConfigOptions } from "@multiplatform.one/i18n";
|
|
3
|
+
import type { AppProviderProps } from "./CreateApp";
|
|
4
|
+
export interface HeadConfig {
|
|
5
|
+
/** Path to favicon (e.g. "/favicon.svg"). */
|
|
6
|
+
favicon?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Preload + declare the default Inter faces (400/700) in the document
|
|
9
|
+
* head with `font-display: optional` so first paint is font-stable
|
|
10
|
+
* (LC-33 FONT-STABLE-MOUNT / DF-17): without a head declaration the
|
|
11
|
+
* Tamagui font CSS arrives as a JS side effect and the fallback→Inter
|
|
12
|
+
* swap reflows settled text. Defaults to true; requires the app to
|
|
13
|
+
* serve `/fonts/inter-400.woff2` + `/fonts/inter-700.woff2` from its
|
|
14
|
+
* public directory. Set false for apps that don't use Inter or ship
|
|
15
|
+
* their own head declaration.
|
|
16
|
+
*/
|
|
17
|
+
interFonts?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface SentryConfig {
|
|
20
|
+
/** Sentry DSN. When provided, Sentry is initialized on the web client. */
|
|
21
|
+
dsn?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Shape of the root layout loader data used by createRootLayout. */
|
|
24
|
+
export interface RootLoaderData {
|
|
25
|
+
cookieHeader?: string;
|
|
26
|
+
/** Language detected from request (cookie or Accept-Language header). */
|
|
27
|
+
detectedLanguage?: string;
|
|
28
|
+
/** Server-side session from the auth loader (used for SSR hydration). */
|
|
29
|
+
session?: unknown;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Props accepted by the `RootLayout` component.
|
|
34
|
+
*
|
|
35
|
+
* `ssrSession` is provided only on web during SSR so auth-related UI
|
|
36
|
+
* (e.g. user name, logout button) can render on the first paint without
|
|
37
|
+
* waiting for a client-side session fetch.
|
|
38
|
+
*/
|
|
39
|
+
export interface RootLayoutProps extends PropsWithChildren {
|
|
40
|
+
/** Server-side session data for SSR hydration (web only). */
|
|
41
|
+
ssrSession?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Configuration for `createRootLayout()`.
|
|
45
|
+
*
|
|
46
|
+
* The factory initializes i18n, detects color scheme, wraps with the
|
|
47
|
+
* appropriate platform providers, and renders the RootLayout + Slot.
|
|
48
|
+
*/
|
|
49
|
+
export interface CreateRootLayoutConfig {
|
|
50
|
+
/** The AppProvider component returned from `createApp()`. */
|
|
51
|
+
AppProvider: ComponentType<AppProviderProps>;
|
|
52
|
+
/** Root layout shell that wraps route content (navigation chrome, header, etc.). */
|
|
53
|
+
RootLayout: ComponentType<RootLayoutProps>;
|
|
54
|
+
/** i18n configuration. i18next is initialized as a side-effect when the factory is called. */
|
|
55
|
+
i18n: I18nConfigOptions;
|
|
56
|
+
/** `<Head>` meta tags for web. Ignored on native. */
|
|
57
|
+
head?: HeadConfig;
|
|
58
|
+
/** Sentry error tracking. Initialized on the web client only. Ignored on native. */
|
|
59
|
+
sentry?: SentryConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Native font map returned by `importFonts()` from `@package/fonts`.
|
|
62
|
+
* Passed to `useFonts()` so custom fonts load before the first render.
|
|
63
|
+
* Ignored on web (fonts are loaded via CSS side-effect imports).
|
|
64
|
+
*/
|
|
65
|
+
fonts?: Record<string, number>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=rootLayoutShared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rootLayoutShared.d.ts","sourceRoot":"","sources":["../../src/app/rootLayoutShared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,oFAAoF;IACpF,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3C,8FAA8F;IAC9F,IAAI,EAAE,iBAAiB,CAAC;IACxB,qDAAqD;IACrD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,oFAAoF;IACpF,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstackProvider.native.d.ts","sourceRoot":"","sources":["../../src/app/tanstackProvider.native.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAErE,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,cAAc,GAAG,iBAAiB,CAQxF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"healthz.d.ts","sourceRoot":"","sources":["../src/healthz.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wBAAsB,GAAG,CAAC,QAAQ,EAAE,OAAO,qBAE1C"}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from "react";
|
|
2
|
+
import { type WithLayout } from "@multiplatform.one/platform";
|
|
3
|
+
export type SafeAreaEdge = "top" | "bottom" | "left" | "right";
|
|
4
|
+
export interface CreateDefaultLayoutOptions {
|
|
5
|
+
/**
|
|
6
|
+
* SafeArea wrapper component.
|
|
7
|
+
* Pass SafeAreaWrapper from @multiplatform.one/components.
|
|
8
|
+
*/
|
|
9
|
+
SafeAreaWrapper?: ComponentType<any>;
|
|
10
|
+
/**
|
|
11
|
+
* Edges to apply safe area insets to.
|
|
12
|
+
* @default ["top", "left", "right"]
|
|
13
|
+
*/
|
|
14
|
+
safeAreaEdges?: SafeAreaEdge[];
|
|
15
|
+
/**
|
|
16
|
+
* Background color token for the safe area wrapper.
|
|
17
|
+
* @default "$background"
|
|
18
|
+
*/
|
|
19
|
+
safeAreaBackground?: string;
|
|
20
|
+
/**
|
|
21
|
+
* KeyboardAvoiding wrapper component.
|
|
22
|
+
* Pass KeyboardAvoidingWrapper from @multiplatform.one/components.
|
|
23
|
+
*/
|
|
24
|
+
KeyboardAvoidingWrapper?: ComponentType<any>;
|
|
25
|
+
/**
|
|
26
|
+
* Background color token for the content area.
|
|
27
|
+
* @default "$background"
|
|
28
|
+
*/
|
|
29
|
+
background?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Toast component to render inside the layout.
|
|
32
|
+
*/
|
|
33
|
+
Toast?: ComponentType;
|
|
34
|
+
/**
|
|
35
|
+
* Debug overlay configuration.
|
|
36
|
+
* - `true`: enable a minimal debug overlay (visible when DEBUG=1)
|
|
37
|
+
* - `ComponentType`: render this component as the debug view when DEBUG=1
|
|
38
|
+
*/
|
|
39
|
+
debug?: boolean | ComponentType;
|
|
40
|
+
/**
|
|
41
|
+
* Additional layout HOCs to compose with the default layout.
|
|
42
|
+
*/
|
|
43
|
+
extraLayouts?: WithLayout[];
|
|
44
|
+
}
|
|
45
|
+
export interface DefaultLayoutProps {
|
|
46
|
+
children: ReactNode;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Factory that creates a DefaultLayout component and withDefaultLayout HOC
|
|
50
|
+
* from configuration. Handles SafeArea, KeyboardAvoiding, fullscreen YStack,
|
|
51
|
+
* Toast, and optional debug overlay composition.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createDefaultLayout(options?: CreateDefaultLayoutOptions): {
|
|
54
|
+
DefaultLayout: ({ children }: DefaultLayoutProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
withDefaultLayout: WithLayout;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=CreateDefaultLayout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateDefaultLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/CreateDefaultLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtD,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEhF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAErC;;;OAGG;IACH,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAE/B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAE7C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAEhC;;OAEG;IACH,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B;kCAYrC,kBAAkB;;EAiDxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,YAAY,GACb,MAAM,uBAAuB,CAAC"}
|
package/CHANGELOG.md
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# @multiplatform.one/core
|
|
2
|
-
|
|
3
|
-
## 6.1.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- Point apps at the `make localnet` dev chains by default: Web3Config gains
|
|
8
|
-
`localnet` (prepends the hardhat 31337 dev chain as wagmi's default chain on
|
|
9
|
-
web AND native via a shared `resolveChains`), `localnetRpcUrl` (emulator host
|
|
10
|
-
addresses), and `suiRpcUrl` alongside the existing `solanaRpcUrl`. createApp
|
|
11
|
-
reads WEB3_LOCALNET_ENABLED / WEB3_EVM_RPC / WEB3_SOLANA_RPC / WEB3_SUI_RPC
|
|
12
|
-
from env config.
|
|
13
|
-
- Native auth + authenticated Frappe data end-to-end:
|
|
14
|
-
- keycloak: native Keycloak login via a hand-rolled Better Auth expo flow
|
|
15
|
-
(fetch + expo-web-browser + SecureStore cookie jar — no @better-auth/expo
|
|
16
|
-
client, whose zod import graph dies on Hermes). Real native dist
|
|
17
|
-
(dist/esm/index.native.js) + react-native export condition; new
|
|
18
|
-
getKeycloakBearerToken() for Frappe Bearer auth; native useSession backed
|
|
19
|
-
by a real store; Loading/Authenticated use RN primitives (they mount above
|
|
20
|
-
TamaguiProvider); KeycloakProvider gains betterAuthBaseUrl/expoScheme.
|
|
21
|
-
- frappe: isBrowser() now means "client runtime" (isNative ||
|
|
22
|
-
isWindowDefined) — the tamagui native dist hardcodes isWindowDefined=false,
|
|
23
|
-
which silently disabled the entire sync pipeline (collections never
|
|
24
|
-
fetched) on iOS/Android. Token type widened to string | fn through the
|
|
25
|
-
React layer.
|
|
26
|
-
- core: createApp wires native Frappe requests with Authorization: Bearer
|
|
27
|
-
from better-auth /get-access-token (web stays same-origin cookie mode);
|
|
28
|
-
keycloak config plumbs betterAuthBaseUrl (BETTER_AUTH_BASE_URL, falls back
|
|
29
|
-
to BASE_URL) and expoScheme.
|
|
30
|
-
- (repo auth service, unpublished: exp:// trusted origin in development for
|
|
31
|
-
Expo Go OAuth returns.)
|
|
32
|
-
|
|
33
|
-
### Patch Changes
|
|
34
|
-
|
|
35
|
-
- Updated dependencies
|
|
36
|
-
- @multiplatform.one/web3@6.1.0
|
|
37
|
-
- @multiplatform.one/i18n@6.1.0
|
|
38
|
-
- @multiplatform.one/logger@6.1.0
|
|
39
|
-
- @multiplatform.one/platform@6.1.0
|
|
40
|
-
- @multiplatform.one/store@6.1.0
|
|
41
|
-
- @multiplatform.one/theme@6.1.0
|
|
42
|
-
|
|
43
|
-
## 6.0.4
|
|
44
|
-
|
|
45
|
-
### Patch Changes
|
|
46
|
-
|
|
47
|
-
- Updated dependencies
|
|
48
|
-
- @multiplatform.one/web3@6.0.4
|
|
49
|
-
- @multiplatform.one/frappe@6.0.4
|
|
50
|
-
- @multiplatform.one/frappe-ui@6.0.4
|
|
51
|
-
- @multiplatform.one/i18n@6.0.4
|
|
52
|
-
- @multiplatform.one/keycloak@6.0.4
|
|
53
|
-
- @multiplatform.one/logger@6.0.4
|
|
54
|
-
- @multiplatform.one/platform@6.0.4
|
|
55
|
-
- @multiplatform.one/store@6.0.4
|
|
56
|
-
- @multiplatform.one/theme@6.0.4
|
|
57
|
-
|
|
58
|
-
## 6.0.3
|
|
59
|
-
|
|
60
|
-
### Patch Changes
|
|
61
|
-
|
|
62
|
-
- Updated dependencies
|
|
63
|
-
- @multiplatform.one/web3@6.0.3
|
|
64
|
-
- @multiplatform.one/frappe@6.0.3
|
|
65
|
-
- @multiplatform.one/frappe-ui@6.0.3
|
|
66
|
-
- @multiplatform.one/i18n@6.0.3
|
|
67
|
-
- @multiplatform.one/keycloak@6.0.3
|
|
68
|
-
- @multiplatform.one/logger@6.0.3
|
|
69
|
-
- @multiplatform.one/platform@6.0.3
|
|
70
|
-
- @multiplatform.one/store@6.0.3
|
|
71
|
-
- @multiplatform.one/theme@6.0.3
|
|
72
|
-
|
|
73
|
-
## 6.0.2
|
|
74
|
-
|
|
75
|
-
### Patch Changes
|
|
76
|
-
|
|
77
|
-
- Updated dependencies
|
|
78
|
-
- @multiplatform.one/web3@6.0.2
|
|
79
|
-
- @multiplatform.one/frappe@6.0.2
|
|
80
|
-
- @multiplatform.one/frappe-ui@6.0.2
|
|
81
|
-
- @multiplatform.one/i18n@6.0.2
|
|
82
|
-
- @multiplatform.one/keycloak@6.0.2
|
|
83
|
-
- @multiplatform.one/logger@6.0.2
|
|
84
|
-
- @multiplatform.one/platform@6.0.2
|
|
85
|
-
- @multiplatform.one/store@6.0.2
|
|
86
|
-
- @multiplatform.one/theme@6.0.2
|
|
87
|
-
|
|
88
|
-
## 6.0.1
|
|
89
|
-
|
|
90
|
-
### Patch Changes
|
|
91
|
-
|
|
92
|
-
- Updated dependencies
|
|
93
|
-
- @multiplatform.one/web3@6.0.1
|
|
94
|
-
- @multiplatform.one/frappe@6.0.1
|
|
95
|
-
- @multiplatform.one/frappe-ui@6.0.1
|
|
96
|
-
- @multiplatform.one/i18n@6.0.1
|
|
97
|
-
- @multiplatform.one/keycloak@6.0.1
|
|
98
|
-
- @multiplatform.one/logger@6.0.1
|
|
99
|
-
- @multiplatform.one/platform@6.0.1
|
|
100
|
-
- @multiplatform.one/store@6.0.1
|
|
101
|
-
- @multiplatform.one/theme@6.0.1
|
|
102
|
-
|
|
103
|
-
## 6.0.0
|
|
104
|
-
|
|
105
|
-
### Major Changes
|
|
106
|
-
|
|
107
|
-
- Unified 6.0.0 release: realign all public `@multiplatform.one/*` packages onto a single, matching version line (changesets `fixed` group). Highlights:
|
|
108
|
-
- **web3 split** into standalone `@multiplatform.one/connectkit` and `@multiplatform.one/gpg` packages; `web3` now depends on them instead of bundling ConnectKit.
|
|
109
|
-
- **Sign-In With GPG** screen added to the ConnectKit modal.
|
|
110
|
-
- **Native workspace web-resolution fix** + platform-split wrappers (rich-text / `TextEditor`, forms `Barcode`) so web-only libraries stay out of the native Hermes bundle.
|
|
111
|
-
|
|
112
|
-
From this release on, these packages are versioned together.
|
|
113
|
-
|
|
114
|
-
### Patch Changes
|
|
115
|
-
|
|
116
|
-
- Updated dependencies
|
|
117
|
-
- @multiplatform.one/frappe@6.0.0
|
|
118
|
-
- @multiplatform.one/frappe-ui@6.0.0
|
|
119
|
-
- @multiplatform.one/i18n@6.0.0
|
|
120
|
-
- @multiplatform.one/keycloak@6.0.0
|
|
121
|
-
- @multiplatform.one/logger@6.0.0
|
|
122
|
-
- @multiplatform.one/platform@6.0.0
|
|
123
|
-
- @multiplatform.one/store@6.0.0
|
|
124
|
-
- @multiplatform.one/theme@6.0.0
|
|
125
|
-
- @multiplatform.one/web3@6.0.0
|
package/tsconfig.json
DELETED