@mmapp/react-compiler 0.1.0-alpha.1
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 +107 -0
- package/compile-blueprint-chat.mjs +99 -0
- package/compile-blueprint-glass-console.mjs +98 -0
- package/compile-chat-defs.mjs +92 -0
- package/dist/babel/index.d.mts +3 -0
- package/dist/babel/index.d.ts +3 -0
- package/dist/babel/index.js +4851 -0
- package/dist/babel/index.mjs +7 -0
- package/dist/chunk-26U577GB.mjs +3465 -0
- package/dist/chunk-2FBDFAX6.mjs +2362 -0
- package/dist/chunk-2L4QSMXG.mjs +175 -0
- package/dist/chunk-2REDFOER.mjs +931 -0
- package/dist/chunk-46YKSHQR.mjs +175 -0
- package/dist/chunk-4XHK6FWL.mjs +2058 -0
- package/dist/chunk-5M7DKKBC.mjs +215 -0
- package/dist/chunk-5VNJ7C6N.mjs +154 -0
- package/dist/chunk-6CQOAAMV.mjs +1803 -0
- package/dist/chunk-6SEVAAVT.mjs +3516 -0
- package/dist/chunk-6YLR5ZDA.mjs +2829 -0
- package/dist/chunk-AOGY2GK6.mjs +3292 -0
- package/dist/chunk-AXXUXRNA.mjs +1434 -0
- package/dist/chunk-CHLVKMQW.mjs +175 -0
- package/dist/chunk-CKGOZAB7.mjs +939 -0
- package/dist/chunk-D34RAZUX.mjs +2223 -0
- package/dist/chunk-EQGA6A6D.mjs +121 -0
- package/dist/chunk-EY2CSXYA.mjs +822 -0
- package/dist/chunk-FIQ65CDR.mjs +925 -0
- package/dist/chunk-FOZXJFAR.mjs +186 -0
- package/dist/chunk-FX6URXWN.mjs +186 -0
- package/dist/chunk-G7SMOWOL.mjs +828 -0
- package/dist/chunk-GGB4G5YY.mjs +175 -0
- package/dist/chunk-HLRGCCIL.mjs +4839 -0
- package/dist/chunk-HOIUP6IF.mjs +690 -0
- package/dist/chunk-I3AU7GRD.mjs +120 -0
- package/dist/chunk-ILFGMUVD.mjs +1933 -0
- package/dist/chunk-IPTX5MJU.mjs +3223 -0
- package/dist/chunk-ITGUSH2Z.mjs +2783 -0
- package/dist/chunk-IXHBCAMF.mjs +3306 -0
- package/dist/chunk-J7TWJ3TM.mjs +2784 -0
- package/dist/chunk-JDPLDGVF.mjs +4810 -0
- package/dist/chunk-K53XP2DL.mjs +148 -0
- package/dist/chunk-K5HX2SVL.mjs +1902 -0
- package/dist/chunk-KFGYOOVS.mjs +214 -0
- package/dist/chunk-KFVVOS5N.mjs +925 -0
- package/dist/chunk-L2OZ4CDV.mjs +113 -0
- package/dist/chunk-MIZV3TAN.mjs +3293 -0
- package/dist/chunk-NKKLQE5V.mjs +148 -0
- package/dist/chunk-NOW23XFZ.mjs +186 -0
- package/dist/chunk-NRXQKQ74.mjs +148 -0
- package/dist/chunk-OWI6XWCD.mjs +3375 -0
- package/dist/chunk-PRUMNNDI.mjs +3192 -0
- package/dist/chunk-QTBD5B3F.mjs +148 -0
- package/dist/chunk-SKSDPPNT.mjs +3788 -0
- package/dist/chunk-SP2YUS33.mjs +186 -0
- package/dist/chunk-SU4E6E7B.mjs +3153 -0
- package/dist/chunk-SYUUKW5A.mjs +3379 -0
- package/dist/chunk-UL2XZEMA.mjs +3128 -0
- package/dist/chunk-XMWUHQVV.mjs +939 -0
- package/dist/chunk-XZNEDRGN.mjs +3876 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/chunk-YFS6JMYO.mjs +3342 -0
- package/dist/chunk-Z6AIQ4KL.mjs +113 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +11585 -0
- package/dist/cli/index.mjs +701 -0
- package/dist/codemod/cli.d.mts +1 -0
- package/dist/codemod/cli.d.ts +1 -0
- package/dist/codemod/cli.js +1104 -0
- package/dist/codemod/cli.mjs +157 -0
- package/dist/codemod/index.d.mts +148 -0
- package/dist/codemod/index.d.ts +148 -0
- package/dist/codemod/index.js +981 -0
- package/dist/codemod/index.mjs +25 -0
- package/dist/dev-server-Bs_sz2DG.d.mts +111 -0
- package/dist/dev-server-Bs_sz2DG.d.ts +111 -0
- package/dist/dev-server-CjoufJ-u.d.mts +109 -0
- package/dist/dev-server-CjoufJ-u.d.ts +109 -0
- package/dist/dev-server.d.mts +3 -0
- package/dist/dev-server.d.ts +3 -0
- package/dist/dev-server.js +7603 -0
- package/dist/dev-server.mjs +11 -0
- package/dist/envelope-DD7v0v6E.d.mts +265 -0
- package/dist/envelope-DD7v0v6E.d.ts +265 -0
- package/dist/envelope-vCVjrHlo.d.mts +265 -0
- package/dist/envelope-vCVjrHlo.d.ts +265 -0
- package/dist/envelope.d.mts +2 -0
- package/dist/envelope.d.ts +2 -0
- package/dist/envelope.js +5184 -0
- package/dist/envelope.mjs +9 -0
- package/dist/index-B5gSgvnd.d.mts +44 -0
- package/dist/index-B5gSgvnd.d.ts +44 -0
- package/dist/index-Bs0MnR54.d.mts +103 -0
- package/dist/index-Bs0MnR54.d.ts +103 -0
- package/dist/index-DR0nNc_f.d.mts +101 -0
- package/dist/index-DR0nNc_f.d.ts +101 -0
- package/dist/index-revho_gS.d.mts +104 -0
- package/dist/index-revho_gS.d.ts +104 -0
- package/dist/index.d.mts +1099 -0
- package/dist/index.d.ts +1099 -0
- package/dist/index.js +10162 -0
- package/dist/index.mjs +372 -0
- package/dist/init-IXEE2RCF.mjs +340 -0
- package/dist/project-compiler-EGJUTAJU.mjs +10 -0
- package/dist/project-compiler-VFR6CSDX.mjs +10 -0
- package/dist/project-decompiler-5GY2KSG4.mjs +7 -0
- package/dist/pull-A2QUHW4K.mjs +109 -0
- package/dist/pull-JBEQWVPE.mjs +109 -0
- package/dist/testing/index.d.mts +211 -0
- package/dist/testing/index.d.ts +211 -0
- package/dist/testing/index.js +5106 -0
- package/dist/testing/index.mjs +247 -0
- package/dist/vite/index.d.mts +59 -0
- package/dist/vite/index.d.ts +59 -0
- package/dist/vite/index.js +5023 -0
- package/dist/vite/index.mjs +8 -0
- package/examples/README.md +72 -0
- package/examples/authentication/main.workflow.tsx +139 -0
- package/examples/authentication/mm.config.ts +22 -0
- package/examples/authentication/models/auth.ts +45 -0
- package/examples/authentication/pages/LoginPage.tsx +79 -0
- package/examples/authentication/pages/SignupPage.tsx +87 -0
- package/examples/counter.workflow.tsx +65 -0
- package/examples/dashboard.workflow.tsx +419 -0
- package/examples/invoice-approval/actions/invoice.server.ts +72 -0
- package/examples/invoice-approval/main.workflow.tsx +168 -0
- package/examples/invoice-approval/mm.config.ts +18 -0
- package/examples/invoice-approval/models/invoice.ts +46 -0
- package/examples/invoice-approval/pages/InvoiceDetailPage.tsx +175 -0
- package/examples/invoice-approval/pages/InvoiceFormPage.tsx +198 -0
- package/examples/invoice-approval/pages/InvoiceListPage.tsx +141 -0
- package/examples/todo-app.workflow.tsx +131 -0
- package/examples/uber-app/actions/matching.server.ts +177 -0
- package/examples/uber-app/actions/notifications.server.ts +176 -0
- package/examples/uber-app/actions/payments.server.ts +184 -0
- package/examples/uber-app/actions/pricing.server.ts +176 -0
- package/examples/uber-app/app/admin/analytics.tsx +102 -0
- package/examples/uber-app/app/admin/fleet.tsx +102 -0
- package/examples/uber-app/app/admin/surge-pricing.tsx +95 -0
- package/examples/uber-app/app/driver/dashboard.tsx +87 -0
- package/examples/uber-app/app/driver/earnings.tsx +101 -0
- package/examples/uber-app/app/driver/navigation.tsx +94 -0
- package/examples/uber-app/app/driver/ride-acceptance.tsx +103 -0
- package/examples/uber-app/app/rider/home.tsx +109 -0
- package/examples/uber-app/app/rider/payment-methods.tsx +134 -0
- package/examples/uber-app/app/rider/ride-history.tsx +90 -0
- package/examples/uber-app/app/rider/ride-tracking.tsx +108 -0
- package/examples/uber-app/components/DriverCard.tsx +176 -0
- package/examples/uber-app/components/MapView.tsx +216 -0
- package/examples/uber-app/components/RatingStars.tsx +227 -0
- package/examples/uber-app/components/RideCard.tsx +167 -0
- package/examples/uber-app/mm.config.ts +30 -0
- package/examples/uber-app/models/location.model.ts +70 -0
- package/examples/uber-app/models/payment.model.ts +87 -0
- package/examples/uber-app/models/rating.model.ts +54 -0
- package/examples/uber-app/models/ride.model.ts +118 -0
- package/examples/uber-app/models/user.model.ts +66 -0
- package/examples/uber-app/models/vehicle.model.ts +63 -0
- package/examples/uber-app/tests/payment.test.tsx +129 -0
- package/examples/uber-app/tests/ride-flow.test.tsx +123 -0
- package/examples/uber-app/workflows/dispute-resolution.workflow.tsx +205 -0
- package/examples/uber-app/workflows/driver-onboarding.workflow.tsx +227 -0
- package/examples/uber-app/workflows/payment-processing.workflow.tsx +223 -0
- package/examples/uber-app/workflows/ride-request.workflow.tsx +194 -0
- package/package.json +77 -0
- package/package.json.backup +86 -0
- package/scripts/decompile.ts +226 -0
- package/scripts/seed-auth.ts +267 -0
- package/scripts/seed-uber.ts +248 -0
- package/scripts/validate-uber.ts +119 -0
- package/seed-blueprint-chat.mjs +444 -0
- package/seed-blueprint-glass-console.mjs +445 -0
- package/seed-compiled.mjs +318 -0
- package/src/RoundTripValidator.ts +400 -0
- package/src/__tests__/atom-rendering-coverage.test.ts +680 -0
- package/src/__tests__/auth-module-compilation.test.ts +247 -0
- package/src/__tests__/auth-template-compilation.test.ts +589 -0
- package/src/__tests__/change-extractor.test.ts +142 -0
- package/src/__tests__/cli-pull.test.ts +73 -0
- package/src/__tests__/cli-test.test.ts +72 -0
- package/src/__tests__/component-extractor.test.ts +331 -0
- package/src/__tests__/context-extractor.test.ts +145 -0
- package/src/__tests__/decompiler.test.ts +718 -0
- package/src/__tests__/define-blueprint.test.ts +133 -0
- package/src/__tests__/definition-validator.test.ts +519 -0
- package/src/__tests__/during-extractor.test.ts +152 -0
- package/src/__tests__/effect-extractor.test.ts +107 -0
- package/src/__tests__/event-emission.test.ts +127 -0
- package/src/__tests__/examples.test.ts +236 -0
- package/src/__tests__/full-blueprint-coverage.test.ts +1221 -0
- package/src/__tests__/golden-suite.test.ts +403 -0
- package/src/__tests__/grammar-island-extractor.test.ts +289 -0
- package/src/__tests__/instance-key.test.ts +82 -0
- package/src/__tests__/ir-migration.test.ts +255 -0
- package/src/__tests__/lock-file.test.ts +117 -0
- package/src/__tests__/model-extractor.test.ts +195 -0
- package/src/__tests__/model-field-acl.test.ts +237 -0
- package/src/__tests__/model-hooks.test.ts +130 -0
- package/src/__tests__/model-ref-resolution.test.ts +268 -0
- package/src/__tests__/model-roundtrip.test.ts +502 -0
- package/src/__tests__/model-runtime.test.ts +112 -0
- package/src/__tests__/model-transitions.test.ts +183 -0
- package/src/__tests__/nrt-action-trace.test.ts +391 -0
- package/src/__tests__/pipeline-hardening.test.ts +413 -0
- package/src/__tests__/project-compiler.test.ts +546 -0
- package/src/__tests__/project-decompiler.test.ts +343 -0
- package/src/__tests__/query-compilation.test.ts +145 -0
- package/src/__tests__/round-trip/PLAN.md +158 -0
- package/src/__tests__/round-trip/README.md +52 -0
- package/src/__tests__/round-trip/RESULTS.md +86 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +55 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +11 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +54 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +79 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +12 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +50 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +25 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +11 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +32 -0
- package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +79 -0
- package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +10 -0
- package/src/__tests__/round-trip/round-trip.test.ts +2598 -0
- package/src/__tests__/round-trip-ir.test.ts +300 -0
- package/src/__tests__/round-trip.test.ts +1212 -0
- package/src/__tests__/route-merging.test.ts +372 -0
- package/src/__tests__/router-composition.test.ts +489 -0
- package/src/__tests__/router-extractor.test.ts +176 -0
- package/src/__tests__/server-action-extractor.test.ts +128 -0
- package/src/__tests__/smart-type-inference.test.ts +365 -0
- package/src/__tests__/source-envelope.test.ts +284 -0
- package/src/__tests__/source-fidelity.test.ts +516 -0
- package/src/__tests__/state-extractor.test.ts +115 -0
- package/src/__tests__/strict-mode.test.ts +227 -0
- package/src/__tests__/transition-effect-extractor.test.ts +119 -0
- package/src/__tests__/transition-extractor.test.ts +68 -0
- package/src/__tests__/ts-to-expression.test.ts +462 -0
- package/src/__tests__/type-generator.test.ts +201 -0
- package/src/__tests__/uber-validation.test.ts +502 -0
- package/src/action-compiler.ts +361 -0
- package/src/babel/emitters/experience-transform.ts +199 -0
- package/src/babel/emitters/ir-to-tsx-emitter.ts +110 -0
- package/src/babel/emitters/pure-form-emitter.ts +1023 -0
- package/src/babel/emitters/runtime-glue-emitter.ts +39 -0
- package/src/babel/extractors/change-extractor.ts +199 -0
- package/src/babel/extractors/component-extractor.ts +907 -0
- package/src/babel/extractors/computed-extractor.ts +262 -0
- package/src/babel/extractors/context-extractor.ts +277 -0
- package/src/babel/extractors/during-extractor.ts +295 -0
- package/src/babel/extractors/effect-extractor.ts +340 -0
- package/src/babel/extractors/event-extractor.ts +235 -0
- package/src/babel/extractors/grammar-island-extractor.ts +302 -0
- package/src/babel/extractors/model-extractor.ts +1018 -0
- package/src/babel/extractors/router-extractor.ts +303 -0
- package/src/babel/extractors/server-action-extractor.ts +173 -0
- package/src/babel/extractors/server-action-hook-extractor.ts +72 -0
- package/src/babel/extractors/server-state-extractor.ts +88 -0
- package/src/babel/extractors/state-extractor.ts +214 -0
- package/src/babel/extractors/transition-effect-extractor.ts +176 -0
- package/src/babel/extractors/transition-extractor.ts +143 -0
- package/src/babel/index.ts +24 -0
- package/src/babel/transpilers/ts-to-expression.ts +674 -0
- package/src/babel/visitor.ts +807 -0
- package/src/cli/auth.ts +255 -0
- package/src/cli/build.ts +288 -0
- package/src/cli/deploy.ts +206 -0
- package/src/cli/index.ts +328 -0
- package/src/cli/init.ts +388 -0
- package/src/cli/installer.ts +261 -0
- package/src/cli/lock-file.ts +94 -0
- package/src/cli/mmrc.ts +22 -0
- package/src/cli/pull.ts +172 -0
- package/src/cli/registry-client.ts +175 -0
- package/src/cli/test.ts +397 -0
- package/src/cli/type-generator.ts +243 -0
- package/src/codemod/__tests__/forward.test.ts +239 -0
- package/src/codemod/__tests__/reverse.test.ts +145 -0
- package/src/codemod/__tests__/round-trip.test.ts +137 -0
- package/src/codemod/annotation.ts +97 -0
- package/src/codemod/classify.ts +197 -0
- package/src/codemod/cli.ts +207 -0
- package/src/codemod/control-flow.ts +409 -0
- package/src/codemod/forward.ts +244 -0
- package/src/codemod/import-manager.ts +171 -0
- package/src/codemod/index.ts +120 -0
- package/src/codemod/reverse.ts +197 -0
- package/src/codemod/rules.ts +174 -0
- package/src/codemod/state-transform.ts +126 -0
- package/src/decompiler/ast-builder.ts +538 -0
- package/src/decompiler/config-generator.ts +151 -0
- package/src/decompiler/index.ts +315 -0
- package/src/decompiler/project-decompiler.ts +1776 -0
- package/src/decompiler/project.ts +862 -0
- package/src/decompiler/split-strategy.ts +140 -0
- package/src/decompiler/state-emitter.ts +1053 -0
- package/src/decompiler/sx-emitter.ts +318 -0
- package/src/decompiler/workspace-hydrator.ts +189 -0
- package/src/dev-server.ts +238 -0
- package/src/envelope/fs-tree.ts +217 -0
- package/src/envelope/source-envelope.ts +264 -0
- package/src/envelope.ts +315 -0
- package/src/incremental-compiler.ts +401 -0
- package/src/index.ts +99 -0
- package/src/model-compiler.ts +277 -0
- package/src/project-compiler.ts +1629 -0
- package/src/route-extractor.ts +333 -0
- package/src/testing/index.ts +32 -0
- package/src/testing/snapshot.ts +252 -0
- package/src/testing/test-utils.ts +226 -0
- package/src/types.ts +68 -0
- package/src/vite/index.ts +288 -0
- package/test-compile.mjs +142 -0
- package/tsconfig.json +25 -0
- package/tsup.config.ts +23 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# @mindmatrix/react-compiler — Examples
|
|
2
|
+
|
|
3
|
+
Sample `.workflow.tsx` files demonstrating the React framework for MindMatrix workflows.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| File | What it demonstrates |
|
|
8
|
+
|------|---------------------|
|
|
9
|
+
| `counter.workflow.tsx` | State fields (`useState`), transitions (`useTransition`), enter hooks (`useOnEnter`), field watchers (`useOnChange`), `sx` prop styling, JSX experience tree |
|
|
10
|
+
| `todo-app.workflow.tsx` | Data sources (`useQuery`), mutations (`useMutation`), role guards (`useRole`), polling (`useWhileIn`), conditional rendering, list mapping (`Each`), multi-state transitions |
|
|
11
|
+
| `dashboard.workflow.tsx` | Blueprint with multi-route layout (`/dashboard`, `/data`, `/settings`), 3 roles (`admin`, `viewer`, `editor`), 5 data sources, event subscriptions (`useOnEvent`), visualization atoms (`Chart`, `MetricCard`, `ServerGrid`), complex state machine (4 states, 7 transitions) |
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
### Compile a single file
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd packages/react-compiler
|
|
19
|
+
npx babel --plugins ./src/babel examples/counter.workflow.tsx
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Build all workflow files
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# From the react-compiler package
|
|
26
|
+
npx mmrc build --src examples --out dist/examples
|
|
27
|
+
|
|
28
|
+
# Output: dist/examples/counter.json, dist/examples/todo-app.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Dev server (watch + hot reload)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx mmrc dev --src examples --port 5199
|
|
35
|
+
|
|
36
|
+
# Watches for changes, recompiles on save, notifies connected editors via WebSocket
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Run tests
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx mmrc test --src examples
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## What the compiler extracts
|
|
46
|
+
|
|
47
|
+
Each `.workflow.tsx` compiles to an IR (Intermediate Representation) containing:
|
|
48
|
+
|
|
49
|
+
- **fields** — from `useState()` calls (name, type, default value)
|
|
50
|
+
- **states** — from `useOnEnter()`, `useOnExit()`, `useTransition()` (name, type, enter/exit actions)
|
|
51
|
+
- **transitions** — from `useTransition()` (name, from, to, conditions)
|
|
52
|
+
- **experience** — from the JSX return (component tree with bindings, layout, config)
|
|
53
|
+
- **dataSources** — from `useQuery()` (slug, filters, pagination, sort)
|
|
54
|
+
- **mutationTargets** — from `useMutation()` (slugs this workflow writes to)
|
|
55
|
+
- **roleDependencies** — from `useRole()` (roles this workflow checks)
|
|
56
|
+
- **fieldWatchers** — from `useOnChange()` (reactive field observers)
|
|
57
|
+
|
|
58
|
+
## Hooks reference
|
|
59
|
+
|
|
60
|
+
| Hook | Compiler output | Description |
|
|
61
|
+
|------|----------------|-------------|
|
|
62
|
+
| `useState(init)` | `fields[]` | Declares a workflow field with inferred type |
|
|
63
|
+
| `useTransition(name, { from, to })` | `transitions[]` | Declares a state transition |
|
|
64
|
+
| `useOnEnter(state, fn)` | `states[].on_enter[]` | Action when entering a state |
|
|
65
|
+
| `useOnExit(state, fn)` | `states[].on_exit[]` | Action when leaving a state |
|
|
66
|
+
| `useOnEvent(event, fn)` | `on_event[]` | Subscribe to external events |
|
|
67
|
+
| `useWhileIn(state, ms, fn)` | `states[].during[]` | Polling action while in state |
|
|
68
|
+
| `useOnChange(field, fn)` | `metadata.fieldWatchers[]` | React to field value changes |
|
|
69
|
+
| `useOnTransition(fn)` | `metadata.transitionEffects[]` | Run on any transition |
|
|
70
|
+
| `useQuery(slug, opts)` | `metadata.dataSources[]` | Bind to a data workflow |
|
|
71
|
+
| `useMutation(slug)` | `metadata.mutationTargets[]` | Declare write access to a workflow |
|
|
72
|
+
| `useRole(role)` | `metadata.roleDependencies[]` | Check role-based access |
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @workflow slug="mod-authentication" version="1.0.0" category="module"
|
|
3
|
+
* @description Login & signup pages with configurable layout, routing, and features.
|
|
4
|
+
*
|
|
5
|
+
* States: unauthenticated → authenticating → authenticated | error
|
|
6
|
+
* Pages: Login, Signup (optional)
|
|
7
|
+
* Config: appName, layout, showSignup, showForgotPassword, redirectPath
|
|
8
|
+
*
|
|
9
|
+
* This is a system module — it ships with the platform and can be inserted
|
|
10
|
+
* into any blueprint project. Configuration fields control the generated
|
|
11
|
+
* experience tree (layout variant, feature toggles, app branding).
|
|
12
|
+
*/
|
|
13
|
+
import {
|
|
14
|
+
Stack,
|
|
15
|
+
Row,
|
|
16
|
+
Card,
|
|
17
|
+
Heading,
|
|
18
|
+
Text,
|
|
19
|
+
Route,
|
|
20
|
+
Show,
|
|
21
|
+
useOnEnter,
|
|
22
|
+
useTransition,
|
|
23
|
+
} from '@mindmatrix/react';
|
|
24
|
+
import { useState } from 'react';
|
|
25
|
+
import { LoginPage } from './pages/LoginPage';
|
|
26
|
+
import { SignupPage } from './pages/SignupPage';
|
|
27
|
+
|
|
28
|
+
export default function Authentication() {
|
|
29
|
+
// -------------------------------------------------------------------------
|
|
30
|
+
// Config fields — set at module insertion time, stored as workflow fields
|
|
31
|
+
// -------------------------------------------------------------------------
|
|
32
|
+
const [appName, setAppName] = useState('My App');
|
|
33
|
+
const [layout, setLayout] = useState('card');
|
|
34
|
+
const [showSignup, setShowSignup] = useState(true);
|
|
35
|
+
const [showForgotPassword, setShowForgotPassword] = useState(true);
|
|
36
|
+
const [redirectPath, setRedirectPath] = useState('/');
|
|
37
|
+
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
39
|
+
// Runtime fields — managed during auth flow
|
|
40
|
+
// -------------------------------------------------------------------------
|
|
41
|
+
const [email, setEmail] = useState('');
|
|
42
|
+
const [password, setPassword] = useState('');
|
|
43
|
+
const [confirmPassword, setConfirmPassword] = useState('');
|
|
44
|
+
const [firstName, setFirstName] = useState('');
|
|
45
|
+
const [lastName, setLastName] = useState('');
|
|
46
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
47
|
+
|
|
48
|
+
// -------------------------------------------------------------------------
|
|
49
|
+
// State effects
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
useOnEnter('unauthenticated', () => {
|
|
52
|
+
setErrorMessage('');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
useOnEnter('error', () => {
|
|
56
|
+
setErrorMessage('Authentication failed. Please try again.');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
useOnEnter('authenticated', () => {
|
|
60
|
+
setEmail('');
|
|
61
|
+
setPassword('');
|
|
62
|
+
setConfirmPassword('');
|
|
63
|
+
setErrorMessage('');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// -------------------------------------------------------------------------
|
|
67
|
+
// Transitions — auth state machine
|
|
68
|
+
// -------------------------------------------------------------------------
|
|
69
|
+
const login = useTransition('login', {
|
|
70
|
+
from: 'unauthenticated',
|
|
71
|
+
to: 'authenticating',
|
|
72
|
+
requiredFields: ['email', 'password'],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const loginSuccess = useTransition('login_success', {
|
|
76
|
+
from: 'authenticating',
|
|
77
|
+
to: 'authenticated',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const loginError = useTransition('login_error', {
|
|
81
|
+
from: 'authenticating',
|
|
82
|
+
to: 'error',
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const signup = useTransition('signup', {
|
|
86
|
+
from: 'unauthenticated',
|
|
87
|
+
to: 'authenticating',
|
|
88
|
+
requiredFields: ['email', 'password', 'firstName', 'lastName'],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const signupSuccess = useTransition('signup_success', {
|
|
92
|
+
from: 'authenticating',
|
|
93
|
+
to: 'authenticated',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const signupError = useTransition('signup_error', {
|
|
97
|
+
from: 'authenticating',
|
|
98
|
+
to: 'error',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const logout = useTransition('logout', {
|
|
102
|
+
from: 'authenticated',
|
|
103
|
+
to: 'unauthenticated',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const retry = useTransition('retry', {
|
|
107
|
+
from: 'error',
|
|
108
|
+
to: 'unauthenticated',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// -------------------------------------------------------------------------
|
|
112
|
+
// View — Router with login + optional signup routes
|
|
113
|
+
// -------------------------------------------------------------------------
|
|
114
|
+
return (
|
|
115
|
+
<Stack sx={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', bg: '#f8fafc', p: [24, 16] }}>
|
|
116
|
+
<Card sx={{ p: [32, 28], maxWidth: 420, width: '100%', rounded: 12 }}>
|
|
117
|
+
<Route path="/login">
|
|
118
|
+
<LoginPage
|
|
119
|
+
appName={appName}
|
|
120
|
+
showForgotPassword={showForgotPassword}
|
|
121
|
+
showSignup={showSignup}
|
|
122
|
+
onLogin={() => login.fire()}
|
|
123
|
+
errorMessage={errorMessage}
|
|
124
|
+
/>
|
|
125
|
+
</Route>
|
|
126
|
+
|
|
127
|
+
<Show when={showSignup}>
|
|
128
|
+
<Route path="/signup">
|
|
129
|
+
<SignupPage
|
|
130
|
+
appName={appName}
|
|
131
|
+
onSignup={() => signup.fire()}
|
|
132
|
+
errorMessage={errorMessage}
|
|
133
|
+
/>
|
|
134
|
+
</Route>
|
|
135
|
+
</Show>
|
|
136
|
+
</Card>
|
|
137
|
+
</Stack>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module configuration for "Authentication".
|
|
3
|
+
*
|
|
4
|
+
* This is a system module — it ships with the platform and provides
|
|
5
|
+
* login/signup pages with configurable layout, routing, and features.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { defineBlueprint } from '@mindmatrix/react';
|
|
9
|
+
|
|
10
|
+
export default defineBlueprint({
|
|
11
|
+
slug: 'mod-authentication',
|
|
12
|
+
name: 'Authentication',
|
|
13
|
+
version: '1.0.0',
|
|
14
|
+
category: 'module',
|
|
15
|
+
description:
|
|
16
|
+
'Login & signup pages with configurable layout, routing, and features. ' +
|
|
17
|
+
'Supports card, split, and minimal layouts with optional signup and forgot-password flows.',
|
|
18
|
+
roles: [
|
|
19
|
+
{ name: 'anonymous', permissions: ['view'] },
|
|
20
|
+
{ name: 'user', permissions: ['view', 'transition'] },
|
|
21
|
+
],
|
|
22
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth — data model interface.
|
|
3
|
+
*
|
|
4
|
+
* Fields map directly to workflow definition fields (parameters).
|
|
5
|
+
* Config fields control how the module renders (layout, feature toggles).
|
|
6
|
+
* Runtime fields track auth state during execution.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Configuration parameters — set at module insertion time */
|
|
10
|
+
export interface AuthConfig {
|
|
11
|
+
/** Application name displayed in headings */
|
|
12
|
+
appName: string;
|
|
13
|
+
/** Layout variant: card (centered), split (image + form), minimal (inline) */
|
|
14
|
+
layout: 'card' | 'split' | 'minimal';
|
|
15
|
+
/** Whether to include a signup page/route */
|
|
16
|
+
showSignup: boolean;
|
|
17
|
+
/** Whether to show the forgot-password link on login */
|
|
18
|
+
showForgotPassword: boolean;
|
|
19
|
+
/** Where to redirect after successful login */
|
|
20
|
+
redirectPath: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Runtime fields — managed during auth flow */
|
|
24
|
+
export interface AuthRuntime {
|
|
25
|
+
/** User email input */
|
|
26
|
+
email: string;
|
|
27
|
+
/** User password input */
|
|
28
|
+
password: string;
|
|
29
|
+
/** Confirm password (signup only) */
|
|
30
|
+
confirmPassword: string;
|
|
31
|
+
/** First name (signup only) */
|
|
32
|
+
firstName: string;
|
|
33
|
+
/** Last name (signup only) */
|
|
34
|
+
lastName: string;
|
|
35
|
+
/** Error message from failed auth attempt */
|
|
36
|
+
errorMessage: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Auth lifecycle states */
|
|
40
|
+
export enum AuthState {
|
|
41
|
+
Unauthenticated = 'unauthenticated',
|
|
42
|
+
Authenticating = 'authenticating',
|
|
43
|
+
Authenticated = 'authenticated',
|
|
44
|
+
Error = 'error',
|
|
45
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LoginPage — login form with email/password fields and action buttons.
|
|
3
|
+
*
|
|
4
|
+
* Uses @mindmatrix/react atoms: Stack, Heading, Text, TextInput, Button.
|
|
5
|
+
* Bindings connect to workflow fields; transition fires move through auth states.
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
Stack,
|
|
9
|
+
Heading,
|
|
10
|
+
Text,
|
|
11
|
+
TextInput,
|
|
12
|
+
Button,
|
|
13
|
+
Show,
|
|
14
|
+
Link,
|
|
15
|
+
} from '@mindmatrix/react';
|
|
16
|
+
|
|
17
|
+
interface LoginPageProps {
|
|
18
|
+
appName: string;
|
|
19
|
+
showForgotPassword: boolean;
|
|
20
|
+
showSignup: boolean;
|
|
21
|
+
onLogin: () => void;
|
|
22
|
+
errorMessage: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function LoginPage({
|
|
26
|
+
appName,
|
|
27
|
+
showForgotPassword,
|
|
28
|
+
showSignup,
|
|
29
|
+
onLogin,
|
|
30
|
+
errorMessage,
|
|
31
|
+
}: LoginPageProps) {
|
|
32
|
+
return (
|
|
33
|
+
<Stack sx={{ gap: 16 }}>
|
|
34
|
+
<Heading sx={{ fontSize: 24, fontWeight: 'bold', textAlign: 'center' }}>
|
|
35
|
+
Sign in to {appName}
|
|
36
|
+
</Heading>
|
|
37
|
+
<Text sx={{ fontSize: 14, textAlign: 'center', color: '#64748b' }}>
|
|
38
|
+
Enter your credentials to continue
|
|
39
|
+
</Text>
|
|
40
|
+
|
|
41
|
+
<Show when={!!errorMessage}>
|
|
42
|
+
<Text sx={{ fontSize: 13, color: '#dc2626', textAlign: 'center', bg: '#fef2f2', p: 8, rounded: 8 }}>
|
|
43
|
+
{errorMessage}
|
|
44
|
+
</Text>
|
|
45
|
+
</Show>
|
|
46
|
+
|
|
47
|
+
<TextInput
|
|
48
|
+
bind="email"
|
|
49
|
+
placeholder="you@example.com"
|
|
50
|
+
sx={{ width: '100%' }}
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
<TextInput
|
|
54
|
+
bind="password"
|
|
55
|
+
placeholder="••••••••"
|
|
56
|
+
sx={{ width: '100%' }}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
<Show when={showForgotPassword}>
|
|
60
|
+
<Text sx={{ fontSize: 13, textAlign: 'right', color: '#2563eb', cursor: 'pointer' }}>
|
|
61
|
+
Forgot your password?
|
|
62
|
+
</Text>
|
|
63
|
+
</Show>
|
|
64
|
+
|
|
65
|
+
<Button onClick={onLogin} sx={{ width: '100%', mt: 8 }}>
|
|
66
|
+
Sign In
|
|
67
|
+
</Button>
|
|
68
|
+
|
|
69
|
+
<Show when={showSignup}>
|
|
70
|
+
<Text sx={{ fontSize: 13, textAlign: 'center', color: '#64748b', mt: 8 }}>
|
|
71
|
+
Don't have an account?{' '}
|
|
72
|
+
<Link to="/signup" sx={{ color: '#2563eb', fontWeight: 'medium' }}>
|
|
73
|
+
Sign up
|
|
74
|
+
</Link>
|
|
75
|
+
</Text>
|
|
76
|
+
</Show>
|
|
77
|
+
</Stack>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SignupPage — registration form with name, email, password fields.
|
|
3
|
+
*
|
|
4
|
+
* Uses @mindmatrix/react atoms: Stack, Row, Heading, Text, TextInput, Button.
|
|
5
|
+
* Bindings connect to workflow fields; transition fires move through auth states.
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
Stack,
|
|
9
|
+
Row,
|
|
10
|
+
Heading,
|
|
11
|
+
Text,
|
|
12
|
+
TextInput,
|
|
13
|
+
Button,
|
|
14
|
+
Show,
|
|
15
|
+
Link,
|
|
16
|
+
} from '@mindmatrix/react';
|
|
17
|
+
|
|
18
|
+
interface SignupPageProps {
|
|
19
|
+
appName: string;
|
|
20
|
+
onSignup: () => void;
|
|
21
|
+
errorMessage: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function SignupPage({
|
|
25
|
+
appName,
|
|
26
|
+
onSignup,
|
|
27
|
+
errorMessage,
|
|
28
|
+
}: SignupPageProps) {
|
|
29
|
+
return (
|
|
30
|
+
<Stack sx={{ gap: 16 }}>
|
|
31
|
+
<Heading sx={{ fontSize: 24, fontWeight: 'bold', textAlign: 'center' }}>
|
|
32
|
+
Create your {appName} account
|
|
33
|
+
</Heading>
|
|
34
|
+
<Text sx={{ fontSize: 14, textAlign: 'center', color: '#64748b' }}>
|
|
35
|
+
Fill in your details to get started
|
|
36
|
+
</Text>
|
|
37
|
+
|
|
38
|
+
<Show when={!!errorMessage}>
|
|
39
|
+
<Text sx={{ fontSize: 13, color: '#dc2626', textAlign: 'center', bg: '#fef2f2', p: 8, rounded: 8 }}>
|
|
40
|
+
{errorMessage}
|
|
41
|
+
</Text>
|
|
42
|
+
</Show>
|
|
43
|
+
|
|
44
|
+
<Row sx={{ gap: 12 }}>
|
|
45
|
+
<TextInput
|
|
46
|
+
bind="firstName"
|
|
47
|
+
placeholder="First name"
|
|
48
|
+
sx={{ flex: 1 }}
|
|
49
|
+
/>
|
|
50
|
+
<TextInput
|
|
51
|
+
bind="lastName"
|
|
52
|
+
placeholder="Last name"
|
|
53
|
+
sx={{ flex: 1 }}
|
|
54
|
+
/>
|
|
55
|
+
</Row>
|
|
56
|
+
|
|
57
|
+
<TextInput
|
|
58
|
+
bind="email"
|
|
59
|
+
placeholder="you@example.com"
|
|
60
|
+
sx={{ width: '100%' }}
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
<TextInput
|
|
64
|
+
bind="password"
|
|
65
|
+
placeholder="Min 8 characters"
|
|
66
|
+
sx={{ width: '100%' }}
|
|
67
|
+
/>
|
|
68
|
+
|
|
69
|
+
<TextInput
|
|
70
|
+
bind="confirmPassword"
|
|
71
|
+
placeholder="Repeat password"
|
|
72
|
+
sx={{ width: '100%' }}
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
<Button onClick={onSignup} sx={{ width: '100%', mt: 8 }}>
|
|
76
|
+
Create Account
|
|
77
|
+
</Button>
|
|
78
|
+
|
|
79
|
+
<Text sx={{ fontSize: 13, textAlign: 'center', color: '#64748b', mt: 8 }}>
|
|
80
|
+
Already have an account?{' '}
|
|
81
|
+
<Link to="/login" sx={{ color: '#2563eb', fontWeight: 'medium' }}>
|
|
82
|
+
Sign in
|
|
83
|
+
</Link>
|
|
84
|
+
</Text>
|
|
85
|
+
</Stack>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @workflow slug="counter" version="1.0.0" category="workflow"
|
|
3
|
+
* @description A simple counter demonstrating state, transitions, hooks, and sx styling.
|
|
4
|
+
*/
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
import { useOnEnter, useTransition, useOnChange } from '@mindmatrix/react';
|
|
7
|
+
|
|
8
|
+
export function Counter() {
|
|
9
|
+
const [count, setCount] = useState(0);
|
|
10
|
+
const [status, setStatus] = useState('idle');
|
|
11
|
+
const [lastAction, setLastAction] = useState('');
|
|
12
|
+
|
|
13
|
+
// --- States & Hooks ---
|
|
14
|
+
|
|
15
|
+
// When entering the 'counting' state, reset the counter to zero
|
|
16
|
+
useOnEnter('counting', () => {
|
|
17
|
+
setCount(0);
|
|
18
|
+
setLastAction('reset');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Watch for count changes — tracks field mutations
|
|
22
|
+
useOnChange('count', () => {
|
|
23
|
+
setLastAction('counted');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// --- Transitions ---
|
|
27
|
+
|
|
28
|
+
// Start counting from idle
|
|
29
|
+
useTransition('start', { from: 'idle', to: 'counting' });
|
|
30
|
+
|
|
31
|
+
// Increment stays in the counting state
|
|
32
|
+
useTransition('increment', { from: 'counting', to: 'counting' });
|
|
33
|
+
|
|
34
|
+
// Decrement stays in the counting state
|
|
35
|
+
useTransition('decrement', { from: 'counting', to: 'counting' });
|
|
36
|
+
|
|
37
|
+
// Reset returns to idle
|
|
38
|
+
useTransition('reset', { from: 'counting', to: 'idle' });
|
|
39
|
+
|
|
40
|
+
// --- UI ---
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Stack className="counter-app" data-slot="main">
|
|
44
|
+
<Heading sx={{ fontSize: '2xl', fontWeight: 'bold', mb: 4 }}>
|
|
45
|
+
Counter: {count}
|
|
46
|
+
</Heading>
|
|
47
|
+
|
|
48
|
+
<Text sx={{ color: 'gray.500', mb: 2 }}>
|
|
49
|
+
Status: {status} | Last: {lastAction}
|
|
50
|
+
</Text>
|
|
51
|
+
|
|
52
|
+
<Stack sx={{ direction: 'row', gap: 2 }}>
|
|
53
|
+
<Button onClick={() => setCount(count + 1)} sx={{ colorScheme: 'blue' }}>
|
|
54
|
+
+1
|
|
55
|
+
</Button>
|
|
56
|
+
<Button onClick={() => setCount(count - 1)} sx={{ colorScheme: 'red' }}>
|
|
57
|
+
-1
|
|
58
|
+
</Button>
|
|
59
|
+
<Button onClick={() => setCount(0)} sx={{ variant: 'outline' }}>
|
|
60
|
+
Reset
|
|
61
|
+
</Button>
|
|
62
|
+
</Stack>
|
|
63
|
+
</Stack>
|
|
64
|
+
);
|
|
65
|
+
}
|