mythik-react 0.1.0 → 0.1.2
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 +129 -28
- package/package.json +58 -59
package/README.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# mythik-react
|
|
2
2
|
|
|
3
|
-
React
|
|
3
|
+
The React rendering surface for Mythik. Turns JSON specs into rendered
|
|
4
|
+
UI: mount a multi-screen app via `MythikApp`, or embed a single spec
|
|
5
|
+
via `MythikRenderer`. Both consume the same spec format and resolve
|
|
6
|
+
expressions, actions, and primitives at render time.
|
|
7
|
+
|
|
8
|
+
> See [the framework README on GitHub](https://github.com/mldixdev/mythik#readme)
|
|
9
|
+
> for the full Mythik architecture and design philosophy. This file
|
|
10
|
+
> documents what `mythik-react` gives you and how to use it.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## What Mythik is, briefly
|
|
15
|
+
|
|
16
|
+
Mythik is an **AI-first, spec-driven framework**. Every UI screen
|
|
17
|
+
lives as a JSON spec in a database — not a `.tsx` file in a repo.
|
|
18
|
+
Apps grow by adding rows, not files. The framework validates every
|
|
19
|
+
change atomically and versions everything automatically, so your
|
|
20
|
+
favorite AI agent can author and patch specs through the CLI without
|
|
21
|
+
human supervision in the loop. This package is the React rendering
|
|
22
|
+
surface — it turns those specs into a real UI.
|
|
4
23
|
|
|
5
24
|
## Install
|
|
6
25
|
|
|
@@ -8,17 +27,37 @@ React renderer and app shell for Mythik specs.
|
|
|
8
27
|
npm install mythik mythik-react
|
|
9
28
|
```
|
|
10
29
|
|
|
11
|
-
|
|
30
|
+
`mythik` is a peer dependency: it ships the spec types, validators,
|
|
31
|
+
and runtime engines. `mythik-react` adds the React renderer on top.
|
|
32
|
+
|
|
33
|
+
## What you get
|
|
34
|
+
|
|
35
|
+
- **`<MythikApp>`** — full multi-screen app shell. Reads an `AppSpec`
|
|
36
|
+
(navigation, screens, theme, app-level layout) plus a `SpecStore`
|
|
37
|
+
and renders the active screen, handles navigation, manages auth
|
|
38
|
+
context, and coordinates editor sessions.
|
|
39
|
+
|
|
40
|
+
- **`<MythikRenderer>`** — single-spec renderer for embedding Mythik
|
|
41
|
+
inside an existing React app. Useful for islands and demos where
|
|
42
|
+
you don't need the full app shell.
|
|
43
|
+
|
|
44
|
+
- **38 built-in primitives** — form fields, layout, lists, modals,
|
|
45
|
+
charts, and more. Each primitive maps a spec `type` value (e.g.
|
|
46
|
+
`"button"`) to a React component with a strict prop schema. See
|
|
47
|
+
`ai-context-primitives.md` (bundled in the `mythik` package) for
|
|
48
|
+
the full catalog.
|
|
12
49
|
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Built-in React primitive registry with 38 primitives.
|
|
17
|
-
- `spatial-map`, a generic SVG/data-first primitive for spatial editors.
|
|
18
|
-
- Icon renderer hookup through `MythikApp.onPlugins` and `plugins.setIconRenderer`.
|
|
19
|
-
- Auth provider convenience re-exports sourced from core.
|
|
50
|
+
- **Customization hooks** — register custom primitives, expressions,
|
|
51
|
+
and action handlers via `MythikApp.onPlugins`. The icon renderer is
|
|
52
|
+
hookable via `plugins.setIconRenderer`.
|
|
20
53
|
|
|
21
|
-
|
|
54
|
+
- **Auth provider re-exports** — convenience surface sourced from
|
|
55
|
+
`mythik` core, so your app can import everything auth-related from
|
|
56
|
+
one place.
|
|
57
|
+
|
|
58
|
+
## Minimal example
|
|
59
|
+
|
|
60
|
+
A two-screen app, all behavior described in JSON:
|
|
22
61
|
|
|
23
62
|
```tsx
|
|
24
63
|
import { MemorySpecStore, type AppSpec, type Spec } from 'mythik';
|
|
@@ -26,13 +65,11 @@ import { MythikApp } from 'mythik-react';
|
|
|
26
65
|
|
|
27
66
|
const appSpec: AppSpec = {
|
|
28
67
|
type: 'app',
|
|
29
|
-
name: 'Demo',
|
|
30
|
-
navigation: {
|
|
31
|
-
type: 'tabs',
|
|
32
|
-
initialScreen: 'home',
|
|
33
|
-
},
|
|
68
|
+
name: 'Demo App',
|
|
69
|
+
navigation: { type: 'tabs', initialScreen: 'home' },
|
|
34
70
|
screens: {
|
|
35
|
-
home:
|
|
71
|
+
home: { label: 'Home' },
|
|
72
|
+
profile: { label: 'Profile' },
|
|
36
73
|
},
|
|
37
74
|
layout: {
|
|
38
75
|
root: 'app-shell',
|
|
@@ -42,9 +79,7 @@ const appSpec: AppSpec = {
|
|
|
42
79
|
props: { style: { minHeight: '100vh', padding: 24 } },
|
|
43
80
|
children: ['outlet'],
|
|
44
81
|
},
|
|
45
|
-
outlet: {
|
|
46
|
-
type: 'screen-outlet',
|
|
47
|
-
},
|
|
82
|
+
outlet: { type: 'screen-outlet' },
|
|
48
83
|
},
|
|
49
84
|
},
|
|
50
85
|
};
|
|
@@ -53,31 +88,97 @@ const homeSpec: Spec = {
|
|
|
53
88
|
root: 'root',
|
|
54
89
|
elements: {
|
|
55
90
|
root: {
|
|
91
|
+
type: 'box',
|
|
92
|
+
props: { style: { padding: 24 } },
|
|
93
|
+
children: ['title', 'go-profile'],
|
|
94
|
+
},
|
|
95
|
+
title: {
|
|
56
96
|
type: 'text',
|
|
57
|
-
props: { content: 'Hello from Mythik' },
|
|
97
|
+
props: { content: 'Hello from Mythik', variant: 'heading' },
|
|
98
|
+
},
|
|
99
|
+
'go-profile': {
|
|
100
|
+
type: 'button',
|
|
101
|
+
props: { label: 'View profile' },
|
|
102
|
+
on: { press: [{ action: 'navigateScreen', params: { screen: 'profile' } }] },
|
|
58
103
|
},
|
|
59
104
|
},
|
|
60
105
|
};
|
|
61
106
|
|
|
107
|
+
const profileSpec: Spec = {
|
|
108
|
+
root: 'root',
|
|
109
|
+
elements: {
|
|
110
|
+
root: { type: 'text', props: { content: 'Profile screen' } },
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
62
114
|
const specStore = new MemorySpecStore({
|
|
63
115
|
home: homeSpec,
|
|
116
|
+
profile: profileSpec,
|
|
64
117
|
});
|
|
65
118
|
|
|
66
|
-
export function App() {
|
|
119
|
+
export default function App() {
|
|
67
120
|
return <MythikApp appSpec={appSpec} specStore={specStore} />;
|
|
68
121
|
}
|
|
69
122
|
```
|
|
70
123
|
|
|
71
|
-
|
|
124
|
+
Replace `MemorySpecStore` with `SupabaseSpecStore` (or
|
|
125
|
+
`SqlServerSpecStore` from `mythik/server`) to back the same code with
|
|
126
|
+
a real database. The host file does not change as the app grows from
|
|
127
|
+
2 screens to 200.
|
|
128
|
+
|
|
129
|
+
## How the renderer works
|
|
130
|
+
|
|
131
|
+
When `MythikApp` mounts:
|
|
132
|
+
|
|
133
|
+
1. It loads the active spec from the `SpecStore`.
|
|
134
|
+
2. It walks the spec's element tree starting from `root`.
|
|
135
|
+
3. For each element, it instantiates the React component registered
|
|
136
|
+
for that element's `type` value (built-in primitive or custom).
|
|
137
|
+
4. It resolves `$token`, `$state`, `$template`, and other expressions
|
|
138
|
+
at render time, against the current state and AppSpec tokens.
|
|
139
|
+
5. It wires `on` action handlers to the action dispatcher.
|
|
140
|
+
6. When state changes or a new spec version arrives, only affected
|
|
141
|
+
subtrees re-render.
|
|
142
|
+
|
|
143
|
+
The renderer's contract: same spec + same plugins + same state =
|
|
144
|
+
identical render. This determinism is what lets AI agents iterate on
|
|
145
|
+
specs with confidence.
|
|
146
|
+
|
|
147
|
+
## Customization
|
|
148
|
+
|
|
149
|
+
Register custom primitives, expressions, and action handlers through
|
|
150
|
+
the plugin hook:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
<MythikApp
|
|
154
|
+
appSpec={appSpec}
|
|
155
|
+
specStore={specStore}
|
|
156
|
+
onPlugins={(plugins) => {
|
|
157
|
+
plugins.registerPrimitive('my-custom-card', MyCustomCard);
|
|
158
|
+
plugins.registerExpression('uppercase', (args, ctx) => String(args[0]).toUpperCase());
|
|
159
|
+
plugins.registerAction('analyticsTrack', async (params) => { /* ... */ });
|
|
160
|
+
plugins.setIconRenderer(MyIconRenderer);
|
|
161
|
+
}}
|
|
162
|
+
/>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Custom primitives become available as a `type` value in any spec
|
|
166
|
+
loaded from your store. Custom expressions and actions can be
|
|
167
|
+
referenced from any spec. Use these sparingly — every custom hook is
|
|
168
|
+
code that lives outside the spec store and outside the version-control
|
|
169
|
+
audit trail.
|
|
170
|
+
|
|
171
|
+
## Related packages
|
|
72
172
|
|
|
73
|
-
|
|
173
|
+
- [`mythik`](https://github.com/mldixdev/mythik/tree/main/packages/core#readme) — the runtime this renderer consumes (peer dependency)
|
|
174
|
+
- [`mythik-cli`](https://github.com/mldixdev/mythik/tree/main/packages/cli#readme) — author and patch the specs you're rendering
|
|
175
|
+
- [`mythik-server`](https://github.com/mldixdev/mythik/tree/main/packages/server#readme) — declarative REST server from an `ApiSpec`
|
|
74
176
|
|
|
75
|
-
|
|
177
|
+
## Status
|
|
178
|
+
|
|
179
|
+
`v0.1.2` public release. React Native work remains a repository
|
|
180
|
+
preview track and is not part of the initial npm publish surface.
|
|
76
181
|
|
|
77
182
|
## License
|
|
78
183
|
|
|
79
184
|
Apache-2.0.
|
|
80
|
-
|
|
81
|
-
## Status
|
|
82
|
-
|
|
83
|
-
v0.1.0 public release. React Native work remains a repository preview track and is not part of the initial npm publish surface.
|
package/package.json
CHANGED
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mythik-react",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "React runtime and primitives for rendering Mythik JSON specs as applications.",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"keywords": [
|
|
10
|
-
"mythik",
|
|
11
|
-
"react",
|
|
12
|
-
"json",
|
|
13
|
-
"spec-driven",
|
|
14
|
-
"application-framework",
|
|
15
|
-
"low-code",
|
|
16
|
-
"ai"
|
|
17
|
-
],
|
|
18
|
-
"homepage": "https://mythik.dev",
|
|
19
|
-
"bugs": {
|
|
20
|
-
"url": "https://github.com/mldixdev/mythik/issues"
|
|
21
|
-
},
|
|
22
|
-
"repository": {
|
|
23
|
-
"type": "git",
|
|
24
|
-
"url": "git+https://github.com/mldixdev/mythik.git",
|
|
25
|
-
"directory": "packages/react"
|
|
26
|
-
},
|
|
27
|
-
"files": [
|
|
28
|
-
"dist",
|
|
29
|
-
"LICENSE",
|
|
30
|
-
"NOTICE"
|
|
31
|
-
],
|
|
32
|
-
"exports": {
|
|
33
|
-
".": {
|
|
34
|
-
"types": "./dist/index.d.ts",
|
|
35
|
-
"default": "./dist/index.js"
|
|
36
|
-
},
|
|
37
|
-
"./package.json": "./package.json"
|
|
38
|
-
},
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "mythik-react",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "React runtime and primitives for rendering Mythik JSON specs as applications.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"mythik",
|
|
11
|
+
"react",
|
|
12
|
+
"json",
|
|
13
|
+
"spec-driven",
|
|
14
|
+
"application-framework",
|
|
15
|
+
"low-code",
|
|
16
|
+
"ai"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://mythik.dev",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/mldixdev/mythik/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/mldixdev/mythik.git",
|
|
25
|
+
"directory": "packages/react"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"NOTICE"
|
|
31
|
+
],
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./package.json": "./package.json"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"motion": "^12.38.0",
|
|
41
|
+
"mythik": "0.1.2"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
45
|
+
"@testing-library/react": "^16.0.0",
|
|
46
|
+
"@types/node": "^25.5.2",
|
|
47
|
+
"@types/react": "^19.0.0",
|
|
48
|
+
"typescript": "^5.7.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
52
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "node ../../node_modules/typescript/bin/tsc",
|
|
56
|
+
"typecheck": "node ../../node_modules/typescript/bin/tsc --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|